hachem.wtf
aboutsummaryrefslogtreecommitdiff
path: root/src/rendering/rhi.h
blob: 7684aa00efa7f5aa70dad24383e360e3eb0e262a (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
#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,
        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 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 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;
    };
}