Compare commits

..

55 Commits

Author SHA1 Message Date
Gregory Wells
5228b6630c finally redo physical device creation 2025-10-01 13:22:52 -04:00
Gregory Wells
5ce0ff3350 fix can device present function 2025-10-01 11:41:08 -04:00
Gregory Wells
63ec31216e forgot to return array of devices 2025-10-01 11:37:40 -04:00
Gregory Wells
ebc6ce724f fix some shit in the validation layers 2025-10-01 09:23:09 -04:00
Gregory Wells
3a5ddac2c5 "fixed" metal impl 2025-10-01 09:21:21 -04:00
Gregory Wells
f93853608c removed a ton of errors 2025-10-01 09:19:43 -04:00
Gregory Wells
481f590234 did some stuff in queue creation for vulkan 2025-10-01 09:18:22 -04:00
Gregory Wells
d79a3c45bf change more words 2025-09-29 23:33:47 -04:00
Gregory Wells
3bf252d582 uhhhh me change word 2025-09-29 23:30:32 -04:00
Gregory Wells
228d75e5ac finish query functions in Vulkan 2025-09-19 10:12:10 -04:00
Gregory Wells
3066f7c2bd check functions for new API 2025-09-19 09:29:55 -04:00
Gregory Wells
427f0ee5b1 reorder code 2025-09-19 09:25:12 -04:00
Gregory Wells
4b981055bd forgot that im stuipd 2025-09-19 09:24:20 -04:00
Gregory Wells
1095e20dc2 update utils version 2025-09-19 09:21:25 -04:00
Gregory Wells
a0450a0351 write all new functions headers 2025-09-19 09:21:18 -04:00
Gregory Wells
c495a7a0e8 change some useless stuff 2025-09-19 09:21:03 -04:00
Gregory Wells
eef7045ac2 feature layer functions 2025-09-17 13:47:23 -04:00
Gregory Wells
7ace503ab0 physical device features function and struct 2025-09-17 13:45:42 -04:00
Gregory Wells
6f278affc6 metal is instance suitable 2025-09-17 13:39:19 -04:00
Gregory Wells
f7e71b77c2 metal physical device properties function 2025-09-17 13:37:50 -04:00
Gregory Wells
88bdbe1e64 don't remember what I changed 2025-09-17 13:26:16 -04:00
Gregory Wells
17b7970aa0 vulkan physical device get properties 2025-09-17 13:24:30 -04:00
Gregory Wells
ef53ffd458 physical device retrieval functions 2025-09-10 13:46:49 -04:00
Gregory Wells
a446d6e75f instance suitability functions 2025-09-10 13:26:18 -04:00
Gregory Wells
0310652abc finish queryDevices function 2025-09-09 09:39:13 -04:00
Gregory Wells
88649174a9 remove old gnGetPhysicalDevices 2025-09-09 09:32:01 -04:00
Gregory Wells
9244b82f79 query metal devices 2025-09-09 09:31:09 -04:00
Gregory Wells
c5297cb17b start to redo physical device model 2025-09-04 14:52:37 -04:00
Gregory Wells
a709ff8808 rename gnPhysicalOutputDevice -> gnPhysicalDevice 2025-08-29 13:55:29 -04:00
Gregory Wells
76a787d48f fix some compile errors 2025-08-29 13:45:08 -04:00
Gregory Wells
1e8855905d update version of utils used 2025-08-29 13:43:25 -04:00
Gregory Wells
809750749a Update README.md 2025-08-20 14:39:18 -04:00
Gregory Wells
4d904557d8 Finish OpenGL support 2025-08-20 14:37:39 -04:00
Gregory Wells
263a8e54fa truly bind all uniforms 2025-08-20 10:52:26 -04:00
Gregory Wells
5422fd8b68 finally get stuff to present 2025-08-20 10:47:50 -04:00
Gregory Wells
0c89bdb791 bind texture uniforms 2025-08-19 22:20:53 -04:00
Gregory Wells
c7ae6532fd update uniforms properly 2025-08-19 22:18:55 -04:00
Gregory Wells
18ec089ebc copy set map to graphics pipeline 2025-08-19 22:18:44 -04:00
Gregory Wells
0c0988b75a redo shader mapping 2025-08-19 22:15:24 -04:00
Gregory Wells
01de997df5 fix buffer binding on OpenGL 2025-08-19 21:43:12 -04:00
Gregory Wells
380c5d056f flip framebuffer 2025-08-19 20:41:45 -04:00
Gregory Wells
f5d7257e66 fix framebuffers being drawn flipped 2025-08-19 17:43:56 -04:00
Gregory Wells
16d2e7b8fc SRGB in OpenGL 2025-08-19 16:50:16 -04:00
Gregory Wells
7f6ec430de finish the most basic rendering pipeline 2025-08-19 16:31:19 -04:00
Gregory Wells
50d8a669b3 draw commands 2025-08-19 08:50:00 -04:00
Gregory Wells
55605b6d5f render 2025-08-19 08:39:29 -04:00
Gregory Wells
740cf1e628 render fullscreen texcoord quad 2025-08-18 23:22:09 -04:00
Gregory Wells
453f7b70db create framebuffer object 2025-08-18 23:02:56 -04:00
Gregory Wells
51bd6e28fa get the first opengl commands to be deferred 2025-08-18 22:30:00 -04:00
Gregory Wells
7b1266281c Run OpenGL commands 2025-08-18 22:09:05 -04:00
Gregory Wells
be2f91e2bb command runner and some tests 2025-08-18 22:00:23 -04:00
Gregory Wells
d1862e3d6f setup basic command runner 2025-08-18 21:42:32 -04:00
Gregory Wells
10cd374731 create graphics pipelines 2025-08-18 21:30:54 -04:00
Gregory Wells
4477c41dc4 render pass in OpenGL 2025-08-18 21:22:22 -04:00
Gregory Wells
916df68f06 OpenGL framebuffer API 2025-08-18 21:13:40 -04:00
79 changed files with 1127 additions and 357 deletions

View File

