gallium: add some temporary code for testing draw module vertex passthrough
[mesa.git] / src / mesa / state_tracker / st_cb_clear.c
index 0cd469c156a99dc64355e6494b76647bea273c76..4fe6195a07013c7a555453affcce17e073f9d55b 100644 (file)
@@ -35,7 +35,6 @@
 #include "main/macros.h"
 #include "shader/prog_instruction.h"
 #include "st_atom.h"
-#include "st_cache.h"
 #include "st_context.h"
 #include "st_cb_accum.h"
 #include "st_cb_clear.h"
 #include "pipe/p_defines.h"
 #include "pipe/p_winsys.h"
 
+#include "cso_cache/cso_context.h"
 
 
+/* XXX for testing draw module vertex passthrough: */
+#define TEST_DRAW_PASSTHROUGH 0
 
 
 static GLuint
@@ -157,8 +159,7 @@ make_frag_shader(struct st_context *st)
    p->OutputsWritten = (1 << FRAG_RESULT_COLR);
 
    stfp = (struct st_fragment_program *) p;
-   st_translate_fragment_program(st, stfp, NULL,
-                                 stfp->tokens, ST_MAX_SHADER_TOKENS);
+   st_translate_fragment_program(st, stfp, NULL);
 
    return stfp;
 }
@@ -206,9 +207,10 @@ make_vertex_shader(struct st_context *st)
                         (1 << VERT_RESULT_HPOS));
 
    stvp = (struct st_vertex_program *) p;
-   st_translate_vertex_program(st, stvp, NULL,
-                               stvp->tokens, ST_MAX_SHADER_TOKENS);
+   st_translate_vertex_program(st, stvp, NULL);
+#if 0
    assert(stvp->cso);
+#endif
 
    return stvp;
 }
@@ -228,6 +230,12 @@ draw_quad(GLcontext *ctx,
    GLfloat verts[4][2][4]; /* four verts, two attribs, XYZW */
    GLuint i;
 
+#if TEST_DRAW_PASSTHROUGH
+   /* invert Y coords (may be off by one pixel) */
+   y0 = ctx->DrawBuffer->Height - y0;
+   y1 = ctx->DrawBuffer->Height - y1;
+#endif
+
    /* positions */
    verts[0][0][0] = x0;
    verts[0][0][1] = y0;
@@ -251,7 +259,7 @@ draw_quad(GLcontext *ctx,
       verts[i][1][3] = color[3];
    }
 
-   st_draw_vertices(ctx, PIPE_PRIM_QUADS, 4, (float *) verts, 2);
+   st_draw_vertices(ctx, PIPE_PRIM_QUADS, 4, (float *) verts, 2, GL_FALSE);
 }
 
 
@@ -272,11 +280,18 @@ clear_with_quad(GLcontext *ctx,
    const GLfloat x1 = ctx->DrawBuffer->_Xmax;
    const GLfloat y1 = ctx->DrawBuffer->_Ymax;
 
+   /*
+   printf("%s %s%s%s %f,%f %f,%f\n", __FUNCTION__, 
+         color ? "color, " : "",
+         depth ? "depth, " : "",
+         stencil ? "stencil" : "",
+         x0, y0,
+         x1, y1);
+   */
 
    /* blend state: RGBA masking */
    {
       struct pipe_blend_state blend;
-      const struct cso_blend *cso;
       memset(&blend, 0, sizeof(blend));
       if (color) {
          if (ctx->Color.ColorMask[0])
@@ -290,14 +305,12 @@ clear_with_quad(GLcontext *ctx,
          if (st->ctx->Color.DitherFlag)
             blend.dither = 1;
       }
-      cso = st_cached_blend_state(st, &blend);
-      pipe->bind_blend_state(pipe, cso->data);
+      cso_set_blend(st->cso_context, &blend);
    }
 
    /* depth_stencil state: always pass/set to ref value */
    {
       struct pipe_depth_stencil_alpha_state depth_stencil;
-      const struct cso_depth_stencil_alpha *cso;
       memset(&depth_stencil, 0, sizeof(depth_stencil));
       if (depth) {
          depth_stencil.depth.enabled = 1;
@@ -315,14 +328,13 @@ clear_with_quad(GLcontext *ctx,
          depth_stencil.stencil[0].value_mask = 0xff;
          depth_stencil.stencil[0].write_mask = ctx->Stencil.WriteMask[0] & 0xff;
       }
-      cso = st_cached_depth_stencil_alpha_state(st, &depth_stencil);
-      pipe->bind_depth_stencil_alpha_state(pipe, cso->data);
+
+      cso_set_depth_stencil_alpha(st->cso_context, &depth_stencil);
    }
 
    /* rasterizer state: nothing */
    {
       struct pipe_rasterizer_state raster;
-      const struct cso_rasterizer *cso;
       memset(&raster, 0, sizeof(raster));
 #if 0
       /* don't do per-pixel scissor; we'll just draw a PIPE_PRIM_QUAD
@@ -331,8 +343,11 @@ clear_with_quad(GLcontext *ctx,
       if (ctx->Scissor.Enabled)
          raster.scissor = 1;
 #endif
-      cso = st_cached_rasterizer_state(st, &raster);
-      pipe->bind_rasterizer_state(pipe, cso->data);
+#if TEST_DRAW_PASSTHROUGH
+      raster.bypass_clipping = 1;
+      raster.bypass_vs = 1;
+#endif
+      cso_set_rasterizer(st->cso_context, &raster);
    }
 
    /* fragment shader state: color pass-through program */
@@ -341,18 +356,21 @@ clear_with_quad(GLcontext *ctx,
       if (!stfp) {
          stfp = make_frag_shader(st);
       }
-      pipe->bind_fs_state(pipe, stfp->fs->data);
+      pipe->bind_fs_state(pipe, stfp->driver_shader);
    }
 
+#if !TEST_DRAW_PASSTHROUGH
    /* vertex shader state: color/position pass-through */
    {
       static struct st_vertex_program *stvp = NULL;
       if (!stvp) {
          stvp = make_vertex_shader(st);
       }
-      pipe->bind_vs_state(pipe, stvp->cso->data);
+      pipe->bind_vs_state(pipe, stvp->driver_shader);
    }
+#endif
 
+#if !TEST_DRAW_PASSTHROUGH
    /* viewport state: viewport matching window dims */
    {
       const float width = ctx->DrawBuffer->Width;
@@ -368,20 +386,24 @@ clear_with_quad(GLcontext *ctx,
       vp.translate[3] = 0.0;
       pipe->set_viewport_state(pipe, &vp);
    }
+#endif
 
    /* draw quad matching scissor rect (XXX verify coord round-off) */
    draw_quad(ctx, x0, y0, x1, y1, ctx->Depth.Clear, ctx->Color.ClearColor);
 
+#if 0
+   /* Can't depend on old state objects still existing -- may have
+    * been deleted to make room in the hash, etc.  (Should get
+    * fixed...)
+    */
+   st_invalidate_state(ctx, _NEW_COLOR | _NEW_DEPTH | _NEW_STENCIL);
+#else
    /* Restore pipe state */
-   pipe->bind_blend_state(pipe, st->state.blend->data);
-   pipe->bind_depth_stencil_alpha_state(pipe, st->state.depth_stencil->data);
-   pipe->bind_fs_state(pipe, st->state.fs->data);
-   pipe->bind_vs_state(pipe, st->state.vs->cso->data);
-   pipe->bind_rasterizer_state(pipe, st->state.rasterizer->data);
+   cso_set_rasterizer(st->cso_context, &st->state.rasterizer);
+   pipe->bind_fs_state(pipe, st->fp->driver_shader);
+   pipe->bind_vs_state(pipe, st->vp->driver_shader);
+#endif
    pipe->set_viewport_state(pipe, &st->state.viewport);
-   /* OR:
-   st_invalidate_state(ctx, _NEW_COLOR | _NEW_DEPTH | _NEW_STENCIL);
-   */
 }
 
 
@@ -389,13 +411,44 @@ clear_with_quad(GLcontext *ctx,
  * Determine if we need to clear the depth buffer by drawing a quad.
  */
 static INLINE GLboolean
-check_clear_color_with_quad(GLcontext *ctx)
+check_clear_color_with_quad(GLcontext *ctx, struct gl_renderbuffer *rb)
+{
+   const struct st_renderbuffer *strb = st_renderbuffer(rb);
+
+   if (strb->surface->status == PIPE_SURFACE_STATUS_UNDEFINED)
+      return FALSE;
+
+   if (ctx->Scissor.Enabled)
+      return TRUE;
+
+   if (!ctx->Color.ColorMask[0] ||
+       !ctx->Color.ColorMask[1] ||
+       !ctx->Color.ColorMask[2] ||
+       !ctx->Color.ColorMask[3])
+      return TRUE;
+
+   return FALSE;
+}
+
+
+static INLINE GLboolean
+check_clear_depth_stencil_with_quad(GLcontext *ctx, struct gl_renderbuffer *rb)
 {
-   return !(ctx->Color.ColorMask[0] &&
-            ctx->Color.ColorMask[1] &&
-            ctx->Color.ColorMask[2] &&
-            ctx->Color.ColorMask[3] &&
-            !ctx->Scissor.Enabled);
+   const struct st_renderbuffer *strb = st_renderbuffer(rb);
+   const GLuint stencilMax = (1 << rb->StencilBits) - 1;
+   GLboolean maskStencil
+      = (ctx->Stencil.WriteMask[0] & stencilMax) != stencilMax;
+
+   if (strb->surface->status == PIPE_SURFACE_STATUS_UNDEFINED)
+      return FALSE;
+
+   if (ctx->Scissor.Enabled)
+      return TRUE;
+
+   if (maskStencil)
+      return TRUE;
+
+   return FALSE;
 }
 
 
@@ -407,10 +460,19 @@ check_clear_depth_with_quad(GLcontext *ctx, struct gl_renderbuffer *rb)
 {
    const struct st_renderbuffer *strb = st_renderbuffer(rb);
    const GLboolean isDS = is_depth_stencil_format(strb->surface->format);
-   return  ctx->Scissor.Enabled
-      || (isDS && 
-         strb->surface->status == PIPE_SURFACE_STATUS_DEFINED &&
-         ctx->DrawBuffer->Visual.stencilBits > 0);
+
+   if (strb->surface->status == PIPE_SURFACE_STATUS_UNDEFINED)
+      return FALSE;
+
+   if (ctx->Scissor.Enabled)
+      return TRUE;
+
+   if (isDS && 
+       strb->surface->status == PIPE_SURFACE_STATUS_DEFINED &&
+       ctx->DrawBuffer->Visual.stencilBits > 0)
+      return TRUE;
+
+   return FALSE;
 }
 
 
@@ -425,9 +487,27 @@ check_clear_stencil_with_quad(GLcontext *ctx, struct gl_renderbuffer *rb)
    const GLuint stencilMax = (1 << rb->StencilBits) - 1;
    const GLboolean maskStencil
       = (ctx->Stencil.WriteMask[0] & stencilMax) != stencilMax;
-   return maskStencil
-      || ctx->Scissor.Enabled
-      || (isDS && ctx->DrawBuffer->Visual.depthBits > 0);
+
+   if (strb->surface->status == PIPE_SURFACE_STATUS_UNDEFINED)
+      return FALSE;
+
+   if (maskStencil) 
+      return TRUE;
+
+   if (ctx->Scissor.Enabled)
+      return TRUE;
+
+   /* This is correct, but it is necessary to look at the depth clear
+    * value held in the surface when it comes time to issue the clear,
+    * rather than taking depth and stencil clear values from the
+    * current state.
+    */
+   if (isDS && 
+       strb->surface->status == PIPE_SURFACE_STATUS_DEFINED &&
+       ctx->DrawBuffer->Visual.depthBits > 0)
+      return TRUE;
+
+   return FALSE;
 }
 
 
@@ -436,41 +516,30 @@ check_clear_stencil_with_quad(GLcontext *ctx, struct gl_renderbuffer *rb)
 static void
 clear_color_buffer(GLcontext *ctx, struct gl_renderbuffer *rb)
 {
-   struct st_renderbuffer *strb = st_renderbuffer(rb);
+   if (check_clear_color_with_quad( ctx, rb )) {
+      /* masking or scissoring */
+      clear_with_quad(ctx, GL_TRUE, GL_FALSE, GL_FALSE);
+   }
+   else {
+      struct st_renderbuffer *strb = st_renderbuffer(rb);
 
-   if (ctx->Color.ColorMask[0] &&
-       ctx->Color.ColorMask[1] &&
-       ctx->Color.ColorMask[2] &&
-       ctx->Color.ColorMask[3] &&
-       !ctx->Scissor.Enabled)
-   {
       /* clear whole buffer w/out masking */
-      GLuint clearValue
-         = color_value(strb->surface->format, ctx->Color.ClearColor);
+      uint clearValue = color_value(strb->surface->format, ctx->Color.ClearColor);
       ctx->st->pipe->clear(ctx->st->pipe, strb->surface, clearValue);
    }
-   else {
-      /* masking or scissoring */
-      clear_with_quad(ctx, GL_TRUE, GL_FALSE, GL_FALSE);
-   }
 }
 
 
 static void
 clear_depth_buffer(GLcontext *ctx, struct gl_renderbuffer *rb)
 {
-   struct st_renderbuffer *strb = st_renderbuffer(rb);
-   /*
-   const GLboolean isDS = is_depth_stencil_format(strb->surface->format);
-   */
-
-   assert(strb->surface->format);
-
    if (check_clear_depth_with_quad(ctx, rb)) {
       /* scissoring or we have a combined depth/stencil buffer */
       clear_with_quad(ctx, GL_FALSE, GL_TRUE, GL_FALSE);
    }
    else {
+      struct st_renderbuffer *strb = st_renderbuffer(rb);
+
       /* simple clear of whole buffer */
       uint clearValue = depth_value(strb->surface->format, ctx->Depth.Clear);
       ctx->st->pipe->clear(ctx->st->pipe, strb->surface, clearValue);
@@ -481,21 +550,24 @@ clear_depth_buffer(GLcontext *ctx, struct gl_renderbuffer *rb)
 static void
 clear_stencil_buffer(GLcontext *ctx, struct gl_renderbuffer *rb)
 {
-   struct st_renderbuffer *strb = st_renderbuffer(rb);
-   const GLboolean isDS = is_depth_stencil_format(strb->surface->format);
-   const GLuint stencilMax = (1 << rb->StencilBits) - 1;
-   GLboolean maskStencil
-      = (ctx->Stencil.WriteMask[0] & stencilMax) != stencilMax;
-
-   if (maskStencil ||
-       ctx->Scissor.Enabled ||
-       (isDS && ctx->DrawBuffer->Visual.depthBits > 0)) {
+   if (check_clear_stencil_with_quad(ctx, rb)) {
       /* masking or scissoring or combined depth/stencil buffer */
       clear_with_quad(ctx, GL_FALSE, GL_FALSE, GL_TRUE);
    }
    else {
+      struct st_renderbuffer *strb = st_renderbuffer(rb);
+
       /* simple clear of whole buffer */
       GLuint clearValue = ctx->Stencil.Clear;
+
+      switch (strb->surface->format) {
+      case PIPE_FORMAT_S8Z24_UNORM:
+         clearValue <<= 24;
+         break;
+      default:
+         ; /* no-op, stencil value is in least significant bits */
+      }  
+
       ctx->st->pipe->clear(ctx->st->pipe, strb->surface, clearValue);
    }
 }
@@ -504,14 +576,14 @@ clear_stencil_buffer(GLcontext *ctx, struct gl_renderbuffer *rb)
 static void
 clear_depth_stencil_buffer(GLcontext *ctx, struct gl_renderbuffer *rb)
 {
-   struct st_renderbuffer *strb = st_renderbuffer(rb);
-   const GLuint stencilMax = (1 << rb->StencilBits) - 1;
-   GLboolean maskStencil
-      = (ctx->Stencil.WriteMask[0] & stencilMax) != stencilMax;
 
-   assert(is_depth_stencil_format(strb->surface->format));
+   if (check_clear_depth_stencil_with_quad(ctx, rb)) {
+      /* masking or scissoring */
+      clear_with_quad(ctx, GL_FALSE, GL_TRUE, GL_TRUE);
+   }
+   else {
+      struct st_renderbuffer *strb = st_renderbuffer(rb);
 
-   if (!maskStencil && !ctx->Scissor.Enabled) {
       /* clear whole buffer w/out masking */
       GLuint clearValue = depth_value(strb->surface->format, ctx->Depth.Clear);
 
@@ -520,7 +592,7 @@ clear_depth_stencil_buffer(GLcontext *ctx, struct gl_renderbuffer *rb)
          clearValue |= ctx->Stencil.Clear << 24;
          break;
       case PIPE_FORMAT_Z24S8_UNORM:
-         clearValue |= clearValue | ctx->Stencil.Clear;
+         clearValue |= ctx->Stencil.Clear;
          break;
       default:
          assert(0);
@@ -528,10 +600,6 @@ clear_depth_stencil_buffer(GLcontext *ctx, struct gl_renderbuffer *rb)
 
       ctx->st->pipe->clear(ctx->st->pipe, strb->surface, clearValue);
    }
-   else {
-      /* masking or scissoring */
-      clear_with_quad(ctx, GL_FALSE, GL_TRUE, GL_TRUE);
-   }
 }