Commit 1f79adad authored by Johannes Braun's avatar Johannes Braun
Browse files

Made Buffers, VAOs and Framebuffers fully bindless and cleaned them up a lot.

parent 47d2dc83
assets/screenshots/render.png

2.88 MB | W: | H:

assets/screenshots/render.png

2.45 MB | W: | H:

assets/screenshots/render.png
assets/screenshots/render.png
assets/screenshots/render.png
assets/screenshots/render.png
  • 2-up
  • Swipe
  • Onion skin
......@@ -80,8 +80,8 @@ namespace glare
//initializeScene(m_current_scene_root / "artifact_suzanne_x2_glass_0r.dae", 1.f);
//initializeScene(m_current_scene_root / "artifact_suzanne_x2_mirror_0r.dae", 1.f);
//initializeScene(m_current_scene_root / "artifact_suzanne_x2_transparent.dae", 1.f);
//initializeScene(m_current_scene_root / "benchmark_stfd_bunny_diff.dae", 1.f);
initializeScene(m_current_scene_root / "difficult.dae", 1.f);
initializeScene(m_current_scene_root / "benchmark_stfd_bunny_diff.dae", 1.f);
//initializeScene(m_current_scene_root / "difficult.dae", 1.f);
initializeRenderRequirements();
initializeAdvanced();
......
......@@ -134,14 +134,14 @@ void Game::initialize()
case 1: {
gl::viewport(0, 0, 1024, 1024);
texrend->draw(light_sun->shadowMapRenderer().framebuffer().getColorAttachment(0));
texrend->draw(light_sun->shadowMapRenderer().framebuffer().colorAttachment(gl::Attachment::eColor0));
gl::viewport(0, 0, unsigned(core::EngineState::main_camera->getWidth()),
unsigned(core::EngineState::main_camera->getWidth() / core::EngineState::main_camera->getAspectRatio()));
} break;
case 2: {
gl::viewport(0, 0, 1024, 1024);
texrend->draw(light_sun->shadowMapRenderer().framebuffer().getDepthAttachment());
texrend->draw(light_sun->shadowMapRenderer().framebuffer().depthAttachment());
gl::viewport(0, 0, unsigned(core::EngineState::main_camera->getWidth()),
unsigned(core::EngineState::main_camera->getWidth() / core::EngineState::main_camera->getAspectRatio()));
} break;
......
......@@ -49,8 +49,8 @@ namespace glare
if (!m_vertex_buffer)
m_vertex_buffer = std::make_shared<core::Buffer<gl::BufferType::eShaderStorage>>();
m_triangle_buffer->setData(m_triangles, gl::BufferUsage::eDynamicRead);
m_vertex_buffer->setData(m_vertices, gl::BufferUsage::eDynamicRead);
m_triangle_buffer->upload(m_triangles, gl::BufferUsage::eDynamicRead);
m_vertex_buffer->upload(m_vertices, gl::BufferUsage::eDynamicRead);
m_vertex_buffer->makeResident(gl::Access::eReadOnly);
m_triangle_buffer->makeResident(gl::Access::eReadOnly);
......@@ -95,19 +95,19 @@ namespace glare
{
Mesh mesh;
mesh.id = unsigned(id());
mesh.datastructure_buffer_ptr = m_datastructure->buffer().getResidentAddress();
mesh.datastructure_buffer_ptr = m_datastructure->buffer().residentAddress();
mesh.transformation = m_transform;
mesh.inverse_transformation = glm::inverse(m_transform);
mesh.normal_matrix = glm::mat4(glm::mat3(glm::transpose(glm::inverse(m_transform))));
mesh.vertex_buffer_ptr = m_vertex_buffer->getResidentAddress();
mesh.triangle_buffer_ptr = m_triangle_buffer->getResidentAddress();
mesh.vertex_buffer_ptr = m_vertex_buffer->residentAddress();
mesh.triangle_buffer_ptr = m_triangle_buffer->residentAddress();
if (m_linespace) {
mesh.bounds_min = m_linespace->bounds().min;
mesh.bounds_max = m_linespace->bounds().max;
mesh.patch_size = m_linespace->subdivisions().size;
mesh.resolution = glm::uvec3(m_linespace->subdivisions().subdivisions);
mesh.lines_buffer = m_linespace->lineBuffer().getResidentAddress();
mesh.lines_buffer = m_linespace->lineBuffer().residentAddress();
for (int i = 0; i < 15; ++i) {
mesh.offsets[i] = glm::uint(m_linespace->offsets()[i]);
......
......@@ -49,7 +49,7 @@ namespace glare
m_buffer = std::make_shared<core::Buffer<gl::BufferType::eShaderStorage>>();
}
m_buffer->setData(data, gl::BufferUsage::eDynamicRead);
m_buffer->upload(data, gl::BufferUsage::eDynamicRead);
m_buffer->makeResident(gl::Access::eReadOnly);
}
}
......
......@@ -144,16 +144,16 @@ namespace glare
m_light_buffer = std::make_unique<core::Buffer<gl::BufferType::eShaderStorage>>();
if (update_materials) {
m_material_buffer->setData(m_materials, gl::BufferUsage::eDynamicRead);
m_material_buffer->upload(m_materials, gl::BufferUsage::eDynamicRead);
m_material_buffer->makeResident(gl::Access::eReadOnly);
}
if (update_meshes || update_mesh_transforms || update_materials) {
m_mesh_buffer->setData(m_meshes, gl::BufferUsage::eDynamicRead);
m_mesh_buffer->upload(m_meshes, gl::BufferUsage::eDynamicRead);
}
if (update_light) {
m_light_buffer->setData(m_lights, gl::BufferUsage::eDynamicRead);
m_light_buffer->upload(m_lights, gl::BufferUsage::eDynamicRead);
}
m_dirty_flags.clear();
......@@ -267,11 +267,11 @@ namespace glare
if (!m_object_bvh_id_buffer)
m_object_bvh_id_buffer = std::make_shared<core::Buffer<gl::BufferType::eShaderStorage>>();
m_object_bvh_id_buffer->setData(mesh_ids, gl::BufferUsage::eDynamicRead);
m_object_bvh_id_buffer->upload(mesh_ids, gl::BufferUsage::eDynamicRead);
if (!m_object_bvh_node_buffer)
m_object_bvh_node_buffer = std::make_shared<core::Buffer<gl::BufferType::eShaderStorage>>();
m_object_bvh_node_buffer->setData(m_nodes, gl::BufferUsage::eDynamicRead);
m_object_bvh_node_buffer->upload(m_nodes, gl::BufferUsage::eDynamicRead);
m_meshes.resize(mesh_ids.size());
......
......@@ -68,9 +68,9 @@ namespace glare
if (raytracer.width() != m_last_width || raytracer.height() != m_last_height) {
m_last_width = raytracer.width();
m_last_height = raytracer.height();
m_framebuffer = std::make_unique<core::Framebuffer>(raytracer.width(), raytracer.height());
m_framebuffer->addAttachment(gl::Attachment::eColor0);
m_framebuffer->addAttachment(gl::Attachment::eDepth);
m_framebuffer = std::make_unique<core::Framebuffer<core::Texture>>(raytracer.width(), raytracer.height());
m_framebuffer->attach(gl::Attachment::eColor0);
m_framebuffer->attach(gl::Attachment::eDepth);
}
m_generator_shader_gbuffer->updateStorageBuffer("mesh_buffer", raytracer.collector()->meshBuffer());
......@@ -88,7 +88,11 @@ namespace glare
auto id = raytracer.collector()->getIdMapping().at(pair.first);
m_generator_shader_gbuffer->updateUniformUInt("u_mesh_id", unsigned(id));
m_generator_shader_gbuffer->updateUniformMatrix("u_mvp", core::EngineState::main_camera->getViewProjection() * pair.second->m_transform);
m_vertex_array->draw(gl::PrimitiveType::ePoints, pair.second->triangles().size());
m_vertex_array->bind();
gl::drawArrays(gl::PrimitiveType::ePoints, 0, pair.second->triangles().size());
m_vertex_array->unbind();
}
gl::memoryBarrier(gl::MemoryBarrierBit::eAll);
......@@ -96,7 +100,7 @@ namespace glare
core::OpenGLState::reset();
m_buffer_depthtest->updateUniformImageRGBA32F("u_gbuffer_texture_01", m_framebuffer->getColorAttachment(0), gl::Access::eReadOnly);
m_buffer_depthtest->updateUniformImageRGBA32F("u_gbuffer_texture_01", m_framebuffer->colorAttachment(gl::Attachment::eColor0), gl::Access::eReadOnly);
m_buffer_depthtest->updateUniformImageRGBA32F("u_render_target", raytracer.renderTarget(), gl::Access::eReadWrite);
m_buffer_depthtest->updateStorageBuffer("trace_buffer", raytracer.traceBuffer());
m_buffer_depthtest->updateUniformStruct("u_camera", raytracer.collector()->getActiveCamera());
......
......@@ -69,7 +69,7 @@ namespace glare
std::unique_ptr<core::ShaderProgram> m_generator_shader_gbuffer;
std::unique_ptr<core::ShaderProgram> m_buffer_depthtest;
std::unique_ptr<core::VertexArray> m_vertex_array;
std::unique_ptr<core::Framebuffer> m_framebuffer;
std::unique_ptr<core::Framebuffer<core::Texture>> m_framebuffer;
};
}
}
......
......@@ -140,7 +140,7 @@ namespace glare
Log_Info << "RESIZED: " << width << ", " << height;
m_trace_buffer->setData(sizeof(Trace) * width * height, gl::BufferUsage::eDynamicCopy);
m_trace_buffer->reserve<Trace>(width * height, gl::BufferUsage::eDynamicCopy);
m_render_target = std::make_unique<core::TextureRGBA_32F>(width, height);
m_color_store = std::make_unique<core::TextureRGBA_32F>(width, height);
m_render_config.current_sample = 0;
......
#include "RadixSort.h"
#include <glm/ext.hpp>
#include <atomic>
namespace glare
{
namespace core
{
}
}
......@@ -502,7 +502,7 @@ namespace glare
{
m_size = measure(m_max_dimensions);
const auto data = m_current_font->renderText(m_text, m_align, m_max_dimensions);
m_text_buffer->setData(unsigned(sizeof(TextBufferItem) * m_text.length()), gl::BufferUsage::eDynamicDraw, data.data());
m_text_buffer->upload<TextBufferItem>(data, gl::BufferUsage::eDynamicDraw);
}
std::shared_ptr<Font> Text::getFont() const
......@@ -595,7 +595,10 @@ namespace glare
m_shader->updateUniformVec4("u_text_color", text.getColor());
m_shader->updateStorageBuffer("TextBuffer", text.getBuffer());
m_vertex_array->draw(gl::PrimitiveType::ePoints, text.getLength());
m_vertex_array->bind();
gl::drawArrays(gl::PrimitiveType::ePoints, 0, text.getLength());
m_vertex_array->unbind();
}
}
......
......@@ -77,6 +77,8 @@ namespace glare
public:
using tex_type = typename TextureType<T>::type;
static constexpr bool is_multisampled = false;
constexpr static const gl::TextureFormat gl_format = Format;
constexpr static const gl::TextureInternalFormat gl_internal_format = InternalFormat;
constexpr static const gl::Type gl_type = T;
......@@ -88,6 +90,10 @@ namespace glare
void resize(unsigned width, unsigned height, tex_type* data = nullptr);
//compatibility for msaa framebuffers
Texture(unsigned width, unsigned height, unsigned t) : Texture(width, height) {}
void resize(unsigned width, unsigned height, unsigned t) { resize(width, height, nullptr); }
void bindToShader(std::shared_ptr<ShaderProgram> shader, std::string uniform_name) const;
void bindToShader(const ShaderProgram &shader, std::string uniform_name) const;
......
......@@ -11,19 +11,20 @@ namespace glare
namespace core
{
template<gl::TextureInternalFormat InternalFormat, gl::Type T>
template<gl::TextureFormat Format, gl::TextureInternalFormat InternalFormat, gl::Type T>
class TextureMultisampled
{
public:
using tex_type = typename TextureType<T>::type;
static constexpr bool is_multisampled = true;
constexpr static const gl::TextureInternalFormat gl_internal_format = InternalFormat;
constexpr static const gl::Type gl_type = T;
TextureMultisampled(unsigned width, unsigned height, unsigned samples);
TextureMultisampled(unsigned width, unsigned height, unsigned samples = 1);
~TextureMultisampled();
void resize(unsigned width, unsigned height, unsigned samples);
void resize(unsigned width, unsigned height, unsigned samples = 1);
void bindToShader(std::shared_ptr<ShaderProgram> shader, std::string uniform_name) const;
void bindToShader(const ShaderProgram &shader, std::string uniform_name) const;
......@@ -50,8 +51,8 @@ namespace glare
};
//General typed textures.
template<gl::TextureInternalFormat InternalFormat> using TextureMultisampled_UByte = TextureMultisampled<InternalFormat, gl::Type::eUByte>;
template<gl::TextureInternalFormat InternalFormat> using TextureMultisampled_Float = TextureMultisampled<InternalFormat, gl::Type::eFloat>;
template<gl::TextureInternalFormat InternalFormat> using TextureMultisampled_UByte = TextureMultisampled<gl::TextureFormat::eNone, InternalFormat, gl::Type::eUByte>;
template<gl::TextureInternalFormat InternalFormat> using TextureMultisampled_Float = TextureMultisampled<gl::TextureFormat::eNone, InternalFormat, gl::Type::eFloat>;
//Float textures
using TextureMultisampledRGBA_32F = TextureMultisampled_Float<gl::TextureInternalFormat::eRGBA32Float>;
......@@ -65,8 +66,8 @@ namespace glare
using TextureMultisampledR_UB = TextureMultisampled_UByte<gl::TextureInternalFormat::eRed>;
using TextureMultisampledDepth_32F = TextureMultisampled_Float<gl::TextureInternalFormat::eDepthComponent32Float>;
template<gl::TextureInternalFormat InternalFormat, gl::Type T>
TextureMultisampled<InternalFormat, T>::TextureMultisampled(unsigned width, unsigned height, unsigned samples)
template<gl::TextureFormat Format, gl::TextureInternalFormat InternalFormat, gl::Type T>
TextureMultisampled<Format, InternalFormat, T>::TextureMultisampled(unsigned width, unsigned height, unsigned samples)
{
resize(width, height, samples);
......@@ -75,14 +76,14 @@ namespace glare
gl::bindTexture(gl::TextureTarget::e2DMultisample, 0);
}
template<gl::TextureInternalFormat InternalFormat, gl::Type T>
TextureMultisampled<InternalFormat, T>::~TextureMultisampled()
template<gl::TextureFormat Format, gl::TextureInternalFormat InternalFormat, gl::Type T>
TextureMultisampled<Format, InternalFormat, T>::~TextureMultisampled()
{
gl::makeTextureHandleNonResident(m_texture_id_bindless);
}
template<gl::TextureInternalFormat InternalFormat, gl::Type T>
void TextureMultisampled<InternalFormat, T>::resize(unsigned width, unsigned height, unsigned samples)
template<gl::TextureFormat Format, gl::TextureInternalFormat InternalFormat, gl::Type T>
void TextureMultisampled<Format, InternalFormat, T>::resize(unsigned width, unsigned height, unsigned samples)
{
m_width = width;
m_height = height;
......@@ -93,8 +94,8 @@ namespace glare
gl::bindTexture(gl::TextureTarget::e2DMultisample, 0);
}
template<gl::TextureInternalFormat InternalFormat, gl::Type T>
void TextureMultisampled<InternalFormat, T>::bindToShader(std::shared_ptr<ShaderProgram> shader, std::string uniform_name) const
template<gl::TextureFormat Format, gl::TextureInternalFormat InternalFormat, gl::Type T>
void TextureMultisampled<Format, InternalFormat, T>::bindToShader(std::shared_ptr<ShaderProgram> shader, std::string uniform_name) const
{
gl::bindTexture(gl::TextureTarget::e2DMultisample, m_texture_handle);
gl::makeTextureHandleResident(m_texture_id_bindless);
......@@ -102,8 +103,8 @@ namespace glare
gl::makeTextureHandleNonResident(m_texture_id_bindless);
}
template<gl::TextureInternalFormat InternalFormat, gl::Type T>
void TextureMultisampled<InternalFormat, T>::bindToShader(const ShaderProgram &shader, std::string uniform_name) const
template<gl::TextureFormat Format, gl::TextureInternalFormat InternalFormat, gl::Type T>
void TextureMultisampled<Format, InternalFormat, T>::bindToShader(const ShaderProgram &shader, std::string uniform_name) const
{
gl::bindTexture(gl::TextureTarget::e2DMultisample, m_texture_handle);
gl::makeTextureHandleResident(m_texture_id_bindless);
......@@ -111,28 +112,28 @@ namespace glare
gl::makeTextureHandleNonResident(m_texture_id_bindless);
}
template <gl::TextureInternalFormat InternalFormat, gl::Type T>
GLuint TextureMultisampled<InternalFormat, T>::getID() const
template <gl::TextureFormat Format, gl::TextureInternalFormat InternalFormat, gl::Type T>
GLuint TextureMultisampled<Format, InternalFormat, T>::getID() const
{
return m_texture_handle;
}
template <gl::TextureInternalFormat InternalFormat, gl::Type T>
GLuint64 TextureMultisampled<InternalFormat, T>::getResidentTextureID() const
template <gl::TextureFormat Format, gl::TextureInternalFormat InternalFormat, gl::Type T>
GLuint64 TextureMultisampled<Format, InternalFormat, T>::getResidentTextureID() const
{
gl::bindTexture(gl::TextureTarget::e2DMultisample, m_texture_handle);
gl::makeTextureHandleResident(m_texture_id_bindless);
return m_texture_id_bindless;
}
template <gl::TextureInternalFormat InternalFormat, gl::Type T>
glm::ivec2 TextureMultisampled<InternalFormat, T>::getSize() const
template <gl::TextureFormat Format, gl::TextureInternalFormat InternalFormat, gl::Type T>
glm::ivec2 TextureMultisampled<Format, InternalFormat, T>::getSize() const
{
return {m_width, m_height};
}
template <gl::TextureInternalFormat InternalFormat, gl::Type T>
unsigned TextureMultisampled<InternalFormat, T>::getSamples() const
template <gl::TextureFormat Format, gl::TextureInternalFormat InternalFormat, gl::Type T>
unsigned TextureMultisampled<Format, InternalFormat, T>::getSamples() const
{
return m_samples;
}
......
......@@ -44,7 +44,7 @@ namespace glare
ShadowMap shadow_map;
shadow_map.available = m_shadow_map_renderer ? 1 : 0;
shadow_map.map = shadow_map.available ? m_shadow_map_renderer->framebuffer().getDepthAttachment().getResidentTextureID() : 0;
shadow_map.map = shadow_map.available ? m_shadow_map_renderer->framebuffer().depthAttachment().getResidentTextureID() : 0;
shadow_map.matrix = shadow_map.available ? m_shadow_map_renderer->matrix() : glm::mat4(1.f);
LightManager::getInstance().registerLightForNextPass({ m_light, shadow_map });
......
......@@ -119,14 +119,15 @@ namespace glare
m_element_array_buffer = std::make_unique<Buffer<gl::BufferType::eElementArray>>();
m_vertex_array = std::make_unique<VertexArray>();
m_array_buffer->setData(sizeof(math::Vertex) * m_vertices.size(), gl::BufferUsage::eStaticDraw, m_vertices.data());
m_element_array_buffer->setData(m_indices.size() * sizeof(unsigned int), gl::BufferUsage::eStaticDraw, m_indices.data());
m_vertex_array->link(unsigned(VertexAttribLocation::ePosition), 4, gl::Type::eFloat, false, sizeof(math::Vertex), 0);
m_vertex_array->link(unsigned(VertexAttribLocation::eNormal), 4, gl::Type::eFloat, false, sizeof(math::Vertex), sizeof(glm::vec4));
m_vertex_array->link(unsigned(VertexAttribLocation::eTexcoord), 2, gl::Type::eFloat, false, sizeof(math::Vertex), 2 * sizeof(glm::vec4)); //Length of 2, but there is a padding in-between.
m_vertex_array->link(unsigned(VertexAttribLocation::eTangent), 4, gl::Type::eFloat, false, sizeof(math::Vertex), 3 * sizeof(glm::vec4));
m_vertex_array->link(unsigned(VertexAttribLocation::eBitangend), 4, gl::Type::eFloat, false, sizeof(math::Vertex), 4 * sizeof(glm::vec4));
m_array_buffer->upload(m_vertices, gl::BufferUsage::eStaticDraw);
m_element_array_buffer->upload(m_indices, gl::BufferUsage::eStaticDraw);
m_vertex_array->linkAttribute(m_array_buffer->id(), unsigned(VertexAttribLocation::ePosition), 4, gl::Type::eFloat, false, sizeof(math::Vertex), 0);
m_vertex_array->linkAttribute(m_array_buffer->id(), unsigned(VertexAttribLocation::eNormal), 4, gl::Type::eFloat, false, sizeof(math::Vertex), sizeof(glm::vec4));
m_vertex_array->linkAttribute(m_array_buffer->id(), unsigned(VertexAttribLocation::eTexcoord), 2, gl::Type::eFloat, false, sizeof(math::Vertex), 2 * sizeof(glm::vec4)); //Length of 2, but there is a padding in-between.
m_vertex_array->linkAttribute(m_array_buffer->id(), unsigned(VertexAttribLocation::eTangent), 4, gl::Type::eFloat, false, sizeof(math::Vertex), 3 * sizeof(glm::vec4));
m_vertex_array->linkAttribute(m_array_buffer->id(), unsigned(VertexAttribLocation::eBitangend), 4, gl::Type::eFloat, false, sizeof(math::Vertex), 4 * sizeof(glm::vec4));
m_vertex_array->linkIndices(m_element_array_buffer->id());
}
const std::vector<math::Vertex>& Mesh::getVertices() const
......@@ -180,7 +181,10 @@ namespace glare
void Mesh::draw()
{
m_vertex_array->drawElements(gl::PrimitiveType::eTriangles, m_indices.size(), gl::Type::eUInt, *m_element_array_buffer);
m_vertex_array->bind();
m_element_array_buffer->bind();
gl::drawElements(gl::PrimitiveType::eTriangles, m_indices.size(), gl::Type::eUInt, nullptr);
m_vertex_array->unbind();
}
}
}
#ifndef __BUFFER_H
#define __BUFFER_H
// --- STDLIB ---------------------------------------------
#include <vector>
// --- EXTERN ---------------------------------------------
#include <opengl/OpenGL.h>
#include<types/templates.h>
// --- INTERN ---------------------------------------------
namespace glare
{
namespace core
{
template<gl::BufferType TBuffer>
class Buffer
{
public:
Buffer();
Buffer(Buffer& other) = delete;
Buffer& operator=(Buffer& other) = delete;
Buffer(Buffer&& other) = default;
Buffer& operator=(Buffer&& other) = default;
~Buffer();
void bind() const;
void bind(unsigned point) const;
void unbind() const;
unsigned id() const;
uint64_t residentAddress() const;
bool resident() const;
uint64_t makeResident(gl::Access access);
void makeNonResident() const;
template<typename T> void upload(size_t count, const T* data, gl::BufferUsage usage) const;
template<typename T> void upload(const std::vector<T>& data, gl::BufferUsage usage) const;
template<typename T = uint8_t> void reserve(size_t count, gl::BufferUsage usage) const;
template<typename T> std::vector<T> download(size_t count, size_t offset = 0) const;
template<typename TReturn = void> TReturn* map(size_t count, size_t offset, gl::BufferMapBit flags) const;
template<typename TReturn = void> TReturn* map(size_t count, gl::BufferMapBit flags) const;
void unmap() const;
protected:
gl::handle::buffer m_handle;
uint64_t m_resident_address = 0;
};
// -------------------------------------------------------------------------------------------------------------------------
// --- IMPLEMENTATIONS -----------------------------------------------------------------------------------------------------
// -------------------------------------------------------------------------------------------------------------------------
template<gl::BufferType TBuffer> Buffer<TBuffer>::Buffer() {}
template<gl::BufferType TBuffer>
Buffer<TBuffer>::~Buffer()
{
makeNonResident();
}
template<gl::BufferType TBuffer>
void Buffer<TBuffer>::bind() const
{
gl::bindBuffer(TBuffer, m_handle);
}
template<gl::BufferType TBuffer>
void Buffer<TBuffer>::bind(unsigned point) const
{
bind();
gl::bindBufferBase(TBuffer, point, m_handle);
}
template<gl::BufferType TBuffer>
void Buffer<TBuffer>::unbind() const
{
gl::bindBuffer(TBuffer, 0);
}
template<gl::BufferType TBuffer>
unsigned Buffer<TBuffer>::id() const
{
return m_handle;
}
template<gl::BufferType TBuffer>
uint64_t Buffer<TBuffer>::residentAddress() const
{
return m_resident_address;
}
template<gl::BufferType TBuffer>
bool Buffer<TBuffer>::resident() const
{
return gl::isNamedBufferResident(m_handle);
}
template<gl::BufferType TBuffer>
uint64_t Buffer<TBuffer>::makeResident(gl::Access access)
{
if (!resident())
{
bind();
gl::makeNamedBufferResident(m_handle, access);
gl::getNamedBufferParameterui64v(m_handle, gl::GetNamedBufferParameters::eGPUAddress, &m_resident_address);
}
assert(resident());
return m_resident_address;
}
template<gl::BufferType TBuffer>
void Buffer<TBuffer>::makeNonResident() const
{
if (resident())
{
gl::makeNamedBufferNonResident(m_handle);
}
}
template<gl::BufferType TBuffer>
template<typename T>
void Buffer<TBuffer>::upload(size_t count, const T* data, gl::BufferUsage usage) const
{
gl::namedBufferData(m_handle, sizeof(T) * count, data, usage);
}
template<gl::BufferType TBuffer>
template<typename T>
void Buffer<TBuffer>::upload(const std::vector<T>& data, gl::BufferUsage usage) const
{
gl::namedBufferData(m_handle, sizeof(T) * data.size(), data.data(), usage);
}
template<gl::BufferType TBuffer>
template<typename T>
void Buffer<TBuffer>::reserve(size_t count, gl::BufferUsage usage) const
{
upload<T>(count, nullptr, usage);
}
template<gl::BufferType TBuffer>
template<typename T>
std::vector<T> Buffer<TBuffer>::download(size_t count, size_t offset) const
{
std::vector<T> out(count);
memcpy(out.data(), map(count, offset, gl::BufferMapBit::eRead), count * sizeof(T));
unmap();
}
template<gl::BufferType TBuffer>
template<typename TReturn>
TReturn* Buffer<TBuffer>::map(size_t count, size_t offset, gl::BufferMapBit flags) const
{
// as you can't do sizeof(void), you can set it equivalent to 8 bit.
using measure_t = templates::decide_on_t<std::is_same_v<void, TReturn>, uint8_t, TReturn>>;
return reinterpret_cast<TReturn*>(gl::mapNamedBufferRange(m_handle, offset * sizeof(measure_t), count * sizeof(measure_t), flags));
}
template<gl::BufferType TBuffer>
template<typename TReturn>
TReturn* Buffer<TBuffer>::map(size_t count, gl::BufferMapBit flags) const
{
return map<TReturn>(count, 0, flags);
}
template<gl::BufferType TBuffer>
void Buffer<TBuffer>::unmap() const
{
gl::unmapNamedBuffer(m_handle);
}
}
}
#endif //__BUFFER_H