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_probe_rect_rgba(struct pipe_context
*ctx
, struct pipe_resource
*tex
,
143 unsigned offx
, unsigned offy
, unsigned w
, unsigned h
,
144 const float *expected
)
146 struct pipe_transfer
*transfer
;
148 float *pixels
= malloc(w
* h
* 4 * sizeof(float));
152 map
= pipe_transfer_map(ctx
, tex
, 0, 0, PIPE_TRANSFER_READ
,
153 offx
, offy
, w
, h
, &transfer
);
154 pipe_get_tile_rgba(transfer
, map
, 0, 0, w
, h
, pixels
);
155 pipe_transfer_unmap(ctx
, transfer
);
157 for (y
= 0; y
< h
; y
++) {
158 for (x
= 0; x
< w
; x
++) {
159 float *probe
= &pixels
[(y
*w
+ x
)*4];
161 for (c
= 0; c
< 4; c
++)
162 if (fabs(probe
[c
] - expected
[c
]) >= TOLERANCE
) {
163 printf("Probe color at (%i,%i), ", offx
+x
, offy
+y
);
164 printf("Expected: %.3f, %.3f, %.3f, %.3f, ",
165 expected
[0], expected
[1], expected
[2], expected
[3]);
166 printf("Got: %.3f, %.3f, %.3f, %.3f\n",
167 probe
[0], probe
[1], probe
[2], probe
[2]);
180 * Test TGSI_PROPERTY_VS_WINDOW_SPACE_POSITION.
182 * The viewport state is set as usual, but it should have no effect.
183 * Clipping should also be disabled.
185 * POSITION.xyz should already be multiplied by 1/w and POSITION.w should
186 * contain 1/w. By setting w=0, we can test that POSITION.xyz isn't
187 * multiplied by 1/w (otherwise nothing would be rendered).
189 * TODO: Whether the value of POSITION.w is correctly interpreted as 1/w
190 * during perspective interpolation is not tested.
193 tgsi_vs_window_space_position(struct pipe_context
*ctx
)
195 struct cso_context
*cso
;
196 struct pipe_resource
*cb
;
200 static uint vs_attribs
[] = {
201 TGSI_SEMANTIC_POSITION
,
202 TGSI_SEMANTIC_GENERIC
204 static uint vs_indices
[] = {0, 0};
205 static float vertices
[] = {
206 0, 0, 0, 0, 1, 0, 0, 1,
207 0, 256, 0, 0, 1, 0, 0, 1,
208 256, 256, 0, 0, 1, 0, 0, 1,
209 256, 0, 0, 0, 1, 0, 0, 1,
211 static float red
[] = {1, 0, 0, 1};
212 static float clear_color
[] = {0.1, 0.1, 0.1, 0.1};
214 if (!ctx
->screen
->get_param(ctx
->screen
,
215 PIPE_CAP_TGSI_VS_WINDOW_SPACE_POSITION
)) {
216 printf("Test(%s) = skip\n", __func__
);
220 cso
= cso_create_context(ctx
);
221 cb
= util_create_texture2d(ctx
->screen
, 256, 256,
222 PIPE_FORMAT_R8G8B8A8_UNORM
);
225 util_set_framebuffer_cb0(cso
, ctx
, cb
);
226 util_set_blend_normal(cso
);
227 util_set_dsa_disable(cso
);
228 util_set_rasterizer_normal(cso
);
229 util_set_max_viewport(cso
, cb
);
230 util_set_interleaved_vertex_elements(cso
, 2);
232 /* Fragment shader. */
233 fs
= util_make_fragment_passthrough_shader(ctx
, TGSI_SEMANTIC_GENERIC
,
234 TGSI_INTERPOLATE_LINEAR
, TRUE
);
235 cso_set_fragment_shader_handle(cso
, fs
);
238 vs
= util_make_vertex_passthrough_shader(ctx
, 2, vs_attribs
, vs_indices
,
240 cso_set_vertex_shader_handle(cso
, vs
);
242 /* Clear and draw. */
243 ctx
->clear(ctx
, PIPE_CLEAR_COLOR0
, (void*)clear_color
, 0, 0);
244 util_draw_user_vertex_buffer(cso
, vertices
, PIPE_PRIM_QUADS
, 4, 2);
247 pass
= pass
&& util_probe_rect_rgba(ctx
, cb
, 0, 0,
248 cb
->width0
, cb
->height0
, red
);
251 cso_release_all(cso
);
252 cso_destroy_context(cso
);
253 ctx
->delete_vs_state(ctx
, vs
);
254 ctx
->delete_fs_state(ctx
, fs
);
255 pipe_resource_reference(&cb
, NULL
);
257 printf("Test(%s) = %s\n", __func__
, pass
? "pass" : "fail");
261 * Run all tests. This should be run with a clean context after
265 util_run_tests(struct pipe_context
*ctx
)
267 tgsi_vs_window_space_position(ctx
);