示例#1
0
static void i830SetTexBorderColor(i830TextureObjectPtr t, GLubyte color[4])
{
   if(INTEL_DEBUG&DEBUG_DRI)
      fprintf(stderr, "%s\n", __FUNCTION__);

    t->Setup[I830_TEXREG_TM0S4] = 
        INTEL_PACKCOLOR8888(color[0],color[1],color[2],color[3]);
}
示例#2
0
static void
intelClearColor(GLcontext * ctx, const GLfloat color[4])
{
   struct intel_context *intel = intel_context(ctx);
   GLubyte clear[4];

   CLAMPED_FLOAT_TO_UBYTE(clear[0], color[0]);
   CLAMPED_FLOAT_TO_UBYTE(clear[1], color[1]);
   CLAMPED_FLOAT_TO_UBYTE(clear[2], color[2]);
   CLAMPED_FLOAT_TO_UBYTE(clear[3], color[3]);

   /* compute both 32 and 16-bit clear values */
   intel->ClearColor8888 = INTEL_PACKCOLOR8888(clear[0], clear[1],
                                               clear[2], clear[3]);
   intel->ClearColor565 = INTEL_PACKCOLOR565(clear[0], clear[1], clear[2]);
}
示例#3
0
static void i915ImportTexObjState( struct gl_texture_object *texObj )
{   
   i915TextureObjectPtr t = (i915TextureObjectPtr)texObj->DriverData;
   int minFilt = 0, mipFilt = 0, magFilt = 0, shadow = 0;

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

   switch (texObj->MinFilter) {
   case GL_NEAREST:
      minFilt = FILTER_NEAREST;
      mipFilt = MIPFILTER_NONE;
      break;
   case GL_LINEAR:
      minFilt = FILTER_LINEAR;
      mipFilt = MIPFILTER_NONE;
      break;
   case GL_NEAREST_MIPMAP_NEAREST:
      minFilt = FILTER_NEAREST;
      mipFilt = MIPFILTER_NEAREST;
      break;
   case GL_LINEAR_MIPMAP_NEAREST:
      minFilt = FILTER_LINEAR;
      mipFilt = MIPFILTER_NEAREST;
      break;
   case GL_NEAREST_MIPMAP_LINEAR:
      minFilt = FILTER_NEAREST;
      mipFilt = MIPFILTER_LINEAR;
      break;
   case GL_LINEAR_MIPMAP_LINEAR:
      minFilt = FILTER_LINEAR;
      mipFilt = MIPFILTER_LINEAR;
      break;
   default:
      break;
   }

   if ( texObj->MaxAnisotropy > 1.0 ) {
      minFilt = FILTER_ANISOTROPIC; 
      magFilt = FILTER_ANISOTROPIC;
   }
   else {
      switch (texObj->MagFilter) {
      case GL_NEAREST:
	 magFilt = FILTER_NEAREST;
	 break;
      case GL_LINEAR:
	 magFilt = FILTER_LINEAR;
	 break;
      default:
	 break;
      }  
   }

   if (texObj->CompareMode == GL_COMPARE_R_TO_TEXTURE_ARB && 
       texObj->Target != GL_TEXTURE_3D) {

      shadow = SS2_SHADOW_ENABLE;
      shadow |= intel_translate_compare_func( texObj->CompareFunc );
      
      minFilt = FILTER_4X4_FLAT;
      magFilt = FILTER_4X4_FLAT;
   }


   t->Setup[I915_TEXREG_SS2] &= ~(SS2_MIN_FILTER_MASK |
				 SS2_MIP_FILTER_MASK |
				 SS2_MAG_FILTER_MASK |
				 SS2_SHADOW_ENABLE |
				 SS2_SHADOW_FUNC_MASK);
   t->Setup[I915_TEXREG_SS2] |= ((minFilt << SS2_MIN_FILTER_SHIFT) |
				(mipFilt << SS2_MIP_FILTER_SHIFT) |
				(magFilt << SS2_MAG_FILTER_SHIFT) |
				shadow);

   {
      GLuint ss3 = t->Setup[I915_TEXREG_SS3] & ~(SS3_TCX_ADDR_MODE_MASK |
						SS3_TCY_ADDR_MODE_MASK |
						SS3_TCZ_ADDR_MODE_MASK);
      GLenum ws = texObj->WrapS;
      GLenum wt = texObj->WrapT;
      GLenum wr = texObj->WrapR;
      
      t->refs_border_color = 0;

      if (texObj->Target == GL_TEXTURE_3D &&
	  (texObj->MinFilter != GL_NEAREST ||
	   texObj->MagFilter != GL_NEAREST)) {
	 
	 /* Try to mimic GL_CLAMP functionality a little better -
	  * switch to CLAMP_TO_BORDER whenever a non-NEAREST filter is
	  * in use.  Only do this for 3D textures at the moment --
	  * doing it universally would fix the conform texbc.c
	  * failure, though.
	  */
	 if (ws == GL_CLAMP) ws = GL_CLAMP_TO_BORDER;
	 if (wt == GL_CLAMP) wt = GL_CLAMP_TO_BORDER;
	 if (wr == GL_CLAMP) wr = GL_CLAMP_TO_BORDER;

	 /* 3D textures don't seem to respect the border color.
	  * Fallback if there's ever a danger that they might refer to
	  * it.
	  */
	 if (ws == GL_CLAMP_TO_BORDER) t->refs_border_color = 1;
	 if (wt == GL_CLAMP_TO_BORDER) t->refs_border_color = 1;
	 if (wr == GL_CLAMP_TO_BORDER) t->refs_border_color = 1;
      }

      ss3 |= translate_wrap_mode(ws) << SS3_TCX_ADDR_MODE_SHIFT;
      ss3 |= translate_wrap_mode(wt) << SS3_TCY_ADDR_MODE_SHIFT;
      ss3 |= translate_wrap_mode(wr) << SS3_TCZ_ADDR_MODE_SHIFT;
   
      if (ss3 != t->Setup[I915_TEXREG_SS3]) {
	 t->intel.dirty = I915_UPLOAD_TEX_ALL;
	 t->Setup[I915_TEXREG_SS3] = ss3;
      }
   }

   {   
      const GLubyte *color = texObj->_BorderChan;

      t->Setup[I915_TEXREG_SS4] = INTEL_PACKCOLOR8888(color[0],color[1],
						     color[2],color[3]);
   }
}
/* Recalculate all state from scratch.  Perhaps not the most
 * efficient, but this has gotten complex enough that we need
 * something which is understandable and reliable.
 */
