This commit is contained in:
2025-03-17 22:41:04 +01:00
parent cbcc1b7e25
commit b70317d85d
37 changed files with 698 additions and 229 deletions

View File

@@ -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);