1209ff23fSmrg/* 2209ff23fSmrg * Copyright 2000 ATI Technologies Inc., Markham, Ontario, and 3209ff23fSmrg * VA Linux Systems Inc., Fremont, California. 4209ff23fSmrg * 5209ff23fSmrg * All Rights Reserved. 6209ff23fSmrg * 7209ff23fSmrg * Permission is hereby granted, free of charge, to any person obtaining 8209ff23fSmrg * a copy of this software and associated documentation files (the 9209ff23fSmrg * "Software"), to deal in the Software without restriction, including 10209ff23fSmrg * without limitation on the rights to use, copy, modify, merge, 11209ff23fSmrg * publish, distribute, sublicense, and/or sell copies of the Software, 12209ff23fSmrg * and to permit persons to whom the Software is furnished to do so, 13209ff23fSmrg * subject to the following conditions: 14209ff23fSmrg * 15209ff23fSmrg * The above copyright notice and this permission notice (including the 16209ff23fSmrg * next paragraph) shall be included in all copies or substantial 17209ff23fSmrg * portions of the Software. 18209ff23fSmrg * 19209ff23fSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 20209ff23fSmrg * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 21209ff23fSmrg * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 22209ff23fSmrg * NON-INFRINGEMENT. IN NO EVENT SHALL ATI, VA LINUX SYSTEMS AND/OR 23209ff23fSmrg * THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 24209ff23fSmrg * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 25209ff23fSmrg * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 26209ff23fSmrg * DEALINGS IN THE SOFTWARE. 27209ff23fSmrg */ 28209ff23fSmrg 29209ff23fSmrg#ifdef HAVE_CONFIG_H 30209ff23fSmrg#include "config.h" 31209ff23fSmrg#endif 32209ff23fSmrg 33209ff23fSmrg/* 34209ff23fSmrg * Authors: 35209ff23fSmrg * Kevin E. Martin <martin@xfree86.org> 36209ff23fSmrg * Rickard E. Faith <faith@valinux.com> 37209ff23fSmrg * Alan Hourihane <alanh@fairlite.demon.co.uk> 38209ff23fSmrg * Michel Dänzer <michel@daenzer.net> 39209ff23fSmrg * 40209ff23fSmrg * Credits: 41209ff23fSmrg * 42209ff23fSmrg * Thanks to Ani Joshi <ajoshi@shell.unixbox.com> for providing source 43209ff23fSmrg * code to his Radeon driver. Portions of this file are based on the 44209ff23fSmrg * initialization code for that driver. 45209ff23fSmrg * 46209ff23fSmrg * References: 47209ff23fSmrg * 48209ff23fSmrg * !!!! FIXME !!!! 49209ff23fSmrg * RAGE 128 VR/ RAGE 128 GL Register Reference Manual (Technical 50209ff23fSmrg * Reference Manual P/N RRG-G04100-C Rev. 0.04), ATI Technologies: April 51209ff23fSmrg * 1999. 52209ff23fSmrg * 53209ff23fSmrg * RAGE 128 Software Development Manual (Technical Reference Manual P/N 54209ff23fSmrg * SDK-G04000 Rev. 0.01), ATI Technologies: June 1999. 55209ff23fSmrg * 56209ff23fSmrg * Notes on unimplemented XAA optimizations: 57209ff23fSmrg * 58209ff23fSmrg * SetClipping: This has been removed as XAA expects 16bit registers 59209ff23fSmrg * for full clipping. 60209ff23fSmrg * TwoPointLine: The Radeon supports this. Not Bresenham. 61209ff23fSmrg * DashedLine with non-power-of-two pattern length: Apparently, there is 62209ff23fSmrg * no way to set the length of the pattern -- it is always 63209ff23fSmrg * assumed to be 8 or 32 (or 1024?). 64209ff23fSmrg * ScreenToScreenColorExpandFill: See p. 4-17 of the Technical Reference 65209ff23fSmrg * Manual where it states that monochrome expansion of frame 66209ff23fSmrg * buffer data is not supported. 67209ff23fSmrg * CPUToScreenColorExpandFill, direct: The implementation here uses a hybrid 68209ff23fSmrg * direct/indirect method. If we had more data registers, 69209ff23fSmrg * then we could do better. If XAA supported a trigger write 70209ff23fSmrg * address, the code would be simpler. 71209ff23fSmrg * Color8x8PatternFill: Apparently, an 8x8 color brush cannot take an 8x8 72209ff23fSmrg * pattern from frame buffer memory. 73209ff23fSmrg * ImageWrites: Same as CPUToScreenColorExpandFill 74209ff23fSmrg * 75209ff23fSmrg */ 76209ff23fSmrg 77209ff23fSmrg#if defined(ACCEL_MMIO) && defined(ACCEL_CP) 78209ff23fSmrg#error Cannot define both MMIO and CP acceleration! 79209ff23fSmrg#endif 80209ff23fSmrg 81209ff23fSmrg#if !defined(UNIXCPP) || defined(ANSICPP) 82209ff23fSmrg#define FUNC_NAME_CAT(prefix,suffix) prefix##suffix 83209ff23fSmrg#else 84209ff23fSmrg#define FUNC_NAME_CAT(prefix,suffix) prefix/**/suffix 85209ff23fSmrg#endif 86209ff23fSmrg 87209ff23fSmrg#ifdef ACCEL_MMIO 88209ff23fSmrg#define FUNC_NAME(prefix) FUNC_NAME_CAT(prefix,MMIO) 89209ff23fSmrg#else 90209ff23fSmrg#ifdef ACCEL_CP 91209ff23fSmrg#define FUNC_NAME(prefix) FUNC_NAME_CAT(prefix,CP) 92209ff23fSmrg#else 93209ff23fSmrg#error No accel type defined! 94209ff23fSmrg#endif 95209ff23fSmrg#endif 96209ff23fSmrg 97209ff23fSmrg#ifdef USE_XAA 98209ff23fSmrg 99209ff23fSmrg/* This callback is required for multiheader cards using XAA */ 100209ff23fSmrgstatic void 101209ff23fSmrgFUNC_NAME(RADEONRestoreAccelState)(ScrnInfoPtr pScrn) 102209ff23fSmrg{ 103209ff23fSmrg /*RADEONInfoPtr info = RADEONPTR(pScrn); 104209ff23fSmrg unsigned char *RADEONMMIO = info->MMIO;*/ 105209ff23fSmrg 106209ff23fSmrg#ifdef ACCEL_MMIO 107209ff23fSmrg 108209ff23fSmrg/* OUTREG(RADEON_DEFAULT_OFFSET, info->dst_pitch_offset);*/ 109209ff23fSmrg /* FIXME: May need to restore other things, like BKGD_CLK FG_CLK... */ 110209ff23fSmrg 111209ff23fSmrg RADEONWaitForIdleMMIO(pScrn); 112209ff23fSmrg 113209ff23fSmrg#else /* ACCEL_CP */ 114209ff23fSmrg 115209ff23fSmrg/* RADEONWaitForFifo(pScrn, 1); 116209ff23fSmrg OUTREG(RADEON_DEFAULT_OFFSET, info->frontPitchOffset);*/ 117209ff23fSmrg 118209ff23fSmrg RADEONWaitForIdleMMIO(pScrn); 119209ff23fSmrg 120209ff23fSmrg#if 0 121209ff23fSmrg /* Not working yet */ 122209ff23fSmrg RADEONMMIO_TO_CP(pScrn, info); 123209ff23fSmrg#endif 124209ff23fSmrg 125209ff23fSmrg /* FIXME: May need to restore other things, like BKGD_CLK FG_CLK... */ 126209ff23fSmrg#endif 127209ff23fSmrg} 128209ff23fSmrg 129209ff23fSmrg/* Setup for XAA SolidFill */ 130209ff23fSmrgstatic void 131209ff23fSmrgFUNC_NAME(RADEONSetupForSolidFill)(ScrnInfoPtr pScrn, 132209ff23fSmrg int color, 133209ff23fSmrg int rop, 134209ff23fSmrg unsigned int planemask) 135209ff23fSmrg{ 136209ff23fSmrg RADEONInfoPtr info = RADEONPTR(pScrn); 137209ff23fSmrg ACCEL_PREAMBLE(); 138209ff23fSmrg 139209ff23fSmrg /* Save for later clipping */ 140b7e1c893Smrg info->accel_state->dp_gui_master_cntl_clip = (info->accel_state->dp_gui_master_cntl 141b7e1c893Smrg | RADEON_GMC_BRUSH_SOLID_COLOR 142b7e1c893Smrg | RADEON_GMC_SRC_DATATYPE_COLOR 143b7e1c893Smrg | RADEON_ROP[rop].pattern); 144209ff23fSmrg 145209ff23fSmrg BEGIN_ACCEL(4); 146209ff23fSmrg 147b7e1c893Smrg OUT_ACCEL_REG(RADEON_DP_GUI_MASTER_CNTL, info->accel_state->dp_gui_master_cntl_clip); 148209ff23fSmrg OUT_ACCEL_REG(RADEON_DP_BRUSH_FRGD_CLR, color); 149209ff23fSmrg OUT_ACCEL_REG(RADEON_DP_WRITE_MASK, planemask); 150209ff23fSmrg OUT_ACCEL_REG(RADEON_DP_CNTL, (RADEON_DST_X_LEFT_TO_RIGHT 151209ff23fSmrg | RADEON_DST_Y_TOP_TO_BOTTOM)); 152209ff23fSmrg 153209ff23fSmrg FINISH_ACCEL(); 154209ff23fSmrg BEGIN_ACCEL(2); 155209ff23fSmrg OUT_ACCEL_REG(RADEON_DSTCACHE_CTLSTAT, RADEON_RB2D_DC_FLUSH_ALL); 156209ff23fSmrg OUT_ACCEL_REG(RADEON_WAIT_UNTIL, 157209ff23fSmrg RADEON_WAIT_2D_IDLECLEAN | RADEON_WAIT_DMA_GUI_IDLE); 158209ff23fSmrg FINISH_ACCEL(); 159209ff23fSmrg} 160209ff23fSmrg 161209ff23fSmrg/* Subsequent XAA SolidFillRect 162209ff23fSmrg * 163209ff23fSmrg * Tests: xtest CH06/fllrctngl, xterm 164209ff23fSmrg */ 165209ff23fSmrgstatic void 166209ff23fSmrgFUNC_NAME(RADEONSubsequentSolidFillRect)(ScrnInfoPtr pScrn, 167209ff23fSmrg int x, int y, 168209ff23fSmrg int w, int h) 169209ff23fSmrg{ 170209ff23fSmrg RADEONInfoPtr info = RADEONPTR(pScrn); 171209ff23fSmrg ACCEL_PREAMBLE(); 172209ff23fSmrg 173209ff23fSmrg BEGIN_ACCEL(3); 174209ff23fSmrg 175b7e1c893Smrg OUT_ACCEL_REG(RADEON_DST_PITCH_OFFSET, info->accel_state->dst_pitch_offset | 176209ff23fSmrg ((info->tilingEnabled && (y <= pScrn->virtualY)) ? RADEON_DST_TILE_MACRO : 0)); 177209ff23fSmrg OUT_ACCEL_REG(RADEON_DST_Y_X, (y << 16) | x); 178209ff23fSmrg OUT_ACCEL_REG(RADEON_DST_WIDTH_HEIGHT, (w << 16) | h); 179209ff23fSmrg 180209ff23fSmrg FINISH_ACCEL(); 181209ff23fSmrg} 182209ff23fSmrg 183209ff23fSmrg/* Setup for XAA solid lines */ 184209ff23fSmrgstatic void 185209ff23fSmrgFUNC_NAME(RADEONSetupForSolidLine)(ScrnInfoPtr pScrn, 186209ff23fSmrg int color, 187209ff23fSmrg int rop, 188209ff23fSmrg unsigned int planemask) 189209ff23fSmrg{ 190209ff23fSmrg RADEONInfoPtr info = RADEONPTR(pScrn); 191209ff23fSmrg ACCEL_PREAMBLE(); 192209ff23fSmrg 193209ff23fSmrg /* Save for later clipping */ 194b7e1c893Smrg info->accel_state->dp_gui_master_cntl_clip = (info->accel_state->dp_gui_master_cntl 195b7e1c893Smrg | RADEON_GMC_BRUSH_SOLID_COLOR 196b7e1c893Smrg | RADEON_GMC_SRC_DATATYPE_COLOR 197b7e1c893Smrg | RADEON_ROP[rop].pattern); 198209ff23fSmrg 199209ff23fSmrg if (info->ChipFamily >= CHIP_FAMILY_RV200) { 200209ff23fSmrg BEGIN_ACCEL(1); 201209ff23fSmrg OUT_ACCEL_REG(RADEON_DST_LINE_PATCOUNT, 202209ff23fSmrg 0x55 << RADEON_BRES_CNTL_SHIFT); 203209ff23fSmrg FINISH_ACCEL(); 204209ff23fSmrg } 205209ff23fSmrg 206209ff23fSmrg BEGIN_ACCEL(3); 207209ff23fSmrg 208b7e1c893Smrg OUT_ACCEL_REG(RADEON_DP_GUI_MASTER_CNTL, info->accel_state->dp_gui_master_cntl_clip); 209209ff23fSmrg OUT_ACCEL_REG(RADEON_DP_BRUSH_FRGD_CLR, color); 210209ff23fSmrg OUT_ACCEL_REG(RADEON_DP_WRITE_MASK, planemask); 211209ff23fSmrg 212209ff23fSmrg FINISH_ACCEL(); 213209ff23fSmrg BEGIN_ACCEL(2); 214209ff23fSmrg OUT_ACCEL_REG(RADEON_DSTCACHE_CTLSTAT, RADEON_RB2D_DC_FLUSH_ALL); 215209ff23fSmrg OUT_ACCEL_REG(RADEON_WAIT_UNTIL, 216209ff23fSmrg RADEON_WAIT_2D_IDLECLEAN | RADEON_WAIT_DMA_GUI_IDLE); 217209ff23fSmrg FINISH_ACCEL(); 218209ff23fSmrg} 219209ff23fSmrg 220209ff23fSmrg/* Subsequent XAA solid horizontal and vertical lines */ 221209ff23fSmrgstatic void 222209ff23fSmrgFUNC_NAME(RADEONSubsequentSolidHorVertLine)(ScrnInfoPtr pScrn, 223209ff23fSmrg int x, int y, 224209ff23fSmrg int len, 225209ff23fSmrg int dir) 226209ff23fSmrg{ 227209ff23fSmrg RADEONInfoPtr info = RADEONPTR(pScrn); 228209ff23fSmrg int w = 1; 229209ff23fSmrg int h = 1; 230209ff23fSmrg ACCEL_PREAMBLE(); 231209ff23fSmrg 232209ff23fSmrg if (dir == DEGREES_0) w = len; 233209ff23fSmrg else h = len; 234209ff23fSmrg 235209ff23fSmrg BEGIN_ACCEL(4); 236209ff23fSmrg 237209ff23fSmrg OUT_ACCEL_REG(RADEON_DP_CNTL, (RADEON_DST_X_LEFT_TO_RIGHT 238209ff23fSmrg | RADEON_DST_Y_TOP_TO_BOTTOM)); 239b7e1c893Smrg OUT_ACCEL_REG(RADEON_DST_PITCH_OFFSET, info->accel_state->dst_pitch_offset | 240209ff23fSmrg ((info->tilingEnabled && (y <= pScrn->virtualY)) ? RADEON_DST_TILE_MACRO : 0)); 241209ff23fSmrg OUT_ACCEL_REG(RADEON_DST_Y_X, (y << 16) | x); 242209ff23fSmrg OUT_ACCEL_REG(RADEON_DST_WIDTH_HEIGHT, (w << 16) | h); 243209ff23fSmrg 244209ff23fSmrg FINISH_ACCEL(); 245209ff23fSmrg} 246209ff23fSmrg 247209ff23fSmrg/* Subsequent XAA solid TwoPointLine line 248209ff23fSmrg * 249209ff23fSmrg * Tests: xtest CH06/drwln, ico, Mark Vojkovich's linetest program 250209ff23fSmrg * 251209ff23fSmrg * [See http://www.xfree86.org/devel/archives/devel/1999-Jun/0102.shtml for 252209ff23fSmrg * Mark Vojkovich's linetest program, posted 2Jun99 to devel@xfree86.org.] 253209ff23fSmrg */ 254209ff23fSmrgstatic void 255209ff23fSmrgFUNC_NAME(RADEONSubsequentSolidTwoPointLine)(ScrnInfoPtr pScrn, 256209ff23fSmrg int xa, int ya, 257209ff23fSmrg int xb, int yb, 258209ff23fSmrg int flags) 259209ff23fSmrg{ 260209ff23fSmrg RADEONInfoPtr info = RADEONPTR(pScrn); 261209ff23fSmrg ACCEL_PREAMBLE(); 262209ff23fSmrg 263209ff23fSmrg /* TODO: Check bounds -- RADEON only has 14 bits */ 264209ff23fSmrg 265209ff23fSmrg if (!(flags & OMIT_LAST)) 266209ff23fSmrg FUNC_NAME(RADEONSubsequentSolidHorVertLine)(pScrn, 267209ff23fSmrg xb, yb, 1, 268209ff23fSmrg DEGREES_0); 269209ff23fSmrg 270209ff23fSmrg BEGIN_ACCEL(3); 271209ff23fSmrg 272b7e1c893Smrg OUT_ACCEL_REG(RADEON_DST_PITCH_OFFSET, info->accel_state->dst_pitch_offset | 273209ff23fSmrg ((info->tilingEnabled && (ya <= pScrn->virtualY)) ? RADEON_DST_TILE_MACRO : 0)); 274209ff23fSmrg OUT_ACCEL_REG(RADEON_DST_LINE_START, (ya << 16) | xa); 275209ff23fSmrg OUT_ACCEL_REG(RADEON_DST_LINE_END, (yb << 16) | xb); 276209ff23fSmrg 277209ff23fSmrg FINISH_ACCEL(); 278209ff23fSmrg} 279209ff23fSmrg 280209ff23fSmrg/* Setup for XAA dashed lines 281209ff23fSmrg * 282209ff23fSmrg * Tests: xtest CH05/stdshs, XFree86/drwln 283209ff23fSmrg * 284209ff23fSmrg * NOTE: Since we can only accelerate lines with power-of-2 patterns of 285209ff23fSmrg * length <= 32 286209ff23fSmrg */ 287209ff23fSmrgstatic void 288209ff23fSmrgFUNC_NAME(RADEONSetupForDashedLine)(ScrnInfoPtr pScrn, 289209ff23fSmrg int fg, 290209ff23fSmrg int bg, 291209ff23fSmrg int rop, 292209ff23fSmrg unsigned int planemask, 293209ff23fSmrg int length, 294209ff23fSmrg unsigned char *pattern) 295209ff23fSmrg{ 296209ff23fSmrg RADEONInfoPtr info = RADEONPTR(pScrn); 297209ff23fSmrg uint32_t pat = *(uint32_t *)(pointer)pattern; 298209ff23fSmrg ACCEL_PREAMBLE(); 299209ff23fSmrg 300209ff23fSmrg /* Save for determining whether or not to draw last pixel */ 301b7e1c893Smrg info->accel_state->dashLen = length; 302b7e1c893Smrg info->accel_state->dashPattern = pat; 303209ff23fSmrg 304209ff23fSmrg#if X_BYTE_ORDER == X_BIG_ENDIAN 305209ff23fSmrg# define PAT_SHIFT(pat, shift) (pat >> shift) 306209ff23fSmrg#else 307209ff23fSmrg# define PAT_SHIFT(pat, shift) (pat << shift) 308209ff23fSmrg#endif 309209ff23fSmrg 310209ff23fSmrg switch (length) { 311209ff23fSmrg case 2: pat |= PAT_SHIFT(pat, 2); /* fall through */ 312209ff23fSmrg case 4: pat |= PAT_SHIFT(pat, 4); /* fall through */ 313209ff23fSmrg case 8: pat |= PAT_SHIFT(pat, 8); /* fall through */ 314209ff23fSmrg case 16: pat |= PAT_SHIFT(pat, 16); 315209ff23fSmrg } 316209ff23fSmrg 317209ff23fSmrg /* Save for later clipping */ 318b7e1c893Smrg info->accel_state->dp_gui_master_cntl_clip = (info->accel_state->dp_gui_master_cntl 319b7e1c893Smrg | (bg == -1 320b7e1c893Smrg ? RADEON_GMC_BRUSH_32x1_MONO_FG_LA 321b7e1c893Smrg : RADEON_GMC_BRUSH_32x1_MONO_FG_BG) 322b7e1c893Smrg | RADEON_ROP[rop].pattern 323b7e1c893Smrg | RADEON_GMC_BYTE_LSB_TO_MSB); 324b7e1c893Smrg info->accel_state->dash_fg = fg; 325b7e1c893Smrg info->accel_state->dash_bg = bg; 326209ff23fSmrg 327209ff23fSmrg BEGIN_ACCEL((bg == -1) ? 4 : 5); 328209ff23fSmrg 329b7e1c893Smrg OUT_ACCEL_REG(RADEON_DP_GUI_MASTER_CNTL, info->accel_state->dp_gui_master_cntl_clip); 330209ff23fSmrg OUT_ACCEL_REG(RADEON_DP_WRITE_MASK, planemask); 331209ff23fSmrg OUT_ACCEL_REG(RADEON_DP_BRUSH_FRGD_CLR, fg); 332209ff23fSmrg if (bg != -1) 333209ff23fSmrg OUT_ACCEL_REG(RADEON_DP_BRUSH_BKGD_CLR, bg); 334209ff23fSmrg OUT_ACCEL_REG(RADEON_BRUSH_DATA0, pat); 335209ff23fSmrg 336209ff23fSmrg FINISH_ACCEL(); 337209ff23fSmrg BEGIN_ACCEL(2); 338209ff23fSmrg OUT_ACCEL_REG(RADEON_DSTCACHE_CTLSTAT, RADEON_RB2D_DC_FLUSH_ALL); 339209ff23fSmrg OUT_ACCEL_REG(RADEON_WAIT_UNTIL, 340209ff23fSmrg RADEON_WAIT_2D_IDLECLEAN | RADEON_WAIT_DMA_GUI_IDLE); 341209ff23fSmrg FINISH_ACCEL(); 342209ff23fSmrg} 343209ff23fSmrg 344209ff23fSmrg/* Helper function to draw last point for dashed lines */ 345209ff23fSmrgstatic void 346209ff23fSmrgFUNC_NAME(RADEONDashedLastPel)(ScrnInfoPtr pScrn, 347209ff23fSmrg int x, int y, 348209ff23fSmrg int fg) 349209ff23fSmrg{ 350209ff23fSmrg RADEONInfoPtr info = RADEONPTR(pScrn); 351b7e1c893Smrg uint32_t dp_gui_master_cntl = info->accel_state->dp_gui_master_cntl_clip; 352209ff23fSmrg ACCEL_PREAMBLE(); 353209ff23fSmrg 354209ff23fSmrg dp_gui_master_cntl &= ~RADEON_GMC_BRUSH_DATATYPE_MASK; 355209ff23fSmrg dp_gui_master_cntl |= RADEON_GMC_BRUSH_SOLID_COLOR; 356209ff23fSmrg 357209ff23fSmrg dp_gui_master_cntl &= ~RADEON_GMC_SRC_DATATYPE_MASK; 358209ff23fSmrg dp_gui_master_cntl |= RADEON_GMC_SRC_DATATYPE_COLOR; 359209ff23fSmrg 360209ff23fSmrg BEGIN_ACCEL(8); 361209ff23fSmrg 362209ff23fSmrg OUT_ACCEL_REG(RADEON_DP_GUI_MASTER_CNTL, dp_gui_master_cntl); 363209ff23fSmrg OUT_ACCEL_REG(RADEON_DP_CNTL, (RADEON_DST_X_LEFT_TO_RIGHT 364209ff23fSmrg | RADEON_DST_Y_TOP_TO_BOTTOM)); 365b7e1c893Smrg OUT_ACCEL_REG(RADEON_DST_PITCH_OFFSET, info->accel_state->dst_pitch_offset | 366209ff23fSmrg ((info->tilingEnabled && (y <= pScrn->virtualY)) ? RADEON_DST_TILE_MACRO : 0)); 367209ff23fSmrg OUT_ACCEL_REG(RADEON_DP_BRUSH_FRGD_CLR, fg); 368209ff23fSmrg OUT_ACCEL_REG(RADEON_DST_Y_X, (y << 16) | x); 369209ff23fSmrg OUT_ACCEL_REG(RADEON_DST_WIDTH_HEIGHT, (1 << 16) | 1); 370209ff23fSmrg 371209ff23fSmrg /* Restore old values */ 372b7e1c893Smrg OUT_ACCEL_REG(RADEON_DP_GUI_MASTER_CNTL, info->accel_state->dp_gui_master_cntl_clip); 373b7e1c893Smrg OUT_ACCEL_REG(RADEON_DP_BRUSH_FRGD_CLR, info->accel_state->dash_fg); 374209ff23fSmrg 375209ff23fSmrg FINISH_ACCEL(); 376209ff23fSmrg BEGIN_ACCEL(2); 377209ff23fSmrg OUT_ACCEL_REG(RADEON_DSTCACHE_CTLSTAT, RADEON_RB2D_DC_FLUSH_ALL); 378209ff23fSmrg OUT_ACCEL_REG(RADEON_WAIT_UNTIL, 379209ff23fSmrg RADEON_WAIT_2D_IDLECLEAN | RADEON_WAIT_DMA_GUI_IDLE); 380209ff23fSmrg FINISH_ACCEL(); 381209ff23fSmrg} 382209ff23fSmrg 383209ff23fSmrg/* Subsequent XAA dashed line */ 384209ff23fSmrgstatic void 385209ff23fSmrgFUNC_NAME(RADEONSubsequentDashedTwoPointLine)(ScrnInfoPtr pScrn, 386209ff23fSmrg int xa, int ya, 387209ff23fSmrg int xb, int yb, 388209ff23fSmrg int flags, 389209ff23fSmrg int phase) 390209ff23fSmrg{ 391209ff23fSmrg RADEONInfoPtr info = RADEONPTR(pScrn); 392209ff23fSmrg ACCEL_PREAMBLE(); 393209ff23fSmrg 394209ff23fSmrg /* TODO: Check bounds -- RADEON only has 14 bits */ 395209ff23fSmrg 396209ff23fSmrg if (!(flags & OMIT_LAST)) { 397209ff23fSmrg int deltax = abs(xa - xb); 398209ff23fSmrg int deltay = abs(ya - yb); 399209ff23fSmrg int shift; 400209ff23fSmrg 401209ff23fSmrg if (deltax > deltay) shift = deltax; 402209ff23fSmrg else shift = deltay; 403209ff23fSmrg 404209ff23fSmrg shift += phase; 405b7e1c893Smrg shift %= info->accel_state->dashLen; 406209ff23fSmrg 407b7e1c893Smrg if ((info->accel_state->dashPattern >> shift) & 1) 408b7e1c893Smrg FUNC_NAME(RADEONDashedLastPel)(pScrn, xb, yb, info->accel_state->dash_fg); 409b7e1c893Smrg else if (info->accel_state->dash_bg != -1) 410b7e1c893Smrg FUNC_NAME(RADEONDashedLastPel)(pScrn, xb, yb, info->accel_state->dash_bg); 411209ff23fSmrg } 412209ff23fSmrg 413209ff23fSmrg BEGIN_ACCEL(4); 414209ff23fSmrg 415b7e1c893Smrg OUT_ACCEL_REG(RADEON_DST_PITCH_OFFSET, info->accel_state->dst_pitch_offset | 416209ff23fSmrg ((info->tilingEnabled && (ya <= pScrn->virtualY)) ? RADEON_DST_TILE_MACRO : 0)); 417209ff23fSmrg OUT_ACCEL_REG(RADEON_DST_LINE_START, (ya << 16) | xa); 418209ff23fSmrg OUT_ACCEL_REG(RADEON_DST_LINE_PATCOUNT, phase); 419209ff23fSmrg OUT_ACCEL_REG(RADEON_DST_LINE_END, (yb << 16) | xb); 420209ff23fSmrg 421209ff23fSmrg FINISH_ACCEL(); 422209ff23fSmrg} 423209ff23fSmrg 424209ff23fSmrg/* Set up for transparency 425209ff23fSmrg * 426209ff23fSmrg * Mmmm, Seems as though the transparency compare is opposite to r128. 427209ff23fSmrg * It should only draw when source != trans_color, this is the opposite 428209ff23fSmrg * of that. 429209ff23fSmrg */ 430209ff23fSmrgstatic void 431209ff23fSmrgFUNC_NAME(RADEONSetTransparency)(ScrnInfoPtr pScrn, 432209ff23fSmrg int trans_color) 433209ff23fSmrg{ 434209ff23fSmrg RADEONInfoPtr info = RADEONPTR(pScrn); 435209ff23fSmrg 436b7e1c893Smrg if ((trans_color != -1) || (info->accel_state->XAAForceTransBlit == TRUE)) { 437209ff23fSmrg ACCEL_PREAMBLE(); 438209ff23fSmrg 439209ff23fSmrg BEGIN_ACCEL(3); 440209ff23fSmrg 441209ff23fSmrg OUT_ACCEL_REG(RADEON_CLR_CMP_CLR_SRC, trans_color); 442209ff23fSmrg OUT_ACCEL_REG(RADEON_CLR_CMP_MASK, RADEON_CLR_CMP_MSK); 443209ff23fSmrg OUT_ACCEL_REG(RADEON_CLR_CMP_CNTL, (RADEON_SRC_CMP_EQ_COLOR 444209ff23fSmrg | RADEON_CLR_CMP_SRC_SOURCE)); 445209ff23fSmrg 446209ff23fSmrg FINISH_ACCEL(); 447209ff23fSmrg } 448209ff23fSmrg} 449209ff23fSmrg 450209ff23fSmrg/* Setup for XAA screen-to-screen copy 451209ff23fSmrg * 452209ff23fSmrg * Tests: xtest CH06/fllrctngl (also tests transparency) 453209ff23fSmrg */ 454209ff23fSmrgstatic void 455209ff23fSmrgFUNC_NAME(RADEONSetupForScreenToScreenCopy)(ScrnInfoPtr pScrn, 456209ff23fSmrg int xdir, int ydir, 457209ff23fSmrg int rop, 458209ff23fSmrg unsigned int planemask, 459209ff23fSmrg int trans_color) 460209ff23fSmrg{ 461209ff23fSmrg RADEONInfoPtr info = RADEONPTR(pScrn); 462209ff23fSmrg ACCEL_PREAMBLE(); 463209ff23fSmrg 464b7e1c893Smrg info->accel_state->xdir = xdir; 465b7e1c893Smrg info->accel_state->ydir = ydir; 466209ff23fSmrg 467209ff23fSmrg /* Save for later clipping */ 468b7e1c893Smrg info->accel_state->dp_gui_master_cntl_clip = (info->accel_state->dp_gui_master_cntl 469b7e1c893Smrg | RADEON_GMC_BRUSH_NONE 470b7e1c893Smrg | RADEON_GMC_SRC_DATATYPE_COLOR 471b7e1c893Smrg | RADEON_ROP[rop].rop 472b7e1c893Smrg | RADEON_DP_SRC_SOURCE_MEMORY 473b7e1c893Smrg | RADEON_GMC_SRC_PITCH_OFFSET_CNTL); 474209ff23fSmrg 475209ff23fSmrg BEGIN_ACCEL(3); 476209ff23fSmrg 477b7e1c893Smrg OUT_ACCEL_REG(RADEON_DP_GUI_MASTER_CNTL, info->accel_state->dp_gui_master_cntl_clip); 478209ff23fSmrg OUT_ACCEL_REG(RADEON_DP_WRITE_MASK, planemask); 479209ff23fSmrg OUT_ACCEL_REG(RADEON_DP_CNTL, 480209ff23fSmrg ((xdir >= 0 ? RADEON_DST_X_LEFT_TO_RIGHT : 0) | 481209ff23fSmrg (ydir >= 0 ? RADEON_DST_Y_TOP_TO_BOTTOM : 0))); 482209ff23fSmrg 483209ff23fSmrg FINISH_ACCEL(); 484209ff23fSmrg BEGIN_ACCEL(2); 485209ff23fSmrg OUT_ACCEL_REG(RADEON_DSTCACHE_CTLSTAT, RADEON_RB2D_DC_FLUSH_ALL); 486209ff23fSmrg OUT_ACCEL_REG(RADEON_WAIT_UNTIL, 487209ff23fSmrg RADEON_WAIT_2D_IDLECLEAN | RADEON_WAIT_DMA_GUI_IDLE); 488209ff23fSmrg FINISH_ACCEL(); 489209ff23fSmrg 490b7e1c893Smrg info->accel_state->trans_color = trans_color; 491209ff23fSmrg FUNC_NAME(RADEONSetTransparency)(pScrn, trans_color); 492209ff23fSmrg} 493209ff23fSmrg 494209ff23fSmrg/* Subsequent XAA screen-to-screen copy */ 495209ff23fSmrgstatic void 496209ff23fSmrgFUNC_NAME(RADEONSubsequentScreenToScreenCopy)(ScrnInfoPtr pScrn, 497209ff23fSmrg int xa, int ya, 498209ff23fSmrg int xb, int yb, 499209ff23fSmrg int w, int h) 500209ff23fSmrg{ 501209ff23fSmrg RADEONInfoPtr info = RADEONPTR(pScrn); 502209ff23fSmrg ACCEL_PREAMBLE(); 503209ff23fSmrg 504b7e1c893Smrg if (info->accel_state->xdir < 0) xa += w - 1, xb += w - 1; 505b7e1c893Smrg if (info->accel_state->ydir < 0) ya += h - 1, yb += h - 1; 506209ff23fSmrg 507209ff23fSmrg BEGIN_ACCEL(5); 508209ff23fSmrg 509b7e1c893Smrg OUT_ACCEL_REG(RADEON_SRC_PITCH_OFFSET, info->accel_state->dst_pitch_offset | 510209ff23fSmrg ((info->tilingEnabled && (ya <= pScrn->virtualY)) ? RADEON_DST_TILE_MACRO : 0)); 511b7e1c893Smrg OUT_ACCEL_REG(RADEON_DST_PITCH_OFFSET, info->accel_state->dst_pitch_offset | 512209ff23fSmrg ((info->tilingEnabled && (yb <= pScrn->virtualY)) ? RADEON_DST_TILE_MACRO : 0)); 513209ff23fSmrg OUT_ACCEL_REG(RADEON_SRC_Y_X, (ya << 16) | xa); 514209ff23fSmrg OUT_ACCEL_REG(RADEON_DST_Y_X, (yb << 16) | xb); 515209ff23fSmrg OUT_ACCEL_REG(RADEON_DST_HEIGHT_WIDTH, (h << 16) | w); 516209ff23fSmrg 517209ff23fSmrg FINISH_ACCEL(); 518209ff23fSmrg} 519209ff23fSmrg 520209ff23fSmrg/* Setup for XAA mono 8x8 pattern color expansion. Patterns with 521209ff23fSmrg * transparency use `bg == -1'. This routine is only used if the XAA 522209ff23fSmrg * pixmap cache is turned on. 523209ff23fSmrg * 524209ff23fSmrg * Tests: xtest XFree86/fllrctngl (no other test will test this routine with 525209ff23fSmrg * both transparency and non-transparency) 526209ff23fSmrg */ 527209ff23fSmrgstatic void 528209ff23fSmrgFUNC_NAME(RADEONSetupForMono8x8PatternFill)(ScrnInfoPtr pScrn, 529209ff23fSmrg int patternx, 530209ff23fSmrg int patterny, 531209ff23fSmrg int fg, 532209ff23fSmrg int bg, 533209ff23fSmrg int rop, 534209ff23fSmrg unsigned int planemask) 535209ff23fSmrg{ 536209ff23fSmrg RADEONInfoPtr info = RADEONPTR(pScrn); 537209ff23fSmrg#if X_BYTE_ORDER == X_BIG_ENDIAN 538209ff23fSmrg unsigned char pattern[8]; 539209ff23fSmrg#endif 540209ff23fSmrg ACCEL_PREAMBLE(); 541209ff23fSmrg 542209ff23fSmrg#if X_BYTE_ORDER == X_BIG_ENDIAN 543209ff23fSmrg /* Take care of endianness */ 544209ff23fSmrg pattern[0] = (patternx & 0x000000ff); 545209ff23fSmrg pattern[1] = (patternx & 0x0000ff00) >> 8; 546209ff23fSmrg pattern[2] = (patternx & 0x00ff0000) >> 16; 547209ff23fSmrg pattern[3] = (patternx & 0xff000000) >> 24; 548209ff23fSmrg pattern[4] = (patterny & 0x000000ff); 549209ff23fSmrg pattern[5] = (patterny & 0x0000ff00) >> 8; 550209ff23fSmrg pattern[6] = (patterny & 0x00ff0000) >> 16; 551209ff23fSmrg pattern[7] = (patterny & 0xff000000) >> 24; 552209ff23fSmrg#endif 553209ff23fSmrg 554209ff23fSmrg /* Save for later clipping */ 555b7e1c893Smrg info->accel_state->dp_gui_master_cntl_clip = (info->accel_state->dp_gui_master_cntl 556b7e1c893Smrg | (bg == -1 557b7e1c893Smrg ? RADEON_GMC_BRUSH_8X8_MONO_FG_LA 558b7e1c893Smrg : RADEON_GMC_BRUSH_8X8_MONO_FG_BG) 559b7e1c893Smrg | RADEON_ROP[rop].pattern 560209ff23fSmrg#if X_BYTE_ORDER == X_LITTLE_ENDIAN 561b7e1c893Smrg | RADEON_GMC_BYTE_MSB_TO_LSB 562209ff23fSmrg#endif 563b7e1c893Smrg ); 564209ff23fSmrg 565209ff23fSmrg BEGIN_ACCEL((bg == -1) ? 5 : 6); 566209ff23fSmrg 567b7e1c893Smrg OUT_ACCEL_REG(RADEON_DP_GUI_MASTER_CNTL, info->accel_state->dp_gui_master_cntl_clip); 568209ff23fSmrg OUT_ACCEL_REG(RADEON_DP_WRITE_MASK, planemask); 569209ff23fSmrg OUT_ACCEL_REG(RADEON_DP_BRUSH_FRGD_CLR, fg); 570209ff23fSmrg if (bg != -1) 571209ff23fSmrg OUT_ACCEL_REG(RADEON_DP_BRUSH_BKGD_CLR, bg); 572209ff23fSmrg#if X_BYTE_ORDER == X_LITTLE_ENDIAN 573209ff23fSmrg OUT_ACCEL_REG(RADEON_BRUSH_DATA0, patternx); 574209ff23fSmrg OUT_ACCEL_REG(RADEON_BRUSH_DATA1, patterny); 575209ff23fSmrg#else 576209ff23fSmrg OUT_ACCEL_REG(RADEON_BRUSH_DATA0, *(uint32_t *)(pointer)&pattern[0]); 577209ff23fSmrg OUT_ACCEL_REG(RADEON_BRUSH_DATA1, *(uint32_t *)(pointer)&pattern[4]); 578209ff23fSmrg#endif 579209ff23fSmrg 580209ff23fSmrg FINISH_ACCEL(); 581209ff23fSmrg BEGIN_ACCEL(2); 582209ff23fSmrg OUT_ACCEL_REG(RADEON_DSTCACHE_CTLSTAT, RADEON_RB2D_DC_FLUSH_ALL); 583209ff23fSmrg OUT_ACCEL_REG(RADEON_WAIT_UNTIL, 584209ff23fSmrg RADEON_WAIT_2D_IDLECLEAN | RADEON_WAIT_DMA_GUI_IDLE); 585209ff23fSmrg FINISH_ACCEL(); 586209ff23fSmrg} 587209ff23fSmrg 588209ff23fSmrg/* Subsequent XAA 8x8 pattern color expansion. Because they are used in 589209ff23fSmrg * the setup function, `patternx' and `patterny' are not used here. 590209ff23fSmrg */ 591209ff23fSmrgstatic void 592209ff23fSmrgFUNC_NAME(RADEONSubsequentMono8x8PatternFillRect)(ScrnInfoPtr pScrn, 593209ff23fSmrg int patternx, 594209ff23fSmrg int patterny, 595209ff23fSmrg int x, int y, 596209ff23fSmrg int w, int h) 597209ff23fSmrg{ 598209ff23fSmrg RADEONInfoPtr info = RADEONPTR(pScrn); 599209ff23fSmrg ACCEL_PREAMBLE(); 600209ff23fSmrg 601209ff23fSmrg BEGIN_ACCEL(4); 602209ff23fSmrg 603b7e1c893Smrg OUT_ACCEL_REG(RADEON_DST_PITCH_OFFSET, info->accel_state->dst_pitch_offset | 604209ff23fSmrg ((info->tilingEnabled && (y <= pScrn->virtualY)) ? RADEON_DST_TILE_MACRO : 0)); 605209ff23fSmrg OUT_ACCEL_REG(RADEON_BRUSH_Y_X, (patterny << 8) | patternx); 606209ff23fSmrg OUT_ACCEL_REG(RADEON_DST_Y_X, (y << 16) | x); 607209ff23fSmrg OUT_ACCEL_REG(RADEON_DST_HEIGHT_WIDTH, (h << 16) | w); 608209ff23fSmrg 609209ff23fSmrg FINISH_ACCEL(); 610209ff23fSmrg} 611209ff23fSmrg 612209ff23fSmrg#if 0 613209ff23fSmrg/* Setup for XAA color 8x8 pattern fill 614209ff23fSmrg * 615209ff23fSmrg * Tests: xtest XFree86/fllrctngl (with Mono8x8PatternFill off) 616209ff23fSmrg */ 617209ff23fSmrgstatic void 618209ff23fSmrgFUNC_NAME(RADEONSetupForColor8x8PatternFill)(ScrnInfoPtr pScrn, 619209ff23fSmrg int patx, int paty, 620209ff23fSmrg int rop, 621209ff23fSmrg unsigned int planemask, 622209ff23fSmrg int trans_color) 623209ff23fSmrg{ 624209ff23fSmrg RADEONInfoPtr info = RADEONPTR(pScrn); 625209ff23fSmrg ACCEL_PREAMBLE(); 626209ff23fSmrg 627209ff23fSmrg /* Save for later clipping */ 628b7e1c893Smrg info->accel_state->dp_gui_master_cntl_clip = (info->accel_state->dp_gui_master_cntl 629b7e1c893Smrg | RADEON_GMC_BRUSH_8x8_COLOR 630b7e1c893Smrg | RADEON_GMC_SRC_DATATYPE_COLOR 631b7e1c893Smrg | RADEON_ROP[rop].pattern 632b7e1c893Smrg | RADEON_DP_SRC_SOURCE_MEMORY); 633209ff23fSmrg 634209ff23fSmrg BEGIN_ACCEL(3); 635209ff23fSmrg 636b7e1c893Smrg OUT_ACCEL_REG(RADEON_DP_GUI_MASTER_CNTL, info->accel_state->dp_gui_master_cntl_clip); 637209ff23fSmrg OUT_ACCEL_REG(RADEON_DP_WRITE_MASK, planemask); 638209ff23fSmrg OUT_ACCEL_REG(RADEON_SRC_Y_X, (paty << 16) | patx); 639209ff23fSmrg 640209ff23fSmrg FINISH_ACCEL(); 641209ff23fSmrg 642b7e1c893Smrg info->accel_state->trans_color = trans_color; 643209ff23fSmrg FUNC_NAME(RADEONSetTransparency)(pScrn, trans_color); 644209ff23fSmrg} 645209ff23fSmrg 646209ff23fSmrg/* Subsequent XAA 8x8 pattern color expansion */ 647209ff23fSmrgstatic void 648209ff23fSmrgFUNC_NAME(RADEONSubsequentColor8x8PatternFillRect)(ScrnInfoPtr pScrn, 649209ff23fSmrg int patx, int paty, 650209ff23fSmrg int x, int y, 651209ff23fSmrg int w, int h) 652209ff23fSmrg{ 653209ff23fSmrg RADEONInfoPtr info = RADEONPTR(pScrn); 654209ff23fSmrg ACCEL_PREAMBLE(); 655209ff23fSmrg 656209ff23fSmrg BEGIN_ACCEL(4); 657209ff23fSmrg 658b7e1c893Smrg OUT_ACCEL_REG(RADEON_DST_PITCH_OFFSET, info->accel_state->dst_pitch_offset | 659209ff23fSmrg ((info->tilingEnabled && (y <= pScrn->virtualY)) ? RADEON_DST_TILE_MACRO : 0)); 660209ff23fSmrg OUT_ACCEL_REG(RADEON_BRUSH_Y_X, (paty << 16) | patx); 661209ff23fSmrg OUT_ACCEL_REG(RADEON_DST_Y_X, (y << 16) | x); 662209ff23fSmrg OUT_ACCEL_REG(RADEON_DST_HEIGHT_WIDTH, (h << 16) | w); 663209ff23fSmrg 664209ff23fSmrg FINISH_ACCEL(); 665209ff23fSmrg} 666209ff23fSmrg#endif 667209ff23fSmrg 668209ff23fSmrg#ifdef ACCEL_CP 669b7e1c893Smrg#define CP_BUFSIZE (info->cp->indirectBuffer->total/4-10) 670209ff23fSmrg 671209ff23fSmrg/* Helper function to write out a HOSTDATA_BLT packet into the indirect 672209ff23fSmrg * buffer and set the XAA scratch buffer address appropriately. 673209ff23fSmrg */ 674209ff23fSmrgstatic void 675209ff23fSmrgRADEONCPScanlinePacket(ScrnInfoPtr pScrn, int bufno) 676209ff23fSmrg{ 677209ff23fSmrg RADEONInfoPtr info = RADEONPTR(pScrn); 678b7e1c893Smrg int chunk_words = info->accel_state->scanline_hpass * info->accel_state->scanline_words; 679209ff23fSmrg ACCEL_PREAMBLE(); 680209ff23fSmrg 681209ff23fSmrg if (RADEON_VERBOSE) { 682209ff23fSmrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 683209ff23fSmrg "CPScanline Packet h=%d hpass=%d chunkwords=%d\n", 684b7e1c893Smrg info->accel_state->scanline_h, info->accel_state->scanline_hpass, chunk_words); 685209ff23fSmrg } 686209ff23fSmrg BEGIN_RING(chunk_words+10); 687209ff23fSmrg 688209ff23fSmrg OUT_RING(CP_PACKET3(RADEON_CP_PACKET3_CNTL_HOSTDATA_BLT,chunk_words+10-2)); 689b7e1c893Smrg OUT_RING(info->accel_state->dp_gui_master_cntl_clip); 690b7e1c893Smrg OUT_RING(info->accel_state->dst_pitch_offset | 691b7e1c893Smrg ((info->tilingEnabled && (info->accel_state->scanline_y <= pScrn->virtualY)) ? RADEON_DST_TILE_MACRO : 0)); 692b7e1c893Smrg OUT_RING((info->accel_state->scanline_y << 16) | 693b7e1c893Smrg (info->accel_state->scanline_x1clip & 0xffff)); 694b7e1c893Smrg OUT_RING(((info->accel_state->scanline_y+info->accel_state->scanline_hpass) << 16) | 695b7e1c893Smrg (info->accel_state->scanline_x2clip & 0xffff)); 696b7e1c893Smrg OUT_RING(info->accel_state->scanline_fg); 697b7e1c893Smrg OUT_RING(info->accel_state->scanline_bg); 698b7e1c893Smrg OUT_RING((info->accel_state->scanline_y << 16) | 699b7e1c893Smrg (info->accel_state->scanline_x & 0xffff)); 700b7e1c893Smrg OUT_RING((info->accel_state->scanline_hpass << 16) | 701b7e1c893Smrg (info->accel_state->scanline_w & 0xffff)); 702209ff23fSmrg OUT_RING(chunk_words); 703209ff23fSmrg 704b7e1c893Smrg info->accel_state->scratch_buffer[bufno] = (unsigned char *)&__head[__count]; 705209ff23fSmrg __count += chunk_words; 706209ff23fSmrg 707209ff23fSmrg /* The ring can only be advanced after the __head and __count have 708209ff23fSmrg been adjusted above */ 709209ff23fSmrg FINISH_ACCEL(); 710209ff23fSmrg 711b7e1c893Smrg info->accel_state->scanline_y += info->accel_state->scanline_hpass; 712b7e1c893Smrg info->accel_state->scanline_h -= info->accel_state->scanline_hpass; 713209ff23fSmrg} 714209ff23fSmrg#endif 715209ff23fSmrg 716209ff23fSmrg/* Setup for XAA indirect CPU-to-screen color expansion (indirect). 717209ff23fSmrg * Because of how the scratch buffer is initialized, this is really a 718209ff23fSmrg * mainstore-to-screen color expansion. Transparency is supported when 719209ff23fSmrg * `bg == -1'. 720209ff23fSmrg */ 721209ff23fSmrgstatic void 722209ff23fSmrgFUNC_NAME(RADEONSetupForScanlineCPUToScreenColorExpandFill)(ScrnInfoPtr pScrn, 723209ff23fSmrg int fg, 724209ff23fSmrg int bg, 725209ff23fSmrg int rop, 726209ff23fSmrg unsigned int 727209ff23fSmrg planemask) 728209ff23fSmrg{ 729209ff23fSmrg RADEONInfoPtr info = RADEONPTR(pScrn); 730209ff23fSmrg ACCEL_PREAMBLE(); 731209ff23fSmrg 732b7e1c893Smrg info->accel_state->scanline_bpp = 0; 733209ff23fSmrg 734209ff23fSmrg /* Save for later clipping */ 735b7e1c893Smrg info->accel_state->dp_gui_master_cntl_clip = (info->accel_state->dp_gui_master_cntl 736b7e1c893Smrg | RADEON_GMC_DST_CLIPPING 737b7e1c893Smrg | RADEON_GMC_BRUSH_NONE 738b7e1c893Smrg | (bg == -1 739b7e1c893Smrg ? RADEON_GMC_SRC_DATATYPE_MONO_FG_LA 740b7e1c893Smrg : RADEON_GMC_SRC_DATATYPE_MONO_FG_BG) 741b7e1c893Smrg | RADEON_ROP[rop].rop 742209ff23fSmrg#if X_BYTE_ORDER == X_LITTLE_ENDIAN 743b7e1c893Smrg | RADEON_GMC_BYTE_LSB_TO_MSB 744209ff23fSmrg#else 745b7e1c893Smrg | RADEON_GMC_BYTE_MSB_TO_LSB 746209ff23fSmrg#endif 747b7e1c893Smrg | RADEON_DP_SRC_SOURCE_HOST_DATA); 748209ff23fSmrg 749209ff23fSmrg#ifdef ACCEL_MMIO 750209ff23fSmrg 751209ff23fSmrg#if X_BYTE_ORDER == X_LITTLE_ENDIAN 752209ff23fSmrg BEGIN_ACCEL(4); 753209ff23fSmrg#else 754209ff23fSmrg BEGIN_ACCEL(5); 755209ff23fSmrg 756209ff23fSmrg OUT_ACCEL_REG(RADEON_RBBM_GUICNTL, RADEON_HOST_DATA_SWAP_NONE); 757209ff23fSmrg#endif 758b7e1c893Smrg OUT_ACCEL_REG(RADEON_DP_GUI_MASTER_CNTL, info->accel_state->dp_gui_master_cntl_clip); 759209ff23fSmrg OUT_ACCEL_REG(RADEON_DP_WRITE_MASK, planemask); 760209ff23fSmrg OUT_ACCEL_REG(RADEON_DP_SRC_FRGD_CLR, fg); 761209ff23fSmrg OUT_ACCEL_REG(RADEON_DP_SRC_BKGD_CLR, bg); 762209ff23fSmrg 763209ff23fSmrg#else /* ACCEL_CP */ 764209ff23fSmrg 765b7e1c893Smrg info->accel_state->scanline_fg = fg; 766b7e1c893Smrg info->accel_state->scanline_bg = bg; 767209ff23fSmrg 768209ff23fSmrg#if X_BYTE_ORDER == X_LITTLE_ENDIAN 769209ff23fSmrg BEGIN_ACCEL(1); 770209ff23fSmrg#else 771209ff23fSmrg if (info->ChipFamily < CHIP_FAMILY_R300) { 772209ff23fSmrg BEGIN_ACCEL(2); 773209ff23fSmrg 774209ff23fSmrg OUT_ACCEL_REG(RADEON_RBBM_GUICNTL, RADEON_HOST_DATA_SWAP_32BIT); 775209ff23fSmrg } else 776209ff23fSmrg BEGIN_ACCEL(1); 777209ff23fSmrg#endif 778209ff23fSmrg OUT_ACCEL_REG(RADEON_DP_WRITE_MASK, planemask); 779209ff23fSmrg 780209ff23fSmrg#endif 781209ff23fSmrg 782209ff23fSmrg FINISH_ACCEL(); 783209ff23fSmrg} 784209ff23fSmrg 785209ff23fSmrg/* Subsequent XAA indirect CPU-to-screen color expansion. This is only 786209ff23fSmrg * called once for each rectangle. 787209ff23fSmrg */ 788209ff23fSmrgstatic void 789209ff23fSmrgFUNC_NAME(RADEONSubsequentScanlineCPUToScreenColorExpandFill)(ScrnInfoPtr 790209ff23fSmrg pScrn, 791209ff23fSmrg int x, int y, 792209ff23fSmrg int w, int h, 793209ff23fSmrg int skipleft) 794209ff23fSmrg{ 795209ff23fSmrg RADEONInfoPtr info = RADEONPTR(pScrn); 796209ff23fSmrg#ifdef ACCEL_MMIO 797209ff23fSmrg ACCEL_PREAMBLE(); 798209ff23fSmrg 799b7e1c893Smrg info->accel_state->scanline_h = h; 800b7e1c893Smrg info->accel_state->scanline_words = (w + 31) >> 5; 801209ff23fSmrg 802209ff23fSmrg#ifdef __alpha__ 803209ff23fSmrg /* Always use indirect for Alpha */ 804209ff23fSmrg if (0) 805209ff23fSmrg#else 806b7e1c893Smrg if ((info->accel_state->scanline_words * h) <= 9) 807209ff23fSmrg#endif 808209ff23fSmrg { 809209ff23fSmrg /* Turn on direct for less than 9 dword colour expansion */ 810b7e1c893Smrg info->accel_state->scratch_buffer[0] = 811209ff23fSmrg (unsigned char *)(ADDRREG(RADEON_HOST_DATA_LAST) 812b7e1c893Smrg - (info->accel_state->scanline_words - 1)); 813b7e1c893Smrg info->accel_state->scanline_direct = 1; 814209ff23fSmrg } else { 815209ff23fSmrg /* Use indirect for anything else */ 816b7e1c893Smrg info->accel_state->scratch_buffer[0] = info->accel_state->scratch_save; 817b7e1c893Smrg info->accel_state->scanline_direct = 0; 818209ff23fSmrg } 819209ff23fSmrg 820b7e1c893Smrg BEGIN_ACCEL(5 + (info->accel_state->scanline_direct ? 821b7e1c893Smrg (info->accel_state->scanline_words * h) : 0)); 822209ff23fSmrg 823b7e1c893Smrg OUT_ACCEL_REG(RADEON_DST_PITCH_OFFSET, info->accel_state->dst_pitch_offset | 824209ff23fSmrg ((info->tilingEnabled && (y <= pScrn->virtualY)) ? RADEON_DST_TILE_MACRO : 0)); 825209ff23fSmrg OUT_ACCEL_REG(RADEON_SC_TOP_LEFT, (y << 16) | ((x+skipleft) 826209ff23fSmrg & 0xffff)); 827209ff23fSmrg OUT_ACCEL_REG(RADEON_SC_BOTTOM_RIGHT, ((y+h) << 16) | ((x+w) & 0xffff)); 828209ff23fSmrg OUT_ACCEL_REG(RADEON_DST_Y_X, (y << 16) | (x & 0xffff)); 829209ff23fSmrg /* Have to pad the width here and use clipping engine */ 830ad43ddacSmrg OUT_ACCEL_REG(RADEON_DST_HEIGHT_WIDTH, (h << 16) | RADEON_ALIGN(w, 32)); 831209ff23fSmrg 832209ff23fSmrg FINISH_ACCEL(); 833209ff23fSmrg 834209ff23fSmrg#else /* ACCEL_CP */ 835209ff23fSmrg 836b7e1c893Smrg info->accel_state->scanline_x = x; 837b7e1c893Smrg info->accel_state->scanline_y = y; 838209ff23fSmrg /* Have to pad the width here and use clipping engine */ 839ad43ddacSmrg info->accel_state->scanline_w = RADEON_ALIGN(w, 32); 840b7e1c893Smrg info->accel_state->scanline_h = h; 841209ff23fSmrg 842b7e1c893Smrg info->accel_state->scanline_x1clip = x + skipleft; 843b7e1c893Smrg info->accel_state->scanline_x2clip = x + w; 844209ff23fSmrg 845b7e1c893Smrg info->accel_state->scanline_words = info->accel_state->scanline_w / 32; 846b7e1c893Smrg info->accel_state->scanline_hpass = min(h,(CP_BUFSIZE/info->accel_state->scanline_words)); 847209ff23fSmrg 848209ff23fSmrg RADEONCPScanlinePacket(pScrn, 0); 849209ff23fSmrg 850209ff23fSmrg#endif 851209ff23fSmrg} 852209ff23fSmrg 853209ff23fSmrg/* Subsequent XAA indirect CPU-to-screen color expansion and indirect 854209ff23fSmrg * image write. This is called once for each scanline. 855209ff23fSmrg */ 856209ff23fSmrgstatic void 857209ff23fSmrgFUNC_NAME(RADEONSubsequentScanline)(ScrnInfoPtr pScrn, 858209ff23fSmrg int bufno) 859209ff23fSmrg{ 860209ff23fSmrg RADEONInfoPtr info = RADEONPTR(pScrn); 861209ff23fSmrg#ifdef ACCEL_MMIO 862b7e1c893Smrg uint32_t *p = (pointer)info->accel_state->scratch_buffer[bufno]; 863209ff23fSmrg int i; 864b7e1c893Smrg int left = info->accel_state->scanline_words; 865209ff23fSmrg volatile uint32_t *d; 866209ff23fSmrg ACCEL_PREAMBLE(); 867209ff23fSmrg 868b7e1c893Smrg if (info->accel_state->scanline_direct) return; 869209ff23fSmrg 870b7e1c893Smrg --info->accel_state->scanline_h; 871209ff23fSmrg 872209ff23fSmrg while (left) { 873209ff23fSmrg write_mem_barrier(); 874209ff23fSmrg if (left <= 8) { 875209ff23fSmrg /* Last scanline - finish write to DATA_LAST */ 876b7e1c893Smrg if (info->accel_state->scanline_h == 0) { 877209ff23fSmrg BEGIN_ACCEL(left); 878209ff23fSmrg /* Unrolling doesn't improve performance */ 879209ff23fSmrg for (d = ADDRREG(RADEON_HOST_DATA_LAST) - (left - 1); left; --left) 880209ff23fSmrg *d++ = *p++; 881209ff23fSmrg return; 882209ff23fSmrg } else { 883209ff23fSmrg BEGIN_ACCEL(left); 884209ff23fSmrg /* Unrolling doesn't improve performance */ 885209ff23fSmrg for (d = ADDRREG(RADEON_HOST_DATA7) - (left - 1); left; --left) 886209ff23fSmrg *d++ = *p++; 887209ff23fSmrg } 888209ff23fSmrg } else { 889209ff23fSmrg BEGIN_ACCEL(8); 890209ff23fSmrg /* Unrolling doesn't improve performance */ 891209ff23fSmrg for (d = ADDRREG(RADEON_HOST_DATA0), i = 0; i < 8; i++) 892209ff23fSmrg *d++ = *p++; 893209ff23fSmrg left -= 8; 894209ff23fSmrg } 895209ff23fSmrg } 896209ff23fSmrg 897209ff23fSmrg FINISH_ACCEL(); 898209ff23fSmrg 899209ff23fSmrg#else /* ACCEL_CP */ 900209ff23fSmrg 901209ff23fSmrg#if X_BYTE_ORDER == X_BIG_ENDIAN 902209ff23fSmrg if (info->ChipFamily >= CHIP_FAMILY_R300) { 903b7e1c893Smrg if (info->accel_state->scanline_bpp == 16) { 904b7e1c893Smrg RADEONCopySwap(info->accel_state->scratch_buffer[bufno], 905b7e1c893Smrg info->accel_state->scratch_buffer[bufno], 906b7e1c893Smrg info->accel_state->scanline_words << 2, 907209ff23fSmrg RADEON_HOST_DATA_SWAP_HDW); 908b7e1c893Smrg } else if (info->accel_state->scanline_bpp < 15) { 909b7e1c893Smrg RADEONCopySwap(info->accel_state->scratch_buffer[bufno], 910b7e1c893Smrg info->accel_state->scratch_buffer[bufno], 911b7e1c893Smrg info->accel_state->scanline_words << 2, 912209ff23fSmrg RADEON_HOST_DATA_SWAP_32BIT); 913209ff23fSmrg } 914209ff23fSmrg } 915209ff23fSmrg#endif 916209ff23fSmrg 917b7e1c893Smrg if (--info->accel_state->scanline_hpass) { 918b7e1c893Smrg info->accel_state->scratch_buffer[bufno] += 4 * info->accel_state->scanline_words; 919b7e1c893Smrg } else if (info->accel_state->scanline_h) { 920b7e1c893Smrg info->accel_state->scanline_hpass = 921b7e1c893Smrg min(info->accel_state->scanline_h,(CP_BUFSIZE/info->accel_state->scanline_words)); 922209ff23fSmrg RADEONCPScanlinePacket(pScrn, bufno); 923209ff23fSmrg } 924209ff23fSmrg 925209ff23fSmrg#endif 926209ff23fSmrg} 927209ff23fSmrg 928209ff23fSmrg/* Setup for XAA indirect image write */ 929209ff23fSmrgstatic void 930209ff23fSmrgFUNC_NAME(RADEONSetupForScanlineImageWrite)(ScrnInfoPtr pScrn, 931209ff23fSmrg int rop, 932209ff23fSmrg unsigned int planemask, 933209ff23fSmrg int trans_color, 934209ff23fSmrg int bpp, 935209ff23fSmrg int depth) 936209ff23fSmrg{ 937209ff23fSmrg RADEONInfoPtr info = RADEONPTR(pScrn); 938209ff23fSmrg ACCEL_PREAMBLE(); 939209ff23fSmrg 940b7e1c893Smrg info->accel_state->scanline_bpp = bpp; 941209ff23fSmrg 942209ff23fSmrg /* Save for later clipping */ 943b7e1c893Smrg info->accel_state->dp_gui_master_cntl_clip = (info->accel_state->dp_gui_master_cntl 944b7e1c893Smrg | RADEON_GMC_DST_CLIPPING 945b7e1c893Smrg | RADEON_GMC_BRUSH_NONE 946b7e1c893Smrg | RADEON_GMC_SRC_DATATYPE_COLOR 947b7e1c893Smrg | RADEON_ROP[rop].rop 948b7e1c893Smrg | RADEON_GMC_BYTE_MSB_TO_LSB 949b7e1c893Smrg | RADEON_DP_SRC_SOURCE_HOST_DATA); 950209ff23fSmrg 951209ff23fSmrg#ifdef ACCEL_MMIO 952209ff23fSmrg 953209ff23fSmrg#if X_BYTE_ORDER == X_LITTLE_ENDIAN 954209ff23fSmrg BEGIN_ACCEL(2); 955209ff23fSmrg#else 956209ff23fSmrg BEGIN_ACCEL(3); 957209ff23fSmrg 958209ff23fSmrg if (bpp == 16) 959209ff23fSmrg OUT_ACCEL_REG(RADEON_RBBM_GUICNTL, RADEON_HOST_DATA_SWAP_16BIT); 960209ff23fSmrg else if (bpp == 32) 961209ff23fSmrg OUT_ACCEL_REG(RADEON_RBBM_GUICNTL, RADEON_HOST_DATA_SWAP_32BIT); 962209ff23fSmrg else 963209ff23fSmrg OUT_ACCEL_REG(RADEON_RBBM_GUICNTL, RADEON_HOST_DATA_SWAP_NONE); 964209ff23fSmrg#endif 965b7e1c893Smrg OUT_ACCEL_REG(RADEON_DP_GUI_MASTER_CNTL, info->accel_state->dp_gui_master_cntl_clip); 966209ff23fSmrg 967209ff23fSmrg#else /* ACCEL_CP */ 968209ff23fSmrg 969209ff23fSmrg#if X_BYTE_ORDER == X_LITTLE_ENDIAN 970209ff23fSmrg BEGIN_ACCEL(1); 971209ff23fSmrg#else 972209ff23fSmrg if (info->ChipFamily < CHIP_FAMILY_R300) { 973209ff23fSmrg BEGIN_ACCEL(2); 974209ff23fSmrg 975209ff23fSmrg if (bpp == 16) 976209ff23fSmrg OUT_ACCEL_REG(RADEON_RBBM_GUICNTL, RADEON_HOST_DATA_SWAP_HDW); 977209ff23fSmrg else 978209ff23fSmrg OUT_ACCEL_REG(RADEON_RBBM_GUICNTL, RADEON_HOST_DATA_SWAP_NONE); 979209ff23fSmrg } else 980209ff23fSmrg BEGIN_ACCEL(1); 981209ff23fSmrg#endif 982209ff23fSmrg#endif 983209ff23fSmrg OUT_ACCEL_REG(RADEON_DP_WRITE_MASK, planemask); 984209ff23fSmrg 985209ff23fSmrg FINISH_ACCEL(); 986209ff23fSmrg 987b7e1c893Smrg info->accel_state->trans_color = trans_color; 988209ff23fSmrg FUNC_NAME(RADEONSetTransparency)(pScrn, trans_color); 989209ff23fSmrg} 990209ff23fSmrg 991209ff23fSmrg/* Subsequent XAA indirect image write. This is only called once for 992209ff23fSmrg * each rectangle. 993209ff23fSmrg */ 994209ff23fSmrgstatic void 995209ff23fSmrgFUNC_NAME(RADEONSubsequentScanlineImageWriteRect)(ScrnInfoPtr pScrn, 996209ff23fSmrg int x, int y, 997209ff23fSmrg int w, int h, 998209ff23fSmrg int skipleft) 999209ff23fSmrg{ 1000209ff23fSmrg RADEONInfoPtr info = RADEONPTR(pScrn); 1001209ff23fSmrg 1002209ff23fSmrg#ifdef ACCEL_MMIO 1003209ff23fSmrg 1004209ff23fSmrg int shift = 0; /* 32bpp */ 1005209ff23fSmrg ACCEL_PREAMBLE(); 1006209ff23fSmrg 1007209ff23fSmrg if (pScrn->bitsPerPixel == 8) shift = 3; 1008209ff23fSmrg else if (pScrn->bitsPerPixel == 16) shift = 1; 1009209ff23fSmrg 1010b7e1c893Smrg info->accel_state->scanline_h = h; 1011b7e1c893Smrg info->accel_state->scanline_words = (w * info->accel_state->scanline_bpp + 31) >> 5; 1012209ff23fSmrg 1013209ff23fSmrg#ifdef __alpha__ 1014209ff23fSmrg /* Always use indirect for Alpha */ 1015209ff23fSmrg if (0) 1016209ff23fSmrg#else 1017b7e1c893Smrg if ((info->accel_state->scanline_words * h) <= 9) 1018209ff23fSmrg#endif 1019209ff23fSmrg { 1020209ff23fSmrg /* Turn on direct for less than 9 dword colour expansion */ 1021b7e1c893Smrg info->accel_state->scratch_buffer[0] 1022209ff23fSmrg = (unsigned char *)(ADDRREG(RADEON_HOST_DATA_LAST) 1023b7e1c893Smrg - (info->accel_state->scanline_words - 1)); 1024b7e1c893Smrg info->accel_state->scanline_direct = 1; 1025209ff23fSmrg } else { 1026209ff23fSmrg /* Use indirect for anything else */ 1027b7e1c893Smrg info->accel_state->scratch_buffer[0] = info->accel_state->scratch_save; 1028b7e1c893Smrg info->accel_state->scanline_direct = 0; 1029209ff23fSmrg } 1030209ff23fSmrg 1031b7e1c893Smrg BEGIN_ACCEL(5 + (info->accel_state->scanline_direct ? 1032b7e1c893Smrg (info->accel_state->scanline_words * h) : 0)); 1033209ff23fSmrg 1034b7e1c893Smrg OUT_ACCEL_REG(RADEON_DST_PITCH_OFFSET, info->accel_state->dst_pitch_offset | 1035209ff23fSmrg ((info->tilingEnabled && (y <= pScrn->virtualY)) ? RADEON_DST_TILE_MACRO : 0)); 1036209ff23fSmrg OUT_ACCEL_REG(RADEON_SC_TOP_LEFT, (y << 16) | ((x+skipleft) 1037209ff23fSmrg & 0xffff)); 1038209ff23fSmrg OUT_ACCEL_REG(RADEON_SC_BOTTOM_RIGHT, ((y+h) << 16) | ((x+w) & 0xffff)); 1039209ff23fSmrg OUT_ACCEL_REG(RADEON_DST_Y_X, (y << 16) | (x & 0xffff)); 1040209ff23fSmrg /* Have to pad the width here and use clipping engine */ 1041209ff23fSmrg OUT_ACCEL_REG(RADEON_DST_HEIGHT_WIDTH, (h << 16) | ((w + shift) & 1042209ff23fSmrg ~shift)); 1043209ff23fSmrg 1044209ff23fSmrg FINISH_ACCEL(); 1045209ff23fSmrg 1046209ff23fSmrg#else /* ACCEL_CP */ 1047209ff23fSmrg 1048209ff23fSmrg int pad = 0; /* 32bpp */ 1049209ff23fSmrg 1050209ff23fSmrg if (pScrn->bitsPerPixel == 8) pad = 3; 1051209ff23fSmrg else if (pScrn->bitsPerPixel == 16) pad = 1; 1052209ff23fSmrg 1053b7e1c893Smrg info->accel_state->scanline_x = x; 1054b7e1c893Smrg info->accel_state->scanline_y = y; 1055209ff23fSmrg /* Have to pad the width here and use clipping engine */ 1056b7e1c893Smrg info->accel_state->scanline_w = (w + pad) & ~pad; 1057b7e1c893Smrg info->accel_state->scanline_h = h; 1058209ff23fSmrg 1059b7e1c893Smrg info->accel_state->scanline_x1clip = x + skipleft; 1060b7e1c893Smrg info->accel_state->scanline_x2clip = x + w; 1061209ff23fSmrg 1062b7e1c893Smrg info->accel_state->scanline_words = (w * info->accel_state->scanline_bpp + 31) / 32; 1063b7e1c893Smrg info->accel_state->scanline_hpass = min(h,(CP_BUFSIZE/info->accel_state->scanline_words)); 1064209ff23fSmrg 1065209ff23fSmrg RADEONCPScanlinePacket(pScrn, 0); 1066209ff23fSmrg 1067209ff23fSmrg#endif 1068209ff23fSmrg} 1069209ff23fSmrg 1070209ff23fSmrg/* Set up the clipping rectangle */ 1071209ff23fSmrgstatic void 1072209ff23fSmrgFUNC_NAME(RADEONSetClippingRectangle)(ScrnInfoPtr pScrn, 1073209ff23fSmrg int xa, int ya, 1074209ff23fSmrg int xb, int yb) 1075209ff23fSmrg{ 1076209ff23fSmrg RADEONInfoPtr info = RADEONPTR(pScrn); 1077209ff23fSmrg unsigned long tmp1 = 0; 1078209ff23fSmrg unsigned long tmp2 = 0; 1079209ff23fSmrg ACCEL_PREAMBLE(); 1080209ff23fSmrg 1081209ff23fSmrg if (xa < 0) { 1082209ff23fSmrg tmp1 = (-xa) & 0x3fff; 1083209ff23fSmrg tmp1 |= RADEON_SC_SIGN_MASK_LO; 1084209ff23fSmrg } else { 1085209ff23fSmrg tmp1 = xa; 1086209ff23fSmrg } 1087209ff23fSmrg 1088209ff23fSmrg if (ya < 0) { 1089209ff23fSmrg tmp1 |= (((-ya) & 0x3fff) << 16); 1090209ff23fSmrg tmp1 |= RADEON_SC_SIGN_MASK_HI; 1091209ff23fSmrg } else { 1092209ff23fSmrg tmp1 |= (ya << 16); 1093209ff23fSmrg } 1094209ff23fSmrg 1095209ff23fSmrg xb++; yb++; 1096209ff23fSmrg 1097209ff23fSmrg if (xb < 0) { 1098209ff23fSmrg tmp2 = (-xb) & 0x3fff; 1099209ff23fSmrg tmp2 |= RADEON_SC_SIGN_MASK_LO; 1100209ff23fSmrg } else { 1101209ff23fSmrg tmp2 = xb; 1102209ff23fSmrg } 1103209ff23fSmrg 1104209ff23fSmrg if (yb < 0) { 1105209ff23fSmrg tmp2 |= (((-yb) & 0x3fff) << 16); 1106209ff23fSmrg tmp2 |= RADEON_SC_SIGN_MASK_HI; 1107209ff23fSmrg } else { 1108209ff23fSmrg tmp2 |= (yb << 16); 1109209ff23fSmrg } 1110209ff23fSmrg 1111209ff23fSmrg BEGIN_ACCEL(3); 1112209ff23fSmrg 1113b7e1c893Smrg OUT_ACCEL_REG(RADEON_DP_GUI_MASTER_CNTL, (info->accel_state->dp_gui_master_cntl_clip 1114209ff23fSmrg | RADEON_GMC_DST_CLIPPING)); 1115209ff23fSmrg OUT_ACCEL_REG(RADEON_SC_TOP_LEFT, tmp1); 1116209ff23fSmrg OUT_ACCEL_REG(RADEON_SC_BOTTOM_RIGHT, tmp2); 1117209ff23fSmrg 1118209ff23fSmrg FINISH_ACCEL(); 1119209ff23fSmrg BEGIN_ACCEL(2); 1120209ff23fSmrg OUT_ACCEL_REG(RADEON_DSTCACHE_CTLSTAT, RADEON_RB2D_DC_FLUSH_ALL); 1121209ff23fSmrg OUT_ACCEL_REG(RADEON_WAIT_UNTIL, 1122209ff23fSmrg RADEON_WAIT_2D_IDLECLEAN | RADEON_WAIT_DMA_GUI_IDLE); 1123209ff23fSmrg FINISH_ACCEL(); 1124209ff23fSmrg 1125b7e1c893Smrg FUNC_NAME(RADEONSetTransparency)(pScrn, info->accel_state->trans_color); 1126209ff23fSmrg} 1127209ff23fSmrg 1128209ff23fSmrg/* Disable the clipping rectangle */ 1129209ff23fSmrgstatic void 1130209ff23fSmrgFUNC_NAME(RADEONDisableClipping)(ScrnInfoPtr pScrn) 1131209ff23fSmrg{ 1132209ff23fSmrg RADEONInfoPtr info = RADEONPTR(pScrn); 1133209ff23fSmrg ACCEL_PREAMBLE(); 1134209ff23fSmrg 1135209ff23fSmrg BEGIN_ACCEL(3); 1136209ff23fSmrg 1137b7e1c893Smrg OUT_ACCEL_REG(RADEON_DP_GUI_MASTER_CNTL, info->accel_state->dp_gui_master_cntl_clip); 1138209ff23fSmrg OUT_ACCEL_REG(RADEON_SC_TOP_LEFT, 0); 1139209ff23fSmrg OUT_ACCEL_REG(RADEON_SC_BOTTOM_RIGHT, (RADEON_DEFAULT_SC_RIGHT_MAX | 1140209ff23fSmrg RADEON_DEFAULT_SC_BOTTOM_MAX)); 1141209ff23fSmrg 1142209ff23fSmrg FINISH_ACCEL(); 1143209ff23fSmrg BEGIN_ACCEL(2); 1144209ff23fSmrg OUT_ACCEL_REG(RADEON_DSTCACHE_CTLSTAT, RADEON_RB2D_DC_FLUSH_ALL); 1145209ff23fSmrg OUT_ACCEL_REG(RADEON_WAIT_UNTIL, 1146209ff23fSmrg RADEON_WAIT_2D_IDLECLEAN | RADEON_WAIT_DMA_GUI_IDLE); 1147209ff23fSmrg FINISH_ACCEL(); 1148209ff23fSmrg 1149b7e1c893Smrg FUNC_NAME(RADEONSetTransparency)(pScrn, info->accel_state->trans_color); 1150209ff23fSmrg} 1151209ff23fSmrg 1152209ff23fSmrgvoid 1153209ff23fSmrgFUNC_NAME(RADEONAccelInit)(ScreenPtr pScreen, XAAInfoRecPtr a) 1154209ff23fSmrg{ 1155c135ecebSveego ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 1156209ff23fSmrg RADEONInfoPtr info = RADEONPTR(pScrn); 1157209ff23fSmrg 1158209ff23fSmrg a->Flags = (PIXMAP_CACHE 1159209ff23fSmrg | OFFSCREEN_PIXMAPS 1160209ff23fSmrg | LINEAR_FRAMEBUFFER); 1161209ff23fSmrg 1162209ff23fSmrg /* Sync */ 1163209ff23fSmrg a->Sync = FUNC_NAME(RADEONWaitForIdle); 1164209ff23fSmrg 1165209ff23fSmrg /* Solid Filled Rectangle */ 1166209ff23fSmrg a->PolyFillRectSolidFlags = 0; 1167209ff23fSmrg a->SetupForSolidFill 1168209ff23fSmrg = FUNC_NAME(RADEONSetupForSolidFill); 1169209ff23fSmrg a->SubsequentSolidFillRect 1170209ff23fSmrg = FUNC_NAME(RADEONSubsequentSolidFillRect); 1171209ff23fSmrg 1172209ff23fSmrg /* Screen-to-screen Copy */ 1173209ff23fSmrg a->ScreenToScreenCopyFlags = 0; 1174209ff23fSmrg a->SetupForScreenToScreenCopy 1175209ff23fSmrg = FUNC_NAME(RADEONSetupForScreenToScreenCopy); 1176209ff23fSmrg a->SubsequentScreenToScreenCopy 1177209ff23fSmrg = FUNC_NAME(RADEONSubsequentScreenToScreenCopy); 1178209ff23fSmrg 1179209ff23fSmrg /* Mono 8x8 Pattern Fill (Color Expand) */ 1180209ff23fSmrg a->SetupForMono8x8PatternFill 1181209ff23fSmrg = FUNC_NAME(RADEONSetupForMono8x8PatternFill); 1182209ff23fSmrg a->SubsequentMono8x8PatternFillRect 1183209ff23fSmrg = FUNC_NAME(RADEONSubsequentMono8x8PatternFillRect); 1184209ff23fSmrg a->Mono8x8PatternFillFlags = (HARDWARE_PATTERN_PROGRAMMED_BITS 1185209ff23fSmrg | HARDWARE_PATTERN_PROGRAMMED_ORIGIN 1186209ff23fSmrg | HARDWARE_PATTERN_SCREEN_ORIGIN); 1187209ff23fSmrg 1188209ff23fSmrg#if X_BYTE_ORDER == X_LITTLE_ENDIAN 1189209ff23fSmrg if (info->ChipFamily >= CHIP_FAMILY_RV200) 1190209ff23fSmrg a->Mono8x8PatternFillFlags |= BIT_ORDER_IN_BYTE_MSBFIRST; 1191209ff23fSmrg else 1192209ff23fSmrg a->Mono8x8PatternFillFlags |= BIT_ORDER_IN_BYTE_LSBFIRST; 1193209ff23fSmrg#else 1194209ff23fSmrg a->Mono8x8PatternFillFlags |= BIT_ORDER_IN_BYTE_LSBFIRST; 1195209ff23fSmrg#endif 1196209ff23fSmrg 1197209ff23fSmrg /* Indirect CPU-To-Screen Color Expand */ 1198209ff23fSmrg 1199209ff23fSmrg /* RADEON gets upset, when using HOST provided data without a source 1200209ff23fSmrg rop. To show run 'xtest's drwarc. */ 1201209ff23fSmrg a->ScanlineCPUToScreenColorExpandFillFlags 1202209ff23fSmrg = (LEFT_EDGE_CLIPPING 1203209ff23fSmrg | ROP_NEEDS_SOURCE 1204209ff23fSmrg | LEFT_EDGE_CLIPPING_NEGATIVE_X); 1205209ff23fSmrg a->NumScanlineColorExpandBuffers = 1; 1206b7e1c893Smrg a->ScanlineColorExpandBuffers = info->accel_state->scratch_buffer; 1207b7e1c893Smrg if (!info->accel_state->scratch_save) 1208b7e1c893Smrg info->accel_state->scratch_save 12092f39173dSmrg = malloc(((pScrn->virtualX+31)/32*4) 1210209ff23fSmrg + (pScrn->virtualX * info->CurrentLayout.pixel_bytes)); 1211b7e1c893Smrg info->accel_state->scratch_buffer[0] = info->accel_state->scratch_save; 1212209ff23fSmrg a->SetupForScanlineCPUToScreenColorExpandFill 1213209ff23fSmrg = FUNC_NAME(RADEONSetupForScanlineCPUToScreenColorExpandFill); 1214209ff23fSmrg a->SubsequentScanlineCPUToScreenColorExpandFill 1215209ff23fSmrg = FUNC_NAME(RADEONSubsequentScanlineCPUToScreenColorExpandFill); 1216209ff23fSmrg a->SubsequentColorExpandScanline 1217209ff23fSmrg = FUNC_NAME(RADEONSubsequentScanline); 1218209ff23fSmrg 1219209ff23fSmrg /* Solid Lines */ 1220209ff23fSmrg a->SetupForSolidLine 1221209ff23fSmrg = FUNC_NAME(RADEONSetupForSolidLine); 1222209ff23fSmrg a->SubsequentSolidHorVertLine 1223209ff23fSmrg = FUNC_NAME(RADEONSubsequentSolidHorVertLine); 1224209ff23fSmrg 1225209ff23fSmrg if (info->xaaReq.minorversion >= 1) { 1226209ff23fSmrg 1227209ff23fSmrg /* RADEON only supports 14 bits for lines and clipping and only 1228209ff23fSmrg * draws lines that are completely on-screen correctly. This will 1229209ff23fSmrg * cause display corruption problem in the cases when out-of-range 1230209ff23fSmrg * commands are issued, like when dimming screen during GNOME logout 1231209ff23fSmrg * in dual-head setup. Solid and dashed lines are therefore limited 1232209ff23fSmrg * to the virtual screen. 1233209ff23fSmrg */ 1234209ff23fSmrg 1235209ff23fSmrg a->SolidLineFlags = LINE_LIMIT_COORDS; 1236209ff23fSmrg a->SolidLineLimits.x1 = 0; 1237209ff23fSmrg a->SolidLineLimits.y1 = 0; 1238209ff23fSmrg a->SolidLineLimits.x2 = pScrn->virtualX-1; 1239209ff23fSmrg a->SolidLineLimits.y2 = pScrn->virtualY-1; 1240209ff23fSmrg 1241209ff23fSmrg /* Call miSetZeroLineBias() to have mi/mfb/fb routines match 1242209ff23fSmrg hardware accel two point lines */ 1243209ff23fSmrg miSetZeroLineBias(pScreen, (OCTANT5 | OCTANT6 | OCTANT7 | OCTANT8)); 1244209ff23fSmrg 1245209ff23fSmrg#ifdef ACCEL_CP 1246209ff23fSmrg /* RV280s lock up with this using the CP for reasons to be determined. 1247209ff23fSmrg * See https://bugs.freedesktop.org/show_bug.cgi?id=5986 . 1248209ff23fSmrg */ 1249209ff23fSmrg if (info->ChipFamily != CHIP_FAMILY_RV280) 1250209ff23fSmrg#endif 1251209ff23fSmrg a->SubsequentSolidTwoPointLine 1252209ff23fSmrg = FUNC_NAME(RADEONSubsequentSolidTwoPointLine); 1253209ff23fSmrg 1254209ff23fSmrg /* Disabled on RV200 and newer because it does not pass XTest */ 1255209ff23fSmrg if (info->ChipFamily < CHIP_FAMILY_RV200) { 1256209ff23fSmrg a->SetupForDashedLine 1257209ff23fSmrg = FUNC_NAME(RADEONSetupForDashedLine); 1258209ff23fSmrg a->SubsequentDashedTwoPointLine 1259209ff23fSmrg = FUNC_NAME(RADEONSubsequentDashedTwoPointLine); 1260209ff23fSmrg a->DashPatternMaxLength = 32; 1261209ff23fSmrg /* ROP3 doesn't seem to work properly for dashedline with GXinvert */ 1262209ff23fSmrg a->DashedLineFlags = (LINE_PATTERN_LSBFIRST_LSBJUSTIFIED 1263209ff23fSmrg | LINE_PATTERN_POWER_OF_2_ONLY 1264209ff23fSmrg | LINE_LIMIT_COORDS 1265209ff23fSmrg | ROP_NEEDS_SOURCE); 1266209ff23fSmrg a->DashedLineLimits.x1 = 0; 1267209ff23fSmrg a->DashedLineLimits.y1 = 0; 1268209ff23fSmrg a->DashedLineLimits.x2 = pScrn->virtualX-1; 1269209ff23fSmrg a->DashedLineLimits.y2 = pScrn->virtualY-1; 1270209ff23fSmrg } 1271209ff23fSmrg 1272209ff23fSmrg } else { 1273209ff23fSmrg xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 1274209ff23fSmrg "libxaa too old, can't accelerate TwoPoint lines\n"); 1275209ff23fSmrg } 1276209ff23fSmrg 1277209ff23fSmrg /* Clipping, note that without this, all line accelerations will 1278209ff23fSmrg * not be called 1279209ff23fSmrg */ 1280209ff23fSmrg a->SetClippingRectangle 1281209ff23fSmrg = FUNC_NAME(RADEONSetClippingRectangle); 1282209ff23fSmrg a->DisableClipping 1283209ff23fSmrg = FUNC_NAME(RADEONDisableClipping); 1284209ff23fSmrg a->ClippingFlags 1285209ff23fSmrg = (HARDWARE_CLIP_SOLID_LINE 1286209ff23fSmrg | HARDWARE_CLIP_DASHED_LINE 1287209ff23fSmrg /* | HARDWARE_CLIP_SOLID_FILL -- seems very slow with this on */ 1288209ff23fSmrg | HARDWARE_CLIP_MONO_8x8_FILL 1289209ff23fSmrg | HARDWARE_CLIP_SCREEN_TO_SCREEN_COPY); 1290209ff23fSmrg 1291209ff23fSmrg if (xf86IsEntityShared(info->pEnt->index)) { 1292209ff23fSmrg /* If there are more than one devices sharing this entity, we 1293209ff23fSmrg * have to assign this call back, otherwise the XAA will be 1294209ff23fSmrg * disabled 1295209ff23fSmrg */ 1296209ff23fSmrg if (xf86GetNumEntityInstances(info->pEnt->index) > 1) 1297209ff23fSmrg a->RestoreAccelState = FUNC_NAME(RADEONRestoreAccelState); 1298209ff23fSmrg } 1299209ff23fSmrg 1300209ff23fSmrg /* ImageWrite */ 1301209ff23fSmrg a->NumScanlineImageWriteBuffers = 1; 1302b7e1c893Smrg a->ScanlineImageWriteBuffers = info->accel_state->scratch_buffer; 1303209ff23fSmrg a->SetupForScanlineImageWrite 1304209ff23fSmrg = FUNC_NAME(RADEONSetupForScanlineImageWrite); 1305209ff23fSmrg a->SubsequentScanlineImageWriteRect 1306209ff23fSmrg = FUNC_NAME(RADEONSubsequentScanlineImageWriteRect); 1307209ff23fSmrg a->SubsequentImageWriteScanline = FUNC_NAME(RADEONSubsequentScanline); 1308209ff23fSmrg a->ScanlineImageWriteFlags = (CPU_TRANSFER_PAD_DWORD 1309209ff23fSmrg#ifdef ACCEL_MMIO 1310209ff23fSmrg /* Performance tests show that we shouldn't use GXcopy 1311209ff23fSmrg * for uploads as a memcpy is faster 1312209ff23fSmrg */ 1313209ff23fSmrg | NO_GXCOPY 1314209ff23fSmrg#endif 1315209ff23fSmrg /* RADEON gets upset, when using HOST provided data 1316209ff23fSmrg * without a source rop. To show run 'xtest's ptimg 1317209ff23fSmrg */ 1318209ff23fSmrg | ROP_NEEDS_SOURCE 1319209ff23fSmrg | SCANLINE_PAD_DWORD 1320209ff23fSmrg | LEFT_EDGE_CLIPPING 1321209ff23fSmrg | LEFT_EDGE_CLIPPING_NEGATIVE_X); 1322209ff23fSmrg 1323209ff23fSmrg#if 0 1324209ff23fSmrg /* Color 8x8 Pattern Fill */ 1325209ff23fSmrg a->SetupForColor8x8PatternFill 1326209ff23fSmrg = FUNC_NAME(RADEONSetupForColor8x8PatternFill); 1327209ff23fSmrg a->SubsequentColor8x8PatternFillRect 1328209ff23fSmrg = FUNC_NAME(RADEONSubsequentColor8x8PatternFillRect); 1329209ff23fSmrg a->Color8x8PatternFillFlags = (HARDWARE_PATTERN_PROGRAMMED_ORIGIN 1330209ff23fSmrg | HARDWARE_PATTERN_SCREEN_ORIGIN 1331209ff23fSmrg | BIT_ORDER_IN_BYTE_LSBFIRST); 1332209ff23fSmrg#endif 1333209ff23fSmrg 1334209ff23fSmrg#ifdef RENDER 1335209ff23fSmrg if (info->RenderAccel && info->xaaReq.minorversion >= 2) { 1336209ff23fSmrg 1337209ff23fSmrg a->CPUToScreenAlphaTextureFlags = XAA_RENDER_POWER_OF_2_TILE_ONLY; 1338209ff23fSmrg a->CPUToScreenAlphaTextureFormats = RADEONTextureFormats; 1339209ff23fSmrg a->CPUToScreenAlphaTextureDstFormats = RADEONDstFormats; 1340209ff23fSmrg a->CPUToScreenTextureFlags = XAA_RENDER_POWER_OF_2_TILE_ONLY; 1341209ff23fSmrg a->CPUToScreenTextureFormats = RADEONTextureFormats; 1342209ff23fSmrg a->CPUToScreenTextureDstFormats = RADEONDstFormats; 1343209ff23fSmrg 1344209ff23fSmrg if (IS_R300_VARIANT || IS_AVIVO_VARIANT) { 1345209ff23fSmrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, "XAA Render acceleration " 1346209ff23fSmrg "unsupported on Radeon 9500/9700 and newer. " 1347209ff23fSmrg "Please use EXA instead.\n"); 1348ad43ddacSmrg } else if (IS_R200_3D) { 1349209ff23fSmrg a->SetupForCPUToScreenAlphaTexture2 = 1350209ff23fSmrg FUNC_NAME(R200SetupForCPUToScreenAlphaTexture); 1351209ff23fSmrg a->SubsequentCPUToScreenAlphaTexture = 1352209ff23fSmrg FUNC_NAME(R200SubsequentCPUToScreenTexture); 1353209ff23fSmrg 1354209ff23fSmrg a->SetupForCPUToScreenTexture2 = 1355209ff23fSmrg FUNC_NAME(R200SetupForCPUToScreenTexture); 1356209ff23fSmrg a->SubsequentCPUToScreenTexture = 1357209ff23fSmrg FUNC_NAME(R200SubsequentCPUToScreenTexture); 1358209ff23fSmrg } else { 1359209ff23fSmrg a->SetupForCPUToScreenAlphaTexture2 = 1360209ff23fSmrg FUNC_NAME(R100SetupForCPUToScreenAlphaTexture); 1361209ff23fSmrg a->SubsequentCPUToScreenAlphaTexture = 1362209ff23fSmrg FUNC_NAME(R100SubsequentCPUToScreenTexture); 1363209ff23fSmrg 1364209ff23fSmrg a->SetupForCPUToScreenTexture2 = 1365209ff23fSmrg FUNC_NAME(R100SetupForCPUToScreenTexture); 1366209ff23fSmrg a->SubsequentCPUToScreenTexture = 1367209ff23fSmrg FUNC_NAME(R100SubsequentCPUToScreenTexture); 1368209ff23fSmrg } 1369209ff23fSmrg } else if (info->RenderAccel) { 1370209ff23fSmrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Render acceleration currently " 1371209ff23fSmrg "requires XAA v1.2 or newer.\n"); 1372209ff23fSmrg } 1373209ff23fSmrg 1374209ff23fSmrg if (!a->SetupForCPUToScreenAlphaTexture2 && !a->SetupForCPUToScreenTexture2) 1375209ff23fSmrg info->RenderAccel = FALSE; 1376209ff23fSmrg 1377209ff23fSmrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Render acceleration %s\n", 1378209ff23fSmrg info->RenderAccel ? "enabled" : "disabled"); 1379209ff23fSmrg#endif /* RENDER */ 1380209ff23fSmrg} 1381209ff23fSmrg 1382209ff23fSmrg#endif /* USE_XAA */ 1383209ff23fSmrg 1384209ff23fSmrg#undef FUNC_NAME 1385