Fixed bugs in lazy shader compilation.

This commit is contained in:
zy4n
2025-03-03 20:45:30 +01:00
parent 925125e99b
commit fde6a2fd7b
26 changed files with 234 additions and 321 deletions

View File

@@ -181,6 +181,8 @@ add_executable(z3d main.cpp
include/opengl/data_uploaders/shader_program_compiler.hpp
include/shader_program/metadata_type.hpp
source/opengl/data_uploaders/shader_compiler.cpp
include/shader_program/geometry.hpp
include/shader_program/stage.hpp
)
target_include_directories(z3d PRIVATE include)

View File

@@ -22,7 +22,8 @@ inline constexpr type color = 3;
inline constexpr type reflectance = 4;
}
enum class flags : std::uint8_t {
enum class flags : std::uint8_t
{
none = 0,
position = 1 << indices::position,
normal = 1 << indices::normal,

View File

@@ -20,7 +20,8 @@ inline constexpr type color = 2;
inline constexpr type reflectance = 3;
} // namespace indices
enum class flags : std::uint8_t {
enum class flags : std::uint8_t
{
none = 0,
position = 1 << indices::position,
normal = 1 << indices::normal,

View File

@@ -11,7 +11,8 @@ using green = std::uint8_t;
using blue = std::uint8_t;
using luminance = std::uint8_t;
enum class flags : std::uint8_t {
enum class flags : std::uint8_t
{
none = 0,
luminance = 1 << 1,
red = 1 << 2,

View File

@@ -3,6 +3,7 @@
#include "assets/components/material_components.hpp"
#include "assets/components/mesh_vertex_components.hpp"
#include "shader_program/features/mesh_features.hpp"
#include "util/enum_bitfield_operators.hpp"
#include <array>
@@ -11,16 +12,16 @@ namespace rendering::requirements::mesh
struct type
{
shader_program::capabilities::mesh::indices::type shader_program_requirement_index{};
shader_program::features::mesh::indices::type shader_program_requirement_index{};
components::mesh_vertex::flags vertex_requirements{
components::mesh_vertex::flags::none
};
material_component::flags material_requirements{
material_component::flags::none
components::material::flags material_requirements{
components::material::flags::none
};
};
enum class flags : int
enum class flags : std::uint8_t
{
none = 0,
position = 1 << 0,
@@ -32,33 +33,33 @@ enum class flags : int
};
constexpr inline auto position = type{
.shader_program_requirement_index = shader_program::capabilities::mesh::indices::position,
.shader_program_requirement_index = shader_program::features::mesh::indices::position,
.vertex_requirements = components::mesh_vertex::flags::position
};
constexpr inline auto lit = type{
.shader_program_requirement_index = shader_program::capabilities::mesh::indices::lit,
.shader_program_requirement_index = shader_program::features::mesh::indices::lit,
.vertex_requirements = components::mesh_vertex::flags::normal,
.material_requirements = material_component::flags::surface_properties
.material_requirements = components::material::flags::surface_properties
};
constexpr inline auto point = type{
.shader_program_requirement_index = shader_program::capabilities::mesh::indices::point
.shader_program_requirement_index = shader_program::features::mesh::indices::point
};
constexpr inline auto textured = type{
.shader_program_requirement_index = shader_program::capabilities::mesh::indices::textured,
.shader_program_requirement_index = shader_program::features::mesh::indices::textured,
.vertex_requirements = components::mesh_vertex::flags::tex_coord,
.material_requirements = material_component::flags::texture,
.material_requirements = components::material::flags::texture,
};
constexpr inline auto uniform_color = type{
.shader_program_requirement_index = shader_program::capabilities::mesh::indices::uniform_color
.shader_program_requirement_index = shader_program::features::mesh::indices::uniform_color
};
constexpr inline auto uniform_alpha = type{
.shader_program_requirement_index = shader_program::capabilities::mesh::indices::uniform_alpha,
.material_requirements = material_component::flags::transparency
.shader_program_requirement_index = shader_program::features::mesh::indices::uniform_alpha,
.material_requirements = components::material::flags::transparency
};
constexpr inline auto all = std::array{
@@ -67,61 +68,4 @@ constexpr inline auto all = std::array{
}
[[nodiscard]] constexpr rendering::requirements::mesh::flags operator|(
const rendering::requirements::mesh::flags& a, const rendering::requirements::mesh::flags& b
) {
return static_cast<rendering::requirements::mesh::flags>(static_cast<int>(a) | static_cast<int>(b));
}
[[nodiscard]] constexpr rendering::requirements::mesh::flags operator&(
const rendering::requirements::mesh::flags& a, const rendering::requirements::mesh::flags& b
) {
return static_cast<rendering::requirements::mesh::flags>(static_cast<int>(a) & static_cast<int>(b));
}
[[nodiscard]] constexpr rendering::requirements::mesh::flags operator^(
const rendering::requirements::mesh::flags& a, const rendering::requirements::mesh::flags& b
) {
return static_cast<rendering::requirements::mesh::flags>(static_cast<int>(a) ^ static_cast<int>(b));
}
[[nodiscard]] constexpr rendering::requirements::mesh::flags operator~(const rendering::requirements::mesh::flags& a) {
return static_cast<rendering::requirements::mesh::flags>(~static_cast<int>(a));
}
constexpr rendering::requirements::mesh::flags& operator|=(rendering::requirements::mesh::flags& a, const rendering::requirements::mesh::flags& b) {
return a = a | b;
}
constexpr rendering::requirements::mesh::flags& operator&=(rendering::requirements::mesh::flags& a, const rendering::requirements::mesh::flags& b) {
return a = a & b;
}
constexpr rendering::requirements::mesh::flags& operator^=(rendering::requirements::mesh::flags& a, const rendering::requirements::mesh::flags& b) {
return a = a ^ b;
}
[[nodiscard]] constexpr bool operator<(
rendering::requirements::mesh::flags lhs, rendering::requirements::mesh::flags rhs
) {
return static_cast<int>(lhs) < static_cast<int>(rhs);
}
[[nodiscard]] constexpr bool operator<=(
rendering::requirements::mesh::flags lhs, rendering::requirements::mesh::flags rhs
) {
return static_cast<int>(lhs) <= static_cast<int>(rhs);
}
[[nodiscard]] constexpr bool operator>(
rendering::requirements::mesh::flags lhs, rendering::requirements::mesh::flags rhs
) {
return static_cast<int>(lhs) > static_cast<int>(rhs);
}
[[nodiscard]] constexpr bool operator>=(
rendering::requirements::mesh::flags lhs, rendering::requirements::mesh::flags rhs
) {
return static_cast<int>(lhs) >= static_cast<int>(rhs);
}
DEFINE_ENUM_BITFIELD_OPERATORS(rendering::requirements::mesh::flags)

View File

@@ -4,20 +4,21 @@
#include "shader_program/features/point_cloud_features.hpp"
#include <array>
#include "util/enum_bitfield_operators.hpp"
namespace rendering::requirements::point_cloud
{
struct type
{
shader_program::capabilities::point_cloud::indices::type shader_program_requirement_index{};
shader_program::features::point_cloud::indices::type shader_program_requirement_index{};
components::point_cloud_vertex::flags vertex_requirements{
components::point_cloud_vertex::flags::none
};
};
enum class flags : int
enum class flags : std::uint8_t
{
none = 0,
position = 1 << 0,
@@ -30,30 +31,30 @@ enum class flags : int
constexpr inline auto position = type{
.shader_program_requirement_index = shader_program::capabilities::point_cloud::indices::position,
.shader_program_requirement_index = shader_program::features::point_cloud::indices::position,
.vertex_requirements = components::point_cloud_vertex::flags::position
};
constexpr inline auto rainbow = type{
.shader_program_requirement_index = shader_program::capabilities::point_cloud::indices::rainbow
.shader_program_requirement_index = shader_program::features::point_cloud::indices::rainbow
};
constexpr inline auto vertex_color = type{
.shader_program_requirement_index = shader_program::capabilities::point_cloud::indices::vertex_color,
.shader_program_requirement_index = shader_program::features::point_cloud::indices::vertex_color,
.vertex_requirements = components::point_cloud_vertex::flags::color
};
constexpr inline auto uniform_color = type{
.shader_program_requirement_index = shader_program::capabilities::point_cloud::indices::uniform_color
.shader_program_requirement_index = shader_program::features::point_cloud::indices::uniform_color
};
constexpr inline auto normal = type{
.shader_program_requirement_index = shader_program::capabilities::point_cloud::indices::normal,
.shader_program_requirement_index = shader_program::features::point_cloud::indices::normal,
.vertex_requirements = components::point_cloud_vertex::flags::normal
};
constexpr inline auto reflectance = type{
.shader_program_requirement_index = shader_program::capabilities::point_cloud::indices::reflectance,
.shader_program_requirement_index = shader_program::features::point_cloud::indices::reflectance,
.vertex_requirements = components::point_cloud_vertex::flags::reflectance
};
@@ -62,61 +63,4 @@ constexpr inline auto all = std::array{
};
}
[[nodiscard]] constexpr rendering::requirements::point_cloud::flags operator|(
const rendering::requirements::point_cloud::flags& a, const rendering::requirements::point_cloud::flags& b
) {
return static_cast<rendering::requirements::point_cloud::flags>(static_cast<int>(a) | static_cast<int>(b));
}
[[nodiscard]] constexpr rendering::requirements::point_cloud::flags operator&(
const rendering::requirements::point_cloud::flags& a, const rendering::requirements::point_cloud::flags& b
) {
return static_cast<rendering::requirements::point_cloud::flags>(static_cast<int>(a) & static_cast<int>(b));
}
[[nodiscard]] constexpr rendering::requirements::point_cloud::flags operator^(
const rendering::requirements::point_cloud::flags& a, const rendering::requirements::point_cloud::flags& b
) {
return static_cast<rendering::requirements::point_cloud::flags>(static_cast<int>(a) ^ static_cast<int>(b));
}
[[nodiscard]] constexpr rendering::requirements::point_cloud::flags operator~(const rendering::requirements::point_cloud::flags& a) {
return static_cast<rendering::requirements::point_cloud::flags>(~static_cast<int>(a));
}
constexpr rendering::requirements::point_cloud::flags& operator|=(rendering::requirements::point_cloud::flags& a, const rendering::requirements::point_cloud::flags& b) {
return a = a | b;
}
constexpr rendering::requirements::point_cloud::flags& operator&=(rendering::requirements::point_cloud::flags& a, const rendering::requirements::point_cloud::flags& b) {
return a = a & b;
}
constexpr rendering::requirements::point_cloud::flags& operator^=(rendering::requirements::point_cloud::flags& a, const rendering::requirements::point_cloud::flags& b) {
return a = a ^ b;
}
[[nodiscard]] constexpr bool operator<(
rendering::requirements::point_cloud::flags lhs, rendering::requirements::point_cloud::flags rhs
) {
return static_cast<int>(lhs) < static_cast<int>(rhs);
}
[[nodiscard]] constexpr bool operator<=(
rendering::requirements::point_cloud::flags lhs, rendering::requirements::point_cloud::flags rhs
) {
return static_cast<int>(lhs) <= static_cast<int>(rhs);
}
[[nodiscard]] constexpr bool operator>(
rendering::requirements::point_cloud::flags lhs, rendering::requirements::point_cloud::flags rhs
) {
return static_cast<int>(lhs) > static_cast<int>(rhs);
}
[[nodiscard]] constexpr bool operator>=(
rendering::requirements::point_cloud::flags lhs, rendering::requirements::point_cloud::flags rhs
) {
return static_cast<int>(lhs) >= static_cast<int>(rhs);
}
DEFINE_ENUM_BITFIELD_OPERATORS(rendering::requirements::point_cloud::flags)

View File

@@ -8,7 +8,8 @@
namespace shader_program::attributes::mesh
{
enum class flags : unsigned {
enum class flags : std::uint8_t
{
none = 0,
position = 1 << 0,
normal = 1 << 1,

View File

@@ -8,7 +8,8 @@
namespace shader_program::attributes::point_cloud
{
enum class flags : unsigned {
enum class flags : std::uint8_t
{
none = 0,
position = 1 << 0,
normal = 1 << 1,

View File

@@ -35,7 +35,7 @@ constexpr inline type texture = 7;
constexpr inline type uniform_color = 8;
}
enum class flags : unsigned
enum class flags : std::uint16_t
{
none = 0,
face = 1 << indices::face,
@@ -46,7 +46,7 @@ enum class flags : unsigned
alpha = 1 << indices::alpha,
lighting = 1 << indices::lighting,
texture = 1 << indices::texture,
uniform_color = 1 << indices::uniform_color,
uniform_color = 1 << indices::uniform_color
};
constexpr inline auto face = type{

View File

@@ -33,7 +33,7 @@ constexpr inline type uniform_color = 5;
constexpr inline type rainbow = 6;
}
enum class flags : unsigned
enum class flags : std::uint8_t
{
none = 0,
square = 1 << indices::square,

View File

@@ -0,0 +1,21 @@
#pragma once
#include <cinttypes>
#include <array>
#include <string_view>
namespace shader_program::geometry
{
enum class types : std::uint8_t
{
mesh = 0,
point_cloud = 1
};
inline constexpr auto names = std::array<std::string_view, 2>{
"mesh", "point_cloud"
};
}

View File

@@ -3,28 +3,14 @@
#include <limits>
#include <utility>
#include "geometry.hpp"
#include "stage.hpp"
#include "features/mesh_features.hpp"
#include "features/point_cloud_features.hpp"
namespace shader_program
{
enum class geometries : int
{
mesh = 0,
point_cloud = 1
};
enum class stages : GLenum
{
vertex = GL_VERTEX_SHADER,
geometry = GL_GEOMETRY_SHADER,
fragment = GL_FRAGMENT_SHADER
};
union combined_feature_type
{
features::mesh::flags mesh;
@@ -35,185 +21,164 @@ union combined_feature_type
std::underlying_type_t<features::point_cloud::flags>
>;
generic_type generic(const geometries geometry) const noexcept
[[nodiscard]] generic_type generic(const geometry::types geometry) const noexcept
{
switch (geometry)
{
case geometries::mesh:
case geometry::types::mesh:
return static_cast<generic_type>(mesh);
case geometries::point_cloud:
case geometry::types::point_cloud:
return static_cast<generic_type>(point_cloud);
}
std::unreachable();
}
void from_generic(
const geometries geometry,
const geometry::types geometry,
generic_type new_features
) noexcept {
switch (geometry)
{
case geometries::mesh:
case geometry::types::mesh:
mesh = static_cast<features::mesh::flags>(new_features);
case geometries::point_cloud:
case geometry::types::point_cloud:
point_cloud = static_cast<features::point_cloud::flags>(new_features);
}
std::unreachable();
}
};
template<typename T>
struct shader_features_set
{
T features, static_enable, dynamic_enable;
template<typename U>
[[nodiscard]] shader_features_set<U> cast() const noexcept
{
return {
.features = static_cast<U>(features),
.static_enable = static_cast<U>(static_enable),
.dynamic_enable = static_cast<U>(dynamic_enable)
};
}
[[nodiscard]] auto operator<=>(const shader_features_set& other) const noexcept requires std::unsigned_integral<T>
{
std::array<T, 6> pop_counts;
std::ranges::transform(
{
this->features, this->static_enable, this->dynamic_enable,
other.features, other.static_enable, other.dynamic_enable
},
pop_counts.begin(),
std::popcount<T>
);
return (
std::tie(pop_counts[0], pop_counts[1], pop_counts[2]) <=>
std::tie(pop_counts[3], pop_counts[4], pop_counts[5])
);
}
[[nodiscard]] auto operator<=>(const shader_features_set& other) const noexcept requires std::is_enum_v<T>
{
using integer_type = std::underlying_type_t<T>;
return this->cast<integer_type>() <=> other.cast<integer_type>();
}
// TODO this may not compile
[[nodiscard]] bool operator==(const shader_features_set& other) const noexcept = default;
};
struct metadata_type
{
geometries geometry;
stages stage;
combined_feature_type features;
combined_feature_type feature_toggles;
union combined_feature_set_type {
shader_features_set<features::mesh::flags> mesh;
shader_features_set<features::point_cloud::flags> point_cloud;
};
std::pair<combined_feature_type::generic_type, combined_feature_type::generic_type> generic() const noexcept
using generic_feature_type = std::common_type_t<
std::underlying_type_t<features::mesh::flags>,
std::underlying_type_t<features::point_cloud::flags>
>;
using generic_feature_set_type = shader_features_set<generic_feature_type>;
stage::types stage;
geometry::types geometry;
combined_feature_set_type feature_set;
[[nodiscard]] generic_feature_set_type generic_feature_set() const noexcept
{
switch (geometry)
{
case geometries::mesh:
return {
static_cast<combined_feature_type::generic_type>(features.mesh),
static_cast<combined_feature_type::generic_type>(feature_toggles.mesh)
};
case geometries::point_cloud:
return {
static_cast<combined_feature_type::generic_type>(features.point_cloud),
static_cast<combined_feature_type::generic_type>(feature_toggles.point_cloud)
};
case geometry::types::mesh:
return feature_set.mesh.cast<generic_feature_type>();
case geometry::types::point_cloud:
return feature_set.point_cloud.cast<generic_feature_type>();
default:
std::unreachable();
}
std::unreachable();
}
void from_generic(
combined_feature_type::generic_type new_features,
combined_feature_type::generic_type new_feature_toggles
) noexcept {
void from_generic_feature_set(const generic_feature_set_type& generic_feature_set) noexcept
{
switch (geometry)
{
case geometries::mesh:
features.mesh = static_cast<features::mesh::flags>(new_features);
feature_toggles.mesh = static_cast<features::mesh::flags>(new_feature_toggles);
case geometries::point_cloud:
features.point_cloud = static_cast<features::point_cloud::flags>(new_features);
feature_toggles.point_cloud = static_cast<features::point_cloud::flags>(new_feature_toggles);
case geometry::types::mesh:
feature_set.mesh = generic_feature_set.cast<features::mesh::flags>();
case geometry::types::point_cloud:
feature_set.point_cloud = generic_feature_set.cast<features::point_cloud::flags>();
}
std::unreachable();
}
auto operator<=>(const metadata_type& other) const noexcept
{
if (this->geometry == other.geometry)
if (this->stage != other.stage)
{
switch (this->geometry)
{
case geometries::mesh:
return (
std::tie(this->stage, this->features.mesh, this->feature_toggles.mesh) <=>
std::tie(other.stage, other.features.mesh, other.feature_toggles.mesh)
);
case geometries::point_cloud:
return (
std::tie(this->stage, this->features.point_cloud, this->feature_toggles.point_cloud) <=>
std::tie(other.stage, other.features.point_cloud, other.feature_toggles.point_cloud)
);
}
std::unreachable();
return this->stage <=> other.stage;
}
else
if (this->geometry != other.geometry)
{
return this->geometry <=> other.geometry;
}
return this->generic_feature_set() <=> other.generic_feature_set();
}
bool operator==(const metadata_type& other) const noexcept
{
if (this->geometry == other.geometry)
if (this->stage != other.stage)
{
switch (this->geometry)
{
case geometries::mesh:
return (
std::tie(this->stage, this->features.mesh, this->feature_toggles.mesh) ==
std::tie(other.stage, other.features.mesh, other.feature_toggles.mesh)
);
case geometries::point_cloud:
return (
std::tie(this->stage, this->features.point_cloud, this->feature_toggles.point_cloud) ==
std::tie(other.stage, other.features.point_cloud, other.feature_toggles.point_cloud)
);
}
std::unreachable();
return false;
}
return false;
}
if (this->geometry != other.geometry)
{
return false;
}
return this->generic_feature_set() == other.generic_feature_set();
}
struct feature_ignorant_less
{
bool operator()(const metadata_type& a, const metadata_type& b) const
{
return (
std::tie(a.geometry, a.stage) <
std::tie(a.geometry, b.stage)
std::tie(a.stage, a.geometry) <
std::tie(b.stage, a.geometry)
);
}
};
struct feature_count_less
{
bool operator()(const metadata_type& a, const metadata_type& b) const
{
if (a.geometry == b.geometry)
{
int feature_count{}, feature_toggle_count{};
int other_feature_count{}, other_feature_toggle_count{};
constexpr auto count_features = []<typename T>(const T features)
{
using int_type = std::underlying_type_t<T>;
using uint_type = std::make_unsigned_t<int_type>;
return std::popcount(static_cast<uint_type>(static_cast<int_type>(features)));
};
switch (a.geometry)
{
case geometries::mesh:
for (auto& [ count, features ] : {
std::tie(feature_count, a.features.mesh),
std::tie(feature_toggle_count, a.feature_toggles.mesh),
std::tie(other_feature_count, b.features.mesh),
std::tie(other_feature_toggle_count, b.feature_toggles.mesh)
}) {
count = count_features(features);
}
case geometries::point_cloud:
for (auto& [ count, features ] : {
std::tie(feature_count, a.features.point_cloud),
std::tie(feature_toggle_count, a.feature_toggles.point_cloud),
std::tie(other_feature_count, b.features.point_cloud),
std::tie(other_feature_toggle_count, b.feature_toggles.point_cloud)
}) {
count = count_features(features);
}
default:
std::unreachable();
}
return (
std::tie(a.stage, feature_count, feature_toggle_count) <
std::tie(b.stage, other_feature_count, other_feature_toggle_count)
);
}
else
{
return a.geometry < b.geometry;
}
}
};
};
inline constexpr auto my_size = sizeof(metadata_type);
inline constexpr auto ma_align = alignof(metadata_type);
}

View File

@@ -0,0 +1,29 @@
#pragma once
#include <cinttypes>
#include <array>
#include <string_view>
#include <GL/glew.h>
namespace shader_program::stage
{
enum class types : std::uint8_t
{
vertex = 0,
geometry = 1,
fragment = 2
};
inline constexpr auto names = std::array<std::string_view, 3>{
"vertex", "geometry", "fragment"
};
inline constexpr auto gl_enums = std::array<GLenum, 3>{
GL_VERTEX_SHADER,
GL_GEOMETRY_SHADER,
GL_FRAGMENT_SHADER
};
}

View File

@@ -7,7 +7,7 @@
namespace shader_program::uniforms::mesh
{
enum class flags : unsigned
enum class flags : std::uint16_t
{
none = 0,
mvp_matrix = 1 << 0,

View File

@@ -6,7 +6,7 @@
namespace shader_program::uniforms::point_cloud
{
enum class flags : unsigned
enum class flags : std::uint8_t
{
none = 0,
mvp_matrix = 1 << 0,

View File

@@ -44,12 +44,12 @@ constexpr ENUM_TYPE operator<<( \
); \
} \
\
constexpr ENUM_TYPE operator<<( \
constexpr ENUM_TYPE operator>>( \
ENUM_TYPE& lhs, \
int shift \
) { \
return static_cast<ENUM_TYPE>( \
static_cast<std::underlying_type_t<ENUM_TYPE>>(lhs) << shift \
static_cast<std::underlying_type_t<ENUM_TYPE>>(lhs) >> shift \
); \
} \
\

View File

@@ -1,7 +1,8 @@
#pragma STAGE: FRAGMENT
#pragma GEOMETRY: MESH
#pragma FEATURES: FACE LINE V_L V_RGB V_A LIGHTING TEXTURE U_RGBA
#pragma FEATURE_TOGGLES: LIGHTING TEXTURE
#pragma STATIC_ENABLE: LIGHTING TEXTURE
#pragma DYNAMIC_ENABLE: FACE LINE V_L V_RGB V_A U_RGBA
//------------[ Uniforms ]------------//

View File

@@ -1,7 +1,8 @@
#pragma STAGE: FRAGMENT
#pragma GEOMETRY: MESH
#pragma FEATURES: POINT V_L V_RGB V_A LIGHTING U_RGBA
#pragma FEATURE_TOGGLES:
#pragma STATIC_ENABLE:
#pragma DYNAMIC_ENABLE: V_L V_RGB V_A LIGHTING U_RGBA
//------------[ Inputs ]------------//

View File

@@ -1,8 +1,8 @@
#pragma STAGE: FRAGMENT
#pragma GEOMETRY: POINT_CLOUD
#pragma FEATURES: SQUARE V_L V_RGB V_A LIGHTING U_RGBA RAINBOW
#pragma FEATURE_TOGGLES:
#pragma STATIC_ENABLE:
#pragma DYNAMIC_ENABLE: V_L V_RGB V_A LIGHTING U_RGBA RAINBOW
//------------[ Inputs ]------------//
layout (location = 0) in vec4 frag_color;

View File

@@ -1,8 +1,8 @@
#pragma STAGE: VERTEX
#pragma GEOMETRY: MESH
#pragma FEATURES: FACE LINE V_L V_RGB V_A LIGHTING TEXTURE U_RGBA
#pragma FEATURE_TOGGLES: V_L V_RGB V_A LIGHTING TEXTURE U_RGBA
#pragma STATIC_ENABLE: V_L V_RGB V_A LIGHTING TEXTURE U_RGBA
#pragma DYNAMIC_ENABLE: FACE LINE
#ifdef V_L
#ifdef V_RGB

View File

@@ -1,8 +1,8 @@
#pragma STAGE: VERTEX
#pragma GEOMETRY: MESH
#pragma FEATURES: POINT V_L V_RGB V_A LIGHTING U_RGBA
#pragma FEATURE_TOGGLES: V_L V_RGB V_A LIGHTING U_RGBA
#pragma STATIC_ENABLE: V_L V_RGB V_A LIGHTING U_RGBA
#pragma DYNAMIC_ENABLE:
#ifdef V_L
#ifdef V_RGB

View File

@@ -1,8 +1,8 @@
#pragma STAGE: VERTEX
#pragma GEOMETRY: POINT_CLOUD
#pragma FEATURES: SQUARE V_L V_RGB V_A LIGHTING U_RGBA RAINBOW
#pragma FEATURE_TOGGLES: V_L V_RGB V_A LIGHTING U_RGBA RAINBOW
#pragma STATIC_ENABLE: V_L V_RGB V_A LIGHTING U_RGBA RAINBOW
#pragma DYNAMIC_ENABLE:
#ifdef V_L
#ifdef V_RGB

View File

@@ -153,10 +153,10 @@ bool zgl::shader_program_compiler::parse_features_declaration(
) {
switch (metadata.geometry)
{
case shader_program::geometries::mesh:
case shader_program::geometry::types::mesh:
parse_feature_tokens(tokens, mesh_feature_lookup, metadata.features.mesh);
break;
case shader_program::geometries::point_cloud:
case shader_program::geometry::types::point_cloud:
parse_feature_tokens(tokens, point_cloud_feature_lookup, metadata.features.point_cloud);
break;
default:
@@ -172,11 +172,11 @@ bool zgl::shader_program_compiler::parse_feature_toggles_declaration(
) {
switch (metadata.geometry)
{
case shader_program::geometries::mesh:
parse_feature_tokens(tokens, mesh_feature_lookup, metadata.feature_toggles.mesh);
case shader_program::geometry::types::mesh:
parse_feature_tokens(tokens, mesh_feature_lookup, metadata.static_enable.mesh);
break;
case shader_program::geometries::point_cloud:
parse_feature_tokens(tokens, point_cloud_feature_lookup, metadata.feature_toggles.point_cloud);
case shader_program::geometry::types::point_cloud:
parse_feature_tokens(tokens, point_cloud_feature_lookup, metadata.static_enable.point_cloud);
break;
default:
ztu::logger::warn("Internal error: Unknown geometry index %.", static_cast<int>(metadata.geometry));
@@ -236,27 +236,28 @@ auto zgl::shader_program_compiler::find_compatible_shader_source(
&std::pair<shader_program::metadata_type, dynamic_shader_source_store::id_type>::first
);
if (lower_it == shader_lookup.end()) {
return std::nullopt;
}
const auto required_features = requirements.features.generic(requirements.geometry);
auto generic_requirement_feature_set = requirements.generic_feature_set();
const auto& required_features = generic_requirement_feature_set.features;
while (
lower_it != shader_lookup.end() and
lower_it->first.geometry == requirements.geometry and
lower_it->first.stage == requirements.stage
) {
const auto& data = lower_it->first;
const auto& [ features, feature_toggles ] = data.generic();
const auto& [ features, static_enable, dynamic_enable ] = data.generic_feature_set();
const auto missing_features = required_features & ~features;
const auto extra_features = ~required_features & features;
const auto untoggleable_extra_features = extra_features & ~feature_toggles;
const auto unwanted_features = ~required_features & features;
const auto fixed_unwanted_features = unwanted_features & ~static_enable & ~dynamic_enable;
if (missing_features == 0 and untoggleable_extra_features == 0)
if (missing_features == 0 and fixed_unwanted_features == 0)
{
const auto to_be_toggled = required_features & feature_toggles;
requirements.feature_toggles.from_generic(requirements.geometry, to_be_toggled);
// Tell caller which features need to be toggled before compilation
// and which features can still be dynamically enabled after compilation.
generic_requirement_feature_set.static_enable = required_features & static_enable;
generic_requirement_feature_set.dynamic_enable = dynamic_enable;
requirements.from_generic_feature_set(generic_requirement_feature_set);
return lower_it->second;
}
@@ -325,11 +326,11 @@ void zgl::shader_program_compiler::compile_shaders(
shader_strings.clear();
switch (requirements.geometry) {
case shader_program::geometries::mesh:
add_required_feature_defines(requirements.feature_toggles.mesh, mesh_feature_defines, shader_strings);
case shader_program::geometry::types::mesh:
add_required_feature_defines(requirements.feature_set.mesh.static_enable, mesh_feature_defines, shader_strings);
break;
case shader_program::geometries::point_cloud:
add_required_feature_defines(requirements.feature_toggles.point_cloud, point_cloud_feature_defines, shader_strings);
case shader_program::geometry::types::point_cloud:
add_required_feature_defines(requirements.feature_set.point_cloud.static_enable, point_cloud_feature_defines, shader_strings);
break;
default:
std::unreachable();
@@ -339,7 +340,7 @@ void zgl::shader_program_compiler::compile_shaders(
shader_id = glCreateShader(static_cast<GLenum>(requirements.stage));
glShaderSource(shader_id, shader_strings.size(), shader_strings.data(), nullptr);
glShaderSource(shader_id, static_cast<GLsizei>(shader_strings.size()), shader_strings.data(), nullptr);
glCompileShader(shader_id);
GLint success;
@@ -399,7 +400,7 @@ void zgl::shader_program_compiler::register_shader_sources(
const auto it = std::ranges::upper_bound(
shader_lookup,
*metadata,
shader_program::metadata_type::feature_count_less{},
std::less{},
&std::pair<shader_program::metadata_type, dynamic_shader_source_store::id_type>::first
);

View File

@@ -65,7 +65,7 @@ std::optional<mesh_batch_renderer::id_type> mesh_batch_renderer::add(
ztu::logger::debug("vertex_comps: %", std::bitset<32>{ static_cast<unsigned long long>(static_cast<int>(vertex_comps)) });
ztu::logger::debug("material_comps: %", std::bitset<32>{ static_cast<unsigned long long>(static_cast<int>(material_comps)) });
ztu::logger::debug("lit reqs: %", std::bitset<32>{ static_cast<unsigned long long>(static_cast<int>(shader_program::capabilities::mesh::lit.uniforms)) });
ztu::logger::debug("lit reqs: %", std::bitset<32>{ static_cast<unsigned long long>(static_cast<int>(shader_program::features::mesh::lit.uniforms)) });
for (std::size_t i{}; i != requirements::mesh::all.size(); ++i)

View File

@@ -19,7 +19,7 @@ void mesh_lookup::add(
std::optional<zgl::shader_program_handle> mesh_lookup::find(
requirements::mesh::flags requirements
) const {
auto capability = shader_program::capabilities::mesh::type{};
auto capability = shader_program::features::mesh::type{};
auto index = std::size_t{};
@@ -30,7 +30,7 @@ std::optional<zgl::shader_program_handle> mesh_lookup::find(
if (requirement_flags & 1)
{
const auto shader_requirements_index = requirements::mesh::all[index].shader_program_requirement_index;
const auto& [ attributes, uniforms ] = shader_program::capabilities::mesh::all[shader_requirements_index];
const auto& [ attributes, uniforms ] = shader_program::features::mesh::all[shader_requirements_index];
capability.attributes |= attributes;
capability.uniforms |= uniforms;
}

View File

@@ -17,7 +17,7 @@ void point_cloud_lookup::add(
std::optional<zgl::shader_program_handle> point_cloud_lookup::find(
requirements::point_cloud::flags requirements
) const {
auto capability = shader_program::capabilities::point_cloud::type{};
auto capability = shader_program::features::point_cloud::type{};
auto index = std::size_t{};
@@ -28,7 +28,7 @@ std::optional<zgl::shader_program_handle> point_cloud_lookup::find(
if (requirement_flags & 1)
{
const auto shader_requirements_index = requirements::point_cloud::all[index].shader_program_requirement_index;
const auto& [ attributes, uniforms ] = shader_program::capabilities::point_cloud::all[shader_requirements_index];
const auto& [ attributes, uniforms ] = shader_program::features::point_cloud::all[shader_requirements_index];
capability.attributes |= attributes;
capability.uniforms |= uniforms;
}