1fa225cbcSrjs/************************************************************************** 2fa225cbcSrjs * 3fa225cbcSrjs * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. 4fa225cbcSrjs * All Rights Reserved. 5fa225cbcSrjs * 6fa225cbcSrjs * Permission is hereby granted, free of charge, to any person obtaining a 7fa225cbcSrjs * copy of this software and associated documentation files (the 8fa225cbcSrjs * "Software"), to deal in the Software without restriction, including 9fa225cbcSrjs * without limitation the rights to use, copy, modify, merge, publish, 10fa225cbcSrjs * distribute, sub license, and/or sell copies of the Software, and to 11fa225cbcSrjs * permit persons to whom the Software is furnished to do so, subject to 12fa225cbcSrjs * the following conditions: 13fa225cbcSrjs * 14fa225cbcSrjs * The above copyright notice and this permission notice (including the 15fa225cbcSrjs * next paragraph) shall be included in all copies or substantial portions 16fa225cbcSrjs * of the Software. 17fa225cbcSrjs * 18fa225cbcSrjs * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19fa225cbcSrjs * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20fa225cbcSrjs * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 21fa225cbcSrjs * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR 22fa225cbcSrjs * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 23fa225cbcSrjs * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 24fa225cbcSrjs * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25fa225cbcSrjs * 26fa225cbcSrjs **************************************************************************/ 27fa225cbcSrjs 28fa225cbcSrjs#include <stdio.h> 29fa225cbcSrjs#include <stdlib.h> 30fa225cbcSrjs#include <unistd.h> 31fa225cbcSrjs#include <errno.h> 32fa225cbcSrjs#include <signal.h> 33fa225cbcSrjs#include <fcntl.h> 34fa225cbcSrjs#include <dirent.h> 35fa225cbcSrjs#include <string.h> 36fa225cbcSrjs#include <assert.h> 37fa225cbcSrjs 38fa225cbcSrjs#include <sys/ioctl.h> 39fa225cbcSrjs#include <X11/Xlibint.h> 40fa225cbcSrjs#include <fourcc.h> 41fa225cbcSrjs#include <X11/extensions/Xv.h> 42fa225cbcSrjs#include <X11/extensions/Xvlib.h> 43fa225cbcSrjs#include <X11/extensions/XvMC.h> 44fa225cbcSrjs#include <X11/extensions/XvMClib.h> 45fa225cbcSrjs 46fa225cbcSrjs#include "intel_xvmc.h" 47fa225cbcSrjs#include "intel_batchbuffer.h" 48fa225cbcSrjs#include "brw_defines.h" 49fa225cbcSrjs#include "brw_structs.h" 50fa225cbcSrjs#define MI_BATCH_BUFFER_END (0xA << 23) 51fa225cbcSrjs#define BATCH_SIZE 8*1024 /* one bo is allocated each time, so the size can be small */ 52fa225cbcSrjsstatic int intelEmitIrqLocked(void) 53fa225cbcSrjs{ 54fa225cbcSrjs drmI830IrqEmit ie; 55fa225cbcSrjs int ret, seq; 56fa225cbcSrjs 57fa225cbcSrjs ie.irq_seq = &seq; 58fa225cbcSrjs ret = drmCommandWriteRead(xvmc_driver->fd, DRM_I830_IRQ_EMIT, 59fa225cbcSrjs &ie, sizeof(ie)); 60fa225cbcSrjs 61fa225cbcSrjs if ( ret ) { 62fa225cbcSrjs fprintf(stderr, "%s: drmI830IrqEmit: %d\n", __FUNCTION__, ret); 63fa225cbcSrjs exit(1); 64fa225cbcSrjs } 65fa225cbcSrjs 66fa225cbcSrjs return seq; 67fa225cbcSrjs} 68fa225cbcSrjs 69fa225cbcSrjsstatic void intelWaitIrq(int seq) 70fa225cbcSrjs{ 71fa225cbcSrjs int ret; 72fa225cbcSrjs drmI830IrqWait iw; 73fa225cbcSrjs 74fa225cbcSrjs iw.irq_seq = seq; 75fa225cbcSrjs 76fa225cbcSrjs do { 77fa225cbcSrjs ret = drmCommandWrite(xvmc_driver->fd, DRM_I830_IRQ_WAIT, &iw, sizeof(iw) ); 78fa225cbcSrjs } while (ret == -EAGAIN || ret == -EINTR); 79fa225cbcSrjs 80fa225cbcSrjs if (ret) { 81fa225cbcSrjs fprintf(stderr, "%s: drmI830IrqWait: %d\n", __FUNCTION__, ret); 82fa225cbcSrjs exit(1); 83fa225cbcSrjs } 84fa225cbcSrjs} 85fa225cbcSrjs 86fa225cbcSrjsstatic void i965_end_batch(void) 87fa225cbcSrjs{ 88fa225cbcSrjs unsigned int size = xvmc_driver->batch.ptr - 89fa225cbcSrjs xvmc_driver->batch.init_ptr; 90fa225cbcSrjs if ((size & 4) == 0) { 91fa225cbcSrjs *(unsigned int*)xvmc_driver->batch.ptr = 0; 92fa225cbcSrjs xvmc_driver->batch.ptr += 4; 93fa225cbcSrjs } 94fa225cbcSrjs *(unsigned int*)xvmc_driver->batch.ptr = MI_BATCH_BUFFER_END; 95fa225cbcSrjs xvmc_driver->batch.ptr += 4; 96fa225cbcSrjs} 97fa225cbcSrjs 98fa225cbcSrjsBool intelInitBatchBuffer(void) 99fa225cbcSrjs{ 100fa225cbcSrjs int i; 101fa225cbcSrjs 102fa225cbcSrjs if((xvmc_driver->batch.buf = 103fa225cbcSrjs drm_intel_bo_alloc(xvmc_driver->bufmgr, 104fa225cbcSrjs "batch buffer", BATCH_SIZE, 0x1000)) == NULL) { 105fa225cbcSrjs fprintf(stderr, "unable to alloc batch buffer\n"); 106fa225cbcSrjs return False; 107fa225cbcSrjs } 108fa225cbcSrjs 109fa225cbcSrjs if (xvmc_driver->kernel_exec_fencing) 110fa225cbcSrjs drm_intel_gem_bo_map_gtt(xvmc_driver->batch.buf); 111fa225cbcSrjs else 112fa225cbcSrjs drm_intel_bo_map(xvmc_driver->batch.buf, 1); 113fa225cbcSrjs 114fa225cbcSrjs xvmc_driver->batch.init_ptr = xvmc_driver->batch.buf->virtual; 115fa225cbcSrjs xvmc_driver->batch.size = BATCH_SIZE; 116fa225cbcSrjs xvmc_driver->batch.space = BATCH_SIZE; 117fa225cbcSrjs xvmc_driver->batch.ptr = xvmc_driver->batch.init_ptr; 118fa225cbcSrjs return True; 119fa225cbcSrjs} 120fa225cbcSrjs 121fa225cbcSrjsvoid intelFiniBatchBuffer(void) 122fa225cbcSrjs{ 123fa225cbcSrjs if (xvmc_driver->kernel_exec_fencing) 124fa225cbcSrjs drm_intel_gem_bo_unmap_gtt(xvmc_driver->batch.buf); 125fa225cbcSrjs else 126fa225cbcSrjs drm_intel_bo_unmap(xvmc_driver->batch.buf); 127fa225cbcSrjs 128fa225cbcSrjs drm_intel_bo_unreference(xvmc_driver->batch.buf); 129fa225cbcSrjs} 130fa225cbcSrjs 131fa225cbcSrjs 132fa225cbcSrjsvoid intelFlushBatch(Bool refill ) 133fa225cbcSrjs{ 134fa225cbcSrjs i965_end_batch(); 135fa225cbcSrjs 136fa225cbcSrjs if (xvmc_driver->kernel_exec_fencing) 137fa225cbcSrjs drm_intel_gem_bo_unmap_gtt(xvmc_driver->batch.buf); 138fa225cbcSrjs else 139fa225cbcSrjs drm_intel_bo_unmap(xvmc_driver->batch.buf); 140fa225cbcSrjs 141fa225cbcSrjs drm_intel_bo_exec(xvmc_driver->batch.buf, 142fa225cbcSrjs xvmc_driver->batch.ptr - xvmc_driver->batch.init_ptr, 143fa225cbcSrjs 0, 0, 0); 144fa225cbcSrjs 145fa225cbcSrjs if (xvmc_driver == &i915_xvmc_mc_driver) 146fa225cbcSrjs dri_bo_wait_rendering(xvmc_driver->batch.buf); 147fa225cbcSrjs 148fa225cbcSrjs drm_intel_bo_unreference(xvmc_driver->batch.buf); 149fa225cbcSrjs if((xvmc_driver->batch.buf = 150fa225cbcSrjs drm_intel_bo_alloc(xvmc_driver->bufmgr, 151fa225cbcSrjs "batch buffer", BATCH_SIZE, 0x1000)) == NULL) { 152fa225cbcSrjs fprintf(stderr, "unable to alloc batch buffer\n"); 153fa225cbcSrjs } 154fa225cbcSrjs 155fa225cbcSrjs if (xvmc_driver->kernel_exec_fencing) 156fa225cbcSrjs drm_intel_gem_bo_map_gtt(xvmc_driver->batch.buf); 157fa225cbcSrjs else 158fa225cbcSrjs drm_intel_bo_map(xvmc_driver->batch.buf, 1); 159fa225cbcSrjs 160fa225cbcSrjs xvmc_driver->batch.init_ptr = xvmc_driver->batch.buf->virtual; 161fa225cbcSrjs xvmc_driver->batch.size = BATCH_SIZE; 162fa225cbcSrjs xvmc_driver->batch.space = BATCH_SIZE; 163fa225cbcSrjs xvmc_driver->batch.ptr = xvmc_driver->batch.init_ptr; 164fa225cbcSrjs} 165fa225cbcSrjs 166fa225cbcSrjsvoid intelBatchbufferRequireSpace(int size) 167fa225cbcSrjs{ 168fa225cbcSrjs assert(xvmc_driver->batch.ptr - xvmc_driver->batch.init_ptr + size < 169fa225cbcSrjs xvmc_driver->batch.size - 8); 170fa225cbcSrjs if (xvmc_driver->batch.ptr - xvmc_driver->batch.init_ptr + size 171fa225cbcSrjs >= xvmc_driver->batch.size - 8) 172fa225cbcSrjs intelFlushBatch(1); 173fa225cbcSrjs} 174fa225cbcSrjs 175fa225cbcSrjsvoid intelBatchbufferData(const void *data, unsigned bytes, unsigned flags) 176fa225cbcSrjs{ 177fa225cbcSrjs intelBatchbufferRequireSpace(bytes); 178fa225cbcSrjs memcpy(xvmc_driver->batch.ptr, data, bytes); 179fa225cbcSrjs xvmc_driver->batch.ptr += bytes; 180fa225cbcSrjs xvmc_driver->batch.space -= bytes; 181fa225cbcSrjs} 182fa225cbcSrjs 183fa225cbcSrjsvoid intel_batch_emit_reloc(dri_bo *bo, uint32_t read_domain, 184fa225cbcSrjs uint32_t write_domain, uint32_t delta, unsigned char *ptr) 185fa225cbcSrjs{ 186fa225cbcSrjs drm_intel_bo_emit_reloc(xvmc_driver->batch.buf, 187fa225cbcSrjs ptr - xvmc_driver->batch.init_ptr, bo, delta, 188fa225cbcSrjs read_domain, write_domain); 189fa225cbcSrjs} 190