mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-16 23:17:29 +00:00
Merge pull request #1787 from kd-11/vulkan-wip
vk: Properly enable window resizing
This commit is contained in:
commit
338fb6cc7e
@ -430,7 +430,9 @@ VKGSRender::VKGSRender() : GSRender(frame_type::Vulkan)
|
||||
vk::set_current_thread_ctx(m_thread_context);
|
||||
vk::set_current_renderer(m_swap_chain->get_device());
|
||||
|
||||
m_swap_chain->init_swapchain(m_frame->client_width(), m_frame->client_height());
|
||||
m_client_width = m_frame->client_width();
|
||||
m_client_height = m_frame->client_height();
|
||||
m_swap_chain->init_swapchain(m_client_width, m_client_height);
|
||||
|
||||
//create command buffer...
|
||||
m_command_buffer_pool.create((*m_device));
|
||||
@ -1135,13 +1137,9 @@ void VKGSRender::prepare_rtts()
|
||||
return;
|
||||
|
||||
m_rtts_dirty = false;
|
||||
bool reconfigure_render_pass = true;
|
||||
|
||||
if (m_surface.format != surface_format)
|
||||
{
|
||||
m_surface.unpack(surface_format);
|
||||
reconfigure_render_pass = true;
|
||||
}
|
||||
|
||||
u32 clip_horizontal = rsx::method_registers[NV4097_SET_SURFACE_CLIP_HORIZONTAL];
|
||||
u32 clip_vertical = rsx::method_registers[NV4097_SET_SURFACE_CLIP_VERTICAL];
|
||||
@ -1202,7 +1200,17 @@ void VKGSRender::prepare_rtts()
|
||||
|
||||
void VKGSRender::flip(int buffer)
|
||||
{
|
||||
//LOG_NOTICE(Log::RSX, "flip(%d)", buffer);
|
||||
bool resize_screen = false;
|
||||
|
||||
if (m_client_height != m_frame->client_height() ||
|
||||
m_client_width != m_frame->client_width())
|
||||
{
|
||||
if (!!m_frame->client_height() && !!m_frame->client_width())
|
||||
resize_screen = true;
|
||||
}
|
||||
|
||||
if (!resize_screen)
|
||||
{
|
||||
u32 buffer_width = gcm_buffers[buffer].width;
|
||||
u32 buffer_height = gcm_buffers[buffer].height;
|
||||
u32 buffer_pitch = gcm_buffers[buffer].pitch;
|
||||
@ -1212,8 +1220,7 @@ void VKGSRender::flip(int buffer)
|
||||
areai screen_area = coordi({}, { (int)buffer_width, (int)buffer_height });
|
||||
|
||||
coordi aspect_ratio;
|
||||
if (1) //enable aspect ratio
|
||||
{
|
||||
|
||||
sizei csize = { m_frame->client_width(), m_frame->client_height() };
|
||||
sizei new_size = csize;
|
||||
|
||||
@ -1233,18 +1240,12 @@ void VKGSRender::flip(int buffer)
|
||||
}
|
||||
|
||||
aspect_ratio.size = new_size;
|
||||
}
|
||||
else
|
||||
{
|
||||
aspect_ratio.size = { m_frame->client_width(), m_frame->client_height() };
|
||||
}
|
||||
|
||||
VkSwapchainKHR swap_chain = (VkSwapchainKHR)(*m_swap_chain);
|
||||
|
||||
//Prepare surface for new frame
|
||||
CHECK_RESULT(vkAcquireNextImageKHR((*m_device), (*m_swap_chain), 0, m_present_semaphore, VK_NULL_HANDLE, &m_current_present_image));
|
||||
|
||||
|
||||
//Blit contents to screen..
|
||||
VkImage image_to_flip = nullptr;
|
||||
|
||||
@ -1279,6 +1280,71 @@ void VKGSRender::flip(int buffer)
|
||||
present.pSwapchains = &swap_chain;
|
||||
present.pImageIndices = &m_current_present_image;
|
||||
CHECK_RESULT(m_swap_chain->queuePresentKHR(m_swap_chain->get_present_queue(), &present));
|
||||
}
|
||||
else
|
||||
{
|
||||
/**
|
||||
* Since we are about to destroy the old swapchain and its images, we just discard the commandbuffer.
|
||||
* Waiting for the commands to process does not work reliably as the fence can be signaled before swap images are released
|
||||
* and there are no explicit methods to ensure that the presentation engine is not using the images at all.
|
||||
*/
|
||||
|
||||
CHECK_RESULT(vkEndCommandBuffer(m_command_buffer));
|
||||
|
||||
//Will have to block until rendering is completed
|
||||
VkFence resize_fence = VK_NULL_HANDLE;
|
||||
VkFenceCreateInfo infos = {};
|
||||
infos.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
|
||||
|
||||
vkQueueWaitIdle(m_swap_chain->get_present_queue());
|
||||
vkDeviceWaitIdle(*m_device);
|
||||
|
||||
vkCreateFence((*m_device), &infos, nullptr, &resize_fence);
|
||||
|
||||
//Wait for all grpahics tasks to complete
|
||||
VkPipelineStageFlags pipe_stage_flags = VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT;
|
||||
VkSubmitInfo submit_infos = {};
|
||||
submit_infos.commandBufferCount = 0;
|
||||
submit_infos.pCommandBuffers = nullptr;
|
||||
submit_infos.pWaitDstStageMask = &pipe_stage_flags;
|
||||
submit_infos.pWaitSemaphores = nullptr;
|
||||
submit_infos.waitSemaphoreCount = 0;
|
||||
submit_infos.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
|
||||
CHECK_RESULT(vkQueueSubmit(m_swap_chain->get_present_queue(), 1, &submit_infos, resize_fence));
|
||||
|
||||
vkWaitForFences((*m_device), 1, &resize_fence, VK_TRUE, UINT64_MAX);
|
||||
vkResetFences((*m_device), 1, &resize_fence);
|
||||
|
||||
vkDeviceWaitIdle(*m_device);
|
||||
|
||||
//Rebuild swapchain. Old swapchain destruction is handled by the init_swapchain call
|
||||
m_client_width = m_frame->client_width();
|
||||
m_client_height = m_frame->client_height();
|
||||
m_swap_chain->init_swapchain(m_client_width, m_client_height);
|
||||
|
||||
//Prepare new swapchain images for use
|
||||
CHECK_RESULT(vkResetCommandPool(*m_device, m_command_buffer_pool, 0));
|
||||
open_command_buffer();
|
||||
|
||||
for (u32 i = 0; i < m_swap_chain->get_swap_image_count(); ++i)
|
||||
{
|
||||
vk::change_image_layout(m_command_buffer, m_swap_chain->get_swap_chain_image(i),
|
||||
VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL,
|
||||
vk::get_image_subresource_range(0, 0, 1, 1, VK_IMAGE_ASPECT_COLOR_BIT));
|
||||
|
||||
VkClearColorValue clear_color{};
|
||||
auto range = vk::get_image_subresource_range(0, 0, 1, 1, VK_IMAGE_ASPECT_COLOR_BIT);
|
||||
vkCmdClearColorImage(m_command_buffer, m_swap_chain->get_swap_chain_image(i), VK_IMAGE_LAYOUT_GENERAL, &clear_color, 1, &range);
|
||||
vk::change_image_layout(m_command_buffer, m_swap_chain->get_swap_chain_image(i),
|
||||
VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,
|
||||
vk::get_image_subresource_range(0, 0, 1, 1, VK_IMAGE_ASPECT_COLOR_BIT));
|
||||
}
|
||||
|
||||
//Flush the command buffer
|
||||
close_and_submit_command_buffer({}, resize_fence);
|
||||
CHECK_RESULT(vkWaitForFences((*m_device), 1, &resize_fence, VK_TRUE, UINT64_MAX));
|
||||
vkDestroyFence((*m_device), resize_fence, nullptr);
|
||||
}
|
||||
|
||||
m_uniform_buffer_ring_info.m_get_pos = m_uniform_buffer_ring_info.get_current_put_pos_minus_one();
|
||||
m_index_buffer_ring_info.m_get_pos = m_index_buffer_ring_info.get_current_put_pos_minus_one();
|
||||
|
@ -69,6 +69,9 @@ private:
|
||||
std::vector<std::unique_ptr<vk::framebuffer> > m_framebuffer_to_clean;
|
||||
std::vector<std::unique_ptr<vk::sampler> > m_sampler_to_clean;
|
||||
|
||||
u32 m_client_width = 0;
|
||||
u32 m_client_height = 0;
|
||||
|
||||
u32 m_draw_calls = 0;
|
||||
u32 m_used_descriptors = 0;
|
||||
u8 m_draw_buffers_count = 0;
|
||||
|
Loading…
Reference in New Issue
Block a user