Exemplo n.º 1
0
void
_mesa_update_fetch_functions(struct gl_context *ctx, GLuint unit)
{
   struct gl_texture_object *texObj = ctx->Texture.Unit[unit]._Current;
   struct gl_sampler_object *samp;
   GLuint face, i;
   GLuint dims;

   if (!texObj)
      return;

   samp = _mesa_get_samplerobj(ctx, unit);

   dims = _mesa_get_texture_dimensions(texObj->Target);

   for (face = 0; face < 6; face++) {
      for (i = 0; i < MAX_TEXTURE_LEVELS; i++) {
         if (texObj->Image[face][i]) {
	    set_fetch_functions(samp,
                                swrast_texture_image(texObj->Image[face][i]),
                                dims);
         }
      }
   }
}
Exemplo n.º 2
0
/**
 * This is the software fallback for Driver.GetTexImage().
 * All error checking will have been done before this routine is called.
 * We'll call ctx->Driver.MapTextureImage() to access the data, then
 * unmap with ctx->Driver.UnmapTextureImage().
 */
void
_mesa_GetTexImage_sw(struct gl_context *ctx,
                     GLenum format, GLenum type, GLvoid *pixels,
                     struct gl_texture_image *texImage)
{
   const GLuint dimensions =
      _mesa_get_texture_dimensions(texImage->TexObject->Target);

   /* map dest buffer, if PBO */
   if (_mesa_is_bufferobj(ctx->Pack.BufferObj)) {
      /* Packing texture image into a PBO.
       * Map the (potentially) VRAM-based buffer into our process space so
       * we can write into it with the code below.
       * A hardware driver might use a sophisticated blit to move the
       * texture data to the PBO if the PBO is in VRAM along with the texture.
       */
      GLubyte *buf = (GLubyte *)
         ctx->Driver.MapBufferRange(ctx, 0, ctx->Pack.BufferObj->Size,
				    GL_MAP_WRITE_BIT, ctx->Pack.BufferObj,
                                    MAP_INTERNAL);
      if (!buf) {
         /* out of memory or other unexpected error */
         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGetTexImage(map PBO failed)");
         return;
      }
      /* <pixels> was an offset into the PBO.
       * Now make it a real, client-side pointer inside the mapped region.
       */
      pixels = ADD_POINTERS(buf, pixels);
   }

   if (get_tex_memcpy(ctx, format, type, pixels, texImage)) {
      /* all done */
   }
   else if (format == GL_DEPTH_COMPONENT) {
      get_tex_depth(ctx, dimensions, format, type, pixels, texImage);
   }
   else if (format == GL_DEPTH_STENCIL) {
      get_tex_depth_stencil(ctx, dimensions, format, type, pixels, texImage);
   }
   else if (format == GL_STENCIL_INDEX) {
      get_tex_stencil(ctx, dimensions, format, type, pixels, texImage);
   }
   else if (format == GL_YCBCR_MESA) {
      get_tex_ycbcr(ctx, dimensions, format, type, pixels, texImage);
   }
   else {
      get_tex_rgba(ctx, dimensions, format, type, pixels, texImage);
   }

   if (_mesa_is_bufferobj(ctx->Pack.BufferObj)) {
      ctx->Driver.UnmapBuffer(ctx, ctx->Pack.BufferObj, MAP_INTERNAL);
   }
}
Exemplo n.º 3
0
/*
 * Returns the dimensions associated to a target. GL_TEXTURE_BUFFER and
 * GL_RENDERBUFFER have associated a dimension, but they are not textures
 * per-se, so we can't just call _mesa_get_texture_dimension directly.
 */
static GLint
_get_target_dimensions(GLenum target)
{
   switch(target) {
   case GL_TEXTURE_BUFFER:
      return 1;
   case GL_RENDERBUFFER:
      return 2;
   default:
      return _mesa_get_texture_dimensions(target);
   }
}
Exemplo n.º 4
0
void
_mesa_update_fetch_functions(struct gl_texture_object *texObj)
{
   GLuint face, i;
   GLuint dims;

   dims = _mesa_get_texture_dimensions(texObj->Target);

   for (face = 0; face < 6; face++) {
      for (i = 0; i < MAX_TEXTURE_LEVELS; i++) {
         if (texObj->Image[face][i]) {
	    set_fetch_functions(swrast_texture_image(texObj->Image[face][i]),
                                dims);
         }
      }
   }
}
Exemplo n.º 5
0
/**
 * This is the software fallback for Driver.GetCompressedTexImage().
 * All error checking will have been done before this routine is called.
 */
void
_mesa_GetCompressedTexImage_sw(struct gl_context *ctx,
                               struct gl_texture_image *texImage,
                               GLvoid *img)
{
   const GLuint dimensions =
      _mesa_get_texture_dimensions(texImage->TexObject->Target);
   struct compressed_pixelstore store;
   GLint slice;
   GLubyte *dest;

   _mesa_compute_compressed_pixelstore(dimensions, texImage->TexFormat,
                                       texImage->Width, texImage->Height,
                                       texImage->Depth,
                                       &ctx->Pack,
                                       &store);

   if (_mesa_is_bufferobj(ctx->Pack.BufferObj)) {
      /* pack texture image into a PBO */
      dest = (GLubyte *)
         ctx->Driver.MapBufferRange(ctx, 0, ctx->Pack.BufferObj->Size,
				    GL_MAP_WRITE_BIT, ctx->Pack.BufferObj,
                                    MAP_INTERNAL);
      if (!dest) {
         /* out of memory or other unexpected error */
         _mesa_error(ctx, GL_OUT_OF_MEMORY,
                     "glGetCompresssedTexImage(map PBO failed)");
         return;
      }
      dest = ADD_POINTERS(dest, img);
   } else {
      dest = img;
   }

   dest += store.SkipBytes;

   for (slice = 0; slice < store.CopySlices; slice++) {
      GLint srcRowStride;
      GLubyte *src;

      /* map src texture buffer */
      ctx->Driver.MapTextureImage(ctx, texImage, slice,
                                  0, 0, texImage->Width, texImage->Height,
                                  GL_MAP_READ_BIT, &src, &srcRowStride);

      if (src) {
         GLint i;
         for (i = 0; i < store.CopyRowsPerSlice; i++) {
            memcpy(dest, src, store.CopyBytesPerRow);
            dest += store.TotalBytesPerRow;
            src += srcRowStride;
         }

         ctx->Driver.UnmapTextureImage(ctx, texImage, slice);

         /* Advance to next slice */
         dest += store.TotalBytesPerRow * (store.TotalRowsPerSlice - store.CopyRowsPerSlice);

      } else {
         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGetCompresssedTexImage");
      }
   }

   if (_mesa_is_bufferobj(ctx->Pack.BufferObj)) {
      ctx->Driver.UnmapBuffer(ctx, ctx->Pack.BufferObj, MAP_INTERNAL);
   }
}
Exemplo n.º 6
0
/**
 * Do error checking for a glGetCompressedTexImage() call.
 * \return GL_TRUE if any error, GL_FALSE if no errors.
 */
static GLboolean
getcompressedteximage_error_check(struct gl_context *ctx,
                                  struct gl_texture_image *texImage,
                                  GLenum target,
                                  GLint level, GLsizei clientMemSize,
                                  GLvoid *img, bool dsa)
{
   const GLint maxLevels = _mesa_max_texture_levels(ctx, target);
   GLuint compressedSize, dimensions;
   const char *suffix = dsa ? "ture" : "";

   assert(texImage);

   if (!legal_getteximage_target(ctx, target, dsa)) {
      _mesa_error(ctx, GL_INVALID_ENUM,
                  "glGetCompressedTex%sImage(target=%s)", suffix,
                  _mesa_lookup_enum_by_nr(target));
      return GL_TRUE;
   }

   assert(maxLevels != 0);
   if (level < 0 || level >= maxLevels) {
      _mesa_error(ctx, GL_INVALID_VALUE,
                  "glGetCompressedTex%sImage(bad level = %d)", suffix, level);
      return GL_TRUE;
   }

   if (!_mesa_is_format_compressed(texImage->TexFormat)) {
      _mesa_error(ctx, GL_INVALID_OPERATION,
                  "glGetCompressedTex%sImage(texture is not compressed)",
                  suffix);
      return GL_TRUE;
   }

   compressedSize = _mesa_format_image_size(texImage->TexFormat,
                                            texImage->Width,
                                            texImage->Height,
                                            texImage->Depth);

   /* Check for invalid pixel storage modes */
   dimensions = _mesa_get_texture_dimensions(texImage->TexObject->Target);
   if (!_mesa_compressed_pixel_storage_error_check(ctx, dimensions,
                                              &ctx->Pack, dsa ?
                                              "glGetCompressedTextureImage":
                                              "glGetCompressedTexImage")) {
      return GL_TRUE;
   }

   if (!_mesa_is_bufferobj(ctx->Pack.BufferObj)) {
      /* do bounds checking on writing to client memory */
      if (clientMemSize < (GLsizei) compressedSize) {
         _mesa_error(ctx, GL_INVALID_OPERATION,
                     "%s(out of bounds access: bufSize (%d) is too small)",
                     dsa ? "glGetCompressedTextureImage" :
                     "glGetnCompressedTexImageARB", clientMemSize);
         return GL_TRUE;
      }
   } else {
      /* do bounds checking on PBO write */
      if ((const GLubyte *) img + compressedSize >
          (const GLubyte *) ctx->Pack.BufferObj->Size) {
         _mesa_error(ctx, GL_INVALID_OPERATION,
                     "glGetCompressedTex%sImage(out of bounds PBO access)",
                     suffix);
         return GL_TRUE;
      }

      /* make sure PBO is not mapped */
      if (_mesa_check_disallowed_mapping(ctx->Pack.BufferObj)) {
         _mesa_error(ctx, GL_INVALID_OPERATION,
                     "glGetCompressedTex%sImage(PBO is mapped)", suffix);
         return GL_TRUE;
      }
   }

   return GL_FALSE;
}
Exemplo n.º 7
0
/**
 * Do error checking for a glGetCompressedTexImage() call.
 * \return GL_TRUE if any error, GL_FALSE if no errors.
 */
