2 #include "nv50_context.h"
3 #include "os/os_time.h"
6 nv50_validate_fb(struct nv50_context
*nv50
)
8 struct nouveau_channel
*chan
= nv50
->screen
->base
.channel
;
9 struct pipe_framebuffer_state
*fb
= &nv50
->framebuffer
;
11 boolean serialize
= FALSE
;
13 nv50_bufctx_reset(nv50
, NV50_BUFCTX_FRAME
);
15 BEGIN_RING(chan
, RING_3D(RT_CONTROL
), 1);
16 OUT_RING (chan
, (076543210 << 4) | fb
->nr_cbufs
);
17 BEGIN_RING(chan
, RING_3D(SCREEN_SCISSOR_HORIZ
), 2);
18 OUT_RING (chan
, fb
->width
<< 16);
19 OUT_RING (chan
, fb
->height
<< 16);
21 MARK_RING(chan
, 9 * fb
->nr_cbufs
, 2 * fb
->nr_cbufs
);
23 for (i
= 0; i
< fb
->nr_cbufs
; ++i
) {
24 struct nv50_miptree
*mt
= nv50_miptree(fb
->cbufs
[i
]->texture
);
25 struct nv50_surface
*sf
= nv50_surface(fb
->cbufs
[i
]);
26 struct nouveau_bo
*bo
= mt
->base
.bo
;
27 uint32_t offset
= sf
->offset
;
29 BEGIN_RING(chan
, RING_3D(RT_ADDRESS_HIGH(i
)), 5);
30 OUT_RELOCh(chan
, bo
, offset
, NOUVEAU_BO_VRAM
| NOUVEAU_BO_RDWR
);
31 OUT_RELOCl(chan
, bo
, offset
, NOUVEAU_BO_VRAM
| NOUVEAU_BO_RDWR
);
32 OUT_RING (chan
, nv50_format_table
[sf
->base
.format
].rt
);
33 OUT_RING (chan
, mt
->level
[sf
->base
.u
.tex
.level
].tile_mode
<< 4);
34 OUT_RING (chan
, mt
->layer_stride
>> 2);
35 BEGIN_RING(chan
, RING_3D(RT_HORIZ(i
)), 2);
36 OUT_RING (chan
, sf
->width
);
37 OUT_RING (chan
, sf
->height
);
38 BEGIN_RING(chan
, RING_3D(RT_ARRAY_MODE
), 1);
39 OUT_RING (chan
, sf
->depth
);
41 if (mt
->base
.status
& NOUVEAU_BUFFER_STATUS_GPU_READING
)
43 mt
->base
.status
|= NOUVEAU_BUFFER_STATUS_GPU_WRITING
;
44 mt
->base
.status
&= NOUVEAU_BUFFER_STATUS_GPU_READING
;
46 nv50_bufctx_add_resident(nv50
, NV50_BUFCTX_FRAME
, &mt
->base
,
47 NOUVEAU_BO_VRAM
| NOUVEAU_BO_RDWR
);
51 struct nv50_miptree
*mt
= nv50_miptree(fb
->zsbuf
->texture
);
52 struct nv50_surface
*sf
= nv50_surface(fb
->zsbuf
);
53 struct nouveau_bo
*bo
= mt
->base
.bo
;
54 int unk
= mt
->base
.base
.target
== PIPE_TEXTURE_2D
;
55 uint32_t offset
= sf
->offset
;
57 MARK_RING (chan
, 12, 2);
58 BEGIN_RING(chan
, RING_3D(ZETA_ADDRESS_HIGH
), 5);
59 OUT_RELOCh(chan
, bo
, offset
, NOUVEAU_BO_VRAM
| NOUVEAU_BO_RDWR
);
60 OUT_RELOCl(chan
, bo
, offset
, NOUVEAU_BO_VRAM
| NOUVEAU_BO_RDWR
);
61 OUT_RING (chan
, nv50_format_table
[fb
->zsbuf
->format
].rt
);
62 OUT_RING (chan
, mt
->level
[sf
->base
.u
.tex
.level
].tile_mode
<< 4);
63 OUT_RING (chan
, mt
->layer_stride
>> 2);
64 BEGIN_RING(chan
, RING_3D(ZETA_ENABLE
), 1);
66 BEGIN_RING(chan
, RING_3D(ZETA_HORIZ
), 3);
67 OUT_RING (chan
, sf
->width
);
68 OUT_RING (chan
, sf
->height
);
69 OUT_RING (chan
, (unk
<< 16) | sf
->depth
);
71 if (mt
->base
.status
& NOUVEAU_BUFFER_STATUS_GPU_READING
)
73 mt
->base
.status
|= NOUVEAU_BUFFER_STATUS_GPU_WRITING
;
74 mt
->base
.status
&= NOUVEAU_BUFFER_STATUS_GPU_READING
;
76 nv50_bufctx_add_resident(nv50
, NV50_BUFCTX_FRAME
, &mt
->base
,
77 NOUVEAU_BO_VRAM
| NOUVEAU_BO_RDWR
);
79 BEGIN_RING(chan
, RING_3D(ZETA_ENABLE
), 1);
83 BEGIN_RING(chan
, RING_3D(VIEWPORT_HORIZ(0)), 2);
84 OUT_RING (chan
, fb
->width
<< 16);
85 OUT_RING (chan
, fb
->height
<< 16);
88 BEGIN_RING(chan
, RING_3D(SERIALIZE
), 1);
94 nv50_validate_blend_colour(struct nv50_context
*nv50
)
96 struct nouveau_channel
*chan
= nv50
->screen
->base
.channel
;
98 BEGIN_RING(chan
, RING_3D(BLEND_COLOR(0)), 4);
99 OUT_RINGf (chan
, nv50
->blend_colour
.color
[0]);
100 OUT_RINGf (chan
, nv50
->blend_colour
.color
[1]);
101 OUT_RINGf (chan
, nv50
->blend_colour
.color
[2]);
102 OUT_RINGf (chan
, nv50
->blend_colour
.color
[3]);
106 nv50_validate_stencil_ref(struct nv50_context
*nv50
)
108 struct nouveau_channel
*chan
= nv50
->screen
->base
.channel
;
110 BEGIN_RING(chan
, RING_3D(STENCIL_FRONT_FUNC_REF
), 1);
111 OUT_RING (chan
, nv50
->stencil_ref
.ref_value
[0]);
112 BEGIN_RING(chan
, RING_3D(STENCIL_BACK_FUNC_REF
), 1);
113 OUT_RING (chan
, nv50
->stencil_ref
.ref_value
[1]);
117 nv50_validate_stipple(struct nv50_context
*nv50
)
119 struct nouveau_channel
*chan
= nv50
->screen
->base
.channel
;
122 BEGIN_RING(chan
, RING_3D(POLYGON_STIPPLE_PATTERN(0)), 32);
123 for (i
= 0; i
< 32; ++i
)
124 OUT_RING(chan
, util_bswap32(nv50
->stipple
.stipple
[i
]));
128 nv50_validate_scissor(struct nv50_context
*nv50
)
130 struct nouveau_channel
*chan
= nv50
->screen
->base
.channel
;
131 struct pipe_scissor_state
*s
= &nv50
->scissor
;
132 #ifdef NV50_SCISSORS_CLIPPING
133 struct pipe_viewport_state
*vp
= &nv50
->viewport
;
134 int minx
, maxx
, miny
, maxy
;
137 (NV50_NEW_SCISSOR
| NV50_NEW_VIEWPORT
| NV50_NEW_FRAMEBUFFER
)) &&
138 nv50
->state
.scissor
== nv50
->rast
->pipe
.scissor
)
140 nv50
->state
.scissor
= nv50
->rast
->pipe
.scissor
;
142 if (nv50
->state
.scissor
) {
149 maxx
= nv50
->framebuffer
.width
;
151 maxy
= nv50
->framebuffer
.height
;
154 minx
= MAX2(minx
, (int)(vp
->translate
[0] - fabsf(vp
->scale
[0])));
155 maxx
= MIN2(maxx
, (int)(vp
->translate
[0] + fabsf(vp
->scale
[0])));
156 miny
= MAX2(miny
, (int)(vp
->translate
[1] - fabsf(vp
->scale
[1])));
157 maxy
= MIN2(maxy
, (int)(vp
->translate
[1] + fabsf(vp
->scale
[1])));
159 BEGIN_RING(chan
, RING_3D(SCISSOR_HORIZ(0)), 2);
160 OUT_RING (chan
, (maxx
<< 16) | minx
);
161 OUT_RING (chan
, (maxy
<< 16) | miny
);
163 BEGIN_RING(chan
, RING_3D(SCISSOR_HORIZ(0)), 2);
164 OUT_RING (chan
, (s
->maxx
<< 16) | s
->minx
);
165 OUT_RING (chan
, (s
->maxy
<< 16) | s
->miny
);
170 nv50_validate_viewport(struct nv50_context
*nv50
)
172 struct nouveau_channel
*chan
= nv50
->screen
->base
.channel
;
175 BEGIN_RING(chan
, RING_3D(VIEWPORT_TRANSLATE_X(0)), 3);
176 OUT_RINGf (chan
, nv50
->viewport
.translate
[0]);
177 OUT_RINGf (chan
, nv50
->viewport
.translate
[1]);
178 OUT_RINGf (chan
, nv50
->viewport
.translate
[2]);
179 BEGIN_RING(chan
, RING_3D(VIEWPORT_SCALE_X(0)), 3);
180 OUT_RINGf (chan
, nv50
->viewport
.scale
[0]);
181 OUT_RINGf (chan
, nv50
->viewport
.scale
[1]);
182 OUT_RINGf (chan
, nv50
->viewport
.scale
[2]);
184 zmin
= nv50
->viewport
.translate
[2] - fabsf(nv50
->viewport
.scale
[2]);
185 zmax
= nv50
->viewport
.translate
[2] + fabsf(nv50
->viewport
.scale
[2]);
187 #ifdef NV50_SCISSORS_CLIPPING
188 BEGIN_RING(chan
, RING_3D(DEPTH_RANGE_NEAR(0)), 2);
189 OUT_RINGf (chan
, zmin
);
190 OUT_RINGf (chan
, zmax
);
195 nv50_validate_clip(struct nv50_context
*nv50
)
197 struct nouveau_channel
*chan
= nv50
->screen
->base
.channel
;
200 clip
= nv50
->clip
.depth_clamp
? 0x0018 : 0x0000;
201 #ifndef NV50_SCISSORS_CLIPPING
205 BEGIN_RING(chan
, RING_3D(VIEW_VOLUME_CLIP_CTRL
), 1);
206 OUT_RING (chan
, clip
);
209 BEGIN_RING(chan
, RING_3D(CB_ADDR
), 1);
210 OUT_RING (chan
, (0 << 8) | NV50_CB_AUX
);
211 BEGIN_RING_NI(chan
, RING_3D(CB_DATA(0)), nv50
->clip
.nr
* 4);
212 OUT_RINGp (chan
, &nv50
->clip
.ucp
[0][0], nv50
->clip
.nr
* 4);
215 BEGIN_RING(chan
, RING_3D(VP_CLIP_DISTANCE_ENABLE
), 1);
216 OUT_RING (chan
, (1 << nv50
->clip
.nr
) - 1);
220 nv50_validate_blend(struct nv50_context
*nv50
)
222 struct nouveau_channel
*chan
= nv50
->screen
->base
.channel
;
224 WAIT_RING(chan
, nv50
->blend
->size
);
225 OUT_RINGp(chan
, nv50
->blend
->state
, nv50
->blend
->size
);
229 nv50_validate_zsa(struct nv50_context
*nv50
)
231 struct nouveau_channel
*chan
= nv50
->screen
->base
.channel
;
233 WAIT_RING(chan
, nv50
->zsa
->size
);
234 OUT_RINGp(chan
, nv50
->zsa
->state
, nv50
->zsa
->size
);
238 nv50_validate_rasterizer(struct nv50_context
*nv50
)
240 struct nouveau_channel
*chan
= nv50
->screen
->base
.channel
;
242 WAIT_RING(chan
, nv50
->rast
->size
);
243 OUT_RINGp(chan
, nv50
->rast
->state
, nv50
->rast
->size
);
246 static struct state_validate
{
247 void (*func
)(struct nv50_context
*);
249 } validate_list
[] = {
250 { nv50_validate_fb
, NV50_NEW_FRAMEBUFFER
},
251 { nv50_validate_blend
, NV50_NEW_BLEND
},
252 { nv50_validate_zsa
, NV50_NEW_ZSA
},
253 { nv50_validate_rasterizer
, NV50_NEW_RASTERIZER
},
254 { nv50_validate_blend_colour
, NV50_NEW_BLEND_COLOUR
},
255 { nv50_validate_stencil_ref
, NV50_NEW_STENCIL_REF
},
256 { nv50_validate_stipple
, NV50_NEW_STIPPLE
},
257 #ifdef NV50_SCISSORS_CLIPPING
258 { nv50_validate_scissor
, NV50_NEW_SCISSOR
| NV50_NEW_VIEWPORT
|
259 NV50_NEW_RASTERIZER
|
260 NV50_NEW_FRAMEBUFFER
},
262 { nv50_validate_scissor
, NV50_NEW_SCISSOR
},
264 { nv50_validate_viewport
, NV50_NEW_VIEWPORT
},
265 { nv50_validate_clip
, NV50_NEW_CLIP
},
266 { nv50_vertprog_validate
, NV50_NEW_VERTPROG
},
267 { nv50_gmtyprog_validate
, NV50_NEW_GMTYPROG
},
268 { nv50_fragprog_validate
, NV50_NEW_FRAGPROG
},
269 { nv50_fp_linkage_validate
, NV50_NEW_FRAGPROG
| NV50_NEW_VERTPROG
|
271 { nv50_gp_linkage_validate
, NV50_NEW_GMTYPROG
| NV50_NEW_VERTPROG
},
272 { nv50_constbufs_validate
, NV50_NEW_CONSTBUF
},
273 { nv50_validate_textures
, NV50_NEW_TEXTURES
},
274 { nv50_validate_samplers
, NV50_NEW_SAMPLERS
},
275 { nv50_vertex_arrays_validate
, NV50_NEW_VERTEX
| NV50_NEW_ARRAYS
}
277 #define validate_list_len (sizeof(validate_list) / sizeof(validate_list[0]))
280 nv50_state_validate(struct nv50_context
*nv50
)
284 if (nv50
->screen
->cur_ctx
!= nv50
) /* FIXME: not everything is valid */
285 nv50
->dirty
= 0xffffffff;
287 nv50
->screen
->cur_ctx
= nv50
;
290 for (i
= 0; i
< validate_list_len
; ++i
) {
291 struct state_validate
*validate
= &validate_list
[i
];
293 if (nv50
->dirty
& validate
->states
)
294 validate
->func(nv50
);
299 nv50_bufctx_emit_relocs(nv50
);