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
28 typedef struct
29 {
30 Bool supported;
31 CARD32 col0;
32 CARD32 col1;
33 CARD32 al0;
34 CARD32 al1;
35 } ViaCompositeOperator;
36
37 typedef struct
38 {
39 CARD32 pictFormat;
40 Bool dstSupported;
41 Bool texSupported;
42 CARD32 dstFormat;
43 CARD32 texFormat;
44 } Via3DFormat;
45
46 static ViaCompositeOperator viaOperatorModes[256];
47 static 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
53 static 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
75 static 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
93 static CARD32
via3DDstFormat(int format)94 via3DDstFormat(int format)
95 {
96 return via3DFormats[VIA_FMT_HASH(format)].dstFormat;
97 }
98
99 static CARD32
via3DTexFormat(int format)100 via3DTexFormat(int format)
101 {
102 return via3DFormats[VIA_FMT_HASH(format)].texFormat;
103 }
104
105 static Bool
via3DDstSupported(int format)106 via3DDstSupported(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
115 static Bool
via3DTexSupported(int format)116 via3DTexSupported(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
125 static void
viaSet3DDestination(Via3DState * v3d,CARD32 offset,CARD32 pitch,int format)126 viaSet3DDestination(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
136 static void
viaSet3DDrawing(Via3DState * v3d,int rop,CARD32 planeMask,CARD32 solidColor,CARD32 solidAlpha)137 viaSet3DDrawing(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
147 static void
viaSet3DFlags(Via3DState * v3d,int numTextures,Bool writeAlpha,Bool writeColor,Bool blend)148 viaSet3DFlags(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
159 static Bool
viaOrder(CARD32 val,CARD32 * shift)160 viaOrder(CARD32 val, CARD32 * shift)
161 {
162 *shift = 0;
163
164 while (val > (1 << *shift))
165 (*shift)++;
166 return (val == (1 << *shift));
167 }
168
169 static Bool
viaSet3DTexture(Via3DState * v3d,int tex,CARD32 offset,CARD32 pitch,Bool npot,CARD32 width,CARD32 height,int format,ViaTextureModes sMode,ViaTextureModes tMode,ViaTexBlendingModes blendingMode,Bool agpTexture)170 viaSet3DTexture(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
235 static void
viaSet3DTexBlendCol(Via3DState * v3d,int tex,Bool component,CARD32 color)236 viaSet3DTexBlendCol(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 */
255 static void
viaSet3DCompositeOperator(Via3DState * v3d,CARD8 op)256 viaSet3DCompositeOperator(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
273 static Bool
via3DOpSupported(CARD8 op)274 via3DOpSupported(CARD8 op)
275 {
276 return viaOperatorModes[op].supported;
277 }
278
279 static void
via3DEmitQuad(Via3DState * v3d,ViaCommandBuffer * cb,int dstX,int dstY,int src0X,int src0Y,int src1X,int src1Y,int w,int h)280 via3DEmitQuad(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
386 static void
via3DEmitState(Via3DState * v3d,ViaCommandBuffer * cb,Bool forceUpload)387 via3DEmitState(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 */
534 static void
via3DEmitClipRect(Via3DState * v3d,ViaCommandBuffer * cb,int x,int y,int w,int h)535 via3DEmitClipRect(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
547 void
viaInit3DState(Via3DState * v3d)548 viaInit3DState(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