Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Vk validation fixes, plus PowerVR swapchain hack #11747

Merged
merged 6 commits into from
Jan 26, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 9 additions & 10 deletions Common/FileUtil.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -652,7 +652,6 @@ bool DeleteDirRecursively(const std::string &directory)

if (hFind == INVALID_HANDLE_VALUE)
{
FindClose(hFind);
return false;
}

Expand All @@ -671,7 +670,6 @@ bool DeleteDirRecursively(const std::string &directory)
{
const std::string virtualName = result->d_name;
#endif

// check for "." and ".."
if (((virtualName[0] == '.') && (virtualName[1] == '\0')) ||
((virtualName[0] == '.') && (virtualName[1] == '.') &&
Expand All @@ -683,21 +681,23 @@ bool DeleteDirRecursively(const std::string &directory)
{
if (!DeleteDirRecursively(newPath))
{
#ifndef _WIN32
#ifndef _WIN32
closedir(dirp);
#endif

#else
FindClose(hFind);
#endif
return false;
}
}
else
{
if (!File::Delete(newPath))
{
#ifndef _WIN32
#ifndef _WIN32
closedir(dirp);
#endif

#else
FindClose(hFind);
#endif
return false;
}
}
Expand All @@ -709,8 +709,7 @@ bool DeleteDirRecursively(const std::string &directory)
}
closedir(dirp);
#endif
File::DeleteDir(directory);
return true;
return File::DeleteDir(directory);
#endif
}

Expand Down
103 changes: 47 additions & 56 deletions Common/Vulkan/VulkanContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -505,15 +505,18 @@ void VulkanContext::ChooseDevice(int physical_device) {
ELOG("Could not find a usable depth stencil format.");
}

// This is as good a place as any to do this
// This is as good a place as any to do this.
vkGetPhysicalDeviceMemoryProperties(physical_devices_[physical_device_], &memory_properties);
ILOG("Memory Types (%d):", memory_properties.memoryTypeCount);
for (int i = 0; i < memory_properties.memoryTypeCount; i++) {
for (int i = 0; i < (int)memory_properties.memoryTypeCount; i++) {
// Don't bother printing dummy memory types.
if (!memory_properties.memoryTypes[i].propertyFlags)
continue;
ILOG(" %d: Heap %d; Flags: %s%s%s%s ", i, memory_properties.memoryTypes[i].heapIndex,
(memory_properties.memoryTypes[i].propertyFlags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) ? "DEVICE_LOCAL_BIT" : "",
(memory_properties.memoryTypes[i].propertyFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) ? "HOST_VISIBLE_BIT" : "",
(memory_properties.memoryTypes[i].propertyFlags & VK_MEMORY_PROPERTY_HOST_CACHED_BIT) ? "HOST_CACHED_BIT" : "",
(memory_properties.memoryTypes[i].propertyFlags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT) ? "HOST_COHERENT_BIT" : "");
(memory_properties.memoryTypes[i].propertyFlags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) ? "DEVICE_LOCAL " : "",
(memory_properties.memoryTypes[i].propertyFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) ? "HOST_VISIBLE " : "",
(memory_properties.memoryTypes[i].propertyFlags & VK_MEMORY_PROPERTY_HOST_CACHED_BIT) ? "HOST_CACHED " : "",
(memory_properties.memoryTypes[i].propertyFlags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT) ? "HOST_COHERENT " : "");
}

// Optional features
Expand Down Expand Up @@ -585,7 +588,9 @@ VkResult VulkanContext::CreateDevice() {
}
assert(found);

deviceExtensionsLookup_.DEDICATED_ALLOCATION = EnableDeviceExtension(VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME);
if (EnableDeviceExtension(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME)) {
deviceExtensionsLookup_.DEDICATED_ALLOCATION = EnableDeviceExtension(VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME);
}

VkDeviceCreateInfo device_info{ VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO };
device_info.queueCreateInfoCount = 1;
Expand Down Expand Up @@ -642,43 +647,30 @@ void VulkanContext::DestroyDebugMsgCallback() {
}
}

void VulkanContext::InitSurface(WindowSystem winsys, void *data1, void *data2, int width, int height) {
VkResult VulkanContext::InitSurface(WindowSystem winsys, void *data1, void *data2) {
winsys_ = winsys;
winsysData1_ = data1;
winsysData2_ = data2;
ReinitSurface(width, height);
return ReinitSurface();
}

void VulkanContext::ReinitSurface(int width, int height) {
VkResult VulkanContext::ReinitSurface() {
if (surface_ != VK_NULL_HANDLE) {
ILOG("Destroying Vulkan surface (%d, %d)", width_, height_);
ILOG("Destroying Vulkan surface (%d, %d)", swapChainExtent_.width, swapChainExtent_.height);
vkDestroySurfaceKHR(instance_, surface_, nullptr);
surface_ = VK_NULL_HANDLE;
}

ILOG("Creating Vulkan surface (%d, %d)", width, height);
ILOG("Creating Vulkan surface for window");
switch (winsys_) {
#ifdef _WIN32
case WINDOWSYSTEM_WIN32:
{
HINSTANCE connection = (HINSTANCE)winsysData1_;
HWND window = (HWND)winsysData2_;

if (width < 0 || height < 0)
{
RECT rc;
GetClientRect(window, &rc);
width = rc.right - rc.left;
height = rc.bottom - rc.top;
}

VkWin32SurfaceCreateInfoKHR win32{ VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR };
win32.flags = 0;
win32.hwnd = window;
win32.hinstance = connection;
VkResult res = vkCreateWin32SurfaceKHR(instance_, &win32, nullptr, &surface_);
assert(res == VK_SUCCESS);
break;
win32.hwnd = (HWND)winsysData2_;
win32.hinstance = (HINSTANCE)winsysData1_;
return vkCreateWin32SurfaceKHR(instance_, &win32, nullptr, &surface_);
}
#endif
#if defined(__ANDROID__)
Expand All @@ -688,9 +680,7 @@ void VulkanContext::ReinitSurface(int width, int height) {
VkAndroidSurfaceCreateInfoKHR android{ VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR };
android.flags = 0;
android.window = wnd;
VkResult res = vkCreateAndroidSurfaceKHR(instance_, &android, nullptr, &surface_);
assert(res == VK_SUCCESS);
break;
return vkCreateAndroidSurfaceKHR(instance_, &android, nullptr, &surface_);
}
#endif
#if defined(VK_USE_PLATFORM_XLIB_KHR)
Expand All @@ -700,9 +690,7 @@ void VulkanContext::ReinitSurface(int width, int height) {
xlib.flags = 0;
xlib.dpy = (Display *)winsysData1_;
xlib.window = (Window)winsysData2_;
VkResult res = vkCreateXlibSurfaceKHR(instance_, &xlib, nullptr, &surface_);
assert(res == VK_SUCCESS);
break;
return vkCreateXlibSurfaceKHR(instance_, &xlib, nullptr, &surface_);
}
#endif
#if defined(VK_USE_PLATFORM_XCB_KHR)
Expand All @@ -712,9 +700,7 @@ void VulkanContext::ReinitSurface(int width, int height) {
xcb.flags = 0;
xcb.connection = (Connection *)winsysData1_;
xcb.window = (Window)(uintptr_t)winsysData2_;
VkResult res = vkCreateXcbSurfaceKHR(instance_, &xcb, nullptr, &surface_);
assert(res == VK_SUCCESS);
break;
return vkCreateXcbSurfaceKHR(instance_, &xcb, nullptr, &surface_);
}
#endif
#if defined(VK_USE_PLATFORM_WAYLAND_KHR)
Expand All @@ -724,18 +710,14 @@ void VulkanContext::ReinitSurface(int width, int height) {
wayland.flags = 0;
wayland.display = (wl_display *)winsysData1_;
wayland.surface = (wl_surface *)winsysData2_;
VkResult res = vkCreateWaylandSurfaceKHR(instance_, &wayland, nullptr, &surface_);
assert(res == VK_SUCCESS);
break;
return vkCreateWaylandSurfaceKHR(instance_, &wayland, nullptr, &surface_);
}
#endif

default:
_assert_msg_(G3D, false, "Vulkan support for chosen window system not implemented");
break;
return VK_ERROR_INITIALIZATION_FAILED;
}
width_ = width;
height_ = height;
}

bool VulkanContext::InitQueue() {
Expand Down Expand Up @@ -826,6 +808,14 @@ bool VulkanContext::InitQueue() {
return true;
}

int clamp(int x, int a, int b) {
if (x < a)
return a;
if (x > b)
return b;
return x;
}

bool VulkanContext::InitSwapchain() {
VkResult res = vkGetPhysicalDeviceSurfaceCapabilitiesKHR(physical_devices_[physical_device_], surface_, &surfCapabilities_);
assert(res == VK_SUCCESS);
Expand All @@ -837,19 +827,20 @@ bool VulkanContext::InitSwapchain() {
res = vkGetPhysicalDeviceSurfacePresentModesKHR(physical_devices_[physical_device_], surface_, &presentModeCount, presentModes);
assert(res == VK_SUCCESS);

VkExtent2D swapChainExtent;
// width and height are either both -1, or both not -1.
if (surfCapabilities_.currentExtent.width == (uint32_t)-1) {
// If the surface size is undefined, the size is set to
// the size of the images requested.
ILOG("initSwapchain: %dx%d", width_, height_);
swapChainExtent.width = width_;
swapChainExtent.height = height_;
} else {
// If the surface size is defined, the swap chain size must match
swapChainExtent = surfCapabilities_.currentExtent;
ILOG("surfCapabilities_.currentExtent: %dx%d", surfCapabilities_.currentExtent.width, surfCapabilities_.currentExtent.height);
ILOG("surfCapabilities_.minImageExtent: %dx%d", surfCapabilities_.minImageExtent.width, surfCapabilities_.minImageExtent.height);
ILOG("surfCapabilities_.maxImageExtent: %dx%d", surfCapabilities_.maxImageExtent.width, surfCapabilities_.maxImageExtent.height);

swapChainExtent_.width = clamp(surfCapabilities_.currentExtent.width, surfCapabilities_.minImageExtent.width, surfCapabilities_.maxImageExtent.width);
swapChainExtent_.height = clamp(surfCapabilities_.currentExtent.height, surfCapabilities_.minImageExtent.height, surfCapabilities_.maxImageExtent.height);

if (physicalDeviceProperties_[physical_device_].vendorID == VULKAN_VENDOR_IMGTEC) {
// Swap chain width hack to avoid issue #11743 (PowerVR driver bug).
swapChainExtent_.width &= ~31;
}

ILOG("swapChainExtent: %dx%d", swapChainExtent_.width, swapChainExtent_.height);

// TODO: Find a better way to specify the prioritized present mode while being able
// to fall back in a sensible way.
VkPresentModeKHR swapchainPresentMode = VK_PRESENT_MODE_MAX_ENUM_KHR;
Expand Down Expand Up @@ -904,8 +895,8 @@ bool VulkanContext::InitSwapchain() {
swap_chain_info.minImageCount = desiredNumberOfSwapChainImages;
swap_chain_info.imageFormat = swapchainFormat_;
swap_chain_info.imageColorSpace = VK_COLORSPACE_SRGB_NONLINEAR_KHR;
swap_chain_info.imageExtent.width = swapChainExtent.width;
swap_chain_info.imageExtent.height = swapChainExtent.height;
swap_chain_info.imageExtent.width = swapChainExtent_.width;
swap_chain_info.imageExtent.height = swapChainExtent_.height;
swap_chain_info.preTransform = preTransform;
swap_chain_info.imageArrayLayers = 1;
swap_chain_info.presentMode = swapchainPresentMode;
Expand Down
15 changes: 8 additions & 7 deletions Common/Vulkan/VulkanContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -142,8 +142,9 @@ class VulkanContext {
VulkanDeleteList &Delete() { return globalDeleteList_; }

// The parameters are whatever the chosen window system wants.
void InitSurface(WindowSystem winsys, void *data1, void *data2, int width = -1, int height = -1);
void ReinitSurface(int width = -1, int height = -1);
// The extents will be automatically determined.
VkResult InitSurface(WindowSystem winsys, void *data1, void *data2);
VkResult ReinitSurface();

bool InitQueue();
bool InitObjects();
Expand All @@ -160,8 +161,8 @@ class VulkanContext {
VkFence CreateFence(bool presignalled);
bool CreateShaderModule(const std::vector<uint32_t> &spirv, VkShaderModule *shaderModule);

int GetBackbufferWidth() { return width_; }
int GetBackbufferHeight() { return height_; }
int GetBackbufferWidth() { return (int)swapChainExtent_.width; }
int GetBackbufferHeight() { return (int)swapChainExtent_.height; }

void BeginFrame();
void EndFrame();
Expand Down Expand Up @@ -295,9 +296,9 @@ class VulkanContext {
// Custom collection of things that are good to know
VulkanPhysicalDeviceInfo deviceInfo_{};

// Swap chain
int width_ = 0;
int height_ = 0;
// Swap chain extent
VkExtent2D swapChainExtent_{};

int flags_ = 0;

int inflightFrames_ = MAX_INFLIGHT_FRAMES;
Expand Down
2 changes: 0 additions & 2 deletions Common/Vulkan/VulkanDebug.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,6 @@ VkBool32 VKAPI_CALL Vulkan_Dbg(VkDebugReportFlagsEXT msgFlags, VkDebugReportObje
return false;
if (msgCode == 5)
return false; // Not exactly a false positive, see https://github.com/KhronosGroup/glslang/issues/1418
if (msgCode == 0 && strstr(pMsg, "vertexPipelineStoresAndAtomics")) // https://github.com/KhronosGroup/Vulkan-ValidationLayers/issues/73
return false;
#ifdef _WIN32
std::string msg = message.str();
OutputDebugStringA(msg.c_str());
Expand Down
9 changes: 2 additions & 7 deletions Common/Vulkan/VulkanImage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,11 +76,8 @@ bool VulkanTexture::CreateDirect(VkCommandBuffer cmd, int w, int h, int numMips,

if (allocator_) {
offset_ = allocator_->Allocate(mem_reqs, &mem_, Tag());
if (offset_ == VulkanDeviceAllocator::ALLOCATE_FAILED) {
vkDestroyImage(vulkan_->GetDevice(), image_, nullptr);
ELOG("Image memory allocation failed (mem_reqs.size = %d)", (int)mem_reqs.size);
return false;
}
// Destructor will take care of the image.
return false;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wait, shouldn't this be inside the ALLOCATE_FAILED if?

-[Unknown]

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oops what happened here.. sloppy editing. I'll fix soon.

} else {
VkMemoryAllocateInfo mem_alloc{ VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO };
mem_alloc.memoryTypeIndex = 0;
Expand All @@ -95,8 +92,6 @@ bool VulkanTexture::CreateDirect(VkCommandBuffer cmd, int w, int h, int numMips,
ELOG("vkAllocateMemory failed: %s", VulkanResultToString(res));
_assert_msg_(G3D, res != VK_ERROR_TOO_MANY_OBJECTS, "Too many Vulkan memory objects!");
_assert_(res == VK_ERROR_OUT_OF_HOST_MEMORY || res == VK_ERROR_OUT_OF_DEVICE_MEMORY || res == VK_ERROR_TOO_MANY_OBJECTS);
vkDestroyImage(vulkan_->GetDevice(), image_, nullptr);
image_ = VK_NULL_HANDLE;
return false;
}

Expand Down
9 changes: 6 additions & 3 deletions GPU/Vulkan/PipelineManagerVulkan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -112,12 +112,14 @@ static int SetupVertexAttribs(VkVertexInputAttributeDescription attrs[], const D
return count;
}

static int SetupVertexAttribsPretransformed(VkVertexInputAttributeDescription attrs[]) {
static int SetupVertexAttribsPretransformed(VkVertexInputAttributeDescription attrs[], bool needsColor1) {
int count = 0;
VertexAttribSetup(&attrs[count++], DEC_FLOAT_4, 0, PspAttributeLocation::POSITION);
VertexAttribSetup(&attrs[count++], DEC_FLOAT_3, 16, PspAttributeLocation::TEXCOORD);
VertexAttribSetup(&attrs[count++], DEC_U8_4, 28, PspAttributeLocation::COLOR0);
VertexAttribSetup(&attrs[count++], DEC_U8_4, 32, PspAttributeLocation::COLOR1);
if (needsColor1) {
VertexAttribSetup(&attrs[count++], DEC_U8_4, 32, PspAttributeLocation::COLOR1);
}
return count;
}

Expand Down Expand Up @@ -243,7 +245,8 @@ static VulkanPipeline *CreateVulkanPipeline(VkDevice device, VkPipelineCache pip
attributeCount = SetupVertexAttribs(attrs, *decFmt);
vertexStride = decFmt->stride;
} else {
attributeCount = SetupVertexAttribsPretransformed(attrs);
bool needsColor1 = vs->GetID().Bit(FS_BIT_LMODE);
attributeCount = SetupVertexAttribsPretransformed(attrs, needsColor1);
vertexStride = 36;
}

Expand Down
7 changes: 3 additions & 4 deletions SDL/SDLVulkanGraphicsContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,16 +63,15 @@ bool SDLVulkanGraphicsContext::Init(SDL_Window *&window, int x, int y, int mode,
case SDL_SYSWM_X11:
#if defined(VK_USE_PLATFORM_XLIB_KHR)
vulkan_->InitSurface(WINDOWSYSTEM_XLIB, (void*)sys_info.info.x11.display,
(void *)(intptr_t)sys_info.info.x11.window, pixel_xres, pixel_yres);
(void *)(intptr_t)sys_info.info.x11.window);
#elif defined(VK_USE_PLATFORM_XCB_KHR)
vulkan_->InitSurface(WINDOWSYSTEM_XCB, (void*)XGetXCBConnection(sys_info.info.x11.display),
(void *)(intptr_t)sys_info.info.x11.window, pixel_xres, pixel_yres);
(void *)(intptr_t)sys_info.info.x11.window);
#endif
break;
#if defined(VK_USE_PLATFORM_WAYLAND_KHR)
case SDL_SYSWM_WAYLAND:
vulkan_->InitSurface(WINDOWSYSTEM_WAYLAND, (void*)sys_info.info.wl.display,
(void *)sys_info.info.wl.surface, pixel_xres, pixel_yres);
vulkan_->InitSurface(WINDOWSYSTEM_WAYLAND, (void*)sys_info.info.wl.display, (void *)sys_info.info.wl.surface);
break;
#endif
default:
Expand Down
12 changes: 3 additions & 9 deletions android/jni/AndroidVulkanContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -135,14 +135,8 @@ bool AndroidVulkanContext::InitAPI() {
}

bool AndroidVulkanContext::InitFromRenderThread(ANativeWindow *wnd, int desiredBackbufferSizeX, int desiredBackbufferSizeY, int backbufferFormat, int androidVersion) {
int width = desiredBackbufferSizeX;
int height = desiredBackbufferSizeY;
if (!width || !height) {
width = pixel_xres;
height = pixel_yres;
}
ILOG("InitSurfaceAndroid: width=%d height=%d", width, height);
g_Vulkan->InitSurface(WINDOWSYSTEM_ANDROID, (void *)wnd, nullptr, width, height);
ILOG("InitSurfaceAndroid: desiredwidth=%d desiredheight=%d", desiredBackbufferSizeX, desiredBackbufferSizeY);
g_Vulkan->InitSurface(WINDOWSYSTEM_ANDROID, (void *)wnd, nullptr);
if (g_validate_) {
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);
Expand Down Expand Up @@ -205,7 +199,7 @@ void AndroidVulkanContext::Resize() {
g_Vulkan->DestroyObjects();

// backbufferResize updated these values. TODO: Notify another way?
g_Vulkan->ReinitSurface(pixel_xres, pixel_yres);
g_Vulkan->ReinitSurface();
g_Vulkan->InitObjects();
draw_->HandleEvent(Draw::Event::GOT_BACKBUFFER, g_Vulkan->GetBackbufferWidth(), g_Vulkan->GetBackbufferHeight());
ILOG("AndroidVulkanContext::Resize end (%d, %d)", g_Vulkan->GetBackbufferWidth(), g_Vulkan->GetBackbufferHeight());
Expand Down
Loading