rsx: Zcull refactoring and vulkan implementation

This commit is contained in:
kd-11 2017-11-17 00:52:21 +03:00
parent c926868758
commit 680ca1d12a
8 changed files with 575 additions and 286 deletions

View file

@ -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);
}
}