diff options
author | Mark Janes <mark.a.janes@intel.com> | 2017-04-03 21:09:11 -0700 |
---|---|---|
committer | Mark Janes <mark.a.janes@intel.com> | 2017-06-19 14:04:51 -0700 |
commit | aabb76b85595e211560d2d01b1f78c9188ea5e51 (patch) | |
tree | bf13f9fd61c669232b02f04f4f70b0a8dfec3c18 | |
parent | c49e091b8949520b01c9d174dafb2f0121896c3f (diff) |
Support multiple contexts
Metrics can only be collected for a single context, with the current
implementation of INTEL_performance_query. Stop/start metrics before
and after context switches, and collect metrics from each context before
publishing.
Reorganize renders into contexts. Contexts contain renders for a GL
context, and manage state changes that must be intstrumented as contexts
switch.
Eliminate awkward checking of current context when retracing metrics.
Subsequent features (state tracking/uniforms) will be per-context.
-rw-r--r-- | lib/trace/trace_parser.hpp | 1 | ||||
-rw-r--r-- | retrace/daemon/CMakeLists.txt | 2 | ||||
-rw-r--r-- | retrace/daemon/glframe_metrics.cpp | 210 | ||||
-rw-r--r-- | retrace/daemon/glframe_metrics.hpp | 19 | ||||
-rw-r--r-- | retrace/daemon/glframe_retrace.cpp | 249 | ||||
-rw-r--r-- | retrace/daemon/glframe_retrace.hpp | 5 | ||||
-rw-r--r-- | retrace/daemon/glframe_retrace_context.cpp | 397 | ||||
-rw-r--r-- | retrace/daemon/glframe_retrace_context.hpp | 108 | ||||
-rw-r--r-- | retrace/daemon/glframe_retrace_interface.hpp | 3 | ||||
-rw-r--r-- | retrace/daemon/glframe_retrace_render.cpp | 73 | ||||
-rw-r--r-- | retrace/daemon/glframe_retrace_render.hpp | 5 | ||||
-rw-r--r-- | retrace/daemon/glframe_state.cpp | 18 | ||||
-rw-r--r-- | retrace/daemon/glframe_state.hpp | 2 | ||||
-rw-r--r-- | retrace/daemon/test/retrace_metrics_test.cpp | 4 | ||||
-rw-r--r-- | retrace/daemon/ui/main.cpp | 2 | ||||
-rw-r--r-- | retrace/retrace_swizzle.cpp | 2 |
16 files changed, 783 insertions, 317 deletions
diff --git a/lib/trace/trace_parser.hpp b/lib/trace/trace_parser.hpp index dad9f9cf..747fb8f9 100644 --- a/lib/trace/trace_parser.hpp +++ b/lib/trace/trace_parser.hpp @@ -34,7 +34,6 @@ #include "trace_model.hpp" #include "trace_api.hpp" - namespace trace { diff --git a/retrace/daemon/CMakeLists.txt b/retrace/daemon/CMakeLists.txt index fea03d69..2d3a3c33 100644 --- a/retrace/daemon/CMakeLists.txt +++ b/retrace/daemon/CMakeLists.txt @@ -56,6 +56,8 @@ set (RETRACE_SOURCES glframe_perf_enabled.hpp glframe_retrace.cpp glframe_retrace.hpp + glframe_retrace_context.cpp + glframe_retrace_context.hpp glframe_retrace_interface.hpp glframe_retrace_render.cpp glframe_retrace_render.hpp diff --git a/retrace/daemon/glframe_metrics.cpp b/retrace/daemon/glframe_metrics.cpp index 05d28972..3e3b57e8 100644 --- a/retrace/daemon/glframe_metrics.cpp +++ b/retrace/daemon/glframe_metrics.cpp @@ -36,6 +36,7 @@ #include "glframe_glhelper.hpp" #include "glframe_logger.hpp" +#include "glretrace.hpp" using glretrace::ExperimentId; using glretrace::GlFunctions; @@ -43,10 +44,13 @@ using glretrace::MetricId; using glretrace::NoAssign; using glretrace::NoCopy; using glretrace::OnFrameRetrace; -using glretrace::PerfMetricGroup; using glretrace::PerfMetrics; +using glretrace::PerfMetricsContext; using glretrace::RenderId; using glretrace::SelectionId; +using glretrace::GL; +using glretrace::glretrace_delay; +using glretrace::ID_PREFIX_MASK; namespace { @@ -75,7 +79,6 @@ class PerfMetric : public NoCopy, NoAssign { std::string m_name, m_description; }; -} // namespace class PerfMetricGroup : public NoCopy, NoAssign { public: @@ -85,17 +88,12 @@ class PerfMetricGroup : public NoCopy, NoAssign { void metrics(std::vector<MetricDescription> *m) const; void begin(RenderId render); void end(RenderId render); - void publish(MetricId metric, - ExperimentId experimentCount, - SelectionId selectionCount, - OnFrameRetrace *callback); + void publish(MetricId metric, PerfMetrics::MetricMap *m); private: std::string m_query_name; const int m_query_id; unsigned int m_data_size; - unsigned int m_number_counters; - unsigned int m_capabilities_mask; std::vector<unsigned char> m_data_buf; std::map<MetricId, PerfMetric *> m_metrics; @@ -107,7 +105,34 @@ class PerfMetricGroup : public NoCopy, NoAssign { std::vector<unsigned int> m_free_query_handles; }; -PerfMetrics::PerfMetrics(OnFrameRetrace *cb) : current_group(NULL) { +} // namespace + +namespace glretrace { + +class PerfMetricsContext : public NoCopy, NoAssign { + public: + explicit PerfMetricsContext(OnFrameRetrace *cb); + ~PerfMetricsContext(); + int groupCount() const; + void selectMetric(MetricId metric); + void selectGroup(int index); + void begin(RenderId render); + void end(); + void publish(PerfMetrics::MetricMap *metrics); + private: + std::vector<PerfMetricGroup *> groups; + // indicates offset in groups of PerfMetricGroup reporting MetricId + std::map<MetricId, int> metric_map; + // indicates the group that will handle subsequent begin/end calls + PerfMetricGroup *current_group; + MetricId current_metric; + RenderId current_render; +}; + +} // namespace glretrace + +PerfMetricsContext::PerfMetricsContext(OnFrameRetrace *cb) + : current_group(NULL) { GLuint query_id; GLint count; bool has_metrics = false; @@ -121,7 +146,7 @@ PerfMetrics::PerfMetrics(OnFrameRetrace *cb) : current_group(NULL) { return; GlFunctions::GetFirstPerfQueryIdINTEL(&query_id); - if (query_id == -1) + if (query_id == GLuint(-1)) return; if (query_id == 0) @@ -167,10 +192,12 @@ PerfMetrics::PerfMetrics(OnFrameRetrace *cb) : current_group(NULL) { ids.push_back(i.second.id); descriptions.push_back(i.second.description); } - cb->onMetricList(ids, names, descriptions); + if (cb) + // only send metrics list on first context + cb->onMetricList(ids, names, descriptions); } -PerfMetrics::~PerfMetrics() { +PerfMetricsContext::~PerfMetricsContext() { for (auto g : groups) delete g; groups.clear(); @@ -246,25 +273,12 @@ PerfMetricGroup::begin(RenderId render) { m_extant_query_handles[render] = query_handle; } +static const MetricId ALL_METRICS_IN_GROUP = MetricId(~ID_PREFIX_MASK); + void PerfMetricGroup::publish(MetricId metric, - ExperimentId experimentCount, - SelectionId selectionCount, - OnFrameRetrace *callback) { - const bool publish_all = ((metric() | ID_PREFIX_MASK) == -1); - const int publish_count = m_extant_query_handles.size(); - std::map<MetricId, MetricSeries> out_data; - if (publish_all) { - for (auto i : m_metrics) { - out_data[i.first].data.reserve(publish_count); - out_data[i.first].metric = i.first; - } - } else { - assert(m_metrics.find(metric) != m_metrics.end()); - out_data[metric].data.reserve(publish_count); - out_data[metric].metric = metric; - } - + PerfMetrics::MetricMap *out_metrics) { + const bool publish_all = (metric == ALL_METRICS_IN_GROUP); for (auto extant_query : m_extant_query_handles) { memset(m_data_buf.data(), 0, m_data_buf.size()); GLuint bytes_written; @@ -274,22 +288,19 @@ PerfMetricGroup::publish(MetricId metric, &bytes_written); assert(bytes_written == m_data_size); - // TODO(majanes) verify order of m_extant_query_handles is by - // RenderId - for (auto desired_metric : out_data) { - MetricId m = desired_metric.first; - out_data[m].data.push_back(m_metrics[m]->getMetric(m_data_buf)); + if (publish_all) { + for (auto desired_metric : m_metrics) { + MetricId met_id = desired_metric.first; + (*out_metrics)[met_id][extant_query.first] = + desired_metric.second->getMetric(m_data_buf); + } + } else { + (*out_metrics)[metric][extant_query.first] = + m_metrics[metric]->getMetric(m_data_buf); } m_free_query_handles.push_back(extant_query.second); } m_extant_query_handles.clear(); - if (callback) { - for (auto desired_metric : out_data) { - callback->onMetrics(desired_metric.second, - experimentCount, - selectionCount); - } - } for (auto free_query : m_free_query_handles) { GlFunctions::DeletePerfQueryINTEL(free_query); } @@ -298,7 +309,8 @@ PerfMetricGroup::publish(MetricId metric, void PerfMetricGroup::end(RenderId render) { - GlFunctions::EndPerfQueryINTEL(m_extant_query_handles[render]); + if (m_extant_query_handles.find(render) != m_extant_query_handles.end()) + GlFunctions::EndPerfQueryINTEL(m_extant_query_handles[render]); } @@ -381,40 +393,130 @@ PerfMetric::getMetric(const std::vector<unsigned char> &data) const { } void -PerfMetrics::selectMetric(MetricId metric) { +PerfMetricsContext::selectMetric(MetricId metric) { assert(metric_map.find(metric) != metric_map.end()); current_metric = metric; current_group = groups[metric_map[metric]]; } void -PerfMetrics::publish(ExperimentId experimentCount, - SelectionId selectionCount, - OnFrameRetrace *callback) { - current_group->publish(current_metric, experimentCount, - selectionCount, callback); +PerfMetricsContext::publish(PerfMetrics::MetricMap *metrics) { + current_group->publish(current_metric, metrics); } void -PerfMetrics::begin(RenderId render) { +PerfMetricsContext::begin(RenderId render) { current_group->begin(render); current_render = render; } void -PerfMetrics::end() { +PerfMetricsContext::end() { current_group->end(current_render); } int -PerfMetrics::groupCount() const { +PerfMetricsContext::groupCount() const { return groups.size(); } void -PerfMetrics::selectGroup(int index) { +PerfMetricsContext::selectGroup(int index) { current_group = groups[index]; - // choose an invalid metric to represent "all metrics" - current_metric = MetricId(~ID_PREFIX_MASK); + current_metric = ALL_METRICS_IN_GROUP; } +PerfMetrics::PerfMetrics(OnFrameRetrace *cb) + : m_current_group(0) { + Context *c = getCurrentContext(); + m_current_context = new PerfMetricsContext(cb); + m_contexts[c] = m_current_context; +} + +PerfMetrics::~PerfMetrics() { + for (auto i : m_contexts) { + delete i.second; + } + m_contexts.clear(); +} + +int +PerfMetrics::groupCount() const { + assert(!m_contexts.empty()); + return m_contexts.begin()->second->groupCount(); +} + +void +PerfMetrics::selectMetric(MetricId metric) { + m_data.clear(); + m_current_metric = metric; + for (auto i : m_contexts) + i.second->selectMetric(metric); +} + +void +PerfMetrics::selectGroup(int index) { + m_current_group = index; + m_current_metric = ALL_METRICS_IN_GROUP; + for (auto i : m_contexts) + i.second->selectGroup(index); +} + +void +PerfMetrics::begin(RenderId render) { + if (!m_current_context) { + beginContext(); + } + m_current_context->begin(render); +} + +void +PerfMetrics::end() { + if (m_current_context) + m_current_context->end(); +} + +void +PerfMetrics::publish(ExperimentId experimentCount, + SelectionId selectionCount, + OnFrameRetrace *callback) { + for (auto i : m_contexts) + i.second->publish(&m_data); + + for (auto i : m_data) { + MetricSeries s; + s.metric = i.first; + s.data.resize(i.second.rbegin()->first.index() + 1); + for (auto datapoint : i.second) + s.data[datapoint.first.index()] = datapoint.second; + callback->onMetrics(s, experimentCount, selectionCount); + } + m_data.clear(); +} + +void +PerfMetrics::beginContext() { + Context *c = getCurrentContext(); + auto entry = m_contexts.find(c); + if (entry != m_contexts.end()) { + m_current_context = entry->second; + } else { + // create a new metrics context + GRLOG(glretrace::WARN, "new context in frame"); + m_current_context = new PerfMetricsContext(NULL); + m_contexts[c] = m_current_context; + } + m_current_context->selectGroup(m_current_group); + if (m_current_metric() && + (m_current_metric != ALL_METRICS_IN_GROUP)) + m_current_context->selectMetric(m_current_metric); +} + +void +PerfMetrics::endContext() { + if (m_current_context) { + m_current_context->end(); + m_current_context->publish(&m_data); + } + m_current_context = NULL; +} diff --git a/retrace/daemon/glframe_metrics.hpp b/retrace/daemon/glframe_metrics.hpp index 3099b2a7..41180f64 100644 --- a/retrace/daemon/glframe_metrics.hpp +++ b/retrace/daemon/glframe_metrics.hpp @@ -36,7 +36,8 @@ namespace glretrace { -class PerfMetricGroup; +class PerfMetricsContext; +struct Context; class PerfMetrics : public NoCopy, NoAssign { public: @@ -50,14 +51,16 @@ class PerfMetrics : public NoCopy, NoAssign { void publish(ExperimentId experimentCount, SelectionId selectionCount, OnFrameRetrace *callback); + // call before changing to another context + void endContext(); + void beginContext(); + typedef std::map<MetricId, std::map<RenderId, float>> MetricMap; private: - std::vector<PerfMetricGroup *> groups; - // indicates offset in groups of PerfMetricGroup reporting MetricId - std::map<MetricId, int> metric_map; - // indicates the group that will handle subsequent begin/end calls - PerfMetricGroup *current_group; - MetricId current_metric; - RenderId current_render; + PerfMetricsContext* m_current_context; + std::map<Context*, PerfMetricsContext*> m_contexts; + MetricMap m_data; + int m_current_group; + MetricId m_current_metric; }; } // namespace glretrace diff --git a/retrace/daemon/glframe_retrace.cpp b/retrace/daemon/glframe_retrace.cpp index b9fa7f4c..da421c93 100644 --- a/retrace/daemon/glframe_retrace.cpp +++ b/retrace/daemon/glframe_retrace.cpp @@ -36,9 +36,11 @@ #include <vector> #include "glframe_glhelper.hpp" +#include "glframe_gpu_speed.hpp" #include "glframe_logger.hpp" #include "glframe_metrics.hpp" #include "glframe_perf_enabled.hpp" +#include "glframe_retrace_context.hpp" #include "glframe_retrace_render.hpp" #include "glframe_stderr.hpp" #include "glretrace.hpp" @@ -50,7 +52,6 @@ #include "glstate.hpp" #include "glstate_internal.hpp" #include "trace_dump.hpp" -#include "glframe_gpu_speed.hpp" using glretrace::ExperimentId; using glretrace::FrameRetrace; @@ -84,29 +85,21 @@ static StdErrRedirect assemblyOutput; #endif FrameRetrace::FrameRetrace() - : m_tracker(&assemblyOutput) { + : m_tracker(&assemblyOutput), + m_metrics(NULL) { } FrameRetrace::~FrameRetrace() { - delete m_metrics; + if (m_metrics) + delete m_metrics; parser->close(); retrace::cleanUp(); } -int currentRenderBuffer() { - glstate::Context context; - const GLenum framebuffer_binding = context.ES ? - GL_FRAMEBUFFER_BINDING : - GL_DRAW_FRAMEBUFFER_BINDING; - GLint draw_framebuffer = 0; - GlFunctions::GetIntegerv(framebuffer_binding, &draw_framebuffer); - return draw_framebuffer; -} - void FrameRetrace::openFile(const std::string &filename, - const std::vector<unsigned char> &md5, - uint64_t fileSize, + const std::vector<unsigned char> &, + uint64_t, uint32_t framenumber, OnFrameRetrace *callback) { check_gpu_speed(callback); @@ -133,7 +126,7 @@ FrameRetrace::openFile(const std::string &filename, // play up to the requested frame trace::Call *call; - int current_frame = 0; + unsigned int current_frame = 0; while ((call = parser->parse_call()) && current_frame < framenumber) { std::stringstream call_stream; trace::dump(*call, call_stream, @@ -165,36 +158,31 @@ FrameRetrace::openFile(const std::string &filename, return; } + // sends list of available metrics to ui m_metrics = new PerfMetrics(callback); parser->getBookmark(frame_start.start); - int current_render_buffer = currentRenderBuffer(); - // play through the frame, recording renders and call counts + // play through the frame, recording each context + RenderId current_render(0); while (true) { - auto r = new RetraceRender(parser, &retracer, &m_tracker); - if (r->endsFrame()) { - delete r; + auto c = new RetraceContext(current_render, parser, &retracer, &m_tracker); + current_render = RenderId(current_render.index() + c->getRenderCount()); + m_contexts.push_back(c); + if (c->endsFrame()) { break; } - m_renders.push_back(r); - - const int new_render_buffer = currentRenderBuffer(); - if (new_render_buffer != current_render_buffer) { - if (m_renders.size() > 1) // don't record the very first draw as - // ending a render target - render_target_regions.push_back(RenderId(m_renders.size() - 1)); - current_render_buffer = new_render_buffer; - } } - // record the final render as ending a render target region - render_target_regions.push_back(RenderId(m_renders.size() - 1)); callback->onFileOpening(false, true, current_frame); } int FrameRetrace::getRenderCount() const { - return m_renders.size(); + int count = 0; + for (auto i : m_contexts) { + count += i->getRenderCount(); + } + return count; } void @@ -205,75 +193,9 @@ FrameRetrace::retraceRenderTarget(ExperimentId experimentCount, OnFrameRetrace *callback) const { // reset to beginning of frame parser->setBookmark(frame_start.start); - - bool clear_once = true; - - // play up to the beginning of the render - RenderId current_render_id(0); - for (const auto &sequence : selection.series) { - while (current_render_id < sequence.begin) { - m_renders[current_render_id.index()]->retraceRenderTarget(m_tracker, - NORMAL_RENDER); - ++current_render_id; - } - - while (current_render_id < sequence.end) { - if ((options & glretrace::CLEAR_BEFORE_RENDER) && clear_once) { - GlFunctions::Clear(GL_COLOR_BUFFER_BIT); - GlFunctions::Clear(GL_DEPTH_BUFFER_BIT); - GlFunctions::Clear(GL_STENCIL_BUFFER_BIT); - GlFunctions::Clear(GL_ACCUM_BUFFER_BIT); - // ignore errors from unsupported clears - GlFunctions::GetError(); - - // don't clear the frame buffer before every sequence. We - // want to clear everything before the first selection. - clear_once = false; - } - - // play up to the end of the render - m_renders[current_render_id.index()]->retraceRenderTarget(m_tracker, - type); - ++current_render_id; - } - - if (!(options & glretrace::STOP_AT_RENDER)) { - // play to the end of the render target - - const RenderId last_render = lastRenderForRTRegion(current_render_id); - while (current_render_id < last_render) { - const int i = current_render_id.index(); - m_renders[i]->retraceRenderTarget(m_tracker, - NORMAL_RENDER); - ++current_render_id; - } - } - } - - Image *i = glstate::getDrawBufferImage(0); - if (!i) { - GRLOGF(WARN, "Failed to obtain draw buffer image for render id: %d", - current_render_id()); - if (callback) - callback->onError(RETRACE_WARN, "Failed to obtain draw buffer image"); - } else { - std::stringstream png; - i->writePNG(png); - - std::vector<unsigned char> d; - const int bytes = png.str().size(); - d.resize(bytes); - memcpy(d.data(), png.str().c_str(), bytes); - if (callback) - callback->onRenderTarget(selection.id, experimentCount, d); - } - - // play to the rest of the frame - while (current_render_id.index() < m_renders.size()) { - m_renders[current_render_id.index()]->retraceRenderTarget(m_tracker, - NORMAL_RENDER); - ++current_render_id; - } + for (auto i : m_contexts) + i->retraceRenderTarget(experimentCount, selection, type, options, + m_tracker, callback); } void @@ -283,31 +205,8 @@ FrameRetrace::retraceShaderAssembly(const RenderSelection &selection, parser->setBookmark(frame_start.start); StateTrack tmp_tracker = m_tracker; - RenderId current_render_id(0); - for (const auto &sequence : selection.series) { - // play up to the end of the render - while (current_render_id < sequence.begin) { - m_renders[current_render_id.index()]->retrace(&tmp_tracker); - ++current_render_id; - } - while (current_render_id < sequence.end) { - m_renders[current_render_id.index()]->retrace(&tmp_tracker); - callback->onShaderAssembly(current_render_id, - selection.id, - tmp_tracker.currentVertexShader(), - tmp_tracker.currentFragmentShader(), - tmp_tracker.currentTessControlShader(), - tmp_tracker.currentTessEvalShader(), - tmp_tracker.currentGeomShader(), - tmp_tracker.currentCompShader()); - ++current_render_id; - } - } - // play to the rest of the frame - while (current_render_id.index() < m_renders.size()) { - m_renders[current_render_id.index()]->retrace(&tmp_tracker); - ++current_render_id; - } + for (auto i : m_contexts) + i->retraceShaderAssembly(selection, &m_tracker, callback); } FrameState::FrameState(const std::string &filename, @@ -347,9 +246,9 @@ FrameRetrace::retraceMetrics(const std::vector<MetricId> &ids, // retrace the frame once to warm up the gpu, ensuring that the gpu // is not throttled parser->setBookmark(frame_start.start); - for (int i = 0; i < m_renders.size(); ++i) { - m_renders[i]->retrace(m_tracker); - } + + for (auto i : m_contexts) + i->retraceMetrics(NULL, m_tracker); const int render_count = getRenderCount(); for (const auto &id : ids) { @@ -368,16 +267,12 @@ FrameRetrace::retraceMetrics(const std::vector<MetricId> &ids, SelectionId(0)); continue; } - m_metrics->selectMetric(id); - for (int i = 0; i < m_renders.size(); ++i) { - m_metrics->begin(RenderId(i)); - m_renders[i]->retrace(m_tracker); - m_metrics->end(); - } + for (auto i : m_contexts) + i->retraceMetrics(m_metrics, m_tracker); m_metrics->publish(experimentCount, SelectionId(0), // this use case is not based - // on render selection + // on render selection callback); } } @@ -389,44 +284,19 @@ FrameRetrace::retraceAllMetrics(const RenderSelection &selection, // retrace the frame once to warm up the gpu, ensuring that the gpu // is not throttled parser->setBookmark(frame_start.start); - for (int i = 0; i < m_renders.size(); ++i) { - m_renders[i]->retrace(m_tracker); - } + for (auto i : m_contexts) + i->retraceMetrics(NULL, m_tracker); for (int i = 0; i < m_metrics->groupCount(); ++i) { - bool query_active = false; m_metrics->selectGroup(i); parser->setBookmark(frame_start.start); - // iterate through the RenderSelection, and insert begin/end - // around each RenderSeries - auto currentRenderSequence = selection.series.begin(); - for (int i = 0; i < m_renders.size(); ++i) { - if (currentRenderSequence != selection.series.end()) { - if (RenderId(i) == currentRenderSequence->end) { - m_metrics->end(); - query_active = false; - ++currentRenderSequence; - } - if (currentRenderSequence != selection.series.end() && - (RenderId(i) == currentRenderSequence->begin)) { - m_metrics->begin(RenderId(i)); - query_active = true; - } - } - m_renders[i]->retrace(m_tracker); - } - if (query_active) - m_metrics->end(); - m_metrics->publish(experimentCount, selection.id, callback); - } -} -RenderId -FrameRetrace::lastRenderForRTRegion(RenderId render) const { - for (auto rt_render : render_target_regions) - if (rt_render > render) - return rt_render; - return render_target_regions.back(); + for (auto i : m_contexts) + i->retraceAllMetrics(selection, m_metrics, m_tracker); + } + m_metrics->publish(experimentCount, + selection.id, + callback); } void @@ -440,41 +310,16 @@ FrameRetrace::replaceShaders(RenderId renderId, const std::string &comp, OnFrameRetrace *callback) { GRLOGF(DEBUG, "%s\n%s", vs.c_str(), fs.c_str()); - std::string message; - const bool result = m_renders[renderId.index()]->replaceShaders(&m_tracker, - vs, fs, - tessControl, - tessEval, - geom, - comp, - &message); - if (!result) - GRLOGF(WARN, "compile failed: %s", message.c_str()); - callback->onShaderCompile(renderId, experimentCount, - result, message); + for (auto i : m_contexts) + if (i->replaceShaders(renderId, experimentCount, &m_tracker, + vs, fs, tessControl, tessEval, + geom, comp, callback)) + return; } void FrameRetrace::retraceApi(const RenderSelection &selection, OnFrameRetrace *callback) { - if (selection.series.empty()) { - // empty selection: display the full api log - for (RenderId currentRender(0); - currentRender.index() < m_renders.size(); - ++currentRender) { - m_renders[currentRender.index()]->onApi(selection.id, - currentRender, - callback); - } - return; - } - for (auto sequence : selection.series) { - auto currentRender = sequence.begin; - while (currentRender < sequence.end) { - m_renders[currentRender.index()]->onApi(selection.id, - currentRender, - callback); - ++currentRender; - } - } + for (auto i : m_contexts) + i->retraceApi(selection, callback); } diff --git a/retrace/daemon/glframe_retrace.hpp b/retrace/daemon/glframe_retrace.hpp index 5102e888..6f5dd9f1 100644 --- a/retrace/daemon/glframe_retrace.hpp +++ b/retrace/daemon/glframe_retrace.hpp @@ -54,6 +54,7 @@ struct RenderBookmark { class PerfMetrics; class RetraceRender; +class RetraceContext; class FrameRetrace : public IFrameRetrace { public: FrameRetrace(); @@ -105,14 +106,12 @@ class FrameRetrace : public IFrameRetrace { // retrace::Retracer retracer; RenderBookmark frame_start; - std::vector<RetraceRender*> m_renders; + std::vector<RetraceContext*> m_contexts; StateTrack m_tracker; PerfMetrics * m_metrics; // each entry is the last render in an RT region std::vector<RenderId> render_target_regions; - - RenderId lastRenderForRTRegion(RenderId render) const; }; } /* namespace glretrace */ diff --git a/retrace/daemon/glframe_retrace_context.cpp b/retrace/daemon/glframe_retrace_context.cpp new file mode 100644 index 00000000..0fc02e5e --- /dev/null +++ b/retrace/daemon/glframe_retrace_context.cpp @@ -0,0 +1,397 @@ +/************************************************************************** + * + * Copyright 2017 Intel Corporation + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * Authors: + * Mark Janes <mark.a.janes@intel.com> + **************************************************************************/ + +#include "glframe_retrace_context.hpp" + +#include <sstream> +#include <string> +#include <vector> + +#include "trace_model.hpp" +#include "glframe_glhelper.hpp" +#include "glretrace.hpp" +#include "glframe_logger.hpp" +#include "glframe_metrics.hpp" +#include "glframe_retrace_render.hpp" +#include "glstate.hpp" + +using glretrace::RenderId; +using glretrace::RenderSelection; +using glretrace::RetraceContext; +using glretrace::WARN; +using image::Image; + +RetraceContext::RetraceContext(RenderId current_render, + trace::AbstractParser *parser, + retrace::Retracer *retracer, + StateTrack *tracker) + : m_parser(parser), m_retracer(retracer), + m_context_switch(NULL), m_ends_frame(false) { + m_parser->getBookmark(m_start_bookmark); + trace::Call *call = parser->parse_call(); + if (RetraceRender::changesContext(*call)) + m_context_switch = call; + else + delete call; + + m_parser->setBookmark(m_start_bookmark); + + int current_render_buffer = RetraceRender::currentRenderBuffer(); + // play through the frame, generating renders + while (true) { + auto r = new RetraceRender(parser, retracer, tracker); + if (r->endsFrame()) { + delete r; + m_ends_frame = true; + break; + } + m_renders[current_render] = r; + ++current_render; + + // peek ahead to see if next call is in the following context + m_parser->getBookmark(m_end_bookmark); + call = parser->parse_call(); + m_parser->setBookmark(m_end_bookmark); + if (RetraceRender::changesContext(*call)) { + m_parser->setBookmark(m_end_bookmark); + delete call; + break; + } + + const int new_render_buffer = RetraceRender::currentRenderBuffer(); + + // consider refactoring context to be a container of rt regions + if (new_render_buffer != current_render_buffer) { + if (m_renders.size() > 1) // don't record the very first draw as + // ending a render target + end_render_target_regions.push_back(RenderId(m_renders.size() - 1)); + current_render_buffer = new_render_buffer; + } + } +} + +int +RetraceContext::getRenderCount() const { + return m_renders.size(); +} + +bool isFirstRender(RenderId id, const RenderSelection &s) { + return id == s.series.front().begin; +} + +RenderId lastRender(const RenderSelection &s) { + return RenderId(s.series.back().end() - 1); +} + + +bool isSelected(RenderId id, const RenderSelection &s) { + for (auto seq : s.series) { + if (id >= seq.end) + continue; + if (id < seq.begin) + return false; + return true; + } + return false; +} + +RenderId +RetraceContext::lastRenderForRTRegion(RenderId render) const { + for (auto rt_render : end_render_target_regions) + if (rt_render > render) + return RenderId(rt_render() - 1); + // last render for the context is the final render for the last + // region. + return m_renders.rbegin()->first; +} + +void +RetraceContext::retraceRenderTarget(ExperimentId experimentCount, + const RenderSelection &selection, + RenderTargetType type, + RenderOptions options, + const StateTrack &tracker, + OnFrameRetrace *callback) const { + auto current_render = m_renders.begin(); + // play up to the beginning of the first render + while (current_render->first < selection.series.front().begin) { + current_render->second->retraceRenderTarget(tracker, NORMAL_RENDER); + ++current_render; + if (current_render == m_renders.end()) + // played through the context + return; + } + + // TODO(majanes) possibly should be clearing on the first selected + // render of the last selected framebuffer + if (selection.series.front().begin == current_render->first) { + // this is the first render of the selection + if ((options & glretrace::CLEAR_BEFORE_RENDER)) { + GlFunctions::Clear(GL_COLOR_BUFFER_BIT); + GlFunctions::Clear(GL_DEPTH_BUFFER_BIT); + GlFunctions::Clear(GL_STENCIL_BUFFER_BIT); + GlFunctions::Clear(GL_ACCUM_BUFFER_BIT); + // ignore errors from unsupported clears + GlFunctions::GetError(); + } + } + + // play through the selected renders + const RenderId last_render = lastRender(selection); + while (current_render->first < selection.series.back().end) { + RenderTargetType current_type = type; + if (!isSelected(current_render->first, selection)) + // unselected renders don't get highlighting + type = NORMAL_RENDER; + const bool is_last_render = (current_render->first == last_render); + current_render->second->retraceRenderTarget(tracker, + current_type); + ++current_render; + + if (is_last_render) + // reached end of selection + break; + if (current_render == m_renders.end()) + // played through the context + break; + } + + if ((!(options & glretrace::STOP_AT_RENDER)) && + (current_render != m_renders.end())) { + // play through to the end of the currently attached framebuffer + RenderId last_render_in_rt_region = + lastRenderForRTRegion(last_render); + while (current_render->first <= last_render_in_rt_region) { + current_render->second->retraceRenderTarget(tracker, + NORMAL_RENDER); + ++current_render; + if (current_render == m_renders.end()) + // played through the context + break; + } + } + + // report an image if the last selected render is in this context + const bool contains_last_render = + ((last_render >= m_renders.begin()->first) && + (last_render <= m_renders.rbegin()->first)); + if (contains_last_render) { + Image *i = glstate::getDrawBufferImage(0); + if (!i) { + GRLOG(WARN, "Failed to obtain draw buffer image for render id"); + if (callback) + callback->onError(RETRACE_WARN, "Failed to obtain draw buffer image"); + } else { + std::stringstream png; + i->writePNG(png); + + std::vector<unsigned char> d; + const int bytes = png.str().size(); + d.resize(bytes); + memcpy(d.data(), png.str().c_str(), bytes); + if (callback) + callback->onRenderTarget(selection.id, experimentCount, d); + } + } + + // play to the rest of the context + while (current_render != m_renders.end()) { + current_render->second->retraceRenderTarget(tracker, + NORMAL_RENDER); + ++current_render; + } +} + +void +RetraceContext::retraceMetrics(PerfMetrics *perf, + const StateTrack &tracker) const { + // NULL perf is passed for a warm-up round + if (m_context_switch) + m_retracer->retrace(*m_context_switch); + if (perf) + perf->beginContext(); + for (auto i : m_renders) { + if (perf) + perf->begin(i.first); + i.second->retrace(tracker); + if (perf) + perf->end(); + } + if (perf) + perf->endContext(); +} + + +class CleanPerf { + public: + CleanPerf(glretrace::PerfMetrics *perf, + bool *active) : m_perf(perf), + m_active(active) {} + ~CleanPerf() { + if (*m_active) { + m_perf->end(); + } + m_perf->endContext(); + } + private: + glretrace::PerfMetrics *m_perf; + bool *m_active; +}; + +void +RetraceContext::retraceAllMetrics(const RenderSelection &selection, + PerfMetrics *perf, + const StateTrack &tracker) const { + if (m_context_switch) + m_retracer->retrace(*m_context_switch); + perf->beginContext(); + + // iterate through the RenderSelection, and insert begin/end + // around each RenderSeries + // auto currentRenderSequence = selection.series.begin(); + auto current_render = m_renders.begin(); + bool metrics_active = false; + CleanPerf cleanup(perf, &metrics_active); + if (isSelected(current_render->first, selection)) { + // continues a selection from the previous context + perf->begin(current_render->first); + metrics_active = true; + } + + for (auto sequence : selection.series) { + if (current_render->first >= sequence.end) + // this sequence ended before our context begins + continue; + + while (current_render->first < sequence.begin) { + current_render->second->retrace(tracker); + ++current_render; + if (current_render == m_renders.end()) + return; + } + + if ((current_render->first == sequence.begin) && (!metrics_active)) { + perf->begin(current_render->first); + metrics_active = true; + } + + while (current_render->first < sequence.end) { + current_render->second->retrace(tracker); + ++current_render; + if (current_render == m_renders.end()) + return; + } + + if (sequence.end == current_render->first) { + assert(metrics_active); + metrics_active = false; + perf->end(); + } + } + + // CleanPerf destructor will end context +} + +bool +RetraceContext::endsFrame() const { + return m_ends_frame; +} + +bool +RetraceContext::replaceShaders(RenderId renderId, + ExperimentId experimentCount, + StateTrack *tracker, + const std::string &vs, + const std::string &fs, + const std::string &tessControl, + const std::string &tessEval, + const std::string &geom, + const std::string &comp, + OnFrameRetrace *callback) { + auto r = m_renders.find(renderId); + if (r == m_renders.end()) + return true; + std::string message; + const bool result = r->second->replaceShaders(tracker, + vs, fs, + tessControl, + tessEval, + geom, + comp, + &message); + if (!result) + GRLOGF(WARN, "compile failed: %s", message.c_str()); + callback->onShaderCompile(renderId, experimentCount, + result, message); + return result; +} + +void +RetraceContext::retraceApi(const RenderSelection &selection, + OnFrameRetrace *callback) { + if (selection.series.empty()) { + // empty selection: display the full api log + for (auto r : m_renders) + r.second->onApi(selection.id, r.first, callback); + return; + } + for (auto sequence : selection.series) { + auto currentRender = sequence.begin; + while (currentRender < sequence.end) { + auto r = m_renders.find(currentRender); + if (r != m_renders.end()) + r->second->onApi(selection.id, + currentRender, + callback); + ++currentRender; + } + } +} + + +void +RetraceContext::retraceShaderAssembly(const RenderSelection &selection, + StateTrack *tracker, + OnFrameRetrace *callback) { + trace::ParseBookmark bm; + m_parser->getBookmark(bm); + assert(bm.offset == m_start_bookmark.offset); + + for (auto r : m_renders) { + r.second->retrace(tracker); + if (isSelected(r.first, selection)) { + callback->onShaderAssembly(r.first, + selection.id, + tracker->currentVertexShader(), + tracker->currentFragmentShader(), + tracker->currentTessControlShader(), + tracker->currentTessEvalShader(), + tracker->currentGeomShader(), + tracker->currentCompShader()); + } + } +} diff --git a/retrace/daemon/glframe_retrace_context.hpp b/retrace/daemon/glframe_retrace_context.hpp new file mode 100644 index 00000000..b5c056c0 --- /dev/null +++ b/retrace/daemon/glframe_retrace_context.hpp @@ -0,0 +1,108 @@ +/************************************************************************** + * + * Copyright 2017 Intel Corporation + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * Authors: + * Mark Janes <mark.a.janes@intel.com> + **************************************************************************/ + +#ifndef _GLFRAME_RETRACE_CONTEXT_HPP_ +#define _GLFRAME_RETRACE_CONTEXT_HPP_ + +#include <map> +#include <string> +#include <vector> + +#include "glframe_retrace_interface.hpp" +#include "glframe_retrace.hpp" +#include "trace_parser.hpp" + +namespace trace { +class AbstractParser; +class Call; +} +namespace retrace { +class Retracer; +} + +namespace glretrace { + +struct Context; + +class StateTrack; +class OnFrameRetrace; +class ExperimentId; +class MetricId; +class PerfMetrics; +class RetraceRender; + +class RetraceContext { + public: + RetraceContext(RenderId current_render, + trace::AbstractParser *parser, + retrace::Retracer *retracer, + StateTrack *tracker); + void retraceRenderTarget(ExperimentId experimentCount, + const RenderSelection &selection, + RenderTargetType type, + RenderOptions options, + const StateTrack &tracker, + OnFrameRetrace *callback) const; + void retraceMetrics(PerfMetrics *perf, const StateTrack &tracker) const; + void retraceAllMetrics(const RenderSelection &selection, + PerfMetrics *perf, + const StateTrack &tracker) const; + bool endsFrame() const; + bool replaceShaders(RenderId renderId, + ExperimentId experimentCount, + StateTrack *tracker, + const std::string &vs, + const std::string &fs, + const std::string &tessControl, + const std::string &tessEval, + const std::string &geom, + const std::string &comp, + OnFrameRetrace *callback); + void retraceApi(const RenderSelection &selection, + OnFrameRetrace *callback); + void retraceShaderAssembly(const RenderSelection &selection, + StateTrack *tracker, + OnFrameRetrace *callback); + int getRenderCount() const; + + private: + trace::AbstractParser *m_parser; + retrace::Retracer *m_retracer; + trace::ParseBookmark m_start_bookmark, m_end_bookmark; + trace::Call *m_context_switch; + RenderBookmark m_context_start; + std::map<RenderId, RetraceRender*> m_renders; + std::vector<RenderId> end_render_target_regions; + bool m_ends_frame; + + RenderId lastRenderForRTRegion(RenderId render) const; +}; + +} // namespace glretrace + +#endif // _GLFRAME_RETRACE_CONTEXT_HPP_ + diff --git a/retrace/daemon/glframe_retrace_interface.hpp b/retrace/daemon/glframe_retrace_interface.hpp index 5ef4e2d5..0a20dc09 100644 --- a/retrace/daemon/glframe_retrace_interface.hpp +++ b/retrace/daemon/glframe_retrace_interface.hpp @@ -90,6 +90,8 @@ class RenderId { uint32_t index() const { return value & (~ID_PREFIX_MASK); } bool operator<(const RenderId &o) const { return value < o.value; } bool operator>(const RenderId &o) const { return value > o.value; } + bool operator>=(const RenderId &o) const { return value >= o.value; } + bool operator<=(const RenderId &o) const { return value <= o.value; } bool operator==(const RenderId &o) const { return value == o.value; } private: uint32_t value; @@ -114,6 +116,7 @@ class MetricId { uint32_t counter() const { return (value & 0x0FFFF); } bool operator<(const MetricId &o) const { return value < o.value; } bool operator==(const MetricId &o) const { return value == o.value; } + bool operator!=(const MetricId &o) const { return value != o.value; } private: // low 16 bits are the counter number // middle 32 bits are the group diff --git a/retrace/daemon/glframe_retrace_render.cpp b/retrace/daemon/glframe_retrace_render.cpp index a9435cd4..7420eb12 100644 --- a/retrace/daemon/glframe_retrace_render.cpp +++ b/retrace/daemon/glframe_retrace_render.cpp @@ -33,12 +33,15 @@ #include "glframe_glhelper.hpp" #include "glframe_logger.hpp" +#include "glframe_metrics.hpp" #include "glframe_state.hpp" #include "retrace.hpp" +#include "glstate_internal.hpp" #include "trace_parser.hpp" using glretrace::DEBUG; using glretrace::GlFunctions; +using glretrace::PerfMetrics; using glretrace::RetraceRender; using glretrace::SelectionId; using glretrace::StateTrack; @@ -46,29 +49,39 @@ using glretrace::RenderTargetType; using glretrace::RenderId; using glretrace::OnFrameRetrace; -bool changesContext(const trace::Call * const call) { - if (strncmp(call->name(), "glXMakeCurrent", strlen("glXMakeCurrent")) == 0) - return true; - return false; -} - static const std::string simple_fs = "void main(void) {\n" " gl_FragColor = vec4(1,0,1,1);\n" "}"; bool -RetraceRender::isRender(const trace::Call &call) { - return (call.flags & trace::CALL_FLAG_RENDER) || - (strcmp("glDispatchCompute", call.name()) == 0) || - (strcmp("glDispatchComputeIndirect", - call.name()) == 0); +isCompute(const trace::Call &call) { + return ((strcmp("glDispatchCompute", call.name()) == 0) || + (strcmp("glDispatchComputeIndirect", + call.name()) == 0)); } bool -isCompute(const trace::Call &call) { - return (RetraceRender::isRender(call) && - (!(call.flags & trace::CALL_FLAG_RENDER))); +RetraceRender::changesContext(const trace::Call &call) { + if (strncmp(call.name(), "glXMakeCurrent", strlen("glXMakeCurrent")) == 0) + return true; + return false; +} + +bool +RetraceRender::isRender(const trace::Call &call) { + return ((call.flags & trace::CALL_FLAG_RENDER) || isCompute(call)); +} + +int +RetraceRender::currentRenderBuffer() { + glstate::Context context; + const GLenum framebuffer_binding = context.ES ? + GL_FRAMEBUFFER_BINDING : + GL_DRAW_FRAMEBUFFER_BINDING; + GLint draw_framebuffer = 0; + GlFunctions::GetIntegerv(framebuffer_binding, &draw_framebuffer); + return draw_framebuffer; } RetraceRender::RetraceRender(trace::AbstractParser *parser, @@ -78,29 +91,39 @@ RetraceRender::RetraceRender(trace::AbstractParser *parser, m_rt_program(-1), m_retrace_program(-1), m_end_of_frame(false), - m_highlight_rt(false) { + m_highlight_rt(false), + m_changes_context(false) { m_parser->getBookmark(m_bookmark.start); trace::Call *call = NULL; std::stringstream call_stream; bool compute = false; + trace::ParseBookmark call_start; while ((call = parser->parse_call())) { - trace::dump(*call, call_stream, - trace::DUMP_FLAG_NO_COLOR); - m_api_calls.push_back(call_stream.str()); - call_stream.str(""); - tracker->flush(); m_retracer->retrace(*call); tracker->track(*call); m_end_of_frame = call->flags & trace::CALL_FLAG_END_FRAME; const bool render = isRender(*call); compute = isCompute(*call); - assert(!changesContext(call)); + if (changesContext(*call)) { + m_changes_context = true; + if (m_api_calls.size() > 0) { + // this ought to be in the next context + m_parser->setBookmark(call_start); + delete call; + break; + } + } + trace::dump(*call, call_stream, + trace::DUMP_FLAG_NO_COLOR); + m_api_calls.push_back(call_stream.str()); + call_stream.str(""); delete call; ++(m_bookmark.numberOfCalls); if (render || m_end_of_frame) break; + m_parser->getBookmark(call_start); } m_original_program = tracker->CurrentProgram(); m_original_vs = tracker->currentVertexShader().shader; @@ -138,7 +161,7 @@ RetraceRender::retraceRenderTarget(const StateTrack &tracker, assert(bm.offset == m_bookmark.start.offset); // play up to but not past the end of the render - for (uint calls = 0; calls < m_bookmark.numberOfCalls - 1; ++calls) { + for (unsigned int calls = 0; calls < m_bookmark.numberOfCalls - 1; ++calls) { trace::Call *call = m_parser->parse_call(); assert(call); tracker.retraceProgramSideEffects(m_original_program, call, m_retracer); @@ -187,7 +210,7 @@ RetraceRender::retrace(StateTrack *tracker) const { tracker->flush(); // play up to but not past the end of the render - for (uint calls = 0; calls < m_bookmark.numberOfCalls - 1; ++calls) { + for (unsigned int calls = 0; calls < m_bookmark.numberOfCalls - 1; ++calls) { trace::Call *call = m_parser->parse_call(); assert(call); @@ -225,12 +248,14 @@ RetraceRender::retrace(const StateTrack &tracker) const { assert(bm.offset == m_bookmark.start.offset); // play up to but not past the end of the render - for (uint calls = 0; calls < m_bookmark.numberOfCalls - 1; ++calls) { + for (unsigned int calls = 0; calls < m_bookmark.numberOfCalls - 1; ++calls) { trace::Call *call = m_parser->parse_call(); assert(call); tracker.retraceProgramSideEffects(m_original_program, call, m_retracer); + // context change must be on the first call of the render + assert((!changesContext(*call)) || calls == 0); m_retracer->retrace(*call); delete(call); diff --git a/retrace/daemon/glframe_retrace_render.hpp b/retrace/daemon/glframe_retrace_render.hpp index 64908487..a553c678 100644 --- a/retrace/daemon/glframe_retrace_render.hpp +++ b/retrace/daemon/glframe_retrace_render.hpp @@ -47,6 +47,7 @@ class StateTrack; class OnFrameRetrace; class ExperimentId; class MetricId; +class PerfMetrics; class RetraceRender { public: @@ -75,6 +76,8 @@ class RetraceRender { RenderId renderId, OnFrameRetrace *callback); static bool isRender(const trace::Call &c); + static bool changesContext(const trace::Call &c); + static int currentRenderBuffer(); private: trace::AbstractParser *m_parser; @@ -88,7 +91,7 @@ class RetraceRender { m_modified_tess_eval, m_modified_tess_control, m_modified_geom, m_modified_comp; int m_rt_program, m_retrace_program, m_original_program; - bool m_end_of_frame, m_highlight_rt; + bool m_end_of_frame, m_highlight_rt, m_changes_context; std::vector<std::string> m_api_calls; }; diff --git a/retrace/daemon/glframe_state.cpp b/retrace/daemon/glframe_state.cpp index 49975878..44ee0f99 100644 --- a/retrace/daemon/glframe_state.cpp +++ b/retrace/daemon/glframe_state.cpp @@ -61,7 +61,6 @@ StateTrack::TrackMap StateTrack::lookup; StateTrack::StateTrack(OutputPoller *p) : m_poller(p), current_program(0), - current_context(0), empty_shader() { } @@ -90,20 +89,6 @@ StateTrack::TrackMap::track(StateTrack *tracker, const Call &call) { return true; } -bool -changesContext(const trace::Call &call) { - if (strncmp(call.name(), "glXMakeCurrent", strlen("glXMakeCurrent")) == 0) - return true; - return false; -} - -uint64_t -getContext(const trace::Call &call) { - assert(changesContext(call)); - // there ought to be a const variant for this - return const_cast<trace::Call &>(call).arg(2).toUIntPtr(); -} - // TODO(majanes): use a lookup table void StateTrack::track(const Call &call) { @@ -118,9 +103,6 @@ StateTrack::track(const Call &call) { #endif } - if (changesContext(call)) - current_context = getContext(call); - #ifndef WIN32 // on Linux we can parse for shader assembly data on every call. parse(); diff --git a/retrace/daemon/glframe_state.hpp b/retrace/daemon/glframe_state.hpp index f32159e2..52a73aa8 100644 --- a/retrace/daemon/glframe_state.hpp +++ b/retrace/daemon/glframe_state.hpp @@ -98,7 +98,6 @@ class StateTrack { const ShaderAssembly ¤tGeomShader() const; const ShaderAssembly ¤tCompShader() const; void onAssembly(ShaderType st, AssemblyType at, const std::string &assembly); - uint64_t currentContext() const { return current_context; } int useProgram(int orig_program, const std::string &vs, const std::string &fs, const std::string &tessControl, const std::string &tessEval, @@ -147,7 +146,6 @@ class StateTrack { OutputPoller *m_poller; int current_program; - uint64_t current_context; std::map<int, std::string> shader_to_source; std::map<int, int> shader_to_type; std::map<std::string, int> source_to_shader; diff --git a/retrace/daemon/test/retrace_metrics_test.cpp b/retrace/daemon/test/retrace_metrics_test.cpp index 22aa4c25..9eb41d81 100644 --- a/retrace/daemon/test/retrace_metrics_test.cpp +++ b/retrace/daemon/test/retrace_metrics_test.cpp @@ -117,10 +117,10 @@ TEST_F(RetraceTest, SingleMetricData) { FrameRetrace rt; rt.openFile(test_file, md5, fileSize, 7, &cb); - p.begin(RenderId(1)); + p.begin(RenderId(0)); RenderSelection s; s.id = SelectionId(0); - s.series.push_back(RenderSequence(RenderId(1), RenderId(2))); + s.series.push_back(RenderSequence(RenderId(0), RenderId(1))); rt.retraceRenderTarget(ExperimentId(0), s, glretrace::NORMAL_RENDER, glretrace::STOP_AT_RENDER, &cb); diff --git a/retrace/daemon/ui/main.cpp b/retrace/daemon/ui/main.cpp index 0c8be714..84dd572b 100644 --- a/retrace/daemon/ui/main.cpp +++ b/retrace/daemon/ui/main.cpp @@ -77,7 +77,7 @@ int main(int argc, char *argv[]) { GlFunctions::Init(); Logger::Create(); - Logger::SetSeverity(glretrace::WARN); + Logger::SetSeverity(glretrace::DEBUG); Socket::Init(); Logger::Begin(); diff --git a/retrace/retrace_swizzle.cpp b/retrace/retrace_swizzle.cpp index c308334d..e6d0696b 100644 --- a/retrace/retrace_swizzle.cpp +++ b/retrace/retrace_swizzle.cpp @@ -122,7 +122,7 @@ addRegion(trace::Call &call, unsigned long long address, void *buffer, unsigned #ifdef NDEBUG false #else - true + false #endif ; if (debug) { |