mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-15 19:28:43 +12:00
rsx: Zcull refactoring and vulkan implementation
This commit is contained in:
parent
c926868758
commit
680ca1d12a
8 changed files with 575 additions and 286 deletions
|
@ -343,6 +343,9 @@ namespace rsx
|
|||
|
||||
element_push_buffer.resize(0);
|
||||
|
||||
if (zcull_task_queue.active_query && zcull_task_queue.active_query->active)
|
||||
zcull_task_queue.active_query->num_draws++;
|
||||
|
||||
if (capture_current_frame)
|
||||
{
|
||||
u32 element_count = rsx::method_registers.current_draw_clause.get_elements_count();
|
||||
|
@ -1925,4 +1928,179 @@ namespace rsx
|
|||
skip_frame = (m_skip_frame_ctr < 0);
|
||||
}
|
||||
}
|
||||
|
||||
void thread::check_zcull_status(bool framebuffer_swap, bool force_read)
|
||||
{
|
||||
if (g_cfg.video.disable_zcull_queries)
|
||||
return;
|
||||
|
||||
bool testing_enabled = zcull_pixel_cnt_enabled || zcull_stats_enabled;
|
||||
|
||||
if (framebuffer_swap)
|
||||
{
|
||||
zcull_surface_active = false;
|
||||
const u32 zeta_address = m_depth_surface_info.address;
|
||||
|
||||
if (zeta_address)
|
||||
{
|
||||
//Find zeta address in bound zculls
|
||||
for (int i = 0; i < rsx::limits::zculls_count; i++)
|
||||
{
|
||||
if (zculls[i].binded)
|
||||
{
|
||||
const u32 rsx_address = rsx::get_address(zculls[i].offset, CELL_GCM_LOCATION_LOCAL);
|
||||
if (rsx_address == zeta_address)
|
||||
{
|
||||
zcull_surface_active = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
occlusion_query_info* query = nullptr;
|
||||
|
||||
if (zcull_task_queue.task_stack.size() > 0)
|
||||
query = zcull_task_queue.active_query;
|
||||
|
||||
if (query && query->active)
|
||||
{
|
||||
if (force_read || (!zcull_rendering_enabled || !testing_enabled || !zcull_surface_active))
|
||||
{
|
||||
end_occlusion_query(query);
|
||||
query->active = false;
|
||||
query->pending = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (zcull_rendering_enabled && testing_enabled && zcull_surface_active)
|
||||
{
|
||||
//Find query
|
||||
u32 free_index = synchronize_zcull_stats();
|
||||
query = &occlusion_query_data[free_index];
|
||||
zcull_task_queue.add(query);
|
||||
|
||||
begin_occlusion_query(query);
|
||||
query->active = true;
|
||||
query->result = 0;
|
||||
query->num_draws = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void thread::clear_zcull_stats(u32 type)
|
||||
{
|
||||
if (g_cfg.video.disable_zcull_queries)
|
||||
return;
|
||||
|
||||
if (type == CELL_GCM_ZPASS_PIXEL_CNT)
|
||||
{
|
||||
if (zcull_task_queue.active_query &&
|
||||
zcull_task_queue.active_query->active &&
|
||||
zcull_task_queue.active_query->num_draws > 0)
|
||||
{
|
||||
//discard active query results
|
||||
check_zcull_status(false, true);
|
||||
zcull_task_queue.active_query->pending = false;
|
||||
|
||||
//re-enable cull stats if stats are enabled
|
||||
check_zcull_status(false, false);
|
||||
zcull_task_queue.active_query->num_draws = 0;
|
||||
}
|
||||
|
||||
current_zcull_stats.clear();
|
||||
}
|
||||
}
|
||||
|
||||
u32 thread::get_zcull_stats(u32 type)
|
||||
{
|
||||
if (g_cfg.video.disable_zcull_queries)
|
||||
return 0u;
|
||||
|
||||
if (zcull_task_queue.active_query &&
|
||||
zcull_task_queue.active_query->active &&
|
||||
current_zcull_stats.zpass_pixel_cnt == 0 &&
|
||||
type == CELL_GCM_ZPASS_PIXEL_CNT)
|
||||
{
|
||||
//The zcull unit is still bound as the read is happening and there are no results ready
|
||||
check_zcull_status(false, true); //close current query
|
||||
check_zcull_status(false, false); //start new query since stat counting is still active
|
||||
}
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case CELL_GCM_ZPASS_PIXEL_CNT:
|
||||
{
|
||||
if (current_zcull_stats.zpass_pixel_cnt > 0)
|
||||
return UINT16_MAX;
|
||||
|
||||
synchronize_zcull_stats(true);
|
||||
return (current_zcull_stats.zpass_pixel_cnt > 0) ? UINT16_MAX : 0;
|
||||
}
|
||||
case CELL_GCM_ZCULL_STATS:
|
||||
case CELL_GCM_ZCULL_STATS1:
|
||||
case CELL_GCM_ZCULL_STATS2:
|
||||
//TODO
|
||||
return UINT16_MAX;
|
||||
case CELL_GCM_ZCULL_STATS3:
|
||||
{
|
||||
//Some kind of inverse value
|
||||
if (current_zcull_stats.zpass_pixel_cnt > 0)
|
||||
return 0;
|
||||
|
||||
synchronize_zcull_stats(true);
|
||||
return (current_zcull_stats.zpass_pixel_cnt > 0) ? 0 : UINT16_MAX;
|
||||
}
|
||||
default:
|
||||
LOG_ERROR(RSX, "Unknown zcull stat type %d", type);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
u32 thread::synchronize_zcull_stats(bool hard_sync)
|
||||
{
|
||||
if (!zcull_rendering_enabled || zcull_task_queue.pending == 0)
|
||||
return 0;
|
||||
|
||||
u32 result = UINT16_MAX;
|
||||
|
||||
for (auto &query : zcull_task_queue.task_stack)
|
||||
{
|
||||
if (query == nullptr || query->active)
|
||||
continue;
|
||||
|
||||
bool status = check_occlusion_query_status(query);
|
||||
if (status == false && !hard_sync)
|
||||
continue;
|
||||
|
||||
get_occlusion_query_result(query);
|
||||
current_zcull_stats.zpass_pixel_cnt += query->result;
|
||||
|
||||
query->pending = false;
|
||||
query = nullptr;
|
||||
zcull_task_queue.pending--;
|
||||
}
|
||||
|
||||
for (u32 i = 0; i < occlusion_query_count; ++i)
|
||||
{
|
||||
auto &query = occlusion_query_data[i];
|
||||
if (!query.pending && !query.active)
|
||||
{
|
||||
result = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (result == UINT16_MAX && !hard_sync)
|
||||
return synchronize_zcull_stats(true);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void thread::notify_zcull_info_changed()
|
||||
{
|
||||
check_zcull_status(false, false);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue