[Mesa-dev] [PATCH 06/31] mesa: don't update draw buffer bounds in _mesa_update_state

Marek Olšák maraeo at gmail.com
Mon Jun 12 16:55:31 UTC 2017


From: Marek Olšák <marek.olsak at amd.com>

st/mesa doesn't need the draw bounds for draw calls. I've added the call
where it's necessary in core Mesa and drivers, but I suspect that most
drivers can just move the call to the right places.

The core Mesa places aren't hot paths, so the call overhead doesn't matter
there.

For now, only st/mesa is made such that this function is invoked very
rarely.
---
 src/mesa/drivers/dri/i915/i915_context.c     | 4 ++++
 src/mesa/drivers/dri/i915/intel_context.c    | 3 +++
 src/mesa/drivers/dri/i965/brw_context.c      | 3 +++
 src/mesa/drivers/dri/nouveau/nouveau_state.c | 4 ++++
 src/mesa/drivers/dri/r200/r200_state.c       | 3 +++
 src/mesa/drivers/dri/radeon/radeon_state.c   | 3 +++
 src/mesa/drivers/dri/swrast/swrast.c         | 3 +++
 src/mesa/drivers/osmesa/osmesa.c             | 3 +++
 src/mesa/drivers/x11/xm_dd.c                 | 3 +++
 src/mesa/main/accum.c                        | 5 +++++
 src/mesa/main/state.c                        | 3 ---
 src/mesa/state_tracker/st_cb_clear.c         | 4 ++++
 src/mesa/state_tracker/st_cb_drawpixels.c    | 4 ++++
 13 files changed, 42 insertions(+), 3 deletions(-)

diff --git a/src/mesa/drivers/dri/i915/i915_context.c b/src/mesa/drivers/dri/i915/i915_context.c
index 4d89af1..4f6bdb7 100644
--- a/src/mesa/drivers/dri/i915/i915_context.c
+++ b/src/mesa/drivers/dri/i915/i915_context.c
@@ -20,20 +20,21 @@
  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
  * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  * 
  **************************************************************************/
 
 #include "i915_context.h"
 #include "main/api_exec.h"
+#include "main/framebuffer.h"
 #include "main/imports.h"
 #include "main/macros.h"
 #include "main/version.h"
 #include "main/vtxfmt.h"
 #include "intel_chipset.h"
 #include "intel_tris.h"
 #include "tnl/t_context.h"
 #include "tnl/t_pipeline.h"
 #include "tnl/t_vertex.h"
 
@@ -55,20 +56,23 @@ static void
 i915InvalidateState(struct gl_context * ctx)
 {
    GLuint new_state = ctx->NewState;
 
    _swrast_InvalidateState(ctx, new_state);
    _swsetup_InvalidateState(ctx, new_state);
    _tnl_InvalidateState(ctx, new_state);
    _tnl_invalidate_vertex_state(ctx, new_state);
    intel_context(ctx)->NewGLState |= new_state;
 
+   if (new_state & (_NEW_SCISSOR | _NEW_BUFFERS | _NEW_VIEWPORT))
+      _mesa_update_draw_buffer_bounds(ctx, ctx->DrawBuffer);
+
    /* Todo: gather state values under which tracked parameters become
     * invalidated, add callbacks for things like
     * ProgramLocalParameters, etc.
     */
    {
       struct i915_fragment_program *p =
          (struct i915_fragment_program *) ctx->FragmentProgram._Current;
       if (p && p->nr_params)
          p->params_uptodate = 0;
    }
diff --git a/src/mesa/drivers/dri/i915/intel_context.c b/src/mesa/drivers/dri/i915/intel_context.c
index 7f39245..e0766a0 100644
--- a/src/mesa/drivers/dri/i915/intel_context.c
+++ b/src/mesa/drivers/dri/i915/intel_context.c
@@ -317,20 +317,23 @@ static void
 intelInvalidateState(struct gl_context * ctx)
 {
    GLuint new_state = ctx->NewState;
     struct intel_context *intel = intel_context(ctx);
 
     if (ctx->swrast_context)
        _swrast_InvalidateState(ctx, new_state);
 
    intel->NewGLState |= new_state;
 
+   if (new_state & (_NEW_SCISSOR | _NEW_BUFFERS | _NEW_VIEWPORT))
+      _mesa_update_draw_buffer_bounds(ctx, ctx->DrawBuffer);
+
    if (intel->vtbl.invalidate_state)
       intel->vtbl.invalidate_state( intel, new_state );
 }
 
 void
 intel_flush_rendering_to_batch(struct gl_context *ctx)
 {
    struct intel_context *intel = intel_context(ctx);
 
    if (intel->Fallback)
diff --git a/src/mesa/drivers/dri/i965/brw_context.c b/src/mesa/drivers/dri/i965/brw_context.c
index 30ab2de..c059873 100644
--- a/src/mesa/drivers/dri/i965/brw_context.c
+++ b/src/mesa/drivers/dri/i965/brw_context.c
@@ -196,20 +196,23 @@ intel_update_state(struct gl_context * ctx)
    struct intel_texture_object *tex_obj;
    struct intel_renderbuffer *depth_irb;
 
    if (ctx->swrast_context)
       _swrast_InvalidateState(ctx, new_state);
 
    brw->NewGLState |= new_state;
 
    _mesa_unlock_context_textures(ctx);
 
+   if (new_state & (_NEW_SCISSOR | _NEW_BUFFERS | _NEW_VIEWPORT))
+      _mesa_update_draw_buffer_bounds(ctx, ctx->DrawBuffer);
+
    if (new_state & (_NEW_STENCIL | _NEW_BUFFERS)) {
       brw->stencil_enabled = _mesa_stencil_is_enabled(ctx);
       brw->stencil_two_sided = _mesa_stencil_is_two_sided(ctx);
       brw->stencil_write_enabled =
          _mesa_stencil_is_write_enabled(ctx, brw->stencil_two_sided);
    }
 
    if (new_state & _NEW_POLYGON)
       brw->polygon_front_bit = _mesa_polygon_get_front_bit(ctx);
 
diff --git a/src/mesa/drivers/dri/nouveau/nouveau_state.c b/src/mesa/drivers/dri/nouveau/nouveau_state.c
index 6d998fc..1aa26e9 100644
--- a/src/mesa/drivers/dri/nouveau/nouveau_state.c
+++ b/src/mesa/drivers/dri/nouveau/nouveau_state.c
@@ -25,20 +25,21 @@
  */
 
 #include "nouveau_driver.h"
 #include "nouveau_context.h"
 #include "nouveau_texture.h"
 #include "nouveau_util.h"
 
 #include "swrast/swrast.h"
 #include "tnl/tnl.h"
 #include "util/bitscan.h"
+#include "main/framebuffer.h"
 
 static void
 nouveau_alpha_func(struct gl_context *ctx, GLenum func, GLfloat ref)
 {
 	context_dirty(ctx, ALPHA_FUNC);
 }
 
 static void
 nouveau_blend_color(struct gl_context *ctx, const GLfloat color[4])
 {
@@ -449,20 +450,23 @@ nouveau_state_emit(struct gl_context *ctx)
 
 	BITSET_ZERO(nctx->dirty);
 }
 
 static void
 nouveau_update_state(struct gl_context *ctx)
 {
 	GLbitfield new_state = ctx->NewState;
 	int i;
 
+	if (new_state & (_NEW_SCISSOR | _NEW_BUFFERS | _NEW_VIEWPORT))
+		_mesa_update_draw_buffer_bounds(ctx, ctx->DrawBuffer);
+
 	if (new_state & (_NEW_PROJECTION | _NEW_MODELVIEW))
 		context_dirty(ctx, PROJECTION);
 
 	if (new_state & _NEW_MODELVIEW)
 		context_dirty(ctx, MODELVIEW);
 
 	if (new_state & _NEW_TEXTURE_MATRIX) {
 		for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++)
 			context_dirty_i(ctx, TEX_MAT, i);
 	}
diff --git a/src/mesa/drivers/dri/r200/r200_state.c b/src/mesa/drivers/dri/r200/r200_state.c
index 30437e3..b157572 100644
--- a/src/mesa/drivers/dri/r200/r200_state.c
+++ b/src/mesa/drivers/dri/r200/r200_state.c
@@ -2275,20 +2275,23 @@ GLboolean r200ValidateState( struct gl_context *ctx )
    return GL_TRUE;
 }
 
 
 static void r200InvalidateState(struct gl_context *ctx)
 {
    GLuint new_state = ctx->NewState;
 
    r200ContextPtr rmesa = R200_CONTEXT(ctx);
 
+   if (new_state & (_NEW_SCISSOR | _NEW_BUFFERS | _NEW_VIEWPORT))
+      _mesa_update_draw_buffer_bounds(ctx, ctx->DrawBuffer);
+
    _swrast_InvalidateState( ctx, new_state );
    _swsetup_InvalidateState( ctx, new_state );
    _tnl_InvalidateState( ctx, new_state );
    R200_CONTEXT(ctx)->radeon.NewGLState |= new_state;
 
    if (new_state & _NEW_PROGRAM)
       rmesa->curr_vp_hw = NULL;
 }
 
 /* A hack.  The r200 can actually cope just fine with materials
diff --git a/src/mesa/drivers/dri/radeon/radeon_state.c b/src/mesa/drivers/dri/radeon/radeon_state.c
index 940f8de..d2ca812 100644
--- a/src/mesa/drivers/dri/radeon/radeon_state.c
+++ b/src/mesa/drivers/dri/radeon/radeon_state.c
@@ -2041,20 +2041,23 @@ GLboolean radeonValidateState( struct gl_context *ctx )
    rmesa->radeon.NewGLState = 0;
 
    return GL_TRUE;
 }
 
 
 static void radeonInvalidateState(struct gl_context *ctx)
 {
    GLuint new_state = ctx->NewState;
 
+   if (new_state & (_NEW_SCISSOR | _NEW_BUFFERS | _NEW_VIEWPORT))
+      _mesa_update_draw_buffer_bounds(ctx, ctx->DrawBuffer);
+
    _swrast_InvalidateState( ctx, new_state );
    _swsetup_InvalidateState( ctx, new_state );
    _tnl_InvalidateState( ctx, new_state );
    R100_CONTEXT(ctx)->radeon.NewGLState |= new_state;
 }
 
 
 /* A hack.  Need a faster way to find this out.
  */
 static GLboolean check_material( struct gl_context *ctx )
diff --git a/src/mesa/drivers/dri/swrast/swrast.c b/src/mesa/drivers/dri/swrast/swrast.c
index 3b1de42..e66b225 100644
--- a/src/mesa/drivers/dri/swrast/swrast.c
+++ b/src/mesa/drivers/dri/swrast/swrast.c
@@ -694,20 +694,23 @@ get_string(struct gl_context *ctx, GLenum pname)
 	default:
 	    return NULL;
     }
 }
 
 static void
 update_state(struct gl_context *ctx)
 {
     GLuint new_state = ctx->NewState;
 
+    if (new_state & (_NEW_SCISSOR | _NEW_BUFFERS | _NEW_VIEWPORT))
+      _mesa_update_draw_buffer_bounds(ctx, ctx->DrawBuffer);
+
     /* not much to do here - pass it on */
     _swrast_InvalidateState( ctx, new_state );
     _swsetup_InvalidateState( ctx, new_state );
     _tnl_InvalidateState( ctx, new_state );
 }
 
 static void
 viewport(struct gl_context *ctx)
 {
     struct gl_framebuffer *draw = ctx->WinSysDrawBuffer;
diff --git a/src/mesa/drivers/osmesa/osmesa.c b/src/mesa/drivers/osmesa/osmesa.c
index c77dcc4..734a4e8 100644
--- a/src/mesa/drivers/osmesa/osmesa.c
+++ b/src/mesa/drivers/osmesa/osmesa.c
@@ -112,20 +112,23 @@ get_string( struct gl_context *ctx, GLenum name )
 #endif
       default:
          return NULL;
    }
 }
 
 
 static void
 osmesa_update_state(struct gl_context *ctx, GLuint new_state)
 {
+   if (new_state & (_NEW_SCISSOR | _NEW_BUFFERS | _NEW_VIEWPORT))
+      _mesa_update_draw_buffer_bounds(ctx, ctx->DrawBuffer);
+
    /* easy - just propogate */
    _swrast_InvalidateState( ctx, new_state );
    _swsetup_InvalidateState( ctx, new_state );
    _tnl_InvalidateState( ctx, new_state );
 }
 
 static void
 osmesa_update_state_wrapper(struct gl_context *ctx)
 {
    osmesa_update_state(ctx, ctx->NewState);
diff --git a/src/mesa/drivers/x11/xm_dd.c b/src/mesa/drivers/x11/xm_dd.c
index 61aa6c8..27534da 100644
--- a/src/mesa/drivers/x11/xm_dd.c
+++ b/src/mesa/drivers/x11/xm_dd.c
@@ -677,20 +677,23 @@ enable( struct gl_context *ctx, GLenum pname, GLboolean state )
 /**
  * Called when the driver should update its state, based on the new_state
  * flags.
  */
 static void
 xmesa_update_state(struct gl_context *ctx)
 {
    GLbitfield new_state = ctx->NewState;
    const XMesaContext xmesa = XMESA_CONTEXT(ctx);
 
+   if (new_state & (_NEW_SCISSOR | _NEW_BUFFERS | _NEW_VIEWPORT))
+      _mesa_update_draw_buffer_bounds(ctx, ctx->DrawBuffer);
+
    /* Propagate statechange information to swrast and swrast_setup
     * modules.  The X11 driver has no internal GL-dependent state.
     */
    _swrast_InvalidateState( ctx, new_state );
    _tnl_InvalidateState( ctx, new_state );
    _swsetup_InvalidateState( ctx, new_state );
 
    if (_mesa_is_user_fbo(ctx->DrawBuffer))
       return;
 
diff --git a/src/mesa/main/accum.c b/src/mesa/main/accum.c
index c0a3e7e..2b15b6e 100644
--- a/src/mesa/main/accum.c
+++ b/src/mesa/main/accum.c
@@ -21,20 +21,21 @@
  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  * OTHER DEALINGS IN THE SOFTWARE.
  */
 
 #include "glheader.h"
 #include "accum.h"
 #include "condrender.h"
 #include "context.h"
 #include "format_unpack.h"
 #include "format_pack.h"
+#include "framebuffer.h"
 #include "imports.h"
 #include "macros.h"
 #include "state.h"
 #include "mtypes.h"
 #include "main/dispatch.h"
 
 
 void GLAPIENTRY
 _mesa_ClearAccum( GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha )
 {
@@ -66,20 +67,22 @@ _mesa_clear_accum_buffer(struct gl_context *ctx)
    GLint accRowStride;
    struct gl_renderbuffer *accRb;
 
    if (!ctx->DrawBuffer)
       return;
 
    accRb = ctx->DrawBuffer->Attachment[BUFFER_ACCUM].Renderbuffer;
    if (!accRb)
       return;   /* missing accum buffer, not an error */
 
+   _mesa_update_draw_buffer_bounds(ctx, ctx->DrawBuffer);
+
    /* bounds, with scissor */
    x = ctx->DrawBuffer->_Xmin;
    y = ctx->DrawBuffer->_Ymin;
    width = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin;
    height = ctx->DrawBuffer->_Ymax - ctx->DrawBuffer->_Ymin;
 
    ctx->Driver.MapRenderbuffer(ctx, accRb, x, y, width, height,
                                GL_MAP_WRITE_BIT, &accMap, &accRowStride);
 
    if (!accMap) {
@@ -391,20 +394,22 @@ accum(struct gl_context *ctx, GLenum op, GLfloat value)
    GLint xpos, ypos, width, height;
 
    if (!ctx->DrawBuffer->Attachment[BUFFER_ACCUM].Renderbuffer) {
       _mesa_warning(ctx, "Calling glAccum() without an accumulation buffer");
       return;
    }
 
    if (!_mesa_check_conditional_render(ctx))
       return;
 
+   _mesa_update_draw_buffer_bounds(ctx, ctx->DrawBuffer);
+
    xpos = ctx->DrawBuffer->_Xmin;
    ypos = ctx->DrawBuffer->_Ymin;
    width =  ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin;
    height = ctx->DrawBuffer->_Ymax - ctx->DrawBuffer->_Ymin;
 
    switch (op) {
    case GL_ADD:
       if (value != 0.0F) {
          accum_scale_or_bias(ctx, value, xpos, ypos, width, height, GL_TRUE);
       }
diff --git a/src/mesa/main/state.c b/src/mesa/main/state.c
index 7972798..8df03f0 100644
--- a/src/mesa/main/state.c
+++ b/src/mesa/main/state.c
@@ -329,23 +329,20 @@ _mesa_update_state_locked( struct gl_context *ctx )
 
    if (new_state & _NEW_TEXTURE_MATRIX)
       _mesa_update_texture_matrices(ctx);
 
    if (new_state & (_NEW_TEXTURE_OBJECT | _NEW_TEXTURE_STATE | _NEW_PROGRAM))
       _mesa_update_texture_state(ctx);
 
    if (new_state & _NEW_BUFFERS)
       _mesa_update_framebuffer(ctx, ctx->ReadBuffer, ctx->DrawBuffer);
 
-   if (new_state & (_NEW_SCISSOR | _NEW_BUFFERS | _NEW_VIEWPORT))
-      _mesa_update_draw_buffer_bounds(ctx, ctx->DrawBuffer);
-
    if (new_state & _NEW_LIGHT)
       _mesa_update_lighting( ctx );
 
    if (new_state & _NEW_PIXEL)
       _mesa_update_pixel( ctx );
 
    /* ctx->_NeedEyeCoords is now up to date.
     *
     * If the truth value of this variable has changed, update for the
     * new lighting space and recompute the positions of lights and the
diff --git a/src/mesa/state_tracker/st_cb_clear.c b/src/mesa/state_tracker/st_cb_clear.c
index 175e2e8..cda9c71 100644
--- a/src/mesa/state_tracker/st_cb_clear.c
+++ b/src/mesa/state_tracker/st_cb_clear.c
@@ -29,20 +29,21 @@
  /*
   * Authors:
   *   Keith Whitwell <keithw at vmware.com>
   *   Brian Paul
   *   Michel Dänzer
   */
 
 #include "main/glheader.h"
 #include "main/accum.h"
 #include "main/formats.h"
+#include "main/framebuffer.h"
 #include "main/macros.h"
 #include "main/glformats.h"
 #include "program/prog_instruction.h"
 #include "st_context.h"
 #include "st_atom.h"
 #include "st_cb_bitmap.h"
 #include "st_cb_clear.h"
 #include "st_cb_fbo.h"
 #include "st_draw.h"
 #include "st_format.h"
@@ -172,20 +173,23 @@ set_vertex_shader_layered(struct st_context *st)
  * ctx->DrawBuffer->_X/Ymin/max fields.
  */
 static void
 clear_with_quad(struct gl_context *ctx, unsigned clear_buffers)
 {
    struct st_context *st = st_context(ctx);
    struct cso_context *cso = st->cso_context;
    const struct gl_framebuffer *fb = ctx->DrawBuffer;
    const GLfloat fb_width = (GLfloat) fb->Width;
    const GLfloat fb_height = (GLfloat) fb->Height;
+
+   _mesa_update_draw_buffer_bounds(ctx, ctx->DrawBuffer);
+
    const GLfloat x0 = (GLfloat) ctx->DrawBuffer->_Xmin / fb_width * 2.0f - 1.0f;
    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;
    unsigned num_layers = st->state.fb_num_layers;
 
    /*
    printf("%s %s%s%s %f,%f %f,%f\n", __func__,
 	  color ? "color, " : "",
 	  depth ? "depth, " : "",
diff --git a/src/mesa/state_tracker/st_cb_drawpixels.c b/src/mesa/state_tracker/st_cb_drawpixels.c
index 33d10f6..092b418 100644
--- a/src/mesa/state_tracker/st_cb_drawpixels.c
+++ b/src/mesa/state_tracker/st_cb_drawpixels.c
@@ -1065,20 +1065,22 @@ st_DrawPixels(struct gl_context *ctx, GLint x, GLint y,
    GLboolean write_stencil = GL_FALSE, write_depth = GL_FALSE;
    struct pipe_sampler_view *sv[2] = { NULL };
    int num_sampler_view = 1;
    struct gl_pixelstore_attrib clippedUnpack;
    struct st_fp_variant *fpv = NULL;
    struct pipe_resource *pt;
 
    /* Mesa state should be up to date by now */
    assert(ctx->NewState == 0x0);
 
+   _mesa_update_draw_buffer_bounds(ctx, ctx->DrawBuffer);
+
    st_flush_bitmap_cache(st);
    st_invalidate_readpix_cache(st);
 
    st_validate_state(st, ST_PIPELINE_RENDER);
 
    /* Limit the size of the glDrawPixels to the max texture size.
     * Strictly speaking, that's not correct but since we don't handle
     * larger images yet, this is better than crashing.
     */
    clippedUnpack = *unpack;
@@ -1430,20 +1432,22 @@ st_CopyPixels(struct gl_context *ctx, GLint srcx, GLint srcy,
    struct pipe_resource *pt;
    struct pipe_sampler_view *sv[2] = { NULL };
    struct st_fp_variant *fpv = NULL;
    int num_sampler_view = 1;
    enum pipe_format srcFormat;
    unsigned srcBind;
    GLboolean invertTex = GL_FALSE;
    GLint readX, readY, readW, readH;
    struct gl_pixelstore_attrib pack = ctx->DefaultPacking;
 
+   _mesa_update_draw_buffer_bounds(ctx, ctx->DrawBuffer);
+
    st_flush_bitmap_cache(st);
    st_invalidate_readpix_cache(st);
 
    st_validate_state(st, ST_PIPELINE_RENDER);
 
    if (type == GL_DEPTH_STENCIL) {
       /* XXX make this more efficient */
       st_CopyPixels(ctx, srcx, srcy, width, height, dstx, dsty, GL_STENCIL);
       st_CopyPixels(ctx, srcx, srcy, width, height, dstx, dsty, GL_DEPTH);
       return;
-- 
2.7.4



More information about the mesa-dev mailing list