gallium: add a couple of hardwired vertex fetch functions

This commit is contained in:
Keith Whitwell 2008-01-28 12:40:29 +00:00 committed by Ben Skeggs
parent f7e64c323f
commit bb37e7f591
3 changed files with 141 additions and 30 deletions

View file

@ -141,6 +141,10 @@ struct draw_vertex_shader {
/* Internal function for vertex fetch.
*/
typedef void (*fetch_func)(const void *ptr, float *attrib);
typedef void (*full_fetch_func)( struct draw_context *draw,
struct tgsi_exec_machine *machine,
const unsigned *elts,
unsigned count );
@ -210,6 +214,7 @@ struct draw_context
unsigned pitch[PIPE_ATTRIB_MAX];
fetch_func fetch[PIPE_ATTRIB_MAX];
unsigned nr_attrs;
full_fetch_func fetch_func;
} vertex_fetch;
/* Post-tnl vertex cache:
@ -287,10 +292,6 @@ extern void draw_vertex_shader_queue_flush_llvm( struct draw_context *draw );
struct tgsi_exec_machine;
extern void draw_update_vertex_fetch( struct draw_context *draw );
extern void draw_vertex_fetch( struct draw_context *draw,
struct tgsi_exec_machine *machine,
const unsigned *elts,
unsigned count );
#define DRAW_FLUSH_SHADER_QUEUE 0x1 /* sized not to overflow, never raised */

View file

