rsx: Implement precise ZCULL stats

This commit is contained in:
kd-11 2021-09-04 21:50:53 +03:00 committed by kd-11
parent 0525070898
commit 472efc08eb
7 changed files with 62 additions and 58 deletions

View file

@ -93,6 +93,7 @@ void GLGSRender::on_init_thread()
gl::set_primary_context_thread(); gl::set_primary_context_thread();
zcull_ctrl.reset(static_cast<::rsx::reports::ZCULL_control*>(this)); zcull_ctrl.reset(static_cast<::rsx::reports::ZCULL_control*>(this));
m_occlusion_type = g_cfg.video.precise_zpass_count ? GL_SAMPLES_PASSED : GL_ANY_SAMPLES_PASSED;
gl::init(); gl::init();
@ -1061,13 +1062,13 @@ void GLGSRender::notify_tile_unbound(u32 tile)
void GLGSRender::begin_occlusion_query(rsx::reports::occlusion_query_info* query) void GLGSRender::begin_occlusion_query(rsx::reports::occlusion_query_info* query)
{ {
query->result = 0; query->result = 0;
glBeginQuery(GL_ANY_SAMPLES_PASSED, query->driver_handle); glBeginQuery(m_occlusion_type, query->driver_handle);
} }
void GLGSRender::end_occlusion_query(rsx::reports::occlusion_query_info* query) void GLGSRender::end_occlusion_query(rsx::reports::occlusion_query_info* query)
{ {
ensure(query->active); ensure(query->active);
glEndQuery(GL_ANY_SAMPLES_PASSED); glEndQuery(m_occlusion_type);
} }
bool GLGSRender::check_occlusion_query_status(rsx::reports::occlusion_query_info* query) bool GLGSRender::check_occlusion_query_status(rsx::reports::occlusion_query_info* query)
@ -1097,6 +1098,6 @@ void GLGSRender::discard_occlusion_query(rsx::reports::occlusion_query_info* que
if (query->active) if (query->active)
{ {
//Discard is being called on an active query, close it //Discard is being called on an active query, close it
glEndQuery(GL_ANY_SAMPLES_PASSED); glEndQuery(m_occlusion_type);
} }
} }

View file

@ -139,6 +139,9 @@ private:
std::unordered_map<GLenum, std::unique_ptr<gl::texture>> m_null_textures; std::unordered_map<GLenum, std::unique_ptr<gl::texture>> m_null_textures;
std::vector<u8> m_scratch_buffer; std::vector<u8> m_scratch_buffer;
// Occlusion query type, can be SAMPLES_PASSED or ANY_SAMPLES_PASSED
GLenum m_occlusion_type = GL_ANY_SAMPLES_PASSED;
public: public:
u64 get_cycles() final; u64 get_cycles() final;
GLGSRender(); GLGSRender();

View file

@ -3377,7 +3377,10 @@ namespace rsx
switch (type) switch (type)
{ {
case CELL_GCM_ZPASS_PIXEL_CNT: case CELL_GCM_ZPASS_PIXEL_CNT:
if (!g_cfg.video.precise_zpass_count)
{
value = value ? u16{ umax } : 0; value = value ? u16{ umax } : 0;
}
break; break;
case CELL_GCM_ZCULL_STATS3: case CELL_GCM_ZCULL_STATS3:
value = value ? 0 : u16{umax}; value = value ? 0 : u16{umax};
@ -3470,7 +3473,9 @@ namespace rsx
ensure(query->pending); ensure(query->pending);
const bool implemented = (writer.type == CELL_GCM_ZPASS_PIXEL_CNT || writer.type == CELL_GCM_ZCULL_STATS3); const bool implemented = (writer.type == CELL_GCM_ZPASS_PIXEL_CNT || writer.type == CELL_GCM_ZCULL_STATS3);
if (implemented && !result && query->num_draws) const bool have_result = result && !g_cfg.video.precise_zpass_count;
if (implemented && !have_result && query->num_draws)
{ {
get_occlusion_query_result(query); get_occlusion_query_result(query);
@ -3622,9 +3627,13 @@ namespace rsx
ensure(query->pending); ensure(query->pending);
const bool implemented = (writer.type == CELL_GCM_ZPASS_PIXEL_CNT || writer.type == CELL_GCM_ZCULL_STATS3); const bool implemented = (writer.type == CELL_GCM_ZPASS_PIXEL_CNT || writer.type == CELL_GCM_ZCULL_STATS3);
if (force_read) const bool have_result = result && !g_cfg.video.precise_zpass_count;
if (!implemented || !query->num_draws || have_result)
{ {
if (implemented && !result && query->num_draws) discard_occlusion_query(query);
}
else if (force_read || check_occlusion_query_status(query))
{ {
get_occlusion_query_result(query); get_occlusion_query_result(query);
@ -3638,40 +3647,11 @@ namespace rsx
} }
} }
else else
{
//No need to read this
discard_occlusion_query(query);
}
}
else
{
if (implemented && !result && query->num_draws)
{
//Maybe we get lucky and results are ready
if (check_occlusion_query_status(query))
{
get_occlusion_query_result(query);
if (query->result)
{
result += query->result;
if (query->data_type & CELL_GCM_ZPASS_PIXEL_CNT)
{
m_statistics_map[writer.counter_tag] += query->result;
}
}
}
else
{ {
// Too early; abort // Too early; abort
ensure(!force_read && implemented);
break; break;
} }
}
else
{
//Not necessary to read the result anymore
discard_occlusion_query(query);
}
}
free_query(query); free_query(query);
} }

