1 /*
2  * Copyright © 2015 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 DEALINGS
21  * IN THE SOFTWARE.
22  */
23 
24 /** @file read-depth.c
25  *
26  * Tests NV_read_depth implementation
27  *
28  * Test iterates over table of depth buffer formats and expected types to
29  * read values back from each format. For each format it renders a rectangle at
30  * different depth levels, reads back a pixel and verifies expected depth value.
31  */
32 
33 #include "piglit-util-gl.h"
34 
35 PIGLIT_GL_TEST_CONFIG_BEGIN
36 
37 	config.supports_gl_es_version = 30;
38 	config.window_visual = PIGLIT_GL_VISUAL_DEPTH;
39 
40 PIGLIT_GL_TEST_CONFIG_END
41 
42 static GLint prog;
43 
44 const char *vs_source =
45 	"attribute vec4 vertex;\n"
46 	"uniform float depth;\n"
47 	"void main()\n"
48 	"{\n"
49 	"	gl_Position = vec4(vertex.xy, depth, 1.0);\n"
50 	"}\n";
51 
52 const char *fs_source =
53 	"void main()\n"
54 	"{\n"
55 	"}\n";
56 
57 const GLenum tests[] = {
58 	GL_DEPTH_COMPONENT16, GL_UNSIGNED_INT_24_8_OES,
59 	GL_DEPTH_COMPONENT24, GL_UNSIGNED_INT_24_8_OES,
60 	GL_DEPTH_COMPONENT32F, GL_FLOAT,
61 };
62 
63 static bool
equals(float a,float b)64 equals(float a, float b)
65 {
66    return fabs(a - b) < 0.00001;
67 }
68 
69 static GLuint
create_depth_fbo(GLenum depth_type)70 create_depth_fbo(GLenum depth_type)
71 {
72 	GLuint fbo, buffer;
73 	GLenum status;
74 
75 	glGenRenderbuffers(1, &buffer);
76 	glBindRenderbuffer(GL_RENDERBUFFER, buffer);
77 	glRenderbufferStorage(GL_RENDERBUFFER,
78 		depth_type, piglit_width, piglit_height);
79 
80 	glGenFramebuffers(1, &fbo);
81 	glBindFramebuffer(GL_FRAMEBUFFER, fbo);
82 
83 	glFramebufferRenderbuffer(GL_FRAMEBUFFER,
84 		GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, buffer);
85 
86 	status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
87 	if (status != GL_FRAMEBUFFER_COMPLETE) {
88 		fprintf(stderr, "error creating framebuffer, status 0x%x\n",
89 			status);
90 		return 0;
91 	}
92 	return fbo;
93 }
94 
95 static bool
read_depth(GLenum type,float expect)96 read_depth(GLenum type, float expect)
97 {
98 	GLfloat data;
99 	GLuint uint_pixel;
100 	if (type == GL_FLOAT) {
101 		glReadPixels(0, 0, 1, 1, GL_DEPTH_COMPONENT, type,
102 			(void *) &data);
103 	} else {
104 		glReadPixels(0, 0, 1, 1, GL_DEPTH_COMPONENT, type,
105 			(void *) &uint_pixel);
106 		uint_pixel = uint_pixel >> 8;
107 		data = (1.0 * ((float) uint_pixel)) / 16777215.0;
108 	}
109 
110 	if (!piglit_check_gl_error(GL_NO_ERROR))
111 		return false;
112 
113 	if (!equals(data, expect)) {
114 		fprintf(stderr, "expected %f, got %f\n", expect, data);
115 		return false;
116 	}
117 	return true;
118 }
119 
120 enum piglit_result
piglit_display(void)121 piglit_display(void)
122 {
123 	const float step = 0.1;
124 	unsigned j;
125 	float i;
126 
127 	glEnable(GL_DEPTH_TEST);
128 	glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
129 
130 	/* Loop through formats listed in 'tests'. */
131 	for (j = 0; j < ARRAY_SIZE(tests); j += 2) {
132 
133 		float expect = 0.0;
134 
135 		GLuint fbo = create_depth_fbo(tests[j]);
136 		if (!fbo)
137 			return PIGLIT_FAIL;
138 
139 		/* Step from -1.0 to 1.0, linear depth. Render a rectangle at
140 		 * depth i, read pixel and verify expected depth value.
141 		 */
142 		for (i = -1.0; !equals(i, 1.0 + step); i += step) {
143 
144 			glClear(GL_DEPTH_BUFFER_BIT);
145 			glUniform1f(glGetUniformLocation(prog, "depth"), i);
146 
147 			piglit_draw_rect(-1, -1, 2, 2);
148 
149 			if (!(read_depth(tests[j + 1], expect)))
150 				return PIGLIT_FAIL;
151 
152 			expect += step / 2.0;
153 		}
154 		glDeleteFramebuffers(1, &fbo);
155 	}
156 	return PIGLIT_PASS;
157 }
158 
159 void
piglit_init(int argc,char ** argv)160 piglit_init(int argc, char **argv)
161 {
162 	piglit_require_extension("GL_NV_read_depth");
163 	prog = piglit_build_simple_program(vs_source, fs_source);
164 	glUseProgram(prog);
165 }
166