renderer_vulkan: Remove DescriptorSetProvider
This commit is contained in:
parent
e28c2a390c
commit
ed699f1e2b
@ -7,7 +7,6 @@
|
||||
#include "common/memory_detect.h"
|
||||
#include "common/microprofile.h"
|
||||
#include "common/settings.h"
|
||||
#include "common/texture.h"
|
||||
#include "core/core.h"
|
||||
#include "core/frontend/emu_window.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_interlaced_frag_spv.h"
|
||||
#include "video_core/host_shaders/vulkan_present_vert_spv.h"
|
||||
#include "vulkan/vulkan_format_traits.hpp"
|
||||
|
||||
#include <vk_mem_alloc.h>
|
||||
|
||||
@ -49,10 +47,6 @@ constexpr std::array<f32, 4 * 4> MakeOrthographicMatrix(u32 width, u32 height) {
|
||||
// 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,
|
||||
Frontend::EmuWindow* secondary_window)
|
||||
: RendererBase{system, window, secondary_window}, memory{system.Memory()},
|
||||
@ -69,10 +63,9 @@ RendererVulkan::RendererVulkan(Core::System& system, Frontend::EmuWindow& window
|
||||
scheduler,
|
||||
pool,
|
||||
renderpass_cache,
|
||||
main_window.ImageCount()},
|
||||
present_set_provider{instance, pool, PRESENT_BINDINGS} {
|
||||
main_window.ImageCount()} {
|
||||
CompileShaders();
|
||||
BuildLayouts();
|
||||
BuildLayoutsAndDescriptors();
|
||||
BuildPipelines();
|
||||
if (secondary_window) {
|
||||
second_window = std::make_unique<PresentWindow>(*secondary_window, instance, scheduler);
|
||||
@ -80,17 +73,22 @@ RendererVulkan::RendererVulkan(Core::System& system, Frontend::EmuWindow& window
|
||||
}
|
||||
|
||||
RendererVulkan::~RendererVulkan() {
|
||||
vk::Device device = instance.GetDevice();
|
||||
const vk::Device device = instance.GetDevice();
|
||||
scheduler.Finish();
|
||||
device.waitIdle();
|
||||
|
||||
device.destroyShaderModule(present_vertex_shader);
|
||||
for (u32 i = 0; i < PRESENT_PIPELINES; i++) {
|
||||
device.destroyPipeline(present_pipelines[i]);
|
||||
device.destroyShaderModule(present_shaders[i]);
|
||||
device.destroyPipelineLayout(pipeline_layout);
|
||||
device.destroyDescriptorPool(descriptor_pool);
|
||||
device.destroyDescriptorSetLayout(descriptor_set_layout);
|
||||
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);
|
||||
}
|
||||
|
||||
@ -105,9 +103,10 @@ void RendererVulkan::Sync() {
|
||||
}
|
||||
|
||||
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 auto& framebuffer = GPU::g_regs.framebuffer_config[fb_id];
|
||||
auto& texture = screen_infos[i].texture;
|
||||
|
||||
// Main LCD (0): 0x1ED02204, Sub LCD (1): 0x1ED02A04
|
||||
u32 lcd_color_addr =
|
||||
@ -118,37 +117,31 @@ void RendererVulkan::PrepareRendertarget() {
|
||||
|
||||
if (color_fill.is_enabled) {
|
||||
LoadColorToActiveVkTexture(color_fill.color_r, color_fill.color_g, color_fill.color_b,
|
||||
screen_infos[i].texture);
|
||||
} else {
|
||||
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;
|
||||
texture);
|
||||
continue;
|
||||
}
|
||||
|
||||
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) {
|
||||
const auto sampler = present_samplers[!Settings::values.filter_mode.GetValue()];
|
||||
std::transform(screen_infos.begin(), screen_infos.end(), present_textures.begin(),
|
||||
[&](auto& info) {
|
||||
return DescriptorData{vk::DescriptorImageInfo{sampler, info.image_view,
|
||||
vk::ImageLayout::eGeneral}};
|
||||
});
|
||||
const auto sampler = samplers[!Settings::values.filter_mode.GetValue()];
|
||||
std::transform(screen_infos.begin(), screen_infos.end(), image_infos.begin(), [&](auto& info) {
|
||||
return 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();
|
||||
scheduler.Record([this, layout, frame, descriptor_set, renderpass = main_window.Renderpass(),
|
||||
index = current_pipeline](vk::CommandBuffer cmdbuf) {
|
||||
@ -170,12 +163,11 @@ void RendererVulkan::PrepareDraw(Frame* frame, const Layout::FramebufferLayout&
|
||||
cmdbuf.setScissor(0, scissor);
|
||||
|
||||
const vk::ClearValue clear{.color = clear_color};
|
||||
const vk::PipelineLayout layout{*present_pipeline_layout};
|
||||
const vk::RenderPassBeginInfo renderpass_begin_info = {
|
||||
.renderPass = renderpass,
|
||||
.framebuffer = frame->framebuffer,
|
||||
.renderArea =
|
||||
vk::Rect2D{
|
||||
{
|
||||
.offset = {0, 0},
|
||||
.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.bindPipeline(vk::PipelineBindPoint::eGraphics, present_pipelines[index]);
|
||||
cmdbuf.bindDescriptorSets(vk::PipelineBindPoint::eGraphics, layout, 0, descriptor_set, {});
|
||||
cmdbuf.bindPipeline(vk::PipelineBindPoint::eGraphics, pipelines[index]);
|
||||
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() {
|
||||
vk::Device device = instance.GetDevice();
|
||||
present_vertex_shader = CompileSPV(VULKAN_PRESENT_VERT_SPV, device);
|
||||
present_shaders[0] = CompileSPV(VULKAN_PRESENT_FRAG_SPV, device);
|
||||
present_shaders[1] = CompileSPV(VULKAN_PRESENT_ANAGLYPH_FRAG_SPV, device);
|
||||
present_shaders[2] = CompileSPV(VULKAN_PRESENT_INTERLACED_FRAG_SPV, device);
|
||||
vert_shader = CompileSPV(VULKAN_PRESENT_VERT_SPV, device);
|
||||
frag_shaders[0] = CompileSPV(VULKAN_PRESENT_FRAG_SPV, device);
|
||||
frag_shaders[1] = CompileSPV(VULKAN_PRESENT_ANAGLYPH_FRAG_SPV, device);
|
||||
frag_shaders[2] = CompileSPV(VULKAN_PRESENT_INTERLACED_FRAG_SPV, device);
|
||||
|
||||
auto properties = instance.GetPhysicalDevice().getProperties();
|
||||
for (std::size_t i = 0; i < present_samplers.size(); i++) {
|
||||
const auto properties = instance.GetPhysicalDevice().getProperties();
|
||||
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::SamplerCreateInfo sampler_info = {
|
||||
.magFilter = filter_mode,
|
||||
@ -261,25 +254,81 @@ void RendererVulkan::CompileShaders() {
|
||||
.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 = {
|
||||
.stageFlags = vk::ShaderStageFlagBits::eVertex | vk::ShaderStageFlagBits::eFragment,
|
||||
.offset = 0,
|
||||
.size = sizeof(PresentUniformData),
|
||||
};
|
||||
|
||||
const auto descriptor_set_layout = present_set_provider.Layout();
|
||||
const vk::PipelineLayoutCreateInfo layout_info = {
|
||||
const vk::DescriptorSetLayoutBinding binding = {
|
||||
.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,
|
||||
.pSetLayouts = &descriptor_set_layout,
|
||||
.pushConstantRangeCount = 1,
|
||||
.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() {
|
||||
@ -370,16 +419,16 @@ void RendererVulkan::BuildPipelines() {
|
||||
.stencilTestEnable = false,
|
||||
};
|
||||
|
||||
for (u32 i = 0; i < PRESENT_PIPELINES; i++) {
|
||||
for (u32 i = 0; i < NUM_PIPELINES; i++) {
|
||||
const std::array shader_stages = {
|
||||
vk::PipelineShaderStageCreateInfo{
|
||||
.stage = vk::ShaderStageFlagBits::eVertex,
|
||||
.module = present_vertex_shader,
|
||||
.module = vert_shader,
|
||||
.pName = "main",
|
||||
},
|
||||
vk::PipelineShaderStageCreateInfo{
|
||||
.stage = vk::ShaderStageFlagBits::eFragment,
|
||||
.module = present_shaders[i],
|
||||
.module = frag_shaders[i],
|
||||
.pName = "main",
|
||||
},
|
||||
};
|
||||
@ -395,14 +444,14 @@ void RendererVulkan::BuildPipelines() {
|
||||
.pDepthStencilState = &depth_info,
|
||||
.pColorBlendState = &color_blending,
|
||||
.pDynamicState = &dynamic_info,
|
||||
.layout = *present_pipeline_layout,
|
||||
.layout = pipeline_layout,
|
||||
.renderPass = main_window.Renderpass(),
|
||||
};
|
||||
|
||||
const auto [result, pipeline] =
|
||||
instance.GetDevice().createGraphicsPipeline({}, pipeline_info);
|
||||
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);
|
||||
}
|
||||
|
||||
const VideoCore::PixelFormat pixel_format =
|
||||
VideoCore::PixelFormatFromGPUPixelFormat(framebuffer.color_format);
|
||||
const auto pixel_format = VideoCore::PixelFormatFromGPUPixelFormat(framebuffer.color_format);
|
||||
const vk::Format format = instance.GetTraits(pixel_format).native;
|
||||
const vk::ImageCreateInfo image_info = {
|
||||
.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) {
|
||||
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,
|
||||
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) {
|
||||
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,
|
||||
0, sizeof(info), &info);
|
||||
|
||||
@ -1032,9 +1080,8 @@ bool RendererVulkan::TryRenderScreenshotWithHostMemory() {
|
||||
.imageExtent = {width, height, 1},
|
||||
};
|
||||
|
||||
const vk::MemoryHostPointerPropertiesEXT import_properties =
|
||||
device.getMemoryHostPointerPropertiesEXT(
|
||||
vk::ExternalMemoryHandleTypeFlagBits::eHostAllocationEXT, aligned_pointer);
|
||||
const auto import_properties = device.getMemoryHostPointerPropertiesEXT(
|
||||
vk::ExternalMemoryHandleTypeFlagBits::eHostAllocationEXT, aligned_pointer);
|
||||
|
||||
if (!import_properties.memoryTypeBits) {
|
||||
// Could not import memory
|
||||
@ -1051,33 +1098,31 @@ bool RendererVulkan::TryRenderScreenshotWithHostMemory() {
|
||||
return false;
|
||||
}
|
||||
|
||||
const vk::StructureChain<vk::MemoryAllocateInfo, vk::ImportMemoryHostPointerInfoEXT>
|
||||
allocation_chain = {
|
||||
vk::MemoryAllocateInfo{
|
||||
.allocationSize = aligned_size,
|
||||
.memoryTypeIndex = memory_type_index.value(),
|
||||
},
|
||||
vk::ImportMemoryHostPointerInfoEXT{
|
||||
.handleType = vk::ExternalMemoryHandleTypeFlagBits::eHostAllocationEXT,
|
||||
.pHostPointer = aligned_pointer,
|
||||
},
|
||||
};
|
||||
const vk::StructureChain allocation_chain = {
|
||||
vk::MemoryAllocateInfo{
|
||||
.allocationSize = aligned_size,
|
||||
.memoryTypeIndex = memory_type_index.value(),
|
||||
},
|
||||
vk::ImportMemoryHostPointerInfoEXT{
|
||||
.handleType = vk::ExternalMemoryHandleTypeFlagBits::eHostAllocationEXT,
|
||||
.pHostPointer = aligned_pointer,
|
||||
},
|
||||
};
|
||||
|
||||
// Import host memory
|
||||
const vk::UniqueDeviceMemory imported_memory =
|
||||
device.allocateMemoryUnique(allocation_chain.get());
|
||||
|
||||
const vk::StructureChain<vk::BufferCreateInfo, vk::ExternalMemoryBufferCreateInfo> buffer_info =
|
||||
{
|
||||
vk::BufferCreateInfo{
|
||||
.size = aligned_size,
|
||||
.usage = vk::BufferUsageFlagBits::eTransferDst,
|
||||
.sharingMode = vk::SharingMode::eExclusive,
|
||||
},
|
||||
vk::ExternalMemoryBufferCreateInfo{
|
||||
.handleTypes = vk::ExternalMemoryHandleTypeFlagBits::eHostAllocationEXT,
|
||||
},
|
||||
};
|
||||
const vk::StructureChain buffer_info = {
|
||||
vk::BufferCreateInfo{
|
||||
.size = aligned_size,
|
||||
.usage = vk::BufferUsageFlagBits::eTransferDst,
|
||||
.sharingMode = vk::SharingMode::eExclusive,
|
||||
},
|
||||
vk::ExternalMemoryBufferCreateInfo{
|
||||
.handleTypes = vk::ExternalMemoryHandleTypeFlagBits::eHostAllocationEXT,
|
||||
},
|
||||
};
|
||||
|
||||
// Bind imported memory to buffer
|
||||
const vk::UniqueBuffer imported_buffer = device.createBufferUnique(buffer_info.get());
|
||||
|
@ -61,7 +61,8 @@ static_assert(sizeof(PresentUniformData) == 112,
|
||||
"PresentUniformData does not structure in shader!");
|
||||
|
||||
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:
|
||||
explicit RendererVulkan(Core::System& system, Frontend::EmuWindow& window,
|
||||
@ -83,7 +84,7 @@ public:
|
||||
private:
|
||||
void ReloadPipeline();
|
||||
void CompileShaders();
|
||||
void BuildLayouts();
|
||||
void BuildLayoutsAndDescriptors();
|
||||
void BuildPipelines();
|
||||
void ConfigureFramebufferTexture(TextureInfo& texture,
|
||||
const GPU::Regs::FramebufferConfig& framebuffer);
|
||||
@ -121,16 +122,19 @@ private:
|
||||
RasterizerVulkan rasterizer;
|
||||
std::unique_ptr<PresentWindow> second_window;
|
||||
|
||||
vk::UniquePipelineLayout present_pipeline_layout;
|
||||
DescriptorSetProvider present_set_provider;
|
||||
std::array<vk::Pipeline, PRESENT_PIPELINES> present_pipelines;
|
||||
std::array<vk::ShaderModule, PRESENT_PIPELINES> present_shaders;
|
||||
std::array<vk::Sampler, 2> present_samplers;
|
||||
vk::ShaderModule present_vertex_shader;
|
||||
vk::PipelineLayout pipeline_layout;
|
||||
vk::DescriptorPool descriptor_pool;
|
||||
vk::DescriptorSetLayout descriptor_set_layout;
|
||||
vk::DescriptorUpdateTemplate update_template;
|
||||
std::vector<vk::DescriptorSet> present_sets;
|
||||
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;
|
||||
|
||||
std::array<ScreenInfo, 3> screen_infos{};
|
||||
std::array<DescriptorData, 3> present_textures{};
|
||||
std::array<ScreenInfo, NUM_SCREENS> screen_infos{};
|
||||
std::array<vk::DescriptorImageInfo, NUM_SCREENS> image_infos{};
|
||||
PresentUniformData draw_info{};
|
||||
vk::ClearColorValue clear_color{};
|
||||
};
|
||||
|
@ -130,6 +130,7 @@ PresentWindow::PresentWindow(Frontend::EmuWindow& emu_window_, const Instance& i
|
||||
for (u32 i = 0; i < num_images; i++) {
|
||||
Frame& frame = swap_chain[i];
|
||||
frame.cmdbuf = command_buffers[i];
|
||||
frame.index = i;
|
||||
frame.render_ready = device.createSemaphore({});
|
||||
frame.present_done = device.createFence({.flags = vk::FenceCreateFlagBits::eSignaled});
|
||||
free_queue.push(&frame);
|
||||
|
@ -4,7 +4,6 @@
|
||||
|
||||
#include <atomic>
|
||||
#include <condition_variable>
|
||||
#include <mutex>
|
||||
#include <queue>
|
||||
#include "common/polyfill_thread.h"
|
||||
#include "video_core/renderer_vulkan/vk_swapchain.h"
|
||||
@ -25,6 +24,7 @@ class RenderpassCache;
|
||||
struct Frame {
|
||||
u32 width;
|
||||
u32 height;
|
||||
u32 index;
|
||||
VmaAllocation allocation;
|
||||
vk::Framebuffer framebuffer;
|
||||
vk::Image image;
|
||||
@ -55,19 +55,17 @@ public:
|
||||
/// This is called to notify the rendering backend of a surface change
|
||||
void NotifySurfaceChanged();
|
||||
|
||||
[[nodiscard]] vk::RenderPass Renderpass() const noexcept {
|
||||
vk::RenderPass Renderpass() const noexcept {
|
||||
return present_renderpass;
|
||||
}
|
||||
|
||||
u32 ImageCount() const noexcept {
|
||||
return swapchain.GetImageCount();
|
||||
return swap_chain.size();
|
||||
}
|
||||
|
||||
private:
|
||||
void PresentThread(std::stop_token token);
|
||||
|
||||
void CopyToSwapchain(Frame* frame);
|
||||
|
||||
vk::RenderPass CreateRenderpass();
|
||||
|
||||
private:
|
||||
|
@ -56,6 +56,10 @@ public:
|
||||
return image_count;
|
||||
}
|
||||
|
||||
u32 GetImageIndex() const {
|
||||
return image_index;
|
||||
}
|
||||
|
||||
vk::Extent2D GetExtent() const {
|
||||
return extent;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user