[Mesa-dev] [PATCH 3/6] st/mesa: consolidate quad drawing code

Brian Paul brianp at vmware.com
Fri Feb 12 15:43:50 UTC 2016


The glClear, glBitmap and glDrawPixels code now use a new st_draw_quad()
helper function.
---
 src/mesa/state_tracker/st_cb_bitmap.c     |  66 +---------------
 src/mesa/state_tracker/st_cb_clear.c      |  91 ++++------------------
 src/mesa/state_tracker/st_cb_drawpixels.c | 120 ++++++------------------------
 src/mesa/state_tracker/st_draw.c          |  84 +++++++++++++++++++++
 src/mesa/state_tracker/st_draw.h          |   7 ++
 5 files changed, 130 insertions(+), 238 deletions(-)

diff --git a/src/mesa/state_tracker/st_cb_bitmap.c b/src/mesa/state_tracker/st_cb_bitmap.c
index b5387d7..5081639 100644
--- a/src/mesa/state_tracker/st_cb_bitmap.c
+++ b/src/mesa/state_tracker/st_cb_bitmap.c
@@ -41,6 +41,7 @@
 #include "st_context.h"
 #include "st_atom.h"
 #include "st_atom_constbuf.h"
+#include "st_draw.h"
 #include "st_program.h"
 #include "st_cb_bitmap.h"
 #include "st_texture.h"
@@ -50,7 +51,6 @@
 #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"
 
