コード例 #1
0
ファイル: st_gen_mipmap.c プロジェクト: toastpp/toastpp
static void
fallback_generate_mipmap(GLcontext *ctx, GLenum target,
                         struct gl_texture_object *texObj)
{
   struct pipe_context *pipe = ctx->st->pipe;
   struct pipe_screen *screen = pipe->screen;
   struct pipe_texture *pt = st_get_texobj_texture(texObj);
   const uint baseLevel = texObj->BaseLevel;
   const uint lastLevel = pt->last_level;
   const uint face = _mesa_tex_target_to_face(target), zslice = 0;
   uint dstLevel;
   GLenum datatype;
   GLuint comps;

   assert(target != GL_TEXTURE_3D); /* not done yet */

   _mesa_format_to_type_and_comps(texObj->Image[face][baseLevel]->TexFormat,
                                  &datatype, &comps);

   for (dstLevel = baseLevel + 1; dstLevel <= lastLevel; dstLevel++) {
      const uint srcLevel = dstLevel - 1;
      struct pipe_transfer *srcTrans, *dstTrans;
      const ubyte *srcData;
      ubyte *dstData;
      int srcStride, dstStride;

      srcTrans = st_cond_flush_get_tex_transfer(st_context(ctx), pt, face,
						srcLevel, zslice,
						PIPE_TRANSFER_READ, 0, 0,
						pt->width[srcLevel],
						pt->height[srcLevel]);

      dstTrans = st_cond_flush_get_tex_transfer(st_context(ctx), pt, face,
						dstLevel, zslice,
						PIPE_TRANSFER_WRITE, 0, 0,
						pt->width[dstLevel],
						pt->height[dstLevel]);

      srcData = (ubyte *) screen->transfer_map(screen, srcTrans);
      dstData = (ubyte *) screen->transfer_map(screen, dstTrans);

      srcStride = srcTrans->stride / srcTrans->block.size;
      dstStride = dstTrans->stride / dstTrans->block.size;

      _mesa_generate_mipmap_level(target, datatype, comps,
                   0 /*border*/,
                   pt->width[srcLevel], pt->height[srcLevel], pt->depth[srcLevel],
                   srcData,
                   srcStride, /* stride in texels */
                   pt->width[dstLevel], pt->height[dstLevel], pt->depth[dstLevel],
                   dstData,
                   dstStride); /* stride in texels */

      screen->transfer_unmap(screen, srcTrans);
      screen->transfer_unmap(screen, dstTrans);

      screen->tex_transfer_destroy(srcTrans);
      screen->tex_transfer_destroy(dstTrans);
   }
}
コード例 #2
0
ファイル: st_gen_mipmap.c プロジェクト: nikai3d/mesa
/**
 * Software fallback for generate mipmap levels.
 */
static void
fallback_generate_mipmap(struct gl_context *ctx, GLenum target,
                         struct gl_texture_object *texObj)
{
   struct pipe_context *pipe = st_context(ctx)->pipe;
   struct pipe_resource *pt = st_get_texobj_resource(texObj);
   const uint baseLevel = texObj->BaseLevel;
   const uint lastLevel = pt->last_level;
   const uint face = _mesa_tex_target_to_face(target);
   uint dstLevel;
   GLenum datatype;
   GLuint comps;
   GLboolean compressed;

   if (ST_DEBUG & DEBUG_FALLBACK)
      debug_printf("%s: fallback processing\n", __FUNCTION__);

   assert(target != GL_TEXTURE_3D); /* not done yet */

   compressed =
      _mesa_is_format_compressed(texObj->Image[face][baseLevel]->TexFormat);

   if (compressed) {
      GLenum type =
         _mesa_get_format_datatype(texObj->Image[face][baseLevel]->TexFormat);

      datatype = type == GL_UNSIGNED_NORMALIZED ? GL_UNSIGNED_BYTE : GL_FLOAT;
      comps = 4;
   }
   else {
      _mesa_format_to_type_and_comps(texObj->Image[face][baseLevel]->TexFormat,
                                     &datatype, &comps);
      assert(comps > 0 && "bad texture format in fallback_generate_mipmap()");
   }

