Go to the source code of this file.
Data Structures | |
struct | pstip_fragment_shader |
Polygon stipple stage: implement polygon stipple with texture map and fragment program. More... | |
struct | pstip_stage |
Subclass of draw_stage. More... | |
struct | pstip_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 1000 |
Functions | |
static void | pstip_transform_decl (struct tgsi_transform_context *ctx, struct tgsi_full_declaration *decl) |
TGSI declaration transform callback. | |
static void | pstip_transform_immed (struct tgsi_transform_context *ctx, struct tgsi_full_immediate *immed) |
static int | free_bit (uint bitfield) |
Find the lowest zero bit in the given word, or -1 if bitfield is all ones. | |
static void | pstip_transform_inst (struct tgsi_transform_context *ctx, struct tgsi_full_instruction *inst) |
TGSI instruction transform callback. | |
static boolean | generate_pstip_fs (struct pstip_stage *pstip) |
Generate the frag shader we'll use for doing polygon stipple. | |
static void | pstip_update_texture (struct pstip_stage *pstip) |
Load texture image with current stipple pattern. | |
static boolean | pstip_create_texture (struct pstip_stage *pstip) |
Create the texture map we'll use for stippling. | |
static boolean | pstip_create_sampler (struct pstip_stage *pstip) |
Create the sampler CSO that'll be used for stippling. | |
static boolean | bind_pstip_fragment_shader (struct pstip_stage *pstip) |
When we're about to draw our first stipple polygon in a batch, this function is called to tell the driver to bind our modified fragment shader. | |
static struct pstip_stage * | pstip_stage (struct draw_stage *stage) |
static void | pstip_first_tri (struct draw_stage *stage, struct prim_header *header) |
static void | pstip_flush (struct draw_stage *stage, unsigned flags) |
static void | pstip_reset_stipple_counter (struct draw_stage *stage) |
static void | pstip_destroy (struct draw_stage *stage) |
static struct pstip_stage * | draw_pstip_stage (struct draw_context *draw) |
static struct pstip_stage * | pstip_stage_from_pipe (struct pipe_context *pipe) |
static void * | pstip_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 | pstip_bind_fs_state (struct pipe_context *pipe, void *fs) |
static void | pstip_delete_fs_state (struct pipe_context *pipe, void *fs) |
static void | pstip_bind_sampler_states (struct pipe_context *pipe, unsigned num, void **sampler) |
static void | pstip_set_sampler_textures (struct pipe_context *pipe, unsigned num, struct pipe_texture **texture) |
static void | pstip_set_polygon_stipple (struct pipe_context *pipe, const struct pipe_poly_stipple *stipple) |
boolean | draw_install_pstipple_stage (struct draw_context *draw, struct pipe_context *pipe) |
Called by drivers that want to install this polygon stipple stage into the draw module's pipeline. |
#define MAX 1000 |
static boolean bind_pstip_fragment_shader | ( | struct pstip_stage * | pstip | ) | [static] |
When we're about to draw our first stipple polygon in a batch, this function is called to tell the driver to bind our modified fragment shader.
Definition at line 474 of file draw_pipe_pstipple.c.
References draw_stage::draw, draw, pstip_stage::driver_bind_fs_state, FALSE, pstip_stage::fs, generate_pstip_fs(), pstip_stage::pipe, pstip_fragment_shader::pstip_fs, pstip_stage::stage, draw_context::suspend_flushing, and TRUE.
00475 { 00476 struct draw_context *draw = pstip->stage.draw; 00477 if (!pstip->fs->pstip_fs && 00478 !generate_pstip_fs(pstip)) 00479 return FALSE; 00480 00481 draw->suspend_flushing = TRUE; 00482 pstip->driver_bind_fs_state(pstip->pipe, pstip->fs->pstip_fs); 00483 draw->suspend_flushing = FALSE; 00484 return TRUE; 00485 }
boolean draw_install_pstipple_stage | ( | struct draw_context * | draw, | |
struct pipe_context * | pipe | |||
) |
Called by drivers that want to install this polygon stipple stage into the draw module's pipeline.
This will not be used if the hardware has native support for polygon stipple.
Definition at line 720 of file draw_pipe_pstipple.c.
References 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_pstip_stage(), pstip_stage::driver_bind_fs_state, pstip_stage::driver_bind_sampler_states, pstip_stage::driver_create_fs_state, pstip_stage::driver_delete_fs_state, pstip_stage::driver_set_polygon_stipple, pstip_stage::driver_set_sampler_textures, FALSE, pstip_stage::pipe, draw_context::pipeline, pstip_bind_fs_state(), pstip_bind_sampler_states(), pstip_create_fs_state(), pstip_create_sampler(), pstip_create_texture(), pstip_delete_fs_state(), pstip_set_polygon_stipple(), pstip_set_sampler_textures(), draw_context::pstipple, pipe_context::set_polygon_stipple, pipe_context::set_sampler_textures, pstip_stage::stage, and TRUE.
00722 { 00723 struct pstip_stage *pstip; 00724 00725 pipe->draw = (void *) draw; 00726 00727 /* 00728 * Create / install pgon stipple drawing / prim stage 00729 */ 00730 pstip = draw_pstip_stage( draw ); 00731 if (pstip == NULL) 00732 goto fail; 00733 00734 draw->pipeline.pstipple = &pstip->stage; 00735 00736 pstip->pipe = pipe; 00737 00738 /* create special texture, sampler state */ 00739 if (!pstip_create_texture(pstip)) 00740 goto fail; 00741 00742 if (!pstip_create_sampler(pstip)) 00743 goto fail; 00744 00745 /* save original driver functions */ 00746 pstip->driver_create_fs_state = pipe->create_fs_state; 00747 pstip->driver_bind_fs_state = pipe->bind_fs_state; 00748 pstip->driver_delete_fs_state = pipe->delete_fs_state; 00749 00750 pstip->driver_bind_sampler_states = pipe->bind_sampler_states; 00751 pstip->driver_set_sampler_textures = pipe->set_sampler_textures; 00752 pstip->driver_set_polygon_stipple = pipe->set_polygon_stipple; 00753 00754 /* override the driver's functions */ 00755 pipe->create_fs_state = pstip_create_fs_state; 00756 pipe->bind_fs_state = pstip_bind_fs_state; 00757 pipe->delete_fs_state = pstip_delete_fs_state; 00758 00759 pipe->bind_sampler_states = pstip_bind_sampler_states; 00760 pipe->set_sampler_textures = pstip_set_sampler_textures; 00761 pipe->set_polygon_stipple = pstip_set_polygon_stipple; 00762 00763 return TRUE; 00764 00765 fail: 00766 if (pstip) 00767 pstip->stage.destroy( &pstip->stage ); 00768 00769 return FALSE; 00770 }
static struct pstip_stage* draw_pstip_stage | ( | struct draw_context * | draw | ) | [static, read] |
Definition at line 584 of file draw_pipe_pstipple.c.
References CALLOC_STRUCT, draw_stage::destroy, draw_stage::draw, draw_alloc_temp_verts(), draw_pipe_passthrough_line(), draw_pipe_passthrough_point(), draw_stage::flush, draw_stage::line, draw_stage::next, draw_stage::point, pstip_destroy(), pstip_first_tri(), pstip_flush(), pstip_reset_stipple_counter(), draw_stage::reset_stipple_counter, pstip_stage::stage, and draw_stage::tri.
00585 { 00586 struct pstip_stage *pstip = CALLOC_STRUCT(pstip_stage); 00587 00588 draw_alloc_temp_verts( &pstip->stage, 8 ); 00589 00590 pstip->stage.draw = draw; 00591 pstip->stage.next = NULL; 00592 pstip->stage.point = draw_pipe_passthrough_point; 00593 pstip->stage.line = draw_pipe_passthrough_line; 00594 pstip->stage.tri = pstip_first_tri; 00595 pstip->stage.flush = pstip_flush; 00596 pstip->stage.reset_stipple_counter = pstip_reset_stipple_counter; 00597 pstip->stage.destroy = pstip_destroy; 00598 00599 return pstip; 00600 }
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 172 of file draw_pipe_pstipple.c.
00173 { 00174 int i; 00175 for (i = 0; i < 32; i++) { 00176 if ((bitfield & (1 << i)) == 0) 00177 return i; 00178 } 00179 return -1; 00180 }
static boolean generate_pstip_fs | ( | struct pstip_stage * | pstip | ) | [static] |
Generate the frag shader we'll use for doing polygon stipple.
This will be the user's shader prefixed with a TEX and KIL instruction.
Definition at line 325 of file draw_pipe_pstipple.c.
References assert, pstip_transform_context::base, pstip_stage::driver_create_fs_state, FALSE, pstip_transform_context::firstInstruction, pstip_transform_context::freeSampler, pstip_stage::fs, MALLOC, MAX, pstip_transform_context::maxInput, pstip_stage::pipe, PIPE_MAX_SAMPLERS, pstip_fragment_shader::pstip_fs, pstip_transform_decl(), pstip_transform_immed(), pstip_transform_inst(), pstip_fragment_shader::sampler_unit, pstip_fragment_shader::state, pstip_transform_context::texTemp, tgsi_dump(), tgsi_transform_shader(), pipe_shader_state::tokens, tgsi_transform_context::transform_declaration, tgsi_transform_context::transform_immediate, tgsi_transform_context::transform_instruction, TRUE, and pstip_transform_context::wincoordInput.
00326 { 00327 const struct pipe_shader_state *orig_fs = &pstip->fs->state; 00328 /*struct draw_context *draw = pstip->stage.draw;*/ 00329 struct pipe_shader_state pstip_fs; 00330 struct pstip_transform_context transform; 00331 00332 #define MAX 1000 00333 00334 pstip_fs = *orig_fs; /* copy to init */ 00335 pstip_fs.tokens = MALLOC(sizeof(struct tgsi_token) * MAX); 00336 if (pstip_fs.tokens == NULL) 00337 return FALSE; 00338 00339 memset(&transform, 0, sizeof(transform)); 00340 transform.wincoordInput = -1; 00341 transform.maxInput = -1; 00342 transform.texTemp = -1; 00343 transform.firstInstruction = TRUE; 00344 transform.base.transform_instruction = pstip_transform_inst; 00345 transform.base.transform_declaration = pstip_transform_decl; 00346 transform.base.transform_immediate = pstip_transform_immed; 00347 00348 tgsi_transform_shader(orig_fs->tokens, 00349 (struct tgsi_token *) pstip_fs.tokens, 00350 MAX, &transform.base); 00351 00352 #if 0 /* DEBUG */ 00353 tgsi_dump(orig_fs->tokens, 0); 00354 tgsi_dump(pstip_fs.tokens, 0); 00355 #endif 00356 00357 pstip->fs->sampler_unit = transform.freeSampler; 00358 assert(pstip->fs->sampler_unit < PIPE_MAX_SAMPLERS); 00359 00360 pstip->fs->pstip_fs = pstip->driver_create_fs_state(pstip->pipe, &pstip_fs); 00361 00362 return TRUE; 00363 }
static void pstip_bind_fs_state | ( | struct pipe_context * | pipe, | |
void * | fs | |||
) | [static] |
Definition at line 634 of file draw_pipe_pstipple.c.
References pstip_stage::driver_bind_fs_state, pstip_fragment_shader::driver_fs, pstip_stage::fs, pstip_stage::pipe, and pstip_stage_from_pipe().
00635 { 00636 struct pstip_stage *pstip = pstip_stage_from_pipe(pipe); 00637 struct pstip_fragment_shader *aafs = (struct pstip_fragment_shader *) fs; 00638 /* save current */ 00639 pstip->fs = aafs; 00640 /* pass-through */ 00641 pstip->driver_bind_fs_state(pstip->pipe, 00642 (aafs ? aafs->driver_fs : NULL)); 00643 }
static void pstip_bind_sampler_states | ( | struct pipe_context * | pipe, | |
unsigned | num, | |||
void ** | sampler | |||
) | [static] |
Definition at line 658 of file draw_pipe_pstipple.c.
References pstip_stage::driver_bind_sampler_states, pstip_stage::num_samplers, pstip_stage::pipe, PIPE_MAX_SAMPLERS, pstip_stage_from_pipe(), pstip_stage::samplers, and pstip_stage::state.
00660 { 00661 struct pstip_stage *pstip = pstip_stage_from_pipe(pipe); 00662 uint i; 00663 00664 /* save current */ 00665 memcpy(pstip->state.samplers, sampler, num * sizeof(void *)); 00666 for (i = num; i < PIPE_MAX_SAMPLERS; i++) { 00667 pstip->state.samplers[i] = NULL; 00668 } 00669 00670 pstip->num_samplers = num; 00671 /* pass-through */ 00672 pstip->driver_bind_sampler_states(pstip->pipe, num, sampler); 00673 }
static void* pstip_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 616 of file draw_pipe_pstipple.c.
References CALLOC_STRUCT, pstip_stage::driver_create_fs_state, pstip_fragment_shader::driver_fs, pstip_stage::pipe, pstip_stage_from_pipe(), and pstip_fragment_shader::state.
00618 { 00619 struct pstip_stage *pstip = pstip_stage_from_pipe(pipe); 00620 struct pstip_fragment_shader *aafs = CALLOC_STRUCT(pstip_fragment_shader); 00621 00622 if (aafs) { 00623 aafs->state = *fs; 00624 00625 /* pass-through */ 00626 aafs->driver_fs = pstip->driver_create_fs_state(pstip->pipe, fs); 00627 } 00628 00629 return aafs; 00630 }
static boolean pstip_create_sampler | ( | struct pstip_stage * | pstip | ) | [static] |
Create the sampler CSO that'll be used for stippling.
Definition at line 445 of file draw_pipe_pstipple.c.
References pipe_context::create_sampler_state, FALSE, pipe_sampler_state::mag_img_filter, pipe_sampler_state::max_lod, pipe_sampler_state::min_img_filter, pipe_sampler_state::min_lod, pipe_sampler_state::min_mip_filter, pipe_sampler_state::normalized_coords, pstip_stage::pipe, PIPE_TEX_FILTER_NEAREST, PIPE_TEX_MIPFILTER_NONE, PIPE_TEX_WRAP_REPEAT, pstip_stage::sampler_cso, TRUE, pipe_sampler_state::wrap_r, pipe_sampler_state::wrap_s, and pipe_sampler_state::wrap_t.
00446 { 00447 struct pipe_sampler_state sampler; 00448 struct pipe_context *pipe = pstip->pipe; 00449 00450 memset(&sampler, 0, sizeof(sampler)); 00451 sampler.wrap_s = PIPE_TEX_WRAP_REPEAT; 00452 sampler.wrap_t = PIPE_TEX_WRAP_REPEAT; 00453 sampler.wrap_r = PIPE_TEX_WRAP_REPEAT; 00454 sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NONE; 00455 sampler.min_img_filter = PIPE_TEX_FILTER_NEAREST; 00456 sampler.mag_img_filter = PIPE_TEX_FILTER_NEAREST; 00457 sampler.normalized_coords = 1; 00458 sampler.min_lod = 0.0f; 00459 sampler.max_lod = 0.0f; 00460 00461 pstip->sampler_cso = pipe->create_sampler_state(pipe, &sampler); 00462 if (pstip->sampler_cso == NULL) 00463 return FALSE; 00464 00465 return TRUE; 00466 }
static boolean pstip_create_texture | ( | struct pstip_stage * | pstip | ) | [static] |
Create the texture map we'll use for stippling.
Definition at line 418 of file draw_pipe_pstipple.c.
References pipe_texture::block, pipe_texture::depth, FALSE, pipe_texture::format, pipe_texture::height, pipe_texture::last_level, pf_get_block(), pstip_stage::pipe, PIPE_FORMAT_A8_UNORM, PIPE_TEXTURE_2D, pipe_context::screen, pipe_texture::target, pstip_stage::texture, pipe_screen::texture_create, TRUE, and pipe_texture::width.
00419 { 00420 struct pipe_context *pipe = pstip->pipe; 00421 struct pipe_screen *screen = pipe->screen; 00422 struct pipe_texture texTemp; 00423 00424 memset(&texTemp, 0, sizeof(texTemp)); 00425 texTemp.target = PIPE_TEXTURE_2D; 00426 texTemp.format = PIPE_FORMAT_A8_UNORM; /* XXX verify supported by driver! */ 00427 texTemp.last_level = 0; 00428 texTemp.width[0] = 32; 00429 texTemp.height[0] = 32; 00430 texTemp.depth[0] = 1; 00431 pf_get_block(texTemp.format, &texTemp.block); 00432 00433 pstip->texture = screen->texture_create(screen, &texTemp); 00434 if (pstip->texture == NULL) 00435 return FALSE; 00436 00437 return TRUE; 00438 }
static void pstip_delete_fs_state | ( | struct pipe_context * | pipe, | |
void * | fs | |||
) | [static] |
Definition at line 647 of file draw_pipe_pstipple.c.
References pstip_stage::driver_delete_fs_state, pstip_fragment_shader::driver_fs, FREE, pstip_stage::pipe, and pstip_stage_from_pipe().
00648 { 00649 struct pstip_stage *pstip = pstip_stage_from_pipe(pipe); 00650 struct pstip_fragment_shader *aafs = (struct pstip_fragment_shader *) fs; 00651 /* pass-through */ 00652 pstip->driver_delete_fs_state(pstip->pipe, aafs->driver_fs); 00653 FREE(aafs); 00654 }
static void pstip_destroy | ( | struct draw_stage * | stage | ) | [static] |
Definition at line 565 of file draw_pipe_pstipple.c.
References pipe_context::delete_sampler_state, draw_free_temp_verts(), FREE, pstip_stage::pipe, PIPE_MAX_SAMPLERS, pipe_texture_reference(), pipe_texture_release(), pstip_stage(), pstip_stage::sampler_cso, pstip_stage::state, pstip_stage::texture, and pstip_stage::textures.
00566 { 00567 struct pstip_stage *pstip = pstip_stage(stage); 00568 uint i; 00569 00570 for (i = 0; i < PIPE_MAX_SAMPLERS; i++) { 00571 pipe_texture_reference(&pstip->state.textures[i], NULL); 00572 } 00573 00574 pstip->pipe->delete_sampler_state(pstip->pipe, pstip->sampler_cso); 00575 00576 pipe_texture_release(&pstip->texture); 00577 00578 draw_free_temp_verts( stage ); 00579 FREE( stage ); 00580 }
static void pstip_first_tri | ( | struct draw_stage * | stage, | |
struct prim_header * | header | |||
) | [static] |
Definition at line 496 of file draw_pipe_pstipple.c.
References assert, bind_pstip_fragment_shader(), draw_stage::draw, draw, draw_pipe_passthrough_tri(), pstip_stage::driver_bind_sampler_states, pstip_stage::driver_set_sampler_textures, FALSE, pstip_stage::fs, MAX2, pstip_stage::num_samplers, pstip_stage::num_textures, pstip_stage::pipe, PIPE_MAX_SAMPLERS, pipe_texture_reference(), pipe_rasterizer_state::poly_stipple_enable, pstip_stage(), draw_context::rasterizer, pstip_stage::sampler_cso, pstip_fragment_shader::sampler_unit, pstip_stage::samplers, pstip_stage::state, draw_context::suspend_flushing, pstip_stage::texture, pstip_stage::textures, draw_stage::tri, and TRUE.
00497 { 00498 struct pstip_stage *pstip = pstip_stage(stage); 00499 struct pipe_context *pipe = pstip->pipe; 00500 struct draw_context *draw = stage->draw; 00501 uint num_samplers; 00502 00503 assert(stage->draw->rasterizer->poly_stipple_enable); 00504 00505 /* bind our fragprog */ 00506 if (!bind_pstip_fragment_shader(pstip)) { 00507 stage->tri = draw_pipe_passthrough_tri; 00508 stage->tri(stage, header); 00509 return; 00510 } 00511 00512 00513 /* how many samplers? */ 00514 /* we'll use sampler/texture[pstip->sampler_unit] for the stipple */ 00515 num_samplers = MAX2(pstip->num_textures, pstip->num_samplers); 00516 num_samplers = MAX2(num_samplers, pstip->fs->sampler_unit + 1); 00517 00518 /* plug in our sampler, texture */ 00519 pstip->state.samplers[pstip->fs->sampler_unit] = pstip->sampler_cso; 00520 pipe_texture_reference(&pstip->state.textures[pstip->fs->sampler_unit], 00521 pstip->texture); 00522 00523 assert(num_samplers <= PIPE_MAX_SAMPLERS); 00524 00525 draw->suspend_flushing = TRUE; 00526 pstip->driver_bind_sampler_states(pipe, num_samplers, pstip->state.samplers); 00527 pstip->driver_set_sampler_textures(pipe, num_samplers, pstip->state.textures); 00528 draw->suspend_flushing = FALSE; 00529 00530 /* now really draw first triangle */ 00531 stage->tri = draw_pipe_passthrough_tri; 00532 stage->tri(stage, header); 00533 }
static void pstip_flush | ( | struct draw_stage * | stage, | |
unsigned | flags | |||
) | [static] |
Definition at line 537 of file draw_pipe_pstipple.c.
References draw_stage::draw, draw, pstip_stage::driver_bind_fs_state, pstip_stage::driver_bind_sampler_states, pstip_fragment_shader::driver_fs, pstip_stage::driver_set_sampler_textures, FALSE, draw_stage::flush, pstip_stage::fs, draw_stage::next, pstip_stage::num_samplers, pstip_stage::num_textures, pstip_stage::pipe, pstip_first_tri(), pstip_stage(), pstip_stage::samplers, pstip_stage::state, draw_context::suspend_flushing, pstip_stage::textures, draw_stage::tri, and TRUE.
00538 { 00539 struct draw_context *draw = stage->draw; 00540 struct pstip_stage *pstip = pstip_stage(stage); 00541 struct pipe_context *pipe = pstip->pipe; 00542 00543 stage->tri = pstip_first_tri; 00544 stage->next->flush( stage->next, flags ); 00545 00546 /* restore original frag shader, texture, sampler state */ 00547 draw->suspend_flushing = TRUE; 00548 pstip->driver_bind_fs_state(pipe, pstip->fs->driver_fs); 00549 pstip->driver_bind_sampler_states(pipe, pstip->num_samplers, 00550 pstip->state.samplers); 00551 pstip->driver_set_sampler_textures(pipe, pstip->num_textures, 00552 pstip->state.textures); 00553 draw->suspend_flushing = FALSE; 00554 }
static void pstip_reset_stipple_counter | ( | struct draw_stage * | stage | ) | [static] |
Definition at line 558 of file draw_pipe_pstipple.c.
References draw_stage::next, and draw_stage::reset_stipple_counter.
00559 { 00560 stage->next->reset_stipple_counter( stage->next ); 00561 }
static void pstip_set_polygon_stipple | ( | struct pipe_context * | pipe, | |
const struct pipe_poly_stipple * | stipple | |||
) | [static] |
Definition at line 699 of file draw_pipe_pstipple.c.
References pstip_stage::driver_set_polygon_stipple, pstip_stage::pipe, pstip_stage_from_pipe(), pstip_update_texture(), pstip_stage::state, and pstip_stage::stipple.
00701 { 00702 struct pstip_stage *pstip = pstip_stage_from_pipe(pipe); 00703 00704 /* save current */ 00705 pstip->state.stipple = stipple; 00706 00707 /* pass-through */ 00708 pstip->driver_set_polygon_stipple(pstip->pipe, stipple); 00709 00710 pstip_update_texture(pstip); 00711 }
static void pstip_set_sampler_textures | ( | struct pipe_context * | pipe, | |
unsigned | num, | |||
struct pipe_texture ** | texture | |||
) | [static] |
Definition at line 677 of file draw_pipe_pstipple.c.
References pstip_stage::driver_set_sampler_textures, pstip_stage::num_textures, pstip_stage::pipe, PIPE_MAX_SAMPLERS, pipe_texture_reference(), pstip_stage_from_pipe(), pstip_stage::state, and pstip_stage::textures.
00679 { 00680 struct pstip_stage *pstip = pstip_stage_from_pipe(pipe); 00681 uint i; 00682 00683 /* save current */ 00684 for (i = 0; i < num; i++) { 00685 pipe_texture_reference(&pstip->state.textures[i], texture[i]); 00686 } 00687 for (; i < PIPE_MAX_SAMPLERS; i++) { 00688 pipe_texture_reference(&pstip->state.textures[i], NULL); 00689 } 00690 00691 pstip->num_textures = num; 00692 00693 /* pass-through */ 00694 pstip->driver_set_sampler_textures(pstip->pipe, num, texture); 00695 }
static struct pstip_stage* pstip_stage | ( | struct draw_stage * | stage | ) | [static, read] |
Definition at line 489 of file draw_pipe_pstipple.c.
00490 { 00491 return (struct pstip_stage *) stage; 00492 }
static struct pstip_stage* pstip_stage_from_pipe | ( | struct pipe_context * | pipe | ) | [static, read] |
Definition at line 604 of file draw_pipe_pstipple.c.
References pipe_context::draw, draw, draw_context::pipeline, and draw_context::pstipple.
00605 { 00606 struct draw_context *draw = (struct draw_context *) pipe->draw; 00607 return pstip_stage(draw->pipeline.pstipple); 00608 }
static void pstip_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 130 of file draw_pipe_pstipple.c.
References tgsi_full_declaration::Declaration, tgsi_full_declaration::DeclarationRange, tgsi_transform_context::emit_declaration, tgsi_declaration::File, tgsi_declaration_range::First, tgsi_declaration_range::Last, MAX2, pstip_transform_context::maxInput, pstip_transform_context::samplersUsed, tgsi_full_declaration::Semantic, tgsi_declaration_semantic::SemanticName, pstip_transform_context::tempsUsed, TGSI_FILE_INPUT, TGSI_FILE_SAMPLER, TGSI_FILE_TEMPORARY, TGSI_SEMANTIC_POSITION, and pstip_transform_context::wincoordInput.
00132 { 00133 struct pstip_transform_context *pctx = (struct pstip_transform_context *) ctx; 00134 00135 if (decl->Declaration.File == TGSI_FILE_SAMPLER) { 00136 uint i; 00137 for (i = decl->DeclarationRange.First; 00138 i <= decl->DeclarationRange.Last; i++) { 00139 pctx->samplersUsed |= 1 << i; 00140 } 00141 } 00142 else if (decl->Declaration.File == TGSI_FILE_INPUT) { 00143 pctx->maxInput = MAX2(pctx->maxInput, (int) decl->DeclarationRange.Last); 00144 if (decl->Semantic.SemanticName == TGSI_SEMANTIC_POSITION) 00145 pctx->wincoordInput = (int) decl->DeclarationRange.First; 00146 } 00147 else if (decl->Declaration.File == TGSI_FILE_TEMPORARY) { 00148 uint i; 00149 for (i = decl->DeclarationRange.First; 00150 i <= decl->DeclarationRange.Last; i++) { 00151 pctx->tempsUsed |= (1 << i); 00152 } 00153 } 00154 00155 ctx->emit_declaration(ctx, decl); 00156 }
static void pstip_transform_immed | ( | struct tgsi_transform_context * | ctx, | |
struct tgsi_full_immediate * | immed | |||
) | [static] |
Definition at line 160 of file draw_pipe_pstipple.c.
References pstip_transform_context::numImmed.
00162 { 00163 struct pstip_transform_context *pctx = (struct pstip_transform_context *) ctx; 00164 pctx->numImmed++; 00165 }
static void pstip_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 189 of file draw_pipe_pstipple.c.
References assert, tgsi_full_declaration::Declaration, tgsi_full_declaration::DeclarationRange, tgsi_full_dst_register::DstRegister, tgsi_transform_context::emit_declaration, tgsi_transform_context::emit_immediate, tgsi_transform_context::emit_instruction, FALSE, tgsi_src_register::File, tgsi_dst_register::File, tgsi_declaration::File, tgsi_declaration_range::First, pstip_transform_context::firstInstruction, free_bit(), pstip_transform_context::freeSampler, tgsi_full_instruction::FullDstRegisters, tgsi_full_instruction::FullSrcRegisters, tgsi_full_immediate::Immediate, tgsi_src_register::Index, tgsi_dst_register::Index, tgsi_full_instruction::Instruction, tgsi_full_instruction::InstructionExtTexture, tgsi_declaration::Interpolate, tgsi_declaration_range::Last, pstip_transform_context::maxInput, tgsi_src_register::Negate, tgsi_instruction::NumDstRegs, pstip_transform_context::numImmed, tgsi_instruction::NumSrcRegs, tgsi_instruction::Opcode, PIPE_MAX_SAMPLERS, tgsi_full_immediate::Pointer, pstip_transform_context::samplersUsed, tgsi_full_declaration::Semantic, tgsi_declaration::Semantic, tgsi_declaration_semantic::SemanticIndex, tgsi_declaration_semantic::SemanticName, tgsi_immediate::Size, tgsi_full_src_register::SrcRegister, pstip_transform_context::tempsUsed, pstip_transform_context::texTemp, tgsi_instruction_ext_texture::Texture, tgsi_default_full_declaration(), tgsi_default_full_immediate(), tgsi_default_full_instruction(), TGSI_FILE_IMMEDIATE, TGSI_FILE_INPUT, TGSI_FILE_SAMPLER, TGSI_FILE_TEMPORARY, TGSI_INTERPOLATE_LINEAR, TGSI_OPCODE_KIL, TGSI_OPCODE_MUL, TGSI_OPCODE_TEX, TGSI_SEMANTIC_POSITION, TGSI_TEXTURE_2D, tgsi_full_immediate::u, and pstip_transform_context::wincoordInput.
00191 { 00192 struct pstip_transform_context *pctx = (struct pstip_transform_context *) ctx; 00193 00194 if (pctx->firstInstruction) { 00195 /* emit our new declarations before the first instruction */ 00196 00197 struct tgsi_full_declaration decl; 00198 struct tgsi_full_instruction newInst; 00199 uint i; 00200 int wincoordInput; 00201 00202 /* find free sampler */ 00203 pctx->freeSampler = free_bit(pctx->samplersUsed); 00204 if (pctx->freeSampler >= PIPE_MAX_SAMPLERS) 00205 pctx->freeSampler = PIPE_MAX_SAMPLERS - 1; 00206 00207 if (pctx->wincoordInput < 0) 00208 wincoordInput = pctx->maxInput + 1; 00209 else 00210 wincoordInput = pctx->wincoordInput; 00211 00212 /* find one free temp reg */ 00213 for (i = 0; i < 32; i++) { 00214 if ((pctx->tempsUsed & (1 << i)) == 0) { 00215 /* found a free temp */ 00216 if (pctx->texTemp < 0) 00217 pctx->texTemp = i; 00218 else 00219 break; 00220 } 00221 } 00222 assert(pctx->texTemp >= 0); 00223 00224 if (pctx->wincoordInput < 0) { 00225 /* declare new position input reg */ 00226 decl = tgsi_default_full_declaration(); 00227 decl.Declaration.File = TGSI_FILE_INPUT; 00228 decl.Declaration.Interpolate = TGSI_INTERPOLATE_LINEAR; /* XXX? */ 00229 decl.Declaration.Semantic = 1; 00230 decl.Semantic.SemanticName = TGSI_SEMANTIC_POSITION; 00231 decl.Semantic.SemanticIndex = 0; 00232 decl.DeclarationRange.First = 00233 decl.DeclarationRange.Last = wincoordInput; 00234 ctx->emit_declaration(ctx, &decl); 00235 } 00236 00237 /* declare new sampler */ 00238 decl = tgsi_default_full_declaration(); 00239 decl.Declaration.File = TGSI_FILE_SAMPLER; 00240 decl.DeclarationRange.First = 00241 decl.DeclarationRange.Last = pctx->freeSampler; 00242 ctx->emit_declaration(ctx, &decl); 00243 00244 /* declare new temp regs */ 00245 decl = tgsi_default_full_declaration(); 00246 decl.Declaration.File = TGSI_FILE_TEMPORARY; 00247 decl.DeclarationRange.First = 00248 decl.DeclarationRange.Last = pctx->texTemp; 00249 ctx->emit_declaration(ctx, &decl); 00250 00251 /* emit immediate = {1/32, 1/32, 1, 1} 00252 * The index/position of this immediate will be pctx->numImmed 00253 */ 00254 { 00255 static const float value[4] = { 1.0/32, 1.0/32, 1.0, 1.0 }; 00256 struct tgsi_full_immediate immed; 00257 uint size = 4; 00258 immed = tgsi_default_full_immediate(); 00259 immed.Immediate.Size = 1 + size; /* one for the token itself */ 00260 immed.u.Pointer = (void *) value; 00261 ctx->emit_immediate(ctx, &immed); 00262 } 00263 00264 pctx->firstInstruction = FALSE; 00265 00266 00267 /* 00268 * Insert new MUL/TEX/KILP instructions at start of program 00269 * Take gl_FragCoord, divide by 32 (stipple size), sample the 00270 * texture and kill fragment if needed. 00271 * 00272 * We'd like to use non-normalized texcoords to index into a RECT 00273 * texture, but we can only use GL_REPEAT wrap mode with normalized 00274 * texcoords. Darn. 00275 */ 00276 00277 /* MUL texTemp, INPUT[wincoord], 1/32; */ 00278 newInst = tgsi_default_full_instruction(); 00279 newInst.Instruction.Opcode = TGSI_OPCODE_MUL; 00280 newInst.Instruction.NumDstRegs = 1; 00281 newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; 00282 newInst.FullDstRegisters[0].DstRegister.Index = pctx->texTemp; 00283 newInst.Instruction.NumSrcRegs = 2; 00284 newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_INPUT; 00285 newInst.FullSrcRegisters[0].SrcRegister.Index = wincoordInput; 00286 newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_IMMEDIATE; 00287 newInst.FullSrcRegisters[1].SrcRegister.Index = pctx->numImmed; 00288 ctx->emit_instruction(ctx, &newInst); 00289 00290 /* TEX texTemp, texTemp, sampler; */ 00291 newInst = tgsi_default_full_instruction(); 00292 newInst.Instruction.Opcode = TGSI_OPCODE_TEX; 00293 newInst.Instruction.NumDstRegs = 1; 00294 newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; 00295 newInst.FullDstRegisters[0].DstRegister.Index = pctx->texTemp; 00296 newInst.Instruction.NumSrcRegs = 2; 00297 newInst.InstructionExtTexture.Texture = TGSI_TEXTURE_2D; 00298 newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; 00299 newInst.FullSrcRegisters[0].SrcRegister.Index = pctx->texTemp; 00300 newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_SAMPLER; 00301 newInst.FullSrcRegisters[1].SrcRegister.Index = pctx->freeSampler; 00302 ctx->emit_instruction(ctx, &newInst); 00303 00304 /* KIL -texTemp; # if -texTemp < 0, KILL fragment */ 00305 newInst = tgsi_default_full_instruction(); 00306 newInst.Instruction.Opcode = TGSI_OPCODE_KIL; 00307 newInst.Instruction.NumDstRegs = 0; 00308 newInst.Instruction.NumSrcRegs = 1; 00309 newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; 00310 newInst.FullSrcRegisters[0].SrcRegister.Index = pctx->texTemp; 00311 newInst.FullSrcRegisters[0].SrcRegister.Negate = 1; 00312 ctx->emit_instruction(ctx, &newInst); 00313 } 00314 00315 /* emit this instruction */ 00316 ctx->emit_instruction(ctx, inst); 00317 }
static void pstip_update_texture | ( | struct pstip_stage * | pstip | ) | [static] |
Load texture image with current stipple pattern.
Definition at line 370 of file draw_pipe_pstipple.c.
References pipe_context::flush, pipe_screen::get_tex_surface, pstip_stage::pipe, PIPE_BUFFER_USAGE_CPU_WRITE, PIPE_FLUSH_TEXTURE_CACHE, pipe_context::screen, pstip_stage::state, pipe_poly_stipple::stipple, pstip_stage::stipple, pipe_surface::stride, pipe_screen::surface_map, pipe_screen::surface_unmap, pipe_screen::tex_surface_release, and pstip_stage::texture.
00371 { 00372 static const uint bit31 = 1 << 31; 00373 struct pipe_context *pipe = pstip->pipe; 00374 struct pipe_screen *screen = pipe->screen; 00375 struct pipe_surface *surface; 00376 const uint *stipple = pstip->state.stipple->stipple; 00377 uint i, j; 00378 ubyte *data; 00379 00380 /* XXX: want to avoid flushing just because we use stipple: 00381 */ 00382 pipe->flush( pipe, PIPE_FLUSH_TEXTURE_CACHE, NULL ); 00383 00384 surface = screen->get_tex_surface(screen, pstip->texture, 0, 0, 0, 00385 PIPE_BUFFER_USAGE_CPU_WRITE); 00386 data = screen->surface_map(screen, surface, 00387 PIPE_BUFFER_USAGE_CPU_WRITE); 00388 00389 /* 00390 * Load alpha texture. 00391 * Note: 0 means keep the fragment, 255 means kill it. 00392 * We'll negate the texel value and use KILP which kills if value 00393 * is negative. 00394 */ 00395 for (i = 0; i < 32; i++) { 00396 for (j = 0; j < 32; j++) { 00397 if (stipple[i] & (bit31 >> j)) { 00398 /* fragment "on" */ 00399 data[i * surface->stride + j] = 0; 00400 } 00401 else { 00402 /* fragment "off" */ 00403 data[i * surface->stride + j] = 255; 00404 } 00405 } 00406 } 00407 00408 /* unmap */ 00409 screen->surface_unmap(screen, surface); 00410 screen->tex_surface_release(screen, &surface); 00411 }