1 /*
2  * Copyright (c) 2017 Timothy Arceri
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 VMWARE 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 /**
26  * Tests that api errors are thrown where expected for the
27  * GL_EXT_memory_object extension.
28  */
29 
30 #include "piglit-util-gl.h"
31 
32 PIGLIT_GL_TEST_CONFIG_BEGIN
33 
34 	config.supports_gl_compat_version = 20; /* Need 2.0 for DSA tests */
35 	config.window_visual = PIGLIT_GL_VISUAL_RGBA | PIGLIT_GL_VISUAL_DOUBLE;
36 	config.khr_no_error_support = PIGLIT_HAS_ERRORS;
37 
38 PIGLIT_GL_TEST_CONFIG_END
39 
40 
41 static bool
test_tex_storage_errors(GLenum target,bool dsa)42 test_tex_storage_errors(GLenum target, bool dsa)
43 {
44 	const GLint width = 64, height = 4, depth = 8;
45 	GLuint tex;
46 
47 	assert(target == GL_TEXTURE_1D ||
48 	       target == GL_TEXTURE_2D ||
49 	       target == GL_TEXTURE_3D);
50 
51 	glGenTextures(1, &tex);
52 	glBindTexture(target, tex);
53 
54 	/* Test that passing 0 for <memory> results in an error. */
55 	if (target == GL_TEXTURE_1D) {
56 		if (dsa) {
57 			glTextureStorageMem1DEXT(tex, 1, GL_RGBA8, width, 0,
58 						 0);
59 		} else {
60 			glTexStorageMem1DEXT(target, 1, GL_RGBA8, width, 0,
61 					     0);
62 		}
63 	}
64 	else if (target == GL_TEXTURE_2D) {
65 		if (dsa) {
66 			glTextureStorageMem2DEXT(tex, 1, GL_RGBA8, width,
67 						 height, 0, 0);
68 		} else {
69 			glTexStorageMem2DEXT(target, 1, GL_RGBA8, width,
70 					     height, 0, 0);
71 		}
72 	}
73 	else if (target == GL_TEXTURE_3D) {
74 		if (dsa) {
75 			glTextureStorageMem3DEXT(tex, 1, GL_RGBA8, width,
76 						 height, depth, 0, 0);
77 		} else {
78 			glTexStorageMem3DEXT(target, 1, GL_RGBA8, width,
79 					     height, depth, 0, 0);
80 		}
81 	}
82 
83 	/* From the EXT_external_objects spec:
84 	 *
85 	 *    "An INVALID_VALUE error is generated if <memory> is 0 ..."
86 	 */
87 	return piglit_check_gl_error(GL_INVALID_VALUE);
88 }
89 
90 static bool
test_tex_storage_ms_errors(GLenum target,bool dsa)91 test_tex_storage_ms_errors(GLenum target, bool dsa)
92 {
93 	const GLint width = 64, height = 4, depth = 8;
94 	GLuint tex;
95 
96 	assert(target == GL_TEXTURE_2D_MULTISAMPLE ||
97 	       target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY);
98 
99 	glGenTextures(1, &tex);
100 	glBindTexture(target, tex);
101 
102 	/* Test that passing 0 for <memory> results in an error. */
103 	if (target == GL_TEXTURE_2D_MULTISAMPLE) {
104 		if (dsa) {
105 			glTextureStorageMem2DMultisampleEXT(tex, 1, GL_RGBA8,
106 							    width, height,
107 							    GL_FALSE, 0, 0);
108 		} else {
109 			glTexStorageMem2DMultisampleEXT(target, 1, GL_RGBA8,
110 							width, height,
111 							GL_FALSE, 0, 0);
112 		}
113 	}
114 	else if (target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY) {
115 		if (dsa) {
116 			glTextureStorageMem3DMultisampleEXT(tex, 1, GL_RGBA8,
117 							    width, height,
118 							    depth, GL_FALSE,
119 							    0, 0);
120 		} else {
121 			glTexStorageMem3DMultisampleEXT(target, 1, GL_RGBA8,
122 							width, height,
123 							depth, GL_FALSE,
124 							0, 0);
125 		}
126 	}
127 
128 	/* From the EXT_external_objects spec:
129 	 *
130 	 *    "An INVALID_VALUE error is generated if <memory> is 0 ..."
131 	 */
132 	return piglit_check_gl_error(GL_INVALID_VALUE);
133 }
134 
135 #define BUF_SIZE (12 * 4 * sizeof(float))
136 
137 static bool
test_buffer_storage_errors(bool dsa)138 test_buffer_storage_errors(bool dsa)
139 {
140 	GLuint buffer;
141 
142 	glGenBuffers(1, &buffer);
143 	glBindBuffer(GL_ARRAY_BUFFER, buffer);
144 
145 	/* Test that passing 0 for <memory> results in an error. */
146 	if (dsa) {
147 		glNamedBufferStorageMemEXT(buffer, BUF_SIZE, 0, 0);
148 	} else {
149 		glBufferStorageMemEXT(GL_ARRAY_BUFFER, BUF_SIZE, 0, 0);
150 	}
151 
152 	/* From the EXT_external_objects spec:
153 	 *
154 	 *    "An INVALID_VALUE error is generated if <memory> is 0 ..."
155 	 */
156 	return piglit_check_gl_error(GL_INVALID_VALUE);
157 }
158 
159 static bool
test_get_unsigned_byte_v_enum_errors()160 test_get_unsigned_byte_v_enum_errors()
161 {
162 	GLubyte data[GL_UUID_SIZE_EXT];
163 
164 	glGetUnsignedBytevEXT(UINT32_MAX, data);
165 
166 	return piglit_check_gl_error(GL_INVALID_ENUM);
167 }
168 
169 static bool
test_get_unsigned_byte_i_v_enum_errors()170 test_get_unsigned_byte_i_v_enum_errors()
171 {
172 	GLubyte data[GL_UUID_SIZE_EXT];
173 
174 	glGetUnsignedBytei_vEXT(UINT32_MAX, 0, data);
175 
176 	return piglit_check_gl_error(GL_INVALID_ENUM);
177 }
178 
179 static bool
test_get_unsigned_byte_i_v_value_errors()180 test_get_unsigned_byte_i_v_value_errors()
181 {
182 	GLubyte data[GL_UUID_SIZE_EXT];
183 	GLint numDevices;
184 
185 	glGetIntegerv(GL_NUM_DEVICE_UUIDS_EXT, &numDevices);
186 
187 	if (!piglit_check_gl_error(GL_NO_ERROR))
188 		return PIGLIT_FAIL;
189 
190 	glGetUnsignedBytei_vEXT(GL_DEVICE_UUID_EXT, numDevices + 1, data);
191 
192 	return piglit_check_gl_error(GL_INVALID_VALUE);
193 }
194 
195 #define X(f, desc)					     	\
196 	do {							\
197 		const bool subtest_pass = (f);			\
198 		piglit_report_subtest_result(subtest_pass	\
199 					     ? PIGLIT_PASS : PIGLIT_FAIL, \
200 					     (desc));		\
201 		pass = pass && subtest_pass;			\
202 	} while (0)
203 
204 enum piglit_result
piglit_display(void)205 piglit_display(void)
206 {
207 	/* TODO: currently this test only tests for errors when we pass 0 for
208 	 * <memory>. We need to test for other errors.
209 	 */
210 
211 	bool pass = true;
212 	bool dsa = piglit_is_extension_supported("GL_ARB_direct_state_access");
213 
214 	X(test_tex_storage_errors(GL_TEXTURE_1D, false), "1D texture");
215 	X(test_tex_storage_errors(GL_TEXTURE_2D, false), "2D texture");
216 	X(test_tex_storage_errors(GL_TEXTURE_3D, false), "3D texture");
217 
218 	if (dsa) {
219 		X(test_tex_storage_errors(GL_TEXTURE_1D, true), "1D texture direct state access");
220 		X(test_tex_storage_errors(GL_TEXTURE_2D, true), "2D texture direct state access");
221 		X(test_tex_storage_errors(GL_TEXTURE_3D, true), "3D texture direct state access");
222 	}
223 
224 	if (piglit_is_extension_supported("GL_ARB_texture_storage_multisample")) {
225 		X(test_tex_storage_ms_errors(GL_TEXTURE_2D_MULTISAMPLE, false), "2D texture ms");
226 		X(test_tex_storage_ms_errors(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, false), "3D texture ms");
227 
228 		if (dsa) {
229 			X(test_tex_storage_ms_errors(GL_TEXTURE_2D_MULTISAMPLE, true), "2D texture ms direct state access");
230 			X(test_tex_storage_ms_errors(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, true), "3D texture ms direct state access");
231 		}
232 	}
233 
234 	if (piglit_is_extension_supported("GL_ARB_buffer_storage")) {
235 		X(test_buffer_storage_errors(false), "buffer storage");
236 
237 		if (dsa) {
238 			X(test_buffer_storage_errors(true), "buffer storage direct state access");
239 		}
240 	}
241 
242 	X(test_get_unsigned_byte_v_enum_errors(), "unsigned-byte-v-bad-enum");
243 	X(test_get_unsigned_byte_i_v_enum_errors(), "unsigned-byte-i-v-bad-enum");
244 	X(test_get_unsigned_byte_i_v_value_errors(), "unsigned-byte-i-v-bad-value");
245 
246 	return pass ? PIGLIT_PASS : PIGLIT_FAIL;
247 }
248 
249 
250 void
piglit_init(int argc,char ** argv)251 piglit_init(int argc, char **argv)
252 {
253 	/* From the EXT_external_objects spec:
254 	 *
255 	 *   "GL_EXT_memory_object requires ARB_texture_storage or a
256 	 *   version of OpenGL or OpenGL ES that incorporates it."
257 	 */
258 	piglit_require_extension("GL_ARB_texture_storage");
259 	piglit_require_extension("GL_EXT_memory_object");
260 }
261