Permalink
Browse files

Merge pull request #10111 from unknownbrackets/vulkan-minor

Vulkan: Cut down on asserts during init
  • Loading branch information...
hrydgard committed Nov 13, 2017
2 parents a1b3a43 + d2d5b8e commit c3c4ec4cc971f5ce1391e5ef72d299d79cedac90
@@ -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();
@@ -177,7 +177,7 @@ void GameSettingsScreen::CreateViews() {
tabHolder->AddTab(ms->T("Graphics"), graphicsSettingsScroll);
graphicsSettings->Add(new ItemHeader(gr->T("Rendering Mode")));
static const char *renderingBackend[] = { "OpenGL", "Direct3D 9", "Direct3D 11", "Vulkan (experimental)" };
static const char *renderingBackend[] = { "OpenGL", "Direct3D 9", "Direct3D 11", "Vulkan" };
PopupMultiChoice *renderingBackendChoice = graphicsSettings->Add(new PopupMultiChoice(&g_Config.iGPUBackend, gr->T("Backend"), renderingBackend, GPU_BACKEND_OPENGL, ARRAY_SIZE(renderingBackend), gr->GetName(), screenManager()));
renderingBackendChoice->OnChoice.Handle(this, &GameSettingsScreen::OnRenderingBackend);
#if !PPSSPP_PLATFORM(WINDOWS)
@@ -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 c3c4ec4

Please sign in to comment.