1 /*
2  * Copyright (c) 2012 Marek Olšák <maraeo@gmail.com>
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  * on the rights to use, copy, modify, merge, publish, distribute, sub
8  * license, and/or sell copies of the Software, and to permit persons to whom
9  * the 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,
16  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18  * NON-INFRINGEMENT.  IN NO EVENT SHALL AUTHORS AND/OR THEIR SUPPLIERS
19  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
20  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22  * SOFTWARE.
23  */
24 
25 #include "piglit-util-gl.h"
26 
27 PIGLIT_GL_TEST_CONFIG_BEGIN
28 
29 	config.supports_gl_compat_version = 10;
30 	config.require_debug_context = true;
31 
32 	config.window_visual = PIGLIT_GL_VISUAL_RGBA | PIGLIT_GL_VISUAL_DOUBLE;
33 
34 	config.khr_no_error_support = PIGLIT_HAS_ERRORS;
35 
36 PIGLIT_GL_TEST_CONFIG_END
37 
38 #define USER_PARAM ((void*)(intptr_t)12345678)
39 
40 static GLboolean callback_called;
41 
42 enum piglit_result
piglit_display(void)43 piglit_display(void)
44 {
45    return PIGLIT_PASS;
46 }
47 
debug_callback(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar * message,GLvoid * userParam)48 static void GLAPIENTRY debug_callback(GLenum source,
49                                       GLenum type,
50                                       GLuint id,
51                                       GLenum severity,
52                                       GLsizei length,
53                                       const GLchar* message,
54                                       GLvoid* userParam)
55 {
56    if (source != GL_DEBUG_SOURCE_API_ARB) {
57       puts("source isn't API");
58       piglit_report_result(PIGLIT_FAIL);
59    }
60 
61    if (type != GL_DEBUG_TYPE_ERROR_ARB) {
62       puts("type isn't error");
63       piglit_report_result(PIGLIT_FAIL);
64    }
65 
66    if (userParam != USER_PARAM) {
67       puts("wrong userParam in the callback");
68       piglit_report_result(PIGLIT_FAIL);
69    }
70 
71    callback_called = GL_TRUE;
72    printf("Callback: ");
73    fwrite(message, length, 1, stdout);
74    printf("\n");
75 }
76 
fetch_one_log_message()77 static GLboolean fetch_one_log_message()
78 {
79    char log[4096];
80    GLboolean ret =
81       !!glGetDebugMessageLogARB(1, 4096, NULL, NULL, NULL, NULL, NULL, log);
82 
83    if (ret) {
84       printf("Log: %s\n", log);
85    }
86    return ret;
87 }
88 
89 enum {
90    SKIP_SETUP = 1 << 0,
91    DEBUG_ENABLE = 1 << 1,
92    CALLBACK_ENABLE = 1 << 2
93 };
94 
test_api_error(unsigned flags)95 static void test_api_error(unsigned flags)
96 {
97    GLboolean skip_setup = !!(flags & SKIP_SETUP);
98    GLboolean debug_enable = !!(flags & DEBUG_ENABLE);
99    GLboolean callback_enable = !!(flags & CALLBACK_ENABLE);
100 
101    if (!skip_setup) {
102       printf("Testing Debug %s and Callback %s\n",
103              debug_enable ? "enabled" : "disabled",
104              callback_enable ? "enabled" : "disabled");
105 
106       glDebugMessageControlARB(GL_DEBUG_SOURCE_API_ARB, GL_DEBUG_TYPE_ERROR_ARB,
107                                GL_DEBUG_SEVERITY_HIGH_ARB, 0, NULL, debug_enable);
108       glDebugMessageCallbackARB(callback_enable ? debug_callback : NULL, USER_PARAM);
109    } else {
110       puts("Testing defaults.");
111    }
112 
113    if (!piglit_check_gl_error(GL_NO_ERROR))
114       piglit_report_result(PIGLIT_FAIL);
115 
116    /* empty the log */
117    while (fetch_one_log_message());
118 
119    callback_called = GL_FALSE;
120    glEnable(0xFFFFFFFF); /* GL error */
121 
122    if (!piglit_check_gl_error(GL_INVALID_ENUM))
123       piglit_report_result(PIGLIT_FAIL);
124 
125    if (callback_called != (callback_enable && debug_enable)) {
126       puts(callback_called ? "  The callback shouldn't have been called."
127                            : "  The callback should have been called.");
128       piglit_report_result(PIGLIT_FAIL);
129    }
130 
131    if ((skip_setup || debug_enable) && !callback_enable) {
132       /* the log must contain the error */
133       if (!fetch_one_log_message()) {
134          puts("  The log shouldn't be empty.");
135          piglit_report_result(PIGLIT_FAIL);
136       }
137    } else {
138       /* the log must be empty */
139       if (fetch_one_log_message()) {
140          puts("  The log should be empty.");
141          piglit_report_result(PIGLIT_FAIL);
142       }
143    }
144 
145    if (!piglit_check_gl_error(GL_NO_ERROR))
146       piglit_report_result(PIGLIT_FAIL);
147 }
148 
piglit_init(int argc,char ** argv)149 void piglit_init(int argc, char **argv)
150 {
151    piglit_automatic = GL_TRUE;
152    piglit_require_extension("GL_ARB_debug_output");
153 
154    glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB);
155 
156    if (!piglit_check_gl_error(GL_NO_ERROR))
157       piglit_report_result(PIGLIT_FAIL);
158 
159    test_api_error(SKIP_SETUP);
160    test_api_error(CALLBACK_ENABLE);
161    test_api_error(DEBUG_ENABLE);
162    test_api_error(DEBUG_ENABLE | CALLBACK_ENABLE);
163    test_api_error(0);
164 
165    piglit_report_result(PIGLIT_PASS);
166 }
167