From a6f202ca5e50d7c4c25afa9d8bded1daf8f23a37 Mon Sep 17 00:00:00 2001 From: Janos Pantos Date: Fri, 19 May 2017 21:55:55 +0200 Subject: [PATCH] Add support for primitive bounding boxes feature of GLES --- renderdoc/driver/gl/gl_common.h | 10 ++++-- renderdoc/driver/gl/gl_driver.cpp | 6 ++++ renderdoc/driver/gl/gl_driver.h | 11 ++++-- renderdoc/driver/gl/gl_hookset.h | 3 ++ renderdoc/driver/gl/gl_hookset_defs.h | 8 ++--- renderdoc/driver/gl/gl_renderstate.cpp | 22 ++++++++++++ renderdoc/driver/gl/gl_renderstate.h | 7 ++++ .../driver/gl/wrappers/gl_draw_funcs.cpp | 34 +++++++++++++++++++ 8 files changed, 91 insertions(+), 10 deletions(-) diff --git a/renderdoc/driver/gl/gl_common.h b/renderdoc/driver/gl/gl_common.h index c23ef890a..c02b81fe2 100644 --- a/renderdoc/driver/gl/gl_common.h +++ b/renderdoc/driver/gl/gl_common.h @@ -339,14 +339,16 @@ extern bool IsGLES; EXT_TO_CHECK(99, 30, EXT_texture_swizzle) \ EXT_TO_CHECK(99, 99, KHR_blend_equation_advanced_coherent) \ /* OpenGL ES extensions */ \ + EXT_TO_CHECK(99, 32, EXT_color_buffer_float) \ + EXT_TO_CHECK(99, 32, EXT_primitive_bounding_box) \ + EXT_TO_CHECK(99, 32, OES_primitive_bounding_box) \ + EXT_TO_CHECK(99, 32, OES_texture_storage_multisample_2d_array) \ EXT_TO_CHECK(99, 99, EXT_clip_cull_distance) \ EXT_TO_CHECK(99, 99, EXT_multisample_compatibility) \ EXT_TO_CHECK(99, 99, NV_polygon_mode) \ EXT_TO_CHECK(99, 99, NV_read_depth) \ EXT_TO_CHECK(99, 99, NV_read_stencil) \ - EXT_TO_CHECK(99, 99, NV_read_depth_stencil) \ - EXT_TO_CHECK(99, 32, OES_texture_storage_multisample_2d_array) \ - EXT_TO_CHECK(99, 32, EXT_color_buffer_float) + EXT_TO_CHECK(99, 99, NV_read_depth_stencil) // GL extensions and their roughly equivalent GLES alternatives #define EXTENSION_COMPATIBILITY_CHECKS() \ @@ -722,5 +724,7 @@ enum GLChunkType INTEROP_INIT, INTEROP_DATA, + PRIMITIVE_BOUNDING_BOX, + NUM_OPENGL_CHUNKS, }; diff --git a/renderdoc/driver/gl/gl_driver.cpp b/renderdoc/driver/gl/gl_driver.cpp index 6fe15c6e4..8b429f589 100644 --- a/renderdoc/driver/gl/gl_driver.cpp +++ b/renderdoc/driver/gl/gl_driver.cpp @@ -320,6 +320,8 @@ const char *GLChunkNames[] = { "wglDXRegisterObjectNV", "wglDXLockObjectsNV", + + "glPrimitiveBoundingBox", }; GLInitParams::GLInitParams() @@ -346,6 +348,7 @@ const uint32_t GLInitParams::GL_OLD_VERSIONS[GLInitParams::GL_NUM_SUPPORTED_OLD_ 0x000012, // Added support for GL-DX interop 0x000013, // Serialised vertex attribute and fragdata bindings for programs as initial // contents data + 0x000014, // Added support for primitive bounding boxes on GLES }; ReplayStatus GLInitParams::Serialise() @@ -746,6 +749,7 @@ void WrappedOpenGL::BuildGLESExtensions() m_GLESExtensions.push_back("GL_OES_texture_float_linear"); m_GLESExtensions.push_back("GL_OES_texture_half_float"); m_GLESExtensions.push_back("GL_OES_texture_half_float_linear"); + m_GLESExtensions.push_back("GL_OES_primitive_bounding_box"); m_GLESExtensions.push_back("GL_EXT_copy_image"); m_GLESExtensions.push_back("GL_EXT_draw_buffers"); @@ -783,6 +787,7 @@ void WrappedOpenGL::BuildGLESExtensions() m_GLESExtensions.push_back("GL_EXT_shader_non_constant_global_initializers"); m_GLESExtensions.push_back("GL_EXT_shader_texture_lod"); m_GLESExtensions.push_back("GL_EXT_shadow_samplers"); + m_GLESExtensions.push_back("GL_EXT_primitive_bounding_box"); // we'll be sorting the implementation extension array, so make sure the // sorts are identical so we can do the intersection easily @@ -3836,6 +3841,7 @@ void WrappedOpenGL::ProcessChunk(uint64_t offset, GLChunkType context) Serialise_wglDXRegisterObjectNV(GLResource(MakeNullResource), eGL_NONE, NULL); break; case INTEROP_DATA: Serialise_wglDXLockObjectsNV(GLResource(MakeNullResource)); break; + case PRIMITIVE_BOUNDING_BOX: Serialise_glPrimitiveBoundingBox(0, 0, 0, 0, 0, 0, 0, 0); break; default: // ignore system chunks if((int)context == (int)INITIAL_CONTENTS) diff --git a/renderdoc/driver/gl/gl_driver.h b/renderdoc/driver/gl/gl_driver.h index f99e1c19e..5b8a93934 100644 --- a/renderdoc/driver/gl/gl_driver.h +++ b/renderdoc/driver/gl/gl_driver.h @@ -53,10 +53,10 @@ struct GLInitParams : public RDCInitParams uint32_t width; uint32_t height; - static const uint32_t GL_SERIALISE_VERSION = 0x0000014; + static const uint32_t GL_SERIALISE_VERSION = 0x0000015; // backwards compatibility for old logs described at the declaration of this array - static const uint32_t GL_NUM_SUPPORTED_OLD_VERSIONS = 4; + static const uint32_t GL_NUM_SUPPORTED_OLD_VERSIONS = 5; static const uint32_t GL_OLD_VERSIONS[GL_NUM_SUPPORTED_OLD_VERSIONS]; // version number internal to opengl stream @@ -352,7 +352,6 @@ private: ResourceId m_FakeVAOID; - uint32_t GetLogVersion() { return m_InitParams.SerialiseVersion; } void ProcessChunk(uint64_t offset, GLChunkType context); void ContextReplayLog(LogState readType, uint32_t startEventID, uint32_t endEventID, bool partial); void ContextProcessChunk(uint64_t offset, GLChunkType chunk); @@ -534,6 +533,7 @@ public: WrappedOpenGL(const char *logfile, const GLHookSet &funcs, GLPlatform &platform); virtual ~WrappedOpenGL(); + uint32_t GetLogVersion() { return m_InitParams.SerialiseVersion; } static const char *GetChunkName(uint32_t idx); GLResourceManager *GetResourceManager() { return m_ResourceManager; } ResourceId GetDeviceResourceID() { return m_DeviceResourceID; } @@ -2444,6 +2444,11 @@ public: BOOL wglDXObjectAccessNV(HANDLE hObject, GLenum access); BOOL wglDXLockObjectsNV(HANDLE hDevice, GLint count, HANDLE *hObjects); BOOL wglDXUnlockObjectsNV(HANDLE hDevice, GLint count, HANDLE *hObjects); + + IMPLEMENT_FUNCTION_SERIALISED(void, + glPrimitiveBoundingBox(GLfloat minX, GLfloat minY, GLfloat minZ, + GLfloat minW, GLfloat maxX, GLfloat maxY, + GLfloat maxZ, GLfloat maxW)); }; class ScopedDebugContext diff --git a/renderdoc/driver/gl/gl_hookset.h b/renderdoc/driver/gl/gl_hookset.h index 55730f9ce..fa548bd0b 100644 --- a/renderdoc/driver/gl/gl_hookset.h +++ b/renderdoc/driver/gl/gl_hookset.h @@ -603,6 +603,9 @@ struct GLHookSet PFNGLDRAWELEMENTSINDIRECTPROC glDrawElementsIndirect; PFNGLBLITFRAMEBUFFERPROC glBlitFramebuffer; // aliases glBlitFramebufferEXT + // GLES core + PFNGLPRIMITIVEBOUNDINGBOXEXTPROC glPrimitiveBoundingBox; // aliases glPrimitiveBoundingBoxEXT, glPrimitiveBoundingBoxOES + // ARB_shading_language_include PFNGLNAMEDSTRINGARBPROC glNamedStringARB; PFNGLDELETENAMEDSTRINGARBPROC glDeleteNamedStringARB; diff --git a/renderdoc/driver/gl/gl_hookset_defs.h b/renderdoc/driver/gl/gl_hookset_defs.h index e1625d2d6..0120d2710 100644 --- a/renderdoc/driver/gl/gl_hookset_defs.h +++ b/renderdoc/driver/gl/gl_hookset_defs.h @@ -1113,6 +1113,9 @@ HookExtension(PFNGLRASTERSAMPLESEXTPROC, glRasterSamplesEXT); \ HookExtension(PFNGLFRAMETERMINATORGREMEDYPROC, glFrameTerminatorGREMEDY); \ HookExtension(PFNGLSTRINGMARKERGREMEDYPROC, glStringMarkerGREMEDY); \ + HookExtension(PFNGLPRIMITIVEBOUNDINGBOXOESPROC, glPrimitiveBoundingBox); \ + HookExtensionAlias(PFNGLPRIMITIVEBOUNDINGBOXOESPROC, glPrimitiveBoundingBox, glPrimitiveBoundingBoxEXT); \ + HookExtensionAlias(PFNGLPRIMITIVEBOUNDINGBOXOESPROC, glPrimitiveBoundingBox, glPrimitiveBoundingBoxOES); \ HookExtension(PFNWGLDXSETRESOURCESHAREHANDLENVPROC, wglDXSetResourceShareHandleNV); \ HookExtension(PFNWGLDXOPENDEVICENVPROC, wglDXOpenDeviceNV); \ HookExtension(PFNWGLDXCLOSEDEVICENVPROC, wglDXCloseDeviceNV); \ @@ -1965,6 +1968,7 @@ HookWrapper2(void, glRasterSamplesEXT, GLuint, samples, GLboolean, fixedsamplelocations); \ HookWrapper0(void, glFrameTerminatorGREMEDY); \ HookWrapper2(void, glStringMarkerGREMEDY, GLsizei, len, const void *, string); \ + HookWrapper8(void, glPrimitiveBoundingBox, GLfloat, minX, GLfloat, minY, GLfloat, minZ, GLfloat, minW, GLfloat, maxX, GLfloat, maxY, GLfloat, maxZ, GLfloat, maxW); \ HookWrapper2(BOOL, wglDXSetResourceShareHandleNV, void *, dxObject, HANDLE, shareHandle); \ HookWrapper1(HANDLE, wglDXOpenDeviceNV, void *, dxDevice); \ HookWrapper1(BOOL, wglDXCloseDeviceNV, HANDLE, hDevice); \ @@ -3537,7 +3541,6 @@ HookWrapper4(void, glframebuffertextureoes, GLenum, target, GLenum, attachment, GLuint, texture, GLint, level); \ HookWrapper5(void, glgetprogrambinaryoes, GLuint, program, GLsizei, bufSize, GLsizei *, length, GLenum *, binaryFormat, void *, binary); \ HookWrapper4(void, glprogrambinaryoes, GLuint, program, GLenum, binaryFormat, const void *, binary, GLint, length); \ - HookWrapper8(void, glprimitiveboundingboxoes, GLfloat, minX, GLfloat, minY, GLfloat, minZ, GLfloat, minW, GLfloat, maxX, GLfloat, maxY, GLfloat, maxZ, GLfloat, maxW); \ HookWrapper1(void, glminsampleshadingoes, GLfloat, value); \ HookWrapper2(void, glpatchparameterioes, GLenum, pname, GLint, value); \ HookWrapper10(void, glteximage3does, GLenum, target, GLint, level, GLenum, internalformat, GLsizei, width, GLsizei, height, GLsizei, depth, GLint, border, GLenum, format, GLenum, type, const void *, pixels); \ @@ -3631,7 +3634,6 @@ HookWrapper2(void, glreadbufferindexedext, GLenum, src, GLint, index); \ HookWrapper3(void, gldrawbuffersindexedext, GLint, n, const GLenum *, location, const GLint *, indices); \ HookWrapper3(void, glgetintegeri_vext, GLenum, target, GLuint, index, GLint *, data); \ - HookWrapper8(void, glprimitiveboundingboxext, GLfloat, minX, GLfloat, minY, GLfloat, minZ, GLfloat, minW, GLfloat, maxX, GLfloat, maxY, GLfloat, maxZ, GLfloat, maxW); \ HookWrapper0(GLenum, glgetgraphicsresetstatusext); \ HookWrapper8(void, glreadnpixelsext, GLint, x, GLint, y, GLsizei, width, GLsizei, height, GLenum, format, GLenum, type, GLsizei, bufSize, void *, data); \ HookWrapper4(void, glgetnuniformfvext, GLuint, program, GLint, location, GLsizei, bufSize, GLfloat *, params); \ @@ -5567,7 +5569,6 @@ HandleUnsupported(PFNGLFRAMEBUFFERTEXTUREOESPROC, glframebuffertextureoes); \ HandleUnsupported(PFNGLGETPROGRAMBINARYOESPROC, glgetprogrambinaryoes); \ HandleUnsupported(PFNGLPROGRAMBINARYOESPROC, glprogrambinaryoes); \ - HandleUnsupported(PFNGLPRIMITIVEBOUNDINGBOXOESPROC, glprimitiveboundingboxoes); \ HandleUnsupported(PFNGLMINSAMPLESHADINGOESPROC, glminsampleshadingoes); \ HandleUnsupported(PFNGLPATCHPARAMETERIOESPROC, glpatchparameterioes); \ HandleUnsupported(PFNGLTEXIMAGE3DOESPROC, glteximage3does); \ @@ -5661,7 +5662,6 @@ HandleUnsupported(PFNGLREADBUFFERINDEXEDEXTPROC, glreadbufferindexedext); \ HandleUnsupported(PFNGLDRAWBUFFERSINDEXEDEXTPROC, gldrawbuffersindexedext); \ HandleUnsupported(PFNGLGETINTEGERI_VEXTPROC, glgetintegeri_vext); \ - HandleUnsupported(PFNGLPRIMITIVEBOUNDINGBOXEXTPROC, glprimitiveboundingboxext); \ HandleUnsupported(PFNGLGETGRAPHICSRESETSTATUSEXTPROC, glgetgraphicsresetstatusext); \ HandleUnsupported(PFNGLREADNPIXELSEXTPROC, glreadnpixelsext); \ HandleUnsupported(PFNGLGETNUNIFORMFVEXTPROC, glgetnuniformfvext); \ diff --git a/renderdoc/driver/gl/gl_renderstate.cpp b/renderdoc/driver/gl/gl_renderstate.cpp index 27542b169..6b1a6b921 100644 --- a/renderdoc/driver/gl/gl_renderstate.cpp +++ b/renderdoc/driver/gl/gl_renderstate.cpp @@ -1155,6 +1155,9 @@ void GLRenderState::FetchState(void *ctx, WrappedOpenGL *gl) m_Real->glGetIntegerv(eGL_FRONT_FACE, (GLint *)&FrontFace); m_Real->glGetIntegerv(eGL_CULL_FACE_MODE, (GLint *)&CullFace); + if(IsGLES && (HasExt[EXT_primitive_bounding_box] || HasExt[OES_primitive_bounding_box])) + m_Real->glGetFloatv(eGL_PRIMITIVE_BOUNDING_BOX_EXT, (GLfloat *)&PrimitiveBoundingBox); + Unpack.Fetch(m_Real, true); ClearGLErrors(*m_Real); @@ -1516,6 +1519,12 @@ void GLRenderState::ApplyState(void *ctx, WrappedOpenGL *gl) m_Real->glFrontFace(FrontFace); m_Real->glCullFace(CullFace); + if(IsGLES && (HasExt[EXT_primitive_bounding_box] || HasExt[OES_primitive_bounding_box])) + m_Real->glPrimitiveBoundingBox(PrimitiveBoundingBox.minX, PrimitiveBoundingBox.minY, + PrimitiveBoundingBox.minZ, PrimitiveBoundingBox.minW, + PrimitiveBoundingBox.maxX, PrimitiveBoundingBox.maxY, + PrimitiveBoundingBox.maxZ, PrimitiveBoundingBox.maxW); + Unpack.Apply(m_Real, true); ClearGLErrors(*m_Real); @@ -1564,6 +1573,7 @@ void GLRenderState::Clear() RDCEraseEl(PointSize); RDCEraseEl(PrimitiveRestartIndex); + RDCEraseEl(PrimitiveBoundingBox); RDCEraseEl(ClipOrigin); RDCEraseEl(ClipDepth); RDCEraseEl(ProvokingVertex); @@ -1938,4 +1948,16 @@ void GLRenderState::Serialise(LogState state, void *ctx, WrappedOpenGL *gl) m_pSerialiser->Serialise("GL_UNPACK_COMPRESSED_BLOCK_HEIGHT", Unpack.compressedBlockHeight); m_pSerialiser->Serialise("GL_UNPACK_COMPRESSED_BLOCK_DEPTH", Unpack.compressedBlockDepth); m_pSerialiser->Serialise("GL_UNPACK_COMPRESSED_BLOCK_SIZE", Unpack.compressedBlockSize); + + if(IsGLES && gl->GetLogVersion() >= 0x000015) + { + m_pSerialiser->Serialise("GL_PRIMITIVE_BOUNDING_BOX_MINX", PrimitiveBoundingBox.minX); + m_pSerialiser->Serialise("GL_PRIMITIVE_BOUNDING_BOX_MINY", PrimitiveBoundingBox.minY); + m_pSerialiser->Serialise("GL_PRIMITIVE_BOUNDING_BOX_MINZ", PrimitiveBoundingBox.minZ); + m_pSerialiser->Serialise("GL_PRIMITIVE_BOUNDING_BOX_MINW", PrimitiveBoundingBox.minW); + m_pSerialiser->Serialise("GL_PRIMITIVE_BOUNDING_BOX_MAXX", PrimitiveBoundingBox.maxX); + m_pSerialiser->Serialise("GL_PRIMITIVE_BOUNDING_BOX_MAXY", PrimitiveBoundingBox.maxY); + m_pSerialiser->Serialise("GL_PRIMITIVE_BOUNDING_BOX_MAXZ", PrimitiveBoundingBox.maxZ); + m_pSerialiser->Serialise("GL_PRIMITIVE_BOUNDING_BOX_MAXW", PrimitiveBoundingBox.maxW); + } } diff --git a/renderdoc/driver/gl/gl_renderstate.h b/renderdoc/driver/gl/gl_renderstate.h index 204764b55..6def1ca2e 100644 --- a/renderdoc/driver/gl/gl_renderstate.h +++ b/renderdoc/driver/gl/gl_renderstate.h @@ -185,6 +185,13 @@ struct GLRenderState float PointSize; uint32_t PrimitiveRestartIndex; + + struct BoundingBox + { + float minX, minY, minZ, minW; + float maxX, maxY, maxZ, maxW; + } PrimitiveBoundingBox; + GLenum ClipOrigin, ClipDepth; GLenum ProvokingVertex; diff --git a/renderdoc/driver/gl/wrappers/gl_draw_funcs.cpp b/renderdoc/driver/gl/wrappers/gl_draw_funcs.cpp index d9d57fef1..73fabd3bf 100644 --- a/renderdoc/driver/gl/wrappers/gl_draw_funcs.cpp +++ b/renderdoc/driver/gl/wrappers/gl_draw_funcs.cpp @@ -4078,3 +4078,37 @@ void WrappedOpenGL::glClearTexSubImage(GLuint texture, GLint level, GLint xoffse GetResourceManager()->MarkDirtyResource(TextureRes(GetCtx(), texture)); } } + +bool WrappedOpenGL::Serialise_glPrimitiveBoundingBox(GLfloat minX, GLfloat minY, GLfloat minZ, + GLfloat minW, GLfloat maxX, GLfloat maxY, + GLfloat maxZ, GLfloat maxW) +{ + SERIALISE_ELEMENT(float, MinX, minX); + SERIALISE_ELEMENT(float, MinY, minY); + SERIALISE_ELEMENT(float, MinZ, minZ); + SERIALISE_ELEMENT(float, MinW, minW); + SERIALISE_ELEMENT(float, MaxX, maxX); + SERIALISE_ELEMENT(float, MaxY, maxY); + SERIALISE_ELEMENT(float, MaxZ, maxZ); + SERIALISE_ELEMENT(float, MaxW, maxW); + + if(m_State <= EXECUTING) + { + m_Real.glPrimitiveBoundingBox(MinX, MinY, MinZ, MinW, MaxX, MaxY, MaxZ, MaxW); + } + + return true; +} + +void WrappedOpenGL::glPrimitiveBoundingBox(GLfloat minX, GLfloat minY, GLfloat minZ, GLfloat minW, + GLfloat maxX, GLfloat maxY, GLfloat maxZ, GLfloat maxW) +{ + m_Real.glPrimitiveBoundingBox(minX, minY, minZ, minW, maxX, maxY, maxZ, maxW); + + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(PRIMITIVE_BOUNDING_BOX); + Serialise_glPrimitiveBoundingBox(minX, minY, minZ, minW, maxX, maxY, maxZ, maxW); + m_ContextRecord->AddChunk(scope.Get()); + } +}