2 #include "nvc0_context.h"
3 #include "os/os_time.h"
6 nvc0_validate_zcull(struct nvc0_context
*nvc0
)
8 struct nouveau_channel
*chan
= nvc0
->screen
->base
.channel
;
9 struct pipe_framebuffer_state
*fb
= &nvc0
->framebuffer
;
10 struct nvc0_miptree
*mt
= nvc0_miptree(fb
->zsbuf
->texture
);
11 struct nouveau_bo
*bo
= mt
->base
.bo
;
13 uint32_t offset
= align(mt
->total_size
, 1 << 17);
14 unsigned width
, height
;
16 size
= mt
->total_size
* 2;
18 height
= align(fb
->height
, 32);
19 width
= fb
->width
% 224;
21 width
= fb
->width
+ (224 - width
);
25 BEGIN_RING(chan
, RING_3D_(0x1590), 1); /* ZCULL_REGION_INDEX (bits 0x3f) */
27 BEGIN_RING(chan
, RING_3D_(0x07e8), 2); /* ZCULL_ADDRESS_A_HIGH */
28 OUT_RELOCh(chan
, bo
, offset
, NOUVEAU_BO_VRAM
| NOUVEAU_BO_RDWR
);
29 OUT_RELOCl(chan
, bo
, offset
, NOUVEAU_BO_VRAM
| NOUVEAU_BO_RDWR
);
31 BEGIN_RING(chan
, RING_3D_(0x07f0), 2); /* ZCULL_ADDRESS_B_HIGH */
32 OUT_RELOCh(chan
, bo
, offset
, NOUVEAU_BO_VRAM
| NOUVEAU_BO_RDWR
);
33 OUT_RELOCl(chan
, bo
, offset
, NOUVEAU_BO_VRAM
| NOUVEAU_BO_RDWR
);
34 BEGIN_RING(chan
, RING_3D_(0x07e0), 2);
35 OUT_RING (chan
, size
);
36 OUT_RING (chan
, size
>> 16);
37 BEGIN_RING(chan
, RING_3D_(0x15c8), 1); /* bits 0x3 */
39 BEGIN_RING(chan
, RING_3D_(0x07c0), 4); /* ZCULL dimensions */
40 OUT_RING (chan
, width
);
41 OUT_RING (chan
, height
);
44 BEGIN_RING(chan
, RING_3D_(0x15fc), 2);
45 OUT_RING (chan
, 0); /* bits 0xffff */
46 OUT_RING (chan
, 0); /* bits 0xffff */
47 BEGIN_RING(chan
, RING_3D_(0x1958), 1);
48 OUT_RING (chan
, 0); /* bits ~0 */
52 nvc0_validate_fb(struct nvc0_context
*nvc0
)
54 struct nouveau_channel
*chan
= nvc0
->screen
->base
.channel
;
55 struct pipe_framebuffer_state
*fb
= &nvc0
->framebuffer
;
58 nvc0_bufctx_reset(nvc0
, NVC0_BUFCTX_FRAME
);
60 BEGIN_RING(chan
, RING_3D(RT_CONTROL
), 1);
61 OUT_RING (chan
, (076543210 << 4) | fb
->nr_cbufs
);
62 BEGIN_RING(chan
, RING_3D(SCREEN_SCISSOR_HORIZ
), 2);
63 OUT_RING (chan
, fb
->width
<< 16);
64 OUT_RING (chan
, fb
->height
<< 16);
66 for (i
= 0; i
< fb
->nr_cbufs
; ++i
) {
67 struct nvc0_miptree
*mt
= nvc0_miptree(fb
->cbufs
[i
]->texture
);
68 struct nouveau_bo
*bo
= mt
->base
.bo
;
69 unsigned offset
= fb
->cbufs
[i
]->offset
;
71 BEGIN_RING(chan
, RING_3D(RT_ADDRESS_HIGH(i
)), 8);
72 OUT_RELOCh(chan
, bo
, offset
, NOUVEAU_BO_VRAM
| NOUVEAU_BO_RDWR
);
73 OUT_RELOCl(chan
, bo
, offset
, NOUVEAU_BO_VRAM
| NOUVEAU_BO_RDWR
);
74 OUT_RING (chan
, fb
->cbufs
[i
]->width
);
75 OUT_RING (chan
, fb
->cbufs
[i
]->height
);
76 OUT_RING (chan
, nvc0_format_table
[fb
->cbufs
[i
]->format
].rt
);
77 OUT_RING (chan
, mt
->level
[fb
->cbufs
[i
]->level
].tile_mode
);
81 nvc0_bufctx_add_resident(nvc0
, NVC0_BUFCTX_FRAME
, &mt
->base
,
82 NOUVEAU_BO_VRAM
| NOUVEAU_BO_RDWR
);
86 struct nvc0_miptree
*mt
= nvc0_miptree(fb
->zsbuf
->texture
);
87 struct nouveau_bo
*bo
= mt
->base
.bo
;
88 unsigned offset
= fb
->zsbuf
->offset
;
90 BEGIN_RING(chan
, RING_3D(ZETA_ADDRESS_HIGH
), 5);
91 OUT_RELOCh(chan
, bo
, offset
, NOUVEAU_BO_VRAM
| NOUVEAU_BO_RDWR
);
92 OUT_RELOCl(chan
, bo
, offset
, NOUVEAU_BO_VRAM
| NOUVEAU_BO_RDWR
);
93 OUT_RING (chan
, nvc0_format_table
[fb
->zsbuf
->format
].rt
);
94 OUT_RING (chan
, mt
->level
[fb
->zsbuf
->level
].tile_mode
);
96 BEGIN_RING(chan
, RING_3D(ZETA_ENABLE
), 1);
98 BEGIN_RING(chan
, RING_3D(ZETA_HORIZ
), 3);
99 OUT_RING (chan
, fb
->zsbuf
->width
);
100 OUT_RING (chan
, fb
->zsbuf
->height
);
101 OUT_RING (chan
, (1 << 16) | 1);
103 nvc0_bufctx_add_resident(nvc0
, NVC0_BUFCTX_FRAME
, &mt
->base
,
104 NOUVEAU_BO_VRAM
| NOUVEAU_BO_RDWR
);
106 BEGIN_RING(chan
, RING_3D(ZETA_ENABLE
), 1);
110 BEGIN_RING(chan
, RING_3D(VIEWPORT_HORIZ(0)), 2);
111 OUT_RING (chan
, fb
->width
<< 16);
112 OUT_RING (chan
, fb
->height
<< 16);
116 nvc0_validate_blend_colour(struct nvc0_context
*nvc0
)
118 struct nouveau_channel
*chan
= nvc0
->screen
->base
.channel
;
120 BEGIN_RING(chan
, RING_3D(BLEND_COLOR(0)), 4);
121 OUT_RINGf (chan
, nvc0
->blend_colour
.color
[0]);
122 OUT_RINGf (chan
, nvc0
->blend_colour
.color
[1]);
123 OUT_RINGf (chan
, nvc0
->blend_colour
.color
[2]);
124 OUT_RINGf (chan
, nvc0
->blend_colour
.color
[3]);
128 nvc0_validate_stencil_ref(struct nvc0_context
*nvc0
)
130 struct nouveau_channel
*chan
= nvc0
->screen
->base
.channel
;
132 BEGIN_RING(chan
, RING_3D(STENCIL_FRONT_FUNC_REF
), 1);
133 OUT_RING (chan
, nvc0
->stencil_ref
.ref_value
[0]);
134 BEGIN_RING(chan
, RING_3D(STENCIL_BACK_FUNC_REF
), 1);
135 OUT_RING (chan
, nvc0
->stencil_ref
.ref_value
[1]);
139 nvc0_validate_stipple(struct nvc0_context
*nvc0
)
141 struct nouveau_channel
*chan
= nvc0
->screen
->base
.channel
;
144 BEGIN_RING(chan
, RING_3D(POLYGON_STIPPLE_PATTERN(0)), 32);
145 for (i
= 0; i
< 32; ++i
)
146 OUT_RING(chan
, util_bswap32(nvc0
->stipple
.stipple
[i
]));
150 nvc0_validate_scissor(struct nvc0_context
*nvc0
)
152 struct nouveau_channel
*chan
= nvc0
->screen
->base
.channel
;
153 struct pipe_scissor_state
*s
= &nvc0
->scissor
;
155 if (!(nvc0
->dirty
& NVC0_NEW_SCISSOR
) &&
156 nvc0
->state
.scissor
== nvc0
->rast
->pipe
.scissor
)
158 nvc0
->state
.scissor
= nvc0
->rast
->pipe
.scissor
;
160 if (nvc0
->state
.scissor
) {
161 BEGIN_RING(chan
, RING_3D(SCISSOR_HORIZ(0)), 2);
162 OUT_RING (chan
, (s
->maxx
<< 16) | s
->minx
);
163 OUT_RING (chan
, (s
->maxy
<< 16) | s
->miny
);
165 BEGIN_RING(chan
, RING_3D(SCISSOR_HORIZ(0)), 2);
166 OUT_RING (chan
, nvc0
->framebuffer
.width
<< 16);
167 OUT_RING (chan
, nvc0
->framebuffer
.height
<< 16);
172 nvc0_validate_viewport(struct nvc0_context
*nvc0
)
174 struct nouveau_channel
*chan
= nvc0
->screen
->base
.channel
;
176 BEGIN_RING(chan
, RING_3D(VIEWPORT_TRANSLATE_X(0)), 3);
177 OUT_RINGf (chan
, nvc0
->viewport
.translate
[0]);
178 OUT_RINGf (chan
, nvc0
->viewport
.translate
[1]);
179 OUT_RINGf (chan
, nvc0
->viewport
.translate
[2]);
180 BEGIN_RING(chan
, RING_3D(VIEWPORT_SCALE_X(0)), 3);
181 OUT_RINGf (chan
, nvc0
->viewport
.scale
[0]);
182 OUT_RINGf (chan
, nvc0
->viewport
.scale
[1]);
183 OUT_RINGf (chan
, nvc0
->viewport
.scale
[2]);
187 nvc0_validate_clip(struct nvc0_context
*nvc0
)
189 struct nouveau_channel
*chan
= nvc0
->screen
->base
.channel
;
192 clip
= nvc0
->clip
.depth_clamp
? 0x201a : 0x0002;
194 BEGIN_RING(chan
, RING_3D(VIEW_VOLUME_CLIP_CTRL
), 1);
195 OUT_RING (chan
, clip
);
199 nvc0_validate_blend(struct nvc0_context
*nvc0
)
201 struct nouveau_channel
*chan
= nvc0
->screen
->base
.channel
;
203 WAIT_RING(chan
, nvc0
->blend
->size
);
204 OUT_RINGp(chan
, nvc0
->blend
->state
, nvc0
->blend
->size
);
208 nvc0_validate_zsa(struct nvc0_context
*nvc0
)
210 struct nouveau_channel
*chan
= nvc0
->screen
->base
.channel
;
212 WAIT_RING(chan
, nvc0
->zsa
->size
);
213 OUT_RINGp(chan
, nvc0
->zsa
->state
, nvc0
->zsa
->size
);
217 nvc0_validate_rasterizer(struct nvc0_context
*nvc0
)
219 struct nouveau_channel
*chan
= nvc0
->screen
->base
.channel
;
221 WAIT_RING(chan
, nvc0
->rast
->size
);
222 OUT_RINGp(chan
, nvc0
->rast
->state
, nvc0
->rast
->size
);
226 nvc0_constbufs_validate(struct nvc0_context
*nvc0
)
228 struct nouveau_channel
*chan
= nvc0
->screen
->base
.channel
;
229 struct nouveau_bo
*bo
;
232 for (s
= 0; s
< 5; ++s
) {
233 struct nvc0_resource
*res
;
236 while (nvc0
->constbuf_dirty
[s
]) {
238 unsigned offset
= 0, words
= 0;
239 boolean rebind
= TRUE
;
241 i
= ffs(nvc0
->constbuf_dirty
[s
]) - 1;
242 nvc0
->constbuf_dirty
[s
] &= ~(1 << i
);
244 res
= nvc0_resource(nvc0
->constbuf
[s
][i
]);
246 BEGIN_RING(chan
, RING_3D(CB_BIND(s
)), 1);
247 OUT_RING (chan
, (i
<< 4) | 0);
249 nvc0
->state
.uniform_buffer_bound
&= ~(1 << s
);
253 if (!nvc0_resource_mapped_by_gpu(&res
->base
)) {
256 bo
= nvc0
->screen
->uniforms
;
258 if (nvc0
->state
.uniform_buffer_bound
& (1 << s
))
261 nvc0
->state
.uniform_buffer_bound
|= (1 << s
);
266 nvc0_m2mf_push_linear(nvc0
, bo
, NOUVEAU_BO_VRAM
,
267 base
, res
->base
.width0
, res
->data
);
268 BEGIN_RING(chan
, RING_3D_(0x021c), 1);
269 OUT_RING (chan
, 0x1111);
271 words
= res
->base
.width0
/ 4;
276 nvc0
->state
.uniform_buffer_bound
&= ~(1 << s
);
279 if (bo
!= nvc0
->screen
->uniforms
)
280 nvc0_bufctx_add_resident(nvc0
, NVC0_BUFCTX_CONSTANT
, res
,
281 NOUVEAU_BO_VRAM
| NOUVEAU_BO_RD
);
284 BEGIN_RING(chan
, RING_3D(CB_SIZE
), 3);
285 OUT_RING (chan
, align(res
->base
.width0
, 0x100));
286 OUT_RELOCh(chan
, bo
, base
, NOUVEAU_BO_VRAM
| NOUVEAU_BO_RD
);
287 OUT_RELOCl(chan
, bo
, base
, NOUVEAU_BO_VRAM
| NOUVEAU_BO_RD
);
288 BEGIN_RING(chan
, RING_3D(CB_BIND(s
)), 1);
289 OUT_RING (chan
, (i
<< 4) | 1);
293 unsigned nr
= AVAIL_RING(chan
);
299 nr
= MIN2(MIN2(nr
- 6, words
), NV04_PFIFO_MAX_PACKET_LEN
- 1);
301 BEGIN_RING(chan
, RING_3D(CB_SIZE
), 3);
302 OUT_RING (chan
, align(res
->base
.width0
, 0x100));
303 OUT_RELOCh(chan
, bo
, base
, NOUVEAU_BO_VRAM
| NOUVEAU_BO_RD
);
304 OUT_RELOCl(chan
, bo
, base
, NOUVEAU_BO_VRAM
| NOUVEAU_BO_RD
);
305 BEGIN_RING_1I(chan
, RING_3D(CB_POS
), nr
+ 1);
306 OUT_RING (chan
, offset
);
307 OUT_RINGp (chan
, &res
->data
[offset
], nr
);
316 static struct state_validate
{
317 void (*func
)(struct nvc0_context
*);
319 } validate_list
[] = {
320 { nvc0_validate_fb
, NVC0_NEW_FRAMEBUFFER
},
321 { nvc0_validate_blend
, NVC0_NEW_BLEND
},
322 { nvc0_validate_zsa
, NVC0_NEW_ZSA
},
323 { nvc0_validate_rasterizer
, NVC0_NEW_RASTERIZER
},
324 { nvc0_validate_blend_colour
, NVC0_NEW_BLEND_COLOUR
},
325 { nvc0_validate_stencil_ref
, NVC0_NEW_STENCIL_REF
},
326 { nvc0_validate_stipple
, NVC0_NEW_STIPPLE
},
327 { nvc0_validate_scissor
, NVC0_NEW_SCISSOR
| NVC0_NEW_FRAMEBUFFER
|
328 NVC0_NEW_RASTERIZER
},
329 { nvc0_validate_viewport
, NVC0_NEW_VIEWPORT
},
330 { nvc0_validate_clip
, NVC0_NEW_CLIP
},
331 { nvc0_vertprog_validate
, NVC0_NEW_VERTPROG
},
332 { nvc0_tctlprog_validate
, NVC0_NEW_TCTLPROG
},
333 { nvc0_tevlprog_validate
, NVC0_NEW_TEVLPROG
},
334 { nvc0_gmtyprog_validate
, NVC0_NEW_GMTYPROG
},
335 { nvc0_fragprog_validate
, NVC0_NEW_FRAGPROG
},
336 { nvc0_constbufs_validate
, NVC0_NEW_CONSTBUF
},
337 { nvc0_validate_textures
, NVC0_NEW_TEXTURES
},
338 { nvc0_validate_samplers
, NVC0_NEW_SAMPLERS
},
339 { nvc0_vertex_arrays_validate
, NVC0_NEW_VERTEX
| NVC0_NEW_ARRAYS
}
341 #define validate_list_len (sizeof(validate_list) / sizeof(validate_list[0]))
344 nvc0_state_validate(struct nvc0_context
*nvc0
)
348 if (nvc0
->screen
->cur_ctx
!= nvc0
) /* FIXME: not everything is valid */
349 nvc0
->dirty
= 0xffffffff;
351 nvc0
->screen
->cur_ctx
= nvc0
;
354 for (i
= 0; i
< validate_list_len
; ++i
) {
355 struct state_validate
*validate
= &validate_list
[i
];
357 if (nvc0
->dirty
& validate
->states
)
358 validate
->func(nvc0
);
363 nvc0_bufctx_emit_relocs(nvc0
);