Merge remote branch 'upstream/gallium-0.1' into nouveau-gallium-0.1

This commit is contained in:
Ben Skeggs 2008-03-30 19:58:03 +10:00
commit 03c60e0fb6
110 changed files with 2040 additions and 1043 deletions

View file

@ -19,7 +19,9 @@ OPT_FLAGS = -g
SDK = /opt/ibm/cell-sdk/prototype/sysroot/usr
CFLAGS = $(OPT_FLAGS) -Wall -Winline -fPIC -m32 -mabi=altivec -maltivec -I. -I$(SDK)/include -DGALLIUM_CELL
CFLAGS = $(OPT_FLAGS) -Wall -Winline -fPIC -m32 -mabi=altivec -maltivec \
-I. -I$(SDK)/include \
-DGALLIUM_CELL -DUSE_XSHM
CXXFLAGS = $(CFLAGS)

View file

@ -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)
@ -163,6 +169,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.
@ -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;
aaline->tex_slot = draw->num_vs_outputs;
assert(aaline->tex_slot > 0); /* output[0] is vertex pos */
draw->extra_vp_outputs.slot = aaline->tex_slot;
/*
* Bind our fragprog, sampler and texture
* Bind (generate) our fragprog, sampler and texture
*/
bind_aaline_fragment_shader(aaline);
aaline->state.sampler[num] = aaline->sampler_cso;
pipe_texture_reference(&aaline->state.texture[num], aaline->texture);
/* update vertex attrib info */
aaline->tex_slot = draw->num_vs_outputs;
assert(aaline->tex_slot > 0); /* output[0] is vertex pos */
aaline->driver_bind_sampler_states(pipe, num + 1, aaline->state.sampler);
aaline->driver_set_sampler_textures(pipe, num + 1, aaline->state.texture);
/* 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;
/* 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[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_samplers, aaline->state.sampler);
aaline->driver_set_sampler_textures(pipe, num_samplers, aaline->state.texture);
/* now really draw first line */
stage->line = aaline_line;

View file

@ -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) {

View file

@ -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]));
}

View file

@ -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 );

View file

@ -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__);

View file

@ -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;

View file

@ -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):

View file

@ -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);
@ -159,6 +163,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.
@ -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);
}

View file

@ -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;

View file

@ -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;

View file

@ -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;
}

View file

@ -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;
/* 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;
/* wide lines */
if (draw->rasterizer->line_width > draw->wide_line_threshold)
return TRUE;
/* wide lines */
if (draw->rasterizer->line_width > draw->wide_line_threshold)
return TRUE;
/* large points */
if (draw->rasterizer->point_size > draw->wide_point_threshold)
return TRUE;
/* AA lines */
if (draw->rasterizer->line_smooth && draw->pipeline.aaline)
return TRUE;
}
/* AA lines */
if (draw->rasterizer->line_smooth && draw->pipeline.aaline)
return TRUE;
if (points(prim))
{
/* large points */
if (draw->rasterizer->point_size > draw->wide_point_threshold)
return TRUE;
/* AA points */
if (draw->rasterizer->point_smooth && draw->pipeline.aapoint)
return TRUE;
/* AA points */
if (draw->rasterizer->point_smooth && draw->pipeline.aapoint)
return TRUE;
/* polygon stipple */
if (draw->rasterizer->poly_stipple_enable && draw->pipeline.pstipple)
return TRUE;
/* point sprites */
if (draw->rasterizer->point_sprite && draw->point_sprite)
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;
if (triangles(prim))
{
/* polygon stipple */
if (draw->rasterizer->poly_stipple_enable && draw->pipeline.pstipple)
return TRUE;
/* point sprites */
if (draw->rasterizer->point_sprite && draw->point_sprite)
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;
/* 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.

View file

@ -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;
}
}

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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) \

View file

@ -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);

View file

@ -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;
}

View file

@ -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);

View file

@ -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);

View file

@ -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));

View file

@ -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);
}

View file

@ -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

View file

@ -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:
/*

View file

@ -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
*/

View file

@ -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;

View file

@ -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];
};

View file

@ -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);

View file

@ -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]);

View file

@ -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);

View file

@ -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 );

View file

@ -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;

View file

@ -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
}

View file

@ -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 */

View file

@ -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);
}

View file

@ -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
}

View file

@ -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;

View file

@ -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;

View file

@ -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);

View file

@ -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];

