diff options
author | Mark Janes <mark.a.janes@intel.com> | 2017-08-31 08:51:08 -0700 |
---|---|---|
committer | Mark Janes <mark.a.janes@intel.com> | 2017-11-26 19:00:11 -0800 |
commit | 3f22204a81662d225bf997ca66d28d8036373142 (patch) | |
tree | d28dd4d96dbf03be4b281bf2713292ff9770e987 /retrace | |
parent | 84ce12907199d0a7eb581b06de1d47e716fbd68b (diff) |
State: Initial implementation for retracing GL state
Allows cull state to be retraced, as a first step.
Diffstat (limited to 'retrace')
-rw-r--r-- | retrace/daemon/glframe_retrace.cpp | 10 | ||||
-rw-r--r-- | retrace/daemon/glframe_retrace.hpp | 3 | ||||
-rw-r--r-- | retrace/daemon/glframe_retrace_context.cpp | 12 | ||||
-rw-r--r-- | retrace/daemon/glframe_retrace_context.hpp | 4 | ||||
-rw-r--r-- | retrace/daemon/glframe_retrace_interface.hpp | 20 | ||||
-rw-r--r-- | retrace/daemon/glframe_retrace_render.cpp | 43 | ||||
-rw-r--r-- | retrace/daemon/glframe_retrace_render.hpp | 4 | ||||
-rw-r--r-- | retrace/daemon/glframe_retrace_skeleton.cpp | 40 | ||||
-rw-r--r-- | retrace/daemon/glframe_retrace_skeleton.hpp | 5 | ||||
-rw-r--r-- | retrace/daemon/glframe_retrace_stub.cpp | 99 | ||||
-rw-r--r-- | retrace/daemon/glframe_retrace_stub.hpp | 3 | ||||
-rw-r--r-- | retrace/daemon/playback.proto | 32 | ||||
-rw-r--r-- | retrace/daemon/ui/glframe_metrics_model.hpp | 6 | ||||
-rw-r--r-- | retrace/daemon/ui/glframe_retrace_model.cpp | 27 | ||||
-rw-r--r-- | retrace/daemon/ui/glframe_retrace_model.hpp | 10 |
15 files changed, 308 insertions, 10 deletions
diff --git a/retrace/daemon/glframe_retrace.cpp b/retrace/daemon/glframe_retrace.cpp index 5e04d1f3..73b00fdd 100644 --- a/retrace/daemon/glframe_retrace.cpp +++ b/retrace/daemon/glframe_retrace.cpp @@ -385,3 +385,13 @@ FrameRetrace::setUniform(const RenderSelection &selection, for (auto i : m_contexts) i->setUniform(selection, name, index, data); } + +void +FrameRetrace::retraceState(const RenderSelection &selection, + ExperimentId experimentCount, + OnFrameRetrace *callback) { + // reset to beginning of frame + parser->setBookmark(frame_start.start); + for (auto i : m_contexts) + i->retraceState(selection, experimentCount, m_tracker, callback); +} diff --git a/retrace/daemon/glframe_retrace.hpp b/retrace/daemon/glframe_retrace.hpp index c562be7f..336360a2 100644 --- a/retrace/daemon/glframe_retrace.hpp +++ b/retrace/daemon/glframe_retrace.hpp @@ -113,6 +113,9 @@ class FrameRetrace : public IFrameRetrace { const std::string &name, int index, const std::string &data); + void retraceState(const RenderSelection &selection, + ExperimentId experimentCount, + OnFrameRetrace *callback); private: // these are global diff --git a/retrace/daemon/glframe_retrace_context.cpp b/retrace/daemon/glframe_retrace_context.cpp index c5d9b255..6160858c 100644 --- a/retrace/daemon/glframe_retrace_context.cpp +++ b/retrace/daemon/glframe_retrace_context.cpp @@ -484,3 +484,15 @@ RetraceContext::setUniform(const RenderSelection &selection, if (isSelected(r.first, selection)) r.second->setUniform(name, index, data); } + +void +RetraceContext::retraceState(const RenderSelection &selection, + ExperimentId experimentCount, + const StateTrack &tracker, + OnFrameRetrace *callback) { + for (auto r : m_renders) { + r.second->retrace(tracker); + if (isSelected(r.first, selection)) + r.second->onState(selection.id, experimentCount, r.first, callback); + } +} diff --git a/retrace/daemon/glframe_retrace_context.hpp b/retrace/daemon/glframe_retrace_context.hpp index cd5d2508..bbbe7c89 100644 --- a/retrace/daemon/glframe_retrace_context.hpp +++ b/retrace/daemon/glframe_retrace_context.hpp @@ -106,6 +106,10 @@ class RetraceContext { void setUniform(const RenderSelection &selection, const std::string &name, int index, const std::string &data); + void retraceState(const RenderSelection &selection, + ExperimentId experimentCount, + const StateTrack &tracker, + OnFrameRetrace *callback); private: trace::AbstractParser *m_parser; diff --git a/retrace/daemon/glframe_retrace_interface.hpp b/retrace/daemon/glframe_retrace_interface.hpp index 4b5cf649..c1f072d2 100644 --- a/retrace/daemon/glframe_retrace_interface.hpp +++ b/retrace/daemon/glframe_retrace_interface.hpp @@ -255,6 +255,18 @@ enum UniformDimension { // Serializable asynchronous callbacks made from remote // implementations of IFrameRetrace. +enum StateItem { + CULL_FACE = 0x0B44, + CULL_FACE_MODE = 0x0B45, +}; + +struct StateKey { + StateItem name; + int index; + + StateKey(StateItem n, int i) : name(n), index(i) {} +}; + class OnFrameRetrace { public: typedef std::vector<unsigned char> uvec; @@ -298,6 +310,11 @@ class OnFrameRetrace { UniformType type, UniformDimension dimension, const std::vector<unsigned char> &data) = 0; + virtual void onState(SelectionId selectionCount, + ExperimentId experimentCount, + RenderId renderId, + StateKey item, + const std::string &value) = 0; }; // Serializable asynchronous retrace requests. @@ -353,6 +370,9 @@ class IFrameRetrace { const std::string &name, int index, const std::string &data) = 0; + virtual void retraceState(const RenderSelection &selection, + ExperimentId experimentCount, + OnFrameRetrace *callback) = 0; }; class FrameState { diff --git a/retrace/daemon/glframe_retrace_render.cpp b/retrace/daemon/glframe_retrace_render.cpp index 29915e91..4251d568 100644 --- a/retrace/daemon/glframe_retrace_render.cpp +++ b/retrace/daemon/glframe_retrace_render.cpp @@ -425,3 +425,46 @@ RetraceRender::setUniform(const std::string &name, int index, const std::string &data) { m_uniform_override->setUniform(name, index, data); } + +std::string cull_to_string(GLint cull) { + switch (cull) { + case GL_FRONT: + return std::string("GL_FRONT"); + case GL_BACK: + return std::string("GL_BACK"); + case GL_FRONT_AND_BACK: + return std::string("GL_FRONT_AND_BACK"); + default: + assert(false); + } +} + +void +RetraceRender::onState(SelectionId selId, + ExperimentId experimentCount, + RenderId renderId, + OnFrameRetrace *callback) { + { + GL::GetError(); + GLboolean cull_enabled = GlFunctions::IsEnabled(GL_CULL_FACE); + GLenum e = GL::GetError(); + if (e == GL_NO_ERROR) { + callback->onState(selId, experimentCount, renderId, + StateKey(CULL_FACE, 0), + cull_enabled ? "true" : "false"); + } + } + { + GL::GetError(); + GLint cull; + GlFunctions::GetIntegerv(GL_CULL_FACE_MODE, &cull); + GLenum e = GL::GetError(); + if (e == GL_NO_ERROR) { + const std::string cull_str = cull_to_string(cull); + if (cull_str.size() > 0) { + callback->onState(selId, experimentCount, renderId, + StateKey(CULL_FACE_MODE, 0), cull_str); + } + } + } +} diff --git a/retrace/daemon/glframe_retrace_render.hpp b/retrace/daemon/glframe_retrace_render.hpp index 788f1d6e..7fd2066a 100644 --- a/retrace/daemon/glframe_retrace_render.hpp +++ b/retrace/daemon/glframe_retrace_render.hpp @@ -88,6 +88,10 @@ class RetraceRender { OnFrameRetrace *callback); void setUniform(const std::string &name, int index, const std::string &data); + void onState(SelectionId selId, + ExperimentId experimentCount, + RenderId renderId, + OnFrameRetrace *callback); static bool isRender(const trace::Call &c); static bool changesContext(const trace::Call &c); static bool endsFrame(const trace::Call &c); diff --git a/retrace/daemon/glframe_retrace_skeleton.cpp b/retrace/daemon/glframe_retrace_skeleton.cpp index 23b2b588..46334f49 100644 --- a/retrace/daemon/glframe_retrace_skeleton.cpp +++ b/retrace/daemon/glframe_retrace_skeleton.cpp @@ -385,6 +385,28 @@ FrameRetraceSkeleton::Run() { set_uniform.data()); break; } + case ApiTrace::STATE_REQUEST: + { + assert(request.has_state()); + auto state = request.state(); + RenderSelection selection; + makeRenderSelection(state.selection(), &selection); + m_frame->retraceState(selection, + ExperimentId(state.experiment_count()), + this); + // send empty message to signal the last response + RetraceResponse proto_response; + auto state_resp = proto_response.mutable_state(); + state_resp->set_selection_count(-1); + state_resp->set_render_id(-1); + state_resp->set_experiment_count(-1); + state_resp->set_value(""); + auto r_item = state_resp->mutable_item(); + r_item->set_name(ApiTrace::StateItem(ApiTrace::INVALID_STATE_ITEM)); + r_item->set_index(0); + writeResponse(m_socket, proto_response, &m_buf); + break; + } } } } @@ -602,3 +624,21 @@ FrameRetraceSkeleton::onUniform(SelectionId selectionCount, response->set_data(data.data(), data.size()); writeResponse(m_socket, proto_response, &m_buf); } + +void +FrameRetraceSkeleton::onState(SelectionId selectionCount, + ExperimentId experimentCount, + RenderId renderId, + StateKey item, + const std::string &value) { + RetraceResponse proto_response; + auto response = proto_response.mutable_state(); + response->set_render_id(renderId()); + response->set_selection_count(selectionCount()); + response->set_experiment_count(experimentCount.count()); + auto r_item = response->mutable_item(); + r_item->set_name(ApiTrace::StateItem(item.name)); + r_item->set_index(item.index); + response->set_value(value); + writeResponse(m_socket, proto_response, &m_buf); +} diff --git a/retrace/daemon/glframe_retrace_skeleton.hpp b/retrace/daemon/glframe_retrace_skeleton.hpp index 65665dfa..5f5cfe62 100644 --- a/retrace/daemon/glframe_retrace_skeleton.hpp +++ b/retrace/daemon/glframe_retrace_skeleton.hpp @@ -96,6 +96,11 @@ class FrameRetraceSkeleton : public Thread, UniformType type, UniformDimension dimension, const std::vector<unsigned char> &data); + virtual void onState(SelectionId selectionCount, + ExperimentId experimentCount, + RenderId renderId, + StateKey item, + const std::string &value); protected: bool m_force_upload; // for unit test diff --git a/retrace/daemon/glframe_retrace_stub.cpp b/retrace/daemon/glframe_retrace_stub.cpp index 419f2dc4..968afc37 100644 --- a/retrace/daemon/glframe_retrace_stub.cpp +++ b/retrace/daemon/glframe_retrace_stub.cpp @@ -765,10 +765,10 @@ class BatchRequest : public IRetraceRequest { class UniformRequest : public IRetraceRequest { public: UniformRequest(SelectionId *current_selection, - ExperimentId *current_experiment, - std::mutex *protect, - const RenderSelection &selection, - OnFrameRetrace *cb) + ExperimentId *current_experiment, + std::mutex *protect, + const RenderSelection &selection, + OnFrameRetrace *cb) : m_sel_count(current_selection), m_exp_count(current_experiment), m_protect(protect), @@ -932,6 +932,81 @@ class SetUniformRequest : public IRetraceRequest { RetraceRequest m_proto_msg; }; +class StateRequest : public IRetraceRequest { + public: + StateRequest(SelectionId *current_selection, + ExperimentId *current_experiment, + std::mutex *protect, + const RenderSelection &selection, + OnFrameRetrace *cb) + : m_sel_count(current_selection), + m_exp_count(current_experiment), + m_protect(protect), + m_callback(cb) { + auto stateRequest = m_proto_msg.mutable_state(); + auto selectionRequest = stateRequest->mutable_selection(); + makeRenderSelection(selection, selectionRequest); + stateRequest->set_experiment_count((*current_experiment)()); + m_proto_msg.set_requesttype(ApiTrace::STATE_REQUEST); + } + virtual void retrace(RetraceSocket *s) { + { + std::lock_guard<std::mutex> l(*m_protect); + const auto &sel = m_proto_msg.state().selection(); + const SelectionId id(sel.selection_count()); + if (*m_sel_count != id) + // more recent selection was made while this was enqueued + return; + const ExperimentId eid(m_proto_msg.state().experiment_count()); + if (*m_exp_count != eid) + // more recent experiment was made while this was enqueued + return; + } + RetraceResponse response; + // sends single request, read multiple responses + s->request(m_proto_msg); + while (true) { + response.Clear(); + s->response(&response); + assert(response.has_state()); + const auto &state_response = response.state(); + if (state_response.render_id() == (unsigned int)-1) + // all responses sent + break; + + const auto selection = SelectionId(state_response.selection_count()); + { + std::lock_guard<std::mutex> l(*m_protect); + if (*m_sel_count != selection) + // more recent selection was made while retrace was being + // executed. + continue; + } + const auto experiment = ExperimentId(state_response.experiment_count()); + { + std::lock_guard<std::mutex> l(*m_protect); + if (*m_exp_count != experiment) + // more recent selection was made while retrace was being + // executed. + continue; + } + const RenderId rid(state_response.render_id()); + glretrace::StateKey k((glretrace::StateItem)state_response.item().name(), + state_response.item().index()); + + m_callback->onState(selection, experiment, rid, + k, state_response.value()); + } + } + + private: + const SelectionId * const m_sel_count; + const ExperimentId * const m_exp_count; + std::mutex *m_protect; + RetraceRequest m_proto_msg; + OnFrameRetrace *m_callback; +}; + class NullRequest : public IRetraceRequest { public: // to pump the thread, and force it to stop @@ -1192,3 +1267,19 @@ FrameRetraceStub::setUniform(const RenderSelection &selection, } m_thread->push(new SetUniformRequest(selection, name, index, data)); } + +void +FrameRetraceStub::retraceState(const RenderSelection &selection, + ExperimentId experimentCount, + OnFrameRetrace *callback) { + { + std::lock_guard<std::mutex> l(m_mutex); + m_current_render_selection = selection.id; + assert(m_current_experiment <= experimentCount); + m_current_experiment = experimentCount; + } + m_thread->push(new StateRequest(&m_current_render_selection, + &m_current_experiment, + &m_mutex, + selection, callback)); +} diff --git a/retrace/daemon/glframe_retrace_stub.hpp b/retrace/daemon/glframe_retrace_stub.hpp index 4514c774..ac34f771 100644 --- a/retrace/daemon/glframe_retrace_stub.hpp +++ b/retrace/daemon/glframe_retrace_stub.hpp @@ -93,6 +93,9 @@ class FrameRetraceStub : public IFrameRetrace { const std::string &name, int index, const std::string &data); + virtual void retraceState(const RenderSelection &selection, + ExperimentId experimentCount, + OnFrameRetrace *callback); private: mutable std::mutex m_mutex; diff --git a/retrace/daemon/playback.proto b/retrace/daemon/playback.proto index 93242b1e..a0369af0 100644 --- a/retrace/daemon/playback.proto +++ b/retrace/daemon/playback.proto @@ -19,6 +19,7 @@ enum RequestType { SIMPLE_SHADER_REQUEST = 10; UNIFORM_REQUEST = 11; SET_UNIFORM_REQUEST = 12; + STATE_REQUEST = 13; }; message OpenFileRequest { @@ -157,11 +158,6 @@ message ErrorResponse { required string message = 2; } -enum BatchRequestType { - BATCH = 0; - UNIFORM = 1; -} - message BatchRequest { required RenderSelection selection = 2; required uint32 experiment_count = 3; @@ -229,6 +225,30 @@ message SimpleRequest { required bool simple_shader = 2; } +message StateRequest { + required RenderSelection selection = 1; + required uint32 experiment_count = 2; +} + +enum StateItem { + CULL_FACE = 0x0B44; + CULL_FACE_MODE = 0x0B45; + INVALID_STATE_ITEM = 0x0; +} + +message StateKey { + required StateItem name = 1; + required uint32 index = 2; +} + +message StateResponse { + required uint32 selection_count = 1; + required uint32 render_id = 2; + required uint32 experiment_count = 3; + required StateKey item = 4; + required string value = 5; +} + message RetraceRequest { required RequestType requestType = 1; optional RenderTargetRequest renderTarget = 2; @@ -243,6 +263,7 @@ message RetraceRequest { optional SimpleRequest simpleShader = 11; optional UniformRequest uniform = 12; optional SetUniformRequest set_uniform = 13; + optional StateRequest state = 14; } message RetraceResponse { @@ -256,4 +277,5 @@ message RetraceResponse { optional ErrorResponse error = 8; optional BatchResponse batch = 9; optional UniformResponse uniform = 10; + optional StateResponse state = 11; } diff --git a/retrace/daemon/ui/glframe_metrics_model.hpp b/retrace/daemon/ui/glframe_metrics_model.hpp index bf931cbd..f3078d86 100644 --- a/retrace/daemon/ui/glframe_metrics_model.hpp +++ b/retrace/daemon/ui/glframe_metrics_model.hpp @@ -131,6 +131,12 @@ class QMetricsModel : public QObject, OnFrameRetrace, UniformType type, UniformDimension dimension, const std::vector<unsigned char> &data) { assert(false); } + void onState(SelectionId selectionCount, + ExperimentId experimentCount, + RenderId renderId, + StateKey item, + const std::string &value) { assert(false); } + void filter(const QString& f); QQmlListProperty<QMetricValue> metrics(); diff --git a/retrace/daemon/ui/glframe_retrace_model.cpp b/retrace/daemon/ui/glframe_retrace_model.cpp index 48841e34..7da82b3c 100644 --- a/retrace/daemon/ui/glframe_retrace_model.cpp +++ b/retrace/daemon/ui/glframe_retrace_model.cpp @@ -435,6 +435,8 @@ FrameRetraceModel::onSelect(SelectionId id, QList<int> selection) { retrace_uniforms(); if (m_current_tab == kMetrics) m_metrics_table.onSelect(id, selection); + if (m_current_tab == kState) + retrace_state(); // refresh other tabs if (m_current_tab != kRenderTarget) @@ -449,6 +451,8 @@ FrameRetraceModel::onSelect(SelectionId id, QList<int> selection) { retrace_uniforms(); if (m_current_tab != kMetrics) m_metrics_table.onSelect(id, selection); + if (m_current_tab != kState) + retrace_state(); } void @@ -564,6 +568,8 @@ FrameRetraceModel::onExperiment(ExperimentId experiment_count) { retrace_uniforms(); if (m_current_tab == kMetrics) m_metrics_table.onExperiment(experiment_count); + if (m_current_tab == kState) + retrace_state(); // refresh the rest of the tabs if (m_current_tab != kRenderTarget) @@ -576,6 +582,8 @@ FrameRetraceModel::onExperiment(ExperimentId experiment_count) { retrace_uniforms(); if (m_current_tab != kMetrics) m_metrics_table.onExperiment(experiment_count); + if (m_current_tab != kState) + retrace_state(); } void @@ -604,3 +612,22 @@ void FrameRetraceModel::setTab(const int index) { m_current_tab = static_cast<TabIndex>(index); } + + +void +FrameRetraceModel::onState(SelectionId selectionCount, + ExperimentId experimentCount, + RenderId renderId, + StateKey item, + const std::string &value) { + std::cout << value << "\n"; +} + +void +FrameRetraceModel::retrace_state() { + RenderSelection sel; + glretrace::renderSelectionFromList(m_selection_count, + m_cached_selection, + &sel); + m_retrace.retraceState(sel, m_experiment_count, this); +} diff --git a/retrace/daemon/ui/glframe_retrace_model.hpp b/retrace/daemon/ui/glframe_retrace_model.hpp index 099b094f..5d485f6b 100644 --- a/retrace/daemon/ui/glframe_retrace_model.hpp +++ b/retrace/daemon/ui/glframe_retrace_model.hpp @@ -180,6 +180,12 @@ class FrameRetraceModel : public QObject, UniformType type, UniformDimension dimension, const std::vector<unsigned char> &data); + void onState(SelectionId selectionCount, + ExperimentId experimentCount, + RenderId renderId, + StateKey item, + const std::string &value); + int frameCount() const { ScopedLock s(m_protect); return m_frame_count; } float maxMetric() const { ScopedLock s(m_protect); return m_max_metric; } QString apiCalls(); @@ -223,6 +229,7 @@ class FrameRetraceModel : public QObject, void retrace_api(); void retrace_batch(); void retrace_uniforms(); + void retrace_state(); void refreshBarMetrics(); enum TabIndex { @@ -232,7 +239,8 @@ class FrameRetraceModel : public QObject, kBatch, kMetrics, kExperiments, - kUniforms + kUniforms, + kState }; mutable std::mutex m_protect; |