rsx/common: Make get_exact_mipmap_count take compressed format into account

This commit is contained in:
Vincent Lejeune 2016-03-29 18:24:25 +02:00
parent 0c231e6578
commit b7c539ad7a
3 changed files with 25 additions and 7 deletions

View File

@ -152,7 +152,7 @@ std::vector<rsx_subresource_layout> get_subresources_layout(const rsx::texture &
{ {
case CELL_GCM_TEXTURE_D8R8G8B8: case CELL_GCM_TEXTURE_D8R8G8B8:
case CELL_GCM_TEXTURE_A8R8G8B8: case CELL_GCM_TEXTURE_A8R8G8B8:
return get_subresources_layout_impl<1, u32>(pixels, w, h, depth, layer, texture.mipmap(), texture.pitch(), !is_swizzled); return get_subresources_layout_impl<1, u32>(pixels, w, h, depth, layer, texture.get_exact_mipmap_count(), texture.pitch(), !is_swizzled);
case CELL_GCM_TEXTURE_DEPTH16: case CELL_GCM_TEXTURE_DEPTH16:
case CELL_GCM_TEXTURE_D1R5G5B5: case CELL_GCM_TEXTURE_D1R5G5B5:
case CELL_GCM_TEXTURE_A1R5G5B5: case CELL_GCM_TEXTURE_A1R5G5B5:
@ -160,16 +160,16 @@ std::vector<rsx_subresource_layout> get_subresources_layout(const rsx::texture &
case CELL_GCM_TEXTURE_A4R4G4B4: case CELL_GCM_TEXTURE_A4R4G4B4:
case CELL_GCM_TEXTURE_R5G6B5: case CELL_GCM_TEXTURE_R5G6B5:
case CELL_GCM_TEXTURE_G8B8: case CELL_GCM_TEXTURE_G8B8:
return get_subresources_layout_impl<1, u16>(pixels, w, h, depth, layer, texture.mipmap(), texture.pitch(), !is_swizzled); return get_subresources_layout_impl<1, u16>(pixels, w, h, depth, layer, texture.get_exact_mipmap_count(), texture.pitch(), !is_swizzled);
case CELL_GCM_TEXTURE_W16_Z16_Y16_X16_FLOAT: case CELL_GCM_TEXTURE_W16_Z16_Y16_X16_FLOAT:
return get_subresources_layout_impl<1, u64>(pixels, w, h, depth, layer, texture.mipmap(), texture.pitch(), !is_swizzled); return get_subresources_layout_impl<1, u64>(pixels, w, h, depth, layer, texture.get_exact_mipmap_count(), texture.pitch(), !is_swizzled);
case CELL_GCM_TEXTURE_COMPRESSED_DXT1: case CELL_GCM_TEXTURE_COMPRESSED_DXT1:
return get_subresources_layout_impl<4, u64>(pixels, w, h, depth, layer, texture.mipmap(), texture.pitch(), !is_swizzled); return get_subresources_layout_impl<4, u64>(pixels, w, h, depth, layer, texture.get_exact_mipmap_count(), texture.pitch(), !is_swizzled);
case CELL_GCM_TEXTURE_COMPRESSED_DXT23: case CELL_GCM_TEXTURE_COMPRESSED_DXT23:
case CELL_GCM_TEXTURE_COMPRESSED_DXT45: case CELL_GCM_TEXTURE_COMPRESSED_DXT45:
return get_subresources_layout_impl<4, u128>(pixels, w, h, depth, layer, texture.mipmap(), texture.pitch(), !is_swizzled); return get_subresources_layout_impl<4, u128>(pixels, w, h, depth, layer, texture.get_exact_mipmap_count(), texture.pitch(), !is_swizzled);
case CELL_GCM_TEXTURE_B8: case CELL_GCM_TEXTURE_B8:
return get_subresources_layout_impl<1, u8>(pixels, w, h, depth, layer, texture.mipmap(), texture.pitch(), !is_swizzled); return get_subresources_layout_impl<1, u8>(pixels, w, h, depth, layer, texture.get_exact_mipmap_count(), texture.pitch(), !is_swizzled);
} }
throw EXCEPTION("Wrong format %d", format); throw EXCEPTION("Wrong format %d", format);
} }

View File

@ -70,6 +70,16 @@ namespace rsx
return ((method_registers[NV4097_SET_TEXTURE_FORMAT + (m_index * 8)] >> 8) & 0xff); return ((method_registers[NV4097_SET_TEXTURE_FORMAT + (m_index * 8)] >> 8) & 0xff);
} }
bool texture::is_compressed_format() const
{
int texture_format = format() & ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN);
if (texture_format == CELL_GCM_TEXTURE_COMPRESSED_DXT1 ||
texture_format == CELL_GCM_TEXTURE_COMPRESSED_DXT23 ||
texture_format == CELL_GCM_TEXTURE_COMPRESSED_DXT45)
return true;
return false;
}
u16 texture::mipmap() const u16 texture::mipmap() const
{ {
return ((method_registers[NV4097_SET_TEXTURE_FORMAT + (m_index * 8)] >> 16) & 0xffff); return ((method_registers[NV4097_SET_TEXTURE_FORMAT + (m_index * 8)] >> 16) & 0xffff);
@ -77,7 +87,14 @@ namespace rsx
u16 texture::get_exact_mipmap_count() const u16 texture::get_exact_mipmap_count() const
{ {
u16 max_mipmap_count = static_cast<u16>(floor(log2(std::max(width(), height()))) + 1); if (is_compressed_format())
{
// OpenGL considers that highest mipmap level for DXTC format is when either width or height is 1
// not both. Assume it's the same for others backend.
u16 max_mipmap_count = static_cast<u16>(floor(log2(std::min(width() / 4, height() / 4))) + 1);
return std::min(mipmap(), max_mipmap_count);
}
u16 max_mipmap_count = static_cast<u16>(floor(log2(std::max(width(), height()))) + 1) - 2;
return std::min(mipmap(), max_mipmap_count); return std::min(mipmap(), max_mipmap_count);
} }

View File

@ -21,6 +21,7 @@ namespace rsx
u8 border_type() const; u8 border_type() const;
rsx::texture_dimension dimension() const; rsx::texture_dimension dimension() const;
u8 format() const; u8 format() const;
bool is_compressed_format() const;
u16 mipmap() const; u16 mipmap() const;
/** /**
* mipmap() returns value from register which can be higher than the actual number of mipmap level. * mipmap() returns value from register which can be higher than the actual number of mipmap level.