2 * Copyright 2007 Ben Skeggs
3 * Copyright 2007 Stephane Marchesin
4 * Copyright 2007 Jeremy Kolb
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
21 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
31 #include "nv_include.h"
32 #include "nv_shaders.h"
34 typedef struct nv_pict_surface_format {
37 } nv_pict_surface_format_t;
39 typedef struct nv_pict_texture_format {
43 } nv_pict_texture_format_t;
45 typedef struct nv_pict_op {
52 typedef struct nv30_exa_state {
56 PictTransformPtr transform;
61 static nv30_exa_state_t exa_state;
62 #define NV30EXA_STATE nv30_exa_state_t *state = &exa_state
64 static nv_pict_surface_format_t
65 NV30SurfaceFormat[] = {
66 { PICT_a8r8g8b8 , 0x148 },
67 { PICT_a8b8g8r8 , 0x150 },
68 { PICT_x8r8g8b8 , 0x145 },
69 { PICT_x8b8g8r8 , 0x14f },
70 { PICT_r5g6b5 , 0x143 },
74 static nv_pict_surface_format_t *
75 NV30_GetPictSurfaceFormat(int format)
79 for(i=0;i<sizeof(NV30SurfaceFormat)/sizeof(NV30SurfaceFormat[0]);i++)
81 if (NV30SurfaceFormat[i].pict_fmt == format)
82 return &NV30SurfaceFormat[i];
89 NV30EXA_FPID_PASS_COL0 = 0,
90 NV30EXA_FPID_PASS_TEX0 = 1,
91 NV30EXA_FPID_COMPOSITE_MASK = 2,
92 NV30EXA_FPID_COMPOSITE_MASK_SA_CA = 3,
93 NV30EXA_FPID_COMPOSITE_MASK_CA = 4,
97 static nv_shader_t *nv40_fp_map[NV30EXA_FPID_MAX] = {
100 &nv30_fp_composite_mask,
101 &nv30_fp_composite_mask_sa_ca,
102 &nv30_fp_composite_mask_ca
105 static nv_shader_t *nv40_fp_map_a8[NV30EXA_FPID_MAX];
108 NV30EXAHackupA8Shaders(ScrnInfoPtr pScrn)
112 for (s = 0; s < NV30EXA_FPID_MAX; s++) {
113 nv_shader_t *def, *a8;
115 def = nv40_fp_map[s];
116 a8 = xcalloc(1, sizeof(nv_shader_t));
117 a8->card_priv.NV30FP.num_regs = def->card_priv.NV30FP.num_regs;
118 a8->size = def->size + 4;
119 memcpy(a8->data, def->data, def->size * sizeof(uint32_t));
120 nv40_fp_map_a8[s] = a8;
122 a8->data[a8->size - 8 + 0] &= ~0x00000081;
123 a8->data[a8->size - 4 + 0] = 0x01401e81;
124 a8->data[a8->size - 4 + 1] = 0x1c9dfe00;
125 a8->data[a8->size - 4 + 2] = 0x0001c800;
126 a8->data[a8->size - 4 + 3] = 0x0001c800;
130 /* should be in nouveau_reg.h at some point.. */
131 #define NV30TCL_TX_SWIZZLE_UNIT_S0_X_SHIFT 14
132 #define NV30TCL_TX_SWIZZLE_UNIT_S0_X_ZERO 0
133 #define NV30TCL_TX_SWIZZLE_UNIT_S0_X_ONE 1
134 #define NV30TCL_TX_SWIZZLE_UNIT_S0_X_S1 2
135 #define NV30TCL_TX_SWIZZLE_UNIT_S0_Y_SHIFT 12
136 #define NV30TCL_TX_SWIZZLE_UNIT_S0_Z_SHIFT 10
137 #define NV30TCL_TX_SWIZZLE_UNIT_S0_W_SHIFT 8
138 #define NV30TCL_TX_SWIZZLE_UNIT_S1_X_SHIFT 6
139 #define NV30TCL_TX_SWIZZLE_UNIT_S1_X_X 3
140 #define NV30TCL_TX_SWIZZLE_UNIT_S1_X_Y 2
141 #define NV30TCL_TX_SWIZZLE_UNIT_S1_X_Z 1
142 #define NV30TCL_TX_SWIZZLE_UNIT_S1_X_W 0
143 #define NV30TCL_TX_SWIZZLE_UNIT_S1_Y_SHIFT 4
144 #define NV30TCL_TX_SWIZZLE_UNIT_S1_Z_SHIFT 2
145 #define NV30TCL_TX_SWIZZLE_UNIT_S1_W_SHIFT 0
147 #define _(r,tf,ts0x,ts0y,ts0z,ts0w,ts1x,ts1y,ts1z,ts1w) \
151 (NV30TCL_TX_SWIZZLE_UNIT_S0_X_##ts0x << NV30TCL_TX_SWIZZLE_UNIT_S0_X_SHIFT)|\
152 (NV30TCL_TX_SWIZZLE_UNIT_S0_X_##ts0y << NV30TCL_TX_SWIZZLE_UNIT_S0_Y_SHIFT)|\
153 (NV30TCL_TX_SWIZZLE_UNIT_S0_X_##ts0z << NV30TCL_TX_SWIZZLE_UNIT_S0_Z_SHIFT)|\
154 (NV30TCL_TX_SWIZZLE_UNIT_S0_X_##ts0w << NV30TCL_TX_SWIZZLE_UNIT_S0_W_SHIFT)|\
155 (NV30TCL_TX_SWIZZLE_UNIT_S1_X_##ts1x << NV30TCL_TX_SWIZZLE_UNIT_S1_X_SHIFT)|\
156 (NV30TCL_TX_SWIZZLE_UNIT_S1_X_##ts1y << NV30TCL_TX_SWIZZLE_UNIT_S1_Y_SHIFT)|\
157 (NV30TCL_TX_SWIZZLE_UNIT_S1_X_##ts1z << NV30TCL_TX_SWIZZLE_UNIT_S1_Z_SHIFT)|\
158 (NV30TCL_TX_SWIZZLE_UNIT_S1_X_##ts1w << NV30TCL_TX_SWIZZLE_UNIT_S1_W_SHIFT)\
161 static nv_pict_texture_format_t
162 NV30TextureFormat[] = {
163 _(a8r8g8b8, 0x12, S1, S1, S1, S1, X, Y, Z, W),
164 _(a8b8g8r8, 0x12, S1, S1, S1, S1, Z, Y, X, W),
165 _(x8r8g8b8, 0x12, S1, S1, S1, ONE, X, Y, Z, W),
166 _(x8b8g8r8, 0x12, S1, S1, S1, ONE, Z, Y, X, W),
167 _(a1r5g5b5, 0x10, S1, S1, S1, S1, X, Y, Z, W),
168 _(x1r5g5b5, 0x10, S1, S1, S1, ONE, X, Y, Z, W),
169 _(x4r4g4b4, 0x1d, S1, S1, S1, ONE, X, Y, Z, W),
170 _(a4r4g4b4, 0x1d, S1, S1, S1, S1, X, Y, Z, W),
171 _( a8, 0x1b, ZERO, ZERO, ZERO, S1, X, X, X, X),
175 static nv_pict_texture_format_t *
176 NV30_GetPictTextureFormat(int format)
180 for(i=0;i<sizeof(NV30TextureFormat)/sizeof(NV30TextureFormat[0]);i++)
182 if (NV30TextureFormat[i].pict_fmt == format)
183 return &NV30TextureFormat[i];
189 #define NV34_TCL_PRIMITIVE_3D_BF_ZERO 0x0000
190 #define NV34_TCL_PRIMITIVE_3D_BF_ONE 0x0001
191 #define NV34_TCL_PRIMITIVE_3D_BF_SRC_COLOR 0x0300
192 #define NV34_TCL_PRIMITIVE_3D_BF_ONE_MINUS_SRC_COLOR 0x0301
193 #define NV34_TCL_PRIMITIVE_3D_BF_SRC_ALPHA 0x0302
194 #define NV34_TCL_PRIMITIVE_3D_BF_ONE_MINUS_SRC_ALPHA 0x0303
195 #define NV34_TCL_PRIMITIVE_3D_BF_DST_ALPHA 0x0304
196 #define NV34_TCL_PRIMITIVE_3D_BF_ONE_MINUS_DST_ALPHA 0x0305
197 #define NV34_TCL_PRIMITIVE_3D_BF_DST_COLOR 0x0306
198 #define NV34_TCL_PRIMITIVE_3D_BF_ONE_MINUS_DST_COLOR 0x0307
199 #define NV34_TCL_PRIMITIVE_3D_BF_ALPHA_SATURATE 0x0308
200 #define BF(bf) NV34_TCL_PRIMITIVE_3D_BF_##bf
204 /* Clear */ { 0, 0, BF( ZERO), BF( ZERO) },
205 /* Src */ { 0, 0, BF( ONE), BF( ZERO) },
206 /* Dst */ { 0, 0, BF( ZERO), BF( ONE) },
207 /* Over */ { 1, 0, BF( ONE), BF(ONE_MINUS_SRC_ALPHA) },
208 /* OverReverse */ { 0, 1, BF(ONE_MINUS_DST_ALPHA), BF( ONE) },
209 /* In */ { 0, 1, BF( DST_ALPHA), BF( ZERO) },
210 /* InReverse */ { 1, 0, BF( ZERO), BF( SRC_ALPHA) },
211 /* Out */ { 0, 1, BF(ONE_MINUS_DST_ALPHA), BF( ZERO) },
212 /* OutReverse */ { 1, 0, BF( ZERO), BF(ONE_MINUS_SRC_ALPHA) },
213 /* Atop */ { 1, 1, BF( DST_ALPHA), BF(ONE_MINUS_SRC_ALPHA) },
214 /* AtopReverse */ { 1, 1, BF(ONE_MINUS_DST_ALPHA), BF( SRC_ALPHA) },
215 /* Xor */ { 1, 1, BF(ONE_MINUS_DST_ALPHA), BF(ONE_MINUS_SRC_ALPHA) },
216 /* Add */ { 0, 0, BF( ONE), BF( ONE) }
219 static nv_pict_op_t *
220 NV30_GetPictOpRec(int op)
222 if (op >= PictOpSaturate)
227 case 0:ErrorF("Op Clear\n");break;
228 case 1:ErrorF("Op Src\n");break;
229 case 2:ErrorF("Op Dst\n");break;
230 case 3:ErrorF("Op Over\n");break;
231 case 4:ErrorF("Op OverReverse\n");break;
232 case 5:ErrorF("Op In\n");break;
233 case 6:ErrorF("Op InReverse\n");break;
234 case 7:ErrorF("Op Out\n");break;
235 case 8:ErrorF("Op OutReverse\n");break;
236 case 9:ErrorF("Op Atop\n");break;
237 case 10:ErrorF("Op AtopReverse\n");break;
238 case 11:ErrorF("Op Xor\n");break;
239 case 12:ErrorF("Op Add\n");break;
242 return &NV30PictOp[op];
245 #define FALLBACK_DEBUG 0
246 #if FALLBACK_DEBUG == 1
247 #define FALLBACK(fmt,args...) do { \
248 ErrorF("FALLBACK %s:%d> " fmt, __func__, __LINE__, ##args); \
252 #define FALLBACK(fmt,args...) do { \
258 NV30_LoadFragProg(ScrnInfoPtr pScrn, nv_shader_t *shader)
260 NVPtr pNv = NVPTR(pScrn);
261 static NVAllocRec *fp_mem = NULL;
262 static int next_hw_id_offset = 0;
265 fp_mem = NVAllocateMemory(pNv, NOUVEAU_MEM_FB, 0x1000);
267 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
268 "Couldn't alloc fragprog buffer!\n");
273 if (!shader->hw_id) {
274 memcpy(fp_mem->map + next_hw_id_offset, shader->data,
278 shader->hw_id = fp_mem->offset;
279 shader->hw_id += next_hw_id_offset;
281 next_hw_id_offset += (shader->size * sizeof(uint32_t));
282 next_hw_id_offset = (next_hw_id_offset + 63) & ~63;
285 BEGIN_RING(Nv3D, NV34_TCL_PRIMITIVE_3D_FP_ACTIVE_PROGRAM, 1);
286 OUT_RING (shader->hw_id|1);
288 BEGIN_RING(Nv3D, 0x1d60, 1);
289 OUT_RING (0); /* USES_KIL (1<<7) == 0 */
290 BEGIN_RING(Nv3D, 0x1450, 1);
291 OUT_RING (shader->card_priv.NV30FP.num_regs << 16| 4);
292 BEGIN_RING(Nv3D, 0x1d7c, 1);
293 OUT_RING (0xffff0000);
298 NV30_SetupBlend(ScrnInfoPtr pScrn, nv_pict_op_t *blend,
299 PictFormatShort dest_format, Bool component_alpha)
301 NVPtr pNv = NVPTR(pScrn);
302 uint32_t sblend, dblend;
304 sblend = blend->src_card_op;
305 dblend = blend->dst_card_op;
307 if (blend->dst_alpha) {
308 if (!PICT_FORMAT_A(dest_format)) {
309 if (sblend == BF(DST_ALPHA)) {
311 } else if (sblend == BF(ONE_MINUS_DST_ALPHA)) {
314 } else if (dest_format == PICT_a8) {
315 if (sblend == BF(DST_ALPHA)) {
316 sblend = BF(DST_COLOR);
317 } else if (sblend == BF(ONE_MINUS_DST_ALPHA)) {
318 sblend = BF(ONE_MINUS_DST_COLOR);
323 if (blend->src_alpha && (component_alpha || dest_format == PICT_a8)) {
324 if (dblend == BF(SRC_ALPHA)) {
325 dblend = BF(SRC_COLOR);
326 } else if (dblend == BF(ONE_MINUS_SRC_ALPHA)) {
327 dblend = BF(ONE_MINUS_SRC_COLOR);
331 if (sblend == BF(ONE) && dblend == BF(ZERO)) {
332 BEGIN_RING(Nv3D, NV34_TCL_PRIMITIVE_3D_BLEND_FUNC_ENABLE, 1);
335 BEGIN_RING(Nv3D, NV34_TCL_PRIMITIVE_3D_BLEND_FUNC_ENABLE, 5);
337 OUT_RING ((sblend << 16) | sblend);
338 OUT_RING ((dblend << 16) | dblend);
339 OUT_RING (0x00000000); /* Blend colour */
340 OUT_RING (0x8006); /* FUNC_ADD */
345 NV30EXATexture(ScrnInfoPtr pScrn, PixmapPtr pPix, PicturePtr pPict, int unit)
347 NVPtr pNv = NVPTR(pScrn);
348 nv_pict_texture_format_t *fmt;
349 uint32_t card_filter, card_repeat;
352 fmt = NV30_GetPictTextureFormat(pPict->format);
356 card_repeat = 3; /* repeatNone */
358 if (pPict->filter == PictFilterBilinear)
364 NV34_TCL_PRIMITIVE_3D_TX_OFFSET(unit), 8);
365 OUT_RING (NVAccelGetPixmapOffset(pPix));
367 OUT_RING ((2 << 4) /* 2D */ |
368 (fmt->card_fmt << 8) |
369 (1 << 16) /* 1 mipmap level */ |
370 (log2i(pPix->drawable.width) << 20) |
371 (log2i(pPix->drawable.height) << 24) |
374 OUT_RING ((card_repeat << 0) /* S */ |
375 (card_repeat << 8) /* T */ |
376 (card_repeat << 16) /* R */);
377 OUT_RING (0x40000000); /* enable */
378 OUT_RING ((((uint32_t)exaGetPixmapPitch(pPix))<<16) | fmt->card_swz);
380 OUT_RING ((card_filter << 16) /* min */ |
381 (card_filter << 24) /* mag */ |
382 0x2000 /* engine lock */);
383 OUT_RING ((pPix->drawable.width << 16) | pPix->drawable.height);
384 OUT_RING (0); /* border ARGB */
386 BEGIN_RING(Nv3D, 0xb00 + 4*unit,1);
389 state->unit[unit].width = (float)pPix->drawable.width;
390 state->unit[unit].height = (float)pPix->drawable.height;
391 state->unit[unit].transform = pPict->transform;
397 NV30_SetupSurface(ScrnInfoPtr pScrn, PixmapPtr pPix, PicturePtr pPict)
399 NVPtr pNv = NVPTR(pScrn);
400 nv_pict_surface_format_t *fmt;
402 fmt = NV30_GetPictSurfaceFormat(pPict->format);
404 ErrorF("AIII no format\n");
408 uint32_t pitch = (uint32_t)exaGetPixmapPitch(pPix);
410 int x = pPict->pDrawable->x;
411 int y = pPict->pDrawable->y;
412 int w = pPict->pDrawable->width;
413 int h = pPict->pDrawable->height;
414 BEGIN_RING(Nv3D, NV34_TCL_PRIMITIVE_3D_VIEWPORT_HORIZ, 5);
415 OUT_RING ((w<<16)|x);
416 OUT_RING ((h<<16)|y);
417 OUT_RING (fmt->card_fmt); /* format */
418 OUT_RING (pitch << 16 | pitch);
419 OUT_RING (NVAccelGetPixmapOffset(pPix));
420 BEGIN_RING(Nv3D, NV34_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_HORIZ(0), 2);
421 OUT_RING ((w-1+x)<<16);
422 OUT_RING ((h-1+y)<<16);
428 NV30EXACheckCompositeTexture(PicturePtr pPict)
430 nv_pict_texture_format_t *fmt;
431 int w = pPict->pDrawable->width;
432 int h = pPict->pDrawable->height;
434 if ((w > 4096) || (h>4096))
435 FALLBACK("picture too large, %dx%d\n", w, h);
437 fmt = NV30_GetPictTextureFormat(pPict->format);
439 FALLBACK("picture format 0x%08x not supported\n",
442 if (pPict->filter != PictFilterNearest &&
443 pPict->filter != PictFilterBilinear)
444 FALLBACK("filter 0x%x not supported\n", pPict->filter);
446 if (!(w==1 && h==1) && pPict->repeat && pPict->repeatType != RepeatNone)
447 FALLBACK("repeat 0x%x not supported (surface %dx%d)\n", pPict->repeatType,w,h);
453 NV30EXACheckComposite(int op, PicturePtr psPict,
457 nv_pict_surface_format_t *fmt;
460 opr = NV30_GetPictOpRec(op);
462 FALLBACK("unsupported blend op 0x%x\n", op);
464 fmt = NV30_GetPictSurfaceFormat(pdPict->format);
466 FALLBACK("dst picture format 0x%08x not supported\n",
469 if (!NV30EXACheckCompositeTexture(psPict))
470 FALLBACK("src picture\n");
472 if (pmPict->componentAlpha &&
473 PICT_FORMAT_RGB(pmPict->format) &&
474 opr->src_alpha && opr->src_card_op != BF(ZERO))
475 FALLBACK("mask CA + SA\n");
476 if (!NV30EXACheckCompositeTexture(pmPict))
477 FALLBACK("mask picture\n");
484 NV30EXAPrepareComposite(int op, PicturePtr psPict,
491 ScrnInfoPtr pScrn = xf86Screens[psPix->drawable.pScreen->myNum];
492 NVPtr pNv = NVPTR(pScrn);
494 int fpid = NV30EXA_FPID_PASS_COL0;
497 blend = NV30_GetPictOpRec(op);
499 NV30_SetupBlend(pScrn, blend, pdPict->format,
500 (pmPict && pmPict->componentAlpha &&
501 PICT_FORMAT_RGB(pmPict->format)));
503 NV30_SetupSurface(pScrn, pdPix, pdPict);
504 NV30EXATexture(pScrn, psPix, psPict, 0);
507 #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)
508 ErrorF("Preparecomposite src(%dx%d)",psPict->pDrawable->width,psPict->pDrawable->height);
509 printformat((psPict->format));
510 ErrorF(" dst(%dx%d)",pdPict->pDrawable->width,pdPict->pDrawable->height);
511 printformat((pdPict->format));
514 ErrorF(" mask(%dx%d)",pmPict->pDrawable->width,pmPict->pDrawable->height);
515 printformat((pmPict->format));
521 NV30EXATexture(pScrn, pmPix, pmPict, 1);
523 if (pmPict->componentAlpha && PICT_FORMAT_RGB(pmPict->format)) {
524 if (blend->src_alpha)
525 fpid = NV30EXA_FPID_COMPOSITE_MASK_SA_CA;
527 fpid = NV30EXA_FPID_COMPOSITE_MASK_CA;
529 fpid = NV30EXA_FPID_COMPOSITE_MASK;
532 state->have_mask = TRUE;
534 fpid = NV30EXA_FPID_PASS_TEX0;
536 state->have_mask = FALSE;
539 if (pdPict->format == PICT_a8)
540 NV30_LoadFragProg(pScrn, nv40_fp_map_a8[fpid]);
542 NV30_LoadFragProg(pScrn, nv40_fp_map[fpid]);
544 BEGIN_RING(Nv3D, 0x23c, 1);
545 OUT_RING (pmPict?3:1);
547 BEGIN_RING(Nv3D, NV34_TCL_PRIMITIVE_3D_VERTEX_BEGIN_END, 1);
548 OUT_RING (8); /* GL_QUADS */
553 #define xFixedToFloat(v) \
554 ((float)xFixedToInt((v)) + ((float)xFixedFrac(v) / 65536.0))
557 NV30EXATransformCoord(PictTransformPtr t, int x, int y, float sx, float sy,
558 float *x_ret, float *y_ret)
563 v.vector[0] = IntToxFixed(x);
564 v.vector[1] = IntToxFixed(y);
565 v.vector[2] = xFixed1;
566 PictureTransformPoint(t, &v);
567 *x_ret = xFixedToFloat(v.vector[0]);
568 *y_ret = xFixedToFloat(v.vector[1]);
575 #define CV_OUTm(sx,sy,mx,my,dx,dy) do { \
576 BEGIN_RING(Nv3D, NV34_TCL_PRIMITIVE_3D_VERTEX_ATTR_2F_X(8), 4); \
577 OUT_RINGf ((sx)); OUT_RINGf ((sy)); \
578 OUT_RINGf ((mx)); OUT_RINGf ((my)); \
579 BEGIN_RING(Nv3D, NV34_TCL_PRIMITIVE_3D_VERTEX_ATTR_2I(0), 1); \
580 OUT_RING (((dy)<<16)|(dx)); \
582 #define CV_OUT(sx,sy,dx,dy) do { \
583 BEGIN_RING(Nv3D, NV34_TCL_PRIMITIVE_3D_VERTEX_ATTR_2F_X(8), 2); \
584 OUT_RINGf ((sx)); OUT_RINGf ((sy)); \
585 BEGIN_RING(Nv3D, NV34_TCL_PRIMITIVE_3D_VERTEX_ATTR_2I(0), 1); \
586 OUT_RING (((dy)<<16)|(dx)); \
590 NV30EXAComposite(PixmapPtr pdPix, int srcX , int srcY,
591 int maskX, int maskY,
593 int width, int height)
595 ScrnInfoPtr pScrn = xf86Screens[pdPix->drawable.pScreen->myNum];
596 NVPtr pNv = NVPTR(pScrn);
597 float sX0, sX1, sY0, sY1;
598 float mX0, mX1, mY0, mY1;
602 ErrorF("Composite [%dx%d] (%d,%d)IN(%d,%d)OP(%d,%d)\n",width,height,srcX,srcY,maskX,maskY,dstX,dstY);
604 NV30EXATransformCoord(state->unit[0].transform, srcX, srcY,
605 state->unit[0].width,
606 state->unit[0].height, &sX0, &sY0);
607 NV30EXATransformCoord(state->unit[0].transform,
608 srcX + width, srcY + height,
609 state->unit[0].width,
610 state->unit[0].height, &sX1, &sY1);
612 if (state->have_mask) {
613 NV30EXATransformCoord(state->unit[1].transform, maskX, maskY,
614 state->unit[1].width,
615 state->unit[1].height, &mX0, &mY0);
616 NV30EXATransformCoord(state->unit[1].transform,
617 maskX + width, maskY + height,
618 state->unit[1].width,
619 state->unit[1].height, &mX1, &mY1);
620 CV_OUTm(sX0 , sY0 , mX0, mY0, dstX , dstY);
621 CV_OUTm(sX1 , sY0 , mX1, mY0, dstX + width, dstY);
622 CV_OUTm(sX1 , sY1 , mX1, mY1, dstX + width, dstY + height);
623 CV_OUTm(sX0 , sY1 , mX0, mY1, dstX , dstY + height);
625 CV_OUT(sX0 , sY0 , dstX , dstY);
626 CV_OUT(sX1 , sY0 , dstX + width, dstY);
627 CV_OUT(sX1 , sY1 , dstX + width, dstY + height);
628 CV_OUT(sX0 , sY1 , dstX , dstY + height);
633 NV30EXADoneComposite(PixmapPtr pdPix)
635 ScrnInfoPtr pScrn = xf86Screens[pdPix->drawable.pScreen->myNum];
636 NVPtr pNv = NVPTR(pScrn);
638 BEGIN_RING(Nv3D, NV34_TCL_PRIMITIVE_3D_VERTEX_BEGIN_END, 1);
645 NVAccelInitNV30TCL(ScrnInfoPtr pScrn)
647 NVPtr pNv = NVPTR(pScrn);
648 static int have_object = FALSE;
649 uint32_t class = 0, chipset;
652 NV30EXAHackupA8Shaders(pScrn);
654 #undef NV30_TCL_PRIMITIVE_3D
655 #define NV30_TCL_PRIMITIVE_3D 0x0397
656 #define NV30_TCL_PRIMITIVE_3D_CHIPSET_3X_MASK 0x00000003
657 #define NV35_TCL_PRIMITIVE_3D 0x0497
658 #define NV35_TCL_PRIMITIVE_3D_CHIPSET_3X_MASK 0x000001e0
659 #define NV34_TCL_PRIMITIVE_3D_CHIPSET_3X_MASK 0x00000010
661 chipset = (nvReadMC(pNv, 0) >> 20) & 0xff;
662 if ((chipset & 0xf0) != NV_ARCH_30)
666 if (NV30_TCL_PRIMITIVE_3D_CHIPSET_3X_MASK & (1<<chipset))
667 class = NV30_TCL_PRIMITIVE_3D;
668 else if (NV35_TCL_PRIMITIVE_3D_CHIPSET_3X_MASK & (1<<chipset))
669 class = NV35_TCL_PRIMITIVE_3D;
670 else if (NV34_TCL_PRIMITIVE_3D_CHIPSET_3X_MASK & (1<<chipset))
671 class = NV34_TCL_PRIMITIVE_3D;
673 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
674 "NV30EXA: Unknown chipset NV3%1x\n", chipset);
679 if (!NVDmaCreateContextObject(pNv, Nv3D, class))
684 BEGIN_RING(Nv3D, NV34_TCL_PRIMITIVE_3D_DMA_IN_MEMORY0, 3);
688 BEGIN_RING(Nv3D, NV34_TCL_PRIMITIVE_3D_DMA_IN_MEMORY7, 1);
690 BEGIN_RING(Nv3D, NV34_TCL_PRIMITIVE_3D_DMA_IN_MEMORY3, 2);
693 BEGIN_RING(Nv3D, NV34_TCL_PRIMITIVE_3D_DMA_IN_MEMORY8, 1);
696 for(i = 0x2c8; i <= 0x2fc; i += 4)
698 BEGIN_RING(Nv3D, i, 1);
702 BEGIN_RING(Nv3D, 0x220, 1);
705 BEGIN_RING(Nv3D, 0x03b0, 1);
706 OUT_RING (0x00100000);
707 BEGIN_RING(Nv3D, 0x1454, 1);
709 BEGIN_RING(Nv3D, 0x1d80, 1);
713 BEGIN_RING(Nv3D, 0x1e98, 1);
715 BEGIN_RING(Nv3D, 0x17e0, 3);
718 OUT_RING (0x3f800000);
719 BEGIN_RING(Nv3D, 0x1f80, 16);
720 OUT_RING (0); OUT_RING (0); OUT_RING (0); OUT_RING (0);
721 OUT_RING (0); OUT_RING (0); OUT_RING (0); OUT_RING (0);
722 OUT_RING (0x0000ffff);
723 OUT_RING (0); OUT_RING (0); OUT_RING (0); OUT_RING (0);
724 OUT_RING (0); OUT_RING (0); OUT_RING (0);
726 BEGIN_RING(Nv3D, 0x120, 3);
731 BEGIN_RING(Nv3D, 0x1d88, 1);
732 OUT_RING (0x00001200);
734 BEGIN_RING(Nv3D, NV34_TCL_PRIMITIVE_3D_RC_ENABLE, 1);
737 /* Attempt to setup a known state.. Probably missing a heap of
740 BEGIN_RING(Nv3D, NV34_TCL_PRIMITIVE_3D_STENCIL_FRONT_ENABLE, 1);
742 BEGIN_RING(Nv3D, NV34_TCL_PRIMITIVE_3D_STENCIL_BACK_ENABLE, 1);
744 BEGIN_RING(Nv3D, NV34_TCL_PRIMITIVE_3D_ALPHA_FUNC_ENABLE, 1);
746 BEGIN_RING(Nv3D, NV34_TCL_PRIMITIVE_3D_DEPTH_WRITE_ENABLE, 2);
747 OUT_RING (0); /* wr disable */
748 OUT_RING (0); /* test disable */
749 BEGIN_RING(Nv3D, NV34_TCL_PRIMITIVE_3D_COLOR_MASK, 1);
750 OUT_RING (0x01010101); /* TR,TR,TR,TR */
751 BEGIN_RING(Nv3D, NV34_TCL_PRIMITIVE_3D_CULL_FACE_ENABLE, 1);
753 BEGIN_RING(Nv3D, NV34_TCL_PRIMITIVE_3D_BLEND_FUNC_ENABLE, 1);
755 BEGIN_RING(Nv3D, NV34_TCL_PRIMITIVE_3D_COLOR_LOGIC_OP_ENABLE, 2);
757 OUT_RING (0x1503 /*GL_COPY*/);
758 BEGIN_RING(Nv3D, NV34_TCL_PRIMITIVE_3D_DITHER_ENABLE, 1);
760 BEGIN_RING(Nv3D, NV34_TCL_PRIMITIVE_3D_SHADE_MODEL, 1);
761 OUT_RING (0x1d01 /*GL_SMOOTH*/);
762 BEGIN_RING(Nv3D, NV34_TCL_PRIMITIVE_3D_POLYGON_OFFSET_FACTOR,2);
765 BEGIN_RING(Nv3D, NV34_TCL_PRIMITIVE_3D_POLYGON_MODE_FRONT, 2);
766 OUT_RING (0x1b02 /*GL_FILL*/);
767 OUT_RING (0x1b02 /*GL_FILL*/);
768 /* - Disable texture units
769 * - Set fragprog to MOVR result.color, fragment.color */
772 NV34_TCL_PRIMITIVE_3D_TX_ENABLE(i), 1);
775 /* Polygon stipple */
777 NV34_TCL_PRIMITIVE_3D_POLYGON_STIPPLE_PATTERN(0), 0x20);
779 OUT_RING (0xFFFFFFFF);
781 /* Ok. If you start X with the nvidia driver, kill it, and then
782 * start X with nouveau you will get black rendering instead of
783 * what you'd expect. This fixes the problem, and it seems that
784 * it's not needed between nouveau restarts - which suggests that
785 * the 3D context (wherever it's stored?) survives somehow.
787 //BEGIN_RING(Nv3D, 0x1d60,1);
788 //OUT_RING (0x03008000);
793 BEGIN_RING(Nv3D, NV34_TCL_PRIMITIVE_3D_VIEWPORT_HORIZ, 5);
796 OUT_RING (0x148); /* format */
797 OUT_RING (pitch << 16 | pitch);
799 BEGIN_RING(Nv3D, 0x0a00, 2);
800 OUT_RING ((w<<16) | 0);
801 OUT_RING ((h<<16) | 0);
802 BEGIN_RING(Nv3D, NV34_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_HORIZ(0), 2);
803 OUT_RING ((w-1)<<16);
804 OUT_RING ((h-1)<<16);
805 BEGIN_RING(Nv3D, NV34_TCL_PRIMITIVE_3D_SCISSOR_HORIZ, 2);
808 BEGIN_RING(Nv3D, NV34_TCL_PRIMITIVE_3D_VIEWPORT_HORIZ, 2);
812 BEGIN_RING(Nv3D, NV34_TCL_PRIMITIVE_3D_VIEWPORT_SCALE0_X, 8);
822 BEGIN_RING(Nv3D, NV34_TCL_PRIMITIVE_3D_MODELVIEW_MATRIX(0), 16);
840 BEGIN_RING(Nv3D, NV34_TCL_PRIMITIVE_3D_PROJECTION_MATRIX(0), 16);
858 BEGIN_RING(Nv3D, NV34_TCL_PRIMITIVE_3D_SCISSOR_HORIZ, 2);
867 #endif /* ENABLE_NV30EXA */