radeon_textured_videofuncs.c revision 209ff23f
1/* 2 * Copyright 2008 Alex Deucher 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice (including the next 12 * paragraph) shall be included in all copies or substantial portions of the 13 * Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 * SOFTWARE. 22 * 23 * 24 * Based on radeon_exa_render.c and kdrive ati_video.c by Eric Anholt, et al. 25 * 26 */ 27 28#if defined(ACCEL_MMIO) && defined(ACCEL_CP) 29#error Cannot define both MMIO and CP acceleration! 30#endif 31 32#if !defined(UNIXCPP) || defined(ANSICPP) 33#define FUNC_NAME_CAT(prefix,suffix) prefix##suffix 34#else 35#define FUNC_NAME_CAT(prefix,suffix) prefix/**/suffix 36#endif 37 38#ifdef ACCEL_MMIO 39#define FUNC_NAME(prefix) FUNC_NAME_CAT(prefix,MMIO) 40#else 41#ifdef ACCEL_CP 42#define FUNC_NAME(prefix) FUNC_NAME_CAT(prefix,CP) 43#else 44#error No accel type defined! 45#endif 46#endif 47 48#define VTX_DWORD_COUNT 4 49 50#ifdef ACCEL_CP 51 52#define VTX_OUT(_dstX, _dstY, _srcX, _srcY) \ 53do { \ 54 OUT_VIDEO_RING_F(_dstX); \ 55 OUT_VIDEO_RING_F(_dstY); \ 56 OUT_VIDEO_RING_F(_srcX); \ 57 OUT_VIDEO_RING_F(_srcY); \ 58} while (0) 59 60#else /* ACCEL_CP */ 61 62#define VTX_OUT(_dstX, _dstY, _srcX, _srcY) \ 63do { \ 64 OUT_VIDEO_REG_F(RADEON_SE_PORT_DATA0, _dstX); \ 65 OUT_VIDEO_REG_F(RADEON_SE_PORT_DATA0, _dstY); \ 66 OUT_VIDEO_REG_F(RADEON_SE_PORT_DATA0, _srcX); \ 67 OUT_VIDEO_REG_F(RADEON_SE_PORT_DATA0, _srcY); \ 68} while (0) 69 70#endif /* !ACCEL_CP */ 71 72static void 73FUNC_NAME(RADEONDisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv) 74{ 75 RADEONInfoPtr info = RADEONPTR(pScrn); 76 PixmapPtr pPixmap = pPriv->pPixmap; 77 uint32_t txformat; 78 uint32_t txfilter, txformat0, txformat1, txoffset, txpitch; 79 uint32_t dst_offset, dst_pitch, dst_format; 80 uint32_t txenable, colorpitch; 81 uint32_t blendcntl; 82 int dstxoff, dstyoff, pixel_shift; 83 BoxPtr pBox = REGION_RECTS(&pPriv->clip); 84 int nBox = REGION_NUM_RECTS(&pPriv->clip); 85 VIDEO_PREAMBLE(); 86 87 pixel_shift = pPixmap->drawable.bitsPerPixel >> 4; 88 89#ifdef USE_EXA 90 if (info->useEXA) { 91 dst_offset = exaGetPixmapOffset(pPixmap) + info->fbLocation + pScrn->fbOffset; 92 dst_pitch = exaGetPixmapPitch(pPixmap); 93 } else 94#endif 95 { 96 dst_offset = (pPixmap->devPrivate.ptr - info->FB) + 97 info->fbLocation + pScrn->fbOffset; 98 dst_pitch = pPixmap->devKind; 99 } 100 101#ifdef COMPOSITE 102 dstxoff = -pPixmap->screen_x + pPixmap->drawable.x; 103 dstyoff = -pPixmap->screen_y + pPixmap->drawable.y; 104#else 105 dstxoff = 0; 106 dstyoff = 0; 107#endif 108 109 if (!info->XInited3D) 110 RADEONInit3DEngine(pScrn); 111 112 /* we can probably improve this */ 113 BEGIN_VIDEO(2); 114 if (IS_R300_3D || IS_R500_3D) 115 OUT_VIDEO_REG(R300_RB3D_DSTCACHE_CTLSTAT, R300_DC_FLUSH_3D); 116 else 117 OUT_VIDEO_REG(RADEON_RB3D_DSTCACHE_CTLSTAT, RADEON_RB3D_DC_FLUSH); 118 /* We must wait for 3d to idle, in case source was just written as a dest. */ 119 OUT_VIDEO_REG(RADEON_WAIT_UNTIL, 120 RADEON_WAIT_HOST_IDLECLEAN | 121 RADEON_WAIT_2D_IDLECLEAN | 122 RADEON_WAIT_3D_IDLECLEAN | 123 RADEON_WAIT_DMA_GUI_IDLE); 124 FINISH_VIDEO(); 125 126 if (IS_R300_3D || IS_R500_3D) { 127 uint32_t output_fmt; 128 129 switch (pPixmap->drawable.bitsPerPixel) { 130 case 16: 131 if (pPixmap->drawable.depth == 15) 132 dst_format = R300_COLORFORMAT_ARGB1555; 133 else 134 dst_format = R300_COLORFORMAT_RGB565; 135 break; 136 case 32: 137 dst_format = R300_COLORFORMAT_ARGB8888; 138 break; 139 default: 140 return; 141 } 142 143 output_fmt = (R300_OUT_FMT_C4_8 | 144 R300_OUT_FMT_C0_SEL_BLUE | 145 R300_OUT_FMT_C1_SEL_GREEN | 146 R300_OUT_FMT_C2_SEL_RED | 147 R300_OUT_FMT_C3_SEL_ALPHA); 148 149 colorpitch = dst_pitch >> pixel_shift; 150 colorpitch |= dst_format; 151 152 if (RADEONTilingEnabled(pScrn, pPixmap)) 153 colorpitch |= R300_COLORTILE; 154 155 if (pPriv->id == FOURCC_UYVY) 156 txformat1 = R300_TX_FORMAT_YVYU422; 157 else 158 txformat1 = R300_TX_FORMAT_VYUY422; 159 160 txformat1 |= R300_TX_FORMAT_YUV_TO_RGB_CLAMP; 161 162 txformat0 = ((((pPriv->w - 1) & 0x7ff) << R300_TXWIDTH_SHIFT) | 163 (((pPriv->h - 1) & 0x7ff) << R300_TXHEIGHT_SHIFT)); 164 165 txformat0 |= R300_TXPITCH_EN; 166 167 info->texW[0] = pPriv->w; 168 info->texH[0] = pPriv->h; 169 170 txfilter = (R300_TX_CLAMP_S(R300_TX_CLAMP_CLAMP_LAST) | 171 R300_TX_CLAMP_T(R300_TX_CLAMP_CLAMP_LAST) | 172 R300_TX_MAG_FILTER_LINEAR | R300_TX_MIN_FILTER_LINEAR); 173 174 /* pitch is in pixels */ 175 txpitch = pPriv->src_pitch / 2; 176 txpitch -= 1; 177 178 if (IS_R500_3D && ((pPriv->w - 1) & 0x800)) 179 txpitch |= R500_TXWIDTH_11; 180 181 if (IS_R500_3D && ((pPriv->h - 1) & 0x800)) 182 txpitch |= R500_TXHEIGHT_11; 183 184 txoffset = pPriv->src_offset; 185 186 BEGIN_VIDEO(6); 187 OUT_VIDEO_REG(R300_TX_FILTER0_0, txfilter); 188 OUT_VIDEO_REG(R300_TX_FILTER1_0, 0); 189 OUT_VIDEO_REG(R300_TX_FORMAT0_0, txformat0); 190 OUT_VIDEO_REG(R300_TX_FORMAT1_0, txformat1); 191 OUT_VIDEO_REG(R300_TX_FORMAT2_0, txpitch); 192 OUT_VIDEO_REG(R300_TX_OFFSET_0, txoffset); 193 FINISH_VIDEO(); 194 195 txenable = R300_TEX_0_ENABLE; 196 197 /* setup the VAP */ 198 if (info->has_tcl) 199 BEGIN_VIDEO(6); 200 else 201 BEGIN_VIDEO(4); 202 203 /* These registers define the number, type, and location of data submitted 204 * to the PVS unit of GA input (when PVS is disabled) 205 * DST_VEC_LOC is the slot in the PVS input vector memory when PVS/TCL is 206 * enabled. This memory provides the imputs to the vertex shader program 207 * and ordering is not important. When PVS/TCL is disabled, this field maps 208 * directly to the GA input memory and the order is signifigant. In 209 * PVS_BYPASS mode the order is as follows: 210 * Position 211 * Point Size 212 * Color 0-3 213 * Textures 0-7 214 * Fog 215 */ 216 OUT_VIDEO_REG(R300_VAP_PROG_STREAM_CNTL_0, 217 ((R300_DATA_TYPE_FLOAT_2 << R300_DATA_TYPE_0_SHIFT) | 218 (0 << R300_SKIP_DWORDS_0_SHIFT) | 219 (0 << R300_DST_VEC_LOC_0_SHIFT) | 220 R300_SIGNED_0 | 221 (R300_DATA_TYPE_FLOAT_2 << R300_DATA_TYPE_1_SHIFT) | 222 (0 << R300_SKIP_DWORDS_1_SHIFT) | 223 (6 << R300_DST_VEC_LOC_1_SHIFT) | 224 R300_LAST_VEC_1 | 225 R300_SIGNED_1)); 226 227 /* load the vertex shader 228 * We pre-load vertex programs in RADEONInit3DEngine(): 229 * - exa no mask 230 * - exa mask 231 * - Xv 232 * Here we select the offset of the vertex program we want to use 233 */ 234 if (info->has_tcl) { 235 OUT_VIDEO_REG(R300_VAP_PVS_CODE_CNTL_0, 236 ((5 << R300_PVS_FIRST_INST_SHIFT) | 237 (6 << R300_PVS_XYZW_VALID_INST_SHIFT) | 238 (6 << R300_PVS_LAST_INST_SHIFT))); 239 OUT_VIDEO_REG(R300_VAP_PVS_CODE_CNTL_1, 240 (6 << R300_PVS_LAST_VTX_SRC_INST_SHIFT)); 241 } 242 243 /* Position and one set of 2 texture coordinates */ 244 OUT_VIDEO_REG(R300_VAP_OUT_VTX_FMT_0, R300_VTX_POS_PRESENT); 245 OUT_VIDEO_REG(R300_VAP_OUT_VTX_FMT_1, (2 << R300_TEX_0_COMP_CNT_SHIFT)); 246 OUT_VIDEO_REG(R300_US_OUT_FMT_0, output_fmt); 247 FINISH_VIDEO(); 248 249 /* setup pixel shader */ 250 if (IS_R300_3D) { 251 BEGIN_VIDEO(8); 252 /* 2 components: 2 for tex0 */ 253 OUT_VIDEO_REG(R300_RS_COUNT, 254 ((2 << R300_RS_COUNT_IT_COUNT_SHIFT) | 255 R300_RS_COUNT_HIRES_EN)); 256 /* R300_INST_COUNT_RS - highest RS instruction used */ 257 OUT_VIDEO_REG(R300_RS_INST_COUNT, R300_INST_COUNT_RS(0) | R300_TX_OFFSET_RS(6)); 258 259 OUT_VIDEO_REG(R300_US_CODE_OFFSET, 260 (R300_ALU_CODE_OFFSET(0) | 261 R300_ALU_CODE_SIZE(1) | 262 R300_TEX_CODE_OFFSET(0) | 263 R300_TEX_CODE_SIZE(1))); 264 265 OUT_VIDEO_REG(R300_US_CODE_ADDR_3, 266 (R300_ALU_START(0) | 267 R300_ALU_SIZE(0) | 268 R300_TEX_START(0) | 269 R300_TEX_SIZE(0) | 270 R300_RGBA_OUT)); 271 272 /* tex inst is preloaded in RADEONInit3DEngine() */ 273 274 /* ALU inst */ 275 /* RGB */ 276 OUT_VIDEO_REG(R300_US_ALU_RGB_ADDR_0, 277 (R300_ALU_RGB_ADDR0(0) | 278 R300_ALU_RGB_ADDR1(0) | 279 R300_ALU_RGB_ADDR2(0) | 280 R300_ALU_RGB_ADDRD(0) | 281 R300_ALU_RGB_OMASK((R300_ALU_RGB_MASK_R | 282 R300_ALU_RGB_MASK_G | 283 R300_ALU_RGB_MASK_B)) | 284 R300_ALU_RGB_TARGET_A)); 285 OUT_VIDEO_REG(R300_US_ALU_RGB_INST_0, 286 (R300_ALU_RGB_SEL_A(R300_ALU_RGB_SRC0_RGB) | 287 R300_ALU_RGB_MOD_A(R300_ALU_RGB_MOD_NOP) | 288 R300_ALU_RGB_SEL_B(R300_ALU_RGB_1_0) | 289 R300_ALU_RGB_MOD_B(R300_ALU_RGB_MOD_NOP) | 290 R300_ALU_RGB_SEL_C(R300_ALU_RGB_0_0) | 291 R300_ALU_RGB_MOD_C(R300_ALU_RGB_MOD_NOP) | 292 R300_ALU_RGB_OP(R300_ALU_RGB_OP_MAD) | 293 R300_ALU_RGB_OMOD(R300_ALU_RGB_OMOD_NONE) | 294 R300_ALU_RGB_CLAMP)); 295 /* Alpha */ 296 OUT_VIDEO_REG(R300_US_ALU_ALPHA_ADDR_0, 297 (R300_ALU_ALPHA_ADDR0(0) | 298 R300_ALU_ALPHA_ADDR1(0) | 299 R300_ALU_ALPHA_ADDR2(0) | 300 R300_ALU_ALPHA_ADDRD(0) | 301 R300_ALU_ALPHA_OMASK(R300_ALU_ALPHA_MASK_A) | 302 R300_ALU_ALPHA_TARGET_A | 303 R300_ALU_ALPHA_OMASK_W(R300_ALU_ALPHA_MASK_NONE))); 304 OUT_VIDEO_REG(R300_US_ALU_ALPHA_INST_0, 305 (R300_ALU_ALPHA_SEL_A(R300_ALU_ALPHA_SRC0_A) | 306 R300_ALU_ALPHA_MOD_A(R300_ALU_ALPHA_MOD_NOP) | 307 R300_ALU_ALPHA_SEL_B(R300_ALU_ALPHA_1_0) | 308 R300_ALU_ALPHA_MOD_B(R300_ALU_ALPHA_MOD_NOP) | 309 R300_ALU_ALPHA_SEL_C(R300_ALU_ALPHA_0_0) | 310 R300_ALU_ALPHA_MOD_C(R300_ALU_ALPHA_MOD_NOP) | 311 R300_ALU_ALPHA_OP(R300_ALU_ALPHA_OP_MAD) | 312 R300_ALU_ALPHA_OMOD(R300_ALU_ALPHA_OMOD_NONE) | 313 R300_ALU_ALPHA_CLAMP)); 314 FINISH_VIDEO(); 315 } else { 316 BEGIN_VIDEO(18); 317 /* 2 components: 2 for tex0 */ 318 OUT_VIDEO_REG(R300_RS_COUNT, 319 ((2 << R300_RS_COUNT_IT_COUNT_SHIFT) | 320 R300_RS_COUNT_HIRES_EN)); 321 322 /* R300_INST_COUNT_RS - highest RS instruction used */ 323 OUT_VIDEO_REG(R300_RS_INST_COUNT, R300_INST_COUNT_RS(0) | R300_TX_OFFSET_RS(6)); 324 325 OUT_VIDEO_REG(R500_US_CODE_ADDR, (R500_US_CODE_START_ADDR(0) | 326 R500_US_CODE_END_ADDR(1))); 327 OUT_VIDEO_REG(R500_US_CODE_RANGE, (R500_US_CODE_RANGE_ADDR(0) | 328 R500_US_CODE_RANGE_SIZE(1))); 329 OUT_VIDEO_REG(R500_US_CODE_OFFSET, 0); 330 OUT_VIDEO_REG(R500_GA_US_VECTOR_INDEX, 0); 331 332 /* tex inst */ 333 OUT_VIDEO_REG(R500_GA_US_VECTOR_DATA, (R500_INST_TYPE_TEX | 334 R500_INST_TEX_SEM_WAIT | 335 R500_INST_RGB_WMASK_R | 336 R500_INST_RGB_WMASK_G | 337 R500_INST_RGB_WMASK_B | 338 R500_INST_ALPHA_WMASK | 339 R500_INST_RGB_CLAMP | 340 R500_INST_ALPHA_CLAMP)); 341 342 OUT_VIDEO_REG(R500_GA_US_VECTOR_DATA, (R500_TEX_ID(0) | 343 R500_TEX_INST_LD | 344 R500_TEX_SEM_ACQUIRE | 345 R500_TEX_IGNORE_UNCOVERED)); 346 347 OUT_VIDEO_REG(R500_GA_US_VECTOR_DATA, (R500_TEX_SRC_ADDR(0) | 348 R500_TEX_SRC_S_SWIZ_R | 349 R500_TEX_SRC_T_SWIZ_G | 350 R500_TEX_DST_ADDR(0) | 351 R500_TEX_DST_R_SWIZ_R | 352 R500_TEX_DST_G_SWIZ_G | 353 R500_TEX_DST_B_SWIZ_B | 354 R500_TEX_DST_A_SWIZ_A)); 355 OUT_VIDEO_REG(R500_GA_US_VECTOR_DATA, (R500_DX_ADDR(0) | 356 R500_DX_S_SWIZ_R | 357 R500_DX_T_SWIZ_R | 358 R500_DX_R_SWIZ_R | 359 R500_DX_Q_SWIZ_R | 360 R500_DY_ADDR(0) | 361 R500_DY_S_SWIZ_R | 362 R500_DY_T_SWIZ_R | 363 R500_DY_R_SWIZ_R | 364 R500_DY_Q_SWIZ_R)); 365 OUT_VIDEO_REG(R500_GA_US_VECTOR_DATA, 0x00000000); 366 OUT_VIDEO_REG(R500_GA_US_VECTOR_DATA, 0x00000000); 367 368 /* ALU inst */ 369 OUT_VIDEO_REG(R500_GA_US_VECTOR_DATA, (R500_INST_TYPE_OUT | 370 R500_INST_TEX_SEM_WAIT | 371 R500_INST_LAST | 372 R500_INST_RGB_OMASK_R | 373 R500_INST_RGB_OMASK_G | 374 R500_INST_RGB_OMASK_B | 375 R500_INST_ALPHA_OMASK | 376 R500_INST_RGB_CLAMP | 377 R500_INST_ALPHA_CLAMP)); 378 379 OUT_VIDEO_REG(R500_GA_US_VECTOR_DATA, (R500_RGB_ADDR0(0) | 380 R500_RGB_ADDR1(0) | 381 R500_RGB_ADDR1_CONST | 382 R500_RGB_ADDR2(0) | 383 R500_RGB_ADDR2_CONST)); 384 OUT_VIDEO_REG(R500_GA_US_VECTOR_DATA, (R500_ALPHA_ADDR0(0) | 385 R500_ALPHA_ADDR1(0) | 386 R500_ALPHA_ADDR1_CONST | 387 R500_ALPHA_ADDR2(0) | 388 R500_ALPHA_ADDR2_CONST)); 389 390 OUT_VIDEO_REG(R500_GA_US_VECTOR_DATA, (R500_ALU_RGB_SEL_A_SRC0 | 391 R500_ALU_RGB_R_SWIZ_A_R | 392 R500_ALU_RGB_G_SWIZ_A_G | 393 R500_ALU_RGB_B_SWIZ_A_B | 394 R500_ALU_RGB_SEL_B_SRC0 | 395 R500_ALU_RGB_R_SWIZ_B_1 | 396 R500_ALU_RGB_B_SWIZ_B_1 | 397 R500_ALU_RGB_G_SWIZ_B_1)); 398 399 OUT_VIDEO_REG(R500_GA_US_VECTOR_DATA, (R500_ALPHA_OP_MAD | 400 R500_ALPHA_SWIZ_A_A | 401 R500_ALPHA_SWIZ_B_1)); 402 403 OUT_VIDEO_REG(R500_GA_US_VECTOR_DATA, (R500_ALU_RGBA_OP_MAD | 404 R500_ALU_RGBA_R_SWIZ_0 | 405 R500_ALU_RGBA_G_SWIZ_0 | 406 R500_ALU_RGBA_B_SWIZ_0 | 407 R500_ALU_RGBA_A_SWIZ_0)); 408 FINISH_VIDEO(); 409 } 410 411 BEGIN_VIDEO(5); 412 OUT_VIDEO_REG(R300_TX_INVALTAGS, 0); 413 OUT_VIDEO_REG(R300_TX_ENABLE, txenable); 414 415 OUT_VIDEO_REG(R300_RB3D_COLOROFFSET0, dst_offset); 416 OUT_VIDEO_REG(R300_RB3D_COLORPITCH0, colorpitch); 417 418 blendcntl = RADEON_SRC_BLEND_GL_ONE | RADEON_DST_BLEND_GL_ZERO; 419 /* no need to enable blending */ 420 OUT_VIDEO_REG(R300_RB3D_BLENDCNTL, blendcntl); 421 FINISH_VIDEO(); 422 423 BEGIN_VIDEO(1); 424 OUT_VIDEO_REG(R300_VAP_VTX_SIZE, VTX_DWORD_COUNT); 425 FINISH_VIDEO(); 426 427 } else { 428 429 /* Same for R100/R200 */ 430 switch (pPixmap->drawable.bitsPerPixel) { 431 case 16: 432 if (pPixmap->drawable.depth == 15) 433 dst_format = RADEON_COLOR_FORMAT_ARGB1555; 434 else 435 dst_format = RADEON_COLOR_FORMAT_RGB565; 436 break; 437 case 32: 438 dst_format = RADEON_COLOR_FORMAT_ARGB8888; 439 break; 440 default: 441 return; 442 } 443 444 if (pPriv->id == FOURCC_UYVY) 445 txformat = RADEON_TXFORMAT_YVYU422; 446 else 447 txformat = RADEON_TXFORMAT_VYUY422; 448 449 txformat |= RADEON_TXFORMAT_NON_POWER2; 450 451 colorpitch = dst_pitch >> pixel_shift; 452 453 if (RADEONTilingEnabled(pScrn, pPixmap)) 454 colorpitch |= RADEON_COLOR_TILE_ENABLE; 455 456 BEGIN_VIDEO(5); 457 458 OUT_VIDEO_REG(RADEON_PP_CNTL, 459 RADEON_TEX_0_ENABLE | RADEON_TEX_BLEND_0_ENABLE); 460 OUT_VIDEO_REG(RADEON_RB3D_CNTL, 461 dst_format | RADEON_ALPHA_BLEND_ENABLE); 462 OUT_VIDEO_REG(RADEON_RB3D_COLOROFFSET, dst_offset); 463 464 OUT_VIDEO_REG(RADEON_RB3D_COLORPITCH, colorpitch); 465 466 OUT_VIDEO_REG(RADEON_RB3D_BLENDCNTL, 467 RADEON_SRC_BLEND_GL_ONE | RADEON_DST_BLEND_GL_ZERO); 468 469 FINISH_VIDEO(); 470 471 472 if ((info->ChipFamily == CHIP_FAMILY_RV250) || 473 (info->ChipFamily == CHIP_FAMILY_RV280) || 474 (info->ChipFamily == CHIP_FAMILY_RS300) || 475 (info->ChipFamily == CHIP_FAMILY_R200)) { 476 477 info->texW[0] = pPriv->w; 478 info->texH[0] = pPriv->h; 479 480 BEGIN_VIDEO(12); 481 482 OUT_VIDEO_REG(R200_SE_VTX_FMT_0, R200_VTX_XY); 483 OUT_VIDEO_REG(R200_SE_VTX_FMT_1, 484 (2 << R200_VTX_TEX0_COMP_CNT_SHIFT)); 485 486 OUT_VIDEO_REG(R200_PP_TXFILTER_0, 487 R200_MAG_FILTER_LINEAR | 488 R200_MIN_FILTER_LINEAR | 489 R200_YUV_TO_RGB); 490 OUT_VIDEO_REG(R200_PP_TXFORMAT_0, txformat); 491 OUT_VIDEO_REG(R200_PP_TXFORMAT_X_0, 0); 492 OUT_VIDEO_REG(R200_PP_TXSIZE_0, 493 (pPriv->w - 1) | 494 ((pPriv->h - 1) << RADEON_TEX_VSIZE_SHIFT)); 495 OUT_VIDEO_REG(R200_PP_TXPITCH_0, pPriv->src_pitch - 32); 496 497 OUT_VIDEO_REG(R200_PP_TXOFFSET_0, pPriv->src_offset); 498 499 OUT_VIDEO_REG(R200_PP_TXCBLEND_0, 500 R200_TXC_ARG_A_ZERO | 501 R200_TXC_ARG_B_ZERO | 502 R200_TXC_ARG_C_R0_COLOR | 503 R200_TXC_OP_MADD); 504 OUT_VIDEO_REG(R200_PP_TXCBLEND2_0, 505 R200_TXC_CLAMP_0_1 | R200_TXC_OUTPUT_REG_R0); 506 OUT_VIDEO_REG(R200_PP_TXABLEND_0, 507 R200_TXA_ARG_A_ZERO | 508 R200_TXA_ARG_B_ZERO | 509 R200_TXA_ARG_C_R0_ALPHA | 510 R200_TXA_OP_MADD); 511 OUT_VIDEO_REG(R200_PP_TXABLEND2_0, 512 R200_TXA_CLAMP_0_1 | R200_TXA_OUTPUT_REG_R0); 513 FINISH_VIDEO(); 514 } else { 515 516 info->texW[0] = 1; 517 info->texH[0] = 1; 518 519 BEGIN_VIDEO(8); 520 521 OUT_VIDEO_REG(RADEON_SE_VTX_FMT, RADEON_SE_VTX_FMT_XY | 522 RADEON_SE_VTX_FMT_ST0); 523 524 OUT_VIDEO_REG(RADEON_PP_TXFILTER_0, RADEON_MAG_FILTER_LINEAR | 525 RADEON_MIN_FILTER_LINEAR | 526 RADEON_YUV_TO_RGB); 527 OUT_VIDEO_REG(RADEON_PP_TXFORMAT_0, txformat); 528 OUT_VIDEO_REG(RADEON_PP_TXOFFSET_0, pPriv->src_offset); 529 OUT_VIDEO_REG(RADEON_PP_TXCBLEND_0, 530 RADEON_COLOR_ARG_A_ZERO | 531 RADEON_COLOR_ARG_B_ZERO | 532 RADEON_COLOR_ARG_C_T0_COLOR | 533 RADEON_BLEND_CTL_ADD | 534 RADEON_CLAMP_TX); 535 OUT_VIDEO_REG(RADEON_PP_TXABLEND_0, 536 RADEON_ALPHA_ARG_A_ZERO | 537 RADEON_ALPHA_ARG_B_ZERO | 538 RADEON_ALPHA_ARG_C_T0_ALPHA | 539 RADEON_BLEND_CTL_ADD | 540 RADEON_CLAMP_TX); 541 542 OUT_VIDEO_REG(RADEON_PP_TEX_SIZE_0, 543 (pPriv->w - 1) | 544 ((pPriv->h - 1) << RADEON_TEX_VSIZE_SHIFT)); 545 OUT_VIDEO_REG(RADEON_PP_TEX_PITCH_0, 546 pPriv->src_pitch - 32); 547 FINISH_VIDEO(); 548 } 549 } 550 551 while (nBox--) { 552 int srcX, srcY, srcw, srch; 553 int dstX, dstY, dstw, dsth; 554 xPointFixed srcTopLeft, srcTopRight, srcBottomLeft, srcBottomRight; 555 dstX = pBox->x1 + dstxoff; 556 dstY = pBox->y1 + dstyoff; 557 dstw = pBox->x2 - pBox->x1; 558 dsth = pBox->y2 - pBox->y1; 559 560 srcX = ((pBox->x1 - pPriv->drw_x) * 561 pPriv->src_w) / pPriv->dst_w; 562 srcY = ((pBox->y1 - pPriv->drw_y) * 563 pPriv->src_h) / pPriv->dst_h; 564 565 srcw = (pPriv->src_w * dstw) / pPriv->dst_w; 566 srch = (pPriv->src_h * dsth) / pPriv->dst_h; 567 568 srcTopLeft.x = IntToxFixed(srcX); 569 srcTopLeft.y = IntToxFixed(srcY); 570 srcTopRight.x = IntToxFixed(srcX + srcw); 571 srcTopRight.y = IntToxFixed(srcY); 572 srcBottomLeft.x = IntToxFixed(srcX); 573 srcBottomLeft.y = IntToxFixed(srcY + srch); 574 srcBottomRight.x = IntToxFixed(srcX + srcw); 575 srcBottomRight.y = IntToxFixed(srcY + srch); 576 577 578#if 0 579 ErrorF("dst: %d, %d, %d, %d\n", dstX, dstY, dstw, dsth); 580 ErrorF("src: %d, %d, %d, %d\n", srcX, srcY, srcw, srch); 581#endif 582 583#ifdef ACCEL_CP 584 if (info->ChipFamily < CHIP_FAMILY_R200) { 585 BEGIN_RING(4 * VTX_DWORD_COUNT + 3); 586 OUT_RING(CP_PACKET3(RADEON_CP_PACKET3_3D_DRAW_IMMD, 587 4 * VTX_DWORD_COUNT + 1)); 588 OUT_RING(RADEON_CP_VC_FRMT_XY | 589 RADEON_CP_VC_FRMT_ST0); 590 OUT_RING(RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_FAN | 591 RADEON_CP_VC_CNTL_PRIM_WALK_RING | 592 RADEON_CP_VC_CNTL_MAOS_ENABLE | 593 RADEON_CP_VC_CNTL_VTX_FMT_RADEON_MODE | 594 (4 << RADEON_CP_VC_CNTL_NUM_SHIFT)); 595 } else { 596 if (IS_R300_3D || IS_R500_3D) 597 BEGIN_RING(4 * VTX_DWORD_COUNT + 4); 598 else 599 BEGIN_RING(4 * VTX_DWORD_COUNT + 2); 600 OUT_RING(CP_PACKET3(R200_CP_PACKET3_3D_DRAW_IMMD_2, 601 4 * VTX_DWORD_COUNT)); 602 OUT_RING(RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_FAN | 603 RADEON_CP_VC_CNTL_PRIM_WALK_RING | 604 (4 << RADEON_CP_VC_CNTL_NUM_SHIFT)); 605 } 606#else /* ACCEL_CP */ 607 if (IS_R300_3D || IS_R500_3D) 608 BEGIN_VIDEO(2 + VTX_DWORD_COUNT * 4); 609 else 610 BEGIN_VIDEO(1 + VTX_DWORD_COUNT * 4); 611 612 if (info->ChipFamily < CHIP_FAMILY_R200) { 613 OUT_VIDEO_REG(RADEON_SE_VF_CNTL, (RADEON_VF_PRIM_TYPE_TRIANGLE_FAN | 614 RADEON_VF_PRIM_WALK_DATA | 615 RADEON_VF_RADEON_MODE | 616 4 << RADEON_VF_NUM_VERTICES_SHIFT)); 617 } else { 618 OUT_VIDEO_REG(RADEON_SE_VF_CNTL, (RADEON_VF_PRIM_TYPE_QUAD_LIST | 619 RADEON_VF_PRIM_WALK_DATA | 620 4 << RADEON_VF_NUM_VERTICES_SHIFT)); 621 } 622#endif 623 624 VTX_OUT((float)dstX, (float)dstY, 625 xFixedToFloat(srcTopLeft.x) / info->texW[0], xFixedToFloat(srcTopLeft.y) / info->texH[0]); 626 VTX_OUT((float)dstX, (float)(dstY + dsth), 627 xFixedToFloat(srcBottomLeft.x) / info->texW[0], xFixedToFloat(srcBottomLeft.y) / info->texH[0]); 628 VTX_OUT((float)(dstX + dstw), (float)(dstY + dsth), 629 xFixedToFloat(srcBottomRight.x) / info->texW[0], xFixedToFloat(srcBottomRight.y) / info->texH[0]); 630 VTX_OUT((float)(dstX + dstw), (float)dstY, 631 xFixedToFloat(srcTopRight.x) / info->texW[0], xFixedToFloat(srcTopRight.y) / info->texH[0]); 632 633 if (IS_R300_3D || IS_R500_3D) 634 /* flushing is pipelined, free/finish is not */ 635 OUT_VIDEO_REG(R300_RB3D_DSTCACHE_CTLSTAT, R300_DC_FLUSH_3D); 636 637#ifdef ACCEL_CP 638 ADVANCE_RING(); 639#else 640 FINISH_VIDEO(); 641#endif /* !ACCEL_CP */ 642 643 pBox++; 644 } 645 646 if (IS_R300_3D || IS_R500_3D) { 647 BEGIN_VIDEO(2); 648 OUT_VIDEO_REG(R300_RB3D_DSTCACHE_CTLSTAT, R300_RB3D_DC_FLUSH_ALL); 649 } else 650 BEGIN_VIDEO(1); 651 OUT_VIDEO_REG(RADEON_WAIT_UNTIL, RADEON_WAIT_3D_IDLECLEAN); 652 FINISH_VIDEO(); 653 654 DamageDamageRegion(pPriv->pDraw, &pPriv->clip); 655} 656 657#undef VTX_OUT 658#undef FUNC_NAME 659