hwr2: Reformat C++ code

This commit is contained in:
Eidolon 2023-01-14 19:59:41 -06:00
parent fcb4dfe3d7
commit ccc10eadd0
13 changed files with 1157 additions and 669 deletions

View file

@ -5,14 +5,15 @@
#include <cstddef>
#include <cstdint>
#include <functional>
#include <iterator>
#include <initializer_list>
#include <iterator>
#include <stdexcept>
#include <type_traits>
#include "../cxxutil.hpp"
namespace srb2 {
namespace srb2
{
template <typename T, size_t Limit>
class StaticVec
@ -98,15 +99,9 @@ public:
return *this;
}
void push_back(const T& value)
{
arr_[size_++] = value;
}
void push_back(const T& value) { arr_[size_++] = value; }
void pop_back()
{
arr_[size_--] = T();
}
void pop_back() { arr_[size_--] = T(); }
void resize(size_t size, T value = T())
{
@ -135,80 +130,35 @@ public:
}
}
constexpr T* begin() noexcept
{
return &arr_[0];
}
constexpr T* begin() noexcept { return &arr_[0]; }
constexpr const T* begin() const noexcept
{
return cbegin();
}
constexpr const T* begin() const noexcept { return cbegin(); }
constexpr const T* cbegin() const noexcept
{
return &arr_[0];
}
constexpr const T* cbegin() const noexcept { return &arr_[0]; }
constexpr T* end() noexcept
{
return &arr_[size_];
}
constexpr T* end() noexcept { return &arr_[size_]; }
constexpr const T* end() const noexcept
{
return cend();
}
constexpr const T* end() const noexcept { return cend(); }
constexpr const T* cend() const noexcept
{
return &arr_[size_];
}
constexpr const T* cend() const noexcept { return &arr_[size_]; }
constexpr std::reverse_iterator<T*> rbegin() noexcept
{
return &arr_[size_];
}
constexpr std::reverse_iterator<T*> rbegin() noexcept { return &arr_[size_]; }
constexpr std::reverse_iterator<const T*> crbegin() const noexcept
{
return &arr_[size_];
}
constexpr std::reverse_iterator<const T*> crbegin() const noexcept { return &arr_[size_]; }
constexpr std::reverse_iterator<T*> rend() noexcept
{
return &arr_[0];
}
constexpr std::reverse_iterator<T*> rend() noexcept { return &arr_[0]; }
constexpr std::reverse_iterator<const T*> crend() const noexcept
{
return &arr_[0];
}
constexpr std::reverse_iterator<const T*> crend() const noexcept { return &arr_[0]; }
constexpr bool empty() const noexcept
{
return size_ == 0;
}
constexpr bool empty() const noexcept { return size_ == 0; }
constexpr size_t size() const noexcept
{
return size_;
}
constexpr size_t size() const noexcept { return size_; }
constexpr size_t capacity() const noexcept
{
return Limit;
}
constexpr size_t capacity() const noexcept { return Limit; }
constexpr size_t max_size() const noexcept
{
return Limit;
}
constexpr size_t max_size() const noexcept { return Limit; }
constexpr T& operator[](size_t index) noexcept
{
return arr_[index];
}
constexpr T& operator[](size_t index) noexcept { return arr_[index]; }
T& at(size_t index)
{
@ -219,10 +169,7 @@ public:
return this[index];
}
constexpr const T& operator[](size_t index) const noexcept
{
return arr_[index];
}
constexpr const T& operator[](size_t index) const noexcept { return arr_[index]; }
const T& at(size_t index) const
{
@ -233,15 +180,9 @@ public:
return this[index];
}
T& front()
{
return *arr_[0];
}
T& front() { return *arr_[0]; }
T& back()
{
return *arr_[size_ - 1];
}
T& back() { return *arr_[size_ - 1]; }
};
} // namespace srb2
@ -254,7 +195,8 @@ bool operator==(const srb2::StaticVec<T, L1>& lhs, const srb2::StaticVec<T, L2>&
{
return false;
}
for (size_t i = 0; i < lhs; i++) {
for (size_t i = 0; i < lhs; i++)
{
if (rhs[i] != lhs[i])
{
return false;
@ -274,8 +216,8 @@ struct std::hash<srb2::StaticVec<T, Limit>>
{
uint64_t operator()(const srb2::StaticVec<T, Limit>& input) const
{
constexpr const uint64_t prime { 0x00000100000001B3 };
std::size_t ret { 0xcbf29ce484222325 };
constexpr const uint64_t prime {0x00000100000001B3};
std::size_t ret {0xcbf29ce484222325};
for (auto itr = input.begin(); itr != input.end(); itr++)
{

View file

@ -7,9 +7,9 @@
#include <imgui.h>
#include "cxxutil.hpp"
#include "v_video.h"
#include "hwr2/pass_imgui.hpp"
#include "hwr2/pass_software.hpp"
#include "v_video.h"
// KILL THIS WHEN WE KILL OLD OGL SUPPORT PLEASE
#include "sdl/ogl_sdl.h"

File diff suppressed because it is too large Load diff

View file

@ -11,19 +11,17 @@
#include "../rhi.hpp"
namespace srb2::rhi {
namespace srb2::rhi
{
struct GlCoreFramebufferKey {
struct GlCoreFramebufferKey
{
TextureOrRenderbuffer color;
std::optional<TextureOrRenderbuffer> depth;
bool operator==(const GlCoreFramebufferKey& rhs) const noexcept {
return color == rhs.color && depth == rhs.depth;
}
bool operator==(const GlCoreFramebufferKey& rhs) const noexcept { return color == rhs.color && depth == rhs.depth; }
bool operator!=(const GlCoreFramebufferKey& rhs) const noexcept {
return !(*this == rhs);
}
bool operator!=(const GlCoreFramebufferKey& rhs) const noexcept { return !(*this == rhs); }
};
} // namespace srb2::rhi
@ -32,19 +30,25 @@ struct GlCoreFramebufferKey {
// we need to split the namespace declarations _before_ the instantiation of std::unordered_map.
template <>
struct std::hash<srb2::rhi::GlCoreFramebufferKey> {
std::size_t operator()(const srb2::rhi::GlCoreFramebufferKey& key) const {
struct GetHandleHashVisitor {
uint32_t operator()(const srb2::rhi::Handle<srb2::rhi::Texture>& handle) const noexcept {
struct std::hash<srb2::rhi::GlCoreFramebufferKey>
{
std::size_t operator()(const srb2::rhi::GlCoreFramebufferKey& key) const
{
struct GetHandleHashVisitor
{
uint32_t operator()(const srb2::rhi::Handle<srb2::rhi::Texture>& handle) const noexcept
{
return std::hash<srb2::rhi::Handle<srb2::rhi::Texture>>()(handle);
}
uint32_t operator()(const srb2::rhi::Handle<srb2::rhi::Renderbuffer>& handle) const noexcept {
uint32_t operator()(const srb2::rhi::Handle<srb2::rhi::Renderbuffer>& handle) const noexcept
{
return std::hash<srb2::rhi::Handle<srb2::rhi::Renderbuffer>>()(handle);
}
};
std::size_t color_hash = std::visit(GetHandleHashVisitor {}, key.color);
std::size_t depth_hash = 0;
if (key.depth) {
if (key.depth)
{
depth_hash = std::visit(GetHandleHashVisitor {}, *key.depth);
}
return color_hash ^ (depth_hash << 1);
@ -53,13 +57,15 @@ struct std::hash<srb2::rhi::GlCoreFramebufferKey> {
struct GladGLContext;
namespace srb2::rhi {
namespace srb2::rhi
{
typedef void (*GlProc)(void);
typedef GlProc (*GlLoadFunc)(const char* name);
/// @brief Platform-specific implementation details for the GLES2 backend.
struct GlCorePlatform {
struct GlCorePlatform
{
virtual ~GlCorePlatform();
virtual void present() = 0;
@ -67,7 +73,8 @@ struct GlCorePlatform {
virtual Rect get_default_framebuffer_dimensions() = 0;
};
class GlCoreRhi final : public Rhi {
class GlCoreRhi final : public Rhi
{
std::unique_ptr<GlCorePlatform> platform_;
std::unique_ptr<GladGLContext> gl_;
@ -82,7 +89,9 @@ class GlCoreRhi final : public Rhi {
std::unordered_map<GlCoreFramebufferKey, uint32_t> framebuffers_ {16};
struct DefaultRenderPassState {};
struct DefaultRenderPassState
{
};
using RenderPassState = std::variant<DefaultRenderPassState, RenderPassBeginInfo>;
std::optional<RenderPassState> current_render_pass_;
std::optional<Handle<Pipeline>> current_pipeline_;
@ -114,10 +123,24 @@ public:
virtual Handle<TransferContext> begin_transfer() override;
virtual void end_transfer(Handle<TransferContext> handle) override;
virtual void update_buffer_contents(Handle<TransferContext> ctx, Handle<Buffer> buffer, uint32_t offset, tcb::span<const std::byte> data) override;
virtual void update_texture(Handle<TransferContext> ctx, Handle<Texture> texture, Rect region, srb2::rhi::PixelFormat data_format, tcb::span<const std::byte> data) override;
virtual Handle<UniformSet> create_uniform_set(Handle<TransferContext> ctx, const CreateUniformSetInfo& info) override;
virtual Handle<BindingSet> create_binding_set(Handle<TransferContext> ctx, Handle<Pipeline> pipeline, const CreateBindingSetInfo& info) override;
virtual void update_buffer_contents(
Handle<TransferContext> ctx,
Handle<Buffer> buffer,
uint32_t offset,
tcb::span<const std::byte> data
) override;
virtual void update_texture(
Handle<TransferContext> ctx,
Handle<Texture> texture,
Rect region,
srb2::rhi::PixelFormat data_format,
tcb::span<const std::byte> data
) override;
virtual Handle<UniformSet>
create_uniform_set(Handle<TransferContext> ctx, const CreateUniformSetInfo& info) override;
virtual Handle<BindingSet>
create_binding_set(Handle<TransferContext> ctx, Handle<Pipeline> pipeline, const CreateBindingSetInfo& info)
override;
virtual Handle<GraphicsContext> begin_graphics() override;
virtual void end_graphics(Handle<GraphicsContext> ctx) override;
@ -133,9 +156,7 @@ public:
virtual void set_scissor(Handle<GraphicsContext> ctx, const Rect& rect) override;
virtual void set_viewport(Handle<GraphicsContext> ctx, const Rect& rect) override;
virtual void draw(Handle<GraphicsContext> ctx, uint32_t vertex_count, uint32_t first_vertex) override;
virtual void draw_indexed(Handle<GraphicsContext> ctx,
uint32_t index_count,
uint32_t first_index) override;
virtual void draw_indexed(Handle<GraphicsContext> ctx, uint32_t index_count, uint32_t first_index) override;
virtual void read_pixels(Handle<GraphicsContext> ctx, const Rect& rect, tcb::span<std::byte> out) override;
virtual void present() override;

File diff suppressed because it is too large Load diff

View file

@ -11,19 +11,17 @@
#include "../rhi.hpp"
namespace srb2::rhi {
namespace srb2::rhi
{
struct Gles2FramebufferKey {
struct Gles2FramebufferKey
{
TextureOrRenderbuffer color;
std::optional<TextureOrRenderbuffer> depth;
bool operator==(const Gles2FramebufferKey& rhs) const noexcept {
return color == rhs.color && depth == rhs.depth;
}
bool operator==(const Gles2FramebufferKey& rhs) const noexcept { return color == rhs.color && depth == rhs.depth; }
bool operator!=(const Gles2FramebufferKey& rhs) const noexcept {
return !(*this == rhs);
}
bool operator!=(const Gles2FramebufferKey& rhs) const noexcept { return !(*this == rhs); }
};
} // namespace srb2::rhi
@ -32,29 +30,37 @@ struct Gles2FramebufferKey {
// we need to split the namespace declarations _before_ the instantiation of std::unordered_map.
template <>
struct std::hash<srb2::rhi::Gles2FramebufferKey> {
std::size_t operator()(const srb2::rhi::Gles2FramebufferKey& key) const {
struct GetHandleHashVisitor {
uint32_t operator()(const srb2::rhi::Handle<srb2::rhi::Texture>& handle) const noexcept {
struct std::hash<srb2::rhi::Gles2FramebufferKey>
{
std::size_t operator()(const srb2::rhi::Gles2FramebufferKey& key) const
{
struct GetHandleHashVisitor
{
uint32_t operator()(const srb2::rhi::Handle<srb2::rhi::Texture>& handle) const noexcept
{
return std::hash<srb2::rhi::Handle<srb2::rhi::Texture>>()(handle);
}
uint32_t operator()(const srb2::rhi::Handle<srb2::rhi::Renderbuffer>& handle) const noexcept {
uint32_t operator()(const srb2::rhi::Handle<srb2::rhi::Renderbuffer>& handle) const noexcept
{
return std::hash<srb2::rhi::Handle<srb2::rhi::Renderbuffer>>()(handle);
}
};
std::size_t color_hash = std::visit(GetHandleHashVisitor {}, key.color);
std::size_t depth_hash = 0;
if (key.depth) {
if (key.depth)
{
depth_hash = std::visit(GetHandleHashVisitor {}, *key.depth);
}
return color_hash ^ (depth_hash << 1);
}
};
namespace srb2::rhi {
namespace srb2::rhi
{
/// @brief Platform-specific implementation details for the GLES2 backend.
struct Gles2Platform {
struct Gles2Platform
{
virtual ~Gles2Platform();
virtual void present() = 0;
@ -62,7 +68,8 @@ struct Gles2Platform {
virtual Rect get_default_framebuffer_dimensions() = 0;
};
class Gles2Rhi final : public Rhi {
class Gles2Rhi final : public Rhi
{
std::unique_ptr<Gles2Platform> platform_;
Slab<RenderPass> render_pass_slab_;
@ -73,7 +80,9 @@ class Gles2Rhi final : public Rhi {
std::unordered_map<Gles2FramebufferKey, uint32_t> framebuffers_ {16};
struct DefaultRenderPassState {};
struct DefaultRenderPassState
{
};
using RenderPassState = std::variant<DefaultRenderPassState, RenderPassBeginInfo>;
std::optional<RenderPassState> current_render_pass_;
std::optional<Handle<Pipeline>> current_pipeline_;
@ -90,7 +99,9 @@ public:
virtual Handle<RenderPass> create_render_pass(const RenderPassDesc& desc) override;
virtual void destroy_render_pass(Handle<RenderPass>&& handle) override;
virtual Handle<Texture> create_texture(const TextureDesc& desc, srb2::rhi::PixelFormat data_format, tcb::span<const std::byte> data) override;
virtual Handle<Texture>
create_texture(const TextureDesc& desc, srb2::rhi::PixelFormat data_format, tcb::span<const std::byte> data)
override;
virtual void destroy_texture(Handle<Texture>&& handle) override;
virtual Handle<Buffer> create_buffer(const BufferDesc& desc, tcb::span<const std::byte> data) override;
virtual void destroy_buffer(Handle<Buffer>&& handle) override;
@ -99,8 +110,14 @@ public:
virtual Handle<Pipeline> create_pipeline(const PipelineDesc& desc) override;
virtual void destroy_pipeline(Handle<Pipeline>&& handle) override;
virtual void update_buffer_contents(Handle<Buffer> buffer, uint32_t offset, tcb::span<const std::byte> data) override;
virtual void update_texture(Handle<Texture> texture, Rect region, srb2::rhi::PixelFormat data_format, tcb::span<const std::byte> data) override;
virtual void
update_buffer_contents(Handle<Buffer> buffer, uint32_t offset, tcb::span<const std::byte> data) override;
virtual void update_texture(
Handle<Texture> texture,
Rect region,
srb2::rhi::PixelFormat data_format,
tcb::span<const std::byte> data
) override;
virtual Handle<GraphicsContext> begin_graphics() override;
virtual void end_graphics(Handle<GraphicsContext>&& ctx) override;
@ -115,10 +132,9 @@ public:
virtual void set_scissor(Handle<GraphicsContext> ctx, const Rect& rect) override;
virtual void set_viewport(Handle<GraphicsContext> ctx, const Rect& rect) override;
virtual void draw(Handle<GraphicsContext> ctx, uint32_t vertex_count, uint32_t first_vertex) override;
virtual void draw_indexed(Handle<GraphicsContext> ctx,
uint32_t index_count,
uint32_t first_index,
uint32_t vertex_offset) override;
virtual void
draw_indexed(Handle<GraphicsContext> ctx, uint32_t index_count, uint32_t first_index, uint32_t vertex_offset)
override;
virtual void present() override;

View file

@ -10,35 +10,40 @@
#include "../cxxutil.hpp"
namespace srb2::rhi {
namespace srb2::rhi
{
struct NullHandleType {};
struct NullHandleType
{
};
constexpr const NullHandleType kNullHandle = NullHandleType {};
template <typename T = void>
class Handle {
class Handle
{
uint32_t id_;
uint32_t generation_;
public:
Handle(uint32_t id, uint32_t generation) noexcept : id_(id), generation_(generation) {}
Handle(uint64_t combined) noexcept
: id_(combined & 0xFFFFFFFF)
, generation_((combined & 0xFFFFFFFF00000000) >> 32)
{}
Handle(uint64_t combined) noexcept : id_(combined & 0xFFFFFFFF), generation_((combined & 0xFFFFFFFF00000000) >> 32)
{
}
Handle() noexcept : Handle(0, 0) {}
Handle(NullHandleType) noexcept : Handle() {}
Handle(const Handle&) = default;
Handle(Handle&& rhs) noexcept {
Handle(Handle&& rhs) noexcept
{
id_ = std::exchange(rhs.id_, 0);
generation_ = std::exchange(rhs.generation_, 0);
};
Handle& operator=(const Handle&) = default;
Handle& operator=(Handle&& rhs) noexcept {
Handle& operator=(Handle&& rhs) noexcept
{
id_ = std::exchange(rhs.id_, 0);
generation_ = std::exchange(rhs.generation_, 0);
return *this;
@ -47,22 +52,27 @@ public:
// Conversions from Handles of derived type U to base type T
template <typename U, typename std::enable_if_t<std::is_base_of_v<T, U>, bool> = true>
Handle(const Handle<U>& rhs) noexcept : id_(rhs.id_), generation_(rhs.generation_) {}
Handle(const Handle<U>& rhs) noexcept : id_(rhs.id_), generation_(rhs.generation_)
{
}
template <typename U, typename std::enable_if_t<std::is_base_of_v<T, U>, bool> = true>
Handle(Handle<U>&& rhs) noexcept {
Handle(Handle<U>&& rhs) noexcept
{
id_ = std::exchange(rhs.id_, 0);
generation_ = std::exchange(rhs.generation_, 0);
}
template <typename U, typename std::enable_if_t<std::is_base_of_v<T, U>, bool> = true>
Handle& operator=(const Handle<U>& rhs) noexcept {
Handle& operator=(const Handle<U>& rhs) noexcept
{
id_ = rhs.id_;
generation_ = rhs.generation_;
}
template <typename U, typename std::enable_if_t<std::is_base_of_v<T, U>, bool> = true>
Handle& operator=(Handle<U>&& rhs) noexcept {
Handle& operator=(Handle<U>&& rhs) noexcept
{
id_ = std::exchange(rhs.id_, 0);
generation_ = std::exchange(rhs.generation_, 0);
return *this;
@ -74,7 +84,8 @@ public:
/// @return true if this Handle is valid (belonging to a generation > 0); false otherwise
bool valid() const noexcept { return generation_ != 0; }
bool operator==(const Handle& handle) const noexcept {
bool operator==(const Handle& handle) const noexcept
{
return handle.generation_ == generation_ && handle.id_ == id_;
}
bool operator!=(const Handle& handle) const noexcept { return !(handle == *this); }
@ -100,17 +111,20 @@ inline bool operator==(const Handle<T>& lhs, const std::nullptr_t&) noexcept
// Non-member equality of base Handle<T> to derived Handle<U>
template <typename T, typename U, typename std::enable_if_t<std::is_base_of_v<T, U>, bool> = true>
inline bool operator==(const Handle<T>& lhs, const Handle<U>& rhs) noexcept {
inline bool operator==(const Handle<T>& lhs, const Handle<U>& rhs) noexcept
{
return lhs.generation() == rhs.generation() && lhs.id() == rhs.id();
}
template <typename T, typename U, typename std::enable_if_t<std::is_base_of_v<T, U>, bool> = true>
inline bool operator!=(const Handle<T>& lhs, const Handle<U>& rhs) noexcept {
inline bool operator!=(const Handle<T>& lhs, const Handle<U>& rhs) noexcept
{
return !(lhs == rhs);
}
template <typename T = void>
class HandlePool {
class HandlePool
{
std::atomic_uint32_t current_id_ {0};
std::atomic_uint32_t current_gen_ {1};
@ -124,7 +138,8 @@ public:
/// @brief Create a new unique Handle in the current generation.
/// @return the new Handle.
Handle<T> create() noexcept {
Handle<T> create() noexcept
{
const uint32_t id = current_id_.fetch_add(1);
SRB2_ASSERT(id != UINT32_MAX);
const uint32_t gen = current_gen_.load();
@ -132,7 +147,8 @@ public:
}
/// @brief Increment the generation. All handles created after this will belong to a new generation.
void generation() noexcept {
void generation() noexcept
{
const uint32_t old_gen = current_gen_.fetch_add(1);
SRB2_ASSERT(old_gen != UINT32_MAX);
}
@ -150,6 +166,7 @@ class SlabIterator
SlabIterator(size_t index, const Slab<std::remove_const_t<T>>* slab) : index_(index), slab_(slab) {}
friend Slab<std::remove_const_t<T>>;
public:
SlabIterator() = default;
SlabIterator(const SlabIterator&) = default;
@ -158,10 +175,7 @@ public:
SlabIterator& operator=(const SlabIterator&) = default;
SlabIterator& operator=(SlabIterator&&) = default;
T& operator*() const noexcept
{
return *slab_->vec_[index_].item.get();
}
T& operator*() const noexcept { return *slab_->vec_[index_].item.get(); }
SlabIterator& operator++() noexcept
{
@ -187,20 +201,16 @@ public:
return SlabIterator {index_ + 1, slab_};
}
bool operator==(const SlabIterator& rhs) const noexcept
{
return slab_ == rhs.slab_ && index_ == rhs.index_;
}
bool operator==(const SlabIterator& rhs) const noexcept { return slab_ == rhs.slab_ && index_ == rhs.index_; }
bool operator!=(const SlabIterator& rhs) const noexcept
{
return !(*this == rhs);
}
bool operator!=(const SlabIterator& rhs) const noexcept { return !(*this == rhs); }
};
template <typename T>
class Slab {
struct SlabStorage {
class Slab
{
struct SlabStorage
{
std::unique_ptr<T> item;
uint32_t gen;
};
@ -210,34 +220,42 @@ class Slab {
friend SlabIterator<T>;
friend SlabIterator<const T>;
public:
Slab() = default;
Slab(const Slab&) = delete;
Slab& operator=(const Slab&) = delete;
Handle<T> insert(std::unique_ptr<T>&& value) {
Handle<T> insert(std::unique_ptr<T>&& value)
{
uint32_t ret_id = 0;
if (!free_list_.empty()) {
if (!free_list_.empty())
{
ret_id = free_list_.back();
free_list_.pop_back();
SlabStorage& storage = vec_[ret_id];
storage.item = std::move(value);
storage.gen = gen_;
} else {
}
else
{
ret_id = vec_.size();
vec_.push_back(SlabStorage {std::move(value), gen_});
}
return Handle<T>(ret_id, gen_);
}
std::unique_ptr<T> remove(Handle<T> handle) {
std::unique_ptr<T> remove(Handle<T> handle)
{
uint32_t handle_id = handle.id();
uint32_t handle_gen = handle.generation();
if (handle_id >= vec_.size()) {
if (handle_id >= vec_.size())
{
return nullptr;
}
SlabStorage& storage = vec_[handle_id];
if (storage.gen > handle_gen) {
if (storage.gen > handle_gen)
{
return nullptr;
}
std::unique_ptr<T> ret = std::move(storage.item);
@ -251,14 +269,17 @@ public:
return ret;
}
bool is_valid(Handle<T> handle) {
bool is_valid(Handle<T> handle)
{
uint32_t handle_id = handle.id();
uint32_t handle_gen = handle.generation();
if (handle_id >= vec_.size()) {
if (handle_id >= vec_.size())
{
return false;
}
SlabStorage& storage = vec_[handle_id];
if (storage.gen > handle_gen) {
if (storage.gen > handle_gen)
{
return false;
}
return true;
@ -275,39 +296,31 @@ public:
}
}
T& operator[](Handle<T> handle) {
T& operator[](Handle<T> handle)
{
SRB2_ASSERT(is_valid(handle));
return *vec_[handle.id()].item;
}
SlabIterator<T> begin()
{
return SlabIterator<T> {0, this};
}
SlabIterator<T> begin() { return SlabIterator<T> {0, this}; }
SlabIterator<T> end()
{
return SlabIterator<T> {vec_.size(), this};
}
SlabIterator<T> end() { return SlabIterator<T> {vec_.size(), this}; }
SlabIterator<const T> cbegin() const
{
return SlabIterator<const T> {0, this};
}
SlabIterator<const T> cbegin() const { return SlabIterator<const T> {0, this}; }
SlabIterator<const T> cend() const
{
return SlabIterator<const T> {vec_.size(), this};
}
SlabIterator<const T> cend() const { return SlabIterator<const T> {vec_.size(), this}; }
};
} // namespace srb2::rhi
namespace std {
namespace std
{
template <typename T>
struct hash<srb2::rhi::Handle<T>> {
std::size_t operator()(const srb2::rhi::Handle<T>& e) const {
struct hash<srb2::rhi::Handle<T>>
{
std::size_t operator()(const srb2::rhi::Handle<T>& e) const
{
return std::hash<uint32_t>()(e.generation()) ^ (std::hash<uint32_t>()(e.id()) << 1);
}
};

View file

@ -9,38 +9,28 @@ using namespace srb2::rhi;
Rhi::~Rhi() = default;
const ProgramRequirements srb2::rhi::kProgramRequirementsUnshaded = {
ProgramVertexInputRequirements {{
ProgramVertexInput {VertexAttributeName::kPosition, VertexAttributeFormat::kFloat3, true},
ProgramVertexInput {VertexAttributeName::kTexCoord0, VertexAttributeFormat::kFloat2, false},
ProgramVertexInput {VertexAttributeName::kColor, VertexAttributeFormat::kFloat4, false}
}},
ProgramUniformRequirements {{
{{UniformName::kProjection}},
{{UniformName::kModelView, UniformName::kTexCoord0Transform}}
}},
ProgramSamplerRequirements {{
ProgramSamplerInput {SamplerName::kSampler0, true}
}}
};
ProgramVertexInputRequirements {
{ProgramVertexInput {VertexAttributeName::kPosition, VertexAttributeFormat::kFloat3, true},
ProgramVertexInput {VertexAttributeName::kTexCoord0, VertexAttributeFormat::kFloat2, false},
ProgramVertexInput {VertexAttributeName::kColor, VertexAttributeFormat::kFloat4, false}}},
ProgramUniformRequirements {
{{{UniformName::kProjection}}, {{UniformName::kModelView, UniformName::kTexCoord0Transform}}}},
ProgramSamplerRequirements {{ProgramSamplerInput {SamplerName::kSampler0, true}}}};
const ProgramRequirements srb2::rhi::kProgramRequirementsUnshadedPaletted = {
ProgramVertexInputRequirements {{
ProgramVertexInput {VertexAttributeName::kPosition, VertexAttributeFormat::kFloat3, true},
ProgramVertexInput {VertexAttributeName::kTexCoord0, VertexAttributeFormat::kFloat2, false},
ProgramVertexInput {VertexAttributeName::kColor, VertexAttributeFormat::kFloat4, false}
}},
ProgramUniformRequirements {{
{{UniformName::kProjection}},
{{UniformName::kModelView, UniformName::kTexCoord0Transform}}
}},
ProgramSamplerRequirements {{
ProgramSamplerInput {SamplerName::kSampler0, true},
ProgramSamplerInput {SamplerName::kSampler1, true}
}}
};
ProgramVertexInputRequirements {
{ProgramVertexInput {VertexAttributeName::kPosition, VertexAttributeFormat::kFloat3, true},
ProgramVertexInput {VertexAttributeName::kTexCoord0, VertexAttributeFormat::kFloat2, false},
ProgramVertexInput {VertexAttributeName::kColor, VertexAttributeFormat::kFloat4, false}}},
ProgramUniformRequirements {
{{{UniformName::kProjection}}, {{UniformName::kModelView, UniformName::kTexCoord0Transform}}}},
ProgramSamplerRequirements {
{ProgramSamplerInput {SamplerName::kSampler0, true}, ProgramSamplerInput {SamplerName::kSampler1, true}}}};
const ProgramRequirements& rhi::program_requirements_for_program(PipelineProgram program) noexcept {
switch (program) {
const ProgramRequirements& rhi::program_requirements_for_program(PipelineProgram program) noexcept
{
switch (program)
{
case PipelineProgram::kUnshaded:
return kProgramRequirementsUnshaded;
case PipelineProgram::kUnshadedPaletted:

View file

@ -12,28 +12,41 @@
#include "../core/static_vec.hpp"
#include "handle.hpp"
namespace srb2::rhi {
namespace srb2::rhi
{
struct Buffer {};
struct Buffer
{
};
struct Texture {};
struct Texture
{
};
struct Pipeline {};
struct Pipeline
{
};
struct RenderPass {};
struct RenderPass
{
};
struct Renderbuffer {};
struct Renderbuffer
{
};
using TextureOrRenderbuffer = std::variant<Handle<Texture>, Handle<Renderbuffer>>;
enum class VertexAttributeFormat {
enum class VertexAttributeFormat
{
kFloat,
kFloat2,
kFloat3,
kFloat4
};
enum class UniformFormat {
enum class UniformFormat
{
kFloat,
kFloat2,
kFloat3,
@ -47,20 +60,23 @@ enum class UniformFormat {
kMat4
};
enum class PixelFormat {
enum class PixelFormat
{
kR8,
kRGBA8,
kDepth16,
kStencil8
};
enum class TextureFormat {
enum class TextureFormat
{
kLuminance,
kRGB,
kRGBA
};
enum class CompareFunc {
enum class CompareFunc
{
kNever,
kLess,
kEqual,
@ -71,7 +87,8 @@ enum class CompareFunc {
kAlways
};
enum class BlendFactor {
enum class BlendFactor
{
kZero,
kOne,
kSource,
@ -89,13 +106,15 @@ enum class BlendFactor {
kSourceAlphaSaturated
};
enum class BlendFunction {
enum class BlendFunction
{
kAdd,
kSubtract,
kReverseSubtract
};
enum class PrimitiveType {
enum class PrimitiveType
{
kPoints,
kLines,
kLineStrip,
@ -104,44 +123,52 @@ enum class PrimitiveType {
kTriangleFan
};
enum class CullMode {
enum class CullMode
{
kNone,
kFront,
kBack
};
enum class FaceWinding {
enum class FaceWinding
{
kCounterClockwise,
kClockwise
};
enum class AttachmentLoadOp {
enum class AttachmentLoadOp
{
kLoad,
kClear,
kDontCare
};
enum class AttachmentStoreOp {
enum class AttachmentStoreOp
{
kStore,
kDontCare
};
enum class PipelineProgram {
enum class PipelineProgram
{
kUnshaded,
kUnshadedPaletted
};
enum class BufferType {
enum class BufferType
{
kVertexBuffer,
kIndexBuffer
};
enum class BufferUsage {
enum class BufferUsage
{
kImmutable,
kDynamic
};
enum class VertexAttributeName {
enum class VertexAttributeName
{
kPosition,
kNormal,
kTexCoord0,
@ -149,28 +176,32 @@ enum class VertexAttributeName {
kColor
};
enum class UniformName {
enum class UniformName
{
kTime,
kModelView,
kProjection,
kTexCoord0Transform
};
enum class SamplerName {
enum class SamplerName
{
kSampler0,
kSampler1,
kSampler2,
kSampler3
};
struct Color {
struct Color
{
float r;
float g;
float b;
float a;
};
struct Rect {
struct Rect
{
int32_t x;
int32_t y;
uint32_t w;
@ -180,35 +211,42 @@ struct Rect {
constexpr const size_t kMaxVertexAttributes = 8;
constexpr const size_t kMaxSamplers = 4;
struct ProgramVertexInput {
struct ProgramVertexInput
{
VertexAttributeName name;
VertexAttributeFormat type;
bool required;
};
struct ProgramUniformInput {
struct ProgramUniformInput
{
UniformName name;
bool required;
};
struct ProgramSamplerInput {
struct ProgramSamplerInput
{
SamplerName name;
bool required;
};
struct ProgramVertexInputRequirements {
struct ProgramVertexInputRequirements
{
srb2::StaticVec<ProgramVertexInput, kMaxVertexAttributes> attributes;
};
struct ProgramUniformRequirements {
struct ProgramUniformRequirements
{
srb2::StaticVec<srb2::StaticVec<UniformName, 16>, 4> uniform_groups;
};
struct ProgramSamplerRequirements {
struct ProgramSamplerRequirements
{
std::array<std::optional<ProgramSamplerInput>, kMaxSamplers> samplers;
};
struct ProgramRequirements {
struct ProgramRequirements
{
ProgramVertexInputRequirements vertex_input;
ProgramUniformRequirements uniforms;
ProgramSamplerRequirements samplers;
@ -221,7 +259,8 @@ const ProgramRequirements& program_requirements_for_program(PipelineProgram prog
inline constexpr const VertexAttributeFormat vertex_attribute_format(VertexAttributeName name) noexcept
{
switch (name) {
switch (name)
{
case VertexAttributeName::kPosition:
return VertexAttributeFormat::kFloat3;
case VertexAttributeName::kNormal:
@ -239,7 +278,8 @@ inline constexpr const VertexAttributeFormat vertex_attribute_format(VertexAttri
inline constexpr const UniformFormat uniform_format(UniformName name) noexcept
{
switch (name) {
switch (name)
{
case UniformName::kTime:
return UniformFormat::kFloat;
case UniformName::kModelView:
@ -253,11 +293,13 @@ inline constexpr const UniformFormat uniform_format(UniformName name) noexcept
}
}
struct VertexBufferLayoutDesc {
struct VertexBufferLayoutDesc
{
uint32_t stride;
};
struct VertexAttributeLayoutDesc {
struct VertexAttributeLayoutDesc
{
VertexAttributeName name;
uint32_t buffer_index;
uint32_t offset;
@ -265,27 +307,32 @@ struct VertexAttributeLayoutDesc {
// constexpr const size_t kMaxVertexBufferBindings = 4;
struct VertexInputDesc {
struct VertexInputDesc
{
std::vector<VertexBufferLayoutDesc> buffer_layouts;
std::vector<VertexAttributeLayoutDesc> attr_layouts;
};
struct UniformInputDesc {
struct UniformInputDesc
{
srb2::StaticVec<srb2::StaticVec<UniformName, 16>, 4> enabled_uniforms;
};
struct SamplerInputDesc {
struct SamplerInputDesc
{
std::vector<SamplerName> enabled_samplers;
};
struct ColorMask {
struct ColorMask
{
bool r;
bool g;
bool b;
bool a;
};
struct BlendDesc {
struct BlendDesc
{
BlendFactor source_factor_color;
BlendFactor dest_factor_color;
BlendFunction color_function;
@ -294,19 +341,22 @@ struct BlendDesc {
BlendFunction alpha_function;
};
struct PipelineDepthAttachmentDesc {
struct PipelineDepthAttachmentDesc
{
PixelFormat format;
CompareFunc func;
bool write;
};
struct PipelineColorAttachmentDesc {
struct PipelineColorAttachmentDesc
{
PixelFormat format;
std::optional<BlendDesc> blend;
ColorMask color_mask;
};
struct PipelineDesc {
struct PipelineDesc
{
PipelineProgram program;
VertexInputDesc vertex_input;
UniformInputDesc uniform_input;
@ -320,32 +370,37 @@ struct PipelineDesc {
Color blend_color;
};
struct RenderPassDesc {
struct RenderPassDesc
{
std::optional<PixelFormat> depth_format;
PixelFormat color_format;
AttachmentLoadOp load_op;
AttachmentStoreOp store_op;
};
struct RenderbufferDesc {
struct RenderbufferDesc
{
PixelFormat format;
uint32_t width;
uint32_t height;
};
struct TextureDesc {
struct TextureDesc
{
TextureFormat format;
uint32_t width;
uint32_t height;
};
struct BufferDesc {
struct BufferDesc
{
uint32_t size;
BufferType type;
BufferUsage usage;
};
struct RenderPassBeginInfo {
struct RenderPassBeginInfo
{
Handle<RenderPass> render_pass;
TextureOrRenderbuffer color_attachment;
std::optional<TextureOrRenderbuffer> depth_attachment;
@ -367,8 +422,7 @@ using UniformVariant = std::variant<
std::array<std::array<float, 2>, 2>,
std::array<std::array<float, 3>, 3>,
std::array<std::array<float, 4>, 4>
>;
std::array<std::array<float, 4>, 4>>;
inline constexpr UniformFormat uniform_variant_format(const UniformVariant& variant)
{
@ -382,40 +436,62 @@ inline constexpr UniformFormat uniform_variant_format(const UniformVariant& vari
UniformFormat operator()(const std::array<int32_t, 2>&) const noexcept { return UniformFormat::kInt2; }
UniformFormat operator()(const std::array<int32_t, 3>&) const noexcept { return UniformFormat::kInt3; }
UniformFormat operator()(const std::array<int32_t, 4>&) const noexcept { return UniformFormat::kInt4; }
UniformFormat operator()(const std::array<std::array<float, 2>, 2>&) const noexcept { return UniformFormat::kMat2; }
UniformFormat operator()(const std::array<std::array<float, 3>, 3>&) const noexcept { return UniformFormat::kMat3; }
UniformFormat operator()(const std::array<std::array<float, 4>, 4>&) const noexcept { return UniformFormat::kMat4; }
UniformFormat operator()(const std::array<std::array<float, 2>, 2>&) const noexcept
{
return UniformFormat::kMat2;
}
UniformFormat operator()(const std::array<std::array<float, 3>, 3>&) const noexcept
{
return UniformFormat::kMat3;
}
UniformFormat operator()(const std::array<std::array<float, 4>, 4>&) const noexcept
{
return UniformFormat::kMat4;
}
};
return std::visit(Visitor{}, variant);
return std::visit(Visitor {}, variant);
}
struct VertexAttributeBufferBinding {
struct VertexAttributeBufferBinding
{
uint32_t attribute_index;
Handle<Buffer> vertex_buffer;
};
struct TextureBinding {
struct TextureBinding
{
SamplerName name;
Handle<Texture> texture;
};
struct CreateUniformSetInfo {
struct CreateUniformSetInfo
{
tcb::span<UniformVariant> uniforms;
};
struct CreateBindingSetInfo {
struct CreateBindingSetInfo
{
tcb::span<VertexAttributeBufferBinding> vertex_buffers;
tcb::span<TextureBinding> sampler_textures;
};
struct UniformSet {};
struct BindingSet {};
struct UniformSet
{
};
struct BindingSet
{
};
struct TransferContext {};
struct GraphicsContext {};
struct TransferContext
{
};
struct GraphicsContext
{
};
/// @brief An active handle to a rendering device.
struct Rhi {
struct Rhi
{
virtual ~Rhi();
virtual Handle<RenderPass> create_render_pass(const RenderPassDesc& desc) = 0;
@ -434,10 +510,22 @@ struct Rhi {
virtual void end_transfer(Handle<TransferContext> handle) = 0;
// Transfer Context functions
virtual void update_buffer_contents(Handle<TransferContext> ctx, Handle<Buffer> buffer, uint32_t offset, tcb::span<const std::byte> data) = 0;
virtual void update_texture(Handle<TransferContext> ctx, Handle<Texture> texture, Rect region, srb2::rhi::PixelFormat data_format, tcb::span<const std::byte> data) = 0;
virtual void update_buffer_contents(
Handle<TransferContext> ctx,
Handle<Buffer> buffer,
uint32_t offset,
tcb::span<const std::byte> data
) = 0;
virtual void update_texture(
Handle<TransferContext> ctx,
Handle<Texture> texture,
Rect region,
srb2::rhi::PixelFormat data_format,
tcb::span<const std::byte> data
) = 0;
virtual Handle<UniformSet> create_uniform_set(Handle<TransferContext> ctx, const CreateUniformSetInfo& info) = 0;
virtual Handle<BindingSet> create_binding_set(Handle<TransferContext> ctx, Handle<Pipeline> pipeline, const CreateBindingSetInfo& info) = 0;
virtual Handle<BindingSet>
create_binding_set(Handle<TransferContext> ctx, Handle<Pipeline> pipeline, const CreateBindingSetInfo& info) = 0;
virtual Handle<GraphicsContext> begin_graphics() = 0;
virtual void end_graphics(Handle<GraphicsContext> ctx) = 0;

View file

@ -11,17 +11,20 @@ using namespace srb2::rhi;
SdlGlCorePlatform::~SdlGlCorePlatform() = default;
void SdlGlCorePlatform::present() {
void SdlGlCorePlatform::present()
{
SRB2_ASSERT(window != nullptr);
SRB2_ASSERT(SDL_GetWindowID(window) != 0);
SDL_GL_SwapWindow(window);
}
std::tuple<std::string, std::string> SdlGlCorePlatform::find_shader_sources(rhi::PipelineProgram program) {
std::tuple<std::string, std::string> SdlGlCorePlatform::find_shader_sources(rhi::PipelineProgram program)
{
const char* vertex_lump_name = nullptr;
const char* fragment_lump_name = nullptr;
switch (program) {
switch (program)
{
case rhi::PipelineProgram::kUnshaded:
vertex_lump_name = "rhi_glcore_vertex_unshaded";
fragment_lump_name = "rhi_glcore_fragment_unshaded";
@ -47,7 +50,8 @@ std::tuple<std::string, std::string> SdlGlCorePlatform::find_shader_sources(rhi:
return std::make_tuple(std::move(vertex_shader), std::move(fragment_shader));
}
rhi::Rect SdlGlCorePlatform::get_default_framebuffer_dimensions() {
rhi::Rect SdlGlCorePlatform::get_default_framebuffer_dimensions()
{
SRB2_ASSERT(window != nullptr);
int w;
int h;

View file

@ -1,14 +1,16 @@
#ifndef __SRB2_SDL_RHI_GLES2_PLATFORM_HPP__
#define __SRB2_SDL_RHI_GLES2_PLATFORM_HPP__
#include "../rhi/rhi.hpp"
#include "../rhi/gl3_core/gl3_core_rhi.hpp"
#include "../rhi/rhi.hpp"
#include <SDL.h>
namespace srb2::rhi {
namespace srb2::rhi
{
struct SdlGlCorePlatform final : public GlCorePlatform {
struct SdlGlCorePlatform final : public GlCorePlatform
{
SDL_Window* window = nullptr;
virtual ~SdlGlCorePlatform();

View file

@ -11,17 +11,20 @@ using namespace srb2::rhi;
SdlGles2Platform::~SdlGles2Platform() = default;
void SdlGles2Platform::present() {
void SdlGles2Platform::present()
{
SRB2_ASSERT(window != nullptr);
SRB2_ASSERT(SDL_GetWindowID(window) != 0);
SDL_GL_SwapWindow(window);
}
std::tuple<std::string, std::string> SdlGles2Platform::find_shader_sources(rhi::PipelineProgram program) {
std::tuple<std::string, std::string> SdlGles2Platform::find_shader_sources(rhi::PipelineProgram program)
{
const char* vertex_lump_name = nullptr;
const char* fragment_lump_name = nullptr;
switch (program) {
switch (program)
{
case rhi::PipelineProgram::kUnshaded:
vertex_lump_name = "rhi_glsles_vertex_unshaded";
fragment_lump_name = "rhi_glsles_fragment_unshaded";
@ -47,7 +50,8 @@ std::tuple<std::string, std::string> SdlGles2Platform::find_shader_sources(rhi::
return std::make_tuple(std::move(vertex_shader), std::move(fragment_shader));
}
rhi::Rect SdlGles2Platform::get_default_framebuffer_dimensions() {
rhi::Rect SdlGles2Platform::get_default_framebuffer_dimensions()
{
SRB2_ASSERT(window != nullptr);
int w;
int h;

View file

@ -1,14 +1,16 @@
#ifndef __SRB2_SDL_RHI_GLES2_PLATFORM_HPP__
#define __SRB2_SDL_RHI_GLES2_PLATFORM_HPP__
#include "../rhi/rhi.hpp"
#include "../rhi/gles2/gles2_rhi.hpp"
#include "../rhi/rhi.hpp"
#include <SDL.h>
namespace srb2::rhi {
namespace srb2::rhi
{
struct SdlGles2Platform final : public Gles2Platform {
struct SdlGles2Platform final : public Gles2Platform
{
SDL_Window* window = nullptr;
virtual ~SdlGles2Platform();