Permalink
Browse files

Merge pull request #9935 from hrydgard/vulkan-init-fixes

Vulkan init refactor
  • Loading branch information...
hrydgard committed Aug 28, 2017
2 parents 4938ab7 + 21d8561 commit 966cbd3ebcb63b5b1ab3ab47b8516204e0fad1a3

Large diffs are not rendered by default.

Oops, something went wrong.
@@ -43,13 +43,6 @@ enum {
VULKAN_FLAG_PRESENT_FIFO_RELAXED = 8,
};
// A layer can expose extensions, keep track of those extensions here.
struct layer_properties {
VkLayerProperties properties;
std::vector<VkExtensionProperties> extensions;
};
struct VulkanPhysicalDeviceInfo {
VkFormat preferredDepthStencilFormat;
};
@@ -206,10 +199,16 @@ class VulkanDeleteList {
// Optionally, it can create a depth buffer for you as well.
class VulkanContext {
public:
VulkanContext(const char *app_name, int app_ver, uint32_t flags);
VulkanContext();
~VulkanContext();
VkResult CreateDevice(int physical_device);
VkResult CreateInstance(const char *app_name, int app_ver, uint32_t flags);
// TODO: Actually do some checks?
int GetBestPhysicalDevice() const { return 0; }
void ChooseDevice(int physical_device);
bool EnableDeviceExtension(const char *extension);
VkResult CreateDevice();
const std::string &InitError() { return init_error_; }
@@ -300,59 +299,83 @@ class VulkanContext {
return gpu_props;
}
VkResult InitGlobalExtensionProperties();
VkResult InitLayerExtensionProperties(layer_properties &layer_props);
VkResult InitGlobalLayerProperties();
VkResult GetInstanceLayerExtensionList(const char *layerName, std::vector<VkExtensionProperties> &extensions);
VkResult GetInstanceLayerProperties();
VkResult InitDeviceExtensionProperties(layer_properties &layer_props);
VkResult InitDeviceLayerProperties();
VkResult GetDeviceLayerExtensionList(const char *layerName, std::vector<VkExtensionProperties> &extensions);
VkResult GetDeviceLayerProperties();
const std::vector<VkExtensionProperties> &GetDeviceExtensionsAvailable() const {
return device_extension_properties_;
}
const std::vector<const char *> &GetDeviceExtensionsEnabled() const {
return device_extensions_enabled_;
}
const VkPhysicalDeviceFeatures &GetFeaturesAvailable() const { return featuresAvailable_; }
const VkPhysicalDeviceFeatures &GetFeaturesEnabled() const { return featuresEnabled_; }
const VulkanPhysicalDeviceInfo &GetDeviceInfo() const { return deviceInfo_; }
bool IsDeviceExtensionAvailable(const char *name) const {
for (auto &iter : device_extension_properties_) {
if (!strcmp(name, iter.extensionName))
return true;
}
return false;
}
int GetInflightFrames() const {
return inflightFrames_;
}
enum {
MAX_INFLIGHT_FRAMES = 2,
};
private:
// A layer can expose extensions, keep track of those extensions here.
struct LayerProperties {
VkLayerProperties properties;
std::vector<VkExtensionProperties> extensions;
};
VkSemaphore acquireSemaphore;
VkSemaphore renderingCompleteSemaphore;
bool CheckLayers(const std::vector<LayerProperties> &layer_props, const std::vector<const char *> &layer_names) const;
VkSemaphore acquireSemaphore_;
VkSemaphore renderingCompleteSemaphore_;
#ifdef _WIN32
HINSTANCE connection; // hInstance - Windows Instance
HWND window; // hWnd - window handle
HINSTANCE connection = nullptr; // hInstance - Windows Instance
HWND window = nullptr; // hWnd - window handle
#elif __ANDROID__ // _WIN32
ANativeWindow *native_window;
ANativeWindow *native_window = nullptr;
#endif // _WIN32
VkInstance instance_;
VkDevice device_;
VkQueue gfx_queue_;
VkSurfaceKHR surface_;
VkInstance instance_ = VK_NULL_HANDLE;
VkDevice device_ = VK_NULL_HANDLE;
VkQueue gfx_queue_ = VK_NULL_HANDLE;
VkSurfaceKHR surface_ = VK_NULL_HANDLE;
std::string init_error_;
std::vector<const char *> instance_layer_names;
std::vector<const char *> instance_extension_names;
std::vector<layer_properties> instance_layer_properties;
std::vector<VkExtensionProperties> instance_extension_properties;
std::vector<const char *> device_layer_names;
std::vector<const char *> device_extension_names;
std::vector<layer_properties> device_layer_properties;
std::vector<VkExtensionProperties> device_extension_properties;
std::vector<const char *> instance_layer_names_;
std::vector<LayerProperties> instance_layer_properties_;
std::vector<const char *> instance_extensions_enabled_;
std::vector<VkExtensionProperties> instance_extension_properties_;
std::vector<const char *> device_layer_names_;
std::vector<LayerProperties> device_layer_properties_;
std::vector<const char *> device_extensions_enabled_;
std::vector<VkExtensionProperties> device_extension_properties_;
std::vector<VkPhysicalDevice> physical_devices_;
uint32_t graphics_queue_family_index_;
VkPhysicalDeviceProperties gpu_props;
int physical_device_ = -1;
uint32_t graphics_queue_family_index_ = -1;
VkPhysicalDeviceProperties gpu_props{};
std::vector<VkQueueFamilyProperties> queue_props;
VkPhysicalDeviceMemoryProperties memory_properties;
VkPhysicalDeviceMemoryProperties memory_properties{};
// Custom collection of things that are good to know
VulkanPhysicalDeviceInfo deviceInfo_;
@@ -363,12 +386,13 @@ class VulkanContext {
};
// Swap chain
int width_, height_;
int flags_;
VkFormat swapchain_format;
int width_ = 0;
int height_ = 0;
int flags_ = 0;
VkFormat swapchain_format = VK_FORMAT_UNDEFINED;
std::vector<VkFramebuffer> framebuffers_;
uint32_t swapchainImageCount;
VkSwapchainKHR swap_chain_;
uint32_t swapchainImageCount = 0;
VkSwapchainKHR swap_chain_ = VK_NULL_HANDLE;
std::vector<swap_chain_buffer> swapChainBuffers;
int inflightFrames_ = MAX_INFLIGHT_FRAMES;
View
@@ -493,27 +493,27 @@ void SystemInfoScreen::CreateViews() {
cpuExtensions->Add(new TextView(exts[i]))->SetFocusable(true);
}
ViewGroup *oglExtensionsScroll = new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(FILL_PARENT, FILL_PARENT));
oglExtensionsScroll->SetTag("DevSystemInfoOGLExt");
LinearLayout *oglExtensions = new LinearLayout(ORIENT_VERTICAL);
oglExtensions->SetSpacing(0);
oglExtensionsScroll->Add(oglExtensions);
ViewGroup *gpuExtensionsScroll = new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(FILL_PARENT, FILL_PARENT));
gpuExtensionsScroll->SetTag("DevSystemInfoOGLExt");
LinearLayout *gpuExtensions = new LinearLayout(ORIENT_VERTICAL);
gpuExtensions->SetSpacing(0);
gpuExtensionsScroll->Add(gpuExtensions);
if (g_Config.iGPUBackend == GPU_BACKEND_OPENGL) {
tabHolder->AddTab("OGL Extensions", oglExtensionsScroll);
tabHolder->AddTab("OGL Extensions", gpuExtensionsScroll);
if (!gl_extensions.IsGLES) {
oglExtensions->Add(new ItemHeader("OpenGL Extensions"));
gpuExtensions->Add(new ItemHeader("OpenGL Extensions"));
} else if (gl_extensions.GLES3) {
oglExtensions->Add(new ItemHeader("OpenGL ES 3.0 Extensions"));
gpuExtensions->Add(new ItemHeader("OpenGL ES 3.0 Extensions"));
} else {
oglExtensions->Add(new ItemHeader("OpenGL ES 2.0 Extensions"));
gpuExtensions->Add(new ItemHeader("OpenGL ES 2.0 Extensions"));
}
exts.clear();
SplitString(g_all_gl_extensions, ' ', exts);
std::sort(exts.begin(), exts.end());
for (size_t i = 0; i < exts.size(); i++) {
oglExtensions->Add(new TextView(exts[i]))->SetFocusable(true);
gpuExtensions->Add(new TextView(exts[i]))->SetFocusable(true);
}
exts.clear();
@@ -537,12 +537,17 @@ void SystemInfoScreen::CreateViews() {
}
}
} else if (g_Config.iGPUBackend == GPU_BACKEND_VULKAN) {
tabHolder->AddTab("Vulkan Features", oglExtensionsScroll);
tabHolder->AddTab("Vulkan Features", gpuExtensionsScroll);
oglExtensions->Add(new ItemHeader("Vulkan Features"));
gpuExtensions->Add(new ItemHeader("Vulkan Features"));
std::vector<std::string> features = draw->GetFeatureList();
for (auto &feature : features) {
oglExtensions->Add(new TextView(feature))->SetFocusable(true);
gpuExtensions->Add(new TextView(feature))->SetFocusable(true);
}
gpuExtensions->Add(new ItemHeader("Vulkan Extensions"));
std::vector<std::string> extensions = draw->GetExtensionList();
for (auto &extension : extensions) {
gpuExtensions->Add(new TextView(extension))->SetFocusable(true);
}
}
}
@@ -179,8 +179,16 @@ bool WindowsVulkanContext::Init(HINSTANCE hInst, HWND hWnd, std::string *error_m
g_LogOptions.msgBoxOnError = false;
Version gitVer(PPSSPP_GIT_VERSION);
g_Vulkan = new VulkanContext("PPSSPP", gitVer.ToInteger(), (g_validate_ ? VULKAN_FLAG_VALIDATE : 0) | VULKAN_FLAG_PRESENT_MAILBOX);
if (g_Vulkan->CreateDevice(0) != VK_SUCCESS) {
g_Vulkan = new VulkanContext();
if (VK_SUCCESS != g_Vulkan->CreateInstance("PPSSPP", gitVer.ToInteger(), (g_validate_ ? VULKAN_FLAG_VALIDATE : 0) | VULKAN_FLAG_PRESENT_MAILBOX)) {
*error_message = g_Vulkan->InitError();
return false;
}
g_Vulkan->ChooseDevice(g_Vulkan->GetBestPhysicalDevice());
if (g_Vulkan->EnableDeviceExtension(VK_NV_DEDICATED_ALLOCATION_EXTENSION_NAME)) {
supportsDedicatedAlloc_ = true;
}
if (g_Vulkan->CreateDevice() != VK_SUCCESS) {
*error_message = g_Vulkan->InitError();
return false;
}
@@ -35,5 +35,6 @@ class WindowsVulkanContext : public WindowsGraphicsContext {
Draw::DrawContext *GetDrawContext() override { return draw_; }
private:
Draw::DrawContext *draw_;
bool supportsDedicatedAlloc_;
};
View
@@ -65,7 +65,7 @@
#include "Windows/main.h"
// Nvidia drivers >= v302 will check if the application exports a global
// Nvidia OpenGL drivers >= v302 will check if the application exports a global
// variable named NvOptimusEnablement to know if it should run the app in high
// performance graphics mode or using the IGP.
extern "C" {
@@ -278,15 +278,22 @@ bool AndroidVulkanContext::Init(ANativeWindow *wnd, int desiredBackbufferSizeX,
ILOG("Creating vulkan context");
Version gitVer(PPSSPP_GIT_VERSION);
g_Vulkan = new VulkanContext("PPSSPP", gitVer.ToInteger(), VULKAN_FLAG_PRESENT_MAILBOX | VULKAN_FLAG_PRESENT_FIFO_RELAXED);
if (!g_Vulkan->GetInstance()) {
ELOG("Failed to create vulkan context");
g_Vulkan = new VulkanContext();
if (VK_SUCCESS != g_Vulkan->CreateInstance("PPSSPP", gitVer.ToInteger(), VULKAN_FLAG_PRESENT_MAILBOX | VULKAN_FLAG_PRESENT_FIFO_RELAXED)) {
ELOG("Failed to create vulkan context: %s", g_Vulkan->InitError().c_str());
delete g_Vulkan;
g_Vulkan = nullptr;
return false;
}
g_Vulkan->ChooseDevice(g_Vulkan->GetBestPhysicalDevice());
// Here we can enable device extensions if we like.
ILOG("Creating vulkan device");
if (g_Vulkan->CreateDevice(0) != VK_SUCCESS) {
if (g_Vulkan->CreateDevice() != VK_SUCCESS) {
ILOG("Failed to create vulkan device: %s", g_Vulkan->InitError().c_str());
delete g_Vulkan;
g_Vulkan = nullptr;
return false;
}
int width = desiredBackbufferSizeX;
@@ -587,6 +587,7 @@ class DrawContext {
virtual const DeviceCaps &GetDeviceCaps() const = 0;
virtual uint32_t GetDataFormatSupport(DataFormat fmt) const = 0;
virtual std::vector<std::string> GetFeatureList() const { return std::vector<std::string>(); }
virtual std::vector<std::string> GetExtensionList() const { return std::vector<std::string>(); }
virtual uint32_t GetSupportedShaderLanguages() const = 0;
@@ -457,6 +457,7 @@ class VKContext : public DrawContext {
VkDescriptorSet GetOrCreateDescriptorSet(VkBuffer buffer);
std::vector<std::string> GetFeatureList() const override;
std::vector<std::string> GetExtensionList() const override;
uintptr_t GetNativeObject(NativeObject obj) const override {
switch (obj) {
@@ -1423,6 +1424,14 @@ std::vector<std::string> VKContext::GetFeatureList() const {
return features;
}
std::vector<std::string> VKContext::GetExtensionList() const {
std::vector<std::string> extensions;
for (auto &iter : vulkan_->GetDeviceExtensionsAvailable()) {
extensions.push_back(iter.extensionName);
}
return extensions;
}
uint32_t VKContext::GetDataFormatSupport(DataFormat fmt) const {
// TODO: Actually do proper checks
switch (fmt) {

0 comments on commit 966cbd3

Please sign in to comment.