static GLboolean
getcompressedteximage_error_check(struct gl_context *ctx, GLenum target,
                                  GLint level, GLsizei clientMemSize, GLvoid *img)
{
   struct gl_texture_object *texObj;
   struct gl_texture_image *texImage;
   const GLint maxLevels = _mesa_max_texture_levels(ctx, target);
   GLuint compressedSize, dimensions;

   if (!legal_getteximage_target(ctx, target)) {
      _mesa_error(ctx, GL_INVALID_ENUM, "glGetCompressedTexImage(target=0x%x)",
                  target);
      return GL_TRUE;
   }

   assert(maxLevels != 0);
   if (level < 0 || level >= maxLevels) {
      _mesa_error(ctx, GL_INVALID_VALUE,
                  "glGetCompressedTexImageARB(bad level = %d)", level);
      return GL_TRUE;
   }

   texObj = _mesa_get_current_tex_object(ctx, target);
   if (!texObj) {
      _mesa_error(ctx, GL_INVALID_ENUM, "glGetCompressedTexImageARB(target)");
      return GL_TRUE;
   }

   texImage = _mesa_select_tex_image(ctx, texObj, target, level);

   if (!texImage) {
      /* probably invalid mipmap level */
      _mesa_error(ctx, GL_INVALID_VALUE,
                  "glGetCompressedTexImageARB(level)");
      return GL_TRUE;
   }

   if (!_mesa_is_format_compressed(texImage->TexFormat)) {
      _mesa_error(ctx, GL_INVALID_OPERATION,
                  "glGetCompressedTexImageARB(texture is not compressed)");
      return GL_TRUE;
   }

   compressedSize = _mesa_format_image_size(texImage->TexFormat,
                                            texImage->Width,
                                            texImage->Height,
                                            texImage->Depth);

   /* Check for invalid pixel storage modes */
   dimensions = _mesa_get_texture_dimensions(texImage->TexObject->Target);
   if (!_mesa_compressed_texture_pixel_storage_error_check(ctx, dimensions,
                                                           &ctx->Pack,
                                                           "glGetCompressedTexImageARB")) {
      return GL_TRUE;
   }

   if (!_mesa_is_bufferobj(ctx->Pack.BufferObj)) {
      /* do bounds checking on writing to client memory */
      if (clientMemSize < (GLsizei) compressedSize) {
         _mesa_error(ctx, GL_INVALID_OPERATION,
                     "glGetnCompressedTexImageARB(out of bounds access:"
                     " bufSize (%d) is too small)", clientMemSize);
         return GL_TRUE;
      }
   } else {
      /* do bounds checking on PBO write */
      if ((const GLubyte *) img + compressedSize >
          (const GLubyte *) ctx->Pack.BufferObj->Size) {
         _mesa_error(ctx, GL_INVALID_OPERATION,
                     "glGetCompressedTexImage(out of bounds PBO access)");
         return GL_TRUE;
      }

      /* make sure PBO is not mapped */
      if (_mesa_check_disallowed_mapping(ctx->Pack.BufferObj)) {
         _mesa_error(ctx, GL_INVALID_OPERATION,
                     "glGetCompressedTexImage(PBO is mapped)");
         return GL_TRUE;
      }
   }

   return GL_FALSE;
}