summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Janes <mark.a.janes@intel.com>2017-03-18 10:20:36 -0700
committerMark Janes <mark.a.janes@intel.com>2017-06-19 14:04:51 -0700
commit5acb3a035fb9a0232796eb281dad981ce7119f9e (patch)
tree444612a84f3894930a0b239ef347ce9822881959
parentd43196a6ea06d9e4f1c2c53116c71be283f6450e (diff)
Shaders: handle glBindFragDataLocation
This GL feature is used in some renders in Borderlands2. When programs are relinked, the fragData must be bound in the same location.
-rw-r--r--retrace/daemon/gldispatch/glframe_glhelper.cpp14
-rw-r--r--retrace/daemon/gldispatch/glframe_glhelper.hpp2
-rw-r--r--retrace/daemon/glframe_state.cpp18
-rw-r--r--retrace/daemon/glframe_state.hpp2
4 files changed, 35 insertions, 1 deletions
diff --git a/retrace/daemon/gldispatch/glframe_glhelper.cpp b/retrace/daemon/gldispatch/glframe_glhelper.cpp
index 32cabac8..2fe55e68 100644
--- a/retrace/daemon/gldispatch/glframe_glhelper.cpp
+++ b/retrace/daemon/gldispatch/glframe_glhelper.cpp
@@ -93,6 +93,7 @@ static void *pValidateProgram = NULL;
static void *pIsEnabled = NULL;
static void *pGetUniformBlockIndex = NULL;
static void *pUniformBlockBinding = NULL;
+static void *pBindFragDataLocation = NULL;
} // namespace
@@ -249,6 +250,8 @@ GlFunctions::Init(void *lookup_fn) {
assert(pGetUniformBlockIndex);
pUniformBlockBinding = _GetProcAddress("glUniformBlockBinding");
assert(pUniformBlockBinding);
+ pBindFragDataLocation = _GetProcAddress("glBindFragDataLocation");
+ assert(pBindFragDataLocation);
}
GLuint
@@ -652,3 +655,14 @@ GlFunctions::UniformBlockBinding(GLuint program, GLuint uniformBlockIndex,
uniformBlockIndex,
uniformBlockBinding);
}
+
+
+void
+GlFunctions::BindFragDataLocation(GLuint program, GLuint colorNumber,
+ const char * name) {
+ typedef void (*BINDFRAGDATALOCATION)(GLuint program, GLuint colorNumber,
+ const char * name);
+ return ((BINDFRAGDATALOCATION)pBindFragDataLocation)(program,
+ colorNumber,
+ name);
+}
diff --git a/retrace/daemon/gldispatch/glframe_glhelper.hpp b/retrace/daemon/gldispatch/glframe_glhelper.hpp
index b70d2e08..39a2ab48 100644
--- a/retrace/daemon/gldispatch/glframe_glhelper.hpp
+++ b/retrace/daemon/gldispatch/glframe_glhelper.hpp
@@ -133,6 +133,8 @@ class GlFunctions {
const GLchar *uniformBlockName);
static void UniformBlockBinding(GLuint program, GLuint uniformBlockIndex,
GLuint uniformBlockBinding);
+ static void BindFragDataLocation(GLuint program, GLuint colorNumber,
+ const char * name);
private:
GlFunctions();
diff --git a/retrace/daemon/glframe_state.cpp b/retrace/daemon/glframe_state.cpp
index 57cd9a2b..a8e5d8d2 100644
--- a/retrace/daemon/glframe_state.cpp
+++ b/retrace/daemon/glframe_state.cpp
@@ -59,7 +59,8 @@ StateTrack::TrackMap StateTrack::lookup;
StateTrack::StateTrack(OutputPoller *p)
: m_poller(p),
current_program(0),
- current_context(0) {
+ current_context(0),
+ empty_shader() {
}
StateTrack::TrackMap::TrackMap() {
@@ -74,6 +75,7 @@ StateTrack::TrackMap::TrackMap() {
lookup["glGetUniformLocation"] = &StateTrack::trackGetUniformLocation;
lookup["glGetUniformBlockIndex"] = &StateTrack::trackGetUniformBlockIndex;
lookup["glUniformBlockBinding"] = &StateTrack::trackUniformBlockBinding;
+ lookup["glBindFragDataLocation"] = &StateTrack::trackBindFragDataLocation;
}
bool
@@ -567,6 +569,11 @@ StateTrack::useProgram(int orig_retraced_program,
GlFunctions::BindAttribLocation(pid, binding.first, binding.second.c_str());
}
+ for (auto &binding : m_program_to_frag_data_location[orig_retraced_program]) {
+ GlFunctions::BindFragDataLocation(pid, binding.second,
+ binding.first.c_str());
+ }
+
GlFunctions::LinkProgram(pid);
GL_CHECK();
if (message) {
@@ -735,6 +742,15 @@ StateTrack::trackUniformBlockBinding(const trace::Call &call) {
}
void
+StateTrack::trackBindFragDataLocation(const trace::Call &call) {
+ const int call_program = call.args[0].value->toDouble();
+ const int program = glretrace::getRetracedProgram(call_program);
+ const int call_location = call.args[1].value->toDouble();
+ const std::string name(call.args[2].value->toString());
+ m_program_to_frag_data_location[program][name] = call_location;
+}
+
+void
StateTrack::onAssembly(ShaderType st, AssemblyType at,
const std::string &assembly) {
if (!current_program)
diff --git a/retrace/daemon/glframe_state.hpp b/retrace/daemon/glframe_state.hpp
index d5437bc3..f32159e2 100644
--- a/retrace/daemon/glframe_state.hpp
+++ b/retrace/daemon/glframe_state.hpp
@@ -143,6 +143,7 @@ class StateTrack {
void trackGetUniformLocation(const trace::Call &);
void trackGetUniformBlockIndex(const trace::Call &);
void trackUniformBlockBinding(const trace::Call &);
+ void trackBindFragDataLocation(const trace::Call &);
OutputPoller *m_poller;
int current_program;
@@ -154,6 +155,7 @@ class StateTrack {
std::map<int, std::map<int, std::string>> m_program_to_bound_attrib;
std::map<int, std::map<int, std::string>> m_program_to_uniform_name;
std::map<int, std::map<std::string, int>> m_program_to_uniform_block_index;
+ std::map<int, std::map<std::string, int>> m_program_to_frag_data_location;
// key is program, internal key is index, value is binding
std::map<int, std::map<int, int>> m_program_to_uniform_block_binding;