示例#1
0
文件: texutil.c 项目: wwzbwwzb/fbdri
static void
unconvert_teximage_argb8888( struct gl_texture_convert *convert )
{
   const GLubyte *src = (const GLubyte *)convert->srcImage;
   GLint texels, i;

   texels = convert->width * convert->height * convert->depth;

   switch ( convert->format ) {
   case GL_RGBA: {
      GLuint *dst = (GLuint *)convert->dstImage;
      for ( i = 0 ; i < texels ; i++ ) {
	 *dst++ = PACK_COLOR_8888( src[3], src[0], src[1], src[2] );
	 src += 4;
      }
      break;
   }
   case GL_RGB: {
      GLubyte *dst = (GLubyte *)convert->dstImage;
      for ( i = 0 ; i < texels ; i++ ) {
	 *dst++ = src[2];
	 *dst++ = src[1];
	 *dst++ = src[0];
	 src += 4;
      }
      break;
   }
   default:
      gl_problem(NULL, "texture unconvert error");
   }
}
示例#2
0
static void nv30ClearColor(GLcontext *ctx, const GLfloat color[4])
{
	nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
	GLubyte c[4];
	UNCLAMPED_FLOAT_TO_RGBA_CHAN(c,color);
	BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_CLEAR_VALUE_ARGB, 1);
	OUT_RING_CACHE(PACK_COLOR_8888(c[3],c[0],c[1],c[2]));
}
示例#3
0
static void mgaSetTexBorderColor(mgaTextureObjectPtr t, const GLfloat color[4])
{
   GLubyte c[4];
   CLAMPED_FLOAT_TO_UBYTE(c[0], color[0]);
   CLAMPED_FLOAT_TO_UBYTE(c[1], color[1]);
   CLAMPED_FLOAT_TO_UBYTE(c[2], color[2]);
   CLAMPED_FLOAT_TO_UBYTE(c[3], color[3]);
   t->setup.texbordercol = PACK_COLOR_8888(c[3], c[0], c[1], c[2] );
}
示例#4
0
static void nv30BlendColor(GLcontext *ctx, const GLfloat color[4])
{
	nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); 
	GLubyte cf[4];

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

	BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_BLEND_COLOR, 1);
	OUT_RING_CACHE(PACK_COLOR_8888(cf[3], cf[1], cf[2], cf[0]));
}
示例#5
0
文件: mgatex.c 项目: aosm/X11
static void mgaDDTexEnv( GLcontext *ctx, GLenum target,
			 GLenum pname, const GLfloat *param )
{
   GLuint unit = ctx->Texture.CurrentUnit;
   struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
   mgaContextPtr mmesa = MGA_CONTEXT(ctx);

   switch( pname ) {
   case GL_TEXTURE_ENV_COLOR: {
      GLubyte c[4];

      UNCLAMPED_FLOAT_TO_RGBA_CHAN( c, texUnit->EnvColor );
      mmesa->envcolor[unit] = PACK_COLOR_8888( c[3], c[0], c[1], c[2] );
      break;
   }
   }
}
示例#6
0
/**
 * Handle a common case of drawing GL_RGBA/GL_UNSIGNED_BYTE into a
 * MESA_FORMAT_ARGB888 or MESA_FORMAT_xRGB888 renderbuffer.
 */
static void
fast_draw_rgba_ubyte_pixels(struct gl_context *ctx,
                           struct gl_renderbuffer *rb,
                           GLint x, GLint y,
                           GLsizei width, GLsizei height,
                           const struct gl_pixelstore_attrib *unpack,
                           const GLvoid *pixels)
{
   const GLubyte *src = (const GLubyte *)
      _mesa_image_address2d(unpack, pixels, width,
                            height, GL_RGBA, GL_UNSIGNED_BYTE, 0, 0);
   const GLint srcRowStride =
      _mesa_image_row_stride(unpack, width, GL_RGBA, GL_UNSIGNED_BYTE);
   GLint i, j;
   GLubyte *dst;
   GLint dstRowStride;

   ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height,
                               GL_MAP_WRITE_BIT, &dst, &dstRowStride);

   if (!dst) {
      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glDrawPixels");
      return;
   }

   if (ctx->Pixel.ZoomY == -1.0f) {
      dst = dst + (height - 1) * dstRowStride;
      dstRowStride = -dstRowStride;
   }

   for (i = 0; i < height; i++) {
      GLuint *dst4 = (GLuint *) dst;
      for (j = 0; j < width; j++) {
         dst4[j] = PACK_COLOR_8888(src[j*4+3], src[j*4+0],
                                   src[j*4+1], src[j*4+2]);
      }
      dst += dstRowStride;
      src += srcRowStride;
   }

   ctx->Driver.UnmapRenderbuffer(ctx, rb);
}
示例#7
0
/**
 * Use blitting to clear the renderbuffers named by 'flags'.
 * Note: we can't use the ctx->DrawBuffer->_ColorDrawBufferIndexes field
 * since that might include software renderbuffers or renderbuffers
 * which we're clearing with triangles.
 * \param mask  bitmask of BUFFER_BIT_* values indicating buffers to clear
 */
