summaryrefslogtreecommitdiff
path: root/retrace
diff options
context:
space:
mode:
authorMark Janes <mark.a.janes@intel.com>2017-11-21 12:11:38 -0800
committerMark Janes <mark.a.janes@intel.com>2017-11-27 11:29:21 -0800
commitf6f5d7efe8ad982262d7fdb564d7c0dcc996186f (patch)
treec2dbf31c896a034cc91862d606990caaa3495511 /retrace
parent718cdc66dd273fc1ccad765d378cdbccc8da1f65 (diff)
State: Enable glColorMask
The color mask state is odd because it sets state for colors (red/blue/green/alpha) which is not a float value. To work around this mismatch of our data model, the values are split into different state settings in the UI that resolve to a single GL call. This is the first state setting that is in a nested directory.
Diffstat (limited to 'retrace')
-rw-r--r--retrace/daemon/gldispatch/glframe_glhelper.cpp13
-rw-r--r--retrace/daemon/gldispatch/glframe_glhelper.hpp2
-rw-r--r--retrace/daemon/glframe_retrace_render.cpp7
-rw-r--r--retrace/daemon/glframe_state_enums.cpp4
-rw-r--r--retrace/daemon/glframe_state_override.cpp174
-rw-r--r--retrace/daemon/glframe_state_override.hpp15
-rw-r--r--retrace/daemon/ui/glframe_state_model.cpp7
7 files changed, 179 insertions, 43 deletions
diff --git a/retrace/daemon/gldispatch/glframe_glhelper.cpp b/retrace/daemon/gldispatch/glframe_glhelper.cpp
index 501d0942..a326aebb 100644
--- a/retrace/daemon/gldispatch/glframe_glhelper.cpp
+++ b/retrace/daemon/gldispatch/glframe_glhelper.cpp
@@ -122,7 +122,7 @@ static void *pUniformMatrix4x3fv = NULL;
static void *pFinish = NULL;
static void *pCullFace = NULL;
static void *pLineWidth = NULL;
-
+static void *pColorMask = NULL;
} // namespace
static void * _GetProcAddress(const char *name) {
@@ -336,6 +336,8 @@ GlFunctions::Init(void *lookup_fn) {
assert(pCullFace);
pLineWidth = _GetProcAddress("glLineWidth");
assert(pLineWidth);
+ pColorMask = _GetProcAddress("glColorMask");
+ assert(pColorMask);;
}
GLuint
@@ -968,3 +970,12 @@ GlFunctions::LineWidth(GLfloat width) {
typedef void (*LINEWIDTH)(GLfloat width);
return ((LINEWIDTH)pLineWidth)(width);
}
+
+
+void
+GlFunctions::ColorMask(GLboolean red, GLboolean green,
+ GLboolean blue, GLboolean alpha) {
+ typedef void (*COLORMASK)(GLboolean red, GLboolean green,
+ GLboolean blue, GLboolean alpha);
+ return ((COLORMASK)pColorMask)(red, green, blue, alpha);
+}
diff --git a/retrace/daemon/gldispatch/glframe_glhelper.hpp b/retrace/daemon/gldispatch/glframe_glhelper.hpp
index 2154b70d..7383c7a9 100644
--- a/retrace/daemon/gldispatch/glframe_glhelper.hpp
+++ b/retrace/daemon/gldispatch/glframe_glhelper.hpp
@@ -177,6 +177,8 @@ class GlFunctions {
static void Finish();
static void CullFace(GLenum mode);
static void LineWidth(GLfloat width);
+ static void ColorMask(GLboolean red, GLboolean green,
+ GLboolean blue, GLboolean alpha);
private:
GlFunctions();
diff --git a/retrace/daemon/glframe_retrace_render.cpp b/retrace/daemon/glframe_retrace_render.cpp
index 429bcf2f..46661277 100644
--- a/retrace/daemon/glframe_retrace_render.cpp
+++ b/retrace/daemon/glframe_retrace_render.cpp
@@ -457,10 +457,5 @@ void
RetraceRender::setState(const StateKey &item,
int offset,
const std::string &value) {
- uint32_t e = state_name_to_enum(value);
- if (e != GL_INVALID_ENUM) {
- assert(offset == 0);
- return m_state_override->setState(item, e);
- }
- m_state_override->setState(item, offset, std::stof(value));
+ m_state_override->setState(item, offset, value);
}
diff --git a/retrace/daemon/glframe_state_enums.cpp b/retrace/daemon/glframe_state_enums.cpp
index ec0316d7..e070a637 100644
--- a/retrace/daemon/glframe_state_enums.cpp
+++ b/retrace/daemon/glframe_state_enums.cpp
@@ -49,6 +49,7 @@ glretrace::state_name_to_enum(const std::string &value) {
{"GL_BLEND_SRC_ALPHA", GL_BLEND_SRC_ALPHA},
{"GL_BLEND_SRC_RGB", GL_BLEND_SRC_RGB},
{"GL_COLOR_CLEAR_VALUE", GL_COLOR_CLEAR_VALUE},
+ {"GL_COLOR_WRITEMASK", GL_COLOR_WRITEMASK},
{"GL_CONSTANT_ALPHA", GL_CONSTANT_ALPHA},
{"GL_CONSTANT_COLOR", GL_CONSTANT_COLOR},
{"GL_CULL_FACE", GL_CULL_FACE},
@@ -152,8 +153,9 @@ glretrace::state_enum_to_name(GLint value) {
std::vector<std::string>
glretrace::state_name_to_choices(const std::string &n) {
switch (state_name_to_enum(n)) {
- case GL_CULL_FACE:
case GL_BLEND:
+ case GL_COLOR_WRITEMASK:
+ case GL_CULL_FACE:
case GL_LINE_SMOOTH:
return {"true", "false"};
case GL_CULL_FACE_MODE:
diff --git a/retrace/daemon/glframe_state_override.cpp b/retrace/daemon/glframe_state_override.cpp
index 814ece38..01e8bbad 100644
--- a/retrace/daemon/glframe_state_override.cpp
+++ b/retrace/daemon/glframe_state_override.cpp
@@ -27,6 +27,7 @@
#include "glframe_state_override.hpp"
+#include <map>
#include <string>
#include <vector>
@@ -42,41 +43,113 @@ union IntFloat {
void
StateOverride::setState(const StateKey &item,
- GLint value) {
- auto &i = m_overrides[item];
+ int offset,
+ const std::string &value) {
+ StateKey adjusted_item(item);
+ adjust_item(&adjusted_item);
+ auto &i = m_overrides[adjusted_item];
if (i.empty()) {
// save the prior state so we can restore it
- getState(item, &i);
- m_saved_state[item] = i;
+ getState(adjusted_item, &i);
+ m_saved_state[adjusted_item] = i;
}
- assert(i.size() == 1);
- i[0] = value;
+ adjust_offset(item, &offset);
+ const uint32_t data_value = interpret_value(item, value);
+ i[offset] = data_value;
}
+// Not all StateKey items from the UI will match the data model for
+// state overrides during retrace. For example, GL_COLOR_WRITEMASK is
+// stored in 4 separate items in the UI, but a single override in this
+// model. The reason for this discrepancy is to allow mapping of
+// model offsets to UI colors (0->red, 1->green, etc). This method
+// interprets a StateKey from the UI and adjusts it to match the
+// model.
void
-StateOverride::setState(const StateKey &item,
- int offset,
- float value) {
- m_data_types[item] = kFloat;
- auto &i = m_overrides[item];
- if (i.empty()) {
- // save the prior state so we can restore it
- getState(item, &i);
- m_saved_state[item] = i;
+StateOverride::adjust_item(StateKey *item) const {
+ switch (state_name_to_enum(item->name)) {
+ case GL_COLOR_WRITEMASK: {
+ item->path = "";
+ break;
+ }
+ default:
+ break;
+ }
+}
+
+// As with adjust_item, offsets from the UI do not always match the
+// model used by this override. This method interprets an offset from
+// the UI, and adjusts it to match the model implementation.
+void
+StateOverride::adjust_offset(const StateKey &item,
+ int *offset) const {
+ switch (state_name_to_enum(item.name)) {
+ case GL_COLOR_WRITEMASK: {
+ static const std::map<std::string, int> writemask_offsets {
+ { "FrameBuffer State/Red Enabled", 0 },
+ { "FrameBuffer State/Green Enabled", 1 },
+ { "FrameBuffer State/Blue Enabled", 2 },
+ { "FrameBuffer State/Alpha Enabled", 3 },
+ };
+ const auto i = writemask_offsets.find(item.path);
+ assert(i != writemask_offsets.end());
+ *offset = i->second;
+ return;
+ }
+ default:
+ return;
+ }
+}
+
+// The UI uses strings for all state values. The override model
+// stores all data types in a vector of uint32_t.
+uint32_t
+StateOverride::interpret_value(const StateKey &item,
+ const std::string &value) {
+ switch (state_name_to_enum(item.name)) {
+ // enumeration values
+ // true/false values
+ case GL_BLEND:
+ case GL_BLEND_DST:
+ case GL_BLEND_DST_ALPHA:
+ case GL_BLEND_DST_RGB:
+ case GL_BLEND_EQUATION_ALPHA:
+ case GL_BLEND_EQUATION_RGB:
+ case GL_BLEND_SRC:
+ case GL_BLEND_SRC_ALPHA:
+ case GL_BLEND_SRC_RGB:
+ case GL_COLOR_WRITEMASK:
+ case GL_CULL_FACE:
+ case GL_CULL_FACE_MODE:
+ case GL_LINE_SMOOTH:
+ return state_name_to_enum(value);
+
+ // float values
+ case GL_BLEND_COLOR:
+ case GL_COLOR_CLEAR_VALUE:
+ case GL_LINE_WIDTH: {
+ IntFloat i_f;
+ i_f.f = std::stof(value);
+ return i_f.i;
+ }
+
+ // int values
+ default:
+ assert(false);
+ return 0;
}
- IntFloat u;
- u.f = value;
- i[offset] = u.i;
}
void
StateOverride::getState(const StateKey &item,
std::vector<uint32_t> *data) {
const auto n = state_name_to_enum(item.name);
+ data->clear();
switch (n) {
case GL_BLEND:
case GL_CULL_FACE:
case GL_LINE_SMOOTH: {
+ data->resize(1);
get_enabled_state(n, data);
break;
}
@@ -89,12 +162,22 @@ StateOverride::getState(const StateKey &item,
case GL_BLEND_SRC_ALPHA:
case GL_BLEND_SRC_RGB:
case GL_CULL_FACE_MODE: {
+ data->resize(1);
get_integer_state(n, data);
break;
}
+ case GL_COLOR_WRITEMASK: {
+ data->resize(4);
+ get_bool_state(n, data);
+ break;
+ }
case GL_BLEND_COLOR:
case GL_COLOR_CLEAR_VALUE:
+ data->resize(4);
+ get_float_state(n, data);
+ break;
case GL_LINE_WIDTH: {
+ data->resize(1);
get_float_state(n, data);
break;
}
@@ -105,8 +188,7 @@ void
StateOverride::get_enabled_state(GLint k,
std::vector<uint32_t> *data) {
GL::GetError();
- data->clear();
- data->resize(1);
+ assert(data->size() == 1);
(*data)[0] = GlFunctions::IsEnabled(k);
assert(!GL::GetError());
}
@@ -116,17 +198,27 @@ void
StateOverride::get_integer_state(GLint k,
std::vector<uint32_t> *data) {
GL::GetError();
- data->clear();
- data->resize(1);
GlFunctions::GetIntegerv(k, reinterpret_cast<GLint*>(data->data()));
assert(!GL::GetError());
}
void
+StateOverride::get_bool_state(GLint k,
+ std::vector<uint32_t> *data) {
+ GL::GetError();
+ std::vector<GLboolean> b(data->size());
+ GlFunctions::GetBooleanv(k, b.data());
+ auto d = data->begin();
+ for (auto v : b) {
+ *d = v ? 1 : 0;
+ ++d;
+ }
+ assert(!GL::GetError());
+}
+
+void
StateOverride::get_float_state(GLint k, std::vector<uint32_t> *data) {
GL::GetError();
- data->clear();
- data->resize(4);
GlFunctions::GetFloatv(k, reinterpret_cast<GLfloat*>(data->data()));
assert(!GL::GetError());
}
@@ -230,8 +322,15 @@ StateOverride::enact_state(const KeyMap &m) const {
assert(GL::GetError() == GL_NO_ERROR);
break;
}
+ case GL_COLOR_WRITEMASK: {
+ GlFunctions::ColorMask(i.second[0],
+ i.second[1],
+ i.second[2],
+ i.second[3]);
+ break;
+ }
case GL_LINE_WIDTH: {
- // assert(i.second.size() == 1);
+ assert(i.second.size() == 1);
IntFloat u;
u.i = i.second[0];
GlFunctions::LineWidth(u.f);
@@ -362,4 +461,29 @@ StateOverride::onState(SelectionId selId,
floatStrings(data, &color);
callback->onState(selId, experimentCount, renderId, k, color);
}
+ {
+ StateKey k("Rendering", "FrameBuffer State/Red Enabled",
+ "GL_COLOR_WRITEMASK");
+ getState(k, &data);
+ callback->onState(selId, experimentCount, renderId, k,
+ {data[0] ? "true" : "false"});
+ {
+ StateKey k("Rendering", "FrameBuffer State/Green Enabled",
+ "GL_COLOR_WRITEMASK");
+ callback->onState(selId, experimentCount, renderId, k,
+ {data[1] ? "true" : "false"});
+ }
+ {
+ StateKey k("Rendering", "FrameBuffer State/Blue Enabled",
+ "GL_COLOR_WRITEMASK");
+ callback->onState(selId, experimentCount, renderId, k,
+ {data[2] ? "true" : "false"});
+ }
+ {
+ StateKey k("Rendering", "FrameBuffer State/Alpha Enabled",
+ "GL_COLOR_WRITEMASK");
+ callback->onState(selId, experimentCount, renderId, k,
+ {data[3] ? "true" : "false"});
+ }
+ }
}
diff --git a/retrace/daemon/glframe_state_override.hpp b/retrace/daemon/glframe_state_override.hpp
index 891ef697..91ff5dab 100644
--- a/retrace/daemon/glframe_state_override.hpp
+++ b/retrace/daemon/glframe_state_override.hpp
@@ -28,6 +28,7 @@
#include <GL/gl.h>
#include <map>
+#include <string>
#include <vector>
#include "glframe_retrace_interface.hpp"
@@ -40,10 +41,7 @@ class StateOverride {
StateOverride() {}
void setState(const StateKey &item,
int offset,
- float value);
- void setState(const StateKey &item,
- GLint value);
- void saveState();
+ const std::string &value);
void overrideState() const;
void restoreState() const;
@@ -66,13 +64,16 @@ class StateOverride {
typedef std::map<StateKey, std::vector<uint32_t>> KeyMap;
void enact_state(const KeyMap &m) const;
void enact_enabled_state(GLint setting, bool v) const;
- void enact_int_state(uint32_t k, const std::vector<uint32_t> &v) const;
- void save_enabled_state(const StateKey &k, GLint v);
- void save_int_state(const StateKey &k, GLint v);
void get_enabled_state(GLint k, std::vector<uint32_t> *data);
void get_integer_state(GLint k, std::vector<uint32_t> *data);
void get_float_state(GLint k, std::vector<uint32_t> *data);
+ void get_bool_state(GLint k, std::vector<uint32_t> *data);
+ void adjust_item(StateKey *item) const;
+ void adjust_offset(const StateKey &item,
+ int *offset) const;
+ uint32_t interpret_value(const StateKey &item,
+ const std::string &value);
KeyMap m_overrides;
KeyMap m_saved_state;
diff --git a/retrace/daemon/ui/glframe_state_model.cpp b/retrace/daemon/ui/glframe_state_model.cpp
index f293fe94..fe878e64 100644
--- a/retrace/daemon/ui/glframe_state_model.cpp
+++ b/retrace/daemon/ui/glframe_state_model.cpp
@@ -65,8 +65,9 @@ QStateValue::QStateValue(QObject *parent,
for (auto c : _choices)
m_choices.append(QVariant(c.c_str()));
- m_indent = static_cast<int>(std::count(_path.begin(), _path.end(), '/')) +
- _name.length() > 0;
+ const int path_count = std::count(_path.begin(), _path.end(), '/');
+ const int indent = path_count + (_name.length() > 0 ? 1 : 0);
+ m_indent = indent;
if (_name.length() == 0)
m_name = _path.substr(_path.find_last_of("/") + 1).c_str();
}
@@ -210,7 +211,7 @@ void QStateModel::onState(SelectionId selectionCount,
std::vector<std::string>());
StateKey k(item.group, path_comp, "");
m_state_by_name[k] = i;
- m_known_paths[item.path] = true;
+ m_known_paths[path_comp] = true;
} else {
break;
}