boolean emit_common_func = cso->rt[0].blend_enable;
uint32_t ms;
- if (nv50_context(pipe)->screen->tesla->grclass >= NVA3_3D) {
+ if (nv50_context(pipe)->screen->tesla->oclass >= NVA3_3D_CLASS) {
SB_BEGIN_3D(so, BLEND_INDEPENDENT, 1);
SB_DATA (so, cso->independent_blend_enable);
}
emit_common_func = TRUE;
}
- if (nv50_context(pipe)->screen->tesla->grclass >= NVA3_3D) {
+ if (nv50_context(pipe)->screen->tesla->oclass >= NVA3_3D_CLASS) {
emit_common_func = FALSE;
for (i = 0; i < 8; ++i) {
const struct pipe_rasterizer_state *cso)
{
struct nv50_rasterizer_stateobj *so;
+ uint32_t reg;
so = CALLOC_STRUCT(nv50_rasterizer_stateobj);
if (!so)
SB_DATA (so, fui(cso->offset_scale));
SB_BEGIN_3D(so, POLYGON_OFFSET_UNITS, 1);
SB_DATA (so, fui(cso->offset_units * 2.0f));
+ SB_BEGIN_3D(so, POLYGON_OFFSET_CLAMP, 1);
+ SB_DATA (so, fui(cso->offset_clamp));
}
+ if (cso->depth_clip) {
+ reg = 0;
+ } else {
+ reg =
+ NV50_3D_VIEW_VOLUME_CLIP_CTRL_DEPTH_CLAMP_NEAR |
+ NV50_3D_VIEW_VOLUME_CLIP_CTRL_DEPTH_CLAMP_FAR |
+ NV50_3D_VIEW_VOLUME_CLIP_CTRL_UNK12_UNK1;
+ }
+#ifndef NV50_SCISSORS_CLIPPING
+ reg |=
+ NV50_3D_VIEW_VOLUME_CLIP_CTRL_UNK7 |
+ NV50_3D_VIEW_VOLUME_CLIP_CTRL_UNK12_UNK1;
+#endif
+ SB_BEGIN_3D(so, VIEW_VOLUME_CLIP_CTRL, 1);
+ SB_DATA (so, reg);
+
assert(so->size <= (sizeof(so->state) / sizeof(so->state[0])));
return (void *)so;
}
(nv50_tsc_wrap_mode(cso->wrap_t) << 3) |
(nv50_tsc_wrap_mode(cso->wrap_r) << 6));
+ if (nouveau_screen(pipe->screen)->class_3d >= NVE4_3D_CLASS) {
+ if (cso->seamless_cube_map)
+ so->tsc[1] |= NVE4_TSC_1_CUBE_SEAMLESS;
+ if (!cso->normalized_coords)
+ so->tsc[1] |= NVE4_TSC_1_FORCE_NONNORMALIZED_COORDS;
+ }
+
switch (cso->mag_img_filter) {
case PIPE_TEX_FILTER_LINEAR:
so->tsc[1] |= NV50_TSC_1_MAGF_LINEAR;
nv50->num_textures[s] = nr;
- nv50_bufctx_reset(nv50, NV50_BUFCTX_TEXTURES);
+ nouveau_bufctx_reset(nv50->bufctx_3d, NV50_BIND_TEXTURES);
nv50->dirty |= NV50_NEW_TEXTURES;
}
prog->type = type;
prog->pipe.tokens = tgsi_dup_tokens(cso->tokens);
+ if (cso->stream_output.num_outputs)
+ prog->pipe.stream_output = cso->stream_output;
+
return (void *)prog;
}
static void
nv50_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index,
- struct pipe_resource *res)
+ struct pipe_constant_buffer *cb)
{
struct nv50_context *nv50 = nv50_context(pipe);
+ struct pipe_resource *res = cb ? cb->buffer : NULL;
- if (nv50->constbuf[shader][index])
- nv50_bufctx_del_resident(nv50, NV50_BUFCTX_CONSTANT,
- nv04_resource(nv50->constbuf[shader][index]));
+ if (cb && cb->user_buffer) {
+ res = nouveau_user_buffer_create(pipe->screen, cb->user_buffer,
+ cb->buffer_size,
+ PIPE_BIND_CONSTANT_BUFFER);
+ }
pipe_resource_reference(&nv50->constbuf[shader][index], res);
nv50->constbuf_dirty[shader] |= 1 << index;
+ if (res)
+ nv50->constbuf_valid[shader] |= 1 << index;
+ else
+ nv50->constbuf_valid[shader] &= ~(1 << index);
+
+ nouveau_bufctx_reset(nv50->bufctx_3d, NV50_BIND_CB(shader, index));
nv50->dirty |= NV50_NEW_CONSTBUF;
+
+ if (cb && cb->user_buffer) {
+ pipe_resource_reference(&res, NULL);
+ }
}
/* =============================================================================
const struct pipe_clip_state *clip)
{
struct nv50_context *nv50 = nv50_context(pipe);
- const unsigned size = clip->nr * sizeof(clip->ucp[0]);
-
- memcpy(&nv50->clip.ucp[0][0], &clip->ucp[0][0], size);
- nv50->clip.nr = clip->nr;
- nv50->clip.depth_clamp = clip->depth_clamp;
+ memcpy(nv50->clip.ucp, clip->ucp, sizeof(clip->ucp));
nv50->dirty |= NV50_NEW_CLIP;
}
const struct pipe_framebuffer_state *fb)
{
struct nv50_context *nv50 = nv50_context(pipe);
+ unsigned i;
+
+ nouveau_bufctx_reset(nv50->bufctx_3d, NV50_BIND_FB);
+
+ for (i = 0; i < fb->nr_cbufs; ++i)
+ pipe_surface_reference(&nv50->framebuffer.cbufs[i], fb->cbufs[i]);
+ for (; i < nv50->framebuffer.nr_cbufs; ++i)
+ pipe_surface_reference(&nv50->framebuffer.cbufs[i], NULL);
+
+ nv50->framebuffer.nr_cbufs = fb->nr_cbufs;
+
+ nv50->framebuffer.width = fb->width;
+ nv50->framebuffer.height = fb->height;
+
+ pipe_surface_reference(&nv50->framebuffer.zsbuf, fb->zsbuf);
- nv50->framebuffer = *fb;
nv50->dirty |= NV50_NEW_FRAMEBUFFER;
}
memcpy(nv50->vtxbuf, vb, sizeof(*vb) * count);
nv50->num_vtxbufs = count;
- nv50_bufctx_reset(nv50, NV50_BUFCTX_VERTEX);
+ nouveau_bufctx_reset(nv50->bufctx_3d, NV50_BIND_VERTEX);
nv50->dirty |= NV50_NEW_ARRAYS;
}
{
struct nv50_context *nv50 = nv50_context(pipe);
- if (ib) {
- pipe_resource_reference(&nv50->idxbuf.buffer, ib->buffer);
+ if (nv50->idxbuf.buffer)
+ nouveau_bufctx_reset(nv50->bufctx_3d, NV50_BIND_INDEX);
- memcpy(&nv50->idxbuf, ib, sizeof(nv50->idxbuf));
+ if (ib && ib->buffer) {
+ pipe_resource_reference(&nv50->idxbuf.buffer, ib->buffer);
+ nv50->idxbuf.offset = ib->offset;
+ nv50->idxbuf.index_size = ib->index_size;
+ if (nouveau_resource_mapped_by_gpu(ib->buffer))
+ BCTX_REFN(nv50->bufctx_3d, INDEX, nv04_resource(ib->buffer), RD);
} else {
pipe_resource_reference(&nv50->idxbuf.buffer, NULL);
}
nv50->dirty |= NV50_NEW_VERTEX;
}
+static struct pipe_stream_output_target *
+nv50_so_target_create(struct pipe_context *pipe,
+ struct pipe_resource *res,
+ unsigned offset, unsigned size)
+{
+ struct nv50_so_target *targ = MALLOC_STRUCT(nv50_so_target);
+ if (!targ)
+ return NULL;
+
+ if (nouveau_context(pipe)->screen->class_3d >= NVA0_3D_CLASS) {
+ targ->pq = pipe->create_query(pipe,
+ NVA0_QUERY_STREAM_OUTPUT_BUFFER_OFFSET);
+ if (!targ->pq) {
+ FREE(targ);
+ return NULL;
+ }
+ } else {
+ targ->pq = NULL;
+ }
+ targ->clean = TRUE;
+
+ targ->pipe.buffer_size = size;
+ targ->pipe.buffer_offset = offset;
+ targ->pipe.context = pipe;
+ targ->pipe.buffer = NULL;
+ pipe_resource_reference(&targ->pipe.buffer, res);
+ pipe_reference_init(&targ->pipe.reference, 1);
+
+ return &targ->pipe;
+}
+
+static void
+nv50_so_target_destroy(struct pipe_context *pipe,
+ struct pipe_stream_output_target *ptarg)
+{
+ struct nv50_so_target *targ = nv50_so_target(ptarg);
+ if (targ->pq)
+ pipe->destroy_query(pipe, targ->pq);
+ FREE(targ);
+}
+
+static void
+nv50_set_stream_output_targets(struct pipe_context *pipe,
+ unsigned num_targets,
+ struct pipe_stream_output_target **targets,
+ unsigned append_mask)
+{
+ struct nv50_context *nv50 = nv50_context(pipe);
+ unsigned i;
+ boolean serialize = TRUE;
+ const boolean can_resume = nv50->screen->base.class_3d >= NVA0_3D_CLASS;
+
+ assert(num_targets <= 4);
+
+ for (i = 0; i < num_targets; ++i) {
+ const boolean changed = nv50->so_target[i] != targets[i];
+ if (!changed && (append_mask & (1 << i)))
+ continue;
+ nv50->so_targets_dirty |= 1 << i;
+
+ if (can_resume && changed && nv50->so_target[i]) {
+ nva0_so_target_save_offset(pipe, nv50->so_target[i], i, serialize);
+ serialize = FALSE;
+ }
+
+ if (targets[i] && !(append_mask & (1 << i)))
+ nv50_so_target(targets[i])->clean = TRUE;
+
+ pipe_so_target_reference(&nv50->so_target[i], targets[i]);
+ }
+ for (; i < nv50->num_so_targets; ++i) {
+ if (can_resume && nv50->so_target[i]) {
+ nva0_so_target_save_offset(pipe, nv50->so_target[i], i, serialize);
+ serialize = FALSE;
+ }
+ pipe_so_target_reference(&nv50->so_target[i], NULL);
+ nv50->so_targets_dirty |= 1 << i;
+ }
+ nv50->num_so_targets = num_targets;
+
+ if (nv50->so_targets_dirty)
+ nv50->dirty |= NV50_NEW_STRMOUT;
+}
+
void
nv50_init_state_functions(struct nv50_context *nv50)
{
pipe->set_vertex_buffers = nv50_set_vertex_buffers;
pipe->set_index_buffer = nv50_set_index_buffer;
- pipe->redefine_user_buffer = u_default_redefine_user_buffer;
+ pipe->create_stream_output_target = nv50_so_target_create;
+ pipe->stream_output_target_destroy = nv50_so_target_destroy;
+ pipe->set_stream_output_targets = nv50_set_stream_output_targets;
}
-