GLbitfield
intelClearWithBlit(struct gl_context *ctx, GLbitfield mask)
{
   struct intel_context *intel = intel_context(ctx);
   struct gl_framebuffer *fb = ctx->DrawBuffer;
   GLuint clear_depth_value, clear_depth_mask;
   GLint cx, cy, cw, ch;
   GLbitfield fail_mask = 0;
   BATCH_LOCALS;

   /* Note: we don't use this function on Gen7+ hardware, so we can safely
    * ignore fast color clear issues.
    */
   assert(intel->gen < 7);

   /*
    * Compute values for clearing the buffers.
    */
   clear_depth_value = 0;
   clear_depth_mask = 0;
   if (mask & BUFFER_BIT_DEPTH) {
      clear_depth_value = (GLuint) (fb->_DepthMax * ctx->Depth.Clear);
      clear_depth_mask = XY_BLT_WRITE_RGB;
   }
   if (mask & BUFFER_BIT_STENCIL) {
      clear_depth_value |= (ctx->Stencil.Clear & 0xff) << 24;
      clear_depth_mask |= XY_BLT_WRITE_ALPHA;
   }

   cx = fb->_Xmin;
   if (_mesa_is_winsys_fbo(fb))
      cy = ctx->DrawBuffer->Height - fb->_Ymax;
   else
      cy = fb->_Ymin;
   cw = fb->_Xmax - fb->_Xmin;
   ch = fb->_Ymax - fb->_Ymin;

   if (cw == 0 || ch == 0)
      return 0;

   /* Loop over all renderbuffers */
   mask &= (1 << BUFFER_COUNT) - 1;
   while (mask) {
      GLuint buf = ffs(mask) - 1;
      bool is_depth_stencil = buf == BUFFER_DEPTH || buf == BUFFER_STENCIL;
      struct intel_renderbuffer *irb;
      int x1, y1, x2, y2;
      uint32_t clear_val;
      uint32_t BR13, CMD;
      struct intel_region *region;
      int pitch, cpp;
      drm_intel_bo *aper_array[2];

      mask &= ~(1 << buf);

      irb = intel_get_renderbuffer(fb, buf);
      if (irb && irb->mt) {
	 region = irb->mt->region;
	 assert(region);
	 assert(region->bo);
      } else {
         fail_mask |= 1 << buf;
         continue;
      }

      /* OK, clear this renderbuffer */
      x1 = cx + irb->draw_x;
      y1 = cy + irb->draw_y;
      x2 = cx + cw + irb->draw_x;
      y2 = cy + ch + irb->draw_y;

      pitch = region->pitch;
      cpp = region->cpp;

      DBG("%s dst:buf(%p)/%d %d,%d sz:%dx%d\n",
	  __FUNCTION__,
	  region->bo, pitch,
	  x1, y1, x2 - x1, y2 - y1);

      BR13 = 0xf0 << 16;
      CMD = XY_COLOR_BLT_CMD;

      /* Setup the blit command */
      if (cpp == 4) {
	 if (is_depth_stencil) {
	    CMD |= clear_depth_mask;
	 } else {
	    /* clearing RGBA */
	    CMD |= XY_BLT_WRITE_ALPHA | XY_BLT_WRITE_RGB;
	 }
      }

      assert(region->tiling != I915_TILING_Y);

      BR13 |= pitch;

      if (is_depth_stencil) {
	 clear_val = clear_depth_value;
      } else {
	 uint8_t clear[4];
	 GLfloat *color = ctx->Color.ClearColor.f;

	 _mesa_unclamped_float_rgba_to_ubyte(clear, color);

	 switch (intel_rb_format(irb)) {
	 case MESA_FORMAT_ARGB8888:
	 case MESA_FORMAT_XRGB8888:
	    clear_val = PACK_COLOR_8888(clear[3], clear[0],
					clear[1], clear[2]);
	    break;
	 case MESA_FORMAT_RGB565:
	    clear_val = PACK_COLOR_565(clear[0], clear[1], clear[2]);
	    break;
	 case MESA_FORMAT_ARGB4444:
	    clear_val = PACK_COLOR_4444(clear[3], clear[0],
					clear[1], clear[2]);
	    break;
	 case MESA_FORMAT_ARGB1555:
	    clear_val = PACK_COLOR_1555(clear[3], clear[0],
					clear[1], clear[2]);
	    break;
	 case MESA_FORMAT_A8:
	    clear_val = PACK_COLOR_8888(clear[3], clear[3],
					clear[3], clear[3]);
	    break;
	 default:
	    fail_mask |= 1 << buf;
	    continue;
	 }
      }

      BR13 |= br13_for_cpp(cpp);

      assert(x1 < x2);
      assert(y1 < y2);

      /* do space check before going any further */
      aper_array[0] = intel->batch.bo;
      aper_array[1] = region->bo;

      if (drm_intel_bufmgr_check_aperture_space(aper_array,
						ARRAY_SIZE(aper_array)) != 0) {
	 intel_batchbuffer_flush(intel);
      }

      BEGIN_BATCH(6);
      OUT_BATCH(CMD | (6 - 2));
      OUT_BATCH(BR13);
      OUT_BATCH((y1 << 16) | x1);
      OUT_BATCH((y2 << 16) | x2);
      OUT_RELOC_FENCED(region->bo,
		       I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER,
		       0);
      OUT_BATCH(clear_val);
      ADVANCE_BATCH();

      if (intel->always_flush_cache)
	 intel_batchbuffer_emit_mi_flush(intel);

      if (buf == BUFFER_DEPTH || buf == BUFFER_STENCIL)
	 mask &= ~(BUFFER_BIT_DEPTH | BUFFER_BIT_STENCIL);
   }

   return fail_mask;
}
示例#8
0
/*
 * Render a bitmap.
 */
static bool
do_blit_bitmap( struct gl_context *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 gl_framebuffer *fb = ctx->DrawBuffer;
   struct intel_renderbuffer *irb;
   GLfloat tmpColor[4];
   GLubyte ubcolor[4];
   GLuint color;
   GLsizei bitmap_width = width;
   GLsizei bitmap_height = height;
   GLint px, py;
   GLuint stipple[32];
   GLint orig_dstx = dstx;
   GLint orig_dsty = dsty;

   /* Update draw buffer bounds */
   _mesa_update_state(ctx);

   if (ctx->Depth.Test) {
      /* The blit path produces incorrect results when depth testing is on.
       * It seems the blit Z coord is always 1.0 (the far plane) so fragments
       * will likely be obscured by other, closer geometry.
       */
      return false;
   }

   intel_prepare_render(intel);

   if (fb->_NumColorDrawBuffers != 1) {
      perf_debug("accelerated glBitmap() only supports rendering to a "
                 "single color buffer\n");
      return false;
   }

   irb = intel_renderbuffer(fb->_ColorDrawBuffers[0]);

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

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

   if (_mesa_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]);

   switch (irb->mt->format) {
   case MESA_FORMAT_B8G8R8A8_UNORM:
   case MESA_FORMAT_B8G8R8X8_UNORM:
      color = PACK_COLOR_8888(ubcolor[3], ubcolor[0], ubcolor[1], ubcolor[2]);
      break;
   case MESA_FORMAT_B5G6R5_UNORM:
      color = PACK_COLOR_565(ubcolor[0], ubcolor[1], ubcolor[2]);
      break;
   default:
      perf_debug("Unsupported format %s in accelerated glBitmap()\n",
                 _mesa_get_format_name(irb->mt->format));
      return false;
   }

   if (!intel_check_blit_fragment_ops(ctx, tmpColor[3] == 1.0F))
      return false;

   /* Clip to buffer bounds and scissor. */
   if (!_mesa_clip_to_region(fb->_Xmin, fb->_Ymin,
			     fb->_Xmax, fb->_Ymax,
			     &dstx, &dsty, &width, &height))
      goto out;

   dsty = y_flip(fb, dsty, height);

