2 #include "util/u_math.h"
4 #include "nvc0_context.h"
7 nvc0_validate_zcull(struct nvc0_context
*nvc0
)
9 struct nouveau_pushbuf
*push
= nvc0
->base
.pushbuf
;
10 struct pipe_framebuffer_state
*fb
= &nvc0
->framebuffer
;
11 struct nv50_surface
*sf
= nv50_surface(fb
->zsbuf
);
12 struct nv50_miptree
*mt
= nv50_miptree(sf
->base
.texture
);
13 struct nouveau_bo
*bo
= mt
->base
.bo
;
15 uint32_t offset
= align(mt
->total_size
, 1 << 17);
16 unsigned width
, height
;
18 assert(mt
->base
.base
.depth0
== 1 && mt
->base
.base
.array_size
< 2);
20 size
= mt
->total_size
* 2;
22 height
= align(fb
->height
, 32);
23 width
= fb
->width
% 224;
25 width
= fb
->width
+ (224 - width
);
29 BEGIN_NVC0(push
, NVC0_3D(ZCULL_REGION
), 1);
31 BEGIN_NVC0(push
, NVC0_3D(ZCULL_ADDRESS_HIGH
), 2);
32 PUSH_DATAh(push
, bo
->offset
+ offset
);
33 PUSH_DATA (push
, bo
->offset
+ offset
);
35 BEGIN_NVC0(push
, NVC0_3D(ZCULL_LIMIT_HIGH
), 2);
36 PUSH_DATAh(push
, bo
->offset
+ offset
);
37 PUSH_DATA (push
, bo
->offset
+ offset
);
38 BEGIN_NVC0(push
, SUBC_3D(0x07e0), 2);
39 PUSH_DATA (push
, size
);
40 PUSH_DATA (push
, size
>> 16);
41 BEGIN_NVC0(push
, SUBC_3D(0x15c8), 1); /* bits 0x3 */
43 BEGIN_NVC0(push
, NVC0_3D(ZCULL_WIDTH
), 4);
44 PUSH_DATA (push
, width
);
45 PUSH_DATA (push
, height
);
48 BEGIN_NVC0(push
, NVC0_3D(ZCULL_WINDOW_OFFSET_X
), 2);
51 BEGIN_NVC0(push
, NVC0_3D(ZCULL_INVALIDATE
), 1);
56 nvc0_validate_fb(struct nvc0_context
*nvc0
)
58 struct nouveau_pushbuf
*push
= nvc0
->base
.pushbuf
;
59 struct pipe_framebuffer_state
*fb
= &nvc0
->framebuffer
;
61 unsigned ms_mode
= NVC0_3D_MULTISAMPLE_MODE_MS1
;
62 boolean serialize
= FALSE
;
64 nouveau_bufctx_reset(nvc0
->bufctx_3d
, NVC0_BIND_FB
);
66 BEGIN_NVC0(push
, NVC0_3D(RT_CONTROL
), 1);
67 PUSH_DATA (push
, (076543210 << 4) | fb
->nr_cbufs
);
68 BEGIN_NVC0(push
, NVC0_3D(SCREEN_SCISSOR_HORIZ
), 2);
69 PUSH_DATA (push
, fb
->width
<< 16);
70 PUSH_DATA (push
, fb
->height
<< 16);
72 for (i
= 0; i
< fb
->nr_cbufs
; ++i
) {
73 struct nv50_surface
*sf
= nv50_surface(fb
->cbufs
[i
]);
74 struct nv04_resource
*res
= nv04_resource(sf
->base
.texture
);
75 struct nouveau_bo
*bo
= res
->bo
;
77 BEGIN_NVC0(push
, NVC0_3D(RT_ADDRESS_HIGH(i
)), 9);
78 PUSH_DATAh(push
, res
->address
+ sf
->offset
);
79 PUSH_DATA (push
, res
->address
+ sf
->offset
);
80 if (likely(nouveau_bo_memtype(bo
))) {
81 struct nv50_miptree
*mt
= nv50_miptree(sf
->base
.texture
);
83 assert(sf
->base
.texture
->target
!= PIPE_BUFFER
);
85 PUSH_DATA(push
, sf
->width
);
86 PUSH_DATA(push
, sf
->height
);
87 PUSH_DATA(push
, nvc0_format_table
[sf
->base
.format
].rt
);
88 PUSH_DATA(push
, (mt
->layout_3d
<< 16) |
89 mt
->level
[sf
->base
.u
.tex
.level
].tile_mode
);
90 PUSH_DATA(push
, sf
->base
.u
.tex
.first_layer
+ sf
->depth
);
91 PUSH_DATA(push
, mt
->layer_stride
>> 2);
92 PUSH_DATA(push
, sf
->base
.u
.tex
.first_layer
);
94 ms_mode
= mt
->ms_mode
;
96 if (res
->base
.target
== PIPE_BUFFER
) {
97 PUSH_DATA(push
, 262144);
100 PUSH_DATA(push
, nv50_miptree(sf
->base
.texture
)->level
[0].pitch
);
101 PUSH_DATA(push
, sf
->height
);
103 PUSH_DATA(push
, nvc0_format_table
[sf
->base
.format
].rt
);
104 PUSH_DATA(push
, 1 << 12);
109 nvc0_resource_fence(res
, NOUVEAU_BO_WR
);
114 if (res
->status
& NOUVEAU_BUFFER_STATUS_GPU_READING
)
116 res
->status
|= NOUVEAU_BUFFER_STATUS_GPU_WRITING
;
117 res
->status
&= ~NOUVEAU_BUFFER_STATUS_GPU_READING
;
119 /* only register for writing, otherwise we'd always serialize here */
120 BCTX_REFN(nvc0
->bufctx_3d
, FB
, res
, WR
);
124 struct nv50_miptree
*mt
= nv50_miptree(fb
->zsbuf
->texture
);
125 struct nv50_surface
*sf
= nv50_surface(fb
->zsbuf
);
126 int unk
= mt
->base
.base
.target
== PIPE_TEXTURE_2D
;
128 BEGIN_NVC0(push
, NVC0_3D(ZETA_ADDRESS_HIGH
), 5);
129 PUSH_DATAh(push
, mt
->base
.address
+ sf
->offset
);
130 PUSH_DATA (push
, mt
->base
.address
+ sf
->offset
);
131 PUSH_DATA (push
, nvc0_format_table
[fb
->zsbuf
->format
].rt
);
132 PUSH_DATA (push
, mt
->level
[sf
->base
.u
.tex
.level
].tile_mode
);
133 PUSH_DATA (push
, mt
->layer_stride
>> 2);
134 BEGIN_NVC0(push
, NVC0_3D(ZETA_ENABLE
), 1);
136 BEGIN_NVC0(push
, NVC0_3D(ZETA_HORIZ
), 3);
137 PUSH_DATA (push
, sf
->width
);
138 PUSH_DATA (push
, sf
->height
);
139 PUSH_DATA (push
, (unk
<< 16) |
140 (sf
->base
.u
.tex
.first_layer
+ sf
->depth
));
141 BEGIN_NVC0(push
, NVC0_3D(ZETA_BASE_LAYER
), 1);
142 PUSH_DATA (push
, sf
->base
.u
.tex
.first_layer
);
144 ms_mode
= mt
->ms_mode
;
146 if (mt
->base
.status
& NOUVEAU_BUFFER_STATUS_GPU_READING
)
148 mt
->base
.status
|= NOUVEAU_BUFFER_STATUS_GPU_WRITING
;
149 mt
->base
.status
&= ~NOUVEAU_BUFFER_STATUS_GPU_READING
;
151 BCTX_REFN(nvc0
->bufctx_3d
, FB
, &mt
->base
, WR
);
153 BEGIN_NVC0(push
, NVC0_3D(ZETA_ENABLE
), 1);
157 IMMED_NVC0(push
, NVC0_3D(MULTISAMPLE_MODE
), ms_mode
);
160 IMMED_NVC0(push
, NVC0_3D(SERIALIZE
), 0);
164 nvc0_validate_blend_colour(struct nvc0_context
*nvc0
)
166 struct nouveau_pushbuf
*push
= nvc0
->base
.pushbuf
;
168 BEGIN_NVC0(push
, NVC0_3D(BLEND_COLOR(0)), 4);
169 PUSH_DATAf(push
, nvc0
->blend_colour
.color
[0]);
170 PUSH_DATAf(push
, nvc0
->blend_colour
.color
[1]);
171 PUSH_DATAf(push
, nvc0
->blend_colour
.color
[2]);
172 PUSH_DATAf(push
, nvc0
->blend_colour
.color
[3]);
176 nvc0_validate_stencil_ref(struct nvc0_context
*nvc0
)
178 struct nouveau_pushbuf
*push
= nvc0
->base
.pushbuf
;
179 const ubyte
*ref
= &nvc0
->stencil_ref
.ref_value
[0];
181 IMMED_NVC0(push
, NVC0_3D(STENCIL_FRONT_FUNC_REF
), ref
[0]);
182 IMMED_NVC0(push
, NVC0_3D(STENCIL_BACK_FUNC_REF
), ref
[1]);
186 nvc0_validate_stipple(struct nvc0_context
*nvc0
)
188 struct nouveau_pushbuf
*push
= nvc0
->base
.pushbuf
;
191 BEGIN_NVC0(push
, NVC0_3D(POLYGON_STIPPLE_PATTERN(0)), 32);
192 for (i
= 0; i
< 32; ++i
)
193 PUSH_DATA(push
, util_bswap32(nvc0
->stipple
.stipple
[i
]));
197 nvc0_validate_scissor(struct nvc0_context
*nvc0
)
199 struct nouveau_pushbuf
*push
= nvc0
->base
.pushbuf
;
200 struct pipe_scissor_state
*s
= &nvc0
->scissor
;
202 if (!(nvc0
->dirty
& NVC0_NEW_SCISSOR
) &&
203 nvc0
->rast
->pipe
.scissor
== nvc0
->state
.scissor
)
205 nvc0
->state
.scissor
= nvc0
->rast
->pipe
.scissor
;
207 BEGIN_NVC0(push
, NVC0_3D(SCISSOR_HORIZ(0)), 2);
208 if (nvc0
->rast
->pipe
.scissor
) {
209 PUSH_DATA(push
, (s
->maxx
<< 16) | s
->minx
);
210 PUSH_DATA(push
, (s
->maxy
<< 16) | s
->miny
);
212 PUSH_DATA(push
, (0xffff << 16) | 0);
213 PUSH_DATA(push
, (0xffff << 16) | 0);
218 nvc0_validate_viewport(struct nvc0_context
*nvc0
)
220 struct nouveau_pushbuf
*push
= nvc0
->base
.pushbuf
;
221 struct pipe_viewport_state
*vp
= &nvc0
->viewport
;
225 BEGIN_NVC0(push
, NVC0_3D(VIEWPORT_TRANSLATE_X(0)), 3);
226 PUSH_DATAf(push
, vp
->translate
[0]);
227 PUSH_DATAf(push
, vp
->translate
[1]);
228 PUSH_DATAf(push
, vp
->translate
[2]);
229 BEGIN_NVC0(push
, NVC0_3D(VIEWPORT_SCALE_X(0)), 3);
230 PUSH_DATAf(push
, vp
->scale
[0]);
231 PUSH_DATAf(push
, vp
->scale
[1]);
232 PUSH_DATAf(push
, vp
->scale
[2]);
234 /* now set the viewport rectangle to viewport dimensions for clipping */
236 x
= util_iround(MAX2(0.0f
, vp
->translate
[0] - fabsf(vp
->scale
[0])));
237 y
= util_iround(MAX2(0.0f
, vp
->translate
[1] - fabsf(vp
->scale
[1])));
238 w
= util_iround(vp
->translate
[0] + fabsf(vp
->scale
[0])) - x
;
239 h
= util_iround(vp
->translate
[1] + fabsf(vp
->scale
[1])) - y
;
241 zmin
= vp
->translate
[2] - fabsf(vp
->scale
[2]);
242 zmax
= vp
->translate
[2] + fabsf(vp
->scale
[2]);
244 BEGIN_NVC0(push
, NVC0_3D(VIEWPORT_HORIZ(0)), 2);
245 PUSH_DATA (push
, (w
<< 16) | x
);
246 PUSH_DATA (push
, (h
<< 16) | y
);
247 BEGIN_NVC0(push
, NVC0_3D(DEPTH_RANGE_NEAR(0)), 2);
248 PUSH_DATAf(push
, zmin
);
249 PUSH_DATAf(push
, zmax
);
253 nvc0_upload_uclip_planes(struct nvc0_context
*nvc0
)
255 struct nouveau_pushbuf
*push
= nvc0
->base
.pushbuf
;
256 struct nouveau_bo
*bo
= nvc0
->screen
->uniforms
;
258 BEGIN_NVC0(push
, NVC0_3D(CB_SIZE
), 3);
259 PUSH_DATA (push
, 256);
260 PUSH_DATAh(push
, bo
->offset
+ (5 << 16));
261 PUSH_DATA (push
, bo
->offset
+ (5 << 16));
262 BEGIN_1IC0(push
, NVC0_3D(CB_POS
), PIPE_MAX_CLIP_PLANES
* 4 + 1);
264 PUSH_DATAp(push
, &nvc0
->clip
.ucp
[0][0], PIPE_MAX_CLIP_PLANES
* 4);
268 nvc0_check_program_ucps(struct nvc0_context
*nvc0
,
269 struct nvc0_program
*vp
, uint8_t mask
)
271 const unsigned n
= util_logbase2(mask
) + 1;
273 if (vp
->vp
.num_ucps
>= n
)
275 nvc0_program_destroy(nvc0
, vp
);
278 if (likely(vp
== nvc0
->vertprog
))
279 nvc0_vertprog_validate(nvc0
);
281 if (likely(vp
== nvc0
->gmtyprog
))
282 nvc0_vertprog_validate(nvc0
);
284 nvc0_tevlprog_validate(nvc0
);
288 nvc0_validate_clip(struct nvc0_context
*nvc0
)
290 struct nouveau_pushbuf
*push
= nvc0
->base
.pushbuf
;
291 struct nvc0_program
*vp
;
292 uint8_t clip_enable
= nvc0
->rast
->pipe
.clip_plane_enable
;
294 if (nvc0
->dirty
& NVC0_NEW_CLIP
)
295 nvc0_upload_uclip_planes(nvc0
);
304 if (clip_enable
&& vp
->vp
.num_ucps
< PIPE_MAX_CLIP_PLANES
)
305 nvc0_check_program_ucps(nvc0
, vp
, clip_enable
);
307 clip_enable
&= vp
->vp
.clip_enable
;
309 if (nvc0
->state
.clip_enable
!= clip_enable
) {
310 nvc0
->state
.clip_enable
= clip_enable
;
311 IMMED_NVC0(push
, NVC0_3D(CLIP_DISTANCE_ENABLE
), clip_enable
);
313 if (nvc0
->state
.clip_mode
!= vp
->vp
.clip_mode
) {
314 nvc0
->state
.clip_mode
= vp
->vp
.clip_mode
;
315 BEGIN_NVC0(push
, NVC0_3D(CLIP_DISTANCE_MODE
), 1);
316 PUSH_DATA (push
, vp
->vp
.clip_mode
);
321 nvc0_validate_blend(struct nvc0_context
*nvc0
)
323 struct nouveau_pushbuf
*push
= nvc0
->base
.pushbuf
;
325 PUSH_SPACE(push
, nvc0
->blend
->size
);
326 PUSH_DATAp(push
, nvc0
->blend
->state
, nvc0
->blend
->size
);
330 nvc0_validate_zsa(struct nvc0_context
*nvc0
)
332 struct nouveau_pushbuf
*push
= nvc0
->base
.pushbuf
;
334 PUSH_SPACE(push
, nvc0
->zsa
->size
);
335 PUSH_DATAp(push
, nvc0
->zsa
->state
, nvc0
->zsa
->size
);
339 nvc0_validate_rasterizer(struct nvc0_context
*nvc0
)
341 struct nouveau_pushbuf
*push
= nvc0
->base
.pushbuf
;
343 PUSH_SPACE(push
, nvc0
->rast
->size
);
344 PUSH_DATAp(push
, nvc0
->rast
->state
, nvc0
->rast
->size
);
348 nvc0_constbufs_validate(struct nvc0_context
*nvc0
)
350 struct nouveau_pushbuf
*push
= nvc0
->base
.pushbuf
;
351 struct nouveau_bo
*bo
;
354 for (s
= 0; s
< 5; ++s
) {
355 struct nv04_resource
*res
;
358 while (nvc0
->constbuf_dirty
[s
]) {
361 boolean rebind
= TRUE
;
363 i
= ffs(nvc0
->constbuf_dirty
[s
]) - 1;
364 nvc0
->constbuf_dirty
[s
] &= ~(1 << i
);
366 res
= nv04_resource(nvc0
->constbuf
[s
][i
]);
368 BEGIN_NVC0(push
, NVC0_3D(CB_BIND(s
)), 1);
369 PUSH_DATA (push
, (i
<< 4) | 0);
371 nvc0
->state
.uniform_buffer_bound
[s
] = 0;
375 if (!nouveau_resource_mapped_by_gpu(&res
->base
)) {
376 if (i
== 0 && (res
->status
& NOUVEAU_BUFFER_STATUS_USER_MEMORY
)) {
378 bo
= nvc0
->screen
->uniforms
;
380 if (nvc0
->state
.uniform_buffer_bound
[s
] >= res
->base
.width0
)
383 nvc0
->state
.uniform_buffer_bound
[s
] =
384 align(res
->base
.width0
, 0x100);
386 words
= res
->base
.width0
/ 4;
388 nouveau_buffer_migrate(&nvc0
->base
, res
, NOUVEAU_BO_VRAM
);
396 nvc0
->state
.uniform_buffer_bound
[s
] = 0;
399 if (bo
!= nvc0
->screen
->uniforms
)
400 BCTX_REFN(nvc0
->bufctx_3d
, CB(s
, i
), res
, RD
);
403 BEGIN_NVC0(push
, NVC0_3D(CB_SIZE
), 3);
404 PUSH_DATA (push
, align(res
->base
.width0
, 0x100));
405 PUSH_DATAh(push
, bo
->offset
+ base
);
406 PUSH_DATA (push
, bo
->offset
+ base
);
407 BEGIN_NVC0(push
, NVC0_3D(CB_BIND(s
)), 1);
408 PUSH_DATA (push
, (i
<< 4) | 1);
412 nvc0_cb_push(&nvc0
->base
,
413 bo
, NOUVEAU_BO_VRAM
, base
, res
->base
.width0
,
414 0, words
, (const uint32_t *)res
->data
);
420 nvc0_validate_sample_mask(struct nvc0_context
*nvc0
)
422 struct nouveau_pushbuf
*push
= nvc0
->base
.pushbuf
;
426 nvc0
->sample_mask
& 0xffff,
427 nvc0
->sample_mask
& 0xffff,
428 nvc0
->sample_mask
& 0xffff,
429 nvc0
->sample_mask
& 0xffff
432 BEGIN_NVC0(push
, NVC0_3D(MSAA_MASK(0)), 4);
433 PUSH_DATA (push
, mask
[0]);
434 PUSH_DATA (push
, mask
[1]);
435 PUSH_DATA (push
, mask
[2]);
436 PUSH_DATA (push
, mask
[3]);
437 BEGIN_NVC0(push
, NVC0_3D(SAMPLE_SHADING
), 1);
438 PUSH_DATA (push
, 0x01);
442 nvc0_validate_derived_1(struct nvc0_context
*nvc0
)
444 struct nouveau_pushbuf
*push
= nvc0
->base
.pushbuf
;
446 boolean rasterizer_discard
;
448 early_z
= nvc0
->fragprog
->fp
.early_z
&& !nvc0
->zsa
->pipe
.alpha
.enabled
;
450 if (early_z
!= nvc0
->state
.early_z
) {
451 nvc0
->state
.early_z
= early_z
;
452 IMMED_NVC0(push
, NVC0_3D(EARLY_FRAGMENT_TESTS
), early_z
);
455 rasterizer_discard
= (!nvc0
->fragprog
|| !nvc0
->fragprog
->hdr
[18]) &&
456 !nvc0
->zsa
->pipe
.depth
.enabled
&& !nvc0
->zsa
->pipe
.stencil
[0].enabled
;
457 rasterizer_discard
= rasterizer_discard
||
458 nvc0
->rast
->pipe
.rasterizer_discard
;
460 if (rasterizer_discard
!= nvc0
->state
.rasterizer_discard
) {
461 nvc0
->state
.rasterizer_discard
= rasterizer_discard
;
462 IMMED_NVC0(push
, NVC0_3D(RASTERIZE_ENABLE
), !rasterizer_discard
);
467 nvc0_switch_pipe_context(struct nvc0_context
*ctx_to
)
469 struct nvc0_context
*ctx_from
= ctx_to
->screen
->cur_ctx
;
472 ctx_to
->state
= ctx_from
->state
;
477 ctx_to
->dirty
&= ~(NVC0_NEW_VERTEX
| NVC0_NEW_ARRAYS
);
479 if (!ctx_to
->vertprog
)
480 ctx_to
->dirty
&= ~NVC0_NEW_VERTPROG
;
481 if (!ctx_to
->fragprog
)
482 ctx_to
->dirty
&= ~NVC0_NEW_FRAGPROG
;
485 ctx_to
->dirty
&= ~NVC0_NEW_BLEND
;
487 ctx_to
->dirty
&= ~(NVC0_NEW_RASTERIZER
| NVC0_NEW_SCISSOR
);
489 ctx_to
->dirty
&= ~NVC0_NEW_ZSA
;
491 ctx_to
->screen
->cur_ctx
= ctx_to
;
494 static struct state_validate
{
495 void (*func
)(struct nvc0_context
*);
497 } validate_list
[] = {
498 { nvc0_validate_fb
, NVC0_NEW_FRAMEBUFFER
},
499 { nvc0_validate_blend
, NVC0_NEW_BLEND
},
500 { nvc0_validate_zsa
, NVC0_NEW_ZSA
},
501 { nvc0_validate_sample_mask
, NVC0_NEW_SAMPLE_MASK
},
502 { nvc0_validate_rasterizer
, NVC0_NEW_RASTERIZER
},
503 { nvc0_validate_blend_colour
, NVC0_NEW_BLEND_COLOUR
},
504 { nvc0_validate_stencil_ref
, NVC0_NEW_STENCIL_REF
},
505 { nvc0_validate_stipple
, NVC0_NEW_STIPPLE
},
506 { nvc0_validate_scissor
, NVC0_NEW_SCISSOR
| NVC0_NEW_RASTERIZER
},
507 { nvc0_validate_viewport
, NVC0_NEW_VIEWPORT
},
508 { nvc0_vertprog_validate
, NVC0_NEW_VERTPROG
},
509 { nvc0_tctlprog_validate
, NVC0_NEW_TCTLPROG
},
510 { nvc0_tevlprog_validate
, NVC0_NEW_TEVLPROG
},
511 { nvc0_gmtyprog_validate
, NVC0_NEW_GMTYPROG
},
512 { nvc0_fragprog_validate
, NVC0_NEW_FRAGPROG
},
513 { nvc0_validate_derived_1
, NVC0_NEW_FRAGPROG
| NVC0_NEW_ZSA
|
514 NVC0_NEW_RASTERIZER
},
515 { nvc0_validate_clip
, NVC0_NEW_CLIP
| NVC0_NEW_RASTERIZER
|
519 { nvc0_constbufs_validate
, NVC0_NEW_CONSTBUF
},
520 { nvc0_validate_textures
, NVC0_NEW_TEXTURES
},
521 { nvc0_validate_samplers
, NVC0_NEW_SAMPLERS
},
522 { nvc0_vertex_arrays_validate
, NVC0_NEW_VERTEX
| NVC0_NEW_ARRAYS
},
523 { nvc0_idxbuf_validate
, NVC0_NEW_IDXBUF
},
524 { nvc0_tfb_validate
, NVC0_NEW_TFB_TARGETS
| NVC0_NEW_GMTYPROG
}
526 #define validate_list_len (sizeof(validate_list) / sizeof(validate_list[0]))
529 nvc0_state_validate(struct nvc0_context
*nvc0
, uint32_t mask
, unsigned words
)
535 if (nvc0
->screen
->cur_ctx
!= nvc0
)
536 nvc0_switch_pipe_context(nvc0
);
538 state_mask
= nvc0
->dirty
& mask
;
541 for (i
= 0; i
< validate_list_len
; ++i
) {
542 struct state_validate
*validate
= &validate_list
[i
];
544 if (state_mask
& validate
->states
)
545 validate
->func(nvc0
);
547 nvc0
->dirty
&= ~state_mask
;
549 nvc0_bufctx_fence(nvc0
, nvc0
->bufctx_3d
, FALSE
);
552 nouveau_pushbuf_bufctx(nvc0
->base
.pushbuf
, nvc0
->bufctx_3d
);
553 ret
= nouveau_pushbuf_validate(nvc0
->base
.pushbuf
);
557 if (unlikely(nvc0
->state
.flushed
))
558 nvc0_bufctx_fence(nvc0
, nvc0
->bufctx_3d
, TRUE
);