Browse Source

Support BC4/BC5 compression, more texture formats, DX10 DDS files, rgba16/32 DDS files

rdb 10 years ago
parent
commit
17ad8f254d

+ 16 - 10
panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx

@@ -2662,13 +2662,13 @@ reset() {
   _supports_shadow_filter = _supports_depth_texture;
 
   // check if compressed textures are supported
-  #define CHECK_FOR_DXTVERSION(num) \
-  if (_screen->_supported_tex_formats_mask & DXT##num##_FLAG) {\
+  #define CHECK_COMPRESSED_FMT(mode, fmt) \
+  if (_screen->_supported_tex_formats_mask & fmt##_FLAG) {\
     if (dxgsg9_cat.is_debug()) {\
-      dxgsg9_cat.debug() << "Compressed texture format DXT" << #num << " supported\n";\
+      dxgsg9_cat.debug() << "Compressed texture format " << #fmt << " supported\n";\
     }\
     _supports_compressed_texture = true;\
-    _compressed_texture_formats.set_bit(Texture::CM_dxt##num);\
+    _compressed_texture_formats.set_bit(Texture::mode);\
   }
 
   if (_screen->_intel_compressed_texture_bug) {
@@ -2679,14 +2679,16 @@ reset() {
 
   } else {
     // Check for available compressed formats normally.
-    CHECK_FOR_DXTVERSION(1);
-    CHECK_FOR_DXTVERSION(2);
-    CHECK_FOR_DXTVERSION(3);
-    CHECK_FOR_DXTVERSION(4);
-    CHECK_FOR_DXTVERSION(5);
+    CHECK_COMPRESSED_FMT(CM_dxt1, DXT1);
+    CHECK_COMPRESSED_FMT(CM_dxt2, DXT2);
+    CHECK_COMPRESSED_FMT(CM_dxt3, DXT3);
+    CHECK_COMPRESSED_FMT(CM_dxt4, DXT4);
+    CHECK_COMPRESSED_FMT(CM_dxt5, DXT5);
+    CHECK_COMPRESSED_FMT(CM_rgtc, ATI1);
+    CHECK_COMPRESSED_FMT(CM_rgtc, ATI2);
   }
 
-  #undef CHECK_FOR_DXTVERSION
+  #undef CHECK_COMPRESSED_FMT
 
   _screen->_supports_rgba16f_texture_format = false;
   hr = _screen->_d3d9->CheckDeviceFormat(_screen->_card_id, D3DDEVTYPE_HAL, _screen->_display_mode.Format, 0x0, D3DRTYPE_TEXTURE, D3DFMT_A16B16G16R16F);
@@ -4137,6 +4139,10 @@ void DXGraphicsStateGuardian9::
 close_gsg() {
   GraphicsStateGuardian::close_gsg();
 
+  if (_prepared_objects.is_null()) {
+    return;
+  }
+
   if (dxgsg9_cat.is_debug()) {
     dxgsg9_cat.debug()
       << "Closing GSG, prepared_objects count = "

+ 74 - 14
panda/src/dxgsg9/dxTextureContext9.cxx

@@ -244,10 +244,11 @@ create_texture(DXScreenData &scrn) {
     case 1:
       if (num_alpha_bits > 0) {
         _d3d_format = D3DFMT_A8;
+      } else {
+        _d3d_format = D3DFMT_L8;
       }
       break;
     case 2:
-      nassertr(false && (num_alpha_bits > 0), false);
       _d3d_format = D3DFMT_A8L8;
       break;
     case 3:
@@ -417,12 +418,24 @@ create_texture(DXScreenData &scrn) {
     case Texture::CM_dxt5:
       CHECK_FOR_FMT(DXT5);
       break;
+    case Texture::CM_rgtc:
+      if (num_color_channels == 1) {
+        CHECK_FOR_FMT(ATI1);
+      } else {
+        CHECK_FOR_FMT(ATI2);
+      }
+      break;
     }
 
     // We don't support the compressed format.  Fall through.
   }
 
   if (compress_texture) {
+    if (num_color_channels == 1) {
+      CHECK_FOR_FMT(ATI1);
+    } else if (num_alpha_bits == 0 && num_color_channels == 2) {
+      CHECK_FOR_FMT(ATI2);
+    }
     if (num_alpha_bits <= 1) {
       CHECK_FOR_FMT(DXT1);
     } else if (num_alpha_bits <= 4) {
@@ -542,7 +555,7 @@ create_texture(DXScreenData &scrn) {
         CHECK_FOR_FMT(D16);
       } else {
         if (scrn._supported_tex_formats_mask & INTZ_FLAG) {
-          target_pixel_format = (D3DFORMAT)MAKEFOURCC('I', 'N', 'T', 'Z');
+          target_pixel_format = D3DFMT_INTZ;
           goto found_matching_format;
         }
 
@@ -587,7 +600,7 @@ create_texture(DXScreenData &scrn) {
         CHECK_FOR_FMT(D32);
       } else {
         if (scrn._supported_tex_formats_mask & INTZ_FLAG) {
-          target_pixel_format = (D3DFORMAT)MAKEFOURCC('I', 'N', 'T', 'Z');
+          target_pixel_format = D3DFMT_INTZ;
           goto found_matching_format;
         }
 
@@ -716,7 +729,7 @@ create_texture(DXScreenData &scrn) {
           << "GetDesc failed in create_texture: " << D3DERRORSTRING(hr);
       } else {
         if (target_pixel_format != surface_desc.Format &&
-            target_pixel_format != MAKEFOURCC('I', 'N', 'T', 'Z')) {
+            target_pixel_format != D3DFMT_INTZ) {
           if (dxgsg9_cat.is_debug()) {
             dxgsg9_cat.debug()
               << "Chose format " << D3DFormatStr(surface_desc.Format)
@@ -861,6 +874,25 @@ create_texture(DXScreenData &scrn) {
           << endl;
       }
     }
+
+    // DirectX will corrupt memory if we try to load mipmaps smaller than
+    // 4x4 for ATI1 or ATI2 textures.
+    if (target_pixel_format == D3DFMT_ATI1 ||
+        target_pixel_format == D3DFMT_ATI2) {
+
+      UINT dimension = min(target_height, target_width);
+      mip_level_count = 0;
+      while (dimension >= 4) {
+        ++mip_level_count;
+        dimension >>= 1;
+      }
+
+      if ((UINT)tex->get_num_ram_mipmap_images() < mip_level_count) {
+        // We also have to generate mipmaps on the CPU for these.
+        tex->generate_ram_mipmap_images();
+        mip_level_count = min(mip_level_count, (UINT)tex->get_num_ram_mipmap_images());
+      }
+    }
   } else {
     mip_level_count = 1;
   }
@@ -1254,6 +1286,11 @@ extract_texture_data(DXScreenData &screen) {
     compression = Texture::CM_dxt5;
     div = 4;
     break;
+  case D3DFMT_ATI1:
+  case D3DFMT_ATI2:
+    compression = Texture::CM_rgtc;
+    div = 4;
+    break;
 
   default:
     dxgsg9_cat.error()
@@ -1682,6 +1719,7 @@ static UINT calculate_row_byte_length (int width, int num_color_channels, D3DFOR
     // check for compressed textures and adjust source_row_byte_length and source_format accordingly
     switch (tex_format) {
       case D3DFMT_DXT1:
+      case D3DFMT_ATI1:
           // for dxt1 compressed textures, the row_byte_lenght is "the width of one row of cells, in bytes"
           // cells are 4 pixels wide, take up 8 bytes, and at least 1 cell has to be there.
           source_row_byte_length = max(1,width / 4)*8;
@@ -1690,6 +1728,7 @@ static UINT calculate_row_byte_length (int width, int num_color_channels, D3DFOR
       case D3DFMT_DXT3:
       case D3DFMT_DXT4:
       case D3DFMT_DXT5:
+      case D3DFMT_ATI2:
           // analogue as above, but cells take up 16 bytes
           source_row_byte_length = max(1,width / 4)*16;
         break;
@@ -1813,15 +1852,27 @@ HRESULT DXTextureContext9::fill_d3d_texture_mipmap_pixels(int mip_level, int dep
 #ifdef DO_PSTATS
   GraphicsStateGuardian::_data_transferred_pcollector.add_level(source_row_byte_length * height);
 #endif
-  hr = D3DXLoadSurfaceFromMemory
-    (mip_surface, (PALETTEENTRY*)NULL, (RECT*)NULL, (LPCVOID)pixels,
-      source_format, source_row_byte_length, (PALETTEENTRY*)NULL,
-      &source_size, mip_filter, (D3DCOLOR)0x0);
-  if (FAILED(hr)) {
-    dxgsg9_cat.error()
-      << "FillDDTextureMipmapPixels failed for " << get_texture()->get_name()
-      << ", mip_level " << mip_level
-      << ", D3DXLoadSurfFromMem failed" << D3DERRORSTRING(hr);
+  if (source_format == D3DFMT_ATI1 || source_format == D3DFMT_ATI2) {
+    // These formats are not supported by D3DXLoadSurfaceFromMemory.
+    D3DLOCKED_RECT rect;
+    _d3d_2d_texture->LockRect(mip_level, &rect, 0, D3DLOCK_DISCARD);
+
+    unsigned char *dest = (unsigned char *)rect.pBits;
+    memcpy(dest, pixels, view_size);
+
+    _d3d_2d_texture->UnlockRect(mip_level);
+
+  } else {
+    hr = D3DXLoadSurfaceFromMemory
+      (mip_surface, (PALETTEENTRY*)NULL, (RECT*)NULL, (LPCVOID)pixels,
+        source_format, source_row_byte_length, (PALETTEENTRY*)NULL,
+        &source_size, mip_filter, (D3DCOLOR)0x0);
+    if (FAILED(hr)) {
+      dxgsg9_cat.error()
+        << "FillDDTextureMipmapPixels failed for " << get_texture()->get_name()
+        << ", mip_level " << mip_level
+        << ", D3DXLoadSurfFromMem failed" << D3DERRORSTRING(hr);
+    }
   }
 
 exit_FillMipmapSurf:
@@ -1950,6 +2001,13 @@ fill_d3d_texture_pixels(DXScreenData &scrn, bool compress_texture) {
   case Texture::CM_dxt5:
     source_format = D3DFMT_DXT5;
     break;
+  case Texture::CM_rgtc:
+    if (tex->get_num_components() == 1) {
+      source_format = D3DFMT_ATI1;
+    } else {
+      source_format = D3DFMT_ATI2;
+    }
+    break;
   default:
     // no known compression format.. no adjustment
     break;
@@ -2369,7 +2427,7 @@ d3d_format_to_bytes_per_pixel (D3DFORMAT format)
     case D3DFMT_D24S8:
     case D3DFMT_D32:
     case (D3DFORMAT)MAKEFOURCC('D', 'F', '2', '4'):
-    case (D3DFORMAT)MAKEFOURCC('I', 'N', 'T', 'Z'):
+    case D3DFMT_INTZ:
       bytes_per_pixel = 4.0f;
       break;
 
@@ -2385,12 +2443,14 @@ d3d_format_to_bytes_per_pixel (D3DFORMAT format)
       break;
 
     case D3DFMT_DXT1:
+    case D3DFMT_ATI1:
       bytes_per_pixel = 0.5f;
       break;
     case D3DFMT_DXT2:
     case D3DFMT_DXT3:
     case D3DFMT_DXT4:
     case D3DFMT_DXT5:
+    case D3DFMT_ATI2:
       bytes_per_pixel = 1.0f;
       break;
   }

+ 6 - 2
panda/src/dxgsg9/dxgsg9base.h

@@ -172,8 +172,8 @@ typedef enum {
     INTZ_FLAG =         FLG(22),
     W11V11U10_FLAG =    FLG(23),
     A2W10V10U10_FLAG =  FLG(24),
-    UYVY_FLAG =         FLG(25),
-    YUY2_FLAG =         FLG(26),
+    ATI1_FLAG =         FLG(25),
+    ATI2_FLAG =         FLG(26),
     DXT1_FLAG =         FLG(27),
     DXT2_FLAG =         FLG(28),
     DXT3_FLAG =         FLG(29),
@@ -181,6 +181,10 @@ typedef enum {
     DXT5_FLAG =         FLG(31)
 } D3DFORMAT_FLAG;
 
+#define D3DFMT_INTZ ((D3DFORMAT)MAKEFOURCC('I', 'N', 'T', 'Z'))
+#define D3DFMT_ATI1 ((D3DFORMAT)MAKEFOURCC('A', 'T', 'I', '1'))
+#define D3DFMT_ATI2 ((D3DFORMAT)MAKEFOURCC('A', 'T', 'I', '2'))
+
 // this is only used in conjunction w/rendertgt fmts, so just make it something that can never be a rtgt
 #define DISPLAY_32BPP_REQUIRES_16BPP_ZBUFFER_FLAG DXT1_FLAG
 #define DISPLAY_16BPP_REQUIRES_16BPP_ZBUFFER_FLAG DXT2_FLAG

+ 6 - 5
panda/src/dxgsg9/wdxGraphicsPipe9.cxx

@@ -894,12 +894,12 @@ void Init_D3DFORMAT_map() {
   INSERT_ELEM(D24X8);
   INSERT_ELEM(D24S8);
   INSERT_ELEM(D32);
-  g_D3DFORMATmap[INTZ_FLAG] = (D3DFORMAT)MAKEFOURCC('I', 'N', 'T', 'Z');
+  INSERT_ELEM(INTZ);
 //  NOT IN DX9
 //  INSERT_ELEM(W11V11U10);
   INSERT_ELEM(A2W10V10U10);
-  INSERT_ELEM(UYVY);
-  INSERT_ELEM(YUY2);
+  INSERT_ELEM(ATI1);
+  INSERT_ELEM(ATI2);
   INSERT_ELEM(DXT1);
   INSERT_ELEM(DXT2);
   INSERT_ELEM(DXT3);
@@ -940,8 +940,8 @@ const char *D3DFormatStr(D3DFORMAT fmt) {
 //  NOT IN DX9
 //    CASESTR(D3DFMT_W11V11U10);
     CASESTR(D3DFMT_A2W10V10U10);
-    CASESTR(D3DFMT_UYVY);
-    CASESTR(D3DFMT_YUY2);
+    CASESTR(D3DFMT_ATI1);
+    CASESTR(D3DFMT_ATI2);
     CASESTR(D3DFMT_DXT1);
     CASESTR(D3DFMT_DXT2);
     CASESTR(D3DFMT_DXT3);
@@ -954,6 +954,7 @@ const char *D3DFormatStr(D3DFORMAT fmt) {
     CASESTR(D3DFMT_D16);
     CASESTR(D3DFMT_D24X8);
     CASESTR(D3DFMT_D24X4S4);
+    CASESTR(D3DFMT_INTZ);
     CASESTR(D3DFMT_VERTEXDATA);
     CASESTR(D3DFMT_INDEX16);
     CASESTR(D3DFMT_INDEX32);

+ 115 - 2
panda/src/glstuff/glGraphicsStateGuardian_src.cxx

@@ -1035,6 +1035,16 @@ reset() {
         break;
       }
     }
+
+#ifndef OPENGLES
+    // The OpenGL spec states that these are not reported by the above
+    // mechanism, so we have to check for the extension ourselves.
+    if (is_at_least_gl_version(3, 0) ||
+        has_extension("GL_ARB_texture_compression_rgtc") ||
+        has_extension("GL_EXT_texture_compression_rgtc")) {
+      _compressed_texture_formats.set_bit(Texture::CM_rgtc);
+    }
+#endif
   }
 
 #ifdef OPENGLES_2
@@ -8115,6 +8125,8 @@ get_component_type(Texture::ComponentType component_type) {
     return GL_BYTE;
   case Texture::T_short:
     return GL_SHORT;
+  case Texture::T_half_float:
+    return GL_HALF_FLOAT;
   default:
     GLCAT.error() << "Invalid Texture::Type value!\n";
     return GL_UNSIGNED_BYTE;
@@ -8144,6 +8156,7 @@ get_external_image_format(Texture *tex) const {
       case Texture::F_depth_component32:
       case Texture::F_depth_stencil:
       case Texture::F_r11_g11_b10:
+      case Texture::F_rgb9_e5:
         // This shouldn't be possible.
         nassertr(false, GL_RGB);
         break;
@@ -8156,6 +8169,7 @@ get_external_image_format(Texture *tex) const {
       case Texture::F_rgba16:
       case Texture::F_rgba32:
       case Texture::F_rgba8i:
+      case Texture::F_rgb10_a2:
         return GL_COMPRESSED_RGBA;
 
       case Texture::F_rgb:
@@ -8181,6 +8195,7 @@ get_external_image_format(Texture *tex) const {
       case Texture::F_r32i:
         return GL_COMPRESSED_RED;
 
+      case Texture::F_rg:
       case Texture::F_rg8i:
       case Texture::F_rg16:
       case Texture::F_rg32:
@@ -8274,6 +8289,20 @@ get_external_image_format(Texture *tex) const {
       break;
 #endif  // OPENGLES
 
+    case Texture::CM_rgtc:
+#ifndef OPENGLES
+      if (tex->get_format() == Texture::F_luminance) {
+        return GL_COMPRESSED_LUMINANCE_LATC1_EXT;
+      } else if (tex->get_format() == Texture::F_luminance_alpha) {
+        return GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT;
+      } else if (tex->get_num_components() == 1) {
+        return GL_COMPRESSED_RED_RGTC1;
+      } else {
+        return GL_COMPRESSED_RG_RGTC2;
+      }
+#endif
+      break;
+
     case Texture::CM_default:
     case Texture::CM_off:
     case Texture::CM_dxt2:
@@ -8315,6 +8344,7 @@ get_external_image_format(Texture *tex) const {
 #endif
 
 #ifndef OPENGLES_1
+  case Texture::F_rg:
   case Texture::F_rg16:
   case Texture::F_rg32:
     return GL_RG;
@@ -8328,6 +8358,7 @@ get_external_image_format(Texture *tex) const {
   case Texture::F_rgb32:
   case Texture::F_srgb:
   case Texture::F_r11_g11_b10:
+  case Texture::F_rgb9_e5:
 #ifdef OPENGLES
     return GL_RGB;
 #else
@@ -8342,6 +8373,7 @@ get_external_image_format(Texture *tex) const {
   case Texture::F_rgba16:
   case Texture::F_rgba32:
   case Texture::F_srgb_alpha:
+  case Texture::F_rgb10_a2:
 #ifdef OPENGLES_2
     return GL_RGBA;
 #else
@@ -8427,10 +8459,12 @@ get_internal_image_format(Texture *tex, bool force_sized) const {
       case Texture::F_rgba8i:
       case Texture::F_r32i:
       case Texture::F_r11_g11_b10:
+      case Texture::F_rgb9_e5:
         // Unsupported; fall through to below.
         break;
 
       case Texture::F_rgbm:
+      case Texture::F_rgb10_a2:
         if (get_supports_compressed_texture_format(Texture::CM_dxt1) && !is_3d) {
           return GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
         }
@@ -8512,7 +8546,9 @@ get_internal_image_format(Texture *tex, bool force_sized) const {
       case Texture::F_blue:
       case Texture::F_r16:
       case Texture::F_r32:
-        if (get_supports_compressed_texture_format(Texture::CM_dxt1) && !is_3d) {
+        if (get_supports_compressed_texture_format(Texture::CM_rgtc) && !is_3d) {
+          return GL_COMPRESSED_RED_RGTC1;
+        } else if (get_supports_compressed_texture_format(Texture::CM_dxt1) && !is_3d) {
           return GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
         }
 #ifndef OPENGLES
@@ -8523,9 +8559,12 @@ get_internal_image_format(Texture *tex, bool force_sized) const {
 #endif
         break;
 
+      case Texture::F_rg:
       case Texture::F_rg16:
       case Texture::F_rg32:
-        if (get_supports_compressed_texture_format(Texture::CM_dxt1) && !is_3d) {
+        if (get_supports_compressed_texture_format(Texture::CM_rgtc) && !is_3d) {
+          return GL_COMPRESSED_RG_RGTC2;
+        } else if (get_supports_compressed_texture_format(Texture::CM_dxt1) && !is_3d) {
           return GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
         }
 #ifndef OPENGLES
@@ -8657,6 +8696,20 @@ get_internal_image_format(Texture *tex, bool force_sized) const {
       break;
 #endif
 
+    case Texture::CM_rgtc:
+#ifndef OPENGLES
+      if (tex->get_format() == Texture::F_luminance) {
+        return GL_COMPRESSED_LUMINANCE_LATC1_EXT;
+      } else if (tex->get_format() == Texture::F_luminance_alpha) {
+        return GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT;
+      } else if (tex->get_num_components() == 1) {
+        return GL_COMPRESSED_RED_RGTC1;
+      } else if (tex->get_num_components() == 2) {
+        return GL_COMPRESSED_RG_RGTC2;
+      }
+#endif
+      break;
+
     case Texture::CM_default:
     case Texture::CM_off:
     case Texture::CM_dxt2:
@@ -8942,6 +8995,9 @@ get_internal_image_format(Texture *tex, bool force_sized) const {
     return force_sized ? GL_RG8 : GL_RG;
 #endif
 
+  case Texture::F_rg:
+    return force_sized ? GL_RG8 : GL_RG;
+
 #ifndef OPENGLES_1
   case Texture::F_srgb:
 #ifndef OPENGLES
@@ -8965,6 +9021,12 @@ get_internal_image_format(Texture *tex, bool force_sized) const {
 #ifndef OPENGLES
   case Texture::F_r11_g11_b10:
     return GL_R11F_G11F_B10F;
+
+  case Texture::F_rgb9_e5:
+    return GL_RGB9_E5;
+
+  case Texture::F_rgb10_a2:
+    return GL_RGB10_A2;
 #endif
 
   default:
@@ -9018,8 +9080,19 @@ is_compressed_format(GLenum format) {
   case GL_COMPRESSED_RGB_FXT1_3DFX:
   case GL_COMPRESSED_RGBA_FXT1_3DFX:
 
+  case GL_COMPRESSED_RED_RGTC1:
+  case GL_COMPRESSED_SIGNED_RED_RGTC1:
+  case GL_COMPRESSED_RG_RGTC2:
+  case GL_COMPRESSED_SIGNED_RG_RGTC2:
+  case GL_COMPRESSED_LUMINANCE_LATC1_EXT:
+  case GL_COMPRESSED_SIGNED_LUMINANCE_LATC1_EXT:
+  case GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT:
+  case GL_COMPRESSED_SIGNED_LUMINANCE_ALPHA_LATC2_EXT:
+
   case GL_COMPRESSED_RGB:
+  case GL_COMPRESSED_SRGB_EXT:
   case GL_COMPRESSED_RGBA:
+  case GL_COMPRESSED_SRGB_ALPHA_EXT:
   case GL_COMPRESSED_ALPHA:
   case GL_COMPRESSED_LUMINANCE:
   case GL_COMPRESSED_LUMINANCE_ALPHA:
@@ -11170,6 +11243,10 @@ upload_texture(CLP(TextureContext) *gtc, bool force, bool uses_mipmaps) {
   if (!get_supports_compressed_texture_format(image_compression)) {
     image = tex->get_uncompressed_ram_image();
     image_compression = Texture::CM_off;
+
+    // If this triggers, Panda cannot decompress the texture.  Compile
+    // with libsquish support or precompress the texture.
+    nassertr(!image.is_null(), false);
   }
 
   int mipmap_bias = 0;
@@ -12620,6 +12697,16 @@ do_extract_texture_data(CLP(TextureContext) *gtc) {
     type = Texture::T_float;
     format = Texture::F_r11_g11_b10;
     break;
+
+  case GL_RGB9_E5:
+    type = Texture::T_float;
+    format = Texture::F_rgb9_e5;
+    break;
+
+  case GL_RGB10_A2:
+    type = Texture::T_unsigned_short;
+    format = Texture::F_rgb10_a2;
+    break;
 #endif
 
 #ifdef OPENGLES_2
@@ -12790,6 +12877,32 @@ do_extract_texture_data(CLP(TextureContext) *gtc) {
     format = Texture::F_rgba;
     compression = Texture::CM_fxt1;
     break;
+  case GL_COMPRESSED_LUMINANCE_LATC1_EXT:
+    format = Texture::F_luminance;
+    compression = Texture::CM_rgtc;
+    break;
+  case GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT:
+    format = Texture::F_luminance_alpha;
+    compression = Texture::CM_rgtc;
+    break;
+  case GL_COMPRESSED_RED_RGTC1:
+    format = Texture::F_red;
+    compression = Texture::CM_rgtc;
+    break;
+  case GL_COMPRESSED_SIGNED_RED_RGTC1:
+    type = Texture::T_byte;
+    format = Texture::F_red;
+    compression = Texture::CM_rgtc;
+    break;
+  case GL_COMPRESSED_RG_RGTC2:
+    format = Texture::F_rg;
+    compression = Texture::CM_rgtc;
+    break;
+  case GL_COMPRESSED_SIGNED_RG_RGTC2:
+    type = Texture::T_byte;
+    format = Texture::F_rg;
+    compression = Texture::CM_rgtc;
+    break;
 #endif
   default:
     GLCAT.warning()

File diff suppressed because it is too large
+ 867 - 18
panda/src/gobj/texture.cxx


+ 39 - 14
panda/src/gobj/texture.h

@@ -95,6 +95,7 @@ PUBLISHED:
     T_int,
     T_byte,
     T_short,
+    T_half_float,
   };
 
   enum Format {
@@ -160,7 +161,10 @@ PUBLISHED:
     F_rgba8i, // 8 integer bits per R,G,B,A channel
 
     F_r11_g11_b10, // unsigned floating-point, 11 Red, 11 Green, 10 Blue Bits
+    F_rgb9_e5,
+    F_rgb10_a2,
 
+    F_rg,
   };
 
   // Deprecated.  See SamplerState.FilterType.
@@ -201,13 +205,14 @@ PUBLISHED:
     // GSG::get_supports_compressed_texture_format() to query the
     // available compression modes for a particular GSG.
     CM_fxt1,
-    CM_dxt1,
-    CM_dxt2,
-    CM_dxt3,
-    CM_dxt4,
-    CM_dxt5,
+    CM_dxt1, // BC1: RGB with optional binary alpha.
+    CM_dxt2, // Like DXT3, but assumes premultiplied alpha
+    CM_dxt3, // BC2: RGB with uncompressed 4-bit alpha.
+    CM_dxt4, // Like DXT5, but assumes premultiplied alpha
+    CM_dxt5, // BC3: RGB with separately compressed 8-bit alpha.
     CM_pvr1_2bpp,
     CM_pvr1_4bpp,
+    CM_rgtc, // BC4/BC5: 1 or 2 channels, individually compressed.
   };
 
   enum QualityLevel {
@@ -568,6 +573,7 @@ public:
 
 protected:
   class CData;
+  class RamImage;
 
   virtual void reconsider_dirty();
 
@@ -633,6 +639,15 @@ protected:
                              QualityLevel quality_level,
                              GraphicsStateGuardianBase *gsg);
   bool do_uncompress_ram_image(CData *cdata);
+
+  static void do_compress_ram_image_bc4(const RamImage &src, RamImage &dest,
+                                        int x_size, int y_size, int z_size);
+  static void do_compress_ram_image_bc5(const RamImage &src, RamImage &dest,
+                                        int x_size, int y_size, int z_size);
+  static void do_uncompress_ram_image_bc4(const RamImage &src, RamImage &dest,
+                                          int x_size, int y_size, int z_size);
+  static void do_uncompress_ram_image_bc5(const RamImage &src, RamImage &dest,
+                                          int x_size, int y_size, int z_size);
   bool do_has_all_ram_mipmap_images(const CData *cdata) const;
 
   bool do_reconsider_z_size(CData *cdata, int z, const LoaderOptions &options);
@@ -738,21 +753,31 @@ private:
                                         int n, istream &in);
   static PTA_uchar read_dds_level_rgba8(Texture *tex, CData *cdata, const DDSHeader &header,
                                         int n, istream &in);
+  static PTA_uchar read_dds_level_abgr16(Texture *tex, CData *cdata, const DDSHeader &header,
+                                         int n, istream &in);
+  static PTA_uchar read_dds_level_abgr32(Texture *tex, CData *cdata, const DDSHeader &header,
+                                         int n, istream &in);
   static PTA_uchar read_dds_level_generic_uncompressed(Texture *tex, CData *cdata,
                                                        const DDSHeader &header,
                                                        int n, istream &in);
   static PTA_uchar read_dds_level_luminance_uncompressed(Texture *tex, CData *cdata,
                                                          const DDSHeader &header,
                                                          int n, istream &in);
-  static PTA_uchar read_dds_level_dxt1(Texture *tex, CData *cdata,
-                                       const DDSHeader &header,
-                                       int n, istream &in);
-  static PTA_uchar read_dds_level_dxt23(Texture *tex, CData *cdata,
-                                        const DDSHeader &header,
-                                        int n, istream &in);
-  static PTA_uchar read_dds_level_dxt45(Texture *tex, CData *cdata,
-                                        const DDSHeader &header,
-                                        int n, istream &in);
+  static PTA_uchar read_dds_level_bc1(Texture *tex, CData *cdata,
+                                      const DDSHeader &header,
+                                      int n, istream &in);
+  static PTA_uchar read_dds_level_bc2(Texture *tex, CData *cdata,
+                                      const DDSHeader &header,
+                                      int n, istream &in);
+  static PTA_uchar read_dds_level_bc3(Texture *tex, CData *cdata,
+                                      const DDSHeader &header,
+                                      int n, istream &in);
+  static PTA_uchar read_dds_level_bc4(Texture *tex, CData *cdata,
+                                      const DDSHeader &header,
+                                      int n, istream &in);
+  static PTA_uchar read_dds_level_bc5(Texture *tex, CData *cdata,
+                                      const DDSHeader &header,
+                                      int n, istream &in);
 
   void clear_prepared(int view, PreparedGraphicsObjects *prepared_objects);
 

Some files were not shown because too many files changed in this diff