static void do_draw_pix( GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height, GLint pitch, const void *pixels, GLuint dest ) { intelContextPtr intel = INTEL_CONTEXT(ctx); __DRIdrawablePrivate *dPriv = intel->driDrawable; drm_clip_rect_t *box = dPriv->pClipRects; int nbox = dPriv->numClipRects; int i; int src_offset = intelAgpOffsetFromVirtual( intel, pixels); int src_pitch = pitch; assert(src_offset != ~0); /* should be caught earlier */ if (INTEL_DEBUG & DEBUG_PIXEL) fprintf(stderr, "%s\n", __FUNCTION__); intelFlush( &intel->ctx ); LOCK_HARDWARE( intel ); if (ctx->DrawBuffer) { y -= height; /* cope with pixel zoom */ if (!clip_pixelrect(ctx, ctx->DrawBuffer, &x, &y, &width, &height)) { UNLOCK_HARDWARE( intel ); return; } y = dPriv->h - y - height; /* convert from gl to hardware coords */ x += dPriv->x; y += dPriv->y; for (i = 0 ; i < nbox ; i++ ) { GLint bx, by, bw, bh; if (intersect_region(box + i, x, y, width, height, &bx, &by, &bw, &bh)) { intelEmitCopyBlitLocked( intel, intel->intelScreen->cpp, src_pitch, src_offset, intel->intelScreen->front.pitch, intel->drawRegion->offset, bx - x, by - y, bx, by, bw, bh ); } } } UNLOCK_HARDWARE( intel ); intelFinish( &intel->ctx ); }
static void do_draw_pix( GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height, GLint pitch, const void *pixels, GLuint dest ) { intelContextPtr intel = INTEL_CONTEXT(ctx); __DRIdrawablePrivate *dPriv = intel->driDrawable; drm_clip_rect_t *box = dPriv->pClipRects; int nbox = dPriv->numClipRects; int i; int size; int src_offset = intelAgpOffsetFromVirtual( intel, pixels); int src_pitch = pitch; if (INTEL_DEBUG & DEBUG_PIXEL) fprintf(stderr, "%s\n", __FUNCTION__); intelFlush( &intel->ctx ); LOCK_HARDWARE( intel ); if (ctx->DrawBuffer) { y -= height; /* cope with pixel zoom */ if (!clip_pixelrect(ctx, ctx->DrawBuffer, &x, &y, &width, &height, &size)) { UNLOCK_HARDWARE( intel ); return; } y = dPriv->h - y - height; /* convert from gl to hardware coords */ x += dPriv->x; y += dPriv->y; for (i = 0 ; i < nbox ; i++ ) { GLint bx = box[i].x1; GLint by = box[i].y1; GLint bw = box[i].x2 - bx; GLint bh = box[i].y2 - by; if (bx < x) bw -= x - bx, bx = x; if (by < y) bh -= y - by, by = y; if (bx + bw > x + width) bw = x + width - bx; if (by + bh > y + height) bh = y + height - by; if (bw <= 0) continue; if (bh <= 0) continue; intelEmitCopyBlitLocked( intel, intel->intelScreen->cpp, src_pitch, src_offset, intel->intelScreen->frontPitch, intel->drawOffset, bx - x, by - y, bx, by, bw, bh ); } } UNLOCK_HARDWARE( intel ); intelFinish( &intel->ctx ); }
static GLboolean intelTryReadPixels( GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, const struct gl_pixelstore_attrib *pack, GLvoid *pixels ) { intelContextPtr intel = INTEL_CONTEXT(ctx); GLint size = 0; /* not really used */ GLint pitch = pack->RowLength ? pack->RowLength : width; if (INTEL_DEBUG & DEBUG_PIXEL) fprintf(stderr, "%s\n", __FUNCTION__); /* Only accelerate reading to agp buffers. */ if ( !intelIsAgpMemory(intel, pixels, pitch * height * intel->intelScreen->cpp ) ) { if (INTEL_DEBUG & DEBUG_PIXEL) fprintf(stderr, "%s: dest not agp\n", __FUNCTION__); return GL_FALSE; } /* Need GL_PACK_INVERT_MESA to cope with upsidedown results from * blitter: */ if (!pack->Invert) { if (INTEL_DEBUG & DEBUG_PIXEL) fprintf(stderr, "%s: MESA_PACK_INVERT not set\n", __FUNCTION__); return GL_FALSE; } if (!check_color(ctx, type, format, pack, pixels, size, pitch)) return GL_FALSE; switch ( intel->intelScreen->cpp ) { case 4: break; default: return GL_FALSE; } /* Although the blits go on the command buffer, need to do this and * fire with lock held to guarentee cliprects and drawing offset are * correct. * * This is an unusual situation however, as the code which flushes * a full command buffer expects to be called unlocked. As a * workaround, immediately flush the buffer on aquiring the lock. */ intelFlush( &intel->ctx ); LOCK_HARDWARE( intel ); { __DRIdrawablePrivate *dPriv = intel->driDrawable; int nbox = dPriv->numClipRects; int src_offset = intel->readRegion->offset; int src_pitch = intel->intelScreen->front.pitch; int dst_offset = intelAgpOffsetFromVirtual( intel, pixels); drm_clip_rect_t *box = dPriv->pClipRects; int i; assert(dst_offset != ~0); /* should have been caught above */ if (!clip_pixelrect(ctx, ctx->ReadBuffer, &x, &y, &width, &height)) { UNLOCK_HARDWARE( intel ); if (INTEL_DEBUG & DEBUG_PIXEL) fprintf(stderr, "%s totally clipped -- nothing to do\n", __FUNCTION__); return GL_TRUE; } /* convert to screen coords (y=0=top) */ y = dPriv->h - y - height; x += dPriv->x; y += dPriv->y; if (INTEL_DEBUG & DEBUG_PIXEL) fprintf(stderr, "readpixel blit src_pitch %d dst_pitch %d\n", src_pitch, pitch); /* We don't really have to do window clipping for readpixels. * The OpenGL spec says that pixels read from outside the * visible window region (pixel ownership) have undefined value. */ for (i = 0 ; i < nbox ; i++) { GLint bx, by, bw, bh; if (intersect_region(box+i, x, y, width, height, &bx, &by, &bw, &bh)) { intelEmitCopyBlitLocked( intel, intel->intelScreen->cpp, src_pitch, src_offset, pitch, dst_offset, bx, by, bx - x, by - y, bw, bh ); } } } UNLOCK_HARDWARE( intel ); intelFinish( &intel->ctx ); return GL_TRUE; }
static GLboolean intelTryReadPixels( GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, const struct gl_pixelstore_attrib *pack, GLvoid *pixels ) { intelContextPtr intel = INTEL_CONTEXT(ctx); GLint size = 0; GLint pitch = pack->RowLength ? pack->RowLength : width; if (INTEL_DEBUG & DEBUG_PIXEL) fprintf(stderr, "%s\n", __FUNCTION__); /* Only accelerate reading to agp buffers. */ if ( !intelIsAgpMemory(intel, pixels, pitch * height * intel->intelScreen->cpp ) ) { if (INTEL_DEBUG & DEBUG_PIXEL) fprintf(stderr, "%s: dest not agp\n", __FUNCTION__); return GL_FALSE; } /* Need GL_PACK_INVERT_MESA to cope with upsidedown results from * blitter: */ if (!pack->Invert) { if (INTEL_DEBUG & DEBUG_PIXEL) fprintf(stderr, "%s: MESA_PACK_INVERT not set\n", __FUNCTION__); return GL_FALSE; } if (!check_color(ctx, type, format, pack, pixels, size, pitch)) return GL_FALSE; switch ( intel->intelScreen->cpp ) { case 4: break; default: return GL_FALSE; } /* Although the blits go on the command buffer, need to do this and * fire with lock held to guarentee cliprects and drawOffset are * correct. * * This is an unusual situation however, as the code which flushes * a full command buffer expects to be called unlocked. As a * workaround, immediately flush the buffer on aquiring the lock. */ intelFlush( &intel->ctx ); LOCK_HARDWARE( intel ); { __DRIdrawablePrivate *dPriv = intel->driDrawable; int nbox = dPriv->numClipRects; int src_offset = intel->drawOffset; int src_pitch = intel->intelScreen->frontPitch; int dst_offset = intelAgpOffsetFromVirtual( intel, pixels); drm_clip_rect_t *box = dPriv->pClipRects; int i; if (!clip_pixelrect(ctx, ctx->ReadBuffer, &x, &y, &width, &height, &size)) { UNLOCK_HARDWARE( intel ); if (INTEL_DEBUG & DEBUG_PIXEL) fprintf(stderr, "%s totally clipped -- nothing to do\n", __FUNCTION__); return GL_TRUE; } y = dPriv->h - y - height; x += dPriv->x; y += dPriv->y; if (INTEL_DEBUG & DEBUG_PIXEL) fprintf(stderr, "readpixel blit src_pitch %d dst_pitch %d\n", src_pitch, pitch); for (i = 0 ; i < nbox ; i++) { GLint bx = box[i].x1; GLint by = box[i].y1; GLint bw = box[i].x2 - bx; GLint bh = box[i].y2 - by; if (bx < x) bw -= x - bx, bx = x; if (by < y) bh -= y - by, by = y; if (bx + bw > x + width) bw = x + width - bx; if (by + bh > y + height) bh = y + height - by; if (bw <= 0) continue; if (bh <= 0) continue; intelEmitCopyBlitLocked( intel, intel->intelScreen->cpp, src_pitch, src_offset, pitch, dst_offset, bx, by, bx - x, by - y, bw, bh ); } } UNLOCK_HARDWARE( intel ); intelFinish( &intel->ctx ); return GL_TRUE; }