Пример #1
0
/* Called via glXFreeMemoryMESA() */
void intelFreeMemoryMESA(__DRInativeDisplay *dpy, int scrn, GLvoid *pointer)
{
   GET_CURRENT_CONTEXT(ctx);
   if (INTEL_DEBUG & DEBUG_IOCTL) 
      fprintf(stderr, "%s %p\n", __FUNCTION__, pointer);

   if (!ctx || INTEL_CONTEXT(ctx) == 0) {
      fprintf(stderr, "%s: no context\n", __FUNCTION__);
      return;
   }

   intelFreeAGP( INTEL_CONTEXT(ctx), pointer );
}
Пример #2
0
static GLboolean
check_color( const GLcontext *ctx, GLenum type, GLenum format,
	     const struct gl_pixelstore_attrib *packing,
	     const void *pixels, GLint sz, GLint pitch )
{
   intelContextPtr intel = INTEL_CONTEXT(ctx);
   GLuint cpp = intel->intelScreen->cpp;

   if (INTEL_DEBUG & DEBUG_PIXEL)
      fprintf(stderr, "%s\n", __FUNCTION__);

   if (	(pitch & 63) ||
	ctx->_ImageTransferState ||
	packing->SwapBytes ||
	packing->LsbFirst) {
      if (INTEL_DEBUG & DEBUG_PIXEL)
	 fprintf(stderr, "%s: failed 1\n", __FUNCTION__);
      return GL_FALSE;
   }

   if ( type == GL_UNSIGNED_INT_8_8_8_8_REV && 
	cpp == 4 && 
	format == GL_BGRA ) {
      if (INTEL_DEBUG & DEBUG_PIXEL)
	 fprintf(stderr, "%s: passed 2\n", __FUNCTION__);
      return GL_TRUE;
   }

   if (INTEL_DEBUG & DEBUG_PIXEL)
      fprintf(stderr, "%s: failed\n", __FUNCTION__);

   return GL_FALSE;
}
Пример #3
0
static GLboolean i915UpdateTexUnit( GLcontext *ctx, GLuint unit )
{
   struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];

   if (texUnit->_ReallyEnabled &&
       INTEL_CONTEXT(ctx)->intelScreen->tex.size < 2048 * 1024)
      return GL_FALSE;

   switch (texUnit->_ReallyEnabled) {
   case TEXTURE_1D_BIT:
   case TEXTURE_2D_BIT:
      return (enable_tex_2d( ctx, unit ) &&
	      enable_tex_common( ctx, unit ));
   case TEXTURE_RECT_BIT:
      return (enable_tex_rect( ctx, unit ) &&
	      enable_tex_common( ctx, unit ));
   case TEXTURE_CUBE_BIT:
      return (enable_tex_cube( ctx, unit ) &&
	      enable_tex_common( ctx, unit ));
   case TEXTURE_3D_BIT:
       return (enable_tex_2d( ctx, unit ) && 
	       enable_tex_common( ctx, unit ) &&
	       enable_tex_3d( ctx, unit)); 
   case 0:
      return disable_tex( ctx, unit );
   default:
      return GL_FALSE;
   }
}
Пример #4
0
void intelFinish( GLcontext *ctx  ) 
{
   intelContextPtr intel = INTEL_CONTEXT( ctx );
   intelFlush( ctx );
   intelWaitForIdle( intel );
   intelCheckFrontRotate(ctx);
}
Пример #5
0
static void intelRenderPrimitive( GLcontext *ctx, GLenum prim )
{
   intelContextPtr intel = INTEL_CONTEXT(ctx);

   if (0)
      fprintf(stderr, "%s %s\n", __FUNCTION__, _mesa_lookup_enum_by_nr(prim));

   /* Let some clipping routines know which primitive they're dealing
    * with.
    */
   intel->render_primitive = prim;

   /* Shortcircuit this when called from t_dd_rendertmp.h for unfilled
    * triangles.  The rasterized primitive will always be reset by
    * lower level functions in that case, potentially pingponging the
    * state:
    */
   if (reduced_prim[prim] == GL_TRIANGLES && 
       (ctx->_TriangleCaps & DD_TRI_UNFILLED))
      return;

   /* Set some primitive-dependent state and Start? a new primitive.
    */
   intelRasterPrimitive( ctx, reduced_prim[prim], hw_prim[prim] );
}
Пример #6
0
/* Move locking out to get reasonable span performance.
 */
