[Vulkan v2] Swapchain ImageViews, error messages
This commit is contained in:
parent
be6fa2b577
commit
490f3de853
|
@ -215,6 +215,8 @@ bool VulkanContext::Initialize() {
|
|||
return false;
|
||||
}
|
||||
|
||||
// TODO(Triang3l): Presentation render pass.
|
||||
|
||||
// Initialize the immediate mode drawer if not offscreen.
|
||||
immediate_drawer_ = std::make_unique<VulkanImmediateDrawer>(this);
|
||||
if (!immediate_drawer_->Initialize()) {
|
||||
|
@ -240,6 +242,7 @@ void VulkanContext::Shutdown() {
|
|||
initialized_fully_ = false;
|
||||
|
||||
if (target_window_) {
|
||||
DestroySwapchainImages();
|
||||
util::DestroyAndNullHandle(vkDestroySwapchainKHR, device, swapchain_);
|
||||
|
||||
immediate_drawer_.reset();
|
||||
|
@ -257,6 +260,16 @@ void VulkanContext::Shutdown() {
|
|||
}
|
||||
}
|
||||
|
||||
void VulkanContext::DestroySwapchainImages() {
|
||||
auto device = GetVulkanProvider()->GetDevice();
|
||||
for (auto& image : swapchain_images_) {
|
||||
// TODO(Triang3l): Destroy the framebuffer.
|
||||
// vkDestroyFramebuffer(device, image.framebuffer, nullptr);
|
||||
vkDestroyImageView(device, image.image_view, nullptr);
|
||||
}
|
||||
swapchain_images_.clear();
|
||||
}
|
||||
|
||||
ImmediateDrawer* VulkanContext::immediate_drawer() {
|
||||
return immediate_drawer_.get();
|
||||
}
|
||||
|
@ -281,6 +294,7 @@ void VulkanContext::BeginSwap() {
|
|||
// submissions).
|
||||
if (vkWaitForFences(device, 1, &fences_[current_queue_frame_], VK_TRUE,
|
||||
UINT64_MAX) != VK_SUCCESS) {
|
||||
XELOGE("Failed to wait for the Vulkan fence the next frame");
|
||||
context_lost_ = true;
|
||||
return;
|
||||
}
|
||||
|
@ -321,6 +335,7 @@ void VulkanContext::BeginSwap() {
|
|||
// either the swapchain needs to be recreated in the next frame, or the
|
||||
// semaphore must be awaited right now (since suboptimal is a successful
|
||||
// result). Assume all other errors are fatal.
|
||||
XELOGE("Failed to acquire a Vulkan swapchain image");
|
||||
context_lost_ = true;
|
||||
return;
|
||||
}
|
||||
|
@ -332,7 +347,7 @@ void VulkanContext::BeginSwap() {
|
|||
return;
|
||||
}
|
||||
}
|
||||
// TODO(Triang3l): Destroy the old pass, framebuffer and image views.
|
||||
DestroySwapchainImages();
|
||||
// Destroying the old swapchain after creating the new one because
|
||||
// swapchain creation needs the old one.
|
||||
VkSwapchainKHR swapchain;
|
||||
|
@ -357,6 +372,8 @@ void VulkanContext::BeginSwap() {
|
|||
swapchain_create_info.oldSwapchain = swapchain_;
|
||||
if (vkCreateSwapchainKHR(device, &swapchain_create_info, nullptr,
|
||||
&swapchain) != VK_SUCCESS) {
|
||||
XELOGE("Failed to create a %ux%u Vulkan swap chain",
|
||||
target_window_extent.width, target_window_extent.height);
|
||||
context_lost_ = true;
|
||||
return;
|
||||
}
|
||||
|
@ -366,16 +383,62 @@ void VulkanContext::BeginSwap() {
|
|||
swapchain_ = swapchain;
|
||||
swapchain_extent_ = target_window_extent;
|
||||
surface_transform_ = current_transform;
|
||||
// TODO(Triang3l): Get images, create the framebuffer and the passes.
|
||||
uint32_t swapchain_image_count;
|
||||
if (vkGetSwapchainImagesKHR(device, swapchain_, &swapchain_image_count,
|
||||
nullptr) != VK_SUCCESS) {
|
||||
XELOGE("Failed to get Vulkan swapchain image count");
|
||||
context_lost_ = true;
|
||||
return;
|
||||
}
|
||||
std::vector<VkImage> swapchain_images;
|
||||
swapchain_images.resize(swapchain_image_count);
|
||||
if (vkGetSwapchainImagesKHR(device, swapchain_, &swapchain_image_count,
|
||||
swapchain_images.data()) != VK_SUCCESS) {
|
||||
XELOGE("Failed to get Vulkan swapchain images");
|
||||
context_lost_ = true;
|
||||
return;
|
||||
}
|
||||
swapchain_images_.reserve(swapchain_image_count);
|
||||
for (uint32_t i = 0; i < swapchain_image_count; ++i) {
|
||||
SwapchainImage swapchain_image;
|
||||
swapchain_image.image = swapchain_images[i];
|
||||
VkImageViewCreateInfo image_view_create_info;
|
||||
image_view_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
|
||||
image_view_create_info.pNext = nullptr;
|
||||
image_view_create_info.flags = 0;
|
||||
image_view_create_info.image = swapchain_image.image;
|
||||
image_view_create_info.viewType = VK_IMAGE_VIEW_TYPE_2D;
|
||||
image_view_create_info.format = surface_format_.format;
|
||||
image_view_create_info.components.r = VK_COMPONENT_SWIZZLE_IDENTITY;
|
||||
image_view_create_info.components.g = VK_COMPONENT_SWIZZLE_IDENTITY;
|
||||
image_view_create_info.components.b = VK_COMPONENT_SWIZZLE_IDENTITY;
|
||||
image_view_create_info.components.a = VK_COMPONENT_SWIZZLE_IDENTITY;
|
||||
image_view_create_info.subresourceRange.aspectMask =
|
||||
VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
image_view_create_info.subresourceRange.baseMipLevel = 0;
|
||||
image_view_create_info.subresourceRange.levelCount = 1;
|
||||
image_view_create_info.subresourceRange.baseArrayLayer = 0;
|
||||
image_view_create_info.subresourceRange.layerCount = 1;
|
||||
if (vkCreateImageView(device, &image_view_create_info, nullptr,
|
||||
&swapchain_image.image_view) != VK_SUCCESS) {
|
||||
XELOGE("Failed to create a Vulkan swapchain image view");
|
||||
context_lost_ = true;
|
||||
return;
|
||||
}
|
||||
// TODO(Triang3l): Create the VkFramebuffer.
|
||||
// Add now so it's complete if DestroySwapchainImages is called.
|
||||
swapchain_images_.push_back(swapchain_image);
|
||||
}
|
||||
VkResult acquire_result = vkAcquireNextImageKHR(
|
||||
device, swapchain_, UINT64_MAX, semaphore_present_complete_,
|
||||
VK_NULL_HANDLE, &swapchain_acquired_image_index_);
|
||||
if (acquire_result != VK_SUCCESS && acquire_result != VK_SUBOPTIMAL_KHR) {
|
||||
XELOGE("Failed to acquire a Vulkan swapchain image");
|
||||
context_lost_ = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
// TODO(Triang3l): Insert a barrier and clear.
|
||||
// TODO(Triang3l): Begin the pass.
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -388,8 +451,8 @@ void VulkanContext::EndSwap() {
|
|||
auto queue = provider->GetGraphicsQueue();
|
||||
|
||||
if (target_window_ != nullptr) {
|
||||
// TODO(Triang3l): End the pass.
|
||||
// Present.
|
||||
// TODO(Triang3l): Insert a barrier.
|
||||
VkSubmitInfo submit_info;
|
||||
submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
|
||||
submit_info.pNext = nullptr;
|
||||
|
@ -401,6 +464,7 @@ void VulkanContext::EndSwap() {
|
|||
submit_info.signalSemaphoreCount = 1;
|
||||
submit_info.pSignalSemaphores = &semaphore_draw_complete_;
|
||||
if (vkQueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE) != VK_SUCCESS) {
|
||||
XELOGE("Failed to submit the presentation command buffer");
|
||||
context_lost_ = true;
|
||||
return;
|
||||
}
|
||||
|
@ -419,6 +483,7 @@ void VulkanContext::EndSwap() {
|
|||
// VK_ERROR_OUT_OF_DATE_KHR will be handled in the next BeginSwap. In case
|
||||
// of it, the semaphore will be unsignaled anyway:
|
||||
// https://github.com/KhronosGroup/Vulkan-Docs/issues/572
|
||||
XELOGE("Failed to present the image");
|
||||
context_lost_ = true;
|
||||
return;
|
||||
}
|
||||
|
@ -429,6 +494,7 @@ void VulkanContext::EndSwap() {
|
|||
vkResetFences(provider->GetDevice(), 1, &fence);
|
||||
if (vkQueueSubmit(queue, 0, nullptr, fences_[current_queue_frame_]) !=
|
||||
VK_SUCCESS) {
|
||||
XELOGE("Failed to signal a Vulkan frame fence");
|
||||
context_lost_ = true;
|
||||
return;
|
||||
}
|
||||
|
@ -456,6 +522,7 @@ void VulkanContext::AwaitAllFramesCompletion() {
|
|||
}
|
||||
if (vkWaitForFences(device, 1, &fences_[await_frame], VK_TRUE, UINT64_MAX) !=
|
||||
VK_SUCCESS) {
|
||||
XELOGE("Failed to wait for the Vulkan fence the last frame");
|
||||
context_lost_ = true;
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#define XENIA_UI_VK_VULKAN_CONTEXT_H_
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "xenia/ui/graphics_context.h"
|
||||
#include "xenia/ui/vk/vulkan_immediate_drawer.h"
|
||||
|
@ -62,6 +63,8 @@ class VulkanContext : public GraphicsContext {
|
|||
bool Initialize();
|
||||
void Shutdown();
|
||||
|
||||
void DestroySwapchainImages();
|
||||
|
||||
bool initialized_fully_ = false;
|
||||
|
||||
bool context_lost_ = false;
|
||||
|
@ -88,6 +91,12 @@ class VulkanContext : public GraphicsContext {
|
|||
|
||||
VkSwapchainKHR swapchain_ = VK_NULL_HANDLE;
|
||||
VkExtent2D swapchain_extent_ = {};
|
||||
struct SwapchainImage {
|
||||
VkImage image;
|
||||
VkImageView image_view;
|
||||
VkFramebuffer framebuffer;
|
||||
};
|
||||
std::vector<SwapchainImage> swapchain_images_;
|
||||
uint32_t swapchain_acquired_image_index_ = 0;
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue