This sub-struct collects the incoming user-provided data/pointers in one place. Ex: draw->mapped_vbuffer becomes draw->user.vbuffer, etc.tags/mesa_20090313
{ | { | ||||
draw_flush( draw ); | draw_flush( draw ); | ||||
draw->mapped_vbuffer[attr] = buffer; | |||||
draw->user.vbuffer[attr] = buffer; | |||||
} | } | ||||
{ | { | ||||
draw_flush( draw ); | draw_flush( draw ); | ||||
draw->mapped_constants = buffer; | |||||
draw->user.constants = buffer; | |||||
} | } | ||||
draw_flush( draw ); | draw_flush( draw ); | ||||
assert(index < PIPE_MAX_FEEDBACK_ATTRIBS); | assert(index < PIPE_MAX_FEEDBACK_ATTRIBS); | ||||
draw->mapped_feedback_buffer[index] = buffer; | |||||
draw->mapped_feedback_buffer_size[index] = size; /* in bytes */ | |||||
draw->user.feedback_buffer[index] = buffer; | |||||
draw->user.feedback_buffer_size[index] = size; /* in bytes */ | |||||
} | } | ||||
vertex_size += feedback->size[i]; | vertex_size += feedback->size[i]; | ||||
} | } | ||||
/* compute max number of vertices we can feedback */ | /* compute max number of vertices we can feedback */ | ||||
fs->max_vert_emit = stage->draw->mapped_feedback_buffer_size[0] | |||||
fs->max_vert_emit = stage->draw->user.feedback_buffer_size[0] | |||||
/ sizeof(float) / vertex_size; | / sizeof(float) / vertex_size; | ||||
fs->dest[0] = (float *) stage->draw->mapped_feedback_buffer[0]; | |||||
fs->dest[0] = (float *) stage->draw->user.feedback_buffer[0]; | |||||
} | } | ||||
else { | else { | ||||
uint i; | uint i; | ||||
uint max = ~0; | uint max = ~0; | ||||
for (i = 0; i < feedback->num_attribs; i++) { | for (i = 0; i < feedback->num_attribs; i++) { | ||||
uint n = stage->draw->mapped_feedback_buffer_size[i] | |||||
uint n = stage->draw->user.feedback_buffer_size[i] | |||||
/ sizeof(float) / feedback->size[i]; | / sizeof(float) / feedback->size[i]; | ||||
if (n < max) | if (n < max) | ||||
max = n; | max = n; | ||||
fs->dest[i] = (float *) stage->draw->mapped_feedback_buffer[i]; | |||||
fs->dest[i] = (float *) stage->draw->user.feedback_buffer[i]; | |||||
} | } | ||||
fs->max_vert_emit = max; | fs->max_vert_emit = max; | ||||
} | } |
printf("Flushing with %d prims, %d verts\n", | printf("Flushing with %d prims, %d verts\n", | ||||
draw->pq.queue_nr, draw->vs.queue_nr); | draw->pq.queue_nr, draw->vs.queue_nr); | ||||
/* Make sure all vertices are available: | |||||
/* Make sure all vertices are available/shaded: | |||||
*/ | */ | ||||
if (draw->vs.queue_nr) | if (draw->vs.queue_nr) | ||||
draw_vertex_shader_queue_flush(draw); | draw_vertex_shader_queue_flush(draw); |
struct pipe_vertex_buffer feedback_buffer[PIPE_ATTRIB_MAX]; | struct pipe_vertex_buffer feedback_buffer[PIPE_ATTRIB_MAX]; | ||||
struct pipe_vertex_element feedback_element[PIPE_ATTRIB_MAX]; | struct pipe_vertex_element feedback_element[PIPE_ATTRIB_MAX]; | ||||
/** The mapped vertex element/index buffer */ | |||||
const void *mapped_elts; | |||||
unsigned eltSize; /**< bytes per index (0, 1, 2 or 4) */ | |||||
/** The mapped vertex arrays */ | |||||
const void *mapped_vbuffer[PIPE_ATTRIB_MAX]; | |||||
/** The mapped constant buffers (for vertex shader) */ | |||||
const void *mapped_constants; | |||||
/** The mapped vertex element/index buffer */ | |||||
void *mapped_feedback_buffer[PIPE_MAX_FEEDBACK_ATTRIBS]; | |||||
uint mapped_feedback_buffer_size[PIPE_MAX_FEEDBACK_ATTRIBS]; /* in bytes */ | |||||
/* user-space vertex data, buffers */ | |||||
struct { | |||||
/** vertex element/index buffer (ex: glDrawElements) */ | |||||
const void *elts; | |||||
/** bytes per index (0, 1, 2 or 4) */ | |||||
unsigned eltSize; | |||||
/** vertex arrays */ | |||||
const void *vbuffer[PIPE_ATTRIB_MAX]; | |||||
/** constant buffer (for vertex shader) */ | |||||
const void *constants; | |||||
/** The vertex feedback buffer */ | |||||
void *feedback_buffer[PIPE_MAX_FEEDBACK_ATTRIBS]; | |||||
uint feedback_buffer_size[PIPE_MAX_FEEDBACK_ATTRIBS]; /* in bytes */ | |||||
} user; | |||||
/* Clip derived state: | /* Clip derived state: | ||||
*/ | */ | ||||
struct vertex_header *vertex[VCACHE_SIZE + VCACHE_OVERFLOW]; | struct vertex_header *vertex[VCACHE_SIZE + VCACHE_OVERFLOW]; | ||||
unsigned overflow; | unsigned overflow; | ||||
/** To find space in the vertex cache: */ | |||||
struct vertex_header *(*get_vertex)( struct draw_context *draw, | struct vertex_header *(*get_vertex)( struct draw_context *draw, | ||||
unsigned i ); | unsigned i ); | ||||
} vcache; | } vcache; | ||||
/* Prim pipeline queue: | /* Prim pipeline queue: | ||||
*/ | */ | ||||
struct { | struct { | ||||
/* Need to queue up primitives until their vertices have been | /* Need to queue up primitives until their vertices have been | ||||
* transformed by a vs queue flush. | * transformed by a vs queue flush. | ||||
*/ | */ |
} | } | ||||
/* Check if vertex is in cache, otherwise add it. It won't go through | |||||
/** | |||||
* Check if vertex is in cache, otherwise add it. It won't go through | |||||
* VS yet, not until there is a flush operation or the VS queue fills up. | * VS yet, not until there is a flush operation or the VS queue fills up. | ||||
* | |||||
* Note that cache entries are basically just two pointers: the first | |||||
* an index into the user's vertex arrays, the second a location in | |||||
* the vertex shader cache for the post-transformed vertex. | |||||
* | |||||
* \return pointer to location of (post-transformed) vertex header in the cache | |||||
*/ | */ | ||||
static struct vertex_header *get_vertex( struct draw_context *draw, | static struct vertex_header *get_vertex( struct draw_context *draw, | ||||
unsigned i ) | unsigned i ) | ||||
static struct vertex_header *get_uint_elt_vertex( struct draw_context *draw, | static struct vertex_header *get_uint_elt_vertex( struct draw_context *draw, | ||||
unsigned i ) | unsigned i ) | ||||
{ | { | ||||
const unsigned *elts = (const unsigned *) draw->mapped_elts; | |||||
const unsigned *elts = (const unsigned *) draw->user.elts; | |||||
return get_vertex( draw, elts[i] ); | return get_vertex( draw, elts[i] ); | ||||
} | } | ||||
static struct vertex_header *get_ushort_elt_vertex( struct draw_context *draw, | static struct vertex_header *get_ushort_elt_vertex( struct draw_context *draw, | ||||
unsigned i ) | unsigned i ) | ||||
{ | { | ||||
const ushort *elts = (const ushort *) draw->mapped_elts; | |||||
const ushort *elts = (const ushort *) draw->user.elts; | |||||
return get_vertex( draw, elts[i] ); | return get_vertex( draw, elts[i] ); | ||||
} | } | ||||
static struct vertex_header *get_ubyte_elt_vertex( struct draw_context *draw, | static struct vertex_header *get_ubyte_elt_vertex( struct draw_context *draw, | ||||
unsigned i ) | unsigned i ) | ||||
{ | { | ||||
const ubyte *elts = (const ubyte *) draw->mapped_elts; | |||||
const ubyte *elts = (const ubyte *) draw->user.elts; | |||||
return get_vertex( draw, elts[i] ); | return get_vertex( draw, elts[i] ); | ||||
} | } | ||||
default: | default: | ||||
assert(0); | assert(0); | ||||
} | } | ||||
draw->mapped_elts = elements; | |||||
draw->eltSize = eltSize; | |||||
draw->user.elts = elements; | |||||
draw->user.eltSize = eltSize; | |||||
} | } | ||||
unsigned buf = draw->vertex_element[attr].vertex_buffer_index; | unsigned buf = draw->vertex_element[attr].vertex_buffer_index; | ||||
const void *src | const void *src | ||||
= (const void *) ((const ubyte *) draw->mapped_vbuffer[buf] | |||||
= (const void *) ((const ubyte *) draw->user.vbuffer[buf] | |||||
+ draw->vertex_buffer[buf].buffer_offset | + draw->vertex_buffer[buf].buffer_offset | ||||
+ draw->vertex_element[attr].src_offset | + draw->vertex_element[attr].src_offset | ||||
+ elts[j] * draw->vertex_buffer[buf].pitch); | + elts[j] * draw->vertex_buffer[buf].pitch); |
== TGSI_SEMANTIC_POSITION); | == TGSI_SEMANTIC_POSITION); | ||||
/* Consts does not require 16 byte alignment. */ | /* Consts does not require 16 byte alignment. */ | ||||
machine->Consts = (float (*)[4]) draw->mapped_constants; | |||||
machine->Consts = (float (*)[4]) draw->user.constants; | |||||
machine->Inputs = ALIGN16_ASSIGN(inputs); | machine->Inputs = ALIGN16_ASSIGN(inputs); | ||||
machine->Outputs = ALIGN16_ASSIGN(outputs); | machine->Outputs = ALIGN16_ASSIGN(outputs); | ||||
/** | /** | ||||
* Run the vertex shader on all vertices in the vertex queue. | |||||
* Called by the draw module when the vertx cache needs to be flushed. | * Called by the draw module when the vertx cache needs to be flushed. | ||||
* This involves running the vertex shader. | |||||
*/ | */ | ||||
void draw_vertex_shader_queue_flush( struct draw_context *draw ) | void draw_vertex_shader_queue_flush( struct draw_context *draw ) | ||||
{ | { |
unsigned buf = draw->vertex_element[attr].vertex_buffer_index; | unsigned buf = draw->vertex_element[attr].vertex_buffer_index; | ||||
const void *src | const void *src | ||||
= (const void *) ((const ubyte *) draw->mapped_vbuffer[buf] | |||||
= (const void *) ((const ubyte *) draw->user.vbuffer[buf] | |||||
+ draw->vertex_buffer[buf].buffer_offset | + draw->vertex_buffer[buf].buffer_offset | ||||
+ draw->vertex_element[attr].src_offset | + draw->vertex_element[attr].src_offset | ||||
+ elt * draw->vertex_buffer[buf].pitch); | + elt * draw->vertex_buffer[buf].pitch); | ||||
struct vertex_header *dests[VS_QUEUE_LENGTH]; | struct vertex_header *dests[VS_QUEUE_LENGTH]; | ||||
float inputs[VS_QUEUE_LENGTH][PIPE_MAX_SHADER_INPUTS][4]; | float inputs[VS_QUEUE_LENGTH][PIPE_MAX_SHADER_INPUTS][4]; | ||||
float outputs[VS_QUEUE_LENGTH][PIPE_MAX_SHADER_INPUTS][4]; | float outputs[VS_QUEUE_LENGTH][PIPE_MAX_SHADER_INPUTS][4]; | ||||
float (*consts)[4] = (float (*)[4]) draw->mapped_constants; | |||||
float (*consts)[4] = (float (*)[4]) draw->user.constants; | |||||
struct gallivm_prog *prog = draw->vertex_shader->llvm_prog; | struct gallivm_prog *prog = draw->vertex_shader->llvm_prog; | ||||
const float *scale = draw->viewport.scale; | const float *scale = draw->viewport.scale; | ||||
const float *trans = draw->viewport.translate; | const float *trans = draw->viewport.translate; |