Преглед на файлове

pandify some more, fix redundant texture loads

David Rose преди 20 години
родител
ревизия
636925152b
променени са 3 файла, в които са добавени 175 реда и са изтрити 114 реда
  1. 2 10
      panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx
  2. 169 101
      panda/src/dxgsg8/dxTextureContext8.cxx
  3. 4 3
      panda/src/dxgsg8/dxTextureContext8.h

+ 2 - 10
panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx

@@ -148,7 +148,7 @@ DXGraphicsStateGuardian8::
 TextureContext *DXGraphicsStateGuardian8::
 prepare_texture(Texture *tex) {
   DXTextureContext8 *dtc = new DXTextureContext8(tex);
-  if (dtc->CreateTexture(*_pScrn) == NULL) {
+  if (dtc->create_texture(*_pScrn) == NULL) {
     delete dtc;
     return NULL;
   }
@@ -175,10 +175,6 @@ apply_texture(int i, TextureContext *tc) {
   add_to_texture_record(tc);
 #endif
 
-  // Note: if this code changes, make sure to change initialization
-  // SetTSS code in dx_init as well so DX TSS renderstate matches
-  // dxgsg state
-
   DXTextureContext8 *dtc = DCAST(DXTextureContext8, tc);
 
   int dirty = dtc->get_dirty_flags();
@@ -197,9 +193,7 @@ apply_texture(int i, TextureContext *tc) {
           << "Texture " << *dtc->_texture << " has changed mipmap state.\n";
       }
 
-      dtc->DeleteTexture();
-      if (dtc->CreateTexture(*_pScrn) == NULL) {
-
+      if (dtc->create_texture(*_pScrn) == NULL) {
         // Oops, we can't re-create the texture for some reason.
         dxgsg8_cat.error()
           << "Unable to re-create texture " << *dtc->_texture << endl;
@@ -207,7 +201,6 @@ apply_texture(int i, TextureContext *tc) {
         return;
       }
     }
-    dtc->clear_dirty_flags();
   }
 
   Texture *tex = tc->_texture;
@@ -273,7 +266,6 @@ apply_texture(int i, TextureContext *tc) {
 void DXGraphicsStateGuardian8::
 release_texture(TextureContext *tc) {
   DXTextureContext8 *gtc = DCAST(DXTextureContext8, tc);
-  gtc->DeleteTexture();
   delete gtc;
 }
 

+ 169 - 101
panda/src/dxgsg8/dxTextureContext8.cxx

@@ -306,19 +306,23 @@ d3d_surface_to_texture(RECT &source_rect, IDirect3DSurface8 *d3d_surface, Textur
 }
 
 //-----------------------------------------------------------------------------
-// Name: CreateTexture()
+// Name: create_texture()
 // Desc: Use panda texture's pixelbuffer to create a texture for the specified device.
 //       This code gets the attributes of the texture from the bitmap, creates the
 //       texture, and then copies the bitmap into the texture.
 //-----------------------------------------------------------------------------
 IDirect3DTexture8 *DXTextureContext8::
-CreateTexture(DXScreenData &scrn) {
+create_texture(DXScreenData &scrn) {
   HRESULT hr;
   int cNumAlphaBits;     //  number of alpha bits in texture pixfmt
   D3DFORMAT TargetPixFmt = D3DFMT_UNKNOWN;
   bool bNeedLuminance = false;
 
-  assert(IS_VALID_PTR(_texture));
+  nassertr(IS_VALID_PTR(_texture), NULL);
+
+  delete_texture();
+
+  clear_dirty_flags(Texture::DF_image | Texture::DF_mipmap);
 
   // bpp indicates requested fmt, not texture fmt
   DWORD target_bpp = get_bits_per_pixel(_texture->get_format(), &cNumAlphaBits);
@@ -326,7 +330,7 @@ CreateTexture(DXScreenData &scrn) {
 
   //PRINT_REFCNT(dxgsg8, scrn.pD3D8);
 
-  DWORD dwOrigWidth  = (DWORD)_texture->get_x_size();
+  DWORD dwOrigWidth = (DWORD)_texture->get_x_size();
   DWORD dwOrigHeight = (DWORD)_texture->get_y_size();
 
   if ((_texture->get_format() == Texture::F_luminance_alpha)||
@@ -335,10 +339,11 @@ CreateTexture(DXScreenData &scrn) {
     bNeedLuminance = true;
   }
 
-  if (cNumAlphaBits>0) {
+  if (cNumAlphaBits > 0) {
     if (cNumColorChannels == 3) {
-      dxgsg8_cat.error() << "ERROR: texture " << _tex->get_name() << " has no inherent alpha channel, but alpha format is requested (that would be wasteful)!\n";
-      exit(1);
+      dxgsg8_cat.error()
+        << "texture " << _tex->get_name() 
+        << " has no inherent alpha channel, but alpha format is requested!\n";
     }
   }
 
@@ -346,15 +351,16 @@ CreateTexture(DXScreenData &scrn) {
 
   // figure out what 'D3DFMT' the Texture is in, so D3DXLoadSurfFromMem knows how to perform copy
 
-  switch(cNumColorChannels) {
+  switch (cNumColorChannels) {
   case 1:
-    if (cNumAlphaBits>0)
+    if (cNumAlphaBits > 0) {
       _d3d_format = D3DFMT_A8;
-    else if (bNeedLuminance)
+    } else if (bNeedLuminance) {
       _d3d_format = D3DFMT_L8;
+    }
     break;
   case 2:
-    assert(bNeedLuminance && (cNumAlphaBits>0));
+    assert(bNeedLuminance && (cNumAlphaBits > 0));
     _d3d_format = D3DFMT_A8L8;
     break;
   case 3:
@@ -371,54 +377,54 @@ CreateTexture(DXScreenData &scrn) {
   DWORD TargetWidth = dwOrigWidth;
   DWORD TargetHeight = dwOrigHeight;
 
-  if (!ISPOW2(dwOrigWidth) || !ISPOW2(dwOrigHeight)) {
-    dxgsg8_cat.error() << "ERROR: texture dimensions are not a power of 2 for " << _tex->get_name() << "! Please rescale them so it doesnt have to be done at runtime.\n";
-#ifndef NDEBUG
-    exit(1);  // want to catch badtexsize errors
-#else
-    goto error_exit;
-#endif
+  if (scrn.d3dcaps.TextureCaps & D3DPTEXTURECAPS_POW2) {
+    if (!ISPOW2(TargetWidth)) {
+      TargetWidth = down_to_power_2(TargetWidth);
+    }
+    if (!ISPOW2(TargetHeight)) {
+      TargetHeight = down_to_power_2(TargetHeight);
+    }
   }
 
-  bool bShrinkOriginal;
-  bShrinkOriginal = false;
-
-  if ((dwOrigWidth>scrn.d3dcaps.MaxTextureWidth)||(dwOrigHeight>scrn.d3dcaps.MaxTextureHeight)) {
-#ifdef _DEBUG
-    dxgsg8_cat.error() << "WARNING: " <<_tex->get_name() << ": Image size exceeds max texture dimensions of (" << scrn.d3dcaps.MaxTextureWidth << ", " << scrn.d3dcaps.MaxTextureHeight << ") !!\n"
-                       << "Scaling " << _tex->get_name() << " (" << dwOrigWidth<< ", " <<dwOrigHeight << ") = > (" <<  scrn.d3dcaps.MaxTextureWidth << ", " << scrn.d3dcaps.MaxTextureHeight << ") !\n";
-#endif
-
-    if (dwOrigWidth>scrn.d3dcaps.MaxTextureWidth)
-      TargetWidth = scrn.d3dcaps.MaxTextureWidth;
-    if (dwOrigHeight>scrn.d3dcaps.MaxTextureHeight)
-      TargetHeight = scrn.d3dcaps.MaxTextureHeight;
-    bShrinkOriginal = true;
+  if (TargetWidth > scrn.d3dcaps.MaxTextureWidth) {
+    TargetWidth = scrn.d3dcaps.MaxTextureWidth;
+  }
+  if (TargetHeight > scrn.d3dcaps.MaxTextureHeight) {
+    TargetHeight = scrn.d3dcaps.MaxTextureHeight;
   }
 
   // checks for SQUARE reqmt (nvidia riva128 needs this)
   if ((TargetWidth != TargetHeight) && (scrn.d3dcaps.TextureCaps & D3DPTEXTURECAPS_SQUAREONLY)) {
     // assume pow2 textures.   sum exponents, divide by 2 rounding down to get sq size
     int i, width_exp, height_exp;
-    for(i = TargetWidth, width_exp = 0; i>1; width_exp++, i >>= 1);
-    for(i = TargetHeight, height_exp = 0; i>1; height_exp++, i >>= 1);
+    for (i = TargetWidth, width_exp = 0; i > 1; width_exp++, i >>= 1);
+    for (i = TargetHeight, height_exp = 0; i > 1; height_exp++, i >>= 1);
     TargetHeight = TargetWidth = 1<<((width_exp+height_exp)>>1);
-    bShrinkOriginal = true;
+  }
 
-#ifdef _DEBUG
-    dxgsg8_cat.debug() << "Scaling " << _tex->get_name() << " (" << dwOrigWidth<< ", " <<dwOrigHeight << ") = > (" << TargetWidth<< ", " << TargetHeight << ") to meet HW square texture reqmt\n";
-#endif
+  bool bShrinkOriginal = false;
+
+  if (dwOrigWidth != TargetWidth || dwOrigHeight != TargetHeight) {
+    dxgsg8_cat.info()
+      << "Reducing size of " << _tex->get_name()
+      << " from " << dwOrigWidth << "x" << dwOrigHeight
+      << " to " << TargetWidth << "x" << TargetHeight << "\n";
+
+    bShrinkOriginal = true;
   }
 
   char *szErrorMsg;
 
-  szErrorMsg = "CreateTexture failed: couldn't find compatible device Texture Pixel Format for input texture";
+  szErrorMsg = "create_texture failed: couldn't find compatible device Texture Pixel Format for input texture";
 
   if (dxgsg8_cat.is_spam())
-    dxgsg8_cat.spam() << "CreateTexture handling target bitdepth: " << target_bpp << " alphabits: " << cNumAlphaBits << endl;
+    dxgsg8_cat.spam()
+      << "create_texture handling target bitdepth: " << target_bpp
+      << " alphabits: " << cNumAlphaBits << endl;
 
-  // I could possibly replace some of this logic with D3DXCheckTextureRequirements(), but
-  // it wouldnt handle all my specialized low-memory cases perfectly
+  // I could possibly replace some of this logic with
+  // D3DXCheckTextureRequirements(), but it wouldnt handle all my
+  // specialized low-memory cases perfectly
 
 #define CONVTYPE_STMT
 
@@ -428,12 +434,14 @@ CreateTexture(DXScreenData &scrn) {
                         TargetPixFmt = D3DFMT_##FMT;                 \
                         goto found_matching_format; }
 
-  // handle each target bitdepth separately.  might be less confusing to reorg by cNumColorChannels (input type, rather
-  // than desired 1st target)
-  switch(target_bpp) {
+  // handle each target bitdepth separately.  might be less confusing
+  // to reorg by cNumColorChannels (input type, rather than desired
+  // 1st target)
+  switch (target_bpp) {
 
     // IMPORTANT NOTE:
-    // target_bpp is REQUESTED bpp, not what exists in the texture array (the texture array contains cNumColorChannels*8bits)
+    // target_bpp is REQUESTED bpp, not what exists in the texture
+    // array (the texture array contains cNumColorChannels*8bits)
 
   case 32:
     if (!((cNumColorChannels == 3) || (cNumColorChannels == 4)))
@@ -452,14 +460,17 @@ CreateTexture(DXScreenData &scrn) {
 
       // no 32-bit fmt, look for 16 bit w/alpha  (1-15)
 
-      // 32 bit RGBA was requested, but only 16 bit alpha fmts are avail
-      // by default, convert to 4-4-4-4 which has 4-bit alpha for blurry edges
-      // if we know tex only needs 1 bit alpha (i.e. for a mask), use 1555 instead
+      // 32 bit RGBA was requested, but only 16 bit alpha fmts are
+      // avail.  By default, convert to 4-4-4-4 which has 4-bit alpha
+      // for blurry edges.  If we know tex only needs 1 bit alpha
+      // (i.e. for a mask), use 1555 instead.
 
-      //                ConversionType ConvTo1 = Conv32to16_4444, ConvTo2 = Conv32to16_1555;
-      //                DWORD dwAlphaMask1 = 0xF000, dwAlphaMask2 = 0x8000;
-      // assume ALPHAMASK is x8000 and RGBMASK is x7fff to simplify 32->16 conversion
-      // this should be true on most cards.
+
+      //  ConversionType ConvTo1 = Conv32to16_4444, ConvTo2 = Conv32to16_1555;
+      //  DWORD dwAlphaMask1 = 0xF000, dwAlphaMask2 = 0x8000;
+
+      // assume ALPHAMASK is x8000 and RGBMASK is x7fff to simplify
+      // 32->16 conversion.  This should be true on most cards.
 
 #ifndef FORCE_16bpp_1555
       if (cNumAlphaBits == 1)
@@ -472,9 +483,9 @@ CreateTexture(DXScreenData &scrn) {
       CHECK_FOR_FMT(A4R4G4B4, Conv32to16_4444);
       CHECK_FOR_FMT(A1R5G5B5, Conv32to16_1555);
 
-      // at this point, bail.  dont worry about converting to non-alpha formats yet,
-      // I think this will be a very rare case
-      szErrorMsg = "CreateTexture failed: couldn't find compatible Tex DDPIXELFORMAT! no available 16 or 32-bit alpha formats!";
+      // At this point, bail.  Don't worry about converting to
+      // non-alpha formats yet, I think this will be a very rare case.
+      szErrorMsg = "create_texture failed: couldn't find compatible Tex DDPIXELFORMAT! no available 16 or 32-bit alpha formats!";
     } else {
       // convert 3 or 4 channel to closest 16bpp color fmt
 
@@ -494,8 +505,9 @@ CreateTexture(DXScreenData &scrn) {
     if (!dx_force_16bpptextures) {
       CHECK_FOR_FMT(R8G8B8, Conv24to24);
 
-      // no 24-bit fmt.  look for 32 bit fmt  (note: this is memory-hogging choice
-      // instead I could look for memory-conserving 16-bit fmt).
+      // no 24-bit fmt.  look for 32 bit fmt (note: this is
+      // memory-hogging choice instead I could look for
+      // memory-conserving 16-bit fmt).
 
       CHECK_FOR_FMT(X8R8G8B8, Conv24to32);
     }
@@ -543,13 +555,16 @@ CreateTexture(DXScreenData &scrn) {
         }
         break;
       case 1:
-        // app specifically requests 1-5-5-5 F_rgba5 case, where you explicitly want 1-5-5-5 fmt, as opposed
-        // to F_rgbm, which could use 32bpp ARGB.  fail if this particular fmt not avail.
+        // app specifically requests 1-5-5-5 F_rgba5 case, where you
+        // explicitly want 1-5-5-5 fmt, as opposed to F_rgbm, which
+        // could use 32bpp ARGB.  fail if this particular fmt not
+        // avail.
         assert(cNumColorChannels == 4);
         CHECK_FOR_FMT(X1R5G5B5, Conv32to16_X555);
         break;
       case 4:
-        // app specifically requests 4-4-4-4 F_rgba4 case, as opposed to F_rgba, which could use 32bpp ARGB
+        // app specifically requests 4-4-4-4 F_rgba4 case, as opposed
+        // to F_rgba, which could use 32bpp ARGB
         assert(cNumColorChannels == 4);
         CHECK_FOR_FMT(A4R4G4B4, Conv32to16_4444);
         break;
@@ -558,7 +573,8 @@ CreateTexture(DXScreenData &scrn) {
     }
   case 8:
     if (bNeedLuminance) {
-      // dont bother handling those other 8bit lum fmts like 4-4, since 16 8-8 is usually supported too
+      // dont bother handling those other 8bit lum fmts like 4-4,
+      // since 16 8-8 is usually supported too
       assert(cNumColorChannels == 1);
 
       // look for native lum fmt first
@@ -576,9 +592,10 @@ CreateTexture(DXScreenData &scrn) {
     } else if (cNumAlphaBits == 8) {
       // look for 16bpp A8L8, else 32-bit ARGB, else 16-4444.
 
-      // skip 8bit alpha only (D3DFMT_A8), because I think only voodoo supports it
-      // and the voodoo support isn't the kind of blending model we need somehow
-      // (is it that voodoo assumes color is white?  isnt that what we do in ConvAlpha8to32 anyway?)
+      // skip 8bit alpha only (D3DFMT_A8), because I think only voodoo
+      // supports it and the voodoo support isn't the kind of blending
+      // model we need somehow (is it that voodoo assumes color is
+      // white?  isnt that what we do in ConvAlpha8to32 anyway?)
 
       CHECK_FOR_FMT(A8L8, ConvAlpha8to16_A8L8);
 
@@ -591,14 +608,15 @@ CreateTexture(DXScreenData &scrn) {
     break;
 
   default:
-    szErrorMsg = "CreateTexture failed: unhandled pixel bitdepth in DX loader";
+    szErrorMsg = "create_texture failed: unhandled pixel bitdepth in DX loader";
   }
 
   // if we've gotten here, haven't found a match
-  dxgsg8_cat.error() << szErrorMsg << ": " << _tex->get_name() << endl
-                     << "NumColorChannels: " <<cNumColorChannels << "; NumAlphaBits: " << cNumAlphaBits
-                     << "; targetbpp: " <<target_bpp << "; SupportedTexFmtsMask: 0x" << (void*)scrn.SupportedTexFmtsMask
-                     << "; NeedLuminance: " << bNeedLuminance << endl;
+  dxgsg8_cat.error()
+    << szErrorMsg << ": " << _tex->get_name() << endl
+    << "NumColorChannels: " <<cNumColorChannels << "; NumAlphaBits: " << cNumAlphaBits
+    << "; targetbpp: " <<target_bpp << "; SupportedTexFmtsMask: 0x" << (void*)scrn.SupportedTexFmtsMask
+    << "; NeedLuminance: " << bNeedLuminance << endl;
   goto error_exit;
 
   ///////////////////////////////////////////////////////////
@@ -613,13 +631,14 @@ CreateTexture(DXScreenData &scrn) {
     IDirect3DSurface8 *pCurRenderTarget;
     hr = scrn.pD3DDevice->GetRenderTarget(&pCurRenderTarget);
     if (FAILED(hr)) {
-      dxgsg8_cat.error() << "GetRenderTgt failed in CreateTexture: " << D3DERRORSTRING(hr);
+      dxgsg8_cat.error()
+        << "GetRenderTgt failed in create_texture: " << D3DERRORSTRING(hr);
     } else {
       D3DSURFACE_DESC SurfDesc;
       hr = pCurRenderTarget->GetDesc(&SurfDesc);
       if (FAILED(hr)) {
         dxgsg8_cat.error()
-          << "GetDesc failed in CreateTexture: " << D3DERRORSTRING(hr);
+          << "GetDesc failed in create_texture: " << D3DERRORSTRING(hr);
       } else {
         if (TargetPixFmt != SurfDesc.Format) {
           if (dxgsg8_cat.is_debug()) {
@@ -648,8 +667,9 @@ CreateTexture(DXScreenData &scrn) {
     else ft = Texture::FT_linear;
   }
 
-  if ((ft == Texture::FT_linear) && !(scrn.d3dcaps.TextureFilterCaps & D3DPTFILTERCAPS_MAGFLINEAR))
+  if ((ft == Texture::FT_linear) && !(scrn.d3dcaps.TextureFilterCaps & D3DPTFILTERCAPS_MAGFLINEAR)) {
     ft = Texture::FT_nearest;
+  }
   _tex->set_magfilter(ft);
 
   // figure out if we are mipmapping this texture
@@ -668,15 +688,18 @@ CreateTexture(DXScreenData &scrn) {
     if (dx_mipmap_everything) {  // debug toggle, ok to leave in since its just a creation cost
       _has_mipmaps = true;
       if (dxgsg8_cat.is_spam()) {
-        if (ft != Texture::FT_linear_mipmap_linear)
+        if (ft != Texture::FT_linear_mipmap_linear) {
           dxgsg8_cat.spam() << "Forcing trilinear mipmapping on DX texture [" << _tex->get_name() << "]\n";
+        }
       }
       ft = Texture::FT_linear_mipmap_linear;
       _tex->set_minfilter(ft);
     }
+
   } else if ((ft == Texture::FT_nearest_mipmap_nearest) ||   // cvt to no-mipmap filter types
-            (ft == Texture::FT_nearest_mipmap_linear)) {
+             (ft == Texture::FT_nearest_mipmap_linear)) {
     ft = Texture::FT_nearest;
+
   } else if ((ft == Texture::FT_linear_mipmap_nearest) ||
             (ft == Texture::FT_linear_mipmap_linear)) {
     ft = Texture::FT_linear;
@@ -690,25 +713,35 @@ CreateTexture(DXScreenData &scrn) {
   switch(ft) {
   case Texture::FT_linear_mipmap_linear:
     if ((scrn.d3dcaps.TextureFilterCaps & TRILINEAR_MIPMAP_TEXFILTERCAPS) != TRILINEAR_MIPMAP_TEXFILTERCAPS) {
-      if (scrn.d3dcaps.TextureFilterCaps & D3DPTFILTERCAPS_MINFLINEAR)
+      if (scrn.d3dcaps.TextureFilterCaps & D3DPTFILTERCAPS_MINFLINEAR) {
         ft = Texture::FT_linear_mipmap_nearest;
-      else ft = Texture::FT_nearest_mipmap_nearest;  // if you cant do linear in a level, you probably cant do linear b/w levels, so just do nearest-all
+      } else {
+        // if you cant do linear in a level, you probably cant do
+        // linear b/w levels, so just do nearest-all
+        ft = Texture::FT_nearest_mipmap_nearest;
+      }
     }
     break;
+
   case Texture::FT_nearest_mipmap_linear:
     // if we dont have bilinear, do nearest_nearest
     if (!((scrn.d3dcaps.TextureFilterCaps & D3DPTFILTERCAPS_MIPFPOINT) &&
-         (scrn.d3dcaps.TextureFilterCaps & D3DPTFILTERCAPS_MINFLINEAR)))
+          (scrn.d3dcaps.TextureFilterCaps & D3DPTFILTERCAPS_MINFLINEAR))) {
       ft = Texture::FT_nearest_mipmap_nearest;
+    }
     break;
+
   case Texture::FT_linear_mipmap_nearest:
     // if we dont have mip linear, do nearest_nearest
-    if (!(scrn.d3dcaps.TextureFilterCaps & D3DPTFILTERCAPS_MIPFLINEAR))
+    if (!(scrn.d3dcaps.TextureFilterCaps & D3DPTFILTERCAPS_MIPFLINEAR)) {
       ft = Texture::FT_nearest_mipmap_nearest;
+    }
     break;
+
   case Texture::FT_linear:
-    if (!(scrn.d3dcaps.TextureFilterCaps & D3DPTFILTERCAPS_MINFLINEAR))
+    if (!(scrn.d3dcaps.TextureFilterCaps & D3DPTFILTERCAPS_MINFLINEAR)) {
       ft = Texture::FT_nearest;
+    }
     break;
   }
 
@@ -719,35 +752,50 @@ CreateTexture(DXScreenData &scrn) {
   aniso_degree = 1;
   if (scrn.d3dcaps.RasterCaps & D3DPRASTERCAPS_ANISOTROPY) {
     aniso_degree = _tex->get_anisotropic_degree();
-    if ((aniso_degree>scrn.d3dcaps.MaxAnisotropy) || dx_force_anisotropic_filtering)
+    if ((aniso_degree>scrn.d3dcaps.MaxAnisotropy) || 
+        dx_force_anisotropic_filtering) {
       aniso_degree = scrn.d3dcaps.MaxAnisotropy;
+    }
   }
   _tex->set_anisotropic_degree(aniso_degree);
 
 #ifdef _DEBUG
-  dxgsg8_cat.spam() << "CreateTexture: setting aniso degree for " << _tex->get_name() << " to: " << aniso_degree << endl;
+  dxgsg8_cat.spam()
+    << "create_texture: setting aniso degree for " << _tex->get_name()
+    << " to: " << aniso_degree << endl;
 #endif
 
   UINT cMipLevelCount;
 
   if (_has_mipmaps) {
-    cMipLevelCount = 0;  // tell CreateTex to alloc space for all mip levels down to 1x1
+    // tell CreateTex to alloc space for all mip levels down to 1x1
+    cMipLevelCount = 0;
 
-    if (dxgsg8_cat.is_debug())
-      dxgsg8_cat.debug() << "CreateTexture: generating mipmaps for " << _tex->get_name() << endl;
-  } else cMipLevelCount = 1;
+    if (dxgsg8_cat.is_debug()) {
+      dxgsg8_cat.debug()
+        << "create_texture: generating mipmaps for " << _tex->get_name()
+        << endl;
+    }
+  } else {
+    cMipLevelCount = 1;
+  }
 
-  if (FAILED( hr = scrn.pD3DDevice->CreateTexture(TargetWidth, TargetHeight, cMipLevelCount, 0x0,
-                                                 TargetPixFmt, D3DPOOL_MANAGED, &_d3d_texture) )) {
-    dxgsg8_cat.error() << "D3D CreateTexture failed!" << D3DERRORSTRING(hr);
+  hr = scrn.pD3DDevice->CreateTexture(TargetWidth, TargetHeight, cMipLevelCount, 0x0,
+                                      TargetPixFmt, D3DPOOL_MANAGED, &_d3d_texture);
+  if (FAILED(hr)) {
+    dxgsg8_cat.error()
+      << "D3D create_texture failed!" << D3DERRORSTRING(hr);
     goto error_exit;
   }
 
   if (dxgsg8_cat.is_debug()) {
-    dxgsg8_cat.debug() << "CreateTexture: " << _tex->get_name() << " converting panda equivalent of " << D3DFormatStr(_d3d_format) << " = > " << D3DFormatStr(TargetPixFmt) << endl;
+    dxgsg8_cat.debug()
+      << "create_texture: " << _tex->get_name()
+      << " converting panda equivalent of " << D3DFormatStr(_d3d_format)
+      << " => " << D3DFormatStr(TargetPixFmt) << endl;
   }
 
-  hr = FillDDSurfTexturePixels();
+  hr = fill_d3d_texture_pixels();
   if (FAILED(hr)) {
     goto error_exit;
   }
@@ -764,7 +812,7 @@ CreateTexture(DXScreenData &scrn) {
 }
 
 HRESULT DXTextureContext8::
-FillDDSurfTexturePixels() {
+fill_d3d_texture_pixels() {
   HRESULT hr = E_FAIL;
   assert(IS_VALID_PTR(_texture));
 
@@ -866,22 +914,25 @@ FillDDSurfTexturePixels() {
   GraphicsStateGuardian::_data_transferred_pcollector.add_level(SrcPixBufRowByteLength * OrigHeight);
 #endif
   hr = D3DXLoadSurfaceFromMemory(pMipLevel0, (PALETTEENTRY*)NULL, (RECT*)NULL, (LPCVOID)pPixels, SrcFormat,
-                               SrcPixBufRowByteLength, (PALETTEENTRY*)NULL, &SrcSize, Lev0Filter, (D3DCOLOR)0x0);
+                                 SrcPixBufRowByteLength, (PALETTEENTRY*)NULL, &SrcSize, Lev0Filter, (D3DCOLOR)0x0);
   if (FAILED(hr)) {
     dxgsg8_cat.error() << "FillDDSurfaceTexturePixels failed for " << _tex->get_name() << ", D3DXLoadSurfFromMem failed" << D3DERRORSTRING(hr);
     goto exit_FillDDSurf;
   }
 
   if (_has_mipmaps) {
-    if (!dx_use_triangle_mipgen_filter)
+    if (!dx_use_triangle_mipgen_filter) {
       MipFilterFlags = D3DX_FILTER_BOX;
-    else MipFilterFlags = D3DX_FILTER_TRIANGLE;
+    } else {
+      MipFilterFlags = D3DX_FILTER_TRIANGLE;
+    }
 
     //    MipFilterFlags| = D3DX_FILTER_DITHER;
 
     hr = D3DXFilterTexture(_d3d_texture, (PALETTEENTRY*)NULL, 0, MipFilterFlags);
     if (FAILED(hr)) {
-      dxgsg8_cat.error() << "FillDDSurfaceTexturePixels failed for " << _tex->get_name() << ", D3DXFilterTex failed" << D3DERRORSTRING(hr);
+      dxgsg8_cat.error()
+        << "FillDDSurfaceTexturePixels failed for " << _tex->get_name() << ", D3DXFilterTex failed" << D3DERRORSTRING(hr);
       goto exit_FillDDSurf;
     }
   }
@@ -895,11 +946,11 @@ FillDDSurfTexturePixels() {
 }
 
 //-----------------------------------------------------------------------------
-// Name: DeleteTexture()
+// Name: delete_texture()
 // Desc: Release the surface used to store the texture
 //-----------------------------------------------------------------------------
 void DXTextureContext8::
-DeleteTexture( ) {
+delete_texture( ) {
   if (_d3d_texture == NULL) {
     // dont bother printing the msg below, since we already released it.
     return;
@@ -923,7 +974,8 @@ DXTextureContext8(Texture *tex) :
   TextureContext(tex) {
 
   if (dxgsg8_cat.is_spam()) {
-    dxgsg8_cat.spam() << "Creating DX texture [" << tex->get_name() << "], minfilter(" << tex->get_minfilter() << "), magfilter(" << tex->get_magfilter() << "), anisodeg(" << tex->get_anisotropic_degree() << ")\n";
+    dxgsg8_cat.spam() 
+      << "Creating DX texture [" << tex->get_name() << "], minfilter(" << tex->get_minfilter() << "), magfilter(" << tex->get_magfilter() << "), anisodeg(" << tex->get_anisotropic_degree() << ")\n";
   }
 
   _d3d_texture = NULL;
@@ -934,10 +986,26 @@ DXTextureContext8(Texture *tex) :
 DXTextureContext8::
 ~DXTextureContext8() {
   if (dxgsg8_cat.is_spam()) {
-    dxgsg8_cat.spam() << "Deleting DX8 TexContext for " << _tex->get_name() << "\n";
+    dxgsg8_cat.spam()
+      << "Deleting DX8 TexContext for " << _tex->get_name() << "\n";
   }
-  DeleteTexture();
+  delete_texture();
   TextureContext::~TextureContext();
   _tex = NULL;
 }
 
+
+////////////////////////////////////////////////////////////////////
+//     Function: DXTextureContext8::down_to_power_2
+//       Access: Private, Static
+//  Description: Returns the largest power of 2 less than or equal
+//               to value.
+////////////////////////////////////////////////////////////////////
+int DXTextureContext8::
+down_to_power_2(int value) {
+  int x = 1;
+  while ((x << 1) <= value) {
+    x = (x << 1);
+  }
+  return x;
+}

+ 4 - 3
panda/src/dxgsg8/dxTextureContext8.h

@@ -32,14 +32,15 @@ public:
   DXTextureContext8(Texture *tex);
   ~DXTextureContext8();
 
-  IDirect3DTexture8 *CreateTexture(DXScreenData &scrn);
-  void DeleteTexture();
+  IDirect3DTexture8 *create_texture(DXScreenData &scrn);
+  void delete_texture();
 
   INLINE bool has_mipmaps() const;
   INLINE IDirect3DTexture8 *get_d3d_texture() const;
 
 private:
-  HRESULT FillDDSurfTexturePixels();
+  HRESULT fill_d3d_texture_pixels();
+  static int down_to_power_2(int value);
 
 private:
   Texture *_tex;            // ptr to parent, primarily for access to namestr