mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-05 05:18:08 +02:00
Merge remote branch 'upstream/gallium-0.1' into nouveau-gallium-0.1
This commit is contained in:
commit
03c60e0fb6
110 changed files with 2040 additions and 1043 deletions
|
|
@ -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)
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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]));
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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 );
|
||||
|
|
|
|||
|
|
@ -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__);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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):
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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) \
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -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
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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];
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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]);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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 );
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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];
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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 );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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];
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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 );
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 );
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -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]? */
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
Loading…
Add table
Reference in a new issue