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
.scale
[3] = 1.0f
;
118 viewport
.translate
[0] = 0.5f
* tex
->width0
;
119 viewport
.translate
[1] = 0.5f
* tex
->height0
;
120 viewport
.translate
[2] = 0.0f
;
121 viewport
.translate
[3] = 0.0f
;
123 cso_set_viewport(cso
, &viewport
);
127 util_set_interleaved_vertex_elements(struct cso_context
*cso
,
128 unsigned num_elements
)
131 struct pipe_vertex_element
*velem
=
132 calloc(1, num_elements
* sizeof(struct pipe_vertex_element
));
134 for (i
= 0; i
< num_elements
; i
++) {
135 velem
[i
].src_format
= PIPE_FORMAT_R32G32B32A32_FLOAT
;
136 velem
[i
].src_offset
= i
* 16;
139 cso_set_vertex_elements(cso
, num_elements
, velem
);
144 util_probe_rect_rgba(struct pipe_context
*ctx
, struct pipe_resource
*tex
,
145 unsigned offx
, unsigned offy
, unsigned w
, unsigned h
,
146 const float *expected
)
148 struct pipe_transfer
*transfer
;
150 float *pixels
= malloc(w
* h
* 4 * sizeof(float));
154 map
= pipe_transfer_map(ctx
, tex
, 0, 0, PIPE_TRANSFER_READ
,
155 offx
, offy
, w
, h
, &transfer
);
156 pipe_get_tile_rgba(transfer
, map
, 0, 0, w
, h
, pixels
);
157 pipe_transfer_unmap(ctx
, transfer
);
159 for (y
= 0; y
< h
; y
++) {
160 for (x
= 0; x
< w
; x
++) {
161 float *probe
= &pixels
[(y
*w
+ x
)*4];
163 for (c
= 0; c
< 4; c
++)
164 if (fabs(probe
[c
] - expected
[c
]) >= TOLERANCE
) {
165 printf("Probe color at (%i,%i), ", offx
+x
, offy
+y
);
166 printf("Expected: %.3f, %.3f, %.3f, %.3f, ",
167 expected
[0], expected
[1], expected
[2], expected
[3]);
168 printf("Got: %.3f, %.3f, %.3f, %.3f\n",
169 probe
[0], probe
[1], probe
[2], probe
[2]);
182 * Test TGSI_PROPERTY_VS_WINDOW_SPACE_POSITION.
184 * The viewport state is set as usual, but it should have no effect.
185 * Clipping should also be disabled.
187 * POSITION.xyz should already be multiplied by 1/w and POSITION.w should
188 * contain 1/w. By setting w=0, we can test that POSITION.xyz isn't
189 * multiplied by 1/w (otherwise nothing would be rendered).
191 * TODO: Whether the value of POSITION.w is correctly interpreted as 1/w
192 * during perspective interpolation is not tested.
195 tgsi_vs_window_space_position(struct pipe_context
*ctx
)
197 struct cso_context
*cso
;
198 struct pipe_resource
*cb
;
202 static uint vs_attribs
[] = {
203 TGSI_SEMANTIC_POSITION
,
204 TGSI_SEMANTIC_GENERIC
206 static uint vs_indices
[] = {0, 0};
207 static float vertices
[] = {
208 0, 0, 0, 0, 1, 0, 0, 1,
209 0, 256, 0, 0, 1, 0, 0, 1,
210 256, 256, 0, 0, 1, 0, 0, 1,
211 256, 0, 0, 0, 1, 0, 0, 1,
213 static float red
[] = {1, 0, 0, 1};
214 static float clear_color
[] = {0.1, 0.1, 0.1, 0.1};
216 if (!ctx
->screen
->get_param(ctx
->screen
,
217 PIPE_CAP_TGSI_VS_WINDOW_SPACE_POSITION
)) {
218 printf("Test(%s) = skip\n", __func__
);
222 cso
= cso_create_context(ctx
);
223 cb
= util_create_texture2d(ctx
->screen
, 256, 256,
224 PIPE_FORMAT_R8G8B8A8_UNORM
);
227 util_set_framebuffer_cb0(cso
, ctx
, cb
);
228 util_set_blend_normal(cso
);
229 util_set_dsa_disable(cso
);
230 util_set_rasterizer_normal(cso
);
231 util_set_max_viewport(cso
, cb
);
232 util_set_interleaved_vertex_elements(cso
, 2);
234 /* Fragment shader. */
235 fs
= util_make_fragment_passthrough_shader(ctx
, TGSI_SEMANTIC_GENERIC
,
236 TGSI_INTERPOLATE_LINEAR
, TRUE
);
237 cso_set_fragment_shader_handle(cso
, fs
);
240 vs
= util_make_vertex_passthrough_shader(ctx
, 2, vs_attribs
, vs_indices
,
242 cso_set_vertex_shader_handle(cso
, vs
);
244 /* Clear and draw. */
245 ctx
->clear(ctx
, PIPE_CLEAR_COLOR0
, (void*)clear_color
, 0, 0);
246 util_draw_user_vertex_buffer(cso
, vertices
, PIPE_PRIM_QUADS
, 4, 2);
249 pass
= pass
&& util_probe_rect_rgba(ctx
, cb
, 0, 0,
250 cb
->width0
, cb
->height0
, red
);
253 cso_release_all(cso
);
254 cso_destroy_context(cso
);
255 ctx
->delete_vs_state(ctx
, vs
);
256 ctx
->delete_fs_state(ctx
, fs
);
257 pipe_resource_reference(&cb
, NULL
);
259 printf("Test(%s) = %s\n", __func__
, pass
? "pass" : "fail");
263 * Run all tests. This should be run with a clean context after
267 util_run_tests(struct pipe_context
*ctx
)
269 tgsi_vs_window_space_position(ctx
);