Merge commit 'origin/master' into gallium-0.2
[mesa.git] / src / gallium / auxiliary / draw / draw_pipe_aapoint.c
index e84d380e500de01bbe2a2c5a9983bb244937919f..2c1cacbdb4768de78351abdaadc1307fd7a6cd36 100644 (file)
  */
 
 
-#include "pipe/p_util.h"
 #include "pipe/p_inlines.h"
 #include "pipe/p_context.h"
 #include "pipe/p_defines.h"
 #include "pipe/p_shader_tokens.h"
 
-#include "tgsi/util/tgsi_transform.h"
-#include "tgsi/util/tgsi_dump.h"
+#include "tgsi/tgsi_transform.h"
+#include "tgsi/tgsi_dump.h"
+
+#include "util/u_math.h"
+#include "util/u_memory.h"
 
 #include "draw_context.h"
 #include "draw_vs.h"
+#include "draw_pipe.h"
 
 
 /*
@@ -84,6 +87,7 @@ struct aapoint_stage
 
    /** this is the vertex attrib slot for the new texcoords */
    uint tex_slot;
+   uint pos_slot;
 
    /*
     * Currently bound state
@@ -130,11 +134,11 @@ aa_transform_decl(struct tgsi_transform_context *ctx,
    if (decl->Declaration.File == TGSI_FILE_OUTPUT &&
        decl->Semantic.SemanticName == TGSI_SEMANTIC_COLOR &&
        decl->Semantic.SemanticIndex == 0) {
-      aactx->colorOutput = decl->u.DeclarationRange.First;
+      aactx->colorOutput = decl->DeclarationRange.First;
    }
    else if (decl->Declaration.File == TGSI_FILE_INPUT) {
-      if ((int) decl->u.DeclarationRange.Last > aactx->maxInput)
-         aactx->maxInput = decl->u.DeclarationRange.Last;
+      if ((int) decl->DeclarationRange.Last > aactx->maxInput)
+         aactx->maxInput = decl->DeclarationRange.Last;
       if (decl->Semantic.SemanticName == TGSI_SEMANTIC_GENERIC &&
            (int) decl->Semantic.SemanticIndex > aactx->maxGeneric) {
          aactx->maxGeneric = decl->Semantic.SemanticIndex;
@@ -142,8 +146,8 @@ aa_transform_decl(struct tgsi_transform_context *ctx,
    }
    else if (decl->Declaration.File == TGSI_FILE_TEMPORARY) {
       uint i;
-      for (i = decl->u.DeclarationRange.First;
-           i <= decl->u.DeclarationRange.Last; i++) {
+      for (i = decl->DeclarationRange.First;
+           i <= decl->DeclarationRange.Last; i++) {
          aactx->tempsUsed |= (1 << i);
       }
    }
@@ -192,27 +196,26 @@ aa_transform_inst(struct tgsi_transform_context *ctx,
       /* declare new generic input/texcoord */
       decl = tgsi_default_full_declaration();
       decl.Declaration.File = TGSI_FILE_INPUT;
+      /* XXX this could be linear... */
+      decl.Declaration.Interpolate = TGSI_INTERPOLATE_PERSPECTIVE;
       decl.Declaration.Semantic = 1;
       decl.Semantic.SemanticName = TGSI_SEMANTIC_GENERIC;
       decl.Semantic.SemanticIndex = aactx->maxGeneric + 1;
-      decl.Declaration.Interpolate = 1;
-      /* XXX this could be linear... */
-      decl.Interpolation.Interpolate = TGSI_INTERPOLATE_PERSPECTIVE;
-      decl.u.DeclarationRange.First = 
-      decl.u.DeclarationRange.Last = texInput;
+      decl.DeclarationRange.First = 
+      decl.DeclarationRange.Last = texInput;
       ctx->emit_declaration(ctx, &decl);
 
       /* declare new temp regs */
       decl = tgsi_default_full_declaration();
       decl.Declaration.File = TGSI_FILE_TEMPORARY;
-      decl.u.DeclarationRange.First = 
-      decl.u.DeclarationRange.Last = tmp0;
+      decl.DeclarationRange.First = 
+      decl.DeclarationRange.Last = tmp0;
       ctx->emit_declaration(ctx, &decl);
 
       decl = tgsi_default_full_declaration();
       decl.Declaration.File = TGSI_FILE_TEMPORARY;
-      decl.u.DeclarationRange.First = 
-      decl.u.DeclarationRange.Last = aactx->colorTemp;
+      decl.DeclarationRange.First = 
+      decl.DeclarationRange.Last = aactx->colorTemp;
       ctx->emit_declaration(ctx, &decl);
 
       aactx->firstInstruction = FALSE;
