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
00035 #include "pipe/p_inlines.h"
00036 #include "pipe/p_context.h"
00037 #include "pipe/p_defines.h"
00038 #include "pipe/p_shader_tokens.h"
00039 #include "util/u_math.h"
00040 #include "util/u_memory.h"
00041
00042 #include "tgsi/tgsi_transform.h"
00043 #include "tgsi/tgsi_dump.h"
00044
00045 #include "draw_context.h"
00046 #include "draw_private.h"
00047 #include "draw_pipe.h"
00048
00049
00053 #define MAX_TEXTURE_LEVEL 5
00054
00055
00059 struct aaline_fragment_shader
00060 {
00061 struct pipe_shader_state state;
00062 void *driver_fs;
00063 void *aaline_fs;
00064 void *aapoint_fs;
00065 void *sprite_fs;
00066 uint sampler_unit;
00067 int generic_attrib;
00068 };
00069
00070
00074 struct aaline_stage
00075 {
00076 struct draw_stage stage;
00077
00078 float half_line_width;
00079
00081 uint tex_slot;
00083 uint pos_slot;
00084
00085 void *sampler_cso;
00086 struct pipe_texture *texture;
00087 uint num_samplers;
00088 uint num_textures;
00089
00090
00091
00092
00093
00094 struct aaline_fragment_shader *fs;
00095 struct {
00096 void *sampler[PIPE_MAX_SAMPLERS];
00097 struct pipe_texture *texture[PIPE_MAX_SAMPLERS];
00098 } state;
00099
00100
00101
00102
00103 void * (*driver_create_fs_state)(struct pipe_context *,
00104 const struct pipe_shader_state *);
00105 void (*driver_bind_fs_state)(struct pipe_context *, void *);
00106 void (*driver_delete_fs_state)(struct pipe_context *, void *);
00107
00108 void (*driver_bind_sampler_states)(struct pipe_context *, unsigned,
00109 void **);
00110 void (*driver_set_sampler_textures)(struct pipe_context *, unsigned,
00111 struct pipe_texture **);
00112
00113 struct pipe_context *pipe;
00114 };
00115
00116
00117
00122 struct aa_transform_context {
00123 struct tgsi_transform_context base;
00124 uint tempsUsed;
00125 int colorOutput;
00126 uint samplersUsed;
00127 int freeSampler;
00128 int maxInput, maxGeneric;
00129 int colorTemp, texTemp;
00130 boolean firstInstruction;
00131 };
00132
00133
00138 static void
00139 aa_transform_decl(struct tgsi_transform_context *ctx,
00140 struct tgsi_full_declaration *decl)
00141 {
00142 struct aa_transform_context *aactx = (struct aa_transform_context *) ctx;
00143
00144 if (decl->Declaration.File == TGSI_FILE_OUTPUT &&
00145 decl->Semantic.SemanticName == TGSI_SEMANTIC_COLOR &&
00146 decl->Semantic.SemanticIndex == 0) {
00147 aactx->colorOutput = decl->DeclarationRange.First;
00148 }
00149 else if (decl->Declaration.File == TGSI_FILE_SAMPLER) {
00150 uint i;
00151 for (i = decl->DeclarationRange.First;
00152 i <= decl->DeclarationRange.Last; i++) {
00153 aactx->samplersUsed |= 1 << i;
00154 }
00155 }
00156 else if (decl->Declaration.File == TGSI_FILE_INPUT) {
00157 if ((int) decl->DeclarationRange.Last > aactx->maxInput)
00158 aactx->maxInput = decl->DeclarationRange.Last;
00159 if (decl->Semantic.SemanticName == TGSI_SEMANTIC_GENERIC &&
00160 (int) decl->Semantic.SemanticIndex > aactx->maxGeneric) {
00161 aactx->maxGeneric = decl->Semantic.SemanticIndex;
00162 }
00163 }
00164 else if (decl->Declaration.File == TGSI_FILE_TEMPORARY) {
00165 uint i;
00166 for (i = decl->DeclarationRange.First;
00167 i <= decl->DeclarationRange.Last; i++) {
00168 aactx->tempsUsed |= (1 << i);
00169 }
00170 }
00171
00172 ctx->emit_declaration(ctx, decl);
00173 }
00174
00175
00179 static int
00180 free_bit(uint bitfield)
00181 {
00182 int i;
00183 for (i = 0; i < 32; i++) {
00184 if ((bitfield & (1 << i)) == 0)
00185 return i;
00186 }
00187 return -1;
00188 }
00189
00190
00196 static void
00197 aa_transform_inst(struct tgsi_transform_context *ctx,
00198 struct tgsi_full_instruction *inst)
00199 {
00200 struct aa_transform_context *aactx = (struct aa_transform_context *) ctx;
00201
00202 if (aactx->firstInstruction) {
00203
00204
00205 struct tgsi_full_declaration decl;
00206 uint i;
00207
00208
00209 aactx->freeSampler = free_bit(aactx->samplersUsed);
00210 if (aactx->freeSampler >= PIPE_MAX_SAMPLERS)
00211 aactx->freeSampler = PIPE_MAX_SAMPLERS - 1;
00212
00213
00214 for (i = 0; i < 32; i++) {
00215 if ((aactx->tempsUsed & (1 << i)) == 0) {
00216
00217 if (aactx->colorTemp < 0)
00218 aactx->colorTemp = i;
00219 else if (aactx->texTemp < 0)
00220 aactx->texTemp = i;
00221 else
00222 break;
00223 }
00224 }
00225 assert(aactx->colorTemp >= 0);
00226 assert(aactx->texTemp >= 0);
00227
00228
00229 decl = tgsi_default_full_declaration();
00230 decl.Declaration.File = TGSI_FILE_INPUT;
00231
00232 decl.Declaration.Interpolate = TGSI_INTERPOLATE_PERSPECTIVE;
00233 decl.Declaration.Semantic = 1;
00234 decl.Semantic.SemanticName = TGSI_SEMANTIC_GENERIC;
00235 decl.Semantic.SemanticIndex = aactx->maxGeneric + 1;
00236 decl.DeclarationRange.First =
00237 decl.DeclarationRange.Last = aactx->maxInput + 1;
00238 ctx->emit_declaration(ctx, &decl);
00239
00240
00241 decl = tgsi_default_full_declaration();
00242 decl.Declaration.File = TGSI_FILE_SAMPLER;
00243 decl.DeclarationRange.First =
00244 decl.DeclarationRange.Last = aactx->freeSampler;
00245 ctx->emit_declaration(ctx, &decl);
00246
00247
00248 decl = tgsi_default_full_declaration();
00249 decl.Declaration.File = TGSI_FILE_TEMPORARY;
00250 decl.DeclarationRange.First =
00251 decl.DeclarationRange.Last = aactx->texTemp;
00252 ctx->emit_declaration(ctx, &decl);
00253
00254 decl = tgsi_default_full_declaration();
00255 decl.Declaration.File = TGSI_FILE_TEMPORARY;
00256 decl.DeclarationRange.First =
00257 decl.DeclarationRange.Last = aactx->colorTemp;
00258 ctx->emit_declaration(ctx, &decl);
00259
00260 aactx->firstInstruction = FALSE;
00261 }
00262
00263 if (inst->Instruction.Opcode == TGSI_OPCODE_END &&
00264 aactx->colorOutput != -1) {
00265 struct tgsi_full_instruction newInst;
00266
00267
00268 newInst = tgsi_default_full_instruction();
00269 newInst.Instruction.Opcode = TGSI_OPCODE_TEX;
00270 newInst.Instruction.NumDstRegs = 1;
00271 newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY;
00272 newInst.FullDstRegisters[0].DstRegister.Index = aactx->texTemp;
00273 newInst.Instruction.NumSrcRegs = 2;
00274 newInst.InstructionExtTexture.Texture = TGSI_TEXTURE_2D;
00275 newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_INPUT;
00276 newInst.FullSrcRegisters[0].SrcRegister.Index = aactx->maxInput + 1;
00277 newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_SAMPLER;
00278 newInst.FullSrcRegisters[1].SrcRegister.Index = aactx->freeSampler;
00279
00280 ctx->emit_instruction(ctx, &newInst);
00281
00282
00283 newInst = tgsi_default_full_instruction();
00284 newInst.Instruction.Opcode = TGSI_OPCODE_MOV;
00285 newInst.Instruction.NumDstRegs = 1;
00286 newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_OUTPUT;
00287 newInst.FullDstRegisters[0].DstRegister.Index = aactx->colorOutput;
00288 newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_XYZ;
00289 newInst.Instruction.NumSrcRegs = 1;
00290 newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY;
00291 newInst.FullSrcRegisters[0].SrcRegister.Index = aactx->colorTemp;
00292 ctx->emit_instruction(ctx, &newInst);
00293
00294
00295 newInst = tgsi_default_full_instruction();
00296 newInst.Instruction.Opcode = TGSI_OPCODE_MUL;
00297 newInst.Instruction.NumDstRegs = 1;
00298 newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_OUTPUT;
00299 newInst.FullDstRegisters[0].DstRegister.Index = aactx->colorOutput;
00300 newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_W;
00301 newInst.Instruction.NumSrcRegs = 2;
00302 newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY;
00303 newInst.FullSrcRegisters[0].SrcRegister.Index = aactx->colorTemp;
00304 newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_TEMPORARY;
00305 newInst.FullSrcRegisters[1].SrcRegister.Index = aactx->texTemp;
00306 ctx->emit_instruction(ctx, &newInst);
00307
00308
00309 newInst = tgsi_default_full_instruction();
00310 newInst.Instruction.Opcode = TGSI_OPCODE_END;
00311 newInst.Instruction.NumDstRegs = 0;
00312 newInst.Instruction.NumSrcRegs = 0;
00313 ctx->emit_instruction(ctx, &newInst);
00314 }
00315 else {
00316
00317
00318
00319 uint i;
00320
00321 for (i = 0; i < inst->Instruction.NumDstRegs; i++) {
00322 struct tgsi_full_dst_register *dst = &inst->FullDstRegisters[i];
00323 if (dst->DstRegister.File == TGSI_FILE_OUTPUT &&
00324 dst->DstRegister.Index == aactx->colorOutput) {
00325 dst->DstRegister.File = TGSI_FILE_TEMPORARY;
00326 dst->DstRegister.Index = aactx->colorTemp;
00327 }
00328 }
00329
00330 ctx->emit_instruction(ctx, inst);
00331 }
00332 }
00333
00334
00339 static boolean
00340 generate_aaline_fs(struct aaline_stage *aaline)
00341 {
00342 const struct pipe_shader_state *orig_fs = &aaline->fs->state;
00343 struct pipe_shader_state aaline_fs;
00344 struct aa_transform_context transform;
00345
00346 #define MAX 1000
00347
00348 aaline_fs = *orig_fs;
00349 aaline_fs.tokens = MALLOC(sizeof(struct tgsi_token) * MAX);
00350 if (aaline_fs.tokens == NULL)
00351 return FALSE;
00352
00353 memset(&transform, 0, sizeof(transform));
00354 transform.colorOutput = -1;
00355 transform.maxInput = -1;
00356 transform.maxGeneric = -1;
00357 transform.colorTemp = -1;
00358 transform.texTemp = -1;
00359 transform.firstInstruction = TRUE;
00360 transform.base.transform_instruction = aa_transform_inst;
00361 transform.base.transform_declaration = aa_transform_decl;
00362
00363 tgsi_transform_shader(orig_fs->tokens,
00364 (struct tgsi_token *) aaline_fs.tokens,
00365 MAX, &transform.base);
00366
00367 #if 0
00368 tgsi_dump(orig_fs->tokens, 0);
00369 tgsi_dump(aaline_fs.tokens, 0);
00370 #endif
00371
00372 aaline->fs->sampler_unit = transform.freeSampler;
00373
00374 aaline->fs->aaline_fs
00375 = aaline->driver_create_fs_state(aaline->pipe, &aaline_fs);
00376 if (aaline->fs->aaline_fs == NULL)
00377 return FALSE;
00378
00379 aaline->fs->generic_attrib = transform.maxGeneric + 1;
00380 return TRUE;
00381 }
00382
00383
00387 static boolean
00388 aaline_create_texture(struct aaline_stage *aaline)
00389 {
00390 struct pipe_context *pipe = aaline->pipe;
00391 struct pipe_screen *screen = pipe->screen;
00392 struct pipe_texture texTemp;
00393 uint level;
00394
00395 memset(&texTemp, 0, sizeof(texTemp));
00396 texTemp.target = PIPE_TEXTURE_2D;
00397 texTemp.format = PIPE_FORMAT_A8_UNORM;
00398 texTemp.last_level = MAX_TEXTURE_LEVEL;
00399 texTemp.width[0] = 1 << MAX_TEXTURE_LEVEL;
00400 texTemp.height[0] = 1 << MAX_TEXTURE_LEVEL;
00401 texTemp.depth[0] = 1;
00402 pf_get_block(texTemp.format, &texTemp.block);
00403
00404 aaline->texture = screen->texture_create(screen, &texTemp);
00405 if (!aaline->texture)
00406 return FALSE;
00407
00408
00409
00410
00411
00412 for (level = 0; level <= MAX_TEXTURE_LEVEL; level++) {
00413 struct pipe_surface *surface;
00414 const uint size = aaline->texture->width[level];
00415 ubyte *data;
00416 uint i, j;
00417
00418 assert(aaline->texture->width[level] == aaline->texture->height[level]);
00419
00420
00421
00422 surface = screen->get_tex_surface(screen, aaline->texture, 0, level, 0,
00423 PIPE_BUFFER_USAGE_CPU_WRITE);
00424 data = screen->surface_map(screen, surface, PIPE_BUFFER_USAGE_CPU_WRITE);
00425 if (data == NULL)
00426 return FALSE;
00427
00428 for (i = 0; i < size; i++) {
00429 for (j = 0; j < size; j++) {
00430 ubyte d;
00431 if (size == 1) {
00432 d = 255;
00433 }
00434 else if (size == 2) {
00435 d = 200;
00436 }
00437 else if (i == 0 || j == 0 || i == size - 1 || j == size - 1) {
00438 d = 0;
00439 }
00440 else {
00441 d = 255;
00442 }
00443 data[i * surface->stride + j] = d;
00444 }
00445 }
00446
00447
00448 screen->surface_unmap(screen, surface);
00449 screen->tex_surface_release(screen, &surface);
00450 }
00451 return TRUE;
00452 }
00453
00454
00460 static boolean
00461 aaline_create_sampler(struct aaline_stage *aaline)
00462 {
00463 struct pipe_sampler_state sampler;
00464 struct pipe_context *pipe = aaline->pipe;
00465
00466 memset(&sampler, 0, sizeof(sampler));
00467 sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
00468 sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
00469 sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
00470 sampler.min_mip_filter = PIPE_TEX_MIPFILTER_LINEAR;
00471 sampler.min_img_filter = PIPE_TEX_FILTER_LINEAR;
00472 sampler.mag_img_filter = PIPE_TEX_FILTER_LINEAR;
00473 sampler.normalized_coords = 1;
00474 sampler.min_lod = 0.0f;
00475 sampler.max_lod = MAX_TEXTURE_LEVEL;
00476
00477 aaline->sampler_cso = pipe->create_sampler_state(pipe, &sampler);
00478 if (aaline->sampler_cso == NULL)
00479 return FALSE;
00480
00481 return TRUE;
00482 }
00483
00484
00489 static boolean
00490 bind_aaline_fragment_shader(struct aaline_stage *aaline)
00491 {
00492 struct draw_context *draw = aaline->stage.draw;
00493
00494 if (!aaline->fs->aaline_fs &&
00495 !generate_aaline_fs(aaline))
00496 return FALSE;
00497
00498 draw->suspend_flushing = TRUE;
00499 aaline->driver_bind_fs_state(aaline->pipe, aaline->fs->aaline_fs);
00500 draw->suspend_flushing = FALSE;
00501
00502 return TRUE;
00503 }
00504
00505
00506
00507 static INLINE struct aaline_stage *
00508 aaline_stage( struct draw_stage *stage )
00509 {
00510 return (struct aaline_stage *) stage;
00511 }
00512
00513
00518 static void
00519 aaline_line(struct draw_stage *stage, struct prim_header *header)
00520 {
00521 const struct aaline_stage *aaline = aaline_stage(stage);
00522 const float half_width = aaline->half_line_width;
00523 struct prim_header tri;
00524 struct vertex_header *v[8];
00525 uint texPos = aaline->tex_slot;
00526 uint posPos = aaline->pos_slot;
00527 float *pos, *tex;
00528 float dx = header->v[1]->data[posPos][0] - header->v[0]->data[posPos][0];
00529 float dy = header->v[1]->data[posPos][1] - header->v[0]->data[posPos][1];
00530 double a = atan2(dy, dx);
00531 float c_a = (float) cos(a), s_a = (float) sin(a);
00532 uint i;
00533
00534
00535 dx = 0.5F * half_width;
00536 dy = half_width;
00537
00538
00539 for (i = 0; i < 8; i++) {
00540 v[i] = dup_vert(stage, header->v[i/4], i);
00541 }
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556 pos = v[0]->data[posPos];
00557 pos[0] += (-dx * c_a - dy * s_a);
00558 pos[1] += (-dx * s_a + dy * c_a);
00559
00560 pos = v[1]->data[posPos];
00561 pos[0] += (-dx * c_a - -dy * s_a);
00562 pos[1] += (-dx * s_a + -dy * c_a);
00563
00564 pos = v[2]->data[posPos];
00565 pos[0] += ( dx * c_a - dy * s_a);
00566 pos[1] += ( dx * s_a + dy * c_a);
00567
00568 pos = v[3]->data[posPos];
00569 pos[0] += ( dx * c_a - -dy * s_a);
00570 pos[1] += ( dx * s_a + -dy * c_a);
00571
00572 pos = v[4]->data[posPos];
00573 pos[0] += (-dx * c_a - dy * s_a);
00574 pos[1] += (-dx * s_a + dy * c_a);
00575
00576 pos = v[5]->data[posPos];
00577 pos[0] += (-dx * c_a - -dy * s_a);
00578 pos[1] += (-dx * s_a + -dy * c_a);
00579
00580 pos = v[6]->data[posPos];
00581 pos[0] += ( dx * c_a - dy * s_a);
00582 pos[1] += ( dx * s_a + dy * c_a);
00583
00584 pos = v[7]->data[posPos];
00585 pos[0] += ( dx * c_a - -dy * s_a);
00586 pos[1] += ( dx * s_a + -dy * c_a);
00587
00588
00589 tex = v[0]->data[texPos];
00590 ASSIGN_4V(tex, 0, 0, 0, 1);
00591
00592 tex = v[1]->data[texPos];
00593 ASSIGN_4V(tex, 0, 1, 0, 1);
00594
00595 tex = v[2]->data[texPos];
00596 ASSIGN_4V(tex, .5, 0, 0, 1);
00597
00598 tex = v[3]->data[texPos];
00599 ASSIGN_4V(tex, .5, 1, 0, 1);
00600
00601 tex = v[4]->data[texPos];
00602 ASSIGN_4V(tex, .5, 0, 0, 1);
00603
00604 tex = v[5]->data[texPos];
00605 ASSIGN_4V(tex, .5, 1, 0, 1);
00606
00607 tex = v[6]->data[texPos];
00608 ASSIGN_4V(tex, 1, 0, 0, 1);
00609
00610 tex = v[7]->data[texPos];
00611 ASSIGN_4V(tex, 1, 1, 0, 1);
00612
00613
00614 tri.v[0] = v[2]; tri.v[1] = v[1]; tri.v[2] = v[0];
00615 stage->next->tri( stage->next, &tri );
00616
00617 tri.v[0] = v[3]; tri.v[1] = v[1]; tri.v[2] = v[2];
00618 stage->next->tri( stage->next, &tri );
00619
00620 tri.v[0] = v[4]; tri.v[1] = v[3]; tri.v[2] = v[2];
00621 stage->next->tri( stage->next, &tri );
00622
00623 tri.v[0] = v[5]; tri.v[1] = v[3]; tri.v[2] = v[4];
00624 stage->next->tri( stage->next, &tri );
00625
00626 tri.v[0] = v[6]; tri.v[1] = v[5]; tri.v[2] = v[4];
00627 stage->next->tri( stage->next, &tri );
00628
00629 tri.v[0] = v[7]; tri.v[1] = v[5]; tri.v[2] = v[6];
00630 stage->next->tri( stage->next, &tri );
00631 }
00632
00633
00634 static void
00635 aaline_first_line(struct draw_stage *stage, struct prim_header *header)
00636 {
00637 auto struct aaline_stage *aaline = aaline_stage(stage);
00638 struct draw_context *draw = stage->draw;
00639 struct pipe_context *pipe = aaline->pipe;
00640 uint num_samplers;
00641
00642 assert(draw->rasterizer->line_smooth);
00643
00644 if (draw->rasterizer->line_width <= 3.0)
00645 aaline->half_line_width = 1.5f;
00646 else
00647 aaline->half_line_width = 0.5f * draw->rasterizer->line_width;
00648
00649
00650
00651
00652 if (!bind_aaline_fragment_shader(aaline)) {
00653 stage->line = draw_pipe_passthrough_line;
00654 stage->line(stage, header);
00655 return;
00656 }
00657
00658
00659 aaline->tex_slot = draw->vs.num_vs_outputs;
00660 aaline->pos_slot = draw->vs.position_output;
00661
00662
00663 draw->extra_vp_outputs.semantic_name = TGSI_SEMANTIC_GENERIC;
00664 draw->extra_vp_outputs.semantic_index = aaline->fs->generic_attrib;
00665 draw->extra_vp_outputs.slot = aaline->tex_slot;
00666
00667
00668
00669 num_samplers = MAX2(aaline->num_textures, aaline->num_samplers);
00670 num_samplers = MAX2(num_samplers, aaline->fs->sampler_unit + 1);
00671
00672 aaline->state.sampler[aaline->fs->sampler_unit] = aaline->sampler_cso;
00673 pipe_texture_reference(&aaline->state.texture[aaline->fs->sampler_unit],
00674 aaline->texture);
00675
00676 draw->suspend_flushing = TRUE;
00677 aaline->driver_bind_sampler_states(pipe, num_samplers, aaline->state.sampler);
00678 aaline->driver_set_sampler_textures(pipe, num_samplers, aaline->state.texture);
00679 draw->suspend_flushing = FALSE;
00680
00681
00682 stage->line = aaline_line;
00683 stage->line(stage, header);
00684 }
00685
00686
00687 static void
00688 aaline_flush(struct draw_stage *stage, unsigned flags)
00689 {
00690 struct draw_context *draw = stage->draw;
00691 struct aaline_stage *aaline = aaline_stage(stage);
00692 struct pipe_context *pipe = aaline->pipe;
00693
00694 stage->line = aaline_first_line;
00695 stage->next->flush( stage->next, flags );
00696
00697
00698 draw->suspend_flushing = TRUE;
00699 aaline->driver_bind_fs_state(pipe, aaline->fs->driver_fs);
00700 aaline->driver_bind_sampler_states(pipe, aaline->num_samplers,
00701 aaline->state.sampler);
00702 aaline->driver_set_sampler_textures(pipe, aaline->num_textures,
00703 aaline->state.texture);
00704 draw->suspend_flushing = FALSE;
00705
00706 draw->extra_vp_outputs.slot = 0;
00707 }
00708
00709
00710 static void
00711 aaline_reset_stipple_counter(struct draw_stage *stage)
00712 {
00713 stage->next->reset_stipple_counter( stage->next );
00714 }
00715
00716
00717 static void
00718 aaline_destroy(struct draw_stage *stage)
00719 {
00720 struct aaline_stage *aaline = aaline_stage(stage);
00721 uint i;
00722
00723 for (i = 0; i < PIPE_MAX_SAMPLERS; i++) {
00724 pipe_texture_reference(&aaline->state.texture[i], NULL);
00725 }
00726
00727 if (aaline->sampler_cso)
00728 aaline->pipe->delete_sampler_state(aaline->pipe, aaline->sampler_cso);
00729
00730 if (aaline->texture)
00731 pipe_texture_release(&aaline->texture);
00732
00733 draw_free_temp_verts( stage );
00734
00735 FREE( stage );
00736 }
00737
00738
00739 static struct aaline_stage *
00740 draw_aaline_stage(struct draw_context *draw)
00741 {
00742 struct aaline_stage *aaline = CALLOC_STRUCT(aaline_stage);
00743 if (aaline == NULL)
00744 return NULL;
00745
00746 if (!draw_alloc_temp_verts( &aaline->stage, 8 ))
00747 goto fail;
00748
00749 aaline->stage.draw = draw;
00750 aaline->stage.next = NULL;
00751 aaline->stage.point = draw_pipe_passthrough_point;
00752 aaline->stage.line = aaline_first_line;
00753 aaline->stage.tri = draw_pipe_passthrough_tri;
00754 aaline->stage.flush = aaline_flush;
00755 aaline->stage.reset_stipple_counter = aaline_reset_stipple_counter;
00756 aaline->stage.destroy = aaline_destroy;
00757
00758 return aaline;
00759
00760 fail:
00761 if (aaline)
00762 aaline_destroy(&aaline->stage);
00763
00764 return NULL;
00765 }
00766
00767
00768 static struct aaline_stage *
00769 aaline_stage_from_pipe(struct pipe_context *pipe)
00770 {
00771 struct draw_context *draw = (struct draw_context *) pipe->draw;
00772 return aaline_stage(draw->pipeline.aaline);
00773 }
00774
00775
00780 static void *
00781 aaline_create_fs_state(struct pipe_context *pipe,
00782 const struct pipe_shader_state *fs)
00783 {
00784 struct aaline_stage *aaline = aaline_stage_from_pipe(pipe);
00785 struct aaline_fragment_shader *aafs = CALLOC_STRUCT(aaline_fragment_shader);
00786 if (aafs == NULL)
00787 return NULL;
00788
00789 aafs->state = *fs;
00790
00791
00792 aafs->driver_fs = aaline->driver_create_fs_state(aaline->pipe, fs);
00793
00794 return aafs;
00795 }
00796
00797
00798 static void
00799 aaline_bind_fs_state(struct pipe_context *pipe, void *fs)
00800 {
00801 struct aaline_stage *aaline = aaline_stage_from_pipe(pipe);
00802 struct aaline_fragment_shader *aafs = (struct aaline_fragment_shader *) fs;
00803
00804
00805 aaline->fs = aafs;
00806
00807 aaline->driver_bind_fs_state(aaline->pipe,
00808 (aafs ? aafs->driver_fs : NULL));
00809 }
00810
00811
00812 static void
00813 aaline_delete_fs_state(struct pipe_context *pipe, void *fs)
00814 {
00815 struct aaline_stage *aaline = aaline_stage_from_pipe(pipe);
00816 struct aaline_fragment_shader *aafs = (struct aaline_fragment_shader *) fs;
00817
00818 aaline->driver_delete_fs_state(aaline->pipe, aafs->driver_fs);
00819 FREE(aafs);
00820 }
00821
00822
00823 static void
00824 aaline_bind_sampler_states(struct pipe_context *pipe,
00825 unsigned num, void **sampler)
00826 {
00827 struct aaline_stage *aaline = aaline_stage_from_pipe(pipe);
00828
00829
00830 memcpy(aaline->state.sampler, sampler, num * sizeof(void *));
00831 aaline->num_samplers = num;
00832
00833
00834 aaline->driver_bind_sampler_states(aaline->pipe, num, sampler);
00835 }
00836
00837
00838 static void
00839 aaline_set_sampler_textures(struct pipe_context *pipe,
00840 unsigned num, struct pipe_texture **texture)
00841 {
00842 struct aaline_stage *aaline = aaline_stage_from_pipe(pipe);
00843 uint i;
00844
00845
00846 for (i = 0; i < num; i++) {
00847 pipe_texture_reference(&aaline->state.texture[i], texture[i]);
00848 }
00849 for ( ; i < PIPE_MAX_SAMPLERS; i++) {
00850 pipe_texture_reference(&aaline->state.texture[i], NULL);
00851 }
00852 aaline->num_textures = num;
00853
00854
00855 aaline->driver_set_sampler_textures(aaline->pipe, num, texture);
00856 }
00857
00858
00864 boolean
00865 draw_install_aaline_stage(struct draw_context *draw, struct pipe_context *pipe)
00866 {
00867 struct aaline_stage *aaline;
00868
00869 pipe->draw = (void *) draw;
00870
00871
00872
00873
00874 aaline = draw_aaline_stage( draw );
00875 if (!aaline)
00876 goto fail;
00877
00878 aaline->pipe = pipe;
00879
00880
00881 if (!aaline_create_texture(aaline))
00882 goto fail;
00883
00884 if (!aaline_create_sampler(aaline))
00885 goto fail;
00886
00887
00888 aaline->driver_create_fs_state = pipe->create_fs_state;
00889 aaline->driver_bind_fs_state = pipe->bind_fs_state;
00890 aaline->driver_delete_fs_state = pipe->delete_fs_state;
00891
00892 aaline->driver_bind_sampler_states = pipe->bind_sampler_states;
00893 aaline->driver_set_sampler_textures = pipe->set_sampler_textures;
00894
00895
00896 pipe->create_fs_state = aaline_create_fs_state;
00897 pipe->bind_fs_state = aaline_bind_fs_state;
00898 pipe->delete_fs_state = aaline_delete_fs_state;
00899
00900 pipe->bind_sampler_states = aaline_bind_sampler_states;
00901 pipe->set_sampler_textures = aaline_set_sampler_textures;
00902
00903
00904
00905 draw->pipeline.aaline = &aaline->stage;
00906
00907 return TRUE;
00908
00909 fail:
00910 if (aaline)
00911 aaline->stage.destroy( &aaline->stage );
00912
00913 return FALSE;
00914 }