1#include "BuffersGL20.h"
9 GLuint createBuffer(GLenum target,
const void * data,
size_t size,
const GLenum usage = GL_STATIC_DRAW)
13 glGenBuffers(1, &bufferId);
14 glBindBuffer(target, bufferId);
15 glBufferData(target,
static_cast<GLsizeiptr
>(size), data, usage);
23 auto format = getVertexFormat(vertexFormat);
24 const size_t size = count * format->size;
26 GLuint bufferId = createBuffer(GL_ARRAY_BUFFER, vertexData, size);
34 std::vector<uint8_t>(),
38 bufferMemoryConsumption += buffer.size;
39 return this->buffers.addResource(std::move(buffer));
44 return loadVertexBuffer(vertexData, count, createVertexFormat(vertexFormat.
elements.data(), vertexFormat.
elements.size()));
49 this->releaseBuffer(vertexBufferHandle);
54 assert(indexSize ==
sizeof(GLuint) || indexSize ==
sizeof(GLushort));
56 GLuint bufferId = createBuffer(GL_ELEMENT_ARRAY_BUFFER, indexData, count * indexSize);
58 BufferGL20 buffer = { bufferId, GL_INVALID_INDEX, count * indexSize, count, GL_ELEMENT_ARRAY_BUFFER, {}, std::vector<uint8_t>(),
MapMode::Read };
59 buffer.indexSize = (indexSize ==
sizeof(GLuint)) ? GL_UNSIGNED_INT : GL_UNSIGNED_SHORT;
61 bufferMemoryConsumption += buffer.size;
62 return this->buffers.addResource(std::move(buffer));
67 this->releaseBuffer(indexBufferHandle);
74 assert(count <
sizeof(inputLayout.formats)/
sizeof(inputLayout.formats[0]));
75 for (
size_t i = 0; i < count; ++i) {
76 inputLayout.formats[i] = getVertexFormat(vertexFormats[i]);
78 inputLayout.numFormats = count;
80 return this->inputLayouts.addResource(std::move(inputLayout));
85 this->inputLayouts.removeResource(handle);
90 unsigned int bindFlagsGl = 0;
92 if (bindFlags == 0) bindFlagsGl = GL_ARRAY_BUFFER;
100 GLenum usageMode = GL_STREAM_COPY;
108 default: usageMode = GL_STREAM_COPY;
break;
116 default: usageMode = GL_STATIC_COPY;
break;
124 default: usageMode = GL_DYNAMIC_COPY;
break;
132 default: usageMode = GL_STREAM_COPY;
break;
140 BufferGL20 buffer = { GL_INVALID_INDEX, GL_INVALID_INDEX, size, 0, bindFlagsGl, {}, std::vector<uint8_t>(),
MapMode::Read };
142 buffer.bufferId = createBuffer(bindFlagsGl, data, size, usageMode);
145 buffer.counterBufferId = createBuffer(GL_COPY_WRITE_BUFFER,
nullptr,
sizeof(GLuint), GL_DYNAMIC_COPY);
149 RegisterGPUResource(glBufferFakeAddress(buffer.bufferId), buffer.size, MemBlockType::GPUVertexBuffer);
152 RegisterGPUResource(glBufferFakeAddress(buffer.bufferId), buffer.size, MemBlockType::GPUIndexBuffer);
155 RegisterGPUResource(glBufferFakeAddress(buffer.bufferId), buffer.size, MemBlockType::GPUConstantBuffer);
158 RegisterGPUResource(glBufferFakeAddress(buffer.bufferId), buffer.size, MemBlockType::GPUBuffer);
161 bufferMemoryConsumption += buffer.size;
162 return this->buffers.addResource(std::move(buffer));
168 assert(HandleIsValid(source) &&
"Source buffer handle must be valid.");
169 const auto & sourceBuffer = this->buffers[source];
170 assert((offset + size <= sourceBuffer.size) &&
"Requested read outside source buffer.");
173 if (glGetNamedBufferSubData) {
174 glGetNamedBufferSubData(sourceBuffer.bufferId,
static_cast<GLintptr
>(offset),
static_cast<GLsizeiptr
>(size), data);
179 glBindBuffer(sourceBuffer.target, sourceBuffer.bufferId);
180 glGetBufferSubData(sourceBuffer.target,
static_cast<GLintptr
>(offset),
static_cast<GLsizeiptr
>(size), data);
181 glBindBuffer(sourceBuffer.target, 0);
187 auto & buffer = this->buffers[bufferHandle];
189 if (buffer.bufferId != GL_INVALID_INDEX) {
190 UnregisterGPUResource(glBufferFakeAddress(buffer.bufferId));
191 glDeleteBuffers(1, &buffer.bufferId);
192 buffer.bufferId = GL_INVALID_INDEX;
195 if (buffer.counterBufferId != GL_INVALID_INDEX) {
196 glDeleteBuffers(1, &buffer.counterBufferId);
197 buffer.counterBufferId = GL_INVALID_INDEX;
200 bufferMemoryConsumption -= buffer.size;
201 this->buffers.removeResource(bufferHandle);
207 std::vector<BufferHandle> handles;
208 for (
auto & buffer : buffers) {
209 handles.push_back(buffers.getHandle(buffer));
212 for (
auto & handle : handles) {
213 releaseBuffer(handle);
217 std::vector<InputLayoutHandle> handles;
218 for (
auto & layout : inputLayouts) {
219 handles.push_back(inputLayouts.getHandle(layout));
222 for (
auto & handle : handles) {
223 releaseInputLayout(handle);
230 auto & buffer = this->buffers[handle];
232 glObjectLabel(GL_BUFFER, buffer.bufferId,
static_cast<GLsizei
>(name.
size()), name.
data());
240 auto & buffer = this->buffers[handle];
242 glObjectLabel(GL_BUFFER, buffer.bufferId,
static_cast<GLsizei
>(name.
size()), name.
data());
Provides a weakly referenced view over the contents of a string.
constexpr const char * data() const noexcept
Get the sequence of characters referenced by the string view.
constexpr size_t size() const noexcept
Get the size of the string.
@ Read
The buffer can be mapped and read from by the CPU after creation.
@ Write
The buffer can be mapped and 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...
@ 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.
@ StructuredBuffer
The buffer can be bound as a structured buffer and read or written from shaders.
void releaseResources() override
Releases all allocated buffer resources.
BufferHandle loadBuffer(const void *data, const size_t size, Usage::EUsage usage, uint32_t accessMode, uint32_t bindFlags, uint32_t stride=0) override
Loads a new buffer using the given data to populate the buffer.
void releaseInputLayout(InputLayoutHandle vertexFormatHandle) override
Releases the input layout with the given inputLayoutHandle.
VertexBufferHandle loadVertexBuffer(const void *data, const size_t count, const VertexFormat &format) override
Loads a new vertex buffer and populates it with the given data.
IndexBufferHandle loadIndexBuffer(const void *data, const size_t count, const size_t indexSize) override
Loads a new index buffer and populates it with the given indexData.
void releaseBuffer(BufferHandle bufferHandle) override
Releases the buffer with the given bufferHandle.
void releaseIndexBuffer(IndexBufferHandle indexBufferHandle) override
Releases the index buffer with the given handle.
void annotate(BufferHandle handle, const StringView &name) override
Associate a name with an object for use in graphics debugging.
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...
void retrieveSubBuffer(void *data, BufferHandle source, const size_t offset, const size_t size) override
Retrieves the contents of a buffer.
void releaseVertexBuffer(VertexBufferHandle vertexBufferHandle) override
Release the vertex buffer with the given handle.
@ Static
Buffer will be loaded once and used to render many subsequent frames without any updates.
@ Dynamic
Buffer will be loaded and modified with some frequency.