@@ -300,9 +303,9 @@ aa_transform_inst(struct tgsi_transform_context *ctx,
       newInst.FullSrcRegisters[1].SrcRegister.SwizzleY = TGSI_SWIZZLE_W;
       ctx->emit_instruction(ctx, &newInst);
 
-      /* KILP -t0.yyyy;   # if b, KILL */
+      /* KIL -tmp0.yyyy;   # if -tmp0.y < 0, KILL */
       newInst = tgsi_default_full_instruction();
-      newInst.Instruction.Opcode = TGSI_OPCODE_KILP;
+      newInst.Instruction.Opcode = TGSI_OPCODE_KIL;
       newInst.Instruction.NumDstRegs = 0;
       newInst.Instruction.NumSrcRegs = 1;
       newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY;
@@ -480,10 +483,10 @@ aa_transform_inst(struct tgsi_transform_context *ctx,
 
 
 /**
- * Generate the frag shader we'll use for drawing AA lines.
+ * Generate the frag shader we'll use for drawing AA points.
  * This will be the user's shader plus some texture/modulate instructions.
  */
-static void
+static boolean
 generate_aapoint_fs(struct aapoint_stage *aapoint)
 {
    const struct pipe_shader_state *orig_fs = &aapoint->fs->state;
@@ -494,6 +497,8 @@ generate_aapoint_fs(struct aapoint_stage *aapoint)
 
    aapoint_fs = *orig_fs; /* copy to init */
    aapoint_fs.tokens = MALLOC(sizeof(struct tgsi_token) * MAX);
+   if (aapoint_fs.tokens == NULL)
+      return FALSE;
 
    memset(&transform, 0, sizeof(transform));
    transform.colorOutput = -1;
@@ -518,22 +523,33 @@ generate_aapoint_fs(struct aapoint_stage *aapoint)
 
    aapoint->fs->aapoint_fs
       = aapoint->driver_create_fs_state(aapoint->pipe, &aapoint_fs);
+   if (aapoint->fs->aapoint_fs == NULL)
+      return FALSE;
 
    aapoint->fs->generic_attrib = transform.maxGeneric + 1;
+
+   return TRUE;
 }
 
 
 /**
- * When we're about to draw our first AA line in a batch, this function is
+ * When we're about to draw our first AA point in a batch, this function is
  * called to tell the driver to bind our modified fragment shader.
  */
-static void
+static boolean
 bind_aapoint_fragment_shader(struct aapoint_stage *aapoint)
 {
-   if (!aapoint->fs->aapoint_fs) {
-      generate_aapoint_fs(aapoint);
-   }
+   struct draw_context *draw = aapoint->stage.draw;
+
+   if (!aapoint->fs->aapoint_fs &&
+       !generate_aapoint_fs(aapoint))
+      return FALSE;
+
+   draw->suspend_flushing = TRUE;
    aapoint->driver_bind_fs_state(aapoint->pipe, aapoint->fs->aapoint_fs);
+   draw->suspend_flushing = FALSE;
+
+   return TRUE;
 }
 
 
@@ -545,18 +561,6 @@ aapoint_stage( struct draw_stage *stage )
 }
 
 
-static void
-passthrough_line(struct draw_stage *stage, struct prim_header *header)
-{
-   stage->next->line(stage->next, header);
-}
-
-
-static void
-passthrough_tri(struct draw_stage *stage, struct prim_header *header)
-{
-   stage->next->tri(stage->next, header);
-}
 
 
 /**
@@ -569,6 +573,7 @@ aapoint_point(struct draw_stage *stage, struct prim_header *header)
    struct prim_header tri;
    struct vertex_header *v[4];
    uint texPos = aapoint->tex_slot;
+   uint pos_slot = aapoint->pos_slot;
    float radius, *pos, *tex;
    uint i;
    float k;
@@ -618,19 +623,19 @@ aapoint_point(struct draw_stage *stage, struct prim_header *header)
    }
 
    /* new verts */
-   pos = v[0]->data[0];
+   pos = v[0]->data[pos_slot];
    pos[0] -= radius;
    pos[1] -= radius;
 
-   pos = v[1]->data[0];
+   pos = v[1]->data[pos_slot];
    pos[0] += radius;
    pos[1] -= radius;
 
-   pos = v[2]->data[0];
+   pos = v[2]->data[pos_slot];
    pos[0] += radius;
    pos[1] += radius;
 
-   pos = v[3]->data[0];
+   pos = v[3]->data[pos_slot];
    pos[0] -= radius;
    pos[1] += radius;
 
@@ -679,9 +684,11 @@ aapoint_first_point(struct draw_stage *stage, struct prim_header *header)
    bind_aapoint_fragment_shader(aapoint);
 
    /* update vertex attrib info */
-   aapoint->tex_slot = draw->num_vs_outputs;
+   aapoint->tex_slot = draw->vs.num_vs_outputs;
    assert(aapoint->tex_slot > 0); /* output[0] is vertex pos */
 
+   aapoint->pos_slot = draw->vs.position_output;
+
    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;
@@ -690,7 +697,7 @@ aapoint_first_point(struct draw_stage *stage, struct prim_header *header)
    aapoint->psize_slot = -1;
    if (draw->rasterizer->point_size_per_vertex) {
       /* find PSIZ vertex output */
-      const struct draw_vertex_shader *vs = draw->vertex_shader;
+      const struct draw_vertex_shader *vs = draw->vs.vertex_shader;
       uint i;
       for (i = 0; i < vs->info.num_outputs; i++) {
          if (vs->info.output_semantic_name[i] == TGSI_SEMANTIC_PSIZE) {
@@ -700,7 +707,7 @@ aapoint_first_point(struct draw_stage *stage, struct prim_header *header)
       }
    }
 
-   /* now really draw first line */
+   /* now really draw first point */
    stage->point = aapoint_point;
    stage->point(stage, header);
 }
@@ -717,7 +724,9 @@ aapoint_flush(struct draw_stage *stage, unsigned flags)
    stage->next->flush( stage->next, flags );
 
    /* restore original frag shader */
+   draw->suspend_flushing = TRUE;
    aapoint->driver_bind_fs_state(pipe, aapoint->fs->driver_fs);
+   draw->suspend_flushing = FALSE;
 
    draw->extra_vp_outputs.slot = 0;
 }
