Esempio n. 1
0
void
radeonCopyTexImage2D(GLcontext *ctx, GLenum target, GLint level,
                     GLenum internalFormat,
                     GLint x, GLint y, GLsizei width, GLsizei height,
                     GLint border)
{
    struct gl_texture_unit *texUnit = _mesa_get_current_tex_unit(ctx);
    struct gl_texture_object *texObj =
        _mesa_select_tex_object(ctx, texUnit, target);
    struct gl_texture_image *texImage =
        _mesa_select_tex_image(ctx, texObj, target, level);
    int srcx, srcy, dstx, dsty;

    radeonContextPtr radeon = RADEON_CONTEXT(ctx);
    radeon_prepare_render(radeon);

    if (border)
        goto fail;

    /* Setup or redefine the texture object, mipmap tree and texture
     * image.  Don't populate yet.
     */
    ctx->Driver.TexImage2D(ctx, target, level, internalFormat,
                           width, height, border,
                           GL_RGBA, GL_UNSIGNED_BYTE, NULL,
                           &ctx->DefaultPacking, texObj, texImage);

    srcx = x;
    srcy = y;
    dstx = 0;
    dsty = 0;
    if (!_mesa_clip_copytexsubimage(ctx,
                                    &dstx, &dsty,
                                    &srcx, &srcy,
                                    &width, &height)) {
        return;
    }

    if (!do_copy_texsubimage(ctx, target, level,
                             radeon_tex_obj(texObj), (radeon_texture_image *)texImage,
                             0, 0, x, y, width, height)) {
        goto fail;
    }

    return;

fail:
    radeon_print(RADEON_FALLBACKS, RADEON_NORMAL,
                 "Falling back to sw for glCopyTexImage2D (internalFormat %s, border %d)\n",
                 _mesa_lookup_enum_by_nr(internalFormat), border);

    _mesa_meta_CopyTexImage2D(ctx, target, level, internalFormat, x, y,
                              width, height, border);
}
static GLboolean
do_blit_readpixels(struct gl_context * ctx,
                   GLint x, GLint y, GLsizei width, GLsizei height,
                   GLenum format, GLenum type,
                   const struct gl_pixelstore_attrib *pack, GLvoid * pixels)
{
    radeonContextPtr radeon = RADEON_CONTEXT(ctx);
    const struct radeon_renderbuffer *rrb = radeon_renderbuffer(ctx->ReadBuffer->_ColorReadBuffer);
    const gl_format dst_format = gl_format_and_type_to_mesa_format(format, type);
    unsigned dst_rowstride, dst_imagesize, aligned_rowstride, flip_y;
    struct radeon_bo *dst_buffer;
    GLint dst_x = 0, dst_y = 0;
    intptr_t dst_offset;

    /* It's not worth if number of pixels to copy is really small */
    if (width * height < 100) {
        return GL_FALSE;
    }

    if (dst_format == MESA_FORMAT_NONE ||
        !radeon->vtbl.check_blit(dst_format) || !radeon->vtbl.blit) {
        return GL_FALSE;
    }

    if (ctx->_ImageTransferState || ctx->Color._LogicOpEnabled) {
        return GL_FALSE;
    }

    if (pack->SwapBytes || pack->LsbFirst) {
        return GL_FALSE;
    }

    if (pack->RowLength > 0) {
        dst_rowstride = pack->RowLength;
    } else {
        dst_rowstride = width;
    }

    if (!_mesa_clip_copytexsubimage(ctx, &dst_x, &dst_y, &x, &y, &width, &height)) {
        return GL_TRUE;
    }
    assert(x >= 0 && y >= 0);

    aligned_rowstride = get_texture_image_row_stride(radeon, dst_format, dst_rowstride, 0);
    dst_rowstride *= _mesa_get_format_bytes(dst_format);
    if (_mesa_is_bufferobj(pack->BufferObj) && aligned_rowstride != dst_rowstride)
        return GL_FALSE;
    dst_imagesize = get_texture_image_size(dst_format,
                                           aligned_rowstride,
                                           height, 1, 0);

    if (!_mesa_is_bufferobj(pack->BufferObj))
    {
        dst_buffer = radeon_bo_open(radeon->radeonScreen->bom, 0, dst_imagesize, 1024, RADEON_GEM_DOMAIN_GTT, 0);
        dst_offset = 0;
    }
    else
    {
        dst_buffer = get_radeon_buffer_object(pack->BufferObj)->bo;
        dst_offset = (intptr_t)pixels;
    }

    /* Disable source Y flipping for FBOs */
    flip_y = (ctx->ReadBuffer->Name == 0);
    if (pack->Invert) {
        y = rrb->base.Height - height - y;
        flip_y = !flip_y;
    }

    if (radeon->vtbl.blit(ctx,
                          rrb->bo,
                          rrb->draw_offset,
                          rrb->base.Format,
                          rrb->pitch / rrb->cpp,
                          rrb->base.Width,
                          rrb->base.Height,
                          x,
                          y,
                          dst_buffer,
                          dst_offset,
                          dst_format,
                          aligned_rowstride / _mesa_get_format_bytes(dst_format),
                          width,
                          height,
                          0, /* dst_x */
                          0, /* dst_y */
                          width,
                          height,
                          flip_y))
    {
        if (!_mesa_is_bufferobj(pack->BufferObj))
        {
            radeon_bo_map(dst_buffer, 0);
            copy_rows(pixels, dst_rowstride, dst_buffer->ptr,
                      aligned_rowstride, height, dst_rowstride);
            radeon_bo_unmap(dst_buffer);
            radeon_bo_unref(dst_buffer);
        }

        return GL_TRUE;
    }

    if (!_mesa_is_bufferobj(pack->BufferObj))
        radeon_bo_unref(dst_buffer);

    return GL_FALSE;
}
Esempio n. 3
0
static GLboolean
do_blit_readpixels(GLcontext * ctx,
                   GLint x, GLint y, GLsizei width, GLsizei height,
                   GLenum format, GLenum type,
                   const struct gl_pixelstore_attrib *pack, GLvoid * pixels)
{
   struct intel_context *intel = intel_context(ctx);
   struct intel_region *src = intel_readbuf_region(intel);
   struct intel_buffer_object *dst = intel_buffer_object(pack->BufferObj);
   GLuint dst_offset;
   GLuint rowLength;
   drm_intel_bo *dst_buffer;
   GLboolean all;
   GLint dst_x, dst_y;

   if (INTEL_DEBUG & DEBUG_PIXEL)
      printf("%s\n", __FUNCTION__);

   if (!src)
      return GL_FALSE;

   if (!_mesa_is_bufferobj(pack->BufferObj)) {
      /* PBO only for now:
       */
      if (INTEL_DEBUG & DEBUG_PIXEL)
         printf("%s - not PBO\n", __FUNCTION__);
      return GL_FALSE;
   }


   if (ctx->_ImageTransferState ||
       !intel_check_blit_format(src, format, type)) {
      if (INTEL_DEBUG & DEBUG_PIXEL)
         printf("%s - bad format for blit\n", __FUNCTION__);
      return GL_FALSE;
   }

   if (pack->Alignment != 1 || pack->SwapBytes || pack->LsbFirst) {
      if (INTEL_DEBUG & DEBUG_PIXEL)
         printf("%s: bad packing params\n", __FUNCTION__);
      return GL_FALSE;
   }

   if (pack->RowLength > 0)
      rowLength = pack->RowLength;
   else
      rowLength = width;

   if (pack->Invert) {
      if (INTEL_DEBUG & DEBUG_PIXEL)
         printf("%s: MESA_PACK_INVERT not done yet\n", __FUNCTION__);
      return GL_FALSE;
   }
   else {
      if (ctx->ReadBuffer->Name == 0)
	 rowLength = -rowLength;
   }

   dst_offset = (GLintptr) _mesa_image_address(2, pack, pixels, width, height,
					       format, type, 0, 0, 0);

   if (!_mesa_clip_copytexsubimage(ctx,
				   &dst_x, &dst_y,
				   &x, &y,
				   &width, &height)) {
      return GL_TRUE;
   }

   intel_prepare_render(intel);

   all = (width * height * src->cpp == dst->Base.Size &&
	  x == 0 && dst_offset == 0);

   dst_x = 0;
   dst_y = 0;

   dst_buffer = intel_bufferobj_buffer(intel, dst,
					       all ? INTEL_WRITE_FULL :
					       INTEL_WRITE_PART);

   if (ctx->ReadBuffer->Name == 0)
      y = ctx->ReadBuffer->Height - (y + height);

   if (!intelEmitCopyBlit(intel,
			  src->cpp,
			  src->pitch, src->buffer, 0, src->tiling,
			  rowLength, dst_buffer, dst_offset, GL_FALSE,
			  x, y,
			  dst_x, dst_y,
			  width, height,
			  GL_COPY)) {
      return GL_FALSE;
   }

   if (INTEL_DEBUG & DEBUG_PIXEL)
      printf("%s - DONE\n", __FUNCTION__);

   return GL_TRUE;
}
Esempio n. 4
0
static bool
do_blit_readpixels(struct gl_context * ctx,
                   GLint x, GLint y, GLsizei width, GLsizei height,
                   GLenum format, GLenum type,
                   const struct gl_pixelstore_attrib *pack, GLvoid * pixels)
{
   struct brw_context *brw = brw_context(ctx);
   struct intel_buffer_object *dst = intel_buffer_object(pack->BufferObj);
   GLuint dst_offset;
   drm_intel_bo *dst_buffer;
   GLint dst_x, dst_y;
   GLuint dirty;

   DBG("%s\n", __FUNCTION__);

   assert(_mesa_is_bufferobj(pack->BufferObj));

   struct gl_renderbuffer *rb = ctx->ReadBuffer->_ColorReadBuffer;
   struct intel_renderbuffer *irb = intel_renderbuffer(rb);

   if (ctx->_ImageTransferState ||
       !_mesa_format_matches_format_and_type(irb->mt->format, format, type,
                                             false)) {
      DBG("%s - bad format for blit\n", __FUNCTION__);
      return false;
   }

   if (pack->SwapBytes || pack->LsbFirst) {
      DBG("%s: bad packing params\n", __FUNCTION__);
      return false;
   }

   int dst_stride = _mesa_image_row_stride(pack, width, format, type);
   bool dst_flip = false;
   /* Mesa flips the dst_stride for pack->Invert, but we want our mt to have a
    * normal dst_stride.
    */
   struct gl_pixelstore_attrib uninverted_pack = *pack;
   if (pack->Invert) {
      dst_stride = -dst_stride;
      dst_flip = true;
      uninverted_pack.Invert = false;
   }

   dst_offset = (GLintptr)pixels;
   dst_offset += _mesa_image_offset(2, &uninverted_pack, width, height,
				    format, type, 0, 0, 0);

   if (!_mesa_clip_copytexsubimage(ctx,
				   &dst_x, &dst_y,
				   &x, &y,
				   &width, &height)) {
      return true;
   }

   dirty = brw->front_buffer_dirty;
   intel_prepare_render(brw);
   brw->front_buffer_dirty = dirty;

   dst_buffer = intel_bufferobj_buffer(brw, dst,
				       dst_offset, height * dst_stride);

   struct intel_mipmap_tree *pbo_mt =
      intel_miptree_create_for_bo(brw,
                                  dst_buffer,
                                  irb->mt->format,
                                  dst_offset,
                                  width, height,
                                  dst_stride, I915_TILING_NONE);

   if (!intel_miptree_blit(brw,
                           irb->mt, irb->mt_level, irb->mt_layer,
                           x, y, _mesa_is_winsys_fbo(ctx->ReadBuffer),
                           pbo_mt, 0, 0,
                           0, 0, dst_flip,
                           width, height, GL_COPY)) {
      return false;
   }

   intel_miptree_release(&pbo_mt);

   DBG("%s - DONE\n", __FUNCTION__);

   return true;
}