mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-06 02:58:05 +02:00
nv40: construct vbo state the same way as the rest
This commit is contained in:
parent
14de997d5d
commit
4058a90127
5 changed files with 137 additions and 136 deletions
|
|
@ -54,7 +54,9 @@ enum nv40_state_index {
|
|||
NV40_STATE_VERTTEX1 = 28,
|
||||
NV40_STATE_VERTTEX2 = 29,
|
||||
NV40_STATE_VERTTEX3 = 30,
|
||||
NV40_STATE_MAX = 31
|
||||
NV40_STATE_VTXBUF = 31,
|
||||
NV40_STATE_VTXFMT = 32,
|
||||
NV40_STATE_MAX = 33
|
||||
};
|
||||
|
||||
#define NV40_NEW_BLEND (1 << 0)
|
||||
|
|
@ -117,7 +119,7 @@ struct nv40_state {
|
|||
unsigned stipple_enabled;
|
||||
unsigned fp_samplers;
|
||||
|
||||
unsigned dirty;
|
||||
uint64_t dirty;
|
||||
struct nouveau_stateobj *hw[NV40_STATE_MAX];
|
||||
};
|
||||
|
||||
|
|
@ -149,13 +151,13 @@ struct nv40_context {
|
|||
struct pipe_blend_color blend_colour;
|
||||
struct pipe_viewport_state viewport;
|
||||
struct pipe_framebuffer_state framebuffer;
|
||||
struct pipe_buffer *idxbuf;
|
||||
unsigned idxbuf_format;
|
||||
} pipe_state;
|
||||
|
||||
struct nv40_state state;
|
||||
unsigned fallback;
|
||||
|
||||
struct nouveau_stateobj *so_vtxbuf;
|
||||
|
||||
struct pipe_vertex_buffer vtxbuf[PIPE_ATTRIB_MAX];
|
||||
struct pipe_vertex_element vtxelt[PIPE_ATTRIB_MAX];
|
||||
};
|
||||
|
|
@ -208,6 +210,7 @@ extern struct nv40_state_entry nv40_state_zsa;
|
|||
extern struct nv40_state_entry nv40_state_viewport;
|
||||
extern struct nv40_state_entry nv40_state_framebuffer;
|
||||
extern struct nv40_state_entry nv40_state_fragtex;
|
||||
extern struct nv40_state_entry nv40_state_vbo;
|
||||
|
||||
/* nv40_vbo.c */
|
||||
extern boolean nv40_draw_arrays(struct pipe_context *, unsigned mode,
|
||||
|
|
|
|||
|
|
@ -140,7 +140,7 @@ nv40_fragtex_validate(struct nv40_context *nv40)
|
|||
so_method(so, nv40->hw->curie, NV40TCL_TEX_ENABLE(unit), 1);
|
||||
so_data (so, 0);
|
||||
so_ref(so, &nv40->state.hw[NV40_STATE_FRAGTEX0 + unit]);
|
||||
state->dirty |= (1 << (NV40_STATE_FRAGTEX0 + unit));
|
||||
state->dirty |= (1ULL << (NV40_STATE_FRAGTEX0 + unit));
|
||||
}
|
||||
|
||||
samplers = nv40->dirty_samplers & fp->samplers;
|
||||
|
|
@ -150,7 +150,7 @@ nv40_fragtex_validate(struct nv40_context *nv40)
|
|||
|
||||
so = nv40_fragtex_build(nv40, unit);
|
||||
so_ref(so, &nv40->state.hw[NV40_STATE_FRAGTEX0 + unit]);
|
||||
state->dirty |= (1 << (NV40_STATE_FRAGTEX0 + unit));
|
||||
state->dirty |= (1ULL << (NV40_STATE_FRAGTEX0 + unit));
|
||||
}
|
||||
|
||||
nv40->state.fp_samplers = fp->samplers;
|
||||
|
|
|
|||
|
|
@ -628,7 +628,6 @@ nv40_set_vertex_buffer(struct pipe_context *pipe, unsigned index,
|
|||
struct nv40_context *nv40 = nv40_context(pipe);
|
||||
|
||||
nv40->vtxbuf[index] = *vb;
|
||||
|
||||
nv40->dirty |= NV40_NEW_ARRAYS;
|
||||
}
|
||||
|
||||
|
|
@ -639,7 +638,6 @@ nv40_set_vertex_element(struct pipe_context *pipe, unsigned index,
|
|||
struct nv40_context *nv40 = nv40_context(pipe);
|
||||
|
||||
nv40->vtxelt[index] = *ve;
|
||||
|
||||
nv40->dirty |= NV40_NEW_ARRAYS;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ static struct nv40_state_entry *render_states[] = {
|
|||
&nv40_state_blend_colour,
|
||||
&nv40_state_zsa,
|
||||
&nv40_state_viewport,
|
||||
&nv40_state_vbo,
|
||||
NULL
|
||||
};
|
||||
|
||||
|
|
@ -31,7 +32,7 @@ nv40_state_validate(struct nv40_context *nv40)
|
|||
|
||||
if (nv40->dirty & e->dirty.pipe) {
|
||||
if (e->validate(nv40))
|
||||
nv40->state.dirty |= (1 << e->dirty.hw);
|
||||
nv40->state.dirty |= (1ULL << e->dirty.hw);
|
||||
}
|
||||
|
||||
states++;
|
||||
|
|
@ -64,20 +65,21 @@ nv40_state_emit(struct nv40_context *nv40)
|
|||
unsigned i, samplers;
|
||||
|
||||
while (state->dirty) {
|
||||
unsigned idx = ffs(state->dirty) - 1;
|
||||
unsigned idx = ffsll(state->dirty) - 1;
|
||||
|
||||
so_ref (state->hw[idx], &nv40->hw->state[idx]);
|
||||
so_emit(nv40->nvws, nv40->hw->state[idx]);
|
||||
state->dirty &= ~(1 << idx);
|
||||
state->dirty &= ~(1ULL << idx);
|
||||
}
|
||||
|
||||
so_emit_reloc_markers(nv40->nvws, state->hw[NV40_STATE_FB]);
|
||||
for (i = 0, samplers = state->fp_samplers; i < 16 && samplers; i++) {
|
||||
so_emit_reloc_markers(nv40->nvws,
|
||||
state->hw[NV40_STATE_FRAGTEX0+i]);
|
||||
samplers &= ~(1 << i);
|
||||
samplers &= ~(1ULL << i);
|
||||
}
|
||||
so_emit_reloc_markers(nv40->nvws, state->hw[NV40_STATE_FRAGPROG]);
|
||||
so_emit_reloc_markers(nv40->nvws, state->hw[NV40_STATE_VTXBUF]);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
|||
|
|
@ -39,6 +39,43 @@ nv40_vbo_type(uint format)
|
|||
}
|
||||
}
|
||||
|
||||
static boolean
|
||||
nv40_vbo_set_idxbuf(struct nv40_context *nv40, struct pipe_buffer *ib,
|
||||
unsigned ib_size)
|
||||
{
|
||||
unsigned type;
|
||||
|
||||
if (!ib) {
|
||||
nv40->pipe_state.idxbuf = NULL;
|
||||
nv40->pipe_state.idxbuf_format = 0xdeadbeef;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* No support for 8bit indices, no support at all on 0x4497 chips */
|
||||
if (nv40->hw->curie->grclass == NV44TCL || ib_size == 1)
|
||||
return FALSE;
|
||||
|
||||
switch (ib_size) {
|
||||
case 2:
|
||||
type = NV40TCL_IDXBUF_FORMAT_TYPE_U16;
|
||||
break;
|
||||
case 4:
|
||||
type = NV40TCL_IDXBUF_FORMAT_TYPE_U32;
|
||||
break;
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (ib != nv40->pipe_state.idxbuf ||
|
||||
type != nv40->pipe_state.idxbuf_format) {
|
||||
nv40->dirty |= NV40_NEW_ARRAYS;
|
||||
nv40->pipe_state.idxbuf = ib;
|
||||
nv40->pipe_state.idxbuf_format = type;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static boolean
|
||||
nv40_vbo_static_attrib(struct nv40_context *nv40, int attrib,
|
||||
struct pipe_vertex_element *ve,
|
||||
|
|
@ -101,104 +138,15 @@ nv40_vbo_static_attrib(struct nv40_context *nv40, int attrib,
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
nv40_vbo_arrays_update(struct nv40_context *nv40, struct pipe_buffer *ib,
|
||||
unsigned ib_format)
|
||||
{
|
||||
struct nv40_vertex_program *vp = nv40->pipe_state.vertprog;
|
||||
struct nouveau_stateobj *vtxbuf, *vtxfmt;
|
||||
unsigned inputs, hw, num_hw;
|
||||
unsigned vb_flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD;
|
||||
|
||||
inputs = vp->ir;
|
||||
for (hw = 0; hw < 16 && inputs; hw++) {
|
||||
if (inputs & (1 << hw)) {
|
||||
num_hw = hw;
|
||||
inputs &= ~(1 << hw);
|
||||
}
|
||||
}
|
||||
num_hw++;
|
||||
|
||||
vtxbuf = so_new(20, 18);
|
||||
so_method(vtxbuf, nv40->hw->curie, NV40TCL_VTXBUF_ADDRESS(0), num_hw);
|
||||
vtxfmt = so_new(17, 0);
|
||||
so_method(vtxfmt, nv40->hw->curie, NV40TCL_VTXFMT(0), num_hw);
|
||||
|
||||
inputs = vp->ir;
|
||||
for (hw = 0; hw < num_hw; hw++) {
|
||||
struct pipe_vertex_element *ve;
|
||||
struct pipe_vertex_buffer *vb;
|
||||
|
||||
if (!(inputs & (1 << hw))) {
|
||||
so_data(vtxbuf, 0);
|
||||
so_data(vtxfmt, NV40TCL_VTXFMT_TYPE_FLOAT);
|
||||
continue;
|
||||
}
|
||||
|
||||
ve = &nv40->vtxelt[hw];
|
||||
vb = &nv40->vtxbuf[ve->vertex_buffer_index];
|
||||
|
||||
if (!vb->pitch && nv40_vbo_static_attrib(nv40, hw, ve, vb)) {
|
||||
so_data(vtxbuf, 0);
|
||||
so_data(vtxfmt, NV40TCL_VTXFMT_TYPE_FLOAT);
|
||||
continue;
|
||||
}
|
||||
|
||||
so_reloc(vtxbuf, vb->buffer, vb->buffer_offset + ve->src_offset,
|
||||
vb_flags | NOUVEAU_BO_LOW | NOUVEAU_BO_OR,
|
||||
0, NV40TCL_VTXBUF_ADDRESS_DMA1);
|
||||
so_data (vtxfmt, ((vb->pitch << NV40TCL_VTXFMT_STRIDE_SHIFT) |
|
||||
(nv40_vbo_ncomp(ve->src_format) <<
|
||||
NV40TCL_VTXFMT_SIZE_SHIFT) |
|
||||
nv40_vbo_type(ve->src_format)));
|
||||
}
|
||||
|
||||
if (ib) {
|
||||
so_method(vtxbuf, nv40->hw->curie, NV40TCL_IDXBUF_ADDRESS, 2);
|
||||
so_reloc (vtxbuf, ib, 0, vb_flags | NOUVEAU_BO_LOW, 0, 0);
|
||||
so_reloc (vtxbuf, ib, ib_format, vb_flags | NOUVEAU_BO_OR,
|
||||
0, NV40TCL_IDXBUF_FORMAT_DMA1);
|
||||
}
|
||||
|
||||
so_emit(nv40->nvws, vtxfmt);
|
||||
so_emit(nv40->nvws, vtxbuf);
|
||||
so_ref (vtxbuf, &nv40->so_vtxbuf);
|
||||
so_ref (NULL, &vtxfmt);
|
||||
}
|
||||
|
||||
static boolean
|
||||
nv40_vbo_validate_state(struct nv40_context *nv40,
|
||||
struct pipe_buffer *ib, unsigned ib_format)
|
||||
{
|
||||
unsigned vdn = nv40->dirty & NV40_NEW_ARRAYS;
|
||||
|
||||
nv40_emit_hw_state(nv40);
|
||||
if (vdn || ib) {
|
||||
nv40_vbo_arrays_update(nv40, ib, ib_format);
|
||||
nv40->dirty &= ~NV40_NEW_ARRAYS;
|
||||
}
|
||||
|
||||
so_emit_reloc_markers(nv40->nvws, nv40->so_vtxbuf);
|
||||
|
||||
BEGIN_RING(curie, 0x1710, 1);
|
||||
OUT_RING (0); /* vtx cache flush */
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
boolean
|
||||
nv40_draw_arrays(struct pipe_context *pipe, unsigned mode, unsigned start,
|
||||
unsigned count)
|
||||
{
|
||||
struct nv40_context *nv40 = nv40_context(pipe);
|
||||
unsigned nr;
|
||||
boolean ret;
|
||||
|
||||
ret = nv40_vbo_validate_state(nv40, NULL, 0);
|
||||
if (!ret) {
|
||||
NOUVEAU_ERR("state validate failed\n");
|
||||
return FALSE;
|
||||
}
|
||||
nv40_vbo_set_idxbuf(nv40, NULL, 0);
|
||||
nv40_emit_hw_state(nv40);
|
||||
|
||||
BEGIN_RING(curie, NV40TCL_BEGIN_END, 1);
|
||||
OUT_RING (nvgl_primitive(mode));
|
||||
|
|
@ -305,14 +253,9 @@ nv40_draw_elements_inline(struct pipe_context *pipe,
|
|||
{
|
||||
struct nv40_context *nv40 = nv40_context(pipe);
|
||||
struct pipe_winsys *ws = pipe->winsys;
|
||||
boolean ret;
|
||||
void *map;
|
||||
|
||||
ret = nv40_vbo_validate_state(nv40, NULL, 0);
|
||||
if (!ret) {
|
||||
NOUVEAU_ERR("state validate failed\n");
|
||||
return FALSE;
|
||||
}
|
||||
nv40_emit_hw_state(nv40);
|
||||
|
||||
map = ws->buffer_map(ws, ib, PIPE_BUFFER_USAGE_CPU_READ);
|
||||
if (!ib) {
|
||||
|
|
@ -348,30 +291,12 @@ nv40_draw_elements_inline(struct pipe_context *pipe,
|
|||
|
||||
static boolean
|
||||
nv40_draw_elements_vbo(struct pipe_context *pipe,
|
||||
struct pipe_buffer *ib, unsigned ib_size,
|
||||
unsigned mode, unsigned start, unsigned count)
|
||||
{
|
||||
struct nv40_context *nv40 = nv40_context(pipe);
|
||||
unsigned nr, type;
|
||||
boolean ret;
|
||||
unsigned nr;
|
||||
|
||||
switch (ib_size) {
|
||||
case 2:
|
||||
type = NV40TCL_IDXBUF_FORMAT_TYPE_U16;
|
||||
break;
|
||||
case 4:
|
||||
type = NV40TCL_IDXBUF_FORMAT_TYPE_U32;
|
||||
break;
|
||||
default:
|
||||
NOUVEAU_ERR("invalid idxbuf fmt %d\n", ib_size);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
ret = nv40_vbo_validate_state(nv40, ib, type);
|
||||
if (!ret) {
|
||||
NOUVEAU_ERR("failed state validation\n");
|
||||
return FALSE;
|
||||
}
|
||||
nv40_emit_hw_state(nv40);
|
||||
|
||||
BEGIN_RING(curie, NV40TCL_BEGIN_END, 1);
|
||||
OUT_RING (nvgl_primitive(mode));
|
||||
|
|
@ -409,19 +334,92 @@ nv40_draw_elements(struct pipe_context *pipe,
|
|||
{
|
||||
struct nv40_context *nv40 = nv40_context(pipe);
|
||||
|
||||
/* 0x4497 doesn't support real index buffers, and there doesn't appear
|
||||
* to be support on any chipset for 8-bit indices.
|
||||
*/
|
||||
if (nv40->hw->curie->grclass == NV44TCL || indexSize == 1) {
|
||||
if (nv40_vbo_set_idxbuf(nv40, indexBuffer, indexSize)) {
|
||||
nv40_draw_elements_vbo(pipe, mode, start, count);
|
||||
} else {
|
||||
nv40_draw_elements_inline(pipe, indexBuffer, indexSize,
|
||||
mode, start, count);
|
||||
} else {
|
||||
nv40_draw_elements_vbo(pipe, indexBuffer, indexSize,
|
||||
mode, start, count);
|
||||
}
|
||||
|
||||
pipe->flush(pipe, 0);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static boolean
|
||||
nv40_vbo_validate(struct nv40_context *nv40)
|
||||
{
|
||||
struct nv40_vertex_program *vp = nv40->pipe_state.vertprog;
|
||||
struct nouveau_stateobj *vtxbuf, *vtxfmt;
|
||||
struct pipe_buffer *ib = nv40->pipe_state.idxbuf;
|
||||
unsigned ib_format = nv40->pipe_state.idxbuf_format;
|
||||
unsigned inputs, hw, num_hw;
|
||||
unsigned vb_flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD;
|
||||
|
||||
inputs = vp->ir;
|
||||
for (hw = 0; hw < 16 && inputs; hw++) {
|
||||
if (inputs & (1 << hw)) {
|
||||
num_hw = hw;
|
||||
inputs &= ~(1 << hw);
|
||||
}
|
||||
}
|
||||
num_hw++;
|
||||
|
||||
vtxbuf = so_new(20, 18);
|
||||
so_method(vtxbuf, nv40->hw->curie, NV40TCL_VTXBUF_ADDRESS(0), num_hw);
|
||||
vtxfmt = so_new(17, 0);
|
||||
so_method(vtxfmt, nv40->hw->curie, NV40TCL_VTXFMT(0), num_hw);
|
||||
|
||||
inputs = vp->ir;
|
||||
for (hw = 0; hw < num_hw; hw++) {
|
||||
struct pipe_vertex_element *ve;
|
||||
struct pipe_vertex_buffer *vb;
|
||||
|
||||
if (!(inputs & (1 << hw))) {
|
||||
so_data(vtxbuf, 0);
|
||||
so_data(vtxfmt, NV40TCL_VTXFMT_TYPE_FLOAT);
|
||||
continue;
|
||||
}
|
||||
|
||||
ve = &nv40->vtxelt[hw];
|
||||
vb = &nv40->vtxbuf[ve->vertex_buffer_index];
|
||||
|
||||
if (!vb->pitch && nv40_vbo_static_attrib(nv40, hw, ve, vb)) {
|
||||
so_data(vtxbuf, 0);
|
||||
so_data(vtxfmt, NV40TCL_VTXFMT_TYPE_FLOAT);
|
||||
continue;
|
||||
}
|
||||
|
||||
so_reloc(vtxbuf, vb->buffer, vb->buffer_offset + ve->src_offset,
|
||||
vb_flags | NOUVEAU_BO_LOW | NOUVEAU_BO_OR,
|
||||
0, NV40TCL_VTXBUF_ADDRESS_DMA1);
|
||||
so_data (vtxfmt, ((vb->pitch << NV40TCL_VTXFMT_STRIDE_SHIFT) |
|
||||
(nv40_vbo_ncomp(ve->src_format) <<
|
||||
NV40TCL_VTXFMT_SIZE_SHIFT) |
|
||||
nv40_vbo_type(ve->src_format)));
|
||||
}
|
||||
|
||||
if (ib) {
|
||||
so_method(vtxbuf, nv40->hw->curie, NV40TCL_IDXBUF_ADDRESS, 2);
|
||||
so_reloc (vtxbuf, ib, 0, vb_flags | NOUVEAU_BO_LOW, 0, 0);
|
||||
so_reloc (vtxbuf, ib, ib_format, vb_flags | NOUVEAU_BO_OR,
|
||||
0, NV40TCL_IDXBUF_FORMAT_DMA1);
|
||||
}
|
||||
|
||||
so_method(vtxbuf, nv40->hw->curie, 0x1710, 1);
|
||||
so_data (vtxbuf, 0);
|
||||
|
||||
so_ref(vtxbuf, &nv40->state.hw[NV40_STATE_VTXBUF]);
|
||||
nv40->state.dirty |= (1ULL << NV40_STATE_VTXBUF);
|
||||
so_ref(vtxfmt, &nv40->state.hw[NV40_STATE_VTXFMT]);
|
||||
nv40->state.dirty |= (1ULL << NV40_STATE_VTXFMT);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
struct nv40_state_entry nv40_state_vbo = {
|
||||
.validate = nv40_vbo_validate,
|
||||
.dirty = {
|
||||
.pipe = NV40_NEW_ARRAYS,
|
||||
.hw = 0,
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue