mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-14 02:38:37 +12:00
rsx: Implement precise ZCULL stats
This commit is contained in:
parent
0525070898
commit
472efc08eb
7 changed files with 62 additions and 58 deletions
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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 };
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue