renderer_gl.cpp 73 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667
  1. /*
  2. * Copyright 2011-2012 Branimir Karadzic. All rights reserved.
  3. * License: http://www.opensource.org/licenses/BSD-2-Clause
  4. */
  5. #include "bgfx_p.h"
  6. #if (BGFX_CONFIG_RENDERER_OPENGLES2|BGFX_CONFIG_RENDERER_OPENGL)
  7. # include "renderer_gl.h"
  8. # include <bx/timer.h>
  9. # include <bx/uint32_t.h>
  10. #if BGFX_CONFIG_RENDERER_OPENGL
  11. # define glClearDepthf(_depth) glClearDepth(_depth)
  12. #endif // BGFX_CONFIG_RENDERER_OPENGL
  13. namespace bgfx
  14. {
  15. #if BGFX_USE_WGL
  16. PFNWGLGETPROCADDRESSPROC wglGetProcAddress;
  17. PFNWGLMAKECURRENTPROC wglMakeCurrent;
  18. PFNWGLCREATECONTEXTPROC wglCreateContext;
  19. PFNWGLDELETECONTEXTPROC wglDeleteContext;
  20. #endif // BGFX_USE_WGL
  21. #define GL_IMPORT(_optional, _proto, _func) _proto _func
  22. #include "glimports.h"
  23. #undef GL_IMPORT
  24. static void GL_APIENTRY stubVertexAttribDivisor(GLuint /*_index*/, GLuint /*_divisor*/)
  25. {
  26. }
  27. static void GL_APIENTRY stubDrawArraysInstanced(GLenum _mode, GLint _first, GLsizei _count, GLsizei /*_primcount*/)
  28. {
  29. glDrawArrays(_mode, _first, _count);
  30. }
  31. static void GL_APIENTRY stubDrawElementsInstanced(GLenum _mode, GLsizei _count, GLenum _type, const GLvoid* _indices, GLsizei /*_primcount*/)
  32. {
  33. glDrawElements(_mode, _count, _type, _indices);
  34. }
  35. static PFNGLVERTEXATTRIBDIVISORBGFXPROC s_vertexAttribDivisor = stubVertexAttribDivisor;
  36. static PFNGLDRAWARRAYSINSTANCEDBGFXPROC s_drawArraysInstanced = stubDrawArraysInstanced;
  37. static PFNGLDRAWELEMENTSINSTANCEDBGFXPROC s_drawElementsInstanced = stubDrawElementsInstanced;
  38. typedef void (*PostSwapBuffersFn)(uint32_t _width, uint32_t _height);
  39. #if BX_PLATFORM_NACL
  40. void naclSwapCompleteCb(void* _data, int32_t _result);
  41. PP_CompletionCallback naclSwapComplete =
  42. {
  43. naclSwapCompleteCb,
  44. NULL,
  45. PP_COMPLETIONCALLBACK_FLAG_NONE
  46. };
  47. #endif // BX_PLATFORM_NACL
  48. struct RendererContext
  49. {
  50. RendererContext()
  51. : m_dxtSupport(false)
  52. , m_flip(false)
  53. , m_postSwapBuffers(NULL)
  54. , m_hash( (BX_PLATFORM_WINDOWS<<1) | BX_ARCH_64BIT)
  55. #if BX_PLATFORM_NACL
  56. , m_context(0)
  57. , m_instance(0)
  58. , m_instInterface(NULL)
  59. , m_graphicsInterface(NULL)
  60. #elif BGFX_USE_WGL
  61. , m_context(NULL)
  62. , m_hdc(NULL)
  63. #elif BGFX_USE_EGL
  64. , m_context(NULL)
  65. , m_display(NULL)
  66. , m_surface(NULL)
  67. #elif BX_PLATFORM_LINUX
  68. , m_context(0)
  69. , m_window(0)
  70. , m_display(NULL)
  71. #endif // BX_PLATFORM_
  72. {
  73. memset(&m_resolution, 0, sizeof(m_resolution) );
  74. }
  75. void updateResolution(const Resolution& _resolution)
  76. {
  77. if (m_resolution.m_width != _resolution.m_width
  78. || m_resolution.m_height != _resolution.m_height
  79. || m_resolution.m_flags != _resolution.m_flags)
  80. {
  81. m_textVideoMem.resize(false, _resolution.m_width, _resolution.m_height);
  82. m_textVideoMem.clear();
  83. m_resolution = _resolution;
  84. setRenderContextSize(_resolution.m_width, _resolution.m_height);
  85. }
  86. }
  87. void setRenderContextSize(uint32_t _width, uint32_t _height)
  88. {
  89. if (_width != 0
  90. || _height != 0)
  91. {
  92. #if BX_PLATFORM_NACL
  93. if (0 == m_context)
  94. {
  95. BX_TRACE("create context");
  96. int32_t attribs[] =
  97. {
  98. PP_GRAPHICS3DATTRIB_ALPHA_SIZE, 8,
  99. PP_GRAPHICS3DATTRIB_DEPTH_SIZE, 24,
  100. PP_GRAPHICS3DATTRIB_STENCIL_SIZE, 8,
  101. PP_GRAPHICS3DATTRIB_SAMPLES, 0,
  102. PP_GRAPHICS3DATTRIB_SAMPLE_BUFFERS, 0,
  103. PP_GRAPHICS3DATTRIB_WIDTH, _width,
  104. PP_GRAPHICS3DATTRIB_HEIGHT, _height,
  105. PP_GRAPHICS3DATTRIB_NONE
  106. };
  107. m_context = m_graphicsInterface->Create(m_instance, 0, attribs);
  108. m_instInterface->BindGraphics(m_instance, m_context);
  109. glSetCurrentContextPPAPI(m_context);
  110. m_graphicsInterface->SwapBuffers(m_context, naclSwapComplete);
  111. #if 0
  112. # define GL_IMPORT(_optional, _proto, _func) \
  113. { \
  114. _func = (_proto)eglGetProcAddress(#_func); \
  115. BGFX_FATAL(_optional || NULL != _func, Fatal::OPENGL_UnableToCreateContext, "Failed to create OpenGL context. eglGetProcAddress(\"%s\")", #_func); \
  116. }
  117. # include "glimports.h"
  118. # undef GL_IMPORT
  119. #endif
  120. }
  121. else
  122. {
  123. m_graphicsInterface->ResizeBuffers(m_context, _width, _height);
  124. }
  125. #elif BGFX_USE_WGL
  126. if (NULL == m_hdc)
  127. {
  128. m_opengl32dll = LoadLibrary("opengl32.dll");
  129. BGFX_FATAL(NULL != m_opengl32dll, Fatal::OPENGL_UnableToCreateContext, "Failed to load opengl32.dll.");
  130. wglGetProcAddress = (PFNWGLGETPROCADDRESSPROC)GetProcAddress(m_opengl32dll, "wglGetProcAddress");
  131. BGFX_FATAL(NULL != wglGetProcAddress, Fatal::OPENGL_UnableToCreateContext, "Failed get wglGetProcAddress.");
  132. wglMakeCurrent = (PFNWGLMAKECURRENTPROC)GetProcAddress(m_opengl32dll, "wglMakeCurrent");
  133. BGFX_FATAL(NULL != wglMakeCurrent, Fatal::OPENGL_UnableToCreateContext, "Failed get wglMakeCurrent.");
  134. wglCreateContext = (PFNWGLCREATECONTEXTPROC)GetProcAddress(m_opengl32dll, "wglCreateContext");
  135. BGFX_FATAL(NULL != wglCreateContext, Fatal::OPENGL_UnableToCreateContext, "Failed get wglCreateContext.");
  136. wglDeleteContext = (PFNWGLDELETECONTEXTPROC)GetProcAddress(m_opengl32dll, "wglDeleteContext");
  137. BGFX_FATAL(NULL != wglDeleteContext, Fatal::OPENGL_UnableToCreateContext, "Failed get wglDeleteContext.");
  138. m_hdc = GetDC(g_bgfxHwnd);
  139. BGFX_FATAL(NULL != m_hdc, Fatal::OPENGL_UnableToCreateContext, "GetDC failed!");
  140. PIXELFORMATDESCRIPTOR pfd;
  141. memset(&pfd, 0, sizeof(pfd) );
  142. pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
  143. pfd.nVersion = 1;
  144. pfd.iPixelType = PFD_TYPE_RGBA;
  145. pfd.cColorBits = 32;
  146. pfd.cAlphaBits = 8;
  147. pfd.cDepthBits = 24;
  148. pfd.cStencilBits = 8;
  149. pfd.iLayerType = PFD_MAIN_PLANE;
  150. int pixelFormat = ChoosePixelFormat(m_hdc, &pfd);
  151. BGFX_FATAL(0 != pixelFormat, Fatal::OPENGL_UnableToCreateContext, "ChoosePixelFormat failed!");
  152. DescribePixelFormat(m_hdc, pixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &pfd);
  153. int result;
  154. result = SetPixelFormat(m_hdc, pixelFormat, &pfd);
  155. BGFX_FATAL(0 != result, Fatal::OPENGL_UnableToCreateContext, "SetPixelFormat failed!");
  156. m_context = wglCreateContext(m_hdc);
  157. BGFX_FATAL(NULL != m_context, Fatal::OPENGL_UnableToCreateContext, "wglCreateContext failed!");
  158. result = wglMakeCurrent(m_hdc, m_context);
  159. BGFX_FATAL(0 != result, Fatal::OPENGL_UnableToCreateContext, "wglMakeCurrent failed!");
  160. # define GL_IMPORT(_optional, _proto, _func) \
  161. { \
  162. _func = (_proto)wglGetProcAddress(#_func); \
  163. if (_func == NULL) \
  164. { \
  165. _func = (_proto)GetProcAddress(m_opengl32dll, #_func); \
  166. } \
  167. BGFX_FATAL(_optional || NULL != _func, Fatal::OPENGL_UnableToCreateContext, "Failed to create OpenGL context. wglGetProcAddress(\"%s\")", #_func); \
  168. }
  169. # include "glimports.h"
  170. # undef GL_IMPORT
  171. }
  172. #elif BX_PLATFORM_LINUX
  173. if (0 == m_display)
  174. {
  175. Display* display = XOpenDisplay(0);
  176. XLockDisplay(display);
  177. BGFX_FATAL(display, Fatal::OPENGL_UnableToCreateContext, "Failed to open X display (0).");
  178. int glxMajor, glxMinor;
  179. if (!glXQueryVersion(display, &glxMajor, &glxMinor))
  180. {
  181. BGFX_FATAL(false, Fatal::OPENGL_UnableToCreateContext, "Failed to query GLX version");
  182. }
  183. BGFX_FATAL((glxMajor == 1 && glxMinor >= 3) || glxMajor > 1, Fatal::OPENGL_UnableToCreateContext, "GLX version is not >=1.3 (%d.%d).", glxMajor, glxMinor);
  184. const int glxAttribs[] =
  185. {
  186. GLX_X_RENDERABLE, True,
  187. GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT,
  188. GLX_RENDER_TYPE, GLX_RGBA_BIT,
  189. GLX_X_VISUAL_TYPE, GLX_TRUE_COLOR,
  190. GLX_RED_SIZE, 8,
  191. GLX_BLUE_SIZE, 8,
  192. GLX_GREEN_SIZE, 8,
  193. GLX_ALPHA_SIZE, 8,
  194. GLX_DEPTH_SIZE, 24,
  195. GLX_STENCIL_SIZE, 8,
  196. GLX_DOUBLEBUFFER, True,
  197. None,
  198. };
  199. // Find suitable config
  200. GLXFBConfig bestconfig = NULL;
  201. int nconfigs;
  202. GLXFBConfig* configs = glXChooseFBConfig(display, DefaultScreen(display), glxAttribs, &nconfigs);
  203. XVisualInfo* visualInfo = 0;
  204. for (int ii = 0; ii < nconfigs; ++ii)
  205. {
  206. visualInfo = glXGetVisualFromFBConfig(display, configs[ii]);
  207. if (visualInfo)
  208. {
  209. // Check if meets min spec
  210. bool validconfig = true;
  211. for (uint32_t attridx = 0; attridx < countof(glxAttribs)-1 && glxAttribs[attridx] != None; attridx += 2)
  212. {
  213. int value;
  214. glXGetFBConfigAttrib(display, configs[ii], glxAttribs[attridx], &value);
  215. if (value < glxAttribs[attridx + 1])
  216. {
  217. validconfig = false;
  218. break;
  219. }
  220. }
  221. if (validconfig)
  222. {
  223. bestconfig = configs[ii];
  224. break;
  225. }
  226. }
  227. XFree(visualInfo);
  228. visualInfo = 0;
  229. }
  230. XFree(configs);
  231. BGFX_FATAL(visualInfo, Fatal::OPENGL_UnableToCreateContext, "Failed to find a suitable X11 display configuration.");
  232. // Generate colormaps
  233. XSetWindowAttributes windowAttrs;
  234. windowAttrs.colormap = XCreateColormap(display, RootWindow(display, visualInfo->screen), visualInfo->visual, AllocNone);
  235. windowAttrs.background_pixmap = None;
  236. windowAttrs.border_pixel = 0;
  237. Window window = XCreateWindow(
  238. display
  239. , RootWindow(display, visualInfo->screen)
  240. , 0, 0
  241. , _width, _height, 0, visualInfo->depth
  242. , InputOutput
  243. , visualInfo->visual
  244. , CWBorderPixel|CWColormap
  245. , &windowAttrs
  246. );
  247. BGFX_FATAL(window, Fatal::OPENGL_UnableToCreateContext, "Failed to create X11 window.");
  248. XMapRaised(display, window);
  249. XFlush(display);
  250. XFree(visualInfo);
  251. BX_TRACE("create context");
  252. typedef GLXContext (*glXCreateContextAttribsARBProc)(Display*, GLXFBConfig, GLXContext, Bool, const int*);
  253. glXCreateContextAttribsARBProc glXCreateContextAttribsARB = (glXCreateContextAttribsARBProc)glXGetProcAddress((const GLubyte*)"glXCreateContextAttribsARB");
  254. BGFX_FATAL(glXCreateContextAttribsARB, Fatal::OPENGL_UnableToCreateContext, "Failed to get glXCreateContextAttribsARB.");
  255. const int contextArrib[] =
  256. {
  257. GLX_CONTEXT_MAJOR_VERSION_ARB, 3,
  258. GLX_CONTEXT_MINOR_VERSION_ARB, 0,
  259. None,
  260. };
  261. m_context = glXCreateContextAttribsARB(display, bestconfig, 0, True, contextArrib);
  262. BGFX_FATAL(m_context, Fatal::OPENGL_UnableToCreateContext, "Failed to create GLX context.");
  263. glXMakeCurrent(display, window, m_context);
  264. # define GL_IMPORT(_optional, _proto, _func) \
  265. { \
  266. _func = (_proto)glXGetProcAddress((const GLubyte*)#_func); \
  267. BGFX_FATAL(_optional || NULL != _func, Fatal::OPENGL_UnableToCreateContext, "Failed to create OpenGL context. glXGetProcAddress %s", #_func); \
  268. }
  269. # include "glimports.h"
  270. # undef GL_IMPORT
  271. glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
  272. glClear(GL_COLOR_BUFFER_BIT);
  273. glXSwapBuffers(display, window);
  274. m_display = display;
  275. m_window = window;
  276. XUnlockDisplay(display);
  277. }
  278. else
  279. {
  280. XResizeWindow(m_display, m_window, _width, _height);
  281. }
  282. #elif BGFX_USE_EGL
  283. if (NULL == m_context)
  284. {
  285. m_display = eglGetDisplay(NULL);
  286. BGFX_FATAL(m_display != EGL_NO_DISPLAY, Fatal::OPENGL_UnableToCreateContext, "Failed to create display 0x%08x", m_display);
  287. EGLint major = 0;
  288. EGLint minor = 0;
  289. EGLBoolean success = eglInitialize(m_display, &major, &minor);
  290. BGFX_FATAL(success && major >= 1 && minor >= 4, Fatal::OPENGL_UnableToCreateContext, "Failed to initialize %d.%d", major, minor);
  291. EGLint attrs[] =
  292. {
  293. # if BX_PLATFORM_ANDROID
  294. EGL_DEPTH_SIZE, 16,
  295. # else
  296. EGL_DEPTH_SIZE, 24,
  297. # endif // BX_PLATFORM_
  298. EGL_NONE
  299. };
  300. EGLint numConfig = 0;
  301. EGLConfig config = 0;
  302. success = eglChooseConfig(m_display, attrs, &config, 1, &numConfig);
  303. BGFX_FATAL(success, Fatal::OPENGL_UnableToCreateContext, "eglChooseConfig");
  304. m_surface = eglCreateWindowSurface(m_display, config, (EGLNativeWindowType)g_bgfxHwnd, NULL);
  305. BGFX_FATAL(m_surface != EGL_NO_SURFACE, Fatal::OPENGL_UnableToCreateContext, "Failed to create surface.");
  306. m_context = eglCreateContext(m_display, config, EGL_NO_CONTEXT, NULL);
  307. BGFX_FATAL(m_context != EGL_NO_CONTEXT, Fatal::OPENGL_UnableToCreateContext, "Failed to create context.");
  308. success = eglMakeCurrent(m_display, m_surface, m_surface, m_context);
  309. BGFX_FATAL(success, Fatal::OPENGL_UnableToCreateContext, "Failed to set context.");
  310. # define GL_IMPORT(_optional, _proto, _func) \
  311. { \
  312. _func = (_proto)eglGetProcAddress(#_func); \
  313. BGFX_FATAL(_optional || NULL != _func, Fatal::OPENGL_UnableToCreateContext, "Failed to create OpenGLES context. eglGetProcAddress(\"%s\")", #_func); \
  314. }
  315. # include "glimports.h"
  316. # undef GL_IMPORT
  317. }
  318. #endif // BX_PLATFORM_
  319. }
  320. if (NULL != glVertexAttribDivisor
  321. && NULL != glDrawArraysInstanced
  322. && NULL != glDrawElementsInstanced)
  323. {
  324. s_vertexAttribDivisor = glVertexAttribDivisor;
  325. s_drawArraysInstanced = glDrawArraysInstanced;
  326. s_drawElementsInstanced = glDrawElementsInstanced;
  327. }
  328. else
  329. {
  330. s_vertexAttribDivisor = stubVertexAttribDivisor;
  331. s_drawArraysInstanced = stubDrawArraysInstanced;
  332. s_drawElementsInstanced = stubDrawElementsInstanced;
  333. }
  334. m_flip = true;
  335. }
  336. void flip()
  337. {
  338. if (m_flip)
  339. {
  340. #if BX_PLATFORM_NACL
  341. glSetCurrentContextPPAPI(m_context);
  342. m_graphicsInterface->SwapBuffers(m_context, naclSwapComplete);
  343. #elif BGFX_USE_WGL
  344. wglMakeCurrent(m_hdc, m_context);
  345. SwapBuffers(m_hdc);
  346. #elif BGFX_USE_EGL
  347. eglMakeCurrent(m_display, m_surface, m_surface, m_context);
  348. eglSwapBuffers(m_display, m_surface);
  349. #elif BX_PLATFORM_LINUX
  350. glXSwapBuffers(m_display, m_window);
  351. #endif // BX_PLATFORM_
  352. }
  353. if (NULL != m_postSwapBuffers)
  354. {
  355. m_postSwapBuffers(m_resolution.m_width, m_resolution.m_height);
  356. }
  357. }
  358. void saveScreenShot(Memory* _mem)
  359. {
  360. #if BGFX_CONFIG_RENDERER_OPENGL
  361. void* data = g_realloc(NULL, m_resolution.m_width*m_resolution.m_height*4);
  362. glReadPixels(0, 0, m_resolution.m_width, m_resolution.m_height, GL_RGBA, GL_UNSIGNED_BYTE, data);
  363. uint8_t* rgba = (uint8_t*)data;
  364. for (uint32_t ii = 0, num = m_resolution.m_width*m_resolution.m_height; ii < num; ++ii)
  365. {
  366. uint8_t temp = rgba[0];
  367. rgba[0] = rgba[2];
  368. rgba[2] = temp;
  369. rgba += 4;
  370. }
  371. saveTga( (const char*)_mem->data, m_resolution.m_width, m_resolution.m_height, m_resolution.m_width*4, data, false, true);
  372. g_free(data);
  373. #endif // BGFX_CONFIG_RENDERER_OPENGL
  374. }
  375. void init()
  376. {
  377. setRenderContextSize(BGFX_DEFAULT_WIDTH, BGFX_DEFAULT_HEIGHT);
  378. #if BGFX_CONFIG_RENDERER_OPENGL
  379. m_queries.create();
  380. #endif // BGFX_CONFIG_RENDERER_OPENGL
  381. }
  382. void shutdown()
  383. {
  384. #if BGFX_CONFIG_RENDERER_OPENGL
  385. m_queries.destroy();
  386. #endif // BGFX_CONFIG_RENDERER_OPENGL
  387. #if BGFX_USE_WGL
  388. if (NULL != m_hdc)
  389. {
  390. wglMakeCurrent(NULL, NULL);
  391. wglDeleteContext(m_context);
  392. m_context = NULL;
  393. }
  394. FreeLibrary(m_opengl32dll);
  395. #elif BGFX_USE_EGL
  396. eglMakeCurrent(EGL_NO_DISPLAY, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
  397. eglDestroyContext(m_display, m_context);
  398. eglDestroySurface(m_display, m_surface);
  399. eglTerminate(m_display);
  400. m_context = NULL;
  401. #endif // BGFX_USE_
  402. }
  403. IndexBuffer m_indexBuffers[BGFX_CONFIG_MAX_INDEX_BUFFERS];
  404. VertexBuffer m_vertexBuffers[BGFX_CONFIG_MAX_VERTEX_BUFFERS];
  405. Shader m_vertexShaders[BGFX_CONFIG_MAX_VERTEX_SHADERS];
  406. Shader m_fragmentShaders[BGFX_CONFIG_MAX_FRAGMENT_SHADERS];
  407. Material m_materials[BGFX_CONFIG_MAX_MATERIALS];
  408. Texture m_textures[BGFX_CONFIG_MAX_TEXTURES];
  409. VertexDecl m_vertexDecls[BGFX_CONFIG_MAX_VERTEX_DECLS];
  410. RenderTarget m_renderTargets[BGFX_CONFIG_MAX_RENDER_TARGETS];
  411. UniformRegistry m_uniformReg;
  412. void* m_uniforms[BGFX_CONFIG_MAX_UNIFORMS];
  413. #if BGFX_CONFIG_RENDERER_OPENGL
  414. Queries m_queries;
  415. #endif // BGFX_CONFIG_RENDERER_OPENGL
  416. TextVideoMem m_textVideoMem;
  417. Resolution m_resolution;
  418. bool m_dxtSupport;
  419. bool m_flip;
  420. PostSwapBuffersFn m_postSwapBuffers;
  421. uint64_t m_hash;
  422. #if BX_PLATFORM_NACL
  423. PP_Resource m_context;
  424. PP_Instance m_instance;
  425. const PPB_Instance* m_instInterface;
  426. const PPB_Graphics3D* m_graphicsInterface;
  427. #elif BGFX_USE_WGL
  428. HMODULE m_opengl32dll;
  429. HGLRC m_context;
  430. HDC m_hdc;
  431. #elif BGFX_USE_EGL
  432. EGLContext m_context;
  433. EGLDisplay m_display;
  434. EGLSurface m_surface;
  435. #elif BX_PLATFORM_LINUX
  436. GLXContext m_context;
  437. Window m_window;
  438. Display* m_display;
  439. #endif // BX_PLATFORM_NACL
  440. };
  441. RendererContext s_renderCtx;
  442. #if BX_PLATFORM_NACL
  443. void naclSetIntefraces(PP_Instance _instance, const PPB_Instance* _instInterface, const PPB_Graphics3D* _graphicsInterface, PostSwapBuffersFn _postSwapBuffers)
  444. {
  445. s_renderCtx.m_instance = _instance;
  446. s_renderCtx.m_instInterface = _instInterface;
  447. s_renderCtx.m_graphicsInterface = _graphicsInterface;
  448. s_renderCtx.m_postSwapBuffers = _postSwapBuffers;
  449. s_renderCtx.setRenderContextSize(BGFX_DEFAULT_WIDTH, BGFX_DEFAULT_HEIGHT);
  450. }
  451. void naclSwapCompleteCb(void* /*_data*/, int32_t /*_result*/)
  452. {
  453. renderFrame();
  454. }
  455. #elif BX_PLATFORM_LINUX
  456. bool linuxGetDisplay(Display** _display, Window* _window)
  457. {
  458. if (!s_renderCtx.m_display)
  459. {
  460. return false;
  461. }
  462. *_display = s_renderCtx.m_display;
  463. *_window = s_renderCtx.m_window;
  464. return true;
  465. }
  466. #endif // BX_PLATFORM_
  467. struct Extension
  468. {
  469. enum Enum
  470. {
  471. EXT_texture_format_BGRA8888,
  472. EXT_texture_compression_s3tc,
  473. EXT_texture_compression_dxt1,
  474. CHROMIUM_texture_compression_dxt3,
  475. CHROMIUM_texture_compression_dxt5,
  476. OES_standard_derivatives,
  477. ARB_get_program_binary,
  478. OES_get_program_binary,
  479. EXT_framebuffer_blit,
  480. ARB_timer_query,
  481. EXT_timer_query,
  482. EXT_texture_sRGB,
  483. ARB_framebuffer_sRGB,
  484. EXT_framebuffer_sRGB,
  485. ARB_multisample,
  486. CHROMIUM_framebuffer_multisample,
  487. ANGLE_translated_shader_source,
  488. ARB_instanced_arrays,
  489. ANGLE_instanced_arrays,
  490. OES_texture_float,
  491. OES_texture_float_linear,
  492. OES_texture_half_float,
  493. OES_texture_half_float_linear,
  494. EXT_occlusion_query_boolean,
  495. ATI_meminfo,
  496. NVX_gpu_memory_info,
  497. Count
  498. };
  499. const char* m_name;
  500. bool m_supported;
  501. bool m_initialize;
  502. };
  503. static Extension s_extension[Extension::Count] =
  504. {
  505. // Nvidia BGRA on Linux bug:
  506. // https://groups.google.com/a/chromium.org/forum/?fromgroups#!topic/chromium-reviews/yFfbUdyeUCQ
  507. { "GL_EXT_texture_format_BGRA8888", false, !BX_PLATFORM_LINUX },
  508. { "GL_EXT_texture_compression_s3tc", false, true },
  509. { "GL_EXT_texture_compression_dxt1", false, true },
  510. { "GL_CHROMIUM_texture_compression_dxt3", false, true },
  511. { "GL_CHROMIUM_texture_compression_dxt5", false, true },
  512. { "GL_OES_standard_derivatives", false, true },
  513. { "GL_ARB_get_program_binary", false, true },
  514. { "GL_OES_get_program_binary", false, false },
  515. { "GL_EXT_framebuffer_blit", false, true },
  516. { "GL_ARB_timer_query", false, true },
  517. { "GL_EXT_timer_query", false, true },
  518. { "GL_EXT_texture_sRGB", false, true },
  519. { "GL_ARB_framebuffer_sRGB", false, true },
  520. { "GL_EXT_framebuffer_sRGB", false, true },
  521. { "GL_ARB_multisample", false, true },
  522. { "GL_CHROMIUM_framebuffer_multisample", false, true },
  523. { "GL_ANGLE_translated_shader_source", false, true },
  524. { "GL_ARB_instanced_arrays", false, true },
  525. { "GL_ANGLE_instanced_arrays", false, true },
  526. { "GL_OES_texture_float", false, true },
  527. { "GL_OES_texture_float_linear", false, true },
  528. { "GL_OES_texture_half_float", false, true },
  529. { "GL_OES_texture_half_float_linear", false, true },
  530. { "GL_EXT_occlusion_query_boolean", false, true },
  531. { "GL_ATI_meminfo", false, true },
  532. { "GL_NVX_gpu_memory_info", false, true },
  533. };
  534. static const GLenum s_primType[] =
  535. {
  536. GL_TRIANGLES,
  537. GL_LINES,
  538. GL_POINTS,
  539. };
  540. static const uint32_t s_primNumVerts[] =
  541. {
  542. 3,
  543. 2,
  544. 1,
  545. };
  546. static const char* s_attribName[Attrib::Count] =
  547. {
  548. "a_position",
  549. "a_normal",
  550. "a_color",
  551. "a_color1",
  552. "a_indices",
  553. "a_weight",
  554. "a_texcoord0",
  555. "a_texcoord1",
  556. "a_texcoord2",
  557. "a_texcoord3",
  558. "a_texcoord4",
  559. "a_texcoord5",
  560. "a_texcoord6",
  561. "a_texcoord7",
  562. };
  563. static const char* s_instanceDataName[BGFX_CONFIG_MAX_INSTANCE_DATA_COUNT] =
  564. {
  565. "i_data0",
  566. "i_data1",
  567. "i_data2",
  568. "i_data3",
  569. "i_data4",
  570. };
  571. static const GLenum s_attribType[AttribType::Count] =
  572. {
  573. GL_UNSIGNED_BYTE,
  574. GL_UNSIGNED_SHORT,
  575. GL_FLOAT,
  576. };
  577. static const GLenum s_blendFactor[][2] =
  578. {
  579. { 0, 0 }, // ignored
  580. { GL_ZERO, GL_ZERO },
  581. { GL_ONE, GL_ONE },
  582. { GL_SRC_COLOR, GL_SRC_COLOR },
  583. { GL_ONE_MINUS_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR },
  584. { GL_SRC_ALPHA, GL_SRC_ALPHA },
  585. { GL_ONE_MINUS_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA },
  586. { GL_DST_ALPHA, GL_DST_ALPHA },
  587. { GL_ONE_MINUS_DST_ALPHA, GL_ONE_MINUS_DST_ALPHA },
  588. { GL_DST_COLOR, GL_DST_COLOR },
  589. { GL_ONE_MINUS_DST_COLOR, GL_ONE_MINUS_DST_COLOR },
  590. { GL_SRC_ALPHA_SATURATE, GL_ONE },
  591. };
  592. static const GLenum s_depthFunc[] =
  593. {
  594. 0, // ignored
  595. GL_LESS,
  596. GL_LEQUAL,
  597. GL_EQUAL,
  598. GL_GEQUAL,
  599. GL_GREATER,
  600. GL_NOTEQUAL,
  601. GL_NEVER,
  602. GL_ALWAYS,
  603. };
  604. // Specifies the internal format of the texture.
  605. // Must be one of the following symbolic constants:
  606. // GL_ALPHA, GL_LUMINANCE, GL_LUMINANCE_ALPHA, GL_RGB, GL_RGBA.
  607. static const GLenum s_colorFormat[] =
  608. {
  609. 0, // ignored
  610. GL_RGBA,
  611. GL_RGBA,
  612. };
  613. static const GLenum s_depthFormat[] =
  614. {
  615. 0, // ignored
  616. 0,
  617. };
  618. static const GLenum s_textureAddress[] =
  619. {
  620. GL_REPEAT,
  621. GL_MIRRORED_REPEAT,
  622. GL_CLAMP_TO_EDGE,
  623. };
  624. static const GLenum s_textureFilter[] =
  625. {
  626. GL_LINEAR,
  627. GL_NEAREST,
  628. };
  629. struct TextureFormatInfo
  630. {
  631. GLenum m_internalFmt;
  632. GLenum m_fmt;
  633. GLenum m_type;
  634. uint8_t m_bpp;
  635. };
  636. static const TextureFormatInfo s_textureFormat[TextureFormat::Count] =
  637. {
  638. { GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_ZERO, GL_ZERO, 4 },
  639. { GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_ZERO, GL_ZERO, 4 },
  640. { GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_ZERO, GL_ZERO, 4 },
  641. { GL_ZERO, GL_ZERO, GL_ZERO, 0 },
  642. { GL_LUMINANCE, GL_LUMINANCE, GL_UNSIGNED_BYTE, 1 },
  643. { GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, 4 },
  644. { GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, 4 },
  645. #if BGFX_CONFIG_RENDERER_OPENGL
  646. { GL_RGBA16, GL_RGBA, GL_UNSIGNED_SHORT, 8 },
  647. #else
  648. { GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, 8 },
  649. #endif // BGFX_CONFIG_RENDERER_OPENGL
  650. };
  651. const char* glslTypeName(GLuint _type)
  652. {
  653. #define GLSL_TYPE(_ty) case _ty: return #_ty
  654. switch (_type)
  655. {
  656. GLSL_TYPE(GL_FLOAT);
  657. GLSL_TYPE(GL_FLOAT_VEC2);
  658. GLSL_TYPE(GL_FLOAT_VEC3);
  659. GLSL_TYPE(GL_FLOAT_VEC4);
  660. GLSL_TYPE(GL_FLOAT_MAT2);
  661. GLSL_TYPE(GL_FLOAT_MAT3);
  662. GLSL_TYPE(GL_FLOAT_MAT4);
  663. // GLSL_TYPE(GL_FLOAT_MAT2x3);
  664. // GLSL_TYPE(GL_FLOAT_MAT2x4);
  665. // GLSL_TYPE(GL_FLOAT_MAT3x2);
  666. // GLSL_TYPE(GL_FLOAT_MAT3x4);
  667. // GLSL_TYPE(GL_FLOAT_MAT4x2);
  668. // GLSL_TYPE(GL_FLOAT_MAT4x3);
  669. // GLSL_TYPE(GL_SAMPLER_1D);
  670. GLSL_TYPE(GL_SAMPLER_2D);
  671. // GLSL_TYPE(GL_SAMPLER_3D);
  672. GLSL_TYPE(GL_SAMPLER_CUBE);
  673. // GLSL_TYPE(GL_SAMPLER_1D_SHADOW);
  674. // GLSL_TYPE(GL_SAMPLER_2D_SHADOW);
  675. }
  676. #undef GLSL_TYPE
  677. return "UNKNOWN GLSL TYPE!";
  678. }
  679. const char* glEnumName(GLenum _enum)
  680. {
  681. #define GLENUM(_ty) case _ty: return #_ty
  682. switch (_enum)
  683. {
  684. GLENUM(GL_TEXTURE);
  685. GLENUM(GL_RENDERBUFFER);
  686. }
  687. #undef GLENUM
  688. return "UNKNOWN GLENUM!";
  689. }
  690. ConstantType::Enum convertGlType(GLenum _type)
  691. {
  692. switch (_type)
  693. {
  694. case GL_FLOAT:
  695. return ConstantType::Uniform1fv;
  696. case GL_FLOAT_VEC2:
  697. return ConstantType::Uniform2fv;
  698. case GL_FLOAT_VEC3:
  699. return ConstantType::Uniform3fv;
  700. case GL_FLOAT_VEC4:
  701. return ConstantType::Uniform4fv;
  702. case GL_FLOAT_MAT2:
  703. break;
  704. case GL_FLOAT_MAT3:
  705. return ConstantType::Uniform3x3fv;
  706. case GL_FLOAT_MAT4:
  707. return ConstantType::Uniform4x4fv;
  708. // case GL_FLOAT_MAT2x3:
  709. // case GL_FLOAT_MAT2x4:
  710. // case GL_FLOAT_MAT3x2:
  711. // case GL_FLOAT_MAT3x4:
  712. // case GL_FLOAT_MAT4x2:
  713. // case GL_FLOAT_MAT4x3:
  714. // break;
  715. case GL_SAMPLER_2D:
  716. case GL_SAMPLER_CUBE:
  717. // case GL_SAMPLER_1D:
  718. // case GL_SAMPLER_3D:
  719. // case GL_SAMPLER_1D_SHADOW:
  720. // case GL_SAMPLER_2D_SHADOW:
  721. return ConstantType::Uniform1iv;
  722. };
  723. return ConstantType::End;
  724. }
  725. void Material::create(const Shader& _vsh, const Shader& _fsh)
  726. {
  727. m_id = glCreateProgram();
  728. BX_TRACE("material create: %d: %d, %d", m_id, _vsh.m_id, _fsh.m_id);
  729. bool cached = false;
  730. #if BGFX_CONFIG_RENDERER_OPENGL
  731. uint64_t id = (uint64_t(_vsh.m_hash)<<32) | _fsh.m_hash;
  732. id ^= s_renderCtx.m_hash;
  733. if (s_extension[Extension::ARB_get_program_binary].m_supported)
  734. {
  735. uint32_t length;
  736. g_cache(id, false, NULL, length);
  737. cached = length > 0;
  738. if (cached)
  739. {
  740. void* data = g_realloc(NULL, length);
  741. g_cache(id, false, data, length);
  742. StreamRead stream(data, length);
  743. GLenum format;
  744. stream.read(format);
  745. GL_CHECK(glProgramBinary(m_id, format, stream.getDataPtr(), stream.remaining() ) );
  746. g_free(data);
  747. }
  748. else
  749. {
  750. GL_CHECK(glProgramParameteri(m_id, GL_PROGRAM_BINARY_RETRIEVABLE_HINT, GL_TRUE) );
  751. }
  752. }
  753. #endif // BGFX_CONFIG_RENDERER_OPENGL
  754. if (!cached)
  755. {
  756. GL_CHECK(glAttachShader(m_id, _vsh.m_id) );
  757. GL_CHECK(glAttachShader(m_id, _fsh.m_id) );
  758. GL_CHECK(glLinkProgram(m_id) );
  759. GLint linked = 0;
  760. GL_CHECK(glGetProgramiv(m_id, GL_LINK_STATUS, &linked) );
  761. if (0 == linked)
  762. {
  763. char log[1024];
  764. GL_CHECK(glGetProgramInfoLog(m_id, sizeof(log), NULL, log) );
  765. BX_TRACE("%d: %s", linked, log);
  766. GL_CHECK(glDeleteProgram(m_id) );
  767. return;
  768. }
  769. #if BGFX_CONFIG_RENDERER_OPENGL
  770. if (s_extension[Extension::ARB_get_program_binary].m_supported)
  771. {
  772. GLint programLength;
  773. GLenum format;
  774. GL_CHECK(glGetProgramiv(m_id, GL_PROGRAM_BINARY_LENGTH, &programLength) );
  775. uint32_t length = programLength + 4;
  776. uint8_t* data = (uint8_t*)g_realloc(NULL, length);
  777. GL_CHECK(glGetProgramBinary(m_id, programLength, NULL, &format, &data[4]) );
  778. *(uint32_t*)data = format;
  779. g_cache(id, true, data, length);
  780. g_free(data);
  781. }
  782. #endif // BGFX_CONFIG_RENDERER_OPENGL
  783. }
  784. init();
  785. }
  786. void Material::destroy()
  787. {
  788. GL_CHECK(glUseProgram(0) );
  789. GL_CHECK(glDeleteProgram(m_id) );
  790. }
  791. void Material::init()
  792. {
  793. GLint activeAttribs;
  794. GLint activeUniforms;
  795. GL_CHECK(glGetProgramiv(m_id, GL_ACTIVE_ATTRIBUTES, &activeAttribs) );
  796. GL_CHECK(glGetProgramiv(m_id, GL_ACTIVE_UNIFORMS, &activeUniforms) );
  797. GLint max0, max1;
  798. GL_CHECK(glGetProgramiv(m_id, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &max0) );
  799. GL_CHECK(glGetProgramiv(m_id, GL_ACTIVE_UNIFORM_MAX_LENGTH, &max1) );
  800. GLint maxLength = uint32_max(max0, max1);
  801. char* name = (char*)g_realloc(NULL, maxLength + 1);
  802. BX_TRACE("Program %d", m_id);
  803. BX_TRACE("Attributes:");
  804. for (int32_t ii = 0; ii < activeAttribs; ++ii)
  805. {
  806. GLint size;
  807. GLenum type;
  808. GL_CHECK(glGetActiveAttrib(m_id, ii, maxLength + 1, NULL, &size, &type, name) );
  809. BX_TRACE("\t%s %s is at location %d"
  810. , glslTypeName(type)
  811. , name
  812. , glGetAttribLocation(m_id, name)
  813. );
  814. }
  815. m_numPredefined = 0;
  816. m_constantBuffer = ConstantBuffer::create(1024);
  817. m_numSamplers = 0;
  818. BX_TRACE("Uniforms:");
  819. for (int32_t ii = 0; ii < activeUniforms; ++ii)
  820. {
  821. GLint num;
  822. GLenum gltype;
  823. GL_CHECK(glGetActiveUniform(m_id, ii, maxLength + 1, NULL, &num, &gltype, name) );
  824. GLint loc = glGetUniformLocation(m_id, name);
  825. int offset = 0;
  826. char* array = strchr(name, '[');
  827. if (NULL != array)
  828. {
  829. BX_TRACE("--- %s", name);
  830. *array = '\0';
  831. array++;
  832. char* end = strchr(array, ']');
  833. *end = '\0';
  834. offset = atoi(array);
  835. }
  836. if (GL_SAMPLER_2D == gltype)
  837. {
  838. BX_TRACE("Sampler %d at %d.", m_numSamplers, loc);
  839. m_sampler[m_numSamplers] = loc;
  840. m_numSamplers++;
  841. }
  842. const void* data = NULL;
  843. PredefinedUniform::Enum predefined = nameToPredefinedUniformEnum(name);
  844. if (PredefinedUniform::Count != predefined)
  845. {
  846. m_predefined[m_numPredefined].m_loc = loc;
  847. m_predefined[m_numPredefined].m_type = predefined;
  848. m_predefined[m_numPredefined].m_count = num;
  849. m_numPredefined++;
  850. }
  851. else
  852. {
  853. const UniformInfo* info = s_renderCtx.m_uniformReg.find(name);
  854. if (NULL != info)
  855. {
  856. data = info->m_data;
  857. ConstantType::Enum type = convertGlType(gltype);
  858. m_constantBuffer->writeUniformRef(type, loc, data, num);
  859. BX_TRACE("store %s %p", name, data);
  860. }
  861. }
  862. BX_TRACE("\tuniform %s %s%s is at location %d, size %d (%p), offset %d"
  863. , glslTypeName(gltype)
  864. , name
  865. , PredefinedUniform::Count != predefined ? "*" : ""
  866. , loc
  867. , num
  868. , data
  869. , offset
  870. );
  871. BX_UNUSED(offset);
  872. }
  873. m_constantBuffer->finish();
  874. g_free(name);
  875. memset(m_attributes, 0xff, sizeof(m_attributes) );
  876. uint32_t used = 0;
  877. for (uint32_t ii = 0; ii < Attrib::Count; ++ii)
  878. {
  879. GLuint loc = glGetAttribLocation(m_id, s_attribName[ii]);
  880. if (GLuint(-1) != loc )
  881. {
  882. BX_TRACE("attr %s: %d", s_attribName[ii], loc);
  883. m_attributes[ii] = loc;
  884. m_used[used++] = ii;
  885. }
  886. }
  887. m_used[used] = Attrib::Count;
  888. used = 0;
  889. for (uint32_t ii = 0; ii < countof(s_instanceDataName); ++ii)
  890. {
  891. GLuint loc = glGetAttribLocation(m_id, s_instanceDataName[ii]);
  892. if (GLuint(-1) != loc )
  893. {
  894. BX_TRACE("instance data %s: %d", s_instanceDataName[ii], loc);
  895. m_instanceData[used++] = loc;
  896. }
  897. }
  898. m_instanceData[used] = 0xffff;
  899. }
  900. void Material::bindAttributes(const VertexDecl& _vertexDecl, uint32_t _baseVertex) const
  901. {
  902. uint32_t enabled = 0;
  903. for (uint32_t ii = 0; Attrib::Count != m_used[ii]; ++ii)
  904. {
  905. Attrib::Enum attr = Attrib::Enum(m_used[ii]);
  906. GLuint loc = m_attributes[attr];
  907. uint8_t num;
  908. AttribType::Enum type;
  909. bool normalized;
  910. _vertexDecl.decode(attr, num, type, normalized);
  911. if (0xffff != loc
  912. && 0xff != _vertexDecl.m_attributes[attr])
  913. {
  914. GL_CHECK(glEnableVertexAttribArray(loc) );
  915. enabled |= 1<<attr;
  916. GL_CHECK(s_vertexAttribDivisor(loc, 0) );
  917. uint32_t baseVertex = _baseVertex*_vertexDecl.m_stride + _vertexDecl.m_offset[attr];
  918. GL_CHECK(glVertexAttribPointer(loc, num, s_attribType[type], normalized, _vertexDecl.m_stride, (void*)(uintptr_t)baseVertex) );
  919. }
  920. else
  921. {
  922. GL_CHECK(glDisableVertexAttribArray(loc) );
  923. switch (num)
  924. {
  925. case 1:
  926. GL_CHECK(glVertexAttrib1f(loc, 0.0f) );
  927. break;
  928. case 2:
  929. GL_CHECK(glVertexAttrib2f(loc, 0.0f, 0.0f) );
  930. break;
  931. case 3:
  932. GL_CHECK(glVertexAttrib3f(loc, 0.0f, 0.0f, 0.0f) );
  933. break;
  934. case 4:
  935. GL_CHECK(glVertexAttrib4f(loc, 0.0f, 0.0f, 0.0f, 0.0f) );
  936. break;
  937. default:
  938. BX_CHECK(false, "You should not be here!");
  939. break;
  940. }
  941. }
  942. }
  943. }
  944. void Material::bindInstanceData(uint32_t _stride, uint32_t _baseVertex) const
  945. {
  946. uint32_t baseVertex = _baseVertex;
  947. for (uint32_t ii = 0; 0xffff != m_instanceData[ii]; ++ii)
  948. {
  949. GLuint loc = m_instanceData[ii];
  950. GL_CHECK(glEnableVertexAttribArray(loc) );
  951. GL_CHECK(glVertexAttribPointer(loc, 4, GL_FLOAT, GL_FALSE, _stride, (void*)(uintptr_t)baseVertex) );
  952. GL_CHECK(s_vertexAttribDivisor(loc, 1) );
  953. baseVertex += 16;
  954. }
  955. }
  956. void Texture::create(const Memory* _mem, uint32_t _flags)
  957. {
  958. Dds dds;
  959. uint8_t numMips = 0;
  960. if (parseDds(dds, _mem) )
  961. {
  962. numMips = dds.m_numMips;
  963. if (dds.m_cubeMap)
  964. {
  965. m_target = GL_TEXTURE_CUBE_MAP;
  966. }
  967. #if BGFX_CONFIG_RENDERER_OPENGL
  968. else if (dds.m_depth > 1)
  969. {
  970. m_target = GL_TEXTURE_3D;
  971. }
  972. #endif // BGFX_CONFIG_RENDERER_OPENGL
  973. else
  974. {
  975. m_target = GL_TEXTURE_2D;
  976. }
  977. GL_CHECK(glGenTextures(1, &m_id) );
  978. BX_CHECK(0 != m_id, "Failed to generate texture id.");
  979. GL_CHECK(glBindTexture(m_target, m_id) );
  980. const TextureFormatInfo& tfi = s_textureFormat[dds.m_type];
  981. GLenum internalFmt = tfi.m_internalFmt;
  982. m_fmt = tfi.m_fmt;
  983. GLenum target = m_target;
  984. if (dds.m_cubeMap)
  985. {
  986. target = GL_TEXTURE_CUBE_MAP_POSITIVE_X;
  987. }
  988. if (!s_renderCtx.m_dxtSupport
  989. || TextureFormat::Unknown < dds.m_type)
  990. {
  991. bool decompress = TextureFormat::Unknown > dds.m_type;
  992. if (GL_RGBA == internalFmt
  993. || decompress)
  994. {
  995. internalFmt = s_extension[Extension::EXT_texture_format_BGRA8888].m_supported ? GL_BGRA_EXT : GL_RGBA;
  996. m_fmt = internalFmt;
  997. }
  998. m_type = tfi.m_type;
  999. if (decompress)
  1000. {
  1001. m_type = GL_UNSIGNED_BYTE;
  1002. }
  1003. uint8_t* bits = (uint8_t*)g_realloc(NULL, dds.m_width*dds.m_height*tfi.m_bpp);
  1004. for (uint8_t side = 0, numSides = dds.m_cubeMap ? 6 : 1; side < numSides; ++side)
  1005. {
  1006. uint32_t width = dds.m_width;
  1007. uint32_t height = dds.m_height;
  1008. uint32_t depth = dds.m_depth;
  1009. for (uint32_t lod = 0, num = dds.m_numMips; lod < num; ++lod)
  1010. {
  1011. width = uint32_max(1, width);
  1012. height = uint32_max(1, height);
  1013. depth = uint32_max(1, depth);
  1014. Mip mip;
  1015. if (getRawImageData(dds, side, lod, _mem, mip) )
  1016. {
  1017. mip.decode(bits);
  1018. if (GL_RGBA == internalFmt)
  1019. {
  1020. uint32_t dstpitch = width*4;
  1021. for (uint32_t yy = 0; yy < height; ++yy)
  1022. {
  1023. uint8_t* dst = &bits[yy*dstpitch];
  1024. for (uint32_t xx = 0; xx < width; ++xx)
  1025. {
  1026. uint8_t tmp = dst[0];
  1027. dst[0] = dst[2];
  1028. dst[2] = tmp;
  1029. dst += 4;
  1030. }
  1031. }
  1032. }
  1033. #if BGFX_CONFIG_RENDERER_OPENGL
  1034. if (target == GL_TEXTURE_3D)
  1035. {
  1036. GL_CHECK(glTexImage3D(target
  1037. , lod
  1038. , internalFmt
  1039. , width
  1040. , height
  1041. , depth
  1042. , 0
  1043. , m_fmt
  1044. , m_type
  1045. , bits
  1046. ) );
  1047. }
  1048. else
  1049. #endif // BGFX_CONFIG_RENDERER_OPENGL
  1050. {
  1051. GL_CHECK(glTexImage2D(target+side
  1052. , lod
  1053. , internalFmt
  1054. , width
  1055. , height
  1056. , 0
  1057. , m_fmt
  1058. , m_type
  1059. , bits
  1060. ) );
  1061. }
  1062. }
  1063. width >>= 1;
  1064. height >>= 1;
  1065. depth >>= 1;
  1066. }
  1067. }
  1068. g_free(bits);
  1069. }
  1070. else
  1071. {
  1072. for (uint8_t side = 0, numSides = dds.m_cubeMap ? 6 : 1; side < numSides; ++side)
  1073. {
  1074. uint32_t width = dds.m_width;
  1075. uint32_t height = dds.m_height;
  1076. uint32_t depth = dds.m_depth;
  1077. for (uint32_t ii = 0, num = dds.m_numMips; ii < num; ++ii)
  1078. {
  1079. width = uint32_max(1, width);
  1080. height = uint32_max(1, height);
  1081. depth = uint32_max(1, depth);
  1082. Mip mip;
  1083. if (getRawImageData(dds, side, ii, _mem, mip) )
  1084. {
  1085. #if BGFX_CONFIG_RENDERER_OPENGL
  1086. if (m_target == GL_TEXTURE_3D)
  1087. {
  1088. GL_CHECK(glCompressedTexImage3D(target
  1089. , ii
  1090. , internalFmt
  1091. , width
  1092. , height
  1093. , depth
  1094. , 0
  1095. , mip.m_size
  1096. , mip.m_data
  1097. ) );
  1098. }
  1099. else
  1100. #endif // BGFX_CONFIG_RENDERER_OPENGL
  1101. {
  1102. GL_CHECK(glCompressedTexImage2D(target+side
  1103. , ii
  1104. , internalFmt
  1105. , width
  1106. , height
  1107. , 0
  1108. , mip.m_size
  1109. , mip.m_data
  1110. ) );
  1111. }
  1112. }
  1113. width >>= 1;
  1114. height >>= 1;
  1115. depth >>= 1;
  1116. }
  1117. }
  1118. }
  1119. }
  1120. else
  1121. {
  1122. m_target = GL_TEXTURE_2D;
  1123. GL_CHECK(glGenTextures(1, &m_id) );
  1124. BX_CHECK(0 != m_id, "Failed to generate texture id.");
  1125. GL_CHECK(glBindTexture(m_target, m_id) );
  1126. StreamRead stream(_mem->data, _mem->size);
  1127. uint32_t magic;
  1128. stream.read(magic);
  1129. if (BGFX_MAGIC == magic)
  1130. {
  1131. TextureInfo ti;
  1132. stream.read(ti);
  1133. const TextureFormatInfo& tfi = s_textureFormat[ti.m_type];
  1134. GLenum internalFmt = tfi.m_internalFmt;
  1135. m_fmt = tfi.m_fmt;
  1136. m_type = tfi.m_type;
  1137. uint32_t bpp = s_textureFormat[ti.m_type].m_bpp;
  1138. uint8_t* data = NULL != ti.m_mem ? ti.m_mem->data : NULL;
  1139. for (uint8_t side = 0, numSides = ti.m_cubeMap ? 6 : 1; side < numSides; ++side)
  1140. {
  1141. uint32_t width = ti.m_width;
  1142. uint32_t height = ti.m_height;
  1143. for (uint32_t lod = 0, num = ti.m_numMips; lod < num; ++lod)
  1144. {
  1145. width = uint32_max(width, 1);
  1146. height = uint32_max(height, 1);
  1147. GL_CHECK(glTexImage2D(m_target
  1148. , lod
  1149. , internalFmt
  1150. , width
  1151. , height
  1152. , 0
  1153. , m_fmt
  1154. , m_type
  1155. , data
  1156. ) );
  1157. if (NULL != data)
  1158. {
  1159. data += width*height*bpp;
  1160. }
  1161. width >>= 1;
  1162. height >>= 1;
  1163. }
  1164. }
  1165. if (NULL != ti.m_mem)
  1166. {
  1167. release(ti.m_mem);
  1168. }
  1169. }
  1170. else
  1171. {
  1172. //
  1173. }
  1174. }
  1175. GL_CHECK(glTexParameteri(m_target, GL_TEXTURE_WRAP_S, s_textureAddress[(_flags&BGFX_TEXTURE_U_MASK)>>BGFX_TEXTURE_U_SHIFT]) );
  1176. GL_CHECK(glTexParameteri(m_target, GL_TEXTURE_WRAP_T, s_textureAddress[(_flags&BGFX_TEXTURE_V_MASK)>>BGFX_TEXTURE_V_SHIFT]) );
  1177. #if BGFX_CONFIG_RENDERER_OPENGL
  1178. if (m_target == GL_TEXTURE_3D)
  1179. {
  1180. GL_CHECK(glTexParameteri(m_target, GL_TEXTURE_WRAP_R, s_textureAddress[(_flags&BGFX_TEXTURE_W_MASK)>>BGFX_TEXTURE_W_SHIFT]) );
  1181. }
  1182. #endif // BGFX_CONFIG_RENDERER_OPENGL
  1183. GL_CHECK(glTexParameteri(m_target, GL_TEXTURE_MIN_FILTER, s_textureFilter[(_flags&BGFX_TEXTURE_MIN_MASK)>>BGFX_TEXTURE_MIN_SHIFT]) );
  1184. GL_CHECK(glTexParameteri(m_target, GL_TEXTURE_MAG_FILTER, s_textureFilter[(_flags&BGFX_TEXTURE_MAG_MASK)>>BGFX_TEXTURE_MAG_SHIFT]) );
  1185. GL_CHECK(glTexParameteri(m_target, GL_TEXTURE_MIN_FILTER, 1 < numMips ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR) );
  1186. GL_CHECK(glBindTexture(m_target, 0) );
  1187. }
  1188. void Texture::createColor(uint32_t _width, uint32_t _height, GLenum _min, GLenum _mag)
  1189. {
  1190. GLenum internalFormat = /*_fp ? GL_RGBA16F_ARB :*/ GL_RGBA;
  1191. GLenum type = /*_fp ? GL_HALF_FLOAT_ARB :*/ GL_UNSIGNED_BYTE;
  1192. m_target = /*0 != _depth ? GL_TEXTURE_3D :*/ GL_TEXTURE_2D;
  1193. GL_CHECK(glGenTextures(1, &m_id) );
  1194. BX_CHECK(0 != m_id, "Failed to generate texture id.");
  1195. GL_CHECK(glBindTexture(m_target, m_id) );
  1196. GL_CHECK(glTexParameteri(m_target, GL_TEXTURE_MIN_FILTER, _min) );
  1197. GL_CHECK(glTexParameteri(m_target, GL_TEXTURE_MAG_FILTER, _mag) );
  1198. GL_CHECK(glTexParameteri(m_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE) );
  1199. GL_CHECK(glTexParameteri(m_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE) );
  1200. GL_CHECK(glTexImage2D(m_target
  1201. , 0
  1202. , internalFormat
  1203. , _width
  1204. , _height
  1205. , 0
  1206. , GL_RGBA
  1207. , type
  1208. , NULL
  1209. ) );
  1210. GL_CHECK(glBindTexture(m_target, 0) );
  1211. }
  1212. void Texture::createDepth(uint32_t _width, uint32_t _height)
  1213. {
  1214. m_target = GL_TEXTURE_2D;
  1215. GL_CHECK(glGenTextures(1, &m_id) );
  1216. BX_CHECK(0 != m_id, "Failed to generate texture id.");
  1217. GL_CHECK(glBindTexture(m_target, m_id) );
  1218. // glTexParameteri(m_target, GL_TEXTURE_COMPARE_MODE, GL_NONE);
  1219. // glTexParameteri(m_target, GL_DEPTH_TEXTURE_MODE, GL_NONE);
  1220. GL_CHECK(glTexParameteri(m_target, GL_TEXTURE_MIN_FILTER, GL_LINEAR) );
  1221. GL_CHECK(glTexParameteri(m_target, GL_TEXTURE_MAG_FILTER, GL_LINEAR) );
  1222. GL_CHECK(glTexParameteri(m_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE) );
  1223. GL_CHECK(glTexParameteri(m_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE) );
  1224. // OpenGL ES 2.0 doesn't support GL_DEPTH_COMPONENT... this will fail.
  1225. GL_CHECK(glTexImage2D(m_target
  1226. , 0
  1227. , GL_DEPTH_COMPONENT
  1228. , _width
  1229. , _height
  1230. , 0
  1231. , GL_DEPTH_COMPONENT
  1232. , GL_FLOAT
  1233. , NULL
  1234. ) );
  1235. GL_CHECK(glBindTexture(m_target, 0) );
  1236. }
  1237. void Texture::destroy()
  1238. {
  1239. if (0 != m_id)
  1240. {
  1241. GL_CHECK(glBindTexture(m_target, 0) );
  1242. GL_CHECK(glDeleteTextures(1, &m_id) );
  1243. m_id = 0;
  1244. }
  1245. }
  1246. void Texture::update(uint8_t _side, uint8_t _mip, const Rect& _rect, uint16_t _z, uint16_t _depth, const Memory* _mem)
  1247. {
  1248. GL_CHECK(glBindTexture(m_target, m_id) );
  1249. GL_CHECK(glPixelStorei(GL_UNPACK_ALIGNMENT, 1) );
  1250. switch (m_target)
  1251. {
  1252. case GL_TEXTURE_2D:
  1253. {
  1254. GL_CHECK(glTexSubImage2D(m_target
  1255. , _mip
  1256. , _rect.m_x
  1257. , _rect.m_y
  1258. , _rect.m_width
  1259. , _rect.m_height
  1260. , m_fmt
  1261. , m_type
  1262. , _mem->data
  1263. ) );
  1264. }
  1265. break;
  1266. case GL_TEXTURE_CUBE_MAP:
  1267. {
  1268. GL_CHECK(glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X+_side
  1269. , _mip
  1270. , _rect.m_x
  1271. , _rect.m_y
  1272. , _rect.m_width
  1273. , _rect.m_height
  1274. , m_fmt
  1275. , m_type
  1276. , _mem->data
  1277. ) );
  1278. }
  1279. break;
  1280. #if BGFX_CONFIG_RENDERER_OPENGL
  1281. case GL_TEXTURE_3D:
  1282. {
  1283. GL_CHECK(glTexSubImage3D(m_target
  1284. , _mip
  1285. , _rect.m_x
  1286. , _rect.m_y
  1287. , _z
  1288. , _rect.m_width
  1289. , _rect.m_height
  1290. , _depth
  1291. , m_fmt
  1292. , m_type
  1293. , _mem->data
  1294. ) );
  1295. }
  1296. break;
  1297. }
  1298. #endif // BGFX_CONFIG_RENDERER_OPENGL
  1299. }
  1300. void RenderTarget::create(uint16_t _width, uint16_t _height, uint32_t _flags, uint32_t _textureFlags)
  1301. {
  1302. BX_TRACE("Create render target %dx%d 0x%02x", _width, _height, _flags);
  1303. m_width = _width;
  1304. m_height = _height;
  1305. // m_msaa = s_msaa[(m_flags&BGFX_RENDER_TARGET_MSAA_MASK)>>BGFX_RENDER_TARGET_MSAA_SHIFT];
  1306. uint32_t colorFormat = (_flags&BGFX_RENDER_TARGET_COLOR_MASK)>>BGFX_RENDER_TARGET_COLOR_SHIFT;
  1307. uint32_t depthFormat = (_flags&BGFX_RENDER_TARGET_DEPTH_MASK)>>BGFX_RENDER_TARGET_DEPTH_SHIFT;
  1308. GLenum minFilter = s_textureFilter[(_textureFlags&BGFX_TEXTURE_MIN_MASK)>>BGFX_TEXTURE_MIN_SHIFT];
  1309. GLenum magFilter = s_textureFilter[(_textureFlags&BGFX_TEXTURE_MAG_MASK)>>BGFX_TEXTURE_MAG_SHIFT];
  1310. if (0 < colorFormat)
  1311. {
  1312. m_color.createColor(_width, _height, minFilter, magFilter);
  1313. }
  1314. #if 0 // GLES can't create texture with depth texture format...
  1315. if (0 < depthFormat)
  1316. {
  1317. m_depth.createDepth(_width, _height);
  1318. }
  1319. #endif //
  1320. GL_CHECK(glGenFramebuffers(1, &m_fbo) );
  1321. BX_CHECK(0 != m_fbo, "Failed to generate framebuffer id.");
  1322. GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, m_fbo) );
  1323. if (0 < colorFormat)
  1324. {
  1325. GL_CHECK(glFramebufferTexture2D(GL_FRAMEBUFFER
  1326. , GL_COLOR_ATTACHMENT0
  1327. , m_color.m_target
  1328. , m_color.m_id
  1329. , 0
  1330. ) );
  1331. }
  1332. if (0 < depthFormat)
  1333. {
  1334. if (0 < colorFormat)
  1335. {
  1336. #if BGFX_CONFIG_RENDERER_OPENGL
  1337. GLenum depthComponent = GL_DEPTH_COMPONENT32;
  1338. #else
  1339. GLenum depthComponent = GL_DEPTH_COMPONENT16;
  1340. #endif // BGFX_CONFIG_RENDERER_OPENGL
  1341. GL_CHECK(glGenRenderbuffers(1, &m_rbo) );
  1342. BX_CHECK(0 != m_rbo, "Failed to generate renderbuffer id.");
  1343. GL_CHECK(glBindRenderbuffer(GL_RENDERBUFFER, m_rbo) );
  1344. GL_CHECK(glRenderbufferStorage(GL_RENDERBUFFER, depthComponent, _width, _height) );
  1345. GL_CHECK(glBindRenderbuffer(GL_RENDERBUFFER, 0) );
  1346. GL_CHECK(glFramebufferRenderbuffer(GL_FRAMEBUFFER
  1347. , GL_DEPTH_ATTACHMENT
  1348. , GL_RENDERBUFFER
  1349. , m_rbo
  1350. ) );
  1351. }
  1352. else
  1353. {
  1354. GL_CHECK(glFramebufferTexture2D(GL_FRAMEBUFFER
  1355. , GL_DEPTH_ATTACHMENT
  1356. , m_depth.m_target
  1357. , m_depth.m_id
  1358. , 0
  1359. ) );
  1360. }
  1361. }
  1362. BX_CHECK(GL_FRAMEBUFFER_COMPLETE == glCheckFramebufferStatus(GL_FRAMEBUFFER)
  1363. , "glCheckFramebufferStatus failed 0x%08x"
  1364. , glCheckFramebufferStatus(GL_FRAMEBUFFER)
  1365. );
  1366. GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, 0) );
  1367. }
  1368. void RenderTarget::destroy()
  1369. {
  1370. GL_CHECK(glDeleteFramebuffers(1, &m_fbo) );
  1371. if (0 != m_rbo)
  1372. {
  1373. GL_CHECK(glDeleteRenderbuffers(1, &m_rbo) );
  1374. }
  1375. m_color.destroy();
  1376. m_depth.destroy();
  1377. }
  1378. void ConstantBuffer::commit()
  1379. {
  1380. reset();
  1381. do
  1382. {
  1383. uint32_t opcode = read();
  1384. if (ConstantType::End == opcode)
  1385. {
  1386. break;
  1387. }
  1388. ConstantType::Enum type;
  1389. uint16_t loc;
  1390. uint16_t num;
  1391. uint16_t copy;
  1392. decodeOpcode(opcode, type, loc, num, copy);
  1393. const char* data;
  1394. if (copy)
  1395. {
  1396. data = read(g_constantTypeSize[type]*num);
  1397. }
  1398. else
  1399. {
  1400. memcpy(&data, read(sizeof(void*) ), sizeof(void*) );
  1401. }
  1402. #define CASE_IMPLEMENT_UNIFORM(_uniform, _glsuffix, _dxsuffix, _type) \
  1403. case ConstantType::_uniform: \
  1404. { \
  1405. _type* value = (_type*)data; \
  1406. GL_CHECK(glUniform##_glsuffix(loc, num, value) ); \
  1407. } \
  1408. break;
  1409. #define CASE_IMPLEMENT_UNIFORM_T(_uniform, _glsuffix, _dxsuffix, _type) \
  1410. case ConstantType::_uniform: \
  1411. { \
  1412. _type* value = (_type*)data; \
  1413. GL_CHECK(glUniform##_glsuffix(loc, num, GL_FALSE, value) ); \
  1414. } \
  1415. break;
  1416. switch (type)
  1417. {
  1418. // case ConstantType::Uniform1iv:
  1419. // {
  1420. // int* value = (int*)data;
  1421. // BX_TRACE("Uniform1iv sampler %d, loc %d (num %d, copy %d)", *value, loc, num, copy);
  1422. // GL_CHECK(glUniform1iv(loc, num, value) );
  1423. // }
  1424. // break;
  1425. CASE_IMPLEMENT_UNIFORM(Uniform1i, 1iv, I, int);
  1426. CASE_IMPLEMENT_UNIFORM(Uniform1f, 1fv, F, float);
  1427. CASE_IMPLEMENT_UNIFORM(Uniform1iv, 1iv, I, int);
  1428. CASE_IMPLEMENT_UNIFORM(Uniform1fv, 1fv, F, float);
  1429. CASE_IMPLEMENT_UNIFORM(Uniform2fv, 2fv, F, float);
  1430. CASE_IMPLEMENT_UNIFORM(Uniform3fv, 3fv, F, float);
  1431. CASE_IMPLEMENT_UNIFORM(Uniform4fv, 4fv, F, float);
  1432. CASE_IMPLEMENT_UNIFORM_T(Uniform3x3fv, Matrix3fv, F, float);
  1433. CASE_IMPLEMENT_UNIFORM_T(Uniform4x4fv, Matrix4fv, F, float);
  1434. case ConstantType::End:
  1435. break;
  1436. default:
  1437. BX_TRACE("%4d: INVALID 0x%08x, t %d, l %d, n %d, c %d", m_pos, opcode, type, loc, num, copy);
  1438. break;
  1439. }
  1440. #undef CASE_IMPLEMENT_UNIFORM
  1441. #undef CASE_IMPLEMENT_UNIFORM_T
  1442. } while (true);
  1443. }
  1444. void TextVideoMemBlitter::setup()
  1445. {
  1446. uint32_t width = s_renderCtx.m_resolution.m_width;
  1447. uint32_t height = s_renderCtx.m_resolution.m_height;
  1448. GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, 0) );
  1449. GL_CHECK(glViewport(0, 0, width, height) );
  1450. GL_CHECK(glDisable(GL_DEPTH_TEST) );
  1451. GL_CHECK(glDepthFunc(GL_ALWAYS) );
  1452. GL_CHECK(glDisable(GL_CULL_FACE) );
  1453. GL_CHECK(glDisable(GL_BLEND) );
  1454. GL_CHECK(glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE) );
  1455. #if BGFX_CONFIG_RENDERER_OPENGL
  1456. GL_CHECK(glDisable(GL_ALPHA_TEST) );
  1457. #endif // BGFX_CONFIG_RENDERER_OPENGL
  1458. Material& material = s_renderCtx.m_materials[m_material.idx];
  1459. GL_CHECK(glUseProgram(material.m_id) );
  1460. GL_CHECK(glUniform1i(material.m_sampler[0], 0) );
  1461. float proj[16];
  1462. matrix_ortho(proj, 0.0f, (float)width, (float)height, 0.0f, 0.0f, 1000.0f);
  1463. GL_CHECK(glUniformMatrix4fv(material.m_predefined[0].m_loc
  1464. , 1
  1465. , GL_FALSE
  1466. , proj
  1467. ) );
  1468. GL_CHECK(glActiveTexture(GL_TEXTURE0) );
  1469. GL_CHECK(glBindTexture(GL_TEXTURE_2D, s_renderCtx.m_textures[m_texture.idx].m_id) );
  1470. }
  1471. void TextVideoMemBlitter::render(uint32_t _numIndices)
  1472. {
  1473. uint32_t numVertices = _numIndices*4/6;
  1474. s_renderCtx.m_indexBuffers[m_ib->handle.idx].update(0, _numIndices*2, m_ib->data);
  1475. s_renderCtx.m_vertexBuffers[m_vb->handle.idx].update(0, numVertices*m_decl.m_stride, m_vb->data);
  1476. VertexBuffer& vb = s_renderCtx.m_vertexBuffers[m_vb->handle.idx];
  1477. GL_CHECK(glBindBuffer(GL_ARRAY_BUFFER, vb.m_id) );
  1478. IndexBuffer& ib = s_renderCtx.m_indexBuffers[m_ib->handle.idx];
  1479. GL_CHECK(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ib.m_id) );
  1480. Material& material = s_renderCtx.m_materials[m_material.idx];
  1481. material.bindAttributes(m_decl, 0);
  1482. GL_CHECK(glDrawElements(GL_TRIANGLES
  1483. , _numIndices
  1484. , GL_UNSIGNED_SHORT
  1485. , (void*)0
  1486. ) );
  1487. }
  1488. void Context::flip()
  1489. {
  1490. s_renderCtx.flip();
  1491. }
  1492. GLint glGet(GLenum _pname)
  1493. {
  1494. GLint result;
  1495. GL_CHECK(glGetIntegerv(_pname, &result) );
  1496. return result;
  1497. }
  1498. void Context::rendererInit()
  1499. {
  1500. s_renderCtx.init();
  1501. #if BGFX_CONFIG_DEBUG
  1502. GLint numCmpFormats;
  1503. GL_CHECK(glGetIntegerv(GL_NUM_COMPRESSED_TEXTURE_FORMATS, &numCmpFormats) );
  1504. BX_TRACE("GL_NUM_COMPRESSED_TEXTURE_FORMATS %d", numCmpFormats);
  1505. GLint* formats = (GLint*)alloca(sizeof(GLint)*numCmpFormats);
  1506. glGetIntegerv(GL_COMPRESSED_TEXTURE_FORMATS, formats);
  1507. for (GLint ii = 0; ii < numCmpFormats; ++ii)
  1508. {
  1509. BX_TRACE("\t%3d: %8x", ii, formats[ii]);
  1510. }
  1511. # define GL_GET(_pname, _min) BX_TRACE(#_pname " %d (min: %d)", glGet(_pname), _min)
  1512. GL_GET(GL_MAX_FRAGMENT_UNIFORM_VECTORS, 16);
  1513. GL_GET(GL_MAX_VERTEX_UNIFORM_VECTORS, 128);
  1514. GL_GET(GL_MAX_VARYING_VECTORS, 8);
  1515. GL_GET(GL_MAX_VERTEX_ATTRIBS, 8);
  1516. GL_GET(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, 8);
  1517. GL_GET(GL_MAX_CUBE_MAP_TEXTURE_SIZE, 16);
  1518. GL_GET(GL_MAX_TEXTURE_IMAGE_UNITS, 8);
  1519. GL_GET(GL_MAX_TEXTURE_SIZE, 64);
  1520. GL_GET(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, 0);
  1521. GL_GET(GL_MAX_RENDERBUFFER_SIZE, 1);
  1522. #endif // BGFX_CONFIG_DEBUG
  1523. const char* extensions = (const char*)glGetString(GL_EXTENSIONS);
  1524. char name[1024];
  1525. const char* pos = extensions;
  1526. const char* end = extensions + strlen(extensions);
  1527. while (pos < end)
  1528. {
  1529. uint32_t len;
  1530. const char* space = strchr(pos, ' ');
  1531. if (NULL != space)
  1532. {
  1533. len = uint32_min(sizeof(name), (uint32_t)(space - pos) );
  1534. }
  1535. else
  1536. {
  1537. len = uint32_min(sizeof(name), (uint32_t)strlen(pos) );
  1538. }
  1539. strncpy(name, pos, len);
  1540. name[len] = '\0';
  1541. bool supported = false;
  1542. for (uint32_t ii = 0; ii < Extension::Count; ++ii)
  1543. {
  1544. Extension& extension = s_extension[ii];
  1545. if (!extension.m_supported
  1546. && extension.m_initialize)
  1547. {
  1548. if (0 == strcmp(name, extension.m_name) )
  1549. {
  1550. extension.m_supported = true;
  1551. supported = true;
  1552. break;
  1553. }
  1554. }
  1555. }
  1556. BX_TRACE("GL_EXTENSION%s: %s", supported ? " (supported)" : "", name);
  1557. BX_UNUSED(supported);
  1558. pos += len+1;
  1559. }
  1560. BX_TRACE("Supported extensions:");
  1561. for (uint32_t ii = 0; ii < Extension::Count; ++ii)
  1562. {
  1563. if (s_extension[ii].m_supported)
  1564. {
  1565. BX_TRACE("\t%2d: %s", ii, s_extension[ii].m_name);
  1566. }
  1567. }
  1568. s_renderCtx.m_dxtSupport = true
  1569. && s_extension[Extension::EXT_texture_compression_dxt1].m_supported
  1570. && s_extension[Extension::CHROMIUM_texture_compression_dxt3].m_supported
  1571. && s_extension[Extension::CHROMIUM_texture_compression_dxt5].m_supported
  1572. ;
  1573. s_renderCtx.m_dxtSupport |=
  1574. s_extension[Extension::EXT_texture_compression_s3tc].m_supported
  1575. ;
  1576. }
  1577. void Context::rendererShutdown()
  1578. {
  1579. s_renderCtx.shutdown();
  1580. }
  1581. void Context::rendererCreateIndexBuffer(IndexBufferHandle _handle, Memory* _mem)
  1582. {
  1583. s_renderCtx.m_indexBuffers[_handle.idx].create(_mem->size, _mem->data);
  1584. }
  1585. void Context::rendererDestroyIndexBuffer(IndexBufferHandle _handle)
  1586. {
  1587. s_renderCtx.m_indexBuffers[_handle.idx].destroy();
  1588. }
  1589. void Context::rendererCreateVertexDecl(VertexDeclHandle _handle, const VertexDecl& _decl)
  1590. {
  1591. VertexDecl& decl = s_renderCtx.m_vertexDecls[_handle.idx];
  1592. memcpy(&decl, &_decl, sizeof(VertexDecl) );
  1593. dump(decl);
  1594. }
  1595. void Context::rendererDestroyVertexDecl(VertexDeclHandle /*_handle*/)
  1596. {
  1597. }
  1598. void Context::rendererCreateVertexBuffer(VertexBufferHandle _handle, Memory* _mem, VertexDeclHandle _declHandle)
  1599. {
  1600. s_renderCtx.m_vertexBuffers[_handle.idx].create(_mem->size, _mem->data, _declHandle);
  1601. }
  1602. void Context::rendererDestroyVertexBuffer(VertexBufferHandle _handle)
  1603. {
  1604. s_renderCtx.m_vertexBuffers[_handle.idx].destroy();
  1605. }
  1606. void Context::rendererCreateDynamicIndexBuffer(IndexBufferHandle _handle, uint32_t _size)
  1607. {
  1608. s_renderCtx.m_indexBuffers[_handle.idx].create(_size, NULL);
  1609. }
  1610. void Context::rendererUpdateDynamicIndexBuffer(IndexBufferHandle _handle, uint32_t _offset, uint32_t _size, Memory* _mem)
  1611. {
  1612. s_renderCtx.m_indexBuffers[_handle.idx].update(_offset, uint32_min(_size, _mem->size), _mem->data);
  1613. }
  1614. void Context::rendererDestroyDynamicIndexBuffer(IndexBufferHandle _handle)
  1615. {
  1616. s_renderCtx.m_indexBuffers[_handle.idx].destroy();
  1617. }
  1618. void Context::rendererCreateDynamicVertexBuffer(VertexBufferHandle _handle, uint32_t _size)
  1619. {
  1620. VertexDeclHandle decl = BGFX_INVALID_HANDLE;
  1621. s_renderCtx.m_vertexBuffers[_handle.idx].create(_size, NULL, decl);
  1622. }
  1623. void Context::rendererUpdateDynamicVertexBuffer(VertexBufferHandle _handle, uint32_t _offset, uint32_t _size, Memory* _mem)
  1624. {
  1625. s_renderCtx.m_vertexBuffers[_handle.idx].update(_offset, uint32_min(_size, _mem->size), _mem->data);
  1626. }
  1627. void Context::rendererDestroyDynamicVertexBuffer(VertexBufferHandle _handle)
  1628. {
  1629. s_renderCtx.m_vertexBuffers[_handle.idx].destroy();
  1630. }
  1631. void Context::rendererCreateVertexShader(VertexShaderHandle _handle, Memory* _mem)
  1632. {
  1633. s_renderCtx.m_vertexShaders[_handle.idx].create(GL_VERTEX_SHADER, _mem->data);
  1634. }
  1635. void Context::rendererDestroyVertexShader(VertexShaderHandle _handle)
  1636. {
  1637. s_renderCtx.m_vertexShaders[_handle.idx].destroy();
  1638. }
  1639. void Context::rendererCreateFragmentShader(FragmentShaderHandle _handle, Memory* _mem)
  1640. {
  1641. s_renderCtx.m_fragmentShaders[_handle.idx].create(GL_FRAGMENT_SHADER, _mem->data);
  1642. }
  1643. void Context::rendererDestroyFragmentShader(FragmentShaderHandle _handle)
  1644. {
  1645. s_renderCtx.m_fragmentShaders[_handle.idx].destroy();
  1646. }
  1647. void Context::rendererCreateMaterial(MaterialHandle _handle, VertexShaderHandle _vsh, FragmentShaderHandle _fsh)
  1648. {
  1649. s_renderCtx.m_materials[_handle.idx].create(s_renderCtx.m_vertexShaders[_vsh.idx], s_renderCtx.m_fragmentShaders[_fsh.idx]);
  1650. }
  1651. void Context::rendererDestroyMaterial(FragmentShaderHandle _handle)
  1652. {
  1653. s_renderCtx.m_materials[_handle.idx].destroy();
  1654. }
  1655. void Context::rendererCreateTexture(TextureHandle _handle, Memory* _mem, uint32_t _flags)
  1656. {
  1657. s_renderCtx.m_textures[_handle.idx].create(_mem, _flags);
  1658. }
  1659. void Context::rendererUpdateTexture(TextureHandle _handle, uint8_t _side, uint8_t _mip, const Rect& _rect, uint16_t _z, uint16_t _depth, const Memory* _mem)
  1660. {
  1661. s_renderCtx.m_textures[_handle.idx].update(_side, _mip, _rect, _z, _depth, _mem);
  1662. }
  1663. void Context::rendererDestroyTexture(TextureHandle _handle)
  1664. {
  1665. s_renderCtx.m_textures[_handle.idx].destroy();
  1666. }
  1667. void Context::rendererCreateRenderTarget(RenderTargetHandle _handle, uint16_t _width, uint16_t _height, uint32_t _flags, uint32_t _textureFlags)
  1668. {
  1669. s_renderCtx.m_renderTargets[_handle.idx].create(_width, _height, _flags, _textureFlags);
  1670. }
  1671. void Context::rendererDestroyRenderTarget(RenderTargetHandle _handle)
  1672. {
  1673. s_renderCtx.m_renderTargets[_handle.idx].destroy();
  1674. }
  1675. void Context::rendererCreateUniform(UniformHandle _handle, ConstantType::Enum _type, uint16_t _num, const char* _name)
  1676. {
  1677. uint32_t size = g_constantTypeSize[_type]*_num;
  1678. void* data = g_realloc(NULL, size);
  1679. memset(data, 0, size);
  1680. s_renderCtx.m_uniforms[_handle.idx] = data;
  1681. s_renderCtx.m_uniformReg.reg(_name, s_renderCtx.m_uniforms[_handle.idx]);
  1682. }
  1683. void Context::rendererDestroyUniform(UniformHandle _handle)
  1684. {
  1685. g_free(s_renderCtx.m_uniforms[_handle.idx]);
  1686. }
  1687. void Context::rendererSaveScreenShot(Memory* _mem)
  1688. {
  1689. s_renderCtx.saveScreenShot(_mem);
  1690. }
  1691. void Context::rendererUpdateUniform(uint16_t _loc, const void* _data, uint32_t _size)
  1692. {
  1693. memcpy(s_renderCtx.m_uniforms[_loc], _data, _size);
  1694. }
  1695. void Context::rendererSubmit()
  1696. {
  1697. s_renderCtx.updateResolution(m_render->m_resolution);
  1698. int64_t elapsed = -bx::getHPCounter();
  1699. #if BGFX_CONFIG_RENDERER_OPENGL
  1700. if (m_render->m_debug & (BGFX_DEBUG_IFH|BGFX_DEBUG_STATS) )
  1701. {
  1702. s_renderCtx.m_queries.begin(0, GL_TIME_ELAPSED);
  1703. }
  1704. #endif // BGFX_CONFIG_RENDERER_OPENGL
  1705. if (0 < m_render->m_iboffset)
  1706. {
  1707. TransientIndexBuffer* ib = m_render->m_transientIb;
  1708. s_renderCtx.m_indexBuffers[ib->handle.idx].update(0, m_render->m_iboffset, ib->data);
  1709. }
  1710. if (0 < m_render->m_vboffset)
  1711. {
  1712. TransientVertexBuffer* vb = m_render->m_transientVb;
  1713. s_renderCtx.m_vertexBuffers[vb->handle.idx].update(0, m_render->m_vboffset, vb->data);
  1714. }
  1715. m_render->sort();
  1716. RenderState currentState;
  1717. currentState.reset();
  1718. currentState.m_flags = BGFX_STATE_NONE;
  1719. Matrix4 viewProj[BGFX_CONFIG_MAX_VIEWS];
  1720. for (uint32_t ii = 0; ii < BGFX_CONFIG_MAX_VIEWS; ++ii)
  1721. {
  1722. matrix_mul(viewProj[ii].val, m_render->m_view[ii].val, m_render->m_proj[ii].val);
  1723. }
  1724. uint16_t materialIdx = invalidHandle;
  1725. SortKey key;
  1726. uint8_t view = 0xff;
  1727. RenderTargetHandle rt = BGFX_INVALID_HANDLE;
  1728. int32_t height = m_render->m_resolution.m_height;
  1729. float alphaRef = 0.0f;
  1730. GLenum primType = m_render->m_debug&BGFX_DEBUG_WIREFRAME ? GL_LINES : GL_TRIANGLES;
  1731. uint32_t primNumVerts = 3;
  1732. uint32_t baseVertex = 0;
  1733. GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, 0) );
  1734. uint32_t statsNumPrimsSubmitted = 0;
  1735. uint32_t statsNumIndices = 0;
  1736. uint32_t statsNumInstances = 0;
  1737. uint32_t statsNumPrimsRendered = 0;
  1738. if (0 == (m_render->m_debug&BGFX_DEBUG_IFH) )
  1739. {
  1740. for (uint32_t item = 0, numItems = m_render->m_num; item < numItems; ++item)
  1741. {
  1742. key.decode(m_render->m_sortKeys[item]);
  1743. const RenderState& state = m_render->m_renderState[m_render->m_sortValues[item] ];
  1744. const uint64_t newFlags = state.m_flags;
  1745. uint64_t changedFlags = currentState.m_flags ^ state.m_flags;
  1746. currentState.m_flags = newFlags;
  1747. if (key.m_view != view)
  1748. {
  1749. currentState.clear();
  1750. changedFlags = BGFX_STATE_MASK;
  1751. currentState.m_flags = newFlags;
  1752. GREMEDY_SETMARKER("view");
  1753. view = key.m_view;
  1754. materialIdx = invalidHandle;
  1755. if (m_render->m_rt[view].idx != rt.idx)
  1756. {
  1757. rt = m_render->m_rt[view];
  1758. if (rt.idx == invalidHandle)
  1759. {
  1760. GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, 0) );
  1761. height = m_render->m_resolution.m_height;
  1762. }
  1763. else
  1764. {
  1765. RenderTarget& renderTarget = s_renderCtx.m_renderTargets[rt.idx];
  1766. GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, renderTarget.m_fbo) );
  1767. height = renderTarget.m_height;
  1768. }
  1769. }
  1770. Rect& rect = m_render->m_rect[view];
  1771. GL_CHECK(glViewport(rect.m_x, height-rect.m_height-rect.m_y, rect.m_width, rect.m_height) );
  1772. Clear& clear = m_render->m_clear[view];
  1773. if (BGFX_CLEAR_NONE != clear.m_flags)
  1774. {
  1775. GLuint flags = 0;
  1776. if (BGFX_CLEAR_COLOR_BIT & clear.m_flags)
  1777. {
  1778. flags |= GL_COLOR_BUFFER_BIT;
  1779. uint32_t rgba = clear.m_rgba;
  1780. float rr = (rgba>>24)/255.0f;
  1781. float gg = ( (rgba>>16)&0xff)/255.0f;
  1782. float bb = ( (rgba>>8)&0xff)/255.0f;
  1783. float aa = (rgba&0xff)/255.0f;
  1784. GL_CHECK(glClearColor(rr, gg, bb, aa) );
  1785. GL_CHECK(glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE) );
  1786. }
  1787. if (BGFX_CLEAR_DEPTH_BIT & clear.m_flags)
  1788. {
  1789. flags |= GL_DEPTH_BUFFER_BIT;
  1790. GL_CHECK(glClearDepthf(clear.m_depth) );
  1791. GL_CHECK(glDepthMask(GL_TRUE) );
  1792. }
  1793. if (BGFX_CLEAR_STENCIL_BIT & clear.m_flags)
  1794. {
  1795. flags |= GL_STENCIL_BUFFER_BIT;
  1796. GL_CHECK(glClearStencil(clear.m_stencil) );
  1797. }
  1798. if (0 != flags)
  1799. {
  1800. GL_CHECK(glEnable(GL_SCISSOR_TEST) );
  1801. GL_CHECK(glScissor(rect.m_x, height-rect.m_height-rect.m_y, rect.m_width, rect.m_height) );
  1802. GL_CHECK(glClear(flags) );
  1803. GL_CHECK(glDisable(GL_SCISSOR_TEST) );
  1804. }
  1805. }
  1806. GL_CHECK(glEnable(GL_DEPTH_TEST) );
  1807. GL_CHECK(glDepthFunc(GL_LESS) );
  1808. GL_CHECK(glEnable(GL_CULL_FACE) );
  1809. GL_CHECK(glDisable(GL_BLEND) );
  1810. }
  1811. if ( (BGFX_STATE_CULL_MASK|BGFX_STATE_DEPTH_WRITE|BGFX_STATE_DEPTH_TEST_MASK
  1812. |BGFX_STATE_ALPHA_MASK|BGFX_STATE_ALPHA_WRITE|BGFX_STATE_RGB_WRITE
  1813. |BGFX_STATE_BLEND_MASK|BGFX_STATE_ALPHA_REF_MASK|BGFX_STATE_PT_MASK
  1814. |BGFX_STATE_POINT_SIZE_MASK) & changedFlags)
  1815. {
  1816. if (BGFX_STATE_CULL_MASK & changedFlags)
  1817. {
  1818. if (BGFX_STATE_CULL_CW & newFlags)
  1819. {
  1820. GL_CHECK(glEnable(GL_CULL_FACE) );
  1821. GL_CHECK(glCullFace(GL_BACK) );
  1822. }
  1823. else if (BGFX_STATE_CULL_CCW & newFlags)
  1824. {
  1825. GL_CHECK(glEnable(GL_CULL_FACE) );
  1826. GL_CHECK(glCullFace(GL_FRONT) );
  1827. }
  1828. else
  1829. {
  1830. GL_CHECK(glDisable(GL_CULL_FACE) );
  1831. }
  1832. }
  1833. if (BGFX_STATE_DEPTH_WRITE & changedFlags)
  1834. {
  1835. GL_CHECK(glDepthMask(!!(BGFX_STATE_DEPTH_WRITE & newFlags) ) );
  1836. }
  1837. if (BGFX_STATE_DEPTH_TEST_MASK & changedFlags)
  1838. {
  1839. uint32_t func = (newFlags&BGFX_STATE_DEPTH_TEST_MASK)>>BGFX_STATE_DEPTH_TEST_SHIFT;
  1840. if (0 != func)
  1841. {
  1842. GL_CHECK(glEnable(GL_DEPTH_TEST) );
  1843. GL_CHECK(glDepthFunc(s_depthFunc[func]) );
  1844. }
  1845. else
  1846. {
  1847. GL_CHECK(glDisable(GL_DEPTH_TEST) );
  1848. }
  1849. }
  1850. if ( (BGFX_STATE_ALPHA_TEST|BGFX_STATE_ALPHA_REF_MASK) & changedFlags)
  1851. {
  1852. uint32_t ref = (newFlags&BGFX_STATE_ALPHA_REF_MASK)>>BGFX_STATE_ALPHA_REF_SHIFT;
  1853. alphaRef = ref/255.0f;
  1854. #if BGFX_CONFIG_RENDERER_OPENGL
  1855. if (BGFX_STATE_ALPHA_TEST & newFlags)
  1856. {
  1857. GL_CHECK(glEnable(GL_ALPHA_TEST) );
  1858. }
  1859. else
  1860. {
  1861. GL_CHECK(glDisable(GL_ALPHA_TEST) );
  1862. }
  1863. #endif // BGFX_CONFIG_RENDERER_OPENGL
  1864. }
  1865. #if BGFX_CONFIG_RENDERER_OPENGL
  1866. if ( (BGFX_STATE_PT_POINTS|BGFX_STATE_POINT_SIZE_MASK) & changedFlags)
  1867. {
  1868. float pointSize = (float)(uint32_max(1, (newFlags&BGFX_STATE_POINT_SIZE_MASK)>>BGFX_STATE_POINT_SIZE_SHIFT) );
  1869. GL_CHECK(glPointSize(pointSize) );
  1870. }
  1871. #endif // BGFX_CONFIG_RENDERER_OPENGL
  1872. if ( (BGFX_STATE_ALPHA_WRITE|BGFX_STATE_RGB_WRITE) & changedFlags)
  1873. {
  1874. GLboolean alpha = !!(newFlags&BGFX_STATE_ALPHA_WRITE);
  1875. GLboolean rgb = !!(newFlags&BGFX_STATE_RGB_WRITE);
  1876. GL_CHECK(glColorMask(rgb, rgb, rgb, alpha) );
  1877. }
  1878. if (BGFX_STATE_BLEND_MASK & changedFlags)
  1879. {
  1880. if (BGFX_STATE_BLEND_MASK & newFlags)
  1881. {
  1882. uint32_t blend = (newFlags&BGFX_STATE_BLEND_MASK)>>BGFX_STATE_BLEND_SHIFT;
  1883. uint32_t src = blend&0xf;
  1884. uint32_t dst = (blend>>4)&0xf;
  1885. GL_CHECK(glEnable(GL_BLEND) );
  1886. GL_CHECK(glBlendFunc(s_blendFactor[src][0], s_blendFactor[dst][1]) );
  1887. }
  1888. else
  1889. {
  1890. GL_CHECK(glDisable(GL_BLEND) );
  1891. }
  1892. }
  1893. uint8_t primIndex = uint8_t( (newFlags&BGFX_STATE_PT_MASK)>>BGFX_STATE_PT_SHIFT);
  1894. primType = m_render->m_debug&BGFX_DEBUG_WIREFRAME ? GL_LINES : s_primType[primIndex];
  1895. primNumVerts = s_primNumVerts[primIndex];
  1896. }
  1897. bool materialChanged = false;
  1898. bool constantsChanged = state.m_constBegin < state.m_constEnd;
  1899. bool bindAttribs = false;
  1900. rendererUpdateUniforms(m_render->m_constantBuffer, state.m_constBegin, state.m_constEnd);
  1901. if (key.m_material != materialIdx)
  1902. {
  1903. materialIdx = key.m_material;
  1904. GLuint id = invalidHandle == materialIdx ? 0 : s_renderCtx.m_materials[materialIdx].m_id;
  1905. GL_CHECK(glUseProgram(id) );
  1906. materialChanged =
  1907. constantsChanged =
  1908. bindAttribs = true;
  1909. }
  1910. if (invalidHandle != materialIdx)
  1911. {
  1912. Material& material = s_renderCtx.m_materials[materialIdx];
  1913. if (constantsChanged)
  1914. {
  1915. material.m_constantBuffer->commit();
  1916. }
  1917. for (uint32_t ii = 0, num = material.m_numPredefined; ii < num; ++ii)
  1918. {
  1919. PredefinedUniform& predefined = material.m_predefined[ii];
  1920. switch (predefined.m_type)
  1921. {
  1922. case PredefinedUniform::ViewRect:
  1923. {
  1924. float rect[4];
  1925. rect[0] = m_render->m_rect[view].m_x;
  1926. rect[1] = m_render->m_rect[view].m_y;
  1927. rect[2] = m_render->m_rect[view].m_width;
  1928. rect[3] = m_render->m_rect[view].m_height;
  1929. GL_CHECK(glUniform4fv(predefined.m_loc
  1930. , 1
  1931. , &rect[0]
  1932. ) );
  1933. }
  1934. break;
  1935. case PredefinedUniform::ViewTexel:
  1936. {
  1937. float rect[4];
  1938. rect[0] = 1.0f/float(m_render->m_rect[view].m_width);
  1939. rect[1] = 1.0f/float(m_render->m_rect[view].m_height);
  1940. GL_CHECK(glUniform4fv(predefined.m_loc
  1941. , 1
  1942. , &rect[0]
  1943. ) );
  1944. }
  1945. break;
  1946. case PredefinedUniform::View:
  1947. {
  1948. GL_CHECK(glUniformMatrix4fv(predefined.m_loc
  1949. , 1
  1950. , GL_FALSE
  1951. , m_render->m_view[view].val
  1952. ) );
  1953. }
  1954. break;
  1955. case PredefinedUniform::ViewProj:
  1956. {
  1957. GL_CHECK(glUniformMatrix4fv(predefined.m_loc
  1958. , 1
  1959. , GL_FALSE
  1960. , viewProj[view].val
  1961. ) );
  1962. }
  1963. break;
  1964. case PredefinedUniform::Model:
  1965. {
  1966. const Matrix4& model = m_render->m_matrixCache.m_cache[state.m_matrix];
  1967. GL_CHECK(glUniformMatrix4fv(predefined.m_loc
  1968. , uint32_min(predefined.m_count, state.m_num)
  1969. , GL_FALSE
  1970. , model.val
  1971. ) );
  1972. }
  1973. break;
  1974. case PredefinedUniform::ModelViewProj:
  1975. {
  1976. Matrix4 modelViewProj;
  1977. const Matrix4& model = m_render->m_matrixCache.m_cache[state.m_matrix];
  1978. matrix_mul(modelViewProj.val, model.val, viewProj[view].val);
  1979. GL_CHECK(glUniformMatrix4fv(predefined.m_loc
  1980. , 1
  1981. , GL_FALSE
  1982. , modelViewProj.val
  1983. ) );
  1984. }
  1985. break;
  1986. case PredefinedUniform::ModelViewProjX:
  1987. {
  1988. const Matrix4& model = m_render->m_matrixCache.m_cache[state.m_matrix];
  1989. static const BX_ALIGN_STRUCT_16(float) s_bias[16] =
  1990. {
  1991. 0.5f, 0.0f, 0.0f, 0.0f,
  1992. 0.0f, 0.5f, 0.0f, 0.0f,
  1993. 0.0f, 0.0f, 0.5f, 0.0f,
  1994. 0.5f, 0.5f, 0.5f, 1.0f,
  1995. };
  1996. uint8_t other = m_render->m_other[view];
  1997. Matrix4 viewProjBias;
  1998. matrix_mul(viewProjBias.val, viewProj[other].val, s_bias);
  1999. Matrix4 modelViewProj;
  2000. matrix_mul(modelViewProj.val, model.val, viewProjBias.val);
  2001. GL_CHECK(glUniformMatrix4fv(predefined.m_loc
  2002. , 1
  2003. , GL_FALSE
  2004. , modelViewProj.val
  2005. ) );
  2006. }
  2007. break;
  2008. case PredefinedUniform::ViewProjX:
  2009. {
  2010. static const BX_ALIGN_STRUCT_16(float) s_bias[16] =
  2011. {
  2012. 0.5f, 0.0f, 0.0f, 0.0f,
  2013. 0.0f, 0.5f, 0.0f, 0.0f,
  2014. 0.0f, 0.0f, 0.5f, 0.0f,
  2015. 0.5f, 0.5f, 0.5f, 1.0f,
  2016. };
  2017. uint8_t other = m_render->m_other[view];
  2018. Matrix4 viewProjBias;
  2019. matrix_mul(viewProjBias.val, viewProj[other].val, s_bias);
  2020. GL_CHECK(glUniformMatrix4fv(predefined.m_loc
  2021. , 1
  2022. , GL_FALSE
  2023. , viewProjBias.val
  2024. ) );
  2025. }
  2026. break;
  2027. case PredefinedUniform::AlphaRef:
  2028. {
  2029. GL_CHECK(glUniform1f(predefined.m_loc, alphaRef) );
  2030. }
  2031. break;
  2032. case PredefinedUniform::Count:
  2033. break;
  2034. }
  2035. }
  2036. // if (BGFX_STATE_TEX_MASK & changedFlags)
  2037. {
  2038. uint64_t flag = BGFX_STATE_TEX0;
  2039. for (uint32_t stage = 0; stage < BGFX_STATE_TEX_COUNT; ++stage)
  2040. {
  2041. const Sampler& sampler = state.m_sampler[stage];
  2042. Sampler& current = currentState.m_sampler[stage];
  2043. if (current.m_idx != sampler.m_idx
  2044. || current.m_flags != sampler.m_flags
  2045. || materialChanged)
  2046. {
  2047. if (invalidHandle != sampler.m_idx)
  2048. {
  2049. GL_CHECK(glActiveTexture(GL_TEXTURE0+stage) );
  2050. switch (sampler.m_flags&BGFX_SAMPLER_TYPE_MASK)
  2051. {
  2052. case BGFX_SAMPLER_TEXTURE:
  2053. {
  2054. const Texture& texture = s_renderCtx.m_textures[sampler.m_idx];
  2055. GL_CHECK(glBindTexture(texture.m_target, texture.m_id) );
  2056. }
  2057. break;
  2058. case BGFX_SAMPLER_RENDERTARGET_COLOR:
  2059. {
  2060. const RenderTarget& rt = s_renderCtx.m_renderTargets[sampler.m_idx];
  2061. GL_CHECK(glBindTexture(rt.m_color.m_target, rt.m_color.m_id) );
  2062. }
  2063. break;
  2064. case BGFX_SAMPLER_RENDERTARGET_DEPTH:
  2065. {
  2066. const RenderTarget& rt = s_renderCtx.m_renderTargets[sampler.m_idx];
  2067. GL_CHECK(glBindTexture(rt.m_depth.m_target, rt.m_depth.m_id) );
  2068. }
  2069. break;
  2070. }
  2071. }
  2072. }
  2073. current = sampler;
  2074. flag <<= 1;
  2075. }
  2076. }
  2077. if (currentState.m_vertexBuffer.idx != state.m_vertexBuffer.idx || materialChanged)
  2078. {
  2079. currentState.m_vertexBuffer = state.m_vertexBuffer;
  2080. uint16_t handle = state.m_vertexBuffer.idx;
  2081. if (invalidHandle != handle)
  2082. {
  2083. VertexBuffer& vb = s_renderCtx.m_vertexBuffers[handle];
  2084. GL_CHECK(glBindBuffer(GL_ARRAY_BUFFER, vb.m_id) );
  2085. bindAttribs = true;
  2086. }
  2087. else
  2088. {
  2089. GL_CHECK(glBindBuffer(GL_ARRAY_BUFFER, 0) );
  2090. }
  2091. }
  2092. if (currentState.m_indexBuffer.idx != state.m_indexBuffer.idx)
  2093. {
  2094. currentState.m_indexBuffer = state.m_indexBuffer;
  2095. uint16_t handle = state.m_indexBuffer.idx;
  2096. if (invalidHandle != handle)
  2097. {
  2098. IndexBuffer& ib = s_renderCtx.m_indexBuffers[handle];
  2099. GL_CHECK(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ib.m_id) );
  2100. }
  2101. else
  2102. {
  2103. GL_CHECK(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0) );
  2104. }
  2105. }
  2106. if (invalidHandle != currentState.m_vertexBuffer.idx)
  2107. {
  2108. if (baseVertex != state.m_startVertex
  2109. || bindAttribs)
  2110. {
  2111. baseVertex = state.m_startVertex;
  2112. VertexBuffer& vb = s_renderCtx.m_vertexBuffers[state.m_vertexBuffer.idx];
  2113. uint16_t decl = vb.m_decl.idx == invalidHandle ? state.m_vertexDecl.idx : vb.m_decl.idx;
  2114. const Material& material = s_renderCtx.m_materials[materialIdx];
  2115. material.bindAttributes(s_renderCtx.m_vertexDecls[decl], state.m_startVertex);
  2116. if (invalidHandle != state.m_instanceDataBuffer.idx)
  2117. {
  2118. GL_CHECK(glBindBuffer(GL_ARRAY_BUFFER, s_renderCtx.m_vertexBuffers[state.m_instanceDataBuffer.idx].m_id) );
  2119. material.bindInstanceData(state.m_instanceDataStride, state.m_instanceDataOffset);
  2120. }
  2121. }
  2122. uint32_t numIndices = 0;
  2123. uint32_t numPrimsSubmitted = 0;
  2124. uint32_t numInstances = 0;
  2125. uint32_t numPrimsRendered = 0;
  2126. if (invalidHandle != state.m_indexBuffer.idx)
  2127. {
  2128. if (BGFX_DRAW_WHOLE_INDEX_BUFFER == state.m_startIndex)
  2129. {
  2130. numIndices = s_renderCtx.m_indexBuffers[state.m_indexBuffer.idx].m_size/2;
  2131. numPrimsSubmitted = numIndices/primNumVerts;
  2132. numInstances = state.m_numInstances;
  2133. numPrimsRendered = numPrimsSubmitted*state.m_numInstances;
  2134. GL_CHECK(s_drawElementsInstanced(primType
  2135. , numIndices
  2136. , GL_UNSIGNED_SHORT
  2137. , (void*)0
  2138. , state.m_numInstances
  2139. ) );
  2140. }
  2141. else if (primNumVerts <= state.m_numIndices)
  2142. {
  2143. numIndices = state.m_numIndices;
  2144. numPrimsSubmitted = numIndices/primNumVerts;
  2145. numInstances = state.m_numInstances;
  2146. numPrimsRendered = numPrimsSubmitted*state.m_numInstances;
  2147. GL_CHECK(s_drawElementsInstanced(primType
  2148. , numIndices
  2149. , GL_UNSIGNED_SHORT
  2150. , (void*)(uintptr_t)(state.m_startIndex*2)
  2151. , state.m_numInstances
  2152. ) );
  2153. }
  2154. }
  2155. else
  2156. {
  2157. numPrimsSubmitted = state.m_numVertices/primNumVerts;
  2158. numInstances = state.m_numInstances;
  2159. numPrimsRendered = numPrimsSubmitted*state.m_numInstances;
  2160. GL_CHECK(s_drawArraysInstanced(primType
  2161. , 0
  2162. , state.m_numVertices
  2163. , state.m_numInstances
  2164. ) );
  2165. }
  2166. statsNumPrimsSubmitted += numPrimsSubmitted;
  2167. statsNumIndices += numIndices;
  2168. statsNumInstances += numInstances;
  2169. statsNumPrimsRendered += numPrimsRendered;
  2170. }
  2171. }
  2172. }
  2173. }
  2174. int64_t now = bx::getHPCounter();
  2175. elapsed += now;
  2176. static int64_t last = now;
  2177. int64_t frameTime = now - last;
  2178. last = now;
  2179. static int64_t min = frameTime;
  2180. static int64_t max = frameTime;
  2181. min = min > frameTime ? frameTime : min;
  2182. max = max < frameTime ? frameTime : max;
  2183. if (m_render->m_debug & (BGFX_DEBUG_IFH|BGFX_DEBUG_STATS) )
  2184. {
  2185. double elapsedGpuMs = 0.0;
  2186. #if BGFX_CONFIG_RENDERER_OPENGL
  2187. s_renderCtx.m_queries.end(GL_TIME_ELAPSED);
  2188. uint64_t elapsedGl = s_renderCtx.m_queries.getResult(0);
  2189. elapsedGpuMs = double(elapsedGl)/1e6;
  2190. #endif // BGFX_CONFIG_RENDERER_OPENGL
  2191. TextVideoMem& tvm = s_renderCtx.m_textVideoMem;
  2192. static int64_t next = now;
  2193. if (now >= next)
  2194. {
  2195. next = now + bx::getHPFrequency();
  2196. double freq = double(bx::getHPFrequency() );
  2197. double toMs = 1000.0/freq;
  2198. double elapsedCpuMs = double(elapsed)*toMs;
  2199. tvm.clear();
  2200. uint16_t pos = 10;
  2201. tvm.printf(0, 0, 0x8f, " " BGFX_RENDERER_NAME " ");
  2202. tvm.printf(10, pos++, 0x8e, " Frame CPU: %7.3f, % 7.3f \x1f, % 7.3f \x1e [ms] / % 6.2f FPS"
  2203. , double(frameTime)*toMs
  2204. , double(min)*toMs
  2205. , double(max)*toMs
  2206. , freq/frameTime
  2207. );
  2208. tvm.printf(10, pos++, 0x8e, " Draw calls: %4d / CPU %3.4f [ms] %c GPU %3.4f [ms]"
  2209. , m_render->m_num
  2210. , elapsedCpuMs
  2211. , elapsedCpuMs > elapsedGpuMs ? '>' : '<'
  2212. , elapsedGpuMs
  2213. );
  2214. tvm.printf(10, pos++, 0x8e, " Prims: %7d (#inst: %5d), submitted: %7d"
  2215. , statsNumPrimsRendered
  2216. , statsNumInstances
  2217. , statsNumPrimsSubmitted
  2218. );
  2219. tvm.printf(10, pos++, 0x8e, " Indices: %7d", statsNumIndices);
  2220. tvm.printf(10, pos++, 0x8e, " DVB size: %7d", m_render->m_vboffset);
  2221. tvm.printf(10, pos++, 0x8e, " DIB size: %7d", m_render->m_iboffset);
  2222. #if BGFX_CONFIG_RENDERER_OPENGL
  2223. if (s_extension[Extension::ATI_meminfo].m_supported)
  2224. {
  2225. GLint vboFree[4];
  2226. GL_CHECK(glGetIntegerv(GL_VBO_FREE_MEMORY_ATI, vboFree) );
  2227. GLint texFree[4];
  2228. GL_CHECK(glGetIntegerv(GL_TEXTURE_FREE_MEMORY_ATI, texFree) );
  2229. GLint rbfFree[4];
  2230. GL_CHECK(glGetIntegerv(GL_RENDERBUFFER_FREE_MEMORY_ATI, rbfFree) );
  2231. pos++;
  2232. tvm.printf(10, pos++, 0x8c, " -------------| free| free b| aux| aux fb");
  2233. tvm.printf(10, pos++, 0x8e, " VBO: %7d, %7d, %7d, %7d", vboFree[0], vboFree[1], vboFree[2], vboFree[3]);
  2234. tvm.printf(10, pos++, 0x8e, " Texture: %7d, %7d, %7d, %7d", texFree[0], texFree[1], texFree[2], texFree[3]);
  2235. tvm.printf(10, pos++, 0x8e, " Render Buffer: %7d, %7d, %7d, %7d", rbfFree[0], rbfFree[1], rbfFree[2], rbfFree[3]);
  2236. }
  2237. else if (s_extension[Extension::NVX_gpu_memory_info].m_supported)
  2238. {
  2239. GLint dedicated;
  2240. GL_CHECK(glGetIntegerv(GL_GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX, &dedicated) );
  2241. GLint totalAvail;
  2242. GL_CHECK(glGetIntegerv(GL_GPU_MEMORY_INFO_TOTAL_AVAILABLE_MEMORY_NVX, &totalAvail) );
  2243. GLint currAvail;
  2244. GL_CHECK(glGetIntegerv(GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX, &currAvail) );
  2245. GLint evictedCount;
  2246. GL_CHECK(glGetIntegerv(GL_GPU_MEMORY_INFO_EVICTION_COUNT_NVX, &evictedCount) );
  2247. GLint evictedMemory;
  2248. GL_CHECK(glGetIntegerv(GL_GPU_MEMORY_INFO_EVICTED_MEMORY_NVX, &evictedMemory) );
  2249. pos++;
  2250. tvm.printf(10, pos++, 0x8c, "----------|");
  2251. tvm.printf(10, pos++, 0x8e, " Dedicated: %7d", dedicated);
  2252. tvm.printf(10, pos++, 0x8e, " Available: %7d (%7d)", currAvail, totalAvail);
  2253. tvm.printf(10, pos++, 0x8e, " Eviction: %7d / %7d", evictedCount, evictedMemory);
  2254. }
  2255. #endif // BGFX_CONFIG_RENDERER_OPENGL
  2256. uint8_t attr[2] = { 0x89, 0x8a };
  2257. uint8_t attrIndex = m_render->m_waitSubmit < m_render->m_waitRender;
  2258. pos++;
  2259. tvm.printf(10, pos++, attr[attrIndex&1], "Submit wait: %3.4f [ms]", double(m_render->m_waitSubmit)*toMs);
  2260. tvm.printf(10, pos++, attr[(attrIndex+1)&1], "Render wait: %3.4f [ms]", double(m_render->m_waitRender)*toMs);
  2261. min = frameTime;
  2262. max = frameTime;
  2263. }
  2264. m_textVideoMemBlitter.blit(tvm);
  2265. }
  2266. else if (m_render->m_debug & BGFX_DEBUG_TEXT)
  2267. {
  2268. m_textVideoMemBlitter.blit(m_render->m_textVideoMem);
  2269. }
  2270. GREMEDY_FRAMETERMINATOR();
  2271. }
  2272. }
  2273. #endif // (BGFX_CONFIG_RENDERER_OPENGLES|BGFX_CONFIG_RENDERER_OPENGL)