diff options
author | Roland Scheidegger <[email protected]> | 2010-03-09 15:59:40 +0100 |
---|---|---|
committer | Roland Scheidegger <[email protected]> | 2010-03-09 15:59:40 +0100 |
commit | 685340a53e1dcb2a888e634ee71ba24356befe69 (patch) | |
tree | d6aa301eb5370eac6fcb3186d26a551c37b3c3a2 /src/gallium/drivers/nv50 | |
parent | e497a58fad878d913a1795b239ddd05870988c58 (diff) | |
parent | ae7b7bf1edcf6c492b4dcc162bca28a0090f601e (diff) |
Merge branch 'gallium-vertexelementcso'
Conflicts:
src/gallium/auxiliary/cso_cache/cso_context.c
src/gallium/auxiliary/util/u_blit.c
src/gallium/auxiliary/util/u_gen_mipmap.c
src/gallium/drivers/i915/i915_context.h
src/gallium/drivers/i965/brw_draw_upload.c
src/gallium/drivers/r300/r300_blit.c
src/gallium/drivers/r300/r300_context.h
src/gallium/drivers/r300/r300_render.c
src/gallium/drivers/r300/r300_state_derived.c
src/mesa/state_tracker/st_cb_bitmap.c
src/mesa/state_tracker/st_cb_clear.c
Diffstat (limited to 'src/gallium/drivers/nv50')
-rw-r--r-- | src/gallium/drivers/nv50/nv50_context.h | 10 | ||||
-rw-r--r-- | src/gallium/drivers/nv50/nv50_state.c | 34 | ||||
-rw-r--r-- | src/gallium/drivers/nv50/nv50_vbo.c | 107 |
3 files changed, 99 insertions, 52 deletions
diff --git a/src/gallium/drivers/nv50/nv50_context.h b/src/gallium/drivers/nv50/nv50_context.h index 044437e75fa..e91a61b27dd 100644 --- a/src/gallium/drivers/nv50/nv50_context.h +++ b/src/gallium/drivers/nv50/nv50_context.h @@ -72,6 +72,12 @@ struct nv50_sampler_stateobj { unsigned tsc[8]; }; +struct nv50_vtxelt_stateobj { + struct pipe_vertex_element pipe[16]; + unsigned num_elements; + uint32_t hw[16]; +}; + static INLINE unsigned get_tile_height(uint32_t tile_mode) { @@ -169,8 +175,7 @@ struct nv50_context { struct pipe_buffer *constbuf[PIPE_SHADER_TYPES]; struct pipe_vertex_buffer vtxbuf[PIPE_MAX_ATTRIBS]; unsigned vtxbuf_nr; - struct pipe_vertex_element vtxelt[PIPE_MAX_ATTRIBS]; - unsigned vtxelt_nr; + struct nv50_vtxelt_stateobj *vtxelt; struct nv50_sampler_stateobj *sampler[PIPE_SHADER_TYPES][PIPE_MAX_SAMPLERS]; unsigned sampler_nr[PIPE_SHADER_TYPES]; struct nv50_miptree *miptree[PIPE_SHADER_TYPES][PIPE_MAX_SAMPLERS]; @@ -218,6 +223,7 @@ extern void nv50_draw_elements_instanced(struct pipe_context *pipe, unsigned count, unsigned startInstance, unsigned instanceCount); +extern void nv50_vtxelt_construct(struct nv50_vtxelt_stateobj *cso); extern void nv50_vbo_validate(struct nv50_context *nv50); /* nv50_clear.c */ diff --git a/src/gallium/drivers/nv50/nv50_state.c b/src/gallium/drivers/nv50/nv50_state.c index 7d304907b65..ffbf3473a1e 100644 --- a/src/gallium/drivers/nv50/nv50_state.c +++ b/src/gallium/drivers/nv50/nv50_state.c @@ -720,15 +720,34 @@ nv50_set_vertex_buffers(struct pipe_context *pipe, unsigned count, nv50->dirty |= NV50_NEW_ARRAYS; } +static void * +nv50_vtxelts_state_create(struct pipe_context *pipe, + unsigned num_elements, + const struct pipe_vertex_element *elements) +{ + struct nv50_vtxelt_stateobj *cso = CALLOC_STRUCT(nv50_vtxelt_stateobj); + + assert(num_elements < 16); /* not doing fallbacks yet */ + cso->num_elements = num_elements; + memcpy(cso->pipe, elements, num_elements * sizeof(*elements)); + + nv50_vtxelt_construct(cso); + + return (void *)cso; +} + static void -nv50_set_vertex_elements(struct pipe_context *pipe, unsigned count, - const struct pipe_vertex_element *ve) +nv50_vtxelts_state_delete(struct pipe_context *pipe, void *hwcso) { - struct nv50_context *nv50 = nv50_context(pipe); + FREE(hwcso); +} - memcpy(nv50->vtxelt, ve, sizeof(*ve) * count); - nv50->vtxelt_nr = count; +static void +nv50_vtxelts_state_bind(struct pipe_context *pipe, void *hwcso) +{ + struct nv50_context *nv50 = nv50_context(pipe); + nv50->vtxelt = hwcso; nv50->dirty |= NV50_NEW_ARRAYS; } @@ -778,7 +797,10 @@ nv50_init_state_functions(struct nv50_context *nv50) nv50->pipe.set_scissor_state = nv50_set_scissor_state; nv50->pipe.set_viewport_state = nv50_set_viewport_state; + nv50->pipe.create_vertex_elements_state = nv50_vtxelts_state_create; + nv50->pipe.delete_vertex_elements_state = nv50_vtxelts_state_delete; + nv50->pipe.bind_vertex_elements_state = nv50_vtxelts_state_bind; + nv50->pipe.set_vertex_buffers = nv50_set_vertex_buffers; - nv50->pipe.set_vertex_elements = nv50_set_vertex_elements; } diff --git a/src/gallium/drivers/nv50/nv50_vbo.c b/src/gallium/drivers/nv50/nv50_vbo.c index 1c8ee0b9adf..c1dcb93b48c 100644 --- a/src/gallium/drivers/nv50/nv50_vbo.c +++ b/src/gallium/drivers/nv50/nv50_vbo.c @@ -139,15 +139,16 @@ nv50_vbo_vtxelt_to_hw(struct pipe_vertex_element *ve) uint32_t hw_type, hw_size; enum pipe_format pf = ve->src_format; const struct util_format_description *desc; - unsigned size; + unsigned size, nr_components; desc = util_format_description(pf); assert(desc); size = util_format_get_component_bits(pf, UTIL_FORMAT_COLORSPACE_RGB, 0); + nr_components = util_format_get_nr_components(pf); hw_type = nv50_vbo_type_to_hw(pf); - hw_size = nv50_vbo_size_to_hw(size, ve->nr_components); + hw_size = nv50_vbo_size_to_hw(size, nr_components); if (!hw_type || !hw_size) { NOUVEAU_ERR("unsupported vbo format: %s\n", util_format_name(pf)); @@ -222,11 +223,12 @@ nv50_set_static_vtxattr(struct nv50_context *nv50, unsigned i, void *data) struct nouveau_grobj *tesla = nv50->screen->tesla; struct nouveau_channel *chan = tesla->channel; float v[4]; + enum pipe_format pf = nv50->vtxelt->pipe[i].src_format; + unsigned nr_components = util_format_get_nr_components(pf); - util_format_read_4f(nv50->vtxelt[i].src_format, - v, 0, data, 0, 0, 0, 1, 1); + util_format_read_4f(pf, v, 0, data, 0, 0, 0, 1, 1); - switch (nv50->vtxelt[i].nr_components) { + switch (nr_components) { case 4: BEGIN_RING(chan, tesla, NV50TCL_VTX_ATTR_4F_X(i), 4); OUT_RINGf (chan, v[0]); @@ -263,16 +265,17 @@ init_per_instance_arrays_immd(struct nv50_context *nv50, struct nouveau_bo *bo; unsigned i, b, count = 0; - for (i = 0; i < nv50->vtxelt_nr; ++i) { - if (!nv50->vtxelt[i].instance_divisor) + for (i = 0; i < nv50->vtxelt->num_elements; ++i) { + if (!nv50->vtxelt->pipe[i].instance_divisor) continue; ++count; - b = nv50->vtxelt[i].vertex_buffer_index; + b = nv50->vtxelt->pipe[i].vertex_buffer_index; - pos[i] = nv50->vtxelt[i].src_offset + + pos[i] = nv50->vtxelt->pipe[i].src_offset + nv50->vtxbuf[b].buffer_offset + startInstance * nv50->vtxbuf[b].stride; - step[i] = startInstance % nv50->vtxelt[i].instance_divisor; + step[i] = startInstance % + nv50->vtxelt->pipe[i].instance_divisor; bo = nouveau_bo(nv50->vtxbuf[b].buffer); if (!bo->map) @@ -293,22 +296,22 @@ init_per_instance_arrays(struct nv50_context *nv50, struct nouveau_channel *chan = tesla->channel; struct nouveau_bo *bo; struct nouveau_stateobj *so; - unsigned i, b, count = 0; + unsigned i, b, count = 0, num_elements = nv50->vtxelt->num_elements; const uint32_t rl = NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD; if (nv50->vbo_fifo) return init_per_instance_arrays_immd(nv50, startInstance, pos, step); - so = so_new(nv50->vtxelt_nr, nv50->vtxelt_nr * 2, nv50->vtxelt_nr * 2); + so = so_new(num_elements, num_elements * 2, num_elements * 2); - for (i = 0; i < nv50->vtxelt_nr; ++i) { - if (!nv50->vtxelt[i].instance_divisor) + for (i = 0; i < nv50->vtxelt->num_elements; ++i) { + if (!nv50->vtxelt->pipe[i].instance_divisor) continue; ++count; - b = nv50->vtxelt[i].vertex_buffer_index; + b = nv50->vtxelt->pipe[i].vertex_buffer_index; - pos[i] = nv50->vtxelt[i].src_offset + + pos[i] = nv50->vtxelt->pipe[i].src_offset + nv50->vtxbuf[b].buffer_offset + startInstance * nv50->vtxbuf[b].stride; @@ -316,7 +319,8 @@ init_per_instance_arrays(struct nv50_context *nv50, step[i] = 0; continue; } - step[i] = startInstance % nv50->vtxelt[i].instance_divisor; + step[i] = startInstance % + nv50->vtxelt->pipe[i].instance_divisor; bo = nouveau_bo(nv50->vtxbuf[b].buffer); @@ -341,12 +345,12 @@ step_per_instance_arrays_immd(struct nv50_context *nv50, struct nouveau_bo *bo; unsigned i, b; - for (i = 0; i < nv50->vtxelt_nr; ++i) { - if (!nv50->vtxelt[i].instance_divisor) + for (i = 0; i < nv50->vtxelt->num_elements; ++i) { + if (!nv50->vtxelt->pipe[i].instance_divisor) continue; - if (++step[i] != nv50->vtxelt[i].instance_divisor) + if (++step[i] != nv50->vtxelt->pipe[i].instance_divisor) continue; - b = nv50->vtxelt[i].vertex_buffer_index; + b = nv50->vtxelt->pipe[i].vertex_buffer_index; bo = nouveau_bo(nv50->vtxbuf[b].buffer); step[i] = 0; @@ -364,7 +368,7 @@ step_per_instance_arrays(struct nv50_context *nv50, struct nouveau_channel *chan = tesla->channel; struct nouveau_bo *bo; struct nouveau_stateobj *so; - unsigned i, b; + unsigned i, b, num_elements = nv50->vtxelt->num_elements; const uint32_t rl = NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD; if (nv50->vbo_fifo) { @@ -372,14 +376,14 @@ step_per_instance_arrays(struct nv50_context *nv50, return; } - so = so_new(nv50->vtxelt_nr, nv50->vtxelt_nr * 2, nv50->vtxelt_nr * 2); + so = so_new(num_elements, num_elements * 2, num_elements * 2); - for (i = 0; i < nv50->vtxelt_nr; ++i) { - if (!nv50->vtxelt[i].instance_divisor) + for (i = 0; i < nv50->vtxelt->num_elements; ++i) { + if (!nv50->vtxelt->pipe[i].instance_divisor) continue; - b = nv50->vtxelt[i].vertex_buffer_index; + b = nv50->vtxelt->pipe[i].vertex_buffer_index; - if (++step[i] == nv50->vtxelt[i].instance_divisor) { + if (++step[i] == nv50->vtxelt->pipe[i].instance_divisor) { step[i] = 0; pos[i] += nv50->vtxbuf[b].stride; } @@ -726,6 +730,7 @@ nv50_vbo_static_attrib(struct nv50_context *nv50, unsigned attrib, struct nouveau_bo *bo = nouveau_bo(vb->buffer); float v[4]; int ret; + unsigned nr_components = util_format_get_nr_components(ve->src_format); ret = nouveau_bo_map(bo, NOUVEAU_BO_RD); if (ret) @@ -736,9 +741,10 @@ nv50_vbo_static_attrib(struct nv50_context *nv50, unsigned attrib, 0, 0, 1, 1); so = *pso; if (!so) - *pso = so = so_new(nv50->vtxelt_nr, nv50->vtxelt_nr * 4, 0); + *pso = so = so_new(nv50->vtxelt->num_elements, + nv50->vtxelt->num_elements * 4, 0); - switch (ve->nr_components) { + switch (nr_components) { case 4: so_method(so, tesla, NV50TCL_VTX_ATTR_4F_X(attrib), 4); so_data (so, fui(v[0])); @@ -775,6 +781,18 @@ nv50_vbo_static_attrib(struct nv50_context *nv50, unsigned attrib, } void +nv50_vtxelt_construct(struct nv50_vtxelt_stateobj *cso) +{ + unsigned i; + + for (i = 0; i < cso->num_elements; ++i) { + struct pipe_vertex_element *ve = &cso->pipe[i]; + + cso->hw[i] = nv50_vbo_vtxelt_to_hw(ve); + } +} + +void nv50_vbo_validate(struct nv50_context *nv50) { struct nouveau_grobj *tesla = nv50->screen->tesla; @@ -794,19 +812,19 @@ nv50_vbo_validate(struct nv50_context *nv50) if (NV50_USING_LOATHED_EDGEFLAG(nv50)) nv50->vbo_fifo = 0xffff; /* vertprog can't set edgeflag */ - n_ve = MAX2(nv50->vtxelt_nr, nv50->state.vtxelt_nr); + n_ve = MAX2(nv50->vtxelt->num_elements, nv50->state.vtxelt_nr); vtxattr = NULL; - vtxbuf = so_new(n_ve * 2, n_ve * 5, nv50->vtxelt_nr * 4); + vtxbuf = so_new(n_ve * 2, n_ve * 5, nv50->vtxelt->num_elements * 4); vtxfmt = so_new(1, n_ve, 0); so_method(vtxfmt, tesla, NV50TCL_VERTEX_ARRAY_ATTRIB(0), n_ve); - for (i = 0; i < nv50->vtxelt_nr; i++) { - struct pipe_vertex_element *ve = &nv50->vtxelt[i]; + for (i = 0; i < nv50->vtxelt->num_elements; i++) { + struct pipe_vertex_element *ve = &nv50->vtxelt->pipe[i]; struct pipe_vertex_buffer *vb = &nv50->vtxbuf[ve->vertex_buffer_index]; struct nouveau_bo *bo = nouveau_bo(vb->buffer); - uint32_t hw = nv50_vbo_vtxelt_to_hw(ve); + uint32_t hw = nv50->vtxelt->hw[i]; if (!vb->stride && nv50_vbo_static_attrib(nv50, i, &vtxattr, ve, vb)) { @@ -855,7 +873,7 @@ nv50_vbo_validate(struct nv50_context *nv50) so_method(vtxbuf, tesla, NV50TCL_VERTEX_ARRAY_FORMAT(i), 1); so_data (vtxbuf, 0); } - nv50->state.vtxelt_nr = nv50->vtxelt_nr; + nv50->state.vtxelt_nr = nv50->vtxelt->num_elements; so_ref (vtxfmt, &nv50->state.vtxfmt); so_ref (vtxbuf, &nv50->state.vtxbuf); @@ -1016,13 +1034,13 @@ emit_prepare(struct nv50_context *nv50, struct nv50_vbo_emitctx *emit, emit->nr_ve = 0; emit->vtx_dwords = 0; - for (i = 0; i < nv50->vtxelt_nr; ++i) { + for (i = 0; i < nv50->vtxelt->num_elements; ++i) { struct pipe_vertex_element *ve; struct pipe_vertex_buffer *vb; - unsigned n, size; + unsigned n, size, nr_components; const struct util_format_description *desc; - ve = &nv50->vtxelt[i]; + ve = &nv50->vtxelt->pipe[i]; vb = &nv50->vtxbuf[ve->vertex_buffer_index]; if (!(nv50->vbo_fifo & (1 << i)) || ve->instance_divisor) continue; @@ -1038,8 +1056,9 @@ emit_prepare(struct nv50_context *nv50, struct nv50_vbo_emitctx *emit, size = util_format_get_component_bits( ve->src_format, UTIL_FORMAT_COLORSPACE_RGB, 0); + nr_components = util_format_get_nr_components(ve->src_format); - assert(ve->nr_components > 0 && ve->nr_components <= 4); + assert(nr_components > 0 && nr_components <= 4); /* It shouldn't be necessary to push the implicit 1s * for case 3 and size 8 cases 1, 2, 3. @@ -1049,25 +1068,25 @@ emit_prepare(struct nv50_context *nv50, struct nv50_vbo_emitctx *emit, NOUVEAU_ERR("unsupported vtxelt size: %u\n", size); return FALSE; case 32: - switch (ve->nr_components) { + switch (nr_components) { case 1: emit->push[n] = emit_b32_1; break; case 2: emit->push[n] = emit_b32_2; break; case 3: emit->push[n] = emit_b32_3; break; case 4: emit->push[n] = emit_b32_4; break; } - emit->vtx_dwords += ve->nr_components; + emit->vtx_dwords += nr_components; break; case 16: - switch (ve->nr_components) { + switch (nr_components) { case 1: emit->push[n] = emit_b16_1; break; case 2: emit->push[n] = emit_b32_1; break; case 3: emit->push[n] = emit_b16_3; break; case 4: emit->push[n] = emit_b32_2; break; } - emit->vtx_dwords += (ve->nr_components + 1) >> 1; + emit->vtx_dwords += (nr_components + 1) >> 1; break; case 8: - switch (ve->nr_components) { + switch (nr_components) { case 1: emit->push[n] = emit_b08_1; break; case 2: emit->push[n] = emit_b16_1; break; case 3: emit->push[n] = emit_b08_3; break; |