mirror of https://github.com/RPCS3/rpcs3.git
rsx: Critical pipeline fixes
- Fix scissor and viewport binding behavior - Fixes recovery if empty scissor is specified and then 'fixed' later - Optimizes state binding a bit
This commit is contained in:
parent
1ad76ad331
commit
54ec363e88
|
@ -644,6 +644,25 @@ void GLGSRender::set_viewport()
|
||||||
const auto clip_width = rsx::apply_resolution_scale(rsx::method_registers.surface_clip_width(), true);
|
const auto clip_width = rsx::apply_resolution_scale(rsx::method_registers.surface_clip_width(), true);
|
||||||
const auto clip_height = rsx::apply_resolution_scale(rsx::method_registers.surface_clip_height(), true);
|
const auto clip_height = rsx::apply_resolution_scale(rsx::method_registers.surface_clip_height(), true);
|
||||||
glViewport(0, 0, clip_width, clip_height);
|
glViewport(0, 0, clip_width, clip_height);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GLGSRender::set_scissor()
|
||||||
|
{
|
||||||
|
if (m_graphics_state & rsx::pipeline_state::scissor_config_state_dirty)
|
||||||
|
{
|
||||||
|
// Optimistic that the new config will allow us to render
|
||||||
|
framebuffer_status_valid = true;
|
||||||
|
}
|
||||||
|
else if (!(m_graphics_state & rsx::pipeline_state::scissor_config_state_dirty))
|
||||||
|
{
|
||||||
|
// Nothing to do
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_graphics_state &= ~(rsx::pipeline_state::scissor_config_state_dirty | rsx::pipeline_state::scissor_config_state_dirty);
|
||||||
|
|
||||||
|
const auto clip_width = rsx::apply_resolution_scale(rsx::method_registers.surface_clip_width(), true);
|
||||||
|
const auto clip_height = rsx::apply_resolution_scale(rsx::method_registers.surface_clip_height(), true);
|
||||||
|
|
||||||
u16 scissor_x = rsx::apply_resolution_scale(rsx::method_registers.scissor_origin_x(), false);
|
u16 scissor_x = rsx::apply_resolution_scale(rsx::method_registers.scissor_origin_x(), false);
|
||||||
u16 scissor_w = rsx::apply_resolution_scale(rsx::method_registers.scissor_width(), true);
|
u16 scissor_w = rsx::apply_resolution_scale(rsx::method_registers.scissor_width(), true);
|
||||||
|
@ -656,6 +675,7 @@ void GLGSRender::set_viewport()
|
||||||
{
|
{
|
||||||
if (!g_cfg.video.strict_rendering_mode)
|
if (!g_cfg.video.strict_rendering_mode)
|
||||||
{
|
{
|
||||||
|
m_graphics_state |= rsx::pipeline_state::scissor_setup_invalid;
|
||||||
framebuffer_status_valid = false;
|
framebuffer_status_valid = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -371,6 +371,7 @@ private:
|
||||||
public:
|
public:
|
||||||
void read_buffers();
|
void read_buffers();
|
||||||
void set_viewport();
|
void set_viewport();
|
||||||
|
void set_scissor();
|
||||||
|
|
||||||
work_item& post_flush_request(u32 address, gl::texture_cache::thrashed_set& flush_data);
|
work_item& post_flush_request(u32 address, gl::texture_cache::thrashed_set& flush_data);
|
||||||
|
|
||||||
|
|
|
@ -181,7 +181,7 @@ void GLGSRender::init_buffers(rsx::framebuffer_creation_context context, bool sk
|
||||||
|
|
||||||
if (m_draw_fbo && !m_rtts_dirty)
|
if (m_draw_fbo && !m_rtts_dirty)
|
||||||
{
|
{
|
||||||
set_viewport();
|
set_scissor();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -371,6 +371,7 @@ void GLGSRender::init_buffers(rsx::framebuffer_creation_context context, bool sk
|
||||||
|
|
||||||
check_zcull_status(true);
|
check_zcull_status(true);
|
||||||
set_viewport();
|
set_viewport();
|
||||||
|
set_scissor();
|
||||||
|
|
||||||
m_gl_texture_cache.clear_ro_tex_invalidate_intr();
|
m_gl_texture_cache.clear_ro_tex_invalidate_intr();
|
||||||
|
|
||||||
|
|
|
@ -98,7 +98,10 @@ namespace rsx
|
||||||
fragment_constants_dirty = 0x20, // Fragment constants changed
|
fragment_constants_dirty = 0x20, // Fragment constants changed
|
||||||
framebuffer_reads_dirty = 0x40, // Framebuffer contents changed
|
framebuffer_reads_dirty = 0x40, // Framebuffer contents changed
|
||||||
fragment_texture_state_dirty = 0x80, // Fragment texture parameters changed
|
fragment_texture_state_dirty = 0x80, // Fragment texture parameters changed
|
||||||
vertex_texture_state_dirty = 0x80, // Fragment texture parameters changed
|
vertex_texture_state_dirty = 0x100, // Fragment texture parameters changed
|
||||||
|
scissor_config_state_dirty = 0x200, // Scissor region changed
|
||||||
|
|
||||||
|
scissor_setup_invalid = 0x400, // Scissor configuration is broken
|
||||||
|
|
||||||
invalidate_pipeline_bits = fragment_program_dirty | vertex_program_dirty,
|
invalidate_pipeline_bits = fragment_program_dirty | vertex_program_dirty,
|
||||||
memory_barrier_bits = framebuffer_reads_dirty,
|
memory_barrier_bits = framebuffer_reads_dirty,
|
||||||
|
|
|
@ -1121,7 +1121,7 @@ void VKGSRender::update_draw_state()
|
||||||
vkCmdSetDepthBounds(*m_current_command_buffer, 0.f, 1.f);
|
vkCmdSetDepthBounds(*m_current_command_buffer, 0.f, 1.f);
|
||||||
}
|
}
|
||||||
|
|
||||||
set_viewport();
|
bind_viewport();
|
||||||
|
|
||||||
//TODO: Set up other render-state parameters into the program pipeline
|
//TODO: Set up other render-state parameters into the program pipeline
|
||||||
|
|
||||||
|
@ -1678,40 +1678,58 @@ void VKGSRender::set_viewport()
|
||||||
{
|
{
|
||||||
const auto clip_width = rsx::apply_resolution_scale(rsx::method_registers.surface_clip_width(), true);
|
const auto clip_width = rsx::apply_resolution_scale(rsx::method_registers.surface_clip_width(), true);
|
||||||
const auto clip_height = rsx::apply_resolution_scale(rsx::method_registers.surface_clip_height(), true);
|
const auto clip_height = rsx::apply_resolution_scale(rsx::method_registers.surface_clip_height(), true);
|
||||||
|
|
||||||
|
//NOTE: The scale_offset matrix already has viewport matrix factored in
|
||||||
|
m_viewport.x = 0;
|
||||||
|
m_viewport.y = 0;
|
||||||
|
m_viewport.width = clip_width;
|
||||||
|
m_viewport.height = clip_height;
|
||||||
|
m_viewport.minDepth = 0.f;
|
||||||
|
m_viewport.maxDepth = 1.f;
|
||||||
|
}
|
||||||
|
|
||||||
|
void VKGSRender::set_scissor()
|
||||||
|
{
|
||||||
|
if (m_graphics_state & rsx::pipeline_state::scissor_config_state_dirty)
|
||||||
|
{
|
||||||
|
// Optimistic that the new config will allow us to render
|
||||||
|
framebuffer_status_valid = true;
|
||||||
|
}
|
||||||
|
else if (!(m_graphics_state & rsx::pipeline_state::scissor_config_state_dirty))
|
||||||
|
{
|
||||||
|
// Nothing to do
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_graphics_state &= ~(rsx::pipeline_state::scissor_config_state_dirty | rsx::pipeline_state::scissor_config_state_dirty);
|
||||||
|
|
||||||
u16 scissor_x = rsx::apply_resolution_scale(rsx::method_registers.scissor_origin_x(), false);
|
u16 scissor_x = rsx::apply_resolution_scale(rsx::method_registers.scissor_origin_x(), false);
|
||||||
u16 scissor_w = rsx::apply_resolution_scale(rsx::method_registers.scissor_width(), true);
|
u16 scissor_w = rsx::apply_resolution_scale(rsx::method_registers.scissor_width(), true);
|
||||||
u16 scissor_y = rsx::apply_resolution_scale(rsx::method_registers.scissor_origin_y(), false);
|
u16 scissor_y = rsx::apply_resolution_scale(rsx::method_registers.scissor_origin_y(), false);
|
||||||
u16 scissor_h = rsx::apply_resolution_scale(rsx::method_registers.scissor_height(), true);
|
u16 scissor_h = rsx::apply_resolution_scale(rsx::method_registers.scissor_height(), true);
|
||||||
|
|
||||||
//NOTE: The scale_offset matrix already has viewport matrix factored in
|
m_scissor.extent.height = scissor_h;
|
||||||
VkViewport viewport = {};
|
m_scissor.extent.width = scissor_w;
|
||||||
viewport.x = 0;
|
m_scissor.offset.x = scissor_x;
|
||||||
viewport.y = 0;
|
m_scissor.offset.y = scissor_y;
|
||||||
viewport.width = clip_width;
|
|
||||||
viewport.height = clip_height;
|
|
||||||
viewport.minDepth = 0.f;
|
|
||||||
viewport.maxDepth = 1.f;
|
|
||||||
|
|
||||||
vkCmdSetViewport(*m_current_command_buffer, 0, 1, &viewport);
|
if (scissor_x >= m_viewport.width || scissor_y >= m_viewport.height || scissor_w == 0 || scissor_h == 0)
|
||||||
|
|
||||||
VkRect2D scissor = {};
|
|
||||||
scissor.extent.height = scissor_h;
|
|
||||||
scissor.extent.width = scissor_w;
|
|
||||||
scissor.offset.x = scissor_x;
|
|
||||||
scissor.offset.y = scissor_y;
|
|
||||||
|
|
||||||
vkCmdSetScissor(*m_current_command_buffer, 0, 1, &scissor);
|
|
||||||
|
|
||||||
if (scissor_x >= viewport.width || scissor_y >= viewport.height || scissor_w == 0 || scissor_h == 0)
|
|
||||||
{
|
{
|
||||||
if (!g_cfg.video.strict_rendering_mode)
|
if (!g_cfg.video.strict_rendering_mode)
|
||||||
{
|
{
|
||||||
|
m_graphics_state |= rsx::pipeline_state::scissor_setup_invalid;
|
||||||
framebuffer_status_valid = false;
|
framebuffer_status_valid = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VKGSRender::bind_viewport()
|
||||||
|
{
|
||||||
|
vkCmdSetViewport(*m_current_command_buffer, 0, 1, &m_viewport);
|
||||||
|
vkCmdSetScissor(*m_current_command_buffer, 0, 1, &m_scissor);
|
||||||
|
}
|
||||||
|
|
||||||
void VKGSRender::on_init_thread()
|
void VKGSRender::on_init_thread()
|
||||||
{
|
{
|
||||||
if (m_device == VK_NULL_HANDLE)
|
if (m_device == VK_NULL_HANDLE)
|
||||||
|
@ -2743,7 +2761,10 @@ void VKGSRender::prepare_rtts(rsx::framebuffer_creation_context context)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_draw_fbo && !m_rtts_dirty)
|
if (m_draw_fbo && !m_rtts_dirty)
|
||||||
|
{
|
||||||
|
set_scissor();
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
m_rtts_dirty = false;
|
m_rtts_dirty = false;
|
||||||
framebuffer_status_valid = false;
|
framebuffer_status_valid = false;
|
||||||
|
@ -2946,6 +2967,9 @@ void VKGSRender::prepare_rtts(rsx::framebuffer_creation_context context)
|
||||||
m_draw_fbo.reset(new vk::framebuffer_holder(*m_device, current_render_pass, fbo_width, fbo_height, std::move(fbo_images)));
|
m_draw_fbo.reset(new vk::framebuffer_holder(*m_device, current_render_pass, fbo_width, fbo_height, std::move(fbo_images)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
set_viewport();
|
||||||
|
set_scissor();
|
||||||
|
|
||||||
check_zcull_status(true);
|
check_zcull_status(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -369,6 +369,9 @@ private:
|
||||||
u32 m_client_width = 0;
|
u32 m_client_width = 0;
|
||||||
u32 m_client_height = 0;
|
u32 m_client_height = 0;
|
||||||
|
|
||||||
|
VkViewport m_viewport{};
|
||||||
|
VkRect2D m_scissor{};
|
||||||
|
|
||||||
// Draw call stats
|
// Draw call stats
|
||||||
u32 m_draw_calls = 0;
|
u32 m_draw_calls = 0;
|
||||||
|
|
||||||
|
@ -432,6 +435,8 @@ public:
|
||||||
void read_buffers();
|
void read_buffers();
|
||||||
void write_buffers();
|
void write_buffers();
|
||||||
void set_viewport();
|
void set_viewport();
|
||||||
|
void set_scissor();
|
||||||
|
void bind_viewport();
|
||||||
|
|
||||||
void sync_hint(rsx::FIFO_hint hint) override;
|
void sync_hint(rsx::FIFO_hint hint) override;
|
||||||
|
|
||||||
|
|
|
@ -650,7 +650,7 @@ namespace rsx
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_vertex_env_dirty_bit(thread* rsx, u32 reg, u32 arg)
|
void set_vertex_env_dirty_bit(thread* rsx, u32, u32 arg)
|
||||||
{
|
{
|
||||||
if (arg != method_registers.register_previous_value)
|
if (arg != method_registers.register_previous_value)
|
||||||
{
|
{
|
||||||
|
@ -658,7 +658,7 @@ namespace rsx
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_fragment_env_dirty_bit(thread* rsx, u32 reg, u32 arg)
|
void set_fragment_env_dirty_bit(thread* rsx, u32, u32 arg)
|
||||||
{
|
{
|
||||||
if (arg != method_registers.register_previous_value)
|
if (arg != method_registers.register_previous_value)
|
||||||
{
|
{
|
||||||
|
@ -666,6 +666,14 @@ namespace rsx
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void set_scissor_dirty_bit(thread* rsx, u32 reg, u32 arg)
|
||||||
|
{
|
||||||
|
if (arg != method_registers.register_previous_value)
|
||||||
|
{
|
||||||
|
rsx->m_graphics_state |= rsx::pipeline_state::scissor_config_state_dirty;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
template<u32 index>
|
template<u32 index>
|
||||||
struct set_texture_dirty_bit
|
struct set_texture_dirty_bit
|
||||||
{
|
{
|
||||||
|
@ -2729,6 +2737,8 @@ namespace rsx
|
||||||
bind<NV4097_SET_SHADER_PACKER, nv4097::set_ROP_state_dirty_bit>();
|
bind<NV4097_SET_SHADER_PACKER, nv4097::set_ROP_state_dirty_bit>();
|
||||||
bind<NV4097_SET_SHADER_WINDOW, nv4097::set_ROP_state_dirty_bit>();
|
bind<NV4097_SET_SHADER_WINDOW, nv4097::set_ROP_state_dirty_bit>();
|
||||||
bind<NV4097_SET_FOG_MODE, nv4097::set_ROP_state_dirty_bit>();
|
bind<NV4097_SET_FOG_MODE, nv4097::set_ROP_state_dirty_bit>();
|
||||||
|
bind<NV4097_SET_SCISSOR_HORIZONTAL, nv4097::set_scissor_dirty_bit>();
|
||||||
|
bind<NV4097_SET_SCISSOR_VERTICAL, nv4097::set_scissor_dirty_bit>();
|
||||||
bind_array<NV4097_SET_FOG_PARAMS, 1, 2, nv4097::set_ROP_state_dirty_bit>();
|
bind_array<NV4097_SET_FOG_PARAMS, 1, 2, nv4097::set_ROP_state_dirty_bit>();
|
||||||
bind_range<NV4097_SET_VIEWPORT_SCALE, 1, 3, nv4097::set_viewport_dirty_bit>();
|
bind_range<NV4097_SET_VIEWPORT_SCALE, 1, 3, nv4097::set_viewport_dirty_bit>();
|
||||||
bind_range<NV4097_SET_VIEWPORT_OFFSET, 1, 3, nv4097::set_viewport_dirty_bit>();
|
bind_range<NV4097_SET_VIEWPORT_OFFSET, 1, 3, nv4097::set_viewport_dirty_bit>();
|
||||||
|
|
Loading…
Reference in New Issue