void intelSpanRenderStart( GLcontext *ctx )
{
   intelContextPtr intel = INTEL_CONTEXT(ctx);

   intelFlush(&intel->ctx);
   LOCK_HARDWARE(intel);
   intelWaitForIdle(intel);
}
Пример #7
0
/* This version of AllocateMemoryMESA allocates only agp memory, and
 * only does so after the point at which the driver has been
 * initialized.
 *
 * Theoretically a valid context isn't required.  However, in this
 * implementation, it is, as I'm using the hardware lock to protect
 * the kernel data structures, and the current context to get the
 * device fd.
 */
void *intelAllocateMemoryMESA(__DRInativeDisplay *dpy, int scrn,
			      GLsizei size, GLfloat readfreq,
			      GLfloat writefreq, GLfloat priority)
{
   GET_CURRENT_CONTEXT(ctx);

   if (INTEL_DEBUG & DEBUG_IOCTL)
      fprintf(stderr, "%s sz %d %f/%f/%f\n", __FUNCTION__, size, readfreq, 
	      writefreq, priority);

   if (getenv("INTEL_NO_ALLOC"))
      return NULL;
   
   if (!ctx || INTEL_CONTEXT(ctx) == 0) 
      return NULL;
   
   return intelAllocateAGP( INTEL_CONTEXT(ctx), size );
}
Пример #8
0
void intelDestroyBatchBuffer( GLcontext *ctx )
{
   intelContextPtr intel = INTEL_CONTEXT(ctx);

   if (intel->alloc.ptr) {
      intelFreeAGP( intel, intel->alloc.ptr );
      intel->alloc.ptr = 0;
   }
}
Пример #9
0
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 );
}
Пример #10
0
/**
 * Check if we need to rotate/warp the front color buffer to the
 * rotated screen.  We generally need to do this when we get a glFlush
 * or glFinish after drawing to the front color buffer.
 */
static void
intelCheckFrontRotate(GLcontext *ctx)
{
   intelContextPtr intel = INTEL_CONTEXT( ctx );
   if (intel->ctx.DrawBuffer->_ColorDrawBufferMask[0] == BUFFER_BIT_FRONT_LEFT) {
      intelScreenPrivate *screen = intel->intelScreen;
      if (screen->current_rotation != 0) {
         __DRIdrawablePrivate *dPriv = intel->driDrawable;
         intelRotateWindow(intel, dPriv, BUFFER_BIT_FRONT_LEFT);
      }
   }
}
Пример #11
0
/**
 * NOT directly called via glFlush.
 */
void intelFlush( GLcontext *ctx )
{
   intelContextPtr intel = INTEL_CONTEXT( ctx );

   if (intel->Fallback)
      _swrast_flush( ctx );

   INTEL_FIREVERTICES( intel );

   if (intel->batch.size != intel->batch.space)
      intelFlushBatch( intel, GL_FALSE );
}
Пример #12
0
static void intel_flush_inline_primitive( GLcontext *ctx )
{
   intelContextPtr intel = INTEL_CONTEXT( ctx );
   GLuint used = intel->batch.ptr - intel->prim.start_ptr;
   GLuint vertcount;

   assert(intel->prim.primitive != ~0);

   if (1) {
      /* Check vertex size against the vertex we're specifying to
       * hardware.  If it's wrong, ditch the primitive.
       */ 
      if (!intel->vtbl.check_vertex_size( intel, intel->vertex_size )) 
	 goto do_discard;

      vertcount = (used - 4)/ (intel->vertex_size * 4);

      if (!vertcount)
	 goto do_discard;
      
      if (vertcount * intel->vertex_size * 4 != used - 4) {
	 fprintf(stderr, "vertex size confusion %d %d\n", used, 
		 intel->vertex_size * vertcount * 4);
	 goto do_discard;
      }

      if (bad_prim_vertex_nr( intel->prim.primitive, vertcount )) {
	 fprintf(stderr, "bad_prim_vertex_nr %x %d\n", intel->prim.primitive,
		 vertcount);
	 goto do_discard;
      }
   }

   if (used < 8)
      goto do_discard;

   *(int *)intel->prim.start_ptr = (_3DPRIMITIVE | 
				    intel->prim.primitive |
				    (used/4-2));

   goto finished;
   
 do_discard:
   intel->batch.ptr -= used;
   intel->batch.space += used;
   assert(intel->batch.space >= 0);

 finished:
   intel->prim.primitive = ~0;
   intel->prim.start_ptr = 0;
   intel->prim.flush = 0;
}
Пример #13
0
/*
 * This function is called to specify which buffer to read and write
 * for software rasterization (swrast) fallbacks.  This doesn't necessarily
 * correspond to glDrawBuffer() or glReadBuffer() calls.
 */
