[Piglit] [PATCH 14/16] namespace-pollution: Add vertex program as an object to test
Ian Romanick
idr at freedesktop.org
Wed Jan 6 16:53:14 PST 2016
From: Ian Romanick <ian.d.romanick at intel.com>
NOTE: The following tests fail on i965 (and presumably other drivers
that use meta) on Mesa master and 11.1:
program with gldrawpixels
Signed-off-by: Ian Romanick <ian.d.romanick at intel.com>
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=92363
---
tests/all.py | 2 +-
tests/general/object-namespace-pollution.c | 213 +++++++++++++++++++++++++++++
2 files changed, 214 insertions(+), 1 deletion(-)
diff --git a/tests/all.py b/tests/all.py
index e477cd8..9169699 100644
--- a/tests/all.py
+++ b/tests/all.py
@@ -4608,7 +4608,7 @@ with profile.group_manager(
with profile.group_manager(
PiglitGLTest,
grouptools.join('object namespace pollution')) as g:
- for object_type in ("buffer", "framebuffer", "renderbuffer", "texture"):
+ for object_type in ("buffer", "framebuffer", "program", "renderbuffer", "texture"):
for operation in ("glBitmap", "glBlitFramebuffer", "glClear", "glClearTexSubImage", "glCopyImageSubData", "glCopyPixels", "glCopyTexSubImage2D", "glDrawPixels", "glGenerateMipmap", "glGetTexImage", "glGetTexImage-compressed", "glTexSubImage2D"):
g(['object-namespace-pollution', operation, object_type],
'{} with {}'.format(object_type, operation))
diff --git a/tests/general/object-namespace-pollution.c b/tests/general/object-namespace-pollution.c
index 1073b65..f99328a 100644
--- a/tests/general/object-namespace-pollution.c
+++ b/tests/general/object-namespace-pollution.c
@@ -353,6 +353,218 @@ validate_framebuffer(unsigned name)
}
/*@}*/
+/** \name Methods for operating on vertex or fragment program objects */
+/*@{*/
+static char *
+generate_program_source(GLenum target, unsigned key)
+{
+ char *source = NULL;
+
+ if (target == GL_VERTEX_PROGRAM_ARB) {
+ const char *position;
+ const char *normal;
+ const char *other;
+ const char *mvp;
+ const char *mv_invtrans;
+
+ if ((key & 2) != 0) {
+ mvp = "state.matrix.mvp";
+ position =
+ "DP4 p.x, mvp[0], vp;\n"
+ "DP4 p.y, mvp[1], vp;\n"
+ "DP4 p.z, mvp[2], vp;\n"
+ "DP4 p.w, mvp[3], vp;\n"
+ ;
+ } else {
+ mvp = "state.matrix.mvp.transpose";
+ position =
+ "MUL r0, mvp[0], vp.xxxx;\n"
+ "MAD r0, mvp[1], vp.yyyy, r0;\n"
+ "MAD r0, mvp[2], vp.zzzz, r0;\n"
+ "MAD r0, mvp[3], vp.wwww, r0;\n"
+ "MOV p, r0;\n"
+ ;
+ }
+
+ if ((key & 4) != 0) {
+ mv_invtrans = "state.matrix.modelview.invtrans";
+ normal =
+ "DP3 n.x, mv_invtrans[0], vn;\n"
+ "DP3 n.y, mv_invtrans[1], vn;\n"
+ "DP3 n.z, mv_invtrans[2], vn;\n"
+ ;
+ } else {
+ mv_invtrans = "state.matrix.modelview.inverse";
+ normal =
+ "MUL r0.xyz, mv_invtrans[0], vn;\n"
+ "MAD r0.xyz, mv_invtrans[1], vn, r0;\n"
+ "MAD r0.xyz, mv_invtrans[2], vn, r0;\n"
+ "SWZ n, r0, x, y, z, 0;\n"
+ ;
+ }
+
+ if ((key & 8) != 0) {
+ other =
+ "# Output the color\n"
+ "MOV t, vertex.color;\n"
+ ;
+ } else {
+ other =
+ "# Output the texture coordinate\n"
+ "MOV t, vertex.texcoord[0];\n"
+ ;
+ }
+
+ asprintf(&source,
+ "!!ARBvp1.0\n"
+ "# Program key 0x%04x\n"
+ "ATTRIB vp = vertex.position;\n"
+ "ATTRIB vn = vertex.normal;\n"
+ "PARAM mvp[4] = { %s.row[0..3] };\n"
+ "PARAM mv_invtrans[3] = { %s.row[0..2] };\n"
+ "OUTPUT p = result.position;\n"
+ "OUTPUT n = result.texcoord[0];\n"
+ "OUTPUT t = result.texcoord[1];\n"
+ "TEMP r0;\n"
+ "\n"
+ "# Transform the vertex to clip coordinates.\n"
+ "%s"
+ "\n"
+ "# Transform the normal to eye coordinates.\n"
+ "%s"
+ "\n"
+ "%s"
+ "END",
+ key,
+ mvp,
+ mv_invtrans,
+ position,
+ normal,
+ other);
+ } else {
+ printf("Unknown program target %s (0x%04x) in %s.\n",
+ piglit_get_gl_enum_name(target), target,
+ __func__);
+ piglit_report_result(PIGLIT_FAIL);
+ }
+
+ return source;
+}
+
+/**
+ * Selects a program target based on the key and the supported extensions.
+ */
+static GLenum
+select_program_target(unsigned key)
+{
+ GLenum target = 0;
+
+ (void) key;
+
+ if (piglit_is_extension_supported("GL_ARB_vertex_program")) {
+ target = GL_VERTEX_PROGRAM_ARB;
+ }
+
+ return target;
+}
+
+static bool
+create_program(unsigned name, bool silent_skip)
+{
+ char *source;
+ const GLenum target = select_program_target(name);
+
+ if (target == 0) {
+ if (silent_skip)
+ return true;
+
+ printf("%s requires GL_ARB_vertex_program.\n", __func__);
+ piglit_report_result(PIGLIT_SKIP);
+ }
+
+ if (glIsProgramARB(name)) {
+ printf("\t%s,%d: %u is already a program\n",
+ __func__, __LINE__, name);
+ return false;
+ }
+
+ glBindProgramARB(target, name);
+
+ source = generate_program_source(target, name);
+ glProgramStringARB(target, GL_PROGRAM_FORMAT_ASCII_ARB,
+ strlen(source), source);
+
+ free(source);
+
+ glBindProgramARB(target, 0);
+
+ return piglit_check_gl_error(GL_NO_ERROR);
+}
+
+static bool
+validate_program(unsigned name)
+{
+ bool pass = true;
+ const GLenum target = select_program_target(name);
+ char *expected = generate_program_source(target, name);
+ const int expected_length = strlen(expected);
+ char *got;
+ GLint length;
+
+ if (!glIsProgramARB(name)) {
+ printf("\t%s,%d: %u is not a program\n",
+ __func__, __LINE__, name);
+ return false;
+ }
+
+ glBindProgramARB(target, name);
+
+ /* The GL_ARB_vertex_program spec does not say whether or not length
+ * includes a terminating NUL. It says:
+ *
+ * "If <pname> is PROGRAM_LENGTH_ARB ... GetProgramivARB returns
+ * one integer holding the program string length (in bytes)
+ * ... for the program object currently bound to <target>."
+ *
+ * and, with respect to glGetProgramStringARB it says:
+ *
+ * "<n> ubytes are returned into the array program where <n> is
+ * the length of the program in ubytes, as returned by
+ * GetProgramivARB when <pname> is PROGRAM_LENGTH_ARB."
+ */
+ glGetProgramivARB(target,
+ GL_PROGRAM_LENGTH_ARB,
+ &length);
+ if (length != expected_length && length != (expected_length + 1)) {
+ printf("\t%s,%d: Program %u length invalid: got %d, expected "
+ "%d or %d.\n",
+ __func__, __LINE__,
+ name,
+ length, expected_length, expected_length + 1);
+ pass = false;
+ }
+
+ got = calloc(length, sizeof(char));
+ glGetProgramStringARB(target,
+ GL_PROGRAM_STRING_ARB,
+ got);
+
+ if (memcmp(expected, got, expected_length) != 0) {
+ printf("\t%s,%d: %u source mismatch\n",
+ __func__, __LINE__,
+ name);
+ pass = false;
+ }
+
+ free(got);
+ free(expected);
+
+ glBindProgramARB(target, 0);
+
+ return piglit_check_gl_error(GL_NO_ERROR) && pass;
+}
+/*@}*/
+
/** \name Methods for operating on renderbuffer objects */
/*@{*/
static bool
@@ -1049,6 +1261,7 @@ static const struct {
} object_types[] = {
{ "buffer", create_buffer, validate_buffer },
{ "framebuffer", create_framebuffer, validate_framebuffer },
+ { "program", create_program, validate_program },
{ "renderbuffer", create_renderbuffer, validate_renderbuffer },
{ "texture", create_texture, validate_texture },
};
--
2.5.0
More information about the Piglit
mailing list