2 * Copyright 2007 Ben Skeggs
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
18 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
19 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 #include "nv_include.h"
24 #include "nv30_shaders.h"
25 #include "nv04_pushbuf.h"
27 #include <aros/debug.h>
31 typedef struct nv_pict_surface_format
{
34 } nv_pict_surface_format_t
;
36 typedef struct nv_pict_texture_format
{
40 } nv_pict_texture_format_t
;
42 typedef struct nv_pict_op
{
49 typedef struct nv40_exa_state
{
53 PictTransformPtr transform
;
58 #if !defined(__AROS__)
59 static nv40_exa_state_t exa_state
;
60 #define NV40EXA_STATE nv40_exa_state_t *state = &exa_state
63 static nv_pict_surface_format_t
64 NV40SurfaceFormat
[] = {
65 { PICT_a8r8g8b8
, NV40TCL_RT_FORMAT_COLOR_A8R8G8B8
},
66 { PICT_x8r8g8b8
, NV40TCL_RT_FORMAT_COLOR_X8R8G8B8
},
67 { PICT_r5g6b5
, NV40TCL_RT_FORMAT_COLOR_R5G6B5
},
68 { PICT_a8
, NV40TCL_RT_FORMAT_COLOR_B8
},
72 static nv_pict_surface_format_t
*
73 NV40_GetPictSurfaceFormat(int format
)
77 while (NV40SurfaceFormat
[i
].pict_fmt
!= -1) {
78 if (NV40SurfaceFormat
[i
].pict_fmt
== format
)
79 return &NV40SurfaceFormat
[i
];
87 NV40EXA_FPID_PASS_COL0
= 0,
88 NV40EXA_FPID_PASS_TEX0
= 1,
89 NV40EXA_FPID_COMPOSITE_MASK
= 2,
90 NV40EXA_FPID_COMPOSITE_MASK_SA_CA
= 3,
91 NV40EXA_FPID_COMPOSITE_MASK_CA
= 4,
95 static nv_shader_t
*nv40_fp_map
[NV40EXA_FPID_MAX
] = {
98 &nv30_fp_composite_mask
,
99 &nv30_fp_composite_mask_sa_ca
,
100 &nv30_fp_composite_mask_ca
103 static nv_shader_t
*nv40_fp_map_a8
[NV40EXA_FPID_MAX
];
106 NV40EXAHackupA8Shaders(ScrnInfoPtr pScrn
)
110 for (s
= 0; s
< NV40EXA_FPID_MAX
; s
++) {
111 nv_shader_t
*def
, *a8
;
113 def
= nv40_fp_map
[s
];
114 a8
= calloc(1, sizeof(nv_shader_t
));
115 a8
->card_priv
.NV30FP
.num_regs
= def
->card_priv
.NV30FP
.num_regs
;
116 a8
->size
= def
->size
+ 4;
117 memcpy(a8
->data
, def
->data
, def
->size
* sizeof(uint32_t));
118 nv40_fp_map_a8
[s
] = a8
;
120 a8
->data
[a8
->size
- 8 + 0] &= ~0x00000081;
121 a8
->data
[a8
->size
- 4 + 0] = 0x01401e81;
122 a8
->data
[a8
->size
- 4 + 1] = 0x1c9dfe00;
123 a8
->data
[a8
->size
- 4 + 2] = 0x0001c800;
124 a8
->data
[a8
->size
- 4 + 3] = 0x0001c800;
128 #define _(r,tf,ts0x,ts0y,ts0z,ts0w,ts1x,ts1y,ts1z,ts1w) \
130 PICT_##r, NV40TCL_TEX_FORMAT_FORMAT_##tf, \
131 NV40TCL_TEX_SWIZZLE_S0_X_##ts0x | NV40TCL_TEX_SWIZZLE_S0_Y_##ts0y | \
132 NV40TCL_TEX_SWIZZLE_S0_Z_##ts0z | NV40TCL_TEX_SWIZZLE_S0_W_##ts0w | \
133 NV40TCL_TEX_SWIZZLE_S1_X_##ts1x | NV40TCL_TEX_SWIZZLE_S1_Y_##ts1y | \
134 NV40TCL_TEX_SWIZZLE_S1_Z_##ts1z | NV40TCL_TEX_SWIZZLE_S1_W_##ts1w, \
136 static nv_pict_texture_format_t
137 NV40TextureFormat
[] = {
138 _(a8r8g8b8
, A8R8G8B8
, S1
, S1
, S1
, S1
, X
, Y
, Z
, W
),
139 _(x8r8g8b8
, A8R8G8B8
, S1
, S1
, S1
, ONE
, X
, Y
, Z
, W
),
140 _(x8b8g8r8
, A8R8G8B8
, S1
, S1
, S1
, ONE
, Z
, Y
, X
, W
),
141 _(a1r5g5b5
, A1R5G5B5
, S1
, S1
, S1
, S1
, X
, Y
, Z
, W
),
142 _(x1r5g5b5
, A1R5G5B5
, S1
, S1
, S1
, ONE
, X
, Y
, Z
, W
),
143 _( r5g6b5
, R5G6B5
, S1
, S1
, S1
, S1
, X
, Y
, Z
, W
),
144 _( a8
, L8
, ZERO
, ZERO
, ZERO
, S1
, X
, X
, X
, X
),
149 static nv_pict_texture_format_t
*
150 NV40_GetPictTextureFormat(int format
)
154 while (NV40TextureFormat
[i
].pict_fmt
!= -1) {
155 if (NV40TextureFormat
[i
].pict_fmt
== format
)
156 return &NV40TextureFormat
[i
];
163 #define SF(bf) (NV40TCL_BLEND_FUNC_SRC_RGB_##bf | \
164 NV40TCL_BLEND_FUNC_SRC_ALPHA_##bf)
165 #define DF(bf) (NV40TCL_BLEND_FUNC_DST_RGB_##bf | \
166 NV40TCL_BLEND_FUNC_DST_ALPHA_##bf)
169 /* Clear */ { 0, 0, SF( ZERO
), DF( ZERO
) },
170 /* Src */ { 0, 0, SF( ONE
), DF( ZERO
) },
171 /* Dst */ { 0, 0, SF( ZERO
), DF( ONE
) },
172 /* Over */ { 1, 0, SF( ONE
), DF(ONE_MINUS_SRC_ALPHA
) },
173 /* OverReverse */ { 0, 1, SF(ONE_MINUS_DST_ALPHA
), DF( ONE
) },
174 /* In */ { 0, 1, SF( DST_ALPHA
), DF( ZERO
) },
175 /* InReverse */ { 1, 0, SF( ZERO
), DF( SRC_ALPHA
) },
176 /* Out */ { 0, 1, SF(ONE_MINUS_DST_ALPHA
), DF( ZERO
) },
177 /* OutReverse */ { 1, 0, SF( ZERO
), DF(ONE_MINUS_SRC_ALPHA
) },
178 /* Atop */ { 1, 1, SF( DST_ALPHA
), DF(ONE_MINUS_SRC_ALPHA
) },
179 /* AtopReverse */ { 1, 1, SF(ONE_MINUS_DST_ALPHA
), DF( SRC_ALPHA
) },
180 /* Xor */ { 1, 1, SF(ONE_MINUS_DST_ALPHA
), DF(ONE_MINUS_SRC_ALPHA
) },
181 /* Add */ { 0, 0, SF( ONE
), DF( ONE
) },
182 /* OverAlpha */ { 1, 0, SF( SRC_ALPHA
), DF(ONE_MINUS_SRC_ALPHA
) }
185 static nv_pict_op_t
*
186 NV40_GetPictOpRec(int op
)
188 if (op
>= PictOpSaturate
)
190 return &NV40PictOp
[op
];
194 NV40_SetupBlend(ScrnInfoPtr pScrn
, nv_pict_op_t
*blend
,
195 PictFormatShort dest_format
, Bool component_alpha
)
197 NVPtr pNv
= NVPTR(pScrn
);
198 struct nouveau_channel
*chan
= pNv
->chan
;
199 struct nouveau_grobj
*curie
= pNv
->Nv3D
;
200 uint32_t sblend
, dblend
;
202 sblend
= blend
->src_card_op
;
203 dblend
= blend
->dst_card_op
;
205 if (blend
->dst_alpha
) {
206 if (!PICT_FORMAT_A(dest_format
)) {
207 if (sblend
== SF(DST_ALPHA
)) {
209 } else if (sblend
== SF(ONE_MINUS_DST_ALPHA
)) {
212 } else if (dest_format
== PICT_a8
) {
213 if (sblend
== SF(DST_ALPHA
)) {
214 sblend
= SF(DST_COLOR
);
215 } else if (sblend
== SF(ONE_MINUS_DST_ALPHA
)) {
216 sblend
= SF(ONE_MINUS_DST_COLOR
);
221 if (blend
->src_alpha
&& (component_alpha
|| dest_format
== PICT_a8
)) {
222 if (dblend
== DF(SRC_ALPHA
)) {
223 dblend
= DF(SRC_COLOR
);
224 } else if (dblend
== DF(ONE_MINUS_SRC_ALPHA
)) {
225 dblend
= DF(ONE_MINUS_SRC_COLOR
);
229 if (sblend
== SF(ONE
) && dblend
== DF(ZERO
)) {
230 BEGIN_RING(chan
, curie
, NV40TCL_BLEND_ENABLE
, 1);
233 BEGIN_RING(chan
, curie
, NV40TCL_BLEND_ENABLE
, 5);
235 OUT_RING (chan
, sblend
);
236 OUT_RING (chan
, dblend
);
237 OUT_RING (chan
, 0x00000000);
238 OUT_RING (chan
, NV40TCL_BLEND_EQUATION_ALPHA_FUNC_ADD
|
239 NV40TCL_BLEND_EQUATION_RGB_FUNC_ADD
);
243 #if !defined(__AROS__)
245 NV40EXATexture(ScrnInfoPtr pScrn
, PixmapPtr pPix
, PicturePtr pPict
, int unit
)
248 NV40EXATexture(ScrnInfoPtr pScrn
, PixmapPtr pPix
, PicturePtr pPict
, int unit
, nv40_exa_state_t
* state
)
251 NVPtr pNv
= NVPTR(pScrn
);
252 struct nouveau_channel
*chan
= pNv
->chan
;
253 struct nouveau_grobj
*curie
= pNv
->Nv3D
;
254 struct nouveau_bo
*bo
= nouveau_pixmap_bo(pPix
);
255 unsigned tex_reloc
= NOUVEAU_BO_VRAM
| NOUVEAU_BO_GART
| NOUVEAU_BO_RD
;
256 nv_pict_texture_format_t
*fmt
;
259 fmt
= NV40_GetPictTextureFormat(pPict
->format
);
263 BEGIN_RING(chan
, curie
, NV40TCL_TEX_OFFSET(unit
), 8);
264 if (OUT_RELOCl(chan
, bo
, 0, tex_reloc
) ||
265 OUT_RELOCd(chan
, bo
, fmt
->card_fmt
| NV40TCL_TEX_FORMAT_LINEAR
|
266 NV40TCL_TEX_FORMAT_DIMS_2D
| 0x8000 |
267 NV40TCL_TEX_FORMAT_NO_BORDER
|
268 (1 << NV40TCL_TEX_FORMAT_MIPMAP_COUNT_SHIFT
),
269 tex_reloc
| NOUVEAU_BO_OR
,
270 NV40TCL_TEX_FORMAT_DMA0
, NV40TCL_TEX_FORMAT_DMA1
))
274 switch(pPict
->repeatType
) {
276 OUT_RING (chan
, NV40TCL_TEX_WRAP_S_CLAMP
|
277 NV40TCL_TEX_WRAP_T_CLAMP
|
278 NV40TCL_TEX_WRAP_R_CLAMP
);
281 OUT_RING (chan
, NV40TCL_TEX_WRAP_S_MIRRORED_REPEAT
|
282 NV40TCL_TEX_WRAP_T_MIRRORED_REPEAT
|
283 NV40TCL_TEX_WRAP_R_MIRRORED_REPEAT
);
287 OUT_RING (chan
, NV40TCL_TEX_WRAP_S_REPEAT
|
288 NV40TCL_TEX_WRAP_T_REPEAT
|
289 NV40TCL_TEX_WRAP_R_REPEAT
);
293 OUT_RING (chan
, NV40TCL_TEX_WRAP_S_CLAMP_TO_BORDER
|
294 NV40TCL_TEX_WRAP_T_CLAMP_TO_BORDER
|
295 NV40TCL_TEX_WRAP_R_CLAMP_TO_BORDER
);
297 OUT_RING (chan
, NV40TCL_TEX_ENABLE_ENABLE
);
298 OUT_RING (chan
, fmt
->card_swz
);
299 if (pPict
->filter
== PictFilterBilinear
) {
300 OUT_RING (chan
, NV40TCL_TEX_FILTER_MIN_LINEAR
|
301 NV40TCL_TEX_FILTER_MAG_LINEAR
| 0x3fd6);
303 OUT_RING (chan
, NV40TCL_TEX_FILTER_MIN_NEAREST
|
304 NV40TCL_TEX_FILTER_MAG_NEAREST
| 0x3fd6);
306 #if !defined(__AROS__)
307 OUT_RING (chan
, (pPix
->drawable
.width
<< 16) | pPix
->drawable
.height
);
308 OUT_RING (chan
, 0); /* border ARGB */
309 BEGIN_RING(chan
, curie
, NV40TCL_TEX_SIZE1(unit
), 1);
310 OUT_RING (chan
, (1 << NV40TCL_TEX_SIZE1_DEPTH_SHIFT
) |
311 (uint32_t)exaGetPixmapPitch(pPix
));
313 state
->unit
[unit
].width
= (float)pPix
->drawable
.width
;
314 state
->unit
[unit
].height
= (float)pPix
->drawable
.height
;
315 state
->unit
[unit
].transform
= pPict
->transform
;
317 OUT_RING (chan
, (pPix
->width
<< 16) | pPix
->height
);
318 OUT_RING (chan
, 0); /* border ARGB */
319 BEGIN_RING(chan
, curie
, NV40TCL_TEX_SIZE1(unit
), 1);
320 OUT_RING (chan
, (1 << NV40TCL_TEX_SIZE1_DEPTH_SHIFT
) |
321 (uint32_t)pPix
->pitch
);
323 state
->unit
[unit
].width
= (float)pPix
->width
;
324 state
->unit
[unit
].height
= (float)pPix
->height
;
325 state
->unit
[unit
].transform
= NULL
; /* Keep this NULL, we are doing simple blits */
331 NV40_SetupSurface(ScrnInfoPtr pScrn
, PixmapPtr pPix
, PictFormatShort format
)
333 NVPtr pNv
= NVPTR(pScrn
);
334 struct nouveau_channel
*chan
= pNv
->chan
;
335 struct nouveau_grobj
*curie
= pNv
->Nv3D
;
336 struct nouveau_bo
*bo
= nouveau_pixmap_bo(pPix
);
337 nv_pict_surface_format_t
*fmt
;
339 fmt
= NV40_GetPictSurfaceFormat(format
);
341 ErrorF("AIII no format\n");
345 BEGIN_RING(chan
, curie
, NV40TCL_RT_FORMAT
, 3);
346 OUT_RING (chan
, NV40TCL_RT_FORMAT_TYPE_LINEAR
|
347 NV40TCL_RT_FORMAT_ZETA_Z24S8
|
349 OUT_RING (chan
, exaGetPixmapPitch(pPix
));
350 if (OUT_RELOCl(chan
, bo
, 0, NOUVEAU_BO_VRAM
| NOUVEAU_BO_WR
))
356 #if !defined(__AROS__)
358 NV40EXACheckCompositeTexture(PicturePtr pPict
, PicturePtr pdPict
, int op
)
360 nv_pict_texture_format_t
*fmt
;
363 if (!pPict
->pDrawable
)
364 NOUVEAU_FALLBACK("Solid and gradient pictures unsupported\n");
366 w
= pPict
->pDrawable
->width
;
367 h
= pPict
->pDrawable
->height
;
369 if ((w
> 4096) || (h
> 4096))
370 NOUVEAU_FALLBACK("picture too large, %dx%d\n", w
, h
);
372 fmt
= NV40_GetPictTextureFormat(pPict
->format
);
374 NOUVEAU_FALLBACK("picture format 0x%08x not supported\n",
377 if (pPict
->filter
!= PictFilterNearest
&&
378 pPict
->filter
!= PictFilterBilinear
)
379 NOUVEAU_FALLBACK("filter 0x%x not supported\n", pPict
->filter
);
381 /* Opengl and Render disagree on what should be sampled outside an XRGB
382 * texture (with no repeating). Opengl has a hardcoded alpha value of
383 * 1.0, while render expects 0.0. We assume that clipping is done for
384 * untranformed sources.
386 if (NV40PictOp
[op
].src_alpha
&& !pPict
->repeat
&&
387 pPict
->transform
&& (PICT_FORMAT_A(pPict
->format
) == 0)
388 && (PICT_FORMAT_A(pdPict
->format
) != 0))
389 NOUVEAU_FALLBACK("REPEAT_NONE unsupported for XRGB source\n");
395 NV40EXACheckComposite(int op
, PicturePtr psPict
,
399 nv_pict_surface_format_t
*fmt
;
402 opr
= NV40_GetPictOpRec(op
);
404 NOUVEAU_FALLBACK("unsupported blend op 0x%x\n", op
);
406 fmt
= NV40_GetPictSurfaceFormat(pdPict
->format
);
408 NOUVEAU_FALLBACK("dst picture format 0x%08x not supported\n",
411 if (!NV40EXACheckCompositeTexture(psPict
, pdPict
, op
))
412 NOUVEAU_FALLBACK("src picture\n");
414 if (pmPict
->componentAlpha
&&
415 PICT_FORMAT_RGB(pmPict
->format
) &&
416 opr
->src_alpha
&& opr
->src_card_op
!= SF(ZERO
))
417 NOUVEAU_FALLBACK("mask CA + SA\n");
418 if (!NV40EXACheckCompositeTexture(pmPict
, pdPict
, op
))
419 NOUVEAU_FALLBACK("mask picture\n");
426 NV40EXAStateCompositeReemit(struct nouveau_channel
*chan
)
428 ScrnInfoPtr pScrn
= chan
->user_private
;
429 NVPtr pNv
= NVPTR(pScrn
);
431 NV40EXAPrepareComposite(pNv
->alu
, pNv
->pspict
, pNv
->pmpict
, pNv
->pdpict
,
432 pNv
->pspix
, pNv
->pmpix
, pNv
->pdpix
);
436 #if !defined(__AROS__)
438 NV40EXAPrepareComposite(int op
, PicturePtr psPict
,
445 ScrnInfoPtr pScrn
= xf86Screens
[psPix
->drawable
.pScreen
->myNum
];
448 NV40EXAPrepareComposite(int op
, PicturePtr psPict
,
454 nv40_exa_state_t
* state
)
456 ScrnInfoPtr pScrn
= globalcarddataptr
;
458 NVPtr pNv
= NVPTR(pScrn
);
459 struct nouveau_channel
*chan
= pNv
->chan
;
460 struct nouveau_grobj
*curie
= pNv
->Nv3D
;
462 int fpid
= NV40EXA_FPID_PASS_COL0
;
465 if (MARK_RING(chan
, 128, 1 + 1 + 2*2))
468 blend
= NV40_GetPictOpRec(op
);
470 NV40_SetupBlend(pScrn
, blend
, pdPict
->format
,
471 (pmPict
&& pmPict
->componentAlpha
&&
472 PICT_FORMAT_RGB(pmPict
->format
)));
474 if (!NV40_SetupSurface(pScrn
, pdPix
, pdPict
->format
) ||
475 #if !defined(__AROS__)
476 !NV40EXATexture(pScrn
, psPix
, psPict
, 0)) {
478 !NV40EXATexture(pScrn
, psPix
, psPict
, 0, state
)) {
484 NV40_LoadVtxProg(pScrn
, &nv40_vp_exa_render
);
486 #if !defined(__AROS__)
487 if (!NV40EXATexture(pScrn
, pmPix
, pmPict
, 1)) {
489 if (!NV40EXATexture(pScrn
, pmPix
, pmPict
, 1, state
)) {
495 if (pmPict
->componentAlpha
&& PICT_FORMAT_RGB(pmPict
->format
)) {
496 if (blend
->src_alpha
)
497 fpid
= NV40EXA_FPID_COMPOSITE_MASK_SA_CA
;
499 fpid
= NV40EXA_FPID_COMPOSITE_MASK_CA
;
501 fpid
= NV40EXA_FPID_COMPOSITE_MASK
;
504 state
->have_mask
= TRUE
;
506 fpid
= NV40EXA_FPID_PASS_TEX0
;
508 state
->have_mask
= FALSE
;
512 if (!NV40_LoadFragProg(pScrn
, (pdPict
->format
== PICT_a8
) ?
513 nv40_fp_map_a8
[fpid
] : nv40_fp_map
[fpid
])) {
518 /* Appears to be some kind of cache flush, needed here at least
519 * sometimes.. funky text rendering otherwise :)
521 BEGIN_RING(chan
, curie
, NV40TCL_TEX_CACHE_CTL
, 1);
523 BEGIN_RING(chan
, curie
, NV40TCL_TEX_CACHE_CTL
, 1);
526 #if !defined(__AROS__)
528 pNv
->pspict
= psPict
;
529 pNv
->pmpict
= pmPict
;
530 pNv
->pdpict
= pdPict
;
534 chan
->flush_notify
= NV40EXAStateCompositeReemit
;
536 chan
->flush_notify
= NULL
;
541 #define xFixedToFloat(v) \
542 ((float)xFixedToInt((v)) + ((float)xFixedFrac(v) / 65536.0))
545 NV40EXATransformCoord(PictTransformPtr t
, int x
, int y
, float sx
, float sy
,
546 float *x_ret
, float *y_ret
)
549 /* Note: current t is always NULL in AROS. That is good enough for
550 operations being done (simple blits with alpha) */
551 #if !defined(__AROS__)
553 v
.vector
[0] = IntToxFixed(x
);
554 v
.vector
[1] = IntToxFixed(y
);
555 v
.vector
[2] = xFixed1
;
556 PictureTransformPoint(t
, &v
);
557 *x_ret
= xFixedToFloat(v
.vector
[0]) / sx
;
558 *y_ret
= xFixedToFloat(v
.vector
[1]) / sy
;
561 *x_ret
= (float)x
/ sx
;
562 *y_ret
= (float)y
/ sy
;
566 #define CV_OUTm(sx,sy,mx,my,dx,dy) do { \
567 BEGIN_RING(chan, curie, NV40TCL_VTX_ATTR_2F_X(8), 4); \
568 OUT_RINGf (chan, (sx)); OUT_RINGf (chan, (sy)); \
569 OUT_RINGf (chan, (mx)); OUT_RINGf (chan, (my)); \
570 BEGIN_RING(chan, curie, NV40TCL_VTX_ATTR_2I(0), 1); \
571 OUT_RING (chan, ((dy)<<16)|(dx)); \
573 #define CV_OUT(sx,sy,dx,dy) do { \
574 BEGIN_RING(chan, curie, NV40TCL_VTX_ATTR_2F_X(8), 2); \
575 OUT_RINGf (chan, (sx)); OUT_RINGf (chan, (sy)); \
576 BEGIN_RING(chan, curie, NV40TCL_VTX_ATTR_2I(0), 1); \
577 OUT_RING (chan, ((dy)<<16)|(dx)); \
580 #if !defined(__AROS__)
582 NV40EXAComposite(PixmapPtr pdPix
, int srcX
, int srcY
,
583 int maskX
, int maskY
,
585 int width
, int height
)
587 ScrnInfoPtr pScrn
= xf86Screens
[pdPix
->drawable
.pScreen
->myNum
];
590 NV40EXAComposite(PixmapPtr pdPix
, int srcX
, int srcY
,
591 int maskX
, int maskY
,
593 int width
, int height
, nv40_exa_state_t
* state
)
595 ScrnInfoPtr pScrn
= globalcarddataptr
;
597 NVPtr pNv
= NVPTR(pScrn
);
598 struct nouveau_channel
*chan
= pNv
->chan
;
599 struct nouveau_grobj
*curie
= pNv
->Nv3D
;
600 float sX0
=0.0f
, sX1
=0.0f
, sX2
=0.0f
, sY0
=0.0f
, sY1
=0.0f
, sY2
=0.0f
;
601 float mX0
=0.0f
, mX1
=0.0f
, mX2
=0.0f
, mY0
=0.0f
, mY1
=0.0f
, mY2
=0.0f
;
606 /* We're drawing a triangle, we need to scissor it to a quad. */
607 /* The scissors are here for a good reason, we don't get the full
608 * image, but just a part.
610 /* Handling the cliprects is done for us already. */
611 BEGIN_RING(chan
, curie
, NV40TCL_SCISSOR_HORIZ
, 2);
612 OUT_RING (chan
, (width
<< 16) | dstX
);
613 OUT_RING (chan
, (height
<< 16) | dstY
);
614 BEGIN_RING(chan
, curie
, NV40TCL_BEGIN_END
, 1);
615 OUT_RING (chan
, NV40TCL_BEGIN_END_TRIANGLES
);
617 NV40EXATransformCoord(state
->unit
[0].transform
, srcX
, srcY
- height
,
618 state
->unit
[0].width
, state
->unit
[0].height
,
620 NV40EXATransformCoord(state
->unit
[0].transform
, srcX
, srcY
+ height
,
621 state
->unit
[0].width
, state
->unit
[0].height
,
623 NV40EXATransformCoord(state
->unit
[0].transform
,
624 srcX
+ 2*width
, srcY
+ height
,
625 state
->unit
[0].width
,
626 state
->unit
[0].height
, &sX2
, &sY2
);
628 if (state
->have_mask
) {
629 NV40EXATransformCoord(state
->unit
[1].transform
,
630 maskX
, maskY
- height
,
631 state
->unit
[1].width
,
632 state
->unit
[1].height
, &mX0
, &mY0
);
633 NV40EXATransformCoord(state
->unit
[1].transform
,
634 maskX
, maskY
+ height
,
635 state
->unit
[1].width
,
636 state
->unit
[1].height
, &mX1
, &mY1
);
637 NV40EXATransformCoord(state
->unit
[1].transform
,
638 maskX
+ 2*width
, maskY
+ height
,
639 state
->unit
[1].width
,
640 state
->unit
[1].height
, &mX2
, &mY2
);
642 CV_OUTm(sX0
, sY0
, mX0
, mY0
, dstX
, dstY
- height
);
643 CV_OUTm(sX1
, sY1
, mX1
, mY1
, dstX
, dstY
+ height
);
644 CV_OUTm(sX2
, sY2
, mX2
, mY2
, dstX
+ 2*width
, dstY
+ height
);
646 CV_OUT(sX0
, sY0
, dstX
, dstY
- height
);
647 CV_OUT(sX1
, sY1
, dstX
, dstY
+ height
);
648 CV_OUT(sX2
, sY2
, dstX
+ 2*width
, dstY
+ height
);
651 BEGIN_RING(chan
, curie
, NV40TCL_BEGIN_END
, 1);
652 OUT_RING (chan
, NV40TCL_BEGIN_END_STOP
);
655 #if !defined(__AROS__)
657 NV40EXADoneComposite(PixmapPtr pdPix
)
659 ScrnInfoPtr pScrn
= xf86Screens
[pdPix
->drawable
.pScreen
->myNum
];
660 NVPtr pNv
= NVPTR(pScrn
);
661 struct nouveau_channel
*chan
= pNv
->chan
;
663 chan
->flush_notify
= NULL
;
667 #define NV40TCL_CHIPSET_4X_MASK 0x00000baf
668 #define NV44TCL_CHIPSET_4X_MASK 0x00005450
670 NVAccelInitNV40TCL(ScrnInfoPtr pScrn
)
672 NVPtr pNv
= NVPTR(pScrn
);
673 struct nouveau_channel
*chan
= pNv
->chan
;
674 struct nouveau_grobj
*curie
;
675 uint32_t class = 0, chipset
;
676 int next_hw_id
= 0, next_hw_offset
= 0, i
;
678 if (!nv40_fp_map_a8
[0])
679 NV40EXAHackupA8Shaders(pScrn
);
681 chipset
= pNv
->dev
->chipset
;
682 if ((chipset
& 0xf0) == NV_ARCH_40
) {
684 if (NV40TCL_CHIPSET_4X_MASK
& (1<<chipset
))
686 else if (NV44TCL_CHIPSET_4X_MASK
& (1<<chipset
))
689 xf86DrvMsg(pScrn
->scrnIndex
, X_ERROR
,
690 "NV40EXA: Unknown chipset NV4%1x\n", chipset
);
693 } else if ( (chipset
& 0xf0) == 0x60) {
699 if (nouveau_grobj_alloc(pNv
->chan
, Nv3D
, class, &pNv
->Nv3D
))
704 if (!pNv
->shader_mem
) {
705 if (nouveau_bo_new(pNv
->dev
, NOUVEAU_BO_VRAM
| NOUVEAU_BO_GART
|
706 NOUVEAU_BO_MAP
, 0, 0x1000,
708 xf86DrvMsg(pScrn
->scrnIndex
, X_ERROR
,
709 "Couldn't alloc fragprog buffer!\n");
710 nouveau_grobj_free(&pNv
->Nv3D
);
715 BEGIN_RING(chan
, curie
, NV40TCL_DMA_NOTIFY
, 1);
716 OUT_RING (chan
, pNv
->notify0
->handle
);
717 BEGIN_RING(chan
, curie
, NV40TCL_DMA_TEXTURE0
, 2);
718 OUT_RING (chan
, pNv
->chan
->vram
->handle
);
719 OUT_RING (chan
, pNv
->chan
->gart
->handle
);
720 BEGIN_RING(chan
, curie
, NV40TCL_DMA_COLOR0
, 2);
721 OUT_RING (chan
, pNv
->chan
->vram
->handle
);
722 OUT_RING (chan
, pNv
->chan
->vram
->handle
);
725 BEGIN_RING(chan
, curie
, 0x1ea4, 3);
726 OUT_RING (chan
, 0x00000010);
727 OUT_RING (chan
, 0x01000100);
728 OUT_RING (chan
, 0xff800006);
729 BEGIN_RING(chan
, curie
, 0x1fc4, 1);
730 OUT_RING (chan
, 0x06144321);
731 BEGIN_RING(chan
, curie
, 0x1fc8, 2);
732 OUT_RING (chan
, 0xedcba987);
733 OUT_RING (chan
, 0x00000021);
734 BEGIN_RING(chan
, curie
, 0x1fd0, 1);
735 OUT_RING (chan
, 0x00171615);
736 BEGIN_RING(chan
, curie
, 0x1fd4, 1);
737 OUT_RING (chan
, 0x001b1a19);
738 BEGIN_RING(chan
, curie
, 0x1ef8, 1);
739 OUT_RING (chan
, 0x0020ffff);
740 BEGIN_RING(chan
, curie
, 0x1d64, 1);
741 OUT_RING (chan
, 0x00d30000);
742 BEGIN_RING(chan
, curie
, 0x1e94, 1);
743 OUT_RING (chan
, 0x00000001);
745 /* This removes the the stair shaped tearing that i get. */
746 /* Verified on one G70 card that it doesn't cause regressions for people without the problem. */
747 /* The blob sets this up by default for NV43. */
748 BEGIN_RING(chan
, curie
, 0x1450, 1);
749 OUT_RING (chan
, 0x0000000F);
751 BEGIN_RING(chan
, curie
, NV40TCL_VIEWPORT_TRANSLATE_X
, 8);
752 OUT_RINGf (chan
, 0.0);
753 OUT_RINGf (chan
, 0.0);
754 OUT_RINGf (chan
, 0.0);
755 OUT_RINGf (chan
, 0.0);
756 OUT_RINGf (chan
, 1.0);
757 OUT_RINGf (chan
, 1.0);
758 OUT_RINGf (chan
, 1.0);
759 OUT_RINGf (chan
, 0.0);
761 /* default 3D state */
762 /*XXX: replace with the same state that the DRI emits on startup */
763 BEGIN_RING(chan
, curie
, NV40TCL_STENCIL_FRONT_ENABLE
, 1);
765 BEGIN_RING(chan
, curie
, NV40TCL_STENCIL_BACK_ENABLE
, 1);
767 BEGIN_RING(chan
, curie
, NV40TCL_ALPHA_TEST_ENABLE
, 1);
769 BEGIN_RING(chan
, curie
, NV40TCL_DEPTH_WRITE_ENABLE
, 2);
772 BEGIN_RING(chan
, curie
, NV40TCL_COLOR_MASK
, 1);
773 OUT_RING (chan
, 0x01010101); /* TR,TR,TR,TR */
774 BEGIN_RING(chan
, curie
, NV40TCL_CULL_FACE_ENABLE
, 1);
776 BEGIN_RING(chan
, curie
, NV40TCL_BLEND_ENABLE
, 1);
778 BEGIN_RING(chan
, curie
, NV40TCL_COLOR_LOGIC_OP_ENABLE
, 2);
780 OUT_RING (chan
, NV40TCL_COLOR_LOGIC_OP_COPY
);
781 BEGIN_RING(chan
, curie
, NV40TCL_DITHER_ENABLE
, 1);
783 BEGIN_RING(chan
, curie
, NV40TCL_SHADE_MODEL
, 1);
784 OUT_RING (chan
, NV40TCL_SHADE_MODEL_SMOOTH
);
785 BEGIN_RING(chan
, curie
, NV40TCL_POLYGON_OFFSET_FACTOR
,2);
786 OUT_RINGf (chan
, 0.0);
787 OUT_RINGf (chan
, 0.0);
788 BEGIN_RING(chan
, curie
, NV40TCL_POLYGON_MODE_FRONT
, 2);
789 OUT_RING (chan
, NV40TCL_POLYGON_MODE_FRONT_FILL
);
790 OUT_RING (chan
, NV40TCL_POLYGON_MODE_BACK_FILL
);
791 BEGIN_RING(chan
, curie
, NV40TCL_POLYGON_STIPPLE_PATTERN(0), 0x20);
793 OUT_RING (chan
, 0xFFFFFFFF);
795 BEGIN_RING(chan
, curie
, NV40TCL_TEX_ENABLE(i
), 1);
799 BEGIN_RING(chan
, curie
, 0x1d78, 1);
800 OUT_RING (chan
, 0x110);
802 BEGIN_RING(chan
, curie
, NV40TCL_RT_ENABLE
, 1);
803 OUT_RING (chan
, NV40TCL_RT_ENABLE_COLOR0
);
805 BEGIN_RING(chan
, curie
, NV40TCL_RT_HORIZ
, 2);
806 OUT_RING (chan
, (4096 << 16));
807 OUT_RING (chan
, (4096 << 16));
808 BEGIN_RING(chan
, curie
, NV40TCL_SCISSOR_HORIZ
, 2);
809 OUT_RING (chan
, (4096 << 16));
810 OUT_RING (chan
, (4096 << 16));
811 BEGIN_RING(chan
, curie
, NV40TCL_VIEWPORT_HORIZ
, 2);
812 OUT_RING (chan
, (4096 << 16));
813 OUT_RING (chan
, (4096 << 16));
814 BEGIN_RING(chan
, curie
, NV40TCL_VIEWPORT_CLIP_HORIZ(0), 2);
815 OUT_RING (chan
, (4095 << 16));
816 OUT_RING (chan
, (4095 << 16));
818 NV40_UploadVtxProg(pNv
, &nv40_vp_exa_render
, &next_hw_id
);
819 for (i
= 0; i
< NV40EXA_FPID_MAX
; i
++) {
820 NV30_UploadFragProg(pNv
, nv40_fp_map
[i
], &next_hw_offset
);
821 NV30_UploadFragProg(pNv
, nv40_fp_map_a8
[i
], &next_hw_offset
);
824 NV40_UploadVtxProg(pNv
, &nv40_vp_video
, &next_hw_id
);
825 NV30_UploadFragProg(pNv
, &nv40_fp_yv12_bicubic
, &next_hw_offset
);
826 NV30_UploadFragProg(pNv
, &nv30_fp_yv12_bilinear
, &next_hw_offset
);
833 /* NOTE: Assumes lock on bitmap is already made */
834 /* NOTE: Assumes buffer is not mapped */
835 /* NOTE: Allows different formats of source and destination */
836 BOOL
HIDDNouveauNV403DCopyBox(struct CardData
* carddata
,
837 struct HIDDNouveauBitMapData
* srcdata
, struct HIDDNouveauBitMapData
* destdata
,
838 LONG srcX
, LONG srcY
, LONG destX
, LONG destY
, LONG width
, LONG height
,
841 struct Picture sPict
, dPict
;
842 nv40_exa_state_t state
;
843 LONG maskX
= 0; LONG maskY
= 0;
845 HIDDNouveauFillPictureFromBitMapData(&sPict
, srcdata
);
846 HIDDNouveauFillPictureFromBitMapData(&dPict
, destdata
);
848 if (NV40EXAPrepareComposite(blendop
,
849 &sPict
, NULL
, &dPict
, srcdata
, NULL
, destdata
, &state
))
851 NV40EXAComposite(destdata
, srcX
, srcY
,
854 width
, height
, &state
);