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:
parent
717f2dd69f
commit
e6a2d3f7b6
|
@ -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 \
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -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
|
Loading…
Reference in New Issue