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"
28 #include "nv04_pushbuf.h"
30 #include <aros/debug.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 #if !defined(__AROS__)
62 static nv30_exa_state_t exa_state
;
63 #define NV30EXA_STATE nv30_exa_state_t *state = &exa_state
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 },
74 { PICT_x1r5g5b5
, 0x142 },
77 static nv_pict_surface_format_t
*
78 NV30_GetPictSurfaceFormat(int format
)
82 for(i
=0;i
<sizeof(NV30SurfaceFormat
)/sizeof(NV30SurfaceFormat
[0]);i
++)
84 if (NV30SurfaceFormat
[i
].pict_fmt
== format
)
85 return &NV30SurfaceFormat
[i
];
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,
100 static nv_shader_t
*nv40_fp_map
[NV30EXA_FPID_MAX
] = {
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
];
111 NV30EXAHackupA8Shaders(ScrnInfoPtr pScrn
)
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) \
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
)
196 for(i
=0;i
<sizeof(NV30TextureFormat
)/sizeof(NV30TextureFormat
[0]);i
++)
198 if (NV30TextureFormat
[i
].pict_fmt
== format
)
199 return &NV30TextureFormat
[i
];
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
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
)
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;
259 return &NV30PictOp
[op
];
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
)) {
278 } else if (sblend
== BF(ONE_MINUS_DST_ALPHA
)) {
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);
302 BEGIN_RING(chan
, rankine
, NV34TCL_BLEND_FUNC_ENABLE
, 3);
304 OUT_RING (chan
, (sblend
<< 16) | sblend
);
305 OUT_RING (chan
, (dblend
<< 16) | dblend
);
309 #if !defined(__AROS__)
311 NV30EXATexture(ScrnInfoPtr pScrn
, PixmapPtr pPix
, PicturePtr pPict
, int unit
)
314 NV30EXATexture(ScrnInfoPtr pScrn
, PixmapPtr pPix
, PicturePtr pPict
, int unit
, nv30_exa_state_t
* state
)
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
;
326 fmt
= NV30_GetPictTextureFormat(pPict
->format
);
330 card_repeat
= 3; /* repeatNone */
332 if (pPict
->filter
== PictFilterBilinear
)
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
) <<
344 (log2i(pPix
->width
) <<
346 NV34TCL_TX_FORMAT_BASE_SIZE_U_SHIFT
) |
347 #if !defined(__AROS__)
348 (log2i(pPix
->drawable
.height
) <<
350 (log2i(pPix
->height
) <<
352 NV34TCL_TX_FORMAT_BASE_SIZE_V_SHIFT
),
353 tex_reloc
| NOUVEAU_BO_OR
,
354 NV34TCL_TX_FORMAT_DMA0
, NV34TCL_TX_FORMAT_DMA1
))
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
) |
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
;
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 */
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
);
396 ErrorF("AIII no format\n");
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
))
411 #if !defined(__AROS__)
413 NV30EXACheckCompositeTexture(PicturePtr pPict
, PicturePtr pdPict
, int op
)
415 nv_pict_texture_format_t
*fmt
;
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
);
429 NOUVEAU_FALLBACK("picture format 0x%08x not supported\n",
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");
454 NV30EXACheckComposite(int op
, PicturePtr psPict
,
458 nv_pict_surface_format_t
*fmt
;
461 opr
= NV30_GetPictOpRec(op
);
463 NOUVEAU_FALLBACK("unsupported blend op 0x%x\n", op
);
465 fmt
= NV30_GetPictSurfaceFormat(pdPict
->format
);
467 NOUVEAU_FALLBACK("dst picture format 0x%08x not supported\n",
470 if (!NV30EXACheckCompositeTexture(psPict
, pdPict
, op
))
471 NOUVEAU_FALLBACK("src picture\n");
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");
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
);
495 #if !defined(__AROS__)
497 NV30EXAPrepareComposite(int op
, PicturePtr psPict
,
504 ScrnInfoPtr pScrn
= xf86Screens
[psPix
->drawable
.pScreen
->myNum
];
507 NV30EXAPrepareComposite(int op
, PicturePtr psPict
,
513 nv30_exa_state_t
* state
)
515 ScrnInfoPtr pScrn
= globalcarddataptr
;
517 NVPtr pNv
= NVPTR(pScrn
);
518 struct nouveau_channel
*chan
= pNv
->chan
;
519 struct nouveau_grobj
*rankine
= pNv
->Nv3D
;
521 int fpid
= NV30EXA_FPID_PASS_COL0
;
524 if (MARK_RING(chan
, 128, 1 + 1 + 4))
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)) {
537 !NV30EXATexture(pScrn
, psPix
, psPict
, 0, state
)) {
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
));
551 ErrorF(" mask(%dx%d)",pmPict
->pDrawable
->width
,pmPict
->pDrawable
->height
);
552 printformat((pmPict
->format
));
558 #if !defined(__AROS__)
559 if (!NV30EXATexture(pScrn
, pmPix
, pmPict
, 1)) {
561 if (!NV30EXATexture(pScrn
, pmPix
, pmPict
, 1, state
)) {
567 if (pmPict
->componentAlpha
&& PICT_FORMAT_RGB(pmPict
->format
)) {
568 if (blend
->src_alpha
)
569 fpid
= NV30EXA_FPID_COMPOSITE_MASK_SA_CA
;
571 fpid
= NV30EXA_FPID_COMPOSITE_MASK_CA
;
573 fpid
= NV30EXA_FPID_COMPOSITE_MASK
;
576 state
->have_mask
= TRUE
;
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
])) {
589 BEGIN_RING(chan
, rankine
, 0x23c, 1);
590 OUT_RING (chan
, pmPict
?3:1);
592 #if !defined(__AROS__)
594 pNv
->pspict
= psPict
;
595 pNv
->pmpict
= pmPict
;
596 pNv
->pdpict
= pdPict
;
600 chan
->flush_notify
= NV30EXAStateCompositeReemit
;
602 chan
->flush_notify
= NULL
;
607 #define xFixedToFloat(v) \
608 ((float)xFixedToInt((v)) + ((float)xFixedFrac(v) / 65536.0))
611 NV30EXATransformCoord(PictTransformPtr t
, int x
, int y
, float sx
, float sy
,
612 float *x_ret
, float *y_ret
)
614 #if !defined(__AROS__)
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]);
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)); \
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)); \
649 #if !defined(__AROS__)
651 NV30EXAComposite(PixmapPtr pdPix
, int srcX
, int srcY
,
652 int maskX
, int maskY
,
654 int width
, int height
)
656 ScrnInfoPtr pScrn
= xf86Screens
[pdPix
->drawable
.pScreen
->myNum
];
659 NV30EXAComposite(PixmapPtr pdPix
, int srcX
, int srcY
,
660 int maskX
, int maskY
,
662 int width
, int height
, nv30_exa_state_t
* state
)
664 ScrnInfoPtr pScrn
= globalcarddataptr
;
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;
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
);
685 ErrorF("Composite [%dx%d] (%d,%d)IN(%d,%d)OP(%d,%d)\n",width
,height
,srcX
,srcY
,maskX
,maskY
,dstX
,dstY
);
687 NV30EXATransformCoord(state
->unit
[0].transform
,
689 state
->unit
[0].width
,
690 state
->unit
[0].height
, &sX0
, &sY0
);
691 NV30EXATransformCoord(state
->unit
[0].transform
,
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
);
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);
727 #if !defined(__AROS__)
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
;
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
)
760 if (NV30TCL_CHIPSET_3X_MASK
& (1<<chipset
))
762 else if (NV35TCL_CHIPSET_3X_MASK
& (1<<chipset
))
764 else if (NV34TCL_CHIPSET_3X_MASK
& (1<<chipset
))
767 xf86DrvMsg(pScrn
->scrnIndex
, X_ERROR
,
768 "NV30EXA: Unknown chipset NV3%1x\n", chipset
);
774 if (nouveau_grobj_alloc(chan
, Nv3D
, class, &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
);
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);
807 BEGIN_RING(chan
, rankine
, 0x220, 1);
810 BEGIN_RING(chan
, rankine
, 0x03b0, 1);
811 OUT_RING (chan
, 0x00100000);
812 BEGIN_RING(chan
, rankine
, 0x1454, 1);
814 BEGIN_RING(chan
, rankine
, 0x1d80, 1);
816 BEGIN_RING(chan
, rankine
, 0x1450, 1);
817 OUT_RING (chan
, 0x00030004);
820 BEGIN_RING(chan
, rankine
, 0x1e98, 1);
822 BEGIN_RING(chan
, rankine
, 0x17e0, 3);
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);
838 BEGIN_RING(chan
, pNv
->NvImageBlit
, 0x120, 3);
843 BEGIN_RING(chan
, rankine
, 0x1d88, 1);
844 OUT_RING (chan
, 0x00001200);
846 BEGIN_RING(chan
, rankine
, NV34TCL_RC_ENABLE
, 1);
849 /* Attempt to setup a known state.. Probably missing a heap of
852 BEGIN_RING(chan
, rankine
, NV34TCL_STENCIL_FRONT_ENABLE
, 1);
854 BEGIN_RING(chan
, rankine
, NV34TCL_STENCIL_BACK_ENABLE
, 1);
856 BEGIN_RING(chan
, rankine
, NV34TCL_ALPHA_FUNC_ENABLE
, 1);
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);
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);
873 OUT_RING (chan
, 0x1503 /*GL_COPY*/);
874 BEGIN_RING(chan
, rankine
, NV34TCL_DITHER_ENABLE
, 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 */
887 BEGIN_RING(chan
, rankine
, NV34TCL_TX_ENABLE(i
), 1);
890 /* Polygon stipple */
891 BEGIN_RING(chan
, rankine
, NV34TCL_POLYGON_STIPPLE_PATTERN(0), 0x20);
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);
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);
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
);
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
,
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
,
1015 width
, height
, &state
);