mirror of
https://github.com/Kbz-8/Pulse.git
synced 2026-01-11 15:33:34 +00:00
working on vulkan
This commit is contained in:
@@ -89,6 +89,7 @@ typedef enum PulseErrorType
|
||||
PULSE_ERROR_BACKENDS_CANDIDATES_SHADER_FORMAT_MISMATCH,
|
||||
PULSE_ERROR_INITIALIZATION_FAILED,
|
||||
PULSE_ERROR_INVALID_HANDLE,
|
||||
PULSE_ERROR_ALLOCATION_FAILED,
|
||||
} PulseErrorType;
|
||||
|
||||
typedef enum PulseImageType
|
||||
|
||||
@@ -116,11 +116,7 @@ extern "C" {
|
||||
|
||||
#define PULSE_DEFINE_NULLABLE_HANDLE(object) typedef struct object##Handler* object
|
||||
|
||||
#if (defined(__cplusplus) && (__cplusplus >= 201103L)) || (defined(_MSVC_LANG) && (_MSVC_LANG >= 201103L))
|
||||
#define PULSE_NULL_HANDLE nullptr
|
||||
#else
|
||||
#define PULSE_NULL_HANDLE ((void*)0)
|
||||
#endif
|
||||
#define PULSE_NULL_HANDLE PULSE_NULLPTR
|
||||
|
||||
#define PULSE_MAKE_VERSION(major, minor, patch) ((((uint32_t)(major)) << 22U) | (((uint32_t)(minor)) << 12U) | ((uint32_t)(patch)))
|
||||
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
// This file is part of "Pulse"
|
||||
// For conditions of distribution and use, see copyright notice in LICENSE
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <Pulse.h>
|
||||
#include "../../PulseInternal.h"
|
||||
|
||||
@@ -18,13 +20,33 @@ bool VulkanLoadBackend()
|
||||
{
|
||||
if(!VulkanInitLoader())
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
PulseDevice VulkanCreatePulseDevice(PulseDebugLevel debug_level)
|
||||
{
|
||||
VulkanPulseDevice* vulkan_device = (VulkanPulseDevice*)calloc(1, sizeof(VulkanPulseDevice));
|
||||
PULSE_CHECK_ALLOCATION_RETVAL(vulkan_device, PULSE_NULL_HANDLE);
|
||||
|
||||
if(!VulkanInitInstance(&vulkan_device->instance, debug_level))
|
||||
return PULSE_NULL_HANDLE;
|
||||
|
||||
PulseDeviceHandler* pulse_device = (PulseDeviceHandler*)calloc(1, sizeof(PulseDeviceHandler));
|
||||
PULSE_CHECK_ALLOCATION_RETVAL(pulse_device, PULSE_NULL_HANDLE);
|
||||
pulse_device->debug_level = debug_level;
|
||||
pulse_device->driver_data = vulkan_device;
|
||||
return pulse_device;
|
||||
}
|
||||
|
||||
void VulkanDestroyPulseDevice(PulseDevice device)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
PulseBackendLoader VulkanDriver = {
|
||||
.PFN_LoadBackend = VulkanLoadBackend,
|
||||
.PFN_CreateDevice = PULSE_NULLPTR,
|
||||
.PFN_CreateDevice = VulkanCreatePulseDevice,
|
||||
.PFN_DestroyDevice = VulkanDestroyPulseDevice,
|
||||
.backend = PULSE_BACKEND_VULKAN,
|
||||
.supported_shader_formats = PULSE_SHADER_FORMAT_SPIRV_BIT
|
||||
};
|
||||
|
||||
@@ -19,11 +19,11 @@ typedef struct VulkanGlobal
|
||||
#undef PULSE_VULKAN_GLOBAL_FUNCTION
|
||||
} VulkanGlobal;
|
||||
|
||||
typedef struct VulkanContext
|
||||
typedef struct VulkanPulseDevice
|
||||
{
|
||||
VulkanInstance instance;
|
||||
VulkanDevice device;
|
||||
} VulkanContext;
|
||||
} VulkanPulseDevice;
|
||||
|
||||
VulkanGlobal* VulkanGetGlobal();
|
||||
|
||||
|
||||
7
Sources/Backends/Vulkan/VulkanDevice.c
git.filemode.normal_file
7
Sources/Backends/Vulkan/VulkanDevice.c
git.filemode.normal_file
@@ -0,0 +1,7 @@
|
||||
// Copyright (C) 2024 kanel
|
||||
// This file is part of "Pulse"
|
||||
// For conditions of distribution and use, see copyright notice in LICENSE
|
||||
|
||||
#include "VulkanDevice.h"
|
||||
|
||||
|
||||
@@ -14,6 +14,8 @@
|
||||
#define VMA_VULKAN_VERSION 1000000
|
||||
#include <vk_mem_alloc.h>
|
||||
|
||||
#include <Pulse.h>
|
||||
|
||||
typedef struct VulkanDevice
|
||||
{
|
||||
VkPhysicalDeviceFeatures features;
|
||||
@@ -30,6 +32,9 @@ typedef struct VulkanDevice
|
||||
#undef PULSE_VULKAN_DEVICE_FUNCTION
|
||||
} VulkanDevice;
|
||||
|
||||
VulkanDevice* VulkanCreateDevice(PulseDebugLevel debug_level);
|
||||
void VulkanDestroyDevice(VulkanDevice* device);
|
||||
|
||||
#endif // PULSE_VULKAN_DEVICE_H_
|
||||
|
||||
#endif // PULSE_ENABLE_VULKAN_BACKEND
|
||||
|
||||
55
Sources/Backends/Vulkan/VulkanInstance.c
git.filemode.normal_file
55
Sources/Backends/Vulkan/VulkanInstance.c
git.filemode.normal_file
@@ -0,0 +1,55 @@
|
||||
// Copyright (C) 2024 kanel
|
||||
// This file is part of "Pulse"
|
||||
// For conditions of distribution and use, see copyright notice in LICENSE
|
||||
|
||||
#include "../../PulseInternal.h"
|
||||
#include "VulkanInstance.h"
|
||||
#include "VulkanLoader.h"
|
||||
#include "Vulkan.h"
|
||||
|
||||
static VkInstance VulkanCreateInstance(const char** extensions_enabled, uint32_t extensions_count, PulseDebugLevel debug_level)
|
||||
{
|
||||
static const char* layer_names[] = { "VK_LAYER_KHRONOS_validation" };
|
||||
|
||||
VkInstance instance = VK_NULL_HANDLE;
|
||||
|
||||
VkApplicationInfo app_info = {};
|
||||
app_info.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
|
||||
app_info.pEngineName = "PulseGPU";
|
||||
app_info.engineVersion = PULSE_VERSION;
|
||||
app_info.apiVersion = VK_API_VERSION_1_0;
|
||||
|
||||
VkInstanceCreateInfo create_info = {};
|
||||
create_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
|
||||
create_info.pApplicationInfo = &app_info;
|
||||
create_info.enabledExtensionCount = extensions_count;
|
||||
create_info.ppEnabledExtensionNames = extensions_enabled;
|
||||
create_info.enabledLayerCount = sizeof(layer_names) / sizeof(layer_names[0]);
|
||||
create_info.ppEnabledLayerNames = layer_names;
|
||||
create_info.pNext = PULSE_NULLPTR;
|
||||
#ifdef PULSE_PLAT_MACOS
|
||||
create_info.flags = VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR;
|
||||
#else
|
||||
create_info.flags = 0;
|
||||
#endif
|
||||
|
||||
VulkanGetGlobal()->vkCreateInstance(&create_info, PULSE_NULLPTR, &instance);
|
||||
return instance;
|
||||
}
|
||||
|
||||
bool VulkanInitInstance(VulkanInstance* instance, PulseDebugLevel debug_level)
|
||||
{
|
||||
instance->instance = VulkanCreateInstance(NULL, 0, debug_level);
|
||||
if(instance->instance == VK_NULL_HANDLE)
|
||||
{
|
||||
PulseSetInternalError(PULSE_ERROR_INITIALIZATION_FAILED);
|
||||
return false;
|
||||
}
|
||||
if(VulkanLoadInstance(instance))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void VulkanDestroyInstance(VulkanInstance* instance)
|
||||
{
|
||||
}
|
||||
@@ -9,6 +9,8 @@
|
||||
|
||||
#include <vulkan/vulkan_core.h>
|
||||
|
||||
#include <Pulse.h>
|
||||
|
||||
typedef struct VulkanInstance
|
||||
{
|
||||
VkInstance instance;
|
||||
@@ -18,6 +20,9 @@ typedef struct VulkanInstance
|
||||
#undef PULSE_VULKAN_INSTANCE_FUNCTION
|
||||
} VulkanInstance;
|
||||
|
||||
bool VulkanInitInstance(VulkanInstance* instance, PulseDebugLevel debug_level);
|
||||
void VulkanDestroyInstance(VulkanInstance* instance);
|
||||
|
||||
#endif // PULSE_VULKAN_INSTANCE_H_
|
||||
|
||||
#endif // PULSE_ENABLE_VULKAN_BACKEND
|
||||
|
||||
@@ -40,9 +40,9 @@
|
||||
|
||||
static LibModule vulkan_lib_module = PULSE_NULLPTR;
|
||||
|
||||
static void VulkanLoadGlobalFunctions(void* context, PFN_vkVoidFunction (*load)(void*, const char*));
|
||||
static void VulkanLoadInstanceFunctions(VulkanInstance* instance, PFN_vkVoidFunction (*load)(void*, const char*));
|
||||
static void VulkanLoadDeviceFunctions(VulkanInstance* instance, VulkanDevice* device, PFN_vkVoidFunction (*load)(VulkanInstance*, void*, const char*));
|
||||
static bool VulkanLoadGlobalFunctions(void* context, PFN_vkVoidFunction (*load)(void*, const char*));
|
||||
static bool VulkanLoadInstanceFunctions(VulkanInstance* instance, PFN_vkVoidFunction (*load)(void*, const char*));
|
||||
static bool VulkanLoadDeviceFunctions(VulkanInstance* instance, VulkanDevice* device, PFN_vkVoidFunction (*load)(VulkanInstance*, void*, const char*));
|
||||
|
||||
static inline PFN_vkVoidFunction vkGetInstanceProcAddrStub(void* context, const char* name)
|
||||
{
|
||||
@@ -127,18 +127,17 @@ bool VulkanInitLoader()
|
||||
PulseSetInternalError(PULSE_ERROR_INITIALIZATION_FAILED);
|
||||
return false;
|
||||
}
|
||||
VulkanLoadGlobalFunctions(PULSE_NULLPTR, vkGetInstanceProcAddrStub);
|
||||
return true;
|
||||
return VulkanLoadGlobalFunctions(PULSE_NULLPTR, vkGetInstanceProcAddrStub);
|
||||
}
|
||||
|
||||
void VulkanLoadInstance(VulkanInstance* instance)
|
||||
bool VulkanLoadInstance(VulkanInstance* instance)
|
||||
{
|
||||
VulkanLoadInstanceFunctions(instance, vkGetInstanceProcAddrStub);
|
||||
return VulkanLoadInstanceFunctions(instance, vkGetInstanceProcAddrStub);
|
||||
}
|
||||
|
||||
void VulkanLoadDevice(VulkanInstance* instance, VulkanDevice* device)
|
||||
bool VulkanLoadDevice(VulkanInstance* instance, VulkanDevice* device)
|
||||
{
|
||||
VulkanLoadDeviceFunctions(instance, device, vkGetDeviceProcAddrStub);
|
||||
return VulkanLoadDeviceFunctions(instance, device, vkGetDeviceProcAddrStub);
|
||||
}
|
||||
|
||||
void VulkanLoaderShutdown()
|
||||
@@ -147,23 +146,35 @@ void VulkanLoaderShutdown()
|
||||
vulkan_lib_module = PULSE_NULLPTR;
|
||||
}
|
||||
|
||||
static void VulkanLoadGlobalFunctions(void* context, PFN_vkVoidFunction (*load)(void*, const char*))
|
||||
static bool VulkanLoadGlobalFunctions(void* context, PFN_vkVoidFunction (*load)(void*, const char*))
|
||||
{
|
||||
#define PULSE_VULKAN_GLOBAL_FUNCTION(func) VulkanGetGlobal()->func = (PFN_##func)load(context, #func);
|
||||
#define PULSE_VULKAN_GLOBAL_FUNCTION(func) \
|
||||
VulkanGetGlobal()->func = (PFN_##func)load(context, #func); \
|
||||
if(!VulkanGetGlobal()->func) \
|
||||
return false;
|
||||
#include "VulkanGlobalPrototypes.h"
|
||||
#undef PULSE_VULKAN_GLOBAL_FUNCTION
|
||||
return true;
|
||||
}
|
||||
|
||||
static void VulkanLoadInstanceFunctions(VulkanInstance* instance, PFN_vkVoidFunction (*load)(void*, const char*))
|
||||
static bool VulkanLoadInstanceFunctions(VulkanInstance* instance, PFN_vkVoidFunction (*load)(void*, const char*))
|
||||
{
|
||||
#define PULSE_VULKAN_INSTANCE_FUNCTION(func) instance->func = (PFN_##func)load(instance->instance, #func);
|
||||
#define PULSE_VULKAN_INSTANCE_FUNCTION(func) \
|
||||
instance->func = (PFN_##func)load(instance->instance, #func); \
|
||||
if(!instance->func) \
|
||||
return false;
|
||||
#include "VulkanInstancePrototypes.h"
|
||||
#undef PULSE_VULKAN_INSTANCE_FUNCTION
|
||||
return true;
|
||||
}
|
||||
|
||||
static void VulkanLoadDeviceFunctions(VulkanInstance* instance, VulkanDevice* device, PFN_vkVoidFunction (*load)(VulkanInstance*, void*, const char*))
|
||||
static bool VulkanLoadDeviceFunctions(VulkanInstance* instance, VulkanDevice* device, PFN_vkVoidFunction (*load)(VulkanInstance*, void*, const char*))
|
||||
{
|
||||
#define PULSE_VULKAN_DEVICE_FUNCTION(func) device->func = (PFN_##func)load(instance, device->device, #func);
|
||||
#define PULSE_VULKAN_DEVICE_FUNCTION(func) \
|
||||
device->func = (PFN_##func)load(instance, device->device, #func); \
|
||||
if(!device->func) \
|
||||
return false;
|
||||
#include "VulkanDevicePrototypes.h"
|
||||
#undef PULSE_VULKAN_DEVICE_FUNCTION
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -9,8 +9,8 @@
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
typedef struct VulkanInstance VulkanInstance;
|
||||
typedef struct VulkanDevice VulkanDevice;
|
||||
#include "VulkanDevice.h"
|
||||
#include "VulkanInstance.h"
|
||||
|
||||
bool VulkanInitLoader();
|
||||
bool VulkanLoadInstance(VulkanInstance* instance);
|
||||
|
||||
@@ -66,19 +66,20 @@ PULSE_API PulseDevice PulseCreateDevice(PulseBackendFlags backend_candidates, Pu
|
||||
PulseDevice device = backend->PFN_CreateDevice(debug_level);
|
||||
if(device == PULSE_NULL_HANDLE)
|
||||
PulseSetInternalError(PULSE_ERROR_INITIALIZATION_FAILED);
|
||||
device->backend = backend;
|
||||
return device;
|
||||
}
|
||||
|
||||
PULSE_API void PulseDestroyDevice(PulseDevice device)
|
||||
{
|
||||
PULSE_CHECK_HANDLE(device);
|
||||
device->PFN_DestroyDevice(device);
|
||||
device->backend->PFN_DestroyDevice(device);
|
||||
}
|
||||
|
||||
PULSE_API PulseBackendBits PulseGetBackendInUseByDevice(PulseDevice device)
|
||||
{
|
||||
PULSE_CHECK_HANDLE_RETVAL(device, PULSE_BACKEND_INVALID);
|
||||
return device->backend;
|
||||
return device->backend->backend;
|
||||
}
|
||||
|
||||
PULSE_API bool PulseSupportsBackend(PulseBackendFlags backend_candidates, PulseShaderFormatsFlags shader_formats_used)
|
||||
@@ -100,7 +101,7 @@ PULSE_API bool PulseSupportsBackend(PulseBackendFlags backend_candidates, PulseS
|
||||
PULSE_API bool PulseDeviceSupportsSahderFormats(PulseDevice device, PulseShaderFormatsFlags shader_formats_used)
|
||||
{
|
||||
PULSE_CHECK_HANDLE_RETVAL(device, false);
|
||||
return (device->supported_shader_formats & shader_formats_used) != 0;
|
||||
return (device->backend->supported_shader_formats & shader_formats_used) != 0;
|
||||
}
|
||||
|
||||
PULSE_API PulseErrorType PulseGetLastErrorType()
|
||||
@@ -117,6 +118,7 @@ PULSE_API const char* PulseVerbaliseErrorType(PulseErrorType error)
|
||||
case PULSE_ERROR_NONE: return "no error";
|
||||
case PULSE_ERROR_BACKENDS_CANDIDATES_SHADER_FORMAT_MISMATCH: return "no backend candidates support the required shader formats";
|
||||
case PULSE_ERROR_INITIALIZATION_FAILED: return "initialization of an object could not be completed for implementation-specific reasons";
|
||||
case PULSE_ERROR_ALLOCATION_FAILED: return "an internal allocation failed";
|
||||
|
||||
default: return "invalid error type";
|
||||
};
|
||||
|
||||
@@ -11,33 +11,43 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define PULSE_CHECK_ALLOCATION_RETVAL(ptr, retval) \
|
||||
do { \
|
||||
if(ptr == PULSE_NULLPTR) \
|
||||
{ \
|
||||
PulseSetInternalError(PULSE_ERROR_ALLOCATION_FAILED); \
|
||||
return retval; \
|
||||
} \
|
||||
} while(0); \
|
||||
|
||||
#define PULSE_CHECK_ALLOCATION(ptr) PULSE_CHECK_ALLOCATION_RETVAL(ptr, )
|
||||
|
||||
typedef bool (*PulseLoadBackendPFN)(void);
|
||||
typedef PulseDevice (*PulseCreateDevicePFN)(PulseDebugLevel);
|
||||
|
||||
typedef void (*PulseDestroyDevicePFN)(PulseDevice);
|
||||
|
||||
typedef struct PulseDeviceHandler
|
||||
{
|
||||
// PFNs
|
||||
PulseDestroyDevicePFN PFN_DestroyDevice;
|
||||
|
||||
// Attributes
|
||||
PulseBackendFlags backend;
|
||||
PulseShaderFormatsFlags supported_shader_formats;
|
||||
PulseDebugLevel debug_level;
|
||||
} PulseDeviceHandler;
|
||||
|
||||
typedef struct PulseBackendLoader
|
||||
{
|
||||
// PFNs
|
||||
PulseLoadBackendPFN PFN_LoadBackend;
|
||||
PulseCreateDevicePFN PFN_CreateDevice;
|
||||
PulseDestroyDevicePFN PFN_DestroyDevice;
|
||||
|
||||
// Attributes
|
||||
PulseBackendFlags backend;
|
||||
PulseShaderFormatsFlags supported_shader_formats;
|
||||
} PulseBackendLoader;
|
||||
|
||||
typedef struct PulseDeviceHandler
|
||||
{
|
||||
// PFNs
|
||||
|
||||
// Attributes
|
||||
void* driver_data;
|
||||
const PulseBackendLoader* backend;
|
||||
PulseDebugLevel debug_level;
|
||||
} PulseDeviceHandler;
|
||||
|
||||
void PulseSetInternalError(PulseErrorType error);
|
||||
|
||||
#define PULSE_LOAD_DRIVER_DEVICE_FUNCTION(fn, _namespace) device->PFN_##fn = _namespace##fn;
|
||||
|
||||
@@ -4,5 +4,4 @@ target("LoadingPulse")
|
||||
set_extension(".x86_64")
|
||||
end
|
||||
add_files("main.c")
|
||||
set_targetdir("build/")
|
||||
target_end()
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
option("tests", { description = "Build tests", default = true })
|
||||
option("tests", { description = "Build tests", default = false })
|
||||
|
||||
if has_config("tests") then
|
||||
set_group("Tests")
|
||||
|
||||
41
xmake.lua
41
xmake.lua
@@ -63,36 +63,31 @@ end
|
||||
target("pulse_gpu")
|
||||
set_kind("$(kind)")
|
||||
add_defines("PULSE_BUILD")
|
||||
add_headerfiles("Includes/*.hpp)")
|
||||
add_headerfiles("Sources/*.h", { prefixdir = "private", install = false })
|
||||
add_headerfiles("Sources/*.inl", { prefixdir = "private", install = false })
|
||||
|
||||
add_files("Sources/*.c")
|
||||
|
||||
for name, module in pairs(backends) do
|
||||
if not has_config(module.option) then
|
||||
goto continue
|
||||
if has_config(module.option) then
|
||||
if module.packages then
|
||||
add_packages(table.unpack(module.packages))
|
||||
end
|
||||
|
||||
add_defines("PULSE_ENABLE_" .. name:upper() .. "_BACKEND")
|
||||
|
||||
add_headerfiles("Sources/Backends/" .. name .. "/**.h", { prefixdir = "private", install = false })
|
||||
add_headerfiles("Sources/Backends/" .. name .. "/**.inl", { prefixdir = "private", install = false })
|
||||
|
||||
add_files("Sources/Backends/" .. name .. "/**.c")
|
||||
if module.has_cpp_files then
|
||||
add_files("Sources/Backends/" .. name .. "/**.cpp")
|
||||
end
|
||||
|
||||
if module.custom then
|
||||
module.custom()
|
||||
end
|
||||
end
|
||||
|
||||
if module.packages then
|
||||
add_packages(table.unpack(module.packages))
|
||||
end
|
||||
|
||||
add_defines("PULSE_ENABLE_" .. name:upper() .. "_BACKEND")
|
||||
|
||||
add_headerfiles("Sources/Backends/" .. name .. "/**.h", { prefixdir = "private", install = false })
|
||||
add_headerfiles("Sources/Backends/" .. name .. "/*.inl", { prefixdir = "private", install = false })
|
||||
|
||||
add_files("Sources/Backends/" .. name .. "/**.c")
|
||||
if module.has_cpp_files then
|
||||
add_files("Sources/Backends/" .. name .. "/**.cpp")
|
||||
end
|
||||
|
||||
if module.custom then
|
||||
module.custom()
|
||||
end
|
||||
|
||||
::continue::
|
||||
end
|
||||
|
||||
on_load(function(target)
|
||||
|
||||
Reference in New Issue
Block a user