@@ -322,7 +322,6 @@ draw_bitmap_quad(struct gl_context *ctx, GLint x, GLint y, GLfloat z,
 {
    struct st_context *st = st_context(ctx);
    struct pipe_context *pipe = st->pipe;
-   struct pipe_vertex_buffer vb = {0};
    const float fb_width = (float) st->state.framebuffer.width;
    const float fb_height = (float) st->state.framebuffer.height;
    const float x0 = (float) x;
@@ -335,7 +334,6 @@ draw_bitmap_quad(struct gl_context *ctx, GLint x, GLint y, GLfloat z,
    const float clip_y0 = y0 / fb_height * 2.0f - 1.0f;
    const float clip_x1 = x1 / fb_width * 2.0f - 1.0f;
    const float clip_y1 = y1 / fb_height * 2.0f - 1.0f;
-   struct st_util_vertex *verts;
 
    /* limit checks */
    {
@@ -359,71 +357,13 @@ draw_bitmap_quad(struct gl_context *ctx, GLint x, GLint y, GLfloat z,
       tBot = (float) height;
    }
 
-   vb.stride = sizeof(struct st_util_vertex);
-
-   u_upload_alloc(st->uploader, 0, 4 * sizeof(struct st_util_vertex), 4,
-                  &vb.buffer_offset, &vb.buffer, (void **) &verts);
-   if (!vb.buffer) {
+   if (!st_draw_quad(st, clip_x0, clip_y0, clip_x1, clip_y1, z,
+                     sLeft, tBot, sRight, tTop, color, 0)) {
       _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBitmap");
-      restore_render_state(ctx);
-      return;
    }
 
-   /* Positions are in clip coords since we need to do clipping in case
-    * the bitmap quad goes beyond the window bounds.
-    */
-   verts[0].x = clip_x0;
-   verts[0].y = clip_y0;
-   verts[0].z = z;
-   verts[0].r = color[0];
-   verts[0].g = color[1];
-   verts[0].b = color[2];
-   verts[0].a = color[3];
-   verts[0].s = sLeft;
-   verts[0].t = tTop;
-
-   verts[1].x = clip_x1;
-   verts[1].y = clip_y0;
-   verts[1].z = z;
-   verts[1].r = color[0];
-   verts[1].g = color[1];
-   verts[1].b = color[2];
-   verts[1].a = color[3];
-   verts[1].s = sRight;
-   verts[1].t = tTop;
-
-   verts[2].x = clip_x1;
-   verts[2].y = clip_y1;
-   verts[2].z = z;
-   verts[2].r = color[0];
-   verts[2].g = color[1];
-   verts[2].b = color[2];
-   verts[2].a = color[3];
-   verts[2].s = sRight;
-   verts[2].t = tBot;
-
-   verts[3].x = clip_x0;
-   verts[3].y = clip_y1;
-   verts[3].z = z;
-   verts[3].r = color[0];
-   verts[3].g = color[1];
-   verts[3].b = color[2];
-   verts[3].a = color[3];
-   verts[3].s = sLeft;
-   verts[3].t = tBot;
-
-   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_TRIANGLE_FAN, 0, 4);
-
    restore_render_state(ctx);
 
-   pipe_resource_reference(&vb.buffer, NULL);
-
    /* We uploaded modified constants, need to invalidate them. */
    st->dirty.mesa |= _NEW_PROGRAM_CONSTANTS;
 }
diff --git a/src/mesa/state_tracker/st_cb_clear.c b/src/mesa/state_tracker/st_cb_clear.c
index 9d043c1..b6bb6dc 100644
--- a/src/mesa/state_tracker/st_cb_clear.c
+++ b/src/mesa/state_tracker/st_cb_clear.c
@@ -44,6 +44,7 @@
 #include "st_cb_bitmap.h"
 #include "st_cb_clear.h"
 #include "st_cb_fbo.h"
+#include "st_draw.h"
 #include "st_format.h"
 #include "st_program.h"
 
@@ -55,7 +56,6 @@
 #include "util/u_framebuffer.h"
 #include "util/u_inlines.h"
 #include "util/u_simple_shaders.h"
-#include "util/u_upload_mgr.h"
 
 #include "cso_cache/cso_context.h"
 
@@ -168,77 +168,6 @@ set_vertex_shader_layered(struct st_context *st)
 
 
 /**
- * Draw a screen-aligned quadrilateral.
- * Coords are clip coords with y=0=bottom.
- */
-static void
-draw_quad(struct st_context *st,
-          float x0, float y0, float x1, float y1, GLfloat z,
-          unsigned num_instances,
-          const union pipe_color_union *color)
-{
-   struct cso_context *cso = st->cso_context;
-   struct pipe_vertex_buffer vb = {0};
-   struct st_util_vertex *verts;
-
-   vb.stride = sizeof(struct st_util_vertex);
-
-   u_upload_alloc(st->uploader, 0, 4 * sizeof(struct st_util_vertex), 4,
-                  &vb.buffer_offset, &vb.buffer, (void **) &verts);
-   if (!vb.buffer) {
-      return;
-   }
-
-   /* Convert Z from [0,1] to [-1,1] range */
-   z = z * 2.0f - 1.0f;
-
-   /* Note: if we're only clearing depth/stencil we still setup vertices
-    * with color, but they'll be ignored.
-    */
-   verts[0].x = x0;
-   verts[0].y = y0;
-   verts[0].z = z;
-   verts[0].r = color->f[0];
-   verts[0].g = color->f[1];
-   verts[0].b = color->f[2];
-   verts[0].a = color->f[3];
-
-   verts[1].x = x1;
-   verts[1].y = y0;
-   verts[1].z = z;
-   verts[1].r = color->f[0];
-   verts[1].g = color->f[1];
-   verts[1].b = color->f[2];
-   verts[1].a = color->f[3];
-
-   verts[2].x = x1;
-   verts[2].y = y1;
-   verts[2].z = z;
-   verts[2].r = color->f[0];
-   verts[2].g = color->f[1];
-   verts[2].b = color->f[2];
-   verts[2].a = color->f[3];
-
-   verts[3].x = x0;
-   verts[3].y = y1;
-   verts[3].z = z;
-   verts[3].r = color->f[0];
-   verts[3].g = color->f[1];
-   verts[3].b = color->f[2];
-   verts[3].a = color->f[3];
-
-   u_upload_unmap(st->uploader);
-
-   /* draw */
-   cso_set_vertex_buffers(cso, cso_get_aux_vertex_buffer_slot(cso), 1, &vb);
-   cso_draw_arrays_instanced(cso, PIPE_PRIM_TRIANGLE_FAN, 0, 4,
-                             0, num_instances);
-   pipe_resource_reference(&vb.buffer, NULL);
-}
-
-
-
-/**
  * Do glClear by drawing a quadrilateral.
  * The vertices of the quad will be computed from the
  * ctx->DrawBuffer->_X/Ymin/max fields.
@@ -368,13 +297,21 @@ clear_with_quad(struct gl_context *ctx, unsigned clear_buffers)
    else
       set_vertex_shader(st);
 
-   /* We can't translate the clear color to the colorbuffer format,
+   /* draw quad matching scissor rect.
+    *
+    * Note: if we're only clearing depth/stencil we still setup vertices
+    * with color, but they'll be ignored.
+    *
+    * We can't translate the clear color to the colorbuffer format,
     * because different colorbuffers may have different formats.
     */
-
-   /* draw quad matching scissor rect */
-   draw_quad(st, x0, y0, x1, y1, (GLfloat) ctx->Depth.Clear, num_layers,
-             (union pipe_color_union*)&ctx->Color.ClearColor);
+   if (!st_draw_quad(st, x0, y0, x1, y1,
+                     ctx->Depth.Clear * 2.0f - 1.0f,
+                     0.0f, 0.0f, 0.0f, 0.0f,
+                     (const float *) &ctx->Color.ClearColor.f,
+                     num_layers)) {
+      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glClear");
+   }
 
    /* Restore pipe state */
    cso_restore_blend(st->cso_context);
diff --git a/src/mesa/state_tracker/st_cb_drawpixels.c b/src/mesa/state_tracker/st_cb_drawpixels.c
index 3a3e51a..d5768c9 100644
--- a/src/mesa/state_tracker/st_cb_drawpixels.c
+++ b/src/mesa/state_tracker/st_cb_drawpixels.c
@@ -56,6 +56,7 @@
 #include "st_cb_fbo.h"
 #include "st_context.h"
 #include "st_debug.h"
+#include "st_draw.h"
 #include "st_format.h"
 #include "st_program.h"
 #include "st_texture.h"
@@ -67,7 +68,6 @@
 #include "util/u_inlines.h"
 #include "util/u_math.h"
 #include "util/u_tile.h"
-#include "util/u_upload_mgr.h"
 #include "cso_cache/cso_context.h"
 
 
@@ -440,100 +440,6 @@ make_texture(struct st_context *st,
 }
 
 
-/**
- * Draw quad with texcoords and optional color.
- * Coords are gallium window coords with y=0=top.
- * \param color  may be null
- * \param invertTex  if true, flip texcoords vertically
- */
-static void
-draw_quad(struct gl_context *ctx, GLfloat x0, GLfloat y0, GLfloat z,
-          GLfloat x1, GLfloat y1, const GLfloat *color,
-          GLboolean invertTex, GLfloat maxXcoord, GLfloat maxYcoord)
-{
-   struct st_context *st = st_context(ctx);
-   struct pipe_vertex_buffer vb = {0};
-   struct st_util_vertex *verts;
-
-   vb.stride = sizeof(struct st_util_vertex);
-
-   u_upload_alloc(st->uploader, 0, 4 * sizeof(struct st_util_vertex), 4,
-                  &vb.buffer_offset, &vb.buffer, (void **) &verts);
-   if (!vb.buffer) {
-      return;
-   }
-
-   /* setup vertex data */
-   {
-      const struct gl_framebuffer *fb = st->ctx->DrawBuffer;
-      const GLfloat fb_width = (GLfloat) fb->Width;
-      const GLfloat fb_height = (GLfloat) fb->Height;
-      const GLfloat clip_x0 = x0 / fb_width * 2.0f - 1.0f;
-      const GLfloat clip_y0 = y0 / fb_height * 2.0f - 1.0f;
-      const GLfloat clip_x1 = x1 / fb_width * 2.0f - 1.0f;
-      const GLfloat clip_y1 = y1 / fb_height * 2.0f - 1.0f;
-      const GLfloat sLeft = 0.0f, sRight = maxXcoord;
-      const GLfloat tTop = invertTex ? maxYcoord : 0.0f;
-      const GLfloat tBot = invertTex ? 0.0f : maxYcoord;
-
-      /* upper-left */
-      verts[0].x = clip_x0;
-      verts[0].y = clip_y0;
-      verts[0].z = z;
-      verts[0].r = color[0];
-      verts[0].g = color[1];
-      verts[0].b = color[2];
-      verts[0].a = color[3];
-      verts[0].s = sLeft;
-      verts[0].t = tTop;
-
-      /* upper-right */
-      verts[1].x = clip_x1;
-      verts[1].y = clip_y0;
-      verts[1].z = z;
-      verts[1].r = color[0];
-      verts[1].g = color[1];
-      verts[1].b = color[2];
-      verts[1].a = color[3];
-      verts[1].s = sRight;
-      verts[1].t = tTop;
-
-      /* lower-right */
-      verts[2].x = clip_x1;
-      verts[2].y = clip_y1;
-      verts[2].z = z;
-      verts[2].r = color[0];
-      verts[2].g = color[1];
-      verts[2].b = color[2];
-      verts[2].a = color[3];
-      verts[2].s = sRight;
-      verts[2].t = tBot;
-
-      /* lower-left */
-      verts[3].x = clip_x0;
-      verts[3].y = clip_y1;
-      verts[3].z = z;
-      verts[3].r = color[0];
-      verts[3].g = color[1];
-      verts[3].b = color[2];
-      verts[3].a = color[3];
-      verts[3].s = sLeft;
-      verts[3].t = tBot;
-   }
-
-   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, 4);
-
-   pipe_resource_reference(&vb.buffer, NULL);
-}
-
-
-
 static void
 draw_textured_quad(struct gl_context *ctx, GLint x, GLint y, GLfloat z,
                    GLsizei width, GLsizei height,
@@ -723,9 +629,27 @@ draw_textured_quad(struct gl_context *ctx, GLint x, GLint y, GLfloat z,
    /* convert Z from [0,1] to [-1,-1] to match viewport Z scale/bias */
    z = z * 2.0f - 1.0f;
 
-   draw_quad(ctx, x0, y0, z, x1, y1, color, invertTex,
-             normalized ? ((GLfloat) width / sv[0]->texture->width0) : (GLfloat)width,
-             normalized ? ((GLfloat) height / sv[0]->texture->height0) : (GLfloat)height);
+   {
+      const struct gl_framebuffer *fb = ctx->DrawBuffer;
+      const float fb_width = (float) fb->Width;
+      const float fb_height = (float) fb->Height;
+      const float clip_x0 = x0 / fb_width * 2.0f - 1.0f;
+      const float clip_y0 = y0 / fb_height * 2.0f - 1.0f;
+      const float clip_x1 = x1 / fb_width * 2.0f - 1.0f;
+      const float clip_y1 = y1 / fb_height * 2.0f - 1.0f;
+      const float maxXcoord = normalized ?
+         ((float) width / sv[0]->texture->width0) : (float) width;
+      const float maxYcoord = normalized
+         ? ((float) height / sv[0]->texture->height0) : (float) height;
+      const float sLeft = 0.0f, sRight = maxXcoord;
+      const float tTop = invertTex ? maxYcoord : 0.0f;
+      const float tBot = invertTex ? 0.0f : maxYcoord;
+
+      if (!st_draw_quad(ctx->st, clip_x0, clip_y0, clip_x1, clip_y1, z,
+                        sLeft, tBot, sRight, tTop, color, 0)) {
+         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glDrawPixels");
+      }
+   }
 
    /* restore state */
    cso_restore_rasterizer(cso);
diff --git a/src/mesa/state_tracker/st_draw.c b/src/mesa/state_tracker/st_draw.c
index a299dd5..daa6441 100644
--- a/src/mesa/state_tracker/st_draw.c
+++ b/src/mesa/state_tracker/st_draw.c
@@ -398,3 +398,87 @@ st_destroy_draw(struct st_context *st)
 {
    draw_destroy(st->draw);
 }
+
+
+/**
+ * Draw a quad with given position, texcoords and color.
+ */
+bool
+st_draw_quad(struct st_context *st,
+             float x0, float y0, float x1, float y1, float z,
+             float s0, float t0, float s1, float t1,
+             const float *color,
+             unsigned num_instances)
+{
+   struct pipe_vertex_buffer vb = {0};
+   struct st_util_vertex *verts;
+
+   vb.stride = sizeof(struct st_util_vertex);
+
+   u_upload_alloc(st->uploader, 0, 4 * sizeof(struct st_util_vertex), 4,
+                  &vb.buffer_offset, &vb.buffer, (void **) &verts);
+   if (!vb.buffer) {
+      return false;
+   }
+
+   /* lower-left */
+   verts[0].x = x0;
+   verts[0].y = y1;
+   verts[0].z = z;
+   verts[0].r = color[0];
+   verts[0].g = color[1];
+   verts[0].b = color[2];
+   verts[0].a = color[3];
+   verts[0].s = s0;
+   verts[0].t = t0;
+
+   /* lower-right */
+   verts[1].x = x1;
+   verts[1].y = y1;
+   verts[1].z = z;
+   verts[1].r = color[0];
+   verts[1].g = color[1];
+   verts[1].b = color[2];
+   verts[1].a = color[3];
+   verts[1].s = s1;
+   verts[1].t = t0;
+
+   /* upper-right */
+   verts[2].x = x1;
+   verts[2].y = y0;
+   verts[2].z = z;
+   verts[2].r = color[0];
+   verts[2].g = color[1];
+   verts[2].b = color[2];
+   verts[2].a = color[3];
+   verts[2].s = s1;
+   verts[2].t = t1;
+
+   /* upper-left */
+   verts[3].x = x0;
+   verts[3].y = y0;
+   verts[3].z = z;
+   verts[3].r = color[0];
+   verts[3].g = color[1];
+   verts[3].b = color[2];
+   verts[3].a = color[3];
+   verts[3].s = s0;
+   verts[3].t = t1;
+
+   u_upload_unmap(st->uploader);
+
+   cso_set_vertex_buffers(st->cso_context,
+                          cso_get_aux_vertex_buffer_slot(st->cso_context),
+                          1, &vb);
+
+   if (num_instances > 1) {
+      cso_draw_arrays_instanced(st->cso_context, PIPE_PRIM_TRIANGLE_FAN, 0, 4,
+                                0, num_instances);
+   } else {
+      cso_draw_arrays(st->cso_context, PIPE_PRIM_TRIANGLE_FAN, 0, 4);
+   }
+
+   pipe_resource_reference(&vb.buffer, NULL);
+
+   return true;
+}
diff --git a/src/mesa/state_tracker/st_draw.h b/src/mesa/state_tracker/st_draw.h
index a973c8a..d85c3b7 100644
--- a/src/mesa/state_tracker/st_draw.h
+++ b/src/mesa/state_tracker/st_draw.h
@@ -85,4 +85,11 @@ pointer_to_offset(const void *ptr)
 }
 
 
+bool
+st_draw_quad(struct st_context *st,
+             float x0, float y0, float x1, float y1, float z,
+             float s0, float t0, float s1, float t1,
+             const float *color,
+             unsigned num_instances);
+
 #endif
-- 
1.9.1



More information about the mesa-dev mailing list