summaryrefslogtreecommitdiff
path: root/retrace
diff options
context:
space:
mode:
authorMark Janes <mark.a.janes@intel.com>2017-08-31 08:51:08 -0700
committerMark Janes <mark.a.janes@intel.com>2017-11-26 19:00:11 -0800
commit3f22204a81662d225bf997ca66d28d8036373142 (patch)
treed28dd4d96dbf03be4b281bf2713292ff9770e987 /retrace
parent84ce12907199d0a7eb581b06de1d47e716fbd68b (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.cpp10
-rw-r--r--retrace/daemon/glframe_retrace.hpp3
-rw-r--r--retrace/daemon/glframe_retrace_context.cpp12
-rw-r--r--retrace/daemon/glframe_retrace_context.hpp4
-rw-r--r--retrace/daemon/glframe_retrace_interface.hpp20
-rw-r--r--retrace/daemon/glframe_retrace_render.cpp43
-rw-r--r--retrace/daemon/glframe_retrace_render.hpp4
-rw-r--r--retrace/daemon/glframe_retrace_skeleton.cpp40
-rw-r--r--retrace/daemon/glframe_retrace_skeleton.hpp5
-rw-r--r--retrace/daemon/glframe_retrace_stub.cpp99
-rw-r--r--retrace/daemon/glframe_retrace_stub.hpp3
-rw-r--r--retrace/daemon/playback.proto32
-rw-r--r--retrace/daemon/ui/glframe_metrics_model.hpp6
-rw-r--r--retrace/daemon/ui/glframe_retrace_model.cpp27
-rw-r--r--retrace/daemon/ui/glframe_retrace_model.hpp10
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;