draw_pipe_aaline.c File Reference

Include dependency graph for draw_pipe_aaline.c:

Go to the source code of this file.

Data Structures

struct  aaline_fragment_shader
 Subclass of pipe_shader_state to carry extra fragment shader info. More...
struct  aaline_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 MAX_TEXTURE_LEVEL   5
 AA line stage: AA lines are converted to texture mapped triangles.
#define MAX   1000

Functions

static void aa_transform_decl (struct tgsi_transform_context *ctx, struct tgsi_full_declaration *decl)
 TGSI declaration transform callback.
static int free_bit (uint bitfield)
 Find the lowest zero bit in the given word, or -1 if bitfield is all ones.
static void aa_transform_inst (struct tgsi_transform_context *ctx, struct tgsi_full_instruction *inst)
 TGSI instruction transform callback.
static boolean generate_aaline_fs (struct aaline_stage *aaline)
 Generate the frag shader we'll use for drawing AA lines.
static boolean aaline_create_texture (struct aaline_stage *aaline)
 Create the texture map we'll use for antialiasing the lines.
static boolean aaline_create_sampler (struct aaline_stage *aaline)
 Create the sampler CSO that'll be used for antialiasing.
static boolean bind_aaline_fragment_shader (struct aaline_stage *aaline)
 When we're about to draw our first AA line in a batch, this function is called to tell the driver to bind our modified fragment shader.
static struct aaline_stageaaline_stage (struct draw_stage *stage)
static void aaline_line (struct draw_stage *stage, struct prim_header *header)
 Draw a wide line by drawing a quad, using geometry which will fullfill GL's antialiased line requirements.
static void aaline_first_line (struct draw_stage *stage, struct prim_header *header)
static void aaline_flush (struct draw_stage *stage, unsigned flags)
static void aaline_reset_stipple_counter (struct draw_stage *stage)
static void aaline_destroy (struct draw_stage *stage)
static struct aaline_stagedraw_aaline_stage (struct draw_context *draw)
static struct aaline_stageaaline_stage_from_pipe (struct pipe_context *pipe)
static void * aaline_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 aaline_bind_fs_state (struct pipe_context *pipe, void *fs)
static void aaline_delete_fs_state (struct pipe_context *pipe, void *fs)
static void aaline_bind_sampler_states (struct pipe_context *pipe, unsigned num, void **sampler)
static void aaline_set_sampler_textures (struct pipe_context *pipe, unsigned num, struct pipe_texture **texture)
boolean draw_install_aaline_stage (struct draw_context *draw, struct pipe_context *pipe)
 Called by drivers that want to install this AA line prim stage into the draw module's pipeline.


Define Documentation

#define MAX   1000

#define MAX_TEXTURE_LEVEL   5

AA line stage: AA lines are converted to texture mapped triangles.

Authors: Brian Paul Max texture level for the alpha texture used for antialiasing

Definition at line 53 of file draw_pipe_aaline.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 a free sampler, a free input attrib, and two free temp regs.

Definition at line 139 of file draw_pipe_aaline.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, aa_transform_context::samplersUsed, tgsi_full_declaration::Semantic, tgsi_declaration_semantic::SemanticIndex, tgsi_declaration_semantic::SemanticName, aa_transform_context::tempsUsed, TGSI_FILE_INPUT, TGSI_FILE_OUTPUT, TGSI_FILE_SAMPLER, TGSI_FILE_TEMPORARY, TGSI_SEMANTIC_COLOR, and TGSI_SEMANTIC_GENERIC.

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 }

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 197 of file draw_pipe_aaline.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_dst_register::File, tgsi_declaration::File, tgsi_declaration_range::First, aa_transform_context::firstInstruction, free_bit(), aa_transform_context::freeSampler, tgsi_full_instruction::FullDstRegisters, tgsi_dst_register::Index, tgsi_full_instruction::Instruction, tgsi_declaration::Interpolate, tgsi_declaration_range::Last, aa_transform_context::maxGeneric, aa_transform_context::maxInput, tgsi_instruction::NumDstRegs, tgsi_instruction::Opcode, PIPE_MAX_SAMPLERS, aa_transform_context::samplersUsed, tgsi_full_declaration::Semantic, tgsi_declaration::Semantic, tgsi_declaration_semantic::SemanticIndex, tgsi_declaration_semantic::SemanticName, aa_transform_context::tempsUsed, aa_transform_context::texTemp, tgsi_default_full_declaration(), tgsi_default_full_instruction(), TGSI_FILE_INPUT, TGSI_FILE_OUTPUT, TGSI_FILE_SAMPLER, TGSI_FILE_TEMPORARY, TGSI_INTERPOLATE_PERSPECTIVE, TGSI_OPCODE_END, TGSI_OPCODE_MOV, TGSI_OPCODE_MUL, TGSI_OPCODE_TEX, TGSI_SEMANTIC_GENERIC, TGSI_TEXTURE_2D, TGSI_WRITEMASK_W, and TGSI_WRITEMASK_XYZ.

