1428d7b3dSmrg/**************************************************************************
2428d7b3dSmrg *
3428d7b3dSmrg * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
4428d7b3dSmrg * All Rights Reserved.
5428d7b3dSmrg *
6428d7b3dSmrg * Permission is hereby granted, free of charge, to any person obtaining a
7428d7b3dSmrg * copy of this software and associated documentation files (the
8428d7b3dSmrg * "Software"), to deal in the Software without restriction, including
9428d7b3dSmrg * without limitation the rights to use, copy, modify, merge, publish,
10428d7b3dSmrg * distribute, sub license, and/or sell copies of the Software, and to
11428d7b3dSmrg * permit persons to whom the Software is furnished to do so, subject to
12428d7b3dSmrg * the following conditions:
13428d7b3dSmrg *
14428d7b3dSmrg * The above copyright notice and this permission notice (including the
15428d7b3dSmrg * next paragraph) shall be included in all copies or substantial portions
16428d7b3dSmrg * of the Software.
17428d7b3dSmrg *
18428d7b3dSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19428d7b3dSmrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20428d7b3dSmrg * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21428d7b3dSmrg * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
22428d7b3dSmrg * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23428d7b3dSmrg * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24428d7b3dSmrg * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25428d7b3dSmrg *
26428d7b3dSmrg **************************************************************************/
27428d7b3dSmrg
28428d7b3dSmrg#include <stdio.h>
29428d7b3dSmrg#include <stdlib.h>
30428d7b3dSmrg#include <unistd.h>
31428d7b3dSmrg#include <errno.h>
32428d7b3dSmrg#include <signal.h>
33428d7b3dSmrg#include <fcntl.h>
34428d7b3dSmrg#include <dirent.h>
35428d7b3dSmrg#include <string.h>
36428d7b3dSmrg#include <assert.h>
37428d7b3dSmrg
38428d7b3dSmrg#include <sys/ioctl.h>
39428d7b3dSmrg#include <X11/Xlibint.h>
40428d7b3dSmrg#include <fourcc.h>
41428d7b3dSmrg#include <X11/extensions/Xv.h>
42428d7b3dSmrg#include <X11/extensions/Xvlib.h>
43428d7b3dSmrg#include <X11/extensions/XvMC.h>
44428d7b3dSmrg#include <X11/extensions/XvMClib.h>
45428d7b3dSmrg
46428d7b3dSmrg#include "intel_xvmc_private.h"
47428d7b3dSmrg#include "intel_batchbuffer.h"
48428d7b3dSmrg#include "brw_defines.h"
49428d7b3dSmrg#include "brw_structs.h"
50428d7b3dSmrg#define MI_BATCH_BUFFER_END     (0xA << 23)
51428d7b3dSmrg#define BATCH_SIZE 8*1024	/* one bo is allocated each time, so the size can be small */
52428d7b3dSmrg
53428d7b3dSmrgstatic void i965_end_batch(void)
54428d7b3dSmrg{
55428d7b3dSmrg	unsigned int size = xvmc_driver->batch.ptr -
56428d7b3dSmrg	    xvmc_driver->batch.init_ptr;
57428d7b3dSmrg	if ((size & 4) == 0) {
58428d7b3dSmrg		*(unsigned int *)xvmc_driver->batch.ptr = 0;
59428d7b3dSmrg		xvmc_driver->batch.ptr += 4;
60428d7b3dSmrg	}
61428d7b3dSmrg	*(unsigned int *)xvmc_driver->batch.ptr = MI_BATCH_BUFFER_END;
62428d7b3dSmrg	xvmc_driver->batch.ptr += 4;
63428d7b3dSmrg}
64428d7b3dSmrg
65428d7b3dSmrgstatic void reset_batch(void)
66428d7b3dSmrg{
67428d7b3dSmrg	dri_bo *bo = xvmc_driver->batch.buf;
68428d7b3dSmrg
69428d7b3dSmrg	xvmc_driver->batch.ptr = xvmc_driver->batch.init_ptr = bo->virtual;
70428d7b3dSmrg	xvmc_driver->batch.size = bo->size;
71428d7b3dSmrg	xvmc_driver->batch.space = bo->size - 8;
72428d7b3dSmrg}
73428d7b3dSmrg
74428d7b3dSmrgBool intelInitBatchBuffer(void)
75428d7b3dSmrg{
76428d7b3dSmrg	if ((xvmc_driver->batch.buf =
77428d7b3dSmrg	     drm_intel_bo_alloc(xvmc_driver->bufmgr,
78428d7b3dSmrg				"batch buffer", BATCH_SIZE, 0x1000)) == NULL) {
79428d7b3dSmrg		fprintf(stderr, "unable to alloc batch buffer\n");
80428d7b3dSmrg		return False;
81428d7b3dSmrg	}
82428d7b3dSmrg
83428d7b3dSmrg	if (drm_intel_gem_bo_map_gtt(xvmc_driver->batch.buf)) {
84428d7b3dSmrg		drm_intel_bo_unreference(xvmc_driver->batch.buf);
85428d7b3dSmrg		return False;
86428d7b3dSmrg	}
87428d7b3dSmrg
88428d7b3dSmrg	reset_batch();
89428d7b3dSmrg	return True;
90428d7b3dSmrg}
91428d7b3dSmrg
92428d7b3dSmrgvoid intelFiniBatchBuffer(void)
93428d7b3dSmrg{
94428d7b3dSmrg	if (xvmc_driver->batch.buf == NULL)
95428d7b3dSmrg		return;
96428d7b3dSmrg
97428d7b3dSmrg	drm_intel_bo_unreference(xvmc_driver->batch.buf);
98428d7b3dSmrg}
99428d7b3dSmrg
100428d7b3dSmrgvoid intelFlushBatch(void)
101428d7b3dSmrg{
102428d7b3dSmrg	dri_bo *bo;
103428d7b3dSmrg
104428d7b3dSmrg	i965_end_batch();
105428d7b3dSmrg
106428d7b3dSmrg	drm_intel_bo_exec(xvmc_driver->batch.buf,
107428d7b3dSmrg			  xvmc_driver->batch.ptr - xvmc_driver->batch.init_ptr,
108428d7b3dSmrg			  0, 0, 0);
109428d7b3dSmrg
110428d7b3dSmrg	bo = drm_intel_bo_alloc(xvmc_driver->bufmgr,
111428d7b3dSmrg				"batch buffer", BATCH_SIZE, 0x1000);
112428d7b3dSmrg	if (bo != NULL && drm_intel_gem_bo_map_gtt(bo) == 0) {
113428d7b3dSmrg		drm_intel_bo_unreference(xvmc_driver->batch.buf);
114428d7b3dSmrg		xvmc_driver->batch.buf = bo;
115428d7b3dSmrg	} else {
116428d7b3dSmrg		if (bo != NULL)
117428d7b3dSmrg			drm_intel_bo_unreference(bo);
118428d7b3dSmrg		drm_intel_gem_bo_map_gtt(xvmc_driver->batch.buf);
119428d7b3dSmrg	}
120428d7b3dSmrg
121428d7b3dSmrg	reset_batch();
122428d7b3dSmrg}
123428d7b3dSmrg
124428d7b3dSmrgvoid intelBatchbufferData(const void *data, unsigned bytes, unsigned flags)
125428d7b3dSmrg{
126428d7b3dSmrg	assert(bytes <= xvmc_driver->batch.space);
127428d7b3dSmrg	memcpy(xvmc_driver->batch.ptr, data, bytes);
128428d7b3dSmrg	xvmc_driver->batch.ptr += bytes;
129428d7b3dSmrg	xvmc_driver->batch.space -= bytes;
130428d7b3dSmrg}
131428d7b3dSmrg
132428d7b3dSmrgvoid intel_batch_emit_reloc(dri_bo * bo, uint32_t read_domain,
133428d7b3dSmrg			    uint32_t write_domain, uint32_t delta,
134428d7b3dSmrg			    unsigned char *ptr)
135428d7b3dSmrg{
136428d7b3dSmrg	drm_intel_bo_emit_reloc(xvmc_driver->batch.buf,
137428d7b3dSmrg				ptr - xvmc_driver->batch.init_ptr, bo, delta,
138428d7b3dSmrg				read_domain, write_domain);
139428d7b3dSmrg}
140