mesa: consolidate internal glCompressedTexSubImage1/2/3D code
[mesa.git] / src / mesa / state_tracker / st_cb_texture.c
index ad4f23c7eb8de43ca7511c7fea9528b697641574..9d1b7f672f5dc6917844119563986db0600097b6 100644 (file)
@@ -137,15 +137,7 @@ st_DeleteTextureObject(struct gl_context *ctx,
    if (stObj->pt)
       pipe_resource_reference(&stObj->pt, NULL);
    if (stObj->sampler_view) {
-      if (stObj->sampler_view->context != st->pipe) {
-         /* Take "ownership" of this texture sampler view by setting
-          * its context pointer to this context.  This avoids potential
-          * crashes when the texture object is shared among contexts
-          * and the original/owner context has already been destroyed.
-          */
-         stObj->sampler_view->context = st->pipe;
-      }
-      pipe_sampler_view_reference(&stObj->sampler_view, NULL);
+      pipe_sampler_view_release(st->pipe, &stObj->sampler_view);
    }
    _mesa_delete_texture_object(ctx, texObj);
 }
@@ -189,6 +181,8 @@ st_MapTextureImage(struct gl_context *ctx,
       pipeMode |= PIPE_TRANSFER_READ;
    if (mode & GL_MAP_WRITE_BIT)
       pipeMode |= PIPE_TRANSFER_WRITE;
+   if (mode & GL_MAP_INVALIDATE_RANGE_BIT)
+      pipeMode |= PIPE_TRANSFER_DISCARD_RANGE;
 
    map = st_texture_image_map(st, stImage, slice, pipeMode, x, y, w, h);
    if (map) {
@@ -406,6 +400,8 @@ guess_and_alloc_texture(struct st_context *st,
                                  ptLayers,
                                  bindings);
 
+   stObj->lastLevel = lastLevel;
+
    DBG("%s returning %d\n", __FUNCTION__, (stObj->pt != NULL));
 
    return stObj->pt != NULL;
@@ -448,7 +444,7 @@ st_AllocTextureImageBuffer(struct gl_context *ctx,
    /* The parent texture object does not have space for this image */
 
    pipe_resource_reference(&stObj->pt, NULL);
-   pipe_sampler_view_reference(&stObj->sampler_view, NULL);
+   pipe_sampler_view_release(st->pipe, &stObj->sampler_view);
 
    if (!guess_and_alloc_texture(st, stObj, stImage)) {
       /* Probably out of memory.
@@ -534,62 +530,31 @@ prep_teximage(struct gl_context *ctx, struct gl_texture_image *texImage,
 
 
 static void
-st_TexImage3D(struct gl_context * ctx,
-              struct gl_texture_image *texImage,
-              GLint internalFormat,
-              GLint width, GLint height, GLint depth,
-              GLint border,
-              GLenum format, GLenum type, const void *pixels,
-              const struct gl_pixelstore_attrib *unpack)
+st_TexImage(struct gl_context * ctx, GLuint dims,
+            struct gl_texture_image *texImage,
+            GLint internalFormat,
+            GLint width, GLint height, GLint depth, GLint border,
+            GLenum format, GLenum type, const void *pixels,
+            const struct gl_pixelstore_attrib *unpack)
 {
    prep_teximage(ctx, texImage, internalFormat, width, height, depth, border,
                  format, type);
-   _mesa_store_teximage3d(ctx, texImage, internalFormat, width, height, depth,
-                          border, format, type, pixels, unpack);
-}
-
-
-static void
-st_TexImage2D(struct gl_context * ctx,
-              struct gl_texture_image *texImage,
-              GLint internalFormat,
-              GLint width, GLint height, GLint border,
-              GLenum format, GLenum type, const void *pixels,
-              const struct gl_pixelstore_attrib *unpack)
-{
-   prep_teximage(ctx, texImage, internalFormat, width, height, 1, border,
-                 format, type);
-   _mesa_store_teximage2d(ctx, texImage, internalFormat, width, height,
-                          border, format, type, pixels, unpack);
-}
-
-
-static void
-st_TexImage1D(struct gl_context * ctx,
-              struct gl_texture_image *texImage,
-              GLint internalFormat,
-              GLint width, GLint border,
-              GLenum format, GLenum type, const void *pixels,
-              const struct gl_pixelstore_attrib *unpack)
-{
-   prep_teximage(ctx, texImage, internalFormat, width, 1, 1, border,
-                 format, type);
-   _mesa_store_teximage1d(ctx, texImage, internalFormat, width,
-                          border, format, type, pixels, unpack);
+   _mesa_store_teximage(ctx, dims, texImage, internalFormat, width, height, depth,
+                        border, format, type, pixels, unpack);
 }
 
 
 static void
-st_CompressedTexImage2D(struct gl_context *ctx,
-                        struct gl_texture_image *texImage,
-                        GLint internalFormat,
-                        GLint width, GLint height, GLint border,
-                        GLsizei imageSize, const GLvoid *data)
+st_CompressedTexImage(struct gl_context *ctx, GLuint dims,
+                      struct gl_texture_image *texImage,
+                      GLint internalFormat,
+                      GLint width, GLint height, GLint border, GLint depth,
+                      GLsizei imageSize, const GLvoid *data)
 {
-   prep_teximage(ctx, texImage, internalFormat, width, 1, 1, border,
+   prep_teximage(ctx, texImage, internalFormat, width, height, depth, border,
                  GL_NONE, GL_NONE);
-   _mesa_store_compressed_teximage2d(ctx, texImage, internalFormat, width,
-                                     height, border, imageSize, data);
+   _mesa_store_compressed_teximage(ctx, dims, texImage, internalFormat, width,
+                                   height, depth, border, imageSize, data);
 }
 
 
@@ -607,8 +572,7 @@ decompress_with_blit(struct gl_context * ctx,
    struct pipe_context *pipe = st->pipe;
    struct st_texture_image *stImage = st_texture_image(texImage);
    struct st_texture_object *stObj = st_texture_object(texImage->TexObject);
-   struct pipe_sampler_view *src_view =
-      st_get_texture_sampler_view(stObj, pipe);
+   struct pipe_sampler_view *src_view;
    const GLuint width = texImage->Width;
    const GLuint height = texImage->Height;
    struct pipe_surface *dst_surface;
@@ -630,8 +594,21 @@ decompress_with_blit(struct gl_context * ctx,
       pipe->render_condition(pipe, NULL, 0);
    }
 
-   /* Choose the source mipmap level */
-   src_view->u.tex.first_level = src_view->u.tex.last_level = texImage->Level;
+   /* Create sampler view that limits fetches to the source mipmap level */
+   {
+      struct pipe_sampler_view sv_temp;
+
+      u_sampler_view_default_template(&sv_temp, stObj->pt, stObj->pt->format);
+
+      sv_temp.u.tex.first_level =
+      sv_temp.u.tex.last_level = texImage->Level;
+
+      src_view = pipe->create_sampler_view(pipe, stObj->pt, &sv_temp);
+      if (!src_view) {
+         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGetTexImage");
+         return;
+      }
+   }
 
    /* blit/render/decompress */
    util_blit_pixels_tex(st->blit,
@@ -659,7 +636,9 @@ decompress_with_blit(struct gl_context * ctx,
    pixels = _mesa_map_pbo_dest(ctx, &ctx->Pack, pixels);
 
    /* copy/pack data into user buffer */
-   if (st_equal_formats(stImage->pt->format, format, type)) {
+   if (_mesa_format_matches_format_and_type(stImage->base.TexFormat,
+                                            format, type,
+                                            ctx->Pack.SwapBytes)) {
       /* memcpy */
       const uint bytesPerRow = width * util_format_get_blocksize(stImage->pt->format);
       ubyte *map = pipe_transfer_map(pipe, tex_xfer);
@@ -676,9 +655,16 @@ decompress_with_blit(struct gl_context * ctx,
       /* format translation via floats */
       GLuint row;
       enum pipe_format pformat = util_format_linear(dst_texture->format);
+      GLfloat *rgba;
+
+      rgba = (GLfloat *) malloc(width * 4 * sizeof(GLfloat));
+      if (!rgba) {
+         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGetTexImage()");
+         goto end;
+      }
+
       for (row = 0; row < height; row++) {
          const GLbitfield transferOps = 0x0; /* bypassed for glGetTexImage() */
-         GLfloat rgba[4 * MAX_WIDTH];
          GLvoid *dest = _mesa_image_address2d(&ctx->Pack, pixels, width,
                                               height, format, type, row, 0);
 
@@ -692,14 +678,19 @@ decompress_with_blit(struct gl_context * ctx,
          _mesa_pack_rgba_span_float(ctx, width, (GLfloat (*)[4]) rgba, format,
                                     type, dest, &ctx->Pack, transferOps);
       }
+
+      free(rgba);
    }
 
+end:
    _mesa_unmap_pbo_dest(ctx, &ctx->Pack);
 
    pipe->transfer_destroy(pipe, tex_xfer);
 
    /* destroy the temp / dest surface */
    util_destroy_rgba_surface(dst_texture, dst_surface);
+
+   pipe_sampler_view_release(pipe, &src_view);
 }
 
 
@@ -753,8 +744,6 @@ fallback_copy_texsubimage(struct gl_context *ctx,
    if (ST_DEBUG & DEBUG_FALLBACK)
       debug_printf("%s: fallback processing\n", __FUNCTION__);
 
-   assert(width <= MAX_WIDTH);
-
    if (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP) {
       srcY = strb->Base.Height - srcY - height;
    }
@@ -783,6 +772,7 @@ fallback_copy_texsubimage(struct gl_context *ctx,
       const GLboolean scaleOrBias = (ctx->Pixel.DepthScale != 1.0F ||
                                      ctx->Pixel.DepthBias != 0.0F);
       GLint row, yStep;
+      uint *data;
 
       /* determine bottom-to-top vs. top-to-bottom order for src buffer */
       if (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP) {
@@ -794,15 +784,23 @@ fallback_copy_texsubimage(struct gl_context *ctx,
          yStep = 1;
       }
 
-      /* To avoid a large temp memory allocation, do copy row by row */
-      for (row = 0; row < height; row++, srcY += yStep) {
-         uint data[MAX_WIDTH];
-         pipe_get_tile_z(pipe, src_trans, 0, srcY, width, 1, data);
-         if (scaleOrBias) {
-            _mesa_scale_and_bias_depth_uint(ctx, width, data);
+      data = (uint *) malloc(width * sizeof(uint));
+
+      if (data) {
+         /* To avoid a large temp memory allocation, do copy row by row */
+         for (row = 0; row < height; row++, srcY += yStep) {
+            pipe_get_tile_z(pipe, src_trans, 0, srcY, width, 1, data);
+            if (scaleOrBias) {
+               _mesa_scale_and_bias_depth_uint(ctx, width, data);
+            }
+            pipe_put_tile_z(pipe, stImage->transfer, 0, row, width, 1, data);
          }
-         pipe_put_tile_z(pipe, stImage->transfer, 0, row, width, 1, data);
       }
+      else {
+         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexSubImage()");
+      }
+
+      free(data);
    }
    else {
       /* RGBA format */
@@ -930,12 +928,11 @@ compatible_src_dst_formats(struct gl_context *ctx,
  * Note: srcY=0=Bottom of renderbuffer (GL convention)
  */
 static void
-st_copy_texsubimage(struct gl_context *ctx,
-                    struct gl_texture_image *texImage,
-                    GLint destX, GLint destY, GLint destZ,
-                    struct gl_renderbuffer *rb,
-                    GLint srcX, GLint srcY,
-                    GLsizei width, GLsizei height)
+st_CopyTexSubImage(struct gl_context *ctx, GLuint dims,
+                   struct gl_texture_image *texImage,
+                   GLint destX, GLint destY, GLint destZ,
+                   struct gl_renderbuffer *rb,
+                   GLint srcX, GLint srcY, GLsizei width, GLsizei height)
 {
    struct st_texture_image *stImage = st_texture_image(texImage);
    const GLenum texBaseFormat = texImage->_BaseFormat;
@@ -1098,49 +1095,6 @@ fallback:
 }
 
 
-
-static void
-st_CopyTexSubImage1D(struct gl_context *ctx,
-                     struct gl_texture_image *texImage,
-                     GLint xoffset,
-                     struct gl_renderbuffer *rb,
-                     GLint x, GLint y, GLsizei width)
-{
-   const GLint yoffset = 0, zoffset = 0;
-   const GLsizei height = 1;
-   st_copy_texsubimage(ctx, texImage,
-                       xoffset, yoffset, zoffset,  /* destX,Y,Z */
-                       rb, x, y, width, height);  /* src X, Y, size */
-}
-
-
-static void
-st_CopyTexSubImage2D(struct gl_context *ctx,
-                     struct gl_texture_image *texImage,
-                     GLint xoffset, GLint yoffset,
-                     struct gl_renderbuffer *rb,
-                     GLint x, GLint y, GLsizei width, GLsizei height)
-{
-   const GLint zoffset = 0;
-   st_copy_texsubimage(ctx, texImage,
-                       xoffset, yoffset, zoffset,  /* destX,Y,Z */
-                       rb, x, y, width, height);  /* src X, Y, size */
-}
-
-
-static void
-st_CopyTexSubImage3D(struct gl_context *ctx,
-                     struct gl_texture_image *texImage,
-                     GLint xoffset, GLint yoffset, GLint zoffset,
-                     struct gl_renderbuffer *rb,
-                     GLint x, GLint y, GLsizei width, GLsizei height)
-{
-   st_copy_texsubimage(ctx, texImage,
-                       xoffset, yoffset, zoffset,  /* destX,Y,Z */
-                       rb, x, y, width, height);  /* src X, Y, size */
-}
-
-
 /**
  * Copy image data from stImage into the texture object 'stObj' at level
  * 'dstLevel'.
@@ -1216,7 +1170,7 @@ st_finalize_texture(struct gl_context *ctx,
    enum pipe_format firstImageFormat;
    GLuint ptWidth, ptHeight, ptDepth, ptLayers;
 
-   if (stObj->base._Complete) {
+   if (_mesa_is_texture_complete(tObj, &tObj->Sampler)) {
       /* The texture is complete and we know exactly how many mipmap levels
        * are present/needed.  This is conditional because we may be called
        * from the st_generate_mipmap() function when the texture object is
@@ -1242,7 +1196,7 @@ st_finalize_texture(struct gl_context *ctx,
        firstImage->pt != stObj->pt &&
        (!stObj->pt || firstImage->pt->last_level >= stObj->pt->last_level)) {
       pipe_resource_reference(&stObj->pt, firstImage->pt);
-      pipe_sampler_view_reference(&stObj->sampler_view, NULL);
+      pipe_sampler_view_release(st->pipe, &stObj->sampler_view);
    }
 
    /* Find gallium format for the Mesa texture */
@@ -1282,7 +1236,7 @@ st_finalize_texture(struct gl_context *ctx,
           * gallium texture now.  We'll make a new one below.
           */
          pipe_resource_reference(&stObj->pt, NULL);
-         pipe_sampler_view_reference(&stObj->sampler_view, NULL);
+         pipe_sampler_view_release(st->pipe, &stObj->sampler_view);
          st->dirty.st |= ST_NEW_FRAMEBUFFER;
       }
    }
@@ -1334,57 +1288,6 @@ st_finalize_texture(struct gl_context *ctx,
 }
 
 
-/**
- * Returns pointer to a default/dummy texture.
- * This is typically used when the current shader has tex/sample instructions
- * but the user has not provided a (any) texture(s).
- */
-struct gl_texture_object *
-st_get_default_texture(struct st_context *st)
-{
-   if (!st->default_texture) {
-      static const GLenum target = GL_TEXTURE_2D;
-      GLubyte pixels[16][16][4];
-      struct gl_texture_object *texObj;
-      struct gl_texture_image *texImg;
-      GLuint i, j;
-
-      /* The ARB_fragment_program spec says (0,0,0,1) should be returned
-       * when attempting to sample incomplete textures.
-       */
-      for (i = 0; i < 16; i++) {
-         for (j = 0; j < 16; j++) {
-            pixels[i][j][0] = 0;
-            pixels[i][j][1] = 0;
-            pixels[i][j][2] = 0;
-            pixels[i][j][3] = 255;
-         }
-      }
-
-      texObj = st->ctx->Driver.NewTextureObject(st->ctx, 0, target);
-
-      texImg = _mesa_get_tex_image(st->ctx, texObj, target, 0);
-
-      _mesa_init_teximage_fields(st->ctx, texImg,
-                                 16, 16, 1, 0,  /* w, h, d, border */
-                                 GL_RGBA, MESA_FORMAT_RGBA8888);
-
-      _mesa_store_teximage2d(st->ctx, texImg, 
-                             GL_RGBA,    /* level, intformat */
-                             16, 16, 1,  /* w, h, d, border */
-                             GL_RGBA, GL_UNSIGNED_BYTE, pixels,
-                             &st->ctx->DefaultPacking);
-
-      texObj->Sampler.MinFilter = GL_NEAREST;
-      texObj->Sampler.MagFilter = GL_NEAREST;
-      texObj->_Complete = GL_TRUE;
-
-      st->default_texture = texObj;
-   }
-   return st->default_texture;
-}
-
-
 /**
  * Called via ctx->Driver.AllocTextureStorage() to allocate texture memory
  * for a whole mipmap stack.
@@ -1449,24 +1352,16 @@ void
 st_init_texture_functions(struct dd_function_table *functions)
 {
    functions->ChooseTextureFormat = st_ChooseTextureFormat;
-   functions->TexImage1D = st_TexImage1D;
-   functions->TexImage2D = st_TexImage2D;
-   functions->TexImage3D = st_TexImage3D;
-   functions->TexSubImage1D = _mesa_store_texsubimage1d;
-   functions->TexSubImage2D = _mesa_store_texsubimage2d;
-   functions->TexSubImage3D = _mesa_store_texsubimage3d;
-   functions->CompressedTexSubImage1D = _mesa_store_compressed_texsubimage1d;
-   functions->CompressedTexSubImage2D = _mesa_store_compressed_texsubimage2d;
-   functions->CompressedTexSubImage3D = _mesa_store_compressed_texsubimage3d;
-   functions->CopyTexSubImage1D = st_CopyTexSubImage1D;
-   functions->CopyTexSubImage2D = st_CopyTexSubImage2D;
-   functions->CopyTexSubImage3D = st_CopyTexSubImage3D;
+   functions->TexImage = st_TexImage;
+   functions->TexSubImage = _mesa_store_texsubimage;
+   functions->CompressedTexSubImage = _mesa_store_compressed_texsubimage;
+   functions->CopyTexSubImage = st_CopyTexSubImage;
    functions->GenerateMipmap = st_generate_mipmap;
 
    functions->GetTexImage = st_GetTexImage;
 
    /* compressed texture functions */
-   functions->CompressedTexImage2D = st_CompressedTexImage2D;
+   functions->CompressedTexImage = st_CompressedTexImage;
    functions->GetCompressedTexImage = _mesa_get_compressed_teximage;
 
    functions->NewTextureObject = st_NewTextureObject;