@@ -742,19 +751,29 @@ static struct aapoint_stage *
 draw_aapoint_stage(struct draw_context *draw)
 {
    struct aapoint_stage *aapoint = CALLOC_STRUCT(aapoint_stage);
+   if (aapoint == NULL)
+      goto fail;
 
-   draw_alloc_temp_verts( &aapoint->stage, 4 );
+   if (!draw_alloc_temp_verts( &aapoint->stage, 4 ))
+      goto fail;
 
    aapoint->stage.draw = draw;
    aapoint->stage.next = NULL;
    aapoint->stage.point = aapoint_first_point;
-   aapoint->stage.line = passthrough_line;
-   aapoint->stage.tri = passthrough_tri;
+   aapoint->stage.line = draw_pipe_passthrough_line;
+   aapoint->stage.tri = draw_pipe_passthrough_tri;
    aapoint->stage.flush = aapoint_flush;
    aapoint->stage.reset_stipple_counter = aapoint_reset_stipple_counter;
    aapoint->stage.destroy = aapoint_destroy;
 
    return aapoint;
+
+ fail:
+   if (aapoint)
+      aapoint_destroy(&aapoint->stage);
+
+   return NULL;
+
 }
 
 
@@ -776,13 +795,13 @@ aapoint_create_fs_state(struct pipe_context *pipe,
 {
    struct aapoint_stage *aapoint = aapoint_stage_from_pipe(pipe);
    struct aapoint_fragment_shader *aafs = CALLOC_STRUCT(aapoint_fragment_shader);
+   if (aafs == NULL) 
+      return NULL;
 
-   if (aafs) {
-      aafs->state = *fs;
+   aafs->state = *fs;
 
-      /* pass-through */
-      aafs->driver_fs = aapoint->driver_create_fs_state(aapoint->pipe, fs);
-   }
+   /* pass-through */
+   aafs->driver_fs = aapoint->driver_create_fs_state(aapoint->pipe, fs);
 
    return aafs;
 }
@@ -817,7 +836,7 @@ aapoint_delete_fs_state(struct pipe_context *pipe, void *fs)
  * into the draw module's pipeline.  This will not be used if the
  * hardware has native support for AA points.
  */
-void
+boolean
 draw_install_aapoint_stage(struct draw_context *draw,
                            struct pipe_context *pipe)
 {
@@ -829,8 +848,8 @@ draw_install_aapoint_stage(struct draw_context *draw,
     * Create / install AA point drawing / prim stage
     */
    aapoint = draw_aapoint_stage( draw );
-   assert(aapoint);
-   draw->pipeline.aapoint = &aapoint->stage;
+   if (aapoint == NULL)
+      goto fail;
 
    aapoint->pipe = pipe;
 
@@ -843,4 +862,14 @@ draw_install_aapoint_stage(struct draw_context *draw,
    pipe->create_fs_state = aapoint_create_fs_state;
    pipe->bind_fs_state = aapoint_bind_fs_state;
    pipe->delete_fs_state = aapoint_delete_fs_state;
+
+   draw->pipeline.aapoint = &aapoint->stage;
+
+   return TRUE;
+
+ fail:
+   if (aapoint)
+      aapoint->stage.destroy( &aapoint->stage );
+
+   return FALSE;
 }