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_memory.h"
34 #include "util/u_simple_shaders.h"
35 #include "util/u_surface.h"
36 #include "util/u_string.h"
37 #include "util/u_tile.h"
38 #include "tgsi/tgsi_strings.h"
39 #include "tgsi/tgsi_text.h"
40 #include "cso_cache/cso_context.h"
43 #define TOLERANCE 0.01
45 static struct pipe_resource
*
46 util_create_texture2d(struct pipe_screen
*screen
, unsigned width
,
47 unsigned height
, enum pipe_format format
,
50 struct pipe_resource templ
= {{0}};
52 templ
.target
= PIPE_TEXTURE_2D
;
54 templ
.height0
= height
;
57 templ
.nr_samples
= num_samples
;
58 templ
.nr_storage_samples
= num_samples
;
59 templ
.format
= format
;
60 templ
.usage
= PIPE_USAGE_DEFAULT
;
61 templ
.bind
= PIPE_BIND_SAMPLER_VIEW
|
62 (util_format_is_depth_or_stencil(format
) ?
63 PIPE_BIND_DEPTH_STENCIL
: PIPE_BIND_RENDER_TARGET
);
65 return screen
->resource_create(screen
, &templ
);
69 util_set_framebuffer_cb0(struct cso_context
*cso
, struct pipe_context
*ctx
,
70 struct pipe_resource
*tex
)
72 struct pipe_surface templ
= {{0}}, *surf
;
73 struct pipe_framebuffer_state fb
= {0};
75 templ
.format
= tex
->format
;
76 surf
= ctx
->create_surface(ctx
, tex
, &templ
);
78 fb
.width
= tex
->width0
;
79 fb
.height
= tex
->height0
;
83 cso_set_framebuffer(cso
, &fb
);
84 pipe_surface_reference(&surf
, NULL
);
88 util_set_blend_normal(struct cso_context
*cso
)
90 struct pipe_blend_state blend
= {0};
92 blend
.rt
[0].colormask
= PIPE_MASK_RGBA
;
93 cso_set_blend(cso
, &blend
);
97 util_set_dsa_disable(struct cso_context
*cso
)
99 struct pipe_depth_stencil_alpha_state dsa
= {{0}};
101 cso_set_depth_stencil_alpha(cso
, &dsa
);
105 util_set_rasterizer_normal(struct cso_context
*cso
)
107 struct pipe_rasterizer_state rs
= {0};
109 rs
.half_pixel_center
= 1;
110 rs
.bottom_edge_rule
= 1;
111 rs
.depth_clip_near
= 1;
112 rs
.depth_clip_far
= 1;
114 cso_set_rasterizer(cso
, &rs
);
118 util_set_max_viewport(struct cso_context
*cso
, struct pipe_resource
*tex
)
120 struct pipe_viewport_state viewport
;
122 viewport
.scale
[0] = 0.5f
* tex
->width0
;
123 viewport
.scale
[1] = 0.5f
* tex
->height0
;
124 viewport
.scale
[2] = 1.0f
;
125 viewport
.translate
[0] = 0.5f
* tex
->width0
;
126 viewport
.translate
[1] = 0.5f
* tex
->height0
;
127 viewport
.translate
[2] = 0.0f
;
129 cso_set_viewport(cso
, &viewport
);
133 util_set_interleaved_vertex_elements(struct cso_context
*cso
,
134 unsigned num_elements
)
137 struct pipe_vertex_element
*velem
=
138 calloc(1, num_elements
* sizeof(struct pipe_vertex_element
));
140 for (i
= 0; i
< num_elements
; i
++) {
141 velem
[i
].src_format
= PIPE_FORMAT_R32G32B32A32_FLOAT
;
142 velem
[i
].src_offset
= i
* 16;
145 cso_set_vertex_elements(cso
, num_elements
, velem
);
150 util_set_passthrough_vertex_shader(struct cso_context
*cso
,
151 struct pipe_context
*ctx
,
154 static const enum tgsi_semantic vs_attribs
[] = {
155 TGSI_SEMANTIC_POSITION
,
156 TGSI_SEMANTIC_GENERIC
158 static const uint vs_indices
[] = {0, 0};
161 vs
= util_make_vertex_passthrough_shader(ctx
, 2, vs_attribs
, vs_indices
,
163 cso_set_vertex_shader_handle(cso
, vs
);
168 util_set_common_states_and_clear(struct cso_context
*cso
, struct pipe_context
*ctx
,
169 struct pipe_resource
*cb
)
171 static const float clear_color
[] = {0.1, 0.1, 0.1, 0.1};
173 util_set_framebuffer_cb0(cso
, ctx
, cb
);
174 util_set_blend_normal(cso
);
175 util_set_dsa_disable(cso
);
176 util_set_rasterizer_normal(cso
);
177 util_set_max_viewport(cso
, cb
);
179 ctx
->clear(ctx
, PIPE_CLEAR_COLOR0
, (void*)clear_color
, 0, 0);
183 util_draw_fullscreen_quad(struct cso_context
*cso
)
185 static float vertices
[] = {
186 -1, -1, 0, 1, 0, 0, 0, 0,
187 -1, 1, 0, 1, 0, 1, 0, 0,
188 1, 1, 0, 1, 1, 1, 0, 0,
189 1, -1, 0, 1, 1, 0, 0, 0
191 util_set_interleaved_vertex_elements(cso
, 2);
192 util_draw_user_vertex_buffer(cso
, vertices
, PIPE_PRIM_QUADS
, 4, 2);
196 util_draw_fullscreen_quad_fill(struct cso_context
*cso
,
197 float r
, float g
, float b
, float a
)
200 -1, -1, 0, 1, r
, g
, b
, a
,
201 -1, 1, 0, 1, r
, g
, b
, a
,
202 1, 1, 0, 1, r
, g
, b
, a
,
203 1, -1, 0, 1, r
, g
, b
, a
,
205 util_set_interleaved_vertex_elements(cso
, 2);
206 util_draw_user_vertex_buffer(cso
, vertices
, PIPE_PRIM_QUADS
, 4, 2);
210 * Probe and test if the rectangle contains the expected color.
212 * If "num_expected_colors" > 1, at least one expected color must match
213 * the probed color. "expected" should be an array of 4*num_expected_colors
217 util_probe_rect_rgba_multi(struct pipe_context
*ctx
, struct pipe_resource
*tex
,
218 unsigned offx
, unsigned offy
, unsigned w
,
220 const float *expected
,
221 unsigned num_expected_colors
)
223 struct pipe_transfer
*transfer
;
225 float *pixels
= malloc(w
* h
* 4 * sizeof(float));
229 map
= pipe_transfer_map(ctx
, tex
, 0, 0, PIPE_TRANSFER_READ
,
230 offx
, offy
, w
, h
, &transfer
);
231 pipe_get_tile_rgba(transfer
, map
, 0, 0, w
, h
, pixels
);
232 pipe_transfer_unmap(ctx
, transfer
);
234 for (e
= 0; e
< num_expected_colors
; e
++) {
235 for (y
= 0; y
< h
; y
++) {
236 for (x
= 0; x
< w
; x
++) {
237 float *probe
= &pixels
[(y
*w
+ x
)*4];
239 for (c
= 0; c
< 4; c
++) {
240 if (fabs(probe
[c
] - expected
[e
*4+c
]) >= TOLERANCE
) {
241 if (e
< num_expected_colors
-1)
242 goto next_color
; /* test the next expected color */
244 printf("Probe color at (%i,%i), ", offx
+x
, offy
+y
);
245 printf("Expected: %.3f, %.3f, %.3f, %.3f, ",
246 expected
[e
*4], expected
[e
*4+1],
247 expected
[e
*4+2], expected
[e
*4+3]);
248 printf("Got: %.3f, %.3f, %.3f, %.3f\n",
249 probe
[0], probe
[1], probe
[2], probe
[3]);
256 break; /* this color was successful */
267 util_probe_rect_rgba(struct pipe_context
*ctx
, struct pipe_resource
*tex
,
268 unsigned offx
, unsigned offy
, unsigned w
, unsigned h
,
269 const float *expected
)
271 return util_probe_rect_rgba_multi(ctx
, tex
, offx
, offy
, w
, h
, expected
, 1);
276 FAIL
= 0, /* also "false" */
277 PASS
= 1 /* also "true" */
281 util_report_result_helper(int status
, const char *name
, ...)
287 util_vsnprintf(buf
, sizeof(buf
), name
, ap
);
290 printf("Test(%s) = %s\n", buf
,
291 status
== SKIP
? "skip" :
292 status
== PASS
? "pass" : "fail");
295 #define util_report_result(status) util_report_result_helper(status, __func__)
298 * Test TGSI_PROPERTY_VS_WINDOW_SPACE_POSITION.
300 * The viewport state is set as usual, but it should have no effect.
301 * Clipping should also be disabled.
303 * POSITION.xyz should already be multiplied by 1/w and POSITION.w should
304 * contain 1/w. By setting w=0, we can test that POSITION.xyz isn't
305 * multiplied by 1/w (otherwise nothing would be rendered).
307 * TODO: Whether the value of POSITION.w is correctly interpreted as 1/w
308 * during perspective interpolation is not tested.
311 tgsi_vs_window_space_position(struct pipe_context
*ctx
)
313 struct cso_context
*cso
;
314 struct pipe_resource
*cb
;
317 static const float red
[] = {1, 0, 0, 1};
319 if (!ctx
->screen
->get_param(ctx
->screen
,
320 PIPE_CAP_TGSI_VS_WINDOW_SPACE_POSITION
)) {
321 util_report_result(SKIP
);
325 cso
= cso_create_context(ctx
, 0);
326 cb
= util_create_texture2d(ctx
->screen
, 256, 256,
327 PIPE_FORMAT_R8G8B8A8_UNORM
, 0);
328 util_set_common_states_and_clear(cso
, ctx
, cb
);
330 /* Fragment shader. */
331 fs
= util_make_fragment_passthrough_shader(ctx
, TGSI_SEMANTIC_GENERIC
,
332 TGSI_INTERPOLATE_LINEAR
, TRUE
);
333 cso_set_fragment_shader_handle(cso
, fs
);
336 vs
= util_set_passthrough_vertex_shader(cso
, ctx
, true);
340 static float vertices
[] = {
341 0, 0, 0, 0, 1, 0, 0, 1,
342 0, 256, 0, 0, 1, 0, 0, 1,
343 256, 256, 0, 0, 1, 0, 0, 1,
344 256, 0, 0, 0, 1, 0, 0, 1,
346 util_set_interleaved_vertex_elements(cso
, 2);
347 util_draw_user_vertex_buffer(cso
, vertices
, PIPE_PRIM_QUADS
, 4, 2);
351 pass
= pass
&& util_probe_rect_rgba(ctx
, cb
, 0, 0,
352 cb
->width0
, cb
->height0
, red
);
355 cso_destroy_context(cso
);
356 ctx
->delete_vs_state(ctx
, vs
);
357 ctx
->delete_fs_state(ctx
, fs
);
358 pipe_resource_reference(&cb
, NULL
);
360 util_report_result(pass
);
364 null_sampler_view(struct pipe_context
*ctx
, unsigned tgsi_tex_target
)
366 struct cso_context
*cso
;
367 struct pipe_resource
*cb
;
370 /* 2 expected colors: */
371 static const float expected_tex
[] = {0, 0, 0, 1,
373 static const float expected_buf
[] = {0, 0, 0, 0};
374 const float *expected
= tgsi_tex_target
== TGSI_TEXTURE_BUFFER
?
375 expected_buf
: expected_tex
;
376 unsigned num_expected
= tgsi_tex_target
== TGSI_TEXTURE_BUFFER
? 1 : 2;
378 if (tgsi_tex_target
== TGSI_TEXTURE_BUFFER
&&
379 !ctx
->screen
->get_param(ctx
->screen
, PIPE_CAP_TEXTURE_BUFFER_OBJECTS
)) {
380 util_report_result_helper(SKIP
, "%s: %s", __func__
,
381 tgsi_texture_names
[tgsi_tex_target
]);
385 cso
= cso_create_context(ctx
, 0);
386 cb
= util_create_texture2d(ctx
->screen
, 256, 256,
387 PIPE_FORMAT_R8G8B8A8_UNORM
, 0);
388 util_set_common_states_and_clear(cso
, ctx
, cb
);
390 ctx
->set_sampler_views(ctx
, PIPE_SHADER_FRAGMENT
, 0, 1, NULL
);
392 /* Fragment shader. */
393 fs
= util_make_fragment_tex_shader(ctx
, tgsi_tex_target
,
394 TGSI_INTERPOLATE_LINEAR
,
395 TGSI_RETURN_TYPE_FLOAT
,
396 TGSI_RETURN_TYPE_FLOAT
, false, false);
397 cso_set_fragment_shader_handle(cso
, fs
);
400 vs
= util_set_passthrough_vertex_shader(cso
, ctx
, false);
401 util_draw_fullscreen_quad(cso
);
404 pass
= pass
&& util_probe_rect_rgba_multi(ctx
, cb
, 0, 0,
405 cb
->width0
, cb
->height0
, expected
,
409 cso_destroy_context(cso
);
410 ctx
->delete_vs_state(ctx
, vs
);
411 ctx
->delete_fs_state(ctx
, fs
);
412 pipe_resource_reference(&cb
, NULL
);
414 util_report_result_helper(pass
, "%s: %s", __func__
,
415 tgsi_texture_names
[tgsi_tex_target
]);
419 util_test_constant_buffer(struct pipe_context
*ctx
,
420 struct pipe_resource
*constbuf
)
422 struct cso_context
*cso
;
423 struct pipe_resource
*cb
;
426 static const float zero
[] = {0, 0, 0, 0};
428 cso
= cso_create_context(ctx
, 0);
429 cb
= util_create_texture2d(ctx
->screen
, 256, 256,
430 PIPE_FORMAT_R8G8B8A8_UNORM
, 0);
431 util_set_common_states_and_clear(cso
, ctx
, cb
);
433 pipe_set_constant_buffer(ctx
, PIPE_SHADER_FRAGMENT
, 0, constbuf
);
435 /* Fragment shader. */
437 static const char *text
= /* I don't like ureg... */
440 "DCL OUT[0], COLOR\n"
442 "MOV OUT[0], CONST[0][0]\n"
444 struct tgsi_token tokens
[1000];
445 struct pipe_shader_state state
;
447 if (!tgsi_text_translate(text
, tokens
, ARRAY_SIZE(tokens
))) {
448 puts("Can't compile a fragment shader.");
449 util_report_result(FAIL
);
452 pipe_shader_state_from_tgsi(&state
, tokens
);
453 fs
= ctx
->create_fs_state(ctx
, &state
);
454 cso_set_fragment_shader_handle(cso
, fs
);
458 vs
= util_set_passthrough_vertex_shader(cso
, ctx
, false);
459 util_draw_fullscreen_quad(cso
);
462 pass
= pass
&& util_probe_rect_rgba(ctx
, cb
, 0, 0, cb
->width0
,
466 cso_destroy_context(cso
);
467 ctx
->delete_vs_state(ctx
, vs
);
468 ctx
->delete_fs_state(ctx
, fs
);
469 pipe_resource_reference(&cb
, NULL
);
471 util_report_result(pass
);
475 null_fragment_shader(struct pipe_context
*ctx
)
477 struct cso_context
*cso
;
478 struct pipe_resource
*cb
;
480 struct pipe_rasterizer_state rs
= {0};
481 struct pipe_query
*query
;
482 union pipe_query_result qresult
;
484 cso
= cso_create_context(ctx
, 0);
485 cb
= util_create_texture2d(ctx
->screen
, 256, 256,
486 PIPE_FORMAT_R8G8B8A8_UNORM
, 0);
487 util_set_common_states_and_clear(cso
, ctx
, cb
);
489 /* No rasterization. */
490 rs
.rasterizer_discard
= 1;
491 cso_set_rasterizer(cso
, &rs
);
493 vs
= util_set_passthrough_vertex_shader(cso
, ctx
, false);
495 query
= ctx
->create_query(ctx
, PIPE_QUERY_PRIMITIVES_GENERATED
, 0);
496 ctx
->begin_query(ctx
, query
);
497 util_draw_fullscreen_quad(cso
);
498 ctx
->end_query(ctx
, query
);
499 ctx
->get_query_result(ctx
, query
, true, &qresult
);
502 cso_destroy_context(cso
);
503 ctx
->delete_vs_state(ctx
, vs
);
504 ctx
->destroy_query(ctx
, query
);
505 pipe_resource_reference(&cb
, NULL
);
507 /* Check PRIMITIVES_GENERATED. */
508 util_report_result(qresult
.u64
== 2);
511 #if defined(PIPE_OS_LINUX) && defined(HAVE_LIBDRM)
514 #define sync_merge(str, fd1, fd2) (-1)
515 #define sync_wait(fd, timeout) (-1)
519 test_sync_file_fences(struct pipe_context
*ctx
)
521 struct pipe_screen
*screen
= ctx
->screen
;
523 enum pipe_fd_type fd_type
= PIPE_FD_TYPE_NATIVE_SYNC
;
525 if (!screen
->get_param(screen
, PIPE_CAP_NATIVE_FENCE_FD
))
528 struct cso_context
*cso
= cso_create_context(ctx
, 0);
529 struct pipe_resource
*buf
=
530 pipe_buffer_create(screen
, 0, PIPE_USAGE_DEFAULT
, 1024 * 1024);
531 struct pipe_resource
*tex
=
532 util_create_texture2d(screen
, 4096, 1024, PIPE_FORMAT_R8_UNORM
, 0);
533 struct pipe_fence_handle
*buf_fence
= NULL
, *tex_fence
= NULL
;
535 /* Run 2 clears, get fencess. */
537 ctx
->clear_buffer(ctx
, buf
, 0, buf
->width0
, &value
, sizeof(value
));
538 ctx
->flush(ctx
, &buf_fence
, PIPE_FLUSH_FENCE_FD
);
541 u_box_2d(0, 0, tex
->width0
, tex
->height0
, &box
);
542 ctx
->clear_texture(ctx
, tex
, 0, &box
, &value
);
543 ctx
->flush(ctx
, &tex_fence
, PIPE_FLUSH_FENCE_FD
);
544 pass
= pass
&& buf_fence
&& tex_fence
;
547 int buf_fd
= screen
->fence_get_fd(screen
, buf_fence
);
548 int tex_fd
= screen
->fence_get_fd(screen
, tex_fence
);
549 pass
= pass
&& buf_fd
>= 0 && tex_fd
>= 0;
552 int merged_fd
= sync_merge("test", buf_fd
, tex_fd
);
553 pass
= pass
&& merged_fd
>= 0;
555 /* (Re)import all fences. */
556 struct pipe_fence_handle
*re_buf_fence
= NULL
, *re_tex_fence
= NULL
;
557 struct pipe_fence_handle
*merged_fence
= NULL
;
558 ctx
->create_fence_fd(ctx
, &re_buf_fence
, buf_fd
, fd_type
);
559 ctx
->create_fence_fd(ctx
, &re_tex_fence
, tex_fd
, fd_type
);
560 ctx
->create_fence_fd(ctx
, &merged_fence
, merged_fd
, fd_type
);
561 pass
= pass
&& re_buf_fence
&& re_tex_fence
&& merged_fence
;
563 /* Run another clear after waiting for everything. */
564 struct pipe_fence_handle
*final_fence
= NULL
;
565 ctx
->fence_server_sync(ctx
, merged_fence
);
567 ctx
->clear_buffer(ctx
, buf
, 0, buf
->width0
, &value
, sizeof(value
));
568 ctx
->flush(ctx
, &final_fence
, PIPE_FLUSH_FENCE_FD
);
569 pass
= pass
&& final_fence
;
571 /* Wait for the last fence. */
572 int final_fd
= screen
->fence_get_fd(screen
, final_fence
);
573 pass
= pass
&& final_fd
>= 0;
574 pass
= pass
&& sync_wait(final_fd
, -1) == 0;
576 /* Check that all fences are signalled. */
577 pass
= pass
&& sync_wait(buf_fd
, 0) == 0;
578 pass
= pass
&& sync_wait(tex_fd
, 0) == 0;
579 pass
= pass
&& sync_wait(merged_fd
, 0) == 0;
581 pass
= pass
&& screen
->fence_finish(screen
, NULL
, buf_fence
, 0);
582 pass
= pass
&& screen
->fence_finish(screen
, NULL
, tex_fence
, 0);
583 pass
= pass
&& screen
->fence_finish(screen
, NULL
, re_buf_fence
, 0);
584 pass
= pass
&& screen
->fence_finish(screen
, NULL
, re_tex_fence
, 0);
585 pass
= pass
&& screen
->fence_finish(screen
, NULL
, merged_fence
, 0);
586 pass
= pass
&& screen
->fence_finish(screen
, NULL
, final_fence
, 0);
589 #ifndef PIPE_OS_WINDOWS
600 screen
->fence_reference(screen
, &buf_fence
, NULL
);
601 screen
->fence_reference(screen
, &tex_fence
, NULL
);
602 screen
->fence_reference(screen
, &re_buf_fence
, NULL
);
603 screen
->fence_reference(screen
, &re_tex_fence
, NULL
);
604 screen
->fence_reference(screen
, &merged_fence
, NULL
);
605 screen
->fence_reference(screen
, &final_fence
, NULL
);
607 cso_destroy_context(cso
);
608 pipe_resource_reference(&buf
, NULL
);
609 pipe_resource_reference(&tex
, NULL
);
611 util_report_result(pass
);
615 test_texture_barrier(struct pipe_context
*ctx
, bool use_fbfetch
,
616 unsigned num_samples
)
618 struct cso_context
*cso
;
619 struct pipe_resource
*cb
;
620 struct pipe_sampler_view
*view
= NULL
;
624 assert(num_samples
>= 1 && num_samples
<= 8);
626 util_snprintf(name
, sizeof(name
), "%s: %s, %u samples", __func__
,
627 use_fbfetch
? "FBFETCH" : "sampler", MAX2(num_samples
, 1));
629 if (!ctx
->screen
->get_param(ctx
->screen
, PIPE_CAP_TEXTURE_BARRIER
)) {
630 util_report_result_helper(SKIP
, name
);
634 !ctx
->screen
->get_param(ctx
->screen
, PIPE_CAP_TGSI_FS_FBFETCH
)) {
635 util_report_result_helper(SKIP
, name
);
639 cso
= cso_create_context(ctx
, 0);
640 cb
= util_create_texture2d(ctx
->screen
, 256, 256,
641 PIPE_FORMAT_R8G8B8A8_UNORM
, num_samples
);
642 util_set_common_states_and_clear(cso
, ctx
, cb
);
644 /* Clear each sample to a different value. */
645 if (num_samples
> 1) {
647 util_make_fragment_passthrough_shader(ctx
, TGSI_SEMANTIC_GENERIC
,
648 TGSI_INTERPOLATE_LINEAR
, TRUE
);
649 cso_set_fragment_shader_handle(cso
, fs
);
652 void *vs
= util_set_passthrough_vertex_shader(cso
, ctx
, false);
654 for (unsigned i
= 0; i
< num_samples
/ 2; i
++) {
657 /* 2 consecutive samples should have the same color to test MSAA
658 * compression properly.
660 if (num_samples
== 2) {
663 /* The average value must be 0.1 */
664 static const float values
[] = {
670 ctx
->set_sample_mask(ctx
, 0x3 << (i
* 2));
671 util_draw_fullscreen_quad_fill(cso
, value
, value
, value
, value
);
673 ctx
->set_sample_mask(ctx
, ~0);
675 cso_set_vertex_shader_handle(cso
, NULL
);
676 cso_set_fragment_shader_handle(cso
, NULL
);
677 ctx
->delete_vs_state(ctx
, vs
);
678 ctx
->delete_fs_state(ctx
, fs
);
682 /* Fragment shader. */
684 "DCL OUT[0], COLOR[0]\n"
686 "IMM[0] FLT32 { 0.1, 0.2, 0.3, 0.4}\n"
688 "FBFETCH TEMP[0], OUT[0]\n"
689 "ADD OUT[0], TEMP[0], IMM[0]\n"
692 struct pipe_sampler_view templ
= {{0}};
693 templ
.format
= cb
->format
;
694 templ
.target
= cb
->target
;
695 templ
.swizzle_r
= PIPE_SWIZZLE_X
;
696 templ
.swizzle_g
= PIPE_SWIZZLE_Y
;
697 templ
.swizzle_b
= PIPE_SWIZZLE_Z
;
698 templ
.swizzle_a
= PIPE_SWIZZLE_W
;
699 view
= ctx
->create_sampler_view(ctx
, cb
, &templ
);
700 ctx
->set_sampler_views(ctx
, PIPE_SHADER_FRAGMENT
, 0, 1, &view
);
702 /* Fragment shader. */
703 if (num_samples
> 1) {
705 "DCL SV[0], POSITION\n"
706 "DCL SV[1], SAMPLEID\n"
708 "DCL SVIEW[0], 2D_MSAA, FLOAT\n"
709 "DCL OUT[0], COLOR[0]\n"
711 "IMM[0] FLT32 { 0.1, 0.2, 0.3, 0.4}\n"
713 "F2I TEMP[0].xy, SV[0].xyyy\n"
714 "MOV TEMP[0].w, SV[1].xxxx\n"
715 "TXF TEMP[0], TEMP[0], SAMP[0], 2D_MSAA\n"
716 "ADD OUT[0], TEMP[0], IMM[0]\n"
720 "DCL SV[0], POSITION\n"
722 "DCL SVIEW[0], 2D, FLOAT\n"
723 "DCL OUT[0], COLOR[0]\n"
725 "IMM[0] FLT32 { 0.1, 0.2, 0.3, 0.4}\n"
726 "IMM[1] INT32 { 0, 0, 0, 0}\n"
728 "F2I TEMP[0].xy, SV[0].xyyy\n"
729 "MOV TEMP[0].zw, IMM[1]\n"
730 "TXF TEMP[0], TEMP[0], SAMP[0], 2D\n"
731 "ADD OUT[0], TEMP[0], IMM[0]\n"
736 struct tgsi_token tokens
[1000];
737 struct pipe_shader_state state
;
739 if (!tgsi_text_translate(text
, tokens
, ARRAY_SIZE(tokens
))) {
741 util_report_result_helper(FAIL
, name
);
744 pipe_shader_state_from_tgsi(&state
, tokens
);
746 void *fs
= ctx
->create_fs_state(ctx
, &state
);
747 cso_set_fragment_shader_handle(cso
, fs
);
750 void *vs
= util_set_passthrough_vertex_shader(cso
, ctx
, false);
752 if (num_samples
> 1 && !use_fbfetch
)
753 ctx
->set_min_samples(ctx
, num_samples
);
755 for (int i
= 0; i
< 2; i
++) {
756 ctx
->texture_barrier(ctx
,
757 use_fbfetch
? PIPE_TEXTURE_BARRIER_FRAMEBUFFER
:
758 PIPE_TEXTURE_BARRIER_SAMPLER
);
759 util_draw_fullscreen_quad(cso
);
761 if (num_samples
> 1 && !use_fbfetch
)
762 ctx
->set_min_samples(ctx
, 1);
767 * result = 0.1 (clear) + (0.1, 0.2, 0.3, 0.4) * 2 = (0.3, 0.5, 0.7, 0.9)
770 * sample0 = 0.0 (clear) + (0.1, 0.2, 0.3, 0.4) * 2 = (0.2, 0.4, 0.6, 0.8)
772 * sample2 = 0.2 (clear) + (0.1, 0.2, 0.3, 0.4) * 2 = (0.4, 0.6, 0.8, 1.0)
774 * resolved = sum(sample[0:3]) / 4 = (0.3, 0.5, 0.7, 0.9)
776 static const float expected
[] = {0.3, 0.5, 0.7, 0.9};
777 bool pass
= util_probe_rect_rgba(ctx
, cb
, 0, 0,
778 cb
->width0
, cb
->height0
, expected
);
781 cso_destroy_context(cso
);
782 ctx
->delete_vs_state(ctx
, vs
);
783 ctx
->delete_fs_state(ctx
, fs
);
784 pipe_sampler_view_reference(&view
, NULL
);
785 pipe_resource_reference(&cb
, NULL
);
787 util_report_result_helper(pass
, name
);
791 test_compute_clear_image(struct pipe_context
*ctx
)
793 struct cso_context
*cso
;
794 struct pipe_resource
*cb
;
795 struct pipe_sampler_view
*view
= NULL
;
798 cso
= cso_create_context(ctx
, 0);
799 cb
= util_create_texture2d(ctx
->screen
, 256, 256,
800 PIPE_FORMAT_R8G8B8A8_UNORM
, 1);
802 /* Compute shader. */
804 "PROPERTY CS_FIXED_BLOCK_WIDTH 8\n"
805 "PROPERTY CS_FIXED_BLOCK_HEIGHT 8\n"
806 "PROPERTY CS_FIXED_BLOCK_DEPTH 1\n"
807 "DCL SV[0], THREAD_ID\n"
808 "DCL SV[1], BLOCK_ID\n"
809 "DCL IMAGE[0], 2D, PIPE_FORMAT_R8G8B8A8_UNORM, WR\n"
811 "IMM[0] UINT32 { 8, 8, 0, 0}\n"
812 "IMM[1] FLT32 { 1, 0, 0, 0}\n"
814 /* TEMP[0].xy = SV[1] * IMM[0] + SV[0]; */
815 "UMAD TEMP[0].xy, SV[1], IMM[0], SV[0]\n"
816 "STORE IMAGE[0], TEMP[0], IMM[1], 2D, PIPE_FORMAT_R8G8B8A8_UNORM\n"
819 struct tgsi_token tokens
[1000];
820 if (!tgsi_text_translate(text
, tokens
, ARRAY_SIZE(tokens
))) {
822 util_report_result(FAIL
);
826 struct pipe_compute_state state
= {};
827 state
.ir_type
= PIPE_SHADER_IR_TGSI
;
830 void *compute_shader
= ctx
->create_compute_state(ctx
, &state
);
831 cso_set_compute_shader_handle(cso
, compute_shader
);
833 /* Bind the image. */
834 struct pipe_image_view image
= {};
836 image
.shader_access
= image
.access
= PIPE_IMAGE_ACCESS_READ_WRITE
;
837 image
.format
= cb
->format
;
839 ctx
->set_shader_images(ctx
, PIPE_SHADER_COMPUTE
, 0, 1, &image
);
841 /* Dispatch compute. */
842 struct pipe_grid_info info
= {};
846 info
.grid
[0] = cb
->width0
/ 8;
847 info
.grid
[1] = cb
->height0
/ 8;
850 ctx
->launch_grid(ctx
, &info
);
853 static const float expected
[] = {1.0, 0.0, 0.0, 0.0};
854 bool pass
= util_probe_rect_rgba(ctx
, cb
, 0, 0,
855 cb
->width0
, cb
->height0
, expected
);
858 cso_destroy_context(cso
);
859 ctx
->delete_compute_state(ctx
, compute_shader
);
860 pipe_resource_reference(&cb
, NULL
);
862 util_report_result(pass
);
866 * Run all tests. This should be run with a clean context after
870 util_run_tests(struct pipe_screen
*screen
)
872 struct pipe_context
*ctx
= screen
->context_create(screen
, NULL
, 0);
874 null_fragment_shader(ctx
);
875 tgsi_vs_window_space_position(ctx
);
876 null_sampler_view(ctx
, TGSI_TEXTURE_2D
);
877 null_sampler_view(ctx
, TGSI_TEXTURE_BUFFER
);
878 util_test_constant_buffer(ctx
, NULL
);
879 test_sync_file_fences(ctx
);
881 for (int i
= 1; i
<= 8; i
= i
* 2)
882 test_texture_barrier(ctx
, false, i
);
883 for (int i
= 1; i
<= 8; i
= i
* 2)
884 test_texture_barrier(ctx
, true, i
);
886 test_compute_clear_image(ctx
);
890 puts("Done. Exiting..");