diff options
-rw-r--r-- | src/mesa/drivers/dri/i915tex/intel_pixel_read.c | 167 |
1 files changed, 91 insertions, 76 deletions
diff --git a/src/mesa/drivers/dri/i915tex/intel_pixel_read.c b/src/mesa/drivers/dri/i915tex/intel_pixel_read.c index c41ca33f8f5..76a6959625e 100644 --- a/src/mesa/drivers/dri/i915tex/intel_pixel_read.c +++ b/src/mesa/drivers/dri/i915tex/intel_pixel_read.c @@ -42,6 +42,8 @@ #include "intel_regions.h" #include "intel_pixel.h" #include "intel_buffer_objects.h" +#include "intel_fbo.h" +#include "intel_tris.h" /* For many applications, the new ability to pull the source buffers * back out of the GTT and then do the packing/conversion operations @@ -54,6 +56,8 @@ * an argument for blit/texture readpixels, or for blitting to a * temporary and then pulling that back. * + * XXX this is not true for fake frontbuffers... + * When the destination is a pbo, however, it's not clear if it is * ever going to be pulled to main memory (though the access param * will be a good hint). So it sounds like we do want to be able to @@ -68,88 +72,105 @@ static GLboolean do_texture_readpixels(GLcontext * ctx, - GLint x, GLint y, GLsizei width, GLsizei height, + GLint srcx, GLint srcy, GLsizei width, GLsizei height, GLenum format, GLenum type, const struct gl_pixelstore_attrib *pack, struct intel_region *dest_region) { #if 0 struct intel_context *intel = intel_context(ctx); - intelScreenPrivate *screen = intel->intelScreen; - GLint pitch = pack->RowLength ? pack->RowLength : width; - int textureFormat; - GLenum glTextureFormat; - int destFormat, depthFormat, destPitch; - drm_clip_rect_t tmp; + struct intel_region *depthreg = NULL; + struct intel_region *src = intel_readbuf_region(intel); +// struct intel_region *src = copypix_src_region(intel, type); + GLenum src_format; + GLenum src_type; if (INTEL_DEBUG & DEBUG_PIXEL) fprintf(stderr, "%s\n", __FUNCTION__); - - if (ctx->_ImageTransferState || - pack->SwapBytes || pack->LsbFirst || !pack->Invert) { - if (INTEL_DEBUG & DEBUG_PIXEL) - fprintf(stderr, "%s: check_color failed\n", __FUNCTION__); - return GL_FALSE; - } - - intel->vtbl.meta_texrect_source(intel, intel_readbuf_region(intel)); - - if (!intel->vtbl.meta_render_dest(intel, dest_region, type, format)) { - if (INTEL_DEBUG & DEBUG_PIXEL) - fprintf(stderr, "%s: couldn't set dest %s/%s\n", - __FUNCTION__, - _mesa_lookup_enum_by_nr(type), - _mesa_lookup_enum_by_nr(format)); + if (!src || type != GL_COLOR) return GL_FALSE; - } - LOCK_HARDWARE(intel); + intelFlush(&intel->ctx); - if (intel->numClipRects) { - intel->vtbl.install_meta_state(intel); - intel->vtbl.meta_no_depth_write(intel); - intel->vtbl.meta_no_stencil_write(intel); + intel->vtbl.install_meta_state(intel); - if (!driClipRectToFramebuffer(ctx->ReadBuffer, &x, &y, &width, &height)) { - UNLOCK_HARDWARE(intel); - SET_STATE(i830, state); - if (INTEL_DEBUG & DEBUG_PIXEL) - fprintf(stderr, "%s: cliprect failed\n", __FUNCTION__); - return GL_TRUE; - } + /* Is this true? Also will need to turn depth testing on according + * to state: + */ + intel->vtbl.meta_no_stencil_write(intel); + intel->vtbl.meta_no_depth_write(intel); - y = intel->pClipRects->y2 - y - height; + /* Set the 3d engine to draw into the destination region: + */ + if (ctx->DrawBuffer->_DepthBuffer && + ctx->DrawBuffer->_DepthBuffer->Wrapped) + depthreg = (intel_renderbuffer(ctx->DrawBuffer->_DepthBuffer->Wrapped))->region; + intel->vtbl.meta_draw_region(intel, dest_region, depthreg); - /* Set the frontbuffer up as a large rectangular texture. - */ - intel->vtbl.meta_tex_rect_source(intel, src_region, textureFormat); + intel->vtbl.meta_import_pixel_state(intel); + if (src->cpp == 2) { + src_format = GL_RGB; + src_type = GL_UNSIGNED_SHORT_5_6_5; + } + else { + src_format = GL_BGRA; + src_type = GL_UNSIGNED_BYTE; + } - intel->vtbl.meta_texture_blend_replace(i830, glTextureFormat); + /* Set the frontbuffer up as a large rectangular texture. + */ + if (!intel->vtbl.meta_tex_rect_source(intel, src->buffer, 0, + src->pitch, + src->height, src_format, src_type)) { + intel->vtbl.leave_meta_state(intel); + return GL_FALSE; + } - /* Set the 3d engine to draw into the destination region: - */ + intel->vtbl.meta_texture_blend_replace(intel); - intel->vtbl.meta_draw_region(intel, dest_region); - intel->vtbl.meta_draw_format(intel, destFormat, depthFormat); /* ?? */ + LOCK_HARDWARE(intel); + { + int dstbufHeight = height * ctx->Pixel.ZoomY; /* ? */ + /* convert from gl to hardware coords */ + srcy = ctx->ReadBuffer->Height - srcy - height; - /* Draw a single quad, no cliprects: + /* Clip against the source region. This is the only source + * clipping we do. XXX: Just set the texcord wrap mode to clamp + * or similar. + * */ - intel->vtbl.meta_disable_cliprects(intel); + if (0) { + if (!_mesa_clip_to_region(0, 0, ctx->ReadBuffer->Width - 1, + ctx->ReadBuffer->Height - 1, + &srcx, &srcy, &width, &height)) + goto out; - intel->vtbl.draw_quad(intel, - 0, width, 0, height, - 0x00ff00ff, x, x + width, y, y + height); + } + /* Just use the regular cliprect mechanism... Does this need to + * even hold the lock??? + */ + intel_meta_draw_quad(intel, + 0, + width * ctx->Pixel.ZoomX, + dstbufHeight - (height * ctx->Pixel.ZoomY), + dstbufHeight, 0, /* XXX: what z value? */ + 0x00ff00ff, + srcx, srcx + width, srcy, srcy + height); + + out: intel->vtbl.leave_meta_state(intel); + intel_batchbuffer_flush(intel->batch); } UNLOCK_HARDWARE(intel); - intel_region_wait_fence(ctx, dest_region); /* required by GL */ + if (INTEL_DEBUG & DEBUG_PIXEL) + _mesa_printf("%s: success\n", __FUNCTION__); return GL_TRUE; #endif @@ -166,7 +187,8 @@ do_blit_readpixels(GLcontext * ctx, 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_renderbuffer *irbread; + struct intel_region *src; struct intel_buffer_object *dst = intel_buffer_object(pack->BufferObj); GLuint dst_offset; GLuint rowLength; @@ -175,8 +197,10 @@ do_blit_readpixels(GLcontext * ctx, if (INTEL_DEBUG & DEBUG_PIXEL) _mesa_printf("%s\n", __FUNCTION__); - if (!src) + irbread = intel_renderbuffer(ctx->ReadBuffer->_ColorReadBuffer); + if (!irbread || !irbread->region) return GL_FALSE; + src = irbread->region; if (dst) { /* XXX This validation should be done by core mesa: @@ -228,44 +252,35 @@ do_blit_readpixels(GLcontext * ctx, dst_offset = (GLuint) _mesa_image_address(2, pack, pixels, width, height, format, type, 0, 0, 0); - /* reading from priv buffer, cliprects should not change */ intelFlush(&intel->ctx); - if (intel->numClipRects) { - assert (intel->numClipRects == 1); + { + GLint srcx = x; + GLint srcy = irbread->Base.Height - (y + height); + GLint srcwidth = width; + GLint srcheight = height; + GLboolean all = (width * height * src->cpp == dst->Base.Size && x == 0 && dst_offset == 0); struct _DriBufferObject *dst_buffer = intel_bufferobj_buffer(intel, dst, all ? INTEL_WRITE_FULL : INTEL_WRITE_PART); - int nbox = intel->numClipRects; - drm_clip_rect_t *box = intel->pClipRects; - drm_clip_rect_t rect; - drm_clip_rect_t src_rect; - int i; - - src_rect.x1 = x; - src_rect.y1 = box->y2 - (y + height); - src_rect.x2 = src_rect.x1 + width; - src_rect.y2 = src_rect.y1 + height; - - - for (i = 0; i < nbox; i++) { - if (!intel_intersect_cliprects(&rect, &src_rect, &box[i])) - continue; + /* clip to src region */ + if (_mesa_clip_to_region(0, 0, irbread->Base.Width - 1, + irbread->Base.Height - 1, + &srcx, &srcy, &srcwidth, &srcheight)); + { intelEmitCopyBlit(intel, src->cpp, src->pitch, src->buffer, 0, rowLength, dst_buffer, dst_offset, - rect.x1, - rect.y1, - rect.x1 - src_rect.x1, - rect.y2 - src_rect.y2, - rect.x2 - rect.x1, rect.y2 - rect.y1, + srcx, srcy, + 0, 0, + width, height, GL_COPY); } |