Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/WolfireGames/overgrowth.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'Source/Timing/intel_gl_perf.cpp')
-rw-r--r--Source/Timing/intel_gl_perf.cpp293
1 files changed, 293 insertions, 0 deletions
diff --git a/Source/Timing/intel_gl_perf.cpp b/Source/Timing/intel_gl_perf.cpp
new file mode 100644
index 00000000..87dde426
--- /dev/null
+++ b/Source/Timing/intel_gl_perf.cpp
@@ -0,0 +1,293 @@
+//-----------------------------------------------------------------------------
+// Name: intel_gl_perf.cpp
+// Developer: Wolfire Games LLC
+// Description:
+// License: Read below
+//-----------------------------------------------------------------------------
+//
+// Copyright 2022 Wolfire Games LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-----------------------------------------------------------------------------
+#include "intel_gl_perf.h"
+#ifdef INTEL_TIMING
+
+#include <Internal/integer.h>
+#include <Internal/filesystem.h>
+#include <Internal/snprintf.h>
+
+#include <Memory/allocation.h>
+#include <Logging/logdata.h>
+#include <Utility/assert.h>
+
+#include <opengl.h>
+
+#include <cstdlib>
+
+IntelGLPerfRequest::IntelGLPerfRequest( std::string query_name, int type_id, std::vector<std::string> query_counter_names ) :
+query_name(query_name),
+type_id(type_id),
+query_counter_names(query_counter_names)
+{
+}
+
+IntelGLPerf::IntelGLPerf() :
+max_query_size(0),
+data_dest(NULL)
+{
+ std::vector<std::string> query_counter_names;
+ query_counter_names.push_back("GpuTime");
+
+ perf_requests.push_back(
+ IntelGLPerfRequest(
+ "Intel_HD_MD_Render_Basic_Hardware_Counters",
+ kIntelGLPerf_TypeId_Standard,
+ query_counter_names
+ )
+ );
+}
+
+IntelGLPerf::~IntelGLPerf() {
+ if( data_dest )
+ OG_FREE(data_dest);
+
+ if( csv_output.is_open() ) {
+ csv_output.close();
+ }
+
+ std::map<std::string,GLuint>::iterator query_it = active_query_handles.begin();
+
+ for( ;query_it != active_query_handles.end(); query_it++ ) {
+ glDeletePerfQueryINTEL(query_it->second);
+ }
+}
+
+void IntelGLPerf::Init() {
+ LOGI << "Initializing IntelGLPerf" << std::endl;
+
+ //Check if this plugin is available.
+ if( GLEW_INTEL_performance_query ) {
+ perf_available = true;
+
+ GLuint query_id;
+ glGetFirstPerfQueryIdINTEL(&query_id);
+ while( query_id != 0 ) {
+ const GLuint query_name_len = 64;
+ GLchar query_name[query_name_len];
+ GLuint data_size;
+ GLuint no_counters;
+ GLuint no_instances;
+ GLuint caps_mask;
+
+ glGetPerfQueryInfoINTEL(query_id,
+ query_name_len, query_name,
+ &data_size, &no_counters,
+ &no_instances, &caps_mask);
+
+ for( unsigned i = 0; i < perf_requests.size(); i++ ){
+ IntelGLPerfRequest &pr = perf_requests[i];
+ if( pr.query_name == std::string(query_name) ) {
+ IntelGLPerfQuery iglpq;
+
+ iglpq.id = query_id;
+ iglpq.name = std::string(query_name);
+ iglpq.size = data_size;
+ iglpq.type_id = pr.type_id;
+ queries.push_back(iglpq);
+
+ if( data_size > max_query_size )
+ max_query_size = data_size;
+ }
+ }
+
+ data_dest = static_cast<char*>(OG_MALLOC( max_query_size ));
+
+ LOGI << "Have query id: " << query_id << std::endl
+ << "name:" << query_name << std::endl
+ << "data_size:" << data_size << std::endl
+ << "no_counters: " << no_counters << std::endl
+ << "no_instances: " << no_instances << std::endl
+ << "caps_mask: " << caps_mask << std::endl
+ << std::endl;
+
+ for(unsigned counter_id = 1; counter_id <= no_counters; counter_id++) {
+ const GLuint counter_name_len = 32;
+ GLchar counter_name[counter_name_len];
+ const GLuint counter_desc_len = 256;
+ GLchar counter_desc[counter_desc_len];
+ GLuint counter_offset;
+ GLuint counter_data_size;
+ GLuint counter_type_enum;
+ GLuint counter_data_type_enum;
+ uint64_t raw_counter_max_value;
+
+ glGetPerfCounterInfoINTEL(
+ query_id,
+ counter_id,
+ counter_name_len,
+ counter_name,
+ counter_desc_len,
+ counter_desc,
+ &counter_offset,
+ &counter_data_size,
+ &counter_type_enum,
+ &counter_data_type_enum,
+ &raw_counter_max_value);
+
+ for( unsigned i = 0; i < perf_requests.size(); i++ ){
+ IntelGLPerfRequest &pr = perf_requests[i];
+ if( pr.query_name == std::string(query_name) ) {
+ for( unsigned k = 0; k < pr.query_counter_names.size(); k++ ) {
+ if( pr.query_counter_names[k] == std::string(counter_name) ) {
+ IntelGLPerfQueryCounter iglpqc;
+
+ iglpqc.query_id = query_id;
+ iglpqc.id = counter_id;
+ iglpqc.data_type = counter_data_type_enum;
+ iglpqc.name = std::string(counter_name);
+ iglpqc.offset = counter_offset;
+ iglpqc.size = counter_data_size;
+
+ query_counters.push_back(iglpqc);
+ }
+ }
+ }
+ }
+
+ LOGI << "Query counter info, query_id: " << query_id << std::endl
+ << "counter_id: " << counter_id << std::endl
+ << "counter_name: " << counter_name << std::endl
+ << "counter_desc: " << counter_desc << std::endl
+ << "counter_offset: " << counter_offset << std::endl
+ << "counter_data_size: " << counter_data_size << std::endl
+ << "counter_type_enum: " << std::hex << counter_type_enum << std::endl
+ << "counter_dta_type_enum: " << std::hex << counter_data_type_enum << std::endl
+ << "raw_counter_max_value: " << raw_counter_max_value << std::endl;
+ }
+
+ glGetNextPerfQueryIdINTEL(query_id, &query_id);
+ }
+ std::string path = std::string(GetWritePath(CoreGameModID).c_str())+ "/intel_gl_perf.csv";
+ my_ofstream_open( csv_output, path.c_str() );
+ } else {
+ LOGI << "Intel performance query is not available on this machine" << std::endl;
+ }
+}
+
+void IntelGLPerf::Finalize() {
+ if( perf_available )
+ {
+ //TODO: Dispose all available handles
+ //TODO: dispose of all actively used query handles
+ }
+}
+
+void IntelGLPerf::PerfGPUBegin(int type, int group, const char* file, const int line) {
+ if( perf_available )
+ {
+ GLuint query_id = 0;
+
+ int offset = 0;
+ int slash_pos = 0;
+ while( *(file + offset) != '\0' ){
+ if( *(file + offset) == '/' || *(file+offset) == '\\')
+ slash_pos = offset;
+ offset++;
+ }
+
+ char counter_name[256];
+ snprintf( counter_name, 256, "%s_%d", file+slash_pos+1, line );
+
+ std::map<std::string,GLuint>::iterator query_it = active_query_handles.find(std::string(counter_name));
+
+ for( unsigned i = 0; i < queries.size(); i++) {
+ if( queries[i].type_id == type ) {
+ query_id = queries[i].id;
+ }
+ }
+
+ GLuint query_handle;
+ if( query_it != active_query_handles.end() ) {
+ query_handle = query_it->second;
+ } else {
+ glCreatePerfQueryINTEL(query_id,&query_handle);
+ active_query_handles[std::string(counter_name)] = query_handle;
+ }
+
+ PerfInstance perf;
+ perf.instance_id = query_handle;
+ glBeginPerfQueryINTEL(perf.instance_id);
+
+ perf.group = group;
+ perf.file = file+slash_pos+1;
+ perf.line = line;
+ perf.query_id = query_id;
+
+ perf_query_instances.push_back(perf);
+ query_handle_stack.push(perf.instance_id);
+ }
+}
+
+void IntelGLPerf::PerfGPUEnd() {
+ if( perf_available )
+ {
+ glEndPerfQueryINTEL(query_handle_stack.top());
+ query_handle_stack.pop();
+ }
+}
+
+void IntelGLPerf::PostFrameSwap() {
+ if( perf_available ) {
+ for( unsigned i = 0; i < perf_query_instances.size(); i++ ) {
+ PerfInstance& p = perf_query_instances[i];
+ GLuint bytes_written;
+ glGetPerfQueryDataINTEL(
+ p.instance_id,
+ GL_PERFQUERY_WAIT_INTEL,
+ max_query_size,
+ data_dest,
+ &bytes_written);
+
+ for( unsigned k = 0; k < query_counters.size(); k++ ) {
+ if( query_counters[k].query_id == p.query_id ) {
+ char* data = data_dest + query_counters[k].offset;
+ switch( query_counters[k].data_type ){
+ case GL_PERFQUERY_COUNTER_DATA_UINT32_INTEL:
+ csv_output << p.file << ":" << p.line << "," << query_counters[k].name << "," << *((uint32_t*)data) << std::endl;
+ break;
+ case GL_PERFQUERY_COUNTER_DATA_UINT64_INTEL:
+ csv_output << p.file << ":" << p.line << "," << query_counters[k].name << "," << *((uint64_t*)data) << std::endl;
+ break;
+ case GL_PERFQUERY_COUNTER_DATA_FLOAT_INTEL:
+ csv_output << p.file << ":" << p.line << "," << query_counters[k].name << "," << *((float*)data) << std::endl;
+ break;
+ case GL_PERFQUERY_COUNTER_DATA_DOUBLE_INTEL:
+ csv_output << p.file << ":" << p.line << "," << query_counters[k].name << "," << *((double*)data) << std::endl;
+ break;
+ case GL_PERFQUERY_COUNTER_DATA_BOOL32_INTEL:
+ csv_output << p.file << ":" << p.line << "," << query_counters[k].name << "," << (*((uint32_t*)data) ? "true" : "false") << std::endl;
+ break;
+ }
+ }
+ }
+
+ }
+ perf_query_instances.clear();
+ }
+}
+
+IntelGLPerf IntelGLTiming;
+IntelGLPerf* intelGLTiming = &IntelGLTiming;
+
+#endif