mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-07 07:21:25 +12:00
rsx: Implement separate viewport raster clipping
- Merge viewport raster window and scissor into one clipping region - Viewport raster clip is different from viewport geometry clipping in hardware as the latter is configurable separately
This commit is contained in:
parent
1b140c8e97
commit
b5a2f0df68
7 changed files with 69 additions and 69 deletions
|
@ -476,7 +476,7 @@ void D3D12GSRender::end()
|
||||||
};
|
};
|
||||||
get_current_resource_storage().command_list->RSSetViewports(1, &viewport);
|
get_current_resource_storage().command_list->RSSetViewports(1, &viewport);
|
||||||
|
|
||||||
get_current_resource_storage().command_list->RSSetScissorRects(1, &get_scissor(rsx::method_registers.scissor_origin_x(), rsx::method_registers.scissor_origin_y(),
|
get_current_resource_storage().command_list->RSSetScissorRects(1, &::get_scissor(rsx::method_registers.scissor_origin_x(), rsx::method_registers.scissor_origin_y(),
|
||||||
rsx::method_registers.scissor_width(), rsx::method_registers.scissor_height()));
|
rsx::method_registers.scissor_width(), rsx::method_registers.scissor_height()));
|
||||||
|
|
||||||
get_current_resource_storage().command_list->IASetPrimitiveTopology(get_primitive_topology(rsx::method_registers.current_draw_clause.primitive));
|
get_current_resource_storage().command_list->IASetPrimitiveTopology(get_primitive_topology(rsx::method_registers.current_draw_clause.primitive));
|
||||||
|
|
|
@ -125,12 +125,12 @@ void D3D12GSRender::clear_surface(u32 arg)
|
||||||
u32 clear_depth = rsx::method_registers.z_clear_value(depth_format == rsx::surface_depth_format::z24s8);
|
u32 clear_depth = rsx::method_registers.z_clear_value(depth_format == rsx::surface_depth_format::z24s8);
|
||||||
u32 max_depth_value = get_max_depth_value(depth_format);
|
u32 max_depth_value = get_max_depth_value(depth_format);
|
||||||
get_current_resource_storage().command_list->ClearDepthStencilView(m_rtts.current_ds_handle, D3D12_CLEAR_FLAG_DEPTH, clear_depth / (float)max_depth_value, 0,
|
get_current_resource_storage().command_list->ClearDepthStencilView(m_rtts.current_ds_handle, D3D12_CLEAR_FLAG_DEPTH, clear_depth / (float)max_depth_value, 0,
|
||||||
1, &get_scissor(rsx::method_registers.scissor_origin_x(), rsx::method_registers.scissor_origin_y(), rsx::method_registers.scissor_width(), rsx::method_registers.scissor_height()));
|
1, &::get_scissor(rsx::method_registers.scissor_origin_x(), rsx::method_registers.scissor_origin_y(), rsx::method_registers.scissor_width(), rsx::method_registers.scissor_height()));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (arg & 0x2)
|
if (arg & 0x2)
|
||||||
get_current_resource_storage().command_list->ClearDepthStencilView(m_rtts.current_ds_handle, D3D12_CLEAR_FLAG_STENCIL, 0.f, get_clear_stencil(rsx::method_registers.stencil_clear_value()),
|
get_current_resource_storage().command_list->ClearDepthStencilView(m_rtts.current_ds_handle, D3D12_CLEAR_FLAG_STENCIL, 0.f, get_clear_stencil(rsx::method_registers.stencil_clear_value()),
|
||||||
1, &get_scissor(rsx::method_registers.scissor_origin_x(), rsx::method_registers.scissor_origin_y(), rsx::method_registers.scissor_width(), rsx::method_registers.scissor_height()));
|
1, &::get_scissor(rsx::method_registers.scissor_origin_x(), rsx::method_registers.scissor_origin_y(), rsx::method_registers.scissor_width(), rsx::method_registers.scissor_height()));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (arg & 0xF0)
|
if (arg & 0xF0)
|
||||||
|
@ -147,7 +147,7 @@ void D3D12GSRender::clear_surface(u32 arg)
|
||||||
};
|
};
|
||||||
for (unsigned i = 0; i < rtt_index; i++)
|
for (unsigned i = 0; i < rtt_index; i++)
|
||||||
get_current_resource_storage().command_list->ClearRenderTargetView(handle.Offset(i, m_descriptor_stride_rtv), clear_color.data(),
|
get_current_resource_storage().command_list->ClearRenderTargetView(handle.Offset(i, m_descriptor_stride_rtv), clear_color.data(),
|
||||||
1, &get_scissor(rsx::method_registers.scissor_origin_x(), rsx::method_registers.scissor_origin_y(), rsx::method_registers.scissor_width(), rsx::method_registers.scissor_height()));
|
1, &::get_scissor(rsx::method_registers.scissor_origin_x(), rsx::method_registers.scissor_origin_y(), rsx::method_registers.scissor_width(), rsx::method_registers.scissor_height()));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::chrono::time_point<steady_clock> end_duration = steady_clock::now();
|
std::chrono::time_point<steady_clock> end_duration = steady_clock::now();
|
||||||
|
|
|
@ -651,43 +651,14 @@ void GLGSRender::set_viewport()
|
||||||
|
|
||||||
void GLGSRender::set_scissor()
|
void GLGSRender::set_scissor()
|
||||||
{
|
{
|
||||||
if (m_graphics_state & rsx::pipeline_state::scissor_config_state_dirty)
|
areau scissor;
|
||||||
|
if (get_scissor(scissor))
|
||||||
{
|
{
|
||||||
// Optimistic that the new config will allow us to render
|
// NOTE: window origin does not affect scissor region (probably only affects viewport matrix; already applied)
|
||||||
framebuffer_status_valid = true;
|
// See LIMBO [NPUB-30373] which uses shader window origin = top
|
||||||
|
glScissor(scissor.x1, scissor.y1, scissor.width(), scissor.height());
|
||||||
|
gl_state.enable(GL_TRUE, GL_SCISSOR_TEST);
|
||||||
}
|
}
|
||||||
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_setup_invalid);
|
|
||||||
|
|
||||||
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_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_h = rsx::apply_resolution_scale(rsx::method_registers.scissor_height(), true);
|
|
||||||
|
|
||||||
// Do not bother drawing anything if output is zero sized
|
|
||||||
// TODO: Clip scissor region
|
|
||||||
if (scissor_x >= clip_width || scissor_y >= clip_height || scissor_w == 0 || scissor_h == 0)
|
|
||||||
{
|
|
||||||
if (!g_cfg.video.strict_rendering_mode)
|
|
||||||
{
|
|
||||||
m_graphics_state |= rsx::pipeline_state::scissor_setup_invalid;
|
|
||||||
framebuffer_status_valid = false;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// NOTE: window origin does not affect scissor region (probably only affects viewport matrix; already applied)
|
|
||||||
// See LIMBO [NPUB-30373] which uses shader window origin = top
|
|
||||||
glScissor(scissor_x, scissor_y, scissor_w, scissor_h);
|
|
||||||
gl_state.enable(GL_TRUE, GL_SCISSOR_TEST);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLGSRender::on_init_thread()
|
void GLGSRender::on_init_thread()
|
||||||
|
|
|
@ -1293,6 +1293,56 @@ namespace rsx
|
||||||
return layout;
|
return layout;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool thread::get_scissor(areau& region)
|
||||||
|
{
|
||||||
|
if (!(m_graphics_state & rsx::pipeline_state::scissor_config_state_dirty))
|
||||||
|
{
|
||||||
|
// Nothing to do
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_graphics_state &= ~rsx::pipeline_state::scissor_config_state_dirty;
|
||||||
|
|
||||||
|
u16 scissor_x = rsx::method_registers.scissor_origin_x();
|
||||||
|
u16 scissor_w = rsx::method_registers.scissor_width();
|
||||||
|
u16 scissor_y = rsx::method_registers.scissor_origin_y();
|
||||||
|
u16 scissor_h = rsx::method_registers.scissor_height();
|
||||||
|
|
||||||
|
u16 raster_x = rsx::method_registers.viewport_origin_x();
|
||||||
|
u16 raster_w = rsx::method_registers.viewport_width();
|
||||||
|
u16 raster_y = rsx::method_registers.viewport_origin_y();
|
||||||
|
u16 raster_h = rsx::method_registers.viewport_height();
|
||||||
|
|
||||||
|
// Get the minimum area between these two
|
||||||
|
u16 x1 = std::max(scissor_x, raster_x);
|
||||||
|
u16 y1 = std::max(scissor_y, raster_y);
|
||||||
|
u16 x2 = std::min(scissor_x + scissor_w, raster_x + raster_w);
|
||||||
|
u16 y2 = std::min(scissor_y + scissor_h, raster_y + raster_h);
|
||||||
|
|
||||||
|
if (x2 <= x1 ||
|
||||||
|
y2 <= y1 ||
|
||||||
|
x1 >= rsx::method_registers.window_clip_horizontal() ||
|
||||||
|
y1 >= rsx::method_registers.window_clip_vertical())
|
||||||
|
{
|
||||||
|
m_graphics_state |= rsx::pipeline_state::scissor_setup_invalid;
|
||||||
|
framebuffer_status_valid = false;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_graphics_state & rsx::pipeline_state::scissor_setup_invalid)
|
||||||
|
{
|
||||||
|
m_graphics_state &= ~rsx::pipeline_state::scissor_setup_invalid;
|
||||||
|
framebuffer_status_valid = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
region.x1 = rsx::apply_resolution_scale(x1, false);
|
||||||
|
region.x2 = rsx::apply_resolution_scale(x2, true);
|
||||||
|
region.y1 = rsx::apply_resolution_scale(y1, false);
|
||||||
|
region.y2 = rsx::apply_resolution_scale(y2, true);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void thread::get_current_vertex_program(const std::array<std::unique_ptr<rsx::sampled_image_descriptor_base>, rsx::limits::vertex_textures_count>& sampler_descriptors, bool skip_textures, bool skip_vertex_inputs)
|
void thread::get_current_vertex_program(const std::array<std::unique_ptr<rsx::sampled_image_descriptor_base>, rsx::limits::vertex_textures_count>& sampler_descriptors, bool skip_textures, bool skip_vertex_inputs)
|
||||||
{
|
{
|
||||||
if (!(m_graphics_state & rsx::pipeline_state::vertex_program_dirty))
|
if (!(m_graphics_state & rsx::pipeline_state::vertex_program_dirty))
|
||||||
|
|
|
@ -520,6 +520,7 @@ namespace rsx
|
||||||
u32 get_zeta_surface_address() const;
|
u32 get_zeta_surface_address() const;
|
||||||
|
|
||||||
framebuffer_layout get_framebuffer_layout(rsx::framebuffer_creation_context context);
|
framebuffer_layout get_framebuffer_layout(rsx::framebuffer_creation_context context);
|
||||||
|
bool get_scissor(areau& region);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Analyze vertex inputs and group all interleaved blocks
|
* Analyze vertex inputs and group all interleaved blocks
|
||||||
|
|
|
@ -1796,37 +1796,13 @@ void VKGSRender::set_viewport()
|
||||||
|
|
||||||
void VKGSRender::set_scissor()
|
void VKGSRender::set_scissor()
|
||||||
{
|
{
|
||||||
if (m_graphics_state & rsx::pipeline_state::scissor_config_state_dirty)
|
areau scissor;
|
||||||
|
if (get_scissor(scissor))
|
||||||
{
|
{
|
||||||
// Optimistic that the new config will allow us to render
|
m_scissor.extent.height = scissor.height();
|
||||||
framebuffer_status_valid = true;
|
m_scissor.extent.width = scissor.width();
|
||||||
}
|
m_scissor.offset.x = scissor.x1;
|
||||||
else if (!(m_graphics_state & rsx::pipeline_state::scissor_config_state_dirty))
|
m_scissor.offset.y = scissor.y1;
|
||||||
{
|
|
||||||
// Nothing to do
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_graphics_state &= ~(rsx::pipeline_state::scissor_config_state_dirty | rsx::pipeline_state::scissor_setup_invalid);
|
|
||||||
|
|
||||||
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_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);
|
|
||||||
|
|
||||||
m_scissor.extent.height = scissor_h;
|
|
||||||
m_scissor.extent.width = scissor_w;
|
|
||||||
m_scissor.offset.x = scissor_x;
|
|
||||||
m_scissor.offset.y = scissor_y;
|
|
||||||
|
|
||||||
if (scissor_x >= m_viewport.width || scissor_y >= m_viewport.height || scissor_w == 0 || scissor_h == 0)
|
|
||||||
{
|
|
||||||
if (!g_cfg.video.strict_rendering_mode)
|
|
||||||
{
|
|
||||||
m_graphics_state |= rsx::pipeline_state::scissor_setup_invalid;
|
|
||||||
framebuffer_status_valid = false;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2790,6 +2790,8 @@ namespace rsx
|
||||||
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_HORIZONTAL, nv4097::set_scissor_dirty_bit>();
|
||||||
bind<NV4097_SET_SCISSOR_VERTICAL, nv4097::set_scissor_dirty_bit>();
|
bind<NV4097_SET_SCISSOR_VERTICAL, nv4097::set_scissor_dirty_bit>();
|
||||||
|
bind<NV4097_SET_VIEWPORT_HORIZONTAL, nv4097::set_scissor_dirty_bit>();
|
||||||
|
bind<NV4097_SET_VIEWPORT_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…
Add table
Add a link
Reference in a new issue