get rid of more cliprects (readpixel)...

This commit is contained in:
Roland Scheidegger
2007-07-16 13:57:49 +02:00
parent d69cae95a0
commit 8b93d9238e
+95 -80
View File
@@ -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 (!src || type != GL_COLOR)
return GL_FALSE;
if (ctx->_ImageTransferState ||
pack->SwapBytes || pack->LsbFirst || !pack->Invert) {
if (INTEL_DEBUG & DEBUG_PIXEL)
fprintf(stderr, "%s: check_color failed\n", __FUNCTION__);
intelFlush(&intel->ctx);
intel->vtbl.install_meta_state(intel);
/* 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);
/* 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);
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;
}
/* 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;
}
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));
return GL_FALSE;
}
intel->vtbl.meta_texture_blend_replace(intel);
LOCK_HARDWARE(intel);
if (intel->numClipRects) {
intel->vtbl.install_meta_state(intel);
intel->vtbl.meta_no_depth_write(intel);
intel->vtbl.meta_no_stencil_write(intel);
{
int dstbufHeight = height * ctx->Pixel.ZoomY; /* ? */
/* convert from gl to hardware coords */
srcy = ctx->ReadBuffer->Height - srcy - height;
/* Clip against the source region. This is the only source
* clipping we do. XXX: Just set the texcord wrap mode to clamp
* or similar.
*
*/
if (0) {
if (!_mesa_clip_to_region(0, 0, ctx->ReadBuffer->Width - 1,
ctx->ReadBuffer->Height - 1,
&srcx, &srcy, &width, &height))
goto out;
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;
}
y = intel->pClipRects->y2 - y - height;
/* Set the frontbuffer up as a large rectangular texture.
/* Just use the regular cliprect mechanism... Does this need to
* even hold the lock???
*/
intel->vtbl.meta_tex_rect_source(intel, src_region, textureFormat);
intel->vtbl.meta_texture_blend_replace(i830, glTextureFormat);
/* Set the 3d engine to draw into the destination region:
*/
intel->vtbl.meta_draw_region(intel, dest_region);
intel->vtbl.meta_draw_format(intel, destFormat, depthFormat); /* ?? */
/* Draw a single quad, no cliprects:
*/
intel->vtbl.meta_disable_cliprects(intel);
intel->vtbl.draw_quad(intel,
0, width, 0, height,
0x00ff00ff, x, x + width, y, y + height);
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);
}