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); }
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); } }
/** * Called via ctx->Driver.GenerateMipmap() * This is basically a wrapper for _mesa_meta_GenerateMipmap() which checks * if we'll be using software mipmap generation. In that case, we need to * map/unmap the base level texture image. */ static void intelGenerateMipmap(struct gl_context *ctx, GLenum target, struct gl_texture_object *texObj) { if (_mesa_meta_check_generate_mipmap_fallback(ctx, target, texObj)) { /* sw path: need to map texture images */ struct intel_context *intel = intel_context(ctx); struct intel_texture_object *intelObj = intel_texture_object(texObj); struct gl_texture_image *first_image = texObj->Image[0][texObj->BaseLevel]; fallback_debug("%s - fallback to swrast\n", __FUNCTION__); intel_tex_map_level_images(intel, intelObj, texObj->BaseLevel); _mesa_generate_mipmap(ctx, target, texObj); intel_tex_unmap_level_images(intel, intelObj, texObj->BaseLevel); if (!_mesa_is_format_compressed(first_image->TexFormat)) { GLuint nr_faces = (texObj->Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1; GLuint face, i; /* Update the level information in our private data in the new images, * since it didn't get set as part of a normal TexImage path. */ for (face = 0; face < nr_faces; face++) { for (i = texObj->BaseLevel + 1; i < texObj->MaxLevel; i++) { struct intel_texture_image *intelImage = intel_texture_image(texObj->Image[face][i]); if (!intelImage) break; intelImage->level = i; intelImage->face = face; /* Unreference the miptree to signal that the new Data is a * bare pointer from mesa. */ intel_miptree_release(intel, &intelImage->mt); } } } } else { _mesa_meta_GenerateMipmap(ctx, target, texObj); } }
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); } }
/** * CopyPixels with the blitter. Don't support zooming, pixel transfer, etc. */ static GLboolean do_blit_copypixels(struct gl_context * ctx, GLint srcx, GLint srcy, GLsizei width, GLsizei height, GLint dstx, GLint dsty, GLenum type) { struct intel_context *intel = intel_context(ctx); struct gl_framebuffer *fb = ctx->DrawBuffer; struct gl_framebuffer *read_fb = ctx->ReadBuffer; GLint orig_dstx; GLint orig_dsty; GLint orig_srcx; GLint orig_srcy; GLboolean flip = GL_FALSE; struct intel_renderbuffer *draw_irb = NULL; struct intel_renderbuffer *read_irb = NULL; /* Update draw buffer bounds */ _mesa_update_state(ctx); switch (type) { case GL_COLOR: if (fb->_NumColorDrawBuffers != 1) { fallback_debug("glCopyPixels() fallback: MRT\n"); return GL_FALSE; } draw_irb = intel_renderbuffer(fb->_ColorDrawBuffers[0]); read_irb = intel_renderbuffer(read_fb->_ColorReadBuffer); break; case GL_DEPTH_STENCIL_EXT: draw_irb = intel_renderbuffer(fb->Attachment[BUFFER_DEPTH].Renderbuffer); read_irb = intel_renderbuffer(read_fb->Attachment[BUFFER_DEPTH].Renderbuffer); break; case GL_DEPTH: fallback_debug("glCopyPixels() fallback: GL_DEPTH\n"); return GL_FALSE; case GL_STENCIL: fallback_debug("glCopyPixels() fallback: GL_STENCIL\n"); return GL_FALSE; default: fallback_debug("glCopyPixels(): Unknown type\n"); return GL_FALSE; } if (!draw_irb) { fallback_debug("glCopyPixels() fallback: missing draw buffer\n"); return GL_FALSE; } if (!read_irb) { fallback_debug("glCopyPixels() fallback: missing read buffer\n"); return GL_FALSE; } if (draw_irb->Base.Format != read_irb->Base.Format && !(draw_irb->Base.Format == MESA_FORMAT_XRGB8888 && read_irb->Base.Format == MESA_FORMAT_ARGB8888)) { fallback_debug("glCopyPixels() fallback: mismatched formats (%s -> %s\n", _mesa_get_format_name(read_irb->Base.Format), _mesa_get_format_name(draw_irb->Base.Format)); return GL_FALSE; } /* Copypixels can be more than a straight copy. Ensure all the * extra operations are disabled: */ if (!intel_check_copypixel_blit_fragment_ops(ctx) || ctx->Pixel.ZoomX != 1.0F || ctx->Pixel.ZoomY != 1.0F) return GL_FALSE; intel_prepare_render(intel); intel_flush(&intel->ctx); /* Clip to destination buffer. */ orig_dstx = dstx; orig_dsty = dsty; if (!_mesa_clip_to_region(fb->_Xmin, fb->_Ymin, fb->_Xmax, fb->_Ymax, &dstx, &dsty, &width, &height)) goto out; /* Adjust src coords for our post-clipped destination origin */ srcx += dstx - orig_dstx; srcy += dsty - orig_dsty; /* Clip to source buffer. */ orig_srcx = srcx; orig_srcy = srcy; if (!_mesa_clip_to_region(0, 0, read_fb->Width, read_fb->Height, &srcx, &srcy, &width, &height)) goto out; /* Adjust dst coords for our post-clipped source origin */ dstx += srcx - orig_srcx; dsty += srcy - orig_srcy; /* Flip dest Y if it's a window system framebuffer. */ if (fb->Name == 0) { /* copypixels to a window system framebuffer */ dsty = fb->Height - dsty - height; flip = !flip; } /* Flip source Y if it's a window system framebuffer. */ if (read_fb->Name == 0) { srcy = read_fb->Height - srcy - height; flip = !flip; } srcx += read_irb->draw_x; srcy += read_irb->draw_y; dstx += draw_irb->draw_x; dsty += draw_irb->draw_y; if (!intel_region_copy(intel, draw_irb->region, 0, dstx, dsty, read_irb->region, 0, srcx, srcy, width, height, flip, ctx->Color.ColorLogicOpEnabled ? ctx->Color.LogicOp : GL_COPY)) { DBG("%s: blit failure\n", __FUNCTION__); return GL_FALSE; } out: intel_check_front_buffer_rendering(intel); DBG("%s: success\n", __FUNCTION__); return GL_TRUE; }