nvc0: fix submission of VertexID and EdgeFlag in push mode

NOTE: This is a candidate for the 8.0 branch.
This commit is contained in:
Christoph Bumiller 2012-01-12 19:12:02 +01:00
parent cb254b75d7
commit 7b6881932a
9 changed files with 84 additions and 21 deletions

View file

@ -938,6 +938,7 @@ nv50_ir_init_prog_info(struct nv50_ir_prog_info *info)
}
info->io.clipDistance = 0xff;
info->io.pointSize = 0xff;
info->io.vertexId = 0xff;
info->io.edgeFlagIn = 0xff;
info->io.edgeFlagOut = 0xff;
info->io.fragDepth = 0xff;

View file

@ -155,6 +155,7 @@ struct nv50_ir_prog_info
uint8_t cullDistanceMask; /* clip distance mode (1 bit per output) */
int8_t genUserClip; /* request user clip planes for ClipVertex */
uint8_t pointSize; /* output index for PointSize */
uint8_t vertexId; /* system value index of VertexID */
uint8_t edgeFlagIn;
uint8_t edgeFlagOut;
uint8_t fragDepth; /* output index of FragDepth */

View file

@ -864,6 +864,13 @@ bool Source::scanDeclaration(const struct tgsi_full_declaration *decl)
}
break;
case TGSI_FILE_SYSTEM_VALUE:
switch (sn) {
case TGSI_SEMANTIC_VERTEXID:
info->io.vertexId = first;
break;
default:
break;
}
for (i = first; i <= last; ++i, ++si) {
info->sv[i].sn = sn;
info->sv[i].si = si;

View file

@ -913,6 +913,11 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define NVC0_3D_VERTEX_BEGIN_GL_INSTANCE_NEXT 0x04000000
#define NVC0_3D_VERTEX_BEGIN_GL_INSTANCE_CONT 0x08000000
#define NVC0_3D_VERTEX_ID_REPLACE 0x0000161c
#define NVC0_3D_VERTEX_ID_REPLACE_ENABLE 0x00000001
#define NVC0_3D_VERTEX_ID_REPLACE_SOURCE__MASK 0x00000ff0
#define NVC0_3D_VERTEX_ID_REPLACE_SOURCE__SHIFT 4
#define NVC0_3D_VERTEX_DATA 0x00001640
#define NVC0_3D_PRIM_RESTART_ENABLE 0x00001644

View file

@ -134,9 +134,6 @@ struct nvc0_context {
struct draw_context *draw;
};
#define NVC0_USING_EDGEFLAG(ctx) \
((ctx)->vertprog->vp.edgeflag < PIPE_MAX_ATTRIBS)
static INLINE struct nvc0_context *
nvc0_context(struct pipe_context *pipe)
{

View file

@ -107,7 +107,7 @@ nvc0_vp_assign_input_slots(struct nv50_ir_prog_info *info)
for (n = 0, i = 0; i < info->numInputs; ++i) {
switch (info->in[i].sn) {
case TGSI_SEMANTIC_INSTANCEID:
case TGSI_SEMANTIC_INSTANCEID: /* for SM4 only, in TGSI they're SVs */
case TGSI_SEMANTIC_VERTEXID:
info->in[i].mask = 0x1;
info->in[i].slot[0] =
@ -580,7 +580,11 @@ nvc0_program_translate(struct nvc0_program *prog)
prog->relocs = info->bin.relocData;
prog->max_gpr = MAX2(4, (info->bin.maxGPR + 1));
prog->vp.edgeflag = PIPE_MAX_ATTRIBS;
prog->vp.need_vertex_id = info->io.vertexId < PIPE_MAX_SHADER_INPUTS;
if (info->io.edgeFlagOut < PIPE_MAX_ATTRIBS)
info->out[info->io.edgeFlagOut].mask = 0; /* for headergen */
prog->vp.edgeflag = info->io.edgeFlagIn;
switch (prog->type) {
case PIPE_SHADER_VERTEX:

View file

@ -37,8 +37,9 @@ struct nvc0_program {
struct {
uint32_t clip_mode; /* clip/cull selection */
uint8_t clip_enable; /* mask of defined clip planes */
uint8_t edgeflag;
uint8_t num_ucps; /* also set to max if ClipDistance is used */
uint8_t edgeflag; /* attribute index of edgeflag input */
boolean need_vertex_id;
} vp;
struct {
uint8_t early_z;

View file

@ -21,6 +21,7 @@ struct push_context {
struct translate *translate;
boolean primitive_restart;
boolean need_vertex_id;
uint32_t prim;
uint32_t restart_index;
uint32_t instance_id;
@ -42,22 +43,23 @@ init_push_context(struct nvc0_context *nvc0, struct push_context *ctx)
ctx->chan = nvc0->screen->base.channel;
ctx->translate = nvc0->vertex->translate;
if (likely(nvc0->vertex->num_elements < 32))
ctx->need_vertex_id = nvc0->vertprog->vp.need_vertex_id;
else
ctx->need_vertex_id = FALSE;
ctx->edgeflag.buffer = -1;
ctx->edgeflag.value = 0.5f;
if (NVC0_USING_EDGEFLAG(nvc0)) {
if (unlikely(nvc0->vertprog->vp.edgeflag < PIPE_MAX_ATTRIBS)) {
ve = &nvc0->vertex->element[nvc0->vertprog->vp.edgeflag].pipe;
ctx->edgeflag.buffer = ve->vertex_buffer_index;
ctx->edgeflag.offset = ve->src_offset;
ctx->packet_vertex_limit = 1;
} else {
ctx->edgeflag.buffer = -1;
ctx->edgeflag.offset = 0;
ctx->edgeflag.stride = 0;
ctx->edgeflag.data = NULL;
ctx->packet_vertex_limit = nvc0->vertex->vtx_per_packet_max;
if (unlikely(ctx->need_vertex_id))
ctx->packet_vertex_limit = 1;
}
ctx->vertex_words = nvc0->vertex->vtx_size;
@ -74,6 +76,17 @@ set_edgeflag(struct push_context *ctx, unsigned vtx_id)
}
}
static INLINE void
set_vertexid(struct push_context *ctx, uint32_t vtx_id)
{
#if 0
BEGIN_RING(ctx->chan, RING_3D(VERTEX_ID), 1); /* broken on nvc0 */
#else
BEGIN_RING(ctx->chan, RING_3D(VERTEX_DATA), 1); /* as last attribute */
#endif
OUT_RING (ctx->chan, vtx_id);
}
static INLINE unsigned
prim_restart_search_i08(uint8_t *elts, unsigned push, uint8_t index)
{
@ -117,7 +130,7 @@ emit_vertices_i08(struct push_context *ctx, unsigned start, unsigned count)
if (ctx->primitive_restart)
nr = prim_restart_search_i08(elts, push, ctx->restart_index);
if (unlikely(ctx->edgeflag.buffer >= 0) && nr)
if (unlikely(ctx->edgeflag.buffer >= 0) && likely(nr))
set_edgeflag(ctx, elts[0]);
size = ctx->vertex_words * nr;
@ -126,8 +139,11 @@ emit_vertices_i08(struct push_context *ctx, unsigned start, unsigned count)
ctx->translate->run_elts8(ctx->translate, elts, nr, ctx->instance_id,
ctx->chan->cur);
ctx->chan->cur += size;
if (unlikely(ctx->need_vertex_id) && likely(size))
set_vertexid(ctx, elts[0]);
count -= nr;
elts += nr;
@ -155,7 +171,7 @@ emit_vertices_i16(struct push_context *ctx, unsigned start, unsigned count)
if (ctx->primitive_restart)
nr = prim_restart_search_i16(elts, push, ctx->restart_index);
if (unlikely(ctx->edgeflag.buffer >= 0) && nr)
if (unlikely(ctx->edgeflag.buffer >= 0) && likely(nr))
set_edgeflag(ctx, elts[0]);
size = ctx->vertex_words * nr;
@ -164,8 +180,11 @@ emit_vertices_i16(struct push_context *ctx, unsigned start, unsigned count)
ctx->translate->run_elts16(ctx->translate, elts, nr, ctx->instance_id,
ctx->chan->cur);
ctx->chan->cur += size;
if (unlikely(ctx->need_vertex_id))
set_vertexid(ctx, elts[0]);
count -= nr;
elts += nr;
@ -193,7 +212,7 @@ emit_vertices_i32(struct push_context *ctx, unsigned start, unsigned count)
if (ctx->primitive_restart)
nr = prim_restart_search_i32(elts, push, ctx->restart_index);
if (unlikely(ctx->edgeflag.buffer >= 0) && nr)
if (unlikely(ctx->edgeflag.buffer >= 0) && likely(nr))
set_edgeflag(ctx, elts[0]);
size = ctx->vertex_words * nr;
@ -202,8 +221,11 @@ emit_vertices_i32(struct push_context *ctx, unsigned start, unsigned count)
ctx->translate->run_elts(ctx->translate, elts, nr, ctx->instance_id,
ctx->chan->cur);
ctx->chan->cur += size;
if (unlikely(ctx->need_vertex_id))
set_vertexid(ctx, elts[0]);
count -= nr;
elts += nr;
@ -233,6 +255,10 @@ emit_vertices_seq(struct push_context *ctx, unsigned start, unsigned count)
ctx->translate->run(ctx->translate, start, push, ctx->instance_id,
ctx->chan->cur);
ctx->chan->cur += size;
if (unlikely(ctx->need_vertex_id))
set_vertexid(ctx, start);
count -= push;
start += push;
}
@ -326,6 +352,16 @@ nvc0_push_vbo(struct nvc0_context *nvc0, const struct pipe_draw_info *info)
ctx.instance_id = info->start_instance;
ctx.prim = nvc0_prim_gl(info->mode);
if (unlikely(ctx.need_vertex_id)) {
const unsigned a = nvc0->vertex->num_elements;
BEGIN_RING(ctx.chan, RING_3D(VERTEX_ATTRIB_FORMAT(a)), 1);
OUT_RING (ctx.chan, (a << NVC0_3D_VERTEX_ATTRIB_FORMAT_BUFFER__SHIFT) |
NVC0_3D_VERTEX_ATTRIB_FORMAT_TYPE_FLOAT |
NVC0_3D_VERTEX_ATTRIB_FORMAT_SIZE_32);
BEGIN_RING(ctx.chan, RING_3D(VERTEX_ID_REPLACE), 1);
OUT_RING (ctx.chan, (((0x80 + a * 0x10) / 4) << 4) | 1);
}
while (inst_count--) {
BEGIN_RING(ctx.chan, RING_3D(VERTEX_BEGIN_GL), 1);
OUT_RING (ctx.chan, ctx.prim);
@ -355,6 +391,16 @@ nvc0_push_vbo(struct nvc0_context *nvc0, const struct pipe_draw_info *info)
if (unlikely(ctx.edgeflag.value == 0.0f))
IMMED_RING(ctx.chan, RING_3D(EDGEFLAG_ENABLE), 1);
if (unlikely(ctx.need_vertex_id)) {
const unsigned a = nvc0->vertex->num_elements;
IMMED_RING(ctx.chan, RING_3D(VERTEX_ID_REPLACE), 0);
BEGIN_RING(ctx.chan, RING_3D(VERTEX_ATTRIB_FORMAT(a)), 1);
OUT_RING (ctx.chan,
NVC0_3D_VERTEX_ATTRIB_FORMAT_CONST |
NVC0_3D_VERTEX_ATTRIB_FORMAT_TYPE_FLOAT |
NVC0_3D_VERTEX_ATTRIB_FORMAT_SIZE_32);
}
if (info->indexed)
nouveau_resource_unmap(nv04_resource(nvc0->idxbuf.buffer));

View file

@ -263,7 +263,8 @@ nvc0_vertex_arrays_validate(struct nvc0_context *nvc0)
struct nvc0_vertex_element *ve;
unsigned i;
if (unlikely(vertex->need_conversion || NVC0_USING_EDGEFLAG(nvc0))) {
if (unlikely(vertex->need_conversion) ||
unlikely(nvc0->vertprog->vp.edgeflag < PIPE_MAX_ATTRIBS)) {
nvc0->vbo_fifo = ~0;
nvc0->vbo_user = 0;
} else {