From 8c5330226f391a7a29b6538851090b0ef730a239 Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Fri, 22 Feb 2013 16:45:27 -0800 Subject: [PATCH] glx/tests: Add unit tests for the DRI2 part of GLX_MESA_query_renderer After adding $(DEFINES) to AM_CPPFLAGS, the __glXGetCurrentContext wrapper function is no longer needed and causes compile errors. Using the correct defines causes it to be a macro! Signed-off-by: Ian Romanick --- src/glx/tests/Makefile.am | 4 + src/glx/tests/fake_glx_screen.cpp | 6 - ...query_renderer_implementation_unittest.cpp | 310 ++++++++++++++++++ 3 files changed, 314 insertions(+), 6 deletions(-) create mode 100644 src/glx/tests/query_renderer_implementation_unittest.cpp diff --git a/src/glx/tests/Makefile.am b/src/glx/tests/Makefile.am index 6995d987d35..4dc358c3261 100644 --- a/src/glx/tests/Makefile.am +++ b/src/glx/tests/Makefile.am @@ -6,6 +6,9 @@ AM_CPPFLAGS = \ -I$(top_srcdir)/src/mesa \ -I$(top_srcdir)/src/glx \ -I$(top_srcdir)/include \ + -I$(top_srcdir)/include/GL/internal \ + $(DEFINES) \ + $(LIBDRM_CFLAGS) \ $(X11_CFLAGS) TESTS = glx-test @@ -17,6 +20,7 @@ glx_test_SOURCES = \ enum_sizes.cpp \ fake_glx_screen.cpp \ indirect_api.cpp \ + query_renderer_implementation_unittest.cpp \ query_renderer_unittest.cpp glx_test_LDADD = \ diff --git a/src/glx/tests/fake_glx_screen.cpp b/src/glx/tests/fake_glx_screen.cpp index 29f244117cd..815330a0b1f 100644 --- a/src/glx/tests/fake_glx_screen.cpp +++ b/src/glx/tests/fake_glx_screen.cpp @@ -76,9 +76,3 @@ indirect_create_context_attribs(struct glx_screen *base, } __thread void *__glX_tls_Context = NULL; - -extern "C" struct glx_context * -__glXGetCurrentContext() -{ - return (struct glx_context *) __glX_tls_Context; -} diff --git a/src/glx/tests/query_renderer_implementation_unittest.cpp b/src/glx/tests/query_renderer_implementation_unittest.cpp new file mode 100644 index 00000000000..474908939d6 --- /dev/null +++ b/src/glx/tests/query_renderer_implementation_unittest.cpp @@ -0,0 +1,310 @@ +/* + * Copyright © 2013 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 +#include +#include + +extern "C" { +#include "glxclient.h" +#include "glx_error.h" +#include "xf86drm.h" +#include "dri2.h" +#include "dri_interface.h" +#include "dri2_priv.h" +} + +struct attribute_test_vector { + const char *glx_string; + const char *dri_string; + int glx_attribute; + int dri_attribute; +}; + +#define E(g, d) { # g, # d, g, d } + +static bool got_sigsegv; +static jmp_buf jmp; + +static void +sigsegv_handler(int sig) +{ + (void) sig; + got_sigsegv = true; + longjmp(jmp, 1); +} + +class dri2_query_renderer_string_test : public ::testing::Test { +public: + virtual void SetUp(); + virtual void TearDown(); + + struct sigaction sa; + struct sigaction old_sa; +}; + +class dri2_query_renderer_integer_test : + public dri2_query_renderer_string_test { +}; + +static bool queryString_called = false; +static int queryString_attribute = -1; + +static bool queryInteger_called = false; +static int queryInteger_attribute = -1; + +static int +fake_queryInteger(__DRIscreen *screen, int attribute, unsigned int *val) +{ + (void) screen; + + queryInteger_attribute = attribute; + queryInteger_called = true; + + switch (attribute) { + case __DRI2_RENDERER_VENDOR_ID: + *val = ~__DRI2_RENDERER_VENDOR_ID; + return 0; + case __DRI2_RENDERER_DEVICE_ID: + *val = ~__DRI2_RENDERER_DEVICE_ID; + return 0; + case __DRI2_RENDERER_VERSION: + *val = ~__DRI2_RENDERER_VERSION; + return 0; + case __DRI2_RENDERER_ACCELERATED: + *val = ~__DRI2_RENDERER_ACCELERATED; + return 0; + case __DRI2_RENDERER_VIDEO_MEMORY: + *val = ~__DRI2_RENDERER_VIDEO_MEMORY; + return 0; + case __DRI2_RENDERER_UNIFIED_MEMORY_ARCHITECTURE: + *val = ~__DRI2_RENDERER_UNIFIED_MEMORY_ARCHITECTURE; + return 0; + case __DRI2_RENDERER_PREFERRED_PROFILE: + *val = ~__DRI2_RENDERER_PREFERRED_PROFILE; + return 0; + case __DRI2_RENDERER_OPENGL_CORE_PROFILE_VERSION: + *val = ~__DRI2_RENDERER_OPENGL_CORE_PROFILE_VERSION; + return 0; + case __DRI2_RENDERER_OPENGL_COMPATIBILITY_PROFILE_VERSION: + *val = ~__DRI2_RENDERER_OPENGL_COMPATIBILITY_PROFILE_VERSION; + return 0; + case __DRI2_RENDERER_OPENGL_ES_PROFILE_VERSION: + *val = ~__DRI2_RENDERER_OPENGL_ES_PROFILE_VERSION; + return 0; + case __DRI2_RENDERER_OPENGL_ES2_PROFILE_VERSION: + *val = ~__DRI2_RENDERER_OPENGL_ES2_PROFILE_VERSION; + return 0; + } + + return -1; +} + +static int +fake_queryString(__DRIscreen *screen, int attribute, const char **val) +{ + (void) screen; + + queryString_attribute = attribute; + queryString_called = true; + + switch (attribute) { + case __DRI2_RENDERER_VENDOR_ID: + *val = "__DRI2_RENDERER_VENDOR_ID"; + return 0; + case __DRI2_RENDERER_DEVICE_ID: + *val = "__DRI2_RENDERER_DEVICE_ID"; + return 0; + } + + return -1; +} + +struct __DRI2rendererQueryExtensionRec rendererQueryExt = { + { __DRI2_RENDERER_QUERY, 1 }, + + fake_queryInteger, + fake_queryString +}; + +void dri2_query_renderer_string_test::SetUp() +{ + got_sigsegv = false; + + sa.sa_handler = sigsegv_handler; + sigemptyset(&sa.sa_mask); + sa.sa_flags = 0; + sigaction(SIGSEGV, &sa, &old_sa); +} + +void dri2_query_renderer_string_test::TearDown() +{ + sigaction(SIGSEGV, &old_sa, NULL); +} + +/** + * dri2_query_renderer_string will return an error if the rendererQuery + * extension is not present. It will also not segfault. + */ +TEST_F(dri2_query_renderer_string_test, DRI2_RENDERER_QUERY_not_supported) +{ + struct dri2_screen dsc; + + memset(&dsc, 0, sizeof(dsc)); + + if (setjmp(jmp) == 0) { + static const char original_value[] = "0xDEADBEEF"; + const char *value = original_value; + const int success = + dri2_query_renderer_string(&dsc.base, + GLX_RENDERER_VENDOR_ID_MESA, &value); + + EXPECT_EQ(-1, success); + EXPECT_EQ(original_value, value); + } else { + EXPECT_FALSE(got_sigsegv); + } +} + +/** + * dri2_query_renderer_string will call queryString with the correct DRI2 enum + * for each GLX attribute value. + * + * \note + * This test does \b not perform any checking for invalid GLX attribte values. + * Other unit tests verify that invalid values are filtered before + * dri2_query_renderer_string is called. + */ +TEST_F(dri2_query_renderer_string_test, valid_attribute_mapping) +{ + struct dri2_screen dsc; + struct attribute_test_vector valid_attributes[] = { + E(GLX_RENDERER_VENDOR_ID_MESA, + __DRI2_RENDERER_VENDOR_ID), + E(GLX_RENDERER_DEVICE_ID_MESA, + __DRI2_RENDERER_DEVICE_ID), + }; + + memset(&dsc, 0, sizeof(dsc)); + dsc.rendererQuery = &rendererQueryExt; + + if (setjmp(jmp) == 0) { + for (unsigned i = 0; i < ARRAY_SIZE(valid_attributes); i++) { + static const char original_value[] = "original value"; + const char *value = original_value; + const int success = + dri2_query_renderer_string(&dsc.base, + valid_attributes[i].glx_attribute, + &value); + + EXPECT_EQ(0, success); + EXPECT_EQ(valid_attributes[i].dri_attribute, queryString_attribute) + << valid_attributes[i].glx_string; + EXPECT_STREQ(valid_attributes[i].dri_string, value) + << valid_attributes[i].glx_string; + } + } else { + EXPECT_FALSE(got_sigsegv); + } +} + +/** + * dri2_query_renderer_integer will return an error if the rendererQuery + * extension is not present. It will also not segfault. + */ +TEST_F(dri2_query_renderer_integer_test, DRI2_RENDERER_QUERY_not_supported) +{ + struct dri2_screen dsc; + + memset(&dsc, 0, sizeof(dsc)); + + if (setjmp(jmp) == 0) { + unsigned int value = 0xDEADBEEF; + const int success = + dri2_query_renderer_integer(&dsc.base, + GLX_RENDERER_VENDOR_ID_MESA, &value); + + EXPECT_EQ(-1, success); + EXPECT_EQ(0xDEADBEEF, value); + } else { + EXPECT_FALSE(got_sigsegv); + } +} + +/** + * dri2_query_renderer_integer will call queryInteger with the correct DRI2 enum + * for each GLX attribute value. + * + * \note + * This test does \b not perform any checking for invalid GLX attribte values. + * Other unit tests verify that invalid values are filtered before + * dri2_query_renderer_integer is called. + */ +TEST_F(dri2_query_renderer_integer_test, valid_attribute_mapping) +{ + struct dri2_screen dsc; + struct attribute_test_vector valid_attributes[] = { + E(GLX_RENDERER_VENDOR_ID_MESA, + __DRI2_RENDERER_VENDOR_ID), + E(GLX_RENDERER_DEVICE_ID_MESA, + __DRI2_RENDERER_DEVICE_ID), + E(GLX_RENDERER_VERSION_MESA, + __DRI2_RENDERER_VERSION), + E(GLX_RENDERER_ACCELERATED_MESA, + __DRI2_RENDERER_ACCELERATED), + E(GLX_RENDERER_VIDEO_MEMORY_MESA, + __DRI2_RENDERER_VIDEO_MEMORY), + E(GLX_RENDERER_UNIFIED_MEMORY_ARCHITECTURE_MESA, + __DRI2_RENDERER_UNIFIED_MEMORY_ARCHITECTURE), + E(GLX_RENDERER_PREFERRED_PROFILE_MESA, + __DRI2_RENDERER_PREFERRED_PROFILE), + E(GLX_RENDERER_OPENGL_CORE_PROFILE_VERSION_MESA, + __DRI2_RENDERER_OPENGL_CORE_PROFILE_VERSION), + E(GLX_RENDERER_OPENGL_COMPATIBILITY_PROFILE_VERSION_MESA, + __DRI2_RENDERER_OPENGL_COMPATIBILITY_PROFILE_VERSION), + E(GLX_RENDERER_OPENGL_ES_PROFILE_VERSION_MESA, + __DRI2_RENDERER_OPENGL_ES_PROFILE_VERSION), + E(GLX_RENDERER_OPENGL_ES2_PROFILE_VERSION_MESA, + __DRI2_RENDERER_OPENGL_ES2_PROFILE_VERSION), + }; + + memset(&dsc, 0, sizeof(dsc)); + dsc.rendererQuery = &rendererQueryExt; + + if (setjmp(jmp) == 0) { + for (unsigned i = 0; i < ARRAY_SIZE(valid_attributes); i++) { + unsigned int value = 0xDEADBEEF; + const int success = + dri2_query_renderer_integer(&dsc.base, + valid_attributes[i].glx_attribute, + &value); + + EXPECT_EQ(0, success); + EXPECT_EQ(valid_attributes[i].dri_attribute, queryInteger_attribute) + << valid_attributes[i].glx_string; + EXPECT_EQ((unsigned int) ~valid_attributes[i].dri_attribute, value) + << valid_attributes[i].glx_string; + } + } else { + EXPECT_FALSE(got_sigsegv); + } +} -- 2.30.2