1bf215546Sopenharmony_ci/* 2bf215546Sopenharmony_ci * Copyright © 2013 Intel Corporation 3bf215546Sopenharmony_ci * 4bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 5bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"), 6bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation 7bf215546Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8bf215546Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the 9bf215546Sopenharmony_ci * Software is furnished to do so, subject to the following conditions: 10bf215546Sopenharmony_ci * 11bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the next 12bf215546Sopenharmony_ci * paragraph) shall be included in all copies or substantial portions of the 13bf215546Sopenharmony_ci * Software. 14bf215546Sopenharmony_ci * 15bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16bf215546Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18bf215546Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19bf215546Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20bf215546Sopenharmony_ci * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 21bf215546Sopenharmony_ci * DEALINGS IN THE SOFTWARE. 22bf215546Sopenharmony_ci */ 23bf215546Sopenharmony_ci#include <gtest/gtest.h> 24bf215546Sopenharmony_ci#include <signal.h> 25bf215546Sopenharmony_ci#include <setjmp.h> 26bf215546Sopenharmony_ci 27bf215546Sopenharmony_ci#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL) 28bf215546Sopenharmony_ci 29bf215546Sopenharmony_ci#include "glxclient.h" 30bf215546Sopenharmony_ci#include "glx_error.h" 31bf215546Sopenharmony_ci#include "dri2.h" 32bf215546Sopenharmony_ci#include "GL/internal/dri_interface.h" 33bf215546Sopenharmony_ci#include "dri2_priv.h" 34bf215546Sopenharmony_ci 35bf215546Sopenharmony_cinamespace { 36bf215546Sopenharmony_ci struct attribute_test_vector { 37bf215546Sopenharmony_ci const char *glx_string; 38bf215546Sopenharmony_ci const char *dri_string; 39bf215546Sopenharmony_ci int glx_attribute; 40bf215546Sopenharmony_ci int dri_attribute; 41bf215546Sopenharmony_ci }; 42bf215546Sopenharmony_ci} 43bf215546Sopenharmony_ci 44bf215546Sopenharmony_ci#define E(g, d) { # g, # d, g, d } 45bf215546Sopenharmony_ci 46bf215546Sopenharmony_cistatic bool got_sigsegv; 47bf215546Sopenharmony_cistatic jmp_buf jmp; 48bf215546Sopenharmony_ci 49bf215546Sopenharmony_cistatic void 50bf215546Sopenharmony_cisigsegv_handler(int sig) 51bf215546Sopenharmony_ci{ 52bf215546Sopenharmony_ci (void) sig; 53bf215546Sopenharmony_ci got_sigsegv = true; 54bf215546Sopenharmony_ci longjmp(jmp, 1); 55bf215546Sopenharmony_ci} 56bf215546Sopenharmony_ci 57bf215546Sopenharmony_ciclass dri2_query_renderer_string_test : public ::testing::Test { 58bf215546Sopenharmony_cipublic: 59bf215546Sopenharmony_ci virtual void SetUp(); 60bf215546Sopenharmony_ci virtual void TearDown(); 61bf215546Sopenharmony_ci 62bf215546Sopenharmony_ci struct sigaction sa; 63bf215546Sopenharmony_ci struct sigaction old_sa; 64bf215546Sopenharmony_ci}; 65bf215546Sopenharmony_ci 66bf215546Sopenharmony_ciclass dri2_query_renderer_integer_test : 67bf215546Sopenharmony_ci public dri2_query_renderer_string_test { 68bf215546Sopenharmony_ci}; 69bf215546Sopenharmony_ci 70bf215546Sopenharmony_cistatic bool queryString_called = false; 71bf215546Sopenharmony_cistatic int queryString_attribute = -1; 72bf215546Sopenharmony_ci 73bf215546Sopenharmony_cistatic bool queryInteger_called = false; 74bf215546Sopenharmony_cistatic int queryInteger_attribute = -1; 75bf215546Sopenharmony_ci 76bf215546Sopenharmony_cistatic int 77bf215546Sopenharmony_cifake_queryInteger(__DRIscreen *screen, int attribute, unsigned int *val) 78bf215546Sopenharmony_ci{ 79bf215546Sopenharmony_ci (void) screen; 80bf215546Sopenharmony_ci 81bf215546Sopenharmony_ci queryInteger_attribute = attribute; 82bf215546Sopenharmony_ci queryInteger_called = true; 83bf215546Sopenharmony_ci 84bf215546Sopenharmony_ci switch (attribute) { 85bf215546Sopenharmony_ci case __DRI2_RENDERER_VENDOR_ID: 86bf215546Sopenharmony_ci *val = ~__DRI2_RENDERER_VENDOR_ID; 87bf215546Sopenharmony_ci return 0; 88bf215546Sopenharmony_ci case __DRI2_RENDERER_DEVICE_ID: 89bf215546Sopenharmony_ci *val = ~__DRI2_RENDERER_DEVICE_ID; 90bf215546Sopenharmony_ci return 0; 91bf215546Sopenharmony_ci case __DRI2_RENDERER_VERSION: 92bf215546Sopenharmony_ci *val = ~__DRI2_RENDERER_VERSION; 93bf215546Sopenharmony_ci return 0; 94bf215546Sopenharmony_ci case __DRI2_RENDERER_ACCELERATED: 95bf215546Sopenharmony_ci *val = ~__DRI2_RENDERER_ACCELERATED; 96bf215546Sopenharmony_ci return 0; 97bf215546Sopenharmony_ci case __DRI2_RENDERER_VIDEO_MEMORY: 98bf215546Sopenharmony_ci *val = ~__DRI2_RENDERER_VIDEO_MEMORY; 99bf215546Sopenharmony_ci return 0; 100bf215546Sopenharmony_ci case __DRI2_RENDERER_UNIFIED_MEMORY_ARCHITECTURE: 101bf215546Sopenharmony_ci *val = ~__DRI2_RENDERER_UNIFIED_MEMORY_ARCHITECTURE; 102bf215546Sopenharmony_ci return 0; 103bf215546Sopenharmony_ci case __DRI2_RENDERER_PREFERRED_PROFILE: 104bf215546Sopenharmony_ci *val = ~__DRI2_RENDERER_PREFERRED_PROFILE; 105bf215546Sopenharmony_ci return 0; 106bf215546Sopenharmony_ci case __DRI2_RENDERER_OPENGL_CORE_PROFILE_VERSION: 107bf215546Sopenharmony_ci *val = ~__DRI2_RENDERER_OPENGL_CORE_PROFILE_VERSION; 108bf215546Sopenharmony_ci return 0; 109bf215546Sopenharmony_ci case __DRI2_RENDERER_OPENGL_COMPATIBILITY_PROFILE_VERSION: 110bf215546Sopenharmony_ci *val = ~__DRI2_RENDERER_OPENGL_COMPATIBILITY_PROFILE_VERSION; 111bf215546Sopenharmony_ci return 0; 112bf215546Sopenharmony_ci case __DRI2_RENDERER_OPENGL_ES_PROFILE_VERSION: 113bf215546Sopenharmony_ci *val = ~__DRI2_RENDERER_OPENGL_ES_PROFILE_VERSION; 114bf215546Sopenharmony_ci return 0; 115bf215546Sopenharmony_ci case __DRI2_RENDERER_OPENGL_ES2_PROFILE_VERSION: 116bf215546Sopenharmony_ci *val = ~__DRI2_RENDERER_OPENGL_ES2_PROFILE_VERSION; 117bf215546Sopenharmony_ci return 0; 118bf215546Sopenharmony_ci } 119bf215546Sopenharmony_ci 120bf215546Sopenharmony_ci return -1; 121bf215546Sopenharmony_ci} 122bf215546Sopenharmony_ci 123bf215546Sopenharmony_cistatic int 124bf215546Sopenharmony_cifake_queryString(__DRIscreen *screen, int attribute, const char **val) 125bf215546Sopenharmony_ci{ 126bf215546Sopenharmony_ci (void) screen; 127bf215546Sopenharmony_ci 128bf215546Sopenharmony_ci queryString_attribute = attribute; 129bf215546Sopenharmony_ci queryString_called = true; 130bf215546Sopenharmony_ci 131bf215546Sopenharmony_ci switch (attribute) { 132bf215546Sopenharmony_ci case __DRI2_RENDERER_VENDOR_ID: 133bf215546Sopenharmony_ci *val = "__DRI2_RENDERER_VENDOR_ID"; 134bf215546Sopenharmony_ci return 0; 135bf215546Sopenharmony_ci case __DRI2_RENDERER_DEVICE_ID: 136bf215546Sopenharmony_ci *val = "__DRI2_RENDERER_DEVICE_ID"; 137bf215546Sopenharmony_ci return 0; 138bf215546Sopenharmony_ci } 139bf215546Sopenharmony_ci 140bf215546Sopenharmony_ci return -1; 141bf215546Sopenharmony_ci} 142bf215546Sopenharmony_ci 143bf215546Sopenharmony_cistatic const __DRI2rendererQueryExtension rendererQueryExt = { 144bf215546Sopenharmony_ci { __DRI2_RENDERER_QUERY, 1 }, 145bf215546Sopenharmony_ci 146bf215546Sopenharmony_ci fake_queryInteger, 147bf215546Sopenharmony_ci fake_queryString 148bf215546Sopenharmony_ci}; 149bf215546Sopenharmony_ci 150bf215546Sopenharmony_civoid dri2_query_renderer_string_test::SetUp() 151bf215546Sopenharmony_ci{ 152bf215546Sopenharmony_ci got_sigsegv = false; 153bf215546Sopenharmony_ci 154bf215546Sopenharmony_ci sa.sa_handler = sigsegv_handler; 155bf215546Sopenharmony_ci sigemptyset(&sa.sa_mask); 156bf215546Sopenharmony_ci sa.sa_flags = 0; 157bf215546Sopenharmony_ci sigaction(SIGSEGV, &sa, &old_sa); 158bf215546Sopenharmony_ci} 159bf215546Sopenharmony_ci 160bf215546Sopenharmony_civoid dri2_query_renderer_string_test::TearDown() 161bf215546Sopenharmony_ci{ 162bf215546Sopenharmony_ci sigaction(SIGSEGV, &old_sa, NULL); 163bf215546Sopenharmony_ci} 164bf215546Sopenharmony_ci 165bf215546Sopenharmony_ci/** 166bf215546Sopenharmony_ci * dri2_query_renderer_string will return an error if the rendererQuery 167bf215546Sopenharmony_ci * extension is not present. It will also not segfault. 168bf215546Sopenharmony_ci */ 169bf215546Sopenharmony_ciTEST_F(dri2_query_renderer_string_test, DRI2_RENDERER_QUERY_not_supported) 170bf215546Sopenharmony_ci{ 171bf215546Sopenharmony_ci struct dri2_screen dsc; 172bf215546Sopenharmony_ci 173bf215546Sopenharmony_ci memset(&dsc, 0, sizeof(dsc)); 174bf215546Sopenharmony_ci 175bf215546Sopenharmony_ci if (setjmp(jmp) == 0) { 176bf215546Sopenharmony_ci static const char original_value[] = "0xDEADBEEF"; 177bf215546Sopenharmony_ci const char *value = original_value; 178bf215546Sopenharmony_ci const int success = 179bf215546Sopenharmony_ci dri2_query_renderer_string(&dsc.base, 180bf215546Sopenharmony_ci GLX_RENDERER_VENDOR_ID_MESA, &value); 181bf215546Sopenharmony_ci 182bf215546Sopenharmony_ci EXPECT_EQ(-1, success); 183bf215546Sopenharmony_ci EXPECT_EQ(original_value, value); 184bf215546Sopenharmony_ci } else { 185bf215546Sopenharmony_ci EXPECT_FALSE(got_sigsegv); 186bf215546Sopenharmony_ci } 187bf215546Sopenharmony_ci} 188bf215546Sopenharmony_ci 189bf215546Sopenharmony_ci/** 190bf215546Sopenharmony_ci * dri2_query_renderer_string will call queryString with the correct DRI2 enum 191bf215546Sopenharmony_ci * for each GLX attribute value. 192bf215546Sopenharmony_ci * 193bf215546Sopenharmony_ci * \note 194bf215546Sopenharmony_ci * This test does \b not perform any checking for invalid GLX attribte values. 195bf215546Sopenharmony_ci * Other unit tests verify that invalid values are filtered before 196bf215546Sopenharmony_ci * dri2_query_renderer_string is called. 197bf215546Sopenharmony_ci */ 198bf215546Sopenharmony_ciTEST_F(dri2_query_renderer_string_test, valid_attribute_mapping) 199bf215546Sopenharmony_ci{ 200bf215546Sopenharmony_ci struct dri2_screen dsc; 201bf215546Sopenharmony_ci struct attribute_test_vector valid_attributes[] = { 202bf215546Sopenharmony_ci E(GLX_RENDERER_VENDOR_ID_MESA, 203bf215546Sopenharmony_ci __DRI2_RENDERER_VENDOR_ID), 204bf215546Sopenharmony_ci E(GLX_RENDERER_DEVICE_ID_MESA, 205bf215546Sopenharmony_ci __DRI2_RENDERER_DEVICE_ID), 206bf215546Sopenharmony_ci }; 207bf215546Sopenharmony_ci 208bf215546Sopenharmony_ci memset(&dsc, 0, sizeof(dsc)); 209bf215546Sopenharmony_ci dsc.rendererQuery = &rendererQueryExt; 210bf215546Sopenharmony_ci 211bf215546Sopenharmony_ci if (setjmp(jmp) == 0) { 212bf215546Sopenharmony_ci for (unsigned i = 0; i < ARRAY_SIZE(valid_attributes); i++) { 213bf215546Sopenharmony_ci static const char original_value[] = "original value"; 214bf215546Sopenharmony_ci const char *value = original_value; 215bf215546Sopenharmony_ci const int success = 216bf215546Sopenharmony_ci dri2_query_renderer_string(&dsc.base, 217bf215546Sopenharmony_ci valid_attributes[i].glx_attribute, 218bf215546Sopenharmony_ci &value); 219bf215546Sopenharmony_ci 220bf215546Sopenharmony_ci EXPECT_EQ(0, success); 221bf215546Sopenharmony_ci EXPECT_EQ(valid_attributes[i].dri_attribute, queryString_attribute) 222bf215546Sopenharmony_ci << valid_attributes[i].glx_string; 223bf215546Sopenharmony_ci EXPECT_STREQ(valid_attributes[i].dri_string, value) 224bf215546Sopenharmony_ci << valid_attributes[i].glx_string; 225bf215546Sopenharmony_ci } 226bf215546Sopenharmony_ci } else { 227bf215546Sopenharmony_ci EXPECT_FALSE(got_sigsegv); 228bf215546Sopenharmony_ci } 229bf215546Sopenharmony_ci} 230bf215546Sopenharmony_ci 231bf215546Sopenharmony_ci/** 232bf215546Sopenharmony_ci * dri2_query_renderer_integer will return an error if the rendererQuery 233bf215546Sopenharmony_ci * extension is not present. It will also not segfault. 234bf215546Sopenharmony_ci */ 235bf215546Sopenharmony_ciTEST_F(dri2_query_renderer_integer_test, DRI2_RENDERER_QUERY_not_supported) 236bf215546Sopenharmony_ci{ 237bf215546Sopenharmony_ci struct dri2_screen dsc; 238bf215546Sopenharmony_ci 239bf215546Sopenharmony_ci memset(&dsc, 0, sizeof(dsc)); 240bf215546Sopenharmony_ci 241bf215546Sopenharmony_ci if (setjmp(jmp) == 0) { 242bf215546Sopenharmony_ci unsigned int value = 0xDEADBEEF; 243bf215546Sopenharmony_ci const int success = 244bf215546Sopenharmony_ci dri2_query_renderer_integer(&dsc.base, 245bf215546Sopenharmony_ci GLX_RENDERER_VENDOR_ID_MESA, &value); 246bf215546Sopenharmony_ci 247bf215546Sopenharmony_ci EXPECT_EQ(-1, success); 248bf215546Sopenharmony_ci EXPECT_EQ(0xDEADBEEF, value); 249bf215546Sopenharmony_ci } else { 250bf215546Sopenharmony_ci EXPECT_FALSE(got_sigsegv); 251bf215546Sopenharmony_ci } 252bf215546Sopenharmony_ci} 253bf215546Sopenharmony_ci 254bf215546Sopenharmony_ci/** 255bf215546Sopenharmony_ci * dri2_query_renderer_integer will call queryInteger with the correct DRI2 enum 256bf215546Sopenharmony_ci * for each GLX attribute value. 257bf215546Sopenharmony_ci * 258bf215546Sopenharmony_ci * \note 259bf215546Sopenharmony_ci * This test does \b not perform any checking for invalid GLX attribte values. 260bf215546Sopenharmony_ci * Other unit tests verify that invalid values are filtered before 261bf215546Sopenharmony_ci * dri2_query_renderer_integer is called. 262bf215546Sopenharmony_ci */ 263bf215546Sopenharmony_ciTEST_F(dri2_query_renderer_integer_test, valid_attribute_mapping) 264bf215546Sopenharmony_ci{ 265bf215546Sopenharmony_ci struct dri2_screen dsc; 266bf215546Sopenharmony_ci struct attribute_test_vector valid_attributes[] = { 267bf215546Sopenharmony_ci E(GLX_RENDERER_VENDOR_ID_MESA, 268bf215546Sopenharmony_ci __DRI2_RENDERER_VENDOR_ID), 269bf215546Sopenharmony_ci E(GLX_RENDERER_DEVICE_ID_MESA, 270bf215546Sopenharmony_ci __DRI2_RENDERER_DEVICE_ID), 271bf215546Sopenharmony_ci E(GLX_RENDERER_VERSION_MESA, 272bf215546Sopenharmony_ci __DRI2_RENDERER_VERSION), 273bf215546Sopenharmony_ci E(GLX_RENDERER_ACCELERATED_MESA, 274bf215546Sopenharmony_ci __DRI2_RENDERER_ACCELERATED), 275bf215546Sopenharmony_ci E(GLX_RENDERER_VIDEO_MEMORY_MESA, 276bf215546Sopenharmony_ci __DRI2_RENDERER_VIDEO_MEMORY), 277bf215546Sopenharmony_ci E(GLX_RENDERER_UNIFIED_MEMORY_ARCHITECTURE_MESA, 278bf215546Sopenharmony_ci __DRI2_RENDERER_UNIFIED_MEMORY_ARCHITECTURE), 279bf215546Sopenharmony_ci E(GLX_RENDERER_PREFERRED_PROFILE_MESA, 280bf215546Sopenharmony_ci __DRI2_RENDERER_PREFERRED_PROFILE), 281bf215546Sopenharmony_ci E(GLX_RENDERER_OPENGL_CORE_PROFILE_VERSION_MESA, 282bf215546Sopenharmony_ci __DRI2_RENDERER_OPENGL_CORE_PROFILE_VERSION), 283bf215546Sopenharmony_ci E(GLX_RENDERER_OPENGL_COMPATIBILITY_PROFILE_VERSION_MESA, 284bf215546Sopenharmony_ci __DRI2_RENDERER_OPENGL_COMPATIBILITY_PROFILE_VERSION), 285bf215546Sopenharmony_ci E(GLX_RENDERER_OPENGL_ES_PROFILE_VERSION_MESA, 286bf215546Sopenharmony_ci __DRI2_RENDERER_OPENGL_ES_PROFILE_VERSION), 287bf215546Sopenharmony_ci E(GLX_RENDERER_OPENGL_ES2_PROFILE_VERSION_MESA, 288bf215546Sopenharmony_ci __DRI2_RENDERER_OPENGL_ES2_PROFILE_VERSION), 289bf215546Sopenharmony_ci }; 290bf215546Sopenharmony_ci 291bf215546Sopenharmony_ci memset(&dsc, 0, sizeof(dsc)); 292bf215546Sopenharmony_ci dsc.rendererQuery = &rendererQueryExt; 293bf215546Sopenharmony_ci 294bf215546Sopenharmony_ci if (setjmp(jmp) == 0) { 295bf215546Sopenharmony_ci for (unsigned i = 0; i < ARRAY_SIZE(valid_attributes); i++) { 296bf215546Sopenharmony_ci unsigned int value = 0xDEADBEEF; 297bf215546Sopenharmony_ci const int success = 298bf215546Sopenharmony_ci dri2_query_renderer_integer(&dsc.base, 299bf215546Sopenharmony_ci valid_attributes[i].glx_attribute, 300bf215546Sopenharmony_ci &value); 301bf215546Sopenharmony_ci 302bf215546Sopenharmony_ci EXPECT_EQ(0, success); 303bf215546Sopenharmony_ci EXPECT_EQ(valid_attributes[i].dri_attribute, queryInteger_attribute) 304bf215546Sopenharmony_ci << valid_attributes[i].glx_string; 305bf215546Sopenharmony_ci EXPECT_EQ((unsigned int) ~valid_attributes[i].dri_attribute, value) 306bf215546Sopenharmony_ci << valid_attributes[i].glx_string; 307bf215546Sopenharmony_ci } 308bf215546Sopenharmony_ci } else { 309bf215546Sopenharmony_ci EXPECT_FALSE(got_sigsegv); 310bf215546Sopenharmony_ci } 311bf215546Sopenharmony_ci} 312bf215546Sopenharmony_ci 313bf215546Sopenharmony_ci#endif /* GLX_DIRECT_RENDERING */ 314