mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-03-14 01:27:00 +00:00
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:
parent
107129f95a
commit
4df933275b
@ -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)
|
||||
{
|
||||
|
@ -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())
|
||||
{
|
||||
|
@ -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
|
||||
|
@ -56,6 +56,7 @@ namespace rsx
|
||||
u16 pitch;
|
||||
u16 slice_h;
|
||||
u8 bpp;
|
||||
bool swizzled;
|
||||
};
|
||||
|
||||
struct blit_op_result
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
|
@ -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();
|
||||
|
@ -61,6 +61,7 @@ namespace rsx
|
||||
|
||||
enum class surface_raster_type : u8
|
||||
{
|
||||
undefined = 0,
|
||||
linear = 1,
|
||||
swizzle = 2,
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user