mirror of
https://github.com/Kbz-8/Pulse.git
synced 2026-01-11 15:33:34 +00:00
yes
This commit is contained in:
@@ -9,6 +9,10 @@
|
||||
#ifndef PULSE_SOFTWARE_H_
|
||||
#define PULSE_SOFTWARE_H_
|
||||
|
||||
#ifdef __STDC_NO_ATOMICS__
|
||||
#error "Atomic support is not present"
|
||||
#endif
|
||||
|
||||
#define SOFT_RETRIEVE_DRIVER_DATA_AS(handle, cast) ((cast)handle->driver_data)
|
||||
|
||||
PulseBackendFlags SoftCheckSupport(PulseBackendFlags candidates, PulseShaderFormatsFlags shader_formats_used); // Return PULSE_BACKEND_SOFTWARE in case of success and PULSE_BACKEND_INVALID otherwise
|
||||
|
||||
@@ -28,12 +28,7 @@
|
||||
#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
|
||||
#ifndef PULSE_PLAT_WINDOWS
|
||||
#include <dlfcn.h>
|
||||
typedef void* LibModule;
|
||||
#endif
|
||||
|
||||
@@ -59,3 +59,200 @@ PulseBackendHandler WebGPUDriver = {
|
||||
.supported_shader_formats = PULSE_SHADER_FORMAT_WGSL_BIT,
|
||||
.driver_data = PULSE_NULLPTR
|
||||
};
|
||||
|
||||
int32_t WebGPUGetImageBlockWidth(PulseImageFormat format)
|
||||
{
|
||||
switch(format)
|
||||
{
|
||||
case PULSE_IMAGE_FORMAT_BC1_RGBA_UNORM:
|
||||
case PULSE_IMAGE_FORMAT_BC2_RGBA_UNORM:
|
||||
case PULSE_IMAGE_FORMAT_BC3_RGBA_UNORM:
|
||||
case PULSE_IMAGE_FORMAT_BC4_R_UNORM:
|
||||
case PULSE_IMAGE_FORMAT_BC5_RG_UNORM:
|
||||
case PULSE_IMAGE_FORMAT_BC7_RGBA_UNORM:
|
||||
case PULSE_IMAGE_FORMAT_BC6H_RGB_FLOAT:
|
||||
case PULSE_IMAGE_FORMAT_BC6H_RGB_UFLOAT: return 4;
|
||||
|
||||
case PULSE_IMAGE_FORMAT_R8G8B8A8_UNORM:
|
||||
case PULSE_IMAGE_FORMAT_B8G8R8A8_UNORM:
|
||||
case PULSE_IMAGE_FORMAT_B5G6R5_UNORM:
|
||||
case PULSE_IMAGE_FORMAT_B5G5R5A1_UNORM:
|
||||
case PULSE_IMAGE_FORMAT_B4G4R4A4_UNORM:
|
||||
case PULSE_IMAGE_FORMAT_R10G10B10A2_UNORM:
|
||||
case PULSE_IMAGE_FORMAT_R8G8_UNORM:
|
||||
case PULSE_IMAGE_FORMAT_R16G16_UNORM:
|
||||
case PULSE_IMAGE_FORMAT_R16G16B16A16_UNORM:
|
||||
case PULSE_IMAGE_FORMAT_R8_UNORM:
|
||||
case PULSE_IMAGE_FORMAT_R16_UNORM:
|
||||
case PULSE_IMAGE_FORMAT_A8_UNORM:
|
||||
case PULSE_IMAGE_FORMAT_R8_SNORM:
|
||||
case PULSE_IMAGE_FORMAT_R8G8_SNORM:
|
||||
case PULSE_IMAGE_FORMAT_R8G8B8A8_SNORM:
|
||||
case PULSE_IMAGE_FORMAT_R16_SNORM:
|
||||
case PULSE_IMAGE_FORMAT_R16G16_SNORM:
|
||||
case PULSE_IMAGE_FORMAT_R16G16B16A16_SNORM:
|
||||
case PULSE_IMAGE_FORMAT_R16_FLOAT:
|
||||
case PULSE_IMAGE_FORMAT_R16G16_FLOAT:
|
||||
case PULSE_IMAGE_FORMAT_R16G16B16A16_FLOAT:
|
||||
case PULSE_IMAGE_FORMAT_R32_FLOAT:
|
||||
case PULSE_IMAGE_FORMAT_R32G32_FLOAT:
|
||||
case PULSE_IMAGE_FORMAT_R32G32B32A32_FLOAT:
|
||||
case PULSE_IMAGE_FORMAT_R11G11B10_UFLOAT:
|
||||
case PULSE_IMAGE_FORMAT_R8_UINT:
|
||||
case PULSE_IMAGE_FORMAT_R8G8_UINT:
|
||||
case PULSE_IMAGE_FORMAT_R8G8B8A8_UINT:
|
||||
case PULSE_IMAGE_FORMAT_R16_UINT:
|
||||
case PULSE_IMAGE_FORMAT_R16G16_UINT:
|
||||
case PULSE_IMAGE_FORMAT_R16G16B16A16_UINT:
|
||||
case PULSE_IMAGE_FORMAT_R32_UINT:
|
||||
case PULSE_IMAGE_FORMAT_R32G32_UINT:
|
||||
case PULSE_IMAGE_FORMAT_R32G32B32A32_UINT:
|
||||
case PULSE_IMAGE_FORMAT_R8_INT:
|
||||
case PULSE_IMAGE_FORMAT_R8G8_INT:
|
||||
case PULSE_IMAGE_FORMAT_R8G8B8A8_INT:
|
||||
case PULSE_IMAGE_FORMAT_R16_INT:
|
||||
case PULSE_IMAGE_FORMAT_R16G16_INT:
|
||||
case PULSE_IMAGE_FORMAT_R16G16B16A16_INT:
|
||||
case PULSE_IMAGE_FORMAT_R32_INT:
|
||||
case PULSE_IMAGE_FORMAT_R32G32_INT:
|
||||
case PULSE_IMAGE_FORMAT_R32G32B32A32_INT: return 1;
|
||||
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int32_t WebGPUGetImageBlockHeight(PulseImageFormat format)
|
||||
{
|
||||
switch(format)
|
||||
{
|
||||
case PULSE_IMAGE_FORMAT_BC1_RGBA_UNORM:
|
||||
case PULSE_IMAGE_FORMAT_BC2_RGBA_UNORM:
|
||||
case PULSE_IMAGE_FORMAT_BC3_RGBA_UNORM:
|
||||
case PULSE_IMAGE_FORMAT_BC4_R_UNORM:
|
||||
case PULSE_IMAGE_FORMAT_BC5_RG_UNORM:
|
||||
case PULSE_IMAGE_FORMAT_BC7_RGBA_UNORM:
|
||||
case PULSE_IMAGE_FORMAT_BC6H_RGB_FLOAT:
|
||||
case PULSE_IMAGE_FORMAT_BC6H_RGB_UFLOAT: return 4;
|
||||
|
||||
case PULSE_IMAGE_FORMAT_R8G8B8A8_UNORM:
|
||||
case PULSE_IMAGE_FORMAT_B8G8R8A8_UNORM:
|
||||
case PULSE_IMAGE_FORMAT_B5G6R5_UNORM:
|
||||
case PULSE_IMAGE_FORMAT_B5G5R5A1_UNORM:
|
||||
case PULSE_IMAGE_FORMAT_B4G4R4A4_UNORM:
|
||||
case PULSE_IMAGE_FORMAT_R10G10B10A2_UNORM:
|
||||
case PULSE_IMAGE_FORMAT_R8G8_UNORM:
|
||||
case PULSE_IMAGE_FORMAT_R16G16_UNORM:
|
||||
case PULSE_IMAGE_FORMAT_R16G16B16A16_UNORM:
|
||||
case PULSE_IMAGE_FORMAT_R8_UNORM:
|
||||
case PULSE_IMAGE_FORMAT_R16_UNORM:
|
||||
case PULSE_IMAGE_FORMAT_A8_UNORM:
|
||||
case PULSE_IMAGE_FORMAT_R8_SNORM:
|
||||
case PULSE_IMAGE_FORMAT_R8G8_SNORM:
|
||||
case PULSE_IMAGE_FORMAT_R8G8B8A8_SNORM:
|
||||
case PULSE_IMAGE_FORMAT_R16_SNORM:
|
||||
case PULSE_IMAGE_FORMAT_R16G16_SNORM:
|
||||
case PULSE_IMAGE_FORMAT_R16G16B16A16_SNORM:
|
||||
case PULSE_IMAGE_FORMAT_R16_FLOAT:
|
||||
case PULSE_IMAGE_FORMAT_R16G16_FLOAT:
|
||||
case PULSE_IMAGE_FORMAT_R16G16B16A16_FLOAT:
|
||||
case PULSE_IMAGE_FORMAT_R32_FLOAT:
|
||||
case PULSE_IMAGE_FORMAT_R32G32_FLOAT:
|
||||
case PULSE_IMAGE_FORMAT_R32G32B32A32_FLOAT:
|
||||
case PULSE_IMAGE_FORMAT_R11G11B10_UFLOAT:
|
||||
case PULSE_IMAGE_FORMAT_R8_UINT:
|
||||
case PULSE_IMAGE_FORMAT_R8G8_UINT:
|
||||
case PULSE_IMAGE_FORMAT_R8G8B8A8_UINT:
|
||||
case PULSE_IMAGE_FORMAT_R16_UINT:
|
||||
case PULSE_IMAGE_FORMAT_R16G16_UINT:
|
||||
case PULSE_IMAGE_FORMAT_R16G16B16A16_UINT:
|
||||
case PULSE_IMAGE_FORMAT_R32_UINT:
|
||||
case PULSE_IMAGE_FORMAT_R32G32_UINT:
|
||||
case PULSE_IMAGE_FORMAT_R32G32B32A32_UINT:
|
||||
case PULSE_IMAGE_FORMAT_R8_INT:
|
||||
case PULSE_IMAGE_FORMAT_R8G8_INT:
|
||||
case PULSE_IMAGE_FORMAT_R8G8B8A8_INT:
|
||||
case PULSE_IMAGE_FORMAT_R16_INT:
|
||||
case PULSE_IMAGE_FORMAT_R16G16_INT:
|
||||
case PULSE_IMAGE_FORMAT_R16G16B16A16_INT:
|
||||
case PULSE_IMAGE_FORMAT_R32_INT:
|
||||
case PULSE_IMAGE_FORMAT_R32G32_INT:
|
||||
case PULSE_IMAGE_FORMAT_R32G32B32A32_INT: return 1;
|
||||
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t WebGPUImageFormatTexelBlockSize(PulseImageFormat format)
|
||||
{
|
||||
switch(format)
|
||||
{
|
||||
case PULSE_IMAGE_FORMAT_BC1_RGBA_UNORM:
|
||||
case PULSE_IMAGE_FORMAT_BC4_R_UNORM: return 8;
|
||||
|
||||
case PULSE_IMAGE_FORMAT_BC2_RGBA_UNORM:
|
||||
case PULSE_IMAGE_FORMAT_BC3_RGBA_UNORM:
|
||||
case PULSE_IMAGE_FORMAT_BC5_RG_UNORM:
|
||||
case PULSE_IMAGE_FORMAT_BC7_RGBA_UNORM:
|
||||
case PULSE_IMAGE_FORMAT_BC6H_RGB_FLOAT:
|
||||
case PULSE_IMAGE_FORMAT_BC6H_RGB_UFLOAT: return 16;
|
||||
|
||||
case PULSE_IMAGE_FORMAT_R8_UNORM:
|
||||
case PULSE_IMAGE_FORMAT_R8_SNORM:
|
||||
case PULSE_IMAGE_FORMAT_A8_UNORM:
|
||||
case PULSE_IMAGE_FORMAT_R8_UINT:
|
||||
case PULSE_IMAGE_FORMAT_R8_INT: return 1;
|
||||
|
||||
case PULSE_IMAGE_FORMAT_B5G6R5_UNORM:
|
||||
case PULSE_IMAGE_FORMAT_B4G4R4A4_UNORM:
|
||||
case PULSE_IMAGE_FORMAT_B5G5R5A1_UNORM:
|
||||
case PULSE_IMAGE_FORMAT_R16_FLOAT:
|
||||
case PULSE_IMAGE_FORMAT_R8G8_SNORM:
|
||||
case PULSE_IMAGE_FORMAT_R8G8_UNORM:
|
||||
case PULSE_IMAGE_FORMAT_R8G8_UINT:
|
||||
case PULSE_IMAGE_FORMAT_R8G8_INT:
|
||||
case PULSE_IMAGE_FORMAT_R16_UNORM:
|
||||
case PULSE_IMAGE_FORMAT_R16_SNORM:
|
||||
case PULSE_IMAGE_FORMAT_R16_UINT:
|
||||
case PULSE_IMAGE_FORMAT_R16_INT: return 2;
|
||||
|
||||
case PULSE_IMAGE_FORMAT_R8G8B8A8_UNORM:
|
||||
case PULSE_IMAGE_FORMAT_B8G8R8A8_UNORM:
|
||||
case PULSE_IMAGE_FORMAT_R32_FLOAT:
|
||||
case PULSE_IMAGE_FORMAT_R16G16_FLOAT:
|
||||
case PULSE_IMAGE_FORMAT_R11G11B10_UFLOAT:
|
||||
case PULSE_IMAGE_FORMAT_R8G8B8A8_SNORM:
|
||||
case PULSE_IMAGE_FORMAT_R10G10B10A2_UNORM:
|
||||
case PULSE_IMAGE_FORMAT_R8G8B8A8_UINT:
|
||||
case PULSE_IMAGE_FORMAT_R8G8B8A8_INT:
|
||||
case PULSE_IMAGE_FORMAT_R16G16_UINT:
|
||||
case PULSE_IMAGE_FORMAT_R16G16_INT:
|
||||
case PULSE_IMAGE_FORMAT_R16G16_UNORM:
|
||||
case PULSE_IMAGE_FORMAT_R16G16_SNORM:
|
||||
case PULSE_IMAGE_FORMAT_R32_UINT:
|
||||
case PULSE_IMAGE_FORMAT_R32_INT: return 4;
|
||||
|
||||
case PULSE_IMAGE_FORMAT_R16G16B16A16_FLOAT:
|
||||
case PULSE_IMAGE_FORMAT_R16G16B16A16_UNORM:
|
||||
case PULSE_IMAGE_FORMAT_R16G16B16A16_SNORM:
|
||||
case PULSE_IMAGE_FORMAT_R16G16B16A16_UINT:
|
||||
case PULSE_IMAGE_FORMAT_R16G16B16A16_INT:
|
||||
case PULSE_IMAGE_FORMAT_R32G32_FLOAT:
|
||||
case PULSE_IMAGE_FORMAT_R32G32_UINT:
|
||||
case PULSE_IMAGE_FORMAT_R32G32_INT: return 8;
|
||||
|
||||
case PULSE_IMAGE_FORMAT_R32G32B32A32_FLOAT:
|
||||
case PULSE_IMAGE_FORMAT_R32G32B32A32_INT:
|
||||
case PULSE_IMAGE_FORMAT_R32G32B32A32_UINT: return 16;
|
||||
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t WebGPUBytesPerRow(int32_t width, PulseImageFormat format)
|
||||
{
|
||||
uint32_t block_width = WebGPUGetImageBlockWidth(format);
|
||||
if(block_width == 0)
|
||||
return 0;
|
||||
uint32_t blocks_per_row = (width + block_width - 1) / block_width;
|
||||
return blocks_per_row * WebGPUImageFormatTexelBlockSize(format);
|
||||
}
|
||||
|
||||
@@ -9,6 +9,10 @@
|
||||
#ifndef PULSE_WEBGPU_H_
|
||||
#define PULSE_WEBGPU_H_
|
||||
|
||||
#ifdef __STDC_NO_ATOMICS__
|
||||
#error "Atomic support is not present"
|
||||
#endif
|
||||
|
||||
#include <webgpu/webgpu.h>
|
||||
|
||||
#define WEBGPU_RETRIEVE_DRIVER_DATA_AS(handle, cast) ((cast)handle->driver_data)
|
||||
@@ -21,6 +25,11 @@ typedef struct WebGPUDriverData
|
||||
PulseBackendFlags WebGPUCheckSupport(PulseBackendFlags candidates, PulseShaderFormatsFlags shader_formats_used); // Return PULSE_BACKEND_WEBGPU in case of success and PULSE_BACKEND_INVALID otherwise
|
||||
void WebGPUDeviceTick(PulseDevice device);
|
||||
|
||||
uint32_t WebGPUBytesPerRow(int32_t width, PulseImageFormat format);
|
||||
uint32_t WebGPUImageFormatTexelBlockSize(PulseImageFormat format);
|
||||
int32_t WebGPUGetImageBlockHeight(PulseImageFormat format);
|
||||
int32_t WebGPUGetImageBlockWidth(PulseImageFormat format);
|
||||
|
||||
#endif // PULSE_WEBGPU_H_
|
||||
|
||||
#endif // PULSE_ENABLE_WEBGPU_BACKEND
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "WebGPU.h"
|
||||
#include "WebGPUDevice.h"
|
||||
#include "WebGPUBuffer.h"
|
||||
#include "WebGPUImage.h"
|
||||
#include "WebGPUCommandList.h"
|
||||
|
||||
PulseBuffer WebGPUCreateBuffer(PulseDevice device, const PulseBufferCreateInfo* create_infos)
|
||||
@@ -156,6 +157,52 @@ bool WebGPUCopyBufferToBuffer(PulseCommandList cmd, const PulseBufferRegion* src
|
||||
|
||||
bool WebGPUCopyBufferToImage(PulseCommandList cmd, const PulseBufferRegion* src, const PulseImageRegion* dst)
|
||||
{
|
||||
WebGPUDevice* webgpu_device = WEBGPU_RETRIEVE_DRIVER_DATA_AS(cmd->device, WebGPUDevice*);
|
||||
WebGPUBuffer* webgpu_src_buffer = WEBGPU_RETRIEVE_DRIVER_DATA_AS(src->buffer, WebGPUBuffer*);
|
||||
WebGPUImage* webgpu_dst_image = WEBGPU_RETRIEVE_DRIVER_DATA_AS(dst->image, WebGPUImage*);
|
||||
WebGPUCommandList* webgpu_cmd = WEBGPU_RETRIEVE_DRIVER_DATA_AS(cmd, WebGPUCommandList*);
|
||||
|
||||
PulseImageFormat format = dst->image->format;
|
||||
uint32_t block_height = WebGPUGetImageBlockHeight(format) > 1 ? WebGPUGetImageBlockHeight(format) : 1;
|
||||
uint32_t blocks_per_column = (dst->image->height + block_height - 1) / block_height;
|
||||
uint32_t bytes_per_row = WebGPUBytesPerRow(dst->image->width, dst->image->format);
|
||||
|
||||
if(bytes_per_row == 0)
|
||||
{
|
||||
if(PULSE_IS_BACKEND_LOW_LEVEL_DEBUG(cmd->device->backend))
|
||||
PulseLogError(cmd->device->backend, "(WebGPU) unsupported image format");
|
||||
PulseSetInternalError(PULSE_ERROR_INVALID_IMAGE_FORMAT);
|
||||
return false;
|
||||
}
|
||||
|
||||
WGPUTexelCopyBufferLayout layout = { 0 };
|
||||
layout.bytesPerRow = bytes_per_row;
|
||||
layout.rowsPerImage = blocks_per_column;
|
||||
|
||||
WGPUTexelCopyTextureInfo texture_copy_info = { 0 };
|
||||
texture_copy_info.texture = webgpu_dst_image->texture;
|
||||
texture_copy_info.mipLevel = 1;
|
||||
texture_copy_info.aspect = WGPUTextureAspect_All;
|
||||
texture_copy_info.origin.x = dst->x;
|
||||
texture_copy_info.origin.y = dst->y;
|
||||
texture_copy_info.origin.z = dst->z;
|
||||
|
||||
WGPUExtent3D extent = { 0 };
|
||||
extent.width = dst->width;
|
||||
extent.height = dst->height;
|
||||
extent.depthOrArrayLayers = dst->depth;
|
||||
|
||||
if(bytes_per_row >= 256 && bytes_per_row % 256 == 0)
|
||||
{
|
||||
WGPUTexelCopyBufferInfo buffer_copy_info = { 0 };
|
||||
buffer_copy_info.buffer = webgpu_src_buffer->buffer;
|
||||
buffer_copy_info.layout = layout;
|
||||
wgpuCommandEncoderCopyBufferToTexture(webgpu_cmd->encoder, &buffer_copy_info, &texture_copy_info, &extent);
|
||||
}
|
||||
else
|
||||
wgpuQueueWriteTexture(webgpu_device->queue, &texture_copy_info, webgpu_src_buffer->buffer, src->size, &layout, &extent);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void WebGPUDestroyBuffer(PulseDevice device, PulseBuffer buffer)
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include "../../PulseInternal.h"
|
||||
#include "WebGPU.h"
|
||||
#include "WebGPUDevice.h"
|
||||
#include "WebGPUImage.h"
|
||||
#include "WebGPUComputePass.h"
|
||||
#include "WebGPUComputePipeline.h"
|
||||
|
||||
@@ -151,9 +152,12 @@ static void WebGPUBindBindGroups(PulseComputePass pass)
|
||||
uint32_t entry_index = 0;
|
||||
for(uint32_t i = 0; i < pass->current_pipeline->num_readonly_storage_images; i++, entry_index++)
|
||||
{
|
||||
WebGPUImage* webgpu_image = WEBGPU_RETRIEVE_DRIVER_DATA_AS(pass->readonly_images[i], WebGPUImage*);
|
||||
|
||||
WGPUBindGroupEntry* entry = &read_only_entries[entry_index];
|
||||
memset(entry, 0, sizeof(WGPUBindGroupEntry));
|
||||
entry->binding = i;
|
||||
entry->textureView = webgpu_image->view;
|
||||
}
|
||||
|
||||
for(uint32_t i = 0; i < pass->current_pipeline->num_readonly_storage_buffers; i++, entry_index++)
|
||||
@@ -180,9 +184,12 @@ static void WebGPUBindBindGroups(PulseComputePass pass)
|
||||
uint32_t entry_index = 0;
|
||||
for(uint32_t i = 0; i < pass->current_pipeline->num_readwrite_storage_images; i++, entry_index++)
|
||||
{
|
||||
WebGPUImage* webgpu_image = WEBGPU_RETRIEVE_DRIVER_DATA_AS(pass->readwrite_images[i], WebGPUImage*);
|
||||
|
||||
WGPUBindGroupEntry* entry = &read_write_entries[entry_index];
|
||||
memset(entry, 0, sizeof(WGPUBindGroupEntry));
|
||||
entry->binding = i;
|
||||
entry->textureView = webgpu_image->view;
|
||||
}
|
||||
|
||||
for(uint32_t i = 0; i < pass->current_pipeline->num_readwrite_storage_buffers; i++, entry_index++)
|
||||
|
||||
@@ -38,9 +38,9 @@
|
||||
static uint64_t WebGPUScoreAdapter(WGPUAdapter adapter)
|
||||
{
|
||||
uint64_t score = 0;
|
||||
WGPUAdapterInfo infos;
|
||||
WGPUAdapterInfo infos = { 0 };
|
||||
wgpuAdapterGetInfo(adapter, &infos);
|
||||
WGPULimits limits;
|
||||
WGPULimits limits = { 0 };
|
||||
wgpuAdapterGetLimits(adapter, &limits);
|
||||
|
||||
if(infos.adapterType == WGPUAdapterType_DiscreteGPU)
|
||||
@@ -106,7 +106,7 @@ static void WebGPUDeviceLostCallback(const WGPUDevice* _, WGPUDeviceLostReason r
|
||||
"creation failed",
|
||||
};
|
||||
if(PULSE_IS_BACKEND_LOW_LEVEL_DEBUG(backend))
|
||||
PulseLogErrorFmt(backend, "(WebGPU) device %.*s lost because %s. %.*s", device->infos.device.length, device->infos.device.data, reasons[reason], message.length, message.data);
|
||||
PulseLogErrorFmt(backend, "(WebGPU) device %.*s lost because %s. %.*s", device->infos.device.length, device->infos.device.data, reasons[reason - 1], message.length, message.data);
|
||||
}
|
||||
|
||||
static void WebGPUDeviceUncapturedErrorCallback(const WGPUDevice* _, WGPUErrorType type, WGPUStringView message, void* userdata1, void* userdata2)
|
||||
@@ -121,7 +121,7 @@ static void WebGPUDeviceUncapturedErrorCallback(const WGPUDevice* _, WGPUErrorTy
|
||||
"has recieved an unknown error",
|
||||
};
|
||||
if(PULSE_IS_BACKEND_LOW_LEVEL_DEBUG(backend))
|
||||
PulseLogErrorFmt(backend, "(WebGPU) device %.*s %s. %.*s", device->infos.device.length, device->infos.device.data, types[type], message.length, message.data);
|
||||
PulseLogErrorFmt(backend, "(WebGPU) device %.*s %s. %.*s", device->infos.device.length, device->infos.device.data, types[type - 1], message.length, message.data);
|
||||
}
|
||||
|
||||
PulseDevice WebGPUCreateDevice(PulseBackend backend, PulseDevice* forbiden_devices, uint32_t forbiden_devices_count)
|
||||
|
||||
@@ -74,6 +74,15 @@ static WGPUTextureDimension PulseImageTypeToWGPUTextureDimension[] = {
|
||||
};
|
||||
PULSE_STATIC_ASSERT(PulseImageTypeToWGPUTextureDimension, (sizeof(PulseImageTypeToWGPUTextureDimension) / sizeof(WGPUTextureDimension)) == PULSE_IMAGE_TYPE_MAX_ENUM);
|
||||
|
||||
static WGPUTextureViewDimension PulseImageTypeToWGPUTextureViewDimension[] = {
|
||||
WGPUTextureViewDimension_2D, //PULSE_IMAGE_TYPE_2D
|
||||
WGPUTextureViewDimension_2DArray, //PULSE_IMAGE_TYPE_2D_ARRAY
|
||||
WGPUTextureViewDimension_3D, //PULSE_IMAGE_TYPE_3D
|
||||
WGPUTextureViewDimension_Cube, //PULSE_IMAGE_TYPE_CUBE
|
||||
WGPUTextureViewDimension_CubeArray, //PULSE_IMAGE_TYPE_CUBE_ARRAY
|
||||
};
|
||||
PULSE_STATIC_ASSERT(PulseImageTypeToWGPUTextureViewDimension, (sizeof(PulseImageTypeToWGPUTextureViewDimension) / sizeof(WGPUTextureViewDimension)) == PULSE_IMAGE_TYPE_MAX_ENUM);
|
||||
|
||||
PulseImage WebGPUCreateImage(PulseDevice device, const PulseImageCreateInfo* create_infos)
|
||||
{
|
||||
WebGPUDevice* webgpu_device = WEBGPU_RETRIEVE_DRIVER_DATA_AS(device, WebGPUDevice*);
|
||||
@@ -121,6 +130,24 @@ PulseImage WebGPUCreateImage(PulseDevice device, const PulseImageCreateInfo* cre
|
||||
webgpu_image->texture = wgpuDeviceCreateTexture(webgpu_device->device, &descriptor);
|
||||
if(webgpu_image->texture == PULSE_NULLPTR)
|
||||
{
|
||||
PulseSetInternalError(PULSE_ERROR_INVALID_IMAGE_FORMAT);
|
||||
free(webgpu_image);
|
||||
free(image);
|
||||
return PULSE_NULL_HANDLE;
|
||||
}
|
||||
|
||||
WGPUTextureViewDescriptor view_descriptor = { 0 };
|
||||
view_descriptor.format = descriptor.format;
|
||||
view_descriptor.dimension = PulseImageTypeToWGPUTextureViewDimension[create_infos->type];
|
||||
view_descriptor.baseMipLevel = 0;
|
||||
view_descriptor.mipLevelCount = 1;
|
||||
view_descriptor.baseArrayLayer = 0;
|
||||
view_descriptor.arrayLayerCount = view_descriptor.dimension == WGPUTextureViewDimension_3D ? 1 : create_infos->layer_count_or_depth;
|
||||
webgpu_image->view = wgpuTextureCreateView(webgpu_image->texture, &view_descriptor);
|
||||
if(webgpu_image->texture == PULSE_NULLPTR)
|
||||
{
|
||||
PulseSetInternalError(PULSE_ERROR_INVALID_IMAGE_FORMAT);
|
||||
wgpuTextureRelease(webgpu_image->texture);
|
||||
free(webgpu_image);
|
||||
free(image);
|
||||
return PULSE_NULL_HANDLE;
|
||||
@@ -173,6 +200,47 @@ bool WebGPUIsImageFormatValid(PulseDevice device, PulseImageFormat format, Pulse
|
||||
|
||||
bool WebGPUCopyImageToBuffer(PulseCommandList cmd, const PulseImageRegion* src, const PulseBufferRegion* dst)
|
||||
{
|
||||
WebGPUImage* webgpu_src_image = WEBGPU_RETRIEVE_DRIVER_DATA_AS(src->image, WebGPUImage*);
|
||||
WebGPUBuffer* webgpu_dst_buffer = WEBGPU_RETRIEVE_DRIVER_DATA_AS(dst->buffer, WebGPUBuffer*);
|
||||
WebGPUCommandList* webgpu_cmd = WEBGPU_RETRIEVE_DRIVER_DATA_AS(cmd, WebGPUCommandList*);
|
||||
|
||||
PulseImageFormat format = src->image->format;
|
||||
uint32_t block_height = WebGPUGetImageBlockHeight(format) > 1 ? WebGPUGetImageBlockHeight(format) : 1;
|
||||
uint32_t blocks_per_column = (src->image->height + block_height - 1) / block_height;
|
||||
uint32_t bytes_per_row = WebGPUBytesPerRow(src->image->width, src->image->format);
|
||||
|
||||
if(bytes_per_row == 0)
|
||||
{
|
||||
if(PULSE_IS_BACKEND_LOW_LEVEL_DEBUG(cmd->device->backend))
|
||||
PulseLogError(cmd->device->backend, "(WebGPU) unsupported image format");
|
||||
PulseSetInternalError(PULSE_ERROR_INVALID_IMAGE_FORMAT);
|
||||
return false;
|
||||
}
|
||||
|
||||
WGPUTexelCopyBufferLayout layout = { 0 };
|
||||
layout.bytesPerRow = bytes_per_row;
|
||||
layout.rowsPerImage = blocks_per_column;
|
||||
|
||||
WGPUTexelCopyTextureInfo texture_copy_info = { 0 };
|
||||
texture_copy_info.texture = webgpu_src_image->texture;
|
||||
texture_copy_info.mipLevel = 1;
|
||||
texture_copy_info.aspect = WGPUTextureAspect_All;
|
||||
texture_copy_info.origin.x = src->x;
|
||||
texture_copy_info.origin.y = src->y;
|
||||
texture_copy_info.origin.z = src->z;
|
||||
|
||||
WGPUTexelCopyBufferInfo buffer_copy_info = { 0 };
|
||||
buffer_copy_info.buffer = webgpu_dst_buffer->buffer;
|
||||
buffer_copy_info.layout = layout;
|
||||
|
||||
WGPUExtent3D extent = { 0 };
|
||||
extent.width = src->width;
|
||||
extent.height = src->height;
|
||||
extent.depthOrArrayLayers = src->depth;
|
||||
|
||||
wgpuCommandEncoderCopyTextureToBuffer(webgpu_cmd->encoder, &texture_copy_info, &buffer_copy_info, &extent);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WebGPUBlitImage(PulseCommandList cmd, const PulseImageRegion* src, const PulseImageRegion* dst)
|
||||
@@ -183,6 +251,7 @@ void WebGPUDestroyImage(PulseDevice device, PulseImage image)
|
||||
{
|
||||
PULSE_UNUSED(device);
|
||||
WebGPUImage* webgpu_image = WEBGPU_RETRIEVE_DRIVER_DATA_AS(image, WebGPUImage*);
|
||||
wgpuTextureViewRelease(webgpu_image->view);
|
||||
wgpuTextureRelease(webgpu_image->texture);
|
||||
free(webgpu_image);
|
||||
free(image);
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
typedef struct WebGPUImage
|
||||
{
|
||||
WGPUTexture texture;
|
||||
WGPUTextureView view;
|
||||
} WebGPUImage;
|
||||
|
||||
PulseImage WebGPUCreateImage(PulseDevice device, const PulseImageCreateInfo* create_infos);
|
||||
|
||||
Reference in New Issue
Block a user