@ -320,42 +320,101 @@ transpose_4x4( float *out, const float *in )
}
void draw_update_vertex_fetch( struct draw_context *draw )
static void fetch_xyz_rgb( struct draw_context *draw,
struct tgsi_exec_machine *machine,
const unsigned *elts,
unsigned count )
{
unsigned nr_attrs, i;
assert(count <= 4);
// _mesa_printf("%s\n", __FUNCTION__);
/* this may happend during context init */
if (!draw->vertex_shader)
return;
nr_attrs = draw->vertex_shader->state->num_inputs;
/* loop over vertex attributes (vertex shader inputs)
*/
for (i = 0; i < nr_attrs; i++) {
unsigned buf = draw->vertex_element[i].vertex_buffer_index;
enum pipe_format format = draw->vertex_element[i].src_format;
const unsigned *pitch = draw->vertex_fetch.pitch;
const ubyte **src = draw->vertex_fetch.src_ptr;
int i;
draw->vertex_fetch.src_ptr[i] = (const ubyte *) draw->user.vbuffer[buf] +
draw->vertex_buffer[buf].buffer_offset +
draw->vertex_element[i].src_offset;
for (i = 0; i < 4; i++) {
{
const float *in = (const float *)(src[0] + elts[i] * pitch[0]);
float *out = &machine->Inputs[0].xyzw[0].f[i];
out[0] = in[0];
out[4] = in[1];
out[8] = in[2];
out[12] = 1.0f;
}
draw->vertex_fetch.pitch[i] = draw->vertex_buffer[buf].pitch;
draw->vertex_fetch.fetch[i] = get_fetch_func( format );
{
const float *in = (const float *)(src[1] + elts[i] * pitch[1]);
float *out = &machine->Inputs[1].xyzw[0].f[i];
out[0] = in[0];
out[4] = in[1];
out[8] = in[2];
out[12] = 1.0f;
}
}
draw->vertex_fetch.nr_attrs = nr_attrs;
}
static void fetch_xyz_rgb_st( struct draw_context *draw,
struct tgsi_exec_machine *machine,
const unsigned *elts,
unsigned count )
{
assert(count <= 4);
/* loop over vertex attributes (vertex shader inputs)
*/
const unsigned *pitch = draw->vertex_fetch.pitch;
const ubyte **src = draw->vertex_fetch.src_ptr;
int i;
for (i = 0; i < 4; i++) {
{
const float *in = (const float *)(src[0] + elts[i] * pitch[0]);
float *out = &machine->Inputs[0].xyzw[0].f[i];
out[0] = in[0];
out[4] = in[1];
out[8] = in[2];
out[12] = 1.0f;
}
{
const float *in = (const float *)(src[1] + elts[i] * pitch[1]);
float *out = &machine->Inputs[1].xyzw[0].f[i];
out[0] = in[0];
out[4] = in[1];
out[8] = in[2];
out[12] = 1.0f;
}
{
const float *in = (const float *)(src[2] + elts[i] * pitch[2]);
float *out = &machine->Inputs[1].xyzw[0].f[i];
out[0] = in[0];
out[4] = in[1];
out[8] = 0.0f;
out[12] = 1.0f;
}
}
}
/**
* Fetch vertex attributes for 'count' vertices.
*/
void draw_vertex_fetch( struct draw_context *draw,
struct tgsi_exec_machine *machine,
const unsigned *elts,
unsigned count )
static void generic_vertex_fetch( struct draw_context *draw,
struct tgsi_exec_machine *machine,
const unsigned *elts,
unsigned count )
{
unsigned nr_attrs = draw->vertex_fetch.nr_attrs;
unsigned attr;
@ -402,3 +461,50 @@ void draw_vertex_fetch( struct draw_context *draw,
}
}
void draw_update_vertex_fetch( struct draw_context *draw )
{
unsigned nr_attrs, i;
// _mesa_printf("%s\n", __FUNCTION__);
/* this may happend during context init */
if (!draw->vertex_shader)
return;
nr_attrs = draw->vertex_shader->state->num_inputs;
for (i = 0; i < nr_attrs; i++) {
unsigned buf = draw->vertex_element[i].vertex_buffer_index;
enum pipe_format format = draw->vertex_element[i].src_format;
draw->vertex_fetch.src_ptr[i] = (const ubyte *) draw->user.vbuffer[buf] +
draw->vertex_buffer[buf].buffer_offset +
draw->vertex_element[i].src_offset;
draw->vertex_fetch.pitch[i] = draw->vertex_buffer[buf].pitch;
draw->vertex_fetch.fetch[i] = get_fetch_func( format );
}
draw->vertex_fetch.nr_attrs = nr_attrs;
draw->vertex_fetch.fetch_func = generic_vertex_fetch;
switch (nr_attrs) {
case 2:
if (draw->vertex_element[0].src_format == PIPE_FORMAT_R32G32B32_FLOAT &&
draw->vertex_element[1].src_format == PIPE_FORMAT_R32G32B32_FLOAT)
draw->vertex_fetch.fetch_func = fetch_xyz_rgb;
break;
case 3:
if (draw->vertex_element[0].src_format == PIPE_FORMAT_R32G32B32_FLOAT &&
draw->vertex_element[1].src_format == PIPE_FORMAT_R32G32B32_FLOAT &&
draw->vertex_element[1].src_format == PIPE_FORMAT_R32G32_FLOAT)
draw->vertex_fetch.fetch_func = fetch_xyz_rgb_st;
break;
default:
break;
}
}

View file

@ -110,7 +110,7 @@ run_vertex_program(struct draw_context *draw,
machine->Inputs = ALIGN16_ASSIGN(inputs);
machine->Outputs = ALIGN16_ASSIGN(outputs);
draw_vertex_fetch( draw, machine, elts, count );
draw->vertex_fetch.fetch_func( draw, machine, elts, count );
/* run shader */
#if defined(__i386__) || defined(__386__)
@ -219,14 +219,18 @@ draw_vertex_shader_queue_flush(struct draw_context *draw)
for (i = 0; i < draw->vs.queue_nr; i += 4) {
struct vertex_header *dests[4];
unsigned elts[4];
int n;
int n = MIN2(4, draw->vs.queue_nr - i);
for (j = 0; j < 4; j++) {
for (j = 0; j < n; j++) {
elts[j] = draw->vs.queue[i + j].elt;
dests[j] = draw->vs.queue[i + j].dest;
}
n = MIN2(4, draw->vs.queue_nr - i);
for ( ; j < 4; j++) {
elts[j] = elts[0];
dests[j] = dests[0];
}
assert(n > 0);
assert(n <= 4);