Permalink
Browse files

Vulkan: Cut down on asserts during init.

In case something is horribly wrong, or our desired settings aren't
compatible, let's try to stumble our way out.

More things can fail, but the goal is to detect failure or at least be
able to render UI settings to swap out of Vulkan.
  • Loading branch information...
unknownbrackets committed Nov 13, 2017
1 parent d4c345c commit b1554ef0615ddb7a1e4803ab59374f27c5b1a62e
@@ -220,7 +220,9 @@ bool VulkanContext::MemoryTypeFromProperties(uint32_t typeBits, VkFlags requirem
}
bool VulkanContext::InitObjects() {
InitQueue();
if (!InitQueue()) {
return false;
}
if (!InitSwapchain()) {
return false;
@@ -616,7 +618,7 @@ void VulkanContext::ReinitSurfaceAndroid(int width, int height) {
}
#endif
void VulkanContext::InitQueue() {
bool VulkanContext::InitQueue() {
// Iterate over each queue to learn whether it supports presenting:
VkBool32 *supportsPresent = new VkBool32[queue_count];
for (uint32_t i = 0; i < queue_count; i++) {
@@ -654,8 +656,8 @@ void VulkanContext::InitQueue() {
// Generate error if could not find both a graphics and a present queue
if (graphicsQueueNodeIndex == UINT32_MAX || presentQueueNodeIndex == UINT32_MAX) {
std::cout << "Could not find a graphics and a present queue";
exit(-1);
ELOG("Could not find a graphics and a present queue");
return false;
}
graphics_queue_family_index_ = graphicsQueueNodeIndex;
@@ -664,9 +666,15 @@ void VulkanContext::InitQueue() {
uint32_t formatCount;
VkResult res = vkGetPhysicalDeviceSurfaceFormatsKHR(physical_devices_[physical_device_], surface_, &formatCount, nullptr);
assert(res == VK_SUCCESS);
if (res != VK_SUCCESS)
return false;
VkSurfaceFormatKHR *surfFormats = new VkSurfaceFormatKHR[formatCount];
res = vkGetPhysicalDeviceSurfaceFormatsKHR(physical_devices_[physical_device_], surface_, &formatCount, surfFormats);
assert(res == VK_SUCCESS);
if (res != VK_SUCCESS) {
delete[] surfFormats;
return false;
}
// If the format list includes just one entry of VK_FORMAT_UNDEFINED,
// the surface has no preferred format. Otherwise, at least one
// supported format will be returned.
@@ -695,6 +703,7 @@ void VulkanContext::InitQueue() {
vkGetDeviceQueue(device_, graphics_queue_family_index_, 0, &gfx_queue_);
ILOG("gfx_queue_: %p", gfx_queue_);
return true;
}
bool VulkanContext::InitSwapchain() {
@@ -141,7 +141,7 @@ class VulkanContext {
void InitSurfaceAndroid(ANativeWindow *native_window, int width, int height);
void ReinitSurfaceAndroid(int width, int height);
#endif
void InitQueue();
bool InitQueue();
bool InitObjects();
bool InitSwapchain();
@@ -56,6 +56,7 @@
#include "base/stringutil.h"
#include "thin3d/thin3d.h"
#include "thin3d/VulkanRenderManager.h"
#include "util/text/parsers.h"
#include "Windows/GPU/WindowsVulkanContext.h"
@@ -204,6 +205,12 @@ bool WindowsVulkanContext::Init(HINSTANCE hInst, HWND hWnd, std::string *error_m
bool success = draw_->CreatePresets();
assert(success); // Doesn't fail, we include the compiler.
draw_->HandleEvent(Draw::Event::GOT_BACKBUFFER, g_Vulkan->GetBackbufferWidth(), g_Vulkan->GetBackbufferHeight());
VulkanRenderManager *renderManager = (VulkanRenderManager *)draw_->GetNativeObject(Draw::NativeObject::RENDER_MANAGER);
if (!renderManager->HasBackbuffers()) {
Shutdown();
return false;
}
return true;
}
@@ -38,6 +38,7 @@
#include "gfx_es2/gpu_features.h"
#include "thin3d/thin3d.h"
#include "thin3d/VulkanRenderManager.h"
#include "Core/Config.h"
#include "Core/Loaders.h"
#include "Core/System.h"
@@ -326,13 +327,29 @@ bool AndroidVulkanContext::Init(ANativeWindow *wnd, int desiredBackbufferSizeX,
int bits = VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT | VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT;
g_Vulkan->InitDebugMsgCallback(&Vulkan_Dbg, bits, &g_LogOptions);
}
g_Vulkan->InitObjects();
draw_ = Draw::T3DCreateVulkanContext(g_Vulkan);
bool success = draw_->CreatePresets(); // Doesn't fail, we ship the compiler.
assert(success);
draw_->HandleEvent(Draw::Event::GOT_BACKBUFFER, g_Vulkan->GetBackbufferWidth(), g_Vulkan->GetBackbufferHeight());
ILOG("AndroidVulkanContext::Init completed");
return true;
bool success = true;
if (g_Vulkan->InitObjects()) {
draw_ = Draw::T3DCreateVulkanContext(g_Vulkan);
success = draw_->CreatePresets(); // Doesn't fail, we ship the compiler.
assert(success);
draw_->HandleEvent(Draw::Event::GOT_BACKBUFFER, g_Vulkan->GetBackbufferWidth(), g_Vulkan->GetBackbufferHeight());
VulkanRenderManager *renderManager = (VulkanRenderManager *)draw_->GetNativeObject(Draw::NativeObject::RENDER_MANAGER);
success = renderManager->HasBackbuffers();
} else {
success = false;
}
ILOG("AndroidVulkanContext::Init completed, %s", success ? "successfully" : "but failed");
if (!success) {
g_Vulkan->DestroyObjects();
g_Vulkan->DestroyDevice();
g_Vulkan->DestroyDebugMsgCallback();
g_Vulkan->DestroyInstance();
}
return success;
}
void AndroidVulkanContext::Shutdown() {
@@ -133,9 +133,13 @@ void VulkanRenderManager::CreateBackbuffers() {
VkResult res = vkGetSwapchainImagesKHR(vulkan_->GetDevice(), vulkan_->GetSwapchain(), &swapchainImageCount_, nullptr);
assert(res == VK_SUCCESS);
VkImage* swapchainImages = new VkImage[swapchainImageCount_];
VkImage *swapchainImages = new VkImage[swapchainImageCount_];
res = vkGetSwapchainImagesKHR(vulkan_->GetDevice(), vulkan_->GetSwapchain(), &swapchainImageCount_, swapchainImages);
assert(res == VK_SUCCESS);
if (res != VK_SUCCESS) {
delete[] swapchainImages;
return;
}
VkCommandBuffer cmdInit = GetInitCmd();
@@ -172,15 +176,19 @@ void VulkanRenderManager::CreateBackbuffers() {
}
delete[] swapchainImages;
InitDepthStencilBuffer(cmdInit); // Must be before InitBackbufferRenderPass.
InitBackbufferFramebuffers(vulkan_->GetBackbufferWidth(), vulkan_->GetBackbufferHeight());
// Must be before InitBackbufferRenderPass.
if (InitDepthStencilBuffer(cmdInit)) {
InitBackbufferFramebuffers(vulkan_->GetBackbufferWidth(), vulkan_->GetBackbufferHeight());
}
curWidth_ = -1;
curHeight_ = -1;
VLOG("Backbuffers Created");
if (HasBackbuffers()) {
VLOG("Backbuffers Created");
}
// Start the thread.
if (useThread) {
if (useThread && HasBackbuffers()) {
run_ = true;
// Won't necessarily be 0.
threadInitFrame_ = vulkan_->GetCurFrame();
@@ -453,8 +461,8 @@ void VulkanRenderManager::CopyImageToMemorySync(VkImage image, int mipLevel, int
queueRunner_.CopyReadbackBuffer(w, h, destFormat, destFormat, pixelStride, pixels);
}
void VulkanRenderManager::InitBackbufferFramebuffers(int width, int height) {
VkResult U_ASSERT_ONLY res;
bool VulkanRenderManager::InitBackbufferFramebuffers(int width, int height) {
VkResult res;
// We share the same depth buffer but have multiple color buffers, see the loop below.
VkImageView attachments[2] = { VK_NULL_HANDLE, depth_.view };
@@ -473,12 +481,18 @@ void VulkanRenderManager::InitBackbufferFramebuffers(int width, int height) {
attachments[0] = swapchainImages_[i].view;
res = vkCreateFramebuffer(vulkan_->GetDevice(), &fb_info, nullptr, &framebuffers_[i]);
assert(res == VK_SUCCESS);
if (res != VK_SUCCESS) {
framebuffers_.clear();
return false;
}
}
return true;
}
void VulkanRenderManager::InitDepthStencilBuffer(VkCommandBuffer cmd) {
VkResult U_ASSERT_ONLY res;
bool U_ASSERT_ONLY pass;
bool VulkanRenderManager::InitDepthStencilBuffer(VkCommandBuffer cmd) {
VkResult res;
bool pass;
const VkFormat depth_format = vulkan_->GetDeviceInfo().preferredDepthStencilFormat;
int aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
@@ -506,8 +520,10 @@ void VulkanRenderManager::InitDepthStencilBuffer(VkCommandBuffer cmd) {
depth_.format = depth_format;
VkDevice device = vulkan_->GetDevice();
res = vkCreateImage(device, &image_info, NULL, &depth_.image);
res = vkCreateImage(device, &image_info, nullptr, &depth_.image);
assert(res == VK_SUCCESS);
if (res != VK_SUCCESS)
return false;
vkGetImageMemoryRequirements(device, depth_.image, &mem_reqs);
@@ -517,12 +533,18 @@ void VulkanRenderManager::InitDepthStencilBuffer(VkCommandBuffer cmd) {
0, /* No requirements */
&mem_alloc.memoryTypeIndex);
assert(pass);
if (!pass)
return false;
res = vkAllocateMemory(device, &mem_alloc, NULL, &depth_.mem);
assert(res == VK_SUCCESS);
if (res != VK_SUCCESS)
return false;
res = vkBindImageMemory(device, depth_.image, depth_.mem, 0);
assert(res == VK_SUCCESS);
if (res != VK_SUCCESS)
return false;
TransitionImageLayout2(cmd, depth_.image,
aspectMask,
@@ -547,6 +569,10 @@ void VulkanRenderManager::InitDepthStencilBuffer(VkCommandBuffer cmd) {
res = vkCreateImageView(device, &depth_view_info, NULL, &depth_.view);
assert(res == VK_SUCCESS);
if (res != VK_SUCCESS)
return false;
return true;
}
void VulkanRenderManager::Clear(uint32_t clearColor, float clearZ, int clearStencil, int clearMask) {
@@ -204,9 +204,13 @@ class VulkanRenderManager {
void CreateBackbuffers();
void DestroyBackbuffers();
bool HasBackbuffers() {
return !framebuffers_.empty();
}
private:
void InitBackbufferFramebuffers(int width, int height);
void InitDepthStencilBuffer(VkCommandBuffer cmd); // Used for non-buffered rendering.
bool InitBackbufferFramebuffers(int width, int height);
bool InitDepthStencilBuffer(VkCommandBuffer cmd); // Used for non-buffered rendering.
void BeginSubmitFrame(int frame);
void EndSubmitFrame(int frame);
void Submit(int frame, bool triggerFence);

0 comments on commit b1554ef

Please sign in to comment.