mesa-22.2.4-add_xdemos-1.patch 101 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198
  1. Submitted By: DJ Lucas <dj@linuxfromscratch.org>
  2. based on previous patches submitted
  3. by Armin K and Fernando de Oliveira
  4. Date: 2020-10-16
  5. Initial Package Version: 19.0.4
  6. Upstream Status: Not applicable.
  7. Origin: Self.
  8. Description: This patch adds two OpenGL demos, glxinfo and
  9. glxgears and respective man pages.
  10. diff -Naurp mesa-20.2.1-orig/src/glx/meson.build mesa-20.2.1/src/glx/meson.build
  11. --- mesa-20.2.1-orig/src/glx/meson.build 2020-10-14 12:19:10.623185200 -0500
  12. +++ mesa-20.2.1/src/glx/meson.build 2020-10-15 23:06:45.823362439 -0500
  13. @@ -165,6 +165,8 @@ libgl = shared_library(
  14. install : true,
  15. )
  16. +subdir('xdemos')
  17. +
  18. if with_tests
  19. subdir('tests')
  20. endif
  21. diff -Naurp mesa-20.2.1-orig/src/glx/xdemos/glinfo_common.c mesa-20.2.1/src/glx/xdemos/glinfo_common.c
  22. --- mesa-20.2.1-orig/src/glx/xdemos/glinfo_common.c 1969-12-31 18:00:00.000000000 -0600
  23. +++ mesa-20.2.1/src/glx/xdemos/glinfo_common.c 2020-10-15 23:06:45.826695773 -0500
  24. @@ -0,0 +1,800 @@
  25. +/*
  26. + * Copyright (C) 1999-2014 Brian Paul All Rights Reserved.
  27. + *
  28. + * Permission is hereby granted, free of charge, to any person obtaining a
  29. + * copy of this software and associated documentation files (the "Software"),
  30. + * to deal in the Software without restriction, including without limitation
  31. + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  32. + * and/or sell copies of the Software, and to permit persons to whom the
  33. + * Software is furnished to do so, subject to the following conditions:
  34. + *
  35. + * The above copyright notice and this permission notice shall be included
  36. + * in all copies or substantial portions of the Software.
  37. + *
  38. + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  39. + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  40. + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  41. + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
  42. + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  43. + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  44. + */
  45. +
  46. +#include <assert.h>
  47. +#include <ctype.h>
  48. +#include <stdio.h>
  49. +#include <stdlib.h>
  50. +#include <string.h>
  51. +#include "glinfo_common.h"
  52. +
  53. +#ifdef _WIN32
  54. +#define snprintf _snprintf
  55. +#endif
  56. +
  57. +
  58. +/**
  59. + * Return the GL enum name for a numeric value.
  60. + * We really only care about the compressed texture formats for now.
  61. + */
  62. +static const char *
  63. +enum_name(GLenum val)
  64. +{
  65. + static const struct {
  66. + const char *name;
  67. + GLenum val;
  68. + } enums [] = {
  69. + { "GL_COMPRESSED_ALPHA", 0x84E9 },
  70. + { "GL_COMPRESSED_LUMINANCE", 0x84EA },
  71. + { "GL_COMPRESSED_LUMINANCE_ALPHA", 0x84EB },
  72. + { "GL_COMPRESSED_INTENSITY", 0x84EC },
  73. + { "GL_COMPRESSED_RGB", 0x84ED },
  74. + { "GL_COMPRESSED_RGBA", 0x84EE },
  75. + { "GL_COMPRESSED_TEXTURE_FORMATS", 0x86A3 },
  76. + { "GL_COMPRESSED_RGB", 0x84ED },
  77. + { "GL_COMPRESSED_RGBA", 0x84EE },
  78. + { "GL_COMPRESSED_TEXTURE_FORMATS", 0x86A3 },
  79. + { "GL_COMPRESSED_ALPHA", 0x84E9 },
  80. + { "GL_COMPRESSED_LUMINANCE", 0x84EA },
  81. + { "GL_COMPRESSED_LUMINANCE_ALPHA", 0x84EB },
  82. + { "GL_COMPRESSED_INTENSITY", 0x84EC },
  83. + { "GL_COMPRESSED_SRGB", 0x8C48 },
  84. + { "GL_COMPRESSED_SRGB_ALPHA", 0x8C49 },
  85. + { "GL_COMPRESSED_SLUMINANCE", 0x8C4A },
  86. + { "GL_COMPRESSED_SLUMINANCE_ALPHA", 0x8C4B },
  87. + { "GL_COMPRESSED_RED", 0x8225 },
  88. + { "GL_COMPRESSED_RG", 0x8226 },
  89. + { "GL_COMPRESSED_RED_RGTC1", 0x8DBB },
  90. + { "GL_COMPRESSED_SIGNED_RED_RGTC1", 0x8DBC },
  91. + { "GL_COMPRESSED_RG_RGTC2", 0x8DBD },
  92. + { "GL_COMPRESSED_SIGNED_RG_RGTC2", 0x8DBE },
  93. + { "GL_COMPRESSED_RGB8_ETC2", 0x9274 },
  94. + { "GL_COMPRESSED_SRGB8_ETC2", 0x9275 },
  95. + { "GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2", 0x9276 },
  96. + { "GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2", 0x9277 },
  97. + { "GL_COMPRESSED_RGBA8_ETC2_EAC", 0x9278 },
  98. + { "GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC", 0x9279 },
  99. + { "GL_COMPRESSED_R11_EAC", 0x9270 },
  100. + { "GL_COMPRESSED_SIGNED_R11_EAC", 0x9271 },
  101. + { "GL_COMPRESSED_RG11_EAC", 0x9272 },
  102. + { "GL_COMPRESSED_SIGNED_RG11_EAC", 0x9273 },
  103. + { "GL_COMPRESSED_ALPHA_ARB", 0x84E9 },
  104. + { "GL_COMPRESSED_LUMINANCE_ARB", 0x84EA },
  105. + { "GL_COMPRESSED_LUMINANCE_ALPHA_ARB", 0x84EB },
  106. + { "GL_COMPRESSED_INTENSITY_ARB", 0x84EC },
  107. + { "GL_COMPRESSED_RGB_ARB", 0x84ED },
  108. + { "GL_COMPRESSED_RGBA_ARB", 0x84EE },
  109. + { "GL_COMPRESSED_TEXTURE_FORMATS_ARB", 0x86A3 },
  110. + { "GL_COMPRESSED_RGBA_BPTC_UNORM_ARB", 0x8E8C },
  111. + { "GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB", 0x8E8D },
  112. + { "GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB", 0x8E8E },
  113. + { "GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB", 0x8E8F },
  114. + { "GL_COMPRESSED_RGBA_ASTC_4x4_KHR", 0x93B0 },
  115. + { "GL_COMPRESSED_RGBA_ASTC_5x4_KHR", 0x93B1 },
  116. + { "GL_COMPRESSED_RGBA_ASTC_5x5_KHR", 0x93B2 },
  117. + { "GL_COMPRESSED_RGBA_ASTC_6x5_KHR", 0x93B3 },
  118. + { "GL_COMPRESSED_RGBA_ASTC_6x6_KHR", 0x93B4 },
  119. + { "GL_COMPRESSED_RGBA_ASTC_8x5_KHR", 0x93B5 },
  120. + { "GL_COMPRESSED_RGBA_ASTC_8x6_KHR", 0x93B6 },
  121. + { "GL_COMPRESSED_RGBA_ASTC_8x8_KHR", 0x93B7 },
  122. + { "GL_COMPRESSED_RGBA_ASTC_10x5_KHR", 0x93B8 },
  123. + { "GL_COMPRESSED_RGBA_ASTC_10x6_KHR", 0x93B9 },
  124. + { "GL_COMPRESSED_RGBA_ASTC_10x8_KHR", 0x93BA },
  125. + { "GL_COMPRESSED_RGBA_ASTC_10x10_KHR", 0x93BB },
  126. + { "GL_COMPRESSED_RGBA_ASTC_12x10_KHR", 0x93BC },
  127. + { "GL_COMPRESSED_RGBA_ASTC_12x12_KHR", 0x93BD },
  128. + { "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR", 0x93D0 },
  129. + { "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR", 0x93D1 },
  130. + { "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR", 0x93D2 },
  131. + { "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR", 0x93D3 },
  132. + { "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR", 0x93D4 },
  133. + { "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR", 0x93D5 },
  134. + { "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR", 0x93D6 },
  135. + { "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR", 0x93D7 },
  136. + { "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR", 0x93D8 },
  137. + { "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR", 0x93D9 },
  138. + { "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR", 0x93DA },
  139. + { "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR", 0x93DB },
  140. + { "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR", 0x93DC },
  141. + { "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR", 0x93DD },
  142. + { "GL_COMPRESSED_RGB_FXT1_3DFX", 0x86B0 },
  143. + { "GL_COMPRESSED_RGBA_FXT1_3DFX", 0x86B1 },
  144. + { "GL_COMPRESSED_LUMINANCE_LATC1_EXT", 0x8C70 },
  145. + { "GL_COMPRESSED_SIGNED_LUMINANCE_LATC1_EXT", 0x8C71 },
  146. + { "GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT", 0x8C72 },
  147. + { "GL_COMPRESSED_SIGNED_LUMINANCE_ALPHA_LATC2_EXT", 0x8C73 },
  148. + { "GL_COMPRESSED_RED_RGTC1_EXT", 0x8DBB },
  149. + { "GL_COMPRESSED_SIGNED_RED_RGTC1_EXT", 0x8DBC },
  150. + { "GL_COMPRESSED_RED_GREEN_RGTC2_EXT", 0x8DBD },
  151. + { "GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT", 0x8DBE },
  152. + { "GL_COMPRESSED_RGB_S3TC_DXT1_EXT", 0x83F0 },
  153. + { "GL_COMPRESSED_RGBA_S3TC_DXT1_EXT", 0x83F1 },
  154. + { "GL_COMPRESSED_RGBA_S3TC_DXT3_EXT", 0x83F2 },
  155. + { "GL_COMPRESSED_RGBA_S3TC_DXT5_EXT", 0x83F3 },
  156. + { "GL_COMPRESSED_SRGB_EXT", 0x8C48 },
  157. + { "GL_COMPRESSED_SRGB_ALPHA_EXT", 0x8C49 },
  158. + { "GL_COMPRESSED_SLUMINANCE_EXT", 0x8C4A },
  159. + { "GL_COMPRESSED_SLUMINANCE_ALPHA_EXT", 0x8C4B },
  160. + { "GL_COMPRESSED_SRGB_S3TC_DXT1_EXT", 0x8C4C },
  161. + { "GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT", 0x8C4D },
  162. + { "GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT", 0x8C4E },
  163. + { "GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT", 0x8C4F },
  164. + { "GL_PALETTE4_RGB8_OES", 0x8B90 },
  165. + { "GL_PALETTE4_RGBA8_OES", 0x8B91 },
  166. + { "GL_PALETTE4_R5_G6_B5_OES", 0x8B92 },
  167. + { "GL_PALETTE4_RGBA4_OES", 0x8B93 },
  168. + { "GL_PALETTE4_RGB5_A1_OES", 0x8B94 },
  169. + { "GL_PALETTE8_RGB8_OES", 0x8B95 },
  170. + { "GL_PALETTE8_RGBA8_OES", 0x8B96 },
  171. + { "GL_PALETTE8_R5_G6_B5_OES", 0x8B97 },
  172. + { "GL_PALETTE8_RGBA4_OES", 0x8B98 },
  173. + { "GL_PALETTE8_RGB5_A1_OES", 0x8B99 }
  174. + };
  175. + const int n = sizeof(enums) / sizeof(enums[0]);
  176. + static char buffer[100];
  177. + int i;
  178. + for (i = 0; i < n; i++) {
  179. + if (enums[i].val == val) {
  180. + return enums[i].name;
  181. + }
  182. + }
  183. + /* enum val not found, just print hexadecimal value into static buffer */
  184. + snprintf(buffer, sizeof(buffer), "0x%x", val);
  185. + return buffer;
  186. +}
  187. +
  188. +
  189. +/*
  190. + * qsort callback for string comparison.
  191. + */
  192. +static int
  193. +compare_string_ptr(const void *p1, const void *p2)
  194. +{
  195. + return strcmp(* (char * const *) p1, * (char * const *) p2);
  196. +}
  197. +
  198. +/*
  199. + * Print a list of extensions, with word-wrapping.
  200. + */
  201. +void
  202. +print_extension_list(const char *ext, GLboolean singleLine)
  203. +{
  204. + char **extensions;
  205. + int num_extensions;
  206. + const char *indentString = " ";
  207. + const int indent = 4;
  208. + const int max = 79;
  209. + int width, i, j, k;
  210. +
  211. + if (!ext || !ext[0])
  212. + return;
  213. +
  214. + /* count the number of extensions, ignoring successive spaces */
  215. + num_extensions = 0;
  216. + j = 1;
  217. + do {
  218. + if ((ext[j] == ' ' || ext[j] == 0) && ext[j - 1] != ' ') {
  219. + ++num_extensions;
  220. + }
  221. + } while(ext[j++]);
  222. +
  223. + /* copy individual extensions to an array */
  224. + extensions = malloc(num_extensions * sizeof *extensions);
  225. + if (!extensions) {
  226. + fprintf(stderr, "Error: malloc() failed\n");
  227. + exit(1);
  228. + }
  229. + i = j = k = 0;
  230. + while (1) {
  231. + if (ext[j] == ' ' || ext[j] == 0) {
  232. + /* found end of an extension name */
  233. + const int len = j - i;
  234. +
  235. + if (len) {
  236. + assert(k < num_extensions);
  237. +
  238. + extensions[k] = malloc(len + 1);
  239. + if (!extensions[k]) {
  240. + fprintf(stderr, "Error: malloc() failed\n");
  241. + exit(1);
  242. + }
  243. +
  244. + memcpy(extensions[k], ext + i, len);
  245. + extensions[k][len] = 0;
  246. +
  247. + ++k;
  248. + };
  249. +
  250. + i += len + 1;
  251. +
  252. + if (ext[j] == 0) {
  253. + break;
  254. + }
  255. + }
  256. + j++;
  257. + }
  258. + assert(k == num_extensions);
  259. +
  260. + /* sort extensions alphabetically */
  261. + qsort(extensions, num_extensions, sizeof extensions[0], compare_string_ptr);
  262. +
  263. + /* print the extensions */
  264. + width = indent;
  265. + printf("%s", indentString);
  266. + for (k = 0; k < num_extensions; ++k) {
  267. + const int len = strlen(extensions[k]);
  268. + if ((!singleLine) && (width + len > max)) {
  269. + /* start a new line */
  270. + printf("\n");
  271. + width = indent;
  272. + printf("%s", indentString);
  273. + }
  274. + /* print the extension name */
  275. + printf("%s", extensions[k]);
  276. +
  277. + /* either we're all done, or we'll continue with next extension */
  278. + width += len + 1;
  279. +
  280. + if (singleLine) {
  281. + printf("\n");
  282. + width = indent;
  283. + printf("%s", indentString);
  284. + }
  285. + else if (k < (num_extensions -1)) {
  286. + printf(", ");
  287. + width += 2;
  288. + }
  289. + }
  290. + printf("\n");
  291. +
  292. + for (k = 0; k < num_extensions; ++k) {
  293. + free(extensions[k]);
  294. + }
  295. + free(extensions);
  296. +}
  297. +
  298. +
  299. +
  300. +
  301. +/**
  302. + * Get list of OpenGL extensions using core profile's glGetStringi().
  303. + */
  304. +char *
  305. +build_core_profile_extension_list(const struct ext_functions *extfuncs)
  306. +{
  307. + GLint i, n, totalLen;
  308. + char *buffer;
  309. +
  310. + glGetIntegerv(GL_NUM_EXTENSIONS, &n);
  311. +
  312. + /* compute totalLen */
  313. + totalLen = 0;
  314. + for (i = 0; i < n; i++) {
  315. + const char *ext = (const char *) extfuncs->GetStringi(GL_EXTENSIONS, i);
  316. + if (ext)
  317. + totalLen += strlen(ext) + 1; /* plus a space */
  318. + }
  319. +
  320. + if (!totalLen)
  321. + return NULL;
  322. +
  323. + buffer = malloc(totalLen + 1);
  324. + if (buffer) {
  325. + int pos = 0;
  326. + for (i = 0; i < n; i++) {
  327. + const char *ext = (const char *) extfuncs->GetStringi(GL_EXTENSIONS, i);
  328. + strcpy(buffer + pos, ext);
  329. + pos += strlen(ext);
  330. + buffer[pos++] = ' ';
  331. + }
  332. + buffer[pos] = '\0';
  333. + }
  334. + return buffer;
  335. +}
  336. +
  337. +
  338. +/** Is extension 'ext' supported? */
  339. +GLboolean
  340. +extension_supported(const char *ext, const char *extensionsList)
  341. +{
  342. + while (1) {
  343. + const char *p = strstr(extensionsList, ext);
  344. + if (p) {
  345. + /* check that next char is a space or end of string */
  346. + int extLen = strlen(ext);
  347. + if (p[extLen] == 0 || p[extLen] == ' ') {
  348. + return 1;
  349. + }
  350. + else {
  351. + /* We found a superset string, keep looking */
  352. + extensionsList += extLen;
  353. + }
  354. + }
  355. + else {
  356. + break;
  357. + }
  358. + }
  359. + return 0;
  360. +}
  361. +
  362. +
  363. +/**
  364. + * Is verNum >= verString?
  365. + * \param verString such as "2.1", "3.0", etc.
  366. + * \param verNum such as 20, 21, 30, 31, 32, etc.
  367. + */
  368. +static GLboolean
  369. +version_supported(const char *verString, int verNum)
  370. +{
  371. + int v;
  372. +
  373. + if (!verString ||
  374. + !isdigit(verString[0]) ||
  375. + verString[1] != '.' ||
  376. + !isdigit(verString[2])) {
  377. + return GL_FALSE;
  378. + }
  379. +
  380. + v = (verString[0] - '0') * 10 + (verString[2] - '0');
  381. +
  382. + return verNum >= v;
  383. +}
  384. +
  385. +
  386. +struct token_name
  387. +{
  388. + GLenum token;
  389. + const char *name;
  390. +};
  391. +
  392. +
  393. +static void
  394. +print_shader_limit_list(const struct token_name *lim)
  395. +{
  396. + GLint max[1];
  397. + unsigned i;
  398. +
  399. + for (i = 0; lim[i].token; i++) {
  400. + glGetIntegerv(lim[i].token, max);
  401. + if (glGetError() == GL_NO_ERROR) {
  402. + printf(" %s = %d\n", lim[i].name, max[0]);
  403. + }
  404. + }
  405. +}
  406. +
  407. +
  408. +/**
  409. + * Print interesting limits for vertex/fragment shaders.
  410. + */
  411. +static void
  412. +print_shader_limits(GLenum target)
  413. +{
  414. + static const struct token_name vertex_limits[] = {
  415. + { GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB, "GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB" },
  416. + { GL_MAX_VARYING_FLOATS_ARB, "GL_MAX_VARYING_FLOATS_ARB" },
  417. + { GL_MAX_VERTEX_ATTRIBS_ARB, "GL_MAX_VERTEX_ATTRIBS_ARB" },
  418. + { GL_MAX_TEXTURE_IMAGE_UNITS_ARB, "GL_MAX_TEXTURE_IMAGE_UNITS_ARB" },
  419. + { GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB, "GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB" },
  420. + { GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB, "GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB" },
  421. + { GL_MAX_TEXTURE_COORDS_ARB, "GL_MAX_TEXTURE_COORDS_ARB" },
  422. + { GL_MAX_VERTEX_OUTPUT_COMPONENTS , "GL_MAX_VERTEX_OUTPUT_COMPONENTS " },
  423. + { (GLenum) 0, NULL }
  424. + };
  425. + static const struct token_name fragment_limits[] = {
  426. + { GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB, "GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB" },
  427. + { GL_MAX_TEXTURE_COORDS_ARB, "GL_MAX_TEXTURE_COORDS_ARB" },
  428. + { GL_MAX_TEXTURE_IMAGE_UNITS_ARB, "GL_MAX_TEXTURE_IMAGE_UNITS_ARB" },
  429. + { GL_MAX_FRAGMENT_INPUT_COMPONENTS , "GL_MAX_FRAGMENT_INPUT_COMPONENTS " },
  430. + { (GLenum) 0, NULL }
  431. + };
  432. + static const struct token_name geometry_limits[] = {
  433. + { GL_MAX_GEOMETRY_UNIFORM_COMPONENTS, "GL_MAX_GEOMETRY_UNIFORM_COMPONENTS" },
  434. + { GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS, "GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS" },
  435. + { GL_MAX_GEOMETRY_OUTPUT_VERTICES , "GL_MAX_GEOMETRY_OUTPUT_VERTICES " },
  436. + { GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS, "GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS" },
  437. + { GL_MAX_GEOMETRY_INPUT_COMPONENTS , "GL_MAX_GEOMETRY_INPUT_COMPONENTS " },
  438. + { GL_MAX_GEOMETRY_OUTPUT_COMPONENTS, "GL_MAX_GEOMETRY_OUTPUT_COMPONENTS" },
  439. + { (GLenum) 0, NULL }
  440. + };
  441. +
  442. + switch (target) {
  443. + case GL_VERTEX_SHADER:
  444. + printf(" GL_VERTEX_SHADER_ARB:\n");
  445. + print_shader_limit_list(vertex_limits);
  446. + break;
  447. +
  448. + case GL_FRAGMENT_SHADER:
  449. + printf(" GL_FRAGMENT_SHADER_ARB:\n");
  450. + print_shader_limit_list(fragment_limits);
  451. + break;
  452. +
  453. + case GL_GEOMETRY_SHADER:
  454. + printf(" GL_GEOMETRY_SHADER:\n");
  455. + print_shader_limit_list(geometry_limits);
  456. + break;
  457. + }
  458. +}
  459. +
  460. +
  461. +/**
  462. + * Print interesting limits for vertex/fragment programs.
  463. + */
  464. +static void
  465. +print_program_limits(GLenum target,
  466. + const struct ext_functions *extfuncs)
  467. +{
  468. +#if defined(GL_ARB_vertex_program) || defined(GL_ARB_fragment_program)
  469. + struct token_name {
  470. + GLenum token;
  471. + const char *name;
  472. + };
  473. + static const struct token_name common_limits[] = {
  474. + { GL_MAX_PROGRAM_INSTRUCTIONS_ARB, "GL_MAX_PROGRAM_INSTRUCTIONS_ARB" },
  475. + { GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB, "GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB" },
  476. + { GL_MAX_PROGRAM_TEMPORARIES_ARB, "GL_MAX_PROGRAM_TEMPORARIES_ARB" },
  477. + { GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB, "GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB" },
  478. + { GL_MAX_PROGRAM_PARAMETERS_ARB, "GL_MAX_PROGRAM_PARAMETERS_ARB" },
  479. + { GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB, "GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB" },
  480. + { GL_MAX_PROGRAM_ATTRIBS_ARB, "GL_MAX_PROGRAM_ATTRIBS_ARB" },
  481. + { GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB, "GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB" },
  482. + { GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB, "GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB" },
  483. + { GL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB, "GL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB" },
  484. + { GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB, "GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB" },
  485. + { GL_MAX_PROGRAM_ENV_PARAMETERS_ARB, "GL_MAX_PROGRAM_ENV_PARAMETERS_ARB" },
  486. + { (GLenum) 0, NULL }
  487. + };
  488. + static const struct token_name fragment_limits[] = {
  489. + { GL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB, "GL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB" },
  490. + { GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB, "GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB" },
  491. + { GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB, "GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB" },
  492. + { GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB, "GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB" },
  493. + { GL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB, "GL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB" },
  494. + { GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB, "GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB" },
  495. + { (GLenum) 0, NULL }
  496. + };
  497. +
  498. + GLint max[1];
  499. + int i;
  500. +
  501. + if (target == GL_VERTEX_PROGRAM_ARB) {
  502. + printf(" GL_VERTEX_PROGRAM_ARB:\n");
  503. + }
  504. + else if (target == GL_FRAGMENT_PROGRAM_ARB) {
  505. + printf(" GL_FRAGMENT_PROGRAM_ARB:\n");
  506. + }
  507. + else {
  508. + return; /* something's wrong */
  509. + }
  510. +
  511. + for (i = 0; common_limits[i].token; i++) {
  512. + extfuncs->GetProgramivARB(target, common_limits[i].token, max);
  513. + if (glGetError() == GL_NO_ERROR) {
  514. + printf(" %s = %d\n", common_limits[i].name, max[0]);
  515. + }
  516. + }
  517. + if (target == GL_FRAGMENT_PROGRAM_ARB) {
  518. + for (i = 0; fragment_limits[i].token; i++) {
  519. + extfuncs->GetProgramivARB(target, fragment_limits[i].token, max);
  520. + if (glGetError() == GL_NO_ERROR) {
  521. + printf(" %s = %d\n", fragment_limits[i].name, max[0]);
  522. + }
  523. + }
  524. + }
  525. +#endif /* GL_ARB_vertex_program / GL_ARB_fragment_program */
  526. +}
  527. +
  528. +
  529. +/**
  530. + * Print interesting OpenGL implementation limits.
  531. + * \param version 20, 21, 30, 31, 32, etc.
  532. + */
  533. +void
  534. +print_limits(const char *extensions, const char *oglstring, int version,
  535. + const struct ext_functions *extfuncs)
  536. +{
  537. + struct token_name {
  538. + GLuint count;
  539. + GLenum token;
  540. + const char *name;
  541. + const char *extension; /* NULL or GL extension name or version string */
  542. + };
  543. + static const struct token_name limits[] = {
  544. + { 1, GL_MAX_ATTRIB_STACK_DEPTH, "GL_MAX_ATTRIB_STACK_DEPTH", NULL },
  545. + { 1, GL_MAX_CLIENT_ATTRIB_STACK_DEPTH, "GL_MAX_CLIENT_ATTRIB_STACK_DEPTH", NULL },
  546. + { 1, GL_MAX_CLIP_PLANES, "GL_MAX_CLIP_PLANES", NULL },
  547. + { 1, GL_MAX_COLOR_MATRIX_STACK_DEPTH, "GL_MAX_COLOR_MATRIX_STACK_DEPTH", "GL_ARB_imaging" },
  548. + { 1, GL_MAX_ELEMENTS_VERTICES, "GL_MAX_ELEMENTS_VERTICES", NULL },
  549. + { 1, GL_MAX_ELEMENTS_INDICES, "GL_MAX_ELEMENTS_INDICES", NULL },
  550. + { 1, GL_MAX_EVAL_ORDER, "GL_MAX_EVAL_ORDER", NULL },
  551. + { 1, GL_MAX_LIGHTS, "GL_MAX_LIGHTS", NULL },
  552. + { 1, GL_MAX_LIST_NESTING, "GL_MAX_LIST_NESTING", NULL },
  553. + { 1, GL_MAX_MODELVIEW_STACK_DEPTH, "GL_MAX_MODELVIEW_STACK_DEPTH", NULL },
  554. + { 1, GL_MAX_NAME_STACK_DEPTH, "GL_MAX_NAME_STACK_DEPTH", NULL },
  555. + { 1, GL_MAX_PIXEL_MAP_TABLE, "GL_MAX_PIXEL_MAP_TABLE", NULL },
  556. + { 1, GL_MAX_PROJECTION_STACK_DEPTH, "GL_MAX_PROJECTION_STACK_DEPTH", NULL },
  557. + { 1, GL_MAX_TEXTURE_STACK_DEPTH, "GL_MAX_TEXTURE_STACK_DEPTH", NULL },
  558. + { 1, GL_MAX_TEXTURE_SIZE, "GL_MAX_TEXTURE_SIZE", NULL },
  559. + { 1, GL_MAX_3D_TEXTURE_SIZE, "GL_MAX_3D_TEXTURE_SIZE", NULL },
  560. +#if defined(GL_EXT_texture_array)
  561. + { 1, GL_MAX_ARRAY_TEXTURE_LAYERS_EXT, "GL_MAX_ARRAY_TEXTURE_LAYERS", "GL_EXT_texture_array" },
  562. +#endif
  563. + { 2, GL_MAX_VIEWPORT_DIMS, "GL_MAX_VIEWPORT_DIMS", NULL },
  564. + { 2, GL_ALIASED_LINE_WIDTH_RANGE, "GL_ALIASED_LINE_WIDTH_RANGE", NULL },
  565. + { 2, GL_SMOOTH_LINE_WIDTH_RANGE, "GL_SMOOTH_LINE_WIDTH_RANGE", NULL },
  566. + { 2, GL_ALIASED_POINT_SIZE_RANGE, "GL_ALIASED_POINT_SIZE_RANGE", NULL },
  567. + { 2, GL_SMOOTH_POINT_SIZE_RANGE, "GL_SMOOTH_POINT_SIZE_RANGE", NULL },
  568. +#if defined(GL_ARB_texture_cube_map)
  569. + { 1, GL_MAX_CUBE_MAP_TEXTURE_SIZE_ARB, "GL_MAX_CUBE_MAP_TEXTURE_SIZE_ARB", "GL_ARB_texture_cube_map" },
  570. +#endif
  571. +#if defined(GL_NV_texture_rectangle)
  572. + { 1, GL_MAX_RECTANGLE_TEXTURE_SIZE_NV, "GL_MAX_RECTANGLE_TEXTURE_SIZE_NV", "GL_NV_texture_rectangle" },
  573. +#endif
  574. +#if defined(GL_ARB_multitexture)
  575. + { 1, GL_MAX_TEXTURE_UNITS_ARB, "GL_MAX_TEXTURE_UNITS_ARB", "GL_ARB_multitexture" },
  576. +#endif
  577. +#if defined(GL_EXT_texture_lod_bias)
  578. + { 1, GL_MAX_TEXTURE_LOD_BIAS_EXT, "GL_MAX_TEXTURE_LOD_BIAS_EXT", "GL_EXT_texture_lod_bias" },
  579. +#endif
  580. +#if defined(GL_EXT_texture_filter_anisotropic)
  581. + { 1, GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, "GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT", "GL_EXT_texture_filter_anisotropic" },
  582. +#endif
  583. +#if defined(GL_ARB_draw_buffers)
  584. + { 1, GL_MAX_DRAW_BUFFERS_ARB, "GL_MAX_DRAW_BUFFERS_ARB", "GL_ARB_draw_buffers" },
  585. +#endif
  586. +#if defined(GL_ARB_blend_func_extended)
  587. + { 1, GL_MAX_DUAL_SOURCE_DRAW_BUFFERS, "GL_MAX_DUAL_SOURCE_DRAW_BUFFERS", "GL_ARB_blend_func_extended" },
  588. +#endif
  589. +#if defined (GL_ARB_framebuffer_object)
  590. + { 1, GL_MAX_RENDERBUFFER_SIZE, "GL_MAX_RENDERBUFFER_SIZE", "GL_ARB_framebuffer_object" },
  591. + { 1, GL_MAX_COLOR_ATTACHMENTS, "GL_MAX_COLOR_ATTACHMENTS", "GL_ARB_framebuffer_object" },
  592. + { 1, GL_MAX_SAMPLES, "GL_MAX_SAMPLES", "GL_ARB_framebuffer_object" },
  593. +#endif
  594. +#if defined (GL_EXT_transform_feedback)
  595. + { 1, GL_MAX_TRANSFORM_FEEDBACK_BUFFERS, "GL_MAX_TRANSFORM_FEEDBACK_BUFFERS", "GL_EXT_transform_feedback" },
  596. + { 1, GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS_EXT, "GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS", "GL_EXT_transform_feedback" },
  597. + { 1, GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS_EXT, "GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS", "GL_EXT_transform_feedback", },
  598. + { 1, GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS_EXT, "GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS", "GL_EXT_transform_feedback" },
  599. +#endif
  600. +#if defined (GL_ARB_texture_buffer_object)
  601. + { 1, GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT, "GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT", "GL_ARB_texture_buffer_object" },
  602. + { 1, GL_MAX_TEXTURE_BUFFER_SIZE, "GL_MAX_TEXTURE_BUFFER_SIZE", "GL_ARB_texture_buffer_object" },
  603. +#endif
  604. +#if defined (GL_ARB_texture_multisample)
  605. + { 1, GL_MAX_COLOR_TEXTURE_SAMPLES, "GL_MAX_COLOR_TEXTURE_SAMPLES", "GL_ARB_texture_multisample" },
  606. + { 1, GL_MAX_DEPTH_TEXTURE_SAMPLES, "GL_MAX_DEPTH_TEXTURE_SAMPLES", "GL_ARB_texture_multisample" },
  607. + { 1, GL_MAX_INTEGER_SAMPLES, "GL_MAX_INTEGER_SAMPLES", "GL_ARB_texture_multisample" },
  608. +#endif
  609. +#if defined (GL_ARB_uniform_buffer_object)
  610. + { 1, GL_MAX_VERTEX_UNIFORM_BLOCKS, "GL_MAX_VERTEX_UNIFORM_BLOCKS", "GL_ARB_uniform_buffer_object" },
  611. + { 1, GL_MAX_FRAGMENT_UNIFORM_BLOCKS, "GL_MAX_FRAGMENT_UNIFORM_BLOCKS", "GL_ARB_uniform_buffer_object" },
  612. + { 1, GL_MAX_GEOMETRY_UNIFORM_BLOCKS, "GL_MAX_GEOMETRY_UNIFORM_BLOCKS" , "GL_ARB_uniform_buffer_object" },
  613. + { 1, GL_MAX_COMBINED_UNIFORM_BLOCKS, "GL_MAX_COMBINED_UNIFORM_BLOCKS", "GL_ARB_uniform_buffer_object" },
  614. + { 1, GL_MAX_UNIFORM_BUFFER_BINDINGS, "GL_MAX_UNIFORM_BUFFER_BINDINGS", "GL_ARB_uniform_buffer_object" },
  615. + { 1, GL_MAX_UNIFORM_BLOCK_SIZE, "GL_MAX_UNIFORM_BLOCK_SIZE", "GL_ARB_uniform_buffer_object" },
  616. + { 1, GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS, "GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS", "GL_ARB_uniform_buffer_object" },
  617. + { 1, GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS, "GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS", "GL_ARB_uniform_buffer_object" },
  618. + { 1, GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS, "GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS", "GL_ARB_uniform_buffer_object" },
  619. + { 1, GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT, "GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT", "GL_ARB_uniform_buffer_object" },
  620. +#endif
  621. +#if defined (GL_ARB_vertex_attrib_binding)
  622. + { 1, GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET, "GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET", "GL_ARB_vertex_attrib_binding" },
  623. + { 1, GL_MAX_VERTEX_ATTRIB_BINDINGS, "GL_MAX_VERTEX_ATTRIB_BINDINGS", "GL_ARB_vertex_attrib_binding" },
  624. +#endif
  625. +#if defined(GL_VERSION_4_4)
  626. + { 1, GL_MAX_VERTEX_ATTRIB_STRIDE, "GL_MAX_VERTEX_ATTRIB_STRIDE", "4.4" },
  627. +#endif
  628. + { 0, (GLenum) 0, NULL, NULL }
  629. + };
  630. + GLint i, max[2];
  631. +
  632. + printf("%s limits:\n", oglstring);
  633. + for (i = 0; limits[i].count; i++) {
  634. + if (!limits[i].extension ||
  635. + version_supported(limits[i].extension, version) ||
  636. + extension_supported(limits[i].extension, extensions)) {
  637. + glGetIntegerv(limits[i].token, max);
  638. + if (glGetError() == GL_NO_ERROR) {
  639. + if (limits[i].count == 1)
  640. + printf(" %s = %d\n", limits[i].name, max[0]);
  641. + else /* XXX fix if we ever query something with more than 2 values */
  642. + printf(" %s = %d, %d\n", limits[i].name, max[0], max[1]);
  643. + }
  644. + }
  645. + }
  646. +
  647. + /* these don't fit into the above mechanism, unfortunately */
  648. + if (extension_supported("GL_ARB_imaging", extensions)) {
  649. + extfuncs->GetConvolutionParameteriv(GL_CONVOLUTION_2D,
  650. + GL_MAX_CONVOLUTION_WIDTH, max);
  651. + extfuncs->GetConvolutionParameteriv(GL_CONVOLUTION_2D,
  652. + GL_MAX_CONVOLUTION_HEIGHT, max+1);
  653. + printf(" GL_MAX_CONVOLUTION_WIDTH/HEIGHT = %d, %d\n", max[0], max[1]);
  654. + }
  655. +
  656. + if (extension_supported("GL_ARB_texture_compression", extensions)) {
  657. + GLint i, n;
  658. + GLint *formats;
  659. + glGetIntegerv(GL_NUM_COMPRESSED_TEXTURE_FORMATS, &n);
  660. + printf(" GL_NUM_COMPRESSED_TEXTURE_FORMATS = %d\n", n);
  661. + formats = (GLint *) malloc(n * sizeof(GLint));
  662. + glGetIntegerv(GL_COMPRESSED_TEXTURE_FORMATS, formats);
  663. + for (i = 0; i < n; i++) {
  664. + printf(" %s\n", enum_name(formats[i]));
  665. + }
  666. + free(formats);
  667. + }
  668. +#if defined(GL_ARB_vertex_program)
  669. + if (extension_supported("GL_ARB_vertex_program", extensions)) {
  670. + print_program_limits(GL_VERTEX_PROGRAM_ARB, extfuncs);
  671. + }
  672. +#endif
  673. +#if defined(GL_ARB_fragment_program)
  674. + if (extension_supported("GL_ARB_fragment_program", extensions)) {
  675. + print_program_limits(GL_FRAGMENT_PROGRAM_ARB, extfuncs);
  676. + }
  677. +#endif
  678. + if (extension_supported("GL_ARB_vertex_shader", extensions)) {
  679. + print_shader_limits(GL_VERTEX_SHADER_ARB);
  680. + }
  681. + if (extension_supported("GL_ARB_fragment_shader", extensions)) {
  682. + print_shader_limits(GL_FRAGMENT_SHADER_ARB);
  683. + }
  684. + if (version >= 32) {
  685. + print_shader_limits(GL_GEOMETRY_SHADER);
  686. + }
  687. +}
  688. +
  689. +
  690. +
  691. +/**
  692. + * Return string representation for bits in a bitmask.
  693. + */
  694. +const char *
  695. +bitmask_to_string(const struct bit_info bits[], int numBits, int mask)
  696. +{
  697. + static char buffer[256], *p;
  698. + int i;
  699. +
  700. + strcpy(buffer, "(none)");
  701. + p = buffer;
  702. + for (i = 0; i < numBits; i++) {
  703. + if (mask & bits[i].bit) {
  704. + if (p > buffer)
  705. + *p++ = ',';
  706. + strcpy(p, bits[i].name);
  707. + p += strlen(bits[i].name);
  708. + }
  709. + }
  710. +
  711. + return buffer;
  712. +}
  713. +
  714. +/**
  715. + * Return string representation for the bitmask returned by
  716. + * GL_CONTEXT_PROFILE_MASK (OpenGL 3.2 or later).
  717. + */
  718. +const char *
  719. +profile_mask_string(int mask)
  720. +{
  721. + const static struct bit_info bits[] = {
  722. +#ifdef GL_CONTEXT_CORE_PROFILE_BIT
  723. + { GL_CONTEXT_CORE_PROFILE_BIT, "core profile"},
  724. +#endif
  725. +#ifdef GL_CONTEXT_COMPATIBILITY_PROFILE_BIT
  726. + { GL_CONTEXT_COMPATIBILITY_PROFILE_BIT, "compatibility profile" }
  727. +#endif
  728. + };
  729. +
  730. + return bitmask_to_string(bits, ELEMENTS(bits), mask);
  731. +}
  732. +
  733. +
  734. +/**
  735. + * Return string representation for the bitmask returned by
  736. + * GL_CONTEXT_FLAGS (OpenGL 3.0 or later).
  737. + */
  738. +const char *
  739. +context_flags_string(int mask)
  740. +{
  741. + const static struct bit_info bits[] = {
  742. +#ifdef GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT
  743. + { GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT, "forward-compatible" },
  744. +#endif
  745. +#ifdef GL_CONTEXT_FLAG_ROBUST_ACCESS_BIT_ARB
  746. + { GL_CONTEXT_FLAG_ROBUST_ACCESS_BIT_ARB, "robust-access" },
  747. +#endif
  748. + };
  749. +
  750. + return bitmask_to_string(bits, ELEMENTS(bits), mask);
  751. +}
  752. +
  753. +
  754. +static void
  755. +usage(void)
  756. +{
  757. +#ifdef _WIN32
  758. + printf("Usage: wglinfo [-v] [-t] [-h] [-b] [-l] [-s]\n");
  759. +#else
  760. + printf("Usage: glxinfo [-v] [-t] [-h] [-b] [-l] [-s] [-i] [-display <dname>]\n");
  761. + printf("\t-display <dname>: Print GLX visuals on specified server.\n");
  762. + printf("\t-i: Force an indirect rendering context.\n");
  763. +#endif
  764. + printf("\t-B: brief output, print only the basics.\n");
  765. + printf("\t-v: Print visuals info in verbose form.\n");
  766. + printf("\t-t: Print verbose table.\n");
  767. + printf("\t-h: This information.\n");
  768. + printf("\t-b: Find the 'best' visual and print its number.\n");
  769. + printf("\t-l: Print interesting OpenGL limits.\n");
  770. + printf("\t-s: Print a single extension per line.\n");
  771. +}
  772. +
  773. +void
  774. +parse_args(int argc, char *argv[], struct options *options)
  775. +{
  776. + int i;
  777. +
  778. + options->mode = Normal;
  779. + options->findBest = GL_FALSE;
  780. + options->limits = GL_FALSE;
  781. + options->singleLine = GL_FALSE;
  782. + options->displayName = NULL;
  783. + options->allowDirect = GL_TRUE;
  784. +
  785. + for (i = 1; i < argc; i++) {
  786. +#ifndef _WIN32
  787. + if (strcmp(argv[i], "-display") == 0 && i + 1 < argc) {
  788. + options->displayName = argv[i + 1];
  789. + i++;
  790. + }
  791. + else if (strcmp(argv[i], "-i") == 0) {
  792. + options->allowDirect = GL_FALSE;
  793. + }
  794. + else
  795. +#endif
  796. + if (strcmp(argv[i], "-t") == 0) {
  797. + options->mode = Wide;
  798. + }
  799. + else if (strcmp(argv[i], "-v") == 0) {
  800. + options->mode = Verbose;
  801. + }
  802. + else if (strcmp(argv[i], "-B") == 0) {
  803. + options->mode = Brief;
  804. + }
  805. + else if (strcmp(argv[i], "-b") == 0) {
  806. + options->findBest = GL_TRUE;
  807. + }
  808. + else if (strcmp(argv[i], "-l") == 0) {
  809. + options->limits = GL_TRUE;
  810. + }
  811. + else if (strcmp(argv[i], "-h") == 0) {
  812. + usage();
  813. + exit(0);
  814. + }
  815. + else if(strcmp(argv[i], "-s") == 0) {
  816. + options->singleLine = GL_TRUE;
  817. + }
  818. + else {
  819. + printf("Unknown option `%s'\n", argv[i]);
  820. + usage();
  821. + exit(0);
  822. + }
  823. + }
  824. +}
  825. diff -Naurp mesa-20.2.1-orig/src/glx/xdemos/glinfo_common.h mesa-20.2.1/src/glx/xdemos/glinfo_common.h
  826. --- mesa-20.2.1-orig/src/glx/xdemos/glinfo_common.h 1969-12-31 18:00:00.000000000 -0600
  827. +++ mesa-20.2.1/src/glx/xdemos/glinfo_common.h 2020-10-15 23:06:45.826695773 -0500
  828. @@ -0,0 +1,142 @@
  829. +/*
  830. + * Copyright (C) 1999-2014 Brian Paul All Rights Reserved.
  831. + *
  832. + * Permission is hereby granted, free of charge, to any person obtaining a
  833. + * copy of this software and associated documentation files (the "Software"),
  834. + * to deal in the Software without restriction, including without limitation
  835. + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  836. + * and/or sell copies of the Software, and to permit persons to whom the
  837. + * Software is furnished to do so, subject to the following conditions:
  838. + *
  839. + * The above copyright notice and this permission notice shall be included
  840. + * in all copies or substantial portions of the Software.
  841. + *
  842. + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  843. + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  844. + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  845. + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
  846. + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  847. + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  848. + */
  849. +
  850. +
  851. +/**
  852. + * Common code shared by glxinfo and wglinfo.
  853. + */
  854. +
  855. +#ifndef GLINFO_COMMON_H
  856. +#define GLINFO_COMMON_H
  857. +
  858. +
  859. +#ifdef _WIN32
  860. +/* GL/glext.h is not commonly available on Windows. */
  861. +#include <GL/glew.h>
  862. +#else
  863. +#include <GL/gl.h>
  864. +#include <GL/glext.h>
  865. +#endif
  866. +
  867. +typedef void (APIENTRY * GETPROGRAMIVARBPROC) (GLenum target, GLenum pname, GLint *params);
  868. +typedef const GLubyte *(APIENTRY * GETSTRINGIPROC) (GLenum name, GLuint index);
  869. +typedef void (APIENTRY * GETCONVOLUTIONPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params);
  870. +
  871. +
  872. +/**
  873. + * Ext functions needed in common code but must be provided by
  874. + * glxinfo or wglinfo.
  875. + */
  876. +struct ext_functions
  877. +{
  878. + GETPROGRAMIVARBPROC GetProgramivARB;
  879. + GETSTRINGIPROC GetStringi;
  880. + GETCONVOLUTIONPARAMETERIVPROC GetConvolutionParameteriv;
  881. +};
  882. +
  883. +
  884. +#define ELEMENTS(array) (sizeof(array) / sizeof(array[0]))
  885. +
  886. +
  887. +struct bit_info
  888. +{
  889. + int bit;
  890. + const char *name;
  891. +};
  892. +
  893. +
  894. +typedef enum
  895. +{
  896. + Normal,
  897. + Wide,
  898. + Verbose,
  899. + Brief
  900. +} InfoMode;
  901. +
  902. +
  903. +struct options
  904. +{
  905. + InfoMode mode;
  906. + GLboolean findBest;
  907. + GLboolean limits;
  908. + GLboolean singleLine;
  909. + /* GLX only */
  910. + char *displayName;
  911. + GLboolean allowDirect;
  912. +};
  913. +
  914. +
  915. +/** list of known OpenGL versions */
  916. +static const struct { int major, minor; } gl_versions[] = {
  917. + {4, 5},
  918. + {4, 4},
  919. + {4, 3},
  920. + {4, 2},
  921. + {4, 1},
  922. + {4, 0},
  923. +
  924. + {3, 3},
  925. + {3, 2},
  926. + {3, 1},
  927. + {3, 0},
  928. +
  929. + {2, 1},
  930. + {2, 0},
  931. +
  932. + {1, 5},
  933. + {1, 4},
  934. + {1, 3},
  935. + {1, 2},
  936. + {1, 1},
  937. + {1, 0},
  938. +
  939. + {0, 0} /* end of list */
  940. +};
  941. +
  942. +
  943. +void
  944. +print_extension_list(const char *ext, GLboolean singleLine);
  945. +
  946. +char *
  947. +build_core_profile_extension_list(const struct ext_functions *extfuncs);
  948. +
  949. +GLboolean
  950. +extension_supported(const char *ext, const char *extensionsList);
  951. +
  952. +void
  953. +print_limits(const char *extensions, const char *oglstring, int version,
  954. + const struct ext_functions *extfuncs);
  955. +
  956. +const char *
  957. +bitmask_to_string(const struct bit_info bits[], int numBits, int mask);
  958. +
  959. +const char *
  960. +profile_mask_string(int mask);
  961. +
  962. +const char *
  963. +context_flags_string(int mask);
  964. +
  965. +
  966. +void
  967. +parse_args(int argc, char *argv[], struct options *options);
  968. +
  969. +
  970. +#endif /* GLINFO_COMMON_H */
  971. diff -Naurp mesa-20.2.1-orig/src/glx/xdemos/glxgears.1 mesa-20.2.1/src/glx/xdemos/glxgears.1
  972. --- mesa-20.2.1-orig/src/glx/xdemos/glxgears.1 1969-12-31 18:00:00.000000000 -0600
  973. +++ mesa-20.2.1/src/glx/xdemos/glxgears.1 2020-10-15 23:06:45.826695773 -0500
  974. @@ -0,0 +1,37 @@
  975. +.TH glxgears 1 "2006-11-29"
  976. +.SH NAME
  977. +glxgears \- ``gears'' demo for GLX
  978. +.SH SYNOPSIS
  979. +.B glxgears
  980. +.RI [ options ]
  981. +.SH DESCRIPTION
  982. +The \fIglxgears\fP program is a port of the ``gears'' demo to GLX. It displays
  983. +a set of rotating gears and prints out the frame rate at regular intervals. It
  984. +has become quite popular as basic benchmarking tool.
  985. +.SH OPTIONS
  986. +.TP 8
  987. +.B \-display \fIdisplay\fP
  988. +Specify which X display to run on.
  989. +.TP 8
  990. +.B \-stereo
  991. +Use a stereo enabled GLX visual.
  992. +.TP 8
  993. +.B \-samples \fIN\fP
  994. +Run in multisample mode with at least N samples.
  995. +.TP 8
  996. +.B \-fullscreen
  997. +Run in fullscreen mode.
  998. +.TP 8
  999. +.B \-info
  1000. +Display OpenGL renderer information.
  1001. +.TP 8
  1002. +.B \-geometry \fIWxH+X+Y\fP
  1003. +Window geometry.
  1004. +.SH AUTHOR
  1005. +glxgears was written by Brian Paul <brian.paul@tungstengraphics.com>.
  1006. +.PP
  1007. +This manual page was written by Thierry Reding <thierry@gilfi.de>, for the
  1008. +Debian project and updated by Fernando de Oliveira <famobr at yahoo dot
  1009. +com dot br>, for the Linux From Scratch (LFS) project (but may be used by
  1010. +others).
  1011. +
  1012. diff -Naurp mesa-20.2.1-orig/src/glx/xdemos/glxgears.c mesa-20.2.1/src/glx/xdemos/glxgears.c
  1013. --- mesa-20.2.1-orig/src/glx/xdemos/glxgears.c 1969-12-31 18:00:00.000000000 -0600
  1014. +++ mesa-20.2.1/src/glx/xdemos/glxgears.c 2020-10-15 23:06:45.826695773 -0500
  1015. @@ -0,0 +1,809 @@
  1016. +/*
  1017. + * Copyright (C) 1999-2001 Brian Paul All Rights Reserved.
  1018. + *
  1019. + * Permission is hereby granted, free of charge, to any person obtaining a
  1020. + * copy of this software and associated documentation files (the "Software"),
  1021. + * to deal in the Software without restriction, including without limitation
  1022. + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  1023. + * and/or sell copies of the Software, and to permit persons to whom the
  1024. + * Software is furnished to do so, subject to the following conditions:
  1025. + *
  1026. + * The above copyright notice and this permission notice shall be included
  1027. + * in all copies or substantial portions of the Software.
  1028. + *
  1029. + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  1030. + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  1031. + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  1032. + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
  1033. + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  1034. + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  1035. + */
  1036. +
  1037. +/*
  1038. + * This is a port of the infamous "gears" demo to straight GLX (i.e. no GLUT)
  1039. + * Port by Brian Paul 23 March 2001
  1040. + *
  1041. + * See usage() below for command line options.
  1042. + */
  1043. +
  1044. +
  1045. +#include <math.h>
  1046. +#include <stdlib.h>
  1047. +#include <stdio.h>
  1048. +#include <string.h>
  1049. +#include <X11/Xlib.h>
  1050. +#include <X11/keysym.h>
  1051. +#include <GL/gl.h>
  1052. +#include <GL/glx.h>
  1053. +#include <GL/glxext.h>
  1054. +
  1055. +#ifndef GLX_MESA_swap_control
  1056. +#define GLX_MESA_swap_control 1
  1057. +typedef int (*PFNGLXGETSWAPINTERVALMESAPROC)(void);
  1058. +#endif
  1059. +
  1060. +
  1061. +#define BENCHMARK
  1062. +
  1063. +#ifdef BENCHMARK
  1064. +
  1065. +/* XXX this probably isn't very portable */
  1066. +
  1067. +#include <sys/time.h>
  1068. +#include <unistd.h>
  1069. +
  1070. +/* return current time (in seconds) */
  1071. +static double
  1072. +current_time(void)
  1073. +{
  1074. + struct timeval tv;
  1075. +#ifdef __VMS
  1076. + (void) gettimeofday(&tv, NULL );
  1077. +#else
  1078. + struct timezone tz;
  1079. + (void) gettimeofday(&tv, &tz);
  1080. +#endif
  1081. + return (double) tv.tv_sec + tv.tv_usec / 1000000.0;
  1082. +}
  1083. +
  1084. +#else /*BENCHMARK*/
  1085. +
  1086. +/* dummy */
  1087. +static double
  1088. +current_time(void)
  1089. +{
  1090. + /* update this function for other platforms! */
  1091. + static double t = 0.0;
  1092. + static int warn = 1;
  1093. + if (warn) {
  1094. + fprintf(stderr, "Warning: current_time() not implemented!!\n");
  1095. + warn = 0;
  1096. + }
  1097. + return t += 1.0;
  1098. +}
  1099. +
  1100. +#endif /*BENCHMARK*/
  1101. +
  1102. +
  1103. +
  1104. +#ifndef M_PI
  1105. +#define M_PI 3.14159265
  1106. +#endif
  1107. +
  1108. +
  1109. +/** Event handler results: */
  1110. +#define NOP 0
  1111. +#define EXIT 1
  1112. +#define DRAW 2
  1113. +
  1114. +static GLfloat view_rotx = 20.0, view_roty = 30.0, view_rotz = 0.0;
  1115. +static GLint gear1, gear2, gear3;
  1116. +static GLfloat angle = 0.0;
  1117. +
  1118. +static GLboolean fullscreen = GL_FALSE; /* Create a single fullscreen window */
  1119. +static GLboolean stereo = GL_FALSE; /* Enable stereo. */
  1120. +static GLint samples = 0; /* Choose visual with at least N samples. */
  1121. +static GLboolean animate = GL_TRUE; /* Animation */
  1122. +static GLfloat eyesep = 5.0; /* Eye separation. */
  1123. +static GLfloat fix_point = 40.0; /* Fixation point distance. */
  1124. +static GLfloat left, right, asp; /* Stereo frustum params. */
  1125. +
  1126. +
  1127. +/*
  1128. + *
  1129. + * Draw a gear wheel. You'll probably want to call this function when
  1130. + * building a display list since we do a lot of trig here.
  1131. + *
  1132. + * Input: inner_radius - radius of hole at center
  1133. + * outer_radius - radius at center of teeth
  1134. + * width - width of gear
  1135. + * teeth - number of teeth
  1136. + * tooth_depth - depth of tooth
  1137. + */
  1138. +static void
  1139. +gear(GLfloat inner_radius, GLfloat outer_radius, GLfloat width,
  1140. + GLint teeth, GLfloat tooth_depth)
  1141. +{
  1142. + GLint i;
  1143. + GLfloat r0, r1, r2;
  1144. + GLfloat angle, da;
  1145. + GLfloat u, v, len;
  1146. +
  1147. + r0 = inner_radius;
  1148. + r1 = outer_radius - tooth_depth / 2.0;
  1149. + r2 = outer_radius + tooth_depth / 2.0;
  1150. +
  1151. + da = 2.0 * M_PI / teeth / 4.0;
  1152. +
  1153. + glShadeModel(GL_FLAT);
  1154. +
  1155. + glNormal3f(0.0, 0.0, 1.0);
  1156. +
  1157. + /* draw front face */
  1158. + glBegin(GL_QUAD_STRIP);
  1159. + for (i = 0; i <= teeth; i++) {
  1160. + angle = i * 2.0 * M_PI / teeth;
  1161. + glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5);
  1162. + glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5);
  1163. + if (i < teeth) {
  1164. + glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5);
  1165. + glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da),
  1166. + width * 0.5);
  1167. + }
  1168. + }
  1169. + glEnd();
  1170. +
  1171. + /* draw front sides of teeth */
  1172. + glBegin(GL_QUADS);
  1173. + da = 2.0 * M_PI / teeth / 4.0;
  1174. + for (i = 0; i < teeth; i++) {
  1175. + angle = i * 2.0 * M_PI / teeth;
  1176. +
  1177. + glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5);
  1178. + glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), width * 0.5);
  1179. + glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da),
  1180. + width * 0.5);
  1181. + glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da),
  1182. + width * 0.5);
  1183. + }
  1184. + glEnd();
  1185. +
  1186. + glNormal3f(0.0, 0.0, -1.0);
  1187. +
  1188. + /* draw back face */
  1189. + glBegin(GL_QUAD_STRIP);
  1190. + for (i = 0; i <= teeth; i++) {
  1191. + angle = i * 2.0 * M_PI / teeth;
  1192. + glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5);
  1193. + glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5);
  1194. + if (i < teeth) {
  1195. + glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da),
  1196. + -width * 0.5);
  1197. + glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5);
  1198. + }
  1199. + }
  1200. + glEnd();
  1201. +
  1202. + /* draw back sides of teeth */
  1203. + glBegin(GL_QUADS);
  1204. + da = 2.0 * M_PI / teeth / 4.0;
  1205. + for (i = 0; i < teeth; i++) {
  1206. + angle = i * 2.0 * M_PI / teeth;
  1207. +
  1208. + glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da),
  1209. + -width * 0.5);
  1210. + glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da),
  1211. + -width * 0.5);
  1212. + glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), -width * 0.5);
  1213. + glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5);
  1214. + }
  1215. + glEnd();
  1216. +
  1217. + /* draw outward faces of teeth */
  1218. + glBegin(GL_QUAD_STRIP);
  1219. + for (i = 0; i < teeth; i++) {
  1220. + angle = i * 2.0 * M_PI / teeth;
  1221. +
  1222. + glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5);
  1223. + glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5);
  1224. + u = r2 * cos(angle + da) - r1 * cos(angle);
  1225. + v = r2 * sin(angle + da) - r1 * sin(angle);
  1226. + len = sqrt(u * u + v * v);
  1227. + u /= len;
  1228. + v /= len;
  1229. + glNormal3f(v, -u, 0.0);
  1230. + glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), width * 0.5);
  1231. + glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), -width * 0.5);
  1232. + glNormal3f(cos(angle), sin(angle), 0.0);
  1233. + glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da),
  1234. + width * 0.5);
  1235. + glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da),
  1236. + -width * 0.5);
  1237. + u = r1 * cos(angle + 3 * da) - r2 * cos(angle + 2 * da);
  1238. + v = r1 * sin(angle + 3 * da) - r2 * sin(angle + 2 * da);
  1239. + glNormal3f(v, -u, 0.0);
  1240. + glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da),
  1241. + width * 0.5);
  1242. + glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da),
  1243. + -width * 0.5);
  1244. + glNormal3f(cos(angle), sin(angle), 0.0);
  1245. + }
  1246. +
  1247. + glVertex3f(r1 * cos(0), r1 * sin(0), width * 0.5);
  1248. + glVertex3f(r1 * cos(0), r1 * sin(0), -width * 0.5);
  1249. +
  1250. + glEnd();
  1251. +
  1252. + glShadeModel(GL_SMOOTH);
  1253. +
  1254. + /* draw inside radius cylinder */
  1255. + glBegin(GL_QUAD_STRIP);
  1256. + for (i = 0; i <= teeth; i++) {
  1257. + angle = i * 2.0 * M_PI / teeth;
  1258. + glNormal3f(-cos(angle), -sin(angle), 0.0);
  1259. + glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5);
  1260. + glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5);
  1261. + }
  1262. + glEnd();
  1263. +}
  1264. +
  1265. +
  1266. +static void
  1267. +draw(void)
  1268. +{
  1269. + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  1270. +
  1271. + glPushMatrix();
  1272. + glRotatef(view_rotx, 1.0, 0.0, 0.0);
  1273. + glRotatef(view_roty, 0.0, 1.0, 0.0);
  1274. + glRotatef(view_rotz, 0.0, 0.0, 1.0);
  1275. +
  1276. + glPushMatrix();
  1277. + glTranslatef(-3.0, -2.0, 0.0);
  1278. + glRotatef(angle, 0.0, 0.0, 1.0);
  1279. + glCallList(gear1);
  1280. + glPopMatrix();
  1281. +
  1282. + glPushMatrix();
  1283. + glTranslatef(3.1, -2.0, 0.0);
  1284. + glRotatef(-2.0 * angle - 9.0, 0.0, 0.0, 1.0);
  1285. + glCallList(gear2);
  1286. + glPopMatrix();
  1287. +
  1288. + glPushMatrix();
  1289. + glTranslatef(-3.1, 4.2, 0.0);
  1290. + glRotatef(-2.0 * angle - 25.0, 0.0, 0.0, 1.0);
  1291. + glCallList(gear3);
  1292. + glPopMatrix();
  1293. +
  1294. + glPopMatrix();
  1295. +}
  1296. +
  1297. +
  1298. +static void
  1299. +draw_gears(void)
  1300. +{
  1301. + if (stereo) {
  1302. + /* First left eye. */
  1303. + glDrawBuffer(GL_BACK_LEFT);
  1304. +
  1305. + glMatrixMode(GL_PROJECTION);
  1306. + glLoadIdentity();
  1307. + glFrustum(left, right, -asp, asp, 5.0, 60.0);
  1308. +
  1309. + glMatrixMode(GL_MODELVIEW);
  1310. +
  1311. + glPushMatrix();
  1312. + glTranslated(+0.5 * eyesep, 0.0, 0.0);
  1313. + draw();
  1314. + glPopMatrix();
  1315. +
  1316. + /* Then right eye. */
  1317. + glDrawBuffer(GL_BACK_RIGHT);
  1318. +
  1319. + glMatrixMode(GL_PROJECTION);
  1320. + glLoadIdentity();
  1321. + glFrustum(-right, -left, -asp, asp, 5.0, 60.0);
  1322. +
  1323. + glMatrixMode(GL_MODELVIEW);
  1324. +
  1325. + glPushMatrix();
  1326. + glTranslated(-0.5 * eyesep, 0.0, 0.0);
  1327. + draw();
  1328. + glPopMatrix();
  1329. + }
  1330. + else {
  1331. + draw();
  1332. + }
  1333. +}
  1334. +
  1335. +
  1336. +/** Draw single frame, do SwapBuffers, compute FPS */
  1337. +static void
  1338. +draw_frame(Display *dpy, Window win)
  1339. +{
  1340. + static int frames = 0;
  1341. + static double tRot0 = -1.0, tRate0 = -1.0;
  1342. + double dt, t = current_time();
  1343. +
  1344. + if (tRot0 < 0.0)
  1345. + tRot0 = t;
  1346. + dt = t - tRot0;
  1347. + tRot0 = t;
  1348. +
  1349. + if (animate) {
  1350. + /* advance rotation for next frame */
  1351. + angle += 70.0 * dt; /* 70 degrees per second */
  1352. + if (angle > 3600.0)
  1353. + angle -= 3600.0;
  1354. + }
  1355. +
  1356. + draw_gears();
  1357. + glXSwapBuffers(dpy, win);
  1358. +
  1359. + frames++;
  1360. +
  1361. + if (tRate0 < 0.0)
  1362. + tRate0 = t;
  1363. + if (t - tRate0 >= 5.0) {
  1364. + GLfloat seconds = t - tRate0;
  1365. + GLfloat fps = frames / seconds;
  1366. + printf("%d frames in %3.1f seconds = %6.3f FPS\n", frames, seconds,
  1367. + fps);
  1368. + fflush(stdout);
  1369. + tRate0 = t;
  1370. + frames = 0;
  1371. + }
  1372. +}
  1373. +
  1374. +
  1375. +/* new window size or exposure */
  1376. +static void
  1377. +reshape(int width, int height)
  1378. +{
  1379. + glViewport(0, 0, (GLint) width, (GLint) height);
  1380. +
  1381. + if (stereo) {
  1382. + GLfloat w;
  1383. +
  1384. + asp = (GLfloat) height / (GLfloat) width;
  1385. + w = fix_point * (1.0 / 5.0);
  1386. +
  1387. + left = -5.0 * ((w - 0.5 * eyesep) / fix_point);
  1388. + right = 5.0 * ((w + 0.5 * eyesep) / fix_point);
  1389. + }
  1390. + else {
  1391. + GLfloat h = (GLfloat) height / (GLfloat) width;
  1392. +
  1393. + glMatrixMode(GL_PROJECTION);
  1394. + glLoadIdentity();
  1395. + glFrustum(-1.0, 1.0, -h, h, 5.0, 60.0);
  1396. + }
  1397. +
  1398. + glMatrixMode(GL_MODELVIEW);
  1399. + glLoadIdentity();
  1400. + glTranslatef(0.0, 0.0, -40.0);
  1401. +}
  1402. +
  1403. +
  1404. +
  1405. +static void
  1406. +init(void)
  1407. +{
  1408. + static GLfloat pos[4] = { 5.0, 5.0, 10.0, 0.0 };
  1409. + static GLfloat red[4] = { 0.8, 0.1, 0.0, 1.0 };
  1410. + static GLfloat green[4] = { 0.0, 0.8, 0.2, 1.0 };
  1411. + static GLfloat blue[4] = { 0.2, 0.2, 1.0, 1.0 };
  1412. +
  1413. + glLightfv(GL_LIGHT0, GL_POSITION, pos);
  1414. + glEnable(GL_CULL_FACE);
  1415. + glEnable(GL_LIGHTING);
  1416. + glEnable(GL_LIGHT0);
  1417. + glEnable(GL_DEPTH_TEST);
  1418. +
  1419. + /* make the gears */
  1420. + gear1 = glGenLists(1);
  1421. + glNewList(gear1, GL_COMPILE);
  1422. + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, red);
  1423. + gear(1.0, 4.0, 1.0, 20, 0.7);
  1424. + glEndList();
  1425. +
  1426. + gear2 = glGenLists(1);
  1427. + glNewList(gear2, GL_COMPILE);
  1428. + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, green);
  1429. + gear(0.5, 2.0, 2.0, 10, 0.7);
  1430. + glEndList();
  1431. +
  1432. + gear3 = glGenLists(1);
  1433. + glNewList(gear3, GL_COMPILE);
  1434. + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, blue);
  1435. + gear(1.3, 2.0, 0.5, 10, 0.7);
  1436. + glEndList();
  1437. +
  1438. + glEnable(GL_NORMALIZE);
  1439. +}
  1440. +
  1441. +
  1442. +/**
  1443. + * Remove window border/decorations.
  1444. + */
  1445. +static void
  1446. +no_border( Display *dpy, Window w)
  1447. +{
  1448. + static const unsigned MWM_HINTS_DECORATIONS = (1 << 1);
  1449. + static const int PROP_MOTIF_WM_HINTS_ELEMENTS = 5;
  1450. +
  1451. + typedef struct
  1452. + {
  1453. + unsigned long flags;
  1454. + unsigned long functions;
  1455. + unsigned long decorations;
  1456. + long inputMode;
  1457. + unsigned long status;
  1458. + } PropMotifWmHints;
  1459. +
  1460. + PropMotifWmHints motif_hints;
  1461. + Atom prop, proptype;
  1462. + unsigned long flags = 0;
  1463. +
  1464. + /* setup the property */
  1465. + motif_hints.flags = MWM_HINTS_DECORATIONS;
  1466. + motif_hints.decorations = flags;
  1467. +
  1468. + /* get the atom for the property */
  1469. + prop = XInternAtom( dpy, "_MOTIF_WM_HINTS", True );
  1470. + if (!prop) {
  1471. + /* something went wrong! */
  1472. + return;
  1473. + }
  1474. +
  1475. + /* not sure this is correct, seems to work, XA_WM_HINTS didn't work */
  1476. + proptype = prop;
  1477. +
  1478. + XChangeProperty( dpy, w, /* display, window */
  1479. + prop, proptype, /* property, type */
  1480. + 32, /* format: 32-bit datums */
  1481. + PropModeReplace, /* mode */
  1482. + (unsigned char *) &motif_hints, /* data */
  1483. + PROP_MOTIF_WM_HINTS_ELEMENTS /* nelements */
  1484. + );
  1485. +}
  1486. +
  1487. +
  1488. +/*
  1489. + * Create an RGB, double-buffered window.
  1490. + * Return the window and context handles.
  1491. + */
  1492. +static void
  1493. +make_window( Display *dpy, const char *name,
  1494. + int x, int y, int width, int height,
  1495. + Window *winRet, GLXContext *ctxRet, VisualID *visRet)
  1496. +{
  1497. + int attribs[64];
  1498. + int i = 0;
  1499. +
  1500. + int scrnum;
  1501. + XSetWindowAttributes attr;
  1502. + unsigned long mask;
  1503. + Window root;
  1504. + Window win;
  1505. + GLXContext ctx;
  1506. + XVisualInfo *visinfo;
  1507. +
  1508. + /* Singleton attributes. */
  1509. + attribs[i++] = GLX_RGBA;
  1510. + attribs[i++] = GLX_DOUBLEBUFFER;
  1511. + if (stereo)
  1512. + attribs[i++] = GLX_STEREO;
  1513. +
  1514. + /* Key/value attributes. */
  1515. + attribs[i++] = GLX_RED_SIZE;
  1516. + attribs[i++] = 1;
  1517. + attribs[i++] = GLX_GREEN_SIZE;
  1518. + attribs[i++] = 1;
  1519. + attribs[i++] = GLX_BLUE_SIZE;
  1520. + attribs[i++] = 1;
  1521. + attribs[i++] = GLX_DEPTH_SIZE;
  1522. + attribs[i++] = 1;
  1523. + if (samples > 0) {
  1524. + attribs[i++] = GLX_SAMPLE_BUFFERS;
  1525. + attribs[i++] = 1;
  1526. + attribs[i++] = GLX_SAMPLES;
  1527. + attribs[i++] = samples;
  1528. + }
  1529. +
  1530. + attribs[i++] = None;
  1531. +
  1532. + scrnum = DefaultScreen( dpy );
  1533. + root = RootWindow( dpy, scrnum );
  1534. +
  1535. + visinfo = glXChooseVisual(dpy, scrnum, attribs);
  1536. + if (!visinfo) {
  1537. + printf("Error: couldn't get an RGB, Double-buffered");
  1538. + if (stereo)
  1539. + printf(", Stereo");
  1540. + if (samples > 0)
  1541. + printf(", Multisample");
  1542. + printf(" visual\n");
  1543. + exit(1);
  1544. + }
  1545. +
  1546. + /* window attributes */
  1547. + attr.background_pixel = 0;
  1548. + attr.border_pixel = 0;
  1549. + attr.colormap = XCreateColormap( dpy, root, visinfo->visual, AllocNone);
  1550. + attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask;
  1551. + /* XXX this is a bad way to get a borderless window! */
  1552. + mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
  1553. +
  1554. + win = XCreateWindow( dpy, root, x, y, width, height,
  1555. + 0, visinfo->depth, InputOutput,
  1556. + visinfo->visual, mask, &attr );
  1557. +
  1558. + if (fullscreen)
  1559. + no_border(dpy, win);
  1560. +
  1561. + /* set hints and properties */
  1562. + {
  1563. + XSizeHints sizehints;
  1564. + sizehints.x = x;
  1565. + sizehints.y = y;
  1566. + sizehints.width = width;
  1567. + sizehints.height = height;
  1568. + sizehints.flags = USSize | USPosition;
  1569. + XSetNormalHints(dpy, win, &sizehints);
  1570. + XSetStandardProperties(dpy, win, name, name,
  1571. + None, (char **)NULL, 0, &sizehints);
  1572. + }
  1573. +
  1574. + ctx = glXCreateContext( dpy, visinfo, NULL, True );
  1575. + if (!ctx) {
  1576. + printf("Error: glXCreateContext failed\n");
  1577. + exit(1);
  1578. + }
  1579. +
  1580. + *winRet = win;
  1581. + *ctxRet = ctx;
  1582. + *visRet = visinfo->visualid;
  1583. +
  1584. + XFree(visinfo);
  1585. +}
  1586. +
  1587. +
  1588. +/**
  1589. + * Determine whether or not a GLX extension is supported.
  1590. + */
  1591. +static int
  1592. +is_glx_extension_supported(Display *dpy, const char *query)
  1593. +{
  1594. + const int scrnum = DefaultScreen(dpy);
  1595. + const char *glx_extensions = NULL;
  1596. + const size_t len = strlen(query);
  1597. + const char *ptr;
  1598. +
  1599. + if (glx_extensions == NULL) {
  1600. + glx_extensions = glXQueryExtensionsString(dpy, scrnum);
  1601. + }
  1602. +
  1603. + ptr = strstr(glx_extensions, query);
  1604. + return ((ptr != NULL) && ((ptr[len] == ' ') || (ptr[len] == '\0')));
  1605. +}
  1606. +
  1607. +
  1608. +/**
  1609. + * Attempt to determine whether or not the display is synched to vblank.
  1610. + */
  1611. +static void
  1612. +query_vsync(Display *dpy, GLXDrawable drawable)
  1613. +{
  1614. + int interval = 0;
  1615. +
  1616. +#if defined(GLX_EXT_swap_control)
  1617. + if (is_glx_extension_supported(dpy, "GLX_EXT_swap_control")) {
  1618. + unsigned int tmp = -1;
  1619. + glXQueryDrawable(dpy, drawable, GLX_SWAP_INTERVAL_EXT, &tmp);
  1620. + interval = tmp;
  1621. + } else
  1622. +#endif
  1623. + if (is_glx_extension_supported(dpy, "GLX_MESA_swap_control")) {
  1624. + PFNGLXGETSWAPINTERVALMESAPROC pglXGetSwapIntervalMESA =
  1625. + (PFNGLXGETSWAPINTERVALMESAPROC)
  1626. + glXGetProcAddressARB((const GLubyte *) "glXGetSwapIntervalMESA");
  1627. +
  1628. + interval = (*pglXGetSwapIntervalMESA)();
  1629. + } else if (is_glx_extension_supported(dpy, "GLX_SGI_swap_control")) {
  1630. + /* The default swap interval with this extension is 1. Assume that it
  1631. + * is set to the default.
  1632. + *
  1633. + * Many Mesa-based drivers default to 0, but all of these drivers also
  1634. + * export GLX_MESA_swap_control. In that case, this branch will never
  1635. + * be taken, and the correct result should be reported.
  1636. + */
  1637. + interval = 1;
  1638. + }
  1639. +
  1640. +
  1641. + if (interval > 0) {
  1642. + printf("Running synchronized to the vertical refresh. The framerate should be\n");
  1643. + if (interval == 1) {
  1644. + printf("approximately the same as the monitor refresh rate.\n");
  1645. + } else if (interval > 1) {
  1646. + printf("approximately 1/%d the monitor refresh rate.\n",
  1647. + interval);
  1648. + }
  1649. + }
  1650. +}
  1651. +
  1652. +/**
  1653. + * Handle one X event.
  1654. + * \return NOP, EXIT or DRAW
  1655. + */
  1656. +static int
  1657. +handle_event(Display *dpy, Window win, XEvent *event)
  1658. +{
  1659. + (void) dpy;
  1660. + (void) win;
  1661. +
  1662. + switch (event->type) {
  1663. + case Expose:
  1664. + return DRAW;
  1665. + case ConfigureNotify:
  1666. + reshape(event->xconfigure.width, event->xconfigure.height);
  1667. + break;
  1668. + case KeyPress:
  1669. + {
  1670. + char buffer[10];
  1671. + int code;
  1672. + code = XLookupKeysym(&event->xkey, 0);
  1673. + if (code == XK_Left) {
  1674. + view_roty += 5.0;
  1675. + }
  1676. + else if (code == XK_Right) {
  1677. + view_roty -= 5.0;
  1678. + }
  1679. + else if (code == XK_Up) {
  1680. + view_rotx += 5.0;
  1681. + }
  1682. + else if (code == XK_Down) {
  1683. + view_rotx -= 5.0;
  1684. + }
  1685. + else {
  1686. + XLookupString(&event->xkey, buffer, sizeof(buffer),
  1687. + NULL, NULL);
  1688. + if (buffer[0] == 27) {
  1689. + /* escape */
  1690. + return EXIT;
  1691. + }
  1692. + else if (buffer[0] == 'a' || buffer[0] == 'A') {
  1693. + animate = !animate;
  1694. + }
  1695. + }
  1696. + return DRAW;
  1697. + }
  1698. + }
  1699. + return NOP;
  1700. +}
  1701. +
  1702. +
  1703. +static void
  1704. +event_loop(Display *dpy, Window win)
  1705. +{
  1706. + while (1) {
  1707. + int op;
  1708. + while (!animate || XPending(dpy) > 0) {
  1709. + XEvent event;
  1710. + XNextEvent(dpy, &event);
  1711. + op = handle_event(dpy, win, &event);
  1712. + if (op == EXIT)
  1713. + return;
  1714. + else if (op == DRAW)
  1715. + break;
  1716. + }
  1717. +
  1718. + draw_frame(dpy, win);
  1719. + }
  1720. +}
  1721. +
  1722. +
  1723. +static void
  1724. +usage(void)
  1725. +{
  1726. + printf("Usage:\n");
  1727. + printf(" -display <displayname> set the display to run on\n");
  1728. + printf(" -stereo run in stereo mode\n");
  1729. + printf(" -samples N run in multisample mode with at least N samples\n");
  1730. + printf(" -fullscreen run in fullscreen mode\n");
  1731. + printf(" -info display OpenGL renderer info\n");
  1732. + printf(" -geometry WxH+X+Y window geometry\n");
  1733. +}
  1734. +
  1735. +
  1736. +int
  1737. +main(int argc, char *argv[])
  1738. +{
  1739. + unsigned int winWidth = 300, winHeight = 300;
  1740. + int x = 0, y = 0;
  1741. + Display *dpy;
  1742. + Window win;
  1743. + GLXContext ctx;
  1744. + char *dpyName = NULL;
  1745. + GLboolean printInfo = GL_FALSE;
  1746. + VisualID visId;
  1747. + int i;
  1748. +
  1749. + for (i = 1; i < argc; i++) {
  1750. + if (strcmp(argv[i], "-display") == 0) {
  1751. + dpyName = argv[i+1];
  1752. + i++;
  1753. + }
  1754. + else if (strcmp(argv[i], "-info") == 0) {
  1755. + printInfo = GL_TRUE;
  1756. + }
  1757. + else if (strcmp(argv[i], "-stereo") == 0) {
  1758. + stereo = GL_TRUE;
  1759. + }
  1760. + else if (i < argc-1 && strcmp(argv[i], "-samples") == 0) {
  1761. + samples = strtod(argv[i+1], NULL );
  1762. + ++i;
  1763. + }
  1764. + else if (strcmp(argv[i], "-fullscreen") == 0) {
  1765. + fullscreen = GL_TRUE;
  1766. + }
  1767. + else if (i < argc-1 && strcmp(argv[i], "-geometry") == 0) {
  1768. + XParseGeometry(argv[i+1], &x, &y, &winWidth, &winHeight);
  1769. + i++;
  1770. + }
  1771. + else {
  1772. + usage();
  1773. + return -1;
  1774. + }
  1775. + }
  1776. +
  1777. + dpy = XOpenDisplay(dpyName);
  1778. + if (!dpy) {
  1779. + printf("Error: couldn't open display %s\n",
  1780. + dpyName ? dpyName : getenv("DISPLAY"));
  1781. + return -1;
  1782. + }
  1783. +
  1784. + if (fullscreen) {
  1785. + int scrnum = DefaultScreen(dpy);
  1786. +
  1787. + x = 0; y = 0;
  1788. + winWidth = DisplayWidth(dpy, scrnum);
  1789. + winHeight = DisplayHeight(dpy, scrnum);
  1790. + }
  1791. +
  1792. + make_window(dpy, "glxgears", x, y, winWidth, winHeight, &win, &ctx, &visId);
  1793. + XMapWindow(dpy, win);
  1794. + glXMakeCurrent(dpy, win, ctx);
  1795. + query_vsync(dpy, win);
  1796. +
  1797. + if (printInfo) {
  1798. + printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER));
  1799. + printf("GL_VERSION = %s\n", (char *) glGetString(GL_VERSION));
  1800. + printf("GL_VENDOR = %s\n", (char *) glGetString(GL_VENDOR));
  1801. + printf("GL_EXTENSIONS = %s\n", (char *) glGetString(GL_EXTENSIONS));
  1802. + printf("VisualID %d, 0x%x\n", (int) visId, (int) visId);
  1803. + }
  1804. +
  1805. + init();
  1806. +
  1807. + /* Set initial projection/viewing transformation.
  1808. + * We can't be sure we'll get a ConfigureNotify event when the window
  1809. + * first appears.
  1810. + */
  1811. + reshape(winWidth, winHeight);
  1812. +
  1813. + event_loop(dpy, win);
  1814. +
  1815. + glDeleteLists(gear1, 1);
  1816. + glDeleteLists(gear2, 1);
  1817. + glDeleteLists(gear3, 1);
  1818. + glXMakeCurrent(dpy, None, NULL);
  1819. + glXDestroyContext(dpy, ctx);
  1820. + XDestroyWindow(dpy, win);
  1821. + XCloseDisplay(dpy);
  1822. +
  1823. + return 0;
  1824. +}
  1825. diff -Naurp mesa-20.2.1-orig/src/glx/xdemos/glxinfo.1 mesa-20.2.1/src/glx/xdemos/glxinfo.1
  1826. --- mesa-20.2.1-orig/src/glx/xdemos/glxinfo.1 1969-12-31 18:00:00.000000000 -0600
  1827. +++ mesa-20.2.1/src/glx/xdemos/glxinfo.1 2020-10-15 23:06:45.826695773 -0500
  1828. @@ -0,0 +1,46 @@
  1829. +.TH glxinfo 1 "2006-11-29"
  1830. +.SH NAME
  1831. +glxinfo \- show information about the GLX implementation
  1832. +.SH SYNOPSIS
  1833. +.B glxinfo
  1834. +.RI [ options ]
  1835. +.SH DESCRIPTION
  1836. +The \fIglxinfo\fP program shows information about the OpenGL and GLX
  1837. +implementations running on a given X display.
  1838. +.PP
  1839. +The information includes details about the server- and client-side GLX
  1840. +implementation, the OpenGL and GLU implementations as well as a list
  1841. +of available GLX visuals.
  1842. +.SH OPTIONS
  1843. +.TP 8
  1844. +.B \-v
  1845. +Print visuals info in verbose form.
  1846. +.TP 8
  1847. +.B \-t
  1848. +Print verbose table.
  1849. +.TP 8
  1850. +.B \-display \fIdisplay\fP
  1851. +Specify the X display to interrogate.
  1852. +.TP 8
  1853. +.B \-h
  1854. +Print usage information.
  1855. +.TP 8
  1856. +.B \-i
  1857. +Force an indirect rendering context.
  1858. +.TP 8
  1859. +.B \-b
  1860. +Find the "best" visual and print its number.
  1861. +.TP 8
  1862. +.B \-l
  1863. +Print interesting OpenGL limits.
  1864. +.TP 8
  1865. +.B \-s
  1866. +Print a single extension per line.
  1867. +.SH AUTHOR
  1868. +glxinfo was written by Brian Paul <brian.paul@tungstengraphics.com>.
  1869. +.PP
  1870. +This manual page was written by Thierry Reding <thierry@gilfi.de>, for the
  1871. +Debian project and updated by Fernando de Oliveira <famobr at yahoo dot
  1872. +com dot br>, for the Linux From Scratch (LFS) project (but may be used by
  1873. +others).
  1874. +
  1875. diff -Naurp mesa-20.2.1-orig/src/glx/xdemos/glxinfo.c mesa-20.2.1/src/glx/xdemos/glxinfo.c
  1876. --- mesa-20.2.1-orig/src/glx/xdemos/glxinfo.c 1969-12-31 18:00:00.000000000 -0600
  1877. +++ mesa-20.2.1/src/glx/xdemos/glxinfo.c 2020-10-15 23:06:45.826695773 -0500
  1878. @@ -0,0 +1,1281 @@
  1879. +/*
  1880. + * Copyright (C) 1999-2006 Brian Paul All Rights Reserved.
  1881. + *
  1882. + * Permission is hereby granted, free of charge, to any person obtaining a
  1883. + * copy of this software and associated documentation files (the "Software"),
  1884. + * to deal in the Software without restriction, including without limitation
  1885. + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  1886. + * and/or sell copies of the Software, and to permit persons to whom the
  1887. + * Software is furnished to do so, subject to the following conditions:
  1888. + *
  1889. + * The above copyright notice and this permission notice shall be included
  1890. + * in all copies or substantial portions of the Software.
  1891. + *
  1892. + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  1893. + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  1894. + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  1895. + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
  1896. + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  1897. + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  1898. + */
  1899. +
  1900. +
  1901. +/*
  1902. + * This program is a work-alike of the IRIX glxinfo program.
  1903. + * Command line options:
  1904. + * -t print wide table
  1905. + * -v print verbose information
  1906. + * -display DisplayName specify the X display to interogate
  1907. + * -B brief, print only the basics
  1908. + * -b only print ID of "best" visual on screen 0
  1909. + * -i use indirect rendering connection only
  1910. + * -l print interesting OpenGL limits (added 5 Sep 2002)
  1911. + *
  1912. + * Brian Paul 26 January 2000
  1913. + */
  1914. +
  1915. +#define GLX_GLXEXT_PROTOTYPES
  1916. +#define GL_GLEXT_PROTOTYPES
  1917. +
  1918. +#include <assert.h>
  1919. +#include <X11/Xlib.h>
  1920. +#include <X11/Xutil.h>
  1921. +#include <GL/gl.h>
  1922. +#include <GL/glx.h>
  1923. +#include <stdio.h>
  1924. +#include <string.h>
  1925. +#include <stdlib.h>
  1926. +#include "glinfo_common.h"
  1927. +
  1928. +
  1929. +#ifndef GLX_NONE_EXT
  1930. +#define GLX_NONE_EXT 0x8000
  1931. +#endif
  1932. +
  1933. +#ifndef GLX_TRANSPARENT_RGB
  1934. +#define GLX_TRANSPARENT_RGB 0x8008
  1935. +#endif
  1936. +
  1937. +#ifndef GLX_RGBA_BIT
  1938. +#define GLX_RGBA_BIT 0x00000001
  1939. +#endif
  1940. +
  1941. +#ifndef GLX_COLOR_INDEX_BIT
  1942. +#define GLX_COLOR_INDEX_BIT 0x00000002
  1943. +#endif
  1944. +
  1945. +
  1946. +struct visual_attribs
  1947. +{
  1948. + /* X visual attribs */
  1949. + int id; /* May be visual ID or FBConfig ID */
  1950. + int vis_id; /* Visual ID. Only set for FBConfigs */
  1951. + int klass;
  1952. + int depth;
  1953. + int redMask, greenMask, blueMask;
  1954. + int colormapSize;
  1955. + int bitsPerRGB;
  1956. +
  1957. + /* GL visual attribs */
  1958. + int supportsGL;
  1959. + int drawableType;
  1960. + int transparentType;
  1961. + int transparentRedValue;
  1962. + int transparentGreenValue;
  1963. + int transparentBlueValue;
  1964. + int transparentAlphaValue;
  1965. + int transparentIndexValue;
  1966. + int bufferSize;
  1967. + int level;
  1968. + int render_type;
  1969. + int doubleBuffer;
  1970. + int stereo;
  1971. + int auxBuffers;
  1972. + int redSize, greenSize, blueSize, alphaSize;
  1973. + int depthSize;
  1974. + int stencilSize;
  1975. + int accumRedSize, accumGreenSize, accumBlueSize, accumAlphaSize;
  1976. + int numSamples, numMultisample;
  1977. + int visualCaveat;
  1978. + int floatComponents;
  1979. + int packedfloatComponents;
  1980. + int srgb;
  1981. +};
  1982. +
  1983. +
  1984. +/**
  1985. + * Version of the context that was created
  1986. + *
  1987. + * 20, 21, 30, 31, 32, etc.
  1988. + */
  1989. +static int version;
  1990. +
  1991. +/**
  1992. + * GL Error checking/warning.
  1993. + */
  1994. +static void
  1995. +CheckError(int line)
  1996. +{
  1997. + int n;
  1998. + n = glGetError();
  1999. + if (n)
  2000. + printf("Warning: GL error 0x%x at line %d\n", n, line);
  2001. +}
  2002. +
  2003. +
  2004. +static void
  2005. +print_display_info(Display *dpy)
  2006. +{
  2007. + printf("name of display: %s\n", DisplayString(dpy));
  2008. +}
  2009. +
  2010. +
  2011. +/**
  2012. + * Choose a simple FB Config.
  2013. + */
  2014. +static GLXFBConfig *
  2015. +choose_fb_config(Display *dpy, int scrnum)
  2016. +{
  2017. + int fbAttribSingle[] = {
  2018. + GLX_RENDER_TYPE, GLX_RGBA_BIT,
  2019. + GLX_RED_SIZE, 1,
  2020. + GLX_GREEN_SIZE, 1,
  2021. + GLX_BLUE_SIZE, 1,
  2022. + GLX_DOUBLEBUFFER, False,
  2023. + None };
  2024. + int fbAttribDouble[] = {
  2025. + GLX_RENDER_TYPE, GLX_RGBA_BIT,
  2026. + GLX_RED_SIZE, 1,
  2027. + GLX_GREEN_SIZE, 1,
  2028. + GLX_BLUE_SIZE, 1,
  2029. + GLX_DOUBLEBUFFER, True,
  2030. + None };
  2031. + GLXFBConfig *configs;
  2032. + int nConfigs;
  2033. +
  2034. + configs = glXChooseFBConfig(dpy, scrnum, fbAttribSingle, &nConfigs);
  2035. + if (!configs)
  2036. + configs = glXChooseFBConfig(dpy, scrnum, fbAttribDouble, &nConfigs);
  2037. +
  2038. + return configs;
  2039. +}
  2040. +
  2041. +
  2042. +static Bool CreateContextErrorFlag;
  2043. +
  2044. +static int
  2045. +create_context_error_handler(Display *dpy, XErrorEvent *error)
  2046. +{
  2047. + (void) dpy;
  2048. + (void) error->error_code;
  2049. + CreateContextErrorFlag = True;
  2050. + return 0;
  2051. +}
  2052. +
  2053. +
  2054. +/**
  2055. + * Try to create a GLX context of the given version with flags/options.
  2056. + * Note: A version number is required in order to get a core profile
  2057. + * (at least w/ NVIDIA).
  2058. + */
  2059. +static GLXContext
  2060. +create_context_flags(Display *dpy, GLXFBConfig fbconfig, int major, int minor,
  2061. + int contextFlags, int profileMask, Bool direct)
  2062. +{
  2063. +#ifdef GLX_ARB_create_context
  2064. + static PFNGLXCREATECONTEXTATTRIBSARBPROC glXCreateContextAttribsARB_func = 0;
  2065. + static Bool firstCall = True;
  2066. + int (*old_handler)(Display *, XErrorEvent *);
  2067. + GLXContext context;
  2068. + int attribs[20];
  2069. + int n = 0;
  2070. +
  2071. + if (firstCall) {
  2072. + /* See if we have GLX_ARB_create_context_profile and get pointer to
  2073. + * glXCreateContextAttribsARB() function.
  2074. + */
  2075. + const char *glxExt = glXQueryExtensionsString(dpy, 0);
  2076. + if (extension_supported("GLX_ARB_create_context_profile", glxExt)) {
  2077. + glXCreateContextAttribsARB_func = (PFNGLXCREATECONTEXTATTRIBSARBPROC)
  2078. + glXGetProcAddress((const GLubyte *) "glXCreateContextAttribsARB");
  2079. + }
  2080. + firstCall = False;
  2081. + }
  2082. +
  2083. + if (!glXCreateContextAttribsARB_func)
  2084. + return 0;
  2085. +
  2086. + /* setup attribute array */
  2087. + if (major) {
  2088. + attribs[n++] = GLX_CONTEXT_MAJOR_VERSION_ARB;
  2089. + attribs[n++] = major;
  2090. + attribs[n++] = GLX_CONTEXT_MINOR_VERSION_ARB;
  2091. + attribs[n++] = minor;
  2092. + }
  2093. + if (contextFlags) {
  2094. + attribs[n++] = GLX_CONTEXT_FLAGS_ARB;
  2095. + attribs[n++] = contextFlags;
  2096. + }
  2097. +#ifdef GLX_ARB_create_context_profile
  2098. + if (profileMask) {
  2099. + attribs[n++] = GLX_CONTEXT_PROFILE_MASK_ARB;
  2100. + attribs[n++] = profileMask;
  2101. + }
  2102. +#endif
  2103. + attribs[n++] = 0;
  2104. +
  2105. + /* install X error handler */
  2106. + old_handler = XSetErrorHandler(create_context_error_handler);
  2107. + CreateContextErrorFlag = False;
  2108. +
  2109. + /* try creating context */
  2110. + context = glXCreateContextAttribsARB_func(dpy,
  2111. + fbconfig,
  2112. + 0, /* share_context */
  2113. + direct,
  2114. + attribs);
  2115. +
  2116. + /* restore error handler */
  2117. + XSetErrorHandler(old_handler);
  2118. +
  2119. + if (CreateContextErrorFlag)
  2120. + context = 0;
  2121. +
  2122. + if (context && direct) {
  2123. + if (!glXIsDirect(dpy, context)) {
  2124. + glXDestroyContext(dpy, context);
  2125. + return 0;
  2126. + }
  2127. + }
  2128. +
  2129. + return context;
  2130. +#else
  2131. + return 0;
  2132. +#endif
  2133. +}
  2134. +
  2135. +
  2136. +/**
  2137. + * Try to create a GLX context of the newest version.
  2138. + */
  2139. +static GLXContext
  2140. +create_context_with_config(Display *dpy, GLXFBConfig config,
  2141. + Bool coreProfile, Bool es2Profile, Bool direct)
  2142. +{
  2143. + GLXContext ctx = 0;
  2144. +
  2145. + if (coreProfile) {
  2146. + /* Try to create a core profile, starting with the newest version of
  2147. + * GL that we're aware of. If we don't specify the version
  2148. + */
  2149. + int i;
  2150. + for (i = 0; gl_versions[i].major > 0; i++) {
  2151. + /* don't bother below GL 3.0 */
  2152. + if (gl_versions[i].major == 3 &&
  2153. + gl_versions[i].minor == 0)
  2154. + return 0;
  2155. + ctx = create_context_flags(dpy, config,
  2156. + gl_versions[i].major,
  2157. + gl_versions[i].minor,
  2158. + 0x0,
  2159. + GLX_CONTEXT_CORE_PROFILE_BIT_ARB,
  2160. + direct);
  2161. + if (ctx)
  2162. + return ctx;
  2163. + }
  2164. + /* couldn't get core profile context */
  2165. + return 0;
  2166. + }
  2167. +
  2168. + if (es2Profile) {
  2169. +#ifdef GLX_CONTEXT_ES2_PROFILE_BIT_EXT
  2170. + if (extension_supported("GLX_EXT_create_context_es2_profile",
  2171. + glXQueryExtensionsString(dpy, 0))) {
  2172. + ctx = create_context_flags(dpy, config, 2, 0, 0x0,
  2173. + GLX_CONTEXT_ES2_PROFILE_BIT_EXT,
  2174. + direct);
  2175. + return ctx;
  2176. + }
  2177. +#endif
  2178. + return 0;
  2179. + }
  2180. +
  2181. + /* GLX should return a context of the latest GL version that supports
  2182. + * the full profile.
  2183. + */
  2184. + ctx = glXCreateNewContext(dpy, config, GLX_RGBA_TYPE, NULL, direct);
  2185. +
  2186. + /* make sure the context is direct, if direct was requested */
  2187. + if (ctx && direct) {
  2188. + if (!glXIsDirect(dpy, ctx)) {
  2189. + glXDestroyContext(dpy, ctx);
  2190. + return 0;
  2191. + }
  2192. + }
  2193. +
  2194. + return ctx;
  2195. +}
  2196. +
  2197. +
  2198. +static XVisualInfo *
  2199. +choose_xvisinfo(Display *dpy, int scrnum)
  2200. +{
  2201. + int attribSingle[] = {
  2202. + GLX_RGBA,
  2203. + GLX_RED_SIZE, 1,
  2204. + GLX_GREEN_SIZE, 1,
  2205. + GLX_BLUE_SIZE, 1,
  2206. + None };
  2207. + int attribDouble[] = {
  2208. + GLX_RGBA,
  2209. + GLX_RED_SIZE, 1,
  2210. + GLX_GREEN_SIZE, 1,
  2211. + GLX_BLUE_SIZE, 1,
  2212. + GLX_DOUBLEBUFFER,
  2213. + None };
  2214. + XVisualInfo *visinfo;
  2215. +
  2216. + visinfo = glXChooseVisual(dpy, scrnum, attribSingle);
  2217. + if (!visinfo)
  2218. + visinfo = glXChooseVisual(dpy, scrnum, attribDouble);
  2219. +
  2220. + return visinfo;
  2221. +}
  2222. +
  2223. +
  2224. +static void
  2225. +query_renderer(void)
  2226. +{
  2227. +#ifdef GLX_MESA_query_renderer
  2228. + PFNGLXQUERYCURRENTRENDERERINTEGERMESAPROC queryInteger;
  2229. + PFNGLXQUERYCURRENTRENDERERSTRINGMESAPROC queryString;
  2230. + unsigned int v[3];
  2231. +
  2232. + queryInteger = (PFNGLXQUERYCURRENTRENDERERINTEGERMESAPROC)
  2233. + glXGetProcAddressARB((const GLubyte *)
  2234. + "glXQueryCurrentRendererIntegerMESA");
  2235. + queryString = (PFNGLXQUERYCURRENTRENDERERSTRINGMESAPROC)
  2236. + glXGetProcAddressARB((const GLubyte *)
  2237. + "glXQueryCurrentRendererStringMESA");
  2238. +
  2239. + printf("Extended renderer info (GLX_MESA_query_renderer):\n");
  2240. + queryInteger(GLX_RENDERER_VENDOR_ID_MESA, v);
  2241. + printf(" Vendor: %s (0x%x)\n",
  2242. + queryString(GLX_RENDERER_VENDOR_ID_MESA), *v);
  2243. + queryInteger(GLX_RENDERER_DEVICE_ID_MESA, v);
  2244. + printf(" Device: %s (0x%x)\n",
  2245. + queryString(GLX_RENDERER_DEVICE_ID_MESA), *v);
  2246. + queryInteger(GLX_RENDERER_VERSION_MESA, v);
  2247. + printf(" Version: %d.%d.%d\n", v[0], v[1], v[2]);
  2248. + queryInteger(GLX_RENDERER_ACCELERATED_MESA, v);
  2249. + printf(" Accelerated: %s\n", *v ? "yes" : "no");
  2250. + queryInteger(GLX_RENDERER_VIDEO_MEMORY_MESA, v);
  2251. + printf(" Video memory: %dMB\n", *v);
  2252. + queryInteger(GLX_RENDERER_UNIFIED_MEMORY_ARCHITECTURE_MESA, v);
  2253. + printf(" Unified memory: %s\n", *v ? "yes" : "no");
  2254. + queryInteger(GLX_RENDERER_PREFERRED_PROFILE_MESA, v);
  2255. + printf(" Preferred profile: %s (0x%x)\n",
  2256. + *v == GLX_CONTEXT_CORE_PROFILE_BIT_ARB ? "core" :
  2257. + *v == GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB ? "compat" :
  2258. + "unknown", *v);
  2259. + queryInteger(GLX_RENDERER_OPENGL_CORE_PROFILE_VERSION_MESA, v);
  2260. + printf(" Max core profile version: %d.%d\n", v[0], v[1]);
  2261. + queryInteger(GLX_RENDERER_OPENGL_COMPATIBILITY_PROFILE_VERSION_MESA, v);
  2262. + printf(" Max compat profile version: %d.%d\n", v[0], v[1]);
  2263. + queryInteger(GLX_RENDERER_OPENGL_ES_PROFILE_VERSION_MESA, v);
  2264. + printf(" Max GLES1 profile version: %d.%d\n", v[0], v[1]);
  2265. + queryInteger(GLX_RENDERER_OPENGL_ES2_PROFILE_VERSION_MESA, v);
  2266. + printf(" Max GLES[23] profile version: %d.%d\n", v[0], v[1]);
  2267. +#endif
  2268. +}
  2269. +
  2270. +
  2271. +static Bool
  2272. +print_screen_info(Display *dpy, int scrnum,
  2273. + const struct options *opts,
  2274. + Bool coreProfile, Bool es2Profile, Bool limits,
  2275. + Bool coreWorked)
  2276. +{
  2277. + Window win;
  2278. + XSetWindowAttributes attr;
  2279. + unsigned long mask;
  2280. + Window root;
  2281. + GLXContext ctx = NULL;
  2282. + XVisualInfo *visinfo;
  2283. + int width = 100, height = 100;
  2284. + GLXFBConfig *fbconfigs;
  2285. + const char *oglstring = coreProfile ? "OpenGL core profile" :
  2286. + es2Profile ? "OpenGL ES profile" : "OpenGL";
  2287. +
  2288. + root = RootWindow(dpy, scrnum);
  2289. +
  2290. + /*
  2291. + * Choose FBConfig or XVisualInfo and create a context.
  2292. + */
  2293. + fbconfigs = choose_fb_config(dpy, scrnum);
  2294. + if (fbconfigs) {
  2295. + ctx = create_context_with_config(dpy, fbconfigs[0],
  2296. + coreProfile, es2Profile,
  2297. + opts->allowDirect);
  2298. + if (!ctx && opts->allowDirect && !coreProfile) {
  2299. + /* try indirect */
  2300. + ctx = create_context_with_config(dpy, fbconfigs[0],
  2301. + coreProfile, es2Profile, False);
  2302. + }
  2303. +
  2304. + visinfo = glXGetVisualFromFBConfig(dpy, fbconfigs[0]);
  2305. + XFree(fbconfigs);
  2306. + }
  2307. + else if (!coreProfile && !es2Profile) {
  2308. + visinfo = choose_xvisinfo(dpy, scrnum);
  2309. + if (visinfo)
  2310. + ctx = glXCreateContext(dpy, visinfo, NULL, opts->allowDirect);
  2311. + } else
  2312. + visinfo = NULL;
  2313. +
  2314. + if (!visinfo && !coreProfile && !es2Profile) {
  2315. + fprintf(stderr, "Error: couldn't find RGB GLX visual or fbconfig\n");
  2316. + return False;
  2317. + }
  2318. +
  2319. + if (!ctx) {
  2320. + if (!coreProfile && !es2Profile)
  2321. + fprintf(stderr, "Error: glXCreateContext failed\n");
  2322. + XFree(visinfo);
  2323. + return False;
  2324. + }
  2325. +
  2326. + /*
  2327. + * Create a window so that we can just bind the context.
  2328. + */
  2329. + attr.background_pixel = 0;
  2330. + attr.border_pixel = 0;
  2331. + attr.colormap = XCreateColormap(dpy, root, visinfo->visual, AllocNone);
  2332. + attr.event_mask = StructureNotifyMask | ExposureMask;
  2333. + mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
  2334. + win = XCreateWindow(dpy, root, 0, 0, width, height,
  2335. + 0, visinfo->depth, InputOutput,
  2336. + visinfo->visual, mask, &attr);
  2337. +
  2338. + if (glXMakeCurrent(dpy, win, ctx)) {
  2339. + const char *serverVendor = glXQueryServerString(dpy, scrnum, GLX_VENDOR);
  2340. + const char *serverVersion = glXQueryServerString(dpy, scrnum, GLX_VERSION);
  2341. + const char *serverExtensions = glXQueryServerString(dpy, scrnum, GLX_EXTENSIONS);
  2342. + const char *clientVendor = glXGetClientString(dpy, GLX_VENDOR);
  2343. + const char *clientVersion = glXGetClientString(dpy, GLX_VERSION);
  2344. + const char *clientExtensions = glXGetClientString(dpy, GLX_EXTENSIONS);
  2345. + const char *glxExtensions = glXQueryExtensionsString(dpy, scrnum);
  2346. + const char *glVendor = (const char *) glGetString(GL_VENDOR);
  2347. + const char *glRenderer = (const char *) glGetString(GL_RENDERER);
  2348. + const char *glVersion = (const char *) glGetString(GL_VERSION);
  2349. + char *glExtensions = NULL;
  2350. + int glxVersionMajor = 0;
  2351. + int glxVersionMinor = 0;
  2352. + char *displayName = NULL;
  2353. + char *colon = NULL, *period = NULL;
  2354. + struct ext_functions extfuncs;
  2355. +
  2356. + CheckError(__LINE__);
  2357. +
  2358. + /* Get some ext functions */
  2359. + extfuncs.GetProgramivARB = (GETPROGRAMIVARBPROC)
  2360. + glXGetProcAddressARB((GLubyte *) "glGetProgramivARB");
  2361. + extfuncs.GetStringi = (GETSTRINGIPROC)
  2362. + glXGetProcAddressARB((GLubyte *) "glGetStringi");
  2363. + extfuncs.GetConvolutionParameteriv = (GETCONVOLUTIONPARAMETERIVPROC)
  2364. + glXGetProcAddressARB((GLubyte *) "glGetConvolutionParameteriv");
  2365. +
  2366. + if (!glXQueryVersion(dpy, & glxVersionMajor, & glxVersionMinor)) {
  2367. + fprintf(stderr, "Error: glXQueryVersion failed\n");
  2368. + exit(1);
  2369. + }
  2370. +
  2371. + /* Get list of GL extensions */
  2372. + if (coreProfile && extfuncs.GetStringi)
  2373. + glExtensions = build_core_profile_extension_list(&extfuncs);
  2374. + if (!glExtensions) {
  2375. + coreProfile = False;
  2376. + glExtensions = (char *) glGetString(GL_EXTENSIONS);
  2377. + }
  2378. +
  2379. + CheckError(__LINE__);
  2380. +
  2381. + if (!coreWorked) {
  2382. + /* Strip the screen number from the display name, if present. */
  2383. + if (!(displayName = (char *) malloc(strlen(DisplayString(dpy)) + 1))) {
  2384. + fprintf(stderr, "Error: malloc() failed\n");
  2385. + exit(1);
  2386. + }
  2387. + strcpy(displayName, DisplayString(dpy));
  2388. + colon = strrchr(displayName, ':');
  2389. + if (colon) {
  2390. + period = strchr(colon, '.');
  2391. + if (period)
  2392. + *period = '\0';
  2393. + }
  2394. +
  2395. + printf("display: %s screen: %d\n", displayName, scrnum);
  2396. + free(displayName);
  2397. + printf("direct rendering: ");
  2398. + if (glXIsDirect(dpy, ctx)) {
  2399. + printf("Yes\n");
  2400. + }
  2401. + else {
  2402. + if (!opts->allowDirect) {
  2403. + printf("No (-i specified)\n");
  2404. + }
  2405. + else if (getenv("LIBGL_ALWAYS_INDIRECT")) {
  2406. + printf("No (LIBGL_ALWAYS_INDIRECT set)\n");
  2407. + }
  2408. + else {
  2409. + printf("No (If you want to find out why, try setting "
  2410. + "LIBGL_DEBUG=verbose)\n");
  2411. + }
  2412. + }
  2413. + if (opts->mode != Brief) {
  2414. + printf("server glx vendor string: %s\n", serverVendor);
  2415. + printf("server glx version string: %s\n", serverVersion);
  2416. + printf("server glx extensions:\n");
  2417. + print_extension_list(serverExtensions, opts->singleLine);
  2418. + printf("client glx vendor string: %s\n", clientVendor);
  2419. + printf("client glx version string: %s\n", clientVersion);
  2420. + printf("client glx extensions:\n");
  2421. + print_extension_list(clientExtensions, opts->singleLine);
  2422. + printf("GLX version: %u.%u\n", glxVersionMajor, glxVersionMinor);
  2423. + printf("GLX extensions:\n");
  2424. + print_extension_list(glxExtensions, opts->singleLine);
  2425. + }
  2426. + if (strstr(glxExtensions, "GLX_MESA_query_renderer"))
  2427. + query_renderer();
  2428. + printf("OpenGL vendor string: %s\n", glVendor);
  2429. + printf("OpenGL renderer string: %s\n", glRenderer);
  2430. + } else
  2431. + printf("\n");
  2432. +
  2433. + printf("%s version string: %s\n", oglstring, glVersion);
  2434. +
  2435. + version = (glVersion[0] - '0') * 10 + (glVersion[2] - '0');
  2436. +
  2437. + CheckError(__LINE__);
  2438. +
  2439. +#ifdef GL_VERSION_2_0
  2440. + if (version >= 20) {
  2441. + char *v = (char *) glGetString(GL_SHADING_LANGUAGE_VERSION);
  2442. + printf("%s shading language version string: %s\n", oglstring, v);
  2443. + }
  2444. +#endif
  2445. + CheckError(__LINE__);
  2446. +#ifdef GL_VERSION_3_0
  2447. + if (version >= 30 && !es2Profile) {
  2448. + GLint flags;
  2449. + glGetIntegerv(GL_CONTEXT_FLAGS, &flags);
  2450. + printf("%s context flags: %s\n", oglstring, context_flags_string(flags));
  2451. + }
  2452. +#endif
  2453. + CheckError(__LINE__);
  2454. +#ifdef GL_VERSION_3_2
  2455. + if (version >= 32 && !es2Profile) {
  2456. + GLint mask;
  2457. + glGetIntegerv(GL_CONTEXT_PROFILE_MASK, &mask);
  2458. + printf("%s profile mask: %s\n", oglstring, profile_mask_string(mask));
  2459. + }
  2460. +#endif
  2461. +
  2462. + CheckError(__LINE__);
  2463. +
  2464. + if (opts->mode != Brief) {
  2465. + printf("%s extensions:\n", oglstring);
  2466. + print_extension_list(glExtensions, opts->singleLine);
  2467. + }
  2468. +
  2469. + if (limits) {
  2470. + print_limits(glExtensions, oglstring, version, &extfuncs);
  2471. + }
  2472. +
  2473. + if (coreProfile)
  2474. + free(glExtensions);
  2475. + }
  2476. + else {
  2477. + fprintf(stderr, "Error: glXMakeCurrent failed\n");
  2478. + }
  2479. +
  2480. + glXDestroyContext(dpy, ctx);
  2481. + XFree(visinfo);
  2482. + XDestroyWindow(dpy, win);
  2483. + XSync(dpy, 1);
  2484. + return True;
  2485. +}
  2486. +
  2487. +
  2488. +static const char *
  2489. +visual_class_name(int cls)
  2490. +{
  2491. + switch (cls) {
  2492. + case StaticColor:
  2493. + return "StaticColor";
  2494. + case PseudoColor:
  2495. + return "PseudoColor";
  2496. + case StaticGray:
  2497. + return "StaticGray";
  2498. + case GrayScale:
  2499. + return "GrayScale";
  2500. + case TrueColor:
  2501. + return "TrueColor";
  2502. + case DirectColor:
  2503. + return "DirectColor";
  2504. + default:
  2505. + return "";
  2506. + }
  2507. +}
  2508. +
  2509. +static const char *
  2510. +visual_drawable_type(int type)
  2511. +{
  2512. + const static struct bit_info bits[] = {
  2513. + { GLX_WINDOW_BIT, "window" },
  2514. + { GLX_PIXMAP_BIT, "pixmap" },
  2515. + { GLX_PBUFFER_BIT, "pbuffer" }
  2516. + };
  2517. +
  2518. + return bitmask_to_string(bits, ELEMENTS(bits), type);
  2519. +}
  2520. +
  2521. +static const char *
  2522. +visual_class_abbrev(int cls)
  2523. +{
  2524. + switch (cls) {
  2525. + case StaticColor:
  2526. + return "sc";
  2527. + case PseudoColor:
  2528. + return "pc";
  2529. + case StaticGray:
  2530. + return "sg";
  2531. + case GrayScale:
  2532. + return "gs";
  2533. + case TrueColor:
  2534. + return "tc";
  2535. + case DirectColor:
  2536. + return "dc";
  2537. + default:
  2538. + return "";
  2539. + }
  2540. +}
  2541. +
  2542. +static const char *
  2543. +visual_render_type_name(int type)
  2544. +{
  2545. + switch (type) {
  2546. + case GLX_RGBA_UNSIGNED_FLOAT_BIT_EXT:
  2547. + return "ufloat";
  2548. + case GLX_RGBA_FLOAT_BIT_ARB:
  2549. + return "float";
  2550. + case GLX_RGBA_BIT:
  2551. + return "rgba";
  2552. + case GLX_COLOR_INDEX_BIT:
  2553. + return "ci";
  2554. + case GLX_RGBA_BIT | GLX_COLOR_INDEX_BIT:
  2555. + return "rgba|ci";
  2556. + default:
  2557. + return "";
  2558. + }
  2559. +}
  2560. +
  2561. +static const char *
  2562. +caveat_string(int caveat)
  2563. +{
  2564. + switch (caveat) {
  2565. +#ifdef GLX_EXT_visual_rating
  2566. + case GLX_SLOW_VISUAL_EXT:
  2567. + return "Slow";
  2568. + case GLX_NON_CONFORMANT_VISUAL_EXT:
  2569. + return "Ncon";
  2570. + case GLX_NONE_EXT:
  2571. + /* fall-through */
  2572. +#endif
  2573. + case 0:
  2574. + /* fall-through */
  2575. + default:
  2576. + return "None";
  2577. + }
  2578. +}
  2579. +
  2580. +
  2581. +static Bool
  2582. +get_visual_attribs(Display *dpy, XVisualInfo *vInfo,
  2583. + struct visual_attribs *attribs)
  2584. +{
  2585. + const char *ext = glXQueryExtensionsString(dpy, vInfo->screen);
  2586. + int rgba;
  2587. +
  2588. + memset(attribs, 0, sizeof(struct visual_attribs));
  2589. +
  2590. + attribs->id = vInfo->visualid;
  2591. +#if defined(__cplusplus) || defined(c_plusplus)
  2592. + attribs->klass = vInfo->c_class;
  2593. +#else
  2594. + attribs->klass = vInfo->class;
  2595. +#endif
  2596. + attribs->depth = vInfo->depth;
  2597. + attribs->redMask = vInfo->red_mask;
  2598. + attribs->greenMask = vInfo->green_mask;
  2599. + attribs->blueMask = vInfo->blue_mask;
  2600. + attribs->colormapSize = vInfo->colormap_size;
  2601. + attribs->bitsPerRGB = vInfo->bits_per_rgb;
  2602. +
  2603. + if (glXGetConfig(dpy, vInfo, GLX_USE_GL, &attribs->supportsGL) != 0 ||
  2604. + !attribs->supportsGL)
  2605. + return False;
  2606. + glXGetConfig(dpy, vInfo, GLX_BUFFER_SIZE, &attribs->bufferSize);
  2607. + glXGetConfig(dpy, vInfo, GLX_LEVEL, &attribs->level);
  2608. + glXGetConfig(dpy, vInfo, GLX_RGBA, &rgba);
  2609. + if (rgba)
  2610. + attribs->render_type = GLX_RGBA_BIT;
  2611. + else
  2612. + attribs->render_type = GLX_COLOR_INDEX_BIT;
  2613. +
  2614. + glXGetConfig(dpy, vInfo, GLX_DRAWABLE_TYPE, &attribs->drawableType);
  2615. + glXGetConfig(dpy, vInfo, GLX_DOUBLEBUFFER, &attribs->doubleBuffer);
  2616. + glXGetConfig(dpy, vInfo, GLX_STEREO, &attribs->stereo);
  2617. + glXGetConfig(dpy, vInfo, GLX_AUX_BUFFERS, &attribs->auxBuffers);
  2618. + glXGetConfig(dpy, vInfo, GLX_RED_SIZE, &attribs->redSize);
  2619. + glXGetConfig(dpy, vInfo, GLX_GREEN_SIZE, &attribs->greenSize);
  2620. + glXGetConfig(dpy, vInfo, GLX_BLUE_SIZE, &attribs->blueSize);
  2621. + glXGetConfig(dpy, vInfo, GLX_ALPHA_SIZE, &attribs->alphaSize);
  2622. + glXGetConfig(dpy, vInfo, GLX_DEPTH_SIZE, &attribs->depthSize);
  2623. + glXGetConfig(dpy, vInfo, GLX_STENCIL_SIZE, &attribs->stencilSize);
  2624. + glXGetConfig(dpy, vInfo, GLX_ACCUM_RED_SIZE, &attribs->accumRedSize);
  2625. + glXGetConfig(dpy, vInfo, GLX_ACCUM_GREEN_SIZE, &attribs->accumGreenSize);
  2626. + glXGetConfig(dpy, vInfo, GLX_ACCUM_BLUE_SIZE, &attribs->accumBlueSize);
  2627. + glXGetConfig(dpy, vInfo, GLX_ACCUM_ALPHA_SIZE, &attribs->accumAlphaSize);
  2628. +
  2629. + /* get transparent pixel stuff */
  2630. + glXGetConfig(dpy, vInfo,GLX_TRANSPARENT_TYPE, &attribs->transparentType);
  2631. + if (attribs->transparentType == GLX_TRANSPARENT_RGB) {
  2632. + glXGetConfig(dpy, vInfo, GLX_TRANSPARENT_RED_VALUE, &attribs->transparentRedValue);
  2633. + glXGetConfig(dpy, vInfo, GLX_TRANSPARENT_GREEN_VALUE, &attribs->transparentGreenValue);
  2634. + glXGetConfig(dpy, vInfo, GLX_TRANSPARENT_BLUE_VALUE, &attribs->transparentBlueValue);
  2635. + glXGetConfig(dpy, vInfo, GLX_TRANSPARENT_ALPHA_VALUE, &attribs->transparentAlphaValue);
  2636. + }
  2637. + else if (attribs->transparentType == GLX_TRANSPARENT_INDEX) {
  2638. + glXGetConfig(dpy, vInfo, GLX_TRANSPARENT_INDEX_VALUE, &attribs->transparentIndexValue);
  2639. + }
  2640. +
  2641. + /* multisample attribs */
  2642. +#ifdef GLX_ARB_multisample
  2643. + if (ext && strstr(ext, "GLX_ARB_multisample")) {
  2644. + glXGetConfig(dpy, vInfo, GLX_SAMPLE_BUFFERS_ARB, &attribs->numMultisample);
  2645. + glXGetConfig(dpy, vInfo, GLX_SAMPLES_ARB, &attribs->numSamples);
  2646. + }
  2647. +#endif
  2648. + else {
  2649. + attribs->numSamples = 0;
  2650. + attribs->numMultisample = 0;
  2651. + }
  2652. +
  2653. +#if defined(GLX_EXT_visual_rating)
  2654. + if (ext && strstr(ext, "GLX_EXT_visual_rating")) {
  2655. + glXGetConfig(dpy, vInfo, GLX_VISUAL_CAVEAT_EXT, &attribs->visualCaveat);
  2656. + }
  2657. + else {
  2658. + attribs->visualCaveat = GLX_NONE_EXT;
  2659. + }
  2660. +#else
  2661. + attribs->visualCaveat = 0;
  2662. +#endif
  2663. +
  2664. +#if defined(GLX_EXT_framebuffer_sRGB)
  2665. + if (ext && strstr(ext, "GLX_EXT_framebuffer_sRGB")) {
  2666. + glXGetConfig(dpy, vInfo, GLX_FRAMEBUFFER_SRGB_CAPABLE_EXT, &attribs->srgb);
  2667. + }
  2668. +#endif
  2669. +
  2670. + return True;
  2671. +}
  2672. +
  2673. +#ifdef GLX_VERSION_1_3
  2674. +
  2675. +static int
  2676. +glx_token_to_visual_class(int visual_type)
  2677. +{
  2678. + switch (visual_type) {
  2679. + case GLX_TRUE_COLOR:
  2680. + return TrueColor;
  2681. + case GLX_DIRECT_COLOR:
  2682. + return DirectColor;
  2683. + case GLX_PSEUDO_COLOR:
  2684. + return PseudoColor;
  2685. + case GLX_STATIC_COLOR:
  2686. + return StaticColor;
  2687. + case GLX_GRAY_SCALE:
  2688. + return GrayScale;
  2689. + case GLX_STATIC_GRAY:
  2690. + return StaticGray;
  2691. + case GLX_NONE:
  2692. + default:
  2693. + return None;
  2694. + }
  2695. +}
  2696. +
  2697. +static Bool
  2698. +get_fbconfig_attribs(Display *dpy, GLXFBConfig fbconfig,
  2699. + struct visual_attribs *attribs)
  2700. +{
  2701. + const char *ext = glXQueryExtensionsString(dpy, 0);
  2702. + int visual_type;
  2703. + XVisualInfo *vInfo;
  2704. +
  2705. + memset(attribs, 0, sizeof(struct visual_attribs));
  2706. +
  2707. + glXGetFBConfigAttrib(dpy, fbconfig, GLX_FBCONFIG_ID, &attribs->id);
  2708. +
  2709. + vInfo = glXGetVisualFromFBConfig(dpy, fbconfig);
  2710. +
  2711. + if (vInfo != NULL) {
  2712. + attribs->vis_id = vInfo->visualid;
  2713. + attribs->depth = vInfo->depth;
  2714. + attribs->redMask = vInfo->red_mask;
  2715. + attribs->greenMask = vInfo->green_mask;
  2716. + attribs->blueMask = vInfo->blue_mask;
  2717. + attribs->colormapSize = vInfo->colormap_size;
  2718. + attribs->bitsPerRGB = vInfo->bits_per_rgb;
  2719. + }
  2720. +
  2721. + glXGetFBConfigAttrib(dpy, fbconfig, GLX_X_VISUAL_TYPE, &visual_type);
  2722. + attribs->klass = glx_token_to_visual_class(visual_type);
  2723. +
  2724. + glXGetFBConfigAttrib(dpy, fbconfig, GLX_DRAWABLE_TYPE, &attribs->drawableType);
  2725. + glXGetFBConfigAttrib(dpy, fbconfig, GLX_BUFFER_SIZE, &attribs->bufferSize);
  2726. + glXGetFBConfigAttrib(dpy, fbconfig, GLX_LEVEL, &attribs->level);
  2727. + glXGetFBConfigAttrib(dpy, fbconfig, GLX_RENDER_TYPE, &attribs->render_type);
  2728. + glXGetFBConfigAttrib(dpy, fbconfig, GLX_DOUBLEBUFFER, &attribs->doubleBuffer);
  2729. + glXGetFBConfigAttrib(dpy, fbconfig, GLX_STEREO, &attribs->stereo);
  2730. + glXGetFBConfigAttrib(dpy, fbconfig, GLX_AUX_BUFFERS, &attribs->auxBuffers);
  2731. +
  2732. + glXGetFBConfigAttrib(dpy, fbconfig, GLX_RED_SIZE, &attribs->redSize);
  2733. + glXGetFBConfigAttrib(dpy, fbconfig, GLX_GREEN_SIZE, &attribs->greenSize);
  2734. + glXGetFBConfigAttrib(dpy, fbconfig, GLX_BLUE_SIZE, &attribs->blueSize);
  2735. + glXGetFBConfigAttrib(dpy, fbconfig, GLX_ALPHA_SIZE, &attribs->alphaSize);
  2736. + glXGetFBConfigAttrib(dpy, fbconfig, GLX_DEPTH_SIZE, &attribs->depthSize);
  2737. + glXGetFBConfigAttrib(dpy, fbconfig, GLX_STENCIL_SIZE, &attribs->stencilSize);
  2738. +
  2739. + glXGetFBConfigAttrib(dpy, fbconfig, GLX_ACCUM_RED_SIZE, &attribs->accumRedSize);
  2740. + glXGetFBConfigAttrib(dpy, fbconfig, GLX_ACCUM_GREEN_SIZE, &attribs->accumGreenSize);
  2741. + glXGetFBConfigAttrib(dpy, fbconfig, GLX_ACCUM_BLUE_SIZE, &attribs->accumBlueSize);
  2742. + glXGetFBConfigAttrib(dpy, fbconfig, GLX_ACCUM_ALPHA_SIZE, &attribs->accumAlphaSize);
  2743. +
  2744. + /* get transparent pixel stuff */
  2745. + glXGetFBConfigAttrib(dpy, fbconfig,GLX_TRANSPARENT_TYPE, &attribs->transparentType);
  2746. + if (attribs->transparentType == GLX_TRANSPARENT_RGB) {
  2747. + glXGetFBConfigAttrib(dpy, fbconfig, GLX_TRANSPARENT_RED_VALUE, &attribs->transparentRedValue);
  2748. + glXGetFBConfigAttrib(dpy, fbconfig, GLX_TRANSPARENT_GREEN_VALUE, &attribs->transparentGreenValue);
  2749. + glXGetFBConfigAttrib(dpy, fbconfig, GLX_TRANSPARENT_BLUE_VALUE, &attribs->transparentBlueValue);
  2750. + glXGetFBConfigAttrib(dpy, fbconfig, GLX_TRANSPARENT_ALPHA_VALUE, &attribs->transparentAlphaValue);
  2751. + }
  2752. + else if (attribs->transparentType == GLX_TRANSPARENT_INDEX) {
  2753. + glXGetFBConfigAttrib(dpy, fbconfig, GLX_TRANSPARENT_INDEX_VALUE, &attribs->transparentIndexValue);
  2754. + }
  2755. +
  2756. + glXGetFBConfigAttrib(dpy, fbconfig, GLX_SAMPLE_BUFFERS, &attribs->numMultisample);
  2757. + glXGetFBConfigAttrib(dpy, fbconfig, GLX_SAMPLES, &attribs->numSamples);
  2758. + glXGetFBConfigAttrib(dpy, fbconfig, GLX_CONFIG_CAVEAT, &attribs->visualCaveat);
  2759. +
  2760. +#if defined(GLX_NV_float_buffer)
  2761. + if (ext && strstr(ext, "GLX_NV_float_buffer")) {
  2762. + glXGetFBConfigAttrib(dpy, fbconfig, GLX_FLOAT_COMPONENTS_NV, &attribs->floatComponents);
  2763. + }
  2764. +#endif
  2765. +#if defined(GLX_ARB_fbconfig_float)
  2766. + if (ext && strstr(ext, "GLX_ARB_fbconfig_float")) {
  2767. + if (attribs->render_type & GLX_RGBA_FLOAT_BIT_ARB) {
  2768. + attribs->floatComponents = True;
  2769. + }
  2770. + }
  2771. +#endif
  2772. +#if defined(GLX_EXT_fbconfig_packed_float)
  2773. + if (ext && strstr(ext, "GLX_EXT_fbconfig_packed_float")) {
  2774. + if (attribs->render_type & GLX_RGBA_UNSIGNED_FLOAT_BIT_EXT) {
  2775. + attribs->packedfloatComponents = True;
  2776. + }
  2777. + }
  2778. +#endif
  2779. +
  2780. +#if defined(GLX_EXT_framebuffer_sRGB)
  2781. + if (ext && strstr(ext, "GLX_EXT_framebuffer_sRGB")) {
  2782. + glXGetFBConfigAttrib(dpy, fbconfig, GLX_FRAMEBUFFER_SRGB_CAPABLE_EXT, &attribs->srgb);
  2783. + }
  2784. +#endif
  2785. + return True;
  2786. +}
  2787. +
  2788. +#endif
  2789. +
  2790. +
  2791. +
  2792. +static void
  2793. +print_visual_attribs_verbose(const struct visual_attribs *attribs,
  2794. + int fbconfigs)
  2795. +{
  2796. + if (fbconfigs) {
  2797. + printf("FBConfig ID: %x Visual ID=%x depth=%d class=%s, type=%s\n",
  2798. + attribs->id, attribs->vis_id, attribs->depth,
  2799. + visual_class_name(attribs->klass),
  2800. + visual_drawable_type(attribs->drawableType));
  2801. + }
  2802. + else {
  2803. + printf("Visual ID: %x depth=%d class=%s, type=%s\n",
  2804. + attribs->id, attribs->depth, visual_class_name(attribs->klass),
  2805. + visual_drawable_type(attribs->drawableType));
  2806. + }
  2807. + printf(" bufferSize=%d level=%d renderType=%s doubleBuffer=%d stereo=%d\n",
  2808. + attribs->bufferSize, attribs->level,
  2809. + visual_render_type_name(attribs->render_type),
  2810. + attribs->doubleBuffer, attribs->stereo);
  2811. + printf(" rgba: redSize=%d greenSize=%d blueSize=%d alphaSize=%d float=%c sRGB=%c\n",
  2812. + attribs->redSize, attribs->greenSize,
  2813. + attribs->blueSize, attribs->alphaSize,
  2814. + attribs->packedfloatComponents ? 'P' : attribs->floatComponents ? 'Y' : 'N',
  2815. + attribs->srgb ? 'Y' : 'N');
  2816. + printf(" auxBuffers=%d depthSize=%d stencilSize=%d\n",
  2817. + attribs->auxBuffers, attribs->depthSize, attribs->stencilSize);
  2818. + printf(" accum: redSize=%d greenSize=%d blueSize=%d alphaSize=%d\n",
  2819. + attribs->accumRedSize, attribs->accumGreenSize,
  2820. + attribs->accumBlueSize, attribs->accumAlphaSize);
  2821. + printf(" multiSample=%d multiSampleBuffers=%d\n",
  2822. + attribs->numSamples, attribs->numMultisample);
  2823. +#ifdef GLX_EXT_visual_rating
  2824. + if (attribs->visualCaveat == GLX_NONE_EXT || attribs->visualCaveat == 0)
  2825. + printf(" visualCaveat=None\n");
  2826. + else if (attribs->visualCaveat == GLX_SLOW_VISUAL_EXT)
  2827. + printf(" visualCaveat=Slow\n");
  2828. + else if (attribs->visualCaveat == GLX_NON_CONFORMANT_VISUAL_EXT)
  2829. + printf(" visualCaveat=Nonconformant\n");
  2830. +#endif
  2831. + if (attribs->transparentType == GLX_NONE) {
  2832. + printf(" Opaque.\n");
  2833. + }
  2834. + else if (attribs->transparentType == GLX_TRANSPARENT_RGB) {
  2835. + printf(" Transparent RGB: Red=%d Green=%d Blue=%d Alpha=%d\n",attribs->transparentRedValue,attribs->transparentGreenValue,attribs->transparentBlueValue,attribs->transparentAlphaValue);
  2836. + }
  2837. + else if (attribs->transparentType == GLX_TRANSPARENT_INDEX) {
  2838. + printf(" Transparent index=%d\n",attribs->transparentIndexValue);
  2839. + }
  2840. +}
  2841. +
  2842. +
  2843. +static void
  2844. +print_visual_attribs_short_header(void)
  2845. +{
  2846. + printf(" visual x bf lv rg d st colorbuffer sr ax dp st accumbuffer ms cav\n");
  2847. + printf(" id dep cl sp sz l ci b ro r g b a F gb bf th cl r g b a ns b eat\n");
  2848. + printf("----------------------------------------------------------------------------\n");
  2849. +}
  2850. +
  2851. +
  2852. +static void
  2853. +print_visual_attribs_short(const struct visual_attribs *attribs)
  2854. +{
  2855. + const char *caveat = caveat_string(attribs->visualCaveat);
  2856. +
  2857. + printf("0x%03x %2d %2s %2d %3d %2d %c%c %c %c %2d %2d %2d %2d %c %c %2d %2d %2d",
  2858. + attribs->id,
  2859. + attribs->depth,
  2860. + visual_class_abbrev(attribs->klass),
  2861. + attribs->transparentType != GLX_NONE,
  2862. + attribs->bufferSize,
  2863. + attribs->level,
  2864. + (attribs->render_type & GLX_RGBA_BIT) ? 'r' : ' ',
  2865. + (attribs->render_type & GLX_COLOR_INDEX_BIT) ? 'c' : ' ',
  2866. + attribs->doubleBuffer ? 'y' : '.',
  2867. + attribs->stereo ? 'y' : '.',
  2868. + attribs->redSize, attribs->greenSize,
  2869. + attribs->blueSize, attribs->alphaSize,
  2870. + attribs->packedfloatComponents ? 'u' : attribs->floatComponents ? 'f' : '.',
  2871. + attribs->srgb ? 's' : '.',
  2872. + attribs->auxBuffers,
  2873. + attribs->depthSize,
  2874. + attribs->stencilSize
  2875. + );
  2876. +
  2877. + printf(" %2d %2d %2d %2d %2d %1d %s\n",
  2878. + attribs->accumRedSize, attribs->accumGreenSize,
  2879. + attribs->accumBlueSize, attribs->accumAlphaSize,
  2880. + attribs->numSamples, attribs->numMultisample,
  2881. + caveat
  2882. + );
  2883. +}
  2884. +
  2885. +
  2886. +static void
  2887. +print_visual_attribs_long_header(void)
  2888. +{
  2889. + printf("Vis Vis Visual Trans buff lev render DB ste r g b a s aux dep ste accum buffer MS MS \n");
  2890. + printf(" ID Depth Type parent size el type reo sz sz sz sz flt rgb buf th ncl r g b a num bufs caveats\n");
  2891. + printf("--------------------------------------------------------------------------------------------------------------------\n");
  2892. +}
  2893. +
  2894. +
  2895. +static void
  2896. +print_visual_attribs_long(const struct visual_attribs *attribs)
  2897. +{
  2898. + const char *caveat = caveat_string(attribs->visualCaveat);
  2899. +
  2900. + printf("0x%3x %2d %-11s %2d %3d %2d %4s %3d %3d %3d %3d %3d %3d",
  2901. + attribs->id,
  2902. + attribs->depth,
  2903. + visual_class_name(attribs->klass),
  2904. + attribs->transparentType != GLX_NONE,
  2905. + attribs->bufferSize,
  2906. + attribs->level,
  2907. + visual_render_type_name(attribs->render_type),
  2908. + attribs->doubleBuffer,
  2909. + attribs->stereo,
  2910. + attribs->redSize, attribs->greenSize,
  2911. + attribs->blueSize, attribs->alphaSize
  2912. + );
  2913. +
  2914. + printf(" %c %c %3d %4d %2d %3d %3d %3d %3d %2d %2d %6s\n",
  2915. + attribs->floatComponents ? 'f' : '.',
  2916. + attribs->srgb ? 's' : '.',
  2917. + attribs->auxBuffers,
  2918. + attribs->depthSize,
  2919. + attribs->stencilSize,
  2920. + attribs->accumRedSize, attribs->accumGreenSize,
  2921. + attribs->accumBlueSize, attribs->accumAlphaSize,
  2922. + attribs->numSamples, attribs->numMultisample,
  2923. + caveat
  2924. + );
  2925. +}
  2926. +
  2927. +
  2928. +static void
  2929. +print_visual_info(Display *dpy, int scrnum, InfoMode mode)
  2930. +{
  2931. + XVisualInfo theTemplate;
  2932. + XVisualInfo *visuals;
  2933. + int numVisuals, numGlxVisuals;
  2934. + long mask;
  2935. + int i;
  2936. + struct visual_attribs attribs;
  2937. +
  2938. + /* get list of all visuals on this screen */
  2939. + theTemplate.screen = scrnum;
  2940. + mask = VisualScreenMask;
  2941. + visuals = XGetVisualInfo(dpy, mask, &theTemplate, &numVisuals);
  2942. +
  2943. + numGlxVisuals = 0;
  2944. + for (i = 0; i < numVisuals; i++) {
  2945. + if (get_visual_attribs(dpy, &visuals[i], &attribs))
  2946. + numGlxVisuals++;
  2947. + }
  2948. +
  2949. + if (numGlxVisuals == 0)
  2950. + return;
  2951. +
  2952. + printf("%d GLX Visuals\n", numGlxVisuals);
  2953. +
  2954. + if (mode == Normal)
  2955. + print_visual_attribs_short_header();
  2956. + else if (mode == Wide)
  2957. + print_visual_attribs_long_header();
  2958. +
  2959. + for (i = 0; i < numVisuals; i++) {
  2960. + if (!get_visual_attribs(dpy, &visuals[i], &attribs))
  2961. + continue;
  2962. +
  2963. + if (mode == Verbose)
  2964. + print_visual_attribs_verbose(&attribs, False);
  2965. + else if (mode == Normal)
  2966. + print_visual_attribs_short(&attribs);
  2967. + else if (mode == Wide)
  2968. + print_visual_attribs_long(&attribs);
  2969. + }
  2970. + printf("\n");
  2971. +
  2972. + XFree(visuals);
  2973. +}
  2974. +
  2975. +#ifdef GLX_VERSION_1_3
  2976. +
  2977. +static void
  2978. +print_fbconfig_info(Display *dpy, int scrnum, InfoMode mode)
  2979. +{
  2980. + int numFBConfigs = 0;
  2981. + struct visual_attribs attribs;
  2982. + GLXFBConfig *fbconfigs;
  2983. + int i;
  2984. +
  2985. + /* get list of all fbconfigs on this screen */
  2986. + fbconfigs = glXGetFBConfigs(dpy, scrnum, &numFBConfigs);
  2987. +
  2988. + if (numFBConfigs == 0) {
  2989. + XFree(fbconfigs);
  2990. + return;
  2991. + }
  2992. +
  2993. + printf("%d GLXFBConfigs:\n", numFBConfigs);
  2994. + if (mode == Normal)
  2995. + print_visual_attribs_short_header();
  2996. + else if (mode == Wide)
  2997. + print_visual_attribs_long_header();
  2998. +
  2999. + for (i = 0; i < numFBConfigs; i++) {
  3000. + get_fbconfig_attribs(dpy, fbconfigs[i], &attribs);
  3001. +
  3002. + if (mode == Verbose)
  3003. + print_visual_attribs_verbose(&attribs, True);
  3004. + else if (mode == Normal)
  3005. + print_visual_attribs_short(&attribs);
  3006. + else if (mode == Wide)
  3007. + print_visual_attribs_long(&attribs);
  3008. + }
  3009. + printf("\n");
  3010. +
  3011. + XFree(fbconfigs);
  3012. +}
  3013. +
  3014. +#endif
  3015. +
  3016. +/*
  3017. + * Stand-alone Mesa doesn't really implement the GLX protocol so it
  3018. + * doesn't really know the GLX attributes associated with an X visual.
  3019. + * The first time a visual is presented to Mesa's pseudo-GLX it
  3020. + * attaches ancilliary buffers to it (like depth and stencil).
  3021. + * But that usually only works if glXChooseVisual is used.
  3022. + * This function calls glXChooseVisual() to sort of "prime the pump"
  3023. + * for Mesa's GLX so that the visuals that get reported actually
  3024. + * reflect what applications will see.
  3025. + * This has no effect when using true GLX.
  3026. + */
  3027. +static void
  3028. +mesa_hack(Display *dpy, int scrnum)
  3029. +{
  3030. + static int attribs[] = {
  3031. + GLX_RGBA,
  3032. + GLX_RED_SIZE, 1,
  3033. + GLX_GREEN_SIZE, 1,
  3034. + GLX_BLUE_SIZE, 1,
  3035. + GLX_DEPTH_SIZE, 1,
  3036. + GLX_STENCIL_SIZE, 1,
  3037. + GLX_ACCUM_RED_SIZE, 1,
  3038. + GLX_ACCUM_GREEN_SIZE, 1,
  3039. + GLX_ACCUM_BLUE_SIZE, 1,
  3040. + GLX_ACCUM_ALPHA_SIZE, 1,
  3041. + GLX_DOUBLEBUFFER,
  3042. + None
  3043. + };
  3044. + XVisualInfo *visinfo;
  3045. +
  3046. + visinfo = glXChooseVisual(dpy, scrnum, attribs);
  3047. + if (visinfo)
  3048. + XFree(visinfo);
  3049. +}
  3050. +
  3051. +
  3052. +/*
  3053. + * Examine all visuals to find the so-called best one.
  3054. + * We prefer deepest RGBA buffer with depth, stencil and accum
  3055. + * that has no caveats.
  3056. + */
  3057. +static int
  3058. +find_best_visual(Display *dpy, int scrnum)
  3059. +{
  3060. + XVisualInfo theTemplate;
  3061. + XVisualInfo *visuals;
  3062. + int numVisuals;
  3063. + long mask;
  3064. + int i;
  3065. + struct visual_attribs bestVis;
  3066. +
  3067. + /* get list of all visuals on this screen */
  3068. + theTemplate.screen = scrnum;
  3069. + mask = VisualScreenMask;
  3070. + visuals = XGetVisualInfo(dpy, mask, &theTemplate, &numVisuals);
  3071. +
  3072. + /* init bestVis with first visual info */
  3073. + get_visual_attribs(dpy, &visuals[0], &bestVis);
  3074. +
  3075. + /* try to find a "better" visual */
  3076. + for (i = 1; i < numVisuals; i++) {
  3077. + struct visual_attribs vis;
  3078. +
  3079. + get_visual_attribs(dpy, &visuals[i], &vis);
  3080. +
  3081. + /* always skip visuals with caveats */
  3082. + if (vis.visualCaveat != GLX_NONE_EXT)
  3083. + continue;
  3084. +
  3085. + /* see if this vis is better than bestVis */
  3086. + if ((!bestVis.supportsGL && vis.supportsGL) ||
  3087. + (bestVis.visualCaveat != GLX_NONE_EXT) ||
  3088. + (!(bestVis.render_type & GLX_RGBA_BIT) && (vis.render_type & GLX_RGBA_BIT)) ||
  3089. + (!bestVis.doubleBuffer && vis.doubleBuffer) ||
  3090. + (bestVis.redSize < vis.redSize) ||
  3091. + (bestVis.greenSize < vis.greenSize) ||
  3092. + (bestVis.blueSize < vis.blueSize) ||
  3093. + (bestVis.alphaSize < vis.alphaSize) ||
  3094. + (bestVis.depthSize < vis.depthSize) ||
  3095. + (bestVis.stencilSize < vis.stencilSize) ||
  3096. + (bestVis.accumRedSize < vis.accumRedSize)) {
  3097. + /* found a better visual */
  3098. + bestVis = vis;
  3099. + }
  3100. + }
  3101. +
  3102. + XFree(visuals);
  3103. +
  3104. + return bestVis.id;
  3105. +}
  3106. +
  3107. +
  3108. +int
  3109. +main(int argc, char *argv[])
  3110. +{
  3111. + Display *dpy;
  3112. + int numScreens, scrnum;
  3113. + struct options opts;
  3114. + Bool coreWorked;
  3115. +
  3116. + parse_args(argc, argv, &opts);
  3117. +
  3118. + dpy = XOpenDisplay(opts.displayName);
  3119. + if (!dpy) {
  3120. + fprintf(stderr, "Error: unable to open display %s\n",
  3121. + XDisplayName(opts.displayName));
  3122. + return -1;
  3123. + }
  3124. +
  3125. + if (opts.findBest) {
  3126. + int b;
  3127. + mesa_hack(dpy, 0);
  3128. + b = find_best_visual(dpy, 0);
  3129. + printf("%d\n", b);
  3130. + }
  3131. + else {
  3132. + numScreens = ScreenCount(dpy);
  3133. + print_display_info(dpy);
  3134. + for (scrnum = 0; scrnum < numScreens; scrnum++) {
  3135. + mesa_hack(dpy, scrnum);
  3136. + coreWorked = print_screen_info(dpy, scrnum, &opts,
  3137. + True, False, opts.limits, False);
  3138. + print_screen_info(dpy, scrnum, &opts, False, False,
  3139. + opts.limits, coreWorked);
  3140. + print_screen_info(dpy, scrnum, &opts, False, True, False, True);
  3141. +
  3142. + printf("\n");
  3143. +
  3144. + if (opts.mode != Brief) {
  3145. + print_visual_info(dpy, scrnum, opts.mode);
  3146. +#ifdef GLX_VERSION_1_3
  3147. + print_fbconfig_info(dpy, scrnum, opts.mode);
  3148. +#endif
  3149. + }
  3150. +
  3151. + if (scrnum + 1 < numScreens)
  3152. + printf("\n\n");
  3153. + }
  3154. + }
  3155. +
  3156. + XCloseDisplay(dpy);
  3157. +
  3158. + return 0;
  3159. +}
  3160. diff -Naurp mesa-20.2.1-orig/src/glx/xdemos/meson.build mesa-20.2.1/src/glx/xdemos/meson.build
  3161. --- mesa-20.2.1-orig/src/glx/xdemos/meson.build 1969-12-31 18:00:00.000000000 -0600
  3162. +++ mesa-20.2.1/src/glx/xdemos/meson.build 2020-10-15 23:07:14.486696790 -0500
  3163. @@ -0,0 +1,32 @@
  3164. +inc_xdemos = include_directories('.')
  3165. +
  3166. +glxinfo_files = files(
  3167. + 'glxinfo.c',
  3168. + 'glinfo_common.c',
  3169. +)
  3170. +
  3171. +x11_dep = dependency('x11', required: true)
  3172. +
  3173. +executable('glxinfo', glxinfo_files,
  3174. + install : true,
  3175. + #c_args : gl_lib_cargs,
  3176. + link_args : [ld_args_bsymbolic, ld_args_gc_sections, extra_ld_args_libgl, '-lm'],
  3177. + link_with : libgl,
  3178. + include_directories : [ inc_src, inc_include, inc_mesa, inc_glx],
  3179. + dependencies : [x11_dep]
  3180. +)
  3181. +
  3182. +executable('glxgears', 'glxgears.c',
  3183. + install : true,
  3184. + #c_args : gl_lib_cargs,
  3185. + link_args : [ld_args_bsymbolic, ld_args_gc_sections, extra_ld_args_libgl, '-lm'],
  3186. + link_with : libgl,
  3187. + include_directories : [inc_src, inc_include, inc_mesa, inc_glx],
  3188. + dependencies : [x11_dep]
  3189. +)
  3190. +
  3191. +man_dir = get_option('prefix') + '/share/man/man1'
  3192. +install_data(['glxinfo.1', 'glxgears.1'],
  3193. + install_dir : man_dir
  3194. +)
  3195. +