View file

@ -426,6 +426,11 @@ VKGSRender::VKGSRender() : GSRender()
for (u32 n = 0; n < occlusion_query_count; ++n) for (u32 n = 0; n < occlusion_query_count; ++n)
m_occlusion_query_data[n].driver_handle = n; m_occlusion_query_data[n].driver_handle = n;
if (g_cfg.video.precise_zpass_count)
{
m_occlusion_query_manager->set_control_flags(VK_QUERY_CONTROL_PRECISE_BIT, 0);
}
//Generate frame contexts //Generate frame contexts
const auto& binding_table = m_device->get_pipeline_binding_table(); const auto& binding_table = m_device->get_pipeline_binding_table();
const u32 num_fs_samplers = binding_table.vertex_textures_first_bind_slot - binding_table.textures_first_bind_slot; const u32 num_fs_samplers = binding_table.vertex_textures_first_bind_slot - binding_table.textures_first_bind_slot;
@ -2437,7 +2442,7 @@ bool VKGSRender::check_occlusion_query_status(rsx::reports::occlusion_query_info
if (data.is_current(m_current_command_buffer)) if (data.is_current(m_current_command_buffer))
return false; return false;
u32 oldest = data.indices.front(); const u32 oldest = data.indices.front();
return m_occlusion_query_manager->check_query_status(oldest); return m_occlusion_query_manager->check_query_status(oldest);
} }
@ -2468,10 +2473,10 @@ void VKGSRender::get_occlusion_query_result(rsx::reports::occlusion_query_info*
// Gather data // Gather data
for (const auto occlusion_id : data.indices) for (const auto occlusion_id : data.indices)
{ {
// We only need one hit query->result += m_occlusion_query_manager->get_query_result(occlusion_id);
if (m_occlusion_query_manager->get_query_result(occlusion_id)) if (query->result && !g_cfg.video.precise_zpass_count)
{ {
query->result = 1; // We only need one hit unless precise zcull is requested
break; break;
} }
} }

View file

@ -20,12 +20,14 @@ namespace vk
{ {
query.any_passed = true; query.any_passed = true;
query.ready = true; query.ready = true;
query.data = result[0];
return true; return true;
} }
else if (result[1]) else if (result[1])
{ {
query.any_passed = false; query.any_passed = false;
query.ready = true; query.ready = true;
query.data = 0;
return true; return true;
} }
@ -33,10 +35,11 @@ namespace vk
} }
case VK_NOT_READY: case VK_NOT_READY:
{ {
if (result[0]) if (result[0] && (flags & VK_QUERY_RESULT_PARTIAL_BIT))
{ {
query.any_passed = true; query.any_passed = true;
query.ready = true; query.ready = true;
query.data = result[0];
return true; return true;
} }
@ -123,6 +126,12 @@ namespace vk
} }
} }
void query_pool_manager::set_control_flags(VkQueryControlFlags control_, VkQueryResultFlags result_)
{
control_flags = control_;
result_flags = result_;
}
void query_pool_manager::begin_query(vk::command_buffer& cmd, u32 index) void query_pool_manager::begin_query(vk::command_buffer& cmd, u32 index)
{ {
ensure(query_slot_status[index].active == false); ensure(query_slot_status[index].active == false);
@ -131,7 +140,7 @@ namespace vk
query_info.pool = m_current_query_pool.get(); query_info.pool = m_current_query_pool.get();
query_info.active = true; query_info.active = true;
vkCmdBeginQuery(cmd, *query_info.pool, index, 0);//VK_QUERY_CONTROL_PRECISE_BIT); vkCmdBeginQuery(cmd, *query_info.pool, index, control_flags);
} }
void query_pool_manager::end_query(vk::command_buffer& cmd, u32 index) void query_pool_manager::end_query(vk::command_buffer& cmd, u32 index)
@ -141,20 +150,19 @@ namespace vk
bool query_pool_manager::check_query_status(u32 index) bool query_pool_manager::check_query_status(u32 index)
{ {
return poke_query(query_slot_status[index], index, VK_QUERY_RESULT_PARTIAL_BIT); return poke_query(query_slot_status[index], index, result_flags);
} }
u32 query_pool_manager::get_query_result(u32 index) u32 query_pool_manager::get_query_result(u32 index)
{ {
// Check for cached result // Check for cached result
auto& query_info = query_slot_status[index]; auto& query_info = query_slot_status[index];
while (!query_info.ready) while (!query_info.ready)
{ {
poke_query(query_info, index, VK_QUERY_RESULT_PARTIAL_BIT); poke_query(query_info, index, result_flags);
} }
return query_info.any_passed ? 1 : 0; return query_info.data;
} }
void query_pool_manager::get_query_result_indirect(vk::command_buffer& cmd, u32 index, VkBuffer dst, VkDeviceSize dst_offset) void query_pool_manager::get_query_result_indirect(vk::command_buffer& cmd, u32 index, VkBuffer dst, VkDeviceSize dst_offset)

View file

@ -16,13 +16,17 @@ namespace vk
bool any_passed; bool any_passed;
bool active; bool active;
bool ready; bool ready;
u32 data;
}; };
std::vector<std::unique_ptr<query_pool>> m_consumed_pools; std::vector<std::unique_ptr<query_pool>> m_consumed_pools;
std::unique_ptr<query_pool> m_current_query_pool; std::unique_ptr<query_pool> m_current_query_pool;
std::deque<u32> m_available_slots; std::deque<u32> m_available_slots;
u32 m_pool_lifetime_counter = 0; u32 m_pool_lifetime_counter = 0;
VkQueryType query_type = VK_QUERY_TYPE_OCCLUSION; VkQueryType query_type = VK_QUERY_TYPE_OCCLUSION;
VkQueryResultFlags result_flags = VK_QUERY_RESULT_PARTIAL_BIT;
VkQueryControlFlags control_flags = 0;
vk::render_device* owner = nullptr; vk::render_device* owner = nullptr;
std::vector<query_slot_info> query_slot_status; std::vector<query_slot_info> query_slot_status;
@ -36,6 +40,8 @@ namespace vk
query_pool_manager(vk::render_device& dev, VkQueryType type, u32 num_entries); query_pool_manager(vk::render_device& dev, VkQueryType type, u32 num_entries);
~query_pool_manager(); ~query_pool_manager();
void set_control_flags(VkQueryControlFlags control_flags, VkQueryResultFlags result_flags);
void begin_query(vk::command_buffer& cmd, u32 index); void begin_query(vk::command_buffer& cmd, u32 index);
void end_query(vk::command_buffer& cmd, u32 index); void end_query(vk::command_buffer& cmd, u32 index);

View file

@ -156,6 +156,7 @@ struct cfg_root : cfg::node
cfg::_bool relaxed_zcull_sync{ this, "Relaxed ZCULL Sync", false }; cfg::_bool relaxed_zcull_sync{ this, "Relaxed ZCULL Sync", false };
cfg::_bool enable_3d{ this, "Enable 3D", false }; cfg::_bool enable_3d{ this, "Enable 3D", false };
cfg::_bool debug_program_analyser{ this, "Debug Program Analyser", false }; cfg::_bool debug_program_analyser{ this, "Debug Program Analyser", false };
cfg::_bool precise_zpass_count{ this, "Accurate ZCULL stats", false };
cfg::_int<1, 8> consecutive_frames_to_draw{ this, "Consecutive Frames To Draw", 1, true}; cfg::_int<1, 8> consecutive_frames_to_draw{ this, "Consecutive Frames To Draw", 1, true};
cfg::_int<1, 8> consecutive_frames_to_skip{ this, "Consecutive Frames To Skip", 1, true}; cfg::_int<1, 8> consecutive_frames_to_skip{ this, "Consecutive Frames To Skip", 1, true};
cfg::_int<50, 800> resolution_scale_percent{ this, "Resolution Scale", 100 }; cfg::_int<50, 800> resolution_scale_percent{ this, "Resolution Scale", 100 };