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
.format
= format
;
59 templ
.usage
= PIPE_USAGE_DEFAULT
;
60 templ
.bind
= PIPE_BIND_SAMPLER_VIEW
|
61 (util_format_is_depth_or_stencil(format
) ?
62 PIPE_BIND_DEPTH_STENCIL
: PIPE_BIND_RENDER_TARGET
);
64 return screen
->resource_create(screen
, &templ
);
68 util_set_framebuffer_cb0(struct cso_context
*cso
, struct pipe_context
*ctx
,
69 struct pipe_resource
*tex
)
71 struct pipe_surface templ
= {{0}}, *surf
;
72 struct pipe_framebuffer_state fb
= {0};
74 templ
.format
= tex
->format
;
75 surf
= ctx
->create_surface(ctx
, tex
, &templ
);
77 fb
.width
= tex
->width0
;
78 fb
.height
= tex
->height0
;
82 cso_set_framebuffer(cso
, &fb
);
83 pipe_surface_reference(&surf
, NULL
);
87 util_set_blend_normal(struct cso_context
*cso
)
89 struct pipe_blend_state blend
= {0};
91 blend
.rt
[0].colormask
= PIPE_MASK_RGBA
;
92 cso_set_blend(cso
, &blend
);
96 util_set_dsa_disable(struct cso_context
*cso
)
98 struct pipe_depth_stencil_alpha_state dsa
= {{0}};
100 cso_set_depth_stencil_alpha(cso
, &dsa
);
104 util_set_rasterizer_normal(struct cso_context
*cso
)
106 struct pipe_rasterizer_state rs
= {0};
108 rs
.half_pixel_center
= 1;
109 rs
.bottom_edge_rule
= 1;
112 cso_set_rasterizer(cso
, &rs
);
116 util_set_max_viewport(struct cso_context
*cso
, struct pipe_resource
*tex
)
118 struct pipe_viewport_state viewport
;
120 viewport
.scale
[0] = 0.5f
* tex
->width0
;
121 viewport
.scale
[1] = 0.5f
* tex
->height0
;
122 viewport
.scale
[2] = 1.0f
;
123 viewport
.translate
[0] = 0.5f
* tex
->width0
;
124 viewport
.translate
[1] = 0.5f
* tex
->height0
;
125 viewport
.translate
[2] = 0.0f
;
127 cso_set_viewport(cso
, &viewport
);
131 util_set_interleaved_vertex_elements(struct cso_context
*cso
,
132 unsigned num_elements
)
135 struct pipe_vertex_element
*velem
=
136 calloc(1, num_elements
* sizeof(struct pipe_vertex_element
));
138 for (i
= 0; i
< num_elements
; i
++) {
139 velem
[i
].src_format
= PIPE_FORMAT_R32G32B32A32_FLOAT
;
140 velem
[i
].src_offset
= i
* 16;
143 cso_set_vertex_elements(cso
, num_elements
, velem
);
148 util_set_passthrough_vertex_shader(struct cso_context
*cso
,
149 struct pipe_context
*ctx
,
152 static const enum tgsi_semantic vs_attribs
[] = {
153 TGSI_SEMANTIC_POSITION
,
154 TGSI_SEMANTIC_GENERIC
156 static const uint vs_indices
[] = {0, 0};
159 vs
= util_make_vertex_passthrough_shader(ctx
, 2, vs_attribs
, vs_indices
,
161 cso_set_vertex_shader_handle(cso
, vs
);
166 util_set_common_states_and_clear(struct cso_context
*cso
, struct pipe_context
*ctx
,
167 struct pipe_resource
*cb
)
169 static const float clear_color
[] = {0.1, 0.1, 0.1, 0.1};
171 util_set_framebuffer_cb0(cso
, ctx
, cb
);
172 util_set_blend_normal(cso
);
173 util_set_dsa_disable(cso
);
174 util_set_rasterizer_normal(cso
);
175 util_set_max_viewport(cso
, cb
);
177 ctx
->clear(ctx
, PIPE_CLEAR_COLOR0
, (void*)clear_color
, 0, 0);
181 util_draw_fullscreen_quad(struct cso_context
*cso
)
183 static float vertices
[] = {
184 -1, -1, 0, 1, 0, 0, 0, 0,
185 -1, 1, 0, 1, 0, 1, 0, 0,
186 1, 1, 0, 1, 1, 1, 0, 0,
187 1, -1, 0, 1, 1, 0, 0, 0
189 util_set_interleaved_vertex_elements(cso
, 2);
190 util_draw_user_vertex_buffer(cso
, vertices
, PIPE_PRIM_QUADS
, 4, 2);
194 util_draw_fullscreen_quad_fill(struct cso_context
*cso
,
195 float r
, float g
, float b
, float a
)
198 -1, -1, 0, 1, r
, g
, b
, a
,
199 -1, 1, 0, 1, r
, g
, b
, a
,
200 1, 1, 0, 1, r
, g
, b
, a
,
201 1, -1, 0, 1, r
, g
, b
, a
,
203 util_set_interleaved_vertex_elements(cso
, 2);
204 util_draw_user_vertex_buffer(cso
, vertices
, PIPE_PRIM_QUADS
, 4, 2);
208 * Probe and test if the rectangle contains the expected color.
210 * If "num_expected_colors" > 1, at least one expected color must match
211 * the probed color. "expected" should be an array of 4*num_expected_colors
215 util_probe_rect_rgba_multi(struct pipe_context
*ctx
, struct pipe_resource
*tex
,
216 unsigned offx
, unsigned offy
, unsigned w
,
218 const float *expected
,
219 unsigned num_expected_colors
)
221 struct pipe_transfer
*transfer
;
223 float *pixels
= malloc(w
* h
* 4 * sizeof(float));
227 map
= pipe_transfer_map(ctx
, tex
, 0, 0, PIPE_TRANSFER_READ
,
228 offx
, offy
, w
, h
, &transfer
);
229 pipe_get_tile_rgba(transfer
, map
, 0, 0, w
, h
, pixels
);
230 pipe_transfer_unmap(ctx
, transfer
);
232 for (e
= 0; e
< num_expected_colors
; e
++) {
233 for (y
= 0; y
< h
; y
++) {
234 for (x
= 0; x
< w
; x
++) {
235 float *probe
= &pixels
[(y
*w
+ x
)*4];
237 for (c
= 0; c
< 4; c
++) {
238 if (fabs(probe
[c
] - expected
[e
*4+c
]) >= TOLERANCE
) {
239 if (e
< num_expected_colors
-1)
240 goto next_color
; /* test the next expected color */
242 printf("Probe color at (%i,%i), ", offx
+x
, offy
+y
);
243 printf("Expected: %.3f, %.3f, %.3f, %.3f, ",
244 expected
[e
*4], expected
[e
*4+1],
245 expected
[e
*4+2], expected
[e
*4+3]);
246 printf("Got: %.3f, %.3f, %.3f, %.3f\n",
247 probe
[0], probe
[1], probe
[2], probe
[3]);
254 break; /* this color was successful */
265 util_probe_rect_rgba(struct pipe_context
*ctx
, struct pipe_resource
*tex
,
266 unsigned offx
, unsigned offy
, unsigned w
, unsigned h
,
267 const float *expected
)
269 return util_probe_rect_rgba_multi(ctx
, tex
, offx
, offy
, w
, h
, expected
, 1);
274 FAIL
= 0, /* also "false" */
275 PASS
= 1 /* also "true" */
279 util_report_result_helper(int status
, const char *name
, ...)
285 util_vsnprintf(buf
, sizeof(buf
), name
, ap
);
288 printf("Test(%s) = %s\n", buf
,
289 status
== SKIP
? "skip" :
290 status
== PASS
? "pass" : "fail");
293 #define util_report_result(status) util_report_result_helper(status, __func__)
296 * Test TGSI_PROPERTY_VS_WINDOW_SPACE_POSITION.
298 * The viewport state is set as usual, but it should have no effect.
299 * Clipping should also be disabled.
301 * POSITION.xyz should already be multiplied by 1/w and POSITION.w should
302 * contain 1/w. By setting w=0, we can test that POSITION.xyz isn't
303 * multiplied by 1/w (otherwise nothing would be rendered).
305 * TODO: Whether the value of POSITION.w is correctly interpreted as 1/w
306 * during perspective interpolation is not tested.
309 tgsi_vs_window_space_position(struct pipe_context
*ctx
)
311 struct cso_context
*cso
;
312 struct pipe_resource
*cb
;
315 static const float red
[] = {1, 0, 0, 1};
317 if (!ctx
->screen
->get_param(ctx
->screen
,
318 PIPE_CAP_TGSI_VS_WINDOW_SPACE_POSITION
)) {
319 util_report_result(SKIP
);
323 cso
= cso_create_context(ctx
, 0);
324 cb
= util_create_texture2d(ctx
->screen
, 256, 256,
325 PIPE_FORMAT_R8G8B8A8_UNORM
, 0);
326 util_set_common_states_and_clear(cso
, ctx
, cb
);
328 /* Fragment shader. */
329 fs
= util_make_fragment_passthrough_shader(ctx
, TGSI_SEMANTIC_GENERIC
,
330 TGSI_INTERPOLATE_LINEAR
, TRUE
);
331 cso_set_fragment_shader_handle(cso
, fs
);
334 vs
= util_set_passthrough_vertex_shader(cso
, ctx
, true);
338 static float vertices
[] = {
339 0, 0, 0, 0, 1, 0, 0, 1,
340 0, 256, 0, 0, 1, 0, 0, 1,
341 256, 256, 0, 0, 1, 0, 0, 1,
342 256, 0, 0, 0, 1, 0, 0, 1,
344 util_set_interleaved_vertex_elements(cso
, 2);
345 util_draw_user_vertex_buffer(cso
, vertices
, PIPE_PRIM_QUADS
, 4, 2);
349 pass
= pass
&& util_probe_rect_rgba(ctx
, cb
, 0, 0,
350 cb
->width0
, cb
->height0
, red
);
353 cso_destroy_context(cso
);
354 ctx
->delete_vs_state(ctx
, vs
);
355 ctx
->delete_fs_state(ctx
, fs
);
356 pipe_resource_reference(&cb
, NULL
);
358 util_report_result(pass
);
362 null_sampler_view(struct pipe_context
*ctx
, unsigned tgsi_tex_target
)
364 struct cso_context
*cso
;
365 struct pipe_resource
*cb
;
368 /* 2 expected colors: */
369 static const float expected_tex
[] = {0, 0, 0, 1,
371 static const float expected_buf
[] = {0, 0, 0, 0};
372 const float *expected
= tgsi_tex_target
== TGSI_TEXTURE_BUFFER
?
373 expected_buf
: expected_tex
;
374 unsigned num_expected
= tgsi_tex_target
== TGSI_TEXTURE_BUFFER
? 1 : 2;
376 if (tgsi_tex_target
== TGSI_TEXTURE_BUFFER
&&
377 !ctx
->screen
->get_param(ctx
->screen
, PIPE_CAP_TEXTURE_BUFFER_OBJECTS
)) {
378 util_report_result_helper(SKIP
, "%s: %s", __func__
,
379 tgsi_texture_names
[tgsi_tex_target
]);
383 cso
= cso_create_context(ctx
, 0);
384 cb
= util_create_texture2d(ctx
->screen
, 256, 256,
385 PIPE_FORMAT_R8G8B8A8_UNORM
, 0);
386 util_set_common_states_and_clear(cso
, ctx
, cb
);
388 ctx
->set_sampler_views(ctx
, PIPE_SHADER_FRAGMENT
, 0, 1, NULL
);
390 /* Fragment shader. */
391 fs
= util_make_fragment_tex_shader(ctx
, tgsi_tex_target
,
392 TGSI_INTERPOLATE_LINEAR
,
393 TGSI_RETURN_TYPE_FLOAT
,
394 TGSI_RETURN_TYPE_FLOAT
, false, false);
395 cso_set_fragment_shader_handle(cso
, fs
);
398 vs
= util_set_passthrough_vertex_shader(cso
, ctx
, false);
399 util_draw_fullscreen_quad(cso
);
402 pass
= pass
&& util_probe_rect_rgba_multi(ctx
, cb
, 0, 0,
403 cb
->width0
, cb
->height0
, expected
,
407 cso_destroy_context(cso
);
408 ctx
->delete_vs_state(ctx
, vs
);
409 ctx
->delete_fs_state(ctx
, fs
);
410 pipe_resource_reference(&cb
, NULL
);
412 util_report_result_helper(pass
, "%s: %s", __func__
,
413 tgsi_texture_names
[tgsi_tex_target
]);
417 util_test_constant_buffer(struct pipe_context
*ctx
,
418 struct pipe_resource
*constbuf
)
420 struct cso_context
*cso
;
421 struct pipe_resource
*cb
;
424 static const float zero
[] = {0, 0, 0, 0};
426 cso
= cso_create_context(ctx
, 0);
427 cb
= util_create_texture2d(ctx
->screen
, 256, 256,
428 PIPE_FORMAT_R8G8B8A8_UNORM
, 0);
429 util_set_common_states_and_clear(cso
, ctx
, cb
);
431 pipe_set_constant_buffer(ctx
, PIPE_SHADER_FRAGMENT
, 0, constbuf
);
433 /* Fragment shader. */
435 static const char *text
= /* I don't like ureg... */
438 "DCL OUT[0], COLOR\n"
440 "MOV OUT[0], CONST[0][0]\n"
442 struct tgsi_token tokens
[1000];
443 struct pipe_shader_state state
;
445 if (!tgsi_text_translate(text
, tokens
, ARRAY_SIZE(tokens
))) {
446 puts("Can't compile a fragment shader.");
447 util_report_result(FAIL
);
450 pipe_shader_state_from_tgsi(&state
, tokens
);
451 fs
= ctx
->create_fs_state(ctx
, &state
);
452 cso_set_fragment_shader_handle(cso
, fs
);
456 vs
= util_set_passthrough_vertex_shader(cso
, ctx
, false);
457 util_draw_fullscreen_quad(cso
);
460 pass
= pass
&& util_probe_rect_rgba(ctx
, cb
, 0, 0, cb
->width0
,
464 cso_destroy_context(cso
);
465 ctx
->delete_vs_state(ctx
, vs
);
466 ctx
->delete_fs_state(ctx
, fs
);
467 pipe_resource_reference(&cb
, NULL
);
469 util_report_result(pass
);
473 null_fragment_shader(struct pipe_context
*ctx
)
475 struct cso_context
*cso
;
476 struct pipe_resource
*cb
;
478 struct pipe_rasterizer_state rs
= {0};
479 struct pipe_query
*query
;
480 union pipe_query_result qresult
;
482 cso
= cso_create_context(ctx
, 0);
483 cb
= util_create_texture2d(ctx
->screen
, 256, 256,
484 PIPE_FORMAT_R8G8B8A8_UNORM
, 0);
485 util_set_common_states_and_clear(cso
, ctx
, cb
);
487 /* No rasterization. */
488 rs
.rasterizer_discard
= 1;
489 cso_set_rasterizer(cso
, &rs
);
491 vs
= util_set_passthrough_vertex_shader(cso
, ctx
, false);
493 query
= ctx
->create_query(ctx
, PIPE_QUERY_PRIMITIVES_GENERATED
, 0);
494 ctx
->begin_query(ctx
, query
);
495 util_draw_fullscreen_quad(cso
);
496 ctx
->end_query(ctx
, query
);
497 ctx
->get_query_result(ctx
, query
, true, &qresult
);
500 cso_destroy_context(cso
);
501 ctx
->delete_vs_state(ctx
, vs
);
502 ctx
->destroy_query(ctx
, query
);
503 pipe_resource_reference(&cb
, NULL
);
505 /* Check PRIMITIVES_GENERATED. */
506 util_report_result(qresult
.u64
== 2);
509 #if defined(PIPE_OS_LINUX) && defined(HAVE_LIBDRM)
512 #define sync_merge(str, fd1, fd2) (-1)
513 #define sync_wait(fd, timeout) (-1)
517 test_sync_file_fences(struct pipe_context
*ctx
)
519 struct pipe_screen
*screen
= ctx
->screen
;
521 enum pipe_fd_type fd_type
= PIPE_FD_TYPE_NATIVE_SYNC
;
523 if (!screen
->get_param(screen
, PIPE_CAP_NATIVE_FENCE_FD
))
526 struct cso_context
*cso
= cso_create_context(ctx
, 0);
527 struct pipe_resource
*buf
=
528 pipe_buffer_create(screen
, 0, PIPE_USAGE_DEFAULT
, 1024 * 1024);
529 struct pipe_resource
*tex
=
530 util_create_texture2d(screen
, 4096, 1024, PIPE_FORMAT_R8_UNORM
, 0);
531 struct pipe_fence_handle
*buf_fence
= NULL
, *tex_fence
= NULL
;
533 /* Run 2 clears, get fencess. */
535 ctx
->clear_buffer(ctx
, buf
, 0, buf
->width0
, &value
, sizeof(value
));
536 ctx
->flush(ctx
, &buf_fence
, PIPE_FLUSH_FENCE_FD
);
539 u_box_2d(0, 0, tex
->width0
, tex
->height0
, &box
);
540 ctx
->clear_texture(ctx
, tex
, 0, &box
, &value
);
541 ctx
->flush(ctx
, &tex_fence
, PIPE_FLUSH_FENCE_FD
);
542 pass
= pass
&& buf_fence
&& tex_fence
;
545 int buf_fd
= screen
->fence_get_fd(screen
, buf_fence
);
546 int tex_fd
= screen
->fence_get_fd(screen
, tex_fence
);
547 pass
= pass
&& buf_fd
>= 0 && tex_fd
>= 0;
550 int merged_fd
= sync_merge("test", buf_fd
, tex_fd
);
551 pass
= pass
&& merged_fd
>= 0;
553 /* (Re)import all fences. */
554 struct pipe_fence_handle
*re_buf_fence
= NULL
, *re_tex_fence
= NULL
;
555 struct pipe_fence_handle
*merged_fence
= NULL
;
556 ctx
->create_fence_fd(ctx
, &re_buf_fence
, buf_fd
, fd_type
);
557 ctx
->create_fence_fd(ctx
, &re_tex_fence
, tex_fd
, fd_type
);
558 ctx
->create_fence_fd(ctx
, &merged_fence
, merged_fd
, fd_type
);
559 pass
= pass
&& re_buf_fence
&& re_tex_fence
&& merged_fence
;
561 /* Run another clear after waiting for everything. */
562 struct pipe_fence_handle
*final_fence
= NULL
;
563 ctx
->fence_server_sync(ctx
, merged_fence
);
565 ctx
->clear_buffer(ctx
, buf
, 0, buf
->width0
, &value
, sizeof(value
));
566 ctx
->flush(ctx
, &final_fence
, PIPE_FLUSH_FENCE_FD
);
567 pass
= pass
&& final_fence
;
569 /* Wait for the last fence. */
570 int final_fd
= screen
->fence_get_fd(screen
, final_fence
);
571 pass
= pass
&& final_fd
>= 0;
572 pass
= pass
&& sync_wait(final_fd
, -1) == 0;
574 /* Check that all fences are signalled. */
575 pass
= pass
&& sync_wait(buf_fd
, 0) == 0;
576 pass
= pass
&& sync_wait(tex_fd
, 0) == 0;
577 pass
= pass
&& sync_wait(merged_fd
, 0) == 0;
579 pass
= pass
&& screen
->fence_finish(screen
, NULL
, buf_fence
, 0);
580 pass
= pass
&& screen
->fence_finish(screen
, NULL
, tex_fence
, 0);
581 pass
= pass
&& screen
->fence_finish(screen
, NULL
, re_buf_fence
, 0);
582 pass
= pass
&& screen
->fence_finish(screen
, NULL
, re_tex_fence
, 0);
583 pass
= pass
&& screen
->fence_finish(screen
, NULL
, merged_fence
, 0);
584 pass
= pass
&& screen
->fence_finish(screen
, NULL
, final_fence
, 0);
587 #ifndef PIPE_OS_WINDOWS
598 screen
->fence_reference(screen
, &buf_fence
, NULL
);
599 screen
->fence_reference(screen
, &tex_fence
, NULL
);
600 screen
->fence_reference(screen
, &re_buf_fence
, NULL
);
601 screen
->fence_reference(screen
, &re_tex_fence
, NULL
);
602 screen
->fence_reference(screen
, &merged_fence
, NULL
);
603 screen
->fence_reference(screen
, &final_fence
, NULL
);
605 cso_destroy_context(cso
);
606 pipe_resource_reference(&buf
, NULL
);
607 pipe_resource_reference(&tex
, NULL
);
609 util_report_result(pass
);
613 test_texture_barrier(struct pipe_context
*ctx
, bool use_fbfetch
,
614 unsigned num_samples
)
616 struct cso_context
*cso
;
617 struct pipe_resource
*cb
;
618 struct pipe_sampler_view
*view
= NULL
;
622 assert(num_samples
>= 1 && num_samples
<= 8);
624 snprintf(name
, sizeof(name
), "%s: %s, %u samples", __func__
,
625 use_fbfetch
? "FBFETCH" : "sampler", MAX2(num_samples
, 1));
627 if (!ctx
->screen
->get_param(ctx
->screen
, PIPE_CAP_TEXTURE_BARRIER
)) {
628 util_report_result_helper(SKIP
, name
);
632 !ctx
->screen
->get_param(ctx
->screen
, PIPE_CAP_TGSI_FS_FBFETCH
)) {
633 util_report_result_helper(SKIP
, name
);
637 cso
= cso_create_context(ctx
, 0);
638 cb
= util_create_texture2d(ctx
->screen
, 256, 256,
639 PIPE_FORMAT_R8G8B8A8_UNORM
, num_samples
);
640 util_set_common_states_and_clear(cso
, ctx
, cb
);
642 /* Clear each sample to a different value. */
643 if (num_samples
> 1) {
645 util_make_fragment_passthrough_shader(ctx
, TGSI_SEMANTIC_GENERIC
,
646 TGSI_INTERPOLATE_LINEAR
, TRUE
);
647 cso_set_fragment_shader_handle(cso
, fs
);
650 void *vs
= util_set_passthrough_vertex_shader(cso
, ctx
, false);
652 for (unsigned i
= 0; i
< num_samples
/ 2; i
++) {
655 /* 2 consecutive samples should have the same color to test MSAA
656 * compression properly.
658 if (num_samples
== 2) {
661 /* The average value must be 0.1 */
662 static const float values
[] = {
668 ctx
->set_sample_mask(ctx
, 0x3 << (i
* 2));
669 util_draw_fullscreen_quad_fill(cso
, value
, value
, value
, value
);
671 ctx
->set_sample_mask(ctx
, ~0);
673 cso_set_vertex_shader_handle(cso
, NULL
);
674 cso_set_fragment_shader_handle(cso
, NULL
);
675 ctx
->delete_vs_state(ctx
, vs
);
676 ctx
->delete_fs_state(ctx
, fs
);
680 /* Fragment shader. */
682 "DCL OUT[0], COLOR[0]\n"
684 "IMM[0] FLT32 { 0.1, 0.2, 0.3, 0.4}\n"
686 "FBFETCH TEMP[0], OUT[0]\n"
687 "ADD OUT[0], TEMP[0], IMM[0]\n"
690 struct pipe_sampler_view templ
= {{0}};
691 templ
.format
= cb
->format
;
692 templ
.target
= cb
->target
;
693 templ
.swizzle_r
= PIPE_SWIZZLE_X
;
694 templ
.swizzle_g
= PIPE_SWIZZLE_Y
;
695 templ
.swizzle_b
= PIPE_SWIZZLE_Z
;
696 templ
.swizzle_a
= PIPE_SWIZZLE_W
;
697 view
= ctx
->create_sampler_view(ctx
, cb
, &templ
);
698 ctx
->set_sampler_views(ctx
, PIPE_SHADER_FRAGMENT
, 0, 1, &view
);
700 /* Fragment shader. */
701 if (num_samples
> 1) {
703 "DCL SV[0], POSITION\n"
704 "DCL SV[1], SAMPLEID\n"
706 "DCL SVIEW[0], 2D_MSAA, FLOAT\n"
707 "DCL OUT[0], COLOR[0]\n"
709 "IMM[0] FLT32 { 0.1, 0.2, 0.3, 0.4}\n"
711 "F2I TEMP[0].xy, SV[0].xyyy\n"
712 "MOV TEMP[0].w, SV[1].xxxx\n"
713 "TXF TEMP[0], TEMP[0], SAMP[0], 2D_MSAA\n"
714 "ADD OUT[0], TEMP[0], IMM[0]\n"
718 "DCL SV[0], POSITION\n"
720 "DCL SVIEW[0], 2D, FLOAT\n"
721 "DCL OUT[0], COLOR[0]\n"
723 "IMM[0] FLT32 { 0.1, 0.2, 0.3, 0.4}\n"
724 "IMM[1] INT32 { 0, 0, 0, 0}\n"
726 "F2I TEMP[0].xy, SV[0].xyyy\n"
727 "MOV TEMP[0].zw, IMM[1]\n"
728 "TXF TEMP[0], TEMP[0], SAMP[0], 2D\n"
729 "ADD OUT[0], TEMP[0], IMM[0]\n"
734 struct tgsi_token tokens
[1000];
735 struct pipe_shader_state state
;
737 if (!tgsi_text_translate(text
, tokens
, ARRAY_SIZE(tokens
))) {
739 util_report_result_helper(FAIL
, name
);
742 pipe_shader_state_from_tgsi(&state
, tokens
);
744 void *fs
= ctx
->create_fs_state(ctx
, &state
);
745 cso_set_fragment_shader_handle(cso
, fs
);
748 void *vs
= util_set_passthrough_vertex_shader(cso
, ctx
, false);
750 if (num_samples
> 1 && !use_fbfetch
)
751 ctx
->set_min_samples(ctx
, num_samples
);
753 for (int i
= 0; i
< 2; i
++) {
754 ctx
->texture_barrier(ctx
,
755 use_fbfetch
? PIPE_TEXTURE_BARRIER_FRAMEBUFFER
:
756 PIPE_TEXTURE_BARRIER_SAMPLER
);
757 util_draw_fullscreen_quad(cso
);
759 if (num_samples
> 1 && !use_fbfetch
)
760 ctx
->set_min_samples(ctx
, 1);
765 * result = 0.1 (clear) + (0.1, 0.2, 0.3, 0.4) * 2 = (0.3, 0.5, 0.7, 0.9)
768 * sample0 = 0.0 (clear) + (0.1, 0.2, 0.3, 0.4) * 2 = (0.2, 0.4, 0.6, 0.8)
770 * sample2 = 0.2 (clear) + (0.1, 0.2, 0.3, 0.4) * 2 = (0.4, 0.6, 0.8, 1.0)
772 * resolved = sum(sample[0:3]) / 4 = (0.3, 0.5, 0.7, 0.9)
774 static const float expected
[] = {0.3, 0.5, 0.7, 0.9};
775 bool pass
= util_probe_rect_rgba(ctx
, cb
, 0, 0,
776 cb
->width0
, cb
->height0
, expected
);
779 cso_destroy_context(cso
);
780 ctx
->delete_vs_state(ctx
, vs
);
781 ctx
->delete_fs_state(ctx
, fs
);
782 pipe_sampler_view_reference(&view
, NULL
);
783 pipe_resource_reference(&cb
, NULL
);
785 util_report_result_helper(pass
, name
);
789 * Run all tests. This should be run with a clean context after
793 util_run_tests(struct pipe_screen
*screen
)
795 struct pipe_context
*ctx
= screen
->context_create(screen
, NULL
, 0);
797 null_fragment_shader(ctx
);
798 tgsi_vs_window_space_position(ctx
);
799 null_sampler_view(ctx
, TGSI_TEXTURE_2D
);
800 null_sampler_view(ctx
, TGSI_TEXTURE_BUFFER
);
801 util_test_constant_buffer(ctx
, NULL
);
802 test_sync_file_fences(ctx
);
804 for (int i
= 1; i
<= 8; i
= i
* 2)
805 test_texture_barrier(ctx
, false, i
);
806 for (int i
= 1; i
<= 8; i
= i
* 2)
807 test_texture_barrier(ctx
, true, i
);
811 puts("Done. Exiting..");