#include "nouveau/nouveau_gldefs.h"
+/* Caveats:
+ * ! pipe_sampler_state.normalized_coords is ignored - rectangle textures will
+ * use non-normalized coordinates, everything else won't
+ * (The relevant bit is in the TIC entry and not the TSC entry.)
+ *
+ * ! pipe_sampler_state.seamless_cube_map is ignored - seamless filtering is
+ * always activated on NVA0 +
+ * (Give me the global bit, otherwise it's not worth the CPU work.)
+ *
+ * ! pipe_sampler_state.border_color is not swizzled according to the texture
+ * swizzle in pipe_sampler_view
+ * (This will be ugly with indirect independent texture/sampler access,
+ * we'd have to emulate the logic in the shader. GL doesn't have that,
+ * D3D doesn't have swizzle, if we knew what we were implementing we'd be
+ * good.)
+ *
+ * ! pipe_rasterizer_state.line_last_pixel is ignored - it is never drawn
+ *
+ * ! pipe_rasterizer_state.flatshade_first also applies to QUADS
+ * (There's a GL query for that, forcing an exception is just ridiculous.)
+ *
+ * ! pipe_rasterizer_state.gl_rasterization_rules is ignored - pixel centers
+ * are always at half integer coordinates and the top-left rule applies
+ * (There does not seem to be a hardware switch for this.)
+ *
+ * ! pipe_rasterizer_state.sprite_coord_enable is masked with 0xff on NVC0
+ * (The hardware only has 8 slots meant for TexCoord and we have to assign
+ * in advance to maintain elegant separate shader objects.)
+ */
+
static INLINE uint32_t
nv50_colormask(unsigned mask)
{
{
struct nv50_blend_stateobj *so = CALLOC_STRUCT(nv50_blend_stateobj);
int i;
- boolean blend_enabled = cso->rt[0].blend_enable;
+ boolean emit_common_func = cso->rt[0].blend_enable;
+ uint32_t ms;
+
+ if (nv50_context(pipe)->screen->tesla->oclass >= NVA3_3D_CLASS) {
+ SB_BEGIN_3D(so, BLEND_INDEPENDENT, 1);
+ SB_DATA (so, cso->independent_blend_enable);
+ }
so->pipe = *cso;
- SB_BEGIN_3D(so, BLEND_ENABLE(0), 8);
+ SB_BEGIN_3D(so, COLOR_MASK_COMMON, 1);
+ SB_DATA (so, !cso->independent_blend_enable);
+
+ SB_BEGIN_3D(so, BLEND_ENABLE_COMMON, 1);
+ SB_DATA (so, !cso->independent_blend_enable);
+
if (cso->independent_blend_enable) {
+ SB_BEGIN_3D(so, BLEND_ENABLE(0), 8);
for (i = 0; i < 8; ++i) {
SB_DATA(so, cso->rt[i].blend_enable);
if (cso->rt[i].blend_enable)
- blend_enabled = TRUE;
+ emit_common_func = TRUE;
+ }
+
+ if (nv50_context(pipe)->screen->tesla->oclass >= NVA3_3D_CLASS) {
+ emit_common_func = FALSE;
+
+ for (i = 0; i < 8; ++i) {
+ if (!cso->rt[i].blend_enable)
+ continue;
+ SB_BEGIN_3D_(so, NVA3_3D_IBLEND_EQUATION_RGB(i), 6);
+ SB_DATA (so, nvgl_blend_eqn(cso->rt[i].rgb_func));
+ SB_DATA (so, nv50_blend_fac(cso->rt[i].rgb_src_factor));
+ SB_DATA (so, nv50_blend_fac(cso->rt[i].rgb_dst_factor));
+ SB_DATA (so, nvgl_blend_eqn(cso->rt[i].alpha_func));
+ SB_DATA (so, nv50_blend_fac(cso->rt[i].alpha_src_factor));
+ SB_DATA (so, nv50_blend_fac(cso->rt[i].alpha_dst_factor));
+ }
}
} else {
- for (i = 0; i < 8; ++i)
- SB_DATA(so, blend_enabled);
+ SB_BEGIN_3D(so, BLEND_ENABLE(0), 1);
+ SB_DATA (so, cso->rt[0].blend_enable);
}
- if (blend_enabled) {
+ if (emit_common_func) {
SB_BEGIN_3D(so, BLEND_EQUATION_RGB, 5);
SB_DATA (so, nvgl_blend_eqn(cso->rt[0].rgb_func));
SB_DATA (so, nv50_blend_fac(cso->rt[0].rgb_src_factor));
SB_DATA (so, 0);
}
- SB_BEGIN_3D(so, COLOR_MASK(0), 8);
if (cso->independent_blend_enable) {
+ SB_BEGIN_3D(so, COLOR_MASK(0), 8);
for (i = 0; i < 8; ++i)
SB_DATA(so, nv50_colormask(cso->rt[i].colormask));
} else {
- uint32_t cmask = nv50_colormask(cso->rt[0].colormask);
- for (i = 0; i < 8; ++i)
- SB_DATA(so, cmask);
+ SB_BEGIN_3D(so, COLOR_MASK(0), 1);
+ SB_DATA (so, nv50_colormask(cso->rt[0].colormask));
}
- assert(so->size < (sizeof(so->state) / sizeof(so->state[0])));
+ ms = 0;
+ if (cso->alpha_to_coverage)
+ ms |= NV50_3D_MULTISAMPLE_CTRL_ALPHA_TO_COVERAGE;
+ if (cso->alpha_to_one)
+ ms |= NV50_3D_MULTISAMPLE_CTRL_ALPHA_TO_ONE;
+
+ SB_BEGIN_3D(so, MULTISAMPLE_CTRL, 1);
+ SB_DATA (so, ms);
+
+ assert(so->size <= (sizeof(so->state) / sizeof(so->state[0])));
return so;
}
FREE(hwcso);
}
+/* NOTE: ignoring line_last_pixel, using FALSE (set on screen init) */
static void *
nv50_rasterizer_state_create(struct pipe_context *pipe,
const struct pipe_rasterizer_state *cso)
{
struct nv50_rasterizer_stateobj *so;
+ uint32_t reg;
so = CALLOC_STRUCT(nv50_rasterizer_stateobj);
if (!so)
SB_BEGIN_3D(so, VERTEX_TWO_SIDE_ENABLE, 1);
SB_DATA (so, cso->light_twoside);
+ SB_BEGIN_3D(so, FRAG_COLOR_CLAMP_EN, 1);
+ SB_DATA (so, cso->clamp_fragment_color ? 0x11111111 : 0x00000000);
+
+ SB_BEGIN_3D(so, MULTISAMPLE_ENABLE, 1);
+ SB_DATA (so, cso->multisample);
+
SB_BEGIN_3D(so, LINE_WIDTH, 1);
SB_DATA (so, fui(cso->line_width));
SB_BEGIN_3D(so, LINE_SMOOTH_ENABLE, 1);
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));
}
- assert(so->size < (sizeof(so->state) / sizeof(so->state[0])));
+ 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;
}
SB_DATA (so, 0);
}
- assert(so->size < (sizeof(so->state) / sizeof(so->state[0])));
+ assert(so->size <= (sizeof(so->state) / sizeof(so->state[0])));
return (void *)so;
}
}
}
-static void *
+void *
nv50_sampler_state_create(struct pipe_context *pipe,
const struct pipe_sampler_state *cso)
{
so->tsc[2] |=
(((int)(f[1] * 256.0f) & 0xfff) << 12) | ((int)(f[0] * 256.0f) & 0xfff);
- so->tsc[4] = fui(cso->border_color[0]);
- so->tsc[5] = fui(cso->border_color[1]);
- so->tsc[6] = fui(cso->border_color[2]);
- so->tsc[7] = fui(cso->border_color[3]);
+ so->tsc[4] = fui(cso->border_color.f[0]);
+ so->tsc[5] = fui(cso->border_color.f[1]);
+ so->tsc[6] = fui(cso->border_color.f[2]);
+ so->tsc[7] = fui(cso->border_color.f[3]);
return (void *)so;
}
{
unsigned s, i;
- for (s = 0; s < 5; ++s)
+ for (s = 0; s < 3; ++s)
for (i = 0; i < nv50_context(pipe)->num_samplers[s]; ++i)
if (nv50_context(pipe)->samplers[s][i] == hwcso)
nv50_context(pipe)->samplers[s][i] = NULL;
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;
}
{
struct nv50_context *nv50 = nv50_context(pipe);
- if (nv50->constbuf[shader][index])
- nv50_bufctx_del_resident(nv50, NV50_BUFCTX_CONSTANT,
- nv04_resource(nv50->constbuf[shader][index]));
-
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;
}
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)
- memcpy(&nv50->idxbuf, ib, sizeof(nv50->idxbuf));
- else
- nv50->idxbuf.buffer = NULL;
+ if (nv50->idxbuf.buffer)
+ nouveau_bufctx_reset(nv50->bufctx_3d, NV50_BIND_INDEX);
+
+ 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);
+ }
}
static void
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;
}