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