Check for SYS/GL during library init. Reason is that
[AROS.git] / workbench / hidds / nouveau / xf86-video-nouveau / nv30_exa.c
blobe64e38e77bed4ecc0763d2ad4717affdd056b646
1 /*
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
23 * SOFTWARE.
26 #include "nv_include.h"
27 #include "nv30_shaders.h"
28 #include "nv04_pushbuf.h"
29 #if defined(__AROS__)
30 #include <aros/debug.h>
31 #define NV30EXA_STATE
32 #endif
34 typedef struct nv_pict_surface_format {
35 int pict_fmt;
36 uint32_t card_fmt;
37 } nv_pict_surface_format_t;
39 typedef struct nv_pict_texture_format {
40 int pict_fmt;
41 uint32_t card_fmt;
42 uint32_t card_swz;
43 } nv_pict_texture_format_t;
45 typedef struct nv_pict_op {
46 Bool src_alpha;
47 Bool dst_alpha;
48 uint32_t src_card_op;
49 uint32_t dst_card_op;
50 } nv_pict_op_t;
52 typedef struct nv30_exa_state {
53 Bool have_mask;
55 struct {
56 PictTransformPtr transform;
57 float width;
58 float height;
59 } unit[2];
60 } nv30_exa_state_t;
61 #if !defined(__AROS__)
62 static nv30_exa_state_t exa_state;
63 #define NV30EXA_STATE nv30_exa_state_t *state = &exa_state
64 #endif
66 static nv_pict_surface_format_t
67 NV30SurfaceFormat[] = {
68 { PICT_a8r8g8b8 , 0x148 },
69 { PICT_a8b8g8r8 , 0x150 },
70 { PICT_x8r8g8b8 , 0x145 },
71 { PICT_x8b8g8r8 , 0x14f },
72 { PICT_r5g6b5 , 0x143 },
73 { PICT_a8 , 0x149 },
74 { PICT_x1r5g5b5 , 0x142 },
77 static nv_pict_surface_format_t *
78 NV30_GetPictSurfaceFormat(int format)
80 int i;
82 for(i=0;i<sizeof(NV30SurfaceFormat)/sizeof(NV30SurfaceFormat[0]);i++)
84 if (NV30SurfaceFormat[i].pict_fmt == format)
85 return &NV30SurfaceFormat[i];
88 return NULL;
91 enum {
92 NV30EXA_FPID_PASS_COL0 = 0,
93 NV30EXA_FPID_PASS_TEX0 = 1,
94 NV30EXA_FPID_COMPOSITE_MASK = 2,
95 NV30EXA_FPID_COMPOSITE_MASK_SA_CA = 3,
96 NV30EXA_FPID_COMPOSITE_MASK_CA = 4,
97 NV30EXA_FPID_MAX = 5
98 } NV30EXA_FPID;
100 static nv_shader_t *nv40_fp_map[NV30EXA_FPID_MAX] = {
101 &nv30_fp_pass_col0,
102 &nv30_fp_pass_tex0,
103 &nv30_fp_composite_mask,
104 &nv30_fp_composite_mask_sa_ca,
105 &nv30_fp_composite_mask_ca
108 static nv_shader_t *nv40_fp_map_a8[NV30EXA_FPID_MAX];
110 static void
111 NV30EXAHackupA8Shaders(ScrnInfoPtr pScrn)
113 int s;
115 for (s = 0; s < NV30EXA_FPID_MAX; s++) {
116 nv_shader_t *def, *a8;
118 def = nv40_fp_map[s];
119 a8 = calloc(1, sizeof(nv_shader_t));
120 a8->card_priv.NV30FP.num_regs = def->card_priv.NV30FP.num_regs;
121 a8->size = def->size + 4;
122 memcpy(a8->data, def->data, def->size * sizeof(uint32_t));
123 nv40_fp_map_a8[s] = a8;
125 a8->data[a8->size - 8 + 0] &= ~0x00000081;
126 a8->data[a8->size - 4 + 0] = 0x01401e81;
127 a8->data[a8->size - 4 + 1] = 0x1c9dfe00;
128 a8->data[a8->size - 4 + 2] = 0x0001c800;
129 a8->data[a8->size - 4 + 3] = 0x0001c800;
133 /* should be in nouveau_reg.h at some point.. */
134 #define NV34TCL_TX_SWIZZLE_UNIT_S0_X_ZERO 0
135 #define NV34TCL_TX_SWIZZLE_UNIT_S0_X_ONE 1
136 #define NV34TCL_TX_SWIZZLE_UNIT_S0_X_S1 2
138 #define NV34TCL_TX_SWIZZLE_UNIT_S0_X_SHIFT 14
139 #define NV34TCL_TX_SWIZZLE_UNIT_S0_Y_SHIFT 12
140 #define NV34TCL_TX_SWIZZLE_UNIT_S0_Z_SHIFT 10
141 #define NV34TCL_TX_SWIZZLE_UNIT_S0_W_SHIFT 8
143 #define NV34TCL_TX_SWIZZLE_UNIT_S1_X_X 3
144 #define NV34TCL_TX_SWIZZLE_UNIT_S1_X_Y 2
145 #define NV34TCL_TX_SWIZZLE_UNIT_S1_X_Z 1
146 #define NV34TCL_TX_SWIZZLE_UNIT_S1_X_W 0
148 #define NV34TCL_TX_SWIZZLE_UNIT_S1_X_SHIFT 6
149 #define NV34TCL_TX_SWIZZLE_UNIT_S1_Y_SHIFT 4
150 #define NV34TCL_TX_SWIZZLE_UNIT_S1_Z_SHIFT 2
151 #define NV34TCL_TX_SWIZZLE_UNIT_S1_W_SHIFT 0
153 #define _(r,tf,ts0x,ts0y,ts0z,ts0w,ts1x,ts1y,ts1z,ts1w) \
155 PICT_##r, \
156 (tf), \
157 (NV34TCL_TX_SWIZZLE_UNIT_S0_X_##ts0x << NV34TCL_TX_SWIZZLE_UNIT_S0_X_SHIFT)|\
158 (NV34TCL_TX_SWIZZLE_UNIT_S0_X_##ts0y << NV34TCL_TX_SWIZZLE_UNIT_S0_Y_SHIFT)|\
159 (NV34TCL_TX_SWIZZLE_UNIT_S0_X_##ts0z << NV34TCL_TX_SWIZZLE_UNIT_S0_Z_SHIFT)|\
160 (NV34TCL_TX_SWIZZLE_UNIT_S0_X_##ts0w << NV34TCL_TX_SWIZZLE_UNIT_S0_W_SHIFT)|\
161 (NV34TCL_TX_SWIZZLE_UNIT_S1_X_##ts1x << NV34TCL_TX_SWIZZLE_UNIT_S1_X_SHIFT)|\
162 (NV34TCL_TX_SWIZZLE_UNIT_S1_X_##ts1y << NV34TCL_TX_SWIZZLE_UNIT_S1_Y_SHIFT)|\
163 (NV34TCL_TX_SWIZZLE_UNIT_S1_X_##ts1z << NV34TCL_TX_SWIZZLE_UNIT_S1_Z_SHIFT)|\
164 (NV34TCL_TX_SWIZZLE_UNIT_S1_X_##ts1w << NV34TCL_TX_SWIZZLE_UNIT_S1_W_SHIFT)\
167 static nv_pict_texture_format_t
168 NV30TextureFormat[] = {
169 _(a8r8g8b8, 0x12, S1, S1, S1, S1, X, Y, Z, W),
170 _(a8b8g8r8, 0x12, S1, S1, S1, S1, Z, Y, X, W),
171 _(x8r8g8b8, 0x12, S1, S1, S1, ONE, X, Y, Z, W),
172 _(x8b8g8r8, 0x12, S1, S1, S1, ONE, Z, Y, X, W),
174 _(a1r5g5b5, 0x10, S1, S1, S1, S1, X, Y, Z, W),
175 _(x1r5g5b5, 0x10, S1, S1, S1, ONE, X, Y, Z, W),
176 _(a1b5g5r5, 0x10, S1, S1, S1, S1, Z, Y, X, W),
177 _(x1b5g5r5, 0x10, S1, S1, S1, ONE, Z, Y, X, W),
179 _(x4r4g4b4, 0x1d, S1, S1, S1, ONE, X, Y, Z, W),
180 _(a4r4g4b4, 0x1d, S1, S1, S1, S1, X, Y, Z, W),
181 _(x4b4g4r4, 0x1d, S1, S1, S1, ONE, Z, Y, X, W),
182 _(a4b4g4r4, 0x1d, S1, S1, S1, S1, Z, Y, X, W),
184 _( a8, 0x1b, ZERO, ZERO, ZERO, S1, X, X, X, X),
186 _( r5g6b5, 0x11, S1, S1, S1, ONE, X, Y, Z, W),
187 _( b5g6r5, 0x11, S1, S1, S1, ONE, Z, Y, X, W),
191 static nv_pict_texture_format_t *
192 NV30_GetPictTextureFormat(int format)
194 int i;
196 for(i=0;i<sizeof(NV30TextureFormat)/sizeof(NV30TextureFormat[0]);i++)
198 if (NV30TextureFormat[i].pict_fmt == format)
199 return &NV30TextureFormat[i];
202 return NULL;
205 #define NV34TCL_BF_ZERO 0x0000
206 #define NV34TCL_BF_ONE 0x0001
207 #define NV34TCL_BF_SRC_COLOR 0x0300
208 #define NV34TCL_BF_ONE_MINUS_SRC_COLOR 0x0301
209 #define NV34TCL_BF_SRC_ALPHA 0x0302
210 #define NV34TCL_BF_ONE_MINUS_SRC_ALPHA 0x0303
211 #define NV34TCL_BF_DST_ALPHA 0x0304
212 #define NV34TCL_BF_ONE_MINUS_DST_ALPHA 0x0305
213 #define NV34TCL_BF_DST_COLOR 0x0306
214 #define NV34TCL_BF_ONE_MINUS_DST_COLOR 0x0307
215 #define NV34TCL_BF_ALPHA_SATURATE 0x0308
216 #define BF(bf) NV34TCL_BF_##bf
218 static nv_pict_op_t
219 NV30PictOp[] = {
220 /* Clear */ { 0, 0, BF( ZERO), BF( ZERO) },
221 /* Src */ { 0, 0, BF( ONE), BF( ZERO) },
222 /* Dst */ { 0, 0, BF( ZERO), BF( ONE) },
223 /* Over */ { 1, 0, BF( ONE), BF(ONE_MINUS_SRC_ALPHA) },
224 /* OverReverse */ { 0, 1, BF(ONE_MINUS_DST_ALPHA), BF( ONE) },
225 /* In */ { 0, 1, BF( DST_ALPHA), BF( ZERO) },
226 /* InReverse */ { 1, 0, BF( ZERO), BF( SRC_ALPHA) },
227 /* Out */ { 0, 1, BF(ONE_MINUS_DST_ALPHA), BF( ZERO) },
228 /* OutReverse */ { 1, 0, BF( ZERO), BF(ONE_MINUS_SRC_ALPHA) },
229 /* Atop */ { 1, 1, BF( DST_ALPHA), BF(ONE_MINUS_SRC_ALPHA) },
230 /* AtopReverse */ { 1, 1, BF(ONE_MINUS_DST_ALPHA), BF( SRC_ALPHA) },
231 /* Xor */ { 1, 1, BF(ONE_MINUS_DST_ALPHA), BF(ONE_MINUS_SRC_ALPHA) },
232 /* Add */ { 0, 0, BF( ONE), BF( ONE) },
233 /* OverAlpha */ { 1, 0, BF( SRC_ALPHA), BF(ONE_MINUS_SRC_ALPHA) }
236 static nv_pict_op_t *
237 NV30_GetPictOpRec(int op)
239 if (op >= PictOpSaturate)
240 return NULL;
241 #if 0
242 switch(op)
244 case 0:ErrorF("Op Clear\n");break;
245 case 1:ErrorF("Op Src\n");break;
246 case 2:ErrorF("Op Dst\n");break;
247 case 3:ErrorF("Op Over\n");break;
248 case 4:ErrorF("Op OverReverse\n");break;
249 case 5:ErrorF("Op In\n");break;
250 case 6:ErrorF("Op InReverse\n");break;
251 case 7:ErrorF("Op Out\n");break;
252 case 8:ErrorF("Op OutReverse\n");break;
253 case 9:ErrorF("Op Atop\n");break;
254 case 10:ErrorF("Op AtopReverse\n");break;
255 case 11:ErrorF("Op Xor\n");break;
256 case 12:ErrorF("Op Add\n");break;
258 #endif
259 return &NV30PictOp[op];
262 static void
263 NV30_SetupBlend(ScrnInfoPtr pScrn, nv_pict_op_t *blend,
264 PictFormatShort dest_format, Bool component_alpha)
266 NVPtr pNv = NVPTR(pScrn);
267 struct nouveau_channel *chan = pNv->chan;
268 struct nouveau_grobj *rankine = pNv->Nv3D;
269 uint32_t sblend, dblend;
271 sblend = blend->src_card_op;
272 dblend = blend->dst_card_op;
274 if (blend->dst_alpha) {
275 if (!PICT_FORMAT_A(dest_format)) {
276 if (sblend == BF(DST_ALPHA)) {
277 sblend = BF(ONE);
278 } else if (sblend == BF(ONE_MINUS_DST_ALPHA)) {
279 sblend = BF(ZERO);
281 } else if (dest_format == PICT_a8) {
282 if (sblend == BF(DST_ALPHA)) {
283 sblend = BF(DST_COLOR);
284 } else if (sblend == BF(ONE_MINUS_DST_ALPHA)) {
285 sblend = BF(ONE_MINUS_DST_COLOR);
290 if (blend->src_alpha && (component_alpha || dest_format == PICT_a8)) {
291 if (dblend == BF(SRC_ALPHA)) {
292 dblend = BF(SRC_COLOR);
293 } else if (dblend == BF(ONE_MINUS_SRC_ALPHA)) {
294 dblend = BF(ONE_MINUS_SRC_COLOR);
298 if (sblend == BF(ONE) && dblend == BF(ZERO)) {
299 BEGIN_RING(chan, rankine, NV34TCL_BLEND_FUNC_ENABLE, 1);
300 OUT_RING (chan, 0);
301 } else {
302 BEGIN_RING(chan, rankine, NV34TCL_BLEND_FUNC_ENABLE, 3);
303 OUT_RING (chan, 1);
304 OUT_RING (chan, (sblend << 16) | sblend);
305 OUT_RING (chan, (dblend << 16) | dblend);
309 #if !defined(__AROS__)
310 static Bool
311 NV30EXATexture(ScrnInfoPtr pScrn, PixmapPtr pPix, PicturePtr pPict, int unit)
312 #else
313 static Bool
314 NV30EXATexture(ScrnInfoPtr pScrn, PixmapPtr pPix, PicturePtr pPict, int unit, nv30_exa_state_t * state)
315 #endif
317 NVPtr pNv = NVPTR(pScrn);
318 struct nouveau_channel *chan = pNv->chan;
319 struct nouveau_grobj *rankine = pNv->Nv3D;
320 struct nouveau_bo *bo = nouveau_pixmap_bo(pPix);
321 nv_pict_texture_format_t *fmt;
322 uint32_t card_filter, card_repeat;
323 uint32_t tex_reloc = NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD;
324 NV30EXA_STATE;
326 fmt = NV30_GetPictTextureFormat(pPict->format);
327 if (!fmt)
328 return FALSE;
330 card_repeat = 3; /* repeatNone */
332 if (pPict->filter == PictFilterBilinear)
333 card_filter = 2;
334 else
335 card_filter = 1;
337 BEGIN_RING(chan, rankine, NV34TCL_TX_OFFSET(unit), 8);
338 if (OUT_RELOCl(chan, bo, 0, tex_reloc) ||
339 OUT_RELOCd(chan, bo, NV34TCL_TX_FORMAT_DIMS_2D | (1 << 16) | 8 |
340 (fmt->card_fmt << NV34TCL_TX_FORMAT_FORMAT_SHIFT) |
341 #if !defined(__AROS__)
342 (log2i(pPix->drawable.width) <<
343 #else
344 (log2i(pPix->width) <<
345 #endif
346 NV34TCL_TX_FORMAT_BASE_SIZE_U_SHIFT) |
347 #if !defined(__AROS__)
348 (log2i(pPix->drawable.height) <<
349 #else
350 (log2i(pPix->height) <<
351 #endif
352 NV34TCL_TX_FORMAT_BASE_SIZE_V_SHIFT),
353 tex_reloc | NOUVEAU_BO_OR,
354 NV34TCL_TX_FORMAT_DMA0, NV34TCL_TX_FORMAT_DMA1))
355 return FALSE;
356 OUT_RING (chan, (card_repeat << NV34TCL_TX_WRAP_S_SHIFT) |
357 (card_repeat << NV34TCL_TX_WRAP_T_SHIFT) |
358 (card_repeat << NV34TCL_TX_WRAP_R_SHIFT));
359 OUT_RING (chan, NV34TCL_TX_ENABLE_ENABLE);
360 OUT_RING (chan, (((uint32_t)exaGetPixmapPitch(pPix)) << NV34TCL_TX_SWIZZLE_RECT_PITCH_SHIFT ) |
361 fmt->card_swz);
363 OUT_RING (chan, (card_filter << NV34TCL_TX_FILTER_MINIFY_SHIFT) /* min */ |
364 (card_filter << NV34TCL_TX_FILTER_MAGNIFY_SHIFT) /* mag */ |
365 0x2000 /* engine lock */);
366 #if !defined(__AROS__)
367 OUT_RING (chan, (pPix->drawable.width << NV34TCL_TX_NPOT_SIZE_W_SHIFT) | pPix->drawable.height);
368 OUT_RING (chan, 0); /* border ARGB */
370 state->unit[unit].width = (float)pPix->drawable.width;
371 state->unit[unit].height = (float)pPix->drawable.height;
372 state->unit[unit].transform = pPict->transform;
373 #else
374 OUT_RING (chan, (pPix->width << NV34TCL_TX_NPOT_SIZE_W_SHIFT) | pPix->height);
375 OUT_RING (chan, 0); /* border ARGB */
377 state->unit[unit].width = (float)pPix->width;
378 state->unit[unit].height = (float)pPix->height;
379 state->unit[unit].transform = NULL; /* Keep this NULL, we are doing simple blits */
380 #endif
382 return TRUE;
385 static Bool
386 NV30_SetupSurface(ScrnInfoPtr pScrn, PixmapPtr pPix, PicturePtr pPict)
388 NVPtr pNv = NVPTR(pScrn);
389 struct nouveau_channel *chan = pNv->chan;
390 struct nouveau_grobj *rankine = pNv->Nv3D;
391 struct nouveau_bo *bo = nouveau_pixmap_bo(pPix);
392 nv_pict_surface_format_t *fmt;
394 fmt = NV30_GetPictSurfaceFormat(pPict->format);
395 if (!fmt) {
396 ErrorF("AIII no format\n");
397 return FALSE;
400 uint32_t pitch = (uint32_t)exaGetPixmapPitch(pPix);
402 BEGIN_RING(chan, rankine, NV34TCL_RT_FORMAT, 3);
403 OUT_RING (chan, fmt->card_fmt); /* format */
404 OUT_RING (chan, pitch << 16 | pitch);
405 if (OUT_RELOCl(chan, bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR))
406 return FALSE;
408 return TRUE;
411 #if !defined(__AROS__)
412 static Bool
413 NV30EXACheckCompositeTexture(PicturePtr pPict, PicturePtr pdPict, int op)
415 nv_pict_texture_format_t *fmt;
416 int w, h;
418 if (!pPict->pDrawable)
419 NOUVEAU_FALLBACK("Solid and gradient pictures unsupported\n");
421 w = pPict->pDrawable->width;
422 h = pPict->pDrawable->height;
424 if ((w > 4096) || (h > 4096))
425 NOUVEAU_FALLBACK("picture too large, %dx%d\n", w, h);
427 fmt = NV30_GetPictTextureFormat(pPict->format);
428 if (!fmt)
429 NOUVEAU_FALLBACK("picture format 0x%08x not supported\n",
430 pPict->format);
432 if (pPict->filter != PictFilterNearest &&
433 pPict->filter != PictFilterBilinear)
434 NOUVEAU_FALLBACK("filter 0x%x not supported\n", pPict->filter);
436 if (!(w==1 && h==1) && pPict->repeat && pPict->repeatType != RepeatNone)
437 NOUVEAU_FALLBACK("repeat 0x%x not supported (surface %dx%d)\n",
438 pPict->repeatType,w,h);
440 /* Opengl and Render disagree on what should be sampled outside an XRGB
441 * texture (with no repeating). Opengl has a hardcoded alpha value of
442 * 1.0, while render expects 0.0. We assume that clipping is done for
443 * untranformed sources.
445 if (NV30PictOp[op].src_alpha && !pPict->repeat &&
446 pPict->transform && (PICT_FORMAT_A(pPict->format) == 0)
447 && (PICT_FORMAT_A(pdPict->format) != 0))
448 NOUVEAU_FALLBACK("REPEAT_NONE unsupported for XRGB source\n");
450 return TRUE;
453 Bool
454 NV30EXACheckComposite(int op, PicturePtr psPict,
455 PicturePtr pmPict,
456 PicturePtr pdPict)
458 nv_pict_surface_format_t *fmt;
459 nv_pict_op_t *opr;
461 opr = NV30_GetPictOpRec(op);
462 if (!opr)
463 NOUVEAU_FALLBACK("unsupported blend op 0x%x\n", op);
465 fmt = NV30_GetPictSurfaceFormat(pdPict->format);
466 if (!fmt)
467 NOUVEAU_FALLBACK("dst picture format 0x%08x not supported\n",
468 pdPict->format);
470 if (!NV30EXACheckCompositeTexture(psPict, pdPict, op))
471 NOUVEAU_FALLBACK("src picture\n");
472 if (pmPict) {
473 if (pmPict->componentAlpha &&
474 PICT_FORMAT_RGB(pmPict->format) &&
475 opr->src_alpha && opr->src_card_op != BF(ZERO))
476 NOUVEAU_FALLBACK("mask CA + SA\n");
477 if (!NV30EXACheckCompositeTexture(pmPict, pdPict, op))
478 NOUVEAU_FALLBACK("mask picture\n");
481 return TRUE;
484 static void
485 NV30EXAStateCompositeReemit(struct nouveau_channel *chan)
487 ScrnInfoPtr pScrn = chan->user_private;
488 NVPtr pNv = NVPTR(pScrn);
490 NV30EXAPrepareComposite(pNv->alu, pNv->pspict, pNv->pmpict, pNv->pdpict,
491 pNv->pspix, pNv->pmpix, pNv->pdpix);
493 #endif
495 #if !defined(__AROS__)
496 Bool
497 NV30EXAPrepareComposite(int op, PicturePtr psPict,
498 PicturePtr pmPict,
499 PicturePtr pdPict,
500 PixmapPtr psPix,
501 PixmapPtr pmPix,
502 PixmapPtr pdPix)
504 ScrnInfoPtr pScrn = xf86Screens[psPix->drawable.pScreen->myNum];
505 #else
506 static Bool
507 NV30EXAPrepareComposite(int op, PicturePtr psPict,
508 PicturePtr pmPict,
509 PicturePtr pdPict,
510 PixmapPtr psPix,
511 PixmapPtr pmPix,
512 PixmapPtr pdPix,
513 nv30_exa_state_t * state)
515 ScrnInfoPtr pScrn = globalcarddataptr;
516 #endif
517 NVPtr pNv = NVPTR(pScrn);
518 struct nouveau_channel *chan = pNv->chan;
519 struct nouveau_grobj *rankine = pNv->Nv3D;
520 nv_pict_op_t *blend;
521 int fpid = NV30EXA_FPID_PASS_COL0;
522 NV30EXA_STATE;
524 if (MARK_RING(chan, 128, 1 + 1 + 4))
525 return FALSE;
527 blend = NV30_GetPictOpRec(op);
529 NV30_SetupBlend(pScrn, blend, pdPict->format,
530 (pmPict && pmPict->componentAlpha &&
531 PICT_FORMAT_RGB(pmPict->format)));
533 if (!NV30_SetupSurface(pScrn, pdPix, pdPict) ||
534 #if !defined(__AROS__)
535 !NV30EXATexture(pScrn, psPix, psPict, 0)) {
536 #else
537 !NV30EXATexture(pScrn, psPix, psPict, 0, state)) {
538 #endif
539 MARK_UNDO(chan);
540 return FALSE;
543 #if 0
544 #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)
545 ErrorF("Preparecomposite src(%dx%d)",psPict->pDrawable->width,psPict->pDrawable->height);
546 printformat((psPict->format));
547 ErrorF(" dst(%dx%d)",pdPict->pDrawable->width,pdPict->pDrawable->height);
548 printformat((pdPict->format));
549 if (pmPict)
551 ErrorF(" mask(%dx%d)",pmPict->pDrawable->width,pmPict->pDrawable->height);
552 printformat((pmPict->format));
554 ErrorF("\n");
555 #endif
557 if (pmPict) {
558 #if !defined(__AROS__)
559 if (!NV30EXATexture(pScrn, pmPix, pmPict, 1)) {
560 #else
561 if (!NV30EXATexture(pScrn, pmPix, pmPict, 1, state)) {
562 #endif
563 MARK_UNDO(chan);
564 return FALSE;
567 if (pmPict->componentAlpha && PICT_FORMAT_RGB(pmPict->format)) {
568 if (blend->src_alpha)
569 fpid = NV30EXA_FPID_COMPOSITE_MASK_SA_CA;
570 else
571 fpid = NV30EXA_FPID_COMPOSITE_MASK_CA;
572 } else {
573 fpid = NV30EXA_FPID_COMPOSITE_MASK;
576 state->have_mask = TRUE;
577 } else {
578 fpid = NV30EXA_FPID_PASS_TEX0;
580 state->have_mask = FALSE;
583 if (!NV30_LoadFragProg(pScrn, (pdPict->format == PICT_a8) ?
584 nv40_fp_map_a8[fpid] : nv40_fp_map[fpid])) {
585 MARK_UNDO(chan);
586 return FALSE;
589 BEGIN_RING(chan, rankine, 0x23c, 1);
590 OUT_RING (chan, pmPict?3:1);
592 #if !defined(__AROS__)
593 pNv->alu = op;
594 pNv->pspict = psPict;
595 pNv->pmpict = pmPict;
596 pNv->pdpict = pdPict;
597 pNv->pspix = psPix;
598 pNv->pmpix = pmPix;
599 pNv->pdpix = pdPix;
600 chan->flush_notify = NV30EXAStateCompositeReemit;
601 #else
602 chan->flush_notify = NULL;
603 #endif
604 return TRUE;
607 #define xFixedToFloat(v) \
608 ((float)xFixedToInt((v)) + ((float)xFixedFrac(v) / 65536.0))
610 static void
611 NV30EXATransformCoord(PictTransformPtr t, int x, int y, float sx, float sy,
612 float *x_ret, float *y_ret)
614 #if !defined(__AROS__)
615 PictVector v;
616 #endif
618 if (t) {
619 /* Note: current t is always NULL in AROS. That is good enough for
620 operations being done (simple blits with alpha) */
621 #if !defined(__AROS__)
622 v.vector[0] = IntToxFixed(x);
623 v.vector[1] = IntToxFixed(y);
624 v.vector[2] = xFixed1;
625 PictureTransformPoint(t, &v);
626 *x_ret = xFixedToFloat(v.vector[0]);
627 *y_ret = xFixedToFloat(v.vector[1]);
628 #endif
629 } else {
630 *x_ret = (float)x;
631 *y_ret = (float)y;
635 #define CV_OUTm(sx,sy,mx,my,dx,dy) do { \
636 BEGIN_RING(chan, rankine, NV34TCL_VTX_ATTR_2F_X(8), 4); \
637 OUT_RINGf (chan, (sx)); OUT_RINGf (chan, (sy)); \
638 OUT_RINGf (chan, (mx)); OUT_RINGf (chan, (my)); \
639 BEGIN_RING(chan, rankine, NV34TCL_VTX_ATTR_2I(0), 1); \
640 OUT_RING (chan, ((dy)<<16)|(dx)); \
641 } while(0)
642 #define CV_OUT(sx,sy,dx,dy) do { \
643 BEGIN_RING(chan, rankine, NV34TCL_VTX_ATTR_2F_X(8), 2); \
644 OUT_RINGf (chan, (sx)); OUT_RINGf (chan, (sy)); \
645 BEGIN_RING(chan, rankine, NV34TCL_VTX_ATTR_2I(0), 1); \
646 OUT_RING (chan, ((dy)<<16)|(dx)); \
647 } while(0)
649 #if !defined(__AROS__)
650 void
651 NV30EXAComposite(PixmapPtr pdPix, int srcX , int srcY,
652 int maskX, int maskY,
653 int dstX , int dstY,
654 int width, int height)
656 ScrnInfoPtr pScrn = xf86Screens[pdPix->drawable.pScreen->myNum];
657 #else
658 static void
659 NV30EXAComposite(PixmapPtr pdPix, int srcX , int srcY,
660 int maskX, int maskY,
661 int dstX , int dstY,
662 int width, int height, nv30_exa_state_t * state)
664 ScrnInfoPtr pScrn = globalcarddataptr;
665 #endif
666 NVPtr pNv = NVPTR(pScrn);
667 struct nouveau_channel *chan = pNv->chan;
668 struct nouveau_grobj *rankine = pNv->Nv3D;
669 float sX0 = 0, sX1 = 0, sX2 = 0, sY0 = 0, sY1 = 0, sY2 = 0;
670 float mX0 = 0, mX1 = 0, mX2 = 0, mY0 = 0, mY1 = 0, mY2 = 0;
671 NV30EXA_STATE;
673 WAIT_RING(chan, 64);
675 /* We're drawing a triangle, we need to scissor it to a quad. */
676 /* The scissors are here for a good reason, we don't get the full image, but just a part. */
677 /* Handling the cliprects is done for us already. */
678 BEGIN_RING(chan, rankine, NV34TCL_SCISSOR_HORIZ, 2);
679 OUT_RING (chan, (width << 16) | dstX);
680 OUT_RING (chan, (height << 16) | dstY);
681 BEGIN_RING(chan, rankine, NV34TCL_VERTEX_BEGIN_END, 1);
682 OUT_RING (chan, NV34TCL_VERTEX_BEGIN_END_TRIANGLES);
684 #if 0
685 ErrorF("Composite [%dx%d] (%d,%d)IN(%d,%d)OP(%d,%d)\n",width,height,srcX,srcY,maskX,maskY,dstX,dstY);
686 #endif
687 NV30EXATransformCoord(state->unit[0].transform,
688 srcX, srcY - height,
689 state->unit[0].width,
690 state->unit[0].height, &sX0, &sY0);
691 NV30EXATransformCoord(state->unit[0].transform,
692 srcX, srcY + height,
693 state->unit[0].width,
694 state->unit[0].height, &sX1, &sY1);
695 NV30EXATransformCoord(state->unit[0].transform,
696 srcX + 2*width, srcY + height,
697 state->unit[0].width,
698 state->unit[0].height, &sX2, &sY2);
700 if (state->have_mask) {
701 NV30EXATransformCoord(state->unit[1].transform,
702 maskX, maskY - height,
703 state->unit[1].width,
704 state->unit[1].height, &mX0, &mY0);
705 NV30EXATransformCoord(state->unit[1].transform,
706 maskX, maskY + height,
707 state->unit[1].width,
708 state->unit[1].height, &mX1, &mY1);
709 NV30EXATransformCoord(state->unit[1].transform,
710 maskX + 2*width, maskY + height,
711 state->unit[1].width,
712 state->unit[1].height, &mX2, &mY2);
714 CV_OUTm(sX0 , sY0 , mX0, mY0, dstX , dstY - height);
715 CV_OUTm(sX1 , sY1 , mX1, mY1, dstX , dstY + height);
716 CV_OUTm(sX2 , sY2 , mX2, mY2, dstX + 2*width , dstY + height);
717 } else {
718 CV_OUT(sX0 , sY0 , dstX , dstY - height);
719 CV_OUT(sX1 , sY1 , dstX , dstY + height);
720 CV_OUT(sX2 , sY2 , dstX + 2*width , dstY + height);
723 BEGIN_RING(chan, rankine, NV34TCL_VERTEX_BEGIN_END, 1);
724 OUT_RING (chan, 0);
727 #if !defined(__AROS__)
728 void
729 NV30EXADoneComposite(PixmapPtr pdPix)
731 ScrnInfoPtr pScrn = xf86Screens[pdPix->drawable.pScreen->myNum];
732 NVPtr pNv = NVPTR(pScrn);
733 struct nouveau_channel *chan = pNv->chan;
735 chan->flush_notify = NULL;
737 #endif
739 Bool
740 NVAccelInitNV30TCL(ScrnInfoPtr pScrn)
742 NVPtr pNv = NVPTR(pScrn);
743 struct nouveau_channel *chan = pNv->chan;
744 struct nouveau_grobj *rankine;
745 uint32_t class = 0, chipset;
746 int next_hw_offset = 0, i;
748 if (!nv40_fp_map_a8[0])
749 NV30EXAHackupA8Shaders(pScrn);
751 #define NV30TCL_CHIPSET_3X_MASK 0x00000003
752 #define NV35TCL_CHIPSET_3X_MASK 0x000001e0
753 #define NV34TCL_CHIPSET_3X_MASK 0x00000010
755 chipset = pNv->dev->chipset;
756 if ((chipset & 0xf0) != NV_ARCH_30)
757 return TRUE;
758 chipset &= 0xf;
760 if (NV30TCL_CHIPSET_3X_MASK & (1<<chipset))
761 class = NV30TCL;
762 else if (NV35TCL_CHIPSET_3X_MASK & (1<<chipset))
763 class = NV35TCL;
764 else if (NV34TCL_CHIPSET_3X_MASK & (1<<chipset))
765 class = NV34TCL;
766 else {
767 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
768 "NV30EXA: Unknown chipset NV3%1x\n", chipset);
769 return FALSE;
773 if (!pNv->Nv3D) {
774 if (nouveau_grobj_alloc(chan, Nv3D, class, &pNv->Nv3D))
775 return FALSE;
777 rankine = pNv->Nv3D;
779 if (!pNv->shader_mem) {
780 if (nouveau_bo_new(pNv->dev, NOUVEAU_BO_VRAM | NOUVEAU_BO_MAP,
781 0, 0x1000, &pNv->shader_mem)) {
782 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
783 "Couldn't alloc fragprog buffer!\n");
784 nouveau_grobj_free(&pNv->Nv3D);
785 return FALSE;
789 BEGIN_RING(chan, rankine, NV34TCL_DMA_TEXTURE0, 3);
790 OUT_RING (chan, pNv->chan->vram->handle);
791 OUT_RING (chan, pNv->chan->gart->handle);
792 OUT_RING (chan, pNv->chan->vram->handle);
793 BEGIN_RING(chan, rankine, NV34TCL_DMA_IN_MEMORY7, 1);
794 OUT_RING (chan, pNv->chan->vram->handle);
795 BEGIN_RING(chan, rankine, NV34TCL_DMA_COLOR0, 2);
796 OUT_RING (chan, pNv->chan->vram->handle);
797 OUT_RING (chan, pNv->chan->vram->handle);
798 BEGIN_RING(chan, rankine, NV34TCL_DMA_IN_MEMORY8, 1);
799 OUT_RING (chan, pNv->chan->vram->handle);
801 for (i=1; i<8; i++) {
802 BEGIN_RING(chan, rankine, NV34TCL_VIEWPORT_CLIP_HORIZ(i), 2);
803 OUT_RING (chan, 0);
804 OUT_RING (chan, 0);
807 BEGIN_RING(chan, rankine, 0x220, 1);
808 OUT_RING (chan, 1);
810 BEGIN_RING(chan, rankine, 0x03b0, 1);
811 OUT_RING (chan, 0x00100000);
812 BEGIN_RING(chan, rankine, 0x1454, 1);
813 OUT_RING (chan, 0);
814 BEGIN_RING(chan, rankine, 0x1d80, 1);
815 OUT_RING (chan, 3);
816 BEGIN_RING(chan, rankine, 0x1450, 1);
817 OUT_RING (chan, 0x00030004);
819 /* NEW */
820 BEGIN_RING(chan, rankine, 0x1e98, 1);
821 OUT_RING (chan, 0);
822 BEGIN_RING(chan, rankine, 0x17e0, 3);
823 OUT_RING (chan, 0);
824 OUT_RING (chan, 0);
825 OUT_RING (chan, 0x3f800000);
826 BEGIN_RING(chan, rankine, 0x1f80, 16);
827 OUT_RING (chan, 0); OUT_RING (chan, 0); OUT_RING (chan, 0); OUT_RING (chan, 0);
828 OUT_RING (chan, 0); OUT_RING (chan, 0); OUT_RING (chan, 0); OUT_RING (chan, 0);
829 OUT_RING (chan, 0x0000ffff);
830 OUT_RING (chan, 0); OUT_RING (chan, 0); OUT_RING (chan, 0); OUT_RING (chan, 0);
831 OUT_RING (chan, 0); OUT_RING (chan, 0); OUT_RING (chan, 0);
833 BEGIN_RING(chan, rankine, 0x120, 3);
834 OUT_RING (chan, 0);
835 OUT_RING (chan, 1);
836 OUT_RING (chan, 2);
838 BEGIN_RING(chan, pNv->NvImageBlit, 0x120, 3);
839 OUT_RING (chan, 0);
840 OUT_RING (chan, 1);
841 OUT_RING (chan, 2);
843 BEGIN_RING(chan, rankine, 0x1d88, 1);
844 OUT_RING (chan, 0x00001200);
846 BEGIN_RING(chan, rankine, NV34TCL_RC_ENABLE, 1);
847 OUT_RING (chan, 0);
849 /* Attempt to setup a known state.. Probably missing a heap of
850 * stuff here..
852 BEGIN_RING(chan, rankine, NV34TCL_STENCIL_FRONT_ENABLE, 1);
853 OUT_RING (chan, 0);
854 BEGIN_RING(chan, rankine, NV34TCL_STENCIL_BACK_ENABLE, 1);
855 OUT_RING (chan, 0);
856 BEGIN_RING(chan, rankine, NV34TCL_ALPHA_FUNC_ENABLE, 1);
857 OUT_RING (chan, 0);
858 BEGIN_RING(chan, rankine, NV34TCL_DEPTH_WRITE_ENABLE, 2);
859 OUT_RING (chan, 0); /* wr disable */
860 OUT_RING (chan, 0); /* test disable */
861 BEGIN_RING(chan, rankine, NV34TCL_COLOR_MASK, 1);
862 OUT_RING (chan, 0x01010101); /* TR,TR,TR,TR */
863 BEGIN_RING(chan, rankine, NV34TCL_CULL_FACE_ENABLE, 1);
864 OUT_RING (chan, 0);
865 BEGIN_RING(chan, rankine, NV34TCL_BLEND_FUNC_ENABLE, 5);
866 OUT_RING (chan, 0); /* Blend enable */
867 OUT_RING (chan, 0); /* Blend src */
868 OUT_RING (chan, 0); /* Blend dst */
869 OUT_RING (chan, 0x00000000); /* Blend colour */
870 OUT_RING (chan, 0x8006); /* FUNC_ADD */
871 BEGIN_RING(chan, rankine, NV34TCL_COLOR_LOGIC_OP_ENABLE, 2);
872 OUT_RING (chan, 0);
873 OUT_RING (chan, 0x1503 /*GL_COPY*/);
874 BEGIN_RING(chan, rankine, NV34TCL_DITHER_ENABLE, 1);
875 OUT_RING (chan, 1);
876 BEGIN_RING(chan, rankine, NV34TCL_SHADE_MODEL, 1);
877 OUT_RING (chan, 0x1d01 /*GL_SMOOTH*/);
878 BEGIN_RING(chan, rankine, NV34TCL_POLYGON_OFFSET_FACTOR,2);
879 OUT_RINGf (chan, 0.0);
880 OUT_RINGf (chan, 0.0);
881 BEGIN_RING(chan, rankine, NV34TCL_POLYGON_MODE_FRONT, 2);
882 OUT_RING (chan, 0x1b02 /*GL_FILL*/);
883 OUT_RING (chan, 0x1b02 /*GL_FILL*/);
884 /* - Disable texture units
885 * - Set fragprog to MOVR result.color, fragment.color */
886 for (i=0;i<4;i++) {
887 BEGIN_RING(chan, rankine, NV34TCL_TX_ENABLE(i), 1);
888 OUT_RING (chan, 0);
890 /* Polygon stipple */
891 BEGIN_RING(chan, rankine, NV34TCL_POLYGON_STIPPLE_PATTERN(0), 0x20);
892 for (i=0;i<0x20;i++)
893 OUT_RING (chan, 0xFFFFFFFF);
895 BEGIN_RING(chan, rankine, NV34TCL_DEPTH_RANGE_NEAR, 2);
896 OUT_RINGf (chan, 0.0);
897 OUT_RINGf (chan, 1.0);
899 /* Ok. If you start X with the nvidia driver, kill it, and then
900 * start X with nouveau you will get black rendering instead of
901 * what you'd expect. This fixes the problem, and it seems that
902 * it's not needed between nouveau restarts - which suggests that
903 * the 3D context (wherever it's stored?) survives somehow.
905 //BEGIN_RING(chan, rankine, 0x1d60,1);
906 //OUT_RING (chan, 0x03008000);
908 int w=4096;
909 int h=4096;
910 int pitch=4096*4;
911 BEGIN_RING(chan, rankine, NV34TCL_RT_HORIZ, 5);
912 OUT_RING (chan, w<<16);
913 OUT_RING (chan, h<<16);
914 OUT_RING (chan, 0x148); /* format */
915 OUT_RING (chan, pitch << 16 | pitch);
916 OUT_RING (chan, 0x0);
917 BEGIN_RING(chan, rankine, NV34TCL_VIEWPORT_TX_ORIGIN, 1);
918 OUT_RING (chan, 0);
919 BEGIN_RING(chan, rankine, 0x0a00, 2);
920 OUT_RING (chan, (w<<16) | 0);
921 OUT_RING (chan, (h<<16) | 0);
922 BEGIN_RING(chan, rankine, NV34TCL_VIEWPORT_CLIP_HORIZ(0), 2);
923 OUT_RING (chan, (w-1)<<16);
924 OUT_RING (chan, (h-1)<<16);
925 BEGIN_RING(chan, rankine, NV34TCL_SCISSOR_HORIZ, 2);
926 OUT_RING (chan, w<<16);
927 OUT_RING (chan, h<<16);
928 BEGIN_RING(chan, rankine, NV34TCL_VIEWPORT_HORIZ, 2);
929 OUT_RING (chan, w<<16);
930 OUT_RING (chan, h<<16);
932 BEGIN_RING(chan, rankine, NV34TCL_VIEWPORT_TRANSLATE_X, 8);
933 OUT_RINGf (chan, 0.0);
934 OUT_RINGf (chan, 0.0);
935 OUT_RINGf (chan, 0.0);
936 OUT_RINGf (chan, 0.0);
937 OUT_RINGf (chan, 1.0);
938 OUT_RINGf (chan, 1.0);
939 OUT_RINGf (chan, 1.0);
940 OUT_RINGf (chan, 0.0);
942 BEGIN_RING(chan, rankine, NV34TCL_MODELVIEW_MATRIX(0), 16);
943 OUT_RINGf (chan, 1.0);
944 OUT_RINGf (chan, 0.0);
945 OUT_RINGf (chan, 0.0);
946 OUT_RINGf (chan, 0.0);
947 OUT_RINGf (chan, 0.0);
948 OUT_RINGf (chan, 1.0);
949 OUT_RINGf (chan, 0.0);
950 OUT_RINGf (chan, 0.0);
951 OUT_RINGf (chan, 0.0);
952 OUT_RINGf (chan, 0.0);
953 OUT_RINGf (chan, 1.0);
954 OUT_RINGf (chan, 0.0);
955 OUT_RINGf (chan, 0.0);
956 OUT_RINGf (chan, 0.0);
957 OUT_RINGf (chan, 0.0);
958 OUT_RINGf (chan, 1.0);
960 BEGIN_RING(chan, rankine, NV34TCL_PROJECTION_MATRIX(0), 16);
961 OUT_RINGf (chan, 1.0);
962 OUT_RINGf (chan, 0.0);
963 OUT_RINGf (chan, 0.0);
964 OUT_RINGf (chan, 0.0);
965 OUT_RINGf (chan, 0.0);
966 OUT_RINGf (chan, 1.0);
967 OUT_RINGf (chan, 0.0);
968 OUT_RINGf (chan, 0.0);
969 OUT_RINGf (chan, 0.0);
970 OUT_RINGf (chan, 0.0);
971 OUT_RINGf (chan, 1.0);
972 OUT_RINGf (chan, 0.0);
973 OUT_RINGf (chan, 0.0);
974 OUT_RINGf (chan, 0.0);
975 OUT_RINGf (chan, 0.0);
976 OUT_RINGf (chan, 1.0);
978 BEGIN_RING(chan, rankine, NV34TCL_SCISSOR_HORIZ, 2);
979 OUT_RING (chan, 4096<<16);
980 OUT_RING (chan, 4096<<16);
982 for (i = 0; i < NV30EXA_FPID_MAX; i++) {
983 NV30_UploadFragProg(pNv, nv40_fp_map[i], &next_hw_offset);
984 NV30_UploadFragProg(pNv, nv40_fp_map_a8[i], &next_hw_offset);
986 NV30_UploadFragProg(pNv, &nv30_fp_yv12_bicubic, &next_hw_offset);
987 NV30_UploadFragProg(pNv, &nv30_fp_yv12_bilinear, &next_hw_offset);
989 return TRUE;
992 /* AROS CODE */
994 /* NOTE: Assumes lock on bitmap is already made */
995 /* NOTE: Assumes buffer is not mapped */
996 /* NOTE: Allows different formats of source and destination */
997 BOOL HIDDNouveauNV303DCopyBox(struct CardData * carddata,
998 struct HIDDNouveauBitMapData * srcdata, struct HIDDNouveauBitMapData * destdata,
999 LONG srcX, LONG srcY, LONG destX, LONG destY, LONG width, LONG height,
1000 ULONG blendop)
1002 struct Picture sPict, dPict;
1003 nv30_exa_state_t state;
1004 LONG maskX = 0; LONG maskY = 0;
1006 HIDDNouveauFillPictureFromBitMapData(&sPict, srcdata);
1007 HIDDNouveauFillPictureFromBitMapData(&dPict, destdata);
1009 if (NV30EXAPrepareComposite(blendop,
1010 &sPict, NULL, &dPict, srcdata, NULL, destdata, &state))
1012 NV30EXAComposite(destdata, srcX, srcY,
1013 maskX, maskY,
1014 destX , destY,
1015 width, height, &state);
1016 return TRUE;
1019 return FALSE;