/** * Prepare for softare rendering. Map current read/draw framebuffers' * renderbuffes and all currently bound texture objects. * * Old note: Moved locking out to get reasonable span performance. */ void intelSpanRenderStart(GLcontext * ctx) { struct intel_context *intel = intel_context(ctx); GLuint i; intelFinish(&intel->ctx); LOCK_HARDWARE(intel); #if 0 /* Just map the framebuffer and all textures. Bufmgr code will * take care of waiting on the necessary fences: */ intel_region_map(intel->intelScreen, intel->front_region); intel_region_map(intel->intelScreen, intel->back_region); intel_region_map(intel->intelScreen, intel->intelScreen->depth_region); #endif for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++) { if (ctx->Texture.Unit[i]._ReallyEnabled) { struct gl_texture_object *texObj = ctx->Texture.Unit[i]._Current; intel_tex_map_images(intel, intel_texture_object(texObj)); } } intel_map_unmap_buffers(intel, GL_TRUE); }
void brw_draw_prims( GLcontext *ctx, const struct gl_client_array *arrays[], const struct _mesa_prim *prim, GLuint nr_prims, const struct _mesa_index_buffer *ib, GLuint min_index, GLuint max_index ) { struct intel_context *intel = intel_context(ctx); GLboolean retval; /* Decide if we want to rebase. If so we end up recursing once * only into this function. */ if (brw_need_rebase( ctx, arrays, ib, min_index )) { vbo_rebase_prims( ctx, arrays, prim, nr_prims, ib, min_index, max_index, brw_draw_prims ); return; } /* Make a first attempt at drawing: */ retval = brw_try_draw_prims(ctx, arrays, prim, nr_prims, ib, min_index, max_index); /* This looks like out-of-memory but potentially we have * situation where there is enough memory but it has become * fragmented. Clear out all heaps and start from scratch by * faking a contended lock event: (done elsewhere) */ if (!retval && !intel->Fallback && bmError(intel)) { DBG("retrying\n"); /* Then try a second time only to upload textures and draw the * primitives: */ retval = brw_try_draw_prims(ctx, arrays, prim, nr_prims, ib, min_index, max_index); } /* Otherwise, we really are out of memory. Pass the drawing * command to the software tnl module and which will in turn call * swrast to do the drawing. */ if (!retval) { _swsetup_Wakeup(ctx); _tnl_draw_prims(ctx, arrays, prim, nr_prims, ib, min_index, max_index); } if (intel->aub_file && (INTEL_DEBUG & DEBUG_SYNC)) { intelFinish( &intel->ctx ); intel->aub_wrap = 1; } }
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 ); }
GLboolean i830TryTextureDrawPixels( GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, const struct gl_pixelstore_attrib *unpack, const GLvoid *pixels ) { intelContextPtr intel = INTEL_CONTEXT(ctx); i830ContextPtr i830 = I830_CONTEXT(ctx); GLint pitch = unpack->RowLength ? unpack->RowLength : width; __DRIdrawablePrivate *dPriv = intel->driDrawable; int textureFormat; GLenum glTextureFormat; int dst_offset = i830->meta.Buffer[I830_DESTREG_CBUFADDR2]; int src_offset = intelAgpOffsetFromVirtual( intel, pixels ); if (INTEL_DEBUG & DEBUG_PIXEL) fprintf(stderr, "%s\n", __FUNCTION__); /* Todo -- upload images that aren't in agp space, then texture * from them. */ if ( !intelIsAgpMemory( intel, pixels, pitch*height ) ) { fprintf(stderr, "%s: intelIsAgpMemory failed\n", __FUNCTION__); return GL_FALSE; } /* Todo -- don't want to clobber all the drawing state like we do * for readpixels -- most of this state can be handled just fine. */ if ( ctx->_ImageTransferState || unpack->SwapBytes || unpack->LsbFirst || ctx->Color.AlphaEnabled || ctx->Depth.Test || ctx->Fog.Enabled || ctx->Scissor.Enabled || ctx->Stencil.Enabled || !ctx->Color.ColorMask[0] || !ctx->Color.ColorMask[1] || !ctx->Color.ColorMask[2] || !ctx->Color.ColorMask[3] || ctx->Color.ColorLogicOpEnabled || ctx->Texture._EnabledUnits || ctx->Depth.OcclusionTest) { fprintf(stderr, "%s: other tests failed\n", __FUNCTION__); return GL_FALSE; } /* Todo -- remove these restrictions: */ if (ctx->Pixel.ZoomX != 1.0F || ctx->Pixel.ZoomY != -1.0F) return GL_FALSE; switch (type) { case GL_UNSIGNED_SHORT_1_5_5_5_REV: if (format != GL_BGRA) return GL_FALSE; textureFormat = MAPSURF_16BIT | MT_16BIT_ARGB1555; glTextureFormat = GL_RGBA; break; case GL_UNSIGNED_SHORT_5_6_5: if (format != GL_RGB) return GL_FALSE; textureFormat = MAPSURF_16BIT | MT_16BIT_RGB565; glTextureFormat = GL_RGB; break; case GL_UNSIGNED_SHORT_8_8_MESA: if (format != GL_YCBCR_MESA) return GL_FALSE; textureFormat = (MAPSURF_422 | MT_422_YCRCB_SWAPY /* | TM0S1_COLORSPACE_CONVERSION */ ); glTextureFormat = GL_YCBCR_MESA; break; case GL_UNSIGNED_SHORT_8_8_REV_MESA: if (format != GL_YCBCR_MESA) return GL_FALSE; textureFormat = (MAPSURF_422 | MT_422_YCRCB_NORMAL /* | TM0S1_COLORSPACE_CONVERSION */ ); glTextureFormat = GL_YCBCR_MESA; break; case GL_UNSIGNED_INT_8_8_8_8_REV: if (format != GL_BGRA) return GL_FALSE; textureFormat = MAPSURF_32BIT | MT_32BIT_ARGB8888; glTextureFormat = GL_RGBA; break; default: fprintf(stderr, "%s: destFormat failed\n", __FUNCTION__); return GL_FALSE; } intelFlush( ctx ); SET_STATE( i830, meta ); LOCK_HARDWARE( intel ); { intelWaitForIdle( intel ); /* required by GL */ y -= height; /* cope with pixel zoom */ if (!driClipRectToFramebuffer(ctx->ReadBuffer, &x, &y, &width, &height)) { UNLOCK_HARDWARE( intel ); SET_STATE(i830, state); fprintf(stderr, "%s: cliprect failed\n", __FUNCTION__); return GL_TRUE; } y = dPriv->h - y - height; set_initial_state( i830 ); /* Set the pixel image up as a rectangular texture. */ set_tex_rect_source( i830, src_offset, width, height, pitch, /* XXXX!!!! -- /2 sometimes */ textureFormat ); enable_texture_blend_replace( i830 ); /* Draw to the current draw buffer: */ set_draw_offset( i830, dst_offset ); /* Draw a quad, use regular cliprects */ /* fprintf(stderr, "x: %d y: %d width %d height %d\n", x, y, width, height); */ draw_quad( i830, x, x+width, y, y+height, 0, 255, 0, 0, 0, width, 0, height ); intelWindowMoved( intel ); } UNLOCK_HARDWARE( intel ); intelFinish( ctx ); /* required by GL */ SET_STATE(i830, state); return GL_TRUE; }
GLboolean i830TryTextureReadPixels( GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, const struct gl_pixelstore_attrib *pack, GLvoid *pixels ) { i830ContextPtr i830 = I830_CONTEXT(ctx); intelContextPtr intel = INTEL_CONTEXT(ctx); intelScreenPrivate *screen = i830->intel.intelScreen; GLint pitch = pack->RowLength ? pack->RowLength : width; __DRIdrawablePrivate *dPriv = i830->intel.driDrawable; int textureFormat; GLenum glTextureFormat; int src_offset = i830->meta.Buffer[I830_DESTREG_CBUFADDR2]; int destOffset = intelAgpOffsetFromVirtual( &i830->intel, pixels); int destFormat, depthFormat, destPitch; drm_clip_rect_t tmp; if (INTEL_DEBUG & DEBUG_PIXEL) fprintf(stderr, "%s\n", __FUNCTION__); if ( ctx->_ImageTransferState || pack->SwapBytes || pack->LsbFirst || !pack->Invert) { fprintf(stderr, "%s: check_color failed\n", __FUNCTION__); return GL_FALSE; } switch (screen->fbFormat) { case DV_PF_565: textureFormat = MAPSURF_16BIT | MT_16BIT_RGB565; glTextureFormat = GL_RGB; break; case DV_PF_555: textureFormat = MAPSURF_16BIT | MT_16BIT_ARGB1555; glTextureFormat = GL_RGBA; break; case DV_PF_8888: textureFormat = MAPSURF_32BIT | MT_32BIT_ARGB8888; glTextureFormat = GL_RGBA; break; default: fprintf(stderr, "%s: textureFormat failed %x\n", __FUNCTION__, screen->fbFormat); return GL_FALSE; } switch (type) { case GL_UNSIGNED_SHORT_5_6_5: if (format != GL_RGB) return GL_FALSE; destFormat = COLR_BUF_RGB565; depthFormat = DEPTH_FRMT_16_FIXED; destPitch = pitch * 2; break; case GL_UNSIGNED_INT_8_8_8_8_REV: if (format != GL_BGRA) return GL_FALSE; destFormat = COLR_BUF_ARGB8888; depthFormat = DEPTH_FRMT_24_FIXED_8_OTHER; destPitch = pitch * 4; break; default: fprintf(stderr, "%s: destFormat failed %s\n", __FUNCTION__, _mesa_lookup_enum_by_nr(type)); return GL_FALSE; } destFormat |= (0x02<<24); /* fprintf(stderr, "type: %s destFormat: %x\n", */ /* _mesa_lookup_enum_by_nr(type), */ /* destFormat); */ intelFlush( ctx ); SET_STATE( i830, meta ); set_initial_state( i830 ); set_no_depth_stencil_write( i830 ); LOCK_HARDWARE( intel ); { intelWaitForIdle( intel ); /* required by GL */ if (!driClipRectToFramebuffer(ctx->ReadBuffer, &x, &y, &width, &height)) { UNLOCK_HARDWARE( intel ); SET_STATE(i830, state); fprintf(stderr, "%s: cliprect failed\n", __FUNCTION__); return GL_TRUE; } #if 0 /* FIXME -- Just emit the correct state */ if (i830SetParam(i830->driFd, I830_SETPARAM_CBUFFER_PITCH, destPitch) != 0) { UNLOCK_HARDWARE( intel ); SET_STATE(i830, state); fprintf(stderr, "%s: setparam failed\n", __FUNCTION__); return GL_FALSE; } #endif y = dPriv->h - y - height; x += dPriv->x; y += dPriv->y; /* Set the frontbuffer up as a large rectangular texture. */ set_tex_rect_source( i830, src_offset, screen->width, screen->height, screen->front.pitch, textureFormat ); enable_texture_blend_replace( i830 ); /* Set the 3d engine to draw into the agp memory */ set_draw_region( i830, destOffset ); set_draw_format( i830, destFormat, depthFormat ); /* Draw a single quad, no cliprects: */ i830->intel.numClipRects = 1; i830->intel.pClipRects = &tmp; i830->intel.pClipRects[0].x1 = 0; i830->intel.pClipRects[0].y1 = 0; i830->intel.pClipRects[0].x2 = width; i830->intel.pClipRects[0].y2 = height; draw_quad( i830, 0, width, 0, height, 0, 255, 0, 0, x, x+width, y, y+height ); intelWindowMoved( intel ); } UNLOCK_HARDWARE( intel ); intelFinish( ctx ); /* required by GL */ SET_STATE( i830, state ); 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; /* 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 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; 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; }