X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fgallium%2Fauxiliary%2Futil%2Fu_tests.c;h=00f75906173154fa0a1a3ff5f30fa73536b76de9;hb=1c8bcad81a7ce106b37f1ee4a75b817651d6545e;hp=7360eb976394d9fefa3fd1d3048fb44ea9b2a201;hpb=18d9dc179f78f68e598cb21143743dbd71197c93;p=mesa.git diff --git a/src/gallium/auxiliary/util/u_tests.c b/src/gallium/auxiliary/util/u_tests.c index 7360eb97639..00f75906173 100644 --- a/src/gallium/auxiliary/util/u_tests.c +++ b/src/gallium/auxiliary/util/u_tests.c @@ -28,7 +28,7 @@ #include "util/u_tests.h" #include "util/u_draw_quad.h" -#include "util/u_format.h" +#include "util/format/u_format.h" #include "util/u_inlines.h" #include "util/u_memory.h" #include "util/u_simple_shaders.h" @@ -38,6 +38,7 @@ #include "tgsi/tgsi_strings.h" #include "tgsi/tgsi_text.h" #include "cso_cache/cso_context.h" +#include "state_tracker/winsys_handle.h" #include #define TOLERANCE 0.01 @@ -108,7 +109,8 @@ util_set_rasterizer_normal(struct cso_context *cso) rs.half_pixel_center = 1; rs.bottom_edge_rule = 1; - rs.depth_clip = 1; + rs.depth_clip_near = 1; + rs.depth_clip_far = 1; cso_set_rasterizer(cso, &rs); } @@ -132,17 +134,17 @@ static void util_set_interleaved_vertex_elements(struct cso_context *cso, unsigned num_elements) { + struct cso_velems_state velem; unsigned i; - struct pipe_vertex_element *velem = - calloc(1, num_elements * sizeof(struct pipe_vertex_element)); + memset(&velem, 0, sizeof(velem)); + velem.count = num_elements; for (i = 0; i < num_elements; i++) { - velem[i].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT; - velem[i].src_offset = i * 16; + velem.velems[i].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT; + velem.velems[i].src_offset = i * 16; } - cso_set_vertex_elements(cso, num_elements, velem); - free(velem); + cso_set_vertex_elements(cso, &velem); } static void * @@ -175,7 +177,7 @@ util_set_common_states_and_clear(struct cso_context *cso, struct pipe_context *c util_set_rasterizer_normal(cso); util_set_max_viewport(cso, cb); - ctx->clear(ctx, PIPE_CLEAR_COLOR0, (void*)clear_color, 0, 0); + ctx->clear(ctx, PIPE_CLEAR_COLOR0, NULL, (void*)clear_color, 0, 0); } static void @@ -227,7 +229,7 @@ util_probe_rect_rgba_multi(struct pipe_context *ctx, struct pipe_resource *tex, map = pipe_transfer_map(ctx, tex, 0, 0, PIPE_TRANSFER_READ, offx, offy, w, h, &transfer); - pipe_get_tile_rgba(transfer, map, 0, 0, w, h, pixels); + pipe_get_tile_rgba(transfer, map, 0, 0, w, h, tex->format, pixels); pipe_transfer_unmap(ctx, transfer); for (e = 0; e < num_expected_colors; e++) { @@ -283,7 +285,7 @@ util_report_result_helper(int status, const char *name, ...) va_list ap; va_start(ap, name); - util_vsnprintf(buf, sizeof(buf), name, ap); + vsnprintf(buf, sizeof(buf), name, ap); va_end(ap); printf("Test(%s) = %s\n", buf, @@ -622,15 +624,15 @@ test_texture_barrier(struct pipe_context *ctx, bool use_fbfetch, assert(num_samples >= 1 && num_samples <= 8); - util_snprintf(name, sizeof(name), "%s: %s, %u samples", __func__, - use_fbfetch ? "FBFETCH" : "sampler", MAX2(num_samples, 1)); + 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, name); return; } if (use_fbfetch && - !ctx->screen->get_param(ctx->screen, PIPE_CAP_TGSI_FS_FBFETCH)) { + !ctx->screen->get_param(ctx->screen, PIPE_CAP_FBFETCH)) { util_report_result_helper(SKIP, name); return; } @@ -786,6 +788,233 @@ test_texture_barrier(struct pipe_context *ctx, bool use_fbfetch, util_report_result_helper(pass, name); } +static void +test_compute_clear_image(struct pipe_context *ctx) +{ + struct pipe_resource *cb; + const char *text; + + cb = util_create_texture2d(ctx->screen, 256, 256, + PIPE_FORMAT_R8G8B8A8_UNORM, 1); + + /* Compute shader. */ + text = "COMP\n" + "PROPERTY CS_FIXED_BLOCK_WIDTH 8\n" + "PROPERTY CS_FIXED_BLOCK_HEIGHT 8\n" + "PROPERTY CS_FIXED_BLOCK_DEPTH 1\n" + "DCL SV[0], THREAD_ID\n" + "DCL SV[1], BLOCK_ID\n" + "DCL IMAGE[0], 2D, PIPE_FORMAT_R8G8B8A8_UNORM, WR\n" + "DCL TEMP[0]\n" + "IMM[0] UINT32 { 8, 8, 0, 0}\n" + "IMM[1] FLT32 { 1, 0, 0, 0}\n" + + /* TEMP[0].xy = SV[1] * IMM[0] + SV[0]; */ + "UMAD TEMP[0].xy, SV[1], IMM[0], SV[0]\n" + "STORE IMAGE[0], TEMP[0], IMM[1], 2D, PIPE_FORMAT_R8G8B8A8_UNORM\n" + "END\n"; + + struct tgsi_token tokens[1000]; + if (!tgsi_text_translate(text, tokens, ARRAY_SIZE(tokens))) { + assert(0); + util_report_result(FAIL); + return; + } + + struct pipe_compute_state state = {0}; + state.ir_type = PIPE_SHADER_IR_TGSI; + state.prog = tokens; + + void *compute_shader = ctx->create_compute_state(ctx, &state); + ctx->bind_compute_state(ctx, compute_shader); + + /* Bind the image. */ + struct pipe_image_view image = {0}; + image.resource = cb; + image.shader_access = image.access = PIPE_IMAGE_ACCESS_READ_WRITE; + image.format = cb->format; + + ctx->set_shader_images(ctx, PIPE_SHADER_COMPUTE, 0, 1, &image); + + /* Dispatch compute. */ + struct pipe_grid_info info = {0}; + info.block[0] = 8; + info.block[1] = 8; + info.block[2] = 1; + info.grid[0] = cb->width0 / 8; + info.grid[1] = cb->height0 / 8; + info.grid[2] = 1; + + ctx->launch_grid(ctx, &info); + + /* Check pixels. */ + static const float expected[] = {1.0, 0.0, 0.0, 0.0}; + bool pass = util_probe_rect_rgba(ctx, cb, 0, 0, + cb->width0, cb->height0, expected); + + /* Cleanup. */ + ctx->delete_compute_state(ctx, compute_shader); + pipe_resource_reference(&cb, NULL); + + util_report_result(pass); +} + +#define NV12_WIDTH 2560 +#define NV12_HEIGHT 1440 + +static bool +nv12_validate_resource_fields(struct pipe_resource *tex) +{ + return tex->format == util_format_get_plane_format(PIPE_FORMAT_NV12, 0) && + tex->width0 == NV12_WIDTH && + tex->height0 == NV12_HEIGHT && + tex->last_level == 0 && + tex->usage == PIPE_USAGE_DEFAULT && + tex->next && + tex->next->format == util_format_get_plane_format(PIPE_FORMAT_NV12, 1) && + tex->next->width0 == tex->width0 / 2 && + tex->next->height0 == tex->height0 / 2 && + tex->next->usage == tex->usage; +} + +/* This test enforces the behavior of NV12 allocation and exports. */ +static void +test_nv12(struct pipe_screen *screen) +{ + struct pipe_resource *tex = util_create_texture2d(screen, NV12_WIDTH, NV12_HEIGHT, + PIPE_FORMAT_NV12, 1); + + if (!tex) { + printf("resource_create failed\n"); + util_report_result(false); + return; + } + + if (!nv12_validate_resource_fields(tex)) { + printf("incorrect pipe_resource fields\n"); + util_report_result(false); + return; + } + + /* resource_get_param */ + if (screen->resource_get_param) { + struct { + uint64_t handle, dmabuf, offset, stride, planes; + } handle[3]; + + /* Export */ + for (unsigned i = 0; i < 3; i++) { + struct pipe_resource *res = i == 2 ? tex->next : tex; + unsigned plane = i == 2 ? 0 : i; + + if (!screen->resource_get_param(screen, NULL, res, plane, 0, + PIPE_RESOURCE_PARAM_HANDLE_TYPE_KMS, + 0, &handle[i].handle)) { + printf("resource_get_param failed\n"); + util_report_result(false); + goto cleanup; + } + + if (!screen->resource_get_param(screen, NULL, res, plane, 0, + PIPE_RESOURCE_PARAM_HANDLE_TYPE_FD, + 0, &handle[i].dmabuf)) { + printf("resource_get_param failed\n"); + util_report_result(false); + goto cleanup; + } + + if (!screen->resource_get_param(screen, NULL, res, plane, 0, + PIPE_RESOURCE_PARAM_OFFSET, + 0, &handle[i].offset)) { + printf("resource_get_param failed\n"); + util_report_result(false); + goto cleanup; + } + + if (!screen->resource_get_param(screen, NULL, res, plane, 0, + PIPE_RESOURCE_PARAM_STRIDE, + 0, &handle[i].stride)) { + printf("resource_get_param failed\n"); + util_report_result(false); + goto cleanup; + } + + if (!screen->resource_get_param(screen, NULL, res, plane, 0, + PIPE_RESOURCE_PARAM_NPLANES, + 0, &handle[i].planes)) { + printf("resource_get_param failed\n"); + util_report_result(false); + goto cleanup; + } + } + + /* Validate export. */ + bool get_param_pass = /* Sanity checking */ + handle[0].handle && handle[1].handle && handle[2].handle && + handle[0].dmabuf && handle[1].dmabuf && handle[2].dmabuf && + handle[0].stride && handle[1].stride && handle[2].stride && + handle[0].planes == 2 && + handle[1].planes == 2 && + handle[2].planes == 2 && + /* Different planes */ + handle[0].handle == handle[1].handle && + handle[0].offset != handle[1].offset && + /* Same planes. */ + handle[1].handle == handle[2].handle && + handle[1].stride == handle[2].stride && + handle[1].offset == handle[2].offset; + + if (!get_param_pass) { + printf("resource_get_param returned incorrect values\n"); + util_report_result(false); + goto cleanup; + } + } + + /* resource_get_handle */ + struct winsys_handle handle[4] = {{0}}; + + /* Export */ + for (unsigned i = 0; i < 4; i++) { + handle[i].type = i < 2 ? WINSYS_HANDLE_TYPE_KMS : WINSYS_HANDLE_TYPE_FD; + handle[i].plane = i % 2; + + if (!screen->resource_get_handle(screen, NULL, tex, &handle[i], 0)) { + printf("resource_get_handle failed\n"); + util_report_result(false); + goto cleanup; + } + } + + /* Validate export. */ + bool get_handle_pass = /* Sanity checking */ + handle[0].handle && handle[1].handle && + handle[0].stride && handle[1].stride && + handle[2].handle && handle[3].handle && + handle[2].stride && handle[3].stride && + /* KMS - different planes */ + handle[0].handle == handle[1].handle && + handle[0].offset != handle[1].offset && + /* DMABUF - different planes */ + handle[2].offset != handle[3].offset && + /* KMS and DMABUF equivalence */ + handle[0].offset == handle[2].offset && + handle[1].offset == handle[3].offset && + handle[0].stride == handle[2].stride && + handle[1].stride == handle[3].stride; + + if (!get_handle_pass) { + printf("resource_get_handle returned incorrect values\n"); + util_report_result(false); + goto cleanup; + } + + util_report_result(true); + +cleanup: + pipe_resource_reference(&tex, NULL); +} + /** * Run all tests. This should be run with a clean context after * context_create. @@ -806,9 +1035,14 @@ util_run_tests(struct pipe_screen *screen) test_texture_barrier(ctx, false, i); for (int i = 1; i <= 8; i = i * 2) test_texture_barrier(ctx, true, i); + ctx->destroy(ctx); + ctx = screen->context_create(screen, NULL, PIPE_CONTEXT_COMPUTE_ONLY); + test_compute_clear_image(ctx); ctx->destroy(ctx); + test_nv12(screen); + puts("Done. Exiting.."); exit(0); }