Skip to content

Commit

Permalink
Merge pull request #9935 from hrydgard/vulkan-init-fixes
Browse files Browse the repository at this point in the history
Vulkan init refactor
  • Loading branch information
hrydgard committed Aug 28, 2017
2 parents 4938ab7 + 21d8561 commit 966cbd3
Show file tree
Hide file tree
Showing 9 changed files with 284 additions and 299 deletions.
404 changes: 167 additions & 237 deletions Common/Vulkan/VulkanContext.cpp

Large diffs are not rendered by default.

108 changes: 66 additions & 42 deletions Common/Vulkan/VulkanContext.h
Expand Up @@ -43,13 +43,6 @@ enum {
VULKAN_FLAG_PRESENT_FIFO_RELAXED = 8, 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 { struct VulkanPhysicalDeviceInfo {
VkFormat preferredDepthStencilFormat; VkFormat preferredDepthStencilFormat;
}; };
Expand Down Expand Up @@ -206,10 +199,16 @@ class VulkanDeleteList {
// Optionally, it can create a depth buffer for you as well. // Optionally, it can create a depth buffer for you as well.
class VulkanContext { class VulkanContext {
public: public:
VulkanContext(const char *app_name, int app_ver, uint32_t flags); VulkanContext();
~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_; } const std::string &InitError() { return init_error_; }


Expand Down Expand Up @@ -300,59 +299,83 @@ class VulkanContext {
return gpu_props; return gpu_props;
} }


VkResult InitGlobalExtensionProperties(); VkResult GetInstanceLayerExtensionList(const char *layerName, std::vector<VkExtensionProperties> &extensions);
VkResult InitLayerExtensionProperties(layer_properties &layer_props); VkResult GetInstanceLayerProperties();

VkResult InitGlobalLayerProperties();


VkResult InitDeviceExtensionProperties(layer_properties &layer_props); VkResult GetDeviceLayerExtensionList(const char *layerName, std::vector<VkExtensionProperties> &extensions);
VkResult InitDeviceLayerProperties(); 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 &GetFeaturesAvailable() const { return featuresAvailable_; }
const VkPhysicalDeviceFeatures &GetFeaturesEnabled() const { return featuresEnabled_; } const VkPhysicalDeviceFeatures &GetFeaturesEnabled() const { return featuresEnabled_; }
const VulkanPhysicalDeviceInfo &GetDeviceInfo() const { return deviceInfo_; } 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 { int GetInflightFrames() const {
return inflightFrames_; return inflightFrames_;
} }


enum { enum {
MAX_INFLIGHT_FRAMES = 2, MAX_INFLIGHT_FRAMES = 2,
}; };

private: private:
// A layer can expose extensions, keep track of those extensions here.
struct LayerProperties {
VkLayerProperties properties;
std::vector<VkExtensionProperties> extensions;
};


VkSemaphore acquireSemaphore; bool CheckLayers(const std::vector<LayerProperties> &layer_props, const std::vector<const char *> &layer_names) const;
VkSemaphore renderingCompleteSemaphore;
VkSemaphore acquireSemaphore_;
VkSemaphore renderingCompleteSemaphore_;


#ifdef _WIN32 #ifdef _WIN32
HINSTANCE connection; // hInstance - Windows Instance HINSTANCE connection = nullptr; // hInstance - Windows Instance
HWND window; // hWnd - window handle HWND window = nullptr; // hWnd - window handle
#elif __ANDROID__ // _WIN32 #elif __ANDROID__ // _WIN32
ANativeWindow *native_window; ANativeWindow *native_window = nullptr;
#endif // _WIN32 #endif // _WIN32


VkInstance instance_; VkInstance instance_ = VK_NULL_HANDLE;
VkDevice device_; VkDevice device_ = VK_NULL_HANDLE;
VkQueue gfx_queue_; VkQueue gfx_queue_ = VK_NULL_HANDLE;

VkSurfaceKHR surface_ = VK_NULL_HANDLE;
VkSurfaceKHR surface_;


std::string init_error_; std::string init_error_;
std::vector<const char *> instance_layer_names; std::vector<const char *> instance_layer_names_;
std::vector<const char *> instance_extension_names; std::vector<LayerProperties> instance_layer_properties_;
std::vector<layer_properties> instance_layer_properties;
std::vector<VkExtensionProperties> instance_extension_properties; std::vector<const char *> instance_extensions_enabled_;

std::vector<VkExtensionProperties> instance_extension_properties_;
std::vector<const char *> device_layer_names;
std::vector<const char *> device_extension_names; std::vector<const char *> device_layer_names_;
std::vector<layer_properties> device_layer_properties; std::vector<LayerProperties> device_layer_properties_;
std::vector<VkExtensionProperties> device_extension_properties;
std::vector<const char *> device_extensions_enabled_;
std::vector<VkExtensionProperties> device_extension_properties_;

std::vector<VkPhysicalDevice> physical_devices_; std::vector<VkPhysicalDevice> physical_devices_;


uint32_t graphics_queue_family_index_; int physical_device_ = -1;
VkPhysicalDeviceProperties gpu_props;
uint32_t graphics_queue_family_index_ = -1;
VkPhysicalDeviceProperties gpu_props{};
std::vector<VkQueueFamilyProperties> queue_props; std::vector<VkQueueFamilyProperties> queue_props;
VkPhysicalDeviceMemoryProperties memory_properties; VkPhysicalDeviceMemoryProperties memory_properties{};


// Custom collection of things that are good to know // Custom collection of things that are good to know
VulkanPhysicalDeviceInfo deviceInfo_; VulkanPhysicalDeviceInfo deviceInfo_;
Expand All @@ -363,12 +386,13 @@ class VulkanContext {
}; };


// Swap chain // Swap chain
int width_, height_; int width_ = 0;
int flags_; int height_ = 0;
VkFormat swapchain_format; int flags_ = 0;
VkFormat swapchain_format = VK_FORMAT_UNDEFINED;
std::vector<VkFramebuffer> framebuffers_; std::vector<VkFramebuffer> framebuffers_;
uint32_t swapchainImageCount; uint32_t swapchainImageCount = 0;
VkSwapchainKHR swap_chain_; VkSwapchainKHR swap_chain_ = VK_NULL_HANDLE;
std::vector<swap_chain_buffer> swapChainBuffers; std::vector<swap_chain_buffer> swapChainBuffers;


int inflightFrames_ = MAX_INFLIGHT_FRAMES; int inflightFrames_ = MAX_INFLIGHT_FRAMES;
Expand Down
31 changes: 18 additions & 13 deletions UI/DevScreens.cpp
Expand Up @@ -493,27 +493,27 @@ void SystemInfoScreen::CreateViews() {
cpuExtensions->Add(new TextView(exts[i]))->SetFocusable(true); cpuExtensions->Add(new TextView(exts[i]))->SetFocusable(true);
} }