static GLboolean
i830_update_tex_unit(struct intel_context *intel, GLuint unit, GLuint ss3)
{
   GLcontext *ctx = &intel->ctx;
   struct i830_context *i830 = i830_context(ctx);
   struct gl_texture_object *tObj = ctx->Texture.Unit[unit]._Current;
   struct intel_texture_object *intelObj = intel_texture_object(tObj);
   struct gl_texture_image *firstImage;
   GLuint *state = i830->state.Tex[unit], format, pitch;

   memset(state, 0, sizeof(state));

   /*We need to refcount these. */

   if (i830->state.tex_buffer[unit] != NULL) {
       dri_bo_unreference(i830->state.tex_buffer[unit]);
       i830->state.tex_buffer[unit] = NULL;
   }

   if (!intelObj->imageOverride && !intel_finalize_mipmap_tree(intel, unit))
      return GL_FALSE;

   /* Get first image here, since intelObj->firstLevel will get set in
    * the intel_finalize_mipmap_tree() call above.
    */
   firstImage = tObj->Image[0][intelObj->firstLevel];

   if (intelObj->imageOverride) {
      i830->state.tex_buffer[unit] = NULL;
      i830->state.tex_offset[unit] = intelObj->textureOffset;

      switch (intelObj->depthOverride) {
      case 32:
	 format = MAPSURF_32BIT | MT_32BIT_ARGB8888;
	 break;
      case 24:
      default:
	 format = MAPSURF_32BIT | MT_32BIT_XRGB8888;
	 break;
      case 16:
	 format = MAPSURF_16BIT | MT_16BIT_RGB565;
	 break;
      }

      pitch = intelObj->pitchOverride;
   } else {
      dri_bo_reference(intelObj->mt->region->buffer);
      i830->state.tex_buffer[unit] = intelObj->mt->region->buffer;
      i830->state.tex_offset[unit] = intel_miptree_image_offset(intelObj->mt,
								0, intelObj->
								firstLevel);

      format = translate_texture_format(firstImage->TexFormat->MesaFormat);
      pitch = intelObj->mt->pitch * intelObj->mt->cpp;
   }

   state[I830_TEXREG_TM0LI] = (_3DSTATE_LOAD_STATE_IMMEDIATE_2 |
                               (LOAD_TEXTURE_MAP0 << unit) | 4);

/*    state[I830_TEXREG_TM0S0] = (TM0S0_USE_FENCE | */
/* 			       t->intel.TextureOffset); */


   state[I830_TEXREG_TM0S1] =
      (((firstImage->Height - 1) << TM0S1_HEIGHT_SHIFT) |
       ((firstImage->Width - 1) << TM0S1_WIDTH_SHIFT) | format);

   state[I830_TEXREG_TM0S2] =
      ((((pitch / 4) - 1) << TM0S2_PITCH_SHIFT) | TM0S2_CUBE_FACE_ENA_MASK);

   {
      if (tObj->Target == GL_TEXTURE_CUBE_MAP)
         state[I830_TEXREG_CUBE] = (_3DSTATE_MAP_CUBE | MAP_UNIT(unit) |
                                    CUBE_NEGX_ENABLE |
                                    CUBE_POSX_ENABLE |
                                    CUBE_NEGY_ENABLE |
                                    CUBE_POSY_ENABLE |
                                    CUBE_NEGZ_ENABLE | CUBE_POSZ_ENABLE);
      else
         state[I830_TEXREG_CUBE] = (_3DSTATE_MAP_CUBE | MAP_UNIT(unit));
   }




   {
      GLuint minFilt, mipFilt, magFilt;

      switch (tObj->MinFilter) {
      case GL_NEAREST:
         minFilt = FILTER_NEAREST;
         mipFilt = MIPFILTER_NONE;
         break;
      case GL_LINEAR:
         minFilt = FILTER_LINEAR;
         mipFilt = MIPFILTER_NONE;
         break;
      case GL_NEAREST_MIPMAP_NEAREST:
         minFilt = FILTER_NEAREST;
         mipFilt = MIPFILTER_NEAREST;
         break;
      case GL_LINEAR_MIPMAP_NEAREST:
         minFilt = FILTER_LINEAR;
         mipFilt = MIPFILTER_NEAREST;
         break;
      case GL_NEAREST_MIPMAP_LINEAR:
         minFilt = FILTER_NEAREST;
         mipFilt = MIPFILTER_LINEAR;
         break;
      case GL_LINEAR_MIPMAP_LINEAR:
         minFilt = FILTER_LINEAR;
         mipFilt = MIPFILTER_LINEAR;
         break;
      default:
         return GL_FALSE;
      }

      if (tObj->MaxAnisotropy > 1.0) {
         minFilt = FILTER_ANISOTROPIC;
         magFilt = FILTER_ANISOTROPIC;
      }
      else {
         switch (tObj->MagFilter) {
         case GL_NEAREST:
            magFilt = FILTER_NEAREST;
            break;
         case GL_LINEAR:
            magFilt = FILTER_LINEAR;
            break;
         default:
            return GL_FALSE;
         }
      }

      state[I830_TEXREG_TM0S3] = i830->lodbias_tm0s3[unit];

#if 0
      /* YUV conversion:
       */
      if (firstImage->TexFormat->MesaFormat == MESA_FORMAT_YCBCR ||
          firstImage->TexFormat->MesaFormat == MESA_FORMAT_YCBCR_REV)
         state[I830_TEXREG_TM0S3] |= SS2_COLORSPACE_CONVERSION;
#endif

      state[I830_TEXREG_TM0S3] |= ((intelObj->lastLevel -
                                    intelObj->firstLevel) *
                                   4) << TM0S3_MIN_MIP_SHIFT;

      state[I830_TEXREG_TM0S3] |= ((minFilt << TM0S3_MIN_FILTER_SHIFT) |
                                   (mipFilt << TM0S3_MIP_FILTER_SHIFT) |
                                   (magFilt << TM0S3_MAG_FILTER_SHIFT));
   }

   {
      GLenum ws = tObj->WrapS;
      GLenum wt = tObj->WrapT;


      /* 3D textures not available on i830
       */
      if (tObj->Target == GL_TEXTURE_3D)
         return GL_FALSE;

      state[I830_TEXREG_MCS] = (_3DSTATE_MAP_COORD_SET_CMD |
                                MAP_UNIT(unit) |
                                ENABLE_TEXCOORD_PARAMS |
                                ss3 |
                                ENABLE_ADDR_V_CNTL |
                                TEXCOORD_ADDR_V_MODE(translate_wrap_mode(wt))
                                | ENABLE_ADDR_U_CNTL |
                                TEXCOORD_ADDR_U_MODE(translate_wrap_mode
                                                     (ws)));
   }


   state[I830_TEXREG_TM0S4] = INTEL_PACKCOLOR8888(tObj->_BorderChan[0],
                                                  tObj->_BorderChan[1],
                                                  tObj->_BorderChan[2],
                                                  tObj->_BorderChan[3]);


   I830_ACTIVESTATE(i830, I830_UPLOAD_TEX(unit), GL_TRUE);
   /* memcmp was already disabled, but definitely won't work as the
    * region might now change and that wouldn't be detected:
    */
   I830_STATECHANGE(i830, I830_UPLOAD_TEX(unit));
   return GL_TRUE;
}
示例#5
0
/*
 * Render a bitmap.
 */
