2 * Copyright 2007 Ben Skeggs
3 * Copyright 2007 Stephane Marchesin
4 * Copyright 2007 Jeremy Kolb
5 * Copyright 2007 Patrice Mandin
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software.
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
22 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26 #include "nv_include.h"
27 #include "nv30_shaders.h"
29 typedef struct nv_pict_surface_format {
32 } nv_pict_surface_format_t;
34 typedef struct nv_pict_texture_format {
38 } nv_pict_texture_format_t;
40 typedef struct nv_pict_op {
47 typedef struct nv30_exa_state {
51 PictTransformPtr transform;
56 static nv30_exa_state_t exa_state;
57 #define NV30EXA_STATE nv30_exa_state_t *state = &exa_state
59 static nv_pict_surface_format_t
60 NV30SurfaceFormat[] = {
61 { PICT_a8r8g8b8 , 0x148 },
62 { PICT_a8b8g8r8 , 0x150 },
63 { PICT_x8r8g8b8 , 0x145 },
64 { PICT_x8b8g8r8 , 0x14f },
65 { PICT_r5g6b5 , 0x143 },
69 static nv_pict_surface_format_t *
70 NV30_GetPictSurfaceFormat(int format)
74 for(i=0;i<sizeof(NV30SurfaceFormat)/sizeof(NV30SurfaceFormat[0]);i++)
76 if (NV30SurfaceFormat[i].pict_fmt == format)
77 return &NV30SurfaceFormat[i];
84 NV30EXA_FPID_PASS_COL0 = 0,
85 NV30EXA_FPID_PASS_TEX0 = 1,
86 NV30EXA_FPID_COMPOSITE_MASK = 2,
87 NV30EXA_FPID_COMPOSITE_MASK_SA_CA = 3,
88 NV30EXA_FPID_COMPOSITE_MASK_CA = 4,
92 static nv_shader_t *nv40_fp_map[NV30EXA_FPID_MAX] = {
95 &nv30_fp_composite_mask,
96 &nv30_fp_composite_mask_sa_ca,
97 &nv30_fp_composite_mask_ca
100 static nv_shader_t *nv40_fp_map_a8[NV30EXA_FPID_MAX];
103 NV30EXAHackupA8Shaders(ScrnInfoPtr pScrn)
107 for (s = 0; s < NV30EXA_FPID_MAX; s++) {
108 nv_shader_t *def, *a8;
110 def = nv40_fp_map[s];
111 a8 = xcalloc(1, sizeof(nv_shader_t));
112 a8->card_priv.NV30FP.num_regs = def->card_priv.NV30FP.num_regs;
113 a8->size = def->size + 4;
114 memcpy(a8->data, def->data, def->size * sizeof(uint32_t));
115 nv40_fp_map_a8[s] = a8;
117 a8->data[a8->size - 8 + 0] &= ~0x00000081;
118 a8->data[a8->size - 4 + 0] = 0x01401e81;
119 a8->data[a8->size - 4 + 1] = 0x1c9dfe00;
120 a8->data[a8->size - 4 + 2] = 0x0001c800;
121 a8->data[a8->size - 4 + 3] = 0x0001c800;
125 /* should be in nouveau_reg.h at some point.. */
126 #define NV34TCL_TX_SWIZZLE_UNIT_S0_X_SHIFT 14
127 #define NV34TCL_TX_SWIZZLE_UNIT_S0_X_ZERO 0
128 #define NV34TCL_TX_SWIZZLE_UNIT_S0_X_ONE 1
129 #define NV34TCL_TX_SWIZZLE_UNIT_S0_X_S1 2
130 #define NV34TCL_TX_SWIZZLE_UNIT_S0_Y_SHIFT 12
131 #define NV34TCL_TX_SWIZZLE_UNIT_S0_Z_SHIFT 10
132 #define NV34TCL_TX_SWIZZLE_UNIT_S0_W_SHIFT 8
133 #define NV34TCL_TX_SWIZZLE_UNIT_S1_X_SHIFT 6
134 #define NV34TCL_TX_SWIZZLE_UNIT_S1_X_X 3
135 #define NV34TCL_TX_SWIZZLE_UNIT_S1_X_Y 2
136 #define NV34TCL_TX_SWIZZLE_UNIT_S1_X_Z 1
137 #define NV34TCL_TX_SWIZZLE_UNIT_S1_X_W 0
138 #define NV34TCL_TX_SWIZZLE_UNIT_S1_Y_SHIFT 4
139 #define NV34TCL_TX_SWIZZLE_UNIT_S1_Z_SHIFT 2
140 #define NV34TCL_TX_SWIZZLE_UNIT_S1_W_SHIFT 0
142 #define _(r,tf,ts0x,ts0y,ts0z,ts0w,ts1x,ts1y,ts1z,ts1w) \
146 (NV34TCL_TX_SWIZZLE_UNIT_S0_X_##ts0x << NV34TCL_TX_SWIZZLE_UNIT_S0_X_SHIFT)|\
147 (NV34TCL_TX_SWIZZLE_UNIT_S0_X_##ts0y << NV34TCL_TX_SWIZZLE_UNIT_S0_Y_SHIFT)|\
148 (NV34TCL_TX_SWIZZLE_UNIT_S0_X_##ts0z << NV34TCL_TX_SWIZZLE_UNIT_S0_Z_SHIFT)|\
149 (NV34TCL_TX_SWIZZLE_UNIT_S0_X_##ts0w << NV34TCL_TX_SWIZZLE_UNIT_S0_W_SHIFT)|\
150 (NV34TCL_TX_SWIZZLE_UNIT_S1_X_##ts1x << NV34TCL_TX_SWIZZLE_UNIT_S1_X_SHIFT)|\
151 (NV34TCL_TX_SWIZZLE_UNIT_S1_X_##ts1y << NV34TCL_TX_SWIZZLE_UNIT_S1_Y_SHIFT)|\
152 (NV34TCL_TX_SWIZZLE_UNIT_S1_X_##ts1z << NV34TCL_TX_SWIZZLE_UNIT_S1_Z_SHIFT)|\
153 (NV34TCL_TX_SWIZZLE_UNIT_S1_X_##ts1w << NV34TCL_TX_SWIZZLE_UNIT_S1_W_SHIFT)\
156 static nv_pict_texture_format_t
157 NV30TextureFormat[] = {
158 _(a8r8g8b8, 0x12, S1, S1, S1, S1, X, Y, Z, W),
159 _(a8b8g8r8, 0x12, S1, S1, S1, S1, Z, Y, X, W),
160 _(x8r8g8b8, 0x12, S1, S1, S1, ONE, X, Y, Z, W),
161 _(x8b8g8r8, 0x12, S1, S1, S1, ONE, Z, Y, X, W),
162 _(a1r5g5b5, 0x10, S1, S1, S1, S1, X, Y, Z, W),
163 _(x1r5g5b5, 0x10, S1, S1, S1, ONE, X, Y, Z, W),
164 _(x4r4g4b4, 0x1d, S1, S1, S1, ONE, X, Y, Z, W),
165 _(a4r4g4b4, 0x1d, S1, S1, S1, S1, X, Y, Z, W),
166 _( a8, 0x1b, ZERO, ZERO, ZERO, S1, X, X, X, X),
170 static nv_pict_texture_format_t *
171 NV30_GetPictTextureFormat(int format)
175 for(i=0;i<sizeof(NV30TextureFormat)/sizeof(NV30TextureFormat[0]);i++)
177 if (NV30TextureFormat[i].pict_fmt == format)
178 return &NV30TextureFormat[i];
184 #define NV34TCL_BF_ZERO 0x0000
185 #define NV34TCL_BF_ONE 0x0001
186 #define NV34TCL_BF_SRC_COLOR 0x0300
187 #define NV34TCL_BF_ONE_MINUS_SRC_COLOR 0x0301
188 #define NV34TCL_BF_SRC_ALPHA 0x0302
189 #define NV34TCL_BF_ONE_MINUS_SRC_ALPHA 0x0303
190 #define NV34TCL_BF_DST_ALPHA 0x0304
191 #define NV34TCL_BF_ONE_MINUS_DST_ALPHA 0x0305
192 #define NV34TCL_BF_DST_COLOR 0x0306
193 #define NV34TCL_BF_ONE_MINUS_DST_COLOR 0x0307
194 #define NV34TCL_BF_ALPHA_SATURATE 0x0308
195 #define BF(bf) NV34TCL_BF_##bf
199 /* Clear */ { 0, 0, BF( ZERO), BF( ZERO) },
200 /* Src */ { 0, 0, BF( ONE), BF( ZERO) },
201 /* Dst */ { 0, 0, BF( ZERO), BF( ONE) },
202 /* Over */ { 1, 0, BF( ONE), BF(ONE_MINUS_SRC_ALPHA) },
203 /* OverReverse */ { 0, 1, BF(ONE_MINUS_DST_ALPHA), BF( ONE) },
204 /* In */ { 0, 1, BF( DST_ALPHA), BF( ZERO) },
205 /* InReverse */ { 1, 0, BF( ZERO), BF( SRC_ALPHA) },
206 /* Out */ { 0, 1, BF(ONE_MINUS_DST_ALPHA), BF( ZERO) },
207 /* OutReverse */ { 1, 0, BF( ZERO), BF(ONE_MINUS_SRC_ALPHA) },
208 /* Atop */ { 1, 1, BF( DST_ALPHA), BF(ONE_MINUS_SRC_ALPHA) },
209 /* AtopReverse */ { 1, 1, BF(ONE_MINUS_DST_ALPHA), BF( SRC_ALPHA) },
210 /* Xor */ { 1, 1, BF(ONE_MINUS_DST_ALPHA), BF(ONE_MINUS_SRC_ALPHA) },
211 /* Add */ { 0, 0, BF( ONE), BF( ONE) }
214 static nv_pict_op_t *
215 NV30_GetPictOpRec(int op)
217 if (op >= PictOpSaturate)
222 case 0:ErrorF("Op Clear\n");break;
223 case 1:ErrorF("Op Src\n");break;
224 case 2:ErrorF("Op Dst\n");break;
225 case 3:ErrorF("Op Over\n");break;
226 case 4:ErrorF("Op OverReverse\n");break;
227 case 5:ErrorF("Op In\n");break;
228 case 6:ErrorF("Op InReverse\n");break;
229 case 7:ErrorF("Op Out\n");break;
230 case 8:ErrorF("Op OutReverse\n");break;
231 case 9:ErrorF("Op Atop\n");break;
232 case 10:ErrorF("Op AtopReverse\n");break;
233 case 11:ErrorF("Op Xor\n");break;
234 case 12:ErrorF("Op Add\n");break;
237 return &NV30PictOp[op];
241 NV30_SetupBlend(ScrnInfoPtr pScrn, nv_pict_op_t *blend,
242 PictFormatShort dest_format, Bool component_alpha)
244 NVPtr pNv = NVPTR(pScrn);
245 struct nouveau_channel *chan = pNv->chan;
246 struct nouveau_grobj *rankine = pNv->Nv3D;
247 uint32_t sblend, dblend;
249 sblend = blend->src_card_op;
250 dblend = blend->dst_card_op;
252 if (blend->dst_alpha) {
253 if (!PICT_FORMAT_A(dest_format)) {
254 if (sblend == BF(DST_ALPHA)) {
256 } else if (sblend == BF(ONE_MINUS_DST_ALPHA)) {
259 } else if (dest_format == PICT_a8) {
260 if (sblend == BF(DST_ALPHA)) {
261 sblend = BF(DST_COLOR);
262 } else if (sblend == BF(ONE_MINUS_DST_ALPHA)) {
263 sblend = BF(ONE_MINUS_DST_COLOR);
268 if (blend->src_alpha && (component_alpha || dest_format == PICT_a8)) {
269 if (dblend == BF(SRC_ALPHA)) {
270 dblend = BF(SRC_COLOR);
271 } else if (dblend == BF(ONE_MINUS_SRC_ALPHA)) {
272 dblend = BF(ONE_MINUS_SRC_COLOR);
276 if (sblend == BF(ONE) && dblend == BF(ZERO)) {
277 BEGIN_RING(chan, rankine, NV34TCL_BLEND_FUNC_ENABLE, 1);
280 BEGIN_RING(chan, rankine, NV34TCL_BLEND_FUNC_ENABLE, 3);
282 OUT_RING (chan, (sblend << 16) | sblend);
283 OUT_RING (chan, (dblend << 16) | dblend);
288 NV30EXATexture(ScrnInfoPtr pScrn, PixmapPtr pPix, PicturePtr pPict, int unit)
290 NVPtr pNv = NVPTR(pScrn);
291 struct nouveau_channel *chan = pNv->chan;
292 struct nouveau_grobj *rankine = pNv->Nv3D;
293 nv_pict_texture_format_t *fmt;
294 uint32_t card_filter, card_repeat;
297 fmt = NV30_GetPictTextureFormat(pPict->format);
301 card_repeat = 3; /* repeatNone */
303 if (pPict->filter == PictFilterBilinear)
308 BEGIN_RING(chan, rankine, NV34TCL_TX_OFFSET(unit), 8);
309 OUT_PIXMAPl(chan, pPix, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
311 OUT_RING (chan, NV34TCL_TX_FORMAT_DIMS_2D |
312 (fmt->card_fmt << NV34TCL_TX_FORMAT_FORMAT_SHIFT) |
313 (1 << NV34TCL_TX_FORMAT_MIPMAP_LEVELS_SHIFT) |
314 (log2i(pPix->drawable.width) << NV34TCL_TX_FORMAT_BASE_SIZE_U_SHIFT) |
315 (log2i(pPix->drawable.height) << NV34TCL_TX_FORMAT_BASE_SIZE_V_SHIFT) |
317 NV34TCL_TX_FORMAT_DMA0);
319 OUT_RING (chan, (card_repeat << NV34TCL_TX_WRAP_S_SHIFT) |
320 (card_repeat << NV34TCL_TX_WRAP_T_SHIFT) |
321 (card_repeat << NV34TCL_TX_WRAP_R_SHIFT));
322 OUT_RING (chan, NV34TCL_TX_ENABLE_ENABLE);
323 OUT_RING (chan, (((uint32_t)exaGetPixmapPitch(pPix)) << NV34TCL_TX_SWIZZLE_RECT_PITCH_SHIFT ) |
326 OUT_RING (chan, (card_filter << NV34TCL_TX_FILTER_MINIFY_SHIFT) /* min */ |
327 (card_filter << NV34TCL_TX_FILTER_MAGNIFY_SHIFT) /* mag */ |
328 0x2000 /* engine lock */);
329 OUT_RING (chan, (pPix->drawable.width << NV34TCL_TX_NPOT_SIZE_W_SHIFT) | pPix->drawable.height);
330 OUT_RING (chan, 0); /* border ARGB */
332 state->unit[unit].width = (float)pPix->drawable.width;
333 state->unit[unit].height = (float)pPix->drawable.height;
334 state->unit[unit].transform = pPict->transform;
340 NV30_SetupSurface(ScrnInfoPtr pScrn, PixmapPtr pPix, PicturePtr pPict)
342 NVPtr pNv = NVPTR(pScrn);
343 struct nouveau_channel *chan = pNv->chan;
344 struct nouveau_grobj *rankine = pNv->Nv3D;
345 nv_pict_surface_format_t *fmt;
347 fmt = NV30_GetPictSurfaceFormat(pPict->format);
349 ErrorF("AIII no format\n");
353 uint32_t pitch = (uint32_t)exaGetPixmapPitch(pPix);
355 BEGIN_RING(chan, rankine, NV34TCL_RT_FORMAT, 3);
356 OUT_RING (chan, fmt->card_fmt); /* format */
357 OUT_RING (chan, pitch << 16 | pitch);
358 OUT_PIXMAPl(chan, pPix, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
364 NV30EXACheckCompositeTexture(PicturePtr pPict)
366 nv_pict_texture_format_t *fmt;
367 int w = pPict->pDrawable->width;
368 int h = pPict->pDrawable->height;
370 if ((w > 4096) || (h>4096))
371 NOUVEAU_FALLBACK("picture too large, %dx%d\n", w, h);
373 fmt = NV30_GetPictTextureFormat(pPict->format);
375 NOUVEAU_FALLBACK("picture format 0x%08x not supported\n",
378 if (pPict->filter != PictFilterNearest &&
379 pPict->filter != PictFilterBilinear)
380 NOUVEAU_FALLBACK("filter 0x%x not supported\n", pPict->filter);
382 if (!(w==1 && h==1) && pPict->repeat && pPict->repeatType != RepeatNone)
383 NOUVEAU_FALLBACK("repeat 0x%x not supported (surface %dx%d)\n",
384 pPict->repeatType,w,h);
390 NV30EXACheckComposite(int op, PicturePtr psPict,
394 nv_pict_surface_format_t *fmt;
397 opr = NV30_GetPictOpRec(op);
399 NOUVEAU_FALLBACK("unsupported blend op 0x%x\n", op);
401 fmt = NV30_GetPictSurfaceFormat(pdPict->format);
403 NOUVEAU_FALLBACK("dst picture format 0x%08x not supported\n",
406 if (!NV30EXACheckCompositeTexture(psPict))
407 NOUVEAU_FALLBACK("src picture\n");
409 if (pmPict->componentAlpha &&
410 PICT_FORMAT_RGB(pmPict->format) &&
411 opr->src_alpha && opr->src_card_op != BF(ZERO))
412 NOUVEAU_FALLBACK("mask CA + SA\n");
413 if (!NV30EXACheckCompositeTexture(pmPict))
414 NOUVEAU_FALLBACK("mask picture\n");
421 NV30EXAPrepareComposite(int op, PicturePtr psPict,
428 ScrnInfoPtr pScrn = xf86Screens[psPix->drawable.pScreen->myNum];
429 NVPtr pNv = NVPTR(pScrn);
430 struct nouveau_channel *chan = pNv->chan;
431 struct nouveau_grobj *rankine = pNv->Nv3D;
433 int fpid = NV30EXA_FPID_PASS_COL0;
436 blend = NV30_GetPictOpRec(op);
438 NV30_SetupBlend(pScrn, blend, pdPict->format,
439 (pmPict && pmPict->componentAlpha &&
440 PICT_FORMAT_RGB(pmPict->format)));
442 NV30_SetupSurface(pScrn, pdPix, pdPict);
443 NV30EXATexture(pScrn, psPix, psPict, 0);
446 #define printformat(f) ErrorF("(%xh %s %dbpp A%dR%dG%dB%d)",f,(f>>16)&0xf==2?"ARGB":"ABGR",(f>>24),(f&0xf000)>>12,(f&0xf00)>>8,(f&0xf0)>>4,f&0xf)
447 ErrorF("Preparecomposite src(%dx%d)",psPict->pDrawable->width,psPict->pDrawable->height);
448 printformat((psPict->format));
449 ErrorF(" dst(%dx%d)",pdPict->pDrawable->width,pdPict->pDrawable->height);
450 printformat((pdPict->format));
453 ErrorF(" mask(%dx%d)",pmPict->pDrawable->width,pmPict->pDrawable->height);
454 printformat((pmPict->format));
460 NV30EXATexture(pScrn, pmPix, pmPict, 1);
462 if (pmPict->componentAlpha && PICT_FORMAT_RGB(pmPict->format)) {
463 if (blend->src_alpha)
464 fpid = NV30EXA_FPID_COMPOSITE_MASK_SA_CA;
466 fpid = NV30EXA_FPID_COMPOSITE_MASK_CA;
468 fpid = NV30EXA_FPID_COMPOSITE_MASK;
471 state->have_mask = TRUE;
473 fpid = NV30EXA_FPID_PASS_TEX0;
475 state->have_mask = FALSE;
478 if (pdPict->format == PICT_a8)
479 NV30_LoadFragProg(pScrn, nv40_fp_map_a8[fpid]);
481 NV30_LoadFragProg(pScrn, nv40_fp_map[fpid]);
483 BEGIN_RING(chan, rankine, 0x23c, 1);
484 OUT_RING (chan, pmPict?3:1);
486 BEGIN_RING(chan, rankine, NV34TCL_VERTEX_BEGIN_END, 1);
487 OUT_RING (chan, NV34TCL_VERTEX_BEGIN_END_TRIANGLES);
492 #define xFixedToFloat(v) \
493 ((float)xFixedToInt((v)) + ((float)xFixedFrac(v) / 65536.0))
496 NV30EXATransformCoord(PictTransformPtr t, int x, int y, float sx, float sy,
497 float *x_ret, float *y_ret)
502 v.vector[0] = IntToxFixed(x);
503 v.vector[1] = IntToxFixed(y);
504 v.vector[2] = xFixed1;
505 PictureTransformPoint(t, &v);
506 *x_ret = xFixedToFloat(v.vector[0]);
507 *y_ret = xFixedToFloat(v.vector[1]);
514 #define CV_OUTm(sx,sy,mx,my,dx,dy) do { \
515 BEGIN_RING(chan, rankine, NV34TCL_VTX_ATTR_2F_X(8), 4); \
516 OUT_RINGf (chan, (sx)); OUT_RINGf (chan, (sy)); \
517 OUT_RINGf (chan, (mx)); OUT_RINGf (chan, (my)); \
518 BEGIN_RING(chan, rankine, NV34TCL_VTX_ATTR_2I(0), 1); \
519 OUT_RING (chan, ((dy)<<16)|(dx)); \
521 #define CV_OUT(sx,sy,dx,dy) do { \
522 BEGIN_RING(chan, rankine, NV34TCL_VTX_ATTR_2F_X(8), 2); \
523 OUT_RINGf (chan, (sx)); OUT_RINGf (chan, (sy)); \
524 BEGIN_RING(chan, rankine, NV34TCL_VTX_ATTR_2I(0), 1); \
525 OUT_RING (chan, ((dy)<<16)|(dx)); \
529 NV30EXAComposite(PixmapPtr pdPix, int srcX , int srcY,
530 int maskX, int maskY,
532 int width, int height)
534 ScrnInfoPtr pScrn = xf86Screens[pdPix->drawable.pScreen->myNum];
535 NVPtr pNv = NVPTR(pScrn);
536 struct nouveau_channel *chan = pNv->chan;
537 struct nouveau_grobj *rankine = pNv->Nv3D;
538 float sX0, sX1, sX2, sY0, sY1, sY2;
539 float mX0, mX1, mX2, mY0, mY1, mY2;
542 /* We're drawing a triangle, we need to scissor it to a quad. */
543 /* The scissors are here for a good reason, we don't get the full image, but just a part. */
544 /* Handling the cliprects is done for us already. */
545 BEGIN_RING(chan, rankine, NV34TCL_SCISSOR_HORIZ, 2);
546 OUT_RING (chan, (width << 16) | dstX);
547 OUT_RING (chan, (height << 16) | dstY);
550 ErrorF("Composite [%dx%d] (%d,%d)IN(%d,%d)OP(%d,%d)\n",width,height,srcX,srcY,maskX,maskY,dstX,dstY);
552 NV30EXATransformCoord(state->unit[0].transform,
554 state->unit[0].width,
555 state->unit[0].height, &sX0, &sY0);
556 NV30EXATransformCoord(state->unit[0].transform,
558 state->unit[0].width,
559 state->unit[0].height, &sX1, &sY1);
560 NV30EXATransformCoord(state->unit[0].transform,
561 srcX + 2*width, srcY + height,
562 state->unit[0].width,
563 state->unit[0].height, &sX2, &sY2);
565 if (state->have_mask) {
566 NV30EXATransformCoord(state->unit[1].transform,
567 maskX, maskY - height,
568 state->unit[1].width,
569 state->unit[1].height, &mX0, &mY0);
570 NV30EXATransformCoord(state->unit[1].transform,
571 maskX, maskY + height,
572 state->unit[1].width,
573 state->unit[1].height, &mX1, &mY1);
574 NV30EXATransformCoord(state->unit[1].transform,
575 maskX + 2*width, maskY + height,
576 state->unit[1].width,
577 state->unit[1].height, &mX2, &mY2);
579 CV_OUTm(sX0 , sY0 , mX0, mY0, dstX , dstY - height);
580 CV_OUTm(sX1 , sY1 , mX1, mY1, dstX , dstY + height);
581 CV_OUTm(sX2 , sY2 , mX2, mY2, dstX + 2*width , dstY + height);
583 CV_OUT(sX0 , sY0 , dstX , dstY - height);
584 CV_OUT(sX1 , sY1 , dstX , dstY + height);
585 CV_OUT(sX2 , sY2 , dstX + 2*width , dstY + height);
590 NV30EXADoneComposite(PixmapPtr pdPix)
592 ScrnInfoPtr pScrn = xf86Screens[pdPix->drawable.pScreen->myNum];
593 NVPtr pNv = NVPTR(pScrn);
594 struct nouveau_channel *chan = pNv->chan;
595 struct nouveau_grobj *rankine = pNv->Nv3D;
597 BEGIN_RING(chan, rankine, NV34TCL_VERTEX_BEGIN_END, 1);
604 NVAccelInitNV30TCL(ScrnInfoPtr pScrn)
606 NVPtr pNv = NVPTR(pScrn);
607 struct nouveau_channel *chan = pNv->chan;
608 struct nouveau_grobj *rankine;
609 uint32_t class = 0, chipset;
610 int next_hw_offset = 0, i;
612 if (!nv40_fp_map_a8[0])
613 NV30EXAHackupA8Shaders(pScrn);
615 #define NV30TCL_CHIPSET_3X_MASK 0x00000003
616 #define NV35TCL_CHIPSET_3X_MASK 0x000001e0
617 #define NV34TCL_CHIPSET_3X_MASK 0x00000010
619 chipset = (nvReadMC(pNv, NV_PMC_BOOT_0) >> 20) & 0xff;
620 if ((chipset & 0xf0) != NV_ARCH_30)
624 if (NV30TCL_CHIPSET_3X_MASK & (1<<chipset))
626 else if (NV35TCL_CHIPSET_3X_MASK & (1<<chipset))
628 else if (NV34TCL_CHIPSET_3X_MASK & (1<<chipset))
631 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
632 "NV30EXA: Unknown chipset NV3%1x\n", chipset);
638 if (nouveau_grobj_alloc(chan, Nv3D, class, &pNv->Nv3D))
643 if (!pNv->shader_mem) {
644 if (nouveau_bo_new(pNv->dev, NOUVEAU_BO_VRAM | NOUVEAU_BO_PIN,
645 0, 0x1000, &pNv->shader_mem)) {
646 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
647 "Couldn't alloc fragprog buffer!\n");
648 nouveau_grobj_free(&pNv->Nv3D);
651 if (nouveau_bo_map(pNv->shader_mem, NOUVEAU_BO_RDWR)) {
652 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
653 "Couldn't map fragprog buffer!\n");
654 nouveau_grobj_free(&pNv->Nv3D);
659 BEGIN_RING(chan, rankine, NV34TCL_DMA_TEXTURE0, 3);
660 OUT_RING (chan, pNv->chan->vram->handle);
661 OUT_RING (chan, pNv->chan->gart->handle);
662 OUT_RING (chan, pNv->chan->vram->handle);
663 BEGIN_RING(chan, rankine, NV34TCL_DMA_IN_MEMORY7, 1);
664 OUT_RING (chan, pNv->chan->vram->handle);
665 BEGIN_RING(chan, rankine, NV34TCL_DMA_COLOR0, 2);
666 OUT_RING (chan, pNv->chan->vram->handle);
667 OUT_RING (chan, pNv->chan->vram->handle);
668 BEGIN_RING(chan, rankine, NV34TCL_DMA_IN_MEMORY8, 1);
669 OUT_RING (chan, pNv->chan->vram->handle);
671 for (i=1; i<8; i++) {
672 BEGIN_RING(chan, rankine, NV34TCL_VIEWPORT_CLIP_HORIZ(i), 2);
677 BEGIN_RING(chan, rankine, 0x220, 1);
680 BEGIN_RING(chan, rankine, 0x03b0, 1);
681 OUT_RING (chan, 0x00100000);
682 BEGIN_RING(chan, rankine, 0x1454, 1);
684 BEGIN_RING(chan, rankine, 0x1d80, 1);
686 BEGIN_RING(chan, rankine, 0x1450, 1);
687 OUT_RING (chan, 0x00030004);
690 BEGIN_RING(chan, rankine, 0x1e98, 1);
692 BEGIN_RING(chan, rankine, 0x17e0, 3);
695 OUT_RING (chan, 0x3f800000);
696 BEGIN_RING(chan, rankine, 0x1f80, 16);
697 OUT_RING (chan, 0); OUT_RING (chan, 0); OUT_RING (chan, 0); OUT_RING (chan, 0);
698 OUT_RING (chan, 0); OUT_RING (chan, 0); OUT_RING (chan, 0); OUT_RING (chan, 0);
699 OUT_RING (chan, 0x0000ffff);
700 OUT_RING (chan, 0); OUT_RING (chan, 0); OUT_RING (chan, 0); OUT_RING (chan, 0);
701 OUT_RING (chan, 0); OUT_RING (chan, 0); OUT_RING (chan, 0);
703 BEGIN_RING(chan, rankine, 0x120, 3);
708 BEGIN_RING(chan, pNv->NvImageBlit, 0x120, 3);
713 BEGIN_RING(chan, rankine, 0x1d88, 1);
714 OUT_RING (chan, 0x00001200);
716 BEGIN_RING(chan, rankine, NV34TCL_RC_ENABLE, 1);
719 /* Attempt to setup a known state.. Probably missing a heap of
722 BEGIN_RING(chan, rankine, NV34TCL_STENCIL_FRONT_ENABLE, 1);
724 BEGIN_RING(chan, rankine, NV34TCL_STENCIL_BACK_ENABLE, 1);
726 BEGIN_RING(chan, rankine, NV34TCL_ALPHA_FUNC_ENABLE, 1);
728 BEGIN_RING(chan, rankine, NV34TCL_DEPTH_WRITE_ENABLE, 2);
729 OUT_RING (chan, 0); /* wr disable */
730 OUT_RING (chan, 0); /* test disable */
731 BEGIN_RING(chan, rankine, NV34TCL_COLOR_MASK, 1);
732 OUT_RING (chan, 0x01010101); /* TR,TR,TR,TR */
733 BEGIN_RING(chan, rankine, NV34TCL_CULL_FACE_ENABLE, 1);
735 BEGIN_RING(chan, rankine, NV34TCL_BLEND_FUNC_ENABLE, 5);
736 OUT_RING (chan, 0); /* Blend enable */
737 OUT_RING (chan, 0); /* Blend src */
738 OUT_RING (chan, 0); /* Blend dst */
739 OUT_RING (chan, 0x00000000); /* Blend colour */
740 OUT_RING (chan, 0x8006); /* FUNC_ADD */
741 BEGIN_RING(chan, rankine, NV34TCL_COLOR_LOGIC_OP_ENABLE, 2);
743 OUT_RING (chan, 0x1503 /*GL_COPY*/);
744 BEGIN_RING(chan, rankine, NV34TCL_DITHER_ENABLE, 1);
746 BEGIN_RING(chan, rankine, NV34TCL_SHADE_MODEL, 1);
747 OUT_RING (chan, 0x1d01 /*GL_SMOOTH*/);
748 BEGIN_RING(chan, rankine, NV34TCL_POLYGON_OFFSET_FACTOR,2);
749 OUT_RINGf (chan, 0.0);
750 OUT_RINGf (chan, 0.0);
751 BEGIN_RING(chan, rankine, NV34TCL_POLYGON_MODE_FRONT, 2);
752 OUT_RING (chan, 0x1b02 /*GL_FILL*/);
753 OUT_RING (chan, 0x1b02 /*GL_FILL*/);
754 /* - Disable texture units
755 * - Set fragprog to MOVR result.color, fragment.color */
757 BEGIN_RING(chan, rankine, NV34TCL_TX_ENABLE(i), 1);
760 /* Polygon stipple */
761 BEGIN_RING(chan, rankine, NV34TCL_POLYGON_STIPPLE_PATTERN(0), 0x20);
763 OUT_RING (chan, 0xFFFFFFFF);
765 BEGIN_RING(chan, rankine, NV34TCL_DEPTH_RANGE_NEAR, 2);
766 OUT_RINGf (chan, 0.0);
767 OUT_RINGf (chan, 1.0);
769 /* Ok. If you start X with the nvidia driver, kill it, and then
770 * start X with nouveau you will get black rendering instead of
771 * what you'd expect. This fixes the problem, and it seems that
772 * it's not needed between nouveau restarts - which suggests that
773 * the 3D context (wherever it's stored?) survives somehow.
775 //BEGIN_RING(chan, rankine, 0x1d60,1);
776 //OUT_RING (chan, 0x03008000);
781 BEGIN_RING(chan, rankine, NV34TCL_RT_HORIZ, 5);
782 OUT_RING (chan, w<<16);
783 OUT_RING (chan, h<<16);
784 OUT_RING (chan, 0x148); /* format */
785 OUT_RING (chan, pitch << 16 | pitch);
786 OUT_RING (chan, 0x0);
787 BEGIN_RING(chan, rankine, NV34TCL_VIEWPORT_TX_ORIGIN, 1);
789 BEGIN_RING(chan, rankine, 0x0a00, 2);
790 OUT_RING (chan, (w<<16) | 0);
791 OUT_RING (chan, (h<<16) | 0);
792 BEGIN_RING(chan, rankine, NV34TCL_VIEWPORT_CLIP_HORIZ(0), 2);
793 OUT_RING (chan, (w-1)<<16);
794 OUT_RING (chan, (h-1)<<16);
795 BEGIN_RING(chan, rankine, NV34TCL_SCISSOR_HORIZ, 2);
796 OUT_RING (chan, w<<16);
797 OUT_RING (chan, h<<16);
798 BEGIN_RING(chan, rankine, NV34TCL_VIEWPORT_HORIZ, 2);
799 OUT_RING (chan, w<<16);
800 OUT_RING (chan, h<<16);
802 BEGIN_RING(chan, rankine, NV34TCL_VIEWPORT_TRANSLATE_X, 8);
803 OUT_RINGf (chan, 0.0);
804 OUT_RINGf (chan, 0.0);
805 OUT_RINGf (chan, 0.0);
806 OUT_RINGf (chan, 0.0);
807 OUT_RINGf (chan, 1.0);
808 OUT_RINGf (chan, 1.0);
809 OUT_RINGf (chan, 1.0);
810 OUT_RINGf (chan, 0.0);
812 BEGIN_RING(chan, rankine, NV34TCL_MODELVIEW_MATRIX(0), 16);
813 OUT_RINGf (chan, 1.0);
814 OUT_RINGf (chan, 0.0);
815 OUT_RINGf (chan, 0.0);
816 OUT_RINGf (chan, 0.0);
817 OUT_RINGf (chan, 0.0);
818 OUT_RINGf (chan, 1.0);
819 OUT_RINGf (chan, 0.0);
820 OUT_RINGf (chan, 0.0);
821 OUT_RINGf (chan, 0.0);
822 OUT_RINGf (chan, 0.0);
823 OUT_RINGf (chan, 1.0);
824 OUT_RINGf (chan, 0.0);
825 OUT_RINGf (chan, 0.0);
826 OUT_RINGf (chan, 0.0);
827 OUT_RINGf (chan, 0.0);
828 OUT_RINGf (chan, 1.0);
830 BEGIN_RING(chan, rankine, NV34TCL_PROJECTION_MATRIX(0), 16);
831 OUT_RINGf (chan, 1.0);
832 OUT_RINGf (chan, 0.0);
833 OUT_RINGf (chan, 0.0);
834 OUT_RINGf (chan, 0.0);
835 OUT_RINGf (chan, 0.0);
836 OUT_RINGf (chan, 1.0);
837 OUT_RINGf (chan, 0.0);
838 OUT_RINGf (chan, 0.0);
839 OUT_RINGf (chan, 0.0);
840 OUT_RINGf (chan, 0.0);
841 OUT_RINGf (chan, 1.0);
842 OUT_RINGf (chan, 0.0);
843 OUT_RINGf (chan, 0.0);
844 OUT_RINGf (chan, 0.0);
845 OUT_RINGf (chan, 0.0);
846 OUT_RINGf (chan, 1.0);
848 BEGIN_RING(chan, rankine, NV34TCL_SCISSOR_HORIZ, 2);
849 OUT_RING (chan, 4096<<16);
850 OUT_RING (chan, 4096<<16);
852 for (i = 0; i < NV30EXA_FPID_MAX; i++) {
853 NV30_UploadFragProg(pNv, nv40_fp_map[i], &next_hw_offset);
854 NV30_UploadFragProg(pNv, nv40_fp_map_a8[i], &next_hw_offset);
856 NV30_UploadFragProg(pNv, &nv30_fp_yv12_bicubic, &next_hw_offset);
857 NV30_UploadFragProg(pNv, &nv30_fp_yv12_bilinear, &next_hw_offset);