summaryrefslogtreecommitdiff
path: root/main.c
diff options
context:
space:
mode:
authorJordan Halase <jordan@halase.me>2019-10-27 23:08:04 -0500
committerJordan Halase <jordan@halase.me>2019-10-27 23:08:04 -0500
commit0854a0f3a0aa9d5c51b8d46686ce02723f14a666 (patch)
treec3f84170cca4c1abe7e98f0e6be90d0f3dfeaf85 /main.c
First Commit
Diffstat (limited to 'main.c')
-rw-r--r--main.c162
1 files changed, 162 insertions, 0 deletions
diff --git a/main.c b/main.c
new file mode 100644
index 0000000..cf59f16
--- /dev/null
+++ b/main.c
@@ -0,0 +1,162 @@
+/*
+Copyright (c) 2019, Jordan Halase <jordan@halase.me>
+
+Permission to use, copy, modify, and/or distribute this software for any
+purpose with or without fee is hereby granted, provided that the above
+copyright notice and this permission notice appear in all copies.
+
+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
+REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
+INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+PERFORMANCE OF THIS SOFTWARE.
+*/
+
+// TODO: Create debug report callback
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <vulkan/vulkan.h>
+
+#if defined(_WIN32)
+#include <windows.h>
+#include <vulkan/vulkan_win32.h>
+#else
+#include <X11/Xlib.h>
+#include <vulkan/vulkan_xlib.h>
+#endif
+
+struct RenderVulkan {
+ /** Put `device` first in struct to reduce pointer arithmetic on most Vulkan functions */
+ VkDevice device;
+ VkInstance instance;
+};
+
+struct RenderVulkan *vk;
+
+#if defined(_WIN32)
+void getRequiredInstanceExtensions(unsigned *nRequired, const char **extensions)
+{
+ static const char *const required[] = {
+ VK_KHR_SURFACE_EXTENSION_NAME,
+ VK_KHR_WIN32_SURFACE_EXTENSION_NAME
+ };
+ static const unsigned num = sizeof(required) / sizeof(required[0]);
+ if (extensions) {
+ for (int i = 0; i < num; ++i) {
+ extensions[i] = required[i];
+ }
+ } else {
+ *nRequired = num;
+ }
+}
+#else
+void getRequiredInstanceExtensions(unsigned *nRequired, const char **const extensions)
+{
+ static const char *const required[] = {
+ VK_KHR_SURFACE_EXTENSION_NAME,
+ VK_KHR_XLIB_SURFACE_EXTENSION_NAME
+ };
+ static const unsigned num = sizeof(required) / sizeof(required[0]);
+ if (extensions) {
+ for (int i = 0; i < num; ++i) {
+ extensions[i] = required[i];
+ }
+ } else {
+ *nRequired = num;
+ }
+}
+#endif
+
+void createInstance(struct RenderVulkan *vk,
+ const uint32_t nLayers, const char *const *layers,
+ const uint32_t nAdditional, const char *const *additionalExtensions)
+{
+ VkApplicationInfo appInfo = { 0 };
+ appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
+ appInfo.pApplicationName = "Pugl Vulkan Test";
+ appInfo.applicationVersion = VK_MAKE_VERSION(0, 1, 0);
+ appInfo.pEngineName = "Pugl Vulkan Test Engine";
+ appInfo.engineVersion = VK_MAKE_VERSION(0, 1, 0);
+ appInfo.apiVersion = VK_MAKE_VERSION(1, 0, 0); // MoltenVK for macOS only supports Vulkan 1.0
+
+ unsigned i, j, nRequired;
+ getRequiredInstanceExtensions(&nRequired, NULL);
+
+ const uint32_t nExtensions = nRequired + nAdditional;
+ const char **const extensions = malloc(sizeof(const char*) * nExtensions);
+
+ getRequiredInstanceExtensions(NULL, extensions);
+ for (i = nRequired, j = 0; i < nExtensions; ++i, ++j) {
+ extensions[i] = additionalExtensions[j];
+ }
+
+ for (i = 0; i < nExtensions; ++i) {
+ printf("Using instance extension:\t%s\n", extensions[i]);
+ }
+
+ for (i = 0; i < nLayers; ++i) {
+ printf("Using instance layer:\t%s\n", layers[i]);
+ }
+
+ VkInstanceCreateInfo createInfo = { 0 };
+ createInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
+ createInfo.pApplicationInfo = &appInfo;
+ createInfo.enabledLayerCount = nLayers;
+ createInfo.ppEnabledLayerNames = layers;
+ createInfo.enabledExtensionCount = nExtensions;
+ createInfo.ppEnabledExtensionNames = extensions;
+
+ VkResult result;
+ if ((result = vkCreateInstance(&createInfo, NULL, &vk->instance))) {
+ exit(result);
+ }
+ free(extensions);
+}
+
+/** Must not be called until all derivative objects are destroyed first */
+void destroyInstance(struct RenderVulkan *vk)
+{
+ vkDestroyInstance(vk->instance, NULL);
+ vk->instance = NULL;
+}
+
+int main()
+{
+ static const char *const instanceLayers[] = {
+ "VK_LAYER_LUNARG_standard_validation"
+ };
+ const uint32_t nInstanceLayers = sizeof(instanceLayers) / sizeof(instanceLayers[0]);
+ static const char *const instanceExtensions[] = {
+ VK_EXT_DEBUG_REPORT_EXTENSION_NAME
+ };
+ const uint32_t nInstanceExtensions = sizeof(instanceExtensions) / sizeof(instanceExtensions[0]);
+
+ vk = malloc(sizeof(*vk));
+ createInstance(vk, nInstanceLayers, instanceLayers, nInstanceExtensions, instanceExtensions);
+ printf("Created Vulkan Instance Successfully\n");
+ destroyInstance(vk);
+ free(vk);
+ vk = NULL;
+ return 0;
+}
+
+//#if defined(_WIN32)
+#if 0
+int WINAPI WinMain(
+ HINSTANCE hInstance,
+ HINSTANCE hPrevInstance,
+ LPSTR lpCmdLine,
+ int nCmdShow
+ )
+{
+ (void)hInstance;
+ (void)hPrevInstance;
+ (void)lpCmdLine;
+ (void)nCmdShow;
+ return main();
+}
+#endif