diff --git a/renderdoc/driver/gl/gl_common.h b/renderdoc/driver/gl/gl_common.h index b22d7e212..aba84dc98 100644 --- a/renderdoc/driver/gl/gl_common.h +++ b/renderdoc/driver/gl/gl_common.h @@ -145,6 +145,7 @@ enum GLChunkType CLEARBUFFERI, CLEARBUFFERUI, CLEARBUFFERFI, + CLEARBUFFERDATA, POLYGON_MODE, POLYGON_OFFSET, CULL_FACE, diff --git a/renderdoc/driver/gl/gl_driver.cpp b/renderdoc/driver/gl/gl_driver.cpp index bf0bfe1e2..a3c39051a 100644 --- a/renderdoc/driver/gl/gl_driver.cpp +++ b/renderdoc/driver/gl/gl_driver.cpp @@ -98,6 +98,7 @@ const char *GLChunkNames[] = "glClearBufferiv", "glClearBufferuiv", "glClearBufferfi", + "glClearBufferData", "glPolygonMode", "glPolygonOffset", "glCullFace", @@ -1578,6 +1579,9 @@ void WrappedOpenGL::ProcessChunk(uint64_t offset, GLChunkType context) case CLEARBUFFERFI: Serialise_glClearBufferfi(eGL_NONE, 0, 0, 0); break; + case CLEARBUFFERDATA: + Serialise_glClearBufferData(eGL_NONE, eGL_NONE, eGL_NONE, eGL_NONE, NULL); + break; case POLYGON_MODE: Serialise_glPolygonMode(eGL_NONE, eGL_NONE); break; diff --git a/renderdoc/driver/gl/gl_driver.h b/renderdoc/driver/gl/gl_driver.h index 06f1c9ca6..7e1724ceb 100644 --- a/renderdoc/driver/gl/gl_driver.h +++ b/renderdoc/driver/gl/gl_driver.h @@ -526,6 +526,7 @@ class WrappedOpenGL IMPLEMENT_FUNCTION_SERIALISED(void, glClearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *value)); IMPLEMENT_FUNCTION_SERIALISED(void, glClearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *value)); IMPLEMENT_FUNCTION_SERIALISED(void, glClearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil)); + IMPLEMENT_FUNCTION_SERIALISED(void, glClearBufferData(GLenum target, GLenum internalformat, GLenum format, GLenum type, const void *data)); IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer)); IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttribIPointer(GLuint index, GLint size, GLenum type, GLsizei stride, const void *pointer)); IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttribBinding(GLuint attribindex, GLuint bindingindex)); diff --git a/renderdoc/driver/gl/gl_hookset.h b/renderdoc/driver/gl/gl_hookset.h index a5fb0f6f0..0bade91ab 100644 --- a/renderdoc/driver/gl/gl_hookset.h +++ b/renderdoc/driver/gl/gl_hookset.h @@ -237,6 +237,7 @@ struct GLHookSet PFNGLCLEARBUFFERIVPROC glClearBufferiv; PFNGLCLEARBUFFERUIVPROC glClearBufferuiv; PFNGLCLEARBUFFERFIPROC glClearBufferfi; + PFNGLCLEARBUFFERDATAPROC glClearBufferData; PFNGLSCISSORARRAYVPROC glScissorArrayv; PFNGLSCISSORINDEXEDPROC glScissorIndexed; PFNGLSCISSORINDEXEDVPROC glScissorIndexedv; diff --git a/renderdoc/driver/gl/gl_hookset_defs.h b/renderdoc/driver/gl/gl_hookset_defs.h index 55c8bfd99..fbb2f4c32 100644 --- a/renderdoc/driver/gl/gl_hookset_defs.h +++ b/renderdoc/driver/gl/gl_hookset_defs.h @@ -251,6 +251,7 @@ HookExtension(PFNGLCLEARBUFFERIVPROC, glClearBufferiv); \ HookExtension(PFNGLCLEARBUFFERUIVPROC, glClearBufferuiv); \ HookExtension(PFNGLCLEARBUFFERFIPROC, glClearBufferfi); \ + HookExtension(PFNGLCLEARBUFFERDATAPROC, glClearBufferData); \ HookExtension(PFNGLSCISSORARRAYVPROC, glScissorArrayv); \ HookExtension(PFNGLSCISSORINDEXEDPROC, glScissorIndexed); \ HookExtension(PFNGLSCISSORINDEXEDVPROC, glScissorIndexedv); \ @@ -604,6 +605,7 @@ HookWrapper3(void, glClearBufferiv, GLenum, buffer, GLint, drawbuffer, const GLint *, value); \ HookWrapper3(void, glClearBufferuiv, GLenum, buffer, GLint, drawbuffer, const GLuint *, value); \ HookWrapper4(void, glClearBufferfi, GLenum, buffer, GLint, drawbuffer, GLfloat, depth, GLint, stencil); \ + HookWrapper5(void, glClearBufferData, GLenum, target, GLenum, internalformat, GLenum, format, GLenum, type, const void *, data); \ HookWrapper3(void, glScissorArrayv, GLuint, first, GLsizei, count, const GLint *, v); \ HookWrapper5(void, glScissorIndexed, GLuint, index, GLint, left, GLint, bottom, GLsizei, width, GLsizei, height); \ HookWrapper2(void, glScissorIndexedv, GLuint, index, const GLint *, v); \ diff --git a/renderdoc/driver/gl/wrappers/gl_draw_funcs.cpp b/renderdoc/driver/gl/wrappers/gl_draw_funcs.cpp index 6fa345ef1..8c3244bfc 100644 --- a/renderdoc/driver/gl/wrappers/gl_draw_funcs.cpp +++ b/renderdoc/driver/gl/wrappers/gl_draw_funcs.cpp @@ -930,6 +930,91 @@ void WrappedOpenGL::glClearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat dep } } +bool WrappedOpenGL::Serialise_glClearBufferData(GLenum target, GLenum internalformat, GLenum format, GLenum type, const void *data) +{ + SERIALISE_ELEMENT(GLenum, Target, target); + SERIALISE_ELEMENT(GLenum, InternalFormat, internalformat); + SERIALISE_ELEMENT(GLenum, Format, format); + SERIALISE_ELEMENT(GLenum, Type, type); + + uint64_t val[4] = {0}; + + if(m_State >= WRITING) + { + size_t s = 1; + switch(Format) + { + default: + RDCWARN("Unexpected format %x, defaulting to single component", Format); + case eGL_RED: + case eGL_DEPTH_COMPONENT: + s = 1; break; + case eGL_RG: + case eGL_DEPTH_STENCIL: + s = 2; break; + case eGL_RGB: + case eGL_BGR: + s = 3; break; + case eGL_RGBA: + case eGL_BGRA: + s = 4; break; + } + switch(Type) + { + case eGL_UNSIGNED_BYTE: + case eGL_BYTE: + s *= 1; break; + case eGL_UNSIGNED_SHORT: + case eGL_SHORT: + s *= 2; break; + case eGL_UNSIGNED_INT: + case eGL_INT: + case eGL_FLOAT: + s *= 4; break; + default: + RDCWARN("Unexpected type %x, defaulting to 1 byte single component type", Format); + case eGL_UNSIGNED_BYTE_3_3_2: + case eGL_UNSIGNED_BYTE_2_3_3_REV: + s = 1; break; + case eGL_UNSIGNED_SHORT_5_6_5: + case eGL_UNSIGNED_SHORT_5_6_5_REV: + case eGL_UNSIGNED_SHORT_4_4_4_4: + case eGL_UNSIGNED_SHORT_4_4_4_4_REV: + case eGL_UNSIGNED_SHORT_5_5_5_1: + case eGL_UNSIGNED_SHORT_1_5_5_5_REV: + case eGL_UNSIGNED_INT_8_8_8_8: + case eGL_UNSIGNED_INT_8_8_8_8_REV: + s = 2; break; + case eGL_UNSIGNED_INT_10_10_10_2: + case eGL_UNSIGNED_INT_2_10_10_10_REV: + s = 4; break; + } + memcpy(val, data, s); + } + + m_pSerialiser->Serialise<4>("data", val); + + if(m_State <= EXECUTING) + { + m_Real.glClearBufferData(Target, InternalFormat, Format, Type, (const void *)&val[0]); + } + + return true; +} + +void WrappedOpenGL::glClearBufferData(GLenum target, GLenum internalformat, GLenum format, GLenum type, const void *data) +{ + m_Real.glClearBufferData(target, internalformat, format, type, data); + + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(CLEARBUFFERDATA); + Serialise_glClearBufferData(target, internalformat, format, type, data); + + m_ContextRecord->AddChunk(scope.Get()); + } +} + bool WrappedOpenGL::Serialise_glClear(GLbitfield mask) { SERIALISE_ELEMENT(uint32_t, Mask, mask);