MetricType Metric_INTEL_perfquery::type() {
    GLenum type;
    glGetPerfCounterInfoINTEL(m_group, m_id, 0, nullptr, 0, nullptr, nullptr,
                              nullptr, &type, nullptr, nullptr);
    if (type == GL_PERFQUERY_COUNTER_TIMESTAMP_INTEL) return CNT_TYPE_TIMESTAMP;
    else if (type == GL_PERFQUERY_COUNTER_EVENT_INTEL) return CNT_TYPE_NUM;
    else if (type == GL_PERFQUERY_COUNTER_DURATION_NORM_INTEL ||
             type == GL_PERFQUERY_COUNTER_DURATION_RAW_INTEL) return CNT_TYPE_DURATION;
    else if (type == GL_PERFQUERY_COUNTER_RAW_INTEL) return CNT_TYPE_GENERIC;
    else if (type == GL_PERFQUERY_COUNTER_THROUGHPUT_INTEL) return CNT_TYPE_GENERIC;
    else return CNT_TYPE_OTHER;
}
void Metric_INTEL_perfquery::precache() {
    unsigned offset;
    glGetPerfCounterInfoINTEL(m_group, m_id, 0, nullptr, 0, nullptr, &offset,
                              nullptr, nullptr, nullptr, nullptr);
    this->m_offset = offset;

    GLenum type;
    glGetPerfCounterInfoINTEL(m_group, m_id, 0, nullptr, 0, nullptr, nullptr,
                              nullptr, nullptr, &type, nullptr);
    if (type == GL_PERFQUERY_COUNTER_DATA_UINT32_INTEL) m_nType = CNT_NUM_UINT;
    else if (type == GL_PERFQUERY_COUNTER_DATA_FLOAT_INTEL) m_nType = CNT_NUM_FLOAT;
    else if (type == GL_PERFQUERY_COUNTER_DATA_DOUBLE_INTEL) m_nType = CNT_NUM_DOUBLE;
    else if (type == GL_PERFQUERY_COUNTER_DATA_BOOL32_INTEL) m_nType = CNT_NUM_BOOL;
    else if (type == GL_PERFQUERY_COUNTER_DATA_UINT64_INTEL) m_nType = CNT_NUM_UINT64;
    else m_nType = CNT_NUM_UINT;

    char name[INTEL_NAME_LENGTH];
    glGetPerfCounterInfoINTEL(m_group, m_id, INTEL_NAME_LENGTH, name, 0, nullptr,
                              nullptr, nullptr, nullptr, nullptr, nullptr);
    m_name = std::string(name);

    m_precached = true;
}
std::string Metric_INTEL_perfquery::description() {
    char desc[INTEL_DESC_LENGTH];
    glGetPerfCounterInfoINTEL(m_group, m_id, 0, nullptr, INTEL_DESC_LENGTH, desc,
                              nullptr, nullptr, nullptr, nullptr, nullptr);
    return std::string(desc);
}
	bool initPerf()
	{
		GLint QueryNameMaxLength = 0;
		glGetIntegerv(GL_PERFQUERY_QUERY_NAME_LENGTH_MAX_INTEL, &QueryNameMaxLength);
		GLint CounterNameMaxLength = 0;
		glGetIntegerv(GL_PERFQUERY_COUNTER_NAME_LENGTH_MAX_INTEL, &CounterNameMaxLength);
		GLint CounterDescMaxLength = 0;
		glGetIntegerv(GL_PERFQUERY_COUNTER_DESC_LENGTH_MAX_INTEL, &CounterDescMaxLength);

		const GLuint queryNameLen = 1024;
		GLchar queryName[queryNameLen];

		const GLuint counterNameLen = 1024;
		GLchar counterName[counterNameLen];

		const GLuint counterDescLen = 4096;
		GLchar counterDesc[counterDescLen];

		GLuint queryId;
		glGetFirstPerfQueryIdINTEL(&queryId);

		while(queryId)
		{
			GLuint dataSize = 0;
			GLuint noCounters = 0;
			GLuint noInstances = 0;
			GLuint capsMask = 0;

			memset(queryName, 0, sizeof(queryName));

			glGetPerfQueryInfoINTEL(
				queryId,
				QueryNameMaxLength,
				queryName,
				&dataSize,
				&noCounters,
				&noInstances,
				&capsMask);

			printf("%d - %s (%s)/ output size: %d, counters: %d, instances: %d\n", queryId, queryName, capsMask & GL_PERFQUERY_GLOBAL_CONTEXT_INTEL ? "global" : "local", dataSize, noCounters, noInstances);

			glGetNextPerfQueryIdINTEL(queryId, &queryId);

			for(GLuint counterId = 1; counterId <= noCounters; counterId++)
			{
				GLuint counterOffset = 0;
				GLuint counterDataSize = 0;
				GLuint counterTypeEnum = 0;
				GLuint counterDataTypeEnum = 0;
				GLuint64 rawCounterMaxValue = 0;

				memset(counterName, 0, sizeof(counterName));
				memset(counterDesc, 0, sizeof(counterDesc));

				glGetPerfCounterInfoINTEL(
					queryId,
					counterId,
					CounterNameMaxLength,
					counterName,
					CounterDescMaxLength,
					counterDesc,
					&counterOffset,
					&counterDataSize,
					&counterTypeEnum,
					&counterDataTypeEnum,
					&rawCounterMaxValue);

				printf("- %d - %s output: %s - %s - %d, max counter values: %lld\n", counterId, counterName, GetCounterTypeString(counterTypeEnum), GetCounterDataTypeString(counterDataTypeEnum), dataSize, rawCounterMaxValue);
				printf("\t%s\n", counterDesc);

				continue;
			}
		}

		return true;
	}