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
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
|
#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 Sampler_Id : public Primitive_Id<uint32_t> {
using Primitive_Id<uint32_t>::Primitive_Id;
};
struct Descriptor {
enum class Type {
texture
} type;
int slot;
Descriptor* next;
};
struct Texture_Descriptor : public Descriptor {
Sampler_Id sampler;
Texture_Id texture;
};
struct Pipeline {
Vertex_Format_Id vertex_format;
Shader_Id shader;
Descriptor* descriptors;
int count_descriptors() const {
const Descriptor* d = descriptors;
int c = 0;
for (; d; d = d->next)
c++;
return c;
}
};
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);
void texture(int binding, Texture_Id t, Sampler_Id s);
Pipeline& build();
void validate();
};
enum Resource_State {
undefined,
copy_dst,
copy_src,
shader_read
};
struct Texture : public Asset {
Texture_Id id;
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 {
Buffer_Id id;
};
enum class Filter_Mode {
point,
linear
};
enum class Address_Mode {
repeat,
mirror,
clamp,
border
};
struct Sampler_State {
Filter_Mode min;
Filter_Mode mag;
Filter_Mode mip;
Address_Mode address_u;
Address_Mode address_v;
Address_Mode address_w;
float border[4];
float mip_bias;
bool aniso;
};
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);
Sampler_Id create_sampler(const Sampler_State& state);
void destroy_sampler(Sampler_Id id);
};
struct Context {
void wait();
void submit(
const Draw& draw,
const Pipeline& p,
const Render_Pass& rp
);
void submit(
const Draw* draws,
int count,
const Pipeline& p,
const Render_Pass& rp
);
void submit(const Render_Pass& rp);
void copy(Buffer_Id dst, Buffer_Id src);
void copy(Texture_Id dst, Buffer_Id src);
void transition(Texture_Id id, Resource_State state);
};
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);
int descriptor_index(const char* name);
int descriptor_stage(int slot);
};
#endif
|