diff options
author | Mark Janes <mark.a.janes@intel.com> | 2017-11-21 12:11:38 -0800 |
---|---|---|
committer | Mark Janes <mark.a.janes@intel.com> | 2017-11-27 11:29:21 -0800 |
commit | f6f5d7efe8ad982262d7fdb564d7c0dcc996186f (patch) | |
tree | c2dbf31c896a034cc91862d606990caaa3495511 /retrace | |
parent | 718cdc66dd273fc1ccad765d378cdbccc8da1f65 (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.cpp | 13 | ||||
-rw-r--r-- | retrace/daemon/gldispatch/glframe_glhelper.hpp | 2 | ||||
-rw-r--r-- | retrace/daemon/glframe_retrace_render.cpp | 7 | ||||
-rw-r--r-- | retrace/daemon/glframe_state_enums.cpp | 4 | ||||
-rw-r--r-- | retrace/daemon/glframe_state_override.cpp | 174 | ||||
-rw-r--r-- | retrace/daemon/glframe_state_override.hpp | 15 | ||||
-rw-r--r-- | retrace/daemon/ui/glframe_state_model.cpp | 7 |
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; } |