From fcb28682101dfa127486373411043d5d97a0ff8f Mon Sep 17 00:00:00 2001 From: Christoph Bumiller Date: Wed, 16 May 2012 20:52:41 +0200 Subject: nv50,nvc0: handle user constbufs without wrapping them in a resource --- src/gallium/drivers/nv50/nv50_context.c | 5 +- src/gallium/drivers/nv50/nv50_context.h | 17 +++- src/gallium/drivers/nv50/nv50_screen.c | 7 +- src/gallium/drivers/nv50/nv50_screen.h | 3 + src/gallium/drivers/nv50/nv50_shader_state.c | 109 ++++++++++++------------- src/gallium/drivers/nv50/nv50_state.c | 42 ++++++---- src/gallium/drivers/nv50/nv50_stateobj.h | 10 +++ src/gallium/drivers/nvc0/nvc0_context.c | 5 +- src/gallium/drivers/nvc0/nvc0_context.h | 19 ++++- src/gallium/drivers/nvc0/nvc0_screen.c | 2 +- src/gallium/drivers/nvc0/nvc0_screen.h | 3 + src/gallium/drivers/nvc0/nvc0_state.c | 45 +++++----- src/gallium/drivers/nvc0/nvc0_state_validate.c | 89 ++++++++------------ src/gallium/drivers/nvc0/nvc0_stateobj.h | 10 +++ 14 files changed, 201 insertions(+), 165 deletions(-) (limited to 'src') diff --git a/src/gallium/drivers/nv50/nv50_context.c b/src/gallium/drivers/nv50/nv50_context.c index 558fe0b3684..1e6bbaf8eb8 100644 --- a/src/gallium/drivers/nv50/nv50_context.c +++ b/src/gallium/drivers/nv50/nv50_context.c @@ -86,8 +86,9 @@ nv50_context_unreference_resources(struct nv50_context *nv50) for (i = 0; i < nv50->num_textures[s]; ++i) pipe_sampler_view_reference(&nv50->textures[s][i], NULL); - for (i = 0; i < 16; ++i) - pipe_resource_reference(&nv50->constbuf[s][i], NULL); + for (i = 0; i < NV50_MAX_PIPE_CONSTBUFS; ++i) + if (!nv50->constbuf[s][i].user) + pipe_resource_reference(&nv50->constbuf[s][i].u.buf, NULL); } } diff --git a/src/gallium/drivers/nv50/nv50_context.h b/src/gallium/drivers/nv50/nv50_context.h index 44a0ba0f561..8f5363b3684 100644 --- a/src/gallium/drivers/nv50/nv50_context.h +++ b/src/gallium/drivers/nv50/nv50_context.h @@ -90,6 +90,7 @@ struct nv50_context { uint32_t semantic_color; uint32_t semantic_psize; int32_t index_bias; + boolean uniform_buffer_bound[3]; boolean prim_restart; boolean point_sprite; boolean rt_serialize; @@ -113,7 +114,7 @@ struct nv50_context { struct nv50_program *gmtyprog; struct nv50_program *fragprog; - struct pipe_resource *constbuf[3][16]; + struct nv50_constbuf constbuf[3][NV50_MAX_PIPE_CONSTBUFS]; uint16_t constbuf_dirty[3]; uint16_t constbuf_valid[3]; @@ -163,6 +164,20 @@ nv50_context_screen(struct nv50_context *nv50) return nv50_screen(&nv50->base.screen->base); } +/* return index used in nv50_context arrays for a specific shader type */ +static INLINE unsigned +nv50_context_shader_stage(unsigned pipe) +{ + switch (pipe) { + case PIPE_SHADER_VERTEX: return 0; + case PIPE_SHADER_FRAGMENT: return 1; + case PIPE_SHADER_GEOMETRY: return 2; + case PIPE_SHADER_COMPUTE: return 3; + default: + assert(!"invalid/unhandled shader type"); + return 0; + } +} /* nv50_context.c */ struct pipe_context *nv50_create(struct pipe_screen *, void *); diff --git a/src/gallium/drivers/nv50/nv50_screen.c b/src/gallium/drivers/nv50/nv50_screen.c index c96e028b2a2..9f356ff6556 100644 --- a/src/gallium/drivers/nv50/nv50_screen.c +++ b/src/gallium/drivers/nv50/nv50_screen.c @@ -196,7 +196,7 @@ nv50_screen_get_shader_param(struct pipe_screen *pscreen, unsigned shader, case PIPE_SHADER_CAP_MAX_CONSTS: return 65536 / 16; case PIPE_SHADER_CAP_MAX_CONST_BUFFERS: - return 14; + return NV50_MAX_PIPE_CONSTBUFS; case PIPE_SHADER_CAP_MAX_ADDRS: return 1; case PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR: @@ -437,10 +437,7 @@ nv50_screen_init_hwctx(struct nv50_screen *screen, unsigned tls_space) PUSH_DATA (push, screen->uniforms->offset + (3 << 16)); PUSH_DATA (push, (NV50_CB_AUX << 16) | 0x0200); - BEGIN_NI04(push, NV50_3D(SET_PROGRAM_CB), 6); - PUSH_DATA (push, (NV50_CB_PVP << 12) | 0x001); - PUSH_DATA (push, (NV50_CB_PGP << 12) | 0x021); - PUSH_DATA (push, (NV50_CB_PFP << 12) | 0x031); + BEGIN_NI04(push, NV50_3D(SET_PROGRAM_CB), 3); PUSH_DATA (push, (NV50_CB_AUX << 12) | 0xf01); PUSH_DATA (push, (NV50_CB_AUX << 12) | 0xf21); PUSH_DATA (push, (NV50_CB_AUX << 12) | 0xf31); diff --git a/src/gallium/drivers/nv50/nv50_screen.h b/src/gallium/drivers/nv50/nv50_screen.h index 9eae08ea1d3..4292f7fc9a6 100644 --- a/src/gallium/drivers/nv50/nv50_screen.h +++ b/src/gallium/drivers/nv50/nv50_screen.h @@ -12,6 +12,9 @@ #define NV50_TIC_MAX_ENTRIES 2048 #define NV50_TSC_MAX_ENTRIES 2048 +/* doesn't count reserved slots (for auxiliary constants, immediates, etc.) */ +#define NV50_MAX_PIPE_CONSTBUFS 14 + struct nv50_context; #define NV50_CODE_BO_SIZE_LOG2 19 diff --git a/src/gallium/drivers/nv50/nv50_shader_state.c b/src/gallium/drivers/nv50/nv50_shader_state.c index d070f07bbbc..df6764b216f 100644 --- a/src/gallium/drivers/nv50/nv50_shader_state.c +++ b/src/gallium/drivers/nv50/nv50_shader_state.c @@ -35,9 +35,7 @@ nv50_constbufs_validate(struct nv50_context *nv50) unsigned s; for (s = 0; s < 3; ++s) { - struct nv04_resource *res; - int i; - unsigned p, b; + unsigned p; if (s == PIPE_SHADER_FRAGMENT) p = NV50_3D_SET_PROGRAM_CB_PROGRAM_FRAGMENT; @@ -48,68 +46,63 @@ nv50_constbufs_validate(struct nv50_context *nv50) p = NV50_3D_SET_PROGRAM_CB_PROGRAM_VERTEX; while (nv50->constbuf_dirty[s]) { - struct nouveau_bo *bo; - unsigned start = 0; - unsigned words = 0; - - i = ffs(nv50->constbuf_dirty[s]) - 1; + const int i = ffs(nv50->constbuf_dirty[s]) - 1; nv50->constbuf_dirty[s] &= ~(1 << i); - res = nv04_resource(nv50->constbuf[s][i]); - if (!res) { - if (i != 0) { + if (nv50->constbuf[s][i].user) { + const unsigned b = NV50_CB_PVP + s; + unsigned start = 0; + unsigned words = nv50->constbuf[s][0].size / 4; + if (i) { + NOUVEAU_ERR("user constbufs only supported in slot 0\n"); + continue; + } + if (!nv50->state.uniform_buffer_bound[s]) { + nv50->state.uniform_buffer_bound[s] = TRUE; BEGIN_NV04(push, NV50_3D(SET_PROGRAM_CB), 1); - PUSH_DATA (push, (i << 8) | p | 0); + PUSH_DATA (push, (b << 12) | (i << 8) | p | 1); + } + while (words) { + unsigned nr; + + if (!PUSH_SPACE(push, 16)) + break; + nr = PUSH_AVAIL(push); + assert(nr >= 16); + nr = MIN2(MIN2(nr - 3, words), NV04_PFIFO_MAX_PACKET_LEN); + + BEGIN_NV04(push, NV50_3D(CB_ADDR), 1); + PUSH_DATA (push, (start << 8) | b); + BEGIN_NI04(push, NV50_3D(CB_DATA(0)), nr); + PUSH_DATAp(push, &nv50->constbuf[s][0].u.data[start * 4], nr); + + start += nr; + words -= nr; } - continue; - } - - if (i == 0) { - b = NV50_CB_PVP + s; - - /* always upload GL uniforms through CB DATA */ - bo = nv50->screen->uniforms; - words = res->base.width0 / 4; } else { - b = s * 16 + i; - - assert(0); - - if (!nouveau_resource_mapped_by_gpu(&res->base)) { - nouveau_buffer_migrate(&nv50->base, res, NOUVEAU_BO_VRAM); + struct nv04_resource *res = + nv04_resource(nv50->constbuf[s][i].u.buf); + if (res) { + /* TODO: allocate persistent bindings */ + const unsigned b = s * 16 + i; + + assert(nouveau_resource_mapped_by_gpu(&res->base)); + + BEGIN_NV04(push, NV50_3D(CB_DEF_ADDRESS_HIGH), 3); + PUSH_DATAh(push, res->address + nv50->constbuf[s][i].offset); + PUSH_DATA (push, res->address + nv50->constbuf[s][i].offset); + PUSH_DATA (push, (b << 16) | + (nv50->constbuf[s][i].size & 0xffff)); + BEGIN_NV04(push, NV50_3D(SET_PROGRAM_CB), 1); + PUSH_DATA (push, (b << 12) | (i << 8) | p | 1); - BEGIN_NV04(push, NV50_3D(CODE_CB_FLUSH), 1); - PUSH_DATA (push, 0); + BCTX_REFN(nv50->bufctx_3d, CB(s, i), res, RD); + } else { + BEGIN_NV04(push, NV50_3D(SET_PROGRAM_CB), 1); + PUSH_DATA (push, (i << 8) | p | 0); } - BEGIN_NV04(push, NV50_3D(CB_DEF_ADDRESS_HIGH), 3); - PUSH_DATAh(push, res->address); - PUSH_DATA (push, res->address); - PUSH_DATA (push, (b << 16) | (res->base.width0 & 0xffff)); - BEGIN_NV04(push, NV50_3D(SET_PROGRAM_CB), 1); - PUSH_DATA (push, (b << 12) | (i << 8) | p | 1); - - bo = res->bo; - } - - if (bo != nv50->screen->uniforms) - BCTX_REFN(nv50->bufctx_3d, CB(s, i), res, RD); - - while (words) { - unsigned nr; - - if (!PUSH_SPACE(push, 16)) - break; - nr = PUSH_AVAIL(push); - assert(nr >= 16); - nr = MIN2(MIN2(nr - 3, words), NV04_PFIFO_MAX_PACKET_LEN); - - BEGIN_NV04(push, NV50_3D(CB_ADDR), 1); - PUSH_DATA (push, (start << 8) | b); - BEGIN_NI04(push, NV50_3D(CB_DATA(0)), nr); - PUSH_DATAp(push, &res->data[start * 4], nr); - - start += nr; - words -= nr; + if (i == 0) + nv50->state.uniform_buffer_bound[s] = FALSE; } } } diff --git a/src/gallium/drivers/nv50/nv50_state.c b/src/gallium/drivers/nv50/nv50_state.c index 7f840e2b42e..eea3ffd5270 100644 --- a/src/gallium/drivers/nv50/nv50_state.c +++ b/src/gallium/drivers/nv50/nv50_state.c @@ -751,28 +751,36 @@ nv50_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index, { struct nv50_context *nv50 = nv50_context(pipe); struct pipe_resource *res = cb ? cb->buffer : NULL; + const unsigned s = nv50_context_shader_stage(shader); + const unsigned i = index; - if (cb && cb->user_buffer) { - res = nouveau_user_buffer_create(pipe->screen, cb->user_buffer, - cb->buffer_size, - PIPE_BIND_CONSTANT_BUFFER); - } - - pipe_resource_reference(&nv50->constbuf[shader][index], res); + if (shader == PIPE_SHADER_COMPUTE) + return; - nv50->constbuf_dirty[shader] |= 1 << index; - if (res) - nv50->constbuf_valid[shader] |= 1 << index; + if (nv50->constbuf[s][i].user) + nv50->constbuf[s][i].u.buf = NULL; else - nv50->constbuf_valid[shader] &= ~(1 << index); - - nouveau_bufctx_reset(nv50->bufctx_3d, NV50_BIND_CB(shader, index)); + if (nv50->constbuf[s][i].u.buf) + nouveau_bufctx_reset(nv50->bufctx_3d, NV50_BIND_CB(s, i)); + + pipe_resource_reference(&nv50->constbuf[s][i].u.buf, res); + + nv50->constbuf[s][i].user = (cb && cb->user_buffer) ? TRUE : FALSE; + if (nv50->constbuf[s][i].user) { + nv50->constbuf[s][i].u.data = cb->user_buffer; + nv50->constbuf[s][i].size = cb->buffer_size; + nv50->constbuf_valid[s] |= 1 << i; + } else + if (res) { + nv50->constbuf[s][i].offset = cb->buffer_offset; + nv50->constbuf[s][i].size = align(cb->buffer_size, 0x100); + nv50->constbuf_valid[s] |= 1 << i; + } else { + nv50->constbuf_valid[s] &= ~(1 << i); + } + nv50->constbuf_dirty[s] |= 1 << i; nv50->dirty |= NV50_NEW_CONSTBUF; - - if (cb && cb->user_buffer) { - pipe_resource_reference(&res, NULL); - } } /* ============================================================================= diff --git a/src/gallium/drivers/nv50/nv50_stateobj.h b/src/gallium/drivers/nv50/nv50_stateobj.h index 8a9260c937e..eec146552b4 100644 --- a/src/gallium/drivers/nv50/nv50_stateobj.h +++ b/src/gallium/drivers/nv50/nv50_stateobj.h @@ -34,6 +34,16 @@ struct nv50_zsa_stateobj { uint32_t state[29]; }; +struct nv50_constbuf { + union { + struct pipe_resource *buf; + const uint8_t *data; + } u; + uint32_t size; /* max 65536 */ + uint16_t offset; + boolean user; /* should only be TRUE if u.data is valid and non-NULL */ +}; + struct nv50_vertex_element { struct pipe_vertex_element pipe; uint32_t state; diff --git a/src/gallium/drivers/nvc0/nvc0_context.c b/src/gallium/drivers/nvc0/nvc0_context.c index b0ab5bdc504..f93081465bd 100644 --- a/src/gallium/drivers/nvc0/nvc0_context.c +++ b/src/gallium/drivers/nvc0/nvc0_context.c @@ -72,8 +72,9 @@ nvc0_context_unreference_resources(struct nvc0_context *nvc0) for (i = 0; i < nvc0->num_textures[s]; ++i) pipe_sampler_view_reference(&nvc0->textures[s][i], NULL); - for (i = 0; i < 16; ++i) - pipe_resource_reference(&nvc0->constbuf[s][i], NULL); + for (i = 0; i < NVC0_MAX_PIPE_CONSTBUFS; ++i) + if (!nvc0->constbuf[s][i].user) + pipe_resource_reference(&nvc0->constbuf[s][i].u.buf, NULL); } for (i = 0; i < nvc0->num_tfbbufs; ++i) diff --git a/src/gallium/drivers/nvc0/nvc0_context.h b/src/gallium/drivers/nvc0/nvc0_context.h index d2dee03a19e..261cfb11007 100644 --- a/src/gallium/drivers/nvc0/nvc0_context.h +++ b/src/gallium/drivers/nvc0/nvc0_context.h @@ -121,7 +121,7 @@ struct nvc0_context { struct nvc0_program *gmtyprog; struct nvc0_program *fragprog; - struct pipe_resource *constbuf[5][16]; + struct nvc0_constbuf constbuf[5][NVC0_MAX_PIPE_CONSTBUFS]; uint16_t constbuf_dirty[5]; struct pipe_vertex_buffer vtxbuf[PIPE_MAX_ATTRIBS]; @@ -168,6 +168,23 @@ nvc0_context(struct pipe_context *pipe) return (struct nvc0_context *)pipe; } +static INLINE unsigned +nvc0_shader_stage(unsigned pipe) +{ + switch (pipe) { + case PIPE_SHADER_VERTEX: return 0; +/* case PIPE_SHADER_TESSELLATION_CONTROL: return 1; */ +/* case PIPE_SHADER_TESSELLATION_EVALUATION: return 2; */ + case PIPE_SHADER_GEOMETRY: return 3; + case PIPE_SHADER_FRAGMENT: return 4; + case PIPE_SHADER_COMPUTE: return 5; + default: + assert(!"invalid PIPE_SHADER type"); + return 0; + } +} + + /* nvc0_context.c */ struct pipe_context *nvc0_create(struct pipe_screen *, void *); void nvc0_bufctx_fence(struct nvc0_context *, struct nouveau_bufctx *, diff --git a/src/gallium/drivers/nvc0/nvc0_screen.c b/src/gallium/drivers/nvc0/nvc0_screen.c index 5d6befd45b7..498207f613d 100644 --- a/src/gallium/drivers/nvc0/nvc0_screen.c +++ b/src/gallium/drivers/nvc0/nvc0_screen.c @@ -190,7 +190,7 @@ nvc0_screen_get_shader_param(struct pipe_screen *pscreen, unsigned shader, case PIPE_SHADER_CAP_MAX_CONSTS: return 65536 / 16; case PIPE_SHADER_CAP_MAX_CONST_BUFFERS: - return 14; + return NVC0_MAX_PIPE_CONSTBUFS; case PIPE_SHADER_CAP_MAX_ADDRS: return 1; case PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR: diff --git a/src/gallium/drivers/nvc0/nvc0_screen.h b/src/gallium/drivers/nvc0/nvc0_screen.h index 8bcc1470593..69cddf2c9b0 100644 --- a/src/gallium/drivers/nvc0/nvc0_screen.h +++ b/src/gallium/drivers/nvc0/nvc0_screen.h @@ -14,6 +14,9 @@ #define NVC0_TIC_MAX_ENTRIES 2048 #define NVC0_TSC_MAX_ENTRIES 2048 +/* doesn't count reserved slots (for auxiliary constants, immediates, etc.) */ +#define NVC0_MAX_PIPE_CONSTBUFS 14 + struct nvc0_context; struct nvc0_blitctx; diff --git a/src/gallium/drivers/nvc0/nvc0_state.c b/src/gallium/drivers/nvc0/nvc0_state.c index 40161252a3d..cab238e7e06 100644 --- a/src/gallium/drivers/nvc0/nvc0_state.c +++ b/src/gallium/drivers/nvc0/nvc0_state.c @@ -620,38 +620,33 @@ nvc0_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index, { struct nvc0_context *nvc0 = nvc0_context(pipe); struct pipe_resource *res = cb ? cb->buffer : NULL; + const unsigned s = nvc0_shader_stage(shader); + const unsigned i = index; - if (cb && cb->user_buffer) { - res = nouveau_user_buffer_create(pipe->screen, cb->user_buffer, - cb->buffer_size, - PIPE_BIND_CONSTANT_BUFFER); - } + if (shader == PIPE_SHADER_COMPUTE) + return; - switch (shader) { - case PIPE_SHADER_VERTEX: shader = 0; break; - /* - case PIPE_SHADER_TESSELLATION_CONTROL: shader = 1; break; - case PIPE_SHADER_TESSELLATION_EVALUATION: shader = 2; break; - */ - case PIPE_SHADER_GEOMETRY: shader = 3; break; - case PIPE_SHADER_FRAGMENT: shader = 4; break; - default: - assert(0); - break; - } + if (nvc0->constbuf[s][i].user) + nvc0->constbuf[s][i].u.buf = NULL; + else + if (nvc0->constbuf[s][i].u.buf) + nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_CB(s, i)); - if (nvc0->constbuf[shader][index]) - nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_CB(shader, index)); + pipe_resource_reference(&nvc0->constbuf[s][i].u.buf, res); - pipe_resource_reference(&nvc0->constbuf[shader][index], res); + nvc0->constbuf[s][i].user = (cb && cb->user_buffer) ? TRUE : FALSE; + if (nvc0->constbuf[s][i].user) { + nvc0->constbuf[s][i].u.data = cb->user_buffer; + nvc0->constbuf[s][i].size = cb->buffer_size; + } else + if (cb) { + nvc0->constbuf[s][i].offset = cb->buffer_offset; + nvc0->constbuf[s][i].size = align(cb->buffer_size, 0x100); + } - nvc0->constbuf_dirty[shader] |= 1 << index; + nvc0->constbuf_dirty[s] |= 1 << i; nvc0->dirty |= NVC0_NEW_CONSTBUF; - - if (cb->user_buffer) { - pipe_resource_reference(&res, NULL); - } } /* ============================================================================= diff --git a/src/gallium/drivers/nvc0/nvc0_state_validate.c b/src/gallium/drivers/nvc0/nvc0_state_validate.c index 5d34f2b0bcc..c2d115e715f 100644 --- a/src/gallium/drivers/nvc0/nvc0_state_validate.c +++ b/src/gallium/drivers/nvc0/nvc0_state_validate.c @@ -355,70 +355,53 @@ static void nvc0_constbufs_validate(struct nvc0_context *nvc0) { struct nouveau_pushbuf *push = nvc0->base.pushbuf; - struct nouveau_bo *bo; unsigned s; for (s = 0; s < 5; ++s) { - struct nv04_resource *res; - int i; - while (nvc0->constbuf_dirty[s]) { - unsigned base = 0; - unsigned words = 0; - boolean rebind = TRUE; - - i = ffs(nvc0->constbuf_dirty[s]) - 1; + int i = ffs(nvc0->constbuf_dirty[s]) - 1; nvc0->constbuf_dirty[s] &= ~(1 << i); - res = nv04_resource(nvc0->constbuf[s][i]); - if (!res) { - 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; - continue; - } - - if (!nouveau_resource_mapped_by_gpu(&res->base)) { - if (i == 0 && (res->status & NOUVEAU_BUFFER_STATUS_USER_MEMORY)) { - base = s << 16; - bo = nvc0->screen->uniform_bo; - - if (nvc0->state.uniform_buffer_bound[s] >= res->base.width0) - rebind = FALSE; - else - nvc0->state.uniform_buffer_bound[s] = - align(res->base.width0, 0x100); - - words = res->base.width0 / 4; - } else { - nouveau_buffer_migrate(&nvc0->base, res, NOUVEAU_BO_VRAM); - bo = res->bo; - base = res->offset; + if (nvc0->constbuf[s][i].user) { + struct nouveau_bo *bo = nvc0->screen->uniform_bo; + const unsigned base = s << 16; + const unsigned size = nvc0->constbuf[s][0].size; + assert(i == 0); /* we really only want OpenGL uniforms here */ + assert(nvc0->constbuf[s][0].u.data); + + if (nvc0->state.uniform_buffer_bound[s] < size) { + 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_cb_push(&nvc0->base, bo, NOUVEAU_BO_VRAM, + base, nvc0->state.uniform_buffer_bound[s], + 0, (size + 3) / 4, + nvc0->constbuf[s][0].u.data); } else { - bo = res->bo; - base = res->offset; + 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); + + BCTX_REFN(nvc0->bufctx_3d, CB(s, i), res, RD); + } 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; } - - if (bo != nvc0->screen->uniform_bo) - BCTX_REFN(nvc0->bufctx_3d, CB(s, i), res, RD); - - if (rebind) { - BEGIN_NVC0(push, NVC0_3D(CB_SIZE), 3); - PUSH_DATA (push, align(res->base.width0, 0x100)); - PUSH_DATAh(push, bo->offset + base); - PUSH_DATA (push, bo->offset + base); - BEGIN_NVC0(push, NVC0_3D(CB_BIND(s)), 1); - PUSH_DATA (push, (i << 4) | 1); - } - - if (words) - nvc0_cb_push(&nvc0->base, - bo, NOUVEAU_BO_VRAM, base, res->base.width0, - 0, words, (const uint32_t *)res->data); } } } diff --git a/src/gallium/drivers/nvc0/nvc0_stateobj.h b/src/gallium/drivers/nvc0/nvc0_stateobj.h index 16d336cfab2..5afbffb7d22 100644 --- a/src/gallium/drivers/nvc0/nvc0_stateobj.h +++ b/src/gallium/drivers/nvc0/nvc0_stateobj.h @@ -32,6 +32,16 @@ struct nvc0_zsa_stateobj { uint32_t state[26]; }; +struct nvc0_constbuf { + union { + struct pipe_resource *buf; + const void *data; + } u; + uint32_t size; + uint16_t offset; + boolean user; /* should only be TRUE if u.data is valid and non-NULL */ +}; + struct nvc0_vertex_element { struct pipe_vertex_element pipe; uint32_t state; -- cgit v1.2.3