home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / mesa5.zip / mesa5src.zip / swrast / s_texstore.cpp < prev    next >
C/C++ Source or Header  |  2002-10-24  |  14KB  |  430 lines

  1. /* $Id: s_texstore.c,v 1.9 2002/10/24 23:57:24 brianp Exp $ */
  2.  
  3. /*
  4.  * Mesa 3-D graphics library
  5.  * Version:  4.1
  6.  *
  7.  * Copyright (C) 1999-2002  Brian Paul   All Rights Reserved.
  8.  *
  9.  * Permission is hereby granted, free of charge, to any person obtaining a
  10.  * copy of this software and associated documentation files (the "Software"),
  11.  * to deal in the Software without restriction, including without limitation
  12.  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  13.  * and/or sell copies of the Software, and to permit persons to whom the
  14.  * Software is furnished to do so, subject to the following conditions:
  15.  *
  16.  * The above copyright notice and this permission notice shall be included
  17.  * in all copies or substantial portions of the Software.
  18.  *
  19.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  20.  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  21.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  22.  * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
  23.  * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  24.  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  25.  */
  26.  
  27. /*
  28.  * Authors:
  29.  *   Brian Paul
  30.  */
  31.  
  32.  
  33. /*
  34.  * The functions in this file are mostly related to software texture fallbacks.
  35.  * This includes texture image transfer/packing and texel fetching.
  36.  * Hardware drivers will likely override most of this.
  37.  */
  38.  
  39.  
  40.  
  41. #include "colormac.h"
  42. #include "context.h"
  43. #include "convolve.h"
  44. #include "image.h"
  45. #include "imports.h"
  46. #include "macros.h"
  47. #include "texformat.h"
  48. #include "teximage.h"
  49. #include "texstore.h"
  50.  
  51. #include "s_context.h"
  52. #include "s_depth.h"
  53. #include "s_span.h"
  54.  
  55. /*
  56.  * Read an RGBA image from the frame buffer.
  57.  * This is used by glCopyTex[Sub]Image[12]D().
  58.  * Input:  ctx - the context
  59.  *         x, y - lower left corner
  60.  *         width, height - size of region to read
  61.  * Return: pointer to block of GL_RGBA, GLchan data.
  62.  */
  63. static GLchan *
  64. read_color_image( GLcontext *ctx, GLint x, GLint y,
  65.                   GLsizei width, GLsizei height )
  66. {
  67.    SWcontext *swrast = SWRAST_CONTEXT(ctx);
  68.    GLint stride, i;
  69.    GLchan *image, *dst;
  70.  
  71.    image = (GLchan *) MALLOC(width * height * 4 * sizeof(GLchan));
  72.    if (!image)
  73.       return NULL;
  74.  
  75.    /* Select buffer to read from */
  76.    _swrast_use_read_buffer(ctx);
  77.  
  78.    RENDER_START(swrast,ctx);
  79.  
  80.    dst = image;
  81.    stride = width * 4;
  82.    for (i = 0; i < height; i++) {
  83.       _mesa_read_rgba_span( ctx, ctx->ReadBuffer, width, x, y + i,
  84.                          (GLchan (*)[4]) dst );
  85.       dst += stride;
  86.    }
  87.  
  88.    RENDER_FINISH(swrast,ctx);
  89.  
  90.    /* Read from draw buffer (the default) */
  91.    _swrast_use_draw_buffer(ctx);
  92.  
  93.    return image;
  94. }
  95.  
  96.  
  97. /*
  98.  * As above, but read data from depth buffer.
  99.  */
  100. static GLfloat *
  101. read_depth_image( GLcontext *ctx, GLint x, GLint y,
  102.                   GLsizei width, GLsizei height )
  103. {
  104.    SWcontext *swrast = SWRAST_CONTEXT(ctx);
  105.    GLfloat *image, *dst;
  106.    GLint i;
  107.  
  108.    image = (GLfloat *) MALLOC(width * height * sizeof(GLfloat));
  109.    if (!image)
  110.       return NULL;
  111.  
  112.    RENDER_START(swrast,ctx);
  113.  
  114.    dst = image;
  115.    for (i = 0; i < height; i++) {
  116.       _mesa_read_depth_span_float(ctx, width, x, y + i, dst);
  117.       dst += width;
  118.    }
  119.  
  120.    RENDER_FINISH(swrast,ctx);
  121.  
  122.    return image;
  123. }
  124.  
  125.  
  126.  
  127. static GLboolean
  128. is_depth_format(GLenum format)
  129. {
  130.    switch (format) {
  131.       case GL_DEPTH_COMPONENT:
  132.       case GL_DEPTH_COMPONENT16_SGIX:
  133.       case GL_DEPTH_COMPONENT24_SGIX:
  134.       case GL_DEPTH_COMPONENT32_SGIX:
  135.          return GL_TRUE;
  136.       default:
  137.          return GL_FALSE;
  138.    }
  139. }
  140.  
  141.  
  142. /*
  143.  * Fallback for Driver.CopyTexImage1D().
  144.  */
  145. void
  146. _swrast_copy_teximage1d( GLcontext *ctx, GLenum target, GLint level,
  147.                          GLenum internalFormat,
  148.                          GLint x, GLint y, GLsizei width, GLint border )
  149. {
  150.    struct gl_texture_unit *texUnit;
  151.    struct gl_texture_object *texObj;
  152.    struct gl_texture_image *texImage;
  153.  
  154.    texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
  155.    texObj = _mesa_select_tex_object(ctx, texUnit, target);
  156.    ASSERT(texObj);
  157.    texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
  158.    ASSERT(texImage);
  159.  
  160.    ASSERT(ctx->Driver.TexImage1D);
  161.  
  162.    if (is_depth_format(internalFormat)) {
  163.       /* read depth image from framebuffer */
  164.       GLfloat *image = read_depth_image(ctx, x, y, width, 1);
  165.       if (!image) {
  166.          _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage1D");
  167.          return;
  168.       }
  169.  
  170.       /* call glTexImage1D to redefine the texture */
  171.       (*ctx->Driver.TexImage1D)(ctx, target, level, internalFormat,
  172.                                 width, border,
  173.                                 GL_DEPTH_COMPONENT, GL_FLOAT, image,
  174.                                 &_mesa_native_packing, texObj, texImage);
  175.       FREE(image);
  176.    }
  177.    else {
  178.       /* read RGBA image from framebuffer */
  179.       GLchan *image = read_color_image(ctx, x, y, width, 1);
  180.       if (!image) {
  181.          _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage1D");
  182.          return;
  183.       }
  184.  
  185.       /* call glTexImage1D to redefine the texture */
  186.       (*ctx->Driver.TexImage1D)(ctx, target, level, internalFormat,
  187.                                 width, border,
  188.                                 GL_RGBA, CHAN_TYPE, image,
  189.                                 &_mesa_native_packing, texObj, texImage);
  190.       FREE(image);
  191.    }
  192.  
  193.    /* GL_SGIS_generate_mipmap */
  194.    if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
  195.       _mesa_generate_mipmap(ctx, target, texUnit, texObj);
  196.    }
  197. }
  198.  
  199.  
  200. /*
  201.  * Fallback for Driver.CopyTexImage2D().
  202.  */
  203. void
  204. _swrast_copy_teximage2d( GLcontext *ctx, GLenum target, GLint level,
  205.                          GLenum internalFormat,
  206.                          GLint x, GLint y, GLsizei width, GLsizei height,
  207.                          GLint border )
  208. {
  209.    struct gl_texture_unit *texUnit;
  210.    struct gl_texture_object *texObj;
  211.    struct gl_texture_image *texImage;
  212.  
  213.    texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
  214.    texObj = _mesa_select_tex_object(ctx, texUnit, target);
  215.    ASSERT(texObj);
  216.    texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
  217.    ASSERT(texImage);
  218.  
  219.    ASSERT(ctx->Driver.TexImage2D);
  220.  
  221.    if (is_depth_format(internalFormat)) {
  222.       /* read depth image from framebuffer */
  223.       GLfloat *image = read_depth_image(ctx, x, y, width, height);
  224.       if (!image) {
  225.          _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage2D");
  226.          return;
  227.       }
  228.  
  229.       /* call glTexImage2D to redefine the texture */
  230.       (*ctx->Driver.TexImage2D)(ctx, target, level, internalFormat,
  231.                                 width, height, border,
  232.                                 GL_DEPTH_COMPONENT, GL_FLOAT, image,
  233.                                 &_mesa_native_packing, texObj, texImage);
  234.       FREE(image);
  235.    }
  236.    else {
  237.       /* read RGBA image from framebuffer */
  238.       GLchan *image = read_color_image(ctx, x, y, width, height);
  239.       if (!image) {
  240.          _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage2D");
  241.          return;
  242.       }
  243.  
  244.       /* call glTexImage2D to redefine the texture */
  245.       (*ctx->Driver.TexImage2D)(ctx, target, level, internalFormat,
  246.                                 width, height, border,
  247.                                 GL_RGBA, CHAN_TYPE, image,
  248.                                 &_mesa_native_packing, texObj, texImage);
  249.       FREE(image);
  250.    }
  251.  
  252.    /* GL_SGIS_generate_mipmap */
  253.    if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
  254.       _mesa_generate_mipmap(ctx, target, texUnit, texObj);
  255.    }
  256. }
  257.  
  258.  
  259. /*
  260.  * Fallback for Driver.CopyTexSubImage1D().
  261.  */
  262. void
  263. _swrast_copy_texsubimage1d( GLcontext *ctx, GLenum target, GLint level,
  264.                             GLint xoffset, GLint x, GLint y, GLsizei width )
  265. {
  266.    struct gl_texture_unit *texUnit;
  267.    struct gl_texture_object *texObj;
  268.    struct gl_texture_image *texImage;
  269.  
  270.    texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
  271.    texObj = _mesa_select_tex_object(ctx, texUnit, target);
  272.    ASSERT(texObj);
  273.    texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
  274.    ASSERT(texImage);
  275.  
  276.    ASSERT(ctx->Driver.TexImage1D);
  277.  
  278.    if (texImage->Format == GL_DEPTH_COMPONENT) {
  279.       /* read depth image from framebuffer */
  280.       GLfloat *image = read_depth_image(ctx, x, y, width, 1);
  281.       if (!image) {
  282.          _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexSubImage1D");
  283.          return;
  284.       }
  285.  
  286.       /* call glTexSubImage1D to redefine the texture */
  287.       (*ctx->Driver.TexSubImage1D)(ctx, target, level, xoffset, width,
  288.                                    GL_DEPTH_COMPONENT, GL_FLOAT, image,
  289.                                    &_mesa_native_packing, texObj, texImage);
  290.       FREE(image);
  291.    }
  292.    else {
  293.       /* read RGBA image from framebuffer */
  294.       GLchan *image = read_color_image(ctx, x, y, width, 1);
  295.       if (!image) {
  296.          _mesa_error( ctx, GL_OUT_OF_MEMORY, "glCopyTexSubImage1D" );
  297.          return;
  298.       }
  299.  
  300.       /* now call glTexSubImage1D to do the real work */
  301.       (*ctx->Driver.TexSubImage1D)(ctx, target, level, xoffset, width,
  302.                                    GL_RGBA, CHAN_TYPE, image,
  303.                                    &_mesa_native_packing, texObj, texImage);
  304.       FREE(image);
  305.    }
  306.  
  307.    /* GL_SGIS_generate_mipmap */
  308.    if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
  309.       _mesa_generate_mipmap(ctx, target, texUnit, texObj);
  310.    }
  311. }
  312.  
  313.  
  314. /*
  315.  * Fallback for Driver.CopyTexSubImage2D().
  316.  */
  317. void
  318. _swrast_copy_texsubimage2d( GLcontext *ctx,
  319.                             GLenum target, GLint level,
  320.                             GLint xoffset, GLint yoffset,
  321.                             GLint x, GLint y, GLsizei width, GLsizei height )
  322. {
  323.    struct gl_texture_unit *texUnit;
  324.    struct gl_texture_object *texObj;
  325.    struct gl_texture_image *texImage;
  326.  
  327.    texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
  328.    texObj = _mesa_select_tex_object(ctx, texUnit, target);
  329.    ASSERT(texObj);
  330.    texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
  331.    ASSERT(texImage);
  332.  
  333.    ASSERT(ctx->Driver.TexImage2D);
  334.  
  335.    if (texImage->Format == GL_DEPTH_COMPONENT) {
  336.       /* read depth image from framebuffer */
  337.       GLfloat *image = read_depth_image(ctx, x, y, width, height);
  338.       if (!image) {
  339.          _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexSubImage2D");
  340.          return;
  341.       }
  342.  
  343.       /* call glTexImage1D to redefine the texture */
  344.       (*ctx->Driver.TexSubImage2D)(ctx, target, level,
  345.                                    xoffset, yoffset, width, height,
  346.                                    GL_DEPTH_COMPONENT, GL_FLOAT, image,
  347.                                    &_mesa_native_packing, texObj, texImage);
  348.       FREE(image);
  349.    }
  350.    else {
  351.       /* read RGBA image from framebuffer */
  352.       GLchan *image = read_color_image(ctx, x, y, width, height);
  353.       if (!image) {
  354.          _mesa_error( ctx, GL_OUT_OF_MEMORY, "glCopyTexSubImage2D" );
  355.          return;
  356.       }
  357.  
  358.       /* now call glTexSubImage2D to do the real work */
  359.       (*ctx->Driver.TexSubImage2D)(ctx, target, level,
  360.                                    xoffset, yoffset, width, height,
  361.                                    GL_RGBA, CHAN_TYPE, image,
  362.                                    &_mesa_native_packing, texObj, texImage);
  363.       FREE(image);
  364.    }
  365.  
  366.    /* GL_SGIS_generate_mipmap */
  367.    if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
  368.       _mesa_generate_mipmap(ctx, target, texUnit, texObj);
  369.    }
  370. }
  371.  
  372.  
  373. /*
  374.  * Fallback for Driver.CopyTexSubImage3D().
  375.  */
  376. void
  377. _swrast_copy_texsubimage3d( GLcontext *ctx,
  378.                             GLenum target, GLint level,
  379.                             GLint xoffset, GLint yoffset, GLint zoffset,
  380.                             GLint x, GLint y, GLsizei width, GLsizei height )
  381. {
  382.    struct gl_texture_unit *texUnit;
  383.    struct gl_texture_object *texObj;
  384.    struct gl_texture_image *texImage;
  385.  
  386.    texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
  387.    texObj = _mesa_select_tex_object(ctx, texUnit, target);
  388.    ASSERT(texObj);
  389.    texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
  390.    ASSERT(texImage);
  391.  
  392.    ASSERT(ctx->Driver.TexImage3D);
  393.  
  394.    if (texImage->Format == GL_DEPTH_COMPONENT) {
  395.       /* read depth image from framebuffer */
  396.       GLfloat *image = read_depth_image(ctx, x, y, width, height);
  397.       if (!image) {
  398.          _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexSubImage3D");
  399.          return;
  400.       }
  401.  
  402.       /* call glTexImage1D to redefine the texture */
  403.       (*ctx->Driver.TexSubImage3D)(ctx, target, level,
  404.                                    xoffset, yoffset, zoffset, width, height, 1,
  405.                                    GL_DEPTH_COMPONENT, GL_FLOAT, image,
  406.                                    &_mesa_native_packing, texObj, texImage);
  407.       FREE(image);
  408.    }
  409.    else {
  410.       /* read RGBA image from framebuffer */
  411.       GLchan *image = read_color_image(ctx, x, y, width, height);
  412.       if (!image) {
  413.          _mesa_error( ctx, GL_OUT_OF_MEMORY, "glCopyTexSubImage3D" );
  414.          return;
  415.       }
  416.  
  417.       /* now call glTexSubImage3D to do the real work */
  418.       (*ctx->Driver.TexSubImage3D)(ctx, target, level,
  419.                                    xoffset, yoffset, zoffset, width, height, 1,
  420.                                    GL_RGBA, CHAN_TYPE, image,
  421.                                    &_mesa_native_packing, texObj, texImage);
  422.       FREE(image);
  423.    }
  424.  
  425.    /* GL_SGIS_generate_mipmap */
  426.    if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
  427.       _mesa_generate_mipmap(ctx, target, texUnit, texObj);
  428.    }
  429. }
  430.