From 05f872370420117a0d8e4c3f8d5138c1f6d4fddd Mon Sep 17 00:00:00 2001 From: Thomas White Date: Sun, 8 Nov 2009 22:52:12 +0100 Subject: Add new test: gdrm-burst-cmdq --- Makefile | 8 +- gdrm-burst-cmdq.c | 296 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 302 insertions(+), 2 deletions(-) create mode 100644 gdrm-burst-cmdq.c diff --git a/Makefile b/Makefile index 3859a82..c361b6c 100644 --- a/Makefile +++ b/Makefile @@ -3,7 +3,7 @@ LIBS=-lX11 -lXext -ldrm -ldrm_glamo CC=gcc default: gdri-cmdq-submission gdri-mem-manager gdri-buf-cmdq gdrm-gem-mmap \ - gdrm-kms-addfb + gdrm-kms-addfb gdrm-burst-cmdq .c.o: $(CC) -c ${CFLAGS} ${CROSS_CFLAGS} $*.c @@ -23,9 +23,12 @@ gdrm-gem-mmap: gdrm-gem-mmap.o drmtest.o gdrm-kms-addfb: gdrm-kms-addfb.o drmtest.o $(CC) gdrm-kms-addfb.o drmtest.o -o gdrm-kms-addfb ${LIBS} +gdrm-burst-cmdq: gdrm-burst-cmdq.o drmtest.o + $(CC) gdrm-burst-cmdq.o drmtest.o -o gdrm-burst-cmdq ${LIBS} + clean: rm -rf dri2.o gdri-cmdq-submission.o utils.o gdri-cmdq-submission \ - gdri-mem-manager gdri-buf-cmdq gdrm-gem-mmap + gdri-mem-manager gdri-buf-cmdq gdrm-gem-mmap gdrm-burst-cmdq install: install -d -m 755 ${PREFIX}/bin @@ -34,5 +37,6 @@ install: install -m 755 gdri-buf-cmdq ${PREFIX}/bin install -m 755 gdrm-gem-mmap ${PREFIX}/bin install -m 755 gdrm-kms-addfb ${PREFIX}/bin + install -m 755 gdrm-burst-cmdq ${PREFIX}/bin .PHONY: clean install default diff --git a/gdrm-burst-cmdq.c b/gdrm-burst-cmdq.c new file mode 100644 index 0000000..486aa96 --- /dev/null +++ b/gdrm-burst-cmdq.c @@ -0,0 +1,296 @@ +/* + * gdrm-burst-cmdq.c + * + * Test Glamo DRM Burst Commands + * + * (c) 2009 Thomas White + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * Copyright © 2008 Intel Corporation + * + * + * Based on tests/gem_mmap.c from libdrm, to which the following notice applies: + * + * Copyright © 2008 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + * + * Authors: + * Eric Anholt + * + */ + +#define _FILE_OFFSET_BITS 64 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "drm.h" +#include "glamo_drm.h" +#include "drmtest.h" +#include "glamo-regs.h" + +#define OBJECT_SIZE (640*480*2) + + +struct glamo_context +{ + int drm_fd; /* DRM fd */ + + uint16_t *cmdq_drm; /* Command queue cache */ + uint16_t cmd_burst_base; + int cmdq_drm_used; + int cmdq_drm_size; + int cmdq_obj_used; + uint32_t *cmdq_objs; + unsigned int *cmdq_obj_pos; +}; +typedef struct glamo_context glamoContext; + + +struct glamo_context *gCtx; + + +static uint16_t random_colour() +{ + uint16_t c; + + c = random() & 0xff; + c |= (random() & 0xff) << 8; + + return c; +} + + +/* Submit the prepared command sequence to the kernel */ +void glamoDRMDispatch(glamoContext *gCtx) +{ + drm_glamo_cmd_burst_t burst; + int r; + + burst.base = gCtx->cmd_burst_base; + burst.data = gCtx->cmdq_drm; + burst.bufsz = gCtx->cmdq_drm_used * 2; /* -> bytes */ + burst.nobjs = gCtx->cmdq_obj_used; + burst.objs = gCtx->cmdq_objs; + burst.obj_pos = gCtx->cmdq_obj_pos; + + printf("%i\n", gCtx->cmdq_objs[0]); + printf("%i\n", gCtx->cmdq_obj_pos[0]); + + for ( r=0; rcmdq_drm_used; r++ ) { + printf("0x%02x = %4i : %04x = %4i\n", r, r, + gCtx->cmdq_drm[r], gCtx->cmdq_drm[r]); + } + + r = drmCommandWrite(gCtx->drm_fd, DRM_GLAMO_CMDBURST, + &burst, sizeof(burst)); + if ( r != 0 ) { + fprintf(stderr, "DRM_GLAMO_CMDBURST failed\n"); + } + + /* Reset counts to zero for the next sequence */ + gCtx->cmdq_obj_used = 0; + gCtx->cmdq_drm_used = 0; +} + + +void glamoDRMAddData(glamoContext *gCtx, uint32_t val, int len) +{ + if ( gCtx->cmdq_drm_used+4 > gCtx->cmdq_drm_size ) { + fprintf(stderr, "Burst command too large\n"); + return; + } + + /* Record command */ + if ( len == 2 ) { + gCtx->cmdq_drm[gCtx->cmdq_drm_used++] = val & 0xffff; + } else if ( len == 4 ) { + gCtx->cmdq_drm[gCtx->cmdq_drm_used++] = val & 0x0000ffff; + gCtx->cmdq_drm[gCtx->cmdq_drm_used++] = val & 0xffff0000; + } else { + fprintf(stderr, "Wrong command length!\n"); + } +} + + +void glamoDRMAddBO(glamoContext *gCtx, int bo) +{ + if ( gCtx->cmdq_drm_used+4 > gCtx->cmdq_drm_size ) { + fprintf(stderr, "Burst command too large\n"); + return; + } + + /* Record object position */ + gCtx->cmdq_objs[gCtx->cmdq_obj_used] = bo; + /* -> bytes */ + printf("recording at %i (%i)\n", + gCtx->cmdq_drm_used*2, gCtx->cmdq_obj_used); + gCtx->cmdq_obj_pos[gCtx->cmdq_obj_used] = gCtx->cmdq_drm_used * 2; + gCtx->cmdq_obj_used++; + + /* Record command */ + gCtx->cmdq_drm[gCtx->cmdq_drm_used++] = 0x0000; + gCtx->cmdq_drm[gCtx->cmdq_drm_used++] = 0x0000; +} + + +void glamoDRMStartBurst(glamoContext *gCtx, uint16_t base) +{ + gCtx->cmd_burst_base = base; +} + + +void glamoInitCmdqCache(glamoContext *gCtx) +{ + gCtx->cmdq_objs = malloc(1024); + gCtx->cmdq_obj_pos = malloc(1024); + gCtx->cmdq_obj_used = 0; + gCtx->cmdq_drm_used = 0; + gCtx->cmdq_drm_size = 4 * 1024; + gCtx->cmdq_drm = malloc(gCtx->cmdq_drm_size); +} + + +int main(int argc, char **argv) +{ + int fd; + struct drm_glamo_gem_create create; + struct drm_glamo_gem_mmap mmap_arg; + struct drm_gem_close unref; + uint8_t expected[OBJECT_SIZE]; + uint8_t buf[OBJECT_SIZE]; + uint8_t *addr; + uint16_t *addr16; + int ret; + int handle; + char tmp[4]; + int i; + drmModeResPtr r; + drmModeCrtcPtr crtc; + int crtc_id; + int conn_id; + int fb_id; + uint32_t old_buffer_id; + + fd = drm_open_any(); + + printf("Creating a GEM object\n"); + memset(&create, 0, sizeof(create)); + create.size = OBJECT_SIZE; + ret = ioctl(fd, DRM_IOCTL_GLAMO_GEM_CREATE, &create); + assert(ret == 0); + handle = create.handle; + + gCtx = malloc(sizeof(*gCtx)); + gCtx->drm_fd = fd; + glamoInitCmdqCache(gCtx); + + r = drmModeGetResources(fd); + if ( r == NULL ) { + printf("Could not get DRM resources\n"); + return 1; + } + printf("There are %i CRTCs, %i connectors, %i encoders" + " and %i framebuffers\n", + r->count_crtcs, r->count_connectors, r->count_encoders, + r->count_fbs); + + crtc_id = r->crtcs[0]; + conn_id = r->connectors[0]; + printf("The first CRTC ID is %i\n", crtc_id); + printf("The first connector ID is %i\n", conn_id); + + drmModeAddFB(fd, 480, 640, 16, 16, 480*2, handle, &fb_id); + printf("My new FB handle is %i\n", fb_id); + if (!fb_id) { + printf("Could not add FB\n"); + return 1; + } + + printf("Getting CRTC info\n"); + crtc = drmModeGetCrtc(fd, crtc_id); + old_buffer_id = crtc->buffer_id; + printf("Old FB handle is %i\n", old_buffer_id); + + printf("crtc=%p\n", crtc); + if ( drmModeSetCrtc(fd, crtc_id, fb_id, 0, 0, r->connectors, 1, + &(crtc->mode)) ) { + printf("drmModeSetCrtc returned %i\n", ret); + } + + do { + + glamoDRMStartBurst(gCtx, GLAMO_REG_2D_DST_X); + glamoDRMAddData(gCtx, 0, 2); + glamoDRMAddData(gCtx, 0, 2); + glamoDRMAddBO(gCtx, handle); + glamoDRMAddData(gCtx, 960 & 0x7ff, 2); + glamoDRMAddData(gCtx, 640, 2); + glamoDRMAddData(gCtx, 480, 2); + glamoDRMAddData(gCtx, 640, 2); + glamoDRMAddData(gCtx, 0x0000, 2); + glamoDRMAddData(gCtx, 0x0000, 2); + glamoDRMAddData(gCtx, random_colour(), 2); + glamoDRMDispatch(gCtx); + + glamoDRMStartBurst(gCtx, GLAMO_REG_2D_COMMAND1); + glamoDRMAddData(gCtx, 0x0000, 2); /* Cmd param 1 */ + glamoDRMAddData(gCtx, 0xf0 << 8, 2); /* Cmd param 2 */ + glamoDRMAddData(gCtx, 0x0000, 2); /* Cmd param 3 */ + glamoDRMDispatch(gCtx); + + printf("Press to continue, q to finish..."); + fgets(tmp, 3, stdin); + + } while ( tmp[0] != 'q' ); + + printf("Removing FB\n"); + drmModeRmFB(fd, fb_id); + + printf("Restoring original FB\n"); + if ( drmModeSetCrtc(fd, crtc_id, old_buffer_id, 0, 0, r->connectors, 1, + &(crtc->mode)) ) { + printf("drmModeSetCrtc returned %i\n", ret); + } + + close(fd); + + return 0; +} -- cgit v1.2.3