From b56ad403d9ac868023d6e9888d39192f491e299a Mon Sep 17 00:00:00 2001 From: baldurk Date: Mon, 26 May 2014 19:04:04 +0100 Subject: [PATCH] Serialise blend functions and blend state --- renderdoc/driver/gl/gl_common.h | 6 + renderdoc/driver/gl/gl_context_driver.cpp | 157 +++++++++++++++++++++- renderdoc/driver/gl/gl_driver.cpp | 24 ++++ renderdoc/driver/gl/gl_driver.h | 5 + renderdoc/driver/gl/gl_hookset.h | 5 + renderdoc/driver/gl/gl_hookset_defs.h | 11 ++ renderdoc/driver/gl/gl_renderstate.cpp | 38 ++++++ renderdoc/driver/gl/gl_renderstate.h | 9 ++ 8 files changed, 254 insertions(+), 1 deletion(-) diff --git a/renderdoc/driver/gl/gl_common.h b/renderdoc/driver/gl/gl_common.h index 67c0afdd4..1d5baa5ea 100644 --- a/renderdoc/driver/gl/gl_common.h +++ b/renderdoc/driver/gl/gl_common.h @@ -121,6 +121,12 @@ enum GLChunkType CLEARBUFFERF, ENABLE, DISABLE, + BLEND_FUNC, + BLEND_COLOR, + BLEND_FUNC_SEP, + BLEND_FUNC_SEPI, + BLEND_EQ_SEP, + BLEND_EQ_SEPI, DEPTH_FUNC, VIEWPORT, USEPROGRAM, diff --git a/renderdoc/driver/gl/gl_context_driver.cpp b/renderdoc/driver/gl/gl_context_driver.cpp index eac1cea69..99200bc9d 100644 --- a/renderdoc/driver/gl/gl_context_driver.cpp +++ b/renderdoc/driver/gl/gl_context_driver.cpp @@ -29,13 +29,167 @@ #pragma region State functions +bool WrappedOpenGL::Serialise_glBlendFunc(GLenum sfactor, GLenum dfactor) +{ + SERIALISE_ELEMENT(GLenum, s, sfactor); + SERIALISE_ELEMENT(GLenum, d, dfactor); + + if(m_State <= EXECUTING) + { + m_Real.glBlendFunc(s, d); + } + + return true; +} + void WrappedOpenGL::glBlendFunc(GLenum sfactor, GLenum dfactor) { m_Real.glBlendFunc(sfactor, dfactor); if(m_State >= WRITING) { - RDCUNIMPLEMENTED(); + SCOPED_SERIALISE_CONTEXT(BLEND_FUNC); + Serialise_glBlendFunc(sfactor, dfactor); + + m_ContextRecord->AddChunk(scope.Get()); + } +} + +bool WrappedOpenGL::Serialise_glBlendColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) +{ + SERIALISE_ELEMENT(GLfloat, r, red); + SERIALISE_ELEMENT(GLfloat, g, green); + SERIALISE_ELEMENT(GLfloat, b, blue); + SERIALISE_ELEMENT(GLfloat, a, alpha); + + if(m_State <= EXECUTING) + { + m_Real.glBlendColor(r, g, b, a); + } + + return true; +} + +void WrappedOpenGL::glBlendColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) +{ + m_Real.glBlendColor(red, green, blue, alpha); + + if(m_State >= WRITING) + { + SCOPED_SERIALISE_CONTEXT(BLEND_COLOR); + Serialise_glBlendColor(red, green, blue, alpha); + + m_ContextRecord->AddChunk(scope.Get()); + } +} + +bool WrappedOpenGL::Serialise_glBlendFuncSeparate(GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha) +{ + SERIALISE_ELEMENT(GLenum, s1, sfactorRGB); + SERIALISE_ELEMENT(GLenum, d1, dfactorRGB); + SERIALISE_ELEMENT(GLenum, s2, sfactorAlpha); + SERIALISE_ELEMENT(GLenum, d2, dfactorAlpha); + + if(m_State <= EXECUTING) + { + m_Real.glBlendFuncSeparate(s1, d1, s2, d2); + } + + return true; +} + +void WrappedOpenGL::glBlendFuncSeparate(GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha) +{ + m_Real.glBlendFuncSeparate(sfactorRGB, dfactorRGB, sfactorAlpha, dfactorAlpha); + + if(m_State >= WRITING) + { + SCOPED_SERIALISE_CONTEXT(BLEND_FUNC_SEP); + Serialise_glBlendFuncSeparate(sfactorRGB, dfactorRGB, sfactorAlpha, dfactorAlpha); + + m_ContextRecord->AddChunk(scope.Get()); + } +} + +bool WrappedOpenGL::Serialise_glBlendFuncSeparatei(GLuint buf, GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha) +{ + SERIALISE_ELEMENT(uint32_t, b, buf); + SERIALISE_ELEMENT(GLenum, s1, sfactorRGB); + SERIALISE_ELEMENT(GLenum, d1, dfactorRGB); + SERIALISE_ELEMENT(GLenum, s2, sfactorAlpha); + SERIALISE_ELEMENT(GLenum, d2, dfactorAlpha); + + if(m_State <= EXECUTING) + { + m_Real.glBlendFuncSeparatei(b, s1, d1, s2, d2); + } + + return true; +} + +void WrappedOpenGL::glBlendFuncSeparatei(GLuint buf, GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha) +{ + m_Real.glBlendFuncSeparatei(buf, sfactorRGB, dfactorRGB, sfactorAlpha, dfactorAlpha); + + if(m_State >= WRITING) + { + SCOPED_SERIALISE_CONTEXT(BLEND_FUNC_SEPI); + Serialise_glBlendFuncSeparatei(buf, sfactorRGB, dfactorRGB, sfactorAlpha, dfactorAlpha); + + m_ContextRecord->AddChunk(scope.Get()); + } +} + +bool WrappedOpenGL::Serialise_glBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha) +{ + SERIALISE_ELEMENT(GLenum, m1, modeRGB); + SERIALISE_ELEMENT(GLenum, m2, modeAlpha); + + if(m_State <= EXECUTING) + { + m_Real.glBlendEquationSeparate(m1, m2); + } + + return true; +} + +void WrappedOpenGL::glBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha) +{ + m_Real.glBlendEquationSeparate(modeRGB, modeAlpha); + + if(m_State >= WRITING) + { + SCOPED_SERIALISE_CONTEXT(BLEND_EQ_SEP); + Serialise_glBlendEquationSeparate(modeRGB, modeAlpha); + + m_ContextRecord->AddChunk(scope.Get()); + } +} + +bool WrappedOpenGL::Serialise_glBlendEquationSeparatei(GLuint buf, GLenum modeRGB, GLenum modeAlpha) +{ + SERIALISE_ELEMENT(uint32_t, b, buf); + SERIALISE_ELEMENT(GLenum, m1, modeRGB); + SERIALISE_ELEMENT(GLenum, m2, modeAlpha); + + if(m_State <= EXECUTING) + { + m_Real.glBlendEquationSeparatei(b, m1, m2); + } + + return true; +} + +void WrappedOpenGL::glBlendEquationSeparatei(GLuint buf, GLenum modeRGB, GLenum modeAlpha) +{ + m_Real.glBlendEquationSeparatei(buf, modeRGB, modeAlpha); + + if(m_State >= WRITING) + { + SCOPED_SERIALISE_CONTEXT(BLEND_EQ_SEPI); + Serialise_glBlendEquationSeparatei(buf, modeRGB, modeAlpha); + + m_ContextRecord->AddChunk(scope.Get()); } } @@ -133,6 +287,7 @@ void WrappedOpenGL::glEnable(GLenum cap) m_ContextRecord->AddChunk(scope.Get()); } + // TODO replace this with glIsEnabled() for the relevant states if(m_State == WRITING_IDLE) { SCOPED_SERIALISE_CONTEXT(ENABLE); diff --git a/renderdoc/driver/gl/gl_driver.cpp b/renderdoc/driver/gl/gl_driver.cpp index 99c3284ff..6b6160f91 100644 --- a/renderdoc/driver/gl/gl_driver.cpp +++ b/renderdoc/driver/gl/gl_driver.cpp @@ -78,6 +78,12 @@ const char *GLChunkNames[] = "glClearBufferfv", "glEnable", "glDisable", + "glBlendFunc", + "glBlendColor", + "glBlendFuncSeparate", + "glBlendFuncSeparatei", + "glBlendEquationSeparate", + "glBlendEquationSeparatei", "glDepthFunc", "glViewport", "glUseProgram", @@ -967,6 +973,24 @@ void WrappedOpenGL::ProcessChunk(uint64_t offset, GLChunkType context) case ENABLE: Serialise_glEnable(eGL_UNKNOWN_ENUM); break; + case BLEND_FUNC: + glBlendFunc(eGL_UNKNOWN_ENUM, eGL_UNKNOWN_ENUM); + break; + case BLEND_COLOR: + glBlendColor(0, 0, 0, 0); + break; + case BLEND_FUNC_SEP: + glBlendFuncSeparate(eGL_UNKNOWN_ENUM, eGL_UNKNOWN_ENUM, eGL_UNKNOWN_ENUM, eGL_UNKNOWN_ENUM); + break; + case BLEND_FUNC_SEPI: + glBlendFuncSeparatei(0, eGL_UNKNOWN_ENUM, eGL_UNKNOWN_ENUM, eGL_UNKNOWN_ENUM, eGL_UNKNOWN_ENUM); + break; + case BLEND_EQ_SEP: + glBlendEquationSeparate(eGL_UNKNOWN_ENUM, eGL_UNKNOWN_ENUM); + break; + case BLEND_EQ_SEPI: + glBlendEquationSeparatei(0, eGL_UNKNOWN_ENUM, eGL_UNKNOWN_ENUM); + break; case DEPTH_FUNC: Serialise_glDepthFunc(eGL_UNKNOWN_ENUM); break; diff --git a/renderdoc/driver/gl/gl_driver.h b/renderdoc/driver/gl/gl_driver.h index f9412efca..b6dfe045c 100644 --- a/renderdoc/driver/gl/gl_driver.h +++ b/renderdoc/driver/gl/gl_driver.h @@ -266,6 +266,11 @@ class WrappedOpenGL IMPLEMENT_FUNCTION_SERIALISED(void, glBindTexture(GLenum target, GLuint texture)); IMPLEMENT_FUNCTION_SERIALISED(void, glBlendFunc(GLenum sfactor, GLenum dfactor)); + IMPLEMENT_FUNCTION_SERIALISED(void, glBlendColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)); + IMPLEMENT_FUNCTION_SERIALISED(void, glBlendFuncSeparate(GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha)); + IMPLEMENT_FUNCTION_SERIALISED(void, glBlendFuncSeparatei(GLuint buf, GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha)); + IMPLEMENT_FUNCTION_SERIALISED(void, glBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)); + IMPLEMENT_FUNCTION_SERIALISED(void, glBlendEquationSeparatei(GLuint buf, GLenum modeRGB, GLenum modeAlpha)); IMPLEMENT_FUNCTION_SERIALISED(void, glClear(GLbitfield mask)); IMPLEMENT_FUNCTION_SERIALISED(void, glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)); IMPLEMENT_FUNCTION_SERIALISED(void, glClearDepth(GLclampd depth)); diff --git a/renderdoc/driver/gl/gl_hookset.h b/renderdoc/driver/gl/gl_hookset.h index 8f1c8762c..c008980cf 100644 --- a/renderdoc/driver/gl/gl_hookset.h +++ b/renderdoc/driver/gl/gl_hookset.h @@ -33,6 +33,7 @@ struct GLHookSet // ++ dllexport PFNGLBINDTEXTUREPROC glBindTexture; PFNGLBLENDFUNCPROC glBlendFunc; + PFNGLBLENDCOLORPROC glBlendColor; PFNGLCLEARPROC glClear; PFNGLCLEARCOLORPROC glClearColor; PFNGLCLEARDEPTHPROC glClearDepth; @@ -92,6 +93,10 @@ struct GLHookSet PFNGLGETSTRINGIPROC glGetStringi; PFNGLGETINTEGERI_VPROC glGetIntegeri_v; PFNGLGETINTEGER64I_VPROC glGetInteger64i_v; + PFNGLBLENDFUNCSEPARATEPROC glBlendFuncSeparate; + PFNGLBLENDFUNCSEPARATEIPROC glBlendFuncSeparatei; + PFNGLBLENDEQUATIONSEPARATEPROC glBlendEquationSeparate; + PFNGLBLENDEQUATIONSEPARATEIPROC glBlendEquationSeparatei; PFNGLCREATESHADERPROC glCreateShader; PFNGLDELETESHADERPROC glDeleteShader; PFNGLSHADERSOURCEPROC glShaderSource; diff --git a/renderdoc/driver/gl/gl_hookset_defs.h b/renderdoc/driver/gl/gl_hookset_defs.h index 1f975cc34..c3eeba05b 100644 --- a/renderdoc/driver/gl/gl_hookset_defs.h +++ b/renderdoc/driver/gl/gl_hookset_defs.h @@ -33,6 +33,7 @@ #define DLLExportHooks() \ HookInit(glBindTexture); \ HookInit(glBlendFunc); \ + HookInit(glBlendColor); \ HookInit(glClear); \ HookInit(glClearColor); \ HookInit(glClearDepth); \ @@ -103,6 +104,10 @@ HookExtension(PFNGLGETSTRINGIPROC, glGetStringi); \ HookExtension(PFNGLGETINTEGERI_VPROC, glGetIntegeri_v); \ HookExtension(PFNGLGETINTEGER64I_VPROC, glGetInteger64i_v); \ + HookExtension(PFNGLBLENDFUNCSEPARATEPROC, glBlendFuncSeparate); \ + HookExtension(PFNGLBLENDFUNCSEPARATEIPROC, glBlendFuncSeparatei); \ + HookExtension(PFNGLBLENDEQUATIONSEPARATEPROC, glBlendEquationSeparate); \ + HookExtension(PFNGLBLENDEQUATIONSEPARATEIPROC, glBlendEquationSeparatei); \ HookExtension(PFNGLCREATESHADERPROC, glCreateShader); \ HookExtension(PFNGLDELETESHADERPROC, glDeleteShader); \ HookExtension(PFNGLSHADERSOURCEPROC, glShaderSource); \ @@ -158,6 +163,7 @@ HookExtension(PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEPROC, glDrawArraysInstancedBaseInstance); \ HookExtension(PFNGLBINDTEXTUREPROC, glBindTexture); \ HookExtension(PFNGLBLENDFUNCPROC, glBlendFunc); \ + HookExtension(PFNGLBLENDCOLORPROC, glBlendColor); \ HookExtension(PFNGLCLEARPROC, glClear); \ HookExtension(PFNGLCLEARCOLORPROC, glClearColor); \ HookExtension(PFNGLCLEARDEPTHPROC, glClearDepth); \ @@ -210,6 +216,7 @@ #define DefineDLLExportHooks() \ HookWrapper2(void, glBindTexture, GLenum, target, GLuint, texture); \ HookWrapper2(void, glBlendFunc, GLenum, sfactor, GLenum, dfactor); \ + HookWrapper4(void, glBlendColor, GLfloat, red, GLfloat, green, GLfloat, blue, GLfloat, alpha); \ HookWrapper1(void, glClear, GLbitfield, mask); \ HookWrapper4(void, glClearColor, GLfloat, red, GLfloat, green, GLfloat, blue, GLfloat, alpha); \ HookWrapper1(void, glClearDepth, GLdouble, depth); \ @@ -280,6 +287,10 @@ HookWrapper2(const GLubyte *, glGetStringi, GLenum, name, GLuint, index); \ HookWrapper3(void, glGetIntegeri_v, GLenum, target, GLuint, index, GLint *, data); \ HookWrapper3(void, glGetInteger64i_v, GLenum, target, GLuint, index, GLint64 *, data); \ + HookWrapper4(void, glBlendFuncSeparate, GLenum, sfactorRGB, GLenum, dfactorRGB, GLenum, sfactorAlpha, GLenum, dfactorAlpha); \ + HookWrapper5(void, glBlendFuncSeparatei, GLuint, buf, GLenum, sfactorRGB, GLenum, dfactorRGB, GLenum, sfactorAlpha, GLenum, dfactorAlpha); \ + HookWrapper2(void, glBlendEquationSeparate, GLenum, modeRGB, GLenum, modeAlpha); \ + HookWrapper3(void, glBlendEquationSeparatei, GLuint, buf, GLenum, modeRGB, GLenum, modeAlpha); \ HookWrapper1(GLuint, glCreateShader, GLenum, type); \ HookWrapper1(void, glDeleteShader, GLuint, shader); \ HookWrapper4(void, glShaderSource, GLuint, shader, GLsizei, count, const GLchar *const*, string, const GLint *, length); \ diff --git a/renderdoc/driver/gl/gl_renderstate.cpp b/renderdoc/driver/gl/gl_renderstate.cpp index 9f2ae43aa..ee0521294 100644 --- a/renderdoc/driver/gl/gl_renderstate.cpp +++ b/renderdoc/driver/gl/gl_renderstate.cpp @@ -78,6 +78,20 @@ void GLRenderState::FetchState() m_Real->glGetInteger64i_v(idxBufs[b].size, i, (GLint64*)&idxBufs[b].bufs[i].size); } } + + for(int i=0; i < ARRAY_COUNT(Blends); i++) + { + m_Real->glGetIntegeri_v(eGL_BLEND_EQUATION_RGB, i, (GLint*)Blends[i].EquationRGB); + m_Real->glGetIntegeri_v(eGL_BLEND_EQUATION_ALPHA, i, (GLint*)Blends[i].EquationAlpha); + + m_Real->glGetIntegeri_v(eGL_BLEND_SRC_RGB, i, (GLint*)Blends[i].SourceRGB); + m_Real->glGetIntegeri_v(eGL_BLEND_SRC_ALPHA, i, (GLint*)Blends[i].SourceAlpha); + + m_Real->glGetIntegeri_v(eGL_BLEND_DST_RGB, i, (GLint*)Blends[i].DestinationRGB); + m_Real->glGetIntegeri_v(eGL_BLEND_DST_ALPHA, i, (GLint*)Blends[i].DestinationAlpha); + } + + m_Real->glGetFloatv(eGL_BLEND_COLOR, &BlendColor[0]); } void GLRenderState::ApplyState() @@ -112,6 +126,14 @@ void GLRenderState::ApplyState() for(int b=0; b < ARRAY_COUNT(idxBufs); b++) for(int i=0; i < idxBufs[b].count; i++) m_Real->glBindBufferRange(idxBufs[b].binding, i, idxBufs[b].bufs[i].name, (GLintptr)idxBufs[b].bufs[i].start, (GLsizeiptr)idxBufs[b].bufs[i].size); + + for(int i=0; i < ARRAY_COUNT(Blends); i++) + { + m_Real->glBlendFuncSeparatei(i, Blends[i].SourceRGB, Blends[i].DestinationRGB, Blends[i].DestinationRGB, Blends[i].DestinationAlpha); + m_Real->glBlendEquationSeparatei(i, Blends[i].EquationRGB, Blends[i].EquationAlpha); + } + + m_Real->glBlendColor(BlendColor[0], BlendColor[1], BlendColor[2], BlendColor[3]); } void GLRenderState::Clear() @@ -123,6 +145,8 @@ void GLRenderState::Clear() RDCEraseEl(ShaderStorage); RDCEraseEl(TransformFeedback); RDCEraseEl(UniformBinding); + RDCEraseEl(Blends); + RDCEraseEl(BlendColor); } void GLRenderState::Serialise(LogState state, GLResourceManager *rm) @@ -165,4 +189,18 @@ void GLRenderState::Serialise(LogState state, GLResourceManager *rm) m_pSerialiser->Serialise("BUFFER_SIZE", idxBufs[b].bufs[i].size); } } + + for(int i=0; i < ARRAY_COUNT(Blends); i++) + { + m_pSerialiser->Serialise("GL_BLEND_EQUATION_RGB", Blends[i].EquationRGB); + m_pSerialiser->Serialise("GL_BLEND_EQUATION_ALPHA", Blends[i].EquationAlpha); + + m_pSerialiser->Serialise("GL_BLEND_SRC_RGB", Blends[i].SourceRGB); + m_pSerialiser->Serialise("GL_BLEND_SRC_ALPHA", Blends[i].SourceAlpha); + + m_pSerialiser->Serialise("GL_BLEND_DST_RGB", Blends[i].DestinationRGB); + m_pSerialiser->Serialise("GL_BLEND_DST_ALPHA", Blends[i].DestinationAlpha); + } + + m_pSerialiser->Serialise<4>("GL_BLEND_COLOR", BlendColor); } diff --git a/renderdoc/driver/gl/gl_renderstate.h b/renderdoc/driver/gl/gl_renderstate.h index 66205326f..5c8e92b7e 100644 --- a/renderdoc/driver/gl/gl_renderstate.h +++ b/renderdoc/driver/gl/gl_renderstate.h @@ -41,6 +41,7 @@ struct GLRenderState // uint32_t Tex2D[128]; GLenum ActiveTexture; + uint32_t BufferBindings[10]; struct IdxRangeBuffer { @@ -48,6 +49,14 @@ struct GLRenderState uint64_t start; uint64_t size; } AtomicCounter[8], ShaderStorage[8], TransformFeedback[8], UniformBinding[128]; + + struct BlendState + { + GLenum EquationRGB, EquationAlpha; + GLenum SourceRGB, SourceAlpha; + GLenum DestinationRGB, DestinationAlpha; + } Blends[8]; + float BlendColor[4]; // void Serialise(LogState state, GLResourceManager *rm);