mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-04-21 20:15:27 +00: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();
|
||||
|
||||
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();
|
||||
|
||||
|
@ -1061,13 +1062,13 @@ void GLGSRender::notify_tile_unbound(u32 tile)
|
|||
void GLGSRender::begin_occlusion_query(rsx::reports::occlusion_query_info* query)
|
||||
{
|
||||
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)
|
||||
{
|
||||
ensure(query->active);
|
||||
glEndQuery(GL_ANY_SAMPLES_PASSED);
|
||||
glEndQuery(m_occlusion_type);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
//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::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:
|
||||
u64 get_cycles() final;
|
||||
GLGSRender();
|
||||
|
|
|
@ -3377,7 +3377,10 @@ namespace rsx
|
|||
switch (type)
|
||||
{
|
||||
case CELL_GCM_ZPASS_PIXEL_CNT:
|
||||
value = value ? u16{umax} : 0;
|
||||
if (!g_cfg.video.precise_zpass_count)
|
||||
{
|
||||
value = value ? u16{ umax } : 0;
|
||||
}
|
||||
break;
|
||||
case CELL_GCM_ZCULL_STATS3:
|
||||
value = value ? 0 : u16{umax};
|
||||
|
@ -3470,7 +3473,9 @@ namespace rsx
|
|||
ensure(query->pending);
|
||||
|
||||
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);
|
||||
|
||||
|
@ -3622,55 +3627,30 @@ namespace rsx
|
|||
ensure(query->pending);
|
||||
|
||||
const bool implemented = (writer.type == CELL_GCM_ZPASS_PIXEL_CNT || writer.type == CELL_GCM_ZCULL_STATS3);
|
||||
if (force_read)
|
||||
{
|
||||
if (implemented && !result && query->num_draws)
|
||||
{
|
||||
get_occlusion_query_result(query);
|
||||
const bool have_result = result && !g_cfg.video.precise_zpass_count;
|
||||
|
||||
if (query->result)
|
||||
{
|
||||
result += query->result;
|
||||
if (query->data_type & CELL_GCM_ZPASS_PIXEL_CNT)
|
||||
{
|
||||
m_statistics_map[writer.counter_tag] += query->result;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
if (!implemented || !query->num_draws || have_result)
|
||||
{
|
||||
discard_occlusion_query(query);
|
||||
}
|
||||
else if (force_read || check_occlusion_query_status(query))
|
||||
{
|
||||
get_occlusion_query_result(query);
|
||||
|
||||
if (query->result)
|
||||
{
|
||||
//No need to read this
|
||||
discard_occlusion_query(query);
|
||||
result += query->result;
|
||||
if (query->data_type & CELL_GCM_ZPASS_PIXEL_CNT)
|
||||
{
|
||||
m_statistics_map[writer.counter_tag] += query->result;
|
||||
}
|
||||
}
|
||||
}
|
||||
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
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//Not necessary to read the result anymore
|
||||
discard_occlusion_query(query);
|
||||
}
|
||||
// Too early; abort
|
||||
ensure(!force_read && implemented);
|
||||
break;
|
||||
}
|
||||
|
||||
free_query(query);
|
||||
|
|
|
@ -426,6 +426,11 @@ VKGSRender::VKGSRender() : GSRender()
|
|||
for (u32 n = 0; n < occlusion_query_count; ++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
|
||||
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;
|
||||
|
@ -2437,7 +2442,7 @@ bool VKGSRender::check_occlusion_query_status(rsx::reports::occlusion_query_info
|
|||
if (data.is_current(m_current_command_buffer))
|
||||
return false;
|
||||
|
||||
u32 oldest = data.indices.front();
|
||||
const u32 oldest = data.indices.front();
|
||||
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
|
||||
for (const auto occlusion_id : data.indices)
|
||||
{
|
||||
// We only need one hit
|
||||
if (m_occlusion_query_manager->get_query_result(occlusion_id))
|
||||
query->result += 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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,12 +20,14 @@ namespace vk
|
|||
{
|
||||
query.any_passed = true;
|
||||
query.ready = true;
|
||||
query.data = result[0];
|
||||
return true;
|
||||
}
|
||||
else if (result[1])
|
||||
{
|
||||
query.any_passed = false;
|
||||
query.ready = true;
|
||||
query.data = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -33,10 +35,11 @@ namespace vk
|
|||
}
|
||||
case VK_NOT_READY:
|
||||
{
|
||||
if (result[0])
|
||||
if (result[0] && (flags & VK_QUERY_RESULT_PARTIAL_BIT))
|
||||
{
|
||||
query.any_passed = true;
|
||||
query.ready = true;
|
||||
query.data = result[0];
|
||||
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)
|
||||
{
|
||||
ensure(query_slot_status[index].active == false);
|
||||
|
@ -131,7 +140,7 @@ namespace vk
|
|||
query_info.pool = m_current_query_pool.get();
|
||||
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)
|
||||
|
@ -141,20 +150,19 @@ namespace vk
|
|||
|
||||
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)
|
||||
{
|
||||
// Check for cached result
|
||||
auto& query_info = query_slot_status[index];
|
||||
|
||||
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)
|
||||
|
|
|
@ -16,13 +16,17 @@ namespace vk
|
|||
bool any_passed;
|
||||
bool active;
|
||||
bool ready;
|
||||
u32 data;
|
||||
};
|
||||
|
||||
std::vector<std::unique_ptr<query_pool>> m_consumed_pools;
|
||||
std::unique_ptr<query_pool> m_current_query_pool;
|
||||
std::deque<u32> m_available_slots;
|
||||
u32 m_pool_lifetime_counter = 0;
|
||||
|
||||
VkQueryType query_type = VK_QUERY_TYPE_OCCLUSION;
|
||||
VkQueryResultFlags result_flags = VK_QUERY_RESULT_PARTIAL_BIT;
|
||||
VkQueryControlFlags control_flags = 0;
|
||||
|
||||
vk::render_device* owner = nullptr;
|
||||
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();
|
||||
|
||||
void set_control_flags(VkQueryControlFlags control_flags, VkQueryResultFlags result_flags);
|
||||
|
||||
void begin_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 enable_3d{ this, "Enable 3D", 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_skip{ this, "Consecutive Frames To Skip", 1, true};
|
||||
cfg::_int<50, 800> resolution_scale_percent{ this, "Resolution Scale", 100 };
|
||||
|
|
Loading…
Add table
Reference in a new issue