Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /**************************************************************************
  2.  *
  3.  * Copyright 2007 VMware, Inc.
  4.  * All Rights Reserved.
  5.  *
  6.  * Permission is hereby granted, free of charge, to any person obtaining a
  7.  * copy of this software and associated documentation files (the
  8.  * "Software"), to deal in the Software without restriction, including
  9.  * without limitation the rights to use, copy, modify, merge, publish,
  10.  * distribute, sub license, and/or sell copies of the Software, and to
  11.  * permit persons to whom the Software is furnished to do so, subject to
  12.  * the following conditions:
  13.  *
  14.  * The above copyright notice and this permission notice (including the
  15.  * next paragraph) shall be included in all copies or substantial portions
  16.  * of the Software.
  17.  *
  18.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  19.  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  20.  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
  21.  * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
  22.  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  23.  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  24.  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  25.  *
  26.  **************************************************************************/
  27.  
  28. /**
  29.  * AA line stage:  AA lines are converted to texture mapped triangles.
  30.  *
  31.  * Authors:  Brian Paul
  32.  */
  33.  
  34.  
  35. #include "pipe/p_context.h"
  36. #include "pipe/p_defines.h"
  37. #include "pipe/p_shader_tokens.h"
  38. #include "util/u_inlines.h"
  39.  
  40. #include "util/u_format.h"
  41. #include "util/u_math.h"
  42. #include "util/u_memory.h"
  43. #include "util/u_sampler.h"
  44.  
  45. #include "tgsi/tgsi_transform.h"
  46. #include "tgsi/tgsi_dump.h"
  47.  
  48. #include "draw_context.h"
  49. #include "draw_private.h"
  50. #include "draw_pipe.h"
  51.  
  52.  
  53. /** Approx number of new tokens for instructions in aa_transform_inst() */
  54. #define NUM_NEW_TOKENS 50
  55.  
  56.  
  57. /**
  58.  * Size for the alpha texture used for antialiasing
  59.  */
  60. #define TEXTURE_SIZE_LOG2  5   /* 32 x 32 */
  61.  
  62. /**
  63.  * Max texture level for the alpha texture used for antialiasing
  64.  *
  65.  * Don't use the 1x1 and 2x2 mipmap levels.
  66.  */
  67. #define MAX_TEXTURE_LEVEL  (TEXTURE_SIZE_LOG2 - 2)
  68.  
  69.  
  70. /**
  71.  * Subclass of pipe_shader_state to carry extra fragment shader info.
  72.  */
  73. struct aaline_fragment_shader
  74. {
  75.    struct pipe_shader_state state;
  76.    void *driver_fs;
  77.    void *aaline_fs;
  78.    uint sampler_unit;
  79.    int generic_attrib;  /**< texcoord/generic used for texture */
  80. };
  81.  
  82.  
  83. /**
  84.  * Subclass of draw_stage
  85.  */
  86. struct aaline_stage
  87. {
  88.    struct draw_stage stage;
  89.  
  90.    float half_line_width;
  91.  
  92.    /** For AA lines, this is the vertex attrib slot for the new texcoords */
  93.    uint tex_slot;
  94.    /** position, not necessarily output zero */
  95.    uint pos_slot;
  96.  
  97.    void *sampler_cso;
  98.    struct pipe_resource *texture;
  99.    struct pipe_sampler_view *sampler_view;
  100.    uint num_samplers;
  101.    uint num_sampler_views;
  102.  
  103.  
  104.    /*
  105.     * Currently bound state
  106.     */
  107.    struct aaline_fragment_shader *fs;
  108.    struct {
  109.       void *sampler[PIPE_MAX_SAMPLERS];
  110.       struct pipe_sampler_view *sampler_views[PIPE_MAX_SHADER_SAMPLER_VIEWS];
  111.    } state;
  112.  
  113.    /*
  114.     * Driver interface/override functions
  115.     */
  116.    void * (*driver_create_fs_state)(struct pipe_context *,
  117.                                     const struct pipe_shader_state *);
  118.    void (*driver_bind_fs_state)(struct pipe_context *, void *);
  119.    void (*driver_delete_fs_state)(struct pipe_context *, void *);
  120.  
  121.    void (*driver_bind_sampler_states)(struct pipe_context *, unsigned, unsigned,
  122.                                       unsigned, void **);
  123.  
  124.    void (*driver_set_sampler_views)(struct pipe_context *, unsigned shader,
  125.                                     unsigned start, unsigned count,
  126.                                     struct pipe_sampler_view **);
  127. };
  128.  
  129.  
  130.  
  131. /**
  132.  * Subclass of tgsi_transform_context, used for transforming the
  133.  * user's fragment shader to add the special AA instructions.
  134.  */
  135. struct aa_transform_context {
  136.    struct tgsi_transform_context base;
  137.    uint tempsUsed;  /**< bitmask */
  138.    int colorOutput; /**< which output is the primary color */
  139.    uint samplersUsed;  /**< bitfield of samplers used */
  140.    int freeSampler;  /** an available sampler for the pstipple */
  141.    int maxInput, maxGeneric;  /**< max input index found */
  142.    int colorTemp, texTemp;  /**< temp registers */
  143. };
  144.  
  145.  
  146. /**
  147.  * TGSI declaration transform callback.
  148.  * Look for a free sampler, a free input attrib, and two free temp regs.
  149.  */
  150. static void
  151. aa_transform_decl(struct tgsi_transform_context *ctx,
  152.                   struct tgsi_full_declaration *decl)
  153. {
  154.    struct aa_transform_context *aactx = (struct aa_transform_context *) ctx;
  155.  
  156.    if (decl->Declaration.File == TGSI_FILE_OUTPUT &&
  157.        decl->Semantic.Name == TGSI_SEMANTIC_COLOR &&
  158.        decl->Semantic.Index == 0) {
  159.       aactx->colorOutput = decl->Range.First;
  160.    }
  161.    else if (decl->Declaration.File == TGSI_FILE_SAMPLER) {
  162.       uint i;
  163.       for (i = decl->Range.First;
  164.            i <= decl->Range.Last; i++) {
  165.          aactx->samplersUsed |= 1 << i;
  166.       }
  167.    }
  168.    else if (decl->Declaration.File == TGSI_FILE_INPUT) {
  169.       if ((int) decl->Range.Last > aactx->maxInput)
  170.          aactx->maxInput = decl->Range.Last;
  171.       if (decl->Semantic.Name == TGSI_SEMANTIC_GENERIC &&
  172.            (int) decl->Semantic.Index > aactx->maxGeneric) {
  173.          aactx->maxGeneric = decl->Semantic.Index;
  174.       }
  175.    }
  176.    else if (decl->Declaration.File == TGSI_FILE_TEMPORARY) {
  177.       uint i;
  178.       for (i = decl->Range.First;
  179.            i <= decl->Range.Last; i++) {
  180.          aactx->tempsUsed |= (1 << i);
  181.       }
  182.    }
  183.  
  184.    ctx->emit_declaration(ctx, decl);
  185. }
  186.  
  187.  
  188. /**
  189.  * Find the lowest zero bit in the given word, or -1 if bitfield is all ones.
  190.  */
  191. static int
  192. free_bit(uint bitfield)
  193. {
  194.    return ffs(~bitfield) - 1;
  195. }
  196.  
  197.  
  198. /**
  199.  * TGSI transform prolog callback.
  200.  */
  201. static void
  202. aa_transform_prolog(struct tgsi_transform_context *ctx)
  203. {
  204.    struct aa_transform_context *aactx = (struct aa_transform_context *) ctx;
  205.    uint i;
  206.  
  207.    /* find free sampler */
  208.    aactx->freeSampler = free_bit(aactx->samplersUsed);
  209.    if (aactx->freeSampler >= PIPE_MAX_SAMPLERS)
  210.       aactx->freeSampler = PIPE_MAX_SAMPLERS - 1;
  211.  
  212.    /* find two free temp regs */
  213.    for (i = 0; i < 32; i++) {
  214.       if ((aactx->tempsUsed & (1 << i)) == 0) {
  215.       /* found a free temp */
  216.       if (aactx->colorTemp < 0)
  217.          aactx->colorTemp  = i;
  218.       else if (aactx->texTemp < 0)
  219.          aactx->texTemp  = i;
  220.       else
  221.          break;
  222.       }
  223.    }
  224.    assert(aactx->colorTemp >= 0);
  225.    assert(aactx->texTemp >= 0);
  226.  
  227.    /* declare new generic input/texcoord */
  228.    tgsi_transform_input_decl(ctx, aactx->maxInput + 1,
  229.                              TGSI_SEMANTIC_GENERIC, aactx->maxGeneric + 1,
  230.                              TGSI_INTERPOLATE_LINEAR);
  231.  
  232.    /* declare new sampler */
  233.    tgsi_transform_sampler_decl(ctx, aactx->freeSampler);
  234.  
  235.    /* declare new temp regs */
  236.    tgsi_transform_temp_decl(ctx, aactx->texTemp);
  237.    tgsi_transform_temp_decl(ctx, aactx->colorTemp);
  238. }
  239.  
  240.  
  241. /**
  242.  * TGSI transform epilog callback.
  243.  */
  244. static void
  245. aa_transform_epilog(struct tgsi_transform_context *ctx)
  246. {
  247.    struct aa_transform_context *aactx = (struct aa_transform_context *) ctx;
  248.  
  249.    if (aactx->colorOutput != -1) {
  250.       /* insert texture sampling code for antialiasing. */
  251.  
  252.       /* TEX texTemp, input_coord, sampler */
  253.       tgsi_transform_tex_2d_inst(ctx,
  254.                                  TGSI_FILE_TEMPORARY, aactx->texTemp,
  255.                                  TGSI_FILE_INPUT, aactx->maxInput + 1,
  256.                                  aactx->freeSampler);
  257.  
  258.       /* MOV rgb */
  259.       tgsi_transform_op1_inst(ctx, TGSI_OPCODE_MOV,
  260.                               TGSI_FILE_OUTPUT, aactx->colorOutput,
  261.                               TGSI_WRITEMASK_XYZ,
  262.                               TGSI_FILE_TEMPORARY, aactx->colorTemp);
  263.  
  264.       /* MUL alpha */
  265.       tgsi_transform_op2_inst(ctx, TGSI_OPCODE_MUL,
  266.                               TGSI_FILE_OUTPUT, aactx->colorOutput,
  267.                               TGSI_WRITEMASK_W,
  268.                               TGSI_FILE_TEMPORARY, aactx->colorTemp,
  269.                               TGSI_FILE_TEMPORARY, aactx->texTemp);
  270.    }
  271. }
  272.  
  273.  
  274. /**
  275.  * TGSI instruction transform callback.
  276.  * Replace writes to result.color w/ a temp reg.
  277.  */
  278. static void
  279. aa_transform_inst(struct tgsi_transform_context *ctx,
  280.                   struct tgsi_full_instruction *inst)
  281. {
  282.    struct aa_transform_context *aactx = (struct aa_transform_context *) ctx;
  283.    uint i;
  284.  
  285.    /*
  286.     * Look for writes to result.color and replace with colorTemp reg.
  287.     */
  288.    for (i = 0; i < inst->Instruction.NumDstRegs; i++) {
  289.       struct tgsi_full_dst_register *dst = &inst->Dst[i];
  290.       if (dst->Register.File == TGSI_FILE_OUTPUT &&
  291.           dst->Register.Index == aactx->colorOutput) {
  292.          dst->Register.File = TGSI_FILE_TEMPORARY;
  293.          dst->Register.Index = aactx->colorTemp;
  294.       }
  295.    }
  296.  
  297.    ctx->emit_instruction(ctx, inst);
  298. }
  299.  
  300.  
  301. /**
  302.  * Generate the frag shader we'll use for drawing AA lines.
  303.  * This will be the user's shader plus some texture/modulate instructions.
  304.  */
  305. static boolean
  306. generate_aaline_fs(struct aaline_stage *aaline)
  307. {
  308.    struct pipe_context *pipe = aaline->stage.draw->pipe;
  309.    const struct pipe_shader_state *orig_fs = &aaline->fs->state;
  310.    struct pipe_shader_state aaline_fs;
  311.    struct aa_transform_context transform;
  312.    const uint newLen = tgsi_num_tokens(orig_fs->tokens) + NUM_NEW_TOKENS;
  313.  
  314.    aaline_fs = *orig_fs; /* copy to init */
  315.    aaline_fs.tokens = tgsi_alloc_tokens(newLen);
  316.    if (aaline_fs.tokens == NULL)
  317.       return FALSE;
  318.  
  319.    memset(&transform, 0, sizeof(transform));
  320.    transform.colorOutput = -1;
  321.    transform.maxInput = -1;
  322.    transform.maxGeneric = -1;
  323.    transform.colorTemp = -1;
  324.    transform.texTemp = -1;
  325.    transform.base.prolog = aa_transform_prolog;
  326.    transform.base.epilog = aa_transform_epilog;
  327.    transform.base.transform_instruction = aa_transform_inst;
  328.    transform.base.transform_declaration = aa_transform_decl;
  329.  
  330.    tgsi_transform_shader(orig_fs->tokens,
  331.                          (struct tgsi_token *) aaline_fs.tokens,
  332.                          newLen, &transform.base);
  333.  
  334. #if 0 /* DEBUG */
  335.    debug_printf("draw_aaline, orig shader:\n");
  336.    tgsi_dump(orig_fs->tokens, 0);
  337.    debug_printf("draw_aaline, new shader:\n");
  338.    tgsi_dump(aaline_fs.tokens, 0);
  339. #endif
  340.  
  341.    aaline->fs->sampler_unit = transform.freeSampler;
  342.  
  343.    aaline->fs->aaline_fs = aaline->driver_create_fs_state(pipe, &aaline_fs);
  344.    if (aaline->fs->aaline_fs == NULL)
  345.       goto fail;
  346.  
  347.    aaline->fs->generic_attrib = transform.maxGeneric + 1;
  348.    FREE((void *)aaline_fs.tokens);
  349.    return TRUE;
  350.  
  351. fail:
  352.    FREE((void *)aaline_fs.tokens);
  353.    return FALSE;
  354. }
  355.  
  356.  
  357. /**
  358.  * Create the texture map we'll use for antialiasing the lines.
  359.  */
  360. static boolean
  361. aaline_create_texture(struct aaline_stage *aaline)
  362. {
  363.    struct pipe_context *pipe = aaline->stage.draw->pipe;
  364.    struct pipe_screen *screen = pipe->screen;
  365.    struct pipe_resource texTemp;
  366.    struct pipe_sampler_view viewTempl;
  367.    uint level;
  368.  
  369.    memset(&texTemp, 0, sizeof(texTemp));
  370.    texTemp.target = PIPE_TEXTURE_2D;
  371.    texTemp.format = PIPE_FORMAT_A8_UNORM; /* XXX verify supported by driver! */
  372.    texTemp.last_level = MAX_TEXTURE_LEVEL;
  373.    texTemp.width0 = 1 << TEXTURE_SIZE_LOG2;
  374.    texTemp.height0 = 1 << TEXTURE_SIZE_LOG2;
  375.    texTemp.depth0 = 1;
  376.    texTemp.array_size = 1;
  377.    texTemp.bind = PIPE_BIND_SAMPLER_VIEW;
  378.  
  379.    aaline->texture = screen->resource_create(screen, &texTemp);
  380.    if (!aaline->texture)
  381.       return FALSE;
  382.  
  383.    u_sampler_view_default_template(&viewTempl,
  384.                                    aaline->texture,
  385.                                    aaline->texture->format);
  386.    aaline->sampler_view = pipe->create_sampler_view(pipe,
  387.                                                     aaline->texture,
  388.                                                     &viewTempl);
  389.    if (!aaline->sampler_view) {
  390.       return FALSE;
  391.    }
  392.  
  393.    /* Fill in mipmap images.
  394.     * Basically each level is solid opaque, except for the outermost
  395.     * texels which are zero.  Special case the 1x1 and 2x2 levels
  396.     * (though, those levels shouldn't be used - see the max_lod setting).
  397.     */
  398.    for (level = 0; level <= MAX_TEXTURE_LEVEL; level++) {
  399.       struct pipe_transfer *transfer;
  400.       struct pipe_box box;
  401.       const uint size = u_minify(aaline->texture->width0, level);
  402.       ubyte *data;
  403.       uint i, j;
  404.  
  405.       assert(aaline->texture->width0 == aaline->texture->height0);
  406.  
  407.       u_box_origin_2d( size, size, &box );
  408.  
  409.       /* This texture is new, no need to flush.
  410.        */
  411.       data = pipe->transfer_map(pipe,
  412.                                 aaline->texture,
  413.                                 level,
  414.                                 PIPE_TRANSFER_WRITE,
  415.                                 &box, &transfer);
  416.  
  417.       if (data == NULL)
  418.          return FALSE;
  419.  
  420.       for (i = 0; i < size; i++) {
  421.          for (j = 0; j < size; j++) {
  422.             ubyte d;
  423.             if (size == 1) {
  424.                d = 255;
  425.             }
  426.             else if (size == 2) {
  427.                d = 200; /* tuneable */
  428.             }
  429.             else if (i == 0 || j == 0 || i == size - 1 || j == size - 1) {
  430.                d = 35;  /* edge texel */
  431.             }
  432.             else {
  433.                d = 255;
  434.             }
  435.             data[i * transfer->stride + j] = d;
  436.          }
  437.       }
  438.  
  439.       /* unmap */
  440.       pipe->transfer_unmap(pipe, transfer);
  441.    }
  442.    return TRUE;
  443. }
  444.  
  445.  
  446. /**
  447.  * Create the sampler CSO that'll be used for antialiasing.
  448.  * By using a mipmapped texture, we don't have to generate a different
  449.  * texture image for each line size.
  450.  */
  451. static boolean
  452. aaline_create_sampler(struct aaline_stage *aaline)
  453. {
  454.    struct pipe_sampler_state sampler;
  455.    struct pipe_context *pipe = aaline->stage.draw->pipe;
  456.  
  457.    memset(&sampler, 0, sizeof(sampler));
  458.    sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
  459.    sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
  460.    sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
  461.    sampler.min_mip_filter = PIPE_TEX_MIPFILTER_LINEAR;
  462.    sampler.min_img_filter = PIPE_TEX_FILTER_LINEAR;
  463.    sampler.mag_img_filter = PIPE_TEX_FILTER_LINEAR;
  464.    sampler.normalized_coords = 1;
  465.    sampler.min_lod = 0.0f;
  466.    sampler.max_lod = MAX_TEXTURE_LEVEL;
  467.  
  468.    aaline->sampler_cso = pipe->create_sampler_state(pipe, &sampler);
  469.    if (aaline->sampler_cso == NULL)
  470.       return FALSE;
  471.  
  472.    return TRUE;
  473. }
  474.  
  475.  
  476. /**
  477.  * When we're about to draw our first AA line in a batch, this function is
  478.  * called to tell the driver to bind our modified fragment shader.
  479.  */
  480. static boolean
  481. bind_aaline_fragment_shader(struct aaline_stage *aaline)
  482. {
  483.    struct draw_context *draw = aaline->stage.draw;
  484.    struct pipe_context *pipe = draw->pipe;
  485.  
  486.    if (!aaline->fs->aaline_fs &&
  487.        !generate_aaline_fs(aaline))
  488.       return FALSE;
  489.  
  490.    draw->suspend_flushing = TRUE;
  491.    aaline->driver_bind_fs_state(pipe, aaline->fs->aaline_fs);
  492.    draw->suspend_flushing = FALSE;
  493.  
  494.    return TRUE;
  495. }
  496.  
  497.  
  498.  
  499. static INLINE struct aaline_stage *
  500. aaline_stage( struct draw_stage *stage )
  501. {
  502.    return (struct aaline_stage *) stage;
  503. }
  504.  
  505.  
  506. /**
  507.  * Draw a wide line by drawing a quad, using geometry which will
  508.  * fullfill GL's antialiased line requirements.
  509.  */
  510. static void
  511. aaline_line(struct draw_stage *stage, struct prim_header *header)
  512. {
  513.    const struct aaline_stage *aaline = aaline_stage(stage);
  514.    const float half_width = aaline->half_line_width;
  515.    struct prim_header tri;
  516.    struct vertex_header *v[8];
  517.    uint texPos = aaline->tex_slot;
  518.    uint posPos = aaline->pos_slot;
  519.    float *pos, *tex;
  520.    float dx = header->v[1]->data[posPos][0] - header->v[0]->data[posPos][0];
  521.    float dy = header->v[1]->data[posPos][1] - header->v[0]->data[posPos][1];
  522.    double a = atan2(dy, dx);
  523.    float c_a = (float) cos(a), s_a = (float) sin(a);
  524.    uint i;
  525.  
  526.    /* XXX the ends of lines aren't quite perfect yet, but probably passable */
  527.    dx = 0.5F * half_width;
  528.    dy = half_width;
  529.  
  530.    /* allocate/dup new verts */
  531.    for (i = 0; i < 8; i++) {
  532.       v[i] = dup_vert(stage, header->v[i/4], i);
  533.    }
  534.  
  535.    /*
  536.     * Quad strip for line from v0 to v1 (*=endpoints):
  537.     *
  538.     *  1   3                     5   7
  539.     *  +---+---------------------+---+
  540.     *  |                             |
  541.     *  | *v0                     v1* |
  542.     *  |                             |
  543.     *  +---+---------------------+---+
  544.     *  0   2                     4   6
  545.     */
  546.  
  547.    /* new verts */
  548.    pos = v[0]->data[posPos];
  549.    pos[0] += (-dx * c_a -  dy * s_a);
  550.    pos[1] += (-dx * s_a +  dy * c_a);
  551.  
  552.    pos = v[1]->data[posPos];
  553.    pos[0] += (-dx * c_a - -dy * s_a);
  554.    pos[1] += (-dx * s_a + -dy * c_a);
  555.  
  556.    pos = v[2]->data[posPos];
  557.    pos[0] += ( dx * c_a -  dy * s_a);
  558.    pos[1] += ( dx * s_a +  dy * c_a);
  559.  
  560.    pos = v[3]->data[posPos];
  561.    pos[0] += ( dx * c_a - -dy * s_a);
  562.    pos[1] += ( dx * s_a + -dy * c_a);
  563.  
  564.    pos = v[4]->data[posPos];
  565.    pos[0] += (-dx * c_a -  dy * s_a);
  566.    pos[1] += (-dx * s_a +  dy * c_a);
  567.  
  568.    pos = v[5]->data[posPos];
  569.    pos[0] += (-dx * c_a - -dy * s_a);
  570.    pos[1] += (-dx * s_a + -dy * c_a);
  571.  
  572.    pos = v[6]->data[posPos];
  573.    pos[0] += ( dx * c_a -  dy * s_a);
  574.    pos[1] += ( dx * s_a +  dy * c_a);
  575.  
  576.    pos = v[7]->data[posPos];
  577.    pos[0] += ( dx * c_a - -dy * s_a);
  578.    pos[1] += ( dx * s_a + -dy * c_a);
  579.  
  580.    /* new texcoords */
  581.    tex = v[0]->data[texPos];
  582.    ASSIGN_4V(tex, 0, 0, 0, 1);
  583.  
  584.    tex = v[1]->data[texPos];
  585.    ASSIGN_4V(tex, 0, 1, 0, 1);
  586.  
  587.    tex = v[2]->data[texPos];
  588.    ASSIGN_4V(tex, .5, 0, 0, 1);
  589.  
  590.    tex = v[3]->data[texPos];
  591.    ASSIGN_4V(tex, .5, 1, 0, 1);
  592.  
  593.    tex = v[4]->data[texPos];
  594.    ASSIGN_4V(tex, .5, 0, 0, 1);
  595.  
  596.    tex = v[5]->data[texPos];
  597.    ASSIGN_4V(tex, .5, 1, 0, 1);
  598.  
  599.    tex = v[6]->data[texPos];
  600.    ASSIGN_4V(tex, 1, 0, 0, 1);
  601.  
  602.    tex = v[7]->data[texPos];
  603.    ASSIGN_4V(tex, 1, 1, 0, 1);
  604.  
  605.    /* emit 6 tris for the quad strip */
  606.    tri.v[0] = v[2];  tri.v[1] = v[1];  tri.v[2] = v[0];
  607.    stage->next->tri( stage->next, &tri );
  608.  
  609.    tri.v[0] = v[3];  tri.v[1] = v[1];  tri.v[2] = v[2];
  610.    stage->next->tri( stage->next, &tri );
  611.  
  612.    tri.v[0] = v[4];  tri.v[1] = v[3];  tri.v[2] = v[2];
  613.    stage->next->tri( stage->next, &tri );
  614.  
  615.    tri.v[0] = v[5];  tri.v[1] = v[3];  tri.v[2] = v[4];
  616.    stage->next->tri( stage->next, &tri );
  617.  
  618.    tri.v[0] = v[6];  tri.v[1] = v[5];  tri.v[2] = v[4];
  619.    stage->next->tri( stage->next, &tri );
  620.  
  621.    tri.v[0] = v[7];  tri.v[1] = v[5];  tri.v[2] = v[6];
  622.    stage->next->tri( stage->next, &tri );
  623. }
  624.  
  625.  
  626. static void
  627. aaline_first_line(struct draw_stage *stage, struct prim_header *header)
  628. {
  629.    auto struct aaline_stage *aaline = aaline_stage(stage);
  630.    struct draw_context *draw = stage->draw;
  631.    struct pipe_context *pipe = draw->pipe;
  632.    const struct pipe_rasterizer_state *rast = draw->rasterizer;
  633.    uint num_samplers;
  634.    void *r;
  635.  
  636.    assert(draw->rasterizer->line_smooth);
  637.  
  638.    if (draw->rasterizer->line_width <= 2.2)
  639.       aaline->half_line_width = 1.1f;
  640.    else
  641.       aaline->half_line_width = 0.5f * draw->rasterizer->line_width;
  642.  
  643.    /*
  644.     * Bind (generate) our fragprog, sampler and texture
  645.     */
  646.    if (!bind_aaline_fragment_shader(aaline)) {
  647.       stage->line = draw_pipe_passthrough_line;
  648.       stage->line(stage, header);
  649.       return;
  650.    }
  651.  
  652.    draw_aaline_prepare_outputs(draw, draw->pipeline.aaline);
  653.  
  654.    /* how many samplers? */
  655.    /* we'll use sampler/texture[pstip->sampler_unit] for the stipple */
  656.    num_samplers = MAX2(aaline->num_sampler_views, aaline->num_samplers);
  657.    num_samplers = MAX2(num_samplers, aaline->fs->sampler_unit + 1);
  658.  
  659.    aaline->state.sampler[aaline->fs->sampler_unit] = aaline->sampler_cso;
  660.    pipe_sampler_view_reference(&aaline->state.sampler_views[aaline->fs->sampler_unit],
  661.                                aaline->sampler_view);
  662.  
  663.    draw->suspend_flushing = TRUE;
  664.  
  665.    aaline->driver_bind_sampler_states(pipe, PIPE_SHADER_FRAGMENT, 0,
  666.                                       num_samplers, aaline->state.sampler);
  667.  
  668.    aaline->driver_set_sampler_views(pipe, PIPE_SHADER_FRAGMENT, 0,
  669.                                     num_samplers, aaline->state.sampler_views);
  670.  
  671.    /* Disable triangle culling, stippling, unfilled mode etc. */
  672.    r = draw_get_rasterizer_no_cull(draw, rast->scissor, rast->flatshade);
  673.    pipe->bind_rasterizer_state(pipe, r);
  674.  
  675.    draw->suspend_flushing = FALSE;
  676.  
  677.    /* now really draw first line */
  678.    stage->line = aaline_line;
  679.    stage->line(stage, header);
  680. }
  681.  
  682.  
  683. static void
  684. aaline_flush(struct draw_stage *stage, unsigned flags)
  685. {
  686.    struct draw_context *draw = stage->draw;
  687.    struct aaline_stage *aaline = aaline_stage(stage);
  688.    struct pipe_context *pipe = draw->pipe;
  689.  
  690.    stage->line = aaline_first_line;
  691.    stage->next->flush( stage->next, flags );
  692.  
  693.    /* restore original frag shader, texture, sampler state */
  694.    draw->suspend_flushing = TRUE;
  695.    aaline->driver_bind_fs_state(pipe, aaline->fs ? aaline->fs->driver_fs : NULL);
  696.  
  697.    aaline->driver_bind_sampler_states(pipe, PIPE_SHADER_FRAGMENT, 0,
  698.                                       aaline->num_samplers,
  699.                                       aaline->state.sampler);
  700.  
  701.    aaline->driver_set_sampler_views(pipe, PIPE_SHADER_FRAGMENT, 0,
  702.                                     aaline->num_samplers,
  703.                                     aaline->state.sampler_views);
  704.  
  705.    /* restore original rasterizer state */
  706.    if (draw->rast_handle) {
  707.       pipe->bind_rasterizer_state(pipe, draw->rast_handle);
  708.    }
  709.  
  710.    draw->suspend_flushing = FALSE;
  711.  
  712.    draw_remove_extra_vertex_attribs(draw);
  713. }
  714.  
  715.  
  716. static void
  717. aaline_reset_stipple_counter(struct draw_stage *stage)
  718. {
  719.    stage->next->reset_stipple_counter( stage->next );
  720. }
  721.  
  722.  
  723. static void
  724. aaline_destroy(struct draw_stage *stage)
  725. {
  726.    struct aaline_stage *aaline = aaline_stage(stage);
  727.    struct pipe_context *pipe = stage->draw->pipe;
  728.    uint i;
  729.  
  730.    for (i = 0; i < PIPE_MAX_SHADER_SAMPLER_VIEWS; i++) {
  731.       pipe_sampler_view_reference(&aaline->state.sampler_views[i], NULL);
  732.    }
  733.  
  734.    if (aaline->sampler_cso)
  735.       pipe->delete_sampler_state(pipe, aaline->sampler_cso);
  736.  
  737.    if (aaline->texture)
  738.       pipe_resource_reference(&aaline->texture, NULL);
  739.  
  740.    if (aaline->sampler_view) {
  741.       pipe_sampler_view_reference(&aaline->sampler_view, NULL);
  742.    }
  743.  
  744.    draw_free_temp_verts( stage );
  745.  
  746.    /* restore the old entry points */
  747.    pipe->create_fs_state = aaline->driver_create_fs_state;
  748.    pipe->bind_fs_state = aaline->driver_bind_fs_state;
  749.    pipe->delete_fs_state = aaline->driver_delete_fs_state;
  750.  
  751.    pipe->bind_sampler_states = aaline->driver_bind_sampler_states;
  752.    pipe->set_sampler_views = aaline->driver_set_sampler_views;
  753.  
  754.    FREE( stage );
  755. }
  756.  
  757.  
  758. static struct aaline_stage *
  759. draw_aaline_stage(struct draw_context *draw)
  760. {
  761.    struct aaline_stage *aaline = CALLOC_STRUCT(aaline_stage);
  762.    if (aaline == NULL)
  763.       return NULL;
  764.  
  765.    aaline->stage.draw = draw;
  766.    aaline->stage.name = "aaline";
  767.    aaline->stage.next = NULL;
  768.    aaline->stage.point = draw_pipe_passthrough_point;
  769.    aaline->stage.line = aaline_first_line;
  770.    aaline->stage.tri = draw_pipe_passthrough_tri;
  771.    aaline->stage.flush = aaline_flush;
  772.    aaline->stage.reset_stipple_counter = aaline_reset_stipple_counter;
  773.    aaline->stage.destroy = aaline_destroy;
  774.  
  775.    if (!draw_alloc_temp_verts( &aaline->stage, 8 ))
  776.       goto fail;
  777.  
  778.    return aaline;
  779.  
  780.  fail:
  781.    if (aaline)
  782.       aaline->stage.destroy(&aaline->stage);
  783.  
  784.    return NULL;
  785. }
  786.  
  787.  
  788. static struct aaline_stage *
  789. aaline_stage_from_pipe(struct pipe_context *pipe)
  790. {
  791.    struct draw_context *draw = (struct draw_context *) pipe->draw;
  792.  
  793.    if (draw) {
  794.       return aaline_stage(draw->pipeline.aaline);
  795.    } else {
  796.       return NULL;
  797.    }
  798. }
  799.  
  800.  
  801. /**
  802.  * This function overrides the driver's create_fs_state() function and
  803.  * will typically be called by the state tracker.
  804.  */
  805. static void *
  806. aaline_create_fs_state(struct pipe_context *pipe,
  807.                        const struct pipe_shader_state *fs)
  808. {
  809.    struct aaline_stage *aaline = aaline_stage_from_pipe(pipe);
  810.    struct aaline_fragment_shader *aafs = NULL;
  811.  
  812.    if (aaline == NULL)
  813.       return NULL;
  814.  
  815.    aafs = CALLOC_STRUCT(aaline_fragment_shader);
  816.  
  817.    if (aafs == NULL)
  818.       return NULL;
  819.  
  820.    aafs->state.tokens = tgsi_dup_tokens(fs->tokens);
  821.  
  822.    /* pass-through */
  823.    aafs->driver_fs = aaline->driver_create_fs_state(pipe, fs);
  824.  
  825.    return aafs;
  826. }
  827.  
  828.  
  829. static void
  830. aaline_bind_fs_state(struct pipe_context *pipe, void *fs)
  831. {
  832.    struct aaline_stage *aaline = aaline_stage_from_pipe(pipe);
  833.    struct aaline_fragment_shader *aafs = (struct aaline_fragment_shader *) fs;
  834.  
  835.    if (aaline == NULL) {
  836.       return;
  837.    }
  838.  
  839.    /* save current */
  840.    aaline->fs = aafs;
  841.    /* pass-through */
  842.    aaline->driver_bind_fs_state(pipe, (aafs ? aafs->driver_fs : NULL));
  843. }
  844.  
  845.  
  846. static void
  847. aaline_delete_fs_state(struct pipe_context *pipe, void *fs)
  848. {
  849.    struct aaline_stage *aaline = aaline_stage_from_pipe(pipe);
  850.    struct aaline_fragment_shader *aafs = (struct aaline_fragment_shader *) fs;
  851.  
  852.    if (aafs == NULL) {
  853.       return;
  854.    }
  855.  
  856.    if (aaline != NULL) {
  857.       /* pass-through */
  858.       aaline->driver_delete_fs_state(pipe, aafs->driver_fs);
  859.  
  860.       if (aafs->aaline_fs)
  861.          aaline->driver_delete_fs_state(pipe, aafs->aaline_fs);
  862.    }
  863.  
  864.    FREE((void*)aafs->state.tokens);
  865.    FREE(aafs);
  866. }
  867.  
  868.  
  869. static void
  870. aaline_bind_sampler_states(struct pipe_context *pipe, unsigned shader,
  871.                            unsigned start, unsigned num, void **sampler)
  872. {
  873.    struct aaline_stage *aaline = aaline_stage_from_pipe(pipe);
  874.  
  875.    assert(start == 0);
  876.  
  877.    if (aaline == NULL) {
  878.       return;
  879.    }
  880.  
  881.    if (shader == PIPE_SHADER_FRAGMENT) {
  882.       /* save current */
  883.       memcpy(aaline->state.sampler, sampler, num * sizeof(void *));
  884.       aaline->num_samplers = num;
  885.    }
  886.  
  887.    /* pass-through */
  888.    aaline->driver_bind_sampler_states(pipe, shader, start, num, sampler);
  889. }
  890.  
  891.  
  892. static void
  893. aaline_set_sampler_views(struct pipe_context *pipe, unsigned shader,
  894.                          unsigned start, unsigned num,
  895.                          struct pipe_sampler_view **views)
  896. {
  897.    struct aaline_stage *aaline = aaline_stage_from_pipe(pipe);
  898.    uint i;
  899.  
  900.    if (aaline == NULL) {
  901.       return;
  902.    }
  903.  
  904.    if (shader == PIPE_SHADER_FRAGMENT) {
  905.       /* save current */
  906.       for (i = 0; i < num; i++) {
  907.          pipe_sampler_view_reference(&aaline->state.sampler_views[start + i],
  908.                                      views[i]);
  909.       }
  910.       aaline->num_sampler_views = num;
  911.    }
  912.  
  913.    /* pass-through */
  914.    aaline->driver_set_sampler_views(pipe, shader, start, num, views);
  915. }
  916.  
  917.  
  918. void
  919. draw_aaline_prepare_outputs(struct draw_context *draw,
  920.                             struct draw_stage *stage)
  921. {
  922.    struct aaline_stage *aaline = aaline_stage(stage);
  923.    const struct pipe_rasterizer_state *rast = draw->rasterizer;
  924.  
  925.    /* update vertex attrib info */
  926.    aaline->pos_slot = draw_current_shader_position_output(draw);;
  927.  
  928.    if (!rast->line_smooth)
  929.       return;
  930.  
  931.    /* allocate the extra post-transformed vertex attribute */
  932.    aaline->tex_slot = draw_alloc_extra_vertex_attrib(draw,
  933.                                                      TGSI_SEMANTIC_GENERIC,
  934.                                                      aaline->fs->generic_attrib);
  935. }
  936.  
  937. /**
  938.  * Called by drivers that want to install this AA line prim stage
  939.  * into the draw module's pipeline.  This will not be used if the
  940.  * hardware has native support for AA lines.
  941.  */
  942. boolean
  943. draw_install_aaline_stage(struct draw_context *draw, struct pipe_context *pipe)
  944. {
  945.    struct aaline_stage *aaline;
  946.  
  947.    pipe->draw = (void *) draw;
  948.  
  949.    /*
  950.     * Create / install AA line drawing / prim stage
  951.     */
  952.    aaline = draw_aaline_stage( draw );
  953.    if (!aaline)
  954.       goto fail;
  955.  
  956.    /* save original driver functions */
  957.    aaline->driver_create_fs_state = pipe->create_fs_state;
  958.    aaline->driver_bind_fs_state = pipe->bind_fs_state;
  959.    aaline->driver_delete_fs_state = pipe->delete_fs_state;
  960.  
  961.    aaline->driver_bind_sampler_states = pipe->bind_sampler_states;
  962.    aaline->driver_set_sampler_views = pipe->set_sampler_views;
  963.  
  964.    /* create special texture, sampler state */
  965.    if (!aaline_create_texture(aaline))
  966.       goto fail;
  967.  
  968.    if (!aaline_create_sampler(aaline))
  969.       goto fail;
  970.  
  971.    /* override the driver's functions */
  972.    pipe->create_fs_state = aaline_create_fs_state;
  973.    pipe->bind_fs_state = aaline_bind_fs_state;
  974.    pipe->delete_fs_state = aaline_delete_fs_state;
  975.  
  976.    pipe->bind_sampler_states = aaline_bind_sampler_states;
  977.    pipe->set_sampler_views = aaline_set_sampler_views;
  978.    
  979.    /* Install once everything is known to be OK:
  980.     */
  981.    draw->pipeline.aaline = &aaline->stage;
  982.  
  983.    return TRUE;
  984.  
  985.  fail:
  986.    if (aaline)
  987.       aaline->stage.destroy( &aaline->stage );
  988.    
  989.    return FALSE;
  990. }
  991.