summaryrefslogtreecommitdiff
path: root/video.hpp
blob: 786d013d651a47d2e25398f6f4f8febdca87f45d (plain) (blame)
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
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
#ifndef video_hpp
#define video_hpp

#include <stddef.h>
#include <stdint.h>

extern "C" {
#include "vid_enums.h"
}

#include "asset.hpp"

struct App;
struct Arena;
struct Heap;

template <typename T>
struct Primitive_Id {
	T index;
	Primitive_Id(): index(0) {}
	Primitive_Id(T i): index(i) {}
	bool operator==(Primitive_Id<T> other) const {
		return index == other.index;
	}
	operator bool() const {
		return index != 0;
	}
};

struct Texture_Id : public Primitive_Id<uint32_t> {
	using Primitive_Id<uint32_t>::Primitive_Id;
};
struct Buffer_Id  : public Primitive_Id<uint32_t> {
	using Primitive_Id<uint32_t>::Primitive_Id;
};
struct Vertex_Format_Id : public Primitive_Id<uint32_t> {
	using Primitive_Id<uint32_t>::Primitive_Id;
};
struct Shader_Id : public Primitive_Id<uint32_t> {
	using Primitive_Id<uint32_t>::Primitive_Id;
};

struct Pipeline {
	Vertex_Format_Id vertex_format;
	Shader_Id shader;
};

struct Colour {
	uint8_t r, g, b, a;
};

struct Render_Pass {
	Texture_Id target;
	Colour clear;

	bool operator==(const Render_Pass& other) const {
		int size = sizeof *this, i;
		uint8_t* bba = (uint8_t*)this;
		uint8_t* bbb = (uint8_t*)&other;
		for (i = 0; i < size; i++, bba++, bbb++)
			if (*bba != *bbb) return false;
		return true;
	}
};

struct Vertex_Buffer_Binding {
	Buffer_Id id;
	size_t offset;
	int target;
};

struct Draw {
	Vertex_Buffer_Binding* verts;
	int vertex_count;
	int instance_count;
	int first_vertex;
	int first_instance;
};

struct Pipeline_Builder {
	Arena* arena;
	Render_Pass* pass;
	Pipeline* pip;

	Pipeline_Builder(Arena* arena);

	void begin_rp();
	void rp_target(Texture_Id id, Colour clear_colour);
	Render_Pass& build_rp();
	void validate_rp();

	void begin();
	void shader(Shader_Id s);
	void vertex_format(Vertex_Format_Id vf);
	Pipeline& build();
	void validate();
};

struct Texture {
	int w, h;
	bool alias;
};

namespace Buffer_Flags {
	enum {
		index_buffer   = 1 << 0,
		vertex_buffer  = 1 << 1,
		uniform_buffer = 1 << 2,
		storage_buffer = 1 << 3,
		cpu_read       = 1 << 4,
		cpu_readwrite  = 1 << 5,
		copy_src       = 1 << 6,
		copy_dst       = 1 << 7
	};
};

struct Buffer {};

struct Context;
struct Shader;
struct Device {
	Arena* arena;
	Heap* heap;
	App* app;

	static Device* create(Arena* a, App* ap);
	void init(Arena* a, App* ap);
	void destroy();

	void on_resize();

	void begin_frame();
	void submit(Context& ctx);
	void present();

	Context& acquire();
	Context& get_ctx();
	Texture_Id get_backbuffer();
	Texture& get_texture(Texture_Id id);
	void destroy_texture(Texture_Id id);

	Buffer_Id create_buffer(size_t size, int flags);
	void* map_buffer(Buffer_Id id, size_t offset, size_t size);
	void unmap_buffer(Buffer_Id id);
	Buffer& get_buffer(Buffer_Id id);
	void destroy_buffer(Buffer_Id id);

	Shader& get_shader(Shader_Id id);
};

struct Context {
	void wait(Device& d);
	void submit(
		Device& d,
		const Draw& draw,
		const Pipeline& p,
		const Render_Pass& rp
	);
	void submit(
		Device& d,
		const Draw* draws,
		int count,
		const Pipeline& p,
		const Render_Pass& rp
	);
	void submit(Device& d, const Render_Pass& rp);
};

struct Shader : public Asset {
	Shader_Id id;
	Vertex_Format_Id vf;
	void destroy(Device* dev);

	/* -1 on failure */
	int binding_index(const char* name);
	int attribute_index(const char* name);
	int target_index(const char* name);

	bool load(
		Asset_Loader* loader,
		Arena* a,
		Pack_File* f
	) override;
	void unload(Asset_Loader* loader) override;
};

#endif