From: Marek Olšák <marek.ol...@amd.com> --- src/gallium/auxiliary/util/u_tests.c | 168 ++++++++++++++++++++++++++--------- 1 file changed, 128 insertions(+), 40 deletions(-)
diff --git a/src/gallium/auxiliary/util/u_tests.c b/src/gallium/auxiliary/util/u_tests.c index 86eee6e68b1..293a4580a9f 100644 --- a/src/gallium/auxiliary/util/u_tests.c +++ b/src/gallium/auxiliary/util/u_tests.c @@ -37,29 +37,31 @@ #include "util/u_tile.h" #include "tgsi/tgsi_strings.h" #include "tgsi/tgsi_text.h" #include "cso_cache/cso_context.h" #include <stdio.h> #define TOLERANCE 0.01 static struct pipe_resource * util_create_texture2d(struct pipe_screen *screen, unsigned width, - unsigned height, enum pipe_format format) + unsigned height, enum pipe_format format, + unsigned num_samples) { struct pipe_resource templ = {{0}}; templ.target = PIPE_TEXTURE_2D; templ.width0 = width; templ.height0 = height; templ.depth0 = 1; templ.array_size = 1; + templ.nr_samples = num_samples; templ.format = format; templ.usage = PIPE_USAGE_DEFAULT; templ.bind = PIPE_BIND_SAMPLER_VIEW | (util_format_is_depth_or_stencil(format) ? PIPE_BIND_DEPTH_STENCIL : PIPE_BIND_RENDER_TARGET); return screen->resource_create(screen, &templ); } static void @@ -181,20 +183,34 @@ util_draw_fullscreen_quad(struct cso_context *cso) static float vertices[] = { -1, -1, 0, 1, 0, 0, 0, 0, -1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 1, -1, 0, 1, 1, 0, 0, 0 }; util_set_interleaved_vertex_elements(cso, 2); util_draw_user_vertex_buffer(cso, vertices, PIPE_PRIM_QUADS, 4, 2); } +static void +util_draw_fullscreen_quad_fill(struct cso_context *cso, + float r, float g, float b, float a) +{ + float vertices[] = { + -1, -1, 0, 1, r, g, b, a, + -1, 1, 0, 1, r, g, b, a, + 1, 1, 0, 1, r, g, b, a, + 1, -1, 0, 1, r, g, b, a, + }; + util_set_interleaved_vertex_elements(cso, 2); + util_draw_user_vertex_buffer(cso, vertices, PIPE_PRIM_QUADS, 4, 2); +} + /** * Probe and test if the rectangle contains the expected color. * * If "num_expected_colors" > 1, at least one expected color must match * the probed color. "expected" should be an array of 4*num_expected_colors * floats. */ static bool util_probe_rect_rgba_multi(struct pipe_context *ctx, struct pipe_resource *tex, unsigned offx, unsigned offy, unsigned w, @@ -299,21 +315,21 @@ tgsi_vs_window_space_position(struct pipe_context *ctx) static const float red[] = {1, 0, 0, 1}; if (!ctx->screen->get_param(ctx->screen, PIPE_CAP_TGSI_VS_WINDOW_SPACE_POSITION)) { util_report_result(SKIP); return; } cso = cso_create_context(ctx, 0); cb = util_create_texture2d(ctx->screen, 256, 256, - PIPE_FORMAT_R8G8B8A8_UNORM); + PIPE_FORMAT_R8G8B8A8_UNORM, 0); util_set_common_states_and_clear(cso, ctx, cb); /* Fragment shader. */ fs = util_make_fragment_passthrough_shader(ctx, TGSI_SEMANTIC_GENERIC, TGSI_INTERPOLATE_LINEAR, TRUE); cso_set_fragment_shader_handle(cso, fs); /* Vertex shader. */ vs = util_set_passthrough_vertex_shader(cso, ctx, true); @@ -359,21 +375,21 @@ null_sampler_view(struct pipe_context *ctx, unsigned tgsi_tex_target) if (tgsi_tex_target == TGSI_TEXTURE_BUFFER && !ctx->screen->get_param(ctx->screen, PIPE_CAP_TEXTURE_BUFFER_OBJECTS)) { util_report_result_helper(SKIP, "%s: %s", __func__, tgsi_texture_names[tgsi_tex_target]); return; } cso = cso_create_context(ctx, 0); cb = util_create_texture2d(ctx->screen, 256, 256, - PIPE_FORMAT_R8G8B8A8_UNORM); + PIPE_FORMAT_R8G8B8A8_UNORM, 0); util_set_common_states_and_clear(cso, ctx, cb); ctx->set_sampler_views(ctx, PIPE_SHADER_FRAGMENT, 0, 1, NULL); /* Fragment shader. */ fs = util_make_fragment_tex_shader(ctx, tgsi_tex_target, TGSI_INTERPOLATE_LINEAR, TGSI_RETURN_TYPE_FLOAT, TGSI_RETURN_TYPE_FLOAT, false, false); cso_set_fragment_shader_handle(cso, fs); @@ -402,21 +418,21 @@ util_test_constant_buffer(struct pipe_context *ctx, struct pipe_resource *constbuf) { struct cso_context *cso; struct pipe_resource *cb; void *fs, *vs; bool pass = true; static const float zero[] = {0, 0, 0, 0}; cso = cso_create_context(ctx, 0); cb = util_create_texture2d(ctx->screen, 256, 256, - PIPE_FORMAT_R8G8B8A8_UNORM); + PIPE_FORMAT_R8G8B8A8_UNORM, 0); util_set_common_states_and_clear(cso, ctx, cb); pipe_set_constant_buffer(ctx, PIPE_SHADER_FRAGMENT, 0, constbuf); /* Fragment shader. */ { static const char *text = /* I don't like ureg... */ "FRAG\n" "DCL CONST[0][0]\n" "DCL OUT[0], COLOR\n" @@ -458,21 +474,21 @@ null_fragment_shader(struct pipe_context *ctx) { struct cso_context *cso; struct pipe_resource *cb; void *vs; struct pipe_rasterizer_state rs = {0}; struct pipe_query *query; union pipe_query_result qresult; cso = cso_create_context(ctx, 0); cb = util_create_texture2d(ctx->screen, 256, 256, - PIPE_FORMAT_R8G8B8A8_UNORM); + PIPE_FORMAT_R8G8B8A8_UNORM, 0); util_set_common_states_and_clear(cso, ctx, cb); /* No rasterization. */ rs.rasterizer_discard = 1; cso_set_rasterizer(cso, &rs); vs = util_set_passthrough_vertex_shader(cso, ctx, false); query = ctx->create_query(ctx, PIPE_QUERY_PRIMITIVES_GENERATED, 0); ctx->begin_query(ctx, query); @@ -504,21 +520,21 @@ test_sync_file_fences(struct pipe_context *ctx) bool pass = true; enum pipe_fd_type fd_type = PIPE_FD_TYPE_NATIVE_SYNC; if (!screen->get_param(screen, PIPE_CAP_NATIVE_FENCE_FD)) return; struct cso_context *cso = cso_create_context(ctx, 0); struct pipe_resource *buf = pipe_buffer_create(screen, 0, PIPE_USAGE_DEFAULT, 1024 * 1024); struct pipe_resource *tex = - util_create_texture2d(screen, 4096, 1024, PIPE_FORMAT_R8_UNORM); + util_create_texture2d(screen, 4096, 1024, PIPE_FORMAT_R8_UNORM, 0); struct pipe_fence_handle *buf_fence = NULL, *tex_fence = NULL; /* Run 2 clears, get fencess. */ uint32_t value = 0; ctx->clear_buffer(ctx, buf, 0, buf->width0, &value, sizeof(value)); ctx->flush(ctx, &buf_fence, PIPE_FLUSH_FENCE_FD); struct pipe_box box; u_box_2d(0, 0, tex->width0, tex->height0, &box); ctx->clear_texture(ctx, tex, 0, &box, &value); @@ -587,45 +603,86 @@ test_sync_file_fences(struct pipe_context *ctx) screen->fence_reference(screen, &final_fence, NULL); cso_destroy_context(cso); pipe_resource_reference(&buf, NULL); pipe_resource_reference(&tex, NULL); util_report_result(pass); } static void -test_texture_barrier(struct pipe_context *ctx, bool use_fbfetch) +test_texture_barrier(struct pipe_context *ctx, bool use_fbfetch, + unsigned num_samples) { struct cso_context *cso; struct pipe_resource *cb; - void *fs, *vs; struct pipe_sampler_view *view = NULL; + char name[256]; const char *text; + assert(num_samples >= 1 && num_samples <= 8); + + snprintf(name, sizeof(name), "%s: %s, %u samples", __func__, + use_fbfetch ? "FBFETCH" : "sampler", MAX2(num_samples, 1)); + if (!ctx->screen->get_param(ctx->screen, PIPE_CAP_TEXTURE_BARRIER)) { - util_report_result_helper(SKIP, "%s: %s", __func__, - use_fbfetch ? "FBFETCH" : "sampler"); + util_report_result_helper(SKIP, name); return; } if (use_fbfetch && !ctx->screen->get_param(ctx->screen, PIPE_CAP_TGSI_FS_FBFETCH)) { - util_report_result_helper(SKIP, "%s: %s", __func__, - use_fbfetch ? "FBFETCH" : "sampler"); + util_report_result_helper(SKIP, name); return; } cso = cso_create_context(ctx, 0); cb = util_create_texture2d(ctx->screen, 256, 256, - PIPE_FORMAT_R8G8B8A8_UNORM); + PIPE_FORMAT_R8G8B8A8_UNORM, num_samples); util_set_common_states_and_clear(cso, ctx, cb); + /* Clear each sample to a different value. */ + if (num_samples > 1) { + void *fs = + util_make_fragment_passthrough_shader(ctx, TGSI_SEMANTIC_GENERIC, + TGSI_INTERPOLATE_LINEAR, TRUE); + cso_set_fragment_shader_handle(cso, fs); + + /* Vertex shader. */ + void *vs = util_set_passthrough_vertex_shader(cso, ctx, false); + + for (int i = 0; i < num_samples / 2; i++) { + float value; + + /* 2 consecutive samples should have the same color to test MSAA + * compression properly. + */ + if (num_samples == 2) { + value = 0.1; + } else { + /* The average value must be 0.1 */ + static const float values[] = { + 0.0, 0.2, 0.05, 0.15 + }; + value = values[i]; + } + + ctx->set_sample_mask(ctx, 0x3 << (i * 2)); + util_draw_fullscreen_quad_fill(cso, value, value, value, value); + } + ctx->set_sample_mask(ctx, ~0); + + cso_set_vertex_shader_handle(cso, NULL); + cso_set_fragment_shader_handle(cso, NULL); + ctx->delete_vs_state(ctx, vs); + ctx->delete_fs_state(ctx, fs); + } + if (use_fbfetch) { /* Fragment shader. */ text = "FRAG\n" "DCL OUT[0], COLOR[0]\n" "DCL TEMP[0]\n" "IMM[0] FLT32 { 0.1, 0.2, 0.3, 0.4}\n" "FBFETCH TEMP[0], OUT[0]\n" "ADD OUT[0], TEMP[0], IMM[0]\n" "END\n"; @@ -634,92 +691,123 @@ test_texture_barrier(struct pipe_context *ctx, bool use_fbfetch) templ.format = cb->format; templ.target = cb->target; templ.swizzle_r = PIPE_SWIZZLE_X; templ.swizzle_g = PIPE_SWIZZLE_Y; templ.swizzle_b = PIPE_SWIZZLE_Z; templ.swizzle_a = PIPE_SWIZZLE_W; view = ctx->create_sampler_view(ctx, cb, &templ); ctx->set_sampler_views(ctx, PIPE_SHADER_FRAGMENT, 0, 1, &view); /* Fragment shader. */ - text = "FRAG\n" - "DCL SV[0], POSITION\n" - "DCL SAMP[0]\n" - "DCL SVIEW[0], 2D, FLOAT\n" - "DCL OUT[0], COLOR[0]\n" - "DCL TEMP[0]\n" - "IMM[0] FLT32 { 0.1, 0.2, 0.3, 0.4}\n" - "IMM[1] INT32 { 0, 0, 0, 0}\n" - - "F2I TEMP[0].xy, SV[0].xyyy\n" - "MOV TEMP[0].z, IMM[1].xxxx\n" - "TXF TEMP[0], TEMP[0].xyzz, SAMP[0], 2D\n" - "ADD OUT[0], TEMP[0], IMM[0]\n" - "END\n"; + if (num_samples > 1) { + text = "FRAG\n" + "DCL SV[0], POSITION\n" + "DCL SV[1], SAMPLEID\n" + "DCL SAMP[0]\n" + "DCL SVIEW[0], 2D_MSAA, FLOAT\n" + "DCL OUT[0], COLOR[0]\n" + "DCL TEMP[0]\n" + "IMM[0] FLT32 { 0.1, 0.2, 0.3, 0.4}\n" + + "F2I TEMP[0].xy, SV[0].xyyy\n" + "MOV TEMP[0].w, SV[1].xxxx\n" + "TXF TEMP[0], TEMP[0], SAMP[0], 2D_MSAA\n" + "ADD OUT[0], TEMP[0], IMM[0]\n" + "END\n"; + } else { + text = "FRAG\n" + "DCL SV[0], POSITION\n" + "DCL SAMP[0]\n" + "DCL SVIEW[0], 2D, FLOAT\n" + "DCL OUT[0], COLOR[0]\n" + "DCL TEMP[0]\n" + "IMM[0] FLT32 { 0.1, 0.2, 0.3, 0.4}\n" + "IMM[1] INT32 { 0, 0, 0, 0}\n" + + "F2I TEMP[0].xy, SV[0].xyyy\n" + "MOV TEMP[0].zw, IMM[1]\n" + "TXF TEMP[0], TEMP[0], SAMP[0], 2D\n" + "ADD OUT[0], TEMP[0], IMM[0]\n" + "END\n"; + } } struct tgsi_token tokens[1000]; struct pipe_shader_state state; if (!tgsi_text_translate(text, tokens, ARRAY_SIZE(tokens))) { assert(0); - util_report_result_helper(FAIL, "%s: %s", __func__, - use_fbfetch ? "FBFETCH" : "sampler"); + util_report_result_helper(FAIL, name); return; } pipe_shader_state_from_tgsi(&state, tokens); -#if 0 - tgsi_dump(state.tokens, 0); -#endif - fs = ctx->create_fs_state(ctx, &state); + void *fs = ctx->create_fs_state(ctx, &state); cso_set_fragment_shader_handle(cso, fs); /* Vertex shader. */ - vs = util_set_passthrough_vertex_shader(cso, ctx, false); + void *vs = util_set_passthrough_vertex_shader(cso, ctx, false); + + if (num_samples > 1 && !use_fbfetch) + ctx->set_min_samples(ctx, num_samples); for (int i = 0; i < 2; i++) { ctx->texture_barrier(ctx, use_fbfetch ? PIPE_TEXTURE_BARRIER_FRAMEBUFFER : PIPE_TEXTURE_BARRIER_SAMPLER); util_draw_fullscreen_quad(cso); } - - /* Probe pixels. */ + if (num_samples > 1 && !use_fbfetch) + ctx->set_min_samples(ctx, 1); + + /* Probe pixels. + * + * For single sample: + * result = 0.1 (clear) + (0.1, 0.2, 0.3, 0.4) * 2 = (0.3, 0.5, 0.7, 0.9) + * + * For MSAA 4x: + * sample0 = 0.0 (clear) + (0.1, 0.2, 0.3, 0.4) * 2 = (0.2, 0.4, 0.6, 0.8) + * sample1 = sample0 + * sample2 = 0.2 (clear) + (0.1, 0.2, 0.3, 0.4) * 2 = (0.4, 0.6, 0.8, 1.0) + * sample3 = sample2 + * resolved = sum(sample[0:3]) / 4 = (0.3, 0.5, 0.7, 0.9) + */ static const float expected[] = {0.3, 0.5, 0.7, 0.9}; bool pass = util_probe_rect_rgba(ctx, cb, 0, 0, cb->width0, cb->height0, expected); /* Cleanup. */ cso_destroy_context(cso); ctx->delete_vs_state(ctx, vs); ctx->delete_fs_state(ctx, fs); pipe_sampler_view_reference(&view, NULL); pipe_resource_reference(&cb, NULL); - util_report_result_helper(pass, "%s: %s", __func__, - use_fbfetch ? "FBFETCH" : "sampler"); + util_report_result_helper(pass, name); } /** * Run all tests. This should be run with a clean context after * context_create. */ void util_run_tests(struct pipe_screen *screen) { struct pipe_context *ctx = screen->context_create(screen, NULL, 0); null_fragment_shader(ctx); tgsi_vs_window_space_position(ctx); null_sampler_view(ctx, TGSI_TEXTURE_2D); null_sampler_view(ctx, TGSI_TEXTURE_BUFFER); util_test_constant_buffer(ctx, NULL); test_sync_file_fences(ctx); - test_texture_barrier(ctx, false); - test_texture_barrier(ctx, true); + + for (int i = 1; i <= 8; i = i * 2) + test_texture_barrier(ctx, false, i); + for (int i = 1; i <= 8; i = i * 2) + test_texture_barrier(ctx, true, i); ctx->destroy(ctx); puts("Done. Exiting.."); exit(0); } -- 2.15.1 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev