rsx: Support partial texture descriptors

- It is safe to declare w > pitch and it works as long as sampling inside the legal 2D area is obeyed.
This commit is contained in:
kd-11 2020-07-08 23:47:40 +03:00 committed by kd-11
parent 282b00674a
commit 632af8d723
2 changed files with 46 additions and 23 deletions

View File

@ -457,7 +457,8 @@ std::vector<rsx_subresource_layout> get_subresources_layout_impl(const RsxTextur
std::tie(h, depth, layer) = get_height_depth_layer(texture);
int format = texture.format() & ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN);
const auto format = texture.format() & ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN);
const auto pitch = texture.pitch();
const u32 texaddr = rsx::get_address(texture.offset(), texture.location(), HERE);
auto pixels = vm::_ptr<const std::byte>(texaddr);
@ -465,10 +466,26 @@ std::vector<rsx_subresource_layout> get_subresources_layout_impl(const RsxTextur
const bool is_swizzled = !(texture.format() & CELL_GCM_TEXTURE_LN);
const bool has_border = !texture.border_type();
if (!is_swizzled)
{
if (pitch) [[likely]]
{
if (pitch < get_format_packed_pitch(format, w, has_border, false))
{
const u32 real_width_in_block = pitch / get_format_block_size_in_bytes(format);
w = std::max<u16>(real_width_in_block * get_format_block_size_in_texel(format), 1);
}
}
else
{
w = h = depth = 1;
}
}
switch (format)
{
case CELL_GCM_TEXTURE_B8:
return get_subresources_layout_impl<1, u8>(pixels, w, h, depth, layer, texture.get_exact_mipmap_count(), texture.pitch(), !is_swizzled, has_border);
return get_subresources_layout_impl<1, u8>(pixels, w, h, depth, layer, texture.get_exact_mipmap_count(), pitch, !is_swizzled, has_border);
case CELL_GCM_TEXTURE_COMPRESSED_B8R8_G8R8:
case CELL_GCM_TEXTURE_COMPRESSED_R8B8_R8G8:
case CELL_GCM_TEXTURE_COMPRESSED_HILO8:
@ -483,7 +500,7 @@ std::vector<rsx_subresource_layout> get_subresources_layout_impl(const RsxTextur
case CELL_GCM_TEXTURE_R6G5B5:
case CELL_GCM_TEXTURE_G8B8:
case CELL_GCM_TEXTURE_X16:
return get_subresources_layout_impl<1, u16>(pixels, w, h, depth, layer, texture.get_exact_mipmap_count(), texture.pitch(), !is_swizzled, has_border);
return get_subresources_layout_impl<1, u16>(pixels, w, h, depth, layer, texture.get_exact_mipmap_count(), pitch, !is_swizzled, has_border);
case CELL_GCM_TEXTURE_DEPTH24_D8: // Untested
case CELL_GCM_TEXTURE_DEPTH24_D8_FLOAT: // Untested
case CELL_GCM_TEXTURE_D8R8G8B8:
@ -491,16 +508,16 @@ std::vector<rsx_subresource_layout> get_subresources_layout_impl(const RsxTextur
case CELL_GCM_TEXTURE_Y16_X16:
case CELL_GCM_TEXTURE_Y16_X16_FLOAT:
case CELL_GCM_TEXTURE_X32_FLOAT:
return get_subresources_layout_impl<1, u32>(pixels, w, h, depth, layer, texture.get_exact_mipmap_count(), texture.pitch(), !is_swizzled, has_border);
return get_subresources_layout_impl<1, u32>(pixels, w, h, depth, layer, texture.get_exact_mipmap_count(), pitch, !is_swizzled, has_border);
case CELL_GCM_TEXTURE_W16_Z16_Y16_X16_FLOAT:
return get_subresources_layout_impl<1, u64>(pixels, w, h, depth, layer, texture.get_exact_mipmap_count(), texture.pitch(), !is_swizzled, has_border);
return get_subresources_layout_impl<1, u64>(pixels, w, h, depth, layer, texture.get_exact_mipmap_count(), pitch, !is_swizzled, has_border);
case CELL_GCM_TEXTURE_W32_Z32_Y32_X32_FLOAT:
return get_subresources_layout_impl<1, u128>(pixels, w, h, depth, layer, texture.get_exact_mipmap_count(), texture.pitch(), !is_swizzled, has_border);
return get_subresources_layout_impl<1, u128>(pixels, w, h, depth, layer, texture.get_exact_mipmap_count(), pitch, !is_swizzled, has_border);
case CELL_GCM_TEXTURE_COMPRESSED_DXT1:
return get_subresources_layout_impl<4, u64>(pixels, w, h, depth, layer, texture.get_exact_mipmap_count(), texture.pitch(), !is_swizzled, false);
return get_subresources_layout_impl<4, u64>(pixels, w, h, depth, layer, texture.get_exact_mipmap_count(), pitch, !is_swizzled, false);
case CELL_GCM_TEXTURE_COMPRESSED_DXT23:
case CELL_GCM_TEXTURE_COMPRESSED_DXT45:
return get_subresources_layout_impl<4, u128>(pixels, w, h, depth, layer, texture.get_exact_mipmap_count(), texture.pitch(), !is_swizzled, false);
return get_subresources_layout_impl<4, u128>(pixels, w, h, depth, layer, texture.get_exact_mipmap_count(), pitch, !is_swizzled, false);
}
fmt::throw_exception("Wrong format 0x%x" HERE, format);
}

View File

@ -1731,17 +1731,36 @@ namespace rsx
u8 subsurface_count;
size2f scale{ 1.f, 1.f };
if (is_unnormalized)
{
if (extended_dimension <= rsx::texture_dimension_extended::texture_dimension_2d)
{
scale.width /= attributes.width;
scale.height /= attributes.height;
}
else
{
rsx_log.error("Unimplemented unnormalized sampling for texture type %d", static_cast<u32>(extended_dimension));
}
}
const auto packed_pitch = get_format_packed_pitch(attributes.gcm_format, attributes.width, !tex.border_type(), is_swizzled);
if (!is_swizzled) [[likely]]
{
if (attributes.pitch = tex.pitch(); !attributes.pitch)
{
attributes.pitch = get_format_packed_pitch(attributes.gcm_format, attributes.width, !tex.border_type(), false);
attributes.pitch = packed_pitch;
scale = { 0.f, 0.f };
}
else if (packed_pitch > attributes.pitch && !options.is_compressed_format)
{
scale.width *= f32(packed_pitch) / attributes.pitch;
attributes.width = attributes.pitch / attributes.bpp;
}
}
else
{
attributes.pitch = get_format_packed_pitch(attributes.gcm_format, attributes.width, !tex.border_type(), true);
attributes.pitch = packed_pitch;
}
switch (extended_dimension)
@ -1774,19 +1793,6 @@ namespace rsx
break;
}
if (is_unnormalized)
{
if (extended_dimension <= rsx::texture_dimension_extended::texture_dimension_2d)
{
scale.width /= attributes.width;
scale.height /= attributes.height;
}
else
{
rsx_log.error("Unimplemented unnormalized sampling for texture type %d", static_cast<u32>(extended_dimension));
}
}
if (options.is_compressed_format)
{
// Compressed textures cannot be 1D in some APIs