radeon.h revision de2362d3
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#include "radeon_glamor.h" 55 56 /* Exa and Cursor Support */ 57#include "xf86Cursor.h" 58 59 /* DDC support */ 60#include "xf86DDC.h" 61 62 /* Xv support */ 63#include "xf86xv.h" 64 65#include "radeon_probe.h" 66 67 /* DRI support */ 68#include "xf86drm.h" 69#include "radeon_drm.h" 70 71#ifdef DAMAGE 72#include "damage.h" 73#include "globals.h" 74#endif 75 76#include "xf86Crtc.h" 77#include "X11/Xatom.h" 78 79#include "radeon_bo.h" 80#include "radeon_cs.h" 81#include "radeon_dri2.h" 82#include "drmmode_display.h" 83#include "radeon_surface.h" 84 85 /* Render support */ 86#ifdef RENDER 87#include "picturestr.h" 88#endif 89 90#include "compat-api.h" 91 92#include "simple_list.h" 93#include "atipcirename.h" 94 95#ifndef MAX 96#define MAX(a,b) ((a)>(b)?(a):(b)) 97#endif 98#ifndef MIN 99#define MIN(a,b) ((a)>(b)?(b):(a)) 100#endif 101 102#if HAVE_BYTESWAP_H 103#include <byteswap.h> 104#elif defined(USE_SYS_ENDIAN_H) 105#include <sys/endian.h> 106#else 107#define bswap_16(value) \ 108 ((((value) & 0xff) << 8) | ((value) >> 8)) 109 110#define bswap_32(value) \ 111 (((uint32_t)bswap_16((uint16_t)((value) & 0xffff)) << 16) | \ 112 (uint32_t)bswap_16((uint16_t)((value) >> 16))) 113 114#define bswap_64(value) \ 115 (((uint64_t)bswap_32((uint32_t)((value) & 0xffffffff)) \ 116 << 32) | \ 117 (uint64_t)bswap_32((uint32_t)((value) >> 32))) 118#endif 119 120#if X_BYTE_ORDER == X_BIG_ENDIAN 121#define le32_to_cpu(x) bswap_32(x) 122#define le16_to_cpu(x) bswap_16(x) 123#define cpu_to_le32(x) bswap_32(x) 124#define cpu_to_le16(x) bswap_16(x) 125#else 126#define le32_to_cpu(x) (x) 127#define le16_to_cpu(x) (x) 128#define cpu_to_le32(x) (x) 129#define cpu_to_le16(x) (x) 130#endif 131 132/* Provide substitutes for gcc's __FUNCTION__ on other compilers */ 133#if !defined(__GNUC__) && !defined(__FUNCTION__) 134# define __FUNCTION__ __func__ /* C99 */ 135#endif 136 137typedef enum { 138 OPTION_ACCEL, 139 OPTION_SW_CURSOR, 140 OPTION_PAGE_FLIP, 141 OPTION_EXA_PIXMAPS, 142 OPTION_COLOR_TILING, 143 OPTION_COLOR_TILING_2D, 144#ifdef RENDER 145 OPTION_RENDER_ACCEL, 146 OPTION_SUBPIXEL_ORDER, 147#endif 148 OPTION_ACCELMETHOD, 149 OPTION_EXA_VSYNC, 150 OPTION_ZAPHOD_HEADS, 151 OPTION_SWAPBUFFERS_WAIT 152} RADEONOpts; 153 154 155#define RADEON_VSYNC_TIMEOUT 20000 /* Maximum wait for VSYNC (in usecs) */ 156 157/* Buffer are aligned on 4096 byte boundaries */ 158#define RADEON_GPU_PAGE_SIZE 4096 159#define RADEON_BUFFER_ALIGN (RADEON_GPU_PAGE_SIZE - 1) 160 161 162#define xFixedToFloat(f) (((float) (f)) / 65536) 163 164#define RADEON_LOGLEVEL_DEBUG 4 165 166/* for Xv, outputs */ 167#define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE) 168 169/* Other macros */ 170#define RADEON_ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0])) 171#define RADEON_ALIGN(x,bytes) (((x) + ((bytes) - 1)) & ~((bytes) - 1)) 172#define RADEONPTR(pScrn) ((RADEONInfoPtr)(pScrn)->driverPrivate) 173 174#define IS_RV100_VARIANT ((info->ChipFamily == CHIP_FAMILY_RV100) || \ 175 (info->ChipFamily == CHIP_FAMILY_RV200) || \ 176 (info->ChipFamily == CHIP_FAMILY_RS100) || \ 177 (info->ChipFamily == CHIP_FAMILY_RS200) || \ 178 (info->ChipFamily == CHIP_FAMILY_RV250) || \ 179 (info->ChipFamily == CHIP_FAMILY_RV280) || \ 180 (info->ChipFamily == CHIP_FAMILY_RS300)) 181 182 183#define IS_R300_VARIANT ((info->ChipFamily == CHIP_FAMILY_R300) || \ 184 (info->ChipFamily == CHIP_FAMILY_RV350) || \ 185 (info->ChipFamily == CHIP_FAMILY_R350) || \ 186 (info->ChipFamily == CHIP_FAMILY_RV380) || \ 187 (info->ChipFamily == CHIP_FAMILY_R420) || \ 188 (info->ChipFamily == CHIP_FAMILY_RV410) || \ 189 (info->ChipFamily == CHIP_FAMILY_RS400) || \ 190 (info->ChipFamily == CHIP_FAMILY_RS480)) 191 192#define IS_AVIVO_VARIANT ((info->ChipFamily >= CHIP_FAMILY_RV515)) 193 194#define IS_DCE3_VARIANT ((info->ChipFamily >= CHIP_FAMILY_RV620)) 195 196#define IS_DCE32_VARIANT ((info->ChipFamily >= CHIP_FAMILY_RV730)) 197 198#define IS_DCE4_VARIANT ((info->ChipFamily >= CHIP_FAMILY_CEDAR)) 199 200#define IS_DCE41_VARIANT ((info->ChipFamily >= CHIP_FAMILY_PALM)) 201 202#define IS_DCE5_VARIANT ((info->ChipFamily >= CHIP_FAMILY_BARTS)) 203 204#define IS_EVERGREEN_3D (info->ChipFamily >= CHIP_FAMILY_CEDAR) 205 206#define IS_R600_3D (info->ChipFamily >= CHIP_FAMILY_R600) 207 208#define IS_R500_3D ((info->ChipFamily == CHIP_FAMILY_RV515) || \ 209 (info->ChipFamily == CHIP_FAMILY_R520) || \ 210 (info->ChipFamily == CHIP_FAMILY_RV530) || \ 211 (info->ChipFamily == CHIP_FAMILY_R580) || \ 212 (info->ChipFamily == CHIP_FAMILY_RV560) || \ 213 (info->ChipFamily == CHIP_FAMILY_RV570)) 214 215/* RS6xx, RS740 are technically R4xx as well, but the 216 * clipping hardware seems to follow the r3xx restrictions 217 */ 218#define IS_R400_3D ((info->ChipFamily == CHIP_FAMILY_R420) || \ 219 (info->ChipFamily == CHIP_FAMILY_RV410)) 220 221#define IS_R300_3D ((info->ChipFamily == CHIP_FAMILY_R300) || \ 222 (info->ChipFamily == CHIP_FAMILY_RV350) || \ 223 (info->ChipFamily == CHIP_FAMILY_R350) || \ 224 (info->ChipFamily == CHIP_FAMILY_RV380) || \ 225 (info->ChipFamily == CHIP_FAMILY_R420) || \ 226 (info->ChipFamily == CHIP_FAMILY_RV410) || \ 227 (info->ChipFamily == CHIP_FAMILY_RS690) || \ 228 (info->ChipFamily == CHIP_FAMILY_RS600) || \ 229 (info->ChipFamily == CHIP_FAMILY_RS740) || \ 230 (info->ChipFamily == CHIP_FAMILY_RS400) || \ 231 (info->ChipFamily == CHIP_FAMILY_RS480)) 232 233#define IS_R200_3D ((info->ChipFamily == CHIP_FAMILY_RV250) || \ 234 (info->ChipFamily == CHIP_FAMILY_RV280) || \ 235 (info->ChipFamily == CHIP_FAMILY_RS300) || \ 236 (info->ChipFamily == CHIP_FAMILY_R200)) 237 238#define CURSOR_WIDTH 64 239#define CURSOR_HEIGHT 64 240 241#define CURSOR_WIDTH_CIK 128 242#define CURSOR_HEIGHT_CIK 128 243 244struct radeon_exa_pixmap_priv { 245 struct radeon_bo *bo; 246 uint32_t tiling_flags; 247 struct radeon_surface surface; 248 Bool bo_mapped; 249 Bool shared; 250}; 251 252#define RADEON_2D_EXA_COPY 1 253#define RADEON_2D_EXA_SOLID 2 254 255struct radeon_2d_state { 256 int op; // 257 uint32_t dst_pitch_offset; 258 uint32_t src_pitch_offset; 259 uint32_t dp_gui_master_cntl; 260 uint32_t dp_cntl; 261 uint32_t dp_write_mask; 262 uint32_t dp_brush_frgd_clr; 263 uint32_t dp_brush_bkgd_clr; 264 uint32_t dp_src_frgd_clr; 265 uint32_t dp_src_bkgd_clr; 266 uint32_t default_sc_bottom_right; 267 uint32_t dst_domain; 268 struct radeon_bo *dst_bo; 269 struct radeon_bo *src_bo; 270}; 271 272#define DMA_BO_FREE_TIME 1000 273 274struct radeon_dma_bo { 275 struct radeon_dma_bo *next, *prev; 276 struct radeon_bo *bo; 277 int expire_counter; 278}; 279 280struct r600_accel_object { 281 uint32_t pitch; 282 uint32_t width; 283 uint32_t height; 284 int bpp; 285 uint32_t domain; 286 struct radeon_bo *bo; 287 uint32_t tiling_flags; 288 struct radeon_surface *surface; 289}; 290 291struct radeon_vbo_object { 292 int vb_offset; 293 int vb_total; 294 uint32_t vb_size; 295 uint32_t vb_op_vert_size; 296 int32_t vb_start_op; 297 struct radeon_bo *vb_bo; 298 unsigned verts_per_op; 299}; 300 301struct radeon_accel_state { 302 303 /* Saved values for ScreenToScreenCopy */ 304 int xdir; 305 int ydir; 306 307 /* render accel */ 308 unsigned short texW[2]; 309 unsigned short texH[2]; 310 Bool XInited3D; /* X itself has the 3D context */ 311 int num_gb_pipes; 312 Bool has_tcl; 313 Bool allowHWDFS; 314 315 /* EXA */ 316 ExaDriverPtr exa; 317 int exaSyncMarker; 318 int exaMarkerSynced; 319 int engineMode; 320#define EXA_ENGINEMODE_UNKNOWN 0 321#define EXA_ENGINEMODE_2D 1 322#define EXA_ENGINEMODE_3D 2 323 324 int composite_op; 325 PicturePtr dst_pic; 326 PicturePtr msk_pic; 327 PicturePtr src_pic; 328 PixmapPtr dst_pix; 329 PixmapPtr msk_pix; 330 PixmapPtr src_pix; 331 Bool is_transform[2]; 332 PictTransform *transform[2]; 333 /* Whether we are tiling horizontally and vertically */ 334 Bool need_src_tile_x; 335 Bool need_src_tile_y; 336 /* Size of tiles ... set to 65536x65536 if not tiling in that direction */ 337 Bool src_tile_width; 338 Bool src_tile_height; 339 uint32_t *draw_header; 340 unsigned vtx_count; 341 unsigned num_vtx; 342 Bool vsync; 343 344 struct radeon_vbo_object vbo; 345 struct radeon_vbo_object cbuf; 346 347 /* where to discard IB from if we cancel operation */ 348 uint32_t ib_reset_op; 349 struct radeon_dma_bo bo_free; 350 struct radeon_dma_bo bo_wait; 351 struct radeon_dma_bo bo_reserved; 352 Bool use_vbos; 353 void (*finish_op)(ScrnInfoPtr, int); 354 // shader storage 355 struct radeon_bo *shaders_bo; 356 uint32_t solid_vs_offset; 357 uint32_t solid_ps_offset; 358 uint32_t copy_vs_offset; 359 uint32_t copy_ps_offset; 360 uint32_t comp_vs_offset; 361 uint32_t comp_ps_offset; 362 uint32_t xv_vs_offset; 363 uint32_t xv_ps_offset; 364 // shader consts 365 uint32_t solid_vs_const_offset; 366 uint32_t solid_ps_const_offset; 367 uint32_t copy_vs_const_offset; 368 uint32_t copy_ps_const_offset; 369 uint32_t comp_vs_const_offset; 370 uint32_t comp_ps_const_offset; 371 uint32_t comp_mask_ps_const_offset; 372 uint32_t xv_vs_const_offset; 373 uint32_t xv_ps_const_offset; 374 375 //size/addr stuff 376 struct r600_accel_object src_obj[2]; 377 struct r600_accel_object dst_obj; 378 uint32_t src_size[2]; 379 uint32_t dst_size; 380 381 uint32_t vs_size; 382 uint64_t vs_mc_addr; 383 uint32_t ps_size; 384 uint64_t ps_mc_addr; 385 386 // solid/copy 387 void *copy_area; 388 struct radeon_bo *copy_area_bo; 389 Bool same_surface; 390 int rop; 391 uint32_t planemask; 392 uint32_t fg; 393 394 // composite 395 Bool component_alpha; 396 Bool src_alpha; 397 // vline 398 xf86CrtcPtr vline_crtc; 399 int vline_y1; 400 int vline_y2; 401 402 Bool force; 403}; 404 405typedef struct { 406 EntityInfoPtr pEnt; 407 pciVideoPtr PciInfo; 408 int Chipset; 409 RADEONChipFamily ChipFamily; 410 411 Bool (*CloseScreen)(CLOSE_SCREEN_ARGS_DECL); 412 413 void (*BlockHandler)(BLOCKHANDLER_ARGS_DECL); 414 415 int pix24bpp; /* Depth of pixmap for 24bpp fb */ 416 Bool dac6bits; /* Use 6 bit DAC? */ 417 418 int pixel_bytes; 419 420 Bool directRenderingEnabled; 421 struct radeon_dri2 dri2; 422 Bool accelDFS; 423 424 /* accel */ 425 Bool RenderAccel; /* Render */ 426 Bool allowColorTiling; 427 Bool allowColorTiling2D; 428 struct radeon_accel_state *accel_state; 429 Bool accelOn; 430 Bool use_glamor; 431 Bool exa_pixmaps; 432 Bool exa_force_create; 433 XF86ModReqInfo exaReq; 434 Bool is_fast_fb; /* use direct mapping for fast fb access */ 435 436 unsigned int xv_max_width; 437 unsigned int xv_max_height; 438 439 /* general */ 440 OptionInfoPtr Options; 441 442 DisplayModePtr currentMode; 443 444 CreateScreenResourcesProcPtr CreateScreenResources; 445 446 Bool IsSecondary; 447 Bool IsPrimary; 448 449 Bool r600_shadow_fb; 450 void *fb_shadow; 451 452 void (*reemit_current2d)(ScrnInfoPtr pScrn, int op); // emit the current 2D state into the IB 453 struct radeon_2d_state state_2d; 454 struct radeon_bo *front_bo; 455 struct radeon_bo_manager *bufmgr; 456 struct radeon_cs_manager *csm; 457 struct radeon_cs *cs; 458 459 struct radeon_bo *cursor_bo[32]; 460 uint64_t vram_size; 461 uint64_t gart_size; 462 drmmode_rec drmmode; 463 Bool drmmode_inited; 464 /* r6xx+ tile config */ 465 Bool have_tiling_info; 466 uint32_t tile_config; 467 int group_bytes; 468 int num_channels; 469 int num_banks; 470 int r7xx_bank_op; 471 struct radeon_surface_manager *surf_man; 472 struct radeon_surface front_surface; 473 474 /* Xv bicubic filtering */ 475 struct radeon_bo *bicubic_bo; 476 477 /* kms pageflipping */ 478 Bool allowPageFlip; 479 480 /* Perform vsync'ed SwapBuffers? */ 481 Bool swapBuffersWait; 482 483 /* cursor size */ 484 int cursor_w; 485 int cursor_h; 486} RADEONInfoRec, *RADEONInfoPtr; 487 488/* radeon_accel.c */ 489extern Bool RADEONAccelInit(ScreenPtr pScreen); 490extern void RADEONEngineInit(ScrnInfoPtr pScrn); 491extern void RADEONCopySwap(uint8_t *dst, uint8_t *src, unsigned int size, int swap); 492extern void RADEONInit3DEngine(ScrnInfoPtr pScrn); 493extern int radeon_cs_space_remaining(ScrnInfoPtr pScrn); 494 495/* radeon_commonfuncs.c */ 496extern void RADEONWaitForVLine(ScrnInfoPtr pScrn, PixmapPtr pPix, 497 xf86CrtcPtr crtc, int start, int stop); 498 499 500/* radeon_exa.c */ 501extern unsigned eg_tile_split(unsigned tile_split); 502extern Bool radeon_transform_is_affine_or_scaled(PictTransformPtr t); 503 504/* radeon_exa_funcs.c */ 505extern Bool RADEONDrawInit(ScreenPtr pScreen); 506extern Bool R600DrawInit(ScreenPtr pScreen); 507extern Bool R600LoadShaders(ScrnInfoPtr pScrn); 508extern Bool EVERGREENDrawInit(ScreenPtr pScreen); 509 510/* radeon_exa.c */ 511extern Bool RADEONGetDatatypeBpp(int bpp, uint32_t *type); 512extern Bool RADEONGetPixmapOffsetPitch(PixmapPtr pPix, 513 uint32_t *pitch_offset); 514 515/* radeon_video.c */ 516extern void RADEONInitVideo(ScreenPtr pScreen); 517extern void RADEONResetVideo(ScrnInfoPtr pScrn); 518extern Bool radeon_load_bicubic_texture(ScrnInfoPtr pScrn); 519extern xf86CrtcPtr radeon_pick_best_crtc(ScrnInfoPtr pScrn, 520 Bool consider_disabled, 521 int x1, int x2, int y1, int y2); 522 523extern void radeon_cs_flush_indirect(ScrnInfoPtr pScrn); 524extern void radeon_ddx_cs_start(ScrnInfoPtr pScrn, 525 int num, const char *file, 526 const char *func, int line); 527void radeon_kms_update_vram_limit(ScrnInfoPtr pScrn, uint32_t new_fb_size); 528extern RADEONEntPtr RADEONEntPriv(ScrnInfoPtr pScrn); 529 530drmVBlankSeqType radeon_populate_vbl_request_type(xf86CrtcPtr crtc); 531 532#if XF86_CRTC_VERSION >= 5 533#define RADEON_PIXMAP_SHARING 1 534#endif 535 536static inline struct radeon_surface *radeon_get_pixmap_surface(PixmapPtr pPix) 537{ 538#ifdef USE_GLAMOR 539 RADEONInfoPtr info = RADEONPTR(xf86ScreenToScrn(pPix->drawable.pScreen)); 540 541 if (info->use_glamor) { 542 struct radeon_pixmap *priv; 543 priv = radeon_get_pixmap_private(pPix); 544 return priv ? &priv->surface : NULL; 545 } else 546#endif 547 { 548 struct radeon_exa_pixmap_priv *driver_priv; 549 driver_priv = exaGetPixmapDriverPrivate(pPix); 550 return &driver_priv->surface; 551 } 552 553 return NULL; 554} 555 556uint32_t radeon_get_pixmap_tiling(PixmapPtr pPix); 557 558static inline void radeon_set_pixmap_bo(PixmapPtr pPix, struct radeon_bo *bo) 559{ 560#ifdef USE_GLAMOR 561 RADEONInfoPtr info = RADEONPTR(xf86ScreenToScrn(pPix->drawable.pScreen)); 562 563 if (info->use_glamor) { 564 struct radeon_pixmap *priv; 565 566 priv = radeon_get_pixmap_private(pPix); 567 if (priv == NULL && bo == NULL) 568 return; 569 570 if (priv) { 571 if (priv->bo == bo) 572 return; 573 574 if (priv->bo) 575 radeon_bo_unref(priv->bo); 576 577 if (!bo) { 578 free(priv); 579 priv = NULL; 580 } 581 } 582 583 if (bo) { 584 uint32_t pitch; 585 586 if (!priv) { 587 priv = calloc(1, sizeof (struct radeon_pixmap)); 588 if (!priv) 589 goto out; 590 } 591 592 radeon_bo_ref(bo); 593 priv->bo = bo; 594 595 radeon_bo_get_tiling(bo, &priv->tiling_flags, &pitch); 596 } 597out: 598 radeon_set_pixmap_private(pPix, priv); 599 } else 600#endif /* USE_GLAMOR */ 601 { 602 struct radeon_exa_pixmap_priv *driver_priv; 603 604 driver_priv = exaGetPixmapDriverPrivate(pPix); 605 if (driver_priv) { 606 uint32_t pitch; 607 608 if (driver_priv->bo) 609 radeon_bo_unref(driver_priv->bo); 610 611 radeon_bo_ref(bo); 612 driver_priv->bo = bo; 613 614 radeon_bo_get_tiling(bo, &driver_priv->tiling_flags, &pitch); 615 } 616 } 617} 618 619static inline struct radeon_bo *radeon_get_pixmap_bo(PixmapPtr pPix) 620{ 621#ifdef USE_GLAMOR 622 RADEONInfoPtr info = RADEONPTR(xf86ScreenToScrn(pPix->drawable.pScreen)); 623 624 if (info->use_glamor) { 625 struct radeon_pixmap *priv; 626 priv = radeon_get_pixmap_private(pPix); 627 return priv ? priv->bo : NULL; 628 } else 629#endif 630 { 631 struct radeon_exa_pixmap_priv *driver_priv; 632 driver_priv = exaGetPixmapDriverPrivate(pPix); 633 return driver_priv->bo; 634 } 635 636 return NULL; 637} 638 639static inline Bool radeon_get_pixmap_shared(PixmapPtr pPix) 640{ 641#ifdef USE_GLAMOR 642 RADEONInfoPtr info = RADEONPTR(xf86ScreenToScrn(pPix->drawable.pScreen)); 643 644 if (info->use_glamor) { 645 ErrorF("glamor sharing todo\n"); 646 return FALSE; 647 } else 648#endif 649 { 650 struct radeon_exa_pixmap_priv *driver_priv; 651 driver_priv = exaGetPixmapDriverPrivate(pPix); 652 return driver_priv->shared; 653 } 654 return FALSE; 655} 656 657#define CP_PACKET0(reg, n) \ 658 (RADEON_CP_PACKET0 | ((n) << 16) | ((reg) >> 2)) 659#define CP_PACKET1(reg0, reg1) \ 660 (RADEON_CP_PACKET1 | (((reg1) >> 2) << 11) | ((reg0) >> 2)) 661#define CP_PACKET2() \ 662 (RADEON_CP_PACKET2) 663#define CP_PACKET3(pkt, n) \ 664 (RADEON_CP_PACKET3 | (pkt) | ((n) << 16)) 665 666 667#define RADEON_VERBOSE 0 668 669#define BEGIN_RING(n) do { \ 670 if (RADEON_VERBOSE) { \ 671 xf86DrvMsg(pScrn->scrnIndex, X_INFO, \ 672 "BEGIN_RING(%d) in %s\n", (unsigned int)n, __FUNCTION__);\ 673 } \ 674 radeon_ddx_cs_start(pScrn, n, __FILE__, __func__, __LINE__); \ 675} while (0) 676 677#define ADVANCE_RING() do { \ 678 radeon_cs_end(info->cs, __FILE__, __func__, __LINE__); \ 679 } while (0) 680 681#define OUT_RING(x) do { \ 682 if (RADEON_VERBOSE) { \ 683 xf86DrvMsg(pScrn->scrnIndex, X_INFO, \ 684 " OUT_RING(0x%08x)\n", (unsigned int)(x)); \ 685 } \ 686 radeon_cs_write_dword(info->cs, (x)); \ 687} while (0) 688 689#define OUT_RING_REG(reg, val) \ 690do { \ 691 OUT_RING(CP_PACKET0(reg, 0)); \ 692 OUT_RING(val); \ 693} while (0) 694 695#define OUT_RING_RELOC(x, read_domains, write_domain) \ 696 do { \ 697 int _ret; \ 698 _ret = radeon_cs_write_reloc(info->cs, x, read_domains, write_domain, 0); \ 699 if (_ret) ErrorF("reloc emit failure %d\n", _ret); \ 700 } while(0) 701 702 703#define FLUSH_RING() \ 704do { \ 705 if (RADEON_VERBOSE) \ 706 xf86DrvMsg(pScrn->scrnIndex, X_INFO, \ 707 "FLUSH_RING in %s\n", __FUNCTION__); \ 708 radeon_cs_flush_indirect(pScrn); \ 709} while (0) 710 711#define CS_FULL(cs) ((cs)->cdw > 15 * 1024) 712 713#define RADEON_SWITCH_TO_2D() \ 714do { \ 715 uint32_t flush = 0; \ 716 switch (info->accel_state->engineMode) { \ 717 case EXA_ENGINEMODE_UNKNOWN: \ 718 flush = 1; \ 719 break; \ 720 case EXA_ENGINEMODE_3D: \ 721 flush = CS_FULL(info->cs); \ 722 break; \ 723 case EXA_ENGINEMODE_2D: \ 724 flush = CS_FULL(info->cs); \ 725 break; \ 726 } \ 727 if (flush) { \ 728 radeon_cs_flush_indirect(pScrn); \ 729 } \ 730 info->accel_state->engineMode = EXA_ENGINEMODE_2D; \ 731} while (0); 732 733#define RADEON_SWITCH_TO_3D() \ 734do { \ 735 uint32_t flush = 0; \ 736 switch (info->accel_state->engineMode) { \ 737 case EXA_ENGINEMODE_UNKNOWN: \ 738 flush = 1; \ 739 break; \ 740 case EXA_ENGINEMODE_2D: \ 741 flush = CS_FULL(info->cs); \ 742 break; \ 743 case EXA_ENGINEMODE_3D: \ 744 flush = CS_FULL(info->cs); \ 745 break; \ 746 } \ 747 if (flush) { \ 748 radeon_cs_flush_indirect(pScrn); \ 749 } \ 750 if (!info->accel_state->XInited3D) \ 751 RADEONInit3DEngine(pScrn); \ 752 info->accel_state->engineMode = EXA_ENGINEMODE_3D; \ 753} while (0); 754 755 /* Memory mapped register access macros */ 756 757#define BEGIN_ACCEL_RELOC(n, r) do { \ 758 int _nqw = (n) + (r); \ 759 BEGIN_RING(2*_nqw); \ 760 } while (0) 761 762#define EMIT_OFFSET(reg, value, pPix, rd, wd) do { \ 763 driver_priv = exaGetPixmapDriverPrivate(pPix); \ 764 OUT_RING_REG((reg), (value)); \ 765 OUT_RING_RELOC(driver_priv->bo, (rd), (wd)); \ 766 } while(0) 767 768#define EMIT_READ_OFFSET(reg, value, pPix) EMIT_OFFSET(reg, value, pPix, (RADEON_GEM_DOMAIN_VRAM | RADEON_GEM_DOMAIN_GTT), 0) 769#define EMIT_WRITE_OFFSET(reg, value, pPix) EMIT_OFFSET(reg, value, pPix, 0, RADEON_GEM_DOMAIN_VRAM) 770 771#define OUT_TEXTURE_REG(reg, offset, bo) do { \ 772 OUT_RING_REG((reg), (offset)); \ 773 OUT_RING_RELOC((bo), RADEON_GEM_DOMAIN_VRAM | RADEON_GEM_DOMAIN_GTT, 0); \ 774 } while(0) 775 776#define EMIT_COLORPITCH(reg, value, pPix) do { \ 777 driver_priv = exaGetPixmapDriverPrivate(pPix); \ 778 OUT_RING_REG((reg), value); \ 779 OUT_RING_RELOC(driver_priv->bo, 0, RADEON_GEM_DOMAIN_VRAM); \ 780} while(0) 781 782static __inline__ void RADEON_SYNC(RADEONInfoPtr info, ScrnInfoPtr pScrn) 783{ 784 if (pScrn->pScreen) 785 exaWaitSync(pScrn->pScreen); 786} 787 788enum { 789 RADEON_CREATE_PIXMAP_DRI2 = 0x04000000, 790 RADEON_CREATE_PIXMAP_TILING_MICRO_SQUARE = 0x08000000, 791 RADEON_CREATE_PIXMAP_TILING_MACRO = 0x10000000, 792 RADEON_CREATE_PIXMAP_TILING_MICRO = 0x20000000, 793 RADEON_CREATE_PIXMAP_DEPTH = 0x40000000, /* for r200 */ 794 RADEON_CREATE_PIXMAP_SZBUFFER = 0x80000000, /* for eg */ 795}; 796 797#define RADEON_CREATE_PIXMAP_TILING_FLAGS \ 798 (RADEON_CREATE_PIXMAP_TILING_MICRO_SQUARE | \ 799 RADEON_CREATE_PIXMAP_TILING_MACRO | \ 800 RADEON_CREATE_PIXMAP_TILING_MICRO | \ 801 RADEON_CREATE_PIXMAP_DEPTH | \ 802 RADEON_CREATE_PIXMAP_SZBUFFER) 803 804 805/* Compute log base 2 of val. */ 806static __inline__ int 807RADEONLog2(int val) 808{ 809 int bits; 810#if (defined __i386__ || defined __x86_64__) && (defined __GNUC__) 811 __asm volatile("bsrl %1, %0" 812 : "=r" (bits) 813 : "c" (val) 814 ); 815 return bits; 816#else 817 for (bits = 0; val != 0; val >>= 1, ++bits) 818 ; 819 return bits - 1; 820#endif 821} 822 823#define RADEON_TILING_MASK 0xff 824#define RADEON_TILING_LINEAR 0x0 825 826#endif /* _RADEON_H_ */ 827