Exemplo n.º 1
0
static void
do_blorp_blit(struct brw_context *brw, GLbitfield buffer_bit,
              struct intel_renderbuffer *src_irb, mesa_format src_format,
              struct intel_renderbuffer *dst_irb, mesa_format dst_format,
              GLfloat srcX0, GLfloat srcY0, GLfloat srcX1, GLfloat srcY1,
              GLfloat dstX0, GLfloat dstY0, GLfloat dstX1, GLfloat dstY1,
              GLenum filter, bool mirror_x, bool mirror_y)
{
   const struct gl_context *ctx = &brw->ctx;

   /* Find source/dst miptrees */
   struct intel_mipmap_tree *src_mt = find_miptree(buffer_bit, src_irb);
   struct intel_mipmap_tree *dst_mt = find_miptree(buffer_bit, dst_irb);

   const bool do_srgb = ctx->Color.sRGBEnabled;

   /* Do the blit */
   brw_blorp_blit_miptrees(brw,
                           src_mt, src_irb->mt_level, src_irb->mt_layer,
                           src_format, blorp_get_texture_swizzle(src_irb),
                           dst_mt, dst_irb->mt_level, dst_irb->mt_layer,
                           dst_format,
                           srcX0, srcY0, srcX1, srcY1,
                           dstX0, dstY0, dstX1, dstY1,
                           filter, mirror_x, mirror_y,
                           do_srgb, do_srgb);

   dst_irb->need_downsample = true;
}
Exemplo n.º 2
0
/**
 * The GenerateMipmap() driver hook.
 */
void
brw_generate_mipmap(struct gl_context *ctx, GLenum target,
                    struct gl_texture_object *tex_obj)
{
   struct brw_context *brw = brw_context(ctx);
   struct gen_device_info *devinfo = &brw->screen->devinfo;
   struct intel_texture_object *intel_obj = intel_texture_object(tex_obj);
   const unsigned base_level = tex_obj->BaseLevel;
   unsigned last_level, first_layer, last_layer;

   /* Blorp doesn't handle combined depth/stencil surfaces on Gen4-5 yet. */
   if (devinfo->gen <= 5 &&
       (tex_obj->Image[0][base_level]->_BaseFormat == GL_DEPTH_COMPONENT ||
        tex_obj->Image[0][base_level]->_BaseFormat == GL_DEPTH_STENCIL)) {
      _mesa_meta_GenerateMipmap(ctx, target, tex_obj);
      return;
   }

   /* find expected last mipmap level to generate */
   last_level = _mesa_compute_num_levels(ctx, tex_obj, target) - 1;

   if (last_level == 0)
      return;

   /* The texture isn't in a "complete" state yet so set the expected
    * last_level here; we're not going through normal texture validation.
    */
   intel_obj->_MaxLevel = last_level;

   if (!tex_obj->Immutable) {
      _mesa_prepare_mipmap_levels(ctx, tex_obj, base_level, last_level);

      /* At this point, memory for all the texture levels has been
       * allocated.  However, the base level image may be in one resource
       * while the subsequent/smaller levels may be in another resource.
       * Finalizing the texture will copy the base images from the former
       * resource to the latter.
       *
       * After this, we'll have all mipmap levels in one resource.
       */
      intel_finalize_mipmap_tree(brw, tex_obj);
   }

   struct intel_mipmap_tree *mt = intel_obj->mt;
   if (!mt) {
      _mesa_error(ctx, GL_OUT_OF_MEMORY, "mipmap generation");
      return;
   }

   const mesa_format format = intel_obj->_Format;

   /* Fall back to the CPU for non-renderable cases.
    *
    * TODO: 3D textures require blending data from multiple slices,
    * which means we need custom shaders.  For now, fall back.
    */
   if (!brw->mesa_format_supports_render[format] || target == GL_TEXTURE_3D) {
      _mesa_generate_mipmap(ctx, target, tex_obj);
      return;
   }

   const struct isl_extent4d *base_size = &mt->surf.logical_level0_px;

   if (mt->target == GL_TEXTURE_CUBE_MAP) {
      first_layer = _mesa_tex_target_to_face(target);
      last_layer = first_layer;
   } else {
      first_layer = 0;
      last_layer = base_size->array_len - 1;
   }

   /* The GL_EXT_texture_sRGB_decode extension's issues section says:
    *
    *    "10) How is mipmap generation of sRGB textures affected by the
    *     TEXTURE_SRGB_DECODE_EXT parameter?
    *
    *     RESOLVED:  When the TEXTURE_SRGB_DECODE parameter is DECODE_EXT
    *     for an sRGB texture, mipmap generation should decode sRGB texels
    *     to a linear RGB color space, perform downsampling, then encode
    *     back to an sRGB color space.  (Issue 24 in the EXT_texture_sRGB
    *     specification provides a rationale for why.)  When the parameter
    *     is SKIP_DECODE_EXT instead, mipmap generation skips the encode
    *     and decode steps during mipmap generation.  By skipping the
    *     encode and decode steps, sRGB mipmap generation should match
    *     the mipmap generation for a non-sRGB texture."
    */
   bool do_srgb = tex_obj->Sampler.sRGBDecode == GL_DECODE_EXT;

