Example #1
0
static void
intelCopyTexSubImage(struct gl_context *ctx, GLuint dims,
                     struct gl_texture_image *texImage,
                     GLint xoffset, GLint yoffset, GLint slice,
                     struct gl_renderbuffer *rb,
                     GLint x, GLint y,
                     GLsizei width, GLsizei height)
{
   struct brw_context *brw = brw_context(ctx);

   /* Try BLORP first.  It can handle almost everything. */
   if (brw_blorp_copytexsubimage(brw, rb, texImage, slice, x, y,
                                 xoffset, yoffset, width, height))
      return;

   /* Next, try the BLT engine. */
   if (intel_copy_texsubimage(brw,
                              intel_texture_image(texImage),
                              xoffset, yoffset, slice,
                              intel_renderbuffer(rb), x, y, width, height)) {
      return;
   }

   /* Finally, fall back to meta.  This will likely be slow. */
   perf_debug("%s - fallback to swrast\n", __func__);
   _mesa_meta_CopyTexSubImage(ctx, dims, texImage,
                              xoffset, yoffset, slice,
                              rb, x, y, width, height);
}
Example #2
0
static void
intelCopyTexSubImage(struct gl_context *ctx, GLuint dims,
                     struct gl_texture_image *texImage,
                     GLint xoffset, GLint yoffset, GLint zoffset,
                     struct gl_renderbuffer *rb,
                     GLint x, GLint y,
                     GLsizei width, GLsizei height)
{
    struct intel_context *intel = intel_context(ctx);
    if (dims != 3) {
#ifndef I915
        /* Try BLORP first.  It can handle almost everything. */
        if (brw_blorp_copytexsubimage(intel, rb, texImage, x, y,
                                      xoffset, yoffset, width, height))
            return;
#endif

        /* Next, try the BLT engine. */
        if (intel_copy_texsubimage(intel,
                                   intel_texture_image(texImage),
                                   xoffset, yoffset,
                                   intel_renderbuffer(rb), x, y, width, height))
            return;
    }

    /* Finally, fall back to meta.  This will likely be slow. */
    fallback_debug("%s - fallback to swrast\n", __FUNCTION__);
    _mesa_meta_CopyTexSubImage(ctx, dims, texImage,
                               xoffset, yoffset, zoffset,
                               rb, x, y, width, height);
}
/**
 * Try to do a glBlitFramebuffer using glCopyTexSubImage2D
 * We can do this when the dst renderbuffer is actually a texture and
 * there is no scaling, mirroring or scissoring.
 *
 * \return new buffer mask indicating the buffers left to blit using the
 *         normal path.
 */
static GLbitfield
intel_blit_framebuffer_copy_tex_sub_image(struct gl_context *ctx,
                                          GLint srcX0, GLint srcY0,
                                          GLint srcX1, GLint srcY1,
                                          GLint dstX0, GLint dstY0,
                                          GLint dstX1, GLint dstY1,
                                          GLbitfield mask, GLenum filter)
{
   if (mask & GL_COLOR_BUFFER_BIT) {
      const struct gl_framebuffer *drawFb = ctx->DrawBuffer;
      const struct gl_framebuffer *readFb = ctx->ReadBuffer;
      const struct gl_renderbuffer_attachment *drawAtt =
         &drawFb->Attachment[drawFb->_ColorDrawBufferIndexes[0]];
      struct intel_renderbuffer *srcRb = 
         intel_renderbuffer(readFb->_ColorReadBuffer);

      /* If the source and destination are the same size with no
         mirroring, the rectangles are within the size of the
         texture and there is no scissor then we can use
         glCopyTexSubimage2D to implement the blit. This will end
         up as a fast hardware blit on some drivers */
      if (srcRb && drawAtt && drawAtt->Texture &&
          srcX0 - srcX1 == dstX0 - dstX1 &&
          srcY0 - srcY1 == dstY0 - dstY1 &&
          srcX1 >= srcX0 &&
          srcY1 >= srcY0 &&
          srcX0 >= 0 && srcX1 <= readFb->Width &&
          srcY0 >= 0 && srcY1 <= readFb->Height &&
          dstX0 >= 0 && dstX1 <= drawFb->Width &&
          dstY0 >= 0 && dstY1 <= drawFb->Height &&
          !ctx->Scissor.Enabled) {
         const struct gl_texture_object *texObj = drawAtt->Texture;
         const GLuint dstLevel = drawAtt->TextureLevel;
         const GLenum target = texObj->Target;

         struct gl_texture_image *texImage =
            _mesa_select_tex_image(ctx, texObj, target, dstLevel);

         if (intel_copy_texsubimage(intel_context(ctx),
                                    intel_texture_image(texImage),
                                    dstX0, dstY0,
                                    srcRb,
                                    srcX0, srcY0,
                                    srcX1 - srcX0, /* width */
                                    srcY1 - srcY0))
            mask &= ~GL_COLOR_BUFFER_BIT;
      }
   }

   return mask;
}
Example #4
0
static void
intelCopyTexSubImage1D(struct gl_context *ctx,
                       struct gl_texture_image *texImage,
                       GLint xoffset,
                       struct gl_renderbuffer *rb,
                       GLint x, GLint y, GLsizei width)
{
   if (!intel_copy_texsubimage(intel_context(ctx),
                               intel_texture_image(texImage),
                               xoffset, 0,
                               intel_renderbuffer(rb), x, y, width, 1)) {
      fallback_debug("%s - fallback to swrast\n", __FUNCTION__);
      _mesa_meta_CopyTexSubImage1D(ctx, texImage, xoffset,
                                   rb, x, y, width);
   }
}
Example #5
0
static void
intelCopyTexSubImage2D(struct gl_context * ctx, GLenum target, GLint level,
                       GLint xoffset, GLint yoffset,
                       GLint x, GLint y, GLsizei width, GLsizei height)
{
   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);

   /* Need to check texture is compatible with source format. 
    */

   if (!intel_copy_texsubimage(intel_context(ctx),
                               intel_texture_image(texImage),
                               xoffset, yoffset, x, y, width, height)) {
      fallback_debug("%s - fallback to swrast\n", __FUNCTION__);
      _mesa_meta_CopyTexSubImage2D(ctx, target, level,
                                   xoffset, yoffset, x, y, width, height);
   }
}
Example #6
0
static void
intelCopyTexSubImage(struct gl_context *ctx, GLuint dims,
                     struct gl_texture_image *texImage,
                     GLint xoffset, GLint yoffset, GLint slice,
                     struct gl_renderbuffer *rb,
                     GLint x, GLint y,
                     GLsizei width, GLsizei height)
{
   struct intel_context *intel = intel_context(ctx);

   /* Try the BLT engine. */
   if (intel_copy_texsubimage(intel,
                              intel_texture_image(texImage),
                              xoffset, yoffset, slice,
                              intel_renderbuffer(rb), x, y, width, height)) {
      return;
   }

   /* Otherwise, fall back to meta.  This will likely be slow. */
   perf_debug("%s - fallback to swrast\n", __FUNCTION__);
   _mesa_meta_CopyTexSubImage(ctx, dims, texImage,
                              xoffset, yoffset, slice,
                              rb, x, y, width, height);
}
Example #7
0
/**
 * Try to do a glBlitFramebuffer using glCopyTexSubImage2D
 * We can do this when the dst renderbuffer is actually a texture and
 * there is no scaling, mirroring or scissoring.
 *
 * \return new buffer mask indicating the buffers left to blit using the
 *         normal path.
 */
