radeon.h revision 8bf5c682
1de2362d3Smrg/*
2de2362d3Smrg * Copyright 2000 ATI Technologies Inc., Markham, Ontario, and
3de2362d3Smrg *                VA Linux Systems Inc., Fremont, California.
4de2362d3Smrg *
5de2362d3Smrg * All Rights Reserved.
6de2362d3Smrg *
7de2362d3Smrg * Permission is hereby granted, free of charge, to any person obtaining
8de2362d3Smrg * a copy of this software and associated documentation files (the
9de2362d3Smrg * "Software"), to deal in the Software without restriction, including
10de2362d3Smrg * without limitation on the rights to use, copy, modify, merge,
11de2362d3Smrg * publish, distribute, sublicense, and/or sell copies of the Software,
12de2362d3Smrg * and to permit persons to whom the Software is furnished to do so,
13de2362d3Smrg * subject to the following conditions:
14de2362d3Smrg *
15de2362d3Smrg * The above copyright notice and this permission notice (including the
16de2362d3Smrg * next paragraph) shall be included in all copies or substantial
17de2362d3Smrg * portions of the Software.
18de2362d3Smrg *
19de2362d3Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20de2362d3Smrg * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21de2362d3Smrg * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
22de2362d3Smrg * NON-INFRINGEMENT.  IN NO EVENT SHALL ATI, VA LINUX SYSTEMS AND/OR
23de2362d3Smrg * THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
24de2362d3Smrg * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25de2362d3Smrg * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
26de2362d3Smrg * DEALINGS IN THE SOFTWARE.
27de2362d3Smrg */
28de2362d3Smrg
29de2362d3Smrg/*
30de2362d3Smrg * Authors:
31de2362d3Smrg *   Kevin E. Martin <martin@xfree86.org>
32de2362d3Smrg *   Rickard E. Faith <faith@valinux.com>
33de2362d3Smrg *   Alan Hourihane <alanh@fairlite.demon.co.uk>
34de2362d3Smrg *
35de2362d3Smrg */
36de2362d3Smrg
37de2362d3Smrg#ifndef _RADEON_H_
38de2362d3Smrg#define _RADEON_H_
39de2362d3Smrg
40de2362d3Smrg#include <stdlib.h>		/* For abs() */
41de2362d3Smrg#include <unistd.h>		/* For usleep() */
42de2362d3Smrg#include <sys/time.h>		/* For gettimeofday() */
43de2362d3Smrg
44de2362d3Smrg#include "config.h"
45de2362d3Smrg
46de2362d3Smrg#include "xf86str.h"
47de2362d3Smrg#include "compiler.h"
48de2362d3Smrg
49de2362d3Smrg				/* PCI support */
50de2362d3Smrg#include "xf86Pci.h"
51de2362d3Smrg
52de2362d3Smrg#include "exa.h"
53de2362d3Smrg
54de2362d3Smrg				/* Exa and Cursor Support */
55de2362d3Smrg#include "xf86Cursor.h"
56de2362d3Smrg
57de2362d3Smrg				/* DDC support */
58de2362d3Smrg#include "xf86DDC.h"
59de2362d3Smrg
60de2362d3Smrg				/* Xv support */
61de2362d3Smrg#include "xf86xv.h"
62de2362d3Smrg
63de2362d3Smrg#include "radeon_probe.h"
64de2362d3Smrg
65de2362d3Smrg				/* DRI support */
66de2362d3Smrg#include "xf86drm.h"
67de2362d3Smrg#include "radeon_drm.h"
68de2362d3Smrg
6918781e08Smrg#ifndef RADEON_GEM_NO_CPU_ACCESS
7018781e08Smrg#define RADEON_GEM_NO_CPU_ACCESS	(1 << 4)
7118781e08Smrg#endif
7218781e08Smrg
73de2362d3Smrg#ifdef DAMAGE
74de2362d3Smrg#include "damage.h"
75de2362d3Smrg#include "globals.h"
76de2362d3Smrg#endif
77de2362d3Smrg
78de2362d3Smrg#include "xf86Crtc.h"
79de2362d3Smrg#include "X11/Xatom.h"
80de2362d3Smrg
81de2362d3Smrg#include "radeon_bo.h"
82de2362d3Smrg#include "radeon_cs.h"
83de2362d3Smrg#include "radeon_dri2.h"
84de2362d3Smrg#include "drmmode_display.h"
85de2362d3Smrg#include "radeon_surface.h"
86de2362d3Smrg
87de2362d3Smrg				/* Render support */
88de2362d3Smrg#ifdef RENDER
89de2362d3Smrg#include "picturestr.h"
90de2362d3Smrg#endif
91de2362d3Smrg
92de2362d3Smrg#include "compat-api.h"
93de2362d3Smrg
94de2362d3Smrg#include "simple_list.h"
95de2362d3Smrg#include "atipcirename.h"
96de2362d3Smrg
9718781e08Smrgstruct _SyncFence;
9818781e08Smrg
9918781e08Smrg#ifndef HAVE_REGIONDUPLICATE
10018781e08Smrg
10118781e08Smrgstatic inline RegionPtr
10218781e08SmrgRegionDuplicate(RegionPtr pOld)
10318781e08Smrg{
10418781e08Smrg    RegionPtr pNew;
10518781e08Smrg
10618781e08Smrg    pNew = RegionCreate(&pOld->extents, 0);
10718781e08Smrg    if (!pNew)
10818781e08Smrg	return NULL;
10918781e08Smrg    if (!RegionCopy(pNew, pOld)) {
11018781e08Smrg	RegionDestroy(pNew);
11118781e08Smrg	return NULL;
11218781e08Smrg    }
11318781e08Smrg    return pNew;
11418781e08Smrg}
11518781e08Smrg
11618781e08Smrg#endif
11718781e08Smrg
118de2362d3Smrg#ifndef MAX
119de2362d3Smrg#define MAX(a,b) ((a)>(b)?(a):(b))
120de2362d3Smrg#endif
121de2362d3Smrg#ifndef MIN
122de2362d3Smrg#define MIN(a,b) ((a)>(b)?(b):(a))
123de2362d3Smrg#endif
124de2362d3Smrg
125de2362d3Smrg#if HAVE_BYTESWAP_H
126de2362d3Smrg#include <byteswap.h>
127de2362d3Smrg#elif defined(USE_SYS_ENDIAN_H)
128de2362d3Smrg#include <sys/endian.h>
129de2362d3Smrg#else
130de2362d3Smrg#define bswap_16(value)  \
131de2362d3Smrg        ((((value) & 0xff) << 8) | ((value) >> 8))
132de2362d3Smrg
133de2362d3Smrg#define bswap_32(value) \
134de2362d3Smrg        (((uint32_t)bswap_16((uint16_t)((value) & 0xffff)) << 16) | \
135de2362d3Smrg        (uint32_t)bswap_16((uint16_t)((value) >> 16)))
136de2362d3Smrg
137de2362d3Smrg#define bswap_64(value) \
138de2362d3Smrg        (((uint64_t)bswap_32((uint32_t)((value) & 0xffffffff)) \
139de2362d3Smrg            << 32) | \
140de2362d3Smrg        (uint64_t)bswap_32((uint32_t)((value) >> 32)))
141de2362d3Smrg#endif
142de2362d3Smrg
143de2362d3Smrg#if X_BYTE_ORDER == X_BIG_ENDIAN
144de2362d3Smrg#define le32_to_cpu(x) bswap_32(x)
145de2362d3Smrg#define le16_to_cpu(x) bswap_16(x)
146de2362d3Smrg#define cpu_to_le32(x) bswap_32(x)
147de2362d3Smrg#define cpu_to_le16(x) bswap_16(x)
148de2362d3Smrg#else
149de2362d3Smrg#define le32_to_cpu(x) (x)
150de2362d3Smrg#define le16_to_cpu(x) (x)
151de2362d3Smrg#define cpu_to_le32(x) (x)
152de2362d3Smrg#define cpu_to_le16(x) (x)
153de2362d3Smrg#endif
154de2362d3Smrg
155de2362d3Smrg/* Provide substitutes for gcc's __FUNCTION__ on other compilers */
156de2362d3Smrg#if !defined(__GNUC__) && !defined(__FUNCTION__)
157de2362d3Smrg# define __FUNCTION__ __func__		/* C99 */
158de2362d3Smrg#endif
159de2362d3Smrg
160de2362d3Smrgtypedef enum {
16118781e08Smrg    OPTION_ACCEL,
162de2362d3Smrg    OPTION_SW_CURSOR,
163de2362d3Smrg    OPTION_PAGE_FLIP,
164de2362d3Smrg    OPTION_EXA_PIXMAPS,
165de2362d3Smrg    OPTION_COLOR_TILING,
166de2362d3Smrg    OPTION_COLOR_TILING_2D,
167de2362d3Smrg#ifdef RENDER
168de2362d3Smrg    OPTION_RENDER_ACCEL,
169de2362d3Smrg    OPTION_SUBPIXEL_ORDER,
170de2362d3Smrg#endif
171de2362d3Smrg    OPTION_ACCELMETHOD,
172de2362d3Smrg    OPTION_EXA_VSYNC,
173de2362d3Smrg    OPTION_ZAPHOD_HEADS,
17418781e08Smrg    OPTION_SWAPBUFFERS_WAIT,
17518781e08Smrg    OPTION_DELETE_DP12,
17618781e08Smrg    OPTION_DRI3,
17718781e08Smrg    OPTION_DRI,
17818781e08Smrg    OPTION_SHADOW_PRIMARY,
17918781e08Smrg    OPTION_TEAR_FREE,
180de2362d3Smrg} RADEONOpts;
181de2362d3Smrg
182de2362d3Smrg
1838bf5c682Smrgstatic inline ScreenPtr
1848bf5c682Smrgradeon_master_screen(ScreenPtr screen)
1858bf5c682Smrg{
1868bf5c682Smrg    if (screen->current_master)
1878bf5c682Smrg	return screen->current_master;
1888bf5c682Smrg
1898bf5c682Smrg    return screen;
1908bf5c682Smrg}
1918bf5c682Smrg
1928bf5c682Smrgstatic inline ScreenPtr
1938bf5c682Smrgradeon_dirty_master(PixmapDirtyUpdatePtr dirty)
1948bf5c682Smrg{
1958bf5c682Smrg    return radeon_master_screen(dirty->slave_dst->drawable.pScreen);
1968bf5c682Smrg}
1978bf5c682Smrg
1988bf5c682Smrgstatic inline DrawablePtr
1998bf5c682Smrgradeon_dirty_src_drawable(PixmapDirtyUpdatePtr dirty)
2008bf5c682Smrg{
2018bf5c682Smrg#ifdef HAS_DIRTYTRACKING_DRAWABLE_SRC
2028bf5c682Smrg    return dirty->src;
2033ed65abbSmrg#else
2048bf5c682Smrg    return &dirty->src->drawable;
20518781e08Smrg#endif
2068bf5c682Smrg}
2078bf5c682Smrg
2088bf5c682Smrgstatic inline Bool
2098bf5c682Smrgradeon_dirty_src_equals(PixmapDirtyUpdatePtr dirty, PixmapPtr pixmap)
2108bf5c682Smrg{
2118bf5c682Smrg    return radeon_dirty_src_drawable(dirty) == &pixmap->drawable;
2128bf5c682Smrg}
2138bf5c682Smrg
2140d16fef4Smrg
215de2362d3Smrg#define RADEON_VSYNC_TIMEOUT	20000 /* Maximum wait for VSYNC (in usecs) */
216de2362d3Smrg
217de2362d3Smrg/* Buffer are aligned on 4096 byte boundaries */
218de2362d3Smrg#define RADEON_GPU_PAGE_SIZE 4096
219de2362d3Smrg#define RADEON_BUFFER_ALIGN (RADEON_GPU_PAGE_SIZE - 1)
22018781e08Smrg
221de2362d3Smrg
222de2362d3Smrg#define xFixedToFloat(f) (((float) (f)) / 65536)
223de2362d3Smrg
224de2362d3Smrg#define RADEON_LOGLEVEL_DEBUG 4
225de2362d3Smrg
226de2362d3Smrg/* for Xv, outputs */
227de2362d3Smrg#define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE)
228de2362d3Smrg
229de2362d3Smrg/* Other macros */
230de2362d3Smrg#define RADEON_ALIGN(x,bytes) (((x) + ((bytes) - 1)) & ~((bytes) - 1))
231de2362d3Smrg#define RADEONPTR(pScrn)      ((RADEONInfoPtr)(pScrn)->driverPrivate)
232de2362d3Smrg
233de2362d3Smrg#define IS_RV100_VARIANT ((info->ChipFamily == CHIP_FAMILY_RV100)  ||  \
234de2362d3Smrg        (info->ChipFamily == CHIP_FAMILY_RV200)  ||  \
235de2362d3Smrg        (info->ChipFamily == CHIP_FAMILY_RS100)  ||  \
236de2362d3Smrg        (info->ChipFamily == CHIP_FAMILY_RS200)  ||  \
237de2362d3Smrg        (info->ChipFamily == CHIP_FAMILY_RV250)  ||  \
238de2362d3Smrg        (info->ChipFamily == CHIP_FAMILY_RV280)  ||  \
239de2362d3Smrg        (info->ChipFamily == CHIP_FAMILY_RS300))
240de2362d3Smrg
241de2362d3Smrg
242de2362d3Smrg#define IS_R300_VARIANT ((info->ChipFamily == CHIP_FAMILY_R300)  ||  \
243de2362d3Smrg        (info->ChipFamily == CHIP_FAMILY_RV350) ||  \
244de2362d3Smrg        (info->ChipFamily == CHIP_FAMILY_R350)  ||  \
245de2362d3Smrg        (info->ChipFamily == CHIP_FAMILY_RV380) ||  \
246de2362d3Smrg        (info->ChipFamily == CHIP_FAMILY_R420)  ||  \
247de2362d3Smrg        (info->ChipFamily == CHIP_FAMILY_RV410) ||  \
248de2362d3Smrg        (info->ChipFamily == CHIP_FAMILY_RS400) ||  \
249de2362d3Smrg        (info->ChipFamily == CHIP_FAMILY_RS480))
250de2362d3Smrg
251de2362d3Smrg#define IS_AVIVO_VARIANT ((info->ChipFamily >= CHIP_FAMILY_RV515))
252de2362d3Smrg
253de2362d3Smrg#define IS_DCE3_VARIANT ((info->ChipFamily >= CHIP_FAMILY_RV620))
254de2362d3Smrg
255de2362d3Smrg#define IS_DCE32_VARIANT ((info->ChipFamily >= CHIP_FAMILY_RV730))
256de2362d3Smrg
257de2362d3Smrg#define IS_DCE4_VARIANT ((info->ChipFamily >= CHIP_FAMILY_CEDAR))
258de2362d3Smrg
259de2362d3Smrg#define IS_DCE41_VARIANT ((info->ChipFamily >= CHIP_FAMILY_PALM))
260de2362d3Smrg
261de2362d3Smrg#define IS_DCE5_VARIANT ((info->ChipFamily >= CHIP_FAMILY_BARTS))
262de2362d3Smrg
263de2362d3Smrg#define IS_EVERGREEN_3D (info->ChipFamily >= CHIP_FAMILY_CEDAR)
264de2362d3Smrg
265de2362d3Smrg#define IS_R600_3D (info->ChipFamily >= CHIP_FAMILY_R600)
266de2362d3Smrg
267de2362d3Smrg#define IS_R500_3D ((info->ChipFamily == CHIP_FAMILY_RV515)  ||  \
268de2362d3Smrg	(info->ChipFamily == CHIP_FAMILY_R520)   ||  \
269de2362d3Smrg	(info->ChipFamily == CHIP_FAMILY_RV530)  ||  \
270de2362d3Smrg	(info->ChipFamily == CHIP_FAMILY_R580)   ||  \
271de2362d3Smrg	(info->ChipFamily == CHIP_FAMILY_RV560)  ||  \
272de2362d3Smrg	(info->ChipFamily == CHIP_FAMILY_RV570))
273de2362d3Smrg
27418781e08Smrg/* RS6xx, RS740 are technically R4xx as well, but the
27518781e08Smrg * clipping hardware seems to follow the r3xx restrictions
27618781e08Smrg */
277de2362d3Smrg#define IS_R400_3D ((info->ChipFamily == CHIP_FAMILY_R420)  ||  \
27818781e08Smrg	(info->ChipFamily == CHIP_FAMILY_RV410))
279de2362d3Smrg
280de2362d3Smrg#define IS_R300_3D ((info->ChipFamily == CHIP_FAMILY_R300)  ||  \
281de2362d3Smrg	(info->ChipFamily == CHIP_FAMILY_RV350) ||  \
282de2362d3Smrg	(info->ChipFamily == CHIP_FAMILY_R350)  ||  \
283de2362d3Smrg	(info->ChipFamily == CHIP_FAMILY_RV380) ||  \
284de2362d3Smrg	(info->ChipFamily == CHIP_FAMILY_R420)  ||  \
285de2362d3Smrg	(info->ChipFamily == CHIP_FAMILY_RV410) ||  \
286de2362d3Smrg	(info->ChipFamily == CHIP_FAMILY_RS690) ||  \
287de2362d3Smrg	(info->ChipFamily == CHIP_FAMILY_RS600) ||  \
288de2362d3Smrg	(info->ChipFamily == CHIP_FAMILY_RS740) ||  \
289de2362d3Smrg	(info->ChipFamily == CHIP_FAMILY_RS400) ||  \
290de2362d3Smrg	(info->ChipFamily == CHIP_FAMILY_RS480))
291de2362d3Smrg
292de2362d3Smrg#define IS_R200_3D ((info->ChipFamily == CHIP_FAMILY_RV250) || \
293de2362d3Smrg	(info->ChipFamily == CHIP_FAMILY_RV280) || \
294de2362d3Smrg	(info->ChipFamily == CHIP_FAMILY_RS300) || \
295de2362d3Smrg	(info->ChipFamily == CHIP_FAMILY_R200))
296de2362d3Smrg
29718781e08Smrg#define CURSOR_WIDTH	64
29818781e08Smrg#define CURSOR_HEIGHT	64
2990d16fef4Smrg
30018781e08Smrg#define CURSOR_WIDTH_CIK	128
30118781e08Smrg#define CURSOR_HEIGHT_CIK	128
3020d16fef4Smrg
3030d16fef4Smrg
30418781e08Smrg#ifdef USE_GLAMOR
3050d16fef4Smrg
30618781e08Smrgstruct radeon_pixmap {
30718781e08Smrg	struct radeon_surface surface;
3080d16fef4Smrg
30918781e08Smrg	uint_fast32_t gpu_read;
31018781e08Smrg	uint_fast32_t gpu_write;
3110d16fef4Smrg
31218781e08Smrg	struct radeon_bo *bo;
3138bf5c682Smrg	struct drmmode_fb *fb;
31418781e08Smrg
31518781e08Smrg	uint32_t tiling_flags;
31618781e08Smrg
31718781e08Smrg	/* GEM handle for glamor-only pixmaps shared via DRI3 */
31818781e08Smrg	Bool handle_valid;
31918781e08Smrg	uint32_t handle;
32018781e08Smrg};
32118781e08Smrg
32218781e08Smrgextern DevPrivateKeyRec glamor_pixmap_index;
32318781e08Smrg
32418781e08Smrgstatic inline struct radeon_pixmap *radeon_get_pixmap_private(PixmapPtr pixmap)
32518781e08Smrg{
32618781e08Smrg	return dixGetPrivate(&pixmap->devPrivates, &glamor_pixmap_index);
32718781e08Smrg}
32818781e08Smrg
32918781e08Smrgstatic inline void radeon_set_pixmap_private(PixmapPtr pixmap, struct radeon_pixmap *priv)
33018781e08Smrg{
33118781e08Smrg	dixSetPrivate(&pixmap->devPrivates, &glamor_pixmap_index, priv);
33218781e08Smrg}
3330d16fef4Smrg
33418781e08Smrg#endif /* USE_GLAMOR */
3350d16fef4Smrg
3360d16fef4Smrg
337de2362d3Smrgstruct radeon_exa_pixmap_priv {
338de2362d3Smrg    struct radeon_bo *bo;
3398bf5c682Smrg    struct drmmode_fb *fb;
340de2362d3Smrg    uint32_t tiling_flags;
341de2362d3Smrg    struct radeon_surface surface;
342de2362d3Smrg    Bool bo_mapped;
34318781e08Smrg    Bool shared;
344de2362d3Smrg};
345de2362d3Smrg
346de2362d3Smrg#define RADEON_2D_EXA_COPY 1
347de2362d3Smrg#define RADEON_2D_EXA_SOLID 2
348de2362d3Smrg
349de2362d3Smrgstruct radeon_2d_state {
350de2362d3Smrg    int op; //
351de2362d3Smrg    uint32_t dst_pitch_offset;
352de2362d3Smrg    uint32_t src_pitch_offset;
353de2362d3Smrg    uint32_t dp_gui_master_cntl;
354de2362d3Smrg    uint32_t dp_cntl;
355de2362d3Smrg    uint32_t dp_write_mask;
356de2362d3Smrg    uint32_t dp_brush_frgd_clr;
357de2362d3Smrg    uint32_t dp_brush_bkgd_clr;
358de2362d3Smrg    uint32_t dp_src_frgd_clr;
359de2362d3Smrg    uint32_t dp_src_bkgd_clr;
360de2362d3Smrg    uint32_t default_sc_bottom_right;
36118781e08Smrg    uint32_t dst_domain;
362de2362d3Smrg    struct radeon_bo *dst_bo;
363de2362d3Smrg    struct radeon_bo *src_bo;
364de2362d3Smrg};
365de2362d3Smrg
366de2362d3Smrg#define DMA_BO_FREE_TIME 1000
367de2362d3Smrg
368de2362d3Smrgstruct radeon_dma_bo {
369de2362d3Smrg    struct radeon_dma_bo *next, *prev;
370de2362d3Smrg    struct radeon_bo  *bo;
371de2362d3Smrg    int expire_counter;
372de2362d3Smrg};
373de2362d3Smrg
374de2362d3Smrgstruct r600_accel_object {
375de2362d3Smrg    uint32_t pitch;
376de2362d3Smrg    uint32_t width;
377de2362d3Smrg    uint32_t height;
378de2362d3Smrg    int bpp;
379de2362d3Smrg    uint32_t domain;
380de2362d3Smrg    struct radeon_bo *bo;
381de2362d3Smrg    uint32_t tiling_flags;
382de2362d3Smrg    struct radeon_surface *surface;
383de2362d3Smrg};
384de2362d3Smrg
385de2362d3Smrgstruct radeon_vbo_object {
386de2362d3Smrg    int               vb_offset;
387de2362d3Smrg    int               vb_total;
388de2362d3Smrg    uint32_t          vb_size;
389de2362d3Smrg    uint32_t          vb_op_vert_size;
390de2362d3Smrg    int32_t           vb_start_op;
391de2362d3Smrg    struct radeon_bo *vb_bo;
392de2362d3Smrg    unsigned          verts_per_op;
393de2362d3Smrg};
394de2362d3Smrg
395de2362d3Smrgstruct radeon_accel_state {
39618781e08Smrg
397de2362d3Smrg				/* Saved values for ScreenToScreenCopy */
398de2362d3Smrg    int               xdir;
399de2362d3Smrg    int               ydir;
400de2362d3Smrg
401de2362d3Smrg    /* render accel */
402de2362d3Smrg    unsigned short    texW[2];
403de2362d3Smrg    unsigned short    texH[2];
404de2362d3Smrg    Bool              XInited3D; /* X itself has the 3D context */
405de2362d3Smrg    int               num_gb_pipes;
406de2362d3Smrg    Bool              has_tcl;
407de2362d3Smrg    Bool              allowHWDFS;
408de2362d3Smrg
409de2362d3Smrg    /* EXA */
410de2362d3Smrg    ExaDriverPtr      exa;
411de2362d3Smrg    int               exaSyncMarker;
412de2362d3Smrg    int               exaMarkerSynced;
413de2362d3Smrg    int               engineMode;
414de2362d3Smrg#define EXA_ENGINEMODE_UNKNOWN 0
415de2362d3Smrg#define EXA_ENGINEMODE_2D      1
416de2362d3Smrg#define EXA_ENGINEMODE_3D      2
417de2362d3Smrg
418de2362d3Smrg    int               composite_op;
419de2362d3Smrg    PicturePtr        dst_pic;
420de2362d3Smrg    PicturePtr        msk_pic;
421de2362d3Smrg    PicturePtr        src_pic;
422de2362d3Smrg    PixmapPtr         dst_pix;
423de2362d3Smrg    PixmapPtr         msk_pix;
424de2362d3Smrg    PixmapPtr         src_pix;
425de2362d3Smrg    Bool              is_transform[2];
426de2362d3Smrg    PictTransform     *transform[2];
427de2362d3Smrg    /* Whether we are tiling horizontally and vertically */
428de2362d3Smrg    Bool              need_src_tile_x;
429de2362d3Smrg    Bool              need_src_tile_y;
430de2362d3Smrg    /* Size of tiles ... set to 65536x65536 if not tiling in that direction */
431de2362d3Smrg    Bool              src_tile_width;
432de2362d3Smrg    Bool              src_tile_height;
433de2362d3Smrg    uint32_t          *draw_header;
434de2362d3Smrg    unsigned          vtx_count;
435de2362d3Smrg    unsigned          num_vtx;
436de2362d3Smrg    Bool              vsync;
437de2362d3Smrg
438de2362d3Smrg    struct radeon_vbo_object vbo;
439de2362d3Smrg    struct radeon_vbo_object cbuf;
440de2362d3Smrg
441de2362d3Smrg    /* where to discard IB from if we cancel operation */
442de2362d3Smrg    uint32_t          ib_reset_op;
443de2362d3Smrg    struct radeon_dma_bo bo_free;
444de2362d3Smrg    struct radeon_dma_bo bo_wait;
445de2362d3Smrg    struct radeon_dma_bo bo_reserved;
446de2362d3Smrg    Bool use_vbos;
447de2362d3Smrg    void (*finish_op)(ScrnInfoPtr, int);
448de2362d3Smrg    // shader storage
449de2362d3Smrg    struct radeon_bo  *shaders_bo;
450de2362d3Smrg    uint32_t          solid_vs_offset;
451de2362d3Smrg    uint32_t          solid_ps_offset;
452de2362d3Smrg    uint32_t          copy_vs_offset;
453de2362d3Smrg    uint32_t          copy_ps_offset;
454de2362d3Smrg    uint32_t          comp_vs_offset;
455de2362d3Smrg    uint32_t          comp_ps_offset;
456de2362d3Smrg    uint32_t          xv_vs_offset;
457de2362d3Smrg    uint32_t          xv_ps_offset;
458de2362d3Smrg    // shader consts
459de2362d3Smrg    uint32_t          solid_vs_const_offset;
460de2362d3Smrg    uint32_t          solid_ps_const_offset;
461de2362d3Smrg    uint32_t          copy_vs_const_offset;
462de2362d3Smrg    uint32_t          copy_ps_const_offset;
463de2362d3Smrg    uint32_t          comp_vs_const_offset;
464de2362d3Smrg    uint32_t          comp_ps_const_offset;
465de2362d3Smrg    uint32_t          comp_mask_ps_const_offset;
466de2362d3Smrg    uint32_t          xv_vs_const_offset;
467de2362d3Smrg    uint32_t          xv_ps_const_offset;
468de2362d3Smrg
469de2362d3Smrg    //size/addr stuff
470de2362d3Smrg    struct r600_accel_object src_obj[2];
471de2362d3Smrg    struct r600_accel_object dst_obj;
472de2362d3Smrg    uint32_t          src_size[2];
473de2362d3Smrg    uint32_t          dst_size;
474de2362d3Smrg
475de2362d3Smrg    uint32_t          vs_size;
476de2362d3Smrg    uint64_t          vs_mc_addr;
477de2362d3Smrg    uint32_t          ps_size;
478de2362d3Smrg    uint64_t          ps_mc_addr;
479de2362d3Smrg
480de2362d3Smrg    // solid/copy
48118781e08Smrg    void *copy_area;
482de2362d3Smrg    struct radeon_bo  *copy_area_bo;
483de2362d3Smrg    Bool              same_surface;
484de2362d3Smrg    int               rop;
485de2362d3Smrg    uint32_t          planemask;
486de2362d3Smrg    uint32_t          fg;
487de2362d3Smrg
488de2362d3Smrg    // composite
489de2362d3Smrg    Bool              component_alpha;
490de2362d3Smrg    Bool              src_alpha;
491de2362d3Smrg    // vline
492de2362d3Smrg    xf86CrtcPtr       vline_crtc;
493de2362d3Smrg    int               vline_y1;
494de2362d3Smrg    int               vline_y2;
495de2362d3Smrg
49618781e08Smrg    Bool              force;
49718781e08Smrg};
498de2362d3Smrg
49918781e08Smrgstruct radeon_client_priv {
50018781e08Smrg    uint_fast32_t     needs_flush;
5017314432eSmrg};
5027314432eSmrg
5038bf5c682Smrgstruct radeon_device_priv {
5048bf5c682Smrg    CursorPtr cursor;
5058bf5c682Smrg    Bool sprite_visible;
5068bf5c682Smrg};
5078bf5c682Smrg
5088bf5c682Smrgextern DevScreenPrivateKeyRec radeon_device_private_key;
5098bf5c682Smrg
510de2362d3Smrgtypedef struct {
511de2362d3Smrg    EntityInfoPtr     pEnt;
512de2362d3Smrg    pciVideoPtr       PciInfo;
513de2362d3Smrg    int               Chipset;
514de2362d3Smrg    RADEONChipFamily  ChipFamily;
51518781e08Smrg
5168bf5c682Smrg    Bool              (*CloseScreen)(ScreenPtr pScreen);
517de2362d3Smrg
518de2362d3Smrg    void              (*BlockHandler)(BLOCKHANDLER_ARGS_DECL);
519de2362d3Smrg
52018781e08Smrg    void              (*CreateFence) (ScreenPtr pScreen, struct _SyncFence *pFence,
52118781e08Smrg				      Bool initially_triggered);
5220d16fef4Smrg
523de2362d3Smrg    int               pix24bpp;         /* Depth of pixmap for 24bpp fb      */
524de2362d3Smrg    Bool              dac6bits;         /* Use 6 bit DAC?                    */
525de2362d3Smrg
52618781e08Smrg    int               pixel_bytes;
527de2362d3Smrg
528de2362d3Smrg    Bool              directRenderingEnabled;
529de2362d3Smrg    struct radeon_dri2  dri2;
530de2362d3Smrg
531de2362d3Smrg    /* accel */
532de2362d3Smrg    Bool              RenderAccel; /* Render */
533de2362d3Smrg    Bool              allowColorTiling;
534de2362d3Smrg    Bool              allowColorTiling2D;
53518781e08Smrg    int               callback_event_type;
53618781e08Smrg    uint_fast32_t     gpu_flushed;
53718781e08Smrg    uint_fast32_t     gpu_synced;
538de2362d3Smrg    struct radeon_accel_state *accel_state;
53918781e08Smrg    PixmapPtr         fbcon_pixmap;
540de2362d3Smrg    Bool              accelOn;
54118781e08Smrg    Bool              use_glamor;
54218781e08Smrg    Bool              shadow_primary;
5433ed65abbSmrg    int               tear_free;
544de2362d3Smrg    Bool	      exa_pixmaps;
545de2362d3Smrg    Bool              exa_force_create;
546de2362d3Smrg    XF86ModReqInfo    exaReq;
54718781e08Smrg    Bool              is_fast_fb; /* use direct mapping for fast fb access */
548de2362d3Smrg
549de2362d3Smrg    unsigned int xv_max_width;
550de2362d3Smrg    unsigned int xv_max_height;
551de2362d3Smrg
552de2362d3Smrg    /* general */
553de2362d3Smrg    OptionInfoPtr     Options;
554de2362d3Smrg
55518781e08Smrg    DisplayModePtr currentMode;
556de2362d3Smrg
557de2362d3Smrg    CreateScreenResourcesProcPtr CreateScreenResources;
55818781e08Smrg    CreateWindowProcPtr CreateWindow;
5593ed65abbSmrg    WindowExposuresProcPtr WindowExposures;
5608bf5c682Smrg    void (*SetCursor) (DeviceIntPtr pDev, ScreenPtr pScreen,
5618bf5c682Smrg		       CursorPtr pCursor, int x, int y);
5628bf5c682Smrg    void (*MoveCursor) (DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y);
5638bf5c682Smrg
5648bf5c682Smrg    /* Number of SW cursors currently visible on this screen */
5658bf5c682Smrg    int sprites_visible;
566de2362d3Smrg
567de2362d3Smrg    Bool              IsSecondary;
568de2362d3Smrg
569de2362d3Smrg    Bool              r600_shadow_fb;
570de2362d3Smrg    void *fb_shadow;
571de2362d3Smrg
572de2362d3Smrg    void (*reemit_current2d)(ScrnInfoPtr pScrn, int op); // emit the current 2D state into the IB
573de2362d3Smrg    struct radeon_2d_state state_2d;
574de2362d3Smrg    struct radeon_bo *front_bo;
575de2362d3Smrg    struct radeon_bo_manager *bufmgr;
576de2362d3Smrg    struct radeon_cs_manager *csm;
577de2362d3Smrg    struct radeon_cs *cs;
578de2362d3Smrg
579de2362d3Smrg    struct radeon_bo *cursor_bo[32];
580de2362d3Smrg    uint64_t vram_size;
581de2362d3Smrg    uint64_t gart_size;
582de2362d3Smrg    drmmode_rec drmmode;
58318781e08Smrg    Bool drmmode_inited;
584de2362d3Smrg    /* r6xx+ tile config */
585de2362d3Smrg    Bool have_tiling_info;
586de2362d3Smrg    uint32_t tile_config;
587de2362d3Smrg    int group_bytes;
588de2362d3Smrg    int num_channels;
589de2362d3Smrg    int num_banks;
590de2362d3Smrg    int r7xx_bank_op;
591de2362d3Smrg    struct radeon_surface_manager *surf_man;
592de2362d3Smrg    struct radeon_surface front_surface;
593de2362d3Smrg
594de2362d3Smrg    /* Xv bicubic filtering */
595de2362d3Smrg    struct radeon_bo *bicubic_bo;
59618781e08Smrg
597de2362d3Smrg    /* kms pageflipping */
598de2362d3Smrg    Bool allowPageFlip;
599de2362d3Smrg
600de2362d3Smrg    /* Perform vsync'ed SwapBuffers? */
601de2362d3Smrg    Bool swapBuffersWait;
602de2362d3Smrg
60318781e08Smrg    /* cursor size */
60418781e08Smrg    int cursor_w;
60518781e08Smrg    int cursor_h;
6060d16fef4Smrg
60718781e08Smrg    /* If bit n of this field is set, xf86_config->crtc[n] currently can't
60818781e08Smrg     * use the HW cursor
60918781e08Smrg     */
61018781e08Smrg    unsigned hwcursor_disabled;
61118781e08Smrg
61218781e08Smrg#ifdef USE_GLAMOR
61318781e08Smrg    struct {
61418781e08Smrg	CreateGCProcPtr SavedCreateGC;
61518781e08Smrg	RegionPtr (*SavedCopyArea)(DrawablePtr, DrawablePtr, GCPtr, int, int,
61618781e08Smrg				   int, int, int, int);
61718781e08Smrg	void (*SavedPolyFillRect)(DrawablePtr, GCPtr, int, xRectangle*);
61818781e08Smrg	CloseScreenProcPtr SavedCloseScreen;
61918781e08Smrg	GetImageProcPtr SavedGetImage;
62018781e08Smrg	GetSpansProcPtr SavedGetSpans;
62118781e08Smrg	CreatePixmapProcPtr SavedCreatePixmap;
62218781e08Smrg	DestroyPixmapProcPtr SavedDestroyPixmap;
62318781e08Smrg	CopyWindowProcPtr SavedCopyWindow;
62418781e08Smrg	ChangeWindowAttributesProcPtr SavedChangeWindowAttributes;
62518781e08Smrg	BitmapToRegionProcPtr SavedBitmapToRegion;
62618781e08Smrg#ifdef RENDER
62718781e08Smrg	CompositeProcPtr SavedComposite;
62818781e08Smrg	TrianglesProcPtr SavedTriangles;
62918781e08Smrg	GlyphsProcPtr SavedGlyphs;
63018781e08Smrg	TrapezoidsProcPtr SavedTrapezoids;
63118781e08Smrg	AddTrapsProcPtr SavedAddTraps;
63218781e08Smrg	UnrealizeGlyphProcPtr SavedUnrealizeGlyph;
63318781e08Smrg#endif
63418781e08Smrg	SharePixmapBackingProcPtr SavedSharePixmapBacking;
63518781e08Smrg	SetSharedPixmapBackingProcPtr SavedSetSharedPixmapBacking;
63618781e08Smrg    } glamor;
63718781e08Smrg#endif /* USE_GLAMOR */
6388bf5c682Smrg
6398bf5c682Smrg    xf86CrtcFuncsRec drmmode_crtc_funcs;
64018781e08Smrg} RADEONInfoRec, *RADEONInfoPtr;
641de2362d3Smrg
642de2362d3Smrg/* radeon_accel.c */
643de2362d3Smrgextern Bool RADEONAccelInit(ScreenPtr pScreen);
644de2362d3Smrgextern void RADEONEngineInit(ScrnInfoPtr pScrn);
645de2362d3Smrgextern void  RADEONCopySwap(uint8_t *dst, uint8_t *src, unsigned int size, int swap);
646de2362d3Smrgextern void RADEONInit3DEngine(ScrnInfoPtr pScrn);
647de2362d3Smrgextern int radeon_cs_space_remaining(ScrnInfoPtr pScrn);
648de2362d3Smrg
6498bf5c682Smrg/* radeon_bo_helper.c */
6508bf5c682Smrgextern Bool radeon_get_pixmap_handle(PixmapPtr pixmap, uint32_t *handle);
6518bf5c682Smrg
6527821949aSmrg/* radeon_commonfuncs.c */
65318781e08Smrgextern void RADEONWaitForVLine(ScrnInfoPtr pScrn, PixmapPtr pPix,
65418781e08Smrg			       xf86CrtcPtr crtc, int start, int stop);
65518781e08Smrg
656de2362d3Smrg
657de2362d3Smrg/* radeon_exa.c */
658de2362d3Smrgextern unsigned eg_tile_split(unsigned tile_split);
659de2362d3Smrgextern Bool radeon_transform_is_affine_or_scaled(PictTransformPtr t);
660de2362d3Smrg
661de2362d3Smrg/* radeon_exa_funcs.c */
66218781e08Smrgextern Bool RADEONDrawInit(ScreenPtr pScreen);
663de2362d3Smrgextern Bool R600DrawInit(ScreenPtr pScreen);
664de2362d3Smrgextern Bool R600LoadShaders(ScrnInfoPtr pScrn);
665de2362d3Smrgextern Bool EVERGREENDrawInit(ScreenPtr pScreen);
666de2362d3Smrg
667de2362d3Smrg/* radeon_exa.c */
668de2362d3Smrgextern Bool RADEONGetDatatypeBpp(int bpp, uint32_t *type);
669de2362d3Smrgextern Bool RADEONGetPixmapOffsetPitch(PixmapPtr pPix,
670de2362d3Smrg				       uint32_t *pitch_offset);
671de2362d3Smrg
67218781e08Smrg/* radeon_dri3.c */
67318781e08SmrgBool radeon_dri3_screen_init(ScreenPtr screen);
67418781e08Smrg
67518781e08Smrg/* radeon_kms.c */
6768bf5c682SmrgBool radeon_scanout_do_update(xf86CrtcPtr xf86_crtc, int scanout_id,
6778bf5c682Smrg			      PixmapPtr src_pix, BoxPtr extents);
6788bf5c682Smrgvoid RADEONWindowExposures_oneshot(WindowPtr pWin, RegionPtr pRegion
6798bf5c682Smrg#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1,16,99,901,0)
6808bf5c682Smrg				   , RegionPtr pBSRegion
6818bf5c682Smrg#endif
6828bf5c682Smrg				   );
68318781e08Smrg
68418781e08Smrg/* radeon_present.c */
68518781e08SmrgBool radeon_present_screen_init(ScreenPtr screen);
68618781e08Smrg
68718781e08Smrg/* radeon_sync.c */
68818781e08Smrgextern Bool radeon_sync_init(ScreenPtr screen);
68918781e08Smrgextern void radeon_sync_close(ScreenPtr screen);
6900d16fef4Smrg
691de2362d3Smrg/* radeon_video.c */
692de2362d3Smrgextern void RADEONInitVideo(ScreenPtr pScreen);
693de2362d3Smrgextern void RADEONResetVideo(ScrnInfoPtr pScrn);
694de2362d3Smrgextern Bool radeon_load_bicubic_texture(ScrnInfoPtr pScrn);
695de2362d3Smrgextern xf86CrtcPtr radeon_pick_best_crtc(ScrnInfoPtr pScrn,
69618781e08Smrg					 Bool consider_disabled,
697de2362d3Smrg					 int x1, int x2, int y1, int y2);
698de2362d3Smrg
699de2362d3Smrgextern void radeon_cs_flush_indirect(ScrnInfoPtr pScrn);
700de2362d3Smrgextern void radeon_ddx_cs_start(ScrnInfoPtr pScrn,
701de2362d3Smrg				int num, const char *file,
702de2362d3Smrg				const char *func, int line);
70318781e08Smrgvoid radeon_kms_update_vram_limit(ScrnInfoPtr pScrn, uint32_t new_fb_size);
70418781e08Smrgextern RADEONEntPtr RADEONEntPriv(ScrnInfoPtr pScrn);
70518781e08Smrg
70618781e08Smrgstatic inline struct radeon_surface *radeon_get_pixmap_surface(PixmapPtr pPix)
70718781e08Smrg{
70818781e08Smrg#ifdef USE_GLAMOR
70918781e08Smrg    RADEONInfoPtr info = RADEONPTR(xf86ScreenToScrn(pPix->drawable.pScreen));
71018781e08Smrg
71118781e08Smrg    if (info->use_glamor) {
71218781e08Smrg	struct radeon_pixmap *priv;
71318781e08Smrg	priv = radeon_get_pixmap_private(pPix);
71418781e08Smrg	return priv ? &priv->surface : NULL;
71518781e08Smrg    } else
71618781e08Smrg#endif
71718781e08Smrg    {
71818781e08Smrg	struct radeon_exa_pixmap_priv *driver_priv;
71918781e08Smrg	driver_priv = exaGetPixmapDriverPrivate(pPix);
72018781e08Smrg	return &driver_priv->surface;
72118781e08Smrg    }
72218781e08Smrg
72318781e08Smrg    return NULL;
72418781e08Smrg}
72518781e08Smrg
726de2362d3Smrguint32_t radeon_get_pixmap_tiling(PixmapPtr pPix);
727de2362d3Smrg
72818781e08Smrgstatic inline Bool radeon_set_pixmap_bo(PixmapPtr pPix, struct radeon_bo *bo)
72918781e08Smrg{
7308bf5c682Smrg    ScrnInfoPtr scrn = xf86ScreenToScrn(pPix->drawable.pScreen);
7318bf5c682Smrg    RADEONEntPtr pRADEONEnt = RADEONEntPriv(scrn);
73218781e08Smrg#ifdef USE_GLAMOR
7338bf5c682Smrg    RADEONInfoPtr info = RADEONPTR(scrn);
734de2362d3Smrg
73518781e08Smrg    if (info->use_glamor) {
73618781e08Smrg	struct radeon_pixmap *priv;
737de2362d3Smrg
73818781e08Smrg	priv = radeon_get_pixmap_private(pPix);
73918781e08Smrg	if (priv == NULL && bo == NULL)
74018781e08Smrg	    return TRUE;
741de2362d3Smrg
74218781e08Smrg	if (priv) {
74318781e08Smrg	    if (priv->bo) {
74418781e08Smrg		if (priv->bo == bo)
74518781e08Smrg		    return TRUE;
7467314432eSmrg
74718781e08Smrg		radeon_bo_unref(priv->bo);
74818781e08Smrg	    }
749de2362d3Smrg
7508bf5c682Smrg	    drmmode_fb_reference(pRADEONEnt->fd, &priv->fb, NULL);
7518bf5c682Smrg
75218781e08Smrg	    if (!bo) {
75318781e08Smrg		free(priv);
75418781e08Smrg		priv = NULL;
75518781e08Smrg	    }
75618781e08Smrg	}
75718781e08Smrg
75818781e08Smrg	if (bo) {
75918781e08Smrg	    uint32_t pitch;
76018781e08Smrg
76118781e08Smrg	    if (!priv) {
76218781e08Smrg		priv = calloc(1, sizeof (struct radeon_pixmap));
76318781e08Smrg		if (!priv)
76418781e08Smrg		    return FALSE;
76518781e08Smrg	    }
766de2362d3Smrg
76718781e08Smrg	    radeon_bo_ref(bo);
76818781e08Smrg	    priv->bo = bo;
76918781e08Smrg
77018781e08Smrg	    radeon_bo_get_tiling(bo, &priv->tiling_flags, &pitch);
77118781e08Smrg	}
77218781e08Smrg
77318781e08Smrg	radeon_set_pixmap_private(pPix, priv);
77418781e08Smrg	return TRUE;
77518781e08Smrg    } else
77618781e08Smrg#endif /* USE_GLAMOR */
77718781e08Smrg    {
77818781e08Smrg	struct radeon_exa_pixmap_priv *driver_priv;
77918781e08Smrg
78018781e08Smrg	driver_priv = exaGetPixmapDriverPrivate(pPix);
78118781e08Smrg	if (driver_priv) {
78218781e08Smrg	    uint32_t pitch;
78318781e08Smrg
78418781e08Smrg	    if (driver_priv->bo)
78518781e08Smrg		radeon_bo_unref(driver_priv->bo);
78618781e08Smrg
7878bf5c682Smrg	    drmmode_fb_reference(pRADEONEnt->fd, &driver_priv->fb, NULL);
7888bf5c682Smrg
78918781e08Smrg	    radeon_bo_ref(bo);
79018781e08Smrg	    driver_priv->bo = bo;
79118781e08Smrg
79218781e08Smrg	    radeon_bo_get_tiling(bo, &driver_priv->tiling_flags, &pitch);
79318781e08Smrg	    return TRUE;
79418781e08Smrg	}
79518781e08Smrg
79618781e08Smrg	return FALSE;
79718781e08Smrg    }
79818781e08Smrg}
79918781e08Smrg
80018781e08Smrgstatic inline struct radeon_bo *radeon_get_pixmap_bo(PixmapPtr pPix)
80118781e08Smrg{
80218781e08Smrg#ifdef USE_GLAMOR
80318781e08Smrg    RADEONInfoPtr info = RADEONPTR(xf86ScreenToScrn(pPix->drawable.pScreen));
80418781e08Smrg
80518781e08Smrg    if (info->use_glamor) {
80618781e08Smrg	struct radeon_pixmap *priv;
80718781e08Smrg	priv = radeon_get_pixmap_private(pPix);
80818781e08Smrg	return priv ? priv->bo : NULL;
80918781e08Smrg    } else
81018781e08Smrg#endif
81118781e08Smrg    {
81218781e08Smrg	struct radeon_exa_pixmap_priv *driver_priv;
81318781e08Smrg	driver_priv = exaGetPixmapDriverPrivate(pPix);
81418781e08Smrg	return driver_priv ? driver_priv->bo : NULL;
81518781e08Smrg    }
81618781e08Smrg
81718781e08Smrg    return NULL;
81818781e08Smrg}
81918781e08Smrg
82018781e08Smrgstatic inline Bool radeon_get_pixmap_shared(PixmapPtr pPix)
82118781e08Smrg{
82218781e08Smrg#ifdef USE_GLAMOR
82318781e08Smrg    RADEONInfoPtr info = RADEONPTR(xf86ScreenToScrn(pPix->drawable.pScreen));
82418781e08Smrg
82518781e08Smrg    if (info->use_glamor) {
82618781e08Smrg        ErrorF("glamor sharing todo\n");
82718781e08Smrg	return FALSE;
82818781e08Smrg    } else
82918781e08Smrg#endif
83018781e08Smrg    {
83118781e08Smrg	struct radeon_exa_pixmap_priv *driver_priv;
83218781e08Smrg	driver_priv = exaGetPixmapDriverPrivate(pPix);
83318781e08Smrg	return driver_priv->shared;
83418781e08Smrg    }
83518781e08Smrg    return FALSE;
83618781e08Smrg}
837de2362d3Smrg
8388bf5c682Smrgstatic inline struct drmmode_fb*
8398bf5c682Smrgradeon_fb_create(ScrnInfoPtr scrn, int drm_fd, uint32_t width, uint32_t height,
8408bf5c682Smrg		 uint32_t pitch, uint32_t handle)
8418bf5c682Smrg{
8428bf5c682Smrg    struct drmmode_fb *fb  = malloc(sizeof(*fb));
8438bf5c682Smrg
8448bf5c682Smrg    if (!fb)
8458bf5c682Smrg	return NULL;
8468bf5c682Smrg
8478bf5c682Smrg    fb->refcnt = 1;
8488bf5c682Smrg    if (drmModeAddFB(drm_fd, width, height, scrn->depth, scrn->bitsPerPixel,
8498bf5c682Smrg		     pitch, handle, &fb->handle) == 0)
8508bf5c682Smrg	return fb;
8518bf5c682Smrg
8528bf5c682Smrg    free(fb);
8538bf5c682Smrg    return NULL;
8548bf5c682Smrg}
8558bf5c682Smrg
8568bf5c682Smrgstatic inline struct drmmode_fb**
8578bf5c682Smrgradeon_pixmap_get_fb_ptr(PixmapPtr pix)
8588bf5c682Smrg{
8598bf5c682Smrg    ScrnInfoPtr scrn = xf86ScreenToScrn(pix->drawable.pScreen);
8608bf5c682Smrg    RADEONInfoPtr info = RADEONPTR(scrn);
8618bf5c682Smrg
8628bf5c682Smrg#ifdef USE_GLAMOR
8638bf5c682Smrg    if (info->use_glamor) {
8648bf5c682Smrg	struct radeon_pixmap *priv = radeon_get_pixmap_private(pix);
8658bf5c682Smrg
8668bf5c682Smrg	if (!priv)
8678bf5c682Smrg	    return NULL;
8688bf5c682Smrg
8698bf5c682Smrg	return &priv->fb;
8708bf5c682Smrg    } else
8718bf5c682Smrg#endif
8728bf5c682Smrg    if (info->accelOn)
8738bf5c682Smrg    {
8748bf5c682Smrg	struct radeon_exa_pixmap_priv *driver_priv =
8758bf5c682Smrg	    exaGetPixmapDriverPrivate(pix);
8768bf5c682Smrg
8778bf5c682Smrg	if (!driver_priv)
8788bf5c682Smrg	    return NULL;
8798bf5c682Smrg
8808bf5c682Smrg	return &driver_priv->fb;
8818bf5c682Smrg    }
8828bf5c682Smrg
8838bf5c682Smrg    return NULL;
8848bf5c682Smrg}
8858bf5c682Smrg
8868bf5c682Smrgstatic inline struct drmmode_fb*
8878bf5c682Smrgradeon_pixmap_get_fb(PixmapPtr pix)
8888bf5c682Smrg{
8898bf5c682Smrg    struct drmmode_fb **fb_ptr = radeon_pixmap_get_fb_ptr(pix);
8908bf5c682Smrg
8918bf5c682Smrg    if (!fb_ptr)
8928bf5c682Smrg	return NULL;
8938bf5c682Smrg
8948bf5c682Smrg    if (!*fb_ptr) {
8958bf5c682Smrg	uint32_t handle;
8968bf5c682Smrg
8978bf5c682Smrg	if (radeon_get_pixmap_handle(pix, &handle)) {
8988bf5c682Smrg	    ScrnInfoPtr scrn = xf86ScreenToScrn(pix->drawable.pScreen);
8998bf5c682Smrg	    RADEONEntPtr pRADEONEnt = RADEONEntPriv(scrn);
9008bf5c682Smrg
9018bf5c682Smrg	    *fb_ptr = radeon_fb_create(scrn, pRADEONEnt->fd, pix->drawable.width,
9028bf5c682Smrg				       pix->drawable.height, pix->devKind,
9038bf5c682Smrg				       handle);
9048bf5c682Smrg	}
9058bf5c682Smrg    }
9068bf5c682Smrg
9078bf5c682Smrg    return *fb_ptr;
9088bf5c682Smrg}
9098bf5c682Smrg
910de2362d3Smrg#define CP_PACKET0(reg, n)						\
911de2362d3Smrg	(RADEON_CP_PACKET0 | ((n) << 16) | ((reg) >> 2))
912de2362d3Smrg#define CP_PACKET1(reg0, reg1)						\
913de2362d3Smrg	(RADEON_CP_PACKET1 | (((reg1) >> 2) << 11) | ((reg0) >> 2))
914de2362d3Smrg#define CP_PACKET2()							\
915de2362d3Smrg	(RADEON_CP_PACKET2)
916de2362d3Smrg#define CP_PACKET3(pkt, n)						\
917de2362d3Smrg	(RADEON_CP_PACKET3 | (pkt) | ((n) << 16))
918de2362d3Smrg
919de2362d3Smrg
920de2362d3Smrg#define RADEON_VERBOSE	0
921de2362d3Smrg
922de2362d3Smrg#define BEGIN_RING(n) do {						\
923de2362d3Smrg    if (RADEON_VERBOSE) {						\
924de2362d3Smrg	xf86DrvMsg(pScrn->scrnIndex, X_INFO,				\
925de2362d3Smrg		   "BEGIN_RING(%d) in %s\n", (unsigned int)n, __FUNCTION__);\
926de2362d3Smrg    }									\
92718781e08Smrg    radeon_ddx_cs_start(pScrn, n, __FILE__, __func__, __LINE__);   \
928de2362d3Smrg} while (0)
929de2362d3Smrg
930de2362d3Smrg#define ADVANCE_RING() do {						\
93118781e08Smrg    radeon_cs_end(info->cs, __FILE__, __func__, __LINE__); \
932de2362d3Smrg  } while (0)
933de2362d3Smrg
934de2362d3Smrg#define OUT_RING(x) do {						\
935de2362d3Smrg    if (RADEON_VERBOSE) {						\
936de2362d3Smrg	xf86DrvMsg(pScrn->scrnIndex, X_INFO,				\
937de2362d3Smrg		   "   OUT_RING(0x%08x)\n", (unsigned int)(x));		\
938de2362d3Smrg    }									\
93918781e08Smrg    radeon_cs_write_dword(info->cs, (x));		\
940de2362d3Smrg} while (0)
941de2362d3Smrg
942de2362d3Smrg#define OUT_RING_REG(reg, val)						\
943de2362d3Smrgdo {									\
944de2362d3Smrg    OUT_RING(CP_PACKET0(reg, 0));					\
945de2362d3Smrg    OUT_RING(val);							\
946de2362d3Smrg} while (0)
947de2362d3Smrg
948de2362d3Smrg#define OUT_RING_RELOC(x, read_domains, write_domain)			\
949de2362d3Smrg  do {									\
950de2362d3Smrg	int _ret; \
951de2362d3Smrg    _ret = radeon_cs_write_reloc(info->cs, x, read_domains, write_domain, 0); \
952de2362d3Smrg	if (_ret) ErrorF("reloc emit failure %d\n", _ret); \
953de2362d3Smrg  } while(0)
954de2362d3Smrg
955de2362d3Smrg
956de2362d3Smrg#define FLUSH_RING()							\
957de2362d3Smrgdo {									\
958de2362d3Smrg    if (RADEON_VERBOSE)							\
959de2362d3Smrg	xf86DrvMsg(pScrn->scrnIndex, X_INFO,				\
960de2362d3Smrg		   "FLUSH_RING in %s\n", __FUNCTION__);			\
96118781e08Smrg    radeon_cs_flush_indirect(pScrn); 				\
962de2362d3Smrg} while (0)
963de2362d3Smrg
964de2362d3Smrg#define CS_FULL(cs) ((cs)->cdw > 15 * 1024)
965de2362d3Smrg
966de2362d3Smrg#define RADEON_SWITCH_TO_2D()						\
967de2362d3Smrgdo {									\
968de2362d3Smrg	uint32_t flush = 0;                                             \
969de2362d3Smrg	switch (info->accel_state->engineMode) {			\
970de2362d3Smrg	case EXA_ENGINEMODE_UNKNOWN:					\
971de2362d3Smrg	    flush = 1;                                                  \
972de2362d3Smrg	    break;							\
973de2362d3Smrg	case EXA_ENGINEMODE_3D:						\
97418781e08Smrg	    flush = CS_FULL(info->cs);			\
975de2362d3Smrg	    break;							\
976de2362d3Smrg	case EXA_ENGINEMODE_2D:						\
97718781e08Smrg	    flush = CS_FULL(info->cs);			\
978de2362d3Smrg	    break;							\
979de2362d3Smrg	}								\
980de2362d3Smrg	if (flush) {							\
98118781e08Smrg	    radeon_cs_flush_indirect(pScrn);			\
982de2362d3Smrg	}								\
983de2362d3Smrg        info->accel_state->engineMode = EXA_ENGINEMODE_2D;              \
984de2362d3Smrg} while (0);
985de2362d3Smrg
986de2362d3Smrg#define RADEON_SWITCH_TO_3D()						\
987de2362d3Smrgdo {									\
988de2362d3Smrg	uint32_t flush = 0;						\
989de2362d3Smrg	switch (info->accel_state->engineMode) {			\
990de2362d3Smrg	case EXA_ENGINEMODE_UNKNOWN:					\
991de2362d3Smrg	    flush = 1;                                                  \
992de2362d3Smrg	    break;							\
993de2362d3Smrg	case EXA_ENGINEMODE_2D:						\
99418781e08Smrg	    flush = CS_FULL(info->cs);	 		\
995de2362d3Smrg	    break;							\
996de2362d3Smrg	case EXA_ENGINEMODE_3D:						\
99718781e08Smrg	    flush = CS_FULL(info->cs);			\
998de2362d3Smrg	    break;							\
999de2362d3Smrg	}								\
1000de2362d3Smrg	if (flush) {							\
100118781e08Smrg	    radeon_cs_flush_indirect(pScrn);			\
1002de2362d3Smrg	}                                                               \
1003de2362d3Smrg	if (!info->accel_state->XInited3D)				\
1004de2362d3Smrg	    RADEONInit3DEngine(pScrn);                                  \
1005de2362d3Smrg        info->accel_state->engineMode = EXA_ENGINEMODE_3D;              \
1006de2362d3Smrg} while (0);
1007de2362d3Smrg
100818781e08Smrg				/* Memory mapped register access macros */
100918781e08Smrg
101018781e08Smrg#define BEGIN_ACCEL_RELOC(n, r) do {		\
101118781e08Smrg	int _nqw = (n) + (r);	\
101218781e08Smrg	BEGIN_RING(2*_nqw);			\
101318781e08Smrg    } while (0)
101418781e08Smrg
101518781e08Smrg#define EMIT_OFFSET(reg, value, pPix, rd, wd) do {		\
101618781e08Smrg    driver_priv = exaGetPixmapDriverPrivate(pPix);		\
101718781e08Smrg    OUT_RING_REG((reg), (value));				\
101818781e08Smrg    OUT_RING_RELOC(driver_priv->bo, (rd), (wd));			\
101918781e08Smrg    } while(0)
102018781e08Smrg
102118781e08Smrg#define EMIT_READ_OFFSET(reg, value, pPix) EMIT_OFFSET(reg, value, pPix, (RADEON_GEM_DOMAIN_VRAM | RADEON_GEM_DOMAIN_GTT), 0)
102218781e08Smrg#define EMIT_WRITE_OFFSET(reg, value, pPix) EMIT_OFFSET(reg, value, pPix, 0, RADEON_GEM_DOMAIN_VRAM)
102318781e08Smrg
102418781e08Smrg#define OUT_TEXTURE_REG(reg, offset, bo) do {   \
102518781e08Smrg    OUT_RING_REG((reg), (offset));                                   \
102618781e08Smrg    OUT_RING_RELOC((bo), RADEON_GEM_DOMAIN_VRAM | RADEON_GEM_DOMAIN_GTT, 0); \
102718781e08Smrg  } while(0)
102818781e08Smrg
102918781e08Smrg#define EMIT_COLORPITCH(reg, value, pPix) do {			\
103018781e08Smrg    driver_priv = exaGetPixmapDriverPrivate(pPix);			\
103118781e08Smrg    OUT_RING_REG((reg), value);					\
103218781e08Smrg    OUT_RING_RELOC(driver_priv->bo, 0, RADEON_GEM_DOMAIN_VRAM);		\
103318781e08Smrg} while(0)
1034de2362d3Smrg
1035de2362d3Smrgstatic __inline__ void RADEON_SYNC(RADEONInfoPtr info, ScrnInfoPtr pScrn)
1036de2362d3Smrg{
103718781e08Smrg    if (pScrn->pScreen)
1038de2362d3Smrg	exaWaitSync(pScrn->pScreen);
1039de2362d3Smrg}
1040de2362d3Smrg
104118781e08Smrgenum {
104218781e08Smrg    RADEON_CREATE_PIXMAP_SCANOUT		= 0x02000000,
104318781e08Smrg    RADEON_CREATE_PIXMAP_DRI2			= 0x04000000,
104418781e08Smrg    RADEON_CREATE_PIXMAP_TILING_MICRO_SQUARE	= 0x08000000,
104518781e08Smrg    RADEON_CREATE_PIXMAP_TILING_MACRO		= 0x10000000,
104618781e08Smrg    RADEON_CREATE_PIXMAP_TILING_MICRO		= 0x20000000,
104718781e08Smrg    RADEON_CREATE_PIXMAP_DEPTH			= 0x40000000, /* for r200 */
104818781e08Smrg    RADEON_CREATE_PIXMAP_SZBUFFER		= 0x80000000, /* for eg */
104918781e08Smrg};
1050de2362d3Smrg
105118781e08Smrg#define RADEON_CREATE_PIXMAP_TILING_FLAGS	\
105218781e08Smrg    (RADEON_CREATE_PIXMAP_TILING_MICRO_SQUARE |	\
105318781e08Smrg     RADEON_CREATE_PIXMAP_TILING_MACRO |	\
105418781e08Smrg     RADEON_CREATE_PIXMAP_TILING_MICRO |	\
105518781e08Smrg     RADEON_CREATE_PIXMAP_DEPTH |		\
105618781e08Smrg     RADEON_CREATE_PIXMAP_SZBUFFER)
105718781e08Smrg
105818781e08Smrg
105918781e08Smrg/* Compute log base 2 of val. */
106018781e08Smrgstatic __inline__ int
106118781e08SmrgRADEONLog2(int val)
1062de2362d3Smrg{
10633ed65abbSmrg	return 31 - __builtin_clz(val);
1064de2362d3Smrg}
1065de2362d3Smrg
106618781e08Smrg#define RADEON_TILING_MASK				0xff
106718781e08Smrg#define RADEON_TILING_LINEAR				0x0
1068de2362d3Smrg
1069de2362d3Smrg#endif /* _RADEON_H_ */
1070