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-2006  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 software-based renderbuffers.
  28.  * Also, routines for reading/writing software-based renderbuffer data as
  29.  * ubytes, ushorts, uints, etc.
  30.  */
  31.  
  32.  
  33. #include "main/glheader.h"
  34. #include "main/imports.h"
  35. #include "main/context.h"
  36. #include "main/fbobject.h"
  37. #include "main/formats.h"
  38. #include "main/mtypes.h"
  39. #include "main/renderbuffer.h"
  40. #include "swrast/s_context.h"
  41. #include "swrast/s_renderbuffer.h"
  42.  
  43.  
  44. /**
  45.  * This is a software fallback for the gl_renderbuffer->AllocStorage
  46.  * function.
  47.  * Device drivers will typically override this function for the buffers
  48.  * which it manages (typically color buffers, Z and stencil).
  49.  * Other buffers (like software accumulation and aux buffers) which the driver
  50.  * doesn't manage can be handled with this function.
  51.  *
  52.  * This one multi-purpose function can allocate stencil, depth, accum, color
  53.  * or color-index buffers!
  54.  */
  55. static GLboolean
  56. soft_renderbuffer_storage(struct gl_context *ctx, struct gl_renderbuffer *rb,
  57.                           GLenum internalFormat,
  58.                           GLuint width, GLuint height)
  59. {
  60.    struct swrast_renderbuffer *srb = swrast_renderbuffer(rb);
  61.    GLuint bpp;
  62.  
  63.    switch (internalFormat) {
  64.    case GL_RGB:
  65.    case GL_R3_G3_B2:
  66.    case GL_RGB4:
  67.    case GL_RGB5:
  68.    case GL_RGB8:
  69.    case GL_RGB10:
  70.    case GL_RGB12:
  71.    case GL_RGB16:
  72.       rb->Format = MESA_FORMAT_RGB888;
  73.       break;
  74.    case GL_RGBA:
  75.    case GL_RGBA2:
  76.    case GL_RGBA4:
  77.    case GL_RGB5_A1:
  78.    case GL_RGBA8:
  79. #if 1
  80.    case GL_RGB10_A2:
  81.    case GL_RGBA12:
  82. #endif
  83.       if (_mesa_little_endian())
  84.          rb->Format = MESA_FORMAT_RGBA8888_REV;
  85.       else
  86.          rb->Format = MESA_FORMAT_RGBA8888;
  87.       break;
  88.    case GL_RGBA16:
  89.    case GL_RGBA16_SNORM:
  90.       /* for accum buffer */
  91.       rb->Format = MESA_FORMAT_SIGNED_RGBA_16;
  92.       break;
  93.    case GL_STENCIL_INDEX:
  94.    case GL_STENCIL_INDEX1_EXT:
  95.    case GL_STENCIL_INDEX4_EXT:
  96.    case GL_STENCIL_INDEX8_EXT:
  97.    case GL_STENCIL_INDEX16_EXT:
  98.       rb->Format = MESA_FORMAT_S8;
  99.       break;
  100.    case GL_DEPTH_COMPONENT:
  101.    case GL_DEPTH_COMPONENT16:
  102.       rb->Format = MESA_FORMAT_Z16;
  103.       break;
  104.    case GL_DEPTH_COMPONENT24:
  105.       rb->Format = MESA_FORMAT_X8_Z24;
  106.       break;
  107.    case GL_DEPTH_COMPONENT32:
  108.       rb->Format = MESA_FORMAT_Z32;
  109.       break;
  110.    case GL_DEPTH_STENCIL_EXT:
  111.    case GL_DEPTH24_STENCIL8_EXT:
  112.       rb->Format = MESA_FORMAT_Z24_S8;
  113.       break;
  114.    default:
  115.       /* unsupported format */
  116.       return GL_FALSE;
  117.    }
  118.  
  119.    bpp = _mesa_get_format_bytes(rb->Format);
  120.  
  121.    /* free old buffer storage */
  122.    free(srb->Buffer);
  123.    srb->Buffer = NULL;
  124.  
  125.    srb->RowStride = width * bpp;
  126.  
  127.    if (width > 0 && height > 0) {
  128.       /* allocate new buffer storage */
  129.       srb->Buffer = malloc(srb->RowStride * height);
  130.  
  131.       if (srb->Buffer == NULL) {
  132.          rb->Width = 0;
  133.          rb->Height = 0;
  134.          _mesa_error(ctx, GL_OUT_OF_MEMORY,
  135.                      "software renderbuffer allocation (%d x %d x %d)",
  136.                      width, height, bpp);
  137.          return GL_FALSE;
  138.       }
  139.    }
  140.  
  141.    rb->Width = width;
  142.    rb->Height = height;
  143.    rb->_BaseFormat = _mesa_base_fbo_format(ctx, internalFormat);
  144.  
  145.    if (rb->Name == 0 &&
  146.        internalFormat == GL_RGBA16_SNORM &&
  147.        rb->_BaseFormat == 0) {
  148.       /* NOTE: This is a special case just for accumulation buffers.
  149.        * This is a very limited use case- there's no snorm texturing or
  150.        * rendering going on.
  151.        */
  152.       rb->_BaseFormat = GL_RGBA;
  153.    }
  154.    else {
  155.       /* the internalFormat should have been error checked long ago */
  156.       ASSERT(rb->_BaseFormat);
  157.    }
  158.  
  159.    return GL_TRUE;
  160. }
  161.  
  162.  
  163. /**
  164.  * Called via gl_renderbuffer::Delete()
  165.  */
  166. static void
  167. soft_renderbuffer_delete(struct gl_context *ctx, struct gl_renderbuffer *rb)
  168. {
  169.    struct swrast_renderbuffer *srb = swrast_renderbuffer(rb);
  170.  
  171.    free(srb->Buffer);
  172.    srb->Buffer = NULL;
  173.    _mesa_delete_renderbuffer(ctx, rb);
  174. }
  175.  
  176.  
  177. void
  178. _swrast_map_soft_renderbuffer(struct gl_context *ctx,
  179.                               struct gl_renderbuffer *rb,
  180.                               GLuint x, GLuint y, GLuint w, GLuint h,
  181.                               GLbitfield mode,
  182.                               GLubyte **out_map,
  183.                               GLint *out_stride)
  184. {
  185.    struct swrast_renderbuffer *srb = swrast_renderbuffer(rb);
  186.    GLubyte *map = srb->Buffer;
  187.    int cpp = _mesa_get_format_bytes(rb->Format);
  188.    int stride = rb->Width * cpp;
  189.  
  190.    if (!map) {
  191.       *out_map = NULL;
  192.       *out_stride = 0;
  193.    }
  194.  
  195.    map += y * stride;
  196.    map += x * cpp;
  197.  
  198.    *out_map = map;
  199.    *out_stride = stride;
  200. }
  201.  
  202.  
  203. void
  204. _swrast_unmap_soft_renderbuffer(struct gl_context *ctx,
  205.                                 struct gl_renderbuffer *rb)
  206. {
  207. }
  208.  
  209.  
  210.  
  211. /**
  212.  * Allocate a software-based renderbuffer.  This is called via the
  213.  * ctx->Driver.NewRenderbuffer() function when the user creates a new
  214.  * renderbuffer.
  215.  * This would not be used for hardware-based renderbuffers.
  216.  */
  217. struct gl_renderbuffer *
  218. _swrast_new_soft_renderbuffer(struct gl_context *ctx, GLuint name)
  219. {
  220.    struct swrast_renderbuffer *srb = CALLOC_STRUCT(swrast_renderbuffer);
  221.    if (srb) {
  222.       _mesa_init_renderbuffer(&srb->Base, name);
  223.       srb->Base.AllocStorage = soft_renderbuffer_storage;
  224.       srb->Base.Delete = soft_renderbuffer_delete;
  225.    }
  226.    return &srb->Base;
  227. }
  228.  
  229.  
  230. /**
  231.  * Add software-based color renderbuffers to the given framebuffer.
  232.  * This is a helper routine for device drivers when creating a
  233.  * window system framebuffer (not a user-created render/framebuffer).
  234.  * Once this function is called, you can basically forget about this
  235.  * renderbuffer; core Mesa will handle all the buffer management and
  236.  * rendering!
  237.  */
  238. static GLboolean
  239. add_color_renderbuffers(struct gl_context *ctx, struct gl_framebuffer *fb,
  240.                         GLuint rgbBits, GLuint alphaBits,
  241.                         GLboolean frontLeft, GLboolean backLeft,
  242.                         GLboolean frontRight, GLboolean backRight)
  243. {
  244.    gl_buffer_index b;
  245.  
  246.    if (rgbBits > 16 || alphaBits > 16) {
  247.       _mesa_problem(ctx,
  248.                     "Unsupported bit depth in add_color_renderbuffers");
  249.       return GL_FALSE;
  250.    }
  251.  
  252.    assert(MAX_COLOR_ATTACHMENTS >= 4);
  253.  
  254.    for (b = BUFFER_FRONT_LEFT; b <= BUFFER_BACK_RIGHT; b++) {
  255.       struct gl_renderbuffer *rb;
  256.  
  257.       if (b == BUFFER_FRONT_LEFT && !frontLeft)
  258.          continue;
  259.       else if (b == BUFFER_BACK_LEFT && !backLeft)
  260.          continue;
  261.       else if (b == BUFFER_FRONT_RIGHT && !frontRight)
  262.          continue;
  263.       else if (b == BUFFER_BACK_RIGHT && !backRight)
  264.          continue;
  265.  
  266.       assert(fb->Attachment[b].Renderbuffer == NULL);
  267.  
  268.       rb = ctx->Driver.NewRenderbuffer(ctx, 0);
  269.       if (!rb) {
  270.          _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating color buffer");
  271.          return GL_FALSE;
  272.       }
  273.  
  274.       rb->InternalFormat = GL_RGBA;
  275.  
  276.       rb->AllocStorage = soft_renderbuffer_storage;
  277.       _mesa_add_renderbuffer(fb, b, rb);
  278.    }
  279.  
  280.    return GL_TRUE;
  281. }
  282.  
  283.  
  284. /**
  285.  * Add a software-based depth renderbuffer to the given framebuffer.
  286.  * This is a helper routine for device drivers when creating a
  287.  * window system framebuffer (not a user-created render/framebuffer).
  288.  * Once this function is called, you can basically forget about this
  289.  * renderbuffer; core Mesa will handle all the buffer management and
  290.  * rendering!
  291.  */
  292. static GLboolean
  293. add_depth_renderbuffer(struct gl_context *ctx, struct gl_framebuffer *fb,
  294.                        GLuint depthBits)
  295. {
  296.    struct gl_renderbuffer *rb;
  297.  
  298.    if (depthBits > 32) {
  299.       _mesa_problem(ctx,
  300.                     "Unsupported depthBits in add_depth_renderbuffer");
  301.       return GL_FALSE;
  302.    }
  303.  
  304.    assert(fb->Attachment[BUFFER_DEPTH].Renderbuffer == NULL);
  305.  
  306.    rb = _swrast_new_soft_renderbuffer(ctx, 0);
  307.    if (!rb) {
  308.       _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating depth buffer");
  309.       return GL_FALSE;
  310.    }
  311.  
  312.    if (depthBits <= 16) {
  313.       rb->InternalFormat = GL_DEPTH_COMPONENT16;
  314.    }
  315.    else if (depthBits <= 24) {
  316.       rb->InternalFormat = GL_DEPTH_COMPONENT24;
  317.    }
  318.    else {
  319.       rb->InternalFormat = GL_DEPTH_COMPONENT32;
  320.    }
  321.  
  322.    rb->AllocStorage = soft_renderbuffer_storage;
  323.    _mesa_add_renderbuffer(fb, BUFFER_DEPTH, rb);
  324.  
  325.    return GL_TRUE;
  326. }
  327.  
  328.  
  329. /**
  330.  * Add a software-based stencil renderbuffer to the given framebuffer.
  331.  * This is a helper routine for device drivers when creating a
  332.  * window system framebuffer (not a user-created render/framebuffer).
  333.  * Once this function is called, you can basically forget about this
  334.  * renderbuffer; core Mesa will handle all the buffer management and
  335.  * rendering!
  336.  */
  337. static GLboolean
  338. add_stencil_renderbuffer(struct gl_context *ctx, struct gl_framebuffer *fb,
  339.                          GLuint stencilBits)
  340. {
  341.    struct gl_renderbuffer *rb;
  342.  
  343.    if (stencilBits > 16) {
  344.       _mesa_problem(ctx,
  345.                   "Unsupported stencilBits in add_stencil_renderbuffer");
  346.       return GL_FALSE;
  347.    }
  348.  
  349.    assert(fb->Attachment[BUFFER_STENCIL].Renderbuffer == NULL);
  350.  
  351.    rb = _swrast_new_soft_renderbuffer(ctx, 0);
  352.    if (!rb) {
  353.       _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating stencil buffer");
  354.       return GL_FALSE;
  355.    }
  356.  
  357.    assert(stencilBits <= 8);
  358.    rb->InternalFormat = GL_STENCIL_INDEX8;
  359.  
  360.    rb->AllocStorage = soft_renderbuffer_storage;
  361.    _mesa_add_renderbuffer(fb, BUFFER_STENCIL, rb);
  362.  
  363.    return GL_TRUE;
  364. }
  365.  
  366.  
  367. static GLboolean
  368. add_depth_stencil_renderbuffer(struct gl_context *ctx,
  369.                                struct gl_framebuffer *fb)
  370. {
  371.    struct gl_renderbuffer *rb;
  372.  
  373.    assert(fb->Attachment[BUFFER_DEPTH].Renderbuffer == NULL);
  374.    assert(fb->Attachment[BUFFER_STENCIL].Renderbuffer == NULL);
  375.  
  376.    rb = _swrast_new_soft_renderbuffer(ctx, 0);
  377.    if (!rb) {
  378.       _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating depth+stencil buffer");
  379.       return GL_FALSE;
  380.    }
  381.  
  382.    rb->InternalFormat = GL_DEPTH_STENCIL;
  383.  
  384.    rb->AllocStorage = soft_renderbuffer_storage;
  385.    _mesa_add_renderbuffer(fb, BUFFER_DEPTH, rb);
  386.    _mesa_add_renderbuffer(fb, BUFFER_STENCIL, rb);
  387.  
  388.    return GL_TRUE;
  389. }
  390.  
  391.  
  392. /**
  393.  * Add a software-based accumulation renderbuffer to the given framebuffer.
  394.  * This is a helper routine for device drivers when creating a
  395.  * window system framebuffer (not a user-created render/framebuffer).
  396.  * Once this function is called, you can basically forget about this
  397.  * renderbuffer; core Mesa will handle all the buffer management and
  398.  * rendering!
  399.  */
  400. static GLboolean
  401. add_accum_renderbuffer(struct gl_context *ctx, struct gl_framebuffer *fb,
  402.                        GLuint redBits, GLuint greenBits,
  403.                        GLuint blueBits, GLuint alphaBits)
  404. {
  405.    struct gl_renderbuffer *rb;
  406.  
  407.    if (redBits > 16 || greenBits > 16 || blueBits > 16 || alphaBits > 16) {
  408.       _mesa_problem(ctx,
  409.                     "Unsupported accumBits in add_accum_renderbuffer");
  410.       return GL_FALSE;
  411.    }
  412.  
  413.    assert(fb->Attachment[BUFFER_ACCUM].Renderbuffer == NULL);
  414.  
  415.    rb = _swrast_new_soft_renderbuffer(ctx, 0);
  416.    if (!rb) {
  417.       _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating accum buffer");
  418.       return GL_FALSE;
  419.    }
  420.  
  421.    rb->InternalFormat = GL_RGBA16_SNORM;
  422.    rb->AllocStorage = soft_renderbuffer_storage;
  423.    _mesa_add_renderbuffer(fb, BUFFER_ACCUM, rb);
  424.  
  425.    return GL_TRUE;
  426. }
  427.  
  428.  
  429.  
  430. /**
  431.  * Add a software-based aux renderbuffer to the given framebuffer.
  432.  * This is a helper routine for device drivers when creating a
  433.  * window system framebuffer (not a user-created render/framebuffer).
  434.  * Once this function is called, you can basically forget about this
  435.  * renderbuffer; core Mesa will handle all the buffer management and
  436.  * rendering!
  437.  *
  438.  * NOTE: color-index aux buffers not supported.
  439.  */
  440. static GLboolean
  441. add_aux_renderbuffers(struct gl_context *ctx, struct gl_framebuffer *fb,
  442.                       GLuint colorBits, GLuint numBuffers)
  443. {
  444.    GLuint i;
  445.  
  446.    if (colorBits > 16) {
  447.       _mesa_problem(ctx,
  448.                     "Unsupported colorBits in add_aux_renderbuffers");
  449.       return GL_FALSE;
  450.    }
  451.  
  452.    assert(numBuffers <= MAX_AUX_BUFFERS);
  453.  
  454.    for (i = 0; i < numBuffers; i++) {
  455.       struct gl_renderbuffer *rb = _swrast_new_soft_renderbuffer(ctx, 0);
  456.  
  457.       assert(fb->Attachment[BUFFER_AUX0 + i].Renderbuffer == NULL);
  458.  
  459.       if (!rb) {
  460.          _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating aux buffer");
  461.          return GL_FALSE;
  462.       }
  463.  
  464.       assert (colorBits <= 8);
  465.       rb->InternalFormat = GL_RGBA;
  466.  
  467.       rb->AllocStorage = soft_renderbuffer_storage;
  468.       _mesa_add_renderbuffer(fb, BUFFER_AUX0 + i, rb);
  469.    }
  470.    return GL_TRUE;
  471. }
  472.  
  473.  
  474. /**
  475.  * Create/attach software-based renderbuffers to the given framebuffer.
  476.  * This is a helper routine for device drivers.  Drivers can just as well
  477.  * call the individual _mesa_add_*_renderbuffer() routines directly.
  478.  */
  479. void
  480. _swrast_add_soft_renderbuffers(struct gl_framebuffer *fb,
  481.                                GLboolean color,
  482.                                GLboolean depth,
  483.                                GLboolean stencil,
  484.                                GLboolean accum,
  485.                                GLboolean alpha,
  486.                                GLboolean aux)
  487. {
  488.    GLboolean frontLeft = GL_TRUE;
  489.    GLboolean backLeft = fb->Visual.doubleBufferMode;
  490.    GLboolean frontRight = fb->Visual.stereoMode;
  491.    GLboolean backRight = fb->Visual.stereoMode && fb->Visual.doubleBufferMode;
  492.  
  493.    if (color) {
  494.       assert(fb->Visual.redBits == fb->Visual.greenBits);
  495.       assert(fb->Visual.redBits == fb->Visual.blueBits);
  496.       add_color_renderbuffers(NULL, fb,
  497.                               fb->Visual.redBits,
  498.                               fb->Visual.alphaBits,
  499.                               frontLeft, backLeft,
  500.                               frontRight, backRight);
  501.    }
  502.  
  503. #if 0
  504.    /* This is pretty much for debugging purposes only since there's a perf
  505.     * hit for using combined depth/stencil in swrast.
  506.     */
  507.    if (depth && fb->Visual.depthBits == 24 &&
  508.        stencil && fb->Visual.stencilBits == 8) {
  509.       /* use combined depth/stencil buffer */
  510.       add_depth_stencil_renderbuffer(NULL, fb);
  511.    }
  512.    else
  513. #else
  514.    (void) add_depth_stencil_renderbuffer;
  515. #endif
  516.    {
  517.       if (depth) {
  518.          assert(fb->Visual.depthBits > 0);
  519.          add_depth_renderbuffer(NULL, fb, fb->Visual.depthBits);
  520.       }
  521.  
  522.       if (stencil) {
  523.          assert(fb->Visual.stencilBits > 0);
  524.          add_stencil_renderbuffer(NULL, fb, fb->Visual.stencilBits);
  525.       }
  526.    }
  527.  
  528.    if (accum) {
  529.       assert(fb->Visual.accumRedBits > 0);
  530.       assert(fb->Visual.accumGreenBits > 0);
  531.       assert(fb->Visual.accumBlueBits > 0);
  532.       add_accum_renderbuffer(NULL, fb,
  533.                              fb->Visual.accumRedBits,
  534.                              fb->Visual.accumGreenBits,
  535.                              fb->Visual.accumBlueBits,
  536.                              fb->Visual.accumAlphaBits);
  537.    }
  538.  
  539.    if (aux) {
  540.       assert(fb->Visual.numAuxBuffers > 0);
  541.       add_aux_renderbuffers(NULL, fb, fb->Visual.redBits,
  542.                             fb->Visual.numAuxBuffers);
  543.    }
  544.  
  545. #if 0
  546.    if (multisample) {
  547.       /* maybe someday */
  548.    }
  549. #endif
  550. }
  551.  
  552.  
  553.  
  554. static void
  555. map_attachment(struct gl_context *ctx,
  556.                  struct gl_framebuffer *fb,
  557.                  gl_buffer_index buffer)
  558. {
  559.    struct gl_texture_object *texObj = fb->Attachment[buffer].Texture;
  560.    struct gl_renderbuffer *rb = fb->Attachment[buffer].Renderbuffer;
  561.    struct swrast_renderbuffer *srb = swrast_renderbuffer(rb);
  562.  
  563.    if (texObj) {
  564.       /* map texture image (render to texture) */
  565.       const GLuint level = fb->Attachment[buffer].TextureLevel;
  566.       const GLuint face = fb->Attachment[buffer].CubeMapFace;
  567.       const GLuint slice = fb->Attachment[buffer].Zoffset;
  568.       struct gl_texture_image *texImage = texObj->Image[face][level];
  569.       if (texImage) {
  570.          ctx->Driver.MapTextureImage(ctx, texImage, slice,
  571.                                      0, 0, texImage->Width, texImage->Height,
  572.                                      GL_MAP_READ_BIT | GL_MAP_WRITE_BIT,
  573.                                      &srb->Map, &srb->RowStride);
  574.       }
  575.    }
  576.    else if (rb) {
  577.       /* Map ordinary renderbuffer */
  578.       ctx->Driver.MapRenderbuffer(ctx, rb,
  579.                                   0, 0, rb->Width, rb->Height,
  580.                                   GL_MAP_READ_BIT | GL_MAP_WRITE_BIT,
  581.                                   &srb->Map, &srb->RowStride);
  582.    }
  583.  
  584.    assert(srb->Map);
  585. }
  586.  
  587.  
  588. static void
  589. unmap_attachment(struct gl_context *ctx,
  590.                    struct gl_framebuffer *fb,
  591.                    gl_buffer_index buffer)
  592. {
  593.    struct gl_texture_object *texObj = fb->Attachment[buffer].Texture;
  594.    struct gl_renderbuffer *rb = fb->Attachment[buffer].Renderbuffer;
  595.    struct swrast_renderbuffer *srb = swrast_renderbuffer(rb);
  596.  
  597.    if (texObj) {
  598.       /* unmap texture image (render to texture) */
  599.       const GLuint level = fb->Attachment[buffer].TextureLevel;
  600.       const GLuint face = fb->Attachment[buffer].CubeMapFace;
  601.       const GLuint slice = fb->Attachment[buffer].Zoffset;
  602.       struct gl_texture_image *texImage = texObj->Image[face][level];
  603.       if (texImage) {
  604.          ctx->Driver.UnmapTextureImage(ctx, texImage, slice);
  605.       }
  606.    }
  607.    else if (rb) {
  608.       /* unmap ordinary renderbuffer */
  609.       ctx->Driver.UnmapRenderbuffer(ctx, rb);
  610.    }
  611.  
  612.    srb->Map = NULL;
  613. }
  614.  
  615.  
  616. /**
  617.  * Determine what type to use (ubyte vs. float) for span colors for the
  618.  * given renderbuffer.
  619.  * See also _swrast_write_rgba_span().
  620.  */
  621. static void
  622. find_renderbuffer_colortype(struct gl_renderbuffer *rb)
  623. {
  624.    struct swrast_renderbuffer *srb = swrast_renderbuffer(rb);
  625.    GLuint rbMaxBits = _mesa_get_format_max_bits(rb->Format);
  626.    GLenum rbDatatype = _mesa_get_format_datatype(rb->Format);
  627.  
  628.    if (rbDatatype == GL_UNSIGNED_NORMALIZED && rbMaxBits <= 8) {
  629.       /* the buffer's values fit in GLubyte values */
  630.       srb->ColorType = GL_UNSIGNED_BYTE;
  631.    }
  632.    else {
  633.       /* use floats otherwise */
  634.       srb->ColorType = GL_FLOAT;
  635.    }
  636. }
  637.  
  638.  
  639. /**
  640.  * Map the renderbuffers we'll use for tri/line/point rendering.
  641.  */
  642. void
  643. _swrast_map_renderbuffers(struct gl_context *ctx)
  644. {
  645.    struct gl_framebuffer *fb = ctx->DrawBuffer;
  646.    struct gl_renderbuffer *depthRb, *stencilRb;
  647.    GLuint buf;
  648.  
  649.    depthRb = fb->Attachment[BUFFER_DEPTH].Renderbuffer;
  650.    if (depthRb) {
  651.       /* map depth buffer */
  652.       map_attachment(ctx, fb, BUFFER_DEPTH);
  653.    }
  654.  
  655.    stencilRb = fb->Attachment[BUFFER_STENCIL].Renderbuffer;
  656.    if (stencilRb && stencilRb != depthRb) {
  657.       /* map stencil buffer */
  658.       map_attachment(ctx, fb, BUFFER_STENCIL);
  659.    }
  660.  
  661.    for (buf = 0; buf < fb->_NumColorDrawBuffers; buf++) {
  662.       map_attachment(ctx, fb, fb->_ColorDrawBufferIndexes[buf]);
  663.       find_renderbuffer_colortype(fb->_ColorDrawBuffers[buf]);
  664.    }
  665. }
  666.  
  667.  
  668. /**
  669.  * Unmap renderbuffers after rendering.
  670.  */
  671. void
  672. _swrast_unmap_renderbuffers(struct gl_context *ctx)
  673. {
  674.    struct gl_framebuffer *fb = ctx->DrawBuffer;
  675.    struct gl_renderbuffer *depthRb, *stencilRb;
  676.    GLuint buf;
  677.  
  678.    depthRb = fb->Attachment[BUFFER_DEPTH].Renderbuffer;
  679.    if (depthRb) {
  680.       /* map depth buffer */
  681.       unmap_attachment(ctx, fb, BUFFER_DEPTH);
  682.    }
  683.  
  684.    stencilRb = fb->Attachment[BUFFER_STENCIL].Renderbuffer;
  685.    if (stencilRb && stencilRb != depthRb) {
  686.       /* map stencil buffer */
  687.       unmap_attachment(ctx, fb, BUFFER_STENCIL);
  688.    }
  689.  
  690.    for (buf = 0; buf < fb->_NumColorDrawBuffers; buf++) {
  691.       unmap_attachment(ctx, fb, fb->_ColorDrawBufferIndexes[buf]);
  692.    }
  693. }
  694.