00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00041 #include "pipe/p_inlines.h"
00042 #include "pipe/p_context.h"
00043 #include "pipe/p_defines.h"
00044 #include "pipe/p_shader_tokens.h"
00045
00046 #include "tgsi/tgsi_transform.h"
00047 #include "tgsi/tgsi_dump.h"
00048
00049 #include "util/u_math.h"
00050 #include "util/u_memory.h"
00051
00052 #include "draw_context.h"
00053 #include "draw_vs.h"
00054 #include "draw_pipe.h"
00055
00056
00057
00058
00059
00060
00061
00062
00063 #define NORMALIZE 0
00064
00065
00069 struct aapoint_fragment_shader
00070 {
00071 struct pipe_shader_state state;
00072 void *driver_fs;
00073 void *aapoint_fs;
00074 int generic_attrib;
00075 };
00076
00077
00081 struct aapoint_stage
00082 {
00083 struct draw_stage stage;
00084
00085 int psize_slot;
00086 float radius;
00087
00089 uint tex_slot;
00090 uint pos_slot;
00091
00092
00093
00094
00095 struct aapoint_fragment_shader *fs;
00096
00097
00098
00099
00100 void * (*driver_create_fs_state)(struct pipe_context *,
00101 const struct pipe_shader_state *);
00102 void (*driver_bind_fs_state)(struct pipe_context *, void *);
00103 void (*driver_delete_fs_state)(struct pipe_context *, void *);
00104
00105 struct pipe_context *pipe;
00106 };
00107
00108
00109
00114 struct aa_transform_context {
00115 struct tgsi_transform_context base;
00116 uint tempsUsed;
00117 int colorOutput;
00118 int maxInput, maxGeneric;
00119 int tmp0, colorTemp;
00120 boolean firstInstruction;
00121 };
00122
00123
00128 static void
00129 aa_transform_decl(struct tgsi_transform_context *ctx,
00130 struct tgsi_full_declaration *decl)
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 }
00157
00158
00164 static void
00165 aa_transform_inst(struct tgsi_transform_context *ctx,
00166 struct tgsi_full_instruction *inst)
00167 {
00168 struct aa_transform_context *aactx = (struct aa_transform_context *) ctx;
00169 struct tgsi_full_instruction newInst;
00170
00171 if (aactx->firstInstruction) {
00172
00173
00174 struct tgsi_full_declaration decl;
00175 const int texInput = aactx->maxInput + 1;
00176 int tmp0;
00177 uint i;
00178
00179
00180 for (i = 0; i < 32; i++) {
00181 if ((aactx->tempsUsed & (1 << i)) == 0) {
00182
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
00197 decl = tgsi_default_full_declaration();
00198 decl.Declaration.File = TGSI_FILE_INPUT;
00199
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
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
00226
00227
00228
00229
00230
00231
00232
00233
00234
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
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
00265
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
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
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
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
00322
00323
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
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
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
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
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
00401
00402
00403
00404
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
00438
00439
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
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
00467
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 }
00483
00484
00489 static boolean
00490 generate_aapoint_fs(struct aapoint_stage *aapoint)
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;
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
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 }
00533
00534
00539 static boolean
00540 bind_aapoint_fragment_shader(struct aapoint_stage *aapoint)
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 }
00554
00555
00556
00557 static INLINE struct aapoint_stage *
00558 aapoint_stage( struct draw_stage *stage )
00559 {
00560 return (struct aapoint_stage *) stage;
00561 }
00562
00563
00564
00565
00569 static void
00570 aapoint_point(struct draw_stage *stage, struct prim_header *header)
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
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610
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
00621 for (i = 0; i < 4; i++) {
00622 v[i] = dup_vert(stage, header->v[0], i);
00623 }
00624
00625
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
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
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 );
00665 }
00666
00667
00668 static void
00669 aapoint_first_point(struct draw_stage *stage, struct prim_header *header)
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
00683
00684 bind_aapoint_fragment_shader(aapoint);
00685
00686
00687 aapoint->tex_slot = draw->vs.num_vs_outputs;
00688 assert(aapoint->tex_slot > 0);
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
00697 aapoint->psize_slot = -1;
00698 if (draw->rasterizer->point_size_per_vertex) {
00699
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
00711 stage->point = aapoint_point;
00712 stage->point(stage, header);
00713 }
00714
00715
00716 static void
00717 aapoint_flush(struct draw_stage *stage, unsigned flags)
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
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;
00732 }
00733
00734
00735 static void
00736 aapoint_reset_stipple_counter(struct draw_stage *stage)
00737 {
00738 stage->next->reset_stipple_counter( stage->next );
00739 }
00740
00741
00742 static void
00743 aapoint_destroy(struct draw_stage *stage)
00744 {
00745 draw_free_temp_verts( stage );
00746 FREE( stage );
00747 }
00748
00749
00750 static struct aapoint_stage *
00751 draw_aapoint_stage(struct draw_context *draw)
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
00777 }
00778
00779
00780 static struct aapoint_stage *
00781 aapoint_stage_from_pipe(struct pipe_context *pipe)
00782 {
00783 struct draw_context *draw = (struct draw_context *) pipe->draw;
00784 return aapoint_stage(draw->pipeline.aapoint);
00785 }
00786
00787
00792 static void *
00793 aapoint_create_fs_state(struct pipe_context *pipe,
00794 const struct pipe_shader_state *fs)
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
00804 aafs->driver_fs = aapoint->driver_create_fs_state(aapoint->pipe, fs);
00805
00806 return aafs;
00807 }
00808
00809
00810 static void
00811 aapoint_bind_fs_state(struct pipe_context *pipe, void *fs)
00812 {
00813 struct aapoint_stage *aapoint = aapoint_stage_from_pipe(pipe);
00814 struct aapoint_fragment_shader *aafs = (struct aapoint_fragment_shader *) fs;
00815
00816 aapoint->fs = aafs;
00817
00818 aapoint->driver_bind_fs_state(aapoint->pipe,
00819 (aafs ? aafs->driver_fs : NULL));
00820 }
00821
00822
00823 static void
00824 aapoint_delete_fs_state(struct pipe_context *pipe, void *fs)
00825 {
00826 struct aapoint_stage *aapoint = aapoint_stage_from_pipe(pipe);
00827 struct aapoint_fragment_shader *aafs = (struct aapoint_fragment_shader *) fs;
00828
00829 aapoint->driver_delete_fs_state(aapoint->pipe, aafs->driver_fs);
00830 FREE(aafs);
00831 }
00832
00833
00839 boolean
00840 draw_install_aapoint_stage(struct draw_context *draw,
00841 struct pipe_context *pipe)
00842 {
00843 struct aapoint_stage *aapoint;
00844
00845 pipe->draw = (void *) draw;
00846
00847
00848
00849
00850 aapoint = draw_aapoint_stage( draw );
00851 if (aapoint == NULL)
00852 goto fail;
00853
00854 aapoint->pipe = pipe;
00855
00856
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
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;
00875 }