Compare commits

..

21 Commits

Author SHA1 Message Date
Gregory Wells eaf3bcb290 create vulkan swapchain 2026-05-25 18:14:40 -04:00
Gregory Wells 629036542a make gryphn create all queue familes 2026-05-25 18:03:38 -04:00
Gregory Wells fb2aa8504f create graphics queue for vulkan 2026-05-25 14:09:02 -04:00
Gregory Wells 0eff3c62ee get vulkan functions up and running 2026-05-25 12:52:56 -04:00
Gregory Wells 587f3cd224 make vulkan enable swapchain extension 2026-05-25 12:37:52 -04:00
Gregory Wells dd3c50be07 redo folder structure 2026-05-25 12:27:10 -04:00
Gregory Wells a252a9cf6b fix crash from junk data 2026-05-25 12:13:25 -04:00
Gregory Wells 96ddecda52 final vulkn functions 2026-05-25 11:45:21 -04:00
Gregory Wells f86d6b9a54 redo code and add xlib surface loader interface 2026-05-25 09:16:17 -04:00
Gregory Wells f39024c045 vulkan device creation 2026-05-24 20:28:50 -04:00
Gregory Wells b0c36a6bea get physical device properties 2026-05-24 20:19:22 -04:00
Gregory Wells ebaf4fde0a enumerate through physical devices 2026-05-24 20:08:32 -04:00
Gregory Wells 9387e8afd9 add a helper function 2026-05-24 19:53:32 -04:00
Gregory Wells c51c05fb08 allow clang to see compile commands 2026-05-24 19:51:25 -04:00
Gregory Wells 55889a32d4 create vulkan instance 2026-05-24 19:21:50 -04:00
Gregory Wells 7a952fcb19 misspelling 2026-05-24 19:15:12 -04:00
Gregory Wells e8e54c0c0d renmove a kinda stupid printf 2026-05-24 14:03:00 -04:00
Gregory Wells 01148e2dad add real vulkan check 2026-05-24 14:01:43 -04:00
Gregory Wells 2379e3ae6b load vulkan backend (if compiled always say is avaliable) 2026-05-24 13:17:21 -04:00
Gregory Wells de67b88f18 allow opening of .SO files on linux 2026-05-24 13:15:47 -04:00
Gregory Wells 6fd8917b88 get Gryphn to compile on Linux 2026-05-24 13:03:28 -04:00
36 changed files with 839 additions and 45 deletions
+2
View File
@@ -0,0 +1,2 @@
CompileFlags:
CompilationDatabase: build
+14 -4
View File
@@ -1,12 +1,18 @@
cmake_minimum_required(VERSION 3.12) cmake_minimum_required(VERSION 3.12)
project(ChemistryRenderingApp LANGUAGES C CXX OBJCXX) # OBJCXX is required for Metal .mm files project(ChemistryRenderingApp LANGUAGES C CXX)
add_executable(ChemistryRenderingApp main.mm) set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
target_link_libraries(ChemistryRenderingApp PRIVATE if (APPLE)
add_executable(ChemistryRenderingApp main.mm)
target_link_libraries(ChemistryRenderingApp PRIVATE
"-framework Metal" "-framework Metal"
"-framework Foundation" "-framework Foundation"
"-framework QuartzCore" "-framework QuartzCore"
"-framework Cocoa" "-framework Cocoa"
) )
endif()
if (UNIX AND NOT APPLE)
add_executable(ChemistryRenderingApp main.cpp)
endif()
target_include_directories(ChemistryRenderingApp PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}") target_include_directories(ChemistryRenderingApp PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}")
target_include_directories(ChemistryRenderingApp PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/glfw/include/") target_include_directories(ChemistryRenderingApp PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/glfw/include/")
target_link_libraries(ChemistryRenderingApp PRIVATE GryphnLoader glfw) target_link_libraries(ChemistryRenderingApp PRIVATE GryphnLoader glfw)
@@ -17,5 +23,9 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON)
add_subdirectory(Gryphn) add_subdirectory(Gryphn)
set(BUILD_SHARED_LIBS ON) set(BUILD_SHARED_LIBS ON)
set(GLFW_BUILD_WAYLAND OFF CACHE BOOL "" FORCE)
set(GLFW_BUILD_X11 ON CACHE BOOL "" FORCE)
add_subdirectory(glfw) add_subdirectory(glfw)
set(BUILD_SHARED_LIBS OFF) set(BUILD_SHARED_LIBS OFF)
+9 -2
View File
@@ -1,5 +1,5 @@
cmake_minimum_required(VERSION 3.12) cmake_minimum_required(VERSION 3.12)
project(Gryphn LANGUAGES C CXX OBJCXX) # OBJCXX is required for Metal .mm files project(Gryphn LANGUAGES C CXX)
set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_STANDARD_REQUIRED ON)
@@ -10,4 +10,11 @@ set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
# Add subdirectories # Add subdirectories
add_subdirectory(GryphnLoader) add_subdirectory(GryphnLoader)
add_subdirectory(apis/GryphnMetal) if (APPLE)
add_compile_definitions(GN_USE_SURFACE_COCOA)
add_subdirectory(apis/GryphnMetal)
endif()
if (UNIX)
add_compile_definitions(GN_USE_SURFACE_XLIB)
add_subdirectory(apis/GryphnVulkan)
endif()
+3
View File
@@ -16,6 +16,9 @@ target_include_directories(GryphnLoader PUBLIC
if(APPLE) if(APPLE)
target_compile_definitions(GryphnLoader PUBLIC GN_PLATFORM_MACOS) target_compile_definitions(GryphnLoader PUBLIC GN_PLATFORM_MACOS)
endif() endif()
if (UNIX AND NOT APPLE)
target_compile_definitions(GryphnLoader PUBLIC GN_PLATFORM_LINUX)
endif()
# 4. Links # 4. Links
if(UNIX AND NOT APPLE) if(UNIX AND NOT APPLE)
@@ -6,18 +6,31 @@
typedef uint32_t (*PFN_gnInternalIsApiSupported)(gnVersion); typedef uint32_t (*PFN_gnInternalIsApiSupported)(gnVersion);
gnReturnCode gnGetAvaliableBackends(gnVersion version, uint32_t* avaliable_backends, gnBackend* backends) { int gryphn_CheckLib(gnVersion version, const char* name) {
*avaliable_backends = 0; gnLib metalLib = gnLoadLib(name);
gnLib metalLib = gnLoadLib("bin/gryphn_metal.dylib");
if (gnLibValid(&metalLib)) { if (gnLibValid(&metalLib)) {
PFN_gnInternalIsApiSupported isSupported = (PFN_gnInternalIsApiSupported)gnLoadLibFunction(&metalLib, "gnInternalIsApiSupported"); PFN_gnInternalIsApiSupported isSupported = (PFN_gnInternalIsApiSupported)gnLoadLibFunction(&metalLib, "gnInternalIsApiSupported");
if (isSupported(version) > 0) { if (isSupported(version) > 0) {
if (backends != NULL) { return 1;
backends[*avaliable_backends] = GN_BACKEND_METAL;
}
*avaliable_backends += 1;
}
} }
gnCloseLib(&metalLib); gnCloseLib(&metalLib);
}
return 0;
}
gnReturnCode gnGetAvaliableBackends(gnVersion version, uint32_t* avaliable_backends, gnBackend* backends) {
*avaliable_backends = 0;
int metalSupported = gryphn_CheckLib(version, "bin/gryphn_metal.dylib");
int vulkanSupported = gryphn_CheckLib(version, "bin/gryphn_vulkan.so");
if (metalSupported) {
if (backends != NULL)
backends[*avaliable_backends] = GN_BACKEND_METAL;
*avaliable_backends += 1;
}
if (vulkanSupported) {
if (backends != NULL)
backends[*avaliable_backends] = GN_BACKEND_VULKAN;
*avaliable_backends += 1;
}
return GN_SUCCESS; return GN_SUCCESS;
} }
@@ -21,6 +21,7 @@ typedef enum gnFormat {
typedef enum gnColorSpace { typedef enum gnColorSpace {
GN_COLOR_SPACE_SRGB_NONLINEAR = 0, GN_COLOR_SPACE_SRGB_NONLINEAR = 0,
GN_COLOR_SPACE_UNKNOWN = 1
} gnColorSpace; } gnColorSpace;
typedef struct gnSurfaceFormat { typedef struct gnSurfaceFormat {
@@ -5,4 +5,5 @@ typedef enum gnPresentMode {
GN_PRESENT_MODE_MAILBOX = 1, GN_PRESENT_MODE_MAILBOX = 1,
GN_PRESENT_MODE_FIFO = 2, GN_PRESENT_MODE_FIFO = 2,
GN_PRESENT_MODE_FIFO_RELAXED = 3, GN_PRESENT_MODE_FIFO_RELAXED = 3,
GN_PRESENT_MODE_UNKNOWN = 4
} gnPresentMode; } gnPresentMode;
@@ -1,6 +1,5 @@
#include "gryphn_device.h" #include "gryphn_device.h"
#include "instance/gryphn_instance.h" #include "instance/gryphn_instance.h"
#include "stdio.h"
#include "stdlib.h" #include "stdlib.h"
gnReturnCode gnCreateDevice(gnInstance instance, gnDeviceCreateInfo* createInfo, gnDevice* device) { gnReturnCode gnCreateDevice(gnInstance instance, gnDeviceCreateInfo* createInfo, gnDevice* device) {
@@ -0,0 +1,10 @@
#include "gryphn_swapchain.h"
#include "gryphn_return_code.h"
#include <device/gryphn_device.h>
gnReturnCode gnCreateSwapchain(gnDevice device, gnSwapchainCreateInfo* createInfo, gnSwapchain* swapchain) {
return device->dispatchTable.createSwapchain(device, createInfo, swapchain);
}
gnReturnCode gnDestroySwapchain(gnDevice device, gnSwapchain* swapchain) {
return device->dispatchTable.destroySwapchain(device, swapchain);
}
@@ -0,0 +1,20 @@
#pragma once
#include <gryphn_handle.h>
#include "core/gryphn_format.h"
#include "core/gryphn_present_mode.h"
#include "core/gryphn_vec2d.h"
#include "gryphn_return_code.h"
#include "stdint.h"
typedef struct gnSwapchainCreateInfo {
gnSurface surface;
uint32_t minImageCount;
gnFormat imageFormat;
gnColorSpace imageColorSpace;
gnExtent2D imageExtent;
uint32_t imageArrayLayers;
gnPresentMode presentMode;
} gnSwapchainCreateInfo;
gnReturnCode gnCreateSwapchain(gnDevice device, gnSwapchainCreateInfo* createInfo, gnSwapchain* swapchain);
gnReturnCode gnDestroySwapchain(gnDevice device, gnSwapchain* swapchain);
@@ -1,11 +1,11 @@
#pragma once #pragma once
#ifdef GN_USE_SURFACE_COCOA
#include "gryphn_handle.h" #include "gryphn_handle.h"
#include "gryphn_return_code.h" #include "gryphn_return_code.h"
#ifndef GN_CA_METAL_LAYER #import <QuartzCore/CAMetalLayer.h>
typedef struct CAMetalLayer CAMetalLayer;
#endif
typedef struct gnMetalSurfaceCreateInfo { typedef struct gnMetalSurfaceCreateInfo {
CAMetalLayer* metalLayer; CAMetalLayer* metalLayer;
} gnMetalSurfaceCreateInfo; } gnMetalSurfaceCreateInfo;
gnReturnCode gnCreateMetalSurface(gnInstance instance, gnMetalSurfaceCreateInfo* createInfo, gnSurface* surface); gnReturnCode gnCreateMetalSurface(gnInstance instance, gnMetalSurfaceCreateInfo* createInfo, gnSurface* surface);
#endif
@@ -1,5 +1,8 @@
#pragma once #pragma once
#include "gryphn_metal_surface.h" #include "gryphn_metal_surface.h"
#include "gryphn_xlib_surface.h"
#include "gryphn_return_code.h"
#include "gryphn_handle.h"
#include "core/gryphn_vec2d.h" #include "core/gryphn_vec2d.h"
#include "core/gryphn_format.h" #include "core/gryphn_format.h"
#include "core/gryphn_present_mode.h" #include "core/gryphn_present_mode.h"
@@ -0,0 +1,6 @@
#include "gryphn_xlib_surface.h"
#include "instance/gryphn_instance.h"
gnReturnCode gnCreateXlibSurface(gnInstance instance, gnXlibSurfaceCreateInfo* createInfo, gnSurface* surface) {
return instance->dispatchTable.createXlibSurface(instance, createInfo, surface);
}
@@ -0,0 +1,13 @@
#pragma once
#ifdef GN_USE_SURFACE_XLIB
#include "gryphn_handle.h"
#include "gryphn_return_code.h"
#include "X11/Xlib.h"
typedef struct gnXlibSurfaceCreateInfo {
Display* dpy;
Window window;
} gnXlibSurfaceCreateInfo;
gnReturnCode gnCreateXlibSurface(gnInstance instance, gnXlibSurfaceCreateInfo* createInfo, gnSurface* surface);
#endif
@@ -1,9 +1,9 @@
#pragma once #pragma once
typedef struct gnLib { typedef struct gnLib {
#ifdef GN_PLATFORM_MACOS #if defined(GN_PLATFORM_MACOS) || defined(GN_PLATFORM_LINUX)
void* dylib; void* dylib;
#endif #endif
} gnLib; } gnLib;
gnLib gnLoadLib(const char* path); gnLib gnLoadLib(const char* path);
@@ -1,31 +1,23 @@
#include "gryphn_lib.h" #include "gryphn_lib.h"
#ifdef GN_PLATFORM_MACOS #if defined(GN_PLATFORM_MACOS) || defined(GN_PLATFORM_LINUX)
#include <dlfcn.h> #include <dlfcn.h>
#endif
gnLib gnLoadLib(const char* path) { gnLib gnLoadLib(const char* path) {
#ifdef GN_PLATFORM_MACOS
gnLib lib; gnLib lib;
lib.dylib = dlopen(path, RTLD_NOW | RTLD_LOCAL); lib.dylib = dlopen(path, RTLD_NOW | RTLD_LOCAL);
return lib; return lib;
#endif
} }
int gnLibValid(const gnLib* lib) { int gnLibValid(const gnLib* lib) {
#ifdef GN_PLATFORM_MACOS
return lib->dylib != 0; return lib->dylib != 0;
#endif
} }
void* gnLoadLibFunction(const gnLib* lib, const char* function) { void* gnLoadLibFunction(const gnLib* lib, const char* function) {
#ifdef GN_PLATFORM_MACOS
return dlsym(lib->dylib, function); return dlsym(lib->dylib, function);
#endif
} }
void gnCloseLib(const gnLib* lib) { void gnCloseLib(const gnLib* lib) {
#ifdef GN_PLATFORM_MACOS
dlclose(lib->dylib); dlclose(lib->dylib);
#endif
} }
#endif
+5 -2
View File
@@ -1,6 +1,9 @@
#pragma once #pragma once
typedef enum gnReturnCode { typedef enum gnReturnCode {
GN_SUCCESS, GN_SUCCESS = 0,
GN_FAILED_TO_FIND_LIBARY GN_FAILED_TO_FIND_LIBARY = 1,
GN_UNSUPPORTED_BACKEND = 2,
GN_EXTENSION_NOT_PRESENT = 3,
GN_UNSUPPOTED_SURFACE
} gnReturnCode; } gnReturnCode;
@@ -1,8 +1,13 @@
#pragma once #pragma once
#include "gryphn_handle.h" #include "gryphn_handle.h"
typedef struct gnSwapchainCreateInfo gnSwapchainCreateInfo;
typedef gnReturnCode (*PFN_gnDestroyDevice)(gnDevice); typedef gnReturnCode (*PFN_gnDestroyDevice)(gnDevice);
typedef gnReturnCode (*PFN_gnCreateSwapchain)(gnDevice, gnSwapchainCreateInfo*, gnSwapchain*);
typedef gnReturnCode (*PFN_gnDestroySwapchain)(gnDevice, gnSwapchain*);
typedef struct gnDeviceDispatchTable { typedef struct gnDeviceDispatchTable {
PFN_gnDestroyDevice destroyDevice; PFN_gnDestroyDevice destroyDevice;
PFN_gnCreateSwapchain createSwapchain;
PFN_gnDestroySwapchain destroySwapchain;
} gnDeviceDispatchTable; } gnDeviceDispatchTable;
@@ -3,11 +3,13 @@
#include "core/gryphn_format.h" #include "core/gryphn_format.h"
#include "core/gryphn_present_mode.h" #include "core/gryphn_present_mode.h"
typedef struct gnMetalSurfaceCreateInfo gnMetalSurfaceCreateInfo; typedef struct gnMetalSurfaceCreateInfo gnMetalSurfaceCreateInfo;
typedef struct gnXlibSurfaceCreateInfo gnXlibSurfaceCreateInfo;
typedef struct gnSurfaceCapabilities gnSurfaceCapabilities; typedef struct gnSurfaceCapabilities gnSurfaceCapabilities;
typedef struct gnPhysicalDeviceProperties gnPhysicalDeviceProperties; typedef struct gnPhysicalDeviceProperties gnPhysicalDeviceProperties;
typedef struct gnDeviceCreateInfo gnDeviceCreateInfo; typedef struct gnDeviceCreateInfo gnDeviceCreateInfo;
typedef gnReturnCode (*PFN_gnCreateMetalSurface)(gnInstance, gnMetalSurfaceCreateInfo*, gnSurface*); typedef gnReturnCode (*PFN_gnCreateMetalSurface)(gnInstance, gnMetalSurfaceCreateInfo*, gnSurface*);
typedef gnReturnCode (*PFN_gnCreateXlibSurface)(gnInstance, gnXlibSurfaceCreateInfo*, gnSurface*);
typedef gnReturnCode (*PFN_enumeratePhysicalDevices)(gnInstance, uint32_t*, gnPhysicalDevice*); typedef gnReturnCode (*PFN_enumeratePhysicalDevices)(gnInstance, uint32_t*, gnPhysicalDevice*);
typedef gnReturnCode (*PFN_gnGetPhysicalDeviceProperties)(gnPhysicalDevice, gnPhysicalDeviceProperties*); typedef gnReturnCode (*PFN_gnGetPhysicalDeviceProperties)(gnPhysicalDevice, gnPhysicalDeviceProperties*);
typedef gnReturnCode (*PFN_gnCreateDevice)(gnInstance, gnDeviceCreateInfo*, gnDevice); typedef gnReturnCode (*PFN_gnCreateDevice)(gnInstance, gnDeviceCreateInfo*, gnDevice);
@@ -19,6 +21,7 @@ typedef gnReturnCode (*PFN_gnDestroyInstance)(gnInstance);
typedef struct gnInstanceDispatchTable { typedef struct gnInstanceDispatchTable {
PFN_gnCreateMetalSurface createMetalSurface; PFN_gnCreateMetalSurface createMetalSurface;
PFN_gnCreateXlibSurface createXlibSurface;
PFN_gnGetSurfaceCapabilities getSurfaceCapabilities; PFN_gnGetSurfaceCapabilities getSurfaceCapabilities;
PFN_gnGetSurfaceFormats getSurfaceFormats; PFN_gnGetSurfaceFormats getSurfaceFormats;
PFN_gnGetSurfacePresentModes getSurfacePresentModes; PFN_gnGetSurfacePresentModes getSurfacePresentModes;
@@ -8,5 +8,5 @@ typedef struct gnApplicationInfo {
const char* applicationName; const char* applicationName;
gnVersion applicationVersion; gnVersion applicationVersion;
const char* engineName; const char* engineName;
gnVersion enginnVersion; gnVersion engineVersion;
} gnApplicationInfo; } gnApplicationInfo;
@@ -11,10 +11,15 @@ gnReturnCode gnCreateInstance(gnInstance* newInstance, gnInstanceCreateInfo* cre
if (createInfo->backend == GN_BACKEND_METAL) { if (createInfo->backend == GN_BACKEND_METAL) {
instance->internalLib = gnLoadLib("bin/gryphn_metal.dylib"); instance->internalLib = gnLoadLib("bin/gryphn_metal.dylib");
PFN_initBackend initBackend = (PFN_initBackend)gnLoadLibFunction(&instance->internalLib, "initBackend"); PFN_initBackend initBackend = (PFN_initBackend)gnLoadLibFunction(&instance->internalLib, "initBackend");
initBackend(instance, createInfo); return initBackend(instance, createInfo);
}
if (createInfo->backend == GN_BACKEND_VULKAN) {
instance->internalLib = gnLoadLib("bin/gryphn_vulkan.so");
PFN_initBackend initBackend = (PFN_initBackend)gnLoadLibFunction(&instance->internalLib, "initBackend");
return initBackend(instance, createInfo);
} }
return GN_SUCCESS; return GN_UNSUPPORTED_BACKEND;
} }
gnReturnCode gnDestroyInstance(gnInstance* instance) { gnReturnCode gnDestroyInstance(gnInstance* instance) {
(*instance)->dispatchTable.destroyInstance(*instance); (*instance)->dispatchTable.destroyInstance(*instance);
@@ -6,7 +6,7 @@
#include "stdint.h" #include "stdint.h"
#include "device/gryphn_physical_device.h" #include "device/gryphn_physical_device.h"
#include "device/gryphn_device.h" #include "device/gryphn_device.h"
#include "surface/gryphn_surface.h" #include "ext/instance/surface/gryphn_surface.h"
gnReturnCode metalEnumeratePhysicalDevices(gnInstance instance, uint32_t* deviceCount, gnPhysicalDevice* devices); gnReturnCode metalEnumeratePhysicalDevices(gnInstance instance, uint32_t* deviceCount, gnPhysicalDevice* devices);
gnReturnCode metalGetPhysicalDeviceProperties(gnPhysicalDevice device, gnPhysicalDeviceProperties* properties); gnReturnCode metalGetPhysicalDeviceProperties(gnPhysicalDevice device, gnPhysicalDeviceProperties* properties);
+5
View File
@@ -0,0 +1,5 @@
file(GLOB_RECURSE VULKAN_SOURCES CONFIGURE_DEPENDS "src/*.c")
add_library(gryphn_vulkan SHARED ${VULKAN_SOURCES})
project(gryphn_vulkan LANGUAGES C)
set_target_properties(gryphn_vulkan PROPERTIES PREFIX "")
target_link_libraries(gryphn_vulkan PRIVATE GryphnLoader vulkan)
@@ -0,0 +1,99 @@
#include "core/gryphn_format.h"
#include "core/gryphn_present_mode.h"
#include "gryphn_return_code.h"
#include "../vulkan_functions.h"
#include <vulkan/vulkan_core.h>
#include "instance/gryphn_instance.h"
#include "ext/instance/surface/gryphn_surface.h"
#include "../vulkan_helpers.h"
#include "stdlib.h"
#include <stdio.h>
#ifdef GN_USE_SURFACE_XLIB
#include <vulkan/vulkan_xlib.h>
#endif
gnReturnCode vulkanCreateXlibSurface(gnInstance instance, gnXlibSurfaceCreateInfo* info, gnSurface* surface) {
#ifdef GN_USE_SURFACE_XLIB
VkXlibSurfaceCreateInfoKHR createInfo = {
.sType = VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR,
.pNext = 0,
.flags = 0,
.dpy = info->dpy,
.window = info->window
};
return vulkanCodeToGryphnCode(vkCreateXlibSurfaceKHR(instance->internalData, &createInfo, NULL, (VkSurfaceKHR*)surface));
#else
return GN_SUCCESS;
#endif
}
gnReturnCode vulkanGetSurfaceCapabilities(gnPhysicalDevice device, gnSurface surface, gnSurfaceCapabilities* capabilities) {
VkSurfaceCapabilitiesKHR vulkanCapabilities;
VkResult result = vkGetPhysicalDeviceSurfaceCapabilitiesKHR(device->internalData, surface, &vulkanCapabilities);
*capabilities = (gnSurfaceCapabilities){
.minImageCount = vulkanCapabilities.minImageCount,
.maxImageCount = vulkanCapabilities.maxImageCount,
.currentExtent = { vulkanCapabilities.currentExtent.width, vulkanCapabilities.currentExtent.height },
.minImageExtent = { vulkanCapabilities.maxImageExtent.width, vulkanCapabilities.maxImageExtent.height },
.maxImageExtent = { vulkanCapabilities.maxImageExtent.width, vulkanCapabilities.maxImageExtent.height },
.maxImageArrayLayers = vulkanCapabilities.maxImageArrayLayers
};
return vulkanCodeToGryphnCode(result);
}
gnReturnCode vulkanGetSurfaceFormats(gnPhysicalDevice device, gnSurface surface, uint32_t* formatCount, gnSurfaceFormat* formats) {
*formatCount = 0;
uint32_t internal_formatCout;
gnReturnCode result = vulkanCodeToGryphnCode(vkGetPhysicalDeviceSurfaceFormatsKHR(device->internalData, surface, &internal_formatCout, NULL));
if (result != GN_SUCCESS) {
*formatCount = internal_formatCout;
return result;
}
VkSurfaceFormatKHR* internal_formats = malloc(sizeof(VkSurfaceFormatKHR) * internal_formatCout);
result = vulkanCodeToGryphnCode(vkGetPhysicalDeviceSurfaceFormatsKHR(device->internalData, surface, &internal_formatCout, internal_formats));
if (result != GN_SUCCESS) {
free(internal_formats);
*formatCount = internal_formatCout;
return result;
}
for (int i = 0; i < internal_formatCout; i++) {
gnSurfaceFormat format = {
.format = vulkanFormatToGryphnFormat(internal_formats[i].format),
.colorSpace = vulkanColorSpaceToGryphnColorSpace(internal_formats[i].colorSpace)
};
if ((format.format == GN_FORMAT_UNDEFINED && internal_formats[i].format != VK_FORMAT_UNDEFINED) || format.colorSpace == GN_COLOR_SPACE_UNKNOWN)
continue;
if (formats != NULL)
formats[*formatCount] = format;
(*formatCount)++;
}
free(internal_formats);
return GN_SUCCESS;
}
gnReturnCode vulkanGetSurfacePresentModes(gnPhysicalDevice device, gnSurface surface, uint32_t* presentModeCount, gnPresentMode* presentModes) {
*presentModeCount = 0;
uint32_t internal_presentModeCount;
gnReturnCode result = vulkanCodeToGryphnCode(vkGetPhysicalDeviceSurfacePresentModesKHR(device->internalData, surface, &internal_presentModeCount, NULL));
if (result != GN_SUCCESS) {
*presentModeCount = internal_presentModeCount;
return result;
}
VkPresentModeKHR* internal_presentModes = malloc(sizeof(VkPresentModeKHR) * internal_presentModeCount);
result = vulkanCodeToGryphnCode(vkGetPhysicalDeviceSurfacePresentModesKHR(device->internalData, surface, &internal_presentModeCount, NULL));
if (result != GN_SUCCESS) {
free(internal_presentModes);
*presentModeCount = internal_presentModeCount;
return result;
}
for (int i = 0; i < internal_presentModeCount; i++) {
gnPresentMode mode = vulkanPresentModeToGryphnPresentMode(internal_presentModes[i]);
if (mode == GN_PRESENT_MODE_UNKNOWN) continue;
if (presentModes != NULL)
presentModes[*presentModeCount] = mode;
(*presentModeCount)++;
}
free(internal_presentModes);
return GN_SUCCESS;
}
gnReturnCode vulkanDestroySurface(gnInstance instance, gnSurface* surface) {
vkDestroySurfaceKHR(instance->internalData, *surface, NULL);
return GN_SUCCESS;
}
@@ -0,0 +1,61 @@
#include "../vulkan_functions.h"
#include "gryphn_handle.h"
#include "gryphn_return_code.h"
#include "ext/device/swapchain/gryphn_swapchain.h"
#include "../vulkan_helpers.h"
#include "../vulkan_device.h"
#include <vulkan/vulkan_core.h>
typedef struct vulkanSwapchain {
uint32_t presentQueueIndex;
VkQueue presentQueue;
} vulkanSwapchain;
gnReturnCode vulkanCreateSwapchain(gnDevice device, gnSwapchainCreateInfo* info, gnSwapchain* swapchain) {
uint32_t presentQueueIndex;
VkBool32 presentSupport = VK_FALSE;
for (int i = 0; i < ((vulkanDevice*)device->internalData)->queueCount; i++) {
vkGetPhysicalDeviceSurfaceSupportKHR(((vulkanDevice*)device->internalData)->physicalDevice, i, info->surface, &presentSupport);
if (presentSupport == VK_TRUE) {
presentQueueIndex = i;
break;
}
}
if (presentSupport == VK_FALSE) return GN_UNSUPPOTED_SURFACE;
VkSurfaceCapabilitiesKHR capabilities;
vkGetPhysicalDeviceSurfaceCapabilitiesKHR(((vulkanDevice*)device->internalData)->physicalDevice, info->surface, &capabilities);
VkSwapchainCreateInfoKHR createInfo = {
.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR,
.pNext = NULL,
.flags = 0,
.surface = info->surface,
.minImageCount = info->minImageCount,
.imageFormat = gryphnFormatToVulkanFormat(info->imageFormat),
.imageColorSpace = gryphnColorSpaceToVulkanColorSpace(info->imageColorSpace),
.imageExtent = { info->imageExtent.width, info->imageExtent.height },
.imageArrayLayers = info->imageArrayLayers,
.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE,
.queueFamilyIndexCount = 0,
.pQueueFamilyIndices = NULL,
.preTransform = capabilities.currentTransform,
.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR,
.presentMode = gryphnPresentModeToVulkanPresentMode(info->presentMode),
.clipped = VK_TRUE,
.oldSwapchain = NULL,
};
if (((vulkanDevice*)device->internalData)->graphicsQueueIndex != presentQueueIndex) {
createInfo.imageSharingMode = VK_SHARING_MODE_CONCURRENT;
createInfo.queueFamilyIndexCount = 2;
createInfo.pQueueFamilyIndices = (uint32_t[]){((vulkanDevice*)device->internalData)->graphicsQueueIndex, presentQueueIndex};
}
return vulkanCodeToGryphnCode(vkCreateSwapchainKHR(((vulkanDevice*)device->internalData)->device, &createInfo, NULL, (VkSwapchainKHR*)swapchain));
}
gnReturnCode vulkanDestroySwapchain(gnDevice device, gnSwapchain* swapchain) {
vkDestroySwapchainKHR(((vulkanDevice*)device->internalData)->device, *((VkSwapchainKHR*)swapchain), NULL);
return GN_SUCCESS;
}
+88
View File
@@ -0,0 +1,88 @@
#include "instance/gryphn_instance.h"
#include "gryphn_handle.h"
#include "stdlib.h"
#include <vulkan/vulkan_core.h>
#include "vulkan_functions.h"
#include "vulkan_helpers.h"
#include "string.h"
uint32_t gnInternalIsApiSupported(gnVersion gryphnVersion) {
if (gryphnVersion != gnCreateVersion(1, 0, 0)) return 0;
VkApplicationInfo appInfo = {
.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO,
.pApplicationName = "Gryphn Vulkan Test",
.applicationVersion = VK_MAKE_VERSION(1, 0, 0),
.pEngineName = "Gryphn Vulkan Test",
.engineVersion = VK_MAKE_VERSION(1, 0, 0),
.apiVersion = VK_API_VERSION_1_0
};
VkInstanceCreateInfo createInfo = {
.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
.pApplicationInfo = &appInfo
};
VkInstance instance;
VkResult result = vkCreateInstance(&createInfo, NULL, &instance);
if (result != VK_SUCCESS)
return 0;
vkDestroyInstance(instance, NULL);
return 1;
}
gnReturnCode destroyBackend(gnInstance instance) {
vkDestroyInstance(instance->internalData, NULL);
return GN_SUCCESS;
}
gnReturnCode initBackend(gnInstance instance, gnInstanceCreateInfo* info) {
VkApplicationInfo applicationInfo = {
.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO,
.pNext = NULL,
.pApplicationName = info->info.applicationName,
.applicationVersion = info->info.applicationVersion,
.pEngineName = info->info.engineName,
.engineVersion = info->info.engineVersion,
.apiVersion = VK_API_VERSION_1_0
};
const char** extensions = malloc(sizeof(const char*) * info->enabledExtensionCount);
int realEnabledExtensionCount = 0;
for (int i = 0; i < info->enabledExtensionCount; i++) {
if (strcmp(info->enabledExtensions[i], "GN_EXT_surface") == 0) {
extensions[realEnabledExtensionCount] = "VK_KHR_surface";
realEnabledExtensionCount++;
instance->dispatchTable.destroySurface = vulkanDestroySurface;
instance->dispatchTable.getSurfaceCapabilities = vulkanGetSurfaceCapabilities;
instance->dispatchTable.getSurfaceFormats = vulkanGetSurfaceFormats;
instance->dispatchTable.getSurfacePresentModes = vulkanGetSurfacePresentModes;
}
if (strcmp(info->enabledExtensions[i], "GN_EXT_surface_xlib") == 0) {
extensions[realEnabledExtensionCount] = "VK_KHR_xlib_surface";
realEnabledExtensionCount++;
instance->dispatchTable.createXlibSurface = vulkanCreateXlibSurface;
}
}
VkInstanceCreateInfo createInfo = {
.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
.pNext = NULL,
.flags = 0,
.pApplicationInfo = &applicationInfo,
.enabledLayerCount = 0,
.ppEnabledLayerNames = NULL,
.enabledExtensionCount = realEnabledExtensionCount,
.ppEnabledExtensionNames = extensions,
};
instance->dispatchTable.destroyInstance = destroyBackend;
instance->dispatchTable.enumeratePhysicalDevices = vulkanEnumeratePhysicalDevices;
instance->dispatchTable.getPhysicalDeviceProperties = vulkanGetPhysicalDeviceProperties;
instance->dispatchTable.createDevice = vulkanCreateDevice;
VkInstance vulkanInstance;
VkResult result = vkCreateInstance(&createInfo, NULL, &vulkanInstance);
instance->internalData = vulkanInstance;
return vulkanCodeToGryphnCode(result);
}
@@ -0,0 +1,129 @@
#include "stdlib.h"
#include "gryphn_return_code.h"
#include "vulkan_functions.h"
#include "vulkan_helpers.h"
#include "instance/gryphn_instance.h"
#include "device/gryphn_physical_device.h"
#include <string.h>
#include <stdio.h>
#include <vulkan/vulkan_core.h>
#include "vulkan_device.h"
gnPhysicalDeviceType vulkanDeviceTypeToGryphnDeviceType(VkPhysicalDeviceType type) {
switch (type) {
case VK_PHYSICAL_DEVICE_TYPE_OTHER: return GN_PHYSICAL_DEVICE_TYPE_OTHER;
case VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU: return GN_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU;
case VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU: return GN_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU;
case VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU: return GN_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU;
case VK_PHYSICAL_DEVICE_TYPE_CPU: return GN_PHYSICAL_DEVICE_TYPE_CPU;
case VK_PHYSICAL_DEVICE_TYPE_MAX_ENUM: return GN_PHYSICAL_DEVICE_TYPE_OTHER;
}
}
gnReturnCode vulkanEnumeratePhysicalDevices(gnInstance instance, uint32_t* deviceCount, gnPhysicalDevice* devices) {
if (devices == NULL) {
vkEnumeratePhysicalDevices(instance->internalData, deviceCount, NULL);
return GN_SUCCESS;
}
VkPhysicalDevice* vulkanDevices = malloc(sizeof(VkPhysicalDevice) * (*deviceCount));
VkResult result = vkEnumeratePhysicalDevices(instance->internalData, deviceCount, vulkanDevices);
if (result != VK_SUCCESS) {
free(vulkanDevices);
return vulkanCodeToGryphnCode(result);
}
for (uint32_t i = 0; i < *deviceCount; i++) {
devices[i] = malloc(sizeof(gnPhysicalDevice_t));
devices[i]->instance = instance;
devices[i]->internalData = vulkanDevices[i];
}
free(vulkanDevices);
return GN_SUCCESS;
}
gnReturnCode vulkanGetPhysicalDeviceProperties(gnPhysicalDevice device, gnPhysicalDeviceProperties* properties) {
VkPhysicalDeviceProperties deviceProperties;
vkGetPhysicalDeviceProperties(device->internalData, &deviceProperties);
*properties = (gnPhysicalDeviceProperties){
.apiVersion = deviceProperties.apiVersion,
.vendorID = deviceProperties.vendorID,
.deviceID = deviceProperties.deviceID,
.deviceType = vulkanDeviceTypeToGryphnDeviceType(deviceProperties.deviceType),
};
strcpy(properties->deviceName, deviceProperties.deviceName);
return GN_SUCCESS;
}
gnReturnCode vulkanCreateDevice(gnInstance instance, gnDeviceCreateInfo* info, gnDevice device) {
// create a list of the vulkan extentions to enable from gryphn extententions
const char** extensions = malloc(sizeof(const char*) * info->enabledExtensionCount);
int realEnabledExtensionCount = 0;
for (int i = 0; i < info->enabledExtensionCount; i++) {
if (strcmp(info->enabledExtensions[i], "GN_EXT_swapchain") == 0) {
extensions[realEnabledExtensionCount] = VK_KHR_SWAPCHAIN_EXTENSION_NAME;
realEnabledExtensionCount++;
device->dispatchTable.createSwapchain = vulkanCreateSwapchain;
device->dispatchTable.destroySwapchain = vulkanDestroySwapchain;
}
}
uint32_t queueFamilyCount = 0;
vkGetPhysicalDeviceQueueFamilyProperties(info->physicalDevice->internalData, &queueFamilyCount, NULL);
VkQueueFamilyProperties* queueFamilyProperties = malloc(sizeof(VkQueueFamilyProperties) * queueFamilyCount);
vkGetPhysicalDeviceQueueFamilyProperties(info->physicalDevice->internalData, &queueFamilyCount, queueFamilyProperties);
VkDeviceQueueCreateInfo* queueCreateInfos = malloc(sizeof(VkDeviceQueueCreateInfo) * queueFamilyCount);
for (int i = 0; i < queueFamilyCount; i++) {
queueCreateInfos[i] = (VkDeviceQueueCreateInfo){
.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
.pNext = NULL,
.flags = 0,
.queueFamilyIndex = i,
.queueCount = 1,
.pQueuePriorities = (float[]){ 1.0f }
};
}
VkPhysicalDeviceFeatures deviceFeatures = {
};
VkDeviceCreateInfo createInfo = {
.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
.pNext = NULL,
.flags = 0,
.queueCreateInfoCount = queueFamilyCount,
.pQueueCreateInfos = queueCreateInfos,
.enabledExtensionCount = realEnabledExtensionCount,
.ppEnabledExtensionNames = extensions,
.pEnabledFeatures = &deviceFeatures,
};
VkDevice vkDevice;
VkResult result = vkCreateDevice(info->physicalDevice->internalData, &createInfo, NULL, &vkDevice);
device->internalData = malloc(sizeof(vulkanDevice));
((vulkanDevice*)device->internalData)->device = vkDevice;
((vulkanDevice*)device->internalData)->physicalDevice = info->physicalDevice->internalData;
((vulkanDevice*)device->internalData)->queueCount = queueFamilyCount;
for (int i = 0; i < queueFamilyCount; i++) {
if ((queueFamilyProperties[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) == VK_QUEUE_GRAPHICS_BIT) {
((vulkanDevice*)device->internalData)->graphicsQueueIndex = i;
vkGetDeviceQueue(vkDevice, i, 0, &((vulkanDevice*)device->internalData)->graphicsQueue);
break;
}
}
device->dispatchTable.destroyDevice = vulkanDestroyDevice;
free(extensions);
return vulkanCodeToGryphnCode(result);
}
gnReturnCode vulkanDestroyDevice(gnDevice device) {
vkDestroyDevice(((vulkanDevice*)device->internalData)->device, NULL);
free(device->internalData);
return GN_SUCCESS;
}
@@ -0,0 +1,11 @@
#pragma once
#include <vulkan/vulkan_core.h>
typedef struct vulkanDevice {
VkDevice device;
VkPhysicalDevice physicalDevice;
uint32_t queueCount;
uint32_t graphicsQueueIndex;
VkQueue graphicsQueue;
} vulkanDevice;
@@ -0,0 +1,19 @@
#pragma once
#include "stdint.h"
#include "gryphn_handle.h"
#include "gryphn_return_code.h"
#include "device/gryphn_physical_device.h"
#include "device/gryphn_device.h"
#include "dispatch/gryphn_instance_dispatch_table.h"
gnReturnCode vulkanEnumeratePhysicalDevices(gnInstance instance, uint32_t* deviceCount, gnPhysicalDevice* devices);
gnReturnCode vulkanGetPhysicalDeviceProperties(gnPhysicalDevice device, gnPhysicalDeviceProperties* properties);
gnReturnCode vulkanCreateDevice(gnInstance instance, gnDeviceCreateInfo* createInfo, gnDevice device);
gnReturnCode vulkanDestroyDevice(gnDevice device);
gnReturnCode vulkanCreateXlibSurface(gnInstance instance, gnXlibSurfaceCreateInfo* createInfo, gnSurface* surface);
gnReturnCode vulkanGetSurfaceCapabilities(gnPhysicalDevice device, gnSurface surface, gnSurfaceCapabilities* capabilities);
gnReturnCode vulkanGetSurfaceFormats(gnPhysicalDevice device, gnSurface surface, uint32_t* formatCount, gnSurfaceFormat* formats);
gnReturnCode vulkanGetSurfacePresentModes(gnPhysicalDevice device, gnSurface surface, uint32_t* presentModeCount, gnPresentMode* presentModes);
gnReturnCode vulkanDestroySurface(gnInstance instance, gnSurface* surface);
gnReturnCode vulkanCreateSwapchain(gnDevice device, gnSwapchainCreateInfo* createInfo, gnSwapchain* swapchain);
gnReturnCode vulkanDestroySwapchain(gnDevice device, gnSwapchain* swapchain);
@@ -0,0 +1,89 @@
#include "vulkan_helpers.h"
#include "core/gryphn_format.h"
#include "core/gryphn_present_mode.h"
#include "gryphn_return_code.h"
#include "stdio.h"
#include <vulkan/vulkan_core.h>
gnReturnCode vulkanCodeToGryphnCode(VkResult result) {
switch(result) {
default: {
printf("Unknown instance fail mr gregory please diagnose this: %d\n", result);
return GN_UNSUPPORTED_BACKEND;
}
case VK_SUCCESS: return GN_SUCCESS;
case VK_ERROR_EXTENSION_NOT_PRESENT: return GN_EXTENSION_NOT_PRESENT;
}
}
gnFormat vulkanFormatToGryphnFormat(VkFormat format) {
switch (format) {
case VK_FORMAT_UNDEFINED: return GN_FORMAT_UNDEFINED;
case VK_FORMAT_R8G8B8A8_UNORM: return GN_FORMAT_RGBA8_UNORM;
case VK_FORMAT_R8G8B8A8_SNORM: return GN_FORMAT_RGBA8_SNORM;
case VK_FORMAT_R8G8B8A8_USCALED: return GN_FORMAT_RGBA8_USCALED;
case VK_FORMAT_R8G8B8A8_SSCALED: return GN_FORMAT_RGBA8_SSCALED;
case VK_FORMAT_R8G8B8A8_UINT: return GN_FORMAT_RGBA8_UINT;
case VK_FORMAT_R8G8B8A8_SINT: return GN_FORMAT_RGBA8_SINT;
case VK_FORMAT_R8G8B8A8_SRGB: return GN_FORMAT_RGBA8_SRGB;
case VK_FORMAT_B8G8R8A8_UNORM: return GN_FORMAT_BGRA8_UNORM;
case VK_FORMAT_B8G8R8A8_SNORM: return GN_FORMAT_BGRA8_SNORM;
case VK_FORMAT_B8G8R8A8_USCALED: return GN_FORMAT_BGRA8_USCALED;
case VK_FORMAT_B8G8R8A8_SSCALED: return GN_FORMAT_BGRA8_SSCALED;
case VK_FORMAT_B8G8R8A8_UINT: return GN_FORMAT_BGRA8_UINT;
case VK_FORMAT_B8G8R8A8_SINT: return GN_FORMAT_BGRA8_SINT;
case VK_FORMAT_B8G8R8A8_SRGB: return GN_FORMAT_BGRA8_SRGB;
default: return GN_FORMAT_UNDEFINED;
}
}
gnColorSpace vulkanColorSpaceToGryphnColorSpace(VkColorSpaceKHR colorSpace) {
switch (colorSpace) {
case VK_COLOR_SPACE_SRGB_NONLINEAR_KHR: return GN_COLOR_SPACE_SRGB_NONLINEAR;
default: return GN_COLOR_SPACE_UNKNOWN;
}
}
gnPresentMode vulkanPresentModeToGryphnPresentMode(VkPresentModeKHR presentMode) {
switch (presentMode) {
case VK_PRESENT_MODE_IMMEDIATE_KHR: return GN_PRESENT_MODE_IMMEDIATE;
case VK_PRESENT_MODE_MAILBOX_KHR: return GN_PRESENT_MODE_MAILBOX;
case VK_PRESENT_MODE_FIFO_KHR: return GN_PRESENT_MODE_FIFO;
case VK_PRESENT_MODE_FIFO_RELAXED_KHR: return GN_PRESENT_MODE_FIFO_RELAXED;
default: return GN_PRESENT_MODE_UNKNOWN;
}
}
VkFormat gryphnFormatToVulkanFormat(gnFormat format) {
switch (format) {
case GN_FORMAT_UNDEFINED: return VK_FORMAT_UNDEFINED;
case GN_FORMAT_RGBA8_UNORM: return VK_FORMAT_R8G8B8A8_UNORM;
case GN_FORMAT_RGBA8_SNORM: return VK_FORMAT_R8G8B8A8_SNORM;
case GN_FORMAT_RGBA8_USCALED: return VK_FORMAT_R8G8B8A8_USCALED;
case GN_FORMAT_RGBA8_SSCALED: return VK_FORMAT_R8G8B8A8_SSCALED;
case GN_FORMAT_RGBA8_UINT: return VK_FORMAT_R8G8B8A8_UINT;
case GN_FORMAT_RGBA8_SINT: return VK_FORMAT_R8G8B8A8_SINT;
case GN_FORMAT_RGBA8_SRGB: return VK_FORMAT_R8G8B8A8_SRGB;
case GN_FORMAT_BGRA8_UNORM: return VK_FORMAT_B8G8R8A8_UNORM;
case GN_FORMAT_BGRA8_SNORM: return VK_FORMAT_B8G8R8A8_SNORM;
case GN_FORMAT_BGRA8_USCALED: return VK_FORMAT_B8G8R8A8_USCALED;
case GN_FORMAT_BGRA8_SSCALED: return VK_FORMAT_B8G8R8A8_SSCALED;
case GN_FORMAT_BGRA8_UINT: return VK_FORMAT_B8G8R8A8_UINT;
case GN_FORMAT_BGRA8_SINT: return VK_FORMAT_B8G8R8A8_SINT;
case GN_FORMAT_BGRA8_SRGB: return VK_FORMAT_B8G8R8A8_SRGB;
}
}
VkColorSpaceKHR gryphnColorSpaceToVulkanColorSpace(gnColorSpace colorSpace) {
switch (colorSpace) {
case GN_COLOR_SPACE_SRGB_NONLINEAR: return VK_COLOR_SPACE_SRGB_NONLINEAR_KHR;
case GN_COLOR_SPACE_UNKNOWN: return VK_COLOR_SPACE_MAX_ENUM_KHR;
}
}
VkPresentModeKHR gryphnPresentModeToVulkanPresentMode(gnPresentMode presentMode) {
switch (presentMode) {
case GN_PRESENT_MODE_IMMEDIATE: return VK_PRESENT_MODE_IMMEDIATE_KHR;
case GN_PRESENT_MODE_MAILBOX: return VK_PRESENT_MODE_MAILBOX_KHR;
case GN_PRESENT_MODE_FIFO: return VK_PRESENT_MODE_FIFO_KHR;
case GN_PRESENT_MODE_FIFO_RELAXED: return VK_PRESENT_MODE_FIFO_RELAXED_KHR;
case GN_PRESENT_MODE_UNKNOWN: return VK_PRESENT_MODE_MAX_ENUM_KHR;
}
}
@@ -0,0 +1,14 @@
#pragma once
#include "gryphn_return_code.h"
#include "core/gryphn_format.h"
#include "core/gryphn_present_mode.h"
#include <vulkan/vulkan_core.h>
gnReturnCode vulkanCodeToGryphnCode(VkResult result);
gnFormat vulkanFormatToGryphnFormat(VkFormat format);
gnColorSpace vulkanColorSpaceToGryphnColorSpace(VkColorSpaceKHR colorSpace);
gnPresentMode vulkanPresentModeToGryphnPresentMode(VkPresentModeKHR presentMode);
VkFormat gryphnFormatToVulkanFormat(gnFormat format);
VkColorSpaceKHR gryphnColorSpaceToVulkanColorSpace(gnColorSpace colorSpace);
VkPresentModeKHR gryphnPresentModeToVulkanPresentMode(gnPresentMode presentMode);
+2 -1
View File
@@ -6,7 +6,8 @@ extern "C" {
#include "GryphnLoader/src/instance/gryphn_instance.h" #include "GryphnLoader/src/instance/gryphn_instance.h"
#include "GryphnLoader/src/device/gryphn_physical_device.h" #include "GryphnLoader/src/device/gryphn_physical_device.h"
#include "GryphnLoader/src/device/gryphn_device.h" #include "GryphnLoader/src/device/gryphn_device.h"
#include "GryphnLoader/src/surface/gryphn_surface.h" #include "GryphnLoader/src/ext/instance/surface/gryphn_surface.h"
#include "GryphnLoader/src/ext/device/swapchain/gryphn_swapchain.h"
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
+182
View File
@@ -0,0 +1,182 @@
#define GN_USE_SURFACE_XLIB
#include <Gryphn/gryphn.h>
#include "stdlib.h"
#include "iostream"
#define GLFW_EXPOSE_NATIVE_X11
#include "glfw/include/GLFW/glfw3.h"
#include "glfw/include/GLFW/glfw3native.h"
#define CONCAT_IMPL(a, b) a##b
#define CONCAT(a, b) CONCAT_IMPL(a, b)
#define CHECK(func) \
gnReturnCode CONCAT(res, __LINE__) = (func); \
if (CONCAT(res, __LINE__) != GN_SUCCESS) { \
std::cout << "Gryphn Error at line " << __LINE__ \
<< ": " << CONCAT(res, __LINE__) << "\n"; \
}
GLFWwindow* window;
gnVersion version = gnCreateVersion(1, 0, 0);
gnInstance instance;
gnPhysicalDevice pysicalDevice;
gnDevice device;
gnSurface surface;
gnSwapchain swapchain;
uint32_t min(uint32_t a, uint32_t b) {
if (a < b) return a;
return b;
}
void createInstance() {
uint32_t backendCount = 0;
CHECK(gnGetAvaliableBackends(version, &backendCount, nullptr));
if (backendCount == 0) {
throw std::runtime_error("Gryphn returned 0 avaliable backends");
}
gnBackend* backends = (gnBackend*)malloc(sizeof(gnBackend) * backendCount);
CHECK(gnGetAvaliableBackends(version, &backendCount, backends));
const char* extensions[2] = {
"GN_EXT_surface",
"GN_EXT_surface_xlib"
};
gnInstanceCreateInfo createInfo = {
.backend = backends[0],
.info = {
.applicationName = "Chemistry Rendering App",
.applicationVersion = gnCreateVersion(0, 0, 1),
.engineName = "Chemistry Rendering Engine",
.engineVersion = gnCreateVersion(0, 0, 1)
},
.enabledValidationLayerCount = 0,
.enabledValidationLayers = nullptr,
.enabledExtensionCount = 2,
.enabledExtensions = extensions
};
CHECK(gnCreateInstance(&instance, &createInfo));
free(backends);
}
void createDevice() {
uint32_t physicalDeviceCount;
CHECK(gnEnumeratePhysicalDevices(instance, &physicalDeviceCount, nullptr));
gnPhysicalDevice* devices = (gnPhysicalDevice*)malloc(sizeof(gnPhysicalDevice) * physicalDeviceCount);
CHECK(gnEnumeratePhysicalDevices(instance, &physicalDeviceCount, devices));
std::cout << "Found " << physicalDeviceCount << " physical devices:\n";
for (int i = 0; i < physicalDeviceCount; i++) {
gnPhysicalDeviceProperties properties;
gnGetPhysicalDeviceProperties(devices[i], &properties);
std::cout << "Name: " << properties.deviceName << "\n";
}
pysicalDevice = devices[0];
const char* extensions[1] = {
"GN_EXT_swapchain"
};
gnDeviceCreateInfo createInfo = {
.physicalDevice = pysicalDevice,
.enabledExtensionCount = 1,
.enabledExtensions = extensions
};
CHECK(gnCreateDevice(instance, &createInfo, &device));
}
void createSurface() {
gnXlibSurfaceCreateInfo createInfo = {
.dpy = glfwGetX11Display(),
.window = glfwGetX11Window(window)
};
CHECK(gnCreateXlibSurface(instance, &createInfo, &surface));
}
gnSurfaceFormat getSurfaceFormat() {
uint32_t surfaceFormatCount = 0;
CHECK(gnGetSurfaceFormats(pysicalDevice, surface, &surfaceFormatCount, NULL));
if (surfaceFormatCount == 0)
throw std::runtime_error("Gryphn returned 0 avaliable surface formats");
gnSurfaceFormat* formats = (gnSurfaceFormat*)malloc(sizeof(gnSurfaceFormat) * surfaceFormatCount);
CHECK(gnGetSurfaceFormats(pysicalDevice, surface, &surfaceFormatCount, formats));
for (int i = 0; i < surfaceFormatCount; i++)
if (formats[i].format == GN_FORMAT_BGRA8_SRGB && formats[i].colorSpace == GN_COLOR_SPACE_SRGB_NONLINEAR) return formats[i];
return formats[0];
return (gnSurfaceFormat){
.format = GN_FORMAT_UNDEFINED,
.colorSpace = GN_COLOR_SPACE_UNKNOWN
};
}
gnPresentMode getPresentMode() {
uint32_t presentModeCount = 0;
CHECK(gnGetSurfacePresentModes(pysicalDevice, surface, &presentModeCount, NULL));
if (presentModeCount == 0)
throw std::runtime_error("Gryphn returned 0 avaliable presentMode");
gnPresentMode* presentModes = (gnPresentMode*)malloc(sizeof(gnPresentMode) * presentModeCount);
CHECK(gnGetSurfacePresentModes(pysicalDevice, surface, &presentModeCount, presentModes));
for (int i = 0; i < presentModeCount; i++)
if (presentModes[i] == GN_PRESENT_MODE_MAILBOX) return presentModes[i];
return presentModes[0];
}
void createSwapchain() {
gnSurfaceCapabilities capabilites;
gnGetSurfaceCapabilities(pysicalDevice, surface, &capabilites);
gnSurfaceFormat chosenFormat = getSurfaceFormat();
gnPresentMode chosenMode = getPresentMode();
int width, height;
glfwGetWindowSize(window, &width, &height);
gnSwapchainCreateInfo createInfo = {
.surface = surface,
.minImageCount = min(capabilites.minImageCount + 1, capabilites.maxImageCount),
.imageFormat = chosenFormat.format,
.imageColorSpace = chosenFormat.colorSpace,
.imageExtent = { (uint32_t)width, (uint32_t)height },
.imageArrayLayers = 1,
.presentMode = chosenMode,
};
CHECK(gnCreateSwapchain(device, &createInfo, &swapchain));
}
int main() {
if (!glfwInit()) {
std::cout << "Failed to init GLFW\n";
return -1;
}
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
window = glfwCreateWindow(640, 360, "Chemistry Rendering App", nullptr, nullptr);
if (!window) {
std::cerr << "Failed to create window\n";
return -1;
}
try {
createInstance();
createDevice();
createSurface();
createSwapchain();
while (!glfwWindowShouldClose(window)) {
glfwPollEvents();
}
} catch (const std::exception& e) {
std::cerr << "Caught Exception: " << e.what() << "\n";
return 0;
}
glfwDestroyWindow(window);
gnDestroySurface(instance, &surface);
gnDestroyDevice(&device);
gnDestroyInstance(&instance);
}
+1 -1
View File
@@ -45,7 +45,7 @@ void createInstance() {
.applicationName = "Chemistry Rendering App", .applicationName = "Chemistry Rendering App",
.applicationVersion = gnCreateVersion(0, 0, 1), .applicationVersion = gnCreateVersion(0, 0, 1),
.engineName = "Chemistry Rendering Engine", .engineName = "Chemistry Rendering Engine",
.enginnVersion = gnCreateVersion(0, 0, 1) .engineVersion = gnCreateVersion(0, 0, 1)
}, },
.enabledValidationLayerCount = 0, .enabledValidationLayerCount = 0,
.enabledValidationLayers = nullptr, .enabledValidationLayers = nullptr,