/** * Get the intel_region which is the source for any glCopyTex[Sub]Image call. * * Do the best we can using the blitter. A future project is to use * the texture engine and fragment programs for these copies. */ static const struct intel_region * get_teximage_source(struct intel_context *intel, GLenum internalFormat) { struct intel_renderbuffer *irb; DBG("%s %s\n", __FUNCTION__, _mesa_lookup_enum_by_nr(internalFormat)); switch (internalFormat) { case GL_DEPTH_COMPONENT: case GL_DEPTH_COMPONENT16_ARB: irb = intel_get_renderbuffer(intel->ctx.ReadBuffer, BUFFER_DEPTH); if (irb && irb->region && irb->region->cpp == 2) return irb->region; return NULL; case GL_DEPTH24_STENCIL8_EXT: case GL_DEPTH_STENCIL_EXT: irb = intel_get_renderbuffer(intel->ctx.ReadBuffer, BUFFER_DEPTH); if (irb && irb->region && irb->region->cpp == 4) return irb->region; return NULL; case GL_RGBA: case GL_RGBA8: return intel_readbuf_region(intel); case GL_RGB: if (intel->intelScreen->cpp == 2) return intel_readbuf_region(intel); return NULL; default: return NULL; } }
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; }