st/vega: Add CLEAR renderer state for vgClear.
authorChia-I Wu <olv@lunarg.com>
Fri, 26 Nov 2010 15:21:17 +0000 (23:21 +0800)
committerChia-I Wu <olv@lunarg.com>
Wed, 1 Dec 2010 03:23:49 +0000 (11:23 +0800)
This state provides the ability to clear rectangles of the framebuffer
to the specified color, honoring scissoring.  vegaClear is updated to
make use of the state.

src/gallium/state_trackers/vega/api_masks.c
src/gallium/state_trackers/vega/renderer.c
src/gallium/state_trackers/vega/renderer.h

index 189390ec2d38d582813bca4774f1dc36b06cae46..45f77d7d707c49eeb254d67983492558216021e1 100644 (file)
@@ -28,6 +28,7 @@
 
 #include "mask.h"
 #include "api.h"
+#include "renderer.h"
 
 #include "vg_context.h"
 #include "pipe/p_context.h"
 
 #define DISABLE_1_1_MASKING 1
 
-/**
- * Draw a screen-aligned quadrilateral.
- * Coords are window coords with y=0=bottom.  These coords will be transformed
- * by the vertex shader and viewport transform.
- */
-static void
-draw_clear_quad(struct vg_context *st,
-                float x0, float y0, float x1, float y1, float z,
-                const VGfloat color[4])
-{
-   struct pipe_context *pipe = st->pipe;
-   struct pipe_resource *buf;
-   VGuint i;
-
-   /* positions */
-   st->clear.vertices[0][0][0] = x0;
-   st->clear.vertices[0][0][1] = y0;
-
-   st->clear.vertices[1][0][0] = x1;
-   st->clear.vertices[1][0][1] = y0;
-
-   st->clear.vertices[2][0][0] = x1;
-   st->clear.vertices[2][0][1] = y1;
-
-   st->clear.vertices[3][0][0] = x0;
-   st->clear.vertices[3][0][1] = y1;
-
-   /* same for all verts: */
-   for (i = 0; i < 4; i++) {
-      st->clear.vertices[i][0][2] = z;
-      st->clear.vertices[i][0][3] = 1.0;
-      st->clear.vertices[i][1][0] = color[0];
-      st->clear.vertices[i][1][1] = color[1];
-      st->clear.vertices[i][1][2] = color[2];
-      st->clear.vertices[i][1][3] = color[3];
-   }
-
-
-   /* put vertex data into vbuf */
-   buf =  pipe_user_buffer_create(pipe->screen,
-                                  st->clear.vertices,
-                                  sizeof(st->clear.vertices),
-                                 PIPE_BIND_VERTEX_BUFFER);
-
-
-   /* draw */
-   if (buf) {
-      cso_set_vertex_elements(st->cso_context, 2, st->velems);
-
-      util_draw_vertex_buffer(pipe, buf, 0,
-                              PIPE_PRIM_TRIANGLE_FAN,
-                              4,  /* verts */
-                              2); /* attribs/vert */
-
-      pipe_resource_reference(&buf, NULL);
-   }
-}
-
-/**
- * Do vgClear by drawing a quadrilateral.
- */
-static void
-clear_with_quad(struct vg_context *st, float x0, float y0,
-                float width, float height, const VGfloat clear_color[4])
-{
-   VGfloat x1, y1;
-
-   vg_validate_state(st);
-
-   x1 = x0 + width;
-   y1 = y0 + height;
-
-   /*
-     printf("%s %f,%f %f,%f\n", __FUNCTION__,
-     x0, y0,
-     x1, y1);
-   */
-
-   cso_save_blend(st->cso_context);
-   cso_save_rasterizer(st->cso_context);
-   cso_save_fragment_shader(st->cso_context);
-   cso_save_vertex_shader(st->cso_context);
-
-   /* blend state: RGBA masking */
-   {
-      struct pipe_blend_state blend;
-      memset(&blend, 0, sizeof(blend));
-      blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE;
-      blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE;
-      blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO;
-      blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO;
-      blend.rt[0].colormask = PIPE_MASK_RGBA;
-      cso_set_blend(st->cso_context, &blend);
-   }
-
-   cso_set_rasterizer(st->cso_context, &st->clear.raster);
-
-   cso_set_fragment_shader_handle(st->cso_context, st->clear.fs);
-   cso_set_vertex_shader_handle(st->cso_context, vg_clear_vs(st));
-
-   /* draw quad matching scissor rect (XXX verify coord round-off) */
-   draw_clear_quad(st, x0, y0, x1, y1, 0, clear_color);
-
-   /* Restore pipe state */
-   cso_restore_blend(st->cso_context);
-   cso_restore_rasterizer(st->cso_context);
-   cso_restore_fragment_shader(st->cso_context);
-   cso_restore_vertex_shader(st->cso_context);
-}
-
-
 void vegaMask(VGHandle mask, VGMaskOperation operation,
               VGint x, VGint y,
               VGint width, VGint height)
@@ -214,8 +104,10 @@ void vegaClear(VGint x, VGint y,
        (x == 0 && y == 0 && width == fb->width && height == fb->height)) {
       ctx->pipe->clear(ctx->pipe, PIPE_CLEAR_COLOR | PIPE_CLEAR_DEPTHSTENCIL,
                        ctx->state.vg.clear_color, 1., 0);
-   } else {
-      clear_with_quad(ctx, x, y, width, height, ctx->state.vg.clear_color);
+   } else if (renderer_clear_begin(ctx->renderer)) {
+      /* XXX verify coord round-off */
+      renderer_clear(ctx->renderer, x, y, width, height, ctx->state.vg.clear_color);
+      renderer_clear_end(ctx->renderer);
    }
 }
 
index 60c4315a1fd75914de11f1249ddeea1bb581fb3e..d326cfc50156c26387e2a6f44c50f7cb45c551b0 100644 (file)
@@ -48,6 +48,7 @@ typedef enum {
    RENDERER_STATE_COPY,
    RENDERER_STATE_DRAWTEX,
    RENDERER_STATE_SCISSOR,
+   RENDERER_STATE_CLEAR,
    NUM_RENDERER_STATES
 } RendererState;
 
@@ -623,6 +624,60 @@ void renderer_scissor_end(struct renderer *renderer)
    renderer->state = RENDERER_STATE_INIT;
 }
 
+/**
+ * Prepare the renderer for clearing.
+ */
+VGboolean renderer_clear_begin(struct renderer *renderer)
+{
+   assert(renderer->state == RENDERER_STATE_INIT);
+
+   cso_save_blend(renderer->cso);
+   cso_save_fragment_shader(renderer->cso);
+   cso_save_vertex_shader(renderer->cso);
+
+   renderer_set_blend(renderer, ~0);
+   renderer_set_fs(renderer, RENDERER_FS_COLOR);
+   renderer_set_vs(renderer, RENDERER_VS_COLOR);
+
+   renderer->state = RENDERER_STATE_CLEAR;
+
+   return VG_TRUE;
+}
+
+/**
+ * Clear the framebuffer with the specified region and color.
+ *
+ * The coordinates are in surface coordinates.
+ */
+void renderer_clear(struct renderer *renderer,
+                    VGint x, VGint y, VGint width, VGint height,
+                    const VGfloat color[4])
+{
+   VGuint i;
+
+   assert(renderer->state == RENDERER_STATE_CLEAR);
+
+   renderer_quad_pos(renderer, x, y, x + width, y + height, VG_TRUE);
+   for (i = 0; i < 4; i++)
+      memcpy(renderer->vertices[i][1], color, sizeof(VGfloat) * 4);
+
+   renderer_quad_draw(renderer);
+}
+
+/**
+ * End clearing and retore the states.
+ */
+void renderer_clear_end(struct renderer *renderer)
+{
+   assert(renderer->state == RENDERER_STATE_CLEAR);
+
+   cso_restore_blend(renderer->cso);
+   cso_restore_fragment_shader(renderer->cso);
+   cso_restore_vertex_shader(renderer->cso);
+
+   renderer->state = RENDERER_STATE_INIT;
+}
+
 static void setup_shaders(struct renderer *ctx)
 {
    struct pipe_context *pipe = ctx->pipe;
index 2644c9f580debd2cb2eac0c1a31492a7bb3f9006..fa0782280ad053739138282edf14a96006ce51a8 100644 (file)
@@ -68,6 +68,14 @@ void renderer_scissor(struct renderer *renderer,
 
 void renderer_scissor_end(struct renderer *renderer);
 
+VGboolean renderer_clear_begin(struct renderer *renderer);
+
+void renderer_clear(struct renderer *renderer,
+                    VGint x, VGint y, VGint width, VGint height,
+                    const VGfloat color[4]);
+
+void renderer_clear_end(struct renderer *renderer);
+
 void renderer_draw_quad(struct renderer *,
                         VGfloat x1, VGfloat y1,
                         VGfloat x2, VGfloat y2,