+#include "util/u_format.h"
#include "util/u_math.h"
#include "nvc0/nvc0_context.h"
}
#endif
-static INLINE void
+static inline void
nvc0_fb_set_null_rt(struct nouveau_pushbuf *push, unsigned i)
{
BEGIN_NVC0(push, NVC0_3D(RT_ADDRESS_HIGH(i)), 6);
struct pipe_framebuffer_state *fb = &nvc0->framebuffer;
unsigned i, ms;
unsigned ms_mode = NVC0_3D_MULTISAMPLE_MODE_MS1;
- boolean serialize = FALSE;
+ bool serialize = false;
nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_FB);
}
if (res->status & NOUVEAU_BUFFER_STATUS_GPU_READING)
- serialize = TRUE;
+ serialize = true;
res->status |= NOUVEAU_BUFFER_STATUS_GPU_WRITING;
res->status &= ~NOUVEAU_BUFFER_STATUS_GPU_READING;
ms_mode = mt->ms_mode;
if (mt->base.status & NOUVEAU_BUFFER_STATUS_GPU_READING)
- serialize = TRUE;
+ serialize = true;
mt->base.status |= NOUVEAU_BUFFER_STATUS_GPU_WRITING;
mt->base.status &= ~NOUVEAU_BUFFER_STATUS_GPU_READING;
nvc0->viewports_dirty = 0;
}
-static INLINE void
+static inline void
nvc0_upload_uclip_planes(struct nvc0_context *nvc0, unsigned s)
{
struct nouveau_pushbuf *push = nvc0->base.pushbuf;
PUSH_DATAp(push, &nvc0->clip.ucp[0][0], PIPE_MAX_CLIP_PLANES * 4);
}
-static INLINE void
+static inline void
nvc0_check_program_ucps(struct nvc0_context *nvc0,
struct nvc0_program *vp, uint8_t mask)
{
nvc0_vertprog_validate(nvc0);
else
if (likely(vp == nvc0->gmtyprog))
- nvc0_vertprog_validate(nvc0);
+ nvc0_gmtyprog_validate(nvc0);
else
nvc0_tevlprog_validate(nvc0);
}
BEGIN_NVC0(push, NVC0_3D(CB_BIND(s)), 1);
PUSH_DATA (push, (0 << 4) | 1);
}
- nvc0_cb_push(&nvc0->base, bo, NOUVEAU_BO_VRAM,
+ nvc0_cb_bo_push(&nvc0->base, bo, NV_VRAM_DOMAIN(&nvc0->screen->base),
base, nvc0->state.uniform_buffer_bound[s],
0, (size + 3) / 4,
nvc0->constbuf[s][0].u.data);
PUSH_DATA (push, (i << 4) | 1);
BCTX_REFN(nvc0->bufctx_3d, CB(s, i), res, RD);
+
+ nvc0->cb_dirty = 1; /* Force cache flush for UBO. */
+ res->cb_bindings[s] |= 1 << i;
} else {
BEGIN_NVC0(push, NVC0_3D(CB_BIND(s)), 1);
PUSH_DATA (push, (i << 4) | 0);
nvc0_validate_derived_1(struct nvc0_context *nvc0)
{
struct nouveau_pushbuf *push = nvc0->base.pushbuf;
- boolean rasterizer_discard;
+ bool rasterizer_discard;
if (nvc0->rast && nvc0->rast->pipe.rasterizer_discard) {
- rasterizer_discard = TRUE;
+ rasterizer_discard = true;
} else {
- boolean zs = nvc0->zsa &&
+ bool zs = nvc0->zsa &&
(nvc0->zsa->pipe.depth.enabled || nvc0->zsa->pipe.stencil[0].enabled);
rasterizer_discard = !zs &&
(!nvc0->fragprog || !nvc0->fragprog->hdr[18]);
}
}
+/* alpha test is disabled if there are no color RTs, so make sure we have at
+ * least one if alpha test is enabled. Note that this must run after
+ * nvc0_validate_fb, otherwise that will override the RT count setting.
+ */
+static void
+nvc0_validate_derived_2(struct nvc0_context *nvc0)
+{
+ struct nouveau_pushbuf *push = nvc0->base.pushbuf;
+
+ if (nvc0->zsa && nvc0->zsa->pipe.alpha.enabled &&
+ nvc0->framebuffer.nr_cbufs == 0) {
+ nvc0_fb_set_null_rt(push, 0);
+ BEGIN_NVC0(push, NVC0_3D(RT_CONTROL), 1);
+ PUSH_DATA (push, (076543210 << 4) | 1);
+ }
+}
+
+static void
+nvc0_validate_derived_3(struct nvc0_context *nvc0)
+{
+ struct nouveau_pushbuf *push = nvc0->base.pushbuf;
+ struct pipe_framebuffer_state *fb = &nvc0->framebuffer;
+ uint32_t ms = 0;
+
+ if ((!fb->nr_cbufs || !fb->cbufs[0] ||
+ !util_format_is_pure_integer(fb->cbufs[0]->format)) && nvc0->blend) {
+ if (nvc0->blend->pipe.alpha_to_coverage)
+ ms |= NVC0_3D_MULTISAMPLE_CTRL_ALPHA_TO_COVERAGE;
+ if (nvc0->blend->pipe.alpha_to_one)
+ ms |= NVC0_3D_MULTISAMPLE_CTRL_ALPHA_TO_ONE;
+ }
+
+ BEGIN_NVC0(push, NVC0_3D(MULTISAMPLE_CTRL), 1);
+ PUSH_DATA (push, ms);
+}
+
+static void
+nvc0_validate_tess_state(struct nvc0_context *nvc0)
+{
+ struct nouveau_pushbuf *push = nvc0->base.pushbuf;
+
+ BEGIN_NVC0(push, NVC0_3D(TESS_LEVEL_OUTER(0)), 6);
+ PUSH_DATAp(push, nvc0->default_tess_outer, 4);
+ PUSH_DATAp(push, nvc0->default_tess_inner, 2);
+}
+
static void
nvc0_switch_pipe_context(struct nvc0_context *ctx_to)
{
ctx_to->constbuf_dirty[s] = (1 << NVC0_MAX_PIPE_CONSTBUFS) - 1;
}
+ /* Reset tfb as the shader that owns it may have been deleted. */
+ ctx_to->state.tfb = NULL;
+
if (!ctx_to->vertex)
ctx_to->dirty &= ~(NVC0_NEW_VERTEX | NVC0_NEW_ARRAYS);
if (!ctx_to->idxbuf.buffer)
{ nvc0_vertprog_validate, NVC0_NEW_VERTPROG },
{ nvc0_tctlprog_validate, NVC0_NEW_TCTLPROG },
{ nvc0_tevlprog_validate, NVC0_NEW_TEVLPROG },
+ { nvc0_validate_tess_state, NVC0_NEW_TESSFACTOR },
{ nvc0_gmtyprog_validate, NVC0_NEW_GMTYPROG },
- { nvc0_fragprog_validate, NVC0_NEW_FRAGPROG },
+ { nvc0_fragprog_validate, NVC0_NEW_FRAGPROG | NVC0_NEW_RASTERIZER },
{ nvc0_validate_derived_1, NVC0_NEW_FRAGPROG | NVC0_NEW_ZSA |
NVC0_NEW_RASTERIZER },
+ { nvc0_validate_derived_2, NVC0_NEW_ZSA | NVC0_NEW_FRAMEBUFFER },
+ { nvc0_validate_derived_3, NVC0_NEW_BLEND | NVC0_NEW_FRAMEBUFFER },
{ nvc0_validate_clip, NVC0_NEW_CLIP | NVC0_NEW_RASTERIZER |
NVC0_NEW_VERTPROG |
NVC0_NEW_TEVLPROG |
{ nvc0_tfb_validate, NVC0_NEW_TFB_TARGETS | NVC0_NEW_GMTYPROG },
{ nvc0_validate_min_samples, NVC0_NEW_MIN_SAMPLES },
};
-#define validate_list_len (sizeof(validate_list) / sizeof(validate_list[0]))
-boolean
+bool
nvc0_state_validate(struct nvc0_context *nvc0, uint32_t mask, unsigned words)
{
uint32_t state_mask;
state_mask = nvc0->dirty & mask;
if (state_mask) {
- for (i = 0; i < validate_list_len; ++i) {
+ for (i = 0; i < ARRAY_SIZE(validate_list); ++i) {
struct state_validate *validate = &validate_list[i];
if (state_mask & validate->states)
}
nvc0->dirty &= ~state_mask;
- nvc0_bufctx_fence(nvc0, nvc0->bufctx_3d, FALSE);
+ nvc0_bufctx_fence(nvc0, nvc0->bufctx_3d, false);
}
nouveau_pushbuf_bufctx(nvc0->base.pushbuf, nvc0->bufctx_3d);
ret = nouveau_pushbuf_validate(nvc0->base.pushbuf);
if (unlikely(nvc0->state.flushed)) {
- nvc0->state.flushed = FALSE;
- nvc0_bufctx_fence(nvc0, nvc0->bufctx_3d, TRUE);
+ nvc0->state.flushed = false;
+ nvc0_bufctx_fence(nvc0, nvc0->bufctx_3d, true);
}
return !ret;
}