1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 16:07:47 +00:00

LibGL: Add simple implementation of buffer objects

For now, buffers are only implemented on the LibGL side, however in the
future buffer objects should be stored in LibGPU.
This commit is contained in:
cflip 2022-11-13 15:08:24 -07:00 committed by Andreas Kling
parent 892006218a
commit 59df2e62ee
6 changed files with 170 additions and 10 deletions

View file

@ -1,5 +1,6 @@
/*
* Copyright (c) 2022, Jelle Raaijmakers <jelle@gmta.nl>
* Copyright (c) 2022, cflip <cflip@cflip.net>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
@ -11,32 +12,99 @@ namespace GL {
void GLContext::gl_bind_buffer(GLenum target, GLuint buffer)
{
// FIXME: implement me
dbgln_if(GL_DEBUG, "{}({:#x}, {})): unimplemented", __FUNCTION__, target, buffer);
RETURN_WITH_ERROR_IF(target != GL_ARRAY_BUFFER && target != GL_ELEMENT_ARRAY_BUFFER, GL_INVALID_ENUM);
RETURN_WITH_ERROR_IF(!m_buffer_name_allocator.has_allocated_name(buffer), GL_INVALID_VALUE);
auto& target_buffer = target == GL_ELEMENT_ARRAY_BUFFER ? m_element_array_buffer : m_array_buffer;
target_buffer = nullptr;
if (buffer != 0) {
auto it = m_allocated_buffers.find(buffer);
if (it != m_allocated_buffers.end()) {
auto buffer_object = it->value;
if (!buffer_object.is_null()) {
target_buffer = buffer_object;
}
}
if (!target_buffer) {
target_buffer = adopt_ref(*new Buffer());
m_allocated_buffers.set(buffer, target_buffer);
}
}
}
void GLContext::gl_buffer_data(GLenum target, GLsizeiptr size, void const* data, GLenum usage)
{
// FIXME: implement me
dbgln_if(GL_DEBUG, "{}({:#x}, {}, {:p}, {:#x}): unimplemented", __FUNCTION__, target, size, data, usage);
RETURN_WITH_ERROR_IF(usage != GL_STREAM_DRAW
&& usage != GL_STREAM_READ
&& usage != GL_STREAM_COPY
&& usage != GL_STATIC_DRAW
&& usage != GL_STATIC_READ
&& usage != GL_STATIC_COPY
&& usage != GL_DYNAMIC_DRAW
&& usage != GL_DYNAMIC_READ
&& usage != GL_DYNAMIC_COPY,
GL_INVALID_ENUM);
RETURN_WITH_ERROR_IF(target != GL_ARRAY_BUFFER && target != GL_ELEMENT_ARRAY_BUFFER, GL_INVALID_ENUM);
auto& target_buffer = target == GL_ELEMENT_ARRAY_BUFFER ? m_element_array_buffer : m_array_buffer;
RETURN_WITH_ERROR_IF(!target_buffer, GL_INVALID_OPERATION);
// FIXME: Report GL_OUT_OF_MEMORY or other errors as needed here
MUST(target_buffer->set_data(data, size));
}
void GLContext::gl_buffer_sub_data(GLenum target, GLintptr offset, GLsizeiptr size, void const* data)
{
// FIXME: implement me
dbgln_if(GL_DEBUG, "{}({:#x}, {}, {}, {:p}): unimplemented", __FUNCTION__, target, offset, size, data);
RETURN_WITH_ERROR_IF(target != GL_ARRAY_BUFFER && target != GL_ELEMENT_ARRAY_BUFFER, GL_INVALID_ENUM);
RETURN_WITH_ERROR_IF(offset < 0, GL_INVALID_VALUE);
// FIXME: Support buffer storage mutability flags.
auto& target_buffer = target == GL_ELEMENT_ARRAY_BUFFER ? m_element_array_buffer : m_array_buffer;
RETURN_WITH_ERROR_IF(!target_buffer, GL_INVALID_OPERATION);
RETURN_WITH_ERROR_IF((offset + size) > target_buffer->size(), GL_INVALID_VALUE);
target_buffer->replace_data(data, offset, size);
}
void GLContext::gl_delete_buffers(GLsizei n, GLuint const* buffers)
{
// FIXME: implement me
dbgln_if(GL_DEBUG, "{}({}, {:p}): unimplemented", __FUNCTION__, n, buffers);
RETURN_WITH_ERROR_IF(n < 0, GL_INVALID_VALUE);
for (auto i = 0; i < n; i++) {
GLuint name = buffers[i];
if (name == 0)
continue;
auto buffer_object = m_allocated_buffers.find(name);
if (buffer_object == m_allocated_buffers.end() || buffer_object->value.is_null())
continue;
Buffer* buffer = buffer_object->value;
if (m_array_buffer == buffer)
m_array_buffer = nullptr;
if (m_element_array_buffer == buffer)
m_element_array_buffer = nullptr;
m_buffer_name_allocator.free(name);
m_allocated_buffers.remove(name);
}
}
void GLContext::gl_gen_buffers(GLsizei n, GLuint* buffers)
{
// FIXME: implement me
dbgln_if(GL_DEBUG, "{}({}, {:p}): unimplemented", __FUNCTION__, n, buffers);
RETURN_WITH_ERROR_IF(n < 0, GL_INVALID_VALUE);
m_buffer_name_allocator.allocate(n, buffers);
// Initialize all buffer names with a nullptr
for (auto i = 0; i < n; ++i) {
GLuint name = buffers[i];
m_allocated_buffers.set(name, nullptr);
}
}
}