static GLboolean
do_blit_bitmap( GLcontext *ctx, 
		GLint dstx, GLint dsty,
		GLsizei width, GLsizei height,
		const struct gl_pixelstore_attrib *unpack,
		const GLubyte *bitmap )
{
   struct intel_context *intel = intel_context(ctx);
   struct intel_region *dst = intel_drawbuf_region(intel);
   GLfloat tmpColor[4];
   GLubyte ubcolor[4];
   GLuint color8888, color565;

   if (!dst)
       return GL_FALSE;

   if (unpack->BufferObj->Name) {
      bitmap = map_pbo(ctx, width, height, unpack, bitmap);
      if (bitmap == NULL)
	 return GL_TRUE;	/* even though this is an error, we're done */
   }

   COPY_4V(tmpColor, ctx->Current.RasterColor);

   if (NEED_SECONDARY_COLOR(ctx)) {
       ADD_3V(tmpColor, tmpColor, ctx->Current.RasterSecondaryColor);
   }

   UNCLAMPED_FLOAT_TO_UBYTE(ubcolor[0], tmpColor[0]);
   UNCLAMPED_FLOAT_TO_UBYTE(ubcolor[1], tmpColor[1]);
   UNCLAMPED_FLOAT_TO_UBYTE(ubcolor[2], tmpColor[2]);
   UNCLAMPED_FLOAT_TO_UBYTE(ubcolor[3], tmpColor[3]);

   color8888 = INTEL_PACKCOLOR8888(ubcolor[0], ubcolor[1], ubcolor[2], ubcolor[3]);
   color565 = INTEL_PACKCOLOR565(ubcolor[0], ubcolor[1], ubcolor[2]);
 

   /* Does zoom apply to bitmaps?
    */
   if (!intel_check_blit_fragment_ops(ctx) ||
       ctx->Pixel.ZoomX != 1.0F || 
       ctx->Pixel.ZoomY != 1.0F)
      return GL_FALSE;

   LOCK_HARDWARE(intel);

   if (intel->driDrawable->numClipRects) {
      __DRIdrawablePrivate *dPriv = intel->driDrawable;
      drm_clip_rect_t *box = dPriv->pClipRects;
      drm_clip_rect_t dest_rect;
      GLint nbox = dPriv->numClipRects;
      GLint srcx = 0, srcy = 0;
      GLint orig_screen_x1, orig_screen_y2;
      GLuint i;


      orig_screen_x1 = dPriv->x + dstx;
      orig_screen_y2 = dPriv->y + (dPriv->h - dsty);

      /* Do scissoring in GL coordinates:
       */
      if (ctx->Scissor.Enabled)
      {
	 GLint x = ctx->Scissor.X;
	 GLint y = ctx->Scissor.Y;
	 GLuint w = ctx->Scissor.Width;
	 GLuint h = ctx->Scissor.Height;

         if (!_mesa_clip_to_region(x, y, x+w-1, y+h-1, &dstx, &dsty, &width, &height))
            goto out;
      }

      /* Convert from GL to hardware coordinates:
       */
      dsty = dPriv->y + (dPriv->h - dsty - height);  
      dstx = dPriv->x + dstx;

      dest_rect.x1 = dstx < 0 ? 0 : dstx;
      dest_rect.y1 = dsty < 0 ? 0 : dsty;
      dest_rect.x2 = dstx + width < 0 ? 0 : dstx + width;
      dest_rect.y2 = dsty + height < 0 ? 0 : dsty + height;

      for (i = 0; i < nbox; i++) {
         drm_clip_rect_t rect;
	 int box_w, box_h;
	 GLint px, py;
	 GLuint stipple[32];  

         if (!intel_intersect_cliprects(&rect, &dest_rect, &box[i]))
            continue;

	 /* Now go back to GL coordinates to figure out what subset of
	  * the bitmap we are uploading for this cliprect:
	  */
	 box_w = rect.x2 - rect.x1;
	 box_h = rect.y2 - rect.y1;
	 srcx = rect.x1 - orig_screen_x1;
	 srcy = orig_screen_y2 - rect.y2;


#define DY 32
#define DX 32

	 /* Then, finally, chop it all into chunks that can be
	  * digested by hardware:
	  */
	 for (py = 0; py < box_h; py += DY) { 
	    for (px = 0; px < box_w; px += DX) { 
	       int h = MIN2(DY, box_h - py);
	       int w = MIN2(DX, box_w - px); 
	       GLuint sz = ALIGN(ALIGN(w,8) * h, 64)/8;
	       GLenum logic_op = ctx->Color.ColorLogicOpEnabled ?
		  ctx->Color.LogicOp : GL_COPY;

	       assert(sz <= sizeof(stipple));
	       memset(stipple, 0, sz);

	       /* May need to adjust this when padding has been introduced in
		* sz above:
		*/
	       if (get_bitmap_rect(width, height, unpack, 
				   bitmap,
				   srcx + px, srcy + py, w, h,
				   (GLubyte *)stipple,
				   8,
				   GL_TRUE) == 0)
		  continue;

	       /* 
		*/
	       intelEmitImmediateColorExpandBlit( intel,
						  dst->cpp,
						  (GLubyte *)stipple, 
						  sz,
						  (dst->cpp == 2) ? color565 : color8888,
						  dst->pitch,
						  dst->buffer,
						  0,
						  dst->tiled,
						  rect.x1 + px,
						  rect.y2 - (py + h),
						  w, h,
						  logic_op);
	    } 
	 } 
      }
      intel->need_flush = GL_TRUE;
   out:
      intel_batchbuffer_flush(intel->batch);
   }
   UNLOCK_HARDWARE(intel);


   if (unpack->BufferObj->Name) {
      /* done with PBO so unmap it now */
      ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
                              unpack->BufferObj);
   }

   return GL_TRUE;
}