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