#define DY 32
#define DX 32

   /* Chop it all into chunks that can be digested by hardware: */
   for (py = 0; py < height; py += DY) {
      for (px = 0; px < width; px += DX) {
	 int h = MIN2(DY, height - py);
	 int w = MIN2(DX, width - 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:
	  *
	  * Have to translate destination coordinates back into source
	  * coordinates.
	  */
         int count = get_bitmap_rect(bitmap_width, bitmap_height, unpack,
                                     bitmap,
                                     -orig_dstx + (dstx + px),
                                     -orig_dsty + y_flip(fb, dsty + py, h),
                                     w, h,
                                     (GLubyte *)stipple,
                                     8,
                                     _mesa_is_winsys_fbo(fb));
         if (count == 0)
	    continue;

	 if (!intelEmitImmediateColorExpandBlit(intel,
						irb->mt->cpp,
						(GLubyte *)stipple,
						sz,
						color,
						irb->mt->region->pitch,
						irb->mt->region->bo,
						0,
						irb->mt->region->tiling,
						dstx + px,
						dsty + py,
						w, h,
						logic_op)) {
	    return false;
	 }

         if (ctx->Query.CurrentOcclusionObject)
            ctx->Query.CurrentOcclusionObject->Result += count;
      }
   }
out:

   if (unlikely(INTEL_DEBUG & DEBUG_SYNC))
      intel_batchbuffer_flush(intel);

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

   intel_check_front_buffer_rendering(intel);

   return true;
}
示例#9
0
文件: mgatex.c 项目: aosm/X11
static void mgaSetTexBorderColor(mgaTextureObjectPtr t, GLubyte color[4])
{
   t->setup.texbordercol = PACK_COLOR_8888(color[3], color[0], 
					   color[1], color[2] );
}
示例#10
0
/* Returns 0 if a software fallback is necessary */
static GLboolean
sis_set_texobj_parm( struct gl_context *ctx, struct gl_texture_object *texObj,
   int hw_unit )
{
   sisContextPtr smesa = SIS_CONTEXT(ctx);
   int ok = 1;

   __GLSiSHardware *prev = &smesa->prev;
   __GLSiSHardware *current = &smesa->current;

   sisTexObjPtr t = texObj->DriverData;

   GLint firstLevel, lastLevel;
   GLint i;

   current->texture[hw_unit].hwTextureMip = 0UL;
   current->texture[hw_unit].hwTextureSet = t->hwformat;

   if ((texObj->MinFilter == GL_NEAREST) || (texObj->MinFilter == GL_LINEAR)) {
      firstLevel = lastLevel = texObj->BaseLevel;
   } else {
      /* Compute which mipmap levels we really want to send to the hardware.
       * This depends on the base image size, GL_TEXTURE_MIN_LOD,
       * GL_TEXTURE_MAX_LOD, GL_TEXTURE_BASE_LEVEL and GL_TEXTURE_MAX_LEVEL.
       * Yes, this looks overly complicated, but it's all needed.
       */

      firstLevel = texObj->BaseLevel + (GLint)(texObj->MinLod + 0.5);
      firstLevel = MAX2(firstLevel, texObj->BaseLevel);
      lastLevel = texObj->BaseLevel + (GLint)(texObj->MaxLod + 0.5);
      lastLevel = MAX2(lastLevel, texObj->BaseLevel);
      lastLevel = MIN2(lastLevel, texObj->BaseLevel +
         texObj->Image[0][texObj->BaseLevel]->MaxLog2);
      lastLevel = MIN2(lastLevel, texObj->MaxLevel);
      lastLevel = MAX2(firstLevel, lastLevel); /* need at least one level */
   }

   current->texture[hw_unit].hwTextureSet |= (lastLevel << 8);

   switch (texObj->MagFilter)
   {
   case GL_NEAREST:
      current->texture[hw_unit].hwTextureMip |= TEXTURE_FILTER_NEAREST;
      break;
   case GL_LINEAR:
      current->texture[hw_unit].hwTextureMip |= (TEXTURE_FILTER_LINEAR << 3);
      break;
   }

   {
      GLint b;

      /* The mipmap lod biasing is based on experiment.  It seems there's a
       * limit of around +4/-4 to the bias value; we're being conservative.
       */
      b = (GLint) (ctx->Texture.Unit[hw_unit].LodBias * 32.0);
      if (b > 127)
         b = 127;
      else if (b < -128)
         b = -128;

      current->texture[hw_unit].hwTextureMip |= ((b << 4) &
         MASK_TextureMipmapLodBias);
   }

   switch (texObj->MinFilter)
   {
   case GL_NEAREST:
      current->texture[hw_unit].hwTextureMip |= TEXTURE_FILTER_NEAREST;
      break;
   case GL_LINEAR:
      current->texture[hw_unit].hwTextureMip |= TEXTURE_FILTER_LINEAR;
      break;
   case GL_NEAREST_MIPMAP_NEAREST:
      current->texture[hw_unit].hwTextureMip |=
         TEXTURE_FILTER_NEAREST_MIP_NEAREST;
      break;
   case GL_NEAREST_MIPMAP_LINEAR:
      current->texture[hw_unit].hwTextureMip |=
         TEXTURE_FILTER_NEAREST_MIP_LINEAR;
      break;
   case GL_LINEAR_MIPMAP_NEAREST:
      current->texture[hw_unit].hwTextureMip |=
         TEXTURE_FILTER_LINEAR_MIP_NEAREST;
      break;
   case GL_LINEAR_MIPMAP_LINEAR:
      current->texture[hw_unit].hwTextureMip |=
         TEXTURE_FILTER_LINEAR_MIP_LINEAR;
      break;
   }

   switch (texObj->WrapS)
   {
   case GL_REPEAT:
      current->texture[hw_unit].hwTextureSet |= MASK_TextureWrapU;
      break;
   case GL_MIRRORED_REPEAT:
      current->texture[hw_unit].hwTextureSet |= MASK_TextureMirrorU;
      break;
   case GL_CLAMP:
      current->texture[hw_unit].hwTextureSet |= MASK_TextureClampU;
       /* XXX: GL_CLAMP isn't conformant, but falling back makes the situation
        * worse in other programs at the moment.
        */
      /*ok = 0;*/
      break;
   case GL_CLAMP_TO_EDGE:
      current->texture[hw_unit].hwTextureSet |= MASK_TextureClampU;
      break;
   case GL_CLAMP_TO_BORDER:
      current->texture[hw_unit].hwTextureSet |= MASK_TextureBorderU;
      break;
   }

   switch (texObj->WrapT)
   {
   case GL_REPEAT:
      current->texture[hw_unit].hwTextureSet |= MASK_TextureWrapV;
      break;
   case GL_MIRRORED_REPEAT:
      current->texture[hw_unit].hwTextureSet |= MASK_TextureMirrorV;
      break;
   case GL_CLAMP:
      current->texture[hw_unit].hwTextureSet |= MASK_TextureClampV;
       /* XXX: GL_CLAMP isn't conformant, but falling back makes the situation
        * worse in other programs at the moment.
        */
      /*ok = 0;*/
      break;
   case GL_CLAMP_TO_EDGE:
      current->texture[hw_unit].hwTextureSet |= MASK_TextureClampV;
      break;
   case GL_CLAMP_TO_BORDER:
      current->texture[hw_unit].hwTextureSet |= MASK_TextureBorderV;
      break;
   }

   {
      GLubyte c[4];
      CLAMPED_FLOAT_TO_UBYTE(c[0], texObj->BorderColor.f[0]);
      CLAMPED_FLOAT_TO_UBYTE(c[1], texObj->BorderColor.f[1]);
      CLAMPED_FLOAT_TO_UBYTE(c[2], texObj->BorderColor.f[2]);
      CLAMPED_FLOAT_TO_UBYTE(c[3], texObj->BorderColor.f[3]);

      current->texture[hw_unit].hwTextureBorderColor = 
         PACK_COLOR_8888(c[3], c[0], c[1], c[2]);
   }

   if (current->texture[hw_unit].hwTextureBorderColor !=
       prev->texture[hw_unit].hwTextureBorderColor) 
   {
      prev->texture[hw_unit].hwTextureBorderColor =
         current->texture[hw_unit].hwTextureBorderColor; 
      if (hw_unit == 1)
         smesa->GlobalFlag |= GFLAG_TEXBORDERCOLOR_1; 
      else
         smesa->GlobalFlag |= GFLAG_TEXBORDERCOLOR;
   }

   current->texture[hw_unit].hwTextureSet |=
      texObj->Image[0][firstLevel]->WidthLog2 << 4;
   current->texture[hw_unit].hwTextureSet |=
      texObj->Image[0][firstLevel]->HeightLog2;

   if (hw_unit == 0)
      smesa->GlobalFlag |= GFLAG_TEXTUREADDRESS;
   else
      smesa->GlobalFlag |= GFLAG_TEXTUREADDRESS_1;

   for (i = firstLevel; i <= lastLevel; i++)
   {
      GLuint texOffset = 0;
      GLuint texPitch = TransferTexturePitch( t->image[i].pitch );

      switch (t->image[i].memType)
      {
      case VIDEO_TYPE:
         texOffset = ((unsigned long)t->image[i].Data - (unsigned long)smesa->FbBase);
         break;
      case AGP_TYPE:
         texOffset = ((unsigned long)t->image[i].Data - (unsigned long)smesa->AGPBase) +
            (unsigned long) smesa->AGPAddr;
         current->texture[hw_unit].hwTextureMip |=
            (MASK_TextureLevel0InSystem << i);
         break;
      }

      switch (i)
      {
      case 0:
         prev->texture[hw_unit].texOffset0 = texOffset;
         prev->texture[hw_unit].texPitch01 = texPitch << 16;
         break;
      case 1:
         prev->texture[hw_unit].texOffset1 = texOffset;
         prev->texture[hw_unit].texPitch01 |= texPitch;
         break;
      case 2:
         prev->texture[hw_unit].texOffset2 = texOffset;
         prev->texture[hw_unit].texPitch23 = texPitch << 16;
         break;
      case 3:
         prev->texture[hw_unit].texOffset3 = texOffset;
         prev->texture[hw_unit].texPitch23 |= texPitch;
         break;
      case 4:
         prev->texture[hw_unit].texOffset4 = texOffset;
         prev->texture[hw_unit].texPitch45 = texPitch << 16;
         break;
      case 5:
         prev->texture[hw_unit].texOffset5 = texOffset;
         prev->texture[hw_unit].texPitch45 |= texPitch;
         break;
      case 6:
         prev->texture[hw_unit].texOffset6 = texOffset;
         prev->texture[hw_unit].texPitch67 = texPitch << 16;
         break;
      case 7:
         prev->texture[hw_unit].texOffset7 = texOffset;
         prev->texture[hw_unit].texPitch67 |= texPitch;
         break;
      case 8:
         prev->texture[hw_unit].texOffset8 = texOffset;
         prev->texture[hw_unit].texPitch89 = texPitch << 16;
         break;
      case 9:
         prev->texture[hw_unit].texOffset9 = texOffset;
         prev->texture[hw_unit].texPitch89 |= texPitch;
         break;
      case 10:
         prev->texture[hw_unit].texOffset10 = texOffset;
         prev->texture[hw_unit].texPitch10 = texPitch << 16;
         break;
      case 11:
         prev->texture[hw_unit].texOffset11 = texOffset;
         prev->texture[hw_unit].texPitch10 |= texPitch;
         break;
      }
   }

   if (current->texture[hw_unit].hwTextureSet != 
      prev->texture[hw_unit].hwTextureSet)
   {
      prev->texture[hw_unit].hwTextureSet =
         current->texture[hw_unit].hwTextureSet;
      if (hw_unit == 1)
         smesa->GlobalFlag |= CFLAG_TEXTURERESET_1;
      else
         smesa->GlobalFlag |= CFLAG_TEXTURERESET;
   }
   if (current->texture[hw_unit].hwTextureMip != 
      prev->texture[hw_unit].hwTextureMip)
   {
      prev->texture[hw_unit].hwTextureMip =
         current->texture[hw_unit].hwTextureMip;
      if (hw_unit == 1)
         smesa->GlobalFlag |= GFLAG_TEXTUREMIPMAP_1;
      else
         smesa->GlobalFlag |= GFLAG_TEXTUREMIPMAP;
   }

   return ok;
}
示例#11
0
/* 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
i915_update_tex_unit(struct intel_context *intel, GLuint unit, GLuint ss3)
{
   struct gl_context *ctx = &intel->ctx;
   struct i915_context *i915 = i915_context(ctx);
   struct gl_texture_unit *tUnit = &ctx->Texture.Unit[unit];
   struct gl_texture_object *tObj = tUnit->_Current;
   struct intel_texture_object *intelObj = intel_texture_object(tObj);
   struct gl_texture_image *firstImage;
   GLuint *state = i915->state.Tex[unit], format, pitch;
   GLint lodbias, aniso = 0;
   GLubyte border[4];
   GLfloat maxlod;

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

   /*We need to refcount these. */

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

   if (!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];

   drm_intel_bo_reference(intelObj->mt->region->buffer);
   i915->state.tex_buffer[unit] = intelObj->mt->region->buffer;
   i915->state.tex_offset[unit] = 0; /* Always the origin of the miptree */

   format = translate_texture_format(firstImage->TexFormat,
				     firstImage->InternalFormat,
				     tObj->DepthMode);
   pitch = intelObj->mt->region->pitch * intelObj->mt->cpp;

   state[I915_TEXREG_MS3] =
      (((firstImage->Height - 1) << MS3_HEIGHT_SHIFT) |
       ((firstImage->Width - 1) << MS3_WIDTH_SHIFT) | format);

   if (intelObj->mt->region->tiling != I915_TILING_NONE) {
      state[I915_TEXREG_MS3] |= MS3_TILED_SURFACE;
      if (intelObj->mt->region->tiling == I915_TILING_Y)
	 state[I915_TEXREG_MS3] |= MS3_TILE_WALK;
   }

   /* We get one field with fraction bits for the maximum addressable
    * (lowest resolution) LOD.  Use it to cover both MAX_LEVEL and
    * MAX_LOD.
    */
   maxlod = MIN2(tObj->MaxLod, tObj->_MaxLevel - tObj->BaseLevel);
   state[I915_TEXREG_MS4] =
      ((((pitch / 4) - 1) << MS4_PITCH_SHIFT) |
       MS4_CUBE_FACE_ENA_MASK |
       (U_FIXED(CLAMP(maxlod, 0.0, 11.0), 2) << MS4_MAX_LOD_SHIFT) |
       ((firstImage->Depth - 1) << MS4_VOLUME_DEPTH_SHIFT));


   {
      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;
         if (tObj->MaxAnisotropy > 2.0)
            aniso = SS2_MAX_ANISO_4;
         else
            aniso = SS2_MAX_ANISO_2;
      }
      else {
         switch (tObj->MagFilter) {
         case GL_NEAREST:
            magFilt = FILTER_NEAREST;
            break;
         case GL_LINEAR:
            magFilt = FILTER_LINEAR;
            break;
         default:
            return GL_FALSE;
         }
      }

      lodbias = (int) ((tUnit->LodBias + tObj->LodBias) * 16.0);
      if (lodbias < -256)
          lodbias = -256;
      if (lodbias > 255)
          lodbias = 255;
      state[I915_TEXREG_SS2] = ((lodbias << SS2_LOD_BIAS_SHIFT) & 
                                SS2_LOD_BIAS_MASK);

      /* YUV conversion:
       */
      if (firstImage->TexFormat == MESA_FORMAT_YCBCR ||
          firstImage->TexFormat == MESA_FORMAT_YCBCR_REV)
         state[I915_TEXREG_SS2] |= SS2_COLORSPACE_CONVERSION;

      /* Shadow:
       */
      if (tObj->CompareMode == GL_COMPARE_R_TO_TEXTURE_ARB &&
          tObj->Target != GL_TEXTURE_3D) {
         if (tObj->Target == GL_TEXTURE_1D) 
            return GL_FALSE;

         state[I915_TEXREG_SS2] |=
            (SS2_SHADOW_ENABLE |
             intel_translate_shadow_compare_func(tObj->CompareFunc));

         minFilt = FILTER_4X4_FLAT;
         magFilt = FILTER_4X4_FLAT;
      }

      state[I915_TEXREG_SS2] |= ((minFilt << SS2_MIN_FILTER_SHIFT) |
                                 (mipFilt << SS2_MIP_FILTER_SHIFT) |
                                 (magFilt << SS2_MAG_FILTER_SHIFT) |
                                 aniso);
   }

   {
      GLenum ws = tObj->WrapS;
      GLenum wt = tObj->WrapT;
      GLenum wr = tObj->WrapR;
      float minlod;

      /* We program 1D textures as 2D textures, so the 2D texcoord could
       * result in sampling border values if we don't set the T wrap to
       * repeat.
       */
      if (tObj->Target == GL_TEXTURE_1D)
	 wt = GL_REPEAT;

      /* 3D textures don't seem to respect the border color.
       * Fallback if there's ever a danger that they might refer to
       * it.  
       * 
       * Effectively this means fallback on 3D clamp or
       * clamp_to_border.
       */
      if (tObj->Target == GL_TEXTURE_3D &&
          (tObj->MinFilter != GL_NEAREST ||
           tObj->MagFilter != GL_NEAREST) &&
          (ws == GL_CLAMP ||
           wt == GL_CLAMP ||
           wr == GL_CLAMP ||
           ws == GL_CLAMP_TO_BORDER ||
           wt == GL_CLAMP_TO_BORDER || wr == GL_CLAMP_TO_BORDER))
         return GL_FALSE;

      /* Only support TEXCOORDMODE_CLAMP_EDGE and TEXCOORDMODE_CUBE (not 
       * used) when using cube map texture coordinates
       */
      if (tObj->Target == GL_TEXTURE_CUBE_MAP_ARB &&
          (((ws != GL_CLAMP) && (ws != GL_CLAMP_TO_EDGE)) ||
           ((wt != GL_CLAMP) && (wt != GL_CLAMP_TO_EDGE))))
          return GL_FALSE;

      state[I915_TEXREG_SS3] = ss3;     /* SS3_NORMALIZED_COORDS */

      state[I915_TEXREG_SS3] |=
         ((translate_wrap_mode(ws) << SS3_TCX_ADDR_MODE_SHIFT) |
          (translate_wrap_mode(wt) << SS3_TCY_ADDR_MODE_SHIFT) |
          (translate_wrap_mode(wr) << SS3_TCZ_ADDR_MODE_SHIFT));

      minlod = MIN2(tObj->MinLod, tObj->_MaxLevel - tObj->BaseLevel);
      state[I915_TEXREG_SS3] |= (unit << SS3_TEXTUREMAP_INDEX_SHIFT);
      state[I915_TEXREG_SS3] |= (U_FIXED(CLAMP(minlod, 0.0, 11.0), 4) <<
				 SS3_MIN_LOD_SHIFT);

   }

   /* convert border color from float to ubyte */
   CLAMPED_FLOAT_TO_UBYTE(border[0], tObj->BorderColor.f[0]);
   CLAMPED_FLOAT_TO_UBYTE(border[1], tObj->BorderColor.f[1]);
   CLAMPED_FLOAT_TO_UBYTE(border[2], tObj->BorderColor.f[2]);
   CLAMPED_FLOAT_TO_UBYTE(border[3], tObj->BorderColor.f[3]);

   if (firstImage->_BaseFormat == GL_DEPTH_COMPONENT) {
      /* GL specs that border color for depth textures is taken from the
       * R channel, while the hardware uses A.  Spam R into all the channels
       * for safety.
       */
      state[I915_TEXREG_SS4] = PACK_COLOR_8888(border[0],
					       border[0],
					       border[0],
					       border[0]);
   } else {
      state[I915_TEXREG_SS4] = PACK_COLOR_8888(border[3],
					       border[0],
					       border[1],
					       border[2]);
   }


   I915_ACTIVESTATE(i915, I915_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:
    */
   I915_STATECHANGE(i915, I915_UPLOAD_TEX(unit));


#if 0
   DBG(TEXTURE, "state[I915_TEXREG_SS2] = 0x%x\n", state[I915_TEXREG_SS2]);
   DBG(TEXTURE, "state[I915_TEXREG_SS3] = 0x%x\n", state[I915_TEXREG_SS3]);
   DBG(TEXTURE, "state[I915_TEXREG_SS4] = 0x%x\n", state[I915_TEXREG_SS4]);
   DBG(TEXTURE, "state[I915_TEXREG_MS2] = 0x%x\n", state[I915_TEXREG_MS2]);
   DBG(TEXTURE, "state[I915_TEXREG_MS3] = 0x%x\n", state[I915_TEXREG_MS3]);
   DBG(TEXTURE, "state[I915_TEXREG_MS4] = 0x%x\n", state[I915_TEXREG_MS4]);
#endif

   return GL_TRUE;
}
示例#12
0
/* 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 bool
i915_update_tex_unit(struct intel_context *intel, GLuint unit, GLuint ss3)
{
   struct gl_context *ctx = &intel->ctx;
   struct i915_context *i915 = i915_context(ctx);
   struct gl_texture_unit *tUnit = &ctx->Texture.Unit[unit];
   struct gl_texture_object *tObj = tUnit->_Current;
   struct intel_texture_object *intelObj = intel_texture_object(tObj);
   struct gl_texture_image *firstImage;
   struct gl_sampler_object *sampler = _mesa_get_samplerobj(ctx, unit);
   GLuint *state = i915->state.Tex[unit], format, pitch;
   GLint lodbias, aniso = 0;
   GLubyte border[4];
   GLfloat maxlod;

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

   /*We need to refcount these. */

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

   if (!intel_finalize_mipmap_tree(intel, unit))
      return false;

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

   drm_intel_bo_reference(intelObj->mt->region->bo);
   i915->state.tex_buffer[unit] = intelObj->mt->region->bo;
   i915->state.tex_offset[unit] = intelObj->mt->offset;

   format = translate_texture_format(firstImage->TexFormat,
				     tObj->DepthMode);
   pitch = intelObj->mt->region->pitch * intelObj->mt->cpp;

   state[I915_TEXREG_MS3] =
      (((firstImage->Height - 1) << MS3_HEIGHT_SHIFT) |
       ((firstImage->Width - 1) << MS3_WIDTH_SHIFT) | format);

   if (intelObj->mt->region->tiling != I915_TILING_NONE) {
      state[I915_TEXREG_MS3] |= MS3_TILED_SURFACE;
      if (intelObj->mt->region->tiling == I915_TILING_Y)
	 state[I915_TEXREG_MS3] |= MS3_TILE_WALK;
   }

   /* We get one field with fraction bits for the maximum addressable
    * (lowest resolution) LOD.  Use it to cover both MAX_LEVEL and
    * MAX_LOD.
    */
   maxlod = MIN2(sampler->MaxLod, tObj->_MaxLevel - tObj->BaseLevel);
   state[I915_TEXREG_MS4] =
      ((((pitch / 4) - 1) << MS4_PITCH_SHIFT) |
       MS4_CUBE_FACE_ENA_MASK |
       (U_FIXED(CLAMP(maxlod, 0.0, 11.0), 2) << MS4_MAX_LOD_SHIFT) |
       ((firstImage->Depth - 1) << MS4_VOLUME_DEPTH_SHIFT));


   {
      GLuint minFilt, mipFilt, magFilt;

      switch (sampler->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 false;
      }

      if (sampler->MaxAnisotropy > 1.0) {
         minFilt = FILTER_ANISOTROPIC;
         magFilt = FILTER_ANISOTROPIC;
         if (sampler->MaxAnisotropy > 2.0)
            aniso = SS2_MAX_ANISO_4;
         else
            aniso = SS2_MAX_ANISO_2;
      }
      else {
         switch (sampler->MagFilter) {
         case GL_NEAREST:
            magFilt = FILTER_NEAREST;
            break;
         case GL_LINEAR:
            magFilt = FILTER_LINEAR;
            break;
         default:
            return false;
         }
      }

      lodbias = (int) ((tUnit->LodBias + sampler->LodBias) * 16.0);
      if (lodbias < -256)
          lodbias = -256;
      if (lodbias > 255)
          lodbias = 255;
      state[I915_TEXREG_SS2] = ((lodbias << SS2_LOD_BIAS_SHIFT) & 
                                SS2_LOD_BIAS_MASK);

      /* YUV conversion:
       */
      if (firstImage->TexFormat == MESA_FORMAT_YCBCR ||
          firstImage->TexFormat == MESA_FORMAT_YCBCR_REV)
         state[I915_TEXREG_SS2] |= SS2_COLORSPACE_CONVERSION;

      /* Shadow:
       */
      if (sampler->CompareMode == GL_COMPARE_R_TO_TEXTURE_ARB &&
          tObj->Target != GL_TEXTURE_3D) {
         if (tObj->Target == GL_TEXTURE_1D) 
            return false;

         state[I915_TEXREG_SS2] |=
            (SS2_SHADOW_ENABLE |
             intel_translate_shadow_compare_func(sampler->CompareFunc));

         minFilt = FILTER_4X4_FLAT;
         magFilt = FILTER_4X4_FLAT;
      }

      state[I915_TEXREG_SS2] |= ((minFilt << SS2_MIN_FILTER_SHIFT) |
                                 (mipFilt << SS2_MIP_FILTER_SHIFT) |
                                 (magFilt << SS2_MAG_FILTER_SHIFT) |
                                 aniso);
   }

   {
      GLenum ws = sampler->WrapS;
      GLenum wt = sampler->WrapT;
      GLenum wr = sampler->WrapR;
      float minlod;

      /* We program 1D textures as 2D textures, so the 2D texcoord could
       * result in sampling border values if we don't set the T wrap to
       * repeat.
       */
      if (tObj->Target == GL_TEXTURE_1D)
	 wt = GL_REPEAT;

      /* 3D textures don't seem to respect the border color.
       * Fallback if there's ever a danger that they might refer to
       * it.  
       * 
       * Effectively this means fallback on 3D clamp or
       * clamp_to_border.
       */
      if (tObj->Target == GL_TEXTURE_3D &&
          (sampler->MinFilter != GL_NEAREST ||
           sampler->MagFilter != GL_NEAREST) &&
          (ws == GL_CLAMP ||
           wt == GL_CLAMP ||
           wr == GL_CLAMP ||
           ws == GL_CLAMP_TO_BORDER ||
           wt == GL_CLAMP_TO_BORDER || wr == GL_CLAMP_TO_BORDER))
         return false;

      /* Only support TEXCOORDMODE_CLAMP_EDGE and TEXCOORDMODE_CUBE (not 
       * used) when using cube map texture coordinates
       */
      if (tObj->Target == GL_TEXTURE_CUBE_MAP_ARB &&
          (((ws != GL_CLAMP) && (ws != GL_CLAMP_TO_EDGE)) ||
           ((wt != GL_CLAMP) && (wt != GL_CLAMP_TO_EDGE))))
          return false;

      /*
       * According to 3DSTATE_MAP_STATE at page of 104 in Bspec
       * Vol3d 3D Instructions:
       *   [DevGDG and DevAlv]: Must be a power of 2 for cube maps.
       *   [DevLPT, DevCST and DevBLB]: If not a power of 2, cube maps
       *      must have all faces enabled.
       *
       * But, as I tested on pineview(DevBLB derived), the rendering is
       * bad(you will find the color isn't samplered right in some
       * fragments). After checking, it seems that the texture layout is
       * wrong: making the width and height align of 4(although this
       * doesn't make much sense) will fix this issue and also broke some
       * others. Well, Bspec mentioned nothing about the layout alignment
       * and layout for NPOT cube map.  I guess the Bspec just assume it's
       * a POT cube map.
       *
       * Thus, I guess we need do this for other platforms as well.
       */
      if (tObj->Target == GL_TEXTURE_CUBE_MAP_ARB &&
          !is_power_of_two(firstImage->Height))
         return false;

      state[I915_TEXREG_SS3] = ss3;     /* SS3_NORMALIZED_COORDS */

      state[I915_TEXREG_SS3] |=
         ((translate_wrap_mode(ws) << SS3_TCX_ADDR_MODE_SHIFT) |
          (translate_wrap_mode(wt) << SS3_TCY_ADDR_MODE_SHIFT) |
          (translate_wrap_mode(wr) << SS3_TCZ_ADDR_MODE_SHIFT));

      minlod = MIN2(sampler->MinLod, tObj->_MaxLevel - tObj->BaseLevel);
      state[I915_TEXREG_SS3] |= (unit << SS3_TEXTUREMAP_INDEX_SHIFT);
      state[I915_TEXREG_SS3] |= (U_FIXED(CLAMP(minlod, 0.0, 11.0), 4) <<
				 SS3_MIN_LOD_SHIFT);

   }

   /* convert border color from float to ubyte */
   CLAMPED_FLOAT_TO_UBYTE(border[0], sampler->BorderColor.f[0]);
   CLAMPED_FLOAT_TO_UBYTE(border[1], sampler->BorderColor.f[1]);
   CLAMPED_FLOAT_TO_UBYTE(border[2], sampler->BorderColor.f[2]);
   CLAMPED_FLOAT_TO_UBYTE(border[3], sampler->BorderColor.f[3]);

   if (firstImage->_BaseFormat == GL_DEPTH_COMPONENT) {
      /* GL specs that border color for depth textures is taken from the
       * R channel, while the hardware uses A.  Spam R into all the channels
       * for safety.
       */
      state[I915_TEXREG_SS4] = PACK_COLOR_8888(border[0],
					       border[0],
					       border[0],
					       border[0]);
   } else {
      state[I915_TEXREG_SS4] = PACK_COLOR_8888(border[3],
					       border[0],
					       border[1],
					       border[2]);
   }


   I915_ACTIVESTATE(i915, I915_UPLOAD_TEX(unit), true);
   /* memcmp was already disabled, but definitely won't work as the
    * region might now change and that wouldn't be detected:
    */
   I915_STATECHANGE(i915, I915_UPLOAD_TEX(unit));


