Clone of mesa.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

nouveau_screen.c 6.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259
  1. /*
  2. * Copyright (C) 2009 Francisco Jerez.
  3. * All Rights Reserved.
  4. *
  5. * Permission is hereby granted, free of charge, to any person obtaining
  6. * a copy of this software and associated documentation files (the
  7. * "Software"), to deal in the Software without restriction, including
  8. * without limitation the rights to use, copy, modify, merge, publish,
  9. * distribute, sublicense, and/or sell copies of the Software, and to
  10. * permit persons to whom the Software is furnished to do so, subject to
  11. * the following conditions:
  12. *
  13. * The above copyright notice and this permission notice (including the
  14. * next paragraph) shall be included in all copies or substantial
  15. * portions of the Software.
  16. *
  17. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  18. * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  19. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  20. * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
  21. * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  22. * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  23. * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  24. *
  25. */
  26. #include "nouveau_driver.h"
  27. #include "nouveau_context.h"
  28. #include "nouveau_fbo.h"
  29. #include "nouveau_texture.h"
  30. #include "nouveau_drmif.h"
  31. #include "nv04_driver.h"
  32. #include "nv10_driver.h"
  33. #include "nv20_driver.h"
  34. #include "main/framebuffer.h"
  35. #include "main/renderbuffer.h"
  36. static const __DRIextension *nouveau_screen_extensions[];
  37. static void
  38. nouveau_destroy_screen(__DRIscreen *dri_screen);
  39. static const __DRIconfig **
  40. nouveau_get_configs(void)
  41. {
  42. __DRIconfig **configs = NULL;
  43. int i;
  44. const uint8_t depth_bits[] = { 0, 16, 24, 24 };
  45. const uint8_t stencil_bits[] = { 0, 0, 0, 8 };
  46. const uint8_t msaa_samples[] = { 0 };
  47. const struct {
  48. GLenum format;
  49. GLenum type;
  50. } fb_formats[] = {
  51. { GL_RGB , GL_UNSIGNED_SHORT_5_6_5 },
  52. { GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV },
  53. { GL_BGR , GL_UNSIGNED_INT_8_8_8_8_REV },
  54. };
  55. const GLenum back_buffer_modes[] = {
  56. GLX_NONE, GLX_SWAP_UNDEFINED_OML
  57. };
  58. for (i = 0; i < Elements(fb_formats); i++) {
  59. __DRIconfig **config;
  60. config = driCreateConfigs(fb_formats[i].format,
  61. fb_formats[i].type,
  62. depth_bits, stencil_bits,
  63. Elements(depth_bits),
  64. back_buffer_modes,
  65. Elements(back_buffer_modes),
  66. msaa_samples,
  67. Elements(msaa_samples),
  68. GL_TRUE);
  69. assert(config);
  70. configs = configs ? driConcatConfigs(configs, config)
  71. : config;
  72. }
  73. return (const __DRIconfig **)configs;
  74. }
  75. static const __DRIconfig **
  76. nouveau_init_screen2(__DRIscreen *dri_screen)
  77. {
  78. const __DRIconfig **configs;
  79. struct nouveau_screen *screen;
  80. int ret;
  81. /* Allocate the screen. */
  82. screen = CALLOC_STRUCT(nouveau_screen);
  83. if (!screen)
  84. return NULL;
  85. dri_screen->private = screen;
  86. dri_screen->extensions = nouveau_screen_extensions;
  87. screen->dri_screen = dri_screen;
  88. /* Open the DRM device. */
  89. ret = nouveau_device_open_existing(&screen->device, 0, dri_screen->fd,
  90. 0);
  91. if (ret) {
  92. nouveau_error("Error opening the DRM device.\n");
  93. goto fail;
  94. }
  95. /* Choose the card specific function pointers. */
  96. switch (screen->device->chipset & 0xf0) {
  97. case 0x00:
  98. screen->driver = &nv04_driver;
  99. break;
  100. case 0x10:
  101. screen->driver = &nv10_driver;
  102. break;
  103. case 0x20:
  104. screen->driver = &nv20_driver;
  105. break;
  106. default:
  107. assert(0);
  108. }
  109. configs = nouveau_get_configs();
  110. if (!configs)
  111. goto fail;
  112. return configs;
  113. fail:
  114. nouveau_destroy_screen(dri_screen);
  115. return NULL;
  116. }
  117. static void
  118. nouveau_destroy_screen(__DRIscreen *dri_screen)
  119. {
  120. struct nouveau_screen *screen = dri_screen->private;
  121. if (!screen)
  122. return;
  123. if (screen->device)
  124. nouveau_device_close(&screen->device);
  125. FREE(screen);
  126. dri_screen->private = NULL;
  127. }
  128. static GLboolean
  129. nouveau_create_buffer(__DRIscreen *dri_screen,
  130. __DRIdrawable *drawable,
  131. const __GLcontextModes *visual,
  132. GLboolean is_pixmap)
  133. {
  134. struct gl_renderbuffer *rb;
  135. struct gl_framebuffer *fb;
  136. GLenum color_format;
  137. if (is_pixmap)
  138. return GL_FALSE; /* not implemented */
  139. if (visual->redBits == 5)
  140. color_format = GL_RGB5;
  141. else if (visual->alphaBits == 0)
  142. color_format = GL_RGB8;
  143. else
  144. color_format = GL_RGBA8;
  145. fb = nouveau_framebuffer_dri_new(visual);
  146. if (!fb)
  147. return GL_FALSE;
  148. /* Front buffer. */
  149. rb = nouveau_renderbuffer_dri_new(color_format, drawable);
  150. _mesa_add_renderbuffer(fb, BUFFER_FRONT_LEFT, rb);
  151. /* Back buffer */
  152. if (visual->doubleBufferMode) {
  153. rb = nouveau_renderbuffer_dri_new(color_format, drawable);
  154. _mesa_add_renderbuffer(fb, BUFFER_BACK_LEFT, rb);
  155. }
  156. /* Depth/stencil buffer. */
  157. if (visual->depthBits == 24 && visual->stencilBits == 8) {
  158. rb = nouveau_renderbuffer_dri_new(GL_DEPTH24_STENCIL8_EXT, drawable);
  159. _mesa_add_renderbuffer(fb, BUFFER_DEPTH, rb);
  160. _mesa_add_renderbuffer(fb, BUFFER_STENCIL, rb);
  161. } else if (visual->depthBits == 24) {
  162. rb = nouveau_renderbuffer_dri_new(GL_DEPTH_COMPONENT24, drawable);
  163. _mesa_add_renderbuffer(fb, BUFFER_DEPTH, rb);
  164. } else if (visual->depthBits == 16) {
  165. rb = nouveau_renderbuffer_dri_new(GL_DEPTH_COMPONENT16, drawable);
  166. _mesa_add_renderbuffer(fb, BUFFER_DEPTH, rb);
  167. }
  168. /* Software renderbuffers. */
  169. _mesa_add_soft_renderbuffers(fb, GL_FALSE, GL_FALSE, GL_FALSE,
  170. visual->accumRedBits > 0,
  171. GL_FALSE, GL_FALSE);
  172. drawable->driverPrivate = fb;
  173. return GL_TRUE;
  174. }
  175. static void
  176. nouveau_destroy_buffer(__DRIdrawable *drawable)
  177. {
  178. _mesa_reference_framebuffer(
  179. (struct gl_framebuffer **)&drawable->driverPrivate, NULL);
  180. }
  181. static void
  182. nouveau_drawable_flush(__DRIdrawable *draw)
  183. {
  184. }
  185. static const struct __DRI2flushExtensionRec nouveau_flush_extension = {
  186. { __DRI2_FLUSH, __DRI2_FLUSH_VERSION },
  187. nouveau_drawable_flush,
  188. dri2InvalidateDrawable,
  189. };
  190. static const struct __DRItexBufferExtensionRec nouveau_texbuffer_extension = {
  191. { __DRI_TEX_BUFFER, __DRI_TEX_BUFFER_VERSION },
  192. NULL,
  193. nouveau_set_texbuffer,
  194. };
  195. static const __DRIextension *nouveau_screen_extensions[] = {
  196. &nouveau_flush_extension.base,
  197. &nouveau_texbuffer_extension.base,
  198. &dri2ConfigQueryExtension.base,
  199. NULL
  200. };
  201. const struct __DriverAPIRec driDriverAPI = {
  202. .InitScreen2 = nouveau_init_screen2,
  203. .DestroyScreen = nouveau_destroy_screen,
  204. .CreateBuffer = nouveau_create_buffer,
  205. .DestroyBuffer = nouveau_destroy_buffer,
  206. .CreateContext = nouveau_context_create,
  207. .DestroyContext = nouveau_context_destroy,
  208. .MakeCurrent = nouveau_context_make_current,
  209. .UnbindContext = nouveau_context_unbind,
  210. };
  211. /* This is the table of extensions that the loader will dlsym() for. */
  212. PUBLIC const __DRIextension *__driDriverExtensions[] = {
  213. &driCoreExtension.base,
  214. &driDRI2Extension.base,
  215. NULL
  216. };