hachem.wtf
aboutsummaryrefslogtreecommitdiff
path: root/src/rendering/rhi.h
blob: ddbcceb4de17f044fec29bc17efbd1653dbaa76c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
#pragma once

#include "core/memory.h"
#include <glm/glm.hpp>
#include <cstdint>
#include <string>
#include <vector>
#include <functional>

namespace Donut::RHI
{
    enum class Format
    {
        None,
        Swapchain,
        RGBA8,
        RGBA16F,
        RGBA32F,
        D32,
    };

    struct RenderTargetFormat
    {
        Format color = Format::RGBA8;
        Format depth = Format::None;
    };

    struct NativeWindow
    {
        void* glfw_handle = nullptr;
        int   width  = 0;
        int   height = 0;
    };

    enum class BufferType { Vertex, Index, Uniform };
    enum class Topology   { Triangles, Lines };
    enum class CullMode   { None, Back, Front };
    enum class BlendMode  { Opaque, AlphaBlend };
    enum class CompareOp  { Always, Less, LessEqual };
    enum class Filter     { Nearest, Linear };

    struct VertexAttribute { uint32_t location; uint32_t components; uint32_t offset; };
    struct VertexLayout    { uint32_t stride = 0; std::vector<VertexAttribute> attributes; };

    enum class ResourceKind { UniformBuffer, Texture };
    struct ResourceSlot { ResourceKind kind; uint32_t binding; std::string name; };

    class Buffer  { public: virtual ~Buffer() = default; virtual auto update(const void* data, size_t size) -> void = 0; };
    class Texture { public: virtual ~Texture() = default; };
    class Pipeline{ public: virtual ~Pipeline() = default; };

    class RenderTarget
    {
    public:
        virtual ~RenderTarget() = default;
        virtual auto width()  const -> int = 0;
        virtual auto height() const -> int = 0;
        virtual auto color_texture() -> Texture* = 0;
    };

    struct PipelineDesc
    {
        std::string  shader;
        VertexLayout vertex_layout;
        std::vector<ResourceSlot> resources;
        Topology  topology    = Topology::Triangles;
        CullMode  cull        = CullMode::None;
        BlendMode blend       = BlendMode::Opaque;
        bool      depth_test  = false;
        bool      depth_write = false;
        CompareOp depth_op    = CompareOp::Less;
        RenderTargetFormat target;
    };

    class CommandList
    {
    public:
        virtual ~CommandList() = default;

        virtual auto begin_render_pass(RenderTarget* target, const glm::vec4& clear) -> void = 0;
        virtual auto end_render_pass() -> void = 0;

        virtual auto bind_pipeline(Pipeline* pipeline) -> void = 0;
        virtual auto set_viewport(int x, int y, int w, int h, bool flip_y = false) -> void = 0;

        virtual auto bind_uniform(uint32_t binding, Buffer* ubo) -> void = 0;
        virtual auto bind_texture(uint32_t binding, Texture* texture) -> void = 0;

        virtual auto bind_vertex_buffer(Buffer* vb) -> void = 0;
        virtual auto bind_index_buffer(Buffer* ib) -> void = 0;

        virtual auto draw(uint32_t vertex_count) -> void = 0;
        virtual auto draw_indexed(uint32_t index_count) -> void = 0;
    };

    class Device
    {
    public:
        virtual ~Device() = default;

        virtual auto init(const NativeWindow& window) -> bool = 0;
        virtual auto shutdown() -> void = 0;
        virtual auto resize(int width, int height) -> void = 0;
        virtual auto wait_idle() -> void = 0;

        virtual auto set_vsync(bool enabled) -> void { (void)enabled; }

        virtual auto create_buffer(BufferType type, size_t size, const void* data = nullptr) -> Ref<Buffer> = 0;
        virtual auto create_texture(int width, int height, Format format, Filter filter, const void* data = nullptr) -> Ref<Texture> = 0;
        virtual auto create_cubemap_from_hdri(const std::string& equirect_path) -> Ref<Texture> = 0;
        virtual auto create_render_target(int width, int height, Format color, Format depth = Format::None,
                                          Filter sample_filter = Filter::Linear, int mip_levels = 1) -> Ref<RenderTarget> = 0;
        virtual auto create_pipeline(const PipelineDesc& desc) -> Ref<Pipeline> = 0;

        virtual auto begin_frame(const glm::vec4& clear) -> CommandList* = 0;
        virtual auto end_frame() -> void = 0;

        virtual auto run_offscreen(const std::function<void(CommandList&)>& record) -> void = 0;

        virtual auto read_render_target(RenderTarget* target, std::vector<uint8_t>& out) -> void = 0;

        virtual auto read_render_target_float(RenderTarget* target, std::vector<float>& out) -> void = 0;

        virtual auto init_imgui() -> void = 0;
        virtual auto imgui_new_frame() -> void = 0;
        virtual auto imgui_render(CommandList& swapchain_cmds) -> void = 0;

        virtual auto device_name() const -> const std::string& = 0;
    };
}