draw_pipe_aapoint.c File Reference

Include dependency graph for draw_pipe_aapoint.c:

Go to the source code of this file.

Data Structures

struct  aapoint_fragment_shader
 Subclass of pipe_shader_state to carry extra fragment shader info. More...
struct  aapoint_stage
 Subclass of draw_stage. More...
struct  aa_transform_context
 Subclass of tgsi_transform_context, used for transforming the user's fragment shader to add the special AA instructions. More...

Defines

#define NORMALIZE   0
 AA point stage: AA points are converted to quads and rendered with a special fragment shader.
#define MAX   1000

Functions

static void aa_transform_decl (struct tgsi_transform_context *ctx, struct tgsi_full_declaration *decl)
 TGSI declaration transform callback.
static void aa_transform_inst (struct tgsi_transform_context *ctx, struct tgsi_full_instruction *inst)
 TGSI instruction transform callback.
static boolean generate_aapoint_fs (struct aapoint_stage *aapoint)
 Generate the frag shader we'll use for drawing AA points.
static boolean bind_aapoint_fragment_shader (struct aapoint_stage *aapoint)
 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 struct aapoint_stageaapoint_stage (struct draw_stage *stage)
static void aapoint_point (struct draw_stage *stage, struct prim_header *header)
 Draw an AA point by drawing a quad.
static void aapoint_first_point (struct draw_stage *stage, struct prim_header *header)
static void aapoint_flush (struct draw_stage *stage, unsigned flags)
static void aapoint_reset_stipple_counter (struct draw_stage *stage)
static void aapoint_destroy (struct draw_stage *stage)
static struct aapoint_stagedraw_aapoint_stage (struct draw_context *draw)
static struct aapoint_stageaapoint_stage_from_pipe (struct pipe_context *pipe)
static void * aapoint_create_fs_state (struct pipe_context *pipe, const struct pipe_shader_state *fs)
 This function overrides the driver's create_fs_state() function and will typically be called by the state tracker.
static void aapoint_bind_fs_state (struct pipe_context *pipe, void *fs)
static void aapoint_delete_fs_state (struct pipe_context *pipe, void *fs)
boolean draw_install_aapoint_stage (struct draw_context *draw, struct pipe_context *pipe)
 Called by drivers that want to install this AA point prim stage into the draw module's pipeline.


Define Documentation

#define MAX   1000

#define NORMALIZE   0

AA point stage: AA points are converted to quads and rendered with a special fragment shader.

Another approach would be to use a texture map image of a point, but experiments indicate the quality isn't nearly as good as this approach.

Note: this looks a lot like draw_aaline.c but there's actually little if any code that can be shared.

Authors: Brian Paul

Definition at line 63 of file draw_pipe_aapoint.c.


Function Documentation

static void aa_transform_decl ( struct tgsi_transform_context ctx,
struct tgsi_full_declaration decl 
) [static]

TGSI declaration transform callback.

Look for two free temp regs and available input reg for new texcoords.

Definition at line 129 of file draw_pipe_aapoint.c.

References aa_transform_context::colorOutput, tgsi_full_declaration::Declaration, tgsi_full_declaration::DeclarationRange, tgsi_transform_context::emit_declaration, tgsi_declaration::File, tgsi_declaration_range::First, tgsi_declaration_range::Last, aa_transform_context::maxGeneric, aa_transform_context::maxInput, tgsi_full_declaration::Semantic, tgsi_declaration_semantic::SemanticIndex, tgsi_declaration_semantic::SemanticName, aa_transform_context::tempsUsed, TGSI_FILE_INPUT, TGSI_FILE_OUTPUT, TGSI_FILE_TEMPORARY, TGSI_SEMANTIC_COLOR, and TGSI_SEMANTIC_GENERIC.

00131 {
00132    struct aa_transform_context *aactx = (struct aa_transform_context *) ctx;
00133 
00134    if (decl->Declaration.File == TGSI_FILE_OUTPUT &&
00135        decl->Semantic.SemanticName == TGSI_SEMANTIC_COLOR &&
00136        decl->Semantic.SemanticIndex == 0) {
00137       aactx->colorOutput = decl->DeclarationRange.First;
00138    }
00139    else if (decl->Declaration.File == TGSI_FILE_INPUT) {
00140       if ((int) decl->DeclarationRange.Last > aactx->maxInput)
00141          aactx->maxInput = decl->DeclarationRange.Last;
00142       if (decl->Semantic.SemanticName == TGSI_SEMANTIC_GENERIC &&
00143            (int) decl->Semantic.SemanticIndex > aactx->maxGeneric) {
00144          aactx->maxGeneric = decl->Semantic.SemanticIndex;
00145       }
00146    }
00147    else if (decl->Declaration.File == TGSI_FILE_TEMPORARY) {
00148       uint i;
00149       for (i = decl->DeclarationRange.First;
00150            i <= decl->DeclarationRange.Last; i++) {
00151          aactx->tempsUsed |= (1 << i);
00152       }
00153    }
00154 
00155    ctx->emit_declaration(ctx, decl);
00156 }

static void aa_transform_inst ( struct tgsi_transform_context ctx,
struct tgsi_full_instruction inst 
) [static]

TGSI instruction transform callback.

Replace writes to result.color w/ a temp reg. Upon END instruction, insert texture sampling code for antialiasing.

Definition at line 165 of file draw_pipe_aapoint.c.

