add support for creating a metal surface
This commit is contained in:
+8
-2
@@ -1,10 +1,16 @@
|
|||||||
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 OBJCXX) # OBJCXX is required for Metal .mm files
|
||||||
add_executable(ChemistryRenderingApp main.cpp)
|
add_executable(ChemistryRenderingApp main.mm)
|
||||||
|
target_link_libraries(ChemistryRenderingApp PRIVATE
|
||||||
|
"-framework Metal"
|
||||||
|
"-framework Foundation"
|
||||||
|
"-framework QuartzCore"
|
||||||
|
"-framework Cocoa"
|
||||||
|
)
|
||||||
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)
|
||||||
project(ChemistryRenderingApp LANGUAGES C CXX OBJC OBJCXX)
|
|
||||||
|
|
||||||
set(CMAKE_CXX_STANDARD 17)
|
set(CMAKE_CXX_STANDARD 17)
|
||||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||||
|
|||||||
@@ -6,3 +6,4 @@
|
|||||||
GN_HANDLE(gnInstance);
|
GN_HANDLE(gnInstance);
|
||||||
GN_HANDLE(gnPhysicalDevice);
|
GN_HANDLE(gnPhysicalDevice);
|
||||||
GN_HANDLE(gnDevice);
|
GN_HANDLE(gnDevice);
|
||||||
|
GN_IMPLEMENTATION_HANDLE(gnSurface);
|
||||||
|
|||||||
@@ -1,16 +1,19 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "gryphn_handle.h"
|
#include "gryphn_handle.h"
|
||||||
|
typedef struct gnMetalSurfaceCreateInfo gnMetalSurfaceCreateInfo;
|
||||||
typedef struct gnPhysicalDeviceProperties gnPhysicalDeviceProperties;
|
typedef struct gnPhysicalDeviceProperties gnPhysicalDeviceProperties;
|
||||||
typedef struct gnDeviceCreateInfo gnDeviceCreateInfo;
|
typedef struct gnDeviceCreateInfo gnDeviceCreateInfo;
|
||||||
|
|
||||||
typedef gnReturnCode (*PFN_gnDestroyInstance)(gnInstance);
|
typedef gnReturnCode (*PFN_gnCreateMetalSurface)(gnInstance, gnMetalSurfaceCreateInfo*, 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);
|
||||||
|
typedef gnReturnCode (*PFN_gnDestroyInstance)(gnInstance);
|
||||||
|
|
||||||
typedef struct gnInstanceDispatchTable {
|
typedef struct gnInstanceDispatchTable {
|
||||||
PFN_gnDestroyInstance destroyInstance;
|
PFN_gnCreateMetalSurface createMetalSurface;
|
||||||
PFN_enumeratePhysicalDevices enumeratePhysicalDevices;
|
PFN_enumeratePhysicalDevices enumeratePhysicalDevices;
|
||||||
PFN_gnGetPhysicalDeviceProperties getPhysicalDeviceProperties;
|
PFN_gnGetPhysicalDeviceProperties getPhysicalDeviceProperties;
|
||||||
PFN_gnCreateDevice createDevice;
|
PFN_gnCreateDevice createDevice;
|
||||||
|
PFN_gnDestroyInstance destroyInstance;
|
||||||
} gnInstanceDispatchTable;
|
} gnInstanceDispatchTable;
|
||||||
|
|||||||
@@ -0,0 +1,6 @@
|
|||||||
|
#include "gryphn_metal_surface.h"
|
||||||
|
#include "instance/gryphn_instance.h"
|
||||||
|
|
||||||
|
gnReturnCode gnCreateMetalSurface(gnInstance instance, gnMetalSurfaceCreateInfo* createInfo, gnSurface* surface) {
|
||||||
|
return instance->dispatchTable.createMetalSurface(instance, createInfo, surface);
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "gryphn_handle.h"
|
||||||
|
#include "gryphn_return_code.h"
|
||||||
|
|
||||||
|
#ifndef GN_CA_METAL_LAYER
|
||||||
|
typedef struct CAMetalLayer CAMetalLayer;
|
||||||
|
#endif
|
||||||
|
typedef struct gnMetalSurfaceCreateInfo {
|
||||||
|
CAMetalLayer* metalLayer;
|
||||||
|
} gnMetalSurfaceCreateInfo;
|
||||||
|
gnReturnCode gnCreateMetalSurface(gnInstance instance, gnMetalSurfaceCreateInfo* createInfo, gnSurface* surface);
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
file(GLOB_RECURSE METAL_SOURCES CONFIGURE_DEPENDS "src/*.m")
|
file(GLOB_RECURSE METAL_SOURCES CONFIGURE_DEPENDS "src/*.m")
|
||||||
add_library(gryphn_metal SHARED ${METAL_SOURCES})
|
add_library(gryphn_metal SHARED ${METAL_SOURCES})
|
||||||
|
project(gryphn_metal LANGUAGES C CXX OBJC OBJCXX)
|
||||||
set_target_properties(gryphn_metal PROPERTIES PREFIX "")
|
set_target_properties(gryphn_metal PROPERTIES PREFIX "")
|
||||||
target_link_libraries(gryphn_metal PRIVATE GryphnLoader)
|
target_link_libraries(gryphn_metal PRIVATE GryphnLoader)
|
||||||
if(APPLE)
|
if(APPLE)
|
||||||
|
|||||||
@@ -0,0 +1,6 @@
|
|||||||
|
#include "../metal_functions.h"
|
||||||
|
|
||||||
|
gnReturnCode metalCreateSurface(gnInstance instance, gnMetalSurfaceCreateInfo* createInfo, gnSurface* surface) {
|
||||||
|
*surface = createInfo->metalLayer;
|
||||||
|
return GN_SUCCESS;
|
||||||
|
}
|
||||||
@@ -22,5 +22,12 @@ gnReturnCode initBackend(gnInstance instance, gnInstanceCreateInfo* info) {
|
|||||||
instance->dispatchTable.enumeratePhysicalDevices = metalEnumeratePhysicalDevices;
|
instance->dispatchTable.enumeratePhysicalDevices = metalEnumeratePhysicalDevices;
|
||||||
instance->dispatchTable.getPhysicalDeviceProperties = metalGetPhysicalDeviceProperties;
|
instance->dispatchTable.getPhysicalDeviceProperties = metalGetPhysicalDeviceProperties;
|
||||||
instance->dispatchTable.createDevice = metalCreateDevice;
|
instance->dispatchTable.createDevice = metalCreateDevice;
|
||||||
|
|
||||||
|
for (int i = 0; i < info->enabledExtensionCount; i++) {
|
||||||
|
if (strcmp(info->enabledExtensions[i], "GN_EXT_surface") == 0) {
|
||||||
|
instance->dispatchTable.createMetalSurface = metalCreateSurface;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return GN_SUCCESS;
|
return GN_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,15 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
#define GN_CA_METAL_LAYER
|
||||||
|
#import <QuartzCore/CAMetalLayer.h>
|
||||||
#include "gryphn_handle.h"
|
#include "gryphn_handle.h"
|
||||||
#include "gryphn_return_code.h"
|
#include "gryphn_return_code.h"
|
||||||
#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_metal_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);
|
||||||
gnReturnCode metalCreateDevice(gnInstance instance, gnDeviceCreateInfo* createInfo, gnDevice device);
|
gnReturnCode metalCreateDevice(gnInstance instance, gnDeviceCreateInfo* createInfo, gnDevice device);
|
||||||
gnReturnCode metalDestroyDevice(gnDevice device);
|
gnReturnCode metalDestroyDevice(gnDevice device);
|
||||||
|
gnReturnCode metalCreateSurface(gnInstance instance, gnMetalSurfaceCreateInfo* createInfo, gnSurface* surface);
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ 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_metal_surface.h"
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+29
-2
@@ -1,7 +1,13 @@
|
|||||||
|
#import <QuartzCore/CAMetalLayer.h>
|
||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
#import <AppKit/AppKit.h>
|
||||||
|
#define GN_CA_METAL_LAYER
|
||||||
#include "Gryphn/gryphn.h"
|
#include "Gryphn/gryphn.h"
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include "stdlib.h"
|
#include "stdlib.h"
|
||||||
|
#define GLFW_EXPOSE_NATIVE_COCOA
|
||||||
#include "glfw/include/GLFW/glfw3.h"
|
#include "glfw/include/GLFW/glfw3.h"
|
||||||
|
#include "glfw/include/GLFW/glfw3native.h"
|
||||||
|
|
||||||
#define CONCAT_IMPL(a, b) a##b
|
#define CONCAT_IMPL(a, b) a##b
|
||||||
#define CONCAT(a, b) CONCAT_IMPL(a, b)
|
#define CONCAT(a, b) CONCAT_IMPL(a, b)
|
||||||
@@ -13,9 +19,11 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
GLFWwindow* window;
|
GLFWwindow* window;
|
||||||
|
CAMetalLayer* layer;
|
||||||
gnVersion version = gnCreateVersion(1, 0, 0);
|
gnVersion version = gnCreateVersion(1, 0, 0);
|
||||||
gnInstance instance;
|
gnInstance instance;
|
||||||
gnDevice device;
|
gnDevice device;
|
||||||
|
gnSurface surface;
|
||||||
|
|
||||||
void createInstance() {
|
void createInstance() {
|
||||||
uint32_t backendCount = 0;
|
uint32_t backendCount = 0;
|
||||||
@@ -25,6 +33,9 @@ void createInstance() {
|
|||||||
}
|
}
|
||||||
gnBackend* backends = (gnBackend*)malloc(sizeof(gnBackend) * backendCount);
|
gnBackend* backends = (gnBackend*)malloc(sizeof(gnBackend) * backendCount);
|
||||||
CHECK(gnGetAvaliableBackends(version, &backendCount, backends));
|
CHECK(gnGetAvaliableBackends(version, &backendCount, backends));
|
||||||
|
const char* extensions[1] = {
|
||||||
|
"GN_EXT_surface"
|
||||||
|
};
|
||||||
|
|
||||||
gnInstanceCreateInfo createInfo = {
|
gnInstanceCreateInfo createInfo = {
|
||||||
.backend = backends[0],
|
.backend = backends[0],
|
||||||
@@ -36,8 +47,8 @@ void createInstance() {
|
|||||||
},
|
},
|
||||||
.enabledValidationLayerCount = 0,
|
.enabledValidationLayerCount = 0,
|
||||||
.enabledValidationLayers = nullptr,
|
.enabledValidationLayers = nullptr,
|
||||||
.enabledExtensionCount = 0,
|
.enabledExtensionCount = 1,
|
||||||
.enabledExtensions = nullptr
|
.enabledExtensions = extensions
|
||||||
};
|
};
|
||||||
CHECK(gnCreateInstance(&instance, &createInfo));
|
CHECK(gnCreateInstance(&instance, &createInfo));
|
||||||
free(backends);
|
free(backends);
|
||||||
@@ -62,12 +73,27 @@ void createDevice() {
|
|||||||
CHECK(gnCreateDevice(instance, &createInfo, &device));
|
CHECK(gnCreateDevice(instance, &createInfo, &device));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void createSurface() {
|
||||||
|
NSWindow* nswin = glfwGetCocoaWindow((GLFWwindow*)window);
|
||||||
|
NSView* view = [nswin contentView];
|
||||||
|
layer = [CAMetalLayer layer];
|
||||||
|
[view setWantsLayer:YES];
|
||||||
|
[view setLayer:layer];
|
||||||
|
layer.contentsScale = [nswin backingScaleFactor];
|
||||||
|
|
||||||
|
gnMetalSurfaceCreateInfo createInfo = {
|
||||||
|
.metalLayer = layer
|
||||||
|
};
|
||||||
|
CHECK(gnCreateMetalSurface(instance, &createInfo, &surface))
|
||||||
|
}
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
if (!glfwInit()) {
|
if (!glfwInit()) {
|
||||||
std::cout << "Failed to init GLFW\n";
|
std::cout << "Failed to init GLFW\n";
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
|
||||||
window = glfwCreateWindow(640, 360, "Chemistry Rendering App", nullptr, nullptr);
|
window = glfwCreateWindow(640, 360, "Chemistry Rendering App", nullptr, nullptr);
|
||||||
if (!window) {
|
if (!window) {
|
||||||
std::cerr << "Failed to create window\n";
|
std::cerr << "Failed to create window\n";
|
||||||
@@ -77,6 +103,7 @@ int main() {
|
|||||||
try {
|
try {
|
||||||
createInstance();
|
createInstance();
|
||||||
createDevice();
|
createDevice();
|
||||||
|
createSurface();
|
||||||
while (!glfwWindowShouldClose(window)) {
|
while (!glfwWindowShouldClose(window)) {
|
||||||
glfwPollEvents();
|
glfwPollEvents();
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user