[Piglit] [PATCH 3/3] fbo-depth-array: rewrite the test to make it really comprehensive
Marek Olšák
maraeo at gmail.com
Sat Aug 23 09:38:18 PDT 2014
From: Marek Olšák <marek.olsak at amd.com>
It tests:
- clearing
- layered clearing
- drawing
- drawing with a depth or stencil shader output
- various sizes of TEXTURE_2D_ARRAY
- texturing
with both depth and stencil.
---
tests/all.py | 8 +-
tests/fbo/fbo-depth-array.c | 513 ++++++++++++++++++++++++++++++++------------
2 files changed, 380 insertions(+), 141 deletions(-)
diff --git a/tests/all.py b/tests/all.py
index 20ebec2..5cc4d42 100644
--- a/tests/all.py
+++ b/tests/all.py
@@ -39,6 +39,9 @@ def add_single_param_test_set(group, name, *params):
def add_plain_test(group, args):
group[args] = plain_test(args)
+def add_plain_fbo_test(group, args):
+ group[args] = plain_test(args + ' -fbo')
+
def concurrent_test(args):
test = plain_test(args + ' -fbo')
test.run_concurrent = True
@@ -2782,7 +2785,10 @@ add_shader_test_dir(ext_texture_array,
add_msaa_visual_plain_tests(ext_texture_array, 'copyteximage 1D_ARRAY')
add_msaa_visual_plain_tests(ext_texture_array, 'copyteximage 2D_ARRAY')
add_plain_test(ext_texture_array, 'fbo-array')
-add_plain_test(ext_texture_array, 'fbo-depth-array')
+# no concurrency for these, they need a lot of memory
+for test in ('depth-clear', 'depth-layered-clear', 'depth-draw', 'fs-writes-depth',
+ 'stencil-clear', 'stencil-layered-clear', 'stencil-draw', 'fs-writes-stencil'):
+ add_plain_fbo_test(ext_texture_array, 'fbo-depth-array ' + test)
add_plain_test(ext_texture_array, 'array-texture')
add_concurrent_test(ext_texture_array, 'getteximage-targets 1D_ARRAY')
add_concurrent_test(ext_texture_array, 'getteximage-targets 2D_ARRAY')
diff --git a/tests/fbo/fbo-depth-array.c b/tests/fbo/fbo-depth-array.c
index c047057..884d7f6 100644
--- a/tests/fbo/fbo-depth-array.c
+++ b/tests/fbo/fbo-depth-array.c
@@ -2,6 +2,7 @@
* Copyright © 2009 Intel Corporation
* Copyright (c) 2010 VMware, Inc.
* Copyright © 2011 Red Hat Inc.
+ * Copyright © 2014 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -25,136 +26,324 @@
* Authors:
* Dave Airlie
* Christoph Bumiller
- *
+ * Marek Olšák <maraeo at gmail.com>
*/
/** @file fbo-depth-array.c
*
- * Tests that drawing to each level of a depth-only array texture FBO and then
- * drawing views of those individual depths to the window system framebuffer
- * succeeds.
+ * Tests that drawing to or clearing each layer of a depth-stencil array
+ * texture FBO and then drawing views of those individual layers
+ * to the window system framebuffer succeeds.
* based on fbo-array.c
*/
#include "piglit-util-gl.h"
-#define BUF_WIDTH 32
-#define BUF_HEIGHT 32
+enum {
+ CLEAR,
+ LAYERED_CLEAR,
+ DRAW,
+ FS_WRITES_VALUE,
+};
+
+static bool test_stencil;
+static bool test_single_size;
+static unsigned width = 32, height = 32, layers = 6;
+static unsigned test;
+
+static void parse_args(int argc, char **argv);
PIGLIT_GL_TEST_CONFIG_BEGIN
- config.supports_gl_compat_version = 10;
+ piglit_gl_process_args(&argc, argv, &config);
+ parse_args(argc, argv);
+
+ config.supports_gl_compat_version = 33;
+ config.supports_gl_core_version = 33;
- config.window_width = 200;
- config.window_height = 100;
+ if (piglit_use_fbo && !test_single_size) {
+ config.window_width = 8192;
+ config.window_height = 8192;
+ }
+ else {
+ config.window_width = (width + 2) * MIN2(layers, 3);
+ config.window_height = (height + 2) * ((layers + 2) / 3);
+ }
config.window_visual = PIGLIT_GL_VISUAL_DOUBLE | PIGLIT_GL_VISUAL_RGB;
PIGLIT_GL_TEST_CONFIG_END
-#define NUM_LAYERS 6
-
-float layer_depth[NUM_LAYERS][4] = {
- {0.1, 0.1, 0.1, 0.0},
- {0.2, 0.2, 0.2, 0.0},
- {0.4, 0.4, 0.4, 0.0},
- {0.6, 0.6, 0.6, 0.0},
- {0.8, 0.8, 0.8, 0.0},
- {1.0, 1.0, 1.0, 0.0},
-};
+static const char *vs_text =
+ "#version 330 \n"
+ "layout(location = 0) in vec4 piglit_vertex; \n"
+ "layout(location = 1) in vec4 piglit_texcoord; \n"
+ "out vec4 texcoord; \n"
+ "void main() { \n"
+ " gl_Position = piglit_vertex; \n"
+ " texcoord = piglit_texcoord; \n"
+ "}\n";
+
+static const char *frag_shader_empty_text =
+ "#version 330 \n"
+ "void main() {} \n";
+
+static const char *fs_depth_output_text =
+ "#version 330 \n"
+ "uniform float z; \n"
+ "void main() \n"
+ "{ \n"
+ " gl_FragDepth = z; \n"
+ "} \n";
+
+static const char *fs_stencil_output_text =
+ "#version 330 \n"
+ "#extension GL_ARB_shader_stencil_export : require \n"
+ "uniform int ref; \n"
+ "void main() \n"
+ "{ \n"
+ " gl_FragStencilRefARB = ref; \n"
+ "} \n";
+
+
+static const char *fs_texdepth_text =
+ "#version 330 \n"
+ "uniform sampler2DArray tex; \n"
+ "uniform float z; \n"
+ "in vec4 texcoord; \n"
+ "void main() \n"
+ "{ \n"
+ " gl_FragColor = texture(tex, vec3(texcoord.xy, z)).xxxx; \n"
+ "} \n";
+
+static const char *fs_texstencil_text =
+ "#version 330 \n"
+ "uniform usampler2DArray tex; \n"
+ "uniform float z; \n"
+ "in vec4 texcoord; \n"
+ "void main() \n"
+ "{ \n"
+ " gl_FragColor = vec4(float(texture(tex, vec3(texcoord.xy, z)))) / 255.0; \n"
+ "} \n";
+
+static GLuint program_fs_empty;
+static GLuint program_depth_output;
+static GLuint program_stencil_output;
+static GLuint program_texdepth;
+static GLuint program_texstencil;
-static int num_layers = NUM_LAYERS;
-static const char *prog = "fbo-depth-array";
-/* debug aid */
-static void
-check_error(int line)
+static float
+get_depth_value(unsigned layer)
{
- GLenum err = glGetError();
- if (err) {
- printf("%s: GL error 0x%x at line %d\n", prog, err, line);
- }
+ if (test == LAYERED_CLEAR)
+ return 0.4; /* constant */
+ else
+ return (double)(layer+1) / (layers+1);
}
-static const char *frag_shader_depth_output_text =
- "void main() \n"
- "{ \n"
- " gl_FragDepth = gl_Color.r;\n"
- "} \n";
-
-static GLuint frag_shader_depth_output;
-static GLuint program_depth_output;
-
-static const char *frag_shader_2d_array_text =
- "#extension GL_EXT_texture_array : enable \n"
- "uniform sampler2DArray tex; \n"
- "void main() \n"
- "{ \n"
- " gl_FragColor = texture2DArray(tex, gl_TexCoord[0].xyz).rrrr; \n"
- "} \n";
+static unsigned
+get_stencil_value(unsigned layer) {
+ if (test == LAYERED_CLEAR)
+ return 0x53;
+ else
+ return (layer+1) * 255 / (layers+1);
+}
-static GLuint frag_shader_2d_array;
-static GLuint program_2d_array;
+static float
+get_stencil_value_float(unsigned layer)
+{
+ return get_stencil_value(layer) / 255.0;
+}
+static void
+parse_args(int argc, char **argv)
+{
+ unsigned lwidth, lheight, llayers;
+ int i;
+
+ for (i = 1; i < argc; i++) {
+ if (sscanf(argv[i], "%ux%ux%u", &lwidth, &lheight, &llayers) == 3 &&
+ lwidth && lheight && llayers) {
+ width = lwidth;
+ height = lheight;
+ layers = llayers;
+ test_single_size = true;
+ }
+ else if (!strcmp(argv[i], "depth-clear")) {
+ test = CLEAR;
+ puts("Testing glClear");
+ }
+ else if (!strcmp(argv[i], "depth-layered-clear")) {
+ test = LAYERED_CLEAR;
+ puts("Testing layered glClear");
+ }
+ else if (!strcmp(argv[i], "depth-draw")) {
+ test = DRAW;
+ puts("Testing drawing");
+ }
+ else if (!strcmp(argv[i], "fs-writes-depth")) {
+ test = FS_WRITES_VALUE;
+ puts("Testing gl_FragDepth");
+ }
+ else if (!strcmp(argv[i], "stencil-clear")) {
+ test = CLEAR;
+ test_stencil = true;
+ puts("Testing stencil glClear");
+ }
+ else if (!strcmp(argv[i], "stencil-layered-clear")) {
+ test = LAYERED_CLEAR;
+ test_stencil = true;
+ puts("Testing stencil layered glClear");
+ }
+ else if (!strcmp(argv[i], "stencil-draw")) {
+ test = DRAW;
+ test_stencil = true;
+ puts("Testing stencil drawing");
+ }
+ else if (!strcmp(argv[i], "fs-writes-stencil")) {
+ test = FS_WRITES_VALUE;
+ test_stencil = true;
+ puts("Testing gl_FragStencilRef");
+ }
+ else {
+ puts("Invalid parameter.");
+ piglit_report_result(PIGLIT_FAIL);
+ }
+ }
+}
-static int
+static GLuint
create_array_fbo(void)
{
- GLuint tex, fb;
+ GLuint tex, fb, z, ref;
GLenum status;
int layer;
- glUseProgram(program_depth_output);
-
glGenTextures(1, &tex);
- glBindTexture(GL_TEXTURE_2D_ARRAY_EXT, tex);
+ glBindTexture(GL_TEXTURE_2D_ARRAY, tex);
assert(glGetError() == 0);
/* allocate empty array texture */
- glTexImage3D(GL_TEXTURE_2D_ARRAY_EXT, 0, GL_DEPTH_COMPONENT24,
- BUF_WIDTH, BUF_HEIGHT, num_layers,
- 0,
- GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NULL);
+ glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_DEPTH24_STENCIL8,
+ width, height, layers, 0,
+ GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, NULL);
assert(glGetError() == 0);
- glGenFramebuffersEXT(1, &fb);
- glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb);
+ glGenFramebuffers(1, &fb);
+ glBindFramebuffer(GL_FRAMEBUFFER, fb);
glDrawBuffer(GL_NONE);
glReadBuffer(GL_NONE);
/* draw something into each layer of the array texture */
- for (layer = 0; layer < NUM_LAYERS; layer++) {
- glFramebufferTextureLayer(GL_FRAMEBUFFER_EXT,
- GL_DEPTH_ATTACHMENT,
+ for (layer = 0; layer < layers; layer++) {
+ if (test == LAYERED_CLEAR) {
+ glFramebufferTexture(GL_FRAMEBUFFER,
+ test_stencil ? GL_STENCIL_ATTACHMENT :
+ GL_DEPTH_ATTACHMENT,
+ tex, 0);
+
+ status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
+ if (status != GL_FRAMEBUFFER_COMPLETE) {
+ fprintf(stderr, "FBO incomplete\n");
+ goto done;
+ }
+
+ glViewport(0, 0, width, height);
+ if (test_stencil) {
+ glClearStencil(get_stencil_value(0));
+ glClear(GL_STENCIL_BUFFER_BIT);
+ }
+ else {
+ glClearDepth(get_depth_value(0));
+ glClear(GL_DEPTH_BUFFER_BIT);
+ }
+ break;
+ }
+ glFramebufferTextureLayer(GL_FRAMEBUFFER,
+ test_stencil ? GL_STENCIL_ATTACHMENT :
+ GL_DEPTH_ATTACHMENT,
tex,
0,
layer);
assert(glGetError() == 0);
- status = glCheckFramebufferStatusEXT (GL_FRAMEBUFFER_EXT);
- if (status != GL_FRAMEBUFFER_COMPLETE_EXT) {
+ status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
+ if (status != GL_FRAMEBUFFER_COMPLETE) {
fprintf(stderr, "FBO incomplete\n");
goto done;
}
- glViewport(0, 0, BUF_WIDTH, BUF_HEIGHT);
- piglit_ortho_projection(BUF_WIDTH, BUF_HEIGHT, GL_FALSE);
-
- glEnable(GL_DEPTH_TEST);
- glDepthFunc(GL_ALWAYS);
-
- /* solid color quad */
- glColor4fv(layer_depth[layer]);
- piglit_draw_rect(-2, -2, BUF_WIDTH + 2, BUF_HEIGHT + 2);
-
- glDisable(GL_DEPTH_TEST);
+ glViewport(0, 0, width, height);
+
+ switch (test) {
+ case CLEAR:
+ if (test_stencil) {
+ glClearStencil(get_stencil_value(layer));
+ glClear(GL_STENCIL_BUFFER_BIT);
+ }
+ else {
+ glClearDepth(get_depth_value(layer));
+ glClear(GL_DEPTH_BUFFER_BIT);
+ }
+ break;
+ case DRAW:
+ glUseProgram(program_fs_empty);
+ if (test_stencil) {
+ glEnable(GL_STENCIL_TEST);
+ glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
+ glStencilFunc(GL_ALWAYS, get_stencil_value(layer), 0xff);
+
+ piglit_draw_rect(-1, -1, 2, 2);
+
+ glDisable(GL_STENCIL_TEST);
+ }
+ else {
+ glEnable(GL_DEPTH_TEST);
+ glDepthFunc(GL_ALWAYS);
+
+ piglit_draw_rect_z(get_depth_value(layer) * 2 - 1,
+ -1, -1, 2, 2);
+
+ glDisable(GL_DEPTH_TEST);
+ }
+ glUseProgram(0);
+ break;
+ case FS_WRITES_VALUE:
+ if (test_stencil) {
+ glUseProgram(program_stencil_output);
+ ref = glGetUniformLocation(program_stencil_output, "ref");
+ glUniform1i(ref, get_stencil_value(layer));
+
+ glEnable(GL_STENCIL_TEST);
+ glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
+ glStencilFunc(GL_ALWAYS, 0, 0xff);
+
+ piglit_draw_rect(-1, -1, 2, 2);
+
+ glDisable(GL_STENCIL_TEST);
+ }
+ else {
+ glUseProgram(program_depth_output);
+ z = glGetUniformLocation(program_depth_output, "z");
+ glUniform1f(z, get_depth_value(layer));
+
+ glEnable(GL_DEPTH_TEST);
+ glDepthFunc(GL_ALWAYS);
+
+ piglit_draw_rect(-1, -1, 2, 2);
+
+ glDisable(GL_DEPTH_TEST);
+ }
+ glUseProgram(0);
+ break;
+ }
}
- glUseProgram(0);
-
done:
- glDeleteFramebuffersEXT(1, &fb);
+ glDeleteFramebuffers(1, &fb);
+ assert(glGetError() == 0);
return tex;
}
@@ -165,73 +354,107 @@ static void
draw_layer(int x, int y, int depth)
{
GLfloat depth_coord = (GLfloat)depth;
- GLint loc;
+ GLuint prog = test_stencil ? program_texstencil : program_texdepth;
+ GLint loc, z;
- glUseProgram(program_2d_array);
- loc = glGetUniformLocation(program_2d_array, "tex");
+ glUseProgram(prog);
+ loc = glGetUniformLocation(prog, "tex");
+ z = glGetUniformLocation(prog, "z");
glUniform1i(loc, 0); /* texture unit p */
+ glUniform1f(z, depth_coord);
glViewport(0, 0, piglit_width, piglit_height);
- piglit_ortho_projection(piglit_width, piglit_height, GL_FALSE);
-
- glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, piglit_winsys_fbo);
-
- glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
- glTexParameteri(GL_TEXTURE_2D_ARRAY_EXT, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D_ARRAY_EXT, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D_ARRAY_EXT, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_2D_ARRAY_EXT, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_2D_ARRAY_EXT, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
- glBegin(GL_QUADS);
-
- glTexCoord3f(0, 0, depth_coord);
- glVertex2f(x, y);
-
- glTexCoord3f(1, 0, depth_coord);
- glVertex2f(x + BUF_WIDTH, y);
-
- glTexCoord3f(1, 1, depth_coord);
- glVertex2f(x + BUF_WIDTH, y + BUF_HEIGHT);
-
- glTexCoord3f(0, 1, depth_coord);
- glVertex2f(x, y + BUF_HEIGHT);
-
- glEnd();
-
+ glBindFramebuffer(GL_FRAMEBUFFER, piglit_winsys_fbo);
+
+ glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
+ glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
+ glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_BORDER);
+ if (test_stencil)
+ glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_DEPTH_STENCIL_TEXTURE_MODE,
+ GL_STENCIL_INDEX);
+
+ piglit_draw_rect_tex((double)x / piglit_width * 2 - 1,
+ (double)y / piglit_height * 2 - 1,
+ (double)width / piglit_width * 2,
+ (double)height / piglit_height * 2,
+ 0, 0, 1, 1);
glUseProgram(0);
+ assert(glGetError() == 0);
}
-static GLboolean test_layer_drawing(int start_x, int start_y, float *expected)
+static GLboolean test_layer_drawing(int start_x, int start_y, float expected)
{
- return piglit_probe_rect_rgb(start_x, start_y, BUF_WIDTH, BUF_HEIGHT,
- expected);
+ return piglit_probe_rect_r_ubyte(start_x, start_y, width, height,
+ expected * 255.0);
}
-enum piglit_result
-piglit_display(void)
+static bool
+test_once(void)
{
- GLboolean pass = GL_TRUE;
+ bool pass = true;
int layer;
GLuint tex;
- glClearColor(1.0, 1.0, 1.0, 1.0);
+ printf("Testing %ix%ix%i\n", width, height, layers);
+
+ glClearColor(0.2, 0.1, 0.1, 1.0);
glClear(GL_COLOR_BUFFER_BIT);
tex = create_array_fbo();
- for (layer = 0; layer < NUM_LAYERS; layer++) {
- int x = 1 + layer * (BUF_WIDTH + 1);
- int y = 1;
+ for (layer = 0; layer < layers; layer++) {
+ int x,y;
+
+ if (piglit_use_fbo && !test_single_size) {
+ x = 0;
+ y = 0;
+ }
+ else {
+ x = 1 + (layer % 3) * (width + 1);
+ y = 1 + (layer / 3) * (height + 1);
+ }
draw_layer(x, y, layer);
- }
- for (layer = 0; layer < NUM_LAYERS; layer++) {
- int x = 1 + layer * (BUF_WIDTH + 1);
- int y = 1;
- pass &= test_layer_drawing(x, y, layer_depth[layer]);
+ pass &= test_layer_drawing(x, y,
+ test_stencil ?
+ get_stencil_value_float(layer) :
+ get_depth_value(layer));
+
+ if (piglit_use_fbo && !test_single_size && layer < layers-1) {
+ glClearColor(0.2, 0.1, 0.1, 1.0);
+ glClear(GL_COLOR_BUFFER_BIT);
+ }
}
glDeleteTextures(1, &tex);
+ assert(glGetError() == 0);
+ return pass;
+}
+
+enum piglit_result
+piglit_display(void)
+{
+ bool pass = true;
+ int i,j;
+
+ if (piglit_use_fbo && !test_single_size) {
+ for (i = 16; i <= 8192; i <<= 1) {
+ for (j = 16; j <= 8192; j <<= 1) {
+ /* Don't allocate too much texture memory. */
+ if (i*j > 2048*1024)
+ continue;
+
+ width = i;
+ height = j;
+ pass = test_once() && pass;
+ }
+ }
+ }
+ else {
+ pass = test_once() && pass;
+ }
piglit_present_results();
@@ -240,24 +463,34 @@ piglit_display(void)
void piglit_init(int argc, char **argv)
{
- piglit_require_extension("GL_EXT_framebuffer_object");
- piglit_require_extension("GL_EXT_texture_array");
-
- /* Make shader programs */
- frag_shader_2d_array =
- piglit_compile_shader_text(GL_FRAGMENT_SHADER,
- frag_shader_2d_array_text);
- check_error(__LINE__);
-
- frag_shader_depth_output =
- piglit_compile_shader_text(GL_FRAGMENT_SHADER,
- frag_shader_depth_output_text);
- check_error(__LINE__);
-
- program_2d_array = piglit_link_simple_program(0, frag_shader_2d_array);
- check_error(__LINE__);
-
- program_depth_output = piglit_link_simple_program(0,
- frag_shader_depth_output);
- check_error(__LINE__);
+ if (piglit_get_gl_version() < 33) {
+ piglit_report_result(PIGLIT_SKIP);
+ }
+
+ if (test_stencil) {
+ piglit_require_extension("GL_ARB_stencil_texturing");
+ if (test == FS_WRITES_VALUE)
+ piglit_require_extension("GL_ARB_shader_stencil_export");
+ }
+
+ if (test_stencil) {
+ program_texstencil = piglit_build_simple_program(vs_text,
+ fs_texstencil_text);
+
+ if (test == FS_WRITES_VALUE)
+ program_stencil_output = piglit_build_simple_program(vs_text,
+ fs_stencil_output_text);
+ }
+ else {
+ program_texdepth = piglit_build_simple_program(vs_text,
+ fs_texdepth_text);
+
+ if (test == FS_WRITES_VALUE)
+ program_depth_output = piglit_build_simple_program(vs_text,
+ fs_depth_output_text);
+ }
+
+ program_fs_empty = piglit_build_simple_program(vs_text,
+ frag_shader_empty_text);
+ assert(glGetError() == 0);
}
--
1.9.1
More information about the Piglit
mailing list