⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 via_tex.c

📁 Mesa is an open-source implementation of the OpenGL specification - a system for rendering interacti
💻 C
📖 第 1 页 / 共 2 页
字号:
   /* 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.    */   if (texObj->MinFilter == GL_LINEAR || texObj->MinFilter == GL_NEAREST) {      firstLevel = lastLevel = texObj->BaseLevel;   }   else {      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 + baseImage->image.MaxLog2);      lastLevel = MIN2(lastLevel, texObj->MaxLevel);      lastLevel = MAX2(firstLevel, lastLevel);     /* need at least one level */   }   numLevels = lastLevel - firstLevel + 1;   /* The hardware supports only 10 mipmap levels; ignore higher levels.    */   if ((numLevels > 10) && (ctx->Const.MaxTextureLevels > 10)) {       lastLevel -= numLevels - 10;       numLevels = 10;   }   /* save these values, check if they effect the residency of the    * texture:    */   if (viaObj->firstLevel != firstLevel ||       viaObj->lastLevel != lastLevel) {      viaObj->firstLevel = firstLevel;      viaObj->lastLevel = lastLevel;      viaObj->memType = VIA_MEM_MIXED;   }   if (VIA_DEBUG & DEBUG_TEXTURE & 0)      fprintf(stderr, "%s, current memType: %s\n",	      __FUNCTION__,	      get_memtype_name(viaObj->memType));      if (viaObj->memType == VIA_MEM_MIXED ||       viaObj->memType == VIA_MEM_SYSTEM) {      if (!viaSwapInTexObject(vmesa, viaObj)) { 	 if (VIA_DEBUG & DEBUG_TEXTURE) 	    if (!vmesa->thrashing)	       fprintf(stderr, "Thrashing flag set for frame %d\n", 		       vmesa->swap_count);	 vmesa->thrashing = GL_TRUE;	 return GL_FALSE;      }   }   if (viaObj->memType == VIA_MEM_AGP)      viaObj->regTexFM = (HC_SubA_HTXnFM << 24) | HC_HTXnLoc_AGP | texFormat;   else      viaObj->regTexFM = (HC_SubA_HTXnFM << 24) | HC_HTXnLoc_Local | texFormat;   for (i = 0; i < numLevels; i++) {          struct via_texture_image *viaImage = 	 (struct via_texture_image *)texObj->Image[0][firstLevel + i];      w = viaImage->image.WidthLog2;      h = viaImage->image.HeightLog2;      p = viaImage->pitchLog2;      assert(viaImage->texMem->memType == viaObj->memType);      texBase = viaImage->texMem->texBase;      if (!texBase) {	 if (VIA_DEBUG & DEBUG_TEXTURE)	    fprintf(stderr, "%s: no texBase[%d]\n", __FUNCTION__, i); 	 return GL_FALSE;      }      /* Image has to remain resident until the coming fence is retired.       */      move_to_head( &vmesa->tex_image_list[viaImage->texMem->memType],		    viaImage->texMem );      viaImage->texMem->lastUsed = vmesa->lastBreadcrumbWrite;      viaObj->regTexBaseAndPitch[i].baseL = 	 ((HC_SubA_HTXnL0BasL + i) << 24) | (texBase & 0xFFFFFF);      viaObj->regTexBaseAndPitch[i].pitchLog2 = 	 ((HC_SubA_HTXnL0Pit + i) << 24) | (p << 20);					      					            /* The base high bytes for each 3 levels are packed       * together into one register:       */      j = i / 3;      k = 3 - (i % 3);      basH |= ((texBase & 0xFF000000) >> (k << 3));      if (k == 1) {	 viaObj->regTexBaseH[j] = ((j + HC_SubA_HTXnL012BasH) << 24) | basH;	 basH = 0;      }                  /* Likewise, sets of 6 log2width and log2height values are       * packed into individual registers:       */      l = i / 6;      m = i % 6;      widthExp |= (((GLuint)w & 0xF) << (m << 2));      heightExp |= (((GLuint)h & 0xF) << (m << 2));      if (m == 5) {	 viaObj->regTexWidthLog2[l] = 	    (l + HC_SubA_HTXnL0_5WE) << 24 | widthExp;	 viaObj->regTexHeightLog2[l] = 	    (l + HC_SubA_HTXnL0_5HE) << 24 | heightExp;	 widthExp = 0;	 heightExp = 0;      }      if (w) w--;      if (h) h--;      if (p) p--;                                              }           if (k != 1) {      viaObj->regTexBaseH[j] = ((j + HC_SubA_HTXnL012BasH) << 24) | basH;         }   if (m != 5) {      viaObj->regTexWidthLog2[l] = (l + HC_SubA_HTXnL0_5WE) << 24 | widthExp;      viaObj->regTexHeightLog2[l] = (l + HC_SubA_HTXnL0_5HE) << 24 | heightExp;   }   return GL_TRUE;}GLboolean viaUpdateTextureState( GLcontext *ctx ){   struct gl_texture_unit *texUnit = ctx->Texture.Unit;   GLuint i;   for (i = 0; i < 2; i++) {         if (texUnit[i]._ReallyEnabled == TEXTURE_2D_BIT || 	  texUnit[i]._ReallyEnabled == TEXTURE_1D_BIT) {	 if (!viaSetTexImages(ctx, texUnit[i]._Current)) 	    return GL_FALSE;      }      else if (texUnit[i]._ReallyEnabled) {	 return GL_FALSE;      }    }      return GL_TRUE;}				 static void viaTexImage(GLcontext *ctx, 			GLint dims,			GLenum target, GLint level,			GLint internalFormat,			GLint width, GLint height, GLint border,			GLenum format, GLenum type, const void *pixels,			const struct gl_pixelstore_attrib *packing,			struct gl_texture_object *texObj,			struct gl_texture_image *texImage){   struct via_context *vmesa = VIA_CONTEXT(ctx);   GLint postConvWidth = width;   GLint postConvHeight = height;   GLint texelBytes, sizeInBytes;   struct via_texture_object *viaObj = (struct via_texture_object *)texObj;   struct via_texture_image *viaImage = (struct via_texture_image *)texImage;   int heaps[3], nheaps, i;   if (!is_empty_list(&vmesa->freed_tex_buffers)) {      viaCheckBreadcrumb(vmesa, 0);      via_release_pending_textures(vmesa);   }   if (ctx->_ImageTransferState & IMAGE_CONVOLUTION_BIT) {      _mesa_adjust_image_for_convolution(ctx, dims, &postConvWidth,                                         &postConvHeight);   }   /* choose the texture format */   texImage->TexFormat = viaChooseTexFormat(ctx, internalFormat, 					    format, type);   assert(texImage->TexFormat);   if (dims == 1) {      texImage->FetchTexelc = texImage->TexFormat->FetchTexel1D;      texImage->FetchTexelf = texImage->TexFormat->FetchTexel1Df;   }   else {      texImage->FetchTexelc = texImage->TexFormat->FetchTexel2D;      texImage->FetchTexelf = texImage->TexFormat->FetchTexel2Df;   }   texelBytes = texImage->TexFormat->TexelBytes;   if (texelBytes == 0) {      /* compressed format */      texImage->IsCompressed = GL_TRUE;      texImage->CompressedSize =         ctx->Driver.CompressedTextureSize(ctx, texImage->Width,                                           texImage->Height, texImage->Depth,                                           texImage->TexFormat->MesaFormat);   }   /* Minimum pitch of 32 bytes */   if (postConvWidth * texelBytes < 32) {      postConvWidth = 32 / texelBytes;      texImage->RowStride = postConvWidth;   }   assert(texImage->RowStride == postConvWidth);   viaImage->pitchLog2 = logbase2(postConvWidth * texelBytes);   /* allocate memory */   if (texImage->IsCompressed)      sizeInBytes = texImage->CompressedSize;   else      sizeInBytes = postConvWidth * postConvHeight * texelBytes;   /* Attempt to allocate texture memory directly, otherwise use main    * memory and this texture will always be a fallback.   FIXME!    *    * TODO: make room in agp if this fails.    * TODO: use fb ram for textures as well.    */            switch (viaObj->memType) {   case VIA_MEM_UNKNOWN:      heaps[0] = VIA_MEM_AGP;      heaps[1] = VIA_MEM_VIDEO;      heaps[2] = VIA_MEM_SYSTEM;      nheaps = 3;      break;   case VIA_MEM_AGP:   case VIA_MEM_VIDEO:      heaps[0] = viaObj->memType;      heaps[1] = VIA_MEM_SYSTEM;      nheaps = 2;      break;   case VIA_MEM_MIXED:   case VIA_MEM_SYSTEM:   default:      heaps[0] = VIA_MEM_SYSTEM;      nheaps = 1;      break;   }	   for (i = 0; i < nheaps && !viaImage->texMem; i++) {      if (VIA_DEBUG & DEBUG_TEXTURE) 	 fprintf(stderr, "try %s (obj %s)\n", get_memtype_name(heaps[i]),		 get_memtype_name(viaObj->memType));      viaImage->texMem = via_alloc_texture(vmesa, sizeInBytes, heaps[i]);   }   if (!viaImage->texMem) {      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage");      return;   }   if (VIA_DEBUG & DEBUG_TEXTURE)      fprintf(stderr, "upload %d bytes to %s\n", sizeInBytes, 	      get_memtype_name(viaImage->texMem->memType));   viaImage->texMem->image = viaImage;   texImage->Data = viaImage->texMem->bufAddr;   if (viaObj->memType == VIA_MEM_UNKNOWN)      viaObj->memType = viaImage->texMem->memType;   else if (viaObj->memType != viaImage->texMem->memType)      viaObj->memType = VIA_MEM_MIXED;   if (VIA_DEBUG & DEBUG_TEXTURE)      fprintf(stderr, "%s, obj %s, image : %s\n",	      __FUNCTION__,	      	      get_memtype_name(viaObj->memType),	      get_memtype_name(viaImage->texMem->memType));   vmesa->clearTexCache = 1;   pixels = _mesa_validate_pbo_teximage(ctx, dims, width, height, 1, 					format, type,					pixels, packing, "glTexImage");   if (!pixels) {      /* Note: we check for a NULL image pointer here, _after_ we allocated       * memory for the texture.  That's what the GL spec calls for.       */      return;   }   else {      GLint dstRowStride;      GLboolean success;      if (texImage->IsCompressed) {         dstRowStride = _mesa_compressed_row_stride(texImage->TexFormat->MesaFormat, width);      }      else {         dstRowStride = postConvWidth * texImage->TexFormat->TexelBytes;      }      ASSERT(texImage->TexFormat->StoreImage);      success = texImage->TexFormat->StoreImage(ctx, dims,                                                texImage->_BaseFormat,                                                texImage->TexFormat,                                                texImage->Data,                                                0, 0, 0,  /* dstX/Y/Zoffset */                                                dstRowStride,                                                texImage->ImageOffsets,                                                width, height, 1,                                                format, type, pixels, packing);      if (!success) {         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage");      }   }   /* GL_SGIS_generate_mipmap */   if (level == texObj->BaseLevel && texObj->GenerateMipmap) {      _mesa_generate_mipmap(ctx, target, texObj);   }   _mesa_unmap_teximage_pbo(ctx, packing);}static void viaTexImage2D(GLcontext *ctx, 			  GLenum target, GLint level,			  GLint internalFormat,			  GLint width, GLint height, GLint border,			  GLenum format, GLenum type, const void *pixels,			  const struct gl_pixelstore_attrib *packing,			  struct gl_texture_object *texObj,			  struct gl_texture_image *texImage){   viaTexImage( ctx, 2, target, level, 		internalFormat, width, height, border,		format, type, pixels,		packing, texObj, texImage );}static void viaTexSubImage2D(GLcontext *ctx,                             GLenum target,                             GLint level,                             GLint xoffset, GLint yoffset,                             GLsizei width, GLsizei height,                             GLenum format, GLenum type,                             const GLvoid *pixels,                             const struct gl_pixelstore_attrib *packing,                             struct gl_texture_object *texObj,                             struct gl_texture_image *texImage){   struct via_context *vmesa = VIA_CONTEXT(ctx);     viaWaitIdle(vmesa, GL_TRUE);   vmesa->clearTexCache = 1;   _mesa_store_texsubimage2d(ctx, target, level, xoffset, yoffset, width,			     height, format, type, pixels, packing, texObj,			     texImage);}static void viaTexImage1D(GLcontext *ctx, 			  GLenum target, GLint level,			  GLint internalFormat,			  GLint width, GLint border,			  GLenum format, GLenum type, const void *pixels,			  const struct gl_pixelstore_attrib *packing,			  struct gl_texture_object *texObj,			  struct gl_texture_image *texImage){   viaTexImage( ctx, 1, target, level, 		internalFormat, width, 1, border,		format, type, pixels,		packing, texObj, texImage );}static void viaTexSubImage1D(GLcontext *ctx,                             GLenum target,                             GLint level,                             GLint xoffset,                             GLsizei width,                             GLenum format, GLenum type,                             const GLvoid *pixels,                             const struct gl_pixelstore_attrib *packing,                             struct gl_texture_object *texObj,                             struct gl_texture_image *texImage){   struct via_context *vmesa = VIA_CONTEXT(ctx);   viaWaitIdle(vmesa, GL_TRUE);    vmesa->clearTexCache = 1;   _mesa_store_texsubimage1d(ctx, target, level, xoffset, width,			     format, type, pixels, packing, texObj,			     texImage);}static GLboolean viaIsTextureResident(GLcontext *ctx,                                      struct gl_texture_object *texObj){   struct via_texture_object *viaObj =       (struct via_texture_object *)texObj;   return (viaObj->memType == VIA_MEM_AGP ||	   viaObj->memType == VIA_MEM_VIDEO);}static struct gl_texture_image *viaNewTextureImage( GLcontext *ctx ){   (void) ctx;   return (struct gl_texture_image *)CALLOC_STRUCT(via_texture_image);}static struct gl_texture_object *viaNewTextureObject( GLcontext *ctx, 						      GLuint name, 						      GLenum target ){   struct via_texture_object *obj = CALLOC_STRUCT(via_texture_object);   _mesa_initialize_texture_object(&obj->obj, name, target);   (void) ctx;   obj->memType = VIA_MEM_UNKNOWN;   return &obj->obj;}static void viaFreeTextureImageData( GLcontext *ctx, 				     struct gl_texture_image *texImage ){   struct via_context *vmesa = VIA_CONTEXT(ctx);   struct via_texture_image *image = (struct via_texture_image *)texImage;   if (image->texMem) {      via_free_texture(vmesa, image->texMem);      image->texMem = NULL;   }      texImage->Data = NULL;}void viaInitTextureFuncs(struct dd_function_table * functions){   functions->ChooseTextureFormat = viaChooseTexFormat;   functions->TexImage1D = viaTexImage1D;   functions->TexImage2D = viaTexImage2D;   functions->TexSubImage1D = viaTexSubImage1D;   functions->TexSubImage2D = viaTexSubImage2D;   functions->NewTextureObject = viaNewTextureObject;   functions->NewTextureImage = viaNewTextureImage;   functions->DeleteTexture = _mesa_delete_texture_object;   functions->FreeTexImageData = viaFreeTextureImageData;#if 0 && defined( USE_SSE_ASM )   /*    * XXX this code is disabled for now because the via_sse_memcpy()    * routine causes segfaults with flightgear.    * See Mesa3d-dev mail list messages from 7/15/2005 for details.    * Note that this function is currently disabled in via_tris.c too.    */   if (getenv("VIA_NO_SSE"))      functions->TextureMemCpy = _mesa_memcpy;   else      functions->TextureMemCpy = via_sse_memcpy;#else   functions->TextureMemCpy = _mesa_memcpy;#endif   functions->UpdateTexturePalette = 0;   functions->IsTextureResident = viaIsTextureResident;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -