Created
April 5, 2016 10:24
-
-
Save jsimmons/0805d9ac5c07947cc7b02a667dfc8add to your computer and use it in GitHub Desktop.
GLFAST + MINIMAL GL
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdint.h> | |
#include <stdbool.h> | |
#include <X11/Xlib.h> | |
#include <X11/Xutil.h> | |
#include <X11/XKBlib.h> | |
#include <dlfcn.h> | |
#include <stdio.h> | |
#include <sys/syscall.h> | |
#include <time.h> | |
#define SCRW 800 | |
#define SCRH 600 | |
#ifndef i8 | |
#define i8 int8_t | |
#endif | |
#ifndef i16 | |
#define i16 int16_t | |
#endif | |
#ifndef i32 | |
#define i32 int32_t | |
#endif | |
#ifndef i64 | |
#define i64 int64_t | |
#endif | |
#ifndef u8 | |
#define u8 uint8_t | |
#endif | |
#ifndef u16 | |
#define u16 uint16_t | |
#endif | |
#ifndef u32 | |
#define u32 uint32_t | |
#endif | |
#ifndef u64 | |
#define u64 uint64_t | |
#endif | |
#ifndef f16 | |
#define f16 uint16_t | |
#endif | |
#ifndef f32 | |
#define f32 float | |
#endif | |
#ifndef f64 | |
#define f64 double | |
#endif | |
#define GL_TRUE 1 | |
#define GL_FALSE 0 | |
#define GL_R8 0x8229 | |
#define GL_R16F 0x822D | |
#define GL_R32F 0x822E | |
#define GL_R8I 0x8231 | |
#define GL_R16I 0x8233 | |
#define GL_R32I 0x8235 | |
#define GL_R8UI 0x8232 | |
#define GL_R16UI 0x8234 | |
#define GL_R32UI 0x8236 | |
#define GL_RG8 0x822B | |
#define GL_RG16F 0x822F | |
#define GL_RG32F 0x8230 | |
#define GL_RG8I 0x8237 | |
#define GL_RG16I 0x8239 | |
#define GL_RG32I 0x823B | |
#define GL_RG8UI 0x8238 | |
#define GL_RG16UI 0x823A | |
#define GL_RG32UI 0x823C | |
#define GL_RGB16F 0x881B | |
#define GL_RGB32F 0x8815 | |
#define GL_RGB32I 0x8D83 | |
#define GL_RGB32UI 0x8D71 | |
#define GL_RGBA8 0x8058 | |
#define GL_RGBA16F 0x881A | |
#define GL_RGBA32F 0x8814 | |
#define GL_RGBA8I 0x8D8E | |
#define GL_RGBA16I 0x8D88 | |
#define GL_RGBA32I 0x8D82 | |
#define GL_RGBA8UI 0x8D7C | |
#define GL_RGBA16UI 0x8D76 | |
#define GL_RGBA32UI 0x8D70 | |
#define GL_RGB8 0x8051 | |
#define GL_SRGB8 0x8C41 | |
#define GL_SRGB8_ALPHA8 0x8C43 | |
#define GL_DEPTH_COMPONENT16 0x81A5 | |
#define GL_DEPTH_COMPONENT24 0x81A6 | |
#define GL_DEPTH_COMPONENT32 0x81A7 | |
#define GL_TEXTURE_BUFFER 0x8C2A | |
#define GL_MAP_WRITE_BIT 0x0002 | |
#define GL_MAP_PERSISTENT_BIT 0x0040 | |
#define GL_MAP_COHERENT_BIT 0x0080 | |
#define GL_FRAMEBUFFER 0x8D40 | |
#define GL_DEPTH_BUFFER_BIT 0x00000100 | |
#define GL_COLOR_BUFFER_BIT 0x00004000 | |
#define GL_DEPTH_ATTACHMENT 0x8D00 | |
#define GL_COLOR_ATTACHMENT0 0x8CE0 | |
#define GL_TEXTURE_2D_ARRAY 0x8C1A | |
#define GL_TEXTURE_CUBE_MAP_ARRAY 0x9009 | |
#define GL_RGB 0x1907 | |
#define GL_RGBA 0x1908 | |
#define GL_BGR 0x80E0 | |
#define GL_BGRA 0x80E1 | |
#define GL_BYTE 0x1400 | |
#define GL_UNSIGNED_BYTE 0x1401 | |
#define GL_SHORT 0x1402 | |
#define GL_UNSIGNED_SHORT 0x1403 | |
#define GL_INT 0x1404 | |
#define GL_UNSIGNED_INT 0x1405 | |
#define GL_FLOAT 0x1406 | |
#define GL_NEAREST 0x2600 | |
#define GL_LINEAR 0x2601 | |
#define GL_NEAREST_MIPMAP_NEAREST 0x2700 | |
#define GL_LINEAR_MIPMAP_NEAREST 0x2701 | |
#define GL_NEAREST_MIPMAP_LINEAR 0x2702 | |
#define GL_LINEAR_MIPMAP_LINEAR 0x2703 | |
#define GL_TEXTURE_MAG_FILTER 0x2800 | |
#define GL_TEXTURE_MIN_FILTER 0x2801 | |
#define GL_TEXTURE_WRAP_S 0x2802 | |
#define GL_TEXTURE_WRAP_T 0x2803 | |
#define GL_REPEAT 0x2901 | |
#define GL_TEXTURE_MAX_ANISOTROPY 0x84FE | |
#define GL_FRAGMENT_SHADER 0x8B30 | |
#define GL_VERTEX_SHADER 0x8B31 | |
#define GL_VERTEX_SHADER_BIT 0x00000001 | |
#define GL_FRAGMENT_SHADER_BIT 0x00000002 | |
#define GL_CULL_FACE 0x0B44 | |
#define GL_BLEND 0x0BE2 | |
#define GL_DEPTH_TEST 0x0B71 | |
#define GL_FRAMEBUFFER_SRGB 0x8DB9 | |
#define GL_TEXTURE_CUBE_MAP_SEAMLESS 0x884F | |
#define GL_TRIANGLES 0x0004 | |
#define GL_DEBUG_SOURCE_API 0x8246 | |
#define GL_DEBUG_SEVERITY_NOTIFICATION 0x826B | |
#define GL_DEBUG_SEVERITY_HIGH 0x9146 | |
#define GL_DEBUG_TYPE_ERROR 0x824C | |
#define GLX_RGBA 4 | |
#define GLX_DOUBLEBUFFER 5 | |
#define GLX_DEPTH_SIZE 12 | |
typedef struct {} *GLXContext; | |
typedef XID GLXDrawable; | |
#define countof(x) (sizeof(x) / sizeof((x)[0])) | |
static __inline long __syscall2(long n, long a1, long a2) | |
{ | |
unsigned long ret; | |
__asm__ __volatile__ ("syscall" : "=a"(ret) : "a"(n), "D"(a1), "S"(a2) | |
: "rcx", "r11", "memory"); | |
return ret; | |
} | |
static __inline uint64_t time_monotonic(void) | |
{ | |
struct timespec now; | |
__syscall2(SYS_clock_gettime, CLOCK_MONOTONIC_RAW, (long)&now); | |
return now.tv_sec * 1000000 + now.tv_nsec / 1000; | |
} | |
static int visual_hints[] = { | |
GLX_RGBA, | |
GLX_DEPTH_SIZE, 24, | |
GLX_DOUBLEBUFFER, | |
None | |
}; | |
static const char *sym_names = | |
"libX11.so\0" | |
"XOpenDisplay\0" | |
"XCreateSimpleWindow\0" | |
"XSelectInput\0" | |
"XMapWindow\0" | |
"XPending\0" | |
"XNextEvent\0" | |
"XkbKeycodeToKeysym\0" | |
"\0" | |
"libGL.so\0" | |
"glXChooseVisual\0" | |
"glXCreateContext\0" | |
"glXMakeCurrent\0" | |
"glXSwapBuffers\0" | |
"glClear\0" | |
"glFinish\0" | |
"glEnable\0" | |
"glDisable\0" | |
"glViewport\0" | |
"glCreateBuffers\0" | |
"glCreateTextures\0" | |
"glCreateSamplers\0" | |
"glCreateFramebuffers\0" | |
"glCreateShaderProgramv\0" | |
"glCreateProgramPipelines\0" | |
"glDeleteBuffers\0" | |
"glDeleteTextures\0" | |
"glDeleteSamplers\0" | |
"glDeleteFramebuffers\0" | |
"glDeleteProgram\0" | |
"glDeleteProgramPipelines\0" | |
"glBindTextures\0" | |
"glBindSamplers\0" | |
"glBindFramebuffer\0" | |
"glBindProgramPipeline\0" | |
"glNamedBufferStorage\0" | |
"glMapNamedBufferRange\0" | |
"glTextureBuffer\0" | |
"glTextureStorage3D\0" | |
"glTextureSubImage3D\0" | |
"glGetTextureSubImage\0" | |
"glGenerateTextureMipmap\0" | |
"glSamplerParameteri\0" | |
"glNamedFramebufferTextureLayer\0" | |
"glNamedFramebufferDrawBuffers\0" | |
"glUseProgramStages\0" | |
"glDrawArraysInstancedBaseInstance\0" | |
"glProgramUniform1uiv\0" | |
"glProgramUniform1iv\0" | |
"glProgramUniform1dv\0" | |
"glProgramUniform1fv\0" | |
"glProgramUniform2fv\0" | |
"glProgramUniform3fv\0" | |
"glProgramUniform4fv\0\0\0"; | |
static void *syms[51]; | |
#define _XOpenDisplay ((Display *(*)(const char *))syms[0]) | |
#define _XCreateSimpleWindow ((Window (*)(Display *, Window, int, int, unsigned, unsigned, unsigned, unsigned long, unsigned long))syms[1]) | |
#define _XSelectInput ((int (*)(Display *, Window, long))syms[2]) | |
#define _XMapWindow ((int (*)(Display *, Window))syms[3]) | |
#define _XPending ((int (*)(Display *))syms[4]) | |
#define _XNextEvent ((int (*)(Display *, XEvent *))syms[5]) | |
#define _XkbKeycodeToKeysym ((KeySym (*)(Display *, KeyCode, int, int))syms[6]) | |
#define _glXChooseVisual ((XVisualInfo *(*)(Display *, int, int *))syms[7]) | |
#define _glXCreateContext ((GLXContext (*)(Display *, XVisualInfo *, GLXContext, Bool))syms[8]) | |
#define _glXMakeCurrent ((bool (*)(Display *, GLXDrawable, GLXContext))syms[9]) | |
#define _glXSwapBuffers ((void (*)(Display *, GLXDrawable))syms[10]) | |
#define _glClear ((void (*)(u32))syms[11]) | |
#define _glFinish ((void (*)())syms[12]) | |
#define _glEnable ((void (*)(u32 cap))syms[13]) | |
#define _glDisable ((void (*)(u32 cap))syms[14]) | |
#define _glViewport ((void (*)(i32 x, i32 y, i32 w, i32 h))syms[15]) | |
#define _glCreateBuffers ((void (*)(i32 n, u32 *buffers))syms[16]) | |
#define _glCreateTextures ((void (*)(u32 target, i32 n, u32 *textures))syms[17]) | |
#define _glCreateSamplers ((void (*)(i32 n, u32 *samplers))syms[18]) | |
#define _glCreateFramebuffers ((void (*)(i32 n, u32 * framebuffers))syms[19]) | |
#define _glCreateShaderProgramv ((u32 (*)(u32 type, i32 count, const char ** strings))syms[20]) | |
#define _glCreateProgramPipelines ((void (*)(i32 n, u32 * pipelines))syms[21]) | |
#define _glDeleteBuffers ((void (*)(i32 n, const u32 * buffers))syms[22]) | |
#define _glDeleteTextures ((void (*)(i32 n, const u32 * textures))syms[23]) | |
#define _glDeleteSamplers ((void (*)(i32 n, const u32 * samplers))syms[24]) | |
#define _glDeleteFramebuffers ((void (*)(i32 n, const u32 * framebuffers))syms[25]) | |
#define _glDeleteProgram ((void (*)(u32 program))syms[26]) | |
#define _glDeleteProgramPipelines ((void (*)(i32 n, const u32 * pipelines))syms[27]) | |
#define _glBindTextures ((void (*)(u32 first, i32 count, const u32 * textures))syms[28]) | |
#define _glBindSamplers ((void (*)(u32 first, i32 count, const u32 * samplers))syms[29]) | |
#define _glBindFramebuffer ((void (*)(u32 target, u32 framebuffer))syms[30]) | |
#define _glBindProgramPipeline ((void (*)(u32 pipeline))syms[31]) | |
#define _glNamedBufferStorage ((void (*)(u32 buffer, ptrdiff_t size, const void * data, u32 flags))syms[32]) | |
#define _glMapNamedBufferRange ((void *(*)(u32 buffer, ptrdiff_t offset, ptrdiff_t length, u32 access))syms[33]) | |
#define _glTextureBuffer ((void (*)(u32 texture, u32 internalformat, u32 buffer))syms[34]) | |
#define _glTextureStorage3D ((void (*)(u32 texture, i32 levels, u32 internalformat, i32 width, i32 height, i32 depth))syms[35]) | |
#define _glTextureSubImage3D ((void (*)(u32 texture, i32 level, i32 xoffset, i32 yoffset, i32 zoffset, i32 width, i32 height, i32 depth, u32 format, u32 type, const void * pixels))syms[36]) | |
#define _glGetTextureSubImage ((void (*)(u32 texture, i32 level, i32 xoffset, i32 yoffset, i32 zoffset, i32 width, i32 height, i32 depth, u32 format, u32 type, i32 bufSize, void * pixels))syms[37]) | |
#define _glGenerateTextureMipmap ((void (*)(u32 texture))syms[38]) | |
#define _glSamplerParameteri ((void (*)(u32 sampler, u32 pname, i32 param))syms[39]) | |
#define _glNamedFramebufferTextureLayer ((void (*)(u32 framebuffer, u32 attachment, u32 texture, i32 level, i32 layer))syms[40]) | |
#define _glNamedFramebufferDrawBuffers ((void (*)(u32 framebuffer, i32 n, const u32 * bufs))syms[41]) | |
#define _glUseProgramStages ((void (*)(u32 pipeline, u32 stages, u32 program))syms[42]) | |
#define _glDrawArraysInstancedBaseInstance ((void (*)(u32 mode, i32 first, i32 count, i32 instancecount, u32 baseinstance))syms[43]) | |
#define _glProgramUniform1uiv ((void (*)(u32 program, i32 location, i32 count, const u32 * value))syms[44]) | |
#define _glProgramUniform1iv ((void (*)(u32 program, i32 location, i32 count, const i32 * value))syms[45]) | |
#define _glProgramUniform1dv ((void (*)(u32 program, i32 location, i32 count, const f64 * value))syms[46]) | |
#define _glProgramUniform1fv ((void (*)(u32 program, i32 location, i32 count, const f32 * value))syms[47]) | |
#define _glProgramUniform2fv ((void (*)(u32 program, i32 location, i32 count, const f32 * value))syms[48]) | |
#define _glProgramUniform3fv ((void (*)(u32 program, i32 location, i32 count, const f32 * value))syms[49]) | |
#define _glProgramUniform4fv ((void (*)(u32 program, i32 location, i32 count, const f32 * value))syms[50]) | |
static void dl_load(void) | |
{ | |
const char *name = sym_names; | |
void **sym = syms; | |
do | |
{ | |
void *dl = dlopen(name, RTLD_LAZY | RTLD_GLOBAL); | |
for(;;) | |
{ | |
while(*name++); | |
if(*name == 0) break; | |
*sym++ = dlsym(dl, name); | |
} | |
} while(*++name); | |
} | |
#define x_b8 GL_R8 | |
#define x_f16 GL_R16F | |
#define x_f32 GL_R32F | |
#define x_i8 GL_R8I | |
#define x_i16 GL_R16I | |
#define x_i32 GL_R32I | |
#define x_u8 GL_R8UI | |
#define x_u16 GL_R16UI | |
#define x_u32 GL_R32UI | |
#define xy_b8 GL_RG8 | |
#define xy_f16 GL_RG16F | |
#define xy_f32 GL_RG32F | |
#define xy_i8 GL_RG8I | |
#define xy_i16 GL_RG16I | |
#define xy_i32 GL_RG32I | |
#define xy_u8 GL_RG8UI | |
#define xy_u16 GL_RG16UI | |
#define xy_u32 GL_RG32UI | |
#define xyz_f32 GL_RGB32F | |
#define xyz_i32 GL_RGB32I | |
#define xyz_u32 GL_RGB32UI | |
#define xyzw_b8 GL_RGBA8 | |
#define xyzw_f16 GL_RGBA16F | |
#define xyzw_f32 GL_RGBA32F | |
#define xyzw_i8 GL_RGBA8I | |
#define xyzw_i16 GL_RGBA16I | |
#define xyzw_i32 GL_RGBA32I | |
#define xyzw_u8 GL_RGBA8UI | |
#define xyzw_u16 GL_RGBA16UI | |
#define xyzw_u32 GL_RGBA32UI | |
#define rgb_b8 GL_RGB8 | |
#define rgba_b8 GL_RGBA8 | |
#define srgb_b8 GL_SRGB8 | |
#define srgba_b8 GL_SRGB8_ALPHA8 | |
#define rgba_f16 GL_RGBA16F | |
#define rgba_f32 GL_RGBA32F | |
#define depth_b16 GL_DEPTH_COMPONENT16 | |
#define depth_b24 GL_DEPTH_COMPONENT24 | |
#define depth_b32 GL_DEPTH_COMPONENT32 | |
#define GF_TO_STRING(x) #x | |
#define GF_VERT_HEAD \ | |
"#version 330\n" \ | |
"#extension GL_ARB_shader_precision : enable\n" \ | |
"#extension GL_ARB_separate_shader_objects : enable\n" \ | |
"#extension GL_ARB_shading_language_420pack : enable\n" \ | |
"#extension GL_ARB_explicit_uniform_location : enable\n" \ | |
"out gl_PerVertex { vec4 gl_Position; };\n" | |
#define GF_FRAG_HEAD \ | |
"#version 330\n" \ | |
"#extension GL_ARB_shader_precision : enable\n" \ | |
"#extension GL_ARB_conservative_depth : enable\n" \ | |
"#extension GL_ARB_texture_cube_map_array : enable\n" \ | |
"#extension GL_ARB_separate_shader_objects : enable\n" \ | |
"#extension GL_ARB_shading_language_420pack : enable\n" \ | |
"#extension GL_ARB_shading_language_packing : enable\n" \ | |
"#extension GL_ARB_explicit_uniform_location : enable\n" \ | |
"layout(depth_unchanged) out float gl_FragDepth;\n" | |
typedef struct | |
{ | |
union | |
{ | |
u8 * ptr; | |
i8 * as_i8; | |
u8 * as_u8; | |
i16 * as_i16; | |
u16 * as_u16; | |
i32 * as_i32; | |
u32 * as_u32; | |
f32 * as_f32; | |
struct | |
{ | |
union { f32 x; f32 u; }; | |
union { f32 y; f32 v; }; | |
} * as_vec2; | |
struct | |
{ | |
union { f32 x; f32 r; }; | |
union { f32 y; f32 g; }; | |
union { f32 z; f32 b; }; | |
} * as_vec3; | |
struct | |
{ | |
union { f32 x; f32 r; }; | |
union { f32 y; f32 g; }; | |
union { f32 z; f32 b; }; | |
union { f32 w; f32 a; }; | |
} * as_vec4; | |
}; | |
u32 bytes; | |
u32 count; | |
u32 format; | |
u32 buffer_id; | |
u32 id; | |
} gpu_storage_t; | |
typedef struct | |
{ | |
i32 w; | |
i32 h; | |
i32 count; | |
u32 format; | |
i32 mipmap; | |
u8 cubemap; | |
u32 id; | |
} gpu_texture_t; | |
typedef struct | |
{ | |
i32 aniso; | |
i32 min; | |
i32 mag; | |
i32 wrap; | |
u32 id; | |
} gpu_sampler_t; | |
typedef struct | |
{ | |
u32 count; | |
u32 instance_count; | |
u32 first; | |
u32 instance_first; | |
} gpu_cmd_t; | |
gpu_storage_t gfStorageCreateFromStruct(gpu_storage_t tbo); | |
gpu_texture_t gfTextureCreateFromStruct(gpu_texture_t texture); | |
gpu_sampler_t gfSamplerCreateFromStruct(gpu_sampler_t sampler); | |
gpu_texture_t gfTextureCreateFromBmp(i32 width, i32 height, i32 mipmap, i32 texture_count, const char ** texture_paths); | |
gpu_texture_t gfCubemapCreateFromBmp(i32 width, i32 height, i32 mipmap, i32 texture_count, const char ** pos_x_texture_paths, const char ** neg_x_texture_paths, const char ** pos_y_texture_paths, const char ** neg_y_texture_paths, const char ** pos_z_texture_paths, const char ** neg_z_texture_paths); | |
void gfTextureSetPixels(u32 texture_id, i32 texture_layer, i32 x, i32 y, i32 width, i32 height, u32 pixels_format, u32 pixels_type, const void * data); | |
void gfTextureGetPixels(u32 texture_id, i32 texture_layer, i32 x, i32 y, i32 width, i32 height, u32 pixels_format, u32 pixels_type, i32 pixels_bytes, void * pixels); | |
void gfTextureSaveToBmp(u32 texture_id, i32 texture_layer, i32 width, i32 height, const char * bmp_filepath); | |
u32 gfFboCreate(u32 depth_texture_id, i32 depth_texture_layer, i32 color_texture_count, const u32 * color_texture_ids, const i32 * color_texture_layers); | |
void gfFboBind(u32 fbo_id); | |
u32 gfProgramCreateFromFile(u32 shader_type, const char * shader_filepath); | |
u32 gfProgramCreateFromString(u32 shader_type, const char * shader_string); | |
u32 gfProgramPipelineCreate(u32 vert_program, u32 frag_program); | |
void gfClear(); | |
void gfDraw(u32 program_pipeline, u32 gpu_cmd_count, const gpu_cmd_t * gpu_cmd); | |
void gfFire(u32 program_pipeline, u32 count); | |
void my_main(int argc, const char **argv) | |
{ | |
dl_load(); | |
Display *display = _XOpenDisplay(NULL); | |
int screen = DefaultScreen(display); | |
Window window = _XCreateSimpleWindow(display, RootWindow(display, screen), 0, 0, SCRW, SCRH, 0, 0, 0); | |
_XSelectInput(display, window, KeyPressMask | KeyReleaseMask); | |
XVisualInfo *visual_info = _glXChooseVisual(display, screen, visual_hints); | |
GLXContext context = _glXCreateContext(display, visual_info, NULL, True); | |
_glXMakeCurrent(display, window, context); | |
_XMapWindow(display, window); | |
gpu_storage_t mesh = {0}; | |
mesh.format = xyz_f32; | |
mesh.count = 3; | |
mesh = gfStorageCreateFromStruct(mesh); | |
mesh.as_vec3[0].x = -0.5f; | |
mesh.as_vec3[0].y = -0.5f; | |
mesh.as_vec3[0].z = 0.0f; | |
mesh.as_vec3[1].x = 0.0f; | |
mesh.as_vec3[1].y = 0.5f; | |
mesh.as_vec3[1].z = 0.0f; | |
mesh.as_vec3[2].x = 0.5f; | |
mesh.as_vec3[2].y = -0.5f; | |
mesh.as_vec3[2].z = 0.0f; | |
gpu_cmd_t cmd[1] = {0}; | |
cmd[0].count = mesh.count; | |
cmd[0].instance_count = 1; | |
const char * vs_str = GF_VERT_HEAD GF_TO_STRING | |
( | |
layout(binding = 0) uniform samplerBuffer s_pos; | |
void main() | |
{ | |
vec3 pos = texelFetch(s_pos, gl_VertexID).xyz; | |
gl_Position = vec4(pos, 1.f); | |
} | |
); | |
const char * fs_str = GF_FRAG_HEAD GF_TO_STRING | |
( | |
out vec4 color; | |
void main() | |
{ | |
color = vec4(1.f); | |
} | |
); | |
u32 vs = gfProgramCreateFromString(GL_VERTEX_SHADER, vs_str); | |
u32 fs = gfProgramCreateFromString(GL_FRAGMENT_SHADER, fs_str); | |
u32 pp = gfProgramPipelineCreate(vs, fs); | |
u32 state_textures[16] = { mesh.id }; | |
_glBindTextures(0, 16, state_textures); | |
uint64_t prev = time_monotonic(); | |
uint64_t t = 0; | |
for(;;) | |
{ | |
XEvent event; | |
while(_XPending(display)) | |
{ | |
_XNextEvent(display, &event); | |
if(event.type == KeyPress) | |
{ | |
switch(_XkbKeycodeToKeysym(display, event.xkey.keycode, 0, 0)) | |
{ | |
case XK_Escape: goto shutdown; | |
} | |
} | |
} | |
// draw demo | |
gfClear(); | |
gfDraw(pp, countof(cmd), cmd); | |
_glXSwapBuffers(display, window); | |
t += time_monotonic() - prev; | |
} | |
shutdown: | |
return; | |
} | |
gpu_storage_t gfStorageCreateFromStruct(gpu_storage_t tbo) | |
{ | |
u32 elem_width = 0; | |
u32 elem_bytes = 0; | |
switch(tbo.format) | |
{ | |
case(x_b8): elem_width = 1; elem_bytes = sizeof(u8); break; | |
case(x_f16): elem_width = 1; elem_bytes = sizeof(f16); break; | |
case(x_f32): elem_width = 1; elem_bytes = sizeof(f32); break; | |
case(x_i8): elem_width = 1; elem_bytes = sizeof(i8); break; | |
case(x_i16): elem_width = 1; elem_bytes = sizeof(i16); break; | |
case(x_i32): elem_width = 1; elem_bytes = sizeof(i32); break; | |
case(x_u8): elem_width = 1; elem_bytes = sizeof(u8); break; | |
case(x_u16): elem_width = 1; elem_bytes = sizeof(u16); break; | |
case(x_u32): elem_width = 1; elem_bytes = sizeof(u32); break; | |
case(xy_b8): elem_width = 2; elem_bytes = sizeof(u8); break; | |
case(xy_f16): elem_width = 2; elem_bytes = sizeof(f16); break; | |
case(xy_f32): elem_width = 2; elem_bytes = sizeof(f32); break; | |
case(xy_i8): elem_width = 2; elem_bytes = sizeof(i8); break; | |
case(xy_i16): elem_width = 2; elem_bytes = sizeof(i16); break; | |
case(xy_i32): elem_width = 2; elem_bytes = sizeof(i32); break; | |
case(xy_u8): elem_width = 2; elem_bytes = sizeof(u8); break; | |
case(xy_u16): elem_width = 2; elem_bytes = sizeof(u16); break; | |
case(xy_u32): elem_width = 2; elem_bytes = sizeof(u32); break; | |
case(xyz_f32): elem_width = 3; elem_bytes = sizeof(f32); break; | |
case(xyz_i32): elem_width = 3; elem_bytes = sizeof(i32); break; | |
case(xyz_u32): elem_width = 3; elem_bytes = sizeof(u32); break; | |
case(xyzw_b8): elem_width = 4; elem_bytes = sizeof(u8); break; | |
case(xyzw_f16): elem_width = 4; elem_bytes = sizeof(f16); break; | |
case(xyzw_f32): elem_width = 4; elem_bytes = sizeof(f32); break; | |
case(xyzw_i8): elem_width = 4; elem_bytes = sizeof(i8); break; | |
case(xyzw_i16): elem_width = 4; elem_bytes = sizeof(i16); break; | |
case(xyzw_i32): elem_width = 4; elem_bytes = sizeof(i32); break; | |
case(xyzw_u8): elem_width = 4; elem_bytes = sizeof(u8); break; | |
case(xyzw_u16): elem_width = 4; elem_bytes = sizeof(u16); break; | |
case(xyzw_u32): elem_width = 4; elem_bytes = sizeof(u32); break; | |
} | |
if(!tbo.bytes) | |
tbo.bytes = tbo.count * elem_width * elem_bytes; | |
else | |
tbo.count = tbo.bytes / elem_width / elem_bytes; | |
_glCreateBuffers(1, &tbo.buffer_id); | |
_glCreateTextures(GL_TEXTURE_BUFFER, 1, &tbo.id); | |
u32 flags = GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT; | |
_glNamedBufferStorage(tbo.buffer_id, tbo.bytes, NULL, flags); | |
tbo.ptr = (u8 *)_glMapNamedBufferRange(tbo.buffer_id, 0, tbo.bytes, flags); | |
_glTextureBuffer(tbo.id, tbo.format, tbo.buffer_id); | |
return tbo; | |
} | |
gpu_texture_t gfTextureCreateFromStruct(gpu_texture_t texture) | |
{ | |
if(!texture.count) texture.count = 1; | |
if(!texture.mipmap) texture.mipmap = 1; | |
_glCreateTextures(texture.cubemap ? GL_TEXTURE_CUBE_MAP_ARRAY : GL_TEXTURE_2D_ARRAY, 1, &texture.id); | |
_glTextureStorage3D(texture.id, texture.mipmap, texture.format, texture.w, texture.h, texture.count * (texture.cubemap ? 6 : 1)); | |
return texture; | |
} | |
gpu_sampler_t gfSamplerCreateFromStruct(gpu_sampler_t sampler) | |
{ | |
if(!sampler.aniso) sampler.aniso = 1; | |
if(!sampler.min) sampler.min = GL_LINEAR_MIPMAP_LINEAR; | |
if(!sampler.mag) sampler.mag = GL_LINEAR; | |
if(!sampler.wrap) sampler.wrap = GL_REPEAT; | |
_glCreateSamplers(1, &sampler.id); | |
_glSamplerParameteri(sampler.id, GL_TEXTURE_MAX_ANISOTROPY, sampler.aniso); | |
_glSamplerParameteri(sampler.id, GL_TEXTURE_MIN_FILTER, sampler.min); | |
_glSamplerParameteri(sampler.id, GL_TEXTURE_MAG_FILTER, sampler.mag); | |
_glSamplerParameteri(sampler.id, GL_TEXTURE_WRAP_S, sampler.wrap); | |
_glSamplerParameteri(sampler.id, GL_TEXTURE_WRAP_T, sampler.wrap); | |
return sampler; | |
} | |
void gfTextureSetPixels( | |
u32 texture_id, | |
i32 texture_layer, | |
i32 x, | |
i32 y, | |
i32 width, | |
i32 height, | |
u32 pixels_format, | |
u32 pixels_type, | |
const void * pixels) | |
{ | |
_glTextureSubImage3D(texture_id, 0, x, y, texture_layer, width, height, 1, pixels_format, pixels_type, pixels); | |
} | |
void gfTextureGetPixels( | |
u32 texture_id, | |
i32 texture_layer, | |
i32 x, | |
i32 y, | |
i32 width, | |
i32 height, | |
u32 pixels_format, | |
u32 pixels_type, | |
i32 pixels_bytes, | |
void * pixels) | |
{ | |
_glGetTextureSubImage(texture_id, 0, x, y, texture_layer, width, height, 1, pixels_format, pixels_type, pixels_bytes, pixels); | |
} | |
u32 gfFboCreate( | |
u32 depth_texture_id, | |
i32 depth_texture_layer, | |
i32 color_texture_count, | |
const u32 * color_texture_ids, | |
const i32 * color_texture_layers) | |
{ | |
u32 fbo; | |
_glCreateFramebuffers(1, &fbo); | |
if(depth_texture_id) | |
_glNamedFramebufferTextureLayer(fbo, GL_DEPTH_ATTACHMENT, depth_texture_id, 0, depth_texture_layer); | |
if(color_texture_count) | |
{ | |
u32 attachments[8] = {0}; | |
for(i32 i = 0; i < color_texture_count; ++i) | |
{ | |
attachments[i] = GL_COLOR_ATTACHMENT0 + (u32)i; | |
_glNamedFramebufferTextureLayer(fbo, GL_COLOR_ATTACHMENT0 + (u32)i, color_texture_ids[i], 0, color_texture_layers ? color_texture_layers[i] : 0); | |
} | |
_glNamedFramebufferDrawBuffers(fbo, color_texture_count, attachments); | |
} | |
return fbo; | |
} | |
void gfFboBind(u32 fbo_id) | |
{ | |
_glBindFramebuffer(GL_FRAMEBUFFER, fbo_id); | |
} | |
u32 gfProgramCreateFromString( | |
u32 shader_type, | |
const char * shader_string) | |
{ | |
return _glCreateShaderProgramv(shader_type, 1, (const char **)&shader_string); | |
} | |
u32 gfProgramPipelineCreate( | |
u32 vert_program, | |
u32 frag_program) | |
{ | |
u32 ppo; | |
_glCreateProgramPipelines(1, &ppo); | |
if(vert_program) _glUseProgramStages(ppo, GL_VERTEX_SHADER_BIT, vert_program); | |
if(frag_program) _glUseProgramStages(ppo, GL_FRAGMENT_SHADER_BIT, frag_program); | |
return ppo; | |
} | |
void gfClear() | |
{ | |
_glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); | |
} | |
void gfDraw( | |
u32 program_pipeline, | |
u32 gpu_cmd_count, | |
const gpu_cmd_t * gpu_cmd) | |
{ | |
_glBindProgramPipeline(program_pipeline); | |
for(u32 i = 0; i < gpu_cmd_count; ++i) | |
{ | |
gpu_cmd_t cmd = gpu_cmd[i]; | |
_glDrawArraysInstancedBaseInstance(GL_TRIANGLES, (i32)cmd.first, (i32)cmd.count, (i32)cmd.instance_count, cmd.instance_first); | |
} | |
_glBindProgramPipeline(0); | |
} | |
void gfFire( | |
u32 program_pipeline, | |
u32 count) | |
{ | |
gpu_cmd_t cmd; | |
cmd.first = 0; | |
cmd.count = count; | |
cmd.instance_first = 0; | |
cmd.instance_count = 1; | |
gfDraw(program_pipeline, 1, &cmd); | |
} | |
asm ( | |
".text\n" | |
".global _start\n" | |
"_start:\n" | |
"xor %rbp,%rbp\n" | |
"pop %rdi\n" | |
"mov %rsp,%rsi\n" | |
"andq $-16,%rsp\n" | |
"call my_main\n" | |
"movq $60,%rax\n" | |
"xor %rdi,%rdi\n" | |
"syscall\n" | |
); | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment