1#include "BuffersWebGPU.h"
3#include "FormatsWebGPU.h"
4#include "GraphicsDeviceWebGPU.h"
6#include "Foundation/Logging/Logger.h"
14 void BufferWebGPU::CreateInstance(GraphicsDeviceWebGPU *graphicsDevice)
16 WGPUBufferDescriptor desc = {};
19 desc.usage |= WGPUBufferUsage_MapRead;
20 desc.usage |= WGPUBufferUsage_CopyDst;
23 desc.usage |= WGPUBufferUsage_CopyDst;
27 desc.usage |= WGPUBufferUsage_Vertex;
29 desc.usage |= WGPUBufferUsage_Index;
31 desc.usage |= WGPUBufferUsage_Uniform;
33 desc.usage |= WGPUBufferUsage_Storage;
35 desc.usage |= WGPUBufferUsage_Storage;
37 desc.usage |= WGPUBufferUsage_Storage;
39 desc.usage |= WGPUBufferUsage_Storage;
42 desc.mappedAtCreation =
false;
44 buffer = wgpuDeviceCreateBuffer(graphicsDevice->device, &desc);
46 alias.push_back(buffer);
49 void BufferWebGPU::NextInstance(GraphicsDeviceWebGPU *graphicsDevice)
51 uint32_t idx = alias_idx;
53 if(idx >= alias.size()){
54 CreateInstance(graphicsDevice);
55 assert(idx+1 == alias.size());
61 void BufferWebGPU::ResetInstance()
67 void BuffersWebGPU::initialize(GraphicsDeviceWebGPU *device)
69 graphicsDevice = device;
71 void BuffersWebGPU::resetInstances()
73 for(BufferWebGPU &buffer : buffers){
74 buffer.ResetInstance();
80 const uint32_t stride = getSize(vertexFormat);
81 const size_t size = count * stride;
88 return loadVertexBuffer(vertexData, count, *VertexFormats::getVertexFormat(vertexFormatHandle));
93 buffers.removeResource(handle);
98 const size_t size = count * indexSize;
105 buffers.removeResource(handle);
110 size_t attribute_count = 0;
111 for(
size_t i=0; i<count; i++){
112 const VertexFormat *vtx_format = getVertexFormat(vertexFormats[i]);
113 for(
size_t j=0; j<vtx_format->
elements.size(); j++){
115 if(element.
format == DataFormat::MAT4X4_FLOAT){
116 attribute_count += 4;
119 attribute_count += 1;
125 input_layout.vertex_attributes.resize(attribute_count);
126 input_layout.vertex_buffer_layout.resize(count);
128 size_t attribute_offset = 0;
129 for(
size_t i=0; i<count; i++){
130 const VertexFormat *vtx_format = getVertexFormat(vertexFormats[i]);
131 WGPUVertexBufferLayout &vtx_layout = input_layout.vertex_buffer_layout[i];
132 vtx_layout.arrayStride = getSize(*vtx_format);
134 vtx_layout.stepMode = WGPUVertexStepMode_Vertex;
137 vtx_layout.stepMode = WGPUVertexStepMode_Instance;
143 vtx_layout.attributeCount = 0;
144 vtx_layout.attributes = vtx_format->
elements.size() ? &input_layout.vertex_attributes[attribute_offset] :
nullptr;
145 for(
size_t j=0; j<vtx_format->
elements.size(); j++){
147 if(vtx_layout.stepMode == WGPUVertexStepMode_Vertex){
151 else if(vtx_layout.stepMode == WGPUVertexStepMode_Instance){
158 EffectWebGPU& effect = graphicsDevice->effects.effects[effectHandle];
160 uint32_t attribute_location = std::numeric_limits<uint32_t>::max();
162 semantic.format = WGPUVertexFormat_Undefined;
163 for (
size_t s = 0; s < effect.num_attribs; s++) {
166 attribute_location = sem.binding;
171 if (attribute_location == std::numeric_limits<uint32_t>::max()) {
172 LOG_WARNING(logger,
"Vertex attribute semantic %d, slot %d not used in shader", (
int)element.
semantic, element.
semanticIndex);
174 if(element.
format == DataFormat::MAT4X4_FLOAT){
175 for(
int k=0; k<4; k++){
176 WGPUVertexAttribute &att = input_layout.vertex_attributes[attribute_offset++];
177 att.format = WGPUVertexFormat_Float32x4;
178 att.offset = element.
offset +
sizeof(float)*4*k;
179 att.shaderLocation = attribute_location+k;
180 vtx_layout.attributeCount++;
184 WGPUVertexAttribute &att = input_layout.vertex_attributes[attribute_offset++];
185 att.format = VertexFormatsWebGPU[(size_t)element.
format];
186 if (semantic.format != VertexFormatsWebGPU[(
size_t)element.
format]) {
187 LOG_WARNING(logger,
"Inconsisten vertex attribute format");
189 assert(att.format != WGPUVertexFormat_Undefined);
190 att.offset = element.
offset;
191 att.shaderLocation = attribute_location;
192 vtx_layout.attributeCount++;
196 assert(attribute_offset == input_layout.vertex_attributes.size());
197 return inputLayouts.addResource(std::move(input_layout));
202 inputLayouts.removeResource(inputLayoutHandle);
212 buffer.accessMode = accessMode;
213 buffer.bindFlags = bindFlags;
216 buffer.is_read_buffer =
true;
217 assert(bindFlags == 0);
219 size_t granularity = 256;
220 if(buffer.size%granularity != 0)
221 buffer.size += granularity-buffer.size%granularity;
225 size_t granularity = 16;
226 if (buffer.size % granularity != 0)
227 buffer.size += granularity - buffer.size % granularity;
230 buffer.CreateInstance(graphicsDevice);
232 wgpuQueueWriteBuffer(graphicsDevice->queue, buffer.buffer, 0, data, buffer.size);
235 return this->buffers.addResource(std::move(buffer));
240 if(!buffers[handle].is_read_buffer){
241 wgpuBufferRelease(buffers[handle].buffer);
244 for(WGPUBuffer &buffer: buffers[handle].alias){
245 wgpuBufferRelease(buffer);
248 buffers.removeResource(handle);
253 return static_cast<void*
>(buffers[handle].buffer);
virtual IndexBufferHandle loadIndexBuffer(const void *, const size_t, const size_t) override
Loads a new index buffer and populates it with the given indexData.
virtual VertexBufferHandle loadVertexBuffer(const void *, const size_t, const VertexFormat &vertexFormat) override
Loads a new vertex buffer and populates it with the given data.
virtual void releaseVertexBuffer(VertexBufferHandle vertexBufferHandle) override
Release the vertex buffer with the given handle.
virtual InputLayoutHandle loadInputLayout(const VertexFormatHandle *vertexFormats, const size_t count, EffectHandle effectHandle) override
Loads a new input layout to map vertex flow between vertex buffers with the given vertexFormats to ef...
virtual BufferHandle loadBuffer(const void *, const size_t, Usage::EUsage, uint32_t, uint32_t, uint32_t=0) override
Loads a new buffer using the given data to populate the buffer.
virtual void * getNativeHandle(BufferHandle bufferHandle) override
Get the device-specific handle (D3D buffer pointer, OpenGL buffer ID etc) associated with the given b...
virtual void releaseBuffer(BufferHandle bufferHandle) override
Releases the buffer with the given bufferHandle.
virtual void releaseInputLayout(InputLayoutHandle inputLayoutHandle) override
Releases the input layout with the given inputLayoutHandle.
virtual void releaseIndexBuffer(IndexBufferHandle indexBufferHandle) override
Releases the index buffer with the given handle.
Log implementation class.
constexpr Log getLogger(const char(&name)[LEN]) noexcept
Contains all Cogs related functionality.
@ InstanceData
Per instance data.
@ VertexData
Per vertex data.
@ Read
The buffer can be mapped and read from by the CPU after creation.
@ None
The buffer can not be either read from or written to by the CPU after creation.
@ ConstantBuffer
The buffer can be bound as input to effects as a constant buffer.
@ StructuredBufferWithCounter
The buffer can be bound as a structured buffer and read or written from shaders, with an additional a...
@ StreamOutBuffer
The buffer can be bound as stream output to receive transform feedback results.
@ VertexBuffer
The buffer can be bound as input to the vertex shader stage as a vertex buffer.
@ RawBuffer
The buffer can be bound as a byte address buffer and read or written from shaders.
@ IndexBuffer
The buffer can be bound as input to the vertex shader stage as an index buffer.
@ ShaderResource
The buffer can be bound as a shader resource and read from shaders.
@ StructuredBuffer
The buffer can be bound as a structured buffer and read or written from shaders.
@ Dynamic
Buffer will be loaded and modified with some frequency.
Vertex element structure used to describe a single data element in a vertex for the input assembler.
InputType inputType
Input type of the element, vertex or instance data.
DataFormat format
Format of the element.
uint16_t offset
Offset in bytes from the vertex position in memory.
uint16_t semanticIndex
Index for the semantic mapping.
ElementSemantic semantic
Semantic mapping of the element (position, normal, etc...).
uint16_t instanceStep
Instance step factor.