[Mesa-dev] [PATCH 2/2] st/mesa: new st_DrawAtlasBitmaps() function for drawing bitmap text

Nicolai Hähnle nhaehnle at gmail.com
Mon Feb 15 15:45:48 UTC 2016


On 12.02.2016 20:07, Brian Paul wrote:
> This basically saves the current pipeline state, sets up state for
> rendering, constructs a set of textured quads, renders, then restores
> the previous pipeline state.
>
> It shouldn't be hard to implement a similar function for non-gallium
> drives.  With some code refactoring, the vertex definition code could
> probably be shared.

Except for the potential (trivial) interaction with my comments on the 
first patch, this is

Reviewed-by: Nicolai Hähnle <nicolai.haehnle at amd.com>

> ---
>   src/mesa/state_tracker/st_cb_bitmap.c | 143 +++++++++++++++++++++++++++++++++-
>   src/mesa/state_tracker/st_context.h   |   1 +
>   2 files changed, 141 insertions(+), 3 deletions(-)
>
> diff --git a/src/mesa/state_tracker/st_cb_bitmap.c b/src/mesa/state_tracker/st_cb_bitmap.c
> index d84bfef..461159b 100644
> --- a/src/mesa/state_tracker/st_cb_bitmap.c
> +++ b/src/mesa/state_tracker/st_cb_bitmap.c
> @@ -33,6 +33,7 @@
>   #include "main/imports.h"
>   #include "main/image.h"
>   #include "main/bufferobj.h"
> +#include "main/dlist.h"
>   #include "main/macros.h"
>   #include "main/pbo.h"
>   #include "program/program.h"
> @@ -51,6 +52,7 @@
>   #include "pipe/p_shader_tokens.h"
>   #include "util/u_inlines.h"
>   #include "util/u_simple_shaders.h"
> +#include "util/u_upload_mgr.h"
>   #include "program/prog_instruction.h"
>   #include "cso_cache/cso_context.h"
>
> @@ -182,7 +184,8 @@ make_bitmap_texture(struct gl_context *ctx, GLsizei width, GLsizei height,
>   static void
>   setup_render_state(struct gl_context *ctx,
>                      struct pipe_sampler_view *sv,
> -                   const GLfloat *color)
> +                   const GLfloat *color,
> +                   bool atlas)
>   {
>      struct st_context *st = st_context(ctx);
>      struct cso_context *cso = st->cso_context;
> @@ -249,7 +252,10 @@ setup_render_state(struct gl_context *ctx,
>         for (i = 0; i < st->state.num_samplers[PIPE_SHADER_FRAGMENT]; i++) {
>            samplers[i] = &st->state.samplers[PIPE_SHADER_FRAGMENT][i];
>         }
> -      samplers[fpv->bitmap_sampler] = &st->bitmap.sampler;
> +      if (atlas)
> +         samplers[fpv->bitmap_sampler] = &st->bitmap.atlas_sampler;
> +      else
> +         samplers[fpv->bitmap_sampler] = &st->bitmap.sampler;
>         cso_set_samplers(cso, PIPE_SHADER_FRAGMENT, num,
>                          (const struct pipe_sampler_state **) samplers);
>      }
> @@ -324,7 +330,7 @@ draw_bitmap_quad(struct gl_context *ctx, GLint x, GLint y, GLfloat z,
>         assert(height <= (GLsizei) maxSize);
>      }
>
> -   setup_render_state(ctx, sv, color);
> +   setup_render_state(ctx, sv, color, false);
>
>      /* convert Z from [0,1] to [-1,-1] to match viewport Z scale/bias */
>      z = z * 2.0f - 1.0f;
> @@ -571,6 +577,9 @@ init_bitmap_state(struct st_context *st)
>      st->bitmap.sampler.mag_img_filter = PIPE_TEX_FILTER_NEAREST;
>      st->bitmap.sampler.normalized_coords = st->internal_target == PIPE_TEXTURE_2D;
>
> +   st->bitmap.atlas_sampler = st->bitmap.sampler;
> +   st->bitmap.atlas_sampler.normalized_coords = 0;
> +
>      /* init baseline rasterizer state once */
>      memset(&st->bitmap.rasterizer, 0, sizeof(st->bitmap.rasterizer));
>      st->bitmap.rasterizer.half_pixel_center = 1;
> @@ -665,11 +674,139 @@ st_Bitmap(struct gl_context *ctx, GLint x, GLint y,
>   }
>
>
> +/**
> + * Called via ctx->Driver.DrawAtlasBitmap()
> + */
> +static void
> +st_DrawAtlasBitmaps(struct gl_context *ctx,
> +                    const struct gl_bitmap_atlas *atlas,
> +                    GLuint count, const GLubyte *ids)
> +{
> +   struct st_context *st = st_context(ctx);
> +   struct pipe_context *pipe = st->pipe;
> +   struct st_texture_object *stObj = st_texture_object(atlas->texObj);
> +   struct pipe_sampler_view *sv;
> +   /* convert Z from [0,1] to [-1,-1] to match viewport Z scale/bias */
> +   const float z = ctx->Current.RasterPos[2] * 2.0f - 1.0f;
> +   const float *color = ctx->Current.RasterColor;
> +   const float clip_x_scale = 2.0f / st->state.framebuffer.width;
> +   const float clip_y_scale = 2.0f / st->state.framebuffer.height;
> +   const unsigned num_verts = count * 4;
> +   const unsigned num_vert_bytes = num_verts * sizeof(struct st_util_vertex);
> +   struct st_util_vertex *verts;
> +   struct pipe_vertex_buffer vb = {0};
> +   unsigned i;
> +
> +   if (!st->bitmap.cache) {
> +      init_bitmap_state(st);
> +   }
> +
> +   st_flush_bitmap_cache(st);
> +
> +   st_validate_state(st);
> +
> +   sv = st_create_texture_sampler_view(pipe, stObj->pt);
> +
> +   setup_render_state(ctx, sv, color, true);
> +
> +   vb.stride = sizeof(struct st_util_vertex);
> +
> +   u_upload_alloc(st->uploader, 0, num_vert_bytes, 4,
> +                  &vb.buffer_offset, &vb.buffer, (void **) &verts);
> +
> +   /* build quads vertex data */
> +   for (i = 0; i < count; i++) {
> +      const GLfloat epsilon = 0.0001F;
> +      const struct gl_bitmap_glyph *g = &atlas->glyphs[ids[i]];
> +      const float xmove = g->xmove, ymove = g->ymove;
> +      const float xorig = g->xorig, yorig = g->yorig;
> +      const float s0 = g->x, t0 = g->y;
> +      const float s1 = s0 + g->w, t1 = t0 + g->h;
> +      const float x0 = IFLOOR(ctx->Current.RasterPos[0] - xorig + epsilon);
> +      const float y0 = IFLOOR(ctx->Current.RasterPos[1] - yorig + epsilon);
> +      const float x1 = x0 + g->w, y1 = y0 + g->h;
> +      const float clip_x0 = x0 * clip_x_scale - 1.0f;
> +      const float clip_y0 = y0 * clip_y_scale - 1.0f;
> +      const float clip_x1 = x1 * clip_x_scale - 1.0f;
> +      const float clip_y1 = y1 * clip_y_scale - 1.0f;
> +
> +      /* lower-left corner */
> +      verts->x = clip_x0;
> +      verts->y = clip_y0;
> +      verts->z = z;
> +      verts->r = color[0];
> +      verts->g = color[1];
> +      verts->b = color[2];
> +      verts->a = color[3];
> +      verts->s = s0;
> +      verts->t = t0;
> +      verts++;
> +
> +      /* lower-right corner */
> +      verts->x = clip_x1;
> +      verts->y = clip_y0;
> +      verts->z = z;
> +      verts->r = color[0];
> +      verts->g = color[1];
> +      verts->b = color[2];
> +      verts->a = color[3];
> +      verts->s = s1;
> +      verts->t = t0;
> +      verts++;
> +
> +      /* upper-right corner */
> +      verts->x = clip_x1;
> +      verts->y = clip_y1;
> +      verts->z = z;
> +      verts->r = color[0];
> +      verts->g = color[1];
> +      verts->b = color[2];
> +      verts->a = color[3];
> +      verts->s = s1;
> +      verts->t = t1;
> +      verts++;
> +
> +      /* upper-left corner */
> +      verts->x = clip_x0;
> +      verts->y = clip_y1;
> +      verts->z = z;
> +      verts->r = color[0];
> +      verts->g = color[1];
> +      verts->b = color[2];
> +      verts->a = color[3];
> +      verts->s = s0;
> +      verts->t = t1;
> +      verts++;
> +
> +      /* Update the raster position */
> +      ctx->Current.RasterPos[0] += xmove;
> +      ctx->Current.RasterPos[1] += ymove;
> +   }
> +
> +   u_upload_unmap(st->uploader);
> +
> +   cso_set_vertex_buffers(st->cso_context,
> +                          cso_get_aux_vertex_buffer_slot(st->cso_context),
> +                          1, &vb);
> +
> +   cso_draw_arrays(st->cso_context, PIPE_PRIM_QUADS, 0, num_verts);
> +
> +   restore_render_state(ctx);
> +
> +   pipe_resource_reference(&vb.buffer, NULL);
> +
> +   /* We uploaded modified constants, need to invalidate them. */
> +   st->dirty.mesa |= _NEW_PROGRAM_CONSTANTS;
> +}
> +
> +
> +
>   /** Per-context init */
>   void
>   st_init_bitmap_functions(struct dd_function_table *functions)
>   {
>      functions->Bitmap = st_Bitmap;
> +   functions->DrawAtlasBitmaps = st_DrawAtlasBitmaps;
>   }
>
>
> diff --git a/src/mesa/state_tracker/st_context.h b/src/mesa/state_tracker/st_context.h
> index 85a1396..98187d7 100644
> --- a/src/mesa/state_tracker/st_context.h
> +++ b/src/mesa/state_tracker/st_context.h
> @@ -191,6 +191,7 @@ struct st_context
>      struct {
>         struct pipe_rasterizer_state rasterizer;
>         struct pipe_sampler_state sampler;
> +      struct pipe_sampler_state atlas_sampler;
>         enum pipe_format tex_format;
>         void *vs;
>         struct bitmap_cache *cache;
>


More information about the mesa-dev mailing list