diff options
Diffstat (limited to 'src/mesa/tnl/t_vertex.c')
| -rw-r--r-- | src/mesa/tnl/t_vertex.c | 109 |
1 files changed, 102 insertions, 7 deletions
diff --git a/src/mesa/tnl/t_vertex.c b/src/mesa/tnl/t_vertex.c index 900648a..6245f70 100644 --- a/src/mesa/tnl/t_vertex.c +++ b/src/mesa/tnl/t_vertex.c @@ -871,6 +871,107 @@ static void generic_emit( GLcontext *ctx, } +#define FUSED_EMIT( NAME, COLSZ, HAVE_TEX ) \ +static void NAME( GLcontext *ctx, GLuint start, GLuint end, \ + void *dest ) \ +{ \ + struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx); \ + const struct tnl_clipspace_attr *a = vtx->attr; \ + const GLfloat * const vp = a[0].vp; \ + const GLubyte *pos_ptr = a[0].inputptr; \ + const GLubyte *col_ptr = a[1].inputptr; \ + const GLubyte *tex_ptr = HAVE_TEX ? a[2].inputptr : NULL; \ + const GLuint pos_stride = a[0].inputstride; \ + const GLuint col_stride = a[1].inputstride; \ + const GLuint tex_stride = HAVE_TEX ? a[2].inputstride : 0; \ + const GLuint pos_off = a[0].vertoffset; \ + const GLuint col_off = a[1].vertoffset; \ + const GLuint tex_off = HAVE_TEX ? a[2].vertoffset : 0; \ + const GLuint stride = vtx->vertex_size; \ + GLubyte *v = (GLubyte *)dest; \ + GLuint i; \ + \ + end -= start; \ + \ + for (i = 0; i < end; i++, v += stride) { \ + { \ + const GLfloat *in = (const GLfloat *)pos_ptr; \ + GLfloat *out = (GLfloat *)(v + pos_off); \ + \ + out[0] = vp[0] * in[0] + vp[12]; \ + out[1] = vp[5] * in[1] + vp[13]; \ + out[2] = vp[10] * in[2] + vp[14]; \ + out[3] = in[3]; \ + pos_ptr += pos_stride; \ + } \ + { \ + const GLfloat *in = (const GLfloat *)col_ptr; \ + GLchan *c = (GLchan *)(v + col_off); \ + \ + UNCLAMPED_FLOAT_TO_CHAN(c[0], in[0]); \ + UNCLAMPED_FLOAT_TO_CHAN(c[1], in[1]); \ + UNCLAMPED_FLOAT_TO_CHAN(c[2], in[2]); \ + if (COLSZ == 4) { \ + UNCLAMPED_FLOAT_TO_CHAN(c[3], in[3]); \ + } \ + else \ + c[3] = CHAN_MAX; \ + col_ptr += col_stride; \ + } \ + if (HAVE_TEX) { \ + const GLfloat *in = (const GLfloat *)tex_ptr; \ + GLfloat *out = (GLfloat *)(v + tex_off); \ + \ + out[0] = in[0]; \ + out[1] = in[1]; \ + out[2] = 0; \ + out[3] = 1; \ + tex_ptr += tex_stride; \ + } \ + } \ +} + +FUSED_EMIT( emit_viewport4_rgba3, 3, 0 ) +FUSED_EMIT( emit_viewport4_rgba4, 4, 0 ) +FUSED_EMIT( emit_viewport4_rgba3_st, 3, 1 ) +FUSED_EMIT( emit_viewport4_rgba4_st, 4, 1 ) + +#undef FUSED_EMIT + +/* Match the installed attribute map plus this flush's input vector + * sizes against the fused layouts above; anything else takes + * generic_emit. + */ +static tnl_emit_func choose_emit_func( struct tnl_clipspace *vtx, + struct vertex_buffer *VB ) +{ + const struct tnl_clipspace_attr *a = vtx->attr; + const GLuint count = vtx->attr_count; + GLuint colsz; + + if (count < 2 || count > 3 || + a[0].format != EMIT_4F_VIEWPORT || + VB->AttribPtr[a[0].attrib]->size != 4 || + a[1].attrib != VERT_ATTRIB_COLOR0 || + a[1].format != EMIT_4CHAN_4F_RGBA) + return generic_emit; + + colsz = VB->AttribPtr[a[1].attrib]->size; + if (colsz != 3 && colsz != 4) + return generic_emit; + + if (count == 3) { + if (a[2].format != EMIT_4F || + VB->AttribPtr[a[2].attrib]->size != 2) + return generic_emit; + return (colsz == 4) ? emit_viewport4_rgba4_st + : emit_viewport4_rgba3_st; + } + + return (colsz == 4) ? emit_viewport4_rgba4 : emit_viewport4_rgba3; +} + + static void generic_interp( GLcontext *ctx, GLfloat t, GLuint edst, GLuint eout, GLuint ein, @@ -1030,13 +1131,7 @@ static void do_emit( GLcontext *ctx, GLuint start, GLuint end, a[j].emit = a[j].insert[vptr->size - 1]; } - vtx->emit = 0; - - if (0) - vtx->emit = _tnl_codegen_emit(ctx); - - if (!vtx->emit) - vtx->emit = generic_emit; + vtx->emit = choose_emit_func( vtx, VB ); vtx->emit( ctx, start, end, dest ); } |
