Subversion Repositories Kolibri OS

Rev

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

  1. /*
  2.  * Mesa 3-D graphics library
  3.  * Version:  7.2
  4.  *
  5.  * Copyright (C) 1999-2008  Brian Paul   All Rights Reserved.
  6.  *
  7.  * Permission is hereby granted, free of charge, to any person obtaining a
  8.  * copy of this software and associated documentation files (the "Software"),
  9.  * to deal in the Software without restriction, including without limitation
  10.  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  11.  * and/or sell copies of the Software, and to permit persons to whom the
  12.  * Software is furnished to do so, subject to the following conditions:
  13.  *
  14.  * The above copyright notice and this permission notice shall be included
  15.  * in all copies or substantial portions of the Software.
  16.  *
  17.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  18.  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  19.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  20.  * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
  21.  * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  22.  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  23.  */
  24.  
  25.  
  26. /**
  27.  * Functions for allocating/managing framebuffers and renderbuffers.
  28.  * Also, routines for reading/writing renderbuffer data as ubytes,
  29.  * ushorts, uints, etc.
  30.  */
  31.  
  32.  
  33. #include "glheader.h"
  34. #include "imports.h"
  35. #include "buffers.h"
  36. #include "context.h"
  37. #include "depthstencil.h"
  38. #include "enums.h"
  39. #include "formats.h"
  40. #include "macros.h"
  41. #include "mtypes.h"
  42. #include "fbobject.h"
  43. #include "framebuffer.h"
  44. #include "renderbuffer.h"
  45. #include "texobj.h"
  46.  
  47.  
  48.  
  49. /**
  50.  * Compute/set the _DepthMax field for the given framebuffer.
  51.  * This value depends on the Z buffer resolution.
  52.  */
  53. static void
  54. compute_depth_max(struct gl_framebuffer *fb)
  55. {
  56.    if (fb->Visual.depthBits == 0) {
  57.       /* Special case.  Even if we don't have a depth buffer we need
  58.        * good values for DepthMax for Z vertex transformation purposes
  59.        * and for per-fragment fog computation.
  60.        */
  61.       fb->_DepthMax = (1 << 16) - 1;
  62.    }
  63.    else if (fb->Visual.depthBits < 32) {
  64.       fb->_DepthMax = (1 << fb->Visual.depthBits) - 1;
  65.    }
  66.    else {
  67.       /* Special case since shift values greater than or equal to the
  68.        * number of bits in the left hand expression's type are undefined.
  69.        */
  70.       fb->_DepthMax = 0xffffffff;
  71.    }
  72.    fb->_DepthMaxF = (GLfloat) fb->_DepthMax;
  73.  
  74.    /* Minimum resolvable depth value, for polygon offset */
  75.    fb->_MRD = (GLfloat)1.0 / fb->_DepthMaxF;
  76. }
  77.  
  78. /**
  79.  * Create and initialize a gl_framebuffer object.
  80.  * This is intended for creating _window_system_ framebuffers, not generic
  81.  * framebuffer objects ala GL_EXT_framebuffer_object.
  82.  *
  83.  * \sa _mesa_new_framebuffer
  84.  */
  85. struct gl_framebuffer *
  86. _mesa_create_framebuffer(const struct gl_config *visual)
  87. {
  88.    struct gl_framebuffer *fb = CALLOC_STRUCT(gl_framebuffer);
  89.    assert(visual);
  90.    if (fb) {
  91.       _mesa_initialize_window_framebuffer(fb, visual);
  92.    }
  93.    return fb;
  94. }
  95.  
  96.  
  97. /**
  98.  * Allocate a new gl_framebuffer object.
  99.  * This is the default function for ctx->Driver.NewFramebuffer().
  100.  * This is for allocating user-created framebuffers, not window-system
  101.  * framebuffers!
  102.  * \sa _mesa_create_framebuffer
  103.  */
  104. struct gl_framebuffer *
  105. _mesa_new_framebuffer(struct gl_context *ctx, GLuint name)
  106. {
  107.    struct gl_framebuffer *fb;
  108.    (void) ctx;
  109.    assert(name != 0);
  110.    fb = CALLOC_STRUCT(gl_framebuffer);
  111.    if (fb) {
  112.       _mesa_initialize_user_framebuffer(fb, name);
  113.    }
  114.    return fb;
  115. }
  116.  
  117.  
  118. /**
  119.  * Initialize a gl_framebuffer object.  Typically used to initialize
  120.  * window system-created framebuffers, not user-created framebuffers.
  121.  * \sa _mesa_initialize_user_framebuffer
  122.  */
  123. void
  124. _mesa_initialize_window_framebuffer(struct gl_framebuffer *fb,
  125.                                      const struct gl_config *visual)
  126. {
  127.    assert(fb);
  128.    assert(visual);
  129.  
  130.    memset(fb, 0, sizeof(struct gl_framebuffer));
  131.  
  132.    _glthread_INIT_MUTEX(fb->Mutex);
  133.  
  134.    fb->RefCount = 1;
  135.  
  136.    /* save the visual */
  137.    fb->Visual = *visual;
  138.  
  139.    /* Init read/draw renderbuffer state */
  140.    if (visual->doubleBufferMode) {
  141.       fb->_NumColorDrawBuffers = 1;
  142.       fb->ColorDrawBuffer[0] = GL_BACK;
  143.       fb->_ColorDrawBufferIndexes[0] = BUFFER_BACK_LEFT;
  144.       fb->ColorReadBuffer = GL_BACK;
  145.       fb->_ColorReadBufferIndex = BUFFER_BACK_LEFT;
  146.    }
  147.    else {
  148.       fb->_NumColorDrawBuffers = 1;
  149.       fb->ColorDrawBuffer[0] = GL_FRONT;
  150.       fb->_ColorDrawBufferIndexes[0] = BUFFER_FRONT_LEFT;
  151.       fb->ColorReadBuffer = GL_FRONT;
  152.       fb->_ColorReadBufferIndex = BUFFER_FRONT_LEFT;
  153.    }
  154.  
  155.    fb->Delete = _mesa_destroy_framebuffer;
  156.    fb->_Status = GL_FRAMEBUFFER_COMPLETE_EXT;
  157.  
  158.    compute_depth_max(fb);
  159. }
  160.  
  161.  
  162. /**
  163.  * Initialize a user-created gl_framebuffer object.
  164.  * \sa _mesa_initialize_window_framebuffer
  165.  */
  166. void
  167. _mesa_initialize_user_framebuffer(struct gl_framebuffer *fb, GLuint name)
  168. {
  169.    assert(fb);
  170.    assert(name);
  171.  
  172.    memset(fb, 0, sizeof(struct gl_framebuffer));
  173.  
  174.    fb->Name = name;
  175.    fb->RefCount = 1;
  176.    fb->_NumColorDrawBuffers = 1;
  177.    fb->ColorDrawBuffer[0] = GL_COLOR_ATTACHMENT0_EXT;
  178.    fb->_ColorDrawBufferIndexes[0] = BUFFER_COLOR0;
  179.    fb->ColorReadBuffer = GL_COLOR_ATTACHMENT0_EXT;
  180.    fb->_ColorReadBufferIndex = BUFFER_COLOR0;
  181.    fb->Delete = _mesa_destroy_framebuffer;
  182.    _glthread_INIT_MUTEX(fb->Mutex);
  183. }
  184.  
  185.  
  186. /**
  187.  * Deallocate buffer and everything attached to it.
  188.  * Typically called via the gl_framebuffer->Delete() method.
  189.  */
  190. void
  191. _mesa_destroy_framebuffer(struct gl_framebuffer *fb)
  192. {
  193.    if (fb) {
  194.       _mesa_free_framebuffer_data(fb);
  195.       free(fb);
  196.    }
  197. }
  198.  
  199.  
  200. /**
  201.  * Free all the data hanging off the given gl_framebuffer, but don't free
  202.  * the gl_framebuffer object itself.
  203.  */
  204. void
  205. _mesa_free_framebuffer_data(struct gl_framebuffer *fb)
  206. {
  207.    GLuint i;
  208.  
  209.    assert(fb);
  210.    assert(fb->RefCount == 0);
  211.  
  212.    _glthread_DESTROY_MUTEX(fb->Mutex);
  213.  
  214.    for (i = 0; i < BUFFER_COUNT; i++) {
  215.       struct gl_renderbuffer_attachment *att = &fb->Attachment[i];
  216.       if (att->Renderbuffer) {
  217.          _mesa_reference_renderbuffer(&att->Renderbuffer, NULL);
  218.       }
  219.       if (att->Texture) {
  220.          _mesa_reference_texobj(&att->Texture, NULL);
  221.       }
  222.       ASSERT(!att->Renderbuffer);
  223.       ASSERT(!att->Texture);
  224.       att->Type = GL_NONE;
  225.    }
  226.  
  227.    /* unbind _Depth/_StencilBuffer to decr ref counts */
  228.    _mesa_reference_renderbuffer(&fb->_DepthBuffer, NULL);
  229.    _mesa_reference_renderbuffer(&fb->_StencilBuffer, NULL);
  230. }
  231.  
  232.  
  233. /**
  234.  * Set *ptr to point to fb, with refcounting and locking.
  235.  */
  236. void
  237. _mesa_reference_framebuffer(struct gl_framebuffer **ptr,
  238.                             struct gl_framebuffer *fb)
  239. {
  240.    assert(ptr);
  241.    if (*ptr == fb) {
  242.       /* no change */
  243.       return;
  244.    }
  245.  
  246.    if (*ptr) {
  247.       /* unreference old renderbuffer */
  248.       GLboolean deleteFlag = GL_FALSE;
  249.       struct gl_framebuffer *oldFb = *ptr;
  250.  
  251.       _glthread_LOCK_MUTEX(oldFb->Mutex);
  252.       ASSERT(oldFb->RefCount > 0);
  253.       oldFb->RefCount--;
  254.       deleteFlag = (oldFb->RefCount == 0);
  255.       _glthread_UNLOCK_MUTEX(oldFb->Mutex);
  256.      
  257.       if (deleteFlag)
  258.          oldFb->Delete(oldFb);
  259.  
  260.       *ptr = NULL;
  261.    }
  262.    assert(!*ptr);
  263.  
  264.    if (fb) {
  265.       _glthread_LOCK_MUTEX(fb->Mutex);
  266.       fb->RefCount++;
  267.       _glthread_UNLOCK_MUTEX(fb->Mutex);
  268.       *ptr = fb;
  269.    }
  270. }
  271.  
  272.  
  273. /**
  274.  * Resize the given framebuffer's renderbuffers to the new width and height.
  275.  * This should only be used for window-system framebuffers, not
  276.  * user-created renderbuffers (i.e. made with GL_EXT_framebuffer_object).
  277.  * This will typically be called via ctx->Driver.ResizeBuffers() or directly
  278.  * from a device driver.
  279.  *
  280.  * \note it's possible for ctx to be null since a window can be resized
  281.  * without a currently bound rendering context.
  282.  */
  283. void
  284. _mesa_resize_framebuffer(struct gl_context *ctx, struct gl_framebuffer *fb,
  285.                          GLuint width, GLuint height)
  286. {
  287.    GLuint i;
  288.  
  289.    /* XXX I think we could check if the size is not changing
  290.     * and return early.
  291.     */
  292.  
  293.    /* For window system framebuffers, Name is zero */
  294.    assert(fb->Name == 0);
  295.  
  296.    for (i = 0; i < BUFFER_COUNT; i++) {
  297.       struct gl_renderbuffer_attachment *att = &fb->Attachment[i];
  298.       if (att->Type == GL_RENDERBUFFER_EXT && att->Renderbuffer) {
  299.          struct gl_renderbuffer *rb = att->Renderbuffer;
  300.          /* only resize if size is changing */
  301.          if (rb->Width != width || rb->Height != height) {
  302.             if (rb->AllocStorage(ctx, rb, rb->InternalFormat, width, height)) {
  303.                ASSERT(rb->Width == width);
  304.                ASSERT(rb->Height == height);
  305.             }
  306.             else {
  307.                _mesa_error(ctx, GL_OUT_OF_MEMORY, "Resizing framebuffer");
  308.                /* no return */
  309.             }
  310.          }
  311.       }
  312.    }
  313.  
  314.    if (fb->_DepthBuffer) {
  315.       struct gl_renderbuffer *rb = fb->_DepthBuffer;
  316.       if (rb->Width != width || rb->Height != height) {
  317.          if (!rb->AllocStorage(ctx, rb, rb->InternalFormat, width, height)) {
  318.             _mesa_error(ctx, GL_OUT_OF_MEMORY, "Resizing framebuffer");
  319.          }
  320.       }
  321.    }
  322.  
  323.    if (fb->_StencilBuffer) {
  324.       struct gl_renderbuffer *rb = fb->_StencilBuffer;
  325.       if (rb->Width != width || rb->Height != height) {
  326.          if (!rb->AllocStorage(ctx, rb, rb->InternalFormat, width, height)) {
  327.             _mesa_error(ctx, GL_OUT_OF_MEMORY, "Resizing framebuffer");
  328.          }
  329.       }
  330.    }
  331.  
  332.    fb->Width = width;
  333.    fb->Height = height;
  334.  
  335.    if (ctx) {
  336.       /* update scissor / window bounds */
  337.       _mesa_update_draw_buffer_bounds(ctx);
  338.       /* Signal new buffer state so that swrast will update its clipping
  339.        * info (the CLIP_BIT flag).
  340.        */
  341.       ctx->NewState |= _NEW_BUFFERS;
  342.    }
  343. }
  344.  
  345.  
  346.  
  347. /**
  348.  * XXX THIS IS OBSOLETE - drivers should take care of detecting window
  349.  * size changes and act accordingly, likely calling _mesa_resize_framebuffer().
  350.  *
  351.  * GL_MESA_resize_buffers extension.
  352.  *
  353.  * When this function is called, we'll ask the window system how large
  354.  * the current window is.  If it's a new size, we'll call the driver's
  355.  * ResizeBuffers function.  The driver will then resize its color buffers
  356.  * as needed, and maybe call the swrast's routine for reallocating
  357.  * swrast-managed depth/stencil/accum/etc buffers.
  358.  * \note This function should only be called through the GL API, not
  359.  * from device drivers (as was done in the past).
  360.  */
  361. void
  362. _mesa_resizebuffers( struct gl_context *ctx )
  363. {
  364.    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH( ctx );
  365.  
  366.    if (MESA_VERBOSE & VERBOSE_API)
  367.       _mesa_debug(ctx, "glResizeBuffersMESA\n");
  368.  
  369.    if (!ctx->Driver.GetBufferSize) {
  370.       return;
  371.    }
  372.  
  373.    if (ctx->WinSysDrawBuffer) {
  374.       GLuint newWidth, newHeight;
  375.       struct gl_framebuffer *buffer = ctx->WinSysDrawBuffer;
  376.  
  377.       assert(buffer->Name == 0);
  378.  
  379.       /* ask device driver for size of output buffer */
  380.       ctx->Driver.GetBufferSize( buffer, &newWidth, &newHeight );
  381.  
  382.       /* see if size of device driver's color buffer (window) has changed */
  383.       if (buffer->Width != newWidth || buffer->Height != newHeight) {
  384.          if (ctx->Driver.ResizeBuffers)
  385.             ctx->Driver.ResizeBuffers(ctx, buffer, newWidth, newHeight );
  386.       }
  387.    }
  388.  
  389.    if (ctx->WinSysReadBuffer
  390.        && ctx->WinSysReadBuffer != ctx->WinSysDrawBuffer) {
  391.       GLuint newWidth, newHeight;
  392.       struct gl_framebuffer *buffer = ctx->WinSysReadBuffer;
  393.  
  394.       assert(buffer->Name == 0);
  395.  
  396.       /* ask device driver for size of read buffer */
  397.       ctx->Driver.GetBufferSize( buffer, &newWidth, &newHeight );
  398.  
  399.       /* see if size of device driver's color buffer (window) has changed */
  400.       if (buffer->Width != newWidth || buffer->Height != newHeight) {
  401.          if (ctx->Driver.ResizeBuffers)
  402.             ctx->Driver.ResizeBuffers(ctx, buffer, newWidth, newHeight );
  403.       }
  404.    }
  405.  
  406.    ctx->NewState |= _NEW_BUFFERS;  /* to update scissor / window bounds */
  407. }
  408.  
  409.  
  410. /*
  411.  * XXX THIS IS OBSOLETE
  412.  */
  413. void GLAPIENTRY
  414. _mesa_ResizeBuffersMESA( void )
  415. {
  416.    GET_CURRENT_CONTEXT(ctx);
  417.  
  418.    if (ctx->Extensions.MESA_resize_buffers)
  419.       _mesa_resizebuffers( ctx );
  420. }
  421.  
  422.  
  423.  
  424. /**
  425.  * Examine all the framebuffer's renderbuffers to update the Width/Height
  426.  * fields of the framebuffer.  If we have renderbuffers with different
  427.  * sizes, set the framebuffer's width and height to the min size.
  428.  * Note: this is only intended for user-created framebuffers, not
  429.  * window-system framebuffes.
  430.  */
  431. static void
  432. update_framebuffer_size(struct gl_context *ctx, struct gl_framebuffer *fb)
  433. {
  434.    GLuint minWidth = ~0, minHeight = ~0;
  435.    GLuint i;
  436.  
  437.    /* user-created framebuffers only */
  438.    assert(fb->Name);
  439.  
  440.    for (i = 0; i < BUFFER_COUNT; i++) {
  441.       struct gl_renderbuffer_attachment *att = &fb->Attachment[i];
  442.       const struct gl_renderbuffer *rb = att->Renderbuffer;
  443.       if (rb) {
  444.          minWidth = MIN2(minWidth, rb->Width);
  445.          minHeight = MIN2(minHeight, rb->Height);
  446.       }
  447.    }
  448.  
  449.    if (minWidth != ~0) {
  450.       fb->Width = minWidth;
  451.       fb->Height = minHeight;
  452.    }
  453.    else {
  454.       fb->Width = 0;
  455.       fb->Height = 0;
  456.    }
  457. }
  458.  
  459.  
  460. /**
  461.  * Update the context's current drawing buffer's Xmin, Xmax, Ymin, Ymax fields.
  462.  * These values are computed from the buffer's width and height and
  463.  * the scissor box, if it's enabled.
  464.  * \param ctx  the GL context.
  465.  */
  466. void
  467. _mesa_update_draw_buffer_bounds(struct gl_context *ctx)
  468. {
  469.    struct gl_framebuffer *buffer = ctx->DrawBuffer;
  470.  
  471.    if (!buffer)
  472.       return;
  473.  
  474.    if (buffer->Name) {
  475.       /* user-created framebuffer size depends on the renderbuffers */
  476.       update_framebuffer_size(ctx, buffer);
  477.    }
  478.  
  479.    buffer->_Xmin = 0;
  480.    buffer->_Ymin = 0;
  481.    buffer->_Xmax = buffer->Width;
  482.    buffer->_Ymax = buffer->Height;
  483.  
  484.    if (ctx->Scissor.Enabled) {
  485.       if (ctx->Scissor.X > buffer->_Xmin) {
  486.          buffer->_Xmin = ctx->Scissor.X;
  487.       }
  488.       if (ctx->Scissor.Y > buffer->_Ymin) {
  489.          buffer->_Ymin = ctx->Scissor.Y;
  490.       }
  491.       if (ctx->Scissor.X + ctx->Scissor.Width < buffer->_Xmax) {
  492.          buffer->_Xmax = ctx->Scissor.X + ctx->Scissor.Width;
  493.       }
  494.       if (ctx->Scissor.Y + ctx->Scissor.Height < buffer->_Ymax) {
  495.          buffer->_Ymax = ctx->Scissor.Y + ctx->Scissor.Height;
  496.       }
  497.       /* finally, check for empty region */
  498.       if (buffer->_Xmin > buffer->_Xmax) {
  499.          buffer->_Xmin = buffer->_Xmax;
  500.       }
  501.       if (buffer->_Ymin > buffer->_Ymax) {
  502.          buffer->_Ymin = buffer->_Ymax;
  503.       }
  504.    }
  505.  
  506.    ASSERT(buffer->_Xmin <= buffer->_Xmax);
  507.    ASSERT(buffer->_Ymin <= buffer->_Ymax);
  508. }
  509.  
  510.  
  511. /**
  512.  * The glGet queries of the framebuffer red/green/blue size, stencil size,
  513.  * etc. are satisfied by the fields of ctx->DrawBuffer->Visual.  These can
  514.  * change depending on the renderbuffer bindings.  This function updates
  515.  * the given framebuffer's Visual from the current renderbuffer bindings.
  516.  *
  517.  * This may apply to user-created framebuffers or window system framebuffers.
  518.  *
  519.  * Also note: ctx->DrawBuffer->Visual.depthBits might not equal
  520.  * ctx->DrawBuffer->Attachment[BUFFER_DEPTH].Renderbuffer.DepthBits.
  521.  * The former one is used to convert floating point depth values into
  522.  * integer Z values.
  523.  */
  524. void
  525. _mesa_update_framebuffer_visual(struct gl_framebuffer *fb)
  526. {
  527.    GLuint i;
  528.  
  529.    memset(&fb->Visual, 0, sizeof(fb->Visual));
  530.    fb->Visual.rgbMode = GL_TRUE; /* assume this */
  531.  
  532. #if 0 /* this _might_ be needed */
  533.    if (fb->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
  534.       /* leave visual fields zero'd */
  535.       return;
  536.    }
  537. #endif
  538.  
  539.    /* find first RGB renderbuffer */
  540.    for (i = 0; i < BUFFER_COUNT; i++) {
  541.       if (fb->Attachment[i].Renderbuffer) {
  542.          const struct gl_renderbuffer *rb = fb->Attachment[i].Renderbuffer;
  543.          const GLenum baseFormat = _mesa_get_format_base_format(rb->Format);
  544.          const gl_format fmt = rb->Format;
  545.          
  546.          if (baseFormat == GL_RGBA || baseFormat == GL_RGB ||
  547.              baseFormat == GL_ALPHA) {
  548.             fb->Visual.redBits = _mesa_get_format_bits(fmt, GL_RED_BITS);
  549.             fb->Visual.greenBits = _mesa_get_format_bits(fmt, GL_GREEN_BITS);
  550.             fb->Visual.blueBits = _mesa_get_format_bits(fmt, GL_BLUE_BITS);
  551.             fb->Visual.alphaBits = _mesa_get_format_bits(fmt, GL_ALPHA_BITS);
  552.             fb->Visual.rgbBits = fb->Visual.redBits
  553.                + fb->Visual.greenBits + fb->Visual.blueBits;
  554.             fb->Visual.floatMode = GL_FALSE;
  555.             fb->Visual.samples = rb->NumSamples;
  556.             break;
  557.          }
  558.       }
  559.    }
  560.  
  561.    if (fb->Attachment[BUFFER_DEPTH].Renderbuffer) {
  562.       const struct gl_renderbuffer *rb =
  563.          fb->Attachment[BUFFER_DEPTH].Renderbuffer;
  564.       const gl_format fmt = rb->Format;
  565.       fb->Visual.haveDepthBuffer = GL_TRUE;
  566.       fb->Visual.depthBits = _mesa_get_format_bits(fmt, GL_DEPTH_BITS);
  567.    }
  568.  
  569.    if (fb->Attachment[BUFFER_STENCIL].Renderbuffer) {
  570.       const struct gl_renderbuffer *rb =
  571.          fb->Attachment[BUFFER_STENCIL].Renderbuffer;
  572.       const gl_format fmt = rb->Format;
  573.       fb->Visual.haveStencilBuffer = GL_TRUE;
  574.       fb->Visual.stencilBits = _mesa_get_format_bits(fmt, GL_STENCIL_BITS);
  575.    }
  576.  
  577.    if (fb->Attachment[BUFFER_ACCUM].Renderbuffer) {
  578.       const struct gl_renderbuffer *rb =
  579.          fb->Attachment[BUFFER_ACCUM].Renderbuffer;
  580.       const gl_format fmt = rb->Format;
  581.       fb->Visual.haveAccumBuffer = GL_TRUE;
  582.       fb->Visual.accumRedBits = _mesa_get_format_bits(fmt, GL_RED_BITS);
  583.       fb->Visual.accumGreenBits = _mesa_get_format_bits(fmt, GL_GREEN_BITS);
  584.       fb->Visual.accumBlueBits = _mesa_get_format_bits(fmt, GL_BLUE_BITS);
  585.       fb->Visual.accumAlphaBits = _mesa_get_format_bits(fmt, GL_ALPHA_BITS);
  586.    }
  587.  
  588.    compute_depth_max(fb);
  589. }
  590.  
  591.  
  592. /**
  593.  * Update the framebuffer's _DepthBuffer field using the renderbuffer
  594.  * found at the given attachment index.
  595.  *
  596.  * If that attachment points to a combined GL_DEPTH_STENCIL renderbuffer,
  597.  * create and install a depth wrapper/adaptor.
  598.  *
  599.  * \param fb  the framebuffer whose _DepthBuffer field to update
  600.  * \param attIndex  indicates the renderbuffer to possibly wrap
  601.  */
  602. void
  603. _mesa_update_depth_buffer(struct gl_context *ctx,
  604.                           struct gl_framebuffer *fb,
  605.                           GLuint attIndex)
  606. {
  607.    struct gl_renderbuffer *depthRb;
  608.  
  609.    /* only one possiblity for now */
  610.    ASSERT(attIndex == BUFFER_DEPTH);
  611.  
  612.    depthRb = fb->Attachment[attIndex].Renderbuffer;
  613.  
  614.    if (depthRb && _mesa_is_format_packed_depth_stencil(depthRb->Format)) {
  615.       /* The attached depth buffer is a GL_DEPTH_STENCIL renderbuffer */
  616.       if (!fb->_DepthBuffer
  617.           || fb->_DepthBuffer->Wrapped != depthRb
  618.           || _mesa_get_format_base_format(fb->_DepthBuffer->Format) != GL_DEPTH_COMPONENT) {
  619.          /* need to update wrapper */
  620.          struct gl_renderbuffer *wrapper
  621.             = _mesa_new_z24_renderbuffer_wrapper(ctx, depthRb);
  622.          _mesa_reference_renderbuffer(&fb->_DepthBuffer, wrapper);
  623.          ASSERT(fb->_DepthBuffer->Wrapped == depthRb);
  624.       }
  625.    }
  626.    else {
  627.       /* depthRb may be null */
  628.       _mesa_reference_renderbuffer(&fb->_DepthBuffer, depthRb);
  629.    }
  630. }
  631.  
  632.  
  633. /**
  634.  * Update the framebuffer's _StencilBuffer field using the renderbuffer
  635.  * found at the given attachment index.
  636.  *
  637.  * If that attachment points to a combined GL_DEPTH_STENCIL renderbuffer,
  638.  * create and install a stencil wrapper/adaptor.
  639.  *
  640.  * \param fb  the framebuffer whose _StencilBuffer field to update
  641.  * \param attIndex  indicates the renderbuffer to possibly wrap
  642.  */
  643. void
  644. _mesa_update_stencil_buffer(struct gl_context *ctx,
  645.                             struct gl_framebuffer *fb,
  646.                             GLuint attIndex)
  647. {
  648.    struct gl_renderbuffer *stencilRb;
  649.  
  650.    ASSERT(attIndex == BUFFER_DEPTH ||
  651.           attIndex == BUFFER_STENCIL);
  652.  
  653.    stencilRb = fb->Attachment[attIndex].Renderbuffer;
  654.  
  655.    if (stencilRb && _mesa_is_format_packed_depth_stencil(stencilRb->Format)) {
  656.       /* The attached stencil buffer is a GL_DEPTH_STENCIL renderbuffer */
  657.       if (!fb->_StencilBuffer
  658.           || fb->_StencilBuffer->Wrapped != stencilRb
  659.           || _mesa_get_format_base_format(fb->_StencilBuffer->Format) != GL_STENCIL_INDEX) {
  660.          /* need to update wrapper */
  661.          struct gl_renderbuffer *wrapper
  662.             = _mesa_new_s8_renderbuffer_wrapper(ctx, stencilRb);
  663.          _mesa_reference_renderbuffer(&fb->_StencilBuffer, wrapper);
  664.          ASSERT(fb->_StencilBuffer->Wrapped == stencilRb);
  665.       }
  666.    }
  667.    else {
  668.       /* stencilRb may be null */
  669.       _mesa_reference_renderbuffer(&fb->_StencilBuffer, stencilRb);
  670.    }
  671. }
  672.  
  673.  
  674. /*
  675.  * Example DrawBuffers scenarios:
  676.  *
  677.  * 1. glDrawBuffer(GL_FRONT_AND_BACK), fixed-func or shader writes to
  678.  * "gl_FragColor" or program writes to the "result.color" register:
  679.  *
  680.  *   fragment color output   renderbuffer
  681.  *   ---------------------   ---------------
  682.  *   color[0]                Front, Back
  683.  *
  684.  *
  685.  * 2. glDrawBuffers(3, [GL_FRONT, GL_AUX0, GL_AUX1]), shader writes to
  686.  * gl_FragData[i] or program writes to result.color[i] registers:
  687.  *
  688.  *   fragment color output   renderbuffer
  689.  *   ---------------------   ---------------
  690.  *   color[0]                Front
  691.  *   color[1]                Aux0
  692.  *   color[3]                Aux1
  693.  *
  694.  *
  695.  * 3. glDrawBuffers(3, [GL_FRONT, GL_AUX0, GL_AUX1]) and shader writes to
  696.  * gl_FragColor, or fixed function:
  697.  *
  698.  *   fragment color output   renderbuffer
  699.  *   ---------------------   ---------------
  700.  *   color[0]                Front, Aux0, Aux1
  701.  *
  702.  *
  703.  * In either case, the list of renderbuffers is stored in the
  704.  * framebuffer->_ColorDrawBuffers[] array and
  705.  * framebuffer->_NumColorDrawBuffers indicates the number of buffers.
  706.  * The renderer (like swrast) has to look at the current fragment shader
  707.  * to see if it writes to gl_FragColor vs. gl_FragData[i] to determine
  708.  * how to map color outputs to renderbuffers.
  709.  *
  710.  * Note that these two calls are equivalent (for fixed function fragment
  711.  * shading anyway):
  712.  *   a)  glDrawBuffer(GL_FRONT_AND_BACK);  (assuming non-stereo framebuffer)
  713.  *   b)  glDrawBuffers(2, [GL_FRONT_LEFT, GL_BACK_LEFT]);
  714.  */
  715.  
  716.  
  717.  
  718.  
  719. /**
  720.  * Update the (derived) list of color drawing renderbuffer pointers.
  721.  * Later, when we're rendering we'll loop from 0 to _NumColorDrawBuffers
  722.  * writing colors.
  723.  */
  724. static void
  725. update_color_draw_buffers(struct gl_context *ctx, struct gl_framebuffer *fb)
  726. {
  727.    GLuint output;
  728.  
  729.    /* set 0th buffer to NULL now in case _NumColorDrawBuffers is zero */
  730.    fb->_ColorDrawBuffers[0] = NULL;
  731.  
  732.    for (output = 0; output < fb->_NumColorDrawBuffers; output++) {
  733.       GLint buf = fb->_ColorDrawBufferIndexes[output];
  734.       if (buf >= 0) {
  735.          fb->_ColorDrawBuffers[output] = fb->Attachment[buf].Renderbuffer;
  736.       }
  737.       else {
  738.          fb->_ColorDrawBuffers[output] = NULL;
  739.       }
  740.    }
  741. }
  742.  
  743.  
  744. /**
  745.  * Update the (derived) color read renderbuffer pointer.
  746.  * Unlike the DrawBuffer, we can only read from one (or zero) color buffers.
  747.  */
  748. static void
  749. update_color_read_buffer(struct gl_context *ctx, struct gl_framebuffer *fb)
  750. {
  751.    (void) ctx;
  752.    if (fb->_ColorReadBufferIndex == -1 ||
  753.        fb->DeletePending ||
  754.        fb->Width == 0 ||
  755.        fb->Height == 0) {
  756.       fb->_ColorReadBuffer = NULL; /* legal! */
  757.    }
  758.    else {
  759.       ASSERT(fb->_ColorReadBufferIndex >= 0);
  760.       ASSERT(fb->_ColorReadBufferIndex < BUFFER_COUNT);
  761.       fb->_ColorReadBuffer
  762.          = fb->Attachment[fb->_ColorReadBufferIndex].Renderbuffer;
  763.    }
  764. }
  765.  
  766.  
  767. /**
  768.  * Update a gl_framebuffer's derived state.
  769.  *
  770.  * Specifically, update these framebuffer fields:
  771.  *    _ColorDrawBuffers
  772.  *    _NumColorDrawBuffers
  773.  *    _ColorReadBuffer
  774.  *    _DepthBuffer
  775.  *    _StencilBuffer
  776.  *
  777.  * If the framebuffer is user-created, make sure it's complete.
  778.  *
  779.  * The following functions (at least) can effect framebuffer state:
  780.  * glReadBuffer, glDrawBuffer, glDrawBuffersARB, glFramebufferRenderbufferEXT,
  781.  * glRenderbufferStorageEXT.
  782.  */
  783. static void
  784. update_framebuffer(struct gl_context *ctx, struct gl_framebuffer *fb)
  785. {
  786.    if (fb->Name == 0) {
  787.       /* This is a window-system framebuffer */
  788.       /* Need to update the FB's GL_DRAW_BUFFER state to match the
  789.        * context state (GL_READ_BUFFER too).
  790.        */
  791.       if (fb->ColorDrawBuffer[0] != ctx->Color.DrawBuffer[0]) {
  792.          _mesa_drawbuffers(ctx, ctx->Const.MaxDrawBuffers,
  793.                            ctx->Color.DrawBuffer, NULL);
  794.       }
  795.       if (fb->ColorReadBuffer != ctx->Pixel.ReadBuffer) {
  796.          
  797.       }
  798.    }
  799.    else {
  800.       /* This is a user-created framebuffer.
  801.        * Completeness only matters for user-created framebuffers.
  802.        */
  803.       if (fb->_Status != GL_FRAMEBUFFER_COMPLETE) {
  804.          _mesa_test_framebuffer_completeness(ctx, fb);
  805.       }
  806.    }
  807.  
  808.    /* Strictly speaking, we don't need to update the draw-state
  809.     * if this FB is bound as ctx->ReadBuffer (and conversely, the
  810.     * read-state if this FB is bound as ctx->DrawBuffer), but no
  811.     * harm.
  812.     */
  813.    update_color_draw_buffers(ctx, fb);
  814.    update_color_read_buffer(ctx, fb);
  815.    _mesa_update_depth_buffer(ctx, fb, BUFFER_DEPTH);
  816.    _mesa_update_stencil_buffer(ctx, fb, BUFFER_STENCIL);
  817.  
  818.    compute_depth_max(fb);
  819. }
  820.  
  821.  
  822. /**
  823.  * Update state related to the current draw/read framebuffers.
  824.  */
  825. void
  826. _mesa_update_framebuffer(struct gl_context *ctx)
  827. {
  828.    struct gl_framebuffer *drawFb;
  829.    struct gl_framebuffer *readFb;
  830.  
  831.    assert(ctx);
  832.    drawFb = ctx->DrawBuffer;
  833.    readFb = ctx->ReadBuffer;
  834.  
  835.    update_framebuffer(ctx, drawFb);
  836.    if (readFb != drawFb)
  837.       update_framebuffer(ctx, readFb);
  838. }
  839.  
  840.  
  841. /**
  842.  * Check if the renderbuffer for a read operation (glReadPixels, glCopyPixels,
  843.  * glCopyTex[Sub]Image, etc) exists.
  844.  * \param format  a basic image format such as GL_RGB, GL_RGBA, GL_ALPHA,
  845.  *                GL_DEPTH_COMPONENT, etc. or GL_COLOR, GL_DEPTH, GL_STENCIL.
  846.  * \return GL_TRUE if buffer exists, GL_FALSE otherwise
  847.  */
  848. GLboolean
  849. _mesa_source_buffer_exists(struct gl_context *ctx, GLenum format)
  850. {
  851.    const struct gl_renderbuffer_attachment *att = ctx->ReadBuffer->Attachment;
  852.  
  853.    /* If we don't know the framebuffer status, update it now */
  854.    if (ctx->ReadBuffer->_Status == 0) {
  855.       _mesa_test_framebuffer_completeness(ctx, ctx->ReadBuffer);
  856.    }
  857.  
  858.    if (ctx->ReadBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
  859.       return GL_FALSE;
  860.    }
  861.  
  862.    switch (format) {
  863.    case GL_COLOR:
  864.    case GL_RED:
  865.    case GL_GREEN:
  866.    case GL_BLUE:
  867.    case GL_ALPHA:
  868.    case GL_LUMINANCE:
  869.    case GL_LUMINANCE_ALPHA:
  870.    case GL_INTENSITY:
  871.    case GL_RG:
  872.    case GL_RGB:
  873.    case GL_BGR:
  874.    case GL_RGBA:
  875.    case GL_BGRA:
  876.    case GL_ABGR_EXT:
  877.    case GL_COLOR_INDEX:
  878.    case GL_RED_INTEGER_EXT:
  879.    case GL_GREEN_INTEGER_EXT:
  880.    case GL_BLUE_INTEGER_EXT:
  881.    case GL_ALPHA_INTEGER_EXT:
  882.    case GL_RGB_INTEGER_EXT:
  883.    case GL_RGBA_INTEGER_EXT:
  884.    case GL_BGR_INTEGER_EXT:
  885.    case GL_BGRA_INTEGER_EXT:
  886.    case GL_LUMINANCE_INTEGER_EXT:
  887.    case GL_LUMINANCE_ALPHA_INTEGER_EXT:
  888.       if (ctx->ReadBuffer->_ColorReadBuffer == NULL) {
  889.          return GL_FALSE;
  890.       }
  891.       ASSERT(_mesa_get_format_bits(ctx->ReadBuffer->_ColorReadBuffer->Format, GL_RED_BITS) > 0 ||
  892.              _mesa_get_format_bits(ctx->ReadBuffer->_ColorReadBuffer->Format, GL_ALPHA_BITS) > 0 ||
  893.              _mesa_get_format_bits(ctx->ReadBuffer->_ColorReadBuffer->Format, GL_INDEX_BITS) > 0);
  894.       break;
  895.    case GL_DEPTH:
  896.    case GL_DEPTH_COMPONENT:
  897.       if (!att[BUFFER_DEPTH].Renderbuffer) {
  898.          return GL_FALSE;
  899.       }
  900.       /*ASSERT(att[BUFFER_DEPTH].Renderbuffer->DepthBits > 0);*/
  901.       break;
  902.    case GL_STENCIL:
  903.    case GL_STENCIL_INDEX:
  904.       if (!att[BUFFER_STENCIL].Renderbuffer) {
  905.          return GL_FALSE;
  906.       }
  907.       /*ASSERT(att[BUFFER_STENCIL].Renderbuffer->StencilBits > 0);*/
  908.       break;
  909.    case GL_DEPTH_STENCIL_EXT:
  910.       if (!att[BUFFER_DEPTH].Renderbuffer ||
  911.           !att[BUFFER_STENCIL].Renderbuffer) {
  912.          return GL_FALSE;
  913.       }
  914.       /*
  915.       ASSERT(att[BUFFER_DEPTH].Renderbuffer->DepthBits > 0);
  916.       ASSERT(att[BUFFER_STENCIL].Renderbuffer->StencilBits > 0);
  917.       */
  918.       break;
  919.    default:
  920.       _mesa_problem(ctx,
  921.                     "Unexpected format 0x%x in _mesa_source_buffer_exists",
  922.                     format);
  923.       return GL_FALSE;
  924.    }
  925.  
  926.    /* OK */
  927.    return GL_TRUE;
  928. }
  929.  
  930.  
  931. /**
  932.  * As above, but for drawing operations.
  933.  * XXX could do some code merging w/ above function.
  934.  */
  935. GLboolean
  936. _mesa_dest_buffer_exists(struct gl_context *ctx, GLenum format)
  937. {
  938.    const struct gl_renderbuffer_attachment *att = ctx->DrawBuffer->Attachment;
  939.  
  940.    /* If we don't know the framebuffer status, update it now */
  941.    if (ctx->DrawBuffer->_Status == 0) {
  942.       _mesa_test_framebuffer_completeness(ctx, ctx->DrawBuffer);
  943.    }
  944.  
  945.    if (ctx->DrawBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
  946.       return GL_FALSE;
  947.    }
  948.  
  949.    switch (format) {
  950.    case GL_COLOR:
  951.    case GL_RED:
  952.    case GL_GREEN:
  953.    case GL_BLUE:
  954.    case GL_ALPHA:
  955.    case GL_LUMINANCE:
  956.    case GL_LUMINANCE_ALPHA:
  957.    case GL_INTENSITY:
  958.    case GL_RGB:
  959.    case GL_BGR:
  960.    case GL_RGBA:
  961.    case GL_BGRA:
  962.    case GL_ABGR_EXT:
  963.    case GL_COLOR_INDEX:
  964.    case GL_RED_INTEGER_EXT:
  965.    case GL_GREEN_INTEGER_EXT:
  966.    case GL_BLUE_INTEGER_EXT:
  967.    case GL_ALPHA_INTEGER_EXT:
  968.    case GL_RGB_INTEGER_EXT:
  969.    case GL_RGBA_INTEGER_EXT:
  970.    case GL_BGR_INTEGER_EXT:
  971.    case GL_BGRA_INTEGER_EXT:
  972.    case GL_LUMINANCE_INTEGER_EXT:
  973.    case GL_LUMINANCE_ALPHA_INTEGER_EXT:
  974.       /* Nothing special since GL_DRAW_BUFFER could be GL_NONE. */
  975.       /* Could assert that colorbuffer has RedBits > 0 */
  976.       break;
  977.    case GL_DEPTH:
  978.    case GL_DEPTH_COMPONENT:
  979.       if (!att[BUFFER_DEPTH].Renderbuffer) {
  980.          return GL_FALSE;
  981.       }
  982.       /*ASSERT(att[BUFFER_DEPTH].Renderbuffer->DepthBits > 0);*/
  983.       break;
  984.    case GL_STENCIL:
  985.    case GL_STENCIL_INDEX:
  986.       if (!att[BUFFER_STENCIL].Renderbuffer) {
  987.          return GL_FALSE;
  988.       }
  989.       /*ASSERT(att[BUFFER_STENCIL].Renderbuffer->StencilBits > 0);*/
  990.       break;
  991.    case GL_DEPTH_STENCIL_EXT:
  992.       if (!att[BUFFER_DEPTH].Renderbuffer ||
  993.           !att[BUFFER_STENCIL].Renderbuffer) {
  994.          return GL_FALSE;
  995.       }
  996.       /*
  997.       ASSERT(att[BUFFER_DEPTH].Renderbuffer->DepthBits > 0);
  998.       ASSERT(att[BUFFER_STENCIL].Renderbuffer->StencilBits > 0);
  999.       */
  1000.       break;
  1001.    default:
  1002.       _mesa_problem(ctx,
  1003.                     "Unexpected format 0x%x in _mesa_dest_buffer_exists",
  1004.                     format);
  1005.       return GL_FALSE;
  1006.    }
  1007.  
  1008.    /* OK */
  1009.    return GL_TRUE;
  1010. }
  1011.  
  1012.  
  1013. /**
  1014.  * Used to answer the GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES query.
  1015.  */
  1016. GLenum
  1017. _mesa_get_color_read_format(struct gl_context *ctx)
  1018. {
  1019.    switch (ctx->ReadBuffer->_ColorReadBuffer->Format) {
  1020.    case MESA_FORMAT_ARGB8888:
  1021.       return GL_BGRA;
  1022.    case MESA_FORMAT_RGB565:
  1023.       return GL_BGR;
  1024.    default:
  1025.       return GL_RGBA;
  1026.    }
  1027. }
  1028.  
  1029.  
  1030. /**
  1031.  * Used to answer the GL_IMPLEMENTATION_COLOR_READ_TYPE_OES query.
  1032.  */
  1033. GLenum
  1034. _mesa_get_color_read_type(struct gl_context *ctx)
  1035. {
  1036.    switch (ctx->ReadBuffer->_ColorReadBuffer->Format) {
  1037.    case MESA_FORMAT_ARGB8888:
  1038.       return GL_UNSIGNED_BYTE;
  1039.    case MESA_FORMAT_RGB565:
  1040.       return GL_UNSIGNED_SHORT_5_6_5_REV;
  1041.    default:
  1042.       return GL_UNSIGNED_BYTE;
  1043.    }
  1044. }
  1045.  
  1046.  
  1047. /**
  1048.  * Print framebuffer info to stderr, for debugging.
  1049.  */
  1050. void
  1051. _mesa_print_framebuffer(const struct gl_framebuffer *fb)
  1052. {
  1053.    GLuint i;
  1054.  
  1055.    fprintf(stderr, "Mesa Framebuffer %u at %p\n", fb->Name, (void *) fb);
  1056.    fprintf(stderr, "  Size: %u x %u  Status: %s\n", fb->Width, fb->Height,
  1057.            _mesa_lookup_enum_by_nr(fb->_Status));
  1058.    fprintf(stderr, "  Attachments:\n");
  1059.  
  1060.    for (i = 0; i < BUFFER_COUNT; i++) {
  1061.       const struct gl_renderbuffer_attachment *att = &fb->Attachment[i];
  1062.       if (att->Type == GL_TEXTURE) {
  1063.          const struct gl_texture_image *texImage;
  1064.          fprintf(stderr,
  1065.                  "  %2d: Texture %u, level %u, face %u, slice %u, complete %d\n",
  1066.                  i, att->Texture->Name, att->TextureLevel, att->CubeMapFace,
  1067.                  att->Zoffset, att->Complete);
  1068.          texImage = att->Texture->Image[att->CubeMapFace][att->TextureLevel];
  1069.          fprintf(stderr, "       Size: %u x %u x %u  Format %s\n",
  1070.                  texImage->Width, texImage->Height, texImage->Depth,
  1071.                  _mesa_get_format_name(texImage->TexFormat));
  1072.       }
  1073.       else if (att->Type == GL_RENDERBUFFER) {
  1074.          fprintf(stderr, "  %2d: Renderbuffer %u, complete %d\n",
  1075.                  i, att->Renderbuffer->Name, att->Complete);
  1076.          fprintf(stderr, "       Size: %u x %u  Format %s\n",
  1077.                  att->Renderbuffer->Width, att->Renderbuffer->Height,
  1078.                  _mesa_get_format_name(att->Renderbuffer->Format));
  1079.       }
  1080.       else {
  1081.          fprintf(stderr, "  %2d: none\n", i);
  1082.       }
  1083.    }
  1084. }
  1085.