...
This commit is contained in:
@@ -9,21 +9,11 @@
|
||||
|
||||
namespace zgl
|
||||
{
|
||||
class shader_program_data
|
||||
struct shader_program_data
|
||||
{
|
||||
private:
|
||||
explicit shader_program_data(GLuint program_id);
|
||||
|
||||
public:
|
||||
|
||||
shader_program_data() = default;
|
||||
|
||||
[[nodiscard]] static std::error_code build_from(
|
||||
const shader_handle& vertex_shader,
|
||||
const shader_handle& geometry_shader,
|
||||
const shader_handle& fragment_shader,
|
||||
shader_program_data& data
|
||||
);
|
||||
explicit shader_program_data(GLuint program_id);
|
||||
|
||||
shader_program_data(const shader_program_data& other) = delete;
|
||||
shader_program_data& operator=(const shader_program_data& other) = delete;
|
||||
@@ -31,12 +21,9 @@ public:
|
||||
shader_program_data(shader_program_data&& other) noexcept ;
|
||||
shader_program_data& operator=(shader_program_data&& other) noexcept;
|
||||
|
||||
[[nodiscard]] shader_program_handle handle() const;
|
||||
|
||||
~shader_program_data();
|
||||
|
||||
private:
|
||||
shader_program_handle m_handle{};
|
||||
shader_program_handle handle{};
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "GL/glew.h"
|
||||
#include "opengl/handles/texture_handle.hpp"
|
||||
|
||||
#include <span>
|
||||
|
||||
namespace zgl
|
||||
{
|
||||
struct texture_data
|
||||
{
|
||||
private:
|
||||
explicit texture_data(GLuint texture_id);
|
||||
|
||||
public:
|
||||
texture_data() = default;
|
||||
|
||||
template<typename T>
|
||||
[[nodiscard]] static std::error_code build_from(
|
||||
std::span<const T> buffer,
|
||||
GLenum format,
|
||||
GLenum type,
|
||||
GLsizei width,
|
||||
GLsizei height,
|
||||
texture_data& data
|
||||
);
|
||||
|
||||
texture_data(const texture_data&) = delete;
|
||||
texture_data& operator=(const texture_data&) = delete;
|
||||
|
||||
texture_data(texture_data&&) noexcept;
|
||||
texture_data& operator=(texture_data&&) noexcept;
|
||||
|
||||
~texture_data();
|
||||
|
||||
[[nodiscard]] texture_handle handle() const;
|
||||
|
||||
private:
|
||||
texture_handle m_handle{};
|
||||
};
|
||||
}
|
||||
|
||||
#define INCLUDE_TEXTURE_DATA_IMPLEMENTATION
|
||||
#include "opengl/data/texture_data.ipp"
|
||||
#undef INCLUDE_TEXTURE_DATA_IMPLEMENTATION
|
||||
36
include/opengl/data_managers/buffer_manager.hpp
Normal file
36
include/opengl/data_managers/buffer_manager.hpp
Normal file
@@ -0,0 +1,36 @@
|
||||
#pragma once
|
||||
|
||||
namespace zgl
|
||||
{
|
||||
|
||||
class buffer_manager
|
||||
{
|
||||
public:
|
||||
using store_type = dynamic_texture_store;
|
||||
using store_id_type = store_type::id_type;
|
||||
using resource_manager_type = resource_manager<store_id_type>;
|
||||
using resource_type = resource_manager_type::resource_handle;
|
||||
using handle_type = texture_handle;
|
||||
|
||||
static constexpr std::size_t min_garbage_collection_count = 4;
|
||||
|
||||
void process(store_type& store);
|
||||
|
||||
std::optional<handle_type> get_handle(store_id_type id);
|
||||
|
||||
void collect_garbage(bool force = false);
|
||||
|
||||
private:
|
||||
|
||||
resource_manager<store_id_type> m_resource_manager;
|
||||
|
||||
std::vector<std::pair<dynamic_texture_store::id_type, const dynamic_texture_buffer&>> m_texture_buffer;
|
||||
std::vector<GLuint> m_texture_id_buffer;
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
32
include/opengl/data_managers/mesh_vertex_buffer_manager.hpp
Normal file
32
include/opengl/data_managers/mesh_vertex_buffer_manager.hpp
Normal file
@@ -0,0 +1,32 @@
|
||||
#pragma once
|
||||
|
||||
|
||||
#include "assets/dynamic_data_stores/dynamic_mesh_store.hpp"
|
||||
#include "opengl/resource_management/resource_manager.hpp"
|
||||
#include "opengl/handles/vertex_buffer_handle.hpp"
|
||||
#include "opengl/metadata/vertex_buffer_metadata.hpp"
|
||||
|
||||
namespace zgl
|
||||
{
|
||||
class mesh_vertex_buffer_manager
|
||||
{
|
||||
public:
|
||||
using store_type = dynamic_mesh_store;
|
||||
using store_id_type = store_type::id_type;
|
||||
using metadata_type = vertex_buffer_metadata;
|
||||
using handle_type = vertex_buffer_handle;
|
||||
using resource_manager_type = resource_manager<store_id_type, metadata_type>;
|
||||
using texture_entry_type = std::pair<handle_type, metadata_type>;
|
||||
|
||||
static constexpr std::size_t min_garbage_collection_count = 4;
|
||||
|
||||
void process(store_type& store);
|
||||
|
||||
std::optional<texture_entry_type> get_handle(store_id_type id);
|
||||
|
||||
void collect_garbage(bool force = false);
|
||||
|
||||
private:
|
||||
resource_manager_type m_resource_manager;
|
||||
};
|
||||
}
|
||||
@@ -10,7 +10,7 @@
|
||||
#include "opengl/shader_program_lookup.hpp"
|
||||
#include "opengl/handles/shader_handle.hpp"
|
||||
#include "util/string_lookup.hpp"
|
||||
#include "shader_preprocessor.hpp"
|
||||
#include "shader_source_manager.hpp"
|
||||
#include "opengl/metadata/shader_metadata.hpp"
|
||||
#include "opengl/data/shader_data.hpp"
|
||||
#include "opengl/handles/shader_handle_set.hpp"
|
||||
@@ -20,26 +20,16 @@
|
||||
|
||||
namespace zgl
|
||||
{
|
||||
class shader_program_compiler
|
||||
class shader_manager
|
||||
{
|
||||
using shader_lookup_entry_type = std::pair<shader_metadata, shader_data>;
|
||||
|
||||
static constexpr auto gl_shader_types = std::array<GLenum, shading::stage::count>{
|
||||
GL_VERTEX_SHADER,
|
||||
GL_TESS_CONTROL_SHADER,
|
||||
GL_TESS_EVALUATION_SHADER,
|
||||
GL_GEOMETRY_SHADER,
|
||||
GL_FRAGMENT_SHADER
|
||||
};
|
||||
|
||||
|
||||
public:
|
||||
|
||||
void preprocess(
|
||||
void process(
|
||||
const dynamic_shader_source_store& shader_sources
|
||||
);
|
||||
|
||||
void compile_shaders(
|
||||
void get_handles(
|
||||
const dynamic_shader_source_store& shader_sources,
|
||||
std::span<const shading::shader_set_requirements> requirements,
|
||||
std::span<shader_set_metadata> metadata,
|
||||
@@ -47,22 +37,22 @@ public:
|
||||
);
|
||||
|
||||
protected:
|
||||
shader_handle find_shader(
|
||||
std::optional<std::pair<shader_metadata, shader_handle>> find_shader(
|
||||
const shading::shader_requirements& requirements
|
||||
);
|
||||
|
||||
bool compile_shader(
|
||||
static bool compile_shader(
|
||||
GLenum shader_type,
|
||||
std::span<const char*> source_strings,
|
||||
shader_data& shader
|
||||
);
|
||||
|
||||
private:
|
||||
shader_preprocessor m_preprocessor{};
|
||||
shader_source_manager m_preprocessor{};
|
||||
|
||||
std::vector<shading::shader_source_requirements> m_source_requirement_buffer{};
|
||||
std::vector<preprocessed_shader_source_metadata> m_preprocessed_shader_source_metadata_buffer;
|
||||
std::vector<const char*> m_source_strings_buffer;
|
||||
std::vector<shader_lookup_entry_type> m_shader_lookup;
|
||||
std::vector<preprocessed_shader_source_metadata> m_preprocessed_shader_source_metadata_buffer{};
|
||||
std::vector<const char*> m_source_strings_buffer{};
|
||||
std::vector<shader_lookup_entry_type> m_shader_lookup{};
|
||||
};
|
||||
}
|
||||
50
include/opengl/data_managers/shader_program_manager.hpp
Normal file
50
include/opengl/data_managers/shader_program_manager.hpp
Normal file
@@ -0,0 +1,50 @@
|
||||
#pragma once
|
||||
|
||||
#include "shader_manager.hpp"
|
||||
#include "assets/dynamic_data_stores/dynamic_shader_source_store.hpp"
|
||||
#include "opengl/data/shader_program_data.hpp"
|
||||
#include "opengl/shading/requirements/shader_program_requirements.hpp"
|
||||
#include "opengl/metadata/shader_program_metadata.hpp"
|
||||
|
||||
namespace zgl
|
||||
{
|
||||
|
||||
class shader_program_manager
|
||||
{
|
||||
using shader_program_lookup_entry_type = std::pair<
|
||||
shader_program_metadata,
|
||||
shader_program_data
|
||||
>;
|
||||
|
||||
public:
|
||||
void process(
|
||||
const dynamic_shader_source_store& shader_sources
|
||||
);
|
||||
|
||||
void get_handles(
|
||||
const dynamic_shader_source_store& shader_sources,
|
||||
std::span<const shading::shader_program_requirements> requirements,
|
||||
std::span<shader_program_metadata> metadata,
|
||||
std::span<shader_program_handle> shader_programs
|
||||
);
|
||||
|
||||
protected:
|
||||
std::optional<std::pair<shader_program_metadata, shader_program_handle>> find_shader_program(
|
||||
const shading::shader_program_requirements& requirements
|
||||
);
|
||||
|
||||
bool link_shader_program(
|
||||
const shader_handle_set& shaders
|
||||
);
|
||||
|
||||
shader_manager m_shader_manager;
|
||||
std::vector<shader_program_lookup_entry_type> m_shader_program_lookup;
|
||||
|
||||
private:
|
||||
|
||||
std::vector<shading::shader_set_requirements> m_shader_requirements_buffer;
|
||||
std::vector<shader_set_metadata> m_shader_metadata_buffer;
|
||||
std::vector<shader_handle_set> shader_set_buffer;
|
||||
};
|
||||
|
||||
}
|
||||
@@ -15,21 +15,20 @@
|
||||
|
||||
namespace zgl {
|
||||
|
||||
class shader_preprocessor {
|
||||
class shader_source_manager {
|
||||
|
||||
public:
|
||||
void preprocess(
|
||||
void process(
|
||||
const dynamic_shader_source_store& shader_sources
|
||||
);
|
||||
|
||||
void fetch_shader_sources(
|
||||
void get_shader_sources(
|
||||
const dynamic_shader_source_store& shader_sources,
|
||||
std::span<const shading::shader_source_requirements> requirements,
|
||||
std::span<preprocessed_shader_source_metadata> metadata,
|
||||
std::vector<const char*>& shader_strings
|
||||
);
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
void tokenize_declarations(std::string_view source);
|
||||
@@ -76,28 +75,6 @@ protected:
|
||||
);
|
||||
|
||||
private:
|
||||
inline static auto mesh_feature_defines = std::array{
|
||||
"#define FACE\n",
|
||||
"#define LINE\n",
|
||||
"#define POINT\n",
|
||||
"#define V_L\n",
|
||||
"#define V_RGB\n",
|
||||
"#define V_A\n",
|
||||
"#define LIGHTING\n",
|
||||
"#define TEXTURE\n",
|
||||
"#define U_RGBA\n",
|
||||
};
|
||||
|
||||
inline static auto point_cloud_feature_defines = std::array{
|
||||
"#define SQUARE\n",
|
||||
"#define LIGHTING\n",
|
||||
"#define V_L\n",
|
||||
"#define V_RGB\n",
|
||||
"#define V_A\n",
|
||||
"#define U_RGBA\n",
|
||||
"#define RAINBOW\n"
|
||||
};
|
||||
|
||||
std::vector<std::string_view> m_value_token_buffer;
|
||||
std::vector<std::size_t> m_declaration_token_count_buffer;
|
||||
std::array<std::size_t, 4> m_declaration_type_index_buffer;
|
||||
41
include/opengl/data_managers/texture_manager.hpp
Normal file
41
include/opengl/data_managers/texture_manager.hpp
Normal file
@@ -0,0 +1,41 @@
|
||||
#pragma once
|
||||
|
||||
#include <unordered_map>
|
||||
|
||||
#include "assets/dynamic_read_buffers/dynamic_texture_buffer.hpp"
|
||||
#include "assets/dynamic_data_stores/dynamic_texture_store.hpp"
|
||||
#include "opengl/handles/texture_handle.hpp"
|
||||
#include <vector>
|
||||
|
||||
#include "opengl/metadata/texture_metadata.hpp"
|
||||
#include "opengl/resource_management/resource_manager.hpp"
|
||||
|
||||
namespace zgl
|
||||
{
|
||||
class texture_manager
|
||||
{
|
||||
public:
|
||||
using store_type = dynamic_texture_store;
|
||||
using store_id_type = store_type::id_type;
|
||||
using metadata_type = texture_metadata;
|
||||
using handle_type = texture_handle;
|
||||
using resource_manager_type = resource_manager<store_id_type, metadata_type>;
|
||||
using texture_entry_type = std::pair<handle_type, metadata_type>;
|
||||
|
||||
static constexpr std::size_t min_garbage_collection_count = 4;
|
||||
|
||||
void process(store_type& store);
|
||||
|
||||
std::optional<texture_entry_type> get_handle(store_id_type id);
|
||||
|
||||
void collect_garbage(bool force = false);
|
||||
|
||||
private:
|
||||
|
||||
resource_manager_type m_resource_manager;
|
||||
|
||||
std::vector<std::pair<dynamic_texture_store::id_type, const dynamic_texture_buffer&>> m_texture_buffer;
|
||||
std::vector<GLuint> m_texture_id_buffer;
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <unordered_map>
|
||||
#include "assets/dynamic_data_stores/dynamic_shader_source_store.hpp"
|
||||
#include "opengl/shader_program_lookup.hpp"
|
||||
#include "opengl/handles/shader_handle.hpp"
|
||||
#include "opengl/handles/shader_program_handle.hpp"
|
||||
#include "../metadata/shader_source_metadata.hpp"
|
||||
#include "shading/shader_program_requirements.hpp"
|
||||
|
||||
namespace zgl
|
||||
{
|
||||
|
||||
class shader_program_compiler
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
|
||||
// compile shader programs for given requirements
|
||||
// cache shader programs with their capabilities
|
||||
// store sstream for creating defines
|
||||
|
||||
// register shader source code
|
||||
// store define types for these shaders as bitmap
|
||||
void register_shader_sources(
|
||||
const dynamic_shader_source_store& shader_sources
|
||||
);
|
||||
|
||||
void compile_shader_programs(
|
||||
const dynamic_shader_source_store& shader_sources,
|
||||
std::span<const shading::shader_program_metadata> requirements,
|
||||
std::vector<shader_program_handle>& shader_handles
|
||||
);
|
||||
|
||||
// create metadata for all sources
|
||||
|
||||
// get
|
||||
ś
|
||||
protected:
|
||||
|
||||
|
||||
|
||||
private:
|
||||
std::vector<shading::compiled_shader_metadata_type, shader_handle> shader_lookup;
|
||||
std::vector<shading::shader_program_metadata, shader_program_handle> shader_program_lookup;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,78 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "../../assets/dynamic_read_buffers"
|
||||
#include "assets/dynamic_data_stores/dynamic_texture_store.hpp"
|
||||
#include "opengl/data/texture_data.hpp"
|
||||
#include <vector>
|
||||
|
||||
namespace zgl
|
||||
{
|
||||
class texture_data_uploader
|
||||
{
|
||||
|
||||
void upload(
|
||||
std::span<const dynamic_texture_data> dynamic_data,
|
||||
std::span<const dynamic_texture_store::id_type> dynamic_data_ids
|
||||
) {
|
||||
|
||||
std::vector<GLuint> texture_ids;
|
||||
|
||||
texture_ids.resize(dynamic_data.size());
|
||||
|
||||
glGenTextures(texture_ids.size(), texture_ids.data());
|
||||
|
||||
const auto invalid_texture_ids = std::ranges::partition(
|
||||
texture_ids,
|
||||
[](GLuint texture_id)
|
||||
{
|
||||
GLenum format;
|
||||
switch (texture.components()) {
|
||||
using enum components::texture::flags;
|
||||
case luminance:
|
||||
format = GL_LUMINANCE;
|
||||
break;
|
||||
case luminance | alpha:
|
||||
format = GL_LUMINANCE_ALPHA;
|
||||
break;
|
||||
case red | green | blue:
|
||||
format = GL_RGB;
|
||||
break;
|
||||
case red | green | blue | alpha:
|
||||
format = GL_RGBA;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, texture_id);
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
|
||||
|
||||
glTexImage2D(
|
||||
GL_TEXTURE_2D, 0,
|
||||
GL_RGBA8,
|
||||
texture.width(),
|
||||
texture.height(),
|
||||
0,
|
||||
format,
|
||||
GL_UNSIGNED_BYTE,
|
||||
texture.data()
|
||||
);
|
||||
glGenerateMipmap(GL_TEXTURE_2D);
|
||||
|
||||
return true;
|
||||
}
|
||||
);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
glDeleteTextures(invalid_texture_ids.size(), invalid_texture_ids.data());
|
||||
|
||||
invalid_texture_ids.resize(texture_ids.size() - invalid_texture_ids.size());
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -68,6 +68,11 @@ struct category : std::error_category
|
||||
return { static_cast<int>(e), error_category() };
|
||||
}
|
||||
|
||||
[[nodiscard]] inline std::error_code get_error()
|
||||
{
|
||||
return make_error_code(glGetError());
|
||||
}
|
||||
|
||||
} // namespace zgl
|
||||
|
||||
template<>
|
||||
|
||||
18
include/opengl/handles/index_buffer_handle.hpp
Normal file
18
include/opengl/handles/index_buffer_handle.hpp
Normal file
@@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
|
||||
#include "opengl/resource_management/resource_handle.hpp"
|
||||
|
||||
namespace zgl
|
||||
{
|
||||
|
||||
struct index_buffer_handle : resource_handle
|
||||
{
|
||||
inline void bind() const;
|
||||
inline static void unbind();
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#define INCLUDE_INDEX_BUFFER_HANDLE_IMPLEMENTATION
|
||||
#include "opengl/handles/index_buffer_handle.ipp"
|
||||
#undef INCLUDE_INDEX_BUFFER_HANDLE_IMPLEMENTATION
|
||||
@@ -7,7 +7,7 @@ namespace zgl
|
||||
|
||||
struct shader_handle_set
|
||||
{
|
||||
std::array<shader_handle, zgl::shading::stage::count> stages;
|
||||
std::array<shader_handle, shading::stage::count> stages;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -24,7 +24,9 @@ struct shader_program_handle
|
||||
|
||||
[[nodiscard]] uniform_support_type check_uniform_support(std::span<const shader_program_variable> uniforms) const;
|
||||
|
||||
GLuint program_id{ 0 };
|
||||
[[nodiscard]] bool valid() const;
|
||||
|
||||
GLuint id{ 0 };
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -1,15 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
#include "GL/glew.h"
|
||||
#include "opengl/resource_management/resource_handle.hpp"
|
||||
|
||||
namespace zgl {
|
||||
struct texture_handle
|
||||
namespace zgl
|
||||
{
|
||||
|
||||
struct texture_handle : resource_handle
|
||||
{
|
||||
inline void bind() const;
|
||||
inline static void unbind();
|
||||
|
||||
GLuint texture_id{ 0 };
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#define INCLUDE_TEXTURE_INSTANCE_IMPLEMENTATION
|
||||
|
||||
19
include/opengl/handles/vertex_buffer_handle.hpp
Normal file
19
include/opengl/handles/vertex_buffer_handle.hpp
Normal file
@@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
#include "opengl/resource_management/resource_handle.hpp"
|
||||
|
||||
|
||||
namespace zgl
|
||||
{
|
||||
|
||||
struct vertex_buffer_handle : resource_handle
|
||||
{
|
||||
inline void bind() const;
|
||||
inline static void unbind();
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#define INCLUDE_VERTEX_BUFFER_HANDLE_IMPLEMENTATION
|
||||
#include "opengl/handles/vertex_buffer_handle.ipp"
|
||||
#undef INCLUDE_VERTEX_BUFFER_HANDLE_IMPLEMENTATION
|
||||
15
include/opengl/metadata/shader_program_metadata.hpp
Normal file
15
include/opengl/metadata/shader_program_metadata.hpp
Normal file
@@ -0,0 +1,15 @@
|
||||
#pragma once
|
||||
|
||||
#include "opengl/shading/model_geometry.hpp"
|
||||
#include "opengl/shading/features/generic_features.hpp"
|
||||
|
||||
namespace zgl {
|
||||
|
||||
struct shader_program_metadata
|
||||
{
|
||||
shading::model_geometry::types geometry;
|
||||
shading::features::generic::type static_enabled{};
|
||||
shading::features::generic::type dynamic_enable{};
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,7 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include "opengl/shading/model_geometry.hpp"
|
||||
#include "opengl/shading/shader_stage.hpp"
|
||||
#include "opengl/shading/features/generic_features.hpp"
|
||||
|
||||
namespace zgl
|
||||
|
||||
13
include/opengl/metadata/texture_metadata.hpp
Normal file
13
include/opengl/metadata/texture_metadata.hpp
Normal file
@@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
#include "assets/components/texture_components.hpp"
|
||||
|
||||
namespace zgl
|
||||
{
|
||||
|
||||
struct texture_metadata
|
||||
{
|
||||
components::texture::flags components;
|
||||
};
|
||||
|
||||
}
|
||||
26
include/opengl/metadata/vertex_buffer_metadata.hpp
Normal file
26
include/opengl/metadata/vertex_buffer_metadata.hpp
Normal file
@@ -0,0 +1,26 @@
|
||||
#pragma once
|
||||
|
||||
#include "assets/components/texture_components.hpp"
|
||||
#include <array>
|
||||
|
||||
#include "GL/glew.h"
|
||||
|
||||
namespace zgl
|
||||
{
|
||||
|
||||
struct vertex_buffer_metadata
|
||||
{
|
||||
static constexpr std::size_t max_component_count = 8;
|
||||
|
||||
struct component
|
||||
{
|
||||
GLenum type{ GL_INVALID_ENUM };
|
||||
GLint length{ 0 };
|
||||
};
|
||||
|
||||
std::array<component, max_component_count> components{};
|
||||
GLuint component_count{};
|
||||
GLsizei stride{};
|
||||
};
|
||||
|
||||
}
|
||||
20
include/opengl/resource_management/reference_counter.hpp
Normal file
20
include/opengl/resource_management/reference_counter.hpp
Normal file
@@ -0,0 +1,20 @@
|
||||
#pragma once
|
||||
|
||||
#include "GL/glew.h"
|
||||
|
||||
namespace zgl
|
||||
{
|
||||
|
||||
class reference_counter
|
||||
{
|
||||
public:
|
||||
using gl_id_type = GLuint;
|
||||
|
||||
virtual void add_reference(gl_id_type id) = 0;
|
||||
|
||||
virtual void remove_reference(gl_id_type id) = 0;
|
||||
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
36
include/opengl/resource_management/resource_handle.hpp
Normal file
36
include/opengl/resource_management/resource_handle.hpp
Normal file
@@ -0,0 +1,36 @@
|
||||
#pragma once
|
||||
|
||||
#include "resource_manager.hpp"
|
||||
|
||||
namespace zgl
|
||||
{
|
||||
|
||||
class resource_handle
|
||||
{
|
||||
public:
|
||||
using id_type = reference_counter::gl_id_type;
|
||||
|
||||
resource_handle() = default;
|
||||
|
||||
inline resource_handle(id_type id, reference_counter* manager);
|
||||
|
||||
resource_handle(const resource_handle& other) = delete;
|
||||
resource_handle& operator=(const resource_handle& other) = delete;
|
||||
|
||||
inline resource_handle(resource_handle&& other) noexcept;
|
||||
inline resource_handle& operator=(resource_handle&& other) noexcept;
|
||||
|
||||
inline ~resource_handle();
|
||||
|
||||
protected:
|
||||
id_type m_id{ 0 };
|
||||
|
||||
private:
|
||||
reference_counter* m_counter{ nullptr };
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#define INCLUDE_RESOURCE_HANDLE_IMPLEMENTATION
|
||||
#include "opengl/resource_management/resource_handle.ipp"
|
||||
#undef INCLUDE_RESOURCE_HANDLE_IMPLEMENTATION
|
||||
55
include/opengl/resource_management/resource_manager.hpp
Normal file
55
include/opengl/resource_management/resource_manager.hpp
Normal file
@@ -0,0 +1,55 @@
|
||||
#pragma once
|
||||
|
||||
#include <mutex>
|
||||
#include <shared_mutex>
|
||||
#include <vector>
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
|
||||
#include "opengl/resource_management/reference_counter.hpp"
|
||||
namespace zgl
|
||||
{
|
||||
|
||||
|
||||
template<typename StoreID, typename MetaData>
|
||||
class resource_manager : public reference_counter
|
||||
{
|
||||
public:
|
||||
using gl_id_type = GLuint;
|
||||
using size_type = std::uint64_t;
|
||||
using resource_entry_type = std::pair<gl_id_type, MetaData>;
|
||||
|
||||
friend class resource_handle;
|
||||
|
||||
bool has_resource(StoreID store_id);
|
||||
|
||||
std::optional<std::pair<resource_handle, MetaData>> get_resource(StoreID store_id);
|
||||
|
||||
void collect_garbage();
|
||||
|
||||
void add_resource(StoreID store_id, gl_id_type gl_id, MetaData meta);
|
||||
|
||||
[[nodiscard]] size_type count_garbage();
|
||||
|
||||
void extract_garbage(std::vector<gl_id_type>& dst);
|
||||
|
||||
void add_reference(gl_id_type id) override;
|
||||
|
||||
void remove_reference(gl_id_type id) override;
|
||||
|
||||
private:
|
||||
static constexpr size_type unused_resource_flag = size_type{ 1 } << (sizeof(size_type) * 8 - 1);
|
||||
|
||||
size_type max_unused_collection_cycle_count;
|
||||
|
||||
std::shared_mutex m_lock;
|
||||
std::unordered_map<StoreID, resource_entry_type> m_resource_lookup;
|
||||
std::unordered_map<gl_id_type, size_type> m_reference_counters;
|
||||
std::unordered_set<gl_id_type> m_unused_handles;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#define INCLUDE_RESOURCE_MANAGER_IMPLEMENTATION
|
||||
#include "opengl/resource_management/resource_manager.ipp"
|
||||
#undef INCLUDE_RESOURCE_MANAGER_IMPLEMENTATION
|
||||
@@ -1,44 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
#include "model_geometry.hpp"
|
||||
#include "shader_stage.hpp"
|
||||
#include "features/mesh_features.hpp"
|
||||
#include "features/point_cloud_features.hpp"
|
||||
#include "features/generic_features.hpp"
|
||||
#include "opengl/shading/model_geometry.hpp"
|
||||
#include "opengl/shading/features/generic_features.hpp"
|
||||
|
||||
namespace zgl::shading
|
||||
{
|
||||
|
||||
struct shader_program_requirements
|
||||
{
|
||||
|
||||
static constexpr auto geometry_bits = static_cast<std::size_t>(std::bit_width(model_geometry::names.size()));
|
||||
static constexpr auto feature_bits = sizeof(features::generic::type) * 8 - geometry_bits;
|
||||
|
||||
explicit shader_program_requirements(const features::mesh::flags mesh_features) :
|
||||
shader_program_requirements(model_geometry::types::mesh, static_cast<features::generic::type>(mesh_features)) {}
|
||||
|
||||
explicit shader_program_requirements(const features::point_cloud::flags point_cloud_features) :
|
||||
shader_program_requirements(model_geometry::types::point_cloud, static_cast<features::generic::type>(point_cloud_features)) {}
|
||||
|
||||
shader_program_requirements(const model_geometry::types geometry_type, const features::generic::type generic_features) :
|
||||
geometry_type{ geometry_type }, features{ generic_features } {}
|
||||
|
||||
|
||||
[[nodiscard]] auto operator<=>(const shader_program_requirements& other) const noexcept
|
||||
{
|
||||
return (
|
||||
std::tie(this->geometry_type, std::popcount(this->features)) <=>
|
||||
std::tie(other.geometry_type, std::popcount(other.features))
|
||||
);
|
||||
}
|
||||
|
||||
[[nodiscard]] bool operator==(const shader_program_requirements& other) const noexcept = default;
|
||||
|
||||
model_geometry::types geometry_type : geometry_bits;
|
||||
features::generic::type features : feature_bits;
|
||||
model_geometry::types geometry;
|
||||
features::generic::type features;
|
||||
};
|
||||
|
||||
}
|
||||
/*
|
||||
struct shader_program_metadata
|
||||
{
|
||||
@@ -83,4 +55,3 @@ struct shader_program_metadata
|
||||
generic_feature_type m_dynamic_enable;
|
||||
};*/
|
||||
|
||||
};
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "opengl/handles/shader_handle.hpp"
|
||||
|
||||
namespace zgl
|
||||
{
|
||||
struct shader_set
|
||||
{
|
||||
shader_handle vertex_shader;
|
||||
shader_handle tesselation_control_shader;
|
||||
shader_handle tesselation_evaluation_shader;
|
||||
shader_handle geometry_shader;
|
||||
shader_handle fragment_shader;
|
||||
};
|
||||
}
|
||||
@@ -28,4 +28,12 @@ inline constexpr auto names = std::array<std::string_view, count>{
|
||||
"fragment"
|
||||
};
|
||||
|
||||
static constexpr auto mandatory = std::array<bool, zgl::shading::stage::count>{
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
55
include/util/reference_counter.hpp
Normal file
55
include/util/reference_counter.hpp
Normal file
@@ -0,0 +1,55 @@
|
||||
#pragma once
|
||||
|
||||
#include <cinttypes>
|
||||
#include <atomic>
|
||||
|
||||
/*
|
||||
* Code taken Daniel Anderson's Talk "When Lock-Free Still Isn't Enough" Slide 28:
|
||||
* https://github.com/CppCon/CppCon2024/blob/main/Presentations/When_Lock-Free_Still_Isn't_Enough.pdf
|
||||
*/
|
||||
|
||||
struct reference_counter
|
||||
{
|
||||
using size_type = std::uint64_t;
|
||||
|
||||
static constexpr size_type bit_count = sizeof(size_type) * 8;
|
||||
static constexpr size_type was_zero_flag = size_type{ 1 } << (bit_count - 1);
|
||||
static constexpr size_type has_helped_flag = size_type{ 1 } << (bit_count - 2);
|
||||
|
||||
bool increment()
|
||||
{
|
||||
const auto prev_count = m_counter.fetch_add(1);
|
||||
return (prev_count & was_zero_flag) == 0;
|
||||
}
|
||||
|
||||
bool decrement()
|
||||
{
|
||||
if (m_counter.fetch_sub(1) == 1)
|
||||
{
|
||||
auto e = size_type{};
|
||||
if (m_counter.compare_exchange_strong(e, was_zero_flag))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if ((e & has_helped_flag) and (m_counter.exchange(was_zero_flag) & has_helped_flag))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
size_type count()
|
||||
{
|
||||
auto value = m_counter.load();
|
||||
if (value == 0 and m_counter.compare_exchange_strong(value, was_zero_flag | has_helped_flag))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return value & was_zero_flag ? 0 : value;
|
||||
}
|
||||
|
||||
private:
|
||||
std::atomic<size_type> m_counter{ 1 };
|
||||
};
|
||||
Reference in New Issue
Block a user