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;
113 cso_set_rasterizer(cso
, &rs
);
117 util_set_max_viewport(struct cso_context
*cso
, struct pipe_resource
*tex
)
119 struct pipe_viewport_state viewport
;
121 viewport
.scale
[0] = 0.5f
* tex
->width0
;
122 viewport
.scale
[1] = 0.5f
* tex
->height0
;
123 viewport
.scale
[2] = 1.0f
;
124 viewport
.translate
[0] = 0.5f
* tex
->width0
;
125 viewport
.translate
[1] = 0.5f
* tex
->height0
;
126 viewport
.translate
[2] = 0.0f
;
128 cso_set_viewport(cso
, &viewport
);
132 util_set_interleaved_vertex_elements(struct cso_context
*cso
,
133 unsigned num_elements
)
136 struct pipe_vertex_element
*velem
=
137 calloc(1, num_elements
* sizeof(struct pipe_vertex_element
));
139 for (i
= 0; i
< num_elements
; i
++) {
140 velem
[i
].src_format
= PIPE_FORMAT_R32G32B32A32_FLOAT
;
141 velem
[i
].src_offset
= i
* 16;
144 cso_set_vertex_elements(cso
, num_elements
, velem
);
149 util_set_passthrough_vertex_shader(struct cso_context
*cso
,
150 struct pipe_context
*ctx
,
153 static const enum tgsi_semantic vs_attribs
[] = {
154 TGSI_SEMANTIC_POSITION
,
155 TGSI_SEMANTIC_GENERIC
157 static const uint vs_indices
[] = {0, 0};
160 vs
= util_make_vertex_passthrough_shader(ctx
, 2, vs_attribs
, vs_indices
,
162 cso_set_vertex_shader_handle(cso
, vs
);
167 util_set_common_states_and_clear(struct cso_context
*cso
, struct pipe_context
*ctx
,
168 struct pipe_resource
*cb
)
170 static const float clear_color
[] = {0.1, 0.1, 0.1, 0.1};
172 util_set_framebuffer_cb0(cso
, ctx
, cb
);
173 util_set_blend_normal(cso
);
174 util_set_dsa_disable(cso
);
175 util_set_rasterizer_normal(cso
);
176 util_set_max_viewport(cso
, cb
);
178 ctx
->clear(ctx
, PIPE_CLEAR_COLOR0
, (void*)clear_color
, 0, 0);
182 util_draw_fullscreen_quad(struct cso_context
*cso
)
184 static float vertices
[] = {
185 -1, -1, 0, 1, 0, 0, 0, 0,
186 -1, 1, 0, 1, 0, 1, 0, 0,
187 1, 1, 0, 1, 1, 1, 0, 0,
188 1, -1, 0, 1, 1, 0, 0, 0
190 util_set_interleaved_vertex_elements(cso
, 2);
191 util_draw_user_vertex_buffer(cso
, vertices
, PIPE_PRIM_QUADS
, 4, 2);
195 util_draw_fullscreen_quad_fill(struct cso_context
*cso
,
196 float r
, float g
, float b
, float 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
,
202 1, -1, 0, 1, r
, g
, b
, a
,
204 util_set_interleaved_vertex_elements(cso
, 2);
205 util_draw_user_vertex_buffer(cso
, vertices
, PIPE_PRIM_QUADS
, 4, 2);
209 * Probe and test if the rectangle contains the expected color.
211 * If "num_expected_colors" > 1, at least one expected color must match
212 * the probed color. "expected" should be an array of 4*num_expected_colors
216 util_probe_rect_rgba_multi(struct pipe_context
*ctx
, struct pipe_resource
*tex
,
217 unsigned offx
, unsigned offy
, unsigned w
,
219 const float *expected
,
220 unsigned num_expected_colors
)
222 struct pipe_transfer
*transfer
;
224 float *pixels
= malloc(w
* h
* 4 * sizeof(float));
228 map
= pipe_transfer_map(ctx
, tex
, 0, 0, PIPE_TRANSFER_READ
,
229 offx
, offy
, w
, h
, &transfer
);
230 pipe_get_tile_rgba(transfer
, map
, 0, 0, w
, h
, pixels
);
231 pipe_transfer_unmap(ctx
, transfer
);
233 for (e
= 0; e
< num_expected_colors
; e
++) {
234 for (y
= 0; y
< h
; y
++) {
235 for (x
= 0; x
< w
; x
++) {
236 float *probe
= &pixels
[(y
*w
+ x
)*4];
238 for (c
= 0; c
< 4; c
++) {
239 if (fabs(probe
[c
] - expected
[e
*4+c
]) >= TOLERANCE
) {
240 if (e
< num_expected_colors
-1)
241 goto next_color
; /* test the next expected color */
243 printf("Probe color at (%i,%i), ", offx
+x
, offy
+y
);
244 printf("Expected: %.3f, %.3f, %.3f, %.3f, ",
245 expected
[e
*4], expected
[e
*4+1],
246 expected
[e
*4+2], expected
[e
*4+3]);
247 printf("Got: %.3f, %.3f, %.3f, %.3f\n",
248 probe
[0], probe
[1], probe
[2], probe
[3]);
255 break; /* this color was successful */
266 util_probe_rect_rgba(struct pipe_context
*ctx
, struct pipe_resource
*tex
,
267 unsigned offx
, unsigned offy
, unsigned w
, unsigned h
,
268 const float *expected
)
270 return util_probe_rect_rgba_multi(ctx
, tex
, offx
, offy
, w
, h
, expected
, 1);
275 FAIL
= 0, /* also "false" */
276 PASS
= 1 /* also "true" */
280 util_report_result_helper(int status
, const char *name
, ...)
286 util_vsnprintf(buf
, sizeof(buf
), name
, ap
);
289 printf("Test(%s) = %s\n", buf
,
290 status
== SKIP
? "skip" :
291 status
== PASS
? "pass" : "fail");
294 #define util_report_result(status) util_report_result_helper(status, __func__)
297 * Test TGSI_PROPERTY_VS_WINDOW_SPACE_POSITION.
299 * The viewport state is set as usual, but it should have no effect.
300 * Clipping should also be disabled.
302 * POSITION.xyz should already be multiplied by 1/w and POSITION.w should
303 * contain 1/w. By setting w=0, we can test that POSITION.xyz isn't
304 * multiplied by 1/w (otherwise nothing would be rendered).
306 * TODO: Whether the value of POSITION.w is correctly interpreted as 1/w
307 * during perspective interpolation is not tested.
310 tgsi_vs_window_space_position(struct pipe_context
*ctx
)
312 struct cso_context
*cso
;
313 struct pipe_resource
*cb
;
316 static const float red
[] = {1, 0, 0, 1};
318 if (!ctx
->screen
->get_param(ctx
->screen
,
319 PIPE_CAP_TGSI_VS_WINDOW_SPACE_POSITION
)) {
320 util_report_result(SKIP
);
324 cso
= cso_create_context(ctx
, 0);
325 cb
= util_create_texture2d(ctx
->screen
, 256, 256,
326 PIPE_FORMAT_R8G8B8A8_UNORM
, 0);
327 util_set_common_states_and_clear(cso
, ctx
, cb
);
329 /* Fragment shader. */
330 fs
= util_make_fragment_passthrough_shader(ctx
, TGSI_SEMANTIC_GENERIC
,
331 TGSI_INTERPOLATE_LINEAR
, TRUE
);
332 cso_set_fragment_shader_handle(cso
, fs
);
335 vs
= util_set_passthrough_vertex_shader(cso
, ctx
, true);
339 static float vertices
[] = {
340 0, 0, 0, 0, 1, 0, 0, 1,
341 0, 256, 0, 0, 1, 0, 0, 1,
342 256, 256, 0, 0, 1, 0, 0, 1,
343 256, 0, 0, 0, 1, 0, 0, 1,
345 util_set_interleaved_vertex_elements(cso
, 2);
346 util_draw_user_vertex_buffer(cso
, vertices
, PIPE_PRIM_QUADS
, 4, 2);
350 pass
= pass
&& util_probe_rect_rgba(ctx
, cb
, 0, 0,
351 cb
->width0
, cb
->height0
, red
);
354 cso_destroy_context(cso
);
355 ctx
->delete_vs_state(ctx
, vs
);
356 ctx
->delete_fs_state(ctx
, fs
);
357 pipe_resource_reference(&cb
, NULL
);
359 util_report_result(pass
);
363 null_sampler_view(struct pipe_context
*ctx
, unsigned tgsi_tex_target
)
365 struct cso_context
*cso
;
366 struct pipe_resource
*cb
;
369 /* 2 expected colors: */
370 static const float expected_tex
[] = {0, 0, 0, 1,
372 static const float expected_buf
[] = {0, 0, 0, 0};
373 const float *expected
= tgsi_tex_target
== TGSI_TEXTURE_BUFFER
?
374 expected_buf
: expected_tex
;
375 unsigned num_expected
= tgsi_tex_target
== TGSI_TEXTURE_BUFFER
? 1 : 2;
377 if (tgsi_tex_target
== TGSI_TEXTURE_BUFFER
&&
378 !ctx
->screen
->get_param(ctx
->screen
, PIPE_CAP_TEXTURE_BUFFER_OBJECTS
)) {
379 util_report_result_helper(SKIP
, "%s: %s", __func__
,
380 tgsi_texture_names
[tgsi_tex_target
]);
384 cso
= cso_create_context(ctx
, 0);
385 cb
= util_create_texture2d(ctx
->screen
, 256, 256,
386 PIPE_FORMAT_R8G8B8A8_UNORM
, 0);
387 util_set_common_states_and_clear(cso
, ctx
, cb
);
389 ctx
->set_sampler_views(ctx
, PIPE_SHADER_FRAGMENT
, 0, 1, NULL
);
391 /* Fragment shader. */
392 fs
= util_make_fragment_tex_shader(ctx
, tgsi_tex_target
,
393 TGSI_INTERPOLATE_LINEAR
,
394 TGSI_RETURN_TYPE_FLOAT
,
395 TGSI_RETURN_TYPE_FLOAT
, false, false);
396 cso_set_fragment_shader_handle(cso
, fs
);
399 vs
= util_set_passthrough_vertex_shader(cso
, ctx
, false);
400 util_draw_fullscreen_quad(cso
);
403 pass
= pass
&& util_probe_rect_rgba_multi(ctx
, cb
, 0, 0,
404 cb
->width0
, cb
->height0
, expected
,
408 cso_destroy_context(cso
);
409 ctx
->delete_vs_state(ctx
, vs
);
410 ctx
->delete_fs_state(ctx
, fs
);
411 pipe_resource_reference(&cb
, NULL
);
413 util_report_result_helper(pass
, "%s: %s", __func__
,
414 tgsi_texture_names
[tgsi_tex_target
]);
418 util_test_constant_buffer(struct pipe_context
*ctx
,
419 struct pipe_resource
*constbuf
)
421 struct cso_context
*cso
;
422 struct pipe_resource
*cb
;
425 static const float zero
[] = {0, 0, 0, 0};
427 cso
= cso_create_context(ctx
, 0);
428 cb
= util_create_texture2d(ctx
->screen
, 256, 256,
429 PIPE_FORMAT_R8G8B8A8_UNORM
, 0);
430 util_set_common_states_and_clear(cso
, ctx
, cb
);
432 pipe_set_constant_buffer(ctx
, PIPE_SHADER_FRAGMENT
, 0, constbuf
);
434 /* Fragment shader. */
436 static const char *text
= /* I don't like ureg... */
439 "DCL OUT[0], COLOR\n"
441 "MOV OUT[0], CONST[0][0]\n"
443 struct tgsi_token tokens
[1000];
444 struct pipe_shader_state state
;
446 if (!tgsi_text_translate(text
, tokens
, ARRAY_SIZE(tokens
))) {
447 puts("Can't compile a fragment shader.");
448 util_report_result(FAIL
);
451 pipe_shader_state_from_tgsi(&state
, tokens
);
452 fs
= ctx
->create_fs_state(ctx
, &state
);
453 cso_set_fragment_shader_handle(cso
, fs
);
457 vs
= util_set_passthrough_vertex_shader(cso
, ctx
, false);
458 util_draw_fullscreen_quad(cso
);
461 pass
= pass
&& util_probe_rect_rgba(ctx
, cb
, 0, 0, cb
->width0
,
465 cso_destroy_context(cso
);
466 ctx
->delete_vs_state(ctx
, vs
);
467 ctx
->delete_fs_state(ctx
, fs
);
468 pipe_resource_reference(&cb
, NULL
);
470 util_report_result(pass
);
474 null_fragment_shader(struct pipe_context
*ctx
)
476 struct cso_context
*cso
;
477 struct pipe_resource
*cb
;
479 struct pipe_rasterizer_state rs
= {0};
480 struct pipe_query
*query
;
481 union pipe_query_result qresult
;
483 cso
= cso_create_context(ctx
, 0);
484 cb
= util_create_texture2d(ctx
->screen
, 256, 256,
485 PIPE_FORMAT_R8G8B8A8_UNORM
, 0);
486 util_set_common_states_and_clear(cso
, ctx
, cb
);
488 /* No rasterization. */
489 rs
.rasterizer_discard
= 1;
490 cso_set_rasterizer(cso
, &rs
);
492 vs
= util_set_passthrough_vertex_shader(cso
, ctx
, false);
494 query
= ctx
->create_query(ctx
, PIPE_QUERY_PRIMITIVES_GENERATED
, 0);
495 ctx
->begin_query(ctx
, query
);
496 util_draw_fullscreen_quad(cso
);
497 ctx
->end_query(ctx
, query
);
498 ctx
->get_query_result(ctx
, query
, true, &qresult
);
501 cso_destroy_context(cso
);
502 ctx
->delete_vs_state(ctx
, vs
);
503 ctx
->destroy_query(ctx
, query
);
504 pipe_resource_reference(&cb
, NULL
);
506 /* Check PRIMITIVES_GENERATED. */
507 util_report_result(qresult
.u64
== 2);
510 #if defined(PIPE_OS_LINUX) && defined(HAVE_LIBDRM)
513 #define sync_merge(str, fd1, fd2) (-1)
514 #define sync_wait(fd, timeout) (-1)
518 test_sync_file_fences(struct pipe_context
*ctx
)
520 struct pipe_screen
*screen
= ctx
->screen
;
522 enum pipe_fd_type fd_type
= PIPE_FD_TYPE_NATIVE_SYNC
;
524 if (!screen
->get_param(screen
, PIPE_CAP_NATIVE_FENCE_FD
))
527 struct cso_context
*cso
= cso_create_context(ctx
, 0);
528 struct pipe_resource
*buf
=
529 pipe_buffer_create(screen
, 0, PIPE_USAGE_DEFAULT
, 1024 * 1024);
530 struct pipe_resource
*tex
=
531 util_create_texture2d(screen
, 4096, 1024, PIPE_FORMAT_R8_UNORM
, 0);
532 struct pipe_fence_handle
*buf_fence
= NULL
, *tex_fence
= NULL
;
534 /* Run 2 clears, get fencess. */
536 ctx
->clear_buffer(ctx
, buf
, 0, buf
->width0
, &value
, sizeof(value
));
537 ctx
->flush(ctx
, &buf_fence
, PIPE_FLUSH_FENCE_FD
);
540 u_box_2d(0, 0, tex
->width0
, tex
->height0
, &box
);
541 ctx
->clear_texture(ctx
, tex
, 0, &box
, &value
);
542 ctx
->flush(ctx
, &tex_fence
, PIPE_FLUSH_FENCE_FD
);
543 pass
= pass
&& buf_fence
&& tex_fence
;
546 int buf_fd
= screen
->fence_get_fd(screen
, buf_fence
);
547 int tex_fd
= screen
->fence_get_fd(screen
, tex_fence
);
548 pass
= pass
&& buf_fd
>= 0 && tex_fd
>= 0;
551 int merged_fd
= sync_merge("test", buf_fd
, tex_fd
);
552 pass
= pass
&& merged_fd
>= 0;
554 /* (Re)import all fences. */
555 struct pipe_fence_handle
*re_buf_fence
= NULL
, *re_tex_fence
= NULL
;
556 struct pipe_fence_handle
*merged_fence
= NULL
;
557 ctx
->create_fence_fd(ctx
, &re_buf_fence
, buf_fd
, fd_type
);
558 ctx
->create_fence_fd(ctx
, &re_tex_fence
, tex_fd
, fd_type
);
559 ctx
->create_fence_fd(ctx
, &merged_fence
, merged_fd
, fd_type
);
560 pass
= pass
&& re_buf_fence
&& re_tex_fence
&& merged_fence
;
562 /* Run another clear after waiting for everything. */
563 struct pipe_fence_handle
*final_fence
= NULL
;
564 ctx
->fence_server_sync(ctx
, merged_fence
);
566 ctx
->clear_buffer(ctx
, buf
, 0, buf
->width0
, &value
, sizeof(value
));
567 ctx
->flush(ctx
, &final_fence
, PIPE_FLUSH_FENCE_FD
);
568 pass
= pass
&& final_fence
;
570 /* Wait for the last fence. */
571 int final_fd
= screen
->fence_get_fd(screen
, final_fence
);
572 pass
= pass
&& final_fd
>= 0;
573 pass
= pass
&& sync_wait(final_fd
, -1) == 0;
575 /* Check that all fences are signalled. */
576 pass
= pass
&& sync_wait(buf_fd
, 0) == 0;
577 pass
= pass
&& sync_wait(tex_fd
, 0) == 0;
578 pass
= pass
&& sync_wait(merged_fd
, 0) == 0;
580 pass
= pass
&& screen
->fence_finish(screen
, NULL
, buf_fence
, 0);
581 pass
= pass
&& screen
->fence_finish(screen
, NULL
, tex_fence
, 0);
582 pass
= pass
&& screen
->fence_finish(screen
, NULL
, re_buf_fence
, 0);
583 pass
= pass
&& screen
->fence_finish(screen
, NULL
, re_tex_fence
, 0);
584 pass
= pass
&& screen
->fence_finish(screen
, NULL
, merged_fence
, 0);
585 pass
= pass
&& screen
->fence_finish(screen
, NULL
, final_fence
, 0);
588 #ifndef PIPE_OS_WINDOWS
599 screen
->fence_reference(screen
, &buf_fence
, NULL
);
600 screen
->fence_reference(screen
, &tex_fence
, NULL
);
601 screen
->fence_reference(screen
, &re_buf_fence
, NULL
);
602 screen
->fence_reference(screen
, &re_tex_fence
, NULL
);
603 screen
->fence_reference(screen
, &merged_fence
, NULL
);
604 screen
->fence_reference(screen
, &final_fence
, NULL
);
606 cso_destroy_context(cso
);
607 pipe_resource_reference(&buf
, NULL
);
608 pipe_resource_reference(&tex
, NULL
);
610 util_report_result(pass
);
614 test_texture_barrier(struct pipe_context
*ctx
, bool use_fbfetch
,
615 unsigned num_samples
)
617 struct cso_context
*cso
;
618 struct pipe_resource
*cb
;
619 struct pipe_sampler_view
*view
= NULL
;
623 assert(num_samples
>= 1 && num_samples
<= 8);
625 snprintf(name
, sizeof(name
), "%s: %s, %u samples", __func__
,
626 use_fbfetch
? "FBFETCH" : "sampler", MAX2(num_samples
, 1));
628 if (!ctx
->screen
->get_param(ctx
->screen
, PIPE_CAP_TEXTURE_BARRIER
)) {
629 util_report_result_helper(SKIP
, name
);
633 !ctx
->screen
->get_param(ctx
->screen
, PIPE_CAP_TGSI_FS_FBFETCH
)) {
634 util_report_result_helper(SKIP
, name
);
638 cso
= cso_create_context(ctx
, 0);
639 cb
= util_create_texture2d(ctx
->screen
, 256, 256,
640 PIPE_FORMAT_R8G8B8A8_UNORM
, num_samples
);
641 util_set_common_states_and_clear(cso
, ctx
, cb
);
643 /* Clear each sample to a different value. */
644 if (num_samples
> 1) {
646 util_make_fragment_passthrough_shader(ctx
, TGSI_SEMANTIC_GENERIC
,
647 TGSI_INTERPOLATE_LINEAR
, TRUE
);
648 cso_set_fragment_shader_handle(cso
, fs
);
651 void *vs
= util_set_passthrough_vertex_shader(cso
, ctx
, false);
653 for (unsigned i
= 0; i
< num_samples
/ 2; i
++) {
656 /* 2 consecutive samples should have the same color to test MSAA
657 * compression properly.
659 if (num_samples
== 2) {
662 /* The average value must be 0.1 */
663 static const float values
[] = {
669 ctx
->set_sample_mask(ctx
, 0x3 << (i
* 2));
670 util_draw_fullscreen_quad_fill(cso
, value
, value
, value
, value
);
672 ctx
->set_sample_mask(ctx
, ~0);
674 cso_set_vertex_shader_handle(cso
, NULL
);
675 cso_set_fragment_shader_handle(cso
, NULL
);
676 ctx
->delete_vs_state(ctx
, vs
);
677 ctx
->delete_fs_state(ctx
, fs
);
681 /* Fragment shader. */
683 "DCL OUT[0], COLOR[0]\n"
685 "IMM[0] FLT32 { 0.1, 0.2, 0.3, 0.4}\n"
687 "FBFETCH TEMP[0], OUT[0]\n"
688 "ADD OUT[0], TEMP[0], IMM[0]\n"
691 struct pipe_sampler_view templ
= {{0}};
692 templ
.format
= cb
->format
;
693 templ
.target
= cb
->target
;
694 templ
.swizzle_r
= PIPE_SWIZZLE_X
;
695 templ
.swizzle_g
= PIPE_SWIZZLE_Y
;
696 templ
.swizzle_b
= PIPE_SWIZZLE_Z
;
697 templ
.swizzle_a
= PIPE_SWIZZLE_W
;
698 view
= ctx
->create_sampler_view(ctx
, cb
, &templ
);
699 ctx
->set_sampler_views(ctx
, PIPE_SHADER_FRAGMENT
, 0, 1, &view
);
701 /* Fragment shader. */
702 if (num_samples
> 1) {
704 "DCL SV[0], POSITION\n"
705 "DCL SV[1], SAMPLEID\n"
707 "DCL SVIEW[0], 2D_MSAA, FLOAT\n"
708 "DCL OUT[0], COLOR[0]\n"
710 "IMM[0] FLT32 { 0.1, 0.2, 0.3, 0.4}\n"
712 "F2I TEMP[0].xy, SV[0].xyyy\n"
713 "MOV TEMP[0].w, SV[1].xxxx\n"
714 "TXF TEMP[0], TEMP[0], SAMP[0], 2D_MSAA\n"
715 "ADD OUT[0], TEMP[0], IMM[0]\n"
719 "DCL SV[0], POSITION\n"
721 "DCL SVIEW[0], 2D, FLOAT\n"
722 "DCL OUT[0], COLOR[0]\n"
724 "IMM[0] FLT32 { 0.1, 0.2, 0.3, 0.4}\n"
725 "IMM[1] INT32 { 0, 0, 0, 0}\n"
727 "F2I TEMP[0].xy, SV[0].xyyy\n"
728 "MOV TEMP[0].zw, IMM[1]\n"
729 "TXF TEMP[0], TEMP[0], SAMP[0], 2D\n"
730 "ADD OUT[0], TEMP[0], IMM[0]\n"
735 struct tgsi_token tokens
[1000];
736 struct pipe_shader_state state
;
738 if (!tgsi_text_translate(text
, tokens
, ARRAY_SIZE(tokens
))) {
740 util_report_result_helper(FAIL
, name
);
743 pipe_shader_state_from_tgsi(&state
, tokens
);
745 void *fs
= ctx
->create_fs_state(ctx
, &state
);
746 cso_set_fragment_shader_handle(cso
, fs
);
749 void *vs
= util_set_passthrough_vertex_shader(cso
, ctx
, false);
751 if (num_samples
> 1 && !use_fbfetch
)
752 ctx
->set_min_samples(ctx
, num_samples
);
754 for (int i
= 0; i
< 2; i
++) {
755 ctx
->texture_barrier(ctx
,
756 use_fbfetch
? PIPE_TEXTURE_BARRIER_FRAMEBUFFER
:
757 PIPE_TEXTURE_BARRIER_SAMPLER
);
758 util_draw_fullscreen_quad(cso
);
760 if (num_samples
> 1 && !use_fbfetch
)
761 ctx
->set_min_samples(ctx
, 1);
766 * result = 0.1 (clear) + (0.1, 0.2, 0.3, 0.4) * 2 = (0.3, 0.5, 0.7, 0.9)
769 * sample0 = 0.0 (clear) + (0.1, 0.2, 0.3, 0.4) * 2 = (0.2, 0.4, 0.6, 0.8)
771 * sample2 = 0.2 (clear) + (0.1, 0.2, 0.3, 0.4) * 2 = (0.4, 0.6, 0.8, 1.0)
773 * resolved = sum(sample[0:3]) / 4 = (0.3, 0.5, 0.7, 0.9)
775 static const float expected
[] = {0.3, 0.5, 0.7, 0.9};
776 bool pass
= util_probe_rect_rgba(ctx
, cb
, 0, 0,
777 cb
->width0
, cb
->height0
, expected
);
780 cso_destroy_context(cso
);
781 ctx
->delete_vs_state(ctx
, vs
);
782 ctx
->delete_fs_state(ctx
, fs
);
783 pipe_sampler_view_reference(&view
, NULL
);
784 pipe_resource_reference(&cb
, NULL
);
786 util_report_result_helper(pass
, name
);
790 * Run all tests. This should be run with a clean context after
794 util_run_tests(struct pipe_screen
*screen
)
796 struct pipe_context
*ctx
= screen
->context_create(screen
, NULL
, 0);
798 null_fragment_shader(ctx
);
799 tgsi_vs_window_space_position(ctx
);
800 null_sampler_view(ctx
, TGSI_TEXTURE_2D
);
801 null_sampler_view(ctx
, TGSI_TEXTURE_BUFFER
);
802 util_test_constant_buffer(ctx
, NULL
);
803 test_sync_file_fences(ctx
);
805 for (int i
= 1; i
<= 8; i
= i
* 2)
806 test_texture_barrier(ctx
, false, i
);
807 for (int i
= 1; i
<= 8; i
= i
* 2)
808 test_texture_barrier(ctx
, true, i
);
812 puts("Done. Exiting..");