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

This commit is contained in:
rdb 2016-01-28 13:16:53 +01:00
parent 0a366e987f
commit 17ad8f254d
7 changed files with 1358 additions and 78 deletions

View File

@ -2662,13 +2662,13 @@ reset() {
_supports_shadow_filter = _supports_depth_texture; _supports_shadow_filter = _supports_depth_texture;
// check if compressed textures are supported // check if compressed textures are supported
#define CHECK_FOR_DXTVERSION(num) \ #define CHECK_COMPRESSED_FMT(mode, fmt) \
if (_screen->_supported_tex_formats_mask & DXT##num##_FLAG) {\ if (_screen->_supported_tex_formats_mask & fmt##_FLAG) {\
if (dxgsg9_cat.is_debug()) {\ 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;\ _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) { if (_screen->_intel_compressed_texture_bug) {
@ -2679,14 +2679,16 @@ reset() {
} else { } else {
// Check for available compressed formats normally. // Check for available compressed formats normally.
CHECK_FOR_DXTVERSION(1); CHECK_COMPRESSED_FMT(CM_dxt1, DXT1);
CHECK_FOR_DXTVERSION(2); CHECK_COMPRESSED_FMT(CM_dxt2, DXT2);
CHECK_FOR_DXTVERSION(3); CHECK_COMPRESSED_FMT(CM_dxt3, DXT3);
CHECK_FOR_DXTVERSION(4); CHECK_COMPRESSED_FMT(CM_dxt4, DXT4);
CHECK_FOR_DXTVERSION(5); 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; _screen->_supports_rgba16f_texture_format = false;
hr = _screen->_d3d9->CheckDeviceFormat(_screen->_card_id, D3DDEVTYPE_HAL, _screen->_display_mode.Format, 0x0, D3DRTYPE_TEXTURE, D3DFMT_A16B16G16R16F); 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() { close_gsg() {
GraphicsStateGuardian::close_gsg(); GraphicsStateGuardian::close_gsg();
if (_prepared_objects.is_null()) {
return;
}
if (dxgsg9_cat.is_debug()) { if (dxgsg9_cat.is_debug()) {
dxgsg9_cat.debug() dxgsg9_cat.debug()
<< "Closing GSG, prepared_objects count = " << "Closing GSG, prepared_objects count = "

View File

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

View File

@ -172,8 +172,8 @@ typedef enum {
INTZ_FLAG = FLG(22), INTZ_FLAG = FLG(22),
W11V11U10_FLAG = FLG(23), W11V11U10_FLAG = FLG(23),
A2W10V10U10_FLAG = FLG(24), A2W10V10U10_FLAG = FLG(24),
UYVY_FLAG = FLG(25), ATI1_FLAG = FLG(25),
YUY2_FLAG = FLG(26), ATI2_FLAG = FLG(26),
DXT1_FLAG = FLG(27), DXT1_FLAG = FLG(27),
DXT2_FLAG = FLG(28), DXT2_FLAG = FLG(28),
DXT3_FLAG = FLG(29), DXT3_FLAG = FLG(29),
@ -181,6 +181,10 @@ typedef enum {
DXT5_FLAG = FLG(31) DXT5_FLAG = FLG(31)
} D3DFORMAT_FLAG; } 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 // 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_32BPP_REQUIRES_16BPP_ZBUFFER_FLAG DXT1_FLAG
#define DISPLAY_16BPP_REQUIRES_16BPP_ZBUFFER_FLAG DXT2_FLAG #define DISPLAY_16BPP_REQUIRES_16BPP_ZBUFFER_FLAG DXT2_FLAG

View File

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

View File

@ -1035,6 +1035,16 @@ reset() {
break; 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 #ifdef OPENGLES_2
@ -8115,6 +8125,8 @@ get_component_type(Texture::ComponentType component_type) {
return GL_BYTE; return GL_BYTE;
case Texture::T_short: case Texture::T_short:
return GL_SHORT; return GL_SHORT;
case Texture::T_half_float:
return GL_HALF_FLOAT;
default: default:
GLCAT.error() << "Invalid Texture::Type value!\n"; GLCAT.error() << "Invalid Texture::Type value!\n";
return GL_UNSIGNED_BYTE; return GL_UNSIGNED_BYTE;
@ -8144,6 +8156,7 @@ get_external_image_format(Texture *tex) const {
case Texture::F_depth_component32: case Texture::F_depth_component32:
case Texture::F_depth_stencil: case Texture::F_depth_stencil:
case Texture::F_r11_g11_b10: case Texture::F_r11_g11_b10:
case Texture::F_rgb9_e5:
// This shouldn't be possible. // This shouldn't be possible.
nassertr(false, GL_RGB); nassertr(false, GL_RGB);
break; break;
@ -8156,6 +8169,7 @@ get_external_image_format(Texture *tex) const {
case Texture::F_rgba16: case Texture::F_rgba16:
case Texture::F_rgba32: case Texture::F_rgba32:
case Texture::F_rgba8i: case Texture::F_rgba8i:
case Texture::F_rgb10_a2:
return GL_COMPRESSED_RGBA; return GL_COMPRESSED_RGBA;
case Texture::F_rgb: case Texture::F_rgb:
@ -8181,6 +8195,7 @@ get_external_image_format(Texture *tex) const {
case Texture::F_r32i: case Texture::F_r32i:
return GL_COMPRESSED_RED; return GL_COMPRESSED_RED;
case Texture::F_rg:
case Texture::F_rg8i: case Texture::F_rg8i:
case Texture::F_rg16: case Texture::F_rg16:
case Texture::F_rg32: case Texture::F_rg32:
@ -8274,6 +8289,20 @@ get_external_image_format(Texture *tex) const {
break; break;
#endif // OPENGLES #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_default:
case Texture::CM_off: case Texture::CM_off:
case Texture::CM_dxt2: case Texture::CM_dxt2:
@ -8315,6 +8344,7 @@ get_external_image_format(Texture *tex) const {
#endif #endif
#ifndef OPENGLES_1 #ifndef OPENGLES_1
case Texture::F_rg:
case Texture::F_rg16: case Texture::F_rg16:
case Texture::F_rg32: case Texture::F_rg32:
return GL_RG; return GL_RG;
@ -8328,6 +8358,7 @@ get_external_image_format(Texture *tex) const {
case Texture::F_rgb32: case Texture::F_rgb32:
case Texture::F_srgb: case Texture::F_srgb:
case Texture::F_r11_g11_b10: case Texture::F_r11_g11_b10:
case Texture::F_rgb9_e5:
#ifdef OPENGLES #ifdef OPENGLES
return GL_RGB; return GL_RGB;
#else #else
@ -8342,6 +8373,7 @@ get_external_image_format(Texture *tex) const {
case Texture::F_rgba16: case Texture::F_rgba16:
case Texture::F_rgba32: case Texture::F_rgba32:
case Texture::F_srgb_alpha: case Texture::F_srgb_alpha:
case Texture::F_rgb10_a2:
#ifdef OPENGLES_2 #ifdef OPENGLES_2
return GL_RGBA; return GL_RGBA;
#else #else
@ -8427,10 +8459,12 @@ get_internal_image_format(Texture *tex, bool force_sized) const {
case Texture::F_rgba8i: case Texture::F_rgba8i:
case Texture::F_r32i: case Texture::F_r32i:
case Texture::F_r11_g11_b10: case Texture::F_r11_g11_b10:
case Texture::F_rgb9_e5:
// Unsupported; fall through to below. // Unsupported; fall through to below.
break; break;
case Texture::F_rgbm: case Texture::F_rgbm:
case Texture::F_rgb10_a2:
if (get_supports_compressed_texture_format(Texture::CM_dxt1) && !is_3d) { if (get_supports_compressed_texture_format(Texture::CM_dxt1) && !is_3d) {
return GL_COMPRESSED_RGBA_S3TC_DXT1_EXT; 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_blue:
case Texture::F_r16: case Texture::F_r16:
case Texture::F_r32: 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; return GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
} }
#ifndef OPENGLES #ifndef OPENGLES
@ -8523,9 +8559,12 @@ get_internal_image_format(Texture *tex, bool force_sized) const {
#endif #endif
break; break;
case Texture::F_rg:
case Texture::F_rg16: case Texture::F_rg16:
case Texture::F_rg32: 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; return GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
} }
#ifndef OPENGLES #ifndef OPENGLES
@ -8657,6 +8696,20 @@ get_internal_image_format(Texture *tex, bool force_sized) const {
break; break;
#endif #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_default:
case Texture::CM_off: case Texture::CM_off:
case Texture::CM_dxt2: 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; return force_sized ? GL_RG8 : GL_RG;
#endif #endif
case Texture::F_rg:
return force_sized ? GL_RG8 : GL_RG;
#ifndef OPENGLES_1 #ifndef OPENGLES_1
case Texture::F_srgb: case Texture::F_srgb:
#ifndef OPENGLES #ifndef OPENGLES
@ -8965,6 +9021,12 @@ get_internal_image_format(Texture *tex, bool force_sized) const {
#ifndef OPENGLES #ifndef OPENGLES
case Texture::F_r11_g11_b10: case Texture::F_r11_g11_b10:
return GL_R11F_G11F_B10F; return GL_R11F_G11F_B10F;
case Texture::F_rgb9_e5:
return GL_RGB9_E5;
case Texture::F_rgb10_a2:
return GL_RGB10_A2;
#endif #endif
default: default:
@ -9018,8 +9080,19 @@ is_compressed_format(GLenum format) {
case GL_COMPRESSED_RGB_FXT1_3DFX: case GL_COMPRESSED_RGB_FXT1_3DFX:
case GL_COMPRESSED_RGBA_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_RGB:
case GL_COMPRESSED_SRGB_EXT:
case GL_COMPRESSED_RGBA: case GL_COMPRESSED_RGBA:
case GL_COMPRESSED_SRGB_ALPHA_EXT:
case GL_COMPRESSED_ALPHA: case GL_COMPRESSED_ALPHA:
case GL_COMPRESSED_LUMINANCE: case GL_COMPRESSED_LUMINANCE:
case GL_COMPRESSED_LUMINANCE_ALPHA: 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)) { if (!get_supports_compressed_texture_format(image_compression)) {
image = tex->get_uncompressed_ram_image(); image = tex->get_uncompressed_ram_image();
image_compression = Texture::CM_off; 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; int mipmap_bias = 0;
@ -12620,6 +12697,16 @@ do_extract_texture_data(CLP(TextureContext) *gtc) {
type = Texture::T_float; type = Texture::T_float;
format = Texture::F_r11_g11_b10; format = Texture::F_r11_g11_b10;
break; 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 #endif
#ifdef OPENGLES_2 #ifdef OPENGLES_2
@ -12790,6 +12877,32 @@ do_extract_texture_data(CLP(TextureContext) *gtc) {
format = Texture::F_rgba; format = Texture::F_rgba;
compression = Texture::CM_fxt1; compression = Texture::CM_fxt1;
break; 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 #endif
default: default:
GLCAT.warning() GLCAT.warning()

File diff suppressed because it is too large Load Diff

View File

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