Example #1
0
void GLGSRender::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 = 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))
		{
			glEndQuery(GL_ANY_SAMPLES_PASSED);
			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);

			glBeginQuery(GL_ANY_SAMPLES_PASSED, query->handle);
			query->active = true;
			query->result = 0;
			query->num_draws = 0;
		}
	}
}
Example #2
0
u32 GLGSRender::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;
	}
}
Example #3
0
u32 GLGSRender::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)
	{
		//The zcull unit is still bound as the read is happening and there are no results ready
		check_zcull_status(false, true);
	}

	switch (type)
	{
	case CELL_GCM_ZPASS_PIXEL_CNT:
	{
		if (current_zcull_stats.zpass_pixel_cnt > 0)
			return UINT32_MAX;

		//If we have no results, we might as well synchronize here and wait for results to become available
		synchronize_zcull_stats(true);
		return (current_zcull_stats.zpass_pixel_cnt > 0)? UINT32_MAX: 0;
	}
	case CELL_GCM_ZCULL_STATS:
	case CELL_GCM_ZCULL_STATS1:
	case CELL_GCM_ZCULL_STATS2:
		//TODO
		return UINT32_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 : UINT32_MAX;
	}
	default:
		LOG_ERROR(RSX, "Unknown zcull stat type %d", type);
		return 0;
	}
}
Example #4
0
u32 GLGSRender::synchronize_zcull_stats(bool hard_sync)
{
	if (!zcull_rendering_enabled || zcull_task_queue.pending == 0)
		return 0;

	u32 result = UINT16_MAX;
	GLint count, status;

	for (auto &query : zcull_task_queue.task_stack)
	{
		if (query == nullptr || query->active)
			continue;

		glGetQueryObjectiv(query->handle, GL_QUERY_RESULT_AVAILABLE, &status);

		if (status == GL_FALSE && !hard_sync)
			continue;

		glGetQueryObjectiv(query->handle, GL_QUERY_RESULT, &count);
		query->pending = false;
		query = nullptr;

		current_zcull_stats.zpass_pixel_cnt += count;
		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;
}