00199 {
00200    struct aa_transform_context *aactx = (struct aa_transform_context *) ctx;
00201 
00202    if (aactx->firstInstruction) {
00203       /* emit our new declarations before the first instruction */
00204 
00205       struct tgsi_full_declaration decl;
00206       uint i;
00207 
00208       /* find free sampler */
00209       aactx->freeSampler = free_bit(aactx->samplersUsed);
00210       if (aactx->freeSampler >= PIPE_MAX_SAMPLERS)
00211          aactx->freeSampler = PIPE_MAX_SAMPLERS - 1;
00212 
00213       /* find two free temp regs */
00214       for (i = 0; i < 32; i++) {
00215          if ((aactx->tempsUsed & (1 << i)) == 0) {
00216             /* found a free temp */
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       /* declare new generic input/texcoord */
00229       decl = tgsi_default_full_declaration();
00230       decl.Declaration.File = TGSI_FILE_INPUT;
00231       /* XXX this could be linear... */
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       /* declare new sampler */
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       /* declare new temp regs */
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       /* TEX */
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       /* MOV rgb */
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       /* MUL alpha */
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       /* END */
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       /* Not an END instruction.
00317        * Look for writes to result.color and replace with colorTemp reg.
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 }

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

Definition at line 799 of file draw_pipe_aaline.c.

References aaline_stage_from_pipe(), aaline_stage::driver_bind_fs_state, aaline_fragment_shader::driver_fs, aaline_stage::fs, and aaline_stage::pipe.

00800 {
00801    struct aaline_stage *aaline = aaline_stage_from_pipe(pipe);
00802    struct aaline_fragment_shader *aafs = (struct aaline_fragment_shader *) fs;
00803 
00804    /* save current */
00805    aaline->fs = aafs;
00806    /* pass-through */
00807    aaline->driver_bind_fs_state(aaline->pipe,
00808                                 (aafs ? aafs->driver_fs : NULL));
00809 }

static void aaline_bind_sampler_states ( struct pipe_context pipe,
unsigned  num,
void **  sampler 
) [static]

Definition at line 824 of file draw_pipe_aaline.c.

References aaline_stage_from_pipe(), aaline_stage::driver_bind_sampler_states, aaline_stage::num_samplers, aaline_stage::pipe, aaline_stage::sampler, and aaline_stage::state.

00826 {
00827    struct aaline_stage *aaline = aaline_stage_from_pipe(pipe);
00828 
00829    /* save current */
00830    memcpy(aaline->state.sampler, sampler, num * sizeof(void *));
00831    aaline->num_samplers = num;
00832 
00833    /* pass-through */
00834    aaline->driver_bind_sampler_states(aaline->pipe, num, sampler);
00835 }

static void* aaline_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 781 of file draw_pipe_aaline.c.

References aaline_stage_from_pipe(), CALLOC_STRUCT, aaline_stage::driver_create_fs_state, aaline_fragment_shader::driver_fs, aaline_stage::pipe, and aaline_fragment_shader::state.

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    /* pass-through */
00792    aafs->driver_fs = aaline->driver_create_fs_state(aaline->pipe, fs);
00793 
00794    return aafs;
00795 }

static boolean aaline_create_sampler ( struct aaline_stage aaline  )  [static]

Create the sampler CSO that'll be used for antialiasing.

By using a mipmapped texture, we don't have to generate a different texture image for each line size.

Definition at line 461 of file draw_pipe_aaline.c.

References pipe_context::create_sampler_state, FALSE, pipe_sampler_state::mag_img_filter, pipe_sampler_state::max_lod, MAX_TEXTURE_LEVEL, pipe_sampler_state::min_img_filter, pipe_sampler_state::min_lod, pipe_sampler_state::min_mip_filter, pipe_sampler_state::normalized_coords, aaline_stage::pipe, PIPE_TEX_FILTER_LINEAR, PIPE_TEX_MIPFILTER_LINEAR, PIPE_TEX_WRAP_CLAMP_TO_EDGE, aaline_stage::sampler_cso, TRUE, pipe_sampler_state::wrap_r, pipe_sampler_state::wrap_s, and pipe_sampler_state::wrap_t.

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 }

static boolean aaline_create_texture ( struct aaline_stage aaline  )  [static]

Create the texture map we'll use for antialiasing the lines.

Definition at line 388 of file draw_pipe_aaline.c.

References assert, pipe_texture::block, pipe_texture::depth, FALSE, pipe_texture::format, pipe_screen::get_tex_surface, pipe_texture::height, pipe_texture::last_level, MAX_TEXTURE_LEVEL, pf_get_block(), aaline_stage::pipe, PIPE_BUFFER_USAGE_CPU_WRITE, PIPE_FORMAT_A8_UNORM, PIPE_TEXTURE_2D, pipe_context::screen, pipe_surface::stride, pipe_screen::surface_map, pipe_screen::surface_unmap, pipe_texture::target, pipe_screen::tex_surface_release, aaline_stage::texture, pipe_screen::texture_create, TRUE, and pipe_texture::width.

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; /* XXX verify supported by driver! */
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    /* Fill in mipmap images.
00409     * Basically each level is solid opaque, except for the outermost
00410     * texels which are zero.  Special case the 1x1 and 2x2 levels.
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       /* This texture is new, no need to flush. 
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; /* tuneable */
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       /* unmap */
00448       screen->surface_unmap(screen, surface);
00449       screen->tex_surface_release(screen, &surface);
00450    }
00451    return TRUE;
00452 }

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

