#ifndef video_hpp #define video_hpp #include #include extern "C" { #include "vid_enums.h" } #include "asset.hpp" struct App; struct Arena; struct Heap; template struct Primitive_Id { T index; Primitive_Id(): index(0) {} Primitive_Id(T i): index(i) {} bool operator==(Primitive_Id other) const { return index == other.index; } operator bool() const { return index != 0; } }; struct Texture_Id : public Primitive_Id { using Primitive_Id::Primitive_Id; }; struct Buffer_Id : public Primitive_Id { using Primitive_Id::Primitive_Id; }; struct Vertex_Format_Id : public Primitive_Id { using Primitive_Id::Primitive_Id; }; struct Shader_Id : public Primitive_Id { using Primitive_Id::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