[Mesa-dev] [PATCH] nvc0: serialize before updating some constant buffer bindings
Rhys Perry
pendingchaos02 at gmail.com
Sun Jul 15 22:40:48 UTC 2018
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 <imirkin at alum.mit.edu> wrote:
> On Sun, Jul 15, 2018 at 6:14 PM, Rhys Perry <pendingchaos02 at 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 <pendingchaos02 at 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
>>
More information about the mesa-dev
mailing list