mirror of
https://github.com/Kbz-8/Pulse.git
synced 2026-01-10 15:03:34 +00:00
314 lines
11 KiB
C
314 lines
11 KiB
C
// Copyright (C) 2025 kanel
|
|
// This file is part of "Pulse"
|
|
// For conditions of distribution and use, see copyright notice in LICENSE
|
|
|
|
#pragma once
|
|
|
|
#ifndef PULSE_H_
|
|
#define PULSE_H_
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
#include <stdint.h>
|
|
#include <stdbool.h>
|
|
|
|
#include "PulseProfile.h"
|
|
|
|
#define PULSE_VERSION PULSE_MAKE_VERSION(0, 1, 0)
|
|
|
|
// Types
|
|
typedef uint64_t PulseDeviceSize;
|
|
typedef uint32_t PulseFlags;
|
|
|
|
PULSE_DEFINE_NULLABLE_HANDLE(PulseBackend);
|
|
PULSE_DEFINE_NULLABLE_HANDLE(PulseBuffer);
|
|
PULSE_DEFINE_NULLABLE_HANDLE(PulseCommandList);
|
|
PULSE_DEFINE_NULLABLE_HANDLE(PulseComputePipeline);
|
|
PULSE_DEFINE_NULLABLE_HANDLE(PulseDevice);
|
|
PULSE_DEFINE_NULLABLE_HANDLE(PulseFence);
|
|
PULSE_DEFINE_NULLABLE_HANDLE(PulseImage);
|
|
PULSE_DEFINE_NULLABLE_HANDLE(PulseComputePass);
|
|
|
|
// Flags
|
|
typedef enum PulseBackendBits
|
|
{
|
|
PULSE_BACKEND_INVALID = PULSE_BIT(1),
|
|
PULSE_BACKEND_ANY = PULSE_BIT(2),
|
|
PULSE_BACKEND_VULKAN = PULSE_BIT(3),
|
|
PULSE_BACKEND_METAL = PULSE_BIT(4),
|
|
PULSE_BACKEND_WEBGPU = PULSE_BIT(5),
|
|
PULSE_BACKEND_SOFTWARE = PULSE_BIT(6),
|
|
PULSE_BACKEND_OPENGL = PULSE_BIT(7),
|
|
PULSE_BACKEND_OPENGL_ES = PULSE_BIT(8),
|
|
PULSE_BACKEND_D3D11 = PULSE_BIT(9),
|
|
} PulseBackendBits;
|
|
typedef PulseFlags PulseBackendFlags;
|
|
|
|
typedef enum PulseBufferUsageBits
|
|
{
|
|
PULSE_BUFFER_USAGE_TRANSFER_UPLOAD = PULSE_BIT(1),
|
|
PULSE_BUFFER_USAGE_TRANSFER_DOWNLOAD = PULSE_BIT(2),
|
|
PULSE_BUFFER_USAGE_STORAGE_READ = PULSE_BIT(3),
|
|
PULSE_BUFFER_USAGE_STORAGE_WRITE = PULSE_BIT(4),
|
|
} PulseBufferUsageBits;
|
|
typedef PulseFlags PulseBufferUsageFlags;
|
|
|
|
/**
|
|
* With regards to compute storage usage, READ | WRITE means that you can have shader A
|
|
* that only writes into the image and shader B that only reads from the image and
|
|
* bind the same image to either shader respectively. SIMULTANEOUS means that you can
|
|
* do reads and writes within the same shader or compute pass.
|
|
*/
|
|
typedef enum PulseImageUsageBits
|
|
{
|
|
PULSE_IMAGE_USAGE_STORAGE_READ = PULSE_BIT(1),
|
|
PULSE_IMAGE_USAGE_STORAGE_WRITE = PULSE_BIT(2),
|
|
PULSE_IMAGE_USAGE_STORAGE_SIMULTANEOUS_READWRITE = PULSE_BIT(3),
|
|
} PulseImageFormatBits;
|
|
typedef PulseFlags PulseImageUsageFlags;
|
|
|
|
typedef enum PulseShaderFormatsBits
|
|
{
|
|
PULSE_SHADER_FORMAT_SPIRV_BIT = PULSE_BIT(1), // Can be used by Vulkan and Software backends
|
|
PULSE_SHADER_FORMAT_MSL_BIT = PULSE_BIT(2), // Can be used by Metal backend
|
|
PULSE_SHADER_FORMAT_METALLIB_BIT = PULSE_BIT(3), // Can be used by Metal backend
|
|
PULSE_SHADER_FORMAT_WGSL_BIT = PULSE_BIT(4), // Can be used by WebGPU backend
|
|
PULSE_SHADER_FORMAT_GLSL_BIT = PULSE_BIT(5), // Can be used by OpenGL / OpenGL_ES backend
|
|
PULSE_SHADER_FORMAT_DXBC_BIT = PULSE_BIT(6), // Can be used by D3D11 backend
|
|
// More to come
|
|
} PulseShaderFormatsBits;
|
|
typedef PulseFlags PulseShaderFormatsFlags;
|
|
|
|
// Enums
|
|
typedef enum PulseCommandListUsage
|
|
{
|
|
PULSE_COMMAND_LIST_GENERAL = 0,
|
|
PULSE_COMMAND_LIST_TRANSFER_ONLY,
|
|
|
|
PULSE_COMMAND_LIST_MAX_ENUM,
|
|
} PulseCommandListUsage;
|
|
|
|
typedef enum PulseDebugLevel
|
|
{
|
|
PULSE_NO_DEBUG = 0,
|
|
PULSE_LOW_DEBUG = 1,
|
|
PULSE_HIGH_DEBUG = 2,
|
|
PULSE_PARANOID_DEBUG = 3, // Causes every warning to be treated as error
|
|
|
|
PULSE_DEBUG_MAX_ENUM,
|
|
} PulseDebugLevel;
|
|
|
|
typedef enum PulseDebugMessageSeverity
|
|
{
|
|
PULSE_DEBUG_MESSAGE_SEVERITY_INFO = 0,
|
|
PULSE_DEBUG_MESSAGE_SEVERITY_WARNING,
|
|
PULSE_DEBUG_MESSAGE_SEVERITY_ERROR,
|
|
|
|
PULSE_DEBUG_MESSAGE_SEVERITY_MAX_ENUM,
|
|
} PulseDebugMessageSeverity;
|
|
|
|
typedef enum PulseErrorType
|
|
{
|
|
PULSE_ERROR_NONE = 0,
|
|
PULSE_ERROR_BACKENDS_CANDIDATES_SHADER_FORMAT_MISMATCH,
|
|
PULSE_ERROR_INVALID_BACKEND,
|
|
PULSE_ERROR_INITIALIZATION_FAILED,
|
|
PULSE_ERROR_INVALID_HANDLE,
|
|
PULSE_ERROR_CPU_ALLOCATION_FAILED,
|
|
PULSE_ERROR_DEVICE_ALLOCATION_FAILED,
|
|
PULSE_ERROR_DEVICE_LOST,
|
|
PULSE_ERROR_INVALID_INTERNAL_POINTER,
|
|
PULSE_ERROR_MAP_FAILED,
|
|
PULSE_ERROR_INVALID_DEVICE,
|
|
PULSE_ERROR_INVALID_REGION,
|
|
PULSE_ERROR_INVALID_BUFFER_USAGE,
|
|
PULSE_ERROR_INVALID_IMAGE_USAGE,
|
|
PULSE_ERROR_INVALID_IMAGE_FORMAT,
|
|
|
|
PULSE_ERROR_TYPE_MAX_ENUM,
|
|
} PulseErrorType;
|
|
|
|
typedef enum PulseImageType
|
|
{
|
|
PULSE_IMAGE_TYPE_2D = 0,
|
|
PULSE_IMAGE_TYPE_2D_ARRAY,
|
|
PULSE_IMAGE_TYPE_3D,
|
|
PULSE_IMAGE_TYPE_CUBE,
|
|
PULSE_IMAGE_TYPE_CUBE_ARRAY,
|
|
|
|
PULSE_IMAGE_TYPE_MAX_ENUM,
|
|
} PulseImageType;
|
|
|
|
typedef enum PulseImageFormat
|
|
{
|
|
PULSE_IMAGE_FORMAT_INVALID = 0,
|
|
// Unsigned Normalized Float Color Formats
|
|
PULSE_IMAGE_FORMAT_A8_UNORM,
|
|
PULSE_IMAGE_FORMAT_R8_UNORM,
|
|
PULSE_IMAGE_FORMAT_R8G8_UNORM,
|
|
PULSE_IMAGE_FORMAT_R8G8B8A8_UNORM,
|
|
PULSE_IMAGE_FORMAT_R16_UNORM,
|
|
PULSE_IMAGE_FORMAT_R16G16_UNORM,
|
|
PULSE_IMAGE_FORMAT_R16G16B16A16_UNORM,
|
|
PULSE_IMAGE_FORMAT_R10G10B10A2_UNORM,
|
|
PULSE_IMAGE_FORMAT_B5G6R5_UNORM,
|
|
PULSE_IMAGE_FORMAT_B5G5R5A1_UNORM,
|
|
PULSE_IMAGE_FORMAT_B4G4R4A4_UNORM,
|
|
PULSE_IMAGE_FORMAT_B8G8R8A8_UNORM,
|
|
// Signed Normalized Float Color Formats
|
|
PULSE_IMAGE_FORMAT_R8_SNORM,
|
|
PULSE_IMAGE_FORMAT_R8G8_SNORM,
|
|
PULSE_IMAGE_FORMAT_R8G8B8A8_SNORM,
|
|
PULSE_IMAGE_FORMAT_R16_SNORM,
|
|
PULSE_IMAGE_FORMAT_R16G16_SNORM,
|
|
PULSE_IMAGE_FORMAT_R16G16B16A16_SNORM,
|
|
// Signed Float Color Formats
|
|
PULSE_IMAGE_FORMAT_R16_FLOAT,
|
|
PULSE_IMAGE_FORMAT_R16G16_FLOAT,
|
|
PULSE_IMAGE_FORMAT_R16G16B16A16_FLOAT,
|
|
PULSE_IMAGE_FORMAT_R32_FLOAT,
|
|
PULSE_IMAGE_FORMAT_R32G32_FLOAT,
|
|
PULSE_IMAGE_FORMAT_R32G32B32A32_FLOAT,
|
|
// Unsigned Float Color Formats
|
|
PULSE_IMAGE_FORMAT_R11G11B10_UFLOAT,
|
|
// Unsigned Integer Color Formats
|
|
PULSE_IMAGE_FORMAT_R8_UINT,
|
|
PULSE_IMAGE_FORMAT_R8G8_UINT,
|
|
PULSE_IMAGE_FORMAT_R8G8B8A8_UINT,
|
|
PULSE_IMAGE_FORMAT_R16_UINT,
|
|
PULSE_IMAGE_FORMAT_R16G16_UINT,
|
|
PULSE_IMAGE_FORMAT_R16G16B16A16_UINT,
|
|
PULSE_IMAGE_FORMAT_R32_UINT,
|
|
PULSE_IMAGE_FORMAT_R32G32_UINT,
|
|
PULSE_IMAGE_FORMAT_R32G32B32A32_UINT,
|
|
// Signed Integer Color Formats
|
|
PULSE_IMAGE_FORMAT_R8_INT,
|
|
PULSE_IMAGE_FORMAT_R8G8_INT,
|
|
PULSE_IMAGE_FORMAT_R8G8B8A8_INT,
|
|
PULSE_IMAGE_FORMAT_R16_INT,
|
|
PULSE_IMAGE_FORMAT_R16G16_INT,
|
|
PULSE_IMAGE_FORMAT_R16G16B16A16_INT,
|
|
PULSE_IMAGE_FORMAT_R32_INT,
|
|
PULSE_IMAGE_FORMAT_R32G32_INT,
|
|
PULSE_IMAGE_FORMAT_R32G32B32A32_INT,
|
|
|
|
PULSE_IMAGE_FORMAT_MAX_ENUM // For internal use only
|
|
} PulseImageFormat;
|
|
|
|
typedef enum PulseMapMode
|
|
{
|
|
PULSE_MAP_READ = 0,
|
|
PULSE_MAP_WRITE,
|
|
|
|
PULSE_MAP_MAX_ENUM,
|
|
} PulseMapMode;
|
|
|
|
// Structs
|
|
typedef struct PulseBufferCreateInfo
|
|
{
|
|
PulseBufferUsageFlags usage;
|
|
PulseDeviceSize size;
|
|
} PulseBufferCreateInfo;
|
|
|
|
typedef struct PulseBufferRegion
|
|
{
|
|
PulseBuffer buffer;
|
|
PulseDeviceSize offset;
|
|
PulseDeviceSize size;
|
|
} PulseBufferRegion;
|
|
|
|
typedef struct PulseComputePipelineCreateInfo
|
|
{
|
|
uint64_t code_size;
|
|
const uint8_t* code;
|
|
const char* entrypoint;
|
|
PulseShaderFormatsFlags format;
|
|
uint32_t num_readonly_storage_images;
|
|
uint32_t num_readonly_storage_buffers;
|
|
uint32_t num_readwrite_storage_images;
|
|
uint32_t num_readwrite_storage_buffers;
|
|
uint32_t num_uniform_buffers;
|
|
} PulseComputePipelineCreateInfo;
|
|
|
|
typedef struct PulseImageCreateInfo
|
|
{
|
|
PulseImageType type;
|
|
PulseImageFormat format;
|
|
PulseImageUsageFlags usage;
|
|
uint32_t width;
|
|
uint32_t height;
|
|
uint32_t layer_count_or_depth; // This value is treated as a layer count on 2D array images, and as a depth value on 3D images
|
|
} PulseImageCreateInfo;
|
|
|
|
typedef struct PulseImageRegion
|
|
{
|
|
PulseImage image;
|
|
uint32_t layer;
|
|
uint32_t x;
|
|
uint32_t y;
|
|
uint32_t z;
|
|
uint32_t width;
|
|
uint32_t height;
|
|
uint32_t depth;
|
|
} PulseImageRegion;
|
|
|
|
// Functions
|
|
typedef void (*PulseDebugCallbackPFN)(PulseDebugMessageSeverity, const char*);
|
|
|
|
PULSE_API bool PulseSupportsBackend(PulseBackendFlags backend_candidates, PulseShaderFormatsFlags shader_formats_used);
|
|
|
|
PULSE_API PulseBackend PulseLoadBackend(PulseBackendFlags backend_candidates, PulseShaderFormatsFlags shader_formats_used, PulseDebugLevel debug_level);
|
|
PULSE_API PulseBackendFlags PulseGetBackendType(PulseBackend backend);
|
|
PULSE_API void PulseSetDebugCallback(PulseBackend backend, PulseDebugCallbackPFN callback);
|
|
PULSE_API void PulseUnloadBackend(PulseBackend backend);
|
|
|
|
PULSE_API PulseDevice PulseCreateDevice(PulseBackend backend, PulseDevice* forbiden_devices, uint32_t forbiden_devices_count);
|
|
PULSE_API PulseBackendBits PulseGetBackendInUseByDevice(PulseDevice device);
|
|
PULSE_API bool PulseDeviceSupportsShaderFormats(PulseDevice device, PulseShaderFormatsFlags shader_formats_used);
|
|
PULSE_API void PulseDestroyDevice(PulseDevice device);
|
|
|
|
PULSE_API PulseBuffer PulseCreateBuffer(PulseDevice device, const PulseBufferCreateInfo* create_infos);
|
|
PULSE_API bool PulseMapBuffer(PulseBuffer buffer, PulseMapMode mode, void** data); // Data writing may only apply when unmapping
|
|
PULSE_API void PulseUnmapBuffer(PulseBuffer buffer);
|
|
PULSE_API bool PulseCopyBufferToBuffer(PulseCommandList cmd, const PulseBufferRegion* src, const PulseBufferRegion* dst);
|
|
PULSE_API bool PulseCopyBufferToImage(PulseCommandList cmd, const PulseBufferRegion* src, const PulseImageRegion* dst);
|
|
PULSE_API void PulseDestroyBuffer(PulseDevice device, PulseBuffer buffer);
|
|
|
|
PULSE_API PulseImage PulseCreateImage(PulseDevice device, const PulseImageCreateInfo* create_infos);
|
|
PULSE_API bool PulseIsImageFormatValid(PulseDevice device, PulseImageFormat format, PulseImageType type, PulseImageUsageFlags usage);
|
|
PULSE_API bool PulseCopyImageToBuffer(PulseCommandList cmd, const PulseImageRegion* src, const PulseBufferRegion* dst);
|
|
PULSE_API bool PulseBlitImage(PulseCommandList cmd, const PulseImageRegion* src, const PulseImageRegion* dst);
|
|
PULSE_API void PulseDestroyImage(PulseDevice device, PulseImage image);
|
|
|
|
PULSE_API PulseCommandList PulseRequestCommandList(PulseDevice device, PulseCommandListUsage usage);
|
|
PULSE_API bool PulseSubmitCommandList(PulseDevice device, PulseCommandList cmd, PulseFence fence);
|
|
PULSE_API void PulseReleaseCommandList(PulseDevice device, PulseCommandList cmd);
|
|
|
|
PULSE_API PulseFence PulseCreateFence(PulseDevice device);
|
|
PULSE_API void PulseDestroyFence(PulseDevice device, PulseFence fence);
|
|
PULSE_API bool PulseIsFenceReady(PulseDevice device, PulseFence fence);
|
|
PULSE_API bool PulseWaitForFences(PulseDevice device, const PulseFence* fences, uint32_t fences_count, bool wait_for_all);
|
|
|
|
PULSE_API PulseComputePipeline PulseCreateComputePipeline(PulseDevice device, const PulseComputePipelineCreateInfo* info);
|
|
PULSE_API void PulseDestroyComputePipeline(PulseDevice device, PulseComputePipeline pipeline);
|
|
|
|
PULSE_API PulseComputePass PulseBeginComputePass(PulseCommandList cmd);
|
|
PULSE_API void PulseBindStorageBuffers(PulseComputePass pass, const PulseBuffer* buffers, uint32_t num_buffers);
|
|
PULSE_API void PulseBindUniformData(PulseComputePass pass, uint32_t slot, const void* data, uint32_t data_size);
|
|
PULSE_API void PulseBindStorageImages(PulseComputePass pass, const PulseImage* images, uint32_t num_images);
|
|
PULSE_API void PulseBindComputePipeline(PulseComputePass pass, PulseComputePipeline pipeline);
|
|
PULSE_API void PulseDispatchComputations(PulseComputePass pass, uint32_t groupcount_x, uint32_t groupcount_y, uint32_t groupcount_z);
|
|
PULSE_API void PulseDispatchComputationsIndirect(PulseComputePass pass, PulseBuffer buffer, uint32_t offset);
|
|
PULSE_API void PulseEndComputePass(PulseComputePass pass);
|
|
|
|
PULSE_API PulseErrorType PulseGetLastErrorType(); // Call to this function resets the internal last error variable
|
|
PULSE_API const char* PulseVerbaliseErrorType(PulseErrorType error);
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif // PULSE_H_
|