mirror of
https://github.com/RPCS3/rpcs3.git
synced 2026-10-11 22:49:55 +00:00
rsx/vk: Implement rendering using no attachments
This commit is contained in:
@@ -1477,7 +1477,8 @@ namespace rsx
|
||||
layout.width = rsx::method_registers.surface_clip_width();
|
||||
layout.height = rsx::method_registers.surface_clip_height();
|
||||
|
||||
m_graphics_state.clear(rsx::rtt_config_contested | rsx::rtt_config_valid | rsx::rtt_config_no_attachments);
|
||||
// NOTE: rtt_config_no_attachments is intentionally not reset.
|
||||
m_graphics_state.clear(rsx::rtt_config_contested | rsx::rtt_config_valid);
|
||||
m_current_framebuffer_context = context;
|
||||
|
||||
if (layout.width == 0 || layout.height == 0)
|
||||
@@ -1801,7 +1802,22 @@ namespace rsx
|
||||
}
|
||||
|
||||
// Context must be draw now...
|
||||
m_graphics_state.set(rsx::rtt_config_no_attachments);
|
||||
}
|
||||
|
||||
if (framebufferless != m_graphics_state.test(rsx::rtt_config_no_attachments))
|
||||
{
|
||||
// Programmable blending reads back from the color attachments and is disabled when there are none.
|
||||
// Force the blend configuration to be re-evaluated when moving in or out of this state.
|
||||
if (framebufferless)
|
||||
{
|
||||
m_graphics_state.set(rsx::rtt_config_no_attachments);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_graphics_state.clear(rsx::rtt_config_no_attachments);
|
||||
}
|
||||
|
||||
m_graphics_state.set(rsx::pipeline_config_dirty);
|
||||
}
|
||||
|
||||
// At least one attachment exists
|
||||
@@ -2145,8 +2161,9 @@ namespace rsx
|
||||
{
|
||||
u32 expected_ctrl = 0;
|
||||
|
||||
// Programmable blending
|
||||
if (backend_config.supports_programmable_blending)
|
||||
// Programmable blending. Requires color attachments to read from.
|
||||
if (backend_config.supports_programmable_blending &&
|
||||
!m_graphics_state.test(rsx::rtt_config_no_attachments))
|
||||
{
|
||||
expected_ctrl = current_fragment_program.ctrl & RSX_SHADER_CONTROL_PROGRAMMABLE_BLENDING;
|
||||
|
||||
|
||||
@@ -219,7 +219,9 @@ void VKGSRender::update_draw_state()
|
||||
const auto polygon_offset_scale = rsx::method_registers.poly_offset_scale();
|
||||
auto polygon_offset_bias = rsx::method_registers.poly_offset_bias();
|
||||
|
||||
if (m_draw_fbo->depth_format() == VK_FORMAT_D24_UNORM_S8_UINT && is_NVIDIA(vk::get_chip_family()))
|
||||
if (!m_draw_fbo->attachments.empty() &&
|
||||
m_draw_fbo->depth_format() == VK_FORMAT_D24_UNORM_S8_UINT &&
|
||||
is_NVIDIA(vk::get_chip_family()))
|
||||
{
|
||||
// Empirically derived to be 0.5 * (2^24 - 1) for fixed type on Pascal. The same seems to apply for other NVIDIA GPUs.
|
||||
// RSX seems to be using 2^24 - 1 instead making the biases twice as large when using fixed type Z-buffer on NVIDIA.
|
||||
@@ -1261,7 +1263,6 @@ void VKGSRender::begin()
|
||||
rsx::thread::begin();
|
||||
|
||||
if (skip_current_frame ||
|
||||
swapchain_unavailable ||
|
||||
cond_render_ctrl.disable_rendering())
|
||||
{
|
||||
return;
|
||||
@@ -1279,7 +1280,7 @@ void VKGSRender::begin()
|
||||
|
||||
void VKGSRender::end()
|
||||
{
|
||||
if (skip_current_frame || !m_graphics_state.test(rsx::rtt_config_valid) || swapchain_unavailable || cond_render_ctrl.disable_rendering())
|
||||
if (should_skip_draw())
|
||||
{
|
||||
execute_nop_draw();
|
||||
rsx::thread::end();
|
||||
|
||||
@@ -677,6 +677,21 @@ VKGSRender::VKGSRender(utils::serial* ar) noexcept : GSRender(ar)
|
||||
backend_config.supports_hw_a2one = m_device->get_alpha_to_one_support();
|
||||
}
|
||||
|
||||
// Framebufferless rendering. Zero-attachment subpasses can only rasterize at the sample counts reported for them.
|
||||
const VkSampleCountFlags required_sample_counts = (g_cfg.video.antialiasing_level == msaa_level::_auto)
|
||||
? VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_2_BIT | VK_SAMPLE_COUNT_4_BIT
|
||||
: VK_SAMPLE_COUNT_1_BIT;
|
||||
|
||||
if (const auto supported_sample_counts = m_device->gpu().get_limits().framebufferNoAttachmentsSampleCounts & required_sample_counts;
|
||||
supported_sample_counts == required_sample_counts)
|
||||
{
|
||||
backend_config.supports_framebufferless_rendering = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
rsx_log.warning("Framebufferless rendering is not supported with the current MSAA configuration. Some occlusion queries may return incorrect results.");
|
||||
}
|
||||
|
||||
// NOTE: On NVIDIA cards going back decades (including the PS3) there is a slight normalization inaccuracy in compressed formats.
|
||||
// Confirmed in BLES01916 (The Evil Within) which uses RGB565 for some virtual texturing data.
|
||||
backend_config.supports_hw_renormalization = vk::is_NVIDIA(vk::get_driver_vendor());
|
||||
@@ -1299,7 +1314,7 @@ void VKGSRender::on_exit()
|
||||
|
||||
void VKGSRender::clear_surface(u32 mask)
|
||||
{
|
||||
if (skip_current_frame || swapchain_unavailable) return;
|
||||
if (skip_current_frame) return;
|
||||
|
||||
// If stencil write mask is disabled, remove clear_stencil bit
|
||||
if (!rsx::method_registers.stencil_mask()) mask &= ~RSX_GCM_CLEAR_STENCIL_BIT;
|
||||
@@ -2709,7 +2724,19 @@ void VKGSRender::prepare_rtts(rsx::framebuffer_creation_context context)
|
||||
std::iota(input_attachments.begin(), input_attachments.end(), 0);
|
||||
}
|
||||
|
||||
m_current_renderpass_key = vk::get_renderpass_key(m_fbo_images, input_attachments);
|
||||
if (m_graphics_state.test(rsx::rtt_config_no_attachments))
|
||||
{
|
||||
// Framebufferless rendering. The raster sample count must match what real surfaces would have used.
|
||||
ensure(m_fbo_images.empty() && input_attachments.empty());
|
||||
|
||||
const u8 raster_samples = (g_cfg.video.antialiasing_level == msaa_level::_auto) ? samples : 1;
|
||||
m_current_renderpass_key = vk::get_renderpass_key_no_attachments(raster_samples);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_current_renderpass_key = vk::get_renderpass_key(m_fbo_images, input_attachments);
|
||||
}
|
||||
|
||||
m_cached_renderpass = vk::get_renderpass(*m_device, m_current_renderpass_key);
|
||||
|
||||
// Search old framebuffers for this same configuration
|
||||
@@ -2749,9 +2776,6 @@ void VKGSRender::renderctl(u32 request_code, void* args)
|
||||
|
||||
bool VKGSRender::scaled_image_from_memory(const rsx::blit_src_info& src, const rsx::blit_dst_info& dst, bool interpolate)
|
||||
{
|
||||
if (swapchain_unavailable)
|
||||
return false;
|
||||
|
||||
if (m_texture_cache.blit(src, dst, interpolate, m_rtts, *m_current_command_buffer))
|
||||
{
|
||||
m_samplers_dirty.store(true);
|
||||
|
||||
Reference in New Issue
Block a user