draw_pipe_pstipple.c File Reference

Include dependency graph for draw_pipe_pstipple.c:

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_stagepstip_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_stagedraw_pstip_stage (struct draw_context *draw)
static struct pstip_stagepstip_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 Documentation

#define MAX   1000


Function Documentation

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 }


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