1 /**************************************************************************
3 * Copyright 2014 Advanced Micro Devices, Inc.
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21 * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR
22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 **************************************************************************/
28 #include "util/u_tests.h"
30 #include "util/u_draw_quad.h"
31 #include "util/u_format.h"
32 #include "util/u_inlines.h"
33 #include "util/u_simple_shaders.h"
34 #include "util/u_surface.h"
35 #include "util/u_tile.h"
36 #include "cso_cache/cso_context.h"
39 #define TOLERANCE 0.01
41 static struct pipe_resource
*
42 util_create_texture2d(struct pipe_screen
*screen
, unsigned width
,
43 unsigned height
, enum pipe_format format
)
45 struct pipe_resource templ
= {{0}};
47 templ
.target
= PIPE_TEXTURE_2D
;
49 templ
.height0
= height
;
52 templ
.format
= format
;
53 templ
.usage
= PIPE_USAGE_DEFAULT
;
54 templ
.bind
= PIPE_BIND_SAMPLER_VIEW
|
55 (util_format_is_depth_or_stencil(format
) ?
56 PIPE_BIND_DEPTH_STENCIL
: PIPE_BIND_RENDER_TARGET
);
58 return screen
->resource_create(screen
, &templ
);
62 util_set_framebuffer_cb0(struct cso_context
*cso
, struct pipe_context
*ctx
,
63 struct pipe_resource
*tex
)
65 struct pipe_surface templ
= {{0}}, *surf
;
66 struct pipe_framebuffer_state fb
= {0};
68 templ
.format
= tex
->format
;
69 surf
= ctx
->create_surface(ctx
, tex
, &templ
);
71 fb
.width
= tex
->width0
;
72 fb
.height
= tex
->height0
;
76 cso_set_framebuffer(cso
, &fb
);
77 pipe_surface_reference(&surf
, NULL
);
81 util_set_blend_normal(struct cso_context
*cso
)
83 struct pipe_blend_state blend
= {0};
85 blend
.rt
[0].colormask
= PIPE_MASK_RGBA
;
86 cso_set_blend(cso
, &blend
);
90 util_set_dsa_disable(struct cso_context
*cso
)
92 struct pipe_depth_stencil_alpha_state dsa
= {{0}};
94 cso_set_depth_stencil_alpha(cso
, &dsa
);
98 util_set_rasterizer_normal(struct cso_context
*cso
)
100 struct pipe_rasterizer_state rs
= {0};
102 rs
.half_pixel_center
= 1;
103 rs
.bottom_edge_rule
= 1;
106 cso_set_rasterizer(cso
, &rs
);
110 util_set_max_viewport(struct cso_context
*cso
, struct pipe_resource
*tex
)
112 struct pipe_viewport_state viewport
;
114 viewport
.scale
[0] = 0.5f
* tex
->width0
;
115 viewport
.scale
[1] = 0.5f
* tex
->height0
;
116 viewport
.scale
[2] = 1.0f
;
117 viewport
.translate
[0] = 0.5f
* tex
->width0
;
118 viewport
.translate
[1] = 0.5f
* tex
->height0
;
119 viewport
.translate
[2] = 0.0f
;
121 cso_set_viewport(cso
, &viewport
);
125 util_set_interleaved_vertex_elements(struct cso_context
*cso
,
126 unsigned num_elements
)
129 struct pipe_vertex_element
*velem
=
130 calloc(1, num_elements
* sizeof(struct pipe_vertex_element
));
132 for (i
= 0; i
< num_elements
; i
++) {
133 velem
[i
].src_format
= PIPE_FORMAT_R32G32B32A32_FLOAT
;
134 velem
[i
].src_offset
= i
* 16;
137 cso_set_vertex_elements(cso
, num_elements
, velem
);
142 util_set_passthrough_vertex_shader(struct cso_context
*cso
,
143 struct pipe_context
*ctx
,
146 static const uint vs_attribs
[] = {
147 TGSI_SEMANTIC_POSITION
,
148 TGSI_SEMANTIC_GENERIC
150 static const uint vs_indices
[] = {0, 0};
153 vs
= util_make_vertex_passthrough_shader(ctx
, 2, vs_attribs
, vs_indices
,
155 cso_set_vertex_shader_handle(cso
, vs
);
160 util_set_common_states_and_clear(struct cso_context
*cso
, struct pipe_context
*ctx
,
161 struct pipe_resource
*cb
)
163 static const float clear_color
[] = {0.1, 0.1, 0.1, 0.1};
165 util_set_framebuffer_cb0(cso
, ctx
, cb
);
166 util_set_blend_normal(cso
);
167 util_set_dsa_disable(cso
);
168 util_set_rasterizer_normal(cso
);
169 util_set_max_viewport(cso
, cb
);
171 ctx
->clear(ctx
, PIPE_CLEAR_COLOR0
, (void*)clear_color
, 0, 0);
175 util_draw_fullscreen_quad(struct cso_context
*cso
)
177 static float vertices
[] = {
178 -1, -1, 0, 1, 0, 0, 0, 0,
179 -1, 1, 0, 1, 0, 1, 0, 0,
180 1, 1, 0, 1, 1, 1, 0, 0,
181 1, -1, 0, 1, 1, 0, 0, 0
183 util_set_interleaved_vertex_elements(cso
, 2);
184 util_draw_user_vertex_buffer(cso
, vertices
, PIPE_PRIM_QUADS
, 4, 2);
188 * Probe and test if the rectangle contains the expected color.
190 * If "num_expected_colors" > 1, at least one expected color must match
191 * the probed color. "expected" should be an array of 4*num_expected_colors
195 util_probe_rect_rgba_multi(struct pipe_context
*ctx
, struct pipe_resource
*tex
,
196 unsigned offx
, unsigned offy
, unsigned w
,
198 const float *expected
,
199 unsigned num_expected_colors
)
201 struct pipe_transfer
*transfer
;
203 float *pixels
= malloc(w
* h
* 4 * sizeof(float));
207 map
= pipe_transfer_map(ctx
, tex
, 0, 0, PIPE_TRANSFER_READ
,
208 offx
, offy
, w
, h
, &transfer
);
209 pipe_get_tile_rgba(transfer
, map
, 0, 0, w
, h
, pixels
);
210 pipe_transfer_unmap(ctx
, transfer
);
212 for (e
= 0; e
< num_expected_colors
; e
++) {
213 for (y
= 0; y
< h
; y
++) {
214 for (x
= 0; x
< w
; x
++) {
215 float *probe
= &pixels
[(y
*w
+ x
)*4];
217 for (c
= 0; c
< 4; c
++) {
218 if (fabs(probe
[c
] - expected
[e
*4+c
]) >= TOLERANCE
) {
219 if (e
< num_expected_colors
-1)
220 goto next_color
; /* test the next expected color */
222 printf("Probe color at (%i,%i), ", offx
+x
, offy
+y
);
223 printf("Expected: %.3f, %.3f, %.3f, %.3f, ",
224 expected
[e
*4], expected
[e
*4+1],
225 expected
[e
*4+2], expected
[e
*4+3]);
226 printf("Got: %.3f, %.3f, %.3f, %.3f\n",
227 probe
[0], probe
[1], probe
[2], probe
[2]);
234 break; /* this color was successful */
245 util_probe_rect_rgba(struct pipe_context
*ctx
, struct pipe_resource
*tex
,
246 unsigned offx
, unsigned offy
, unsigned w
, unsigned h
,
247 const float *expected
)
249 return util_probe_rect_rgba_multi(ctx
, tex
, offx
, offy
, w
, h
, expected
, 1);
254 FAIL
= 0, /* also "false" */
255 PASS
= 1 /* also "true" */
259 util_report_result_helper(const char *name
, int status
)
261 printf("Test(%s) = %s\n", name
,
262 status
== SKIP
? "skip" :
263 status
== PASS
? "pass" : "fail");
266 #define util_report_result(status) util_report_result_helper(__func__, status)
269 * Test TGSI_PROPERTY_VS_WINDOW_SPACE_POSITION.
271 * The viewport state is set as usual, but it should have no effect.
272 * Clipping should also be disabled.
274 * POSITION.xyz should already be multiplied by 1/w and POSITION.w should
275 * contain 1/w. By setting w=0, we can test that POSITION.xyz isn't
276 * multiplied by 1/w (otherwise nothing would be rendered).
278 * TODO: Whether the value of POSITION.w is correctly interpreted as 1/w
279 * during perspective interpolation is not tested.
282 tgsi_vs_window_space_position(struct pipe_context
*ctx
)
284 struct cso_context
*cso
;
285 struct pipe_resource
*cb
;
288 static const float red
[] = {1, 0, 0, 1};
290 if (!ctx
->screen
->get_param(ctx
->screen
,
291 PIPE_CAP_TGSI_VS_WINDOW_SPACE_POSITION
)) {
292 util_report_result(SKIP
);
296 cso
= cso_create_context(ctx
);
297 cb
= util_create_texture2d(ctx
->screen
, 256, 256,
298 PIPE_FORMAT_R8G8B8A8_UNORM
);
299 util_set_common_states_and_clear(cso
, ctx
, cb
);
301 /* Fragment shader. */
302 fs
= util_make_fragment_passthrough_shader(ctx
, TGSI_SEMANTIC_GENERIC
,
303 TGSI_INTERPOLATE_LINEAR
, TRUE
);
304 cso_set_fragment_shader_handle(cso
, fs
);
307 vs
= util_set_passthrough_vertex_shader(cso
, ctx
, true);
311 static float vertices
[] = {
312 0, 0, 0, 0, 1, 0, 0, 1,
313 0, 256, 0, 0, 1, 0, 0, 1,
314 256, 256, 0, 0, 1, 0, 0, 1,
315 256, 0, 0, 0, 1, 0, 0, 1,
317 util_set_interleaved_vertex_elements(cso
, 2);
318 util_draw_user_vertex_buffer(cso
, vertices
, PIPE_PRIM_QUADS
, 4, 2);
322 pass
= pass
&& util_probe_rect_rgba(ctx
, cb
, 0, 0,
323 cb
->width0
, cb
->height0
, red
);
326 cso_destroy_context(cso
);
327 ctx
->delete_vs_state(ctx
, vs
);
328 ctx
->delete_fs_state(ctx
, fs
);
329 pipe_resource_reference(&cb
, NULL
);
331 util_report_result(pass
);
335 null_sampler_view(struct pipe_context
*ctx
)
337 struct cso_context
*cso
;
338 struct pipe_resource
*cb
;
341 /* 2 expected colors: */
342 static const float expected
[] = {0, 0, 0, 1,
345 cso
= cso_create_context(ctx
);
346 cb
= util_create_texture2d(ctx
->screen
, 256, 256,
347 PIPE_FORMAT_R8G8B8A8_UNORM
);
348 util_set_common_states_and_clear(cso
, ctx
, cb
);
350 ctx
->set_sampler_views(ctx
, PIPE_SHADER_FRAGMENT
, 0, 1, NULL
);
352 /* Fragment shader. */
353 fs
= util_make_fragment_tex_shader(ctx
, TGSI_TEXTURE_2D
,
354 TGSI_INTERPOLATE_LINEAR
);
355 cso_set_fragment_shader_handle(cso
, fs
);
358 vs
= util_set_passthrough_vertex_shader(cso
, ctx
, false);
359 util_draw_fullscreen_quad(cso
);
362 pass
= pass
&& util_probe_rect_rgba_multi(ctx
, cb
, 0, 0,
363 cb
->width0
, cb
->height0
, expected
, 2);
366 cso_destroy_context(cso
);
367 ctx
->delete_vs_state(ctx
, vs
);
368 ctx
->delete_fs_state(ctx
, fs
);
369 pipe_resource_reference(&cb
, NULL
);
371 util_report_result(pass
);
375 * Run all tests. This should be run with a clean context after
379 util_run_tests(struct pipe_screen
*screen
)
381 struct pipe_context
*ctx
= screen
->context_create(screen
, NULL
);
383 tgsi_vs_window_space_position(ctx
);
384 null_sampler_view(ctx
);
388 puts("Done. Exiting..");