static void intelSetBuffer(GLcontext *ctx, GLframebuffer *colorBuffer,
                          GLuint bufferBit)
{
   intelContextPtr intel = INTEL_CONTEXT(ctx);
   if (bufferBit == BUFFER_BIT_FRONT_LEFT) {
      intel->drawMap = (char *)intel->driScreen->pFB;
      intel->readMap = (char *)intel->driScreen->pFB;
   } else if (bufferBit == BUFFER_BIT_BACK_LEFT) {
      intel->drawMap = intel->intelScreen->back.map;
      intel->readMap = intel->intelScreen->back.map;
   } else {
      ASSERT(0);
   }
}
Пример #14
0
 /* System to flush dma and emit state changes based on the rasterized
  * primitive.
  */
static void intelRasterPrimitive( GLcontext *ctx, GLenum rprim, GLuint hwprim )
{
   intelContextPtr intel = INTEL_CONTEXT(ctx);

   if (0)
      fprintf(stderr, "%s %s %x\n", __FUNCTION__, 
	      _mesa_lookup_enum_by_nr(rprim), hwprim);

   intel->vtbl.reduced_primitive_state( intel, rprim );
    
   /* Start a new primitive.  Arrange to have it flushed later on.
    */
   if (hwprim != intel->prim.primitive) 
      intelStartInlinePrimitive( intel, hwprim );
}
Пример #15
0
static void intelFastRenderClippedPoly( GLcontext *ctx, const GLuint *elts,
				       GLuint n )
{
   intelContextPtr intel = INTEL_CONTEXT( ctx );
   const GLuint vertsize = intel->vertex_size;
   GLuint *vb = intelExtendInlinePrimitive( intel, (n-2) * 3 * vertsize );
   GLubyte *vertptr = (GLubyte *)intel->verts;
   const GLuint *start = (const GLuint *)V(elts[0]);
   int i,j;

   for (i = 2 ; i < n ; i++) {
      COPY_DWORDS( j, vb, vertsize, V(elts[i-1]) );
      COPY_DWORDS( j, vb, vertsize, V(elts[i]) );
      COPY_DWORDS( j, vb, vertsize, start );
   }
}
Пример #16
0
/* Called via glXGetMemoryOffsetMESA() 
 *
 * Returns offset of pointer from the start of agp aperture.
 */