ViewGroup *oglExtensionsScroll = new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(FILL_PARENT, FILL_PARENT)); ViewGroup *gpuExtensionsScroll = new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(FILL_PARENT, FILL_PARENT));
oglExtensionsScroll->SetTag("DevSystemInfoOGLExt"); gpuExtensionsScroll->SetTag("DevSystemInfoOGLExt");
LinearLayout *oglExtensions = new LinearLayout(ORIENT_VERTICAL); LinearLayout *gpuExtensions = new LinearLayout(ORIENT_VERTICAL);
oglExtensions->SetSpacing(0); gpuExtensions->SetSpacing(0);
oglExtensionsScroll->Add(oglExtensions); gpuExtensionsScroll->Add(gpuExtensions);


if (g_Config.iGPUBackend == GPU_BACKEND_OPENGL) { if (g_Config.iGPUBackend == GPU_BACKEND_OPENGL) {
tabHolder->AddTab("OGL Extensions", oglExtensionsScroll); tabHolder->AddTab("OGL Extensions", gpuExtensionsScroll);


if (!gl_extensions.IsGLES) { if (!gl_extensions.IsGLES) {
oglExtensions->Add(new ItemHeader("OpenGL Extensions")); gpuExtensions->Add(new ItemHeader("OpenGL Extensions"));
} else if (gl_extensions.GLES3) { } else if (gl_extensions.GLES3) {
oglExtensions->Add(new ItemHeader("OpenGL ES 3.0 Extensions")); gpuExtensions->Add(new ItemHeader("OpenGL ES 3.0 Extensions"));
} else { } else {
oglExtensions->Add(new ItemHeader("OpenGL ES 2.0 Extensions")); gpuExtensions->Add(new ItemHeader("OpenGL ES 2.0 Extensions"));
} }
exts.clear(); exts.clear();
SplitString(g_all_gl_extensions, ' ', exts); SplitString(g_all_gl_extensions, ' ', exts);
std::sort(exts.begin(), exts.end()); std::sort(exts.begin(), exts.end());
for (size_t i = 0; i < exts.size(); i++) { 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(); exts.clear();
Expand All @@ -537,12 +537,17 @@ void SystemInfoScreen::CreateViews() {
} }
} }
} else if (g_Config.iGPUBackend == GPU_BACKEND_VULKAN) { } 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(); std::vector<std::string> features = draw->GetFeatureList();
for (auto &feature : features) { 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);
} }
} }
} }
Expand Down
12 changes: 10 additions & 2 deletions Windows/GPU/WindowsVulkanContext.cpp
Expand Up @@ -179,8 +179,16 @@ bool WindowsVulkanContext::Init(HINSTANCE hInst, HWND hWnd, std::string *error_m
g_LogOptions.msgBoxOnError = false; g_LogOptions.msgBoxOnError = false;


Version gitVer(PPSSPP_GIT_VERSION); Version gitVer(PPSSPP_GIT_VERSION);
g_Vulkan = new VulkanContext("PPSSPP", gitVer.ToInteger(), (g_validate_ ? VULKAN_FLAG_VALIDATE : 0) | VULKAN_FLAG_PRESENT_MAILBOX); g_Vulkan = new VulkanContext();
if (g_Vulkan->CreateDevice(0) != VK_SUCCESS) { 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(); *error_message = g_Vulkan->InitError();
return false; return false;
} }
Expand Down
1 change: 1 addition & 0 deletions Windows/GPU/WindowsVulkanContext.h
Expand Up @@ -35,5 +35,6 @@ class WindowsVulkanContext : public WindowsGraphicsContext {
Draw::DrawContext *GetDrawContext() override { return draw_; } Draw::DrawContext *GetDrawContext() override { return draw_; }
private: private:
Draw::DrawContext *draw_; Draw::DrawContext *draw_;
bool supportsDedicatedAlloc_;
}; };


