[Piglit] [PATCH 04/15] adj-prims: beef up the test to tease out what nvidia hardware does
Marek Olšák
maraeo at gmail.com
Mon Mar 26 23:32:44 UTC 2018
From: Nicolai Hähnle <nicolai.haehnle at amd.com>
---
tests/spec/gl-3.2/adj-prims.c | 144 +++++++++++++++++++++++++++++++++++++-----
1 file changed, 128 insertions(+), 16 deletions(-)
diff --git a/tests/spec/gl-3.2/adj-prims.c b/tests/spec/gl-3.2/adj-prims.c
index f4479c708..6faff74d2 100644
--- a/tests/spec/gl-3.2/adj-prims.c
+++ b/tests/spec/gl-3.2/adj-prims.c
@@ -135,25 +135,28 @@ static GLuint triangles_adj_vao;
static GLuint triangle_strip_adj_vao;
static GLenum polygon_mode = GL_FILL;
static GLenum cull_mode = GL_NONE;
static GLenum provoking_vertex = GL_LAST_VERTEX_CONVENTION;
static GLuint gs_lines_program;
static GLuint gs_line_strip_program;
static GLuint gs_triangles_program;
static GLuint gs_triangle_strip_program;
+static GLuint xfb_buf;
+static GLuint element_buf;
static GLuint ref_program;
static GLint colorUniform, modelViewProjUniform;
// if false, draw without GS, also draw the 'extra' lines/tris. For debugging.
static bool draw_with_gs = true;
+static bool draw_elements = false;
/**
* Given a primitive type (adjacency type only), and the first/last provoking
* vertex mode, and a primitive (line, triangle) index, return the index of
* the vertex which will specify the primitive's flat-shaded color.
*/
static unsigned
provoking_vertex_index(GLenum prim_mode, GLenum pv_mode, unsigned prim_index)
{
@@ -304,42 +307,47 @@ num_gs_prims(GLenum prim_mode, unsigned num_verts)
static bool
probe_prims(GLenum prim_mode, const float verts[][2], unsigned num_verts,
unsigned vp_pos)
{
const int vp_w = piglit_width / 4;
const unsigned num_prims = num_gs_prims(prim_mode, num_verts);
unsigned prim;
for (prim = 0; prim < num_prims; prim++) {
bool pass = false;
- const float *expected_color = NULL;
- float bad_color[4];
+ float expected_color[4];
+ float bad_color[4] = { -1 };
bool bad_color_found = false;
int x, y, i;
compute_probe_location(prim_mode, prim, verts,
vp_pos * vp_w, 0, &x, &y);
if (cull_mode == GL_FRONT &&
(prim_mode == GL_TRIANGLES_ADJACENCY ||
prim_mode == GL_TRIANGLE_STRIP_ADJACENCY)) {
// All triangles should be front facing.
// With front culling, all should be discarded.
// Region should be black.
if (piglit_probe_rect_rgba(x-1, y-1, 3, 3, black)) {
pass = true;
}
} else {
GLfloat buf[9][4];
unsigned pvi = provoking_vertex_index(prim_mode,
provoking_vertex, prim);
- expected_color = colors[pvi];
+ memcpy(&expected_color, colors[pvi], sizeof(expected_color));
+ if (prim_mode == GL_TRIANGLES_ADJACENCY ||
+ prim_mode == GL_TRIANGLE_STRIP_ADJACENCY) {
+ expected_color[2] = pvi * (1.0 / 255);
+ expected_color[3] = provoking_vertex == GL_FIRST_VERTEX_CONVENTION ? 0.0 : 1.0;
+ }
// Read a 3x3 region for line probing
glReadPixels(x-1, y-1, 3, 3, GL_RGBA, GL_FLOAT, buf);
// look for non-black pixel
for (i = 0; i < 9; i++) {
if (buf[i][0] != 0 || buf[i][1] != 0 ||
buf[i][2] != 0 || buf[i][3] != 0) {
// check for expected color
if (colors_match(expected_color, buf[i]))
@@ -352,57 +360,100 @@ probe_prims(GLenum prim_mode, const float verts[][2], unsigned num_verts,
bad_color[3] = buf[i][3];
}
}
}
}
if (!pass) {
printf("Failure for %s, "
"prim %u wrong color at (%d,%d)\n",
piglit_get_prim_name(prim_mode), prim, x, y);
- if (expected_color && bad_color_found) {
- printf("Expected %.1g, %.1g, %.1g, %.1g\n",
+ if (bad_color_found) {
+ printf("Expected %g, %g, %g, %g\n",
expected_color[0],
expected_color[1],
expected_color[2],
expected_color[3]);
- printf("Found %.1g, %.1g, %.1g, %.1g\n",
+ printf("Found %g, %g, %g, %g\n",
bad_color[0],
bad_color[1],
bad_color[2],
bad_color[3]);
}
return false;
}
}
return true;
}
+static bool
+probe_xfb(GLenum prim_mode, unsigned num_verts)
+{
+ bool pass = true;
+ const unsigned num_prims = num_gs_prims(prim_mode, num_verts);
+ const float *xfb_data = glMapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, GL_READ_ONLY);
+
+ for (unsigned prim = 0; prim < num_prims; prim++) {
+ const float *found_color;
+ float expected_color[4];
+ unsigned pvi = provoking_vertex_index(prim_mode,
+ provoking_vertex, prim);
+
+ memcpy(&expected_color, colors[pvi], sizeof(expected_color));
+ expected_color[2] = pvi * (1.0 / 255);
+ expected_color[3] = provoking_vertex == GL_FIRST_VERTEX_CONVENTION ? 0.0 : 1.0;
+
+ found_color = xfb_data + 4 * (3 * prim + (provoking_vertex == GL_FIRST_VERTEX_CONVENTION ? 0 : 2));
+
+ if (!colors_match(expected_color, found_color)) {
+ printf("Transform Feedback Failure for %s, prim %u wrong color\n",
+ piglit_get_prim_name(prim_mode), prim);
+ printf("Expected %g, %g, %g, %g\n",
+ expected_color[0],
+ expected_color[1],
+ expected_color[2],
+ expected_color[3]);
+ printf("Found %g, %g, %g, %g\n",
+ found_color[0],
+ found_color[1],
+ found_color[2],
+ found_color[3]);
+
+ pass = false;
+ }
+ }
+
+ glUnmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);
+
+ return pass;
+}
static GLuint
make_gs_program(GLenum input_prim)
{
static const char *vs_text =
"#version 150 \n"
"in vec4 vertex; \n"
"in vec4 color; \n"
"uniform mat4 modelViewProj; \n"
"out vec4 pos;\n"
"out vec4 vs_gs_color; \n"
+ "out int vs_gs_vertex_id; \n"
"void main() \n"
"{ \n"
" gl_Position = vertex * modelViewProj; \n"
" pos = vertex * modelViewProj; \n"
" vs_gs_color = color; \n"
+ " vs_gs_vertex_id = gl_VertexID; \n"
"} \n";
static const char *gs_text_lines =
"#version 150 \n"
"layout(lines_adjacency) in;\n"
"layout(line_strip, max_vertices = 2) out;\n"
"in vec4 pos[]; \n"
"in vec4 vs_gs_color[4]; \n"
"flat out vec4 gs_fs_color; \n"
"void main() \n"
"{ \n"
@@ -413,41 +464,49 @@ make_gs_program(GLenum input_prim)
" gl_Position = pos[2]; \n"
" EmitVertex(); \n"
" EndPrimitive(); \n"
"} \n";
static const char *gs_text_triangles =
"#version 150 \n"
"layout(triangles_adjacency) in;\n"
"layout(triangle_strip, max_vertices = 3) out;\n"
"in vec4 pos[]; \n"
"in vec4 vs_gs_color[6]; \n"
+ "in int vs_gs_vertex_id[6]; \n"
"flat out vec4 gs_fs_color; \n"
"void main() \n"
"{ \n"
" gs_fs_color = vs_gs_color[0]; \n"
+ " gs_fs_color.b = vs_gs_vertex_id[0] * (1. / 255.); \n"
+ " gs_fs_color.a = 0.0; \n"
" gl_Position = pos[0]; \n"
" EmitVertex(); \n"
" gs_fs_color = vs_gs_color[2]; \n"
+ " gs_fs_color.b = vs_gs_vertex_id[2] * (1. / 255.); \n"
+ " gs_fs_color.a = 0.5; \n"
" gl_Position = pos[2]; \n"
" EmitVertex(); \n"
" gs_fs_color = vs_gs_color[4]; \n"
+ " gs_fs_color.b = vs_gs_vertex_id[4] * (1. / 255.); \n"
+ " gs_fs_color.a = 1.0; \n"
" gl_Position = pos[4]; \n"
" EmitVertex(); \n"
" //EndPrimitive(); \n"
"} \n";
static const char *fs_text =
"#version 150 \n"
"flat in vec4 gs_fs_color; \n"
"void main() \n"
"{ \n"
" gl_FragColor = gs_fs_color; \n"
"} \n";
+ static const char *gs_xfb_varyings[] = { "gs_fs_color" };
const char *gs_text;
GLuint program;
switch (input_prim) {
case GL_LINES_ADJACENCY:
case GL_LINE_STRIP_ADJACENCY:
gs_text = gs_text_lines;
break;
case GL_TRIANGLES_ADJACENCY:
case GL_TRIANGLE_STRIP_ADJACENCY:
@@ -462,20 +521,23 @@ make_gs_program(GLenum input_prim)
GL_VERTEX_SHADER, vs_text,
GL_GEOMETRY_SHADER, gs_text,
GL_FRAGMENT_SHADER, fs_text,
0);
assert(program);
glBindAttribLocation(program, 0, "vertex");
glBindAttribLocation(program, 1, "color");
+ glTransformFeedbackVaryings(program, 1, &gs_xfb_varyings[0],
+ GL_INTERLEAVED_ATTRIBS);
+
glLinkProgram(program);
return program;
}
static GLuint
make_ref_program(void)
{
static const char *vs_text =
@@ -661,51 +723,96 @@ use_program(GLuint program)
static void
set_viewport(unsigned pos)
{
int vp_w = piglit_width / 4;
assert(pos < 4);
glViewport(pos * vp_w, 0, vp_w, piglit_height);
}
+static void
+draw_gs_triangles(GLenum prim_mode, GLuint vao, unsigned num_verts,
+ unsigned vp_pos)
+{
+ size_t buffer_size;
+ void *zeros;
+
+ use_program(gs_triangles_program);
+ set_viewport(vp_pos);
+ glBindVertexArray(vao);
+
+ buffer_size =
+ 12 * sizeof(float) *
+ num_gs_prims(prim_mode, num_verts);
+ zeros = calloc(1, buffer_size);
+
+ glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, xfb_buf);
+ glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, buffer_size,
+ zeros, GL_STREAM_READ);
+
+ free(zeros);
+
+ glBeginTransformFeedback(GL_TRIANGLES);
+
+ if (draw_elements) {
+ GLushort* elements;
+
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, element_buf);
+ glBufferData(GL_ELEMENT_ARRAY_BUFFER,
+ sizeof(GLushort) * num_verts, NULL,
+ GL_STATIC_DRAW);
+ elements = glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_WRITE_ONLY);
+ for (unsigned i = 0; i < num_verts; i++) {
+ elements[i] = i;
+ }
+ glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER);
+
+ glDrawElements(prim_mode, num_verts, GL_UNSIGNED_SHORT, NULL);
+ } else {
+ glDrawArrays(prim_mode, 0, num_verts);
+ }
+
+ glEndTransformFeedback();
+}
+
enum piglit_result
piglit_display(void)
{
bool pass = true;
glClear(GL_COLOR_BUFFER_BIT);
if (draw_with_gs) {
use_program(gs_lines_program);
set_viewport(0);
glBindVertexArray(lines_adj_vao);
glDrawArrays(GL_LINES_ADJACENCY, 0,
NUM_VERTS(lines_adj_verts));
use_program(gs_line_strip_program);
set_viewport(1);
glBindVertexArray(line_strip_adj_vao);
glDrawArrays(GL_LINE_STRIP_ADJACENCY, 0,
NUM_VERTS(line_strip_adj_verts));
- use_program(gs_triangles_program);
- set_viewport(2);
- glBindVertexArray(triangles_adj_vao);
- glDrawArrays(GL_TRIANGLES_ADJACENCY, 0,
- NUM_VERTS(triangles_adj_verts));
+ draw_gs_triangles(GL_TRIANGLES_ADJACENCY, triangles_adj_vao,
+ NUM_VERTS(triangles_adj_verts), 2);
- use_program(gs_triangle_strip_program);
- set_viewport(3);
- glBindVertexArray(triangle_strip_adj_vao);
- glDrawArrays(GL_TRIANGLE_STRIP_ADJACENCY, 0,
- NUM_VERTS(triangle_strip_adj_verts));
+ pass = probe_xfb(GL_TRIANGLES_ADJACENCY,
+ NUM_VERTS(triangles_adj_verts)) && pass;
+
+ draw_gs_triangles(GL_TRIANGLE_STRIP_ADJACENCY, triangle_strip_adj_vao,
+ NUM_VERTS(triangle_strip_adj_verts), 3);
+
+ pass = probe_xfb(GL_TRIANGLE_STRIP_ADJACENCY,
+ NUM_VERTS(triangle_strip_adj_verts)) && pass;
}
else {
/* This path is basically for debugging and visualizing the
* "extra" lines and tris in adjacency primitives.
*/
use_program(ref_program);
set_viewport(0);
draw_lines_adj(lines_adj_vao, 8);
@@ -780,32 +887,37 @@ piglit_init(int argc, char **argv)
else if (strcmp(argv[i], "cull-back") == 0)
cull_mode = GL_BACK;
else if (strcmp(argv[i], "cull-front") == 0)
cull_mode = GL_FRONT;
else if (strcmp(argv[i], "ref") == 0)
draw_with_gs = GL_FALSE;
else if (strcmp(argv[i], "pv-last") == 0)
provoking_vertex = GL_LAST_VERTEX_CONVENTION;
else if (strcmp(argv[i], "pv-first") == 0)
provoking_vertex = GL_FIRST_VERTEX_CONVENTION;
+ else if (strcmp(argv[i], "elements") == 0)
+ draw_elements = true;
else
printf("Unexpected %s argument\n", argv[i]);
}
glPolygonMode(GL_FRONT_AND_BACK, polygon_mode);
if (cull_mode != GL_NONE) {
glCullFace(cull_mode);
glEnable(GL_CULL_FACE);
glFrontFace(GL_CW);
}
glProvokingVertex(provoking_vertex);
+ glGenBuffers(1, &xfb_buf);
+ glGenBuffers(1, &element_buf);
+
lines_adj_vao = create_vao(lines_adj_verts,
NUM_VERTS(lines_adj_verts));
line_strip_adj_vao = create_vao(line_strip_adj_verts,
NUM_VERTS(line_strip_adj_verts));
triangles_adj_vao = create_vao(triangles_adj_verts,
NUM_VERTS(triangles_adj_verts));
triangle_strip_adj_vao = create_vao(triangle_strip_adj_verts,
--
2.15.1
More information about the Piglit
mailing list