Subversion Repositories Kolibri OS

Rev

Go to most recent revision | 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.  
  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.    _glthread_INIT_MUTEX(fb->Mutex);
  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.    _glthread_INIT_MUTEX(fb->Mutex);
  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);
  199.    }
  200. }
  201.  
  202.  
  203. /**
  204.  * Free all the data hanging off the given gl_framebuffer, but don't free
  205.  * the gl_framebuffer object itself.
  206.  */
  207. void
  208. _mesa_free_framebuffer_data(struct gl_framebuffer *fb)
  209. {
  210.    GLuint i;
  211.  
  212.    assert(fb);
  213.    assert(fb->RefCount == 0);
  214.  
  215.    _glthread_DESTROY_MUTEX(fb->Mutex);
  216.  
  217.    for (i = 0; i < BUFFER_COUNT; i++) {
  218.       struct gl_renderbuffer_attachment *att = &fb->Attachment[i];
  219.       if (att->Renderbuffer) {
  220.          _mesa_reference_renderbuffer(&att->Renderbuffer, NULL);
  221.       }
  222.       if (att->Texture) {
  223.          _mesa_reference_texobj(&att->Texture, NULL);
  224.       }
  225.       ASSERT(!att->Renderbuffer);
  226.       ASSERT(!att->Texture);
  227.       att->Type = GL_NONE;
  228.    }
  229. }
  230.  
  231.  
  232. /**
  233.  * Set *ptr to point to fb, with refcounting and locking.
  234.  * This is normally only called from the _mesa_reference_framebuffer() macro
  235.  * when there's a real pointer change.
  236.  */
  237. void
  238. _mesa_reference_framebuffer_(struct gl_framebuffer **ptr,
  239.                              struct gl_framebuffer *fb)
  240. {
  241.    if (*ptr) {
  242.       /* unreference old renderbuffer */
  243.       GLboolean deleteFlag = GL_FALSE;
  244.       struct gl_framebuffer *oldFb = *ptr;
  245.  
  246.       _glthread_LOCK_MUTEX(oldFb->Mutex);
  247.       ASSERT(oldFb->RefCount > 0);
  248.       oldFb->RefCount--;
  249.       deleteFlag = (oldFb->RefCount == 0);
  250.       _glthread_UNLOCK_MUTEX(oldFb->Mutex);
  251.      
  252.       if (deleteFlag)
  253.          oldFb->Delete(oldFb);
  254.  
  255.       *ptr = NULL;
  256.    }
  257.    assert(!*ptr);
  258.  
  259.    if (fb) {
  260.       _glthread_LOCK_MUTEX(fb->Mutex);
  261.       fb->RefCount++;
  262.       _glthread_UNLOCK_MUTEX(fb->Mutex);
  263.       *ptr = fb;
  264.    }
  265. }
  266.  
  267.  
  268. /**
  269.  * Resize the given framebuffer's renderbuffers to the new width and height.
  270.  * This should only be used for window-system framebuffers, not
  271.  * user-created renderbuffers (i.e. made with GL_EXT_framebuffer_object).
  272.  * This will typically be called via ctx->Driver.ResizeBuffers() or directly
  273.  * from a device driver.
  274.  *
  275.  * \note it's possible for ctx to be null since a window can be resized
  276.  * without a currently bound rendering context.
  277.  */
  278. void
  279. _mesa_resize_framebuffer(struct gl_context *ctx, struct gl_framebuffer *fb,
  280.                          GLuint width, GLuint height)
  281. {
  282.    GLuint i;
  283.  
  284.    /* XXX I think we could check if the size is not changing
  285.     * and return early.
  286.     */
  287.  
  288.    /* Can only resize win-sys framebuffer objects */
  289.    assert(_mesa_is_winsys_fbo(fb));
  290.  
  291.    for (i = 0; i < BUFFER_COUNT; i++) {
  292.       struct gl_renderbuffer_attachment *att = &fb->Attachment[i];
  293.       if (att->Type == GL_RENDERBUFFER_EXT && att->Renderbuffer) {
  294.          struct gl_renderbuffer *rb = att->Renderbuffer;
  295.          /* only resize if size is changing */
  296.          if (rb->Width != width || rb->Height != height) {
  297.             if (rb->AllocStorage(ctx, rb, rb->InternalFormat, width, height)) {
  298.                ASSERT(rb->Width == width);
  299.                ASSERT(rb->Height == height);
  300.             }
  301.             else {
  302.                _mesa_error(ctx, GL_OUT_OF_MEMORY, "Resizing framebuffer");
  303.                /* no return */
  304.             }
  305.          }
  306.       }
  307.    }
  308.  
  309.    fb->Width = width;
  310.    fb->Height = height;
  311.  
  312.    if (ctx) {
  313.       /* update scissor / window bounds */
  314.       _mesa_update_draw_buffer_bounds(ctx);
  315.       /* Signal new buffer state so that swrast will update its clipping
  316.        * info (the CLIP_BIT flag).
  317.        */
  318.       ctx->NewState |= _NEW_BUFFERS;
  319.    }
  320. }
  321.  
  322. /**
  323.  * Examine all the framebuffer's renderbuffers to update the Width/Height
  324.  * fields of the framebuffer.  If we have renderbuffers with different
  325.  * sizes, set the framebuffer's width and height to the min size.
  326.  * Note: this is only intended for user-created framebuffers, not
  327.  * window-system framebuffes.
  328.  */
  329. static void
  330. update_framebuffer_size(struct gl_context *ctx, struct gl_framebuffer *fb)
  331. {
  332.    GLuint minWidth = ~0, minHeight = ~0;
  333.    GLuint i;
  334.  
  335.    /* user-created framebuffers only */
  336.    assert(_mesa_is_user_fbo(fb));
  337.  
  338.    for (i = 0; i < BUFFER_COUNT; i++) {
  339.       struct gl_renderbuffer_attachment *att = &fb->Attachment[i];
  340.       const struct gl_renderbuffer *rb = att->Renderbuffer;
  341.       if (rb) {
  342.          minWidth = MIN2(minWidth, rb->Width);
  343.          minHeight = MIN2(minHeight, rb->Height);
  344.       }
  345.    }
  346.  
  347.    if (minWidth != ~0) {
  348.       fb->Width = minWidth;
  349.       fb->Height = minHeight;
  350.    }
  351.    else {
  352.       fb->Width = 0;
  353.       fb->Height = 0;
  354.    }
  355. }
  356.  
  357.  
  358. /**
  359.  * Update the context's current drawing buffer's Xmin, Xmax, Ymin, Ymax fields.
  360.  * These values are computed from the buffer's width and height and
  361.  * the scissor box, if it's enabled.
  362.  * \param ctx  the GL context.
  363.  */
  364. void
  365. _mesa_update_draw_buffer_bounds(struct gl_context *ctx)
  366. {
  367.    struct gl_framebuffer *buffer = ctx->DrawBuffer;
  368.  
  369.    if (!buffer)
  370.       return;
  371.  
  372.    if (_mesa_is_user_fbo(buffer)) {
  373.       /* user-created framebuffer size depends on the renderbuffers */
  374.       update_framebuffer_size(ctx, buffer);
  375.    }
  376.  
  377.    buffer->_Xmin = 0;
  378.    buffer->_Ymin = 0;
  379.    buffer->_Xmax = buffer->Width;
  380.    buffer->_Ymax = buffer->Height;
  381.  
  382.    if (ctx->Scissor.Enabled) {
  383.       if (ctx->Scissor.X > buffer->_Xmin) {
  384.          buffer->_Xmin = ctx->Scissor.X;
  385.       }
  386.       if (ctx->Scissor.Y > buffer->_Ymin) {
  387.          buffer->_Ymin = ctx->Scissor.Y;
  388.       }
  389.       if (ctx->Scissor.X + ctx->Scissor.Width < buffer->_Xmax) {
  390.          buffer->_Xmax = ctx->Scissor.X + ctx->Scissor.Width;
  391.       }
  392.       if (ctx->Scissor.Y + ctx->Scissor.Height < buffer->_Ymax) {
  393.          buffer->_Ymax = ctx->Scissor.Y + ctx->Scissor.Height;
  394.       }
  395.       /* finally, check for empty region */
  396.       if (buffer->_Xmin > buffer->_Xmax) {
  397.          buffer->_Xmin = buffer->_Xmax;
  398.       }
  399.       if (buffer->_Ymin > buffer->_Ymax) {
  400.          buffer->_Ymin = buffer->_Ymax;
  401.       }
  402.    }
  403.  
  404.    ASSERT(buffer->_Xmin <= buffer->_Xmax);
  405.    ASSERT(buffer->_Ymin <= buffer->_Ymax);
  406. }
  407.  
  408.  
  409. /**
  410.  * The glGet queries of the framebuffer red/green/blue size, stencil size,
  411.  * etc. are satisfied by the fields of ctx->DrawBuffer->Visual.  These can
  412.  * change depending on the renderbuffer bindings.  This function updates
  413.  * the given framebuffer's Visual from the current renderbuffer bindings.
  414.  *
  415.  * This may apply to user-created framebuffers or window system framebuffers.
  416.  *
  417.  * Also note: ctx->DrawBuffer->Visual.depthBits might not equal
  418.  * ctx->DrawBuffer->Attachment[BUFFER_DEPTH].Renderbuffer.DepthBits.
  419.  * The former one is used to convert floating point depth values into
  420.  * integer Z values.
  421.  */
  422. void
  423. _mesa_update_framebuffer_visual(struct gl_context *ctx,
  424.                                 struct gl_framebuffer *fb)
  425. {
  426.    GLuint i;
  427.  
  428.    memset(&fb->Visual, 0, sizeof(fb->Visual));
  429.    fb->Visual.rgbMode = GL_TRUE; /* assume this */
  430.  
  431. #if 0 /* this _might_ be needed */
  432.    if (fb->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
  433.       /* leave visual fields zero'd */
  434.       return;
  435.    }
  436. #endif
  437.  
  438.    /* find first RGB renderbuffer */
  439.    for (i = 0; i < BUFFER_COUNT; i++) {
  440.       if (fb->Attachment[i].Renderbuffer) {
  441.          const struct gl_renderbuffer *rb = fb->Attachment[i].Renderbuffer;
  442.          const GLenum baseFormat = _mesa_get_format_base_format(rb->Format);
  443.          const gl_format fmt = rb->Format;
  444.  
  445.          /* Grab samples and sampleBuffers from any attachment point (assuming
  446.           * the framebuffer is complete, we'll get the same answer from all
  447.           * attachments).
  448.           */
  449.          fb->Visual.samples = rb->NumSamples;
  450.          fb->Visual.sampleBuffers = rb->NumSamples > 0 ? 1 : 0;
  451.  
  452.          if (_mesa_is_legal_color_format(ctx, baseFormat)) {
  453.             fb->Visual.redBits = _mesa_get_format_bits(fmt, GL_RED_BITS);
  454.             fb->Visual.greenBits = _mesa_get_format_bits(fmt, GL_GREEN_BITS);
  455.             fb->Visual.blueBits = _mesa_get_format_bits(fmt, GL_BLUE_BITS);
  456.             fb->Visual.alphaBits = _mesa_get_format_bits(fmt, GL_ALPHA_BITS);
  457.             fb->Visual.rgbBits = fb->Visual.redBits
  458.                + fb->Visual.greenBits + fb->Visual.blueBits;
  459.             if (_mesa_get_format_color_encoding(fmt) == GL_SRGB)
  460.                 fb->Visual.sRGBCapable = ctx->Extensions.EXT_framebuffer_sRGB;
  461.             break;
  462.          }
  463.       }
  464.    }
  465.  
  466.    fb->Visual.floatMode = GL_FALSE;
  467.    for (i = 0; i < BUFFER_COUNT; i++) {
  468.       if (fb->Attachment[i].Renderbuffer) {
  469.          const struct gl_renderbuffer *rb = fb->Attachment[i].Renderbuffer;
  470.          const gl_format fmt = rb->Format;
  471.  
  472.          if (_mesa_get_format_datatype(fmt) == GL_FLOAT) {
  473.             fb->Visual.floatMode = GL_TRUE;
  474.             break;
  475.          }
  476.       }
  477.    }
  478.  
  479.    if (fb->Attachment[BUFFER_DEPTH].Renderbuffer) {
  480.       const struct gl_renderbuffer *rb =
  481.          fb->Attachment[BUFFER_DEPTH].Renderbuffer;
  482.       const gl_format fmt = rb->Format;
  483.       fb->Visual.haveDepthBuffer = GL_TRUE;
  484.       fb->Visual.depthBits = _mesa_get_format_bits(fmt, GL_DEPTH_BITS);
  485.    }
  486.  
  487.    if (fb->Attachment[BUFFER_STENCIL].Renderbuffer) {
  488.       const struct gl_renderbuffer *rb =
  489.          fb->Attachment[BUFFER_STENCIL].Renderbuffer;
  490.       const gl_format fmt = rb->Format;
  491.       fb->Visual.haveStencilBuffer = GL_TRUE;
  492.       fb->Visual.stencilBits = _mesa_get_format_bits(fmt, GL_STENCIL_BITS);
  493.    }
  494.  
  495.    if (fb->Attachment[BUFFER_ACCUM].Renderbuffer) {
  496.       const struct gl_renderbuffer *rb =
  497.          fb->Attachment[BUFFER_ACCUM].Renderbuffer;
  498.       const gl_format fmt = rb->Format;
  499.       fb->Visual.haveAccumBuffer = GL_TRUE;
  500.       fb->Visual.accumRedBits = _mesa_get_format_bits(fmt, GL_RED_BITS);
  501.       fb->Visual.accumGreenBits = _mesa_get_format_bits(fmt, GL_GREEN_BITS);
  502.       fb->Visual.accumBlueBits = _mesa_get_format_bits(fmt, GL_BLUE_BITS);
  503.       fb->Visual.accumAlphaBits = _mesa_get_format_bits(fmt, GL_ALPHA_BITS);
  504.    }
  505.  
  506.    compute_depth_max(fb);
  507. }
  508.  
  509.  
  510. /*
  511.  * Example DrawBuffers scenarios:
  512.  *
  513.  * 1. glDrawBuffer(GL_FRONT_AND_BACK), fixed-func or shader writes to
  514.  * "gl_FragColor" or program writes to the "result.color" register:
  515.  *
  516.  *   fragment color output   renderbuffer
  517.  *   ---------------------   ---------------
  518.  *   color[0]                Front, Back
  519.  *
  520.  *
  521.  * 2. glDrawBuffers(3, [GL_FRONT, GL_AUX0, GL_AUX1]), shader writes to
  522.  * gl_FragData[i] or program writes to result.color[i] registers:
  523.  *
  524.  *   fragment color output   renderbuffer
  525.  *   ---------------------   ---------------
  526.  *   color[0]                Front
  527.  *   color[1]                Aux0
  528.  *   color[3]                Aux1
  529.  *
  530.  *
  531.  * 3. glDrawBuffers(3, [GL_FRONT, GL_AUX0, GL_AUX1]) and shader writes to
  532.  * gl_FragColor, or fixed function:
  533.  *
  534.  *   fragment color output   renderbuffer
  535.  *   ---------------------   ---------------
  536.  *   color[0]                Front, Aux0, Aux1
  537.  *
  538.  *
  539.  * In either case, the list of renderbuffers is stored in the
  540.  * framebuffer->_ColorDrawBuffers[] array and
  541.  * framebuffer->_NumColorDrawBuffers indicates the number of buffers.
  542.  * The renderer (like swrast) has to look at the current fragment shader
  543.  * to see if it writes to gl_FragColor vs. gl_FragData[i] to determine
  544.  * how to map color outputs to renderbuffers.
  545.  *
  546.  * Note that these two calls are equivalent (for fixed function fragment
  547.  * shading anyway):
  548.  *   a)  glDrawBuffer(GL_FRONT_AND_BACK);  (assuming non-stereo framebuffer)
  549.  *   b)  glDrawBuffers(2, [GL_FRONT_LEFT, GL_BACK_LEFT]);
  550.  */
  551.  
  552.  
  553.  
  554.  
  555. /**
  556.  * Update the (derived) list of color drawing renderbuffer pointers.
  557.  * Later, when we're rendering we'll loop from 0 to _NumColorDrawBuffers
  558.  * writing colors.
  559.  */
  560. static void
  561. update_color_draw_buffers(struct gl_context *ctx, struct gl_framebuffer *fb)
  562. {
  563.    GLuint output;
  564.  
  565.    /* set 0th buffer to NULL now in case _NumColorDrawBuffers is zero */
  566.    fb->_ColorDrawBuffers[0] = NULL;
  567.  
  568.    for (output = 0; output < fb->_NumColorDrawBuffers; output++) {
  569.       GLint buf = fb->_ColorDrawBufferIndexes[output];
  570.       if (buf >= 0) {
  571.          fb->_ColorDrawBuffers[output] = fb->Attachment[buf].Renderbuffer;
  572.       }
  573.       else {
  574.          fb->_ColorDrawBuffers[output] = NULL;
  575.       }
  576.    }
  577. }
  578.  
  579.  
  580. /**
  581.  * Update the (derived) color read renderbuffer pointer.
  582.  * Unlike the DrawBuffer, we can only read from one (or zero) color buffers.
  583.  */
  584. static void
  585. update_color_read_buffer(struct gl_context *ctx, struct gl_framebuffer *fb)
  586. {
  587.    (void) ctx;
  588.    if (fb->_ColorReadBufferIndex == -1 ||
  589.        fb->DeletePending ||
  590.        fb->Width == 0 ||
  591.        fb->Height == 0) {
  592.       fb->_ColorReadBuffer = NULL; /* legal! */
  593.    }
  594.    else {
  595.       ASSERT(fb->_ColorReadBufferIndex >= 0);
  596.       ASSERT(fb->_ColorReadBufferIndex < BUFFER_COUNT);
  597.       fb->_ColorReadBuffer
  598.          = fb->Attachment[fb->_ColorReadBufferIndex].Renderbuffer;
  599.    }
  600. }
  601.  
  602.  
  603. /**
  604.  * Update a gl_framebuffer's derived state.
  605.  *
  606.  * Specifically, update these framebuffer fields:
  607.  *    _ColorDrawBuffers
  608.  *    _NumColorDrawBuffers
  609.  *    _ColorReadBuffer
  610.  *
  611.  * If the framebuffer is user-created, make sure it's complete.
  612.  *
  613.  * The following functions (at least) can effect framebuffer state:
  614.  * glReadBuffer, glDrawBuffer, glDrawBuffersARB, glFramebufferRenderbufferEXT,
  615.  * glRenderbufferStorageEXT.
  616.  */
  617. static void
  618. update_framebuffer(struct gl_context *ctx, struct gl_framebuffer *fb)
  619. {
  620.    if (_mesa_is_winsys_fbo(fb)) {
  621.       /* This is a window-system framebuffer */
  622.       /* Need to update the FB's GL_DRAW_BUFFER state to match the
  623.        * context state (GL_READ_BUFFER too).
  624.        */
  625.       if (fb->ColorDrawBuffer[0] != ctx->Color.DrawBuffer[0]) {
  626.          _mesa_drawbuffers(ctx, ctx->Const.MaxDrawBuffers,
  627.                            ctx->Color.DrawBuffer, NULL);
  628.       }
  629.    }
  630.    else {
  631.       /* This is a user-created framebuffer.
  632.        * Completeness only matters for user-created framebuffers.
  633.        */
  634.       if (fb->_Status != GL_FRAMEBUFFER_COMPLETE) {
  635.          _mesa_test_framebuffer_completeness(ctx, fb);
  636.       }
  637.    }
  638.  
  639.    /* Strictly speaking, we don't need to update the draw-state
  640.     * if this FB is bound as ctx->ReadBuffer (and conversely, the
  641.     * read-state if this FB is bound as ctx->DrawBuffer), but no
  642.     * harm.
  643.     */
  644.    update_color_draw_buffers(ctx, fb);
  645.    update_color_read_buffer(ctx, fb);
  646.  
  647.    compute_depth_max(fb);
  648. }
  649.  
  650.  
  651. /**
  652.  * Update state related to the current draw/read framebuffers.
  653.  */
  654. void
  655. _mesa_update_framebuffer(struct gl_context *ctx)
  656. {
  657.    struct gl_framebuffer *drawFb;
  658.    struct gl_framebuffer *readFb;
  659.  
  660.    assert(ctx);
  661.    drawFb = ctx->DrawBuffer;
  662.    readFb = ctx->ReadBuffer;
  663.  
  664.    update_framebuffer(ctx, drawFb);
  665.    if (readFb != drawFb)
  666.       update_framebuffer(ctx, readFb);
  667.  
  668.    _mesa_update_clamp_vertex_color(ctx);
  669.    _mesa_update_clamp_fragment_color(ctx);
  670. }
  671.  
  672.  
  673. /**
  674.  * Check if the renderbuffer for a read/draw operation exists.
  675.  * \param format  a basic image format such as GL_RGB, GL_RGBA, GL_ALPHA,
  676.  *                GL_DEPTH_COMPONENT, etc. or GL_COLOR, GL_DEPTH, GL_STENCIL.
  677.  * \param reading  if TRUE, we're going to read from the buffer,
  678.                    if FALSE, we're going to write to the buffer.
  679.  * \return GL_TRUE if buffer exists, GL_FALSE otherwise
  680.  */
  681. static GLboolean
  682. renderbuffer_exists(struct gl_context *ctx,
  683.                     struct gl_framebuffer *fb,
  684.                     GLenum format,
  685.                     GLboolean reading)
  686. {
  687.    const struct gl_renderbuffer_attachment *att = fb->Attachment;
  688.  
  689.    /* If we don't know the framebuffer status, update it now */
  690.    if (fb->_Status == 0) {
  691.       _mesa_test_framebuffer_completeness(ctx, fb);
  692.    }
  693.  
  694.    if (fb->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
  695.       return GL_FALSE;
  696.    }
  697.  
  698.    switch (format) {
  699.    case GL_COLOR:
  700.    case GL_RED:
  701.    case GL_GREEN:
  702.    case GL_BLUE:
  703.    case GL_ALPHA:
  704.    case GL_LUMINANCE:
  705.    case GL_LUMINANCE_ALPHA:
  706.    case GL_INTENSITY:
  707.    case GL_RG:
  708.    case GL_RGB:
  709.    case GL_BGR:
  710.    case GL_RGBA:
  711.    case GL_BGRA:
  712.    case GL_ABGR_EXT:
  713.    case GL_RED_INTEGER_EXT:
  714.    case GL_RG_INTEGER:
  715.    case GL_GREEN_INTEGER_EXT:
  716.    case GL_BLUE_INTEGER_EXT:
  717.    case GL_ALPHA_INTEGER_EXT:
  718.    case GL_RGB_INTEGER_EXT:
  719.    case GL_RGBA_INTEGER_EXT:
  720.    case GL_BGR_INTEGER_EXT:
  721.    case GL_BGRA_INTEGER_EXT:
  722.    case GL_LUMINANCE_INTEGER_EXT:
  723.    case GL_LUMINANCE_ALPHA_INTEGER_EXT:
  724.       if (reading) {
  725.          /* about to read from a color buffer */
  726.          const struct gl_renderbuffer *readBuf = fb->_ColorReadBuffer;
  727.          if (!readBuf) {
  728.             return GL_FALSE;
  729.          }
  730.          ASSERT(_mesa_get_format_bits(readBuf->Format, GL_RED_BITS) > 0 ||
  731.                 _mesa_get_format_bits(readBuf->Format, GL_ALPHA_BITS) > 0 ||
  732.                 _mesa_get_format_bits(readBuf->Format, GL_TEXTURE_LUMINANCE_SIZE) > 0 ||
  733.                 _mesa_get_format_bits(readBuf->Format, GL_TEXTURE_INTENSITY_SIZE) > 0 ||
  734.                 _mesa_get_format_bits(readBuf->Format, GL_INDEX_BITS) > 0);
  735.       }
  736.       else {
  737.          /* about to draw to zero or more color buffers (none is OK) */
  738.          return GL_TRUE;
  739.       }
  740.       break;
  741.    case GL_DEPTH:
  742.    case GL_DEPTH_COMPONENT:
  743.       if (att[BUFFER_DEPTH].Type == GL_NONE) {
  744.          return GL_FALSE;
  745.       }
  746.       break;
  747.    case GL_STENCIL:
  748.    case GL_STENCIL_INDEX:
  749.       if (att[BUFFER_STENCIL].Type == GL_NONE) {
  750.          return GL_FALSE;
  751.       }
  752.       break;
  753.    case GL_DEPTH_STENCIL_EXT:
  754.       if (att[BUFFER_DEPTH].Type == GL_NONE ||
  755.           att[BUFFER_STENCIL].Type == GL_NONE) {
  756.          return GL_FALSE;
  757.       }
  758.       break;
  759.    default:
  760.       _mesa_problem(ctx,
  761.                     "Unexpected format 0x%x in renderbuffer_exists",
  762.                     format);
  763.       return GL_FALSE;
  764.    }
  765.  
  766.    /* OK */
  767.    return GL_TRUE;
  768. }
  769.  
  770.  
  771. /**
  772.  * Check if the renderbuffer for a read operation (glReadPixels, glCopyPixels,
  773.  * glCopyTex[Sub]Image, etc) exists.
  774.  * \param format  a basic image format such as GL_RGB, GL_RGBA, GL_ALPHA,
  775.  *                GL_DEPTH_COMPONENT, etc. or GL_COLOR, GL_DEPTH, GL_STENCIL.
  776.  * \return GL_TRUE if buffer exists, GL_FALSE otherwise
  777.  */
  778. GLboolean
  779. _mesa_source_buffer_exists(struct gl_context *ctx, GLenum format)
  780. {
  781.    return renderbuffer_exists(ctx, ctx->ReadBuffer, format, GL_TRUE);
  782. }
  783.  
  784.  
  785. /**
  786.  * As above, but for drawing operations.
  787.  */
  788. GLboolean
  789. _mesa_dest_buffer_exists(struct gl_context *ctx, GLenum format)
  790. {
  791.    return renderbuffer_exists(ctx, ctx->DrawBuffer, format, GL_FALSE);
  792. }
  793.  
  794.  
  795. /**
  796.  * Used to answer the GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES query.
  797.  */
  798. GLenum
  799. _mesa_get_color_read_format(struct gl_context *ctx)
  800. {
  801.    if (!ctx->ReadBuffer || !ctx->ReadBuffer->_ColorReadBuffer) {
  802.       /* The spec is unclear how to handle this case, but NVIDIA's
  803.        * driver generates GL_INVALID_OPERATION.
  804.        */
  805.       _mesa_error(ctx, GL_INVALID_OPERATION,
  806.                   "glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_FORMAT: "
  807.                   "no GL_READ_BUFFER)");
  808.       return GL_NONE;
  809.    }
  810.    else {
  811.       const GLenum format = ctx->ReadBuffer->_ColorReadBuffer->Format;
  812.       const GLenum data_type = _mesa_get_format_datatype(format);
  813.  
  814.       if (format == MESA_FORMAT_ARGB8888)
  815.          return GL_BGRA;
  816.       else if (format == MESA_FORMAT_RGB565)
  817.          return GL_BGR;
  818.  
  819.       switch (data_type) {
  820.       case GL_UNSIGNED_INT:
  821.       case GL_INT:
  822.          return GL_RGBA_INTEGER;
  823.       default:
  824.          return GL_RGBA;
  825.       }
  826.    }
  827. }
  828.  
  829.  
  830. /**
  831.  * Used to answer the GL_IMPLEMENTATION_COLOR_READ_TYPE_OES query.
  832.  */
  833. GLenum
  834. _mesa_get_color_read_type(struct gl_context *ctx)
  835. {
  836.    if (!ctx->ReadBuffer || !ctx->ReadBuffer->_ColorReadBuffer) {
  837.       /* The spec is unclear how to handle this case, but NVIDIA's
  838.        * driver generates GL_INVALID_OPERATION.
  839.        */
  840.       _mesa_error(ctx, GL_INVALID_OPERATION,
  841.                   "glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_TYPE: "
  842.                   "no GL_READ_BUFFER)");
  843.       return GL_NONE;
  844.    }
  845.    else {
  846.       const GLenum format = ctx->ReadBuffer->_ColorReadBuffer->Format;
  847.       const GLenum data_type = _mesa_get_format_datatype(format);
  848.  
  849.       if (format == MESA_FORMAT_RGB565)
  850.          return GL_UNSIGNED_SHORT_5_6_5_REV;
  851.  
  852.       switch (data_type) {
  853.       case GL_SIGNED_NORMALIZED:
  854.          return GL_BYTE;
  855.       case GL_UNSIGNED_INT:
  856.       case GL_INT:
  857.       case GL_FLOAT:
  858.          return data_type;
  859.       case GL_UNSIGNED_NORMALIZED:
  860.       default:
  861.          return GL_UNSIGNED_BYTE;
  862.       }
  863.    }
  864. }
  865.  
  866.  
  867. /**
  868.  * Returns the read renderbuffer for the specified format.
  869.  */
  870. struct gl_renderbuffer *
  871. _mesa_get_read_renderbuffer_for_format(const struct gl_context *ctx,
  872.                                        GLenum format)
  873. {
  874.    const struct gl_framebuffer *rfb = ctx->ReadBuffer;
  875.  
  876.    if (_mesa_is_color_format(format)) {
  877.       return rfb->Attachment[rfb->_ColorReadBufferIndex].Renderbuffer;
  878.    } else if (_mesa_is_depth_format(format) ||
  879.               _mesa_is_depthstencil_format(format)) {
  880.       return rfb->Attachment[BUFFER_DEPTH].Renderbuffer;
  881.    } else {
  882.       return rfb->Attachment[BUFFER_STENCIL].Renderbuffer;
  883.    }
  884. }
  885.  
  886.  
  887. /**
  888.  * Print framebuffer info to stderr, for debugging.
  889.  */
  890. void
  891. _mesa_print_framebuffer(const struct gl_framebuffer *fb)
  892. {
  893.    GLuint i;
  894.  
  895.    fprintf(stderr, "Mesa Framebuffer %u at %p\n", fb->Name, (void *) fb);
  896.    fprintf(stderr, "  Size: %u x %u  Status: %s\n", fb->Width, fb->Height,
  897.            _mesa_lookup_enum_by_nr(fb->_Status));
  898.    fprintf(stderr, "  Attachments:\n");
  899.  
  900.    for (i = 0; i < BUFFER_COUNT; i++) {
  901.       const struct gl_renderbuffer_attachment *att = &fb->Attachment[i];
  902.       if (att->Type == GL_TEXTURE) {
  903.          const struct gl_texture_image *texImage = att->Renderbuffer->TexImage;
  904.          fprintf(stderr,
  905.                  "  %2d: Texture %u, level %u, face %u, slice %u, complete %d\n",
  906.                  i, att->Texture->Name, att->TextureLevel, att->CubeMapFace,
  907.                  att->Zoffset, att->Complete);
  908.          fprintf(stderr, "       Size: %u x %u x %u  Format %s\n",
  909.                  texImage->Width, texImage->Height, texImage->Depth,
  910.                  _mesa_get_format_name(texImage->TexFormat));
  911.       }
  912.       else if (att->Type == GL_RENDERBUFFER) {
  913.          fprintf(stderr, "  %2d: Renderbuffer %u, complete %d\n",
  914.                  i, att->Renderbuffer->Name, att->Complete);
  915.          fprintf(stderr, "       Size: %u x %u  Format %s\n",
  916.                  att->Renderbuffer->Width, att->Renderbuffer->Height,
  917.                  _mesa_get_format_name(att->Renderbuffer->Format));
  918.       }
  919.       else {
  920.          fprintf(stderr, "  %2d: none\n", i);
  921.       }
  922.    }
  923. }
  924.