Oops, it should still be a uint32_t. That was a change I forgot to revert.
On Sun, Jul 15, 2018 at 11:38 PM, Ilia Mirkin <imir...@alum.mit.edu> wrote: > On Sun, Jul 15, 2018 at 6:14 PM, Rhys Perry <pendingchao...@gmail.com> wrote: >> To avoid serializing, this has the user constant buffer always be 65536 >> bytes and enabled unless it's required that something else is used for >> constant buffer 0. >> >> Fixes artifacts with at least 0 A.D. and Unigine Valley, Heaven and >> Superposition. >> >> This has only been tested on Pascal but the fix and problem probably >> apply to Maxwell+. >> >> Signed-off-by: Rhys Perry <pendingchao...@gmail.com> >> --- >> src/gallium/drivers/nouveau/nvc0/nvc0_screen.c | 46 >> +++++++++++++++++++--- >> src/gallium/drivers/nouveau/nvc0/nvc0_screen.h | 13 +++++- >> .../drivers/nouveau/nvc0/nvc0_state_validate.c | 37 ++++++++--------- >> 3 files changed, 69 insertions(+), 27 deletions(-) >> >> diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c >> b/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c >> index 37e10dcd07..197b0c1911 100644 >> --- a/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c >> +++ b/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c >> @@ -829,6 +829,40 @@ nvc0_screen_resize_text_area(struct nvc0_screen >> *screen, uint64_t size) >> return 0; >> } >> >> +void >> +nvc0_screen_bind_cb_3d(struct nvc0_screen *screen, bool *can_serialize, >> + int stage, int index, int size, uint64_t addr) >> +{ >> + assert(stage != 5); >> + >> + struct nouveau_pushbuf *push = screen->base.pushbuf; >> + >> + if (screen->base.class_3d >= GM107_3D_CLASS) { >> + struct nvc0_cb_binding *binding = &screen->cb_bindings[stage][index]; >> + >> + // TODO: Better figure out the conditions in which this is needed >> + bool serialize = binding->addr == addr && binding->size != size; >> + if (can_serialize) >> + serialize = serialize && *can_serialize; >> + if (serialize) { >> + IMMED_NVC0(push, NVC0_3D(SERIALIZE), 0); >> + if (can_serialize) >> + *can_serialize = false; >> + } >> + >> + binding->addr = addr; >> + binding->size = size; >> + } >> + >> + if (size >= 0) { >> + BEGIN_NVC0(push, NVC0_3D(CB_SIZE), 3); >> + PUSH_DATA (push, size); >> + PUSH_DATAh(push, addr); >> + PUSH_DATA (push, addr); >> + } >> + IMMED_NVC0(push, NVC0_3D(CB_BIND(stage)), (index << 4) | (size >= 0)); >> +} >> + >> #define FAIL_SCREEN_INIT(str, err) \ >> do { \ >> NOUVEAU_ERR(str, err); \ >> @@ -1272,14 +1306,14 @@ nvc0_screen_create(struct nouveau_device *dev) >> >> /* XXX: Compute and 3D are somehow aliased on Fermi. */ >> for (i = 0; i < 5; ++i) { >> + unsigned j = 0; >> + for (j = 0; j < 16; j++) >> + screen->cb_bindings[i][j].size = -1; >> + >> /* TIC and TSC entries for each unit (nve4+ only) */ >> /* auxiliary constants (6 user clip planes, base instance id) */ >> - BEGIN_NVC0(push, NVC0_3D(CB_SIZE), 3); >> - PUSH_DATA (push, NVC0_CB_AUX_SIZE); >> - PUSH_DATAh(push, screen->uniform_bo->offset + NVC0_CB_AUX_INFO(i)); >> - PUSH_DATA (push, screen->uniform_bo->offset + NVC0_CB_AUX_INFO(i)); >> - BEGIN_NVC0(push, NVC0_3D(CB_BIND(i)), 1); >> - PUSH_DATA (push, (15 << 4) | 1); >> + nvc0_screen_bind_cb_3d(screen, NULL, i, 15, NVC0_CB_AUX_SIZE, >> + screen->uniform_bo->offset + >> NVC0_CB_AUX_INFO(i)); >> if (screen->eng3d->oclass >= NVE4_3D_CLASS) { >> unsigned j; >> BEGIN_1IC0(push, NVC0_3D(CB_POS), 9); >> diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_screen.h >> b/src/gallium/drivers/nouveau/nvc0/nvc0_screen.h >> index efd62a8a41..d088db984a 100644 >> --- a/src/gallium/drivers/nouveau/nvc0/nvc0_screen.h >> +++ b/src/gallium/drivers/nouveau/nvc0/nvc0_screen.h >> @@ -53,12 +53,17 @@ struct nvc0_graph_state { >> uint8_t tls_required; /* bitmask of shader types using l[] */ >> uint8_t clip_enable; >> uint32_t clip_mode; >> - uint32_t uniform_buffer_bound[6]; >> + bool uniform_buffer_bound[6]; >> struct nvc0_transform_feedback_state *tfb; >> bool seamless_cube_map; >> bool post_depth_coverage; >> }; >> >> +struct nvc0_cb_binding { >> + uint64_t addr; >> + int size; >> +}; >> + >> struct nvc0_screen { >> struct nouveau_screen base; >> >> @@ -114,6 +119,9 @@ struct nvc0_screen { >> bool mp_counters_enabled; >> } pm; >> >> + /* only maintained on Maxwell+ */ >> + struct nvc0_cb_binding cb_bindings[5][16]; >> + >> struct nouveau_object *eng3d; /* sqrt(1/2)|kepler> + sqrt(1/2)|fermi> */ >> struct nouveau_object *eng2d; >> struct nouveau_object *m2mf; >> @@ -146,6 +154,9 @@ int nvc0_screen_compute_setup(struct nvc0_screen *, >> struct nouveau_pushbuf *); >> >> int nvc0_screen_resize_text_area(struct nvc0_screen *, uint64_t); >> >> +// 3D Only >> +void nvc0_screen_bind_cb_3d(struct nvc0_screen *, bool *, int, int, int, >> uint64_t); >> + >> static inline void >> nvc0_resource_fence(struct nv04_resource *res, uint32_t flags) >> { >> diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_state_validate.c >> b/src/gallium/drivers/nouveau/nvc0/nvc0_state_validate.c >> index cc18f41c4b..bdfe3c4782 100644 >> --- a/src/gallium/drivers/nouveau/nvc0/nvc0_state_validate.c >> +++ b/src/gallium/drivers/nouveau/nvc0/nvc0_state_validate.c >> @@ -565,9 +565,10 @@ nvc0_validate_rasterizer(struct nvc0_context *nvc0) >> static void >> nvc0_constbufs_validate(struct nvc0_context *nvc0) >> { >> - struct nouveau_pushbuf *push = nvc0->base.pushbuf; >> unsigned s; >> >> + bool can_serialize = true; >> + >> for (s = 0; s < 5; ++s) { >> while (nvc0->constbuf_dirty[s]) { >> int i = ffs(nvc0->constbuf_dirty[s]) - 1; >> @@ -581,14 +582,11 @@ nvc0_constbufs_validate(struct nvc0_context *nvc0) >> assert(nvc0->constbuf[s][0].u.data); >> >> if (nvc0->state.uniform_buffer_bound[s] < size) { > > uniform_buffer_bound is a bool now, so this will ~always be true... > >> - nvc0->state.uniform_buffer_bound[s] = align(size, 0x100); >> - >> - BEGIN_NVC0(push, NVC0_3D(CB_SIZE), 3); >> - PUSH_DATA (push, nvc0->state.uniform_buffer_bound[s]); >> - PUSH_DATAh(push, bo->offset + base); >> - PUSH_DATA (push, bo->offset + base); >> - BEGIN_NVC0(push, NVC0_3D(CB_BIND(s)), 1); >> - PUSH_DATA (push, (0 << 4) | 1); >> + nvc0->state.uniform_buffer_bound[s] = 65536; >> + >> + nvc0_screen_bind_cb_3d(nvc0->screen, &can_serialize, s, i, >> + nvc0->state.uniform_buffer_bound[s], >> + bo->offset + base); >> } >> nvc0_cb_bo_push(&nvc0->base, bo, >> NV_VRAM_DOMAIN(&nvc0->screen->base), >> base, nvc0->state.uniform_buffer_bound[s], >> @@ -598,23 +596,20 @@ nvc0_constbufs_validate(struct nvc0_context *nvc0) >> struct nv04_resource *res = >> nv04_resource(nvc0->constbuf[s][i].u.buf); >> if (res) { >> - BEGIN_NVC0(push, NVC0_3D(CB_SIZE), 3); >> - PUSH_DATA (push, nvc0->constbuf[s][i].size); >> - PUSH_DATAh(push, res->address + nvc0->constbuf[s][i].offset); >> - PUSH_DATA (push, res->address + nvc0->constbuf[s][i].offset); >> - BEGIN_NVC0(push, NVC0_3D(CB_BIND(s)), 1); >> - PUSH_DATA (push, (i << 4) | 1); >> + nvc0_screen_bind_cb_3d(nvc0->screen, &can_serialize, s, i, >> + nvc0->constbuf[s][i].size, >> + res->address + >> nvc0->constbuf[s][i].offset); >> >> BCTX_REFN(nvc0->bufctx_3d, 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); >> + >> + if (i == 0) >> + nvc0->state.uniform_buffer_bound[s] = 0; >> + } else if (i != 0) { >> + nvc0_screen_bind_cb_3d(nvc0->screen, &can_serialize, s, i, >> -1, 0); >> } >> - if (i == 0) >> - nvc0->state.uniform_buffer_bound[s] = 0; >> } >> } >> } >> @@ -721,6 +716,8 @@ nvc0_validate_driverconst(struct nvc0_context *nvc0) >> PUSH_DATA (push, screen->uniform_bo->offset + NVC0_CB_AUX_INFO(i)); >> BEGIN_NVC0(push, NVC0_3D(CB_BIND(i)), 1); >> PUSH_DATA (push, (15 << 4) | 1); >> + nvc0_screen_bind_cb_3d(screen, NULL, i, 15, NVC0_CB_AUX_SIZE, >> + screen->uniform_bo->offset + >> NVC0_CB_AUX_INFO(i)); >> } >> >> nvc0->dirty_cp |= NVC0_NEW_CP_DRIVERCONST; >> -- >> 2.14.4 >> _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev