glxdricommon.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324
  1. /*
  2. * Copyright © 2008 Red Hat, Inc
  3. *
  4. * Permission to use, copy, modify, distribute, and sell this software
  5. * and its documentation for any purpose is hereby granted without
  6. * fee, provided that the above copyright notice appear in all copies
  7. * and that both that copyright notice and this permission notice
  8. * appear in supporting documentation, and that the name of the
  9. * copyright holders not be used in advertising or publicity
  10. * pertaining to distribution of the software without specific,
  11. * written prior permission. The copyright holders make no
  12. * representations about the suitability of this software for any
  13. * purpose. It is provided "as is" without express or implied
  14. * warranty.
  15. *
  16. * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
  17. * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
  18. * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
  19. * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  20. * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
  21. * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
  22. * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  23. * SOFTWARE.
  24. */
  25. #ifdef HAVE_DIX_CONFIG_H
  26. #include <dix-config.h>
  27. #endif
  28. #include <stdint.h>
  29. #include <errno.h>
  30. #include <dlfcn.h>
  31. #include <sys/time.h>
  32. #include <GL/gl.h>
  33. #include <GL/glxtokens.h>
  34. #include <GL/internal/dri_interface.h>
  35. #include <os.h>
  36. #include "glxserver.h"
  37. #include "glxext.h"
  38. #include "glxcontext.h"
  39. #include "glxscreens.h"
  40. #include "glxdricommon.h"
  41. static int
  42. getUST(int64_t * ust)
  43. {
  44. struct timeval tv;
  45. if (ust == NULL)
  46. return -EFAULT;
  47. if (gettimeofday(&tv, NULL) == 0) {
  48. ust[0] = (tv.tv_sec * 1000000) + tv.tv_usec;
  49. return 0;
  50. }
  51. else {
  52. return -errno;
  53. }
  54. }
  55. const __DRIsystemTimeExtension systemTimeExtension = {
  56. {__DRI_SYSTEM_TIME, 1},
  57. getUST,
  58. NULL,
  59. };
  60. #define __ATTRIB(attrib, field) \
  61. { attrib, offsetof(__GLXconfig, field) }
  62. static const struct {
  63. unsigned int attrib, offset;
  64. } attribMap[] = {
  65. __ATTRIB(__DRI_ATTRIB_BUFFER_SIZE, rgbBits),
  66. __ATTRIB(__DRI_ATTRIB_LEVEL, level),
  67. __ATTRIB(__DRI_ATTRIB_RED_SIZE, redBits),
  68. __ATTRIB(__DRI_ATTRIB_GREEN_SIZE, greenBits),
  69. __ATTRIB(__DRI_ATTRIB_BLUE_SIZE, blueBits),
  70. __ATTRIB(__DRI_ATTRIB_ALPHA_SIZE, alphaBits),
  71. __ATTRIB(__DRI_ATTRIB_DEPTH_SIZE, depthBits),
  72. __ATTRIB(__DRI_ATTRIB_STENCIL_SIZE, stencilBits),
  73. __ATTRIB(__DRI_ATTRIB_ACCUM_RED_SIZE, accumRedBits),
  74. __ATTRIB(__DRI_ATTRIB_ACCUM_GREEN_SIZE, accumGreenBits),
  75. __ATTRIB(__DRI_ATTRIB_ACCUM_BLUE_SIZE, accumBlueBits),
  76. __ATTRIB(__DRI_ATTRIB_ACCUM_ALPHA_SIZE, accumAlphaBits),
  77. __ATTRIB(__DRI_ATTRIB_SAMPLE_BUFFERS, sampleBuffers),
  78. __ATTRIB(__DRI_ATTRIB_SAMPLES, samples),
  79. __ATTRIB(__DRI_ATTRIB_DOUBLE_BUFFER, doubleBufferMode),
  80. __ATTRIB(__DRI_ATTRIB_STEREO, stereoMode),
  81. __ATTRIB(__DRI_ATTRIB_AUX_BUFFERS, numAuxBuffers),
  82. __ATTRIB(__DRI_ATTRIB_TRANSPARENT_TYPE, transparentPixel),
  83. __ATTRIB(__DRI_ATTRIB_TRANSPARENT_INDEX_VALUE, transparentPixel),
  84. __ATTRIB(__DRI_ATTRIB_TRANSPARENT_RED_VALUE, transparentRed),
  85. __ATTRIB(__DRI_ATTRIB_TRANSPARENT_GREEN_VALUE, transparentGreen),
  86. __ATTRIB(__DRI_ATTRIB_TRANSPARENT_BLUE_VALUE, transparentBlue),
  87. __ATTRIB(__DRI_ATTRIB_TRANSPARENT_ALPHA_VALUE, transparentAlpha),
  88. __ATTRIB(__DRI_ATTRIB_RED_MASK, redMask),
  89. __ATTRIB(__DRI_ATTRIB_GREEN_MASK, greenMask),
  90. __ATTRIB(__DRI_ATTRIB_BLUE_MASK, blueMask),
  91. __ATTRIB(__DRI_ATTRIB_ALPHA_MASK, alphaMask),
  92. __ATTRIB(__DRI_ATTRIB_MAX_PBUFFER_WIDTH, maxPbufferWidth),
  93. __ATTRIB(__DRI_ATTRIB_MAX_PBUFFER_HEIGHT, maxPbufferHeight),
  94. __ATTRIB(__DRI_ATTRIB_MAX_PBUFFER_PIXELS, maxPbufferPixels),
  95. __ATTRIB(__DRI_ATTRIB_OPTIMAL_PBUFFER_WIDTH, optimalPbufferWidth),
  96. __ATTRIB(__DRI_ATTRIB_OPTIMAL_PBUFFER_HEIGHT, optimalPbufferHeight),
  97. __ATTRIB(__DRI_ATTRIB_SWAP_METHOD, swapMethod),
  98. __ATTRIB(__DRI_ATTRIB_BIND_TO_TEXTURE_RGB, bindToTextureRgb),
  99. __ATTRIB(__DRI_ATTRIB_BIND_TO_TEXTURE_RGBA, bindToTextureRgba),
  100. __ATTRIB(__DRI_ATTRIB_BIND_TO_MIPMAP_TEXTURE, bindToMipmapTexture),
  101. __ATTRIB(__DRI_ATTRIB_YINVERTED, yInverted),
  102. __ATTRIB(__DRI_ATTRIB_FRAMEBUFFER_SRGB_CAPABLE, sRGBCapable),
  103. };
  104. static void
  105. setScalar(__GLXconfig * config, unsigned int attrib, unsigned int value)
  106. {
  107. int i;
  108. for (i = 0; i < ARRAY_SIZE(attribMap); i++)
  109. if (attribMap[i].attrib == attrib) {
  110. *(unsigned int *) ((char *) config + attribMap[i].offset) = value;
  111. return;
  112. }
  113. }
  114. static __GLXconfig *
  115. createModeFromConfig(const __DRIcoreExtension * core,
  116. const __DRIconfig * driConfig,
  117. unsigned int visualType, unsigned int drawableType)
  118. {
  119. __GLXDRIconfig *config;
  120. GLint renderType = 0;
  121. unsigned int attrib, value;
  122. int i;
  123. config = calloc(1, sizeof *config);
  124. config->driConfig = driConfig;
  125. i = 0;
  126. while (core->indexConfigAttrib(driConfig, i++, &attrib, &value)) {
  127. switch (attrib) {
  128. case __DRI_ATTRIB_RENDER_TYPE:
  129. if (value & __DRI_ATTRIB_RGBA_BIT)
  130. renderType |= GLX_RGBA_BIT;
  131. if (value & __DRI_ATTRIB_COLOR_INDEX_BIT)
  132. renderType |= GLX_COLOR_INDEX_BIT;
  133. if (value & __DRI_ATTRIB_FLOAT_BIT)
  134. renderType |= GLX_RGBA_FLOAT_BIT_ARB;
  135. if (value & __DRI_ATTRIB_UNSIGNED_FLOAT_BIT)
  136. renderType |= GLX_RGBA_UNSIGNED_FLOAT_BIT_EXT;
  137. break;
  138. case __DRI_ATTRIB_CONFIG_CAVEAT:
  139. if (value & __DRI_ATTRIB_NON_CONFORMANT_CONFIG)
  140. config->config.visualRating = GLX_NON_CONFORMANT_CONFIG;
  141. else if (value & __DRI_ATTRIB_SLOW_BIT)
  142. config->config.visualRating = GLX_SLOW_CONFIG;
  143. else
  144. config->config.visualRating = GLX_NONE;
  145. break;
  146. case __DRI_ATTRIB_BIND_TO_TEXTURE_TARGETS:
  147. config->config.bindToTextureTargets = 0;
  148. if (value & __DRI_ATTRIB_TEXTURE_1D_BIT)
  149. config->config.bindToTextureTargets |= GLX_TEXTURE_1D_BIT_EXT;
  150. if (value & __DRI_ATTRIB_TEXTURE_2D_BIT)
  151. config->config.bindToTextureTargets |= GLX_TEXTURE_2D_BIT_EXT;
  152. if (value & __DRI_ATTRIB_TEXTURE_RECTANGLE_BIT)
  153. config->config.bindToTextureTargets |=
  154. GLX_TEXTURE_RECTANGLE_BIT_EXT;
  155. break;
  156. default:
  157. setScalar(&config->config, attrib, value);
  158. break;
  159. }
  160. }
  161. config->config.next = NULL;
  162. config->config.xRenderable = GL_TRUE;
  163. config->config.visualType = visualType;
  164. config->config.renderType = renderType;
  165. config->config.drawableType = drawableType;
  166. config->config.yInverted = GL_TRUE;
  167. return &config->config;
  168. }
  169. static Bool
  170. render_type_is_pbuffer_only(unsigned renderType)
  171. {
  172. /* The GL_ARB_color_buffer_float spec says:
  173. *
  174. * "Note that floating point rendering is only supported for
  175. * GLXPbuffer drawables. The GLX_DRAWABLE_TYPE attribute of the
  176. * GLXFBConfig must have the GLX_PBUFFER_BIT bit set and the
  177. * GLX_RENDER_TYPE attribute must have the GLX_RGBA_FLOAT_BIT set."
  178. */
  179. return !!(renderType & (__DRI_ATTRIB_UNSIGNED_FLOAT_BIT
  180. | __DRI_ATTRIB_FLOAT_BIT));
  181. }
  182. __GLXconfig *
  183. glxConvertConfigs(const __DRIcoreExtension * core,
  184. const __DRIconfig ** configs, unsigned int drawableType)
  185. {
  186. __GLXconfig head, *tail;
  187. int i;
  188. tail = &head;
  189. head.next = NULL;
  190. for (i = 0; configs[i]; i++) {
  191. unsigned renderType = 0;
  192. if (core->getConfigAttrib(configs[i], __DRI_ATTRIB_RENDER_TYPE,
  193. &renderType)) {
  194. if (render_type_is_pbuffer_only(renderType) &&
  195. !(drawableType & GLX_PBUFFER_BIT))
  196. continue;
  197. }
  198. /* Add all the others */
  199. tail->next = createModeFromConfig(core,
  200. configs[i], GLX_TRUE_COLOR,
  201. drawableType);
  202. if (tail->next == NULL)
  203. break;
  204. tail = tail->next;
  205. }
  206. for (i = 0; configs[i]; i++) {
  207. unsigned int renderType = 0;
  208. if (core->getConfigAttrib(configs[i], __DRI_ATTRIB_RENDER_TYPE,
  209. &renderType)) {
  210. if (render_type_is_pbuffer_only(renderType) &&
  211. !(drawableType & GLX_PBUFFER_BIT))
  212. continue;
  213. }
  214. /* Add all the others */
  215. tail->next = createModeFromConfig(core,
  216. configs[i], GLX_DIRECT_COLOR,
  217. drawableType);
  218. if (tail->next == NULL)
  219. break;
  220. tail = tail->next;
  221. }
  222. return head.next;
  223. }
  224. static const char dri_driver_path[] = DRI_DRIVER_PATH;
  225. /* Temporary define to allow building without a dri_interface.h from
  226. * updated Mesa. Some day when we don't care about Mesa that old any
  227. * more this can be removed.
  228. */
  229. #ifndef __DRI_DRIVER_GET_EXTENSIONS
  230. #define __DRI_DRIVER_GET_EXTENSIONS "__driDriverGetExtensions"
  231. #endif
  232. void *
  233. glxProbeDriver(const char *driverName,
  234. void **coreExt, const char *coreName, int coreVersion,
  235. void **renderExt, const char *renderName, int renderVersion)
  236. {
  237. int i;
  238. void *driver;
  239. char filename[PATH_MAX];
  240. char *get_extensions_name;
  241. const __DRIextension **extensions = NULL;
  242. snprintf(filename, sizeof filename, "%s/%s_dri.so",
  243. dri_driver_path, driverName);
  244. driver = dlopen(filename, RTLD_LAZY | RTLD_LOCAL);
  245. if (driver == NULL) {
  246. LogMessage(X_ERROR, "AIGLX error: dlopen of %s failed (%s)\n",
  247. filename, dlerror());
  248. goto cleanup_failure;
  249. }
  250. if (asprintf(&get_extensions_name, "%s_%s",
  251. __DRI_DRIVER_GET_EXTENSIONS, driverName) != -1) {
  252. const __DRIextension **(*get_extensions)(void);
  253. get_extensions = dlsym(driver, get_extensions_name);
  254. if (get_extensions)
  255. extensions = get_extensions();
  256. free(get_extensions_name);
  257. }
  258. if (!extensions)
  259. extensions = dlsym(driver, __DRI_DRIVER_EXTENSIONS);
  260. if (extensions == NULL) {
  261. LogMessage(X_ERROR, "AIGLX error: %s exports no extensions (%s)\n",
  262. driverName, dlerror());
  263. goto cleanup_failure;
  264. }
  265. for (i = 0; extensions[i]; i++) {
  266. if (strcmp(extensions[i]->name, coreName) == 0 &&
  267. extensions[i]->version >= coreVersion) {
  268. *coreExt = (void *) extensions[i];
  269. }
  270. if (strcmp(extensions[i]->name, renderName) == 0 &&
  271. extensions[i]->version >= renderVersion) {
  272. *renderExt = (void *) extensions[i];
  273. }
  274. }
  275. if (*coreExt == NULL || *renderExt == NULL) {
  276. LogMessage(X_ERROR,
  277. "AIGLX error: %s does not export required DRI extension\n",
  278. driverName);
  279. goto cleanup_failure;
  280. }
  281. return driver;
  282. cleanup_failure:
  283. if (driver)
  284. dlclose(driver);
  285. *coreExt = *renderExt = NULL;
  286. return NULL;
  287. }