#if 0
   DBG(TEXTURE, "state[I915_TEXREG_SS2] = 0x%x\n", state[I915_TEXREG_SS2]);
   DBG(TEXTURE, "state[I915_TEXREG_SS3] = 0x%x\n", state[I915_TEXREG_SS3]);
   DBG(TEXTURE, "state[I915_TEXREG_SS4] = 0x%x\n", state[I915_TEXREG_SS4]);
   DBG(TEXTURE, "state[I915_TEXREG_MS2] = 0x%x\n", state[I915_TEXREG_MS2]);
   DBG(TEXTURE, "state[I915_TEXREG_MS3] = 0x%x\n", state[I915_TEXREG_MS3]);
   DBG(TEXTURE, "state[I915_TEXREG_MS4] = 0x%x\n", state[I915_TEXREG_MS4]);
#endif

   return true;
}
示例#13
0
/* 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_unit *tUnit = &ctx->Texture.Unit[unit];
   struct gl_texture_object *tObj = tUnit->_Current;
   struct intel_texture_object *intelObj = intel_texture_object(tObj);
   struct gl_texture_image *firstImage;
   GLuint *state = i830->state.Tex[unit], format, pitch;
   GLint lodbias;
   GLubyte border[4];
   GLuint dst_x, dst_y;

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

   /*We need to refcount these. */

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

   if (!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];

   intel_miptree_get_image_offset(intelObj->mt, intelObj->firstLevel, 0, 0,
				  &dst_x, &dst_y);

   drm_intel_bo_reference(intelObj->mt->region->buffer);
   i830->state.tex_buffer[unit] = intelObj->mt->region->buffer;
   pitch = intelObj->mt->region->pitch * intelObj->mt->cpp;

   /* XXX: This calculation is probably broken for tiled images with
    * a non-page-aligned offset.
    */
   i830->state.tex_offset[unit] = dst_x * intelObj->mt->cpp + dst_y * pitch;

   format = translate_texture_format(firstImage->TexFormat,
				     firstImage->InternalFormat);

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

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

   if (intelObj->mt->region->tiling != I915_TILING_NONE) {
      state[I830_TEXREG_TM0S1] |= TM0S1_TILED_SURFACE;
      if (intelObj->mt->region->tiling == I915_TILING_Y)
	 state[I830_TEXREG_TM0S1] |= TM0S1_TILE_WALK;
   }

   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;
         }
      }

      lodbias = (int) ((tUnit->LodBias + tObj->LodBias) * 16.0);
      if (lodbias < -64)
          lodbias = -64;
      if (lodbias > 63)
          lodbias = 63;
      
      state[I830_TEXREG_TM0S3] = ((lodbias << TM0S3_LOD_BIAS_SHIFT) & 
                                  TM0S3_LOD_BIAS_MASK);
