Home | History | Annotate | Download | only in state_tracker
      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   * Authors:
     30   *   Brian Paul
     31   */
     32 
     33 #include "main/imports.h"
     34 #include "main/image.h"
     35 #include "main/bufferobj.h"
     36 #include "main/dlist.h"
     37 #include "main/macros.h"
     38 #include "main/pbo.h"
     39 #include "program/program.h"
     40 #include "program/prog_print.h"
     41 
     42 #include "st_context.h"
     43 #include "st_atom.h"
     44 #include "st_atom_constbuf.h"
     45 #include "st_draw.h"
     46 #include "st_program.h"
     47 #include "st_cb_bitmap.h"
     48 #include "st_sampler_view.h"
     49 #include "st_texture.h"
     50 
     51 #include "pipe/p_context.h"
     52 #include "pipe/p_defines.h"
     53 #include "pipe/p_shader_tokens.h"
     54 #include "util/u_inlines.h"
     55 #include "util/u_simple_shaders.h"
     56 #include "util/u_upload_mgr.h"
     57 #include "program/prog_instruction.h"
     58 #include "cso_cache/cso_context.h"
     59 
     60 
     61 /**
     62  * glBitmaps are drawn as textured quads.  The user's bitmap pattern
     63  * is stored in a texture image.  An alpha8 texture format is used.
     64  * The fragment shader samples a bit (texel) from the texture, then
     65  * discards the fragment if the bit is off.
     66  *
     67  * Note that we actually store the inverse image of the bitmap to
     68  * simplify the fragment program.  An "on" bit gets stored as texel=0x0
     69  * and an "off" bit is stored as texel=0xff.  Then we kill the
     70  * fragment if the negated texel value is less than zero.
     71  */
     72 
     73 
     74 /**
     75  * The bitmap cache attempts to accumulate multiple glBitmap calls in a
     76  * buffer which is then rendered en mass upon a flush, state change, etc.
     77  * A wide, short buffer is used to target the common case of a series
     78  * of glBitmap calls being used to draw text.
     79  */
     80 static GLboolean UseBitmapCache = GL_TRUE;
     81 
     82 
     83 #define BITMAP_CACHE_WIDTH  512
     84 #define BITMAP_CACHE_HEIGHT 32
     85 
     86 
     87 /** Epsilon for Z comparisons */
     88 #define Z_EPSILON 1e-06
     89 
     90 
     91 /**
     92  * Copy user-provide bitmap bits into texture buffer, expanding
     93  * bits into texels.
     94  * "On" bits will set texels to 0x0.
     95  * "Off" bits will not modify texels.
     96  * Note that the image is actually going to be upside down in
     97  * the texture.  We deal with that with texcoords.
     98  */
     99 static void
    100 unpack_bitmap(struct st_context *st,
    101               GLint px, GLint py, GLsizei width, GLsizei height,
    102               const struct gl_pixelstore_attrib *unpack,
    103               const GLubyte *bitmap,
    104               ubyte *destBuffer, uint destStride)
    105 {
    106    destBuffer += py * destStride + px;
    107 
    108    _mesa_expand_bitmap(width, height, unpack, bitmap,
    109                        destBuffer, destStride, 0x0);
    110 }
    111 
    112 
    113 /**
    114  * Create a texture which represents a bitmap image.
    115  */
    116 static struct pipe_resource *
    117 make_bitmap_texture(struct gl_context *ctx, GLsizei width, GLsizei height,
    118                     const struct gl_pixelstore_attrib *unpack,
    119                     const GLubyte *bitmap)
    120 {
    121    struct st_context *st = st_context(ctx);
    122    struct pipe_context *pipe = st->pipe;
    123    struct pipe_transfer *transfer;
    124    ubyte *dest;
    125    struct pipe_resource *pt;
    126 
    127    /* PBO source... */
    128    bitmap = _mesa_map_pbo_source(ctx, unpack, bitmap);
    129    if (!bitmap) {
    130       return NULL;
    131    }
    132 
    133    /**
    134     * Create texture to hold bitmap pattern.
    135     */
    136    pt = st_texture_create(st, st->internal_target, st->bitmap.tex_format,
    137                           0, width, height, 1, 1, 0,
    138                           PIPE_BIND_SAMPLER_VIEW);
    139    if (!pt) {
    140       _mesa_unmap_pbo_source(ctx, unpack);
    141       return NULL;
    142    }
    143 
    144    dest = pipe_transfer_map(st->pipe, pt, 0, 0,
    145                             PIPE_TRANSFER_WRITE,
    146                             0, 0, width, height, &transfer);
    147 
    148    /* Put image into texture transfer */
    149    memset(dest, 0xff, height * transfer->stride);
    150    unpack_bitmap(st, 0, 0, width, height, unpack, bitmap,
    151                  dest, transfer->stride);
    152 
    153    _mesa_unmap_pbo_source(ctx, unpack);
    154 
    155    /* Release transfer */
    156    pipe_transfer_unmap(pipe, transfer);
    157    return pt;
    158 }
    159 
    160 
    161 /**
    162  * Setup pipeline state prior to rendering the bitmap textured quad.
    163  */
    164 static void
    165 setup_render_state(struct gl_context *ctx,
    166                    struct pipe_sampler_view *sv,
    167                    const GLfloat *color,
    168                    bool atlas)
    169 {
    170    struct st_context *st = st_context(ctx);
    171    struct cso_context *cso = st->cso_context;
    172    struct st_fp_variant *fpv;
    173    struct st_fp_variant_key key;
    174 
    175    memset(&key, 0, sizeof(key));
    176    key.st = st->has_shareable_shaders ? NULL : st;
    177    key.bitmap = GL_TRUE;
    178    key.clamp_color = st->clamp_frag_color_in_shader &&
    179                      ctx->Color._ClampFragmentColor;
    180 
    181    fpv = st_get_fp_variant(st, st->fp, &key);
    182 
    183    /* As an optimization, Mesa's fragment programs will sometimes get the
    184     * primary color from a statevar/constant rather than a varying variable.
    185     * when that's the case, we need to ensure that we use the 'color'
    186     * parameter and not the current attribute color (which may have changed
    187     * through glRasterPos and state validation.
    188     * So, we force the proper color here.  Not elegant, but it works.
    189     */
    190    {
    191       GLfloat colorSave[4];
    192       COPY_4V(colorSave, ctx->Current.Attrib[VERT_ATTRIB_COLOR0]);
    193       COPY_4V(ctx->Current.Attrib[VERT_ATTRIB_COLOR0], color);
    194       st_upload_constants(st, &st->fp->Base);
    195       COPY_4V(ctx->Current.Attrib[VERT_ATTRIB_COLOR0], colorSave);
    196    }
    197 
    198    cso_save_state(cso, (CSO_BIT_RASTERIZER |
    199                         CSO_BIT_FRAGMENT_SAMPLERS |
    200                         CSO_BIT_FRAGMENT_SAMPLER_VIEWS |
    201                         CSO_BIT_VIEWPORT |
    202                         CSO_BIT_STREAM_OUTPUTS |
    203                         CSO_BIT_VERTEX_ELEMENTS |
    204                         CSO_BIT_AUX_VERTEX_BUFFER_SLOT |
    205                         CSO_BITS_ALL_SHADERS));
    206 
    207 
    208    /* rasterizer state: just scissor */
    209    st->bitmap.rasterizer.scissor = ctx->Scissor.EnableFlags & 1;
    210    cso_set_rasterizer(cso, &st->bitmap.rasterizer);
    211 
    212    /* fragment shader state: TEX lookup program */
    213    cso_set_fragment_shader_handle(cso, fpv->driver_shader);
    214 
    215    /* vertex shader state: position + texcoord pass-through */
    216    cso_set_vertex_shader_handle(cso, st->bitmap.vs);
    217 
    218    /* disable other shaders */
    219    cso_set_tessctrl_shader_handle(cso, NULL);
    220    cso_set_tesseval_shader_handle(cso, NULL);
    221    cso_set_geometry_shader_handle(cso, NULL);
    222 
    223    /* user samplers, plus our bitmap sampler */
    224    {
    225       struct pipe_sampler_state *samplers[PIPE_MAX_SAMPLERS];
    226       uint num = MAX2(fpv->bitmap_sampler + 1,
    227                       st->state.num_samplers[PIPE_SHADER_FRAGMENT]);
    228       uint i;
    229       for (i = 0; i < st->state.num_samplers[PIPE_SHADER_FRAGMENT]; i++) {
    230          samplers[i] = &st->state.samplers[PIPE_SHADER_FRAGMENT][i];
    231       }
    232       if (atlas)
    233          samplers[fpv->bitmap_sampler] = &st->bitmap.atlas_sampler;
    234       else
    235          samplers[fpv->bitmap_sampler] = &st->bitmap.sampler;
    236       cso_set_samplers(cso, PIPE_SHADER_FRAGMENT, num,
    237                        (const struct pipe_sampler_state **) samplers);
    238    }
    239 
    240    /* user textures, plus the bitmap texture */
    241    {
    242       struct pipe_sampler_view *sampler_views[PIPE_MAX_SAMPLERS];
    243       uint num = MAX2(fpv->bitmap_sampler + 1,
    244                       st->state.num_sampler_views[PIPE_SHADER_FRAGMENT]);
    245       memcpy(sampler_views, st->state.sampler_views[PIPE_SHADER_FRAGMENT],
    246              sizeof(sampler_views));
    247       sampler_views[fpv->bitmap_sampler] = sv;
    248       cso_set_sampler_views(cso, PIPE_SHADER_FRAGMENT, num, sampler_views);
    249    }
    250 
    251    /* viewport state: viewport matching window dims */
    252    cso_set_viewport_dims(cso, st->state.fb_width,
    253                          st->state.fb_height,
    254                          st->state.fb_orientation == Y_0_TOP);
    255 
    256    cso_set_vertex_elements(cso, 3, st->util_velems);
    257 
    258    cso_set_stream_outputs(st->cso_context, 0, NULL, NULL);
    259 }
    260 
    261 
    262 /**
    263  * Restore pipeline state after rendering the bitmap textured quad.
    264  */
    265 static void
    266 restore_render_state(struct gl_context *ctx)
    267 {
    268    struct st_context *st = st_context(ctx);
    269    struct cso_context *cso = st->cso_context;
    270 
    271    cso_restore_state(cso);
    272 }
    273 
    274 
    275 /**
    276  * Render a glBitmap by drawing a textured quad
    277  */
    278 static void
    279 draw_bitmap_quad(struct gl_context *ctx, GLint x, GLint y, GLfloat z,
    280                  GLsizei width, GLsizei height,
    281                  struct pipe_sampler_view *sv,
    282                  const GLfloat *color)
    283 {
    284    struct st_context *st = st_context(ctx);
    285    struct pipe_context *pipe = st->pipe;
    286    const float fb_width = (float) st->state.fb_width;
    287    const float fb_height = (float) st->state.fb_height;
    288    const float x0 = (float) x;
    289    const float x1 = (float) (x + width);
    290    const float y0 = (float) y;
    291    const float y1 = (float) (y + height);
    292    float sLeft = 0.0f, sRight = 1.0f;
    293    float tTop = 0.0f, tBot = 1.0f - tTop;
    294    const float clip_x0 = x0 / fb_width * 2.0f - 1.0f;
    295    const float clip_y0 = y0 / fb_height * 2.0f - 1.0f;
    296    const float clip_x1 = x1 / fb_width * 2.0f - 1.0f;
    297    const float clip_y1 = y1 / fb_height * 2.0f - 1.0f;
    298 
    299    /* limit checks */
    300    {
    301       /* XXX if the bitmap is larger than the max texture size, break
    302        * it up into chunks.
    303        */
    304       GLuint MAYBE_UNUSED maxSize =
    305          1 << (pipe->screen->get_param(pipe->screen,
    306                                        PIPE_CAP_MAX_TEXTURE_2D_LEVELS) - 1);
    307       assert(width <= (GLsizei) maxSize);
    308       assert(height <= (GLsizei) maxSize);
    309    }
    310 
    311    setup_render_state(ctx, sv, color, false);
    312 
    313    /* convert Z from [0,1] to [-1,-1] to match viewport Z scale/bias */
    314    z = z * 2.0f - 1.0f;
    315 
    316    if (sv->texture->target == PIPE_TEXTURE_RECT) {
    317       /* use non-normalized texcoords */
    318       sRight = (float) width;
    319       tBot = (float) height;
    320    }
    321 
    322    if (!st_draw_quad(st, clip_x0, clip_y0, clip_x1, clip_y1, z,
    323                      sLeft, tBot, sRight, tTop, color, 0)) {
    324       _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBitmap");
    325    }
    326 
    327    restore_render_state(ctx);
    328 
    329    /* We uploaded modified constants, need to invalidate them. */
    330    st->dirty |= ST_NEW_FS_CONSTANTS;
    331 }
    332 
    333 
    334 static void
    335 reset_cache(struct st_context *st)
    336 {
    337    struct st_bitmap_cache *cache = &st->bitmap.cache;
    338 
    339    /*memset(cache->buffer, 0xff, sizeof(cache->buffer));*/
    340    cache->empty = GL_TRUE;
    341 
    342    cache->xmin = 1000000;
    343    cache->xmax = -1000000;
    344    cache->ymin = 1000000;
    345    cache->ymax = -1000000;
    346 
    347    assert(!cache->texture);
    348 
    349    /* allocate a new texture */
    350    cache->texture = st_texture_create(st, st->internal_target,
    351                                       st->bitmap.tex_format, 0,
    352                                       BITMAP_CACHE_WIDTH, BITMAP_CACHE_HEIGHT,
    353                                       1, 1, 0,
    354 				      PIPE_BIND_SAMPLER_VIEW);
    355 }
    356 
    357 
    358 /** Print bitmap image to stdout (debug) */
    359 static void
    360 print_cache(const struct st_bitmap_cache *cache)
    361 {
    362    int i, j, k;
    363 
    364    for (i = 0; i < BITMAP_CACHE_HEIGHT; i++) {
    365       k = BITMAP_CACHE_WIDTH * (BITMAP_CACHE_HEIGHT - i - 1);
    366       for (j = 0; j < BITMAP_CACHE_WIDTH; j++) {
    367          if (cache->buffer[k])
    368             printf("X");
    369          else
    370             printf(" ");
    371          k++;
    372       }
    373       printf("\n");
    374    }
    375 }
    376 
    377 
    378 /**
    379  * Create gallium pipe_transfer object for the bitmap cache.
    380  */
    381 static void
    382 create_cache_trans(struct st_context *st)
    383 {
    384    struct pipe_context *pipe = st->pipe;
    385    struct st_bitmap_cache *cache = &st->bitmap.cache;
    386 
    387    if (cache->trans)
    388       return;
    389 
    390    /* Map the texture transfer.
    391     * Subsequent glBitmap calls will write into the texture image.
    392     */
    393    cache->buffer = pipe_transfer_map(pipe, cache->texture, 0, 0,
    394                                      PIPE_TRANSFER_WRITE, 0, 0,
    395                                      BITMAP_CACHE_WIDTH,
    396                                      BITMAP_CACHE_HEIGHT, &cache->trans);
    397 
    398    /* init image to all 0xff */
    399    memset(cache->buffer, 0xff, cache->trans->stride * BITMAP_CACHE_HEIGHT);
    400 }
    401 
    402 
    403 /**
    404  * If there's anything in the bitmap cache, draw/flush it now.
    405  */
    406 void
    407 st_flush_bitmap_cache(struct st_context *st)
    408 {
    409    struct st_bitmap_cache *cache = &st->bitmap.cache;
    410 
    411    if (!cache->empty) {
    412       struct pipe_context *pipe = st->pipe;
    413       struct pipe_sampler_view *sv;
    414 
    415       assert(cache->xmin <= cache->xmax);
    416 
    417       if (0)
    418          printf("flush bitmap, size %d x %d  at %d, %d\n",
    419                 cache->xmax - cache->xmin,
    420                 cache->ymax - cache->ymin,
    421                 cache->xpos, cache->ypos);
    422 
    423       /* The texture transfer has been mapped until now.
    424        * So unmap and release the texture transfer before drawing.
    425        */
    426       if (cache->trans && cache->buffer) {
    427          if (0)
    428             print_cache(cache);
    429          pipe_transfer_unmap(pipe, cache->trans);
    430          cache->buffer = NULL;
    431          cache->trans = NULL;
    432       }
    433 
    434       sv = st_create_texture_sampler_view(st->pipe, cache->texture);
    435       if (sv) {
    436          draw_bitmap_quad(st->ctx,
    437                           cache->xpos,
    438                           cache->ypos,
    439                           cache->zpos,
    440                           BITMAP_CACHE_WIDTH, BITMAP_CACHE_HEIGHT,
    441                           sv,
    442                           cache->color);
    443 
    444          pipe_sampler_view_reference(&sv, NULL);
    445       }
    446 
    447       /* release/free the texture */
    448       pipe_resource_reference(&cache->texture, NULL);
    449 
    450       reset_cache(st);
    451    }
    452 }
    453 
    454 
    455 /**
    456  * Try to accumulate this glBitmap call in the bitmap cache.
    457  * \return  GL_TRUE for success, GL_FALSE if bitmap is too large, etc.
    458  */
    459 static GLboolean
    460 accum_bitmap(struct gl_context *ctx,
    461              GLint x, GLint y, GLsizei width, GLsizei height,
    462              const struct gl_pixelstore_attrib *unpack,
    463              const GLubyte *bitmap )
    464 {
    465    struct st_context *st = ctx->st;
    466    struct st_bitmap_cache *cache = &st->bitmap.cache;
    467    int px = -999, py = -999;
    468    const GLfloat z = ctx->Current.RasterPos[2];
    469 
    470    if (width > BITMAP_CACHE_WIDTH ||
    471        height > BITMAP_CACHE_HEIGHT)
    472       return GL_FALSE; /* too big to cache */
    473 
    474    if (!cache->empty) {
    475       px = x - cache->xpos;  /* pos in buffer */
    476       py = y - cache->ypos;
    477       if (px < 0 || px + width > BITMAP_CACHE_WIDTH ||
    478           py < 0 || py + height > BITMAP_CACHE_HEIGHT ||
    479           !TEST_EQ_4V(ctx->Current.RasterColor, cache->color) ||
    480           ((fabs(z - cache->zpos) > Z_EPSILON))) {
    481          /* This bitmap would extend beyond cache bounds, or the bitmap
    482           * color is changing
    483           * so flush and continue.
    484           */
    485          st_flush_bitmap_cache(st);
    486       }
    487    }
    488 
    489    if (cache->empty) {
    490       /* Initialize.  Center bitmap vertically in the buffer. */
    491       px = 0;
    492       py = (BITMAP_CACHE_HEIGHT - height) / 2;
    493       cache->xpos = x;
    494       cache->ypos = y - py;
    495       cache->zpos = z;
    496       cache->empty = GL_FALSE;
    497       COPY_4FV(cache->color, ctx->Current.RasterColor);
    498    }
    499 
    500    assert(px != -999);
    501    assert(py != -999);
    502 
    503    if (x < cache->xmin)
    504       cache->xmin = x;
    505    if (y < cache->ymin)
    506       cache->ymin = y;
    507    if (x + width > cache->xmax)
    508       cache->xmax = x + width;
    509    if (y + height > cache->ymax)
    510       cache->ymax = y + height;
    511 
    512    /* create the transfer if needed */
    513    create_cache_trans(st);
    514 
    515    /* PBO source... */
    516    bitmap = _mesa_map_pbo_source(ctx, unpack, bitmap);
    517    if (!bitmap) {
    518       return FALSE;
    519    }
    520 
    521    unpack_bitmap(st, px, py, width, height, unpack, bitmap,
    522                  cache->buffer, BITMAP_CACHE_WIDTH);
    523 
    524    _mesa_unmap_pbo_source(ctx, unpack);
    525 
    526    return GL_TRUE; /* accumulated */
    527 }
    528 
    529 
    530 /**
    531  * One-time init for drawing bitmaps.
    532  */
    533 static void
    534 init_bitmap_state(struct st_context *st)
    535 {
    536    struct pipe_context *pipe = st->pipe;
    537    struct pipe_screen *screen = pipe->screen;
    538 
    539    /* This function should only be called once */
    540    assert(st->bitmap.vs == NULL);
    541 
    542    assert(st->internal_target == PIPE_TEXTURE_2D ||
    543           st->internal_target == PIPE_TEXTURE_RECT);
    544 
    545    /* init sampler state once */
    546    memset(&st->bitmap.sampler, 0, sizeof(st->bitmap.sampler));
    547    st->bitmap.sampler.wrap_s = PIPE_TEX_WRAP_CLAMP;
    548    st->bitmap.sampler.wrap_t = PIPE_TEX_WRAP_CLAMP;
    549    st->bitmap.sampler.wrap_r = PIPE_TEX_WRAP_CLAMP;
    550    st->bitmap.sampler.min_img_filter = PIPE_TEX_FILTER_NEAREST;
    551    st->bitmap.sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NONE;
    552    st->bitmap.sampler.mag_img_filter = PIPE_TEX_FILTER_NEAREST;
    553    st->bitmap.sampler.normalized_coords = st->internal_target == PIPE_TEXTURE_2D;
    554 
    555    st->bitmap.atlas_sampler = st->bitmap.sampler;
    556    st->bitmap.atlas_sampler.normalized_coords = 0;
    557 
    558    /* init baseline rasterizer state once */
    559    memset(&st->bitmap.rasterizer, 0, sizeof(st->bitmap.rasterizer));
    560    st->bitmap.rasterizer.half_pixel_center = 1;
    561    st->bitmap.rasterizer.bottom_edge_rule = 1;
    562    st->bitmap.rasterizer.depth_clip = 1;
    563 
    564    /* find a usable texture format */
    565    if (screen->is_format_supported(screen, PIPE_FORMAT_I8_UNORM,
    566                                    st->internal_target, 0,
    567                                    PIPE_BIND_SAMPLER_VIEW)) {
    568       st->bitmap.tex_format = PIPE_FORMAT_I8_UNORM;
    569    }
    570    else if (screen->is_format_supported(screen, PIPE_FORMAT_A8_UNORM,
    571                                         st->internal_target, 0,
    572                                         PIPE_BIND_SAMPLER_VIEW)) {
    573       st->bitmap.tex_format = PIPE_FORMAT_A8_UNORM;
    574    }
    575    else if (screen->is_format_supported(screen, PIPE_FORMAT_L8_UNORM,
    576                                         st->internal_target, 0,
    577                                         PIPE_BIND_SAMPLER_VIEW)) {
    578       st->bitmap.tex_format = PIPE_FORMAT_L8_UNORM;
    579    }
    580    else {
    581       /* XXX support more formats */
    582       assert(0);
    583    }
    584 
    585    /* Create the vertex shader */
    586    {
    587       const uint semantic_names[] = { TGSI_SEMANTIC_POSITION,
    588                                       TGSI_SEMANTIC_COLOR,
    589         st->needs_texcoord_semantic ? TGSI_SEMANTIC_TEXCOORD :
    590                                       TGSI_SEMANTIC_GENERIC };
    591       const uint semantic_indexes[] = { 0, 0, 0 };
    592       st->bitmap.vs = util_make_vertex_passthrough_shader(st->pipe, 3,
    593                                                           semantic_names,
    594                                                           semantic_indexes,
    595                                                           FALSE);
    596    }
    597 
    598    reset_cache(st);
    599 }
    600 
    601 
    602 /**
    603  * Called via ctx->Driver.Bitmap()
    604  */
    605 static void
    606 st_Bitmap(struct gl_context *ctx, GLint x, GLint y,
    607           GLsizei width, GLsizei height,
    608           const struct gl_pixelstore_attrib *unpack, const GLubyte *bitmap )
    609 {
    610    struct st_context *st = st_context(ctx);
    611    struct pipe_resource *pt;
    612 
    613    assert(width > 0);
    614    assert(height > 0);
    615 
    616    st_invalidate_readpix_cache(st);
    617 
    618    if (!st->bitmap.vs) {
    619       init_bitmap_state(st);
    620    }
    621 
    622    /* We only need to validate any non-ST_NEW_CONSTANTS state. The VS we use
    623     * for bitmap drawing uses no constants and the FS constants are
    624     * explicitly uploaded in the draw_bitmap_quad() function.
    625     */
    626    if ((st->dirty | ctx->NewDriverState) & ~ST_NEW_CONSTANTS &
    627        ST_PIPELINE_RENDER_STATE_MASK ||
    628        st->gfx_shaders_may_be_dirty) {
    629       st_validate_state(st, ST_PIPELINE_RENDER);
    630    }
    631 
    632    if (UseBitmapCache && accum_bitmap(ctx, x, y, width, height, unpack, bitmap))
    633       return;
    634 
    635    pt = make_bitmap_texture(ctx, width, height, unpack, bitmap);
    636    if (pt) {
    637       struct pipe_sampler_view *sv =
    638          st_create_texture_sampler_view(st->pipe, pt);
    639 
    640       assert(pt->target == PIPE_TEXTURE_2D || pt->target == PIPE_TEXTURE_RECT);
    641 
    642       if (sv) {
    643          draw_bitmap_quad(ctx, x, y, ctx->Current.RasterPos[2],
    644                           width, height, sv, ctx->Current.RasterColor);
    645 
    646          pipe_sampler_view_reference(&sv, NULL);
    647       }
    648 
    649       /* release/free the texture */
    650       pipe_resource_reference(&pt, NULL);
    651    }
    652 }
    653 
    654 
    655 /**
    656  * Called via ctx->Driver.DrawAtlasBitmap()
    657  */
    658 static void
    659 st_DrawAtlasBitmaps(struct gl_context *ctx,
    660                     const struct gl_bitmap_atlas *atlas,
    661                     GLuint count, const GLubyte *ids)
    662 {
    663    struct st_context *st = st_context(ctx);
    664    struct pipe_context *pipe = st->pipe;
    665    struct st_texture_object *stObj = st_texture_object(atlas->texObj);
    666    struct pipe_sampler_view *sv;
    667    /* convert Z from [0,1] to [-1,-1] to match viewport Z scale/bias */
    668    const float z = ctx->Current.RasterPos[2] * 2.0f - 1.0f;
    669    const float *color = ctx->Current.RasterColor;
    670    const float clip_x_scale = 2.0f / st->state.fb_width;
    671    const float clip_y_scale = 2.0f / st->state.fb_height;
    672    const unsigned num_verts = count * 4;
    673    const unsigned num_vert_bytes = num_verts * sizeof(struct st_util_vertex);
    674    struct st_util_vertex *verts;
    675    struct pipe_vertex_buffer vb = {0};
    676    unsigned i;
    677 
    678    if (!st->bitmap.vs) {
    679       init_bitmap_state(st);
    680    }
    681 
    682    st_flush_bitmap_cache(st);
    683 
    684    st_validate_state(st, ST_PIPELINE_RENDER);
    685    st_invalidate_readpix_cache(st);
    686 
    687    sv = st_create_texture_sampler_view(pipe, stObj->pt);
    688    if (!sv) {
    689       _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCallLists(bitmap text)");
    690       return;
    691    }
    692 
    693    setup_render_state(ctx, sv, color, true);
    694 
    695    vb.stride = sizeof(struct st_util_vertex);
    696 
    697    u_upload_alloc(pipe->stream_uploader, 0, num_vert_bytes, 4,
    698                   &vb.buffer_offset, &vb.buffer.resource, (void **) &verts);
    699 
    700    if (unlikely(!verts)) {
    701       _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCallLists(bitmap text)");
    702       goto out;
    703    }
    704 
    705    /* build quads vertex data */
    706    for (i = 0; i < count; i++) {
    707       const GLfloat epsilon = 0.0001F;
    708       const struct gl_bitmap_glyph *g = &atlas->glyphs[ids[i]];
    709       const float xmove = g->xmove, ymove = g->ymove;
    710       const float xorig = g->xorig, yorig = g->yorig;
    711       const float s0 = g->x, t0 = g->y;
    712       const float s1 = s0 + g->w, t1 = t0 + g->h;
    713       const float x0 = IFLOOR(ctx->Current.RasterPos[0] - xorig + epsilon);
    714       const float y0 = IFLOOR(ctx->Current.RasterPos[1] - yorig + epsilon);
    715       const float x1 = x0 + g->w, y1 = y0 + g->h;
    716       const float clip_x0 = x0 * clip_x_scale - 1.0f;
    717       const float clip_y0 = y0 * clip_y_scale - 1.0f;
    718       const float clip_x1 = x1 * clip_x_scale - 1.0f;
    719       const float clip_y1 = y1 * clip_y_scale - 1.0f;
    720 
    721       /* lower-left corner */
    722       verts->x = clip_x0;
    723       verts->y = clip_y0;
    724       verts->z = z;
    725       verts->r = color[0];
    726       verts->g = color[1];
    727       verts->b = color[2];
    728       verts->a = color[3];
    729       verts->s = s0;
    730       verts->t = t0;
    731       verts++;
    732 
    733       /* lower-right corner */
    734       verts->x = clip_x1;
    735       verts->y = clip_y0;
    736       verts->z = z;
    737       verts->r = color[0];
    738       verts->g = color[1];
    739       verts->b = color[2];
    740       verts->a = color[3];
    741       verts->s = s1;
    742       verts->t = t0;
    743       verts++;
    744 
    745       /* upper-right corner */
    746       verts->x = clip_x1;
    747       verts->y = clip_y1;
    748       verts->z = z;
    749       verts->r = color[0];
    750       verts->g = color[1];
    751       verts->b = color[2];
    752       verts->a = color[3];
    753       verts->s = s1;
    754       verts->t = t1;
    755       verts++;
    756 
    757       /* upper-left corner */
    758       verts->x = clip_x0;
    759       verts->y = clip_y1;
    760       verts->z = z;
    761       verts->r = color[0];
    762       verts->g = color[1];
    763       verts->b = color[2];
    764       verts->a = color[3];
    765       verts->s = s0;
    766       verts->t = t1;
    767       verts++;
    768 
    769       /* Update the raster position */
    770       ctx->Current.RasterPos[0] += xmove;
    771       ctx->Current.RasterPos[1] += ymove;
    772    }
    773 
    774    u_upload_unmap(pipe->stream_uploader);
    775 
    776    cso_set_vertex_buffers(st->cso_context,
    777                           cso_get_aux_vertex_buffer_slot(st->cso_context),
    778                           1, &vb);
    779 
    780    cso_draw_arrays(st->cso_context, PIPE_PRIM_QUADS, 0, num_verts);
    781 
    782 out:
    783    restore_render_state(ctx);
    784 
    785    pipe_resource_reference(&vb.buffer.resource, NULL);
    786 
    787    pipe_sampler_view_reference(&sv, NULL);
    788 
    789    /* We uploaded modified constants, need to invalidate them. */
    790    st->dirty |= ST_NEW_FS_CONSTANTS;
    791 }
    792 
    793 
    794 
    795 /** Per-context init */
    796 void
    797 st_init_bitmap_functions(struct dd_function_table *functions)
    798 {
    799    functions->Bitmap = st_Bitmap;
    800    functions->DrawAtlasBitmaps = st_DrawAtlasBitmaps;
    801 }
    802 
    803 
    804 /** Per-context tear-down */
    805 void
    806 st_destroy_bitmap(struct st_context *st)
    807 {
    808    struct pipe_context *pipe = st->pipe;
    809    struct st_bitmap_cache *cache = &st->bitmap.cache;
    810 
    811    if (st->bitmap.vs) {
    812       cso_delete_vertex_shader(st->cso_context, st->bitmap.vs);
    813       st->bitmap.vs = NULL;
    814    }
    815 
    816    if (cache->trans && cache->buffer) {
    817       pipe_transfer_unmap(pipe, cache->trans);
    818    }
    819    pipe_resource_reference(&st->bitmap.cache.texture, NULL);
    820 }
    821