static GLbitfield
intel_blit_framebuffer_copy_tex_sub_image(struct gl_context *ctx,
                                          GLint srcX0, GLint srcY0,
                                          GLint srcX1, GLint srcY1,
                                          GLint dstX0, GLint dstY0,
                                          GLint dstX1, GLint dstY1,
                                          GLbitfield mask, GLenum filter)
{
   if (mask & GL_COLOR_BUFFER_BIT) {
      GLint i;
      const struct gl_framebuffer *drawFb = ctx->DrawBuffer;
      const struct gl_framebuffer *readFb = ctx->ReadBuffer;
      const struct gl_renderbuffer_attachment *drawAtt;
      struct intel_renderbuffer *srcRb = 
         intel_renderbuffer(readFb->_ColorReadBuffer);

      /* If the source and destination are the same size with no mirroring,
       * the rectangles are within the size of the texture and there is no
       * scissor then we can use glCopyTexSubimage2D to implement the blit.
       * This will end up as a fast hardware blit on some drivers.
       */
      const GLboolean use_intel_copy_texsubimage =
         srcX0 - srcX1 == dstX0 - dstX1 &&
         srcY0 - srcY1 == dstY0 - dstY1 &&
         srcX1 >= srcX0 &&
         srcY1 >= srcY0 &&
         srcX0 >= 0 && srcX1 <= readFb->Width &&
         srcY0 >= 0 && srcY1 <= readFb->Height &&
         dstX0 >= 0 && dstX1 <= drawFb->Width &&
         dstY0 >= 0 && dstY1 <= drawFb->Height &&
         !ctx->Scissor.Enabled;

      /* Verify that all the draw buffers can be blitted using
       * intel_copy_texsubimage().
       */
      for (i = 0; i < ctx->DrawBuffer->_NumColorDrawBuffers; i++) {
         int idx = ctx->DrawBuffer->_ColorDrawBufferIndexes[i];
         if (idx == -1)
            continue;
         drawAtt = &drawFb->Attachment[idx];

         if (srcRb && drawAtt && drawAtt->Texture &&
             use_intel_copy_texsubimage)
            continue;
         else
            return mask;
      }

      /* Blit to all active draw buffers */
      for (i = 0; i < ctx->DrawBuffer->_NumColorDrawBuffers; i++) {
         int idx = ctx->DrawBuffer->_ColorDrawBufferIndexes[i];
         if (idx == -1)
            continue;
         drawAtt = &drawFb->Attachment[idx];

         {
            const struct gl_texture_object *texObj = drawAtt->Texture;
            const GLuint dstLevel = drawAtt->TextureLevel;
            const GLenum target = texObj->Target;

            struct gl_texture_image *texImage =
               _mesa_select_tex_image(ctx, texObj, target, dstLevel);

            if (!intel_copy_texsubimage(intel_context(ctx),
                                        intel_texture_image(texImage),
                                        dstX0, dstY0,
                                        srcRb,
                                        srcX0, srcY0,
                                        srcX1 - srcX0, /* width */
                                        srcY1 - srcY0))
               return mask;
         }
      }

      mask &= ~GL_COLOR_BUFFER_BIT;
   }

   return mask;
}