Repository: google/filament
File: filament/backend/include/backend/Program.h (C/C++)

Code before:
#include <variant>

#include <stddef.h>
#include <stdint.h>

namespace utils::io {
class ostream;
} // namespace utils::io

namespace filament::backend {

class Program {
public:

    static constexpr size_t SHADER_TYPE_COUNT = 3;
    static constexpr size_t UNIFORM_BINDING_COUNT = CONFIG_UNIFORM_BINDING_COUNT;
    static constexpr size_t SAMPLER_BINDING_COUNT = CONFIG_SAMPLER_BINDING_COUNT;

    struct Descriptor {
        utils::CString name;
        DescriptorType type;
        descriptor_binding_t binding;
    };

    using SpecializationConstant = std::variant<int32_t, float, bool>;
    using DescriptorSetLayoutArray = std::array<std::optional<DescriptorSetLayout>, MAX_DESCRIPTOR_SET_COUNT>;

    struct Uniform { // For ES2 support
        utils::CString name;    // full qualified name of the uniform field
        uint16_t offset;        // offset in 'uint32_t' into the uniform buffer
        uint8_t size;           // >1 for arrays
        UniformType type;       // uniform type
    };

    using DescriptorBindingsInfo = utils::FixedCapacityVector<Descriptor>;
    using DescriptorSetInfo = std::array<DescriptorBindingsInfo, MAX_DESCRIPTOR_SET_COUNT>;
    using SpecializationConstantsInfo = utils::FixedCapacityVector<SpecializationConstant>;
    using ShaderBlob = utils::FixedCapacityVector<uint8_t>;
    using ShaderSource = std::array<ShaderBlob, SHADER_TYPE_COUNT>;

    using AttributesInfo = utils::FixedCapacityVector<std::pair<utils::CString, uint8_t>>;
    using UniformInfo = utils::FixedCapacityVector<Uniform>;
    using BindingUniformsInfo = utils::FixedCapacityVector<
            std::tuple<uint8_t, utils::CString, Program::UniformInfo>>;

    Program() noexcept;

    Program(const Program& rhs) = delete;
    Program& operator=(const Program& rhs) = delete;

    Program(Program&& rhs) noexcept;

Review comment (suggestion):
@poweifeng @pixelflinger fyi - realized that because these are structs, they aren't nullable in the same way as a descriptor set. this was my solution here, but let me know if there's an alternative you'd prefer.

note that we only set 3 of the 4 indices here, as MAX_DESCRIPTOR_SET_COUNT is 4. so, there is one guaranteed to be unused every time.

Code after:

#include <stddef.h>
#include <stdint.h>

namespace utils::io {
class ostream;
} // namespace utils::io

namespace filament::backend {

class Program {
public:

    static constexpr size_t SHADER_TYPE_COUNT = 3;
    static constexpr size_t UNIFORM_BINDING_COUNT = CONFIG_UNIFORM_BINDING_COUNT;
    static constexpr size_t SAMPLER_BINDING_COUNT = CONFIG_SAMPLER_BINDING_COUNT;

    struct Descriptor {
        utils::CString name;
        DescriptorType type;
        descriptor_binding_t binding;
    };

    struct DescriptorSetLayoutBinding {
        descriptor_set_t set;
        DescriptorSetLayout layout;
    };

    using SpecializationConstant = std::variant<int32_t, float, bool>;
    using DescriptorSetLayoutArray = utils::FixedCapacityVector<DescriptorSetLayoutBinding>;

    struct Uniform { // For ES2 support
        utils::CString name;    // full qualified name of the uniform field
        uint16_t offset;        // offset in 'uint32_t' into the uniform buffer
        uint8_t size;           // >1 for arrays
        UniformType type;       // uniform type
    };

    using DescriptorBindingsInfo = utils::FixedCapacityVector<Descriptor>;
    using DescriptorSetInfo = std::array<DescriptorBindingsInfo, MAX_DESCRIPTOR_SET_COUNT>;
    using SpecializationConstantsInfo = utils::FixedCapacityVector<SpecializationConstant>;
    using ShaderBlob = utils::FixedCapacityVector<uint8_t>;
    using ShaderSource = std::array<ShaderBlob, SHADER_TYPE_COUNT>;

    using AttributesInfo = utils::FixedCapacityVector<std::pair<utils::CString, uint8_t>>;
    using UniformInfo = utils::FixedCapacityVector<Uniform>;
    using BindingUniformsInfo = utils::FixedCapacityVector<
            std::tuple<uint8_t, utils::CString, Program::UniformInfo>>;

    Program() noexcept;