1/* 2 * Copyright 2006 Thomas Hellström. All Rights Reserved. 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, sub license, 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 12 * next paragraph) shall be included in all copies or substantial portions 13 * of the 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 NON-INFRINGEMENT. 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 20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 21 * DEALINGS IN THE SOFTWARE. 22 */ 23 24#include "via_3d.h" 25#include "via_3d_reg.h" 26#include <picturestr.h> 27 28typedef struct 29{ 30 Bool supported; 31 CARD32 col0; 32 CARD32 col1; 33 CARD32 al0; 34 CARD32 al1; 35} ViaCompositeOperator; 36 37typedef struct 38{ 39 CARD32 pictFormat; 40 Bool dstSupported; 41 Bool texSupported; 42 CARD32 dstFormat; 43 CARD32 texFormat; 44} Via3DFormat; 45 46static ViaCompositeOperator viaOperatorModes[256]; 47static Via3DFormat via3DFormats[256]; 48 49#define VIA_NUM_3D_OPCODES 19 50#define VIA_NUM_3D_FORMATS 15 51#define VIA_FMT_HASH(arg) (((((arg) >> 1) + (arg)) >> 8) & 0xFF) 52 53static const CARD32 viaOpCodes[VIA_NUM_3D_OPCODES][5] = { 54 {PictOpClear, 0x05, 0x45, 0x40, 0x80}, 55 {PictOpSrc, 0x15, 0x45, 0x50, 0x80}, 56 {PictOpDst, 0x05, 0x55, 0x40, 0x90}, 57 {PictOpOver, 0x15, 0x52, 0x50, 0x91}, 58 {PictOpOverReverse, 0x13, 0x45, 0x52, 0x90}, 59 {PictOpIn, 0x03, 0x45, 0x42, 0x80}, 60 {PictOpInReverse, 0x05, 0x42, 0x40, 0x81}, 61 {PictOpOut, 0x13, 0x45, 0x52, 0x80}, 62 {PictOpOutReverse, 0x05, 0x52, 0x40, 0x91}, 63 {PictOpAtop, 0x03, 0x52, 0x42, 0x91}, 64 {PictOpAtopReverse, 0x13, 0x42, 0x52, 0x81}, 65 {PictOpXor, 0x15, 0x52, 0x52, 0x91}, 66 {PictOpAdd, 0x15, 0x55, 0x50, 0x90}, 67 {PictOpDisjointClear, 0x05, 0x45, 0x40, 0x80}, 68 {PictOpDisjointSrc, 0x15, 0x45, 0x50, 0x80}, 69 {PictOpDisjointDst, 0x05, 0x55, 0x40, 0x90}, 70 {PictOpConjointClear, 0x05, 0x45, 0x40, 0x80}, 71 {PictOpConjointSrc, 0x15, 0x45, 0x50, 0x80}, 72 {PictOpConjointDst, 0x05, 0x55, 0x40, 0x90} 73}; 74 75static const CARD32 viaFormats[VIA_NUM_3D_FORMATS][5] = { 76 {PICT_x1r5g5b5, HC_HDBFM_RGB555, HC_HTXnFM_RGB555, 1, 1}, 77 {PICT_r5g6b5, HC_HDBFM_RGB565, HC_HTXnFM_RGB565, 1, 1}, 78 {PICT_a4r4g4b4, HC_HDBFM_ARGB4444, HC_HTXnFM_ARGB4444, 1, 1}, 79 {PICT_a1r5g5b5, HC_HDBFM_ARGB1555, HC_HTXnFM_ARGB1555, 1, 1}, 80 {PICT_x1b5g5r5, HC_HDBFM_BGR555, HC_HTXnFM_BGR555, 1, 1}, 81 {PICT_b5g6r5, HC_HDBFM_BGR565, HC_HTXnFM_BGR565, 1, 1}, 82 {PICT_a4b4g4r4, HC_HDBFM_ABGR4444, HC_HTXnFM_ABGR4444, 1, 1}, 83 {PICT_a1b5g5r5, HC_HDBFM_ABGR1555, HC_HTXnFM_ABGR1555, 1, 1}, 84 {PICT_x8r8g8b8, HC_HDBFM_ARGB0888, HC_HTXnFM_ARGB0888, 1, 1}, 85 {PICT_a8r8g8b8, HC_HDBFM_ARGB8888, HC_HTXnFM_ARGB8888, 1, 1}, 86 {PICT_x8b8g8r8, HC_HDBFM_ABGR0888, HC_HTXnFM_ABGR0888, 1, 1}, 87 {PICT_a8b8g8r8, HC_HDBFM_ABGR8888, HC_HTXnFM_ABGR8888, 1, 1}, 88 {PICT_a8, 0x00, HC_HTXnFM_A8, 0, 1}, 89 {PICT_a4, 0x00, HC_HTXnFM_A4, 0, 1}, 90 {PICT_a1, 0x00, HC_HTXnFM_A1, 0, 1} 91}; 92 93static CARD32 94via3DDstFormat(int format) 95{ 96 return via3DFormats[VIA_FMT_HASH(format)].dstFormat; 97} 98 99static CARD32 100via3DTexFormat(int format) 101{ 102 return via3DFormats[VIA_FMT_HASH(format)].texFormat; 103} 104 105static Bool 106via3DDstSupported(int format) 107{ 108 Via3DFormat *fm = via3DFormats + VIA_FMT_HASH(format); 109 110 if (fm->pictFormat != format) 111 return FALSE; 112 return fm->dstSupported; 113} 114 115static Bool 116via3DTexSupported(int format) 117{ 118 Via3DFormat *fm = via3DFormats + VIA_FMT_HASH(format); 119 120 if (fm->pictFormat != format) 121 return FALSE; 122 return fm->texSupported; 123} 124 125static void 126viaSet3DDestination(Via3DState * v3d, CARD32 offset, CARD32 pitch, int format) 127{ 128 v3d->drawingDirty = TRUE; /* Affects planemask format. */ 129 v3d->destDirty = TRUE; 130 v3d->destOffset = offset; 131 v3d->destPitch = pitch; 132 v3d->destFormat = via3DDstFormat(format); 133 v3d->destDepth = (v3d->destFormat < HC_HDBFM_ARGB0888) ? 16 : 32; 134} 135 136static void 137viaSet3DDrawing(Via3DState * v3d, int rop, 138 CARD32 planeMask, CARD32 solidColor, CARD32 solidAlpha) 139{ 140 v3d->drawingDirty = TRUE; 141 v3d->rop = rop; 142 v3d->planeMask = planeMask; 143 v3d->solidColor = solidColor; 144 v3d->solidAlpha = solidAlpha; 145} 146 147static void 148viaSet3DFlags(Via3DState * v3d, int numTextures, 149 Bool writeAlpha, Bool writeColor, Bool blend) 150{ 151 v3d->enableDirty = TRUE; 152 v3d->blendDirty = TRUE; 153 v3d->numTextures = numTextures; 154 v3d->writeAlpha = writeAlpha; 155 v3d->writeColor = writeColor; 156 v3d->blend = blend; 157} 158 159static Bool 160viaOrder(CARD32 val, CARD32 * shift) 161{ 162 *shift = 0; 163 164 while (val > (1 << *shift)) 165 (*shift)++; 166 return (val == (1 << *shift)); 167} 168 169static Bool 170viaSet3DTexture(Via3DState * v3d, int tex, CARD32 offset, 171 CARD32 pitch, Bool npot, CARD32 width, CARD32 height, 172 int format, ViaTextureModes sMode, ViaTextureModes tMode, 173 ViaTexBlendingModes blendingMode, Bool agpTexture) 174{ 175 ViaTextureUnit *vTex = v3d->tex + tex; 176 177 vTex->textureLevel0Offset = offset; 178 vTex->npot = npot; 179 if (!viaOrder(pitch, &vTex->textureLevel0Exp) && !vTex->npot) 180 return FALSE; 181 vTex->textureLevel0Pitch = pitch; 182 if (!viaOrder(width, &vTex->textureLevel0WExp)) 183 return FALSE; 184 if (!viaOrder(height, &vTex->textureLevel0HExp)) 185 return FALSE; 186 187 if (pitch <= 4) { 188 ErrorF("Warning: texture pitch <= 4 !\n"); 189 } 190 191 vTex->textureFormat = via3DTexFormat(format); 192 193 switch (blendingMode) { 194 case via_src: 195 vTex->texCsat = (0x01 << 23) | (0x10 << 14) | (0x03 << 7) | 0x00; 196 vTex->texAsat = ((0x0B << 14) 197 | ((PICT_FORMAT_A(format) ? 0x04 : 0x02) << 7) 198 | 0x03); 199 vTex->texRCa = 0x00000000; 200 vTex->texRAa = 0x00000000; 201 vTex->texBColDirty = TRUE; 202 break; 203 case via_src_onepix_mask: 204 vTex->texCsat = (0x01 << 23) | (0x09 << 14) | (0x03 << 7) | 0x00; 205 vTex->texAsat = ((0x03 << 14) 206 | ((PICT_FORMAT_A(format) ? 0x04 : 0x02) << 7) 207 | 0x03); 208 break; 209 case via_src_onepix_comp_mask: 210 vTex->texCsat = (0x01 << 23) | (0x09 << 14) | (0x03 << 7) | 0x00; 211 vTex->texAsat = ((0x03 << 14) 212 | ((PICT_FORMAT_A(format) ? 0x04 : 0x02) << 7) 213 | 0x03); 214 break; 215 case via_mask: 216 vTex->texCsat = (0x01 << 23) | (0x07 << 14) | (0x04 << 7) | 0x00; 217 vTex->texAsat = (0x01 << 23) | (0x04 << 14) | (0x02 << 7) | 0x03; 218 break; 219 case via_comp_mask: 220 vTex->texCsat = (0x01 << 23) | (0x03 << 14) | (0x04 << 7) | 0x00; 221 vTex->texAsat = (0x01 << 23) | (0x04 << 14) | (0x02 << 7) | 0x03; 222 break; 223 default: 224 return FALSE; 225 } 226 227 vTex->textureDirty = TRUE; 228 vTex->textureModesS = sMode - via_single; 229 vTex->textureModesT = tMode - via_single; 230 231 vTex->agpTexture = agpTexture; 232 return TRUE; 233} 234 235static void 236viaSet3DTexBlendCol(Via3DState * v3d, int tex, Bool component, CARD32 color) 237{ 238 CARD32 alpha; 239 ViaTextureUnit *vTex = v3d->tex + tex; 240 241 vTex->texRAa = (color >> 8) & 0x00FF0000; 242 if (component) { 243 vTex->texRCa = (color & 0x00FFFFFF); 244 } else { 245 alpha = color >> 24; 246 vTex->texRCa = alpha | (alpha << 8) | (alpha << 16) | (alpha << 24); 247 } 248 vTex->texBColDirty = TRUE; 249} 250 251/* 252 * Check if the compositing operator is supported and 253 * return the corresponding register setting. 254 */ 255static void 256viaSet3DCompositeOperator(Via3DState * v3d, CARD8 op) 257{ 258 ViaCompositeOperator *vOp = viaOperatorModes + op; 259 260 if (v3d) 261 v3d->blendDirty = TRUE; 262 else 263 return; 264 265 if (vOp->supported) { 266 v3d->blendCol0 = vOp->col0 << 4; 267 v3d->blendCol1 = vOp->col1 << 2; 268 v3d->blendAl0 = vOp->al0 << 4; 269 v3d->blendAl1 = vOp->al1 << 2; 270 } 271} 272 273static Bool 274via3DOpSupported(CARD8 op) 275{ 276 return viaOperatorModes[op].supported; 277} 278 279static void 280via3DEmitQuad(Via3DState * v3d, ViaCommandBuffer * cb, int dstX, int dstY, 281 int src0X, int src0Y, int src1X, int src1Y, int w, int h) 282{ 283 CARD32 acmd; 284 float dx1, dx2, dy1, dy2, sx1[2], sx2[2], sy1[2], sy2[2], wf; 285 double scalex, scaley; 286 int i, numTex; 287 ViaTextureUnit *vTex; 288 289 numTex = v3d->numTextures; 290 dx1 = dstX; 291 dx2 = dstX + w; 292 dy1 = dstY; 293 dy2 = dstY + h; 294 295 if (numTex) { 296 sx1[0] = src0X; 297 sx1[1] = src1X; 298 sy1[0] = src0Y; 299 sy1[1] = src1Y; 300 for (i = 0; i < numTex; ++i) { 301 vTex = v3d->tex + i; 302 scalex = 1. / (double)((1 << vTex->textureLevel0WExp)); 303 scaley = 1. / (double)((1 << vTex->textureLevel0HExp)); 304 sx2[i] = sx1[i] + w; 305 sy2[i] = sy1[i] + h; 306 sx1[i] *= scalex; 307 sy1[i] *= scaley; 308 sx2[i] *= scalex; 309 sy2[i] *= scaley; 310 } 311 } 312 313 wf = 0.05; 314 315 /* 316 * Vertex buffer. Emit two 3-point triangles. The W or Z coordinate 317 * is needed for AGP DMA, and the W coordinate is for some obscure 318 * reason needed for texture mapping to be done correctly. So emit 319 * a w value after the x and y coordinates. 320 */ 321 322 BEGIN_H2(HC_ParaType_CmdVdata, 22 + numTex * 6); 323 acmd = ((1 << 14) | (1 << 13) | (1 << 11)); 324 if (numTex) 325 acmd |= ((1 << 7) | (1 << 8)); 326 OUT_RING_SubA(0xEC, acmd); 327 328 acmd = 2 << 16; 329 OUT_RING_SubA(0xEE, acmd); 330 331 OUT_RING(*((CARD32 *) (&dx1))); 332 OUT_RING(*((CARD32 *) (&dy1))); 333 OUT_RING(*((CARD32 *) (&wf))); 334 for (i = 0; i < numTex; ++i) { 335 OUT_RING(*((CARD32 *) (sx1 + i))); 336 OUT_RING(*((CARD32 *) (sy1 + i))); 337 } 338 339 OUT_RING(*((CARD32 *) (&dx2))); 340 OUT_RING(*((CARD32 *) (&dy1))); 341 OUT_RING(*((CARD32 *) (&wf))); 342 for (i = 0; i < numTex; ++i) { 343 OUT_RING(*((CARD32 *) (sx2 + i))); 344 OUT_RING(*((CARD32 *) (sy1 + i))); 345 } 346 347 OUT_RING(*((CARD32 *) (&dx1))); 348 OUT_RING(*((CARD32 *) (&dy2))); 349 OUT_RING(*((CARD32 *) (&wf))); 350 for (i = 0; i < numTex; ++i) { 351 OUT_RING(*((CARD32 *) (sx1 + i))); 352 OUT_RING(*((CARD32 *) (sy2 + i))); 353 } 354 355 OUT_RING(*((CARD32 *) (&dx1))); 356 OUT_RING(*((CARD32 *) (&dy2))); 357 OUT_RING(*((CARD32 *) (&wf))); 358 for (i = 0; i < numTex; ++i) { 359 OUT_RING(*((CARD32 *) (sx1 + i))); 360 OUT_RING(*((CARD32 *) (sy2 + i))); 361 } 362 363 OUT_RING(*((CARD32 *) (&dx2))); 364 OUT_RING(*((CARD32 *) (&dy1))); 365 OUT_RING(*((CARD32 *) (&wf))); 366 for (i = 0; i < numTex; ++i) { 367 OUT_RING(*((CARD32 *) (sx2 + i))); 368 OUT_RING(*((CARD32 *) (sy1 + i))); 369 } 370 371 OUT_RING(*((CARD32 *) (&dx2))); 372 OUT_RING(*((CARD32 *) (&dy2))); 373 OUT_RING(*((CARD32 *) (&wf))); 374 for (i = 0; i < numTex; ++i) { 375 OUT_RING(*((CARD32 *) (sx2 + i))); 376 OUT_RING(*((CARD32 *) (sy2 + i))); 377 } 378 OUT_RING_SubA(0xEE, 379 acmd | HC_HPLEND_MASK | HC_HPMValidN_MASK | HC_HE3Fire_MASK); 380 OUT_RING_SubA(0xEE, 381 acmd | HC_HPLEND_MASK | HC_HPMValidN_MASK | HC_HE3Fire_MASK); 382 383 ADVANCE_RING; 384} 385 386static void 387via3DEmitState(Via3DState * v3d, ViaCommandBuffer * cb, Bool forceUpload) 388{ 389 int i; 390 Bool saveHas3dState; 391 ViaTextureUnit *vTex; 392 393 /* 394 * Destination buffer location, format and pitch. 395 */ 396 397 if (forceUpload || v3d->destDirty) { 398 v3d->destDirty = FALSE; 399 BEGIN_H2(HC_ParaType_NotTex, 3); 400 401 OUT_RING_SubA(HC_SubA_HDBBasL, v3d->destOffset & 0x00FFFFFF); 402 OUT_RING_SubA(HC_SubA_HDBBasH, v3d->destOffset >> 24); 403 OUT_RING_SubA(HC_SubA_HDBFM, v3d->destFormat | 404 (v3d->destPitch & HC_HDBPit_MASK) | HC_HDBLoc_Local); 405 } 406 407 if (forceUpload || v3d->blendDirty) { 408 v3d->blendDirty = FALSE; 409 BEGIN_H2(HC_ParaType_NotTex, 6); 410 OUT_RING_SubA(HC_SubA_HABLRFCa, 0x00); 411 OUT_RING_SubA(HC_SubA_HABLRFCb, 0x00); 412 OUT_RING_SubA(HC_SubA_HABLCsat, v3d->blendCol0); 413 OUT_RING_SubA(HC_SubA_HABLCop, v3d->blendCol1); 414 OUT_RING_SubA(HC_SubA_HABLAsat, v3d->blendAl0); 415 OUT_RING_SubA(HC_SubA_HABLAop, v3d->blendAl1); 416 } 417 418 if (forceUpload || v3d->drawingDirty) { 419 420 CARD32 planeMaskLo, planeMaskHi; 421 422 v3d->drawingDirty = FALSE; 423 BEGIN_H2(HC_ParaType_NotTex, 4); 424 425 /* 426 * Raster operation and Planemask. 427 */ 428 429 if ( /* v3d->destDepth == 16 Bad Docs? */ FALSE) { 430 planeMaskLo = (v3d->planeMask & 0x000000FF) << 16; 431 planeMaskHi = (v3d->planeMask & 0x0000FF00) >> 8; 432 } else { 433 planeMaskLo = v3d->planeMask & 0x00FFFFFF; 434 planeMaskHi = v3d->planeMask >> 24; 435 } 436 437 OUT_RING_SubA(HC_SubA_HROP, ((v3d->rop & 0x0F) << 8) | planeMaskHi); 438 OUT_RING_SubA(HC_SubA_HFBBMSKL, planeMaskLo); 439 440 /* 441 * Solid shading color and alpha. Pixel center at 442 * floating coordinates (X.5,Y.5). 443 */ 444 445 OUT_RING_SubA(HC_SubA_HSolidCL, 446 (v3d->solidColor & 0x00FFFFFF) | (0 << 23)); 447 OUT_RING_SubA(HC_SubA_HPixGC, 448 (((v3d->solidColor & 0xFF000000) >> 16) | (0 << 23) 449 | (v3d->solidAlpha & 0xFF))); 450 } 451 452 if (forceUpload || v3d->enableDirty) { 453 v3d->enableDirty = FALSE; 454 BEGIN_H2(HC_ParaType_NotTex, 1); 455 456 OUT_RING_SubA(HC_SubA_HEnable, 457 ((v3d->writeColor) ? HC_HenCW_MASK : 0) | 458 ((v3d->blend) ? HC_HenABL_MASK : 0) | 459 ((v3d->numTextures) ? HC_HenTXMP_MASK : 0) | 460 ((v3d->writeAlpha) ? HC_HenAW_MASK : 0)); 461 462 if (v3d->numTextures) { 463 BEGIN_H2((HC_ParaType_Tex | (HC_SubType_TexGeneral << 8)), 2); 464 OUT_RING_SubA(HC_SubA_HTXSMD, (0 << 7) | (0 << 6) | 465 (((v3d->numTextures - 1) & 0x1) << 3) | (0 << 1) | 1); 466 OUT_RING_SubA(HC_SubA_HTXSMD, (0 << 7) | (0 << 6) | 467 (((v3d->numTextures - 1) & 0x1) << 3) | (0 << 1) | 0); 468 } 469 } 470 471 for (i = 0; i < v3d->numTextures; ++i) { 472 vTex = v3d->tex + i; 473 474 if (forceUpload || vTex->textureDirty) { 475 vTex->textureDirty = FALSE; 476 477 BEGIN_H2((HC_ParaType_Tex | 478 (((i == 0) ? HC_SubType_Tex0 : HC_SubType_Tex1) << 8)), 479 13); 480 481 OUT_RING_SubA(HC_SubA_HTXnFM, (vTex->textureFormat | 482 (vTex-> 483 agpTexture ? HC_HTXnLoc_AGP : 484 HC_HTXnLoc_Local))); 485 OUT_RING_SubA(HC_SubA_HTXnL0BasL, 486 vTex->textureLevel0Offset & 0x00FFFFFF); 487 OUT_RING_SubA(HC_SubA_HTXnL012BasH, 488 vTex->textureLevel0Offset >> 24); 489 if (vTex->npot) { 490 OUT_RING_SubA(HC_SubA_HTXnL0Pit, 491 (vTex->textureLevel0Pitch & HC_HTXnLnPit_MASK) | 492 HC_HTXnEnPit_MASK); 493 } else { 494 OUT_RING_SubA(HC_SubA_HTXnL0Pit, 495 vTex->textureLevel0Exp << HC_HTXnLnPitE_SHIFT); 496 } 497 OUT_RING_SubA(HC_SubA_HTXnL0_5WE, vTex->textureLevel0WExp); 498 OUT_RING_SubA(HC_SubA_HTXnL0_5HE, vTex->textureLevel0HExp); 499 OUT_RING_SubA(HC_SubA_HTXnL0OS, 0x00); 500 OUT_RING_SubA(HC_SubA_HTXnTB, 0x00); 501 OUT_RING_SubA(HC_SubA_HTXnMPMD, 502 ((((unsigned)vTex->textureModesT) << 19) 503 | (((unsigned)vTex->textureModesS) << 16))); 504 505 OUT_RING_SubA(HC_SubA_HTXnTBLCsat, vTex->texCsat); 506 OUT_RING_SubA(HC_SubA_HTXnTBLCop, (0x00 << 22) | (0x00 << 19) | 507 (0x00 << 14) | (0x02 << 11) | 508 (0x00 << 7) | (0x03 << 3) | 0x02); 509 OUT_RING_SubA(HC_SubA_HTXnTBLAsat, vTex->texAsat); 510 OUT_RING_SubA(HC_SubA_HTXnTBLRFog, 0x00); 511 } 512 } 513 514 for (i = 0; i < v3d->numTextures; ++i) { 515 vTex = v3d->tex + i; 516 517 if (forceUpload || vTex->texBColDirty) { 518 saveHas3dState = cb->has3dState; 519 vTex->texBColDirty = FALSE; 520 BEGIN_H2((HC_ParaType_Tex | 521 (((i == 0) ? HC_SubType_Tex0 : HC_SubType_Tex1) << 8)), 522 2); 523 OUT_RING_SubA(HC_SubA_HTXnTBLRAa, vTex->texRAa); 524 OUT_RING_SubA(HC_SubA_HTXnTBLRCa, vTex->texRCa); 525 cb->has3dState = saveHas3dState; 526 } 527 } 528} 529 530/* 531 * Cliprect. Considered not important for the DRM 3D State, so restore the 532 * has3dState flag afterwards. 533 */ 534static void 535via3DEmitClipRect(Via3DState * v3d, ViaCommandBuffer * cb, int x, int y, 536 int w, int h) 537{ 538 Bool saveHas3dState; 539 540 saveHas3dState = cb->has3dState; 541 BEGIN_H2(HC_ParaType_NotTex, 4); 542 OUT_RING_SubA(HC_SubA_HClipTB, (y << 12) | (y + h)); 543 OUT_RING_SubA(HC_SubA_HClipLR, (x << 12) | (x + w)); 544 cb->has3dState = saveHas3dState; 545} 546 547void 548viaInit3DState(Via3DState * v3d) 549{ 550 ViaCompositeOperator *op; 551 int i; 552 CARD32 tmp, hash; 553 Via3DFormat *format; 554 555 v3d->setDestination = viaSet3DDestination; 556 v3d->setDrawing = viaSet3DDrawing; 557 v3d->setFlags = viaSet3DFlags; 558 v3d->setTexture = viaSet3DTexture; 559 v3d->setTexBlendCol = viaSet3DTexBlendCol; 560 v3d->opSupported = via3DOpSupported; 561 v3d->setCompositeOperator = viaSet3DCompositeOperator; 562 v3d->emitQuad = via3DEmitQuad; 563 v3d->emitState = via3DEmitState; 564 v3d->emitClipRect = via3DEmitClipRect; 565 v3d->dstSupported = via3DDstSupported; 566 v3d->texSupported = via3DTexSupported; 567 568 for (i = 0; i < 256; ++i) { 569 viaOperatorModes[i].supported = FALSE; 570 } 571 572 for (i = 0; i < VIA_NUM_3D_OPCODES; ++i) { 573 op = viaOperatorModes + viaOpCodes[i][0]; 574 op->supported = TRUE; 575 op->col0 = viaOpCodes[i][1]; 576 op->col1 = viaOpCodes[i][2]; 577 op->al0 = viaOpCodes[i][3]; 578 op->al1 = viaOpCodes[i][4]; 579 } 580 581 for (i = 0; i < 256; ++i) { 582 via3DFormats[i].pictFormat = 0x00; 583 } 584 for (i = 0; i < VIA_NUM_3D_FORMATS; ++i) { 585 tmp = viaFormats[i][0]; 586 hash = VIA_FMT_HASH(tmp); 587 format = via3DFormats + hash; 588 if (format->pictFormat) { 589 ErrorF("BUG: Bad hash function\n"); 590 } 591 format->pictFormat = tmp; 592 format->dstSupported = (viaFormats[i][3] != 0x00); 593 format->texSupported = (viaFormats[i][4] != 0x00); 594 format->dstFormat = viaFormats[i][1]; 595 format->texFormat = viaFormats[i][2]; 596 } 597} 598