View file

@ -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;

View file

@ -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 )
}
/* 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.
/* Convert fragment 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]),
qword soa_frag[4];
_transpose_matrix4x4((vec_float4 *) soa_frag, colors);
/* Read the current framebuffer values.
*/
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]),
};
const struct spu_blend_results result =
_transpose_matrix4x4((vec_float4 *) soa_pix, aos_pix);
}
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);
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_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);
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
}

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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)

View file

@ -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);

View file

@ -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);

View file

@ -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;

View file

@ -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);
}

View file

@ -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:
*/

View file

@ -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:
*/

View file

@ -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;
}

View file

@ -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));
}

View file

@ -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

View file

@ -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)

View file

@ -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)

View file

@ -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 );
}

View file

@ -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;
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;
}
brw->vb.inputs[index] = 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;
}

View file

@ -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)

View file

@ -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

View file

@ -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;

View file

@ -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];

View file

@ -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);

View file

@ -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;
}

View file

@ -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

View file

@ -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
}

View file

@ -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);

View file

@ -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 );

View file

@ -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);
}

View file

@ -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 * );
/* Currently a sampler is constrained to sample from a single texture:
*/
void (*set_sampler_textures)( struct pipe_context *,
unsigned num,
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_sampler_textures)( struct pipe_context *,
unsigned num_textures,
struct pipe_texture ** );
void (*set_vertex_element)( struct pipe_context *,
unsigned index,
const struct pipe_vertex_element * );
void (*set_vertex_buffers)( struct pipe_context *,
unsigned num_buffers,
const struct pipe_vertex_buffer * );
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 );
};

View file

@ -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

View file

@ -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
/**

View file

@ -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]? */

View file

@ -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

View file

@ -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;
}

View file

@ -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,22 +114,25 @@ 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;
fu.dri = intel_batchbuffer_flush( intel->batch );
if (fu.dri)
iws->pws->fence_reference(iws->pws, fence, fu.pipe);
intel_batchbuffer_flush( intel->batch );
// if (0) intel_i915_batch_wait_idle( sws );
}
static void intel_i915_batch_finish( struct i915_winsys *sws )
{
struct intel_context *intel = intel_i915_winsys(sws)->intel;
intel_batchbuffer_finish( intel->batch );
}
/**
* Create i915 hardware rendering context.
*/
@ -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);

View file

@ -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;

View file

@ -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->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->surface_alloc = xm_surface_alloc;
ws->surface_alloc_storage = xm_surface_alloc_storage;
ws->surface_release = xm_surface_release;
ws->base.surface_alloc = xm_surface_alloc;
ws->base.surface_alloc_storage = xm_surface_alloc_storage;
ws->base.surface_release = xm_surface_release;
ws->flush_frontbuffer = xm_flush_frontbuffer;
ws->printf = xm_printf;
ws->get_name = xm_get_name;
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;
}

View file

@ -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

View file

@ -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

View file

@ -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 {

View file

@ -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,26 +2611,61 @@ 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.
* Parse vertex/fragment program scalar source register.
*/
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)
{
enum register_file file;
GLint index;
GLubyte negateMask;
GLubyte swizzle[4];
GLboolean isRelOffset;
/* 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 = index;
reg->Swizzle = (swizzle[0] << 0);
reg->NegateBase = negateMask;
reg->RelAddr = isRelOffset;
return 0;
}
/**
* Parse vertex/fragment program destination register.
* \return 1 if error, 0 if no error.
*/
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 )
parse_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))
if (parse_masked_dst_reg (ctx, inst, vc_head, program, &file, &idx, &mask))
return 1;
reg->File = file;
@ -2618,41 +2675,6 @@ parse_fp_dst_reg(GLcontext * ctx, const GLubyte ** inst,
}
/**
* Parse fragment program scalar src 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 )
{
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->NegateBase = Negate;
reg->Swizzle = (Swizzle[0] << 0);
return 0;
}
/**
* This is a big mother that handles getting opcodes into the instruction
* and handling the src & dst registers for fragment program instructions
@ -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;
}

View file

@ -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

View file

@ -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;

View file

@ -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)

View file

@ -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) {

View file

@ -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);

View file

@ -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:

View file

@ -59,6 +59,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.
@ -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;
}
}

View file

@ -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 */

View file

@ -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

View file

@ -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);

Some files were not shown because too many files have changed in this diff Show more