Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * Mesa 3-D graphics library
  3.  *
  4.  * Copyright (C) 2011 VMware, Inc.
  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.  * Functions for mapping/unmapping texture images.
  27.  */
  28.  
  29.  
  30. #include "main/context.h"
  31. #include "main/fbobject.h"
  32. #include "main/teximage.h"
  33. #include "main/texobj.h"
  34. #include "swrast/swrast.h"
  35. #include "swrast/s_context.h"
  36.  
  37.  
  38. /**
  39.  * Allocate a new swrast_texture_image (a subclass of gl_texture_image).
  40.  * Called via ctx->Driver.NewTextureImage().
  41.  */
  42. struct gl_texture_image *
  43. _swrast_new_texture_image( struct gl_context *ctx )
  44. {
  45.    (void) ctx;
  46.    return (struct gl_texture_image *) CALLOC_STRUCT(swrast_texture_image);
  47. }
  48.  
  49.  
  50. /**
  51.  * Free a swrast_texture_image (a subclass of gl_texture_image).
  52.  * Called via ctx->Driver.DeleteTextureImage().
  53.  */
  54. void
  55. _swrast_delete_texture_image(struct gl_context *ctx,
  56.                              struct gl_texture_image *texImage)
  57. {
  58.    /* Nothing special for the subclass yet */
  59.    _mesa_delete_texture_image(ctx, texImage);
  60. }
  61.  
  62. static unsigned int
  63. texture_slices(struct gl_texture_image *texImage)
  64. {
  65.    if (texImage->TexObject->Target == GL_TEXTURE_1D_ARRAY)
  66.       return texImage->Height;
  67.    else
  68.       return texImage->Depth;
  69. }
  70.  
  71. unsigned int
  72. _swrast_teximage_slice_height(struct gl_texture_image *texImage)
  73. {
  74.    /* For 1D array textures, the slices are all 1 pixel high, and Height is
  75.     * the number of slices.
  76.     */
  77.    if (texImage->TexObject->Target == GL_TEXTURE_1D_ARRAY)
  78.       return 1;
  79.    else
  80.       return texImage->Height;
  81. }
  82.  
  83. /**
  84.  * Called via ctx->Driver.AllocTextureImageBuffer()
  85.  */
  86. GLboolean
  87. _swrast_alloc_texture_image_buffer(struct gl_context *ctx,
  88.                                    struct gl_texture_image *texImage)
  89. {
  90.    struct swrast_texture_image *swImg = swrast_texture_image(texImage);
  91.    GLuint bytesPerSlice;
  92.    GLuint slices = texture_slices(texImage);
  93.    GLuint i;
  94.  
  95.    if (!_swrast_init_texture_image(texImage))
  96.       return GL_FALSE;
  97.  
  98.    bytesPerSlice = _mesa_format_image_size(texImage->TexFormat, texImage->Width,
  99.                                            _swrast_teximage_slice_height(texImage), 1);
  100.  
  101.    assert(!swImg->Buffer);
  102.    swImg->Buffer = _mesa_align_malloc(bytesPerSlice * slices, 512);
  103.    if (!swImg->Buffer)
  104.       return GL_FALSE;
  105.  
  106.    /* RowStride and ImageSlices[] describe how to address texels in 'Data' */
  107.    swImg->RowStride = _mesa_format_row_stride(texImage->TexFormat,
  108.                                               texImage->Width);
  109.  
  110.    for (i = 0; i < slices; i++) {
  111.       swImg->ImageSlices[i] = swImg->Buffer + bytesPerSlice * i;
  112.    }
  113.  
  114.    return GL_TRUE;
  115. }
  116.  
  117.  
  118. /**
  119.  * Code that overrides ctx->Driver.AllocTextureImageBuffer may use this to
  120.  * initialize the fields of swrast_texture_image without allocating the image
  121.  * buffer or initializing RowStride or the contents of ImageSlices.
  122.  *
  123.  * Returns GL_TRUE on success, GL_FALSE on memory allocation failure.
  124.  */
  125. GLboolean
  126. _swrast_init_texture_image(struct gl_texture_image *texImage)
  127. {
  128.    struct swrast_texture_image *swImg = swrast_texture_image(texImage);
  129.  
  130.    if ((texImage->Width == 1 || _mesa_is_pow_two(texImage->Width2)) &&
  131.        (texImage->Height == 1 || _mesa_is_pow_two(texImage->Height2)) &&
  132.        (texImage->Depth == 1 || _mesa_is_pow_two(texImage->Depth2)))
  133.       swImg->_IsPowerOfTwo = GL_TRUE;
  134.    else
  135.       swImg->_IsPowerOfTwo = GL_FALSE;
  136.  
  137.    /* Compute Width/Height/DepthScale for mipmap lod computation */
  138.    if (texImage->TexObject->Target == GL_TEXTURE_RECTANGLE_NV) {
  139.       /* scale = 1.0 since texture coords directly map to texels */
  140.       swImg->WidthScale = 1.0;
  141.       swImg->HeightScale = 1.0;
  142.       swImg->DepthScale = 1.0;
  143.    }
  144.    else {
  145.       swImg->WidthScale = (GLfloat) texImage->Width;
  146.       swImg->HeightScale = (GLfloat) texImage->Height;
  147.       swImg->DepthScale = (GLfloat) texImage->Depth;
  148.    }
  149.  
  150.    assert(!swImg->ImageSlices);
  151.    swImg->ImageSlices = calloc(texture_slices(texImage), sizeof(void *));
  152.    if (!swImg->ImageSlices)
  153.       return GL_FALSE;
  154.  
  155.    return GL_TRUE;
  156. }
  157.  
  158.  
  159. /**
  160.  * Called via ctx->Driver.FreeTextureImageBuffer()
  161.  */
  162. void
  163. _swrast_free_texture_image_buffer(struct gl_context *ctx,
  164.                                   struct gl_texture_image *texImage)
  165. {
  166.    struct swrast_texture_image *swImage = swrast_texture_image(texImage);
  167.  
  168.    _mesa_align_free(swImage->Buffer);
  169.    swImage->Buffer = NULL;
  170.  
  171.    free(swImage->ImageSlices);
  172.    swImage->ImageSlices = NULL;
  173. }
  174.  
  175.  
  176. /**
  177.  * Error checking for debugging only.
  178.  */
  179. static void
  180. check_map_teximage(const struct gl_texture_image *texImage,
  181.                    GLuint slice, GLuint x, GLuint y, GLuint w, GLuint h)
  182. {
  183.  
  184.    if (texImage->TexObject->Target == GL_TEXTURE_1D)
  185.       assert(y == 0 && h == 1);
  186.  
  187.    assert(x < texImage->Width || texImage->Width == 0);
  188.    assert(y < texImage->Height || texImage->Height == 0);
  189.    assert(x + w <= texImage->Width);
  190.    assert(y + h <= texImage->Height);
  191. }
  192.  
  193. /**
  194.  * Map a 2D slice of a texture image into user space.
  195.  * (x,y,w,h) defines a region of interest (ROI).  Reading/writing texels
  196.  * outside of the ROI is undefined.
  197.  *
  198.  * \param texImage  the texture image
  199.  * \param slice  the 3D image slice or array texture slice
  200.  * \param x, y, w, h  region of interest
  201.  * \param mode  bitmask of GL_MAP_READ_BIT, GL_MAP_WRITE_BIT
  202.  * \param mapOut  returns start of mapping of region of interest
  203.  * \param rowStrideOut  returns row stride (in bytes)
  204.  */
  205. void
  206. _swrast_map_teximage(struct gl_context *ctx,
  207.                      struct gl_texture_image *texImage,
  208.                      GLuint slice,
  209.                      GLuint x, GLuint y, GLuint w, GLuint h,
  210.                      GLbitfield mode,
  211.                      GLubyte **mapOut,
  212.                      GLint *rowStrideOut)
  213. {
  214.    struct swrast_texture_image *swImage = swrast_texture_image(texImage);
  215.    GLubyte *map;
  216.    GLint stride, texelSize;
  217.    GLuint bw, bh;
  218.  
  219.    check_map_teximage(texImage, slice, x, y, w, h);
  220.  
  221.    if (!swImage->Buffer) {
  222.       /* Either glTexImage was called with a NULL <pixels> argument or
  223.        * we ran out of memory when allocating texture memory,
  224.        */
  225.       *mapOut = NULL;
  226.       *rowStrideOut = 0;
  227.       return;
  228.    }
  229.  
  230.    texelSize = _mesa_get_format_bytes(texImage->TexFormat);
  231.    stride = _mesa_format_row_stride(texImage->TexFormat, texImage->Width);
  232.    _mesa_get_format_block_size(texImage->TexFormat, &bw, &bh);
  233.  
  234.    assert(x % bw == 0);
  235.    assert(y % bh == 0);
  236.  
  237.    /* This function can only be used with a swrast-allocated buffer, in which
  238.     * case ImageSlices is populated with pointers into Buffer.
  239.     */
  240.    assert(swImage->Buffer);
  241.    assert(swImage->Buffer == swImage->ImageSlices[0]);
  242.  
  243.    assert(slice < texture_slices(texImage));
  244.    map = swImage->ImageSlices[slice];
  245.  
  246.    /* apply x/y offset to map address */
  247.    map += stride * (y / bh) + texelSize * (x / bw);
  248.  
  249.    *mapOut = map;
  250.    *rowStrideOut = stride;
  251. }
  252.  
  253. void
  254. _swrast_unmap_teximage(struct gl_context *ctx,
  255.                        struct gl_texture_image *texImage,
  256.                        GLuint slice)
  257. {
  258.    /* nop */
  259. }
  260.  
  261.  
  262. void
  263. _swrast_map_texture(struct gl_context *ctx, struct gl_texture_object *texObj)
  264. {
  265.    const GLuint faces = _mesa_num_tex_faces(texObj->Target);
  266.    GLuint face, level;
  267.  
  268.    for (face = 0; face < faces; face++) {
  269.       for (level = texObj->BaseLevel; level < MAX_TEXTURE_LEVELS; level++) {
  270.          struct gl_texture_image *texImage = texObj->Image[face][level];
  271.          struct swrast_texture_image *swImage = swrast_texture_image(texImage);
  272.          unsigned int i, slices;
  273.  
  274.          if (!texImage)
  275.             continue;
  276.  
  277.          /* In the case of a swrast-allocated texture buffer, the ImageSlices
  278.           * and RowStride are always available.
  279.           */
  280.          if (swImage->Buffer) {
  281.             assert(swImage->ImageSlices[0] == swImage->Buffer);
  282.             continue;
  283.          }
  284.  
  285.          if (!swImage->ImageSlices) {
  286.             swImage->ImageSlices =
  287.                calloc(texture_slices(texImage), sizeof(void *));
  288.             if (!swImage->ImageSlices)
  289.                continue;
  290.          }
  291.  
  292.          slices = texture_slices(texImage);
  293.  
  294.          for (i = 0; i < slices; i++) {
  295.             GLubyte *map;
  296.             GLint rowStride;
  297.  
  298.             if (swImage->ImageSlices[i])
  299.                continue;
  300.  
  301.             ctx->Driver.MapTextureImage(ctx, texImage, i,
  302.                                         0, 0,
  303.                                         texImage->Width, texImage->Height,
  304.                                         GL_MAP_READ_BIT | GL_MAP_WRITE_BIT,
  305.                                         &map, &rowStride);
  306.  
  307.             swImage->ImageSlices[i] = map;
  308.             /* A swrast-using driver has to return the same rowstride for
  309.              * every slice of the same texture, since we don't track them
  310.              * separately.
  311.              */
  312.             if (i == 0)
  313.                swImage->RowStride = rowStride;
  314.             else
  315.                assert(swImage->RowStride == rowStride);
  316.          }
  317.       }
  318.    }
  319. }
  320.  
  321.  
  322. void
  323. _swrast_unmap_texture(struct gl_context *ctx, struct gl_texture_object *texObj)
  324. {
  325.    const GLuint faces = _mesa_num_tex_faces(texObj->Target);
  326.    GLuint face, level;
  327.  
  328.    for (face = 0; face < faces; face++) {
  329.       for (level = texObj->BaseLevel; level < MAX_TEXTURE_LEVELS; level++) {
  330.          struct gl_texture_image *texImage = texObj->Image[face][level];
  331.          struct swrast_texture_image *swImage = swrast_texture_image(texImage);
  332.          unsigned int i, slices;
  333.  
  334.          if (!texImage)
  335.             continue;
  336.  
  337.          if (swImage->Buffer)
  338.             return;
  339.  
  340.          if (!swImage->ImageSlices)
  341.             continue;
  342.  
  343.          slices = texture_slices(texImage);
  344.  
  345.          for (i = 0; i < slices; i++) {
  346.             if (swImage->ImageSlices[i]) {
  347.                ctx->Driver.UnmapTextureImage(ctx, texImage, i);
  348.                swImage->ImageSlices[i] = NULL;
  349.             }
  350.          }
  351.       }
  352.    }
  353. }
  354.  
  355.  
  356. /**
  357.  * Map all textures for reading prior to software rendering.
  358.  */
  359. void
  360. _swrast_map_textures(struct gl_context *ctx)
  361. {
  362.    int unit;
  363.  
  364.    for (unit = 0; unit <= ctx->Texture._MaxEnabledTexImageUnit; unit++) {
  365.       struct gl_texture_object *texObj = ctx->Texture.Unit[unit]._Current;
  366.  
  367.       if (texObj)
  368.          _swrast_map_texture(ctx, texObj);
  369.    }
  370. }
  371.  
  372.  
  373. /**
  374.  * Unmap all textures for reading prior to software rendering.
  375.  */
  376. void
  377. _swrast_unmap_textures(struct gl_context *ctx)
  378. {
  379.    int unit;
  380.    for (unit = 0; unit <= ctx->Texture._MaxEnabledTexImageUnit; unit++) {
  381.       struct gl_texture_object *texObj = ctx->Texture.Unit[unit]._Current;
  382.  
  383.       if (texObj)
  384.          _swrast_unmap_texture(ctx, texObj);
  385.    }
  386. }
  387.