References assert, aa_transform_context::colorOutput, aa_transform_context::colorTemp, tgsi_full_declaration::Declaration, tgsi_full_declaration::DeclarationRange, tgsi_full_dst_register::DstRegister, tgsi_transform_context::emit_declaration, tgsi_transform_context::emit_instruction, FALSE, tgsi_src_register::File, tgsi_dst_register::File, tgsi_declaration::File, tgsi_declaration_range::First, aa_transform_context::firstInstruction, tgsi_full_instruction::FullDstRegisters, tgsi_full_instruction::FullSrcRegisters, tgsi_src_register::Index, tgsi_dst_register::Index, tgsi_full_instruction::Instruction, tgsi_declaration::Interpolate, tgsi_declaration_range::Last, aa_transform_context::maxGeneric, aa_transform_context::maxInput, tgsi_src_register::Negate, tgsi_instruction::NumDstRegs, tgsi_instruction::NumSrcRegs, tgsi_instruction::Opcode, tgsi_full_declaration::Semantic, tgsi_declaration::Semantic, tgsi_declaration_semantic::SemanticIndex, tgsi_declaration_semantic::SemanticName, tgsi_full_src_register::SrcRegister, tgsi_src_register::SwizzleW, tgsi_src_register::SwizzleX, tgsi_src_register::SwizzleY, tgsi_src_register::SwizzleZ, aa_transform_context::tempsUsed, tgsi_default_full_declaration(), tgsi_default_full_instruction(), TGSI_FILE_INPUT, TGSI_FILE_OUTPUT, TGSI_FILE_TEMPORARY, TGSI_INTERPOLATE_PERSPECTIVE, TGSI_OPCODE_ADD, TGSI_OPCODE_CMP, TGSI_OPCODE_END, TGSI_OPCODE_KIL, TGSI_OPCODE_MOV, TGSI_OPCODE_MUL, TGSI_OPCODE_RCP, TGSI_OPCODE_RSQ, TGSI_OPCODE_SGT, TGSI_OPCODE_SLE, TGSI_OPCODE_SUB, TGSI_SEMANTIC_GENERIC, TGSI_SWIZZLE_W, TGSI_SWIZZLE_X, TGSI_SWIZZLE_Y, TGSI_SWIZZLE_Z, TGSI_WRITEMASK_W, TGSI_WRITEMASK_X, TGSI_WRITEMASK_XY, TGSI_WRITEMASK_XYZ, TGSI_WRITEMASK_Y, TGSI_WRITEMASK_Z, aa_transform_context::tmp0, and tgsi_dst_register::WriteMask.

00167 {
00168    struct aa_transform_context *aactx = (struct aa_transform_context *) ctx;
00169    struct tgsi_full_instruction newInst;
00170 
00171    if (aactx->firstInstruction) {
00172       /* emit our new declarations before the first instruction */
00173 
00174       struct tgsi_full_declaration decl;
00175       const int texInput = aactx->maxInput + 1;
00176       int tmp0;
00177       uint i;
00178 
00179       /* find two free temp regs */
00180       for (i = 0; i < 32; i++) {
00181          if ((aactx->tempsUsed & (1 << i)) == 0) {
00182             /* found a free temp */
00183             if (aactx->tmp0 < 0)
00184                aactx->tmp0 = i;
00185             else if (aactx->colorTemp < 0)
00186                aactx->colorTemp = i;
00187             else
00188                break;
00189          }
00190       }
00191 
00192       assert(aactx->colorTemp != aactx->tmp0);
00193 
00194       tmp0 = aactx->tmp0;
00195 
00196       /* declare new generic input/texcoord */
00197       decl = tgsi_default_full_declaration();
00198       decl.Declaration.File = TGSI_FILE_INPUT;
00199       /* XXX this could be linear... */
00200       decl.Declaration.Interpolate = TGSI_INTERPOLATE_PERSPECTIVE;
00201       decl.Declaration.Semantic = 1;
00202       decl.Semantic.SemanticName = TGSI_SEMANTIC_GENERIC;
00203       decl.Semantic.SemanticIndex = aactx->maxGeneric + 1;
00204       decl.DeclarationRange.First = 
00205       decl.DeclarationRange.Last = texInput;
00206       ctx->emit_declaration(ctx, &decl);
00207 
00208       /* declare new temp regs */
00209       decl = tgsi_default_full_declaration();
00210       decl.Declaration.File = TGSI_FILE_TEMPORARY;
00211       decl.DeclarationRange.First = 
00212       decl.DeclarationRange.Last = tmp0;
00213       ctx->emit_declaration(ctx, &decl);
00214 
00215       decl = tgsi_default_full_declaration();
00216       decl.Declaration.File = TGSI_FILE_TEMPORARY;
00217       decl.DeclarationRange.First = 
00218       decl.DeclarationRange.Last = aactx->colorTemp;
00219       ctx->emit_declaration(ctx, &decl);
00220 
00221       aactx->firstInstruction = FALSE;
00222 
00223 
00224       /*
00225        * Emit code to compute fragment coverage, kill if outside point radius
00226        *
00227        * Temp reg0 usage:
00228        *  t0.x = distance of fragment from center point
00229        *  t0.y = boolean, is t0.x > 1.0, also misc temp usage
00230        *  t0.z = temporary for computing 1/(1-k) value
00231        *  t0.w = final coverage value
00232        */
00233 
00234       /* MUL t0.xy, tex, tex;  # compute x^2, y^2 */
00235       newInst = tgsi_default_full_instruction();
00236       newInst.Instruction.Opcode = TGSI_OPCODE_MUL;
00237       newInst.Instruction.NumDstRegs = 1;
00238       newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY;
00239       newInst.FullDstRegisters[0].DstRegister.Index = tmp0;
00240       newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_XY;
00241       newInst.Instruction.NumSrcRegs = 2;
00242       newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_INPUT;
00243       newInst.FullSrcRegisters[0].SrcRegister.Index = texInput;
00244       newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_INPUT;
00245       newInst.FullSrcRegisters[1].SrcRegister.Index = texInput;
00246       ctx->emit_instruction(ctx, &newInst);
00247 
00248       /* ADD t0.x, t0.x, t0.y;  # x^2 + y^2 */
00249       newInst = tgsi_default_full_instruction();
00250       newInst.Instruction.Opcode = TGSI_OPCODE_ADD;
00251       newInst.Instruction.NumDstRegs = 1;
00252       newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY;
00253       newInst.FullDstRegisters[0].DstRegister.Index = tmp0;
00254       newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_X;
00255       newInst.Instruction.NumSrcRegs = 2;
00256       newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY;
00257       newInst.FullSrcRegisters[0].SrcRegister.Index = tmp0;
00258       newInst.FullSrcRegisters[0].SrcRegister.SwizzleX = TGSI_SWIZZLE_X;
00259       newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_TEMPORARY;
00260       newInst.FullSrcRegisters[1].SrcRegister.Index = tmp0;
00261       newInst.FullSrcRegisters[1].SrcRegister.SwizzleX = TGSI_SWIZZLE_Y;
00262       ctx->emit_instruction(ctx, &newInst);
00263 
00264 #if NORMALIZE  /* OPTIONAL normalization of length */
00265       /* RSQ t0.x, t0.x; */
00266       newInst = tgsi_default_full_instruction();
00267       newInst.Instruction.Opcode = TGSI_OPCODE_RSQ;
00268       newInst.Instruction.NumDstRegs = 1;
00269       newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY;
00270       newInst.FullDstRegisters[0].DstRegister.Index = tmp0;
00271       newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_X;
00272       newInst.Instruction.NumSrcRegs = 1;
00273       newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY;
00274       newInst.FullSrcRegisters[0].SrcRegister.Index = tmp0;
00275       ctx->emit_instruction(ctx, &newInst);
00276 
00277       /* RCP t0.x, t0.x; */
00278       newInst = tgsi_default_full_instruction();
00279       newInst.Instruction.Opcode = TGSI_OPCODE_RCP;
00280       newInst.Instruction.NumDstRegs = 1;
00281       newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY;
00282       newInst.FullDstRegisters[0].DstRegister.Index = tmp0;
00283       newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_X;
00284       newInst.Instruction.NumSrcRegs = 1;
00285       newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY;
00286       newInst.FullSrcRegisters[0].SrcRegister.Index = tmp0;
00287       ctx->emit_instruction(ctx, &newInst);
00288 #endif
00289 
00290       /* SGT t0.y, t0.xxxx, t0.wwww;  # bool b = d > 1 (NOTE t0.w == 1) */
00291       newInst = tgsi_default_full_instruction();
00292       newInst.Instruction.Opcode = TGSI_OPCODE_SGT;
00293       newInst.Instruction.NumDstRegs = 1;
00294       newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY;
00295       newInst.FullDstRegisters[0].DstRegister.Index = tmp0;
00296       newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_Y;
00297       newInst.Instruction.NumSrcRegs = 2;
00298       newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY;
00299       newInst.FullSrcRegisters[0].SrcRegister.Index = tmp0;
00300       newInst.FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_X;
00301       newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_INPUT;
00302       newInst.FullSrcRegisters[1].SrcRegister.Index = texInput;
00303       newInst.FullSrcRegisters[1].SrcRegister.SwizzleY = TGSI_SWIZZLE_W;
00304       ctx->emit_instruction(ctx, &newInst);
00305 
00306       /* KIL -tmp0.yyyy;   # if -tmp0.y < 0, KILL */
00307       newInst = tgsi_default_full_instruction();
00308       newInst.Instruction.Opcode = TGSI_OPCODE_KIL;
00309       newInst.Instruction.NumDstRegs = 0;
00310       newInst.Instruction.NumSrcRegs = 1;
00311       newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY;
00312       newInst.FullSrcRegisters[0].SrcRegister.Index = tmp0;
00313       newInst.FullSrcRegisters[0].SrcRegister.SwizzleX = TGSI_SWIZZLE_Y;
00314       newInst.FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_Y;
00315       newInst.FullSrcRegisters[0].SrcRegister.SwizzleZ = TGSI_SWIZZLE_Y;
00316       newInst.FullSrcRegisters[0].SrcRegister.SwizzleW = TGSI_SWIZZLE_Y;
00317       newInst.FullSrcRegisters[0].SrcRegister.Negate = 1;
00318       ctx->emit_instruction(ctx, &newInst);
00319 
00320 
00321       /* compute coverage factor = (1-d)/(1-k) */
00322 
00323       /* SUB t0.z, tex.w, tex.z;  # m = 1 - k */
00324       newInst = tgsi_default_full_instruction();
00325       newInst.Instruction.Opcode = TGSI_OPCODE_SUB;
00326       newInst.Instruction.NumDstRegs = 1;
00327       newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY;
00328       newInst.FullDstRegisters[0].DstRegister.Index = tmp0;
00329       newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_Z;
00330       newInst.Instruction.NumSrcRegs = 2;
00331       newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_INPUT;
00332       newInst.FullSrcRegisters[0].SrcRegister.Index = texInput;
00333       newInst.FullSrcRegisters[0].SrcRegister.SwizzleZ = TGSI_SWIZZLE_W;
00334       newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_INPUT;
00335       newInst.FullSrcRegisters[1].SrcRegister.Index = texInput;
00336       newInst.FullSrcRegisters[1].SrcRegister.SwizzleZ = TGSI_SWIZZLE_Z;
00337       ctx->emit_instruction(ctx, &newInst);
00338 
00339       /* RCP t0.z, t0.z;  # t0.z = 1 / m */
00340       newInst = tgsi_default_full_instruction();
00341       newInst.Instruction.Opcode = TGSI_OPCODE_RCP;
00342       newInst.Instruction.NumDstRegs = 1;
00343       newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY;
00344       newInst.FullDstRegisters[0].DstRegister.Index = tmp0;
00345       newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_Z;
00346       newInst.Instruction.NumSrcRegs = 1;
00347       newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY;
00348       newInst.FullSrcRegisters[0].SrcRegister.Index = tmp0;
00349       newInst.FullSrcRegisters[0].SrcRegister.SwizzleX = TGSI_SWIZZLE_Z;
00350       ctx->emit_instruction(ctx, &newInst);
00351 
00352       /* SUB t0.y, 1, t0.x;  # d = 1 - d */
00353       newInst = tgsi_default_full_instruction();
00354       newInst.Instruction.Opcode = TGSI_OPCODE_SUB;
00355       newInst.Instruction.NumDstRegs = 1;
00356       newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY;
00357       newInst.FullDstRegisters[0].DstRegister.Index = tmp0;
00358       newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_Y;
00359       newInst.Instruction.NumSrcRegs = 2;
00360       newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_INPUT;
00361       newInst.FullSrcRegisters[0].SrcRegister.Index = texInput;
00362       newInst.FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_W;
00363       newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_TEMPORARY;
00364       newInst.FullSrcRegisters[1].SrcRegister.Index = tmp0;
00365       newInst.FullSrcRegisters[1].SrcRegister.SwizzleY = TGSI_SWIZZLE_X;
00366       ctx->emit_instruction(ctx, &newInst);
00367 
00368       /* MUL t0.w, t0.y, t0.z;   # coverage = d * m */
00369       newInst = tgsi_default_full_instruction();
00370       newInst.Instruction.Opcode = TGSI_OPCODE_MUL;
00371       newInst.Instruction.NumDstRegs = 1;
00372       newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY;
00373       newInst.FullDstRegisters[0].DstRegister.Index = tmp0;
00374       newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_W;
00375       newInst.Instruction.NumSrcRegs = 2;
00376       newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY;
00377       newInst.FullSrcRegisters[0].SrcRegister.Index = tmp0;
00378       newInst.FullSrcRegisters[0].SrcRegister.SwizzleW = TGSI_SWIZZLE_Y;
00379       newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_TEMPORARY;
00380       newInst.FullSrcRegisters[1].SrcRegister.Index = tmp0;
00381       newInst.FullSrcRegisters[1].SrcRegister.SwizzleW = TGSI_SWIZZLE_Z;
00382       ctx->emit_instruction(ctx, &newInst);
00383 
00384       /* SLE t0.y, t0.x, tex.z;  # bool b = distance <= k */
00385       newInst = tgsi_default_full_instruction();
00386       newInst.Instruction.Opcode = TGSI_OPCODE_SLE;
00387       newInst.Instruction.NumDstRegs = 1;
00388       newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY;
00389       newInst.FullDstRegisters[0].DstRegister.Index = tmp0;
00390       newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_Y;
00391       newInst.Instruction.NumSrcRegs = 2;
00392       newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY;
00393       newInst.FullSrcRegisters[0].SrcRegister.Index = tmp0;
00394       newInst.FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_X;
00395       newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_INPUT;
00396       newInst.FullSrcRegisters[1].SrcRegister.Index = texInput;
00397       newInst.FullSrcRegisters[1].SrcRegister.SwizzleY = TGSI_SWIZZLE_Z;
00398       ctx->emit_instruction(ctx, &newInst);
00399 
00400       /* CMP t0.w, -t0.y, tex.w, t0.w;
00401        *  # if -t0.y < 0 then
00402        *       t0.w = 1
00403        *    else
00404        *       t0.w = t0.w
00405        */
00406       newInst = tgsi_default_full_instruction();
00407       newInst.Instruction.Opcode = TGSI_OPCODE_CMP;
00408       newInst.Instruction.NumDstRegs = 1;
00409       newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY;
00410       newInst.FullDstRegisters[0].DstRegister.Index = tmp0;
00411       newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_W;
00412       newInst.Instruction.NumSrcRegs = 3;
00413       newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY;
00414       newInst.FullSrcRegisters[0].SrcRegister.Index = tmp0;
00415       newInst.FullSrcRegisters[0].SrcRegister.SwizzleX = TGSI_SWIZZLE_Y;
00416       newInst.FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_Y;
00417       newInst.FullSrcRegisters[0].SrcRegister.SwizzleZ = TGSI_SWIZZLE_Y;
00418       newInst.FullSrcRegisters[0].SrcRegister.SwizzleW = TGSI_SWIZZLE_Y;
00419       newInst.FullSrcRegisters[0].SrcRegister.Negate = 1;
00420       newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_INPUT;
00421       newInst.FullSrcRegisters[1].SrcRegister.Index = texInput;
00422       newInst.FullSrcRegisters[1].SrcRegister.SwizzleX = TGSI_SWIZZLE_W;
00423       newInst.FullSrcRegisters[1].SrcRegister.SwizzleY = TGSI_SWIZZLE_W;
00424       newInst.FullSrcRegisters[1].SrcRegister.SwizzleZ = TGSI_SWIZZLE_W;
00425       newInst.FullSrcRegisters[1].SrcRegister.SwizzleW = TGSI_SWIZZLE_W;
00426       newInst.FullSrcRegisters[2].SrcRegister.File = TGSI_FILE_TEMPORARY;
00427       newInst.FullSrcRegisters[2].SrcRegister.Index = tmp0;
00428       newInst.FullSrcRegisters[2].SrcRegister.SwizzleX = TGSI_SWIZZLE_W;
00429       newInst.FullSrcRegisters[2].SrcRegister.SwizzleY = TGSI_SWIZZLE_W;
00430       newInst.FullSrcRegisters[2].SrcRegister.SwizzleZ = TGSI_SWIZZLE_W;
00431       newInst.FullSrcRegisters[2].SrcRegister.SwizzleW = TGSI_SWIZZLE_W;
00432       ctx->emit_instruction(ctx, &newInst);
00433 
00434    }
00435 
00436    if (inst->Instruction.Opcode == TGSI_OPCODE_END) {
00437       /* add alpha modulation code at tail of program */
00438 
00439       /* MOV result.color.xyz, colorTemp; */
00440       newInst = tgsi_default_full_instruction();
00441       newInst.Instruction.Opcode = TGSI_OPCODE_MOV;
00442       newInst.Instruction.NumDstRegs = 1;
00443       newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_OUTPUT;
00444       newInst.FullDstRegisters[0].DstRegister.Index = aactx->colorOutput;
00445       newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_XYZ;
00446       newInst.Instruction.NumSrcRegs = 1;
00447       newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY;
00448       newInst.FullSrcRegisters[0].SrcRegister.Index = aactx->colorTemp;
00449       ctx->emit_instruction(ctx, &newInst);
00450 
00451       /* MUL result.color.w, colorTemp, tmp0.w; */
00452       newInst = tgsi_default_full_instruction();
00453       newInst.Instruction.Opcode = TGSI_OPCODE_MUL;
00454       newInst.Instruction.NumDstRegs = 1;
00455       newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_OUTPUT;
00456       newInst.FullDstRegisters[0].DstRegister.Index = aactx->colorOutput;
00457       newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_W;
00458       newInst.Instruction.NumSrcRegs = 2;
00459       newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY;
00460       newInst.FullSrcRegisters[0].SrcRegister.Index = aactx->colorTemp;
00461       newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_TEMPORARY;
00462       newInst.FullSrcRegisters[1].SrcRegister.Index = aactx->tmp0;
00463       ctx->emit_instruction(ctx, &newInst);
00464    }
00465    else {
00466       /* Not an END instruction.
00467        * Look for writes to result.color and replace with colorTemp reg.
00468        */
00469       uint i;
00470 
00471       for (i = 0; i < inst->Instruction.NumDstRegs; i++) {
00472          struct tgsi_full_dst_register *dst = &inst->FullDstRegisters[i];
00473          if (dst->DstRegister.File == TGSI_FILE_OUTPUT &&
00474              dst->DstRegister.Index == aactx->colorOutput) {
00475             dst->DstRegister.File = TGSI_FILE_TEMPORARY;
00476             dst->DstRegister.Index = aactx->colorTemp;
00477          }
00478       }
00479    }
00480 
00481    ctx->emit_instruction(ctx, inst);
00482 }

static void aapoint_bind_fs_state ( struct pipe_context pipe,
void *  fs 
) [static]

Definition at line 810 of file draw_pipe_aapoint.c.

References aapoint_stage_from_pipe(), aapoint_stage::driver_bind_fs_state, aapoint_fragment_shader::driver_fs, aapoint_stage::fs, and aapoint_stage::pipe.

00812 {
00813    struct aapoint_stage *aapoint = aapoint_stage_from_pipe(pipe);
00814    struct aapoint_fragment_shader *aafs = (struct aapoint_fragment_shader *) fs;
00815    /* save current */
00816    aapoint->fs = aafs;
00817    /* pass-through */
00818    aapoint->driver_bind_fs_state(aapoint->pipe,
00819                                  (aafs ? aafs->driver_fs : NULL));

static void* aapoint_create_fs_state ( struct pipe_context pipe,
const struct pipe_shader_state fs 
) [static]

This function overrides the driver's create_fs_state() function and will typically be called by the state tracker.

Definition at line 792 of file draw_pipe_aapoint.c.

References aapoint_stage_from_pipe(), CALLOC_STRUCT, aapoint_stage::driver_create_fs_state, aapoint_fragment_shader::driver_fs, aapoint_stage::pipe, and aapoint_fragment_shader::state.

00795 {
00796    struct aapoint_stage *aapoint = aapoint_stage_from_pipe(pipe);
00797    struct aapoint_fragment_shader *aafs = CALLOC_STRUCT(aapoint_fragment_shader);
00798    if (aafs == NULL) 
00799       return NULL;
00800 
00801    aafs->state = *fs;
00802 
00803    /* pass-through */
00804    aafs->driver_fs = aapoint->driver_create_fs_state(aapoint->pipe, fs);
00805 
00806    return aafs;

static void aapoint_delete_fs_state ( struct pipe_context pipe,
void *  fs 
) [static]

Definition at line 823 of file draw_pipe_aapoint.c.

References aapoint_stage_from_pipe(), aapoint_stage::driver_delete_fs_state, aapoint_fragment_shader::driver_fs, FREE, and aapoint_stage::pipe.

00825 {
00826    struct aapoint_stage *aapoint = aapoint_stage_from_pipe(pipe);
00827    struct aapoint_fragment_shader *aafs = (struct aapoint_fragment_shader *) fs;
00828    /* pass-through */
00829    aapoint->driver_delete_fs_state(aapoint->pipe, aafs->driver_fs);
00830    FREE(aafs);

static void aapoint_destroy ( struct draw_stage stage  )  [static]

Definition at line 742 of file draw_pipe_aapoint.c.

References draw_free_temp_verts(), and FREE.

00744 {
00745    draw_free_temp_verts( stage );
00746    FREE( stage );

static void aapoint_first_point ( struct draw_stage stage,
struct prim_header header 
) [static]

Definition at line 668 of file draw_pipe_aapoint.c.

References aapoint_point(), aapoint_stage(), assert, bind_aapoint_fragment_shader(), draw_stage::draw, draw, draw_context::extra_vp_outputs, aapoint_stage::fs, aapoint_fragment_shader::generic_attrib, draw_vertex_shader::info, tgsi_shader_info::num_outputs, draw_context::num_vs_outputs, tgsi_shader_info::output_semantic_name, draw_stage::point, pipe_rasterizer_state::point_size, pipe_rasterizer_state::point_size_per_vertex, pipe_rasterizer_state::point_smooth, aapoint_stage::pos_slot, draw_context::position_output, aapoint_stage::psize_slot, aapoint_stage::radius, draw_context::rasterizer, draw_context::semantic_index, draw_context::semantic_name, draw_context::slot, aapoint_stage::tex_slot, TGSI_SEMANTIC_GENERIC, TGSI_SEMANTIC_PSIZE, draw_context::vertex_shader, and draw_context::vs.

00670 {
00671    auto struct aapoint_stage *aapoint = aapoint_stage(stage);
00672    struct draw_context *draw = stage->draw;
00673 
00674    assert(draw->rasterizer->point_smooth);
00675 
00676    if (draw->rasterizer->point_size <= 2.0)
00677       aapoint->radius = 1.0;
00678    else
00679       aapoint->radius = 0.5f * draw->rasterizer->point_size;
00680 
00681    /*
00682     * Bind (generate) our fragprog.
00683     */
00684    bind_aapoint_fragment_shader(aapoint);
00685 
00686    /* update vertex attrib info */
00687    aapoint->tex_slot = draw->vs.num_vs_outputs;
00688    assert(aapoint->tex_slot > 0); /* output[0] is vertex pos */
00689 
00690    aapoint->pos_slot = draw->vs.position_output;
00691 
00692    draw->extra_vp_outputs.semantic_name = TGSI_SEMANTIC_GENERIC;
00693    draw->extra_vp_outputs.semantic_index = aapoint->fs->generic_attrib;
00694    draw->extra_vp_outputs.slot = aapoint->tex_slot;
00695 
00696    /* find psize slot in post-transform vertex */
00697    aapoint->psize_slot = -1;
00698    if (draw->rasterizer->point_size_per_vertex) {
00699       /* find PSIZ vertex output */
00700       const struct draw_vertex_shader *vs = draw->vs.vertex_shader;
00701       uint i;
00702       for (i = 0; i < vs->info.num_outputs; i++) {
00703          if (vs->info.output_semantic_name[i] == TGSI_SEMANTIC_PSIZE) {
00704             aapoint->psize_slot = i;
00705             break;
00706          }
00707       }
00708    }
00709 
00710    /* now really draw first point */
00711    stage->point = aapoint_point;
00712    stage->point(stage, header);

static void aapoint_flush ( struct draw_stage stage,
unsigned  flags 
) [static]

Definition at line 716 of file draw_pipe_aapoint.c.

References aapoint_first_point(), aapoint_stage(), draw_stage::draw, draw, aapoint_stage::driver_bind_fs_state, aapoint_fragment_shader::driver_fs, draw_context::extra_vp_outputs, FALSE, draw_stage::flush, aapoint_stage::fs, draw_stage::next, aapoint_stage::pipe, draw_stage::point, draw_context::slot, draw_context::suspend_flushing, and TRUE.

00718 {
00719    struct draw_context *draw = stage->draw;
00720    struct aapoint_stage *aapoint = aapoint_stage(stage);
00721    struct pipe_context *pipe = aapoint->pipe;
00722 
00723    stage->point = aapoint_first_point;
00724    stage->next->flush( stage->next, flags );
00725 
00726    /* restore original frag shader */
00727    draw->suspend_flushing = TRUE;
00728    aapoint->driver_bind_fs_state(pipe, aapoint->fs->driver_fs);
00729    draw->suspend_flushing = FALSE;
00730 
00731    draw->extra_vp_outputs.slot = 0;

static void aapoint_point ( struct draw_stage stage,
struct prim_header header 
) [static]

Draw an AA point by drawing a quad.

Definition at line 570 of file draw_pipe_aapoint.c.

References aapoint_stage(), ASSIGN_4V, vertex_header::data, dup_vert(), draw_stage::next, aapoint_stage::pos_slot, aapoint_stage::psize_slot, aapoint_stage::radius, aapoint_stage::tex_slot, draw_stage::tri, and prim_header::v.

00571 {
00572    const struct aapoint_stage *aapoint = aapoint_stage(stage);
00573    struct prim_header tri;
00574    struct vertex_header *v[4];
00575    uint texPos = aapoint->tex_slot;
00576    uint pos_slot = aapoint->pos_slot;
00577    float radius, *pos, *tex;
00578    uint i;
00579    float k;
00580 
00581    if (aapoint->psize_slot >= 0) {
00582       radius = 0.5f * header->v[0]->data[aapoint->psize_slot][0];
00583    }
00584    else {
00585       radius = aapoint->radius;
00586    }
00587 
00588    /*
00589     * Note: the texcoords (generic attrib, really) we use are special:
00590     * The S and T components simply vary from -1 to +1.
00591     * The R component is k, below.
00592     * The Q component is 1.0 and will used as a handy constant in the
00593     * fragment shader.
00594     */
00595 
00596    /*
00597     * k is the threshold distance from the point's center at which
00598     * we begin alpha attenuation (the coverage value).
00599     * Operating within a unit circle, we'll compute the fragment's
00600     * distance 'd' from the center point using the texcoords.
00601     * IF d > 1.0 THEN
00602     *    KILL fragment
00603     * ELSE IF d > k THEN
00604     *    compute coverage in [0,1] proportional to d in [k, 1].
00605     * ELSE
00606     *    coverage = 1.0;  // full coverage
00607     * ENDIF
00608     *
00609     * Note: the ELSEIF and ELSE clauses are actually implemented with CMP to
00610     * avoid using IF/ELSE/ENDIF TGSI opcodes.
00611     */
00612 
00613 #if !NORMALIZE
00614    k = 1.0f / radius;
00615    k = 1.0f - 2.0f * k + k * k;
00616 #else
00617    k = 1.0f - 1.0f / radius;
00618 #endif
00619 
00620    /* allocate/dup new verts */
00621    for (i = 0; i < 4; i++) {
00622       v[i] = dup_vert(stage, header->v[0], i);
00623    }
00624 
00625    /* new verts */
00626    pos = v[0]->data[pos_slot];
00627    pos[0] -= radius;
00628    pos[1] -= radius;
00629 
00630    pos = v[1]->data[pos_slot];
00631    pos[0] += radius;
00632    pos[1] -= radius;
00633 
00634    pos = v[2]->data[pos_slot];
00635    pos[0] += radius;
00636    pos[1] += radius;
00637 
00638    pos = v[3]->data[pos_slot];
00639    pos[0] -= radius;
00640    pos[1] += radius;
00641 
00642    /* new texcoords */
00643    tex = v[0]->data[texPos];
00644    ASSIGN_4V(tex, -1, -1, k, 1);
00645 
00646    tex = v[1]->data[texPos];
00647    ASSIGN_4V(tex,  1, -1, k, 1);
00648 
00649    tex = v[2]->data[texPos];
00650    ASSIGN_4V(tex,  1,  1, k, 1);
00651 
00652    tex = v[3]->data[texPos];
00653    ASSIGN_4V(tex, -1,  1, k, 1);
00654 
00655    /* emit 2 tris for the quad strip */
00656    tri.v[0] = v[0];
00657    tri.v[1] = v[1];
00658    tri.v[2] = v[2];
00659    stage->next->tri( stage->next, &tri );
00660 
00661    tri.v[0] = v[0];
00662    tri.v[1] = v[2];
00663    tri.v[2] = v[3];
00664    stage->next->tri( stage->next, &tri );

static void aapoint_reset_stipple_counter ( struct draw_stage stage  )  [static]

Definition at line 735 of file draw_pipe_aapoint.c.

References draw_stage::next, and draw_stage::reset_stipple_counter.

00737 {
00738    stage->next->reset_stipple_counter( stage->next );

static struct aapoint_stage* aapoint_stage ( struct draw_stage stage  )  [static, read]

Definition at line 558 of file draw_pipe_aapoint.c.

00559 {
00560    return (struct aapoint_stage *) stage;
00561 }

static struct aapoint_stage* aapoint_stage_from_pipe ( struct pipe_context pipe  )  [static, read]

Definition at line 780 of file draw_pipe_aapoint.c.

References draw_context::aapoint, pipe_context::draw, draw, and draw_context::pipeline.

00782 {
00783    struct draw_context *draw = (struct draw_context *) pipe->draw;
00784    return aapoint_stage(draw->pipeline.aapoint);

static boolean bind_aapoint_fragment_shader ( struct aapoint_stage aapoint  )  [static]

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.

Definition at line 540 of file draw_pipe_aapoint.c.

References aapoint_fragment_shader::aapoint_fs, draw_stage::draw, draw, aapoint_stage::driver_bind_fs_state, FALSE, aapoint_stage::fs, generate_aapoint_fs(), aapoint_stage::pipe, aapoint_stage::stage, draw_context::suspend_flushing, and TRUE.

00541 {
00542    struct draw_context *draw = aapoint->stage.draw;
00543 
00544    if (!aapoint->fs->aapoint_fs &&
00545        !generate_aapoint_fs(aapoint))
00546       return FALSE;
00547 
00548    draw->suspend_flushing = TRUE;
00549    aapoint->driver_bind_fs_state(aapoint->pipe, aapoint->fs->aapoint_fs);
00550    draw->suspend_flushing = FALSE;
00551 
00552    return TRUE;
00553 }

static struct aapoint_stage* draw_aapoint_stage ( struct draw_context draw  )  [static, read]

Definition at line 750 of file draw_pipe_aapoint.c.

References aapoint_destroy(), aapoint_first_point(), aapoint_flush(), aapoint_reset_stipple_counter(), CALLOC_STRUCT, draw_stage::destroy, draw_stage::draw, draw_alloc_temp_verts(), draw_pipe_passthrough_line(), draw_pipe_passthrough_tri(), draw_stage::flush, draw_stage::line, draw_stage::next, draw_stage::point, draw_stage::reset_stipple_counter, aapoint_stage::stage, and draw_stage::tri.

00752 {
00753    struct aapoint_stage *aapoint = CALLOC_STRUCT(aapoint_stage);
00754    if (aapoint == NULL)
00755       goto fail;
00756 
00757    if (!draw_alloc_temp_verts( &aapoint->stage, 4 ))
00758       goto fail;
00759 
00760    aapoint->stage.draw = draw;
00761    aapoint->stage.next = NULL;
00762    aapoint->stage.point = aapoint_first_point;
00763    aapoint->stage.line = draw_pipe_passthrough_line;
00764    aapoint->stage.tri = draw_pipe_passthrough_tri;
00765    aapoint->stage.flush = aapoint_flush;
00766    aapoint->stage.reset_stipple_counter = aapoint_reset_stipple_counter;
00767    aapoint->stage.destroy = aapoint_destroy;
00768 
00769    return aapoint;
00770 
00771  fail:
00772    if (aapoint)
00773       aapoint_destroy(&aapoint->stage);
00774 
00775    return NULL;
00776 

boolean draw_install_aapoint_stage ( struct draw_context draw,
struct pipe_context pipe 
)

Called by drivers that want to install this AA point prim stage into the draw module's pipeline.

This will not be used if the hardware has native support for AA points.

Definition at line 839 of file draw_pipe_aapoint.c.

References draw_context::aapoint, aapoint_bind_fs_state(), aapoint_create_fs_state(), aapoint_delete_fs_state(), pipe_context::bind_fs_state, pipe_context::create_fs_state, pipe_context::delete_fs_state, draw_stage::destroy, pipe_context::draw, draw_aapoint_stage(), aapoint_stage::driver_bind_fs_state, aapoint_stage::driver_create_fs_state, aapoint_stage::driver_delete_fs_state, FALSE, aapoint_stage::pipe, draw_context::pipeline, aapoint_stage::stage, and TRUE.

00842 {
00843    struct aapoint_stage *aapoint;
00844 
00845    pipe->draw = (void *) draw;
00846 
00847    /*
00848     * Create / install AA point drawing / prim stage
00849     */
00850    aapoint = draw_aapoint_stage( draw );
00851    if (aapoint == NULL)
00852       goto fail;
00853 
00854    aapoint->pipe = pipe;
00855 
00856    /* save original driver functions */
00857    aapoint->driver_create_fs_state = pipe->create_fs_state;
00858    aapoint->driver_bind_fs_state = pipe->bind_fs_state;
00859    aapoint->driver_delete_fs_state = pipe->delete_fs_state;
00860 
00861    /* override the driver's functions */
00862    pipe->create_fs_state = aapoint_create_fs_state;
00863    pipe->bind_fs_state = aapoint_bind_fs_state;
00864    pipe->delete_fs_state = aapoint_delete_fs_state;
00865 
00866    draw->pipeline.aapoint = &aapoint->stage;
00867 
00868    return TRUE;
00869 
00870  fail:
00871    if (aapoint)
00872       aapoint->stage.destroy( &aapoint->stage );
00873 
00874    return FALSE;

static boolean generate_aapoint_fs ( struct aapoint_stage aapoint  )  [static]

Generate the frag shader we'll use for drawing AA points.

This will be the user's shader plus some texture/modulate instructions.

Definition at line 490 of file draw_pipe_aapoint.c.

References aa_transform_decl(), aa_transform_inst(), aapoint_fragment_shader::aapoint_fs, aa_transform_context::base, aa_transform_context::colorOutput, aa_transform_context::colorTemp, aapoint_stage::driver_create_fs_state, FALSE, aa_transform_context::firstInstruction, aapoint_stage::fs, aapoint_fragment_shader::generic_attrib, MALLOC, MAX, aa_transform_context::maxGeneric, aa_transform_context::maxInput, aapoint_stage::pipe, aapoint_fragment_shader::state, tgsi_dump(), tgsi_transform_shader(), aa_transform_context::tmp0, pipe_shader_state::tokens, tgsi_transform_context::transform_declaration, tgsi_transform_context::transform_instruction, and TRUE.

00491 {
00492    const struct pipe_shader_state *orig_fs = &aapoint->fs->state;
00493    struct pipe_shader_state aapoint_fs;
00494    struct aa_transform_context transform;
00495 
00496 #define MAX 1000
00497 
00498    aapoint_fs = *orig_fs; /* copy to init */
00499    aapoint_fs.tokens = MALLOC(sizeof(struct tgsi_token) * MAX);
00500    if (aapoint_fs.tokens == NULL)
00501       return FALSE;
00502 
00503    memset(&transform, 0, sizeof(transform));
00504    transform.colorOutput = -1;
00505    transform.maxInput = -1;
00506    transform.maxGeneric = -1;
00507    transform.colorTemp = -1;
00508    transform.tmp0 = -1;
00509    transform.firstInstruction = TRUE;
00510    transform.base.transform_instruction = aa_transform_inst;
00511    transform.base.transform_declaration = aa_transform_decl;
00512 
00513    tgsi_transform_shader(orig_fs->tokens,
00514                          (struct tgsi_token *) aapoint_fs.tokens,
00515                          MAX, &transform.base);
00516 
00517 #if 0 /* DEBUG */
00518    printf("draw_aapoint, orig shader:\n");
00519    tgsi_dump(orig_fs->tokens, 0);
00520    printf("draw_aapoint, new shader:\n");
00521    tgsi_dump(aapoint_fs.tokens, 0);
00522 #endif
00523 
00524    aapoint->fs->aapoint_fs
00525       = aapoint->driver_create_fs_state(aapoint->pipe, &aapoint_fs);
00526    if (aapoint->fs->aapoint_fs == NULL)
00527       return FALSE;
00528 
00529    aapoint->fs->generic_attrib = transform.maxGeneric + 1;
00530 
00531    return TRUE;
00532 }


Generated on Tue Sep 29 06:25:19 2009 for Gallium3D by  doxygen 1.5.4