#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"
#include "tgsi/tgsi_strings.h"
#include "tgsi/tgsi_text.h"
#include "cso_cache/cso_context.h"
+#include "state_tracker/winsys_handle.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.height0 = height;
templ.depth0 = 1;
templ.array_size = 1;
+ templ.nr_samples = num_samples;
+ templ.nr_storage_samples = num_samples;
templ.format = format;
templ.usage = PIPE_USAGE_DEFAULT;
templ.bind = PIPE_BIND_SAMPLER_VIEW |
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);
}
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 *
struct pipe_context *ctx,
bool window_space)
{
- static const uint vs_attribs[] = {
+ static const enum tgsi_semantic vs_attribs[] = {
TGSI_SEMANTIC_POSITION,
TGSI_SEMANTIC_GENERIC
};
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
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.
*
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++) {
expected[e*4], expected[e*4+1],
expected[e*4+2], expected[e*4+3]);
printf("Got: %.3f, %.3f, %.3f, %.3f\n",
- probe[0], probe[1], probe[2], probe[2]);
+ probe[0], probe[1], probe[2], probe[3]);
pass = false;
goto done;
}
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,
return;
}
- cso = cso_create_context(ctx);
+ 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. */
return;
}
- cso = cso_create_context(ctx);
+ 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);
fs = util_make_fragment_tex_shader(ctx, tgsi_tex_target,
TGSI_INTERPOLATE_LINEAR,
TGSI_RETURN_TYPE_FLOAT,
- TGSI_RETURN_TYPE_FLOAT);
+ TGSI_RETURN_TYPE_FLOAT, false, false);
cso_set_fragment_shader_handle(cso, fs);
/* Vertex shader. */
tgsi_texture_names[tgsi_tex_target]);
}
-static void
-null_constant_buffer(struct pipe_context *ctx)
+void
+util_test_constant_buffer(struct pipe_context *ctx,
+ struct pipe_resource *constbuf)
{
struct cso_context *cso;
struct pipe_resource *cb;
bool pass = true;
static const float zero[] = {0, 0, 0, 0};
- cso = cso_create_context(ctx);
+ 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_constant_buffer(ctx, PIPE_SHADER_FRAGMENT, 0, NULL);
+ 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]\n"
+ "DCL CONST[0][0]\n"
"DCL OUT[0], COLOR\n"
- "MOV OUT[0], CONST[0]\n"
+ "MOV OUT[0], CONST[0][0]\n"
"END\n";
struct tgsi_token tokens[1000];
struct pipe_shader_state state;
struct pipe_query *query;
union pipe_query_result qresult;
- cso = cso_create_context(ctx);
+ 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. */
util_report_result(qresult.u64 == 2);
}
+#if defined(PIPE_OS_LINUX) && defined(HAVE_LIBDRM)
+#include <libsync.h>
+#else
+#define sync_merge(str, fd1, fd2) (-1)
+#define sync_wait(fd, timeout) (-1)
+#endif
+
+static void
+test_sync_file_fences(struct pipe_context *ctx)
+{
+ struct pipe_screen *screen = ctx->screen;
+ 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, 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);
+ ctx->flush(ctx, &tex_fence, PIPE_FLUSH_FENCE_FD);
+ pass = pass && buf_fence && tex_fence;
+
+ /* Export fences. */
+ int buf_fd = screen->fence_get_fd(screen, buf_fence);
+ int tex_fd = screen->fence_get_fd(screen, tex_fence);
+ pass = pass && buf_fd >= 0 && tex_fd >= 0;
+
+ /* Merge fences. */
+ int merged_fd = sync_merge("test", buf_fd, tex_fd);
+ pass = pass && merged_fd >= 0;
+
+ /* (Re)import all fences. */
+ struct pipe_fence_handle *re_buf_fence = NULL, *re_tex_fence = NULL;
+ struct pipe_fence_handle *merged_fence = NULL;
+ ctx->create_fence_fd(ctx, &re_buf_fence, buf_fd, fd_type);
+ ctx->create_fence_fd(ctx, &re_tex_fence, tex_fd, fd_type);
+ ctx->create_fence_fd(ctx, &merged_fence, merged_fd, fd_type);
+ pass = pass && re_buf_fence && re_tex_fence && merged_fence;
+
+ /* Run another clear after waiting for everything. */
+ struct pipe_fence_handle *final_fence = NULL;
+ ctx->fence_server_sync(ctx, merged_fence);
+ value = 0xff;
+ ctx->clear_buffer(ctx, buf, 0, buf->width0, &value, sizeof(value));
+ ctx->flush(ctx, &final_fence, PIPE_FLUSH_FENCE_FD);
+ pass = pass && final_fence;
+
+ /* Wait for the last fence. */
+ int final_fd = screen->fence_get_fd(screen, final_fence);
+ pass = pass && final_fd >= 0;
+ pass = pass && sync_wait(final_fd, -1) == 0;
+
+ /* Check that all fences are signalled. */
+ pass = pass && sync_wait(buf_fd, 0) == 0;
+ pass = pass && sync_wait(tex_fd, 0) == 0;
+ pass = pass && sync_wait(merged_fd, 0) == 0;
+
+ pass = pass && screen->fence_finish(screen, NULL, buf_fence, 0);
+ pass = pass && screen->fence_finish(screen, NULL, tex_fence, 0);
+ pass = pass && screen->fence_finish(screen, NULL, re_buf_fence, 0);
+ pass = pass && screen->fence_finish(screen, NULL, re_tex_fence, 0);
+ pass = pass && screen->fence_finish(screen, NULL, merged_fence, 0);
+ pass = pass && screen->fence_finish(screen, NULL, final_fence, 0);
+
+ /* Cleanup. */
+#ifndef PIPE_OS_WINDOWS
+ if (buf_fd >= 0)
+ close(buf_fd);
+ if (tex_fd >= 0)
+ close(tex_fd);
+ if (merged_fd >= 0)
+ close(merged_fd);
+ if (final_fd >= 0)
+ close(final_fd);
+#endif
+
+ screen->fence_reference(screen, &buf_fence, NULL);
+ screen->fence_reference(screen, &tex_fence, NULL);
+ screen->fence_reference(screen, &re_buf_fence, NULL);
+ screen->fence_reference(screen, &re_tex_fence, NULL);
+ screen->fence_reference(screen, &merged_fence, NULL);
+ 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,
+ unsigned num_samples)
+{
+ struct cso_context *cso;
+ struct pipe_resource *cb;
+ 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, name);
+ return;
+ }
+ if (use_fbfetch &&
+ !ctx->screen->get_param(ctx->screen, PIPE_CAP_FBFETCH)) {
+ 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, 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 (unsigned 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";
+ } else {
+ struct pipe_sampler_view templ = {{0}};
+ 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. */
+ 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, name);
+ return;
+ }
+ pipe_shader_state_from_tgsi(&state, tokens);
+
+ void *fs = ctx->create_fs_state(ctx, &state);
+ cso_set_fragment_shader_handle(cso, fs);
+
+ /* Vertex shader. */
+ 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);
+ }
+ 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, 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.
tgsi_vs_window_space_position(ctx);
null_sampler_view(ctx, TGSI_TEXTURE_2D);
null_sampler_view(ctx, TGSI_TEXTURE_BUFFER);
- null_constant_buffer(ctx);
+ util_test_constant_buffer(ctx, NULL);
+ test_sync_file_fences(ctx);
+
+ 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);
+ 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);
}