summaryrefslogtreecommitdiff
path: root/src/gallium/auxiliary/draw
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/auxiliary/draw')
-rw-r--r--src/gallium/auxiliary/draw/SConscript3
-rw-r--r--src/gallium/auxiliary/draw/draw_aapoint.c202
-rw-r--r--src/gallium/auxiliary/draw/draw_context.c24
-rw-r--r--src/gallium/auxiliary/draw/draw_pstipple.c4
-rw-r--r--src/gallium/auxiliary/draw/draw_validate.c16
5 files changed, 138 insertions, 111 deletions
diff --git a/src/gallium/auxiliary/draw/SConscript b/src/gallium/auxiliary/draw/SConscript
index 8e3a8caa74..3302dc44f7 100644
--- a/src/gallium/auxiliary/draw/SConscript
+++ b/src/gallium/auxiliary/draw/SConscript
@@ -3,6 +3,8 @@ Import('*')
draw = env.ConvenienceLibrary(
target = 'draw',
source = [
+ 'draw_aaline.c',
+ 'draw_aapoint.c',
'draw_clip.c',
'draw_vs_exec.c',
'draw_vs_sse.c',
@@ -13,6 +15,7 @@ draw = env.ConvenienceLibrary(
'draw_flatshade.c',
'draw_offset.c',
'draw_prim.c',
+ 'draw_pstipple.c',
'draw_stipple.c',
'draw_twoside.c',
'draw_unfilled.c',
diff --git a/src/gallium/auxiliary/draw/draw_aapoint.c b/src/gallium/auxiliary/draw/draw_aapoint.c
index 43119cc70b..cae6fcd4d2 100644
--- a/src/gallium/auxiliary/draw/draw_aapoint.c
+++ b/src/gallium/auxiliary/draw/draw_aapoint.c
@@ -222,7 +222,7 @@ aa_transform_inst(struct tgsi_transform_context *ctx,
*
* Temp reg0 usage:
* t0.x = distance of fragment from center point
- * t0.y = boolean, is t0.x > 1 ?
+ * t0.y = boolean, is t0.x > 1.0, also misc temp usage
* t0.z = temporary for computing 1/(1-k) value
* t0.w = final coverage value
*/
@@ -313,9 +313,73 @@ aa_transform_inst(struct tgsi_transform_context *ctx,
newInst.FullSrcRegisters[0].SrcRegister.Negate = 1;
ctx->emit_instruction(ctx, &newInst);
- /* SGT t0.y, t0.x, tex.z; # bool b = distance > k */
+
+ /* compute coverage factor = (1-d)/(1-k) */
+
+ /* SUB t0.z, tex.w, tex.z; # m = 1 - k */
newInst = tgsi_default_full_instruction();
- newInst.Instruction.Opcode = TGSI_OPCODE_SGT;
+ newInst.Instruction.Opcode = TGSI_OPCODE_SUB;
+ newInst.Instruction.NumDstRegs = 1;
+ newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY;
+ newInst.FullDstRegisters[0].DstRegister.Index = tmp0;
+ newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_Z;
+ newInst.Instruction.NumSrcRegs = 2;
+ newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_INPUT;
+ newInst.FullSrcRegisters[0].SrcRegister.Index = texInput;
+ newInst.FullSrcRegisters[0].SrcRegister.SwizzleZ = TGSI_SWIZZLE_W;
+ newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_INPUT;
+ newInst.FullSrcRegisters[1].SrcRegister.Index = texInput;
+ newInst.FullSrcRegisters[1].SrcRegister.SwizzleZ = TGSI_SWIZZLE_Z;
+ ctx->emit_instruction(ctx, &newInst);
+
+ /* RCP t0.z, t0.z; # t0.z = 1 / m */
+ newInst = tgsi_default_full_instruction();
+ newInst.Instruction.Opcode = TGSI_OPCODE_RCP;
+ newInst.Instruction.NumDstRegs = 1;
+ newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY;
+ newInst.FullDstRegisters[0].DstRegister.Index = tmp0;
+ newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_Z;
+ newInst.Instruction.NumSrcRegs = 1;
+ newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY;
+ newInst.FullSrcRegisters[0].SrcRegister.Index = tmp0;
+ newInst.FullSrcRegisters[0].SrcRegister.SwizzleX = TGSI_SWIZZLE_Z;
+ ctx->emit_instruction(ctx, &newInst);
+
+ /* SUB t0.y, 1, t0.x; # d = 1 - d */
+ newInst = tgsi_default_full_instruction();
+ newInst.Instruction.Opcode = TGSI_OPCODE_SUB;
+ newInst.Instruction.NumDstRegs = 1;
+ newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY;
+ newInst.FullDstRegisters[0].DstRegister.Index = tmp0;
+ newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_Y;
+ newInst.Instruction.NumSrcRegs = 2;
+ newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_INPUT;
+ newInst.FullSrcRegisters[0].SrcRegister.Index = texInput;
+ newInst.FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_W;
+ newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_TEMPORARY;
+ newInst.FullSrcRegisters[1].SrcRegister.Index = tmp0;
+ newInst.FullSrcRegisters[1].SrcRegister.SwizzleY = TGSI_SWIZZLE_X;
+ ctx->emit_instruction(ctx, &newInst);
+
+ /* MUL t0.w, t0.y, t0.z; # coverage = d * m */
+ newInst = tgsi_default_full_instruction();
+ newInst.Instruction.Opcode = TGSI_OPCODE_MUL;
+ newInst.Instruction.NumDstRegs = 1;
+ newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY;
+ newInst.FullDstRegisters[0].DstRegister.Index = tmp0;
+ newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_W;
+ newInst.Instruction.NumSrcRegs = 2;
+ newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY;
+ newInst.FullSrcRegisters[0].SrcRegister.Index = tmp0;
+ newInst.FullSrcRegisters[0].SrcRegister.SwizzleW = TGSI_SWIZZLE_Y;
+ newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_TEMPORARY;
+ newInst.FullSrcRegisters[1].SrcRegister.Index = tmp0;
+ newInst.FullSrcRegisters[1].SrcRegister.SwizzleW = TGSI_SWIZZLE_Z;
+ ctx->emit_instruction(ctx, &newInst);
+
+ /* SLE t0.y, t0.x, tex.z; # bool b = distance <= k */
+ newInst = tgsi_default_full_instruction();
+ newInst.Instruction.Opcode = TGSI_OPCODE_SLE;
newInst.Instruction.NumDstRegs = 1;
newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY;
newInst.FullDstRegisters[0].DstRegister.Index = tmp0;
@@ -329,111 +393,40 @@ aa_transform_inst(struct tgsi_transform_context *ctx,
newInst.FullSrcRegisters[1].SrcRegister.SwizzleY = TGSI_SWIZZLE_Z;
ctx->emit_instruction(ctx, &newInst);
- /* IF t0.y # if b then */
+ /* CMP t0.w, -t0.y, tex.w, t0.w;
+ * # if -t0.y < 0 then
+ * t0.w = 1
+ * else
+ * t0.w = t0.w
+ */
newInst = tgsi_default_full_instruction();
- newInst.Instruction.Opcode = TGSI_OPCODE_IF;
- newInst.Instruction.NumDstRegs = 0;
- newInst.Instruction.NumSrcRegs = 1;
+ newInst.Instruction.Opcode = TGSI_OPCODE_CMP;
+ newInst.Instruction.NumDstRegs = 1;
+ newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY;
+ newInst.FullDstRegisters[0].DstRegister.Index = tmp0;
+ newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_W;
+ newInst.Instruction.NumSrcRegs = 3;
newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY;
newInst.FullSrcRegisters[0].SrcRegister.Index = tmp0;
newInst.FullSrcRegisters[0].SrcRegister.SwizzleX = TGSI_SWIZZLE_Y;
newInst.FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_Y;
newInst.FullSrcRegisters[0].SrcRegister.SwizzleZ = TGSI_SWIZZLE_Y;
newInst.FullSrcRegisters[0].SrcRegister.SwizzleW = TGSI_SWIZZLE_Y;
+ newInst.FullSrcRegisters[0].SrcRegister.Negate = 1;
+ newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_INPUT;
+ newInst.FullSrcRegisters[1].SrcRegister.Index = texInput;
+ newInst.FullSrcRegisters[1].SrcRegister.SwizzleX = TGSI_SWIZZLE_W;
+ newInst.FullSrcRegisters[1].SrcRegister.SwizzleY = TGSI_SWIZZLE_W;
+ newInst.FullSrcRegisters[1].SrcRegister.SwizzleZ = TGSI_SWIZZLE_W;
+ newInst.FullSrcRegisters[1].SrcRegister.SwizzleW = TGSI_SWIZZLE_W;
+ newInst.FullSrcRegisters[2].SrcRegister.File = TGSI_FILE_TEMPORARY;
+ newInst.FullSrcRegisters[2].SrcRegister.Index = tmp0;
+ newInst.FullSrcRegisters[2].SrcRegister.SwizzleX = TGSI_SWIZZLE_W;
+ newInst.FullSrcRegisters[2].SrcRegister.SwizzleY = TGSI_SWIZZLE_W;
+ newInst.FullSrcRegisters[2].SrcRegister.SwizzleZ = TGSI_SWIZZLE_W;
+ newInst.FullSrcRegisters[2].SrcRegister.SwizzleW = TGSI_SWIZZLE_W;
ctx->emit_instruction(ctx, &newInst);
- {
- /* compute coverage factor = (1-d)/(1-k) */
-
- /* SUB t0.z, tex.w, tex.z; # m = 1 - k */
- newInst = tgsi_default_full_instruction();
- newInst.Instruction.Opcode = TGSI_OPCODE_SUB;
- newInst.Instruction.NumDstRegs = 1;
- newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY;
- newInst.FullDstRegisters[0].DstRegister.Index = tmp0;
- newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_Z;
- newInst.Instruction.NumSrcRegs = 2;
- newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_INPUT;
- newInst.FullSrcRegisters[0].SrcRegister.Index = texInput;
- newInst.FullSrcRegisters[0].SrcRegister.SwizzleZ = TGSI_SWIZZLE_W;
- newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_INPUT;
- newInst.FullSrcRegisters[1].SrcRegister.Index = texInput;
- newInst.FullSrcRegisters[1].SrcRegister.SwizzleZ = TGSI_SWIZZLE_Z;
- ctx->emit_instruction(ctx, &newInst);
-
- /* RCP t0.z, t0.z; # t0.z = 1 / m */
- newInst = tgsi_default_full_instruction();
- newInst.Instruction.Opcode = TGSI_OPCODE_RCP;
- newInst.Instruction.NumDstRegs = 1;
- newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY;
- newInst.FullDstRegisters[0].DstRegister.Index = tmp0;
- newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_Z;
- newInst.Instruction.NumSrcRegs = 1;
- newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY;
- newInst.FullSrcRegisters[0].SrcRegister.Index = tmp0;
- newInst.FullSrcRegisters[0].SrcRegister.SwizzleX = TGSI_SWIZZLE_Z;
- ctx->emit_instruction(ctx, &newInst);
-
- /* SUB t0.x, 1, t0.x; # d = 1 - d */
- newInst = tgsi_default_full_instruction();
- newInst.Instruction.Opcode = TGSI_OPCODE_SUB;
- newInst.Instruction.NumDstRegs = 1;
- newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY;
- newInst.FullDstRegisters[0].DstRegister.Index = tmp0;
- newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_X;
- newInst.Instruction.NumSrcRegs = 2;
- newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_INPUT;
- newInst.FullSrcRegisters[0].SrcRegister.Index = texInput;
- newInst.FullSrcRegisters[0].SrcRegister.SwizzleX = TGSI_SWIZZLE_W;
- newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_TEMPORARY;
- newInst.FullSrcRegisters[1].SrcRegister.Index = tmp0;
- newInst.FullSrcRegisters[1].SrcRegister.SwizzleX = TGSI_SWIZZLE_X;
- ctx->emit_instruction(ctx, &newInst);
-
- /* MUL t0.w, t0.x, t0.z; # coverage = d * m */
- newInst = tgsi_default_full_instruction();
- newInst.Instruction.Opcode = TGSI_OPCODE_MUL;
- newInst.Instruction.NumDstRegs = 1;
- newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY;
- newInst.FullDstRegisters[0].DstRegister.Index = tmp0;
- newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_W;
- newInst.Instruction.NumSrcRegs = 2;
- newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY;
- newInst.FullSrcRegisters[0].SrcRegister.Index = tmp0;
- newInst.FullSrcRegisters[0].SrcRegister.SwizzleW = TGSI_SWIZZLE_X;
- newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_TEMPORARY;
- newInst.FullSrcRegisters[1].SrcRegister.Index = tmp0;
- newInst.FullSrcRegisters[1].SrcRegister.SwizzleW = TGSI_SWIZZLE_Z;
- ctx->emit_instruction(ctx, &newInst);
- }
-
- /* ELSE */
- newInst = tgsi_default_full_instruction();
- newInst.Instruction.Opcode = TGSI_OPCODE_ELSE;
- newInst.Instruction.NumDstRegs = 0;
- newInst.Instruction.NumSrcRegs = 0;
- ctx->emit_instruction(ctx, &newInst);
-
- {
- /* MOV t0.w, tex.w; # coverage = 1.0 */
- newInst = tgsi_default_full_instruction();
- newInst.Instruction.Opcode = TGSI_OPCODE_MOV;
- newInst.Instruction.NumDstRegs = 1;
- newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY;
- newInst.FullDstRegisters[0].DstRegister.Index = tmp0;
- newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_W;
- newInst.Instruction.NumSrcRegs = 1;
- newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_INPUT;
- newInst.FullSrcRegisters[0].SrcRegister.Index = texInput;
- ctx->emit_instruction(ctx, &newInst);
- }
-
- /* ENDIF */
- newInst = tgsi_default_full_instruction();
- newInst.Instruction.Opcode = TGSI_OPCODE_ENDIF;
- newInst.Instruction.NumDstRegs = 0;
- newInst.Instruction.NumSrcRegs = 0;
- ctx->emit_instruction(ctx, &newInst);
}
if (inst->Instruction.Opcode == TGSI_OPCODE_END) {
@@ -516,7 +509,7 @@ generate_aapoint_fs(struct aapoint_stage *aapoint)
(struct tgsi_token *) aapoint_fs.tokens,
MAX, &transform.base);
-#if 0 /* DEBUG */
+#if 1 /* DEBUG */
tgsi_dump(orig_fs->tokens, 0);
tgsi_dump(aapoint_fs.tokens, 0);
#endif
@@ -613,13 +606,16 @@ aapoint_point(struct draw_stage *stage, struct prim_header *header)
* ELSE
* coverage = 1.0; // full coverage
* ENDIF
+ *
+ * Note: the ELSEIF and ELSE clauses are actually implemented with CMP to
+ * avoid using IF/ELSE/ENDIF TGSI opcodes.
*/
#if !NORMALIZE
- k = 1.0 / radius;
- k = 1.0 - 2.0 * k + k * k;
+ k = 1.0f / radius;
+ k = 1.0f - 2.0f * k + k * k;
#else
- k = 1.0 - 1.0 / radius;
+ k = 1.0f - 1.0f / radius;
#endif
/* allocate/dup new verts */
diff --git a/src/gallium/auxiliary/draw/draw_context.c b/src/gallium/auxiliary/draw/draw_context.c
index c28e78d33a..7dd1c6f6fa 100644
--- a/src/gallium/auxiliary/draw/draw_context.c
+++ b/src/gallium/auxiliary/draw/draw_context.c
@@ -244,14 +244,32 @@ draw_convert_wide_lines(struct draw_context *draw, boolean enable)
/**
- * The draw module may sometimes generate vertices with extra attributes
- * (such as texcoords for AA lines). The driver can call this function
- * to find those attributes.
+ * Ask the draw module for the location/slot of the given vertex attribute in
+ * a post-transformed vertex.
+ *
+ * With this function, drivers that use the draw module should have no reason
+ * to track the current vertex shader.
+ *
+ * Note that the draw module may sometimes generate vertices with extra
+ * attributes (such as texcoords for AA lines). The driver can call this
+ * function to find those attributes.
+ *
+ * Zero is returned if the attribute is not found since this is
+ * a don't care / undefined situtation. Returning -1 would be a bit more
+ * work for the drivers.
*/
int
draw_find_vs_output(struct draw_context *draw,
uint semantic_name, uint semantic_index)
{
+ const struct pipe_shader_state *vs = draw->vertex_shader->state;
+ uint i;
+ for (i = 0; i < vs->num_outputs; i++) {
+ if (vs->output_semantic_name[i] == semantic_name &&
+ vs->output_semantic_index[i] == semantic_index)
+ return i;
+ }
+
/* XXX there may be more than one extra vertex attrib.
* For example, simulated gl_FragCoord and gl_PointCoord.
*/
diff --git a/src/gallium/auxiliary/draw/draw_pstipple.c b/src/gallium/auxiliary/draw/draw_pstipple.c
index 4048abf856..1ab04cd959 100644
--- a/src/gallium/auxiliary/draw/draw_pstipple.c
+++ b/src/gallium/auxiliary/draw/draw_pstipple.c
@@ -133,7 +133,7 @@ pstip_transform_decl(struct tgsi_transform_context *ctx,
pctx->maxSampler = (int) decl->u.DeclarationRange.Last;
}
else if (decl->Declaration.File == TGSI_FILE_INPUT) {
- pctx->maxInput = MAX2(pctx->maxInput, decl->u.DeclarationRange.Last);
+ pctx->maxInput = MAX2(pctx->maxInput, (int) decl->u.DeclarationRange.Last);
if (decl->Semantic.SemanticName == TGSI_SEMANTIC_POSITION)
pctx->wincoordInput = (int) decl->u.DeclarationRange.First;
}
@@ -332,7 +332,7 @@ generate_pstip_fs(struct pstip_stage *pstip)
if (transform.wincoordInput < 0) {
pstip_fs.input_semantic_name[pstip_fs.num_inputs] = TGSI_SEMANTIC_POSITION;
- pstip_fs.input_semantic_index[pstip_fs.num_inputs] = transform.maxInput;
+ pstip_fs.input_semantic_index[pstip_fs.num_inputs] = (ubyte)transform.maxInput;
pstip_fs.num_inputs++;
}
diff --git a/src/gallium/auxiliary/draw/draw_validate.c b/src/gallium/auxiliary/draw/draw_validate.c
index efd6793f2b..3a19dd4cd7 100644
--- a/src/gallium/auxiliary/draw/draw_validate.c
+++ b/src/gallium/auxiliary/draw/draw_validate.c
@@ -45,6 +45,7 @@ static struct draw_stage *validate_pipeline( struct draw_stage *stage )
struct draw_stage *next = draw->pipeline.rasterize;
int need_det = 0;
int precalc_flat = 0;
+ boolean wide_lines, wide_points;
/* Set the validate's next stage to the rasterize stage, so that it
* can be found later if needed for flushing.
@@ -68,9 +69,18 @@ static struct draw_stage *validate_pipeline( struct draw_stage *stage )
next = draw->pipeline.aapoint;
}
- if ((draw->rasterizer->line_width != 1.0 && draw->convert_wide_lines
- && !draw->rasterizer->line_smooth) ||
- (draw->rasterizer->point_size != 1.0 && draw->convert_wide_points) ||
+ /* drawing wide lines? */
+ wide_lines = (draw->rasterizer->line_width != 1.0
+ && draw->convert_wide_lines
+ && !draw->rasterizer->line_smooth);
+
+ /* drawing large points? */
+ wide_points = (draw->rasterizer->point_size != 1.0
+ && draw->convert_wide_points
+ && !draw->pipeline.aapoint);
+
+ if (wide_lines ||
+ wide_points ||
draw->rasterizer->point_sprite) {
draw->pipeline.wide->next = next;
next = draw->pipeline.wide;