rsx: Propagate raster type of fbo sourced data throughout the pipeline.

- Tracks which kind of raster was done (Z-ordered vs linear) throughout the application.
- This allows to identify if data is in the expected format or not.
This commit is contained in:
kd-11 2020-08-01 14:27:13 +03:00 committed by kd-11
parent 107129f95a
commit 4df933275b
14 changed files with 73 additions and 25 deletions

View File

@ -52,6 +52,8 @@ namespace rsx
bool m_invalidate_on_write = false;
bool m_skip_write_updates = false;
rsx::surface_raster_type m_active_raster_type = rsx::surface_raster_type::linear;
public:
std::pair<u8, u8> m_bound_render_targets_config = {};
std::array<std::pair<u32, surface_type>, 4> m_bound_render_targets = {};
@ -672,6 +674,7 @@ namespace rsx
u32 clip_horizontal_reg, u32 clip_vertical_reg,
surface_target set_surface_target,
surface_antialiasing antialias,
surface_raster_type raster_type,
const std::array<u32, 4> &surface_addresses, u32 address_z,
const std::array<u32, 4> &surface_pitch, u32 zeta_pitch,
Args&&... extra_params)
@ -681,6 +684,7 @@ namespace rsx
cache_tag = rsx::get_shared_tag();
m_invalidate_on_write = (antialias != rsx::surface_antialiasing::center_1_sample);
m_active_raster_type = raster_type;
m_bound_buffers_count = 0;
// Make previous RTTs sampleable
@ -995,7 +999,7 @@ namespace rsx
auto& surface = m_bound_render_targets[i].second;
if (surface->last_use_tag != write_tag)
{
m_bound_render_targets[i].second->on_write(write_tag);
m_bound_render_targets[i].second->on_write(write_tag, surface_state_flags::require_resolve, m_active_raster_type);
}
else if (m_invalidate_on_write)
{
@ -1011,7 +1015,7 @@ namespace rsx
auto& surface = m_bound_depth_stencil.second;
if (surface->last_use_tag != write_tag)
{
m_bound_depth_stencil.second->on_write(write_tag);
m_bound_depth_stencil.second->on_write(write_tag, surface_state_flags::require_resolve, m_active_raster_type);
}
else if (m_invalidate_on_write)
{

View File

@ -139,6 +139,7 @@ namespace rsx
std::unique_ptr<typename std::remove_pointer<image_storage_type>::type> resolve_surface;
surface_sample_layout sample_layout = surface_sample_layout::null;
surface_raster_type raster_type = surface_raster_type::linear;
flags32_t memory_usage_flags = surface_usage_flags::unknown;
flags32_t state_flags = surface_state_flags::ready;
@ -506,7 +507,9 @@ namespace rsx
}
}
void on_write(u64 write_tag = 0, rsx::surface_state_flags resolve_flags = surface_state_flags::require_resolve)
void on_write(u64 write_tag = 0,
rsx::surface_state_flags resolve_flags = surface_state_flags::require_resolve,
surface_raster_type type = rsx::surface_raster_type::undefined)
{
if (write_tag)
{
@ -529,11 +532,18 @@ namespace rsx
{
clear_rw_barrier();
}
if (type != rsx::surface_raster_type::undefined)
{
raster_type = type;
}
}
void on_write_copy(u64 write_tag = 0, bool keep_optimizations = false)
void on_write_copy(u64 write_tag = 0,
bool keep_optimizations = false,
surface_raster_type type = rsx::surface_raster_type::undefined)
{
on_write(write_tag, rsx::surface_state_flags::require_unresolve);
on_write(write_tag, rsx::surface_state_flags::require_unresolve, type);
if (!keep_optimizations && is_depth_surface())
{

View File

@ -318,7 +318,7 @@ namespace rsx
virtual image_view_type create_temporary_subresource_view(commandbuffer_type&, image_storage_type* src, u32 gcm_format, u16 x, u16 y, u16 w, u16 h, const texture_channel_remap_t& remap_vector) = 0;
virtual void release_temporary_subresource(image_view_type rsc) = 0;
virtual section_storage_type* create_new_texture(commandbuffer_type&, const address_range &rsx_range, u16 width, u16 height, u16 depth, u16 mipmaps, u16 pitch, u32 gcm_format,
rsx::texture_upload_context context, rsx::texture_dimension_extended type, texture_create_flags flags) = 0;
rsx::texture_upload_context context, rsx::texture_dimension_extended type, bool swizzled, texture_create_flags flags) = 0;
virtual section_storage_type* upload_image_from_cpu(commandbuffer_type&, const address_range &rsx_range, u16 width, u16 height, u16 depth, u16 mipmaps, u16 pitch, u32 gcm_format, texture_upload_context context,
const std::vector<rsx_subresource_layout>& subresource_layout, rsx::texture_dimension_extended type, bool swizzled) = 0;
virtual section_storage_type* create_nul_section(commandbuffer_type&, const address_range &rsx_range, bool memory_load) = 0;
@ -1597,6 +1597,14 @@ namespace rsx
continue;
}
#endif
if (attr.swizzled != cached_texture->is_swizzled())
{
// We can have the correct data in cached_texture but it needs decoding before it can be sampled.
// Usually a sign of a game bug where the developer forgot to mark the texture correctly the first time we see it.
rsx_log.error("A texture was found in cache for address 0x%x, but swizzle flag does not match", attr.address);
continue;
}
return{ cached_texture->get_view(encoded_remap, remap), cached_texture->get_context(), cached_texture->get_format_type(), scale, cached_texture->get_image_type() };
}
}
@ -1743,9 +1751,9 @@ namespace rsx
attributes.bpp = get_format_block_size_in_bytes(attributes.gcm_format);
attributes.width = tex.width();
attributes.height = tex.height();
attributes.swizzled = !(tex.format() & CELL_GCM_TEXTURE_LN);
const bool is_unnormalized = !!(tex.format() & CELL_GCM_TEXTURE_UN);
const bool is_swizzled = !(tex.format() & CELL_GCM_TEXTURE_LN);
auto extended_dimension = tex.get_extended_texture_dimension();
options.is_compressed_format = helpers::is_compressed_gcm_format(attributes.gcm_format);
@ -1767,8 +1775,8 @@ namespace rsx
}
}
const auto packed_pitch = get_format_packed_pitch(attributes.gcm_format, attributes.width, !tex.border_type(), is_swizzled);
if (!is_swizzled) [[likely]]
const auto packed_pitch = get_format_packed_pitch(attributes.gcm_format, attributes.width, !tex.border_type(), attributes.swizzled);
if (!attributes.swizzled) [[likely]]
{
if (attributes.pitch = tex.pitch(); !attributes.pitch)
{
@ -1883,7 +1891,7 @@ namespace rsx
attr2.height = std::max(attr2.height / 2, 1);
attr2.slice_h = attr2.height;
if (is_swizzled)
if (attributes.swizzled)
{
attr2.pitch = attr2.width * attr2.bpp;
}
@ -1943,7 +1951,7 @@ namespace rsx
// Upload from CPU. Note that sRGB conversion is handled in the FS
auto uploaded = upload_image_from_cpu(cmd, tex_range, attributes.width, attributes.height, attributes.depth, tex.get_exact_mipmap_count(), attributes.pitch, attributes.gcm_format,
texture_upload_context::shader_read, subresources_layout, extended_dimension, is_swizzled);
texture_upload_context::shader_read, subresources_layout, extended_dimension, attributes.swizzled);
return{ uploaded->get_view(tex.remap(), tex.decoded_remap()),
texture_upload_context::shader_read, format_class, scale, extended_dimension };
@ -2672,7 +2680,7 @@ namespace rsx
{
cached_dest = create_new_texture(cmd, rsx_range, dst_dimensions.width, dst_dimensions.height, 1, 1, dst.pitch,
preferred_dst_format, rsx::texture_upload_context::blit_engine_dst, rsx::texture_dimension_extended::texture_dimension_2d,
channel_order);
false, channel_order);
}
else
{
@ -2710,6 +2718,9 @@ namespace rsx
// Invalidate any cached subresources in modified range
notify_surface_changed(dst_range);
// What type of data is being moved?
const auto raster_type = src_is_render_target ? src_subres.surface->raster_type : rsx::surface_raster_type::undefined;
if (cached_dest)
{
// Validate modified range
@ -2721,12 +2732,15 @@ namespace rsx
cached_dest->reprotect(utils::protection::no, { mem_offset, dst_payload_length });
cached_dest->touch(m_cache_update_tag);
update_cache_tag();
// Set swizzle flag
cached_dest->set_swizzled(raster_type == rsx::surface_raster_type::swizzle);
}
else
{
// NOTE: This doesn't work very well in case of Cell access
// Need to lock the affected memory range and actually attach this subres to a locked_region
dst_subres.surface->on_write_copy(rsx::get_shared_tag());
dst_subres.surface->on_write_copy(rsx::get_shared_tag(), false, raster_type);
m_rtts.notify_memory_structure_changed();
// Reset this object's synchronization status if it is locked

View File

@ -56,6 +56,7 @@ namespace rsx
u16 pitch;
u16 slice_h;
u8 bpp;
bool swizzled;
};
struct blit_op_result

View File

@ -1019,6 +1019,7 @@ namespace rsx
u32 gcm_format = 0;
bool pack_unpack_swap_bytes = false;
bool swizzled = false;
u64 sync_timestamp = 0;
bool synchronized = false;
@ -1584,6 +1585,11 @@ namespace rsx
gcm_format = format;
}
void set_swizzled(bool is_swizzled)
{
swizzled = is_swizzled;
}
void set_memory_read_flags(memory_read_flags flags, bool notify_texture_cache = true)
{
const bool changed = (flags != readback_behaviour);
@ -1651,6 +1657,11 @@ namespace rsx
return gcm_format;
}
bool is_swizzled() const
{
return swizzled;
}
memory_read_flags get_memory_read_flags() const
{
return readback_behaviour;
@ -1681,12 +1692,12 @@ namespace rsx
/**
* Comparison
*/
inline bool matches(const address_range &memory_range)
inline bool matches(const address_range &memory_range) const
{
return valid_range() && rsx::buffered_section::matches(memory_range);
}
bool matches(u32 format, u32 width, u32 height, u32 depth, u32 mipmaps)
bool matches(u32 format, u32 width, u32 height, u32 depth, u32 mipmaps) const
{
if (!valid_range())
return false;
@ -1712,7 +1723,7 @@ namespace rsx
return true;
}
bool matches(u32 rsx_address, u32 format, u32 width, u32 height, u32 depth, u32 mipmaps)
bool matches(u32 rsx_address, u32 format, u32 width, u32 height, u32 depth, u32 mipmaps) const
{
if (!valid_range())
return false;
@ -1723,7 +1734,7 @@ namespace rsx
return matches(format, width, height, depth, mipmaps);
}
bool matches(const address_range& memory_range, u32 format, u32 width, u32 height, u32 depth, u32 mipmaps)
bool matches(const address_range& memory_range, u32 format, u32 width, u32 height, u32 depth, u32 mipmaps) const
{
if (!valid_range())
return false;

View File

@ -163,7 +163,7 @@ void GLGSRender::init_buffers(rsx::framebuffer_creation_context context, bool sk
m_rtts.prepare_render_target(cmd,
m_framebuffer_layout.color_format, m_framebuffer_layout.depth_format,
m_framebuffer_layout.width, m_framebuffer_layout.height,
m_framebuffer_layout.target, m_framebuffer_layout.aa_mode,
m_framebuffer_layout.target, m_framebuffer_layout.aa_mode, m_framebuffer_layout.raster_type,
m_framebuffer_layout.color_addresses, m_framebuffer_layout.zeta_address,
m_framebuffer_layout.actual_color_pitch, m_framebuffer_layout.actual_zeta_pitch);

View File

@ -240,6 +240,7 @@ struct gl_render_target_traits
sink->set_rsx_pitch(ref->get_rsx_pitch());
sink->set_old_contents_region(prev, false);
sink->last_use_tag = ref->last_use_tag;
sink->raster_type = ref->raster_type; // Can't actually cut up swizzled data
}
static
@ -275,6 +276,7 @@ struct gl_render_target_traits
surface->last_use_tag = 0;
surface->stencil_init_flags = 0;
surface->memory_usage_flags = rsx::surface_usage_flags::unknown;
surface->raster_type = rsx::surface_raster_type::linear;
}
static

View File

@ -818,7 +818,7 @@ namespace gl
}
cached_texture_section* create_new_texture(gl::command_context&, const utils::address_range &rsx_range, u16 width, u16 height, u16 depth, u16 mipmaps, u16 pitch,
u32 gcm_format, rsx::texture_upload_context context, rsx::texture_dimension_extended type, rsx::texture_create_flags flags) override
u32 gcm_format, rsx::texture_upload_context context, rsx::texture_dimension_extended type, bool swizzled, rsx::texture_create_flags flags) override
{
auto image = gl::create_texture(gcm_format, width, height, depth, mipmaps, type);
@ -834,6 +834,7 @@ namespace gl
cached.set_context(context);
cached.set_image_type(type);
cached.set_gcm_format(gcm_format);
cached.set_swizzled(swizzled);
cached.create(width, height, depth, mipmaps, image, pitch, true);
cached.set_dirty(false);
@ -901,7 +902,7 @@ namespace gl
cached_texture_section* upload_image_from_cpu(gl::command_context &cmd, const utils::address_range& rsx_range, u16 width, u16 height, u16 depth, u16 mipmaps, u16 pitch, u32 gcm_format,
rsx::texture_upload_context context, const std::vector<rsx_subresource_layout>& subresource_layout, rsx::texture_dimension_extended type, bool input_swizzled) override
{
auto section = create_new_texture(cmd, rsx_range, width, height, depth, mipmaps, pitch, gcm_format, context, type,
auto section = create_new_texture(cmd, rsx_range, width, height, depth, mipmaps, pitch, gcm_format, context, type, input_swizzled,
rsx::texture_create_flags::default_component_order);
gl::upload_texture(section->get_raw_texture()->id(), gcm_format, width, height, depth, mipmaps,

View File

@ -1119,10 +1119,10 @@ namespace rsx
u32 minimum_color_pitch = 64u;
u32 minimum_zeta_pitch = 64u;
switch (const auto mode = rsx::method_registers.surface_type())
switch (layout.raster_type = rsx::method_registers.surface_type())
{
default:
rsx_log.error("Unknown raster mode 0x%x", static_cast<u32>(mode));
rsx_log.error("Unknown raster mode 0x%x", static_cast<u32>(layout.raster_type));
[[fallthrough]];
case rsx::surface_raster_type::linear:
break;

View File

@ -342,6 +342,7 @@ namespace rsx
rsx::surface_color_format color_format;
rsx::surface_depth_format depth_format;
rsx::surface_antialiasing aa_mode;
rsx::surface_raster_type raster_type;
u32 aa_factors[2];
bool depth_float;
bool ignore_change;

View File

@ -2030,7 +2030,7 @@ void VKGSRender::prepare_rtts(rsx::framebuffer_creation_context context)
m_rtts.prepare_render_target(*m_current_command_buffer,
m_framebuffer_layout.color_format, m_framebuffer_layout.depth_format,
m_framebuffer_layout.width, m_framebuffer_layout.height,
m_framebuffer_layout.target, m_framebuffer_layout.aa_mode,
m_framebuffer_layout.target, m_framebuffer_layout.aa_mode, m_framebuffer_layout.raster_type,
m_framebuffer_layout.color_addresses, m_framebuffer_layout.zeta_address,
m_framebuffer_layout.actual_color_pitch, m_framebuffer_layout.actual_zeta_pitch,
(*m_device), *m_current_command_buffer);

View File

@ -813,6 +813,7 @@ namespace rsx
sink->rsx_pitch = ref->get_rsx_pitch();
sink->set_old_contents_region(prev, false);
sink->last_use_tag = ref->last_use_tag;
sink->raster_type = ref->raster_type; // Can't actually cut up swizzled data
}
static bool is_compatible_surface(const vk::render_target* surface, const vk::render_target* ref, u16 width, u16 height, u8 sample_count)
@ -853,6 +854,7 @@ namespace rsx
surface->last_use_tag = 0;
surface->stencil_init_flags = 0;
surface->memory_usage_flags = rsx::surface_usage_flags::unknown;
surface->raster_type = rsx::surface_raster_type::linear;
}
static void notify_surface_invalidated(const std::unique_ptr<vk::render_target> &surface)

View File

@ -1100,7 +1100,7 @@ namespace vk
}
cached_texture_section* create_new_texture(vk::command_buffer& cmd, const utils::address_range &rsx_range, u16 width, u16 height, u16 depth, u16 mipmaps, u16 pitch,
u32 gcm_format, rsx::texture_upload_context context, rsx::texture_dimension_extended type, rsx::texture_create_flags flags) override
u32 gcm_format, rsx::texture_upload_context context, rsx::texture_dimension_extended type, bool swizzled, rsx::texture_create_flags flags) override
{
const u16 section_depth = depth;
const bool is_cubemap = type == rsx::texture_dimension_extended::texture_dimension_cubemap;
@ -1180,6 +1180,7 @@ namespace vk
region.set_context(context);
region.set_gcm_format(gcm_format);
region.set_image_type(type);
region.set_swizzled(swizzled);
region.create(width, height, section_depth, mipmaps, image, pitch, true, gcm_format);
region.set_dirty(false);
@ -1232,7 +1233,7 @@ namespace vk
cached_texture_section* upload_image_from_cpu(vk::command_buffer& cmd, const utils::address_range& rsx_range, u16 width, u16 height, u16 depth, u16 mipmaps, u16 pitch, u32 gcm_format,
rsx::texture_upload_context context, const std::vector<rsx_subresource_layout>& subresource_layout, rsx::texture_dimension_extended type, bool swizzled) override
{
auto section = create_new_texture(cmd, rsx_range, width, height, depth, mipmaps, pitch, gcm_format, context, type,
auto section = create_new_texture(cmd, rsx_range, width, height, depth, mipmaps, pitch, gcm_format, context, type, swizzled,
rsx::texture_create_flags::default_component_order);
auto image = section->get_raw_texture();

View File

@ -61,6 +61,7 @@ namespace rsx
enum class surface_raster_type : u8
{
undefined = 0,
linear = 1,
swizzle = 2,
};