Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mesa
Path: blob/21.2-virgl/src/gallium/drivers/nouveau/nv30/nv30_state_validate.c
4574 views
1
/*
2
* Copyright 2012 Red Hat Inc.
3
*
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:
10
*
11
* The above copyright notice and this permission notice shall be included in
12
* all copies or substantial portions of the Software.
13
*
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 OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
18
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20
* OTHER DEALINGS IN THE SOFTWARE.
21
*
22
* Authors: Ben Skeggs
23
*
24
*/
25
26
#include "util/format/u_format.h"
27
#include "util/u_math.h"
28
#include "util/half_float.h"
29
30
#include "nv_object.xml.h"
31
#include "nv30/nv30-40_3d.xml.h"
32
#include "nv30/nv30_context.h"
33
#include "nv30/nv30_format.h"
34
35
static void
36
nv30_validate_fb(struct nv30_context *nv30)
37
{
38
struct pipe_screen *pscreen = &nv30->screen->base.base;
39
struct pipe_framebuffer_state *fb = &nv30->framebuffer;
40
struct nouveau_pushbuf *push = nv30->base.pushbuf;
41
struct nouveau_object *eng3d = nv30->screen->eng3d;
42
uint32_t rt_format;
43
int h = fb->height;
44
int w = fb->width;
45
int x = 0;
46
int y = 0;
47
48
nv30->state.rt_enable = (NV30_3D_RT_ENABLE_COLOR0 << fb->nr_cbufs) - 1;
49
if (nv30->state.rt_enable > 1)
50
nv30->state.rt_enable |= NV30_3D_RT_ENABLE_MRT;
51
52
rt_format = 0;
53
if (fb->nr_cbufs > 0) {
54
struct nv30_miptree *mt = nv30_miptree(fb->cbufs[0]->texture);
55
rt_format |= nv30_format(pscreen, fb->cbufs[0]->format)->hw;
56
rt_format |= mt->ms_mode;
57
if (mt->swizzled)
58
rt_format |= NV30_3D_RT_FORMAT_TYPE_SWIZZLED;
59
else
60
rt_format |= NV30_3D_RT_FORMAT_TYPE_LINEAR;
61
} else {
62
if (fb->zsbuf && util_format_get_blocksize(fb->zsbuf->format) > 2)
63
rt_format |= NV30_3D_RT_FORMAT_COLOR_A8R8G8B8;
64
else
65
rt_format |= NV30_3D_RT_FORMAT_COLOR_R5G6B5;
66
}
67
68
if (fb->zsbuf) {
69
rt_format |= nv30_format(pscreen, fb->zsbuf->format)->hw;
70
if (nv30_miptree(fb->zsbuf->texture)->swizzled)
71
rt_format |= NV30_3D_RT_FORMAT_TYPE_SWIZZLED;
72
else
73
rt_format |= NV30_3D_RT_FORMAT_TYPE_LINEAR;
74
} else {
75
if (fb->nr_cbufs && util_format_get_blocksize(fb->cbufs[0]->format) > 2)
76
rt_format |= NV30_3D_RT_FORMAT_ZETA_Z24S8;
77
else
78
rt_format |= NV30_3D_RT_FORMAT_ZETA_Z16;
79
}
80
81
/* hardware rounds down render target offset to 64 bytes, but surfaces
82
* with a size of 2x2 pixel (16bpp) or 1x1 pixel (32bpp) have an
83
* unaligned start address. For these two important square formats
84
* we can hack around this limitation by adjusting the viewport origin
85
*/
86
if (nv30->state.rt_enable) {
87
int off = nv30_surface(fb->cbufs[0])->offset & 63;
88
if (off) {
89
x += off / (util_format_get_blocksize(fb->cbufs[0]->format) * 2);
90
w = 16;
91
h = 2;
92
}
93
}
94
95
if (rt_format & NV30_3D_RT_FORMAT_TYPE_SWIZZLED) {
96
rt_format |= util_logbase2(w) << 16;
97
rt_format |= util_logbase2(h) << 24;
98
}
99
100
if (!PUSH_SPACE(push, 64))
101
return;
102
PUSH_RESET(push, BUFCTX_FB);
103
104
BEGIN_NV04(push, SUBC_3D(0x1da4), 1);
105
PUSH_DATA (push, 0);
106
BEGIN_NV04(push, NV30_3D(RT_HORIZ), 3);
107
PUSH_DATA (push, w << 16);
108
PUSH_DATA (push, h << 16);
109
PUSH_DATA (push, rt_format);
110
BEGIN_NV04(push, NV30_3D(VIEWPORT_TX_ORIGIN), 4);
111
PUSH_DATA (push, (y << 16) | x);
112
PUSH_DATA (push, 0);
113
PUSH_DATA (push, ((w - 1) << 16) | 0);
114
PUSH_DATA (push, ((h - 1) << 16) | 0);
115
116
if ((nv30->state.rt_enable & NV30_3D_RT_ENABLE_COLOR0) || fb->zsbuf) {
117
struct nv30_surface *rsf = nv30_surface(fb->cbufs[0]);
118
struct nv30_surface *zsf = nv30_surface(fb->zsbuf);
119
struct nouveau_bo *rbo, *zbo;
120
121
if (!rsf) rsf = zsf;
122
else if (!zsf) zsf = rsf;
123
rbo = nv30_miptree(rsf->base.texture)->base.bo;
124
zbo = nv30_miptree(zsf->base.texture)->base.bo;
125
126
if (eng3d->oclass >= NV40_3D_CLASS) {
127
BEGIN_NV04(push, NV40_3D(ZETA_PITCH), 1);
128
PUSH_DATA (push, zsf->pitch);
129
BEGIN_NV04(push, NV40_3D(COLOR0_PITCH), 3);
130
PUSH_DATA (push, rsf->pitch);
131
} else {
132
BEGIN_NV04(push, NV30_3D(COLOR0_PITCH), 3);
133
PUSH_DATA (push, (zsf->pitch << 16) | rsf->pitch);
134
}
135
PUSH_MTHDl(push, NV30_3D(COLOR0_OFFSET), BUFCTX_FB, rbo, rsf->offset & ~63,
136
NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR);
137
PUSH_MTHDl(push, NV30_3D(ZETA_OFFSET), BUFCTX_FB, zbo, zsf->offset & ~63,
138
NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR);
139
}
140
141
if (nv30->state.rt_enable & NV30_3D_RT_ENABLE_COLOR1) {
142
struct nv30_surface *sf = nv30_surface(fb->cbufs[1]);
143
struct nouveau_bo *bo = nv30_miptree(sf->base.texture)->base.bo;
144
145
BEGIN_NV04(push, NV30_3D(COLOR1_OFFSET), 2);
146
PUSH_MTHDl(push, NV30_3D(COLOR1_OFFSET), BUFCTX_FB, bo, sf->offset,
147
NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR);
148
PUSH_DATA (push, sf->pitch);
149
}
150
151
if (nv30->state.rt_enable & NV40_3D_RT_ENABLE_COLOR2) {
152
struct nv30_surface *sf = nv30_surface(fb->cbufs[2]);
153
struct nouveau_bo *bo = nv30_miptree(sf->base.texture)->base.bo;
154
155
BEGIN_NV04(push, NV40_3D(COLOR2_OFFSET), 1);
156
PUSH_MTHDl(push, NV40_3D(COLOR2_OFFSET), BUFCTX_FB, bo, sf->offset,
157
NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR);
158
BEGIN_NV04(push, NV40_3D(COLOR2_PITCH), 1);
159
PUSH_DATA (push, sf->pitch);
160
}
161
162
if (nv30->state.rt_enable & NV40_3D_RT_ENABLE_COLOR3) {
163
struct nv30_surface *sf = nv30_surface(fb->cbufs[3]);
164
struct nouveau_bo *bo = nv30_miptree(sf->base.texture)->base.bo;
165
166
BEGIN_NV04(push, NV40_3D(COLOR3_OFFSET), 1);
167
PUSH_MTHDl(push, NV40_3D(COLOR3_OFFSET), BUFCTX_FB, bo, sf->offset,
168
NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR);
169
BEGIN_NV04(push, NV40_3D(COLOR3_PITCH), 1);
170
PUSH_DATA (push, sf->pitch);
171
}
172
}
173
174
static void
175
nv30_validate_blend_colour(struct nv30_context *nv30)
176
{
177
struct nouveau_pushbuf *push = nv30->base.pushbuf;
178
float *rgba = nv30->blend_colour.color;
179
180
if (nv30->framebuffer.nr_cbufs) {
181
switch (nv30->framebuffer.cbufs[0]->format) {
182
case PIPE_FORMAT_R16G16B16A16_FLOAT:
183
case PIPE_FORMAT_R32G32B32A32_FLOAT:
184
BEGIN_NV04(push, NV30_3D(BLEND_COLOR), 1);
185
PUSH_DATA (push, (_mesa_float_to_half(rgba[0]) << 0) |
186
(_mesa_float_to_half(rgba[1]) << 16));
187
BEGIN_NV04(push, SUBC_3D(0x037c), 1);
188
PUSH_DATA (push, (_mesa_float_to_half(rgba[2]) << 0) |
189
(_mesa_float_to_half(rgba[3]) << 16));
190
break;
191
default:
192
break;
193
}
194
}
195
196
BEGIN_NV04(push, NV30_3D(BLEND_COLOR), 1);
197
PUSH_DATA (push, (float_to_ubyte(rgba[3]) << 24) |
198
(float_to_ubyte(rgba[0]) << 16) |
199
(float_to_ubyte(rgba[1]) << 8) |
200
(float_to_ubyte(rgba[2]) << 0));
201
}
202
203
static void
204
nv30_validate_stencil_ref(struct nv30_context *nv30)
205
{
206
struct nouveau_pushbuf *push = nv30->base.pushbuf;
207
208
BEGIN_NV04(push, NV30_3D(STENCIL_FUNC_REF(0)), 1);
209
PUSH_DATA (push, nv30->stencil_ref.ref_value[0]);
210
BEGIN_NV04(push, NV30_3D(STENCIL_FUNC_REF(1)), 1);
211
PUSH_DATA (push, nv30->stencil_ref.ref_value[1]);
212
}
213
214
static void
215
nv30_validate_stipple(struct nv30_context *nv30)
216
{
217
struct nouveau_pushbuf *push = nv30->base.pushbuf;
218
219
BEGIN_NV04(push, NV30_3D(POLYGON_STIPPLE_PATTERN(0)), 32);
220
PUSH_DATAp(push, nv30->stipple.stipple, 32);
221
}
222
223
static void
224
nv30_validate_scissor(struct nv30_context *nv30)
225
{
226
struct nouveau_pushbuf *push = nv30->base.pushbuf;
227
struct pipe_scissor_state *s = &nv30->scissor;
228
bool rast_scissor = nv30->rast ? nv30->rast->pipe.scissor : false;
229
230
if (!(nv30->dirty & NV30_NEW_SCISSOR) &&
231
rast_scissor != nv30->state.scissor_off)
232
return;
233
nv30->state.scissor_off = !rast_scissor;
234
235
BEGIN_NV04(push, NV30_3D(SCISSOR_HORIZ), 2);
236
if (rast_scissor) {
237
PUSH_DATA (push, ((s->maxx - s->minx) << 16) | s->minx);
238
PUSH_DATA (push, ((s->maxy - s->miny) << 16) | s->miny);
239
} else {
240
PUSH_DATA (push, 0x10000000);
241
PUSH_DATA (push, 0x10000000);
242
}
243
}
244
245
static void
246
nv30_validate_viewport(struct nv30_context *nv30)
247
{
248
struct nouveau_pushbuf *push = nv30->base.pushbuf;
249
struct pipe_viewport_state *vp = &nv30->viewport;
250
251
unsigned x = CLAMP(vp->translate[0] - fabsf(vp->scale[0]), 0, 4095);
252
unsigned y = CLAMP(vp->translate[1] - fabsf(vp->scale[1]), 0, 4095);
253
unsigned w = CLAMP(2.0f * fabsf(vp->scale[0]), 0, 4096);
254
unsigned h = CLAMP(2.0f * fabsf(vp->scale[1]), 0, 4096);
255
256
BEGIN_NV04(push, NV30_3D(VIEWPORT_TRANSLATE_X), 8);
257
PUSH_DATAf(push, vp->translate[0]);
258
PUSH_DATAf(push, vp->translate[1]);
259
PUSH_DATAf(push, vp->translate[2]);
260
PUSH_DATAf(push, 0.0f);
261
PUSH_DATAf(push, vp->scale[0]);
262
PUSH_DATAf(push, vp->scale[1]);
263
PUSH_DATAf(push, vp->scale[2]);
264
PUSH_DATAf(push, 0.0f);
265
BEGIN_NV04(push, NV30_3D(DEPTH_RANGE_NEAR), 2);
266
PUSH_DATAf(push, vp->translate[2] - fabsf(vp->scale[2]));
267
PUSH_DATAf(push, vp->translate[2] + fabsf(vp->scale[2]));
268
269
BEGIN_NV04(push, NV30_3D(VIEWPORT_HORIZ), 2);
270
PUSH_DATA (push, (w << 16) | x);
271
PUSH_DATA (push, (h << 16) | y);
272
}
273
274
static void
275
nv30_validate_clip(struct nv30_context *nv30)
276
{
277
struct nouveau_pushbuf *push = nv30->base.pushbuf;
278
unsigned i;
279
uint32_t clpd_enable = 0;
280
281
for (i = 0; i < 6; i++) {
282
if (nv30->dirty & NV30_NEW_CLIP) {
283
BEGIN_NV04(push, NV30_3D(VP_UPLOAD_CONST_ID), 5);
284
PUSH_DATA (push, i);
285
PUSH_DATAp(push, nv30->clip.ucp[i], 4);
286
}
287
if (nv30->rast->pipe.clip_plane_enable & (1 << i))
288
clpd_enable |= 2 << (4*i);
289
}
290
291
BEGIN_NV04(push, NV30_3D(VP_CLIP_PLANES_ENABLE), 1);
292
PUSH_DATA (push, clpd_enable);
293
}
294
295
static void
296
nv30_validate_blend(struct nv30_context *nv30)
297
{
298
struct nouveau_pushbuf *push = nv30->base.pushbuf;
299
300
PUSH_SPACE(push, nv30->blend->size);
301
PUSH_DATAp(push, nv30->blend->data, nv30->blend->size);
302
}
303
304
static void
305
nv30_validate_zsa(struct nv30_context *nv30)
306
{
307
struct nouveau_pushbuf *push = nv30->base.pushbuf;
308
309
PUSH_SPACE(push, nv30->zsa->size);
310
PUSH_DATAp(push, nv30->zsa->data, nv30->zsa->size);
311
}
312
313
static void
314
nv30_validate_rasterizer(struct nv30_context *nv30)
315
{
316
struct nouveau_pushbuf *push = nv30->base.pushbuf;
317
318
PUSH_SPACE(push, nv30->rast->size);
319
PUSH_DATAp(push, nv30->rast->data, nv30->rast->size);
320
}
321
322
static void
323
nv30_validate_multisample(struct nv30_context *nv30)
324
{
325
struct pipe_rasterizer_state *rasterizer = &nv30->rast->pipe;
326
struct pipe_blend_state *blend = &nv30->blend->pipe;
327
struct nouveau_pushbuf *push = nv30->base.pushbuf;
328
uint32_t ctrl = nv30->sample_mask << 16;
329
330
if (blend->alpha_to_one)
331
ctrl |= 0x00000100;
332
if (blend->alpha_to_coverage)
333
ctrl |= 0x00000010;
334
if (rasterizer->multisample)
335
ctrl |= 0x00000001;
336
337
BEGIN_NV04(push, NV30_3D(MULTISAMPLE_CONTROL), 1);
338
PUSH_DATA (push, ctrl);
339
}
340
341
static void
342
nv30_validate_fragment(struct nv30_context *nv30)
343
{
344
struct nouveau_pushbuf *push = nv30->base.pushbuf;
345
struct nv30_fragprog *fp = nv30->fragprog.program;
346
347
BEGIN_NV04(push, NV30_3D(RT_ENABLE), 1);
348
PUSH_DATA (push, nv30->state.rt_enable & (fp ? ~fp->rt_enable : 0x1f));
349
BEGIN_NV04(push, NV30_3D(COORD_CONVENTIONS), 1);
350
PUSH_DATA (push, (fp ? fp->coord_conventions : 0) | nv30->framebuffer.height);
351
}
352
353
static void
354
nv30_validate_point_coord(struct nv30_context *nv30)
355
{
356
struct pipe_rasterizer_state *rasterizer = &nv30->rast->pipe;
357
struct nouveau_pushbuf *push = nv30->base.pushbuf;
358
struct nv30_fragprog *fp = nv30->fragprog.program;
359
uint32_t hw = 0x00000000;
360
361
if (rasterizer) {
362
hw |= (nv30->rast->pipe.sprite_coord_enable & 0xff) << 8;
363
if (fp)
364
hw |= fp->point_sprite_control;
365
366
if (rasterizer->sprite_coord_mode == PIPE_SPRITE_COORD_LOWER_LEFT) {
367
if (hw)
368
nv30->draw_flags |= NV30_NEW_RASTERIZER;
369
} else
370
if (rasterizer->point_quad_rasterization) {
371
hw |= NV30_3D_POINT_SPRITE_ENABLE;
372
}
373
}
374
375
BEGIN_NV04(push, NV30_3D(POINT_SPRITE), 1);
376
PUSH_DATA (push, hw);
377
}
378
379
struct state_validate {
380
void (*func)(struct nv30_context *);
381
uint32_t mask;
382
};
383
384
static struct state_validate hwtnl_validate_list[] = {
385
{ nv30_validate_fb, NV30_NEW_FRAMEBUFFER },
386
{ nv30_validate_blend, NV30_NEW_BLEND },
387
{ nv30_validate_zsa, NV30_NEW_ZSA },
388
{ nv30_validate_rasterizer, NV30_NEW_RASTERIZER },
389
{ nv30_validate_multisample, NV30_NEW_SAMPLE_MASK | NV30_NEW_BLEND |
390
NV30_NEW_RASTERIZER },
391
{ nv30_validate_blend_colour, NV30_NEW_BLEND_COLOUR |
392
NV30_NEW_FRAMEBUFFER },
393
{ nv30_validate_stencil_ref, NV30_NEW_STENCIL_REF },
394
{ nv30_validate_stipple, NV30_NEW_STIPPLE },
395
{ nv30_validate_scissor, NV30_NEW_SCISSOR | NV30_NEW_RASTERIZER },
396
{ nv30_validate_viewport, NV30_NEW_VIEWPORT },
397
{ nv30_validate_clip, NV30_NEW_CLIP | NV30_NEW_RASTERIZER },
398
{ nv30_fragprog_validate, NV30_NEW_FRAGPROG | NV30_NEW_FRAGCONST },
399
{ nv30_vertprog_validate, NV30_NEW_VERTPROG | NV30_NEW_VERTCONST |
400
NV30_NEW_FRAGPROG | NV30_NEW_RASTERIZER },
401
{ nv30_validate_fragment, NV30_NEW_FRAMEBUFFER | NV30_NEW_FRAGPROG },
402
{ nv30_validate_point_coord, NV30_NEW_RASTERIZER | NV30_NEW_FRAGPROG },
403
{ nv30_fragtex_validate, NV30_NEW_FRAGTEX },
404
{ nv40_verttex_validate, NV30_NEW_VERTTEX },
405
{ nv30_vbo_validate, NV30_NEW_VERTEX | NV30_NEW_ARRAYS },
406
{}
407
};
408
409
#define NV30_SWTNL_MASK (NV30_NEW_VIEWPORT | \
410
NV30_NEW_CLIP | \
411
NV30_NEW_VERTPROG | \
412
NV30_NEW_VERTCONST | \
413
NV30_NEW_VERTTEX | \
414
NV30_NEW_VERTEX | \
415
NV30_NEW_ARRAYS)
416
417
static struct state_validate swtnl_validate_list[] = {
418
{ nv30_validate_fb, NV30_NEW_FRAMEBUFFER },
419
{ nv30_validate_blend, NV30_NEW_BLEND },
420
{ nv30_validate_zsa, NV30_NEW_ZSA },
421
{ nv30_validate_rasterizer, NV30_NEW_RASTERIZER },
422
{ nv30_validate_multisample, NV30_NEW_SAMPLE_MASK | NV30_NEW_BLEND |
423
NV30_NEW_RASTERIZER },
424
{ nv30_validate_blend_colour, NV30_NEW_BLEND_COLOUR |
425
NV30_NEW_FRAMEBUFFER },
426
{ nv30_validate_stencil_ref, NV30_NEW_STENCIL_REF },
427
{ nv30_validate_stipple, NV30_NEW_STIPPLE },
428
{ nv30_validate_scissor, NV30_NEW_SCISSOR | NV30_NEW_RASTERIZER },
429
{ nv30_fragprog_validate, NV30_NEW_FRAGPROG | NV30_NEW_FRAGCONST },
430
{ nv30_validate_fragment, NV30_NEW_FRAMEBUFFER | NV30_NEW_FRAGPROG },
431
{ nv30_fragtex_validate, NV30_NEW_FRAGTEX },
432
{}
433
};
434
435
static void
436
nv30_state_context_switch(struct nv30_context *nv30)
437
{
438
struct nv30_context *prev = nv30->screen->cur_ctx;
439
440
if (prev)
441
nv30->state = prev->state;
442
nv30->dirty = NV30_NEW_ALL;
443
444
if (!nv30->vertex)
445
nv30->dirty &= ~(NV30_NEW_VERTEX | NV30_NEW_ARRAYS);
446
447
if (!nv30->vertprog.program)
448
nv30->dirty &= ~NV30_NEW_VERTPROG;
449
if (!nv30->fragprog.program)
450
nv30->dirty &= ~NV30_NEW_FRAGPROG;
451
452
if (!nv30->blend)
453
nv30->dirty &= ~NV30_NEW_BLEND;
454
if (!nv30->rast)
455
nv30->dirty &= ~NV30_NEW_RASTERIZER;
456
if (!nv30->zsa)
457
nv30->dirty &= ~NV30_NEW_ZSA;
458
459
nv30->screen->cur_ctx = nv30;
460
nv30->base.pushbuf->user_priv = &nv30->bufctx;
461
}
462
463
bool
464
nv30_state_validate(struct nv30_context *nv30, uint32_t mask, bool hwtnl)
465
{
466
struct nouveau_screen *screen = &nv30->screen->base;
467
struct nouveau_pushbuf *push = nv30->base.pushbuf;
468
struct nouveau_bufctx *bctx = nv30->bufctx;
469
struct nouveau_bufref *bref;
470
struct state_validate *validate;
471
472
if (nv30->screen->cur_ctx != nv30)
473
nv30_state_context_switch(nv30);
474
475
if (hwtnl) {
476
nv30->draw_dirty |= nv30->dirty;
477
if (nv30->draw_flags) {
478
nv30->draw_flags &= ~nv30->dirty;
479
if (!nv30->draw_flags)
480
nv30->dirty |= NV30_SWTNL_MASK;
481
}
482
}
483
484
if (!nv30->draw_flags)
485
validate = hwtnl_validate_list;
486
else
487
validate = swtnl_validate_list;
488
489
mask &= nv30->dirty;
490
491
if (mask) {
492
while (validate->func) {
493
if (mask & validate->mask)
494
validate->func(nv30);
495
validate++;
496
}
497
498
nv30->dirty &= ~mask;
499
}
500
501
nouveau_pushbuf_bufctx(push, bctx);
502
if (nouveau_pushbuf_validate(push)) {
503
nouveau_pushbuf_bufctx(push, NULL);
504
return false;
505
}
506
507
/*XXX*/
508
BEGIN_NV04(push, NV30_3D(VTX_CACHE_INVALIDATE_1710), 1);
509
PUSH_DATA (push, 0);
510
if (nv30->screen->eng3d->oclass >= NV40_3D_CLASS) {
511
BEGIN_NV04(push, NV40_3D(TEX_CACHE_CTL), 1);
512
PUSH_DATA (push, 2);
513
BEGIN_NV04(push, NV40_3D(TEX_CACHE_CTL), 1);
514
PUSH_DATA (push, 1);
515
BEGIN_NV04(push, NV30_3D(R1718), 1);
516
PUSH_DATA (push, 0);
517
BEGIN_NV04(push, NV30_3D(R1718), 1);
518
PUSH_DATA (push, 0);
519
BEGIN_NV04(push, NV30_3D(R1718), 1);
520
PUSH_DATA (push, 0);
521
}
522
523
LIST_FOR_EACH_ENTRY(bref, &bctx->current, thead) {
524
struct nv04_resource *res = bref->priv;
525
if (res && res->mm) {
526
nouveau_fence_ref(screen->fence.current, &res->fence);
527
528
if (bref->flags & NOUVEAU_BO_RD)
529
res->status |= NOUVEAU_BUFFER_STATUS_GPU_READING;
530
531
if (bref->flags & NOUVEAU_BO_WR) {
532
nouveau_fence_ref(screen->fence.current, &res->fence_wr);
533
res->status |= NOUVEAU_BUFFER_STATUS_GPU_WRITING;
534
}
535
}
536
}
537
538
return true;
539
}
540
541
void
542
nv30_state_release(struct nv30_context *nv30)
543
{
544
nouveau_pushbuf_bufctx(nv30->base.pushbuf, NULL);
545
}
546
547