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);
35 std::vector<uint8_t>(),
39 BufferHandle handle = this->buffers.addResource(std::move(buffer));
46 return loadVertexBuffer(vertexData, count, createVertexFormat(vertexFormat.
elements.data(), vertexFormat.
elements.size()));
51 this->releaseBuffer(vertexBufferHandle);
56 assert(indexSize ==
sizeof(GLuint) || indexSize ==
sizeof(GLushort));
58 GLuint bufferId = createBuffer(GL_ELEMENT_ARRAY_BUFFER, indexData, count * indexSize);
61 buffer.indexSize = (indexSize ==
sizeof(GLuint)) ? GL_UNSIGNED_INT : GL_UNSIGNED_SHORT;
63 BufferHandle handle = this->buffers.addResource(std::move(buffer));
70 this->releaseBuffer(indexBufferHandle);
77 assert(count <
sizeof(inputLayout.formats)/
sizeof(inputLayout.formats[0]));
78 for (
size_t i = 0; i < count; ++i) {
79 inputLayout.formats[i] = getVertexFormat(vertexFormats[i]);
81 inputLayout.numFormats = count;
83 return this->inputLayouts.addResource(std::move(inputLayout));
88 this->inputLayouts.removeResource(handle);
93 unsigned int bindFlagsGl = 0;
95 if (bindFlags == 0) bindFlagsGl = GL_ARRAY_BUFFER;
103 GLenum usageMode = GL_STREAM_COPY;
111 default: usageMode = GL_STREAM_COPY;
break;
119 default: usageMode = GL_STATIC_COPY;
break;
127 default: usageMode = GL_DYNAMIC_COPY;
break;
135 default: usageMode = GL_STREAM_COPY;
break;
143 BufferGL20 buffer = { GL_INVALID_INDEX, GL_INVALID_INDEX, size, 0, bindFlagsGl, bindFlags, {}, std::vector<uint8_t>(),
MapMode::Read };
145 buffer.bufferId = createBuffer(bindFlagsGl, data, size, usageMode);
148 buffer.counterBufferId = createBuffer(GL_COPY_WRITE_BUFFER,
nullptr,
sizeof(GLuint), GL_DYNAMIC_COPY);
152 RegisterGPUResource(glBufferFakeAddress(buffer.bufferId), buffer.size, MemBlockType::GPUVertexBuffer);
155 RegisterGPUResource(glBufferFakeAddress(buffer.bufferId), buffer.size, MemBlockType::GPUIndexBuffer);
158 RegisterGPUResource(glBufferFakeAddress(buffer.bufferId), buffer.size, MemBlockType::GPUConstantBuffer);
161 RegisterGPUResource(glBufferFakeAddress(buffer.bufferId), buffer.size, MemBlockType::GPUBuffer);
164 BufferHandle handle = this->buffers.addResource(std::move(buffer));
172 assert(HandleIsValid(source) &&
"Source buffer handle must be valid.");
173 const auto & sourceBuffer = this->buffers[source];
174 assert((offset + size <= sourceBuffer.size) &&
"Requested read outside source buffer.");
177 if (glGetNamedBufferSubData) {
178 glGetNamedBufferSubData(sourceBuffer.bufferId,
static_cast<GLintptr
>(offset),
static_cast<GLsizeiptr
>(size), data);
183 glBindBuffer(sourceBuffer.target, sourceBuffer.bufferId);
184 glGetBufferSubData(sourceBuffer.target,
static_cast<GLintptr
>(offset),
static_cast<GLsizeiptr
>(size), data);
185 glBindBuffer(sourceBuffer.target, 0);
191 if (!HandleIsValid(bufferHandle))
return;
193 auto & buffer = this->buffers[bufferHandle];
195 if (buffer.bufferId != GL_INVALID_INDEX) {
196 UnregisterGPUResource(glBufferFakeAddress(buffer.bufferId));
197 glDeleteBuffers(1, &buffer.bufferId);
198 buffer.bufferId = GL_INVALID_INDEX;
201 if (buffer.counterBufferId != GL_INVALID_INDEX) {
202 glDeleteBuffers(1, &buffer.counterBufferId);
203 buffer.counterBufferId = GL_INVALID_INDEX;
206 recordBufferRelease(bufferHandle,
static_cast<BindFlags::EBindFlags>(buffer.bindFlags), buffer.size);
207 this->buffers.removeResource(bufferHandle);
213 std::vector<BufferHandle> handles;
214 for (
auto & buffer : buffers) {
215 handles.push_back(buffers.getHandle(buffer));
218 for (
auto & handle : handles) {
219 releaseBuffer(handle);
223 std::vector<InputLayoutHandle> handles;
224 for (
auto & layout : inputLayouts) {
225 handles.push_back(inputLayouts.getHandle(layout));
228 for (
auto & handle : handles) {
229 releaseInputLayout(handle);
236 auto & buffer = this->buffers[handle];
238 glObjectLabel(GL_BUFFER, buffer.bufferId,
static_cast<GLsizei
>(name.
size()), name.
data());
246 auto & buffer = this->buffers[handle];
248 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.
EBindFlags
Bind flags enumeration.
@ 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 recordBufferCreate(BufferHandle handle, BindFlags::EBindFlags bindFlags, size_t bytes)
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.