Compare commits
99 Commits
b0db5bfd22
...
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 | ||
![]() |
70f8d5f31d | ||
![]() |
94fb6fa2dc | ||
![]() |
3c8205c20f | ||
![]() |
9b0a90f8fc | ||
![]() |
499fa5b1e7 | ||
![]() |
baac536897 | ||
![]() |
0736d87d23 | ||
![]() |
96808c1940 | ||
![]() |
acf2f8c228 | ||
![]() |
ddd28858ef | ||
![]() |
56d79663a2 | ||
![]() |
dd5f1485d9 |
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
|
||||
|
@@ -36,8 +36,7 @@ add_subdirectory(projects/platform) # build gryphn platform
|
||||
|
||||
add_subdirectory(projects/validation_layers/function_loader/)
|
||||
add_subdirectory(projects/validation_layers/allocators/)
|
||||
|
||||
target_link_libraries(Gryphn INTERFACE GryphnUtils GryphnCore GryphnLoader GryphnPlatform GryphnFunctionValidator GryphnAllocatorChecker GryphnExtensions)
|
||||
target_link_libraries(Gryphn INTERFACE GryphnCore GryphnLoader GryphnPlatform GryphnFunctionValidator GryphnAllocatorChecker GryphnExtensions)
|
||||
|
||||
if (VULKAN_BUILT)
|
||||
target_link_libraries(Gryphn INTERFACE GryphnVulkanImpl)
|
||||
@@ -48,3 +47,5 @@ endif()
|
||||
if (OPENGL_BUILT)
|
||||
target_link_libraries(Gryphn INTERFACE GryphnOpenGLImpl)
|
||||
endif()
|
||||
|
||||
target_link_libraries(Gryphn INTERFACE GryphnUtils)
|
||||
|
@@ -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) {
|
||||
if (device == GN_NULL_HANDLE || windowSurface == GN_NULL_HANDLE) return GN_FALSE;
|
||||
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
|
||||
};
|
||||
|
8
projects/apis/opengl/loader/opengl_extensions.c
Normal file
8
projects/apis/opengl/loader/opengl_extensions.c
Normal file
@@ -0,0 +1,8 @@
|
||||
#include "opengl_loader.h"
|
||||
#include "gryphn_extensions.h"
|
||||
|
||||
gnBool openglIsExtensionSupported(gnExtension extension) {
|
||||
if (extension == GN_EXT_SYNCHRONIZATION) return GN_FALSE;
|
||||
if (extension == GN_EXT_QUEUES) return GN_FALSE;
|
||||
return GN_FALSE;
|
||||
}
|
@@ -4,12 +4,18 @@
|
||||
#include "device/opengl_physical_device.h"
|
||||
#include "device/opengl_output_device.h"
|
||||
|
||||
gryphnInstanceFunctionLayers loadOpenGLAPILayer() {
|
||||
return (gryphnInstanceFunctionLayers) {
|
||||
.createInstance = openglCreateInstance,
|
||||
.destroyInstance = openglDestroyInstance,
|
||||
NULL
|
||||
};
|
||||
}
|
||||
|
||||
gnInstanceFunctions loadOpenGLInstanceFunctions() {
|
||||
return (gnInstanceFunctions){
|
||||
._gnCreateInstance = createOpenGLInstance,
|
||||
._gnDestroyInstance = destroyOpenGLInstance,
|
||||
._gnGetPhysicalDevices = getOpenGLDevice,
|
||||
._gnQueueCanPresentToSurface = openGLQueueCanPresent,
|
||||
._gnPhysicalDeviceCanPresentToSurface = openglCanDevicePresent,
|
||||
._gnCreateOutputDevice = createOpenGLOutputDevice,
|
||||
._gnDestroyOutputDevice = destroyOpenGLOutputDevice,
|
||||
#ifdef GN_PLATFORM_LINUX
|
||||
|
@@ -2,7 +2,11 @@
|
||||
#include "loader/src/gryphn_instance_functions.h"
|
||||
#include "loader/src/gryphn_device_functions.h"
|
||||
#include "loader/src/gryphn_command_functions.h"
|
||||
#include "gryphn_extensions.h"
|
||||
|
||||
gnInstanceFunctions loadOpenGLInstanceFunctions();
|
||||
gnDeviceFunctions loadOpenGLDeviceFunctions();
|
||||
gnCommandFunctions loadOpenGLCommandFunctions();
|
||||
|
||||
gryphnInstanceFunctionLayers loadOpenGLAPILayer();
|
||||
gnBool openglIsExtensionSupported(gnExtension extension);
|
||||
|
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(gnOutputDeviceHandle outputDevice, gnInstanceHandle instance, 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,8 +1,10 @@
|
||||
#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(gnOutputDeviceHandle outputDevice, gnInstanceHandle instance, gnOutputDeviceInfo deviceInfo);
|
||||
gnReturnCode createOpenGLOutputDevice(gnInstanceHandle instance, gnOutputDeviceHandle device, gnOutputDeviceInfo deviceInfo);
|
||||
void waitForOpenGLDevice(const gnOutputDeviceHandle device);
|
||||
void destroyOpenGLOutputDevice(gnOutputDeviceHandle device);
|
||||
|
@@ -1,35 +1,26 @@
|
||||
#include "opengl_physical_device.h"
|
||||
#include "stdlib.h"
|
||||
|
||||
gnPhysicalDevice* getOpenGLDevice(gnInstanceHandle instance, uint32_t* deviceCount) {
|
||||
*deviceCount = 1;
|
||||
|
||||
gnPhysicalDevice* devices = malloc(sizeof(gnPhysicalDevice));
|
||||
|
||||
gnPhysicalDevice device = {
|
||||
devices[0] = malloc(sizeof(struct gnPhysicalOutputDevice_t));
|
||||
*devices[0] = (struct gnPhysicalOutputDevice_t){
|
||||
.physicalDevice = malloc(sizeof(gnPlatformPhysicalDevice)),
|
||||
.features = {
|
||||
.maxColorSamples = GN_SAMPLE_BIT_1,
|
||||
.maxDepthSamples = GN_SAMPLE_BIT_1,
|
||||
.maxMemoryAllocations = 0x40000000,
|
||||
.maxPushConstantSize = 256
|
||||
.maxPushConstantSize = 0
|
||||
},
|
||||
.properties = {
|
||||
.deviceType = GN_DEDICATED_DEVICE,
|
||||
.name = gnCreateString("Generic OpenGL device")
|
||||
},
|
||||
.queueProperties = {
|
||||
.queueCount = 1,
|
||||
.queueProperties = (gnQueueProperties[1]){
|
||||
(gnQueueProperties){
|
||||
.queueCount = 1,
|
||||
.queueType = GN_QUEUE_GRAPHICS
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
devices[0] = device;
|
||||
return devices;
|
||||
}
|
||||
gnBool openGLQueueCanPresent(const gnPhysicalDevice device, uint32_t queueIndex, gnWindowSurfaceHandle windowSurface) {
|
||||
return gnTrue;
|
||||
gnBool openglCanDevicePresent(gnPhysicalDevice device, gnWindowSurfaceHandle windowSurface) {
|
||||
return GN_TRUE;
|
||||
}
|
||||
|
@@ -5,4 +5,4 @@
|
||||
typedef struct gnPlatformPhysicalDevice_t {} gnPlatformPhysicalDevice;
|
||||
|
||||
gnPhysicalDevice* getOpenGLDevice(gnInstanceHandle instance, uint32_t* deviceCount);
|
||||
gnBool openGLQueueCanPresent(const gnPhysicalDevice device, uint32_t queueIndex, gnWindowSurfaceHandle windowSurface);
|
||||
gnBool openglCanDevicePresent(gnPhysicalDevice device, gnWindowSurfaceHandle windowSurface);
|
||||
|
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);
|
@@ -1,8 +1,12 @@
|
||||
#include "opengl_instance.h"
|
||||
|
||||
gnReturnCode createOpenGLInstance(gnInstanceHandle instance, gnInstanceInfo instanceInfo) {
|
||||
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 destroyOpenGLInstance(gnInstanceHandle instance) {
|
||||
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 createOpenGLInstance(gnInstanceHandle instance, gnInstanceInfo instanceInfo);
|
||||
void destroyOpenGLInstance(gnInstanceHandle instance);
|
||||
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,39 +5,36 @@
|
||||
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);
|
||||
GLuintArrayListAdd(presentationQueue->presentationQueue->textures, presentationQueue->images[i]->texture->id);
|
||||
uint32_tArrayListAdd(presentationQueue->presentationQueue->avaliableTextures, i);
|
||||
}
|
||||
return GN_SUCCESS;
|
||||
}
|
||||
gnReturnCode getOpenGLPresentationQueueImage(gnPresentationQueue presentationQueue, uint32_t* imageIndex) {
|
||||
while (presentationQueue->presentationQueue->avaliableTextures.count == 0) {}
|
||||
*imageIndex = presentationQueue->presentationQueue->avaliableTextures.data[0];
|
||||
uint32_tArrayListPopHead(&presentationQueue->presentationQueue->avaliableTextures);
|
||||
while (uint32_tArrayListCount(presentationQueue->presentationQueue->avaliableTextures) == 0) {}
|
||||
*imageIndex = uint32_tArrayListAt(presentationQueue->presentationQueue->avaliableTextures, 0);
|
||||
uint32_tArrayListPopHead(presentationQueue->presentationQueue->avaliableTextures);
|
||||
return GN_SUCCESS;
|
||||
}
|
||||
void destroyOpenGLPresentationQueue(gnPresentationQueueHandle presentationQueue) {
|
||||
free(presentationQueue->presentationQueue);
|
||||
}
|
||||
|
||||
|
||||
|
||||
GN_ARRAY_LIST_DEFINITION(GLuint);
|
||||
|
@@ -2,11 +2,12 @@
|
||||
#include <glad/glad.h>
|
||||
#include "presentation_queue/gryphn_presentation_queue.h"
|
||||
|
||||
GN_ARRAY_LIST(GLuint);
|
||||
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,6 +1,55 @@
|
||||
#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
|
||||
@@ -17,11 +66,20 @@ gnReturnCode createGLXContext(gnWindowSurfaceHandle windowSurface, gnInstanceHan
|
||||
XVisualInfo* vi = glXChooseVisual(createInfo.display, 0, attribs);
|
||||
windowSurface->windowSurface->context = glXCreateContext(createInfo.display, vi, NULL, GL_TRUE);
|
||||
if (glXMakeCurrent(createInfo.display, createInfo.window, windowSurface->windowSurface->context) == GL_FALSE)
|
||||
return GN_FAILED_TO_ATTACH_WINDOW;
|
||||
return GN_WINDOW_IN_USE;
|
||||
windowSurface->windowSurface->window = createInfo.window;
|
||||
windowSurface->windowSurface->display = createInfo.display;
|
||||
if (!gladLoadGLLoader((GLADloadproc)glXGetProcAddress))
|
||||
return GN_FAILED_TO_INIT_OPENGL;
|
||||
if (!gladLoadGLLoader((GLADloadproc)glXGetProcAddress)) {
|
||||
gnDebuggerSetErrorMessage(instance->debugger, (gnMessageData){
|
||||
.message = gnCreateString("Failed to load OpenGL functions")
|
||||
});
|
||||
|
||||
return GN_UNKNOWN_ERROR;
|
||||
}
|
||||
|
||||
glEnable(GL_DEBUG_OUTPUT);
|
||||
glDebugMessageCallback(openglMessageCallback, instance);
|
||||
|
||||
return GN_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -31,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
|
||||
@@ -45,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;
|
||||
@@ -70,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")
|
||||
|
@@ -38,6 +38,7 @@ gnDeviceFunctions loadVulkanDeviceFunctions(void) {
|
||||
._gnBufferData = vulkanBufferData,
|
||||
._gnBufferSubData = vulkanBufferSubData,
|
||||
._gnMapBuffer = vulkanMapBuffer,
|
||||
._gnUnmapBuffer = vulkanUnmapBuffer,
|
||||
._gnDestroyBuffer = destroyBuffer,
|
||||
|
||||
._gnCreateUniformPool = createUniformPool,
|
||||
|
@@ -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)
|
||||
|
||||
@@ -83,10 +84,11 @@ gnReturnCode vulkanCreateInstance(gnInstanceHandle instance, gnInstanceCreateInf
|
||||
#endif
|
||||
|
||||
VkDebugUtilsMessengerCreateInfoEXT debugCreateInfo;
|
||||
const char* enabledLayerNames = "VK_LAYER_KHRONOS_validation";
|
||||
if (instance->enabledLayerCounts[GN_DEBUGGER_LAYER_PLATFORM] > 0) {
|
||||
vkStringArrayListAdd(extensions, VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
|
||||
createInfo.enabledLayerCount = 1;
|
||||
createInfo.ppEnabledLayerNames = (const char*[]){ "VK_LAYER_KHRONOS_validation" };
|
||||
createInfo.ppEnabledLayerNames = &enabledLayerNames;
|
||||
|
||||
instance->instance->userData.debuggerCallback = instanceInfo->debuggerInfo.callback;
|
||||
instance->instance->userData.userData = instanceInfo->debuggerInfo.userData;
|
||||
@@ -108,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,22 +8,27 @@
|
||||
#include "vulkan_result_converter.h"
|
||||
#include "string.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 {
|
||||
@@ -32,6 +37,7 @@ gnReturnCode createVulkanOutputDevice(gnInstanceHandle instance, gnOutputDeviceH
|
||||
for (uint32_t i = 0; i < deviceInfo.queueInfoCount; i++) {
|
||||
queueCreateInfos[i].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
|
||||
queueCreateInfos[i].flags = 0;
|
||||
queueCreateInfos[i].pNext = NULL;
|
||||
queueCreateInfos[i].queueCount = deviceInfo.queueInfos[i].queueCount;
|
||||
queueCreateInfos[i].queueFamilyIndex = deviceInfo.queueInfos[i].queueFamilyIndex;
|
||||
queueCreateInfos[i].pQueuePriorities = deviceInfo.queueInfos[i].queuePrioritys;
|
||||
@@ -44,11 +50,13 @@ gnReturnCode createVulkanOutputDevice(gnInstanceHandle instance, gnOutputDeviceH
|
||||
|
||||
VkDeviceCreateInfo deviceCreateInfo = {
|
||||
.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
|
||||
.flags = 0,
|
||||
.pNext = NULL,
|
||||
.queueCreateInfoCount = createQueueCount,
|
||||
.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++)
|
||||
@@ -61,31 +69,38 @@ 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;
|
||||
for (uint32_t i = 0; i < deviceInfo.physicalDevice->physicalDevice->neededQueueCount; i++) {
|
||||
device->outputDevice->queues[i].queueInfo = deviceInfo.physicalDevice->physicalDevice->neededQueues[i];
|
||||
gnBool foundTransferQueue = GN_FALSE, foundGraphicsQueue = GN_FALSE;
|
||||
|
||||
vkGetDeviceQueue(device->outputDevice->device, deviceInfo.physicalDevice->physicalDevice->neededQueues[i].queueIndex, 0, &device->outputDevice->queues[i].queue);
|
||||
if ((device->outputDevice->queues[i].queueInfo.createFlags & VK_QUEUE_TRANSFER_BIT) == VK_QUEUE_TRANSFER_BIT) {
|
||||
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;
|
||||
foundTransferQueue = GN_TRUE;
|
||||
}
|
||||
|
||||
if ((device->outputDevice->queues[i].queueInfo.createFlags & VK_QUEUE_GRAPHICS_BIT) == VK_QUEUE_GRAPHICS_BIT) {
|
||||
if ((device->outputDevice->queues[i].queueInfo.createFlags & VK_QUEUE_GRAPHICS_BIT) == VK_QUEUE_GRAPHICS_BIT && !foundGraphicsQueue) {
|
||||
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,
|
||||
.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,
|
||||
.queueFamilyIndex = transferQueue
|
||||
.queueFamilyIndex = transferQueue,
|
||||
.pNext = NULL
|
||||
};
|
||||
|
||||
VkResult command_pool_result = vkCreateCommandPool(device->outputDevice->device, &poolInfo, NULL, &device->outputDevice->transferCommandPool);
|
||||
@@ -132,10 +147,10 @@ void waitForDevice(const gnOutputDeviceHandle device) {
|
||||
|
||||
void destroyVulkanOutputDevice(gnOutputDeviceHandle device) {
|
||||
vkDestroyFence(device->outputDevice->device, device->outputDevice->barrierFence, NULL);
|
||||
vmaDestroyBuffer(device->outputDevice->allocator, device->outputDevice->stagingBuffer.buffer, device->outputDevice->stagingBuffer.allocation);
|
||||
vkDestroyCommandPool(device->outputDevice->device, device->outputDevice->transferCommandPool, NULL);
|
||||
vkDestroyDevice(device->outputDevice->device, NULL);
|
||||
vmaDestroyBuffer(device->outputDevice->allocator, device->outputDevice->stagingBuffer.buffer, device->outputDevice->stagingBuffer.allocation);
|
||||
vmaDestroyAllocator(device->outputDevice->allocator);
|
||||
vkDestroyDevice(device->outputDevice->device, NULL);
|
||||
free(device->outputDevice);
|
||||
}
|
||||
|
||||
|
@@ -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,89 +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 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) {
|
||||
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 = 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;
|
||||
VkBool32 supportsPresent;
|
||||
vkGetPhysicalDeviceSurfaceSupportKHR((VkPhysicalDevice)physicalDevice, i, surface->windowSurface->surface, &supportsPresent);
|
||||
if (supportsPresent) return GN_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return foundQueue;
|
||||
return GN_FALSE;
|
||||
}
|
||||
|
@@ -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);
|
||||
|
@@ -1,6 +1,5 @@
|
||||
#include "vulkan_present.h"
|
||||
#include "extensions/synchronization/commands/gryphn_sync_present.h"
|
||||
#include "vulkan_surface/vulkan_surface.h"
|
||||
#include "vulkan_result_converter.h"
|
||||
|
||||
gnReturnCode vulkanQueuePresentSync(gnDevice device, gnQueue queue, gnPresentSyncInfo info) {
|
||||
@@ -25,7 +24,7 @@ gnReturnCode vulkanQueuePresentSync(gnDevice device, gnQueue queue, gnPresentSyn
|
||||
}
|
||||
|
||||
gnReturnCode vulkanPresentSync(gnDevice device, gnPresentSyncInfo info) {
|
||||
return vulkanQueuePresentSync(device, (gnQueue)device->outputDevice->queues[info.presentationQueues[0]->info.surface->windowSurface->presentQueueIndex].queue, info);
|
||||
return vulkanQueuePresentSync(device, (gnQueue)device->outputDevice->queues[info.presentationQueues[0]->presentationQueue->presentQueueIndex].queue, info);
|
||||
}
|
||||
|
||||
gnReturnCode vulkanQueuePresent(gnDevice device, gnQueue queue, gnPresentInfo info) {
|
||||
@@ -47,5 +46,5 @@ gnReturnCode vulkanQueuePresent(gnDevice device, gnQueue queue, gnPresentInfo in
|
||||
}
|
||||
|
||||
gnReturnCode vulkanPresent(gnDevice device, gnPresentInfo info) {
|
||||
return vulkanQueuePresent(device, (gnQueue)device->outputDevice->queues[info.presentationQueues[0]->info.surface->windowSurface->presentQueueIndex].queue, info);
|
||||
return vulkanQueuePresent(device, (gnQueue)device->outputDevice->queues[info.presentationQueues[0]->presentationQueue->presentQueueIndex].queue, info);
|
||||
}
|
||||
|
@@ -40,17 +40,25 @@ gnReturnCode createPresentationQueue(gnPresentationQueueHandle presentationQueue
|
||||
presentQueueCreateInfo.queueFamilyIndexCount = presentationInfo.queueFamilyCount;
|
||||
presentQueueCreateInfo.pQueueFamilyIndices = presentationInfo.queueFamilies;
|
||||
} else {
|
||||
if (presentationInfo.surface->windowSurface->presentQueueIndex != device->outputDevice->graphicsQueueIndex) {
|
||||
uint32_t queueFamilyCount = 0;
|
||||
vkGetPhysicalDeviceQueueFamilyProperties(device->outputDevice->physicalDevice, &queueFamilyCount, NULL);
|
||||
for (uint32_t i = 0; i < queueFamilyCount; i++) {
|
||||
VkBool32 supportsPresent;
|
||||
vkGetPhysicalDeviceSurfaceSupportKHR(device->outputDevice->physicalDevice, i, presentationInfo.surface->windowSurface->surface, &supportsPresent);
|
||||
if (supportsPresent) { presentationQueue->presentationQueue->presentQueueIndex = i; break; };
|
||||
}
|
||||
|
||||
if (presentationQueue->presentationQueue->presentQueueIndex != device->outputDevice->graphicsQueueIndex) {
|
||||
presentQueueCreateInfo.imageSharingMode = VK_SHARING_MODE_CONCURRENT;
|
||||
presentQueueCreateInfo.queueFamilyIndexCount = 2;
|
||||
presentQueueCreateInfo.pQueueFamilyIndices = (uint32_t[]){
|
||||
device->outputDevice->queues[presentationInfo.surface->windowSurface->presentQueueIndex].queueInfo.queueIndex,
|
||||
presentationQueue->presentationQueue->presentQueueIndex,
|
||||
device->outputDevice->queues[device->outputDevice->graphicsQueueIndex].queueInfo.queueIndex
|
||||
};
|
||||
} else {
|
||||
presentQueueCreateInfo.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
||||
presentQueueCreateInfo.queueFamilyIndexCount = 1;
|
||||
presentQueueCreateInfo.pQueueFamilyIndices = &device->outputDevice->queues[presentationInfo.surface->windowSurface->presentQueueIndex].queueInfo.queueIndex;
|
||||
presentQueueCreateInfo.pQueueFamilyIndices = &presentationQueue->presentationQueue->presentQueueIndex;
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -7,6 +7,8 @@ typedef struct gnPlatformPresentationQueue_t {
|
||||
|
||||
VkImage* swapChainImages;
|
||||
VkImageView* swapChainImageViews;
|
||||
|
||||
uint32_t presentQueueIndex;
|
||||
} gnPlatformPresentationQueue;
|
||||
|
||||
gnReturnCode createPresentationQueue(gnPresentationQueueHandle presentationQueue, const gnDevice device, gnPresentationQueueInfo presentationInfo);
|
||||
|
@@ -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,
|
||||
|
@@ -3,7 +3,6 @@
|
||||
#include "vulkan_surface.h"
|
||||
#include <output_device/vulkan_physical_device.h>
|
||||
|
||||
|
||||
#ifdef GN_PLATFORM_LINUX
|
||||
#ifdef GN_WINDOW_X11
|
||||
#include <vulkan/vulkan_xlib.h>
|
||||
@@ -14,11 +13,7 @@ gnReturnCode createX11WindowSurface(gnWindowSurfaceHandle windowSurface, gnInsta
|
||||
info.sType = VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR;
|
||||
info.dpy = createInfo.display;
|
||||
info.window = createInfo.window;
|
||||
|
||||
VkResult result = vkCreateXlibSurfaceKHR(instance->instance->vk_instance, &info, NULL, &windowSurface->windowSurface->surface);
|
||||
if (result != VK_SUCCESS)
|
||||
return GN_FAILED_TO_ATTACH_WINDOW;
|
||||
return GN_SUCCESS;
|
||||
return VkResultToGnReturnCode(vkCreateXlibSurfaceKHR(instance->instance->vk_instance, &info, NULL, &windowSurface->windowSurface->surface));
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -61,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; }
|
||||
@@ -89,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;
|
||||
@@ -113,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;
|
||||
|
@@ -5,7 +5,7 @@
|
||||
|
||||
typedef struct gnPlatformWindowSurface_t {
|
||||
VkSurfaceKHR surface;
|
||||
uint32_t presentQueueIndex;
|
||||
// uint32_t presentQueueIndex;
|
||||
} gnPlatformWindowSurface;
|
||||
|
||||
VkFormat vkGryphnFormatToVulkanFormat(gnImageFormat format);
|
||||
|
@@ -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,
|
||||
|
@@ -21,6 +21,9 @@ void* gnMapBuffer(gnBufferHandle buffer) {
|
||||
if (buffer->info.usage == GN_STATIC_DRAW) return NULL;
|
||||
return buffer->device->instance->callingLayer->deviceFunctions._gnMapBuffer(buffer);
|
||||
}
|
||||
void gnUnmapBuffer(gnBufferHandle buffer) {
|
||||
buffer->device->instance->callingLayer->deviceFunctions._gnUnmapBuffer(buffer);
|
||||
}
|
||||
void gnDestroyBuffer(gnBufferHandle buffer) {
|
||||
buffer->device->instance->callingLayer->deviceFunctions._gnDestroyBuffer(buffer);
|
||||
}
|
||||
|
@@ -44,4 +44,5 @@ gnReturnCode gnCreateBuffer(gnBufferHandle* buffer, gnOutputDeviceHandle device,
|
||||
void gnBufferData(gnBufferHandle buffer, size_t dataSize, gnBufferMemory data);
|
||||
void gnBufferSubData(gnBufferHandle buffer, size_t offset, size_t dataSize, gnBufferMemory data);
|
||||
gnBufferMemory gnMapBuffer(gnBufferHandle buffer);
|
||||
void gnUnmapBuffer(gnBufferHandle buffer);
|
||||
void gnDestroyBuffer(gnBufferHandle buffer);
|
||||
|
@@ -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);
|
||||
|
@@ -1,10 +1 @@
|
||||
#include "gryphn_debugger.h"
|
||||
|
||||
void gnDebuggerSetVerboseMessage(gnDebuggerCreateInfo* debugger, gnMessageData data) {
|
||||
debugger->callback(
|
||||
GN_MESSAGE_VERBOSE,
|
||||
GN_DEBUG_MESSAGE_GENERAL,
|
||||
data,
|
||||
debugger->userData
|
||||
);
|
||||
}
|
||||
|
@@ -43,9 +43,19 @@ typedef struct gnDebuggerCreateInfo {
|
||||
} gnDebuggerCreateInfo;
|
||||
|
||||
#ifdef GN_REVEAL_IMPL
|
||||
void gnDebuggerSetVerboseMessage(gnDebuggerCreateInfo* debugger, gnMessageData data);
|
||||
#include "stdlib.h"
|
||||
static inline void gnDebuggerSetVerboseMessage(gnDebuggerCreateInfo* debugger, gnMessageData data) {
|
||||
if (debugger->callback == 0 || debugger == NULL) return;
|
||||
debugger->callback(
|
||||
GN_MESSAGE_VERBOSE,
|
||||
GN_DEBUG_MESSAGE_GENERAL,
|
||||
data,
|
||||
debugger->userData
|
||||
);
|
||||
}
|
||||
|
||||
static inline void gnDebuggerSetErrorMessage(gnDebuggerCreateInfo debugger, gnMessageData data) {
|
||||
// if (debugger == NULL) return;
|
||||
if (debugger.callback == 0) return;
|
||||
debugger.callback(
|
||||
GN_MESSAGE_ERROR,
|
||||
GN_DEBUG_MESSAGE_VALIDATION,
|
||||
|
@@ -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);
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user