mirror of
https://git.suyu.dev/suyu/suyu.git
synced 2024-11-23 15:22:45 +01:00
vk_blit_screen: Make Draw method more generic
Allows specifying the framebuffer and render area dimensions, rather than being hard coded for the render window.
This commit is contained in:
parent
92887a65f0
commit
1e6c5d323d
3 changed files with 70 additions and 54 deletions
|
@ -162,7 +162,7 @@ void RendererVulkan::SwapBuffers(const Tegra::FramebufferConfig* framebuffer) {
|
||||||
if (has_been_recreated) {
|
if (has_been_recreated) {
|
||||||
blit_screen.Recreate();
|
blit_screen.Recreate();
|
||||||
}
|
}
|
||||||
const VkSemaphore render_semaphore = blit_screen.Draw(*framebuffer, use_accelerated);
|
const VkSemaphore render_semaphore = blit_screen.DrawToSwapchain(*framebuffer, use_accelerated);
|
||||||
scheduler.Flush(render_semaphore);
|
scheduler.Flush(render_semaphore);
|
||||||
scheduler.WaitWorker();
|
scheduler.WaitWorker();
|
||||||
swapchain.Present(render_semaphore);
|
swapchain.Present(render_semaphore);
|
||||||
|
|
|
@ -130,7 +130,10 @@ void VKBlitScreen::Recreate() {
|
||||||
CreateDynamicResources();
|
CreateDynamicResources();
|
||||||
}
|
}
|
||||||
|
|
||||||
VkSemaphore VKBlitScreen::Draw(const Tegra::FramebufferConfig& framebuffer, bool use_accelerated) {
|
VkSemaphore VKBlitScreen::Draw(const Tegra::FramebufferConfig& framebuffer,
|
||||||
|
const VkFramebuffer& host_framebuffer,
|
||||||
|
const Layout::FramebufferLayout layout, VkExtent2D render_area,
|
||||||
|
bool use_accelerated) {
|
||||||
RefreshResources(framebuffer);
|
RefreshResources(framebuffer);
|
||||||
|
|
||||||
// Finish any pending renderpass
|
// Finish any pending renderpass
|
||||||
|
@ -145,8 +148,8 @@ VkSemaphore VKBlitScreen::Draw(const Tegra::FramebufferConfig& framebuffer, bool
|
||||||
use_accelerated ? screen_info.image_view : *raw_image_views[image_index]);
|
use_accelerated ? screen_info.image_view : *raw_image_views[image_index]);
|
||||||
|
|
||||||
BufferData data;
|
BufferData data;
|
||||||
SetUniformData(data, framebuffer);
|
SetUniformData(data, layout);
|
||||||
SetVertexData(data, framebuffer);
|
SetVertexData(data, framebuffer, layout);
|
||||||
|
|
||||||
const std::span<u8> mapped_span = buffer_commit.Map();
|
const std::span<u8> mapped_span = buffer_commit.Map();
|
||||||
std::memcpy(mapped_span.data(), &data, sizeof(data));
|
std::memcpy(mapped_span.data(), &data, sizeof(data));
|
||||||
|
@ -220,52 +223,61 @@ VkSemaphore VKBlitScreen::Draw(const Tegra::FramebufferConfig& framebuffer, bool
|
||||||
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0, write_barrier);
|
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0, write_barrier);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
scheduler.Record([this, image_index, size = swapchain.GetSize()](vk::CommandBuffer cmdbuf) {
|
scheduler.Record(
|
||||||
const f32 bg_red = Settings::values.bg_red.GetValue() / 255.0f;
|
[this, host_framebuffer, image_index, size = render_area](vk::CommandBuffer cmdbuf) {
|
||||||
const f32 bg_green = Settings::values.bg_green.GetValue() / 255.0f;
|
const f32 bg_red = Settings::values.bg_red.GetValue() / 255.0f;
|
||||||
const f32 bg_blue = Settings::values.bg_blue.GetValue() / 255.0f;
|
const f32 bg_green = Settings::values.bg_green.GetValue() / 255.0f;
|
||||||
const VkClearValue clear_color{
|
const f32 bg_blue = Settings::values.bg_blue.GetValue() / 255.0f;
|
||||||
.color = {.float32 = {bg_red, bg_green, bg_blue, 1.0f}},
|
const VkClearValue clear_color{
|
||||||
};
|
.color = {.float32 = {bg_red, bg_green, bg_blue, 1.0f}},
|
||||||
const VkRenderPassBeginInfo renderpass_bi{
|
};
|
||||||
.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
|
const VkRenderPassBeginInfo renderpass_bi{
|
||||||
.pNext = nullptr,
|
.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
|
||||||
.renderPass = *renderpass,
|
.pNext = nullptr,
|
||||||
.framebuffer = *framebuffers[image_index],
|
.renderPass = *renderpass,
|
||||||
.renderArea =
|
.framebuffer = host_framebuffer,
|
||||||
{
|
.renderArea =
|
||||||
.offset = {0, 0},
|
{
|
||||||
.extent = size,
|
.offset = {0, 0},
|
||||||
},
|
.extent = size,
|
||||||
.clearValueCount = 1,
|
},
|
||||||
.pClearValues = &clear_color,
|
.clearValueCount = 1,
|
||||||
};
|
.pClearValues = &clear_color,
|
||||||
const VkViewport viewport{
|
};
|
||||||
.x = 0.0f,
|
const VkViewport viewport{
|
||||||
.y = 0.0f,
|
.x = 0.0f,
|
||||||
.width = static_cast<float>(size.width),
|
.y = 0.0f,
|
||||||
.height = static_cast<float>(size.height),
|
.width = static_cast<float>(size.width),
|
||||||
.minDepth = 0.0f,
|
.height = static_cast<float>(size.height),
|
||||||
.maxDepth = 1.0f,
|
.minDepth = 0.0f,
|
||||||
};
|
.maxDepth = 1.0f,
|
||||||
const VkRect2D scissor{
|
};
|
||||||
.offset = {0, 0},
|
const VkRect2D scissor{
|
||||||
.extent = size,
|
.offset = {0, 0},
|
||||||
};
|
.extent = size,
|
||||||
cmdbuf.BeginRenderPass(renderpass_bi, VK_SUBPASS_CONTENTS_INLINE);
|
};
|
||||||
cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);
|
cmdbuf.BeginRenderPass(renderpass_bi, VK_SUBPASS_CONTENTS_INLINE);
|
||||||
cmdbuf.SetViewport(0, viewport);
|
cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);
|
||||||
cmdbuf.SetScissor(0, scissor);
|
cmdbuf.SetViewport(0, viewport);
|
||||||
|
cmdbuf.SetScissor(0, scissor);
|
||||||
|
|
||||||
cmdbuf.BindVertexBuffer(0, *buffer, offsetof(BufferData, vertices));
|
cmdbuf.BindVertexBuffer(0, *buffer, offsetof(BufferData, vertices));
|
||||||
cmdbuf.BindDescriptorSets(VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline_layout, 0,
|
cmdbuf.BindDescriptorSets(VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline_layout, 0,
|
||||||
descriptor_sets[image_index], {});
|
descriptor_sets[image_index], {});
|
||||||
cmdbuf.Draw(4, 1, 0, 0);
|
cmdbuf.Draw(4, 1, 0, 0);
|
||||||
cmdbuf.EndRenderPass();
|
cmdbuf.EndRenderPass();
|
||||||
});
|
});
|
||||||
return *semaphores[image_index];
|
return *semaphores[image_index];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VkSemaphore VKBlitScreen::DrawToSwapchain(const Tegra::FramebufferConfig& framebuffer,
|
||||||
|
bool use_accelerated) {
|
||||||
|
const std::size_t image_index = swapchain.GetImageIndex();
|
||||||
|
const VkExtent2D render_area = swapchain.GetSize();
|
||||||
|
const Layout::FramebufferLayout layout = render_window.GetFramebufferLayout();
|
||||||
|
return Draw(framebuffer, *framebuffers[image_index], layout, render_area, use_accelerated);
|
||||||
|
}
|
||||||
|
|
||||||
void VKBlitScreen::CreateStaticResources() {
|
void VKBlitScreen::CreateStaticResources() {
|
||||||
CreateShaders();
|
CreateShaders();
|
||||||
CreateSemaphores();
|
CreateSemaphores();
|
||||||
|
@ -752,15 +764,13 @@ void VKBlitScreen::UpdateDescriptorSet(std::size_t image_index, VkImageView imag
|
||||||
device.GetLogical().UpdateDescriptorSets(std::array{ubo_write, sampler_write}, {});
|
device.GetLogical().UpdateDescriptorSets(std::array{ubo_write, sampler_write}, {});
|
||||||
}
|
}
|
||||||
|
|
||||||
void VKBlitScreen::SetUniformData(BufferData& data,
|
void VKBlitScreen::SetUniformData(BufferData& data, const Layout::FramebufferLayout layout) const {
|
||||||
const Tegra::FramebufferConfig& framebuffer) const {
|
|
||||||
const auto& layout = render_window.GetFramebufferLayout();
|
|
||||||
data.uniform.modelview_matrix =
|
data.uniform.modelview_matrix =
|
||||||
MakeOrthographicMatrix(static_cast<f32>(layout.width), static_cast<f32>(layout.height));
|
MakeOrthographicMatrix(static_cast<f32>(layout.width), static_cast<f32>(layout.height));
|
||||||
}
|
}
|
||||||
|
|
||||||
void VKBlitScreen::SetVertexData(BufferData& data,
|
void VKBlitScreen::SetVertexData(BufferData& data, const Tegra::FramebufferConfig& framebuffer,
|
||||||
const Tegra::FramebufferConfig& framebuffer) const {
|
const Layout::FramebufferLayout layout) const {
|
||||||
const auto& framebuffer_transform_flags = framebuffer.transform_flags;
|
const auto& framebuffer_transform_flags = framebuffer.transform_flags;
|
||||||
const auto& framebuffer_crop_rect = framebuffer.crop_rect;
|
const auto& framebuffer_crop_rect = framebuffer.crop_rect;
|
||||||
|
|
||||||
|
@ -798,7 +808,7 @@ void VKBlitScreen::SetVertexData(BufferData& data,
|
||||||
static_cast<f32>(screen_info.height);
|
static_cast<f32>(screen_info.height);
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto& screen = render_window.GetFramebufferLayout().screen;
|
const auto& screen = layout.screen;
|
||||||
const auto x = static_cast<f32>(screen.left);
|
const auto x = static_cast<f32>(screen.left);
|
||||||
const auto y = static_cast<f32>(screen.top);
|
const auto y = static_cast<f32>(screen.top);
|
||||||
const auto w = static_cast<f32>(screen.GetWidth());
|
const auto w = static_cast<f32>(screen.GetWidth());
|
||||||
|
|
|
@ -56,8 +56,13 @@ public:
|
||||||
void Recreate();
|
void Recreate();
|
||||||
|
|
||||||
[[nodiscard]] VkSemaphore Draw(const Tegra::FramebufferConfig& framebuffer,
|
[[nodiscard]] VkSemaphore Draw(const Tegra::FramebufferConfig& framebuffer,
|
||||||
|
const VkFramebuffer& host_framebuffer,
|
||||||
|
const Layout::FramebufferLayout layout, VkExtent2D render_area,
|
||||||
bool use_accelerated);
|
bool use_accelerated);
|
||||||
|
|
||||||
|
[[nodiscard]] VkSemaphore DrawToSwapchain(const Tegra::FramebufferConfig& framebuffer,
|
||||||
|
bool use_accelerated);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct BufferData;
|
struct BufferData;
|
||||||
|
|
||||||
|
@ -81,8 +86,9 @@ private:
|
||||||
void CreateRawImages(const Tegra::FramebufferConfig& framebuffer);
|
void CreateRawImages(const Tegra::FramebufferConfig& framebuffer);
|
||||||
|
|
||||||
void UpdateDescriptorSet(std::size_t image_index, VkImageView image_view) const;
|
void UpdateDescriptorSet(std::size_t image_index, VkImageView image_view) const;
|
||||||
void SetUniformData(BufferData& data, const Tegra::FramebufferConfig& framebuffer) const;
|
void SetUniformData(BufferData& data, const Layout::FramebufferLayout layout) const;
|
||||||
void SetVertexData(BufferData& data, const Tegra::FramebufferConfig& framebuffer) const;
|
void SetVertexData(BufferData& data, const Tegra::FramebufferConfig& framebuffer,
|
||||||
|
const Layout::FramebufferLayout layout) const;
|
||||||
|
|
||||||
u64 CalculateBufferSize(const Tegra::FramebufferConfig& framebuffer) const;
|
u64 CalculateBufferSize(const Tegra::FramebufferConfig& framebuffer) const;
|
||||||
u64 GetRawImageOffset(const Tegra::FramebufferConfig& framebuffer,
|
u64 GetRawImageOffset(const Tegra::FramebufferConfig& framebuffer,
|
||||||
|
|
Loading…
Reference in a new issue