- Continued Texture Implementation

- Began reorganizing the planning document into /planning/
This commit is contained in:
2025-08-04 21:11:22 -04:00
parent ff4d6efedc
commit 4a3639ecb4
14 changed files with 674 additions and 31 deletions

View File

@@ -118,7 +118,7 @@ add_library(fennec STATIC
include/fennec/memory/common.h include/fennec/memory/common.h
include/fennec/memory/memory.h include/fennec/memory/memory.h
include/fennec/memory/pointers.h include/fennec/memory/pointers.h
include/fennec/memory/ptr_traits.h include/fennec/memory/pointer_traits.h
include/fennec/memory/detail/_ptr_traits.h include/fennec/memory/detail/_ptr_traits.h

View File

@@ -44,8 +44,8 @@ namespace fennec
/// ///
/// \details /// \details
/// | Property | Value | /// | Property | Value |
/// |----------|-------------------------| /// |:--------:|:-----------------------:|
/// | stable | \emoji heavy_check_mark | /// | stable | |
/// | access | \f$O(1)\f$ | /// | access | \f$O(1)\f$ |
/// | space | \f$O(N)\f$ | /// | space | \f$O(N)\f$ |
/// ///

View File

@@ -32,7 +32,7 @@
#ifndef FENNEC_MEMORY_ALLOCATOR_H #ifndef FENNEC_MEMORY_ALLOCATOR_H
#define FENNEC_MEMORY_ALLOCATOR_H #define FENNEC_MEMORY_ALLOCATOR_H
#include <fennec/memory/ptr_traits.h> #include <fennec/memory/pointer_traits.h>
#include <fennec/memory/new.h> #include <fennec/memory/new.h>
#include <fennec/lang/conditional_types.h> #include <fennec/lang/conditional_types.h>
@@ -85,7 +85,7 @@ private:
// __diff is substituted using only two template arguments. That one uses 'type = typename AllocT::diff_t' // __diff is substituted using only two template arguments. That one uses 'type = typename AllocT::diff_t'
// however, if it fails, the compiler moves on to the original definition. __size works in the same manner. // however, if it fails, the compiler moves on to the original definition. __size works in the same manner.
template<typename AllocT, typename PtrT, typename = void> template<typename AllocT, typename PtrT, typename = void>
struct __diff { using type = typename ptr_traits<PtrT>::diff_t; }; struct __diff { using type = typename pointer_traits<PtrT>::diff_t; };
template<typename AllocT, typename PtrT> template<typename AllocT, typename PtrT>
struct __diff<AllocT, PtrT, void_t<typename AllocT::diff_t>> { using type = typename AllocT::diff_t; }; struct __diff<AllocT, PtrT, void_t<typename AllocT::diff_t>> { using type = typename AllocT::diff_t; };

View File

@@ -29,12 +29,12 @@ namespace fennec
/// \brief Class for retrieving the traits of Pointer-like types /// \brief Class for retrieving the traits of Pointer-like types
/// \tparam ClassT The Pointer class type /// \tparam ClassT The Pointer class type
template<typename ClassT> template<typename ClassT>
struct ptr_traits struct pointer_traits
: detail::_ptr_traits_impl<ClassT, detail::_ptr_get_element<ClassT>> {}; : detail::_ptr_traits_impl<ClassT, detail::_ptr_get_element<ClassT>> {};
// overload for C-Style Pointers // overload for C-Style Pointers
template<typename ElemT> template<typename ElemT>
struct ptr_traits<ElemT*> : detail::_ptr_traits_ptr_to<ElemT*, ElemT> struct pointer_traits<ElemT*> : detail::_ptr_traits_ptr_to<ElemT*, ElemT>
{ {
using pointer_t = ElemT*; using pointer_t = ElemT*;
using element_t = ElemT; using element_t = ElemT;

View File

@@ -25,10 +25,12 @@
* *
* Requires the following: * Requires the following:
* OpenGL ES 3.2 / OpenGL 4.3 OR * OpenGL ES 3.2 / OpenGL 4.3 OR
* - EXT_texture_array
* - ARB_compute_shader * - ARB_compute_shader
* - ARB_shader_image_load_store * - ARB_shader_image_load_store
* - ARB_shader_storage_buffer_object
* - ARB_texture_cube_map_array * - ARB_texture_cube_map_array
* - ARB_texture_storage
* - EXT_texture_array
* *
* This will support all mobile devices since 2012 * This will support all mobile devices since 2012
*/ */

View File

@@ -29,7 +29,23 @@ namespace fennec
namespace gl namespace gl
{ {
template<GLenum TypeV, GLbitfield FlagsV, GLboolean ImmutableV = false> template<GLbitfield FlagsV, GLboolean ImmutableV> using vertex_buffer = buffer<VERTEX, FlagsV, ImmutableV>;
template<GLbitfield FlagsV, GLboolean ImmutableV> using element_buffer = buffer<ELEMENT, FlagsV, ImmutableV>;
template<GLbitfield FlagsV, GLboolean ImmutableV> using uniform_buffer = buffer<UNIFORM, FlagsV, ImmutableV>;
template<GLbitfield FlagsV, GLboolean ImmutableV> using shader_storage_buffer = buffer<SHADER_STORAGE, FlagsV, ImmutableV>;
template<GLbitfield FlagsV, GLboolean ImmutableV> using query_buffer = buffer<QUERY, FlagsV, ImmutableV>;
template<GLbitfield FlagsV, GLboolean ImmutableV> using texture_buffer = buffer<TEXTURE, FlagsV, ImmutableV>;
template<GLbitfield FlagsV, GLboolean ImmutableV> using transform_feedback_buffer = buffer<TRANSFORM_FEEDBACK, FlagsV, ImmutableV>;
template<GLbitfield FlagsV, GLboolean ImmutableV> using atomic_counter_buffer = buffer<ATOMIC_COUNTER, FlagsV, ImmutableV>;
template<GLbitfield FlagsV, GLboolean ImmutableV> using parameter_buffer = buffer<PARAMETER, FlagsV, ImmutableV>;
template<GLbitfield FlagsV, GLboolean ImmutableV> using indirect_draw_buffer = buffer<INDIRECT_DRAW, FlagsV, ImmutableV>;
template<GLbitfield FlagsV, GLboolean ImmutableV> using indirect_dispatch_buffer = buffer<INDIRECT_DISPATCH, FlagsV, ImmutableV>;
template<GLbitfield FlagsV, GLboolean ImmutableV> using copy_read_buffer = buffer<COPY_READ, FlagsV, ImmutableV>;
template<GLbitfield FlagsV, GLboolean ImmutableV> using copy_write_buffer = buffer<COPY_WRITE, FlagsV, ImmutableV>;
template<GLbitfield FlagsV, GLboolean ImmutableV> using pixel_pack_buffer = buffer<PIXEL_PACK, FlagsV, ImmutableV>;
template<GLbitfield FlagsV, GLboolean ImmutableV> using pixel_unpack_buffer = buffer<PIXEL_UNPACK, FlagsV, ImmutableV>;
template<GLenum TypeV, GLbitfield FlagsV, GLboolean ImmutableV>
class buffer { class buffer {
// HELPER FUNCTIONS ==================================================================================================== // HELPER FUNCTIONS ====================================================================================================
@@ -66,6 +82,7 @@ public:
static constexpr GLenum type = TypeV; static constexpr GLenum type = TypeV;
static constexpr GLboolean immutable = ImmutableV; static constexpr GLboolean immutable = ImmutableV;
static constexpr GLbitfield flags = FlagsV; static constexpr GLbitfield flags = FlagsV;
static constexpr GLboolean indexed = type == ATOMIC_COUNTER or type == SHADER_STORAGE or type == TRANSFORM_FEEDBACK or type == UNIFORM;
static constexpr GLboolean map_read = flags & READ; static constexpr GLboolean map_read = flags & READ;
static constexpr GLboolean map_write = flags & WRITE; static constexpr GLboolean map_write = flags & WRITE;
static constexpr GLboolean mapped = map_read or map_write; static constexpr GLboolean mapped = map_read or map_write;
@@ -91,7 +108,6 @@ public:
} else { } else {
glBufferData(type, _size, data, usage); glBufferData(type, _size, data, usage);
} }
end();
} }
constexpr buffer(buffer&& buff) noexcept constexpr buffer(buffer&& buff) noexcept
@@ -100,8 +116,6 @@ public:
, _mapping(nullptr) { , _mapping(nullptr) {
} }
constexpr buffer(const buffer&) = delete;
constexpr buffer& operator=(buffer&& buff) noexcept { constexpr buffer& operator=(buffer&& buff) noexcept {
glDeleteBuffers(1, &_handle); glDeleteBuffers(1, &_handle);
_handle = buff._handle; _handle = buff._handle;
@@ -109,6 +123,9 @@ public:
return *this; return *this;
} }
constexpr buffer(const buffer&) = delete;
constexpr buffer& operator=(const buffer&) = delete;
// OBJECT FUNCTIONS ==================================================================================================== // OBJECT FUNCTIONS ====================================================================================================
@@ -131,6 +148,11 @@ public:
// BASIC BUFFER FUNCTIONS ============================================================================================== // BASIC BUFFER FUNCTIONS ==============================================================================================
constexpr void resize(GLsizei size) requires not immutable {
unmap();
glBufferData(type, _size = size, nullptr, usage);
}
constexpr void* map(GLbitfield access, GLsizeiptr size, GLintptr offset = 0) { constexpr void* map(GLbitfield access, GLsizeiptr size, GLintptr offset = 0) {
if (_mapping) { if (_mapping) {
return _mapping; return _mapping;

View File

@@ -22,4 +22,18 @@
#include <GL/glew.h> #include <GL/glew.h>
#include <GL/gl.h> #include <GL/gl.h>
namespace fennec
{
namespace gl
{
template<GLenum TypeV, GLbitfield FlagsV, GLboolean ImmutableV = false> class buffer;
template<GLenum TypeV, GLint FormatV, GLboolean ImmutableV> class texture;
}
}
#endif // FENNEC_RENDERERS_OPENGL_LIB_FWD_H #endif // FENNEC_RENDERERS_OPENGL_LIB_FWD_H

View File

@@ -19,6 +19,34 @@
#ifndef FENNEC_RENDERERS_OPENGL_LIB_TEXTURE_H #ifndef FENNEC_RENDERERS_OPENGL_LIB_TEXTURE_H
#define FENNEC_RENDERERS_OPENGL_LIB_TEXTURE_H #define FENNEC_RENDERERS_OPENGL_LIB_TEXTURE_H
/* Because our implementation targets minimum OpenGL ES 3.2,
* we are guaranteed to have the following relevant extensions (Starting from OpenGL ES 3.0):
*
* OES_texture_compression_astc
* EXT_texture_border_clamp
* OES_EGL_image_external_essl3
* ARB_shader_image_load_store
* ARB_stencil_texturing
* ARG_shader_image_size
* ARB_texture_multisample
* ARB_texture_storage_multisample
* ARB_sample_locations
* OES_texture_view
* NV_image_formats
* EXT_render_snorm
* EXT_render_norm16
* EXT_color_buffer_float
* OES_copy_image
* OES_shader_image_atomic
* OES_texture_border_clamp
* OES_texture_buffer
* OES_texture_cube_map_array
* OES_texture_stencil8
* OES_texture_storage_multisample_2d_array
*/
#include <fennec/math/common.h>
#include <fennec/renderers/opengl/lib/fwd.h> #include <fennec/renderers/opengl/lib/fwd.h>
#include <fennec/renderers/opengl/lib/enum.h> #include <fennec/renderers/opengl/lib/enum.h>
@@ -28,34 +56,228 @@ namespace fennec
namespace gl namespace gl
{ {
template<GLint FormatV, GLboolean ImmutableV> using texture1d = texture<TEX_1D, FormatV, ImmutableV>;
template<GLint FormatV, GLboolean ImmutableV> using texture1dv = texture<TEX_1D_V, FormatV, ImmutableV>;
template<GLint FormatV, GLboolean ImmutableV> using texture2d = texture<TEX_2D, FormatV, ImmutableV>;
template<GLint FormatV, GLboolean ImmutableV> using texture2dv = texture<TEX_2D_V, FormatV, ImmutableV>;
template<GLint FormatV, GLboolean ImmutableV> using texture_rect = texture<TEX_RECT, FormatV, ImmutableV>;
template<GLint FormatV, GLboolean ImmutableV> using texture2d_ms = texture<TEX_2D_MS, FormatV, ImmutableV>;
template<GLint FormatV, GLboolean ImmutableV> using texture2dv_ms = texture<TEX_2D_MS_V, FormatV, ImmutableV>;
template<GLint FormatV, GLboolean ImmutableV> using cubemap = texture<TEX_CUBEMAP, FormatV, ImmutableV>;
template<GLint FormatV, GLboolean ImmutableV> using cubemapv = texture<TEX_CUBEMAP_V, FormatV, ImmutableV>;
template<GLint FormatV, GLboolean ImmutableV> using texture3d = texture<TEX_3D, FormatV, ImmutableV>;
template<GLint FormatV, GLboolean ImmutableV> using buffer_texture = texture<TEX_BUFFER, FormatV, ImmutableV>;
///
/// \brief Wrapper for OpenGL Texture Objects
/// \tparam TypeV The type of the texture
/// \tparam FormatV The internal format of the texels
/// \tparam ImmutableV Whether the texture is immutable, i.e. cannot be resized after creation
///
/// \details Immutable textures require EXT_texture_storage or ARB_texture_storage
/// Immutable multisample textures require ARB_texture_storage_multisample of OES_texture_storage_multisample_2d_array
template<GLenum TypeV, GLint FormatV, GLboolean ImmutableV> template<GLenum TypeV, GLint FormatV, GLboolean ImmutableV>
class texture { class texture {
// Constants ===========================================================================================================
public: public:
static constexpr GLenum type = TypeV; static constexpr GLenum type = TypeV;
static constexpr GLint format = FormatV; static constexpr GLint format = FormatV;
static constexpr bool immutable = ImmutableV; static constexpr GLboolean immutable = ImmutableV;
static constexpr bool sampled = TypeV == TEX_2D_MS or TypeV == TEX_2D_MS_V; static constexpr GLboolean is_rect = type == TEX_RECT;
static constexpr bool is_rect = TypeV == TEX_RECT; static constexpr GLboolean is_buffered = type == TEX_BUFFER;
static constexpr bool is_buffered = TypeV == TEX_BUFFER; static constexpr GLboolean sampled = type == TEX_2D_MS or type == TEX_2D_MS_V;
static constexpr bool is_2d = sampled or is_rect or TypeV == TEX_2D or TypeV == TEX_2D_V; static constexpr GLboolean cubemap = type == TEX_CUBEMAP or type == TEX_CUBEMAP_V;
static constexpr bool is_1d = TypeV == TEX_1D or TypeV == TEX_1D_V; static constexpr GLboolean is_1d = type == TEX_1D or type == TEX_1D_V;
static constexpr bool is_array = TypeV == TEX_1D_V or TypeV == TEX_2D_V or TypeV == TEX_2D_MS_V or TypeV == TEX_CUBEMAP_V; static constexpr GLboolean is_2d = sampled or is_rect or type == TEX_2D or type == TEX_2D_V or cubemap;
static constexpr bool has_mipmaps = not(sampled or is_rect or is_buffered); static constexpr GLboolean is_array = TypeV == TEX_1D_V or TypeV == TEX_2D_V or type == TEX_2D_MS_V or type == TEX_CUBEMAP_V;
static constexpr GLboolean is_3d = TypeV == TEX_3D;
static constexpr GLboolean has_mipmaps = not(sampled or is_rect or is_buffered);
texture(GLsizei width, GLint mips, void* data) requires is_1d and not is_array static constexpr GLboolean use_1d = is_1d and not is_array;
static constexpr GLboolean use_2d = (is_2d and not is_array) or (is_1d and is_array) and not sampled;
static constexpr GLboolean use_3d = is_3d or (is_2d and is_array) and not sampled and not cubemap;
static constexpr GLint cubemap_faces = 6;
static constexpr GLenum base_cubemap_face = GL_TEXTURE_CUBE_MAP_POSITIVE_X;
static constexpr GLboolean compressed = type == RGB_DXT1 or type == RGBA_DXT1 or type == RGBA_DXT3 or type == RGBA_DXT5
or type == SRGB_DXT1 or type == SRGBA_DXT1 or type == SRGBA_DXT3 or type == SRGBA_DXT5;
// Constructors ========================================================================================================
///
/// \brief 1D Texture Constructor
/// \param width The width of the texture
/// \param mips The number of mipmap levels
/// \param data A pointer to a buffer containing pixel values, used as an offset if a PIXEL_UNPACK_BUFFER is bound.
/// \param component The type of each component
/// \param layout The layout of components in each pixel
texture(GLsizei width, GLint mips,
void* data = nullptr, GLenum component = BYTE, GLenum layout = R, GLsizei size = 0) requires use_1d
: _handle(NULL) : _handle(NULL)
, _width(width), _height(1), _depth(1) , _width(width), _height(1), _depth(1)
, _samples(1) , _samples(1), _mips(mips) {
, _mips(mips) {
glGenTextures(1, &_handle); glGenTextures(1, &_handle);
start();
if constexpr(immutable) {
glTexStorage1D(type, _mips, format, _width);
glTexSubImage1D(type, 0, 0, _width, layout, component, data);
} else if constexpr(compressed) {
glCompressedTexImage1D(type, 0, format, _width, 0, size, data);
} else {
glTexImage1D(type, 0, format, _width, 0, layout, component, data);
}
genmips();
} }
texture(GLsizei width, GLsizei height, GLint mips) requires is_2d and not (is_array or sampled) or (is_1d and is_array) ///
/// \brief 2D Texture Constructor
/// \param width The width of the texture
/// \param height The height of the texture, or number of layers for arrays
/// \param mips The number of mipmap levels
/// \param data A pointer to a buffer containing pixel values, used as an offset if a PIXEL_UNPACK_BUFFER is bound.
/// \param component The type of each component
/// \param layout The layout of components in each pixel
texture(GLsizei width, GLsizei height, GLint mips,
void* data = nullptr, GLenum component = BYTE, GLenum layout = R, GLsizei size = 0) requires use_2d and not cubemap
: _handle(NULL) : _handle(NULL)
, _width(width), _height(height), _depth(1) , _width(width), _height(height), _depth(1)
, _samples(1) , _samples(1), _mips(mips) {
, _mips(mips) { glGenTextures(1, &_handle);
start();
if constexpr(immutable) {
glTexStorage2D(type, _mips, format, _width, _height);
glTexSubImage2D(type, 0, 0, 0, _width, _height, layout, component, data);
} else if constexpr(compressed) {
glCompressedTexImage2D(type, 0, format, _width, _height, 0, size, data);
} else {
glTexImage2D(type, 0, format, _width, _height, 0, layout, component, data);
} }
}
///
/// \brief 2D Texture Constructor
/// \param width The width of the texture
/// \param height The height of the texture
/// \param depth The depth of the texture, or number of layers for arrays
/// \param mips The number of mipmap levels
/// \param data A pointer to a buffer containing pixel values, used as an offset if a PIXEL_UNPACK_BUFFER is bound.
/// \param component The type of each component
/// \param layout The layout of components in each pixel
texture(GLsizei width, GLsizei height, GLsizei depth, GLsizei mips,
void* data = nullptr, GLenum component = BYTE, GLenum layout = R, GLsizei size = 0) requires use_3d and not cubemap
: _handle(NULL)
, _width(width), _height(height), _depth(depth)
, _samples(1), _mips(mips) {
glGenTextures(1, &_handle);
start();
if constexpr(immutable) {
glTexStorage3D(type, _mips, format, _width, _height, _depth);
glTexSubImage3D(type, 0, 0, 0, 0, _width, _height, _depth, layout, component, data);
} else if constexpr(compressed) {
glCompressedTexImage3D(type, 0, format, _width, _height, _depth, 0, size, data);
} else {
glTexImage3D(type, 0, format, _width, _height, _depth, 0, layout, component, data);
}
}
///
/// \brief 2D Multisample Texture Constructor
/// \param width The width of the texture
/// \param height The height of the texture
/// \param samples The number of samples per pixel
/// \param fixed When true, a fixed set of sample locations is used
texture(GLsizei width, GLsizei height, GLsizei samples, GLboolean fixed = true) requires sampled and not is_array
: _handle(NULL)
, _width(width), _height(height), _depth(1)
, _samples(samples), _mips(0) {
glGenTextures(1, &_handle);
start();
if constexpr(immutable) {
glTexStorage2DMultisample(type, _samples, format, _width, _height, fixed);
} else {
glTexImage2DMultisample(type, _samples, format, _width, _height, fixed);
}
}
///
/// \brief 2D Multisample Array Texture Constructor
/// \param width The width of the texture
/// \param height The height of the texture
/// \param depth The number of layers in the array
/// \param samples The number of samples per pixel
/// \param fixed When true, a fixed set of sample locations is used
texture(GLsizei width, GLsizei height, GLsizei depth, GLsizei samples, GLboolean fixed = true) requires sampled and is_array
: _handle(NULL)
, _width(width), _height(height), _depth(depth)
, _samples(samples), _mips(0) {
glGenTextures(1, &_handle);
start();
if constexpr(immutable) {
glTexStorage3DMultisample(type, _samples, format, _width, _height, _depth, fixed);
} else {
glTexImage3DMultisample(type, _samples, format, _width, _height, _depth, fixed);
}
}
///
/// \brief Cubemap Constructor
/// \param size The size of each face texture
/// \param mips The number of mipmap layers
/// \param faces An array of pointers to textures containing pixel data for each face
/// \param component The component type of the data
/// \param layout The layout of the components in the pixel
texture(GLsizei size, GLsizei mips,
const void* faces[6], GLenum component = BYTE, GLenum layout = R, GLsizei size = 0) requires is_2d and cubemap
: _handle(NULL)
, _width(size), _height(size), _depth(1)
, _samples(1), _mips(mips) {
glGenTextures(1, &_handle);
start();
if constexpr(immutable) {
glTexStorage2D(type, _mips, format, _width, _height);
for (int i = 0; i < cubemap_faces; ++i) {
glTexSubImage2D(base_cubemap_face + i, 0, 0, 0, _width, _height, layout, component, faces[i]);
}
} else if constexpr(compressed) {
} else {
for (int i = 0; i < cubemap_faces; ++i) {
glTexImage2D(base_cubemap_face + i, 0, format, _width, _height, 0, layout, component, faces[i]);
}
}
}
///
/// \brief Cubemap Array Constructor
/// \param size The size of each face texture
/// \param depth The number of layers in the array
/// \param mips The number of mipmap layers
/// \param data A pointer to a buffer containing image data
/// \param component The component type of the data
/// \param layout The layout of the components in the pixel
///
/// \details Requires OES_texture_cube_map_array
texture(GLsizei size, GLsizei depth, GLsizei mips,
const void* data, GLenum component = BYTE, GLenum layout = R, GLsizei size = 0) requires is_2d and cubemap
: _handle(NULL)
, _width(size), _height(size), _depth(depth)
, _samples(1), _mips(mips) {
glGenTextures(1, &_handle);
start();
if constexpr(immutable) {
glTexStorage3D(type, _mips, format, _width, _height, _depth * 6);
glTexSubImage3D(type, 0, 0, 0, 0, _width, _height, _depth * 6, layout, component, data);
} else if constexpr(compressed) {
} else {
glTexImage3D(type, 0, format, _width, _height, _depth * 6, 0, layout, component, data);
}
}
// Basic Functions =====================================================================================================
void start() { void start() {
glBindTexture(type, _handle); glBindTexture(type, _handle);
@@ -70,6 +292,10 @@ public:
start(); start();
} }
void genmips() {
glGenerateMipmap(type);
}
private: private:
GLuint _handle; GLuint _handle;
GLsizei _width; GLsizei _width;
@@ -83,4 +309,4 @@ private:
} }
#endif // FENNEC_RENDERERS_OPENGL_TEXTURE_H #endif // FENNEC_RENDERERS_OPENGL_LIB_TEXTURE_H

17
planning/CONTAINERS.md Normal file
View File

@@ -0,0 +1,17 @@
# Containers Library (`containers`)
## Table of Contents
## Introduction
&ensp; This library contains headers and classes that implement common data
structures. The contents are restricted to the Containers Library of the C++
Standard Library and Template Library.
## Implementation

64
planning/CONTENTS.md Normal file
View File

@@ -0,0 +1,64 @@
# Planning Documentation for fennec
## Table of Contents
<!-- TOC -->
* [Planning Documentation for fennec](#planning-documentation-for-fennec)
* [Table of Contents](#table-of-contents)
* [Introduction](#introduction)
* [Definitions](#definitions)
* [Libraries](#libraries)
* [C++ Language Library](./CPP_LANGUAGE.md#c-language-library-lang)
* [Platform Support Library](./PLATFORM_SUPPORT.md#platform-support-library-platform)
<!-- TOC -->
## Introduction
&ensp; These files serve as general planning documentation for engine structure, systems,
pipelines, and implementation.
&ensp; Implementations of core engine systems should strive to be `O(1)` in
implementations, both in terms of runtime and memory performance. This is obviously
not a realistic goal, so rather than the goal requiring the entire engine to be `O(1)`,
we should more specifically look at achieving `O(1)` performance on hot paths.
I distinctly use 'strive' and 'goal' as different concepts, where designs should
*strive* to accommodate function implementations for `O(1)`, however the specifics
of the implementation might not always be able to achieve that, so the end *goal* is
that hot paths should be `O(1)`.
&ensp; Functions should be highly verbose and any bugprone or erroneous behaviour should
throw assertions. **DO NOT USE EXCEPTIONS**.
&ensp; System implementations should be independent of architecture or platforms. i.e.
the code of the graphics system should not care if OpenGL or Vulkan is used and should
not use any direct calls to OpenGL or Vulkan.
&ensp; The engine should not care about the types of objects loaded from a so/dll. In
fact, most of the code should be type independent. Any shared information among a
collection of objects should be held either implicitly or explicitly in the super-class.
It will be the responsibility of the linked code to initialize and cleanup the objects
related to it. This principle should extend to the submodules of the engine.
&ensp; It is also best to avoid objects having behaviour that is not defined by the system
they are in. There are some exceptions in extensions or mods, which should be given
configurability and programmability within those systems and their stages. This can
be achieved using events at different stages of those engines that are on-demand.
## Definitions
&ensp; Many subpages of these documents will contain tables that use symbols to
denote implementation and testing progress. The symbols are defined below.
| Symbol | Meaning |
|:-------:|:------------------------|
| ✔ | Completed |
| ❓ | Partial |
| ❌ | Unimplemented / Failing |
## Libraries
- [C++ Language Library](./CPP_LANGUAGE.md#c-language-library-lang)
- [Platform Support Library](./PLATFORM_SUPPORT.md#platform--api-support)

204
planning/CPP_LANGUAGE.md Normal file
View File

@@ -0,0 +1,204 @@
# C++ Language Library (`lang`)
## Table of Contents
<!-- TOC -->
* [Home](./CONTENTS.md#planning-documentation-for-fennec)
* [C++ Language Library (`lang`)](#c-language-library-lang)
* [Table of Contents](#table-of-contents)
* [Introduction](#introduction)
* [Implementation](#implementation)
* [Diagnostics](#diagnostics)
* [Utility](#utility)
* [Primary Types](#primary-types)
* [Composite Types](#composite-types)
* [Type Properties](#type-properties)
* [Supported Operations](#supported-operations)
* [Property Queries](#property-queries)
* [Type Relationships](#type-relationships)
* [Type Transformations](#type-transformations)
* [Other Transformations](#other-transformations)
* [Logical Operations](#logical-operations)
* [Sequences](#sequences)
<!-- TOC -->
## Introduction
&ensp; This library contains headers and classes related to the C++ language. The
contents of this library are restricted to the Language Support, Diagnostics, and
Metaprogramming libraries of the C++ Standard Library and Template Library.
See:
- [Language Support Library](https://cppreference.com/w/cpp/utility.html#Language_support)
- Basic Memory Management is handled in the [Memory Library](./MEMORY_LIBRARY.md#)
- [Diagnostics Library](https://cppreference.com/w/cpp/error.html)
- [Metaprogramming Library](https://cppreference.com/w/cpp/meta.html)
## Implementation
### Diagnostics
| Symbol | Implemented | Passed |
|:--------|:-----------:|:------:|
| assert | ✔ | ✔ |
| assertf | ✔ | ✔ |
| assertd | ✔ | ✔ |
### Utility
| Symbol | Implemented | Passed |
|:-----------------|:-----------:|:------:|
| numeric_limits | ✔ | ✔ |
| initializer_list | ❌ | ❌ |
### Primary Types
| Symbol | Implemented | Passed |
|:---------------------------|:-----------:|:------:|
| is_void | ✔ | ✔ |
| is_null_pointer | ✔ | ✔ |
| is_integral | ✔ | ✔ |
| is_floating_point | ✔ | ✔ |
| is_array | ✔ | ❓ |
| is_enum | ❌ | ❌ |
| is_union | ❌ | ❌ |
| is_class | ✔ | ✔ |
| is_function | ❌ | ❌ |
| is_pointer | ✔ | ✔ |
| is_lvalue_reference | ✔ | ✔ |
| is_rvalue_reference | ✔ | ✔ |
| is_member_object_pointer | ❌ | ❌ |
| is_member_function_pointer | ❌ | ❌ |
### Composite Types
| Symbol | Implemented | Passed |
|:------------------|:-----------:|:------:|
| is_fundamental | ✔ | ✔ |
| is_arithmetic | ✔ | ✔ |
| is_scalar | ❌ | ❌ |
| is_object | ❌ | ❌ |
| is_compound | ❌ | ❌ |
| is_reference | ❌ | ❌ |
| is_member_pointer | ❌ | ❌ |
### Type Properties
| Symbol | Implemented | Passed |
|:----------------------------------|:-----------:|:------:|
| is_const | ✔ | ✔ |
| is_volatile | ✔ | ✔ |
| is_trivially_copyable | ✔ | ✔ |
| is_standard_layout | ❌ | ❌ |
| has_unique_object_representations | ❌ | ❌ |
| is_empty | ❌ | ❌ |
| is_polymorphic | ❌ | ❌ |
| is_abstract | ❌ | ❌ |
| is_final | ❌ | ❌ |
| is_aggregate | ❌ | ❌ |
| is_implicit_lifetime | ❌ | ❌ |
| is_signed | ✔ | ✔ |
| is_unsigned | ✔ | ✔ |
| is_bounded_array | ❌ | ❌ |
| is_unbounded_array | ❌ | ❌ |
| is_scoped_enum | ❌ | ❌ |
### Supported Operations
| Symbol | Implemented | Passed |
|:------------------------------------|:-----------:|:------:|
| is_constructible | ✔ | ✔ |
| is_trivially_constructible | ✔ | ✔ |
| is_nothrow_constructible | ❌ | ❌ |
| is_default_constructible | ✔ | ✔ |
| is_trivially_default_constructible | ❌ | ❌ |
| is_nothrow_default_constructible | ❌ | ❌ |
| is_copy_constructible | ✔ | ✔ |
| is_trivially_copy_constructible | ❌ | ❌ |
| is_nothrow_copy_constructible | ❌ | ❌ |
| is_move_constructible | ✔ | ✔ |
| is_trivially_move_constructible | ❌ | ❌ |
| is_nothrow_move_constructible | ❌ | ❌ |
| is_destructible | ❌ | ❌ |
| is_trivially_destructible | ❌ | ❌ |
| is_nothrow_destructible | ❌ | ❌ |
| has_virtual_destructor | ❌ | ❌ |
| is_swappable | ❌ | ❌ |
| is_swappable_with | ❌ | ❌ |
| is_nothrow_swappable | ❌ | ❌ |
| is_nothrow_swappable_with | ❌ | ❌ |
| reference_constructs_from_temporary | ❌ | ❌ |
| reference_converts_from_temporary | ❌ | ❌ |
### Property Queries
| Symbol | Implemented | Passed |
|:-------------|:-----------:|:------:|
| alignment_of | ❌ | ❌ |
| rank | ❌ | ❌ |
| extent | ❌ | ❌ |
### Type Relationships
| Symbol | Implemented | Passed |
|:------------------------------------|:-----------:|:------:|
| is_same | ✔ | ✔ |
| is_base_of | ❌ | ❌ |
| is_virtual_base_of | ❌ | ❌ |
| is_convertible | ✔ | ✔ |
| is_nothrow_convertible | ❌ | ❌ |
| is_layout_compatible | ❌ | ❌ |
| is_pointer_interconvertible_base_of | ❌ | ❌ |
| is_invocable | ❌ | ❌ |
| is_invocable_r | ❌ | ❌ |
| is_nothrow_invocable | ❌ | ❌ |
| is_nothrow_invocable_r | ❌ | ❌ |
### Type Transformations
| Symbol | Implemented | Passed |
|:---------------------|:-----------:|:------:|
| add_const | ✔ | ✔ |
| add_volatile | ✔ | ✔ |
| add_cv | ✔ | ✔ |
| remove_const | ✔ | ✔ |
| remove_volatile | ✔ | ✔ |
| remove_cv | ✔ | ✔ |
| add_lvalue_reference | ✔ | ✔ |
| add_rvalue_reference | ✔ | ✔ |
| remove_reference | ✔ | ✔ |
| add_pointer | ✔ | ✔ |
| remove_pointer | ✔ | ✔ |
| make_signed | ✔ | ✔ |
| make_unsigned | ✔ | ✔ |
| remove_extent | ❌ | ❌ |
| remove_all_extents | ❌ | ❌ |
### Other Transformations
| Symbol | Implemented | Passed |
|:-----------------------|:-----------:|:------:|
| aligned_storage | ❌ | ❌ |
| aligned_union | ❌ | ❌ |
| aligned_union | ❌ | ❌ |
| decay | ⭕ | ⭕ |
| remove_cvref | ✔ | ✔ |
| enable_if | ✔ | ✔ |
| conditional | ✔ | ✔ |
| common_type | ❌ | ❌ |
| common_reference | ❌ | ❌ |
| basic_common_reference | ❌ | ❌ |
| underlying_type | ❌ | ❌ |
| result_of | ❌ | ❌ |
| invoke_result | ❌ | ❌ |
| void_t | ✔ | ✔ |
### Logical Operations
| Symbol | Implemented | Passed |
|:------------|:-----------:|:------:|
| conjunction | ❌ | ❌ |
| disjunction | ❌ | ❌ |
| negation | ❌ | ❌ |
### Sequences
| Symbol | Implemented | Passed |
|:----------------------|:-----------:|:------:|
| sequence | ✔ | ✔ |
| integer_sequence | ✔ | ✔ |
| make_integer_sequence | ✔ | ✔ |
| index_sequence | ✔ | ✔ |
| make_index_sequence | ✔ | ✔ |
| concat_sequence | ✔ | ✔ |

33
planning/MEMORY.md Normal file
View File

@@ -0,0 +1,33 @@
# Memory Library (`memory`)
## Table of Contents
<!-- TOC -->
* [Home](./CONTENTS.md#planning-documentation-for-fennec)
* [Memory Library (`memory`)](#memory-library-memory)
* [Table of Contents](#table-of-contents)
* [Introduction](#introduction)
* [Implementation](#implementation)
<!-- TOC -->
## Introduction
&ensp; This library contains headers and classes related to memory allocation and
management in C++. The contents are restricted to the Memory Management Library of
the C++ Standard Library and Template Library. This pulls some functions from the
C stdlib and either wraps them or aliases them.
## Implementation
| Symbol | Implemented | Passed |
|:-----------------|:-----------:|:------:|
| allocator | ✔ | ✔ |
| allocator_traits | ✔ | ✔ |
| allocation | ✔ | ✔ |
| default_delete | ✔ | ❓ |
| unique_pointer | ✔ | ❓ |
| shared_pointer | ❌ | ❌ |
| pointer_traits | ❌ | ❌ |

View File

@@ -0,0 +1,61 @@
# Platform Support Library (`platform`)
## Table of Contents
<!-- TOC -->
* [Home](./CONTENTS.md#planning-documentation-for-fennec)
* [Platform Support Library (`platform`)](#platform-support-library-platform)
* [Table of Contents](#table-of-contents)
* [Introduction](#introduction)
* [Implementation](#implementation)
* [Consoles](#consoles)
<!-- TOC -->
## Introduction
&ensp; The platform support library will include headers, functions, and classes related
to supporting various platforms. Platforms may be defined as any Hardware, OS, or
Drivers that must be initialized for the engine context.
## Implementation
Platform Support will be implemented in the following order:
- Linux/BSD
- Wayland
- OpenGL (EGL) ✔
- XKB
- PulseAudio
- Vulkan
- X11
- ALSA
- Vulkan
- Microsoft Windows
- XInput
- OpenGL (WGL)
- WASAPI
- Vulkan
- Android
- OpenGL ES
- AAudio
- openslES
- macOS/iOS
- cocoa
- OpenGL
- Core Audio
- Vulkan
- Metal
&ensp; Linux Wayland will be implemented first. Once setup, the core engine will be
implemented and tested on top of Wayland. Once the engine is in a stable state,
then support for other platforms will be resumed.
## Consoles
&ensp; Most consoles will never get official platform support due to NDAs which conflict
with the principles of this engine. fennec will avoid using proprietary libraries except
when strictly necessary, such as support for Windows and MacOS. fennec will interact
with any drivers required for the listed operating systems above, even if proprietary.