   for (dstLevel = baseLevel + 1; dstLevel <= lastLevel; dstLevel++) {
      const uint srcLevel = dstLevel - 1;
      const uint srcWidth = u_minify(pt->width0, srcLevel);
      const uint srcHeight = u_minify(pt->height0, srcLevel);
      const uint srcDepth = u_minify(pt->depth0, srcLevel);
      const uint dstWidth = u_minify(pt->width0, dstLevel);
      const uint dstHeight = u_minify(pt->height0, dstLevel);
      const uint dstDepth = u_minify(pt->depth0, dstLevel);
      struct pipe_transfer *srcTrans, *dstTrans;
      const ubyte *srcData;
      ubyte *dstData;
      int srcStride, dstStride;

      srcTrans = pipe_get_transfer(pipe, pt, srcLevel,
                                   face,
                                   PIPE_TRANSFER_READ, 0, 0,
                                   srcWidth, srcHeight);

      dstTrans = pipe_get_transfer(pipe, pt, dstLevel,
                                   face,
                                   PIPE_TRANSFER_WRITE, 0, 0,
                                   dstWidth, dstHeight);

      srcData = (ubyte *) pipe_transfer_map(pipe, srcTrans);
      dstData = (ubyte *) pipe_transfer_map(pipe, dstTrans);

      srcStride = srcTrans->stride / util_format_get_blocksize(srcTrans->resource->format);
      dstStride = dstTrans->stride / util_format_get_blocksize(dstTrans->resource->format);

     /* this cannot work correctly for 3d since it does
        not respect layerStride. */
      if (compressed) {
         const enum pipe_format format = pt->format;
         const uint bw = util_format_get_blockwidth(format);
         const uint bh = util_format_get_blockheight(format);
         const uint srcWidth2 = align(srcWidth, bw);
         const uint srcHeight2 = align(srcHeight, bh);
         const uint dstWidth2 = align(dstWidth, bw);
         const uint dstHeight2 = align(dstHeight, bh);
         uint8_t *srcTemp, *dstTemp;

         assert(comps == 4);

         srcTemp = malloc(srcWidth2 * srcHeight2 * comps * (datatype == GL_FLOAT ? 4 : 1));
         dstTemp = malloc(dstWidth2 * dstHeight2 * comps * (datatype == GL_FLOAT ? 4 : 1));

         /* decompress the src image: srcData -> srcTemp */
         decompress_image(format, datatype, srcData, srcTemp, srcWidth2, srcHeight2, srcTrans->stride);

         _mesa_generate_mipmap_level(target, datatype, comps,
                                     0 /*border*/,
                                     srcWidth2, srcHeight2, srcDepth,
                                     srcTemp,
                                     srcWidth2, /* stride in texels */
                                     dstWidth2, dstHeight2, dstDepth,
                                     dstTemp,
                                     dstWidth2); /* stride in texels */

         /* compress the new image: dstTemp -> dstData */
         compress_image(format, datatype, dstTemp, dstData, dstWidth2, dstHeight2, dstTrans->stride);

         free(srcTemp);
         free(dstTemp);
      }
      else {
         _mesa_generate_mipmap_level(target, datatype, comps,
                                     0 /*border*/,
                                     srcWidth, srcHeight, srcDepth,
                                     srcData,
                                     srcStride, /* stride in texels */
                                     dstWidth, dstHeight, dstDepth,
                                     dstData,
                                     dstStride); /* stride in texels */
      }

      pipe_transfer_unmap(pipe, srcTrans);
      pipe_transfer_unmap(pipe, dstTrans);

      pipe->transfer_destroy(pipe, srcTrans);
      pipe->transfer_destroy(pipe, dstTrans);
   }
}