via_3d.c revision 7e6fb56f
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    v3d->blendDirty = TRUE;
261    if (v3d && vOp->supported) {
262        v3d->blendCol0 = vOp->col0 << 4;
263        v3d->blendCol1 = vOp->col1 << 2;
264        v3d->blendAl0 = vOp->al0 << 4;
265        v3d->blendAl1 = vOp->al1 << 2;
266    }
267}
268
269static Bool
270via3DOpSupported(CARD8 op)
271{
272    return viaOperatorModes[op].supported;
273}
274
275static void
276via3DEmitQuad(Via3DState * v3d, ViaCommandBuffer * cb, int dstX, int dstY,
277              int src0X, int src0Y, int src1X, int src1Y, int w, int h)
278{
279    CARD32 acmd;
280    float dx1, dx2, dy1, dy2, sx1[2], sx2[2], sy1[2], sy2[2], wf;
281    double scalex, scaley;
282    int i, numTex;
283    ViaTextureUnit *vTex;
284
285    numTex = v3d->numTextures;
286    dx1 = dstX;
287    dx2 = dstX + w;
288    dy1 = dstY;
289    dy2 = dstY + h;
290
291    if (numTex) {
292        sx1[0] = src0X;
293        sx1[1] = src1X;
294        sy1[0] = src0Y;
295        sy1[1] = src1Y;
296        for (i = 0; i < numTex; ++i) {
297            vTex = v3d->tex + i;
298            scalex = 1. / (double)((1 << vTex->textureLevel0WExp));
299            scaley = 1. / (double)((1 << vTex->textureLevel0HExp));
300            sx2[i] = sx1[i] + w;
301            sy2[i] = sy1[i] + h;
302            sx1[i] *= scalex;
303            sy1[i] *= scaley;
304            sx2[i] *= scalex;
305            sy2[i] *= scaley;
306        }
307    }
308
309    wf = 0.05;
310
311    /*
312     * Vertex buffer. Emit two 3-point triangles. The W or Z coordinate
313     * is needed for AGP DMA, and the W coordinate is for some obscure
314     * reason needed for texture mapping to be done correctly. So emit
315     * a w value after the x and y coordinates.
316     */
317
318    BEGIN_H2(HC_ParaType_CmdVdata, 22 + numTex * 6);
319    acmd = ((1 << 14) | (1 << 13) | (1 << 11));
320    if (numTex)
321        acmd |= ((1 << 7) | (1 << 8));
322    OUT_RING_SubA(0xEC, acmd);
323
324    acmd = 2 << 16;
325    OUT_RING_SubA(0xEE, acmd);
326
327    OUT_RING(*((CARD32 *) (&dx1)));
328    OUT_RING(*((CARD32 *) (&dy1)));
329    OUT_RING(*((CARD32 *) (&wf)));
330    for (i = 0; i < numTex; ++i) {
331        OUT_RING(*((CARD32 *) (sx1 + i)));
332        OUT_RING(*((CARD32 *) (sy1 + i)));
333    }
334
335    OUT_RING(*((CARD32 *) (&dx2)));
336    OUT_RING(*((CARD32 *) (&dy1)));
337    OUT_RING(*((CARD32 *) (&wf)));
338    for (i = 0; i < numTex; ++i) {
339        OUT_RING(*((CARD32 *) (sx2 + i)));
340        OUT_RING(*((CARD32 *) (sy1 + i)));
341    }
342
343    OUT_RING(*((CARD32 *) (&dx1)));
344    OUT_RING(*((CARD32 *) (&dy2)));
345    OUT_RING(*((CARD32 *) (&wf)));
346    for (i = 0; i < numTex; ++i) {
347        OUT_RING(*((CARD32 *) (sx1 + i)));
348        OUT_RING(*((CARD32 *) (sy2 + i)));
349    }
350
351    OUT_RING(*((CARD32 *) (&dx1)));
352    OUT_RING(*((CARD32 *) (&dy2)));
353    OUT_RING(*((CARD32 *) (&wf)));
354    for (i = 0; i < numTex; ++i) {
355        OUT_RING(*((CARD32 *) (sx1 + i)));
356        OUT_RING(*((CARD32 *) (sy2 + i)));
357    }
358
359    OUT_RING(*((CARD32 *) (&dx2)));
360    OUT_RING(*((CARD32 *) (&dy1)));
361    OUT_RING(*((CARD32 *) (&wf)));
362    for (i = 0; i < numTex; ++i) {
363        OUT_RING(*((CARD32 *) (sx2 + i)));
364        OUT_RING(*((CARD32 *) (sy1 + i)));
365    }
366
367    OUT_RING(*((CARD32 *) (&dx2)));
368    OUT_RING(*((CARD32 *) (&dy2)));
369    OUT_RING(*((CARD32 *) (&wf)));
370    for (i = 0; i < numTex; ++i) {
371        OUT_RING(*((CARD32 *) (sx2 + i)));
372        OUT_RING(*((CARD32 *) (sy2 + i)));
373    }
374    OUT_RING_SubA(0xEE,
375                  acmd | HC_HPLEND_MASK | HC_HPMValidN_MASK | HC_HE3Fire_MASK);
376    OUT_RING_SubA(0xEE,
377                  acmd | HC_HPLEND_MASK | HC_HPMValidN_MASK | HC_HE3Fire_MASK);
378
379    ADVANCE_RING;
380}
381
382static void
383via3DEmitState(Via3DState * v3d, ViaCommandBuffer * cb, Bool forceUpload)
384{
385    int i;
386    Bool saveHas3dState;
387    ViaTextureUnit *vTex;
388
389    /*
390     * Destination buffer location, format and pitch.
391     */
392
393    if (forceUpload || v3d->destDirty) {
394        v3d->destDirty = FALSE;
395        BEGIN_H2(HC_ParaType_NotTex, 3);
396
397        OUT_RING_SubA(HC_SubA_HDBBasL, v3d->destOffset & 0x00FFFFFF);
398        OUT_RING_SubA(HC_SubA_HDBBasH, v3d->destOffset >> 24);
399        OUT_RING_SubA(HC_SubA_HDBFM, v3d->destFormat |
400                      (v3d->destPitch & HC_HDBPit_MASK) | HC_HDBLoc_Local);
401    }
402
403    if (forceUpload || v3d->blendDirty) {
404        v3d->blendDirty = FALSE;
405        BEGIN_H2(HC_ParaType_NotTex, 6);
406        OUT_RING_SubA(HC_SubA_HABLRFCa, 0x00);
407        OUT_RING_SubA(HC_SubA_HABLRFCb, 0x00);
408        OUT_RING_SubA(HC_SubA_HABLCsat, v3d->blendCol0);
409        OUT_RING_SubA(HC_SubA_HABLCop, v3d->blendCol1);
410        OUT_RING_SubA(HC_SubA_HABLAsat, v3d->blendAl0);
411        OUT_RING_SubA(HC_SubA_HABLAop, v3d->blendAl1);
412    }
413
414    if (forceUpload || v3d->drawingDirty) {
415
416        CARD32 planeMaskLo, planeMaskHi;
417
418        v3d->drawingDirty = FALSE;
419        BEGIN_H2(HC_ParaType_NotTex, 4);
420
421        /*
422         * Raster operation and Planemask.
423         */
424
425        if ( /* v3d->destDepth == 16 Bad Docs? */ FALSE) {
426            planeMaskLo = (v3d->planeMask & 0x000000FF) << 16;
427            planeMaskHi = (v3d->planeMask & 0x0000FF00) >> 8;
428        } else {
429            planeMaskLo = v3d->planeMask & 0x00FFFFFF;
430            planeMaskHi = v3d->planeMask >> 24;
431        }
432
433        OUT_RING_SubA(HC_SubA_HROP, ((v3d->rop & 0x0F) << 8) | planeMaskHi);
434        OUT_RING_SubA(HC_SubA_HFBBMSKL, planeMaskLo);
435
436        /*
437         * Solid shading color and alpha. Pixel center at
438         * floating coordinates (X.5,Y.5).
439         */
440
441        OUT_RING_SubA(HC_SubA_HSolidCL,
442                      (v3d->solidColor & 0x00FFFFFF) | (0 << 23));
443        OUT_RING_SubA(HC_SubA_HPixGC,
444                      (((v3d->solidColor & 0xFF000000) >> 16) | (0 << 23)
445                       | (v3d->solidAlpha & 0xFF)));
446    }
447
448    if (forceUpload || v3d->enableDirty) {
449        v3d->enableDirty = FALSE;
450        BEGIN_H2(HC_ParaType_NotTex, 1);
451
452        OUT_RING_SubA(HC_SubA_HEnable,
453                      ((v3d->writeColor) ? HC_HenCW_MASK : 0) |
454                      ((v3d->blend) ? HC_HenABL_MASK : 0) |
455                      ((v3d->numTextures) ? HC_HenTXMP_MASK : 0) |
456                      ((v3d->writeAlpha) ? HC_HenAW_MASK : 0));
457
458        if (v3d->numTextures) {
459            BEGIN_H2((HC_ParaType_Tex | (HC_SubType_TexGeneral << 8)), 2);
460            OUT_RING_SubA(HC_SubA_HTXSMD, (0 << 7) | (0 << 6) |
461                          (((v3d->numTextures - 1) & 0x1) << 3) | (0 << 1) | 1);
462            OUT_RING_SubA(HC_SubA_HTXSMD, (0 << 7) | (0 << 6) |
463                          (((v3d->numTextures - 1) & 0x1) << 3) | (0 << 1) | 0);
464        }
465    }
466
467    for (i = 0; i < v3d->numTextures; ++i) {
468        vTex = v3d->tex + i;
469
470        if (forceUpload || vTex->textureDirty) {
471            vTex->textureDirty = FALSE;
472
473            BEGIN_H2((HC_ParaType_Tex |
474                      (((i == 0) ? HC_SubType_Tex0 : HC_SubType_Tex1) << 8)),
475                     13);
476
477            OUT_RING_SubA(HC_SubA_HTXnFM, (vTex->textureFormat |
478                                           (vTex->
479                                            agpTexture ? HC_HTXnLoc_AGP :
480                                            HC_HTXnLoc_Local)));
481            OUT_RING_SubA(HC_SubA_HTXnL0BasL,
482                          vTex->textureLevel0Offset & 0x00FFFFFF);
483            OUT_RING_SubA(HC_SubA_HTXnL012BasH,
484                          vTex->textureLevel0Offset >> 24);
485            if (vTex->npot) {
486                OUT_RING_SubA(HC_SubA_HTXnL0Pit,
487                              (vTex->textureLevel0Pitch & HC_HTXnLnPit_MASK) |
488                              HC_HTXnEnPit_MASK);
489            } else {
490                OUT_RING_SubA(HC_SubA_HTXnL0Pit,
491                              vTex->textureLevel0Exp << HC_HTXnLnPitE_SHIFT);
492            }
493            OUT_RING_SubA(HC_SubA_HTXnL0_5WE, vTex->textureLevel0WExp);
494            OUT_RING_SubA(HC_SubA_HTXnL0_5HE, vTex->textureLevel0HExp);
495            OUT_RING_SubA(HC_SubA_HTXnL0OS, 0x00);
496            OUT_RING_SubA(HC_SubA_HTXnTB, 0x00);
497            OUT_RING_SubA(HC_SubA_HTXnMPMD,
498                          ((((unsigned)vTex->textureModesT) << 19)
499                           | (((unsigned)vTex->textureModesS) << 16)));
500
501            OUT_RING_SubA(HC_SubA_HTXnTBLCsat, vTex->texCsat);
502            OUT_RING_SubA(HC_SubA_HTXnTBLCop, (0x00 << 22) | (0x00 << 19) |
503                          (0x00 << 14) | (0x02 << 11) |
504                          (0x00 << 7) | (0x03 << 3) | 0x02);
505            OUT_RING_SubA(HC_SubA_HTXnTBLAsat, vTex->texAsat);
506            OUT_RING_SubA(HC_SubA_HTXnTBLRFog, 0x00);
507        }
508    }
509
510    for (i = 0; i < v3d->numTextures; ++i) {
511        vTex = v3d->tex + i;
512
513        if (forceUpload || vTex->texBColDirty) {
514            saveHas3dState = cb->has3dState;
515            vTex->texBColDirty = FALSE;
516            BEGIN_H2((HC_ParaType_Tex |
517                      (((i == 0) ? HC_SubType_Tex0 : HC_SubType_Tex1) << 8)),
518                     2);
519            OUT_RING_SubA(HC_SubA_HTXnTBLRAa, vTex->texRAa);
520            OUT_RING_SubA(HC_SubA_HTXnTBLRCa, vTex->texRCa);
521            cb->has3dState = saveHas3dState;
522        }
523    }
524}
525
526/*
527 * Cliprect. Considered not important for the DRM 3D State, so restore the
528 * has3dState flag afterwards.
529 */
530static void
531via3DEmitClipRect(Via3DState * v3d, ViaCommandBuffer * cb, int x, int y,
532                  int w, int h)
533{
534    Bool saveHas3dState;
535
536    saveHas3dState = cb->has3dState;
537    BEGIN_H2(HC_ParaType_NotTex, 4);
538    OUT_RING_SubA(HC_SubA_HClipTB, (y << 12) | (y + h));
539    OUT_RING_SubA(HC_SubA_HClipLR, (x << 12) | (x + w));
540    cb->has3dState = saveHas3dState;
541}
542
543void
544viaInit3DState(Via3DState * v3d)
545{
546    ViaCompositeOperator *op;
547    int i;
548    CARD32 tmp, hash;
549    Via3DFormat *format;
550
551    v3d->setDestination = viaSet3DDestination;
552    v3d->setDrawing = viaSet3DDrawing;
553    v3d->setFlags = viaSet3DFlags;
554    v3d->setTexture = viaSet3DTexture;
555    v3d->setTexBlendCol = viaSet3DTexBlendCol;
556    v3d->opSupported = via3DOpSupported;
557    v3d->setCompositeOperator = viaSet3DCompositeOperator;
558    v3d->emitQuad = via3DEmitQuad;
559    v3d->emitState = via3DEmitState;
560    v3d->emitClipRect = via3DEmitClipRect;
561    v3d->dstSupported = via3DDstSupported;
562    v3d->texSupported = via3DTexSupported;
563
564    for (i = 0; i < 256; ++i) {
565        viaOperatorModes[i].supported = FALSE;
566    }
567
568    for (i = 0; i < VIA_NUM_3D_OPCODES; ++i) {
569        op = viaOperatorModes + viaOpCodes[i][0];
570        op->supported = TRUE;
571        op->col0 = viaOpCodes[i][1];
572        op->col1 = viaOpCodes[i][2];
573        op->al0 = viaOpCodes[i][3];
574        op->al1 = viaOpCodes[i][4];
575    }
576
577    for (i = 0; i < 256; ++i) {
578        via3DFormats[i].pictFormat = 0x00;
579    }
580    for (i = 0; i < VIA_NUM_3D_FORMATS; ++i) {
581        tmp = viaFormats[i][0];
582        hash = VIA_FMT_HASH(tmp);
583        format = via3DFormats + hash;
584        if (format->pictFormat) {
585            ErrorF("BUG: Bad hash function\n");
586        }
587        format->pictFormat = tmp;
588        format->dstSupported = (viaFormats[i][3] != 0x00);
589        format->texSupported = (viaFormats[i][4] != 0x00);
590        format->dstFormat = viaFormats[i][1];
591        format->texFormat = viaFormats[i][2];
592    }
593}
594