#define W 3
-typedef void (PIPE_CDECL *run_func)( struct translate *translate,
- unsigned start,
- unsigned count,
- unsigned instance_id,
- void *output_buffer );
-
-typedef void (PIPE_CDECL *run_elts_func)( struct translate *translate,
- const unsigned *elts,
- unsigned count,
- unsigned instance_id,
- void *output_buffer );
-
struct translate_buffer {
const void *base_ptr;
unsigned stride;
+ unsigned max_index;
};
struct translate_buffer_varient {
};
+#define ELEMENT_BUFFER_INSTANCE_ID 1001
+
+
struct translate_sse {
struct translate translate;
boolean use_instancing;
unsigned instance_id;
- run_func gen_run;
- run_elts_func gen_run_elts;
-
/* these are actually known values, but putting them in a struct
* like this is helpful to keep them in sync across the file.
*/
boolean linear )
{
unsigned i;
- if (linear) {
- struct x86_reg instance_id = x86_make_disp(p->machine_EDX,
- get_offset(p, &p->instance_id));
+ struct x86_reg instance_id = x86_make_disp(p->machine_EDX,
+ get_offset(p, &p->instance_id));
- for (i = 0; i < p->nr_buffer_varients; i++) {
- struct translate_buffer_varient *varient = &p->buffer_varient[i];
- struct translate_buffer *buffer = &p->buffer[varient->buffer_index];
+ for (i = 0; i < p->nr_buffer_varients; i++) {
+ struct translate_buffer_varient *varient = &p->buffer_varient[i];
+ struct translate_buffer *buffer = &p->buffer[varient->buffer_index];
+
+ if (linear || varient->instance_divisor) {
struct x86_reg buf_stride = x86_make_disp(p->machine_EDX,
get_offset(p, &buffer->stride));
struct x86_reg buf_ptr = x86_make_disp(p->machine_EDX,
} else {
x86_mov(p->func, tmp_EAX, elt);
}
+
+ /*
+ * TODO: Respect translate_buffer::max_index.
+ */
+
x86_imul(p->func, tmp_EAX, buf_stride);
x86_add(p->func, tmp_EAX, buf_base_ptr);
/* In the linear case, keep the buffer pointer instead of the
* index number.
*/
- if (p->nr_buffer_varients == 1)
+ if (linear && p->nr_buffer_varients == 1)
x86_mov(p->func, elt, tmp_EAX);
else
x86_mov(p->func, buf_ptr, tmp_EAX);
unsigned var_idx,
struct x86_reg elt )
{
+ if (var_idx == ELEMENT_BUFFER_INSTANCE_ID) {
+ return x86_make_disp(p->machine_EDX,
+ get_offset(p, &p->instance_id));
+ }
if (linear && p->nr_buffer_varients == 1) {
return p->idx_EBX;
}
- else if (linear) {
+ else if (linear || p->buffer_varient[var_idx].instance_divisor) {
struct x86_reg ptr = p->tmp_EAX;
struct x86_reg buf_ptr =
x86_make_disp(p->machine_EDX,
static void translate_sse_set_buffer( struct translate *translate,
unsigned buf,
const void *ptr,
- unsigned stride )
+ unsigned stride,
+ unsigned max_index )
{
struct translate_sse *p = (struct translate_sse *)translate;
if (buf < p->nr_buffers) {
p->buffer[buf].base_ptr = (char *)ptr;
p->buffer[buf].stride = stride;
+ p->buffer[buf].max_index = max_index;
}
if (0) debug_printf("%s %d/%d: %p %d\n",
FREE(p);
}
-static void PIPE_CDECL translate_sse_run_elts( struct translate *translate,
- const unsigned *elts,
- unsigned count,
- void *output_buffer )
-{
- struct translate_sse *p = (struct translate_sse *)translate;
-
- p->gen_run_elts( translate,
- elts,
- count,
- 0,
- output_buffer );
-}
-
-static void PIPE_CDECL translate_sse_run( struct translate *translate,
- unsigned start,
- unsigned count,
- unsigned instance_id,
- void *output_buffer )
-{
- struct translate_sse *p = (struct translate_sse *)translate;
-
- p->gen_run( translate,
- start,
- count,
- instance_id,
- output_buffer );
-}
-
struct translate *translate_sse2_create( const struct translate_key *key )
{
p->translate.key = *key;
p->translate.release = translate_sse_release;
p->translate.set_buffer = translate_sse_set_buffer;
- p->translate.run_elts = translate_sse_run_elts;
- p->translate.run = translate_sse_run;
for (i = 0; i < key->nr_elements; i++) {
- unsigned j;
+ if (key->element[i].type == TRANSLATE_ELEMENT_NORMAL) {
+ unsigned j;
- p->nr_buffers = MAX2( p->nr_buffers, key->element[i].input_buffer + 1 );
+ p->nr_buffers = MAX2(p->nr_buffers, key->element[i].input_buffer + 1);
- if (key->element[i].instance_divisor) {
- p->use_instancing = TRUE;
- }
+ if (key->element[i].instance_divisor) {
+ p->use_instancing = TRUE;
+ }
- /*
- * Map vertex element to vertex buffer varient.
- */
- for (j = 0; j < p->nr_buffer_varients; j++) {
- if (p->buffer_varient[j].buffer_index == key->element[i].input_buffer &&
- p->buffer_varient[j].instance_divisor == key->element[i].instance_divisor) {
- break;
+ /*
+ * Map vertex element to vertex buffer varient.
+ */
+ for (j = 0; j < p->nr_buffer_varients; j++) {
+ if (p->buffer_varient[j].buffer_index == key->element[i].input_buffer &&
+ p->buffer_varient[j].instance_divisor == key->element[i].instance_divisor) {
+ break;
+ }
}
+ if (j == p->nr_buffer_varients) {
+ p->buffer_varient[j].buffer_index = key->element[i].input_buffer;
+ p->buffer_varient[j].instance_divisor = key->element[i].instance_divisor;
+ p->nr_buffer_varients++;
+ }
+ p->element_to_buffer_varient[i] = j;
+ } else {
+ assert(key->element[i].type == TRANSLATE_ELEMENT_INSTANCE_ID);
+
+ p->element_to_buffer_varient[i] = ELEMENT_BUFFER_INSTANCE_ID;
}
- if (j == p->nr_buffer_varients) {
- p->buffer_varient[j].buffer_index = key->element[i].input_buffer;
- p->buffer_varient[j].instance_divisor = key->element[i].instance_divisor;
- p->nr_buffer_varients++;
- }
- p->element_to_buffer_varient[i] = j;
}
if (0) debug_printf("nr_buffers: %d\n", p->nr_buffers);
if (!build_vertex_emit(p, &p->elt_func, FALSE))
goto fail;
- p->gen_run = (run_func)x86_get_func(&p->linear_func);
- if (p->gen_run == NULL)
+ p->translate.run = (void*)x86_get_func(&p->linear_func);
+ if (p->translate.run == NULL)
goto fail;
- p->gen_run_elts = (run_elts_func)x86_get_func(&p->elt_func);
- if (p->gen_run_elts == NULL)
+ p->translate.run_elts = (void*)x86_get_func(&p->elt_func);
+ if (p->translate.run_elts == NULL)
goto fail;
return &p->translate;