summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Romanick <ian.d.romanick@intel.com>2011-12-15 18:45:27 -0800
committerIan Romanick <ian.d.romanick@intel.com>2012-01-02 12:41:45 -0800
commit3ef3ba4d2eee36f64062a21ce030c3f4d8c4cac4 (patch)
treecb7b3bc1f1946f49cf597abd5fae30035223e308
parent8a4b36de05a133c1c9527836ca58bf8ebdf229bd (diff)
tests/glx: Add unit tests for GLX_ARB_create_context GLX protocol
This adds a new tests directory at the top-level and some extra build infrastructure. The tests use the Google C++ Testing Framework, and they will only be built if configure can detect its availability. The tests are automatically wired-in to run with 'make check'. Signed-off-by: Ian Romanick <ian.d.romanick@intel.com> Acked-by: Chad Versace <chad.versace@linux.intel.com>
-rw-r--r--Makefile2
-rw-r--r--configure.ac20
-rw-r--r--src/glx/Makefile5
-rw-r--r--tests/Makefile.am1
-rw-r--r--tests/glx/Makefile.am16
-rw-r--r--tests/glx/clientinfo_unittest.cpp723
-rw-r--r--tests/glx/create_context_unittest.cpp513
-rw-r--r--tests/glx/fake_glx_screen.cpp57
-rw-r--r--tests/glx/fake_glx_screen.h149
-rw-r--r--tests/glx/mock_xdisplay.h32
10 files changed, 1514 insertions, 4 deletions
diff --git a/Makefile b/Makefile
index cf6555c782d..c7389478977 100644
--- a/Makefile
+++ b/Makefile
@@ -23,7 +23,7 @@ doxygen:
check:
cd src/glsl/tests/ && ./optimization-test
- @echo "All tests passed."
+ make -C tests check
clean:
-@touch $(TOP)/configs/current
diff --git a/configure.ac b/configure.ac
index 8e809b938c6..c29b0bb4a5d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,4 +1,4 @@
-dnl Process this file with autoconf to create configure.
+nl Process this file with autoconf to create configure.
AC_PREREQ([2.59])
@@ -16,6 +16,7 @@ AC_INIT([Mesa],[mesa_version],
[https://bugs.freedesktop.org/enter_bug.cgi?product=Mesa])
AC_CONFIG_AUX_DIR([bin])
AC_CANONICAL_HOST
+AM_INIT_AUTOMAKE([foreign])
dnl Save user CFLAGS and CXXFLAGS so one can override the default ones
USER_CFLAGS="$CFLAGS"
@@ -65,6 +66,19 @@ solaris*)
;;
esac
+AC_PATH_PROG([GTESTCONFIG], [gtest-config])
+if test "x$GTESTCONFIG" != "x"; then
+ GTEST_CFLAGS=`gtest-config --cppflags --cxxflags`
+ GTEST_LIBS=`gtest-config --ldflags --libs`
+ HAVE_GTEST=1
+ AC_SUBST([GTEST_CFLAGS])
+ AC_SUBST([GTEST_LIBS])
+ HAVE_GTEST=yes
+else
+ HAVE_GTEST=no
+fi
+AM_CONDITIONAL(HAVE_GTEST, test x$HAVE_GTEST = xyes)
+
dnl clang is mostly GCC-compatible, but its version is much lower,
dnl so we have to check for it.
AC_MSG_CHECKING([if compiling with clang])
@@ -1907,7 +1921,9 @@ CFLAGS="$CFLAGS $USER_CFLAGS"
CXXFLAGS="$CXXFLAGS $USER_CXXFLAGS"
dnl Substitute the config
-AC_CONFIG_FILES([configs/autoconf])
+AC_CONFIG_FILES([configs/autoconf
+ tests/Makefile
+ tests/glx/Makefile])
dnl Replace the configs/current symlink
AC_CONFIG_COMMANDS([configs],[
diff --git a/src/glx/Makefile b/src/glx/Makefile
index 67d03bc689b..f702f952ce7 100644
--- a/src/glx/Makefile
+++ b/src/glx/Makefile
@@ -83,8 +83,11 @@ INCLUDES = -I. \
default: depend $(TOP)/$(LIB_DIR)/$(GL_LIB_NAME)
+libglx.a: $(OBJECTS)
+ $(MKLIB) -cplusplus -o glx -static $(OBJECTS)
+
# Make libGL
-$(TOP)/$(LIB_DIR)/$(GL_LIB_NAME): $(OBJECTS) $(GLAPI_LIB) Makefile
+$(TOP)/$(LIB_DIR)/$(GL_LIB_NAME): libglx.a $(OBJECTS) $(GLAPI_LIB) Makefile
$(MKLIB) -o $(GL_LIB) -linker '$(CXX)' -ldflags '$(LDFLAGS)' \
-major 1 -minor 2 \
-cplusplus $(MKLIB_OPTIONS) \
diff --git a/tests/Makefile.am b/tests/Makefile.am
new file mode 100644
index 00000000000..4079bb9da9a
--- /dev/null
+++ b/tests/Makefile.am
@@ -0,0 +1 @@
+SUBDIRS=glx
diff --git a/tests/glx/Makefile.am b/tests/glx/Makefile.am
new file mode 100644
index 00000000000..0b061176e1a
--- /dev/null
+++ b/tests/glx/Makefile.am
@@ -0,0 +1,16 @@
+AM_CFLAGS = -I$(top_builddir)/src/glx -I$(top_builddir)/src/mapi \
+ $(X11_CFLAGS) $(GTEST_CFLAGS)
+AM_CXXFLAGS = -I$(top_builddir)/src/glx -I$(top_builddir)/src/mapi \
+ $(X11_CFLAGS) $(GTEST_CFLAGS)
+
+if HAVE_GTEST
+TESTS = glx_unittest
+check_PROGRAMS = glx_unittest
+
+glx_unittest_SOURCES = \
+ clientinfo_unittest.cpp \
+ create_context_unittest.cpp \
+ fake_glx_screen.cpp
+
+glx_unittest_LDADD = $(top_builddir)/src/glx/libglx.a $(GTEST_LIBS) -lgtest_main
+endif \ No newline at end of file
diff --git a/tests/glx/clientinfo_unittest.cpp b/tests/glx/clientinfo_unittest.cpp
new file mode 100644
index 00000000000..f599c833a66
--- /dev/null
+++ b/tests/glx/clientinfo_unittest.cpp
@@ -0,0 +1,723 @@
+/*
+ * Copyright © 2011 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+#include <gtest/gtest.h>
+#include <string.h>
+
+extern "C" {
+#include "glxclient.h"
+}
+
+#include <xcb/glx.h>
+
+#include "mock_xdisplay.h"
+#include "fake_glx_screen.h"
+
+/**
+ * \name Wrappers around some X structures to make the more usable for tests
+ */
+/*@{*/
+class fake_glx_screen;
+
+class fake_glx_display : public glx_display {
+public:
+ fake_glx_display(mock_XDisplay *dpy, int major, int minor)
+ {
+ this->next = 0;
+ this->dpy = dpy;
+ this->majorOpcode = 0;
+ this->majorVersion = major;
+ this->minorVersion = minor;
+ this->serverGLXvendor = 0;
+ this->serverGLXversion = 0;
+ this->glXDrawHash = 0;
+
+ this->screens = new glx_screen *[dpy->nscreens];
+ memset(this->screens, 0, sizeof(struct glx_screen *) * dpy->nscreens);
+ }
+
+ ~fake_glx_display()
+ {
+ for (int i = 0; i < this->dpy->nscreens; i++) {
+ if (this->screens[i] != NULL)
+ delete this->screens[i];
+ }
+
+ delete [] this->screens;
+ }
+
+ void init_screen(int i, const char *ext);
+};
+
+class glX_send_client_info_test : public ::testing::Test {
+public:
+ glX_send_client_info_test();
+ virtual ~glX_send_client_info_test();
+ virtual void SetUp();
+
+ void common_protocol_expected_false_test(unsigned major, unsigned minor,
+ const char *glx_ext, bool *value);
+
+ void common_protocol_expected_true_test(unsigned major, unsigned minor,
+ const char *glx_ext, bool *value);
+
+ void create_single_screen_display(unsigned major, unsigned minor,
+ const char *glx_ext);
+
+ void destroy_display();
+
+protected:
+ fake_glx_display *glx_dpy;
+ mock_XDisplay *display;
+};
+
+void
+fake_glx_display::init_screen(int i, const char *ext)
+{
+ if (this->screens[i] != NULL)
+ delete this->screens[i];
+
+ this->screens[i] = new fake_glx_screen(this, i, ext);
+}
+/*@}*/
+
+static const char ext[] = "GL_XXX_dummy";
+
+static bool ClientInfo_was_sent;
+static bool SetClientInfoARB_was_sent;
+static bool SetClientInfo2ARB_was_sent;
+static xcb_connection_t *connection_used;
+static int gl_ext_length;
+static char *gl_ext_string;
+static int glx_ext_length;
+static char *glx_ext_string;
+static int num_gl_versions;
+static uint32_t *gl_versions;
+static int glx_major;
+static int glx_minor;
+
+extern "C" xcb_connection_t *
+XGetXCBConnection(Display *dpy)
+{
+ return (xcb_connection_t *) 0xdeadbeef;
+}
+
+extern "C" xcb_void_cookie_t
+xcb_glx_client_info(xcb_connection_t *c,
+ uint32_t major_version,
+ uint32_t minor_version,
+ uint32_t str_len,
+ const char *string)
+{
+ xcb_void_cookie_t cookie;
+
+ ClientInfo_was_sent = true;
+ connection_used = c;
+
+ gl_ext_string = (char *) malloc(str_len);
+ memcpy(gl_ext_string, string, str_len);
+ gl_ext_length = str_len;
+
+ glx_major = major_version;
+ glx_minor = minor_version;
+
+ cookie.sequence = 0;
+ return cookie;
+}
+
+extern "C" xcb_void_cookie_t
+xcb_glx_set_client_info_arb(xcb_connection_t *c,
+ uint32_t major_version,
+ uint32_t minor_version,
+ uint32_t num_versions,
+ uint32_t gl_str_len,
+ uint32_t glx_str_len,
+ const uint32_t *versions,
+ const char *gl_string,
+ const char *glx_string)
+{
+ xcb_void_cookie_t cookie;
+
+ SetClientInfoARB_was_sent = true;
+ connection_used = c;
+
+ gl_ext_string = new char[gl_str_len];
+ memcpy(gl_ext_string, gl_string, gl_str_len);
+ gl_ext_length = gl_str_len;
+
+ glx_ext_string = new char[glx_str_len];
+ memcpy(glx_ext_string, glx_string, glx_str_len);
+ glx_ext_length = glx_str_len;
+
+ gl_versions = new uint32_t[num_versions * 2];
+ memcpy(gl_versions, versions, sizeof(uint32_t) * num_versions * 2);
+ num_gl_versions = num_versions;
+
+ glx_major = major_version;
+ glx_minor = minor_version;
+
+ cookie.sequence = 0;
+ return cookie;
+}
+
+extern "C" xcb_void_cookie_t
+xcb_glx_set_client_info_2arb(xcb_connection_t *c,
+ uint32_t major_version,
+ uint32_t minor_version,
+ uint32_t num_versions,
+ uint32_t gl_str_len,
+ uint32_t glx_str_len,
+ const uint32_t *versions,
+ const char *gl_string,
+ const char *glx_string)
+{
+ xcb_void_cookie_t cookie;
+
+ SetClientInfo2ARB_was_sent = true;
+ connection_used = c;
+
+ gl_ext_string = new char[gl_str_len];
+ memcpy(gl_ext_string, gl_string, gl_str_len);
+ gl_ext_length = gl_str_len;
+
+ glx_ext_string = new char[glx_str_len];
+ memcpy(glx_ext_string, glx_string, glx_str_len);
+ glx_ext_length = glx_str_len;
+
+ gl_versions = new uint32_t[num_versions * 3];
+ memcpy(gl_versions, versions, sizeof(uint32_t) * num_versions * 3);
+ num_gl_versions = num_versions;
+
+ glx_major = major_version;
+ glx_minor = minor_version;
+
+ cookie.sequence = 0;
+ return cookie;
+}
+
+extern "C" char *
+__glXGetClientGLExtensionString()
+{
+ char *str = (char *) malloc(sizeof(ext));
+
+ memcpy(str, ext, sizeof(ext));
+ return str;
+}
+
+glX_send_client_info_test::glX_send_client_info_test()
+ : glx_dpy(0), display(0)
+{
+ /* empty */
+}
+
+glX_send_client_info_test::~glX_send_client_info_test()
+{
+ if (glx_dpy)
+ delete glx_dpy;
+
+ if (display)
+ delete display;
+}
+
+void
+glX_send_client_info_test::destroy_display()
+{
+ if (this->glx_dpy != NULL) {
+ if (this->glx_dpy->screens != NULL) {
+ for (int i = 0; i < this->display->nscreens; i++) {
+ delete [] this->glx_dpy->screens[i]->serverGLXexts;
+ delete this->glx_dpy->screens[i];
+ }
+
+ delete [] this->glx_dpy->screens;
+ }
+
+ delete this->glx_dpy;
+ delete this->display;
+ }
+}
+
+void
+glX_send_client_info_test::SetUp()
+{
+ ClientInfo_was_sent = false;
+ SetClientInfoARB_was_sent = false;
+ SetClientInfo2ARB_was_sent = false;
+ connection_used = (xcb_connection_t *) ~0;
+ gl_ext_length = 0;
+ gl_ext_string = (char *) 0;
+ glx_ext_length = 0;
+ glx_ext_string = (char *) 0;
+ num_gl_versions = 0;
+ gl_versions = (uint32_t *) 0;
+ glx_major = 0;
+ glx_minor = 0;
+}
+
+void
+glX_send_client_info_test::create_single_screen_display(unsigned major,
+ unsigned minor,
+ const char *glx_ext)
+{
+ this->display = new mock_XDisplay(1);
+
+ this->glx_dpy = new fake_glx_display(this->display, major, minor);
+ this->glx_dpy->init_screen(0, glx_ext);
+}
+
+void
+glX_send_client_info_test::common_protocol_expected_false_test(unsigned major,
+ unsigned minor,
+ const char *glx_ext,
+ bool *value)
+{
+ create_single_screen_display(major, minor, glx_ext);
+ __glX_send_client_info(this->glx_dpy);
+ EXPECT_FALSE(*value);
+}
+
+void
+glX_send_client_info_test::common_protocol_expected_true_test(unsigned major,
+ unsigned minor,
+ const char *glx_ext,
+ bool *value)
+{
+ create_single_screen_display(major, minor, glx_ext);
+ __glX_send_client_info(this->glx_dpy);
+ EXPECT_TRUE(*value);
+}
+
+TEST_F(glX_send_client_info_test, doesnt_send_ClientInfo_for_1_0)
+{
+ /* The glXClientInfo protocol was added in GLX 1.1. Verify that no
+ * glXClientInfo is sent to a GLX server that only has GLX 1.0.
+ */
+ common_protocol_expected_false_test(1, 0, "", &ClientInfo_was_sent);
+}
+
+TEST_F(glX_send_client_info_test, doesnt_send_SetClientInfoARB_for_1_0)
+{
+ /* The glXSetClientInfoARB protocol was added in GLX 1.4 with the
+ * GLX_ARB_create_context extension. Verify that no glXSetClientInfoARB is
+ * sent to a GLX server that only has GLX 1.0 regardless of the extension
+ * setting.
+ */
+ common_protocol_expected_false_test(1, 0,
+ "GLX_ARB_create_context",
+ &SetClientInfoARB_was_sent);
+}
+
+TEST_F(glX_send_client_info_test, doesnt_send_SetClientInfoARB_for_1_1)
+{
+ /* The glXSetClientInfoARB protocol was added in GLX 1.4 with the
+ * GLX_ARB_create_context extension. Verify that no glXSetClientInfoARB is
+ * sent to a GLX server that only has GLX 1.0 regardless of the extension
+ * setting.
+ */
+ common_protocol_expected_false_test(1, 1,
+ "GLX_ARB_create_context",
+ &SetClientInfoARB_was_sent);
+}
+
+TEST_F(glX_send_client_info_test, doesnt_send_SetClientInfoARB_for_1_4_with_empty_extensions)
+{
+ /* The glXSetClientInfoARB protocol was added in GLX 1.4 with the
+ * GLX_ARB_create_context extension. Verify that no glXSetClientInfoARB is
+ * sent to a GLX server that has GLX 1.4 but has an empty extension string
+ * (i.e., no extensions at all).
+ */
+ common_protocol_expected_false_test(1, 4,
+ "",
+ &SetClientInfoARB_was_sent);
+}
+
+TEST_F(glX_send_client_info_test, doesnt_send_SetClientInfoARB_for_1_4_without_extension)
+{
+ /* The glXSetClientInfoARB protocol was added in GLX 1.4 with the
+ * GLX_ARB_create_context extension. Verify that no glXSetClientInfoARB is
+ * sent to a GLX server that has GLX 1.4 but doesn't have the extension.
+ */
+ common_protocol_expected_false_test(1, 4,
+ "GLX_EXT_texture_from_pixmap",
+ &SetClientInfoARB_was_sent);
+}
+
+TEST_F(glX_send_client_info_test, doesnt_send_SetClientInfoARB_for_1_4_with_wrong_extension)
+{
+ /* The glXSetClientInfoARB protocol was added in GLX 1.4 with the
+ * GLX_ARB_create_context extension. Verify that no glXSetClientInfoARB is
+ * sent to a GLX server that has GLX 1.4 but does not have the extension.
+ *
+ * This test differs from
+ * doesnt_send_SetClientInfoARB_for_1_4_without_extension in that an
+ * extension exists that looks like the correct extension but isn't.
+ */
+ common_protocol_expected_false_test(1, 4,
+ "GLX_ARB_create_context2",
+ &SetClientInfoARB_was_sent);
+}
+
+TEST_F(glX_send_client_info_test, doesnt_send_SetClientInfoARB_for_1_4_with_profile_extension)
+{
+ /* The glXSetClientInfoARB protocol was added in GLX 1.4 with the
+ * GLX_ARB_create_context extension. Verify that no glXSetClientInfoARB is
+ * sent to a GLX server that has GLX 1.4 but does not have the extension.
+ *
+ * This test differs from
+ * doesnt_send_SetClientInfoARB_for_1_4_without_extension in that an
+ * extension exists that looks like the correct extension but isn't.
+ */
+ common_protocol_expected_false_test(1, 4,
+ "GLX_ARB_create_context_profile",
+ &SetClientInfoARB_was_sent);
+}
+
+TEST_F(glX_send_client_info_test, doesnt_send_SetClientInfo2ARB_for_1_0)
+{
+ /* The glXSetClientInfo2ARB protocol was added in GLX 1.4 with the
+ * GLX_ARB_create_context_profile extension. Verify that no
+ * glXSetClientInfo2ARB is sent to a GLX server that only has GLX 1.0
+ * regardless of the extension setting.
+ */
+ common_protocol_expected_false_test(1, 0,
+ "GLX_ARB_create_context_profile",
+ &SetClientInfo2ARB_was_sent);
+}
+
+TEST_F(glX_send_client_info_test, doesnt_send_SetClientInfo2ARB_for_1_1)
+{
+ /* The glXSetClientInfo2ARB protocol was added in GLX 1.4 with the
+ * GLX_ARB_create_context_profile extension. Verify that no
+ * glXSetClientInfo2ARB is sent to a GLX server that only has GLX 1.1
+ * regardless of the extension setting.
+ */
+ common_protocol_expected_false_test(1, 1,
+ "GLX_ARB_create_context_profile",
+ &SetClientInfo2ARB_was_sent);
+}
+
+TEST_F(glX_send_client_info_test, doesnt_send_SetClientInfo2ARB_for_1_4_with_empty_extensions)
+{
+ /* The glXSetClientInfo2ARB protocol was added in GLX 1.4 with the
+ * GLX_ARB_create_context_profile extension. Verify that no
+ * glXSetClientInfo2ARB is sent to a GLX server that has GLX 1.4 but has an
+ * empty extension string (i.e., no extensions at all).
+ */
+ common_protocol_expected_false_test(1, 4,
+ "",
+ &SetClientInfo2ARB_was_sent);
+}
+
+TEST_F(glX_send_client_info_test, doesnt_send_SetClientInfo2ARB_for_1_4_without_extension)
+{
+ /* The glXSetClientInfo2ARB protocol was added in GLX 1.4 with the
+ * GLX_ARB_create_context_profile extension. Verify that no
+ * glXSetClientInfo2ARB is sent to a GLX server that has GLX 1.4 but
+ * doesn't have the extension.
+ */
+ common_protocol_expected_false_test(1, 4,
+ "GLX_EXT_texture_from_pixmap",
+ &SetClientInfo2ARB_was_sent);
+}
+
+TEST_F(glX_send_client_info_test, doesnt_send_SetClientInfo2ARB_for_1_4_with_wrong_extension)
+{
+ /* The glXSetClientInfo2ARB protocol was added in GLX 1.4 with the
+ * GLX_ARB_create_context_profile extension. Verify that no
+ * glXSetClientInfo2ARB is sent to a GLX server that has GLX 1.4 but does
+ * not have the extension.
+ *
+ * This test differs from
+ * doesnt_send_SetClientInfo2ARB_for_1_4_without_extension in that an
+ * extension exists that looks like the correct extension but isn't.
+ */
+ common_protocol_expected_false_test(1, 4,
+ "GLX_ARB_create_context_profile2",
+ &SetClientInfo2ARB_was_sent);
+}
+
+TEST_F(glX_send_client_info_test, does_send_ClientInfo_for_1_1)
+{
+ /* The glXClientInfo protocol was added in GLX 1.1. Verify that
+ * glXClientInfo is sent to a GLX server that has GLX 1.1.
+ */
+ common_protocol_expected_true_test(1, 1,
+ "",
+ &ClientInfo_was_sent);
+}
+
+TEST_F(glX_send_client_info_test, does_send_SetClientInfoARB_for_1_4_with_extension)
+{
+ /* The glXSetClientInfoARB protocol was added in GLX 1.4 with the
+ * GLX_ARB_create_context extension. Verify that glXSetClientInfoARB is
+ * sent to a GLX server that has GLX 1.4 and the extension.
+ */
+ common_protocol_expected_true_test(1, 4,
+ "GLX_ARB_create_context",
+ &SetClientInfoARB_was_sent);
+}
+
+TEST_F(glX_send_client_info_test, does_send_SetClientInfo2ARB_for_1_4_with_just_profile_extension)
+{
+ /* The glXSetClientInfoARB protocol was added in GLX 1.4 with the
+ * GLX_ARB_create_context extension. Verify that glXSetClientInfoARB is
+ * sent to a GLX server that has GLX 1.4 and the extension.
+ */
+ common_protocol_expected_true_test(1, 4,
+ "GLX_ARB_create_context_profile",
+ &SetClientInfo2ARB_was_sent);
+}
+
+TEST_F(glX_send_client_info_test, does_send_SetClientInfo2ARB_for_1_4_with_both_extensions)
+{
+ /* The glXSetClientInfoARB protocol was added in GLX 1.4 with the
+ * GLX_ARB_create_context extension. Verify that glXSetClientInfoARB is
+ * sent to a GLX server that has GLX 1.4 and the extension.
+ */
+ common_protocol_expected_true_test(1, 4,
+ "GLX_ARB_create_context "
+ "GLX_ARB_create_context_profile",
+ &SetClientInfo2ARB_was_sent);
+}
+
+TEST_F(glX_send_client_info_test, does_send_SetClientInfo2ARB_for_1_4_with_both_extensions_reversed)
+{
+ /* The glXSetClientInfoARB protocol was added in GLX 1.4 with the
+ * GLX_ARB_create_context extension. Verify that glXSetClientInfoARB is
+ * sent to a GLX server that has GLX 1.4 and the extension.
+ */
+ common_protocol_expected_true_test(1, 4,
+ "GLX_ARB_create_context_profile "
+ "GLX_ARB_create_context",
+ &SetClientInfo2ARB_was_sent);
+}
+
+TEST_F(glX_send_client_info_test, uses_correct_connection)
+{
+ create_single_screen_display(1, 1, "");
+ __glX_send_client_info(this->glx_dpy);
+ EXPECT_EQ((xcb_connection_t *) 0xdeadbeef, connection_used);
+}
+
+TEST_F(glX_send_client_info_test, sends_correct_gl_extension_string)
+{
+ create_single_screen_display(1, 1, "");
+ __glX_send_client_info(this->glx_dpy);
+
+ ASSERT_EQ(sizeof(ext), gl_ext_length);
+ ASSERT_NE((char *) 0, gl_ext_string);
+ EXPECT_EQ(0, memcmp(gl_ext_string, ext, sizeof(ext)));
+}
+
+TEST_F(glX_send_client_info_test, gl_versions_are_sane)
+{
+ create_single_screen_display(1, 4, "GLX_ARB_create_context");
+ __glX_send_client_info(this->glx_dpy);
+
+ ASSERT_NE(0, num_gl_versions);
+
+ unsigned versions_below_3_0 = 0;
+ for (int i = 0; i < num_gl_versions; i++) {
+ EXPECT_LT(0, gl_versions[i * 2]);
+ EXPECT_GE(4, gl_versions[i * 2]);
+
+ /* Verify that the minor version advertised with the major version makes
+ * sense.
+ */
+ switch (gl_versions[i * 2]) {
+ case 1:
+ EXPECT_GE(5, gl_versions[i * 2 + 1]);
+ versions_below_3_0++;
+ break;
+ case 2:
+ EXPECT_GE(1, gl_versions[i * 2 + 1]);
+ versions_below_3_0++;
+ break;
+ case 3:
+ EXPECT_GE(3, gl_versions[i * 2 + 1]);
+ break;
+ case 4:
+ EXPECT_GE(2, gl_versions[i * 2 + 1]);
+ break;
+ }
+ }
+
+ /* From the GLX_ARB_create_context spec:
+ *
+ * "Only the highest supported version below 3.0 should be sent, since
+ * OpenGL 2.1 is backwards compatible with all earlier versions."
+ */
+ EXPECT_LE(versions_below_3_0, 1);
+}
+
+TEST_F(glX_send_client_info_test, gl_versions_and_profiles_are_sane)
+{
+ create_single_screen_display(1, 4, "GLX_ARB_create_context_profile");
+ __glX_send_client_info(this->glx_dpy);
+
+ ASSERT_NE(0, num_gl_versions);
+
+ const uint32_t all_valid_bits = GLX_CONTEXT_CORE_PROFILE_BIT_ARB
+ | GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB;
+
+ unsigned versions_below_3_0 = 0;
+
+ for (int i = 0; i < num_gl_versions; i++) {
+ EXPECT_LT(0, gl_versions[i * 3]);
+ EXPECT_GE(4, gl_versions[i * 3]);
+
+ /* Verify that the minor version advertised with the major version makes
+ * sense.
+ */
+ switch (gl_versions[i * 3]) {
+ case 1:
+ EXPECT_GE(5, gl_versions[i * 3 + 1]);
+ EXPECT_EQ(0, gl_versions[i * 3 + 2]);
+ versions_below_3_0++;
+ break;
+ case 2:
+ EXPECT_GE(1, gl_versions[i * 3 + 1]);
+ EXPECT_EQ(0, gl_versions[i * 3 + 2]);
+ versions_below_3_0++;
+ break;
+ case 3:
+ EXPECT_GE(3, gl_versions[i * 3 + 1]);
+
+ /* Profiles were not introduced until OpenGL 3.2.
+ */
+ if (gl_versions[i * 3 + 1] < 2) {
+ EXPECT_EQ(0, gl_versions[i * 3 + 2]);
+ } else {
+ EXPECT_EQ(0, gl_versions[i * 3 + 2] & ~all_valid_bits);
+ }
+ break;
+ case 4:
+ EXPECT_GE(2, gl_versions[i * 3 + 1]);
+ EXPECT_EQ(0, gl_versions[i * 3 + 2] & ~all_valid_bits);
+ break;
+ }
+ }
+
+ /* From the GLX_ARB_create_context_profile spec:
+ *
+ * "Only the highest supported version below 3.0 should be sent, since
+ * OpenGL 2.1 is backwards compatible with all earlier versions."
+ */
+ EXPECT_LE(versions_below_3_0, 1);
+}
+
+TEST_F(glX_send_client_info_test, glx_version_is_1_4_for_1_1)
+{
+ create_single_screen_display(1, 1, "");
+ __glX_send_client_info(this->glx_dpy);
+
+ EXPECT_EQ(1, glx_major);
+ EXPECT_EQ(4, glx_minor);
+}
+
+TEST_F(glX_send_client_info_test, glx_version_is_1_4_for_1_4)
+{
+ create_single_screen_display(1, 4, "");
+ __glX_send_client_info(this->glx_dpy);
+
+ EXPECT_EQ(1, glx_major);
+ EXPECT_EQ(4, glx_minor);
+}
+
+TEST_F(glX_send_client_info_test, glx_version_is_1_4_for_1_4_with_ARB_create_context)
+{
+ create_single_screen_display(1, 4, "GLX_ARB_create_context");
+ __glX_send_client_info(this->glx_dpy);
+
+ EXPECT_EQ(1, glx_major);
+ EXPECT_EQ(4, glx_minor);
+}
+
+TEST_F(glX_send_client_info_test, glx_version_is_1_4_for_1_4_with_ARB_create_context_profile)
+{
+ create_single_screen_display(1, 4, "GLX_ARB_create_context_profile");
+ __glX_send_client_info(this->glx_dpy);
+
+ EXPECT_EQ(1, glx_major);
+ EXPECT_EQ(4, glx_minor);
+}
+
+TEST_F(glX_send_client_info_test, glx_version_is_1_4_for_1_5)
+{
+ create_single_screen_display(1, 5, "");
+ __glX_send_client_info(this->glx_dpy);
+
+ EXPECT_EQ(1, glx_major);
+ EXPECT_EQ(4, glx_minor);
+}
+
+TEST_F(glX_send_client_info_test, glx_extensions_has_GLX_ARB_create_context)
+{
+ create_single_screen_display(1, 4, "GLX_ARB_create_context");
+ __glX_send_client_info(this->glx_dpy);
+
+ ASSERT_NE(0, glx_ext_length);
+ ASSERT_NE((char *) 0, glx_ext_string);
+
+ bool found_GLX_ARB_create_context = false;
+ const char *const needle = "GLX_ARB_create_context";
+ const unsigned len = strlen(needle);
+ char *haystack = glx_ext_string;
+ while (haystack != NULL) {
+ char *match = strstr(haystack, needle);
+
+ if (match[len] == '\0' || match[len] == ' ') {
+ found_GLX_ARB_create_context = true;
+ break;
+ }
+
+ haystack = match + len;
+ }
+
+ EXPECT_TRUE(found_GLX_ARB_create_context);
+}
+
+TEST_F(glX_send_client_info_test, glx_extensions_has_GLX_ARB_create_context_profile)
+{
+ create_single_screen_display(1, 4, "GLX_ARB_create_context_profile");
+ __glX_send_client_info(this->glx_dpy);
+
+ ASSERT_NE(0, glx_ext_length);
+ ASSERT_NE((char *) 0, glx_ext_string);
+
+ bool found_GLX_ARB_create_context_profile = false;
+ const char *const needle = "GLX_ARB_create_context_profile";
+ const unsigned len = strlen(needle);
+ char *haystack = glx_ext_string;
+ while (haystack != NULL) {
+ char *match = strstr(haystack, needle);
+
+ if (match[len] == '\0' || match[len] == ' ') {
+ found_GLX_ARB_create_context_profile = true;
+ break;
+ }
+
+ haystack = match + len;
+ }
+
+ EXPECT_TRUE(found_GLX_ARB_create_context_profile);
+}
diff --git a/tests/glx/create_context_unittest.cpp b/tests/glx/create_context_unittest.cpp
new file mode 100644
index 00000000000..f97ec7ca5f2
--- /dev/null
+++ b/tests/glx/create_context_unittest.cpp
@@ -0,0 +1,513 @@
+/*
+ * Copyright © 2011 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+#include <gtest/gtest.h>
+#include <string.h>
+
+extern "C" {
+#include "glxclient.h"
+#include "glx_error.h"
+}
+
+#include <xcb/glx.h>
+#include "mock_xdisplay.h"
+#include "fake_glx_screen.h"
+
+static bool CreateContextAttribsARB_was_sent;
+static xcb_glx_create_context_attribs_arb_request_t req;
+static uint32_t sent_attribs[1024];
+static uint32_t next_id;
+
+
+struct glx_screen *psc;
+
+extern "C" Bool
+glx_context_init(struct glx_context *gc,
+ struct glx_screen *psc, struct glx_config *config)
+{
+ gc->majorOpcode = 123;
+ gc->screen = psc->scr;
+ gc->psc = psc;
+ gc->config = config;
+ gc->isDirect = GL_TRUE;
+ gc->currentContextTag = -1;
+
+ return GL_TRUE;
+}
+
+extern "C" struct glx_screen *
+GetGLXScreenConfigs(Display * dpy, int scrn)
+{
+ (void) dpy;
+ (void) scrn;
+ return psc;
+}
+
+extern "C" uint32_t
+xcb_generate_id(xcb_connection_t *c)
+{
+ (void) c;
+
+ return next_id++;
+}
+
+extern "C" xcb_void_cookie_t
+xcb_glx_create_context_attribs_arb_checked(xcb_connection_t *c,
+ xcb_glx_context_t context,
+ uint32_t fbconfig,
+ uint32_t screen,
+ uint32_t share_list,
+ uint8_t is_direct,
+ uint32_t num_attribs,
+ const uint32_t *attribs)
+{
+ (void) c;
+
+ CreateContextAttribsARB_was_sent = true;
+ req.context = context;
+ req.fbconfig = fbconfig;
+ req.screen = screen;
+ req.share_list = share_list;
+ req.is_direct = is_direct;
+ req.num_attribs = num_attribs;
+
+ if (num_attribs != 0 && attribs != NULL)
+ memcpy(sent_attribs, attribs, num_attribs * 2 * sizeof(uint32_t));
+
+ xcb_void_cookie_t cookie;
+ cookie.sequence = 0xbadc0de;
+
+ return cookie;
+}
+
+extern "C" xcb_generic_error_t *
+xcb_request_check(xcb_connection_t *c, xcb_void_cookie_t cookie)
+{
+ return NULL;
+}
+
+extern "C" void
+__glXSendErrorForXcb(Display * dpy, const xcb_generic_error_t *err)
+{
+}
+
+extern "C" void
+__glXSendError(Display * dpy, int_fast8_t errorCode, uint_fast32_t resourceID,
+ uint_fast16_t minorCode, bool coreX11error)
+{
+}
+
+class glXCreateContextAttribARB_test : public ::testing::Test {
+public:
+ virtual void SetUp();
+
+ /**
+ * Replace the existing screen with a direct-rendering screen
+ */
+ void use_direct_rendering_screen();
+
+ mock_XDisplay *dpy;
+ struct glx_config fbc;
+};
+
+void
+glXCreateContextAttribARB_test::SetUp()
+{
+ CreateContextAttribsARB_was_sent = false;
+ memset(&req, 0, sizeof(req));
+ next_id = 99;
+ fake_glx_context::contexts_allocated = 0;
+ psc = new fake_glx_screen(NULL, 0, "");
+
+ this->dpy = new mock_XDisplay(1);
+
+ memset(&this->fbc, 0, sizeof(this->fbc));
+ this->fbc.fbconfigID = 0xbeefcafe;
+}
+
+void
+glXCreateContextAttribARB_test::use_direct_rendering_screen()
+{
+ struct glx_screen *direct_psc =
+ new fake_glx_screen_direct(psc->display,
+ psc->scr,
+ psc->serverGLXexts);
+
+ delete psc;
+ psc = direct_psc;
+}
+
+/**
+ * \name Verify detection of client-side errors
+ */
+/*@{*/
+TEST_F(glXCreateContextAttribARB_test, NULL_display_returns_None)
+{
+ GLXContext ctx =
+ glXCreateContextAttribsARB(NULL, (GLXFBConfig) &this->fbc, 0,
+ False, NULL);
+
+ EXPECT_EQ(None, ctx);
+ EXPECT_EQ(0, fake_glx_context::contexts_allocated);
+}
+
+TEST_F(glXCreateContextAttribARB_test, NULL_fbconfig_returns_None)
+{
+ GLXContext ctx =
+ glXCreateContextAttribsARB(this->dpy, NULL, 0, False, NULL);
+
+ EXPECT_EQ(None, ctx);
+ EXPECT_EQ(0, fake_glx_context::contexts_allocated);
+}
+
+TEST_F(glXCreateContextAttribARB_test, NULL_screen_returns_None)
+{
+ delete psc;
+ psc = NULL;
+
+ GLXContext ctx =
+ glXCreateContextAttribsARB(this->dpy, (GLXFBConfig) &this->fbc, 0,
+ False, NULL);
+
+ EXPECT_EQ(None, ctx);
+ EXPECT_EQ(0, fake_glx_context::contexts_allocated);
+}
+/*@}*/
+
+/**
+ * \name Verify that correct protocol bits are sent to the server.
+ */
+/*@{*/
+TEST_F(glXCreateContextAttribARB_test, does_send_protocol)
+{
+ glXCreateContextAttribsARB(this->dpy, (GLXFBConfig) &this->fbc, 0,
+ False, NULL);
+
+ EXPECT_TRUE(CreateContextAttribsARB_was_sent);
+}
+
+TEST_F(glXCreateContextAttribARB_test, sent_correct_context)
+{
+ glXCreateContextAttribsARB(this->dpy, (GLXFBConfig) &this->fbc, 0,
+ False, NULL);
+
+ EXPECT_EQ(99, req.context);
+}
+
+TEST_F(glXCreateContextAttribARB_test, sent_correct_fbconfig)
+{
+ glXCreateContextAttribsARB(this->dpy, (GLXFBConfig) &this->fbc, 0,
+ False, NULL);
+
+ EXPECT_EQ(0xbeefcafe, req.fbconfig);
+}
+
+TEST_F(glXCreateContextAttribARB_test, sent_correct_share_list)
+{
+ GLXContext share =
+ glXCreateContextAttribsARB(this->dpy, (GLXFBConfig) &this->fbc, 0,
+ False, NULL);
+
+ ASSERT_NE((GLXContext) 0, share);
+
+ glXCreateContextAttribsARB(this->dpy, (GLXFBConfig) &this->fbc, share,
+ False, NULL);
+
+ struct glx_context *glx_ctx = (struct glx_context *) share;
+ EXPECT_EQ(glx_ctx->xid, req.share_list);
+}
+
+TEST_F(glXCreateContextAttribARB_test, sent_correct_is_direct_for_indirect_screen_and_direct_set_to_true)
+{
+ glXCreateContextAttribsARB(this->dpy, (GLXFBConfig) &this->fbc, 0,
+ True, NULL);
+
+ EXPECT_FALSE(req.is_direct);
+}
+
+TEST_F(glXCreateContextAttribARB_test, sent_correct_is_direct_for_indirect_screen_and_direct_set_to_false)
+{
+ glXCreateContextAttribsARB(this->dpy, (GLXFBConfig) &this->fbc, 0,
+ False, NULL);
+
+ EXPECT_FALSE(req.is_direct);
+}
+
+TEST_F(glXCreateContextAttribARB_test, sent_correct_is_direct_for_direct_screen_and_direct_set_to_true)
+{
+ this->use_direct_rendering_screen();
+
+ glXCreateContextAttribsARB(this->dpy, (GLXFBConfig) &this->fbc, 0,
+ True, NULL);
+
+ EXPECT_TRUE(req.is_direct);
+}
+
+TEST_F(glXCreateContextAttribARB_test, sent_correct_is_direct_for_direct_screen_and_direct_set_to_false)
+{
+ this->use_direct_rendering_screen();
+
+ glXCreateContextAttribsARB(this->dpy, (GLXFBConfig) &this->fbc, 0,
+ False, NULL);
+
+ EXPECT_FALSE(req.is_direct);
+}
+
+TEST_F(glXCreateContextAttribARB_test, sent_correct_screen)
+{
+ this->fbc.screen = 7;
+ psc->scr = 7;
+
+ glXCreateContextAttribsARB(this->dpy, (GLXFBConfig) &this->fbc, 0,
+ False, NULL);
+
+ EXPECT_EQ(7, req.screen);
+}
+
+TEST_F(glXCreateContextAttribARB_test, sent_correct_num_attribs)
+{
+ /* Use zeros in the second half of each attribute pair to try and trick the
+ * implementation into termiating the list early.
+ *
+ * Use non-zero in the second half of the last attribute pair to try and
+ * trick the implementation into not terminating the list early enough.
+ */
+ static const int attribs[] = {
+ 1, 0,
+ 2, 0,
+ 3, 0,
+ 4, 0,
+ 0, 6,
+ 0, 0
+ };
+
+ glXCreateContextAttribsARB(this->dpy, (GLXFBConfig) &this->fbc, 0,
+ False, attribs);
+
+ EXPECT_EQ(4, req.num_attribs);
+}
+
+TEST_F(glXCreateContextAttribARB_test, sent_correct_num_attribs_empty_list)
+{
+ static const int attribs[] = {
+ 0,
+ };
+
+ glXCreateContextAttribsARB(this->dpy, (GLXFBConfig) &this->fbc, 0,
+ False, attribs);
+
+ EXPECT_EQ(0, req.num_attribs);
+}
+
+TEST_F(glXCreateContextAttribARB_test, sent_correct_num_attribs_NULL_list_pointer)
+{
+ glXCreateContextAttribsARB(this->dpy, (GLXFBConfig) &this->fbc, 0,
+ False, NULL);
+
+ EXPECT_EQ(0, req.num_attribs);
+}
+
+TEST_F(glXCreateContextAttribARB_test, sent_correct_attrib_list)
+{
+ int attribs[] = {
+ GLX_RENDER_TYPE, GLX_RGBA_TYPE,
+ GLX_CONTEXT_MAJOR_VERSION_ARB, 1,
+ GLX_CONTEXT_MINOR_VERSION_ARB, 2,
+ 0
+ };
+
+ glXCreateContextAttribsARB(this->dpy, (GLXFBConfig) &this->fbc, 0,
+ False, attribs);
+
+ for (unsigned i = 0; i < 6; i++) {
+ EXPECT_EQ(attribs[i], sent_attribs[i]);
+ }
+}
+/*@}*/
+
+/**
+ * \name Verify details of the returned GLXContext
+ */
+/*@{*/
+TEST_F(glXCreateContextAttribARB_test, correct_context)
+{
+ GLXContext ctx =
+ glXCreateContextAttribsARB(this->dpy, (GLXFBConfig) &this->fbc, 0,
+ False, NULL);
+
+ /* Since the server did not return an error, the GLXContext should not be
+ * NULL.
+ */
+ EXPECT_NE((GLXContext)0, ctx);
+
+ /* It shouldn't be the XID of the context either.
+ */
+ EXPECT_NE((GLXContext)99, ctx);
+}
+
+TEST_F(glXCreateContextAttribARB_test, correct_context_xid)
+{
+ GLXContext ctx =
+ glXCreateContextAttribsARB(this->dpy, (GLXFBConfig) &this->fbc, 0,
+ False, NULL);
+
+ /* Since the server did not return an error, the GLXContext should not be
+ * NULL.
+ */
+ ASSERT_NE((GLXContext)0, ctx);
+
+ struct glx_context *glx_ctx = (struct glx_context *) ctx;
+ EXPECT_EQ(99, glx_ctx->xid);
+}
+
+TEST_F(glXCreateContextAttribARB_test, correct_context_share_xid)
+{
+ GLXContext first =
+ glXCreateContextAttribsARB(this->dpy, (GLXFBConfig) &this->fbc, 0,
+ False, NULL);
+
+ ASSERT_NE((GLXContext) 0, first);
+
+ GLXContext second =
+ glXCreateContextAttribsARB(this->dpy, (GLXFBConfig) &this->fbc, first,
+ False, NULL);
+
+ ASSERT_NE((GLXContext) 0, second);
+
+ struct glx_context *share = (struct glx_context *) first;
+ struct glx_context *ctx = (struct glx_context *) second;
+ EXPECT_EQ(share->xid, ctx->share_xid);
+}
+
+TEST_F(glXCreateContextAttribARB_test, correct_context_isDirect_for_indirect_screen_and_direct_set_to_true)
+{
+ GLXContext ctx =
+ glXCreateContextAttribsARB(this->dpy, (GLXFBConfig) &this->fbc, 0,
+ True, NULL);
+
+ ASSERT_NE((GLXContext) 0, ctx);
+
+ struct glx_context *gc = (struct glx_context *) ctx;
+
+ EXPECT_FALSE(gc->isDirect);
+}
+
+TEST_F(glXCreateContextAttribARB_test, correct_context_isDirect_for_indirect_screen_and_direct_set_to_false)
+{
+ GLXContext ctx =
+ glXCreateContextAttribsARB(this->dpy, (GLXFBConfig) &this->fbc, 0,
+ False, NULL);
+
+ ASSERT_NE((GLXContext) 0, ctx);
+
+ struct glx_context *gc = (struct glx_context *) ctx;
+
+ EXPECT_FALSE(gc->isDirect);
+}
+
+TEST_F(glXCreateContextAttribARB_test, correct_context_isDirect_for_direct_screen_and_direct_set_to_true)
+{
+ this->use_direct_rendering_screen();
+
+ GLXContext ctx =
+ glXCreateContextAttribsARB(this->dpy, (GLXFBConfig) &this->fbc, 0,
+ True, NULL);
+
+ ASSERT_NE((GLXContext) 0, ctx);
+
+ struct glx_context *gc = (struct glx_context *) ctx;
+
+ EXPECT_TRUE(gc->isDirect);
+}
+
+TEST_F(glXCreateContextAttribARB_test, correct_context_isDirect_for_direct_screen_and_direct_set_to_false)
+{
+ this->use_direct_rendering_screen();
+
+ GLXContext ctx =
+ glXCreateContextAttribsARB(this->dpy, (GLXFBConfig) &this->fbc, 0,
+ False, NULL);
+
+ ASSERT_NE((GLXContext) 0, ctx);
+
+ struct glx_context *gc = (struct glx_context *) ctx;
+
+ EXPECT_FALSE(gc->isDirect);
+}
+
+TEST_F(glXCreateContextAttribARB_test, correct_indirect_context_client_state_private)
+{
+ GLXContext ctx =
+ glXCreateContextAttribsARB(this->dpy, (GLXFBConfig) &this->fbc, 0,
+ False, NULL);
+
+ ASSERT_NE((GLXContext) 0, ctx);
+
+ struct glx_context *gc = (struct glx_context *) ctx;
+
+ ASSERT_FALSE(gc->isDirect);
+ EXPECT_EQ((struct __GLXattributeRec *) 0xcafebabe,
+ gc->client_state_private);
+}
+
+TEST_F(glXCreateContextAttribARB_test, correct_indirect_context_config)
+{
+ GLXContext ctx =
+ glXCreateContextAttribsARB(this->dpy, (GLXFBConfig) &this->fbc, 0,
+ False, NULL);
+
+ ASSERT_NE((GLXContext) 0, ctx);
+
+ struct glx_context *gc = (struct glx_context *) ctx;
+
+ EXPECT_EQ(&this->fbc, gc->config);
+}
+
+TEST_F(glXCreateContextAttribARB_test, correct_context_screen_number)
+{
+ this->fbc.screen = 7;
+ psc->scr = 7;
+
+ GLXContext ctx =
+ glXCreateContextAttribsARB(this->dpy, (GLXFBConfig) &this->fbc, 0,
+ False, NULL);
+
+ ASSERT_NE((GLXContext) 0, ctx);
+
+ struct glx_context *gc = (struct glx_context *) ctx;
+
+ EXPECT_EQ(7, gc->screen);
+}
+
+TEST_F(glXCreateContextAttribARB_test, correct_context_screen_pointer)
+{
+ GLXContext ctx =
+ glXCreateContextAttribsARB(this->dpy, (GLXFBConfig) &this->fbc, 0,
+ False, NULL);
+
+ ASSERT_NE((GLXContext) 0, ctx);
+
+ struct glx_context *gc = (struct glx_context *) ctx;
+
+ EXPECT_EQ(psc, gc->psc);
+}
+/*@}*/
diff --git a/tests/glx/fake_glx_screen.cpp b/tests/glx/fake_glx_screen.cpp
new file mode 100644
index 00000000000..12d003b84f7
--- /dev/null
+++ b/tests/glx/fake_glx_screen.cpp
@@ -0,0 +1,57 @@
+/*
+ * Copyright © 2011 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+#include "fake_glx_screen.h"
+
+struct glx_screen_vtable fake_glx_screen::vt = {
+ indirect_create_context,
+ fake_glx_context::create_attribs
+};
+
+struct glx_screen_vtable fake_glx_screen_direct::vt = {
+ fake_glx_context_direct::create,
+ fake_glx_context_direct::create_attribs
+};
+
+const struct glx_context_vtable fake_glx_context::vt = {
+ fake_glx_context::destroy,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+};
+
+int fake_glx_context::contexts_allocated = 0;
+
+extern "C" struct glx_context *
+indirect_create_context(struct glx_screen *psc, struct glx_config *mode,
+ struct glx_context *shareList, int renderType)
+{
+ (void) shareList;
+ (void) renderType;
+
+ return new fake_glx_context(psc, mode);
+}
diff --git a/tests/glx/fake_glx_screen.h b/tests/glx/fake_glx_screen.h
new file mode 100644
index 00000000000..21515225971
--- /dev/null
+++ b/tests/glx/fake_glx_screen.h
@@ -0,0 +1,149 @@
+/*
+ * Copyright © 2011 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+extern "C" {
+#include "glxclient.h"
+};
+
+class fake_glx_screen : public glx_screen {
+public:
+ fake_glx_screen(struct glx_display *glx_dpy, int num, const char *ext)
+ {
+ this->vtable = &fake_glx_screen::vt;
+ this->serverGLXexts = 0;
+ this->effectiveGLXexts = 0;
+ this->display = 0;
+ this->dpy = 0;
+ this->scr = num;
+ this->visuals = 0;
+ this->configs = 0;
+
+ this->display = glx_dpy;
+ this->dpy = (glx_dpy != NULL) ? glx_dpy->dpy : NULL;
+
+ this->serverGLXexts = new char[strlen(ext)];
+ strcpy((char *) this->serverGLXexts, ext);
+ }
+
+ ~fake_glx_screen()
+ {
+ delete [] this->serverGLXexts;
+ }
+
+private:
+ static struct glx_screen_vtable vt;
+};
+
+class fake_glx_screen_direct : public fake_glx_screen {
+public:
+ fake_glx_screen_direct(struct glx_display *glx_dpy, int num,
+ const char *ext)
+ : fake_glx_screen(glx_dpy, num, ext)
+ {
+ this->vtable = &fake_glx_screen_direct::vt;
+ }
+
+private:
+ static struct glx_screen_vtable vt;
+};
+
+class fake_glx_context : public glx_context {
+public:
+ fake_glx_context(struct glx_screen *psc, struct glx_config *mode)
+ {
+ contexts_allocated++;
+
+ this->vtable = &fake_glx_context::vt;
+ this->majorOpcode = 123;
+ this->screen = psc->scr;
+ this->psc = psc;
+ this->config = mode;
+ this->isDirect = false;
+ this->currentContextTag = -1;
+
+ this->client_state_private = (struct __GLXattributeRec *) 0xcafebabe;
+ }
+
+ ~fake_glx_context()
+ {
+ contexts_allocated--;
+ }
+
+ static glx_context *create_attribs(struct glx_screen *psc,
+ struct glx_config *mode,
+ struct glx_context *shareList,
+ unsigned num_attribs,
+ const uint32_t *attribs,
+ unsigned *error)
+ {
+ (void) shareList;
+ (void) num_attribs;
+ (void) attribs;
+
+ *error = 0;
+ return new fake_glx_context(psc, mode);
+ }
+
+ /** Number of context that are allocated (and not freed). */
+ static int contexts_allocated;
+
+private:
+ static const struct glx_context_vtable vt;
+
+ static void destroy(struct glx_context *gc)
+ {
+ delete gc;
+ }
+};
+
+class fake_glx_context_direct : public fake_glx_context {
+public:
+ fake_glx_context_direct(struct glx_screen *psc, struct glx_config *mode)
+ : fake_glx_context(psc, mode)
+ {
+ this->isDirect = True;
+ }
+
+ static glx_context *create(struct glx_screen *psc, struct glx_config *mode,
+ struct glx_context *shareList, int renderType)
+ {
+ (void) shareList;
+ (void) renderType;
+
+ return new fake_glx_context_direct(psc, mode);
+ }
+
+ static glx_context *create_attribs(struct glx_screen *psc,
+ struct glx_config *mode,
+ struct glx_context *shareList,
+ unsigned num_attribs,
+ const uint32_t *attribs,
+ unsigned *error)
+ {
+ (void) shareList;
+ (void) num_attribs;
+ (void) attribs;
+
+ *error = 0;
+ return new fake_glx_context_direct(psc, mode);
+ }
+};
diff --git a/tests/glx/mock_xdisplay.h b/tests/glx/mock_xdisplay.h
new file mode 100644
index 00000000000..736a2784050
--- /dev/null
+++ b/tests/glx/mock_xdisplay.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright © 2011 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+#include <X11/X.h>
+
+class mock_XDisplay : public _XDisplay {
+public:
+ mock_XDisplay(int nscreens)
+ {
+ memset(this, 0, sizeof(struct _XDisplay));
+ this->nscreens = nscreens;
+ }
+};