radeon_exa_shared.c revision 0974d292
1/*
2 * Copyright 2005 Eric Anholt
3 * Copyright 2005 Benjamin Herrenschmidt
4 * Copyright 2008 Advanced Micro Devices, Inc.
5 * All Rights Reserved.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice (including the next
15 * paragraph) shall be included in all copies or substantial portions of the
16 * Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
21 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24 * SOFTWARE.
25 *
26 * Authors:
27 *    Eric Anholt <anholt@FreeBSD.org>
28 *    Zack Rusin <zrusin@trolltech.com>
29 *    Benjamin Herrenschmidt <benh@kernel.crashing.org>
30 *    Alex Deucher <alexander.deucher@amd.com>
31 *    Matthias Hopf <mhopf@suse.de>
32 */
33#ifdef HAVE_CONFIG_H
34#include "config.h"
35#endif
36
37#include "radeon.h"
38#ifdef XF86DRI
39#include "radeon_drm.h"
40#endif
41#include "radeon_macros.h"
42#include "radeon_probe.h"
43#include "radeon_version.h"
44#include "radeon_vbo.h"
45
46PixmapPtr
47RADEONGetDrawablePixmap(DrawablePtr pDrawable)
48{
49    if (pDrawable->type == DRAWABLE_WINDOW)
50	return pDrawable->pScreen->GetWindowPixmap((WindowPtr)pDrawable);
51    else
52	return (PixmapPtr)pDrawable;
53}
54
55void RADEONVlineHelperClear(ScrnInfoPtr pScrn)
56{
57    RADEONInfoPtr info = RADEONPTR(pScrn);
58    struct radeon_accel_state *accel_state = info->accel_state;
59
60    accel_state->vline_crtc = NULL;
61    accel_state->vline_y1 = -1;
62    accel_state->vline_y2 = 0;
63}
64
65void RADEONVlineHelperSet(ScrnInfoPtr pScrn, int x1, int y1, int x2, int y2)
66{
67    RADEONInfoPtr info = RADEONPTR(pScrn);
68    struct radeon_accel_state *accel_state = info->accel_state;
69
70    accel_state->vline_crtc = radeon_pick_best_crtc(pScrn, x1, x2, y1, y2);
71    if (accel_state->vline_y1 == -1)
72	accel_state->vline_y1 = y1;
73    if (y1 < accel_state->vline_y1)
74	accel_state->vline_y1 = y1;
75    if (y2 > accel_state->vline_y2)
76	accel_state->vline_y2 = y2;
77}
78
79Bool RADEONValidPM(uint32_t pm, int bpp)
80{
81    uint8_t r, g, b, a;
82    Bool ret = FALSE;
83
84    switch (bpp) {
85    case 8:
86	a = pm & 0xff;
87	if ((a == 0) || (a == 0xff))
88	    ret = TRUE;
89	break;
90    case 16:
91	r = (pm >> 11) & 0x1f;
92	g = (pm >> 5) & 0x3f;
93	b = (pm >> 0) & 0x1f;
94	if (((r == 0) || (r == 0x1f)) &&
95	    ((g == 0) || (g == 0x3f)) &&
96	    ((b == 0) || (b == 0x1f)))
97	    ret = TRUE;
98	break;
99    case 32:
100	a = (pm >> 24) & 0xff;
101	r = (pm >> 16) & 0xff;
102	g = (pm >> 8) & 0xff;
103	b = (pm >> 0) & 0xff;
104	if (((a == 0) || (a == 0xff)) &&
105	    ((r == 0) || (r == 0xff)) &&
106	    ((g == 0) || (g == 0xff)) &&
107	    ((b == 0) || (b == 0xff)))
108	    ret = TRUE;
109	break;
110    default:
111	break;
112    }
113    return ret;
114}
115
116Bool RADEONCheckBPP(int bpp)
117{
118	switch (bpp) {
119	case 8:
120	case 16:
121	case 32:
122		return TRUE;
123	default:
124		break;
125	}
126	return FALSE;
127}
128
129static Bool radeon_vb_get(ScrnInfoPtr pScrn)
130{
131    RADEONInfoPtr info = RADEONPTR(pScrn);
132    struct radeon_accel_state *accel_state = info->accel_state;
133
134    accel_state->vb_mc_addr = info->gartLocation + info->dri->bufStart +
135	(accel_state->ib->idx*accel_state->ib->total)+
136	(accel_state->ib->total / 2);
137    accel_state->vb_total = (accel_state->ib->total / 2);
138    accel_state->vb_ptr = (pointer)((char*)accel_state->ib->address +
139				    (accel_state->ib->total / 2));
140    accel_state->vb_offset = 0;
141    return TRUE;
142}
143
144void radeon_vb_discard(ScrnInfoPtr pScrn)
145{
146    RADEONInfoPtr info = RADEONPTR(pScrn);
147
148    info->accel_state->vb_start_op = -1;
149}
150
151int radeon_cp_start(ScrnInfoPtr pScrn)
152{
153    RADEONInfoPtr info = RADEONPTR(pScrn);
154    struct radeon_accel_state *accel_state = info->accel_state;
155
156#if defined(XF86DRM_MODE)
157    if (info->cs) {
158	if (CS_FULL(info->cs)) {
159	    radeon_cs_flush_indirect(pScrn);
160	}
161	accel_state->ib_reset_op = info->cs->cdw;
162	accel_state->vb_start_op = accel_state->vb_offset;
163    } else
164#endif
165    {
166	accel_state->ib = RADEONCPGetBuffer(pScrn);
167	if (!radeon_vb_get(pScrn)) {
168	    return -1;
169	}
170	accel_state->vb_start_op = accel_state->vb_offset;
171    }
172    return 0;
173}
174
175void radeon_vb_no_space(ScrnInfoPtr pScrn, int vert_size)
176{
177    RADEONInfoPtr info = RADEONPTR(pScrn);
178    struct radeon_accel_state *accel_state = info->accel_state;
179
180#if defined(XF86DRM_MODE)
181    if (info->cs) {
182	if (accel_state->vb_bo) {
183	    if (accel_state->vb_start_op != accel_state->vb_offset) {
184		accel_state->finish_op(pScrn, vert_size);
185		accel_state->ib_reset_op = info->cs->cdw;
186	    }
187
188	    /* release the current VBO */
189	    radeon_vbo_put(pScrn);
190	}
191	/* get a new one */
192	radeon_vbo_get(pScrn);
193	return;
194    }
195#endif
196    if (accel_state->vb_start_op != -1) {
197        accel_state->finish_op(pScrn, vert_size);
198        radeon_cp_start(pScrn);
199    }
200    return;
201}
202
203#if defined(XF86DRM_MODE)
204void radeon_ib_discard(ScrnInfoPtr pScrn)
205{
206    RADEONInfoPtr info = RADEONPTR(pScrn);
207    int ret;
208
209    if (info->accel_state->ib_reset_op) {
210        /* if we have data just reset the CS and ignore the operation */
211	info->cs->cdw = info->accel_state->ib_reset_op;
212	info->accel_state->ib_reset_op = 0;
213	goto out;
214    }
215
216    info->accel_state->vb_offset = 0;
217    info->accel_state->vb_start_op = -1;
218
219    if (CS_FULL(info->cs)) {
220	radeon_cs_flush_indirect(pScrn);
221	return;
222    }
223    radeon_cs_erase(info->cs);
224    ret = radeon_cs_space_check_with_bo(info->cs,
225					info->accel_state->vb_bo,
226					RADEON_GEM_DOMAIN_GTT, 0);
227    if (ret)
228	ErrorF("space check failed in flush\n");
229
230 out:
231    if (info->dri2.enabled) {
232	info->accel_state->XInited3D = FALSE;
233	info->accel_state->engineMode = EXA_ENGINEMODE_UNKNOWN;
234    }
235
236}
237#endif
238