gallium/util: add a test for TGSI_PROPERTY_VS_WINDOW_SPACE_POSITION

Not testable by OpenGL. Required by Nine.

This is an example of how to implement a piglit-like test using gallium only.
This commit is contained in:
Marek Olšák 2014-11-08 16:48:33 +01:00
parent 717f2dd69f
commit e6a2d3f7b6
3 changed files with 308 additions and 0 deletions

View 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 \

View File

@ -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);
}

View File

@ -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