#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
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 *
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
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++) {
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,
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);
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.
test_compute_clear_image(ctx);
ctx->destroy(ctx);
+ test_nv12(screen);
+
puts("Done. Exiting..");
exit(0);
}