Compare commits
87 Commits
70f8d5f31d
...
master
Author | SHA1 | Date | |
---|---|---|---|
![]() |
5228b6630c | ||
![]() |
5ce0ff3350 | ||
![]() |
63ec31216e | ||
![]() |
ebc6ce724f | ||
![]() |
3a5ddac2c5 | ||
![]() |
f93853608c | ||
![]() |
481f590234 | ||
![]() |
d79a3c45bf | ||
![]() |
3bf252d582 | ||
![]() |
228d75e5ac | ||
![]() |
3066f7c2bd | ||
![]() |
427f0ee5b1 | ||
![]() |
4b981055bd | ||
![]() |
1095e20dc2 | ||
![]() |
a0450a0351 | ||
![]() |
c495a7a0e8 | ||
![]() |
eef7045ac2 | ||
![]() |
7ace503ab0 | ||
![]() |
6f278affc6 | ||
![]() |
f7e71b77c2 | ||
![]() |
88bdbe1e64 | ||
![]() |
17b7970aa0 | ||
![]() |
ef53ffd458 | ||
![]() |
a446d6e75f | ||
![]() |
0310652abc | ||
![]() |
88649174a9 | ||
![]() |
9244b82f79 | ||
![]() |
c5297cb17b | ||
![]() |
a709ff8808 | ||
![]() |
76a787d48f | ||
![]() |
1e8855905d | ||
![]() |
809750749a | ||
![]() |
4d904557d8 | ||
![]() |
263a8e54fa | ||
![]() |
5422fd8b68 | ||
![]() |
0c89bdb791 | ||
![]() |
c7ae6532fd | ||
![]() |
18ec089ebc | ||
![]() |
0c0988b75a | ||
![]() |
01de997df5 | ||
![]() |
380c5d056f | ||
![]() |
f5d7257e66 | ||
![]() |
16d2e7b8fc | ||
![]() |
7f6ec430de | ||
![]() |
50d8a669b3 | ||
![]() |
55605b6d5f | ||
![]() |
740cf1e628 | ||
![]() |
453f7b70db | ||
![]() |
51bd6e28fa | ||
![]() |
7b1266281c | ||
![]() |
be2f91e2bb | ||
![]() |
d1862e3d6f | ||
![]() |
10cd374731 | ||
![]() |
4477c41dc4 | ||
![]() |
916df68f06 | ||
![]() |
5db32f367a | ||
![]() |
2e02bbf799 | ||
![]() |
8658c7646f | ||
![]() |
c99a4cdb31 | ||
![]() |
f045793322 | ||
![]() |
5213e0135a | ||
![]() |
e973386511 | ||
![]() |
cb55a7716f | ||
![]() |
97a70e911d | ||
![]() |
2f1db4043a | ||
![]() |
eb11649a03 | ||
![]() |
026fc52d7c | ||
![]() |
f4e448177b | ||
![]() |
6c6037b76f | ||
![]() |
8fc99079dc | ||
![]() |
5b43e3d5be | ||
![]() |
362efd8920 | ||
![]() |
d48332fdcd | ||
![]() |
f251613d77 | ||
![]() |
bb416aca61 | ||
![]() |
9d4dfd85fc | ||
![]() |
3f7b0737d7 | ||
![]() |
23f46385fe | ||
![]() |
f6484ddde5 | ||
![]() |
adf72d6436 | ||
![]() |
c51c29f7a4 | ||
![]() |
317ffda9e7 | ||
![]() |
1846bdbf26 | ||
![]() |
eeb2896a26 | ||
![]() |
50e84d9802 | ||
![]() |
45cceff843 | ||
![]() |
dbf90882bf |
9
.gitmodules
vendored
9
.gitmodules
vendored
@@ -1,6 +1,9 @@
|
||||
[submodule "projects/utils"]
|
||||
path = projects/utils
|
||||
url = https://github.com/GregoryWells2007/GryphnUtils.git
|
||||
[submodule "projects/apis/metal/depends/SPIRV-Cross"]
|
||||
path = projects/apis/metal/depends/SPIRV-Cross
|
||||
url = https://github.com/KhronosGroup/SPIRV-Cross.git
|
||||
[submodule "projects/utils"]
|
||||
path = projects/utils
|
||||
url = https://git.astraltech.xyz/AstralTech/Gryphn-Utils.git
|
||||
[submodule "projects/apis/opengl/depends/SPIRV-Cross"]
|
||||
path = projects/apis/opengl/depends/SPIRV-Cross
|
||||
url = https://github.com/KhronosGroup/SPIRV-Cross.git
|
||||
|
@@ -9,9 +9,8 @@ Gryphn works to abstract away platform API functions (Vulkan, Metal, D3D11/D3D12
|
||||
- [x] Metal
|
||||
- [ ] Direct 3D 11
|
||||
- [ ] Direct 3D 12
|
||||
- [ ] OpenGL
|
||||
- [x] OpenGL
|
||||
- [ ] Software
|
||||
* Currently working on the OpenGL backend
|
||||
|
||||
# Features
|
||||
#### Application objects
|
||||
@@ -63,6 +62,7 @@ Gryphn validation layers are meant to be more specific so there are certain ones
|
||||
#### Supported layers: <br />
|
||||
- GN_DEBUGGER_LAYER_PLATFORM, this only does anything on vulkan for the time being, metal currently doesnt allow you to disable its validation but that API has a lot more problems when working with it so im fine with that for the time being, it will do things like enable vulkan validation layers or it will also allow the APIs to load there specific validation layers
|
||||
- GN_DEBUGGER_LAYER_FUNCTIONS, this is more for my own sake but when I am writing new backends or layers I may tend to forget to implement a specific function so this layer will just check to make sure that every function is loaded properly.
|
||||
- GN_DEBUGGER_LAYER_ALLOCATORS, this layer will override all Gryphn allocation calls and provide a debug message telling the user an allocation has occured, gryphn will also keep track of all internal allocations and log when certain allocations are not being deallocated, NOTE: these are bugs in Gryphn, where a heap allocated array is never freed unless the programmer has not called the appropriate gnDestroyXXX function.
|
||||
# Plans
|
||||
#### 1.0 Spec <br />
|
||||
Gryphn is getting to the point where I can't keep developing it in the same way I have in the past where I just implement functions and features based on when I need them so slowly over the coming weeks I want to have a true spec written down for every function, that its expected results are, what its functionality does, and just go back and look at every line of code. The spec is going to be based on what I have right now with a few modifacations and also I would like to add more features.
|
||||
@@ -97,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
|
||||
|
@@ -3,7 +3,7 @@
|
||||
|
||||
// core functionality
|
||||
#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_create_functions.h>
|
||||
#include <core/src/presentation_queue/gryphn_presentation_queue.h>
|
||||
|
@@ -3,7 +3,7 @@ set(CMAKE_CXX_STANDARD 17)
|
||||
project(GryphnMetalImpl)
|
||||
|
||||
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
|
||||
"loader/*.m"
|
||||
|
@@ -6,14 +6,16 @@
|
||||
gryphnInstanceFunctionLayers metalLoadAPILayer(void) {
|
||||
return (gryphnInstanceFunctionLayers) {
|
||||
.createInstance = metalCreateInstance,
|
||||
.queryDevices = metalQueryDevices,
|
||||
.destroyInstance = metalDestroyInstance,
|
||||
.isSuitable = metalIsInstanceSuitable,
|
||||
.getPhysicalDeviceProperties = metalQueryPhysicalDeviceProperties,
|
||||
.next = NULL
|
||||
};
|
||||
}
|
||||
|
||||
gnInstanceFunctions loadMetalInstanceFunctions(void) {
|
||||
return (gnInstanceFunctions){
|
||||
._gnGetPhysicalDevices = getMetalDevices,
|
||||
._gnPhysicalDeviceCanPresentToSurface = metalCanDevicePresent,
|
||||
._gnCreateOutputDevice = createMetalOutputDevice,
|
||||
._gnDestroyOutputDevice = destroyMetalOutputDevice,
|
||||
|
@@ -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_output_devices.h"
|
||||
#include "instance/metal_instance.h"
|
||||
@@ -10,7 +10,7 @@ gnReturnCode createMetalOutputDevice(gnInstanceHandle instance, gnOutputDeviceHa
|
||||
if (instance == GN_NULL_HANDLE) return GN_INVALID_HANDLE;
|
||||
|
||||
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->stagingBuffer = [outputDevice->outputDevice->device newBufferWithLength:(128 * 1024 * 1024) options:MTLResourceStorageModeShared];
|
||||
|
@@ -4,9 +4,8 @@
|
||||
#include <Metal/Metal.h>
|
||||
#include <MetalKit/MetalKit.h>
|
||||
|
||||
struct gnPlatformPhysicalDevice_t {
|
||||
id<MTLDevice> device;
|
||||
} gnPlatformPhysicalDevice;
|
||||
typedef id<MTLDevice> mtlDevice;
|
||||
gnPhysicalDeviceProperties metalQueryPhysicalDeviceProperties(gnInstance instance, gnPhysicalDeviceHandle device, gryphnInstanceFunctionLayers* layers);
|
||||
|
||||
struct gnPlatformOutputDevice_t {
|
||||
id<MTLDevice> device;
|
||||
@@ -24,7 +23,7 @@ struct gnPlatformOutputDevice_t {
|
||||
} gnPlatformOutputDevice;
|
||||
|
||||
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);
|
||||
void waitForMetalDevice(gnOutputDeviceHandle device);
|
||||
|
@@ -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_output_devices.h"
|
||||
#include "window_surface/gryphn_surface.h"
|
||||
|
||||
gnPhysicalDevice* getMetalDevices(gnInstanceHandle instance, uint32_t* deviceCount) {
|
||||
if (instance == GN_NULL_HANDLE) return NULL;
|
||||
|
||||
NSArray *devices = MTLCopyAllDevices();
|
||||
*deviceCount = (uint32_t)[devices count];
|
||||
gnPhysicalDevice* devicesList = (gnPhysicalDevice*)malloc(sizeof(gnPhysicalDevice) * *deviceCount);
|
||||
for (uint32_t i = 0; i < *deviceCount; i++) {
|
||||
devicesList[i] = malloc(sizeof(gnPhysicalOutputDevice_t));
|
||||
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;
|
||||
// i made some educated guesses on these conversions and I dont think they are going to work
|
||||
// but for now im worried about the MVP
|
||||
gnPhysicalDeviceType metalDeviceLocationToGryphn(MTLDeviceLocation location) {
|
||||
switch (location) {
|
||||
case MTLDeviceLocationBuiltIn: return GN_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU;
|
||||
case MTLDeviceLocationSlot: return GN_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU;
|
||||
case MTLDeviceLocationExternal: return GN_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU;
|
||||
case MTLDeviceLocationUnspecified: return GN_PHYSICAL_DEVICE_TYPE_FAKED_GPU; //very bad if we get here
|
||||
}
|
||||
[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;
|
||||
|
||||
return GN_TRUE; // I belive that a window should always be able to present to a surface in metal
|
||||
}
|
||||
|
@@ -8,4 +8,6 @@ typedef struct gnPlatformInstance_t {
|
||||
} gnPlatformInstance;
|
||||
|
||||
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);
|
||||
|
@@ -8,6 +8,20 @@ gnReturnCode metalCreateInstance(gnInstanceHandle instance, gnInstanceCreateInfo
|
||||
instance->instance = allocators->malloc(sizeof(gnPlatformInstance), allocators->userData);
|
||||
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) {
|
||||
if (next != NULL) return;
|
||||
allocators->free(instance->instance, allocators->userData);
|
||||
|
@@ -22,8 +22,6 @@ typedef struct gnPlatformRenderPassDescriptor_t {
|
||||
uint32_t subpassCount;
|
||||
mtlSubpass* subpasses;
|
||||
mtlSubpassCopyInfo* copyInfos;
|
||||
|
||||
|
||||
} gnPlatformRenderPassDescriptor;
|
||||
|
||||
gnReturnCode createMetalRenderPass(gnRenderPassDescriptor renderPass, gnDevice device, gnRenderPassDescriptorInfo info);
|
||||
|
@@ -1,5 +1,6 @@
|
||||
#include "metal_shader_compiler.h"
|
||||
#include "spirv_msl.hpp"
|
||||
#include "stdlib.h"
|
||||
// #include "iostream"
|
||||
|
||||
typedef struct mtlCompiler_t {
|
||||
@@ -43,10 +44,10 @@ GN_CPP_FUNCTION const char* mtlCompilerShader(mtlCompiler compiler, gnUniformLay
|
||||
for (size_t c = 0; c < uniformLayout->sets[i].uniformBindingCount; c++) {
|
||||
gnUniformBinding gryphnBinding = uniformLayout->sets[i].uniformBindings[c];
|
||||
spirv_cross::MSLResourceBinding binding = {
|
||||
.stage = (compiler->stage == mtlVertex) ? spv::ExecutionModelVertex : spv::ExecutionModelFragment,
|
||||
.desc_set = ((uint32_t)i + 1),
|
||||
.binding = gryphnBinding.binding,
|
||||
.count = 1,
|
||||
.desc_set = ((uint32_t)i + 1),
|
||||
.stage = (compiler->stage == mtlVertex) ? spv::ExecutionModelVertex : spv::ExecutionModelFragment,
|
||||
};
|
||||
if (gryphnBinding.type == GN_COMBINED_IMAGE_SAMPLER_DESCRIPTOR) {
|
||||
binding.msl_texture = currentBinding;
|
@@ -1,17 +1,11 @@
|
||||
#pragma once
|
||||
#include "stdint.h"
|
||||
#include "stdlib.h"
|
||||
#include "utils/gryphn_bool.h"
|
||||
#include "utils/gryphn_cpp_function.h"
|
||||
#include <core/src/uniforms/gryphn_uniform_layout.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
#define GN_CPP_FUNCTION extern "C"
|
||||
#else
|
||||
#define GN_CPP_FUNCTION
|
||||
#endif
|
||||
|
||||
#define MAX_METAL_SETS 32
|
||||
#define MAX_METAL_BINDINGS 16
|
||||
#define MAX_METAL_SETS 16
|
||||
#define MAX_METAL_BINDINGS 32
|
||||
|
||||
typedef struct mtlCompiler_t* mtlCompiler;
|
||||
|
||||
@@ -31,33 +25,3 @@ typedef struct mtlCompilerInfo {
|
||||
|
||||
GN_CPP_FUNCTION mtlCompiler mtlCreateCompiler(mtlCompilerInfo* info);
|
||||
GN_CPP_FUNCTION const char* mtlCompilerShader(mtlCompiler compiler, gnUniformLayout* uniformLayout);
|
||||
|
||||
// typedef struct mtlShaderOptions {
|
||||
// gnBool useArgumentBuffers;
|
||||
// mtlShaderModuleStage stage;
|
||||
// const char* entryPoint;
|
||||
// } mtlShaderOptions;
|
||||
|
||||
// typedef struct mtlBinding {
|
||||
// uint32_t spvBinding;
|
||||
// uint32_t metalID;
|
||||
// } mtlBinding;
|
||||
|
||||
// typedef struct mtlSetMap {
|
||||
// uint32_t setIndex, mtlSetIndex;
|
||||
// mtlBinding bindings[MAX_METAL_BINDINGS];
|
||||
// } mtlSetMap;
|
||||
|
||||
// typedef struct mtlShaderMap {
|
||||
// mtlSetMap sets[MAX_METAL_SETS];
|
||||
// } mtlShaderMap;
|
||||
|
||||
// typedef struct mtlShader {
|
||||
// const char* code;
|
||||
// mtlShaderMap map;
|
||||
// } mtlShader;
|
||||
|
||||
// #ifdef __cplusplus
|
||||
// extern "C"
|
||||
// #endif
|
||||
// mtlShader mtlCompileShader(uint32_t* code, size_t wordCount, mtlShaderOptions* options);
|
||||
|
@@ -41,8 +41,9 @@ gnSurfaceDetails getMetalSurfaceDetails(
|
||||
MTLPixelFormat mtlGryphnFormatToMetalFormat(gnImageFormat format) {
|
||||
switch (format) {
|
||||
case GN_FORMAT_NONE: return MTLPixelFormatInvalid;
|
||||
case GN_FORMAT_BGRA8_SRGB: return MTLPixelFormatBGRA8Unorm_sRGB;
|
||||
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_D24S8_UINT: return MTLPixelFormatDepth24Unorm_Stencil8;
|
||||
case GN_FORMAT_D32S8_UINT: return MTLPixelFormatDepth32Float_Stencil8;
|
||||
|
@@ -13,4 +13,4 @@ void metalTextureData(gnTextureHandle texture, void* pixelData);
|
||||
void metalDestroyTexture(gnTexture texture);
|
||||
|
||||
|
||||
NSUInteger mtlSampleCount(gnMultisampleCountFlags flags);
|
||||
NSUInteger mtlSampleCount(gnSampleCountFlags flags);
|
||||
|
@@ -2,7 +2,7 @@
|
||||
#include "surface/metal_surface.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_32) == GN_SAMPLE_BIT_32) { return 32; }
|
||||
if ((flags & GN_SAMPLE_BIT_16) == GN_SAMPLE_BIT_16) { return 16; }
|
||||
|
@@ -3,7 +3,7 @@ set(CMAKE_CXX_STANDARD 17)
|
||||
project(GryphnOpenGLImpl)
|
||||
|
||||
file(GLOB_RECURSE SOURCE_FILES CONFIGURE_DEPENDS
|
||||
"src/*.c"
|
||||
"src/*.c" "src/*.cpp"
|
||||
)
|
||||
file(GLOB_RECURSE LOADER_FILES CONFIGURE_DEPENDS
|
||||
"loader/*.c"
|
||||
@@ -19,8 +19,9 @@ target_include_directories(GryphnOpenGLImpl PUBLIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../../include/
|
||||
)
|
||||
add_subdirectory(depends/SPIRV-Cross)
|
||||
target_include_directories(GryphnOpenGLImpl PRIVATE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/depends/glad/include/
|
||||
)
|
||||
add_compile_definitions(GN_REVEAL_IMPL)
|
||||
target_link_libraries(GryphnOpenGLImpl GL "X11")
|
||||
target_link_libraries(GryphnOpenGLImpl GL "X11" spirv-cross-core spirv-cross-glsl spirv-cross-cpp)
|
||||
|
1
projects/apis/opengl/depends/SPIRV-Cross
Submodule
1
projects/apis/opengl/depends/SPIRV-Cross
Submodule
Submodule projects/apis/opengl/depends/SPIRV-Cross added at 7fde3539c7
27
projects/apis/opengl/loader/opengl_commands_loader.c
Normal file
27
projects/apis/opengl/loader/opengl_commands_loader.c
Normal file
@@ -0,0 +1,27 @@
|
||||
#include "opengl_loader.h"
|
||||
#include "commands/buffers/opengl_command_buffer.h"
|
||||
#include "commands/commands/opengl_commands.h"
|
||||
|
||||
gnCommandFunctions loadOpenGLCommandFunctions() {
|
||||
return (gnCommandFunctions) {
|
||||
._gnCommandPoolAllocateCommandBuffers = openglCommandPoolAllocateCommandBuffers,
|
||||
|
||||
._gnBeginCommandBuffer = openglBeginCommandBuffer,
|
||||
._gnResetCommandBuffer = openglResetCommandBuffer,
|
||||
._gnEndCommandBuffer = openglEndCommandBuffer,
|
||||
._gnDestroyCommandBuffer = openglDestroyCommandBuffer,
|
||||
|
||||
._gnCommandBeginRenderPass = openglBeginRenderPass,
|
||||
._gnCommandEndRenderPass = openglEndRenderPass,
|
||||
|
||||
._gnCommandBindGraphicsPipeline = openglBindGraphicsPipeline,
|
||||
._gnCommandSetViewport = openglSetViewport,
|
||||
._gnCommandSetScissor = openglSetScissor,
|
||||
._gnCommandBindUniform = openglBindUniform,
|
||||
._gnCommandPushConstant = openglPushConstant,
|
||||
|
||||
._gnCommandBindBuffer = openglBindBuffer,
|
||||
._gnCommandDraw = openglDraw,
|
||||
._gnCommandDrawIndexed = openglDrawIndexed,
|
||||
};
|
||||
}
|
@@ -1,6 +1,17 @@
|
||||
#include "opengl_loader.h"
|
||||
#include "device/opengl_output_device.h"
|
||||
#include "presentation_queue/opengl_presentation_queue.h"
|
||||
#include "shaders/opengl_shader_module.h"
|
||||
#include "renderpass/opengl_render_pass_descriptor.h"
|
||||
#include "uniforms/pool/opengl_uniform_pool.h"
|
||||
#include "uniforms/uniform/opengl_uniform.h"
|
||||
#include "commands/pool/opengl_command_pool.h"
|
||||
#include "buffer/opengl_buffer.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() {
|
||||
return (gnDeviceFunctions){
|
||||
@@ -8,41 +19,42 @@ gnDeviceFunctions loadOpenGLDeviceFunctions() {
|
||||
._gnPresentationQueueGetImage = getOpenGLPresentationQueueImage,
|
||||
._gnDestroyPresentationQueue = destroyOpenGLPresentationQueue,
|
||||
|
||||
._gnCreateShaderModule = NULL,
|
||||
._gnDestroyShaderModule = NULL,
|
||||
._gnCreateShaderModule = openglCreateShaderModule,
|
||||
._gnDestroyShaderModule = openglDestroyShaderModule,
|
||||
|
||||
._gnCreateRenderPassDescriptor = NULL,
|
||||
._gnDestroyRenderPassDescriptor = NULL,
|
||||
._gnCreateRenderPassDescriptor = openglCreateRenderPass,
|
||||
._gnDestroyRenderPassDescriptor = openglDestroyRenderPass,
|
||||
|
||||
._gnCreateGraphicsPipeline = NULL,
|
||||
._gnDestroyGraphicsPipeline = NULL,
|
||||
._gnCreateGraphicsPipeline = openglCreateGraphicsPipeline,
|
||||
._gnDestroyGraphicsPipeline = openglDestroyGraphicsPipeline,
|
||||
|
||||
._gnCreateFramebuffer = NULL,
|
||||
._gnDestroyFramebuffer = NULL,
|
||||
._gnCreateFramebuffer = openglCreateFramebuffer,
|
||||
._gnDestroyFramebuffer = openglDestroyFramebuffer,
|
||||
|
||||
._gnCreateCommandPool = NULL,
|
||||
._gnDestroyCommandPool = NULL,
|
||||
._gnCreateCommandPool = openglCreateCommandPool,
|
||||
._gnDestroyCommandPool = openglDestroyCommandPool,
|
||||
|
||||
._gnCreateBuffer = NULL,
|
||||
._gnBufferData = NULL,
|
||||
._gnBufferSubData = NULL,
|
||||
._gnMapBuffer = NULL,
|
||||
._gnDestroyBuffer = NULL,
|
||||
._gnCreateBuffer = openglCreateBuffer,
|
||||
._gnBufferData = openglBufferData,
|
||||
._gnBufferSubData = openglBufferSubData,
|
||||
._gnMapBuffer = openglMapBuffer,
|
||||
._gnUnmapBuffer = openglUnmapBuffer,
|
||||
._gnDestroyBuffer = openglDestroyBuffer,
|
||||
|
||||
._gnCreateUniformPool = NULL,
|
||||
._gnUniformPoolAllocateUniforms = NULL,
|
||||
._gnDestroyUniformPool = NULL,
|
||||
._gnCreateUniformPool = openglCreateUniformPool,
|
||||
._gnUniformPoolAllocateUniforms = openglAllocateUniforms,
|
||||
._gnDestroyUniformPool = openglDestroyUniformPool,
|
||||
|
||||
._gnUpdateBufferUniform = NULL,
|
||||
._gnUpdateStorageUniform = NULL,
|
||||
._gnUpdateImageUniform = NULL,
|
||||
._gnUpdateBufferUniform = openglUpdateBufferUniform,
|
||||
._gnUpdateStorageUniform = openglUpdateStorageUniform,
|
||||
._gnUpdateImageUniform = openglUpdateImageUniform,
|
||||
|
||||
._gnCreateTexture = NULL,
|
||||
._gnTextureData = NULL,
|
||||
._gnDestroyTexture = NULL,
|
||||
._gnCreateTexture = openglCreateTexture,
|
||||
._gnTextureData = openglTextureData,
|
||||
._gnDestroyTexture = openglDestroyTexture,
|
||||
|
||||
._gnSubmit = NULL,
|
||||
._gnPresent = NULL,
|
||||
._gnSubmit = openglSubmit,
|
||||
._gnPresent = openglPresent,
|
||||
|
||||
._gnWaitForDevice = waitForOpenGLDevice
|
||||
};
|
||||
|
38
projects/apis/opengl/src/buffer/opengl_buffer.c
Normal file
38
projects/apis/opengl/src/buffer/opengl_buffer.c
Normal file
@@ -0,0 +1,38 @@
|
||||
#include "opengl_buffer.h"
|
||||
#include "string.h"
|
||||
|
||||
GLenum gnBufferTypeToGLEnum(gnBufferType type) {
|
||||
switch (type) {
|
||||
case GN_VERTEX_BUFFER: return GL_ARRAY_BUFFER;
|
||||
case GN_INDEX_BUFFER: return GL_ELEMENT_ARRAY_BUFFER;
|
||||
case GN_UNIFORM_BUFFER: return GL_UNIFORM_BUFFER;
|
||||
case GN_STORAGE_BUFFER: return GL_SHADER_STORAGE_BUFFER;
|
||||
}
|
||||
}
|
||||
|
||||
gnReturnCode openglCreateBuffer(gnBufferHandle buffer, gnDevice device, gnBufferInfo info) {
|
||||
buffer->buffer = malloc(sizeof(gnPlatformBuffer));
|
||||
glCreateBuffers(1, &buffer->buffer->id);
|
||||
buffer->buffer->type = gnBufferTypeToGLEnum(info.type);
|
||||
buffer->buffer->usage = (info.usage == GN_DYNAMIC_DRAW) ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW;
|
||||
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;
|
||||
}
|
||||
void openglBufferData(gnBufferHandle buffer, size_t dataSize, void* data) {
|
||||
openglBufferSubData(buffer, 0, dataSize, data);
|
||||
}
|
||||
#include "stdio.h"
|
||||
void openglBufferSubData(gnBufferHandle buffer, size_t offset, size_t dataSize, gnBufferMemory 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) {
|
||||
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) {
|
||||
glUnmapNamedBuffer(buffer->buffer->id);
|
||||
}
|
||||
void openglDestroyBuffer(gnBufferHandle buffer) {
|
||||
glDeleteBuffers(1, &buffer->buffer->id);
|
||||
}
|
19
projects/apis/opengl/src/buffer/opengl_buffer.h
Normal file
19
projects/apis/opengl/src/buffer/opengl_buffer.h
Normal file
@@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
#include "core/src/buffers/gryphn_buffer.h"
|
||||
#include "glad/glad.h"
|
||||
#include "utils/gryphn_cpp_function.h"
|
||||
|
||||
typedef struct gnPlatformBuffer_t {
|
||||
GLuint id;
|
||||
GLenum type, usage;
|
||||
} gnPlatformBuffer;
|
||||
|
||||
gnReturnCode openglCreateBuffer(gnBufferHandle buffer, gnDevice device, gnBufferInfo info);
|
||||
void openglBufferData(gnBufferHandle buffer, size_t dataSize, void* data);
|
||||
void openglBufferSubData(gnBufferHandle buffer, size_t offset, size_t dataSize, gnBufferMemory data);
|
||||
void* openglMapBuffer(gnBufferHandle buffer);
|
||||
void openglUnmapBuffer(gnBufferHandle buffer);
|
||||
void openglDestroyBuffer(gnBufferHandle buffer);
|
||||
|
||||
|
||||
GN_CPP_FUNCTION GLenum gnBufferTypeToGLEnum(gnBufferType type);
|
@@ -0,0 +1,48 @@
|
||||
#include "opengl_command_buffer.h"
|
||||
#include "commands/pool/opengl_command_pool.h"
|
||||
|
||||
gnReturnCode openglCommandPoolAllocateCommandBuffers(gnCommandBufferHandle* commandBuffers, uint32_t count, gnCommandPoolHandle pool) {
|
||||
for (int i = 0; i < count; i++) {
|
||||
gnBool wasAbleToAllocate = GN_FALSE;
|
||||
for (int c = i; c < pool->commandPool->allocatedCommandBufferCount; c++) {
|
||||
if (pool->commandPool->canBeReallocated[c] == GN_TRUE) {
|
||||
pool->commandPool->canBeReallocated[c] = GN_FALSE;
|
||||
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;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!wasAbleToAllocate) {
|
||||
openglResizeCommandPool(pool);
|
||||
}
|
||||
}
|
||||
|
||||
return GN_SUCCESS;
|
||||
}
|
||||
|
||||
void openglResetCommandBuffer(gnCommandBuffer commandBuffer) { /* nothing, for now command buffers are implictly reset on begin */ }
|
||||
gnReturnCode openglBeginCommandBuffer(gnCommandBuffer commandBuffer) {
|
||||
openglResetCommandRunner(commandBuffer->commandBuffer->commmandRunner);
|
||||
return GN_SUCCESS;
|
||||
}
|
||||
gnReturnCode openglEndCommandBuffer(gnCommandBuffer commandBuffer) {
|
||||
return GN_SUCCESS;
|
||||
}
|
||||
void openglDestroyCommandBuffer(gnCommandBuffer commandBuffer) {
|
||||
commandBuffer->commandPool->commandPool->canBeReallocated[commandBuffer->commandBuffer->index] = GN_TRUE;
|
||||
openglDestroyCommandRunner(&commandBuffer->commandBuffer->commmandRunner);
|
||||
}
|
@@ -0,0 +1,17 @@
|
||||
#pragma once
|
||||
#include "glad/glad.h"
|
||||
#include "core/src/command/command_buffer/gryphn_command_buffer.h"
|
||||
#include "commands/commands/opengl_command_runner.h"
|
||||
|
||||
typedef struct gnPlatformCommandBuffer_t {
|
||||
int index;
|
||||
openglCommandRunner commmandRunner;
|
||||
gnGraphicsPipeline boundGraphicsPipeline;
|
||||
gnBuffer boundVertexBuffer, boundIndexBuffer;
|
||||
} gnPlatformCommandBuffer;
|
||||
gnReturnCode openglCommandPoolAllocateCommandBuffers(gnCommandBufferHandle* commandBuffers, uint32_t count, gnCommandPoolHandle pool);
|
||||
|
||||
void openglResetCommandBuffer(gnCommandBuffer commandBuffer);
|
||||
gnReturnCode openglBeginCommandBuffer(gnCommandBuffer commandBuffer);
|
||||
gnReturnCode openglEndCommandBuffer(gnCommandBuffer commandBuffer);
|
||||
void openglDestroyCommandBuffer(gnCommandBuffer commandBuffer);
|
@@ -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); }
|
@@ -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
|
145
projects/apis/opengl/src/commands/commands/opengl_commands.cpp
Normal file
145
projects/apis/opengl/src/commands/commands/opengl_commands.cpp
Normal 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;
|
||||
// }));
|
||||
}
|
14
projects/apis/opengl/src/commands/commands/opengl_commands.h
Normal file
14
projects/apis/opengl/src/commands/commands/opengl_commands.h
Normal 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);
|
31
projects/apis/opengl/src/commands/pool/opengl_command_pool.c
Normal file
31
projects/apis/opengl/src/commands/pool/opengl_command_pool.c
Normal file
@@ -0,0 +1,31 @@
|
||||
#include "opengl_command_pool.h"
|
||||
#include "stdlib.h"
|
||||
|
||||
gnReturnCode openglCreateCommandPool(gnCommandPool commandPool, gnDevice device, gnCommandPoolInfo info) {
|
||||
commandPool->commandPool = malloc(sizeof(gnPlatformCommandPool));
|
||||
|
||||
uint32_t baseCommandBufferCount = 10;
|
||||
commandPool->commandPool->allocatedCommandBufferCount = baseCommandBufferCount;
|
||||
commandPool->commandPool->commandBuffers = malloc(sizeof(gnPlatformCommandBuffer) * baseCommandBufferCount);
|
||||
commandPool->commandPool->canBeReallocated = malloc(sizeof(gnBool) * baseCommandBufferCount);
|
||||
|
||||
for (int i = 0; i < baseCommandBufferCount; i++) {
|
||||
commandPool->commandPool->commandBuffers[i].index = i;
|
||||
commandPool->commandPool->canBeReallocated[i] = GN_TRUE;
|
||||
}
|
||||
|
||||
return GN_SUCCESS;
|
||||
}
|
||||
void openglDestroyCommandPool(gnCommandPool commandPool) {
|
||||
commandPool->commandPool->allocatedCommandBufferCount = 0;
|
||||
free(commandPool->commandPool->commandBuffers);
|
||||
free(commandPool->commandPool->canBeReallocated);
|
||||
free(commandPool->commandPool);
|
||||
}
|
||||
|
||||
|
||||
void openglResizeCommandPool(gnCommandPoolHandle pool) {
|
||||
pool->commandPool->allocatedCommandBufferCount *= 2;
|
||||
pool->commandPool->commandBuffers = realloc(pool->commandPool->commandBuffers, sizeof(gnPlatformCommandBuffer) * pool->commandPool->allocatedCommandBufferCount);
|
||||
pool->commandPool->canBeReallocated = realloc(pool->commandPool->canBeReallocated, sizeof(gnBool) * pool->commandPool->allocatedCommandBufferCount);
|
||||
}
|
15
projects/apis/opengl/src/commands/pool/opengl_command_pool.h
Normal file
15
projects/apis/opengl/src/commands/pool/opengl_command_pool.h
Normal file
@@ -0,0 +1,15 @@
|
||||
#pragma once
|
||||
#include "core/src/command/command_pool/gryphn_command_pool.h"
|
||||
#include "commands/buffers/opengl_command_buffer.h"
|
||||
#include "utils/gryphn_bool.h"
|
||||
|
||||
typedef struct gnPlatformCommandPool_t {
|
||||
uint32_t allocatedCommandBufferCount;
|
||||
gnPlatformCommandBuffer* commandBuffers;
|
||||
gnBool* canBeReallocated;
|
||||
} gnPlatformCommandPool;
|
||||
|
||||
gnReturnCode openglCreateCommandPool(gnCommandPool commandPool, gnDevice device, gnCommandPoolInfo info);
|
||||
void openglDestroyCommandPool(gnCommandPool commandPool);
|
||||
|
||||
void openglResizeCommandPool(gnCommandPoolHandle pool);
|
23
projects/apis/opengl/src/device/glsl_shader.glsl
Normal file
23
projects/apis/opengl/src/device/glsl_shader.glsl
Normal 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" ;
|
@@ -1,5 +1,72 @@
|
||||
#include "glad/glad.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 destroyOpenGLOutputDevice(gnOutputDeviceHandle device) {}
|
||||
|
@@ -1,7 +1,9 @@
|
||||
#pragma once
|
||||
#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);
|
||||
void waitForOpenGLDevice(const gnOutputDeviceHandle device);
|
||||
|
@@ -12,7 +12,7 @@ gnPhysicalDevice* getOpenGLDevice(gnInstanceHandle instance, uint32_t* deviceCou
|
||||
.maxColorSamples = GN_SAMPLE_BIT_1,
|
||||
.maxDepthSamples = GN_SAMPLE_BIT_1,
|
||||
.maxMemoryAllocations = 0x40000000,
|
||||
.maxPushConstantSize = 256
|
||||
.maxPushConstantSize = 0
|
||||
},
|
||||
.properties = {
|
||||
.deviceType = GN_DEDICATED_DEVICE,
|
||||
|
34
projects/apis/opengl/src/framebuffer/opengl_framebuffer.c
Normal file
34
projects/apis/opengl/src/framebuffer/opengl_framebuffer.c
Normal 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);
|
||||
}
|
11
projects/apis/opengl/src/framebuffer/opengl_framebuffer.h
Normal file
11
projects/apis/opengl/src/framebuffer/opengl_framebuffer.h
Normal 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);
|
@@ -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);
|
||||
}
|
@@ -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);
|
@@ -2,6 +2,9 @@
|
||||
|
||||
gnReturnCode openglCreateInstance(gnInstanceHandle instance, gnInstanceCreateInfo* instanceInfo, gryphnInstanceFunctionLayers* next, gnAllocators* allocators) {
|
||||
if (instanceInfo->coreAPI != GN_RENDERINGAPI_OPENGL) return GN_UNSUPPORTED_API;
|
||||
instance->instance = malloc(sizeof(gnPlatformInstance));
|
||||
instance->instance->enableDebugger = instance->enabledLayerCounts[GN_DEBUGGER_LAYER_PLATFORM] >= 1;
|
||||
|
||||
return GN_SUCCESS;
|
||||
}
|
||||
void openglDestroyInstance(gnInstanceHandle instance, gryphnInstanceFunctionLayers* next, gnAllocators* allocators) {
|
||||
|
@@ -2,7 +2,9 @@
|
||||
#include <GL/gl.h>
|
||||
#include "instance/gryphn_instance.h"
|
||||
|
||||
typedef struct gnPlatformInstance_t {} gnPlatformInstance;
|
||||
typedef struct gnPlatformInstance_t {
|
||||
gnBool enableDebugger;
|
||||
} gnPlatformInstance;
|
||||
|
||||
gnReturnCode openglCreateInstance(gnInstanceHandle instance, gnInstanceCreateInfo* instanceInfo, gryphnInstanceFunctionLayers* next, gnAllocators* allocators);
|
||||
void openglDestroyInstance(gnInstanceHandle instance, gryphnInstanceFunctionLayers* next, gnAllocators* allocators);
|
||||
|
36
projects/apis/opengl/src/present/opengl_present.c
Normal file
36
projects/apis/opengl/src/present/opengl_present.c
Normal 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;
|
||||
}
|
4
projects/apis/opengl/src/present/opengl_present.h
Normal file
4
projects/apis/opengl/src/present/opengl_present.h
Normal file
@@ -0,0 +1,4 @@
|
||||
#pragma once
|
||||
#include "core/src/present/gryphn_present.h"
|
||||
|
||||
gnReturnCode openglPresent(gnOutputDeviceHandle device, gnPresentInfo info);
|
@@ -5,28 +5,21 @@
|
||||
gnReturnCode createOpenGLPresentationQueue(gnPresentationQueueHandle presentationQueue, gnOutputDeviceHandle device, gnPresentationQueueInfo presentationInfo) {
|
||||
presentationQueue->presentationQueue = malloc(sizeof(struct gnPlatformPresentationQueue_t));
|
||||
|
||||
uint32_t convertedFormat = glGryphnFormatToOpenGLFormat(presentationInfo.format.format);
|
||||
|
||||
presentationQueue->imageCount = presentationInfo.minImageCount;
|
||||
presentationQueue->images = malloc(sizeof(gnTexture) * presentationInfo.minImageCount);
|
||||
presentationQueue->presentationQueue->textures = GLuintArrayListCreate();
|
||||
presentationQueue->presentationQueue->avaliableTextures = uint32_tArrayListCreate();
|
||||
presentationQueue->presentationQueue->format = glGryphnFormatToOpenGLInternalFormat(presentationInfo.format.format);
|
||||
for (int i = 0; i < presentationInfo.minImageCount; i++) {
|
||||
presentationQueue->images[i] = malloc(sizeof(struct gnTexture_t));
|
||||
presentationQueue->images[i]->texture = malloc(sizeof(gnPlatformTexture));
|
||||
glGenTextures(1, &presentationQueue->images[i]->texture->id);
|
||||
|
||||
glTexImage2D(
|
||||
GL_TEXTURE_2D,
|
||||
0,
|
||||
glCreateTextures(GL_TEXTURE_2D, 1, &presentationQueue->images[i]->texture->id);
|
||||
glTextureStorage2D(
|
||||
presentationQueue->images[i]->texture->id,
|
||||
1,
|
||||
glGryphnFormatToOpenGLInternalFormat(presentationInfo.format.format),
|
||||
presentationInfo.imageSize.x, presentationInfo.imageSize.y,
|
||||
0,
|
||||
glGryphnFormatToOpenGLFormat(presentationInfo.format.format),
|
||||
GL_UNSIGNED_BYTE,
|
||||
NULL
|
||||
presentationInfo.imageSize.x, presentationInfo.imageSize.y
|
||||
);
|
||||
|
||||
GLuintArrayListAdd(presentationQueue->presentationQueue->textures, presentationQueue->images[i]->texture->id);
|
||||
uint32_tArrayListAdd(presentationQueue->presentationQueue->avaliableTextures, i);
|
||||
}
|
||||
|
@@ -7,6 +7,7 @@ GN_ARRAY_LIST_HEADER(GLuint);
|
||||
typedef struct gnPlatformPresentationQueue_t {
|
||||
GLuintArrayList textures;
|
||||
uint32_tArrayList avaliableTextures;
|
||||
GLenum format;
|
||||
} gnPlatformPresentationQueue_t;
|
||||
|
||||
gnReturnCode createOpenGLPresentationQueue(gnPresentationQueueHandle presentationQueue, gnOutputDeviceHandle device, gnPresentationQueueInfo presentationInfo);
|
||||
|
@@ -0,0 +1,50 @@
|
||||
#include "opengl_render_pass_descriptor.h"
|
||||
#include "surface/opengl_surface.h"
|
||||
#include "stdlib.h"
|
||||
|
||||
gnReturnCode openglCreateRenderPass(gnRenderPassDescriptor renderPass, gnDevice device, gnRenderPassDescriptorInfo info) {
|
||||
if (device == GN_NULL_HANDLE) return GN_INVALID_HANDLE;
|
||||
renderPass->renderPassDescriptor = malloc(sizeof(gnPlatformRenderPassDescriptor));
|
||||
renderPass->renderPassDescriptor->subpassCount = info.subpassCount;
|
||||
renderPass->renderPassDescriptor->subpasses = malloc(sizeof(glSubpass) * info.subpassCount);
|
||||
|
||||
for (uint32_t i = 0; i < info.subpassCount; i++) {
|
||||
renderPass->renderPassDescriptor->subpasses[i] = (glSubpass){
|
||||
.colorAttachmentCount = info.subpassInfos[i].colorAttachmentCount,
|
||||
.colorAttachments = malloc(sizeof(glColorAttachment) * info.subpassInfos[i].colorAttachmentCount),
|
||||
.depthAttachment.index = -1
|
||||
};
|
||||
gnBool resolve = !(info.subpassInfos[i].resolveAttachments == NULL);
|
||||
for (uint32_t c = 0; c < info.subpassInfos[i].colorAttachmentCount; c++) {
|
||||
uint32_t attachmentIndex = info.subpassInfos[i].colorAttachments[c].index;
|
||||
int resolveAttachmentIndex = -1;
|
||||
if (resolve)
|
||||
resolveAttachmentIndex = info.subpassInfos[i].resolveAttachments[c].index;
|
||||
|
||||
renderPass->renderPassDescriptor->subpasses[i].colorAttachments[c] = (glColorAttachment){
|
||||
.loadOperation = info.attachmentInfos[attachmentIndex].loadOperation,
|
||||
.storeOperation = info.attachmentInfos[attachmentIndex].storeOperation,
|
||||
.attachmentIndex = attachmentIndex,
|
||||
.resolveAttachmentIndex = resolveAttachmentIndex,
|
||||
.format = glGryphnFormatToOpenGLInternalFormat(info.attachmentInfos[attachmentIndex].format)
|
||||
};
|
||||
}
|
||||
|
||||
if (info.subpassInfos[i].depthAttachment != NULL) {
|
||||
uint32_t depthAttachmentIndex = info.subpassInfos[i].depthAttachment->index;
|
||||
renderPass->renderPassDescriptor->subpasses[i].depthAttachment = (gnDepthAttachment){
|
||||
.index = depthAttachmentIndex,
|
||||
.format = glGryphnFormatToOpenGLInternalFormat(info.attachmentInfos[depthAttachmentIndex].format),
|
||||
.loadOperation = info.attachmentInfos[depthAttachmentIndex].loadOperation,
|
||||
.storeOperation = info.attachmentInfos[depthAttachmentIndex].storeOperation,
|
||||
};
|
||||
}
|
||||
}
|
||||
return GN_SUCCESS;
|
||||
}
|
||||
void openglDestroyRenderPass(gnRenderPassDescriptor renderPass) {
|
||||
for (int i = 0; i < renderPass->renderPassDescriptor->subpassCount; i++)
|
||||
free(renderPass->renderPassDescriptor->subpasses[i].colorAttachments);
|
||||
free(renderPass->renderPassDescriptor->subpasses);
|
||||
free(renderPass->renderPassDescriptor);
|
||||
}
|
@@ -0,0 +1,34 @@
|
||||
#pragma once
|
||||
#include "glad/glad.h"
|
||||
#include "core/src/renderpass/gryphn_render_pass_descriptor.h"
|
||||
#include "utils/gryphn_color.h"
|
||||
|
||||
typedef struct glColorAttachment {
|
||||
gnColor clearColor;
|
||||
gnLoadOperation loadOperation;
|
||||
gnStoreOperation storeOperation;
|
||||
|
||||
GLenum format;
|
||||
uint32_t attachmentIndex;
|
||||
int resolveAttachmentIndex; // -1 = no attachment
|
||||
} glColorAttachment;
|
||||
|
||||
typedef struct gnDepthAttachment {
|
||||
int index;
|
||||
gnLoadOperation loadOperation;
|
||||
gnStoreOperation storeOperation;
|
||||
GLint format;
|
||||
} gnDepthAttachment;
|
||||
|
||||
typedef struct glSubpass {
|
||||
uint32_t colorAttachmentCount;
|
||||
glColorAttachment* colorAttachments;
|
||||
gnDepthAttachment depthAttachment;
|
||||
} glSubpass;
|
||||
|
||||
typedef struct gnPlatformRenderPassDescriptor_t {
|
||||
uint32_t subpassCount;
|
||||
glSubpass* subpasses;
|
||||
} gnPlatformRenderPassDescriptor;
|
||||
gnReturnCode openglCreateRenderPass(gnRenderPassDescriptor renderPass, gnDevice device, gnRenderPassDescriptorInfo info);
|
||||
void openglDestroyRenderPass(gnRenderPassDescriptor renderPass);
|
73
projects/apis/opengl/src/shaders/opengl_shader_compiler.cpp
Normal file
73
projects/apis/opengl/src/shaders/opengl_shader_compiler.cpp
Normal file
@@ -0,0 +1,73 @@
|
||||
#include "opengl_shader_compiler.h"
|
||||
#include "spirv_glsl.hpp"
|
||||
typedef struct glCompiler_t {
|
||||
spirv_cross::CompilerGLSL* glsl;
|
||||
} glInternalCompiler;
|
||||
|
||||
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++) {
|
||||
uint32_t
|
||||
set = compiler.get_decoration(resources[i].id, spv::DecorationDescriptorSet),
|
||||
binding = compiler.get_decoration(resources[i].id, spv::DecorationBinding);
|
||||
compiler.unset_decoration(resources[i].id, spv::DecorationBinding);
|
||||
compiler.set_decoration(resources[i].id, spv::DecorationBinding, setMap[set].bindings[binding]);
|
||||
}
|
||||
}
|
||||
|
||||
GN_CPP_FUNCTION glCompiler glCreateCompiler(glCompilerInfo* info) {
|
||||
glInternalCompiler* compiler = (glInternalCompiler*)malloc(sizeof(glInternalCompiler));
|
||||
compiler->glsl = new spirv_cross::CompilerGLSL(info->code, info->wordCount);
|
||||
// spirv_cross::CompilerGLSL::Options options = compiler->glsl->get_common_options();
|
||||
// compiler->glsl->set_common_options(options);
|
||||
return compiler;
|
||||
}
|
||||
GN_CPP_FUNCTION glShader glCompilerCompilerShader(glCompiler compiler, gnUniformLayout* layout) {
|
||||
glShader shader = {};
|
||||
uint32_t currentBinding = 0;
|
||||
for (uint32_t i = 0; i < layout->setCount; i++) {
|
||||
for (size_t c = 0; c < layout->sets[i].uniformBindingCount; c++) {
|
||||
gnUniformBinding gryphnBinding = layout->sets[i].uniformBindings[c];
|
||||
shader.sets[i].bindings[c] = currentBinding;
|
||||
currentBinding++;
|
||||
}
|
||||
}
|
||||
|
||||
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();
|
||||
shader.source = (char*)malloc(sizeof(char*) * (output.size() + 1));
|
||||
strcpy(shader.source, output.c_str());
|
||||
shader.source[output.size()] = '\0';
|
||||
return shader;
|
||||
}
|
||||
|
||||
GN_CPP_FUNCTION void glDestroyCompiler(glCompiler compiler) {
|
||||
delete compiler->glsl;
|
||||
free(compiler);
|
||||
}
|
33
projects/apis/opengl/src/shaders/opengl_shader_compiler.h
Normal file
33
projects/apis/opengl/src/shaders/opengl_shader_compiler.h
Normal file
@@ -0,0 +1,33 @@
|
||||
#pragma once
|
||||
#include "stdint.h"
|
||||
#include "glad/glad.h"
|
||||
#include "utils/gryphn_cpp_function.h"
|
||||
#include "core/src/uniforms/gryphn_uniform_layout.h"
|
||||
|
||||
#define MAX_OPENGL_SETS 16
|
||||
#define MAX_OPENGL_BINDINGS 32
|
||||
|
||||
typedef enum glShaderModuleStage {
|
||||
glVertex = GL_VERTEX_SHADER,
|
||||
mtlFragment = GL_FRAGMENT_SHADER,
|
||||
mtlMaxStage
|
||||
} glShaderModuleStage;
|
||||
|
||||
typedef struct glCompilerInfo {
|
||||
uint32_t* code;
|
||||
int wordCount;
|
||||
const char* entryPoint;
|
||||
// glShaderModuleStage stage;
|
||||
} glCompilerInfo;
|
||||
|
||||
typedef struct glSet { uint32_t bindings[MAX_OPENGL_BINDINGS]; } glSet;
|
||||
|
||||
typedef struct glShader {
|
||||
char* source;
|
||||
glSet sets[MAX_OPENGL_SETS];
|
||||
} glShader;
|
||||
|
||||
typedef struct glCompiler_t* glCompiler;
|
||||
GN_CPP_FUNCTION glCompiler glCreateCompiler(glCompilerInfo* info);
|
||||
GN_CPP_FUNCTION glShader glCompilerCompilerShader(glCompiler compiler, gnUniformLayout* layout);
|
||||
GN_CPP_FUNCTION void glDestroyCompiler(glCompiler compiler);
|
26
projects/apis/opengl/src/shaders/opengl_shader_module.c
Normal file
26
projects/apis/opengl/src/shaders/opengl_shader_module.c
Normal file
@@ -0,0 +1,26 @@
|
||||
#include "opengl_shader_module.h"
|
||||
#include "opengl_shader_compiler.h"
|
||||
#include "stdlib.h"
|
||||
|
||||
GLenum gnShaderTypeToGLEnum(gnShaderModuleStage stage) {
|
||||
switch (stage) {
|
||||
case GN_VERTEX_SHADER_MODULE: return GL_VERTEX_SHADER;
|
||||
case GN_FRAGMENT_SHADER_MODULE: return GL_FRAGMENT_SHADER;
|
||||
case GN_ALL_SHADER_MODULE: return GL_VERTEX_SHADER | GL_FRAGMENT_SHADER;
|
||||
}
|
||||
}
|
||||
|
||||
gnReturnCode openglCreateShaderModule(gnShaderModule module, gnDevice device, gnShaderModuleInfo shaderModuleInfo) {
|
||||
module->shaderModule = malloc(sizeof(gnPlatformShaderModule));
|
||||
glCompilerInfo info = {
|
||||
.code = shaderModuleInfo.code,
|
||||
.wordCount = shaderModuleInfo.size / 4,
|
||||
.entryPoint = gnToCString(shaderModuleInfo.entryPoint),
|
||||
};
|
||||
module->shaderModule->compiler = glCreateCompiler(&info);
|
||||
return GN_SUCCESS;
|
||||
}
|
||||
void openglDestroyShaderModule(gnShaderModule module) {
|
||||
glDestroyCompiler(module->shaderModule->compiler);
|
||||
free(module->shaderModule);
|
||||
}
|
12
projects/apis/opengl/src/shaders/opengl_shader_module.h
Normal file
12
projects/apis/opengl/src/shaders/opengl_shader_module.h
Normal file
@@ -0,0 +1,12 @@
|
||||
#pragma once
|
||||
#include "core/src/shader_module/gryphn_shader_module.h"
|
||||
#include "opengl_shader_compiler.h"
|
||||
|
||||
typedef struct gnPlatformShaderModule_t {
|
||||
glCompiler compiler;
|
||||
} gnPlatformShaderModule;
|
||||
|
||||
GLenum gnShaderTypeToGLEnum(gnShaderModuleStage stage);
|
||||
|
||||
gnReturnCode openglCreateShaderModule(gnShaderModule module, gnDevice device, gnShaderModuleInfo shaderModuleInfo);
|
||||
void openglDestroyShaderModule(gnShaderModule module);
|
11
projects/apis/opengl/src/submit/opengl_submit.c
Normal file
11
projects/apis/opengl/src/submit/opengl_submit.c
Normal 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;
|
||||
}
|
3
projects/apis/opengl/src/submit/opengl_submit.h
Normal file
3
projects/apis/opengl/src/submit/opengl_submit.h
Normal file
@@ -0,0 +1,3 @@
|
||||
#pragma once
|
||||
#include "core/src/submit/gryphn_submit.h"
|
||||
gnReturnCode openglSubmit(gnOutputDevice device, gnSubmitInfo info);
|
@@ -1,8 +1,56 @@
|
||||
#include <glad/glad.h>
|
||||
#include "GL/glext.h"
|
||||
#include "opengl_surface.h"
|
||||
#include "utils/gryphn_string.h"
|
||||
|
||||
#include "stdio.h"
|
||||
|
||||
void GLAPIENTRY openglMessageCallback( GLenum source,
|
||||
GLenum type,
|
||||
GLuint id,
|
||||
GLenum severity,
|
||||
GLsizei length,
|
||||
const GLchar* message,
|
||||
const void* userParam ) {
|
||||
gnInstanceHandle handle = (gnInstanceHandle)userParam;
|
||||
|
||||
gnMessageSeverity gryphnSeverity;
|
||||
if (severity == GL_DEBUG_SEVERITY_HIGH) gryphnSeverity = GN_MESSAGE_ERROR;
|
||||
else if (severity == GL_DEBUG_SEVERITY_MEDIUM) gryphnSeverity = GN_MESSAGE_WARNING;
|
||||
else if (severity == GL_DEBUG_SEVERITY_LOW) gryphnSeverity = GN_MESSAGE_WARNING;
|
||||
else if (severity == GL_DEBUG_SEVERITY_NOTIFICATION) gryphnSeverity = GN_MESSAGE_VERBOSE;
|
||||
else {
|
||||
handle->debugger.callback(
|
||||
GN_MESSAGE_ERROR,
|
||||
GN_DEBUG_MESSAGE_VALIDATION,
|
||||
(gnMessageData){ .message = gnCreateString("Uknown severity type from OpenGL") },
|
||||
handle->debugger.userData
|
||||
);
|
||||
}
|
||||
|
||||
gnMessageType gryphnType;
|
||||
if (type == GL_DEBUG_TYPE_ERROR) gryphnType = GN_DEBUG_MESSAGE_VALIDATION;
|
||||
else if (type == GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR) gryphnType = GN_DEBUG_MESSAGE_VALIDATION;
|
||||
else if (type == GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR) gryphnType = GN_DEBUG_MESSAGE_VALIDATION;
|
||||
else if (type == GL_DEBUG_TYPE_PORTABILITY) gryphnType = GN_DEBUG_MESSAGE_VALIDATION;
|
||||
else if (type == GL_DEBUG_TYPE_PERFORMANCE) gryphnType = GN_DEBUG_MESSAGE_PERFORMANCE;
|
||||
else if (type == GL_DEBUG_TYPE_OTHER) gryphnType = GN_DEBUG_MESSAGE_GENERAL;
|
||||
else {
|
||||
handle->debugger.callback(
|
||||
GN_MESSAGE_ERROR,
|
||||
GN_DEBUG_MESSAGE_VALIDATION,
|
||||
(gnMessageData){ .message = gnCreateString("Uknown message type from OpenGL") },
|
||||
handle->debugger.userData
|
||||
);
|
||||
}
|
||||
|
||||
handle->debugger.callback(
|
||||
gryphnSeverity,
|
||||
gryphnType,
|
||||
(gnMessageData){ .message = gnCreateString(message) },
|
||||
handle->debugger.userData
|
||||
);
|
||||
}
|
||||
|
||||
#ifdef GN_PLATFORM_LINUX
|
||||
#ifdef GN_WINDOW_X11
|
||||
#include <X11/Xlib.h>
|
||||
@@ -28,6 +76,10 @@ gnReturnCode createGLXContext(gnWindowSurfaceHandle windowSurface, gnInstanceHan
|
||||
|
||||
return GN_UNKNOWN_ERROR;
|
||||
}
|
||||
|
||||
glEnable(GL_DEBUG_OUTPUT);
|
||||
glDebugMessageCallback(openglMessageCallback, instance);
|
||||
|
||||
return GN_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -37,6 +89,10 @@ gnUInt2 getWindowSize(gnPlatformWindowSurface* surface) {
|
||||
return (gnUInt2){ attr.width, attr.height };
|
||||
}
|
||||
|
||||
void swapBuffers(gnWindowSurface surface) {
|
||||
glXSwapBuffers(surface->windowSurface->display, surface->windowSurface->window);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef GN_WINFDOW_WAYLAND
|
||||
@@ -51,11 +107,14 @@ gnSurfaceDetails genOpenGLSurfaceDetails(
|
||||
) {
|
||||
gnSurfaceDetails surfaceDetails;
|
||||
surfaceDetails.formatCount = 1;
|
||||
surfaceDetails.formats = (gnSurfaceFormat[]){
|
||||
(gnSurfaceFormat){
|
||||
surfaceDetails.formats = malloc(sizeof(gnSurfaceFormat) * 2);
|
||||
surfaceDetails.formats[0] = (gnSurfaceFormat){
|
||||
.format = GN_FORMAT_RGBA8_SRGB,
|
||||
.colorSpace = GN_COLOR_SPACE_SRGB_NONLINEAR
|
||||
}
|
||||
};
|
||||
surfaceDetails.formats[1] = (gnSurfaceFormat){
|
||||
.format = GN_FORMAT_RGBA8,
|
||||
.colorSpace = GN_COLOR_SPACE_SRGB_NONLINEAR
|
||||
};
|
||||
|
||||
surfaceDetails.minImageCount = 2;
|
||||
@@ -76,24 +135,26 @@ void destroyOpenGLSurface(gnWindowSurface surface) {
|
||||
GLint glGryphnFormatToOpenGLFormat(gnImageFormat format) {
|
||||
switch (format) {
|
||||
case GN_FORMAT_NONE: return GL_NONE;
|
||||
case GN_FORMAT_BGRA8: return GL_BGRA;
|
||||
case GN_FORMAT_RGBA8_SRGB: return GL_SRGB_ALPHA;
|
||||
case GN_FORMAT_RGBA8: return GL_RGBA;
|
||||
case GN_FORMAT_RGBA8_SRGB: return GL_RGBA;
|
||||
case GN_FORMAT_D32S8_UINT: return GL_DEPTH_STENCIL;
|
||||
case GN_FORMAT_D24S8_UINT: return GL_DEPTH_STENCIL;
|
||||
|
||||
// unsupprted formats
|
||||
case GN_FORMAT_BGRA8: return GL_NONE;
|
||||
case GN_FORMAT_BGRA8_SRGB: return GL_NONE;
|
||||
}
|
||||
}
|
||||
GLint glGryphnFormatToOpenGLInternalFormat(gnImageFormat format) {
|
||||
switch (format) {
|
||||
case GN_FORMAT_NONE: return GL_NONE;
|
||||
case GN_FORMAT_BGRA8: return GL_BGRA8_EXT;
|
||||
case GN_FORMAT_RGBA8: return GL_RGBA8;
|
||||
case GN_FORMAT_RGBA8_SRGB: return GL_SRGB8_ALPHA8;
|
||||
case GN_FORMAT_D32S8_UINT: return GL_DEPTH32F_STENCIL8;
|
||||
case GN_FORMAT_D24S8_UINT: return GL_DEPTH24_STENCIL8;
|
||||
|
||||
// unsupprted formats
|
||||
case GN_FORMAT_BGRA8: return GL_NONE;
|
||||
case GN_FORMAT_BGRA8_SRGB: return GL_NONE;
|
||||
}
|
||||
}
|
||||
|
@@ -15,6 +15,7 @@ gnReturnCode createGLXContext(gnWindowSurfaceHandle windowSurface, gnInstanceHan
|
||||
#endif
|
||||
|
||||
gnUInt2 getWindowSize(gnPlatformWindowSurface* surface);
|
||||
void swapBuffers(gnWindowSurface surface);
|
||||
gnSurfaceDetails genOpenGLSurfaceDetails(gnWindowSurfaceHandle windowSurface, gnPhysicalDevice device);
|
||||
void destroyOpenGLSurface(gnWindowSurface surface);
|
||||
|
||||
|
36
projects/apis/opengl/src/textures/opengl_texture.c
Normal file
36
projects/apis/opengl/src/textures/opengl_texture.c
Normal file
@@ -0,0 +1,36 @@
|
||||
#include "opengl_texture.h"
|
||||
#include "surface/opengl_surface.h"
|
||||
|
||||
GLenum GryphnTargetToOpenGL(gnTextureType type) {
|
||||
switch(type) {
|
||||
case GN_TEXTURE_2D: return GL_TEXTURE_2D;
|
||||
}
|
||||
}
|
||||
|
||||
gnReturnCode openglCreateTexture(gnTexture texture, gnDevice device, const gnTextureInfo info) {
|
||||
texture->texture = malloc(sizeof(gnPlatformTexture));
|
||||
glCreateTextures(GryphnTargetToOpenGL(info.type), 1, &texture->texture->id);
|
||||
glTextureStorage2D(
|
||||
texture->texture->id,
|
||||
1,
|
||||
glGryphnFormatToOpenGLInternalFormat(info.format),
|
||||
info.extent.x, info.extent.y
|
||||
);
|
||||
return GN_SUCCESS;
|
||||
}
|
||||
#include "stdio.h"
|
||||
void openglTextureData(gnTextureHandle texture, void* pixelData) {
|
||||
printf("OpenGL id: %u\n", texture->texture->id);
|
||||
glTextureSubImage2D(
|
||||
texture->texture->id,
|
||||
0,
|
||||
0, 0,
|
||||
texture->info.extent.x, texture->info.extent.y,
|
||||
GL_RGBA,
|
||||
GL_UNSIGNED_BYTE,
|
||||
pixelData
|
||||
);
|
||||
}
|
||||
void openglDestroyTexture(gnTexture texture) {
|
||||
|
||||
}
|
@@ -5,3 +5,7 @@
|
||||
typedef struct gnPlatformTexture_t {
|
||||
GLuint id;
|
||||
} gnPlatformTexture;
|
||||
|
||||
gnReturnCode openglCreateTexture(gnTexture texture, gnDevice device, const gnTextureInfo info);
|
||||
void openglTextureData(gnTextureHandle texture, void* pixelData);
|
||||
void openglDestroyTexture(gnTexture texture);
|
||||
|
18
projects/apis/opengl/src/uniforms/pool/opengl_uniform_pool.c
Normal file
18
projects/apis/opengl/src/uniforms/pool/opengl_uniform_pool.c
Normal file
@@ -0,0 +1,18 @@
|
||||
#include "opengl_uniform_pool.h"
|
||||
#include "uniforms/uniform/opengl_uniform.h"
|
||||
|
||||
gnReturnCode openglCreateUniformPool(gnUniformPool pool, gnDeviceHandle device) {
|
||||
return GN_SUCCESS;
|
||||
}
|
||||
gnUniform* openglAllocateUniforms(gnUniformPool pool, const gnUniformAllocationInfo allocInfo) {
|
||||
gnUniform* uniforms = malloc(sizeof(gnUniform) * allocInfo.setCount);
|
||||
for (int i = 0; i < allocInfo.setCount; i++) {
|
||||
uniforms[i] = malloc(sizeof(struct gnUniform_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;
|
||||
}
|
||||
void openglDestroyUniformPool(gnUniformPool pool) {
|
||||
|
||||
}
|
@@ -0,0 +1,7 @@
|
||||
#pragma once
|
||||
#include "core/src/uniforms/gryphn_uniform_pool.h"
|
||||
|
||||
typedef struct gnPlatformUniformPool_t { gnBool warningAvoider; } gnPlatformUniformPool;
|
||||
gnReturnCode openglCreateUniformPool(gnUniformPool pool, gnDeviceHandle device);
|
||||
gnUniform* openglAllocateUniforms(gnUniformPool pool, const gnUniformAllocationInfo allocInfo);
|
||||
void openglDestroyUniformPool(gnUniformPool pool);
|
17
projects/apis/opengl/src/uniforms/uniform/opengl_uniform.c
Normal file
17
projects/apis/opengl/src/uniforms/uniform/opengl_uniform.c
Normal file
@@ -0,0 +1,17 @@
|
||||
#include "opengl_uniform.h"
|
||||
|
||||
void openglUpdateBufferUniform(gnUniform uniform, gnBufferUniformInfo* info) {
|
||||
uniform->uniform->bindings[info->binding].isUpdated = GN_TRUE;
|
||||
uniform->uniform->bindings[info->binding].type = gl_buffer;
|
||||
uniform->uniform->bindings[info->binding].buffer_info = *info;
|
||||
}
|
||||
void openglUpdateStorageUniform(gnUniform uniform, gnStorageUniformInfo* info) {
|
||||
uniform->uniform->bindings[info->binding].isUpdated = GN_TRUE;
|
||||
uniform->uniform->bindings[info->binding].type = gl_storage;
|
||||
uniform->uniform->bindings[info->binding].storage_info = *info;
|
||||
}
|
||||
void openglUpdateImageUniform(gnUniform uniform, gnImageUniformInfo* info) {
|
||||
uniform->uniform->bindings[info->binding].isUpdated = GN_TRUE;
|
||||
uniform->uniform->bindings[info->binding].type = gl_image;
|
||||
uniform->uniform->bindings[info->binding].image_info = *info;
|
||||
}
|
26
projects/apis/opengl/src/uniforms/uniform/opengl_uniform.h
Normal file
26
projects/apis/opengl/src/uniforms/uniform/opengl_uniform.h
Normal file
@@ -0,0 +1,26 @@
|
||||
#pragma once
|
||||
#include "glad/glad.h"
|
||||
#include "core/src/uniforms/gryphn_uniform.h"
|
||||
#include "shaders/opengl_shader_compiler.h"
|
||||
|
||||
typedef enum openglUniformType {
|
||||
gl_buffer, gl_storage, gl_image
|
||||
} openglUniformType;
|
||||
|
||||
typedef struct glUniformBinding {
|
||||
openglUniformType type;
|
||||
union {
|
||||
gnBufferUniformInfo buffer_info;
|
||||
gnStorageUniformInfo storage_info;
|
||||
gnImageUniformInfo image_info;
|
||||
};
|
||||
gnBool isUpdated;
|
||||
} glUniformBinding;
|
||||
|
||||
typedef struct gnPlatformUniform_t {
|
||||
glUniformBinding bindings[MAX_OPENGL_BINDINGS];
|
||||
} gnPlatformUniform;
|
||||
|
||||
void openglUpdateBufferUniform(gnUniform uniform, gnBufferUniformInfo* info);
|
||||
void openglUpdateStorageUniform(gnUniform uniform, gnStorageUniformInfo* info);
|
||||
void openglUpdateImageUniform(gnUniform uniform, gnImageUniformInfo* info);
|
@@ -2,7 +2,7 @@ set(CMAKE_EXPORT_COMPILE_COMMANDS on)
|
||||
project(GryphnVulkanImpl)
|
||||
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 LOADER_FILES CONFIGURE_DEPENDS "loader/*.c")
|
||||
|
@@ -7,15 +7,18 @@
|
||||
gryphnInstanceFunctionLayers loadVulkanAPILayer(void) {
|
||||
return (gryphnInstanceFunctionLayers) {
|
||||
.createInstance = vulkanCreateInstance,
|
||||
.isSuitable = vulkanIsInstanceSuitable,
|
||||
.destroyInstance = vulkanDestroyInstance,
|
||||
.queryDevices = vulkanQueryDevices,
|
||||
.getPhysicalDeviceProperties = vulkanQueryPhysicalDeviceProperties,
|
||||
.getPhysicalDeviceFeatures = vulkanQueryPhysicalDeviceFeatures,
|
||||
.getPhysicalDeviceLimits = vulkanQueryPhysicalDeviceLimits,
|
||||
.next = NULL
|
||||
};
|
||||
}
|
||||
|
||||
gnInstanceFunctions loadVulkanInstanceFunctions(void) {
|
||||
return (gnInstanceFunctions){
|
||||
|
||||
._gnGetPhysicalDevices = getPhysicalDevices,
|
||||
._gnPhysicalDeviceCanPresentToSurface = deviceCanPresentToSurface,
|
||||
|
||||
._gnCreateOutputDevice = createVulkanOutputDevice,
|
||||
|
@@ -1,12 +1,12 @@
|
||||
#include "vulkan_device_queues.h"
|
||||
#include "output_device/vulkan_output_devices.h"
|
||||
|
||||
gnReturnCode vulkanPhysicalDeviceQueueProperties(gnPhysicalOutputDeviceHandle device, uint32_t queueFamilyCount, gnQueueFamilyProperties* queues) {
|
||||
vkGetPhysicalDeviceQueueFamilyProperties(device->physicalDevice->device, &queueFamilyCount, NULL);
|
||||
gnReturnCode vulkanPhysicalDeviceQueueProperties(gnPhysicalDeviceHandle device, uint32_t queueFamilyCount, gnQueueFamilyProperties* queues) {
|
||||
vkGetPhysicalDeviceQueueFamilyProperties((VkPhysicalDevice)device, &queueFamilyCount, NULL);
|
||||
if (queues == NULL) return GN_SUCCESS;
|
||||
|
||||
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++) {
|
||||
queues[i].queueCount = queueFamilies[i].queueCount;
|
||||
@@ -21,8 +21,9 @@ gnReturnCode vulkanPhysicalDeviceQueueProperties(gnPhysicalOutputDeviceHandle de
|
||||
return GN_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
void getVulkanDeviceQueue(gnOutputDevice device, uint32_t queueFamily, uint32_t queueIndex, gnQueue* queue) {
|
||||
VkQueue vulkanQueue;
|
||||
vkGetDeviceQueue(device->outputDevice->device, queueFamily, queueIndex, &vulkanQueue);
|
||||
*queue = (uint64_t)vulkanQueue;
|
||||
*queue = (gnQueue)vulkanQueue;
|
||||
}
|
||||
|
@@ -4,5 +4,5 @@
|
||||
#include <output_device/vulkan_physical_device.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);
|
||||
|
@@ -1,4 +1,5 @@
|
||||
#include "vulkan_instance.h"
|
||||
// #include "output_device/vulkan_physical_device.h"
|
||||
#include "vulkan_result_converter.h"
|
||||
GN_ARRAY_LIST_DEFINITION(vkString)
|
||||
|
||||
@@ -109,6 +110,17 @@ gnReturnCode vulkanCreateInstance(gnInstanceHandle instance, gnInstanceCreateInf
|
||||
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) {
|
||||
if (next != NULL) { return; }
|
||||
vkDestroyInstance(instance->instance->vk_instance, NULL);
|
||||
|
@@ -15,6 +15,8 @@ typedef struct gnPlatformInstance_t {
|
||||
} gnPlatformInstance;
|
||||
|
||||
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);
|
||||
|
||||
typedef const char* vkString;
|
||||
|
@@ -8,25 +8,27 @@
|
||||
#include "vulkan_result_converter.h"
|
||||
#include "string.h"
|
||||
|
||||
#include "stdio.h"
|
||||
#include <stdio.h>
|
||||
|
||||
gnReturnCode createVulkanOutputDevice(gnInstanceHandle instance, gnOutputDeviceHandle device, gnOutputDeviceInfo deviceInfo) {
|
||||
device->outputDevice = malloc(sizeof(gnPlatformOutputDevice));
|
||||
device->outputDevice->physicalDevice = deviceInfo.physicalDevice->physicalDevice->device;
|
||||
device->outputDevice->physicalDevice = (VkPhysicalDevice)deviceInfo.physicalDevice;
|
||||
|
||||
int createQueueCount = 0;
|
||||
VkDeviceQueueCreateInfo* queueCreateInfos = NULL;
|
||||
|
||||
if (!instance->enabledExtensions[GN_EXT_QUEUES]) {
|
||||
queueCreateInfos = malloc(sizeof(VkDeviceQueueCreateInfo) * deviceInfo.physicalDevice->physicalDevice->neededQueueCount);
|
||||
createQueueCount = deviceInfo.physicalDevice->physicalDevice->neededQueueCount;
|
||||
uint32_t neededQueueCount;
|
||||
vulkanNeededQueue* neededQueues = vulkanLoadNeededQueues(deviceInfo.physicalDevice, &neededQueueCount);
|
||||
queueCreateInfos = malloc(sizeof(VkDeviceQueueCreateInfo) * neededQueueCount);
|
||||
createQueueCount = neededQueueCount;
|
||||
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].pNext = NULL;
|
||||
queueCreateInfos[i].flags = 0;
|
||||
queueCreateInfos[i].queueCount = 1;
|
||||
queueCreateInfos[i].queueFamilyIndex = deviceInfo.physicalDevice->physicalDevice->neededQueues[i].queueIndex;
|
||||
queueCreateInfos[i].queueFamilyIndex = neededQueues[i].queueIndex;
|
||||
queueCreateInfos[i].pQueuePriorities = &queuePriority;
|
||||
}
|
||||
} else {
|
||||
@@ -54,7 +56,7 @@ gnReturnCode createVulkanOutputDevice(gnInstanceHandle instance, gnOutputDeviceH
|
||||
.pQueueCreateInfos = queueCreateInfos,
|
||||
.pEnabledFeatures = &deviceFeatures
|
||||
};
|
||||
deviceCreateInfo.ppEnabledExtensionNames = vkGetGryphnDeviceExtensions(&deviceCreateInfo.enabledExtensionCount, deviceInfo.physicalDevice->physicalDevice->device);
|
||||
deviceCreateInfo.ppEnabledExtensionNames = vkGetGryphnDeviceExtensions(&deviceCreateInfo.enabledExtensionCount, (VkPhysicalDevice)deviceInfo.physicalDevice);
|
||||
|
||||
device->outputDevice->enabledOversizedDescriptorPools = GN_FALSE;
|
||||
for (uint32_t i = 0; i < deviceCreateInfo.enabledExtensionCount; i++)
|
||||
@@ -67,18 +69,16 @@ gnReturnCode createVulkanOutputDevice(gnInstanceHandle instance, gnOutputDeviceH
|
||||
deviceCreateInfo.enabledLayerCount = 1;
|
||||
deviceCreateInfo.ppEnabledLayerNames = validation_layers;
|
||||
}
|
||||
|
||||
VkResult result = vkCreateDevice(deviceInfo.physicalDevice->physicalDevice->device, &deviceCreateInfo, NULL, &device->outputDevice->device);
|
||||
VkResult result = vkCreateDevice((VkPhysicalDevice)deviceInfo.physicalDevice, &deviceCreateInfo, NULL, &device->outputDevice->device);
|
||||
if (result != VK_SUCCESS)
|
||||
return VkResultToGnReturnCode(result);
|
||||
|
||||
device->outputDevice->queues = malloc(sizeof(vulkanQueue) * deviceInfo.physicalDevice->physicalDevice->neededQueueCount);
|
||||
device->outputDevice->queues = malloc(sizeof(vulkanQueue) * createQueueCount);
|
||||
uint32_t transferQueue = 0;
|
||||
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) {
|
||||
device->outputDevice->transferQueueIndex = i;
|
||||
transferQueue = device->outputDevice->queues[i].queueInfo.queueIndex;
|
||||
@@ -89,7 +89,12 @@ gnReturnCode createVulkanOutputDevice(gnInstanceHandle instance, gnOutputDeviceH
|
||||
device->outputDevice->graphicsQueueIndex = i;
|
||||
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 = {
|
||||
.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
|
||||
|
@@ -3,8 +3,120 @@
|
||||
#include <output_device/vulkan_device_extensions.h>
|
||||
#include <vulkan_surface/vulkan_surface.h>
|
||||
|
||||
gnMultisampleCountFlags vkSampleCountToGryphn(VkSampleCountFlags counts) {
|
||||
gnMultisampleCountFlags sampleCount = 0;
|
||||
inline gnPhysicalDeviceType vulkanDeviceTypeToGryphn(VkPhysicalDeviceType type) {
|
||||
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_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; }
|
||||
@@ -15,9 +127,7 @@ gnMultisampleCountFlags vkSampleCountToGryphn(VkSampleCountFlags counts) {
|
||||
return sampleCount;
|
||||
}
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
VkSampleCountFlags gnSampleCountToVulkan(gnMultisampleCountFlags counts) {
|
||||
VkSampleCountFlags gnSampleCountToVulkan(gnSampleCountFlags counts) {
|
||||
VkSampleCountFlags sampleCount = 0;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
void vulkanLoadNeededQueues(VkPhysicalDevice vulkanDevice, gnPhysicalDevice gryphnDevice) {
|
||||
vulkanNeededQueue* vulkanLoadNeededQueues(gnPhysicalDevice physicalDevice, uint32_t* neededQueueCount) {
|
||||
VkPhysicalDevice device = (VkPhysicalDevice)physicalDevice;
|
||||
uint32_t queueFamilyCount = 0;
|
||||
vkGetPhysicalDeviceQueueFamilyProperties(vulkanDevice, &queueFamilyCount, NULL);
|
||||
vkGetPhysicalDeviceQueueFamilyProperties(device, &queueFamilyCount, NULL);
|
||||
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++) {
|
||||
gnBool hasNeededQueue = GN_FALSE;
|
||||
|
||||
if ((queueFamilies[c].queueFlags & VK_QUEUE_GRAPHICS_BIT) == VK_QUEUE_GRAPHICS_BIT)
|
||||
if ((queueFamilies[c].queueFlags & VK_QUEUE_GRAPHICS_BIT) == VK_QUEUE_GRAPHICS_BIT && !foundGraphicsQueue) {
|
||||
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;
|
||||
foundTransferQueue = GN_TRUE;
|
||||
}
|
||||
|
||||
if (hasNeededQueue) {
|
||||
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_TRANSFER_BIT)) neededQueue.createFlags |= VK_QUEUE_TRANSFER_BIT;
|
||||
|
||||
gryphnDevice->physicalDevice->neededQueues[gryphnDevice->physicalDevice->neededQueueCount] = neededQueue;
|
||||
gryphnDevice->physicalDevice->neededQueueCount++;
|
||||
neededQueues[*neededQueueCount] = neededQueue;
|
||||
(*neededQueueCount)++;
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
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) {
|
||||
gnBool deviceCanPresentToSurface(gnInstance instance, gnPhysicalDevice physicalDevice, gnWindowSurface surface) {;
|
||||
uint32_t queueFamilyCount = 0;
|
||||
vkGetPhysicalDeviceQueueFamilyProperties(device->physicalDevice->device, &queueFamilyCount, NULL);
|
||||
vkGetPhysicalDeviceQueueFamilyProperties((VkPhysicalDevice)physicalDevice, &queueFamilyCount, NULL);
|
||||
for (uint32_t i = 0; i < queueFamilyCount; i++) {
|
||||
VkBool32 supportsPresent;
|
||||
vkGetPhysicalDeviceSurfaceSupportKHR(device->physicalDevice->device, i, surface->windowSurface->surface, &supportsPresent);
|
||||
vkGetPhysicalDeviceSurfaceSupportKHR((VkPhysicalDevice)physicalDevice, i, surface->windowSurface->surface, &supportsPresent);
|
||||
if (supportsPresent) return GN_TRUE;
|
||||
}
|
||||
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;
|
||||
|
@@ -1,23 +1,19 @@
|
||||
#pragma once
|
||||
#include "loader/src/gryphn_instance_functions.h"
|
||||
#include <vulkan/vulkan.h>
|
||||
#include <output_device/gryphn_physical_output_device.h>
|
||||
#include <output_device/gryphn_physical_device.h>
|
||||
|
||||
typedef struct vulkanNeededQueue {
|
||||
VkQueueFlags createFlags;
|
||||
gnBool usedForPresent;
|
||||
uint32_t queueIndex;
|
||||
} vulkanNeededQueue;
|
||||
vulkanNeededQueue* vulkanLoadNeededQueues(gnPhysicalDevice physicalDevice, uint32_t* neededQueueCount);
|
||||
|
||||
typedef struct gnPlatformPhysicalDevice_t {
|
||||
VkPhysicalDevice device;
|
||||
uint32_t neededQueueCount;
|
||||
vulkanNeededQueue* neededQueues;
|
||||
gnPhysicalDeviceProperties vulkanQueryPhysicalDeviceProperties(gnInstance instance, gnPhysicalDeviceHandle device, gryphnInstanceFunctionLayers* layers);
|
||||
gnPhysicalDeviceFeatures vulkanQueryPhysicalDeviceFeatures(gnInstance instance, gnPhysicalDeviceHandle device, gryphnInstanceFunctionLayers* layers);
|
||||
gnPhysicalDeviceLimits vulkanQueryPhysicalDeviceLimits(gnInstance instance, gnPhysicalDeviceHandle device, gryphnInstanceFunctionLayers* layers);
|
||||
|
||||
} gnPlatformPhysicalDevice;
|
||||
|
||||
gnPhysicalDevice* getPhysicalDevices(gnInstanceHandle instance, uint32_t* deviceCount);
|
||||
gnBool deviceCanPresentToSurface(gnPhysicalDevice device, gnWindowSurface surface);
|
||||
|
||||
|
||||
gnMultisampleCountFlags vkSampleCountToGryphn(VkSampleCountFlags counts);
|
||||
VkSampleCountFlags gnSampleCountToVulkan(gnMultisampleCountFlags counts);
|
||||
gnBool deviceCanPresentToSurface(gnInstance instance, gnPhysicalDevice device, gnWindowSurface surface);
|
||||
gnSampleCountFlags vkSampleCountToGryphn(VkSampleCountFlags counts);
|
||||
VkSampleCountFlags gnSampleCountToVulkan(gnSampleCountFlags counts);
|
||||
|
@@ -144,8 +144,15 @@ void VkCopyBufferToImage(VkGryphnBuffer buffer, VkGryphnImage image, gnExtent3D
|
||||
gnReturnCode createTexture(gnTexture texture, gnDevice device, const gnTextureInfo info) {
|
||||
texture->texture = malloc(sizeof(struct gnPlatformTexture_t));
|
||||
size_t imageSize = info.extent.width * info.extent.height;
|
||||
if (info.format == GN_FORMAT_BGRA8_SRGB) { imageSize *= 4; }
|
||||
if (info.format == GN_FORMAT_RGBA8_SRGB) { imageSize *= 4; }
|
||||
switch (info.format) {
|
||||
case GN_FORMAT_NONE: imageSize *= 0; break;
|
||||
case GN_FORMAT_BGRA8_SRGB: imageSize *= 4; break;
|
||||
case GN_FORMAT_BGRA8: imageSize *= 4; break;
|
||||
case GN_FORMAT_RGBA8: imageSize *= 4; break;
|
||||
case GN_FORMAT_RGBA8_SRGB: imageSize *= 4; break;
|
||||
case GN_FORMAT_D32S8_UINT: imageSize *= 5; break;
|
||||
case GN_FORMAT_D24S8_UINT: imageSize *= 4; break;
|
||||
};
|
||||
texture->texture->size = imageSize;
|
||||
VkImageCreateInfo imageInfo = {
|
||||
.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
|
||||
|
@@ -2,7 +2,6 @@
|
||||
#include <instance/vulkan_instance.h>
|
||||
#include "vulkan_surface.h"
|
||||
#include <output_device/vulkan_physical_device.h>
|
||||
#include "vulkan_result_converter.h"
|
||||
|
||||
#ifdef GN_PLATFORM_LINUX
|
||||
#ifdef GN_WINDOW_X11
|
||||
@@ -57,16 +56,17 @@ void destroyWindowSurface(struct gnWindowSurface_t* windowSurface) {
|
||||
}
|
||||
|
||||
gnSurfaceFormat* vkGetSurfaceFormats(
|
||||
struct gnWindowSurface_t* windowSurface, gnPhysicalDevice device, uint32_t* formatCount
|
||||
struct gnWindowSurface_t* windowSurface, gnPhysicalDevice deviceHandle, uint32_t* formatCount
|
||||
) {
|
||||
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);
|
||||
VkSurfaceFormatKHR* vkFormats = malloc(sizeof(VkSurfaceFormatKHR) * *formatCount);;
|
||||
|
||||
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++) {
|
||||
switch (vkFormats[i].format) {
|
||||
case VK_FORMAT_B8G8R8A8_SRGB: { formats[i].format = GN_FORMAT_BGRA8_SRGB; break; }
|
||||
@@ -85,13 +85,13 @@ gnSurfaceFormat* vkGetSurfaceFormats(
|
||||
}
|
||||
|
||||
gnSurfaceDetails getSurfaceDetails(
|
||||
gnWindowSurfaceHandle windowSurface, gnPhysicalDevice device
|
||||
gnWindowSurfaceHandle windowSurface, gnPhysicalDevice deviceHandle
|
||||
) {
|
||||
gnSurfaceDetails surfaceDetails;
|
||||
surfaceDetails.formats = vkGetSurfaceFormats(windowSurface, device, &surfaceDetails.formatCount);
|
||||
surfaceDetails.formats = vkGetSurfaceFormats(windowSurface, deviceHandle, &surfaceDetails.formatCount);
|
||||
|
||||
VkSurfaceCapabilitiesKHR details;
|
||||
vkGetPhysicalDeviceSurfaceCapabilitiesKHR(device->physicalDevice->device, windowSurface->windowSurface->surface, &details);
|
||||
vkGetPhysicalDeviceSurfaceCapabilitiesKHR((VkPhysicalDevice)deviceHandle, windowSurface->windowSurface->surface, &details);
|
||||
|
||||
surfaceDetails.minImageCount = details.minImageCount;
|
||||
surfaceDetails.maxImageCount = details.maxImageCount;
|
||||
@@ -109,6 +109,7 @@ VkFormat vkGryphnFormatToVulkanFormat(gnImageFormat format) {
|
||||
case GN_FORMAT_NONE: return VK_FORMAT_UNDEFINED;
|
||||
case GN_FORMAT_BGRA8_SRGB: return VK_FORMAT_B8G8R8A8_SRGB;
|
||||
case GN_FORMAT_BGRA8: return VK_FORMAT_B8G8R8A8_UNORM;
|
||||
case GN_FORMAT_RGBA8: return VK_FORMAT_R8G8B8A8_UNORM;
|
||||
case GN_FORMAT_RGBA8_SRGB: return VK_FORMAT_R8G8B8A8_SRGB;
|
||||
case GN_FORMAT_D32S8_UINT: return VK_FORMAT_D32_SFLOAT_S8_UINT;
|
||||
case GN_FORMAT_D24S8_UINT: return VK_FORMAT_D24_UNORM_S8_UINT;
|
||||
|
@@ -2,8 +2,9 @@
|
||||
|
||||
typedef enum gnImageFormat {
|
||||
GN_FORMAT_NONE,
|
||||
GN_FORMAT_BGRA8_SRGB,
|
||||
GN_FORMAT_BGRA8,
|
||||
GN_FORMAT_BGRA8_SRGB,
|
||||
GN_FORMAT_RGBA8,
|
||||
GN_FORMAT_RGBA8_SRGB,
|
||||
GN_FORMAT_D24S8_UINT,
|
||||
GN_FORMAT_D32S8_UINT,
|
||||
|
@@ -2,8 +2,6 @@
|
||||
#include "command/command_pool/gryphn_command_pool.h"
|
||||
#include "instance/gryphn_instance.h"
|
||||
|
||||
#include "stdio.h"
|
||||
|
||||
gnReturnCode gnCommandPoolAllocateCommandBuffersFromPointer(gnCommandBufferHandle* buffers, uint32_t count, gnCommandPoolHandle commandPool) {
|
||||
for (uint32_t i = 0; i < count; i++) {
|
||||
buffers[i] = malloc(sizeof(struct gnCommandBuffer_t));
|
||||
|
@@ -10,9 +10,15 @@ typedef struct type##_t* type##Handle; \
|
||||
typedef struct type##_t* type
|
||||
|
||||
// The value of this handle is defined by the implementation
|
||||
#ifndef GN_IMPLEMENTATION
|
||||
#define GN_IMPLEMENTATION_HANDLE(type) \
|
||||
typedef uint64_t type##Handle; \
|
||||
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
|
||||
#define GN_HANDLE_ALIAS(handle, alias) \
|
||||
@@ -20,14 +26,12 @@ typedef struct handle##_t* alias##Handle; \
|
||||
typedef struct handle##_t* alias
|
||||
|
||||
GN_HANDLE(gnInstance);
|
||||
|
||||
GN_IMPLEMENTATION_HANDLE(gnPhysicalDevice); // NOTE: needs to become a impl handle
|
||||
|
||||
GN_HANDLE(gnWindowSurface);
|
||||
GN_HANDLE(gnPresentationQueue);
|
||||
GN_HANDLE(gnTexture);
|
||||
GN_HANDLE(gnRenderPassDescriptor);
|
||||
GN_HANDLE(gnPhysicalOutputDevice);
|
||||
GN_HANDLE_ALIAS(gnPhysicalOutputDevice, gnPhysicalDevice);
|
||||
GN_HANDLE(gnOutputDevice);
|
||||
GN_HANDLE_ALIAS(gnOutputDevice, gnDevice);
|
||||
GN_HANDLE(gnShaderModule);
|
||||
|
@@ -84,6 +84,14 @@ gnReturnCode gnCreateInstance(gnInstanceHandle* instance, gnInstanceCreateInfo*
|
||||
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) {
|
||||
if (instance == GN_NULL_HANDLE) return;
|
||||
(*instance)->functions->destroyInstance(*instance, (*instance)->functions->next, &(*instance)->allocators);
|
||||
|
@@ -7,7 +7,6 @@
|
||||
#include "gryphn_allocators.h"
|
||||
#include <gryphn_extensions.h>
|
||||
|
||||
|
||||
typedef struct gnApplicationInfo {
|
||||
gnString applicationName;
|
||||
gnVersion applicationVersion;
|
||||
@@ -16,6 +15,10 @@ typedef struct gnApplicationInfo {
|
||||
gnVersion engineVersion;
|
||||
} gnApplicationInfo;
|
||||
|
||||
typedef enum gnSuitableField {
|
||||
GN_NON_EXISTANT_PHYSICAL_DEVICE
|
||||
} gnSuitableField;
|
||||
|
||||
typedef struct gnInstanceCreateInfo {
|
||||
gnApplicationInfo applicationInfo;
|
||||
gnDebuggerCreateInfo debuggerInfo;
|
||||
@@ -45,4 +48,6 @@ struct gnInstance_t {
|
||||
#endif
|
||||
|
||||
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);
|
||||
|
@@ -1,5 +1,5 @@
|
||||
#pragma once
|
||||
#include <output_device/gryphn_physical_output_device.h>
|
||||
#include <output_device/gryphn_physical_device.h>
|
||||
#include <core/gryphn_return_code.h>
|
||||
|
||||
typedef struct gnOutputDeviceEnabledFeatures {
|
||||
@@ -24,7 +24,6 @@ typedef struct gnOutputDeviceInfo {
|
||||
struct gnOutputDevice_t {
|
||||
struct gnPlatformOutputDevice_t* outputDevice;
|
||||
gnOutputDeviceInfo deviceInfo;
|
||||
|
||||
gnInstanceHandle instance;
|
||||
};
|
||||
#endif
|
||||
|
19
projects/core/src/output_device/gryphn_physical_device.c
Normal file
19
projects/core/src/output_device/gryphn_physical_device.c
Normal 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);
|
||||
}
|
119
projects/core/src/output_device/gryphn_physical_device.h
Normal file
119
projects/core/src/output_device/gryphn_physical_device.h
Normal 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);
|
@@ -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; }
|
@@ -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);
|
@@ -47,7 +47,7 @@ typedef struct gnScissor {
|
||||
} gnScissor;
|
||||
|
||||
typedef struct gnMultisample {
|
||||
gnMultisampleCountFlags samples;
|
||||
gnSampleCountFlags samples;
|
||||
} gnMultisample;
|
||||
|
||||
typedef enum gnFillMode {
|
||||
|
@@ -2,7 +2,7 @@
|
||||
#include "stdint.h"
|
||||
#include "core/gryphn_image_format.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"
|
||||
|
||||
typedef enum gnRenderPassStage {
|
||||
@@ -34,7 +34,7 @@ typedef struct gnRenderPassAttachmentInfo_t {
|
||||
gnImageLayout initialLayout;
|
||||
gnImageLayout finalLayout;
|
||||
|
||||
gnMultisampleCountFlags samples;
|
||||
gnSampleCountFlags samples;
|
||||
} gnRenderPassAttachmentInfo;
|
||||
|
||||
typedef struct gnSubpassAttachmentInfo_t {
|
||||
|
@@ -6,6 +6,7 @@ gnReturnCode gnCreateTexture(gnTexture* texture, gnDevice device, const gnTextur
|
||||
*texture = malloc(sizeof(struct gnTexture_t));
|
||||
(*texture)->device = device;
|
||||
(*texture)->info = info;
|
||||
|
||||
return device->instance->callingLayer->deviceFunctions._gnCreateTexture(*texture, device, info);
|
||||
}
|
||||
|
||||
@@ -13,5 +14,6 @@ void gnTextureData(gnTextureHandle texture, void* pixelData) {
|
||||
texture->device->instance->callingLayer->deviceFunctions._gnTextureData(texture, pixelData);
|
||||
}
|
||||
void gnDestroyTexture(gnTexture texture) {
|
||||
if (texture == GN_NULL_HANDLE) return;
|
||||
texture->device->instance->callingLayer->deviceFunctions._gnDestroyTexture(texture);
|
||||
}
|
||||
|
@@ -2,7 +2,7 @@
|
||||
#include "core/gryphn_image_format.h"
|
||||
#include "core/gryphn_return_code.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>
|
||||
|
||||
typedef enum gnTextureType {
|
||||
@@ -27,7 +27,7 @@ typedef enum gnTextureUsageFlags {
|
||||
|
||||
typedef struct gnTextureInfo {
|
||||
gnExtent3D extent;
|
||||
gnMultisampleCountFlags samples;
|
||||
gnSampleCountFlags samples;
|
||||
gnTextureUsageFlags usage;
|
||||
uint32_t mipmapLevels;
|
||||
gnTextureType type;
|
||||
|
@@ -16,4 +16,4 @@ typedef struct gnQueueFamilyProperties {
|
||||
gnQueueTypeFlags queueTypeFlags;
|
||||
} gnQueueFamilyProperties;
|
||||
|
||||
gnReturnCode gnGetPhysicalDeviceQueueProperties(gnPhysicalOutputDeviceHandle device, uint32_t queueCount, gnQueueFamilyProperties* queues);
|
||||
gnReturnCode gnGetPhysicalDeviceQueueProperties(gnPhysicalDeviceHandle device, uint32_t queueCount, gnQueueFamilyProperties* queues);
|
||||
|
@@ -10,7 +10,7 @@ typedef struct gnPresentInfo gnPresentInfo;
|
||||
typedef struct gnPresentSyncInfo gnPresentSyncInfo;
|
||||
|
||||
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);
|
||||
|
||||
gnReturnCode (*_gnQueueSubmit)(gnOutputDevice device, gnQueue queue, gnSubmitInfo info);
|
||||
|
@@ -8,7 +8,10 @@
|
||||
typedef struct gnInstanceCreateInfo gnInstanceCreateInfo;
|
||||
typedef struct gnSurfaceDetails gnSurfaceDetails;
|
||||
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_WINDOW_X11
|
||||
@@ -20,12 +23,17 @@ typedef struct gnOutputDeviceInfo gnOutputDeviceInfo;
|
||||
#endif
|
||||
|
||||
typedef struct gryphnInstanceFunctionLayers gryphnInstanceFunctionLayers;
|
||||
typedef gnReturnCode (*PFN_gnCreateInstance)(gnInstanceHandle instance, gnInstanceCreateInfo* info, gryphnInstanceFunctionLayers* next, gnAllocators* alloctors);
|
||||
typedef void (*PFN_gnDestroyInstance)(gnInstanceHandle instance, gryphnInstanceFunctionLayers* next, gnAllocators* alloctors);
|
||||
typedef gnReturnCode (*PFN_gnCreateInstance)(gnInstanceHandle, gnInstanceCreateInfo*, gryphnInstanceFunctionLayers*, gnAllocators*);
|
||||
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 {
|
||||
gnPhysicalDevice* (*_gnGetPhysicalDevices)(gnInstanceHandle instance, uint32_t* count);
|
||||
gnBool (*_gnPhysicalDeviceCanPresentToSurface)(gnPhysicalDevice device, gnWindowSurfaceHandle windowSurface);
|
||||
gnBool (*_gnPhysicalDeviceCanPresentToSurface)(gnInstance instance, gnPhysicalDevice device, gnWindowSurfaceHandle windowSurface);
|
||||
|
||||
gnReturnCode (*_gnCreateOutputDevice)(gnInstanceHandle instance, gnOutputDeviceHandle device, gnOutputDeviceInfo deviceInfo);
|
||||
void (*_gnDestroyOutputDevice)(gnOutputDeviceHandle device);
|
||||
|
@@ -84,7 +84,9 @@ gnCommandFunctions loadAPICommandFunctions(gnRenderingAPI api) {
|
||||
case GN_RENDERINGAPI_SOFTWARE: return (gnCommandFunctions){ NULL };
|
||||
case GN_RENDERINGAPI_DIRECTX11: return (gnCommandFunctions){ NULL };
|
||||
case GN_RENDERINGAPI_DIRECTX12: return (gnCommandFunctions){ NULL };
|
||||
case GN_RENDERINGAPI_OPENGL: return (gnCommandFunctions){ NULL };
|
||||
#ifdef GN_API_OPENGL
|
||||
case GN_RENDERINGAPI_OPENGL: return loadOpenGLCommandFunctions();
|
||||
#endif
|
||||
#ifdef GN_API_METAL
|
||||
case GN_RENDERINGAPI_METAL: return loadMetalCommandFunctions();
|
||||
#endif
|
||||
|
@@ -15,7 +15,12 @@ typedef struct gryphnFunctionLayer {
|
||||
|
||||
typedef struct gryphnInstanceFunctionLayers {
|
||||
PFN_gnCreateInstance createInstance;
|
||||
PFN_gnIsInstanceSuitable isSuitable;
|
||||
PFN_gnInstanceQueryDevices queryDevices;
|
||||
PFN_gnDestroyInstance destroyInstance;
|
||||
PFN_gnQueryPhysicalDeviceProperties getPhysicalDeviceProperties;
|
||||
PFN_gnQueryPhysicalDeviceFeatures getPhysicalDeviceFeatures;
|
||||
PFN_gnQueryPhysicalDeviceLimits getPhysicalDeviceLimits;
|
||||
struct gryphnInstanceFunctionLayers* next;
|
||||
} gryphnInstanceFunctionLayers;
|
||||
|
||||
|
Submodule projects/utils updated: 9f98da3b31...7d818db7f9
@@ -1,6 +1,6 @@
|
||||
#include "queue_functions.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/instance/gryphn_debugger.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_present.h"
|
||||
|
||||
gnReturnCode checkGetPhysicalDeviceQueueProperties(gnPhysicalOutputDeviceHandle device, uint32_t queueCount, gnQueueFamilyProperties* queues) {
|
||||
CHECK_FUNCTION_WITH_RETURN_CODE(device->instance, _gnGetPhysicalDeviceQueueProperties, queueFunctions, device, queueCount, queues);
|
||||
gnReturnCode checkGetPhysicalDeviceQueueProperties(gnPhysicalDeviceHandle device, uint32_t queueCount, gnQueueFamilyProperties* 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) {
|
||||
CHECK_VOID_FUNCTION(device->instance, _gnGetDeviceQueue, queueFunctions, device, queueFamily, queueIndex, queue);
|
||||
|
@@ -1,6 +1,6 @@
|
||||
#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);
|
||||
|
||||
gnReturnCode checkQueueSubmit(gnOutputDevice device, gnQueue queue, gnSubmitInfo info);
|
||||
|
@@ -8,13 +8,18 @@
|
||||
gryphnInstanceFunctionLayers checkerLoadInstanceFunctions(void) {
|
||||
return (gryphnInstanceFunctionLayers) {
|
||||
.createInstance = checkCreateInstance,
|
||||
.destroyInstance = checkDestroyInstance
|
||||
.isSuitable = checkIsInstanceSuitable,
|
||||
.queryDevices = checkQueryDevices,
|
||||
.destroyInstance = checkDestroyInstance,
|
||||
.getPhysicalDeviceProperties = checkQueryPhysicalDeviceProperties,
|
||||
.getPhysicalDeviceFeatures = checkQueryPhysicalDeviceFeatures,
|
||||
.getPhysicalDeviceLimits = checkQueryPhysicalDeviceLimits,
|
||||
.next = GN_NULL_HANDLE
|
||||
};
|
||||
}
|
||||
|
||||
gnInstanceFunctions loadFunctionLoaderInstanceFunctions(void) {
|
||||
return (gnInstanceFunctions){
|
||||
._gnGetPhysicalDevices = checkGetPhysicalDevices,
|
||||
._gnPhysicalDeviceCanPresentToSurface = checkCanDevicePresent,
|
||||
|
||||
._gnCreateOutputDevice = checkCreateOutputDevice,
|
||||
|
@@ -24,11 +24,61 @@ void checkDestroyInstance(gnInstanceHandle instance, gryphnInstanceFunctionLayer
|
||||
next->destroyInstance(instance, next->next, alloctors);
|
||||
}
|
||||
|
||||
gnPhysicalDevice* checkGetPhysicalDevices(gnInstanceHandle instance, uint32_t* count) {
|
||||
CHECK_RETURNED_FUNCTION(instance, _gnGetPhysicalDevices, instanceFunctions, NULL, instance, count);
|
||||
gnBool checkIsInstanceSuitable(gnInstanceHandle instance, gnSuitableField field, gryphnInstanceFunctionLayers* next) {
|
||||
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) {
|
||||
CHECK_RETURNED_FUNCTION(device->instance, _gnPhysicalDeviceCanPresentToSurface, instanceFunctions, GN_FALSE, device, windowSurface);
|
||||
return next->isSuitable(instance, field, next);
|
||||
}
|
||||
|
||||
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) {
|
||||
|
@@ -3,11 +3,16 @@
|
||||
#include <core/src/window_surface/gryphn_surface_create_functions.h>
|
||||
|
||||
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);
|
||||
|
||||
gnPhysicalDevice* checkGetPhysicalDevices(gnInstanceHandle instance, uint32_t* count);
|
||||
gnBool checkCanDevicePresent(gnPhysicalDevice device, gnWindowSurfaceHandle windowSurface);
|
||||
gnPhysicalDeviceProperties checkQueryPhysicalDeviceProperties(gnInstanceHandle instance, gnPhysicalDeviceHandle device, gryphnInstanceFunctionLayers* next);
|
||||
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);
|
||||
void checkDestroyOutputDevice(gnOutputDeviceHandle device);
|
||||
|
||||
|
Reference in New Issue
Block a user