128 lines
4.0 KiB
C++
128 lines
4.0 KiB
C++
// Copyright (c) Wojciech Figat. All rights reserved.
|
|
|
|
#if GRAPHICS_API_WEBGPU
|
|
|
|
#include "GPUBufferWebGPU.h"
|
|
#include "RenderToolsWebGPU.h"
|
|
#include "Engine/Core/Log.h"
|
|
|
|
GPUBufferWebGPU::GPUBufferWebGPU(GPUDeviceWebGPU* device, const StringView& name)
|
|
: GPUResourceWebGPU(device, name)
|
|
{
|
|
}
|
|
|
|
GPUBufferView* GPUBufferWebGPU::View() const
|
|
{
|
|
return (GPUBufferView*)&_view;
|
|
}
|
|
|
|
void* GPUBufferWebGPU::Map(GPUResourceMapMode mode)
|
|
{
|
|
ASSERT(!_mapped);
|
|
WGPUMapMode mapMode = 0;
|
|
if (EnumHasAnyFlags(mode, GPUResourceMapMode::Read))
|
|
mapMode |= WGPUMapMode_Read;
|
|
if (EnumHasAnyFlags(mode, GPUResourceMapMode::Write))
|
|
mapMode |= WGPUMapMode_Write;
|
|
AsyncCallbackWebGPU<WGPUBufferMapCallbackInfo> mapRequest(WGPU_BUFFER_MAP_CALLBACK_INFO_INIT);
|
|
mapRequest.Info.callback = [](WGPUMapAsyncStatus status, WGPUStringView message, WGPU_NULLABLE void* userdata1, WGPU_NULLABLE void* userdata2)
|
|
{
|
|
AsyncCallbackDataWebGPU& userData = *reinterpret_cast<AsyncCallbackDataWebGPU*>(userdata1);
|
|
userData.Call(status == WGPUMapAsyncStatus_Success, status, message);
|
|
};
|
|
wgpuBufferMapAsync(Buffer, mapMode, 0, _desc.Size, mapRequest.Info);
|
|
auto mapRequestResult = mapRequest.Wait();
|
|
if (mapRequestResult == WGPUWaitStatus_TimedOut)
|
|
{
|
|
LOG(Error, "WebGPU buffer map request has timed out after {}s", mapRequest.Data.WaitTime);
|
|
return nullptr;
|
|
}
|
|
if (mapRequestResult == WGPUWaitStatus_Error)
|
|
return nullptr;
|
|
_mapped = true;
|
|
if (EnumHasNoneFlags(mode, GPUResourceMapMode::Write))
|
|
return (void*)wgpuBufferGetConstMappedRange(Buffer, 0, _desc.Size);
|
|
return wgpuBufferGetMappedRange(Buffer, 0, _desc.Size);
|
|
}
|
|
|
|
void GPUBufferWebGPU::Unmap()
|
|
{
|
|
ASSERT(_mapped);
|
|
_mapped = false;
|
|
wgpuBufferUnmap(Buffer);
|
|
}
|
|
|
|
bool GPUBufferWebGPU::OnInit()
|
|
{
|
|
// Create buffer
|
|
WGPUBufferDescriptor bufferDesc = WGPU_BUFFER_DESCRIPTOR_INIT;
|
|
#if GPU_ENABLE_RESOURCE_NAMING
|
|
_name.Set(_namePtr, _nameSize);
|
|
bufferDesc.label = { _name.Get(), (size_t)_name.Length() };
|
|
#endif
|
|
if (EnumHasAllFlags(_desc.Flags, GPUBufferFlags::IndexBuffer))
|
|
bufferDesc.usage |= WGPUBufferUsage_Index;
|
|
else if (EnumHasAllFlags(_desc.Flags, GPUBufferFlags::VertexBuffer))
|
|
bufferDesc.usage |= WGPUBufferUsage_Vertex;
|
|
else if (EnumHasAllFlags(_desc.Flags, GPUBufferFlags::Argument))
|
|
bufferDesc.usage |= WGPUBufferUsage_Indirect;
|
|
if (IsUnorderedAccess())
|
|
bufferDesc.usage |= WGPUBufferUsage_Storage;
|
|
switch (_desc.Usage)
|
|
{
|
|
case GPUResourceUsage::Default:
|
|
if (!_desc.InitData)
|
|
bufferDesc.usage |= WGPUBufferUsage_CopyDst;
|
|
break;
|
|
case GPUResourceUsage::Dynamic:
|
|
bufferDesc.usage |= WGPUBufferUsage_MapWrite;
|
|
break;
|
|
case GPUResourceUsage::StagingUpload:
|
|
bufferDesc.usage |= WGPUBufferUsage_MapWrite | WGPUBufferUsage_CopySrc;
|
|
break;
|
|
case GPUResourceUsage::StagingReadback:
|
|
bufferDesc.usage |= WGPUBufferUsage_MapRead;
|
|
break;
|
|
case GPUResourceUsage::Staging:
|
|
bufferDesc.usage |= WGPUBufferUsage_MapRead | WGPUBufferUsage_MapWrite | WGPUBufferUsage_CopySrc;
|
|
break;
|
|
}
|
|
bufferDesc.size = _desc.Size;
|
|
bufferDesc.mappedAtCreation = _desc.InitData != nullptr;
|
|
Buffer = wgpuDeviceCreateBuffer(_device->Device, &bufferDesc);
|
|
if (!Buffer)
|
|
return true;
|
|
_memoryUsage = _desc.Size;
|
|
|
|
// Initialize with a data if provided
|
|
if (_desc.InitData)
|
|
{
|
|
//wgpuBufferWriteMappedRange(Buffer, 0, _desc.InitData, _desc.Size);
|
|
Platform::MemoryCopy(wgpuBufferGetMappedRange(Buffer, 0, _desc.Size), _desc.InitData, _desc.Size);
|
|
wgpuBufferUnmap(Buffer);
|
|
}
|
|
|
|
// Create view
|
|
_view.Set(this, Buffer);
|
|
|
|
return false;
|
|
}
|
|
|
|
void GPUBufferWebGPU::OnReleaseGPU()
|
|
{
|
|
if (Buffer)
|
|
{
|
|
wgpuBufferDestroy(Buffer);
|
|
wgpuBufferRelease(Buffer);
|
|
Buffer = nullptr;
|
|
}
|
|
#if GPU_ENABLE_RESOURCE_NAMING
|
|
_name.Clear();
|
|
#endif
|
|
|
|
// Base
|
|
GPUBuffer::OnReleaseGPU();
|
|
}
|
|
|
|
#endif
|