gallium/util: add a test for TGSI_PROPERTY_VS_WINDOW_SPACE_POSITION
authorMarek Olšák <marek.olsak@amd.com>
Sat, 8 Nov 2014 15:48:33 +0000 (16:48 +0100)
committerMarek Olšák <marek.olsak@amd.com>
Sun, 16 Nov 2014 00:28:26 +0000 (01:28 +0100)
Not testable by OpenGL. Required by Nine.

This is an example of how to implement a piglit-like test using gallium only.

src/gallium/auxiliary/Makefile.sources
src/gallium/auxiliary/util/u_tests.c [new file with mode: 0644]
src/gallium/auxiliary/util/u_tests.h [new file with mode: 0644]

index f6621ef9947128a7d3c3c86b7feef8f5e793dcc1..9fc1a8ab8c0623917449b6aa71fb56847d98f4ef 100644 (file)
@@ -139,6 +139,7 @@ C_SOURCES := \
        util/u_suballoc.c \
        util/u_surface.c \
        util/u_surfaces.c \
+       util/u_tests.c \
        util/u_texture.c \
        util/u_tile.c \
        util/u_transfer.c \
diff --git a/src/gallium/auxiliary/util/u_tests.c b/src/gallium/auxiliary/util/u_tests.c
new file mode 100644 (file)
index 0000000..9483f06
--- /dev/null
@@ -0,0 +1,270 @@
+/**************************************************************************
+ *
+ * Copyright 2014 Advanced Micro Devices, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+#include "util/u_tests.h"
+
+#include "util/u_draw_quad.h"
+#include "util/u_format.h"
+#include "util/u_inlines.h"
+#include "util/u_simple_shaders.h"
+#include "util/u_surface.h"
+#include "util/u_tile.h"
+#include "cso_cache/cso_context.h"
+#include <stdio.h>
+
+#define TOLERANCE 0.01
+
+static struct pipe_resource *
+util_create_texture2d(struct pipe_screen *screen, unsigned width,
+                      unsigned height, enum pipe_format format)
+{
+   struct pipe_resource templ = {{0}};
+
+   templ.target = PIPE_TEXTURE_2D;
+   templ.width0 = width;
+   templ.height0 = height;
+   templ.depth0 = 1;
+   templ.array_size = 1;
+   templ.format = format;
+   templ.usage = PIPE_USAGE_DEFAULT;
+   templ.bind = PIPE_BIND_SAMPLER_VIEW |
+                (util_format_is_depth_or_stencil(format) ?
+                    PIPE_BIND_DEPTH_STENCIL : PIPE_BIND_RENDER_TARGET);
+
+   return screen->resource_create(screen, &templ);
+}
+
+static void
+util_set_framebuffer_cb0(struct cso_context *cso, struct pipe_context *ctx,
+                        struct pipe_resource *tex)
+{
+   struct pipe_surface templ = {{0}}, *surf;
+   struct pipe_framebuffer_state fb = {0};
+
+   templ.format = tex->format;
+   surf = ctx->create_surface(ctx, tex, &templ);
+
+   fb.width = tex->width0;
+   fb.height = tex->height0;
+   fb.cbufs[0] = surf;
+   fb.nr_cbufs = 1;
+
+   cso_set_framebuffer(cso, &fb);
+   pipe_surface_reference(&surf, NULL);
+}
+
+static void
+util_set_blend_normal(struct cso_context *cso)
+{
+   struct pipe_blend_state blend = {0};
+
+   blend.rt[0].colormask = PIPE_MASK_RGBA;
+   cso_set_blend(cso, &blend);
+}
+
+static void
+util_set_dsa_disable(struct cso_context *cso)
+{
+   struct pipe_depth_stencil_alpha_state dsa = {{0}};
+
+   cso_set_depth_stencil_alpha(cso, &dsa);
+}
+
+static void
+util_set_rasterizer_normal(struct cso_context *cso)
+{
+   struct pipe_rasterizer_state rs = {0};
+
+   rs.half_pixel_center = 1;
+   rs.bottom_edge_rule = 1;
+   rs.depth_clip = 1;
+
+   cso_set_rasterizer(cso, &rs);
+}
+
+static void
+util_set_max_viewport(struct cso_context *cso, struct pipe_resource *tex)
+{
+   struct pipe_viewport_state viewport;
+
+   viewport.scale[0] = 0.5f * tex->width0;
+   viewport.scale[1] = 0.5f * tex->height0;
+   viewport.scale[2] = 1.0f;
+   viewport.scale[3] = 1.0f;
+   viewport.translate[0] = 0.5f * tex->width0;
+   viewport.translate[1] = 0.5f * tex->height0;
+   viewport.translate[2] = 0.0f;
+   viewport.translate[3] = 0.0f;
+
+   cso_set_viewport(cso, &viewport);
+}
+
+static void
+util_set_interleaved_vertex_elements(struct cso_context *cso,
+                                     unsigned num_elements)
+{
+   int i;
+   struct pipe_vertex_element *velem =
+      calloc(1, num_elements * sizeof(struct pipe_vertex_element));
+
+   for (i = 0; i < num_elements; i++) {
+      velem[i].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
+      velem[i].src_offset = i * 16;
+   }
+
+   cso_set_vertex_elements(cso, num_elements, velem);
+   free(velem);
+}
+
+static bool
+util_probe_rect_rgba(struct pipe_context *ctx, struct pipe_resource *tex,
+                     unsigned offx, unsigned offy, unsigned w, unsigned h,
+                     const float *expected)
+{
+   struct pipe_transfer *transfer;
+   void *map;
+   float *pixels = malloc(w * h * 4 * sizeof(float));
+   int x,y,c;
+   bool pass = true;
+
+   map = pipe_transfer_map(ctx, tex, 0, 0, PIPE_TRANSFER_READ,
+                           offx, offy, w, h, &transfer);
+   pipe_get_tile_rgba(transfer, map, 0, 0, w, h, pixels);
+   pipe_transfer_unmap(ctx, transfer);
+
+   for (y = 0; y < h; y++) {
+      for (x = 0; x < w; x++) {
+         float *probe = &pixels[(y*w + x)*4];
+
+         for (c = 0; c < 4; c++)
+            if (fabs(probe[c] - expected[c]) >= TOLERANCE) {
+               printf("Probe color at (%i,%i),  ", offx+x, offy+y);
+               printf("Expected: %.3f, %.3f, %.3f, %.3f,  ",
+                      expected[0], expected[1], expected[2], expected[3]);
+               printf("Got: %.3f, %.3f, %.3f, %.3f\n",
+                      probe[0], probe[1], probe[2], probe[2]);
+               pass = false;
+               goto done;
+            }
+      }
+   }
+done:
+
+   free(pixels);
+   return pass;
+}
+
+/**
+ * Test TGSI_PROPERTY_VS_WINDOW_SPACE_POSITION.
+ *
+ * The viewport state is set as usual, but it should have no effect.
+ * Clipping should also be disabled.
+ *
+ * POSITION.xyz should already be multiplied by 1/w and POSITION.w should
+ * contain 1/w. By setting w=0, we can test that POSITION.xyz isn't
+ * multiplied by 1/w (otherwise nothing would be rendered).
+ *
+ * TODO: Whether the value of POSITION.w is correctly interpreted as 1/w
+ *       during perspective interpolation is not tested.
+ */
+static void
+tgsi_vs_window_space_position(struct pipe_context *ctx)
+{
+   struct cso_context *cso;
+   struct pipe_resource *cb;
+   void *fs, *vs;
+   bool pass = true;
+
+   static uint vs_attribs[] = {
+      TGSI_SEMANTIC_POSITION,
+      TGSI_SEMANTIC_GENERIC
+   };
+   static uint vs_indices[] = {0, 0};
+   static float vertices[] = {
+       0,   0, 0, 0,   1,  0, 0, 1,
+       0, 256, 0, 0,   1,  0, 0, 1,
+     256, 256, 0, 0,   1,  0, 0, 1,
+     256,   0, 0, 0,   1,  0, 0, 1,
+   };
+   static float red[] = {1, 0, 0, 1};
+   static float clear_color[] = {0.1, 0.1, 0.1, 0.1};
+
+   if (!ctx->screen->get_param(ctx->screen,
+                               PIPE_CAP_TGSI_VS_WINDOW_SPACE_POSITION)) {
+      printf("Test(%s) = skip\n", __func__);
+      return;
+   }
+
+   cso = cso_create_context(ctx);
+   cb = util_create_texture2d(ctx->screen, 256, 256,
+                              PIPE_FORMAT_R8G8B8A8_UNORM);
+
+   /* Set states. */
+   util_set_framebuffer_cb0(cso, ctx, cb);
+   util_set_blend_normal(cso);
+   util_set_dsa_disable(cso);
+   util_set_rasterizer_normal(cso);
+   util_set_max_viewport(cso, cb);
+   util_set_interleaved_vertex_elements(cso, 2);
+
+   /* Fragment shader. */
+   fs = util_make_fragment_passthrough_shader(ctx, TGSI_SEMANTIC_GENERIC,
+                                       TGSI_INTERPOLATE_LINEAR, TRUE);
+   cso_set_fragment_shader_handle(cso, fs);
+
+   /* Vertex shader. */
+   vs = util_make_vertex_passthrough_shader(ctx, 2, vs_attribs, vs_indices,
+                                            TRUE);
+   cso_set_vertex_shader_handle(cso, vs);
+
+   /* Clear and draw. */
+   ctx->clear(ctx, PIPE_CLEAR_COLOR0, (void*)clear_color, 0, 0);
+   util_draw_user_vertex_buffer(cso, vertices, PIPE_PRIM_QUADS, 4, 2);
+
+   /* Probe pixels. */
+   pass = pass && util_probe_rect_rgba(ctx, cb, 0, 0,
+                                       cb->width0, cb->height0, red);
+
+   /* Cleanup. */
+   cso_release_all(cso);
+   cso_destroy_context(cso);
+   ctx->delete_vs_state(ctx, vs);
+   ctx->delete_fs_state(ctx, fs);
+   pipe_resource_reference(&cb, NULL);
+
+   printf("Test(%s) = %s\n", __func__, pass ? "pass" : "fail");
+}
+
+/**
+ * Run all tests. This should be run with a clean context after
+ * context_create.
+ */
+void
+util_run_tests(struct pipe_context *ctx)
+{
+   tgsi_vs_window_space_position(ctx);
+}
diff --git a/src/gallium/auxiliary/util/u_tests.h b/src/gallium/auxiliary/util/u_tests.h
new file mode 100644 (file)
index 0000000..a143934
--- /dev/null
@@ -0,0 +1,37 @@
+/**************************************************************************
+ *
+ * Copyright 2014 Advanced Micro Devices, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+#ifndef U_TESTS_H
+#define U_TESTS_H
+
+#include "pipe/p_compiler.h"
+
+struct pipe_context;
+
+void util_run_tests(struct pipe_context *ctx);
+
+#endif