Subversion Repositories Kolibri OS

Rev

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

  1. /*
  2.  * Copyright 2008, 2010 George Sapountzis <gsapountzis@gmail.com>
  3.  *
  4.  * Permission is hereby granted, free of charge, to any person obtaining a
  5.  * copy of this software and associated documentation files (the "Software"),
  6.  * to deal in the Software without restriction, including without limitation
  7.  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  8.  * and/or sell copies of the Software, and to permit persons to whom the
  9.  * Software is furnished to do so, subject to the following conditions:
  10.  *
  11.  * The above copyright notice and this permission notice shall be included
  12.  * in all copies or substantial portions of the Software.
  13.  *
  14.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  15.  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  17.  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
  18.  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  19.  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  20.  * OTHER DEALINGS IN THE SOFTWARE.
  21.  */
  22.  
  23. /*
  24.  * DRI software rasterizer
  25.  *
  26.  * This is the mesa swrast module packaged into a DRI driver structure.
  27.  *
  28.  * The front-buffer is allocated by the loader. The loader provides read/write
  29.  * callbacks for access to the front-buffer. The driver uses a scratch row for
  30.  * front-buffer rendering to avoid repeated calls to the loader.
  31.  *
  32.  * The back-buffer is allocated by the driver and is private.
  33.  */
  34.  
  35. #include "main/api_exec.h"
  36. #include "main/context.h"
  37. #include "main/extensions.h"
  38. #include "main/formats.h"
  39. #include "main/framebuffer.h"
  40. #include "main/imports.h"
  41. #include "main/renderbuffer.h"
  42. #include "main/version.h"
  43. #include "main/vtxfmt.h"
  44. #include "swrast/swrast.h"
  45. #include "swrast/s_renderbuffer.h"
  46. #include "swrast_setup/swrast_setup.h"
  47. #include "tnl/tnl.h"
  48. #include "tnl/t_context.h"
  49. #include "tnl/t_pipeline.h"
  50. #include "vbo/vbo.h"
  51. #include "drivers/common/driverfuncs.h"
  52. #include "drivers/common/meta.h"
  53. #include "utils.h"
  54.  
  55. #include "main/teximage.h"
  56. #include "main/texformat.h"
  57. #include "main/texstate.h"
  58.  
  59. #include "swrast_priv.h"
  60. #include "swrast/s_context.h"
  61.  
  62.  
  63. /**
  64.  * Screen and config-related functions
  65.  */
  66.  
  67. static void swrastSetTexBuffer2(__DRIcontext *pDRICtx, GLint target,
  68.                                 GLint texture_format, __DRIdrawable *dPriv)
  69. {
  70.     struct dri_context *dri_ctx;
  71.     int x, y, w, h;
  72.     __DRIscreen *sPriv = dPriv->driScreenPriv;
  73.     struct gl_texture_unit *texUnit;
  74.     struct gl_texture_object *texObj;
  75.     struct gl_texture_image *texImage;
  76.     struct swrast_texture_image *swImage;
  77.     uint32_t internalFormat;
  78.     gl_format texFormat;
  79.  
  80.     dri_ctx = pDRICtx->driverPrivate;
  81.  
  82.     internalFormat = (texture_format == __DRI_TEXTURE_FORMAT_RGB ? 3 : 4);
  83.  
  84.     texUnit = _mesa_get_current_tex_unit(&dri_ctx->Base);
  85.     texObj = _mesa_select_tex_object(&dri_ctx->Base, texUnit, target);
  86.     texImage = _mesa_get_tex_image(&dri_ctx->Base, texObj, target, 0);
  87.     swImage = swrast_texture_image(texImage);
  88.  
  89.     _mesa_lock_texture(&dri_ctx->Base, texObj);
  90.  
  91.     sPriv->swrast_loader->getDrawableInfo(dPriv, &x, &y, &w, &h, dPriv->loaderPrivate);
  92.  
  93.     if (texture_format == __DRI_TEXTURE_FORMAT_RGB)
  94.         texFormat = MESA_FORMAT_XRGB8888;
  95.     else
  96.         texFormat = MESA_FORMAT_ARGB8888;
  97.  
  98.     _mesa_init_teximage_fields(&dri_ctx->Base, texImage,
  99.                                w, h, 1, 0, internalFormat, texFormat);
  100.  
  101.     sPriv->swrast_loader->getImage(dPriv, x, y, w, h, (char *)swImage->Buffer,
  102.                                    dPriv->loaderPrivate);
  103.  
  104.     _mesa_unlock_texture(&dri_ctx->Base, texObj);
  105. }
  106.  
  107. static void swrastSetTexBuffer(__DRIcontext *pDRICtx, GLint target,
  108.                                __DRIdrawable *dPriv)
  109. {
  110.     swrastSetTexBuffer2(pDRICtx, target, __DRI_TEXTURE_FORMAT_RGBA, dPriv);
  111. }
  112.  
  113. static const __DRItexBufferExtension swrastTexBufferExtension = {
  114.     { __DRI_TEX_BUFFER, __DRI_TEX_BUFFER_VERSION },
  115.     swrastSetTexBuffer,
  116.     swrastSetTexBuffer2,
  117. };
  118.  
  119. static const __DRIextension *dri_screen_extensions[] = {
  120.     &swrastTexBufferExtension.base,
  121.     NULL
  122. };
  123.  
  124. static __DRIconfig **
  125. swrastFillInModes(__DRIscreen *psp,
  126.                   unsigned pixel_bits, unsigned depth_bits,
  127.                   unsigned stencil_bits, GLboolean have_back_buffer)
  128. {
  129.     __DRIconfig **configs;
  130.     unsigned depth_buffer_factor;
  131.     unsigned back_buffer_factor;
  132.     gl_format format;
  133.  
  134.     /* GLX_SWAP_COPY_OML is only supported because the Intel driver doesn't
  135.      * support pageflipping at all.
  136.      */
  137.     static const GLenum back_buffer_modes[] = {
  138.         GLX_NONE, GLX_SWAP_UNDEFINED_OML
  139.     };
  140.  
  141.     uint8_t depth_bits_array[4];
  142.     uint8_t stencil_bits_array[4];
  143.     uint8_t msaa_samples_array[1];
  144.  
  145.     (void) psp;
  146.     (void) have_back_buffer;
  147.  
  148.     depth_bits_array[0] = 0;
  149.     depth_bits_array[1] = 0;
  150.     depth_bits_array[2] = depth_bits;
  151.     depth_bits_array[3] = depth_bits;
  152.  
  153.     /* Just like with the accumulation buffer, always provide some modes
  154.      * with a stencil buffer.
  155.      */
  156.     stencil_bits_array[0] = 0;
  157.     stencil_bits_array[1] = (stencil_bits == 0) ? 8 : stencil_bits;
  158.     stencil_bits_array[2] = 0;
  159.     stencil_bits_array[3] = (stencil_bits == 0) ? 8 : stencil_bits;
  160.  
  161.     msaa_samples_array[0] = 0;
  162.  
  163.     depth_buffer_factor = 4;
  164.     back_buffer_factor = 2;
  165.  
  166.     switch (pixel_bits) {
  167.     case 16:
  168.         format = MESA_FORMAT_RGB565;
  169.         break;
  170.     case 24:
  171.         format = MESA_FORMAT_XRGB8888;
  172.         break;
  173.     case 32:
  174.         format = MESA_FORMAT_ARGB8888;
  175.         break;
  176.     default:
  177.         fprintf(stderr, "[%s:%u] bad depth %d\n", __func__, __LINE__,
  178.                 pixel_bits);
  179.         return NULL;
  180.     }
  181.  
  182.     configs = driCreateConfigs(format,
  183.                                depth_bits_array, stencil_bits_array,
  184.                                depth_buffer_factor, back_buffer_modes,
  185.                                back_buffer_factor, msaa_samples_array, 1,
  186.                                GL_TRUE);
  187.     if (configs == NULL) {
  188.         fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", __func__,
  189.                 __LINE__);
  190.         return NULL;
  191.     }
  192.  
  193.     return configs;
  194. }
  195.  
  196. static const __DRIconfig **
  197. dri_init_screen(__DRIscreen * psp)
  198. {
  199.     __DRIconfig **configs16, **configs24, **configs32;
  200.  
  201.     TRACE;
  202.  
  203.     psp->extensions = dri_screen_extensions;
  204.  
  205.     configs16 = swrastFillInModes(psp, 16, 16, 0, 1);
  206.     configs24 = swrastFillInModes(psp, 24, 24, 8, 1);
  207.     configs32 = swrastFillInModes(psp, 32, 24, 8, 1);
  208.  
  209.     configs24 = driConcatConfigs(configs16, configs24);
  210.     configs32 = driConcatConfigs(configs24, configs32);
  211.  
  212.     return (const __DRIconfig **)configs32;
  213. }
  214.  
  215. static void
  216. dri_destroy_screen(__DRIscreen * sPriv)
  217. {
  218.     TRACE;
  219.     (void) sPriv;
  220. }
  221.  
  222.  
  223. /**
  224.  * Framebuffer and renderbuffer-related functions.
  225.  */
  226.  
  227. static GLuint
  228. choose_pixel_format(const struct gl_config *v)
  229. {
  230.     int depth = v->rgbBits;
  231.  
  232.     if (depth == 32
  233.         && v->redMask   == 0xff0000
  234.         && v->greenMask == 0x00ff00
  235.         && v->blueMask  == 0x0000ff)
  236.         return PF_A8R8G8B8;
  237.     else if (depth == 24
  238.              && v->redMask   == 0xff0000
  239.              && v->greenMask == 0x00ff00
  240.              && v->blueMask  == 0x0000ff)
  241.         return PF_X8R8G8B8;
  242.     else if (depth == 16
  243.              && v->redMask   == 0xf800
  244.              && v->greenMask == 0x07e0
  245.              && v->blueMask  == 0x001f)
  246.         return PF_R5G6B5;
  247.     else if (depth == 8
  248.              && v->redMask   == 0x07
  249.              && v->greenMask == 0x38
  250.              && v->blueMask  == 0xc0)
  251.         return PF_R3G3B2;
  252.  
  253.     _mesa_problem( NULL, "unexpected format in %s", __FUNCTION__ );
  254.     return 0;
  255. }
  256.  
  257. static void
  258. swrast_delete_renderbuffer(struct gl_context *ctx, struct gl_renderbuffer *rb)
  259. {
  260.     struct dri_swrast_renderbuffer *xrb = dri_swrast_renderbuffer(rb);
  261.  
  262.     TRACE;
  263.  
  264.     free(xrb->Base.Buffer);
  265.     _mesa_delete_renderbuffer(ctx, rb);
  266. }
  267.  
  268. /* see bytes_per_line in libGL */
  269. static INLINE int
  270. bytes_per_line(unsigned pitch_bits, unsigned mul)
  271. {
  272.    unsigned mask = mul - 1;
  273.  
  274.    return ((pitch_bits + mask) & ~mask) / 8;
  275. }
  276.  
  277. static GLboolean
  278. swrast_alloc_front_storage(struct gl_context *ctx, struct gl_renderbuffer *rb,
  279.                            GLenum internalFormat, GLuint width, GLuint height)
  280. {
  281.     struct dri_swrast_renderbuffer *xrb = dri_swrast_renderbuffer(rb);
  282.  
  283.     TRACE;
  284.  
  285.     (void) ctx;
  286.     (void) internalFormat;
  287.  
  288.     xrb->Base.Buffer = NULL;
  289.     rb->Width = width;
  290.     rb->Height = height;
  291.     xrb->pitch = bytes_per_line(width * xrb->bpp, 32);
  292.  
  293.     return GL_TRUE;
  294. }
  295.  
  296. static GLboolean
  297. swrast_alloc_back_storage(struct gl_context *ctx, struct gl_renderbuffer *rb,
  298.                           GLenum internalFormat, GLuint width, GLuint height)
  299. {
  300.     struct dri_swrast_renderbuffer *xrb = dri_swrast_renderbuffer(rb);
  301.  
  302.     TRACE;
  303.  
  304.     free(xrb->Base.Buffer);
  305.  
  306.     swrast_alloc_front_storage(ctx, rb, internalFormat, width, height);
  307.  
  308.     xrb->Base.Buffer = malloc(height * xrb->pitch);
  309.  
  310.     return GL_TRUE;
  311. }
  312.  
  313. static struct dri_swrast_renderbuffer *
  314. swrast_new_renderbuffer(const struct gl_config *visual, __DRIdrawable *dPriv,
  315.                         GLboolean front)
  316. {
  317.     struct dri_swrast_renderbuffer *xrb = calloc(1, sizeof *xrb);
  318.     struct gl_renderbuffer *rb;
  319.     GLuint pixel_format;
  320.  
  321.     TRACE;
  322.  
  323.     if (!xrb)
  324.         return NULL;
  325.  
  326.     rb = &xrb->Base.Base;
  327.  
  328.     _mesa_init_renderbuffer(rb, 0);
  329.  
  330.     pixel_format = choose_pixel_format(visual);
  331.  
  332.     xrb->dPriv = dPriv;
  333.     xrb->Base.Base.Delete = swrast_delete_renderbuffer;
  334.     if (front) {
  335.         rb->AllocStorage = swrast_alloc_front_storage;
  336.     }
  337.     else {
  338.         rb->AllocStorage = swrast_alloc_back_storage;
  339.     }
  340.  
  341.     switch (pixel_format) {
  342.     case PF_A8R8G8B8:
  343.         rb->Format = MESA_FORMAT_ARGB8888;
  344.         rb->InternalFormat = GL_RGBA;
  345.         rb->_BaseFormat = GL_RGBA;
  346.         xrb->bpp = 32;
  347.         break;
  348.     case PF_X8R8G8B8:
  349.         rb->Format = MESA_FORMAT_ARGB8888; /* XXX */
  350.         rb->InternalFormat = GL_RGB;
  351.         rb->_BaseFormat = GL_RGB;
  352.         xrb->bpp = 32;
  353.         break;
  354.     case PF_R5G6B5:
  355.         rb->Format = MESA_FORMAT_RGB565;
  356.         rb->InternalFormat = GL_RGB;
  357.         rb->_BaseFormat = GL_RGB;
  358.         xrb->bpp = 16;
  359.         break;
  360.     case PF_R3G3B2:
  361.         rb->Format = MESA_FORMAT_RGB332;
  362.         rb->InternalFormat = GL_RGB;
  363.         rb->_BaseFormat = GL_RGB;
  364.         xrb->bpp = 8;
  365.         break;
  366.     default:
  367.         free(xrb);
  368.         return NULL;
  369.     }
  370.  
  371.     return xrb;
  372. }
  373.  
  374. static void
  375. swrast_map_renderbuffer(struct gl_context *ctx,
  376.                         struct gl_renderbuffer *rb,
  377.                         GLuint x, GLuint y, GLuint w, GLuint h,
  378.                         GLbitfield mode,
  379.                         GLubyte **out_map,
  380.                         GLint *out_stride)
  381. {
  382.    struct dri_swrast_renderbuffer *xrb = dri_swrast_renderbuffer(rb);
  383.    GLubyte *map = xrb->Base.Buffer;
  384.    int cpp = _mesa_get_format_bytes(rb->Format);
  385.    int stride = rb->Width * cpp;
  386.  
  387.    if (rb->AllocStorage == swrast_alloc_front_storage) {
  388.       __DRIdrawable *dPriv = xrb->dPriv;
  389.       __DRIscreen *sPriv = dPriv->driScreenPriv;
  390.  
  391.       xrb->map_mode = mode;
  392.       xrb->map_x = x;
  393.       xrb->map_y = y;
  394.       xrb->map_w = w;
  395.       xrb->map_h = h;
  396.  
  397.       stride = w * cpp;
  398.       xrb->Base.Buffer = malloc(h * stride);
  399.  
  400.       sPriv->swrast_loader->getImage(dPriv, x, rb->Height - y - h, w, h,
  401.                                      (char *) xrb->Base.Buffer,
  402.                                      dPriv->loaderPrivate);
  403.  
  404.       *out_map = xrb->Base.Buffer + (h - 1) * stride;
  405.       *out_stride = -stride;
  406.       return;
  407.    }
  408.  
  409.    ASSERT(xrb->Base.Buffer);
  410.  
  411.    if (rb->AllocStorage == swrast_alloc_back_storage) {
  412.       map += (rb->Height - 1) * stride;
  413.       stride = -stride;
  414.    }
  415.  
  416.    map += (GLsizei)y * stride;
  417.    map += (GLsizei)x * cpp;
  418.  
  419.    *out_map = map;
  420.    *out_stride = stride;
  421. }
  422.  
  423. static void
  424. swrast_unmap_renderbuffer(struct gl_context *ctx,
  425.                           struct gl_renderbuffer *rb)
  426. {
  427.    struct dri_swrast_renderbuffer *xrb = dri_swrast_renderbuffer(rb);
  428.  
  429.    if (rb->AllocStorage == swrast_alloc_front_storage) {
  430.       __DRIdrawable *dPriv = xrb->dPriv;
  431.       __DRIscreen *sPriv = dPriv->driScreenPriv;
  432.  
  433.       if (xrb->map_mode & GL_MAP_WRITE_BIT) {
  434.          sPriv->swrast_loader->putImage(dPriv, __DRI_SWRAST_IMAGE_OP_DRAW,
  435.                                         xrb->map_x, xrb->map_y,
  436.                                         xrb->map_w, xrb->map_h,
  437.                                         (char *) xrb->Base.Buffer,
  438.                                         dPriv->loaderPrivate);
  439.       }
  440.  
  441.       free(xrb->Base.Buffer);
  442.       xrb->Base.Buffer = NULL;
  443.    }
  444. }
  445.  
  446. static GLboolean
  447. dri_create_buffer(__DRIscreen * sPriv,
  448.                   __DRIdrawable * dPriv,
  449.                   const struct gl_config * visual, GLboolean isPixmap)
  450. {
  451.     struct dri_drawable *drawable = NULL;
  452.     struct gl_framebuffer *fb;
  453.     struct dri_swrast_renderbuffer *frontrb, *backrb;
  454.  
  455.     TRACE;
  456.  
  457.     (void) sPriv;
  458.     (void) isPixmap;
  459.  
  460.     drawable = CALLOC_STRUCT(dri_drawable);
  461.     if (drawable == NULL)
  462.         goto drawable_fail;
  463.  
  464.     dPriv->driverPrivate = drawable;
  465.     drawable->dPriv = dPriv;
  466.  
  467.     drawable->row = malloc(SWRAST_MAX_WIDTH * 4);
  468.     if (drawable->row == NULL)
  469.         goto drawable_fail;
  470.  
  471.     fb = &drawable->Base;
  472.  
  473.     /* basic framebuffer setup */
  474.     _mesa_initialize_window_framebuffer(fb, visual);
  475.  
  476.     /* add front renderbuffer */
  477.     frontrb = swrast_new_renderbuffer(visual, dPriv, GL_TRUE);
  478.     _mesa_add_renderbuffer(fb, BUFFER_FRONT_LEFT, &frontrb->Base.Base);
  479.  
  480.     /* add back renderbuffer */
  481.     if (visual->doubleBufferMode) {
  482.         backrb = swrast_new_renderbuffer(visual, dPriv, GL_FALSE);
  483.         _mesa_add_renderbuffer(fb, BUFFER_BACK_LEFT, &backrb->Base.Base);
  484.     }
  485.  
  486.     /* add software renderbuffers */
  487.     _swrast_add_soft_renderbuffers(fb,
  488.                                    GL_FALSE, /* color */
  489.                                    visual->haveDepthBuffer,
  490.                                    visual->haveStencilBuffer,
  491.                                    visual->haveAccumBuffer,
  492.                                    GL_FALSE, /* alpha */
  493.                                    GL_FALSE /* aux bufs */);
  494.  
  495.     return GL_TRUE;
  496.  
  497. drawable_fail:
  498.  
  499.     if (drawable)
  500.         free(drawable->row);
  501.  
  502.     free(drawable);
  503.  
  504.     return GL_FALSE;
  505. }
  506.  
  507. static void
  508. dri_destroy_buffer(__DRIdrawable * dPriv)
  509. {
  510.     TRACE;
  511.  
  512.     if (dPriv) {
  513.         struct dri_drawable *drawable = dri_drawable(dPriv);
  514.         struct gl_framebuffer *fb;
  515.  
  516.         free(drawable->row);
  517.  
  518.         fb = &drawable->Base;
  519.  
  520.         fb->DeletePending = GL_TRUE;
  521.         _mesa_reference_framebuffer(&fb, NULL);
  522.     }
  523. }
  524.  
  525. static void
  526. dri_swap_buffers(__DRIdrawable * dPriv)
  527. {
  528.     __DRIscreen *sPriv = dPriv->driScreenPriv;
  529.  
  530.     GET_CURRENT_CONTEXT(ctx);
  531.  
  532.     struct dri_drawable *drawable = dri_drawable(dPriv);
  533.     struct gl_framebuffer *fb;
  534.     struct dri_swrast_renderbuffer *frontrb, *backrb;
  535.  
  536.     TRACE;
  537.  
  538.     fb = &drawable->Base;
  539.  
  540.     frontrb =
  541.         dri_swrast_renderbuffer(fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer);
  542.     backrb =
  543.         dri_swrast_renderbuffer(fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer);
  544.  
  545.     /* check for signle-buffered */
  546.     if (backrb == NULL)
  547.         return;
  548.  
  549.     /* check if swapping currently bound buffer */
  550.     if (ctx && ctx->DrawBuffer == fb) {
  551.         /* flush pending rendering */
  552.         _mesa_notifySwapBuffers(ctx);
  553.     }
  554.  
  555.     sPriv->swrast_loader->putImage(dPriv, __DRI_SWRAST_IMAGE_OP_SWAP,
  556.                                    0, 0,
  557.                                    frontrb->Base.Base.Width,
  558.                                    frontrb->Base.Base.Height,
  559.                                    (char *) backrb->Base.Buffer,
  560.                                    dPriv->loaderPrivate);
  561. }
  562.  
  563.  
  564. /**
  565.  * General device driver functions.
  566.  */
  567.  
  568. static void
  569. get_window_size( struct gl_framebuffer *fb, GLsizei *w, GLsizei *h )
  570. {
  571.     __DRIdrawable *dPriv = swrast_drawable(fb)->dPriv;
  572.     __DRIscreen *sPriv = dPriv->driScreenPriv;
  573.     int x, y;
  574.  
  575.     sPriv->swrast_loader->getDrawableInfo(dPriv,
  576.                                           &x, &y, w, h,
  577.                                           dPriv->loaderPrivate);
  578. }
  579.  
  580. static void
  581. swrast_check_and_update_window_size( struct gl_context *ctx, struct gl_framebuffer *fb )
  582. {
  583.     GLsizei width, height;
  584.  
  585.     get_window_size(fb, &width, &height);
  586.     if (fb->Width != width || fb->Height != height) {
  587.         _mesa_resize_framebuffer(ctx, fb, width, height);
  588.     }
  589. }
  590.  
  591. static const GLubyte *
  592. get_string(struct gl_context *ctx, GLenum pname)
  593. {
  594.     (void) ctx;
  595.     switch (pname) {
  596.         case GL_VENDOR:
  597.             return (const GLubyte *) "Mesa Project";
  598.         case GL_RENDERER:
  599.             return (const GLubyte *) "Software Rasterizer";
  600.         default:
  601.             return NULL;
  602.     }
  603. }
  604.  
  605. static void
  606. update_state( struct gl_context *ctx, GLuint new_state )
  607. {
  608.     /* not much to do here - pass it on */
  609.     _swrast_InvalidateState( ctx, new_state );
  610.     _swsetup_InvalidateState( ctx, new_state );
  611.     _vbo_InvalidateState( ctx, new_state );
  612.     _tnl_InvalidateState( ctx, new_state );
  613. }
  614.  
  615. static void
  616. viewport(struct gl_context *ctx, GLint x, GLint y, GLsizei w, GLsizei h)
  617. {
  618.     struct gl_framebuffer *draw = ctx->WinSysDrawBuffer;
  619.     struct gl_framebuffer *read = ctx->WinSysReadBuffer;
  620.  
  621.     (void) x;
  622.     (void) y;
  623.     (void) w;
  624.     (void) h;
  625.     swrast_check_and_update_window_size(ctx, draw);
  626.     swrast_check_and_update_window_size(ctx, read);
  627. }
  628.  
  629. static gl_format swrastChooseTextureFormat(struct gl_context * ctx,
  630.                                            GLenum target,
  631.                                            GLint internalFormat,
  632.                                            GLenum format,
  633.                                            GLenum type)
  634. {
  635.     if (internalFormat == GL_RGB)
  636.         return MESA_FORMAT_XRGB8888;
  637.     return _mesa_choose_tex_format(ctx, target, internalFormat, format, type);
  638. }
  639.  
  640. static void
  641. swrast_init_driver_functions(struct dd_function_table *driver)
  642. {
  643.     driver->GetString = get_string;
  644.     driver->UpdateState = update_state;
  645.     driver->Viewport = viewport;
  646.     driver->ChooseTextureFormat = swrastChooseTextureFormat;
  647.     driver->MapRenderbuffer = swrast_map_renderbuffer;
  648.     driver->UnmapRenderbuffer = swrast_unmap_renderbuffer;
  649. }
  650.  
  651. /**
  652.  * Context-related functions.
  653.  */
  654.  
  655. static GLboolean
  656. dri_create_context(gl_api api,
  657.                    const struct gl_config * visual,
  658.                    __DRIcontext * cPriv,
  659.                    unsigned major_version,
  660.                    unsigned minor_version,
  661.                    uint32_t flags,
  662.                    unsigned *error,
  663.                    void *sharedContextPrivate)
  664. {
  665.     struct dri_context *ctx = NULL;
  666.     struct dri_context *share = (struct dri_context *)sharedContextPrivate;
  667.     struct gl_context *mesaCtx = NULL;
  668.     struct gl_context *sharedCtx = NULL;
  669.     struct dd_function_table functions;
  670.  
  671.     TRACE;
  672.  
  673.     /* Flag filtering is handled in dri2CreateContextAttribs.
  674.      */
  675.     (void) flags;
  676.  
  677.     switch (api) {
  678.     case API_OPENGL_COMPAT:
  679.         if (major_version > 2
  680.             || (major_version == 2 && minor_version > 1)) {
  681.             *error = __DRI_CTX_ERROR_BAD_VERSION;
  682.             return GL_FALSE;
  683.         }
  684.         break;
  685.     case API_OPENGLES:
  686.     case API_OPENGLES2:
  687.         break;
  688.     case API_OPENGL_CORE:
  689.         *error = __DRI_CTX_ERROR_BAD_API;
  690.         return GL_FALSE;
  691.     }
  692.  
  693.     ctx = CALLOC_STRUCT(dri_context);
  694.     if (ctx == NULL) {
  695.         *error = __DRI_CTX_ERROR_NO_MEMORY;
  696.         goto context_fail;
  697.     }
  698.  
  699.     cPriv->driverPrivate = ctx;
  700.     ctx->cPriv = cPriv;
  701.  
  702.     /* build table of device driver functions */
  703.     _mesa_init_driver_functions(&functions);
  704.     swrast_init_driver_functions(&functions);
  705.  
  706.     if (share) {
  707.         sharedCtx = &share->Base;
  708.     }
  709.  
  710.     mesaCtx = &ctx->Base;
  711.  
  712.     /* basic context setup */
  713.     if (!_mesa_initialize_context(mesaCtx, api, visual, sharedCtx, &functions)) {
  714.         *error = __DRI_CTX_ERROR_NO_MEMORY;
  715.         goto context_fail;
  716.     }
  717.  
  718.     /* do bounds checking to prevent segfaults and server crashes! */
  719.     mesaCtx->Const.CheckArrayBounds = GL_TRUE;
  720.  
  721.     /* create module contexts */
  722.     _swrast_CreateContext( mesaCtx );
  723.     _vbo_CreateContext( mesaCtx );
  724.     _tnl_CreateContext( mesaCtx );
  725.     _swsetup_CreateContext( mesaCtx );
  726.     _swsetup_Wakeup( mesaCtx );
  727.  
  728.     /* use default TCL pipeline */
  729.     {
  730.        TNLcontext *tnl = TNL_CONTEXT(mesaCtx);
  731.        tnl->Driver.RunPipeline = _tnl_run_pipeline;
  732.     }
  733.  
  734.     _mesa_meta_init(mesaCtx);
  735.     _mesa_enable_sw_extensions(mesaCtx);
  736.  
  737.     _mesa_compute_version(mesaCtx);
  738.  
  739.     _mesa_initialize_dispatch_tables(mesaCtx);
  740.     _mesa_initialize_vbo_vtxfmt(mesaCtx);
  741.  
  742.     *error = __DRI_CTX_ERROR_SUCCESS;
  743.     return GL_TRUE;
  744.  
  745. context_fail:
  746.  
  747.     free(ctx);
  748.  
  749.     return GL_FALSE;
  750. }
  751.  
  752. static void
  753. dri_destroy_context(__DRIcontext * cPriv)
  754. {
  755.     TRACE;
  756.  
  757.     if (cPriv) {
  758.         struct dri_context *ctx = dri_context(cPriv);
  759.         struct gl_context *mesaCtx;
  760.  
  761.         mesaCtx = &ctx->Base;
  762.  
  763.         _mesa_meta_free(mesaCtx);
  764.         _swsetup_DestroyContext( mesaCtx );
  765.         _swrast_DestroyContext( mesaCtx );
  766.         _tnl_DestroyContext( mesaCtx );
  767.         _vbo_DestroyContext( mesaCtx );
  768.         _mesa_destroy_context( mesaCtx );
  769.     }
  770. }
  771.  
  772. static GLboolean
  773. dri_make_current(__DRIcontext * cPriv,
  774.                  __DRIdrawable * driDrawPriv,
  775.                  __DRIdrawable * driReadPriv)
  776. {
  777.     struct gl_context *mesaCtx;
  778.     struct gl_framebuffer *mesaDraw;
  779.     struct gl_framebuffer *mesaRead;
  780.     TRACE;
  781.  
  782.     if (cPriv) {
  783.         struct dri_context *ctx = dri_context(cPriv);
  784.         struct dri_drawable *draw;
  785.         struct dri_drawable *read;
  786.  
  787.         if (!driDrawPriv || !driReadPriv)
  788.             return GL_FALSE;
  789.  
  790.         draw = dri_drawable(driDrawPriv);
  791.         read = dri_drawable(driReadPriv);
  792.         mesaCtx = &ctx->Base;
  793.         mesaDraw = &draw->Base;
  794.         mesaRead = &read->Base;
  795.  
  796.         /* check for same context and buffer */
  797.         if (mesaCtx == _mesa_get_current_context()
  798.             && mesaCtx->DrawBuffer == mesaDraw
  799.             && mesaCtx->ReadBuffer == mesaRead) {
  800.             return GL_TRUE;
  801.         }
  802.  
  803.         _glapi_check_multithread();
  804.  
  805.         swrast_check_and_update_window_size(mesaCtx, mesaDraw);
  806.         if (mesaRead != mesaDraw)
  807.             swrast_check_and_update_window_size(mesaCtx, mesaRead);
  808.  
  809.         _mesa_make_current( mesaCtx,
  810.                             mesaDraw,
  811.                             mesaRead );
  812.     }
  813.     else {
  814.         /* unbind */
  815.         _mesa_make_current( NULL, NULL, NULL );
  816.     }
  817.  
  818.     return GL_TRUE;
  819. }
  820.  
  821. static GLboolean
  822. dri_unbind_context(__DRIcontext * cPriv)
  823. {
  824.     TRACE;
  825.     (void) cPriv;
  826.  
  827.     /* Unset current context and dispath table */
  828.     _mesa_make_current(NULL, NULL, NULL);
  829.  
  830.     return GL_TRUE;
  831. }
  832.  
  833.  
  834. const struct __DriverAPIRec driDriverAPI = {
  835.     .InitScreen = dri_init_screen,
  836.     .DestroyScreen = dri_destroy_screen,
  837.     .CreateContext = dri_create_context,
  838.     .DestroyContext = dri_destroy_context,
  839.     .CreateBuffer = dri_create_buffer,
  840.     .DestroyBuffer = dri_destroy_buffer,
  841.     .SwapBuffers = dri_swap_buffers,
  842.     .MakeCurrent = dri_make_current,
  843.     .UnbindContext = dri_unbind_context,
  844. };
  845.  
  846. /* This is the table of extensions that the loader will dlsym() for. */
  847. PUBLIC const __DRIextension *__driDriverExtensions[] = {
  848.     &driCoreExtension.base,
  849.     &driSWRastExtension.base,
  850.     NULL
  851. };
  852.