2 changes: 1 addition & 1 deletion Windows/main.cpp
Expand Up @@ -65,7 +65,7 @@
#include "Windows/main.h" #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 // variable named NvOptimusEnablement to know if it should run the app in high
// performance graphics mode or using the IGP. // performance graphics mode or using the IGP.
extern "C" { extern "C" {
Expand Down
15 changes: 11 additions & 4 deletions android/jni/app-android.cpp
Expand Up @@ -278,15 +278,22 @@ bool AndroidVulkanContext::Init(ANativeWindow *wnd, int desiredBackbufferSizeX,


ILOG("Creating vulkan context"); ILOG("Creating vulkan context");
Version gitVer(PPSSPP_GIT_VERSION); Version gitVer(PPSSPP_GIT_VERSION);
g_Vulkan = new VulkanContext("PPSSPP", gitVer.ToInteger(), VULKAN_FLAG_PRESENT_MAILBOX | VULKAN_FLAG_PRESENT_FIFO_RELAXED); g_Vulkan = new VulkanContext();
if (!g_Vulkan->GetInstance()) { if (VK_SUCCESS != g_Vulkan->CreateInstance("PPSSPP", gitVer.ToInteger(), VULKAN_FLAG_PRESENT_MAILBOX | VULKAN_FLAG_PRESENT_FIFO_RELAXED)) {
ELOG("Failed to create vulkan context"); ELOG("Failed to create vulkan context: %s", g_Vulkan->InitError().c_str());
delete g_Vulkan;
g_Vulkan = nullptr;
return false; return false;
} }


g_Vulkan->ChooseDevice(g_Vulkan->GetBestPhysicalDevice());
// Here we can enable device extensions if we like.

ILOG("Creating vulkan device"); 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()); ILOG("Failed to create vulkan device: %s", g_Vulkan->InitError().c_str());
delete g_Vulkan;
g_Vulkan = nullptr;
return false; return false;
} }
int width = desiredBackbufferSizeX; int width = desiredBackbufferSizeX;
Expand Down
1 change: 1 addition & 0 deletions ext/native/thin3d/thin3d.h
Expand Up @@ -587,6 +587,7 @@ class DrawContext {
virtual const DeviceCaps &GetDeviceCaps() const = 0; virtual const DeviceCaps &GetDeviceCaps() const = 0;
virtual uint32_t GetDataFormatSupport(DataFormat fmt) 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> 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; virtual uint32_t GetSupportedShaderLanguages() const = 0;


Expand Down
9 changes: 9 additions & 0 deletions ext/native/thin3d/thin3d_vulkan.cpp
Expand Up @@ -457,6 +457,7 @@ class VKContext : public DrawContext {
VkDescriptorSet GetOrCreateDescriptorSet(VkBuffer buffer); VkDescriptorSet GetOrCreateDescriptorSet(VkBuffer buffer);


std::vector<std::string> GetFeatureList() const override; std::vector<std::string> GetFeatureList() const override;
std::vector<std::string> GetExtensionList() const override;


uintptr_t GetNativeObject(NativeObject obj) const override { uintptr_t GetNativeObject(NativeObject obj) const override {
switch (obj) { switch (obj) {
Expand Down Expand Up @@ -1423,6 +1424,14 @@ std::vector<std::string> VKContext::GetFeatureList() const {
return features; 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 { uint32_t VKContext::GetDataFormatSupport(DataFormat fmt) const {
// TODO: Actually do proper checks // TODO: Actually do proper checks
switch (fmt) { switch (fmt) {
Expand Down

0 comments on commit 966cbd3

Please sign in to comment.