GLuint intelGetMemoryOffsetMESA(__DRInativeDisplay *dpy, int scrn, 
				const GLvoid *pointer)
{
   GET_CURRENT_CONTEXT(ctx);
   intelContextPtr intel;

   if (!ctx || !(intel = INTEL_CONTEXT(ctx)) ) {
      fprintf(stderr, "%s: no context\n", __FUNCTION__);
      return ~0;
   }

   if (!intelIsAgpMemory( intel, pointer, 0 ))
      return ~0;

   return intelAgpOffsetFromVirtual( intel, pointer );
}
Пример #17
0
void intelInitBatchBuffer( GLcontext *ctx )
{
   intelContextPtr intel = INTEL_CONTEXT(ctx);

   if (!intel->intelScreen->allow_batchbuffer || getenv("INTEL_NO_BATCH")) {
      intel->alloc.size = 8 * 1024;
      intel->alloc.ptr = malloc( intel->alloc.size );
      intel->alloc.offset = 0;
   }
   else {
      switch (intel->intelScreen->deviceID) {
      case PCI_CHIP_I865_G:
	 /* HW bug?  Seems to crash if batchbuffer crosses 4k boundary.
	  */
	 intel->alloc.size = 8 * 1024; 
	 break;
      default:
	 /* This is the smallest amount of memory the kernel deals with.
	  * We'd ideally like to make this smaller.
	  */
	 intel->alloc.size = 1 << intel->intelScreen->logTextureGranularity;
	 break;
      }

      intel->alloc.ptr = intelAllocateAGP( intel, intel->alloc.size );
      if (intel->alloc.ptr)
	 intel->alloc.offset = 
	    intelAgpOffsetFromVirtual( intel, intel->alloc.ptr );
   }

   if (!intel->alloc.ptr) {
      FALLBACK(intel, INTEL_FALLBACK_NO_BATCHBUFFER, 1);
   }
   else {
      intel->prim.flush = 0;
      intel->vtbl.emit_invarient_state( intel );

      /* Make sure this gets to the hardware, even if we have no cliprects:
       */
      LOCK_HARDWARE( intel );
      intelFlushBatchLocked( intel, GL_TRUE, GL_FALSE, GL_TRUE );
      UNLOCK_HARDWARE( intel );
   }
}
Пример #18
0
static void intelRunPipeline( GLcontext *ctx )
{
   intelContextPtr intel = INTEL_CONTEXT(ctx);

   if (intel->NewGLState) {
      if (intel->NewGLState & _NEW_TEXTURE) {
	 intel->vtbl.update_texture_state( intel ); 
      }

      if (!intel->Fallback) {
	 if (intel->NewGLState & _INTEL_NEW_RENDERSTATE)
	    intelChooseRenderState( ctx );
      }

      intel->NewGLState = 0;
   }

   _tnl_run_pipeline( ctx );
}
Пример #19
0
static GLboolean
clip_pixelrect( const GLcontext *ctx,
		const GLframebuffer *buffer,
		GLint *x, GLint *y,
		GLsizei *width, GLsizei *height,
		GLint *size )
{
   intelContextPtr intel = INTEL_CONTEXT(ctx);

   /* left clipping */
   if (*x < buffer->_Xmin) {
      *width -= (buffer->_Xmin - *x);
      *x = buffer->_Xmin;
   }

   /* right clipping */
   if (*x + *width > buffer->_Xmax)
      *width -= (*x + *width - buffer->_Xmax - 1);

   if (*width <= 0)
      return GL_FALSE;

   /* bottom clipping */
   if (*y < buffer->_Ymin) {
      *height -= (buffer->_Ymin - *y);
      *y = buffer->_Ymin;
   }

   /* top clipping */
   if (*y + *height > buffer->_Ymax)
      *height -= (*y + *height - buffer->_Ymax - 1);

   if (*height <= 0)
      return GL_FALSE;

   *size = ((*y + *height - 1) * intel->intelScreen->frontPitch +
	    (*x + *width - 1) * intel->intelScreen->cpp);

   return GL_TRUE;
}
Пример #20
0
static void intelRenderClippedPoly( GLcontext *ctx, const GLuint *elts,
				   GLuint n )
{
   intelContextPtr intel = INTEL_CONTEXT(ctx);
   TNLcontext *tnl = TNL_CONTEXT(ctx);
   struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
   GLuint prim = intel->render_primitive;

   /* Render the new vertices as an unclipped polygon.
    */
   {
      GLuint *tmp = VB->Elts;
      VB->Elts = (GLuint *)elts;
      tnl->Driver.Render.PrimTabElts[GL_POLYGON]( ctx, 0, n, 
						  PRIM_BEGIN|PRIM_END );
      VB->Elts = tmp;
   }

   /* Restore the render primitive
    */
   if (prim != GL_POLYGON)
      tnl->Driver.Render.PrimitiveNotify( ctx, prim );
}
Пример #21
0
static void intelRenderFinish( GLcontext *ctx )
{
   if (INTEL_CONTEXT(ctx)->RenderIndex & INTEL_FALLBACK_BIT)
      _swrast_flush( ctx );
}
Пример #22
0
static void intelRenderStart( GLcontext *ctx )
{
   INTEL_CONTEXT(ctx)->vtbl.render_start( INTEL_CONTEXT(ctx) );
}
Пример #23
0
void intelClearWithBlit(GLcontext *ctx, GLbitfield flags, GLboolean all,
		      GLint cx1, GLint cy1, GLint cw, GLint ch)
{
   intelContextPtr intel = INTEL_CONTEXT( ctx );
   intelScreenPrivate *intelScreen = intel->intelScreen;
   GLuint clear_depth, clear_color;
   GLint cx, cy;
   GLint pitch = intelScreen->frontPitch;
   GLint cpp = intelScreen->cpp;
   GLint i;
   GLuint BR13, CMD, D_CMD;
   BATCH_LOCALS;

   
   clear_color = intel->ClearColor;
   clear_depth = 0;

   if (flags & BUFFER_BIT_DEPTH) {
      clear_depth = (GLuint)(ctx->Depth.Clear * intel->ClearDepth);
   }

   if (flags & BUFFER_BIT_STENCIL) {
      clear_depth |= (ctx->Stencil.Clear & 0xff) << 24;
   }

   switch(cpp) {
   case 2: 
      BR13 = (0xF0 << 16) | (pitch * cpp) | (1<<24);
      D_CMD = CMD = XY_COLOR_BLT_CMD;
      break;
   case 4:
      BR13 = (0xF0 << 16) | (pitch * cpp) | (1<<24) | (1<<25);
      CMD = (XY_COLOR_BLT_CMD |
	     XY_COLOR_BLT_WRITE_ALPHA | 
	     XY_COLOR_BLT_WRITE_RGB);
      D_CMD = XY_COLOR_BLT_CMD;
      if (flags & BUFFER_BIT_DEPTH) D_CMD |= XY_COLOR_BLT_WRITE_RGB;
      if (flags & BUFFER_BIT_STENCIL) D_CMD |= XY_COLOR_BLT_WRITE_ALPHA;
      break;
   default:
      BR13 = (0xF0 << 16) | (pitch * cpp) | (1<<24);
      D_CMD = CMD = XY_COLOR_BLT_CMD;
      break;
   }

   intelFlush( &intel->ctx );
   LOCK_HARDWARE( intel );
   {
      /* flip top to bottom */
      cy = intel->driDrawable->h-cy1-ch;
      cx = cx1 + intel->drawX;
      cy += intel->drawY;

      /* adjust for page flipping */
      if ( intel->sarea->pf_current_page == 1 ) {
	 GLuint tmp = flags;

	 flags &= ~(BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_BACK_LEFT);
	 if ( tmp & BUFFER_BIT_FRONT_LEFT ) flags |= BUFFER_BIT_BACK_LEFT;
	 if ( tmp & BUFFER_BIT_BACK_LEFT )  flags |= BUFFER_BIT_FRONT_LEFT;
      }

      for (i = 0 ; i < intel->numClipRects ; i++) 
      { 	 
	 drm_clip_rect_t *box = &intel->pClipRects[i];	 
	 drm_clip_rect_t b;

	 if (!all) {
	    GLint x = box[i].x1;
	    GLint y = box[i].y1;
	    GLint w = box[i].x2 - x;
	    GLint h = box[i].y2 - y;

	    if (x < cx) w -= cx - x, x = cx; 
	    if (y < cy) h -= cy - y, y = cy;
	    if (x + w > cx + cw) w = cx + cw - x;
	    if (y + h > cy + ch) h = cy + ch - y;
	    if (w <= 0) continue;
	    if (h <= 0) continue;

	    b.x1 = x;
	    b.y1 = y;
	    b.x2 = x + w;
	    b.y2 = y + h;      
	 } else {
	    b = *box;
	 }


	 if (b.x1 > b.x2 ||
	     b.y1 > b.y2 ||
	     b.x2 > intelScreen->width ||
	     b.y2 > intelScreen->height)
	    continue;

	 if ( flags & BUFFER_BIT_FRONT_LEFT ) {	    
	    BEGIN_BATCH( 6);	    
	    OUT_BATCH( CMD );
	    OUT_BATCH( BR13 );
	    OUT_BATCH( (b.y1 << 16) | b.x1 );
	    OUT_BATCH( (b.y2 << 16) | b.x2 );
	    OUT_BATCH( intelScreen->frontOffset );
	    OUT_BATCH( clear_color );
	    ADVANCE_BATCH();
	 }

	 if ( flags & BUFFER_BIT_BACK_LEFT ) {
	    BEGIN_BATCH( 6); 
	    OUT_BATCH( CMD );
	    OUT_BATCH( BR13 );
	    OUT_BATCH( (b.y1 << 16) | b.x1 );
	    OUT_BATCH( (b.y2 << 16) | b.x2 );
	    OUT_BATCH( intelScreen->backOffset );
	    OUT_BATCH( clear_color );
	    ADVANCE_BATCH();
	 }

	 if ( flags & (BUFFER_BIT_STENCIL | BUFFER_BIT_DEPTH) ) {
	    BEGIN_BATCH( 6);
	    OUT_BATCH( D_CMD );
	    OUT_BATCH( BR13 );
	    OUT_BATCH( (b.y1 << 16) | b.x1 );
	    OUT_BATCH( (b.y2 << 16) | b.x2 );
	    OUT_BATCH( intelScreen->depthOffset );
	    OUT_BATCH( clear_depth );
	    ADVANCE_BATCH();
	 }      
      }
   }
   intelFlushBatchLocked( intel, GL_TRUE, GL_FALSE, GL_TRUE );
   UNLOCK_HARDWARE( intel );
}
Пример #24
0
void intelChooseRenderState(GLcontext *ctx)
{
   TNLcontext *tnl = TNL_CONTEXT(ctx);
   intelContextPtr intel = INTEL_CONTEXT(ctx);
   GLuint flags = ctx->_TriangleCaps;
   const struct gl_fragment_program *fprog = ctx->FragmentProgram._Current;
   GLboolean have_wpos = (fprog && (fprog->Base.InputsRead & FRAG_BIT_WPOS));
   GLuint index = 0;

   if (INTEL_DEBUG & DEBUG_STATE)
     fprintf(stderr,"\n%s\n",__FUNCTION__);

   if ((flags & (ANY_FALLBACK_FLAGS|ANY_RASTER_FLAGS)) || have_wpos) {

      if (flags & ANY_RASTER_FLAGS) {
	 if (flags & DD_TRI_LIGHT_TWOSIDE)    index |= INTEL_TWOSIDE_BIT;
	 if (flags & DD_TRI_OFFSET)	      index |= INTEL_OFFSET_BIT;
	 if (flags & DD_TRI_UNFILLED)	      index |= INTEL_UNFILLED_BIT;
      }

      if (have_wpos) {
	 intel->draw_point = intel_wpos_point;
	 intel->draw_line = intel_wpos_line;
	 intel->draw_tri = intel_wpos_triangle;

	 /* Make sure these get called:
	  */
	 index |= INTEL_FALLBACK_BIT;
      }
      else {
	 intel->draw_point = intel_draw_point;
	 intel->draw_line = intel_draw_line;
	 intel->draw_tri = intel_draw_triangle;
      }

      /* Hook in fallbacks for specific primitives.
       */
      if (flags & ANY_FALLBACK_FLAGS)
      {
	 if (flags & POINT_FALLBACK)
	    intel->draw_point = intel_fallback_point;

	 if (flags & LINE_FALLBACK)
	    intel->draw_line = intel_fallback_line;

	 if (flags & TRI_FALLBACK)
	    intel->draw_tri = intel_fallback_tri;

	 if ((flags & DD_TRI_STIPPLE) && !intel->hw_stipple) 
	    intel->draw_tri = intel_fallback_tri;

	 if (flags & DD_POINT_ATTEN)
	    intel->draw_point = intel_atten_point;

	 index |= INTEL_FALLBACK_BIT;
      }
   }

   if (intel->RenderIndex != index) {
      intel->RenderIndex = index;

      tnl->Driver.Render.Points = rast_tab[index].points;
      tnl->Driver.Render.Line = rast_tab[index].line;
      tnl->Driver.Render.Triangle = rast_tab[index].triangle;
      tnl->Driver.Render.Quad = rast_tab[index].quad;

      if (index == 0) {
	 tnl->Driver.Render.PrimTabVerts = intel_render_tab_verts;
	 tnl->Driver.Render.PrimTabElts = intel_render_tab_elts;
	 tnl->Driver.Render.ClippedLine = line; /* from tritmp.h */
	 tnl->Driver.Render.ClippedPolygon = intelFastRenderClippedPoly;
      } else {
	 tnl->Driver.Render.PrimTabVerts = _tnl_render_tab_verts;
	 tnl->Driver.Render.PrimTabElts = _tnl_render_tab_elts;
	 tnl->Driver.Render.ClippedLine = intelRenderClippedLine;
	 tnl->Driver.Render.ClippedPolygon = intelRenderClippedPoly;
      }
   }
}
Пример #25
0
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 );
}
Пример #26
0
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;
}
Пример #27
0
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;
}
Пример #28
0
static GLboolean
intelTryDrawPixels( 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);
   GLint pitch = unpack->RowLength ? unpack->RowLength : width;
   GLuint dest;
   GLuint cpp = intel->intelScreen->cpp;
   GLint size = width * pitch * cpp;

   if (INTEL_DEBUG & DEBUG_PIXEL)
      fprintf(stderr, "%s\n", __FUNCTION__);

   switch (format) {
   case GL_RGB:
   case GL_RGBA:
   case GL_BGRA:
      dest = intel->drawRegion->offset;

      /* Planemask doesn't have full support in blits.
       */
      if (!ctx->Color.ColorMask[RCOMP] ||
	  !ctx->Color.ColorMask[GCOMP] ||
	  !ctx->Color.ColorMask[BCOMP] ||
	  !ctx->Color.ColorMask[ACOMP]) {
	 if (INTEL_DEBUG & DEBUG_PIXEL)
	    fprintf(stderr, "%s: planemask\n", __FUNCTION__);
	 return GL_FALSE;	
      }

      /* Can't do conversions on agp reads/draws. 
       */
      if ( !intelIsAgpMemory( intel, pixels, size ) ) {
	 if (INTEL_DEBUG & DEBUG_PIXEL)
	    fprintf(stderr, "%s: not agp memory\n", __FUNCTION__);
	 return GL_FALSE;
      }

      if (!check_color(ctx, type, format, unpack, pixels, size, pitch)) {
	 return GL_FALSE;
      }
      if (!check_color_per_fragment_ops(ctx)) {
	 return GL_FALSE;
      }

      if (ctx->Pixel.ZoomX != 1.0F ||
	  ctx->Pixel.ZoomY != -1.0F)
	 return GL_FALSE;
      break;

   default:
      return GL_FALSE;
   }

   if ( intelIsAgpMemory(intel, pixels, size) )
   {
      do_draw_pix( ctx, x, y, width, height, pitch, pixels, dest );
      return GL_TRUE;
   }
   else if (0)
   {
      /* Pixels is in regular memory -- get dma buffers and perform
       * upload through them.  No point doing this for regular uploads
       * but once we remove some of the restrictions above (colormask,
       * pixelformat conversion, zoom?, etc), this could be a win.
       */
   }
   else
      return GL_FALSE;

   return GL_FALSE;
}
Пример #29
0
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;
}
Пример #30
0
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;
}