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); 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); const u32 texaddr = rsx::get_address(texture.offset(), texture.location(), HERE);
auto pixels = vm::_ptr<const std::byte>(texaddr); 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 is_swizzled = !(texture.format() & CELL_GCM_TEXTURE_LN);
const bool has_border = !texture.border_type(); 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) switch (format)
{ {
case CELL_GCM_TEXTURE_B8: 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_B8R8_G8R8:
case CELL_GCM_TEXTURE_COMPRESSED_R8B8_R8G8: case CELL_GCM_TEXTURE_COMPRESSED_R8B8_R8G8:
case CELL_GCM_TEXTURE_COMPRESSED_HILO8: 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_R6G5B5:
case CELL_GCM_TEXTURE_G8B8: case CELL_GCM_TEXTURE_G8B8:
case CELL_GCM_TEXTURE_X16: 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: // Untested
case CELL_GCM_TEXTURE_DEPTH24_D8_FLOAT: // Untested case CELL_GCM_TEXTURE_DEPTH24_D8_FLOAT: // Untested
case CELL_GCM_TEXTURE_D8R8G8B8: 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:
case CELL_GCM_TEXTURE_Y16_X16_FLOAT: case CELL_GCM_TEXTURE_Y16_X16_FLOAT:
case CELL_GCM_TEXTURE_X32_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: 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: 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: 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_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.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); fmt::throw_exception("Wrong format 0x%x" HERE, format);
} }

View File

@ -1731,17 +1731,36 @@ namespace rsx
u8 subsurface_count; u8 subsurface_count;
size2f scale{ 1.f, 1.f }; 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 (!is_swizzled) [[likely]]
{ {
if (attributes.pitch = tex.pitch(); !attributes.pitch) 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 }; 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 else
{ {
attributes.pitch = get_format_packed_pitch(attributes.gcm_format, attributes.width, !tex.border_type(), true); attributes.pitch = packed_pitch;
} }
switch (extended_dimension) switch (extended_dimension)
@ -1774,19 +1793,6 @@ namespace rsx
break; 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) if (options.is_compressed_format)
{ {
// Compressed textures cannot be 1D in some APIs // Compressed textures cannot be 1D in some APIs