#pragma once #include "foundation/result.h" #include #include #include namespace pp::renderer { constexpr std::uint32_t max_texture_dimension = 32768; constexpr std::uint32_t max_mesh_vertices = 16777216; constexpr std::uint32_t max_texture_slots = 32; constexpr std::uint64_t max_texture_bytes = 1024ULL * 1024ULL * 1024ULL; constexpr std::size_t max_shader_source_bytes = 4ULL * 1024ULL * 1024ULL; enum class TextureFormat : std::uint8_t { rgba8, r8, depth24_stencil8, }; struct Extent2D { std::uint32_t width = 0; std::uint32_t height = 0; }; struct TextureDesc { Extent2D extent; TextureFormat format = TextureFormat::rgba8; bool render_target = false; }; struct ReadbackRegion { std::uint32_t x = 0; std::uint32_t y = 0; std::uint32_t width = 0; std::uint32_t height = 0; }; struct Viewport { std::int32_t x = 0; std::int32_t y = 0; std::uint32_t width = 0; std::uint32_t height = 0; float min_depth = 0.0F; float max_depth = 1.0F; }; struct ScissorRect { bool enabled = false; std::int32_t x = 0; std::int32_t y = 0; std::uint32_t width = 0; std::uint32_t height = 0; }; struct ClearColor { float r = 0.0F; float g = 0.0F; float b = 0.0F; float a = 0.0F; }; enum class PrimitiveTopology : std::uint8_t { triangles, triangle_strip, lines, }; enum class BlitFilter : std::uint8_t { nearest, linear, }; enum class BlendFactor : std::uint8_t { zero, one, source_alpha, one_minus_source_alpha, destination_alpha, one_minus_destination_alpha, }; enum class BlendOp : std::uint8_t { add, subtract, reverse_subtract, }; enum class CompareOp : std::uint8_t { never, less, equal, less_or_equal, greater, not_equal, greater_or_equal, always, }; struct BlendState { bool enabled = false; BlendFactor source_color = BlendFactor::one; BlendFactor destination_color = BlendFactor::zero; BlendOp color_op = BlendOp::add; BlendFactor source_alpha = BlendFactor::one; BlendFactor destination_alpha = BlendFactor::zero; BlendOp alpha_op = BlendOp::add; bool write_r = true; bool write_g = true; bool write_b = true; bool write_a = true; }; struct DepthState { bool test_enabled = false; bool write_enabled = false; CompareOp compare = CompareOp::less_or_equal; }; struct MeshDesc { std::uint32_t vertex_count = 0; std::uint32_t index_count = 0; PrimitiveTopology topology = PrimitiveTopology::triangles; }; struct ShaderStageSource { const char* entry_point = "main"; const char* source = nullptr; std::size_t source_size = 0; }; struct ShaderProgramDesc { const char* debug_name = ""; ShaderStageSource vertex; ShaderStageSource fragment; }; class ITexture2D { public: virtual ~ITexture2D() = default; [[nodiscard]] virtual TextureDesc desc() const noexcept = 0; }; class IRenderTarget { public: virtual ~IRenderTarget() = default; [[nodiscard]] virtual TextureDesc color_desc() const noexcept = 0; }; class IShaderProgram { public: virtual ~IShaderProgram() = default; [[nodiscard]] virtual const char* debug_name() const noexcept = 0; }; class IMesh { public: virtual ~IMesh() = default; [[nodiscard]] virtual MeshDesc desc() const noexcept = 0; }; class IReadbackBuffer { public: virtual ~IReadbackBuffer() = default; [[nodiscard]] virtual std::uint64_t size_bytes() const noexcept = 0; }; class IRenderTrace { public: virtual ~IRenderTrace() = default; virtual void marker(const char* component, const char* name) noexcept = 0; }; class ICommandContext { public: virtual ~ICommandContext() = default; [[nodiscard]] virtual pp::foundation::Status begin_render_pass( IRenderTarget& target, ClearColor clear_color) noexcept = 0; [[nodiscard]] virtual pp::foundation::Status set_viewport(Viewport viewport) noexcept = 0; [[nodiscard]] virtual pp::foundation::Status set_scissor(ScissorRect scissor) noexcept = 0; [[nodiscard]] virtual pp::foundation::Status set_blend_state(BlendState state) noexcept = 0; [[nodiscard]] virtual pp::foundation::Status set_depth_state(DepthState state) noexcept = 0; [[nodiscard]] virtual pp::foundation::Status bind_shader(IShaderProgram& shader) noexcept = 0; [[nodiscard]] virtual pp::foundation::Status bind_texture( std::uint32_t slot, ITexture2D& texture) noexcept = 0; [[nodiscard]] virtual pp::foundation::Status bind_mesh(IMesh& mesh) noexcept = 0; [[nodiscard]] virtual pp::foundation::Status draw() noexcept = 0; [[nodiscard]] virtual pp::foundation::Status read_texture( ITexture2D& texture, ReadbackRegion region, IReadbackBuffer& destination) noexcept = 0; [[nodiscard]] virtual pp::foundation::Status upload_texture( ITexture2D& texture, ReadbackRegion region, std::span rgba_or_channel_bytes) noexcept = 0; [[nodiscard]] virtual pp::foundation::Status capture_frame( IRenderTarget& target, IReadbackBuffer& destination) noexcept = 0; [[nodiscard]] virtual pp::foundation::Status blit_render_target( IRenderTarget& source, ReadbackRegion source_region, IRenderTarget& destination, ReadbackRegion destination_region, BlitFilter filter) noexcept = 0; virtual void end_render_pass() noexcept = 0; }; class IRenderDevice { public: virtual ~IRenderDevice() = default; [[nodiscard]] virtual const char* backend_name() const noexcept = 0; [[nodiscard]] virtual ICommandContext& immediate_context() noexcept = 0; [[nodiscard]] virtual IRenderTrace* trace() noexcept = 0; }; [[nodiscard]] std::uint32_t bytes_per_pixel(TextureFormat format) noexcept; [[nodiscard]] pp::foundation::Status validate_extent(Extent2D extent) noexcept; [[nodiscard]] pp::foundation::Status validate_viewport(Viewport viewport, Extent2D target_extent) noexcept; [[nodiscard]] pp::foundation::Status validate_scissor(ScissorRect scissor, Extent2D target_extent) noexcept; [[nodiscard]] pp::foundation::Status validate_blend_factor(BlendFactor factor) noexcept; [[nodiscard]] pp::foundation::Status validate_blend_op(BlendOp op) noexcept; [[nodiscard]] pp::foundation::Status validate_blend_state(BlendState state) noexcept; [[nodiscard]] pp::foundation::Status validate_compare_op(CompareOp op) noexcept; [[nodiscard]] pp::foundation::Status validate_depth_state(DepthState state) noexcept; [[nodiscard]] pp::foundation::Status validate_mesh_desc(MeshDesc desc) noexcept; [[nodiscard]] pp::foundation::Status validate_texture_slot(std::uint32_t slot) noexcept; [[nodiscard]] pp::foundation::Status validate_shader_program_desc(ShaderProgramDesc desc) noexcept; [[nodiscard]] pp::foundation::Result texture_byte_size(TextureDesc desc) noexcept; [[nodiscard]] pp::foundation::Result readback_byte_size( TextureDesc desc, ReadbackRegion region) noexcept; [[nodiscard]] pp::foundation::Result frame_capture_byte_size(TextureDesc desc) noexcept; [[nodiscard]] pp::foundation::Status validate_readback_region(TextureDesc desc, ReadbackRegion region) noexcept; [[nodiscard]] pp::foundation::Status validate_blit_filter(BlitFilter filter) noexcept; [[nodiscard]] pp::foundation::Status validate_blit_descs( TextureDesc source, TextureDesc destination) noexcept; [[nodiscard]] const char* texture_format_name(TextureFormat format) noexcept; [[nodiscard]] const char* primitive_topology_name(PrimitiveTopology topology) noexcept; [[nodiscard]] const char* blit_filter_name(BlitFilter filter) noexcept; [[nodiscard]] const char* blend_factor_name(BlendFactor factor) noexcept; [[nodiscard]] const char* blend_op_name(BlendOp op) noexcept; [[nodiscard]] const char* compare_op_name(CompareOp op) noexcept; }