summaryrefslogtreecommitdiff
path: root/src/gallium/drivers/nv50
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/drivers/nv50')
-rw-r--r--src/gallium/drivers/nv50/nv50_context.h10
-rw-r--r--src/gallium/drivers/nv50/nv50_state.c34
-rw-r--r--src/gallium/drivers/nv50/nv50_vbo.c107
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 044437e75f..e91a61b27d 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 7d304907b6..ffbf3473a1 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 1c8ee0b9ad..c1dcb93b48 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;