Initial commit
This commit is contained in:
@@ -0,0 +1 @@
|
||||
build/
|
||||
@@ -0,0 +1,10 @@
|
||||
cmake_minimum_required(VERSION 3.12)
|
||||
project(ChemistryRenderingApp LANGUAGES C CXX OBJCXX) # OBJCXX is required for Metal .mm files
|
||||
add_executable(ChemistryRenderingApp main.cpp)
|
||||
target_include_directories(ChemistryRenderingApp PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}")
|
||||
target_link_libraries(ChemistryRenderingApp PRIVATE GryphnLoader)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
add_subdirectory(Gryphn)
|
||||
@@ -0,0 +1,13 @@
|
||||
cmake_minimum_required(VERSION 3.12)
|
||||
project(Gryphn LANGUAGES C CXX OBJCXX) # OBJCXX is required for Metal .mm files
|
||||
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
# Define output directories to keep all binaries in one place
|
||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
|
||||
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
|
||||
|
||||
# Add subdirectories
|
||||
add_subdirectory(GryphnLoader)
|
||||
add_subdirectory(apis/GryphnMetal)
|
||||
@@ -0,0 +1,23 @@
|
||||
project(GryphnLoader)
|
||||
|
||||
# 1. Collect sources
|
||||
file(GLOB_RECURSE LOADER_SOURCES CONFIGURE_DEPENDS "src/*.c")
|
||||
|
||||
# 2. Build the library
|
||||
add_library(GryphnLoader STATIC ${LOADER_SOURCES})
|
||||
|
||||
# 3. FIX: Add BOTH the include folder (for the API) and src (for internal headers)
|
||||
# We use CMAKE_SOURCE_DIR to get back to the root 'include' folder
|
||||
target_include_directories(GryphnLoader PUBLIC
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/src"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/src/instance"
|
||||
)
|
||||
|
||||
if(APPLE)
|
||||
target_compile_definitions(GryphnLoader PUBLIC GN_PLATFORM_MACOS)
|
||||
endif()
|
||||
|
||||
# 4. Links
|
||||
if(UNIX AND NOT APPLE)
|
||||
target_link_libraries(GryphnLoader PRIVATE dl)
|
||||
endif()
|
||||
@@ -0,0 +1,23 @@
|
||||
#include "gryphn_backend.h"
|
||||
#include "stdio.h"
|
||||
#include "instance/gryphn_application_info.h"
|
||||
#include "gryphn_lib/gryphn_lib.h"
|
||||
#include "stdint.h"
|
||||
|
||||
typedef uint32_t (*PFN_gnInternalIsApiSupported)(gnVersion);
|
||||
|
||||
gnReturnCode gnGetAvaliableBackends(gnVersion version, uint32_t* avaliable_backends, gnBackend* backends) {
|
||||
*avaliable_backends = 0;
|
||||
gnLib metalLib = gnLoadLib("bin/gryphn_metal.dylib");
|
||||
if (gnLibValid(&metalLib)) {
|
||||
PFN_gnInternalIsApiSupported isSupported = (PFN_gnInternalIsApiSupported)gnLoadLibFunction(&metalLib, "gnInternalIsApiSupported");
|
||||
if (isSupported(version) > 0) {
|
||||
if (backends != NULL) {
|
||||
backends[*avaliable_backends] = GN_BACKEND_METAL;
|
||||
}
|
||||
*avaliable_backends += 1;
|
||||
}
|
||||
}
|
||||
gnCloseLib(&metalLib);
|
||||
return GN_SUCCESS;
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
#pragma once
|
||||
#include "gryphn_return_code.h"
|
||||
#include "stdint.h"
|
||||
#include "instance/gryphn_application_info.h"
|
||||
|
||||
typedef enum gnBackend {
|
||||
GN_BACKEND_VULKAN = 0,
|
||||
GN_BACKEND_METAL = 1,
|
||||
GN_BACKEND_OPENGL = 2,
|
||||
GN_BACKEND_DIRECTX12 = 3
|
||||
} gnBackend;
|
||||
gnReturnCode gnGetAvaliableBackends(gnVersion version, uint32_t* avaliable_backends, gnBackend* backends);
|
||||
@@ -0,0 +1,4 @@
|
||||
#pragma once
|
||||
|
||||
#define GN_HANDLE(type) typedef struct type##_t* type
|
||||
GN_HANDLE(gnInstance);
|
||||
@@ -0,0 +1,31 @@
|
||||
#include "gryphn_lib.h"
|
||||
#ifdef GN_PLATFORM_MACOS
|
||||
#include <dlfcn.h>
|
||||
#endif
|
||||
|
||||
|
||||
gnLib gnLoadLib(const char* path) {
|
||||
#ifdef GN_PLATFORM_MACOS
|
||||
gnLib lib;
|
||||
lib.dylib = dlopen(path, RTLD_NOW | RTLD_LOCAL);
|
||||
return lib;
|
||||
#endif
|
||||
}
|
||||
|
||||
int gnLibValid(const gnLib* lib) {
|
||||
#ifdef GN_PLATFORM_MACOS
|
||||
return lib->dylib != 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
void* gnLoadLibFunction(const gnLib* lib, const char* function) {
|
||||
#ifdef GN_PLATFORM_MACOS
|
||||
return dlsym(lib->dylib, function);
|
||||
#endif
|
||||
}
|
||||
|
||||
void gnCloseLib(const gnLib* lib) {
|
||||
#ifdef GN_PLATFORM_MACOS
|
||||
dlclose(lib->dylib);
|
||||
#endif
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
typedef struct gnLib {
|
||||
#ifdef GN_PLATFORM_MACOS
|
||||
void* dylib;
|
||||
#endif
|
||||
} gnLib;
|
||||
|
||||
gnLib gnLoadLib(const char* path);
|
||||
int gnLibValid(const gnLib* lib);
|
||||
void* gnLoadLibFunction(const gnLib* lib, const char* function);
|
||||
void gnCloseLib(const gnLib* lib);
|
||||
@@ -0,0 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
typedef enum gnReturnCode {
|
||||
GN_SUCCESS,
|
||||
GN_FAILED_TO_FIND_LIBARY
|
||||
} gnReturnCode;
|
||||
@@ -0,0 +1,8 @@
|
||||
#pragma once
|
||||
#include "gryphn_handle.h"
|
||||
|
||||
typedef gnReturnCode (*PFN_gnDestroyInstance)(gnInstance);
|
||||
|
||||
typedef struct gnInstanceDispatchTable {
|
||||
PFN_gnDestroyInstance destroyInstance;
|
||||
} gnInstanceDispatchTable;
|
||||
@@ -0,0 +1,12 @@
|
||||
#pragma once
|
||||
#include <stdint.h>
|
||||
|
||||
typedef uint32_t gnVersion;
|
||||
#define gnCreateVersion(major, minor, patch) ((((uint32_t)(major)) << 22U) | (((uint32_t)(minor)) << 12U) | ((uint32_t)(patch)))
|
||||
|
||||
typedef struct gnApplicationInfo {
|
||||
const char* applicationName;
|
||||
gnVersion applicationVersion;
|
||||
const char* engineName;
|
||||
gnVersion enginnVersion;
|
||||
} gnApplicationInfo;
|
||||
@@ -0,0 +1,25 @@
|
||||
#include "gryphn_instance.h"
|
||||
#include "stdlib.h"
|
||||
#include "stdio.h"
|
||||
|
||||
typedef gnReturnCode (*PFN_initBackend)(gnInstance, gnInstanceCreateInfo*);
|
||||
|
||||
gnReturnCode gnCreateInstance(gnInstance* newInstance, gnInstanceCreateInfo* createInfo) {
|
||||
gnInstance_t* instance = malloc(sizeof(gnInstance_t));
|
||||
*newInstance = instance;
|
||||
|
||||
if (createInfo->backend == GN_BACKEND_METAL) {
|
||||
instance->internalLib = gnLoadLib("bin/gryphn_metal.dylib");
|
||||
PFN_initBackend initBackend = (PFN_initBackend)gnLoadLibFunction(&instance->internalLib, "initBackend");
|
||||
initBackend(instance, createInfo);
|
||||
}
|
||||
|
||||
return GN_SUCCESS;
|
||||
}
|
||||
gnReturnCode gnDestroyInstance(gnInstance* instance) {
|
||||
(*instance)->dispatchTable.destroyInstance(*instance);
|
||||
gnCloseLib(&(*instance)->internalLib);
|
||||
free(*instance);
|
||||
*instance = NULL;
|
||||
return GN_SUCCESS;
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
#pragma once
|
||||
#include "gryphn_instance_create_info.h"
|
||||
#include "gryphn_handle.h"
|
||||
#include "dispatch/gryphn_instance_dispatch_table.h"
|
||||
#include "gryphn_lib/gryphn_lib.h"
|
||||
|
||||
typedef struct gnInstance_t {
|
||||
gnInstanceDispatchTable dispatchTable;
|
||||
gnLib internalLib;
|
||||
void* internalData;
|
||||
} gnInstance_t;
|
||||
|
||||
gnReturnCode gnCreateInstance(gnInstance* instance, gnInstanceCreateInfo* createInfo);
|
||||
gnReturnCode gnDestroyInstance(gnInstance* instance);
|
||||
@@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
#include "gryphn_application_info.h"
|
||||
#include "gryphn_return_code.h"
|
||||
#include <backend/gryphn_backend.h>
|
||||
|
||||
typedef enum gnInstanceCreateInfoFlags {
|
||||
GN_NO_FLAGS
|
||||
} gnInstanceCreateInfoFlags;
|
||||
|
||||
typedef struct gnInstanceCreateInfo {
|
||||
gnBackend backend;
|
||||
gnInstanceCreateInfoFlags flags;
|
||||
gnApplicationInfo info;
|
||||
uint32_t enabledValidationLayerCount;
|
||||
const char** enabledValidationLayers;
|
||||
uint32_t enabledExtensionCount;
|
||||
const char** enabledExtensions;
|
||||
} gnInstanceCreateInfo;
|
||||
@@ -0,0 +1,12 @@
|
||||
file(GLOB_RECURSE METAL_SOURCES CONFIGURE_DEPENDS "src/*.m")
|
||||
add_library(gryphn_metal SHARED ${METAL_SOURCES})
|
||||
set_target_properties(gryphn_metal PROPERTIES PREFIX "")
|
||||
target_link_libraries(gryphn_metal PRIVATE GryphnLoader)
|
||||
if(APPLE)
|
||||
target_link_libraries(gryphn_metal PRIVATE
|
||||
"-framework Metal"
|
||||
"-framework Foundation"
|
||||
"-framework QuartzCore"
|
||||
"-framework Cocoa"
|
||||
)
|
||||
endif()
|
||||
@@ -0,0 +1,24 @@
|
||||
#import <Metal/Metal.h>
|
||||
#include "stdio.h"
|
||||
#include "instance/gryphn_instance.h"
|
||||
#include "gryphn_handle.h"
|
||||
|
||||
extern "C" uint32_t gnInternalIsApiSupported(gnVersion version) {
|
||||
if (version != gnCreateVersion(1, 0, 0)) return 0;
|
||||
id<MTLDevice> testDevice = MTLCreateSystemDefaultDevice();
|
||||
if (testDevice == nil)
|
||||
return 0;
|
||||
[testDevice release];
|
||||
return 1;
|
||||
}
|
||||
|
||||
gnReturnCode destroyBackend(gnInstance instance) {
|
||||
printf("Calling destroy instance");
|
||||
return GN_SUCCESS;
|
||||
}
|
||||
|
||||
extern "C" gnReturnCode initBackend(gnInstance instance, gnInstanceCreateInfo* info) {
|
||||
printf("calling init instance\n");
|
||||
instance->dispatchTable.destroyInstance = destroyBackend;
|
||||
return GN_SUCCESS;
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#include "GryphnLoader/src/instance/gryphn_instance.h"
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,51 @@
|
||||
#include "Gryphn/gryphn.h"
|
||||
#include <iostream>
|
||||
#include "stdlib.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"; \
|
||||
}
|
||||
|
||||
gnVersion version = gnCreateVersion(1, 0, 0);
|
||||
gnInstance instance;
|
||||
|
||||
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));
|
||||
|
||||
gnInstanceCreateInfo createInfo = {
|
||||
.backend = backends[0],
|
||||
.info = {
|
||||
.applicationName = "Chemistry Rendering App",
|
||||
.applicationVersion = gnCreateVersion(0, 0, 1),
|
||||
.engineName = "Chemistry Rendering Engine",
|
||||
.enginnVersion = gnCreateVersion(0, 0, 1)
|
||||
},
|
||||
.enabledValidationLayerCount = 0,
|
||||
.enabledValidationLayers = nullptr,
|
||||
.enabledExtensionCount = 0,
|
||||
.enabledExtensions = nullptr
|
||||
};
|
||||
CHECK(gnCreateInstance(&instance, &createInfo));
|
||||
free(backends);
|
||||
}
|
||||
|
||||
int main() {
|
||||
try {
|
||||
createInstance();
|
||||
} catch (const std::exception& e) {
|
||||
std::cerr << "Caught Exception: " << e.what() << "\n";
|
||||
return 0;
|
||||
}
|
||||
gnDestroyInstance(&instance);
|
||||
}
|
||||
Reference in New Issue
Block a user