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