summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorBen Skeggs <[email protected]>2008-03-30 19:58:03 +1000
committerBen Skeggs <[email protected]>2008-03-30 19:58:03 +1000
commit03c60e0fb691d39a168a8825ace7150ef3a20e02 (patch)
treee7433c539a7584d29d4a6bf23aacdc348167aed8 /src
parent68395f6726183a0776e324b900e429449ede2b22 (diff)
parenta52c0416d1f2105960b4646e2e268aed26814689 (diff)
Merge remote branch 'upstream/gallium-0.1' into nouveau-gallium-0.1
Diffstat (limited to 'src')
-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
-rw-r--r--src/gallium/auxiliary/rtasm/rtasm_ppc_spe.c4
-rw-r--r--src/gallium/auxiliary/rtasm/rtasm_ppc_spe.h10
-rw-r--r--src/gallium/auxiliary/util/p_debug.c13
-rw-r--r--src/gallium/auxiliary/util/u_blit.c15
-rw-r--r--src/gallium/auxiliary/util/u_draw_quad.c16
-rw-r--r--src/gallium/auxiliary/util/u_gen_mipmap.c18
-rw-r--r--src/gallium/auxiliary/util/u_simple_shaders.c31
-rw-r--r--src/gallium/auxiliary/util/u_simple_shaders.h10
-rw-r--r--src/gallium/auxiliary/util/u_snprintf.c8
-rw-r--r--src/gallium/drivers/cell/common.h11
-rw-r--r--src/gallium/drivers/cell/ppu/cell_context.c4
-rw-r--r--src/gallium/drivers/cell/ppu/cell_context.h8
-rw-r--r--src/gallium/drivers/cell/ppu/cell_draw_arrays.c4
-rw-r--r--src/gallium/drivers/cell/ppu/cell_flush.c15
-rw-r--r--src/gallium/drivers/cell/ppu/cell_flush.h5
-rw-r--r--src/gallium/drivers/cell/ppu/cell_state.h12
-rw-r--r--src/gallium/drivers/cell/ppu/cell_state_emit.c18
-rw-r--r--src/gallium/drivers/cell/ppu/cell_state_per_fragment.c261
-rw-r--r--src/gallium/drivers/cell/ppu/cell_state_per_fragment.h4
-rw-r--r--src/gallium/drivers/cell/ppu/cell_state_vertex.c30
-rw-r--r--src/gallium/drivers/cell/ppu/cell_vbuf.c2
-rw-r--r--src/gallium/drivers/cell/ppu/cell_vertex_fetch.c2
-rw-r--r--src/gallium/drivers/cell/ppu/cell_vertex_shader.c4
-rw-r--r--src/gallium/drivers/cell/spu/spu_exec.c2
-rw-r--r--src/gallium/drivers/cell/spu/spu_main.c23
-rw-r--r--src/gallium/drivers/cell/spu/spu_main.h9
-rw-r--r--src/gallium/drivers/cell/spu/spu_tri.c59
-rw-r--r--src/gallium/drivers/cell/spu/spu_vertex_shader.c4
-rw-r--r--src/gallium/drivers/cell/spu/spu_vertex_shader.h8
-rw-r--r--src/gallium/drivers/failover/fo_context.c4
-rw-r--r--src/gallium/drivers/failover/fo_context.h9
-rw-r--r--src/gallium/drivers/failover/fo_state.c35
-rw-r--r--src/gallium/drivers/failover/fo_state_emit.c22
-rw-r--r--src/gallium/drivers/i915simple/i915_batch.h4
-rw-r--r--src/gallium/drivers/i915simple/i915_blit.c4
-rw-r--r--src/gallium/drivers/i915simple/i915_context.c4
-rw-r--r--src/gallium/drivers/i915simple/i915_context.h2
-rw-r--r--src/gallium/drivers/i915simple/i915_flush.c14
-rw-r--r--src/gallium/drivers/i915simple/i915_prim_emit.c2
-rw-r--r--src/gallium/drivers/i915simple/i915_prim_vbuf.c2
-rw-r--r--src/gallium/drivers/i915simple/i915_state.c23
-rw-r--r--src/gallium/drivers/i915simple/i915_state_emit.c2
-rw-r--r--src/gallium/drivers/i915simple/i915_winsys.h5
-rw-r--r--src/gallium/drivers/i965simple/brw_clip.h2
-rw-r--r--src/gallium/drivers/i965simple/brw_context.h12
-rw-r--r--src/gallium/drivers/i965simple/brw_flush.c13
-rw-r--r--src/gallium/drivers/i965simple/brw_state.c60
-rw-r--r--src/gallium/drivers/i965simple/brw_wm.c3
-rw-r--r--src/gallium/drivers/i965simple/brw_wm.h4
-rw-r--r--src/gallium/drivers/softpipe/sp_context.c4
-rw-r--r--src/gallium/drivers/softpipe/sp_context.h6
-rw-r--r--src/gallium/drivers/softpipe/sp_draw_arrays.c4
-rw-r--r--src/gallium/drivers/softpipe/sp_flush.c10
-rw-r--r--src/gallium/drivers/softpipe/sp_flush.h4
-rw-r--r--src/gallium/drivers/softpipe/sp_prim_setup.c30
-rw-r--r--src/gallium/drivers/softpipe/sp_quad_fs.c25
-rw-r--r--src/gallium/drivers/softpipe/sp_state.h12
-rw-r--r--src/gallium/drivers/softpipe/sp_state_vertex.c31
-rw-r--r--src/gallium/include/pipe/p_context.h75
-rw-r--r--src/gallium/include/pipe/p_debug.h8
-rw-r--r--src/gallium/include/pipe/p_defines.h3
-rw-r--r--src/gallium/include/pipe/p_state.h7
-rw-r--r--src/gallium/include/pipe/p_util.h7
-rw-r--r--src/gallium/winsys/dri/intel/intel_context.c4
-rw-r--r--src/gallium/winsys/dri/intel/intel_winsys_i915.c25
-rw-r--r--src/gallium/winsys/xlib/xm_api.c24
-rw-r--r--src/gallium/winsys/xlib/xm_winsys.c332
-rw-r--r--src/gallium/winsys/xlib/xm_winsys_aub.h3
-rw-r--r--src/gallium/winsys/xlib/xmesaP.h3
-rw-r--r--src/mesa/main/fbobject.c2
-rw-r--r--src/mesa/shader/arbprogparse.c362
-rw-r--r--src/mesa/shader/prog_parameter.c2
-rw-r--r--src/mesa/shader/program.c23
-rw-r--r--src/mesa/state_tracker/st_atom.c8
-rw-r--r--src/mesa/state_tracker/st_atom_depth.c5
-rw-r--r--src/mesa/state_tracker/st_atom_sampler.c1
-rw-r--r--src/mesa/state_tracker/st_cb_accum.c2
-rw-r--r--src/mesa/state_tracker/st_cb_bitmap.c272
-rw-r--r--src/mesa/state_tracker/st_cb_bitmap.h5
-rw-r--r--src/mesa/state_tracker/st_cb_clear.c5
-rw-r--r--src/mesa/state_tracker/st_cb_drawpixels.c10
-rw-r--r--src/mesa/state_tracker/st_cb_fbo.c2
-rw-r--r--src/mesa/state_tracker/st_cb_flush.c37
-rw-r--r--src/mesa/state_tracker/st_cb_readpixels.c2
-rw-r--r--src/mesa/state_tracker/st_context.c9
-rw-r--r--src/mesa/state_tracker/st_context.h5
-rw-r--r--src/mesa/state_tracker/st_draw.c84
-rw-r--r--src/mesa/state_tracker/st_format.c260
-rw-r--r--src/mesa/state_tracker/st_framebuffer.c3
-rw-r--r--src/mesa/state_tracker/st_public.h5
-rw-r--r--src/mesa/state_tracker/st_texture.c2
109 files changed, 2028 insertions, 1033 deletions
diff --git a/src/gallium/auxiliary/draw/draw_aaline.c b/src/gallium/auxiliary/draw/draw_aaline.c
index cc1873abada..e8d2a45102c 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 67a7a8ebaba..fcebe3e7a0c 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 903cc267662..10bf9f54c10 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 dae687e5906..84bae3bd78d 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 dd00894c5bd..2198079a880 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 4fe0ddc02a7..ddcde01d9a2 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 0c5afcacfae..8eb2f515cbc 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 9cec9866408..4dddb72906f 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 d7169f78f44..3ec31ec25f3 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 64ef83d8001..9b098bc173f 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 98c22eb4d4a..da9a3a52aed 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 70b477ba5cc..e163e078f0f 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 b56d85396de..11f99babf65 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 f4e29a62932..7bb34ace7aa 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 011c8f0ff1c..7555d1bd588 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 4e2fa727070..487d0ea7f4f 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 bd983f2ddfa..d29cb18efe4 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 a4503c143ed..bc910dc2d04 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;
diff --git a/src/gallium/auxiliary/rtasm/rtasm_ppc_spe.c b/src/gallium/auxiliary/rtasm/rtasm_ppc_spe.c
index 24be65bff9d..7f6bf577b26 100644
--- a/src/gallium/auxiliary/rtasm/rtasm_ppc_spe.c
+++ b/src/gallium/auxiliary/rtasm/rtasm_ppc_spe.c
@@ -267,10 +267,10 @@ void _name (struct spe_function *p, unsigned rT, unsigned rA, int imm) \
emit_RI7(p, _op, rT, rA, imm); \
}
-#define EMIT_RI8(_name, _op) \
+#define EMIT_RI8(_name, _op, bias) \
void _name (struct spe_function *p, unsigned rT, unsigned rA, int imm) \
{ \
- emit_RI8(p, _op, rT, rA, 155 - imm); \
+ emit_RI8(p, _op, rT, rA, bias - imm); \
}
#define EMIT_RI10(_name, _op) \
diff --git a/src/gallium/auxiliary/rtasm/rtasm_ppc_spe.h b/src/gallium/auxiliary/rtasm/rtasm_ppc_spe.h
index 5a1eb1ed8de..1cacc717b15 100644
--- a/src/gallium/auxiliary/rtasm/rtasm_ppc_spe.h
+++ b/src/gallium/auxiliary/rtasm/rtasm_ppc_spe.h
@@ -76,7 +76,7 @@ extern void spe_release_register(struct spe_function *p, int reg);
#define EMIT_RI7(_name, _op) \
extern void _name (struct spe_function *p, unsigned rT, unsigned rA, \
int imm)
-#define EMIT_RI8(_name, _op) \
+#define EMIT_RI8(_name, _op, bias) \
extern void _name (struct spe_function *p, unsigned rT, unsigned rA, \
int imm)
#define EMIT_RI10(_name, _op) \
@@ -289,10 +289,10 @@ EMIT_RR (spe_dfnma, 0x35f);
EMIT_R (spe_frest, 0x1b8);
EMIT_R (spe_frsqest, 0x1b9);
EMIT_RR (spe_fi, 0x3d4);
-EMIT_RI8 (spe_csflt, 0x1da);
-EMIT_RI8 (spe_cflts, 0x1d8);
-EMIT_RI8 (spe_cuflt, 0x1db);
-EMIT_RI8 (spe_cfltu, 0x1d9);
+EMIT_RI8 (spe_csflt, 0x1da, 155);
+EMIT_RI8 (spe_cflts, 0x1d8, 173);
+EMIT_RI8 (spe_cuflt, 0x1db, 155);
+EMIT_RI8 (spe_cfltu, 0x1d9, 173);
EMIT_R (spe_frds, 0x3b9);
EMIT_R (spe_fesd, 0x3b8);
EMIT_RR (spe_dfceq, 0x3c3);
diff --git a/src/gallium/auxiliary/util/p_debug.c b/src/gallium/auxiliary/util/p_debug.c
index cc036dabf82..5447bbb6f55 100644
--- a/src/gallium/auxiliary/util/p_debug.c
+++ b/src/gallium/auxiliary/util/p_debug.c
@@ -155,10 +155,12 @@ debug_get_option(const char *name, const char *dfault)
const char *sol, *eol, *sep;
static char output[1024];
+ result = dfault;
+ /* XXX: this creates the file if it does not exists, so it must either be
+ * disabled on release versions, or put in a less conspicuous place.
+ */
pMap = EngMapFile(L"\\??\\c:\\gallium.cfg", 0, &iFile);
- if(!pMap)
- result = dfault;
- else {
+ if(pMap) {
sol = (const char *)pMap;
while(1) {
/* TODO: handle LF line endings */
@@ -184,10 +186,7 @@ debug_get_option(const char *name, const char *dfault)
result = dfault;
#endif
- if(result)
- debug_printf("%s: %s = %s\n", __FUNCTION__, name, result);
- else
- debug_printf("%s: %s = (null)\n", __FUNCTION__, name);
+ debug_printf("%s: %s = %s\n", __FUNCTION__, name, result ? result : "(null)");
return result;
}
diff --git a/src/gallium/auxiliary/util/u_blit.c b/src/gallium/auxiliary/util/u_blit.c
index 28a404fd01f..eec5e600c91 100644
--- a/src/gallium/auxiliary/util/u_blit.c
+++ b/src/gallium/auxiliary/util/u_blit.c
@@ -58,9 +58,10 @@ struct blit_state
struct pipe_rasterizer_state rasterizer;
struct pipe_sampler_state sampler;
- /*struct pipe_viewport_state viewport;*/
- struct pipe_sampler_state *vs;
- struct pipe_sampler_state *fs;
+ struct pipe_shader_state vert_shader;
+ struct pipe_shader_state frag_shader;
+ void *vs;
+ void *fs;
struct pipe_buffer *vbuf; /**< quad vertices */
float vertices[4][2][4]; /**< vertex/texcoords for quad */
@@ -130,11 +131,12 @@ util_create_blit(struct pipe_context *pipe, struct cso_context *cso)
TGSI_SEMANTIC_GENERIC };
const uint semantic_indexes[] = { 0, 0 };
ctx->vs = util_make_vertex_passthrough_shader(pipe, 2, semantic_names,
- semantic_indexes);
+ semantic_indexes,
+ &ctx->vert_shader);
}
/* fragment shader */
- ctx->fs = util_make_fragment_tex_shader(pipe);
+ ctx->fs = util_make_fragment_tex_shader(pipe, &ctx->frag_shader);
ctx->vbuf = pipe->winsys->buffer_create(pipe->winsys,
32,
@@ -169,6 +171,9 @@ util_destroy_blit(struct blit_state *ctx)
pipe->delete_vs_state(pipe, ctx->vs);
pipe->delete_fs_state(pipe, ctx->fs);
+ FREE((void*) ctx->vert_shader.tokens);
+ FREE((void*) ctx->frag_shader.tokens);
+
pipe->winsys->buffer_destroy(pipe->winsys, ctx->vbuf);
FREE(ctx);
diff --git a/src/gallium/auxiliary/util/u_draw_quad.c b/src/gallium/auxiliary/util/u_draw_quad.c
index 37e85336091..e659edb0881 100644
--- a/src/gallium/auxiliary/util/u_draw_quad.c
+++ b/src/gallium/auxiliary/util/u_draw_quad.c
@@ -45,23 +45,25 @@ util_draw_vertex_buffer(struct pipe_context *pipe,
uint num_attribs)
{
struct pipe_vertex_buffer vbuffer;
- struct pipe_vertex_element velement;
+ struct pipe_vertex_element velements[PIPE_MAX_ATTRIBS];
uint i;
+ assert(num_attribs <= PIPE_MAX_ATTRIBS);
+
/* tell pipe about the vertex buffer */
vbuffer.buffer = vbuf;
vbuffer.pitch = num_attribs * 4 * sizeof(float); /* vertex size */
vbuffer.buffer_offset = 0;
- pipe->set_vertex_buffer(pipe, 0, &vbuffer);
+ pipe->set_vertex_buffers(pipe, 1, &vbuffer);
/* tell pipe about the vertex attributes */
for (i = 0; i < num_attribs; i++) {
- velement.src_offset = i * 4 * sizeof(float);
- velement.vertex_buffer_index = 0;
- velement.src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
- velement.nr_components = 4;
- pipe->set_vertex_element(pipe, i, &velement);
+ velements[i].src_offset = i * 4 * sizeof(float);
+ velements[i].vertex_buffer_index = 0;
+ velements[i].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
+ velements[i].nr_components = 4;
}
+ pipe->set_vertex_elements(pipe, num_attribs, velements);
/* draw */
pipe->draw_arrays(pipe, prim_type, 0, num_verts);
diff --git a/src/gallium/auxiliary/util/u_gen_mipmap.c b/src/gallium/auxiliary/util/u_gen_mipmap.c
index e129c062be6..2fd214d22e2 100644
--- a/src/gallium/auxiliary/util/u_gen_mipmap.c
+++ b/src/gallium/auxiliary/util/u_gen_mipmap.c
@@ -61,9 +61,11 @@ struct gen_mipmap_state
struct pipe_depth_stencil_alpha_state depthstencil;
struct pipe_rasterizer_state rasterizer;
struct pipe_sampler_state sampler;
- /*struct pipe_viewport_state viewport;*/
- struct pipe_sampler_state *vs;
- struct pipe_sampler_state *fs;
+
+ struct pipe_shader_state vert_shader;
+ struct pipe_shader_state frag_shader;
+ void *vs;
+ void *fs;
struct pipe_buffer *vbuf; /**< quad vertices */
float vertices[4][2][4]; /**< vertex/texcoords for quad */
@@ -740,11 +742,12 @@ util_create_gen_mipmap(struct pipe_context *pipe,
TGSI_SEMANTIC_GENERIC };
const uint semantic_indexes[] = { 0, 0 };
ctx->vs = util_make_vertex_passthrough_shader(pipe, 2, semantic_names,
- semantic_indexes);
+ semantic_indexes,
+ &ctx->vert_shader);
}
/* fragment shader */
- ctx->fs = util_make_fragment_tex_shader(pipe);
+ ctx->fs = util_make_fragment_tex_shader(pipe, &ctx->frag_shader);
ctx->vbuf = pipe->winsys->buffer_create(pipe->winsys,
32,
@@ -813,6 +816,9 @@ util_destroy_gen_mipmap(struct gen_mipmap_state *ctx)
pipe->delete_vs_state(pipe, ctx->vs);
pipe->delete_fs_state(pipe, ctx->fs);
+ FREE((void*) ctx->vert_shader.tokens);
+ FREE((void*) ctx->frag_shader.tokens);
+
pipe->winsys->buffer_destroy(pipe->winsys, ctx->vbuf);
FREE(ctx);
@@ -935,7 +941,7 @@ util_gen_mipmap(struct gen_mipmap_state *ctx,
4, /* verts */
2); /* attribs/vert */
- pipe->flush(pipe, PIPE_FLUSH_WAIT);
+ pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, NULL);
/* need to signal that the texture has changed _after_ rendering to it */
pipe->texture_update(pipe, pt, face, (1 << dstLevel));
diff --git a/src/gallium/auxiliary/util/u_simple_shaders.c b/src/gallium/auxiliary/util/u_simple_shaders.c
index d230ddfbebc..5f8d12191d4 100644
--- a/src/gallium/auxiliary/util/u_simple_shaders.c
+++ b/src/gallium/auxiliary/util/u_simple_shaders.c
@@ -56,7 +56,9 @@ void *
util_make_vertex_passthrough_shader(struct pipe_context *pipe,
uint num_attribs,
const uint *semantic_names,
- const uint *semantic_indexes)
+ const uint *semantic_indexes,
+ struct pipe_shader_state *shader)
+
{
uint maxTokens = 100;
struct tgsi_token *tokens;
@@ -66,7 +68,6 @@ util_make_vertex_passthrough_shader(struct pipe_context *pipe,
struct tgsi_full_instruction inst;
const uint procType = TGSI_PROCESSOR_VERTEX;
uint ti, i;
- struct pipe_shader_state shader;
tokens = (struct tgsi_token *) MALLOC(maxTokens * sizeof(tokens[0]));
@@ -145,8 +146,10 @@ util_make_vertex_passthrough_shader(struct pipe_context *pipe,
tgsi_dump(tokens, 0);
#endif
- shader.tokens = tokens;
- return pipe->create_vs_state(pipe, &shader);
+ shader->tokens = tokens;
+ /*shader->num_tokens = ti;*/
+
+ return pipe->create_vs_state(pipe, shader);
}
@@ -158,7 +161,8 @@ util_make_vertex_passthrough_shader(struct pipe_context *pipe,
* END;
*/
void *
-util_make_fragment_tex_shader(struct pipe_context *pipe)
+util_make_fragment_tex_shader(struct pipe_context *pipe,
+ struct pipe_shader_state *shader)
{
uint maxTokens = 100;
struct tgsi_token *tokens;
@@ -168,7 +172,6 @@ util_make_fragment_tex_shader(struct pipe_context *pipe)
struct tgsi_full_instruction inst;
const uint procType = TGSI_PROCESSOR_FRAGMENT;
uint ti;
- struct pipe_shader_state shader;
tokens = (struct tgsi_token *) MALLOC(maxTokens * sizeof(tokens[0]));
@@ -254,8 +257,10 @@ util_make_fragment_tex_shader(struct pipe_context *pipe)
tgsi_dump(tokens, 0);
#endif
- shader.tokens = tokens;
- return pipe->create_fs_state(pipe, &shader);
+ shader->tokens = tokens;
+ /*shader->num_tokens = ti;*/
+
+ return pipe->create_fs_state(pipe, shader);
}
@@ -266,7 +271,8 @@ util_make_fragment_tex_shader(struct pipe_context *pipe)
* Make simple fragment color pass-through shader.
*/
void *
-util_make_fragment_passthrough_shader(struct pipe_context *pipe)
+util_make_fragment_passthrough_shader(struct pipe_context *pipe,
+ struct pipe_shader_state *shader)
{
uint maxTokens = 40;
struct tgsi_token *tokens;
@@ -276,7 +282,6 @@ util_make_fragment_passthrough_shader(struct pipe_context *pipe)
struct tgsi_full_instruction inst;
const uint procType = TGSI_PROCESSOR_FRAGMENT;
uint ti;
- struct pipe_shader_state shader;
tokens = (struct tgsi_token *) MALLOC(maxTokens * sizeof(tokens[0]));
@@ -349,7 +354,9 @@ util_make_fragment_passthrough_shader(struct pipe_context *pipe)
tgsi_dump(tokens, 0);
#endif
- shader.tokens = tokens;
- return pipe->create_fs_state(pipe, &shader);
+ shader->tokens = tokens;
+ /*shader->num_tokens = ti;*/
+
+ return pipe->create_fs_state(pipe, shader);
}
diff --git a/src/gallium/auxiliary/util/u_simple_shaders.h b/src/gallium/auxiliary/util/u_simple_shaders.h
index ca219a092c7..8ca4977d715 100644
--- a/src/gallium/auxiliary/util/u_simple_shaders.h
+++ b/src/gallium/auxiliary/util/u_simple_shaders.h
@@ -34,6 +34,7 @@
struct pipe_context;
+struct pipe_shader_state;
#ifdef __cplusplus
@@ -45,15 +46,18 @@ extern void *
util_make_vertex_passthrough_shader(struct pipe_context *pipe,
uint num_attribs,
const uint *semantic_names,
- const uint *semantic_indexes);
+ const uint *semantic_indexes,
+ struct pipe_shader_state *shader);
extern void *
-util_make_fragment_tex_shader(struct pipe_context *pipe);
+util_make_fragment_tex_shader(struct pipe_context *pipe,
+ struct pipe_shader_state *shader);
extern void *
-util_make_fragment_passthrough_shader(struct pipe_context *pipe);
+util_make_fragment_passthrough_shader(struct pipe_context *pipe,
+ struct pipe_shader_state *shader);
#ifdef __cplusplus
diff --git a/src/gallium/auxiliary/util/u_snprintf.c b/src/gallium/auxiliary/util/u_snprintf.c
index 61c20b48f7e..48426abcb7a 100644
--- a/src/gallium/auxiliary/util/u_snprintf.c
+++ b/src/gallium/auxiliary/util/u_snprintf.c
@@ -783,19 +783,19 @@ rpl_vsnprintf(char *str, size_t size, const char *format, va_list args)
switch (cflags) {
case PRINT_C_CHAR:
charptr = va_arg(args, signed char *);
- *charptr = len;
+ *charptr = (signed char)len;
break;
case PRINT_C_SHORT:
shortptr = va_arg(args, short int *);
- *shortptr = len;
+ *shortptr = (short int)len;
break;
case PRINT_C_LONG:
longptr = va_arg(args, long int *);
- *longptr = len;
+ *longptr = (long int)len;
break;
case PRINT_C_LLONG:
llongptr = va_arg(args, LLONG *);
- *llongptr = len;
+ *llongptr = (LLONG)len;
break;
case PRINT_C_SIZE:
/*
diff --git a/src/gallium/drivers/cell/common.h b/src/gallium/drivers/cell/common.h
index d59e4f7036e..b0928fefd2e 100644
--- a/src/gallium/drivers/cell/common.h
+++ b/src/gallium/drivers/cell/common.h
@@ -92,8 +92,9 @@
#define CELL_CMD_STATE_BIND_VS 18
#define CELL_CMD_STATE_BLEND 19
#define CELL_CMD_STATE_ATTRIB_FETCH 20
-#define CELL_CMD_VS_EXECUTE 21
-#define CELL_CMD_FLUSH_BUFFER_RANGE 22
+#define CELL_CMD_STATE_LOGICOP 21
+#define CELL_CMD_VS_EXECUTE 22
+#define CELL_CMD_FLUSH_BUFFER_RANGE 23
#define CELL_NUM_BUFFERS 4
@@ -124,6 +125,12 @@ struct cell_command_blend {
};
+struct cell_command_logicop {
+ uint64_t base; /**< Effective address of code start. */
+ unsigned size; /**< Size in bytes of test code. */
+};
+
+
/**
* Tell SPUs about the framebuffer size, location
*/
diff --git a/src/gallium/drivers/cell/ppu/cell_context.c b/src/gallium/drivers/cell/ppu/cell_context.c
index ccbbd1d331c..12eb5aa2547 100644
--- a/src/gallium/drivers/cell/ppu/cell_context.c
+++ b/src/gallium/drivers/cell/ppu/cell_context.c
@@ -103,8 +103,8 @@ cell_create_context(struct pipe_screen *screen,
cell->pipe.destroy = cell_destroy_context;
/* state setters */
- cell->pipe.set_vertex_buffer = cell_set_vertex_buffer;
- cell->pipe.set_vertex_element = cell_set_vertex_element;
+ cell->pipe.set_vertex_buffers = cell_set_vertex_buffers;
+ cell->pipe.set_vertex_elements = cell_set_vertex_elements;
cell->pipe.draw_arrays = cell_draw_arrays;
cell->pipe.draw_elements = cell_draw_elements;
diff --git a/src/gallium/drivers/cell/ppu/cell_context.h b/src/gallium/drivers/cell/ppu/cell_context.h
index 9e79db0acef..7f656a97447 100644
--- a/src/gallium/drivers/cell/ppu/cell_context.h
+++ b/src/gallium/drivers/cell/ppu/cell_context.h
@@ -92,6 +92,8 @@ struct cell_context
const struct cell_vertex_shader_state *vs;
const struct cell_fragment_shader_state *fs;
+ struct spe_function logic_op;
+
struct pipe_blend_color blend_color;
struct pipe_clip_state clip;
struct pipe_constant_buffer constants[2];
@@ -101,8 +103,8 @@ struct cell_context
struct cell_texture *texture[PIPE_MAX_SAMPLERS];
uint num_textures;
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];
ubyte *cbuf_map[PIPE_MAX_COLOR_BUFS];
ubyte *zsbuf_map;
@@ -139,7 +141,7 @@ struct cell_context
struct spe_function attrib_fetch;
- unsigned attrib_fetch_offsets[PIPE_ATTRIB_MAX];
+ unsigned attrib_fetch_offsets[PIPE_MAX_ATTRIBS];
};
diff --git a/src/gallium/drivers/cell/ppu/cell_draw_arrays.c b/src/gallium/drivers/cell/ppu/cell_draw_arrays.c
index c839fb4d12d..b896252f817 100644
--- a/src/gallium/drivers/cell/ppu/cell_draw_arrays.c
+++ b/src/gallium/drivers/cell/ppu/cell_draw_arrays.c
@@ -123,7 +123,7 @@ cell_draw_elements(struct pipe_context *pipe,
/*
* Map vertex buffers
*/
- for (i = 0; i < PIPE_ATTRIB_MAX; i++) {
+ for (i = 0; i < PIPE_MAX_ATTRIBS; i++) {
if (sp->vertex_buffer[i].buffer) {
void *buf = pipe->winsys->buffer_map(pipe->winsys,
sp->vertex_buffer[i].buffer,
@@ -151,7 +151,7 @@ cell_draw_elements(struct pipe_context *pipe,
/*
* unmap vertex/index buffers - will cause draw module to flush
*/
- for (i = 0; i < PIPE_ATTRIB_MAX; i++) {
+ for (i = 0; i < PIPE_MAX_ATTRIBS; i++) {
if (sp->vertex_buffer[i].buffer) {
draw_set_mapped_vertex_buffer(draw, i, NULL);
pipe->winsys->buffer_unmap(pipe->winsys, sp->vertex_buffer[i].buffer);
diff --git a/src/gallium/drivers/cell/ppu/cell_flush.c b/src/gallium/drivers/cell/ppu/cell_flush.c
index 66a5627d844..3aaf3de6684 100644
--- a/src/gallium/drivers/cell/ppu/cell_flush.c
+++ b/src/gallium/drivers/cell/ppu/cell_flush.c
@@ -35,12 +35,19 @@
void
-cell_flush(struct pipe_context *pipe, unsigned flags)
+cell_flush(struct pipe_context *pipe, unsigned flags,
+ struct pipe_fence_handle **fence)
{
struct cell_context *cell = cell_context(pipe);
+ if (fence) {
+ *fence = NULL;
+ /* XXX: Implement real fencing */
+ flags |= CELL_FLUSH_WAIT;
+ }
+
if (flags & PIPE_FLUSH_SWAPBUFFERS)
- flags |= PIPE_FLUSH_WAIT;
+ flags |= CELL_FLUSH_WAIT;
draw_flush( cell->draw );
cell_flush_int(pipe, flags);
@@ -58,7 +65,7 @@ cell_flush_int(struct pipe_context *pipe, unsigned flags)
ASSERT(!flushing);
flushing = TRUE;
- if (flags & PIPE_FLUSH_WAIT) {
+ if (flags & CELL_FLUSH_WAIT) {
uint64_t *cmd = (uint64_t *) cell_batch_alloc(cell, sizeof(uint64_t));
*cmd = CELL_CMD_FINISH;
}
@@ -72,7 +79,7 @@ cell_flush_int(struct pipe_context *pipe, unsigned flags)
}
#endif
- if (flags & PIPE_FLUSH_WAIT) {
+ if (flags & CELL_FLUSH_WAIT) {
/* Wait for ack */
for (i = 0; i < cell->num_spus; i++) {
uint k = wait_mbox_message(cell_global.spe_contexts[i]);
diff --git a/src/gallium/drivers/cell/ppu/cell_flush.h b/src/gallium/drivers/cell/ppu/cell_flush.h
index 7f940ae76b6..8f0645c4293 100644
--- a/src/gallium/drivers/cell/ppu/cell_flush.h
+++ b/src/gallium/drivers/cell/ppu/cell_flush.h
@@ -29,8 +29,11 @@
#ifndef CELL_FLUSH
#define CELL_FLUSH
+#define CELL_FLUSH_WAIT 0x80000000
+
extern void
-cell_flush(struct pipe_context *pipe, unsigned flags);
+cell_flush(struct pipe_context *pipe, unsigned flags,
+ struct pipe_fence_handle **fence);
extern void
cell_flush_int(struct pipe_context *pipe, unsigned flags);
diff --git a/src/gallium/drivers/cell/ppu/cell_state.h b/src/gallium/drivers/cell/ppu/cell_state.h
index 31ce505e211..82580ea35ab 100644
--- a/src/gallium/drivers/cell/ppu/cell_state.h
+++ b/src/gallium/drivers/cell/ppu/cell_state.h
@@ -48,13 +48,13 @@
#define CELL_NEW_VERTEX_INFO 0x8000
-void cell_set_vertex_element(struct pipe_context *,
- unsigned index,
- const struct pipe_vertex_element *);
+void cell_set_vertex_elements(struct pipe_context *,
+ unsigned count,
+ const struct pipe_vertex_element *);
-void cell_set_vertex_buffer(struct pipe_context *,
- unsigned index,
- const struct pipe_vertex_buffer *);
+void cell_set_vertex_buffers(struct pipe_context *,
+ unsigned count,
+ const struct pipe_vertex_buffer *);
void cell_update_derived( struct cell_context *softpipe );
diff --git a/src/gallium/drivers/cell/ppu/cell_state_emit.c b/src/gallium/drivers/cell/ppu/cell_state_emit.c
index 5709b48f129..4c75caa0251 100644
--- a/src/gallium/drivers/cell/ppu/cell_state_emit.c
+++ b/src/gallium/drivers/cell/ppu/cell_state_emit.c
@@ -29,6 +29,7 @@
#include "cell_context.h"
#include "cell_state.h"
#include "cell_state_emit.h"
+#include "cell_state_per_fragment.h"
#include "cell_batch.h"
#include "cell_texture.h"
#include "draw/draw_context.h"
@@ -50,6 +51,23 @@ emit_state_cmd(struct cell_context *cell, uint cmd,
void
cell_emit_state(struct cell_context *cell)
{
+ if (cell->dirty & (CELL_NEW_FRAMEBUFFER | CELL_NEW_BLEND)) {
+ struct cell_command_logicop logicop;
+
+ if (cell->logic_op.store != NULL) {
+ spe_release_func(& cell->logic_op);
+ }
+
+ cell_generate_logic_op(& cell->logic_op,
+ & cell->blend->base,
+ cell->framebuffer.cbufs[0]);
+
+ logicop.base = (intptr_t) cell->logic_op.store;
+ logicop.size = 64 * 4;
+ emit_state_cmd(cell, CELL_CMD_STATE_LOGICOP, &logicop,
+ sizeof(logicop));
+ }
+
if (cell->dirty & CELL_NEW_FRAMEBUFFER) {
struct pipe_surface *cbuf = cell->framebuffer.cbufs[0];
struct pipe_surface *zbuf = cell->framebuffer.zsbuf;
diff --git a/src/gallium/drivers/cell/ppu/cell_state_per_fragment.c b/src/gallium/drivers/cell/ppu/cell_state_per_fragment.c
index c750b1d89dc..f10025bd7c7 100644
--- a/src/gallium/drivers/cell/ppu/cell_state_per_fragment.c
+++ b/src/gallium/drivers/cell/ppu/cell_state_per_fragment.c
@@ -977,7 +977,6 @@ cell_generate_alpha_blend(struct cell_blend_state *cb)
spe_allocate_register(f, 13),
spe_allocate_register(f, 14),
};
- const int mask = spe_allocate_register(f, 15);
unsigned func[4];
unsigned sF[4];
unsigned dF[4];
@@ -1114,9 +1113,6 @@ cell_generate_alpha_blend(struct cell_blend_state *cb)
func[i], sF[i], dF[i],
frag[i], src_factor[i],
pixel[i], dst_factor[i]);
- spe_selb(f, frag[i], pixel[i], frag[i], mask);
- } else {
- spe_or(f, frag[i], pixel[i], pixel[i]);
}
}
@@ -1146,3 +1142,260 @@ cell_generate_alpha_blend(struct cell_blend_state *cb)
}
#endif
}
+
+
+int PC_OFFSET(const struct spe_function *f, const void *d)
+{
+ const intptr_t pc = (intptr_t) f->csr;
+ const intptr_t ea = ~0x0f & (intptr_t) d;
+
+ return (ea - pc) >> 2;
+}
+
+
+/**
+ * Generate code to perform color conversion and logic op
+ *
+ * \bug
+ * The code generated by this function should also perform dithering.
+ *
+ * \bug
+ * The code generated by this function should also perform color-write
+ * masking.
+ *
+ * \bug
+ * This routine is hard-coded to only work with ARGB8 data.
+ */
+void
+cell_generate_logic_op(struct spe_function *f, struct pipe_blend_state *blend,
+ struct pipe_surface *surf)
+{
+ const unsigned logic_op = (blend->logicop_enable)
+ ? blend->logicop_func : PIPE_LOGICOP_COPY;
+
+ /* This code generates a maximum of 37 instructions. An additional 32
+ * bytes (equiv. to 8 instructions) are needed for data storage. Round up
+ * to 64 to make it a happy power-of-two.
+ */
+ spe_init_func(f, 4 * 64);
+
+
+ /* Pixel colors in framebuffer format in AoS layout.
+ */
+ const int pixel[4] = {
+ spe_allocate_register(f, 3),
+ spe_allocate_register(f, 4),
+ spe_allocate_register(f, 5),
+ spe_allocate_register(f, 6),
+ };
+
+ /* Fragment colors stored as floats in SoA layout.
+ */
+ const int frag[4] = {
+ spe_allocate_register(f, 7),
+ spe_allocate_register(f, 8),
+ spe_allocate_register(f, 9),
+ spe_allocate_register(f, 10),
+ };
+
+ const int mask = spe_allocate_register(f, 11);
+
+
+ /* Short-circuit the noop and invert cases.
+ */
+ if ((logic_op == PIPE_LOGICOP_NOOP) || (blend->colormask == 0)) {
+ spe_bi(f, 0, 0, 0);
+ return;
+ } else if (logic_op == PIPE_LOGICOP_INVERT) {
+ spe_nor(f, pixel[0], pixel[0], pixel[0]);
+ spe_nor(f, pixel[1], pixel[1], pixel[1]);
+ spe_nor(f, pixel[2], pixel[2], pixel[2]);
+ spe_nor(f, pixel[3], pixel[3], pixel[3]);
+ spe_bi(f, 0, 0, 0);
+ return;
+ }
+
+
+ const int tmp[4] = {
+ spe_allocate_available_register(f),
+ spe_allocate_available_register(f),
+ spe_allocate_available_register(f),
+ spe_allocate_available_register(f),
+ };
+
+ const int shuf_xpose_hi = spe_allocate_available_register(f);
+ const int shuf_xpose_lo = spe_allocate_available_register(f);
+ const int shuf_color = spe_allocate_available_register(f);
+
+
+ /* Pointer to the begining of the function's private data area.
+ */
+ uint32_t *const data = ((uint32_t *) f->store) + (64 - 8);
+
+
+ /* Convert fragment colors to framebuffer format in AoS layout.
+ */
+ data[0] = 0x00010203;
+ data[1] = 0x10111213;
+ data[2] = 0x04050607;
+ data[3] = 0x14151617;
+
+ data[4] = 0x0c000408;
+ data[5] = 0x80808080;
+ data[6] = 0x80808080;
+ data[7] = 0x80808080;
+
+ spe_ilh(f, tmp[0], 0x0808);
+ spe_lqr(f, shuf_xpose_hi, PC_OFFSET(f, data+0));
+ spe_lqr(f, shuf_color, PC_OFFSET(f, data+4));
+ spe_a(f, shuf_xpose_lo, shuf_xpose_hi, tmp[0]);
+
+ spe_shufb(f, tmp[0], frag[0], frag[2], shuf_xpose_hi);
+ spe_shufb(f, tmp[1], frag[0], frag[2], shuf_xpose_lo);
+ spe_shufb(f, tmp[2], frag[1], frag[3], shuf_xpose_hi);
+ spe_shufb(f, tmp[3], frag[1], frag[3], shuf_xpose_lo);
+
+ spe_shufb(f, frag[0], tmp[0], tmp[2], shuf_xpose_hi);
+ spe_shufb(f, frag[1], tmp[0], tmp[2], shuf_xpose_lo);
+ spe_shufb(f, frag[2], tmp[1], tmp[3], shuf_xpose_hi);
+ spe_shufb(f, frag[3], tmp[1], tmp[3], shuf_xpose_lo);
+
+ spe_cfltu(f, frag[0], frag[0], 32);
+ spe_cfltu(f, frag[1], frag[1], 32);
+ spe_cfltu(f, frag[2], frag[2], 32);
+ spe_cfltu(f, frag[3], frag[3], 32);
+
+ spe_shufb(f, frag[0], frag[0], pixel[0], shuf_color);
+ spe_shufb(f, frag[1], frag[1], pixel[1], shuf_color);
+ spe_shufb(f, frag[2], frag[2], pixel[2], shuf_color);
+ spe_shufb(f, frag[3], frag[3], pixel[3], shuf_color);
+
+
+ /* If logic op is enabled, perform the requested logical operation on the
+ * converted fragment colors and the pixel colors.
+ */
+ switch (logic_op) {
+ case PIPE_LOGICOP_CLEAR:
+ spe_il(f, frag[0], 0);
+ spe_il(f, frag[1], 0);
+ spe_il(f, frag[2], 0);
+ spe_il(f, frag[3], 0);
+ break;
+ case PIPE_LOGICOP_NOR:
+ spe_nor(f, frag[0], frag[0], pixel[0]);
+ spe_nor(f, frag[1], frag[1], pixel[1]);
+ spe_nor(f, frag[2], frag[2], pixel[2]);
+ spe_nor(f, frag[3], frag[3], pixel[3]);
+ break;
+ case PIPE_LOGICOP_AND_INVERTED:
+ spe_andc(f, frag[0], pixel[0], frag[0]);
+ spe_andc(f, frag[1], pixel[1], frag[1]);
+ spe_andc(f, frag[2], pixel[2], frag[2]);
+ spe_andc(f, frag[3], pixel[3], frag[3]);
+ break;
+ case PIPE_LOGICOP_COPY_INVERTED:
+ spe_nor(f, frag[0], frag[0], frag[0]);
+ spe_nor(f, frag[1], frag[1], frag[1]);
+ spe_nor(f, frag[2], frag[2], frag[2]);
+ spe_nor(f, frag[3], frag[3], frag[3]);
+ break;
+ case PIPE_LOGICOP_AND_REVERSE:
+ spe_andc(f, frag[0], frag[0], pixel[0]);
+ spe_andc(f, frag[1], frag[1], pixel[1]);
+ spe_andc(f, frag[2], frag[2], pixel[2]);
+ spe_andc(f, frag[3], frag[3], pixel[3]);
+ break;
+ case PIPE_LOGICOP_XOR:
+ spe_xor(f, frag[0], frag[0], pixel[0]);
+ spe_xor(f, frag[1], frag[1], pixel[1]);
+ spe_xor(f, frag[2], frag[2], pixel[2]);
+ spe_xor(f, frag[3], frag[3], pixel[3]);
+ break;
+ case PIPE_LOGICOP_NAND:
+ spe_nand(f, frag[0], frag[0], pixel[0]);
+ spe_nand(f, frag[1], frag[1], pixel[1]);
+ spe_nand(f, frag[2], frag[2], pixel[2]);
+ spe_nand(f, frag[3], frag[3], pixel[3]);
+ break;
+ case PIPE_LOGICOP_AND:
+ spe_and(f, frag[0], frag[0], pixel[0]);
+ spe_and(f, frag[1], frag[1], pixel[1]);
+ spe_and(f, frag[2], frag[2], pixel[2]);
+ spe_and(f, frag[3], frag[3], pixel[3]);
+ break;
+ case PIPE_LOGICOP_EQUIV:
+ spe_eqv(f, frag[0], frag[0], pixel[0]);
+ spe_eqv(f, frag[1], frag[1], pixel[1]);
+ spe_eqv(f, frag[2], frag[2], pixel[2]);
+ spe_eqv(f, frag[3], frag[3], pixel[3]);
+ break;
+ case PIPE_LOGICOP_OR_INVERTED:
+ spe_orc(f, frag[0], pixel[0], frag[0]);
+ spe_orc(f, frag[1], pixel[1], frag[1]);
+ spe_orc(f, frag[2], pixel[2], frag[2]);
+ spe_orc(f, frag[3], pixel[3], frag[3]);
+ break;
+ case PIPE_LOGICOP_COPY:
+ break;
+ case PIPE_LOGICOP_OR_REVERSE:
+ spe_orc(f, frag[0], frag[0], pixel[0]);
+ spe_orc(f, frag[1], frag[1], pixel[1]);
+ spe_orc(f, frag[2], frag[2], pixel[2]);
+ spe_orc(f, frag[3], frag[3], pixel[3]);
+ break;
+ case PIPE_LOGICOP_OR:
+ spe_or(f, frag[0], frag[0], pixel[0]);
+ spe_or(f, frag[1], frag[1], pixel[1]);
+ spe_or(f, frag[2], frag[2], pixel[2]);
+ spe_or(f, frag[3], frag[3], pixel[3]);
+ break;
+ case PIPE_LOGICOP_SET:
+ spe_il(f, frag[0], ~0);
+ spe_il(f, frag[1], ~0);
+ spe_il(f, frag[2], ~0);
+ spe_il(f, frag[3], ~0);
+ break;
+
+ /* These two cases are short-circuited above.
+ */
+ case PIPE_LOGICOP_INVERT:
+ case PIPE_LOGICOP_NOOP:
+ default:
+ assert(0);
+ }
+
+
+ /* Apply fragment mask.
+ */
+ spe_ilh(f, tmp[0], 0x0000);
+ spe_ilh(f, tmp[1], 0x0404);
+ spe_ilh(f, tmp[2], 0x0808);
+ spe_ilh(f, tmp[3], 0x0c0c);
+
+ spe_shufb(f, tmp[0], mask, mask, tmp[0]);
+ spe_shufb(f, tmp[1], mask, mask, tmp[1]);
+ spe_shufb(f, tmp[2], mask, mask, tmp[2]);
+ spe_shufb(f, tmp[3], mask, mask, tmp[3]);
+
+ spe_selb(f, pixel[0], pixel[0], frag[0], tmp[0]);
+ spe_selb(f, pixel[1], pixel[1], frag[1], tmp[1]);
+ spe_selb(f, pixel[2], pixel[2], frag[2], tmp[2]);
+ spe_selb(f, pixel[3], pixel[3], frag[3], tmp[3]);
+
+ spe_bi(f, 0, 0, 0);
+
+#if 0
+ {
+ const uint32_t *p = f->store;
+ unsigned i;
+
+ printf("# %u instructions\n", f->csr - f->store);
+
+ printf("\t.text\n");
+ for (i = 0; i < 64; i++) {
+ printf("\t.long\t0x%04x\n", p[i]);
+ }
+ fflush(stdout);
+ }
+#endif
+}
diff --git a/src/gallium/drivers/cell/ppu/cell_state_per_fragment.h b/src/gallium/drivers/cell/ppu/cell_state_per_fragment.h
index f699247f9e4..ab4de96c69d 100644
--- a/src/gallium/drivers/cell/ppu/cell_state_per_fragment.h
+++ b/src/gallium/drivers/cell/ppu/cell_state_per_fragment.h
@@ -31,4 +31,8 @@ cell_generate_depth_stencil_test(struct cell_depth_stencil_alpha_state *cdsa);
extern void
cell_generate_alpha_blend(struct cell_blend_state *cb);
+extern void
+cell_generate_logic_op(struct spe_function *f, struct pipe_blend_state *blend,
+ struct pipe_surface *surf);
+
#endif /* CELL_STATE_PER_FRAGMENT_H */
diff --git a/src/gallium/drivers/cell/ppu/cell_state_vertex.c b/src/gallium/drivers/cell/ppu/cell_state_vertex.c
index 563831b62db..6c83b8dc722 100644
--- a/src/gallium/drivers/cell/ppu/cell_state_vertex.c
+++ b/src/gallium/drivers/cell/ppu/cell_state_vertex.c
@@ -36,28 +36,34 @@
void
-cell_set_vertex_element(struct pipe_context *pipe,
- unsigned index,
- const struct pipe_vertex_element *attrib)
+cell_set_vertex_elements(struct pipe_context *pipe,
+ unsigned count,
+ const struct pipe_vertex_element *elements)
{
struct cell_context *cell = cell_context(pipe);
- assert(index < PIPE_ATTRIB_MAX);
- cell->vertex_element[index] = *attrib; /* struct copy */
+
+ assert(count <= PIPE_MAX_ATTRIBS);
+
+ memcpy(cell->vertex_element, elements, count * sizeof(elements[0]));
+
cell->dirty |= CELL_NEW_VERTEX;
- draw_set_vertex_element(cell->draw, index, attrib);
+ draw_set_vertex_elements(cell->draw, count, elements);
}
void
-cell_set_vertex_buffer(struct pipe_context *pipe,
- unsigned index,
- const struct pipe_vertex_buffer *buffer)
+cell_set_vertex_buffers(struct pipe_context *pipe,
+ unsigned count,
+ const struct pipe_vertex_buffer *buffers)
{
struct cell_context *cell = cell_context(pipe);
- assert(index < PIPE_ATTRIB_MAX);
- cell->vertex_buffer[index] = *buffer; /* struct copy */
+
+ assert(count <= PIPE_MAX_ATTRIBS);
+
+ memcpy(cell->vertex_buffer, buffers, count * sizeof(buffers[0]));
+
cell->dirty |= CELL_NEW_VERTEX;
- draw_set_vertex_buffer(cell->draw, index, buffer);
+ draw_set_vertex_buffers(cell->draw, count, buffers);
}
diff --git a/src/gallium/drivers/cell/ppu/cell_vbuf.c b/src/gallium/drivers/cell/ppu/cell_vbuf.c
index cc727ff4edb..3a181b585c5 100644
--- a/src/gallium/drivers/cell/ppu/cell_vbuf.c
+++ b/src/gallium/drivers/cell/ppu/cell_vbuf.c
@@ -243,7 +243,7 @@ cell_vbuf_draw(struct vbuf_render *vbr,
#if 0
/* helpful for debug */
- cell_flush_int(&cell->pipe, PIPE_FLUSH_WAIT);
+ cell_flush_int(&cell->pipe, CELL_FLUSH_WAIT);
#endif
}
diff --git a/src/gallium/drivers/cell/ppu/cell_vertex_fetch.c b/src/gallium/drivers/cell/ppu/cell_vertex_fetch.c
index 4828a8023bd..49d5443cde7 100644
--- a/src/gallium/drivers/cell/ppu/cell_vertex_fetch.c
+++ b/src/gallium/drivers/cell/ppu/cell_vertex_fetch.c
@@ -263,7 +263,7 @@ void cell_update_vertex_fetch(struct draw_context *draw)
struct cell_context *const cell =
(struct cell_context *) draw->driver_private;
struct spe_function *p = &cell->attrib_fetch;
- unsigned function_index[PIPE_ATTRIB_MAX];
+ unsigned function_index[PIPE_MAX_ATTRIBS];
unsigned unique_attr_formats;
int out_ptr;
int in_ptr;
diff --git a/src/gallium/drivers/cell/ppu/cell_vertex_shader.c b/src/gallium/drivers/cell/ppu/cell_vertex_shader.c
index f5c27852c14..f753960a0fb 100644
--- a/src/gallium/drivers/cell/ppu/cell_vertex_shader.c
+++ b/src/gallium/drivers/cell/ppu/cell_vertex_shader.c
@@ -69,7 +69,7 @@ cell_vertex_shader_queue_flush(struct draw_context *draw)
batch = cell_batch_alloc(cell, sizeof(batch[0]) + sizeof(*cf));
batch[0] = CELL_CMD_STATE_ATTRIB_FETCH;
cf = (struct cell_attribute_fetch_code *) (&batch[1]);
- cf->base = cell->attrib_fetch.store;
+ cf->base = (uint64_t) cell->attrib_fetch.store;
cf->size = ROUNDUP16((unsigned)((void *) cell->attrib_fetch.csr
- (void *) cell->attrib_fetch.store));
@@ -133,7 +133,7 @@ cell_vertex_shader_queue_flush(struct draw_context *draw)
vs->num_elts = n;
send_mbox_message(cell_global.spe_contexts[0], CELL_CMD_VS_EXECUTE);
- cell_flush_int(& cell->pipe, PIPE_FLUSH_WAIT);
+ cell_flush_int(& cell->pipe, CELL_FLUSH_WAIT);
}
draw->vs.post_nr = draw->vs.queue_nr;
diff --git a/src/gallium/drivers/cell/spu/spu_exec.c b/src/gallium/drivers/cell/spu/spu_exec.c
index 061fbebf618..48edc62f49b 100644
--- a/src/gallium/drivers/cell/spu/spu_exec.c
+++ b/src/gallium/drivers/cell/spu/spu_exec.c
@@ -1453,7 +1453,7 @@ exec_instruction(
break;
case TGSI_OPCODE_TXP:
- /* Texture lookup with projection
+ /* Texture lookup with projection */
/* src[0] = texcoord (src[0].w = projection) */
/* src[1] = sampler unit */
exec_tex(mach, inst, TRUE, TRUE);
diff --git a/src/gallium/drivers/cell/spu/spu_main.c b/src/gallium/drivers/cell/spu/spu_main.c
index 0a490ab277f..d7f46f80246 100644
--- a/src/gallium/drivers/cell/spu/spu_main.c
+++ b/src/gallium/drivers/cell/spu/spu_main.c
@@ -55,7 +55,7 @@ struct spu_global spu;
struct spu_vs_context draw;
-static unsigned char attribute_fetch_code_buffer[136 * PIPE_ATTRIB_MAX]
+static unsigned char attribute_fetch_code_buffer[136 * PIPE_MAX_ATTRIBS]
ALIGN16_ATTRIB;
static unsigned char depth_stencil_code_buffer[4 * 64]
@@ -64,6 +64,9 @@ static unsigned char depth_stencil_code_buffer[4 * 64]
static unsigned char fb_blend_code_buffer[4 * 64]
ALIGN16_ATTRIB;
+static unsigned char logicop_code_buffer[4 * 64]
+ ALIGN16_ATTRIB;
+
/**
* Tell the PPU that this SPU has finished copying a buffer to
@@ -358,7 +361,7 @@ cmd_state_vs_array_info(const struct cell_array_info *vs_info)
{
const unsigned attr = vs_info->attr;
- ASSERT(attr < PIPE_ATTRIB_MAX);
+ ASSERT(attr < PIPE_MAX_ATTRIBS);
draw.vertex_fetch.src_ptr[attr] = vs_info->base;
draw.vertex_fetch.pitch[attr] = vs_info->pitch;
draw.vertex_fetch.size[attr] = vs_info->size;
@@ -513,6 +516,22 @@ cmd_batch(uint opcode)
pos += (1 + ROUNDUP8(sizeof(struct cell_attribute_fetch_code)) / 8);
break;
}
+ case CELL_CMD_STATE_LOGICOP: {
+ struct cell_command_logicop *code =
+ (struct cell_command_logicop *) &buffer[pos+1];
+
+ mfc_get(logicop_code_buffer,
+ (unsigned int) code->base, /* src */
+ code->size,
+ TAG_BATCH_BUFFER,
+ 0, /* tid */
+ 0 /* rid */);
+ wait_on_mask(1 << TAG_BATCH_BUFFER);
+
+ spu.logicop = (logicop_func) logicop_code_buffer;
+ pos += (1 + ROUNDUP8(sizeof(struct cell_command_logicop)) / 8);
+ break;
+ }
case CELL_CMD_FLUSH_BUFFER_RANGE: {
struct cell_buffer_range *br = (struct cell_buffer_range *)
&buffer[pos+1];
diff --git a/src/gallium/drivers/cell/spu/spu_main.h b/src/gallium/drivers/cell/spu/spu_main.h
index 49f5d99674a..c20452931a9 100644
--- a/src/gallium/drivers/cell/spu/spu_main.h
+++ b/src/gallium/drivers/cell/spu/spu_main.h
@@ -77,9 +77,14 @@ struct spu_blend_results {
typedef struct spu_blend_results (*blend_func)(
qword frag_r, qword frag_g, qword frag_b, qword frag_a,
qword pixel_r, qword pixel_g, qword pixel_b, qword pixel_a,
- qword const_r, qword const_g, qword const_b, qword const_a,
+ qword const_r, qword const_g, qword const_b, qword const_a);
+
+typedef struct spu_blend_results (*logicop_func)(
+ qword pixel_r, qword pixel_g, qword pixel_b, qword pixel_a,
+ qword frag_r, qword frag_g, qword frag_b, qword frag_a,
qword frag_mask);
+
struct spu_framebuffer {
void *color_start; /**< addr of color surface in main memory */
void *depth_start; /**< addr of depth surface in main memory */
@@ -111,6 +116,8 @@ struct spu_global
blend_func blend;
qword const_blend_color[4] ALIGN16_ATTRIB;
+ logicop_func logicop;
+
struct pipe_sampler_state sampler[PIPE_MAX_SAMPLERS];
struct cell_command_texture texture;
diff --git a/src/gallium/drivers/cell/spu/spu_tri.c b/src/gallium/drivers/cell/spu/spu_tri.c
index e6a1ce01dfd..95c629a8aae 100644
--- a/src/gallium/drivers/cell/spu/spu_tri.c
+++ b/src/gallium/drivers/cell/spu/spu_tri.c
@@ -305,7 +305,6 @@ emit_quad( int x, int y, mask_t mask )
if (spu_extract(spu_orx(mask), 0)) {
const int ix = x - setup.cliprect_minx;
const int iy = y - setup.cliprect_miny;
- const vector unsigned char shuffle = spu.color_shuffle;
vector float colors[4];
spu.cur_ctile_status = TILE_STATUS_DIRTY;
@@ -330,45 +329,53 @@ emit_quad( int x, int y, mask_t mask )
}
+ /* Convert fragment data from AoS to SoA format.
+ */
+ qword soa_frag[4];
+ _transpose_matrix4x4((vec_float4 *) soa_frag, colors);
+
/* Read the current framebuffer values.
- *
- * Ignore read_fb for now. In the future we can use this to avoid
- * reading the framebuffer if read_fb is false and the fragment mask is
- * all 0xffffffff. This is the common case, so it is probably worth
- * the effort. We'll have to profile to determine whether or not the
- * extra conditional branches hurt overall performance.
*/
- vec_float4 aos_pix[4] = {
- spu_unpack_A8R8G8B8(spu.ctile.ui[iy+0][ix+0]),
- spu_unpack_A8R8G8B8(spu.ctile.ui[iy+0][ix+1]),
- spu_unpack_A8R8G8B8(spu.ctile.ui[iy+1][ix+0]),
- spu_unpack_A8R8G8B8(spu.ctile.ui[iy+1][ix+1]),
+ const qword pix[4] = {
+ (qword) spu_splats(spu.ctile.ui[iy+0][ix+0]),
+ (qword) spu_splats(spu.ctile.ui[iy+0][ix+1]),
+ (qword) spu_splats(spu.ctile.ui[iy+1][ix+0]),
+ (qword) spu_splats(spu.ctile.ui[iy+1][ix+1]),
};
qword soa_pix[4];
- qword soa_frag[4];
- /* Convert pixel and fragment data from AoS to SoA format.
- */
- _transpose_matrix4x4((vec_float4 *) soa_pix, aos_pix);
- _transpose_matrix4x4((vec_float4 *) soa_frag, colors);
+ if (spu.read_fb) {
+ /* Convert pixel data from AoS to SoA format.
+ */
+ vec_float4 aos_pix[4] = {
+ spu_unpack_A8R8G8B8(spu.ctile.ui[iy+0][ix+0]),
+ spu_unpack_A8R8G8B8(spu.ctile.ui[iy+0][ix+1]),
+ spu_unpack_A8R8G8B8(spu.ctile.ui[iy+1][ix+0]),
+ spu_unpack_A8R8G8B8(spu.ctile.ui[iy+1][ix+1]),
+ };
+
+ _transpose_matrix4x4((vec_float4 *) soa_pix, aos_pix);
+ }
- const struct spu_blend_results result =
+
+ struct spu_blend_results result =
(*spu.blend)(soa_frag[0], soa_frag[1], soa_frag[2], soa_frag[3],
soa_pix[0], soa_pix[1], soa_pix[2], soa_pix[3],
spu.const_blend_color[0], spu.const_blend_color[1],
- spu.const_blend_color[2], spu.const_blend_color[3],
- (qword) mask);
+ spu.const_blend_color[2], spu.const_blend_color[3]);
/* Convert final pixel data from SoA to AoS format.
*/
- _transpose_matrix4x4(aos_pix, (const vec_float4 *) &result);
-
- spu.ctile.ui[iy+0][ix+0] = spu_pack_color_shuffle(aos_pix[0], shuffle);
- spu.ctile.ui[iy+0][ix+1] = spu_pack_color_shuffle(aos_pix[1], shuffle);
- spu.ctile.ui[iy+1][ix+0] = spu_pack_color_shuffle(aos_pix[2], shuffle);
- spu.ctile.ui[iy+1][ix+1] = spu_pack_color_shuffle(aos_pix[3], shuffle);
+ result = (*spu.logicop)(pix[0], pix[1], pix[2], pix[3],
+ result.r, result.g, result.b, result.a,
+ (qword) mask);
+
+ spu.ctile.ui[iy+0][ix+0] = spu_extract((vec_uint4) result.r, 0);
+ spu.ctile.ui[iy+0][ix+1] = spu_extract((vec_uint4) result.g, 0);
+ spu.ctile.ui[iy+1][ix+0] = spu_extract((vec_uint4) result.b, 0);
+ spu.ctile.ui[iy+1][ix+1] = spu_extract((vec_uint4) result.a, 0);
}
#endif
}
diff --git a/src/gallium/drivers/cell/spu/spu_vertex_shader.c b/src/gallium/drivers/cell/spu/spu_vertex_shader.c
index 8363efeeb6e..3119a78c060 100644
--- a/src/gallium/drivers/cell/spu/spu_vertex_shader.c
+++ b/src/gallium/drivers/cell/spu/spu_vertex_shader.c
@@ -86,8 +86,8 @@ run_vertex_program(struct spu_vs_context *draw,
struct spu_exec_machine *machine = &draw->machine;
unsigned int j;
- ALIGN16_DECL(struct spu_exec_vector, inputs, PIPE_ATTRIB_MAX);
- ALIGN16_DECL(struct spu_exec_vector, outputs, PIPE_ATTRIB_MAX);
+ ALIGN16_DECL(struct spu_exec_vector, inputs, PIPE_MAX_ATTRIBS);
+ ALIGN16_DECL(struct spu_exec_vector, outputs, PIPE_MAX_ATTRIBS);
const float *scale = draw->viewport.scale;
const float *trans = draw->viewport.translate;
diff --git a/src/gallium/drivers/cell/spu/spu_vertex_shader.h b/src/gallium/drivers/cell/spu/spu_vertex_shader.h
index 54a4b8d9b9f..4c74f5e74d5 100644
--- a/src/gallium/drivers/cell/spu/spu_vertex_shader.h
+++ b/src/gallium/drivers/cell/spu/spu_vertex_shader.h
@@ -16,10 +16,10 @@ struct spu_vs_context {
struct pipe_viewport_state viewport;
struct {
- uint64_t src_ptr[PIPE_ATTRIB_MAX];
- unsigned pitch[PIPE_ATTRIB_MAX];
- unsigned size[PIPE_ATTRIB_MAX];
- unsigned code_offset[PIPE_ATTRIB_MAX];
+ uint64_t src_ptr[PIPE_MAX_ATTRIBS];
+ unsigned pitch[PIPE_MAX_ATTRIBS];
+ unsigned size[PIPE_MAX_ATTRIBS];
+ unsigned code_offset[PIPE_MAX_ATTRIBS];
unsigned nr_attrs;
boolean dirty;
diff --git a/src/gallium/drivers/failover/fo_context.c b/src/gallium/drivers/failover/fo_context.c
index afc0d7eb1ec..cb95ba516f9 100644
--- a/src/gallium/drivers/failover/fo_context.c
+++ b/src/gallium/drivers/failover/fo_context.c
@@ -69,7 +69,7 @@ static boolean failover_draw_elements( struct pipe_context *pipe,
start,
count )) {
- failover->hw->flush( failover->hw, ~0 );
+ failover->hw->flush( failover->hw, ~0, NULL );
failover->mode = FO_SW;
}
}
@@ -92,7 +92,7 @@ static boolean failover_draw_elements( struct pipe_context *pipe,
* intervening flush. Unlikely to be much performance impact to
* this:
*/
- failover->sw->flush( failover->sw, ~0 );
+ failover->sw->flush( failover->sw, ~0, NULL );
}
return TRUE;
diff --git a/src/gallium/drivers/failover/fo_context.h b/src/gallium/drivers/failover/fo_context.h
index 8f3ad3ee798..c6409fe1e1c 100644
--- a/src/gallium/drivers/failover/fo_context.h
+++ b/src/gallium/drivers/failover/fo_context.h
@@ -84,15 +84,16 @@ struct failover_context {
struct pipe_scissor_state scissor;
struct pipe_texture *texture[PIPE_MAX_SAMPLERS];
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_buffers[PIPE_MAX_ATTRIBS];
+ struct pipe_vertex_element vertex_elements[PIPE_MAX_ATTRIBS];
+
+ uint num_vertex_buffers;
+ uint num_vertex_elements;
void *sw_sampler_state[PIPE_MAX_SAMPLERS];
void *hw_sampler_state[PIPE_MAX_SAMPLERS];
unsigned dirty;
- unsigned dirty_vertex_buffer;
- unsigned dirty_vertex_element;
unsigned num_samplers;
unsigned num_textures;
diff --git a/src/gallium/drivers/failover/fo_state.c b/src/gallium/drivers/failover/fo_state.c
index 11eec2714eb..6a797066322 100644
--- a/src/gallium/drivers/failover/fo_state.c
+++ b/src/gallium/drivers/failover/fo_state.c
@@ -402,32 +402,35 @@ failover_set_viewport_state( struct pipe_context *pipe,
static void
-failover_set_vertex_buffer(struct pipe_context *pipe,
- unsigned unit,
- const struct pipe_vertex_buffer *vertex_buffer)
+failover_set_vertex_buffers(struct pipe_context *pipe,
+ unsigned count,
+ const struct pipe_vertex_buffer *vertex_buffers)
{
struct failover_context *failover = failover_context(pipe);
- failover->vertex_buffer[unit] = *vertex_buffer;
+ memcpy(failover->vertex_buffers, vertex_buffers,
+ count * sizeof(vertex_buffers[0]));
failover->dirty |= FO_NEW_VERTEX_BUFFER;
- failover->dirty_vertex_buffer |= (1<<unit);
- failover->sw->set_vertex_buffer( failover->sw, unit, vertex_buffer );
- failover->hw->set_vertex_buffer( failover->hw, unit, vertex_buffer );
+ failover->num_vertex_buffers = count;
+ failover->sw->set_vertex_buffers( failover->sw, count, vertex_buffers );
+ failover->hw->set_vertex_buffers( failover->hw, count, vertex_buffers );
}
static void
-failover_set_vertex_element(struct pipe_context *pipe,
- unsigned unit,
- const struct pipe_vertex_element *vertex_element)
+failover_set_vertex_elements(struct pipe_context *pipe,
+ unsigned count,
+ const struct pipe_vertex_element *vertex_elements)
{
struct failover_context *failover = failover_context(pipe);
- failover->vertex_element[unit] = *vertex_element;
+ memcpy(failover->vertex_elements, vertex_elements,
+ count * sizeof(vertex_elements[0]));
+
failover->dirty |= FO_NEW_VERTEX_ELEMENT;
- failover->dirty_vertex_element |= (1<<unit);
- failover->sw->set_vertex_element( failover->sw, unit, vertex_element );
- failover->hw->set_vertex_element( failover->hw, unit, vertex_element );
+ failover->num_vertex_elements = count;
+ failover->sw->set_vertex_elements( failover->sw, count, vertex_elements );
+ failover->hw->set_vertex_elements( failover->hw, count, vertex_elements );
}
void
@@ -474,7 +477,7 @@ failover_init_state_functions( struct failover_context *failover )
failover->pipe.set_scissor_state = failover_set_scissor_state;
failover->pipe.set_sampler_textures = failover_set_sampler_textures;
failover->pipe.set_viewport_state = failover_set_viewport_state;
- failover->pipe.set_vertex_buffer = failover_set_vertex_buffer;
- failover->pipe.set_vertex_element = failover_set_vertex_element;
+ failover->pipe.set_vertex_buffers = failover_set_vertex_buffers;
+ failover->pipe.set_vertex_elements = failover_set_vertex_elements;
failover->pipe.set_constant_buffer = failover_set_constant_buffer;
}
diff --git a/src/gallium/drivers/failover/fo_state_emit.c b/src/gallium/drivers/failover/fo_state_emit.c
index 3de931e04eb..bd4fce9d209 100644
--- a/src/gallium/drivers/failover/fo_state_emit.c
+++ b/src/gallium/drivers/failover/fo_state_emit.c
@@ -53,8 +53,6 @@
void
failover_state_emit( struct failover_context *failover )
{
- unsigned i;
-
if (failover->dirty & FO_NEW_BLEND)
failover->sw->bind_blend_state( failover->sw,
failover->blend->sw_state );
@@ -104,24 +102,16 @@ failover_state_emit( struct failover_context *failover )
}
if (failover->dirty & FO_NEW_VERTEX_BUFFER) {
- for (i = 0; i < PIPE_ATTRIB_MAX; i++) {
- if (failover->dirty_vertex_buffer & (1<<i)) {
- failover->sw->set_vertex_buffer( failover->sw, i,
- &failover->vertex_buffer[i] );
- }
- }
+ failover->sw->set_vertex_buffers( failover->sw,
+ failover->num_vertex_buffers,
+ failover->vertex_buffers );
}
if (failover->dirty & FO_NEW_VERTEX_ELEMENT) {
- for (i = 0; i < PIPE_ATTRIB_MAX; i++) {
- if (failover->dirty_vertex_element & (1<<i)) {
- failover->sw->set_vertex_element( failover->sw, i,
- &failover->vertex_element[i] );
- }
- }
+ failover->sw->set_vertex_elements( failover->sw,
+ failover->num_vertex_elements,
+ failover->vertex_elements );
}
failover->dirty = 0;
- failover->dirty_vertex_element = 0;
- failover->dirty_vertex_buffer = 0;
}
diff --git a/src/gallium/drivers/i915simple/i915_batch.h b/src/gallium/drivers/i915simple/i915_batch.h
index fb88cd6db0d..4ea06ce02bf 100644
--- a/src/gallium/drivers/i915simple/i915_batch.h
+++ b/src/gallium/drivers/i915simple/i915_batch.h
@@ -44,9 +44,9 @@
#define ADVANCE_BATCH()
-#define FLUSH_BATCH() do { \
+#define FLUSH_BATCH(fence) do { \
if (0) i915_dump_batchbuffer( i915 ); \
- i915->winsys->batch_flush( i915->winsys ); \
+ i915->winsys->batch_flush( i915->winsys, fence ); \
i915->batch_start = NULL; \
i915->hardware_dirty = ~0; \
} while (0)
diff --git a/src/gallium/drivers/i915simple/i915_blit.c b/src/gallium/drivers/i915simple/i915_blit.c
index db4671ff553..24449e3fb33 100644
--- a/src/gallium/drivers/i915simple/i915_blit.c
+++ b/src/gallium/drivers/i915simple/i915_blit.c
@@ -70,7 +70,7 @@ i915_fill_blit(struct i915_context *i915,
if (!BEGIN_BATCH(6, 1)) {
- FLUSH_BATCH();
+ FLUSH_BATCH(NULL);
assert(BEGIN_BATCH(6, 1));
}
OUT_BATCH(CMD);
@@ -145,7 +145,7 @@ i915_copy_blit( struct i915_context *i915,
if (!BEGIN_BATCH(8, 2)) {
- FLUSH_BATCH();
+ FLUSH_BATCH(NULL);
assert(BEGIN_BATCH(8, 2));
}
OUT_BATCH(CMD);
diff --git a/src/gallium/drivers/i915simple/i915_context.c b/src/gallium/drivers/i915simple/i915_context.c
index 15ff2360b74..fee33d82de4 100644
--- a/src/gallium/drivers/i915simple/i915_context.c
+++ b/src/gallium/drivers/i915simple/i915_context.c
@@ -65,7 +65,7 @@ i915_draw_elements( struct pipe_context *pipe,
/*
* Map vertex buffers
*/
- for (i = 0; i < PIPE_ATTRIB_MAX; i++) {
+ for (i = 0; i < PIPE_MAX_ATTRIBS; i++) {
if (i915->vertex_buffer[i].buffer) {
void *buf
= pipe->winsys->buffer_map(pipe->winsys,
@@ -96,7 +96,7 @@ i915_draw_elements( struct pipe_context *pipe,
/*
* unmap vertex/index buffers
*/
- for (i = 0; i < PIPE_ATTRIB_MAX; i++) {
+ for (i = 0; i < PIPE_MAX_ATTRIBS; i++) {
if (i915->vertex_buffer[i].buffer) {
pipe->winsys->buffer_unmap(pipe->winsys, i915->vertex_buffer[i].buffer);
draw_set_mapped_vertex_buffer(draw, i, NULL);
diff --git a/src/gallium/drivers/i915simple/i915_context.h b/src/gallium/drivers/i915simple/i915_context.h
index 746f18ba38d..8e707ea574a 100644
--- a/src/gallium/drivers/i915simple/i915_context.h
+++ b/src/gallium/drivers/i915simple/i915_context.h
@@ -232,7 +232,7 @@ struct i915_context
struct pipe_scissor_state scissor;
struct i915_texture *texture[PIPE_MAX_SAMPLERS];
struct pipe_viewport_state viewport;
- struct pipe_vertex_buffer vertex_buffer[PIPE_ATTRIB_MAX];
+ struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS];
unsigned dirty;
diff --git a/src/gallium/drivers/i915simple/i915_flush.c b/src/gallium/drivers/i915simple/i915_flush.c
index 96a54281f11..7d23e6b6b90 100644
--- a/src/gallium/drivers/i915simple/i915_flush.c
+++ b/src/gallium/drivers/i915simple/i915_flush.c
@@ -37,11 +37,9 @@
#include "i915_batch.h"
-/**
- * In future we may want a fence-like interface instead of finish.
- */
static void i915_flush( struct pipe_context *pipe,
- unsigned flags )
+ unsigned flags,
+ struct pipe_fence_handle **fence )
{
struct i915_context *i915 = i915_context(pipe);
@@ -60,7 +58,7 @@ static void i915_flush( struct pipe_context *pipe,
flush |= FLUSH_MAP_CACHE;
if (!BEGIN_BATCH(1, 0)) {
- FLUSH_BATCH();
+ FLUSH_BATCH(NULL);
assert(BEGIN_BATCH(1, 0));
}
OUT_BATCH( flush );
@@ -69,11 +67,7 @@ static void i915_flush( struct pipe_context *pipe,
/* If there are no flags, just flush pending commands to hardware:
*/
- FLUSH_BATCH();
-
- if (flags & PIPE_FLUSH_WAIT) {
- i915->winsys->batch_finish(i915->winsys);
- }
+ FLUSH_BATCH(fence);
}
diff --git a/src/gallium/drivers/i915simple/i915_prim_emit.c b/src/gallium/drivers/i915simple/i915_prim_emit.c
index d8de5178f60..b6fb0a6d88f 100644
--- a/src/gallium/drivers/i915simple/i915_prim_emit.c
+++ b/src/gallium/drivers/i915simple/i915_prim_emit.c
@@ -140,7 +140,7 @@ emit_prim( struct draw_stage *stage,
assert(vertex_size >= 12); /* never smaller than 12 bytes */
if (!BEGIN_BATCH( 1 + nr * vertex_size / 4, 0 )) {
- FLUSH_BATCH();
+ FLUSH_BATCH(NULL);
/* Make sure state is re-emitted after a flush:
*/
diff --git a/src/gallium/drivers/i915simple/i915_prim_vbuf.c b/src/gallium/drivers/i915simple/i915_prim_vbuf.c
index eb64f51943b..7fb2adbb53b 100644
--- a/src/gallium/drivers/i915simple/i915_prim_vbuf.c
+++ b/src/gallium/drivers/i915simple/i915_prim_vbuf.c
@@ -161,7 +161,7 @@ i915_vbuf_render_draw( struct vbuf_render *render,
i915_emit_hardware_state( i915 );
if (!BEGIN_BATCH( 1 + (nr_indices + 1)/2, 1 )) {
- FLUSH_BATCH();
+ FLUSH_BATCH(NULL);
/* Make sure state is re-emitted after a flush:
*/
diff --git a/src/gallium/drivers/i915simple/i915_state.c b/src/gallium/drivers/i915simple/i915_state.c
index 1cec36e206d..4404bc45901 100644
--- a/src/gallium/drivers/i915simple/i915_state.c
+++ b/src/gallium/drivers/i915simple/i915_state.c
@@ -687,23 +687,24 @@ static void i915_delete_rasterizer_state(struct pipe_context *pipe,
FREE(raster);
}
-static void i915_set_vertex_buffer( struct pipe_context *pipe,
- unsigned index,
- const struct pipe_vertex_buffer *buffer )
+static void i915_set_vertex_buffers(struct pipe_context *pipe,
+ unsigned count,
+ const struct pipe_vertex_buffer *buffers)
{
struct i915_context *i915 = i915_context(pipe);
- i915->vertex_buffer[index] = *buffer;
+
+ memcpy(i915->vertex_buffer, buffers, count * sizeof(buffers[0]));
/* pass-through to draw module */
- draw_set_vertex_buffer(i915->draw, index, buffer);
+ draw_set_vertex_buffers(i915->draw, count, buffers);
}
-static void i915_set_vertex_element( struct pipe_context *pipe,
- unsigned index,
- const struct pipe_vertex_element *element)
+static void i915_set_vertex_elements(struct pipe_context *pipe,
+ unsigned count,
+ const struct pipe_vertex_element *elements)
{
struct i915_context *i915 = i915_context(pipe);
/* pass-through to draw module */
- draw_set_vertex_element(i915->draw, index, element);
+ draw_set_vertex_elements(i915->draw, count, elements);
}
@@ -742,6 +743,6 @@ i915_init_state_functions( struct i915_context *i915 )
i915->pipe.set_scissor_state = i915_set_scissor_state;
i915->pipe.set_sampler_textures = i915_set_sampler_textures;
i915->pipe.set_viewport_state = i915_set_viewport_state;
- i915->pipe.set_vertex_buffer = i915_set_vertex_buffer;
- i915->pipe.set_vertex_element = i915_set_vertex_element;
+ i915->pipe.set_vertex_buffers = i915_set_vertex_buffers;
+ i915->pipe.set_vertex_elements = i915_set_vertex_elements;
}
diff --git a/src/gallium/drivers/i915simple/i915_state_emit.c b/src/gallium/drivers/i915simple/i915_state_emit.c
index a7498d22b7e..6f947d43468 100644
--- a/src/gallium/drivers/i915simple/i915_state_emit.c
+++ b/src/gallium/drivers/i915simple/i915_state_emit.c
@@ -115,7 +115,7 @@ i915_emit_hardware_state(struct i915_context *i915 )
#endif
if(!BEGIN_BATCH(dwords, relocs)) {
- FLUSH_BATCH();
+ FLUSH_BATCH(NULL);
assert(BEGIN_BATCH(dwords, relocs));
}
diff --git a/src/gallium/drivers/i915simple/i915_winsys.h b/src/gallium/drivers/i915simple/i915_winsys.h
index aea30032818..5e16543f4ec 100644
--- a/src/gallium/drivers/i915simple/i915_winsys.h
+++ b/src/gallium/drivers/i915simple/i915_winsys.h
@@ -56,6 +56,7 @@ extern "C" {
*/
struct pipe_buffer;
+struct pipe_fence_handle;
struct pipe_winsys;
struct pipe_screen;
@@ -103,8 +104,8 @@ struct i915_winsys {
unsigned access_flags,
unsigned delta );
- void (*batch_flush)( struct i915_winsys *sws );
- void (*batch_finish)( struct i915_winsys *sws );
+ void (*batch_flush)( struct i915_winsys *sws,
+ struct pipe_fence_handle **fence );
};
#define I915_BUFFER_ACCESS_WRITE 0x1
diff --git a/src/gallium/drivers/i965simple/brw_clip.h b/src/gallium/drivers/i965simple/brw_clip.h
index a89d08b7910..d70fc094ff5 100644
--- a/src/gallium/drivers/i965simple/brw_clip.h
+++ b/src/gallium/drivers/i965simple/brw_clip.h
@@ -116,7 +116,7 @@ struct brw_clip_compile {
unsigned last_mrf;
unsigned header_position_offset;
- unsigned offset[PIPE_ATTRIB_MAX];
+ unsigned offset[PIPE_MAX_ATTRIBS];
};
#define ATTR_SIZE (4*4)
diff --git a/src/gallium/drivers/i965simple/brw_context.h b/src/gallium/drivers/i965simple/brw_context.h
index b83a13c3b6b..0c96ba17327 100644
--- a/src/gallium/drivers/i965simple/brw_context.h
+++ b/src/gallium/drivers/i965simple/brw_context.h
@@ -433,17 +433,17 @@ struct brw_cached_batch_item {
-/* Protect against a future where PIPE_ATTRIB_MAX > 32. Wouldn't life
+/* Protect against a future where PIPE_MAX_ATTRIBS > 32. Wouldn't life
* be easier if C allowed arrays of packed elements?
*/
-#define ATTRIB_BIT_DWORDS ((PIPE_ATTRIB_MAX+31)/32)
+#define ATTRIB_BIT_DWORDS ((PIPE_MAX_ATTRIBS+31)/32)
struct brw_vertex_info {
- unsigned varying; /* varying:1[PIPE_ATTRIB_MAX] */
- unsigned sizes[ATTRIB_BIT_DWORDS * 2]; /* sizes:2[PIPE_ATTRIB_MAX] */
+ unsigned varying; /* varying:1[PIPE_MAX_ATTRIBS] */
+ unsigned sizes[ATTRIB_BIT_DWORDS * 2]; /* sizes:2[PIPE_MAX_ATTRIBS] */
};
@@ -496,9 +496,9 @@ struct brw_context
/* Arrays with buffer objects to copy non-bufferobj arrays into
* for upload:
*/
- const struct pipe_vertex_buffer *vbo_array[PIPE_ATTRIB_MAX];
+ const struct pipe_vertex_buffer *vbo_array[PIPE_MAX_ATTRIBS];
- struct brw_vertex_element_state inputs[PIPE_ATTRIB_MAX];
+ struct brw_vertex_element_state inputs[PIPE_MAX_ATTRIBS];
#define BRW_NR_UPLOAD_BUFS 17
#define BRW_UPLOAD_INIT_SIZE (128*1024)
diff --git a/src/gallium/drivers/i965simple/brw_flush.c b/src/gallium/drivers/i965simple/brw_flush.c
index 5216c680cf6..e6001c30d94 100644
--- a/src/gallium/drivers/i965simple/brw_flush.c
+++ b/src/gallium/drivers/i965simple/brw_flush.c
@@ -36,14 +36,11 @@
#include "brw_batch.h"
-/**
- * In future we may want a fence-like interface instead of finish.
- */
static void brw_flush( struct pipe_context *pipe,
- unsigned flags )
+ unsigned flags,
+ struct pipe_fence_handle **fence )
{
struct brw_context *brw = brw_context(pipe);
- struct pipe_fence_handle *fence;
/* Do we need to emit an MI_FLUSH command to flush the hardware
* caches?
@@ -65,11 +62,7 @@ static void brw_flush( struct pipe_context *pipe,
/* If there are no flags, just flush pending commands to hardware:
*/
- FLUSH_BATCH( &fence );
-
- if (flags & PIPE_FLUSH_WAIT) {
-// brw->winsys->wait_fence(brw->winsys, fence);
- }
+ FLUSH_BATCH( fence );
}
diff --git a/src/gallium/drivers/i965simple/brw_state.c b/src/gallium/drivers/i965simple/brw_state.c
index f5efe9fc06d..376f1487b29 100644
--- a/src/gallium/drivers/i965simple/brw_state.c
+++ b/src/gallium/drivers/i965simple/brw_state.c
@@ -277,45 +277,49 @@ static void brw_set_viewport_state( struct pipe_context *pipe,
}
-static void brw_set_vertex_buffer( struct pipe_context *pipe,
- unsigned index,
- const struct pipe_vertex_buffer *buffer )
+static void brw_set_vertex_buffers(struct pipe_context *pipe,
+ unsigned count,
+ const struct pipe_vertex_buffer *buffers)
{
struct brw_context *brw = brw_context(pipe);
- brw->vb.vbo_array[index] = buffer;
+ memcpy(brw->vb.vbo_array, buffers, count * sizeof(buffers[0]));
}
-static void brw_set_vertex_element(struct pipe_context *pipe,
- unsigned index,
- const struct pipe_vertex_element *element)
+static void brw_set_vertex_elements(struct pipe_context *pipe,
+ unsigned count,
+ const struct pipe_vertex_element *elements)
{
/* flush ? */
struct brw_context *brw = brw_context(pipe);
+ uint i;
- assert(index < PIPE_ATTRIB_MAX);
- struct brw_vertex_element_state el;
- memset(&el, 0, sizeof(el));
+ assert(count <= PIPE_MAX_ATTRIBS);
- el.ve0.src_offset = element->src_offset;
- el.ve0.src_format = brw_translate_surface_format(element->src_format);
- el.ve0.valid = 1;
- el.ve0.vertex_buffer_index = element->vertex_buffer_index;
+ for (i = 0; i < count; i++) {
+ struct brw_vertex_element_state el;
+ memset(&el, 0, sizeof(el));
- el.ve1.dst_offset = index * 4;
+ el.ve0.src_offset = elements[i].src_offset;
+ el.ve0.src_format = brw_translate_surface_format(elements[i].src_format);
+ el.ve0.valid = 1;
+ el.ve0.vertex_buffer_index = elements[i].vertex_buffer_index;
- el.ve1.vfcomponent3 = BRW_VFCOMPONENT_STORE_SRC;
- el.ve1.vfcomponent2 = BRW_VFCOMPONENT_STORE_SRC;
- el.ve1.vfcomponent1 = BRW_VFCOMPONENT_STORE_SRC;
- el.ve1.vfcomponent0 = BRW_VFCOMPONENT_STORE_SRC;
+ el.ve1.dst_offset = i * 4;
- switch (element->nr_components) {
- case 1: el.ve1.vfcomponent1 = BRW_VFCOMPONENT_STORE_0;
- case 2: el.ve1.vfcomponent2 = BRW_VFCOMPONENT_STORE_0;
- case 3: el.ve1.vfcomponent3 = BRW_VFCOMPONENT_STORE_1_FLT;
- break;
- }
+ el.ve1.vfcomponent3 = BRW_VFCOMPONENT_STORE_SRC;
+ el.ve1.vfcomponent2 = BRW_VFCOMPONENT_STORE_SRC;
+ el.ve1.vfcomponent1 = BRW_VFCOMPONENT_STORE_SRC;
+ el.ve1.vfcomponent0 = BRW_VFCOMPONENT_STORE_SRC;
- brw->vb.inputs[index] = el;
+ switch (elements[i].nr_components) {
+ case 1: el.ve1.vfcomponent1 = BRW_VFCOMPONENT_STORE_0;
+ case 2: el.ve1.vfcomponent2 = BRW_VFCOMPONENT_STORE_0;
+ case 3: el.ve1.vfcomponent3 = BRW_VFCOMPONENT_STORE_1_FLT;
+ break;
+ }
+
+ brw->vb.inputs[i] = el;
+ }
}
@@ -457,6 +461,6 @@ brw_init_state_functions( struct brw_context *brw )
brw->pipe.set_scissor_state = brw_set_scissor_state;
brw->pipe.set_sampler_textures = brw_set_sampler_textures;
brw->pipe.set_viewport_state = brw_set_viewport_state;
- brw->pipe.set_vertex_buffer = brw_set_vertex_buffer;
- brw->pipe.set_vertex_element = brw_set_vertex_element;
+ brw->pipe.set_vertex_buffers = brw_set_vertex_buffers;
+ brw->pipe.set_vertex_elements = brw_set_vertex_elements;
}
diff --git a/src/gallium/drivers/i965simple/brw_wm.c b/src/gallium/drivers/i965simple/brw_wm.c
index 1c4b5b5ede2..7fc5f59a98c 100644
--- a/src/gallium/drivers/i965simple/brw_wm.c
+++ b/src/gallium/drivers/i965simple/brw_wm.c
@@ -161,8 +161,7 @@ static void brw_wm_populate_key( struct brw_context *brw,
if (unit) {
- if (unit->compare &&
- unit->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) {
+ if (unit->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) {
key->shadowtex_mask |= 1<<i;
}
if (t->Image[0][t->BaseLevel]->InternalFormat == GL_YCBCR_MESA)
diff --git a/src/gallium/drivers/i965simple/brw_wm.h b/src/gallium/drivers/i965simple/brw_wm.h
index a1ac0f504a6..b29c4393f01 100644
--- a/src/gallium/drivers/i965simple/brw_wm.h
+++ b/src/gallium/drivers/i965simple/brw_wm.h
@@ -76,7 +76,7 @@ struct brw_wm_prog_key {
#define PROGRAM_INTERNAL_PARAM
#define MAX_NV_FRAGMENT_PROGRAM_INSTRUCTIONS 1024 /* 72 for GL_ARB_f_p */
-#define BRW_WM_MAX_INSN (MAX_NV_FRAGMENT_PROGRAM_INSTRUCTIONS*3 + PIPE_ATTRIB_MAX + 3)
+#define BRW_WM_MAX_INSN (MAX_NV_FRAGMENT_PROGRAM_INSTRUCTIONS*3 + PIPE_MAX_ATTRIBS + 3)
#define BRW_WM_MAX_GRF 128 /* hardware limit */
#define BRW_WM_MAX_VREG (BRW_WM_MAX_INSN * 4)
#define BRW_WM_MAX_REF (BRW_WM_MAX_INSN * 12)
@@ -84,7 +84,7 @@ struct brw_wm_prog_key {
#define BRW_WM_MAX_CONST 256
#define BRW_WM_MAX_KILLS MAX_NV_FRAGMENT_PROGRAM_INSTRUCTIONS
-#define PAYLOAD_DEPTH (PIPE_ATTRIB_MAX)
+#define PAYLOAD_DEPTH (PIPE_MAX_ATTRIBS)
#define MAX_IFSN 32
#define MAX_LOOP_DEPTH 32
diff --git a/src/gallium/drivers/softpipe/sp_context.c b/src/gallium/drivers/softpipe/sp_context.c
index 16fb06f176f..e298ed37c36 100644
--- a/src/gallium/drivers/softpipe/sp_context.c
+++ b/src/gallium/drivers/softpipe/sp_context.c
@@ -174,8 +174,8 @@ softpipe_create( struct pipe_screen *screen,
softpipe->pipe.set_sampler_textures = softpipe_set_sampler_textures;
softpipe->pipe.set_viewport_state = softpipe_set_viewport_state;
- softpipe->pipe.set_vertex_buffer = softpipe_set_vertex_buffer;
- softpipe->pipe.set_vertex_element = softpipe_set_vertex_element;
+ softpipe->pipe.set_vertex_buffers = softpipe_set_vertex_buffers;
+ softpipe->pipe.set_vertex_elements = softpipe_set_vertex_elements;
softpipe->pipe.draw_arrays = softpipe_draw_arrays;
softpipe->pipe.draw_elements = softpipe_draw_elements;
diff --git a/src/gallium/drivers/softpipe/sp_context.h b/src/gallium/drivers/softpipe/sp_context.h
index 19e6cfaf02e..dc9d0e6d5d6 100644
--- a/src/gallium/drivers/softpipe/sp_context.h
+++ b/src/gallium/drivers/softpipe/sp_context.h
@@ -77,8 +77,8 @@ struct softpipe_context {
struct pipe_scissor_state scissor;
struct pipe_texture *texture[PIPE_MAX_SAMPLERS];
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];
unsigned dirty;
unsigned num_samplers;
@@ -92,7 +92,7 @@ struct softpipe_context {
/*
* Mapped vertex buffers
*/
- ubyte *mapped_vbuffer[PIPE_ATTRIB_MAX];
+ ubyte *mapped_vbuffer[PIPE_MAX_ATTRIBS];
/** Mapped constant buffers */
void *mapped_constants[PIPE_SHADER_TYPES];
diff --git a/src/gallium/drivers/softpipe/sp_draw_arrays.c b/src/gallium/drivers/softpipe/sp_draw_arrays.c
index 5b5a0fe5735..ab54050d3fe 100644
--- a/src/gallium/drivers/softpipe/sp_draw_arrays.c
+++ b/src/gallium/drivers/softpipe/sp_draw_arrays.c
@@ -125,7 +125,7 @@ softpipe_draw_elements(struct pipe_context *pipe,
/*
* Map vertex buffers
*/
- for (i = 0; i < PIPE_ATTRIB_MAX; i++) {
+ for (i = 0; i < PIPE_MAX_ATTRIBS; i++) {
if (sp->vertex_buffer[i].buffer) {
void *buf
= pipe->winsys->buffer_map(pipe->winsys,
@@ -153,7 +153,7 @@ softpipe_draw_elements(struct pipe_context *pipe,
/*
* unmap vertex/index buffers - will cause draw module to flush
*/
- for (i = 0; i < PIPE_ATTRIB_MAX; i++) {
+ for (i = 0; i < PIPE_MAX_ATTRIBS; i++) {
if (sp->vertex_buffer[i].buffer) {
draw_set_mapped_vertex_buffer(draw, i, NULL);
pipe->winsys->buffer_unmap(pipe->winsys, sp->vertex_buffer[i].buffer);
diff --git a/src/gallium/drivers/softpipe/sp_flush.c b/src/gallium/drivers/softpipe/sp_flush.c
index 2cbd0d7cabe..0625b69099b 100644
--- a/src/gallium/drivers/softpipe/sp_flush.c
+++ b/src/gallium/drivers/softpipe/sp_flush.c
@@ -40,13 +40,10 @@
#include "sp_winsys.h"
-/* There will be actual work to do here. In future we may want a
- * fence-like interface instead of finish, and perhaps flush will take
- * flags to indicate what type of flush is required.
- */
void
softpipe_flush( struct pipe_context *pipe,
- unsigned flags )
+ unsigned flags,
+ struct pipe_fence_handle **fence )
{
struct softpipe_context *softpipe = softpipe_context(pipe);
uint i;
@@ -72,5 +69,8 @@ softpipe_flush( struct pipe_context *pipe,
* to unmap surfaces when flushing.
*/
softpipe_unmap_surfaces(softpipe);
+
+ if (fence)
+ *fence = NULL;
}
diff --git a/src/gallium/drivers/softpipe/sp_flush.h b/src/gallium/drivers/softpipe/sp_flush.h
index 34ec617866b..68d9b5fa835 100644
--- a/src/gallium/drivers/softpipe/sp_flush.h
+++ b/src/gallium/drivers/softpipe/sp_flush.h
@@ -29,7 +29,9 @@
#define SP_FLUSH_H
struct pipe_context;
+struct pipe_fence_handle;
-void softpipe_flush(struct pipe_context *pipe, unsigned flags );
+void softpipe_flush(struct pipe_context *pipe, unsigned flags,
+ struct pipe_fence_handle **fence);
#endif
diff --git a/src/gallium/drivers/softpipe/sp_prim_setup.c b/src/gallium/drivers/softpipe/sp_prim_setup.c
index 6a81e4d8cc2..c7eb12b3bb7 100644
--- a/src/gallium/drivers/softpipe/sp_prim_setup.c
+++ b/src/gallium/drivers/softpipe/sp_prim_setup.c
@@ -44,6 +44,7 @@
#include "pipe/p_shader_tokens.h"
#define DEBUG_VERTS 0
+#define DEBUG_FRAGS 0
/**
* Triangle edge info
@@ -92,6 +93,11 @@ struct setup_stage {
unsigned y_flags;
unsigned mask; /**< mask of MASK_BOTTOM/TOP_LEFT/RIGHT bits */
} span;
+
+#if DEBUG_FRAGS
+ uint numFragsEmitted; /**< per primitive */
+ uint numFragsWritten; /**< per primitive */
+#endif
};
@@ -160,7 +166,20 @@ emit_quad( struct setup_stage *setup, int x, int y, unsigned mask )
setup->quad.x0 = x;
setup->quad.y0 = y;
setup->quad.mask = mask;
+#if DEBUG_FRAGS
+ if (mask & 1) setup->numFragsEmitted++;
+ if (mask & 2) setup->numFragsEmitted++;
+ if (mask & 4) setup->numFragsEmitted++;
+ if (mask & 8) setup->numFragsEmitted++;
+#endif
sp->quad.first->run(sp->quad.first, &setup->quad);
+#if DEBUG_FRAGS
+ mask = setup->quad.mask;
+ if (mask & 1) setup->numFragsWritten++;
+ if (mask & 2) setup->numFragsWritten++;
+ if (mask & 4) setup->numFragsWritten++;
+ if (mask & 8) setup->numFragsWritten++;
+#endif
}
@@ -674,6 +693,11 @@ static void setup_tri( struct draw_stage *stage,
debug_printf("%s\n", __FUNCTION__ );
*/
+#if DEBUG_FRAGS
+ setup->numFragsEmitted = 0;
+ setup->numFragsWritten = 0;
+#endif
+
setup_sort_vertices( setup, prim );
setup_tri_coefficients( setup );
setup_tri_edges( setup );
@@ -702,6 +726,12 @@ static void setup_tri( struct draw_stage *stage,
}
flush_spans( setup );
+
+#if DEBUG_FRAGS
+ printf("Tri: %u frags emitted, %u written\n",
+ setup->numFragsEmitted,
+ setup->numFragsWritten);
+#endif
}
diff --git a/src/gallium/drivers/softpipe/sp_quad_fs.c b/src/gallium/drivers/softpipe/sp_quad_fs.c
index 861285101fd..a73df31383f 100644
--- a/src/gallium/drivers/softpipe/sp_quad_fs.c
+++ b/src/gallium/drivers/softpipe/sp_quad_fs.c
@@ -113,15 +113,18 @@ shade_quad(
}
}
else {
- /* copy input Z (which was interpolated by the executor) to output Z */
- uint i;
- for (i = 0; i < 4; i++) {
- quad->outputs.depth[i] = machine->Inputs[0].xyzw[2].f[i];
- /* XXX not sure the above line is always correct. The following
- * might be better:
- quad->outputs.depth[i] = machine->QuadPos.xyzw[2].f[i];
- */
- }
+ /* compute Z values now, as in the quad earlyz stage */
+ /* XXX we should really only do this if the earlyz stage is not used */
+ const float fx = (float) quad->x0;
+ const float fy = (float) quad->y0;
+ const float dzdx = quad->posCoef->dadx[2];
+ const float dzdy = quad->posCoef->dady[2];
+ const float z0 = quad->posCoef->a0[2] + dzdx * fx + dzdy * fy;
+
+ quad->outputs.depth[0] = z0;
+ quad->outputs.depth[1] = z0 + dzdx;
+ quad->outputs.depth[2] = z0 + dzdy;
+ quad->outputs.depth[3] = z0 + dzdx + dzdy;
}
/* shader may cull fragments */
@@ -185,8 +188,8 @@ struct quad_stage *sp_quad_shade_stage( struct softpipe_context *softpipe )
uint i;
/* allocate storage for program inputs/outputs, aligned to 16 bytes */
- qss->inputs = MALLOC(PIPE_ATTRIB_MAX * sizeof(*qss->inputs) + 16);
- qss->outputs = MALLOC(PIPE_ATTRIB_MAX * sizeof(*qss->outputs) + 16);
+ qss->inputs = MALLOC(PIPE_MAX_ATTRIBS * sizeof(*qss->inputs) + 16);
+ qss->outputs = MALLOC(PIPE_MAX_ATTRIBS * sizeof(*qss->outputs) + 16);
qss->machine.Inputs = align16(qss->inputs);
qss->machine.Outputs = align16(qss->outputs);
diff --git a/src/gallium/drivers/softpipe/sp_state.h b/src/gallium/drivers/softpipe/sp_state.h
index 0bb1095aece..6e6501f5bc4 100644
--- a/src/gallium/drivers/softpipe/sp_state.h
+++ b/src/gallium/drivers/softpipe/sp_state.h
@@ -151,13 +151,13 @@ void softpipe_set_sampler_textures( struct pipe_context *,
void softpipe_set_viewport_state( struct pipe_context *,
const struct pipe_viewport_state * );
-void softpipe_set_vertex_element(struct pipe_context *,
- unsigned index,
- const struct pipe_vertex_element *);
+void softpipe_set_vertex_elements(struct pipe_context *,
+ unsigned count,
+ const struct pipe_vertex_element *);
-void softpipe_set_vertex_buffer(struct pipe_context *,
- unsigned index,
- const struct pipe_vertex_buffer *);
+void softpipe_set_vertex_buffers(struct pipe_context *,
+ unsigned count,
+ const struct pipe_vertex_buffer *);
void softpipe_update_derived( struct softpipe_context *softpipe );
diff --git a/src/gallium/drivers/softpipe/sp_state_vertex.c b/src/gallium/drivers/softpipe/sp_state_vertex.c
index f01a10de3b4..e0230e16a4e 100644
--- a/src/gallium/drivers/softpipe/sp_state_vertex.c
+++ b/src/gallium/drivers/softpipe/sp_state_vertex.c
@@ -37,28 +37,35 @@
void
-softpipe_set_vertex_element(struct pipe_context *pipe,
- unsigned index,
- const struct pipe_vertex_element *attrib)
+softpipe_set_vertex_elements(struct pipe_context *pipe,
+ unsigned count,
+ const struct pipe_vertex_element *attribs)
{
struct softpipe_context *softpipe = softpipe_context(pipe);
- assert(index < PIPE_ATTRIB_MAX);
- softpipe->vertex_element[index] = *attrib; /* struct copy */
+
+ assert(count <= PIPE_MAX_ATTRIBS);
+
+ memcpy(softpipe->vertex_element, attribs,
+ count * sizeof(struct pipe_vertex_element));
+
softpipe->dirty |= SP_NEW_VERTEX;
- draw_set_vertex_element(softpipe->draw, index, attrib);
+ draw_set_vertex_elements(softpipe->draw, count, attribs);
}
void
-softpipe_set_vertex_buffer(struct pipe_context *pipe,
- unsigned index,
- const struct pipe_vertex_buffer *buffer)
+softpipe_set_vertex_buffers(struct pipe_context *pipe,
+ unsigned count,
+ const struct pipe_vertex_buffer *buffers)
{
struct softpipe_context *softpipe = softpipe_context(pipe);
- assert(index < PIPE_ATTRIB_MAX);
- softpipe->vertex_buffer[index] = *buffer; /* struct copy */
+
+ assert(count <= PIPE_MAX_ATTRIBS);
+
+ memcpy(softpipe->vertex_buffer, buffers, count * sizeof(buffers[0]));
+
softpipe->dirty |= SP_NEW_VERTEX;
- draw_set_vertex_buffer(softpipe->draw, index, buffer);
+ draw_set_vertex_buffers(softpipe->draw, count, buffers);
}
diff --git a/src/gallium/include/pipe/p_context.h b/src/gallium/include/pipe/p_context.h
index a3824601be9..324f70185af 100644
--- a/src/gallium/include/pipe/p_context.h
+++ b/src/gallium/include/pipe/p_context.h
@@ -37,33 +37,30 @@ extern "C" {
struct pipe_screen;
-
+struct pipe_fence_handle;
struct pipe_state_cache;
-
-/* Opaque driver handles:
- */
struct pipe_query;
+
/**
* Gallium rendering context. Basically:
* - state setting functions
* - VBO drawing functions
* - surface functions
- * - device queries
*/
struct pipe_context {
struct pipe_winsys *winsys;
struct pipe_screen *screen;
- void *priv; /** context private data (for DRI for example) */
- void *draw; /** private, for draw module (temporary? */
+ void *priv; /**< context private data (for DRI for example) */
+ void *draw; /**< private, for draw module (temporary?) */
void (*destroy)( struct pipe_context * );
- /*
- * Drawing.
- * Return false on fallbacks (temporary??)
+ /**
+ * VBO drawing (return false on fallbacks (temporary??))
*/
+ /*@{*/
boolean (*draw_arrays)( struct pipe_context *pipe,
unsigned mode, unsigned start, unsigned count);
@@ -71,11 +68,13 @@ struct pipe_context {
struct pipe_buffer *indexBuffer,
unsigned indexSize,
unsigned mode, unsigned start, unsigned count);
+ /*@}*/
/**
* Query objects
*/
+ /*@{*/
struct pipe_query *(*create_query)( struct pipe_context *pipe,
unsigned query_type );
@@ -89,10 +88,12 @@ struct pipe_context {
struct pipe_query *q,
boolean wait,
uint64 *result);
+ /*@}*/
- /*
- * State functions
+ /**
+ * State functions (create/bind/destroy state objects)
*/
+ /*@{*/
void * (*create_blend_state)(struct pipe_context *,
const struct pipe_blend_state *);
void (*bind_blend_state)(struct pipe_context *, void *);
@@ -122,10 +123,12 @@ struct pipe_context {
const struct pipe_shader_state *);
void (*bind_vs_state)(struct pipe_context *, void *);
void (*delete_vs_state)(struct pipe_context *, void *);
+ /*@}*/
- /* The following look more properties than states.
- * maybe combine a few of them into states or pass them
- * in the bind calls to the state */
+ /**
+ * Parameter-like state (or properties)
+ */
+ /*@{*/
void (*set_blend_color)( struct pipe_context *,
const struct pipe_blend_color * );
@@ -145,32 +148,27 @@ struct pipe_context {
void (*set_scissor_state)( struct pipe_context *,
const struct pipe_scissor_state * );
+ void (*set_viewport_state)( struct pipe_context *,
+ const struct pipe_viewport_state * );
- /* Currently a sampler is constrained to sample from a single texture:
- */
void (*set_sampler_textures)( struct pipe_context *,
- unsigned num,
+ unsigned num_textures,
struct pipe_texture ** );
- void (*set_viewport_state)( struct pipe_context *,
- const struct pipe_viewport_state * );
-
- /*
- * Vertex arrays
- */
- void (*set_vertex_buffer)( struct pipe_context *,
- unsigned index,
- const struct pipe_vertex_buffer * );
+ void (*set_vertex_buffers)( struct pipe_context *,
+ unsigned num_buffers,
+ const struct pipe_vertex_buffer * );
- void (*set_vertex_element)( struct pipe_context *,
- unsigned index,
- const struct pipe_vertex_element * );
+ void (*set_vertex_elements)( struct pipe_context *,
+ unsigned num_elements,
+ const struct pipe_vertex_element * );
+ /*@}*/
- /*
+ /**
* Surface functions
*/
-
+ /*@{*/
void (*surface_copy)(struct pipe_context *pipe,
unsigned do_flip, /*<< flip surface contents vertically */
struct pipe_surface *dest,
@@ -189,20 +187,19 @@ struct pipe_context {
void (*clear)(struct pipe_context *pipe,
struct pipe_surface *ps,
unsigned clearValue);
+ /*@}*/
- /**
- * Called when texture data is changed.
- */
+
+ /** Called when texture data is changed */
void (*texture_update)(struct pipe_context *pipe,
struct pipe_texture *texture,
uint face, uint dirtyLevelsMask);
-
- /* Flush rendering:
- */
+ /** Flush rendering (flags = bitmask of PIPE_FLUSH_x tokens) */
void (*flush)( struct pipe_context *pipe,
- unsigned flags );
+ unsigned flags,
+ struct pipe_fence_handle **fence );
};
diff --git a/src/gallium/include/pipe/p_debug.h b/src/gallium/include/pipe/p_debug.h
index 577cdaebcdf..9e52ad9a374 100644
--- a/src/gallium/include/pipe/p_debug.h
+++ b/src/gallium/include/pipe/p_debug.h
@@ -90,6 +90,8 @@ debug_printf(const char *format, ...)
va_start(ap, format);
_debug_vprintf(format, ap);
va_end(ap);
+#else
+ (void) format; /* silence warning */
#endif
}
@@ -191,7 +193,7 @@ void _debug_assert_fail(const char *expr,
*/
#ifdef DEBUG
#define debug_warning(__msg) \
- _debug_printf("%s:%u:%s: warning: %s\n", __FILE__, __LINE__, __FUNCTION__, (__msg))
+ _debug_printf("%s:%u:%s: warning: %s\n", __FILE__, __LINE__, __FUNCTION__, __msg)
#else
#define debug_warning(__msg) \
((void)0)
@@ -203,10 +205,10 @@ void _debug_assert_fail(const char *expr,
*/
#ifdef DEBUG
#define debug_error(__msg) \
- _debug_printf("%s:%u:%s: error: %s\n", __FILE__, __LINE__, __FUNCTION__, (__msg))
+ _debug_printf("%s:%u:%s: error: %s\n", __FILE__, __LINE__, __FUNCTION__, __msg)
#else
#define debug_error(__msg) \
- _debug_printf("error: %s\n", __msg))
+ _debug_printf("error: %s\n", __msg)
#endif
diff --git a/src/gallium/include/pipe/p_defines.h b/src/gallium/include/pipe/p_defines.h
index bc938ba2538..586951d9566 100644
--- a/src/gallium/include/pipe/p_defines.h
+++ b/src/gallium/include/pipe/p_defines.h
@@ -201,8 +201,7 @@ enum pipe_texture_target {
*/
#define PIPE_FLUSH_RENDER_CACHE 0x1
#define PIPE_FLUSH_TEXTURE_CACHE 0x2
-#define PIPE_FLUSH_WAIT 0x4
-#define PIPE_FLUSH_SWAPBUFFERS 0x8
+#define PIPE_FLUSH_SWAPBUFFERS 0x4
/**
diff --git a/src/gallium/include/pipe/p_state.h b/src/gallium/include/pipe/p_state.h
index 3e531c4da48..0eeee47a9a5 100644
--- a/src/gallium/include/pipe/p_state.h
+++ b/src/gallium/include/pipe/p_state.h
@@ -51,10 +51,11 @@ extern "C" {
/**
* Implementation limits
*/
-#define PIPE_MAX_SAMPLERS 8
+#define PIPE_MAX_SAMPLERS 16
#define PIPE_MAX_CLIP_PLANES 6
#define PIPE_MAX_CONSTANT 32
-#define PIPE_ATTRIB_MAX 32
+#define PIPE_MAX_ATTRIBS 32
+#define PIPE_ATTRIB_MAX 32 /* XXX obsolete - remove */
#define PIPE_MAX_COLOR_BUFS 8
#define PIPE_MAX_TEXTURE_LEVELS 16
#define PIPE_MAX_FEEDBACK_ATTRIBS 16
@@ -112,6 +113,7 @@ struct pipe_rasterizer_state
unsigned bypass_clipping:1;
unsigned bypass_vs:1; /**< vertices are already fully transformed */
unsigned origin_lower_left:1; /**< Is (0,0) the lower-left corner? */
+ unsigned flatshade_first:1; /**< take color attribute from the first vertex of a primitive */
float line_width;
float point_size; /**< used when no per-vertex size */
@@ -241,7 +243,6 @@ struct pipe_sampler_state
unsigned min_img_filter:2; /**< PIPE_TEX_FILTER_x */
unsigned min_mip_filter:2; /**< PIPE_TEX_MIPFILTER_x */
unsigned mag_img_filter:2; /**< PIPE_TEX_FILTER_x */
- unsigned compare:1; /**< shadow/depth compare enabled? */
unsigned compare_mode:1; /**< PIPE_TEX_COMPARE_x */
unsigned compare_func:3; /**< PIPE_FUNC_x */
unsigned normalized_coords:1; /**< Are coords normalized to [0,1]? */
diff --git a/src/gallium/include/pipe/p_util.h b/src/gallium/include/pipe/p_util.h
index 505626c60b5..1e7b8181f9e 100644
--- a/src/gallium/include/pipe/p_util.h
+++ b/src/gallium/include/pipe/p_util.h
@@ -51,7 +51,6 @@ extern "C" {
debug_free( __FILE__, __LINE__, __FUNCTION__, _ptr )
#define REALLOC( _ptr, _old_size, _size ) \
debug_realloc( __FILE__, __LINE__, __FUNCTION__, _ptr, _old_size, _size )
-#define GETENV( X ) NULL
#else
@@ -118,8 +117,6 @@ REALLOC( void *old_ptr, unsigned old_size, unsigned new_size )
return new_ptr;
}
-#define GETENV( X ) NULL
-
#else /* !WIN32 */
#define MALLOC( SIZE ) malloc( SIZE )
@@ -130,8 +127,6 @@ REALLOC( void *old_ptr, unsigned old_size, unsigned new_size )
#define REALLOC( OLDPTR, OLDSIZE, NEWSIZE ) realloc( OLDPTR, NEWSIZE )
-#define GETENV( X ) getenv( X )
-
#endif /* !WIN32 */
#endif /* !DEBUG */
@@ -139,6 +134,8 @@ REALLOC( void *old_ptr, unsigned old_size, unsigned new_size )
#define CALLOC_STRUCT(T) (struct T *) CALLOC(1, sizeof(struct T))
+#define GETENV( X ) debug_get_option( X, NULL )
+
/**
* Return memory on given byte alignment
diff --git a/src/gallium/winsys/dri/intel/intel_context.c b/src/gallium/winsys/dri/intel/intel_context.c
index 79b320c6bf4..8eba33c3139 100644
--- a/src/gallium/winsys/dri/intel/intel_context.c
+++ b/src/gallium/winsys/dri/intel/intel_context.c
@@ -228,7 +228,7 @@ intelDestroyContext(__DRIcontextPrivate * driContextPriv)
assert(intel); /* should never be null */
if (intel) {
- st_flush(intel->st, PIPE_FLUSH_WAIT);
+ st_finish(intel->st);
intel_batchbuffer_free(intel->batch);
@@ -256,7 +256,7 @@ GLboolean
intelUnbindContext(__DRIcontextPrivate * driContextPriv)
{
struct intel_context *intel = intel_context(driContextPriv);
- st_flush(intel->st, 0x0);
+ st_flush(intel->st, PIPE_FLUSH_RENDER_CACHE, NULL);
/* XXX make_current(NULL)? */
return GL_TRUE;
}
diff --git a/src/gallium/winsys/dri/intel/intel_winsys_i915.c b/src/gallium/winsys/dri/intel/intel_winsys_i915.c
index 2def1afc31e..4d183db7c37 100644
--- a/src/gallium/winsys/dri/intel/intel_winsys_i915.c
+++ b/src/gallium/winsys/dri/intel/intel_winsys_i915.c
@@ -39,12 +39,14 @@
#include "intel_winsys.h"
#include "pipe/p_util.h"
+#include "pipe/p_winsys.h"
#include "i915simple/i915_winsys.h"
#include "i915simple/i915_screen.h"
struct intel_i915_winsys {
struct i915_winsys winsys; /**< batch buffer funcs */
+ struct pipe_winsys *pws;
struct intel_context *intel;
};
@@ -112,19 +114,22 @@ static void intel_i915_batch_reloc( struct i915_winsys *sws,
-static void intel_i915_batch_flush( struct i915_winsys *sws )
+static void intel_i915_batch_flush( struct i915_winsys *sws,
+ struct pipe_fence_handle **fence )
{
- struct intel_context *intel = intel_i915_winsys(sws)->intel;
+ struct intel_i915_winsys *iws = intel_i915_winsys(sws);
+ struct intel_context *intel = iws->intel;
+ union {
+ struct _DriFenceObject *dri;
+ struct pipe_fence_handle *pipe;
+ } fu;
- intel_batchbuffer_flush( intel->batch );
-// if (0) intel_i915_batch_wait_idle( sws );
-}
+ fu.dri = intel_batchbuffer_flush( intel->batch );
+ if (fu.dri)
+ iws->pws->fence_reference(iws->pws, fence, fu.pipe);
-static void intel_i915_batch_finish( struct i915_winsys *sws )
-{
- struct intel_context *intel = intel_i915_winsys(sws)->intel;
- intel_batchbuffer_finish( intel->batch );
+// if (0) intel_i915_batch_wait_idle( sws );
}
@@ -145,7 +150,7 @@ intel_create_i915simple( struct intel_context *intel,
iws->winsys.batch_dword = intel_i915_batch_dword;
iws->winsys.batch_reloc = intel_i915_batch_reloc;
iws->winsys.batch_flush = intel_i915_batch_flush;
- iws->winsys.batch_finish = intel_i915_batch_finish;
+ iws->pws = winsys;
iws->intel = intel;
screen = i915_create_screen(winsys, intel->intelScreen->deviceID);
diff --git a/src/gallium/winsys/xlib/xm_api.c b/src/gallium/winsys/xlib/xm_api.c
index e5fef1d7a81..a82d3c990e7 100644
--- a/src/gallium/winsys/xlib/xm_api.c
+++ b/src/gallium/winsys/xlib/xm_api.c
@@ -104,12 +104,16 @@ static int host_byte_order( void )
* 1 = shared XImage support available
* 2 = shared Pixmap support available also
*/
-static int check_for_xshm( XMesaDisplay *display )
+int xmesa_check_for_xshm( XMesaDisplay *display )
{
#if defined(USE_XSHM) && !defined(XFree86Server)
int major, minor, ignore;
Bool pixmaps;
+ if (getenv("MESA_NOSHM")) {
+ return 0;
+ }
+
if (XQueryExtension( display, "MIT-SHM", &ignore, &ignore, &ignore )) {
if (XShmQueryVersion( display, &major, &minor, &pixmaps )==True) {
return (pixmaps==True) ? 2 : 1;
@@ -507,6 +511,14 @@ initialize_visual_and_buffer(XMesaVisual v, XMesaBuffer b,
return GL_FALSE;
}
v->mesa_visual.indexBits = 0;
+
+ if (v->BitsPerPixel == 32) {
+ /* We use XImages for all front/back buffers. If an X Window or
+ * X Pixmap is 32bpp, there's no guarantee that the alpha channel
+ * will be preserved. For XImages we're in luck.
+ */
+ v->mesa_visual.alphaBits = 8;
+ }
}
/*
@@ -528,7 +540,7 @@ initialize_visual_and_buffer(XMesaVisual v, XMesaBuffer b,
/* Setup for single/double buffering */
if (v->mesa_visual.doubleBufferMode) {
/* Double buffered */
- b->shm = check_for_xshm( v->display );
+ b->shm = xmesa_check_for_xshm( v->display );
}
/* X11 graphics context */
@@ -770,13 +782,16 @@ XMesaContext XMesaCreateContext( XMesaVisual v, XMesaContext share_list )
pf = choose_pixel_format(v);
assert(pf);
+ c->xm_visual = v;
+ c->xm_buffer = NULL; /* set later by XMesaMakeCurrent */
+
if (!getenv("XM_AUB")) {
xmesa_mode = XMESA_SOFTPIPE;
pipe = xmesa_create_pipe_context( c, pf );
}
else {
xmesa_mode = XMESA_AUB;
- pipe = xmesa_create_i965simple( xmesa_get_pipe_winsys_aub() );
+ pipe = xmesa_create_i965simple(xmesa_get_pipe_winsys_aub(v));
}
c->st = st_create_context(pipe, &v->mesa_visual,
@@ -800,9 +815,6 @@ XMesaContext XMesaCreateContext( XMesaVisual v, XMesaContext share_list )
#endif
/* finish up xmesa context initializations */
- c->xm_visual = v;
- c->xm_buffer = NULL; /* set later by XMesaMakeCurrent */
-
c->st->haveFramebufferSurfaces = GL_TRUE;
return c;
diff --git a/src/gallium/winsys/xlib/xm_winsys.c b/src/gallium/winsys/xlib/xm_winsys.c
index 018cf01cd6d..74597562798 100644
--- a/src/gallium/winsys/xlib/xm_winsys.c
+++ b/src/gallium/winsys/xlib/xm_winsys.c
@@ -65,8 +65,19 @@ struct xm_buffer
boolean userBuffer; /** Is this a user-space buffer? */
void *data;
void *mapped;
+
+ XImage *tempImage;
+ int shm;
+#if defined(USE_XSHM) && !defined(XFree86Server)
+ XShmSegmentInfo shminfo;
+#endif
};
+#if defined(USE_XSHM) && !defined(XFree86Server)
+# define XSHM_ENABLED(b) ((b)->shm)
+#else
+# define XSHM_ENABLED(b) 0
+#endif
struct xmesa_surface
{
@@ -88,6 +99,16 @@ struct xmesa_softpipe_winsys
};
+struct xmesa_pipe_winsys
+{
+ struct pipe_winsys base;
+ struct xmesa_visual *xm_visual;
+ int shm;
+};
+
+
+static void alloc_shm_ximage(struct xm_buffer *b, struct xmesa_buffer *xmb,
+ unsigned width, unsigned height);
/** Cast wrapper */
static INLINE struct xmesa_surface *
@@ -136,13 +157,27 @@ xm_buffer_unmap(struct pipe_winsys *pws, struct pipe_buffer *buf)
static void
xm_buffer_destroy(struct pipe_winsys *pws,
- struct pipe_buffer *buf)
+ struct pipe_buffer *buf)
{
struct xm_buffer *oldBuf = xm_buffer(buf);
if (oldBuf->data) {
- if (!oldBuf->userBuffer)
- align_free(oldBuf->data);
+#if defined(USE_XSHM) && !defined(XFree86Server)
+ if (oldBuf->shminfo.shmid >= 0) {
+ shmdt(oldBuf->shminfo.shmaddr);
+ shmctl(oldBuf->shminfo.shmid, IPC_RMID, 0);
+
+ oldBuf->shminfo.shmid = -1;
+ oldBuf->shminfo.shmaddr = (char *) -1;
+ }
+ else
+#endif
+ {
+ if (!oldBuf->userBuffer) {
+ align_free(oldBuf->data);
+ }
+ }
+
oldBuf->data = NULL;
}
@@ -157,7 +192,7 @@ xm_buffer_destroy(struct pipe_winsys *pws,
static void
xmesa_display_surface_tiled(XMesaBuffer b, const struct pipe_surface *surf)
{
- XImage *ximage = b->tempImage;
+ XImage *ximage;
struct xm_buffer *xm_buf = xm_buffer(surf->buffer);
const uint tilesPerRow = (surf->width + TILE_SIZE - 1) / TILE_SIZE;
uint x, y;
@@ -166,10 +201,18 @@ xmesa_display_surface_tiled(XMesaBuffer b, const struct pipe_surface *surf)
assert(ximage->format);
assert(ximage->bitmap_unit);
- /* update XImage's fields */
- ximage->width = TILE_SIZE;
- ximage->height = TILE_SIZE;
- ximage->bytes_per_line = TILE_SIZE * 4;
+ if (XSHM_ENABLED(xm_buf) && (xm_buf->tempImage == NULL)) {
+ alloc_shm_ximage(xm_buf, b, TILE_SIZE, TILE_SIZE);
+ }
+
+ ximage = (XSHM_ENABLED(xm_buf)) ? xm_buf->tempImage : b->tempImage;
+
+ if (!XSHM_ENABLED(xm_buf)) {
+ /* update XImage's fields */
+ ximage->width = TILE_SIZE;
+ ximage->height = TILE_SIZE;
+ ximage->bytes_per_line = TILE_SIZE * 4;
+ }
for (y = 0; y < surf->height; y += TILE_SIZE) {
for (x = 0; x < surf->width; x += TILE_SIZE) {
@@ -183,8 +226,15 @@ xmesa_display_surface_tiled(XMesaBuffer b, const struct pipe_surface *surf)
ximage->data = (char *) xm_buf->data + offset;
- XPutImage(b->xm_visual->display, b->drawable, b->gc,
- ximage, 0, 0, dx, dy, TILE_SIZE, TILE_SIZE);
+ if (XSHM_ENABLED(xm_buf)) {
+#if defined(USE_XSHM) && !defined(XFree86Server)
+ XShmPutImage(b->xm_visual->display, b->drawable, b->gc,
+ ximage, 0, 0, x, y, TILE_SIZE, TILE_SIZE, False);
+#endif
+ } else {
+ XPutImage(b->xm_visual->display, b->drawable, b->gc,
+ ximage, 0, 0, dx, dy, TILE_SIZE, TILE_SIZE);
+ }
}
}
}
@@ -197,7 +247,7 @@ xmesa_display_surface_tiled(XMesaBuffer b, const struct pipe_surface *surf)
void
xmesa_display_surface(XMesaBuffer b, const struct pipe_surface *surf)
{
- XImage *ximage = b->tempImage;
+ XImage *ximage;
struct xm_buffer *xm_buf = xm_buffer(surf->buffer);
const struct xmesa_surface *xm_surf
= xmesa_surface((struct pipe_surface *) surf);
@@ -207,19 +257,33 @@ xmesa_display_surface(XMesaBuffer b, const struct pipe_surface *surf)
return;
}
- /* check that the XImage has been previously initialized */
- assert(ximage->format);
- assert(ximage->bitmap_unit);
- /* update XImage's fields */
- ximage->width = surf->width;
- ximage->height = surf->height;
- ximage->bytes_per_line = surf->pitch * (ximage->bits_per_pixel / 8);
+ if (XSHM_ENABLED(xm_buf) && (xm_buf->tempImage == NULL)) {
+ alloc_shm_ximage(xm_buf, b, surf->pitch, surf->height);
+ }
+
+ ximage = (XSHM_ENABLED(xm_buf)) ? xm_buf->tempImage : b->tempImage;
ximage->data = xm_buf->data;
/* display image in Window */
- XPutImage(b->xm_visual->display, b->drawable, b->gc,
- ximage, 0, 0, 0, 0, surf->width, surf->height);
+ if (XSHM_ENABLED(xm_buf)) {
+#if defined(USE_XSHM) && !defined(XFree86Server)
+ XShmPutImage(b->xm_visual->display, b->drawable, b->gc,
+ ximage, 0, 0, 0, 0, surf->width, surf->height, False);
+#endif
+ } else {
+ /* check that the XImage has been previously initialized */
+ assert(ximage->format);
+ assert(ximage->bitmap_unit);
+
+ /* update XImage's fields */
+ ximage->width = surf->width;
+ ximage->height = surf->height;
+ ximage->bytes_per_line = surf->pitch * surf->cpp;
+
+ XPutImage(b->xm_visual->display, b->drawable, b->gc,
+ ximage, 0, 0, 0, 0, surf->width, surf->height);
+ }
}
@@ -256,6 +320,119 @@ xm_get_name(struct pipe_winsys *pws)
}
+#if defined(USE_XSHM) && !defined(XFree86Server)
+static volatile int mesaXErrorFlag = 0;
+
+/**
+ * Catches potential Xlib errors.
+ */
+static int
+mesaHandleXError(XMesaDisplay *dpy, XErrorEvent *event)
+{
+ (void) dpy;
+ (void) event;
+ mesaXErrorFlag = 1;
+ return 0;
+}
+
+
+static GLboolean alloc_shm(struct xm_buffer *buf, unsigned size)
+{
+ XShmSegmentInfo *const shminfo = & buf->shminfo;
+
+ shminfo->shmid = shmget(IPC_PRIVATE, size, IPC_CREAT|0777);
+ if (shminfo->shmid < 0) {
+ return GL_FALSE;
+ }
+
+ shminfo->shmaddr = (char *) shmat(shminfo->shmid, 0, 0);
+ if (shminfo->shmaddr == (char *) -1) {
+ shmctl(shminfo->shmid, IPC_RMID, 0);
+ return GL_FALSE;
+ }
+
+ shminfo->readOnly = False;
+ return GL_TRUE;
+}
+
+
+/**
+ * Allocate a shared memory XImage back buffer for the given XMesaBuffer.
+ */
+static void
+alloc_shm_ximage(struct xm_buffer *b, struct xmesa_buffer *xmb,
+ unsigned width, unsigned height)
+{
+ /*
+ * We have to do a _lot_ of error checking here to be sure we can
+ * really use the XSHM extension. It seems different servers trigger
+ * errors at different points if the extension won't work. Therefore
+ * we have to be very careful...
+ */
+#if 0
+ GC gc;
+#endif
+ int (*old_handler)(XMesaDisplay *, XErrorEvent *);
+
+ b->tempImage = XShmCreateImage(xmb->xm_visual->display,
+ xmb->xm_visual->visinfo->visual,
+ xmb->xm_visual->visinfo->depth,
+ ZPixmap,
+ NULL,
+ &b->shminfo,
+ width, height);
+ if (b->tempImage == NULL) {
+ b->shm = 0;
+ return;
+ }
+
+
+ mesaXErrorFlag = 0;
+ old_handler = XSetErrorHandler(mesaHandleXError);
+ /* This may trigger the X protocol error we're ready to catch: */
+ XShmAttach(xmb->xm_visual->display, &b->shminfo);
+ XSync(xmb->xm_visual->display, False);
+
+ if (mesaXErrorFlag) {
+ /* we are on a remote display, this error is normal, don't print it */
+ XFlush(xmb->xm_visual->display);
+ mesaXErrorFlag = 0;
+ XDestroyImage(b->tempImage);
+ b->tempImage = NULL;
+ b->shm = 0;
+ (void) XSetErrorHandler(old_handler);
+ return;
+ }
+
+
+ /* Finally, try an XShmPutImage to be really sure the extension works */
+#if 0
+ gc = XCreateGC(xmb->xm_visual->display, xmb->drawable, 0, NULL);
+ XShmPutImage(xmb->xm_visual->display, xmb->drawable, gc,
+ b->tempImage, 0, 0, 0, 0, 1, 1 /*one pixel*/, False);
+ XSync(xmb->xm_visual->display, False);
+ XFreeGC(xmb->xm_visual->display, gc);
+ (void) XSetErrorHandler(old_handler);
+ if (mesaXErrorFlag) {
+ XFlush(xmb->xm_visual->display);
+ mesaXErrorFlag = 0;
+ XDestroyImage(b->tempImage);
+ b->tempImage = NULL;
+ b->shm = 0;
+ return;
+ }
+#endif
+}
+#else
+static void
+alloc_shm_ximage(struct xm_buffer *b, struct xmesa_buffer *xmb,
+ unsigned width, unsigned height)
+{
+ b->shm = 0;
+}
+#endif
+
+
static struct pipe_buffer *
xm_buffer_create(struct pipe_winsys *pws,
unsigned alignment,
@@ -263,13 +440,35 @@ xm_buffer_create(struct pipe_winsys *pws,
unsigned size)
{
struct xm_buffer *buffer = CALLOC_STRUCT(xm_buffer);
+#if defined(USE_XSHM) && !defined(XFree86Server)
+ struct xmesa_pipe_winsys *xpws = (struct xmesa_pipe_winsys *) pws;
+#endif
+
buffer->base.refcount = 1;
buffer->base.alignment = alignment;
buffer->base.usage = usage;
buffer->base.size = size;
- /* align to 16-byte multiple for Cell */
- buffer->data = align_malloc(size, max(alignment, 16));
+
+#if defined(USE_XSHM) && !defined(XFree86Server)
+ buffer->shminfo.shmid = -1;
+ buffer->shminfo.shmaddr = (char *) -1;
+
+ if (xpws->shm && (usage & PIPE_BUFFER_USAGE_PIXEL) != 0) {
+ buffer->shm = xpws->shm;
+
+ if (alloc_shm(buffer, size)) {
+ buffer->data = buffer->shminfo.shmaddr;
+ }
+ }
+#endif
+
+ if (buffer->data == NULL) {
+ buffer->shm = 0;
+
+ /* align to 16-byte multiple for Cell */
+ buffer->data = align_malloc(size, max(alignment, 16));
+ }
return &buffer->base;
}
@@ -286,6 +485,7 @@ xm_user_buffer_create(struct pipe_winsys *pws, void *ptr, unsigned bytes)
buffer->base.size = bytes;
buffer->userBuffer = TRUE;
buffer->data = ptr;
+ buffer->shm = 0;
return &buffer->base;
}
@@ -370,6 +570,33 @@ xm_surface_release(struct pipe_winsys *winsys, struct pipe_surface **s)
}
+/*
+ * Fence functions - basically nothing to do, as we don't create any actual
+ * fence objects.
+ */
+
+static void
+xm_fence_reference(struct pipe_winsys *sws, struct pipe_fence_handle **ptr,
+ struct pipe_fence_handle *fence)
+{
+}
+
+
+static int
+xm_fence_signalled(struct pipe_winsys *sws, struct pipe_fence_handle *fence,
+ unsigned flag)
+{
+ return 0;
+}
+
+
+static int
+xm_fence_finish(struct pipe_winsys *sws, struct pipe_fence_handle *fence,
+ unsigned flag)
+{
+ return 0;
+}
+
/**
* Return pointer to a pipe_winsys object.
@@ -377,35 +604,42 @@ xm_surface_release(struct pipe_winsys *winsys, struct pipe_surface **s)
* Nothing special for the Xlib driver so no subclassing or anything.
*/
struct pipe_winsys *
-xmesa_get_pipe_winsys_aub(void)
+xmesa_get_pipe_winsys_aub(struct xmesa_visual *xm_vis)
{
- static struct pipe_winsys *ws = NULL;
+ static struct xmesa_pipe_winsys *ws = NULL;
if (!ws && getenv("XM_AUB")) {
- ws = xmesa_create_pipe_winsys_aub();
+ ws = (struct xmesa_pipe_winsys *) xmesa_create_pipe_winsys_aub();
}
else if (!ws) {
- ws = CALLOC_STRUCT(pipe_winsys);
-
+ ws = CALLOC_STRUCT(xmesa_pipe_winsys);
+
+ ws->xm_visual = xm_vis;
+ ws->shm = xmesa_check_for_xshm(xm_vis->display);
+
/* Fill in this struct with callbacks that pipe will need to
* communicate with the window system, buffer manager, etc.
*/
- ws->buffer_create = xm_buffer_create;
- ws->user_buffer_create = xm_user_buffer_create;
- ws->buffer_map = xm_buffer_map;
- ws->buffer_unmap = xm_buffer_unmap;
- ws->buffer_destroy = xm_buffer_destroy;
-
- ws->surface_alloc = xm_surface_alloc;
- ws->surface_alloc_storage = xm_surface_alloc_storage;
- ws->surface_release = xm_surface_release;
-
- ws->flush_frontbuffer = xm_flush_frontbuffer;
- ws->printf = xm_printf;
- ws->get_name = xm_get_name;
+ ws->base.buffer_create = xm_buffer_create;
+ ws->base.user_buffer_create = xm_user_buffer_create;
+ ws->base.buffer_map = xm_buffer_map;
+ ws->base.buffer_unmap = xm_buffer_unmap;
+ ws->base.buffer_destroy = xm_buffer_destroy;
+
+ ws->base.surface_alloc = xm_surface_alloc;
+ ws->base.surface_alloc_storage = xm_surface_alloc_storage;
+ ws->base.surface_release = xm_surface_release;
+
+ ws->base.fence_reference = xm_fence_reference;
+ ws->base.fence_signalled = xm_fence_signalled;
+ ws->base.fence_finish = xm_fence_finish;
+
+ ws->base.flush_frontbuffer = xm_flush_frontbuffer;
+ ws->base.printf = xm_printf;
+ ws->base.get_name = xm_get_name;
}
- return ws;
+ return &ws->base;
}
@@ -445,27 +679,27 @@ xmesa_get_softpipe_winsys(uint pixelformat)
struct pipe_context *
xmesa_create_pipe_context(XMesaContext xmesa, uint pixelformat)
{
- struct pipe_winsys *pws = xmesa_get_pipe_winsys_aub();
+ struct pipe_winsys *pws = xmesa_get_pipe_winsys_aub(xmesa->xm_visual);
struct pipe_context *pipe;
#ifdef GALLIUM_CELL
if (!getenv("GALLIUM_NOCELL")) {
struct cell_winsys *cws = cell_get_winsys(pixelformat);
struct pipe_screen *screen = cell_create_screen(pws);
+
pipe = cell_create_context(screen, cws);
- if (pipe)
- pipe->priv = xmesa;
- return pipe;
}
else
#endif
{
struct softpipe_winsys *spws = xmesa_get_softpipe_winsys(pixelformat);
struct pipe_screen *screen = softpipe_create_screen(pws);
- pipe = softpipe_create( screen, pws, spws );
- if (pipe)
- pipe->priv = xmesa;
- return pipe;
+ pipe = softpipe_create(screen, pws, spws);
}
+
+ if (pipe)
+ pipe->priv = xmesa;
+
+ return pipe;
}
diff --git a/src/gallium/winsys/xlib/xm_winsys_aub.h b/src/gallium/winsys/xlib/xm_winsys_aub.h
index 7bee1991169..cc2a7552771 100644
--- a/src/gallium/winsys/xlib/xm_winsys_aub.h
+++ b/src/gallium/winsys/xlib/xm_winsys_aub.h
@@ -62,6 +62,7 @@ void xmesa_commands_aub(struct pipe_winsys *winsys,
void xmesa_display_aub( /* struct pipe_winsys *winsys, */
struct pipe_surface *surface );
-struct pipe_winsys *xmesa_get_pipe_winsys_aub(void);
+extern struct pipe_winsys *
+xmesa_get_pipe_winsys_aub(struct xmesa_visual *xm_vis);
#endif
diff --git a/src/gallium/winsys/xlib/xmesaP.h b/src/gallium/winsys/xlib/xmesaP.h
index fa8d1f14b95..9b15b2ddf99 100644
--- a/src/gallium/winsys/xlib/xmesaP.h
+++ b/src/gallium/winsys/xlib/xmesaP.h
@@ -173,4 +173,7 @@ xmesa_buffer_height(XMesaBuffer b)
extern void
xmesa_display_surface(XMesaBuffer b, const struct pipe_surface *surf);
+extern int
+xmesa_check_for_xshm(XMesaDisplay *display);
+
#endif
diff --git a/src/mesa/main/fbobject.c b/src/mesa/main/fbobject.c
index 6a8cba4d8a9..800f6ee9a31 100644
--- a/src/mesa/main/fbobject.c
+++ b/src/mesa/main/fbobject.c
@@ -307,7 +307,7 @@ test_attachment_completeness(const GLcontext *ctx, GLenum format,
/* OK */
}
else if (ctx->Extensions.EXT_packed_depth_stencil &&
- att->Renderbuffer->_BaseFormat == GL_DEPTH_STENCIL_EXT) {
+ texImage->TexFormat->BaseFormat == GL_DEPTH_STENCIL_EXT) {
/* OK */
}
else {
diff --git a/src/mesa/shader/arbprogparse.c b/src/mesa/shader/arbprogparse.c
index 9e5169eff17..b60b9656c62 100644
--- a/src/mesa/shader/arbprogparse.c
+++ b/src/mesa/shader/arbprogparse.c
@@ -1,8 +1,8 @@
/*
* Mesa 3-D graphics library
- * Version: 6.5.3
+ * Version: 7.1
*
- * Copyright (C) 1999-2007 Brian Paul All Rights Reserved.
+ * Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -35,6 +35,7 @@
#include "shader/grammar/grammar_mesa.h"
#include "arbprogparse.h"
#include "program.h"
+#include "programopt.h"
#include "prog_parameter.h"
#include "prog_statevars.h"
#include "context.h"
@@ -633,6 +634,41 @@ program_error(GLcontext *ctx, GLint position, const char *descrip)
}
+/**
+ * As above, but with an extra string parameter for more info.
+ */
+static void
+program_error2(GLcontext *ctx, GLint position, const char *descrip,
+ const char *var)
+{
+ if (descrip) {
+ const char *prefix = "glProgramString(", *suffix = ")";
+ char *str = (char *) _mesa_malloc(_mesa_strlen(descrip) +
+ _mesa_strlen(": ") +
+ _mesa_strlen(var) +
+ _mesa_strlen(prefix) +
+ _mesa_strlen(suffix) + 1);
+ if (str) {
+ _mesa_sprintf(str, "%s%s: %s%s", prefix, descrip, var, suffix);
+ _mesa_error(ctx, GL_INVALID_OPERATION, str);
+ _mesa_free(str);
+ }
+ }
+ {
+ char *str = (char *) _mesa_malloc(_mesa_strlen(descrip) +
+ _mesa_strlen(": ") +
+ _mesa_strlen(var) + 1);
+ if (str) {
+ _mesa_sprintf(str, "%s: %s", descrip, var);
+ }
+ _mesa_set_program_error(ctx, position, str);
+ if (str) {
+ _mesa_free(str);
+ }
+ }
+}
+
+
/**
* constructs an integer from 4 GLubytes in LE format
@@ -1226,10 +1262,10 @@ parse_state_single_item (GLcontext * ctx, const GLubyte ** inst,
state_tokens[1] = coord;
/* EYE or OBJECT */
- type = *(*inst++);
+ type = *(*inst)++;
/* 0 - s, 1 - t, 2 - r, 3 - q */
- coord = *(*inst++);
+ coord = *(*inst)++;
if (type == TEX_GEN_EYE) {
switch (coord) {
@@ -1245,6 +1281,9 @@ parse_state_single_item (GLcontext * ctx, const GLubyte ** inst,
case COMPONENT_W:
state_tokens[2] = STATE_TEXGEN_EYE_Q;
break;
+ default:
+ _mesa_problem(ctx, "bad texgen component in "
+ "parse_state_single_item()");
}
}
else {
@@ -1261,6 +1300,9 @@ parse_state_single_item (GLcontext * ctx, const GLubyte ** inst,
case COMPONENT_W:
state_tokens[2] = STATE_TEXGEN_OBJECT_Q;
break;
+ default:
+ _mesa_problem(ctx, "bad texgen component in "
+ "parse_state_single_item()");
}
}
}
@@ -1283,7 +1325,7 @@ parse_state_single_item (GLcontext * ctx, const GLubyte ** inst,
break;
case STATE_POINT:
- switch (*(*inst++)) {
+ switch (*(*inst)++) {
case POINT_SIZE:
state_tokens[0] = STATE_POINT_SIZE;
break;
@@ -1685,18 +1727,14 @@ parse_attrib (GLcontext * ctx, const GLubyte ** inst, struct var_cache **vc_head
struct arb_program *Program)
{
GLuint found;
- char *error_msg;
struct var_cache *attrib_var;
attrib_var = parse_string (inst, vc_head, Program, &found);
Program->Position = parse_position (inst);
if (found) {
- error_msg = (char *)
- _mesa_malloc (_mesa_strlen ((char *) attrib_var->name) + 40);
- _mesa_sprintf (error_msg, "Duplicate Variable Declaration: %s",
- attrib_var->name);
- program_error(ctx, Program->Position, error_msg);
- _mesa_free (error_msg);
+ program_error2(ctx, Program->Position,
+ "Duplicate variable declaration",
+ (char *) attrib_var->name);
return 1;
}
@@ -1729,7 +1767,7 @@ parse_param_elements (GLcontext * ctx, const GLubyte ** inst,
{
GLint idx;
GLuint err = 0;
- gl_state_index state_tokens[STATE_LENGTH];
+ gl_state_index state_tokens[STATE_LENGTH] = {0, 0, 0, 0, 0};
GLfloat const_values[4];
switch (*(*inst)++) {
@@ -1876,12 +1914,9 @@ parse_param (GLcontext * ctx, const GLubyte ** inst, struct var_cache **vc_head,
Program->Position = parse_position (inst);
if (found) {
- char *error_msg = (char *)
- _mesa_malloc (_mesa_strlen ((char *) param_var->name) + 40);
- _mesa_sprintf (error_msg, "Duplicate Variable Declaration: %s",
- param_var->name);
- program_error (ctx, Program->Position, error_msg);
- _mesa_free (error_msg);
+ program_error2(ctx, Program->Position,
+ "Duplicate variable declaration",
+ (char *) param_var->name);
return 1;
}
@@ -1976,12 +2011,9 @@ parse_temp (GLcontext * ctx, const GLubyte ** inst, struct var_cache **vc_head,
temp_var = parse_string (inst, vc_head, Program, &found);
Program->Position = parse_position (inst);
if (found) {
- char *error_msg = (char *)
- _mesa_malloc (_mesa_strlen ((char *) temp_var->name) + 40);
- _mesa_sprintf (error_msg, "Duplicate Variable Declaration: %s",
- temp_var->name);
- program_error(ctx, Program->Position, error_msg);
- _mesa_free (error_msg);
+ program_error2(ctx, Program->Position,
+ "Duplicate variable declaration",
+ (char *) temp_var->name);
return 1;
}
@@ -2022,12 +2054,9 @@ parse_output (GLcontext * ctx, const GLubyte ** inst, struct var_cache **vc_head
output_var = parse_string (inst, vc_head, Program, &found);
Program->Position = parse_position (inst);
if (found) {
- char *error_msg = (char *)
- _mesa_malloc (_mesa_strlen ((char *) output_var->name) + 40);
- _mesa_sprintf (error_msg, "Duplicate Variable Declaration: %s",
- output_var->name);
- program_error (ctx, Program->Position, error_msg);
- _mesa_free (error_msg);
+ program_error2(ctx, Program->Position,
+ "Duplicate variable declaration",
+ (char *) output_var->name);
return 1;
}
@@ -2053,12 +2082,9 @@ parse_alias (GLcontext * ctx, const GLubyte ** inst, struct var_cache **vc_head,
Program->Position = parse_position (inst);
if (found) {
- char *error_msg = (char *)
- _mesa_malloc (_mesa_strlen ((char *) temp_var->name) + 40);
- _mesa_sprintf (error_msg, "Duplicate Variable Declaration: %s",
- temp_var->name);
- program_error(ctx, Program->Position, error_msg);
- _mesa_free (error_msg);
+ program_error2(ctx, Program->Position,
+ "Duplicate variable declaration",
+ (char *) temp_var->name);
return 1;
}
@@ -2068,12 +2094,9 @@ parse_alias (GLcontext * ctx, const GLubyte ** inst, struct var_cache **vc_head,
if (!found)
{
- char *error_msg = (char *)
- _mesa_malloc (_mesa_strlen ((char *) temp_var->name) + 40);
- _mesa_sprintf (error_msg, "Alias value %s is not defined",
- temp_var->alias_binding->name);
- program_error (ctx, Program->Position, error_msg);
- _mesa_free (error_msg);
+ program_error2(ctx, Program->Position,
+ "Undefined alias value",
+ (char *) temp_var->alias_binding->name);
return 1;
}
@@ -2096,12 +2119,9 @@ parse_address (GLcontext * ctx, const GLubyte ** inst, struct var_cache **vc_hea
temp_var = parse_string (inst, vc_head, Program, &found);
Program->Position = parse_position (inst);
if (found) {
- char *error_msg = (char *)
- _mesa_malloc (_mesa_strlen ((char *) temp_var->name) + 40);
- _mesa_sprintf (error_msg, "Duplicate Variable Declaration: %s",
- temp_var->name);
- program_error (ctx, Program->Position, error_msg);
- _mesa_free (error_msg);
+ program_error2(ctx, Program->Position,
+ "Duplicate variable declaration",
+ (char *) temp_var->name);
return 1;
}
@@ -2454,8 +2474,9 @@ parse_src_reg (GLcontext * ctx, const GLubyte ** inst,
Program->Position = parse_position (inst);
if (!found) {
- program_error(ctx, Program->Position,
- "2: Undefined variable"); /* src->name */
+ program_error2(ctx, Program->Position,
+ "Undefined variable",
+ (char *) src->name);
return 1;
}
@@ -2562,23 +2583,24 @@ parse_src_reg (GLcontext * ctx, const GLubyte ** inst,
return 0;
}
+
/**
- * Parse fragment program vector source register.
+ * Parse vertex/fragment program vector source register.
*/
static GLuint
-parse_fp_vector_src_reg(GLcontext * ctx, const GLubyte ** inst,
- struct var_cache **vc_head,
- struct arb_program *program,
- struct prog_src_register *reg)
+parse_vector_src_reg(GLcontext *ctx, const GLubyte **inst,
+ struct var_cache **vc_head,
+ struct arb_program *program,
+ struct prog_src_register *reg)
{
enum register_file file;
GLint index;
- GLboolean negate;
+ GLubyte negateMask;
GLubyte swizzle[4];
GLboolean isRelOffset;
/* Grab the sign */
- negate = (parse_sign (inst) == -1) ? 0xf : 0x0;
+ negateMask = (parse_sign (inst) == -1) ? NEGATE_XYZW : NEGATE_NONE;
/* And the src reg */
if (parse_src_reg(ctx, inst, vc_head, program, &file, &index, &isRelOffset))
@@ -2589,66 +2611,66 @@ parse_fp_vector_src_reg(GLcontext * ctx, const GLubyte ** inst,
reg->File = file;
reg->Index = index;
- reg->NegateBase = negate;
reg->Swizzle = MAKE_SWIZZLE4(swizzle[0], swizzle[1], swizzle[2], swizzle[3]);
+ reg->NegateBase = negateMask;
+ reg->RelAddr = isRelOffset;
return 0;
}
/**
- * Parse fragment program destination register.
- * \return 1 if error, 0 if no error.
+ * Parse vertex/fragment program scalar source register.
*/
-static GLuint
-parse_fp_dst_reg(GLcontext * ctx, const GLubyte ** inst,
- struct var_cache **vc_head, struct arb_program *Program,
- struct prog_dst_register *reg )
+static GLuint
+parse_scalar_src_reg(GLcontext *ctx, const GLubyte **inst,
+ struct var_cache **vc_head,
+ struct arb_program *program,
+ struct prog_src_register *reg)
{
- GLint mask;
- GLuint idx;
enum register_file file;
+ GLint index;
+ GLubyte negateMask;
+ GLubyte swizzle[4];
+ GLboolean isRelOffset;
- if (parse_masked_dst_reg (ctx, inst, vc_head, Program, &file, &idx, &mask))
+ /* Grab the sign */
+ negateMask = (parse_sign (inst) == -1) ? NEGATE_XYZW : NEGATE_NONE;
+
+ /* And the src reg */
+ if (parse_src_reg(ctx, inst, vc_head, program, &file, &index, &isRelOffset))
return 1;
+ /* finally, the swizzle */
+ parse_swizzle_mask(inst, swizzle, 1);
+
reg->File = file;
- reg->Index = idx;
- reg->WriteMask = mask;
+ reg->Index = index;
+ reg->Swizzle = (swizzle[0] << 0);
+ reg->NegateBase = negateMask;
+ reg->RelAddr = isRelOffset;
return 0;
}
/**
- * Parse fragment program scalar src register.
+ * Parse vertex/fragment program destination register.
* \return 1 if error, 0 if no error.
*/
-static GLuint
-parse_fp_scalar_src_reg (GLcontext * ctx, const GLubyte ** inst,
- struct var_cache **vc_head,
- struct arb_program *Program,
- struct prog_src_register *reg )
+static GLuint
+parse_dst_reg(GLcontext * ctx, const GLubyte ** inst,
+ struct var_cache **vc_head, struct arb_program *program,
+ struct prog_dst_register *reg )
{
- enum register_file File;
- GLint Index;
- GLubyte Negate;
- GLubyte Swizzle[4];
- GLboolean IsRelOffset;
-
- /* Grab the sign */
- Negate = (parse_sign (inst) == -1) ? 0x1 : 0x0;
+ GLint mask;
+ GLuint idx;
+ enum register_file file;
- /* And the src reg */
- if (parse_src_reg (ctx, inst, vc_head, Program, &File, &Index, &IsRelOffset))
+ if (parse_masked_dst_reg (ctx, inst, vc_head, program, &file, &idx, &mask))
return 1;
- /* finally, the swizzle */
- parse_swizzle_mask(inst, Swizzle, 1);
-
- reg->File = File;
- reg->Index = Index;
- reg->NegateBase = Negate;
- reg->Swizzle = (Swizzle[0] << 0);
-
+ reg->File = file;
+ reg->Index = idx;
+ reg->WriteMask = mask;
return 0;
}
@@ -2729,10 +2751,10 @@ parse_fp_instruction (GLcontext * ctx, const GLubyte ** inst,
break;
}
- if (parse_fp_dst_reg (ctx, inst, vc_head, Program, &fp->DstReg))
+ if (parse_dst_reg (ctx, inst, vc_head, Program, &fp->DstReg))
return 1;
- if (parse_fp_vector_src_reg(ctx, inst, vc_head, Program, &fp->SrcReg[0]))
+ if (parse_vector_src_reg(ctx, inst, vc_head, Program, &fp->SrcReg[0]))
return 1;
break;
@@ -2782,10 +2804,10 @@ parse_fp_instruction (GLcontext * ctx, const GLubyte ** inst,
break;
}
- if (parse_fp_dst_reg (ctx, inst, vc_head, Program, &fp->DstReg))
+ if (parse_dst_reg (ctx, inst, vc_head, Program, &fp->DstReg))
return 1;
- if (parse_fp_scalar_src_reg(ctx, inst, vc_head, Program, &fp->SrcReg[0]))
+ if (parse_scalar_src_reg(ctx, inst, vc_head, Program, &fp->SrcReg[0]))
return 1;
break;
@@ -2798,11 +2820,11 @@ parse_fp_instruction (GLcontext * ctx, const GLubyte ** inst,
break;
}
- if (parse_fp_dst_reg(ctx, inst, vc_head, Program, &fp->DstReg))
+ if (parse_dst_reg(ctx, inst, vc_head, Program, &fp->DstReg))
return 1;
for (a = 0; a < 2; a++) {
- if (parse_fp_scalar_src_reg(ctx, inst, vc_head, Program, &fp->SrcReg[a]))
+ if (parse_scalar_src_reg(ctx, inst, vc_head, Program, &fp->SrcReg[a]))
return 1;
}
break;
@@ -2883,10 +2905,10 @@ parse_fp_instruction (GLcontext * ctx, const GLubyte ** inst,
break;
}
- if (parse_fp_dst_reg (ctx, inst, vc_head, Program, &fp->DstReg))
+ if (parse_dst_reg (ctx, inst, vc_head, Program, &fp->DstReg))
return 1;
for (a = 0; a < 2; a++) {
- if (parse_fp_vector_src_reg(ctx, inst, vc_head, Program, &fp->SrcReg[a]))
+ if (parse_vector_src_reg(ctx, inst, vc_head, Program, &fp->SrcReg[a]))
return 1;
}
break;
@@ -2912,11 +2934,11 @@ parse_fp_instruction (GLcontext * ctx, const GLubyte ** inst,
break;
}
- if (parse_fp_dst_reg (ctx, inst, vc_head, Program, &fp->DstReg))
+ if (parse_dst_reg (ctx, inst, vc_head, Program, &fp->DstReg))
return 1;
for (a = 0; a < 3; a++) {
- if (parse_fp_vector_src_reg(ctx, inst, vc_head, Program, &fp->SrcReg[a]))
+ if (parse_vector_src_reg(ctx, inst, vc_head, Program, &fp->SrcReg[a]))
return 1;
}
break;
@@ -2929,7 +2951,7 @@ parse_fp_instruction (GLcontext * ctx, const GLubyte ** inst,
fp->Opcode = OPCODE_SWZ;
break;
}
- if (parse_fp_dst_reg (ctx, inst, vc_head, Program, &fp->DstReg))
+ if (parse_dst_reg (ctx, inst, vc_head, Program, &fp->DstReg))
return 1;
{
@@ -2972,10 +2994,10 @@ parse_fp_instruction (GLcontext * ctx, const GLubyte ** inst,
break;
}
- if (parse_fp_dst_reg (ctx, inst, vc_head, Program, &fp->DstReg))
+ if (parse_dst_reg (ctx, inst, vc_head, Program, &fp->DstReg))
return 1;
- if (parse_fp_vector_src_reg(ctx, inst, vc_head, Program, &fp->SrcReg[0]))
+ if (parse_vector_src_reg(ctx, inst, vc_head, Program, &fp->SrcReg[0]))
return 1;
/* texImageUnit */
@@ -3047,7 +3069,7 @@ parse_fp_instruction (GLcontext * ctx, const GLubyte ** inst,
case OP_TEX_KIL:
Program->UsesKill = 1;
- if (parse_fp_vector_src_reg(ctx, inst, vc_head, Program, &fp->SrcReg[0]))
+ if (parse_vector_src_reg(ctx, inst, vc_head, Program, &fp->SrcReg[0]))
return 1;
fp->Opcode = OPCODE_KIL;
break;
@@ -3059,23 +3081,6 @@ parse_fp_instruction (GLcontext * ctx, const GLubyte ** inst,
return 0;
}
-static GLuint
-parse_vp_dst_reg(GLcontext * ctx, const GLubyte ** inst,
- struct var_cache **vc_head, struct arb_program *Program,
- struct prog_dst_register *reg )
-{
- GLint mask;
- GLuint idx;
- enum register_file file;
-
- if (parse_masked_dst_reg(ctx, inst, vc_head, Program, &file, &idx, &mask))
- return 1;
-
- reg->File = file;
- reg->Index = idx;
- reg->WriteMask = mask;
- return 0;
-}
/**
* Handle the parsing out of a masked address register
@@ -3107,71 +3112,6 @@ parse_vp_address_reg (GLcontext * ctx, const GLubyte ** inst,
return 0;
}
-/**
- * Parse vertex program vector source register.
- */
-static GLuint
-parse_vp_vector_src_reg(GLcontext * ctx, const GLubyte ** inst,
- struct var_cache **vc_head,
- struct arb_program *program,
- struct prog_src_register *reg )
-{
- enum register_file file;
- GLint index;
- GLubyte negateMask;
- GLubyte swizzle[4];
- GLboolean isRelOffset;
-
- /* Grab the sign */
- negateMask = (parse_sign (inst) == -1) ? 0xf : 0x0;
-
- /* And the src reg */
- if (parse_src_reg (ctx, inst, vc_head, program, &file, &index, &isRelOffset))
- return 1;
-
- /* finally, the swizzle */
- parse_swizzle_mask(inst, swizzle, 4);
-
- reg->File = file;
- reg->Index = index;
- reg->Swizzle = MAKE_SWIZZLE4(swizzle[0], swizzle[1],
- swizzle[2], swizzle[3]);
- reg->NegateBase = negateMask;
- reg->RelAddr = isRelOffset;
- return 0;
-}
-
-
-static GLuint
-parse_vp_scalar_src_reg (GLcontext * ctx, const GLubyte ** inst,
- struct var_cache **vc_head,
- struct arb_program *Program,
- struct prog_src_register *reg )
-{
- enum register_file File;
- GLint Index;
- GLubyte Negate;
- GLubyte Swizzle[4];
- GLboolean IsRelOffset;
-
- /* Grab the sign */
- Negate = (parse_sign (inst) == -1) ? 0x1 : 0x0;
-
- /* And the src reg */
- if (parse_src_reg (ctx, inst, vc_head, Program, &File, &Index, &IsRelOffset))
- return 1;
-
- /* finally, the swizzle */
- parse_swizzle_mask(inst, Swizzle, 1);
-
- reg->File = File;
- reg->Index = Index;
- reg->Swizzle = (Swizzle[0] << 0);
- reg->NegateBase = Negate;
- reg->RelAddr = IsRelOffset;
- return 0;
-}
-
/**
* This is a big mother that handles getting opcodes into the instruction
@@ -3209,7 +3149,7 @@ parse_vp_instruction (GLcontext * ctx, const GLubyte ** inst,
vp->DstReg.File = PROGRAM_ADDRESS;
/* Get a scalar src register */
- if (parse_vp_scalar_src_reg(ctx, inst, vc_head, Program, &vp->SrcReg[0]))
+ if (parse_scalar_src_reg(ctx, inst, vc_head, Program, &vp->SrcReg[0]))
return 1;
break;
@@ -3233,10 +3173,10 @@ parse_vp_instruction (GLcontext * ctx, const GLubyte ** inst,
break;
}
- if (parse_vp_dst_reg(ctx, inst, vc_head, Program, &vp->DstReg))
+ if (parse_dst_reg(ctx, inst, vc_head, Program, &vp->DstReg))
return 1;
- if (parse_vp_vector_src_reg(ctx, inst, vc_head, Program, &vp->SrcReg[0]))
+ if (parse_vector_src_reg(ctx, inst, vc_head, Program, &vp->SrcReg[0]))
return 1;
break;
@@ -3261,10 +3201,10 @@ parse_vp_instruction (GLcontext * ctx, const GLubyte ** inst,
vp->Opcode = OPCODE_RSQ;
break;
}
- if (parse_vp_dst_reg(ctx, inst, vc_head, Program, &vp->DstReg))
+ if (parse_dst_reg(ctx, inst, vc_head, Program, &vp->DstReg))
return 1;
- if (parse_vp_scalar_src_reg(ctx, inst, vc_head, Program, &vp->SrcReg[0]))
+ if (parse_scalar_src_reg(ctx, inst, vc_head, Program, &vp->SrcReg[0]))
return 1;
break;
@@ -3274,11 +3214,11 @@ parse_vp_instruction (GLcontext * ctx, const GLubyte ** inst,
vp->Opcode = OPCODE_POW;
break;
}
- if (parse_vp_dst_reg(ctx, inst, vc_head, Program, &vp->DstReg))
+ if (parse_dst_reg(ctx, inst, vc_head, Program, &vp->DstReg))
return 1;
for (a = 0; a < 2; a++) {
- if (parse_vp_scalar_src_reg(ctx, inst, vc_head, Program, &vp->SrcReg[a]))
+ if (parse_scalar_src_reg(ctx, inst, vc_head, Program, &vp->SrcReg[a]))
return 1;
}
break;
@@ -3322,11 +3262,11 @@ parse_vp_instruction (GLcontext * ctx, const GLubyte ** inst,
vp->Opcode = OPCODE_XPD;
break;
}
- if (parse_vp_dst_reg(ctx, inst, vc_head, Program, &vp->DstReg))
+ if (parse_dst_reg(ctx, inst, vc_head, Program, &vp->DstReg))
return 1;
for (a = 0; a < 2; a++) {
- if (parse_vp_vector_src_reg(ctx, inst, vc_head, Program, &vp->SrcReg[a]))
+ if (parse_vector_src_reg(ctx, inst, vc_head, Program, &vp->SrcReg[a]))
return 1;
}
break;
@@ -3338,11 +3278,11 @@ parse_vp_instruction (GLcontext * ctx, const GLubyte ** inst,
break;
}
- if (parse_vp_dst_reg(ctx, inst, vc_head, Program, &vp->DstReg))
+ if (parse_dst_reg(ctx, inst, vc_head, Program, &vp->DstReg))
return 1;
for (a = 0; a < 3; a++) {
- if (parse_vp_vector_src_reg(ctx, inst, vc_head, Program, &vp->SrcReg[a]))
+ if (parse_vector_src_reg(ctx, inst, vc_head, Program, &vp->SrcReg[a]))
return 1;
}
break;
@@ -3360,7 +3300,7 @@ parse_vp_instruction (GLcontext * ctx, const GLubyte ** inst,
enum register_file file;
GLint index;
- if (parse_vp_dst_reg(ctx, inst, vc_head, Program, &vp->DstReg))
+ if (parse_dst_reg(ctx, inst, vc_head, Program, &vp->DstReg))
return 1;
if (parse_src_reg(ctx, inst, vc_head, Program, &file, &index, &relAddr))
@@ -3794,11 +3734,11 @@ _mesa_parse_arb_program(GLcontext *ctx, GLenum target,
int line, col;
char *s;
fprintf(stderr, "program: %s\n", (char *) strz);
- fprintf(stderr, "Error Pos: %d\n", ctx->program.ErrorPos);
- s = (char *) _mesa_find_line_column(strz, strz+ctx->program.ErrorPos,
+ fprintf(stderr, "Error Pos: %d\n", ctx->Program.ErrorPos);
+ s = (char *) _mesa_find_line_column(strz, strz+ctx->Program.ErrorPos,
&line, &col);
fprintf(stderr, "line %d col %d: %s\n", line, col, s);
- } while (0)
+ } while (0);
#endif
_mesa_free(strz);
@@ -3929,6 +3869,16 @@ _mesa_parse_arb_fragment_program(GLcontext* ctx, GLenum target,
_mesa_free_parameter_list(program->Base.Parameters);
program->Base.Parameters = ap.Base.Parameters;
+ /* Append fog instructions now if the program has "OPTION ARB_fog_exp"
+ * or similar. We used to leave this up to drivers, but it appears
+ * there's no hardware that wants to do fog in a discrete stage separate
+ * from the fragment shader.
+ */
+ if (program->FogOption != GL_NONE) {
+ _mesa_append_fog_code(ctx, program);
+ program->FogOption = GL_NONE;
+ }
+
#if DEBUG_FP
_mesa_printf("____________Fragment program %u ________\n", program->Base.ID);
_mesa_print_program(&program->Base);
@@ -3952,7 +3902,7 @@ _mesa_parse_arb_vertex_program(GLcontext *ctx, GLenum target,
ASSERT(target == GL_VERTEX_PROGRAM_ARB);
if (!_mesa_parse_arb_program(ctx, target, (const GLubyte*) str, len, &ap)) {
- /* Error in the program. Just return. */
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glProgramString(bad program)");
return;
}
diff --git a/src/mesa/shader/prog_parameter.c b/src/mesa/shader/prog_parameter.c
index bb964274b95..4eb7313bec1 100644
--- a/src/mesa/shader/prog_parameter.c
+++ b/src/mesa/shader/prog_parameter.c
@@ -387,7 +387,7 @@ sizeof_state_reference(const GLint *stateTokens)
* PARAM ambient = state.material.front.ambient;
*
* \param paramList the parameter list
- * \param state an array of 6 (STATE_LENGTH) state tokens
+ * \param stateTokens an array of 5 (STATE_LENGTH) state tokens
* \return index of the new parameter.
*/
GLint
diff --git a/src/mesa/shader/program.c b/src/mesa/shader/program.c
index 39c4ca1dd5d..09a8494bd36 100644
--- a/src/mesa/shader/program.c
+++ b/src/mesa/shader/program.c
@@ -426,6 +426,7 @@ replace_registers(struct prog_instruction *inst, GLuint numInst,
{
GLuint i, j;
for (i = 0; i < numInst; i++) {
+ /* src regs */
for (j = 0; j < _mesa_num_inst_src_regs(inst->Opcode); j++) {
if (inst[i].SrcReg[j].File == oldFile &&
inst[i].SrcReg[j].Index == oldIndex) {
@@ -433,6 +434,11 @@ replace_registers(struct prog_instruction *inst, GLuint numInst,
inst[i].SrcReg[j].Index = newIndex;
}
}
+ /* dst reg */
+ if (inst[i].DstReg.File == oldFile && inst[i].DstReg.Index == oldIndex) {
+ inst[i].DstReg.File = newFile;
+ inst[i].DstReg.Index = newIndex;
+ }
}
}
@@ -504,12 +510,25 @@ _mesa_combine_programs(GLcontext *ctx,
newFprog->UsesKill = fprogA->UsesKill || fprogB->UsesKill;
- /* connect color outputs/inputs */
+ /* Connect color outputs of fprogA to color inputs of fprogB, via a
+ * new temporary register.
+ */
if ((progA->OutputsWritten & (1 << FRAG_RESULT_COLR)) &&
(progB->InputsRead & (1 << FRAG_ATTRIB_COL0))) {
+ GLint tempReg = _mesa_find_free_register(newProg, PROGRAM_TEMPORARY);
+ if (!tempReg) {
+ _mesa_problem(ctx, "No free temp regs found in "
+ "_mesa_combine_programs(), using 31");
+ tempReg = 31;
+ }
+ /* replace writes to result.color[0] with tempReg */
+ replace_registers(newInst, lenA,
+ PROGRAM_OUTPUT, FRAG_RESULT_COLR,
+ PROGRAM_TEMPORARY, tempReg);
+ /* replace reads from input.color[0] with tempReg */
replace_registers(newInst + lenA, lenB,
PROGRAM_INPUT, FRAG_ATTRIB_COL0,
- PROGRAM_OUTPUT, FRAG_RESULT_COLR);
+ PROGRAM_TEMPORARY, tempReg);
}
inputsB = progB->InputsRead;
diff --git a/src/mesa/state_tracker/st_atom.c b/src/mesa/state_tracker/st_atom.c
index 0e22a2fa6e7..18063adc79c 100644
--- a/src/mesa/state_tracker/st_atom.c
+++ b/src/mesa/state_tracker/st_atom.c
@@ -32,6 +32,7 @@
#include "pipe/p_defines.h"
#include "st_context.h"
#include "st_atom.h"
+#include "st_cb_bitmap.h"
#include "st_program.h"
@@ -147,6 +148,13 @@ void st_validate_state( struct st_context *st )
struct st_state_flags *state = &st->dirty;
GLuint i;
+ /* The bitmap cache is immune to pixel unpack changes.
+ * Note that GLUT makes several calls to glPixelStore for each
+ * bitmap char it draws so this is an important check.
+ */
+ if (state->mesa & ~_NEW_PACKUNPACK)
+ st_flush_bitmap_cache(st);
+
check_program_state( st );
if (state->st == 0)
diff --git a/src/mesa/state_tracker/st_atom_depth.c b/src/mesa/state_tracker/st_atom_depth.c
index 827ad3b548b..03057e37fa0 100644
--- a/src/mesa/state_tracker/st_atom_depth.c
+++ b/src/mesa/state_tracker/st_atom_depth.c
@@ -105,7 +105,7 @@ update_depth_stencil_alpha(struct st_context *st)
st->ctx->Query.CurrentOcclusionObject->Active)
dsa->depth.occlusion_count = 1;
- if (st->ctx->Stencil.Enabled) {
+ if (st->ctx->Stencil.Enabled && st->ctx->Visual.stencilBits > 0) {
dsa->stencil[0].enabled = 1;
dsa->stencil[0].func = st_compare_func_to_pipe(st->ctx->Stencil.Function[0]);
dsa->stencil[0].fail_op = gl_stencil_op_to_pipe(st->ctx->Stencil.FailFunc[0]);
@@ -125,6 +125,9 @@ update_depth_stencil_alpha(struct st_context *st)
dsa->stencil[1].value_mask = st->ctx->Stencil.ValueMask[1] & 0xff;
dsa->stencil[1].write_mask = st->ctx->Stencil.WriteMask[1] & 0xff;
}
+ else {
+ dsa->stencil[1] = dsa->stencil[0];
+ }
}
if (st->ctx->Color.AlphaEnabled) {
diff --git a/src/mesa/state_tracker/st_atom_sampler.c b/src/mesa/state_tracker/st_atom_sampler.c
index 5787a7492c6..5dd242ac662 100644
--- a/src/mesa/state_tracker/st_atom_sampler.c
+++ b/src/mesa/state_tracker/st_atom_sampler.c
@@ -167,7 +167,6 @@ update_samplers(struct st_context *st)
/* only care about ARB_shadow, not SGI shadow */
if (texobj->CompareMode == GL_COMPARE_R_TO_TEXTURE) {
- sampler->compare = 1;
sampler->compare_mode = PIPE_TEX_COMPARE_R_TO_TEXTURE;
sampler->compare_func
= st_compare_func_to_pipe(texobj->CompareFunc);
diff --git a/src/mesa/state_tracker/st_cb_accum.c b/src/mesa/state_tracker/st_cb_accum.c
index f1fddc4e026..a623d0bcc06 100644
--- a/src/mesa/state_tracker/st_cb_accum.c
+++ b/src/mesa/state_tracker/st_cb_accum.c
@@ -214,7 +214,7 @@ st_Accum(GLcontext *ctx, GLenum op, GLfloat value)
const GLint height = ctx->DrawBuffer->_Ymax - ypos;
/* make sure color bufs aren't cached */
- pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE);
+ pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, NULL);
switch (op) {
case GL_ADD:
diff --git a/src/mesa/state_tracker/st_cb_bitmap.c b/src/mesa/state_tracker/st_cb_bitmap.c
index 6e594398743..ec56b25f7ce 100644
--- a/src/mesa/state_tracker/st_cb_bitmap.c
+++ b/src/mesa/state_tracker/st_cb_bitmap.c
@@ -60,6 +60,33 @@
/**
+ * The bitmap cache attempts to accumulate multiple glBitmap calls in a
+ * buffer which is then rendered en mass upon a flush, state change, etc.
+ * A wide, short buffer is used to target the common case of a series
+ * of glBitmap calls being used to draw text.
+ */
+static GLboolean UseBitmapCache = GL_TRUE;
+
+
+#define BITMAP_CACHE_WIDTH 512
+#define BITMAP_CACHE_HEIGHT 32
+
+struct bitmap_cache
+{
+ /** Window pos to render the cached image */
+ GLint xpos, ypos;
+ /** Bounds of region used in window coords */
+ GLint xmin, ymin, xmax, ymax;
+ struct pipe_texture *texture;
+ GLboolean empty;
+ /** An I8 texture image: */
+ GLubyte buffer[BITMAP_CACHE_HEIGHT][BITMAP_CACHE_WIDTH];
+};
+
+
+
+
+/**
* Make fragment program for glBitmap:
* Sample the texture and kill the fragment if the bit is 0.
* This program will be combined with the user's fragment program.
@@ -326,7 +353,7 @@ setup_bitmap_vertex_data(struct st_context *st,
const GLboolean invert = (st_fb_orientation(fb) == Y_0_TOP);
const GLfloat x0 = x;
const GLfloat x1 = x + width;
- const GLfloat y0 = invert ? (fb->Height - y - height) : y;
+ const GLfloat y0 = invert ? ((int) fb->Height - y - height) : y;
const GLfloat y1 = invert ? (y0 + height) : y + height;
const GLfloat bias = st->bitmap_texcoord_bias;
const GLfloat xBias = bias / (x1-x0);
@@ -390,16 +417,18 @@ setup_bitmap_vertex_data(struct st_context *st,
static void
draw_bitmap_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z,
GLsizei width, GLsizei height,
- struct pipe_texture *pt,
- struct st_fragment_program *stfp)
+ struct pipe_texture *pt)
{
struct st_context *st = ctx->st;
struct pipe_context *pipe = ctx->st->pipe;
struct cso_context *cso = ctx->st->cso_context;
+ struct st_fragment_program *stfp;
GLuint maxSize;
+ stfp = combined_bitmap_fragment_program(ctx);
+
/* limit checks */
- /* XXX if DrawPixels image is larger than max texture size, break
+ /* XXX if the bitmap is larger than the max texture size, break
* it up into chunks.
*/
maxSize = 1 << (pipe->screen->get_param(pipe->screen, PIPE_CAP_MAX_TEXTURE_2D_LEVELS) - 1);
@@ -466,16 +495,215 @@ draw_bitmap_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z,
}
+static void
+reset_cache(struct st_context *st)
+{
+ memset(st->bitmap.cache->buffer, 0, sizeof(st->bitmap.cache->buffer));
+ st->bitmap.cache->empty = GL_TRUE;
+
+ st->bitmap.cache->xmin = 1000000;
+ st->bitmap.cache->xmax = -1000000;
+ st->bitmap.cache->ymin = 1000000;
+ st->bitmap.cache->ymax = -1000000;
+}
+
static void
+init_bitmap_cache(struct st_context *st)
+{
+ struct pipe_context *pipe = st->pipe;
+ struct pipe_screen *screen = pipe->screen;
+ enum pipe_format format;
+
+ st->bitmap.cache = CALLOC_STRUCT(bitmap_cache);
+ if (!st->bitmap.cache)
+ return;
+
+ /* find a usable texture format */
+ if (screen->is_format_supported(screen, PIPE_FORMAT_U_I8, PIPE_TEXTURE)) {
+ format = PIPE_FORMAT_U_I8;
+ }
+ else {
+ /* XXX support more formats */
+ assert(0);
+ }
+
+ st->bitmap.cache->texture
+ = st_texture_create(st, PIPE_TEXTURE_2D, format, 0,
+ BITMAP_CACHE_WIDTH, BITMAP_CACHE_HEIGHT, 1, 0);
+ if (!st->bitmap.cache->texture) {
+ FREE(st->bitmap.cache);
+ st->bitmap.cache = NULL;
+ return;
+ }
+
+ reset_cache(st);
+}
+
+
+/**
+ * If there's anything in the bitmap cache, draw/flush it now.
+ */
+void
+st_flush_bitmap_cache(struct st_context *st)
+{
+ if (!st->bitmap.cache->empty) {
+ struct bitmap_cache *cache = st->bitmap.cache;
+ struct pipe_context *pipe = st->pipe;
+ struct pipe_screen *screen = pipe->screen;
+ struct pipe_surface *surf;
+ void *dest;
+
+ assert(cache->xmin <= cache->xmax);
+ /*
+ printf("flush size %d x %d at %d, %d\n",
+ cache->xmax - cache->xmin,
+ cache->ymax - cache->ymin,
+ cache->xpos, cache->ypos);
+ */
+
+ /* update the texture map image */
+ surf = screen->get_tex_surface(screen, cache->texture, 0, 0, 0);
+ dest = pipe_surface_map(surf);
+ memcpy(dest, cache->buffer, sizeof(cache->buffer));
+ pipe_surface_unmap(surf);
+ pipe_surface_reference(&surf, NULL);
+
+ pipe->texture_update(pipe, cache->texture, 0, 0x1);
+
+ draw_bitmap_quad(st->ctx,
+ cache->xpos,
+ cache->ypos,
+ st->ctx->Current.RasterPos[2],
+ BITMAP_CACHE_WIDTH, BITMAP_CACHE_HEIGHT,
+ cache->texture);
+
+ reset_cache(st);
+ }
+}
+
+
+/**
+ * Try to accumulate this glBitmap call in the bitmap cache.
+ * \return GL_TRUE for success, GL_FALSE if bitmap is too large, etc.
+ */
+static GLboolean
+accum_bitmap(struct st_context *st,
+ GLint x, GLint y, GLsizei width, GLsizei height,
+ const struct gl_pixelstore_attrib *unpack,
+ const GLubyte *bitmap )
+{
+ struct bitmap_cache *cache = st->bitmap.cache;
+ int row, col;
+ int px = -999, py;
+
+ if (width > BITMAP_CACHE_WIDTH ||
+ height > BITMAP_CACHE_HEIGHT)
+ return GL_FALSE; /* too big to cache */
+
+ if (!cache->empty) {
+ px = x - cache->xpos; /* pos in buffer */
+ py = y - cache->ypos;
+ if (px < 0 || px + width > BITMAP_CACHE_WIDTH ||
+ py < 0 || py + height > BITMAP_CACHE_HEIGHT) {
+ /* This bitmap would extend beyond cache bounds,
+ * so flush and continue.
+ */
+ st_flush_bitmap_cache(st);
+ }
+ }
+
+ if (cache->empty) {
+ /* Initialize. Center bitmap vertically in the buffer. */
+ px = 0;
+ py = (BITMAP_CACHE_HEIGHT - height) / 2;
+ cache->xpos = x;
+ cache->ypos = y - py;
+ cache->empty = GL_FALSE;
+ }
+
+ assert(px != -999);
+
+ if (x < cache->xmin)
+ cache->xmin = x;
+ if (y < cache->ymin)
+ cache->ymin = y;
+ if (x + width > cache->xmax)
+ cache->xmax = x + width;
+ if (y + height > cache->ymax)
+ cache->ymax = y + height;
+
+ /* XXX try to combine this code with code in make_bitmap_texture() */
+#define SET_PIXEL(COL, ROW) \
+ cache->buffer[py + (ROW)][px + (COL)] = 0xff;
+
+ for (row = 0; row < height; row++) {
+ const GLubyte *src = (const GLubyte *) _mesa_image_address2d(unpack,
+ bitmap, width, height, GL_COLOR_INDEX, GL_BITMAP, row, 0);
+
+ if (unpack->LsbFirst) {
+ /* Lsb first */
+ GLubyte mask = 1U << (unpack->SkipPixels & 0x7);
+ for (col = 0; col < width; col++) {
+
+ if (*src & mask) {
+ SET_PIXEL(col, row);
+ }
+
+ if (mask == 128U) {
+ src++;
+ mask = 1U;
+ }
+ else {
+ mask = mask << 1;
+ }
+ }
+
+ /* get ready for next row */
+ if (mask != 1)
+ src++;
+ }
+ else {
+ /* Msb first */
+ GLubyte mask = 128U >> (unpack->SkipPixels & 0x7);
+ for (col = 0; col < width; col++) {
+
+ if (*src & mask) {
+ SET_PIXEL(col, row);
+ }
+
+ if (mask == 1U) {
+ src++;
+ mask = 128U;
+ }
+ else {
+ mask = mask >> 1;
+ }
+ }
+
+ /* get ready for next row */
+ if (mask != 128)
+ src++;
+ }
+
+ } /* row */
+
+ return GL_TRUE; /* accumulated */
+}
+
+
+
+/**
+ * Called via ctx->Driver.Bitmap()
+ */
+static void
st_Bitmap(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height,
const struct gl_pixelstore_attrib *unpack, const GLubyte *bitmap )
{
- struct st_fragment_program *stfp;
struct st_context *st = ctx->st;
struct pipe_texture *pt;
- stfp = combined_bitmap_fragment_program(ctx);
+ st_validate_state(st);
if (!st->bitmap.vs) {
/* create pass-through vertex shader now */
@@ -485,28 +713,40 @@ st_Bitmap(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height,
const uint semantic_indexes[] = { 0, 0, 0 };
st->bitmap.vs = util_make_vertex_passthrough_shader(st->pipe, 3,
semantic_names,
- semantic_indexes);
+ semantic_indexes,
+ &st->bitmap.vert_shader);
}
- st_validate_state(st);
+ if (UseBitmapCache && accum_bitmap(st, x, y, width, height, unpack, bitmap))
+ return;
pt = make_bitmap_texture(ctx, width, height, unpack, bitmap);
if (pt) {
+ assert(pt->target == PIPE_TEXTURE_2D);
draw_bitmap_quad(ctx, x, y, ctx->Current.RasterPos[2],
- width, height,
- pt, stfp);
+ width, height, pt);
pipe_texture_reference(&pt, NULL);
}
}
-
-void st_init_bitmap_functions(struct dd_function_table *functions)
+/** Per-context init */
+void
+st_init_bitmap_functions(struct dd_function_table *functions)
{
functions->Bitmap = st_Bitmap;
}
+/** Per-context init */
+void
+st_init_bitmap(struct st_context *st)
+{
+ init_bitmap_cache(st);
+}
+
+
+/** Per-context tear-down */
void
st_destroy_bitmap(struct st_context *st)
{
@@ -524,9 +764,15 @@ st_destroy_bitmap(struct st_context *st)
pipe->delete_vs_state(pipe, st->bitmap.vs);
st->bitmap.vs = NULL;
}
+
if (st->bitmap.vbuf) {
pipe->winsys->buffer_destroy(pipe->winsys, st->bitmap.vbuf);
st->bitmap.vbuf = NULL;
}
-}
+ if (st->bitmap.cache) {
+ pipe_texture_release(&st->bitmap.cache->texture);
+ FREE(st->bitmap.cache);
+ st->bitmap.cache = NULL;
+ }
+}
diff --git a/src/mesa/state_tracker/st_cb_bitmap.h b/src/mesa/state_tracker/st_cb_bitmap.h
index ac19e0ebb12..aae11d34c92 100644
--- a/src/mesa/state_tracker/st_cb_bitmap.h
+++ b/src/mesa/state_tracker/st_cb_bitmap.h
@@ -33,9 +33,14 @@
extern void
st_init_bitmap_functions(struct dd_function_table *functions);
+extern void
+st_init_bitmap(struct st_context *st);
extern void
st_destroy_bitmap(struct st_context *st);
+extern void
+st_flush_bitmap_cache(struct st_context *st);
+
#endif /* ST_CB_BITMAP_H */
diff --git a/src/mesa/state_tracker/st_cb_clear.c b/src/mesa/state_tracker/st_cb_clear.c
index 5ca15df602a..ec8d3e10221 100644
--- a/src/mesa/state_tracker/st_cb_clear.c
+++ b/src/mesa/state_tracker/st_cb_clear.c
@@ -251,7 +251,7 @@ clear_with_quad(GLcontext *ctx,
/* fragment shader state: color pass-through program */
if (!st->clear.fs) {
- st->clear.fs = util_make_fragment_passthrough_shader(pipe);
+ st->clear.fs = util_make_fragment_passthrough_shader(pipe, &st->clear.frag_shader);
}
pipe->bind_fs_state(pipe, st->clear.fs);
@@ -264,7 +264,8 @@ clear_with_quad(GLcontext *ctx,
const uint semantic_indexes[] = { 0, 0 };
st->clear.vs = util_make_vertex_passthrough_shader(pipe, 2,
semantic_names,
- semantic_indexes);
+ semantic_indexes,
+ &st->clear.vert_shader);
}
pipe->bind_vs_state(pipe, st->clear.vs);
#endif
diff --git a/src/mesa/state_tracker/st_cb_drawpixels.c b/src/mesa/state_tracker/st_cb_drawpixels.c
index 0a2d37c1178..43cc21d1fb4 100644
--- a/src/mesa/state_tracker/st_cb_drawpixels.c
+++ b/src/mesa/state_tracker/st_cb_drawpixels.c
@@ -114,6 +114,12 @@ combined_drawpix_fragment_program(GLcontext *ctx)
_mesa_clone_program(ctx, &st->pixel_xfer.program->Base.Base);
}
else {
+#if 0
+ printf("Base program:\n");
+ _mesa_print_program(&st->fp->Base.Base);
+ printf("DrawPix program:\n");
+ _mesa_print_program(&st->pixel_xfer.program->Base.Base);
+#endif
stfp = (struct st_fragment_program *)
_mesa_combine_programs(ctx,
&st->pixel_xfer.program->Base.Base,
@@ -731,7 +737,7 @@ draw_stencil_pixels(GLcontext *ctx, GLint x, GLint y,
GLint skipPixels;
ubyte *stmap;
- pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE);
+ pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, NULL);
/* map the stencil buffer */
stmap = pipe_surface_map(ps);
@@ -946,7 +952,7 @@ st_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy,
enum pipe_format srcFormat, texFormat;
/* make sure rendering has completed */
- pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE);
+ pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, NULL);
st_validate_state(st);
diff --git a/src/mesa/state_tracker/st_cb_fbo.c b/src/mesa/state_tracker/st_cb_fbo.c
index 5384252a8e5..ec7788923a3 100644
--- a/src/mesa/state_tracker/st_cb_fbo.c
+++ b/src/mesa/state_tracker/st_cb_fbo.c
@@ -366,7 +366,7 @@ st_finish_render_texture(GLcontext *ctx,
assert(strb);
- ctx->st->pipe->flush(ctx->st->pipe, PIPE_FLUSH_RENDER_CACHE);
+ ctx->st->pipe->flush(ctx->st->pipe, PIPE_FLUSH_RENDER_CACHE, NULL);
/*
printf("FINISH RENDER TO TEXTURE surf=%p\n", strb->surface);
diff --git a/src/mesa/state_tracker/st_cb_flush.c b/src/mesa/state_tracker/st_cb_flush.c
index dbec993f1ba..e321b401e2d 100644
--- a/src/mesa/state_tracker/st_cb_flush.c
+++ b/src/mesa/state_tracker/st_cb_flush.c
@@ -35,6 +35,7 @@
#include "main/macros.h"
#include "main/context.h"
#include "st_context.h"
+#include "st_cb_bitmap.h"
#include "st_cb_flush.h"
#include "st_cb_fbo.h"
#include "st_public.h"
@@ -43,19 +44,23 @@
#include "pipe/p_winsys.h"
-void st_flush( struct st_context *st, uint pipeFlushFlags )
+void st_flush( struct st_context *st, uint pipeFlushFlags,
+ struct pipe_fence_handle **fence )
{
FLUSH_VERTICES(st->ctx, 0);
- st->pipe->flush( st->pipe, pipeFlushFlags );
+ st_flush_bitmap_cache(st);
+
+ st->pipe->flush( st->pipe, pipeFlushFlags, fence );
}
-static void st_gl_flush( struct st_context *st, uint pipeFlushFlags )
+static void st_gl_flush( struct st_context *st, uint pipeFlushFlags,
+ struct pipe_fence_handle **fence )
{
GLframebuffer *fb = st->ctx->DrawBuffer;
- FLUSH_VERTICES(st->ctx, 0);
+ st_flush( st, pipeFlushFlags, fence );
if (!fb)
return;
@@ -80,15 +85,6 @@ static void st_gl_flush( struct st_context *st, uint pipeFlushFlags )
= st_renderbuffer(fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer);
struct pipe_surface *front_surf = strb->surface;
- /* If we aren't rendering to the frontbuffer, this is a noop.
- * This should be uncontroversial for glFlush, though people may
- * feel more strongly about glFinish.
- *
- * Additionally, need to make sure that the frontbuffer_dirty
- * flag really gets set on frontbuffer rendering.
- */
- st->pipe->flush( st->pipe, pipeFlushFlags );
-
/* Hook for copying "fake" frontbuffer if necessary:
*/
st->pipe->winsys->flush_frontbuffer( st->pipe->winsys, front_surf,
@@ -103,7 +99,18 @@ static void st_gl_flush( struct st_context *st, uint pipeFlushFlags )
*/
static void st_glFlush(GLcontext *ctx)
{
- st_gl_flush(ctx->st, PIPE_FLUSH_RENDER_CACHE);
+ st_gl_flush(ctx->st, PIPE_FLUSH_RENDER_CACHE, NULL);
+}
+
+
+void st_finish( struct st_context *st )
+{
+ struct pipe_fence_handle *fence;
+
+ st_gl_flush(st, PIPE_FLUSH_RENDER_CACHE, &fence);
+
+ st->pipe->winsys->fence_finish(st->pipe->winsys, fence, 0);
+ st->pipe->winsys->fence_reference(st->pipe->winsys, &fence, NULL);
}
@@ -112,7 +119,7 @@ static void st_glFlush(GLcontext *ctx)
*/
static void st_glFinish(GLcontext *ctx)
{
- st_gl_flush(ctx->st, PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_WAIT);
+ st_finish( ctx->st );
}
diff --git a/src/mesa/state_tracker/st_cb_readpixels.c b/src/mesa/state_tracker/st_cb_readpixels.c
index 4cf9adcd28a..e9fcdf69a14 100644
--- a/src/mesa/state_tracker/st_cb_readpixels.c
+++ b/src/mesa/state_tracker/st_cb_readpixels.c
@@ -160,7 +160,7 @@ st_readpixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height,
return;
/* make sure rendering has completed */
- pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE);
+ pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, NULL);
if (format == GL_STENCIL_INDEX) {
st_read_stencil_pixels(ctx, x, y, width, height, type, pack, dest);
diff --git a/src/mesa/state_tracker/st_context.c b/src/mesa/state_tracker/st_context.c
index 7c183865753..a20195f2dea 100644
--- a/src/mesa/state_tracker/st_context.c
+++ b/src/mesa/state_tracker/st_context.c
@@ -95,12 +95,21 @@ st_create_context_priv( GLcontext *ctx, struct pipe_context *pipe )
st->draw = draw_create(); /* for selection/feedback */
+ /* Disable draw options that might convert points/lines to tris, etc.
+ * as that would foul-up feedback/selection mode.
+ */
+ draw_wide_line_threshold(st->draw, 1000.0f);
+ draw_wide_point_threshold(st->draw, 1000.0f);
+ draw_enable_line_stipple(st->draw, FALSE);
+ draw_enable_point_sprites(st->draw, FALSE);
+
st->dirty.mesa = ~0;
st->dirty.st = ~0;
st->cso_context = cso_create_context(pipe);
st_init_atoms( st );
+ st_init_bitmap(st);
st_init_draw( st );
st_init_generate_mipmap(st);
st_init_blit(st);
diff --git a/src/mesa/state_tracker/st_context.h b/src/mesa/state_tracker/st_context.h
index 2d37086799d..85e3d47e1aa 100644
--- a/src/mesa/state_tracker/st_context.h
+++ b/src/mesa/state_tracker/st_context.h
@@ -42,6 +42,7 @@ struct cso_cache;
struct cso_blend;
struct gen_mipmap_state;
struct blit_state;
+struct bitmap_cache;
#define ST_NEW_MESA 0x1 /* Mesa state has changed */
@@ -147,13 +148,17 @@ struct st_context
struct st_fragment_program *program; /**< bitmap tex/kil program */
GLuint user_prog_sn; /**< user fragment program serial no. */
struct st_fragment_program *combined_prog;
+ struct pipe_shader_state vert_shader;
void *vs;
float vertices[4][3][4]; /**< vertex pos + color + texcoord */
struct pipe_buffer *vbuf;
+ struct bitmap_cache *cache;
} bitmap;
/** for glClear */
struct {
+ struct pipe_shader_state vert_shader;
+ struct pipe_shader_state frag_shader;
void *vs;
void *fs;
float vertices[4][2][4]; /**< vertex pos + color */
diff --git a/src/mesa/state_tracker/st_draw.c b/src/mesa/state_tracker/st_draw.c
index 20af90df7d8..f0f62246ddc 100644
--- a/src/mesa/state_tracker/st_draw.c
+++ b/src/mesa/state_tracker/st_draw.c
@@ -210,6 +210,7 @@ st_draw_vbo(GLcontext *ctx,
const struct pipe_shader_state *vs;
struct pipe_vertex_buffer vbuffer[PIPE_MAX_SHADER_INPUTS];
GLuint attr;
+ struct pipe_vertex_element velements[PIPE_MAX_ATTRIBS];
/* sanity check for pointer arithmetic below */
assert(sizeof(arrays[0]->Ptr[0]) == 1);
@@ -226,7 +227,6 @@ st_draw_vbo(GLcontext *ctx,
for (attr = 0; attr < vp->num_inputs; attr++) {
const GLuint mesaAttr = vp->index_to_input[attr];
struct gl_buffer_object *bufobj = arrays[mesaAttr]->BufferObj;
- struct pipe_vertex_element velement;
if (bufobj && bufobj->Name) {
/* Attribute data is in a VBO.
@@ -239,8 +239,8 @@ st_draw_vbo(GLcontext *ctx,
vbuffer[attr].buffer = NULL;
pipe_buffer_reference(winsys, &vbuffer[attr].buffer, stobj->buffer);
vbuffer[attr].buffer_offset = (unsigned) arrays[0]->Ptr;/* in bytes */
- velement.src_offset = arrays[mesaAttr]->Ptr - arrays[0]->Ptr;
- assert(velement.src_offset <= 2048); /* 11-bit field */
+ velements[attr].src_offset = arrays[mesaAttr]->Ptr - arrays[0]->Ptr;
+ assert(velements[attr].src_offset <= 2048); /* 11-bit field */
}
else {
/* attribute data is in user-space memory, not a VBO */
@@ -259,24 +259,24 @@ st_draw_vbo(GLcontext *ctx,
(void *) arrays[mesaAttr]->Ptr,
bytes);
vbuffer[attr].buffer_offset = 0;
- velement.src_offset = 0;
+ velements[attr].src_offset = 0;
}
/* common-case setup */
vbuffer[attr].pitch = arrays[mesaAttr]->StrideB; /* in bytes */
vbuffer[attr].max_index = max_index;
- velement.vertex_buffer_index = attr;
- velement.nr_components = arrays[mesaAttr]->Size;
- velement.src_format = pipe_vertex_format(arrays[mesaAttr]->Type,
- arrays[mesaAttr]->Size,
- arrays[mesaAttr]->Normalized);
- assert(velement.src_format);
-
- /* tell pipe about this attribute */
- pipe->set_vertex_buffer(pipe, attr, &vbuffer[attr]);
- pipe->set_vertex_element(pipe, attr, &velement);
+ velements[attr].vertex_buffer_index = attr;
+ velements[attr].nr_components = arrays[mesaAttr]->Size;
+ velements[attr].src_format
+ = pipe_vertex_format(arrays[mesaAttr]->Type,
+ arrays[mesaAttr]->Size,
+ arrays[mesaAttr]->Normalized);
+ assert(velements[attr].src_format);
}
+ pipe->set_vertex_buffers(pipe, vp->num_inputs, vbuffer);
+ pipe->set_vertex_elements(pipe, vp->num_inputs, velements);
+
/* do actual drawing */
if (ib) {
@@ -336,8 +336,8 @@ st_draw_vbo(GLcontext *ctx,
for (attr = 0; attr < vp->num_inputs; attr++) {
pipe_buffer_reference(winsys, &vbuffer[attr].buffer, NULL);
assert(!vbuffer[attr].buffer);
- pipe->set_vertex_buffer(pipe, attr, &vbuffer[attr]);
}
+ pipe->set_vertex_buffers(pipe, vp->num_inputs, vbuffer);
}
@@ -362,7 +362,7 @@ st_draw_vertices(GLcontext *ctx, unsigned prim,
struct pipe_context *pipe = ctx->st->pipe;
struct pipe_buffer *vbuf;
struct pipe_vertex_buffer vbuffer;
- struct pipe_vertex_element velement;
+ struct pipe_vertex_element velements[PIPE_MAX_ATTRIBS];
unsigned i;
assert(numAttribs > 0);
@@ -393,16 +393,16 @@ st_draw_vertices(GLcontext *ctx, unsigned prim,
vbuffer.buffer = vbuf;
vbuffer.pitch = numAttribs * 4 * sizeof(float); /* vertex size */
vbuffer.buffer_offset = 0;
- pipe->set_vertex_buffer(pipe, 0, &vbuffer);
+ pipe->set_vertex_buffers(pipe, 1, &vbuffer);
/* tell pipe about the vertex attributes */
for (i = 0; i < numAttribs; i++) {
- velement.src_offset = i * 4 * sizeof(GLfloat);
- velement.vertex_buffer_index = 0;
- velement.src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
- velement.nr_components = 4;
- pipe->set_vertex_element(pipe, i, &velement);
+ velements[i].src_offset = i * 4 * sizeof(GLfloat);
+ velements[i].vertex_buffer_index = 0;
+ velements[i].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
+ velements[i].nr_components = 4;
}
+ pipe->set_vertex_elements(pipe, numAttribs, velements);
/* draw */
pipe->draw_arrays(pipe, prim, 0, numVertex);
@@ -470,7 +470,8 @@ st_feedback_draw_vbo(GLcontext *ctx,
const struct st_vertex_program *vp;
const struct pipe_shader_state *vs;
struct pipe_buffer *index_buffer_handle = 0;
- struct pipe_vertex_buffer vbuffer[PIPE_MAX_SHADER_INPUTS];
+ struct pipe_vertex_buffer vbuffers[PIPE_MAX_SHADER_INPUTS];
+ struct pipe_vertex_element velements[PIPE_MAX_ATTRIBS];
GLuint attr, i;
ubyte *mapped_constants;
@@ -505,7 +506,6 @@ st_feedback_draw_vbo(GLcontext *ctx,
for (attr = 0; attr < vp->num_inputs; attr++) {
const GLuint mesaAttr = vp->index_to_input[attr];
struct gl_buffer_object *bufobj = arrays[mesaAttr]->BufferObj;
- struct pipe_vertex_element velement;
void *map;
if (bufobj && bufobj->Name) {
@@ -516,10 +516,10 @@ st_feedback_draw_vbo(GLcontext *ctx,
struct st_buffer_object *stobj = st_buffer_object(bufobj);
assert(stobj->buffer);
- vbuffer[attr].buffer = NULL;
- pipe_buffer_reference(winsys, &vbuffer[attr].buffer, stobj->buffer);
- vbuffer[attr].buffer_offset = (unsigned) arrays[0]->Ptr;/* in bytes */
- velement.src_offset = arrays[mesaAttr]->Ptr - arrays[0]->Ptr;
+ vbuffers[attr].buffer = NULL;
+ pipe_buffer_reference(winsys, &vbuffers[attr].buffer, stobj->buffer);
+ vbuffers[attr].buffer_offset = (unsigned) arrays[0]->Ptr;/* in bytes */
+ velements[attr].src_offset = arrays[mesaAttr]->Ptr - arrays[0]->Ptr;
}
else {
/* attribute data is in user-space memory, not a VBO */
@@ -528,35 +528,39 @@ st_feedback_draw_vbo(GLcontext *ctx,
* (max_index + 1));
/* wrap user data */
- vbuffer[attr].buffer
+ vbuffers[attr].buffer
= winsys->user_buffer_create(winsys,
(void *) arrays[mesaAttr]->Ptr,
bytes);
- vbuffer[attr].buffer_offset = 0;
- velement.src_offset = 0;
+ vbuffers[attr].buffer_offset = 0;
+ velements[attr].src_offset = 0;
}
/* common-case setup */
- vbuffer[attr].pitch = arrays[mesaAttr]->StrideB; /* in bytes */
- vbuffer[attr].max_index = max_index;
- velement.vertex_buffer_index = attr;
- velement.nr_components = arrays[mesaAttr]->Size;
- velement.src_format = pipe_vertex_format(arrays[mesaAttr]->Type,
+ vbuffers[attr].pitch = arrays[mesaAttr]->StrideB; /* in bytes */
+ vbuffers[attr].max_index = max_index;
+ velements[attr].vertex_buffer_index = attr;
+ velements[attr].nr_components = arrays[mesaAttr]->Size;
+ velements[attr].src_format = pipe_vertex_format(arrays[mesaAttr]->Type,
arrays[mesaAttr]->Size,
arrays[mesaAttr]->Normalized);
- assert(velement.src_format);
+ assert(velements[attr].src_format);
/* tell draw about this attribute */
+#if 0
draw_set_vertex_buffer(draw, attr, &vbuffer[attr]);
- draw_set_vertex_element(draw, attr, &velement);
+#endif
/* map the attrib buffer */
map = pipe->winsys->buffer_map(pipe->winsys,
- vbuffer[attr].buffer,
+ vbuffers[attr].buffer,
PIPE_BUFFER_USAGE_CPU_READ);
draw_set_mapped_vertex_buffer(draw, attr, map);
}
+ draw_set_vertex_buffers(draw, vp->num_inputs, vbuffers);
+ draw_set_vertex_elements(draw, vp->num_inputs, velements);
+
if (ib) {
unsigned indexSize;
struct gl_buffer_object *bufobj = ib->obj;
@@ -606,7 +610,7 @@ st_feedback_draw_vbo(GLcontext *ctx,
/*
* unmap vertex/index buffers
*/
- for (i = 0; i < PIPE_ATTRIB_MAX; i++) {
+ for (i = 0; i < PIPE_MAX_ATTRIBS; i++) {
if (draw->vertex_buffer[i].buffer) {
pipe->winsys->buffer_unmap(pipe->winsys,
draw->vertex_buffer[i].buffer);
diff --git a/src/mesa/state_tracker/st_format.c b/src/mesa/state_tracker/st_format.c
index 9aeda65a5c8..cb6fa9a573d 100644
--- a/src/mesa/state_tracker/st_format.c
+++ b/src/mesa/state_tracker/st_format.c
@@ -271,6 +271,10 @@ st_mesa_format_to_pipe_format(GLuint mesaFormat)
return PIPE_FORMAT_U_I8;
case MESA_FORMAT_Z16:
return PIPE_FORMAT_Z16_UNORM;
+ case MESA_FORMAT_Z32:
+ return PIPE_FORMAT_Z32_UNORM;
+ case MESA_FORMAT_Z24_S8:
+ return PIPE_FORMAT_Z24S8_UNORM;
default:
assert(0);
return 0;
@@ -281,7 +285,7 @@ st_mesa_format_to_pipe_format(GLuint mesaFormat)
* Find an RGBA format supported by the context/winsys.
*/
static GLuint
-default_rgba_format(struct pipe_context *pipe, uint type)
+default_rgba_format(struct pipe_screen *screen, uint type)
{
static const enum pipe_format colorFormats[] = {
PIPE_FORMAT_A8R8G8B8_UNORM,
@@ -289,7 +293,6 @@ default_rgba_format(struct pipe_context *pipe, uint type)
PIPE_FORMAT_R8G8B8A8_UNORM,
PIPE_FORMAT_R5G6B5_UNORM
};
- struct pipe_screen *screen = pipe->screen;
uint i;
for (i = 0; i < Elements(colorFormats); i++) {
if (screen->is_format_supported( screen, colorFormats[i], type )) {
@@ -304,9 +307,8 @@ default_rgba_format(struct pipe_context *pipe, uint type)
* Search list of formats for first RGBA format with >8 bits/channel.
*/
static GLuint
-default_deep_rgba_format(struct pipe_context *pipe, uint type)
+default_deep_rgba_format(struct pipe_screen *screen, uint type)
{
- struct pipe_screen *screen = pipe->screen;
if (screen->is_format_supported(screen, PIPE_FORMAT_R16G16B16A16_SNORM, type)) {
return PIPE_FORMAT_R16G16B16A16_SNORM;
}
@@ -318,7 +320,7 @@ default_deep_rgba_format(struct pipe_context *pipe, uint type)
* Find an Z format supported by the context/winsys.
*/
static GLuint
-default_depth_format(struct pipe_context *pipe, uint type)
+default_depth_format(struct pipe_screen *screen, uint type)
{
static const enum pipe_format zFormats[] = {
PIPE_FORMAT_Z16_UNORM,
@@ -326,7 +328,6 @@ default_depth_format(struct pipe_context *pipe, uint type)
PIPE_FORMAT_S8Z24_UNORM,
PIPE_FORMAT_Z24S8_UNORM
};
- struct pipe_screen *screen = pipe->screen;
uint i;
for (i = 0; i < Elements(zFormats); i++) {
if (screen->is_format_supported( screen, zFormats[i], type )) {
@@ -338,15 +339,16 @@ default_depth_format(struct pipe_context *pipe, uint type)
/**
- * Choose the PIPE_FORMAT_ to use for user-created renderbuffers.
- *
- * \return PIPE_FORMAT_NONE if error/problem.
+ * Given an OpenGL internalFormat value for a texture or surface, return
+ * the best matching PIPE_FORMAT_x, or PIPE_FORMAT_NONE if there's no match.
*/
-enum pipe_format
-st_choose_renderbuffer_format(struct pipe_context *pipe, GLint internalFormat)
+static enum pipe_format
+choose_format(struct pipe_context *pipe, GLint internalFormat, uint surfType)
{
struct pipe_screen *screen = pipe->screen;
- uint surfType = PIPE_SURFACE;
+
+ assert(surfType == PIPE_SURFACE ||
+ surfType == PIPE_TEXTURE);
switch (internalFormat) {
case 4:
@@ -358,26 +360,26 @@ st_choose_renderbuffer_format(struct pipe_context *pipe, GLint internalFormat)
case GL_RGBA8:
case GL_RGB10_A2:
case GL_RGBA12:
- return default_rgba_format( pipe, surfType );
+ return default_rgba_format( screen, surfType );
case GL_RGBA16:
- return default_deep_rgba_format( pipe, surfType );
+ return default_deep_rgba_format( screen, surfType );
case GL_RGBA4:
case GL_RGBA2:
if (screen->is_format_supported( screen, PIPE_FORMAT_A4R4G4B4_UNORM, surfType ))
return PIPE_FORMAT_A4R4G4B4_UNORM;
- return default_rgba_format( pipe, surfType );
+ return default_rgba_format( screen, surfType );
case GL_RGB5_A1:
if (screen->is_format_supported( screen, PIPE_FORMAT_A1R5G5B5_UNORM, surfType ))
return PIPE_FORMAT_A1R5G5B5_UNORM;
- return default_rgba_format( pipe, surfType );
+ return default_rgba_format( screen, surfType );
case GL_RGB8:
case GL_RGB10:
case GL_RGB12:
case GL_RGB16:
- return default_rgba_format( pipe, surfType );
+ return default_rgba_format( screen, surfType );
case GL_RGB5:
case GL_RGB4:
@@ -386,7 +388,7 @@ st_choose_renderbuffer_format(struct pipe_context *pipe, GLint internalFormat)
return PIPE_FORMAT_A1R5G5B5_UNORM;
if (screen->is_format_supported( screen, PIPE_FORMAT_R5G6B5_UNORM, surfType ))
return PIPE_FORMAT_R5G6B5_UNORM;
- return default_rgba_format( pipe, surfType );
+ return default_rgba_format( screen, surfType );
case GL_ALPHA:
case GL_ALPHA4:
@@ -396,7 +398,7 @@ st_choose_renderbuffer_format(struct pipe_context *pipe, GLint internalFormat)
case GL_COMPRESSED_ALPHA:
if (screen->is_format_supported( screen, PIPE_FORMAT_U_A8, surfType ))
return PIPE_FORMAT_U_A8;
- return default_rgba_format( pipe, surfType );
+ return default_rgba_format( screen, surfType );
case 1:
case GL_LUMINANCE:
@@ -406,8 +408,8 @@ st_choose_renderbuffer_format(struct pipe_context *pipe, GLint internalFormat)
case GL_LUMINANCE16:
case GL_COMPRESSED_LUMINANCE:
if (screen->is_format_supported( screen, PIPE_FORMAT_U_L8, surfType ))
- return PIPE_FORMAT_U_A8;
- return default_rgba_format( pipe, surfType );
+ return PIPE_FORMAT_U_L8;
+ return default_rgba_format( screen, surfType );
case 2:
case GL_LUMINANCE_ALPHA:
@@ -420,7 +422,7 @@ st_choose_renderbuffer_format(struct pipe_context *pipe, GLint internalFormat)
case GL_COMPRESSED_LUMINANCE_ALPHA:
if (screen->is_format_supported( screen, PIPE_FORMAT_U_A8_L8, surfType ))
return PIPE_FORMAT_U_A8_L8;
- return default_rgba_format( pipe, surfType );
+ return default_rgba_format( screen, surfType );
case GL_INTENSITY:
case GL_INTENSITY4:
@@ -430,32 +432,32 @@ st_choose_renderbuffer_format(struct pipe_context *pipe, GLint internalFormat)
case GL_COMPRESSED_INTENSITY:
if (screen->is_format_supported( screen, PIPE_FORMAT_U_I8, surfType ))
return PIPE_FORMAT_U_I8;
- return default_rgba_format( pipe, surfType );
+ return default_rgba_format( screen, surfType );
-#if 0
- /* not supported for renderbuffers */
case GL_YCBCR_MESA:
return PIPE_FORMAT_NONE;
- case GL_COMPRESSED_RGB_FXT1_3DFX:
- return &_mesa_texformat_rgb_fxt1;
- case GL_COMPRESSED_RGBA_FXT1_3DFX:
- return &_mesa_texformat_rgba_fxt1;
case GL_RGB_S3TC:
case GL_RGB4_S3TC:
case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
- return &_mesa_texformat_rgb_dxt1;
+ return PIPE_FORMAT_DXT1_RGB;
case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
- return &_mesa_texformat_rgba_dxt1;
+ return PIPE_FORMAT_DXT1_RGBA;
case GL_RGBA_S3TC:
case GL_RGBA4_S3TC:
case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
- return &_mesa_texformat_rgba_dxt3;
+ return PIPE_FORMAT_DXT3_RGBA;
case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
- return &_mesa_texformat_rgba_dxt5;
+ return PIPE_FORMAT_DXT5_RGBA;
+
+#if 0
+ case GL_COMPRESSED_RGB_FXT1_3DFX:
+ return PIPE_FORMAT_RGB_FXT1;
+ case GL_COMPRESSED_RGBA_FXT1_3DFX:
+ return PIPE_FORMAT_RGB_FXT1;
#endif
case GL_DEPTH_COMPONENT16:
@@ -473,7 +475,7 @@ st_choose_renderbuffer_format(struct pipe_context *pipe, GLint internalFormat)
return PIPE_FORMAT_Z32_UNORM;
/* fall-through */
case GL_DEPTH_COMPONENT:
- return default_depth_format( pipe, surfType );
+ return default_depth_format( screen, surfType );
case GL_STENCIL_INDEX:
case GL_STENCIL_INDEX1_EXT:
@@ -502,155 +504,79 @@ st_choose_renderbuffer_format(struct pipe_context *pipe, GLint internalFormat)
}
-
-/* It works out that this function is fine for all the supported
- * hardware. However, there is still a need to map the formats onto
- * hardware descriptors.
- */
-/* Note that the i915 can actually support many more formats than
- * these if we take the step of simply swizzling the colors
- * immediately after sampling...
+/**
+ * Called by FBO code to choose a PIPE_FORMAT_ for drawing surfaces.
*/
-const struct gl_texture_format *
-st_ChooseTextureFormat(GLcontext * ctx, GLint internalFormat,
- GLenum format, GLenum type)
+enum pipe_format
+st_choose_renderbuffer_format(struct pipe_context *pipe, GLint internalFormat)
{
-#if 0
- struct intel_context *intel = intel_context(ctx);
- const GLboolean do32bpt = (intel->intelScreen->front.cpp == 4);
-#else
- const GLboolean do32bpt = 1;
-#endif
-
- (void) ctx;
-
- switch (internalFormat) {
- case 4:
- case GL_RGBA:
- case GL_COMPRESSED_RGBA:
- if (format == GL_BGRA) {
- if (type == GL_UNSIGNED_BYTE || type == GL_UNSIGNED_INT_8_8_8_8_REV) {
- return &_mesa_texformat_argb8888;
- }
- else if (type == GL_UNSIGNED_SHORT_4_4_4_4_REV) {
- return &_mesa_texformat_argb4444;
- }
- else if (type == GL_UNSIGNED_SHORT_1_5_5_5_REV) {
- return &_mesa_texformat_argb1555;
- }
- }
- return do32bpt ? &_mesa_texformat_argb8888 : &_mesa_texformat_argb4444;
-
- case 3:
- case GL_RGB:
- case GL_COMPRESSED_RGB:
- if (format == GL_RGB && type == GL_UNSIGNED_SHORT_5_6_5) {
- return &_mesa_texformat_rgb565;
- }
- return do32bpt ? &_mesa_texformat_argb8888 : &_mesa_texformat_rgb565;
-
- case GL_RGBA8:
- case GL_RGB10_A2:
- case GL_RGBA12:
- case GL_RGBA16:
- return do32bpt ? &_mesa_texformat_argb8888 : &_mesa_texformat_argb4444;
+ return choose_format(pipe, internalFormat, PIPE_SURFACE);
+}
- case GL_RGBA4:
- case GL_RGBA2:
- return &_mesa_texformat_argb4444;
- case GL_RGB5_A1:
- return &_mesa_texformat_argb1555;
-
- case GL_RGB8:
- case GL_RGB10:
- case GL_RGB12:
- case GL_RGB16:
+static const struct gl_texture_format *
+translate_gallium_format_to_mesa_format(enum pipe_format format)
+{
+ switch (format) {
+ case PIPE_FORMAT_A8R8G8B8_UNORM:
return &_mesa_texformat_argb8888;
-
- case GL_RGB5:
- case GL_RGB4:
- case GL_R3_G3_B2:
+ case PIPE_FORMAT_A1R5G5B5_UNORM:
+ return &_mesa_texformat_argb1555;
+ case PIPE_FORMAT_A4R4G4B4_UNORM:
+ return &_mesa_texformat_argb4444;
+ case PIPE_FORMAT_R5G6B5_UNORM:
return &_mesa_texformat_rgb565;
-
- case GL_ALPHA:
- case GL_ALPHA4:
- case GL_ALPHA8:
- case GL_ALPHA12:
- case GL_ALPHA16:
- case GL_COMPRESSED_ALPHA:
+ case PIPE_FORMAT_U_A8_L8:
+ return &_mesa_texformat_al88;
+ case PIPE_FORMAT_U_A8:
return &_mesa_texformat_a8;
-
- case 1:
- case GL_LUMINANCE:
- case GL_LUMINANCE4:
- case GL_LUMINANCE8:
- case GL_LUMINANCE12:
- case GL_LUMINANCE16:
- case GL_COMPRESSED_LUMINANCE:
+ case PIPE_FORMAT_U_L8:
return &_mesa_texformat_l8;
-
- case 2:
- case GL_LUMINANCE_ALPHA:
- case GL_LUMINANCE4_ALPHA4:
- case GL_LUMINANCE6_ALPHA2:
- case GL_LUMINANCE8_ALPHA8:
- case GL_LUMINANCE12_ALPHA4:
- case GL_LUMINANCE12_ALPHA12:
- case GL_LUMINANCE16_ALPHA16:
- case GL_COMPRESSED_LUMINANCE_ALPHA:
- return &_mesa_texformat_al88;
-
- case GL_INTENSITY:
- case GL_INTENSITY4:
- case GL_INTENSITY8:
- case GL_INTENSITY12:
- case GL_INTENSITY16:
- case GL_COMPRESSED_INTENSITY:
+ case PIPE_FORMAT_U_I8:
return &_mesa_texformat_i8;
-
- case GL_YCBCR_MESA:
- if (type == GL_UNSIGNED_SHORT_8_8_MESA || type == GL_UNSIGNED_BYTE)
- return &_mesa_texformat_ycbcr;
- else
- return &_mesa_texformat_ycbcr_rev;
-
- case GL_COMPRESSED_RGB_FXT1_3DFX:
- return &_mesa_texformat_rgb_fxt1;
- case GL_COMPRESSED_RGBA_FXT1_3DFX:
- return &_mesa_texformat_rgba_fxt1;
-
- case GL_RGB_S3TC:
- case GL_RGB4_S3TC:
- case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
+ case PIPE_FORMAT_Z16_UNORM:
+ return &_mesa_texformat_z16;
+ case PIPE_FORMAT_Z32_UNORM:
+ return &_mesa_texformat_z32;
+ case PIPE_FORMAT_S8Z24_UNORM:
+ /* XXX fallthrough OK? */
+ case PIPE_FORMAT_Z24S8_UNORM:
+ return &_mesa_texformat_z24_s8;
+ case PIPE_FORMAT_YCBCR:
+ return &_mesa_texformat_ycbcr;
+ case PIPE_FORMAT_YCBCR_REV:
+ return &_mesa_texformat_ycbcr_rev;
+ case PIPE_FORMAT_DXT1_RGB:
return &_mesa_texformat_rgb_dxt1;
-
- case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
+ case PIPE_FORMAT_DXT1_RGBA:
return &_mesa_texformat_rgba_dxt1;
-
- case GL_RGBA_S3TC:
- case GL_RGBA4_S3TC:
- case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
+ case PIPE_FORMAT_DXT3_RGBA:
return &_mesa_texformat_rgba_dxt3;
-
- case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
+ case PIPE_FORMAT_DXT5_RGBA:
return &_mesa_texformat_rgba_dxt5;
+ /* XXX add additional cases */
+ default:
+ assert(0);
+ return NULL;
+ }
+}
- case GL_DEPTH_COMPONENT:
- case GL_DEPTH_COMPONENT16:
- case GL_DEPTH_COMPONENT24:
- case GL_DEPTH_COMPONENT32:
- return &_mesa_texformat_z16;
- case GL_DEPTH_STENCIL_EXT:
- case GL_DEPTH24_STENCIL8_EXT:
- return &_mesa_texformat_z24_s8;
+/**
+ * Called via ctx->Driver.chooseTextureFormat().
+ */
+const struct gl_texture_format *
+st_ChooseTextureFormat(GLcontext *ctx, GLint internalFormat,
+ GLenum format, GLenum type)
+{
+ enum pipe_format pFormat;
- default:
- fprintf(stderr, "unexpected texture format %s in %s\n",
- _mesa_lookup_enum_by_nr(internalFormat), __FUNCTION__);
+ (void) format;
+ (void) type;
+
+ pFormat = choose_format(ctx->st->pipe, internalFormat, PIPE_TEXTURE);
+ if (pFormat == PIPE_FORMAT_NONE)
return NULL;
- }
- return NULL; /* never get here */
+ return translate_gallium_format_to_mesa_format(pFormat);
}
diff --git a/src/mesa/state_tracker/st_framebuffer.c b/src/mesa/state_tracker/st_framebuffer.c
index d46a9178b19..075e9d1bd68 100644
--- a/src/mesa/state_tracker/st_framebuffer.c
+++ b/src/mesa/state_tracker/st_framebuffer.c
@@ -186,7 +186,8 @@ st_notify_swapbuffers(struct st_framebuffer *stfb)
if (ctx && ctx->DrawBuffer == &stfb->Base) {
st_flush( ctx->st,
- PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_SWAPBUFFERS);
+ PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_SWAPBUFFERS,
+ NULL );
}
}
diff --git a/src/mesa/state_tracker/st_public.h b/src/mesa/state_tracker/st_public.h
index 3c397b126a9..9d88ce9764d 100644
--- a/src/mesa/state_tracker/st_public.h
+++ b/src/mesa/state_tracker/st_public.h
@@ -45,6 +45,7 @@
struct st_context;
struct st_framebuffer;
struct pipe_context;
+struct pipe_fence_handle;
struct pipe_surface;
@@ -78,7 +79,9 @@ void st_make_current(struct st_context *st,
struct st_framebuffer *draw,
struct st_framebuffer *read);
-void st_flush( struct st_context *st, uint pipeFlushFlags );
+void st_flush( struct st_context *st, uint pipeFlushFlags,
+ struct pipe_fence_handle **fence );
+void st_finish( struct st_context *st );
void st_notify_swapbuffers(struct st_framebuffer *stfb);
void st_notify_swapbuffers_complete(struct st_framebuffer *stfb);
diff --git a/src/mesa/state_tracker/st_texture.c b/src/mesa/state_tracker/st_texture.c
index cbc6f849982..8e3235cc99d 100644
--- a/src/mesa/state_tracker/st_texture.c
+++ b/src/mesa/state_tracker/st_texture.c
@@ -30,6 +30,8 @@
#include "st_texture.h"
#include "enums.h"
+#undef Elements /* fix re-defined macro warning */
+
#include "pipe/p_state.h"
#include "pipe/p_context.h"
#include "pipe/p_defines.h"