Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

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