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_stage * | aaline_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_stage * | draw_aaline_stage (struct draw_context *draw) |
static struct aaline_stage * | aaline_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 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.
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 }