From eaa763d748e833878abbf10714f10bb670d9a911 Mon Sep 17 00:00:00 2001 From: baldurk Date: Mon, 13 Aug 2018 17:50:57 +0100 Subject: [PATCH] Add support for GL_external_objects family of extensions * This allows sharing between Vulkan and GL. --- renderdoc/driver/gl/gl_common.h | 35 + renderdoc/driver/gl/gl_dispatch_table.h | 42 + renderdoc/driver/gl/gl_dispatch_table_defs.h | 136 +- renderdoc/driver/gl/gl_driver.cpp | 67 +- renderdoc/driver/gl/gl_driver.h | 74 + renderdoc/driver/gl/gl_resources.cpp | 2 + renderdoc/driver/gl/gl_resources.h | 10 + renderdoc/driver/gl/wrappers/gl_get_funcs.cpp | 30 + .../driver/gl/wrappers/gl_interop_funcs.cpp | 1491 ++++++++++++++++- 9 files changed, 1816 insertions(+), 71 deletions(-) diff --git a/renderdoc/driver/gl/gl_common.h b/renderdoc/driver/gl/gl_common.h index 9eca0fe21..da6ae6ccc 100644 --- a/renderdoc/driver/gl/gl_common.h +++ b/renderdoc/driver/gl/gl_common.h @@ -1993,6 +1993,41 @@ enum class GLChunk : uint32_t glUniformMatrix3fvARB, glUniformMatrix4fvARB, + glGetUnsignedBytevEXT, + glGetUnsignedBytei_vEXT, + glDeleteMemoryObjectsEXT, + glIsMemoryObjectEXT, + glCreateMemoryObjectsEXT, + glMemoryObjectParameterivEXT, + glGetMemoryObjectParameterivEXT, + glTexStorageMem2DEXT, + glTexStorageMem2DMultisampleEXT, + glTexStorageMem3DEXT, + glTexStorageMem3DMultisampleEXT, + glBufferStorageMemEXT, + glTextureStorageMem2DEXT, + glTextureStorageMem2DMultisampleEXT, + glTextureStorageMem3DEXT, + glTextureStorageMem3DMultisampleEXT, + glNamedBufferStorageMemEXT, + glTexStorageMem1DEXT, + glTextureStorageMem1DEXT, + glGenSemaphoresEXT, + glDeleteSemaphoresEXT, + glIsSemaphoreEXT, + glSemaphoreParameterui64vEXT, + glGetSemaphoreParameterui64vEXT, + glWaitSemaphoreEXT, + glSignalSemaphoreEXT, + glImportMemoryFdEXT, + glImportSemaphoreFdEXT, + glImportMemoryWin32HandleEXT, + glImportMemoryWin32NameEXT, + glImportSemaphoreWin32HandleEXT, + glImportSemaphoreWin32NameEXT, + glAcquireKeyedMutexWin32EXT, + glReleaseKeyedMutexWin32EXT, + Max, }; diff --git a/renderdoc/driver/gl/gl_dispatch_table.h b/renderdoc/driver/gl/gl_dispatch_table.h index db01b2fcd..62258b463 100644 --- a/renderdoc/driver/gl/gl_dispatch_table.h +++ b/renderdoc/driver/gl/gl_dispatch_table.h @@ -672,6 +672,48 @@ struct GLDispatchTable // ARB_gl_spirv PFNGLSPECIALIZESHADERPROC glSpecializeShader; // aliases glSpecializeShaderARB + // EXT_external_objects + PFNGLGETUNSIGNEDBYTEVEXTPROC glGetUnsignedBytevEXT; + PFNGLGETUNSIGNEDBYTEI_VEXTPROC glGetUnsignedBytei_vEXT; + PFNGLDELETEMEMORYOBJECTSEXTPROC glDeleteMemoryObjectsEXT; + PFNGLISMEMORYOBJECTEXTPROC glIsMemoryObjectEXT; + PFNGLCREATEMEMORYOBJECTSEXTPROC glCreateMemoryObjectsEXT; + PFNGLMEMORYOBJECTPARAMETERIVEXTPROC glMemoryObjectParameterivEXT; + PFNGLGETMEMORYOBJECTPARAMETERIVEXTPROC glGetMemoryObjectParameterivEXT; + PFNGLTEXSTORAGEMEM2DEXTPROC glTexStorageMem2DEXT; + PFNGLTEXSTORAGEMEM2DMULTISAMPLEEXTPROC glTexStorageMem2DMultisampleEXT; + PFNGLTEXSTORAGEMEM3DEXTPROC glTexStorageMem3DEXT; + PFNGLTEXSTORAGEMEM3DMULTISAMPLEEXTPROC glTexStorageMem3DMultisampleEXT; + PFNGLBUFFERSTORAGEMEMEXTPROC glBufferStorageMemEXT; + PFNGLTEXTURESTORAGEMEM2DEXTPROC glTextureStorageMem2DEXT; + PFNGLTEXTURESTORAGEMEM2DMULTISAMPLEEXTPROC glTextureStorageMem2DMultisampleEXT; + PFNGLTEXTURESTORAGEMEM3DEXTPROC glTextureStorageMem3DEXT; + PFNGLTEXTURESTORAGEMEM3DMULTISAMPLEEXTPROC glTextureStorageMem3DMultisampleEXT; + PFNGLNAMEDBUFFERSTORAGEMEMEXTPROC glNamedBufferStorageMemEXT; + PFNGLTEXSTORAGEMEM1DEXTPROC glTexStorageMem1DEXT; + PFNGLTEXTURESTORAGEMEM1DEXTPROC glTextureStorageMem1DEXT; + PFNGLGENSEMAPHORESEXTPROC glGenSemaphoresEXT; + PFNGLDELETESEMAPHORESEXTPROC glDeleteSemaphoresEXT; + PFNGLISSEMAPHOREEXTPROC glIsSemaphoreEXT; + PFNGLSEMAPHOREPARAMETERUI64VEXTPROC glSemaphoreParameterui64vEXT; + PFNGLGETSEMAPHOREPARAMETERUI64VEXTPROC glGetSemaphoreParameterui64vEXT; + PFNGLWAITSEMAPHOREEXTPROC glWaitSemaphoreEXT; + PFNGLSIGNALSEMAPHOREEXTPROC glSignalSemaphoreEXT; + + // EXT_external_objects_fd + PFNGLIMPORTMEMORYFDEXTPROC glImportMemoryFdEXT; + PFNGLIMPORTSEMAPHOREFDEXTPROC glImportSemaphoreFdEXT; + + // EXT_external_objects_win32 + PFNGLIMPORTMEMORYWIN32HANDLEEXTPROC glImportMemoryWin32HandleEXT; + PFNGLIMPORTMEMORYWIN32NAMEEXTPROC glImportMemoryWin32NameEXT; + PFNGLIMPORTSEMAPHOREWIN32HANDLEEXTPROC glImportSemaphoreWin32HandleEXT; + PFNGLIMPORTSEMAPHOREWIN32NAMEEXTPROC glImportSemaphoreWin32NameEXT; + + // EXT_win32_keyed_mutex + PFNGLACQUIREKEYEDMUTEXWIN32EXTPROC glAcquireKeyedMutexWin32EXT; + PFNGLRELEASEKEYEDMUTEXWIN32EXTPROC glReleaseKeyedMutexWin32EXT; + // EXT_direct_state_access below here. We only include the functions relevant for core 3.2+ GL, // not any functions for legacy functionality. // diff --git a/renderdoc/driver/gl/gl_dispatch_table_defs.h b/renderdoc/driver/gl/gl_dispatch_table_defs.h index 46d645ea8..7251ffe24 100644 --- a/renderdoc/driver/gl/gl_dispatch_table_defs.h +++ b/renderdoc/driver/gl/gl_dispatch_table_defs.h @@ -1010,6 +1010,40 @@ FUNC(glMaxShaderCompilerThreadsKHR, glMaxShaderCompilerThreadsARB); \ FUNC(glSpecializeShader, glSpecializeShader); \ FUNC(glSpecializeShader, glSpecializeShaderARB); \ + FUNC(glGetUnsignedBytevEXT, glGetUnsignedBytevEXT); \ + FUNC(glGetUnsignedBytei_vEXT, glGetUnsignedBytei_vEXT); \ + FUNC(glDeleteMemoryObjectsEXT, glDeleteMemoryObjectsEXT); \ + FUNC(glIsMemoryObjectEXT, glIsMemoryObjectEXT); \ + FUNC(glCreateMemoryObjectsEXT, glCreateMemoryObjectsEXT); \ + FUNC(glMemoryObjectParameterivEXT, glMemoryObjectParameterivEXT); \ + FUNC(glGetMemoryObjectParameterivEXT, glGetMemoryObjectParameterivEXT); \ + FUNC(glTexStorageMem2DEXT, glTexStorageMem2DEXT); \ + FUNC(glTexStorageMem2DMultisampleEXT, glTexStorageMem2DMultisampleEXT); \ + FUNC(glTexStorageMem3DEXT, glTexStorageMem3DEXT); \ + FUNC(glTexStorageMem3DMultisampleEXT, glTexStorageMem3DMultisampleEXT); \ + FUNC(glBufferStorageMemEXT, glBufferStorageMemEXT); \ + FUNC(glTextureStorageMem2DEXT, glTextureStorageMem2DEXT); \ + FUNC(glTextureStorageMem2DMultisampleEXT, glTextureStorageMem2DMultisampleEXT); \ + FUNC(glTextureStorageMem3DEXT, glTextureStorageMem3DEXT); \ + FUNC(glTextureStorageMem3DMultisampleEXT, glTextureStorageMem3DMultisampleEXT); \ + FUNC(glNamedBufferStorageMemEXT, glNamedBufferStorageMemEXT); \ + FUNC(glTexStorageMem1DEXT, glTexStorageMem1DEXT); \ + FUNC(glTextureStorageMem1DEXT, glTextureStorageMem1DEXT); \ + FUNC(glGenSemaphoresEXT, glGenSemaphoresEXT); \ + FUNC(glDeleteSemaphoresEXT, glDeleteSemaphoresEXT); \ + FUNC(glIsSemaphoreEXT, glIsSemaphoreEXT); \ + FUNC(glSemaphoreParameterui64vEXT, glSemaphoreParameterui64vEXT); \ + FUNC(glGetSemaphoreParameterui64vEXT, glGetSemaphoreParameterui64vEXT); \ + FUNC(glWaitSemaphoreEXT, glWaitSemaphoreEXT); \ + FUNC(glSignalSemaphoreEXT, glSignalSemaphoreEXT); \ + FUNC(glImportMemoryFdEXT, glImportMemoryFdEXT); \ + FUNC(glImportSemaphoreFdEXT, glImportSemaphoreFdEXT); \ + FUNC(glImportMemoryWin32HandleEXT, glImportMemoryWin32HandleEXT); \ + FUNC(glImportMemoryWin32NameEXT, glImportMemoryWin32NameEXT); \ + FUNC(glImportSemaphoreWin32HandleEXT, glImportSemaphoreWin32HandleEXT); \ + FUNC(glImportSemaphoreWin32NameEXT, glImportSemaphoreWin32NameEXT); \ + FUNC(glAcquireKeyedMutexWin32EXT, glAcquireKeyedMutexWin32EXT); \ + FUNC(glReleaseKeyedMutexWin32EXT, glReleaseKeyedMutexWin32EXT); \ FUNC(glCompressedTextureImage1DEXT, glCompressedTextureImage1DEXT); \ FUNC(glCompressedTextureImage2DEXT, glCompressedTextureImage2DEXT); \ FUNC(glCompressedTextureImage3DEXT, glCompressedTextureImage3DEXT); \ @@ -2223,6 +2257,40 @@ AliasWrapper1(void, glMaxShaderCompilerThreadsARB, glMaxShaderCompilerThreadsKHR, GLuint, count); \ FuncWrapper5(void, glSpecializeShader, GLuint, shader, const GLchar *, pEntryPoint, GLuint, numSpecializationConstants, const GLuint *, pConstantIndex, const GLuint *, pConstantValue); \ AliasWrapper5(void, glSpecializeShaderARB, glSpecializeShader, GLuint, shader, const GLchar *, pEntryPoint, GLuint, numSpecializationConstants, const GLuint *, pConstantIndex, const GLuint *, pConstantValue); \ + FuncWrapper2(void, glGetUnsignedBytevEXT, GLenum, pname, GLubyte *, data); \ + FuncWrapper3(void, glGetUnsignedBytei_vEXT, GLenum, target, GLuint, index, GLubyte *, data); \ + FuncWrapper2(void, glDeleteMemoryObjectsEXT, GLsizei, n, const GLuint *, memoryObjects); \ + FuncWrapper1(GLboolean, glIsMemoryObjectEXT, GLuint, memoryObject); \ + FuncWrapper2(void, glCreateMemoryObjectsEXT, GLsizei, n, GLuint *, memoryObjects); \ + FuncWrapper3(void, glMemoryObjectParameterivEXT, GLuint, memoryObject, GLenum, pname, const GLint *, params); \ + FuncWrapper3(void, glGetMemoryObjectParameterivEXT, GLuint, memoryObject, GLenum, pname, GLint *, params); \ + FuncWrapper7(void, glTexStorageMem2DEXT, GLenum, target, GLsizei, levels, GLenum, internalFormat, GLsizei, width, GLsizei, height, GLuint, memory, GLuint64, offset); \ + FuncWrapper8(void, glTexStorageMem2DMultisampleEXT, GLenum, target, GLsizei, samples, GLenum, internalFormat, GLsizei, width, GLsizei, height, GLboolean, fixedSampleLocations, GLuint, memory, GLuint64, offset); \ + FuncWrapper8(void, glTexStorageMem3DEXT, GLenum, target, GLsizei, levels, GLenum, internalFormat, GLsizei, width, GLsizei, height, GLsizei, depth, GLuint, memory, GLuint64, offset); \ + FuncWrapper9(void, glTexStorageMem3DMultisampleEXT, GLenum, target, GLsizei, samples, GLenum, internalFormat, GLsizei, width, GLsizei, height, GLsizei, depth, GLboolean, fixedSampleLocations, GLuint, memory, GLuint64, offset); \ + FuncWrapper4(void, glBufferStorageMemEXT, GLenum, target, GLsizeiptr, size, GLuint, memory, GLuint64, offset); \ + FuncWrapper7(void, glTextureStorageMem2DEXT, GLuint, texture, GLsizei, levels, GLenum, internalFormat, GLsizei, width, GLsizei, height, GLuint, memory, GLuint64, offset); \ + FuncWrapper8(void, glTextureStorageMem2DMultisampleEXT, GLuint, texture, GLsizei, samples, GLenum, internalFormat, GLsizei, width, GLsizei, height, GLboolean, fixedSampleLocations, GLuint, memory, GLuint64, offset); \ + FuncWrapper8(void, glTextureStorageMem3DEXT, GLuint, texture, GLsizei, levels, GLenum, internalFormat, GLsizei, width, GLsizei, height, GLsizei, depth, GLuint, memory, GLuint64, offset); \ + FuncWrapper9(void, glTextureStorageMem3DMultisampleEXT, GLuint, texture, GLsizei, samples, GLenum, internalFormat, GLsizei, width, GLsizei, height, GLsizei, depth, GLboolean, fixedSampleLocations, GLuint, memory, GLuint64, offset); \ + FuncWrapper4(void, glNamedBufferStorageMemEXT, GLuint, buffer, GLsizeiptr, size, GLuint, memory, GLuint64, offset); \ + FuncWrapper6(void, glTexStorageMem1DEXT, GLenum, target, GLsizei, levels, GLenum, internalFormat, GLsizei, width, GLuint, memory, GLuint64, offset); \ + FuncWrapper6(void, glTextureStorageMem1DEXT, GLuint, texture, GLsizei, levels, GLenum, internalFormat, GLsizei, width, GLuint, memory, GLuint64, offset); \ + FuncWrapper2(void, glGenSemaphoresEXT, GLsizei, n, GLuint *, semaphores); \ + FuncWrapper2(void, glDeleteSemaphoresEXT, GLsizei, n, const GLuint *, semaphores); \ + FuncWrapper1(GLboolean, glIsSemaphoreEXT, GLuint, semaphore); \ + FuncWrapper3(void, glSemaphoreParameterui64vEXT, GLuint, semaphore, GLenum, pname, const GLuint64 *, params); \ + FuncWrapper3(void, glGetSemaphoreParameterui64vEXT, GLuint, semaphore, GLenum, pname, GLuint64 *, params); \ + FuncWrapper6(void, glWaitSemaphoreEXT, GLuint, semaphore, GLuint, numBufferBarriers, const GLuint *, buffers, GLuint, numTextureBarriers, const GLuint *, textures, const GLenum *, srcLayouts); \ + FuncWrapper6(void, glSignalSemaphoreEXT, GLuint, semaphore, GLuint, numBufferBarriers, const GLuint *, buffers, GLuint, numTextureBarriers, const GLuint *, textures, const GLenum *, dstLayouts); \ + FuncWrapper4(void, glImportMemoryFdEXT, GLuint, memory, GLuint64, size, GLenum, handleType, GLint, fd); \ + FuncWrapper3(void, glImportSemaphoreFdEXT, GLuint, semaphore, GLenum, handleType, GLint, fd); \ + FuncWrapper4(void, glImportMemoryWin32HandleEXT, GLuint, memory, GLuint64, size, GLenum, handleType, void *, handle); \ + FuncWrapper4(void, glImportMemoryWin32NameEXT, GLuint, memory, GLuint64, size, GLenum, handleType, const void *, name); \ + FuncWrapper3(void, glImportSemaphoreWin32HandleEXT, GLuint, semaphore, GLenum, handleType, void *, handle); \ + FuncWrapper3(void, glImportSemaphoreWin32NameEXT, GLuint, semaphore, GLenum, handleType, const void *, name); \ + FuncWrapper3(GLboolean, glAcquireKeyedMutexWin32EXT, GLuint, memory, GLuint64, key, GLuint, timeout); \ + FuncWrapper2(GLboolean, glReleaseKeyedMutexWin32EXT, GLuint, memory, GLuint64, key); \ FuncWrapper8(void, glCompressedTextureImage1DEXT, GLuint, texture, GLenum, target, GLint, level, GLenum, internalformat, GLsizei, width, GLint, border, GLsizei, imageSize, const void *, bits); \ FuncWrapper9(void, glCompressedTextureImage2DEXT, GLuint, texture, GLenum, target, GLint, level, GLenum, internalformat, GLsizei, width, GLsizei, height, GLint, border, GLsizei, imageSize, const void *, bits); \ FuncWrapper10(void, glCompressedTextureImage3DEXT, GLuint, texture, GLenum, target, GLint, level, GLenum, internalformat, GLsizei, width, GLsizei, height, GLsizei, depth, GLint, border, GLsizei, imageSize, const void *, bits); \ @@ -3449,28 +3517,6 @@ FUNC(glApplyTextureEXT); \ FUNC(glTextureLightEXT); \ FUNC(glTextureMaterialEXT); \ - FUNC(glGetUnsignedBytevEXT); \ - FUNC(glGetUnsignedBytei_vEXT); \ - FUNC(glDeleteMemoryObjectsEXT); \ - FUNC(glIsMemoryObjectEXT); \ - FUNC(glCreateMemoryObjectsEXT); \ - FUNC(glMemoryObjectParameterivEXT); \ - FUNC(glGetMemoryObjectParameterivEXT); \ - FUNC(glTexStorageMem2DEXT); \ - FUNC(glTexStorageMem2DMultisampleEXT); \ - FUNC(glTexStorageMem3DEXT); \ - FUNC(glTexStorageMem3DMultisampleEXT); \ - FUNC(glBufferStorageMemEXT); \ - FUNC(glTextureStorageMem2DEXT); \ - FUNC(glTextureStorageMem2DMultisampleEXT); \ - FUNC(glTextureStorageMem3DEXT); \ - FUNC(glTextureStorageMem3DMultisampleEXT); \ - FUNC(glNamedBufferStorageMemEXT); \ - FUNC(glTexStorageMem1DEXT); \ - FUNC(glTextureStorageMem1DEXT); \ - FUNC(glImportMemoryFdEXT); \ - FUNC(glImportMemoryWin32HandleEXT); \ - FUNC(glImportMemoryWin32NameEXT); \ FUNC(glMultiDrawElementsEXT); \ FUNC(glSampleMaskEXT); \ FUNC(glSamplePatternEXT); \ @@ -3502,16 +3548,6 @@ FUNC(glSecondaryColor3usEXT); \ FUNC(glSecondaryColor3usvEXT); \ FUNC(glSecondaryColorPointerEXT); \ - FUNC(glGenSemaphoresEXT); \ - FUNC(glDeleteSemaphoresEXT); \ - FUNC(glIsSemaphoreEXT); \ - FUNC(glSemaphoreParameterui64vEXT); \ - FUNC(glGetSemaphoreParameterui64vEXT); \ - FUNC(glWaitSemaphoreEXT); \ - FUNC(glSignalSemaphoreEXT); \ - FUNC(glImportSemaphoreFdEXT); \ - FUNC(glImportSemaphoreWin32HandleEXT); \ - FUNC(glImportSemaphoreWin32NameEXT); \ FUNC(glStencilClearTagEXT); \ FUNC(glActiveStencilFaceEXT); \ FUNC(glTexSubImage1DEXT); \ @@ -3581,8 +3617,6 @@ FUNC(glVertexWeightfEXT); \ FUNC(glVertexWeightfvEXT); \ FUNC(glVertexWeightPointerEXT); \ - FUNC(glAcquireKeyedMutexWin32EXT); \ - FUNC(glReleaseKeyedMutexWin32EXT); \ FUNC(glImportSyncEXT); \ FUNC(glImageTransformParameteriHP); \ FUNC(glImageTransformParameterfHP); \ @@ -5408,28 +5442,6 @@ UnsupportedWrapper1(void, glApplyTextureEXT, GLenum, mode); \ UnsupportedWrapper1(void, glTextureLightEXT, GLenum, pname); \ UnsupportedWrapper2(void, glTextureMaterialEXT, GLenum, face, GLenum, mode); \ - UnsupportedWrapper2(void, glGetUnsignedBytevEXT, GLenum, pname, GLubyte *, data); \ - UnsupportedWrapper3(void, glGetUnsignedBytei_vEXT, GLenum, target, GLuint, index, GLubyte *, data); \ - UnsupportedWrapper2(void, glDeleteMemoryObjectsEXT, GLsizei, n, const GLuint *, memoryObjects); \ - UnsupportedWrapper1(GLboolean, glIsMemoryObjectEXT, GLuint, memoryObject); \ - UnsupportedWrapper2(void, glCreateMemoryObjectsEXT, GLsizei, n, GLuint *, memoryObjects); \ - UnsupportedWrapper3(void, glMemoryObjectParameterivEXT, GLuint, memoryObject, GLenum, pname, const GLint *, params); \ - UnsupportedWrapper3(void, glGetMemoryObjectParameterivEXT, GLuint, memoryObject, GLenum, pname, GLint *, params); \ - UnsupportedWrapper7(void, glTexStorageMem2DEXT, GLenum, target, GLsizei, levels, GLenum, internalFormat, GLsizei, width, GLsizei, height, GLuint, memory, GLuint64, offset); \ - UnsupportedWrapper8(void, glTexStorageMem2DMultisampleEXT, GLenum, target, GLsizei, samples, GLenum, internalFormat, GLsizei, width, GLsizei, height, GLboolean, fixedSampleLocations, GLuint, memory, GLuint64, offset); \ - UnsupportedWrapper8(void, glTexStorageMem3DEXT, GLenum, target, GLsizei, levels, GLenum, internalFormat, GLsizei, width, GLsizei, height, GLsizei, depth, GLuint, memory, GLuint64, offset); \ - UnsupportedWrapper9(void, glTexStorageMem3DMultisampleEXT, GLenum, target, GLsizei, samples, GLenum, internalFormat, GLsizei, width, GLsizei, height, GLsizei, depth, GLboolean, fixedSampleLocations, GLuint, memory, GLuint64, offset); \ - UnsupportedWrapper4(void, glBufferStorageMemEXT, GLenum, target, GLsizeiptr, size, GLuint, memory, GLuint64, offset); \ - UnsupportedWrapper7(void, glTextureStorageMem2DEXT, GLuint, texture, GLsizei, levels, GLenum, internalFormat, GLsizei, width, GLsizei, height, GLuint, memory, GLuint64, offset); \ - UnsupportedWrapper8(void, glTextureStorageMem2DMultisampleEXT, GLuint, texture, GLsizei, samples, GLenum, internalFormat, GLsizei, width, GLsizei, height, GLboolean, fixedSampleLocations, GLuint, memory, GLuint64, offset); \ - UnsupportedWrapper8(void, glTextureStorageMem3DEXT, GLuint, texture, GLsizei, levels, GLenum, internalFormat, GLsizei, width, GLsizei, height, GLsizei, depth, GLuint, memory, GLuint64, offset); \ - UnsupportedWrapper9(void, glTextureStorageMem3DMultisampleEXT, GLuint, texture, GLsizei, samples, GLenum, internalFormat, GLsizei, width, GLsizei, height, GLsizei, depth, GLboolean, fixedSampleLocations, GLuint, memory, GLuint64, offset); \ - UnsupportedWrapper4(void, glNamedBufferStorageMemEXT, GLuint, buffer, GLsizeiptr, size, GLuint, memory, GLuint64, offset); \ - UnsupportedWrapper6(void, glTexStorageMem1DEXT, GLenum, target, GLsizei, levels, GLenum, internalFormat, GLsizei, width, GLuint, memory, GLuint64, offset); \ - UnsupportedWrapper6(void, glTextureStorageMem1DEXT, GLuint, texture, GLsizei, levels, GLenum, internalFormat, GLsizei, width, GLuint, memory, GLuint64, offset); \ - UnsupportedWrapper4(void, glImportMemoryFdEXT, GLuint, memory, GLuint64, size, GLenum, handleType, GLint, fd); \ - UnsupportedWrapper4(void, glImportMemoryWin32HandleEXT, GLuint, memory, GLuint64, size, GLenum, handleType, void *, handle); \ - UnsupportedWrapper4(void, glImportMemoryWin32NameEXT, GLuint, memory, GLuint64, size, GLenum, handleType, const void *, name); \ UnsupportedWrapper5(void, glMultiDrawElementsEXT, GLenum, mode, const GLsizei *, count, GLenum, type, const void *const*, indices, GLsizei, primcount); \ UnsupportedWrapper2(void, glSampleMaskEXT, GLclampf, value, GLboolean, invert); \ UnsupportedWrapper1(void, glSamplePatternEXT, GLenum, pattern); \ @@ -5461,16 +5473,6 @@ UnsupportedWrapper3(void, glSecondaryColor3usEXT, GLushort, red, GLushort, green, GLushort, blue); \ UnsupportedWrapper1(void, glSecondaryColor3usvEXT, const GLushort *, v); \ UnsupportedWrapper4(void, glSecondaryColorPointerEXT, GLint, size, GLenum, type, GLsizei, stride, const void *, pointer); \ - UnsupportedWrapper2(void, glGenSemaphoresEXT, GLsizei, n, GLuint *, semaphores); \ - UnsupportedWrapper2(void, glDeleteSemaphoresEXT, GLsizei, n, const GLuint *, semaphores); \ - UnsupportedWrapper1(GLboolean, glIsSemaphoreEXT, GLuint, semaphore); \ - UnsupportedWrapper3(void, glSemaphoreParameterui64vEXT, GLuint, semaphore, GLenum, pname, const GLuint64 *, params); \ - UnsupportedWrapper3(void, glGetSemaphoreParameterui64vEXT, GLuint, semaphore, GLenum, pname, GLuint64 *, params); \ - UnsupportedWrapper6(void, glWaitSemaphoreEXT, GLuint, semaphore, GLuint, numBufferBarriers, const GLuint *, buffers, GLuint, numTextureBarriers, const GLuint *, textures, const GLenum *, srcLayouts); \ - UnsupportedWrapper6(void, glSignalSemaphoreEXT, GLuint, semaphore, GLuint, numBufferBarriers, const GLuint *, buffers, GLuint, numTextureBarriers, const GLuint *, textures, const GLenum *, dstLayouts); \ - UnsupportedWrapper3(void, glImportSemaphoreFdEXT, GLuint, semaphore, GLenum, handleType, GLint, fd); \ - UnsupportedWrapper3(void, glImportSemaphoreWin32HandleEXT, GLuint, semaphore, GLenum, handleType, void *, handle); \ - UnsupportedWrapper3(void, glImportSemaphoreWin32NameEXT, GLuint, semaphore, GLenum, handleType, const void *, name); \ UnsupportedWrapper2(void, glStencilClearTagEXT, GLsizei, stencilTagBits, GLuint, stencilClearTag); \ UnsupportedWrapper1(void, glActiveStencilFaceEXT, GLenum, face); \ UnsupportedWrapper7(void, glTexSubImage1DEXT, GLenum, target, GLint, level, GLint, xoffset, GLsizei, width, GLenum, format, GLenum, type, const void *, pixels); \ @@ -5540,8 +5542,6 @@ UnsupportedWrapper1(void, glVertexWeightfEXT, GLfloat, weight); \ UnsupportedWrapper1(void, glVertexWeightfvEXT, const GLfloat *, weight); \ UnsupportedWrapper4(void, glVertexWeightPointerEXT, GLint, size, GLenum, type, GLsizei, stride, const void *, pointer); \ - UnsupportedWrapper3(GLboolean, glAcquireKeyedMutexWin32EXT, GLuint, memory, GLuint64, key, GLuint, timeout); \ - UnsupportedWrapper2(GLboolean, glReleaseKeyedMutexWin32EXT, GLuint, memory, GLuint64, key); \ UnsupportedWrapper3(GLsync, glImportSyncEXT, GLenum, external_sync_type, GLintptr, external_sync, GLbitfield, flags); \ UnsupportedWrapper3(void, glImageTransformParameteriHP, GLenum, target, GLenum, pname, GLint, param); \ UnsupportedWrapper3(void, glImageTransformParameterfHP, GLenum, target, GLenum, pname, GLfloat, param); \ diff --git a/renderdoc/driver/gl/gl_driver.cpp b/renderdoc/driver/gl/gl_driver.cpp index 564ecae88..286d85f0a 100644 --- a/renderdoc/driver/gl/gl_driver.cpp +++ b/renderdoc/driver/gl/gl_driver.cpp @@ -201,6 +201,9 @@ void WrappedOpenGL::BuildGLExtensions() m_GLExtensions.push_back("GL_EXT_framebuffer_object"); m_GLExtensions.push_back("GL_EXT_framebuffer_sRGB"); m_GLExtensions.push_back("GL_EXT_gpu_shader4"); + m_GLExtensions.push_back("GL_EXT_memory_object"); + m_GLExtensions.push_back("GL_EXT_memory_object_fd"); + m_GLExtensions.push_back("GL_EXT_memory_object_win32"); m_GLExtensions.push_back("GL_EXT_multisample"); m_GLExtensions.push_back("GL_EXT_multi_draw_arrays"); m_GLExtensions.push_back("GL_EXT_packed_depth_stencil"); @@ -212,6 +215,9 @@ void WrappedOpenGL::BuildGLExtensions() m_GLExtensions.push_back("GL_EXT_post_depth_coverage"); m_GLExtensions.push_back("GL_EXT_provoking_vertex"); m_GLExtensions.push_back("GL_EXT_raster_multisample"); + m_GLExtensions.push_back("GL_EXT_semaphore"); + m_GLExtensions.push_back("GL_EXT_semaphore_fd"); + m_GLExtensions.push_back("GL_EXT_semaphore_win32"); m_GLExtensions.push_back("GL_EXT_shader_image_load_store"); m_GLExtensions.push_back("GL_EXT_shader_image_load_formatted"); m_GLExtensions.push_back("GL_EXT_shader_integer_mix"); @@ -238,6 +244,7 @@ void WrappedOpenGL::BuildGLExtensions() m_GLExtensions.push_back("GL_EXT_timer_query"); m_GLExtensions.push_back("GL_EXT_transform_feedback"); m_GLExtensions.push_back("GL_EXT_vertex_attrib_64bit"); + m_GLExtensions.push_back("GL_EXT_win32_keyed_mutex"); m_GLExtensions.push_back("GL_GREMEDY_frame_terminator"); m_GLExtensions.push_back("GL_GREMEDY_string_marker"); m_GLExtensions.push_back("GL_KHR_blend_equation_advanced"); @@ -2320,6 +2327,8 @@ void WrappedOpenGL::ReleaseResource(GLResource res) case eResFeedback: GL.glDeleteTransformFeedbacks(1, &res.name); break; case eResQuery: GL.glDeleteQueries(1, &res.name); break; case eResSync: GL.glDeleteSync(GetResourceManager()->GetSync(res.name)); break; + case eResExternalMemory: GL.glDeleteMemoryObjectsEXT(1, &res.name); break; + case eResExternalSemaphore: GL.glDeleteSemaphoresEXT(1, &res.name); break; } } @@ -3913,8 +3922,52 @@ bool WrappedOpenGL::ProcessChunk(ReadSerialiser &ser, GLChunk chunk) return Serialise_glSpecializeShader(ser, 0, NULL, 0, NULL, NULL); case GLChunk::glFinish: return Serialise_glFinish(ser); - case GLChunk::glFlush: - return Serialise_glFlush(ser); + case GLChunk::glFlush: return Serialise_glFlush(ser); + + case GLChunk::glCreateMemoryObjectsEXT: return Serialise_glCreateMemoryObjectsEXT(ser, 0, NULL); + case GLChunk::glMemoryObjectParameterivEXT: + return Serialise_glMemoryObjectParameterivEXT(ser, 0, eGL_NONE, 0); + case GLChunk::glTexStorageMem1DEXT: + case GLChunk::glTextureStorageMem1DEXT: + return Serialise_glTextureStorageMem1DEXT(ser, 0, 0, eGL_NONE, 0, 0, 0); + case GLChunk::glTexStorageMem2DEXT: + case GLChunk::glTextureStorageMem2DEXT: + return Serialise_glTextureStorageMem2DEXT(ser, 0, 0, eGL_NONE, 0, 0, 0, 0); + case GLChunk::glTexStorageMem2DMultisampleEXT: + case GLChunk::glTextureStorageMem2DMultisampleEXT: + return Serialise_glTextureStorageMem2DMultisampleEXT(ser, 0, 0, eGL_NONE, 0, 0, GL_FALSE, 0, 0); + case GLChunk::glTexStorageMem3DEXT: + case GLChunk::glTextureStorageMem3DEXT: + return Serialise_glTextureStorageMem3DEXT(ser, 0, 0, eGL_NONE, 0, 0, 0, 0, 0); + case GLChunk::glTexStorageMem3DMultisampleEXT: + case GLChunk::glTextureStorageMem3DMultisampleEXT: + return Serialise_glTextureStorageMem3DMultisampleEXT(ser, 0, 0, eGL_NONE, 0, 0, 0, GL_FALSE, + 0, 0); + case GLChunk::glBufferStorageMemEXT: + case GLChunk::glNamedBufferStorageMemEXT: + return Serialise_glNamedBufferStorageMemEXT(ser, 0, 0, 0, 0); + case GLChunk::glGenSemaphoresEXT: return Serialise_glGenSemaphoresEXT(ser, 0, NULL); + case GLChunk::glSemaphoreParameterui64vEXT: + return Serialise_glSemaphoreParameterui64vEXT(ser, 0, eGL_NONE, NULL); + case GLChunk::glWaitSemaphoreEXT: + return Serialise_glWaitSemaphoreEXT(ser, 0, 0, NULL, 0, NULL, NULL); + case GLChunk::glSignalSemaphoreEXT: + return Serialise_glSignalSemaphoreEXT(ser, 0, 0, NULL, 0, NULL, NULL); + case GLChunk::glImportMemoryFdEXT: return Serialise_glImportMemoryFdEXT(ser, 0, 0, eGL_NONE, 0); + case GLChunk::glImportSemaphoreFdEXT: + return Serialise_glImportSemaphoreFdEXT(ser, 0, eGL_NONE, 0); + case GLChunk::glImportMemoryWin32HandleEXT: + return Serialise_glImportMemoryWin32HandleEXT(ser, 0, 0, eGL_NONE, NULL); + case GLChunk::glImportMemoryWin32NameEXT: + return Serialise_glImportMemoryWin32NameEXT(ser, 0, 0, eGL_NONE, NULL); + case GLChunk::glImportSemaphoreWin32HandleEXT: + return Serialise_glImportSemaphoreWin32HandleEXT(ser, 0, eGL_NONE, NULL); + case GLChunk::glImportSemaphoreWin32NameEXT: + return Serialise_glImportSemaphoreWin32NameEXT(ser, 0, eGL_NONE, NULL); + case GLChunk::glAcquireKeyedMutexWin32EXT: + return Serialise_glAcquireKeyedMutexWin32EXT(ser, 0, 0, 0); + case GLChunk::glReleaseKeyedMutexWin32EXT: + return Serialise_glReleaseKeyedMutexWin32EXT(ser, 0, 0); // these functions are not currently serialised - they do nothing on replay and are not // serialised for information (it would be harmless and perhaps useful for the user to see @@ -4230,6 +4283,16 @@ bool WrappedOpenGL::ProcessChunk(ReadSerialiser &ser, GLChunk chunk) case GLChunk::wglDXUnlockObjectsNV: case GLChunk::glMaxShaderCompilerThreadsARB: case GLChunk::glMaxShaderCompilerThreadsKHR: + + case GLChunk::glGetUnsignedBytevEXT: + case GLChunk::glGetUnsignedBytei_vEXT: + case GLChunk::glDeleteMemoryObjectsEXT: + case GLChunk::glIsMemoryObjectEXT: + case GLChunk::glGetMemoryObjectParameterivEXT: + case GLChunk::glDeleteSemaphoresEXT: + case GLChunk::glIsSemaphoreEXT: + case GLChunk::glGetSemaphoreParameterui64vEXT: + case GLChunk::Max: RDCERR("Unexpected chunk %s, or missing case for processing! Skipping...", ToStr(chunk).c_str()); diff --git a/renderdoc/driver/gl/gl_driver.h b/renderdoc/driver/gl/gl_driver.h index 5b1840907..8bacd7bf8 100644 --- a/renderdoc/driver/gl/gl_driver.h +++ b/renderdoc/driver/gl/gl_driver.h @@ -2272,6 +2272,80 @@ public: IMPLEMENT_FUNCTION_SERIALISED(void, glSpecializeShader, GLuint shader, const GLchar *pEntryPoint, GLuint numSpecializationConstants, const GLuint *pConstantIndex, const GLuint *pConstantValue); + + IMPLEMENT_FUNCTION_SERIALISED(void, glGetUnsignedBytevEXT, GLenum pname, GLubyte *data); + IMPLEMENT_FUNCTION_SERIALISED(void, glGetUnsignedBytei_vEXT, GLenum target, GLuint index, + GLubyte *data); + IMPLEMENT_FUNCTION_SERIALISED(void, glDeleteMemoryObjectsEXT, GLsizei n, + const GLuint *memoryObjects); + IMPLEMENT_FUNCTION_SERIALISED(GLboolean, glIsMemoryObjectEXT, GLuint memoryObject); + IMPLEMENT_FUNCTION_SERIALISED(void, glCreateMemoryObjectsEXT, GLsizei n, GLuint *memoryObjects); + IMPLEMENT_FUNCTION_SERIALISED(void, glMemoryObjectParameterivEXT, GLuint memoryObject, + GLenum pname, const GLint *params); + IMPLEMENT_FUNCTION_SERIALISED(void, glGetMemoryObjectParameterivEXT, GLuint memoryObject, + GLenum pname, GLint *params); + IMPLEMENT_FUNCTION_SERIALISED(void, glTexStorageMem1DEXT, GLenum target, GLsizei levels, + GLenum internalFormat, GLsizei width, GLuint memory, GLuint64 offset); + IMPLEMENT_FUNCTION_SERIALISED(void, glTexStorageMem2DEXT, GLenum target, GLsizei levels, + GLenum internalFormat, GLsizei width, GLsizei height, GLuint memory, + GLuint64 offset); + IMPLEMENT_FUNCTION_SERIALISED(void, glTexStorageMem2DMultisampleEXT, GLenum target, + GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height, + GLboolean fixedSampleLocations, GLuint memory, GLuint64 offset); + IMPLEMENT_FUNCTION_SERIALISED(void, glTexStorageMem3DEXT, GLenum target, GLsizei levels, + GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, + GLuint memory, GLuint64 offset); + IMPLEMENT_FUNCTION_SERIALISED(void, glTexStorageMem3DMultisampleEXT, GLenum target, GLsizei samples, + GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, + GLboolean fixedSampleLocations, GLuint memory, GLuint64 offset); + IMPLEMENT_FUNCTION_SERIALISED(void, glTextureStorageMem1DEXT, GLuint texture, GLsizei levels, + GLenum internalFormat, GLsizei width, GLuint memory, GLuint64 offset); + IMPLEMENT_FUNCTION_SERIALISED(void, glTextureStorageMem2DEXT, GLuint texture, GLsizei levels, + GLenum internalFormat, GLsizei width, GLsizei height, GLuint memory, + GLuint64 offset); + IMPLEMENT_FUNCTION_SERIALISED(void, glTextureStorageMem2DMultisampleEXT, GLuint texture, + GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height, + GLboolean fixedSampleLocations, GLuint memory, GLuint64 offset); + IMPLEMENT_FUNCTION_SERIALISED(void, glTextureStorageMem3DEXT, GLuint texture, GLsizei levels, + GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, + GLuint memory, GLuint64 offset); + IMPLEMENT_FUNCTION_SERIALISED(void, glTextureStorageMem3DMultisampleEXT, GLuint texture, + GLsizei samples, GLenum internalFormat, GLsizei width, + GLsizei height, GLsizei depth, GLboolean fixedSampleLocations, + GLuint memory, GLuint64 offset); + IMPLEMENT_FUNCTION_SERIALISED(void, glBufferStorageMemEXT, GLenum target, GLsizeiptr size, + GLuint memory, GLuint64 offset); + IMPLEMENT_FUNCTION_SERIALISED(void, glNamedBufferStorageMemEXT, GLuint buffer, GLsizeiptr size, + GLuint memory, GLuint64 offset); + IMPLEMENT_FUNCTION_SERIALISED(void, glGenSemaphoresEXT, GLsizei n, GLuint *semaphores); + IMPLEMENT_FUNCTION_SERIALISED(void, glDeleteSemaphoresEXT, GLsizei n, const GLuint *semaphores); + IMPLEMENT_FUNCTION_SERIALISED(GLboolean, glIsSemaphoreEXT, GLuint semaphore); + IMPLEMENT_FUNCTION_SERIALISED(void, glSemaphoreParameterui64vEXT, GLuint semaphore, GLenum pname, + const GLuint64 *params); + IMPLEMENT_FUNCTION_SERIALISED(void, glGetSemaphoreParameterui64vEXT, GLuint semaphore, + GLenum pname, GLuint64 *params); + IMPLEMENT_FUNCTION_SERIALISED(void, glWaitSemaphoreEXT, GLuint semaphore, GLuint numBufferBarriers, + const GLuint *buffers, GLuint numTextureBarriers, + const GLuint *textures, const GLenum *srcLayouts); + IMPLEMENT_FUNCTION_SERIALISED(void, glSignalSemaphoreEXT, GLuint semaphore, + GLuint numBufferBarriers, const GLuint *buffers, + GLuint numTextureBarriers, const GLuint *textures, + const GLenum *dstLayouts); + IMPLEMENT_FUNCTION_SERIALISED(void, glImportMemoryFdEXT, GLuint memory, GLuint64 size, + GLenum handleType, GLint fd); + IMPLEMENT_FUNCTION_SERIALISED(void, glImportSemaphoreFdEXT, GLuint semaphore, GLenum handleType, + GLint fd); + IMPLEMENT_FUNCTION_SERIALISED(void, glImportMemoryWin32HandleEXT, GLuint memory, GLuint64 size, + GLenum handleType, void *handle); + IMPLEMENT_FUNCTION_SERIALISED(void, glImportMemoryWin32NameEXT, GLuint memory, GLuint64 size, + GLenum handleType, const void *name); + IMPLEMENT_FUNCTION_SERIALISED(void, glImportSemaphoreWin32HandleEXT, GLuint semaphore, + GLenum handleType, void *handle); + IMPLEMENT_FUNCTION_SERIALISED(void, glImportSemaphoreWin32NameEXT, GLuint semaphore, + GLenum handleType, const void *name); + IMPLEMENT_FUNCTION_SERIALISED(GLboolean, glAcquireKeyedMutexWin32EXT, GLuint memory, GLuint64 key, + GLuint timeout); + IMPLEMENT_FUNCTION_SERIALISED(GLboolean, glReleaseKeyedMutexWin32EXT, GLuint memory, GLuint64 key); }; class ScopedDebugContext diff --git a/renderdoc/driver/gl/gl_resources.cpp b/renderdoc/driver/gl/gl_resources.cpp index 02e3cb35e..da3e89b19 100644 --- a/renderdoc/driver/gl/gl_resources.cpp +++ b/renderdoc/driver/gl/gl_resources.cpp @@ -46,6 +46,8 @@ std::string DoStringise(const GLNamespace &el) STRINGISE_ENUM_NAMED(eResFeedback, "Transform Feedback"); STRINGISE_ENUM_NAMED(eResQuery, "Query"); STRINGISE_ENUM_NAMED(eResSync, "Sync"); + STRINGISE_ENUM_NAMED(eResExternalMemory, "External Memory"); + STRINGISE_ENUM_NAMED(eResExternalSemaphore, "External Semaphore"); } END_ENUM_STRINGISE(); } diff --git a/renderdoc/driver/gl/gl_resources.h b/renderdoc/driver/gl/gl_resources.h index 0b0cf7995..36160ab89 100644 --- a/renderdoc/driver/gl/gl_resources.h +++ b/renderdoc/driver/gl/gl_resources.h @@ -77,6 +77,8 @@ enum GLNamespace eResFeedback, eResQuery, eResSync, + eResExternalMemory, + eResExternalSemaphore, }; DECLARE_REFLECTION_ENUM(GLNamespace); @@ -195,6 +197,14 @@ inline GLResource SyncRes(const ContextPair &c, GLuint i) { return GLResource(c.shareGroup, eResSync, i); } +inline GLResource ExtMemRes(const ContextPair &c, GLuint i) +{ + return GLResource(c.ctx, eResExternalMemory, i); +} +inline GLResource ExtSemRes(const ContextPair &c, GLuint i) +{ + return GLResource(c.ctx, eResExternalSemaphore, i); +} struct GLResourceRecord : public ResourceRecord { diff --git a/renderdoc/driver/gl/wrappers/gl_get_funcs.cpp b/renderdoc/driver/gl/wrappers/gl_get_funcs.cpp index 514d06331..1504c98c4 100644 --- a/renderdoc/driver/gl/wrappers/gl_get_funcs.cpp +++ b/renderdoc/driver/gl/wrappers/gl_get_funcs.cpp @@ -126,6 +126,16 @@ GLboolean WrappedOpenGL::glIsNamedStringARB(GLint namelen, const GLchar *name) return GL.glIsNamedStringARB(namelen, name); } +GLboolean WrappedOpenGL::glIsMemoryObjectEXT(GLuint memoryObject) +{ + return GL.glIsMemoryObjectEXT(memoryObject); +} + +GLboolean WrappedOpenGL::glIsSemaphoreEXT(GLuint semaphore) +{ + return GL.glIsSemaphoreEXT(semaphore); +} + void WrappedOpenGL::glGetFloatv(GLenum pname, GLfloat *params) { GL.glGetFloatv(pname, params); @@ -241,6 +251,16 @@ void WrappedOpenGL::glGetInteger64i_v(GLenum pname, GLuint index, GLint64 *data) GL.glGetInteger64i_v(pname, index, data); } +void WrappedOpenGL::glGetUnsignedBytevEXT(GLenum pname, GLubyte *data) +{ + GL.glGetUnsignedBytevEXT(pname, data); +} + +void WrappedOpenGL::glGetUnsignedBytei_vEXT(GLenum target, GLuint index, GLubyte *data) +{ + GL.glGetUnsignedBytei_vEXT(target, index, data); +} + void WrappedOpenGL::glGetTexLevelParameteriv(GLenum target, GLint level, GLenum pname, GLint *params) { GL.glGetTexLevelParameteriv(target, level, pname, params); @@ -1175,3 +1195,13 @@ void WrappedOpenGL::glGetVertexArrayPointeri_vEXT(GLuint vaobj, GLuint index, GL { GL.glGetVertexArrayPointeri_vEXT(vaobj, index, pname, param); } + +void WrappedOpenGL::glGetMemoryObjectParameterivEXT(GLuint memoryObject, GLenum pname, GLint *params) +{ + GL.glGetMemoryObjectParameterivEXT(memoryObject, pname, params); +} + +void WrappedOpenGL::glGetSemaphoreParameterui64vEXT(GLuint semaphore, GLenum pname, GLuint64 *params) +{ + GL.glGetSemaphoreParameterui64vEXT(semaphore, pname, params); +} \ No newline at end of file diff --git a/renderdoc/driver/gl/wrappers/gl_interop_funcs.cpp b/renderdoc/driver/gl/wrappers/gl_interop_funcs.cpp index 5fb2b8be1..9652f8e1e 100644 --- a/renderdoc/driver/gl/wrappers/gl_interop_funcs.cpp +++ b/renderdoc/driver/gl/wrappers/gl_interop_funcs.cpp @@ -521,6 +521,1495 @@ bool WrappedOpenGL::Serialise_wglDXLockObjectsNV(SerialiserType &ser, GLResource return true; } +#pragma region Memory Objects + +template +bool WrappedOpenGL::Serialise_glCreateMemoryObjectsEXT(SerialiserType &ser, GLsizei n, + GLuint *memoryObjects) +{ + SERIALISE_ELEMENT(n); + SERIALISE_ELEMENT_LOCAL(memory, GetResourceManager()->GetID(ExtMemRes(GetCtx(), *memoryObjects))) + .TypedAs("GLResource"); + + SERIALISE_CHECK_READ_ERRORS(); + + if(IsReplayingAndReading()) + { + GLuint real = 0; + GL.glGenSemaphoresEXT(1, &real); + + GLResource res = ExtMemRes(GetCtx(), real); + + ResourceId live = m_ResourceManager->RegisterResource(res); + GetResourceManager()->AddLiveResource(memory, res); + + AddResource(memory, ResourceType::Memory, "Memory Object"); + } + + return true; +} + +void WrappedOpenGL::glCreateMemoryObjectsEXT(GLsizei n, GLuint *memoryObjects) +{ + SERIALISE_TIME_CALL(GL.glCreateMemoryObjectsEXT(n, memoryObjects)); + + for(GLsizei i = 0; i < n; i++) + { + GLResource res = ExtMemRes(GetCtx(), memoryObjects[i]); + ResourceId id = GetResourceManager()->RegisterResource(res); + + if(IsCaptureMode(m_State)) + { + Chunk *chunk = NULL; + + { + USE_SCRATCH_SERIALISER(); + SCOPED_SERIALISE_CHUNK(gl_CurChunk); + Serialise_glCreateMemoryObjectsEXT(ser, 1, memoryObjects + i); + + chunk = scope.Get(); + } + + GLResourceRecord *record = GetResourceManager()->AddResourceRecord(id); + RDCASSERT(record); + + record->AddChunk(chunk); + } + else + { + GetResourceManager()->AddLiveResource(id, res); + } + } +} + +void WrappedOpenGL::glDeleteMemoryObjectsEXT(GLsizei n, const GLuint *memoryObjects) +{ + for(GLsizei i = 0; i < n; i++) + { + GLResource res = ExtMemRes(GetCtx(), memoryObjects[i]); + if(GetResourceManager()->HasCurrentResource(res)) + { + if(GetResourceManager()->HasResourceRecord(res)) + GetResourceManager()->GetResourceRecord(res)->Delete(GetResourceManager()); + GetResourceManager()->UnregisterResource(res); + } + } + + GL.glDeleteMemoryObjectsEXT(n, memoryObjects); +} + +template +bool WrappedOpenGL::Serialise_glMemoryObjectParameterivEXT(SerialiserType &ser, + GLuint memoryObjectHandle, GLenum pname, + const GLint *params) +{ + SERIALISE_ELEMENT_LOCAL(memoryObject, ExtMemRes(GetCtx(), memoryObjectHandle)); + SERIALISE_ELEMENT(pname); + // if other parameters are added in future that take more than one value, change the array count + // here. + SERIALISE_ELEMENT_ARRAY(params, 1U); + + SERIALISE_CHECK_READ_ERRORS(); + + RDCASSERT(pname == eGL_DEDICATED_MEMORY_OBJECT_EXT || pname == eGL_PROTECTED_MEMORY_OBJECT_EXT); + + if(IsReplayingAndReading()) + { + GL.glMemoryObjectParameterivEXT(memoryObject.name, pname, params); + + AddResourceInitChunk(memoryObject); + } + + return true; +} + +void WrappedOpenGL::glMemoryObjectParameterivEXT(GLuint memoryObject, GLenum pname, + const GLint *params) +{ + SERIALISE_TIME_CALL(GL.glMemoryObjectParameterivEXT(memoryObject, pname, params)); + + if(IsCaptureMode(m_State)) + { + GLResourceRecord *record = + GetResourceManager()->GetResourceRecord(ExtMemRes(GetCtx(), memoryObject)); + + if(!record) + { + RDCERR("Called glMemoryObjectParameterivEXT with invalid/unrecognised memory object"); + return; + } + + USE_SCRATCH_SERIALISER(); + SCOPED_SERIALISE_CHUNK(gl_CurChunk); + Serialise_glMemoryObjectParameterivEXT(ser, memoryObject, pname, params); + + if(IsActiveCapturing(m_State)) + { + GetContextRecord()->AddChunk(scope.Get()); + GetResourceManager()->MarkResourceFrameReferenced(record->GetResourceID(), eFrameRef_Read); + } + else + { + record->AddChunk(scope.Get()); + } + } +} + +template +bool WrappedOpenGL::Serialise_glImportMemoryFdEXT(SerialiserType &ser, GLuint memoryHandle, + GLuint64 size, GLenum handleType, GLint fd) +{ + SERIALISE_ELEMENT_LOCAL(memory, ExtMemRes(GetCtx(), memoryHandle)); + SERIALISE_ELEMENT(size); + SERIALISE_ELEMENT(handleType); + SERIALISE_ELEMENT(fd); + + SERIALISE_CHECK_READ_ERRORS(); + + if(IsReplayingAndReading()) + { + // nothing to do - we don't replay external memory we just allocate textures/buffers with their + // own backing store. Keep this around for tracking purposes + + AddResourceInitChunk(memory); + } + + return true; +} + +void WrappedOpenGL::glImportMemoryFdEXT(GLuint memory, GLuint64 size, GLenum handleType, GLint fd) +{ + SERIALISE_TIME_CALL(GL.glImportMemoryFdEXT(memory, size, handleType, fd)); + + if(IsCaptureMode(m_State)) + { + GLResourceRecord *record = GetResourceManager()->GetResourceRecord(ExtMemRes(GetCtx(), memory)); + + if(!record) + { + RDCERR("Called glImportMemoryFdEXT with invalid/unrecognised memory object"); + return; + } + + USE_SCRATCH_SERIALISER(); + SCOPED_SERIALISE_CHUNK(gl_CurChunk); + Serialise_glImportMemoryFdEXT(ser, memory, size, handleType, fd); + + record->AddChunk(scope.Get()); + } +} + +template +bool WrappedOpenGL::Serialise_glImportMemoryWin32HandleEXT(SerialiserType &ser, GLuint memoryHandle, + GLuint64 size, GLenum handleType, + void *handlePtr) +{ + SERIALISE_ELEMENT_LOCAL(memory, ExtMemRes(GetCtx(), memoryHandle)); + SERIALISE_ELEMENT(size); + SERIALISE_ELEMENT(handleType); + SERIALISE_ELEMENT_LOCAL(handle, uint64_t(handlePtr)); + + SERIALISE_CHECK_READ_ERRORS(); + + if(IsReplayingAndReading()) + { + // nothing to do - we don't replay external memory we just allocate textures/buffers with their + // own backing store. Keep this around for tracking purposes + + AddResourceInitChunk(memory); + } + + return true; +} + +void WrappedOpenGL::glImportMemoryWin32HandleEXT(GLuint memory, GLuint64 size, GLenum handleType, + void *handle) +{ + SERIALISE_TIME_CALL(GL.glImportMemoryWin32HandleEXT(memory, size, handleType, handle)); + + if(IsCaptureMode(m_State)) + { + GLResourceRecord *record = GetResourceManager()->GetResourceRecord(ExtMemRes(GetCtx(), memory)); + + if(!record) + { + RDCERR("Called glImportMemoryWin32HandleEXT with invalid/unrecognised memory object"); + return; + } + + USE_SCRATCH_SERIALISER(); + SCOPED_SERIALISE_CHUNK(gl_CurChunk); + Serialise_glImportMemoryWin32HandleEXT(ser, memory, size, handleType, handle); + + record->AddChunk(scope.Get()); + } +} + +template +bool WrappedOpenGL::Serialise_glImportMemoryWin32NameEXT(SerialiserType &ser, GLuint memoryHandle, + GLuint64 size, GLenum handleType, + const void *namePtr) +{ + SERIALISE_ELEMENT_LOCAL(memory, ExtMemRes(GetCtx(), memoryHandle)); + SERIALISE_ELEMENT(size); + SERIALISE_ELEMENT(handleType); + SERIALISE_ELEMENT_LOCAL(name, StringFormat::Wide2UTF8((const wchar_t *)namePtr)); + + SERIALISE_CHECK_READ_ERRORS(); + + if(IsReplayingAndReading()) + { + // nothing to do - we don't replay external memory we just allocate textures/buffers with their + // own backing store. Keep this around for tracking purposes + + AddResourceInitChunk(memory); + } + + return true; +} + +void WrappedOpenGL::glImportMemoryWin32NameEXT(GLuint memory, GLuint64 size, GLenum handleType, + const void *name) +{ + SERIALISE_TIME_CALL(GL.glImportMemoryWin32NameEXT(memory, size, handleType, name)); + + if(IsCaptureMode(m_State)) + { + GLResourceRecord *record = GetResourceManager()->GetResourceRecord(ExtMemRes(GetCtx(), memory)); + + if(!record) + { + RDCERR("Called glImportMemoryWin32NameEXT with invalid/unrecognised memory object"); + return; + } + + USE_SCRATCH_SERIALISER(); + SCOPED_SERIALISE_CHUNK(gl_CurChunk); + Serialise_glImportMemoryWin32NameEXT(ser, memory, size, handleType, name); + + record->AddChunk(scope.Get()); + } +} + +#pragma endregion + +#pragma region Semaphores + +template +bool WrappedOpenGL::Serialise_glGenSemaphoresEXT(SerialiserType &ser, GLsizei n, GLuint *semaphores) +{ + SERIALISE_ELEMENT(n); + SERIALISE_ELEMENT_LOCAL(semaphore, GetResourceManager()->GetID(ExtSemRes(GetCtx(), *semaphores))) + .TypedAs("GLResource"); + + SERIALISE_CHECK_READ_ERRORS(); + + if(IsReplayingAndReading()) + { + GLuint real = 0; + GL.glGenSemaphoresEXT(1, &real); + + GLResource res = ExtSemRes(GetCtx(), real); + + ResourceId live = m_ResourceManager->RegisterResource(res); + GetResourceManager()->AddLiveResource(semaphore, res); + + AddResource(semaphore, ResourceType::Sync, "Semaphore"); + } + + return true; +} + +void WrappedOpenGL::glGenSemaphoresEXT(GLsizei n, GLuint *semaphores) +{ + SERIALISE_TIME_CALL(GL.glGenSemaphoresEXT(n, semaphores)); + + for(GLsizei i = 0; i < n; i++) + { + GLResource res = ExtSemRes(GetCtx(), semaphores[i]); + ResourceId id = GetResourceManager()->RegisterResource(res); + + if(IsCaptureMode(m_State)) + { + Chunk *chunk = NULL; + + { + USE_SCRATCH_SERIALISER(); + SCOPED_SERIALISE_CHUNK(gl_CurChunk); + Serialise_glGenSemaphoresEXT(ser, 1, semaphores + i); + + chunk = scope.Get(); + } + + GLResourceRecord *record = GetResourceManager()->AddResourceRecord(id); + RDCASSERT(record); + + record->AddChunk(chunk); + } + else + { + GetResourceManager()->AddLiveResource(id, res); + } + } +} + +void WrappedOpenGL::glDeleteSemaphoresEXT(GLsizei n, const GLuint *semaphores) +{ + for(GLsizei i = 0; i < n; i++) + { + GLResource res = ExtSemRes(GetCtx(), semaphores[i]); + if(GetResourceManager()->HasCurrentResource(res)) + { + if(GetResourceManager()->HasResourceRecord(res)) + GetResourceManager()->GetResourceRecord(res)->Delete(GetResourceManager()); + GetResourceManager()->UnregisterResource(res); + } + } + + GL.glDeleteSemaphoresEXT(n, semaphores); +} + +template +bool WrappedOpenGL::Serialise_glSemaphoreParameterui64vEXT(SerialiserType &ser, + GLuint semaphoreHandle, GLenum pname, + const GLuint64 *params) +{ + SERIALISE_ELEMENT_LOCAL(semaphore, ExtSemRes(GetCtx(), semaphoreHandle)); + SERIALISE_ELEMENT(pname); + // if other parameters are added in future that take more than one value, change the array count + // here. + SERIALISE_ELEMENT_ARRAY(params, 1U); + + SERIALISE_CHECK_READ_ERRORS(); + + RDCASSERT(pname == eGL_D3D12_FENCE_VALUE_EXT); + + if(IsReplayingAndReading()) + { + GL.glSemaphoreParameterui64vEXT(semaphore.name, pname, params); + } + + return true; +} + +void WrappedOpenGL::glSemaphoreParameterui64vEXT(GLuint semaphore, GLenum pname, + const GLuint64 *params) +{ + SERIALISE_TIME_CALL(GL.glSemaphoreParameterui64vEXT(semaphore, pname, params)); + + if(IsCaptureMode(m_State)) + { + GLResourceRecord *record = + GetResourceManager()->GetResourceRecord(ExtSemRes(GetCtx(), semaphore)); + + if(!record) + { + RDCERR("Called glSemaphoreParameterui64vEXT with invalid/unrecognised semaphore"); + return; + } + + USE_SCRATCH_SERIALISER(); + SCOPED_SERIALISE_CHUNK(gl_CurChunk); + Serialise_glSemaphoreParameterui64vEXT(ser, semaphore, pname, params); + + if(IsActiveCapturing(m_State)) + { + GetContextRecord()->AddChunk(scope.Get()); + GetResourceManager()->MarkResourceFrameReferenced(record->GetResourceID(), eFrameRef_Read); + } + else + { + record->AddChunk(scope.Get()); + } + } +} + +template +bool WrappedOpenGL::Serialise_glImportSemaphoreFdEXT(SerialiserType &ser, GLuint semaphoreHandle, + GLenum handleType, GLint fd) +{ + SERIALISE_ELEMENT_LOCAL(semaphore, ExtSemRes(GetCtx(), semaphoreHandle)); + SERIALISE_ELEMENT(handleType); + SERIALISE_ELEMENT(fd); + + SERIALISE_CHECK_READ_ERRORS(); + + if(IsReplayingAndReading()) + { + // nothing to do - we don't replay semaphores we just fully glFinish() when we need to wait on + // them (just in case). + + AddResourceInitChunk(semaphore); + } + + return true; +} + +void WrappedOpenGL::glImportSemaphoreFdEXT(GLuint semaphore, GLenum handleType, GLint fd) +{ + SERIALISE_TIME_CALL(GL.glImportSemaphoreFdEXT(semaphore, handleType, fd)); + + if(IsCaptureMode(m_State)) + { + GLResourceRecord *record = + GetResourceManager()->GetResourceRecord(ExtSemRes(GetCtx(), semaphore)); + + if(!record) + { + RDCERR("Called glImportSemaphoreFdEXT with invalid/unrecognised semaphore object"); + return; + } + + USE_SCRATCH_SERIALISER(); + SCOPED_SERIALISE_CHUNK(gl_CurChunk); + Serialise_glImportSemaphoreFdEXT(ser, semaphore, handleType, fd); + + record->AddChunk(scope.Get()); + } +} + +template +bool WrappedOpenGL::Serialise_glImportSemaphoreWin32HandleEXT(SerialiserType &ser, + GLuint semaphoreHandle, + GLenum handleType, void *handlePtr) +{ + SERIALISE_ELEMENT_LOCAL(semaphore, ExtSemRes(GetCtx(), semaphoreHandle)); + SERIALISE_ELEMENT(handleType); + SERIALISE_ELEMENT_LOCAL(handle, uint64_t(handlePtr)); + + SERIALISE_CHECK_READ_ERRORS(); + + if(IsReplayingAndReading()) + { + // nothing to do - we don't replay semaphores we just fully glFinish() when we need to wait on + // them (just in case). + + AddResourceInitChunk(semaphore); + } + + return true; +} + +void WrappedOpenGL::glImportSemaphoreWin32HandleEXT(GLuint semaphore, GLenum handleType, void *handle) +{ + SERIALISE_TIME_CALL(GL.glImportSemaphoreWin32HandleEXT(semaphore, handleType, handle)); + + if(IsCaptureMode(m_State)) + { + GLResourceRecord *record = + GetResourceManager()->GetResourceRecord(ExtSemRes(GetCtx(), semaphore)); + + if(!record) + { + RDCERR("Called glImportSemaphoreWin32HandleEXT with invalid/unrecognised semaphore object"); + return; + } + + USE_SCRATCH_SERIALISER(); + SCOPED_SERIALISE_CHUNK(gl_CurChunk); + Serialise_glImportSemaphoreWin32HandleEXT(ser, semaphore, handleType, handle); + + record->AddChunk(scope.Get()); + } +} + +template +bool WrappedOpenGL::Serialise_glImportSemaphoreWin32NameEXT(SerialiserType &ser, + GLuint semaphoreHandle, + GLenum handleType, const void *namePtr) +{ + SERIALISE_ELEMENT_LOCAL(semaphore, ExtSemRes(GetCtx(), semaphoreHandle)); + SERIALISE_ELEMENT(handleType); + SERIALISE_ELEMENT_LOCAL(name, StringFormat::Wide2UTF8((const wchar_t *)namePtr)); + + SERIALISE_CHECK_READ_ERRORS(); + + if(IsReplayingAndReading()) + { + // nothing to do - we don't replay semaphores we just fully glFinish() when we need to wait on + // them (just in case). + + AddResourceInitChunk(semaphore); + } + + return true; +} + +void WrappedOpenGL::glImportSemaphoreWin32NameEXT(GLuint semaphore, GLenum handleType, + const void *name) +{ + SERIALISE_TIME_CALL(GL.glImportSemaphoreWin32NameEXT(semaphore, handleType, name)); + + if(IsCaptureMode(m_State)) + { + GLResourceRecord *record = + GetResourceManager()->GetResourceRecord(ExtSemRes(GetCtx(), semaphore)); + + if(!record) + { + RDCERR("Called glImportSemaphoreWin32NameEXT with invalid/unrecognised semaphore object"); + return; + } + + USE_SCRATCH_SERIALISER(); + SCOPED_SERIALISE_CHUNK(gl_CurChunk); + Serialise_glImportSemaphoreWin32NameEXT(ser, semaphore, handleType, name); + + record->AddChunk(scope.Get()); + } +} + +template +bool WrappedOpenGL::Serialise_glWaitSemaphoreEXT(SerialiserType &ser, GLuint semaphoreHandle, + GLuint numBufferBarriers, + const GLuint *bufferHandles, + GLuint numTextureBarriers, + const GLuint *textureHandles, + const GLenum *srcLayouts) +{ + // can't serialise arrays of GL handles since they're not wrapped or typed :(. + std::vector buffers, textures; + + if(ser.IsWriting()) + { + buffers.reserve(numBufferBarriers); + for(GLuint i = 0; i < numBufferBarriers; i++) + buffers.push_back(BufferRes(GetCtx(), bufferHandles ? bufferHandles[i] : 0)); + + textures.reserve(numTextureBarriers); + for(GLuint i = 0; i < numTextureBarriers; i++) + textures.push_back(TextureRes(GetCtx(), textureHandles ? textureHandles[i] : 0)); + } + + SERIALISE_ELEMENT_LOCAL(semaphore, ExtSemRes(GetCtx(), semaphoreHandle)); + SERIALISE_ELEMENT(numBufferBarriers); + SERIALISE_ELEMENT(buffers); + SERIALISE_ELEMENT(numTextureBarriers); + SERIALISE_ELEMENT(textures); + SERIALISE_ELEMENT_ARRAY(srcLayouts, numTextureBarriers); + + SERIALISE_CHECK_READ_ERRORS(); + + if(IsReplayingAndReading()) + { + // nothing to do - we don't replay semaphores we just fully glFinish() when we need to wait on + // them (just in case). + + GL.glFinish(); + } + + return true; +} + +void WrappedOpenGL::glWaitSemaphoreEXT(GLuint semaphore, GLuint numBufferBarriers, + const GLuint *buffers, GLuint numTextureBarriers, + const GLuint *textures, const GLenum *srcLayouts) +{ + SERIALISE_TIME_CALL(GL.glWaitSemaphoreEXT(semaphore, numBufferBarriers, buffers, + numTextureBarriers, textures, srcLayouts)); + + if(IsActiveCapturing(m_State)) + { + USE_SCRATCH_SERIALISER(); + SCOPED_SERIALISE_CHUNK(gl_CurChunk); + Serialise_glWaitSemaphoreEXT(ser, semaphore, numBufferBarriers, buffers, numTextureBarriers, + textures, srcLayouts); + + GetContextRecord()->AddChunk(scope.Get()); + GetResourceManager()->MarkResourceFrameReferenced(ExtSemRes(GetCtx(), semaphore), eFrameRef_Read); + + for(GLuint b = 0; buffers && b < numBufferBarriers; b++) + GetResourceManager()->MarkResourceFrameReferenced(BufferRes(GetCtx(), buffers[b]), + eFrameRef_Read); + + for(GLuint t = 0; textures && t < numTextureBarriers; t++) + GetResourceManager()->MarkResourceFrameReferenced(TextureRes(GetCtx(), textures[t]), + eFrameRef_Read); + } +} + +template +bool WrappedOpenGL::Serialise_glSignalSemaphoreEXT(SerialiserType &ser, GLuint semaphoreHandle, + GLuint numBufferBarriers, + const GLuint *bufferHandles, + GLuint numTextureBarriers, + const GLuint *textureHandles, + const GLenum *dstLayouts) +{ + // can't serialise arrays of GL handles since they're not wrapped or typed :(. + std::vector buffers, textures; + + if(ser.IsWriting()) + { + buffers.reserve(numBufferBarriers); + for(GLuint i = 0; i < numBufferBarriers; i++) + buffers.push_back(BufferRes(GetCtx(), bufferHandles ? bufferHandles[i] : 0)); + + textures.reserve(numTextureBarriers); + for(GLuint i = 0; i < numTextureBarriers; i++) + textures.push_back(TextureRes(GetCtx(), textureHandles ? textureHandles[i] : 0)); + } + + SERIALISE_ELEMENT_LOCAL(semaphore, ExtSemRes(GetCtx(), semaphoreHandle)); + SERIALISE_ELEMENT(numBufferBarriers); + SERIALISE_ELEMENT(buffers); + SERIALISE_ELEMENT(numTextureBarriers); + SERIALISE_ELEMENT(textures); + SERIALISE_ELEMENT_ARRAY(dstLayouts, numTextureBarriers); + + SERIALISE_CHECK_READ_ERRORS(); + + if(IsReplayingAndReading()) + { + // nothing to do - we don't replay semaphores we just fully glFinish() when we need to wait on + // them (just in case). + } + + return true; +} + +void WrappedOpenGL::glSignalSemaphoreEXT(GLuint semaphore, GLuint numBufferBarriers, + const GLuint *buffers, GLuint numTextureBarriers, + const GLuint *textures, const GLenum *dstLayouts) +{ + SERIALISE_TIME_CALL(GL.glSignalSemaphoreEXT(semaphore, numBufferBarriers, buffers, + numTextureBarriers, textures, dstLayouts)); + + if(IsActiveCapturing(m_State)) + { + USE_SCRATCH_SERIALISER(); + SCOPED_SERIALISE_CHUNK(gl_CurChunk); + Serialise_glSignalSemaphoreEXT(ser, semaphore, numBufferBarriers, buffers, numTextureBarriers, + textures, dstLayouts); + + GetContextRecord()->AddChunk(scope.Get()); + GetResourceManager()->MarkResourceFrameReferenced(ExtSemRes(GetCtx(), semaphore), eFrameRef_Read); + + for(GLuint b = 0; buffers && b < numBufferBarriers; b++) + GetResourceManager()->MarkResourceFrameReferenced(BufferRes(GetCtx(), buffers[b]), + eFrameRef_Read); + + for(GLuint t = 0; textures && t < numTextureBarriers; t++) + GetResourceManager()->MarkResourceFrameReferenced(TextureRes(GetCtx(), textures[t]), + eFrameRef_Read); + } +} + +#pragma endregion + +#pragma region Keyed Mutexes + +template +bool WrappedOpenGL::Serialise_glAcquireKeyedMutexWin32EXT(SerialiserType &ser, GLuint memoryHandle, + GLuint64 key, GLuint timeout) +{ + SERIALISE_ELEMENT_LOCAL(memory, ExtSemRes(GetCtx(), memoryHandle)); + SERIALISE_ELEMENT(key); + SERIALISE_ELEMENT(timeout); + + SERIALISE_CHECK_READ_ERRORS(); + + if(IsReplayingAndReading()) + { + // nothing to do - we don't replay keyed mutexes as we don't create external memory + } + + return true; +} + +GLboolean WrappedOpenGL::glAcquireKeyedMutexWin32EXT(GLuint memory, GLuint64 key, GLuint timeout) +{ + GLboolean ret; + SERIALISE_TIME_CALL(ret = GL.glAcquireKeyedMutexWin32EXT(memory, key, timeout)); + + if(IsActiveCapturing(m_State)) + { + USE_SCRATCH_SERIALISER(); + SCOPED_SERIALISE_CHUNK(gl_CurChunk); + Serialise_glAcquireKeyedMutexWin32EXT(ser, memory, key, timeout); + + GetContextRecord()->AddChunk(scope.Get()); + GetResourceManager()->MarkResourceFrameReferenced(ExtMemRes(GetCtx(), memory), eFrameRef_Read); + } + + return ret; +} + +template +bool WrappedOpenGL::Serialise_glReleaseKeyedMutexWin32EXT(SerialiserType &ser, GLuint memoryHandle, + GLuint64 key) +{ + SERIALISE_ELEMENT_LOCAL(memory, ExtSemRes(GetCtx(), memoryHandle)); + SERIALISE_ELEMENT(key); + + SERIALISE_CHECK_READ_ERRORS(); + + if(IsReplayingAndReading()) + { + // nothing to do - we don't replay keyed mutexes as we don't create external memory + } + + return true; +} + +GLboolean WrappedOpenGL::glReleaseKeyedMutexWin32EXT(GLuint memory, GLuint64 key) +{ + GLboolean ret; + SERIALISE_TIME_CALL(ret = GL.glReleaseKeyedMutexWin32EXT(memory, key)); + + if(IsActiveCapturing(m_State)) + { + USE_SCRATCH_SERIALISER(); + SCOPED_SERIALISE_CHUNK(gl_CurChunk); + Serialise_glReleaseKeyedMutexWin32EXT(ser, memory, key); + + GetContextRecord()->AddChunk(scope.Get()); + GetResourceManager()->MarkResourceFrameReferenced(ExtMemRes(GetCtx(), memory), eFrameRef_Read); + } + + return ret; +} + +#pragma endregion + +#pragma region Buffers + +template +bool WrappedOpenGL::Serialise_glNamedBufferStorageMemEXT(SerialiserType &ser, GLuint bufferHandle, + GLsizeiptr sizeptr, GLuint memoryHandle, + GLuint64 offset) +{ + SERIALISE_ELEMENT_LOCAL(buffer, BufferRes(GetCtx(), bufferHandle)); + SERIALISE_ELEMENT_LOCAL(size, (uint64_t)sizeptr); + SERIALISE_ELEMENT_LOCAL(memory, ExtMemRes(GetCtx(), memoryHandle)); + SERIALISE_ELEMENT(offset); + + SERIALISE_CHECK_READ_ERRORS(); + + if(IsReplayingAndReading()) + { + // Replay external buffer storage backed by external memory as just a plain buffer. + + // we have to come up with flags that will work regardless, so we're conservative here. + // The spec says memory object backed buffers can't be mapped, but we set DYNAMIC_STORAGE as + // it's unclear if they can be updated with glBufferSubData or not. + GLbitfield flags = eGL_DYNAMIC_STORAGE_BIT; + + GL.glNamedBufferStorageEXT(buffer.name, (GLsizeiptr)size, NULL, flags); + + ResourceId id = GetResourceManager()->GetID(buffer); + + m_Buffers[id].size = size; + + AddResourceInitChunk(buffer); + DerivedResource(memory, GetResourceManager()->GetOriginalID(id)); + } + + return true; +} + +void WrappedOpenGL::glNamedBufferStorageMemEXT(GLuint buffer, GLsizeiptr size, GLuint memory, + GLuint64 offset) +{ + SERIALISE_TIME_CALL(GL.glNamedBufferStorageMemEXT(buffer, size, memory, offset)); + + if(IsCaptureMode(m_State)) + { + GLResourceRecord *bufrecord = + GetResourceManager()->GetResourceRecord(BufferRes(GetCtx(), buffer)); + GLResourceRecord *memrecord = + GetResourceManager()->GetResourceRecord(ExtMemRes(GetCtx(), memory)); + + if(!bufrecord) + { + RDCERR("Called glNamedBufferStorageMemEXT with invalid buffer"); + return; + } + + if(!memrecord) + { + RDCERR("Called glNamedBufferStorageMemEXT with invalid memory object"); + return; + } + + // when bound to external memory, immediately consider dirty + GetResourceManager()->MarkDirtyResource(bufrecord->Resource); + + USE_SCRATCH_SERIALISER(); + SCOPED_SERIALISE_CHUNK(gl_CurChunk); + Serialise_glNamedBufferStorageMemEXT(ser, buffer, size, memory, offset); + + bufrecord->AddChunk(scope.Get()); + bufrecord->AddParent(memrecord); + bufrecord->Length = (int32_t)size; + } +} + +void WrappedOpenGL::glBufferStorageMemEXT(GLenum target, GLsizeiptr size, GLuint memory, + GLuint64 offset) +{ + SERIALISE_TIME_CALL(GL.glBufferStorageMemEXT(target, size, memory, offset)); + + if(IsCaptureMode(m_State)) + { + GLResourceRecord *bufrecord = GetCtxData().m_BufferRecord[BufferIdx(target)]; + GLResourceRecord *memrecord = + GetResourceManager()->GetResourceRecord(ExtMemRes(GetCtx(), memory)); + + if(!bufrecord) + { + RDCERR("Called glBufferStorageMemEXT with no buffer bound to %s", ToStr(target).c_str()); + return; + } + + if(!memrecord) + { + RDCERR("Called glNamedBufferStorageMemEXT with invalid memory object"); + return; + } + + // when bound to external memory, immediately consider dirty + GetResourceManager()->MarkDirtyResource(bufrecord->Resource); + + USE_SCRATCH_SERIALISER(); + SCOPED_SERIALISE_CHUNK(gl_CurChunk); + Serialise_glNamedBufferStorageMemEXT(ser, bufrecord->Resource.name, size, memory, offset); + + bufrecord->AddChunk(scope.Get()); + bufrecord->AddParent(memrecord); + bufrecord->Length = (int32_t)size; + } +} + +#pragma endregion + +#pragma region Textures + +template +bool WrappedOpenGL::Serialise_glTextureStorageMem1DEXT(SerialiserType &ser, GLuint textureHandle, + GLsizei levels, GLenum internalFormat, + GLsizei width, GLuint memoryHandle, + GLuint64 offset) +{ + SERIALISE_ELEMENT_LOCAL(texture, TextureRes(GetCtx(), textureHandle)); + SERIALISE_ELEMENT(levels); + SERIALISE_ELEMENT(internalFormat); + SERIALISE_ELEMENT(width); + SERIALISE_ELEMENT_LOCAL(memory, ExtMemRes(GetCtx(), memoryHandle)); + SERIALISE_ELEMENT(offset); + + SERIALISE_CHECK_READ_ERRORS(); + + if(IsReplayingAndReading()) + { + // Replay external texture storage backed by external memory as just a plain texture. + ResourceId liveId = GetResourceManager()->GetID(texture); + m_Textures[liveId].width = width; + m_Textures[liveId].height = 1; + m_Textures[liveId].depth = 1; + m_Textures[liveId].dimension = 1; + m_Textures[liveId].internalFormat = internalFormat; + m_Textures[liveId].emulated = false; + m_Textures[liveId].mipsValid = (1 << levels) - 1; + + GL.glTextureStorage1DEXT(texture.name, m_Textures[liveId].curType, levels, internalFormat, width); + + AddResourceInitChunk(texture); + DerivedResource(memory, GetResourceManager()->GetOriginalID(liveId)); + } + + return true; +} + +void WrappedOpenGL::glTextureStorageMem1DEXT(GLuint texture, GLsizei levels, GLenum internalFormat, + GLsizei width, GLuint memory, GLuint64 offset) +{ + SERIALISE_TIME_CALL( + GL.glTextureStorageMem1DEXT(texture, levels, internalFormat, width, memory, offset)); + + if(IsCaptureMode(m_State)) + { + GLResourceRecord *record = GetResourceManager()->GetResourceRecord(TextureRes(GetCtx(), texture)); + + if(!record) + { + RDCERR("Calling glTextureStorageMem1DEXT with unrecognised texture"); + return; + } + + USE_SCRATCH_SERIALISER(); + SCOPED_SERIALISE_CHUNK(gl_CurChunk); + Serialise_glTextureStorageMem1DEXT(ser, texture, levels, internalFormat, width, memory, offset); + + record->AddChunk(scope.Get()); + + // when bound to external memory, immediately consider dirty + GetResourceManager()->MarkDirtyResource(record->Resource); + + ResourceId texId = record->GetResourceID(); + + m_Textures[texId].width = width; + m_Textures[texId].height = 1; + m_Textures[texId].depth = 1; + m_Textures[texId].dimension = 1; + m_Textures[texId].internalFormat = internalFormat; + m_Textures[texId].mipsValid = (1 << levels) - 1; + } +} + +void WrappedOpenGL::glTexStorageMem1DEXT(GLenum target, GLsizei levels, GLenum internalFormat, + GLsizei width, GLuint memory, GLuint64 offset) +{ + SERIALISE_TIME_CALL(GL.glTexStorageMem1DEXT(target, levels, internalFormat, width, memory, offset)); + + if(IsCaptureMode(m_State)) + { + GLResourceRecord *record = GetCtxData().GetActiveTexRecord(); + + if(!record) + { + RDCERR("Calling glTextureStorageMem1DEXT with no texture bound"); + return; + } + + USE_SCRATCH_SERIALISER(); + SCOPED_SERIALISE_CHUNK(gl_CurChunk); + Serialise_glTextureStorageMem1DEXT(ser, record->Resource.name, levels, internalFormat, width, + memory, offset); + + record->AddChunk(scope.Get()); + + // when bound to external memory, immediately consider dirty + GetResourceManager()->MarkDirtyResource(record->Resource); + + ResourceId texId = record->GetResourceID(); + + m_Textures[texId].width = width; + m_Textures[texId].height = 1; + m_Textures[texId].depth = 1; + m_Textures[texId].dimension = 1; + m_Textures[texId].internalFormat = internalFormat; + m_Textures[texId].mipsValid = (1 << levels) - 1; + } +} + +template +bool WrappedOpenGL::Serialise_glTextureStorageMem2DEXT(SerialiserType &ser, GLuint textureHandle, + GLsizei levels, GLenum internalFormat, + GLsizei width, GLsizei height, + GLuint memoryHandle, GLuint64 offset) +{ + SERIALISE_ELEMENT_LOCAL(texture, TextureRes(GetCtx(), textureHandle)); + SERIALISE_ELEMENT(levels); + SERIALISE_ELEMENT(internalFormat); + SERIALISE_ELEMENT(width); + SERIALISE_ELEMENT(height); + SERIALISE_ELEMENT_LOCAL(memory, ExtMemRes(GetCtx(), memoryHandle)); + SERIALISE_ELEMENT(offset); + + SERIALISE_CHECK_READ_ERRORS(); + + if(IsReplayingAndReading()) + { + // Replay external texture storage backed by external memory as just a plain texture. + ResourceId liveId = GetResourceManager()->GetID(texture); + m_Textures[liveId].width = width; + m_Textures[liveId].height = height; + m_Textures[liveId].depth = 1; + m_Textures[liveId].dimension = 2; + m_Textures[liveId].internalFormat = internalFormat; + m_Textures[liveId].emulated = false; + m_Textures[liveId].mipsValid = (1 << levels) - 1; + + GL.glTextureStorage2DEXT(texture.name, m_Textures[liveId].curType, levels, internalFormat, + width, height); + + AddResourceInitChunk(texture); + DerivedResource(memory, GetResourceManager()->GetOriginalID(liveId)); + } + + return true; +} + +void WrappedOpenGL::glTextureStorageMem2DEXT(GLuint texture, GLsizei levels, GLenum internalFormat, + GLsizei width, GLsizei height, GLuint memory, + GLuint64 offset) +{ + SERIALISE_TIME_CALL( + GL.glTextureStorageMem2DEXT(texture, levels, internalFormat, width, height, memory, offset)); + + if(IsCaptureMode(m_State)) + { + GLResourceRecord *record = GetResourceManager()->GetResourceRecord(TextureRes(GetCtx(), texture)); + + if(!record) + { + RDCERR("Calling glTextureStorageMem2DEXT with unrecognised texture"); + return; + } + + USE_SCRATCH_SERIALISER(); + SCOPED_SERIALISE_CHUNK(gl_CurChunk); + Serialise_glTextureStorageMem2DEXT(ser, texture, levels, internalFormat, width, height, memory, + offset); + + record->AddChunk(scope.Get()); + + // when bound to external memory, immediately consider dirty + GetResourceManager()->MarkDirtyResource(record->Resource); + + ResourceId texId = record->GetResourceID(); + + m_Textures[texId].width = width; + m_Textures[texId].height = height; + m_Textures[texId].depth = 1; + m_Textures[texId].dimension = 2; + m_Textures[texId].internalFormat = internalFormat; + m_Textures[texId].mipsValid = (1 << levels) - 1; + } +} + +void WrappedOpenGL::glTexStorageMem2DEXT(GLenum target, GLsizei levels, GLenum internalFormat, + GLsizei width, GLsizei height, GLuint memory, + GLuint64 offset) +{ + SERIALISE_TIME_CALL( + GL.glTexStorageMem2DEXT(target, levels, internalFormat, width, height, memory, offset)); + + if(IsCaptureMode(m_State)) + { + GLResourceRecord *record = GetCtxData().GetActiveTexRecord(); + + if(!record) + { + RDCERR("Calling glTextureStorageMem2DEXT with no texture bound"); + return; + } + + USE_SCRATCH_SERIALISER(); + SCOPED_SERIALISE_CHUNK(gl_CurChunk); + Serialise_glTextureStorageMem2DEXT(ser, record->Resource.name, levels, internalFormat, width, + height, memory, offset); + + record->AddChunk(scope.Get()); + + // when bound to external memory, immediately consider dirty + GetResourceManager()->MarkDirtyResource(record->Resource); + + ResourceId texId = record->GetResourceID(); + + m_Textures[texId].width = width; + m_Textures[texId].height = height; + m_Textures[texId].depth = 1; + m_Textures[texId].dimension = 2; + m_Textures[texId].internalFormat = internalFormat; + m_Textures[texId].mipsValid = (1 << levels) - 1; + } +} + +template +bool WrappedOpenGL::Serialise_glTextureStorageMem2DMultisampleEXT( + SerialiserType &ser, GLuint textureHandle, GLsizei samples, GLenum internalFormat, GLsizei width, + GLsizei height, GLboolean fixedSampleLocations, GLuint memoryHandle, GLuint64 offset) +{ + SERIALISE_ELEMENT_LOCAL(texture, TextureRes(GetCtx(), textureHandle)); + SERIALISE_ELEMENT(samples); + SERIALISE_ELEMENT(internalFormat); + SERIALISE_ELEMENT(width); + SERIALISE_ELEMENT(height); + SERIALISE_ELEMENT_TYPED(bool, fixedSampleLocations); + SERIALISE_ELEMENT_LOCAL(memory, ExtMemRes(GetCtx(), memoryHandle)); + SERIALISE_ELEMENT(offset); + + SERIALISE_CHECK_READ_ERRORS(); + + if(IsReplayingAndReading()) + { + // Replay external texture storage backed by external memory as just a plain texture. + ResourceId liveId = GetResourceManager()->GetID(texture); + m_Textures[liveId].width = width; + m_Textures[liveId].height = height; + m_Textures[liveId].depth = 1; + m_Textures[liveId].samples = samples; + m_Textures[liveId].dimension = 2; + m_Textures[liveId].internalFormat = internalFormat; + m_Textures[liveId].emulated = false; + m_Textures[liveId].mipsValid = 1; + + GL.glTextureStorage2DMultisampleEXT(texture.name, m_Textures[liveId].curType, samples, + internalFormat, width, height, fixedSampleLocations); + + AddResourceInitChunk(texture); + DerivedResource(memory, GetResourceManager()->GetOriginalID(liveId)); + } + + return true; +} + +void WrappedOpenGL::glTextureStorageMem2DMultisampleEXT(GLuint texture, GLsizei samples, + GLenum internalFormat, GLsizei width, + GLsizei height, + GLboolean fixedSampleLocations, + GLuint memory, GLuint64 offset) +{ + SERIALISE_TIME_CALL(GL.glTextureStorageMem2DMultisampleEXT( + texture, samples, internalFormat, width, height, fixedSampleLocations, memory, offset)); + + if(IsCaptureMode(m_State)) + { + GLResourceRecord *record = GetResourceManager()->GetResourceRecord(TextureRes(GetCtx(), texture)); + + if(!record) + { + RDCERR("Calling glTextureStorageMem2DMultisampleEXT with unrecognised texture"); + return; + } + + USE_SCRATCH_SERIALISER(); + SCOPED_SERIALISE_CHUNK(gl_CurChunk); + Serialise_glTextureStorageMem2DMultisampleEXT(ser, texture, samples, internalFormat, width, + height, fixedSampleLocations, memory, offset); + + record->AddChunk(scope.Get()); + + // when bound to external memory, immediately consider dirty + GetResourceManager()->MarkDirtyResource(record->Resource); + + ResourceId texId = record->GetResourceID(); + + m_Textures[texId].width = width; + m_Textures[texId].height = height; + m_Textures[texId].samples = samples; + m_Textures[texId].depth = 1; + m_Textures[texId].dimension = 2; + m_Textures[texId].internalFormat = internalFormat; + m_Textures[texId].mipsValid = 1; + } +} + +void WrappedOpenGL::glTexStorageMem2DMultisampleEXT(GLenum target, GLsizei samples, + GLenum internalFormat, GLsizei width, + GLsizei height, GLboolean fixedSampleLocations, + GLuint memory, GLuint64 offset) +{ + SERIALISE_TIME_CALL(GL.glTexStorageMem2DMultisampleEXT( + target, samples, internalFormat, width, height, fixedSampleLocations, memory, offset)); + + if(IsCaptureMode(m_State)) + { + GLResourceRecord *record = GetCtxData().GetActiveTexRecord(); + + if(!record) + { + RDCERR("Calling glTexStorageMem2DMultisampleEXT with no texture bound"); + return; + } + + USE_SCRATCH_SERIALISER(); + SCOPED_SERIALISE_CHUNK(gl_CurChunk); + Serialise_glTextureStorageMem2DMultisampleEXT(ser, record->Resource.name, samples, + internalFormat, width, height, + fixedSampleLocations, memory, offset); + + record->AddChunk(scope.Get()); + + GetResourceManager()->MarkDirtyResource(record->Resource); + + ResourceId texId = record->GetResourceID(); + + m_Textures[texId].width = width; + m_Textures[texId].height = height; + m_Textures[texId].samples = samples; + m_Textures[texId].depth = 1; + m_Textures[texId].dimension = 2; + m_Textures[texId].internalFormat = internalFormat; + m_Textures[texId].mipsValid = 1; + } +} + +template +bool WrappedOpenGL::Serialise_glTextureStorageMem3DEXT(SerialiserType &ser, GLuint textureHandle, + GLsizei levels, GLenum internalFormat, + GLsizei width, GLsizei height, GLsizei depth, + GLuint memoryHandle, GLuint64 offset) +{ + SERIALISE_ELEMENT_LOCAL(texture, TextureRes(GetCtx(), textureHandle)); + SERIALISE_ELEMENT(levels); + SERIALISE_ELEMENT(internalFormat); + SERIALISE_ELEMENT(width); + SERIALISE_ELEMENT(height); + SERIALISE_ELEMENT(depth); + SERIALISE_ELEMENT_LOCAL(memory, ExtMemRes(GetCtx(), memoryHandle)); + SERIALISE_ELEMENT(offset); + + SERIALISE_CHECK_READ_ERRORS(); + + if(IsReplayingAndReading()) + { + // Replay external texture storage backed by external memory as just a plain texture. + ResourceId liveId = GetResourceManager()->GetID(texture); + m_Textures[liveId].width = width; + m_Textures[liveId].height = height; + m_Textures[liveId].depth = depth; + m_Textures[liveId].dimension = 3; + m_Textures[liveId].internalFormat = internalFormat; + m_Textures[liveId].emulated = false; + m_Textures[liveId].mipsValid = (1 << levels) - 1; + + GL.glTextureStorage3DEXT(texture.name, m_Textures[liveId].curType, levels, internalFormat, + width, height, depth); + + AddResourceInitChunk(texture); + DerivedResource(memory, GetResourceManager()->GetOriginalID(liveId)); + } + + return true; +} + +void WrappedOpenGL::glTextureStorageMem3DEXT(GLuint texture, GLsizei levels, GLenum internalFormat, + GLsizei width, GLsizei height, GLsizei depth, + GLuint memory, GLuint64 offset) +{ + SERIALISE_TIME_CALL(GL.glTextureStorageMem3DEXT(texture, levels, internalFormat, width, height, + depth, memory, offset)); + + if(IsCaptureMode(m_State)) + { + GLResourceRecord *record = GetResourceManager()->GetResourceRecord(TextureRes(GetCtx(), texture)); + + if(!record) + { + RDCERR("Calling glTextureStorageMem3DEXT with unrecognised texture"); + return; + } + + USE_SCRATCH_SERIALISER(); + SCOPED_SERIALISE_CHUNK(gl_CurChunk); + Serialise_glTextureStorageMem3DEXT(ser, texture, levels, internalFormat, width, height, depth, + memory, offset); + + record->AddChunk(scope.Get()); + + GetResourceManager()->MarkDirtyResource(record->Resource); + + ResourceId texId = record->GetResourceID(); + + m_Textures[texId].width = width; + m_Textures[texId].height = height; + m_Textures[texId].depth = depth; + m_Textures[texId].dimension = 3; + m_Textures[texId].internalFormat = internalFormat; + m_Textures[texId].mipsValid = (1 << levels) - 1; + } +} + +void WrappedOpenGL::glTexStorageMem3DEXT(GLenum target, GLsizei levels, GLenum internalFormat, + GLsizei width, GLsizei height, GLsizei depth, + GLuint memory, GLuint64 offset) +{ + SERIALISE_TIME_CALL(GL.glTexStorageMem3DEXT(target, levels, internalFormat, width, height, depth, + memory, offset)); + + if(IsCaptureMode(m_State)) + { + GLResourceRecord *record = GetCtxData().GetActiveTexRecord(); + + if(!record) + { + RDCERR("Calling glTextureStorageMem3DEXT with no texture bound"); + return; + } + + USE_SCRATCH_SERIALISER(); + SCOPED_SERIALISE_CHUNK(gl_CurChunk); + Serialise_glTextureStorageMem3DEXT(ser, record->Resource.name, levels, internalFormat, width, + height, depth, memory, offset); + + record->AddChunk(scope.Get()); + + GetResourceManager()->MarkDirtyResource(record->Resource); + + ResourceId texId = record->GetResourceID(); + + m_Textures[texId].width = width; + m_Textures[texId].height = height; + m_Textures[texId].depth = depth; + m_Textures[texId].dimension = 3; + m_Textures[texId].internalFormat = internalFormat; + m_Textures[texId].mipsValid = (1 << levels) - 1; + } +} + +template +bool WrappedOpenGL::Serialise_glTextureStorageMem3DMultisampleEXT( + SerialiserType &ser, GLuint textureHandle, GLsizei samples, GLenum internalFormat, + GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations, + GLuint memoryHandle, GLuint64 offset) +{ + SERIALISE_ELEMENT_LOCAL(texture, TextureRes(GetCtx(), textureHandle)); + SERIALISE_ELEMENT(samples); + SERIALISE_ELEMENT(internalFormat); + SERIALISE_ELEMENT(width); + SERIALISE_ELEMENT(height); + SERIALISE_ELEMENT(depth); + SERIALISE_ELEMENT_TYPED(bool, fixedSampleLocations); + SERIALISE_ELEMENT_LOCAL(memory, ExtMemRes(GetCtx(), memoryHandle)); + SERIALISE_ELEMENT(offset); + + SERIALISE_CHECK_READ_ERRORS(); + + if(IsReplayingAndReading()) + { + // Replay external texture storage backed by external memory as just a plain texture. + ResourceId liveId = GetResourceManager()->GetID(texture); + m_Textures[liveId].width = width; + m_Textures[liveId].height = height; + m_Textures[liveId].depth = depth; + m_Textures[liveId].samples = samples; + m_Textures[liveId].dimension = 3; + m_Textures[liveId].internalFormat = internalFormat; + m_Textures[liveId].emulated = false; + m_Textures[liveId].mipsValid = 1; + + GL.glTextureStorage3DMultisampleEXT(texture.name, m_Textures[liveId].curType, samples, + internalFormat, width, height, depth, fixedSampleLocations); + + AddResourceInitChunk(texture); + DerivedResource(memory, GetResourceManager()->GetOriginalID(liveId)); + } + + return true; +} + +void WrappedOpenGL::glTextureStorageMem3DMultisampleEXT(GLuint texture, GLsizei samples, + GLenum internalFormat, GLsizei width, + GLsizei height, GLsizei depth, + GLboolean fixedSampleLocations, + GLuint memory, GLuint64 offset) +{ + SERIALISE_TIME_CALL(GL.glTextureStorageMem3DMultisampleEXT( + texture, samples, internalFormat, width, height, depth, fixedSampleLocations, memory, offset)); + + if(IsCaptureMode(m_State)) + { + GLResourceRecord *record = GetResourceManager()->GetResourceRecord(TextureRes(GetCtx(), texture)); + + if(!record) + { + RDCERR("Calling glTextureStorageMem3DMultisampleEXT with unrecognised texture"); + return; + } + + USE_SCRATCH_SERIALISER(); + SCOPED_SERIALISE_CHUNK(gl_CurChunk); + Serialise_glTextureStorageMem3DMultisampleEXT(ser, texture, samples, internalFormat, width, + height, depth, fixedSampleLocations, memory, + offset); + + record->AddChunk(scope.Get()); + + GetResourceManager()->MarkDirtyResource(record->Resource); + + ResourceId texId = record->GetResourceID(); + + m_Textures[texId].width = width; + m_Textures[texId].height = height; + m_Textures[texId].samples = samples; + m_Textures[texId].depth = depth; + m_Textures[texId].dimension = 3; + m_Textures[texId].internalFormat = internalFormat; + m_Textures[texId].mipsValid = 1; + } +} + +void WrappedOpenGL::glTexStorageMem3DMultisampleEXT(GLenum target, GLsizei samples, + GLenum internalFormat, GLsizei width, + GLsizei height, GLsizei depth, + GLboolean fixedSampleLocations, GLuint memory, + GLuint64 offset) +{ + SERIALISE_TIME_CALL(GL.glTexStorageMem3DMultisampleEXT( + target, samples, internalFormat, width, height, depth, fixedSampleLocations, memory, offset)); + + if(IsCaptureMode(m_State)) + { + GLResourceRecord *record = GetCtxData().GetActiveTexRecord(); + + if(!record) + { + RDCERR("Calling glTexStorageMem3DMultisampleEXT with no texture bound"); + return; + } + + USE_SCRATCH_SERIALISER(); + SCOPED_SERIALISE_CHUNK(gl_CurChunk); + Serialise_glTextureStorageMem3DMultisampleEXT(ser, record->Resource.name, samples, + internalFormat, width, height, depth, + fixedSampleLocations, memory, offset); + + record->AddChunk(scope.Get()); + + GetResourceManager()->MarkDirtyResource(record->Resource); + + ResourceId texId = record->GetResourceID(); + + m_Textures[texId].width = width; + m_Textures[texId].height = height; + m_Textures[texId].samples = samples; + m_Textures[texId].depth = depth; + m_Textures[texId].dimension = 3; + m_Textures[texId].internalFormat = internalFormat; + m_Textures[texId].mipsValid = 1; + } +} + +#pragma endregion + INSTANTIATE_FUNCTION_SERIALISED(void, wglDXRegisterObjectNV, GLResource Resource, GLenum type, void *dxObject); -INSTANTIATE_FUNCTION_SERIALISED(void, wglDXLockObjectsNV, GLResource Resource); \ No newline at end of file +INSTANTIATE_FUNCTION_SERIALISED(void, wglDXLockObjectsNV, GLResource Resource); +INSTANTIATE_FUNCTION_SERIALISED(void, glCreateMemoryObjectsEXT, GLsizei n, GLuint *memoryObjects); +INSTANTIATE_FUNCTION_SERIALISED(void, glMemoryObjectParameterivEXT, GLuint memoryObject, + GLenum pname, const GLint *params); +INSTANTIATE_FUNCTION_SERIALISED(void, glTextureStorageMem1DEXT, GLuint texture, GLsizei levels, + GLenum internalFormat, GLsizei width, GLuint memory, GLuint64 offset); +INSTANTIATE_FUNCTION_SERIALISED(void, glTextureStorageMem2DEXT, GLuint texture, GLsizei levels, + GLenum internalFormat, GLsizei width, GLsizei height, GLuint memory, + GLuint64 offset); +INSTANTIATE_FUNCTION_SERIALISED(void, glTextureStorageMem2DMultisampleEXT, GLuint texture, + GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height, + GLboolean fixedSampleLocations, GLuint memory, GLuint64 offset); +INSTANTIATE_FUNCTION_SERIALISED(void, glTextureStorageMem3DEXT, GLuint texture, GLsizei levels, + GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, + GLuint memory, GLuint64 offset); +INSTANTIATE_FUNCTION_SERIALISED(void, glTextureStorageMem3DMultisampleEXT, GLuint texture, + GLsizei samples, GLenum internalFormat, GLsizei width, + GLsizei height, GLsizei depth, GLboolean fixedSampleLocations, + GLuint memory, GLuint64 offset); +INSTANTIATE_FUNCTION_SERIALISED(void, glNamedBufferStorageMemEXT, GLuint buffer, GLsizeiptr size, + GLuint memory, GLuint64 offset); +INSTANTIATE_FUNCTION_SERIALISED(void, glGenSemaphoresEXT, GLsizei n, GLuint *semaphores); +INSTANTIATE_FUNCTION_SERIALISED(void, glSemaphoreParameterui64vEXT, GLuint semaphore, GLenum pname, + const GLuint64 *params); +INSTANTIATE_FUNCTION_SERIALISED(void, glWaitSemaphoreEXT, GLuint semaphore, GLuint numBufferBarriers, + const GLuint *buffers, GLuint numTextureBarriers, + const GLuint *textures, const GLenum *srcLayouts); +INSTANTIATE_FUNCTION_SERIALISED(void, glSignalSemaphoreEXT, GLuint semaphore, + GLuint numBufferBarriers, const GLuint *buffers, + GLuint numTextureBarriers, const GLuint *textures, + const GLenum *dstLayouts); +INSTANTIATE_FUNCTION_SERIALISED(void, glImportMemoryFdEXT, GLuint memory, GLuint64 size, + GLenum handleType, GLint fd); +INSTANTIATE_FUNCTION_SERIALISED(void, glImportSemaphoreFdEXT, GLuint semaphore, GLenum handleType, + GLint fd); +INSTANTIATE_FUNCTION_SERIALISED(void, glImportMemoryWin32HandleEXT, GLuint memory, GLuint64 size, + GLenum handleType, void *handle); +INSTANTIATE_FUNCTION_SERIALISED(void, glImportMemoryWin32NameEXT, GLuint memory, GLuint64 size, + GLenum handleType, const void *name); +INSTANTIATE_FUNCTION_SERIALISED(void, glImportSemaphoreWin32HandleEXT, GLuint semaphore, + GLenum handleType, void *handle); +INSTANTIATE_FUNCTION_SERIALISED(void, glImportSemaphoreWin32NameEXT, GLuint semaphore, + GLenum handleType, const void *name); +INSTANTIATE_FUNCTION_SERIALISED(GLboolean, glAcquireKeyedMutexWin32EXT, GLuint memory, GLuint64 key, + GLuint timeout); +INSTANTIATE_FUNCTION_SERIALISED(GLboolean, glReleaseKeyedMutexWin32EXT, GLuint memory, GLuint64 key); \ No newline at end of file