mirror of
https://github.com/Kbz-8/Pulse.git
synced 2026-01-11 15:33:34 +00:00
adding D3D11 base, working on Vulkan backend
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -6,6 +6,7 @@
|
|||||||
!xmake.lua
|
!xmake.lua
|
||||||
!/Includes/
|
!/Includes/
|
||||||
!/Sources/
|
!/Sources/
|
||||||
|
!/Tests/
|
||||||
!/.github/
|
!/.github/
|
||||||
*.o
|
*.o
|
||||||
*.swp
|
*.swp
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ extern "C" {
|
|||||||
|
|
||||||
#include "PulseProfile.h"
|
#include "PulseProfile.h"
|
||||||
|
|
||||||
#define PULSE_VERSION PULSE_MAKE_VERSION(1, 0, 0)
|
#define PULSE_VERSION PULSE_MAKE_VERSION(0, 0, 1)
|
||||||
|
|
||||||
// Types
|
// Types
|
||||||
typedef uint64_t PulseDeviceSize;
|
typedef uint64_t PulseDeviceSize;
|
||||||
@@ -35,7 +35,9 @@ PULSE_DEFINE_NULLABLE_HANDLE(PulseImage);
|
|||||||
typedef enum PulseBackendBits
|
typedef enum PulseBackendBits
|
||||||
{
|
{
|
||||||
PULSE_BACKEND_INVALID = PULSE_BIT(1),
|
PULSE_BACKEND_INVALID = PULSE_BIT(1),
|
||||||
PULSE_BACKEND_VULKAN = PULSE_BIT(2),
|
PULSE_BACKEND_ANY = PULSE_BIT(2),
|
||||||
|
PULSE_BACKEND_VULKAN = PULSE_BIT(3),
|
||||||
|
PULSE_BACKEND_D3D11 = PULSE_BIT(4),
|
||||||
// More to come
|
// More to come
|
||||||
} PulseBackendBits;
|
} PulseBackendBits;
|
||||||
typedef PulseFlags PulseBackendFlags;
|
typedef PulseFlags PulseBackendFlags;
|
||||||
@@ -65,13 +67,30 @@ typedef PulseFlags PulseImageUsageFlags;
|
|||||||
|
|
||||||
typedef enum PulseShaderFormatsBits
|
typedef enum PulseShaderFormatsBits
|
||||||
{
|
{
|
||||||
PULSE_SHADER_FORMAT_INVALID_BIT = PULSE_BIT(1),
|
PULSE_SHADER_FORMAT_SPIRV_BIT = PULSE_BIT(1), // Can be used by Vulkan | D3D11 backends
|
||||||
PULSE_SHADER_FORMAT_SPIRV_BIT = PULSE_BIT(2),
|
PULSE_SHADER_FORMAT_DXBC_BIT = PULSE_BIT(2), // Can be used by D3D11 backend only
|
||||||
// More to come
|
// More to come
|
||||||
} PulseShaderFormatsBits;
|
} PulseShaderFormatsBits;
|
||||||
typedef PulseFlags PulseShaderFormatsFlags;
|
typedef PulseFlags PulseShaderFormatsFlags;
|
||||||
|
|
||||||
// Enums
|
// Enums
|
||||||
|
typedef enum PulseDebugLevel
|
||||||
|
{
|
||||||
|
PULSE_NO_DEBUG,
|
||||||
|
PULSE_LOW_DEBUG,
|
||||||
|
PULSE_HIGH_DEBUG,
|
||||||
|
PULSE_PARANOID_DEBUG // Causes every warning to be treated as error
|
||||||
|
} PulseDebugLevel;
|
||||||
|
|
||||||
|
typedef enum PulseErrorType
|
||||||
|
{
|
||||||
|
PULSE_ERROR_NONE,
|
||||||
|
|
||||||
|
PULSE_ERROR_BACKENDS_CANDIDATES_SHADER_FORMAT_MISMATCH,
|
||||||
|
PULSE_ERROR_INITIALIZATION_FAILED,
|
||||||
|
PULSE_ERROR_INVALID_HANDLE,
|
||||||
|
} PulseErrorType;
|
||||||
|
|
||||||
typedef enum PulseImageType
|
typedef enum PulseImageType
|
||||||
{
|
{
|
||||||
PULSE_IMAGE_TYPE_2D,
|
PULSE_IMAGE_TYPE_2D,
|
||||||
@@ -180,7 +199,6 @@ typedef struct PulseComputePipelineCreateInfo
|
|||||||
const uint8_t* code;
|
const uint8_t* code;
|
||||||
const char* entrypoint;
|
const char* entrypoint;
|
||||||
PulseShaderFormatsFlags format;
|
PulseShaderFormatsFlags format;
|
||||||
uint32_t num_samplers;
|
|
||||||
uint32_t num_readonly_storage_images;
|
uint32_t num_readonly_storage_images;
|
||||||
uint32_t num_readonly_storage_buffers;
|
uint32_t num_readonly_storage_buffers;
|
||||||
uint32_t num_readwrite_storage_images;
|
uint32_t num_readwrite_storage_images;
|
||||||
@@ -230,10 +248,14 @@ typedef struct PulseImageRegion
|
|||||||
} PulseImageRegion;
|
} PulseImageRegion;
|
||||||
|
|
||||||
// Functions
|
// Functions
|
||||||
PULSE_API PulseDevice PulseCreateDevice(PulseBackendFlags backend_candidates, PulseShaderFormatsFlags shader_formats_used);
|
PULSE_API PulseDevice PulseCreateDevice(PulseBackendFlags backend_candidates, PulseShaderFormatsFlags shader_formats_used, PulseDebugLevel debug_level);
|
||||||
PULSE_API void PulseDestroyDevice(PulseDevice device);
|
PULSE_API void PulseDestroyDevice(PulseDevice device);
|
||||||
PULSE_API PulseBackendBits PulseGetBackendInUseByDevice(PulseDevice device);
|
PULSE_API PulseBackendBits PulseGetBackendInUseByDevice(PulseDevice device);
|
||||||
PULSE_API bool PulseSupportsBackend(PulseBackendFlags backend_candidates, PulseShaderFormatsFlags shader_formats_used);
|
PULSE_API bool PulseSupportsBackend(PulseBackendFlags backend_candidates, PulseShaderFormatsFlags shader_formats_used);
|
||||||
|
PULSE_API bool PulseDeviceSupportsSahderFormats(PulseDevice device, PulseShaderFormatsFlags shader_formats_used);
|
||||||
|
|
||||||
|
PULSE_API PulseErrorType PulseGetLastErrorType(); // /!\ Warning /!\ Call to this function resets the internal last error variable
|
||||||
|
PULSE_API const char* PulseVerbaliseErrorType(PulseErrorType error);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,8 @@
|
|||||||
#ifndef PULSE_PROFILE_H_
|
#ifndef PULSE_PROFILE_H_
|
||||||
#define PULSE_PROFILE_H_
|
#define PULSE_PROFILE_H_
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
@@ -76,6 +78,42 @@ extern "C" {
|
|||||||
#define PULSE_API
|
#define PULSE_API
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef __cplusplus // if we compile in C
|
||||||
|
#ifdef __STDC__
|
||||||
|
#ifdef __STDC_VERSION__
|
||||||
|
#if __STDC_VERSION__ == 199409L
|
||||||
|
#define PULSE_C_VERSION 1994
|
||||||
|
#elif __STDC_VERSION__ == 199901L
|
||||||
|
#define PULSE_C_VERSION 1999
|
||||||
|
#elif __STDC_VERSION__ == 201112L
|
||||||
|
#define PULSE_C_VERSION 2011
|
||||||
|
#elif __STDC_VERSION__ == 201710L
|
||||||
|
#define PULSE_C_VERSION 2017
|
||||||
|
#elif __STDC_VERSION__ == 202311L
|
||||||
|
#define PULSE_C_VERSION 2023
|
||||||
|
#else
|
||||||
|
#define PULSE_C_VERSION 0
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#define PULSE_C_VERSION 0
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#define PULSE_C_VERSION 0
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#define PULSE_C_VERSION 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if PULSE_C_VERSION >= 2023
|
||||||
|
#if defined(PULSE_COMPILER_GCC) || defined(PULSE_COMPILER_CLANG) // for now only GCC and Clang supports nullptr
|
||||||
|
#define PULSE_NULLPTR nullptr
|
||||||
|
#else
|
||||||
|
#define PULSE_NULLPTR NULL
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#define PULSE_NULLPTR NULL
|
||||||
|
#endif
|
||||||
|
|
||||||
#define PULSE_DEFINE_NULLABLE_HANDLE(object) typedef struct object##Handler* object
|
#define PULSE_DEFINE_NULLABLE_HANDLE(object) typedef struct object##Handler* object
|
||||||
|
|
||||||
#if (defined(__cplusplus) && (__cplusplus >= 201103L)) || (defined(_MSVC_LANG) && (_MSVC_LANG >= 201103L))
|
#if (defined(__cplusplus) && (__cplusplus >= 201103L)) || (defined(_MSVC_LANG) && (_MSVC_LANG >= 201103L))
|
||||||
|
|||||||
@@ -4,7 +4,8 @@
|
|||||||
|
|
||||||
#include <Pulse.h>
|
#include <Pulse.h>
|
||||||
|
|
||||||
typedef struct PulseDeviceHandler
|
#ifdef PULSE_ENABLE_D3D11_BACKEND
|
||||||
{
|
|
||||||
|
|
||||||
} PulseDeviceHandler;
|
|
||||||
|
|
||||||
|
#endif // PULSE_ENABLE_D3D11_BACKEND
|
||||||
30
Sources/Backends/Vulkan/Vulkan.c
git.filemode.normal_file
30
Sources/Backends/Vulkan/Vulkan.c
git.filemode.normal_file
@@ -0,0 +1,30 @@
|
|||||||
|
// Copyright (C) 2024 kanel
|
||||||
|
// This file is part of "Pulse"
|
||||||
|
// For conditions of distribution and use, see copyright notice in LICENSE
|
||||||
|
|
||||||
|
#include <Pulse.h>
|
||||||
|
#include "../../PulseInternal.h"
|
||||||
|
|
||||||
|
#include "Vulkan.h"
|
||||||
|
#include "VulkanLoader.h"
|
||||||
|
|
||||||
|
VulkanGlobal* VulkanGetGlobal()
|
||||||
|
{
|
||||||
|
static VulkanGlobal vulkan = { 0 };
|
||||||
|
return &vulkan;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool VulkanLoadBackend()
|
||||||
|
{
|
||||||
|
if(!VulkanInitLoader())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
PulseBackendLoader VulkanDriver = {
|
||||||
|
.PFN_LoadBackend = VulkanLoadBackend,
|
||||||
|
.PFN_CreateDevice = PULSE_NULLPTR,
|
||||||
|
.backend = PULSE_BACKEND_VULKAN,
|
||||||
|
.supported_shader_formats = PULSE_SHADER_FORMAT_SPIRV_BIT
|
||||||
|
};
|
||||||
32
Sources/Backends/Vulkan/Vulkan.h
git.filemode.normal_file
32
Sources/Backends/Vulkan/Vulkan.h
git.filemode.normal_file
@@ -0,0 +1,32 @@
|
|||||||
|
// Copyright (C) 2024 kanel
|
||||||
|
// This file is part of "Pulse"
|
||||||
|
// For conditions of distribution and use, see copyright notice in LICENSE
|
||||||
|
|
||||||
|
#ifdef PULSE_ENABLE_VULKAN_BACKEND
|
||||||
|
|
||||||
|
#ifndef PULSE_VULKAN_H_
|
||||||
|
#define PULSE_VULKAN_H_
|
||||||
|
|
||||||
|
#include <vulkan/vulkan_core.h>
|
||||||
|
|
||||||
|
#include "VulkanDevice.h"
|
||||||
|
#include "VulkanInstance.h"
|
||||||
|
|
||||||
|
typedef struct VulkanGlobal
|
||||||
|
{
|
||||||
|
#define PULSE_VULKAN_GLOBAL_FUNCTION(fn) PFN_##fn fn;
|
||||||
|
#include "VulkanGlobalPrototypes.h"
|
||||||
|
#undef PULSE_VULKAN_GLOBAL_FUNCTION
|
||||||
|
} VulkanGlobal;
|
||||||
|
|
||||||
|
typedef struct VulkanContext
|
||||||
|
{
|
||||||
|
VulkanInstance instance;
|
||||||
|
VulkanDevice device;
|
||||||
|
} VulkanContext;
|
||||||
|
|
||||||
|
VulkanGlobal* VulkanGetGlobal();
|
||||||
|
|
||||||
|
#endif // PULSE_VULKAN_H_
|
||||||
|
|
||||||
|
#endif // PULSE_ENABLE_VULKAN_BACKEND
|
||||||
35
Sources/Backends/Vulkan/VulkanDevice.h
git.filemode.normal_file
35
Sources/Backends/Vulkan/VulkanDevice.h
git.filemode.normal_file
@@ -0,0 +1,35 @@
|
|||||||
|
// Copyright (C) 2024 kanel
|
||||||
|
// This file is part of "Pulse"
|
||||||
|
// For conditions of distribution and use, see copyright notice in LICENSE
|
||||||
|
|
||||||
|
#ifdef PULSE_ENABLE_VULKAN_BACKEND
|
||||||
|
|
||||||
|
#ifndef PULSE_VULKAN_DEVICE_H_
|
||||||
|
#define PULSE_VULKAN_DEVICE_H_
|
||||||
|
|
||||||
|
#include <vulkan/vulkan_core.h>
|
||||||
|
|
||||||
|
#define VMA_STATIC_VULKAN_FUNCTIONS 0
|
||||||
|
#define VMA_DYNAMIC_VULKAN_FUNCTIONS 0
|
||||||
|
#define VMA_VULKAN_VERSION 1000000
|
||||||
|
#include <vk_mem_alloc.h>
|
||||||
|
|
||||||
|
typedef struct VulkanDevice
|
||||||
|
{
|
||||||
|
VkPhysicalDeviceFeatures features;
|
||||||
|
VkPhysicalDeviceMemoryProperties memory_properties;
|
||||||
|
VkPhysicalDeviceProperties properties;
|
||||||
|
VkPhysicalDevice physical;
|
||||||
|
|
||||||
|
VkDevice device;
|
||||||
|
|
||||||
|
VmaAllocator allocator;
|
||||||
|
|
||||||
|
#define PULSE_VULKAN_DEVICE_FUNCTION(fn) PFN_##fn fn;
|
||||||
|
#include "VulkanDevicePrototypes.h"
|
||||||
|
#undef PULSE_VULKAN_DEVICE_FUNCTION
|
||||||
|
} VulkanDevice;
|
||||||
|
|
||||||
|
#endif // PULSE_VULKAN_DEVICE_H_
|
||||||
|
|
||||||
|
#endif // PULSE_ENABLE_VULKAN_BACKEND
|
||||||
75
Sources/Backends/Vulkan/VulkanDevicePrototypes.h
git.filemode.normal_file
75
Sources/Backends/Vulkan/VulkanDevicePrototypes.h
git.filemode.normal_file
@@ -0,0 +1,75 @@
|
|||||||
|
// Copyright (C) 2024 kanel
|
||||||
|
// This file is part of "Pulse"
|
||||||
|
// For conditions of distribution and use, see copyright notice in LICENSE
|
||||||
|
|
||||||
|
// No header guard
|
||||||
|
|
||||||
|
#ifndef PULSE_VULKAN_DEVICE_FUNCTION
|
||||||
|
#error "You must define PULSE_VULKAN_DEVICE_FUNCTION before including this file"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef VK_VERSION_1_0
|
||||||
|
PULSE_VULKAN_DEVICE_FUNCTION(vkAllocateCommandBuffers)
|
||||||
|
PULSE_VULKAN_DEVICE_FUNCTION(vkAllocateDescriptorSets)
|
||||||
|
PULSE_VULKAN_DEVICE_FUNCTION(vkAllocateMemory)
|
||||||
|
PULSE_VULKAN_DEVICE_FUNCTION(vkBeginCommandBuffer)
|
||||||
|
PULSE_VULKAN_DEVICE_FUNCTION(vkBindBufferMemory)
|
||||||
|
PULSE_VULKAN_DEVICE_FUNCTION(vkBindImageMemory)
|
||||||
|
PULSE_VULKAN_DEVICE_FUNCTION(vkCmdBindDescriptorSets)
|
||||||
|
PULSE_VULKAN_DEVICE_FUNCTION(vkCmdBindPipeline)
|
||||||
|
PULSE_VULKAN_DEVICE_FUNCTION(vkCmdCopyBuffer)
|
||||||
|
PULSE_VULKAN_DEVICE_FUNCTION(vkCmdDispatch)
|
||||||
|
PULSE_VULKAN_DEVICE_FUNCTION(vkCmdDispatchIndirect)
|
||||||
|
PULSE_VULKAN_DEVICE_FUNCTION(vkCmdExecuteCommands)
|
||||||
|
PULSE_VULKAN_DEVICE_FUNCTION(vkCmdFillBuffer)
|
||||||
|
PULSE_VULKAN_DEVICE_FUNCTION(vkCmdPipelineBarrier)
|
||||||
|
PULSE_VULKAN_DEVICE_FUNCTION(vkCmdPushConstants)
|
||||||
|
PULSE_VULKAN_DEVICE_FUNCTION(vkCmdUpdateBuffer)
|
||||||
|
PULSE_VULKAN_DEVICE_FUNCTION(vkCreateBuffer)
|
||||||
|
PULSE_VULKAN_DEVICE_FUNCTION(vkCreateBufferView)
|
||||||
|
PULSE_VULKAN_DEVICE_FUNCTION(vkCreateCommandPool)
|
||||||
|
PULSE_VULKAN_DEVICE_FUNCTION(vkCreateComputePipelines)
|
||||||
|
PULSE_VULKAN_DEVICE_FUNCTION(vkCreateDescriptorPool)
|
||||||
|
PULSE_VULKAN_DEVICE_FUNCTION(vkCreateDescriptorSetLayout)
|
||||||
|
PULSE_VULKAN_DEVICE_FUNCTION(vkCreateFence)
|
||||||
|
PULSE_VULKAN_DEVICE_FUNCTION(vkCreateImage)
|
||||||
|
PULSE_VULKAN_DEVICE_FUNCTION(vkCreatePipelineCache)
|
||||||
|
PULSE_VULKAN_DEVICE_FUNCTION(vkCreatePipelineLayout)
|
||||||
|
PULSE_VULKAN_DEVICE_FUNCTION(vkCreateSemaphore)
|
||||||
|
PULSE_VULKAN_DEVICE_FUNCTION(vkCreateShaderModule)
|
||||||
|
PULSE_VULKAN_DEVICE_FUNCTION(vkDestroyBuffer)
|
||||||
|
PULSE_VULKAN_DEVICE_FUNCTION(vkDestroyBufferView)
|
||||||
|
PULSE_VULKAN_DEVICE_FUNCTION(vkDestroyCommandPool)
|
||||||
|
PULSE_VULKAN_DEVICE_FUNCTION(vkDestroyDescriptorPool)
|
||||||
|
PULSE_VULKAN_DEVICE_FUNCTION(vkDestroyDescriptorSetLayout)
|
||||||
|
PULSE_VULKAN_DEVICE_FUNCTION(vkDestroyDevice)
|
||||||
|
PULSE_VULKAN_DEVICE_FUNCTION(vkDestroyFence)
|
||||||
|
PULSE_VULKAN_DEVICE_FUNCTION(vkDestroyImage)
|
||||||
|
PULSE_VULKAN_DEVICE_FUNCTION(vkDestroyPipeline)
|
||||||
|
PULSE_VULKAN_DEVICE_FUNCTION(vkDestroyPipelineCache)
|
||||||
|
PULSE_VULKAN_DEVICE_FUNCTION(vkDestroyPipelineLayout)
|
||||||
|
PULSE_VULKAN_DEVICE_FUNCTION(vkDestroySemaphore)
|
||||||
|
PULSE_VULKAN_DEVICE_FUNCTION(vkDestroyShaderModule)
|
||||||
|
PULSE_VULKAN_DEVICE_FUNCTION(vkDeviceWaitIdle)
|
||||||
|
PULSE_VULKAN_DEVICE_FUNCTION(vkEndCommandBuffer)
|
||||||
|
PULSE_VULKAN_DEVICE_FUNCTION(vkFlushMappedMemoryRanges)
|
||||||
|
PULSE_VULKAN_DEVICE_FUNCTION(vkFreeCommandBuffers)
|
||||||
|
PULSE_VULKAN_DEVICE_FUNCTION(vkFreeMemory)
|
||||||
|
PULSE_VULKAN_DEVICE_FUNCTION(vkGetBufferMemoryRequirements)
|
||||||
|
PULSE_VULKAN_DEVICE_FUNCTION(vkGetDeviceMemoryCommitment)
|
||||||
|
PULSE_VULKAN_DEVICE_FUNCTION(vkGetDeviceQueue)
|
||||||
|
PULSE_VULKAN_DEVICE_FUNCTION(vkGetFenceStatus)
|
||||||
|
PULSE_VULKAN_DEVICE_FUNCTION(vkGetImageMemoryRequirements)
|
||||||
|
PULSE_VULKAN_DEVICE_FUNCTION(vkInvalidateMappedMemoryRanges)
|
||||||
|
PULSE_VULKAN_DEVICE_FUNCTION(vkMapMemory)
|
||||||
|
PULSE_VULKAN_DEVICE_FUNCTION(vkMergePipelineCaches)
|
||||||
|
PULSE_VULKAN_DEVICE_FUNCTION(vkQueueSubmit)
|
||||||
|
PULSE_VULKAN_DEVICE_FUNCTION(vkQueueWaitIdle)
|
||||||
|
PULSE_VULKAN_DEVICE_FUNCTION(vkResetCommandBuffer)
|
||||||
|
PULSE_VULKAN_DEVICE_FUNCTION(vkResetCommandPool)
|
||||||
|
PULSE_VULKAN_DEVICE_FUNCTION(vkResetDescriptorPool)
|
||||||
|
PULSE_VULKAN_DEVICE_FUNCTION(vkResetFences)
|
||||||
|
PULSE_VULKAN_DEVICE_FUNCTION(vkUnmapMemory)
|
||||||
|
PULSE_VULKAN_DEVICE_FUNCTION(vkUpdateDescriptorSets)
|
||||||
|
PULSE_VULKAN_DEVICE_FUNCTION(vkWaitForFences)
|
||||||
|
#endif
|
||||||
16
Sources/Backends/Vulkan/VulkanGlobalPrototypes.h
git.filemode.normal_file
16
Sources/Backends/Vulkan/VulkanGlobalPrototypes.h
git.filemode.normal_file
@@ -0,0 +1,16 @@
|
|||||||
|
// Copyright (C) 2024 kanel
|
||||||
|
// This file is part of "Pulse"
|
||||||
|
// For conditions of distribution and use, see copyright notice in LICENSE
|
||||||
|
|
||||||
|
// No header guard
|
||||||
|
|
||||||
|
#ifndef PULSE_VULKAN_GLOBAL_FUNCTION
|
||||||
|
#error "You must define PULSE_VULKAN_GLOBAL_FUNCTION before including this file"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef VK_VERSION_1_0
|
||||||
|
PULSE_VULKAN_GLOBAL_FUNCTION(vkCreateInstance)
|
||||||
|
PULSE_VULKAN_GLOBAL_FUNCTION(vkEnumerateInstanceExtensionProperties)
|
||||||
|
PULSE_VULKAN_GLOBAL_FUNCTION(vkEnumerateInstanceLayerProperties)
|
||||||
|
PULSE_VULKAN_GLOBAL_FUNCTION(vkGetInstanceProcAddr)
|
||||||
|
#endif
|
||||||
23
Sources/Backends/Vulkan/VulkanInstance.h
git.filemode.normal_file
23
Sources/Backends/Vulkan/VulkanInstance.h
git.filemode.normal_file
@@ -0,0 +1,23 @@
|
|||||||
|
// Copyright (C) 2024 kanel
|
||||||
|
// This file is part of "Pulse"
|
||||||
|
// For conditions of distribution and use, see copyright notice in LICENSE
|
||||||
|
|
||||||
|
#ifdef PULSE_ENABLE_VULKAN_BACKEND
|
||||||
|
|
||||||
|
#ifndef PULSE_VULKAN_INSTANCE_H_
|
||||||
|
#define PULSE_VULKAN_INSTANCE_H_
|
||||||
|
|
||||||
|
#include <vulkan/vulkan_core.h>
|
||||||
|
|
||||||
|
typedef struct VulkanInstance
|
||||||
|
{
|
||||||
|
VkInstance instance;
|
||||||
|
|
||||||
|
#define PULSE_VULKAN_INSTANCE_FUNCTION(fn) PFN_##fn fn;
|
||||||
|
#include "VulkanInstancePrototypes.h"
|
||||||
|
#undef PULSE_VULKAN_INSTANCE_FUNCTION
|
||||||
|
} VulkanInstance;
|
||||||
|
|
||||||
|
#endif // PULSE_VULKAN_INSTANCE_H_
|
||||||
|
|
||||||
|
#endif // PULSE_ENABLE_VULKAN_BACKEND
|
||||||
23
Sources/Backends/Vulkan/VulkanInstancePrototypes.h
git.filemode.normal_file
23
Sources/Backends/Vulkan/VulkanInstancePrototypes.h
git.filemode.normal_file
@@ -0,0 +1,23 @@
|
|||||||
|
// Copyright (C) 2024 kanel
|
||||||
|
// This file is part of "Pulse"
|
||||||
|
// For conditions of distribution and use, see copyright notice in LICENSE
|
||||||
|
|
||||||
|
// No header guard
|
||||||
|
|
||||||
|
#ifndef PULSE_VULKAN_INSTANCE_FUNCTION
|
||||||
|
#error "You must define PULSE_VULKAN_INSTANCE_FUNCTION before including this file"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef VK_VERSION_1_0
|
||||||
|
PULSE_VULKAN_INSTANCE_FUNCTION(vkCreateDevice)
|
||||||
|
PULSE_VULKAN_INSTANCE_FUNCTION(vkDestroyInstance)
|
||||||
|
PULSE_VULKAN_INSTANCE_FUNCTION(vkEnumerateDeviceExtensionProperties)
|
||||||
|
PULSE_VULKAN_INSTANCE_FUNCTION(vkEnumeratePhysicalDevices)
|
||||||
|
PULSE_VULKAN_INSTANCE_FUNCTION(vkGetDeviceProcAddr)
|
||||||
|
PULSE_VULKAN_INSTANCE_FUNCTION(vkGetPhysicalDeviceFeatures)
|
||||||
|
PULSE_VULKAN_INSTANCE_FUNCTION(vkGetPhysicalDeviceFormatProperties)
|
||||||
|
PULSE_VULKAN_INSTANCE_FUNCTION(vkGetPhysicalDeviceImageFormatProperties)
|
||||||
|
PULSE_VULKAN_INSTANCE_FUNCTION(vkGetPhysicalDeviceMemoryProperties)
|
||||||
|
PULSE_VULKAN_INSTANCE_FUNCTION(vkGetPhysicalDeviceProperties)
|
||||||
|
PULSE_VULKAN_INSTANCE_FUNCTION(vkGetPhysicalDeviceQueueFamilyProperties)
|
||||||
|
#endif
|
||||||
169
Sources/Backends/Vulkan/VulkanLoader.c
git.filemode.normal_file
169
Sources/Backends/Vulkan/VulkanLoader.c
git.filemode.normal_file
@@ -0,0 +1,169 @@
|
|||||||
|
// Copyright (C) 2024 kanel
|
||||||
|
// This file is part of "Pulse"
|
||||||
|
// For conditions of distribution and use, see copyright notice in LICENSE
|
||||||
|
|
||||||
|
#include <vulkan/vulkan_core.h>
|
||||||
|
|
||||||
|
#include <Pulse.h>
|
||||||
|
#include "../../PulseInternal.h"
|
||||||
|
|
||||||
|
#include "Vulkan.h"
|
||||||
|
#include "VulkanDevice.h"
|
||||||
|
#include "VulkanInstance.h"
|
||||||
|
|
||||||
|
#ifdef PULSE_PLAT_MACOS
|
||||||
|
#include <stdlib.h> // getenv
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef PULSE_PLAT_WINDOWS
|
||||||
|
typedef const char* LPCSTR;
|
||||||
|
typedef struct HINSTANCE__* HINSTANCE;
|
||||||
|
typedef HINSTANCE HMODULE;
|
||||||
|
#if defined(_MINWINDEF_)
|
||||||
|
/* minwindef.h defines FARPROC, and attempting to redefine it may conflict with -Wstrict-prototypes */
|
||||||
|
#elif defined(_WIN64)
|
||||||
|
typedef __int64 (__stdcall* FARPROC)(void);
|
||||||
|
#else
|
||||||
|
typedef int (__stdcall* FARPROC)(void);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef PULSE_PLAT_WINDOWS
|
||||||
|
__declspec(dllimport) HMODULE __stdcall LoadLibraryA(LPCSTR);
|
||||||
|
__declspec(dllimport) FARPROC __stdcall GetProcAddress(HMODULE, LPCSTR);
|
||||||
|
__declspec(dllimport) int __stdcall FreeLibrary(HMODULE);
|
||||||
|
typedef HMODULE LibModule;
|
||||||
|
#else
|
||||||
|
#include <dlfcn.h>
|
||||||
|
typedef void* LibModule;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
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 inline PFN_vkVoidFunction vkGetInstanceProcAddrStub(void* context, const char* name)
|
||||||
|
{
|
||||||
|
PFN_vkVoidFunction fn = VulkanGetGlobal()->vkGetInstanceProcAddr((VkInstance)context, name);
|
||||||
|
if(!fn)
|
||||||
|
PulseSetInternalError(PULSE_ERROR_INITIALIZATION_FAILED);
|
||||||
|
return fn;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline PFN_vkVoidFunction vkGetDeviceProcAddrStub(VulkanInstance* instance, void* context, const char* name)
|
||||||
|
{
|
||||||
|
PFN_vkVoidFunction fn = instance->vkGetDeviceProcAddr((VkDevice)context, name);
|
||||||
|
if(!fn)
|
||||||
|
PulseSetInternalError(PULSE_ERROR_INITIALIZATION_FAILED);
|
||||||
|
return fn;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline LibModule LoadLibrary(const char* libname)
|
||||||
|
{
|
||||||
|
#ifdef PULSE_PLAT_WINDOWS
|
||||||
|
return LoadLibraryA(libname);
|
||||||
|
#else
|
||||||
|
return dlopen(libname, RTLD_NOW | RTLD_LOCAL);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void* GetSymbol(LibModule module, const char* name)
|
||||||
|
{
|
||||||
|
#ifdef PULSE_PLAT_WINDOWS
|
||||||
|
return (void*)(void(*)(void))GetProcAddress(module, name);
|
||||||
|
#else
|
||||||
|
return dlsym(module, name);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void UnloadLibrary(LibModule lib)
|
||||||
|
{
|
||||||
|
#ifdef PULSE_PLAT_WINDOWS
|
||||||
|
FreeLibrary(lib);
|
||||||
|
#else
|
||||||
|
dlclose(lib);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
bool VulkanInitLoader()
|
||||||
|
{
|
||||||
|
#if defined(PULSE_PLAT_WINDOWS)
|
||||||
|
const char* libnames[] = {
|
||||||
|
"vulkan-1.dll"
|
||||||
|
};
|
||||||
|
#elif defined(PULSE_PLAT_MACOS)
|
||||||
|
const char* libnames[] = {
|
||||||
|
"libvulkan.dylib",
|
||||||
|
"libvulkan.1.dylib",
|
||||||
|
"libMoltenVK.dylib",
|
||||||
|
"vulkan.framework/vulkan",
|
||||||
|
"MoltenVK.framework/MoltenVK",
|
||||||
|
"/usr/local/lib/libvulkan.dylib",
|
||||||
|
};
|
||||||
|
#else
|
||||||
|
const char* libnames[] = {
|
||||||
|
"libvulkan.so.1",
|
||||||
|
"libvulkan.so"
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
for(size_t i = 0; i < sizeof(libnames) / sizeof(const char*); i++)
|
||||||
|
{
|
||||||
|
vulkan_lib_module = LoadLibrary(libnames[i]);
|
||||||
|
if(vulkan_lib_module)
|
||||||
|
{
|
||||||
|
VulkanGetGlobal()->vkGetInstanceProcAddr = (PFN_vkGetInstanceProcAddr)GetSymbol(vulkan_lib_module, "vkGetInstanceProcAddr");
|
||||||
|
if(VulkanGetGlobal()->vkGetInstanceProcAddr == PULSE_NULLPTR)
|
||||||
|
{
|
||||||
|
UnloadLibrary(vulkan_lib_module);
|
||||||
|
vulkan_lib_module = PULSE_NULLPTR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(!vulkan_lib_module)
|
||||||
|
{
|
||||||
|
PulseSetInternalError(PULSE_ERROR_INITIALIZATION_FAILED);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
VulkanLoadGlobalFunctions(PULSE_NULLPTR, vkGetInstanceProcAddrStub);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void VulkanLoadInstance(VulkanInstance* instance)
|
||||||
|
{
|
||||||
|
VulkanLoadInstanceFunctions(instance, vkGetInstanceProcAddrStub);
|
||||||
|
}
|
||||||
|
|
||||||
|
void VulkanLoadDevice(VulkanInstance* instance, VulkanDevice* device)
|
||||||
|
{
|
||||||
|
VulkanLoadDeviceFunctions(instance, device, vkGetDeviceProcAddrStub);
|
||||||
|
}
|
||||||
|
|
||||||
|
void VulkanLoaderShutdown()
|
||||||
|
{
|
||||||
|
UnloadLibrary(vulkan_lib_module);
|
||||||
|
vulkan_lib_module = PULSE_NULLPTR;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void VulkanLoadGlobalFunctions(void* context, PFN_vkVoidFunction (*load)(void*, const char*))
|
||||||
|
{
|
||||||
|
#define PULSE_VULKAN_GLOBAL_FUNCTION(func) VulkanGetGlobal()->func = (PFN_##func)load(context, #func);
|
||||||
|
#include "VulkanGlobalPrototypes.h"
|
||||||
|
#undef PULSE_VULKAN_GLOBAL_FUNCTION
|
||||||
|
}
|
||||||
|
|
||||||
|
static void VulkanLoadInstanceFunctions(VulkanInstance* instance, PFN_vkVoidFunction (*load)(void*, const char*))
|
||||||
|
{
|
||||||
|
#define PULSE_VULKAN_INSTANCE_FUNCTION(func) instance->func = (PFN_##func)load(instance->instance, #func);
|
||||||
|
#include "VulkanInstancePrototypes.h"
|
||||||
|
#undef PULSE_VULKAN_INSTANCE_FUNCTION
|
||||||
|
}
|
||||||
|
|
||||||
|
static void 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);
|
||||||
|
#include "VulkanDevicePrototypes.h"
|
||||||
|
#undef PULSE_VULKAN_DEVICE_FUNCTION
|
||||||
|
}
|
||||||
22
Sources/Backends/Vulkan/VulkanLoader.h
git.filemode.normal_file
22
Sources/Backends/Vulkan/VulkanLoader.h
git.filemode.normal_file
@@ -0,0 +1,22 @@
|
|||||||
|
// Copyright (C) 2024 kanel
|
||||||
|
// This file is part of "Pulse"
|
||||||
|
// For conditions of distribution and use, see copyright notice in LICENSE
|
||||||
|
|
||||||
|
#ifdef PULSE_ENABLE_VULKAN_BACKEND
|
||||||
|
|
||||||
|
#ifndef PULSE_VULKAN_LOADER_H_
|
||||||
|
#define PULSE_VULKAN_LOADER_H_
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
typedef struct VulkanInstance VulkanInstance;
|
||||||
|
typedef struct VulkanDevice VulkanDevice;
|
||||||
|
|
||||||
|
bool VulkanInitLoader();
|
||||||
|
bool VulkanLoadInstance(VulkanInstance* instance);
|
||||||
|
bool VulkanLoadDevice(VulkanInstance* instance, VulkanDevice* device);
|
||||||
|
void VulkanLoaderShutdown();
|
||||||
|
|
||||||
|
#endif // PULSE_VULKAN_LOADER_H_
|
||||||
|
|
||||||
|
#endif // PULSE_ENABLE_VULKAN_BACKEND
|
||||||
@@ -2,5 +2,5 @@
|
|||||||
// This file is part of "Pulse"
|
// This file is part of "Pulse"
|
||||||
// For conditions of distribution and use, see copyright notice in LICENSE
|
// For conditions of distribution and use, see copyright notice in LICENSE
|
||||||
|
|
||||||
#include <Pulse.h>
|
#define VMA_IMPLEMENTATION
|
||||||
|
#include <vk_mem_alloc.h>
|
||||||
@@ -3,19 +3,122 @@
|
|||||||
// For conditions of distribution and use, see copyright notice in LICENSE
|
// For conditions of distribution and use, see copyright notice in LICENSE
|
||||||
|
|
||||||
#include <Pulse.h>
|
#include <Pulse.h>
|
||||||
|
#include "PulseInternal.h"
|
||||||
|
|
||||||
PULSE_API PulseDevice PulseCreateDevice(PulseBackendFlags backend_candidates, PulseShaderFormatsFlags shader_formats_used)
|
#define PULSE_CHECK_HANDLE_RETVAL(handle, retval) \
|
||||||
|
do { \
|
||||||
|
if(handle == PULSE_NULL_HANDLE) \
|
||||||
|
{ \
|
||||||
|
PulseSetInternalError(PULSE_ERROR_INVALID_HANDLE); \
|
||||||
|
return retval; \
|
||||||
|
} \
|
||||||
|
} while(0); \
|
||||||
|
|
||||||
|
#define PULSE_CHECK_HANDLE(handle) PULSE_CHECK_HANDLE_RETVAL(handle, )
|
||||||
|
|
||||||
|
// Ordered by default preference
|
||||||
|
static const PulseBackendLoader* backends[] = {
|
||||||
|
#ifdef PULSE_ENABLE_VULKAN_BACKEND
|
||||||
|
&VulkanDriver,
|
||||||
|
#endif
|
||||||
|
#ifdef PULSE_ENABLE_D3D11_BACKEND
|
||||||
|
&D3D11Driver,
|
||||||
|
#endif
|
||||||
|
PULSE_NULLPTR
|
||||||
|
};
|
||||||
|
|
||||||
|
static PulseErrorType last_error = PULSE_ERROR_NONE;
|
||||||
|
|
||||||
|
void PulseSetInternalError(PulseErrorType error)
|
||||||
{
|
{
|
||||||
|
last_error = error;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const PulseBackendLoader* PulseSelectBackend(PulseBackendFlags backend_candidates, PulseShaderFormatsFlags shader_formats_used)
|
||||||
|
{
|
||||||
|
if((backend_candidates & PULSE_BACKEND_INVALID) != 0)
|
||||||
|
{
|
||||||
|
PulseSetInternalError(PULSE_ERROR_INITIALIZATION_FAILED);
|
||||||
|
return PULSE_NULLPTR;
|
||||||
|
}
|
||||||
|
for(int i = 0; backends[i] != PULSE_NULLPTR; i++)
|
||||||
|
{
|
||||||
|
if(backend_candidates != PULSE_BACKEND_ANY && (backend_candidates & backends[i]->backend) == 0)
|
||||||
|
continue;
|
||||||
|
if((shader_formats_used & backends[i]->supported_shader_formats) == 0)
|
||||||
|
{
|
||||||
|
PulseSetInternalError(PULSE_ERROR_BACKENDS_CANDIDATES_SHADER_FORMAT_MISMATCH);
|
||||||
|
return PULSE_NULLPTR;
|
||||||
|
}
|
||||||
|
if(backends[i]->PFN_LoadBackend())
|
||||||
|
return backends[i];
|
||||||
|
}
|
||||||
|
PulseSetInternalError(PULSE_ERROR_INITIALIZATION_FAILED);
|
||||||
|
return PULSE_NULLPTR;
|
||||||
|
}
|
||||||
|
|
||||||
|
PULSE_API PulseDevice PulseCreateDevice(PulseBackendFlags backend_candidates, PulseShaderFormatsFlags shader_formats_used, PulseDebugLevel debug_level)
|
||||||
|
{
|
||||||
|
const PulseBackendLoader* backend = PulseSelectBackend(backend_candidates, shader_formats_used);
|
||||||
|
if(backend == PULSE_NULLPTR) // Error code already set by PulseSelectBackend
|
||||||
|
return PULSE_NULL_HANDLE;
|
||||||
|
|
||||||
|
PulseDevice device = backend->PFN_CreateDevice(debug_level);
|
||||||
|
if(device == PULSE_NULL_HANDLE)
|
||||||
|
PulseSetInternalError(PULSE_ERROR_INITIALIZATION_FAILED);
|
||||||
|
return device;
|
||||||
}
|
}
|
||||||
|
|
||||||
PULSE_API void PulseDestroyDevice(PulseDevice device)
|
PULSE_API void PulseDestroyDevice(PulseDevice device)
|
||||||
{
|
{
|
||||||
|
PULSE_CHECK_HANDLE(device);
|
||||||
|
device->PFN_DestroyDevice(device);
|
||||||
}
|
}
|
||||||
|
|
||||||
PULSE_API PulseBackendBits PulseGetBackendInUseByDevice(PulseDevice device)
|
PULSE_API PulseBackendBits PulseGetBackendInUseByDevice(PulseDevice device)
|
||||||
{
|
{
|
||||||
|
PULSE_CHECK_HANDLE_RETVAL(device, PULSE_BACKEND_INVALID);
|
||||||
|
return device->backend;
|
||||||
}
|
}
|
||||||
|
|
||||||
PULSE_API bool PulseSupportsBackend(PulseBackendFlags backend_candidates, PulseShaderFormatsFlags shader_formats_used)
|
PULSE_API bool PulseSupportsBackend(PulseBackendFlags backend_candidates, PulseShaderFormatsFlags shader_formats_used)
|
||||||
{
|
{
|
||||||
|
if((backend_candidates & PULSE_BACKEND_INVALID) != 0)
|
||||||
|
return false;
|
||||||
|
if((backend_candidates & PULSE_BACKEND_ANY) != 0)
|
||||||
|
return true;
|
||||||
|
for(int i = 0; backends[i] != PULSE_NULLPTR; i++)
|
||||||
|
{
|
||||||
|
if((backend_candidates & backends[i]->backend) == 0)
|
||||||
|
continue;
|
||||||
|
if((shader_formats_used & backends[i]->supported_shader_formats) != 0)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
PULSE_API PulseErrorType PulseGetLastErrorType()
|
||||||
|
{
|
||||||
|
PulseErrorType error = last_error;
|
||||||
|
last_error = PULSE_ERROR_NONE;
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
PULSE_API const char* PulseVerbaliseErrorType(PulseErrorType error)
|
||||||
|
{
|
||||||
|
switch(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";
|
||||||
|
|
||||||
|
default: return "invalid error type";
|
||||||
|
};
|
||||||
|
return PULSE_NULLPTR; // To avoid warnings, should be unreachable
|
||||||
}
|
}
|
||||||
|
|||||||
58
Sources/PulseInternal.h
git.filemode.normal_file
58
Sources/PulseInternal.h
git.filemode.normal_file
@@ -0,0 +1,58 @@
|
|||||||
|
// Copyright (C) 2024 kanel
|
||||||
|
// This file is part of "Pulse"
|
||||||
|
// For conditions of distribution and use, see copyright notice in LICENSE
|
||||||
|
|
||||||
|
#ifndef PULSE_INTERNAL_H_
|
||||||
|
#define PULSE_INTERNAL_H_
|
||||||
|
|
||||||
|
#include <Pulse.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
// Attributes
|
||||||
|
PulseBackendFlags backend;
|
||||||
|
PulseShaderFormatsFlags supported_shader_formats;
|
||||||
|
} PulseBackendLoader;
|
||||||
|
|
||||||
|
void PulseSetInternalError(PulseErrorType error);
|
||||||
|
|
||||||
|
#define PULSE_LOAD_DRIVER_DEVICE_FUNCTION(fn, _namespace) device->PFN_##fn = _namespace##fn;
|
||||||
|
#define PULSE_LOAD_DRIVER_DEVICE(_namespace) \
|
||||||
|
PULSE_LOAD_DRIVER_DEVICE_FUNCTION(DestroyDevice, _namespace) \
|
||||||
|
|
||||||
|
#ifdef PULSE_ENABLE_VULKAN_BACKEND
|
||||||
|
extern PulseBackendLoader VulkanDriver;
|
||||||
|
#endif // PULSE_ENABLE_VULKAN_BACKEND
|
||||||
|
#ifdef PULSE_ENABLE_D3D11_BACKEND
|
||||||
|
extern PulseBackendLoader D3D11Driver;
|
||||||
|
#endif // PULSE_ENABLE_D3D11_BACKEND
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // PULSE_INTERNAL_H_
|
||||||
BIN
Tests/LoadingPulse/build/LoadingPulse.x86_64
git.filemode.executable_file
BIN
Tests/LoadingPulse/build/LoadingPulse.x86_64
git.filemode.executable_file
Binary file not shown.
15
Tests/LoadingPulse/main.c
git.filemode.normal_file
15
Tests/LoadingPulse/main.c
git.filemode.normal_file
@@ -0,0 +1,15 @@
|
|||||||
|
#include <Pulse.h>
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
PulseDevice device = PulseCreateDevice(PULSE_BACKEND_ANY, PULSE_SHADER_FORMAT_SPIRV_BIT, PULSE_NO_DEBUG);
|
||||||
|
if(device == PULSE_NULL_HANDLE)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Error while loading Pulse: %s", PulseVerbaliseErrorType(PulseGetLastErrorType()));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
PulseDestroyDevice(device);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
8
Tests/LoadingPulse/xmake.lua
git.filemode.normal_file
8
Tests/LoadingPulse/xmake.lua
git.filemode.normal_file
@@ -0,0 +1,8 @@
|
|||||||
|
target("LoadingPulse")
|
||||||
|
add_deps("pulse_gpu")
|
||||||
|
if is_plat("linux") then
|
||||||
|
set_extension(".x86_64")
|
||||||
|
end
|
||||||
|
add_files("main.c")
|
||||||
|
set_targetdir("build/")
|
||||||
|
target_end()
|
||||||
6
Tests/xmake.lua
git.filemode.normal_file
6
Tests/xmake.lua
git.filemode.normal_file
@@ -0,0 +1,6 @@
|
|||||||
|
option("tests", { description = "Build tests", default = true })
|
||||||
|
|
||||||
|
if has_config("tests") then
|
||||||
|
set_group("Tests")
|
||||||
|
includes("*/xmake.lua")
|
||||||
|
end
|
||||||
70
xmake.lua
70
xmake.lua
@@ -2,6 +2,23 @@
|
|||||||
-- This file is part of "Pulse"
|
-- This file is part of "Pulse"
|
||||||
-- For conditions of distribution and use, see copyright notice in LICENSE
|
-- For conditions of distribution and use, see copyright notice in LICENSE
|
||||||
|
|
||||||
|
local backends = {
|
||||||
|
Vulkan = {
|
||||||
|
option = "vulkan",
|
||||||
|
default = true,
|
||||||
|
has_cpp_files = true,
|
||||||
|
packages = { "vulkan-headers", "vulkan-memory-allocator" },
|
||||||
|
custom = function()
|
||||||
|
add_defines("VK_NO_PROTOTYPES")
|
||||||
|
end
|
||||||
|
},
|
||||||
|
D3D11 = {
|
||||||
|
option = "d3d11",
|
||||||
|
default = is_plat("windows", "mingw"),
|
||||||
|
has_cpp_files = false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
local sanitizers = {
|
local sanitizers = {
|
||||||
asan = "address",
|
asan = "address",
|
||||||
lsan = "leak",
|
lsan = "leak",
|
||||||
@@ -15,10 +32,18 @@ for opt, policy in table.orderpairs(sanitizers) do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
for name, module in table.orderpairs(backends) do
|
||||||
|
if module.option then
|
||||||
|
option(module.option, { description = "Enables the " .. name .. " backend", default = module.default })
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
add_rules("mode.debug", "mode.release")
|
add_rules("mode.debug", "mode.release")
|
||||||
|
|
||||||
add_includedirs("Includes")
|
add_includedirs("Includes")
|
||||||
set_languages("c99", "cxx20")
|
set_languages("c99", "cxx20")
|
||||||
|
set_encodings("utf-8")
|
||||||
|
set_warnings("allextra")
|
||||||
|
|
||||||
set_objectdir("build/Objs/$(os)_$(arch)")
|
set_objectdir("build/Objs/$(os)_$(arch)")
|
||||||
set_targetdir("build/Bin/$(os)_$(arch)")
|
set_targetdir("build/Bin/$(os)_$(arch)")
|
||||||
@@ -27,17 +52,54 @@ set_dependir("build/.deps")
|
|||||||
|
|
||||||
set_optimize("fastest")
|
set_optimize("fastest")
|
||||||
|
|
||||||
|
for name, module in pairs(backends) do
|
||||||
|
if has_config(module.option) then
|
||||||
|
if module.packages then
|
||||||
|
add_requires(table.unpack(module.packages))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
target("pulse_gpu")
|
target("pulse_gpu")
|
||||||
set_kind("$(kind)")
|
set_kind("$(kind)")
|
||||||
add_defines("PULSE_BUILD")
|
add_defines("PULSE_BUILD")
|
||||||
add_headerfiles("Includes/*.hpp)")
|
add_headerfiles("Includes/*.hpp)")
|
||||||
add_headerfiles("Sources/**.h", { prefixdir = "private", install = false })
|
add_headerfiles("Sources/*.h", { prefixdir = "private", install = false })
|
||||||
add_headerfiles("Sources/**.inl", { prefixdir = "private", install = false })
|
add_headerfiles("Sources/*.inl", { prefixdir = "private", install = false })
|
||||||
add_files("Sources/**.c")
|
|
||||||
add_files("Sources/**.cpp")
|
add_files("Sources/*.c")
|
||||||
|
|
||||||
|
for name, module in pairs(backends) do
|
||||||
|
if not has_config(module.option) then
|
||||||
|
goto continue
|
||||||
|
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)
|
on_load(function(target)
|
||||||
if target:kind() == "static" then
|
if target:kind() == "static" then
|
||||||
target:add("defines", "PULSE_STATIC", { public = true })
|
target:add("defines", "PULSE_STATIC", { public = true })
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
target_end()
|
target_end()
|
||||||
|
|
||||||
|
includes("Tests/*.lua")
|
||||||
|
|||||||
Reference in New Issue
Block a user