1 #include "nv30_context.h"
2 #include "nouveau/nouveau_util.h"
5 nv30_state_framebuffer_validate(struct nv30_context
*nv30
)
7 struct pipe_framebuffer_state
*fb
= &nv30
->framebuffer
;
8 struct nouveau_channel
*chan
= nv30
->screen
->base
.channel
;
9 struct nouveau_grobj
*eng3d
= nv30
->screen
->eng3d
;
10 struct nv04_surface
*rt
[2], *zeta
= NULL
;
11 uint32_t rt_enable
= 0, rt_format
= 0;
12 int i
, colour_format
= 0, zeta_format
= 0, depth_only
= 0;
13 struct nouveau_stateobj
*so
= so_new(12, 18, 10);
14 unsigned rt_flags
= NOUVEAU_BO_RDWR
| NOUVEAU_BO_VRAM
;
15 unsigned w
= fb
->width
;
16 unsigned h
= fb
->height
;
17 struct nv30_miptree
*nv30mt
;
18 int colour_bits
= 32, zeta_bits
= 32;
20 for (i
= 0; i
< fb
->nr_cbufs
; i
++) {
22 assert(colour_format
== fb
->cbufs
[i
]->format
);
24 colour_format
= fb
->cbufs
[i
]->format
;
25 rt_enable
|= (NV34TCL_RT_ENABLE_COLOR0
<< i
);
26 rt
[i
] = (struct nv04_surface
*)fb
->cbufs
[i
];
30 if (rt_enable
& NV34TCL_RT_ENABLE_COLOR1
)
31 rt_enable
|= NV34TCL_RT_ENABLE_MRT
;
34 zeta_format
= fb
->zsbuf
->format
;
35 zeta
= (struct nv04_surface
*)fb
->zsbuf
;
38 if (rt_enable
& (NV34TCL_RT_ENABLE_COLOR0
|NV34TCL_RT_ENABLE_COLOR1
)) {
39 /* Render to at least a colour buffer */
40 if (!(rt
[0]->base
.texture
->tex_usage
& NOUVEAU_TEXTURE_USAGE_LINEAR
)) {
41 assert(!(fb
->width
& (fb
->width
- 1)) && !(fb
->height
& (fb
->height
- 1)));
42 for (i
= 1; i
< fb
->nr_cbufs
; i
++)
43 assert(!(rt
[i
]->base
.texture
->tex_usage
& NOUVEAU_TEXTURE_USAGE_LINEAR
));
45 rt_format
= NV34TCL_RT_FORMAT_TYPE_SWIZZLED
|
46 (log2i(rt
[0]->base
.width
) << NV34TCL_RT_FORMAT_LOG2_WIDTH_SHIFT
) |
47 (log2i(rt
[0]->base
.height
) << NV34TCL_RT_FORMAT_LOG2_HEIGHT_SHIFT
);
50 rt_format
= NV34TCL_RT_FORMAT_TYPE_LINEAR
;
51 } else if (fb
->zsbuf
) {
54 /* Render to depth buffer only */
55 if (!(zeta
->base
.texture
->tex_usage
& NOUVEAU_TEXTURE_USAGE_LINEAR
)) {
56 assert(!(fb
->width
& (fb
->width
- 1)) && !(fb
->height
& (fb
->height
- 1)));
58 rt_format
= NV34TCL_RT_FORMAT_TYPE_SWIZZLED
|
59 (log2i(zeta
->base
.width
) << NV34TCL_RT_FORMAT_LOG2_WIDTH_SHIFT
) |
60 (log2i(zeta
->base
.height
) << NV34TCL_RT_FORMAT_LOG2_HEIGHT_SHIFT
);
63 rt_format
= NV34TCL_RT_FORMAT_TYPE_LINEAR
;
68 switch (colour_format
) {
69 case PIPE_FORMAT_B8G8R8X8_UNORM
:
70 rt_format
|= NV34TCL_RT_FORMAT_COLOR_X8R8G8B8
;
72 case PIPE_FORMAT_B8G8R8A8_UNORM
:
74 rt_format
|= NV34TCL_RT_FORMAT_COLOR_A8R8G8B8
;
76 case PIPE_FORMAT_B5G6R5_UNORM
:
77 rt_format
|= NV34TCL_RT_FORMAT_COLOR_R5G6B5
;
84 switch (zeta_format
) {
85 case PIPE_FORMAT_Z16_UNORM
:
86 rt_format
|= NV34TCL_RT_FORMAT_ZETA_Z16
;
89 case PIPE_FORMAT_S8Z24_UNORM
:
90 case PIPE_FORMAT_X8Z24_UNORM
:
92 rt_format
|= NV34TCL_RT_FORMAT_ZETA_Z24S8
;
98 if (colour_bits
> zeta_bits
) {
102 if (depth_only
|| (rt_enable
& NV34TCL_RT_ENABLE_COLOR0
)) {
103 struct nv04_surface
*rt0
= (depth_only
? zeta
: rt
[0]);
104 uint32_t pitch
= rt0
->pitch
;
107 pitch
|= (zeta
->pitch
<< 16);
109 pitch
|= (pitch
<< 16);
112 nv30mt
= (struct nv30_miptree
*) rt0
->base
.texture
;
113 so_method(so
, eng3d
, NV34TCL_DMA_COLOR0
, 1);
114 so_reloc (so
, nouveau_bo(nv30mt
->buffer
), 0, rt_flags
| NOUVEAU_BO_OR
,
115 chan
->vram
->handle
, chan
->gart
->handle
);
116 so_method(so
, eng3d
, NV34TCL_COLOR0_PITCH
, 2);
118 so_reloc (so
, nouveau_bo(nv30mt
->buffer
), rt0
->base
.offset
,
119 rt_flags
| NOUVEAU_BO_LOW
, 0, 0);
122 if (rt_enable
& NV34TCL_RT_ENABLE_COLOR1
) {
123 nv30mt
= (struct nv30_miptree
*)rt
[1]->base
.texture
;
124 so_method(so
, eng3d
, NV34TCL_DMA_COLOR1
, 1);
125 so_reloc (so
, nouveau_bo(nv30mt
->buffer
), 0, rt_flags
| NOUVEAU_BO_OR
,
126 chan
->vram
->handle
, chan
->gart
->handle
);
127 so_method(so
, eng3d
, NV34TCL_COLOR1_OFFSET
, 2);
128 so_reloc (so
, nouveau_bo(nv30mt
->buffer
), rt
[1]->base
.offset
,
129 rt_flags
| NOUVEAU_BO_LOW
, 0, 0);
130 so_data (so
, rt
[1]->pitch
);
134 nv30mt
= (struct nv30_miptree
*)zeta
->base
.texture
;
135 so_method(so
, eng3d
, NV34TCL_DMA_ZETA
, 1);
136 so_reloc (so
, nouveau_bo(nv30mt
->buffer
), 0, rt_flags
| NOUVEAU_BO_OR
,
137 chan
->vram
->handle
, chan
->gart
->handle
);
138 so_method(so
, eng3d
, NV34TCL_ZETA_OFFSET
, 1);
139 so_reloc (so
, nouveau_bo(nv30mt
->buffer
), zeta
->base
.offset
,
140 rt_flags
| NOUVEAU_BO_LOW
, 0, 0);
141 /* TODO: allocate LMA depth buffer */
144 so_method(so
, eng3d
, NV34TCL_RT_ENABLE
, 1);
145 so_data (so
, rt_enable
);
146 so_method(so
, eng3d
, NV34TCL_RT_HORIZ
, 3);
147 so_data (so
, (w
<< 16) | 0);
148 so_data (so
, (h
<< 16) | 0);
149 so_data (so
, rt_format
);
150 so_method(so
, eng3d
, NV34TCL_VIEWPORT_HORIZ
, 2);
151 so_data (so
, (w
<< 16) | 0);
152 so_data (so
, (h
<< 16) | 0);
153 so_method(so
, eng3d
, NV34TCL_VIEWPORT_CLIP_HORIZ(0), 2);
154 so_data (so
, ((w
- 1) << 16) | 0);
155 so_data (so
, ((h
- 1) << 16) | 0);
156 so_method(so
, eng3d
, 0x1d88, 1);
157 so_data (so
, (1 << 12) | h
);
158 /* Wonder why this is needed, context should all be set to zero on init */
159 so_method(so
, eng3d
, NV34TCL_VIEWPORT_TX_ORIGIN
, 1);
162 so_ref(so
, &nv30
->state
.hw
[NV30_STATE_FB
]);
167 struct nv30_state_entry nv30_state_framebuffer
= {
168 .validate
= nv30_state_framebuffer_validate
,