radeon.h revision 18781e08
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
183#if XF86_CRTC_VERSION >= 5
184#define RADEON_PIXMAP_SHARING 1
185#endif
186
187#define RADEON_VSYNC_TIMEOUT	20000 /* Maximum wait for VSYNC (in usecs) */
188
189/* Buffer are aligned on 4096 byte boundaries */
190#define RADEON_GPU_PAGE_SIZE 4096
191#define RADEON_BUFFER_ALIGN (RADEON_GPU_PAGE_SIZE - 1)
192
193
194#define xFixedToFloat(f) (((float) (f)) / 65536)
195
196#define RADEON_LOGLEVEL_DEBUG 4
197
198/* for Xv, outputs */
199#define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE)
200
201/* Other macros */
202#define RADEON_ARRAY_SIZE(x)  (sizeof(x)/sizeof(x[0]))
203#define RADEON_ALIGN(x,bytes) (((x) + ((bytes) - 1)) & ~((bytes) - 1))
204#define RADEONPTR(pScrn)      ((RADEONInfoPtr)(pScrn)->driverPrivate)
205
206#define IS_RV100_VARIANT ((info->ChipFamily == CHIP_FAMILY_RV100)  ||  \
207        (info->ChipFamily == CHIP_FAMILY_RV200)  ||  \
208        (info->ChipFamily == CHIP_FAMILY_RS100)  ||  \
209        (info->ChipFamily == CHIP_FAMILY_RS200)  ||  \
210        (info->ChipFamily == CHIP_FAMILY_RV250)  ||  \
211        (info->ChipFamily == CHIP_FAMILY_RV280)  ||  \
212        (info->ChipFamily == CHIP_FAMILY_RS300))
213
214
215#define IS_R300_VARIANT ((info->ChipFamily == CHIP_FAMILY_R300)  ||  \
216        (info->ChipFamily == CHIP_FAMILY_RV350) ||  \
217        (info->ChipFamily == CHIP_FAMILY_R350)  ||  \
218        (info->ChipFamily == CHIP_FAMILY_RV380) ||  \
219        (info->ChipFamily == CHIP_FAMILY_R420)  ||  \
220        (info->ChipFamily == CHIP_FAMILY_RV410) ||  \
221        (info->ChipFamily == CHIP_FAMILY_RS400) ||  \
222        (info->ChipFamily == CHIP_FAMILY_RS480))
223
224#define IS_AVIVO_VARIANT ((info->ChipFamily >= CHIP_FAMILY_RV515))
225
226#define IS_DCE3_VARIANT ((info->ChipFamily >= CHIP_FAMILY_RV620))
227
228#define IS_DCE32_VARIANT ((info->ChipFamily >= CHIP_FAMILY_RV730))
229
230#define IS_DCE4_VARIANT ((info->ChipFamily >= CHIP_FAMILY_CEDAR))
231
232#define IS_DCE41_VARIANT ((info->ChipFamily >= CHIP_FAMILY_PALM))
233
234#define IS_DCE5_VARIANT ((info->ChipFamily >= CHIP_FAMILY_BARTS))
235
236#define IS_EVERGREEN_3D (info->ChipFamily >= CHIP_FAMILY_CEDAR)
237
238#define IS_R600_3D (info->ChipFamily >= CHIP_FAMILY_R600)
239
240#define IS_R500_3D ((info->ChipFamily == CHIP_FAMILY_RV515)  ||  \
241	(info->ChipFamily == CHIP_FAMILY_R520)   ||  \
242	(info->ChipFamily == CHIP_FAMILY_RV530)  ||  \
243	(info->ChipFamily == CHIP_FAMILY_R580)   ||  \
244	(info->ChipFamily == CHIP_FAMILY_RV560)  ||  \
245	(info->ChipFamily == CHIP_FAMILY_RV570))
246
247/* RS6xx, RS740 are technically R4xx as well, but the
248 * clipping hardware seems to follow the r3xx restrictions
249 */
250#define IS_R400_3D ((info->ChipFamily == CHIP_FAMILY_R420)  ||  \
251	(info->ChipFamily == CHIP_FAMILY_RV410))
252
253#define IS_R300_3D ((info->ChipFamily == CHIP_FAMILY_R300)  ||  \
254	(info->ChipFamily == CHIP_FAMILY_RV350) ||  \
255	(info->ChipFamily == CHIP_FAMILY_R350)  ||  \
256	(info->ChipFamily == CHIP_FAMILY_RV380) ||  \
257	(info->ChipFamily == CHIP_FAMILY_R420)  ||  \
258	(info->ChipFamily == CHIP_FAMILY_RV410) ||  \
259	(info->ChipFamily == CHIP_FAMILY_RS690) ||  \
260	(info->ChipFamily == CHIP_FAMILY_RS600) ||  \
261	(info->ChipFamily == CHIP_FAMILY_RS740) ||  \
262	(info->ChipFamily == CHIP_FAMILY_RS400) ||  \
263	(info->ChipFamily == CHIP_FAMILY_RS480))
264
265#define IS_R200_3D ((info->ChipFamily == CHIP_FAMILY_RV250) || \
266	(info->ChipFamily == CHIP_FAMILY_RV280) || \
267	(info->ChipFamily == CHIP_FAMILY_RS300) || \
268	(info->ChipFamily == CHIP_FAMILY_R200))
269
270#define CURSOR_WIDTH	64
271#define CURSOR_HEIGHT	64
272
273#define CURSOR_WIDTH_CIK	128
274#define CURSOR_HEIGHT_CIK	128
275
276
277#ifdef USE_GLAMOR
278
279struct radeon_pixmap {
280	struct radeon_surface surface;
281
282	uint_fast32_t gpu_read;
283	uint_fast32_t gpu_write;
284
285	struct radeon_bo *bo;
286
287	uint32_t tiling_flags;
288
289	/* GEM handle for glamor-only pixmaps shared via DRI3 */
290	Bool handle_valid;
291	uint32_t handle;
292};
293
294extern DevPrivateKeyRec glamor_pixmap_index;
295
296static inline struct radeon_pixmap *radeon_get_pixmap_private(PixmapPtr pixmap)
297{
298	return dixGetPrivate(&pixmap->devPrivates, &glamor_pixmap_index);
299}
300
301static inline void radeon_set_pixmap_private(PixmapPtr pixmap, struct radeon_pixmap *priv)
302{
303	dixSetPrivate(&pixmap->devPrivates, &glamor_pixmap_index, priv);
304}
305
306#endif /* USE_GLAMOR */
307
308
309struct radeon_exa_pixmap_priv {
310    struct radeon_bo *bo;
311    uint32_t tiling_flags;
312    struct radeon_surface surface;
313    Bool bo_mapped;
314    Bool shared;
315};
316
317#define RADEON_2D_EXA_COPY 1
318#define RADEON_2D_EXA_SOLID 2
319
320struct radeon_2d_state {
321    int op; //
322    uint32_t dst_pitch_offset;
323    uint32_t src_pitch_offset;
324    uint32_t dp_gui_master_cntl;
325    uint32_t dp_cntl;
326    uint32_t dp_write_mask;
327    uint32_t dp_brush_frgd_clr;
328    uint32_t dp_brush_bkgd_clr;
329    uint32_t dp_src_frgd_clr;
330    uint32_t dp_src_bkgd_clr;
331    uint32_t default_sc_bottom_right;
332    uint32_t dst_domain;
333    struct radeon_bo *dst_bo;
334    struct radeon_bo *src_bo;
335};
336
337#define DMA_BO_FREE_TIME 1000
338
339struct radeon_dma_bo {
340    struct radeon_dma_bo *next, *prev;
341    struct radeon_bo  *bo;
342    int expire_counter;
343};
344
345struct r600_accel_object {
346    uint32_t pitch;
347    uint32_t width;
348    uint32_t height;
349    int bpp;
350    uint32_t domain;
351    struct radeon_bo *bo;
352    uint32_t tiling_flags;
353    struct radeon_surface *surface;
354};
355
356struct radeon_vbo_object {
357    int               vb_offset;
358    int               vb_total;
359    uint32_t          vb_size;
360    uint32_t          vb_op_vert_size;
361    int32_t           vb_start_op;
362    struct radeon_bo *vb_bo;
363    unsigned          verts_per_op;
364};
365
366struct radeon_accel_state {
367
368				/* Saved values for ScreenToScreenCopy */
369    int               xdir;
370    int               ydir;
371
372    /* render accel */
373    unsigned short    texW[2];
374    unsigned short    texH[2];
375    Bool              XInited3D; /* X itself has the 3D context */
376    int               num_gb_pipes;
377    Bool              has_tcl;
378    Bool              allowHWDFS;
379
380    /* EXA */
381    ExaDriverPtr      exa;
382    int               exaSyncMarker;
383    int               exaMarkerSynced;
384    int               engineMode;
385#define EXA_ENGINEMODE_UNKNOWN 0
386#define EXA_ENGINEMODE_2D      1
387#define EXA_ENGINEMODE_3D      2
388
389    int               composite_op;
390    PicturePtr        dst_pic;
391    PicturePtr        msk_pic;
392    PicturePtr        src_pic;
393    PixmapPtr         dst_pix;
394    PixmapPtr         msk_pix;
395    PixmapPtr         src_pix;
396    Bool              is_transform[2];
397    PictTransform     *transform[2];
398    /* Whether we are tiling horizontally and vertically */
399    Bool              need_src_tile_x;
400    Bool              need_src_tile_y;
401    /* Size of tiles ... set to 65536x65536 if not tiling in that direction */
402    Bool              src_tile_width;
403    Bool              src_tile_height;
404    uint32_t          *draw_header;
405    unsigned          vtx_count;
406    unsigned          num_vtx;
407    Bool              vsync;
408
409    struct radeon_vbo_object vbo;
410    struct radeon_vbo_object cbuf;
411
412    /* where to discard IB from if we cancel operation */
413    uint32_t          ib_reset_op;
414    struct radeon_dma_bo bo_free;
415    struct radeon_dma_bo bo_wait;
416    struct radeon_dma_bo bo_reserved;
417    Bool use_vbos;
418    void (*finish_op)(ScrnInfoPtr, int);
419    // shader storage
420    struct radeon_bo  *shaders_bo;
421    uint32_t          solid_vs_offset;
422    uint32_t          solid_ps_offset;
423    uint32_t          copy_vs_offset;
424    uint32_t          copy_ps_offset;
425    uint32_t          comp_vs_offset;
426    uint32_t          comp_ps_offset;
427    uint32_t          xv_vs_offset;
428    uint32_t          xv_ps_offset;
429    // shader consts
430    uint32_t          solid_vs_const_offset;
431    uint32_t          solid_ps_const_offset;
432    uint32_t          copy_vs_const_offset;
433    uint32_t          copy_ps_const_offset;
434    uint32_t          comp_vs_const_offset;
435    uint32_t          comp_ps_const_offset;
436    uint32_t          comp_mask_ps_const_offset;
437    uint32_t          xv_vs_const_offset;
438    uint32_t          xv_ps_const_offset;
439
440    //size/addr stuff
441    struct r600_accel_object src_obj[2];
442    struct r600_accel_object dst_obj;
443    uint32_t          src_size[2];
444    uint32_t          dst_size;
445
446    uint32_t          vs_size;
447    uint64_t          vs_mc_addr;
448    uint32_t          ps_size;
449    uint64_t          ps_mc_addr;
450
451    // solid/copy
452    void *copy_area;
453    struct radeon_bo  *copy_area_bo;
454    Bool              same_surface;
455    int               rop;
456    uint32_t          planemask;
457    uint32_t          fg;
458
459    // composite
460    Bool              component_alpha;
461    Bool              src_alpha;
462    // vline
463    xf86CrtcPtr       vline_crtc;
464    int               vline_y1;
465    int               vline_y2;
466
467    Bool              force;
468};
469
470struct radeon_client_priv {
471    uint_fast32_t     needs_flush;
472};
473
474typedef struct {
475    EntityInfoPtr     pEnt;
476    pciVideoPtr       PciInfo;
477    int               Chipset;
478    RADEONChipFamily  ChipFamily;
479
480    Bool              (*CloseScreen)(CLOSE_SCREEN_ARGS_DECL);
481
482    void              (*BlockHandler)(BLOCKHANDLER_ARGS_DECL);
483
484    void              (*CreateFence) (ScreenPtr pScreen, struct _SyncFence *pFence,
485				      Bool initially_triggered);
486
487    int               pix24bpp;         /* Depth of pixmap for 24bpp fb      */
488    Bool              dac6bits;         /* Use 6 bit DAC?                    */
489
490    int               pixel_bytes;
491
492    Bool              directRenderingEnabled;
493    struct radeon_dri2  dri2;
494
495    /* accel */
496    Bool              RenderAccel; /* Render */
497    Bool              allowColorTiling;
498    Bool              allowColorTiling2D;
499    int               callback_event_type;
500    uint_fast32_t     gpu_flushed;
501    uint_fast32_t     gpu_synced;
502    struct radeon_accel_state *accel_state;
503    PixmapPtr         fbcon_pixmap;
504    Bool              accelOn;
505    Bool              use_glamor;
506    Bool              shadow_primary;
507    Bool              tear_free;
508    Bool	      exa_pixmaps;
509    Bool              exa_force_create;
510    XF86ModReqInfo    exaReq;
511    Bool              is_fast_fb; /* use direct mapping for fast fb access */
512
513    unsigned int xv_max_width;
514    unsigned int xv_max_height;
515
516    /* general */
517    OptionInfoPtr     Options;
518
519    DisplayModePtr currentMode;
520
521    CreateScreenResourcesProcPtr CreateScreenResources;
522    CreateWindowProcPtr CreateWindow;
523
524    Bool              IsSecondary;
525
526    Bool              r600_shadow_fb;
527    void *fb_shadow;
528
529    void (*reemit_current2d)(ScrnInfoPtr pScrn, int op); // emit the current 2D state into the IB
530    struct radeon_2d_state state_2d;
531    struct radeon_bo *front_bo;
532    struct radeon_bo_manager *bufmgr;
533    struct radeon_cs_manager *csm;
534    struct radeon_cs *cs;
535
536    struct radeon_bo *cursor_bo[32];
537    uint64_t vram_size;
538    uint64_t gart_size;
539    drmmode_rec drmmode;
540    Bool drmmode_inited;
541    /* r6xx+ tile config */
542    Bool have_tiling_info;
543    uint32_t tile_config;
544    int group_bytes;
545    int num_channels;
546    int num_banks;
547    int r7xx_bank_op;
548    struct radeon_surface_manager *surf_man;
549    struct radeon_surface front_surface;
550
551    /* Xv bicubic filtering */
552    struct radeon_bo *bicubic_bo;
553
554    /* kms pageflipping */
555    Bool allowPageFlip;
556
557    /* Perform vsync'ed SwapBuffers? */
558    Bool swapBuffersWait;
559
560    /* cursor size */
561    int cursor_w;
562    int cursor_h;
563
564    /* If bit n of this field is set, xf86_config->crtc[n] currently can't
565     * use the HW cursor
566     */
567    unsigned hwcursor_disabled;
568
569#ifdef USE_GLAMOR
570    struct {
571	CreateGCProcPtr SavedCreateGC;
572	RegionPtr (*SavedCopyArea)(DrawablePtr, DrawablePtr, GCPtr, int, int,
573				   int, int, int, int);
574	void (*SavedPolyFillRect)(DrawablePtr, GCPtr, int, xRectangle*);
575	CloseScreenProcPtr SavedCloseScreen;
576	GetImageProcPtr SavedGetImage;
577	GetSpansProcPtr SavedGetSpans;
578	CreatePixmapProcPtr SavedCreatePixmap;
579	DestroyPixmapProcPtr SavedDestroyPixmap;
580	CopyWindowProcPtr SavedCopyWindow;
581	ChangeWindowAttributesProcPtr SavedChangeWindowAttributes;
582	BitmapToRegionProcPtr SavedBitmapToRegion;
583#ifdef RENDER
584	CompositeProcPtr SavedComposite;
585	TrianglesProcPtr SavedTriangles;
586	GlyphsProcPtr SavedGlyphs;
587	TrapezoidsProcPtr SavedTrapezoids;
588	AddTrapsProcPtr SavedAddTraps;
589	UnrealizeGlyphProcPtr SavedUnrealizeGlyph;
590#endif
591#ifdef RADEON_PIXMAP_SHARING
592	SharePixmapBackingProcPtr SavedSharePixmapBacking;
593	SetSharedPixmapBackingProcPtr SavedSetSharedPixmapBacking;
594#endif
595    } glamor;
596#endif /* USE_GLAMOR */
597} RADEONInfoRec, *RADEONInfoPtr;
598
599/* radeon_accel.c */
600extern Bool RADEONAccelInit(ScreenPtr pScreen);
601extern void RADEONEngineInit(ScrnInfoPtr pScrn);
602extern void  RADEONCopySwap(uint8_t *dst, uint8_t *src, unsigned int size, int swap);
603extern void RADEONInit3DEngine(ScrnInfoPtr pScrn);
604extern int radeon_cs_space_remaining(ScrnInfoPtr pScrn);
605
606/* radeon_commonfuncs.c */
607extern void RADEONWaitForVLine(ScrnInfoPtr pScrn, PixmapPtr pPix,
608			       xf86CrtcPtr crtc, int start, int stop);
609
610
611/* radeon_exa.c */
612extern unsigned eg_tile_split(unsigned tile_split);
613extern Bool radeon_transform_is_affine_or_scaled(PictTransformPtr t);
614
615/* radeon_exa_funcs.c */
616extern Bool RADEONDrawInit(ScreenPtr pScreen);
617extern Bool R600DrawInit(ScreenPtr pScreen);
618extern Bool R600LoadShaders(ScrnInfoPtr pScrn);
619extern Bool EVERGREENDrawInit(ScreenPtr pScreen);
620
621/* radeon_exa.c */
622extern Bool RADEONGetDatatypeBpp(int bpp, uint32_t *type);
623extern Bool RADEONGetPixmapOffsetPitch(PixmapPtr pPix,
624				       uint32_t *pitch_offset);
625
626/* radeon_dri3.c */
627Bool radeon_dri3_screen_init(ScreenPtr screen);
628
629/* radeon_kms.c */
630void radeon_scanout_update_handler(xf86CrtcPtr crtc, uint32_t frame,
631				   uint64_t usec, void *event_data);
632
633/* radeon_present.c */
634Bool radeon_present_screen_init(ScreenPtr screen);
635
636/* radeon_sync.c */
637extern Bool radeon_sync_init(ScreenPtr screen);
638extern void radeon_sync_close(ScreenPtr screen);
639
640/* radeon_video.c */
641extern void RADEONInitVideo(ScreenPtr pScreen);
642extern void RADEONResetVideo(ScrnInfoPtr pScrn);
643extern Bool radeon_load_bicubic_texture(ScrnInfoPtr pScrn);
644extern xf86CrtcPtr radeon_pick_best_crtc(ScrnInfoPtr pScrn,
645					 Bool consider_disabled,
646					 int x1, int x2, int y1, int y2);
647
648extern void radeon_cs_flush_indirect(ScrnInfoPtr pScrn);
649extern void radeon_ddx_cs_start(ScrnInfoPtr pScrn,
650				int num, const char *file,
651				const char *func, int line);
652void radeon_kms_update_vram_limit(ScrnInfoPtr pScrn, uint32_t new_fb_size);
653extern RADEONEntPtr RADEONEntPriv(ScrnInfoPtr pScrn);
654
655drmVBlankSeqType radeon_populate_vbl_request_type(xf86CrtcPtr crtc);
656
657static inline struct radeon_surface *radeon_get_pixmap_surface(PixmapPtr pPix)
658{
659#ifdef USE_GLAMOR
660    RADEONInfoPtr info = RADEONPTR(xf86ScreenToScrn(pPix->drawable.pScreen));
661
662    if (info->use_glamor) {
663	struct radeon_pixmap *priv;
664	priv = radeon_get_pixmap_private(pPix);
665	return priv ? &priv->surface : NULL;
666    } else
667#endif
668    {
669	struct radeon_exa_pixmap_priv *driver_priv;
670	driver_priv = exaGetPixmapDriverPrivate(pPix);
671	return &driver_priv->surface;
672    }
673
674    return NULL;
675}
676
677uint32_t radeon_get_pixmap_tiling(PixmapPtr pPix);
678
679static inline Bool radeon_set_pixmap_bo(PixmapPtr pPix, struct radeon_bo *bo)
680{
681#ifdef USE_GLAMOR
682    RADEONInfoPtr info = RADEONPTR(xf86ScreenToScrn(pPix->drawable.pScreen));
683
684    if (info->use_glamor) {
685	struct radeon_pixmap *priv;
686
687	priv = radeon_get_pixmap_private(pPix);
688	if (priv == NULL && bo == NULL)
689	    return TRUE;
690
691	if (priv) {
692	    if (priv->bo) {
693		if (priv->bo == bo)
694		    return TRUE;
695
696		radeon_bo_unref(priv->bo);
697	    }
698
699	    if (!bo) {
700		free(priv);
701		priv = NULL;
702	    }
703	}
704
705	if (bo) {
706	    uint32_t pitch;
707
708	    if (!priv) {
709		priv = calloc(1, sizeof (struct radeon_pixmap));
710		if (!priv)
711		    return FALSE;
712	    }
713
714	    radeon_bo_ref(bo);
715	    priv->bo = bo;
716
717	    radeon_bo_get_tiling(bo, &priv->tiling_flags, &pitch);
718	}
719
720	radeon_set_pixmap_private(pPix, priv);
721	return TRUE;
722    } else
723#endif /* USE_GLAMOR */
724    {
725	struct radeon_exa_pixmap_priv *driver_priv;
726
727	driver_priv = exaGetPixmapDriverPrivate(pPix);
728	if (driver_priv) {
729	    uint32_t pitch;
730
731	    if (driver_priv->bo)
732		radeon_bo_unref(driver_priv->bo);
733
734	    radeon_bo_ref(bo);
735	    driver_priv->bo = bo;
736
737	    radeon_bo_get_tiling(bo, &driver_priv->tiling_flags, &pitch);
738	    return TRUE;
739	}
740
741	return FALSE;
742    }
743}
744
745static inline struct radeon_bo *radeon_get_pixmap_bo(PixmapPtr pPix)
746{
747#ifdef USE_GLAMOR
748    RADEONInfoPtr info = RADEONPTR(xf86ScreenToScrn(pPix->drawable.pScreen));
749
750    if (info->use_glamor) {
751	struct radeon_pixmap *priv;
752	priv = radeon_get_pixmap_private(pPix);
753	return priv ? priv->bo : NULL;
754    } else
755#endif
756    {
757	struct radeon_exa_pixmap_priv *driver_priv;
758	driver_priv = exaGetPixmapDriverPrivate(pPix);
759	return driver_priv ? driver_priv->bo : NULL;
760    }
761
762    return NULL;
763}
764
765static inline Bool radeon_get_pixmap_shared(PixmapPtr pPix)
766{
767#ifdef USE_GLAMOR
768    RADEONInfoPtr info = RADEONPTR(xf86ScreenToScrn(pPix->drawable.pScreen));
769
770    if (info->use_glamor) {
771        ErrorF("glamor sharing todo\n");
772	return FALSE;
773    } else
774#endif
775    {
776	struct radeon_exa_pixmap_priv *driver_priv;
777	driver_priv = exaGetPixmapDriverPrivate(pPix);
778	return driver_priv->shared;
779    }
780    return FALSE;
781}
782
783#define CP_PACKET0(reg, n)						\
784	(RADEON_CP_PACKET0 | ((n) << 16) | ((reg) >> 2))
785#define CP_PACKET1(reg0, reg1)						\
786	(RADEON_CP_PACKET1 | (((reg1) >> 2) << 11) | ((reg0) >> 2))
787#define CP_PACKET2()							\
788	(RADEON_CP_PACKET2)
789#define CP_PACKET3(pkt, n)						\
790	(RADEON_CP_PACKET3 | (pkt) | ((n) << 16))
791
792
793#define RADEON_VERBOSE	0
794
795#define BEGIN_RING(n) do {						\
796    if (RADEON_VERBOSE) {						\
797	xf86DrvMsg(pScrn->scrnIndex, X_INFO,				\
798		   "BEGIN_RING(%d) in %s\n", (unsigned int)n, __FUNCTION__);\
799    }									\
800    radeon_ddx_cs_start(pScrn, n, __FILE__, __func__, __LINE__);   \
801} while (0)
802
803#define ADVANCE_RING() do {						\
804    radeon_cs_end(info->cs, __FILE__, __func__, __LINE__); \
805  } while (0)
806
807#define OUT_RING(x) do {						\
808    if (RADEON_VERBOSE) {						\
809	xf86DrvMsg(pScrn->scrnIndex, X_INFO,				\
810		   "   OUT_RING(0x%08x)\n", (unsigned int)(x));		\
811    }									\
812    radeon_cs_write_dword(info->cs, (x));		\
813} while (0)
814
815#define OUT_RING_REG(reg, val)						\
816do {									\
817    OUT_RING(CP_PACKET0(reg, 0));					\
818    OUT_RING(val);							\
819} while (0)
820
821#define OUT_RING_RELOC(x, read_domains, write_domain)			\
822  do {									\
823	int _ret; \
824    _ret = radeon_cs_write_reloc(info->cs, x, read_domains, write_domain, 0); \
825	if (_ret) ErrorF("reloc emit failure %d\n", _ret); \
826  } while(0)
827
828
829#define FLUSH_RING()							\
830do {									\
831    if (RADEON_VERBOSE)							\
832	xf86DrvMsg(pScrn->scrnIndex, X_INFO,				\
833		   "FLUSH_RING in %s\n", __FUNCTION__);			\
834    radeon_cs_flush_indirect(pScrn); 				\
835} while (0)
836
837#define CS_FULL(cs) ((cs)->cdw > 15 * 1024)
838
839#define RADEON_SWITCH_TO_2D()						\
840do {									\
841	uint32_t flush = 0;                                             \
842	switch (info->accel_state->engineMode) {			\
843	case EXA_ENGINEMODE_UNKNOWN:					\
844	    flush = 1;                                                  \
845	    break;							\
846	case EXA_ENGINEMODE_3D:						\
847	    flush = CS_FULL(info->cs);			\
848	    break;							\
849	case EXA_ENGINEMODE_2D:						\
850	    flush = CS_FULL(info->cs);			\
851	    break;							\
852	}								\
853	if (flush) {							\
854	    radeon_cs_flush_indirect(pScrn);			\
855	}								\
856        info->accel_state->engineMode = EXA_ENGINEMODE_2D;              \
857} while (0);
858
859#define RADEON_SWITCH_TO_3D()						\
860do {									\
861	uint32_t flush = 0;						\
862	switch (info->accel_state->engineMode) {			\
863	case EXA_ENGINEMODE_UNKNOWN:					\
864	    flush = 1;                                                  \
865	    break;							\
866	case EXA_ENGINEMODE_2D:						\
867	    flush = CS_FULL(info->cs);	 		\
868	    break;							\
869	case EXA_ENGINEMODE_3D:						\
870	    flush = CS_FULL(info->cs);			\
871	    break;							\
872	}								\
873	if (flush) {							\
874	    radeon_cs_flush_indirect(pScrn);			\
875	}                                                               \
876	if (!info->accel_state->XInited3D)				\
877	    RADEONInit3DEngine(pScrn);                                  \
878        info->accel_state->engineMode = EXA_ENGINEMODE_3D;              \
879} while (0);
880
881				/* Memory mapped register access macros */
882
883#define BEGIN_ACCEL_RELOC(n, r) do {		\
884	int _nqw = (n) + (r);	\
885	BEGIN_RING(2*_nqw);			\
886    } while (0)
887
888#define EMIT_OFFSET(reg, value, pPix, rd, wd) do {		\
889    driver_priv = exaGetPixmapDriverPrivate(pPix);		\
890    OUT_RING_REG((reg), (value));				\
891    OUT_RING_RELOC(driver_priv->bo, (rd), (wd));			\
892    } while(0)
893
894#define EMIT_READ_OFFSET(reg, value, pPix) EMIT_OFFSET(reg, value, pPix, (RADEON_GEM_DOMAIN_VRAM | RADEON_GEM_DOMAIN_GTT), 0)
895#define EMIT_WRITE_OFFSET(reg, value, pPix) EMIT_OFFSET(reg, value, pPix, 0, RADEON_GEM_DOMAIN_VRAM)
896
897#define OUT_TEXTURE_REG(reg, offset, bo) do {   \
898    OUT_RING_REG((reg), (offset));                                   \
899    OUT_RING_RELOC((bo), RADEON_GEM_DOMAIN_VRAM | RADEON_GEM_DOMAIN_GTT, 0); \
900  } while(0)
901
902#define EMIT_COLORPITCH(reg, value, pPix) do {			\
903    driver_priv = exaGetPixmapDriverPrivate(pPix);			\
904    OUT_RING_REG((reg), value);					\
905    OUT_RING_RELOC(driver_priv->bo, 0, RADEON_GEM_DOMAIN_VRAM);		\
906} while(0)
907
908static __inline__ void RADEON_SYNC(RADEONInfoPtr info, ScrnInfoPtr pScrn)
909{
910    if (pScrn->pScreen)
911	exaWaitSync(pScrn->pScreen);
912}
913
914enum {
915    RADEON_CREATE_PIXMAP_SCANOUT		= 0x02000000,
916    RADEON_CREATE_PIXMAP_DRI2			= 0x04000000,
917    RADEON_CREATE_PIXMAP_TILING_MICRO_SQUARE	= 0x08000000,
918    RADEON_CREATE_PIXMAP_TILING_MACRO		= 0x10000000,
919    RADEON_CREATE_PIXMAP_TILING_MICRO		= 0x20000000,
920    RADEON_CREATE_PIXMAP_DEPTH			= 0x40000000, /* for r200 */
921    RADEON_CREATE_PIXMAP_SZBUFFER		= 0x80000000, /* for eg */
922};
923
924#define RADEON_CREATE_PIXMAP_TILING_FLAGS	\
925    (RADEON_CREATE_PIXMAP_TILING_MICRO_SQUARE |	\
926     RADEON_CREATE_PIXMAP_TILING_MACRO |	\
927     RADEON_CREATE_PIXMAP_TILING_MICRO |	\
928     RADEON_CREATE_PIXMAP_DEPTH |		\
929     RADEON_CREATE_PIXMAP_SZBUFFER)
930
931
932/* Compute log base 2 of val. */
933static __inline__ int
934RADEONLog2(int val)
935{
936	int bits;
937#if (defined __i386__ || defined __x86_64__) && (defined __GNUC__)
938	__asm volatile("bsrl	%1, %0"
939		: "=r" (bits)
940		: "c" (val)
941	);
942	return bits;
943#else
944	for (bits = 0; val != 0; val >>= 1, ++bits)
945		;
946	return bits - 1;
947#endif
948}
949
950#define RADEON_TILING_MASK				0xff
951#define RADEON_TILING_LINEAR				0x0
952
953#endif /* _RADEON_H_ */
954