test_decode.c revision 3f012e29
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 37e6188e58Smrg#include "libdrm_macros.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); 593f012e29Smrg if (fd < 0) 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; 94e6188e58Smrg#ifdef HAVE_OPEN_MEMSTREAM 95e6188e58Smrg size_t size; 96e6188e58Smrg#endif 97e6188e58Smrg size_t ref_size, batch_size; 98e88f27b3Smrg const char *ref_suffix = "-ref.txt"; 99e88f27b3Smrg char *ref_filename; 100e88f27b3Smrg 101e88f27b3Smrg ref_filename = malloc(strlen(batch_filename) + strlen(ref_suffix) + 1); 102e88f27b3Smrg sprintf(ref_filename, "%s%s", batch_filename, ref_suffix); 103e88f27b3Smrg 104e88f27b3Smrg /* Read the batch and reference. */ 105e88f27b3Smrg read_file(batch_filename, &batch_ptr, &batch_size); 106e88f27b3Smrg read_file(ref_filename, &ref_ptr, &ref_size); 107e88f27b3Smrg 108e88f27b3Smrg /* Set up our decode output in memory, because I don't want to 109e88f27b3Smrg * figure out how to output to a file in a safe and sane way 110e88f27b3Smrg * inside of an automake project's test infrastructure. 111e88f27b3Smrg */ 112e88f27b3Smrg#ifdef HAVE_OPEN_MEMSTREAM 113e88f27b3Smrg out = open_memstream((char **)&ptr, &size); 114e88f27b3Smrg#else 115e88f27b3Smrg fprintf(stderr, "platform lacks open_memstream, skipping.\n"); 116e88f27b3Smrg exit(77); 117e88f27b3Smrg#endif 118e88f27b3Smrg 119e88f27b3Smrg drm_intel_decode_set_batch_pointer(ctx, batch_ptr, HW_OFFSET, 120e88f27b3Smrg batch_size / 4); 121e88f27b3Smrg drm_intel_decode_set_output_file(ctx, out); 122e88f27b3Smrg 123e88f27b3Smrg drm_intel_decode(ctx); 124e88f27b3Smrg 125e88f27b3Smrg if (strcmp(ref_ptr, ptr) != 0) { 126e88f27b3Smrg fprintf(stderr, "Decode mismatch with reference `%s'.\n", 127e88f27b3Smrg ref_filename); 128e88f27b3Smrg fprintf(stderr, "You can dump the new output using:\n"); 129e88f27b3Smrg fprintf(stderr, " test_decode \"%s\" -dump\n", batch_filename); 130e88f27b3Smrg exit(1); 131e88f27b3Smrg } 132e88f27b3Smrg 133e88f27b3Smrg fclose(out); 134e88f27b3Smrg free(ref_filename); 135e88f27b3Smrg free(ptr); 136e88f27b3Smrg} 137e88f27b3Smrg 138e88f27b3Smrgstatic uint16_t 139e88f27b3Smrginfer_devid(const char *batch_filename) 140e88f27b3Smrg{ 141e88f27b3Smrg struct { 142e88f27b3Smrg const char *name; 143e88f27b3Smrg uint16_t devid; 144e88f27b3Smrg } chipsets[] = { 145e88f27b3Smrg { "830", 0x3577}, 146e88f27b3Smrg { "855", 0x3582}, 147e88f27b3Smrg { "945", 0x2772}, 148e88f27b3Smrg { "gen4", 0x2a02 }, 149e88f27b3Smrg { "gm45", 0x2a42 }, 150e88f27b3Smrg { "gen5", PCI_CHIP_ILD_G }, 151e88f27b3Smrg { "gen6", PCI_CHIP_SANDYBRIDGE_GT2 }, 152e88f27b3Smrg { "gen7", PCI_CHIP_IVYBRIDGE_GT2 }, 153e88f27b3Smrg { "gen8", 0x1616 }, 154e88f27b3Smrg { NULL, 0 }, 155e88f27b3Smrg }; 156e88f27b3Smrg int i; 157e88f27b3Smrg 158e88f27b3Smrg for (i = 0; chipsets[i].name != NULL; i++) { 159e88f27b3Smrg if (strstr(batch_filename, chipsets[i].name)) 160e88f27b3Smrg return chipsets[i].devid; 161e88f27b3Smrg } 162e88f27b3Smrg 163e88f27b3Smrg fprintf(stderr, "Couldn't guess chipset id from batch filename `%s'.\n", 164e88f27b3Smrg batch_filename); 165e88f27b3Smrg fprintf(stderr, "Must be contain one of:\n"); 166e88f27b3Smrg for (i = 0; chipsets[i].name != NULL; i++) { 167e88f27b3Smrg fprintf(stderr, " %s\n", chipsets[i].name); 168e88f27b3Smrg } 169e88f27b3Smrg exit(1); 170e88f27b3Smrg} 171e88f27b3Smrg 172e88f27b3Smrgint 173e88f27b3Smrgmain(int argc, char **argv) 174e88f27b3Smrg{ 175e88f27b3Smrg uint16_t devid; 176e88f27b3Smrg struct drm_intel_decode *ctx; 177e88f27b3Smrg 178e88f27b3Smrg if (argc < 2) 179e88f27b3Smrg usage(); 180e88f27b3Smrg 181e88f27b3Smrg 182e88f27b3Smrg devid = infer_devid(argv[1]); 183e88f27b3Smrg 184e88f27b3Smrg ctx = drm_intel_decode_context_alloc(devid); 185e88f27b3Smrg 186e88f27b3Smrg if (argc == 3) { 187e88f27b3Smrg if (strcmp(argv[2], "-dump") == 0) 188e88f27b3Smrg dump_batch(ctx, argv[1]); 189e88f27b3Smrg else 190e88f27b3Smrg usage(); 191e88f27b3Smrg } else { 192e88f27b3Smrg compare_batch(ctx, argv[1]); 193e88f27b3Smrg } 194e88f27b3Smrg 195e88f27b3Smrg drm_intel_decode_context_free(ctx); 196e88f27b3Smrg 197e88f27b3Smrg return 0; 198e88f27b3Smrg} 199