Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  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.  
  27. #include "nouveau_driver.h"
  28. #include "nouveau_context.h"
  29. #include "nouveau_fbo.h"
  30. #include "nouveau_texture.h"
  31. #include "nv04_driver.h"
  32. #include "nv10_driver.h"
  33. #include "nv20_driver.h"
  34.  
  35. #include "main/framebuffer.h"
  36. #include "main/fbobject.h"
  37. #include "main/renderbuffer.h"
  38. #include "swrast/s_renderbuffer.h"
  39.  
  40. static const __DRIextension *nouveau_screen_extensions[];
  41.  
  42. static void
  43. nouveau_destroy_screen(__DRIscreen *dri_screen);
  44.  
  45. static const __DRIconfig **
  46. nouveau_get_configs(void)
  47. {
  48.         __DRIconfig **configs = NULL;
  49.         int i;
  50.  
  51.         const uint8_t depth_bits[]   = { 0, 16, 24, 24 };
  52.         const uint8_t stencil_bits[] = { 0,  0,  0,  8 };
  53.         const uint8_t msaa_samples[] = { 0 };
  54.  
  55.         static const gl_format formats[3] = {
  56.                 MESA_FORMAT_RGB565,
  57.                 MESA_FORMAT_ARGB8888,
  58.                 MESA_FORMAT_XRGB8888,
  59.         };
  60.  
  61.         const GLenum back_buffer_modes[] = {
  62.                 GLX_NONE, GLX_SWAP_UNDEFINED_OML
  63.         };
  64.  
  65.         for (i = 0; i < Elements(formats); i++) {
  66.                 __DRIconfig **config;
  67.  
  68.                 config = driCreateConfigs(formats[i],
  69.                                           depth_bits, stencil_bits,
  70.                                           Elements(depth_bits),
  71.                                           back_buffer_modes,
  72.                                           Elements(back_buffer_modes),
  73.                                           msaa_samples,
  74.                                           Elements(msaa_samples),
  75.                                           GL_TRUE);
  76.                 assert(config);
  77.  
  78.                 configs = driConcatConfigs(configs, config);
  79.         }
  80.  
  81.         return (const __DRIconfig **)configs;
  82. }
  83.  
  84. static const __DRIconfig **
  85. nouveau_init_screen2(__DRIscreen *dri_screen)
  86. {
  87.         const __DRIconfig **configs;
  88.         struct nouveau_screen *screen;
  89.         int ret;
  90.  
  91.         /* Allocate the screen. */
  92.         screen = CALLOC_STRUCT(nouveau_screen);
  93.         if (!screen)
  94.                 return NULL;
  95.  
  96.         dri_screen->driverPrivate = screen;
  97.         dri_screen->extensions = nouveau_screen_extensions;
  98.         screen->dri_screen = dri_screen;
  99.  
  100.         /* Open the DRM device. */
  101.         ret = nouveau_device_wrap(dri_screen->fd, 0, &screen->device);
  102.         if (ret) {
  103.                 nouveau_error("Error opening the DRM device.\n");
  104.                 goto fail;
  105.         }
  106.  
  107.         /* Choose the card specific function pointers. */
  108.         switch (screen->device->chipset & 0xf0) {
  109.         case 0x00:
  110.                 screen->driver = &nv04_driver;
  111.                 break;
  112.         case 0x10:
  113.                 screen->driver = &nv10_driver;
  114.                 break;
  115.         case 0x20:
  116.                 screen->driver = &nv20_driver;
  117.                 break;
  118.         default:
  119.                 assert(0);
  120.         }
  121.  
  122.         configs = nouveau_get_configs();
  123.         if (!configs)
  124.                 goto fail;
  125.  
  126.         return configs;
  127. fail:
  128.         nouveau_destroy_screen(dri_screen);
  129.         return NULL;
  130.  
  131. }
  132.  
  133. static void
  134. nouveau_destroy_screen(__DRIscreen *dri_screen)
  135. {
  136.         struct nouveau_screen *screen = dri_screen->driverPrivate;
  137.  
  138.         if (!screen)
  139.                 return;
  140.  
  141.         nouveau_device_del(&screen->device);
  142.  
  143.         free(screen);
  144.         dri_screen->driverPrivate = NULL;
  145. }
  146.  
  147. static GLboolean
  148. nouveau_create_buffer(__DRIscreen *dri_screen,
  149.                       __DRIdrawable *drawable,
  150.                       const struct gl_config *visual,
  151.                       GLboolean is_pixmap)
  152. {
  153.         struct gl_renderbuffer *rb;
  154.         struct gl_framebuffer *fb;
  155.         GLenum color_format;
  156.  
  157.         if (is_pixmap)
  158.                 return GL_FALSE; /* not implemented */
  159.  
  160.         if (visual->redBits == 5)
  161.                 color_format = GL_RGB5;
  162.         else if (visual->alphaBits == 0)
  163.                 color_format = GL_RGB8;
  164.         else
  165.                 color_format = GL_RGBA8;
  166.  
  167.         fb = nouveau_framebuffer_dri_new(visual);
  168.         if (!fb)
  169.                 return GL_FALSE;
  170.  
  171.         /* Front buffer. */
  172.         rb = nouveau_renderbuffer_dri_new(color_format, drawable);
  173.         _mesa_add_renderbuffer(fb, BUFFER_FRONT_LEFT, rb);
  174.  
  175.         /* Back buffer */
  176.         if (visual->doubleBufferMode) {
  177.                 rb = nouveau_renderbuffer_dri_new(color_format, drawable);
  178.                 _mesa_add_renderbuffer(fb, BUFFER_BACK_LEFT, rb);
  179.         }
  180.  
  181.         /* Depth/stencil buffer. */
  182.         if (visual->depthBits == 24 && visual->stencilBits == 8) {
  183.                 rb = nouveau_renderbuffer_dri_new(GL_DEPTH24_STENCIL8_EXT, drawable);
  184.                 _mesa_add_renderbuffer(fb, BUFFER_DEPTH, rb);
  185.                 _mesa_add_renderbuffer(fb, BUFFER_STENCIL, rb);
  186.  
  187.         } else if (visual->depthBits == 24) {
  188.                 rb = nouveau_renderbuffer_dri_new(GL_DEPTH_COMPONENT24, drawable);
  189.                 _mesa_add_renderbuffer(fb, BUFFER_DEPTH, rb);
  190.  
  191.         } else if (visual->depthBits == 16) {
  192.                 rb = nouveau_renderbuffer_dri_new(GL_DEPTH_COMPONENT16, drawable);
  193.                 _mesa_add_renderbuffer(fb, BUFFER_DEPTH, rb);
  194.         }
  195.  
  196.         /* Software renderbuffers. */
  197.         _swrast_add_soft_renderbuffers(fb, GL_FALSE, GL_FALSE, GL_FALSE,
  198.                                        visual->accumRedBits > 0,
  199.                                        GL_FALSE, GL_FALSE);
  200.  
  201.         drawable->driverPrivate = fb;
  202.  
  203.         return GL_TRUE;
  204. }
  205.  
  206. static void
  207. nouveau_destroy_buffer(__DRIdrawable *drawable)
  208. {
  209.         _mesa_reference_framebuffer(
  210.                 (struct gl_framebuffer **)&drawable->driverPrivate, NULL);
  211. }
  212.  
  213. static void
  214. nouveau_drawable_flush(__DRIdrawable *draw)
  215. {
  216. }
  217.  
  218. static const struct __DRI2flushExtensionRec nouveau_flush_extension = {
  219.     { __DRI2_FLUSH, 3 },
  220.     nouveau_drawable_flush,
  221.     dri2InvalidateDrawable,
  222. };
  223.  
  224. static const struct __DRItexBufferExtensionRec nouveau_texbuffer_extension = {
  225.     { __DRI_TEX_BUFFER, __DRI_TEX_BUFFER_VERSION },
  226.     NULL,
  227.     nouveau_set_texbuffer,
  228. };
  229.  
  230. static const __DRIextension *nouveau_screen_extensions[] = {
  231.     &nouveau_flush_extension.base,
  232.     &nouveau_texbuffer_extension.base,
  233.     &dri2ConfigQueryExtension.base,
  234.     NULL
  235. };
  236.  
  237. const struct __DriverAPIRec driDriverAPI = {
  238.         .InitScreen      = nouveau_init_screen2,
  239.         .DestroyScreen   = nouveau_destroy_screen,
  240.         .CreateBuffer    = nouveau_create_buffer,
  241.         .DestroyBuffer   = nouveau_destroy_buffer,
  242.         .CreateContext   = nouveau_context_create,
  243.         .DestroyContext  = nouveau_context_destroy,
  244.         .MakeCurrent     = nouveau_context_make_current,
  245.         .UnbindContext   = nouveau_context_unbind,
  246. };
  247.  
  248. /* This is the table of extensions that the loader will dlsym() for. */
  249. PUBLIC const __DRIextension *__driDriverExtensions[] = {
  250.         &driCoreExtension.base,
  251.         &driDRI2Extension.base,
  252.         NULL
  253. };
  254.