Back to index

libdrm  2.4.37
test_decode.c
Go to the documentation of this file.
00001 /*
00002  * Copyright © 2011 Intel Corporation
00003  *
00004  * Permission is hereby granted, free of charge, to any person obtaining a
00005  * copy of this software and associated documentation files (the "Software"),
00006  * to deal in the Software without restriction, including without limitation
00007  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
00008  * and/or sell copies of the Software, and to permit persons to whom the
00009  * Software is furnished to do so, subject to the following conditions:
00010  *
00011  * The above copyright notice and this permission notice (including the next
00012  * paragraph) shall be included in all copies or substantial portions of the
00013  * Software.
00014  *
00015  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00016  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00017  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
00018  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
00019  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
00020  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
00021  * IN THE SOFTWARE.
00022  */
00023 
00024 #include <string.h>
00025 #include <stdlib.h>
00026 #include <stdio.h>
00027 #include <unistd.h>
00028 #include <fcntl.h>
00029 #include <sys/types.h>
00030 #include <sys/stat.h>
00031 #include <sys/mman.h>
00032 #include <err.h>
00033 
00034 #include "config.h"
00035 #include "intel_bufmgr.h"
00036 #include "intel_chipset.h"
00037 
00038 #define HW_OFFSET 0x12300000
00039 
00040 static void
00041 usage(void)
00042 {
00043        fprintf(stderr, "usage:\n");
00044        fprintf(stderr, "  test_decode <batch>\n");
00045        fprintf(stderr, "  test_decode <batch> -dump\n");
00046        exit(1);
00047 }
00048 
00049 static void
00050 read_file(const char *filename, void **ptr, size_t *size)
00051 {
00052        int fd, ret;
00053        struct stat st;
00054 
00055        fd = open(filename, O_RDONLY);
00056        if (fd == -1)
00057               errx(1, "couldn't open `%s'", filename);
00058 
00059        ret = fstat(fd, &st);
00060        if (ret)
00061               errx(1, "couldn't stat `%s'", filename);
00062 
00063        *size = st.st_size;
00064        *ptr = mmap(NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0);
00065        if (*ptr == MAP_FAILED)
00066               errx(1, "couldn't map `%s'", filename);
00067 
00068        close(fd);
00069 }
00070 
00071 static void
00072 dump_batch(struct drm_intel_decode *ctx, const char *batch_filename)
00073 {
00074        void *batch_ptr;
00075        size_t batch_size;
00076 
00077        read_file(batch_filename, &batch_ptr, &batch_size);
00078 
00079        drm_intel_decode_set_batch_pointer(ctx, batch_ptr, HW_OFFSET,
00080                                       batch_size / 4);
00081        drm_intel_decode_set_output_file(ctx, stdout);
00082 
00083        drm_intel_decode(ctx);
00084 }
00085 
00086 static void
00087 compare_batch(struct drm_intel_decode *ctx, const char *batch_filename)
00088 {
00089        FILE *out = NULL;
00090        void *ptr, *ref_ptr, *batch_ptr;
00091        size_t size, ref_size, batch_size;
00092        const char *ref_suffix = "-ref.txt";
00093        char *ref_filename;
00094 
00095        ref_filename = malloc(strlen(batch_filename) + strlen(ref_suffix) + 1);
00096        sprintf(ref_filename, "%s%s", batch_filename, ref_suffix);
00097 
00098        /* Read the batch and reference. */
00099        read_file(batch_filename, &batch_ptr, &batch_size);
00100        read_file(ref_filename, &ref_ptr, &ref_size);
00101 
00102        /* Set up our decode output in memory, because I don't want to
00103         * figure out how to output to a file in a safe and sane way
00104         * inside of an automake project's test infrastructure.
00105         */
00106 #ifdef HAVE_OPEN_MEMSTREAM
00107        out = open_memstream((char **)&ptr, &size);
00108 #else
00109        fprintf(stderr, "platform lacks open_memstream, skipping.\n");
00110        exit(77);
00111 #endif
00112 
00113        drm_intel_decode_set_batch_pointer(ctx, batch_ptr, HW_OFFSET,
00114                                       batch_size / 4);
00115        drm_intel_decode_set_output_file(ctx, out);
00116 
00117        drm_intel_decode(ctx);
00118 
00119        if (strcmp(ref_ptr, ptr) != 0) {
00120               fprintf(stderr, "Decode mismatch with reference `%s'.\n",
00121                      ref_filename);
00122               fprintf(stderr, "You can dump the new output using:\n");
00123               fprintf(stderr, "  test_decode \"%s\" -dump\n", batch_filename);
00124               exit(1);
00125        }
00126 
00127        fclose(out);
00128        free(ref_filename);
00129        free(ptr);
00130 }
00131 
00132 static uint16_t
00133 infer_devid(const char *batch_filename)
00134 {
00135        struct {
00136               const char *name;
00137               uint16_t devid;
00138        } chipsets[] = {
00139               { "830",  0x3577},
00140               { "855",  0x3582},
00141               { "945",  0x2772},
00142               { "gen4", 0x2a02 },
00143               { "gm45", 0x2a42 },
00144               { "gen5", PCI_CHIP_ILD_G },
00145               { "gen6", PCI_CHIP_SANDYBRIDGE_GT2 },
00146               { "gen7", PCI_CHIP_IVYBRIDGE_GT2 },
00147               { NULL, 0 },
00148        };
00149        int i;
00150 
00151        for (i = 0; chipsets[i].name != NULL; i++) {
00152               if (strstr(batch_filename, chipsets[i].name))
00153                      return chipsets[i].devid;
00154        }
00155 
00156        fprintf(stderr, "Couldn't guess chipset id from batch filename `%s'.\n",
00157               batch_filename);
00158        fprintf(stderr, "Must be contain one of:\n");
00159        for (i = 0; chipsets[i].name != NULL; i++) {
00160               fprintf(stderr, "  %s\n", chipsets[i].name);
00161        }
00162        exit(1);
00163 }
00164 
00165 int
00166 main(int argc, char **argv)
00167 {
00168        uint16_t devid;
00169        struct drm_intel_decode *ctx;
00170 
00171        if (argc < 2)
00172               usage();
00173 
00174 
00175        devid = infer_devid(argv[1]);
00176 
00177        ctx = drm_intel_decode_context_alloc(devid);
00178 
00179        if (argc == 3) {
00180               if (strcmp(argv[2], "-dump") == 0)
00181                      dump_batch(ctx, argv[1]);
00182               else
00183                      usage();
00184        } else {
00185               compare_batch(ctx, argv[1]);
00186        }
00187 
00188        drm_intel_decode_context_free(ctx);
00189 
00190        return 0;
00191 }