mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-01-06 15:20:17 +01:00
nv50: reinstate dedicated constbuf push path
This was disabled due to occasionally incorrect behavior when trying to
upload data. It later became apparent that nvc0 also had a similar but
slightly different issue, which was resolved in commit e50c01d5. This
takes the same logic as nvc0 and applies it to nv50 (which has somewhat
different interfaces).
Unfortunately I did not note down precisely what was broken with UBOs
when removing the support from nv50, but I've tested a bunch of local
traces, and none of them appear to regress. This should hopefully
improve performance when UBOs are used, but this was not directly
verified.
Signed-off-by: Ilia Mirkin <imirkin@alum.mit.edu>
Reviewed-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
This commit is contained in:
parent
f47845596b
commit
3f48548a6f
5 changed files with 51 additions and 30 deletions
|
|
@ -310,14 +310,7 @@ nv50_create(struct pipe_screen *pscreen, void *priv, unsigned ctxflags)
|
|||
nv50->base.screen = &screen->base;
|
||||
nv50->base.copy_data = nv50_m2mf_copy_linear;
|
||||
nv50->base.push_data = nv50_sifc_linear_u8;
|
||||
/* FIXME: Make it possible to use this again. The problem is that there is
|
||||
* some clever logic in the card that allows for multiple renders to happen
|
||||
* when there are only constbuf changes. However that relies on the
|
||||
* constbuf updates happening to the right constbuf slots. Currently
|
||||
* implementation just makes it go through a separate slot which doesn't
|
||||
* properly update the right constbuf data.
|
||||
nv50->base.push_cb = nv50_cb_push;
|
||||
*/
|
||||
|
||||
nv50->screen = screen;
|
||||
pipe->screen = pscreen;
|
||||
|
|
|
|||
|
|
@ -281,8 +281,7 @@ nv50_m2mf_copy_linear(struct nouveau_context *pipe,
|
|||
unsigned size);
|
||||
void
|
||||
nv50_cb_push(struct nouveau_context *nv,
|
||||
struct nouveau_bo *bo, unsigned domain,
|
||||
unsigned base, unsigned size,
|
||||
struct nv04_resource *res,
|
||||
unsigned offset, unsigned words, const uint32_t *data);
|
||||
|
||||
/* nv50_vbo.c */
|
||||
|
|
|
|||
|
|
@ -99,6 +99,7 @@ nv50_constbufs_validate(struct nv50_context *nv50)
|
|||
BCTX_REFN(nv50->bufctx_3d, 3D_CB(s, i), res, RD);
|
||||
|
||||
nv50->cb_dirty = 1; /* Force cache flush for UBO. */
|
||||
res->cb_bindings[s] |= 1 << i;
|
||||
} else {
|
||||
BEGIN_NV04(push, NV50_3D(SET_PROGRAM_CB), 1);
|
||||
PUSH_DATA (push, (i << 8) | p | 0);
|
||||
|
|
|
|||
|
|
@ -856,9 +856,10 @@ nv50_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index,
|
|||
if (nv50->constbuf[s][i].user)
|
||||
nv50->constbuf[s][i].u.buf = NULL;
|
||||
else
|
||||
if (nv50->constbuf[s][i].u.buf)
|
||||
if (nv50->constbuf[s][i].u.buf) {
|
||||
nouveau_bufctx_reset(nv50->bufctx_3d, NV50_BIND_3D_CB(s, i));
|
||||
|
||||
nv04_resource(nv50->constbuf[s][i].u.buf)->cb_bindings[s] &= ~(1 << i);
|
||||
}
|
||||
pipe_resource_reference(&nv50->constbuf[s][i].u.buf, res);
|
||||
|
||||
nv50->constbuf[s][i].user = (cb && cb->user_buffer) ? true : false;
|
||||
|
|
|
|||
|
|
@ -371,32 +371,24 @@ nv50_miptree_transfer_unmap(struct pipe_context *pctx,
|
|||
FREE(tx);
|
||||
}
|
||||
|
||||
void
|
||||
nv50_cb_push(struct nouveau_context *nv,
|
||||
struct nouveau_bo *bo, unsigned domain,
|
||||
unsigned base, unsigned size,
|
||||
unsigned offset, unsigned words, const uint32_t *data)
|
||||
static void
|
||||
nv50_cb_bo_push(struct nouveau_context *nv,
|
||||
struct nouveau_bo *bo, unsigned domain,
|
||||
unsigned bufid,
|
||||
unsigned offset, unsigned words,
|
||||
const uint32_t *data)
|
||||
{
|
||||
struct nouveau_pushbuf *push = nv->pushbuf;
|
||||
struct nouveau_bufctx *bctx = nv50_context(&nv->pipe)->bufctx;
|
||||
|
||||
assert(!(offset & 3));
|
||||
size = align(size, 0x100);
|
||||
|
||||
nouveau_bufctx_refn(bctx, 0, bo, NOUVEAU_BO_WR | domain);
|
||||
nouveau_pushbuf_bufctx(push, bctx);
|
||||
nouveau_pushbuf_validate(push);
|
||||
|
||||
while (words) {
|
||||
unsigned nr = MIN2(words, NV04_PFIFO_MAX_PACKET_LEN);
|
||||
|
||||
PUSH_SPACE(push, nr + 7);
|
||||
BEGIN_NV04(push, NV50_3D(CB_DEF_ADDRESS_HIGH), 3);
|
||||
PUSH_DATAh(push, bo->offset + base);
|
||||
PUSH_DATA (push, bo->offset + base);
|
||||
PUSH_DATA (push, (NV50_CB_TMP << 16) | (size & 0xffff));
|
||||
PUSH_SPACE(push, nr + 3);
|
||||
PUSH_REFN (push, bo, NOUVEAU_BO_WR | domain);
|
||||
BEGIN_NV04(push, NV50_3D(CB_ADDR), 1);
|
||||
PUSH_DATA (push, (offset << 6) | NV50_CB_TMP);
|
||||
PUSH_DATA (push, (offset << 6) | bufid);
|
||||
BEGIN_NI04(push, NV50_3D(CB_DATA(0)), nr);
|
||||
PUSH_DATAp(push, data, nr);
|
||||
|
||||
|
|
@ -404,6 +396,41 @@ nv50_cb_push(struct nouveau_context *nv,
|
|||
data += nr;
|
||||
offset += nr * 4;
|
||||
}
|
||||
|
||||
nouveau_bufctx_reset(bctx, 0);
|
||||
}
|
||||
|
||||
void
|
||||
nv50_cb_push(struct nouveau_context *nv,
|
||||
struct nv04_resource *res,
|
||||
unsigned offset, unsigned words, const uint32_t *data)
|
||||
{
|
||||
struct nv50_context *nv50 = nv50_context(&nv->pipe);
|
||||
struct nv50_constbuf *cb = NULL;
|
||||
int s, bufid;
|
||||
/* Go through all the constbuf binding points of this buffer and try to
|
||||
* find one which contains the region to be updated.
|
||||
*/
|
||||
/* XXX compute? */
|
||||
for (s = 0; s < 3 && !cb; s++) {
|
||||
uint16_t bindings = res->cb_bindings[s];
|
||||
while (bindings) {
|
||||
int i = ffs(bindings) - 1;
|
||||
uint32_t cb_offset = nv50->constbuf[s][i].offset;
|
||||
|
||||
bindings &= ~(1 << i);
|
||||
if (cb_offset <= offset &&
|
||||
cb_offset + nv50->constbuf[s][i].size >= offset + words * 4) {
|
||||
cb = &nv50->constbuf[s][i];
|
||||
bufid = s * 16 + i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (cb) {
|
||||
nv50_cb_bo_push(nv, res->bo, res->domain,
|
||||
bufid, offset - cb->offset, words, data);
|
||||
} else {
|
||||
nv->push_data(nv, res->bo, res->offset + offset, res->domain,
|
||||
words * 4, data);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue