renderer_vulkan: Remove DescriptorSetProvider

This commit is contained in:
GPUCode
2023-11-15 20:27:59 +02:00
parent e28c2a390c
commit ed699f1e2b
5 changed files with 156 additions and 104 deletions

View File

@ -7,7 +7,6 @@
#include "common/memory_detect.h" #include "common/memory_detect.h"
#include "common/microprofile.h" #include "common/microprofile.h"
#include "common/settings.h" #include "common/settings.h"
#include "common/texture.h"
#include "core/core.h" #include "core/core.h"
#include "core/frontend/emu_window.h" #include "core/frontend/emu_window.h"
#include "core/hw/gpu.h" #include "core/hw/gpu.h"
@ -21,7 +20,6 @@
#include "video_core/host_shaders/vulkan_present_frag_spv.h" #include "video_core/host_shaders/vulkan_present_frag_spv.h"
#include "video_core/host_shaders/vulkan_present_interlaced_frag_spv.h" #include "video_core/host_shaders/vulkan_present_interlaced_frag_spv.h"
#include "video_core/host_shaders/vulkan_present_vert_spv.h" #include "video_core/host_shaders/vulkan_present_vert_spv.h"
#include "vulkan/vulkan_format_traits.hpp"
#include <vk_mem_alloc.h> #include <vk_mem_alloc.h>
@ -49,10 +47,6 @@ constexpr std::array<f32, 4 * 4> MakeOrthographicMatrix(u32 width, u32 height) {
// clang-format on // clang-format on
} }
constexpr static std::array<vk::DescriptorSetLayoutBinding, 1> PRESENT_BINDINGS = {{
{0, vk::DescriptorType::eCombinedImageSampler, 3, vk::ShaderStageFlagBits::eFragment},
}};
RendererVulkan::RendererVulkan(Core::System& system, Frontend::EmuWindow& window, RendererVulkan::RendererVulkan(Core::System& system, Frontend::EmuWindow& window,
Frontend::EmuWindow* secondary_window) Frontend::EmuWindow* secondary_window)
: RendererBase{system, window, secondary_window}, memory{system.Memory()}, : RendererBase{system, window, secondary_window}, memory{system.Memory()},
@ -69,10 +63,9 @@ RendererVulkan::RendererVulkan(Core::System& system, Frontend::EmuWindow& window
scheduler, scheduler,
pool, pool,
renderpass_cache, renderpass_cache,
main_window.ImageCount()}, main_window.ImageCount()} {
present_set_provider{instance, pool, PRESENT_BINDINGS} {
CompileShaders(); CompileShaders();
BuildLayouts(); BuildLayoutsAndDescriptors();
BuildPipelines(); BuildPipelines();
if (secondary_window) { if (secondary_window) {
second_window = std::make_unique<PresentWindow>(*secondary_window, instance, scheduler); second_window = std::make_unique<PresentWindow>(*secondary_window, instance, scheduler);
@ -80,17 +73,22 @@ RendererVulkan::RendererVulkan(Core::System& system, Frontend::EmuWindow& window
} }
RendererVulkan::~RendererVulkan() { RendererVulkan::~RendererVulkan() {
vk::Device device = instance.GetDevice(); const vk::Device device = instance.GetDevice();
scheduler.Finish(); scheduler.Finish();
device.waitIdle(); device.waitIdle();
device.destroyShaderModule(present_vertex_shader); device.destroyPipelineLayout(pipeline_layout);
for (u32 i = 0; i < PRESENT_PIPELINES; i++) { device.destroyDescriptorPool(descriptor_pool);
device.destroyPipeline(present_pipelines[i]); device.destroyDescriptorSetLayout(descriptor_set_layout);
device.destroyShaderModule(present_shaders[i]); device.destroyDescriptorUpdateTemplate(update_template);
device.destroyShaderModule(vert_shader);
for (u32 i = 0; i < NUM_PIPELINES; i++) {
device.destroyPipeline(pipelines[i]);
device.destroyShaderModule(frag_shaders[i]);
} }
for (auto& sampler : present_samplers) { for (auto sampler : samplers) {
device.destroySampler(sampler); device.destroySampler(sampler);
} }
@ -105,9 +103,10 @@ void RendererVulkan::Sync() {
} }
void RendererVulkan::PrepareRendertarget() { void RendererVulkan::PrepareRendertarget() {
for (u32 i = 0; i < 3; i++) { for (u32 i = 0; i < NUM_SCREENS; i++) {
const u32 fb_id = i == 2 ? 1 : 0; const u32 fb_id = i == 2 ? 1 : 0;
const auto& framebuffer = GPU::g_regs.framebuffer_config[fb_id]; const auto& framebuffer = GPU::g_regs.framebuffer_config[fb_id];
auto& texture = screen_infos[i].texture;
// Main LCD (0): 0x1ED02204, Sub LCD (1): 0x1ED02A04 // Main LCD (0): 0x1ED02204, Sub LCD (1): 0x1ED02A04
u32 lcd_color_addr = u32 lcd_color_addr =
@ -118,37 +117,31 @@ void RendererVulkan::PrepareRendertarget() {
if (color_fill.is_enabled) { if (color_fill.is_enabled) {
LoadColorToActiveVkTexture(color_fill.color_r, color_fill.color_g, color_fill.color_b, LoadColorToActiveVkTexture(color_fill.color_r, color_fill.color_g, color_fill.color_b,
screen_infos[i].texture); texture);
} else { continue;
TextureInfo& texture = screen_infos[i].texture;
if (texture.width != framebuffer.width || texture.height != framebuffer.height ||
texture.format != framebuffer.color_format) {
// Reallocate texture if the framebuffer size has changed.
// This is expected to not happen very often and hence should not be a
// performance problem.
ConfigureFramebufferTexture(texture, framebuffer);
}
LoadFBToScreenInfo(framebuffer, screen_infos[i], i == 1);
// Resize the texture in case the framebuffer size has changed
texture.width = framebuffer.width;
texture.height = framebuffer.height;
} }
if (texture.width != framebuffer.width || texture.height != framebuffer.height ||
texture.format != framebuffer.color_format) {
ConfigureFramebufferTexture(texture, framebuffer);
}
LoadFBToScreenInfo(framebuffer, screen_infos[i], i == 1);
} }
} }
void RendererVulkan::PrepareDraw(Frame* frame, const Layout::FramebufferLayout& layout) { void RendererVulkan::PrepareDraw(Frame* frame, const Layout::FramebufferLayout& layout) {
const auto sampler = present_samplers[!Settings::values.filter_mode.GetValue()]; const auto sampler = samplers[!Settings::values.filter_mode.GetValue()];
std::transform(screen_infos.begin(), screen_infos.end(), present_textures.begin(), std::transform(screen_infos.begin(), screen_infos.end(), image_infos.begin(), [&](auto& info) {
[&](auto& info) { return vk::DescriptorImageInfo{sampler, info.image_view, vk::ImageLayout::eGeneral};
return DescriptorData{vk::DescriptorImageInfo{sampler, info.image_view, });
vk::ImageLayout::eGeneral}};
});
const auto descriptor_set = present_set_provider.Acquire(present_textures); // Prepare the descriptor set with presentation images.
const auto descriptor_set = present_sets[frame->index];
const vk::Device device = instance.GetDevice();
device.updateDescriptorSetWithTemplate(descriptor_set, update_template, image_infos);
// Bind presentation pipeline, enter renderpass.
renderpass_cache.EndRendering(); renderpass_cache.EndRendering();
scheduler.Record([this, layout, frame, descriptor_set, renderpass = main_window.Renderpass(), scheduler.Record([this, layout, frame, descriptor_set, renderpass = main_window.Renderpass(),
index = current_pipeline](vk::CommandBuffer cmdbuf) { index = current_pipeline](vk::CommandBuffer cmdbuf) {
@ -170,12 +163,11 @@ void RendererVulkan::PrepareDraw(Frame* frame, const Layout::FramebufferLayout&
cmdbuf.setScissor(0, scissor); cmdbuf.setScissor(0, scissor);
const vk::ClearValue clear{.color = clear_color}; const vk::ClearValue clear{.color = clear_color};
const vk::PipelineLayout layout{*present_pipeline_layout};
const vk::RenderPassBeginInfo renderpass_begin_info = { const vk::RenderPassBeginInfo renderpass_begin_info = {
.renderPass = renderpass, .renderPass = renderpass,
.framebuffer = frame->framebuffer, .framebuffer = frame->framebuffer,
.renderArea = .renderArea =
vk::Rect2D{ {
.offset = {0, 0}, .offset = {0, 0},
.extent = {frame->width, frame->height}, .extent = {frame->width, frame->height},
}, },
@ -184,8 +176,9 @@ void RendererVulkan::PrepareDraw(Frame* frame, const Layout::FramebufferLayout&
}; };
cmdbuf.beginRenderPass(renderpass_begin_info, vk::SubpassContents::eInline); cmdbuf.beginRenderPass(renderpass_begin_info, vk::SubpassContents::eInline);
cmdbuf.bindPipeline(vk::PipelineBindPoint::eGraphics, present_pipelines[index]); cmdbuf.bindPipeline(vk::PipelineBindPoint::eGraphics, pipelines[index]);
cmdbuf.bindDescriptorSets(vk::PipelineBindPoint::eGraphics, layout, 0, descriptor_set, {}); cmdbuf.bindDescriptorSets(vk::PipelineBindPoint::eGraphics, pipeline_layout, 0,
descriptor_set, {});
}); });
} }
@ -239,13 +232,13 @@ void RendererVulkan::LoadFBToScreenInfo(const GPU::Regs::FramebufferConfig& fram
void RendererVulkan::CompileShaders() { void RendererVulkan::CompileShaders() {
vk::Device device = instance.GetDevice(); vk::Device device = instance.GetDevice();
present_vertex_shader = CompileSPV(VULKAN_PRESENT_VERT_SPV, device); vert_shader = CompileSPV(VULKAN_PRESENT_VERT_SPV, device);
present_shaders[0] = CompileSPV(VULKAN_PRESENT_FRAG_SPV, device); frag_shaders[0] = CompileSPV(VULKAN_PRESENT_FRAG_SPV, device);
present_shaders[1] = CompileSPV(VULKAN_PRESENT_ANAGLYPH_FRAG_SPV, device); frag_shaders[1] = CompileSPV(VULKAN_PRESENT_ANAGLYPH_FRAG_SPV, device);
present_shaders[2] = CompileSPV(VULKAN_PRESENT_INTERLACED_FRAG_SPV, device); frag_shaders[2] = CompileSPV(VULKAN_PRESENT_INTERLACED_FRAG_SPV, device);
auto properties = instance.GetPhysicalDevice().getProperties(); const auto properties = instance.GetPhysicalDevice().getProperties();
for (std::size_t i = 0; i < present_samplers.size(); i++) { for (std::size_t i = 0; i < samplers.size(); i++) {
const vk::Filter filter_mode = i == 0 ? vk::Filter::eLinear : vk::Filter::eNearest; const vk::Filter filter_mode = i == 0 ? vk::Filter::eLinear : vk::Filter::eNearest;
const vk::SamplerCreateInfo sampler_info = { const vk::SamplerCreateInfo sampler_info = {
.magFilter = filter_mode, .magFilter = filter_mode,
@ -261,25 +254,81 @@ void RendererVulkan::CompileShaders() {
.unnormalizedCoordinates = false, .unnormalizedCoordinates = false,
}; };
present_samplers[i] = device.createSampler(sampler_info); samplers[i] = device.createSampler(sampler_info);
} }
} }
void RendererVulkan::BuildLayouts() { void RendererVulkan::BuildLayoutsAndDescriptors() {
const vk::PushConstantRange push_range = { const vk::PushConstantRange push_range = {
.stageFlags = vk::ShaderStageFlagBits::eVertex | vk::ShaderStageFlagBits::eFragment, .stageFlags = vk::ShaderStageFlagBits::eVertex | vk::ShaderStageFlagBits::eFragment,
.offset = 0, .offset = 0,
.size = sizeof(PresentUniformData), .size = sizeof(PresentUniformData),
}; };
const auto descriptor_set_layout = present_set_provider.Layout(); const vk::DescriptorSetLayoutBinding binding = {
const vk::PipelineLayoutCreateInfo layout_info = { .binding = 0,
.descriptorType = vk::DescriptorType::eCombinedImageSampler,
.descriptorCount = 3,
.stageFlags = vk::ShaderStageFlagBits::eFragment,
};
const vk::DescriptorUpdateTemplateEntry update_entry = {
.dstBinding = 0,
.dstArrayElement = 0,
.descriptorCount = 3,
.descriptorType = vk::DescriptorType::eCombinedImageSampler,
.offset = 0,
.stride = sizeof(vk::DescriptorImageInfo),
};
const vk::DescriptorSetLayoutCreateInfo layout_info = {
.bindingCount = 1,
.pBindings = &binding,
};
const vk::Device device = instance.GetDevice();
descriptor_set_layout = device.createDescriptorSetLayout(layout_info);
const vk::DescriptorUpdateTemplateCreateInfo template_info = {
.descriptorUpdateEntryCount = 1,
.pDescriptorUpdateEntries = &update_entry,
.templateType = vk::DescriptorUpdateTemplateType::eDescriptorSet,
.descriptorSetLayout = descriptor_set_layout,
};
update_template = device.createDescriptorUpdateTemplate(template_info);
const vk::PipelineLayoutCreateInfo pipeline_layout_info = {
.setLayoutCount = 1, .setLayoutCount = 1,
.pSetLayouts = &descriptor_set_layout, .pSetLayouts = &descriptor_set_layout,
.pushConstantRangeCount = 1, .pushConstantRangeCount = 1,
.pPushConstantRanges = &push_range, .pPushConstantRanges = &push_range,
}; };
present_pipeline_layout = instance.GetDevice().createPipelineLayoutUnique(layout_info); pipeline_layout = device.createPipelineLayout(pipeline_layout_info);
const u32 image_count = main_window.ImageCount();
const vk::DescriptorPoolSize pool_size = {
.type = vk::DescriptorType::eCombinedImageSampler,
.descriptorCount = binding.descriptorCount * image_count,
};
const vk::DescriptorPoolCreateInfo descriptor_pool_info = {
.maxSets = image_count,
.poolSizeCount = 1,
.pPoolSizes = &pool_size,
};
descriptor_pool = device.createDescriptorPool(descriptor_pool_info);
std::array<vk::DescriptorSetLayout, 3> layouts;
layouts.fill(descriptor_set_layout);
const vk::DescriptorSetAllocateInfo alloc_info = {
.descriptorPool = descriptor_pool,
.descriptorSetCount = image_count,
.pSetLayouts = layouts.data(),
};
present_sets = device.allocateDescriptorSets(alloc_info);
} }
void RendererVulkan::BuildPipelines() { void RendererVulkan::BuildPipelines() {
@ -370,16 +419,16 @@ void RendererVulkan::BuildPipelines() {
.stencilTestEnable = false, .stencilTestEnable = false,
}; };
for (u32 i = 0; i < PRESENT_PIPELINES; i++) { for (u32 i = 0; i < NUM_PIPELINES; i++) {
const std::array shader_stages = { const std::array shader_stages = {
vk::PipelineShaderStageCreateInfo{ vk::PipelineShaderStageCreateInfo{
.stage = vk::ShaderStageFlagBits::eVertex, .stage = vk::ShaderStageFlagBits::eVertex,
.module = present_vertex_shader, .module = vert_shader,
.pName = "main", .pName = "main",
}, },
vk::PipelineShaderStageCreateInfo{ vk::PipelineShaderStageCreateInfo{
.stage = vk::ShaderStageFlagBits::eFragment, .stage = vk::ShaderStageFlagBits::eFragment,
.module = present_shaders[i], .module = frag_shaders[i],
.pName = "main", .pName = "main",
}, },
}; };
@ -395,14 +444,14 @@ void RendererVulkan::BuildPipelines() {
.pDepthStencilState = &depth_info, .pDepthStencilState = &depth_info,
.pColorBlendState = &color_blending, .pColorBlendState = &color_blending,
.pDynamicState = &dynamic_info, .pDynamicState = &dynamic_info,
.layout = *present_pipeline_layout, .layout = pipeline_layout,
.renderPass = main_window.Renderpass(), .renderPass = main_window.Renderpass(),
}; };
const auto [result, pipeline] = const auto [result, pipeline] =
instance.GetDevice().createGraphicsPipeline({}, pipeline_info); instance.GetDevice().createGraphicsPipeline({}, pipeline_info);
ASSERT_MSG(result == vk::Result::eSuccess, "Unable to build present pipelines"); ASSERT_MSG(result == vk::Result::eSuccess, "Unable to build present pipelines");
present_pipelines[i] = pipeline; pipelines[i] = pipeline;
} }
} }
@ -416,8 +465,7 @@ void RendererVulkan::ConfigureFramebufferTexture(TextureInfo& texture,
vmaDestroyImage(instance.GetAllocator(), texture.image, texture.allocation); vmaDestroyImage(instance.GetAllocator(), texture.image, texture.allocation);
} }
const VideoCore::PixelFormat pixel_format = const auto pixel_format = VideoCore::PixelFormatFromGPUPixelFormat(framebuffer.color_format);
VideoCore::PixelFormatFromGPUPixelFormat(framebuffer.color_format);
const vk::Format format = instance.GetTraits(pixel_format).native; const vk::Format format = instance.GetTraits(pixel_format).native;
const vk::ImageCreateInfo image_info = { const vk::ImageCreateInfo image_info = {
.imageType = vk::ImageType::e2D, .imageType = vk::ImageType::e2D,
@ -603,7 +651,7 @@ void RendererVulkan::DrawSingleScreen(u32 screen_id, float x, float y, float w,
scheduler.Record([this, offset = offset, info = draw_info](vk::CommandBuffer cmdbuf) { scheduler.Record([this, offset = offset, info = draw_info](vk::CommandBuffer cmdbuf) {
const u32 first_vertex = static_cast<u32>(offset) / sizeof(ScreenRectVertex); const u32 first_vertex = static_cast<u32>(offset) / sizeof(ScreenRectVertex);
cmdbuf.pushConstants(*present_pipeline_layout, cmdbuf.pushConstants(pipeline_layout,
vk::ShaderStageFlagBits::eFragment | vk::ShaderStageFlagBits::eVertex, vk::ShaderStageFlagBits::eFragment | vk::ShaderStageFlagBits::eVertex,
0, sizeof(info), &info); 0, sizeof(info), &info);
@ -676,7 +724,7 @@ void RendererVulkan::DrawSingleScreenStereo(u32 screen_id_l, u32 screen_id_r, fl
scheduler.Record([this, offset = offset, info = draw_info](vk::CommandBuffer cmdbuf) { scheduler.Record([this, offset = offset, info = draw_info](vk::CommandBuffer cmdbuf) {
const u32 first_vertex = static_cast<u32>(offset) / sizeof(ScreenRectVertex); const u32 first_vertex = static_cast<u32>(offset) / sizeof(ScreenRectVertex);
cmdbuf.pushConstants(*present_pipeline_layout, cmdbuf.pushConstants(pipeline_layout,
vk::ShaderStageFlagBits::eFragment | vk::ShaderStageFlagBits::eVertex, vk::ShaderStageFlagBits::eFragment | vk::ShaderStageFlagBits::eVertex,
0, sizeof(info), &info); 0, sizeof(info), &info);
@ -1032,9 +1080,8 @@ bool RendererVulkan::TryRenderScreenshotWithHostMemory() {
.imageExtent = {width, height, 1}, .imageExtent = {width, height, 1},
}; };
const vk::MemoryHostPointerPropertiesEXT import_properties = const auto import_properties = device.getMemoryHostPointerPropertiesEXT(
device.getMemoryHostPointerPropertiesEXT( vk::ExternalMemoryHandleTypeFlagBits::eHostAllocationEXT, aligned_pointer);
vk::ExternalMemoryHandleTypeFlagBits::eHostAllocationEXT, aligned_pointer);
if (!import_properties.memoryTypeBits) { if (!import_properties.memoryTypeBits) {
// Could not import memory // Could not import memory
@ -1051,33 +1098,31 @@ bool RendererVulkan::TryRenderScreenshotWithHostMemory() {
return false; return false;
} }
const vk::StructureChain<vk::MemoryAllocateInfo, vk::ImportMemoryHostPointerInfoEXT> const vk::StructureChain allocation_chain = {
allocation_chain = { vk::MemoryAllocateInfo{
vk::MemoryAllocateInfo{ .allocationSize = aligned_size,
.allocationSize = aligned_size, .memoryTypeIndex = memory_type_index.value(),
.memoryTypeIndex = memory_type_index.value(), },
}, vk::ImportMemoryHostPointerInfoEXT{
vk::ImportMemoryHostPointerInfoEXT{ .handleType = vk::ExternalMemoryHandleTypeFlagBits::eHostAllocationEXT,
.handleType = vk::ExternalMemoryHandleTypeFlagBits::eHostAllocationEXT, .pHostPointer = aligned_pointer,
.pHostPointer = aligned_pointer, },
}, };
};
// Import host memory // Import host memory
const vk::UniqueDeviceMemory imported_memory = const vk::UniqueDeviceMemory imported_memory =
device.allocateMemoryUnique(allocation_chain.get()); device.allocateMemoryUnique(allocation_chain.get());
const vk::StructureChain<vk::BufferCreateInfo, vk::ExternalMemoryBufferCreateInfo> buffer_info = const vk::StructureChain buffer_info = {
{ vk::BufferCreateInfo{
vk::BufferCreateInfo{ .size = aligned_size,
.size = aligned_size, .usage = vk::BufferUsageFlagBits::eTransferDst,
.usage = vk::BufferUsageFlagBits::eTransferDst, .sharingMode = vk::SharingMode::eExclusive,
.sharingMode = vk::SharingMode::eExclusive, },
}, vk::ExternalMemoryBufferCreateInfo{
vk::ExternalMemoryBufferCreateInfo{ .handleTypes = vk::ExternalMemoryHandleTypeFlagBits::eHostAllocationEXT,
.handleTypes = vk::ExternalMemoryHandleTypeFlagBits::eHostAllocationEXT, },
}, };
};
// Bind imported memory to buffer // Bind imported memory to buffer
const vk::UniqueBuffer imported_buffer = device.createBufferUnique(buffer_info.get()); const vk::UniqueBuffer imported_buffer = device.createBufferUnique(buffer_info.get());

View File

@ -61,7 +61,8 @@ static_assert(sizeof(PresentUniformData) == 112,
"PresentUniformData does not structure in shader!"); "PresentUniformData does not structure in shader!");
class RendererVulkan : public VideoCore::RendererBase { class RendererVulkan : public VideoCore::RendererBase {
static constexpr std::size_t PRESENT_PIPELINES = 3; static constexpr std::size_t NUM_PIPELINES = 3;
static constexpr std::size_t NUM_SCREENS = 3;
public: public:
explicit RendererVulkan(Core::System& system, Frontend::EmuWindow& window, explicit RendererVulkan(Core::System& system, Frontend::EmuWindow& window,
@ -83,7 +84,7 @@ public:
private: private:
void ReloadPipeline(); void ReloadPipeline();
void CompileShaders(); void CompileShaders();
void BuildLayouts(); void BuildLayoutsAndDescriptors();
void BuildPipelines(); void BuildPipelines();
void ConfigureFramebufferTexture(TextureInfo& texture, void ConfigureFramebufferTexture(TextureInfo& texture,
const GPU::Regs::FramebufferConfig& framebuffer); const GPU::Regs::FramebufferConfig& framebuffer);
@ -121,16 +122,19 @@ private:
RasterizerVulkan rasterizer; RasterizerVulkan rasterizer;
std::unique_ptr<PresentWindow> second_window; std::unique_ptr<PresentWindow> second_window;
vk::UniquePipelineLayout present_pipeline_layout; vk::PipelineLayout pipeline_layout;
DescriptorSetProvider present_set_provider; vk::DescriptorPool descriptor_pool;
std::array<vk::Pipeline, PRESENT_PIPELINES> present_pipelines; vk::DescriptorSetLayout descriptor_set_layout;
std::array<vk::ShaderModule, PRESENT_PIPELINES> present_shaders; vk::DescriptorUpdateTemplate update_template;
std::array<vk::Sampler, 2> present_samplers; std::vector<vk::DescriptorSet> present_sets;
vk::ShaderModule present_vertex_shader; std::array<vk::Pipeline, NUM_PIPELINES> pipelines;
std::array<vk::ShaderModule, NUM_PIPELINES> frag_shaders;
std::array<vk::Sampler, 2> samplers;
vk::ShaderModule vert_shader;
u32 current_pipeline = 0; u32 current_pipeline = 0;
std::array<ScreenInfo, 3> screen_infos{}; std::array<ScreenInfo, NUM_SCREENS> screen_infos{};
std::array<DescriptorData, 3> present_textures{}; std::array<vk::DescriptorImageInfo, NUM_SCREENS> image_infos{};
PresentUniformData draw_info{}; PresentUniformData draw_info{};
vk::ClearColorValue clear_color{}; vk::ClearColorValue clear_color{};
}; };

View File

@ -130,6 +130,7 @@ PresentWindow::PresentWindow(Frontend::EmuWindow& emu_window_, const Instance& i
for (u32 i = 0; i < num_images; i++) { for (u32 i = 0; i < num_images; i++) {
Frame& frame = swap_chain[i]; Frame& frame = swap_chain[i];
frame.cmdbuf = command_buffers[i]; frame.cmdbuf = command_buffers[i];
frame.index = i;
frame.render_ready = device.createSemaphore({}); frame.render_ready = device.createSemaphore({});
frame.present_done = device.createFence({.flags = vk::FenceCreateFlagBits::eSignaled}); frame.present_done = device.createFence({.flags = vk::FenceCreateFlagBits::eSignaled});
free_queue.push(&frame); free_queue.push(&frame);

View File

@ -4,7 +4,6 @@
#include <atomic> #include <atomic>
#include <condition_variable> #include <condition_variable>
#include <mutex>
#include <queue> #include <queue>
#include "common/polyfill_thread.h" #include "common/polyfill_thread.h"
#include "video_core/renderer_vulkan/vk_swapchain.h" #include "video_core/renderer_vulkan/vk_swapchain.h"
@ -25,6 +24,7 @@ class RenderpassCache;
struct Frame { struct Frame {
u32 width; u32 width;
u32 height; u32 height;
u32 index;
VmaAllocation allocation; VmaAllocation allocation;
vk::Framebuffer framebuffer; vk::Framebuffer framebuffer;
vk::Image image; vk::Image image;
@ -55,19 +55,17 @@ public:
/// This is called to notify the rendering backend of a surface change /// This is called to notify the rendering backend of a surface change
void NotifySurfaceChanged(); void NotifySurfaceChanged();
[[nodiscard]] vk::RenderPass Renderpass() const noexcept { vk::RenderPass Renderpass() const noexcept {
return present_renderpass; return present_renderpass;
} }
u32 ImageCount() const noexcept { u32 ImageCount() const noexcept {
return swapchain.GetImageCount(); return swap_chain.size();
} }
private: private:
void PresentThread(std::stop_token token); void PresentThread(std::stop_token token);
void CopyToSwapchain(Frame* frame); void CopyToSwapchain(Frame* frame);
vk::RenderPass CreateRenderpass(); vk::RenderPass CreateRenderpass();
private: private:

View File

@ -56,6 +56,10 @@ public:
return image_count; return image_count;
} }
u32 GetImageIndex() const {
return image_index;
}
vk::Extent2D GetExtent() const { vk::Extent2D GetExtent() const {
return extent; return extent;
} }