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