summaryrefslogtreecommitdiff
path: root/src/gallium/auxiliary/draw
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/auxiliary/draw')
-rw-r--r--src/gallium/auxiliary/draw/draw_aaline.c76
-rw-r--r--src/gallium/auxiliary/draw/draw_aapoint.c24
-rw-r--r--src/gallium/auxiliary/draw/draw_context.c24
-rw-r--r--src/gallium/auxiliary/draw/draw_context.h12
-rw-r--r--src/gallium/auxiliary/draw/draw_passthrough.c2
-rw-r--r--src/gallium/auxiliary/draw/draw_prim.c178
-rw-r--r--src/gallium/auxiliary/draw/draw_private.h16
-rw-r--r--src/gallium/auxiliary/draw/draw_pstipple.c41
-rw-r--r--src/gallium/auxiliary/draw/draw_pt.c2
-rw-r--r--src/gallium/auxiliary/draw/draw_pt_fetch_emit.c2
-rw-r--r--src/gallium/auxiliary/draw/draw_pt_vcache.c2
-rw-r--r--src/gallium/auxiliary/draw/draw_validate.c99
-rw-r--r--src/gallium/auxiliary/draw/draw_vertex_fetch.c6
-rw-r--r--src/gallium/auxiliary/draw/draw_vf.c4
-rw-r--r--src/gallium/auxiliary/draw/draw_vf.h2
-rw-r--r--src/gallium/auxiliary/draw/draw_vs_exec.c4
-rw-r--r--src/gallium/auxiliary/draw/draw_vs_llvm.c4
-rw-r--r--src/gallium/auxiliary/draw/draw_vs_sse.c4
18 files changed, 334 insertions, 168 deletions
diff --git a/src/gallium/auxiliary/draw/draw_aaline.c b/src/gallium/auxiliary/draw/draw_aaline.c
index cc1873abad..e8d2a45102 100644
--- a/src/gallium/auxiliary/draw/draw_aaline.c
+++ b/src/gallium/auxiliary/draw/draw_aaline.c
@@ -61,6 +61,8 @@ struct aaline_fragment_shader
void *aaline_fs;
void *aapoint_fs; /* not yet */
void *sprite_fs; /* not yet */
+ uint sampler_unit;
+ int generic_attrib; /**< texcoord/generic used for texture */
};
@@ -117,7 +119,8 @@ struct aa_transform_context {
struct tgsi_transform_context base;
uint tempsUsed; /**< bitmask */
int colorOutput; /**< which output is the primary color */
- int maxSampler; /**< max sampler index found */
+ uint samplersUsed; /**< bitfield of samplers used */
+ int freeSampler; /** an available sampler for the pstipple */
int maxInput, maxGeneric; /**< max input index found */
int colorTemp, texTemp; /**< temp registers */
boolean firstInstruction;
@@ -140,8 +143,11 @@ aa_transform_decl(struct tgsi_transform_context *ctx,
aactx->colorOutput = decl->u.DeclarationRange.First;
}
else if (decl->Declaration.File == TGSI_FILE_SAMPLER) {
- if ((int) decl->u.DeclarationRange.Last > aactx->maxSampler)
- aactx->maxSampler = decl->u.DeclarationRange.Last + 1;
+ uint i;
+ for (i = decl->u.DeclarationRange.First;
+ i <= decl->u.DeclarationRange.Last; i++) {
+ aactx->samplersUsed |= 1 << i;
+ }
}
else if (decl->Declaration.File == TGSI_FILE_INPUT) {
if ((int) decl->u.DeclarationRange.Last > aactx->maxInput)
@@ -164,6 +170,21 @@ aa_transform_decl(struct tgsi_transform_context *ctx,
/**
+ * Find the lowest zero bit in the given word, or -1 if bitfield is all ones.
+ */
+static int
+free_bit(uint bitfield)
+{
+ int i;
+ for (i = 0; i < 32; i++) {
+ if ((bitfield & (1 << i)) == 0)
+ return i;
+ }
+ return -1;
+}
+
+
+/**
* TGSI instruction transform callback.
* Replace writes to result.color w/ a temp reg.
* Upon END instruction, insert texture sampling code for antialiasing.
@@ -180,6 +201,11 @@ aa_transform_inst(struct tgsi_transform_context *ctx,
struct tgsi_full_declaration decl;
uint i;
+ /* find free sampler */
+ aactx->freeSampler = free_bit(aactx->samplersUsed);
+ if (aactx->freeSampler >= PIPE_MAX_SAMPLERS)
+ aactx->freeSampler = PIPE_MAX_SAMPLERS - 1;
+
/* find two free temp regs */
for (i = 0; i < 32; i++) {
if ((aactx->tempsUsed & (1 << i)) == 0) {
@@ -212,7 +238,7 @@ aa_transform_inst(struct tgsi_transform_context *ctx,
decl = tgsi_default_full_declaration();
decl.Declaration.File = TGSI_FILE_SAMPLER;
decl.u.DeclarationRange.First =
- decl.u.DeclarationRange.Last = aactx->maxSampler + 1;
+ decl.u.DeclarationRange.Last = aactx->freeSampler;
ctx->emit_declaration(ctx, &decl);
/* declare new temp regs */
@@ -246,7 +272,7 @@ aa_transform_inst(struct tgsi_transform_context *ctx,
newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_INPUT;
newInst.FullSrcRegisters[0].SrcRegister.Index = aactx->maxInput + 1;
newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_SAMPLER;
- newInst.FullSrcRegisters[1].SrcRegister.Index = aactx->maxSampler + 1;
+ newInst.FullSrcRegisters[1].SrcRegister.Index = aactx->freeSampler;
ctx->emit_instruction(ctx, &newInst);
@@ -311,7 +337,7 @@ static void
generate_aaline_fs(struct aaline_stage *aaline)
{
const struct pipe_shader_state *orig_fs = &aaline->fs->state;
- struct draw_context *draw = aaline->stage.draw;
+ //struct draw_context *draw = aaline->stage.draw;
struct pipe_shader_state aaline_fs;
struct aa_transform_context transform;
@@ -322,7 +348,6 @@ generate_aaline_fs(struct aaline_stage *aaline)
memset(&transform, 0, sizeof(transform));
transform.colorOutput = -1;
- transform.maxSampler = -1;
transform.maxInput = -1;
transform.maxGeneric = -1;
transform.colorTemp = -1;
@@ -340,14 +365,12 @@ generate_aaline_fs(struct aaline_stage *aaline)
tgsi_dump(aaline_fs.tokens, 0);
#endif
+ aaline->fs->sampler_unit = transform.freeSampler;
+
aaline->fs->aaline_fs
= aaline->driver_create_fs_state(aaline->pipe, &aaline_fs);
- /* advertise the extra post-transform vertex attributes which will have
- * the texcoords.
- */
- draw->extra_vp_outputs.semantic_name = TGSI_SEMANTIC_GENERIC;
- draw->extra_vp_outputs.semantic_index = transform.maxGeneric + 1;
+ aaline->fs->generic_attrib = transform.maxGeneric + 1;
}
@@ -602,7 +625,7 @@ aaline_first_line(struct draw_stage *stage, struct prim_header *header)
auto struct aaline_stage *aaline = aaline_stage(stage);
struct draw_context *draw = stage->draw;
struct pipe_context *pipe = aaline->pipe;
- uint num = MAX2(aaline->num_textures, aaline->num_samplers);
+ uint num_samplers;
assert(draw->rasterizer->line_smooth);
@@ -611,20 +634,31 @@ aaline_first_line(struct draw_stage *stage, struct prim_header *header)
else
aaline->half_line_width = 0.5f * draw->rasterizer->line_width;
+ /*
+ * Bind (generate) our fragprog, sampler and texture
+ */
+ bind_aaline_fragment_shader(aaline);
+
+ /* update vertex attrib info */
aaline->tex_slot = draw->num_vs_outputs;
assert(aaline->tex_slot > 0); /* output[0] is vertex pos */
+
+ /* advertise the extra post-transformed vertex attribute */
+ draw->extra_vp_outputs.semantic_name = TGSI_SEMANTIC_GENERIC;
+ draw->extra_vp_outputs.semantic_index = aaline->fs->generic_attrib;
draw->extra_vp_outputs.slot = aaline->tex_slot;
- /*
- * Bind our fragprog, sampler and texture
- */
- bind_aaline_fragment_shader(aaline);
+ /* how many samplers? */
+ /* we'll use sampler/texture[pstip->sampler_unit] for the stipple */
+ num_samplers = MAX2(aaline->num_textures, aaline->num_samplers);
+ num_samplers = MAX2(num_samplers, aaline->fs->sampler_unit + 1);
- aaline->state.sampler[num] = aaline->sampler_cso;
- pipe_texture_reference(&aaline->state.texture[num], aaline->texture);
+ aaline->state.sampler[aaline->fs->sampler_unit] = aaline->sampler_cso;
+ pipe_texture_reference(&aaline->state.texture[aaline->fs->sampler_unit],
+ aaline->texture);
- aaline->driver_bind_sampler_states(pipe, num + 1, aaline->state.sampler);
- aaline->driver_set_sampler_textures(pipe, num + 1, aaline->state.texture);
+ aaline->driver_bind_sampler_states(pipe, num_samplers, aaline->state.sampler);
+ aaline->driver_set_sampler_textures(pipe, num_samplers, aaline->state.texture);
/* now really draw first line */
stage->line = aaline_line;
diff --git a/src/gallium/auxiliary/draw/draw_aapoint.c b/src/gallium/auxiliary/draw/draw_aapoint.c
index 67a7a8ebab..fcebe3e7a0 100644
--- a/src/gallium/auxiliary/draw/draw_aapoint.c
+++ b/src/gallium/auxiliary/draw/draw_aapoint.c
@@ -68,6 +68,7 @@ struct aapoint_fragment_shader
struct pipe_shader_state state;
void *driver_fs; /**< the regular shader */
void *aapoint_fs; /**< the aa point-augmented shader */
+ int generic_attrib; /**< The generic input attrib/texcoord we'll use */
};
@@ -486,7 +487,6 @@ static void
generate_aapoint_fs(struct aapoint_stage *aapoint)
{
const struct pipe_shader_state *orig_fs = &aapoint->fs->state;
- struct draw_context *draw = aapoint->stage.draw;
struct pipe_shader_state aapoint_fs;
struct aa_transform_context transform;
@@ -510,18 +510,16 @@ generate_aapoint_fs(struct aapoint_stage *aapoint)
MAX, &transform.base);
#if 0 /* DEBUG */
+ printf("draw_aapoint, orig shader:\n");
tgsi_dump(orig_fs->tokens, 0);
+ printf("draw_aapoint, new shader:\n");
tgsi_dump(aapoint_fs.tokens, 0);
#endif
aapoint->fs->aapoint_fs
= aapoint->driver_create_fs_state(aapoint->pipe, &aapoint_fs);
- /* advertise the extra post-transform vertex attributes which will have
- * the texcoords.
- */
- draw->extra_vp_outputs.semantic_name = TGSI_SEMANTIC_GENERIC;
- draw->extra_vp_outputs.semantic_index = transform.maxGeneric + 1;
+ aapoint->fs->generic_attrib = transform.maxGeneric + 1;
}
@@ -675,15 +673,19 @@ aapoint_first_point(struct draw_stage *stage, struct prim_header *header)
else
aapoint->radius = 0.5f * draw->rasterizer->point_size;
- aapoint->tex_slot = draw->num_vs_outputs;
- assert(aapoint->tex_slot > 0); /* output[0] is vertex pos */
- draw->extra_vp_outputs.slot = aapoint->tex_slot;
-
/*
- * Bind our fragprog.
+ * Bind (generate) our fragprog.
*/
bind_aapoint_fragment_shader(aapoint);
+ /* update vertex attrib info */
+ aapoint->tex_slot = draw->num_vs_outputs;
+ assert(aapoint->tex_slot > 0); /* output[0] is vertex pos */
+
+ draw->extra_vp_outputs.semantic_name = TGSI_SEMANTIC_GENERIC;
+ draw->extra_vp_outputs.semantic_index = aapoint->fs->generic_attrib;
+ draw->extra_vp_outputs.slot = aapoint->tex_slot;
+
/* find psize slot in post-transform vertex */
aapoint->psize_slot = -1;
if (draw->rasterizer->point_size_per_vertex) {
diff --git a/src/gallium/auxiliary/draw/draw_context.c b/src/gallium/auxiliary/draw/draw_context.c
index 903cc26766..10bf9f54c1 100644
--- a/src/gallium/auxiliary/draw/draw_context.c
+++ b/src/gallium/auxiliary/draw/draw_context.c
@@ -233,24 +233,28 @@ void draw_set_viewport_state( struct draw_context *draw,
void
-draw_set_vertex_buffer(struct draw_context *draw,
- unsigned attr,
- const struct pipe_vertex_buffer *buffer)
+draw_set_vertex_buffers(struct draw_context *draw,
+ unsigned count,
+ const struct pipe_vertex_buffer *buffers)
{
+ assert(count <= PIPE_MAX_ATTRIBS);
+
draw_do_flush( draw, DRAW_FLUSH_VERTEX_CACHE/*STATE_CHANGE*/ );
- assert(attr < PIPE_ATTRIB_MAX);
- draw->vertex_buffer[attr] = *buffer;
+
+ memcpy(draw->vertex_buffer, buffers, count * sizeof(buffers[0]));
}
void
-draw_set_vertex_element(struct draw_context *draw,
- unsigned attr,
- const struct pipe_vertex_element *element)
+draw_set_vertex_elements(struct draw_context *draw,
+ unsigned count,
+ const struct pipe_vertex_element *elements)
{
+ assert(count <= PIPE_MAX_ATTRIBS);
+
draw_do_flush( draw, DRAW_FLUSH_VERTEX_CACHE/*STATE_CHANGE*/ );
- assert(attr < PIPE_ATTRIB_MAX);
- draw->vertex_element[attr] = *element;
+
+ memcpy(draw->vertex_element, elements, count * sizeof(elements[0]));
}
diff --git a/src/gallium/auxiliary/draw/draw_context.h b/src/gallium/auxiliary/draw/draw_context.h
index dae687e590..84bae3bd78 100644
--- a/src/gallium/auxiliary/draw/draw_context.h
+++ b/src/gallium/auxiliary/draw/draw_context.h
@@ -138,13 +138,13 @@ void draw_delete_vertex_shader(struct draw_context *draw,
* Vertex data functions
*/
-void draw_set_vertex_buffer(struct draw_context *draw,
- unsigned attr,
- const struct pipe_vertex_buffer *buffer);
+void draw_set_vertex_buffers(struct draw_context *draw,
+ unsigned count,
+ const struct pipe_vertex_buffer *buffers);
-void draw_set_vertex_element(struct draw_context *draw,
- unsigned attr,
- const struct pipe_vertex_element *element);
+void draw_set_vertex_elements(struct draw_context *draw,
+ unsigned count,
+ const struct pipe_vertex_element *elements);
void draw_set_mapped_element_buffer( struct draw_context *draw,
unsigned eltSize, void *elements );
diff --git a/src/gallium/auxiliary/draw/draw_passthrough.c b/src/gallium/auxiliary/draw/draw_passthrough.c
index dd00894c5b..2198079a88 100644
--- a/src/gallium/auxiliary/draw/draw_passthrough.c
+++ b/src/gallium/auxiliary/draw/draw_passthrough.c
@@ -424,7 +424,7 @@ draw_passthrough_arrays(struct draw_context *draw,
debug_printf("%s %d %d %d\n", __FUNCTION__, prim, start, count);
- if (draw_need_pipeline(draw))
+ if (draw_need_pipeline(draw, prim))
return FALSE;
debug_printf("%s AAA\n", __FUNCTION__);
diff --git a/src/gallium/auxiliary/draw/draw_prim.c b/src/gallium/auxiliary/draw/draw_prim.c
index 4fe0ddc02a..ddcde01d9a 100644
--- a/src/gallium/auxiliary/draw/draw_prim.c
+++ b/src/gallium/auxiliary/draw/draw_prim.c
@@ -158,22 +158,19 @@ static INLINE void fetch_and_store(struct draw_context *draw)
void draw_do_flush( struct draw_context *draw, unsigned flags )
{
- static boolean flushing = FALSE;
-
if (0)
debug_printf("Flushing with %d verts, %d prims\n",
draw->vs.queue_nr,
draw->pq.queue_nr );
- if (!flushing) {
- flushing = TRUE;
+ if (draw->flushing)
+ return;
+
+ draw->flushing = TRUE;
if (flags >= DRAW_FLUSH_SHADER_QUEUE) {
if (draw->vs.queue_nr) {
- if (draw->rasterizer->bypass_vs)
- fetch_and_store(draw);
- else
- (*draw->shader_queue_flush)(draw);
+ (*draw->shader_queue_flush)(draw);
}
if (flags >= DRAW_FLUSH_PRIM_QUEUE) {
@@ -192,8 +189,7 @@ void draw_do_flush( struct draw_context *draw, unsigned flags )
}
}
- flushing = FALSE;
- }
+ draw->flushing = FALSE;
}
@@ -333,6 +329,8 @@ draw_prim( struct draw_context *draw,
unsigned i;
boolean unfilled = (draw->rasterizer->fill_cw != PIPE_POLYGON_MODE_FILL ||
draw->rasterizer->fill_ccw != PIPE_POLYGON_MODE_FILL);
+ boolean flatfirst =
+ (draw->rasterizer->flatshade & draw->rasterizer->flatshade_first) ? TRUE : FALSE;
// debug_printf("%s (%d) %d/%d\n", __FUNCTION__, draw->prim, start, count );
@@ -345,11 +343,21 @@ draw_prim( struct draw_context *draw,
break;
case PIPE_PRIM_LINES:
- for (i = 0; i+1 < count; i += 2) {
- do_line( draw,
- TRUE,
- start + i + 0,
- start + i + 1);
+ if (flatfirst) {
+ for (i = 0; i+1 < count; i += 2) {
+ do_line( draw,
+ TRUE,
+ start + i + 1,
+ start + i + 0);
+ }
+ }
+ else {
+ for (i = 0; i+1 < count; i += 2) {
+ do_line( draw,
+ TRUE,
+ start + i + 0,
+ start + i + 1);
+ }
}
break;
@@ -370,60 +378,120 @@ draw_prim( struct draw_context *draw,
break;
case PIPE_PRIM_LINE_STRIP:
- for (i = 1; i < count; i++) {
- do_line( draw,
- i == 1,
- start + i - 1,
- start + i );
+ if (flatfirst) {
+ for (i = 1; i < count; i++) {
+ do_line( draw,
+ i == 1,
+ start + i,
+ start + i - 1 );
+ }
+ }
+ else {
+ for (i = 1; i < count; i++) {
+ do_line( draw,
+ i == 1,
+ start + i - 1,
+ start + i );
+ }
}
break;
case PIPE_PRIM_TRIANGLES:
- if (unfilled) {
- for (i = 0; i+2 < count; i += 3) {
- do_ef_triangle( draw,
- 1,
- ~0,
- start + i + 0,
- start + i + 1,
- start + i + 2 );
- }
- }
+ if (flatfirst) {
+ if (unfilled) {
+ for (i = 0; i+2 < count; i += 3) {
+ do_ef_triangle( draw,
+ 1,
+ ~0,
+ start + i + 1,
+ start + i + 2,
+ start + i + 0 );
+ }
+ }
+ else {
+ for (i = 0; i+2 < count; i += 3) {
+ do_triangle( draw,
+ start + i + 1,
+ start + i + 2,
+ start + i + 0 );
+ }
+ }
+ }
else {
- for (i = 0; i+2 < count; i += 3) {
- do_triangle( draw,
- start + i + 0,
- start + i + 1,
- start + i + 2 );
- }
+ if (unfilled) {
+ for (i = 0; i+2 < count; i += 3) {
+ do_ef_triangle( draw,
+ 1,
+ ~0,
+ start + i + 0,
+ start + i + 1,
+ start + i + 2 );
+ }
+ }
+ else {
+ for (i = 0; i+2 < count; i += 3) {
+ do_triangle( draw,
+ start + i + 0,
+ start + i + 1,
+ start + i + 2 );
+ }
+ }
}
break;
case PIPE_PRIM_TRIANGLE_STRIP:
- for (i = 0; i+2 < count; i++) {
- if (i & 1) {
- do_triangle( draw,
- start + i + 1,
- start + i + 0,
- start + i + 2 );
- }
- else {
- do_triangle( draw,
- start + i + 0,
- start + i + 1,
- start + i + 2 );
- }
+ if (flatfirst) {
+ for (i = 0; i+2 < count; i++) {
+ if (i & 1) {
+ do_triangle( draw,
+ start + i + 2,
+ start + i + 1,
+ start + i + 0 );
+ }
+ else {
+ do_triangle( draw,
+ start + i + 1,
+ start + i + 2,
+ start + i + 0 );
+ }
+ }
+ }
+ else {
+ for (i = 0; i+2 < count; i++) {
+ if (i & 1) {
+ do_triangle( draw,
+ start + i + 1,
+ start + i + 0,
+ start + i + 2 );
+ }
+ else {
+ do_triangle( draw,
+ start + i + 0,
+ start + i + 1,
+ start + i + 2 );
+ }
+ }
}
break;
case PIPE_PRIM_TRIANGLE_FAN:
if (count >= 3) {
- for (i = 0; i+2 < count; i++) {
- do_triangle( draw,
- start + 0,
- start + i + 1,
- start + i + 2 );
- }
+ if (flatfirst) {
+ for (i = 0; i+2 < count; i++) {
+ do_triangle( draw,
+ start + i + 2,
+ start + 0,
+ start + i + 1 );
+ }
+ }
+ else {
+ for (i = 0; i+2 < count; i++) {
+ do_triangle( draw,
+ start + 0,
+ start + i + 1,
+ start + i + 2 );
+ }
+ }
}
break;
diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h
index 0c5afcacfa..8eb2f515cb 100644
--- a/src/gallium/auxiliary/draw/draw_private.h
+++ b/src/gallium/auxiliary/draw/draw_private.h
@@ -223,12 +223,13 @@ struct draw_context
} pt;
+ boolean flushing;
/* pipe state that we need: */
const struct pipe_rasterizer_state *rasterizer;
struct pipe_viewport_state viewport;
- struct pipe_vertex_buffer vertex_buffer[PIPE_ATTRIB_MAX];
- struct pipe_vertex_element vertex_element[PIPE_ATTRIB_MAX];
+ struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS];
+ struct pipe_vertex_element vertex_element[PIPE_MAX_ATTRIBS];
struct draw_vertex_shader *vertex_shader;
uint num_vs_outputs; /**< convenience, from vertex_shader */
@@ -241,7 +242,7 @@ struct draw_context
unsigned eltSize;
/** vertex arrays */
- const void *vbuffer[PIPE_ATTRIB_MAX];
+ const void *vbuffer[PIPE_MAX_ATTRIBS];
/** constant buffer (for vertex shader) */
const void *constants;
@@ -274,9 +275,9 @@ struct draw_context
/* Vertex fetch internal state
*/
struct {
- const ubyte *src_ptr[PIPE_ATTRIB_MAX];
- unsigned pitch[PIPE_ATTRIB_MAX];
- fetch_func fetch[PIPE_ATTRIB_MAX];
+ const ubyte *src_ptr[PIPE_MAX_ATTRIBS];
+ unsigned pitch[PIPE_MAX_ATTRIBS];
+ fetch_func fetch[PIPE_MAX_ATTRIBS];
unsigned nr_attrs;
full_fetch_func fetch_func;
pt_fetch_func pt_fetch;
@@ -364,7 +365,8 @@ extern void draw_vertex_shader_queue_flush( struct draw_context *draw );
extern void draw_update_vertex_fetch( struct draw_context *draw );
-extern boolean draw_need_pipeline(const struct draw_context *draw);
+extern boolean draw_need_pipeline(const struct draw_context *draw,
+ unsigned prim );
/* Passthrough mode (second attempt):
diff --git a/src/gallium/auxiliary/draw/draw_pstipple.c b/src/gallium/auxiliary/draw/draw_pstipple.c
index 9cec986640..4dddb72906 100644
--- a/src/gallium/auxiliary/draw/draw_pstipple.c
+++ b/src/gallium/auxiliary/draw/draw_pstipple.c
@@ -112,7 +112,8 @@ struct pstip_transform_context {
uint tempsUsed; /**< bitmask */
int wincoordInput;
int maxInput;
- int maxSampler; /**< max sampler index found */
+ uint samplersUsed; /**< bitfield of samplers used */
+ int freeSampler; /** an available sampler for the pstipple */
int texTemp; /**< temp registers */
int numImmed;
boolean firstInstruction;
@@ -130,8 +131,11 @@ pstip_transform_decl(struct tgsi_transform_context *ctx,
struct pstip_transform_context *pctx = (struct pstip_transform_context *) ctx;
if (decl->Declaration.File == TGSI_FILE_SAMPLER) {
- if ((int) decl->u.DeclarationRange.Last > pctx->maxSampler)
- pctx->maxSampler = (int) decl->u.DeclarationRange.Last;
+ uint i;
+ for (i = decl->u.DeclarationRange.First;
+ i <= decl->u.DeclarationRange.Last; i++) {
+ pctx->samplersUsed |= 1 << i;
+ }
}
else if (decl->Declaration.File == TGSI_FILE_INPUT) {
pctx->maxInput = MAX2(pctx->maxInput, (int) decl->u.DeclarationRange.Last);
@@ -160,6 +164,21 @@ pstip_transform_immed(struct tgsi_transform_context *ctx,
/**
+ * Find the lowest zero bit in the given word, or -1 if bitfield is all ones.
+ */
+static int
+free_bit(uint bitfield)
+{
+ int i;
+ for (i = 0; i < 32; i++) {
+ if ((bitfield & (1 << i)) == 0)
+ return i;
+ }
+ return -1;
+}
+
+
+/**
* TGSI instruction transform callback.
* Replace writes to result.color w/ a temp reg.
* Upon END instruction, insert texture sampling code for antialiasing.
@@ -177,7 +196,11 @@ pstip_transform_inst(struct tgsi_transform_context *ctx,
struct tgsi_full_instruction newInst;
uint i;
int wincoordInput;
- const int sampler = pctx->maxSampler + 1;
+
+ /* find free sampler */
+ pctx->freeSampler = free_bit(pctx->samplersUsed);
+ if (pctx->freeSampler >= PIPE_MAX_SAMPLERS)
+ pctx->freeSampler = PIPE_MAX_SAMPLERS - 1;
if (pctx->wincoordInput < 0)
wincoordInput = pctx->maxInput + 1;
@@ -214,7 +237,7 @@ pstip_transform_inst(struct tgsi_transform_context *ctx,
decl = tgsi_default_full_declaration();
decl.Declaration.File = TGSI_FILE_SAMPLER;
decl.u.DeclarationRange.First =
- decl.u.DeclarationRange.Last = sampler;
+ decl.u.DeclarationRange.Last = pctx->freeSampler;
ctx->emit_declaration(ctx, &decl);
/* declare new temp regs */
@@ -274,7 +297,7 @@ pstip_transform_inst(struct tgsi_transform_context *ctx,
newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY;
newInst.FullSrcRegisters[0].SrcRegister.Index = pctx->texTemp;
newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_SAMPLER;
- newInst.FullSrcRegisters[1].SrcRegister.Index = sampler;
+ newInst.FullSrcRegisters[1].SrcRegister.Index = pctx->freeSampler;
ctx->emit_instruction(ctx, &newInst);
/* KILP texTemp; # if texTemp < 0, KILL fragment */
@@ -313,7 +336,6 @@ generate_pstip_fs(struct pstip_stage *pstip)
memset(&transform, 0, sizeof(transform));
transform.wincoordInput = -1;
transform.maxInput = -1;
- transform.maxSampler = -1;
transform.texTemp = -1;
transform.firstInstruction = TRUE;
transform.base.transform_instruction = pstip_transform_inst;
@@ -329,7 +351,8 @@ generate_pstip_fs(struct pstip_stage *pstip)
tgsi_dump(pstip_fs.tokens, 0);
#endif
- pstip->fs->sampler_unit = transform.maxSampler + 1;
+ pstip->fs->sampler_unit = transform.freeSampler;
+ assert(pstip->fs->sampler_unit < PIPE_MAX_SAMPLERS);
pstip->fs->pstip_fs = pstip->driver_create_fs_state(pstip->pipe, &pstip_fs);
}
@@ -399,8 +422,6 @@ pstip_create_texture(struct pstip_stage *pstip)
pstip->texture = screen->texture_create(screen, &texTemp);
assert(pstip->texture->refcount == 1);
-
- //pstip_update_texture(pstip);
}
diff --git a/src/gallium/auxiliary/draw/draw_pt.c b/src/gallium/auxiliary/draw/draw_pt.c
index d7169f78f4..3ec31ec25f 100644
--- a/src/gallium/auxiliary/draw/draw_pt.c
+++ b/src/gallium/auxiliary/draw/draw_pt.c
@@ -55,7 +55,7 @@ draw_pt_arrays(struct draw_context *draw,
unsigned start,
unsigned count)
{
- const boolean pipeline = draw_need_pipeline(draw);
+ const boolean pipeline = draw_need_pipeline(draw, prim);
const boolean cliptest = !draw->rasterizer->bypass_clipping;
const boolean shading = !draw->rasterizer->bypass_vs;
struct draw_pt_front_end *frontend = NULL;
diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c b/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c
index 64ef83d800..9b098bc173 100644
--- a/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c
+++ b/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c
@@ -78,7 +78,7 @@ struct fetch_emit_middle_end {
unsigned pitch;
void (*fetch)( const void *from, float *attrib);
void (*emit)( const float *attrib, float **out );
- } fetch[PIPE_ATTRIB_MAX];
+ } fetch[PIPE_MAX_ATTRIBS];
unsigned nr_fetch;
unsigned hw_vertex_size;
diff --git a/src/gallium/auxiliary/draw/draw_pt_vcache.c b/src/gallium/auxiliary/draw/draw_pt_vcache.c
index 98c22eb4d4..da9a3a52ae 100644
--- a/src/gallium/auxiliary/draw/draw_pt_vcache.c
+++ b/src/gallium/auxiliary/draw/draw_pt_vcache.c
@@ -107,7 +107,7 @@ static void vcache_elt( struct vcache_frontend *vcache,
assert(vcache->fetch_count < FETCH_MAX);
vcache->in[idx] = felt;
- vcache->out[idx] = vcache->fetch_count;
+ vcache->out[idx] = (ushort)vcache->fetch_count;
vcache->fetch_elts[vcache->fetch_count++] = felt;
}
diff --git a/src/gallium/auxiliary/draw/draw_validate.c b/src/gallium/auxiliary/draw/draw_validate.c
index 70b477ba5c..e163e078f0 100644
--- a/src/gallium/auxiliary/draw/draw_validate.c
+++ b/src/gallium/auxiliary/draw/draw_validate.c
@@ -32,6 +32,22 @@
#include "pipe/p_defines.h"
#include "draw_private.h"
+static boolean points( unsigned prim )
+{
+ return (prim == PIPE_PRIM_POINTS);
+}
+
+static boolean lines( unsigned prim )
+{
+ return (prim == PIPE_PRIM_LINES ||
+ prim == PIPE_PRIM_LINE_STRIP ||
+ prim == PIPE_PRIM_LINE_LOOP);
+}
+
+static boolean triangles( unsigned prim )
+{
+ return prim >= PIPE_PRIM_TRIANGLES;
+}
/**
* Check if we need any special pipeline stages, or whether
@@ -40,48 +56,63 @@
* pipeline stages.
*/
boolean
-draw_need_pipeline(const struct draw_context *draw)
+draw_need_pipeline(const struct draw_context *draw,
+ unsigned int prim )
{
- /* line stipple */
- if (draw->rasterizer->line_stipple_enable && draw->line_stipple)
- return TRUE;
-
- /* wide lines */
- if (draw->rasterizer->line_width > draw->wide_line_threshold)
- return TRUE;
+ /* Don't have to worry about triangles turning into lines/points
+ * and triggering the pipeline, because we have to trigger the
+ * pipeline *anyway* if unfilled mode is active.
+ */
+ if (lines(prim))
+ {
+ /* line stipple */
+ if (draw->rasterizer->line_stipple_enable && draw->line_stipple)
+ return TRUE;
- /* large points */
- if (draw->rasterizer->point_size > draw->wide_point_threshold)
- return TRUE;
+ /* wide lines */
+ if (draw->rasterizer->line_width > draw->wide_line_threshold)
+ return TRUE;
- /* AA lines */
- if (draw->rasterizer->line_smooth && draw->pipeline.aaline)
- return TRUE;
-
- /* AA points */
- if (draw->rasterizer->point_smooth && draw->pipeline.aapoint)
- return TRUE;
+ /* AA lines */
+ if (draw->rasterizer->line_smooth && draw->pipeline.aaline)
+ return TRUE;
+ }
- /* polygon stipple */
- if (draw->rasterizer->poly_stipple_enable && draw->pipeline.pstipple)
- return TRUE;
+ if (points(prim))
+ {
+ /* large points */
+ if (draw->rasterizer->point_size > draw->wide_point_threshold)
+ return TRUE;
- /* unfilled polygons */
- if (draw->rasterizer->fill_cw != PIPE_POLYGON_MODE_FILL ||
- draw->rasterizer->fill_ccw != PIPE_POLYGON_MODE_FILL)
- return TRUE;
+ /* AA points */
+ if (draw->rasterizer->point_smooth && draw->pipeline.aapoint)
+ return TRUE;
- /* polygon offset */
- if (draw->rasterizer->offset_cw || draw->rasterizer->offset_ccw)
- return TRUE;
+ /* point sprites */
+ if (draw->rasterizer->point_sprite && draw->point_sprite)
+ return TRUE;
+ }
- /* point sprites */
- if (draw->rasterizer->point_sprite && draw->point_sprite)
- return TRUE;
- /* two-side lighting */
- if (draw->rasterizer->light_twoside)
- return TRUE;
+ if (triangles(prim))
+ {
+ /* polygon stipple */
+ if (draw->rasterizer->poly_stipple_enable && draw->pipeline.pstipple)
+ return TRUE;
+
+ /* unfilled polygons */
+ if (draw->rasterizer->fill_cw != PIPE_POLYGON_MODE_FILL ||
+ draw->rasterizer->fill_ccw != PIPE_POLYGON_MODE_FILL)
+ return TRUE;
+
+ /* polygon offset */
+ if (draw->rasterizer->offset_cw || draw->rasterizer->offset_ccw)
+ return TRUE;
+
+ /* two-side lighting */
+ if (draw->rasterizer->light_twoside)
+ return TRUE;
+ }
/* polygon cull - this is difficult - hardware can cull just fine
* most of the time (though sometimes CULL_NEITHER is unsupported.
diff --git a/src/gallium/auxiliary/draw/draw_vertex_fetch.c b/src/gallium/auxiliary/draw/draw_vertex_fetch.c
index b56d85396d..11f99babf6 100644
--- a/src/gallium/auxiliary/draw/draw_vertex_fetch.c
+++ b/src/gallium/auxiliary/draw/draw_vertex_fetch.c
@@ -314,7 +314,11 @@ static fetch_func get_fetch_func( enum pipe_format format )
return NULL; /* not sure why this is needed */
default:
- assert(0);
+ /* This can get hit because draw-state-validation is too eager,
+ and can jump in here validating stuff before the state tracker has set
+ up everything.
+ */
+ /* assert(0); */
return NULL;
}
}
diff --git a/src/gallium/auxiliary/draw/draw_vf.c b/src/gallium/auxiliary/draw/draw_vf.c
index f4e29a6293..7bb34ace7a 100644
--- a/src/gallium/auxiliary/draw/draw_vf.c
+++ b/src/gallium/auxiliary/draw/draw_vf.c
@@ -158,7 +158,7 @@ draw_vf_set_vertex_attributes( struct draw_vertex_fetch *vf,
unsigned offset = 0;
unsigned i, j;
- assert(nr < PIPE_ATTRIB_MAX);
+ assert(nr < PIPE_MAX_ATTRIBS);
for (j = 0, i = 0; i < nr; i++) {
const unsigned format = map[i].format;
@@ -390,7 +390,7 @@ struct draw_vertex_fetch *draw_vf_create( void )
struct draw_vertex_fetch *vf = CALLOC_STRUCT(draw_vertex_fetch);
unsigned i;
- for (i = 0; i < PIPE_ATTRIB_MAX; i++)
+ for (i = 0; i < PIPE_MAX_ATTRIBS; i++)
vf->attr[i].vf = vf;
vf->identity[0] = 0.0;
diff --git a/src/gallium/auxiliary/draw/draw_vf.h b/src/gallium/auxiliary/draw/draw_vf.h
index 011c8f0ff1..7555d1bd58 100644
--- a/src/gallium/auxiliary/draw/draw_vf.h
+++ b/src/gallium/auxiliary/draw/draw_vf.h
@@ -169,7 +169,7 @@ struct draw_vf_attr
struct draw_vertex_fetch
{
- struct draw_vf_attr attr[PIPE_ATTRIB_MAX];
+ struct draw_vf_attr attr[PIPE_MAX_ATTRIBS];
unsigned attr_count;
unsigned vertex_stride;
diff --git a/src/gallium/auxiliary/draw/draw_vs_exec.c b/src/gallium/auxiliary/draw/draw_vs_exec.c
index 4e2fa72707..487d0ea7f4 100644
--- a/src/gallium/auxiliary/draw/draw_vs_exec.c
+++ b/src/gallium/auxiliary/draw/draw_vs_exec.c
@@ -99,8 +99,8 @@ vs_exec_run( struct draw_vertex_shader *shader,
struct tgsi_exec_machine *machine = &draw->machine;
unsigned int j;
- ALIGN16_DECL(struct tgsi_exec_vector, inputs, PIPE_ATTRIB_MAX);
- ALIGN16_DECL(struct tgsi_exec_vector, outputs, PIPE_ATTRIB_MAX);
+ ALIGN16_DECL(struct tgsi_exec_vector, inputs, PIPE_MAX_ATTRIBS);
+ ALIGN16_DECL(struct tgsi_exec_vector, outputs, PIPE_MAX_ATTRIBS);
const float *scale = draw->viewport.scale;
const float *trans = draw->viewport.translate;
diff --git a/src/gallium/auxiliary/draw/draw_vs_llvm.c b/src/gallium/auxiliary/draw/draw_vs_llvm.c
index bd983f2ddf..d29cb18efe 100644
--- a/src/gallium/auxiliary/draw/draw_vs_llvm.c
+++ b/src/gallium/auxiliary/draw/draw_vs_llvm.c
@@ -107,8 +107,8 @@ vs_llvm_run( struct draw_vertex_shader *base,
struct tgsi_exec_machine *machine = &draw->machine;
unsigned int j;
- ALIGN16_DECL(struct tgsi_exec_vector, inputs, PIPE_ATTRIB_MAX);
- ALIGN16_DECL(struct tgsi_exec_vector, outputs, PIPE_ATTRIB_MAX);
+ ALIGN16_DECL(struct tgsi_exec_vector, inputs, PIPE_MAX_ATTRIBS);
+ ALIGN16_DECL(struct tgsi_exec_vector, outputs, PIPE_MAX_ATTRIBS);
const float *scale = draw->viewport.scale;
const float *trans = draw->viewport.translate;
diff --git a/src/gallium/auxiliary/draw/draw_vs_sse.c b/src/gallium/auxiliary/draw/draw_vs_sse.c
index a4503c143e..bc910dc2d0 100644
--- a/src/gallium/auxiliary/draw/draw_vs_sse.c
+++ b/src/gallium/auxiliary/draw/draw_vs_sse.c
@@ -114,8 +114,8 @@ vs_sse_run( struct draw_vertex_shader *base,
struct tgsi_exec_machine *machine = &draw->machine;
unsigned int j;
- ALIGN16_DECL(struct tgsi_exec_vector, inputs, PIPE_ATTRIB_MAX);
- ALIGN16_DECL(struct tgsi_exec_vector, outputs, PIPE_ATTRIB_MAX);
+ ALIGN16_DECL(struct tgsi_exec_vector, inputs, PIPE_MAX_ATTRIBS);
+ ALIGN16_DECL(struct tgsi_exec_vector, outputs, PIPE_MAX_ATTRIBS);
const float *scale = draw->viewport.scale;
const float *trans = draw->viewport.translate;