diff --git a/renderdoc/driver/gl/gl_common.h b/renderdoc/driver/gl/gl_common.h index f0247dbc0..48da01959 100644 --- a/renderdoc/driver/gl/gl_common.h +++ b/renderdoc/driver/gl/gl_common.h @@ -665,6 +665,8 @@ enum GLChunkType FRAMEBUFFER_TEX3D, FRAMEBUFFER_RENDBUF, FRAMEBUFFER_TEXLAYER, + FRAMEBUFFER_MULTIVIEW, + FRAMEBUFFER_MULTIVIEWMS, FRAMEBUFFER_PARAM, READ_BUFFER, BIND_FRAMEBUFFER, diff --git a/renderdoc/driver/gl/gl_driver.cpp b/renderdoc/driver/gl/gl_driver.cpp index 75c7f5754..c2361df0e 100644 --- a/renderdoc/driver/gl/gl_driver.cpp +++ b/renderdoc/driver/gl/gl_driver.cpp @@ -252,6 +252,8 @@ const char *GLChunkNames[] = { "glFramebufferTexture3D", "glFramebufferRenderbuffer", "glFramebufferTextureLayer", + "glFramebufferTextureMultiviewOVR", + "glFramebufferTextureMultisampleMultiviewOVR", "glFramebufferParameteri", "glReadBuffer", "glBindFramebuffer", @@ -815,6 +817,9 @@ void WrappedOpenGL::BuildGLESExtensions() m_GLESExtensions.push_back("GL_OES_texture_storage_multisample_2d_array"); m_GLESExtensions.push_back("GL_OES_vertex_array_object"); m_GLESExtensions.push_back("GL_OES_vertex_half_float"); + m_GLESExtensions.push_back("GL_OVR_multiview"); + m_GLESExtensions.push_back("GL_OVR_multiview2"); + m_GLESExtensions.push_back("GL_OVR_multiview_multisampled_render_to_texture"); // advertise EGL extensions in the gl ext string, just in case anyone is checking it for // this way. @@ -2562,7 +2567,7 @@ void WrappedOpenGL::CreateVRAPITextureSwapChain(GLuint tex, GLenum textureType, if(textureType == eGL_TEXTURE_2D_ARRAY) { - Common_glTextureImage3DEXT(id, eGL_TEXTURE_2D, 0, internalformat, width, height, 2, 0, eGL_RGBA, + Common_glTextureImage3DEXT(id, eGL_TEXTURE_2D_ARRAY, 0, internalformat, width, height, 2, 0, eGL_RGBA, eGL_UNSIGNED_BYTE, NULL); } else @@ -3765,6 +3770,12 @@ void WrappedOpenGL::ProcessChunk(uint64_t offset, GLChunkType context) case FRAMEBUFFER_TEXLAYER: Serialise_glNamedFramebufferTextureLayerEXT(0, eGL_NONE, 0, 0, 0); break; + case FRAMEBUFFER_MULTIVIEW: + Serialise_glFramebufferTextureMultiviewOVR(eGL_NONE, eGL_NONE, 0, 0, 0, 0); + break; + case FRAMEBUFFER_MULTIVIEWMS: + Serialise_glFramebufferTextureMultisampleMultiviewOVR(eGL_NONE, eGL_NONE, 0, 0, 0, 0, 0); + break; case FRAMEBUFFER_PARAM: Serialise_glNamedFramebufferParameteriEXT(0, eGL_NONE, 0); break; case READ_BUFFER: Serialise_glFramebufferReadBufferEXT(0, eGL_NONE); break; case BIND_FRAMEBUFFER: Serialise_glBindFramebuffer(eGL_NONE, 0); break; diff --git a/renderdoc/driver/gl/gl_driver.h b/renderdoc/driver/gl/gl_driver.h index 54be5a77d..c6ff95942 100644 --- a/renderdoc/driver/gl/gl_driver.h +++ b/renderdoc/driver/gl/gl_driver.h @@ -780,6 +780,16 @@ public: IMPLEMENT_FUNCTION_SERIALISED(void, glFramebufferTextureLayer(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer)); + + IMPLEMENT_FUNCTION_SERIALISED( + void, glFramebufferTextureMultiviewOVR(GLenum target, GLenum attachment, GLuint texture, + GLint level, GLint baseViewIndex, GLsizei numViews)); + + IMPLEMENT_FUNCTION_SERIALISED( + void, glFramebufferTextureMultisampleMultiviewOVR(GLenum target, GLenum attachment, + GLuint texture, GLint level, GLsizei samples, + GLint baseViewIndex, GLsizei numViews)); + IMPLEMENT_FUNCTION_SERIALISED(void, glFramebufferParameteri(GLenum target, GLenum pname, GLint param)); IMPLEMENT_FUNCTION_SERIALISED(void, glDeleteFramebuffers(GLsizei n, const GLuint *framebuffers)); diff --git a/renderdoc/driver/gl/gl_hookset.h b/renderdoc/driver/gl/gl_hookset.h index c40aeb3c1..e414d1b98 100644 --- a/renderdoc/driver/gl/gl_hookset.h +++ b/renderdoc/driver/gl/gl_hookset.h @@ -648,6 +648,12 @@ struct GLHookSet // GREMEDY_string_marker PFNGLSTRINGMARKERGREMEDYPROC glStringMarkerGREMEDY; + // OVR_multiview + PFNGLFRAMEBUFFERTEXTUREMULTIVIEWOVRPROC glFramebufferTextureMultiviewOVR; + + // OVR_multiview_multisampled_render_to_texture + PFNGLFRAMEBUFFERTEXTUREMULTISAMPLEMULTIVIEWOVRPROC glFramebufferTextureMultisampleMultiviewOVR; + // 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_hookset_defs.h b/renderdoc/driver/gl/gl_hookset_defs.h index d1a6d9966..597bd5a7d 100644 --- a/renderdoc/driver/gl/gl_hookset_defs.h +++ b/renderdoc/driver/gl/gl_hookset_defs.h @@ -1156,12 +1156,14 @@ HookExtension(PFNGLRASTERSAMPLESEXTPROC, glRasterSamplesEXT); \ HookExtension(PFNGLFRAMETERMINATORGREMEDYPROC, glFrameTerminatorGREMEDY); \ HookExtension(PFNGLSTRINGMARKERGREMEDYPROC, glStringMarkerGREMEDY); \ + HookExtension(PFNGLFRAMEBUFFERTEXTUREMULTIVIEWOVRPROC, glFramebufferTextureMultiviewOVR); \ HookExtension(PFNGLBLENDBARRIERPROC, glBlendBarrier); \ HookExtension(PFNGLPRIMITIVEBOUNDINGBOXPROC, glPrimitiveBoundingBox); \ HookExtensionAlias(PFNGLPRIMITIVEBOUNDINGBOXPROC, glPrimitiveBoundingBox, glPrimitiveBoundingBoxEXT); \ HookExtensionAlias(PFNGLPRIMITIVEBOUNDINGBOXPROC, glPrimitiveBoundingBox, glPrimitiveBoundingBoxOES); \ HookExtension(PFNGLDISCARDFRAMEBUFFEREXTPROC, glDiscardFramebufferEXT); \ HookExtension(PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEEXTPROC, glFramebufferTexture2DMultisampleEXT); \ + HookExtension(PFNGLFRAMEBUFFERTEXTUREMULTISAMPLEMULTIVIEWOVRPROC, glFramebufferTextureMultisampleMultiviewOVR); \ HookExtension(PFNWGLDXSETRESOURCESHAREHANDLENVPROC, wglDXSetResourceShareHandleNV); \ HookExtension(PFNWGLDXOPENDEVICENVPROC, wglDXOpenDeviceNV); \ HookExtension(PFNWGLDXCLOSEDEVICENVPROC, wglDXCloseDeviceNV); \ @@ -2014,10 +2016,12 @@ HookWrapper2(void, glRasterSamplesEXT, GLuint, samples, GLboolean, fixedsamplelocations); \ HookWrapper0(void, glFrameTerminatorGREMEDY); \ HookWrapper2(void, glStringMarkerGREMEDY, GLsizei, len, const void *, string); \ + HookWrapper6(void, glFramebufferTextureMultiviewOVR, GLenum, target, GLenum, attachment, GLuint, texture, GLint, level, GLint, baseViewIndex, GLsizei, numViews); \ HookWrapper0(void, glBlendBarrier); \ HookWrapper8(void, glPrimitiveBoundingBox, GLfloat, minX, GLfloat, minY, GLfloat, minZ, GLfloat, minW, GLfloat, maxX, GLfloat, maxY, GLfloat, maxZ, GLfloat, maxW); \ HookWrapper3(void, glDiscardFramebufferEXT, GLenum, target, GLsizei, numAttachments, const GLenum *, attachments); \ HookWrapper6(void, glFramebufferTexture2DMultisampleEXT, GLenum, target, GLenum, attachment, GLenum, textarget, GLuint, texture, GLint, level, GLsizei, samples); \ + HookWrapper7(void, glFramebufferTextureMultisampleMultiviewOVR, GLenum, target, GLenum, attachment, GLuint, texture, GLint, level, GLsizei, samples, GLint, baseViewIndex, GLsizei, numViews); \ HookWrapper2(BOOL, wglDXSetResourceShareHandleNV, void *, dxObject, HANDLE, shareHandle); \ HookWrapper1(HANDLE, wglDXOpenDeviceNV, void *, dxDevice); \ HookWrapper1(BOOL, wglDXCloseDeviceNV, HANDLE, hDevice); \ @@ -3428,7 +3432,6 @@ HookWrapper4(void, glvideocapturestreamparameterivnv, GLuint, video_capture_slot, GLuint, stream, GLenum, pname, const GLint *, params); \ HookWrapper4(void, glvideocapturestreamparameterfvnv, GLuint, video_capture_slot, GLuint, stream, GLenum, pname, const GLfloat *, params); \ HookWrapper4(void, glvideocapturestreamparameterdvnv, GLuint, video_capture_slot, GLuint, stream, GLenum, pname, const GLdouble *, params); \ - HookWrapper6(void, glframebuffertexturemultiviewovr, GLenum, target, GLenum, attachment, GLuint, texture, GLint, level, GLint, baseViewIndex, GLsizei, numViews); \ HookWrapper2(void, glhintpgi, GLenum, target, GLint, mode); \ HookWrapper3(void, gldetailtexfuncsgis, GLenum, target, GLsizei, n, const GLfloat *, points); \ HookWrapper2(void, glgetdetailtexfuncsgis, GLenum, target, GLfloat *, points); \ @@ -3695,7 +3698,6 @@ HookWrapper2(void, gldisableinv, GLenum, target, GLuint, index); \ HookWrapper2(GLboolean, glisenabledinv, GLenum, target, GLuint, index); \ HookWrapper5(void, glviewportswizzlenv, GLuint, index, GLenum, swizzlex, GLenum, swizzley, GLenum, swizzlez, GLenum, swizzlew); \ - HookWrapper7(void, glframebuffertexturemultisamplemultiviewovr, GLenum, target, GLenum, attachment, GLuint, texture, GLint, level, GLsizei, samples, GLint, baseViewIndex, GLsizei, numViews); \ HookWrapper2(void, glalphafuncqcom, GLenum, func, GLclampf, ref); \ HookWrapper3(void, glgetdrivercontrolsqcom, GLint *, num, GLsizei, size, GLuint *, driverControls); \ HookWrapper4(void, glgetdrivercontrolstringqcom, GLuint, driverControl, GLsizei, bufSize, GLsizei *, length, GLchar *, driverControlString); \ @@ -5393,7 +5395,6 @@ HandleUnsupported(PFNGLVIDEOCAPTURESTREAMPARAMETERIVNVPROC, glvideocapturestreamparameterivnv); \ HandleUnsupported(PFNGLVIDEOCAPTURESTREAMPARAMETERFVNVPROC, glvideocapturestreamparameterfvnv); \ HandleUnsupported(PFNGLVIDEOCAPTURESTREAMPARAMETERDVNVPROC, glvideocapturestreamparameterdvnv); \ - HandleUnsupported(PFNGLFRAMEBUFFERTEXTUREMULTIVIEWOVRPROC, glframebuffertexturemultiviewovr); \ HandleUnsupported(PFNGLHINTPGIPROC, glhintpgi); \ HandleUnsupported(PFNGLDETAILTEXFUNCSGISPROC, gldetailtexfuncsgis); \ HandleUnsupported(PFNGLGETDETAILTEXFUNCSGISPROC, glgetdetailtexfuncsgis); \ @@ -5660,7 +5661,6 @@ HandleUnsupported(PFNGLDISABLEINVPROC, gldisableinv); \ HandleUnsupported(PFNGLISENABLEDINVPROC, glisenabledinv); \ HandleUnsupported(PFNGLVIEWPORTSWIZZLENVPROC, glviewportswizzlenv); \ - HandleUnsupported(PFNGLFRAMEBUFFERTEXTUREMULTISAMPLEMULTIVIEWOVRPROC, glframebuffertexturemultisamplemultiviewovr); \ HandleUnsupported(PFNGLALPHAFUNCQCOMPROC, glalphafuncqcom); \ HandleUnsupported(PFNGLGETDRIVERCONTROLSQCOMPROC, glgetdrivercontrolsqcom); \ HandleUnsupported(PFNGLGETDRIVERCONTROLSTRINGQCOMPROC, glgetdrivercontrolstringqcom); \ diff --git a/renderdoc/driver/gl/wrappers/gl_framebuffer_funcs.cpp b/renderdoc/driver/gl/wrappers/gl_framebuffer_funcs.cpp index e173acd9a..0681c5049 100644 --- a/renderdoc/driver/gl/wrappers/gl_framebuffer_funcs.cpp +++ b/renderdoc/driver/gl/wrappers/gl_framebuffer_funcs.cpp @@ -1100,6 +1100,201 @@ void WrappedOpenGL::glFramebufferTextureLayer(GLenum target, GLenum attachment, } } +bool WrappedOpenGL::Serialise_glFramebufferTextureMultiviewOVR(GLenum target, GLenum attachment, + GLuint texture, GLint level, + GLint baseViewIndex, GLsizei numViews) +{ + SERIALISE_ELEMENT(GLenum, Target, target); + SERIALISE_ELEMENT(GLenum, Attach, attachment); + SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(TextureRes(GetCtx(), texture))); + SERIALISE_ELEMENT(int32_t, Level, level); + SERIALISE_ELEMENT(int32_t, BaseViewIndex, baseViewIndex); + SERIALISE_ELEMENT(uint32_t, NumViews, numViews); + + if(m_State < WRITING) + { + GLuint tex = (id == ResourceId() || !GetResourceManager()->HasLiveResource(id)) + ? 0 + : GetResourceManager()->GetLiveResource(id).name; + + m_Real.glFramebufferTextureMultiviewOVR(Target, Attach, tex, Level, BaseViewIndex, NumViews); + + if(m_State == READING && tex) + { + if(Attach == eGL_DEPTH_ATTACHMENT || Attach == eGL_DEPTH_STENCIL_ATTACHMENT) + m_Textures[GetResourceManager()->GetLiveID(id)].creationFlags |= TextureCategory::DepthTarget; + else + m_Textures[GetResourceManager()->GetLiveID(id)].creationFlags |= TextureCategory::ColorTarget; + } + } + + return true; +} + +void WrappedOpenGL::glFramebufferTextureMultiviewOVR(GLenum target, GLenum attachment, + GLuint texture, GLint level, + GLint baseViewIndex, GLsizei numViews) +{ + m_Real.glFramebufferTextureMultiviewOVR(target, attachment, texture, level, baseViewIndex, + numViews); + + if(m_State >= WRITING) + { + GLResourceRecord *record = m_DeviceRecord; + + if(target == eGL_DRAW_FRAMEBUFFER || target == eGL_FRAMEBUFFER) + { + if(GetCtxData().m_DrawFramebufferRecord) + record = GetCtxData().m_DrawFramebufferRecord; + } + else + { + if(GetCtxData().m_ReadFramebufferRecord) + record = GetCtxData().m_ReadFramebufferRecord; + } + + if(texture != 0 && GetResourceManager()->HasResourceRecord(TextureRes(GetCtx(), texture))) + { + ResourceRecord *texrecord = + GetResourceManager()->GetResourceRecord(TextureRes(GetCtx(), texture)); + if(m_State == WRITING_IDLE) + GetResourceManager()->MarkDirtyResource(texrecord->GetResourceID()); + else + m_MissingTracks.insert(texrecord->GetResourceID()); + } + + if(m_HighTrafficResources.find(record->GetResourceID()) != m_HighTrafficResources.end() && + m_State != WRITING_CAPFRAME) + return; + + SCOPED_SERIALISE_CONTEXT(FRAMEBUFFER_MULTIVIEW); + Serialise_glFramebufferTextureMultiviewOVR(target, attachment, texture, level, baseViewIndex, + numViews); + + if(m_State == WRITING_IDLE) + { + record->AddChunk(scope.Get()); + + if(record != m_DeviceRecord) + { + record->UpdateCount++; + + if(record->UpdateCount > 10) + { + m_HighTrafficResources.insert(record->GetResourceID()); + GetResourceManager()->MarkDirtyResource(record->GetResourceID()); + } + } + } + else + { + m_ContextRecord->AddChunk(scope.Get()); + GetResourceManager()->MarkFBOReferenced(record->Resource, eFrameRef_ReadBeforeWrite); + GetResourceManager()->MarkResourceFrameReferenced(TextureRes(GetCtx(), texture), + eFrameRef_Read); + } + } +} + +bool WrappedOpenGL::Serialise_glFramebufferTextureMultisampleMultiviewOVR( + GLenum target, GLenum attachment, GLuint texture, GLint level, GLsizei samples, + GLint baseViewIndex, GLsizei numViews) +{ + SERIALISE_ELEMENT(GLenum, Target, target); + SERIALISE_ELEMENT(GLenum, Attach, attachment); + SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(TextureRes(GetCtx(), texture))); + SERIALISE_ELEMENT(int32_t, Level, level); + SERIALISE_ELEMENT(uint32_t, Samples, samples); + SERIALISE_ELEMENT(int32_t, BaseViewIndex, baseViewIndex); + SERIALISE_ELEMENT(uint32_t, NumViews, numViews); + + if(m_State < WRITING) + { + GLuint tex = (id == ResourceId() || !GetResourceManager()->HasLiveResource(id)) + ? 0 + : GetResourceManager()->GetLiveResource(id).name; + + m_Real.glFramebufferTextureMultisampleMultiviewOVR(Target, Attach, tex, Level, Samples, + BaseViewIndex, NumViews); + + if(m_State == READING && tex) + { + if(Attach == eGL_DEPTH_ATTACHMENT || Attach == eGL_DEPTH_STENCIL_ATTACHMENT) + m_Textures[GetResourceManager()->GetLiveID(id)].creationFlags |= TextureCategory::DepthTarget; + else + m_Textures[GetResourceManager()->GetLiveID(id)].creationFlags |= TextureCategory::ColorTarget; + } + } + + return true; +} + +void WrappedOpenGL::glFramebufferTextureMultisampleMultiviewOVR(GLenum target, GLenum attachment, + GLuint texture, GLint level, + GLsizei samples, GLint baseViewIndex, + GLsizei numViews) +{ + m_Real.glFramebufferTextureMultisampleMultiviewOVR(target, attachment, texture, level, samples, + baseViewIndex, numViews); + + if(m_State >= WRITING) + { + GLResourceRecord *record = m_DeviceRecord; + + if(target == eGL_DRAW_FRAMEBUFFER || target == eGL_FRAMEBUFFER) + { + if(GetCtxData().m_DrawFramebufferRecord) + record = GetCtxData().m_DrawFramebufferRecord; + } + else + { + if(GetCtxData().m_ReadFramebufferRecord) + record = GetCtxData().m_ReadFramebufferRecord; + } + + if(texture != 0 && GetResourceManager()->HasResourceRecord(TextureRes(GetCtx(), texture))) + { + ResourceRecord *texrecord = + GetResourceManager()->GetResourceRecord(TextureRes(GetCtx(), texture)); + if(m_State == WRITING_IDLE) + GetResourceManager()->MarkDirtyResource(texrecord->GetResourceID()); + else + m_MissingTracks.insert(texrecord->GetResourceID()); + } + + if(m_HighTrafficResources.find(record->GetResourceID()) != m_HighTrafficResources.end() && + m_State != WRITING_CAPFRAME) + return; + + SCOPED_SERIALISE_CONTEXT(FRAMEBUFFER_MULTIVIEWMS); + Serialise_glFramebufferTextureMultisampleMultiviewOVR(target, attachment, texture, level, + samples, baseViewIndex, numViews); + + if(m_State == WRITING_IDLE) + { + record->AddChunk(scope.Get()); + + if(record != m_DeviceRecord) + { + record->UpdateCount++; + + if(record->UpdateCount > 10) + { + m_HighTrafficResources.insert(record->GetResourceID()); + GetResourceManager()->MarkDirtyResource(record->GetResourceID()); + } + } + } + else + { + m_ContextRecord->AddChunk(scope.Get()); + GetResourceManager()->MarkFBOReferenced(record->Resource, eFrameRef_ReadBeforeWrite); + GetResourceManager()->MarkResourceFrameReferenced(TextureRes(GetCtx(), texture), + eFrameRef_Read); + } + } +} + bool WrappedOpenGL::Serialise_glNamedFramebufferParameteriEXT(GLuint framebuffer, GLenum pname, GLint param) {