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
|
#pragma once
#include "core/memory.h"
#include <glm/glm.hpp>
#include <cstdint>
#include <string>
#include <vector>
#include <functional>
namespace Donut::rhi
{
enum class Format
{
RGBA8,
RGBA16F,
D32,
};
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; };
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;
Format color_format = Format::RGBA8;
bool has_depth = false;
};
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(void* glfwWindow, int width, int height) -> 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, bool with_depth,
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 record_offscreen(const std::function<void(CommandList&)>& record) -> 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;
};
}
|