Dynamic loading of vulkan dll.
This commit is contained in:
parent
4214e10c8a
commit
91fb54bc81
|
|
@ -72,8 +72,6 @@
|
||||||
</ResourceCompile>
|
</ResourceCompile>
|
||||||
<Lib>
|
<Lib>
|
||||||
<SuppressStartupBanner>true</SuppressStartupBanner>
|
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||||
<AdditionalDependencies>vulkan-1.lib</AdditionalDependencies>
|
|
||||||
<AdditionalLibraryDirectories>$(ProjectDir)..\..\third_party\lib</AdditionalLibraryDirectories>
|
|
||||||
</Lib>
|
</Lib>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
|
@ -94,8 +92,6 @@
|
||||||
</ResourceCompile>
|
</ResourceCompile>
|
||||||
<Lib>
|
<Lib>
|
||||||
<SuppressStartupBanner>true</SuppressStartupBanner>
|
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||||
<AdditionalDependencies>vulkan-1.lib</AdditionalDependencies>
|
|
||||||
<AdditionalLibraryDirectories>$(ProjectDir)..\..\third_party\lib</AdditionalLibraryDirectories>
|
|
||||||
</Lib>
|
</Lib>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|
|
||||||
|
|
@ -33,31 +33,31 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
**
|
**
|
||||||
** vk_imp_init
|
** vk_imp_init
|
||||||
** vk_imp_shutdown
|
** vk_imp_shutdown
|
||||||
|
** vk_imp_create_surface
|
||||||
*/
|
*/
|
||||||
#include <assert.h>
|
|
||||||
#include "../renderer/tr_local.h"
|
#include "../renderer/tr_local.h"
|
||||||
#include "../qcommon/qcommon.h"
|
|
||||||
#include "resource.h"
|
#include "resource.h"
|
||||||
#include "win_local.h"
|
#include "win_local.h"
|
||||||
|
|
||||||
extern void WG_CheckHardwareGamma( void );
|
|
||||||
extern void WG_RestoreGamma( void );
|
|
||||||
|
|
||||||
#define MAIN_WINDOW_CLASS_NAME "Quake 3: Arena"
|
#define MAIN_WINDOW_CLASS_NAME "Quake 3: Arena"
|
||||||
#define TWIN_WINDOW_CLASS_NAME "Quake 3: Arena [Twin]"
|
#define TWIN_WINDOW_CLASS_NAME "Quake 3: Arena [Twin]"
|
||||||
|
|
||||||
static bool s_main_window_class_registered = false;
|
static bool s_main_window_class_registered = false;
|
||||||
static bool s_twin_window_class_registered = false;
|
static bool s_twin_window_class_registered = false;
|
||||||
|
|
||||||
void QGL_EnableLogging( qboolean enable );
|
|
||||||
qboolean QGL_Init( const char *dllname );
|
|
||||||
void QGL_Shutdown( void );
|
|
||||||
|
|
||||||
static HDC gl_hdc; // handle to device context
|
static HDC gl_hdc; // handle to device context
|
||||||
static HGLRC gl_hglrc; // handle to GL rendering context
|
static HGLRC gl_hglrc; // handle to GL rendering context
|
||||||
|
|
||||||
|
static HINSTANCE vk_library_handle; // HINSTANCE for the Vulkan library
|
||||||
|
|
||||||
FILE* log_fp;
|
FILE* log_fp;
|
||||||
|
|
||||||
|
qboolean QGL_Init(const char *dllname);
|
||||||
|
void QGL_Shutdown();
|
||||||
|
void QGL_EnableLogging(qboolean enable);
|
||||||
|
void WG_CheckHardwareGamma();
|
||||||
|
void WG_RestoreGamma();
|
||||||
|
|
||||||
static int GetDesktopCaps(int index) {
|
static int GetDesktopCaps(int index) {
|
||||||
HDC hdc = GetDC(GetDesktopWindow());
|
HDC hdc = GetDC(GetDesktopWindow());
|
||||||
int value = GetDeviceCaps(hdc, index);
|
int value = GetDeviceCaps(hdc, index);
|
||||||
|
|
@ -703,6 +703,9 @@ void GLimp_Init( void )
|
||||||
if (r_renderAPI->integer == 0) {
|
if (r_renderAPI->integer == 0) {
|
||||||
g_wv.hWnd_opengl = create_main_window(glConfig.vidWidth, glConfig.vidHeight, (qboolean)r_fullscreen->integer);
|
g_wv.hWnd_opengl = create_main_window(glConfig.vidWidth, glConfig.vidHeight, (qboolean)r_fullscreen->integer);
|
||||||
g_wv.hWnd = g_wv.hWnd_opengl;
|
g_wv.hWnd = g_wv.hWnd_opengl;
|
||||||
|
SetForegroundWindow(g_wv.hWnd);
|
||||||
|
SetFocus(g_wv.hWnd);
|
||||||
|
WG_CheckHardwareGamma();
|
||||||
} else {
|
} else {
|
||||||
g_wv.hWnd_opengl = create_twin_window(glConfig.vidWidth, glConfig.vidHeight);
|
g_wv.hWnd_opengl = create_twin_window(glConfig.vidWidth, glConfig.vidHeight);
|
||||||
}
|
}
|
||||||
|
|
@ -711,9 +714,6 @@ void GLimp_Init( void )
|
||||||
ri.Error(ERR_FATAL, "GLW_InitDriver - could not initialize OpenGL subsystem\n");
|
ri.Error(ERR_FATAL, "GLW_InitDriver - could not initialize OpenGL subsystem\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
SetForegroundWindow(g_wv.hWnd);
|
|
||||||
SetFocus(g_wv.hWnd);
|
|
||||||
|
|
||||||
// get our config strings
|
// get our config strings
|
||||||
Q_strncpyz( glConfig.vendor_string, (const char*) qglGetString (GL_VENDOR), sizeof( glConfig.vendor_string ) );
|
Q_strncpyz( glConfig.vendor_string, (const char*) qglGetString (GL_VENDOR), sizeof( glConfig.vendor_string ) );
|
||||||
Q_strncpyz(glConfig.renderer_string, (const char*)qglGetString(GL_RENDERER), sizeof(glConfig.renderer_string));
|
Q_strncpyz(glConfig.renderer_string, (const char*)qglGetString(GL_RENDERER), sizeof(glConfig.renderer_string));
|
||||||
|
|
@ -721,7 +721,6 @@ void GLimp_Init( void )
|
||||||
Q_strncpyz(glConfig.extensions_string, (const char*)qglGetString(GL_EXTENSIONS), sizeof(glConfig.extensions_string));
|
Q_strncpyz(glConfig.extensions_string, (const char*)qglGetString(GL_EXTENSIONS), sizeof(glConfig.extensions_string));
|
||||||
|
|
||||||
GLW_InitExtensions();
|
GLW_InitExtensions();
|
||||||
WG_CheckHardwareGamma();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -759,9 +758,9 @@ void GLimp_Shutdown( void )
|
||||||
ShowWindow(g_wv.hWnd_opengl, SW_HIDE);
|
ShowWindow(g_wv.hWnd_opengl, SW_HIDE);
|
||||||
DestroyWindow(g_wv.hWnd_opengl);
|
DestroyWindow(g_wv.hWnd_opengl);
|
||||||
|
|
||||||
if (g_wv.hWnd == g_wv.hWnd_opengl)
|
if (g_wv.hWnd == g_wv.hWnd_opengl) {
|
||||||
g_wv.hWnd = NULL;
|
g_wv.hWnd = NULL;
|
||||||
|
}
|
||||||
g_wv.hWnd_opengl = NULL;
|
g_wv.hWnd_opengl = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -788,54 +787,63 @@ void GLimp_LogComment( char *comment )
|
||||||
void vk_imp_init() {
|
void vk_imp_init() {
|
||||||
ri.Printf(PRINT_ALL, "Initializing Vulkan subsystem\n");
|
ri.Printf(PRINT_ALL, "Initializing Vulkan subsystem\n");
|
||||||
|
|
||||||
|
// This will set qgl pointers to no-op placeholders.
|
||||||
if (!gl_enabled()) {
|
if (!gl_enabled()) {
|
||||||
QGL_Init(nullptr); // this will set qgl pointers to no-op placeholders
|
QGL_Init(nullptr);
|
||||||
qglActiveTextureARB = [] (GLenum) {};
|
qglActiveTextureARB = [] (GLenum) {};
|
||||||
qglClientActiveTextureARB = [](GLenum) {};
|
qglClientActiveTextureARB = [](GLenum) {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Load Vulkan DLL.
|
||||||
|
const char* dll_name = "vulkan-1.dll";
|
||||||
|
|
||||||
|
ri.Printf(PRINT_ALL, "...calling LoadLibrary('%s'): ", dll_name);
|
||||||
|
vk_library_handle = LoadLibrary(dll_name);
|
||||||
|
|
||||||
|
if (vk_library_handle == NULL) {
|
||||||
|
ri.Printf(PRINT_ALL, "failed\n");
|
||||||
|
ri.Error(ERR_FATAL, "vk_imp_init - could not load %s\n", dll_name);
|
||||||
|
}
|
||||||
|
ri.Printf( PRINT_ALL, "succeeded\n" );
|
||||||
|
|
||||||
|
vkGetInstanceProcAddr = (PFN_vkGetInstanceProcAddr)GetProcAddress(vk_library_handle, "vkGetInstanceProcAddr");
|
||||||
|
|
||||||
|
// Create window.
|
||||||
SetMode(r_mode->integer, (qboolean)r_fullscreen->integer);
|
SetMode(r_mode->integer, (qboolean)r_fullscreen->integer);
|
||||||
|
|
||||||
if (r_renderAPI->integer != 0) {
|
if (r_renderAPI->integer != 0) {
|
||||||
g_wv.hWnd_vulkan = create_main_window(glConfig.vidWidth, glConfig.vidHeight, (qboolean)r_fullscreen->integer);
|
g_wv.hWnd_vulkan = create_main_window(glConfig.vidWidth, glConfig.vidHeight, (qboolean)r_fullscreen->integer);
|
||||||
g_wv.hWnd = g_wv.hWnd_vulkan;
|
g_wv.hWnd = g_wv.hWnd_vulkan;
|
||||||
|
SetForegroundWindow(g_wv.hWnd);
|
||||||
|
SetFocus(g_wv.hWnd);
|
||||||
|
WG_CheckHardwareGamma();
|
||||||
} else {
|
} else {
|
||||||
g_wv.hWnd_vulkan = create_twin_window(glConfig.vidWidth, glConfig.vidHeight);
|
g_wv.hWnd_vulkan = create_twin_window(glConfig.vidWidth, glConfig.vidHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
// In order to create a surface we need to create VkInstance first.
|
|
||||||
vk_create_instance();
|
|
||||||
|
|
||||||
// Create VkSurfaceKHR for Win32 platform.
|
|
||||||
VkWin32SurfaceCreateInfoKHR desc;
|
|
||||||
desc.sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR;
|
|
||||||
desc.pNext = nullptr;
|
|
||||||
desc.flags = 0;
|
|
||||||
desc.hinstance = ::GetModuleHandle(nullptr);
|
|
||||||
desc.hwnd = g_wv.hWnd_vulkan;
|
|
||||||
VK_CHECK(vkCreateWin32SurfaceKHR(vk.instance, &desc, nullptr, &vk.surface));
|
|
||||||
|
|
||||||
SetForegroundWindow(g_wv.hWnd);
|
|
||||||
SetFocus(g_wv.hWnd);
|
|
||||||
|
|
||||||
WG_CheckHardwareGamma();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void vk_imp_shutdown() {
|
void vk_imp_shutdown() {
|
||||||
ri.Printf(PRINT_ALL, "Shutting down Vulkan subsystem\n");
|
ri.Printf(PRINT_ALL, "Shutting down Vulkan subsystem\n");
|
||||||
|
|
||||||
if (g_wv.hWnd_vulkan) {
|
if (g_wv.hWnd_vulkan) {
|
||||||
ri.Printf(PRINT_ALL, "...destroying vulkan window\n");
|
ri.Printf(PRINT_ALL, "...destroying Vulkan window\n");
|
||||||
DestroyWindow(g_wv.hWnd_vulkan);
|
DestroyWindow(g_wv.hWnd_vulkan);
|
||||||
|
|
||||||
if (g_wv.hWnd == g_wv.hWnd_vulkan)
|
if (g_wv.hWnd == g_wv.hWnd_vulkan) {
|
||||||
g_wv.hWnd = NULL;
|
g_wv.hWnd = NULL;
|
||||||
|
}
|
||||||
g_wv.hWnd_vulkan = NULL;
|
g_wv.hWnd_vulkan = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (vk_library_handle != NULL) {
|
||||||
|
ri.Printf(PRINT_ALL, "...unloading Vulkan DLL\n");
|
||||||
|
FreeLibrary(vk_library_handle);
|
||||||
|
vk_library_handle = NULL;
|
||||||
|
}
|
||||||
|
vkGetInstanceProcAddr = nullptr;
|
||||||
|
|
||||||
// For vulkan mode we still have qgl pointers initialized with placeholder values.
|
// For vulkan mode we still have qgl pointers initialized with placeholder values.
|
||||||
// Thus reset them the same way as we do in opengl mode.
|
// Reset them the same way as we do in opengl mode.
|
||||||
QGL_Shutdown();
|
QGL_Shutdown();
|
||||||
|
|
||||||
WG_RestoreGamma();
|
WG_RestoreGamma();
|
||||||
|
|
@ -849,6 +857,16 @@ void vk_imp_shutdown() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void vk_imp_create_surface() {
|
||||||
|
VkWin32SurfaceCreateInfoKHR desc;
|
||||||
|
desc.sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR;
|
||||||
|
desc.pNext = nullptr;
|
||||||
|
desc.flags = 0;
|
||||||
|
desc.hinstance = ::GetModuleHandle(nullptr);
|
||||||
|
desc.hwnd = g_wv.hWnd_vulkan;
|
||||||
|
VK_CHECK(vkCreateWin32SurfaceKHR(vk.instance, &desc, nullptr, &vk.surface));
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
===========================================================
|
===========================================================
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -814,7 +814,7 @@ void GfxInfo_f( void )
|
||||||
ri.Printf(PRINT_ALL, "Vk vendor id: %d\n", props.vendorID);
|
ri.Printf(PRINT_ALL, "Vk vendor id: %d\n", props.vendorID);
|
||||||
ri.Printf(PRINT_ALL, "Vk device id: %d\n", props.deviceID);
|
ri.Printf(PRINT_ALL, "Vk device id: %d\n", props.deviceID);
|
||||||
ri.Printf(PRINT_ALL, "Vk device type: %s\n", device_type);
|
ri.Printf(PRINT_ALL, "Vk device type: %s\n", device_type);
|
||||||
ri.Printf(PRINT_ALL, "Vk device name: %s\n\n", props.deviceName);
|
ri.Printf(PRINT_ALL, "Vk device name: %s\n", props.deviceName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1077,7 +1077,8 @@ void RE_Shutdown( qboolean destroyWindow ) {
|
||||||
R_DoneFreeType();
|
R_DoneFreeType();
|
||||||
|
|
||||||
// shut down platform specific OpenGL stuff
|
// shut down platform specific OpenGL stuff
|
||||||
if ( destroyWindow ) {
|
if ( gl_enabled() ) {
|
||||||
|
if (destroyWindow)
|
||||||
GLimp_Shutdown();
|
GLimp_Shutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1208,6 +1208,7 @@ void GLimp_WakeRenderer( void *data );
|
||||||
|
|
||||||
void vk_imp_init();
|
void vk_imp_init();
|
||||||
void vk_imp_shutdown();
|
void vk_imp_shutdown();
|
||||||
|
void vk_imp_create_surface();
|
||||||
|
|
||||||
// NOTE TTimo linux works with float gamma value, not the gamma table
|
// NOTE TTimo linux works with float gamma value, not the gamma table
|
||||||
// the params won't be used, getting the r_gamma cvar directly
|
// the params won't be used, getting the r_gamma cvar directly
|
||||||
|
|
|
||||||
|
|
@ -75,111 +75,6 @@ static VkFormat find_depth_format(VkPhysicalDevice physical_device) {
|
||||||
VK_IMAGE_TILING_OPTIMAL, VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT);
|
VK_IMAGE_TILING_OPTIMAL, VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t select_queue_family(VkPhysicalDevice physical_device, VkSurfaceKHR surface) {
|
|
||||||
uint32_t queue_family_count;
|
|
||||||
vkGetPhysicalDeviceQueueFamilyProperties(physical_device, &queue_family_count, nullptr);
|
|
||||||
|
|
||||||
std::vector<VkQueueFamilyProperties> queue_families(queue_family_count);
|
|
||||||
vkGetPhysicalDeviceQueueFamilyProperties(physical_device, &queue_family_count, queue_families.data());
|
|
||||||
|
|
||||||
// select queue family with presentation and graphics support
|
|
||||||
for (uint32_t i = 0; i < queue_family_count; i++) {
|
|
||||||
VkBool32 presentation_supported;
|
|
||||||
VK_CHECK(vkGetPhysicalDeviceSurfaceSupportKHR(physical_device, i, surface, &presentation_supported));
|
|
||||||
|
|
||||||
if (presentation_supported && (queue_families[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) != 0)
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
|
|
||||||
ri.Error(ERR_FATAL, "Vulkan error: failed to find queue family");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static VkPhysicalDevice select_physical_device(VkInstance instance) {
|
|
||||||
uint32_t count;
|
|
||||||
VK_CHECK(vkEnumeratePhysicalDevices(instance, &count, nullptr));
|
|
||||||
|
|
||||||
if (count == 0)
|
|
||||||
ri.Error(ERR_FATAL, "Vulkan error: no physical device found");
|
|
||||||
|
|
||||||
std::vector<VkPhysicalDevice> physical_devices(count);
|
|
||||||
VK_CHECK(vkEnumeratePhysicalDevices(instance, &count, physical_devices.data()));
|
|
||||||
return physical_devices[0]; // just get the first one
|
|
||||||
}
|
|
||||||
|
|
||||||
static VkSurfaceKHR create_surface(VkInstance instance, HWND hwnd) {
|
|
||||||
VkWin32SurfaceCreateInfoKHR desc;
|
|
||||||
desc.sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR;
|
|
||||||
desc.pNext = nullptr;
|
|
||||||
desc.flags = 0;
|
|
||||||
desc.hinstance = ::GetModuleHandle(nullptr);
|
|
||||||
desc.hwnd = hwnd;
|
|
||||||
|
|
||||||
VkSurfaceKHR surface;
|
|
||||||
VK_CHECK(vkCreateWin32SurfaceKHR(instance, &desc, nullptr, &surface));
|
|
||||||
return surface;
|
|
||||||
}
|
|
||||||
|
|
||||||
static VkDevice create_device(VkPhysicalDevice physical_device, uint32_t queue_family_index) {
|
|
||||||
uint32_t count = 0;
|
|
||||||
VK_CHECK(vkEnumerateDeviceExtensionProperties(physical_device, nullptr, &count, nullptr));
|
|
||||||
|
|
||||||
std::vector<VkExtensionProperties> extension_properties(count);
|
|
||||||
VK_CHECK(vkEnumerateDeviceExtensionProperties(physical_device, nullptr, &count, extension_properties.data()));
|
|
||||||
|
|
||||||
for (auto name : device_extensions) {
|
|
||||||
if (!is_extension_available(extension_properties, name))
|
|
||||||
ri.Error(ERR_FATAL, "Vulkan error: required device extension is not available: %s", name);
|
|
||||||
}
|
|
||||||
|
|
||||||
const float priority = 1.0;
|
|
||||||
VkDeviceQueueCreateInfo queue_desc;
|
|
||||||
queue_desc.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
|
|
||||||
queue_desc.pNext = nullptr;
|
|
||||||
queue_desc.flags = 0;
|
|
||||||
queue_desc.queueFamilyIndex = queue_family_index;
|
|
||||||
queue_desc.queueCount = 1;
|
|
||||||
queue_desc.pQueuePriorities = &priority;
|
|
||||||
|
|
||||||
VkPhysicalDeviceFeatures features;
|
|
||||||
Com_Memset(&features, 0, sizeof(features));
|
|
||||||
features.shaderClipDistance = VK_TRUE;
|
|
||||||
|
|
||||||
VkDeviceCreateInfo device_desc;
|
|
||||||
device_desc.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
|
|
||||||
device_desc.pNext = nullptr;
|
|
||||||
device_desc.flags = 0;
|
|
||||||
device_desc.queueCreateInfoCount = 1;
|
|
||||||
device_desc.pQueueCreateInfos = &queue_desc;
|
|
||||||
device_desc.enabledLayerCount = 0;
|
|
||||||
device_desc.ppEnabledLayerNames = nullptr;
|
|
||||||
device_desc.enabledExtensionCount = static_cast<uint32_t>(device_extensions.size());
|
|
||||||
device_desc.ppEnabledExtensionNames = device_extensions.data();
|
|
||||||
device_desc.pEnabledFeatures = &features;
|
|
||||||
|
|
||||||
VkDevice device;
|
|
||||||
VK_CHECK(vkCreateDevice(physical_device, &device_desc, nullptr, &device));
|
|
||||||
return device;
|
|
||||||
}
|
|
||||||
|
|
||||||
static VkSurfaceFormatKHR select_surface_format(VkPhysicalDevice physical_device, VkSurfaceKHR surface) {
|
|
||||||
uint32_t format_count;
|
|
||||||
VK_CHECK(vkGetPhysicalDeviceSurfaceFormatsKHR(physical_device, surface, &format_count, nullptr));
|
|
||||||
assert(format_count > 0);
|
|
||||||
|
|
||||||
std::vector<VkSurfaceFormatKHR> candidates(format_count);
|
|
||||||
VK_CHECK(vkGetPhysicalDeviceSurfaceFormatsKHR(physical_device, surface, &format_count, candidates.data()));
|
|
||||||
|
|
||||||
// special case that means we can choose any format
|
|
||||||
if (candidates.size() == 1 && candidates[0].format == VK_FORMAT_UNDEFINED) {
|
|
||||||
VkSurfaceFormatKHR surface_format;
|
|
||||||
surface_format.format = VK_FORMAT_R8G8B8A8_UNORM;
|
|
||||||
surface_format.colorSpace = VK_COLORSPACE_SRGB_NONLINEAR_KHR;
|
|
||||||
return surface_format;
|
|
||||||
}
|
|
||||||
return candidates[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
static VkSwapchainKHR create_swapchain(VkPhysicalDevice physical_device, VkDevice device, VkSurfaceKHR surface, VkSurfaceFormatKHR surface_format) {
|
static VkSwapchainKHR create_swapchain(VkPhysicalDevice physical_device, VkDevice device, VkSurfaceKHR surface, VkSurfaceFormatKHR surface_format) {
|
||||||
VkSurfaceCapabilitiesKHR surface_caps;
|
VkSurfaceCapabilitiesKHR surface_caps;
|
||||||
VK_CHECK(vkGetPhysicalDeviceSurfaceCapabilitiesKHR(physical_device, surface, &surface_caps));
|
VK_CHECK(vkGetPhysicalDeviceSurfaceCapabilitiesKHR(physical_device, surface, &surface_caps));
|
||||||
|
|
@ -490,7 +385,7 @@ static void ensure_staging_buffer_allocation(VkDeviceSize size) {
|
||||||
|
|
||||||
VkPipeline create_pipeline(const Vk_Pipeline_Def&);
|
VkPipeline create_pipeline(const Vk_Pipeline_Def&);
|
||||||
|
|
||||||
void vk_create_instance() {
|
static void create_instance() {
|
||||||
uint32_t count = 0;
|
uint32_t count = 0;
|
||||||
VK_CHECK(vkEnumerateInstanceExtensionProperties(nullptr, &count, nullptr));
|
VK_CHECK(vkEnumerateInstanceExtensionProperties(nullptr, &count, nullptr));
|
||||||
|
|
||||||
|
|
@ -515,20 +410,315 @@ void vk_create_instance() {
|
||||||
VK_CHECK(vkCreateInstance(&desc, nullptr, &vk.instance));
|
VK_CHECK(vkCreateInstance(&desc, nullptr, &vk.instance));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void create_device() {
|
||||||
|
// select physical device
|
||||||
|
{
|
||||||
|
uint32_t count;
|
||||||
|
VK_CHECK(vkEnumeratePhysicalDevices(vk.instance, &count, nullptr));
|
||||||
|
|
||||||
|
if (count == 0)
|
||||||
|
ri.Error(ERR_FATAL, "Vulkan error: no physical device found");
|
||||||
|
|
||||||
|
std::vector<VkPhysicalDevice> physical_devices(count);
|
||||||
|
VK_CHECK(vkEnumeratePhysicalDevices(vk.instance, &count, physical_devices.data()));
|
||||||
|
vk.physical_device = physical_devices[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
vk_imp_create_surface();
|
||||||
|
|
||||||
|
// select surface format
|
||||||
|
{
|
||||||
|
uint32_t format_count;
|
||||||
|
VK_CHECK(vkGetPhysicalDeviceSurfaceFormatsKHR(vk.physical_device, vk.surface, &format_count, nullptr));
|
||||||
|
assert(format_count > 0);
|
||||||
|
|
||||||
|
std::vector<VkSurfaceFormatKHR> candidates(format_count);
|
||||||
|
VK_CHECK(vkGetPhysicalDeviceSurfaceFormatsKHR(vk.physical_device, vk.surface, &format_count, candidates.data()));
|
||||||
|
|
||||||
|
|
||||||
|
if (candidates.size() == 1 && candidates[0].format == VK_FORMAT_UNDEFINED) { // special case that means we can choose any format
|
||||||
|
vk.surface_format.format = VK_FORMAT_R8G8B8A8_UNORM;
|
||||||
|
vk.surface_format.colorSpace = VK_COLORSPACE_SRGB_NONLINEAR_KHR;
|
||||||
|
} else {
|
||||||
|
vk.surface_format = candidates[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// select queue family
|
||||||
|
{
|
||||||
|
uint32_t queue_family_count;
|
||||||
|
vkGetPhysicalDeviceQueueFamilyProperties(vk.physical_device, &queue_family_count, nullptr);
|
||||||
|
|
||||||
|
std::vector<VkQueueFamilyProperties> queue_families(queue_family_count);
|
||||||
|
vkGetPhysicalDeviceQueueFamilyProperties(vk.physical_device, &queue_family_count, queue_families.data());
|
||||||
|
|
||||||
|
// select queue family with presentation and graphics support
|
||||||
|
vk.queue_family_index = -1;
|
||||||
|
for (uint32_t i = 0; i < queue_family_count; i++) {
|
||||||
|
VkBool32 presentation_supported;
|
||||||
|
VK_CHECK(vkGetPhysicalDeviceSurfaceSupportKHR(vk.physical_device, i, vk.surface, &presentation_supported));
|
||||||
|
|
||||||
|
if (presentation_supported && (queue_families[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) != 0) {
|
||||||
|
vk.queue_family_index = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (vk.queue_family_index == -1)
|
||||||
|
ri.Error(ERR_FATAL, "Vulkan error: failed to find queue family");
|
||||||
|
}
|
||||||
|
|
||||||
|
// create VkDevice
|
||||||
|
{
|
||||||
|
uint32_t count = 0;
|
||||||
|
VK_CHECK(vkEnumerateDeviceExtensionProperties(vk.physical_device, nullptr, &count, nullptr));
|
||||||
|
|
||||||
|
std::vector<VkExtensionProperties> extension_properties(count);
|
||||||
|
VK_CHECK(vkEnumerateDeviceExtensionProperties(vk.physical_device, nullptr, &count, extension_properties.data()));
|
||||||
|
|
||||||
|
for (auto name : device_extensions) {
|
||||||
|
if (!is_extension_available(extension_properties, name))
|
||||||
|
ri.Error(ERR_FATAL, "Vulkan error: required device extension is not available: %s", name);
|
||||||
|
}
|
||||||
|
|
||||||
|
const float priority = 1.0;
|
||||||
|
VkDeviceQueueCreateInfo queue_desc;
|
||||||
|
queue_desc.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
|
||||||
|
queue_desc.pNext = nullptr;
|
||||||
|
queue_desc.flags = 0;
|
||||||
|
queue_desc.queueFamilyIndex = vk.queue_family_index;
|
||||||
|
queue_desc.queueCount = 1;
|
||||||
|
queue_desc.pQueuePriorities = &priority;
|
||||||
|
|
||||||
|
VkPhysicalDeviceFeatures features;
|
||||||
|
Com_Memset(&features, 0, sizeof(features));
|
||||||
|
features.shaderClipDistance = VK_TRUE;
|
||||||
|
|
||||||
|
VkDeviceCreateInfo device_desc;
|
||||||
|
device_desc.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
|
||||||
|
device_desc.pNext = nullptr;
|
||||||
|
device_desc.flags = 0;
|
||||||
|
device_desc.queueCreateInfoCount = 1;
|
||||||
|
device_desc.pQueueCreateInfos = &queue_desc;
|
||||||
|
device_desc.enabledLayerCount = 0;
|
||||||
|
device_desc.ppEnabledLayerNames = nullptr;
|
||||||
|
device_desc.enabledExtensionCount = static_cast<uint32_t>(device_extensions.size());
|
||||||
|
device_desc.ppEnabledExtensionNames = device_extensions.data();
|
||||||
|
device_desc.pEnabledFeatures = &features;
|
||||||
|
VK_CHECK(vkCreateDevice(vk.physical_device, &device_desc, nullptr, &vk.device));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#define INIT_INSTANCE_FUNCTION(func) func = (PFN_ ## func)vkGetInstanceProcAddr(vk.instance, #func);
|
||||||
|
#define INIT_DEVICE_FUNCTION(func) func = (PFN_ ## func)vkGetDeviceProcAddr(vk.device, #func);
|
||||||
|
|
||||||
|
static void init_vulkan_library() {
|
||||||
|
//
|
||||||
|
// Get functions that do not depend on VkInstance (vk.instance == nullptr at this point).
|
||||||
|
//
|
||||||
|
INIT_INSTANCE_FUNCTION(vkCreateInstance)
|
||||||
|
INIT_INSTANCE_FUNCTION(vkEnumerateInstanceExtensionProperties)
|
||||||
|
|
||||||
|
//
|
||||||
|
// Get instance level functions.
|
||||||
|
//
|
||||||
|
create_instance();
|
||||||
|
INIT_INSTANCE_FUNCTION(vkCreateDevice)
|
||||||
|
INIT_INSTANCE_FUNCTION(vkEnumerateDeviceExtensionProperties)
|
||||||
|
INIT_INSTANCE_FUNCTION(vkEnumeratePhysicalDevices)
|
||||||
|
INIT_INSTANCE_FUNCTION(vkGetDeviceProcAddr)
|
||||||
|
INIT_INSTANCE_FUNCTION(vkGetPhysicalDeviceFeatures)
|
||||||
|
INIT_INSTANCE_FUNCTION(vkGetPhysicalDeviceFormatProperties)
|
||||||
|
INIT_INSTANCE_FUNCTION(vkGetPhysicalDeviceMemoryProperties)
|
||||||
|
INIT_INSTANCE_FUNCTION(vkGetPhysicalDeviceProperties)
|
||||||
|
INIT_INSTANCE_FUNCTION(vkGetPhysicalDeviceQueueFamilyProperties)
|
||||||
|
INIT_INSTANCE_FUNCTION(vkCreateWin32SurfaceKHR)
|
||||||
|
INIT_INSTANCE_FUNCTION(vkDestroySurfaceKHR)
|
||||||
|
INIT_INSTANCE_FUNCTION(vkGetPhysicalDeviceSurfaceCapabilitiesKHR)
|
||||||
|
INIT_INSTANCE_FUNCTION(vkGetPhysicalDeviceSurfaceFormatsKHR)
|
||||||
|
INIT_INSTANCE_FUNCTION(vkGetPhysicalDeviceSurfacePresentModesKHR)
|
||||||
|
INIT_INSTANCE_FUNCTION(vkGetPhysicalDeviceSurfaceSupportKHR)
|
||||||
|
|
||||||
|
//
|
||||||
|
// Get device level functions.
|
||||||
|
//
|
||||||
|
create_device();
|
||||||
|
INIT_DEVICE_FUNCTION(vkAllocateCommandBuffers)
|
||||||
|
INIT_DEVICE_FUNCTION(vkAllocateDescriptorSets)
|
||||||
|
INIT_DEVICE_FUNCTION(vkAllocateMemory)
|
||||||
|
INIT_DEVICE_FUNCTION(vkBeginCommandBuffer)
|
||||||
|
INIT_DEVICE_FUNCTION(vkBindBufferMemory)
|
||||||
|
INIT_DEVICE_FUNCTION(vkBindImageMemory)
|
||||||
|
INIT_DEVICE_FUNCTION(vkCmdBeginRenderPass)
|
||||||
|
INIT_DEVICE_FUNCTION(vkCmdBindDescriptorSets)
|
||||||
|
INIT_DEVICE_FUNCTION(vkCmdBindIndexBuffer)
|
||||||
|
INIT_DEVICE_FUNCTION(vkCmdBindPipeline)
|
||||||
|
INIT_DEVICE_FUNCTION(vkCmdBindVertexBuffers)
|
||||||
|
INIT_DEVICE_FUNCTION(vkCmdClearAttachments)
|
||||||
|
INIT_DEVICE_FUNCTION(vkCmdCopyBufferToImage)
|
||||||
|
INIT_DEVICE_FUNCTION(vkCmdDrawIndexed)
|
||||||
|
INIT_DEVICE_FUNCTION(vkCmdEndRenderPass)
|
||||||
|
INIT_DEVICE_FUNCTION(vkCmdPipelineBarrier)
|
||||||
|
INIT_DEVICE_FUNCTION(vkCmdPushConstants)
|
||||||
|
INIT_DEVICE_FUNCTION(vkCmdSetDepthBias)
|
||||||
|
INIT_DEVICE_FUNCTION(vkCmdSetScissor)
|
||||||
|
INIT_DEVICE_FUNCTION(vkCmdSetViewport)
|
||||||
|
INIT_DEVICE_FUNCTION(vkCreateBuffer)
|
||||||
|
INIT_DEVICE_FUNCTION(vkCreateCommandPool)
|
||||||
|
INIT_DEVICE_FUNCTION(vkCreateDescriptorPool)
|
||||||
|
INIT_DEVICE_FUNCTION(vkCreateDescriptorSetLayout)
|
||||||
|
INIT_DEVICE_FUNCTION(vkCreateFence)
|
||||||
|
INIT_DEVICE_FUNCTION(vkCreateFramebuffer)
|
||||||
|
INIT_DEVICE_FUNCTION(vkCreateGraphicsPipelines)
|
||||||
|
INIT_DEVICE_FUNCTION(vkCreateImage)
|
||||||
|
INIT_DEVICE_FUNCTION(vkCreateImageView)
|
||||||
|
INIT_DEVICE_FUNCTION(vkCreatePipelineLayout)
|
||||||
|
INIT_DEVICE_FUNCTION(vkCreateRenderPass)
|
||||||
|
INIT_DEVICE_FUNCTION(vkCreateSampler)
|
||||||
|
INIT_DEVICE_FUNCTION(vkCreateSemaphore)
|
||||||
|
INIT_DEVICE_FUNCTION(vkCreateShaderModule)
|
||||||
|
INIT_DEVICE_FUNCTION(vkDestroyBuffer)
|
||||||
|
INIT_DEVICE_FUNCTION(vkDestroyCommandPool)
|
||||||
|
INIT_DEVICE_FUNCTION(vkDestroyDescriptorPool)
|
||||||
|
INIT_DEVICE_FUNCTION(vkDestroyDescriptorSetLayout)
|
||||||
|
INIT_DEVICE_FUNCTION(vkDestroyDevice)
|
||||||
|
INIT_DEVICE_FUNCTION(vkDestroyFence)
|
||||||
|
INIT_DEVICE_FUNCTION(vkDestroyFramebuffer)
|
||||||
|
INIT_DEVICE_FUNCTION(vkDestroyImage)
|
||||||
|
INIT_DEVICE_FUNCTION(vkDestroyImageView)
|
||||||
|
INIT_DEVICE_FUNCTION(vkDestroyInstance)
|
||||||
|
INIT_DEVICE_FUNCTION(vkDestroyPipeline)
|
||||||
|
INIT_DEVICE_FUNCTION(vkDestroyPipelineLayout)
|
||||||
|
INIT_DEVICE_FUNCTION(vkDestroyRenderPass)
|
||||||
|
INIT_DEVICE_FUNCTION(vkDestroySampler)
|
||||||
|
INIT_DEVICE_FUNCTION(vkDestroySemaphore)
|
||||||
|
INIT_DEVICE_FUNCTION(vkDestroyShaderModule)
|
||||||
|
INIT_DEVICE_FUNCTION(vkDeviceWaitIdle)
|
||||||
|
INIT_DEVICE_FUNCTION(vkEndCommandBuffer)
|
||||||
|
INIT_DEVICE_FUNCTION(vkFreeCommandBuffers)
|
||||||
|
INIT_DEVICE_FUNCTION(vkFreeDescriptorSets)
|
||||||
|
INIT_DEVICE_FUNCTION(vkFreeMemory)
|
||||||
|
INIT_DEVICE_FUNCTION(vkGetBufferMemoryRequirements)
|
||||||
|
INIT_DEVICE_FUNCTION(vkGetDeviceQueue)
|
||||||
|
INIT_DEVICE_FUNCTION(vkGetImageMemoryRequirements)
|
||||||
|
INIT_DEVICE_FUNCTION(vkMapMemory)
|
||||||
|
INIT_DEVICE_FUNCTION(vkQueueSubmit)
|
||||||
|
INIT_DEVICE_FUNCTION(vkQueueWaitIdle)
|
||||||
|
INIT_DEVICE_FUNCTION(vkResetDescriptorPool)
|
||||||
|
INIT_DEVICE_FUNCTION(vkResetFences)
|
||||||
|
INIT_DEVICE_FUNCTION(vkUpdateDescriptorSets)
|
||||||
|
INIT_DEVICE_FUNCTION(vkWaitForFences)
|
||||||
|
INIT_DEVICE_FUNCTION(vkAcquireNextImageKHR)
|
||||||
|
INIT_DEVICE_FUNCTION(vkCreateSwapchainKHR)
|
||||||
|
INIT_DEVICE_FUNCTION(vkDestroySwapchainKHR)
|
||||||
|
INIT_DEVICE_FUNCTION(vkGetSwapchainImagesKHR)
|
||||||
|
INIT_DEVICE_FUNCTION(vkQueuePresentKHR)
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef INIT_INSTANCE_FUNCTION
|
||||||
|
#undef INIT_DEVICE_FUNCTION
|
||||||
|
|
||||||
|
static void deinit_vulkan_library() {
|
||||||
|
vkCreateInstance = nullptr;
|
||||||
|
vkEnumerateInstanceExtensionProperties = nullptr;
|
||||||
|
|
||||||
|
vkCreateDevice = nullptr;
|
||||||
|
vkEnumerateDeviceExtensionProperties = nullptr;
|
||||||
|
vkEnumeratePhysicalDevices = nullptr;
|
||||||
|
vkGetDeviceProcAddr = nullptr;
|
||||||
|
vkGetPhysicalDeviceFeatures = nullptr;
|
||||||
|
vkGetPhysicalDeviceFormatProperties = nullptr;
|
||||||
|
vkGetPhysicalDeviceMemoryProperties = nullptr;
|
||||||
|
vkGetPhysicalDeviceProperties = nullptr;
|
||||||
|
vkGetPhysicalDeviceQueueFamilyProperties = nullptr;
|
||||||
|
vkCreateWin32SurfaceKHR = nullptr;
|
||||||
|
vkDestroySurfaceKHR = nullptr;
|
||||||
|
vkGetPhysicalDeviceSurfaceCapabilitiesKHR = nullptr;
|
||||||
|
vkGetPhysicalDeviceSurfaceFormatsKHR = nullptr;
|
||||||
|
vkGetPhysicalDeviceSurfacePresentModesKHR = nullptr;
|
||||||
|
vkGetPhysicalDeviceSurfaceSupportKHR = nullptr;
|
||||||
|
|
||||||
|
vkAllocateCommandBuffers = nullptr;
|
||||||
|
vkAllocateDescriptorSets = nullptr;
|
||||||
|
vkAllocateMemory = nullptr;
|
||||||
|
vkBeginCommandBuffer = nullptr;
|
||||||
|
vkBindBufferMemory = nullptr;
|
||||||
|
vkBindImageMemory = nullptr;
|
||||||
|
vkCmdBeginRenderPass = nullptr;
|
||||||
|
vkCmdBindDescriptorSets = nullptr;
|
||||||
|
vkCmdBindIndexBuffer = nullptr;
|
||||||
|
vkCmdBindPipeline = nullptr;
|
||||||
|
vkCmdBindVertexBuffers = nullptr;
|
||||||
|
vkCmdClearAttachments = nullptr;
|
||||||
|
vkCmdCopyBufferToImage = nullptr;
|
||||||
|
vkCmdDrawIndexed = nullptr;
|
||||||
|
vkCmdEndRenderPass = nullptr;
|
||||||
|
vkCmdPipelineBarrier = nullptr;
|
||||||
|
vkCmdPushConstants = nullptr;
|
||||||
|
vkCmdSetDepthBias = nullptr;
|
||||||
|
vkCmdSetScissor = nullptr;
|
||||||
|
vkCmdSetViewport = nullptr;
|
||||||
|
vkCreateBuffer = nullptr;
|
||||||
|
vkCreateCommandPool = nullptr;
|
||||||
|
vkCreateDescriptorPool = nullptr;
|
||||||
|
vkCreateDescriptorSetLayout = nullptr;
|
||||||
|
vkCreateFence = nullptr;
|
||||||
|
vkCreateFramebuffer = nullptr;
|
||||||
|
vkCreateGraphicsPipelines = nullptr;
|
||||||
|
vkCreateImage = nullptr;
|
||||||
|
vkCreateImageView = nullptr;
|
||||||
|
vkCreatePipelineLayout = nullptr;
|
||||||
|
vkCreateRenderPass = nullptr;
|
||||||
|
vkCreateSampler = nullptr;
|
||||||
|
vkCreateSemaphore = nullptr;
|
||||||
|
vkCreateShaderModule = nullptr;
|
||||||
|
vkDestroyBuffer = nullptr;
|
||||||
|
vkDestroyCommandPool = nullptr;
|
||||||
|
vkDestroyDescriptorPool = nullptr;
|
||||||
|
vkDestroyDescriptorSetLayout = nullptr;
|
||||||
|
vkDestroyDevice = nullptr;
|
||||||
|
vkDestroyFence = nullptr;
|
||||||
|
vkDestroyFramebuffer = nullptr;
|
||||||
|
vkDestroyImage = nullptr;
|
||||||
|
vkDestroyImageView = nullptr;
|
||||||
|
vkDestroyInstance = nullptr;
|
||||||
|
vkDestroyPipeline = nullptr;
|
||||||
|
vkDestroyPipelineLayout = nullptr;
|
||||||
|
vkDestroyRenderPass = nullptr;
|
||||||
|
vkDestroySampler = nullptr;
|
||||||
|
vkDestroySemaphore = nullptr;
|
||||||
|
vkDestroyShaderModule = nullptr;
|
||||||
|
vkDeviceWaitIdle = nullptr;
|
||||||
|
vkEndCommandBuffer = nullptr;
|
||||||
|
vkFreeCommandBuffers = nullptr;
|
||||||
|
vkFreeDescriptorSets = nullptr;
|
||||||
|
vkFreeMemory = nullptr;
|
||||||
|
vkGetBufferMemoryRequirements = nullptr;
|
||||||
|
vkGetDeviceQueue = nullptr;
|
||||||
|
vkGetImageMemoryRequirements = nullptr;
|
||||||
|
vkMapMemory = nullptr;
|
||||||
|
vkQueueSubmit = nullptr;
|
||||||
|
vkQueueWaitIdle = nullptr;
|
||||||
|
vkResetDescriptorPool = nullptr;
|
||||||
|
vkResetFences = nullptr;
|
||||||
|
vkUpdateDescriptorSets = nullptr;
|
||||||
|
vkWaitForFences = nullptr;
|
||||||
|
vkAcquireNextImageKHR = nullptr;
|
||||||
|
vkCreateSwapchainKHR = nullptr;
|
||||||
|
vkDestroySwapchainKHR = nullptr;
|
||||||
|
vkGetSwapchainImagesKHR = nullptr;
|
||||||
|
vkQueuePresentKHR = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
void vk_initialize() {
|
void vk_initialize() {
|
||||||
vk_log_file = fopen("vk_dev.log", "w");
|
vk_log_file = fopen("vk_dev.log", "w");
|
||||||
|
|
||||||
vk.physical_device = select_physical_device(vk.instance);
|
init_vulkan_library();
|
||||||
|
|
||||||
VkPhysicalDeviceFeatures features;
|
VkPhysicalDeviceFeatures features;
|
||||||
vkGetPhysicalDeviceFeatures(vk.physical_device, &features);
|
vkGetPhysicalDeviceFeatures(vk.physical_device, &features);
|
||||||
if (features.shaderClipDistance == VK_FALSE)
|
if (features.shaderClipDistance == VK_FALSE)
|
||||||
ri.Error(ERR_FATAL, "vk_create_instance: shaderClipDistance feature is not supported");
|
ri.Error(ERR_FATAL, "vk_create_instance: shaderClipDistance feature is not supported");
|
||||||
|
|
||||||
vk.surface_format = select_surface_format(vk.physical_device, vk.surface);
|
|
||||||
|
|
||||||
vk.queue_family_index = select_queue_family(vk.physical_device, vk.surface);
|
|
||||||
vk.device = create_device(vk.physical_device, vk.queue_family_index);
|
|
||||||
vkGetDeviceQueue(vk.device, vk.queue_family_index, 0, &vk.queue);
|
vkGetDeviceQueue(vk.device, vk.queue_family_index, 0, &vk.queue);
|
||||||
|
|
||||||
vk.swapchain = create_swapchain(vk.physical_device, vk.device, vk.surface, vk.surface_format);
|
vk.swapchain = create_swapchain(vk.physical_device, vk.device, vk.surface, vk.surface_format);
|
||||||
|
|
@ -968,6 +1158,7 @@ void vk_shutdown() {
|
||||||
vkDestroyInstance(vk.instance, nullptr);
|
vkDestroyInstance(vk.instance, nullptr);
|
||||||
|
|
||||||
Com_Memset(&vk, 0, sizeof(vk));
|
Com_Memset(&vk, 0, sizeof(vk));
|
||||||
|
deinit_vulkan_library();
|
||||||
}
|
}
|
||||||
|
|
||||||
static float pipeline_create_time;
|
static float pipeline_create_time;
|
||||||
|
|
@ -1970,3 +2161,95 @@ void vk_end_frame() {
|
||||||
present_info.pResults = nullptr;
|
present_info.pResults = nullptr;
|
||||||
VK_CHECK(vkQueuePresentKHR(vk.queue, &present_info));
|
VK_CHECK(vkQueuePresentKHR(vk.queue, &present_info));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr;
|
||||||
|
|
||||||
|
PFN_vkCreateInstance vkCreateInstance;
|
||||||
|
PFN_vkEnumerateInstanceExtensionProperties vkEnumerateInstanceExtensionProperties;
|
||||||
|
|
||||||
|
PFN_vkCreateDevice vkCreateDevice;
|
||||||
|
PFN_vkEnumerateDeviceExtensionProperties vkEnumerateDeviceExtensionProperties;
|
||||||
|
PFN_vkEnumeratePhysicalDevices vkEnumeratePhysicalDevices;
|
||||||
|
PFN_vkGetDeviceProcAddr vkGetDeviceProcAddr;
|
||||||
|
PFN_vkGetPhysicalDeviceFeatures vkGetPhysicalDeviceFeatures;
|
||||||
|
PFN_vkGetPhysicalDeviceFormatProperties vkGetPhysicalDeviceFormatProperties;
|
||||||
|
PFN_vkGetPhysicalDeviceMemoryProperties vkGetPhysicalDeviceMemoryProperties;
|
||||||
|
PFN_vkGetPhysicalDeviceProperties vkGetPhysicalDeviceProperties;
|
||||||
|
PFN_vkGetPhysicalDeviceQueueFamilyProperties vkGetPhysicalDeviceQueueFamilyProperties;
|
||||||
|
PFN_vkCreateWin32SurfaceKHR vkCreateWin32SurfaceKHR;
|
||||||
|
PFN_vkDestroySurfaceKHR vkDestroySurfaceKHR;
|
||||||
|
PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR vkGetPhysicalDeviceSurfaceCapabilitiesKHR;
|
||||||
|
PFN_vkGetPhysicalDeviceSurfaceFormatsKHR vkGetPhysicalDeviceSurfaceFormatsKHR;
|
||||||
|
PFN_vkGetPhysicalDeviceSurfacePresentModesKHR vkGetPhysicalDeviceSurfacePresentModesKHR;
|
||||||
|
PFN_vkGetPhysicalDeviceSurfaceSupportKHR vkGetPhysicalDeviceSurfaceSupportKHR;
|
||||||
|
|
||||||
|
PFN_vkAllocateCommandBuffers vkAllocateCommandBuffers;
|
||||||
|
PFN_vkAllocateDescriptorSets vkAllocateDescriptorSets;
|
||||||
|
PFN_vkAllocateMemory vkAllocateMemory;
|
||||||
|
PFN_vkBeginCommandBuffer vkBeginCommandBuffer;
|
||||||
|
PFN_vkBindBufferMemory vkBindBufferMemory;
|
||||||
|
PFN_vkBindImageMemory vkBindImageMemory;
|
||||||
|
PFN_vkCmdBeginRenderPass vkCmdBeginRenderPass;
|
||||||
|
PFN_vkCmdBindDescriptorSets vkCmdBindDescriptorSets;
|
||||||
|
PFN_vkCmdBindIndexBuffer vkCmdBindIndexBuffer;
|
||||||
|
PFN_vkCmdBindPipeline vkCmdBindPipeline;
|
||||||
|
PFN_vkCmdBindVertexBuffers vkCmdBindVertexBuffers;
|
||||||
|
PFN_vkCmdClearAttachments vkCmdClearAttachments;
|
||||||
|
PFN_vkCmdCopyBufferToImage vkCmdCopyBufferToImage;
|
||||||
|
PFN_vkCmdDrawIndexed vkCmdDrawIndexed;
|
||||||
|
PFN_vkCmdEndRenderPass vkCmdEndRenderPass;
|
||||||
|
PFN_vkCmdPipelineBarrier vkCmdPipelineBarrier;
|
||||||
|
PFN_vkCmdPushConstants vkCmdPushConstants;
|
||||||
|
PFN_vkCmdSetDepthBias vkCmdSetDepthBias;
|
||||||
|
PFN_vkCmdSetScissor vkCmdSetScissor;
|
||||||
|
PFN_vkCmdSetViewport vkCmdSetViewport;
|
||||||
|
PFN_vkCreateBuffer vkCreateBuffer;
|
||||||
|
PFN_vkCreateCommandPool vkCreateCommandPool;
|
||||||
|
PFN_vkCreateDescriptorPool vkCreateDescriptorPool;
|
||||||
|
PFN_vkCreateDescriptorSetLayout vkCreateDescriptorSetLayout;
|
||||||
|
PFN_vkCreateFence vkCreateFence;
|
||||||
|
PFN_vkCreateFramebuffer vkCreateFramebuffer;
|
||||||
|
PFN_vkCreateGraphicsPipelines vkCreateGraphicsPipelines;
|
||||||
|
PFN_vkCreateImage vkCreateImage;
|
||||||
|
PFN_vkCreateImageView vkCreateImageView;
|
||||||
|
PFN_vkCreatePipelineLayout vkCreatePipelineLayout;
|
||||||
|
PFN_vkCreateRenderPass vkCreateRenderPass;
|
||||||
|
PFN_vkCreateSampler vkCreateSampler;
|
||||||
|
PFN_vkCreateSemaphore vkCreateSemaphore;
|
||||||
|
PFN_vkCreateShaderModule vkCreateShaderModule;
|
||||||
|
PFN_vkDestroyBuffer vkDestroyBuffer;
|
||||||
|
PFN_vkDestroyCommandPool vkDestroyCommandPool;
|
||||||
|
PFN_vkDestroyDescriptorPool vkDestroyDescriptorPool;
|
||||||
|
PFN_vkDestroyDescriptorSetLayout vkDestroyDescriptorSetLayout;
|
||||||
|
PFN_vkDestroyDevice vkDestroyDevice;
|
||||||
|
PFN_vkDestroyFence vkDestroyFence;
|
||||||
|
PFN_vkDestroyFramebuffer vkDestroyFramebuffer;
|
||||||
|
PFN_vkDestroyImage vkDestroyImage;
|
||||||
|
PFN_vkDestroyImageView vkDestroyImageView;
|
||||||
|
PFN_vkDestroyInstance vkDestroyInstance;
|
||||||
|
PFN_vkDestroyPipeline vkDestroyPipeline;
|
||||||
|
PFN_vkDestroyPipelineLayout vkDestroyPipelineLayout;
|
||||||
|
PFN_vkDestroyRenderPass vkDestroyRenderPass;
|
||||||
|
PFN_vkDestroySampler vkDestroySampler;
|
||||||
|
PFN_vkDestroySemaphore vkDestroySemaphore;
|
||||||
|
PFN_vkDestroyShaderModule vkDestroyShaderModule;
|
||||||
|
PFN_vkDeviceWaitIdle vkDeviceWaitIdle;
|
||||||
|
PFN_vkEndCommandBuffer vkEndCommandBuffer;
|
||||||
|
PFN_vkFreeCommandBuffers vkFreeCommandBuffers;
|
||||||
|
PFN_vkFreeDescriptorSets vkFreeDescriptorSets;
|
||||||
|
PFN_vkFreeMemory vkFreeMemory;
|
||||||
|
PFN_vkGetBufferMemoryRequirements vkGetBufferMemoryRequirements;
|
||||||
|
PFN_vkGetDeviceQueue vkGetDeviceQueue;
|
||||||
|
PFN_vkGetImageMemoryRequirements vkGetImageMemoryRequirements;
|
||||||
|
PFN_vkMapMemory vkMapMemory;
|
||||||
|
PFN_vkQueueSubmit vkQueueSubmit;
|
||||||
|
PFN_vkQueueWaitIdle vkQueueWaitIdle;
|
||||||
|
PFN_vkResetDescriptorPool vkResetDescriptorPool;
|
||||||
|
PFN_vkResetFences vkResetFences;
|
||||||
|
PFN_vkUpdateDescriptorSets vkUpdateDescriptorSets;
|
||||||
|
PFN_vkWaitForFences vkWaitForFences;
|
||||||
|
PFN_vkAcquireNextImageKHR vkAcquireNextImageKHR;
|
||||||
|
PFN_vkCreateSwapchainKHR vkCreateSwapchainKHR;
|
||||||
|
PFN_vkDestroySwapchainKHR vkDestroySwapchainKHR;
|
||||||
|
PFN_vkGetSwapchainImagesKHR vkGetSwapchainImagesKHR;
|
||||||
|
PFN_vkQueuePresentKHR vkQueuePresentKHR;
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
#define NOMINMAX
|
#define NOMINMAX
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define VK_NO_PROTOTYPES
|
||||||
#include "vulkan/vulkan.h"
|
#include "vulkan/vulkan.h"
|
||||||
|
|
||||||
const int MAX_SWAPCHAIN_IMAGES = 8;
|
const int MAX_SWAPCHAIN_IMAGES = 8;
|
||||||
|
|
@ -55,9 +56,6 @@ struct Vk_Image {
|
||||||
// Initialization.
|
// Initialization.
|
||||||
//
|
//
|
||||||
|
|
||||||
// Creates VkInstance and stores it as Vk_Instance::instance.
|
|
||||||
void vk_create_instance();
|
|
||||||
|
|
||||||
// Initializes VK_Instance structure.
|
// Initializes VK_Instance structure.
|
||||||
// After calling this function we get fully functional vulkan subsystem.
|
// After calling this function we get fully functional vulkan subsystem.
|
||||||
void vk_initialize();
|
void vk_initialize();
|
||||||
|
|
@ -201,3 +199,96 @@ struct Vk_Resources {
|
||||||
// cleared by render pass instance clear op (dirty_attachments == false).
|
// cleared by render pass instance clear op (dirty_attachments == false).
|
||||||
bool dirty_attachments;
|
bool dirty_attachments;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Vulkan API function pointers.
|
||||||
|
extern PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr;
|
||||||
|
|
||||||
|
extern PFN_vkCreateInstance vkCreateInstance;
|
||||||
|
extern PFN_vkEnumerateInstanceExtensionProperties vkEnumerateInstanceExtensionProperties;
|
||||||
|
|
||||||
|
extern PFN_vkCreateDevice vkCreateDevice;
|
||||||
|
extern PFN_vkEnumerateDeviceExtensionProperties vkEnumerateDeviceExtensionProperties;
|
||||||
|
extern PFN_vkEnumeratePhysicalDevices vkEnumeratePhysicalDevices;
|
||||||
|
extern PFN_vkGetDeviceProcAddr vkGetDeviceProcAddr;
|
||||||
|
extern PFN_vkGetPhysicalDeviceFeatures vkGetPhysicalDeviceFeatures;
|
||||||
|
extern PFN_vkGetPhysicalDeviceFormatProperties vkGetPhysicalDeviceFormatProperties;
|
||||||
|
extern PFN_vkGetPhysicalDeviceMemoryProperties vkGetPhysicalDeviceMemoryProperties;
|
||||||
|
extern PFN_vkGetPhysicalDeviceProperties vkGetPhysicalDeviceProperties;
|
||||||
|
extern PFN_vkGetPhysicalDeviceQueueFamilyProperties vkGetPhysicalDeviceQueueFamilyProperties;
|
||||||
|
extern PFN_vkCreateWin32SurfaceKHR vkCreateWin32SurfaceKHR;
|
||||||
|
extern PFN_vkDestroySurfaceKHR vkDestroySurfaceKHR;
|
||||||
|
extern PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR vkGetPhysicalDeviceSurfaceCapabilitiesKHR;
|
||||||
|
extern PFN_vkGetPhysicalDeviceSurfaceFormatsKHR vkGetPhysicalDeviceSurfaceFormatsKHR;
|
||||||
|
extern PFN_vkGetPhysicalDeviceSurfacePresentModesKHR vkGetPhysicalDeviceSurfacePresentModesKHR;
|
||||||
|
extern PFN_vkGetPhysicalDeviceSurfaceSupportKHR vkGetPhysicalDeviceSurfaceSupportKHR;
|
||||||
|
|
||||||
|
extern PFN_vkAllocateCommandBuffers vkAllocateCommandBuffers;
|
||||||
|
extern PFN_vkAllocateDescriptorSets vkAllocateDescriptorSets;
|
||||||
|
extern PFN_vkAllocateMemory vkAllocateMemory;
|
||||||
|
extern PFN_vkBeginCommandBuffer vkBeginCommandBuffer;
|
||||||
|
extern PFN_vkBindBufferMemory vkBindBufferMemory;
|
||||||
|
extern PFN_vkBindImageMemory vkBindImageMemory;
|
||||||
|
extern PFN_vkCmdBeginRenderPass vkCmdBeginRenderPass;
|
||||||
|
extern PFN_vkCmdBindDescriptorSets vkCmdBindDescriptorSets;
|
||||||
|
extern PFN_vkCmdBindIndexBuffer vkCmdBindIndexBuffer;
|
||||||
|
extern PFN_vkCmdBindPipeline vkCmdBindPipeline;
|
||||||
|
extern PFN_vkCmdBindVertexBuffers vkCmdBindVertexBuffers;
|
||||||
|
extern PFN_vkCmdClearAttachments vkCmdClearAttachments;
|
||||||
|
extern PFN_vkCmdCopyBufferToImage vkCmdCopyBufferToImage;
|
||||||
|
extern PFN_vkCmdDrawIndexed vkCmdDrawIndexed;
|
||||||
|
extern PFN_vkCmdEndRenderPass vkCmdEndRenderPass;
|
||||||
|
extern PFN_vkCmdPipelineBarrier vkCmdPipelineBarrier;
|
||||||
|
extern PFN_vkCmdPushConstants vkCmdPushConstants;
|
||||||
|
extern PFN_vkCmdSetDepthBias vkCmdSetDepthBias;
|
||||||
|
extern PFN_vkCmdSetScissor vkCmdSetScissor;
|
||||||
|
extern PFN_vkCmdSetViewport vkCmdSetViewport;
|
||||||
|
extern PFN_vkCreateBuffer vkCreateBuffer;
|
||||||
|
extern PFN_vkCreateCommandPool vkCreateCommandPool;
|
||||||
|
extern PFN_vkCreateDescriptorPool vkCreateDescriptorPool;
|
||||||
|
extern PFN_vkCreateDescriptorSetLayout vkCreateDescriptorSetLayout;
|
||||||
|
extern PFN_vkCreateFence vkCreateFence;
|
||||||
|
extern PFN_vkCreateFramebuffer vkCreateFramebuffer;
|
||||||
|
extern PFN_vkCreateGraphicsPipelines vkCreateGraphicsPipelines;
|
||||||
|
extern PFN_vkCreateImage vkCreateImage;
|
||||||
|
extern PFN_vkCreateImageView vkCreateImageView;
|
||||||
|
extern PFN_vkCreatePipelineLayout vkCreatePipelineLayout;
|
||||||
|
extern PFN_vkCreateRenderPass vkCreateRenderPass;
|
||||||
|
extern PFN_vkCreateSampler vkCreateSampler;
|
||||||
|
extern PFN_vkCreateSemaphore vkCreateSemaphore;
|
||||||
|
extern PFN_vkCreateShaderModule vkCreateShaderModule;
|
||||||
|
extern PFN_vkDestroyBuffer vkDestroyBuffer;
|
||||||
|
extern PFN_vkDestroyCommandPool vkDestroyCommandPool;
|
||||||
|
extern PFN_vkDestroyDescriptorPool vkDestroyDescriptorPool;
|
||||||
|
extern PFN_vkDestroyDescriptorSetLayout vkDestroyDescriptorSetLayout;
|
||||||
|
extern PFN_vkDestroyDevice vkDestroyDevice;
|
||||||
|
extern PFN_vkDestroyFence vkDestroyFence;
|
||||||
|
extern PFN_vkDestroyFramebuffer vkDestroyFramebuffer;
|
||||||
|
extern PFN_vkDestroyImage vkDestroyImage;
|
||||||
|
extern PFN_vkDestroyImageView vkDestroyImageView;
|
||||||
|
extern PFN_vkDestroyInstance vkDestroyInstance;
|
||||||
|
extern PFN_vkDestroyPipeline vkDestroyPipeline;
|
||||||
|
extern PFN_vkDestroyPipelineLayout vkDestroyPipelineLayout;
|
||||||
|
extern PFN_vkDestroyRenderPass vkDestroyRenderPass;
|
||||||
|
extern PFN_vkDestroySampler vkDestroySampler;
|
||||||
|
extern PFN_vkDestroySemaphore vkDestroySemaphore;
|
||||||
|
extern PFN_vkDestroyShaderModule vkDestroyShaderModule;
|
||||||
|
extern PFN_vkDeviceWaitIdle vkDeviceWaitIdle;
|
||||||
|
extern PFN_vkEndCommandBuffer vkEndCommandBuffer;
|
||||||
|
extern PFN_vkFreeCommandBuffers vkFreeCommandBuffers;
|
||||||
|
extern PFN_vkFreeDescriptorSets vkFreeDescriptorSets;
|
||||||
|
extern PFN_vkFreeMemory vkFreeMemory;
|
||||||
|
extern PFN_vkGetBufferMemoryRequirements vkGetBufferMemoryRequirements;
|
||||||
|
extern PFN_vkGetDeviceQueue vkGetDeviceQueue;
|
||||||
|
extern PFN_vkGetImageMemoryRequirements vkGetImageMemoryRequirements;
|
||||||
|
extern PFN_vkMapMemory vkMapMemory;
|
||||||
|
extern PFN_vkQueueSubmit vkQueueSubmit;
|
||||||
|
extern PFN_vkQueueWaitIdle vkQueueWaitIdle;
|
||||||
|
extern PFN_vkResetDescriptorPool vkResetDescriptorPool;
|
||||||
|
extern PFN_vkResetFences vkResetFences;
|
||||||
|
extern PFN_vkUpdateDescriptorSets vkUpdateDescriptorSets;
|
||||||
|
extern PFN_vkWaitForFences vkWaitForFences;
|
||||||
|
extern PFN_vkAcquireNextImageKHR vkAcquireNextImageKHR;
|
||||||
|
extern PFN_vkCreateSwapchainKHR vkCreateSwapchainKHR;
|
||||||
|
extern PFN_vkDestroySwapchainKHR vkDestroySwapchainKHR;
|
||||||
|
extern PFN_vkGetSwapchainImagesKHR vkGetSwapchainImagesKHR;
|
||||||
|
extern PFN_vkQueuePresentKHR vkQueuePresentKHR;
|
||||||
|
|
|
||||||
BIN
third_party/lib/vulkan-1.lib
vendored
BIN
third_party/lib/vulkan-1.lib
vendored
Binary file not shown.
Loading…
Reference in New Issue
Block a user