adding backend management responsability to the user

This commit is contained in:
2024-10-09 18:56:41 +02:00
parent b075f8ea73
commit f189928c82
12 changed files with 321 additions and 139 deletions

View File

@@ -5,65 +5,9 @@
#include <Pulse.h>
#include "PulseInternal.h"
#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)
PULSE_API PulseDevice PulseCreateDevice(PulseBackend backend, PulseDevice* forbiden_devices, uint32_t forbiden_devices_count)
{
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);
PulseDevice device = backend->PFN_CreateDevice(backend, forbiden_devices, forbiden_devices_count);
if(device == PULSE_NULL_HANDLE)
PulseSetInternalError(PULSE_ERROR_INITIALIZATION_FAILED);
device->backend = backend;
@@ -73,7 +17,7 @@ PULSE_API PulseDevice PulseCreateDevice(PulseBackendFlags backend_candidates, Pu
PULSE_API void PulseDestroyDevice(PulseDevice device)
{
PULSE_CHECK_HANDLE(device);
device->backend->PFN_DestroyDevice(device);
device->PFN_DestroyDevice(device);
}
PULSE_API PulseBackendBits PulseGetBackendInUseByDevice(PulseDevice device)
@@ -82,45 +26,8 @@ PULSE_API PulseBackendBits PulseGetBackendInUseByDevice(PulseDevice device)
return device->backend->backend;
}
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_API bool PulseDeviceSupportsShaderFormats(PulseDevice device, PulseShaderFormatsFlags shader_formats_used)
{
PULSE_CHECK_HANDLE_RETVAL(device, false);
return (device->backend->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";
case PULSE_ERROR_ALLOCATION_FAILED: return "an internal allocation failed";
default: return "invalid error type";
};
return PULSE_NULLPTR; // To avoid warnings, should be unreachable
}