Skip to content

Commit

Permalink
Decouple frame contexts from number of swapchain images.
Browse files Browse the repository at this point in the history
  • Loading branch information
Hans-Kristian Arntzen committed Nov 2, 2018
1 parent 917e6e1 commit 5215453
Show file tree
Hide file tree
Showing 7 changed files with 151 additions and 176 deletions.
43 changes: 9 additions & 34 deletions application/platforms/application_libretro_utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,15 +32,15 @@ static retro_hw_render_context_negotiation_interface_vulkan vulkan_negotiation;
static std::unique_ptr<Vulkan::Context> vulkan_context;
static Vulkan::ImageViewHandle swapchain_unorm_view;
static Vulkan::ImageHandle swapchain_image;
static Vulkan::Semaphore acquire_semaphore;
static unsigned num_swapchain_images;
static retro_vulkan_image swapchain_image_info;
static bool can_dupe = false;
static std::string application_name;
static unsigned application_version;

static unsigned swapchain_width;
static unsigned swapchain_height;
static unsigned swapchain_frame_index;
static Vulkan::Semaphore acquire_semaphore;

static VkApplicationInfo vulkan_app = {
VK_STRUCTURE_TYPE_APPLICATION_INFO,
Expand Down Expand Up @@ -97,32 +97,12 @@ bool libretro_create_device(

void libretro_begin_frame(Vulkan::WSI &wsi, retro_usec_t frame_time)
{
auto sync_index = vulkan_interface->get_sync_index(vulkan_interface->handle);

// Check if we need to reinitialize the swapchain.
unsigned num_images = 0;
auto sync_mask = vulkan_interface->get_sync_index_mask(vulkan_interface->handle);
for (unsigned i = 0; i < 32; i++)
{
if (sync_mask & (1u << i))
num_images = i + 1;
}

if (num_images != num_swapchain_images)
{
num_swapchain_images = num_images;
std::vector<Vulkan::ImageHandle> images;
for (unsigned i = 0; i < num_images; i++)
images.push_back(swapchain_image);

acquire_semaphore.reset();
wsi.reinit_external_swapchain(std::move(images));
}

// Setup the external frame.
vulkan_interface->wait_sync_index(vulkan_interface->handle);
wsi.set_external_frame(sync_index, acquire_semaphore, frame_time * 1e-6);
wsi.set_external_frame(swapchain_frame_index, acquire_semaphore, frame_time * 1e-6);
acquire_semaphore.reset();

swapchain_frame_index ^= 1;
}

void libretro_end_frame(retro_video_refresh_t video_cb, Vulkan::WSI &wsi)
Expand Down Expand Up @@ -198,14 +178,7 @@ bool libretro_context_reset(retro_hw_render_interface_vulkan *vulkan, Vulkan::WS
vulkan->unlock_queue(vulkan->handle);
});

unsigned num_images = 0;
auto sync_mask = vulkan->get_sync_index_mask(vulkan->handle);
for (unsigned i = 0; i < 32; i++)
{
if (sync_mask & (1u << i))
num_images = i + 1;
}
num_swapchain_images = num_images;
const unsigned num_swapchain_images = 2;

Vulkan::ImageCreateInfo info = Vulkan::ImageCreateInfo::render_target(swapchain_width, swapchain_height,
VK_FORMAT_R8G8B8A8_SRGB);
Expand All @@ -223,9 +196,10 @@ bool libretro_context_reset(retro_hw_render_interface_vulkan *vulkan, Vulkan::WS
swapchain_unorm_view = wsi.get_device().create_image_view(view_info);

std::vector<Vulkan::ImageHandle> images;
for (unsigned i = 0; i < num_images; i++)
for (unsigned i = 0; i < num_swapchain_images; i++)
images.push_back(swapchain_image);

wsi.get_device().init_frame_contexts(2);
if (!wsi.init_external_swapchain(std::move(images)))
return false;

Expand All @@ -243,6 +217,7 @@ bool libretro_context_reset(retro_hw_render_interface_vulkan *vulkan, Vulkan::WS
swapchain_image_info.create_info.subresourceRange.levelCount = 1;
swapchain_image_info.create_info.subresourceRange.layerCount = 1;
swapchain_image_info.create_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
swapchain_frame_index = 0;
return true;
}

Expand Down
2 changes: 1 addition & 1 deletion renderer/render_queue.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ class RenderQueue
uintptr_t begin = 0;
uintptr_t end = 0;

Block(size_t size)
explicit Block(size_t size)
{
buffer.resize(size);
begin = reinterpret_cast<uintptr_t>(buffer.data());
Expand Down
9 changes: 9 additions & 0 deletions vulkan/buffer_pool.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ void BufferPool::init(Device *device, VkDeviceSize block_size, VkDeviceSize alig
this->need_device_local = need_device_local;
}

BufferBlock::~BufferBlock()
{
}

void BufferPool::reset()
{
blocks.clear();
Expand Down Expand Up @@ -105,4 +109,9 @@ void BufferPool::recycle_block(BufferBlock &&block)
blocks.push_back(move(block));
}

BufferPool::~BufferPool()
{
VK_ASSERT(blocks.empty());
}

}
2 changes: 2 additions & 0 deletions vulkan/buffer_pool.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ struct BufferBlockAllocation

struct BufferBlock
{
~BufferBlock();
Util::IntrusivePtr<Buffer> gpu;
Util::IntrusivePtr<Buffer> cpu;
VkDeviceSize offset = 0;
Expand All @@ -63,6 +64,7 @@ struct BufferBlock
class BufferPool
{
public:
~BufferPool();
void init(Device *device, VkDeviceSize block_size, VkDeviceSize alignment, VkBufferUsageFlags usage, bool need_device_local);
void reset();

Expand Down
Loading

0 comments on commit 5215453

Please sign in to comment.