+typedef void (* csr_frag_program)( void *, vmf_vert[3], float, float, float );
+typedef void (* csr_frag_clear)( void * );
+
+// API
+//=======================================================================================================================
+
+// Create a render target. Resolution, msaa, and shader must be known at this point!
+void csr_create_target( csr_target *rt, u32 x, u32 y, EMSAA aa, csr_shader *shader );
+void csr_rt_clear( csr_target *rt );
+void csr_rt_free( csr_target *rt );
+
+// Refit bounds so that it is square, and crops to center with padding
+void csr_auto_fit( csr_target *rt, float padding );
+
+// Run this after bounds have been adjusted on the RT to update the size of the msaa
+// Auto fit will call this.
+void csr_update_subsamples( csr_target *rt );
+
+// Write CS:GO radar txt
+void csr_write_txt( char const *path, const char *name, csr_target *rt );
+
+// Render calls
+// ------------
+
+// Render a finalzied triangle into target. Coordinates are world space
+void simple_raster( csr_target *rt, vmf_vert tri[3] );
+
+// Draw a batch of triangles with an affine world transformation
+void csr_draw( csr_target *rt, vmf_vert *triangles, u32 triangle_count, m4x3f transform );
+
+// Draw VMF with filtering options. Will automatically branch into instances
+// You should call this with the last two recursive arguments (prev,inst), set to NULL
+//
+// Filter is optional, it can be st to NULL to just render everything.
+void csr_vmf_render( csr_target *rt, vmf_map *map, vdf_node *root, csr_filter *filter, m4x3f prev, m4x3f inst );
+
+void csr_rt_save_tga( csr_target *rt, const char *path, u32 offset, u32 nc );
+void csr_rt_save_c32f( csr_target *rt, const char *path, u32 offset );
+
+
+// Implementation
+//=======================================================================================================================
+
+struct csr_shader
+{
+ u32 stride;
+ csr_frag_program frag;
+ csr_frag_clear clear;