Definition at line 813 of file draw_pipe_aaline.c.

References aaline_stage_from_pipe(), aaline_stage::driver_delete_fs_state, aaline_fragment_shader::driver_fs, FREE, and aaline_stage::pipe.

00814 {
00815    struct aaline_stage *aaline = aaline_stage_from_pipe(pipe);
00816    struct aaline_fragment_shader *aafs = (struct aaline_fragment_shader *) fs;
00817    /* pass-through */
00818    aaline->driver_delete_fs_state(aaline->pipe, aafs->driver_fs);
00819    FREE(aafs);
00820 }

static void aaline_destroy ( struct draw_stage stage  )  [static]

Definition at line 718 of file draw_pipe_aaline.c.

References aaline_stage(), pipe_context::delete_sampler_state, draw_free_temp_verts(), FREE, aaline_stage::pipe, PIPE_MAX_SAMPLERS, pipe_texture_reference(), pipe_texture_release(), aaline_stage::sampler_cso, aaline_stage::state, and aaline_stage::texture.

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 }

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

Definition at line 635 of file draw_pipe_aaline.c.

References aaline_line(), aaline_stage(), assert, bind_aaline_fragment_shader(), draw_stage::draw, draw, draw_pipe_passthrough_line(), aaline_stage::driver_bind_sampler_states, aaline_stage::driver_set_sampler_textures, draw_context::extra_vp_outputs, FALSE, aaline_stage::fs, aaline_fragment_shader::generic_attrib, aaline_stage::half_line_width, draw_stage::line, pipe_rasterizer_state::line_smooth, pipe_rasterizer_state::line_width, MAX2, aaline_stage::num_samplers, aaline_stage::num_textures, draw_context::num_vs_outputs, aaline_stage::pipe, pipe_texture_reference(), aaline_stage::pos_slot, draw_context::position_output, draw_context::rasterizer, aaline_stage::sampler, aaline_stage::sampler_cso, aaline_fragment_shader::sampler_unit, draw_context::semantic_index, draw_context::semantic_name, draw_context::slot, aaline_stage::state, draw_context::suspend_flushing, aaline_stage::tex_slot, aaline_stage::texture, TGSI_SEMANTIC_GENERIC, TRUE, and draw_context::vs.

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     * Bind (generate) our fragprog, sampler and texture
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    /* update vertex attrib info */
00659    aaline->tex_slot = draw->vs.num_vs_outputs;
00660    aaline->pos_slot = draw->vs.position_output;
00661 
00662    /* advertise the extra post-transformed vertex attribute */
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    /* how many samplers? */
00668    /* we'll use sampler/texture[pstip->sampler_unit] for the stipple */
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    /* now really draw first line */
00682    stage->line = aaline_line;
00683    stage->line(stage, header);
00684 }

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

Definition at line 688 of file draw_pipe_aaline.c.

References aaline_first_line(), aaline_stage(), draw_stage::draw, draw, aaline_stage::driver_bind_fs_state, aaline_stage::driver_bind_sampler_states, aaline_fragment_shader::driver_fs, aaline_stage::driver_set_sampler_textures, draw_context::extra_vp_outputs, FALSE, draw_stage::flush, aaline_stage::fs, draw_stage::line, draw_stage::next, aaline_stage::num_samplers, aaline_stage::num_textures, aaline_stage::pipe, aaline_stage::sampler, draw_context::slot, aaline_stage::state, draw_context::suspend_flushing, aaline_stage::texture, and TRUE.

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    /* restore original frag shader, texture, sampler state */
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 }

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

Draw a wide line by drawing a quad, using geometry which will fullfill GL's antialiased line requirements.

Definition at line 519 of file draw_pipe_aaline.c.

References aaline_stage(), ASSIGN_4V, vertex_header::data, dup_vert(), aaline_stage::half_line_width, draw_stage::next, aaline_stage::pos_slot, aaline_stage::tex_slot, draw_stage::tri, and prim_header::v.

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    /* XXX the ends of lines aren't quite perfect yet, but probably passable */
00535    dx = 0.5F * half_width;
00536    dy = half_width;
00537 
00538    /* allocate/dup new verts */
00539    for (i = 0; i < 8; i++) {
00540       v[i] = dup_vert(stage, header->v[i/4], i);
00541    }
00542 
00543    /*
00544     * Quad strip for line from v0 to v1 (*=endpoints):
00545     *
00546     *  1   3                     5   7
00547     *  +---+---------------------+---+
00548     *  |                             |
00549     *  | *v0                     v1* |
00550     *  |                             |
00551     *  +---+---------------------+---+
00552     *  0   2                     4   6
00553     */
00554 
00555    /* new verts */
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    /* new texcoords */
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    /* emit 6 tris for the quad strip */
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 }

static void aaline_reset_stipple_counter ( struct draw_stage stage  )  [static]

Definition at line 711 of file draw_pipe_aaline.c.

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

00712 {
00713    stage->next->reset_stipple_counter( stage->next );
00714 }

static void aaline_set_sampler_textures ( struct pipe_context pipe,
unsigned  num,
struct pipe_texture **  texture 
) [static]

Definition at line 839 of file draw_pipe_aaline.c.

References aaline_stage_from_pipe(), aaline_stage::driver_set_sampler_textures, aaline_stage::num_textures, aaline_stage::pipe, PIPE_MAX_SAMPLERS, pipe_texture_reference(), aaline_stage::state, and aaline_stage::texture.

00841 {
00842    struct aaline_stage *aaline = aaline_stage_from_pipe(pipe);
00843    uint i;
00844 
00845    /* save current */
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    /* pass-through */
00855    aaline->driver_set_sampler_textures(aaline->pipe, num, texture);
00856 }

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

Definition at line 508 of file draw_pipe_aaline.c.

00509 {
00510    return (struct aaline_stage *) stage;
00511 }

static struct aaline_stage* aaline_stage_from_pipe ( struct pipe_context pipe  )  [static, read]

Definition at line 769 of file draw_pipe_aaline.c.

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

00770 {
00771    struct draw_context *draw = (struct draw_context *) pipe->draw;
00772    return aaline_stage(draw->pipeline.aaline);
00773 }

static boolean bind_aaline_fragment_shader ( struct aaline_stage aaline  )  [static]

When we're about to draw our first AA line in a batch, this function is called to tell the driver to bind our modified fragment shader.

Definition at line 490 of file draw_pipe_aaline.c.

References aaline_fragment_shader::aaline_fs, draw_stage::draw, draw, aaline_stage::driver_bind_fs_state, FALSE, aaline_stage::fs, generate_aaline_fs(), aaline_stage::pipe, aaline_stage::stage, draw_context::suspend_flushing, and TRUE.

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 }

static struct aaline_stage* draw_aaline_stage ( struct draw_context draw  )  [static, read]

Definition at line 740 of file draw_pipe_aaline.c.

References aaline_destroy(), aaline_first_line(), aaline_flush(), aaline_reset_stipple_counter(), CALLOC_STRUCT, draw_stage::destroy, draw_stage::draw, draw_alloc_temp_verts(), draw_pipe_passthrough_point(), draw_pipe_passthrough_tri(), draw_stage::flush, draw_stage::line, draw_stage::next, draw_stage::point, draw_stage::reset_stipple_counter, aaline_stage::stage, and draw_stage::tri.

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 }

boolean draw_install_aaline_stage ( struct draw_context draw,
struct pipe_context pipe 
)

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

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

Definition at line 865 of file draw_pipe_aaline.c.

References draw_context::aaline, aaline_bind_fs_state(), aaline_bind_sampler_states(), aaline_create_fs_state(), aaline_create_sampler(), aaline_create_texture(), aaline_delete_fs_state(), aaline_set_sampler_textures(), pipe_context::bind_fs_state, pipe_context::bind_sampler_states, pipe_context::create_fs_state, pipe_context::delete_fs_state, draw_stage::destroy, pipe_context::draw, draw_aaline_stage(), aaline_stage::driver_bind_fs_state, aaline_stage::driver_bind_sampler_states, aaline_stage::driver_create_fs_state, aaline_stage::driver_delete_fs_state, aaline_stage::driver_set_sampler_textures, FALSE, aaline_stage::pipe, draw_context::pipeline, pipe_context::set_sampler_textures, aaline_stage::stage, and TRUE.

00866 {
00867    struct aaline_stage *aaline;
00868 
00869    pipe->draw = (void *) draw;
00870 
00871    /*
00872     * Create / install AA line drawing / prim stage
00873     */
00874    aaline = draw_aaline_stage( draw );
00875    if (!aaline)
00876       goto fail;
00877 
00878    aaline->pipe = pipe;
00879 
00880    /* create special texture, sampler state */
00881    if (!aaline_create_texture(aaline))
00882       goto fail;
00883 
00884    if (!aaline_create_sampler(aaline))
00885       goto fail;
00886 
00887    /* save original driver functions */
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    /* override the driver's functions */
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    /* Install once everything is known to be OK:
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 }

static int free_bit ( uint  bitfield  )  [static]

Find the lowest zero bit in the given word, or -1 if bitfield is all ones.

Definition at line 180 of file draw_pipe_aaline.c.

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 }

static boolean generate_aaline_fs ( struct aaline_stage aaline  )  [static]

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

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

Definition at line 340 of file draw_pipe_aaline.c.

References aa_transform_decl(), aa_transform_inst(), aaline_fragment_shader::aaline_fs, aa_transform_context::base, aa_transform_context::colorOutput, aa_transform_context::colorTemp, aaline_stage::driver_create_fs_state, FALSE, aa_transform_context::firstInstruction, aa_transform_context::freeSampler, aaline_stage::fs, aaline_fragment_shader::generic_attrib, MALLOC, MAX, aa_transform_context::maxGeneric, aa_transform_context::maxInput, aaline_stage::pipe, aaline_fragment_shader::sampler_unit, aaline_fragment_shader::state, aa_transform_context::texTemp, tgsi_dump(), tgsi_transform_shader(), pipe_shader_state::tokens, tgsi_transform_context::transform_declaration, tgsi_transform_context::transform_instruction, and TRUE.

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; /* copy to init */
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 /* DEBUG */
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 }


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