#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)));
   }

   /* convert border color from float to ubyte */
   CLAMPED_FLOAT_TO_UBYTE(border[0], tObj->BorderColor.f[0]);
   CLAMPED_FLOAT_TO_UBYTE(border[1], tObj->BorderColor.f[1]);
   CLAMPED_FLOAT_TO_UBYTE(border[2], tObj->BorderColor.f[2]);
   CLAMPED_FLOAT_TO_UBYTE(border[3], tObj->BorderColor.f[3]);

   state[I830_TEXREG_TM0S4] = PACK_COLOR_8888(border[3],
					      border[0],
					      border[1],
					      border[2]);

   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;
}
示例#14
0
文件: intel_blit.c 项目: nikai3d/mesa
/**
 * Use blitting to clear the renderbuffers named by 'flags'.
 * Note: we can't use the ctx->DrawBuffer->_ColorDrawBufferIndexes field
 * since that might include software renderbuffers or renderbuffers
 * which we're clearing with triangles.
 * \param mask  bitmask of BUFFER_BIT_* values indicating buffers to clear
 */
GLbitfield
intelClearWithBlit(struct gl_context *ctx, GLbitfield mask)
{
    struct intel_context *intel = intel_context(ctx);
    struct gl_framebuffer *fb = ctx->DrawBuffer;
    GLuint clear_depth_value, clear_depth_mask;
    GLboolean all;
    GLint cx, cy, cw, ch;
    GLbitfield fail_mask = 0;
    BATCH_LOCALS;

    /*
     * Compute values for clearing the buffers.
     */
    clear_depth_value = 0;
    clear_depth_mask = 0;
    if (mask & BUFFER_BIT_DEPTH) {
        clear_depth_value = (GLuint) (fb->_DepthMax * ctx->Depth.Clear);
        clear_depth_mask = XY_BLT_WRITE_RGB;
    }
    if (mask & BUFFER_BIT_STENCIL) {
        clear_depth_value |= (ctx->Stencil.Clear & 0xff) << 24;
        clear_depth_mask |= XY_BLT_WRITE_ALPHA;
    }

    cx = fb->_Xmin;
    if (fb->Name == 0)
        cy = ctx->DrawBuffer->Height - fb->_Ymax;
    else
        cy = fb->_Ymin;
    cw = fb->_Xmax - fb->_Xmin;
    ch = fb->_Ymax - fb->_Ymin;

    if (cw == 0 || ch == 0)
        return 0;

    all = (cw == fb->Width && ch == fb->Height);

    /* Loop over all renderbuffers */
    mask &= (1 << BUFFER_COUNT) - 1;
    while (mask) {
        GLuint buf = _mesa_ffs(mask) - 1;
        GLboolean is_depth_stencil = buf == BUFFER_DEPTH || buf == BUFFER_STENCIL;
        struct intel_renderbuffer *irb;
        drm_intel_bo *write_buffer;
        int x1, y1, x2, y2;
        uint32_t clear_val;
        uint32_t BR13, CMD;
        int pitch, cpp;
        drm_intel_bo *aper_array[2];

        mask &= ~(1 << buf);

        irb = intel_get_renderbuffer(fb, buf);
        if (irb == NULL || irb->region == NULL || irb->region->buffer == NULL) {
            fail_mask |= 1 << buf;
            continue;
        }

        /* OK, clear this renderbuffer */
        write_buffer = intel_region_buffer(intel, irb->region,
                                           all ? INTEL_WRITE_FULL :
                                           INTEL_WRITE_PART);
        x1 = cx + irb->draw_x;
        y1 = cy + irb->draw_y;
        x2 = cx + cw + irb->draw_x;
        y2 = cy + ch + irb->draw_y;

        pitch = irb->region->pitch;
        cpp = irb->region->cpp;

        DBG("%s dst:buf(%p)/%d %d,%d sz:%dx%d\n",
            __FUNCTION__,
            irb->region->buffer, (pitch * cpp),
            x1, y1, x2 - x1, y2 - y1);

        BR13 = 0xf0 << 16;
        CMD = XY_COLOR_BLT_CMD;

        /* Setup the blit command */
        if (cpp == 4) {
            if (is_depth_stencil) {
                CMD |= clear_depth_mask;
            } else {
                /* clearing RGBA */
                CMD |= XY_BLT_WRITE_ALPHA | XY_BLT_WRITE_RGB;
            }
        }

        assert(irb->region->tiling != I915_TILING_Y);

#ifndef I915
        if (irb->region->tiling != I915_TILING_NONE) {
            CMD |= XY_DST_TILED;
            pitch /= 4;
        }
#endif
        BR13 |= (pitch * cpp);

        if (is_depth_stencil) {
            clear_val = clear_depth_value;
        } else {
            uint8_t clear[4];
            GLclampf *color = ctx->Color.ClearColor;

            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]);

            switch (irb->Base.Format) {
            case MESA_FORMAT_ARGB8888:
            case MESA_FORMAT_XRGB8888:
                clear_val = PACK_COLOR_8888(clear[3], clear[0],
                                            clear[1], clear[2]);
                break;
            case MESA_FORMAT_RGB565:
                clear_val = PACK_COLOR_565(clear[0], clear[1], clear[2]);
                break;
            case MESA_FORMAT_ARGB4444:
                clear_val = PACK_COLOR_4444(clear[3], clear[0],
                                            clear[1], clear[2]);
                break;
            case MESA_FORMAT_ARGB1555:
                clear_val = PACK_COLOR_1555(clear[3], clear[0],
                                            clear[1], clear[2]);
                break;
            case MESA_FORMAT_A8:
                clear_val = PACK_COLOR_8888(clear[3], clear[3],
                                            clear[3], clear[3]);
                break;
            default:
                fail_mask |= 1 << buf;
                continue;
            }
        }

        BR13 |= br13_for_cpp(cpp);

        assert(x1 < x2);
        assert(y1 < y2);

        /* do space check before going any further */
        aper_array[0] = intel->batch.bo;
        aper_array[1] = write_buffer;

        if (drm_intel_bufmgr_check_aperture_space(aper_array,
                ARRAY_SIZE(aper_array)) != 0) {
            intel_batchbuffer_flush(intel);
        }

        BEGIN_BATCH_BLT(6);
        OUT_BATCH(CMD);
        OUT_BATCH(BR13);
        OUT_BATCH((y1 << 16) | x1);
        OUT_BATCH((y2 << 16) | x2);
        OUT_RELOC_FENCED(write_buffer,
                         I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER,
                         0);
        OUT_BATCH(clear_val);
        ADVANCE_BATCH();

        if (intel->always_flush_cache)
            intel_batchbuffer_emit_mi_flush(intel);

        if (buf == BUFFER_DEPTH || buf == BUFFER_STENCIL)
            mask &= ~(BUFFER_BIT_DEPTH | BUFFER_BIT_STENCIL);
    }

    return fail_mask;
}