From cb359681f82fc2caf266f384345b9f7c8fd6af7a Mon Sep 17 00:00:00 2001
From: Alyssa Rosenzweig <alyssa@rosenzweig.io>
Date: Wed, 7 Jun 2023 21:27:08 -0400
Subject: [PATCH 1/2] Fix surfaceless shared contexts

Previously, the surfaceless platform ignored the shared context passed
in to EglRenderContext, instead always passing in EGL_NO_CONTEXT as the
shared context argument to eglCreateContext. However, some tests attempt
to share data between contexts, which is invalid usage of the EGL API.
To fix, the surfaceless platform needs to respect the shared context
argument, passing in the appropriate context to eglCreateContext as
required in EGL.

This fixes GL_INVALID_VALUE errors from glDeleteProgram in these tests
when run with Mesa drivers, as they may delete programs in a different
context than they are created:

Affects: KHR-GLES31.core.compute_shader.simple-compute-shared_context*

Components: Framework
---
 .../surfaceless/tcuSurfacelessPlatform.cpp         | 14 +++++++++-----
 1 file changed, 9 insertions(+), 5 deletions(-)

diff --git a/framework/platform/surfaceless/tcuSurfacelessPlatform.cpp b/framework/platform/surfaceless/tcuSurfacelessPlatform.cpp
index 068dd293d..fa09107e0 100644
--- a/framework/platform/surfaceless/tcuSurfacelessPlatform.cpp
+++ b/framework/platform/surfaceless/tcuSurfacelessPlatform.cpp
@@ -199,10 +199,11 @@ public:
 class EglRenderContext : public glu::RenderContext
 {
 public:
-					EglRenderContext(const glu::RenderConfig& config, const tcu::CommandLine& cmdLine);
+					EglRenderContext(const glu::RenderConfig& config, const tcu::CommandLine& cmdLine, const glu::RenderContext* sharedContext);
 					~EglRenderContext(void);
 
 	glu::ContextType		getType		(void) const	{ return m_contextType; }
+	eglw::EGLContext		getEglContext	(void) const	{ return m_eglContext; }
 	const glw::Functions&		getFunctions	(void) const	{ return m_glFunctions; }
 	const tcu::RenderTarget&	getRenderTarget	(void) const;
 	void				postIterate	(void);
@@ -228,12 +229,12 @@ ContextFactory::ContextFactory()
 	: glu::ContextFactory("default", "EGL surfaceless context")
 {}
 
-glu::RenderContext* ContextFactory::createContext(const glu::RenderConfig& config, const tcu::CommandLine& cmdLine, const glu::RenderContext*) const
+glu::RenderContext* ContextFactory::createContext(const glu::RenderConfig& config, const tcu::CommandLine& cmdLine, const glu::RenderContext* sharedContext) const
 {
-	return new EglRenderContext(config, cmdLine);
+	return new EglRenderContext(config, cmdLine, sharedContext);
 }
 
-EglRenderContext::EglRenderContext(const glu::RenderConfig& config, const tcu::CommandLine& cmdLine)
+EglRenderContext::EglRenderContext(const glu::RenderConfig& config, const tcu::CommandLine& cmdLine, const glu::RenderContext *sharedContext)
 	: m_egl("libEGL.so")
 	, m_contextType(config.type)
 	, m_eglDisplay(EGL_NO_DISPLAY)
@@ -416,7 +417,10 @@ EglRenderContext::EglRenderContext(const glu::RenderConfig& config, const tcu::C
 
 	context_attribs.push_back(EGL_NONE);
 
-	m_eglContext = m_egl.createContext(m_eglDisplay, egl_config, EGL_NO_CONTEXT, &context_attribs[0]);
+	const EglRenderContext *sharedEglRenderContext = dynamic_cast<const EglRenderContext*>(sharedContext);
+	eglw::EGLContext sharedEglContext = sharedEglRenderContext ? sharedEglRenderContext->getEglContext() : EGL_NO_CONTEXT;
+
+	m_eglContext = m_egl.createContext(m_eglDisplay, egl_config, sharedEglContext, &context_attribs[0]);
 	EGLU_CHECK_MSG(m_egl, "eglCreateContext()");
 	if (!m_eglContext)
 		throw tcu::ResourceError("eglCreateContext failed");
-- 
2.39.2

From 00e447851d18496ce85f676fa4e4b484642ab9bb Mon Sep 17 00:00:00 2001
From: Alyssa Rosenzweig <alyssa@rosenzweig.io>
Date: Thu, 8 Jun 2023 07:35:45 -0400
Subject: [PATCH 2/2] Implement makeCurrent for surfaceless platform

Currently, makeCurrent is not implemented for surfaceless, causing two
new tests that use it to fail when run under the surfaceless platform,
spitting the following error in the logs:

	RenderContext::makeCurrent() is not implemented at gluRenderContext.cpp:49

Implement the function, resolving the test failure under surfaceless.

Affects: KHR-GLES31.core.compute_shader.simple-compute-shared_context*

Components: Framework
---
 .../surfaceless/tcuSurfacelessPlatform.cpp         | 14 ++++++++++----
 1 file changed, 10 insertions(+), 4 deletions(-)

diff --git a/framework/platform/surfaceless/tcuSurfacelessPlatform.cpp b/framework/platform/surfaceless/tcuSurfacelessPlatform.cpp
index fa09107e0..97d6d5aab 100644
--- a/framework/platform/surfaceless/tcuSurfacelessPlatform.cpp
+++ b/framework/platform/surfaceless/tcuSurfacelessPlatform.cpp
@@ -207,6 +207,7 @@ public:
 	const glw::Functions&		getFunctions	(void) const	{ return m_glFunctions; }
 	const tcu::RenderTarget&	getRenderTarget	(void) const;
 	void				postIterate	(void);
+	virtual void		makeCurrent		(void);
 
 	virtual glw::GenericFuncType    getProcAddress	(const char* name) const { return m_egl.getProcAddress(name); }
 
@@ -215,6 +216,7 @@ private:
 	const glu::ContextType		m_contextType;
 	eglw::EGLDisplay		m_eglDisplay;
 	eglw::EGLContext		m_eglContext;
+	eglw::EGLSurface		m_eglSurface;
 	de::DynamicLibrary*		m_glLibrary;
 	glw::Functions			m_glFunctions;
 	tcu::RenderTarget		m_renderTarget;
@@ -262,7 +264,6 @@ EglRenderContext::EglRenderContext(const glu::RenderConfig& config, const tcu::C
 	eglw::EGLint		flags = 0;
 	eglw::EGLint		num_configs;
 	eglw::EGLConfig		egl_config = NULL;
-	eglw::EGLSurface	egl_surface;
 
 	(void) cmdLine;
 
@@ -368,11 +369,11 @@ EglRenderContext::EglRenderContext(const glu::RenderConfig& config, const tcu::C
 	switch (config.surfaceType)
 	{
 		case glu::RenderConfig::SURFACETYPE_DONT_CARE:
-			egl_surface = EGL_NO_SURFACE;
+			m_eglSurface = EGL_NO_SURFACE;
 			break;
 		case glu::RenderConfig::SURFACETYPE_OFFSCREEN_NATIVE:
 		case glu::RenderConfig::SURFACETYPE_OFFSCREEN_GENERIC:
-			egl_surface = eglCreatePbufferSurface(m_eglDisplay, egl_config, &surface_attribs[0]);
+			m_eglSurface = eglCreatePbufferSurface(m_eglDisplay, egl_config, &surface_attribs[0]);
 			break;
 		case glu::RenderConfig::SURFACETYPE_WINDOW:
 		case glu::RenderConfig::SURFACETYPE_LAST:
@@ -425,7 +426,7 @@ EglRenderContext::EglRenderContext(const glu::RenderConfig& config, const tcu::C
 	if (!m_eglContext)
 		throw tcu::ResourceError("eglCreateContext failed");
 
-	EGLU_CHECK_CALL(m_egl, makeCurrent(m_eglDisplay, egl_surface, egl_surface, m_eglContext));
+	EGLU_CHECK_CALL(m_egl, makeCurrent(m_eglDisplay, m_eglSurface, m_eglSurface, m_eglContext));
 
 	if ((eglMajorVersion == 1 && eglMinorVersion >= 5) ||
 		isEGLExtensionSupported(m_egl, m_eglDisplay, "EGL_KHR_get_all_proc_addresses") ||
@@ -499,6 +500,11 @@ const tcu::RenderTarget& EglRenderContext::getRenderTarget(void) const
 	return m_renderTarget;
 }
 
+void EglRenderContext::makeCurrent (void)
+{
+	EGLU_CHECK_CALL(m_egl, makeCurrent(m_eglDisplay, m_eglSurface, m_eglSurface, m_eglContext));
+}
+
 void EglRenderContext::postIterate(void)
 {
 	this->getFunctions().finish();
-- 
2.39.2

