mirror of
https://github.com/Kbz-8/Pulse.git
synced 2026-01-11 15:33:34 +00:00
yes
This commit is contained in:
@@ -79,8 +79,10 @@ typedef PulseFlags PulseShaderFormatsFlags;
|
|||||||
// Enums
|
// Enums
|
||||||
typedef enum PulseCommandListUsage
|
typedef enum PulseCommandListUsage
|
||||||
{
|
{
|
||||||
PULSE_COMMAND_LIST_GENERAL,
|
PULSE_COMMAND_LIST_GENERAL = 0,
|
||||||
PULSE_COMMAND_LIST_TRANSFER_ONLY
|
PULSE_COMMAND_LIST_TRANSFER_ONLY,
|
||||||
|
|
||||||
|
PULSE_COMMAND_LIST_MAX_ENUM,
|
||||||
} PulseCommandListUsage;
|
} PulseCommandListUsage;
|
||||||
|
|
||||||
typedef enum PulseDebugLevel
|
typedef enum PulseDebugLevel
|
||||||
@@ -88,19 +90,23 @@ typedef enum PulseDebugLevel
|
|||||||
PULSE_NO_DEBUG = 0,
|
PULSE_NO_DEBUG = 0,
|
||||||
PULSE_LOW_DEBUG = 1,
|
PULSE_LOW_DEBUG = 1,
|
||||||
PULSE_HIGH_DEBUG = 2,
|
PULSE_HIGH_DEBUG = 2,
|
||||||
PULSE_PARANOID_DEBUG = 3 // Causes every warning to be treated as error
|
PULSE_PARANOID_DEBUG = 3, // Causes every warning to be treated as error
|
||||||
|
|
||||||
|
PULSE_DEBUG_MAX_ENUM,
|
||||||
} PulseDebugLevel;
|
} PulseDebugLevel;
|
||||||
|
|
||||||
typedef enum PulseDebugMessageSeverity
|
typedef enum PulseDebugMessageSeverity
|
||||||
{
|
{
|
||||||
PULSE_DEBUG_MESSAGE_SEVERITY_INFO,
|
PULSE_DEBUG_MESSAGE_SEVERITY_INFO = 0,
|
||||||
PULSE_DEBUG_MESSAGE_SEVERITY_WARNING,
|
PULSE_DEBUG_MESSAGE_SEVERITY_WARNING,
|
||||||
PULSE_DEBUG_MESSAGE_SEVERITY_ERROR
|
PULSE_DEBUG_MESSAGE_SEVERITY_ERROR,
|
||||||
|
|
||||||
|
PULSE_DEBUG_MESSAGE_SEVERITY_MAX_ENUM,
|
||||||
} PulseDebugMessageSeverity;
|
} PulseDebugMessageSeverity;
|
||||||
|
|
||||||
typedef enum PulseErrorType
|
typedef enum PulseErrorType
|
||||||
{
|
{
|
||||||
PULSE_ERROR_NONE,
|
PULSE_ERROR_NONE = 0,
|
||||||
PULSE_ERROR_BACKENDS_CANDIDATES_SHADER_FORMAT_MISMATCH,
|
PULSE_ERROR_BACKENDS_CANDIDATES_SHADER_FORMAT_MISMATCH,
|
||||||
PULSE_ERROR_INVALID_BACKEND,
|
PULSE_ERROR_INVALID_BACKEND,
|
||||||
PULSE_ERROR_INITIALIZATION_FAILED,
|
PULSE_ERROR_INITIALIZATION_FAILED,
|
||||||
@@ -114,15 +120,20 @@ typedef enum PulseErrorType
|
|||||||
PULSE_ERROR_INVALID_REGION,
|
PULSE_ERROR_INVALID_REGION,
|
||||||
PULSE_ERROR_INVALID_BUFFER_USAGE,
|
PULSE_ERROR_INVALID_BUFFER_USAGE,
|
||||||
PULSE_ERROR_INVALID_IMAGE_USAGE,
|
PULSE_ERROR_INVALID_IMAGE_USAGE,
|
||||||
|
PULSE_ERROR_INVALID_IMAGE_FORMAT,
|
||||||
|
|
||||||
|
PULSE_ERROR_TYPE_MAX_ENUM,
|
||||||
} PulseErrorType;
|
} PulseErrorType;
|
||||||
|
|
||||||
typedef enum PulseImageType
|
typedef enum PulseImageType
|
||||||
{
|
{
|
||||||
PULSE_IMAGE_TYPE_2D,
|
PULSE_IMAGE_TYPE_2D = 0,
|
||||||
PULSE_IMAGE_TYPE_2D_ARRAY,
|
PULSE_IMAGE_TYPE_2D_ARRAY,
|
||||||
PULSE_IMAGE_TYPE_3D,
|
PULSE_IMAGE_TYPE_3D,
|
||||||
PULSE_IMAGE_TYPE_CUBE,
|
PULSE_IMAGE_TYPE_CUBE,
|
||||||
PULSE_IMAGE_TYPE_CUBE_ARRAY
|
PULSE_IMAGE_TYPE_CUBE_ARRAY,
|
||||||
|
|
||||||
|
PULSE_IMAGE_TYPE_MAX_ENUM,
|
||||||
} PulseImageType;
|
} PulseImageType;
|
||||||
|
|
||||||
typedef enum PulseImageFormat
|
typedef enum PulseImageFormat
|
||||||
@@ -194,8 +205,10 @@ typedef enum PulseImageFormat
|
|||||||
|
|
||||||
typedef enum PulseMapMode
|
typedef enum PulseMapMode
|
||||||
{
|
{
|
||||||
PULSE_MAP_READ,
|
PULSE_MAP_READ = 0,
|
||||||
PULSE_MAP_WRITE,
|
PULSE_MAP_WRITE,
|
||||||
|
|
||||||
|
PULSE_MAP_MAX_ENUM,
|
||||||
} PulseMapMode;
|
} PulseMapMode;
|
||||||
|
|
||||||
// Structs
|
// Structs
|
||||||
|
|||||||
@@ -169,7 +169,7 @@ PulseImage VulkanCreateImage(PulseDevice device, const PulseImageCreateInfo* cre
|
|||||||
|
|
||||||
bool VulkanIsImageFormatValid(PulseDevice device, PulseImageFormat format, PulseImageType type, PulseImageUsageFlags usage)
|
bool VulkanIsImageFormatValid(PulseDevice device, PulseImageFormat format, PulseImageType type, PulseImageUsageFlags usage)
|
||||||
{
|
{
|
||||||
(void)usage;
|
PULSE_UNUSED(usage);
|
||||||
VulkanDriverData* vulkan_driver_data = VULKAN_RETRIEVE_DRIVER_DATA_AS(device->backend, VulkanDriverData*);
|
VulkanDriverData* vulkan_driver_data = VULKAN_RETRIEVE_DRIVER_DATA_AS(device->backend, VulkanDriverData*);
|
||||||
VulkanDevice* vulkan_device = VULKAN_RETRIEVE_DRIVER_DATA_AS(device, VulkanDevice*);
|
VulkanDevice* vulkan_device = VULKAN_RETRIEVE_DRIVER_DATA_AS(device, VulkanDevice*);
|
||||||
VkImageCreateFlags vulkan_flags = 0;
|
VkImageCreateFlags vulkan_flags = 0;
|
||||||
|
|||||||
@@ -3,14 +3,172 @@
|
|||||||
// 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"
|
||||||
#include "WebGPU.h"
|
#include "WebGPU.h"
|
||||||
|
#include "WebGPUDevice.h"
|
||||||
|
#include "WebGPUImage.h"
|
||||||
|
#include "WebGPUCommandList.h"
|
||||||
|
|
||||||
|
static WGPUTextureFormat PulseImageFormatToWGPUTextureFormat[] = {
|
||||||
|
WGPUTextureFormat_Undefined, // INVALID
|
||||||
|
WGPUTextureFormat_R8Unorm, // A8_UNORM
|
||||||
|
WGPUTextureFormat_R8Unorm, // R8_UNORM
|
||||||
|
WGPUTextureFormat_RG8Unorm, // R8G8_UNORM
|
||||||
|
WGPUTextureFormat_RGBA8Unorm, // R8G8B8A8_UNORM
|
||||||
|
WGPUTextureFormat_R16Uint, // R16_UNORM
|
||||||
|
WGPUTextureFormat_RG16Uint, // R16G16_UNORM
|
||||||
|
WGPUTextureFormat_RGBA16Uint, // R16G16B16A16_UNORM
|
||||||
|
WGPUTextureFormat_RGB10A2Unorm, // R10G10B10A2_UNORM
|
||||||
|
WGPUTextureFormat_Undefined, // B5G6R5_UNORM
|
||||||
|
WGPUTextureFormat_Undefined, // B5G5R5A1_UNORM
|
||||||
|
WGPUTextureFormat_Undefined, // B4G4R4A4_UNORM
|
||||||
|
WGPUTextureFormat_BGRA8Unorm, // B8G8R8A8_UNORM
|
||||||
|
WGPUTextureFormat_BC1RGBAUnorm, // BC1_UNORM
|
||||||
|
WGPUTextureFormat_BC2RGBAUnorm, // BC2_UNORM
|
||||||
|
WGPUTextureFormat_BC3RGBAUnorm, // BC3_UNORM
|
||||||
|
WGPUTextureFormat_BC4RUnorm, // BC4_UNORM
|
||||||
|
WGPUTextureFormat_BC5RGUnorm, // BC5_UNORM
|
||||||
|
WGPUTextureFormat_BC7RGBAUnorm, // BC7_UNORM
|
||||||
|
WGPUTextureFormat_BC6HRGBFloat, // BC6H_FLOAT
|
||||||
|
WGPUTextureFormat_BC6HRGBUfloat, // BC6H_UFLOAT
|
||||||
|
WGPUTextureFormat_R8Snorm, // R8_SNORM
|
||||||
|
WGPUTextureFormat_RG8Snorm, // R8G8_SNORM
|
||||||
|
WGPUTextureFormat_RGBA8Snorm, // R8G8B8A8_SNORM
|
||||||
|
WGPUTextureFormat_R16Sint, // R16_SNORM
|
||||||
|
WGPUTextureFormat_RG16Sint, // R16G16_SNORM
|
||||||
|
WGPUTextureFormat_RGBA16Sint, // R16G16B16A16_SNORM
|
||||||
|
WGPUTextureFormat_R16Float, // R16_FLOAT
|
||||||
|
WGPUTextureFormat_RG16Float, // R16G16_FLOAT
|
||||||
|
WGPUTextureFormat_RGBA16Float, // R16G16B16A16_FLOAT
|
||||||
|
WGPUTextureFormat_R32Float, // R32_FLOAT
|
||||||
|
WGPUTextureFormat_RG32Float, // R32G32_FLOAT
|
||||||
|
WGPUTextureFormat_RGBA32Float, // R32G32B32A32_FLOAT
|
||||||
|
WGPUTextureFormat_RG11B10Ufloat, // R11G11B10_UFLOAT
|
||||||
|
WGPUTextureFormat_R8Uint, // R8_UINT
|
||||||
|
WGPUTextureFormat_RG8Unorm, // R8G8_UINT
|
||||||
|
WGPUTextureFormat_RGBA8Uint, // R8G8B8A8_UINT
|
||||||
|
WGPUTextureFormat_R16Uint, // R16_UINT
|
||||||
|
WGPUTextureFormat_RG16Uint, // R16G16_UINT
|
||||||
|
WGPUTextureFormat_RGBA16Uint, // R16G16B16A16_UINT
|
||||||
|
WGPUTextureFormat_R32Uint, // R32_UINT
|
||||||
|
WGPUTextureFormat_RG32Uint, // R32G32_UINT
|
||||||
|
WGPUTextureFormat_RGBA32Uint, // R32G32B32A32_UINT
|
||||||
|
WGPUTextureFormat_R8Sint, // R8_INT
|
||||||
|
WGPUTextureFormat_RG8Sint, // R8G8_INT
|
||||||
|
WGPUTextureFormat_RGBA8Sint, // R8G8B8A8_INT
|
||||||
|
WGPUTextureFormat_R16Sint, // R16_INT
|
||||||
|
WGPUTextureFormat_RG16Sint, // R16G16_INT
|
||||||
|
WGPUTextureFormat_RGBA16Sint, // R16G16B16A16_INT
|
||||||
|
WGPUTextureFormat_R32Sint, // R32_INT
|
||||||
|
WGPUTextureFormat_RG32Sint, // R32G32_INT
|
||||||
|
WGPUTextureFormat_RGBA32Sint, // R32G32B32A32_INT
|
||||||
|
};
|
||||||
|
PULSE_STATIC_ASSERT(PulseImageFormatToWGPUTextureFormat, (sizeof(PulseImageFormatToWGPUTextureFormat) / sizeof(WGPUTextureFormat)) == PULSE_IMAGE_FORMAT_MAX_ENUM);
|
||||||
|
|
||||||
|
static WGPUTextureDimension PulseImageTypeToWGPUTextureDimension[] = {
|
||||||
|
WGPUTextureDimension_2D, //PULSE_IMAGE_TYPE_2D
|
||||||
|
WGPUTextureDimension_2D, //PULSE_IMAGE_TYPE_2D_ARRAY
|
||||||
|
WGPUTextureDimension_3D, //PULSE_IMAGE_TYPE_3D
|
||||||
|
WGPUTextureDimension_2D, //PULSE_IMAGE_TYPE_CUBE
|
||||||
|
WGPUTextureDimension_2D, //PULSE_IMAGE_TYPE_CUBE_ARRAY
|
||||||
|
};
|
||||||
|
PULSE_STATIC_ASSERT(PulseImageTypeToWGPUTextureDimension, (sizeof(PulseImageTypeToWGPUTextureDimension) / sizeof(WGPUTextureDimension)) == PULSE_IMAGE_TYPE_MAX_ENUM);
|
||||||
|
|
||||||
PulseImage WebGPUCreateImage(PulseDevice device, const PulseImageCreateInfo* create_infos)
|
PulseImage WebGPUCreateImage(PulseDevice device, const PulseImageCreateInfo* create_infos)
|
||||||
{
|
{
|
||||||
|
WebGPUDevice* webgpu_device = WEBGPU_RETRIEVE_DRIVER_DATA_AS(device, WebGPUDevice*);
|
||||||
|
|
||||||
|
PulseImageHandler* image = (PulseImageHandler*)calloc(1, sizeof(PulseImageHandler));
|
||||||
|
PULSE_CHECK_ALLOCATION_RETVAL(image, PULSE_NULL_HANDLE);
|
||||||
|
|
||||||
|
WebGPUImage* webgpu_image = (WebGPUImage*)calloc(1, sizeof(WebGPUImage));
|
||||||
|
PULSE_CHECK_ALLOCATION_RETVAL(webgpu_image, PULSE_NULL_HANDLE);
|
||||||
|
|
||||||
|
WGPUTextureDescriptor descriptor = { 0 };
|
||||||
|
descriptor.dimension = PulseImageTypeToWGPUTextureDimension[create_infos->type];
|
||||||
|
descriptor.format = PulseImageFormatToWGPUTextureFormat[create_infos->format];
|
||||||
|
|
||||||
|
if(create_infos->format == PULSE_IMAGE_FORMAT_B4G4R4A4_UNORM || create_infos->format == PULSE_IMAGE_FORMAT_B5G6R5_UNORM || create_infos->format == PULSE_IMAGE_FORMAT_B5G5R5A1_UNORM)
|
||||||
|
{
|
||||||
|
if(PULSE_IS_BACKEND_LOW_LEVEL_DEBUG(device->backend))
|
||||||
|
PulseLogError(device->backend, "(WebGPU) unsupported image format");
|
||||||
|
PulseSetInternalError(PULSE_ERROR_INVALID_IMAGE_FORMAT);
|
||||||
|
return PULSE_NULL_HANDLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
descriptor.viewFormatCount = 1;
|
||||||
|
descriptor.viewFormats = &descriptor.format;
|
||||||
|
descriptor.size.width = create_infos->width;
|
||||||
|
descriptor.size.height = create_infos->height;
|
||||||
|
descriptor.mipLevelCount = 1;
|
||||||
|
descriptor.sampleCount = 1;
|
||||||
|
|
||||||
|
if(create_infos->type == PULSE_IMAGE_TYPE_3D)
|
||||||
|
descriptor.size.depthOrArrayLayers = create_infos->layer_count_or_depth;
|
||||||
|
else if(create_infos->type == PULSE_IMAGE_TYPE_2D_ARRAY || create_infos->type == PULSE_IMAGE_TYPE_CUBE || create_infos->type == PULSE_IMAGE_TYPE_CUBE_ARRAY)
|
||||||
|
descriptor.size.depthOrArrayLayers = create_infos->layer_count_or_depth;
|
||||||
|
else
|
||||||
|
descriptor.size.depthOrArrayLayers = 1;
|
||||||
|
|
||||||
|
descriptor.usage = 0;
|
||||||
|
if(create_infos->usage & PULSE_IMAGE_USAGE_STORAGE_READ)
|
||||||
|
descriptor.usage |= WGPUTextureUsage_StorageBinding | WGPUTextureUsage_CopyDst;
|
||||||
|
if(create_infos->usage & PULSE_IMAGE_USAGE_STORAGE_WRITE)
|
||||||
|
descriptor.usage |= WGPUTextureUsage_StorageBinding | WGPUTextureUsage_CopySrc;
|
||||||
|
if(create_infos->usage & PULSE_IMAGE_USAGE_STORAGE_SIMULTANEOUS_READWRITE)
|
||||||
|
descriptor.usage |= WGPUTextureUsage_StorageBinding | WGPUTextureUsage_CopySrc | WGPUTextureUsage_CopyDst;
|
||||||
|
|
||||||
|
webgpu_image->texture = wgpuDeviceCreateTexture(webgpu_device->device, &descriptor);
|
||||||
|
if(webgpu_image->texture == PULSE_NULLPTR)
|
||||||
|
{
|
||||||
|
free(webgpu_image);
|
||||||
|
free(image);
|
||||||
|
return PULSE_NULL_HANDLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return image;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WebGPUIsImageFormatValid(PulseDevice device, PulseImageFormat format, PulseImageType type, PulseImageUsageFlags usage)
|
bool WebGPUIsImageFormatValid(PulseDevice device, PulseImageFormat format, PulseImageType type, PulseImageUsageFlags usage)
|
||||||
{
|
{
|
||||||
|
WGPUTextureFormat wgpu_format = PulseImageFormatToWGPUTextureFormat[format];
|
||||||
|
|
||||||
|
WGPUTextureDimension dimension = WGPUTextureDimension_Undefined;
|
||||||
|
if(type == PULSE_IMAGE_TYPE_2D || type == PULSE_IMAGE_TYPE_2D_ARRAY)
|
||||||
|
dimension = WGPUTextureDimension_2D;
|
||||||
|
else if(type == PULSE_IMAGE_TYPE_3D || type == PULSE_IMAGE_TYPE_CUBE || type == PULSE_IMAGE_TYPE_CUBE_ARRAY)
|
||||||
|
dimension = WGPUTextureDimension_3D;
|
||||||
|
|
||||||
|
WGPUTextureUsage wgpu_usage = 0;
|
||||||
|
if(usage & PULSE_IMAGE_USAGE_STORAGE_READ)
|
||||||
|
wgpu_usage |= WGPUTextureUsage_StorageBinding | WGPUTextureUsage_CopyDst;
|
||||||
|
if(usage & PULSE_IMAGE_USAGE_STORAGE_WRITE)
|
||||||
|
wgpu_usage |= WGPUTextureUsage_StorageBinding | WGPUTextureUsage_CopySrc;
|
||||||
|
if(usage & PULSE_IMAGE_USAGE_STORAGE_SIMULTANEOUS_READWRITE)
|
||||||
|
wgpu_usage |= WGPUTextureUsage_StorageBinding | WGPUTextureUsage_CopySrc | WGPUTextureUsage_CopyDst;
|
||||||
|
|
||||||
|
if(wgpu_format == WGPUTextureFormat_Undefined)
|
||||||
|
{
|
||||||
|
if(PULSE_IS_BACKEND_LOW_LEVEL_DEBUG(device->backend))
|
||||||
|
PulseLogError(device->backend, "(WebGPU) unsupported image format");
|
||||||
|
PulseSetInternalError(PULSE_ERROR_INVALID_IMAGE_FORMAT);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if(wgpu_usage == WGPUTextureUsage_None)
|
||||||
|
{
|
||||||
|
if(PULSE_IS_BACKEND_LOW_LEVEL_DEBUG(device->backend))
|
||||||
|
PulseLogError(device->backend, "(WebGPU) unsupported image usage");
|
||||||
|
PulseSetInternalError(PULSE_ERROR_INVALID_IMAGE_USAGE);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if(dimension == WGPUTextureDimension_Undefined)
|
||||||
|
{
|
||||||
|
if(PULSE_IS_BACKEND_LOW_LEVEL_DEBUG(device->backend))
|
||||||
|
PulseLogError(device->backend, "(WebGPU) unsupported image type");
|
||||||
|
PulseSetInternalError(PULSE_ERROR_INVALID_IMAGE_FORMAT);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WebGPUCopyImageToBuffer(PulseCommandList cmd, const PulseImageRegion* src, const PulseBufferRegion* dst)
|
bool WebGPUCopyImageToBuffer(PulseCommandList cmd, const PulseImageRegion* src, const PulseBufferRegion* dst)
|
||||||
@@ -23,4 +181,9 @@ bool WebGPUBlitImage(PulseCommandList cmd, const PulseImageRegion* src, const Pu
|
|||||||
|
|
||||||
void WebGPUDestroyImage(PulseDevice device, PulseImage image)
|
void WebGPUDestroyImage(PulseDevice device, PulseImage image)
|
||||||
{
|
{
|
||||||
|
PULSE_UNUSED(device);
|
||||||
|
WebGPUImage* webgpu_image = WEBGPU_RETRIEVE_DRIVER_DATA_AS(image, WebGPUImage*);
|
||||||
|
wgpuTextureRelease(webgpu_image->texture);
|
||||||
|
free(webgpu_image);
|
||||||
|
free(image);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
|
|
||||||
typedef struct WebGPUImage
|
typedef struct WebGPUImage
|
||||||
{
|
{
|
||||||
|
WGPUTexture texture;
|
||||||
} WebGPUImage;
|
} WebGPUImage;
|
||||||
|
|
||||||
PulseImage WebGPUCreateImage(PulseDevice device, const PulseImageCreateInfo* create_infos);
|
PulseImage WebGPUCreateImage(PulseDevice device, const PulseImageCreateInfo* create_infos);
|
||||||
|
|||||||
@@ -186,6 +186,7 @@ PULSE_API const char* PulseVerbaliseErrorType(PulseErrorType error)
|
|||||||
case PULSE_ERROR_INVALID_REGION: return "invalid region";
|
case PULSE_ERROR_INVALID_REGION: return "invalid region";
|
||||||
case PULSE_ERROR_INVALID_BUFFER_USAGE: return "invalid buffer usage";
|
case PULSE_ERROR_INVALID_BUFFER_USAGE: return "invalid buffer usage";
|
||||||
case PULSE_ERROR_INVALID_IMAGE_USAGE: return "invalid image usage";
|
case PULSE_ERROR_INVALID_IMAGE_USAGE: return "invalid image usage";
|
||||||
|
case PULSE_ERROR_INVALID_IMAGE_FORMAT: return "invalid image format";
|
||||||
|
|
||||||
default: return "invalid error type";
|
default: return "invalid error type";
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user