st/mesa: flush the glBitmap cache before changing framebuffer state
[mesa.git] / src / mesa / state_tracker / st_cb_clear.c
index 117000ba7164b37c13dd60c74db353c486851513..3cd8756f2ee415e4b245f1836292cbc3f19f7a06 100644 (file)
   */
 
 #include "main/glheader.h"
+#include "main/accum.h"
 #include "main/formats.h"
 #include "main/macros.h"
 #include "program/prog_instruction.h"
 #include "st_context.h"
 #include "st_atom.h"
-#include "st_cb_accum.h"
 #include "st_cb_clear.h"
 #include "st_cb_fbo.h"
 #include "st_format.h"
@@ -53,6 +53,7 @@
 #include "util/u_inlines.h"
 #include "util/u_simple_shaders.h"
 #include "util/u_draw_quad.h"
+#include "util/u_upload_mgr.h"
 
 #include "cso_cache/cso_context.h"
 
@@ -68,6 +69,7 @@ st_init_clear(struct st_context *st)
    memset(&st->clear, 0, sizeof(st->clear));
 
    st->clear.raster.gl_rasterization_rules = 1;
+   st->clear.raster.depth_clip = 1;
    st->clear.enable_ds_separate = pscreen->get_param(pscreen, PIPE_CAP_DEPTHSTENCIL_CLEAR_SEPARATE);
 }
 
@@ -86,10 +88,6 @@ st_destroy_clear(struct st_context *st)
       cso_delete_vertex_shader(st->cso_context, st->clear.vs);
       st->clear.vs = NULL;
    }
-   if (st->clear.vbuf) {
-      pipe_resource_reference(&st->clear.vbuf, NULL);
-      st->clear.vbuf = NULL;
-   }
 }
 
 
@@ -136,76 +134,53 @@ set_vertex_shader(struct st_context *st)
 static void
 draw_quad(struct st_context *st,
           float x0, float y0, float x1, float y1, GLfloat z,
-          const GLfloat color[4])
+          const union pipe_color_union *color)
 {
    struct pipe_context *pipe = st->pipe;
-
-   /* XXX: Need to improve buffer_write to allow NO_WAIT (as well as
-    * no_flush) updates to buffers where we know there is no conflict
-    * with previous data.  Currently using max_slots > 1 will cause
-    * synchronous rendering if the driver flushes its command buffers
-    * between one bitmap and the next.  Our flush hook below isn't
-    * sufficient to catch this as the driver doesn't tell us when it
-    * flushes its own command buffers.  Until this gets fixed, pay the
-    * price of allocating a new buffer for each bitmap cache-flush to
-    * avoid synchronous rendering.
-    */
-   const GLuint max_slots = 1; /* 1024 / sizeof(st->clear.vertices); */
-   GLuint i;
-
-   if (st->clear.vbuf_slot >= max_slots) {
-      pipe_resource_reference(&st->clear.vbuf, NULL);
-      st->clear.vbuf_slot = 0;
-   }
-
-   if (!st->clear.vbuf) {
-      st->clear.vbuf = pipe_buffer_create(pipe->screen,
-                                          PIPE_BIND_VERTEX_BUFFER,
-                                          PIPE_USAGE_STREAM,
-                                          max_slots * sizeof(st->clear.vertices));
+   struct pipe_resource *vbuf = NULL;
+   GLuint i, offset;
+   float (*vertices)[2][4];  /**< vertex pos + color */
+
+   u_upload_alloc(st->uploader, 0, 4 * sizeof(vertices[0]), &offset, &vbuf,
+                 (void**)&vertices);
+   if (!vbuf) {
+      return;
    }
 
    /* positions */
-   st->clear.vertices[0][0][0] = x0;
-   st->clear.vertices[0][0][1] = y0;
+   vertices[0][0][0] = x0;
+   vertices[0][0][1] = y0;
 
-   st->clear.vertices[1][0][0] = x1;
-   st->clear.vertices[1][0][1] = y0;
+   vertices[1][0][0] = x1;
+   vertices[1][0][1] = y0;
 
-   st->clear.vertices[2][0][0] = x1;
-   st->clear.vertices[2][0][1] = y1;
+   vertices[2][0][0] = x1;
+   vertices[2][0][1] = y1;
 
-   st->clear.vertices[3][0][0] = x0;
-   st->clear.vertices[3][0][1] = y1;
+   vertices[3][0][0] = x0;
+   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];
+      vertices[i][0][2] = z;
+      vertices[i][0][3] = 1.0;
+      vertices[i][1][0] = color->f[0];
+      vertices[i][1][1] = color->f[1];
+      vertices[i][1][2] = color->f[2];
+      vertices[i][1][3] = color->f[3];
    }
 
