mirror of
				https://github.com/KartKrewDev/RingRacers.git
				synced 2025-10-30 08:01:28 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			241 lines
		
	
	
	
		
			7.8 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			241 lines
		
	
	
	
		
			7.8 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| // SONIC ROBO BLAST 2
 | |
| //-----------------------------------------------------------------------------
 | |
| // Copyright (C) 2023 by Ronald "Eidolon" Kinard
 | |
| //
 | |
| // This program is free software distributed under the
 | |
| // terms of the GNU General Public License, version 2.
 | |
| // See the 'LICENSE' file for more details.
 | |
| //-----------------------------------------------------------------------------
 | |
| 
 | |
| #ifndef __SRB2_RHI_GL2_RHI_HPP__
 | |
| #define __SRB2_RHI_GL2_RHI_HPP__
 | |
| 
 | |
| #include <functional>
 | |
| #include <memory>
 | |
| #include <optional>
 | |
| #include <string>
 | |
| #include <tuple>
 | |
| #include <unordered_map>
 | |
| #include <vector>
 | |
| 
 | |
| #include "../rhi.hpp"
 | |
| 
 | |
| namespace srb2::rhi
 | |
| {
 | |
| 
 | |
| struct Gl2FramebufferKey
 | |
| {
 | |
| 	Handle<Texture> color;
 | |
| 	std::optional<Handle<Renderbuffer>> depth_stencil;
 | |
| 
 | |
| 	bool operator==(const Gl2FramebufferKey& rhs) const noexcept
 | |
| 	{
 | |
| 		return color == rhs.color && depth_stencil == rhs.depth_stencil;
 | |
| 	}
 | |
| 
 | |
| 	bool operator!=(const Gl2FramebufferKey& rhs) const noexcept { return !(*this == rhs); }
 | |
| };
 | |
| 
 | |
| } // namespace srb2::rhi
 | |
| 
 | |
| // To make sure the compiler selects the struct specialization of std::hash for Gl2FramebufferKey,
 | |
| // we need to split the namespace declarations _before_ the instantiation of std::unordered_map.
 | |
| 
 | |
| template <>
 | |
| struct std::hash<srb2::rhi::Gl2FramebufferKey>
 | |
| {
 | |
| 	std::size_t operator()(const srb2::rhi::Gl2FramebufferKey& key) const
 | |
| 	{
 | |
| 		std::size_t color_hash = std::hash<srb2::rhi::Handle<srb2::rhi::Texture>>()(key.color);
 | |
| 		std::size_t depth_stencil_hash = 0;
 | |
| 		if (key.depth_stencil)
 | |
| 		{
 | |
| 			depth_stencil_hash = std::hash<srb2::rhi::Handle<srb2::rhi::Renderbuffer>>()(*key.depth_stencil);
 | |
| 		}
 | |
| 		return color_hash ^ (depth_stencil_hash << 1);
 | |
| 	}
 | |
| };
 | |
| 
 | |
| struct GladGLContext;
 | |
| 
 | |
| namespace srb2::rhi
 | |
| {
 | |
| 
 | |
| typedef void (*GlProc)(void);
 | |
| typedef GlProc (*GlLoadFunc)(const char* name);
 | |
| 
 | |
| /// @brief Platform-specific implementation details for the GL2 backend.
 | |
| struct Gl2Platform
 | |
| {
 | |
| 	virtual ~Gl2Platform();
 | |
| 
 | |
| 	virtual void present() = 0;
 | |
| 	virtual std::tuple<std::vector<std::string>, std::vector<std::string>> find_shader_sources(PipelineProgram program) = 0;
 | |
| 	virtual Rect get_default_framebuffer_dimensions() = 0;
 | |
| };
 | |
| 
 | |
| struct Gl2Texture : public rhi::Texture
 | |
| {
 | |
| 	uint32_t texture;
 | |
| 	rhi::TextureDesc desc;
 | |
| };
 | |
| 
 | |
| struct Gl2Buffer : public rhi::Buffer
 | |
| {
 | |
| 	uint32_t buffer;
 | |
| 	rhi::BufferDesc desc;
 | |
| };
 | |
| 
 | |
| struct Gl2RenderPass : public rhi::RenderPass
 | |
| {
 | |
| 	rhi::RenderPassDesc desc;
 | |
| };
 | |
| 
 | |
| struct Gl2Renderbuffer : public rhi::Renderbuffer
 | |
| {
 | |
| 	uint32_t renderbuffer;
 | |
| 	rhi::RenderbufferDesc desc;
 | |
| };
 | |
| 
 | |
| struct Gl2UniformSet : public rhi::UniformSet
 | |
| {
 | |
| 	std::vector<rhi::UniformVariant> uniforms;
 | |
| };
 | |
| 
 | |
| struct Gl2BindingSet : public rhi::BindingSet
 | |
| {
 | |
| 	std::vector<rhi::VertexAttributeBufferBinding> vertex_buffer_bindings;
 | |
| 	std::unordered_map<rhi::SamplerName, uint32_t> textures {4};
 | |
| };
 | |
| 
 | |
| struct Gl2Pipeline : public rhi::Pipeline
 | |
| {
 | |
| 	uint32_t vertex_shader = 0;
 | |
| 	uint32_t fragment_shader = 0;
 | |
| 	uint32_t program = 0;
 | |
| 	std::unordered_map<rhi::VertexAttributeName, uint32_t> attrib_locations {2};
 | |
| 	std::unordered_map<rhi::UniformName, uint32_t> uniform_locations {2};
 | |
| 	std::unordered_map<rhi::SamplerName, uint32_t> sampler_locations {2};
 | |
| 	rhi::PipelineDesc desc;
 | |
| };
 | |
| 
 | |
| struct Gl2GraphicsContext : public rhi::GraphicsContext
 | |
| {
 | |
| };
 | |
| 
 | |
| struct Gl2ActiveUniform
 | |
| {
 | |
| 	uint32_t type;
 | |
| 	uint32_t location;
 | |
| };
 | |
| 
 | |
| class Gl2Rhi final : public Rhi
 | |
| {
 | |
| 	std::unique_ptr<Gl2Platform> platform_;
 | |
| 
 | |
| 	std::unique_ptr<GladGLContext> gl_;
 | |
| 
 | |
| 	Slab<Gl2RenderPass> render_pass_slab_;
 | |
| 	Slab<Gl2Texture> texture_slab_;
 | |
| 	Slab<Gl2Buffer> buffer_slab_;
 | |
| 	Slab<Gl2Renderbuffer> renderbuffer_slab_;
 | |
| 	Slab<Gl2Pipeline> pipeline_slab_;
 | |
| 	Slab<Gl2UniformSet> uniform_set_slab_;
 | |
| 	Slab<Gl2BindingSet> binding_set_slab_;
 | |
| 
 | |
| 	Handle<Buffer> current_index_buffer_;
 | |
| 
 | |
| 	std::unordered_map<Gl2FramebufferKey, uint32_t> framebuffers_ {16};
 | |
| 
 | |
| 	struct DefaultRenderPassState
 | |
| 	{
 | |
| 	};
 | |
| 	using RenderPassState = std::variant<DefaultRenderPassState, RenderPassBeginInfo>;
 | |
| 	std::optional<RenderPassState> current_render_pass_;
 | |
| 	std::optional<Handle<Pipeline>> current_pipeline_;
 | |
| 	PrimitiveType current_primitive_type_ = PrimitiveType::kPoints;
 | |
| 	bool graphics_context_active_ = false;
 | |
| 	uint32_t graphics_context_generation_ = 1;
 | |
| 	uint32_t index_buffer_offset_ = 0;
 | |
| 
 | |
| 	uint8_t stencil_front_reference_ = 0;
 | |
| 	uint8_t stencil_front_compare_mask_ = 0xFF;
 | |
| 	uint8_t stencil_front_write_mask_ = 0xFF;
 | |
| 	uint8_t stencil_back_reference_ = 0;
 | |
| 	uint8_t stencil_back_compare_mask_ = 0xFF;
 | |
| 	uint8_t stencil_back_write_mask_ = 0xFF;
 | |
| 
 | |
| public:
 | |
| 	Gl2Rhi(std::unique_ptr<Gl2Platform>&& platform, GlLoadFunc load_func);
 | |
| 	virtual ~Gl2Rhi();
 | |
| 
 | |
| 	virtual Handle<RenderPass> create_render_pass(const RenderPassDesc& desc) override;
 | |
| 	virtual void destroy_render_pass(Handle<RenderPass> handle) override;
 | |
| 	virtual Handle<Pipeline> create_pipeline(const PipelineDesc& desc) override;
 | |
| 	virtual void destroy_pipeline(Handle<Pipeline> handle) override;
 | |
| 
 | |
| 	virtual Handle<Texture> create_texture(const TextureDesc& desc) override;
 | |
| 	virtual void destroy_texture(Handle<Texture> handle) override;
 | |
| 	virtual Handle<Buffer> create_buffer(const BufferDesc& desc) override;
 | |
| 	virtual void destroy_buffer(Handle<Buffer> handle) override;
 | |
| 	virtual Handle<Renderbuffer> create_renderbuffer(const RenderbufferDesc& desc) override;
 | |
| 	virtual void destroy_renderbuffer(Handle<Renderbuffer> handle) override;
 | |
| 
 | |
| 	virtual TextureDetails get_texture_details(Handle<Texture> texture) override;
 | |
| 	virtual Rect get_renderbuffer_size(Handle<Renderbuffer> renderbuffer) override;
 | |
| 	virtual uint32_t get_buffer_size(Handle<Buffer> buffer) override;
 | |
| 
 | |
| 	virtual void update_buffer(
 | |
| 		Handle<GraphicsContext> ctx,
 | |
| 		Handle<Buffer> buffer,
 | |
| 		uint32_t offset,
 | |
| 		tcb::span<const std::byte> data
 | |
| 	) override;
 | |
| 	virtual void update_texture(
 | |
| 		Handle<GraphicsContext> 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<GraphicsContext> ctx, const CreateUniformSetInfo& info) override;
 | |
| 	virtual Handle<BindingSet>
 | |
| 	create_binding_set(Handle<GraphicsContext> ctx, Handle<Pipeline> pipeline, const CreateBindingSetInfo& info)
 | |
| 		override;
 | |
| 
 | |
| 	virtual Handle<GraphicsContext> begin_graphics() override;
 | |
| 	virtual void end_graphics(Handle<GraphicsContext> ctx) override;
 | |
| 
 | |
| 	// Graphics context functions
 | |
| 	virtual void begin_default_render_pass(Handle<GraphicsContext> ctx, bool clear) override;
 | |
| 	virtual void begin_render_pass(Handle<GraphicsContext> ctx, const RenderPassBeginInfo& info) override;
 | |
| 	virtual void end_render_pass(Handle<GraphicsContext> ctx) override;
 | |
| 	virtual void bind_pipeline(Handle<GraphicsContext> ctx, Handle<Pipeline> pipeline) override;
 | |
| 	virtual void bind_uniform_set(Handle<GraphicsContext> ctx, uint32_t slot, Handle<UniformSet> set) override;
 | |
| 	virtual void bind_binding_set(Handle<GraphicsContext> ctx, Handle<BindingSet> set) override;
 | |
| 	virtual void bind_index_buffer(Handle<GraphicsContext> ctx, Handle<Buffer> buffer) override;
 | |
| 	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
 | |
| 	read_pixels(Handle<GraphicsContext> ctx, const Rect& rect, PixelFormat format, tcb::span<std::byte> out) override;
 | |
| 	virtual void copy_framebuffer_to_texture(
 | |
| 		Handle<GraphicsContext> ctx,
 | |
| 		Handle<Texture> dst_tex,
 | |
| 		const Rect& dst_region,
 | |
| 		const Rect& src_region
 | |
| 	) override;
 | |
| 	virtual void set_stencil_reference(Handle<GraphicsContext> ctx, CullMode face, uint8_t reference) override;
 | |
| 	virtual void set_stencil_compare_mask(Handle<GraphicsContext> ctx, CullMode face, uint8_t mask) override;
 | |
| 	virtual void set_stencil_write_mask(Handle<GraphicsContext> ctx, CullMode face, uint8_t mask) override;
 | |
| 
 | |
| 	virtual void present() override;
 | |
| 
 | |
| 	virtual void finish() override;
 | |
| };
 | |
| 
 | |
| } // namespace srb2::rhi
 | |
| 
 | |
| #endif // __SRB2_RHI_GL2_RHI_HPP__
 | 
