Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  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. extern "C" {
  30. #include "glxclient.h"
  31. #include "glx_error.h"
  32. #include "dri2.h"
  33. #include "dri_interface.h"
  34. #include "dri2_priv.h"
  35. }
  36.  
  37. struct attribute_test_vector {
  38.    const char *glx_string;
  39.    const char *dri_string;
  40.    int glx_attribute;
  41.    int dri_attribute;
  42. };
  43.  
  44. #define E(g, d) { # g, # d, g, d }
  45.  
  46. static bool got_sigsegv;
  47. static jmp_buf jmp;
  48.  
  49. static void
  50. sigsegv_handler(int sig)
  51. {
  52.    (void) sig;
  53.    got_sigsegv = true;
  54.    longjmp(jmp, 1);
  55. }
  56.  
  57. class dri2_query_renderer_string_test : public ::testing::Test {
  58. public:
  59.    virtual void SetUp();
  60.    virtual void TearDown();
  61.  
  62.    struct sigaction sa;
  63.    struct sigaction old_sa;
  64. };
  65.  
  66. class dri2_query_renderer_integer_test :
  67.    public dri2_query_renderer_string_test {
  68. };
  69.  
  70. static bool queryString_called = false;
  71. static int queryString_attribute = -1;
  72.  
  73. static bool queryInteger_called = false;
  74. static int queryInteger_attribute = -1;
  75.  
  76. static int
  77. fake_queryInteger(__DRIscreen *screen, int attribute, unsigned int *val)
  78. {
  79.    (void) screen;
  80.  
  81.    queryInteger_attribute = attribute;
  82.    queryInteger_called = true;
  83.  
  84.    switch (attribute) {
  85.    case __DRI2_RENDERER_VENDOR_ID:
  86.       *val = ~__DRI2_RENDERER_VENDOR_ID;
  87.       return 0;
  88.    case __DRI2_RENDERER_DEVICE_ID:
  89.       *val = ~__DRI2_RENDERER_DEVICE_ID;
  90.       return 0;
  91.    case __DRI2_RENDERER_VERSION:
  92.       *val = ~__DRI2_RENDERER_VERSION;
  93.       return 0;
  94.    case __DRI2_RENDERER_ACCELERATED:
  95.       *val = ~__DRI2_RENDERER_ACCELERATED;
  96.       return 0;
  97.    case __DRI2_RENDERER_VIDEO_MEMORY:
  98.       *val = ~__DRI2_RENDERER_VIDEO_MEMORY;
  99.       return 0;
  100.    case __DRI2_RENDERER_UNIFIED_MEMORY_ARCHITECTURE:
  101.       *val = ~__DRI2_RENDERER_UNIFIED_MEMORY_ARCHITECTURE;
  102.       return 0;
  103.    case __DRI2_RENDERER_PREFERRED_PROFILE:
  104.       *val = ~__DRI2_RENDERER_PREFERRED_PROFILE;
  105.       return 0;
  106.    case __DRI2_RENDERER_OPENGL_CORE_PROFILE_VERSION:
  107.       *val = ~__DRI2_RENDERER_OPENGL_CORE_PROFILE_VERSION;
  108.       return 0;
  109.    case __DRI2_RENDERER_OPENGL_COMPATIBILITY_PROFILE_VERSION:
  110.       *val = ~__DRI2_RENDERER_OPENGL_COMPATIBILITY_PROFILE_VERSION;
  111.       return 0;
  112.    case __DRI2_RENDERER_OPENGL_ES_PROFILE_VERSION:
  113.       *val = ~__DRI2_RENDERER_OPENGL_ES_PROFILE_VERSION;
  114.       return 0;
  115.    case __DRI2_RENDERER_OPENGL_ES2_PROFILE_VERSION:
  116.       *val = ~__DRI2_RENDERER_OPENGL_ES2_PROFILE_VERSION;
  117.       return 0;
  118.    }
  119.  
  120.    return -1;
  121. }
  122.  
  123. static int
  124. fake_queryString(__DRIscreen *screen, int attribute, const char **val)
  125. {
  126.    (void) screen;
  127.  
  128.    queryString_attribute = attribute;
  129.    queryString_called = true;
  130.  
  131.    switch (attribute) {
  132.    case __DRI2_RENDERER_VENDOR_ID:
  133.       *val = "__DRI2_RENDERER_VENDOR_ID";
  134.       return 0;
  135.    case __DRI2_RENDERER_DEVICE_ID:
  136.       *val = "__DRI2_RENDERER_DEVICE_ID";
  137.       return 0;
  138.    }
  139.  
  140.    return -1;
  141. }
  142.  
  143. static const __DRI2rendererQueryExtension rendererQueryExt = {
  144.    { __DRI2_RENDERER_QUERY, 1 },
  145.  
  146.    fake_queryInteger,
  147.    fake_queryString
  148. };
  149.  
  150. void dri2_query_renderer_string_test::SetUp()
  151. {
  152.    got_sigsegv = false;
  153.  
  154.    sa.sa_handler = sigsegv_handler;
  155.    sigemptyset(&sa.sa_mask);
  156.    sa.sa_flags = 0;
  157.    sigaction(SIGSEGV, &sa, &old_sa);
  158. }
  159.  
  160. void dri2_query_renderer_string_test::TearDown()
  161. {
  162.    sigaction(SIGSEGV, &old_sa, NULL);
  163. }
  164.  
  165. /**
  166.  * dri2_query_renderer_string will return an error if the rendererQuery
  167.  * extension is not present.  It will also not segfault.
  168.  */
  169. TEST_F(dri2_query_renderer_string_test, DRI2_RENDERER_QUERY_not_supported)
  170. {
  171.    struct dri2_screen dsc;
  172.  
  173.    memset(&dsc, 0, sizeof(dsc));
  174.  
  175.    if (setjmp(jmp) == 0) {
  176.       static const char original_value[] = "0xDEADBEEF";
  177.       const char *value = original_value;
  178.       const int success =
  179.          dri2_query_renderer_string(&dsc.base,
  180.                                     GLX_RENDERER_VENDOR_ID_MESA, &value);
  181.  
  182.       EXPECT_EQ(-1, success);
  183.       EXPECT_EQ(original_value, value);
  184.    } else {
  185.       EXPECT_FALSE(got_sigsegv);
  186.    }
  187. }
  188.  
  189. /**
  190.  * dri2_query_renderer_string will call queryString with the correct DRI2 enum
  191.  * for each GLX attribute value.
  192.  *
  193.  * \note
  194.  * This test does \b not perform any checking for invalid GLX attribte values.
  195.  * Other unit tests verify that invalid values are filtered before
  196.  * dri2_query_renderer_string is called.
  197.  */
  198. TEST_F(dri2_query_renderer_string_test, valid_attribute_mapping)
  199. {
  200.    struct dri2_screen dsc;
  201.    struct attribute_test_vector valid_attributes[] = {
  202.       E(GLX_RENDERER_VENDOR_ID_MESA,
  203.         __DRI2_RENDERER_VENDOR_ID),
  204.       E(GLX_RENDERER_DEVICE_ID_MESA,
  205.         __DRI2_RENDERER_DEVICE_ID),
  206.    };
  207.  
  208.    memset(&dsc, 0, sizeof(dsc));
  209.    dsc.rendererQuery = &rendererQueryExt;
  210.  
  211.    if (setjmp(jmp) == 0) {
  212.       for (unsigned i = 0; i < ARRAY_SIZE(valid_attributes); i++) {
  213.          static const char original_value[] = "original value";
  214.          const char *value = original_value;
  215.          const int success =
  216.             dri2_query_renderer_string(&dsc.base,
  217.                                        valid_attributes[i].glx_attribute,
  218.                                        &value);
  219.  
  220.          EXPECT_EQ(0, success);
  221.          EXPECT_EQ(valid_attributes[i].dri_attribute, queryString_attribute)
  222.             << valid_attributes[i].glx_string;
  223.          EXPECT_STREQ(valid_attributes[i].dri_string, value)
  224.             << valid_attributes[i].glx_string;
  225.       }
  226.    } else {
  227.       EXPECT_FALSE(got_sigsegv);
  228.    }
  229. }
  230.  
  231. /**
  232.  * dri2_query_renderer_integer will return an error if the rendererQuery
  233.  * extension is not present.  It will also not segfault.
  234.  */
  235. TEST_F(dri2_query_renderer_integer_test, DRI2_RENDERER_QUERY_not_supported)
  236. {
  237.    struct dri2_screen dsc;
  238.  
  239.    memset(&dsc, 0, sizeof(dsc));
  240.  
  241.    if (setjmp(jmp) == 0) {
  242.       unsigned int value = 0xDEADBEEF;
  243.       const int success =
  244.          dri2_query_renderer_integer(&dsc.base,
  245.                                     GLX_RENDERER_VENDOR_ID_MESA, &value);
  246.  
  247.       EXPECT_EQ(-1, success);
  248.       EXPECT_EQ(0xDEADBEEF, value);
  249.    } else {
  250.       EXPECT_FALSE(got_sigsegv);
  251.    }
  252. }
  253.  
  254. /**
  255.  * dri2_query_renderer_integer will call queryInteger with the correct DRI2 enum
  256.  * for each GLX attribute value.
  257.  *
  258.  * \note
  259.  * This test does \b not perform any checking for invalid GLX attribte values.
  260.  * Other unit tests verify that invalid values are filtered before
  261.  * dri2_query_renderer_integer is called.
  262.  */
  263. TEST_F(dri2_query_renderer_integer_test, valid_attribute_mapping)
  264. {
  265.    struct dri2_screen dsc;
  266.    struct attribute_test_vector valid_attributes[] = {
  267.       E(GLX_RENDERER_VENDOR_ID_MESA,
  268.         __DRI2_RENDERER_VENDOR_ID),
  269.       E(GLX_RENDERER_DEVICE_ID_MESA,
  270.         __DRI2_RENDERER_DEVICE_ID),
  271.       E(GLX_RENDERER_VERSION_MESA,
  272.         __DRI2_RENDERER_VERSION),
  273.       E(GLX_RENDERER_ACCELERATED_MESA,
  274.         __DRI2_RENDERER_ACCELERATED),
  275.       E(GLX_RENDERER_VIDEO_MEMORY_MESA,
  276.         __DRI2_RENDERER_VIDEO_MEMORY),
  277.       E(GLX_RENDERER_UNIFIED_MEMORY_ARCHITECTURE_MESA,
  278.         __DRI2_RENDERER_UNIFIED_MEMORY_ARCHITECTURE),
  279.       E(GLX_RENDERER_PREFERRED_PROFILE_MESA,
  280.         __DRI2_RENDERER_PREFERRED_PROFILE),
  281.       E(GLX_RENDERER_OPENGL_CORE_PROFILE_VERSION_MESA,
  282.         __DRI2_RENDERER_OPENGL_CORE_PROFILE_VERSION),
  283.       E(GLX_RENDERER_OPENGL_COMPATIBILITY_PROFILE_VERSION_MESA,
  284.         __DRI2_RENDERER_OPENGL_COMPATIBILITY_PROFILE_VERSION),
  285.       E(GLX_RENDERER_OPENGL_ES_PROFILE_VERSION_MESA,
  286.         __DRI2_RENDERER_OPENGL_ES_PROFILE_VERSION),
  287.       E(GLX_RENDERER_OPENGL_ES2_PROFILE_VERSION_MESA,
  288.         __DRI2_RENDERER_OPENGL_ES2_PROFILE_VERSION),
  289.    };
  290.  
  291.    memset(&dsc, 0, sizeof(dsc));
  292.    dsc.rendererQuery = &rendererQueryExt;
  293.  
  294.    if (setjmp(jmp) == 0) {
  295.       for (unsigned i = 0; i < ARRAY_SIZE(valid_attributes); i++) {
  296.          unsigned int value = 0xDEADBEEF;
  297.          const int success =
  298.             dri2_query_renderer_integer(&dsc.base,
  299.                                        valid_attributes[i].glx_attribute,
  300.                                        &value);
  301.  
  302.          EXPECT_EQ(0, success);
  303.          EXPECT_EQ(valid_attributes[i].dri_attribute, queryInteger_attribute)
  304.             << valid_attributes[i].glx_string;
  305.          EXPECT_EQ((unsigned int) ~valid_attributes[i].dri_attribute, value)
  306.             << valid_attributes[i].glx_string;
  307.       }
  308.    } else {
  309.       EXPECT_FALSE(got_sigsegv);
  310.    }
  311. }
  312.  
  313. #endif /* GLX_DIRECT_RENDERING */
  314.