radeon.h revision 8bf5c682
1/*
2 * Copyright 2000 ATI Technologies Inc., Markham, Ontario, and
3 *                VA Linux Systems Inc., Fremont, California.
4 *
5 * All Rights Reserved.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining
8 * a copy of this software and associated documentation files (the
9 * "Software"), to deal in the Software without restriction, including
10 * without limitation on the rights to use, copy, modify, merge,
11 * publish, distribute, sublicense, and/or sell copies of the Software,
12 * and to permit persons to whom the Software is furnished to do so,
13 * subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice (including the
16 * next paragraph) shall be included in all copies or substantial
17 * portions of the Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
22 * NON-INFRINGEMENT.  IN NO EVENT SHALL ATI, VA LINUX SYSTEMS AND/OR
23 * THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
24 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
26 * DEALINGS IN THE SOFTWARE.
27 */
28
29/*
30 * Authors:
31 *   Kevin E. Martin <martin@xfree86.org>
32 *   Rickard E. Faith <faith@valinux.com>
33 *   Alan Hourihane <alanh@fairlite.demon.co.uk>
34 *
35 */
36
37#ifndef _RADEON_H_
38#define _RADEON_H_
39
40#include <stdlib.h>		/* For abs() */
41#include <unistd.h>		/* For usleep() */
42#include <sys/time.h>		/* For gettimeofday() */
43
44#include "config.h"
45
46#include "xf86str.h"
47#include "compiler.h"
48
49				/* PCI support */
50#include "xf86Pci.h"
51
52#include "exa.h"
53
54				/* Exa and Cursor Support */
55#include "xf86Cursor.h"
56
57				/* DDC support */
58#include "xf86DDC.h"
59
60				/* Xv support */
61#include "xf86xv.h"
62
63#include "radeon_probe.h"
64
65				/* DRI support */
66#include "xf86drm.h"
67#include "radeon_drm.h"
68
69#ifndef RADEON_GEM_NO_CPU_ACCESS
70#define RADEON_GEM_NO_CPU_ACCESS	(1 << 4)
71#endif
72
73#ifdef DAMAGE
74#include "damage.h"
75#include "globals.h"
76#endif
77
78#include "xf86Crtc.h"
79#include "X11/Xatom.h"
80
81#include "radeon_bo.h"
82#include "radeon_cs.h"
83#include "radeon_dri2.h"
84#include "drmmode_display.h"
85#include "radeon_surface.h"
86
87				/* Render support */
88#ifdef RENDER
89#include "picturestr.h"
90#endif
91
92#include "compat-api.h"
93
94#include "simple_list.h"
95#include "atipcirename.h"
96
97struct _SyncFence;
98
99#ifndef HAVE_REGIONDUPLICATE
100
101static inline RegionPtr
102RegionDuplicate(RegionPtr pOld)
103{
104    RegionPtr pNew;
105
106    pNew = RegionCreate(&pOld->extents, 0);
107    if (!pNew)
108	return NULL;
109    if (!RegionCopy(pNew, pOld)) {
110	RegionDestroy(pNew);
111	return NULL;
112    }
113    return pNew;
114}
115
116#endif
117
118#ifndef MAX
119#define MAX(a,b) ((a)>(b)?(a):(b))
120#endif
121#ifndef MIN
122#define MIN(a,b) ((a)>(b)?(b):(a))
123#endif
124
125#if HAVE_BYTESWAP_H
126#include <byteswap.h>
127#elif defined(USE_SYS_ENDIAN_H)
128#include <sys/endian.h>
129#else
130#define bswap_16(value)  \
131        ((((value) & 0xff) << 8) | ((value) >> 8))
132
133#define bswap_32(value) \
134        (((uint32_t)bswap_16((uint16_t)((value) & 0xffff)) << 16) | \
135        (uint32_t)bswap_16((uint16_t)((value) >> 16)))
136
137#define bswap_64(value) \
138        (((uint64_t)bswap_32((uint32_t)((value) & 0xffffffff)) \
139            << 32) | \
140        (uint64_t)bswap_32((uint32_t)((value) >> 32)))
141#endif
142
143#if X_BYTE_ORDER == X_BIG_ENDIAN
144#define le32_to_cpu(x) bswap_32(x)
145#define le16_to_cpu(x) bswap_16(x)
146#define cpu_to_le32(x) bswap_32(x)
147#define cpu_to_le16(x) bswap_16(x)
148#else
149#define le32_to_cpu(x) (x)
150#define le16_to_cpu(x) (x)
151#define cpu_to_le32(x) (x)
152#define cpu_to_le16(x) (x)
153#endif
154
155/* Provide substitutes for gcc's __FUNCTION__ on other compilers */
156#if !defined(__GNUC__) && !defined(__FUNCTION__)
157# define __FUNCTION__ __func__		/* C99 */
158#endif
159
160typedef enum {
161    OPTION_ACCEL,
162    OPTION_SW_CURSOR,
163    OPTION_PAGE_FLIP,
164    OPTION_EXA_PIXMAPS,
165    OPTION_COLOR_TILING,
166    OPTION_COLOR_TILING_2D,
167#ifdef RENDER
168    OPTION_RENDER_ACCEL,
169    OPTION_SUBPIXEL_ORDER,
170#endif
171    OPTION_ACCELMETHOD,
172    OPTION_EXA_VSYNC,
173    OPTION_ZAPHOD_HEADS,
174    OPTION_SWAPBUFFERS_WAIT,
175    OPTION_DELETE_DP12,
176    OPTION_DRI3,
177    OPTION_DRI,
178    OPTION_SHADOW_PRIMARY,
179    OPTION_TEAR_FREE,
180} RADEONOpts;
181
182
183static inline ScreenPtr
184radeon_master_screen(ScreenPtr screen)
185{
186    if (screen->current_master)
187	return screen->current_master;
188
189    return screen;
190}
191
192static inline ScreenPtr
193radeon_dirty_master(PixmapDirtyUpdatePtr dirty)
194{
195    return radeon_master_screen(dirty->slave_dst->drawable.pScreen);
196}
197
198static inline DrawablePtr
199radeon_dirty_src_drawable(PixmapDirtyUpdatePtr dirty)
200{
201#ifdef HAS_DIRTYTRACKING_DRAWABLE_SRC
202    return dirty->src;
203#else
204    return &dirty->src->drawable;
205#endif
206}
207
208static inline Bool
209radeon_dirty_src_equals(PixmapDirtyUpdatePtr dirty, PixmapPtr pixmap)
210{
211    return radeon_dirty_src_drawable(dirty) == &pixmap->drawable;
212}
213
214
215#define RADEON_VSYNC_TIMEOUT	20000 /* Maximum wait for VSYNC (in usecs) */
216
217/* Buffer are aligned on 4096 byte boundaries */
218#define RADEON_GPU_PAGE_SIZE 4096
219#define RADEON_BUFFER_ALIGN (RADEON_GPU_PAGE_SIZE - 1)
220
221
222#define xFixedToFloat(f) (((float) (f)) / 65536)
223
224#define RADEON_LOGLEVEL_DEBUG 4
225
226/* for Xv, outputs */
227#define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE)
228
229/* Other macros */
230#define RADEON_ALIGN(x,bytes) (((x) + ((bytes) - 1)) & ~((bytes) - 1))
231#define RADEONPTR(pScrn)      ((RADEONInfoPtr)(pScrn)->driverPrivate)
232
233#define IS_RV100_VARIANT ((info->ChipFamily == CHIP_FAMILY_RV100)  ||  \
234        (info->ChipFamily == CHIP_FAMILY_RV200)  ||  \
235        (info->ChipFamily == CHIP_FAMILY_RS100)  ||  \
236        (info->ChipFamily == CHIP_FAMILY_RS200)  ||  \
237        (info->ChipFamily == CHIP_FAMILY_RV250)  ||  \
238        (info->ChipFamily == CHIP_FAMILY_RV280)  ||  \
239        (info->ChipFamily == CHIP_FAMILY_RS300))
240
241
242#define IS_R300_VARIANT ((info->ChipFamily == CHIP_FAMILY_R300)  ||  \
243        (info->ChipFamily == CHIP_FAMILY_RV350) ||  \
244        (info->ChipFamily == CHIP_FAMILY_R350)  ||  \
245        (info->ChipFamily == CHIP_FAMILY_RV380) ||  \
246        (info->ChipFamily == CHIP_FAMILY_R420)  ||  \
247        (info->ChipFamily == CHIP_FAMILY_RV410) ||  \
248        (info->ChipFamily == CHIP_FAMILY_RS400) ||  \
249        (info->ChipFamily == CHIP_FAMILY_RS480))
250
251#define IS_AVIVO_VARIANT ((info->ChipFamily >= CHIP_FAMILY_RV515))
252
253#define IS_DCE3_VARIANT ((info->ChipFamily >= CHIP_FAMILY_RV620))
254
255#define IS_DCE32_VARIANT ((info->ChipFamily >= CHIP_FAMILY_RV730))
256
257#define IS_DCE4_VARIANT ((info->ChipFamily >= CHIP_FAMILY_CEDAR))
258
259#define IS_DCE41_VARIANT ((info->ChipFamily >= CHIP_FAMILY_PALM))
260
261#define IS_DCE5_VARIANT ((info->ChipFamily >= CHIP_FAMILY_BARTS))
262
263#define IS_EVERGREEN_3D (info->ChipFamily >= CHIP_FAMILY_CEDAR)
264
265#define IS_R600_3D (info->ChipFamily >= CHIP_FAMILY_R600)
266
267#define IS_R500_3D ((info->ChipFamily == CHIP_FAMILY_RV515)  ||  \
268	(info->ChipFamily == CHIP_FAMILY_R520)   ||  \
269	(info->ChipFamily == CHIP_FAMILY_RV530)  ||  \
270	(info->ChipFamily == CHIP_FAMILY_R580)   ||  \
271	(info->ChipFamily == CHIP_FAMILY_RV560)  ||  \
272	(info->ChipFamily == CHIP_FAMILY_RV570))
273
274/* RS6xx, RS740 are technically R4xx as well, but the
275 * clipping hardware seems to follow the r3xx restrictions
276 */
277#define IS_R400_3D ((info->ChipFamily == CHIP_FAMILY_R420)  ||  \
278	(info->ChipFamily == CHIP_FAMILY_RV410))
279
280#define IS_R300_3D ((info->ChipFamily == CHIP_FAMILY_R300)  ||  \
281	(info->ChipFamily == CHIP_FAMILY_RV350) ||  \
282	(info->ChipFamily == CHIP_FAMILY_R350)  ||  \
283	(info->ChipFamily == CHIP_FAMILY_RV380) ||  \
284	(info->ChipFamily == CHIP_FAMILY_R420)  ||  \
285	(info->ChipFamily == CHIP_FAMILY_RV410) ||  \
286	(info->ChipFamily == CHIP_FAMILY_RS690) ||  \
287	(info->ChipFamily == CHIP_FAMILY_RS600) ||  \
288	(info->ChipFamily == CHIP_FAMILY_RS740) ||  \
289	(info->ChipFamily == CHIP_FAMILY_RS400) ||  \
290	(info->ChipFamily == CHIP_FAMILY_RS480))
291
292#define IS_R200_3D ((info->ChipFamily == CHIP_FAMILY_RV250) || \
293	(info->ChipFamily == CHIP_FAMILY_RV280) || \
294	(info->ChipFamily == CHIP_FAMILY_RS300) || \
295	(info->ChipFamily == CHIP_FAMILY_R200))
296
297#define CURSOR_WIDTH	64
298#define CURSOR_HEIGHT	64
299
300#define CURSOR_WIDTH_CIK	128
301#define CURSOR_HEIGHT_CIK	128
302
303
304#ifdef USE_GLAMOR
305
306struct radeon_pixmap {
307	struct radeon_surface surface;
308
309	uint_fast32_t gpu_read;
310	uint_fast32_t gpu_write;
311
312	struct radeon_bo *bo;
313	struct drmmode_fb *fb;
314
315	uint32_t tiling_flags;
316
317	/* GEM handle for glamor-only pixmaps shared via DRI3 */
318	Bool handle_valid;
319	uint32_t handle;
320};
321
322extern DevPrivateKeyRec glamor_pixmap_index;
323
324static inline struct radeon_pixmap *radeon_get_pixmap_private(PixmapPtr pixmap)
325{
326	return dixGetPrivate(&pixmap->devPrivates, &glamor_pixmap_index);
327}
328
329static inline void radeon_set_pixmap_private(PixmapPtr pixmap, struct radeon_pixmap *priv)
330{
331	dixSetPrivate(&pixmap->devPrivates, &glamor_pixmap_index, priv);
332}
333
334#endif /* USE_GLAMOR */
335
336
337struct radeon_exa_pixmap_priv {
338    struct radeon_bo *bo;
339    struct drmmode_fb *fb;
340    uint32_t tiling_flags;
341    struct radeon_surface surface;
342    Bool bo_mapped;
343    Bool shared;
344};
345
346#define RADEON_2D_EXA_COPY 1
347#define RADEON_2D_EXA_SOLID 2
348
349struct radeon_2d_state {
350    int op; //
351    uint32_t dst_pitch_offset;
352    uint32_t src_pitch_offset;
353    uint32_t dp_gui_master_cntl;
354    uint32_t dp_cntl;
355    uint32_t dp_write_mask;
356    uint32_t dp_brush_frgd_clr;
357    uint32_t dp_brush_bkgd_clr;
358    uint32_t dp_src_frgd_clr;
359    uint32_t dp_src_bkgd_clr;
360    uint32_t default_sc_bottom_right;
361    uint32_t dst_domain;
362    struct radeon_bo *dst_bo;
363    struct radeon_bo *src_bo;
364};
365
366#define DMA_BO_FREE_TIME 1000
367
368struct radeon_dma_bo {
369    struct radeon_dma_bo *next, *prev;
370    struct radeon_bo  *bo;
371    int expire_counter;
372};
373
374struct r600_accel_object {
375    uint32_t pitch;
376    uint32_t width;
377    uint32_t height;
378    int bpp;
379    uint32_t domain;
380    struct radeon_bo *bo;
381    uint32_t tiling_flags;
382    struct radeon_surface *surface;
383};
384
385struct radeon_vbo_object {
386    int               vb_offset;
387    int               vb_total;
388    uint32_t          vb_size;
389    uint32_t          vb_op_vert_size;
390    int32_t           vb_start_op;
391    struct radeon_bo *vb_bo;
392    unsigned          verts_per_op;
393};
394
395struct radeon_accel_state {
396
397				/* Saved values for ScreenToScreenCopy */
398    int               xdir;
399    int               ydir;
400
401    /* render accel */
402    unsigned short    texW[2];
403    unsigned short    texH[2];
404    Bool              XInited3D; /* X itself has the 3D context */
405    int               num_gb_pipes;
406    Bool              has_tcl;
407    Bool              allowHWDFS;
408
409    /* EXA */
410    ExaDriverPtr      exa;
411    int               exaSyncMarker;
412    int               exaMarkerSynced;
413    int               engineMode;
414#define EXA_ENGINEMODE_UNKNOWN 0
415#define EXA_ENGINEMODE_2D      1
416#define EXA_ENGINEMODE_3D      2
417
418    int               composite_op;
419    PicturePtr        dst_pic;
420    PicturePtr        msk_pic;
421    PicturePtr        src_pic;
422    PixmapPtr         dst_pix;
423    PixmapPtr         msk_pix;
424    PixmapPtr         src_pix;
425    Bool              is_transform[2];
426    PictTransform     *transform[2];
427    /* Whether we are tiling horizontally and vertically */
428    Bool              need_src_tile_x;
429    Bool              need_src_tile_y;
430    /* Size of tiles ... set to 65536x65536 if not tiling in that direction */
431    Bool              src_tile_width;
432    Bool              src_tile_height;
433    uint32_t          *draw_header;
434    unsigned          vtx_count;
435    unsigned          num_vtx;
436    Bool              vsync;
437
438    struct radeon_vbo_object vbo;
439    struct radeon_vbo_object cbuf;
440
441    /* where to discard IB from if we cancel operation */
442    uint32_t          ib_reset_op;
443    struct radeon_dma_bo bo_free;
444    struct radeon_dma_bo bo_wait;
445    struct radeon_dma_bo bo_reserved;
446    Bool use_vbos;
447    void (*finish_op)(ScrnInfoPtr, int);
448    // shader storage
449    struct radeon_bo  *shaders_bo;
450    uint32_t          solid_vs_offset;
451    uint32_t          solid_ps_offset;
452    uint32_t          copy_vs_offset;
453    uint32_t          copy_ps_offset;
454    uint32_t          comp_vs_offset;
455    uint32_t          comp_ps_offset;
456    uint32_t          xv_vs_offset;
457    uint32_t          xv_ps_offset;
458    // shader consts
459    uint32_t          solid_vs_const_offset;
460    uint32_t          solid_ps_const_offset;
461    uint32_t          copy_vs_const_offset;
462    uint32_t          copy_ps_const_offset;
463    uint32_t          comp_vs_const_offset;
464    uint32_t          comp_ps_const_offset;
465    uint32_t          comp_mask_ps_const_offset;
466    uint32_t          xv_vs_const_offset;
467    uint32_t          xv_ps_const_offset;
468
469    //size/addr stuff
470    struct r600_accel_object src_obj[2];
471    struct r600_accel_object dst_obj;
472    uint32_t          src_size[2];
473    uint32_t          dst_size;
474
475    uint32_t          vs_size;
476    uint64_t          vs_mc_addr;
477    uint32_t          ps_size;
478    uint64_t          ps_mc_addr;
479
480    // solid/copy
481    void *copy_area;
482    struct radeon_bo  *copy_area_bo;
483    Bool              same_surface;
484    int               rop;
485    uint32_t          planemask;
486    uint32_t          fg;
487
488    // composite
489    Bool              component_alpha;
490    Bool              src_alpha;
491    // vline
492    xf86CrtcPtr       vline_crtc;
493    int               vline_y1;
494    int               vline_y2;
495
496    Bool              force;
497};
498
499struct radeon_client_priv {
500    uint_fast32_t     needs_flush;
501};
502
503struct radeon_device_priv {
504    CursorPtr cursor;
505    Bool sprite_visible;
506};
507
508extern DevScreenPrivateKeyRec radeon_device_private_key;
509
510typedef struct {
511    EntityInfoPtr     pEnt;
512    pciVideoPtr       PciInfo;
513    int               Chipset;
514    RADEONChipFamily  ChipFamily;
515
516    Bool              (*CloseScreen)(ScreenPtr pScreen);
517
518    void              (*BlockHandler)(BLOCKHANDLER_ARGS_DECL);
519
520    void              (*CreateFence) (ScreenPtr pScreen, struct _SyncFence *pFence,
521				      Bool initially_triggered);
522
523    int               pix24bpp;         /* Depth of pixmap for 24bpp fb      */
524    Bool              dac6bits;         /* Use 6 bit DAC?                    */
525
526    int               pixel_bytes;
527
528    Bool              directRenderingEnabled;
529    struct radeon_dri2  dri2;
530
531    /* accel */
532    Bool              RenderAccel; /* Render */
533    Bool              allowColorTiling;
534    Bool              allowColorTiling2D;
535    int               callback_event_type;
536    uint_fast32_t     gpu_flushed;
537    uint_fast32_t     gpu_synced;
538    struct radeon_accel_state *accel_state;
539    PixmapPtr         fbcon_pixmap;
540    Bool              accelOn;
541    Bool              use_glamor;
542    Bool              shadow_primary;
543    int               tear_free;
544    Bool	      exa_pixmaps;
545    Bool              exa_force_create;
546    XF86ModReqInfo    exaReq;
547    Bool              is_fast_fb; /* use direct mapping for fast fb access */
548
549    unsigned int xv_max_width;
550    unsigned int xv_max_height;
551
552    /* general */
553    OptionInfoPtr     Options;
554
555    DisplayModePtr currentMode;
556
557    CreateScreenResourcesProcPtr CreateScreenResources;
558    CreateWindowProcPtr CreateWindow;
559    WindowExposuresProcPtr WindowExposures;
560    void (*SetCursor) (DeviceIntPtr pDev, ScreenPtr pScreen,
561		       CursorPtr pCursor, int x, int y);
562    void (*MoveCursor) (DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y);
563
564    /* Number of SW cursors currently visible on this screen */
565    int sprites_visible;
566
567    Bool              IsSecondary;
568
569    Bool              r600_shadow_fb;
570    void *fb_shadow;
571
572    void (*reemit_current2d)(ScrnInfoPtr pScrn, int op); // emit the current 2D state into the IB
573    struct radeon_2d_state state_2d;
574    struct radeon_bo *front_bo;
575    struct radeon_bo_manager *bufmgr;
576    struct radeon_cs_manager *csm;
577    struct radeon_cs *cs;
578
579    struct radeon_bo *cursor_bo[32];
580    uint64_t vram_size;
581    uint64_t gart_size;
582    drmmode_rec drmmode;
583    Bool drmmode_inited;
584    /* r6xx+ tile config */
585    Bool have_tiling_info;
586    uint32_t tile_config;
587    int group_bytes;
588    int num_channels;
589    int num_banks;
590    int r7xx_bank_op;
591    struct radeon_surface_manager *surf_man;
592    struct radeon_surface front_surface;
593
594    /* Xv bicubic filtering */
595    struct radeon_bo *bicubic_bo;
596
597    /* kms pageflipping */
598    Bool allowPageFlip;
599
600    /* Perform vsync'ed SwapBuffers? */
601    Bool swapBuffersWait;
602
603    /* cursor size */
604    int cursor_w;
605    int cursor_h;
606
607    /* If bit n of this field is set, xf86_config->crtc[n] currently can't
608     * use the HW cursor
609     */
610    unsigned hwcursor_disabled;
611
612#ifdef USE_GLAMOR
613    struct {
614	CreateGCProcPtr SavedCreateGC;
615	RegionPtr (*SavedCopyArea)(DrawablePtr, DrawablePtr, GCPtr, int, int,
616				   int, int, int, int);
617	void (*SavedPolyFillRect)(DrawablePtr, GCPtr, int, xRectangle*);
618	CloseScreenProcPtr SavedCloseScreen;
619	GetImageProcPtr SavedGetImage;
620	GetSpansProcPtr SavedGetSpans;
621	CreatePixmapProcPtr SavedCreatePixmap;
622	DestroyPixmapProcPtr SavedDestroyPixmap;
623	CopyWindowProcPtr SavedCopyWindow;
624	ChangeWindowAttributesProcPtr SavedChangeWindowAttributes;
625	BitmapToRegionProcPtr SavedBitmapToRegion;
626#ifdef RENDER
627	CompositeProcPtr SavedComposite;
628	TrianglesProcPtr SavedTriangles;
629	GlyphsProcPtr SavedGlyphs;
630	TrapezoidsProcPtr SavedTrapezoids;
631	AddTrapsProcPtr SavedAddTraps;
632	UnrealizeGlyphProcPtr SavedUnrealizeGlyph;
633#endif
634	SharePixmapBackingProcPtr SavedSharePixmapBacking;
635	SetSharedPixmapBackingProcPtr SavedSetSharedPixmapBacking;
636    } glamor;
637#endif /* USE_GLAMOR */
638
639    xf86CrtcFuncsRec drmmode_crtc_funcs;
640} RADEONInfoRec, *RADEONInfoPtr;
641
642/* radeon_accel.c */
643extern Bool RADEONAccelInit(ScreenPtr pScreen);
644extern void RADEONEngineInit(ScrnInfoPtr pScrn);
645extern void  RADEONCopySwap(uint8_t *dst, uint8_t *src, unsigned int size, int swap);
646extern void RADEONInit3DEngine(ScrnInfoPtr pScrn);
647extern int radeon_cs_space_remaining(ScrnInfoPtr pScrn);
648
649/* radeon_bo_helper.c */
650extern Bool radeon_get_pixmap_handle(PixmapPtr pixmap, uint32_t *handle);
651
652/* radeon_commonfuncs.c */
653extern void RADEONWaitForVLine(ScrnInfoPtr pScrn, PixmapPtr pPix,
654			       xf86CrtcPtr crtc, int start, int stop);
655
656
657/* radeon_exa.c */
658extern unsigned eg_tile_split(unsigned tile_split);
659extern Bool radeon_transform_is_affine_or_scaled(PictTransformPtr t);
660
661/* radeon_exa_funcs.c */
662extern Bool RADEONDrawInit(ScreenPtr pScreen);
663extern Bool R600DrawInit(ScreenPtr pScreen);
664extern Bool R600LoadShaders(ScrnInfoPtr pScrn);
665extern Bool EVERGREENDrawInit(ScreenPtr pScreen);
666
667/* radeon_exa.c */
668extern Bool RADEONGetDatatypeBpp(int bpp, uint32_t *type);
669extern Bool RADEONGetPixmapOffsetPitch(PixmapPtr pPix,
670				       uint32_t *pitch_offset);
671
672/* radeon_dri3.c */
673Bool radeon_dri3_screen_init(ScreenPtr screen);
674
675/* radeon_kms.c */
676Bool radeon_scanout_do_update(xf86CrtcPtr xf86_crtc, int scanout_id,
677			      PixmapPtr src_pix, BoxPtr extents);
678void RADEONWindowExposures_oneshot(WindowPtr pWin, RegionPtr pRegion
679#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1,16,99,901,0)
680				   , RegionPtr pBSRegion
681#endif
682				   );
683
684/* radeon_present.c */
685Bool radeon_present_screen_init(ScreenPtr screen);
686
687/* radeon_sync.c */
688extern Bool radeon_sync_init(ScreenPtr screen);
689extern void radeon_sync_close(ScreenPtr screen);
690
691/* radeon_video.c */
692extern void RADEONInitVideo(ScreenPtr pScreen);
693extern void RADEONResetVideo(ScrnInfoPtr pScrn);
694extern Bool radeon_load_bicubic_texture(ScrnInfoPtr pScrn);
695extern xf86CrtcPtr radeon_pick_best_crtc(ScrnInfoPtr pScrn,
696					 Bool consider_disabled,
697					 int x1, int x2, int y1, int y2);
698
699extern void radeon_cs_flush_indirect(ScrnInfoPtr pScrn);
700extern void radeon_ddx_cs_start(ScrnInfoPtr pScrn,
701				int num, const char *file,
702				const char *func, int line);
703void radeon_kms_update_vram_limit(ScrnInfoPtr pScrn, uint32_t new_fb_size);
704extern RADEONEntPtr RADEONEntPriv(ScrnInfoPtr pScrn);
705
706static inline struct radeon_surface *radeon_get_pixmap_surface(PixmapPtr pPix)
707{
708#ifdef USE_GLAMOR
709    RADEONInfoPtr info = RADEONPTR(xf86ScreenToScrn(pPix->drawable.pScreen));
710
711    if (info->use_glamor) {
712	struct radeon_pixmap *priv;
713	priv = radeon_get_pixmap_private(pPix);
714	return priv ? &priv->surface : NULL;
715    } else
716#endif
717    {
718	struct radeon_exa_pixmap_priv *driver_priv;
719	driver_priv = exaGetPixmapDriverPrivate(pPix);
720	return &driver_priv->surface;
721    }
722
723    return NULL;
724}
725
726uint32_t radeon_get_pixmap_tiling(PixmapPtr pPix);
727
728static inline Bool radeon_set_pixmap_bo(PixmapPtr pPix, struct radeon_bo *bo)
729{
730    ScrnInfoPtr scrn = xf86ScreenToScrn(pPix->drawable.pScreen);
731    RADEONEntPtr pRADEONEnt = RADEONEntPriv(scrn);
732#ifdef USE_GLAMOR
733    RADEONInfoPtr info = RADEONPTR(scrn);
734
735    if (info->use_glamor) {
736	struct radeon_pixmap *priv;
737
738	priv = radeon_get_pixmap_private(pPix);
739	if (priv == NULL && bo == NULL)
740	    return TRUE;
741
742	if (priv) {
743	    if (priv->bo) {
744		if (priv->bo == bo)
745		    return TRUE;
746
747		radeon_bo_unref(priv->bo);
748	    }
749
750	    drmmode_fb_reference(pRADEONEnt->fd, &priv->fb, NULL);
751
752	    if (!bo) {
753		free(priv);
754		priv = NULL;
755	    }
756	}
757
758	if (bo) {
759	    uint32_t pitch;
760
761	    if (!priv) {
762		priv = calloc(1, sizeof (struct radeon_pixmap));
763		if (!priv)
764		    return FALSE;
765	    }
766
767	    radeon_bo_ref(bo);
768	    priv->bo = bo;
769
770	    radeon_bo_get_tiling(bo, &priv->tiling_flags, &pitch);
771	}
772
773	radeon_set_pixmap_private(pPix, priv);
774	return TRUE;
775    } else
776#endif /* USE_GLAMOR */
777    {
778	struct radeon_exa_pixmap_priv *driver_priv;
779
780	driver_priv = exaGetPixmapDriverPrivate(pPix);
781	if (driver_priv) {
782	    uint32_t pitch;
783
784	    if (driver_priv->bo)
785		radeon_bo_unref(driver_priv->bo);
786
787	    drmmode_fb_reference(pRADEONEnt->fd, &driver_priv->fb, NULL);
788
789	    radeon_bo_ref(bo);
790	    driver_priv->bo = bo;
791
792	    radeon_bo_get_tiling(bo, &driver_priv->tiling_flags, &pitch);
793	    return TRUE;
794	}
795
796	return FALSE;
797    }
798}
799
800static inline struct radeon_bo *radeon_get_pixmap_bo(PixmapPtr pPix)
801{
802#ifdef USE_GLAMOR
803    RADEONInfoPtr info = RADEONPTR(xf86ScreenToScrn(pPix->drawable.pScreen));
804
805    if (info->use_glamor) {
806	struct radeon_pixmap *priv;
807	priv = radeon_get_pixmap_private(pPix);
808	return priv ? priv->bo : NULL;
809    } else
810#endif
811    {
812	struct radeon_exa_pixmap_priv *driver_priv;
813	driver_priv = exaGetPixmapDriverPrivate(pPix);
814	return driver_priv ? driver_priv->bo : NULL;
815    }
816
817    return NULL;
818}
819
820static inline Bool radeon_get_pixmap_shared(PixmapPtr pPix)
821{
822#ifdef USE_GLAMOR
823    RADEONInfoPtr info = RADEONPTR(xf86ScreenToScrn(pPix->drawable.pScreen));
824
825    if (info->use_glamor) {
826        ErrorF("glamor sharing todo\n");
827	return FALSE;
828    } else
829#endif
830    {
831	struct radeon_exa_pixmap_priv *driver_priv;
832	driver_priv = exaGetPixmapDriverPrivate(pPix);
833	return driver_priv->shared;
834    }
835    return FALSE;
836}
837
838static inline struct drmmode_fb*
839radeon_fb_create(ScrnInfoPtr scrn, int drm_fd, uint32_t width, uint32_t height,
840		 uint32_t pitch, uint32_t handle)
841{
842    struct drmmode_fb *fb  = malloc(sizeof(*fb));
843
844    if (!fb)
845	return NULL;
846
847    fb->refcnt = 1;
848    if (drmModeAddFB(drm_fd, width, height, scrn->depth, scrn->bitsPerPixel,
849		     pitch, handle, &fb->handle) == 0)
850	return fb;
851
852    free(fb);
853    return NULL;
854}
855
856static inline struct drmmode_fb**
857radeon_pixmap_get_fb_ptr(PixmapPtr pix)
858{
859    ScrnInfoPtr scrn = xf86ScreenToScrn(pix->drawable.pScreen);
860    RADEONInfoPtr info = RADEONPTR(scrn);
861
862#ifdef USE_GLAMOR
863    if (info->use_glamor) {
864	struct radeon_pixmap *priv = radeon_get_pixmap_private(pix);
865
866	if (!priv)
867	    return NULL;
868
869	return &priv->fb;
870    } else
871#endif
872    if (info->accelOn)
873    {
874	struct radeon_exa_pixmap_priv *driver_priv =
875	    exaGetPixmapDriverPrivate(pix);
876
877	if (!driver_priv)
878	    return NULL;
879
880	return &driver_priv->fb;
881    }
882
883    return NULL;
884}
885
886static inline struct drmmode_fb*
887radeon_pixmap_get_fb(PixmapPtr pix)
888{
889    struct drmmode_fb **fb_ptr = radeon_pixmap_get_fb_ptr(pix);
890
891    if (!fb_ptr)
892	return NULL;
893
894    if (!*fb_ptr) {
895	uint32_t handle;
896
897	if (radeon_get_pixmap_handle(pix, &handle)) {
898	    ScrnInfoPtr scrn = xf86ScreenToScrn(pix->drawable.pScreen);
899	    RADEONEntPtr pRADEONEnt = RADEONEntPriv(scrn);
900
901	    *fb_ptr = radeon_fb_create(scrn, pRADEONEnt->fd, pix->drawable.width,
902				       pix->drawable.height, pix->devKind,
903				       handle);
904	}
905    }
906
907    return *fb_ptr;
908}
909
910#define CP_PACKET0(reg, n)						\
911	(RADEON_CP_PACKET0 | ((n) << 16) | ((reg) >> 2))
912#define CP_PACKET1(reg0, reg1)						\
913	(RADEON_CP_PACKET1 | (((reg1) >> 2) << 11) | ((reg0) >> 2))
914#define CP_PACKET2()							\
915	(RADEON_CP_PACKET2)
916#define CP_PACKET3(pkt, n)						\
917	(RADEON_CP_PACKET3 | (pkt) | ((n) << 16))
918
919
920#define RADEON_VERBOSE	0
921
922#define BEGIN_RING(n) do {						\
923    if (RADEON_VERBOSE) {						\
924	xf86DrvMsg(pScrn->scrnIndex, X_INFO,				\
925		   "BEGIN_RING(%d) in %s\n", (unsigned int)n, __FUNCTION__);\
926    }									\
927    radeon_ddx_cs_start(pScrn, n, __FILE__, __func__, __LINE__);   \
928} while (0)
929
930#define ADVANCE_RING() do {						\
931    radeon_cs_end(info->cs, __FILE__, __func__, __LINE__); \
932  } while (0)
933
934#define OUT_RING(x) do {						\
935    if (RADEON_VERBOSE) {						\
936	xf86DrvMsg(pScrn->scrnIndex, X_INFO,				\
937		   "   OUT_RING(0x%08x)\n", (unsigned int)(x));		\
938    }									\
939    radeon_cs_write_dword(info->cs, (x));		\
940} while (0)
941
942#define OUT_RING_REG(reg, val)						\
943do {									\
944    OUT_RING(CP_PACKET0(reg, 0));					\
945    OUT_RING(val);							\
946} while (0)
947
948#define OUT_RING_RELOC(x, read_domains, write_domain)			\
949  do {									\
950	int _ret; \
951    _ret = radeon_cs_write_reloc(info->cs, x, read_domains, write_domain, 0); \
952	if (_ret) ErrorF("reloc emit failure %d\n", _ret); \
953  } while(0)
954
955
956#define FLUSH_RING()							\
957do {									\
958    if (RADEON_VERBOSE)							\
959	xf86DrvMsg(pScrn->scrnIndex, X_INFO,				\
960		   "FLUSH_RING in %s\n", __FUNCTION__);			\
961    radeon_cs_flush_indirect(pScrn); 				\
962} while (0)
963
964#define CS_FULL(cs) ((cs)->cdw > 15 * 1024)
965
966#define RADEON_SWITCH_TO_2D()						\
967do {									\
968	uint32_t flush = 0;                                             \
969	switch (info->accel_state->engineMode) {			\
970	case EXA_ENGINEMODE_UNKNOWN:					\
971	    flush = 1;                                                  \
972	    break;							\
973	case EXA_ENGINEMODE_3D:						\
974	    flush = CS_FULL(info->cs);			\
975	    break;							\
976	case EXA_ENGINEMODE_2D:						\
977	    flush = CS_FULL(info->cs);			\
978	    break;							\
979	}								\
980	if (flush) {							\
981	    radeon_cs_flush_indirect(pScrn);			\
982	}								\
983        info->accel_state->engineMode = EXA_ENGINEMODE_2D;              \
984} while (0);
985
986#define RADEON_SWITCH_TO_3D()						\
987do {									\
988	uint32_t flush = 0;						\
989	switch (info->accel_state->engineMode) {			\
990	case EXA_ENGINEMODE_UNKNOWN:					\
991	    flush = 1;                                                  \
992	    break;							\
993	case EXA_ENGINEMODE_2D:						\
994	    flush = CS_FULL(info->cs);	 		\
995	    break;							\
996	case EXA_ENGINEMODE_3D:						\
997	    flush = CS_FULL(info->cs);			\
998	    break;							\
999	}								\
1000	if (flush) {							\
1001	    radeon_cs_flush_indirect(pScrn);			\
1002	}                                                               \
1003	if (!info->accel_state->XInited3D)				\
1004	    RADEONInit3DEngine(pScrn);                                  \
1005        info->accel_state->engineMode = EXA_ENGINEMODE_3D;              \
1006} while (0);
1007
1008				/* Memory mapped register access macros */
1009
1010#define BEGIN_ACCEL_RELOC(n, r) do {		\
1011	int _nqw = (n) + (r);	\
1012	BEGIN_RING(2*_nqw);			\
1013    } while (0)
1014
1015#define EMIT_OFFSET(reg, value, pPix, rd, wd) do {		\
1016    driver_priv = exaGetPixmapDriverPrivate(pPix);		\
1017    OUT_RING_REG((reg), (value));				\
1018    OUT_RING_RELOC(driver_priv->bo, (rd), (wd));			\
1019    } while(0)
1020
1021#define EMIT_READ_OFFSET(reg, value, pPix) EMIT_OFFSET(reg, value, pPix, (RADEON_GEM_DOMAIN_VRAM | RADEON_GEM_DOMAIN_GTT), 0)
1022#define EMIT_WRITE_OFFSET(reg, value, pPix) EMIT_OFFSET(reg, value, pPix, 0, RADEON_GEM_DOMAIN_VRAM)
1023
1024#define OUT_TEXTURE_REG(reg, offset, bo) do {   \
1025    OUT_RING_REG((reg), (offset));                                   \
1026    OUT_RING_RELOC((bo), RADEON_GEM_DOMAIN_VRAM | RADEON_GEM_DOMAIN_GTT, 0); \
1027  } while(0)
1028
1029#define EMIT_COLORPITCH(reg, value, pPix) do {			\
1030    driver_priv = exaGetPixmapDriverPrivate(pPix);			\
1031    OUT_RING_REG((reg), value);					\
1032    OUT_RING_RELOC(driver_priv->bo, 0, RADEON_GEM_DOMAIN_VRAM);		\
1033} while(0)
1034
1035static __inline__ void RADEON_SYNC(RADEONInfoPtr info, ScrnInfoPtr pScrn)
1036{
1037    if (pScrn->pScreen)
1038	exaWaitSync(pScrn->pScreen);
1039}
1040
1041enum {
1042    RADEON_CREATE_PIXMAP_SCANOUT		= 0x02000000,
1043    RADEON_CREATE_PIXMAP_DRI2			= 0x04000000,
1044    RADEON_CREATE_PIXMAP_TILING_MICRO_SQUARE	= 0x08000000,
1045    RADEON_CREATE_PIXMAP_TILING_MACRO		= 0x10000000,
1046    RADEON_CREATE_PIXMAP_TILING_MICRO		= 0x20000000,
1047    RADEON_CREATE_PIXMAP_DEPTH			= 0x40000000, /* for r200 */
1048    RADEON_CREATE_PIXMAP_SZBUFFER		= 0x80000000, /* for eg */
1049};
1050
1051#define RADEON_CREATE_PIXMAP_TILING_FLAGS	\
1052    (RADEON_CREATE_PIXMAP_TILING_MICRO_SQUARE |	\
1053     RADEON_CREATE_PIXMAP_TILING_MACRO |	\
1054     RADEON_CREATE_PIXMAP_TILING_MICRO |	\
1055     RADEON_CREATE_PIXMAP_DEPTH |		\
1056     RADEON_CREATE_PIXMAP_SZBUFFER)
1057
1058
1059/* Compute log base 2 of val. */
1060static __inline__ int
1061RADEONLog2(int val)
1062{
1063	return 31 - __builtin_clz(val);
1064}
1065
1066#define RADEON_TILING_MASK				0xff
1067#define RADEON_TILING_LINEAR				0x0
1068
1069#endif /* _RADEON_H_ */
1070