@@ -9,9 +9,8 @@ Gryphn works to abstract away platform API functions (Vulkan, Metal, D3D11/D3D12
- [x] Metal - [x] Metal
- [ ] Direct 3D 11 - [ ] Direct 3D 11
- [ ] Direct 3D 12 - [ ] Direct 3D 12
- [ ] OpenGL - [x] OpenGL
- [ ] Software - [ ] Software
* Currently working on the OpenGL backend
# Features # Features
#### Application objects #### Application objects
@@ -98,3 +97,8 @@ if (code != GN_SUCCESS) printf("Failed to create XXXX %s\n", gnErrorCodeToCStrin
``` ```
# Known limitations
### OpenGL:
OpenGL currently doesn't support push constants, I have some ideas brainstormed to help me support them but for the time being the max push constant size is set to zero
### Metal:
The device must support argument buffers for metal, at some point I will work on a solition to support both

View File

@@ -3,7 +3,7 @@
// core functionality // core functionality
#include <core/src/instance/gryphn_instance.h> #include <core/src/instance/gryphn_instance.h>
#include <core/src/output_device/gryphn_physical_output_device.h> #include <core/src/output_device/gryphn_physical_device.h>
#include <core/src/window_surface/gryphn_surface.h> #include <core/src/window_surface/gryphn_surface.h>
#include <core/src/window_surface/gryphn_surface_create_functions.h> #include <core/src/window_surface/gryphn_surface_create_functions.h>
#include <core/src/presentation_queue/gryphn_presentation_queue.h> #include <core/src/presentation_queue/gryphn_presentation_queue.h>

View File

@@ -3,7 +3,7 @@ set(CMAKE_CXX_STANDARD 17)
project(GryphnMetalImpl) project(GryphnMetalImpl)
file(GLOB_RECURSE SOURCE_FILES CONFIGURE_DEPENDS file(GLOB_RECURSE SOURCE_FILES CONFIGURE_DEPENDS
"src/*.c" "src/*.h" "src/*.m" "src/*.mm" "src/*.c" "src/*.cpp" "src/*.h" "src/*.m" "src/*.mm"
) )
file(GLOB_RECURSE LOADER_FILES CONFIGURE_DEPENDS file(GLOB_RECURSE LOADER_FILES CONFIGURE_DEPENDS
"loader/*.m" "loader/*.m"

View File

@@ -6,14 +6,16 @@
gryphnInstanceFunctionLayers metalLoadAPILayer(void) { gryphnInstanceFunctionLayers metalLoadAPILayer(void) {
return (gryphnInstanceFunctionLayers) { return (gryphnInstanceFunctionLayers) {
.createInstance = metalCreateInstance, .createInstance = metalCreateInstance,
.queryDevices = metalQueryDevices,
.destroyInstance = metalDestroyInstance, .destroyInstance = metalDestroyInstance,
.isSuitable = metalIsInstanceSuitable,
.getPhysicalDeviceProperties = metalQueryPhysicalDeviceProperties,
.next = NULL .next = NULL
}; };
} }
gnInstanceFunctions loadMetalInstanceFunctions(void) { gnInstanceFunctions loadMetalInstanceFunctions(void) {
return (gnInstanceFunctions){ return (gnInstanceFunctions){
._gnGetPhysicalDevices = getMetalDevices,
._gnPhysicalDeviceCanPresentToSurface = metalCanDevicePresent, ._gnPhysicalDeviceCanPresentToSurface = metalCanDevicePresent,
._gnCreateOutputDevice = createMetalOutputDevice, ._gnCreateOutputDevice = createMetalOutputDevice,
._gnDestroyOutputDevice = destroyMetalOutputDevice, ._gnDestroyOutputDevice = destroyMetalOutputDevice,

View File

@@ -1,4 +1,4 @@
#include <output_device/gryphn_physical_output_device.h> #include <output_device/gryphn_physical_device.h>
#include <Metal/Metal.h> #include <Metal/Metal.h>
#include "metal_output_devices.h" #include "metal_output_devices.h"
#include "instance/metal_instance.h" #include "instance/metal_instance.h"
@@ -10,7 +10,7 @@ gnReturnCode createMetalOutputDevice(gnInstanceHandle instance, gnOutputDeviceHa
if (instance == GN_NULL_HANDLE) return GN_INVALID_HANDLE; if (instance == GN_NULL_HANDLE) return GN_INVALID_HANDLE;
outputDevice->outputDevice = malloc(sizeof(gnPlatformOutputDevice)); outputDevice->outputDevice = malloc(sizeof(gnPlatformOutputDevice));
outputDevice->outputDevice->device = deviceInfo.physicalDevice->physicalDevice->device.retain; outputDevice->outputDevice->device = ((mtlDevice)deviceInfo.physicalDevice).retain;
outputDevice->outputDevice->transferQueue = outputDevice->outputDevice->device.newCommandQueue; outputDevice->outputDevice->transferQueue = outputDevice->outputDevice->device.newCommandQueue;
outputDevice->outputDevice->stagingBuffer = [outputDevice->outputDevice->device newBufferWithLength:(128 * 1024 * 1024) options:MTLResourceStorageModeShared]; outputDevice->outputDevice->stagingBuffer = [outputDevice->outputDevice->device newBufferWithLength:(128 * 1024 * 1024) options:MTLResourceStorageModeShared];

View File

@@ -4,9 +4,8 @@
#include <Metal/Metal.h> #include <Metal/Metal.h>
#include <MetalKit/MetalKit.h> #include <MetalKit/MetalKit.h>
struct gnPlatformPhysicalDevice_t { typedef id<MTLDevice> mtlDevice;
id<MTLDevice> device; gnPhysicalDeviceProperties metalQueryPhysicalDeviceProperties(gnInstance instance, gnPhysicalDeviceHandle device, gryphnInstanceFunctionLayers* layers);
} gnPlatformPhysicalDevice;
struct gnPlatformOutputDevice_t { struct gnPlatformOutputDevice_t {
id<MTLDevice> device; id<MTLDevice> device;
@@ -24,7 +23,7 @@ struct gnPlatformOutputDevice_t {
} gnPlatformOutputDevice; } gnPlatformOutputDevice;
gnPhysicalDevice* getMetalDevices(gnInstanceHandle instance, uint32_t* deviceCount); gnPhysicalDevice* getMetalDevices(gnInstanceHandle instance, uint32_t* deviceCount);
gnBool metalCanDevicePresent(gnPhysicalDevice device, gnWindowSurface windowSurface); gnBool metalCanDevicePresent(gnInstance instance, gnPhysicalDevice device, gnWindowSurface windowSurface);
gnReturnCode createMetalOutputDevice(gnInstanceHandle instance, gnOutputDeviceHandle outputDevice, gnOutputDeviceInfo deviceInfo); gnReturnCode createMetalOutputDevice(gnInstanceHandle instance, gnOutputDeviceHandle outputDevice, gnOutputDeviceInfo deviceInfo);
void waitForMetalDevice(gnOutputDeviceHandle device); void waitForMetalDevice(gnOutputDeviceHandle device);

View File

@@ -1,47 +1,29 @@
#include <output_device/gryphn_physical_output_device.h> #include <output_device/gryphn_physical_device.h>
#include <Metal/Metal.h> #include <Metal/Metal.h>
#include "metal_output_devices.h" #include "metal_output_devices.h"
#include "window_surface/gryphn_surface.h" #include "window_surface/gryphn_surface.h"
gnPhysicalDevice* getMetalDevices(gnInstanceHandle instance, uint32_t* deviceCount) { // i made some educated guesses on these conversions and I dont think they are going to work
if (instance == GN_NULL_HANDLE) return NULL; // but for now im worried about the MVP
gnPhysicalDeviceType metalDeviceLocationToGryphn(MTLDeviceLocation location) {
NSArray *devices = MTLCopyAllDevices(); switch (location) {
*deviceCount = (uint32_t)[devices count]; case MTLDeviceLocationBuiltIn: return GN_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU;
gnPhysicalDevice* devicesList = (gnPhysicalDevice*)malloc(sizeof(gnPhysicalDevice) * *deviceCount); case MTLDeviceLocationSlot: return GN_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU;
for (uint32_t i = 0; i < *deviceCount; i++) { case MTLDeviceLocationExternal: return GN_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU;
devicesList[i] = malloc(sizeof(gnPhysicalOutputDevice_t)); case MTLDeviceLocationUnspecified: return GN_PHYSICAL_DEVICE_TYPE_FAKED_GPU; //very bad if we get here
devicesList[i]->physicalDevice = malloc(sizeof(gnPlatformPhysicalDevice));
devicesList[i]->physicalDevice->device = [devices objectAtIndex:0];
id<MTLDevice> device = [devices objectAtIndex:0];
devicesList[i]->properties.name = gnCreateString([[device name] cStringUsingEncoding:NSUTF8StringEncoding]);
MTLDeviceLocation deviceLocation = device.locationNumber;
if (deviceLocation == MTLDeviceLocationBuiltIn)
devicesList[i]->properties.deviceType = GN_INTEGRATED_DEVICE;
else if (deviceLocation == MTLDeviceLocationSlot)
devicesList[i]->properties.deviceType = GN_DEDICATED_DEVICE;
else if (deviceLocation == MTLDeviceLocationExternal)
devicesList[i]->properties.deviceType = GN_EXTERNAL_DEVICE;
devicesList[i]->features.maxColorSamples = GN_SAMPLE_BIT_1;
if ([device supportsTextureSampleCount:2]) { devicesList[i]->features.maxColorSamples |= GN_SAMPLE_BIT_2; } else {}
if ([device supportsTextureSampleCount:4]) { devicesList[i]->features.maxColorSamples |= GN_SAMPLE_BIT_4; } else {}
if ([device supportsTextureSampleCount:8]) { devicesList[i]->features.maxColorSamples |= GN_SAMPLE_BIT_8; } else {}
if ([device supportsTextureSampleCount:16]) { devicesList[i]->features.maxColorSamples |= GN_SAMPLE_BIT_16; } else {}
if ([device supportsTextureSampleCount:32]) { devicesList[i]->features.maxColorSamples |= GN_SAMPLE_BIT_32; } else {}
devicesList[i]->features.maxDepthSamples = devicesList[i]->features.maxColorSamples;
devicesList[i]->features.maxMemoryAllocations = 0x40000000;
devicesList[i]->features.maxPushConstantSize = 4096;
} }
[devices release];
return devicesList;
} }
gnBool metalCanDevicePresent(gnPhysicalDevice device, gnWindowSurface windowSurface) { gnPhysicalDeviceProperties metalQueryPhysicalDeviceProperties(gnInstance instance, gnPhysicalDeviceHandle device, gryphnInstanceFunctionLayers* layers) {
return (gnPhysicalDeviceProperties){
.deviceID = ((mtlDevice)device).registryID,
.deviceName = gnCreateString(((mtlDevice)device).name.UTF8String),
.deviceType = metalDeviceLocationToGryphn(((mtlDevice)device).location),
.driverVersion = ((mtlDevice)device).hash // very bad hack, me should not do this
};
}
gnBool metalCanDevicePresent(gnInstance instance, gnPhysicalDevice device, gnWindowSurface windowSurface) {
if (device == GN_NULL_HANDLE || windowSurface == GN_NULL_HANDLE) return GN_FALSE; if (device == GN_NULL_HANDLE || windowSurface == GN_NULL_HANDLE) return GN_FALSE;
return GN_TRUE; // I belive that a window should always be able to present to a surface in metal return GN_TRUE; // I belive that a window should always be able to present to a surface in metal
} }

View File

@@ -8,4 +8,6 @@ typedef struct gnPlatformInstance_t {
} gnPlatformInstance; } gnPlatformInstance;
gnReturnCode metalCreateInstance(gnInstanceHandle instance, gnInstanceCreateInfo* instanceInfo, gryphnInstanceFunctionLayers* next, gnAllocators* allocators); gnReturnCode metalCreateInstance(gnInstanceHandle instance, gnInstanceCreateInfo* instanceInfo, gryphnInstanceFunctionLayers* next, gnAllocators* allocators);
gnReturnCode metalQueryDevices(gnInstanceHandle instance, uint32_t* count, gnPhysicalDeviceHandle* devices, gryphnInstanceFunctionLayers* next);
gnBool metalIsInstanceSuitable(gnInstanceHandle instance, gnSuitableField field, gryphnInstanceFunctionLayers* next);
void metalDestroyInstance(gnInstance instance, gryphnInstanceFunctionLayers* next, gnAllocators* allocators); void metalDestroyInstance(gnInstance instance, gryphnInstanceFunctionLayers* next, gnAllocators* allocators);

View File

@@ -8,6 +8,20 @@ gnReturnCode metalCreateInstance(gnInstanceHandle instance, gnInstanceCreateInfo
instance->instance = allocators->malloc(sizeof(gnPlatformInstance), allocators->userData); instance->instance = allocators->malloc(sizeof(gnPlatformInstance), allocators->userData);
return GN_SUCCESS; return GN_SUCCESS;
} }
gnReturnCode metalQueryDevices(gnInstanceHandle instance, uint32_t* count, gnPhysicalDeviceHandle* devices, gryphnInstanceFunctionLayers* next) {
if (instance == GN_NULL_HANDLE) return GN_INVALID_HANDLE;
NSArray *metalDevices = MTLCopyAllDevices();
*count = (uint32_t)[metalDevices count];
if (devices == NULL) return GN_SUCCESS;
for (int i = 0; i < *count; i++)
devices[i] = (uint64_t)metalDevices[i];
return GN_SUCCESS;
}
gnBool metalIsInstanceSuitable(gnInstanceHandle instance, gnSuitableField field, gryphnInstanceFunctionLayers* next) {
switch (field) {
case GN_NON_EXISTANT_PHYSICAL_DEVICE: return GN_FALSE;
}
}
void metalDestroyInstance(gnInstanceHandle instance, gryphnInstanceFunctionLayers* next, gnAllocators* allocators) { void metalDestroyInstance(gnInstanceHandle instance, gryphnInstanceFunctionLayers* next, gnAllocators* allocators) {
if (next != NULL) return; if (next != NULL) return;
allocators->free(instance->instance, allocators->userData); allocators->free(instance->instance, allocators->userData);

View File

@@ -41,8 +41,9 @@ gnSurfaceDetails getMetalSurfaceDetails(
MTLPixelFormat mtlGryphnFormatToMetalFormat(gnImageFormat format) { MTLPixelFormat mtlGryphnFormatToMetalFormat(gnImageFormat format) {
switch (format) { switch (format) {
case GN_FORMAT_NONE: return MTLPixelFormatInvalid; case GN_FORMAT_NONE: return MTLPixelFormatInvalid;
case GN_FORMAT_BGRA8_SRGB: return MTLPixelFormatBGRA8Unorm_sRGB;
case GN_FORMAT_BGRA8: return MTLPixelFormatBGRA8Unorm; case GN_FORMAT_BGRA8: return MTLPixelFormatBGRA8Unorm;
case GN_FORMAT_BGRA8_SRGB: return MTLPixelFormatBGRA8Unorm_sRGB;
case GN_FORMAT_RGBA8: return MTLPixelFormatRGBA8Unorm;
case GN_FORMAT_RGBA8_SRGB: return MTLPixelFormatRGBA8Unorm_sRGB; case GN_FORMAT_RGBA8_SRGB: return MTLPixelFormatRGBA8Unorm_sRGB;
case GN_FORMAT_D24S8_UINT: return MTLPixelFormatDepth24Unorm_Stencil8; case GN_FORMAT_D24S8_UINT: return MTLPixelFormatDepth24Unorm_Stencil8;
case GN_FORMAT_D32S8_UINT: return MTLPixelFormatDepth32Float_Stencil8; case GN_FORMAT_D32S8_UINT: return MTLPixelFormatDepth32Float_Stencil8;

View File

@@ -13,4 +13,4 @@ void metalTextureData(gnTextureHandle texture, void* pixelData);
void metalDestroyTexture(gnTexture texture); void metalDestroyTexture(gnTexture texture);
NSUInteger mtlSampleCount(gnMultisampleCountFlags flags); NSUInteger mtlSampleCount(gnSampleCountFlags flags);

View File

@@ -2,7 +2,7 @@
#include "surface/metal_surface.h" #include "surface/metal_surface.h"
#include "devices/metal_output_devices.h" #include "devices/metal_output_devices.h"
NSUInteger mtlSampleCount(gnMultisampleCountFlags flags) { NSUInteger mtlSampleCount(gnSampleCountFlags flags) {
if ((flags & GN_SAMPLE_BIT_64) == GN_SAMPLE_BIT_64) { return 64; } if ((flags & GN_SAMPLE_BIT_64) == GN_SAMPLE_BIT_64) { return 64; }
if ((flags & GN_SAMPLE_BIT_32) == GN_SAMPLE_BIT_32) { return 32; } if ((flags & GN_SAMPLE_BIT_32) == GN_SAMPLE_BIT_32) { return 32; }
if ((flags & GN_SAMPLE_BIT_16) == GN_SAMPLE_BIT_16) { return 16; } if ((flags & GN_SAMPLE_BIT_16) == GN_SAMPLE_BIT_16) { return 16; }

View File

@@ -1,5 +1,6 @@
#include "opengl_loader.h" #include "opengl_loader.h"
#include "commands/buffers/opengl_command_buffer.h" #include "commands/buffers/opengl_command_buffer.h"
#include "commands/commands/opengl_commands.h"
gnCommandFunctions loadOpenGLCommandFunctions() { gnCommandFunctions loadOpenGLCommandFunctions() {
return (gnCommandFunctions) { return (gnCommandFunctions) {
@@ -10,17 +11,17 @@ gnCommandFunctions loadOpenGLCommandFunctions() {
._gnEndCommandBuffer = openglEndCommandBuffer, ._gnEndCommandBuffer = openglEndCommandBuffer,
._gnDestroyCommandBuffer = openglDestroyCommandBuffer, ._gnDestroyCommandBuffer = openglDestroyCommandBuffer,
._gnCommandBeginRenderPass = NULL, ._gnCommandBeginRenderPass = openglBeginRenderPass,
._gnCommandEndRenderPass = NULL, ._gnCommandEndRenderPass = openglEndRenderPass,
._gnCommandBindGraphicsPipeline = NULL, ._gnCommandBindGraphicsPipeline = openglBindGraphicsPipeline,
._gnCommandSetViewport = NULL, ._gnCommandSetViewport = openglSetViewport,
._gnCommandSetScissor = NULL, ._gnCommandSetScissor = openglSetScissor,
._gnCommandBindUniform = NULL, ._gnCommandBindUniform = openglBindUniform,
._gnCommandPushConstant = NULL, ._gnCommandPushConstant = openglPushConstant,
._gnCommandBindBuffer = NULL, ._gnCommandBindBuffer = openglBindBuffer,
._gnCommandDraw = NULL, ._gnCommandDraw = openglDraw,
._gnCommandDrawIndexed = NULL, ._gnCommandDrawIndexed = openglDrawIndexed,
}; };
} }

View File

@@ -8,6 +8,10 @@
#include "commands/pool/opengl_command_pool.h" #include "commands/pool/opengl_command_pool.h"
#include "buffer/opengl_buffer.h" #include "buffer/opengl_buffer.h"
#include "textures/opengl_texture.h" #include "textures/opengl_texture.h"
#include "framebuffer/opengl_framebuffer.h"
#include "graphics_pipeline/opengl_graphics_pipeline.h"
#include "submit/opengl_submit.h"
#include "present/opengl_present.h"
gnDeviceFunctions loadOpenGLDeviceFunctions() { gnDeviceFunctions loadOpenGLDeviceFunctions() {
return (gnDeviceFunctions){ return (gnDeviceFunctions){
@@ -21,11 +25,11 @@ gnDeviceFunctions loadOpenGLDeviceFunctions() {
._gnCreateRenderPassDescriptor = openglCreateRenderPass, ._gnCreateRenderPassDescriptor = openglCreateRenderPass,
._gnDestroyRenderPassDescriptor = openglDestroyRenderPass, ._gnDestroyRenderPassDescriptor = openglDestroyRenderPass,
._gnCreateGraphicsPipeline = NULL, ._gnCreateGraphicsPipeline = openglCreateGraphicsPipeline,
._gnDestroyGraphicsPipeline = NULL, ._gnDestroyGraphicsPipeline = openglDestroyGraphicsPipeline,
._gnCreateFramebuffer = NULL, ._gnCreateFramebuffer = openglCreateFramebuffer,
._gnDestroyFramebuffer = NULL, ._gnDestroyFramebuffer = openglDestroyFramebuffer,
._gnCreateCommandPool = openglCreateCommandPool, ._gnCreateCommandPool = openglCreateCommandPool,
._gnDestroyCommandPool = openglDestroyCommandPool, ._gnDestroyCommandPool = openglDestroyCommandPool,
@@ -49,8 +53,8 @@ gnDeviceFunctions loadOpenGLDeviceFunctions() {
._gnTextureData = openglTextureData, ._gnTextureData = openglTextureData,
._gnDestroyTexture = openglDestroyTexture, ._gnDestroyTexture = openglDestroyTexture,
._gnSubmit = NULL, ._gnSubmit = openglSubmit,
._gnPresent = NULL, ._gnPresent = openglPresent,
._gnWaitForDevice = waitForOpenGLDevice ._gnWaitForDevice = waitForOpenGLDevice
}; };

View File

@@ -1,4 +1,5 @@
#include "opengl_buffer.h" #include "opengl_buffer.h"
#include "string.h"
GLenum gnBufferTypeToGLEnum(gnBufferType type) { GLenum gnBufferTypeToGLEnum(gnBufferType type) {
switch (type) { switch (type) {
@@ -14,17 +15,20 @@ gnReturnCode openglCreateBuffer(gnBufferHandle buffer, gnDevice device, gnBuffer
glCreateBuffers(1, &buffer->buffer->id); glCreateBuffers(1, &buffer->buffer->id);
buffer->buffer->type = gnBufferTypeToGLEnum(info.type); buffer->buffer->type = gnBufferTypeToGLEnum(info.type);
buffer->buffer->usage = (info.usage == GN_DYNAMIC_DRAW) ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW; buffer->buffer->usage = (info.usage == GN_DYNAMIC_DRAW) ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW;
glNamedBufferData(buffer->buffer->id, info.size, NULL, buffer->buffer->usage); glNamedBufferStorage(buffer->buffer->id, info.size, NULL, GL_DYNAMIC_STORAGE_BIT | GL_MAP_READ_BIT | GL_MAP_WRITE_BIT | GL_MAP_COHERENT_BIT | GL_MAP_PERSISTENT_BIT);
return GN_SUCCESS; return GN_SUCCESS;
} }
void openglBufferData(gnBufferHandle buffer, size_t dataSize, void* data) { void openglBufferData(gnBufferHandle buffer, size_t dataSize, void* data) {
glNamedBufferData(buffer->buffer->id, dataSize, data, buffer->buffer->usage); openglBufferSubData(buffer, 0, dataSize, data);
} }
#include "stdio.h"
void openglBufferSubData(gnBufferHandle buffer, size_t offset, size_t dataSize, gnBufferMemory data) { void openglBufferSubData(gnBufferHandle buffer, size_t offset, size_t dataSize, gnBufferMemory data) {
glNamedBufferSubData(buffer->buffer->id, offset, dataSize, data); void* buff = glMapNamedBufferRange(buffer->buffer->id, offset, buffer->info.size, GL_MAP_WRITE_BIT);
memcpy(buff, data, dataSize);
glUnmapNamedBuffer(buffer->buffer->id);
} }
void* openglMapBuffer(gnBufferHandle buffer) { void* openglMapBuffer(gnBufferHandle buffer) {
return glMapNamedBuffer(buffer->buffer->id, GL_READ_WRITE); return glMapNamedBufferRange(buffer->buffer->id, 0, buffer->info.size, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT);
} }
void openglUnmapBuffer(gnBufferHandle buffer) { void openglUnmapBuffer(gnBufferHandle buffer) {
glUnmapNamedBuffer(buffer->buffer->id); glUnmapNamedBuffer(buffer->buffer->id);

View File

@@ -1,6 +1,7 @@
#pragma once #pragma once
#include "core/src/buffers/gryphn_buffer.h" #include "core/src/buffers/gryphn_buffer.h"
#include "glad/glad.h" #include "glad/glad.h"
#include "utils/gryphn_cpp_function.h"
typedef struct gnPlatformBuffer_t { typedef struct gnPlatformBuffer_t {
GLuint id; GLuint id;
@@ -13,3 +14,6 @@ void openglBufferSubData(gnBufferHandle buffer, size_t offset, size_t dataSize,
void* openglMapBuffer(gnBufferHandle buffer); void* openglMapBuffer(gnBufferHandle buffer);
void openglUnmapBuffer(gnBufferHandle buffer); void openglUnmapBuffer(gnBufferHandle buffer);
void openglDestroyBuffer(gnBufferHandle buffer); void openglDestroyBuffer(gnBufferHandle buffer);
GN_CPP_FUNCTION GLenum gnBufferTypeToGLEnum(gnBufferType type);

View File

@@ -8,6 +8,19 @@ gnReturnCode openglCommandPoolAllocateCommandBuffers(gnCommandBufferHandle* comm
if (pool->commandPool->canBeReallocated[c] == GN_TRUE) { if (pool->commandPool->canBeReallocated[c] == GN_TRUE) {
pool->commandPool->canBeReallocated[c] = GN_FALSE; pool->commandPool->canBeReallocated[c] = GN_FALSE;
commandBuffers[i]->commandBuffer = &pool->commandPool->commandBuffers[c]; commandBuffers[i]->commandBuffer = &pool->commandPool->commandBuffers[c];
commandBuffers[i]->commandBuffer->commmandRunner = openglCreateCommandRunner();
commandBuffers[i]->commandBuffer->boundVertexBuffer = GN_NULL_HANDLE;
commandBuffers[i]->commandBuffer->boundIndexBuffer = GN_NULL_HANDLE;
// glGenBuffers(1, &commandBuffers[i]->commandBuffer->vertexBuffer);
// glBindBuffer(GL_ARRAY_BUFFER, commandBuffers[i]->commandBuffer->vertexBuffer);
// glBufferData(GL_ARRAY_BUFFER, sizeof(verts), verts, GL_STATIC_DRAW);
// gl
// glGenBuffers(1, &commandBuffers[i]->commandBuffer->indexBuffer);
wasAbleToAllocate = GN_TRUE; wasAbleToAllocate = GN_TRUE;
break; break;
} }
@@ -21,11 +34,9 @@ gnReturnCode openglCommandPoolAllocateCommandBuffers(gnCommandBufferHandle* comm
return GN_SUCCESS; return GN_SUCCESS;
} }
void openglResetCommandBuffer(gnCommandBuffer commandBuffer) { void openglResetCommandBuffer(gnCommandBuffer commandBuffer) { /* nothing, for now command buffers are implictly reset on begin */ }
// commandBuffer->commandBuffer->
// nothing, for now command buffers are implictly reset on begin
}
gnReturnCode openglBeginCommandBuffer(gnCommandBuffer commandBuffer) { gnReturnCode openglBeginCommandBuffer(gnCommandBuffer commandBuffer) {
openglResetCommandRunner(commandBuffer->commandBuffer->commmandRunner);
return GN_SUCCESS; return GN_SUCCESS;
} }
gnReturnCode openglEndCommandBuffer(gnCommandBuffer commandBuffer) { gnReturnCode openglEndCommandBuffer(gnCommandBuffer commandBuffer) {
@@ -33,4 +44,5 @@ gnReturnCode openglEndCommandBuffer(gnCommandBuffer commandBuffer) {
} }
void openglDestroyCommandBuffer(gnCommandBuffer commandBuffer) { void openglDestroyCommandBuffer(gnCommandBuffer commandBuffer) {
commandBuffer->commandPool->commandPool->canBeReallocated[commandBuffer->commandBuffer->index] = GN_TRUE; commandBuffer->commandPool->commandPool->canBeReallocated[commandBuffer->commandBuffer->index] = GN_TRUE;
openglDestroyCommandRunner(&commandBuffer->commandBuffer->commmandRunner);
} }

View File

@@ -1,8 +1,13 @@
#pragma once #pragma once
#include "glad/glad.h"
#include "core/src/command/command_buffer/gryphn_command_buffer.h" #include "core/src/command/command_buffer/gryphn_command_buffer.h"
#include "commands/commands/opengl_command_runner.h"
typedef struct gnPlatformCommandBuffer_t { typedef struct gnPlatformCommandBuffer_t {
int index; int index;
openglCommandRunner commmandRunner;
gnGraphicsPipeline boundGraphicsPipeline;
gnBuffer boundVertexBuffer, boundIndexBuffer;
} gnPlatformCommandBuffer; } gnPlatformCommandBuffer;
gnReturnCode openglCommandPoolAllocateCommandBuffers(gnCommandBufferHandle* commandBuffers, uint32_t count, gnCommandPoolHandle pool); gnReturnCode openglCommandPoolAllocateCommandBuffers(gnCommandBufferHandle* commandBuffers, uint32_t count, gnCommandPoolHandle pool);

View File

@@ -0,0 +1,23 @@
#include "opengl_command_runner.h"
#include "vector"
typedef struct openglCommandRunner_t {
std::vector<std::function<void()>> commands;
} glCommandRunner;
GN_CPP_FUNCTION openglCommandRunner openglCreateCommandRunner() { return new glCommandRunner(); }
GN_CPP_FUNCTION void openglRunCommandRunner(openglCommandRunner runner) {
for (int i = 0; i < runner->commands.size(); i++)
runner->commands[i]();
}
GN_CPP_FUNCTION void openglResetCommandRunner(openglCommandRunner runner) { runner->commands.clear(); }
GN_CPP_FUNCTION void openglDestroyCommandRunner(openglCommandRunner* runner) {
*runner = NULL;
delete runner;
}
void openglCommandRunnerBindFunction(openglCommandRunner runner, std::function<void()> function) {
runner->commands.push_back(function);
}
// void openglCommandRunnerBindFunction(openglCommandRunner runner, openglFunctionBinding binding) { runner->commands.push_back(binding); }

View File

@@ -0,0 +1,14 @@
#pragma once
#include "utils/gryphn_cpp_function.h"
typedef struct openglCommandRunner_t* openglCommandRunner;
GN_CPP_FUNCTION openglCommandRunner openglCreateCommandRunner();
GN_CPP_FUNCTION void openglResetCommandRunner(openglCommandRunner runner);
GN_CPP_FUNCTION void openglRunCommandRunner(openglCommandRunner runner);
GN_CPP_FUNCTION void openglDestroyCommandRunner(openglCommandRunner* runner);
#ifdef __cplusplus
#include "functional"
#define openglBindFunction(expr) std::function<void()>([=]{ expr; })
void openglCommandRunnerBindFunction(openglCommandRunner runner, std::function<void()> function);
#endif

View File

@@ -0,0 +1,145 @@
#include "glad/glad.h"
#include "opengl_commands.h"
#include "opengl_command_runner.h"
#include "commands/buffers/opengl_command_buffer.h"
#include "framebuffer/opengl_framebuffer.h"
#include <string.h>
#include "buffer/opengl_buffer.h"
#include "graphics_pipeline/opengl_graphics_pipeline.h"
#include "renderpass/opengl_render_pass_descriptor.h"
#include "uniforms/uniform/opengl_uniform.h"
#include "textures/opengl_texture.h"
GN_CPP_FUNCTION void openglBeginRenderPass(gnCommandBuffer buffer, gnRenderPassInfo sPassInfo) {
gnRenderPassInfo passInfo = sPassInfo;
gnClearValue* values = (gnClearValue*)malloc(sizeof(gnClearValue*) * passInfo.clearValueCount);
memcpy(values, passInfo.clearValues, sizeof(gnClearValue*) * passInfo.clearValueCount);
openglCommandRunnerBindFunction(buffer->commandBuffer->commmandRunner, std::function<void()>([passInfo, values]{
glBindFramebuffer(GL_FRAMEBUFFER, passInfo.framebuffer->framebuffer->framebuffers[0]);
if (passInfo.renderPassDescriptor->renderPassDescriptor->subpasses[0].colorAttachments[0].format == GL_SRGB8_ALPHA8) glEnable(GL_FRAMEBUFFER_SRGB);
glClearColor(values[0].r, values[0].g, values[0].b, values[0].a);
glEnable(GL_DEPTH_TEST);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glViewport(passInfo.offset.x, passInfo.offset.y, passInfo.size.x, passInfo.size.y);
free(values);
}));
}
GN_CPP_FUNCTION void openglEndRenderPass(gnCommandBuffer buffer) {
openglCommandRunnerBindFunction(buffer->commandBuffer->commmandRunner, std::function<void()>([]{
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glDisable(GL_FRAMEBUFFER_SRGB);
}));
}
GN_CPP_FUNCTION void openglBindGraphicsPipeline(gnCommandBuffer commandBuffer, gnGraphicsPipeline graphicsPipeline) {
gnGraphicsPipeline pipeline = graphicsPipeline;
gnCommandBuffer buffer = commandBuffer;
openglCommandRunnerBindFunction(buffer->commandBuffer->commmandRunner, std::function<void()>([buffer, pipeline]{
buffer->commandBuffer->boundGraphicsPipeline = pipeline;
glBindVertexArray(buffer->commandBuffer->boundGraphicsPipeline->graphicsPipeline->vertexArrayObject);
if (buffer->commandBuffer->boundVertexBuffer != GN_NULL_HANDLE)
glVertexArrayVertexBuffer(
buffer->commandBuffer->boundGraphicsPipeline->graphicsPipeline->vertexArrayObject, 0,
buffer->commandBuffer->boundVertexBuffer->buffer->id, 0,
buffer->commandBuffer->boundGraphicsPipeline->graphicsPipeline->stride
);
if (buffer->commandBuffer->boundIndexBuffer != GN_NULL_HANDLE)
glVertexArrayElementBuffer(buffer->commandBuffer->boundGraphicsPipeline->graphicsPipeline->vertexArrayObject, buffer->commandBuffer->boundIndexBuffer->buffer->id);
glUseProgram(buffer->commandBuffer->boundGraphicsPipeline->graphicsPipeline->program);
}));
}
GN_CPP_FUNCTION void openglSetViewport(gnCommandBuffer buffer, gnViewport sViewport) {
gnViewport viewport = sViewport;
openglCommandRunnerBindFunction(buffer->commandBuffer->commmandRunner, std::function<void()>([viewport]{
glViewport(viewport.position.x, viewport.position.y, viewport.size.x, viewport.size.y);
glDepthRange(viewport.minDepth, viewport.maxDepth);
}));
}
GN_CPP_FUNCTION void openglSetScissor(gnCommandBuffer buffer, gnScissor sScissor) {
gnScissor scissor = sScissor;
openglCommandRunnerBindFunction(buffer->commandBuffer->commmandRunner, std::function<void()>([scissor]{
glScissor(scissor.position.x, scissor.position.y, scissor.size.x, scissor.size.y);
}));
}
GN_CPP_FUNCTION void openglBindBuffer(gnCommandBufferHandle buffer, gnBufferHandle bufferToBind, gnBufferType type) {
gnBufferType bType = type;
gnCommandBufferHandle bBuffer = buffer;
gnBufferHandle bBufferToBind = bufferToBind;
openglCommandRunnerBindFunction(buffer->commandBuffer->commmandRunner, std::function<void()>([bType, bBuffer, bBufferToBind]{
if (bType == GN_VERTEX_BUFFER) {
bBuffer->commandBuffer->boundVertexBuffer = bBufferToBind;
glVertexArrayVertexBuffer(
bBuffer->commandBuffer->boundGraphicsPipeline->graphicsPipeline->vertexArrayObject, 0,
bBuffer->commandBuffer->boundVertexBuffer->buffer->id, 0,
bBuffer->commandBuffer->boundGraphicsPipeline->graphicsPipeline->stride
);
} else if (bType == GN_INDEX_BUFFER) {
bBuffer->commandBuffer->boundIndexBuffer = bBufferToBind;
glVertexArrayElementBuffer(bBuffer->commandBuffer->boundGraphicsPipeline->graphicsPipeline->vertexArrayObject, bBufferToBind->buffer->id);
}
}));
}
GN_CPP_FUNCTION void openglDraw(gnCommandBuffer buffer, int sVertexCount, int sFirstVertex, int sInstanceCount, int sFirstInstance) {
int vertexCount = sVertexCount, firstVertex = sFirstVertex, instanceCount = sInstanceCount, firstInstance = sFirstInstance;
openglCommandRunnerBindFunction(buffer->commandBuffer->commmandRunner, std::function<void()>([vertexCount, firstVertex, instanceCount, firstInstance]{
glDrawArraysInstancedBaseInstance(GL_TRIANGLES, firstVertex, vertexCount, instanceCount, firstInstance);
}));
}
GN_CPP_FUNCTION void openglDrawIndexed(gnCommandBufferHandle sBuffer, gnIndexType sType, int sIndexCount, int sFirstIndex, int sVertexOffset, int sInstanceCount, int sFirstInstance) {
gnCommandBuffer buffer = sBuffer;
gnIndexType type = sType;
int indexCount = sIndexCount, firstIndex = sFirstIndex, vertexOffset = sVertexOffset, instanceCount = sInstanceCount, firstInstance = sFirstInstance;
openglCommandRunnerBindFunction(buffer->commandBuffer->commmandRunner, std::function<void()>([buffer, type, indexCount, firstIndex, instanceCount, vertexOffset, firstInstance]{
glDrawElementsInstancedBaseVertexBaseInstance(GL_TRIANGLES, indexCount, (type == GN_UINT16) ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, (void*)(sizeof(GLuint) * firstIndex), instanceCount, vertexOffset, firstInstance);
}));
}
GN_CPP_FUNCTION void openglBindUniform(gnCommandBufferHandle sBuffer, gnUniform sUniform, uint32_t sSet, uint32_t dynamicOffsetCount, uint32_t* dynamicOffsets) {
gnCommandBufferHandle buffer = sBuffer;
gnUniform uniform = sUniform;
uint32_t set = sSet;
openglCommandRunnerBindFunction(buffer->commandBuffer->commmandRunner, std::function<void()>([buffer, uniform, set]{
for (int i = 0; i < MAX_OPENGL_BINDINGS; i++) {
if (uniform->uniform->bindings[i].isUpdated != GN_TRUE) continue;
if (uniform->uniform->bindings[i].type == gl_image) {
glActiveTexture(GL_TEXTURE0 + buffer->commandBuffer->boundGraphicsPipeline->graphicsPipeline->setMap[set].bindings[uniform->uniform->bindings[i].image_info.binding]);
glBindTexture(GL_TEXTURE_2D, uniform->uniform->bindings[i].image_info.texture->texture->id);
} else if (uniform->uniform->bindings[i].type == gl_buffer) {
glBindBufferBase(
GL_UNIFORM_BUFFER,
buffer->commandBuffer->boundGraphicsPipeline->graphicsPipeline->setMap[set].bindings[uniform->uniform->bindings[i].buffer_info.binding],
uniform->uniform->bindings[i].buffer_info.buffer->buffer->id
);
glUniformBlockBinding(
buffer->commandBuffer->boundGraphicsPipeline->graphicsPipeline->program,
buffer->commandBuffer->boundGraphicsPipeline->graphicsPipeline->setMap[set].bindings[uniform->uniform->bindings[i].buffer_info.binding],
0
);
} else if (uniform->uniform->bindings[i].type == gl_storage) {
glBindBufferBase(
GL_SHADER_STORAGE_BUFFER,
buffer->commandBuffer->boundGraphicsPipeline->graphicsPipeline->setMap[set].bindings[uniform->uniform->bindings[i].storage_info.binding],
uniform->uniform->bindings[i].storage_info.buffer->buffer->id
);
}
}
}));
}
// #include "stdio.h"
GN_CPP_FUNCTION void openglPushConstant(gnCommandBufferHandle sBuffer, gnPushConstantLayout sLayout, void* sData) {
// gnCommandBufferHandle buffer = sBuffer;
// // gnPushConstantLayout layout = sLayout;
// // void* data = malloc(sizeof(sLayout.size));
// // memcpy(data, sData, sizeof(sLayout.size));
// openglCommandRunnerBindFunction(buffer->commandBuffer->commmandRunner, std::function<void()>([buffer]{
// //TODO: implement OpenGL push constants, its just hard because OpenGL is a bitch and i hate it
// // GLint loc = glGetUniformLocation(buffer->commandBuffer->boundGraphicsPipeline->graphicsPipeline->program, "gnPushConstantBlock");
// // printf("member loc: %i\n", loc);
// // if (loc == -1) return;
// }));
}

View File

@@ -0,0 +1,14 @@
#pragma once
#include "core/src/command/commands/gryphn_command.h"
#include "utils/gryphn_cpp_function.h"
GN_CPP_FUNCTION void openglBeginRenderPass(gnCommandBuffer buffer, gnRenderPassInfo passInfo);
GN_CPP_FUNCTION void openglEndRenderPass(gnCommandBuffer buffer);
GN_CPP_FUNCTION void openglBindGraphicsPipeline(gnCommandBuffer buffer, gnGraphicsPipeline graphicsPipeline);
GN_CPP_FUNCTION void openglSetViewport(gnCommandBuffer buffer, gnViewport viewport);
GN_CPP_FUNCTION void openglSetScissor(gnCommandBuffer buffer, gnScissor scissor);
GN_CPP_FUNCTION void openglBindBuffer(gnCommandBufferHandle buffer, gnBufferHandle bufferToBind, gnBufferType type);
GN_CPP_FUNCTION void openglDraw(gnCommandBuffer buffer, int vertexCount, int firstVertex, int instanceCount, int firstInstance);
GN_CPP_FUNCTION void openglDrawIndexed(gnCommandBufferHandle buffer, gnIndexType type, int indexCount, int firstIndex, int vertexOffset, int instanceCount, int firstInstance);
GN_CPP_FUNCTION void openglBindUniform(gnCommandBufferHandle buffer, gnUniform uniform, uint32_t set, uint32_t dynamicOffsetCount, uint32_t* dynamicOffsets);
GN_CPP_FUNCTION void openglPushConstant(gnCommandBufferHandle buffer, gnPushConstantLayout layout, void* data);

View File

@@ -0,0 +1,23 @@
const char * vertex_shader_source =
"#version 450 core\n"
"\n"
"layout(location = 0) in vec2 inPosition;\n"
"layout(location = 1) in vec2 inTexcoord;\n"
"\n"
"out vec2 texcoord;\n"
"\n"
"void main() {\n"
" gl_Position = vec4(inPosition, 0.0, 1.0);\n"
" texcoord = inTexcoord;\n"
"}\n" ;
const char * fragment_shader_source =
"#version 450 core\n"
"\n"
"out vec4 FragColor;\n"
"layout(binding = 0) uniform sampler2D tex;\n"
"in vec2 texcoord;\n"
"\n"
"void main() {\n"
" FragColor = texture(tex, texcoord);\n"
" //FragColor = vec4(texcoord, 0.0, 1.0);\n"
"}\n" ;

View File

@@ -1,5 +1,72 @@
#include "glad/glad.h"
#include "opengl_output_device.h" #include "opengl_output_device.h"
#include "glsl_shader.glsl"
#include "stdlib.h"
#include "core/src/instance/gryphn_instance.h"
gnReturnCode createOpenGLOutputDevice(gnInstanceHandle instance, gnOutputDeviceHandle device, gnOutputDeviceInfo deviceInfo) { return GN_SUCCESS; } gnReturnCode createOpenGLOutputDevice(gnInstanceHandle instance, gnOutputDeviceHandle device, gnOutputDeviceInfo deviceInfo) {
int success;
char infoLog[512];
device->outputDevice = malloc(sizeof(gnPlatformOutputDevice));
float vertices[] = {
-1.0f, 1.0f, 0.0f, 1.0f,
-1.0f, -1.0f, 0.0f, 0.0f,
1.0f, -1.0f, 1.0f, 0.0f,
-1.0f, 1.0f, 0.0f, 1.0f,
1.0f, 1.0f, 1.0f, 1.0f,
1.0f, -1.0f, 1.0f, 0.0f,
};
glCreateBuffers(1, &device->outputDevice->buffer);
glBindBuffer(GL_ARRAY_BUFFER, device->outputDevice->buffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 4, (void*)0);
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 4, (void*)(sizeof(float) * 2));
glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, 0);
unsigned int vertexShader;
vertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShader, 1, &vertex_shader_source, NULL);
glCompileShader(vertexShader);
glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);
if(!success) {
glGetShaderInfoLog(vertexShader, 512, NULL, infoLog);
gnDebuggerSetErrorMessage(instance->debugger, (gnMessageData){
.message = gnCreateString(infoLog)
});
}
unsigned int fragmentShader;
fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader, 1, &fragment_shader_source, NULL);
glCompileShader(fragmentShader);
glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success);
if(!success) {
glGetShaderInfoLog(vertexShader, 512, NULL, infoLog);
gnDebuggerSetErrorMessage(instance->debugger, (gnMessageData){
.message = gnCreateString(infoLog)
});
}
device->outputDevice->shaderProgram = glCreateProgram();
glAttachShader(device->outputDevice->shaderProgram, vertexShader);
glAttachShader(device->outputDevice->shaderProgram, fragmentShader);
glLinkProgram(device->outputDevice->shaderProgram);
glGetProgramiv(device->outputDevice->shaderProgram, GL_LINK_STATUS, &success);
if(!success) {
glGetProgramInfoLog(device->outputDevice->shaderProgram, 512, NULL, infoLog);
gnDebuggerSetErrorMessage(instance->debugger, (gnMessageData){
.message = gnCreateString(infoLog)
});
}
return GN_SUCCESS;
}
void waitForOpenGLDevice(const gnOutputDeviceHandle device) {} void waitForOpenGLDevice(const gnOutputDeviceHandle device) {}
void destroyOpenGLOutputDevice(gnOutputDeviceHandle device) {} void destroyOpenGLOutputDevice(gnOutputDeviceHandle device) {}

View File

@@ -1,7 +1,9 @@
#pragma once #pragma once
#include <output_device/gryphn_output_device.h> #include <output_device/gryphn_output_device.h>
typedef struct gnPlatformOutputDevice_t {} gnPlatformOutputDevice; typedef struct gnPlatformOutputDevice_t {
unsigned int buffer, shaderProgram;
} gnPlatformOutputDevice;
gnReturnCode createOpenGLOutputDevice(gnInstanceHandle instance, gnOutputDeviceHandle device, gnOutputDeviceInfo deviceInfo); gnReturnCode createOpenGLOutputDevice(gnInstanceHandle instance, gnOutputDeviceHandle device, gnOutputDeviceInfo deviceInfo);
void waitForOpenGLDevice(const gnOutputDeviceHandle device); void waitForOpenGLDevice(const gnOutputDeviceHandle device);

View File

@@ -12,7 +12,7 @@ gnPhysicalDevice* getOpenGLDevice(gnInstanceHandle instance, uint32_t* deviceCou
.maxColorSamples = GN_SAMPLE_BIT_1, .maxColorSamples = GN_SAMPLE_BIT_1,
.maxDepthSamples = GN_SAMPLE_BIT_1, .maxDepthSamples = GN_SAMPLE_BIT_1,
.maxMemoryAllocations = 0x40000000, .maxMemoryAllocations = 0x40000000,
.maxPushConstantSize = 256 .maxPushConstantSize = 0
}, },
.properties = { .properties = {
.deviceType = GN_DEDICATED_DEVICE, .deviceType = GN_DEDICATED_DEVICE,

View File

@@ -0,0 +1,34 @@
#include "opengl_framebuffer.h"
#include "stdlib.h"
#include "renderpass/opengl_render_pass_descriptor.h"
#include "textures/opengl_texture.h"
#include "stdio.h"
#include "core/src/output_device/gryphn_output_device.h"
#include "core/src/instance/gryphn_instance.h"
gnReturnCode openglCreateFramebuffer(gnFramebuffer framebuffer, gnDevice device, gnFramebufferInfo info) {
framebuffer->framebuffer = malloc(sizeof(struct gnPlatformFramebuffer_t));
framebuffer->framebuffer->framebufferCount = info.renderPassDescriptor->renderPassDescriptor->subpassCount;
framebuffer->framebuffer->framebuffers = malloc(sizeof(GLuint) * info.renderPassDescriptor->renderPassDescriptor->subpassCount);
for (int i = 0; i < info.renderPassDescriptor->renderPassDescriptor->subpassCount; i++) {
glCreateFramebuffers(1, &framebuffer->framebuffer->framebuffers[i]);
for (int c = 0; c < info.renderPassDescriptor->renderPassDescriptor->subpasses[i].colorAttachmentCount; c++)
glNamedFramebufferTexture(framebuffer->framebuffer->framebuffers[i], GL_COLOR_ATTACHMENT0 + c, info.attachments[info.renderPassDescriptor->renderPassDescriptor->subpasses[i].colorAttachments[c].attachmentIndex]->texture->id, 0);
if (info.renderPassDescriptor->renderPassDescriptor->subpasses[i].depthAttachment.index >= 0)
glNamedFramebufferTexture(framebuffer->framebuffer->framebuffers[i], GL_DEPTH_STENCIL_ATTACHMENT, info.attachments[info.renderPassDescriptor->renderPassDescriptor->subpasses[i].depthAttachment.index]->texture->id, 0);
if (glCheckNamedFramebufferStatus(framebuffer->framebuffer->framebuffers[i], GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
char string[500];
snprintf(string, 500, "Failed to create OpenGL framebuffer: 0x%x\n", glCheckNamedFramebufferStatus(framebuffer->framebuffer->framebuffers[i], GL_FRAMEBUFFER));
gnDebuggerSetErrorMessage(framebuffer->device->instance->debugger, (gnMessageData){
.message = gnCreateString(string)
});
return GN_FAILED_CREATE_OBJECT;
}
}
return GN_SUCCESS;
}
void openglDestroyFramebuffer(gnFramebuffer framebuffer) {
for (int i = 0; i < framebuffer->framebuffer->framebufferCount; i++)
glDeleteFramebuffers(1, &framebuffer->framebuffer->framebuffers[i]);
free(framebuffer->framebuffer);
}

View File

@@ -0,0 +1,11 @@
#pragma once
#include "glad/glad.h"
#include "core/src/framebuffer/gryphn_framebuffer.h"
typedef struct gnPlatformFramebuffer_t {
uint32_t framebufferCount;
GLuint* framebuffers;
} gnPlatformFramebuffer_t;
gnReturnCode openglCreateFramebuffer(gnFramebuffer framebuffer, gnDevice device, gnFramebufferInfo info);
void openglDestroyFramebuffer(gnFramebuffer framebuffer);

View File

@@ -0,0 +1,80 @@
#include "opengl_graphics_pipeline.h"
#include "core/src/instance/gryphn_instance.h"
#include "shaders/opengl_shader_module.h"
#include "stdio.h"
gnReturnCode openglCreateGraphicsPipeline(gnGraphicsPipeline graphicsPipeline, gnOutputDevice device, gnGraphicsPipelineInfo info) {
graphicsPipeline->graphicsPipeline = malloc(sizeof(gnPlatformGraphicsPipeline));
GLuint* ids = malloc(sizeof(GLuint) * info.shaderModuleCount);
for (int i = 0; i < info.shaderModuleCount; i++) {
glShader shader = glCompilerCompilerShader(info.shaderModules[i]->shaderModule->compiler, &info.uniformLayout);
if (i == 0)
for (int set = 0; set < MAX_OPENGL_SETS; set++)
for (int binding = 0; binding < MAX_OPENGL_BINDINGS; binding++)
graphicsPipeline->graphicsPipeline->setMap[set].bindings[binding] = shader.sets[set].bindings[binding];
ids[i] = glCreateShader(gnShaderTypeToGLEnum(info.shaderModules[i]->info.stage));
const char* source = shader.source;
printf("Shader Source %s\n", source);
glShaderSource(ids[i], 1, &source, NULL);
glCompileShader(ids[i]);
GLint returnCode;
glGetShaderiv(ids[i], GL_COMPILE_STATUS, &returnCode);
if(!returnCode) {
char infoLog[512];
glGetShaderInfoLog(ids[i], 512, NULL, infoLog);
gnDebuggerSetErrorMessage(device->instance->debugger, (gnMessageData){
.message = gnCreateString(infoLog)
});
}
}
graphicsPipeline->graphicsPipeline->program = glCreateProgram();
for (int i = 0; i < info.shaderModuleCount; i++)
glAttachShader(graphicsPipeline->graphicsPipeline->program, ids[i]);
glLinkProgram(graphicsPipeline->graphicsPipeline->program);
GLint linked;
glGetProgramiv(graphicsPipeline->graphicsPipeline->program, GL_LINK_STATUS, &linked);
if (!linked) {
GLchar infoLog[512];
glGetProgramInfoLog(graphicsPipeline->graphicsPipeline->program, 512, NULL, infoLog);
gnDebuggerSetErrorMessage(device->instance->debugger, (gnMessageData){
.message = gnCreateString(infoLog)
});
} else {
gnDebuggerSetVerboseMessage(&device->instance->debugger, (gnMessageData){
.message = gnCreateString("Successfully linked program")
});
}
for (int i = 0; i < info.shaderModuleCount; i++)
glDeleteShader(ids[i]);
glCreateVertexArrays(1, &graphicsPipeline->graphicsPipeline->vertexArrayObject);
glVertexArrayAttribFormat(graphicsPipeline->graphicsPipeline->vertexArrayObject, 0, 3, GL_FLOAT, GL_FALSE, 0);
glVertexArrayAttribBinding(graphicsPipeline->graphicsPipeline->vertexArrayObject, 0, 0);
// Attribute 1: texcoord (2 floats)
glVertexArrayAttribFormat(graphicsPipeline->graphicsPipeline->vertexArrayObject, 1, 2, GL_FLOAT, GL_FALSE, sizeof(float)*3);
glVertexArrayAttribBinding(graphicsPipeline->graphicsPipeline->vertexArrayObject, 1, 0);
// Attribute 2: color (3 floats)
glVertexArrayAttribFormat(graphicsPipeline->graphicsPipeline->vertexArrayObject, 2, 3, GL_FLOAT, GL_FALSE, sizeof(float)*5);
glVertexArrayAttribBinding(graphicsPipeline->graphicsPipeline->vertexArrayObject, 2, 0);
graphicsPipeline->graphicsPipeline->stride = (sizeof(float) * 8);
// Enable them
glEnableVertexArrayAttrib(graphicsPipeline->graphicsPipeline->vertexArrayObject, 0);
glEnableVertexArrayAttrib(graphicsPipeline->graphicsPipeline->vertexArrayObject, 1);
glEnableVertexArrayAttrib(graphicsPipeline->graphicsPipeline->vertexArrayObject, 2);
return GN_SUCCESS;
}
void openglDestroyGraphicsPipeline(gnGraphicsPipeline graphicsPipeline) {
glDeleteProgram(graphicsPipeline->graphicsPipeline->program);
free(graphicsPipeline->graphicsPipeline);
}

View File

@@ -0,0 +1,16 @@
#pragma once
#include "glad/glad.h"
#include "core/src/pipelines/graphics_pipeline/gryphn_graphics_pipeline.h"
#include "shaders/opengl_shader_compiler.h"
typedef struct gnPlatformGraphicsPipeline_t {
glSet setMap[MAX_OPENGL_SETS];
GLuint program;
GLuint vertexArrayObject;
GLsizei stride;
} gnPlatformGraphicsPipeline;
gnReturnCode openglCreateGraphicsPipeline(gnGraphicsPipeline graphicsPipeline, gnOutputDevice device, gnGraphicsPipelineInfo info);
void openglDestroyGraphicsPipeline(gnGraphicsPipeline graphicsPipeline);

View File

@@ -0,0 +1,36 @@
#include "opengl_present.h"
#include "presentation_queue/opengl_presentation_queue.h"
#include "device/opengl_output_device.h"
#include "surface/opengl_surface.h"
gnReturnCode openglPresent(gnOutputDeviceHandle device, gnPresentInfo info) {
for (uint32_t i =0 ; i < info.presentationQueueCount; i++) {
uint32_tArrayListAdd(info.presentationQueues[i]->presentationQueue->avaliableTextures, info.imageIndices[i]);
glBindVertexArray(0);
glDisable(GL_DEPTH_TEST);
if (info.presentationQueues[i]->presentationQueue->format == GL_SRGB8_ALPHA8) glEnable(GL_FRAMEBUFFER_SRGB);
glUseProgram(device->outputDevice->shaderProgram);
glBindBuffer(GL_ARRAY_BUFFER, device->outputDevice->buffer);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, GLuintArrayListAt(info.presentationQueues[i]->presentationQueue->textures, info.imageIndices[i]));
glDrawArrays(GL_TRIANGLES, 0, 6);
glUseProgram(0);
glBindTexture(GL_TEXTURE_2D, 0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
swapBuffers(info.presentationQueues[i]->info.surface);
glDisable(GL_FRAMEBUFFER_SRGB);
}
// for (uint32_t i = 0; i < info.presentationQueueCount; i++) {
// if (info.presentationQueues[i]->info.imageSize.x != info.presentationQueues[i]->info.surface->windowSurface->layer.drawableSize.width ||
// info.presentationQueues[i]->info.imageSize.y != info.presentationQueues[i]->info.surface->windowSurface->layer.drawableSize.height) {
// return GN_SUBOPTIMAL_PRESENTATION_QUEUE;
// }
// }
return GN_SUCCESS;
}

View File

@@ -0,0 +1,4 @@
#pragma once
#include "core/src/present/gryphn_present.h"
gnReturnCode openglPresent(gnOutputDeviceHandle device, gnPresentInfo info);

View File

@@ -9,6 +9,7 @@ gnReturnCode createOpenGLPresentationQueue(gnPresentationQueueHandle presentatio
presentationQueue->images = malloc(sizeof(gnTexture) * presentationInfo.minImageCount); presentationQueue->images = malloc(sizeof(gnTexture) * presentationInfo.minImageCount);
presentationQueue->presentationQueue->textures = GLuintArrayListCreate(); presentationQueue->presentationQueue->textures = GLuintArrayListCreate();
presentationQueue->presentationQueue->avaliableTextures = uint32_tArrayListCreate(); presentationQueue->presentationQueue->avaliableTextures = uint32_tArrayListCreate();
presentationQueue->presentationQueue->format = glGryphnFormatToOpenGLInternalFormat(presentationInfo.format.format);
for (int i = 0; i < presentationInfo.minImageCount; i++) { for (int i = 0; i < presentationInfo.minImageCount; i++) {
presentationQueue->images[i] = malloc(sizeof(struct gnTexture_t)); presentationQueue->images[i] = malloc(sizeof(struct gnTexture_t));
presentationQueue->images[i]->texture = malloc(sizeof(gnPlatformTexture)); presentationQueue->images[i]->texture = malloc(sizeof(gnPlatformTexture));

View File

@@ -7,6 +7,7 @@ GN_ARRAY_LIST_HEADER(GLuint);
typedef struct gnPlatformPresentationQueue_t { typedef struct gnPlatformPresentationQueue_t {
GLuintArrayList textures; GLuintArrayList textures;
uint32_tArrayList avaliableTextures; uint32_tArrayList avaliableTextures;
GLenum format;
} gnPlatformPresentationQueue_t; } gnPlatformPresentationQueue_t;
gnReturnCode createOpenGLPresentationQueue(gnPresentationQueueHandle presentationQueue, gnOutputDeviceHandle device, gnPresentationQueueInfo presentationInfo); gnReturnCode createOpenGLPresentationQueue(gnPresentationQueueHandle presentationQueue, gnOutputDeviceHandle device, gnPresentationQueueInfo presentationInfo);

View File

@@ -26,7 +26,7 @@ gnReturnCode openglCreateRenderPass(gnRenderPassDescriptor renderPass, gnDevice
.storeOperation = info.attachmentInfos[attachmentIndex].storeOperation, .storeOperation = info.attachmentInfos[attachmentIndex].storeOperation,
.attachmentIndex = attachmentIndex, .attachmentIndex = attachmentIndex,
.resolveAttachmentIndex = resolveAttachmentIndex, .resolveAttachmentIndex = resolveAttachmentIndex,
.format = glGryphnFormatToOpenGLFormat(info.attachmentInfos[attachmentIndex].format) .format = glGryphnFormatToOpenGLInternalFormat(info.attachmentInfos[attachmentIndex].format)
}; };
} }
@@ -34,7 +34,7 @@ gnReturnCode openglCreateRenderPass(gnRenderPassDescriptor renderPass, gnDevice
uint32_t depthAttachmentIndex = info.subpassInfos[i].depthAttachment->index; uint32_t depthAttachmentIndex = info.subpassInfos[i].depthAttachment->index;
renderPass->renderPassDescriptor->subpasses[i].depthAttachment = (gnDepthAttachment){ renderPass->renderPassDescriptor->subpasses[i].depthAttachment = (gnDepthAttachment){
.index = depthAttachmentIndex, .index = depthAttachmentIndex,
.format = glGryphnFormatToOpenGLFormat(info.attachmentInfos[depthAttachmentIndex].format), .format = glGryphnFormatToOpenGLInternalFormat(info.attachmentInfos[depthAttachmentIndex].format),
.loadOperation = info.attachmentInfos[depthAttachmentIndex].loadOperation, .loadOperation = info.attachmentInfos[depthAttachmentIndex].loadOperation,
.storeOperation = info.attachmentInfos[depthAttachmentIndex].storeOperation, .storeOperation = info.attachmentInfos[depthAttachmentIndex].storeOperation,
}; };

View File

@@ -8,7 +8,7 @@ typedef struct glColorAttachment {
gnLoadOperation loadOperation; gnLoadOperation loadOperation;
gnStoreOperation storeOperation; gnStoreOperation storeOperation;
GLint format; GLenum format;
uint32_t attachmentIndex; uint32_t attachmentIndex;
int resolveAttachmentIndex; // -1 = no attachment int resolveAttachmentIndex; // -1 = no attachment
} glColorAttachment; } glColorAttachment;

View File

@@ -1,20 +1,16 @@
#include "opengl_shader_compiler.h" #include "opengl_shader_compiler.h"
#include "spirv_glsl.hpp" #include "spirv_glsl.hpp"
typedef struct glCompiler_t { typedef struct glCompiler_t {
spirv_cross::CompilerGLSL* glsl; spirv_cross::CompilerGLSL* glsl;
} glInternalCompiler; } glInternalCompiler;
void handle_resources(spirv_cross::CompilerGLSL& compiler, spirv_cross::SmallVector<spirv_cross::Resource>& resources, int* currentBinding, glSet* setMap) { void handle_resources(spirv_cross::CompilerGLSL& compiler, spirv_cross::SmallVector<spirv_cross::Resource>& resources, glSet* setMap) {
for (size_t i = 0; i < resources.size(); i++) { for (size_t i = 0; i < resources.size(); i++) {
uint32_t uint32_t
set = compiler.get_decoration(resources[i].id, spv::DecorationDescriptorSet), set = compiler.get_decoration(resources[i].id, spv::DecorationDescriptorSet),
binding = compiler.get_decoration(resources[i].id, spv::DecorationBinding); binding = compiler.get_decoration(resources[i].id, spv::DecorationBinding);
setMap[set].bindings[binding] = *currentBinding;
compiler.unset_decoration(resources[i].id, spv::DecorationBinding); compiler.unset_decoration(resources[i].id, spv::DecorationBinding);
compiler.set_decoration(resources[i].id, spv::DecorationBinding, *currentBinding); compiler.set_decoration(resources[i].id, spv::DecorationBinding, setMap[set].bindings[binding]);
*currentBinding = (*currentBinding) + 1;
} }
} }
@@ -25,16 +21,44 @@ GN_CPP_FUNCTION glCompiler glCreateCompiler(glCompilerInfo* info) {
// compiler->glsl->set_common_options(options); // compiler->glsl->set_common_options(options);
return compiler; return compiler;
} }
GN_CPP_FUNCTION glShader glCompilerCompilerShader(glCompiler compiler) { GN_CPP_FUNCTION glShader glCompilerCompilerShader(glCompiler compiler, gnUniformLayout* layout) {
int current_binding = 0;
glShader shader = {}; glShader shader = {};
auto arg_buffers = compiler->glsl->get_shader_resources(); uint32_t currentBinding = 0;
handle_resources(*compiler->glsl, arg_buffers.uniform_buffers, &current_binding, shader.sets); for (uint32_t i = 0; i < layout->setCount; i++) {
handle_resources(*compiler->glsl, arg_buffers.storage_buffers, &current_binding, shader.sets); for (size_t c = 0; c < layout->sets[i].uniformBindingCount; c++) {
handle_resources(*compiler->glsl, arg_buffers.sampled_images, &current_binding, shader.sets); gnUniformBinding gryphnBinding = layout->sets[i].uniformBindings[c];
shader.sets[i].bindings[c] = currentBinding;
currentBinding++;
}
}
shader.sets[0].bindings[3] = 69; auto arg_buffers = compiler->glsl->get_shader_resources();
handle_resources(*compiler->glsl, arg_buffers.uniform_buffers, shader.sets);
handle_resources(*compiler->glsl, arg_buffers.storage_buffers, shader.sets);
handle_resources(*compiler->glsl, arg_buffers.sampled_images, shader.sets);
// for (auto &pc : arg_buffers.push_constant_buffers) {
// compiler->glsl->set_name(pc.id, "gnPushConstantBlock");
// auto type = compiler->glsl->get_type(pc.type_id);
// // printf("members: %lu\n", type.member_types.size());
// for (uint32_t i = 0; i < type.member_types.size(); ++i) {
// // // std::string name = compiler->glsl->get_member_name(pc.type_id, i);
// // compiler.set_member_name(push_constant_type_id, 0, "myMat4");
// // compiler.set_member_name(push_constant_type_id, 1, "myVec3");
// // compiler.set_member_name(push_constant_type_id, 2, "myInt");
// auto member_type = compiler->glsl->get_type(type.member_types[i]);
// // // Example: check if it's a mat4, vec3, or int
// // if (member_type.columns == 4 && member_type.vecsize == 4)
// // printf("member %s: mat4\n", name.c_str());
// // else if (member_type.vecsize == 3 && member_type.columns == 1)
// // printf("member %s: vec3\n", name.c_str());
// // else if (member_type.basetype == spirv_cross::SPIRType::Int)
// // printf("member %s: int\n", name.c_str());
// }
// }
std::string output = compiler->glsl->compile(); std::string output = compiler->glsl->compile();
shader.source = (char*)malloc(sizeof(char*) * (output.size() + 1)); shader.source = (char*)malloc(sizeof(char*) * (output.size() + 1));

View File

@@ -2,6 +2,7 @@
#include "stdint.h" #include "stdint.h"
#include "glad/glad.h" #include "glad/glad.h"
#include "utils/gryphn_cpp_function.h" #include "utils/gryphn_cpp_function.h"
#include "core/src/uniforms/gryphn_uniform_layout.h"
#define MAX_OPENGL_SETS 16 #define MAX_OPENGL_SETS 16
#define MAX_OPENGL_BINDINGS 32 #define MAX_OPENGL_BINDINGS 32
@@ -28,5 +29,5 @@ typedef struct glShader {
typedef struct glCompiler_t* glCompiler; typedef struct glCompiler_t* glCompiler;
GN_CPP_FUNCTION glCompiler glCreateCompiler(glCompilerInfo* info); GN_CPP_FUNCTION glCompiler glCreateCompiler(glCompilerInfo* info);
GN_CPP_FUNCTION glShader glCompilerCompilerShader(glCompiler compiler); GN_CPP_FUNCTION glShader glCompilerCompilerShader(glCompiler compiler, gnUniformLayout* layout);
GN_CPP_FUNCTION void glDestroyCompiler(glCompiler compiler); GN_CPP_FUNCTION void glDestroyCompiler(glCompiler compiler);

View File

@@ -1,7 +1,5 @@
#include "opengl_shader_module.h" #include "opengl_shader_module.h"
#include "opengl_shader_compiler.h" #include "opengl_shader_compiler.h"
#include "output_device/gryphn_output_device.h"
#include "instance/gryphn_instance.h"
#include "stdlib.h" #include "stdlib.h"
GLenum gnShaderTypeToGLEnum(gnShaderModuleStage stage) { GLenum gnShaderTypeToGLEnum(gnShaderModuleStage stage) {
@@ -19,28 +17,10 @@ gnReturnCode openglCreateShaderModule(gnShaderModule module, gnDevice device, gn
.wordCount = shaderModuleInfo.size / 4, .wordCount = shaderModuleInfo.size / 4,
.entryPoint = gnToCString(shaderModuleInfo.entryPoint), .entryPoint = gnToCString(shaderModuleInfo.entryPoint),
}; };
glCompiler compiler = glCreateCompiler(&info); module->shaderModule->compiler = glCreateCompiler(&info);
module->shaderModule->shader = glCompilerCompilerShader(compiler);
glDestroyCompiler(compiler);
module->shaderModule->id = glCreateShader(gnShaderTypeToGLEnum(shaderModuleInfo.stage));
const char* source = module->shaderModule->shader.source;
glShaderSource(module->shaderModule->id, 1, &source, NULL);
glCompileShader(module->shaderModule->id);
GLint returnCode;
glGetShaderiv(module->shaderModule->id, GL_COMPILE_STATUS, &returnCode);
if(!returnCode) {
char infoLog[512];
glGetShaderInfoLog(module->shaderModule->id, 512, NULL, infoLog);
gnDebuggerSetErrorMessage(device->instance->debugger, (gnMessageData){
.message = gnCreateString(infoLog)
});
}
return GN_SUCCESS; return GN_SUCCESS;
} }
void openglDestroyShaderModule(gnShaderModule module) { void openglDestroyShaderModule(gnShaderModule module) {
glDeleteShader(module->shaderModule->id); glDestroyCompiler(module->shaderModule->compiler);
free(module->shaderModule); free(module->shaderModule);
} }

View File

@@ -3,9 +3,10 @@
#include "opengl_shader_compiler.h" #include "opengl_shader_compiler.h"
typedef struct gnPlatformShaderModule_t { typedef struct gnPlatformShaderModule_t {
glShader shader; glCompiler compiler;
GLuint id;
} gnPlatformShaderModule; } gnPlatformShaderModule;
GLenum gnShaderTypeToGLEnum(gnShaderModuleStage stage);
gnReturnCode openglCreateShaderModule(gnShaderModule module, gnDevice device, gnShaderModuleInfo shaderModuleInfo); gnReturnCode openglCreateShaderModule(gnShaderModule module, gnDevice device, gnShaderModuleInfo shaderModuleInfo);
void openglDestroyShaderModule(gnShaderModule module); void openglDestroyShaderModule(gnShaderModule module);

View File

@@ -0,0 +1,11 @@
#include "core/src/submit/gryphn_submit.h"
#include "commands/buffers/opengl_command_buffer.h"
gnReturnCode openglSubmit(gnOutputDevice device, gnSubmitInfo info) {
if (device == GN_NULL_HANDLE) return GN_INVALID_HANDLE;
for (uint32_t i = 0; i < info.commandBufferCount; i++)
openglRunCommandRunner(info.commandBuffers[i]->commandBuffer->commmandRunner);
return GN_SUCCESS;
}

View File

@@ -0,0 +1,3 @@
#pragma once
#include "core/src/submit/gryphn_submit.h"
gnReturnCode openglSubmit(gnOutputDevice device, gnSubmitInfo info);

View File

@@ -89,6 +89,10 @@ gnUInt2 getWindowSize(gnPlatformWindowSurface* surface) {
return (gnUInt2){ attr.width, attr.height }; return (gnUInt2){ attr.width, attr.height };
} }
void swapBuffers(gnWindowSurface surface) {
glXSwapBuffers(surface->windowSurface->display, surface->windowSurface->window);
}
#endif #endif
#ifdef GN_WINFDOW_WAYLAND #ifdef GN_WINFDOW_WAYLAND
@@ -105,11 +109,11 @@ gnSurfaceDetails genOpenGLSurfaceDetails(
surfaceDetails.formatCount = 1; surfaceDetails.formatCount = 1;
surfaceDetails.formats = malloc(sizeof(gnSurfaceFormat) * 2); surfaceDetails.formats = malloc(sizeof(gnSurfaceFormat) * 2);
surfaceDetails.formats[0] = (gnSurfaceFormat){ surfaceDetails.formats[0] = (gnSurfaceFormat){
.format = GN_FORMAT_RGBA8, .format = GN_FORMAT_RGBA8_SRGB,
.colorSpace = GN_COLOR_SPACE_SRGB_NONLINEAR .colorSpace = GN_COLOR_SPACE_SRGB_NONLINEAR
}; };
surfaceDetails.formats[1] = (gnSurfaceFormat){ surfaceDetails.formats[1] = (gnSurfaceFormat){
.format = GN_FORMAT_RGBA8_SRGB, .format = GN_FORMAT_RGBA8,
.colorSpace = GN_COLOR_SPACE_SRGB_NONLINEAR .colorSpace = GN_COLOR_SPACE_SRGB_NONLINEAR
}; };

View File

@@ -15,6 +15,7 @@ gnReturnCode createGLXContext(gnWindowSurfaceHandle windowSurface, gnInstanceHan
#endif #endif
gnUInt2 getWindowSize(gnPlatformWindowSurface* surface); gnUInt2 getWindowSize(gnPlatformWindowSurface* surface);
void swapBuffers(gnWindowSurface surface);
gnSurfaceDetails genOpenGLSurfaceDetails(gnWindowSurfaceHandle windowSurface, gnPhysicalDevice device); gnSurfaceDetails genOpenGLSurfaceDetails(gnWindowSurfaceHandle windowSurface, gnPhysicalDevice device);
void destroyOpenGLSurface(gnWindowSurface surface); void destroyOpenGLSurface(gnWindowSurface surface);

View File

@@ -18,7 +18,9 @@ gnReturnCode openglCreateTexture(gnTexture texture, gnDevice device, const gnTex
); );
return GN_SUCCESS; return GN_SUCCESS;
} }
#include "stdio.h"
void openglTextureData(gnTextureHandle texture, void* pixelData) { void openglTextureData(gnTextureHandle texture, void* pixelData) {
printf("OpenGL id: %u\n", texture->texture->id);
glTextureSubImage2D( glTextureSubImage2D(
texture->texture->id, texture->texture->id,
0, 0,

View File

@@ -9,6 +9,7 @@ gnUniform* openglAllocateUniforms(gnUniformPool pool, const gnUniformAllocationI
for (int i = 0; i < allocInfo.setCount; i++) { for (int i = 0; i < allocInfo.setCount; i++) {
uniforms[i] = malloc(sizeof(struct gnUniform_t)); uniforms[i] = malloc(sizeof(struct gnUniform_t));
uniforms[i]->uniform = malloc(sizeof(struct gnPlatformUniform_t)); uniforms[i]->uniform = malloc(sizeof(struct gnPlatformUniform_t));
for (int c = 0; c < MAX_OPENGL_BINDINGS; c++) uniforms[i]->uniform->bindings[c].isUpdated = GN_FALSE;
} }
return uniforms; return uniforms;
} }

View File

@@ -1,14 +1,17 @@
#include "opengl_uniform.h" #include "opengl_uniform.h"
void openglUpdateBufferUniform(gnUniform uniform, gnBufferUniformInfo* info) { void openglUpdateBufferUniform(gnUniform uniform, gnBufferUniformInfo* info) {
uniform->uniform->type = gl_buffer; uniform->uniform->bindings[info->binding].isUpdated = GN_TRUE;
uniform->uniform->buffer_info = *info; uniform->uniform->bindings[info->binding].type = gl_buffer;
uniform->uniform->bindings[info->binding].buffer_info = *info;
} }
void openglUpdateStorageUniform(gnUniform uniform, gnStorageUniformInfo* info) { void openglUpdateStorageUniform(gnUniform uniform, gnStorageUniformInfo* info) {
uniform->uniform->type = gl_storage; uniform->uniform->bindings[info->binding].isUpdated = GN_TRUE;
uniform->uniform->storage_info = *info; uniform->uniform->bindings[info->binding].type = gl_storage;
uniform->uniform->bindings[info->binding].storage_info = *info;
} }
void openglUpdateImageUniform(gnUniform uniform, gnImageUniformInfo* info) { void openglUpdateImageUniform(gnUniform uniform, gnImageUniformInfo* info) {
uniform->uniform->type = gl_image; uniform->uniform->bindings[info->binding].isUpdated = GN_TRUE;
uniform->uniform->image_info = *info; uniform->uniform->bindings[info->binding].type = gl_image;
uniform->uniform->bindings[info->binding].image_info = *info;
} }

View File

@@ -1,18 +1,24 @@
#pragma once #pragma once
#include "glad/glad.h" #include "glad/glad.h"
#include "core/src/uniforms/gryphn_uniform.h" #include "core/src/uniforms/gryphn_uniform.h"
#include "shaders/opengl_shader_compiler.h"
typedef enum openglUniformType { typedef enum openglUniformType {
gl_buffer, gl_storage, gl_image gl_buffer, gl_storage, gl_image
} openglUniformType; } openglUniformType;
typedef struct gnPlatformUniform_t { typedef struct glUniformBinding {
openglUniformType type; openglUniformType type;
union { union {
gnBufferUniformInfo buffer_info; gnBufferUniformInfo buffer_info;
gnStorageUniformInfo storage_info; gnStorageUniformInfo storage_info;
gnImageUniformInfo image_info; gnImageUniformInfo image_info;
}; };
gnBool isUpdated;
} glUniformBinding;
typedef struct gnPlatformUniform_t {
glUniformBinding bindings[MAX_OPENGL_BINDINGS];
} gnPlatformUniform; } gnPlatformUniform;
void openglUpdateBufferUniform(gnUniform uniform, gnBufferUniformInfo* info); void openglUpdateBufferUniform(gnUniform uniform, gnBufferUniformInfo* info);

View File

@@ -2,7 +2,7 @@ set(CMAKE_EXPORT_COMPILE_COMMANDS on)
project(GryphnVulkanImpl) project(GryphnVulkanImpl)
set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD 17)
add_compile_definitions(GN_REVEAL_IMPL) add_compile_definitions(GN_REVEAL_IMPL GN_IMPLEMENTATION)
file(GLOB_RECURSE SOURCE_FILES CONFIGURE_DEPENDS "src/*.c" "src/*.h") file(GLOB_RECURSE SOURCE_FILES CONFIGURE_DEPENDS "src/*.c" "src/*.h")
file(GLOB_RECURSE LOADER_FILES CONFIGURE_DEPENDS "loader/*.c") file(GLOB_RECURSE LOADER_FILES CONFIGURE_DEPENDS "loader/*.c")

View File

@@ -7,15 +7,18 @@
gryphnInstanceFunctionLayers loadVulkanAPILayer(void) { gryphnInstanceFunctionLayers loadVulkanAPILayer(void) {
return (gryphnInstanceFunctionLayers) { return (gryphnInstanceFunctionLayers) {
.createInstance = vulkanCreateInstance, .createInstance = vulkanCreateInstance,
.isSuitable = vulkanIsInstanceSuitable,
.destroyInstance = vulkanDestroyInstance, .destroyInstance = vulkanDestroyInstance,
.queryDevices = vulkanQueryDevices,
.getPhysicalDeviceProperties = vulkanQueryPhysicalDeviceProperties,
.getPhysicalDeviceFeatures = vulkanQueryPhysicalDeviceFeatures,
.getPhysicalDeviceLimits = vulkanQueryPhysicalDeviceLimits,
.next = NULL .next = NULL
}; };
} }
gnInstanceFunctions loadVulkanInstanceFunctions(void) { gnInstanceFunctions loadVulkanInstanceFunctions(void) {
return (gnInstanceFunctions){ return (gnInstanceFunctions){
._gnGetPhysicalDevices = getPhysicalDevices,
._gnPhysicalDeviceCanPresentToSurface = deviceCanPresentToSurface, ._gnPhysicalDeviceCanPresentToSurface = deviceCanPresentToSurface,
._gnCreateOutputDevice = createVulkanOutputDevice, ._gnCreateOutputDevice = createVulkanOutputDevice,

View File

@@ -1,12 +1,12 @@
#include "vulkan_device_queues.h" #include "vulkan_device_queues.h"
#include "output_device/vulkan_output_devices.h" #include "output_device/vulkan_output_devices.h"
gnReturnCode vulkanPhysicalDeviceQueueProperties(gnPhysicalOutputDeviceHandle device, uint32_t queueFamilyCount, gnQueueFamilyProperties* queues) { gnReturnCode vulkanPhysicalDeviceQueueProperties(gnPhysicalDeviceHandle device, uint32_t queueFamilyCount, gnQueueFamilyProperties* queues) {
vkGetPhysicalDeviceQueueFamilyProperties(device->physicalDevice->device, &queueFamilyCount, NULL); vkGetPhysicalDeviceQueueFamilyProperties((VkPhysicalDevice)device, &queueFamilyCount, NULL);
if (queues == NULL) return GN_SUCCESS; if (queues == NULL) return GN_SUCCESS;
VkQueueFamilyProperties* queueFamilies = malloc(sizeof(VkQueueFamilyProperties) * queueFamilyCount); VkQueueFamilyProperties* queueFamilies = malloc(sizeof(VkQueueFamilyProperties) * queueFamilyCount);
vkGetPhysicalDeviceQueueFamilyProperties(device->physicalDevice->device, &queueFamilyCount, queueFamilies); vkGetPhysicalDeviceQueueFamilyProperties((VkPhysicalDevice)device, &queueFamilyCount, queueFamilies);
for (uint32_t i = 0; i < queueFamilyCount; i++) { for (uint32_t i = 0; i < queueFamilyCount; i++) {
queues[i].queueCount = queueFamilies[i].queueCount; queues[i].queueCount = queueFamilies[i].queueCount;
@@ -21,8 +21,9 @@ gnReturnCode vulkanPhysicalDeviceQueueProperties(gnPhysicalOutputDeviceHandle de
return GN_SUCCESS; return GN_SUCCESS;
} }
void getVulkanDeviceQueue(gnOutputDevice device, uint32_t queueFamily, uint32_t queueIndex, gnQueue* queue) { void getVulkanDeviceQueue(gnOutputDevice device, uint32_t queueFamily, uint32_t queueIndex, gnQueue* queue) {
VkQueue vulkanQueue; VkQueue vulkanQueue;
vkGetDeviceQueue(device->outputDevice->device, queueFamily, queueIndex, &vulkanQueue); vkGetDeviceQueue(device->outputDevice->device, queueFamily, queueIndex, &vulkanQueue);
*queue = (uint64_t)vulkanQueue; *queue = (gnQueue)vulkanQueue;
} }

View File

@@ -4,5 +4,5 @@
#include <output_device/vulkan_physical_device.h> #include <output_device/vulkan_physical_device.h>
#include <extensions/queues/gryphn_physcial_device_queue.h> #include <extensions/queues/gryphn_physcial_device_queue.h>
gnReturnCode vulkanPhysicalDeviceQueueProperties(gnPhysicalOutputDeviceHandle device, uint32_t queueFamilyCount, gnQueueFamilyProperties* queues); gnReturnCode vulkanPhysicalDeviceQueueProperties(gnPhysicalDeviceHandle device, uint32_t queueFamilyCount, gnQueueFamilyProperties* queues);
void getVulkanDeviceQueue(gnOutputDevice device, uint32_t queueFamily, uint32_t queueIndex, gnQueue* queue); void getVulkanDeviceQueue(gnOutputDevice device, uint32_t queueFamily, uint32_t queueIndex, gnQueue* queue);

View File

@@ -1,4 +1,5 @@
#include "vulkan_instance.h" #include "vulkan_instance.h"
// #include "output_device/vulkan_physical_device.h"
#include "vulkan_result_converter.h" #include "vulkan_result_converter.h"
GN_ARRAY_LIST_DEFINITION(vkString) GN_ARRAY_LIST_DEFINITION(vkString)
@@ -109,6 +110,17 @@ gnReturnCode vulkanCreateInstance(gnInstanceHandle instance, gnInstanceCreateInf
return VkResultToGnReturnCode(vkCreateInstance(&createInfo, NULL, &instance->instance->vk_instance)); return VkResultToGnReturnCode(vkCreateInstance(&createInfo, NULL, &instance->instance->vk_instance));
} }
gnReturnCode vulkanQueryDevices(gnInstanceHandle handle, uint32_t* count, gnPhysicalDeviceHandle* devices, gryphnInstanceFunctionLayers* next) {
return VkResultToGnReturnCode(vkEnumeratePhysicalDevices(handle->instance->vk_instance, count, (VkPhysicalDevice*)devices));
}
gnBool vulkanIsInstanceSuitable(gnInstanceHandle instance, gnSuitableField field, gryphnInstanceFunctionLayers* next) {
switch (field) {
case GN_NON_EXISTANT_PHYSICAL_DEVICE: return GN_FALSE;
}
return GN_FALSE;
}
void vulkanDestroyInstance(gnInstanceHandle instance, gryphnInstanceFunctionLayers* next, gnAllocators* alloctors) { void vulkanDestroyInstance(gnInstanceHandle instance, gryphnInstanceFunctionLayers* next, gnAllocators* alloctors) {
if (next != NULL) { return; } if (next != NULL) { return; }
vkDestroyInstance(instance->instance->vk_instance, NULL); vkDestroyInstance(instance->instance->vk_instance, NULL);

View File

@@ -15,6 +15,8 @@ typedef struct gnPlatformInstance_t {
} gnPlatformInstance; } gnPlatformInstance;
gnReturnCode vulkanCreateInstance(gnInstanceHandle instance, gnInstanceCreateInfo* instanceInfo, gryphnInstanceFunctionLayers* next, gnAllocators* alloctors); gnReturnCode vulkanCreateInstance(gnInstanceHandle instance, gnInstanceCreateInfo* instanceInfo, gryphnInstanceFunctionLayers* next, gnAllocators* alloctors);
gnBool vulkanIsInstanceSuitable(gnInstanceHandle instance, gnSuitableField field, gryphnInstanceFunctionLayers* next);
gnReturnCode vulkanQueryDevices(gnInstanceHandle handle, uint32_t* count, gnPhysicalDeviceHandle* devices, gryphnInstanceFunctionLayers* next);
void vulkanDestroyInstance(gnInstanceHandle instance, gryphnInstanceFunctionLayers* next, gnAllocators* alloctors); void vulkanDestroyInstance(gnInstanceHandle instance, gryphnInstanceFunctionLayers* next, gnAllocators* alloctors);
typedef const char* vkString; typedef const char* vkString;

View File

@@ -8,25 +8,27 @@
#include "vulkan_result_converter.h" #include "vulkan_result_converter.h"
#include "string.h" #include "string.h"
#include "stdio.h" #include <stdio.h>
gnReturnCode createVulkanOutputDevice(gnInstanceHandle instance, gnOutputDeviceHandle device, gnOutputDeviceInfo deviceInfo) { gnReturnCode createVulkanOutputDevice(gnInstanceHandle instance, gnOutputDeviceHandle device, gnOutputDeviceInfo deviceInfo) {
device->outputDevice = malloc(sizeof(gnPlatformOutputDevice)); device->outputDevice = malloc(sizeof(gnPlatformOutputDevice));
device->outputDevice->physicalDevice = deviceInfo.physicalDevice->physicalDevice->device; device->outputDevice->physicalDevice = (VkPhysicalDevice)deviceInfo.physicalDevice;
int createQueueCount = 0; int createQueueCount = 0;
VkDeviceQueueCreateInfo* queueCreateInfos = NULL; VkDeviceQueueCreateInfo* queueCreateInfos = NULL;
if (!instance->enabledExtensions[GN_EXT_QUEUES]) { if (!instance->enabledExtensions[GN_EXT_QUEUES]) {
queueCreateInfos = malloc(sizeof(VkDeviceQueueCreateInfo) * deviceInfo.physicalDevice->physicalDevice->neededQueueCount); uint32_t neededQueueCount;
createQueueCount = deviceInfo.physicalDevice->physicalDevice->neededQueueCount; vulkanNeededQueue* neededQueues = vulkanLoadNeededQueues(deviceInfo.physicalDevice, &neededQueueCount);
queueCreateInfos = malloc(sizeof(VkDeviceQueueCreateInfo) * neededQueueCount);
createQueueCount = neededQueueCount;
float queuePriority = 1.0f; float queuePriority = 1.0f;
for (uint32_t i = 0; i < deviceInfo.physicalDevice->physicalDevice->neededQueueCount; i++) { for (uint32_t i = 0; i < neededQueueCount; i++) {
queueCreateInfos[i].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; queueCreateInfos[i].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
queueCreateInfos[i].pNext = NULL; queueCreateInfos[i].pNext = NULL;
queueCreateInfos[i].flags = 0; queueCreateInfos[i].flags = 0;
queueCreateInfos[i].queueCount = 1; queueCreateInfos[i].queueCount = 1;
queueCreateInfos[i].queueFamilyIndex = deviceInfo.physicalDevice->physicalDevice->neededQueues[i].queueIndex; queueCreateInfos[i].queueFamilyIndex = neededQueues[i].queueIndex;
queueCreateInfos[i].pQueuePriorities = &queuePriority; queueCreateInfos[i].pQueuePriorities = &queuePriority;
} }
} else { } else {
@@ -54,7 +56,7 @@ gnReturnCode createVulkanOutputDevice(gnInstanceHandle instance, gnOutputDeviceH
.pQueueCreateInfos = queueCreateInfos, .pQueueCreateInfos = queueCreateInfos,
.pEnabledFeatures = &deviceFeatures .pEnabledFeatures = &deviceFeatures
}; };
deviceCreateInfo.ppEnabledExtensionNames = vkGetGryphnDeviceExtensions(&deviceCreateInfo.enabledExtensionCount, deviceInfo.physicalDevice->physicalDevice->device); deviceCreateInfo.ppEnabledExtensionNames = vkGetGryphnDeviceExtensions(&deviceCreateInfo.enabledExtensionCount, (VkPhysicalDevice)deviceInfo.physicalDevice);
device->outputDevice->enabledOversizedDescriptorPools = GN_FALSE; device->outputDevice->enabledOversizedDescriptorPools = GN_FALSE;
for (uint32_t i = 0; i < deviceCreateInfo.enabledExtensionCount; i++) for (uint32_t i = 0; i < deviceCreateInfo.enabledExtensionCount; i++)
@@ -67,18 +69,16 @@ gnReturnCode createVulkanOutputDevice(gnInstanceHandle instance, gnOutputDeviceH
deviceCreateInfo.enabledLayerCount = 1; deviceCreateInfo.enabledLayerCount = 1;
deviceCreateInfo.ppEnabledLayerNames = validation_layers; deviceCreateInfo.ppEnabledLayerNames = validation_layers;
} }
VkResult result = vkCreateDevice((VkPhysicalDevice)deviceInfo.physicalDevice, &deviceCreateInfo, NULL, &device->outputDevice->device);
VkResult result = vkCreateDevice(deviceInfo.physicalDevice->physicalDevice->device, &deviceCreateInfo, NULL, &device->outputDevice->device);
if (result != VK_SUCCESS) if (result != VK_SUCCESS)
return VkResultToGnReturnCode(result); return VkResultToGnReturnCode(result);
device->outputDevice->queues = malloc(sizeof(vulkanQueue) * deviceInfo.physicalDevice->physicalDevice->neededQueueCount); device->outputDevice->queues = malloc(sizeof(vulkanQueue) * createQueueCount);
uint32_t transferQueue = 0; uint32_t transferQueue = 0;
gnBool foundTransferQueue = GN_FALSE, foundGraphicsQueue = GN_FALSE; gnBool foundTransferQueue = GN_FALSE, foundGraphicsQueue = GN_FALSE;
for (uint32_t i = 0; i < deviceInfo.physicalDevice->physicalDevice->neededQueueCount; i++) {
device->outputDevice->queues[i].queueInfo = deviceInfo.physicalDevice->physicalDevice->neededQueues[i];
vkGetDeviceQueue(device->outputDevice->device, deviceInfo.physicalDevice->physicalDevice->neededQueues[i].queueIndex, 0, &device->outputDevice->queues[i].queue); for (uint32_t i = 0; i < createQueueCount; i++) {
vkGetDeviceQueue(device->outputDevice->device, queueCreateInfos[i].queueFamilyIndex, 0, &device->outputDevice->queues[i].queue);
if ((device->outputDevice->queues[i].queueInfo.createFlags & VK_QUEUE_TRANSFER_BIT) == VK_QUEUE_TRANSFER_BIT && !foundTransferQueue) { if ((device->outputDevice->queues[i].queueInfo.createFlags & VK_QUEUE_TRANSFER_BIT) == VK_QUEUE_TRANSFER_BIT && !foundTransferQueue) {
device->outputDevice->transferQueueIndex = i; device->outputDevice->transferQueueIndex = i;
transferQueue = device->outputDevice->queues[i].queueInfo.queueIndex; transferQueue = device->outputDevice->queues[i].queueInfo.queueIndex;
@@ -89,7 +89,12 @@ gnReturnCode createVulkanOutputDevice(gnInstanceHandle instance, gnOutputDeviceH
device->outputDevice->graphicsQueueIndex = i; device->outputDevice->graphicsQueueIndex = i;
foundGraphicsQueue = GN_FALSE; foundGraphicsQueue = GN_FALSE;
} }
if ((device->outputDevice->queues[i].queueInfo.createFlags & VK_QUEUE_GRAPHICS_BIT) == VK_QUEUE_GRAPHICS_BIT && !foundGraphicsQueue) {
device->outputDevice->graphicsQueueIndex = i;
foundGraphicsQueue = GN_FALSE;
} }
}
VkCommandPoolCreateInfo poolInfo = { VkCommandPoolCreateInfo poolInfo = {
.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, .sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,

View File

@@ -3,8 +3,120 @@
#include <output_device/vulkan_device_extensions.h> #include <output_device/vulkan_device_extensions.h>
#include <vulkan_surface/vulkan_surface.h> #include <vulkan_surface/vulkan_surface.h>
gnMultisampleCountFlags vkSampleCountToGryphn(VkSampleCountFlags counts) { inline gnPhysicalDeviceType vulkanDeviceTypeToGryphn(VkPhysicalDeviceType type) {
gnMultisampleCountFlags sampleCount = 0; switch (type) {
case VK_PHYSICAL_DEVICE_TYPE_OTHER: return GN_PHYSICAL_DEVICE_TYPE_FAKED_GPU;
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_VIRTUAL_GPU; // WE SHOULD NEVER HAVE TO DEAL WITH THIS ERROR
}
}
gnPhysicalDeviceProperties vulkanQueryPhysicalDeviceProperties(gnInstance instance, gnPhysicalDeviceHandle device, gryphnInstanceFunctionLayers* layers) {
VkPhysicalDeviceProperties properties;
vkGetPhysicalDeviceProperties((VkPhysicalDevice)device, &properties);
return (gnPhysicalDeviceProperties){
.deviceID = properties.deviceID,
.deviceName = gnCreateString(properties.deviceName),
.deviceType = vulkanDeviceTypeToGryphn(properties.deviceType),
.driverVersion = properties.driverVersion
};
}
gnPhysicalDeviceFeatures vulkanQueryPhysicalDeviceFeatures(gnInstance instance, gnPhysicalDeviceHandle device, gryphnInstanceFunctionLayers* layers) {
VkPhysicalDeviceFeatures features;
vkGetPhysicalDeviceFeatures((VkPhysicalDevice)device, &features);
return (gnPhysicalDeviceFeatures){
.uint32Index = features.fullDrawIndexUint32,
.geometryShader = features.geometryShader,
.tessellationShader = features.tessellationShader,
.multiDrawIndirect = features.multiDrawIndirect,
.drawIndirectFirstInstance = features.drawIndirectFirstInstance,
.fillModeNonSolid = features.fillModeNonSolid,
.wideLines = features.wideLines,
.largePoints = features.largePoints,
.samplerAnisotropy = features.samplerAnisotropy
};
}
gnPhysicalDeviceLimits vulkanQueryPhysicalDeviceLimits(gnInstance instance, gnPhysicalDeviceHandle device, gryphnInstanceFunctionLayers* layers) {
VkPhysicalDeviceProperties properties;
vkGetPhysicalDeviceProperties((VkPhysicalDevice)device, &properties);
VkPhysicalDeviceLimits limits = properties.limits;
return (gnPhysicalDeviceLimits) {
.maxImageExtent1D = limits.maxImageDimension1D,
.maxImageExtent2D = limits.maxImageDimension2D,
.maxImageExtent3D = limits.maxImageDimension3D,
.maxImageExtentCube = limits.maxImageDimensionCube,
.maxImageArrayLayers = limits.maxImageArrayLayers,
.maxTexelBufferElements = limits.maxTexelBufferElements,
.maxUniformBufferRange = limits.maxUniformBufferRange,
.maxStorageBufferRange = limits.maxStorageBufferRange,
.maxPushConstantsSize = limits.maxPushConstantsSize,
.maxMemoryAllocationCount = limits.maxMemoryAllocationCount,
.maxSamplerAllocationCount = limits.maxSamplerAllocationCount,
.maxBoundUniforms = limits.maxBoundDescriptorSets,
.maxPerStageUniformSamplers = limits.maxPerStageDescriptorSamplers,
.maxPerStageUniformUniformBuffers = limits.maxPerStageDescriptorUniformBuffers,
.maxPerStageUniformStorageBuffers = limits.maxPerStageDescriptorStorageBuffers,
.maxPerStageUniformSampledImages = limits.maxPerStageDescriptorSampledImages,
.maxPerStageUniformStorageImages = limits.maxPerStageDescriptorStorageBuffers,
.maxPerStageUniformInputAttachments = limits.maxPerStageDescriptorInputAttachments,
.maxPerStageResources = limits.maxPerStageResources,
.maxUniformSamplers = limits.maxPerStageDescriptorSamplers,
.maxUniformUniformBuffers = limits.maxDescriptorSetUniformBuffers,
.maxUniformUniformBuffersDynamic = limits.maxDescriptorSetUniformBuffersDynamic,
.maxUniformStorageBuffers = limits.maxDescriptorSetStorageBuffers,
.maxUniformStorageBuffersDynamic = limits.maxDescriptorSetStorageBuffersDynamic,
.maxUniformSampledImages = limits.maxDescriptorSetSampledImages,
.maxUniformStorageImages = limits.maxPerStageDescriptorStorageImages,
.maxUniformInputAttachments = limits.maxDescriptorSetInputAttachments,
.maxVertexInputAttributes = limits.maxVertexInputAttributes,
.maxVertexInputBindings = limits.maxVertexInputBindings,
.maxVertexInputAttributeOffset = limits.maxVertexInputAttributeOffset,
.maxVertexInputBindingStride = limits.maxVertexInputBindingStride,
.maxVertexOutputComponents = limits.maxVertexOutputComponents,
.maxTessellationGenerationLevel = limits.maxTessellationGenerationLevel,
.maxTessellationPatchSize = limits.maxTessellationPatchSize,
.maxTessellationControlPerVertexInputComponents = limits.maxTessellationControlPerVertexInputComponents,
.maxTessellationControlPerVertexOutputComponents = limits.maxTessellationControlPerVertexOutputComponents,
.maxTessellationControlPerPatchOutputComponents = limits.maxTessellationControlPerPatchOutputComponents,
.maxTessellationControlTotalOutputComponents = limits.maxTessellationControlTotalOutputComponents,
.maxTessellationEvaluationInputComponents = limits.maxTessellationEvaluationInputComponents,
.maxTessellationEvaluationOutputComponents = limits.maxTessellationControlPerVertexOutputComponents,
.maxGeometryShaderInvocations = limits.maxGeometryShaderInvocations,
.maxGeometryInputComponents = limits.maxGeometryInputComponents,
.maxGeometryOutputComponents = limits.maxGeometryOutputComponents,
.maxGeometryOutputVertices = limits.maxGeometryOutputVertices,
.maxGeometryTotalOutputComponents = limits.maxGeometryTotalOutputComponents,
.maxFragmentInputComponents = limits.maxFragmentInputComponents,
.maxFragmentOutputAttachments = limits.maxFragmentOutputAttachments,
.maxFragmentDualSrcAttachments = limits.maxFragmentDualSrcAttachments,
.maxFragmentCombinedOutputResources = limits.maxFragmentCombinedOutputResources,
.maxDrawIndexedIndexValue = limits.maxDrawIndexedIndexValue,
.maxDrawIndirectCount = limits.maxDrawIndirectCount,
.maxSamplerLodBias = limits.maxSamplerLodBias,
.maxSamplerAnisotropy = limits.maxSamplerAnisotropy,
.maxViewports = limits.maxViewports,
.maxViewportExtents = { limits.maxViewportDimensions[0], limits.maxViewportDimensions[1] },
.viewportBoundsRange = { limits.viewportBoundsRange[0], limits.viewportBoundsRange[1] },
.maxFramebufferExtent = {limits.maxFramebufferWidth, limits.maxFramebufferHeight},
.maxFramebufferLayers = limits.maxFramebufferLayers,
.framebufferColorSampleCounts = vkSampleCountToGryphn(limits.framebufferColorSampleCounts),
.framebufferDepthSampleCounts = vkSampleCountToGryphn(limits.framebufferDepthSampleCounts),
.framebufferStencilSampleCounts = vkSampleCountToGryphn(limits.framebufferStencilSampleCounts),
.framebufferNoAttachmentsSampleCounts = vkSampleCountToGryphn(limits.framebufferNoAttachmentsSampleCounts),
.maxColorAttachments = limits.maxColorAttachments,
.pointSizeRange = { limits.pointSizeRange[0], limits.pointSizeRange[1] },
.lineWidthRange = { limits.lineWidthRange[0], limits.lineWidthRange[1] },
.pointSizeGranularity = limits.pointSizeGranularity,
.lineWidthGranularity = limits.lineWidthGranularity,
.strictLines = limits.strictLines
};
}
gnSampleCountFlags vkSampleCountToGryphn(VkSampleCountFlags counts) {
gnSampleCountFlags sampleCount = 0;
if ((counts & VK_SAMPLE_COUNT_64_BIT) == VK_SAMPLE_COUNT_64_BIT) { sampleCount |= GN_SAMPLE_BIT_64; } if ((counts & VK_SAMPLE_COUNT_64_BIT) == VK_SAMPLE_COUNT_64_BIT) { sampleCount |= GN_SAMPLE_BIT_64; }
if ((counts & VK_SAMPLE_COUNT_32_BIT) == VK_SAMPLE_COUNT_32_BIT) { sampleCount |= GN_SAMPLE_BIT_32; } if ((counts & VK_SAMPLE_COUNT_32_BIT) == VK_SAMPLE_COUNT_32_BIT) { sampleCount |= GN_SAMPLE_BIT_32; }
if ((counts & VK_SAMPLE_COUNT_16_BIT) == VK_SAMPLE_COUNT_16_BIT) { sampleCount |= GN_SAMPLE_BIT_16; } if ((counts & VK_SAMPLE_COUNT_16_BIT) == VK_SAMPLE_COUNT_16_BIT) { sampleCount |= GN_SAMPLE_BIT_16; }
@@ -15,9 +127,7 @@ gnMultisampleCountFlags vkSampleCountToGryphn(VkSampleCountFlags counts) {
return sampleCount; return sampleCount;
} }
#include <stdio.h> VkSampleCountFlags gnSampleCountToVulkan(gnSampleCountFlags counts) {
VkSampleCountFlags gnSampleCountToVulkan(gnMultisampleCountFlags counts) {
VkSampleCountFlags sampleCount = 0; VkSampleCountFlags sampleCount = 0;
if ((counts & GN_SAMPLE_BIT_64) == GN_SAMPLE_BIT_64) { sampleCount |= VK_SAMPLE_COUNT_64_BIT; } if ((counts & GN_SAMPLE_BIT_64) == GN_SAMPLE_BIT_64) { sampleCount |= VK_SAMPLE_COUNT_64_BIT; }
@@ -31,20 +141,28 @@ VkSampleCountFlags gnSampleCountToVulkan(gnMultisampleCountFlags counts) {
return sampleCount; return sampleCount;
} }
void vulkanLoadNeededQueues(VkPhysicalDevice vulkanDevice, gnPhysicalDevice gryphnDevice) { vulkanNeededQueue* vulkanLoadNeededQueues(gnPhysicalDevice physicalDevice, uint32_t* neededQueueCount) {
VkPhysicalDevice device = (VkPhysicalDevice)physicalDevice;
uint32_t queueFamilyCount = 0; uint32_t queueFamilyCount = 0;
vkGetPhysicalDeviceQueueFamilyProperties(vulkanDevice, &queueFamilyCount, NULL); vkGetPhysicalDeviceQueueFamilyProperties(device, &queueFamilyCount, NULL);
VkQueueFamilyProperties* queueFamilies = malloc(sizeof(VkQueueFamilyProperties) * queueFamilyCount); VkQueueFamilyProperties* queueFamilies = malloc(sizeof(VkQueueFamilyProperties) * queueFamilyCount);
vkGetPhysicalDeviceQueueFamilyProperties(vulkanDevice, &queueFamilyCount, queueFamilies); vkGetPhysicalDeviceQueueFamilyProperties(device, &queueFamilyCount, queueFamilies);
*neededQueueCount = 0;
gnBool foundGraphicsQueue = GN_FALSE, foundTransferQueue = GN_FALSE;
vulkanNeededQueue* neededQueues = malloc(sizeof(vulkanNeededQueue) * queueFamilyCount);
gryphnDevice->physicalDevice->neededQueues = malloc(sizeof(vulkanNeededQueue) * queueFamilyCount);
for (uint32_t c = 0; c < queueFamilyCount; c++) { for (uint32_t c = 0; c < queueFamilyCount; c++) {
gnBool hasNeededQueue = GN_FALSE; gnBool hasNeededQueue = GN_FALSE;
if ((queueFamilies[c].queueFlags & VK_QUEUE_GRAPHICS_BIT) == VK_QUEUE_GRAPHICS_BIT && !foundGraphicsQueue) {
if ((queueFamilies[c].queueFlags & VK_QUEUE_GRAPHICS_BIT) == VK_QUEUE_GRAPHICS_BIT)
hasNeededQueue = GN_TRUE; hasNeededQueue = GN_TRUE;
if ((queueFamilies[c].queueFlags & VK_QUEUE_TRANSFER_BIT) == VK_QUEUE_TRANSFER_BIT) foundGraphicsQueue = GN_TRUE;
}
if ((queueFamilies[c].queueFlags & VK_QUEUE_TRANSFER_BIT) == VK_QUEUE_TRANSFER_BIT && !foundTransferQueue) {
hasNeededQueue = GN_TRUE; hasNeededQueue = GN_TRUE;
foundTransferQueue = GN_TRUE;
}
if (hasNeededQueue) { if (hasNeededQueue) {
vulkanNeededQueue neededQueue = { vulkanNeededQueue neededQueue = {
@@ -55,98 +173,23 @@ void vulkanLoadNeededQueues(VkPhysicalDevice vulkanDevice, gnPhysicalDevice gryp
if ((queueFamilies[c].queueFlags & VK_QUEUE_GRAPHICS_BIT)) neededQueue.createFlags |= VK_QUEUE_GRAPHICS_BIT; if ((queueFamilies[c].queueFlags & VK_QUEUE_GRAPHICS_BIT)) neededQueue.createFlags |= VK_QUEUE_GRAPHICS_BIT;
if ((queueFamilies[c].queueFlags & VK_QUEUE_TRANSFER_BIT)) neededQueue.createFlags |= VK_QUEUE_TRANSFER_BIT; if ((queueFamilies[c].queueFlags & VK_QUEUE_TRANSFER_BIT)) neededQueue.createFlags |= VK_QUEUE_TRANSFER_BIT;
gryphnDevice->physicalDevice->neededQueues[gryphnDevice->physicalDevice->neededQueueCount] = neededQueue; neededQueues[*neededQueueCount] = neededQueue;
gryphnDevice->physicalDevice->neededQueueCount++; (*neededQueueCount)++;
} }
} }
free(queueFamilies); free(queueFamilies);
neededQueues = realloc(neededQueues, sizeof(vulkanNeededQueue) * *neededQueueCount);
return neededQueues;
} }
gnPhysicalDevice* getPhysicalDevices(gnInstanceHandle instance, uint32_t* deviceCount) {
vkEnumeratePhysicalDevices(instance->instance->vk_instance, deviceCount, NULL);
if (deviceCount == 0)
return NULL;
VkPhysicalDevice* physicalDevices = malloc(sizeof(VkPhysicalDevice) * *deviceCount); gnBool deviceCanPresentToSurface(gnInstance instance, gnPhysicalDevice physicalDevice, gnWindowSurface surface) {;
vkEnumeratePhysicalDevices(instance->instance->vk_instance, deviceCount, physicalDevices);
gnPhysicalDevice* outputDevices = (gnPhysicalDevice*)malloc(sizeof(gnPhysicalDevice) * *deviceCount);
for (uint32_t i = 0; i < *deviceCount; i++) {
outputDevices[i] = malloc(sizeof(gnPhysicalOutputDevice_t));
outputDevices[i]->physicalDevice = malloc(sizeof(struct gnPlatformPhysicalDevice_t));
outputDevices[i]->physicalDevice->device = physicalDevices[i];
VkPhysicalDeviceProperties deviceProperties;
vkGetPhysicalDeviceProperties(physicalDevices[i], &deviceProperties);
outputDevices[i]->properties.name = gnCreateString(deviceProperties.deviceName);
switch(deviceProperties.deviceType) {
case VK_PHYSICAL_DEVICE_TYPE_OTHER: outputDevices[i]->properties.deviceType = GN_EXTERNAL_DEVICE;
case VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU: outputDevices[i]->properties.deviceType = GN_INTEGRATED_DEVICE;
case VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU: outputDevices[i]->properties.deviceType = GN_DEDICATED_DEVICE;
case VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU: outputDevices[i]->properties.deviceType = GN_INTEGRATED_DEVICE;
case VK_PHYSICAL_DEVICE_TYPE_CPU: outputDevices[i]->properties.deviceType = GN_INTEGRATED_DEVICE;
case VK_PHYSICAL_DEVICE_TYPE_MAX_ENUM: outputDevices[i]->properties.deviceType = GN_INTEGRATED_DEVICE;
}
if (instance->enabledExtensions[GN_EXT_QUEUES] == GN_FALSE)
vulkanLoadNeededQueues(physicalDevices[i], outputDevices[i]);
VkPhysicalDeviceProperties physicalDeviceProperties;
vkGetPhysicalDeviceProperties(physicalDevices[i], &physicalDeviceProperties);
outputDevices[i]->features.maxColorSamples = vkSampleCountToGryphn(physicalDeviceProperties.limits.framebufferColorSampleCounts);
outputDevices[i]->features.maxDepthSamples = vkSampleCountToGryphn(physicalDeviceProperties.limits.framebufferDepthSampleCounts);
outputDevices[i]->features.maxMemoryAllocations = physicalDeviceProperties.limits.maxMemoryAllocationCount;
outputDevices[i]->features.maxPushConstantSize = physicalDeviceProperties.limits.maxPushConstantsSize;
}
free(physicalDevices);
return outputDevices;
}
gnBool deviceCanPresentToSurface(gnPhysicalDevice device, gnWindowSurface surface) {
uint32_t queueFamilyCount = 0; uint32_t queueFamilyCount = 0;
vkGetPhysicalDeviceQueueFamilyProperties(device->physicalDevice->device, &queueFamilyCount, NULL); vkGetPhysicalDeviceQueueFamilyProperties((VkPhysicalDevice)physicalDevice, &queueFamilyCount, NULL);
for (uint32_t i = 0; i < queueFamilyCount; i++) { for (uint32_t i = 0; i < queueFamilyCount; i++) {
VkBool32 supportsPresent; VkBool32 supportsPresent;
vkGetPhysicalDeviceSurfaceSupportKHR(device->physicalDevice->device, i, surface->windowSurface->surface, &supportsPresent); vkGetPhysicalDeviceSurfaceSupportKHR((VkPhysicalDevice)physicalDevice, i, surface->windowSurface->surface, &supportsPresent);
if (supportsPresent) return GN_TRUE; if (supportsPresent) return GN_TRUE;
} }
return GN_FALSE; return GN_FALSE;
} }
// gnBool foundQueue = GN_FALSE;
// for (uint32_t i = 0; i < device->physicalDevice->neededQueueCount; i++) {
// VkBool32 supportsPresent = VK_FALSE;
// vkGetPhysicalDeviceSurfaceSupportKHR(device->physicalDevice->device, device->physicalDevice->neededQueues[i].queueIndex, surface->windowSurface->surface, &supportsPresent);
// if (supportsPresent) {
// device->physicalDevice->neededQueues[i].usedForPresent = GN_TRUE;
// foundQueue = GN_TRUE;
// break;
// }
// surface->windowSurface->presentQueueIndex = i;
// }
// if (!foundQueue) {
// uint32_t queueFamilyCount = 0;
// vkGetPhysicalDeviceQueueFamilyProperties(device->physicalDevice->device, &queueFamilyCount, NULL);
// for (uint32_t i = 0; i < queueFamilyCount; i++) {
// VkBool32 supportsPresent = VK_FALSE;
// vkGetPhysicalDeviceSurfaceSupportKHR(device->physicalDevice->device, i, surface->windowSurface->surface, &supportsPresent);
// if (supportsPresent) {
// device->physicalDevice->neededQueues[device->physicalDevice->neededQueueCount] = (vulkanNeededQueue){
// .queueIndex = i,
// .createFlags = 0,
// .usedForPresent = GN_TRUE
// };
// foundQueue = GN_TRUE;
// surface->windowSurface->presentQueueIndex = device->physicalDevice->neededQueueCount;
// device->physicalDevice->neededQueueCount++;
// break;
// }
// }
// }
// return foundQueue;

View File

@@ -1,23 +1,19 @@
#pragma once #pragma once
#include "loader/src/gryphn_instance_functions.h"
#include <vulkan/vulkan.h> #include <vulkan/vulkan.h>
#include <output_device/gryphn_physical_output_device.h> #include <output_device/gryphn_physical_device.h>
typedef struct vulkanNeededQueue { typedef struct vulkanNeededQueue {
VkQueueFlags createFlags; VkQueueFlags createFlags;
gnBool usedForPresent; gnBool usedForPresent;
uint32_t queueIndex; uint32_t queueIndex;
} vulkanNeededQueue; } vulkanNeededQueue;
vulkanNeededQueue* vulkanLoadNeededQueues(gnPhysicalDevice physicalDevice, uint32_t* neededQueueCount);
typedef struct gnPlatformPhysicalDevice_t { gnPhysicalDeviceProperties vulkanQueryPhysicalDeviceProperties(gnInstance instance, gnPhysicalDeviceHandle device, gryphnInstanceFunctionLayers* layers);
VkPhysicalDevice device; gnPhysicalDeviceFeatures vulkanQueryPhysicalDeviceFeatures(gnInstance instance, gnPhysicalDeviceHandle device, gryphnInstanceFunctionLayers* layers);
uint32_t neededQueueCount; gnPhysicalDeviceLimits vulkanQueryPhysicalDeviceLimits(gnInstance instance, gnPhysicalDeviceHandle device, gryphnInstanceFunctionLayers* layers);
vulkanNeededQueue* neededQueues;
} gnPlatformPhysicalDevice; gnBool deviceCanPresentToSurface(gnInstance instance, gnPhysicalDevice device, gnWindowSurface surface);
gnSampleCountFlags vkSampleCountToGryphn(VkSampleCountFlags counts);
gnPhysicalDevice* getPhysicalDevices(gnInstanceHandle instance, uint32_t* deviceCount); VkSampleCountFlags gnSampleCountToVulkan(gnSampleCountFlags counts);
gnBool deviceCanPresentToSurface(gnPhysicalDevice device, gnWindowSurface surface);
gnMultisampleCountFlags vkSampleCountToGryphn(VkSampleCountFlags counts);
VkSampleCountFlags gnSampleCountToVulkan(gnMultisampleCountFlags counts);

View File

@@ -2,7 +2,6 @@
#include <instance/vulkan_instance.h> #include <instance/vulkan_instance.h>
#include "vulkan_surface.h" #include "vulkan_surface.h"
#include <output_device/vulkan_physical_device.h> #include <output_device/vulkan_physical_device.h>
#include "vulkan_result_converter.h"
#ifdef GN_PLATFORM_LINUX #ifdef GN_PLATFORM_LINUX
#ifdef GN_WINDOW_X11 #ifdef GN_WINDOW_X11
@@ -57,16 +56,17 @@ void destroyWindowSurface(struct gnWindowSurface_t* windowSurface) {
} }
gnSurfaceFormat* vkGetSurfaceFormats( gnSurfaceFormat* vkGetSurfaceFormats(
struct gnWindowSurface_t* windowSurface, gnPhysicalDevice device, uint32_t* formatCount struct gnWindowSurface_t* windowSurface, gnPhysicalDevice deviceHandle, uint32_t* formatCount
) { ) {
gnSurfaceFormat* formats = NULL; gnSurfaceFormat* formats = NULL;
VkPhysicalDevice device = (VkPhysicalDevice)deviceHandle;
vkGetPhysicalDeviceSurfaceFormatsKHR(device->physicalDevice->device, windowSurface->windowSurface->surface, formatCount, NULL); vkGetPhysicalDeviceSurfaceFormatsKHR(device, windowSurface->windowSurface->surface, formatCount, NULL);
formats = malloc(sizeof(gnSurfaceFormat) * *formatCount); formats = malloc(sizeof(gnSurfaceFormat) * *formatCount);
VkSurfaceFormatKHR* vkFormats = malloc(sizeof(VkSurfaceFormatKHR) * *formatCount);; VkSurfaceFormatKHR* vkFormats = malloc(sizeof(VkSurfaceFormatKHR) * *formatCount);;
if (*formatCount > 0) { if (*formatCount > 0) {
vkGetPhysicalDeviceSurfaceFormatsKHR(device->physicalDevice->device, windowSurface->windowSurface->surface, formatCount, vkFormats); vkGetPhysicalDeviceSurfaceFormatsKHR(device, windowSurface->windowSurface->surface, formatCount, vkFormats);
for (uint32_t i = 0; i < *formatCount; i++) { for (uint32_t i = 0; i < *formatCount; i++) {
switch (vkFormats[i].format) { switch (vkFormats[i].format) {
case VK_FORMAT_B8G8R8A8_SRGB: { formats[i].format = GN_FORMAT_BGRA8_SRGB; break; } case VK_FORMAT_B8G8R8A8_SRGB: { formats[i].format = GN_FORMAT_BGRA8_SRGB; break; }
@@ -85,13 +85,13 @@ gnSurfaceFormat* vkGetSurfaceFormats(
} }
gnSurfaceDetails getSurfaceDetails( gnSurfaceDetails getSurfaceDetails(
gnWindowSurfaceHandle windowSurface, gnPhysicalDevice device gnWindowSurfaceHandle windowSurface, gnPhysicalDevice deviceHandle
) { ) {
gnSurfaceDetails surfaceDetails; gnSurfaceDetails surfaceDetails;
surfaceDetails.formats = vkGetSurfaceFormats(windowSurface, device, &surfaceDetails.formatCount); surfaceDetails.formats = vkGetSurfaceFormats(windowSurface, deviceHandle, &surfaceDetails.formatCount);
VkSurfaceCapabilitiesKHR details; VkSurfaceCapabilitiesKHR details;
vkGetPhysicalDeviceSurfaceCapabilitiesKHR(device->physicalDevice->device, windowSurface->windowSurface->surface, &details); vkGetPhysicalDeviceSurfaceCapabilitiesKHR((VkPhysicalDevice)deviceHandle, windowSurface->windowSurface->surface, &details);
surfaceDetails.minImageCount = details.minImageCount; surfaceDetails.minImageCount = details.minImageCount;
surfaceDetails.maxImageCount = details.maxImageCount; surfaceDetails.maxImageCount = details.maxImageCount;

View File

@@ -10,9 +10,15 @@ typedef struct type##_t* type##Handle; \
typedef struct type##_t* type typedef struct type##_t* type
// The value of this handle is defined by the implementation // The value of this handle is defined by the implementation
#ifndef GN_IMPLEMENTATION
#define GN_IMPLEMENTATION_HANDLE(type) \ #define GN_IMPLEMENTATION_HANDLE(type) \
typedef uint64_t type##Handle; \ typedef uint64_t type##Handle; \
typedef uint64_t type typedef uint64_t type
#else
#define GN_IMPLEMENTATION_HANDLE(type) \
typedef uint64_t type##Handle; \
typedef uint64_t type
#endif
// can be used to alias a normal handle or an implementation handle // can be used to alias a normal handle or an implementation handle
#define GN_HANDLE_ALIAS(handle, alias) \ #define GN_HANDLE_ALIAS(handle, alias) \
@@ -20,14 +26,12 @@ typedef struct handle##_t* alias##Handle; \
typedef struct handle##_t* alias typedef struct handle##_t* alias
GN_HANDLE(gnInstance); GN_HANDLE(gnInstance);
GN_IMPLEMENTATION_HANDLE(gnPhysicalDevice); // NOTE: needs to become a impl handle
GN_HANDLE(gnWindowSurface); GN_HANDLE(gnWindowSurface);
GN_HANDLE(gnPresentationQueue); GN_HANDLE(gnPresentationQueue);
GN_HANDLE(gnTexture); GN_HANDLE(gnTexture);
GN_HANDLE(gnRenderPassDescriptor); GN_HANDLE(gnRenderPassDescriptor);
GN_HANDLE(gnPhysicalOutputDevice);
GN_HANDLE_ALIAS(gnPhysicalOutputDevice, gnPhysicalDevice);
GN_HANDLE(gnOutputDevice); GN_HANDLE(gnOutputDevice);
GN_HANDLE_ALIAS(gnOutputDevice, gnDevice); GN_HANDLE_ALIAS(gnOutputDevice, gnDevice);
GN_HANDLE(gnShaderModule); GN_HANDLE(gnShaderModule);

View File

@@ -84,6 +84,14 @@ gnReturnCode gnCreateInstance(gnInstanceHandle* instance, gnInstanceCreateInfo*
return (*instance)->functions->createInstance(*instance, info, (*instance)->functions->next, &(*instance)->allocators); return (*instance)->functions->createInstance(*instance, info, (*instance)->functions->next, &(*instance)->allocators);
} }
gnBool gnIsInstanceSuitable(gnInstance instance, gnSuitableField field) {
return instance->functions->isSuitable(instance, field, instance->functions->next);
}
gnReturnCode gnInstanceQueryDevices(gnInstanceHandle instance, uint32_t* count, gnPhysicalDeviceHandle* devices) {
return instance->functions->queryDevices(instance, count, devices, instance->functions->next);
}
void gnDestroyInstance(gnInstanceHandle* instance) { void gnDestroyInstance(gnInstanceHandle* instance) {
if (instance == GN_NULL_HANDLE) return; if (instance == GN_NULL_HANDLE) return;
(*instance)->functions->destroyInstance(*instance, (*instance)->functions->next, &(*instance)->allocators); (*instance)->functions->destroyInstance(*instance, (*instance)->functions->next, &(*instance)->allocators);

View File

@@ -7,7 +7,6 @@
#include "gryphn_allocators.h" #include "gryphn_allocators.h"
#include <gryphn_extensions.h> #include <gryphn_extensions.h>
typedef struct gnApplicationInfo { typedef struct gnApplicationInfo {
gnString applicationName; gnString applicationName;
gnVersion applicationVersion; gnVersion applicationVersion;
@@ -16,6 +15,10 @@ typedef struct gnApplicationInfo {
gnVersion engineVersion; gnVersion engineVersion;
} gnApplicationInfo; } gnApplicationInfo;
typedef enum gnSuitableField {
GN_NON_EXISTANT_PHYSICAL_DEVICE
} gnSuitableField;
typedef struct gnInstanceCreateInfo { typedef struct gnInstanceCreateInfo {
gnApplicationInfo applicationInfo; gnApplicationInfo applicationInfo;
gnDebuggerCreateInfo debuggerInfo; gnDebuggerCreateInfo debuggerInfo;
@@ -45,4 +48,6 @@ struct gnInstance_t {
#endif #endif
gnReturnCode gnCreateInstance(gnInstanceHandle* instance, gnInstanceCreateInfo* info); gnReturnCode gnCreateInstance(gnInstanceHandle* instance, gnInstanceCreateInfo* info);
gnBool gnIsInstanceSuitable(gnInstance instance, gnSuitableField field);
gnReturnCode gnInstanceQueryDevices(gnInstanceHandle instance, uint32_t* count, gnPhysicalDeviceHandle* devices);
void gnDestroyInstance(gnInstanceHandle* instance); void gnDestroyInstance(gnInstanceHandle* instance);

View File

@@ -1,5 +1,5 @@
#pragma once #pragma once
#include <output_device/gryphn_physical_output_device.h> #include <output_device/gryphn_physical_device.h>
#include <core/gryphn_return_code.h> #include <core/gryphn_return_code.h>
typedef struct gnOutputDeviceEnabledFeatures { typedef struct gnOutputDeviceEnabledFeatures {
@@ -24,7 +24,6 @@ typedef struct gnOutputDeviceInfo {
struct gnOutputDevice_t { struct gnOutputDevice_t {
struct gnPlatformOutputDevice_t* outputDevice; struct gnPlatformOutputDevice_t* outputDevice;
gnOutputDeviceInfo deviceInfo; gnOutputDeviceInfo deviceInfo;
gnInstanceHandle instance; gnInstanceHandle instance;
}; };
#endif #endif

View File

@@ -0,0 +1,19 @@
#include "gryphn_physical_device.h"
#include "instance/gryphn_instance.h"
#include "loader/src/gryphn_instance_functions.h"
gnPhysicalDeviceProperties gnQueryPhysicalDeviceProperties(gnInstanceHandle instance, gnPhysicalDeviceHandle device) {
return instance->functions->getPhysicalDeviceProperties(instance, device, instance->functions->next);
}
gnPhysicalDeviceFeatures gnQueryPhysicalDeviceFeatures(gnInstanceHandle instance, gnPhysicalDeviceHandle device) {
return instance->functions->getPhysicalDeviceFeatures(instance, device, instance->functions->next);
}
gnPhysicalDeviceLimits gnQueryPhysicalDeviceLimits(gnInstanceHandle instance, gnPhysicalDeviceHandle device) {
return instance->functions->getPhysicalDeviceLimits(instance, device, instance->functions->next);
}
gnBool gnPhysicalDeviceCanPresentToSurface(gnInstanceHandle instance, gnPhysicalDeviceHandle device, gnWindowSurfaceHandle windowSurface) {
return instance->callingLayer->instanceFunctions._gnPhysicalDeviceCanPresentToSurface(instance, device, windowSurface);
}

View File

@@ -0,0 +1,119 @@
#pragma once
#include "stdint.h"
#include "utils/gryphn_string.h"
#include "gryphn_handles.h"
#include <utils/math/gryphn_vec2.h>
typedef enum gnPhysicalDeviceType {
GN_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU,
GN_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU,
GN_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU,
GN_PHYSICAL_DEVICE_TYPE_FAKED_GPU,
GN_PHYSICAL_DEVICE_TYPE_CPU,
} gnPhysicalDeviceType;
typedef enum gnSampleCountFlags {
GN_SAMPLE_BIT_1 = 1 << 0, // 0x01
GN_SAMPLE_BIT_2 = 1 << 1, // 0x02
GN_SAMPLE_BIT_4 = 1 << 2, // 0x04
GN_SAMPLE_BIT_8 = 1 << 3, // 0x08
GN_SAMPLE_BIT_16 = 1 << 4, // 0x10
GN_SAMPLE_BIT_32 = 1 << 5, // 0x20
GN_SAMPLE_BIT_64 = 1 << 6, // 0x40
} gnSampleCountFlags;
typedef struct gnPhysicalDeviceProperties {
uint32_t driverVersion;
uint32_t deviceID;
gnString deviceName;
gnPhysicalDeviceType deviceType;
} gnPhysicalDeviceProperties;
typedef struct gnPhysicalDeviceFeatures {
gnBool uint32Index;
gnBool geometryShader;
gnBool tessellationShader;
gnBool multiDrawIndirect;
gnBool drawIndirectFirstInstance;
gnBool fillModeNonSolid;
gnBool wideLines;
gnBool largePoints;
gnBool samplerAnisotropy;
} gnPhysicalDeviceFeatures;
typedef struct gnPhysicalDeviceLimits {
uint32_t maxImageExtent1D;
uint32_t maxImageExtent2D;
uint32_t maxImageExtent3D;
uint32_t maxImageExtentCube;
uint32_t maxImageArrayLayers;
uint32_t maxTexelBufferElements;
uint32_t maxUniformBufferRange;
uint32_t maxStorageBufferRange;
uint32_t maxPushConstantsSize;
uint32_t maxMemoryAllocationCount;
uint32_t maxSamplerAllocationCount;
uint32_t maxBoundUniforms;
uint32_t maxPerStageUniformSamplers;
uint32_t maxPerStageUniformUniformBuffers;
uint32_t maxPerStageUniformStorageBuffers;
uint32_t maxPerStageUniformSampledImages;
uint32_t maxPerStageUniformStorageImages;
uint32_t maxPerStageUniformInputAttachments;
uint32_t maxPerStageResources;
uint32_t maxUniformSamplers;
uint32_t maxUniformUniformBuffers;
uint32_t maxUniformUniformBuffersDynamic;
uint32_t maxUniformStorageBuffers;
uint32_t maxUniformStorageBuffersDynamic;
uint32_t maxUniformSampledImages;
uint32_t maxUniformStorageImages;
uint32_t maxUniformInputAttachments;
uint32_t maxVertexInputAttributes;
uint32_t maxVertexInputBindings;
uint32_t maxVertexInputAttributeOffset;
uint32_t maxVertexInputBindingStride;
uint32_t maxVertexOutputComponents;
uint32_t maxTessellationGenerationLevel;
uint32_t maxTessellationPatchSize;
uint32_t maxTessellationControlPerVertexInputComponents;
uint32_t maxTessellationControlPerVertexOutputComponents;
uint32_t maxTessellationControlPerPatchOutputComponents;
uint32_t maxTessellationControlTotalOutputComponents;
uint32_t maxTessellationEvaluationInputComponents;
uint32_t maxTessellationEvaluationOutputComponents;
uint32_t maxGeometryShaderInvocations;
uint32_t maxGeometryInputComponents;
uint32_t maxGeometryOutputComponents;
uint32_t maxGeometryOutputVertices;
uint32_t maxGeometryTotalOutputComponents;
uint32_t maxFragmentInputComponents;
uint32_t maxFragmentOutputAttachments;
uint32_t maxFragmentDualSrcAttachments;
uint32_t maxFragmentCombinedOutputResources;
uint32_t maxDrawIndexedIndexValue;
uint32_t maxDrawIndirectCount;
float maxSamplerLodBias;
float maxSamplerAnisotropy;
uint32_t maxViewports;
uint32_t maxViewportExtents[2];
float viewportBoundsRange[2];
gnExtent2D maxFramebufferExtent;
uint32_t maxFramebufferLayers;
gnSampleCountFlags framebufferColorSampleCounts;
gnSampleCountFlags framebufferDepthSampleCounts;
gnSampleCountFlags framebufferStencilSampleCounts;
gnSampleCountFlags framebufferNoAttachmentsSampleCounts;
uint32_t maxColorAttachments;
float pointSizeRange[2];
float lineWidthRange[2];
float pointSizeGranularity;
float lineWidthGranularity;
gnBool strictLines;
} gnPhysicalDeviceLimits;
gnPhysicalDeviceProperties gnQueryPhysicalDeviceProperties(gnInstanceHandle instance, gnPhysicalDeviceHandle device);
gnPhysicalDeviceFeatures gnQueryPhysicalDeviceFeatures(gnInstanceHandle instance, gnPhysicalDeviceHandle device);
gnPhysicalDeviceLimits gnQueryPhysicalDeviceLimits(gnInstanceHandle instance, gnPhysicalDeviceHandle device);
gnBool gnPhysicalDeviceCanPresentToSurface(gnInstance instance, gnPhysicalDeviceHandle device, gnWindowSurfaceHandle windowSurface);

View File

@@ -1,17 +0,0 @@
#include "gryphn_physical_output_device.h"
#include "instance/gryphn_instance.h"
#include "loader/src/gryphn_instance_functions.h"
gnPhysicalOutputDeviceHandle* gnGetPhyscialDevices(gnInstanceHandle instance, uint32_t* count) {;
gnPhysicalOutputDeviceHandle* devices = instance->callingLayer->instanceFunctions._gnGetPhysicalDevices(instance, count);
for (uint32_t i = 0; i < *count; i++)
devices[i]->instance = instance;
return devices;
}
gnBool gnPhysicalDeviceCanPresentToSurface(gnPhysicalOutputDeviceHandle device, gnWindowSurfaceHandle windowSurface) {
return device->instance->callingLayer->instanceFunctions._gnPhysicalDeviceCanPresentToSurface(device, windowSurface);
}
gnPhysicalDeviceProperties gnGetPhysicalDeviceProperties(gnPhysicalOutputDeviceHandle device) { return device->properties; }
gnPhysicalDeviceFeatures gnGetPhysicalDeviceFeatures(gnPhysicalOutputDeviceHandle device) { return device->features; }

View File

@@ -1,45 +0,0 @@
#pragma once
#include "stdint.h"
#include "utils/gryphn_string.h"
#include "gryphn_handles.h"
typedef enum gnDeviceType {
GN_DEDICATED_DEVICE, GN_INTEGRATED_DEVICE, GN_EXTERNAL_DEVICE
} gnDeviceType;
typedef enum gnMultisampleCountFlags {
GN_SAMPLE_BIT_1 = 1 << 0, // 0x01
GN_SAMPLE_BIT_2 = 1 << 1, // 0x02
GN_SAMPLE_BIT_4 = 1 << 2, // 0x04
GN_SAMPLE_BIT_8 = 1 << 3, // 0x08
GN_SAMPLE_BIT_16 = 1 << 4, // 0x10
GN_SAMPLE_BIT_32 = 1 << 5, // 0x20
GN_SAMPLE_BIT_64 = 1 << 6, // 0x40
} gnMultisampleCountFlags;
typedef struct gnPhysicalDeviceProperties {
gnString name;
gnDeviceType deviceType;
} gnPhysicalDeviceProperties;
typedef struct gnPhysicalDeviceFeatures {
gnMultisampleCountFlags maxColorSamples, maxDepthSamples;
uint32_t maxMemoryAllocations;
uint32_t maxPushConstantSize;
} gnPhysicalDeviceFeatures;
#ifdef GN_REVEAL_IMPL
typedef struct gnPhysicalOutputDevice_t {
struct gnPlatformPhysicalDevice_t* physicalDevice;
gnPhysicalDeviceProperties properties;
gnPhysicalDeviceFeatures features;
gnInstanceHandle instance;
} gnPhysicalOutputDevice_t;
#endif
gnPhysicalOutputDeviceHandle* gnGetPhyscialDevices(gnInstanceHandle instance, uint32_t* count);
gnBool gnPhysicalDeviceCanPresentToSurface(gnPhysicalOutputDeviceHandle device, gnWindowSurfaceHandle windowSurface);
gnPhysicalDeviceProperties gnGetPhysicalDeviceProperties(gnPhysicalOutputDeviceHandle device);
gnPhysicalDeviceFeatures gnGetPhysicalDeviceFeatures(gnPhysicalOutputDeviceHandle device);

View File

@@ -47,7 +47,7 @@ typedef struct gnScissor {
} gnScissor; } gnScissor;
typedef struct gnMultisample { typedef struct gnMultisample {
gnMultisampleCountFlags samples; gnSampleCountFlags samples;
} gnMultisample; } gnMultisample;
typedef enum gnFillMode { typedef enum gnFillMode {

View File

@@ -2,7 +2,7 @@
#include "stdint.h" #include "stdint.h"
#include "core/gryphn_image_format.h" #include "core/gryphn_image_format.h"
#include "core/gryphn_return_code.h" #include "core/gryphn_return_code.h"
#include "core/src/output_device/gryphn_physical_output_device.h" #include "core/src/output_device/gryphn_physical_device.h"
#include "gryphn_handles.h" #include "gryphn_handles.h"
typedef enum gnRenderPassStage { typedef enum gnRenderPassStage {
@@ -34,7 +34,7 @@ typedef struct gnRenderPassAttachmentInfo_t {
gnImageLayout initialLayout; gnImageLayout initialLayout;
gnImageLayout finalLayout; gnImageLayout finalLayout;
gnMultisampleCountFlags samples; gnSampleCountFlags samples;
} gnRenderPassAttachmentInfo; } gnRenderPassAttachmentInfo;
typedef struct gnSubpassAttachmentInfo_t { typedef struct gnSubpassAttachmentInfo_t {

View File

@@ -2,7 +2,7 @@
#include "core/gryphn_image_format.h" #include "core/gryphn_image_format.h"
#include "core/gryphn_return_code.h" #include "core/gryphn_return_code.h"
#include "utils/math/gryphn_vec3.h" #include "utils/math/gryphn_vec3.h"
#include "core/src/output_device/gryphn_physical_output_device.h" #include "core/src/output_device/gryphn_physical_device.h"
#include <gryphn_handles.h> #include <gryphn_handles.h>
typedef enum gnTextureType { typedef enum gnTextureType {
@@ -27,7 +27,7 @@ typedef enum gnTextureUsageFlags {
typedef struct gnTextureInfo { typedef struct gnTextureInfo {
gnExtent3D extent; gnExtent3D extent;
gnMultisampleCountFlags samples; gnSampleCountFlags samples;
gnTextureUsageFlags usage; gnTextureUsageFlags usage;
uint32_t mipmapLevels; uint32_t mipmapLevels;
gnTextureType type; gnTextureType type;

View File

@@ -16,4 +16,4 @@ typedef struct gnQueueFamilyProperties {
gnQueueTypeFlags queueTypeFlags; gnQueueTypeFlags queueTypeFlags;
} gnQueueFamilyProperties; } gnQueueFamilyProperties;
gnReturnCode gnGetPhysicalDeviceQueueProperties(gnPhysicalOutputDeviceHandle device, uint32_t queueCount, gnQueueFamilyProperties* queues); gnReturnCode gnGetPhysicalDeviceQueueProperties(gnPhysicalDeviceHandle device, uint32_t queueCount, gnQueueFamilyProperties* queues);

View File

@@ -10,7 +10,7 @@ typedef struct gnPresentInfo gnPresentInfo;
typedef struct gnPresentSyncInfo gnPresentSyncInfo; typedef struct gnPresentSyncInfo gnPresentSyncInfo;
typedef struct gnQueueExtFunctions { typedef struct gnQueueExtFunctions {
gnReturnCode (*_gnGetPhysicalDeviceQueueProperties)(gnPhysicalOutputDeviceHandle device, uint32_t queueCount, gnQueueFamilyProperties* queues); gnReturnCode (*_gnGetPhysicalDeviceQueueProperties)(gnPhysicalDeviceHandle device, uint32_t queueCount, gnQueueFamilyProperties* queues);
void (*_gnGetDeviceQueue)(gnOutputDevice device, uint32_t queueFamily, uint32_t queueIndex, gnQueue* queue); void (*_gnGetDeviceQueue)(gnOutputDevice device, uint32_t queueFamily, uint32_t queueIndex, gnQueue* queue);
gnReturnCode (*_gnQueueSubmit)(gnOutputDevice device, gnQueue queue, gnSubmitInfo info); gnReturnCode (*_gnQueueSubmit)(gnOutputDevice device, gnQueue queue, gnSubmitInfo info);

View File

@@ -8,7 +8,10 @@
typedef struct gnInstanceCreateInfo gnInstanceCreateInfo; typedef struct gnInstanceCreateInfo gnInstanceCreateInfo;
typedef struct gnSurfaceDetails gnSurfaceDetails; typedef struct gnSurfaceDetails gnSurfaceDetails;
typedef struct gnOutputDeviceInfo gnOutputDeviceInfo; typedef struct gnOutputDeviceInfo gnOutputDeviceInfo;
typedef enum gnSuitableField gnSuitableField;
typedef struct gnPhysicalDeviceProperties gnPhysicalDeviceProperties;
typedef struct gnPhysicalDeviceFeatures gnPhysicalDeviceFeatures;
typedef struct gnPhysicalDeviceLimits gnPhysicalDeviceLimits;
#ifdef GN_PLATFORM_LINUX #ifdef GN_PLATFORM_LINUX
#ifdef GN_WINDOW_X11 #ifdef GN_WINDOW_X11
@@ -20,12 +23,17 @@ typedef struct gnOutputDeviceInfo gnOutputDeviceInfo;
#endif #endif
typedef struct gryphnInstanceFunctionLayers gryphnInstanceFunctionLayers; typedef struct gryphnInstanceFunctionLayers gryphnInstanceFunctionLayers;
typedef gnReturnCode (*PFN_gnCreateInstance)(gnInstanceHandle instance, gnInstanceCreateInfo* info, gryphnInstanceFunctionLayers* next, gnAllocators* alloctors); typedef gnReturnCode (*PFN_gnCreateInstance)(gnInstanceHandle, gnInstanceCreateInfo*, gryphnInstanceFunctionLayers*, gnAllocators*);
typedef void (*PFN_gnDestroyInstance)(gnInstanceHandle instance, gryphnInstanceFunctionLayers* next, gnAllocators* alloctors); typedef gnBool (*PFN_gnIsInstanceSuitable)(gnInstanceHandle, gnSuitableField, gryphnInstanceFunctionLayers*);
typedef gnReturnCode (*PFN_gnInstanceQueryDevices)(gnInstanceHandle, uint32_t*, gnPhysicalDeviceHandle*, gryphnInstanceFunctionLayers*);
typedef void (*PFN_gnDestroyInstance)(gnInstanceHandle, gryphnInstanceFunctionLayers*, gnAllocators*);
typedef gnPhysicalDeviceProperties (*PFN_gnQueryPhysicalDeviceProperties)(gnInstance, gnPhysicalDeviceHandle, gryphnInstanceFunctionLayers*);
typedef gnPhysicalDeviceFeatures (*PFN_gnQueryPhysicalDeviceFeatures)(gnInstanceHandle, gnPhysicalDeviceHandle, gryphnInstanceFunctionLayers*);
typedef gnPhysicalDeviceLimits (*PFN_gnQueryPhysicalDeviceLimits)(gnInstanceHandle, gnPhysicalDeviceHandle, gryphnInstanceFunctionLayers*);
typedef struct gnInstanceFunctions { typedef struct gnInstanceFunctions {
gnPhysicalDevice* (*_gnGetPhysicalDevices)(gnInstanceHandle instance, uint32_t* count); gnBool (*_gnPhysicalDeviceCanPresentToSurface)(gnInstance instance, gnPhysicalDevice device, gnWindowSurfaceHandle windowSurface);
gnBool (*_gnPhysicalDeviceCanPresentToSurface)(gnPhysicalDevice device, gnWindowSurfaceHandle windowSurface);
gnReturnCode (*_gnCreateOutputDevice)(gnInstanceHandle instance, gnOutputDeviceHandle device, gnOutputDeviceInfo deviceInfo); gnReturnCode (*_gnCreateOutputDevice)(gnInstanceHandle instance, gnOutputDeviceHandle device, gnOutputDeviceInfo deviceInfo);
void (*_gnDestroyOutputDevice)(gnOutputDeviceHandle device); void (*_gnDestroyOutputDevice)(gnOutputDeviceHandle device);

View File

@@ -15,7 +15,12 @@ typedef struct gryphnFunctionLayer {
typedef struct gryphnInstanceFunctionLayers { typedef struct gryphnInstanceFunctionLayers {
PFN_gnCreateInstance createInstance; PFN_gnCreateInstance createInstance;
PFN_gnIsInstanceSuitable isSuitable;
PFN_gnInstanceQueryDevices queryDevices;
PFN_gnDestroyInstance destroyInstance; PFN_gnDestroyInstance destroyInstance;
PFN_gnQueryPhysicalDeviceProperties getPhysicalDeviceProperties;
PFN_gnQueryPhysicalDeviceFeatures getPhysicalDeviceFeatures;
PFN_gnQueryPhysicalDeviceLimits getPhysicalDeviceLimits;
struct gryphnInstanceFunctionLayers* next; struct gryphnInstanceFunctionLayers* next;
} gryphnInstanceFunctionLayers; } gryphnInstanceFunctionLayers;

View File

@@ -1,6 +1,6 @@
#include "queue_functions.h" #include "queue_functions.h"
#include "loader_utils.h" #include "loader_utils.h"
#include "core/src/output_device/gryphn_physical_output_device.h" #include "core/src/output_device/gryphn_physical_device.h"
#include "core/src/output_device/gryphn_output_device.h" #include "core/src/output_device/gryphn_output_device.h"
#include <core/src/instance/gryphn_debugger.h> #include <core/src/instance/gryphn_debugger.h>
#include <core/src/instance/gryphn_instance.h> #include <core/src/instance/gryphn_instance.h>
@@ -9,8 +9,9 @@
#include "extensions/synchronization/commands/gryphn_sync_submit.h" #include "extensions/synchronization/commands/gryphn_sync_submit.h"
#include "extensions/synchronization/commands/gryphn_sync_present.h" #include "extensions/synchronization/commands/gryphn_sync_present.h"
gnReturnCode checkGetPhysicalDeviceQueueProperties(gnPhysicalOutputDeviceHandle device, uint32_t queueCount, gnQueueFamilyProperties* queues) { gnReturnCode checkGetPhysicalDeviceQueueProperties(gnPhysicalDeviceHandle device, uint32_t queueCount, gnQueueFamilyProperties* queues) {
CHECK_FUNCTION_WITH_RETURN_CODE(device->instance, _gnGetPhysicalDeviceQueueProperties, queueFunctions, device, queueCount, queues); // CHECK_FUNCTION_WITH_RETURN_CODE(device->instance, _gnGetPhysicalDeviceQueueProperties, queueFunctions, device, queueCount, queues);
return GN_UNKNOWN_ERROR;
} }
void checkGetDeviceQueue(gnOutputDevice device, uint32_t queueFamily, uint32_t queueIndex, gnQueue* queue) { void checkGetDeviceQueue(gnOutputDevice device, uint32_t queueFamily, uint32_t queueIndex, gnQueue* queue) {
CHECK_VOID_FUNCTION(device->instance, _gnGetDeviceQueue, queueFunctions, device, queueFamily, queueIndex, queue); CHECK_VOID_FUNCTION(device->instance, _gnGetDeviceQueue, queueFunctions, device, queueFamily, queueIndex, queue);

View File

@@ -1,6 +1,6 @@
#include <loader/src/gryphn_loader.h> #include <loader/src/gryphn_loader.h>
gnReturnCode checkGetPhysicalDeviceQueueProperties(gnPhysicalOutputDeviceHandle device, uint32_t queueCount, gnQueueFamilyProperties* queues); gnReturnCode checkGetPhysicalDeviceQueueProperties(gnPhysicalDeviceHandle device, uint32_t queueCount, gnQueueFamilyProperties* queues);
void checkGetDeviceQueue(gnOutputDevice device, uint32_t queueFamily, uint32_t queueIndex, gnQueue* queue); void checkGetDeviceQueue(gnOutputDevice device, uint32_t queueFamily, uint32_t queueIndex, gnQueue* queue);
gnReturnCode checkQueueSubmit(gnOutputDevice device, gnQueue queue, gnSubmitInfo info); gnReturnCode checkQueueSubmit(gnOutputDevice device, gnQueue queue, gnSubmitInfo info);

View File

@@ -8,13 +8,18 @@
gryphnInstanceFunctionLayers checkerLoadInstanceFunctions(void) { gryphnInstanceFunctionLayers checkerLoadInstanceFunctions(void) {
return (gryphnInstanceFunctionLayers) { return (gryphnInstanceFunctionLayers) {
.createInstance = checkCreateInstance, .createInstance = checkCreateInstance,
.destroyInstance = checkDestroyInstance .isSuitable = checkIsInstanceSuitable,
.queryDevices = checkQueryDevices,
.destroyInstance = checkDestroyInstance,
.getPhysicalDeviceProperties = checkQueryPhysicalDeviceProperties,
.getPhysicalDeviceFeatures = checkQueryPhysicalDeviceFeatures,
.getPhysicalDeviceLimits = checkQueryPhysicalDeviceLimits,
.next = GN_NULL_HANDLE
}; };
} }
gnInstanceFunctions loadFunctionLoaderInstanceFunctions(void) { gnInstanceFunctions loadFunctionLoaderInstanceFunctions(void) {
return (gnInstanceFunctions){ return (gnInstanceFunctions){
._gnGetPhysicalDevices = checkGetPhysicalDevices,
._gnPhysicalDeviceCanPresentToSurface = checkCanDevicePresent, ._gnPhysicalDeviceCanPresentToSurface = checkCanDevicePresent,
._gnCreateOutputDevice = checkCreateOutputDevice, ._gnCreateOutputDevice = checkCreateOutputDevice,

View File

@@ -24,11 +24,61 @@ void checkDestroyInstance(gnInstanceHandle instance, gryphnInstanceFunctionLayer
next->destroyInstance(instance, next->next, alloctors); next->destroyInstance(instance, next->next, alloctors);
} }
gnPhysicalDevice* checkGetPhysicalDevices(gnInstanceHandle instance, uint32_t* count) { gnBool checkIsInstanceSuitable(gnInstanceHandle instance, gnSuitableField field, gryphnInstanceFunctionLayers* next) {
CHECK_RETURNED_FUNCTION(instance, _gnGetPhysicalDevices, instanceFunctions, NULL, instance, count); if (next == NULL || next->isSuitable == NULL) {
gnDebuggerSetErrorMessage(instance->debugger, (gnMessageData){
.message = gnCreateString("Failed to load gnIsInstanceSuitable this indicates a bug within gryphn")
});
return GN_FAILED_TO_LOAD_FUNCTION;
} }
gnBool checkCanDevicePresent(gnPhysicalDevice device, gnWindowSurfaceHandle windowSurface) { return next->isSuitable(instance, field, next);
CHECK_RETURNED_FUNCTION(device->instance, _gnPhysicalDeviceCanPresentToSurface, instanceFunctions, GN_FALSE, device, windowSurface); }
gnReturnCode checkQueryDevices(gnInstanceHandle instance, uint32_t* count, gnPhysicalDeviceHandle* devices, gryphnInstanceFunctionLayers* next) {
if (next == NULL || next->queryDevices == NULL) {
gnDebuggerSetErrorMessage(instance->debugger, (gnMessageData){
.message = gnCreateString("Failed to load gnQueryDevices this indicates a bug within gryphn")
});
return GN_FAILED_TO_LOAD_FUNCTION;
}
return next->queryDevices(instance, count, devices, next->next);
}
gnPhysicalDeviceProperties checkQueryPhysicalDeviceProperties(gnInstanceHandle instance, gnPhysicalDeviceHandle device, gryphnInstanceFunctionLayers* next) {
if (next == NULL || next->getPhysicalDeviceProperties == NULL) {
gnDebuggerSetErrorMessage(instance->debugger, (gnMessageData){
.message = gnCreateString("Failed to load gnQueryPhysicalDeviceProperties this indicates a bug within gryphn")
});
return (gnPhysicalDeviceProperties){
.deviceID = -1,
.deviceName = gnCreateString("Invalid device"),
.deviceType = GN_PHYSICAL_DEVICE_TYPE_FAKED_GPU,
.driverVersion = -1
};
}
return next->getPhysicalDeviceProperties(instance, device, next->next);
}
gnPhysicalDeviceFeatures checkQueryPhysicalDeviceFeatures(gnInstanceHandle instance, gnPhysicalDeviceHandle device, gryphnInstanceFunctionLayers* next) {
if (next == NULL || next->getPhysicalDeviceFeatures == NULL) {
gnDebuggerSetErrorMessage(instance->debugger, (gnMessageData){
.message = gnCreateString("Failed to load gnQueryPhysicalDeviceFeatures this indicates a bug within gryphn")
});
return (gnPhysicalDeviceFeatures){};
}
return next->getPhysicalDeviceFeatures(instance, device, next->next);
}
gnPhysicalDeviceLimits checkQueryPhysicalDeviceLimits(gnInstanceHandle instance, gnPhysicalDeviceHandle device, gryphnInstanceFunctionLayers* next) {
if (next == NULL || next->getPhysicalDeviceLimits == NULL) {
gnDebuggerSetErrorMessage(instance->debugger, (gnMessageData){
.message = gnCreateString("Failed to load gnQueryPhysicalDeviceLimits this indicates a bug within gryphn")
});
return (gnPhysicalDeviceLimits){};
}
return next->getPhysicalDeviceLimits(instance, device, next->next);
}
gnBool checkCanDevicePresent(gnInstance instance, gnPhysicalDevice device, gnWindowSurfaceHandle windowSurface) {
CHECK_RETURNED_FUNCTION(instance, _gnPhysicalDeviceCanPresentToSurface, instanceFunctions, GN_FALSE, instance, device, windowSurface);
} }
gnReturnCode checkCreateOutputDevice(gnInstanceHandle instance, gnOutputDeviceHandle device, gnOutputDeviceInfo deviceInfo) { gnReturnCode checkCreateOutputDevice(gnInstanceHandle instance, gnOutputDeviceHandle device, gnOutputDeviceInfo deviceInfo) {

View File

@@ -3,11 +3,16 @@
#include <core/src/window_surface/gryphn_surface_create_functions.h> #include <core/src/window_surface/gryphn_surface_create_functions.h>
gnReturnCode checkCreateInstance(gnInstanceHandle instance, gnInstanceCreateInfo* info, gryphnInstanceFunctionLayers* next, gnAllocators* alloctors); gnReturnCode checkCreateInstance(gnInstanceHandle instance, gnInstanceCreateInfo* info, gryphnInstanceFunctionLayers* next, gnAllocators* alloctors);
gnBool checkIsInstanceSuitable(gnInstanceHandle instance, gnSuitableField field, gryphnInstanceFunctionLayers* next);
gnReturnCode checkQueryDevices(gnInstanceHandle instance, uint32_t* count, gnPhysicalDeviceHandle* devices, gryphnInstanceFunctionLayers* next);
void checkDestroyInstance(gnInstanceHandle instance, gryphnInstanceFunctionLayers* next, gnAllocators* alloctors); void checkDestroyInstance(gnInstanceHandle instance, gryphnInstanceFunctionLayers* next, gnAllocators* alloctors);
gnPhysicalDevice* checkGetPhysicalDevices(gnInstanceHandle instance, uint32_t* count); gnPhysicalDeviceProperties checkQueryPhysicalDeviceProperties(gnInstanceHandle instance, gnPhysicalDeviceHandle device, gryphnInstanceFunctionLayers* next);
gnBool checkCanDevicePresent(gnPhysicalDevice device, gnWindowSurfaceHandle windowSurface); gnPhysicalDeviceFeatures checkQueryPhysicalDeviceFeatures(gnInstanceHandle instance, gnPhysicalDeviceHandle device, gryphnInstanceFunctionLayers* next);
gnPhysicalDeviceLimits checkQueryPhysicalDeviceLimits(gnInstanceHandle instance, gnPhysicalDeviceHandle device, gryphnInstanceFunctionLayers* next);
// old ahh functions (currently working on removing)
gnBool checkCanDevicePresent(gnInstance instance, gnPhysicalDevice device, gnWindowSurfaceHandle windowSurface);
gnReturnCode checkCreateOutputDevice(gnInstanceHandle instance, gnOutputDeviceHandle device, gnOutputDeviceInfo deviceInfo); gnReturnCode checkCreateOutputDevice(gnInstanceHandle instance, gnOutputDeviceHandle device, gnOutputDeviceInfo deviceInfo);
void checkDestroyOutputDevice(gnOutputDeviceHandle device); void checkDestroyOutputDevice(gnOutputDeviceHandle device);