   for (unsigned dst_level = base_level + 1;
        dst_level <= last_level;
        dst_level++) {

      const unsigned src_level = dst_level - 1;

      for (unsigned layer = first_layer; layer <= last_layer; layer++) {
         brw_blorp_blit_miptrees(brw, mt, src_level, layer, format,
                                 SWIZZLE_XYZW, mt, dst_level, layer, format,
                                 0, 0,
                                 minify(base_size->width, src_level),
                                 minify(base_size->height, src_level),
                                 0, 0,
                                 minify(base_size->width, dst_level),
                                 minify(base_size->height, dst_level),
                                 GL_LINEAR, false, false,
                                 do_srgb, do_srgb);
      }
   }
}
Exemplo n.º 3
0
bool
brw_blorp_copytexsubimage(struct brw_context *brw,
                          struct gl_renderbuffer *src_rb,
                          struct gl_texture_image *dst_image,
                          int slice,
                          int srcX0, int srcY0,
                          int dstX0, int dstY0,
                          int width, int height)
{
   struct gl_context *ctx = &brw->ctx;
   struct intel_renderbuffer *src_irb = intel_renderbuffer(src_rb);
   struct intel_texture_image *intel_image = intel_texture_image(dst_image);

   /* No pixel transfer operations (zoom, bias, mapping), just a blit */
   if (brw->ctx._ImageTransferState)
      return false;

   /* Sync up the state of window system buffers.  We need to do this before
    * we go looking at the src renderbuffer's miptree.
    */
   intel_prepare_render(brw);

   struct intel_mipmap_tree *src_mt = src_irb->mt;
   struct intel_mipmap_tree *dst_mt = intel_image->mt;

   /* There is support for only up to eight samples. */
   if (src_mt->num_samples > 8 || dst_mt->num_samples > 8)
      return false;

   /* BLORP is only supported from Gen6 onwards. */
   if (brw->gen < 6)
      return false;

   if (_mesa_get_format_base_format(src_rb->Format) !=
       _mesa_get_format_base_format(dst_image->TexFormat)) {
      return false;
   }

   /* We can't handle format conversions between Z24 and other formats since
    * we have to lie about the surface format.  See the comments in
    * brw_blorp_surface_info::set().
    */
   if ((src_mt->format == MESA_FORMAT_Z24_UNORM_X8_UINT) !=
       (dst_mt->format == MESA_FORMAT_Z24_UNORM_X8_UINT)) {
      return false;
   }

   if (!brw->format_supported_as_render_target[dst_image->TexFormat])
      return false;

   /* Source clipping shouldn't be necessary, since copytexsubimage (in
    * src/mesa/main/teximage.c) calls _mesa_clip_copytexsubimage() which
    * takes care of it.
    *
    * Destination clipping shouldn't be necessary since the restrictions on
    * glCopyTexSubImage prevent the user from specifying a destination rectangle
    * that falls outside the bounds of the destination texture.
    * See error_check_subtexture_dimensions().
    */

   int srcY1 = srcY0 + height;
   int srcX1 = srcX0 + width;
   int dstX1 = dstX0 + width;
   int dstY1 = dstY0 + height;

   /* Account for the fact that in the system framebuffer, the origin is at
    * the lower left.
    */
   bool mirror_y = false;
   if (_mesa_is_winsys_fbo(ctx->ReadBuffer)) {
      GLint tmp = src_rb->Height - srcY0;
      srcY0 = src_rb->Height - srcY1;
      srcY1 = tmp;
      mirror_y = true;
   }

   /* Account for face selection and texture view MinLayer */
   int dst_slice = slice + dst_image->TexObject->MinLayer + dst_image->Face;
   int dst_level = dst_image->Level + dst_image->TexObject->MinLevel;

   brw_blorp_blit_miptrees(brw,
                           src_mt, src_irb->mt_level, src_irb->mt_layer,
                           src_rb->Format, blorp_get_texture_swizzle(src_irb),
                           dst_mt, dst_level, dst_slice,
                           dst_image->TexFormat,
                           srcX0, srcY0, srcX1, srcY1,
                           dstX0, dstY0, dstX1, dstY1,
                           GL_NEAREST, false, mirror_y,
                           false, false);

   /* If we're copying to a packed depth stencil texture and the source
    * framebuffer has separate stencil, we need to also copy the stencil data
    * over.
    */
   src_rb = ctx->ReadBuffer->Attachment[BUFFER_STENCIL].Renderbuffer;
   if (_mesa_get_format_bits(dst_image->TexFormat, GL_STENCIL_BITS) > 0 &&
       src_rb != NULL) {
      src_irb = intel_renderbuffer(src_rb);
      src_mt = src_irb->mt;

      if (src_mt->stencil_mt)
         src_mt = src_mt->stencil_mt;
      if (dst_mt->stencil_mt)
         dst_mt = dst_mt->stencil_mt;

      if (src_mt != dst_mt) {
         brw_blorp_blit_miptrees(brw,
                                 src_mt, src_irb->mt_level, src_irb->mt_layer,
                                 src_mt->format,
                                 blorp_get_texture_swizzle(src_irb),
                                 dst_mt, dst_level, dst_slice,
                                 dst_mt->format,
                                 srcX0, srcY0, srcX1, srcY1,
                                 dstX0, dstY0, dstX1, dstY1,
                                 GL_NEAREST, false, mirror_y,
                                 false, false);
      }
   }

   return true;
}