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