#include #include #include #include #include #include #include #include #include #include #include #include const int BATCH_BUFFER_SIZE = 524288; /* From media_libva.c */ int drm_fd = 0; drm_intel_bufmgr *buf_mgr; unsigned int FourCC = 842094158; #define Width 720 #define Height 576 int alignedW = (Width + 127) & ~127; int iSize = (3 * ((Height + 31) & ~31)) / 2; drm_intel_bo *surface_bo = NULL; void init() { static int drm_fd = -1; drm_fd = open("/dev/dri/card0", O_RDWR); if (drm_fd < 0) { printf("error: can't open DRM connection!\n"); _exit(-1); } buf_mgr = intel_bufmgr_gem_init(drm_fd, BATCH_BUFFER_SIZE); if (buf_mgr == NULL) { printf("intel_bufmgr_gem_init Failed!\n"); _exit(-1); } intel_bufmgr_gem_enable_reuse(buf_mgr); } void create() { int cpp = 1; uint32_t tiling_mode = I915_TILING_Y; unsigned long pitch = 0; unsigned long flags = 0; surface_bo = drm_intel_bo_alloc_tiled(buf_mgr, "Surface", alignedW, iSize, cpp, &tiling_mode, &pitch, flags); if (surface_bo == NULL) { printf("intel_bo_alloc_tiled error\n"); _exit(-1); } } void writeOrTestFrame(unsigned long child, unsigned int frame, int test) { unsigned int totalBytes = alignedW * iSize; unsigned int totalDWords = totalBytes >> 2; unsigned long i; unsigned int v = (frame << 20) | (child << 24); volatile unsigned int *image_data = NULL; volatile unsigned int r; drm_intel_bo_reference(surface_bo); drm_intel_bo_wait_rendering(surface_bo); drm_intel_gem_bo_map_gtt(surface_bo); image_data = (unsigned int *)surface_bo->virtual; for (i = 0; i < totalDWords; ++i) { if (test) { r = image_data[i]; if (r != v) { printf("Child %2lu: Readback failed at Frame: %lu, DWord: %lu", child, (unsigned long) frame, (unsigned long)i); printf(" (Expected 0x%08lx, Got: 0x%08lx)\n", (unsigned long) v, (unsigned long)r); _exit (-1); } ++v; } else { image_data[i] = v; r = image_data[i]; if (r != v) { printf("Child %2lu: Write failed at Frame: %lu, DWord: %lu", child, (unsigned long) frame, (unsigned long)i); printf(" (Write 0x%08lx, Got: 0x%08lx)\n", (unsigned long) v, (unsigned long)r); _exit (-1); } ++v; } } drm_intel_gem_bo_unmap_gtt(surface_bo); surface_bo->virtual = NULL; drm_intel_bo_unreference(surface_bo); } void test_proc(unsigned long child) { unsigned int i; init(); create(); for (i = 0; i < 10; ++i) { writeOrTestFrame(child, i, 0); writeOrTestFrame(child, i, 1); } _exit(0); } int main(int argc, char **argv) { unsigned long num_forks = 0; unsigned long i; int have_procs = 0; pid_t *pids = NULL; int *results = NULL; int result = -1; for (i = 1; i < argc; ++i) { if (strcmp(argv[i], "-procs") == 0) { ++i; num_forks = strtoul(argv[i], 0, 10); have_procs = 1; } } if (have_procs == 0) { fprintf(stderr, "Usage: %s -procs \n", argv[0]); exit(-1); } /* Fork the processes */ pids = calloc(sizeof(pid_t), num_forks); results = calloc(sizeof(results[0]), num_forks); for (i = 0; i < num_forks; ++i) { printf("Forking child %lu...\n", i); pid_t stat = fork(); if (stat == 0) { /* A Child */ test_proc(i); } else if (stat > 0) { /* The Parent, saved PID */ pids[i] = stat; } else { fprintf(stderr, "Failed to fork child %lu\n", i); exit(-1); } } /* Wait for the children to complete */ result = 0; printf("Waiting for child processes...\n"); for (i = 0; i < num_forks; ++i) { if (waitpid(pids[i], results+i, 0) < 0) { fprintf(stderr, "Failed to waitpid on child %lu (Process %lu)\n", i, (unsigned long)pids[i]); result = -1; } } /* Report results */ if (result == 0) { for (i = 0; i < num_forks; ++i) { if (results[i]== 0) printf("Child %lu (process %lu) PASSED\n", i, (unsigned long)pids[i]); else { printf("Child %lu (process %lu) FAILED\n", i, (unsigned long)pids[i]); result = -1; } } } if (result == 0) printf("\nPASSED\n"); else printf("\nFAILED\n"); return result; }