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