gs_graphics_impl.h 134 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005
  1. /*==============================================================================================================
  2. * Copyright (c) 2020 John Jackson
  3. * File: gs_graphics_impl.h
  4. * Github: https://github.com/MrFrenik/gunslinger
  5. * All Rights Reserved
  6. * MIT License
  7. * May all those that this source may reach be blessed by the LORD and find peace and joy in life.
  8. * Everyone who drinks of this water will be thirsty again; but whoever drinks of the water
  9. * that I will give him shall never thirst; John 4:13-14
  10. * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
  11. * documentation files (the "Software"), to deal in the Software without restriction, including without limitation
  12. * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
  13. * and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
  14. * The above copyright, blessing, biblical verse, notice and this permission notice shall be included in all
  15. * copies or substantial portions of the Software.
  16. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
  17. * TO THE WARRANTIES OF MECHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  18. * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
  19. * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  20. * IN THE SOFTWARE.
  21. =================================================================================================================*/
  22. #ifndef GS_GRAPHICS_IMPL_H
  23. #define GS_GRAPHICS_IMPL_H
  24. #ifndef GS_GRAPHICS_IMPL_CUSTOM
  25. #define GS_GRAPHICS_IMPL_DEFAULT
  26. #endif
  27. #ifdef GS_GRAPHICS_IMPL_DEFAULT
  28. // Default stuff here, if any...
  29. /* Graphics Info Object Query */
  30. gs_graphics_info_t* gs_graphics_info()
  31. {
  32. return &gs_subsystem(graphics)->info;
  33. }
  34. #endif
  35. #if (defined GS_GRAPHICS_IMPL_OPENGL_CORE || defined GS_GRAPHICS_IMPL_OPENGL_ES)
  36. #ifdef GS_GRAPHICS_IMPL_OPENGL_CORE
  37. #define CHECK_GL_CORE(...) __VA_ARGS__
  38. #else
  39. #define CHECK_GL_CORE(...) gs_empty_instruction(void)
  40. #endif
  41. typedef enum gsgl_uniform_type
  42. {
  43. GSGL_UNIFORMTYPE_FLOAT,
  44. GSGL_UNIFORMTYPE_INT,
  45. GSGL_UNIFORMTYPE_VEC2,
  46. GSGL_UNIFORMTYPE_VEC3,
  47. GSGL_UNIFORMTYPE_VEC4,
  48. GSGL_UNIFORMTYPE_MAT4,
  49. GSGL_UNIFORMTYPE_SAMPLER2D,
  50. GSGL_UNIFORMTYPE_SAMPLERCUBE
  51. } gsgl_uniform_type;
  52. /* Uniform (stores samplers as well as primitive uniforms) */
  53. typedef struct gsgl_uniform_t {
  54. char name[64]; // Name of uniform to find location
  55. gsgl_uniform_type type; // Type of uniform data
  56. uint32_t location; // Location of uniform
  57. size_t size; // Total data size of uniform
  58. uint32_t sid; // Shader id (should probably inverse this, but I don't want to force a map lookup)
  59. uint32_t count; // Count (used for arrays)
  60. } gsgl_uniform_t;
  61. // When a user passes in a uniform layout, that handle could then pass to a WHOLE list of uniforms (if describing a struct)
  62. typedef struct gsgl_uniform_list_t {
  63. gs_dyn_array(gsgl_uniform_t) uniforms; // Individual uniforms in list
  64. size_t size; // Total size of uniform data
  65. char name[64]; // Base name of uniform
  66. } gsgl_uniform_list_t;
  67. typedef struct gsgl_uniform_buffer_t {
  68. char name[64];
  69. uint32_t location;
  70. size_t size;
  71. uint32_t ubo;
  72. uint32_t sid;
  73. } gsgl_uniform_buffer_t;
  74. typedef struct gsgl_storage_buffer_t {
  75. char name[64];
  76. uint32_t buffer;
  77. int32_t access;
  78. size_t size;
  79. uint32_t block_idx;
  80. uint32_t location;
  81. void* map;
  82. GLsync sync; // Not sure about this being here...
  83. } gsgl_storage_buffer_t;
  84. /* Pipeline */
  85. typedef struct gsgl_pipeline_t {
  86. gs_graphics_blend_state_desc_t blend;
  87. gs_graphics_depth_state_desc_t depth;
  88. gs_graphics_raster_state_desc_t raster;
  89. gs_graphics_stencil_state_desc_t stencil;
  90. gs_graphics_compute_state_desc_t compute;
  91. gs_dyn_array(gs_graphics_vertex_attribute_desc_t) layout;
  92. } gsgl_pipeline_t;
  93. /* Render Pass */
  94. typedef struct gsgl_renderpass_t {
  95. gs_handle(gs_graphics_framebuffer_t) fbo;
  96. gs_dyn_array(gs_handle(gs_graphics_texture_t)) color;
  97. gs_handle(gs_graphics_texture_t) depth;
  98. gs_handle(gs_graphics_texture_t) stencil;
  99. } gsgl_renderpass_t;
  100. /* Shader */
  101. typedef uint32_t gsgl_shader_t;
  102. /* Gfx Buffer */
  103. typedef uint32_t gsgl_buffer_t;
  104. /* Texture */
  105. typedef struct gsgl_texture_t {
  106. uint32_t id;
  107. gs_graphics_texture_desc_t desc;
  108. } gsgl_texture_t;
  109. typedef struct gsgl_vertex_buffer_decl_t {
  110. gsgl_buffer_t vbo;
  111. gs_graphics_vertex_data_type data_type;
  112. size_t offset;
  113. } gsgl_vertex_buffer_decl_t;
  114. /* Cached data between draws */
  115. typedef struct gsgl_data_cache_t
  116. {
  117. gsgl_buffer_t vao;
  118. gsgl_buffer_t ibo;
  119. size_t ibo_elem_sz;
  120. gs_dyn_array(gsgl_vertex_buffer_decl_t) vdecls;
  121. gs_handle(gs_graphics_pipeline_t) pipeline;
  122. } gsgl_data_cache_t;
  123. /* Internal Opengl Data */
  124. typedef struct gsgl_data_t
  125. {
  126. gs_slot_array(gsgl_shader_t) shaders;
  127. gs_slot_array(gsgl_texture_t) textures;
  128. gs_slot_array(gsgl_buffer_t) vertex_buffers;
  129. gs_slot_array(gsgl_uniform_buffer_t) uniform_buffers;
  130. gs_slot_array(gsgl_storage_buffer_t) storage_buffers;
  131. gs_slot_array(gsgl_buffer_t) index_buffers;
  132. gs_slot_array(gsgl_buffer_t) frame_buffers;
  133. gs_slot_array(gsgl_uniform_list_t) uniforms;
  134. gs_slot_array(gsgl_pipeline_t) pipelines;
  135. gs_slot_array(gsgl_renderpass_t) renderpasses;
  136. // All the required uniform data for strict aliasing.
  137. struct {
  138. gs_dyn_array(uint32_t) ui32;
  139. gs_dyn_array(int32_t) i32;
  140. gs_dyn_array(float) flt;
  141. gs_dyn_array(gs_vec2) vec2;
  142. gs_dyn_array(gs_vec3) vec3;
  143. gs_dyn_array(gs_vec4) vec4;
  144. gs_dyn_array(gs_mat4) mat4;
  145. } uniform_data;
  146. // Cached data between draw calls (to minimize state changes)
  147. gsgl_data_cache_t cache;
  148. } gsgl_data_t;
  149. /* Internal OGL Command Buffer Op Code */
  150. typedef enum gs_opengl_op_code_type
  151. {
  152. GS_OPENGL_OP_BEGIN_RENDER_PASS = 0x00,
  153. GS_OPENGL_OP_END_RENDER_PASS,
  154. GS_OPENGL_OP_SET_VIEWPORT,
  155. GS_OPENGL_OP_SET_VIEW_SCISSOR,
  156. GS_OPENGL_OP_CLEAR,
  157. GS_OPENGL_OP_REQUEST_BUFFER_UPDATE,
  158. GS_OPENGL_OP_REQUEST_TEXTURE_UPDATE,
  159. GS_OPENGL_OP_BIND_PIPELINE,
  160. GS_OPENGL_OP_APPLY_BINDINGS,
  161. GS_OPENGL_OP_DISPATCH_COMPUTE,
  162. GS_OPENGL_OP_DRAW,
  163. } gs_opengl_op_code_type;
  164. void gsgl_reset_data_cache(gsgl_data_cache_t* cache)
  165. {
  166. cache->ibo = 0;
  167. cache->ibo_elem_sz = 0;
  168. cache->pipeline = gs_handle_invalid(gs_graphics_pipeline_t);
  169. gs_dyn_array_clear(cache->vdecls);
  170. }
  171. void gsgl_pipeline_state()
  172. {
  173. glBindBuffer(GL_ARRAY_BUFFER, 0);
  174. glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
  175. glBindTexture(GL_TEXTURE_2D, 0);
  176. glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
  177. CHECK_GL_CORE(
  178. glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, 0);
  179. )
  180. glDisable(GL_DEPTH_TEST);
  181. glDisable(GL_STENCIL_TEST);
  182. glDisable(GL_BLEND);
  183. CHECK_GL_CORE(
  184. glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS);
  185. );
  186. glDisable(GL_MULTISAMPLE);
  187. CHECK_GL_CORE(
  188. gs_graphics_info_t* info = gs_graphics_info();
  189. if (info->compute.available) {
  190. glBindImageTexture(0, 0, 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA32F);
  191. }
  192. )
  193. }
  194. void GLAPIENTRY
  195. gsgl_message_cb(uint32_t source, uint32_t type, uint32_t id, uint32_t severity, int32_t length,
  196. const GLchar* message, void* user_param)
  197. {
  198. return;
  199. if (type == GL_DEBUG_TYPE_ERROR) {
  200. gs_println("GL [DEBUG]: %s type = 0x%x, severity = 0x%x, message = %s",
  201. type == GL_DEBUG_TYPE_ERROR ? "GL ERROR" : "", type, severity, message);
  202. }
  203. }
  204. /* GS/OGL Utilities */
  205. int32_t gsgl_buffer_usage_to_gl_enum(gs_graphics_buffer_usage_type type)
  206. {
  207. int32_t mode = GL_STATIC_DRAW;
  208. switch (type) {
  209. default:
  210. case GS_GRAPHICS_BUFFER_USAGE_STATIC: mode = GL_STATIC_DRAW; break;
  211. case GS_GRAPHICS_BUFFER_USAGE_STREAM: mode = GL_STREAM_DRAW; break;
  212. case GS_GRAPHICS_BUFFER_USAGE_DYNAMIC: mode = GL_DYNAMIC_DRAW; break;
  213. }
  214. return mode;
  215. }
  216. uint32_t gsgl_access_type_to_gl_access_type(gs_graphics_access_type type)
  217. {
  218. CHECK_GL_CORE(
  219. uint32_t access = GL_WRITE_ONLY;
  220. switch (type)
  221. {
  222. case GS_GRAPHICS_ACCESS_WRITE_ONLY: access = GL_WRITE_ONLY; break;
  223. case GS_GRAPHICS_ACCESS_READ_ONLY: access = GL_READ_ONLY; break;
  224. case GS_GRAPHICS_ACCESS_READ_WRITE: access = GL_READ_WRITE; break;
  225. default: break;
  226. }
  227. return access;
  228. )
  229. return 0;
  230. }
  231. uint32_t gsgl_texture_wrap_to_gl_texture_wrap(gs_graphics_texture_wrapping_type type)
  232. {
  233. uint32_t wrap = GL_REPEAT;
  234. switch (type) {
  235. default:
  236. case GS_GRAPHICS_TEXTURE_WRAP_REPEAT: wrap = GL_REPEAT; break;
  237. case GS_GRAPHICS_TEXTURE_WRAP_MIRRORED_REPEAT: wrap = GL_MIRRORED_REPEAT; break;
  238. case GS_GRAPHICS_TEXTURE_WRAP_CLAMP_TO_EDGE: wrap = GL_CLAMP_TO_EDGE; break;
  239. CHECK_GL_CORE(case GS_GRAPHICS_TEXTURE_WRAP_CLAMP_TO_BORDER: wrap = GL_CLAMP_TO_BORDER; break;)
  240. };
  241. return wrap;
  242. }
  243. uint32_t gsgl_texture_format_to_gl_data_type(gs_graphics_texture_format_type type)
  244. {
  245. uint32_t format = GL_UNSIGNED_BYTE;
  246. switch (type) {
  247. default:
  248. case GS_GRAPHICS_TEXTURE_FORMAT_A8: format = GL_UNSIGNED_BYTE; break;
  249. case GS_GRAPHICS_TEXTURE_FORMAT_R8: format = GL_UNSIGNED_BYTE; break;
  250. case GS_GRAPHICS_TEXTURE_FORMAT_RGB8: format = GL_UNSIGNED_BYTE; break;
  251. case GS_GRAPHICS_TEXTURE_FORMAT_R32UI: format = GL_UNSIGNED_INT; break;
  252. case GS_GRAPHICS_TEXTURE_FORMAT_R16UI: format = GL_UNSIGNED_SHORT; break;
  253. case GS_GRAPHICS_TEXTURE_FORMAT_RGBA8: format = GL_UNSIGNED_BYTE; break;
  254. case GS_GRAPHICS_TEXTURE_FORMAT_RGBA16F: format = GL_FLOAT; break;
  255. case GS_GRAPHICS_TEXTURE_FORMAT_RGBA32F: format = GL_FLOAT; break;
  256. case GS_GRAPHICS_TEXTURE_FORMAT_R32F: format = GL_FLOAT; break;
  257. case GS_GRAPHICS_TEXTURE_FORMAT_DEPTH8: format = GL_FLOAT; break;
  258. case GS_GRAPHICS_TEXTURE_FORMAT_DEPTH16: format = GL_FLOAT; break;
  259. case GS_GRAPHICS_TEXTURE_FORMAT_DEPTH24: format = GL_FLOAT; break;
  260. case GS_GRAPHICS_TEXTURE_FORMAT_DEPTH32F: format = GL_FLOAT; break;
  261. case GS_GRAPHICS_TEXTURE_FORMAT_DEPTH24_STENCIL8: format = GL_UNSIGNED_INT_24_8; break;
  262. case GS_GRAPHICS_TEXTURE_FORMAT_DEPTH32F_STENCIL8: format = GL_FLOAT_32_UNSIGNED_INT_24_8_REV; break;
  263. }
  264. return format;
  265. }
  266. uint32_t gsgl_texture_format_to_gl_texture_format(gs_graphics_texture_format_type type)
  267. {
  268. uint32_t dt = GL_RGBA;
  269. switch (type)
  270. {
  271. default:
  272. case GS_GRAPHICS_TEXTURE_FORMAT_RGBA8: dt = GL_RGBA; break;
  273. case GS_GRAPHICS_TEXTURE_FORMAT_A8: dt = GL_ALPHA; break;
  274. case GS_GRAPHICS_TEXTURE_FORMAT_R8: dt = GL_RED; break;
  275. case GS_GRAPHICS_TEXTURE_FORMAT_R16UI: dt = GL_RED_INTEGER; break;
  276. case GS_GRAPHICS_TEXTURE_FORMAT_R32UI: dt = GL_RED_INTEGER; break;
  277. case GS_GRAPHICS_TEXTURE_FORMAT_R32F: dt = GL_RED; break;
  278. case GS_GRAPHICS_TEXTURE_FORMAT_RGB8: dt = GL_RGB; break;
  279. case GS_GRAPHICS_TEXTURE_FORMAT_RGBA16F: dt = GL_RGBA; break;
  280. case GS_GRAPHICS_TEXTURE_FORMAT_RGBA32F: dt = GL_RGBA; break;
  281. case GS_GRAPHICS_TEXTURE_FORMAT_DEPTH8: dt = GL_DEPTH_COMPONENT; break;
  282. case GS_GRAPHICS_TEXTURE_FORMAT_DEPTH16: dt = GL_DEPTH_COMPONENT; break;
  283. case GS_GRAPHICS_TEXTURE_FORMAT_DEPTH24: dt = GL_DEPTH_COMPONENT; break;
  284. case GS_GRAPHICS_TEXTURE_FORMAT_DEPTH32F: dt = GL_DEPTH_COMPONENT; break;
  285. case GS_GRAPHICS_TEXTURE_FORMAT_DEPTH24_STENCIL8: dt = GL_DEPTH_STENCIL;
  286. case GS_GRAPHICS_TEXTURE_FORMAT_DEPTH32F_STENCIL8: dt = GL_DEPTH_STENCIL; break;
  287. }
  288. return dt;
  289. }
  290. uint32_t gsgl_texture_format_to_gl_texture_internal_format(gs_graphics_texture_format_type type)
  291. {
  292. uint32_t format = GL_UNSIGNED_BYTE;
  293. switch (type) {
  294. case GS_GRAPHICS_TEXTURE_FORMAT_A8: format = GL_ALPHA; break;
  295. case GS_GRAPHICS_TEXTURE_FORMAT_R8: format = GL_RED; break;
  296. case GS_GRAPHICS_TEXTURE_FORMAT_R32UI: format = GL_R32UI; break;
  297. case GS_GRAPHICS_TEXTURE_FORMAT_R16UI: format = GL_R16UI; break;
  298. case GS_GRAPHICS_TEXTURE_FORMAT_R32F: format = GL_R32F; break;
  299. case GS_GRAPHICS_TEXTURE_FORMAT_RGB8: format = GL_RGB8; break;
  300. case GS_GRAPHICS_TEXTURE_FORMAT_RGBA8: format = GL_RGBA8; break;
  301. case GS_GRAPHICS_TEXTURE_FORMAT_RGBA16F: format = GL_RGBA16F; break;
  302. case GS_GRAPHICS_TEXTURE_FORMAT_RGBA32F: format = GL_RGBA32F; break;
  303. case GS_GRAPHICS_TEXTURE_FORMAT_DEPTH8: format = GL_DEPTH_COMPONENT; break;
  304. case GS_GRAPHICS_TEXTURE_FORMAT_DEPTH16: format = GL_DEPTH_COMPONENT16; break;
  305. case GS_GRAPHICS_TEXTURE_FORMAT_DEPTH24: format = GL_DEPTH_COMPONENT24; break;
  306. case GS_GRAPHICS_TEXTURE_FORMAT_DEPTH32F: format = GL_DEPTH_COMPONENT32F; break;
  307. case GS_GRAPHICS_TEXTURE_FORMAT_DEPTH24_STENCIL8: format = GL_DEPTH24_STENCIL8; break;
  308. case GS_GRAPHICS_TEXTURE_FORMAT_DEPTH32F_STENCIL8: format = GL_DEPTH32F_STENCIL8; break;
  309. }
  310. return format;
  311. }
  312. uint32_t gsgl_shader_stage_to_gl_stage(gs_graphics_shader_stage_type type)
  313. {
  314. uint32_t stage = GL_VERTEX_SHADER;
  315. switch (type) {
  316. default:
  317. case GS_GRAPHICS_SHADER_STAGE_VERTEX: stage = GL_VERTEX_SHADER; break;
  318. case GS_GRAPHICS_SHADER_STAGE_FRAGMENT: stage = GL_FRAGMENT_SHADER; break;
  319. CHECK_GL_CORE(case GS_GRAPHICS_SHADER_STAGE_COMPUTE: stage = GL_COMPUTE_SHADER; break;)
  320. }
  321. return stage;
  322. }
  323. uint32_t gsgl_primitive_to_gl_primitive(gs_graphics_primitive_type type)
  324. {
  325. uint32_t prim = GL_TRIANGLES;
  326. switch (type) {
  327. default:
  328. case GS_GRAPHICS_PRIMITIVE_TRIANGLES: prim = GL_TRIANGLES; break;
  329. case GS_GRAPHICS_PRIMITIVE_LINES: prim = GL_LINES; break;
  330. CHECK_GL_CORE(case GS_GRAPHICS_PRIMITIVE_QUADS: prim = GL_QUADS; break;)
  331. }
  332. return prim;
  333. }
  334. uint32_t gsgl_blend_equation_to_gl_blend_eq(gs_graphics_blend_equation_type eq)
  335. {
  336. uint32_t beq = GL_FUNC_ADD;
  337. switch (eq) {
  338. default:
  339. case GS_GRAPHICS_BLEND_EQUATION_ADD: beq = GL_FUNC_ADD; break;
  340. case GS_GRAPHICS_BLEND_EQUATION_SUBTRACT: beq = GL_FUNC_SUBTRACT; break;
  341. case GS_GRAPHICS_BLEND_EQUATION_REVERSE_SUBTRACT: beq = GL_FUNC_REVERSE_SUBTRACT; break;
  342. case GS_GRAPHICS_BLEND_EQUATION_MIN: beq = GL_MIN; break;
  343. case GS_GRAPHICS_BLEND_EQUATION_MAX: beq = GL_MAX; break;
  344. };
  345. return beq;
  346. }
  347. uint32_t gsgl_blend_mode_to_gl_blend_mode(gs_graphics_blend_mode_type type, uint32_t def)
  348. {
  349. uint32_t mode = def;
  350. switch (type) {
  351. case GS_GRAPHICS_BLEND_MODE_ZERO: mode = GL_ZERO; break;
  352. case GS_GRAPHICS_BLEND_MODE_ONE: mode = GL_ONE; break;
  353. case GS_GRAPHICS_BLEND_MODE_SRC_COLOR: mode = GL_SRC_COLOR; break;
  354. case GS_GRAPHICS_BLEND_MODE_ONE_MINUS_SRC_COLOR: mode = GL_ONE_MINUS_SRC_COLOR; break;
  355. case GS_GRAPHICS_BLEND_MODE_DST_COLOR: mode = GL_DST_COLOR; break;
  356. case GS_GRAPHICS_BLEND_MODE_ONE_MINUS_DST_COLOR: mode = GL_ONE_MINUS_DST_COLOR; break;
  357. case GS_GRAPHICS_BLEND_MODE_SRC_ALPHA: mode = GL_SRC_ALPHA; break;
  358. case GS_GRAPHICS_BLEND_MODE_ONE_MINUS_SRC_ALPHA: mode = GL_ONE_MINUS_SRC_ALPHA; break;
  359. case GS_GRAPHICS_BLEND_MODE_DST_ALPHA: mode = GL_DST_ALPHA; break;
  360. case GS_GRAPHICS_BLEND_MODE_ONE_MINUS_DST_ALPHA: mode = GL_ONE_MINUS_DST_ALPHA; break;
  361. case GS_GRAPHICS_BLEND_MODE_CONSTANT_COLOR: mode = GL_CONSTANT_COLOR; break;
  362. case GS_GRAPHICS_BLEND_MODE_ONE_MINUS_CONSTANT_COLOR: mode = GL_ONE_MINUS_CONSTANT_COLOR; break;
  363. case GS_GRAPHICS_BLEND_MODE_CONSTANT_ALPHA: mode = GL_CONSTANT_ALPHA; break;
  364. case GS_GRAPHICS_BLEND_MODE_ONE_MINUS_CONSTANT_ALPHA: mode = GL_ONE_MINUS_CONSTANT_ALPHA; break;
  365. }
  366. return mode;
  367. }
  368. uint32_t gsgl_cull_face_to_gl_cull_face(gs_graphics_face_culling_type type)
  369. {
  370. uint32_t fc = GL_BACK;
  371. switch (type) {
  372. default:
  373. case GS_GRAPHICS_FACE_CULLING_BACK: fc = GL_BACK; break;
  374. case GS_GRAPHICS_FACE_CULLING_FRONT: fc = GL_FRONT; break;
  375. case GS_GRAPHICS_FACE_CULLING_FRONT_AND_BACK: fc = GL_FRONT_AND_BACK; break;
  376. }
  377. return fc;
  378. }
  379. uint32_t gsgl_winding_order_to_gl_winding_order(gs_graphics_winding_order_type type)
  380. {
  381. uint32_t wo = GL_CCW;
  382. switch (type)
  383. {
  384. case GS_GRAPHICS_WINDING_ORDER_CCW: wo = GL_CCW; break;
  385. case GS_GRAPHICS_WINDING_ORDER_CW: wo = GL_CW; break;
  386. }
  387. return wo;
  388. }
  389. uint32_t gsgl_depth_func_to_gl_depth_func(gs_graphics_depth_func_type type)
  390. {
  391. uint32_t func = GL_LESS;
  392. switch (type) {
  393. default:
  394. case GS_GRAPHICS_DEPTH_FUNC_LESS: func = GL_LESS; break;
  395. case GS_GRAPHICS_DEPTH_FUNC_NEVER: func = GL_NEVER; break;
  396. case GS_GRAPHICS_DEPTH_FUNC_EQUAL: func = GL_EQUAL; break;
  397. case GS_GRAPHICS_DEPTH_FUNC_LEQUAL: func = GL_LEQUAL; break;
  398. case GS_GRAPHICS_DEPTH_FUNC_GREATER: func = GL_GREATER; break;
  399. case GS_GRAPHICS_DEPTH_FUNC_NOTEQUAL: func = GL_NOTEQUAL; break;
  400. case GS_GRAPHICS_DEPTH_FUNC_GEQUAL: func = GL_GEQUAL; break;
  401. case GS_GRAPHICS_DEPTH_FUNC_ALWAYS: func = GL_ALWAYS; break;
  402. }
  403. return func;
  404. }
  405. bool gsgl_depth_mask_to_gl_mask(gs_graphics_depth_mask_type type)
  406. {
  407. bool ret = true;
  408. switch (type) {
  409. default:
  410. case GS_GRAPHICS_DEPTH_MASK_ENABLED: ret = true; break;
  411. case GS_GRAPHICS_DEPTH_MASK_DISABLED: ret = false; break;
  412. }
  413. return ret;
  414. }
  415. uint32_t gsgl_stencil_func_to_gl_stencil_func(gs_graphics_stencil_func_type type)
  416. {
  417. uint32_t func = GL_ALWAYS;
  418. switch (type) {
  419. default:
  420. case GS_GRAPHICS_STENCIL_FUNC_LESS: func = GL_LESS; break;
  421. case GS_GRAPHICS_STENCIL_FUNC_NEVER: func = GL_NEVER; break;
  422. case GS_GRAPHICS_STENCIL_FUNC_EQUAL: func = GL_EQUAL; break;
  423. case GS_GRAPHICS_STENCIL_FUNC_LEQUAL: func = GL_LEQUAL; break;
  424. case GS_GRAPHICS_STENCIL_FUNC_GREATER: func = GL_GREATER; break;
  425. case GS_GRAPHICS_STENCIL_FUNC_NOTEQUAL: func = GL_NOTEQUAL; break;
  426. case GS_GRAPHICS_STENCIL_FUNC_GEQUAL: func = GL_GEQUAL; break;
  427. case GS_GRAPHICS_STENCIL_FUNC_ALWAYS: func = GL_ALWAYS; break;
  428. }
  429. return func;
  430. }
  431. uint32_t gsgl_stencil_op_to_gl_stencil_op(gs_graphics_stencil_op_type type)
  432. {
  433. uint32_t op = GL_KEEP;
  434. switch (type) {
  435. default:
  436. case GS_GRAPHICS_STENCIL_OP_KEEP: op = GL_KEEP; break;
  437. case GS_GRAPHICS_STENCIL_OP_ZERO: op = GL_ZERO; break;
  438. case GS_GRAPHICS_STENCIL_OP_REPLACE: op = GL_REPLACE; break;
  439. case GS_GRAPHICS_STENCIL_OP_INCR: op = GL_INCR; break;
  440. case GS_GRAPHICS_STENCIL_OP_INCR_WRAP: op = GL_INCR_WRAP; break;
  441. case GS_GRAPHICS_STENCIL_OP_DECR: op = GL_DECR; break;
  442. case GS_GRAPHICS_STENCIL_OP_DECR_WRAP: op = GL_DECR_WRAP; break;
  443. case GS_GRAPHICS_STENCIL_OP_INVERT: op = GL_INVERT; break;
  444. }
  445. return op;
  446. }
  447. gsgl_uniform_type gsgl_uniform_type_to_gl_uniform_type(gs_graphics_uniform_type gstype)
  448. {
  449. gsgl_uniform_type type = GSGL_UNIFORMTYPE_FLOAT;
  450. switch (gstype) {
  451. default:
  452. case GS_GRAPHICS_UNIFORM_FLOAT: type = GSGL_UNIFORMTYPE_FLOAT; break;
  453. case GS_GRAPHICS_UNIFORM_INT: type = GSGL_UNIFORMTYPE_INT; break;
  454. case GS_GRAPHICS_UNIFORM_VEC2: type = GSGL_UNIFORMTYPE_VEC2; break;
  455. case GS_GRAPHICS_UNIFORM_VEC3: type = GSGL_UNIFORMTYPE_VEC3; break;
  456. case GS_GRAPHICS_UNIFORM_VEC4: type = GSGL_UNIFORMTYPE_VEC4; break;
  457. case GS_GRAPHICS_UNIFORM_MAT4: type = GSGL_UNIFORMTYPE_MAT4; break;
  458. case GS_GRAPHICS_UNIFORM_USAMPLER2D: type = GSGL_UNIFORMTYPE_SAMPLER2D; break;
  459. case GS_GRAPHICS_UNIFORM_SAMPLER2D: type = GSGL_UNIFORMTYPE_SAMPLER2D; break;
  460. case GS_GRAPHICS_UNIFORM_SAMPLERCUBE: type = GSGL_UNIFORMTYPE_SAMPLERCUBE; break;
  461. }
  462. return type;
  463. }
  464. uint32_t gsgl_index_buffer_size_to_gl_index_type(size_t sz)
  465. {
  466. uint32_t type = GL_UNSIGNED_INT;
  467. switch (sz) {
  468. default:
  469. case 4: type = GL_UNSIGNED_INT; break;
  470. case 2: type = GL_UNSIGNED_SHORT; break;
  471. case 1: type = GL_UNSIGNED_BYTE; break;
  472. }
  473. return type;
  474. }
  475. size_t gsgl_get_byte_size_of_vertex_attribute(gs_graphics_vertex_attribute_type type)
  476. {
  477. size_t byte_size = 0;
  478. switch (type) {
  479. case GS_GRAPHICS_VERTEX_ATTRIBUTE_FLOAT4: { byte_size = sizeof(float32_t) * 4; } break;
  480. case GS_GRAPHICS_VERTEX_ATTRIBUTE_FLOAT3: { byte_size = sizeof(float32_t) * 3; } break;
  481. case GS_GRAPHICS_VERTEX_ATTRIBUTE_FLOAT2: { byte_size = sizeof(float32_t) * 2; } break;
  482. case GS_GRAPHICS_VERTEX_ATTRIBUTE_FLOAT: { byte_size = sizeof(float32_t) * 1; } break;
  483. case GS_GRAPHICS_VERTEX_ATTRIBUTE_UINT4: { byte_size = sizeof(uint32_t) * 4; } break;
  484. case GS_GRAPHICS_VERTEX_ATTRIBUTE_UINT3: { byte_size = sizeof(uint32_t) * 3; } break;
  485. case GS_GRAPHICS_VERTEX_ATTRIBUTE_UINT2: { byte_size = sizeof(uint32_t) * 2; } break;
  486. case GS_GRAPHICS_VERTEX_ATTRIBUTE_UINT: { byte_size = sizeof(uint32_t) * 1; } break;
  487. case GS_GRAPHICS_VERTEX_ATTRIBUTE_BYTE4: { byte_size = sizeof(uint8_t) * 4; } break;
  488. case GS_GRAPHICS_VERTEX_ATTRIBUTE_BYTE3: { byte_size = sizeof(uint8_t) * 3; } break;
  489. case GS_GRAPHICS_VERTEX_ATTRIBUTE_BYTE2: { byte_size = sizeof(uint8_t) * 2; } break;
  490. case GS_GRAPHICS_VERTEX_ATTRIBUTE_BYTE: { byte_size = sizeof(uint8_t) * 1; } break;
  491. }
  492. return byte_size;
  493. }
  494. size_t gsgl_calculate_vertex_size_in_bytes(gs_graphics_vertex_attribute_desc_t* layout, uint32_t count)
  495. {
  496. // Iterate through all formats in delcarations and calculate total size
  497. size_t sz = 0;
  498. for (uint32_t i = 0; i < count; ++i) {
  499. gs_graphics_vertex_attribute_type type = layout[i].format;
  500. sz += gsgl_get_byte_size_of_vertex_attribute(type);
  501. }
  502. return sz;
  503. }
  504. size_t gsgl_get_vertex_attr_byte_offest(gs_dyn_array(gs_graphics_vertex_attribute_desc_t) layout, uint32_t idx)
  505. {
  506. // Recursively calculate offset
  507. size_t total_offset = 0;
  508. // Base case
  509. if (idx == 0) {
  510. return total_offset;
  511. }
  512. // Calculate total offset up to this point
  513. for (uint32_t i = 0; i < idx; ++i) {
  514. total_offset += gsgl_get_byte_size_of_vertex_attribute(layout[i].format);
  515. }
  516. return total_offset;
  517. }
  518. size_t gsgl_uniform_data_size_in_bytes(gs_graphics_uniform_type type)
  519. {
  520. size_t sz = 0;
  521. switch (type) {
  522. case GS_GRAPHICS_UNIFORM_FLOAT: sz = sizeof(float); break;
  523. case GS_GRAPHICS_UNIFORM_INT: sz = sizeof(int32_t); break;
  524. case GS_GRAPHICS_UNIFORM_VEC2: sz = 2 * sizeof(float); break;
  525. case GS_GRAPHICS_UNIFORM_VEC3: sz = 3 * sizeof(float); break;
  526. case GS_GRAPHICS_UNIFORM_VEC4: sz = 4 * sizeof(float); break;
  527. case GS_GRAPHICS_UNIFORM_MAT4: sz = 16 * sizeof(float); break;
  528. case GS_GRAPHICS_UNIFORM_SAMPLER2D: sz = sizeof(gs_handle(gs_graphics_texture_t)); break; // handle size
  529. case GS_GRAPHICS_UNIFORM_USAMPLER2D: sz = sizeof(gs_handle(gs_graphics_texture_t)); break; // handle size
  530. case GS_GRAPHICS_UNIFORM_SAMPLERCUBE: sz = sizeof(gs_handle(gs_graphics_texture_t)); break; // handle size
  531. default: {
  532. sz = 0;
  533. } break;
  534. }
  535. return sz;
  536. }
  537. /* Graphics Interface Creation / Initialization / Shutdown / Destruction */
  538. GS_API_DECL gs_graphics_t*
  539. gs_graphics_create()
  540. {
  541. // Construct new graphics interface
  542. gs_graphics_t* gfx = gs_malloc_init(gs_graphics_t);
  543. // Construct internal data for opengl
  544. gfx->user_data = gs_malloc_init(gsgl_data_t);
  545. return gfx;
  546. }
  547. GS_API_DECL void
  548. gs_graphics_destroy(gs_graphics_t* graphics)
  549. {
  550. // Free all resources (assuming they've been freed from the GPU already)
  551. if (graphics == NULL) return;
  552. gsgl_data_t* ogl = (gsgl_data_t*)graphics->user_data;
  553. #define OGL_FREE_DATA(SA, T, FUNC)\
  554. do {\
  555. for (\
  556. gs_slot_array_iter it = 1;\
  557. gs_slot_array_iter_valid(SA, it);\
  558. gs_slot_array_iter_advance(SA, it)\
  559. )\
  560. {\
  561. gs_handle(T) hndl = gs_default_val();\
  562. hndl.id = it;\
  563. FUNC(hndl);\
  564. }\
  565. } while (0)
  566. // Free all gl data
  567. if (ogl->pipelines) OGL_FREE_DATA(ogl->pipelines, gs_graphics_pipeline_t, gs_graphics_pipeline_destroy);
  568. if (ogl->shaders) OGL_FREE_DATA(ogl->shaders, gs_graphics_shader_t, gs_graphics_shader_destroy);
  569. if (ogl->vertex_buffers) OGL_FREE_DATA(ogl->vertex_buffers, gs_graphics_vertex_buffer_t, gs_graphics_vertex_buffer_destroy);
  570. if (ogl->index_buffers) OGL_FREE_DATA(ogl->index_buffers, gs_graphics_index_buffer_t, gs_graphics_index_buffer_destroy);
  571. if (ogl->renderpasses) OGL_FREE_DATA(ogl->renderpasses, gs_graphics_renderpass_t, gs_graphics_renderpass_destroy);
  572. if (ogl->frame_buffers) OGL_FREE_DATA(ogl->frame_buffers, gs_graphics_framebuffer_t, gs_graphics_framebuffer_destroy);
  573. if (ogl->textures) OGL_FREE_DATA(ogl->textures, gs_graphics_texture_t, gs_graphics_texture_destroy);
  574. if (ogl->uniforms) OGL_FREE_DATA(ogl->uniforms, gs_graphics_uniform_t, gs_graphics_uniform_destroy);
  575. if (ogl->uniform_buffers) OGL_FREE_DATA(ogl->uniform_buffers, gs_graphics_uniform_buffer_t, gs_graphics_uniform_buffer_destroy);
  576. // if (ogl->storage_buffers) OGL_FREE_DATA(ogl->storage_buffers, gs_graphics_storage_buffer_t, gs_graphics_storage_buffer_destroy);
  577. gs_slot_array_free(ogl->shaders);
  578. gs_slot_array_free(ogl->vertex_buffers);
  579. gs_slot_array_free(ogl->index_buffers);
  580. gs_slot_array_free(ogl->frame_buffers);
  581. gs_slot_array_free(ogl->uniforms);
  582. gs_slot_array_free(ogl->textures);
  583. gs_slot_array_free(ogl->pipelines);
  584. gs_slot_array_free(ogl->renderpasses);
  585. gs_slot_array_free(ogl->uniform_buffers);
  586. gs_slot_array_free(ogl->storage_buffers);
  587. // Free uniform data array
  588. gs_dyn_array_free(ogl->uniform_data.mat4);
  589. gs_dyn_array_free(ogl->uniform_data.vec4);
  590. gs_dyn_array_free(ogl->uniform_data.vec3);
  591. gs_dyn_array_free(ogl->uniform_data.vec2);
  592. gs_dyn_array_free(ogl->uniform_data.flt);
  593. gs_dyn_array_free(ogl->uniform_data.i32);
  594. gs_dyn_array_free(ogl->uniform_data.ui32);
  595. // Free data cache
  596. gs_dyn_array_free(ogl->cache.vdecls);
  597. gs_free(graphics);
  598. graphics = NULL;
  599. }
  600. GS_API_DECL void
  601. gs_graphics_shutdown(gs_graphics_t* graphics)
  602. {
  603. }
  604. gsgl_texture_t gl_texture_update_internal(const gs_graphics_texture_desc_t* desc, uint32_t hndl)
  605. {
  606. gsgl_data_t* ogl = (gsgl_data_t*)gs_subsystem(graphics)->user_data;
  607. gsgl_texture_t tex = gs_default_val();
  608. if (hndl) tex = gs_slot_array_get(ogl->textures, hndl);
  609. uint32_t width = desc->width;
  610. uint32_t height = desc->height;
  611. void* data = NULL;
  612. if (!hndl)
  613. {
  614. glGenTextures(1, &tex.id);
  615. }
  616. GLenum target = 0x00;
  617. switch (desc->type)
  618. {
  619. default:
  620. case GS_GRAPHICS_TEXTURE_2D: {target = GL_TEXTURE_2D;} break;
  621. case GS_GRAPHICS_TEXTURE_CUBEMAP: {target = GL_TEXTURE_CUBE_MAP;} break;
  622. }
  623. glBindTexture(target, tex.id);
  624. uint32_t cnt = GS_GRAPHICS_TEXTURE_DATA_MAX;
  625. switch (desc->type)
  626. {
  627. case GS_GRAPHICS_TEXTURE_2D: cnt = 1; break;
  628. }
  629. for (uint32_t i = 0; i < cnt; ++i)
  630. {
  631. GLenum itarget = 0x00;
  632. data = desc->data[i];
  633. switch (desc->type)
  634. {
  635. default:
  636. case GS_GRAPHICS_TEXTURE_2D: {itarget = GL_TEXTURE_2D;} break;
  637. case GS_GRAPHICS_TEXTURE_CUBEMAP: {itarget = GL_TEXTURE_CUBE_MAP_POSITIVE_X + i;} break;
  638. }
  639. if (tex.desc.width * tex.desc.height < width * height)
  640. {
  641. // Construct texture based on appropriate format
  642. switch(desc->format)
  643. {
  644. case GS_GRAPHICS_TEXTURE_FORMAT_A8: glTexImage2D(itarget, 0, GL_ALPHA, width, height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, data); break;
  645. case GS_GRAPHICS_TEXTURE_FORMAT_R8: glTexImage2D(itarget, 0, GL_RED, width, height, 0, GL_RED, GL_UNSIGNED_BYTE, data); break;
  646. case GS_GRAPHICS_TEXTURE_FORMAT_R32UI: glTexImage2D(itarget, 0, GL_R32UI, width, height, 0, GL_RED_INTEGER, GL_UNSIGNED_INT, data); break;
  647. case GS_GRAPHICS_TEXTURE_FORMAT_R16UI: glTexImage2D(itarget, 0, GL_R16UI, width, height, 0, GL_RED_INTEGER, GL_UNSIGNED_SHORT, data); break;
  648. case GS_GRAPHICS_TEXTURE_FORMAT_RG8: glTexImage2D(itarget, 0, GL_RG8, width, height, 0, GL_RG, GL_UNSIGNED_BYTE, data); break;
  649. case GS_GRAPHICS_TEXTURE_FORMAT_RGB8: glTexImage2D(itarget, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data); break;
  650. case GS_GRAPHICS_TEXTURE_FORMAT_RGBA8: glTexImage2D(itarget, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); break;
  651. case GS_GRAPHICS_TEXTURE_FORMAT_R32F: glTexImage2D(itarget, 0, GL_R32F, width, height, 0, GL_RED, GL_FLOAT, data); break;
  652. case GS_GRAPHICS_TEXTURE_FORMAT_RGBA16F: glTexImage2D(itarget, 0, GL_RGBA16F, width, height, 0, GL_RGBA, GL_FLOAT, data); break;
  653. case GS_GRAPHICS_TEXTURE_FORMAT_RGBA32F: glTexImage2D(itarget, 0, GL_RGBA32F, width, height, 0, GL_RGBA, GL_FLOAT, data); break;
  654. case GS_GRAPHICS_TEXTURE_FORMAT_DEPTH8: glTexImage2D(itarget, 0, GL_DEPTH_COMPONENT, width, height, 0, GL_DEPTH_COMPONENT, GL_FLOAT, data); break;
  655. case GS_GRAPHICS_TEXTURE_FORMAT_DEPTH16: glTexImage2D(itarget, 0, GL_DEPTH_COMPONENT16, width, height, 0, GL_DEPTH_COMPONENT, GL_FLOAT, data); break;
  656. case GS_GRAPHICS_TEXTURE_FORMAT_DEPTH24: glTexImage2D(itarget, 0, GL_DEPTH_COMPONENT24, width, height, 0, GL_DEPTH_COMPONENT, GL_FLOAT, data); break;
  657. case GS_GRAPHICS_TEXTURE_FORMAT_DEPTH32F: glTexImage2D(itarget, 0, GL_DEPTH_COMPONENT32F, width, height, 0, GL_DEPTH_COMPONENT, GL_FLOAT, data); break;
  658. case GS_GRAPHICS_TEXTURE_FORMAT_DEPTH24_STENCIL8: glTexImage2D(itarget, 0, GL_DEPTH24_STENCIL8, width, height, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, data);
  659. case GS_GRAPHICS_TEXTURE_FORMAT_DEPTH32F_STENCIL8: glTexImage2D(itarget, 0, GL_DEPTH32F_STENCIL8, width, height, 0, GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, data); break;
  660. // NOTE(john): Because Apple is a shit company, I have to section this off and provide support for 4.1 only features.
  661. // case GS_GRAPHICS_TEXTURE_FORMAT_STENCIL8: glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT8, width, height, 0, GL_DEPTH_COMPONENT, GL_FLOAT, data); break;
  662. default: break;
  663. }
  664. }
  665. else
  666. {
  667. // Subimage
  668. switch (desc->format)
  669. {
  670. case GS_GRAPHICS_TEXTURE_FORMAT_A8: glTexSubImage2D(itarget, 0, (u32)desc->offset.x, (u32)desc->offset.y, width, height, GL_ALPHA, GL_UNSIGNED_BYTE, data); break;
  671. case GS_GRAPHICS_TEXTURE_FORMAT_R8: glTexSubImage2D(itarget, 0, (u32)desc->offset.x, (u32)desc->offset.y, width, height, GL_RED, GL_UNSIGNED_BYTE, data); break;
  672. case GS_GRAPHICS_TEXTURE_FORMAT_R32UI: glTexImage2D(itarget, 0, GL_R32UI, width, height, 0, GL_RED_INTEGER, GL_UNSIGNED_INT, data); break;
  673. case GS_GRAPHICS_TEXTURE_FORMAT_R16UI: glTexImage2D(itarget, 0, GL_R16UI, width, height, 0, GL_RED_INTEGER, GL_UNSIGNED_SHORT, data); break;
  674. case GS_GRAPHICS_TEXTURE_FORMAT_RG8: glTexSubImage2D(itarget, 0, (u32)desc->offset.x, (u32)desc->offset.y, width, height, GL_RG, GL_UNSIGNED_BYTE, data); break;
  675. case GS_GRAPHICS_TEXTURE_FORMAT_RGB8: glTexSubImage2D(itarget, 0, (u32)desc->offset.x, (u32)desc->offset.y, width, height, GL_RGB, GL_UNSIGNED_BYTE, data); break;
  676. case GS_GRAPHICS_TEXTURE_FORMAT_RGBA8: glTexSubImage2D(itarget, 0, (u32)desc->offset.x, (u32)desc->offset.y, width, height, GL_RGBA, GL_UNSIGNED_BYTE, data); break;
  677. case GS_GRAPHICS_TEXTURE_FORMAT_R32F: glTexImage2D(itarget, 0, GL_R32F, width, height, 0, GL_RED, GL_FLOAT, data); break;
  678. case GS_GRAPHICS_TEXTURE_FORMAT_RGBA16F: glTexSubImage2D(itarget, 0, (u32)desc->offset.x, (u32)desc->offset.y, width, height, GL_RGBA, GL_FLOAT, data); break;
  679. case GS_GRAPHICS_TEXTURE_FORMAT_RGBA32F: glTexSubImage2D(itarget, 0, (u32)desc->offset.x, (u32)desc->offset.y, width, height, GL_RGBA, GL_FLOAT, data); break;
  680. case GS_GRAPHICS_TEXTURE_FORMAT_DEPTH8: glTexSubImage2D(itarget, 0, (u32)desc->offset.x, (u32)desc->offset.y, width, height, GL_DEPTH_COMPONENT, GL_FLOAT, data); break;
  681. case GS_GRAPHICS_TEXTURE_FORMAT_DEPTH16: glTexSubImage2D(itarget, 0, (u32)desc->offset.x, (u32)desc->offset.y, width, height, GL_DEPTH_COMPONENT, GL_FLOAT, data); break;
  682. case GS_GRAPHICS_TEXTURE_FORMAT_DEPTH24: glTexSubImage2D(itarget, 0, (u32)desc->offset.x, (u32)desc->offset.y, width, height, GL_DEPTH_COMPONENT, GL_FLOAT, data); break;
  683. case GS_GRAPHICS_TEXTURE_FORMAT_DEPTH32F: glTexSubImage2D(itarget, 0, (u32)desc->offset.x, (u32)desc->offset.y, width, height, GL_DEPTH_COMPONENT, GL_FLOAT, data); break;
  684. case GS_GRAPHICS_TEXTURE_FORMAT_DEPTH24_STENCIL8: glTexSubImage2D(itarget, 0, (u32)desc->offset.x, (u32)desc->offset.y, width, height, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, data);
  685. case GS_GRAPHICS_TEXTURE_FORMAT_DEPTH32F_STENCIL8: glTexSubImage2D(itarget, 0, (u32)desc->offset.x, (u32)desc->offset.y, width, height, GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, data); break;
  686. // NOTE(john): Because Apple is a shit company, I have to section this off and provide support for 4.1 only features.
  687. // case GS_GRAPHICS_TEXTURE_FORMAT_STENCIL8: glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT8, width, height, 0, GL_DEPTH_COMPONENT, GL_FLOAT, data); break;
  688. default: break;
  689. }
  690. }
  691. }
  692. int32_t mag_filter = desc->mag_filter == GS_GRAPHICS_TEXTURE_FILTER_NEAREST ? GL_NEAREST : GL_LINEAR;
  693. int32_t min_filter = desc->min_filter == GS_GRAPHICS_TEXTURE_FILTER_NEAREST ? GL_NEAREST : GL_LINEAR;
  694. if (desc->num_mips) {
  695. if (desc->min_filter == GS_GRAPHICS_TEXTURE_FILTER_NEAREST) {
  696. min_filter = desc->mip_filter == GS_GRAPHICS_TEXTURE_FILTER_NEAREST ? GL_NEAREST_MIPMAP_NEAREST :
  697. GL_NEAREST_MIPMAP_LINEAR;
  698. }
  699. else {
  700. min_filter = desc->mip_filter == GS_GRAPHICS_TEXTURE_FILTER_NEAREST ? GL_LINEAR_MIPMAP_NEAREST :
  701. GL_NEAREST_MIPMAP_LINEAR;
  702. }
  703. }
  704. const uint32_t texture_wrap_s = gsgl_texture_wrap_to_gl_texture_wrap(desc->wrap_s);
  705. const uint32_t texture_wrap_t = gsgl_texture_wrap_to_gl_texture_wrap(desc->wrap_t);
  706. const uint32_t texture_wrap_r = gsgl_texture_wrap_to_gl_texture_wrap(desc->wrap_r);
  707. if (desc->num_mips) {
  708. glGenerateMipmap(target);
  709. }
  710. // Need to make sure this is available before being able to use
  711. CHECK_GL_CORE(
  712. float aniso = 0.0f;
  713. glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY, &aniso);
  714. glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY, aniso);
  715. );
  716. glTexParameteri(target, GL_TEXTURE_WRAP_S, texture_wrap_s);
  717. glTexParameteri(target, GL_TEXTURE_WRAP_T, texture_wrap_t);
  718. glTexParameteri(target, GL_TEXTURE_WRAP_R, texture_wrap_r);
  719. glTexParameteri(target, GL_TEXTURE_MAG_FILTER, mag_filter);
  720. glTexParameteri(target, GL_TEXTURE_MIN_FILTER, min_filter);
  721. // Unbind buffers
  722. glBindTexture(target, 0);
  723. glBindRenderbuffer(GL_RENDERBUFFER, 0);
  724. // Set description
  725. tex.desc = *desc;
  726. // Add texture to internal resource pool and return handle
  727. return tex;
  728. }
  729. /* Resource Creation */
  730. GS_API_DECL gs_handle(gs_graphics_texture_t)
  731. gs_graphics_texture_create_impl(const gs_graphics_texture_desc_t* desc)
  732. {
  733. gsgl_data_t* ogl = (gsgl_data_t*)gs_subsystem(graphics)->user_data;
  734. gsgl_texture_t tex = gl_texture_update_internal(desc, 0);
  735. // Add texture to internal resource pool and return handle
  736. return (gs_handle_create(gs_graphics_texture_t, gs_slot_array_insert(ogl->textures, tex)));
  737. }
  738. GS_API_DECL gs_handle(gs_graphics_uniform_t)
  739. gs_graphics_uniform_create_impl(const gs_graphics_uniform_desc_t* desc)
  740. {
  741. gsgl_data_t* ogl = (gsgl_data_t*)gs_subsystem(graphics)->user_data;
  742. // Assert if data isn't named
  743. if (*desc->name == 0) {
  744. gs_println("Warning: Uniform must be named for OpenGL.");
  745. return gs_handle_invalid(gs_graphics_uniform_t);
  746. }
  747. uint32_t ct = !desc->layout ? 0 : !desc->layout_size ? 1 : (uint32_t)desc->layout_size / (uint32_t)sizeof(gs_graphics_uniform_layout_desc_t);
  748. if (ct < 1) {
  749. gs_println("Warning: Uniform layout description must not be empty for: %s.", desc->name);
  750. return gs_handle_invalid(gs_graphics_uniform_t);
  751. }
  752. // Construct list for uniform handles
  753. gsgl_uniform_list_t ul = gs_default_val();
  754. memcpy(ul.name, desc->name, 64);
  755. // Iterate layout, construct individual handles
  756. for (uint32_t i = 0; i < ct; ++i)
  757. {
  758. // Uniform to fill out
  759. gsgl_uniform_t u = gs_default_val();
  760. // Cache layout
  761. gs_graphics_uniform_layout_desc_t* layout = &desc->layout[i];
  762. memcpy(u.name, layout->fname, 64);
  763. u.type = gsgl_uniform_type_to_gl_uniform_type(layout->type);
  764. u.size = gsgl_uniform_data_size_in_bytes(layout->type);
  765. u.count = layout->count ? layout->count : 1;
  766. u.location = UINT32_MAX;
  767. // Add to size of ul
  768. ul.size += u.size * u.count;
  769. // Push uniform into list
  770. gs_dyn_array_push(ul.uniforms, u);
  771. }
  772. return gs_handle_create(gs_graphics_uniform_t, gs_slot_array_insert(ogl->uniforms, ul));
  773. }
  774. GS_API_DECL gs_handle(gs_graphics_vertex_buffer_t)
  775. gs_graphics_vertex_buffer_create_impl(const gs_graphics_vertex_buffer_desc_t* desc)
  776. {
  777. gsgl_data_t* ogl = (gsgl_data_t*)gs_subsystem(graphics)->user_data;
  778. gs_handle(gs_graphics_vertex_buffer_t) hndl = gs_default_val();
  779. gsgl_buffer_t buffer = 0;
  780. // Assert if data isn't filled for vertex data when static draw enabled
  781. if (desc->usage == GS_GRAPHICS_BUFFER_USAGE_STATIC && !desc->data) {
  782. gs_println("Error: Vertex buffer desc must contain data when GS_GRAPHICS_BUFFER_USAGE_STATIC set.");
  783. gs_assert(false);
  784. }
  785. glGenBuffers(1, &buffer);
  786. glBindBuffer(GL_ARRAY_BUFFER, buffer);
  787. glBufferData(GL_ARRAY_BUFFER, desc->size, desc->data, gsgl_buffer_usage_to_gl_enum(desc->usage));
  788. glBindBuffer(GL_ARRAY_BUFFER, 0);
  789. hndl = gs_handle_create(gs_graphics_vertex_buffer_t, gs_slot_array_insert(ogl->vertex_buffers, buffer));
  790. return hndl;
  791. }
  792. GS_API_DECL gs_handle(gs_graphics_index_buffer_t)
  793. gs_graphics_index_buffer_create_impl(const gs_graphics_index_buffer_desc_t* desc)
  794. {
  795. gsgl_data_t* ogl = (gsgl_data_t*)gs_subsystem(graphics)->user_data;
  796. gs_handle(gs_graphics_index_buffer_t) hndl = gs_default_val();
  797. gsgl_buffer_t buffer = 0;
  798. // Assert if data isn't filled for vertex data when static draw enabled
  799. if (desc->usage == GS_GRAPHICS_BUFFER_USAGE_STATIC && !desc->data) {
  800. gs_println("Error: Index buffer desc must contain data when GS_GRAPHICS_BUFFER_USAGE_STATIC set.");
  801. gs_assert(false);
  802. }
  803. glGenBuffers(1, &buffer);
  804. glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer);
  805. glBufferData(GL_ELEMENT_ARRAY_BUFFER, desc->size, desc->data, gsgl_buffer_usage_to_gl_enum(desc->usage));
  806. glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
  807. hndl = gs_handle_create(gs_graphics_index_buffer_t, gs_slot_array_insert(ogl->index_buffers, buffer));
  808. return hndl;
  809. }
  810. GS_API_DECL gs_handle(gs_graphics_uniform_buffer_t)
  811. gs_graphics_uniform_buffer_create_impl(const gs_graphics_uniform_buffer_desc_t* desc)
  812. {
  813. gsgl_data_t* ogl = (gsgl_data_t*)gs_subsystem(graphics)->user_data;
  814. gs_handle(gs_graphics_uniform_buffer_t) hndl = gs_default_val();
  815. // Assert if data isn't named
  816. if (desc->name == NULL) {
  817. gs_println("Warning: Uniform buffer must be named for Opengl.");
  818. }
  819. gsgl_uniform_buffer_t u = gs_default_val();
  820. memcpy(u.name, desc->name, 64);
  821. u.size = desc->size;
  822. u.location = UINT32_MAX;
  823. // Generate buffer (if needed)
  824. glGenBuffers(1, &u.ubo);
  825. glBindBuffer(GL_UNIFORM_BUFFER, u.ubo);
  826. glBufferData(GL_UNIFORM_BUFFER, u.size, 0, gsgl_buffer_usage_to_gl_enum(desc->usage));
  827. glBindBuffer(GL_UNIFORM_BUFFER, 0);
  828. hndl = gs_handle_create(gs_graphics_uniform_buffer_t, gs_slot_array_insert(ogl->uniform_buffers, u));
  829. return hndl;
  830. }
  831. GS_API_DECL gs_handle(gs_graphics_storage_buffer_t)
  832. gs_graphics_storage_buffer_create_impl(const gs_graphics_storage_buffer_desc_t* desc)
  833. {
  834. gsgl_data_t* ogl = (gsgl_data_t*)gs_subsystem(graphics)->user_data;
  835. gs_handle(gs_graphics_storage_buffer_t) hndl = gs_default_val();
  836. gsgl_storage_buffer_t sbo = gs_default_val();
  837. if (*desc->name == 0) {
  838. gs_println("Warning: Storage buffer must be named for Opengl.");
  839. }
  840. if (desc->usage == GS_GRAPHICS_BUFFER_USAGE_STATIC && !desc->data) {
  841. gs_println("Error: Storage buffer desc must contain data when GS_GRAPHICS_BUFFER_USAGE_STATIC set.");
  842. gs_assert(false);
  843. }
  844. glGenBuffers(1, &sbo.buffer);
  845. CHECK_GL_CORE(
  846. glBindBuffer(GL_SHADER_STORAGE_BUFFER, sbo.buffer);
  847. // Check for desc flags to map buffer
  848. GLbitfield flags = 0x00;
  849. if (desc->flags & GS_GRAPHICS_BUFFER_FLAG_MAP_PERSISTENT) {flags |= GL_MAP_PERSISTENT_BIT;}
  850. if (desc->flags & GS_GRAPHICS_BUFFER_FLAG_MAP_COHERENT) {flags |= GL_MAP_PERSISTENT_BIT; flags |= GL_MAP_COHERENT_BIT;}
  851. if (desc->access & GS_GRAPHICS_ACCESS_READ_ONLY) {flags |= GL_MAP_READ_BIT;}
  852. else if (desc->access & GS_GRAPHICS_ACCESS_WRITE_ONLY) {flags |= GL_MAP_WRITE_BIT;}
  853. else if (desc->access & GS_GRAPHICS_ACCESS_READ_WRITE) {flags |= (GL_MAP_READ_BIT | GL_MAP_WRITE_BIT);}
  854. GLbitfield store_flags = flags;
  855. if (desc->usage == GS_GRAPHICS_BUFFER_USAGE_DYNAMIC) {
  856. store_flags |= GL_DYNAMIC_STORAGE_BIT;
  857. }
  858. // For now, just do read/write access
  859. // flags |= GL_MAP_READ_BIT; flags |= GL_MAP_WRITE_BIT;
  860. glBufferStorage(GL_SHADER_STORAGE_BUFFER, desc->size, desc->data, store_flags);
  861. // glBufferData(GL_SHADER_STORAGE_BUFFER, desc->size, desc->data, gsgl_buffer_usage_to_gl_enum(desc->usage));
  862. glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT);
  863. // Store mapping
  864. if (flags & GL_MAP_PERSISTENT_BIT) {
  865. int32_t err;
  866. sbo.map = glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, desc->size, flags);
  867. while ((err = glGetError()) != GL_NO_ERROR) {
  868. gs_println("GL ERROR: 0x%x: %s", err, glGetString(err));
  869. }
  870. }
  871. GLenum err = glGetError();
  872. if (err) {
  873. gs_println("GL ERROR: 0x%x: %s", err, glGetString(err));
  874. }
  875. glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
  876. );
  877. memcpy(sbo.name, desc->name, 64);
  878. sbo.access = desc->access;
  879. sbo.size = desc->size;
  880. sbo.block_idx = UINT32_MAX;
  881. hndl = gs_handle_create(gs_graphics_storage_buffer_t, gs_slot_array_insert(ogl->storage_buffers, sbo));
  882. return hndl;
  883. }
  884. GS_API_DECL gs_handle(gs_graphics_framebuffer_t)
  885. gs_graphics_framebuffer_create_impl(const gs_graphics_framebuffer_desc_t* desc)
  886. {
  887. gsgl_data_t* ogl = (gsgl_data_t*)gs_subsystem(graphics)->user_data;
  888. gs_handle(gs_graphics_framebuffer_t) hndl = gs_default_val();
  889. gsgl_buffer_t buffer = 0;
  890. glGenFramebuffers(1, &buffer);
  891. hndl = gs_handle_create(gs_graphics_framebuffer_t, gs_slot_array_insert(ogl->frame_buffers, buffer));
  892. return hndl;
  893. }
  894. #define GSGL_GRAPHICS_SHADER_PIPELINE_GFX 0x01
  895. #define GSGL_GRAPHICS_SHADER_PIPELINE_COMPUTE 0x02
  896. #define GSGL_GRAPHICS_MAX_SID 128
  897. GS_API_DECL gs_handle(gs_graphics_shader_t)
  898. gs_graphics_shader_create_impl(const gs_graphics_shader_desc_t* desc)
  899. {
  900. gsgl_data_t* ogl = (gsgl_data_t*)gs_subsystem(graphics)->user_data;
  901. gsgl_shader_t shader = 0;
  902. uint32_t pip = 0x00;
  903. uint32_t sid_ct = 0;
  904. uint32_t sids[GSGL_GRAPHICS_MAX_SID] = gs_default_val();
  905. // Create shader program
  906. shader = glCreateProgram();
  907. uint32_t ct = (uint32_t)desc->size / (uint32_t)sizeof(gs_graphics_shader_source_desc_t);
  908. for (uint32_t i = 0; i < ct; ++i)
  909. {
  910. if (desc->sources[i].type == GS_GRAPHICS_SHADER_STAGE_VERTEX) pip |= GSGL_GRAPHICS_SHADER_PIPELINE_GFX;
  911. if (desc->sources[i].type == GS_GRAPHICS_SHADER_STAGE_COMPUTE) pip |= GSGL_GRAPHICS_SHADER_PIPELINE_COMPUTE;
  912. // Validity Check: Desc must have vertex source if compute not selected. All other source is optional.
  913. if ((pip & GSGL_GRAPHICS_SHADER_PIPELINE_COMPUTE) && ((pip & GSGL_GRAPHICS_SHADER_PIPELINE_GFX))) {
  914. gs_println("Error: Cannot have compute and graphics stages for shader program.");
  915. gs_assert(false);
  916. }
  917. uint32_t stage = gsgl_shader_stage_to_gl_stage(desc->sources[i].type);
  918. uint32_t sid = glCreateShader(stage);
  919. if (!sid) {
  920. gs_println ("Error: Failed to allocate memory for shader: '%s': stage: {put stage id here}", desc->name);
  921. gs_assert(sid);
  922. }
  923. // Set source
  924. glShaderSource(sid, 1, &desc->sources[i].source, NULL);
  925. // Compile shader
  926. glCompileShader(sid);
  927. //Check for errors
  928. GLint success = 0;
  929. glGetShaderiv(sid, GL_COMPILE_STATUS, &success);
  930. if (success == GL_FALSE)
  931. {
  932. GLint max_len = 0;
  933. glGetShaderiv(sid, GL_INFO_LOG_LENGTH, &max_len);
  934. char* log = (char*)gs_malloc(max_len);
  935. memset(log, 0, max_len);
  936. //The max_len includes the NULL character
  937. glGetShaderInfoLog(sid, max_len, &max_len, log);
  938. // Delete shader.
  939. glDeleteShader(shader);
  940. //Provide the infolog
  941. gs_println("Opengl::opengl_compile_shader::shader: '%s'\nFAILED_TO_COMPILE: %s\n %s", desc->name, log, desc->sources[i].source);
  942. free(log);
  943. log = NULL;
  944. // gs_assert(false);
  945. return gs_handle_invalid(gs_graphics_shader_t);
  946. }
  947. // Attach shader to program
  948. glAttachShader(shader, sid);
  949. // Add to shader array
  950. sids[sid_ct++] = sid;
  951. }
  952. // Link shaders into final program
  953. glLinkProgram(shader);
  954. //Create info log for errors
  955. s32 is_linked = 0;
  956. glGetProgramiv(shader, GL_LINK_STATUS, (s32*)&is_linked);
  957. if (is_linked == GL_FALSE)
  958. {
  959. GLint max_len = 0;
  960. glGetProgramiv(shader, GL_INFO_LOG_LENGTH, &max_len);
  961. char* log = (char*)gs_malloc(max_len);
  962. memset(log, 0, max_len);
  963. glGetProgramInfoLog(shader, max_len, &max_len, log);
  964. // Print error
  965. gs_println("Error: Fail To Link::opengl_link_shaders::shader: '%s', \n%s", desc->name, log);
  966. // //We don't need the program anymore.
  967. glDeleteProgram(shader);
  968. free(log);
  969. log = NULL;
  970. // Just assert for now
  971. gs_assert(false);
  972. }
  973. // Free shaders after use
  974. for (uint32_t i = 0; i < sid_ct; ++i) {
  975. glDeleteShader(sids[i]);
  976. }
  977. // Iterate over uniforms
  978. /*
  979. {
  980. char tmp_name[256] = gs_default_val();
  981. int32_t count = 0;
  982. glGetProgramiv(shader, GL_ACTIVE_UNIFORMS, &count);
  983. gs_println("Active Uniforms: %d\n", count);
  984. for (uint32_t i = 0; i < count; i++) {
  985. int32_t sz = 0;
  986. uint32_t type;
  987. glGetActiveUniform(shader, (GLuint)i, 256, NULL, &sz, &type, tmp_name);
  988. gs_println("Uniform #%d Type: %u Name: %s\n", i, type, tmp_name);
  989. }
  990. }
  991. */
  992. // Add to pool and return handle
  993. return (gs_handle_create(gs_graphics_shader_t, gs_slot_array_insert(ogl->shaders, shader)));
  994. }
  995. GS_API_DECL gs_handle(gs_graphics_renderpass_t)
  996. gs_graphics_renderpass_create_impl(const gs_graphics_renderpass_desc_t* desc)
  997. {
  998. gsgl_data_t* ogl = (gsgl_data_t*)gs_subsystem(graphics)->user_data;
  999. gsgl_renderpass_t pass = gs_default_val();
  1000. // Set fbo
  1001. pass.fbo = desc->fbo;
  1002. // Set color attachments
  1003. uint32_t ct = (uint32_t)desc->color_size / (uint32_t)sizeof(gs_handle(gs_graphics_texture_t));
  1004. for (uint32_t i = 0; i < ct; ++i)
  1005. {
  1006. gs_dyn_array_push(pass.color, desc->color[i]);
  1007. }
  1008. // Set depth attachment
  1009. pass.depth = desc->depth;
  1010. // Create handle and return
  1011. return (gs_handle_create(gs_graphics_renderpass_t, gs_slot_array_insert(ogl->renderpasses, pass)));
  1012. }
  1013. GS_API_DECL gs_handle(gs_graphics_pipeline_t)
  1014. gs_graphics_pipeline_create_impl(const gs_graphics_pipeline_desc_t* desc)
  1015. {
  1016. gsgl_data_t* ogl = (gsgl_data_t*)gs_subsystem(graphics)->user_data;
  1017. gsgl_pipeline_t pipe = gs_default_val();
  1018. // Add states
  1019. pipe.blend = desc->blend;
  1020. pipe.depth = desc->depth;
  1021. pipe.raster = desc->raster;
  1022. pipe.stencil = desc->stencil;
  1023. pipe.compute = desc->compute;
  1024. // Add layout
  1025. uint32_t ct = (uint32_t)desc->layout.size / (uint32_t)sizeof(gs_graphics_vertex_attribute_desc_t);
  1026. gs_dyn_array_reserve(pipe.layout, ct);
  1027. for (uint32_t i = 0; i < ct; ++i) {
  1028. gs_dyn_array_push(pipe.layout, desc->layout.attrs[i]);
  1029. }
  1030. // Create handle and return
  1031. return (gs_handle_create(gs_graphics_pipeline_t, gs_slot_array_insert(ogl->pipelines, pipe)));
  1032. }
  1033. // Resource Destruction
  1034. GS_API_DECL void
  1035. gs_graphics_texture_destroy_impl(gs_handle(gs_graphics_texture_t) hndl)
  1036. {
  1037. gsgl_data_t* ogl = (gsgl_data_t*)gs_subsystem(graphics)->user_data;
  1038. if (!gs_slot_array_handle_valid(ogl->textures, hndl.id)) return;
  1039. gsgl_texture_t* tex = gs_slot_array_getp(ogl->textures, hndl.id);
  1040. glDeleteTextures(1, &tex->id);
  1041. gs_slot_array_erase(ogl->textures, hndl.id);
  1042. }
  1043. GS_API_DECL void
  1044. gs_graphics_uniform_destroy_impl(gs_handle(gs_graphics_uniform_t) hndl)
  1045. {
  1046. gsgl_data_t* ogl = (gsgl_data_t*)gs_subsystem(graphics)->user_data;
  1047. if (!gs_slot_array_handle_valid(ogl->uniforms, hndl.id)) return;
  1048. gsgl_uniform_list_t* ul = gs_slot_array_getp(ogl->uniforms, hndl.id);
  1049. gs_dyn_array_free(ul->uniforms);
  1050. gs_slot_array_erase(ogl->uniforms, hndl.id);
  1051. }
  1052. GS_API_DECL void
  1053. gs_graphics_shader_destroy_impl(gs_handle(gs_graphics_shader_t) hndl)
  1054. {
  1055. gsgl_data_t* ogl = (gsgl_data_t*)gs_subsystem(graphics)->user_data;
  1056. if (!gs_slot_array_handle_valid(ogl->shaders, hndl.id)) return;
  1057. glDeleteProgram(gs_slot_array_get(ogl->shaders, hndl.id));
  1058. gs_slot_array_erase(ogl->shaders, hndl.id);
  1059. }
  1060. GS_API_DECL void
  1061. gs_graphics_vertex_buffer_destroy_impl(gs_handle(gs_graphics_vertex_buffer_t) hndl)
  1062. {
  1063. gsgl_data_t* ogl = (gsgl_data_t*)gs_subsystem(graphics)->user_data;
  1064. if (!gs_slot_array_handle_valid(ogl->vertex_buffers, hndl.id)) return;
  1065. gsgl_buffer_t buffer = gs_slot_array_get(ogl->vertex_buffers, hndl.id);
  1066. glDeleteBuffers(1, &buffer);
  1067. gs_slot_array_erase(ogl->vertex_buffers, hndl.id);
  1068. }
  1069. GS_API_DECL void
  1070. gs_graphics_index_buffer_destroy_impl(gs_handle(gs_graphics_index_buffer_t) hndl)
  1071. {
  1072. gsgl_data_t* ogl = (gsgl_data_t*)gs_subsystem(graphics)->user_data;
  1073. if (!gs_slot_array_handle_valid(ogl->index_buffers, hndl.id)) return;
  1074. gsgl_buffer_t buffer = gs_slot_array_get(ogl->index_buffers, hndl.id);
  1075. glDeleteBuffers(1, &buffer);
  1076. gs_slot_array_erase(ogl->index_buffers, hndl.id);
  1077. }
  1078. GS_API_DECL void
  1079. gs_graphics_uniform_buffer_destroy_impl(gs_handle(gs_graphics_uniform_buffer_t) hndl)
  1080. {
  1081. gsgl_data_t* ogl = (gsgl_data_t*)gs_subsystem(graphics)->user_data;
  1082. if (!gs_slot_array_handle_valid(ogl->uniform_buffers, hndl.id)) return;
  1083. gsgl_uniform_buffer_t* u = gs_slot_array_getp(ogl->uniform_buffers, hndl.id);
  1084. // Delete buffer (if needed)
  1085. glDeleteBuffers(1, &u->ubo);
  1086. // Delete from slot array
  1087. gs_slot_array_erase(ogl->uniform_buffers, hndl.id);
  1088. }
  1089. GS_API_DECL void
  1090. gs_graphics_storage_buffer_destroy_impl(gs_handle(gs_graphics_storage_buffer_t) hndl)
  1091. {
  1092. gsgl_data_t* ogl = (gsgl_data_t*)gs_subsystem(graphics)->user_data;
  1093. if (!gs_slot_array_handle_valid(ogl->storage_buffers, hndl.id)) return;
  1094. gsgl_storage_buffer_t* sb = gs_slot_array_getp(ogl->storage_buffers, hndl.id);
  1095. // Delete buffer (if needed)
  1096. glDeleteBuffers(1, &sb->buffer);
  1097. // Delete from slot array
  1098. gs_slot_array_erase(ogl->storage_buffers, hndl.id);
  1099. }
  1100. GS_API_DECL void
  1101. gs_graphics_framebuffer_destroy_impl(gs_handle(gs_graphics_framebuffer_t) hndl)
  1102. {
  1103. gsgl_data_t* ogl = (gsgl_data_t*)gs_subsystem(graphics)->user_data;
  1104. if (!gs_slot_array_handle_valid(ogl->frame_buffers, hndl.id)) return;
  1105. gsgl_buffer_t buffer = gs_slot_array_get(ogl->frame_buffers, hndl.id);
  1106. glDeleteFramebuffers(1, &buffer);
  1107. gs_slot_array_erase(ogl->frame_buffers, hndl.id);
  1108. }
  1109. GS_API_DECL void
  1110. gs_graphics_renderpass_destroy_impl(gs_handle(gs_graphics_renderpass_t) hndl)
  1111. {
  1112. gsgl_data_t* ogl = (gsgl_data_t*)gs_subsystem(graphics)->user_data;
  1113. if (!gs_slot_array_handle_valid(ogl->renderpasses, hndl.id)) return;
  1114. // TODO(john): erase all color attachments from renderpasss
  1115. gs_slot_array_erase(ogl->renderpasses, hndl.id);
  1116. }
  1117. GS_API_DECL void
  1118. gs_graphics_pipeline_destroy_impl(gs_handle(gs_graphics_pipeline_t) hndl)
  1119. {
  1120. gsgl_data_t* ogl = (gsgl_data_t*)gs_subsystem(graphics)->user_data;
  1121. if (!gs_slot_array_handle_valid(ogl->pipelines, hndl.id)) return;
  1122. gsgl_pipeline_t* pip = gs_slot_array_getp(ogl->pipelines, hndl.id);
  1123. // Free layout
  1124. gs_dyn_array_free(pip->layout);
  1125. // Erase handles from slot arrays
  1126. gs_slot_array_erase(ogl->pipelines, hndl.id);
  1127. }
  1128. // Resource Query
  1129. GS_API_DECL void
  1130. gs_graphics_pipeline_desc_query(gs_handle(gs_graphics_pipeline_t) hndl, gs_graphics_pipeline_desc_t* out)
  1131. {
  1132. if (!out) return;
  1133. gsgl_data_t* ogl = (gsgl_data_t*)gs_subsystem(graphics)->user_data;
  1134. gsgl_pipeline_t* pip = gs_slot_array_getp(ogl->pipelines, hndl.id);
  1135. // Add states
  1136. out->blend = pip->blend;
  1137. out->depth = pip->depth;
  1138. out->raster = pip->raster;
  1139. out->stencil = pip->stencil;
  1140. out->compute = pip->compute;
  1141. // Add layout
  1142. uint32_t ct = gs_dyn_array_size(pip->layout);
  1143. for (uint32_t i = 0; i < ct; ++i) {
  1144. gs_dyn_array_push(out->layout.attrs, pip->layout[i]);
  1145. }
  1146. }
  1147. GS_API_DECL void
  1148. gs_graphics_texture_desc_query(gs_handle(gs_graphics_texture_t) hndl, gs_graphics_texture_desc_t* out)
  1149. {
  1150. if (!out) return;
  1151. gsgl_data_t* ogl = (gsgl_data_t*)gs_subsystem(graphics)->user_data;
  1152. gsgl_texture_t* tex = gs_slot_array_getp(ogl->textures, hndl.id);
  1153. // Read back pixels
  1154. // NOTE(john): This is currently NOT WORKING.
  1155. if (out->read.width && out->read.height)
  1156. {
  1157. uint32_t type = gsgl_texture_format_to_gl_data_type(tex->desc.format);
  1158. uint32_t format = gsgl_texture_format_to_gl_texture_format(tex->desc.format);
  1159. CHECK_GL_CORE(
  1160. glGetTextureSubImage(tex->id, 0, out->read.x, out->read.y, 0, out->read.width, out->read.height, 1, format, type, out->read.size, out->data);
  1161. // glBindTexture(GL_TEXTURE_2D, tex->id);
  1162. // glGetTexImage(GL_TEXTURE_2D, 0, format, type, out->data);
  1163. // glBindTexture(GL_TEXTURE_2D, 0);
  1164. );
  1165. }
  1166. // Just setting to tex desc for now, since reading texels isn't working correctly.
  1167. *out = tex->desc;
  1168. }
  1169. GS_API_DECL size_t
  1170. gs_graphics_uniform_size_query(gs_handle(gs_graphics_uniform_t) hndl)
  1171. {
  1172. gsgl_data_t* ogl = (gsgl_data_t*)gs_subsystem(graphics)->user_data;
  1173. gsgl_uniform_list_t* u = gs_slot_array_getp(ogl->uniforms, hndl.id);
  1174. return u->uniforms[0].size;
  1175. }
  1176. // Resource Updates (main thread only)
  1177. GS_API_DECL void
  1178. gs_graphics_texture_update_impl(gs_handle(gs_graphics_texture_t) hndl, gs_graphics_texture_desc_t* desc)
  1179. {
  1180. if (!desc) return;
  1181. gsgl_data_t* ogl = (gsgl_data_t*)gs_subsystem(graphics)->user_data;
  1182. if (!gs_slot_array_handle_valid(ogl->textures, hndl.id))
  1183. {
  1184. gs_log_warning("Texture handle invalid: %zu", hndl.id);
  1185. return;
  1186. }
  1187. gl_texture_update_internal(desc, hndl.id);
  1188. }
  1189. GS_API_DECL void
  1190. gs_graphics_vertex_buffer_update_impl(gs_handle(gs_graphics_vertex_buffer_t) hndl, gs_graphics_vertex_buffer_desc_t* desc)
  1191. {
  1192. /*
  1193. void __gs_graphics_update_buffer_internal(gs_command_buffer_t* cb,
  1194. uint32_t id,
  1195. gs_graphics_buffer_type type,
  1196. gs_graphics_buffer_usage_type usage,
  1197. size_t sz,
  1198. size_t offset,
  1199. gs_graphics_buffer_update_type update_type,
  1200. void* data)
  1201. {
  1202. // Write command
  1203. gs_byte_buffer_write(&cb->commands, u32, (u32)GS_OPENGL_OP_REQUEST_BUFFER_UPDATE);
  1204. cb->num_commands++;
  1205. // Write handle id
  1206. gs_byte_buffer_write(&cb->commands, uint32_t, id);
  1207. // Write type
  1208. gs_byte_buffer_write(&cb->commands, gs_graphics_buffer_type, type);
  1209. // Write usage
  1210. gs_byte_buffer_write(&cb->commands, gs_graphics_buffer_usage_type, usage);
  1211. // Write data size
  1212. gs_byte_buffer_write(&cb->commands, size_t, sz);
  1213. // Write data offset
  1214. gs_byte_buffer_write(&cb->commands, size_t, offset);
  1215. // Write data update type
  1216. gs_byte_buffer_write(&cb->commands, gs_graphics_buffer_update_type, update_type);
  1217. // Write data
  1218. gs_byte_buffer_write_bulk(&cb->commands, data, sz);
  1219. }
  1220. __gs_graphics_update_buffer_internal(cb, hndl.id, GS_GRAPHICS_BUFFER_VERTEX, desc->usage, desc->size, desc->update.offset, desc->update.type, desc->data);
  1221. */
  1222. gsgl_data_t* ogl = (gsgl_data_t*)gs_subsystem(graphics)->user_data;
  1223. gsgl_buffer_t buffer = gs_slot_array_get(ogl->vertex_buffers, hndl.id);
  1224. glBindBuffer(GL_ARRAY_BUFFER, buffer);
  1225. int32_t glusage = gsgl_buffer_usage_to_gl_enum(desc->usage);
  1226. switch (desc->update.type)
  1227. {
  1228. case GS_GRAPHICS_BUFFER_UPDATE_SUBDATA: glBufferSubData(GL_ARRAY_BUFFER, desc->update.offset, desc->size, desc->data); break;
  1229. default: glBufferData(GL_ARRAY_BUFFER, desc->size, desc->data, glusage); break;
  1230. }
  1231. glBindBuffer(GL_ARRAY_BUFFER, 0);
  1232. }
  1233. GS_API_DECL void
  1234. gs_graphics_index_buffer_update_impl(gs_handle(gs_graphics_index_buffer_t) hndl, gs_graphics_index_buffer_desc_t* desc)
  1235. {
  1236. gsgl_data_t* ogl = (gsgl_data_t*)gs_subsystem(graphics)->user_data;
  1237. gsgl_buffer_t buffer = gs_slot_array_get(ogl->index_buffers, hndl.id);
  1238. int32_t glusage = gsgl_buffer_usage_to_gl_enum(desc->usage);
  1239. glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer);
  1240. switch (desc->update.type) {
  1241. case GS_GRAPHICS_BUFFER_UPDATE_SUBDATA: glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, desc->update.offset, desc->size, desc->data); break;
  1242. default: glBufferData(GL_ELEMENT_ARRAY_BUFFER, desc->size, desc->data, glusage); break;
  1243. }
  1244. glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
  1245. }
  1246. GS_API_DECL void
  1247. gs_graphics_storage_buffer_update_impl(gs_handle(gs_graphics_storage_buffer_t) hndl, gs_graphics_storage_buffer_desc_t* desc)
  1248. {
  1249. gsgl_data_t* ogl = (gsgl_data_t*)gs_subsystem(graphics)->user_data;
  1250. gsgl_storage_buffer_t* sbo = gs_slot_array_getp(ogl->storage_buffers, hndl.id);
  1251. if (!sbo)
  1252. {
  1253. gs_println("Warning: Storage buffer %zu not found.", hndl.id);
  1254. return;
  1255. }
  1256. CHECK_GL_CORE(
  1257. glBindBuffer(GL_SHADER_STORAGE_BUFFER, sbo->buffer);
  1258. glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT);
  1259. switch (desc->update.type) {
  1260. case GS_GRAPHICS_BUFFER_UPDATE_SUBDATA: glBufferSubData(GL_SHADER_STORAGE_BUFFER, desc->update.offset, desc->size, desc->data); break;
  1261. default: glBufferData(GL_SHADER_STORAGE_BUFFER, desc->size, desc->data, gsgl_buffer_usage_to_gl_enum(desc->usage));
  1262. }
  1263. glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
  1264. );
  1265. }
  1266. GS_API_DECL void
  1267. gs_graphics_texture_read_impl(gs_handle(gs_graphics_texture_t) hndl, gs_graphics_texture_desc_t* desc)
  1268. {
  1269. gsgl_data_t* ogl = (gsgl_data_t*)gs_subsystem(graphics)->user_data;
  1270. if (!desc) return;
  1271. if (!gs_slot_array_handle_valid(ogl->textures, hndl.id))
  1272. {
  1273. gs_log_warning("Texture handle invalid: %zu", hndl.id);
  1274. }
  1275. gsgl_texture_t* tex = gs_slot_array_getp(ogl->textures, hndl.id);
  1276. // Bind texture
  1277. GLenum target = 0x00;
  1278. switch (tex->desc.type)
  1279. {
  1280. default:
  1281. case GS_GRAPHICS_TEXTURE_2D: {target = GL_TEXTURE_2D;} break;
  1282. case GS_GRAPHICS_TEXTURE_CUBEMAP: {target = GL_TEXTURE_CUBE_MAP;} break;
  1283. }
  1284. uint32_t gl_format = gsgl_texture_format_to_gl_texture_format(tex->desc.format);
  1285. uint32_t gl_type = gsgl_texture_format_to_gl_data_type(tex->desc.format);
  1286. glBindTexture(target, tex->id);
  1287. glReadPixels(
  1288. desc->read.x,
  1289. desc->read.y,
  1290. desc->read.width,
  1291. desc->read.height,
  1292. gl_format,
  1293. gl_type,
  1294. (void*)desc->data[0]
  1295. );
  1296. glBindTexture(target, 0x00);
  1297. }
  1298. GS_API_DECL void*
  1299. gs_graphics_storage_buffer_map_get_impl(gs_handle(gs_graphics_storage_buffer_t) hndl)
  1300. {
  1301. gsgl_data_t* ogl = (gsgl_data_t*)gs_subsystem(graphics)->user_data;
  1302. if (!gs_slot_array_handle_valid(ogl->storage_buffers, hndl.id)) {
  1303. gs_log_warning("Storage buffer handle invalid: %zu", hndl.id);
  1304. return NULL;
  1305. }
  1306. gsgl_storage_buffer_t* sbo = gs_slot_array_getp(ogl->storage_buffers, hndl.id);
  1307. return sbo->map;
  1308. }
  1309. GS_API_DECL void
  1310. gs_grapics_storage_buffer_unlock_impl(gs_handle(gs_graphics_storage_buffer_t) hndl)
  1311. {
  1312. // Unlock and return mapped pointer
  1313. gsgl_data_t* ogl = (gsgl_data_t*)gs_subsystem(graphics)->user_data;
  1314. if (!gs_slot_array_handle_valid(ogl->storage_buffers, hndl.id)) {
  1315. gs_log_warning("Storage buffer handle invalid: %zu", hndl.id);
  1316. return;
  1317. }
  1318. gsgl_storage_buffer_t* sbo = gs_slot_array_getp(ogl->storage_buffers, hndl.id);
  1319. // Already unlocked?
  1320. if (sbo->sync) {
  1321. while (1) {
  1322. GLenum wait = glClientWaitSync(sbo->sync, GL_SYNC_FLUSH_COMMANDS_BIT, 1);
  1323. if (wait == GL_ALREADY_SIGNALED || wait == GL_CONDITION_SATISFIED) {
  1324. break;
  1325. }
  1326. }
  1327. }
  1328. // Check for persistence here?...
  1329. if (sbo->map) {
  1330. glUnmapBuffer(GL_SHADER_STORAGE_BUFFER); // Do this via DSA instead...
  1331. glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
  1332. }
  1333. }
  1334. GS_API_DECL void*
  1335. gs_grapics_storage_buffer_lock_impl(gs_handle(gs_graphics_storage_buffer_t) hndl, size_t offset, size_t sz)
  1336. {
  1337. // Lock
  1338. gsgl_data_t* ogl = (gsgl_data_t*)gs_subsystem(graphics)->user_data;
  1339. if (!gs_slot_array_handle_valid(ogl->storage_buffers, hndl.id)) {
  1340. gs_log_warning("Storage buffer handle invalid: %zu", hndl.id);
  1341. return NULL;
  1342. }
  1343. gsgl_storage_buffer_t* sbo = gs_slot_array_getp(ogl->storage_buffers, hndl.id);
  1344. // Already locked?
  1345. if (sbo->sync) {
  1346. glDeleteSync(sbo->sync);
  1347. }
  1348. // Not sure if this is correct...
  1349. sbo->sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
  1350. if (sbo->sync) {
  1351. while (1) {
  1352. GLenum wait = glClientWaitSync(sbo->sync, GL_SYNC_FLUSH_COMMANDS_BIT, 1);
  1353. if (wait == GL_ALREADY_SIGNALED || wait == GL_CONDITION_SATISFIED) {
  1354. break;
  1355. }
  1356. }
  1357. }
  1358. if (!sbo->map) {
  1359. // Get buffer size
  1360. glBindBuffer(GL_SHADER_STORAGE_BUFFER, sbo->buffer);
  1361. GLint buffer_sz = 0;
  1362. glGetBufferParameteriv(GL_SHADER_STORAGE_BUFFER, GL_BUFFER_SIZE, &buffer_sz);
  1363. gs_println("SZ: %zu, requested: %zu", buffer_sz, sz);
  1364. sbo->map = glMapBufferRange(GL_SHADER_STORAGE_BUFFER, (GLintptr)offset, (GLsizeiptr)sz, GL_MAP_READ_BIT);
  1365. GLenum err = glGetError();
  1366. if (err) {
  1367. gs_println("GL ERROR: 0x%x: %s", err, glGetString(err));
  1368. }
  1369. }
  1370. return sbo->map;
  1371. }
  1372. GS_API_DECL void
  1373. gs_storage_buffer_get_data_impl(gs_handle(gs_graphics_storage_buffer_t) hndl, size_t offset, size_t stride, void* out)
  1374. {
  1375. // Lock
  1376. gsgl_data_t* ogl = (gsgl_data_t*)gs_subsystem(graphics)->user_data;
  1377. if (!gs_slot_array_handle_valid(ogl->storage_buffers, hndl.id)) {
  1378. gs_log_warning("Storage buffer handle invalid: %zu", hndl.id);
  1379. return;
  1380. }
  1381. gsgl_storage_buffer_t* sbo = gs_slot_array_getp(ogl->storage_buffers, hndl.id);
  1382. glBindBuffer(GL_SHADER_STORAGE_BUFFER, sbo->buffer);
  1383. glGetBufferSubData(GL_SHADER_STORAGE_BUFFER, offset, stride, out);
  1384. GLenum err = glGetError();
  1385. if (err) {
  1386. // gs_println("GL ERROR: 0x%x: %s", err, glGetString(err));
  1387. }
  1388. glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
  1389. }
  1390. #define __ogl_push_command(CB, OP_CODE, ...)\
  1391. do {\
  1392. gsgl_data_t* DATA = (gsgl_data_t*)gs_subsystem(graphics)->user_data;\
  1393. gs_byte_buffer_write(&CB->commands, u32, (u32)OP_CODE);\
  1394. __VA_ARGS__\
  1395. CB->num_commands++;\
  1396. } while (0)
  1397. /* Command Buffer Ops: Pipeline / Pass / Bind / Draw */
  1398. GS_API_DECL void
  1399. gs_graphics_renderpass_begin(gs_command_buffer_t* cb, gs_handle(gs_graphics_renderpass_t) hndl)
  1400. {
  1401. __ogl_push_command(cb, GS_OPENGL_OP_BEGIN_RENDER_PASS, {
  1402. gs_byte_buffer_write(&cb->commands, uint32_t, hndl.id);
  1403. });
  1404. }
  1405. GS_API_DECL void
  1406. gs_graphics_renderpass_end(gs_command_buffer_t* cb)
  1407. {
  1408. __ogl_push_command(cb, GS_OPENGL_OP_END_RENDER_PASS, {
  1409. // Nothing...
  1410. });
  1411. }
  1412. GS_API_DECL void
  1413. gs_graphics_clear(gs_command_buffer_t* cb, gs_graphics_clear_desc_t* desc)
  1414. {
  1415. __ogl_push_command(cb, GS_OPENGL_OP_CLEAR, {
  1416. uint32_t count = !desc->actions ? 0 : !desc->size ? 1 : (uint32_t)((size_t)desc->size / (size_t)sizeof(gs_graphics_clear_action_t));
  1417. gs_byte_buffer_write(&cb->commands, uint32_t, count);
  1418. for (uint32_t i = 0; i < count; ++i) {
  1419. gs_byte_buffer_write(&cb->commands, gs_graphics_clear_action_t, desc->actions[i]);
  1420. }
  1421. });
  1422. }
  1423. GS_API_DECL void
  1424. gs_graphics_set_viewport(gs_command_buffer_t* cb, uint32_t x, uint32_t y, uint32_t w, uint32_t h)
  1425. {
  1426. __ogl_push_command(cb, GS_OPENGL_OP_SET_VIEWPORT, {
  1427. gs_byte_buffer_write(&cb->commands, uint32_t, x);
  1428. gs_byte_buffer_write(&cb->commands, uint32_t, y);
  1429. gs_byte_buffer_write(&cb->commands, uint32_t, w);
  1430. gs_byte_buffer_write(&cb->commands, uint32_t, h);
  1431. });
  1432. }
  1433. GS_API_DECL void
  1434. gs_graphics_set_view_scissor(gs_command_buffer_t* cb, uint32_t x, uint32_t y, uint32_t w, uint32_t h)
  1435. {
  1436. __ogl_push_command(cb, GS_OPENGL_OP_SET_VIEW_SCISSOR, {
  1437. gs_byte_buffer_write(&cb->commands, uint32_t, x);
  1438. gs_byte_buffer_write(&cb->commands, uint32_t, y);
  1439. gs_byte_buffer_write(&cb->commands, uint32_t, w);
  1440. gs_byte_buffer_write(&cb->commands, uint32_t, h);
  1441. });
  1442. }
  1443. GS_API_DECL void
  1444. gs_graphics_texture_request_update(gs_command_buffer_t* cb, gs_handle(gs_graphics_texture_t) hndl, gs_graphics_texture_desc_t* desc)
  1445. {
  1446. // Write command
  1447. gs_byte_buffer_write(&cb->commands, uint32_t, (uint32_t)GS_OPENGL_OP_REQUEST_TEXTURE_UPDATE);
  1448. cb->num_commands++;
  1449. uint32_t num_comps = 0;
  1450. size_t data_type_size = 0;
  1451. size_t total_size = 0;
  1452. switch(desc->format)
  1453. {
  1454. default:
  1455. case GS_GRAPHICS_TEXTURE_FORMAT_RGBA8: num_comps = 4; data_type_size = sizeof(uint8_t); break;
  1456. case GS_GRAPHICS_TEXTURE_FORMAT_RGB8: num_comps = 3; data_type_size = sizeof(uint8_t); break;
  1457. case GS_GRAPHICS_TEXTURE_FORMAT_A8: num_comps = 1; data_type_size = sizeof(uint8_t); break;
  1458. case GS_GRAPHICS_TEXTURE_FORMAT_R8: num_comps = 1; data_type_size = sizeof(uint8_t); break;
  1459. case GS_GRAPHICS_TEXTURE_FORMAT_R32UI: num_comps = 1; data_type_size = sizeof(uint32_t); break;
  1460. case GS_GRAPHICS_TEXTURE_FORMAT_R16UI: num_comps = 1; data_type_size = sizeof(uint16_t); break;
  1461. case GS_GRAPHICS_TEXTURE_FORMAT_RGBA16F: num_comps = 4; data_type_size = sizeof(float); break;
  1462. case GS_GRAPHICS_TEXTURE_FORMAT_RGBA32F: num_comps = 4; data_type_size = sizeof(float); break;
  1463. case GS_GRAPHICS_TEXTURE_FORMAT_DEPTH8: num_comps = 1; data_type_size = sizeof(float); break;
  1464. case GS_GRAPHICS_TEXTURE_FORMAT_DEPTH16: num_comps = 1; data_type_size = sizeof(float); break;
  1465. case GS_GRAPHICS_TEXTURE_FORMAT_DEPTH24: num_comps = 1; data_type_size = sizeof(float); break;
  1466. case GS_GRAPHICS_TEXTURE_FORMAT_DEPTH32F: num_comps = 1; data_type_size = sizeof(float); break;
  1467. case GS_GRAPHICS_TEXTURE_FORMAT_DEPTH24_STENCIL8: num_comps = 1; data_type_size = sizeof(uint32_t); break;
  1468. case GS_GRAPHICS_TEXTURE_FORMAT_DEPTH32F_STENCIL8: num_comps = 1; data_type_size = sizeof(float) + sizeof(uint8_t); break;
  1469. // NOTE(john): Because Apple is a shit company, I have to section this off and provide support for 4.1 only features.
  1470. // case GS_GRAPHICS_TEXTURE_FORMAT_STENCIL8: glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT8, width, height, 0, GL_DEPTH_COMPONENT, GL_FLOAT, data); break;
  1471. }
  1472. total_size = desc->width * desc->height * num_comps * data_type_size;
  1473. gs_byte_buffer_write(&cb->commands, uint32_t, hndl.id);
  1474. gs_byte_buffer_write(&cb->commands, gs_graphics_texture_desc_t, *desc);
  1475. gs_byte_buffer_write(&cb->commands, size_t, total_size);
  1476. gs_byte_buffer_write_bulk(&cb->commands, *desc->data, total_size);
  1477. }
  1478. void __gs_graphics_update_buffer_internal(gs_command_buffer_t* cb,
  1479. uint32_t id,
  1480. gs_graphics_buffer_type type,
  1481. gs_graphics_buffer_usage_type usage,
  1482. size_t sz,
  1483. size_t offset,
  1484. gs_graphics_buffer_update_type update_type,
  1485. void* data)
  1486. {
  1487. // Write command
  1488. gs_byte_buffer_write(&cb->commands, u32, (u32)GS_OPENGL_OP_REQUEST_BUFFER_UPDATE);
  1489. cb->num_commands++;
  1490. // Write handle id
  1491. gs_byte_buffer_write(&cb->commands, uint32_t, id);
  1492. // Write type
  1493. gs_byte_buffer_write(&cb->commands, gs_graphics_buffer_type, type);
  1494. // Write usage
  1495. gs_byte_buffer_write(&cb->commands, gs_graphics_buffer_usage_type, usage);
  1496. // Write data size
  1497. gs_byte_buffer_write(&cb->commands, size_t, sz);
  1498. // Write data offset
  1499. gs_byte_buffer_write(&cb->commands, size_t, offset);
  1500. // Write data update type
  1501. gs_byte_buffer_write(&cb->commands, gs_graphics_buffer_update_type, update_type);
  1502. // Write data
  1503. gs_byte_buffer_write_bulk(&cb->commands, data, sz);
  1504. }
  1505. GS_API_DECL void
  1506. gs_graphics_vertex_buffer_request_update(gs_command_buffer_t* cb, gs_handle(gs_graphics_vertex_buffer_t) hndl, gs_graphics_vertex_buffer_desc_t* desc)
  1507. {
  1508. gsgl_data_t* ogl = (gsgl_data_t*)gs_subsystem(graphics)->user_data;
  1509. // Return if handle not valid
  1510. if (!hndl.id) return;
  1511. __gs_graphics_update_buffer_internal(cb, hndl.id, GS_GRAPHICS_BUFFER_VERTEX, desc->usage, desc->size, desc->update.offset, desc->update.type, desc->data);
  1512. }
  1513. GS_API_DECL void
  1514. gs_graphics_index_buffer_request_update(gs_command_buffer_t* cb, gs_handle(gs_graphics_index_buffer_t) hndl, gs_graphics_index_buffer_desc_t* desc)
  1515. {
  1516. gsgl_data_t* ogl = (gsgl_data_t*)gs_subsystem(graphics)->user_data;
  1517. // Return if handle not valid
  1518. if (!hndl.id) return;
  1519. __gs_graphics_update_buffer_internal(cb, hndl.id, GS_GRAPHICS_BUFFER_INDEX, desc->usage, desc->size, desc->update.offset, desc->update.type, desc->data);
  1520. }
  1521. GS_API_DECL void
  1522. gs_graphics_uniform_buffer_request_update(gs_command_buffer_t* cb, gs_handle(gs_graphics_uniform_buffer_t) hndl, gs_graphics_uniform_buffer_desc_t* desc)
  1523. {
  1524. gsgl_data_t* ogl = (gsgl_data_t*)gs_subsystem(graphics)->user_data;
  1525. // Return if handle not valid
  1526. if (!hndl.id) return;
  1527. __gs_graphics_update_buffer_internal(cb, hndl.id, GS_GRAPHICS_BUFFER_UNIFORM, desc->usage, desc->size, desc->update.offset, desc->update.type, desc->data);
  1528. }
  1529. GS_API_DECL void
  1530. gs_graphics_storage_buffer_request_update(gs_command_buffer_t* cb, gs_handle(gs_graphics_storage_buffer_t) hndl, gs_graphics_storage_buffer_desc_t* desc)
  1531. {
  1532. gsgl_data_t* ogl = (gsgl_data_t*)gs_subsystem(graphics)->user_data;
  1533. // Return if handle not valid
  1534. if (!hndl.id) return;
  1535. __gs_graphics_update_buffer_internal(cb, hndl.id, GS_GRAPHICS_BUFFER_SHADER_STORAGE, desc->usage, desc->size, desc->update.offset, desc->update.type, desc->data);
  1536. }
  1537. void gs_graphics_apply_bindings(gs_command_buffer_t* cb, gs_graphics_bind_desc_t* binds)
  1538. {
  1539. gsgl_data_t* ogl = (gsgl_data_t*)gs_subsystem(graphics)->user_data;
  1540. // Increment commands
  1541. gs_byte_buffer_write(&cb->commands, u32, (u32)GS_OPENGL_OP_APPLY_BINDINGS);
  1542. cb->num_commands++;
  1543. // __ogl_push_command(cb, GS_OPENGL_OP_APPLY_BINDINGS,
  1544. {
  1545. // Get counts from buffers
  1546. uint32_t vct = binds->vertex_buffers.desc ? binds->vertex_buffers.size ? binds->vertex_buffers.size / sizeof(gs_graphics_bind_vertex_buffer_desc_t) : 1 : 0;
  1547. uint32_t ict = binds->index_buffers.desc ? binds->index_buffers.size ? binds->index_buffers.size / sizeof(gs_graphics_bind_index_buffer_desc_t) : 1 : 0;
  1548. uint32_t uct = binds->uniform_buffers.desc ? binds->uniform_buffers.size ? binds->uniform_buffers.size / sizeof(gs_graphics_bind_uniform_buffer_desc_t) : 1 : 0;
  1549. uint32_t pct = binds->uniforms.desc ? binds->uniforms.size ? binds->uniforms.size / sizeof(gs_graphics_bind_uniform_desc_t) : 1 : 0;
  1550. uint32_t ibc = binds->image_buffers.desc ? binds->image_buffers.size ? binds->image_buffers.size / sizeof(gs_graphics_bind_image_buffer_desc_t) : 1 : 0;
  1551. uint32_t sbc = binds->storage_buffers.desc ? binds->storage_buffers.size ? binds->storage_buffers.size / sizeof(gs_graphics_bind_storage_buffer_desc_t) : 1 : 0;
  1552. // Determine total count to write into command buffer
  1553. uint32_t ct = vct + ict + uct + pct + ibc + sbc;
  1554. gs_byte_buffer_write(&cb->commands, uint32_t, ct);
  1555. // Determine if need to clear any previous vertex buffers (if vct != 0)
  1556. gs_byte_buffer_write(&cb->commands, bool, (vct != 0));
  1557. // Vertex buffers
  1558. for (uint32_t i = 0; i < vct; ++i)
  1559. {
  1560. gs_graphics_bind_vertex_buffer_desc_t* decl = &binds->vertex_buffers.desc[i];
  1561. gs_byte_buffer_write(&cb->commands, gs_graphics_bind_type, GS_GRAPHICS_BIND_VERTEX_BUFFER);
  1562. gs_byte_buffer_write(&cb->commands, uint32_t, decl->buffer.id);
  1563. gs_byte_buffer_write(&cb->commands, size_t, decl->offset);
  1564. gs_byte_buffer_write(&cb->commands, gs_graphics_vertex_data_type, decl->data_type);
  1565. }
  1566. // Index buffers
  1567. for (uint32_t i = 0; i < ict; ++i)
  1568. {
  1569. gs_graphics_bind_index_buffer_desc_t* decl = &binds->index_buffers.desc[i];
  1570. gs_byte_buffer_write(&cb->commands, gs_graphics_bind_type, GS_GRAPHICS_BIND_INDEX_BUFFER);
  1571. gs_byte_buffer_write(&cb->commands, uint32_t, decl->buffer.id);
  1572. }
  1573. // Uniform buffers
  1574. for (uint32_t i = 0; i < uct; ++i)
  1575. {
  1576. gs_graphics_bind_uniform_buffer_desc_t* decl = &binds->uniform_buffers.desc[i];
  1577. uint32_t id = decl->buffer.id;
  1578. size_t sz = (size_t)(gs_slot_array_getp(ogl->uniform_buffers, id))->size;
  1579. gs_byte_buffer_write(&cb->commands, gs_graphics_bind_type, GS_GRAPHICS_BIND_UNIFORM_BUFFER);
  1580. gs_byte_buffer_write(&cb->commands, uint32_t, decl->buffer.id);
  1581. gs_byte_buffer_write(&cb->commands, uint32_t, decl->binding);
  1582. gs_byte_buffer_write(&cb->commands, size_t, decl->range.offset);
  1583. gs_byte_buffer_write(&cb->commands, size_t, decl->range.size);
  1584. }
  1585. // Image buffers
  1586. for (uint32_t i = 0; i < ibc; ++i)
  1587. {
  1588. gs_graphics_bind_image_buffer_desc_t* decl = &binds->image_buffers.desc[i];
  1589. gs_byte_buffer_write(&cb->commands, gs_graphics_bind_type, GS_GRAPHICS_BIND_IMAGE_BUFFER);
  1590. gs_byte_buffer_write(&cb->commands, uint32_t, decl->tex.id);
  1591. gs_byte_buffer_write(&cb->commands, uint32_t, decl->binding);
  1592. gs_byte_buffer_write(&cb->commands, gs_graphics_access_type, decl->access);
  1593. }
  1594. // Uniforms
  1595. for (uint32_t i = 0; i < pct; ++i)
  1596. {
  1597. gs_graphics_bind_uniform_desc_t* decl = &binds->uniforms.desc[i];
  1598. // Get size from uniform list
  1599. size_t sz = gs_slot_array_getp(ogl->uniforms, decl->uniform.id)->size;
  1600. gs_byte_buffer_write(&cb->commands, gs_graphics_bind_type, GS_GRAPHICS_BIND_UNIFORM);
  1601. gs_byte_buffer_write(&cb->commands, uint32_t, decl->uniform.id);
  1602. gs_byte_buffer_write(&cb->commands, size_t, sz);
  1603. gs_byte_buffer_write(&cb->commands, uint32_t, decl->binding);
  1604. gs_byte_buffer_write_bulk(&cb->commands, decl->data, sz);
  1605. }
  1606. // Storage buffers
  1607. CHECK_GL_CORE(
  1608. for (uint32_t i = 0; i < sbc; ++i)
  1609. {
  1610. gs_graphics_bind_storage_buffer_desc_t* decl = &binds->storage_buffers.desc[i];
  1611. gs_byte_buffer_write(&cb->commands, gs_graphics_bind_type, GS_GRAPHICS_BIND_STORAGE_BUFFER);
  1612. gs_byte_buffer_write(&cb->commands, uint32_t, decl->buffer.id);
  1613. gs_byte_buffer_write(&cb->commands, uint32_t, decl->binding);
  1614. gs_byte_buffer_write(&cb->commands, size_t, decl->range.offset);
  1615. gs_byte_buffer_write(&cb->commands, size_t, decl->range.size);
  1616. }
  1617. );
  1618. };
  1619. }
  1620. void gs_graphics_pipeline_bind(gs_command_buffer_t* cb, gs_handle(gs_graphics_pipeline_t) hndl)
  1621. {
  1622. // NOTE(john): Not sure if this is safe in the future, since the data for pipelines is on the main thread and MIGHT be tampered with on a separate thread.
  1623. __ogl_push_command(cb, GS_OPENGL_OP_BIND_PIPELINE, {
  1624. gs_byte_buffer_write(&cb->commands, uint32_t, hndl.id);
  1625. });
  1626. }
  1627. void gs_graphics_draw(gs_command_buffer_t* cb, gs_graphics_draw_desc_t* desc)
  1628. {
  1629. __ogl_push_command(cb, GS_OPENGL_OP_DRAW, {
  1630. gs_byte_buffer_write(&cb->commands, uint32_t, desc->start);
  1631. gs_byte_buffer_write(&cb->commands, uint32_t, desc->count);
  1632. gs_byte_buffer_write(&cb->commands, uint32_t, desc->instances);
  1633. gs_byte_buffer_write(&cb->commands, uint32_t, desc->base_vertex);
  1634. gs_byte_buffer_write(&cb->commands, uint32_t, desc->range.start);
  1635. gs_byte_buffer_write(&cb->commands, uint32_t, desc->range.end);
  1636. });
  1637. }
  1638. void gs_graphics_dispatch_compute(gs_command_buffer_t* cb, uint32_t num_x_groups, uint32_t num_y_groups, uint32_t num_z_groups)
  1639. {
  1640. __ogl_push_command(cb, GS_OPENGL_OP_DISPATCH_COMPUTE, {
  1641. gs_byte_buffer_write(&cb->commands, uint32_t, num_x_groups);
  1642. gs_byte_buffer_write(&cb->commands, uint32_t, num_y_groups);
  1643. gs_byte_buffer_write(&cb->commands, uint32_t, num_z_groups);
  1644. });
  1645. }
  1646. /* Submission (Main Thread) */
  1647. void gs_graphics_command_buffer_submit_impl(gs_command_buffer_t* cb)
  1648. {
  1649. /*
  1650. // Structure of command:
  1651. - Op code
  1652. - Data packet
  1653. */
  1654. gsgl_data_t* ogl = (gsgl_data_t*)gs_subsystem(graphics)->user_data;
  1655. // Set read position of buffer to beginning
  1656. gs_byte_buffer_seek_to_beg(&cb->commands);
  1657. // For each command in buffer
  1658. gs_for_range(cb->num_commands)
  1659. {
  1660. // Read in op code of command
  1661. gs_byte_buffer_readc(&cb->commands, gs_opengl_op_code_type, op_code);
  1662. switch (op_code)
  1663. {
  1664. case GS_OPENGL_OP_BEGIN_RENDER_PASS:
  1665. {
  1666. // Bind render pass stuff
  1667. gs_byte_buffer_readc(&cb->commands, uint32_t, rpid);
  1668. // If render pass exists, then we'll bind frame buffer and attachments
  1669. if (rpid && gs_slot_array_exists(ogl->renderpasses, rpid))
  1670. {
  1671. gsgl_renderpass_t* rp = gs_slot_array_getp(ogl->renderpasses, rpid);
  1672. // Bind frame buffer since it actually exists
  1673. if (rp->fbo.id && gs_slot_array_exists(ogl->frame_buffers, rp->fbo.id))
  1674. {
  1675. // Bind frame buffer
  1676. glBindFramebuffer(GL_FRAMEBUFFER, gs_slot_array_get(ogl->frame_buffers, rp->fbo.id));
  1677. // Bind color attachments
  1678. for (uint32_t r = 0; r < gs_dyn_array_size(rp->color); ++r)
  1679. {
  1680. uint32_t cid = rp->color[r].id;
  1681. if (cid && gs_slot_array_exists(ogl->textures, cid))
  1682. {
  1683. gsgl_texture_t* rt = gs_slot_array_getp(ogl->textures, cid);
  1684. glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + r, GL_TEXTURE_2D, rt->id, 0);
  1685. }
  1686. }
  1687. // Bind depth attachment
  1688. {
  1689. uint32_t depth_id = rp->depth.id;
  1690. if (depth_id && gs_slot_array_exists(ogl->textures, depth_id))
  1691. {
  1692. gsgl_texture_t* rt = gs_slot_array_getp(ogl->textures, depth_id);
  1693. glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, rt->id, 0);
  1694. }
  1695. }
  1696. }
  1697. }
  1698. } break;
  1699. case GS_OPENGL_OP_END_RENDER_PASS:
  1700. {
  1701. gsgl_data_t* ogl = (gsgl_data_t*)gs_subsystem(graphics)->user_data;
  1702. gsgl_reset_data_cache(&ogl->cache);
  1703. glBindFramebuffer(GL_FRAMEBUFFER, 0);
  1704. glBindBuffer(GL_ARRAY_BUFFER, 0);
  1705. glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
  1706. CHECK_GL_CORE(
  1707. glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, 0);
  1708. );
  1709. glDisable(GL_SCISSOR_TEST);
  1710. glDisable(GL_DEPTH_TEST);
  1711. glDisable(GL_STENCIL_TEST);
  1712. glDisable(GL_BLEND);
  1713. } break;
  1714. case GS_OPENGL_OP_CLEAR:
  1715. {
  1716. // Actions
  1717. gs_byte_buffer_readc(&cb->commands, uint32_t, action_count);
  1718. for (uint32_t j = 0; j < action_count; ++j)
  1719. {
  1720. gs_byte_buffer_readc(&cb->commands, gs_graphics_clear_action_t, action);
  1721. // No clear
  1722. if (action.flag & GS_GRAPHICS_CLEAR_NONE) {
  1723. continue;
  1724. }
  1725. uint32_t bit = 0x00;
  1726. if (action.flag & GS_GRAPHICS_CLEAR_COLOR || action.flag == 0x00) {
  1727. glClearColor(action.color[0], action.color[1], action.color[2], action.color[3]);
  1728. bit |= GL_COLOR_BUFFER_BIT;
  1729. }
  1730. if (action.flag & GS_GRAPHICS_CLEAR_DEPTH || action.flag == 0x00) {
  1731. bit |= GL_DEPTH_BUFFER_BIT;
  1732. }
  1733. if (action.flag & GS_GRAPHICS_CLEAR_STENCIL || action.flag == 0x00) {
  1734. bit |= GL_STENCIL_BUFFER_BIT;
  1735. glStencilMask(~0);
  1736. }
  1737. glClear(bit);
  1738. }
  1739. } break;
  1740. case GS_OPENGL_OP_SET_VIEWPORT:
  1741. {
  1742. gs_byte_buffer_readc(&cb->commands, uint32_t, x);
  1743. gs_byte_buffer_readc(&cb->commands, uint32_t, y);
  1744. gs_byte_buffer_readc(&cb->commands, uint32_t, w);
  1745. gs_byte_buffer_readc(&cb->commands, uint32_t, h);
  1746. glViewport(x, y, w, h);
  1747. } break;
  1748. case GS_OPENGL_OP_SET_VIEW_SCISSOR:
  1749. {
  1750. gs_byte_buffer_readc(&cb->commands, uint32_t, x);
  1751. gs_byte_buffer_readc(&cb->commands, uint32_t, y);
  1752. gs_byte_buffer_readc(&cb->commands, uint32_t, w);
  1753. gs_byte_buffer_readc(&cb->commands, uint32_t, h);
  1754. glEnable(GL_SCISSOR_TEST);
  1755. glScissor(x, y, w, h);
  1756. } break;
  1757. case GS_OPENGL_OP_APPLY_BINDINGS:
  1758. {
  1759. gs_byte_buffer_readc(&cb->commands, uint32_t, ct);
  1760. // Determine if need to clear any previous vertex buffers here
  1761. gs_byte_buffer_readc(&cb->commands, bool, clear_vertex_buffers);
  1762. // Clear previous vertex decls if necessary
  1763. if (clear_vertex_buffers) {
  1764. gs_dyn_array_clear(ogl->cache.vdecls);
  1765. glBindBuffer(GL_ARRAY_BUFFER, 0);
  1766. }
  1767. for (uint32_t i = 0; i < ct; ++i)
  1768. {
  1769. gs_byte_buffer_readc(&cb->commands, gs_graphics_bind_type, type);
  1770. switch (type)
  1771. {
  1772. case GS_GRAPHICS_BIND_VERTEX_BUFFER:
  1773. {
  1774. gs_byte_buffer_readc(&cb->commands, uint32_t, id);
  1775. gs_byte_buffer_readc(&cb->commands, size_t, offset);
  1776. gs_byte_buffer_readc(&cb->commands, gs_graphics_vertex_data_type, data_type);
  1777. if (!id || !gs_slot_array_exists(ogl->vertex_buffers, id))
  1778. {
  1779. /*
  1780. gs_timed_action(1000, {
  1781. gs_println("Warning:Opengl:BindBindings:VertexBuffer %d does not exist.", id);
  1782. continue;
  1783. });
  1784. */
  1785. }
  1786. // Grab vbo to bind
  1787. gsgl_buffer_t vbo = gs_slot_array_get(ogl->vertex_buffers, id);
  1788. // If the data type is non-interleaved, then push size into vertex buffer decl
  1789. gsgl_vertex_buffer_decl_t vbo_decl = gs_default_val();
  1790. vbo_decl.vbo = vbo;
  1791. vbo_decl.data_type = data_type;
  1792. vbo_decl.offset = offset;
  1793. // Cache vertex buffer for later use
  1794. gs_dyn_array_push(ogl->cache.vdecls, vbo_decl);
  1795. } break;
  1796. case GS_GRAPHICS_BIND_INDEX_BUFFER:
  1797. {
  1798. gs_byte_buffer_readc(&cb->commands, uint32_t, id);
  1799. if (!gs_slot_array_exists(ogl->index_buffers, id))
  1800. {
  1801. /*
  1802. gs_timed_action(1000, {
  1803. gs_println("Warning:Opengl:BindBindings:IndexBuffer %d does not exist.", id);
  1804. });
  1805. */
  1806. }
  1807. else
  1808. {
  1809. gsgl_buffer_t ibo = gs_slot_array_get(ogl->index_buffers, id);
  1810. // Store in cache
  1811. ogl->cache.ibo = id;
  1812. }
  1813. } break;
  1814. case GS_GRAPHICS_BIND_UNIFORM:
  1815. {
  1816. // Get size from uniform list
  1817. gs_byte_buffer_readc(&cb->commands, uint32_t, id);
  1818. // Read data size for uniform list
  1819. gs_byte_buffer_readc(&cb->commands, size_t, sz);
  1820. // Read binding from uniform list (could make this a binding list? not sure how to handle this)
  1821. gs_byte_buffer_readc(&cb->commands, uint32_t, binding);
  1822. // Check buffer id. If invalid, then we can't operate, and instead just need to pass over the data.
  1823. if (!id || !gs_slot_array_exists(ogl->uniforms, id)) {
  1824. /*
  1825. gs_timed_action(1000, {
  1826. gs_println("Warning:Bind Uniform:Uniform %d does not exist.", id);
  1827. });
  1828. */
  1829. gs_byte_buffer_advance_position(&cb->commands, sz);
  1830. continue;
  1831. }
  1832. // Grab currently bound pipeline (TODO(john): assert if this isn't valid)
  1833. if (!ogl->cache.pipeline.id || !gs_slot_array_exists(ogl->pipelines, ogl->cache.pipeline.id)){
  1834. /*
  1835. gs_timed_action(1000, {
  1836. gs_println("Warning:Bind Uniform Buffer:Pipeline %d does not exist.", ogl->cache.pipeline.id);
  1837. });
  1838. */
  1839. gs_byte_buffer_advance_position(&cb->commands, sz);
  1840. continue;
  1841. }
  1842. gsgl_pipeline_t* pip = gs_slot_array_getp(ogl->pipelines, ogl->cache.pipeline.id);
  1843. // Get uniform
  1844. gsgl_uniform_list_t* ul = gs_slot_array_getp(ogl->uniforms, id);
  1845. // Get bound shader from pipeline (either compute or raster)
  1846. uint32_t sid = pip->compute.shader.id ? pip->compute.shader.id : pip->raster.shader.id;
  1847. // Check uniform location. If UINT32_T max, then must construct and place location
  1848. for (uint32_t ui = 0; ui < gs_dyn_array_size(ul->uniforms); ++ui)
  1849. {
  1850. gsgl_uniform_t* u = &ul->uniforms[ui];
  1851. // Searching for location if not bound or sid doesn't match previous use
  1852. if ((u->location == UINT32_MAX && u->location != UINT32_MAX - 1) || u->sid != pip->raster.shader.id)
  1853. {
  1854. if (!sid || !gs_slot_array_exists(ogl->shaders, sid)) {
  1855. /*
  1856. gs_timed_action(1000, {
  1857. gs_println("Warning:Bind Uniform:Shader %d does not exist.", sid);
  1858. });
  1859. */
  1860. // Advance by size of uniform
  1861. gs_byte_buffer_advance_position(&cb->commands, sz);
  1862. continue;
  1863. }
  1864. gsgl_shader_t shader = gs_slot_array_get(ogl->shaders, sid);
  1865. // Construct temp name, concat with base name + uniform field name
  1866. char name[256] = gs_default_val();
  1867. memcpy(name, ul->name, 64);
  1868. gs_snprintfc(UTMP, 256, "%s%s", ul->name, u->name);
  1869. memcpy(name, UTMP, 256);
  1870. // Grab location of uniform based on name
  1871. u->location = glGetUniformLocation(shader, *name ? name : "__EMPTY_UNIFORM_NAME");
  1872. if (u->location >= UINT32_MAX) {
  1873. gs_println("Warning: Bind Uniform: Uniform not found: \"%s\"", name);
  1874. u->location = UINT32_MAX - 1;
  1875. }
  1876. u->sid = pip->raster.shader.id;
  1877. }
  1878. // Switch on uniform type to upload data
  1879. switch (u->type)
  1880. {
  1881. case GSGL_UNIFORMTYPE_FLOAT:
  1882. {
  1883. // Need to read bulk data for array.
  1884. gs_assert(u->size == sizeof(float));
  1885. gs_dyn_array_clear(ogl->uniform_data.flt);
  1886. uint32_t ct = u->count ? u->count : 1;
  1887. size_t sz = ct * u->size;
  1888. gs_for_range(ct) {
  1889. gs_byte_buffer_readc(&cb->commands, float, v);
  1890. gs_dyn_array_push(ogl->uniform_data.flt, v);
  1891. }
  1892. glUniform1fv(u->location, ct, ogl->uniform_data.flt);
  1893. } break;
  1894. case GSGL_UNIFORMTYPE_INT:
  1895. {
  1896. gs_assert(u->size == sizeof(int32_t));
  1897. gs_dyn_array_clear(ogl->uniform_data.i32);
  1898. uint32_t ct = u->count ? u->count : 1;
  1899. size_t sz = ct * u->size;
  1900. gs_for_range(ct) {
  1901. gs_byte_buffer_readc(&cb->commands, int32_t, v);
  1902. gs_dyn_array_push(ogl->uniform_data.i32, v);
  1903. }
  1904. glUniform1iv(u->location, ct, ogl->uniform_data.i32);
  1905. } break;
  1906. case GSGL_UNIFORMTYPE_VEC2:
  1907. {
  1908. gs_assert(u->size == sizeof(gs_vec2));
  1909. gs_dyn_array_clear(ogl->uniform_data.vec2);
  1910. uint32_t ct = u->count ? u->count : 1;
  1911. size_t sz = ct * u->size;
  1912. gs_for_range(ct) {
  1913. gs_byte_buffer_readc(&cb->commands, gs_vec2, v);
  1914. gs_dyn_array_push(ogl->uniform_data.vec2, v);
  1915. }
  1916. glUniform2fv(u->location, ct, (float*)ogl->uniform_data.vec2);
  1917. } break;
  1918. case GSGL_UNIFORMTYPE_VEC3:
  1919. {
  1920. gs_assert(u->size == sizeof(gs_vec3));
  1921. gs_dyn_array_clear(ogl->uniform_data.vec3);
  1922. uint32_t ct = u->count ? u->count : 1;
  1923. size_t sz = ct * u->size;
  1924. gs_for_range(ct) {
  1925. gs_byte_buffer_readc(&cb->commands, gs_vec3, v);
  1926. gs_dyn_array_push(ogl->uniform_data.vec3, v);
  1927. }
  1928. glUniform3fv(u->location, ct, (float*)ogl->uniform_data.vec3);
  1929. } break;
  1930. case GSGL_UNIFORMTYPE_VEC4:
  1931. {
  1932. gs_assert(u->size == sizeof(gs_vec4));
  1933. gs_dyn_array_clear(ogl->uniform_data.vec4);
  1934. uint32_t ct = u->count ? u->count : 1;
  1935. size_t sz = ct * u->size;
  1936. gs_for_range(ct) {
  1937. gs_byte_buffer_readc(&cb->commands, gs_vec4, v);
  1938. gs_dyn_array_push(ogl->uniform_data.vec4, v);
  1939. }
  1940. glUniform4fv(u->location, ct, (float*)ogl->uniform_data.vec4);
  1941. } break;
  1942. case GSGL_UNIFORMTYPE_MAT4:
  1943. {
  1944. gs_assert(u->size == sizeof(gs_mat4));
  1945. gs_dyn_array_clear(ogl->uniform_data.mat4);
  1946. uint32_t ct = u->count ? u->count : 1;
  1947. size_t sz = ct * u->size;
  1948. gs_for_range(ct) {
  1949. gs_byte_buffer_readc(&cb->commands, gs_mat4, v);
  1950. gs_dyn_array_push(ogl->uniform_data.mat4, v);
  1951. }
  1952. glUniformMatrix4fv(u->location, ct, false, (float*)ogl->uniform_data.mat4);
  1953. } break;
  1954. case GSGL_UNIFORMTYPE_SAMPLERCUBE:
  1955. case GSGL_UNIFORMTYPE_SAMPLER2D:
  1956. {
  1957. gs_assert(u->size == sizeof(gs_handle(gs_graphics_texture_t)));
  1958. uint32_t ct = u->count ? u->count : 1;
  1959. int32_t binds[128] = gs_default_val();
  1960. for (uint32_t i = 0; (i < ct && i < 128); ++i) // Max of 128 texture binds. Get real.
  1961. {
  1962. gs_byte_buffer_read_bulkc(&cb->commands, gs_handle(gs_graphics_texture_t), v, u->size);
  1963. // Get texture, also need binding, but will worry about that in a bit
  1964. gsgl_texture_t* tex = gs_slot_array_getp(ogl->textures, v.id);
  1965. // Activate texture slot
  1966. glActiveTexture(GL_TEXTURE0 + binding);
  1967. // Bind texture
  1968. GLenum target = 0x00;
  1969. switch (tex->desc.type)
  1970. {
  1971. default:
  1972. case GS_GRAPHICS_TEXTURE_2D: {target = GL_TEXTURE_2D;} break;
  1973. case GS_GRAPHICS_TEXTURE_CUBEMAP: {target = GL_TEXTURE_CUBE_MAP;} break;
  1974. }
  1975. glBindTexture(target, tex->id);
  1976. binds[i] = (int32_t)binding++;
  1977. }
  1978. // Bind uniforms
  1979. glUniform1iv(u->location, ct, (int32_t*)binds);
  1980. } break;
  1981. default: {
  1982. // Shouldn't hit here
  1983. gs_println("Assert: Bind Uniform: Invalid uniform type specified.");
  1984. gs_assert(false);
  1985. } break;
  1986. }
  1987. }
  1988. } break;
  1989. case GS_GRAPHICS_BIND_UNIFORM_BUFFER:
  1990. {
  1991. // Read slot id of uniform buffer
  1992. gs_byte_buffer_readc(&cb->commands, uint32_t, id);
  1993. // Read binding
  1994. gs_byte_buffer_readc(&cb->commands, uint32_t, binding);
  1995. // Read range offset
  1996. gs_byte_buffer_readc(&cb->commands, size_t, range_offset);
  1997. // Read range size
  1998. gs_byte_buffer_readc(&cb->commands, size_t, range_size);
  1999. // Check buffer id. If invalid, then we can't operate, and instead just need to pass over the data.
  2000. if (!id || !gs_slot_array_exists(ogl->uniform_buffers, id)) {
  2001. /*
  2002. gs_timed_action(1000, {
  2003. gs_println("Warning:Bind Uniform Buffer:Uniform %d does not exist.", id);
  2004. });
  2005. */
  2006. continue;
  2007. }
  2008. // Grab currently bound pipeline (TODO(john): assert if this isn't valid)
  2009. if (!ogl->cache.pipeline.id || !gs_slot_array_exists(ogl->pipelines, ogl->cache.pipeline.id)){
  2010. /*
  2011. gs_timed_action(1000, {
  2012. gs_println("Warning:Bind Uniform Buffer:Pipeline %d does not exist.", ogl->cache.pipeline.id);
  2013. });
  2014. */
  2015. continue;
  2016. }
  2017. gsgl_pipeline_t* pip = gs_slot_array_getp(ogl->pipelines, ogl->cache.pipeline.id);
  2018. // Get uniform
  2019. gsgl_uniform_buffer_t* u = gs_slot_array_getp(ogl->uniform_buffers, id);
  2020. // Get bound shader from pipeline (either compute or raster)
  2021. uint32_t sid = pip->compute.shader.id ? pip->compute.shader.id : pip->raster.shader.id;
  2022. // Check uniform location.
  2023. // If UINT32_T max, then must construct and place location, or if shader id doesn't match previously used shader with this uniform
  2024. // TODO(john): To avoid constant lookups in this case, allow for shaders to hold uniform handles references instead.
  2025. if ((u->location == UINT32_MAX && u->location != UINT32_MAX - 1) || u->sid != pip->raster.shader.id)
  2026. {
  2027. if (!sid || !gs_slot_array_exists(ogl->shaders, sid)) {
  2028. /*
  2029. gs_timed_action(1000, {
  2030. gs_println("Warning:Bind Uniform Buffer:Shader %d does not exist.", sid);
  2031. });
  2032. */
  2033. continue;
  2034. }
  2035. gsgl_shader_t shader = gs_slot_array_get(ogl->shaders, sid);
  2036. // Get uniform location based on name and bound shader
  2037. u->location = glGetUniformBlockIndex(shader, *u->name ? u->name : "__EMPTY_UNIFORM_NAME");
  2038. // Set binding for uniform block
  2039. glUniformBlockBinding(shader, u->location, binding);
  2040. if (u->location >= UINT32_MAX) {
  2041. gs_println("Warning: Bind Uniform Buffer: Uniform not found: \"%s\"", u->name);
  2042. u->location = UINT32_MAX - 1;
  2043. }
  2044. u->sid = pip->raster.shader.id;
  2045. }
  2046. glBindBufferRange(GL_UNIFORM_BUFFER, binding, u->ubo, range_offset, range_size ? range_size : u->size);
  2047. } break;
  2048. case GS_GRAPHICS_BIND_STORAGE_BUFFER:
  2049. {
  2050. gs_byte_buffer_readc(&cb->commands, uint32_t, sb_slot_id);
  2051. gs_byte_buffer_readc(&cb->commands, uint32_t, binding);
  2052. gs_byte_buffer_readc(&cb->commands, size_t, range_offset);
  2053. gs_byte_buffer_readc(&cb->commands, size_t, range_size);
  2054. // Grab storage buffer from id
  2055. if (!sb_slot_id || !gs_slot_array_exists(ogl->storage_buffers, sb_slot_id)) {
  2056. /*
  2057. gs_timed_action(1000, {
  2058. gs_println("Warning:Bind Storage Buffer:Storage Buffer %d does not exist.", sb_slot_id);
  2059. });
  2060. */
  2061. continue;
  2062. }
  2063. // Grab currently bound pipeline (TODO(john): assert if this isn't valid)
  2064. if (!ogl->cache.pipeline.id || !gs_slot_array_exists(ogl->pipelines, ogl->cache.pipeline.id)){
  2065. /*
  2066. gs_timed_action(1000, {
  2067. gs_println("Warning:Bind Storage Buffer:Pipeline %d does not exist or is not bound.", ogl->cache.pipeline.id);
  2068. });
  2069. */
  2070. continue;
  2071. }
  2072. gsgl_pipeline_t* pip = gs_slot_array_getp(ogl->pipelines, ogl->cache.pipeline.id);
  2073. gsgl_storage_buffer_t* sbo = gs_slot_array_getp(ogl->storage_buffers, sb_slot_id);
  2074. // Get bound shader from pipeline (either compute or raster)
  2075. uint32_t sid = pip->compute.shader.id ? pip->compute.shader.id : pip->raster.shader.id;
  2076. if (!sid || !gs_slot_array_exists(ogl->shaders, sid)) {
  2077. /*
  2078. gs_timed_action(1000, {
  2079. gs_println("Warning:Bind Uniform Buffer:Shader %d does not exist.", sid);
  2080. });
  2081. */
  2082. continue;
  2083. }
  2084. gsgl_shader_t shader = gs_slot_array_get(ogl->shaders, sid);
  2085. if ((sbo->block_idx == UINT32_MAX && sbo->block_idx != UINT32_MAX - 1))
  2086. {
  2087. // Get uniform location based on name and bound shader
  2088. CHECK_GL_CORE(
  2089. sbo->block_idx = glGetProgramResourceIndex(shader, GL_SHADER_STORAGE_BLOCK, *sbo->name ? sbo->name : "__EMPTY_BUFFER_NAME");
  2090. int32_t params[1];
  2091. GLenum props[1] = {GL_BUFFER_BINDING};
  2092. glGetProgramResourceiv(shader, GL_SHADER_STORAGE_BLOCK, sbo->block_idx, 1, props, 1, NULL, params);
  2093. sbo->location = (uint32_t)params[0];
  2094. gs_println("Bind Storage Buffer: Binding \"%s\" to location %zu, block index: %zu, binding: %zu",
  2095. sbo->name, sbo->location, sbo->block_idx, binding);
  2096. );
  2097. if (sbo->block_idx >= UINT32_MAX) {
  2098. gs_println("Warning: Bind Storage Buffer: Buffer not found: \"%s\"", sbo->name);
  2099. sbo->block_idx = UINT32_MAX - 1;
  2100. }
  2101. }
  2102. if (sbo->block_idx < UINT32_MAX - 1)
  2103. {
  2104. // Not sure what this actually does atm...
  2105. CHECK_GL_CORE(
  2106. // TODO(): This should use 'binding' instead of 'sbo->location'
  2107. glShaderStorageBlockBinding(shader, sbo->block_idx, sbo->location);
  2108. );
  2109. }
  2110. // This is required
  2111. CHECK_GL_CORE(
  2112. // glBindBufferRange(GL_SHADER_STORAGE_BUFFER, binding, sbo->buffer,
  2113. // range_offset, range_size ? range_size : sbo->size - range_offset);
  2114. glBindBufferBase(GL_SHADER_STORAGE_BUFFER, binding, sbo->buffer);
  2115. );
  2116. } break;
  2117. case GS_GRAPHICS_BIND_IMAGE_BUFFER:
  2118. {
  2119. gs_byte_buffer_readc(&cb->commands, uint32_t, tex_slot_id);
  2120. gs_byte_buffer_readc(&cb->commands, uint32_t, binding);
  2121. gs_byte_buffer_readc(&cb->commands, gs_graphics_access_type, access);
  2122. // Grab texture from sampler id
  2123. if (!tex_slot_id || !gs_slot_array_exists(ogl->textures, tex_slot_id)) {
  2124. /*
  2125. gs_timed_action(1000, {
  2126. gs_println("Warning:Bind Image Buffer:Texture %d does not exist.", tex_slot_id);
  2127. });
  2128. */
  2129. continue;
  2130. }
  2131. gsgl_texture_t* tex = gs_slot_array_getp(ogl->textures, tex_slot_id);
  2132. uint32_t gl_access = gsgl_access_type_to_gl_access_type(access);
  2133. uint32_t gl_format = gsgl_texture_format_to_gl_texture_internal_format(tex->desc.format);
  2134. // Bind image texture
  2135. CHECK_GL_CORE(glBindImageTexture(binding, tex->id, 0, GL_FALSE, 0, gl_access, gl_format);)
  2136. } break;
  2137. default: gs_assert(false); break;
  2138. }
  2139. }
  2140. } break;
  2141. case GS_OPENGL_OP_BIND_PIPELINE:
  2142. {
  2143. // Bind pipeline stuff
  2144. gs_byte_buffer_readc(&cb->commands, uint32_t, pipid);
  2145. // Make sure pipeline exists
  2146. if (!pipid || !gs_slot_array_exists(ogl->pipelines, pipid)) {
  2147. /*
  2148. gs_timed_action(1000, {
  2149. gs_println("Warning: Pipeline %d does not exist.", pipid);
  2150. });
  2151. */
  2152. continue;
  2153. }
  2154. // Reset cache
  2155. gsgl_reset_data_cache(&ogl->cache);
  2156. // Reset state as well
  2157. gsgl_pipeline_state();
  2158. /* Cache pipeline id */
  2159. ogl->cache.pipeline = gs_handle_create(gs_graphics_pipeline_t, pipid);
  2160. gsgl_pipeline_t* pip = gs_slot_array_getp(ogl->pipelines, pipid);
  2161. /* Compute */
  2162. // Early out if compute, since we're not doing a rasterization stage
  2163. if (pip->compute.shader.id)
  2164. {
  2165. /* Shader */
  2166. if (pip->compute.shader.id && gs_slot_array_exists(ogl->shaders, pip->compute.shader.id)) {
  2167. glUseProgram(gs_slot_array_get(ogl->shaders, pip->compute.shader.id));
  2168. }
  2169. else {
  2170. /*
  2171. gs_timed_action(1000, {
  2172. gs_println("Warning:Opengl:BindPipeline:Compute:Shader %d does not exist.", pip->compute.shader.id);
  2173. });
  2174. */
  2175. }
  2176. continue;
  2177. }
  2178. /* Depth */
  2179. if (!pip->depth.func) {
  2180. // If no depth function (default), then disable
  2181. glDisable(GL_DEPTH_TEST);
  2182. }
  2183. else {
  2184. glEnable(GL_DEPTH_TEST);
  2185. glDepthFunc(gsgl_depth_func_to_gl_depth_func(pip->depth.func));
  2186. }
  2187. glDepthMask(gsgl_depth_mask_to_gl_mask(pip->depth.mask));
  2188. /* Stencil */
  2189. if (!pip->stencil.func) {
  2190. // If no stencil function (default), then disable
  2191. glDisable(GL_STENCIL_TEST);
  2192. } else {
  2193. glEnable(GL_STENCIL_TEST);
  2194. uint32_t func = gsgl_stencil_func_to_gl_stencil_func(pip->stencil.func);
  2195. uint32_t sfail = gsgl_stencil_op_to_gl_stencil_op(pip->stencil.sfail);
  2196. uint32_t dpfail = gsgl_stencil_op_to_gl_stencil_op(pip->stencil.dpfail);
  2197. uint32_t dppass = gsgl_stencil_op_to_gl_stencil_op(pip->stencil.dppass);
  2198. glStencilFunc(func, pip->stencil.ref, pip->stencil.comp_mask);
  2199. glStencilMask(pip->stencil.write_mask);
  2200. glStencilOp(sfail, dpfail, dppass);
  2201. }
  2202. /* Blend */
  2203. if (!pip->blend.func) {
  2204. glDisable(GL_BLEND);
  2205. } else {
  2206. glEnable(GL_BLEND);
  2207. glBlendEquation(gsgl_blend_equation_to_gl_blend_eq(pip->blend.func));
  2208. glBlendFunc(gsgl_blend_mode_to_gl_blend_mode(pip->blend.src, GL_ONE),
  2209. gsgl_blend_mode_to_gl_blend_mode(pip->blend.dst, GL_ZERO));
  2210. }
  2211. /* Raster */
  2212. // Face culling
  2213. if (!pip->raster.face_culling) {
  2214. glDisable(GL_CULL_FACE);
  2215. } else {
  2216. glEnable(GL_CULL_FACE);
  2217. glCullFace(gsgl_cull_face_to_gl_cull_face(pip->raster.face_culling));
  2218. }
  2219. // Winding order
  2220. glFrontFace(gsgl_winding_order_to_gl_winding_order(pip->raster.winding_order));
  2221. /* Shader */
  2222. if (pip->raster.shader.id && gs_slot_array_exists(ogl->shaders, pip->raster.shader.id)) {
  2223. glUseProgram(gs_slot_array_get(ogl->shaders, pip->raster.shader.id));
  2224. }
  2225. else {
  2226. /*
  2227. gs_timed_action(1000, {
  2228. gs_println("Warning:Opengl:BindPipeline:Shader %d does not exist.", pip->raster.shader.id);
  2229. });
  2230. */
  2231. }
  2232. } break;
  2233. case GS_OPENGL_OP_DISPATCH_COMPUTE:
  2234. {
  2235. gs_byte_buffer_readc(&cb->commands, uint32_t, num_x_groups);
  2236. gs_byte_buffer_readc(&cb->commands, uint32_t, num_y_groups);
  2237. gs_byte_buffer_readc(&cb->commands, uint32_t, num_z_groups);
  2238. // Grab currently bound pipeline (TODO(john): assert if this isn't valid)
  2239. if (ogl->cache.pipeline.id == 0 || !gs_slot_array_exists(ogl->pipelines, ogl->cache.pipeline.id)) {
  2240. /*
  2241. gs_timed_action(1000, {
  2242. gs_println("Warning:Opengl:DispatchCompute:Compute Pipeline not bound.");
  2243. });
  2244. */
  2245. continue;
  2246. }
  2247. gsgl_pipeline_t* pip = gs_slot_array_getp(ogl->pipelines, ogl->cache.pipeline.id);
  2248. // If pipeline does not have a compute state bound, then leave
  2249. if (!pip->compute.shader.id) {
  2250. /*
  2251. gs_timed_action(1000, {
  2252. gs_println("Warning:Opengl:DispatchCompute:Compute Pipeline not bound.");
  2253. });
  2254. */
  2255. continue;
  2256. }
  2257. // Dispatch shader
  2258. CHECK_GL_CORE(
  2259. // Memory barrier (TODO(john): make this specifically set in the pipeline state)
  2260. glDispatchCompute(num_x_groups, num_y_groups, num_z_groups);
  2261. glMemoryBarrier(GL_ALL_BARRIER_BITS);
  2262. // glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT);
  2263. )
  2264. } break;
  2265. case GS_OPENGL_OP_DRAW:
  2266. {
  2267. // Grab currently bound pipeline (TODO(john): assert if this isn't valid)
  2268. gsgl_pipeline_t* pip = gs_slot_array_getp(ogl->pipelines, ogl->cache.pipeline.id);
  2269. // Must have a vertex buffer bound to draw
  2270. if (gs_dyn_array_empty(ogl->cache.vdecls)) {
  2271. gs_timed_action(1000, {
  2272. gs_println("Error:Opengl:Draw: No vertex buffer bound.");
  2273. });
  2274. // gs_assert(false);
  2275. }
  2276. // Keep track whether or not the data is to be instanced
  2277. bool is_instanced = false;
  2278. for (uint32_t i = 0; i < gs_dyn_array_size(pip->layout); ++i)
  2279. {
  2280. // Vertex buffer to bind
  2281. uint32_t vbo_idx = i; //pip->layout[i].buffer_idx;
  2282. gsgl_vertex_buffer_decl_t vdecl = vbo_idx < gs_dyn_array_size(ogl->cache.vdecls) ? ogl->cache.vdecls[vbo_idx] : ogl->cache.vdecls[0];
  2283. gsgl_buffer_t vbo = vdecl.vbo;
  2284. // Manual override. If you manually set divisor/stride/offset, then will not automatically calculate any of those.
  2285. bool is_manual = pip->layout[i].stride | pip->layout[i].divisor | pip->layout[i].offset | (vdecl.data_type == GS_GRAPHICS_VERTEX_DATA_NONINTERLEAVED);
  2286. // Bind buffer
  2287. glBindBuffer(GL_ARRAY_BUFFER, vbo);
  2288. // Stride of vertex attribute
  2289. size_t stride = is_manual ? pip->layout[i].stride :
  2290. gsgl_calculate_vertex_size_in_bytes(pip->layout, gs_dyn_array_size(pip->layout));
  2291. // Byte offset of vertex attribute (if non-interleaved data, then grab offset from decl instead)
  2292. size_t offset = vdecl.data_type == GS_GRAPHICS_VERTEX_DATA_NONINTERLEAVED ? vdecl.offset : is_manual ? pip->layout[i].offset :
  2293. gsgl_get_vertex_attr_byte_offest(pip->layout, i);
  2294. // If there is a vertex divisor for this layout, then we'll draw instanced
  2295. is_instanced |= (pip->layout[i].divisor != 0);
  2296. // Enable the vertex attribute pointer
  2297. glEnableVertexAttribArray(i);
  2298. switch (pip->layout[i].format)
  2299. {
  2300. case GS_GRAPHICS_VERTEX_ATTRIBUTE_FLOAT4: glVertexAttribPointer(i, 4, GL_FLOAT, GL_FALSE, stride, gs_int2voidp(offset)); break;
  2301. case GS_GRAPHICS_VERTEX_ATTRIBUTE_FLOAT3: glVertexAttribPointer(i, 3, GL_FLOAT, GL_FALSE, stride, gs_int2voidp(offset)); break;
  2302. case GS_GRAPHICS_VERTEX_ATTRIBUTE_FLOAT2: glVertexAttribPointer(i, 2, GL_FLOAT, GL_FALSE, stride, gs_int2voidp(offset)); break;
  2303. case GS_GRAPHICS_VERTEX_ATTRIBUTE_FLOAT: glVertexAttribPointer(i, 1, GL_FLOAT, GL_FALSE, stride, gs_int2voidp(offset)); break;
  2304. case GS_GRAPHICS_VERTEX_ATTRIBUTE_UINT4: glVertexAttribIPointer(i, 4, GL_UNSIGNED_INT, stride, gs_int2voidp(offset)); break;
  2305. case GS_GRAPHICS_VERTEX_ATTRIBUTE_UINT3: glVertexAttribIPointer(i, 3, GL_UNSIGNED_INT, stride, gs_int2voidp(offset)); break;
  2306. case GS_GRAPHICS_VERTEX_ATTRIBUTE_UINT2: glVertexAttribIPointer(i, 2, GL_UNSIGNED_INT, stride, gs_int2voidp(offset)); break;
  2307. case GS_GRAPHICS_VERTEX_ATTRIBUTE_UINT: glVertexAttribIPointer(i, 1, GL_UNSIGNED_INT, stride, gs_int2voidp(offset)); break;
  2308. case GS_GRAPHICS_VERTEX_ATTRIBUTE_BYTE: glVertexAttribPointer(i, 1, GL_UNSIGNED_BYTE, GL_TRUE, stride, gs_int2voidp(offset)); break;
  2309. case GS_GRAPHICS_VERTEX_ATTRIBUTE_BYTE2: glVertexAttribPointer(i, 2, GL_UNSIGNED_BYTE, GL_TRUE, stride, gs_int2voidp(offset)); break;
  2310. case GS_GRAPHICS_VERTEX_ATTRIBUTE_BYTE3: glVertexAttribPointer(i, 3, GL_UNSIGNED_BYTE, GL_TRUE, stride, gs_int2voidp(offset)); break;
  2311. case GS_GRAPHICS_VERTEX_ATTRIBUTE_BYTE4: glVertexAttribPointer(i, 4, GL_UNSIGNED_BYTE, GL_TRUE, stride, gs_int2voidp(offset)); break;
  2312. // Shouldn't get here
  2313. default: {
  2314. gs_assert(false);
  2315. } break;
  2316. }
  2317. // Set up divisor (for instancing)
  2318. glVertexAttribDivisor(i, pip->layout[i].divisor);
  2319. glBindBuffer(GL_ARRAY_BUFFER, 0);
  2320. }
  2321. // Bind all vertex buffers after setting up data and pointers
  2322. for (uint32_t i = 0; i < gs_dyn_array_size(ogl->cache.vdecls); ++i) {
  2323. glBindBuffer(GL_ARRAY_BUFFER, ogl->cache.vdecls[i].vbo);
  2324. }
  2325. // Draw based on bound primitive type in raster
  2326. gs_byte_buffer_readc(&cb->commands, uint32_t, start);
  2327. gs_byte_buffer_readc(&cb->commands, uint32_t, count);
  2328. gs_byte_buffer_readc(&cb->commands, uint32_t, instance_count);
  2329. gs_byte_buffer_readc(&cb->commands, uint32_t, base_vertex);
  2330. gs_byte_buffer_readc(&cb->commands, uint32_t, range_start);
  2331. gs_byte_buffer_readc(&cb->commands, uint32_t, range_end);
  2332. range_end = (range_end && range_end > range_start) ? range_end : start + count;
  2333. // Bind element buffer ranged
  2334. if (ogl->cache.ibo) {
  2335. glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, gs_slot_array_get(ogl->index_buffers, ogl->cache.ibo));
  2336. }
  2337. // If instance count > 1, do instanced drawing
  2338. is_instanced |= (instance_count > 1);
  2339. uint32_t prim = gsgl_primitive_to_gl_primitive(pip->raster.primitive);
  2340. uint32_t itype = gsgl_index_buffer_size_to_gl_index_type(pip->raster.index_buffer_element_size);
  2341. // Draw
  2342. if (ogl->cache.ibo) {
  2343. #ifdef GS_GRAPHICS_IMPL_OPENGL_CORE
  2344. if (is_instanced) glDrawElementsInstancedBaseVertex(prim, count, itype, gs_int2voidp(start), instance_count, base_vertex);
  2345. else glDrawRangeElementsBaseVertex(prim, range_start, range_end, count, itype, gs_int2voidp(start), base_vertex);
  2346. #else
  2347. if (is_instanced) glDrawElementsInstanced(prim, count, itype, gs_int2voidp(start), instance_count);
  2348. else glDrawElements(prim, count, itype, gs_int2voidp(start));
  2349. #endif
  2350. }
  2351. else {
  2352. if (is_instanced) glDrawArraysInstanced(prim, start, count, instance_count);
  2353. else glDrawArrays(prim, start, count);
  2354. }
  2355. } break;
  2356. case GS_OPENGL_OP_REQUEST_TEXTURE_UPDATE:
  2357. {
  2358. gs_byte_buffer_readc(&cb->commands, uint32_t, tex_slot_id);
  2359. gs_byte_buffer_readc(&cb->commands, gs_graphics_texture_desc_t, desc);
  2360. gs_byte_buffer_readc(&cb->commands, size_t, data_size);
  2361. // Update texture with data, depending on update type (for now, just stream new data)
  2362. // Grab texture from sampler id
  2363. if (!tex_slot_id || !gs_slot_array_exists(ogl->textures, tex_slot_id)) {
  2364. gs_timed_action(60, {
  2365. gs_println("Warning:Bind Image Buffer:Texture %d does not exist.", tex_slot_id);
  2366. });
  2367. gs_byte_buffer_advance_position(&cb->commands, data_size);
  2368. }
  2369. gsgl_texture_t* tex = gs_slot_array_getp(ogl->textures, tex_slot_id);
  2370. uint32_t int_format = gsgl_texture_format_to_gl_texture_internal_format(desc.format);
  2371. uint32_t format = gsgl_texture_format_to_gl_texture_format(desc.format);
  2372. uint32_t dt = gsgl_texture_format_to_gl_data_type(desc.format);
  2373. *desc.data = (cb->commands.data + cb->commands.position);
  2374. *tex = gl_texture_update_internal(&desc, tex_slot_id);
  2375. // Bind texture
  2376. // glBindTexture(GL_TEXTURE_2D, tex->id);
  2377. // // Update texture data
  2378. // // glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, desc.width, desc.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, (cb->commands.data, cb->commands.position));
  2379. // // glTexImage2D(GL_TEXTURE_2D, 0, int_format, desc.width, desc.height, 0, format, dt, (cb->commands.data, cb->commands.position));
  2380. // glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, desc.width, desc.height, format, dt, (cb->commands.data + cb->commands.position));
  2381. // glBindTexture(GL_TEXTURE_2D, 0);
  2382. gs_byte_buffer_advance_position(&cb->commands, data_size);
  2383. } break;
  2384. case GS_OPENGL_OP_REQUEST_BUFFER_UPDATE:
  2385. {
  2386. gsgl_data_t* ogl = (gsgl_data_t*)gs_subsystem(graphics)->user_data;
  2387. // Read handle id
  2388. gs_byte_buffer_readc(&cb->commands, uint32_t, id);
  2389. // Read type
  2390. gs_byte_buffer_readc(&cb->commands, gs_graphics_buffer_type, type);
  2391. // Read usage
  2392. gs_byte_buffer_readc(&cb->commands, gs_graphics_buffer_usage_type, usage);
  2393. // Read data size
  2394. gs_byte_buffer_readc(&cb->commands, size_t, sz);
  2395. // Read data offset
  2396. gs_byte_buffer_readc(&cb->commands, size_t, offset);
  2397. // Read update type
  2398. gs_byte_buffer_readc(&cb->commands, gs_graphics_buffer_update_type, update_type);
  2399. int32_t glusage = gsgl_buffer_usage_to_gl_enum(usage);
  2400. switch (type)
  2401. {
  2402. // Vertex Buffer
  2403. default:
  2404. case GS_GRAPHICS_BUFFER_VERTEX:
  2405. {
  2406. gsgl_buffer_t buffer = gs_slot_array_get(ogl->vertex_buffers, id);
  2407. glBindBuffer(GL_ARRAY_BUFFER, buffer);
  2408. switch (update_type) {
  2409. case GS_GRAPHICS_BUFFER_UPDATE_SUBDATA: glBufferSubData(GL_ARRAY_BUFFER, offset, sz, (cb->commands.data + cb->commands.position)); break;
  2410. default: glBufferData(GL_ARRAY_BUFFER, sz, (cb->commands.data + cb->commands.position), glusage); break;
  2411. }
  2412. glBindBuffer(GL_ARRAY_BUFFER, 0);
  2413. } break;
  2414. case GS_GRAPHICS_BUFFER_INDEX:
  2415. {
  2416. gsgl_buffer_t buffer = gs_slot_array_get(ogl->index_buffers, id);
  2417. glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer);
  2418. switch (update_type) {
  2419. case GS_GRAPHICS_BUFFER_UPDATE_SUBDATA: glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, offset, sz, (cb->commands.data + cb->commands.position)); break;
  2420. default: glBufferData(GL_ELEMENT_ARRAY_BUFFER, sz, (cb->commands.data + cb->commands.position), glusage); break;
  2421. }
  2422. glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
  2423. } break;
  2424. case GS_GRAPHICS_BUFFER_UNIFORM:
  2425. {
  2426. // Have to
  2427. gsgl_uniform_buffer_t* u = gs_slot_array_getp(ogl->uniform_buffers, id);
  2428. glBindBuffer(GL_UNIFORM_BUFFER, u->ubo);
  2429. switch (update_type) {
  2430. case GS_GRAPHICS_BUFFER_UPDATE_SUBDATA: {
  2431. glBufferSubData(GL_UNIFORM_BUFFER, offset, sz, (cb->commands.data + cb->commands.position));
  2432. } break;
  2433. default: {
  2434. // Reset uniform size
  2435. u->size = sz;
  2436. // Recreate buffer
  2437. glBufferData(GL_UNIFORM_BUFFER, sz, (cb->commands.data + cb->commands.position), glusage);
  2438. } break;
  2439. }
  2440. glBindBuffer(GL_UNIFORM_BUFFER, 0);
  2441. } break;
  2442. case GS_GRAPHICS_BUFFER_SHADER_STORAGE:
  2443. {
  2444. gs_graphics_storage_buffer_desc_t desc = {
  2445. .data = cb->commands.data + cb->commands.position,
  2446. .size = sz,
  2447. .usage = usage,
  2448. .update = {
  2449. .type = update_type,
  2450. .offset = offset,
  2451. },
  2452. };
  2453. gs_handle(gs_graphics_storage_buffer_t) hndl;
  2454. hndl.id = id;
  2455. gs_graphics_storage_buffer_update(hndl, &desc);
  2456. } break;
  2457. }
  2458. // Advance past data
  2459. gs_byte_buffer_advance_position(&cb->commands, sz);
  2460. } break;
  2461. default:
  2462. {
  2463. // Op code not supported yet!
  2464. gs_println("Op code not supported yet: %zu", (uint32_t)op_code);
  2465. gs_assert(false);
  2466. }
  2467. }
  2468. }
  2469. // Clear byte buffer of commands
  2470. gs_byte_buffer_clear(&cb->commands);
  2471. // Set num commands to 0
  2472. cb->num_commands = 0;
  2473. }
  2474. GS_API_DECL void
  2475. gs_graphics_init(gs_graphics_t* graphics)
  2476. {
  2477. // Push back 0 handles into slot arrays (for 0 init validation)
  2478. gsgl_data_t* ogl = (gsgl_data_t*)graphics->user_data;
  2479. gs_slot_array_insert(ogl->shaders, 0);
  2480. gs_slot_array_insert(ogl->vertex_buffers, 0);
  2481. gs_slot_array_insert(ogl->index_buffers, 0);
  2482. gs_slot_array_insert(ogl->frame_buffers, 0);
  2483. gsgl_uniform_list_t ul = gs_default_val();
  2484. gsgl_uniform_buffer_t ub = gs_default_val();
  2485. gsgl_pipeline_t pip = gs_default_val();
  2486. gsgl_renderpass_t rp = gs_default_val();
  2487. gsgl_texture_t tex = gs_default_val();
  2488. gsgl_storage_buffer_t sb = gs_default_val();
  2489. gs_slot_array_insert(ogl->uniforms, ul);
  2490. gs_slot_array_insert(ogl->pipelines, pip);
  2491. gs_slot_array_insert(ogl->renderpasses, rp);
  2492. gs_slot_array_insert(ogl->uniform_buffers, ub);
  2493. gs_slot_array_insert(ogl->textures, tex);
  2494. gs_slot_array_insert(ogl->storage_buffers, sb);
  2495. // Construct vao then bind
  2496. glGenVertexArrays(1, &ogl->cache.vao);
  2497. glBindVertexArray(ogl->cache.vao);
  2498. // Reset data cache for rendering ops
  2499. gsgl_reset_data_cache(&ogl->cache);
  2500. // Init info object
  2501. gs_graphics_info_t* info = &gs_subsystem(graphics)->info;
  2502. // Major/Minor version
  2503. glGetIntegerv(GL_MAJOR_VERSION, (GLint*)&info->major_version);
  2504. glGetIntegerv(GL_MINOR_VERSION, (GLint*)&info->minor_version);
  2505. // Max texture units
  2506. glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, (GLint*)&info->max_texture_units);
  2507. // Compute shader info
  2508. CHECK_GL_CORE(
  2509. info->compute.available = info->major_version >= 4 && info->minor_version >= 3;
  2510. if (info->compute.available) {
  2511. // Work group counts
  2512. glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_COUNT, 0, (int32_t*)&info->compute.max_work_group_count[0]);
  2513. glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_COUNT, 1, (int32_t*)&info->compute.max_work_group_count[1]);
  2514. glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_COUNT, 2, (int32_t*)&info->compute.max_work_group_count[2]);
  2515. // Work group sizes
  2516. glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_SIZE, 0, (int32_t*)&info->compute.max_work_group_size[0]);
  2517. glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_SIZE, 1, (int32_t*)&info->compute.max_work_group_size[1]);
  2518. glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_SIZE, 2, (int32_t*)&info->compute.max_work_group_size[2]);
  2519. // Work group invocations
  2520. glGetIntegerv(GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS, (int32_t*)&info->compute.max_work_group_invocations);
  2521. }
  2522. glGetIntegerv(GL_MAX_SHADER_STORAGE_BLOCK_SIZE, (int32_t*)&info->max_ssbo_block_size);
  2523. )
  2524. const GLubyte* glslv = glGetString(GL_SHADING_LANGUAGE_VERSION);
  2525. gs_println("GLSL Version: %s", glslv);
  2526. // Set up all function pointers for graphics context
  2527. // Create
  2528. graphics->api.texture_create = gs_graphics_texture_create_impl;
  2529. graphics->api.uniform_create = gs_graphics_uniform_create_impl;
  2530. graphics->api.shader_create = gs_graphics_shader_create_impl;
  2531. graphics->api.vertex_buffer_create = gs_graphics_vertex_buffer_create_impl;
  2532. graphics->api.index_buffer_create = gs_graphics_index_buffer_create_impl;
  2533. graphics->api.uniform_buffer_create = gs_graphics_uniform_buffer_create_impl;
  2534. graphics->api.storage_buffer_create = gs_graphics_storage_buffer_create_impl;
  2535. graphics->api.framebuffer_create = gs_graphics_framebuffer_create_impl;
  2536. graphics->api.renderpass_create = gs_graphics_renderpass_create_impl;
  2537. graphics->api.pipeline_create = gs_graphics_pipeline_create_impl;
  2538. // Destroy
  2539. graphics->api.texture_destroy = gs_graphics_texture_destroy_impl;
  2540. graphics->api.uniform_destroy = gs_graphics_uniform_destroy_impl;
  2541. graphics->api.shader_destroy = gs_graphics_shader_destroy_impl;
  2542. graphics->api.vertex_buffer_destroy = gs_graphics_vertex_buffer_destroy_impl;
  2543. graphics->api.index_buffer_destroy = gs_graphics_index_buffer_destroy_impl;
  2544. graphics->api.uniform_buffer_destroy = gs_graphics_uniform_buffer_destroy_impl;
  2545. graphics->api.storage_buffer_destroy = gs_graphics_storage_buffer_destroy_impl;
  2546. graphics->api.framebuffer_destroy = gs_graphics_framebuffer_destroy_impl;
  2547. graphics->api.renderpass_destroy = gs_graphics_renderpass_destroy_impl;
  2548. graphics->api.pipeline_destroy = gs_graphics_pipeline_destroy_impl;
  2549. // Resource Updates (main thread only)
  2550. graphics->api.vertex_buffer_update = gs_graphics_vertex_buffer_update_impl;
  2551. graphics->api.index_buffer_update = gs_graphics_index_buffer_update_impl;
  2552. graphics->api.storage_buffer_update = gs_graphics_storage_buffer_update_impl;
  2553. graphics->api.texture_update = gs_graphics_texture_update_impl;
  2554. graphics->api.texture_read = gs_graphics_texture_read_impl;
  2555. // Util
  2556. graphics->api.storage_buffer_map_get = gs_graphics_storage_buffer_map_get_impl;
  2557. graphics->api.storage_buffer_lock = gs_grapics_storage_buffer_lock_impl;
  2558. graphics->api.storage_buffer_unlock = gs_grapics_storage_buffer_unlock_impl;
  2559. graphics->api.storage_buffer_get_data = gs_storage_buffer_get_data_impl;
  2560. // Submission (Main Thread)
  2561. graphics->api.command_buffer_submit = gs_graphics_command_buffer_submit_impl;
  2562. // Enable debug output
  2563. glEnable(GL_DEBUG_OUTPUT);
  2564. // glDebugMessageCallback(gsgl_message_cb, 0);
  2565. }
  2566. #endif // GS_GRAPHICS_IMPL_OPENGL
  2567. #endif // GS_GRAPHICS_IMPL_H