[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