test_decode.c revision baaff307
1e88f27b3Smrg/*
2e88f27b3Smrg * Copyright © 2011 Intel Corporation
3e88f27b3Smrg *
4e88f27b3Smrg * Permission is hereby granted, free of charge, to any person obtaining a
5e88f27b3Smrg * copy of this software and associated documentation files (the "Software"),
6e88f27b3Smrg * to deal in the Software without restriction, including without limitation
7e88f27b3Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8e88f27b3Smrg * and/or sell copies of the Software, and to permit persons to whom the
9e88f27b3Smrg * Software is furnished to do so, subject to the following conditions:
10e88f27b3Smrg *
11e88f27b3Smrg * The above copyright notice and this permission notice (including the next
12e88f27b3Smrg * paragraph) shall be included in all copies or substantial portions of the
13e88f27b3Smrg * Software.
14e88f27b3Smrg *
15e88f27b3Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16e88f27b3Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17e88f27b3Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18e88f27b3Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19e88f27b3Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20e88f27b3Smrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21e88f27b3Smrg * IN THE SOFTWARE.
22e88f27b3Smrg */
23e88f27b3Smrg
24baaff307Smrg#ifdef HAVE_CONFIG_H
25baaff307Smrg#include "config.h"
26baaff307Smrg#endif
27e88f27b3Smrg
28e88f27b3Smrg#include <string.h>
29e88f27b3Smrg#include <stdlib.h>
30e88f27b3Smrg#include <stdio.h>
31e88f27b3Smrg#include <unistd.h>
32e88f27b3Smrg#include <fcntl.h>
33e88f27b3Smrg#include <sys/types.h>
34e88f27b3Smrg#include <sys/stat.h>
35e88f27b3Smrg#include <err.h>
36e88f27b3Smrg
37baaff307Smrg#include "libdrm.h"
38e88f27b3Smrg#include "intel_bufmgr.h"
39e88f27b3Smrg#include "intel_chipset.h"
40e88f27b3Smrg
41e88f27b3Smrg#define HW_OFFSET 0x12300000
42e88f27b3Smrg
43e88f27b3Smrgstatic void
44e88f27b3Smrgusage(void)
45e88f27b3Smrg{
46e88f27b3Smrg	fprintf(stderr, "usage:\n");
47e88f27b3Smrg	fprintf(stderr, "  test_decode <batch>\n");
48e88f27b3Smrg	fprintf(stderr, "  test_decode <batch> -dump\n");
49e88f27b3Smrg	exit(1);
50e88f27b3Smrg}
51e88f27b3Smrg
52e88f27b3Smrgstatic void
53e88f27b3Smrgread_file(const char *filename, void **ptr, size_t *size)
54e88f27b3Smrg{
55e88f27b3Smrg	int fd, ret;
56e88f27b3Smrg	struct stat st;
57e88f27b3Smrg
58e88f27b3Smrg	fd = open(filename, O_RDONLY);
59e88f27b3Smrg	if (fd == -1)
60e88f27b3Smrg		errx(1, "couldn't open `%s'", filename);
61e88f27b3Smrg
62e88f27b3Smrg	ret = fstat(fd, &st);
63e88f27b3Smrg	if (ret)
64e88f27b3Smrg		errx(1, "couldn't stat `%s'", filename);
65e88f27b3Smrg
66e88f27b3Smrg	*size = st.st_size;
67baaff307Smrg	*ptr = drm_mmap(NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0);
68e88f27b3Smrg	if (*ptr == MAP_FAILED)
69e88f27b3Smrg		errx(1, "couldn't map `%s'", filename);
70e88f27b3Smrg
71e88f27b3Smrg	close(fd);
72e88f27b3Smrg}
73e88f27b3Smrg
74e88f27b3Smrgstatic void
75e88f27b3Smrgdump_batch(struct drm_intel_decode *ctx, const char *batch_filename)
76e88f27b3Smrg{
77e88f27b3Smrg	void *batch_ptr;
78e88f27b3Smrg	size_t batch_size;
79e88f27b3Smrg
80e88f27b3Smrg	read_file(batch_filename, &batch_ptr, &batch_size);
81e88f27b3Smrg
82e88f27b3Smrg	drm_intel_decode_set_batch_pointer(ctx, batch_ptr, HW_OFFSET,
83e88f27b3Smrg					   batch_size / 4);
84e88f27b3Smrg	drm_intel_decode_set_output_file(ctx, stdout);
85e88f27b3Smrg
86e88f27b3Smrg	drm_intel_decode(ctx);
87e88f27b3Smrg}
88e88f27b3Smrg
89e88f27b3Smrgstatic void
90e88f27b3Smrgcompare_batch(struct drm_intel_decode *ctx, const char *batch_filename)
91e88f27b3Smrg{
92e88f27b3Smrg	FILE *out = NULL;
93e88f27b3Smrg	void *ptr, *ref_ptr, *batch_ptr;
94e88f27b3Smrg	size_t size, ref_size, batch_size;
95e88f27b3Smrg	const char *ref_suffix = "-ref.txt";
96e88f27b3Smrg	char *ref_filename;
97e88f27b3Smrg
98e88f27b3Smrg	ref_filename = malloc(strlen(batch_filename) + strlen(ref_suffix) + 1);
99e88f27b3Smrg	sprintf(ref_filename, "%s%s", batch_filename, ref_suffix);
100e88f27b3Smrg
101e88f27b3Smrg	/* Read the batch and reference. */
102e88f27b3Smrg	read_file(batch_filename, &batch_ptr, &batch_size);
103e88f27b3Smrg	read_file(ref_filename, &ref_ptr, &ref_size);
104e88f27b3Smrg
105e88f27b3Smrg	/* Set up our decode output in memory, because I don't want to
106e88f27b3Smrg	 * figure out how to output to a file in a safe and sane way
107e88f27b3Smrg	 * inside of an automake project's test infrastructure.
108e88f27b3Smrg	 */
109e88f27b3Smrg#ifdef HAVE_OPEN_MEMSTREAM
110e88f27b3Smrg	out = open_memstream((char **)&ptr, &size);
111e88f27b3Smrg#else
112e88f27b3Smrg	fprintf(stderr, "platform lacks open_memstream, skipping.\n");
113e88f27b3Smrg	exit(77);
114e88f27b3Smrg#endif
115e88f27b3Smrg
116e88f27b3Smrg	drm_intel_decode_set_batch_pointer(ctx, batch_ptr, HW_OFFSET,
117e88f27b3Smrg					   batch_size / 4);
118e88f27b3Smrg	drm_intel_decode_set_output_file(ctx, out);
119e88f27b3Smrg
120e88f27b3Smrg	drm_intel_decode(ctx);
121e88f27b3Smrg
122e88f27b3Smrg	if (strcmp(ref_ptr, ptr) != 0) {
123e88f27b3Smrg		fprintf(stderr, "Decode mismatch with reference `%s'.\n",
124e88f27b3Smrg			ref_filename);
125e88f27b3Smrg		fprintf(stderr, "You can dump the new output using:\n");
126e88f27b3Smrg		fprintf(stderr, "  test_decode \"%s\" -dump\n", batch_filename);
127e88f27b3Smrg		exit(1);
128e88f27b3Smrg	}
129e88f27b3Smrg
130e88f27b3Smrg	fclose(out);
131e88f27b3Smrg	free(ref_filename);
132e88f27b3Smrg	free(ptr);
133e88f27b3Smrg}
134e88f27b3Smrg
135e88f27b3Smrgstatic uint16_t
136e88f27b3Smrginfer_devid(const char *batch_filename)
137e88f27b3Smrg{
138e88f27b3Smrg	struct {
139e88f27b3Smrg		const char *name;
140e88f27b3Smrg		uint16_t devid;
141e88f27b3Smrg	} chipsets[] = {
142e88f27b3Smrg		{ "830",  0x3577},
143e88f27b3Smrg		{ "855",  0x3582},
144e88f27b3Smrg		{ "945",  0x2772},
145e88f27b3Smrg		{ "gen4", 0x2a02 },
146e88f27b3Smrg		{ "gm45", 0x2a42 },
147e88f27b3Smrg		{ "gen5", PCI_CHIP_ILD_G },
148e88f27b3Smrg		{ "gen6", PCI_CHIP_SANDYBRIDGE_GT2 },
149e88f27b3Smrg		{ "gen7", PCI_CHIP_IVYBRIDGE_GT2 },
150e88f27b3Smrg		{ "gen8", 0x1616 },
151e88f27b3Smrg		{ NULL, 0 },
152e88f27b3Smrg	};
153e88f27b3Smrg	int i;
154e88f27b3Smrg
155e88f27b3Smrg	for (i = 0; chipsets[i].name != NULL; i++) {
156e88f27b3Smrg		if (strstr(batch_filename, chipsets[i].name))
157e88f27b3Smrg			return chipsets[i].devid;
158e88f27b3Smrg	}
159e88f27b3Smrg
160e88f27b3Smrg	fprintf(stderr, "Couldn't guess chipset id from batch filename `%s'.\n",
161e88f27b3Smrg		batch_filename);
162e88f27b3Smrg	fprintf(stderr, "Must be contain one of:\n");
163e88f27b3Smrg	for (i = 0; chipsets[i].name != NULL; i++) {
164e88f27b3Smrg		fprintf(stderr, "  %s\n", chipsets[i].name);
165e88f27b3Smrg	}
166e88f27b3Smrg	exit(1);
167e88f27b3Smrg}
168e88f27b3Smrg
169e88f27b3Smrgint
170e88f27b3Smrgmain(int argc, char **argv)
171e88f27b3Smrg{
172e88f27b3Smrg	uint16_t devid;
173e88f27b3Smrg	struct drm_intel_decode *ctx;
174e88f27b3Smrg
175e88f27b3Smrg	if (argc < 2)
176e88f27b3Smrg		usage();
177e88f27b3Smrg
178e88f27b3Smrg
179e88f27b3Smrg	devid = infer_devid(argv[1]);
180e88f27b3Smrg
181e88f27b3Smrg	ctx = drm_intel_decode_context_alloc(devid);
182e88f27b3Smrg
183e88f27b3Smrg	if (argc == 3) {
184e88f27b3Smrg		if (strcmp(argv[2], "-dump") == 0)
185e88f27b3Smrg			dump_batch(ctx, argv[1]);
186e88f27b3Smrg		else
187e88f27b3Smrg			usage();
188e88f27b3Smrg	} else {
189e88f27b3Smrg		compare_batch(ctx, argv[1]);
190e88f27b3Smrg	}
191e88f27b3Smrg
192e88f27b3Smrg	drm_intel_decode_context_free(ctx);
193e88f27b3Smrg
194e88f27b3Smrg	return 0;
195e88f27b3Smrg}
196