-   /* put vertex data into vbuf */
-   pipe_buffer_write_nooverlap(st->pipe, st->clear.vbuf,
-                                           st->clear.vbuf_slot
-                                             * sizeof(st->clear.vertices),
-                                           sizeof(st->clear.vertices),
-                                           st->clear.vertices);
+   u_upload_unmap(st->uploader);
 
    /* draw */
    util_draw_vertex_buffer(pipe,
                            st->cso_context,
-                           st->clear.vbuf, 
-                           st->clear.vbuf_slot * sizeof(st->clear.vertices),
+                           vbuf, offset,
                            PIPE_PRIM_TRIANGLE_FAN,
                            4,  /* verts */
                            2); /* attribs/vert */
 
-   /* Increment slot */
-   st->clear.vbuf_slot++;
+   pipe_resource_reference(&vbuf, NULL);
 }
 
 
@@ -227,7 +202,7 @@ clear_with_quad(struct gl_context *ctx,
    const GLfloat x1 = (GLfloat) ctx->DrawBuffer->_Xmax / fb_width * 2.0f - 1.0f;
    const GLfloat y0 = (GLfloat) ctx->DrawBuffer->_Ymin / fb_height * 2.0f - 1.0f;
    const GLfloat y1 = (GLfloat) ctx->DrawBuffer->_Ymax / fb_height * 2.0f - 1.0f;
-   float clearColor[4];
+   union pipe_color_union clearColor;
 
    /*
    printf("%s %s%s%s %f,%f %f,%f\n", __FUNCTION__, 
@@ -243,9 +218,10 @@ clear_with_quad(struct gl_context *ctx,
    cso_save_depth_stencil_alpha(st->cso_context);
    cso_save_rasterizer(st->cso_context);
    cso_save_viewport(st->cso_context);
-   cso_save_clip(st->cso_context);
    cso_save_fragment_shader(st->cso_context);
+   cso_save_stream_outputs(st->cso_context);
    cso_save_vertex_shader(st->cso_context);
+   cso_save_geometry_shader(st->cso_context);
    cso_save_vertex_elements(st->cso_context);
    cso_save_vertex_buffers(st->cso_context);
 
@@ -300,6 +276,7 @@ clear_with_quad(struct gl_context *ctx,
    }
 
    cso_set_vertex_elements(st->cso_context, 2, st->velems_util_draw);
+   cso_set_stream_outputs(st->cso_context, 0, NULL, 0);
 
    cso_set_rasterizer(st->cso_context, &st->clear.raster);
 
@@ -318,18 +295,18 @@ clear_with_quad(struct gl_context *ctx,
       cso_set_viewport(st->cso_context, &vp);
    }
 
-   cso_set_clip(st->cso_context, &st->clear.clip);
    set_fragment_shader(st);
    set_vertex_shader(st);
+   cso_set_geometry_shader_handle(st->cso_context, NULL);
 
    if (ctx->DrawBuffer->_ColorDrawBuffers[0]) {
-      st_translate_color(ctx->Color.ClearColorUnclamped,
-                         ctx->DrawBuffer->_ColorDrawBuffers[0]->_BaseFormat,
-                         clearColor);
+      st_translate_color(ctx->Color.ClearColor.f,
+                               ctx->DrawBuffer->_ColorDrawBuffers[0]->_BaseFormat,
+                               clearColor.f);
    }
 
    /* draw quad matching scissor rect */
-   draw_quad(st, x0, y0, x1, y1, (GLfloat) ctx->Depth.Clear, clearColor);
+   draw_quad(st, x0, y0, x1, y1, (GLfloat) ctx->Depth.Clear, &clearColor);
 
    /* Restore pipe state */
    cso_restore_blend(st->cso_context);
@@ -337,11 +314,12 @@ clear_with_quad(struct gl_context *ctx,
    cso_restore_depth_stencil_alpha(st->cso_context);
    cso_restore_rasterizer(st->cso_context);
    cso_restore_viewport(st->cso_context);
-   cso_restore_clip(st->cso_context);
    cso_restore_fragment_shader(st->cso_context);
    cso_restore_vertex_shader(st->cso_context);
+   cso_restore_geometry_shader(st->cso_context);
    cso_restore_vertex_elements(st->cso_context);
    cso_restore_vertex_buffers(st->cso_context);
+   cso_restore_stream_outputs(st->cso_context);
 }
 
 
@@ -379,10 +357,7 @@ check_clear_depth_stencil_with_quad(struct gl_context *ctx, struct gl_renderbuff
    GLboolean maskStencil
       = (ctx->Stencil.WriteMask[0] & stencilMax) != stencilMax;
 
-   assert(rb->Format == MESA_FORMAT_S8 ||
-          rb->Format == MESA_FORMAT_Z24_S8 ||
-          rb->Format == MESA_FORMAT_S8_Z24 ||
-          rb->Format == MESA_FORMAT_Z32_FLOAT_X24S8);
+   assert(_mesa_get_format_bits(rb->Format, GL_STENCIL_BITS) > 0);
 
    if (ctx->Scissor.Enabled &&
        (ctx->Scissor.X != 0 ||
@@ -435,10 +410,7 @@ check_clear_stencil_with_quad(struct gl_context *ctx, struct gl_renderbuffer *rb
    const GLboolean maskStencil
       = (ctx->Stencil.WriteMask[0] & stencilMax) != stencilMax;
 
-   assert(rb->Format == MESA_FORMAT_S8 ||
-          rb->Format == MESA_FORMAT_Z24_S8 ||
-          rb->Format == MESA_FORMAT_S8_Z24 ||
-          rb->Format == MESA_FORMAT_Z32_FLOAT_X24S8);
+   assert(_mesa_get_format_bits(rb->Format, GL_STENCIL_BITS) > 0);
 
    if (maskStencil) 
       return GL_TRUE;
@@ -462,22 +434,6 @@ check_clear_stencil_with_quad(struct gl_context *ctx, struct gl_renderbuffer *rb
 }
 
 
-
-/**
- * Called when we need to flush.
- */
-void
-st_flush_clear(struct st_context *st)
-{
-   /* Release vertex buffer to avoid synchronous rendering if we were
-    * to map it in the next frame.
-    */
-   pipe_resource_reference(&st->clear.vbuf, NULL);
-   st->clear.vbuf_slot = 0;
-}
-
-
 /**
  * Called via ctx->Driver.Clear()
  */
@@ -572,7 +528,7 @@ st_Clear(struct gl_context *ctx, GLbitfield mask)
        * required from the visual. Hence fix this up to avoid potential
        * read-modify-write in the driver.
        */
-      float clearColor[4];
+      union pipe_color_union clearColor;
 
       if ((clear_buffers & PIPE_CLEAR_DEPTHSTENCIL) &&
           ((clear_buffers & PIPE_CLEAR_DEPTHSTENCIL) != PIPE_CLEAR_DEPTHSTENCIL) &&
@@ -582,17 +538,16 @@ st_Clear(struct gl_context *ctx, GLbitfield mask)
          clear_buffers |= PIPE_CLEAR_DEPTHSTENCIL;
 
       if (ctx->DrawBuffer->_ColorDrawBuffers[0]) {
-         st_translate_color(ctx->Color.ClearColor,
-                            ctx->DrawBuffer->_ColorDrawBuffers[0]->_BaseFormat,
-                            clearColor);
+         st_translate_color(ctx->Color.ClearColor.f,
+                           ctx->DrawBuffer->_ColorDrawBuffers[0]->_BaseFormat,
+                           clearColor.f);
       }
 
-      st->pipe->clear(st->pipe, clear_buffers, ctx->Color.ClearColorUnclamped,
+      st->pipe->clear(st->pipe, clear_buffers, &clearColor,
                       ctx->Depth.Clear, ctx->Stencil.Clear);
    }
    if (mask & BUFFER_BIT_ACCUM)
-      st_clear_accum_buffer(ctx,
-                            ctx->DrawBuffer->Attachment[BUFFER_ACCUM].Renderbuffer);
+      _mesa_clear_accum_buffer(ctx);
 }