-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Use the same buffer suballocation strategy in WebGPU as in Vulkan and OpenGL. This means we will reuse buffers to satisfy temporary buffer requests instead of allocating new ones every frame.
- Loading branch information
1 parent
c5744b1
commit 762d43c
Showing
8 changed files
with
187 additions
and
73 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
85 changes: 85 additions & 0 deletions
85
src/Video/LowLevelRenderer/WebGPU/WebGPUBufferAllocator.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
#include "WebGPUBufferAllocator.hpp" | ||
|
||
#include "WebGPUBuffer.hpp" | ||
#include "WebGPURenderer.hpp" | ||
|
||
namespace Video { | ||
|
||
static WGPUBufferUsageFlags GetBufferUsage(Buffer::BufferUsage bufferUsage) { | ||
WGPUBufferUsageFlags usage; | ||
|
||
switch (bufferUsage) { | ||
case Buffer::BufferUsage::VERTEX_BUFFER: | ||
usage = WGPUBufferUsage_Vertex; | ||
break; | ||
case Buffer::BufferUsage::INDEX_BUFFER: | ||
usage = WGPUBufferUsage_Index; | ||
break; | ||
case Buffer::BufferUsage::UNIFORM_BUFFER: | ||
usage = WGPUBufferUsage_Uniform | WGPUBufferUsage_CopyDst; | ||
break; | ||
case Buffer::BufferUsage::STORAGE_BUFFER: | ||
usage = WGPUBufferUsage_Storage | WGPUBufferUsage_CopyDst; | ||
break; | ||
case Buffer::BufferUsage::VERTEX_STORAGE_BUFFER: | ||
usage = WGPUBufferUsage_Vertex | WGPUBufferUsage_Storage | WGPUBufferUsage_CopyDst; | ||
break; | ||
} | ||
|
||
// For wgpuQueueWriteBuffer. | ||
usage |= WGPUBufferUsage_CopyDst; | ||
|
||
return usage; | ||
} | ||
|
||
WebGPURawBuffer::WebGPURawBuffer(WebGPURenderer& webGPURenderer, Buffer::BufferUsage bufferUsage, bool temporary, unsigned int size) { | ||
this->temporary = temporary; | ||
queue = webGPURenderer.GetQueue(); | ||
|
||
// Create buffer. | ||
WGPUBufferDescriptor bufferDescriptor = {}; | ||
bufferDescriptor.usage = GetBufferUsage(bufferUsage); | ||
bufferDescriptor.size = size; | ||
|
||
buffer = wgpuDeviceCreateBuffer(webGPURenderer.GetDevice(), &bufferDescriptor); | ||
} | ||
|
||
WebGPURawBuffer::~WebGPURawBuffer() { | ||
wgpuBufferRelease(buffer); | ||
} | ||
|
||
void WebGPURawBuffer::Write(uint32_t offset, uint32_t size, const void* data) { | ||
/// @todo Could use mapOnCreate for non-temporary buffers? | ||
wgpuQueueWriteBuffer(queue, buffer, offset, data, size); | ||
} | ||
|
||
WGPUBuffer WebGPURawBuffer::GetBuffer() const { | ||
return buffer; | ||
} | ||
|
||
WebGPUBufferAllocator::WebGPUBufferAllocator(WebGPURenderer& webGPURenderer) : BufferAllocator(1), webGPURenderer(webGPURenderer) { | ||
|
||
} | ||
|
||
WebGPUBufferAllocator::~WebGPUBufferAllocator() { | ||
|
||
} | ||
|
||
uint32_t WebGPUBufferAllocator::GetAlignment(Buffer::BufferUsage bufferUsage) { | ||
// Both minUniformBufferOffsetAlignment and minStorageBufferOffsetAlignment are guaranteed to be at most 256. | ||
// https://www.w3.org/TR/webgpu/#dom-gpusupportedlimits-minuniformbufferoffsetalignment | ||
return 256; | ||
} | ||
|
||
RawBuffer* WebGPUBufferAllocator::Allocate(Buffer::BufferUsage bufferUsage, bool temporary, unsigned int size) { | ||
// Buffer binding sizes must be a multiple of 16. | ||
size = (size + 16 - 1) / 16 * 16; | ||
|
||
return new WebGPURawBuffer(webGPURenderer, bufferUsage, temporary, size); | ||
} | ||
|
||
Buffer* WebGPUBufferAllocator::CreateBufferObject(Buffer::BufferUsage bufferUsage, const BufferAllocation& allocation) { | ||
return new WebGPUBuffer(bufferUsage, allocation); | ||
} | ||
|
||
} |
61 changes: 61 additions & 0 deletions
61
src/Video/LowLevelRenderer/WebGPU/WebGPUBufferAllocator.hpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
#pragma once | ||
|
||
#include "../Interface/BufferAllocator.hpp" | ||
#include "WebGPU.hpp" | ||
|
||
namespace Video { | ||
|
||
class WebGPURenderer; | ||
|
||
/// WebGPU implementation of RawBuffer. | ||
class WebGPURawBuffer : public RawBuffer { | ||
public: | ||
/// Create new raw buffer used to satisfy allocations. | ||
/** | ||
* @param webGPURenderer The WebGPU renderer. | ||
* @param bufferUsage How the buffer will be used. | ||
* @param temporary Whether the buffer is going to be used to satisfy temporary allocations. | ||
* @param size The size of the buffer in bytes. | ||
*/ | ||
WebGPURawBuffer(WebGPURenderer& webGPURenderer, Buffer::BufferUsage bufferUsage, bool temporary, unsigned int size); | ||
|
||
/// Destructor. | ||
~WebGPURawBuffer() final; | ||
|
||
void Write(uint32_t offset, uint32_t size, const void* data) final; | ||
|
||
/// Get the internal WebGPU buffer. | ||
/** | ||
* @return The internal WebGPU buffer. | ||
*/ | ||
WGPUBuffer GetBuffer() const; | ||
|
||
private: | ||
WGPUBuffer buffer; | ||
WGPUQueue queue; | ||
bool temporary; | ||
}; | ||
|
||
/// WebGPU implementation of BufferAllocator. | ||
class WebGPUBufferAllocator : public BufferAllocator { | ||
public: | ||
/// Create a new buffer allocator. | ||
/** | ||
* @param webGPURenderer The WebGPU renderer. | ||
*/ | ||
explicit WebGPUBufferAllocator(WebGPURenderer& webGPURenderer); | ||
|
||
/// Destructor. | ||
~WebGPUBufferAllocator() final; | ||
|
||
private: | ||
WebGPUBufferAllocator(const WebGPUBufferAllocator& other) = delete; | ||
|
||
uint32_t GetAlignment(Buffer::BufferUsage bufferUsage) final; | ||
RawBuffer* Allocate(Buffer::BufferUsage bufferUsage, bool temporary, unsigned int size) final; | ||
Buffer* CreateBufferObject(Buffer::BufferUsage bufferUsage, const BufferAllocation& allocation) final; | ||
|
||
WebGPURenderer& webGPURenderer; | ||
}; | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.