[Mesa-dev] [PATCH 3/3] st/mesa: generate blend state according to the number of enabled color buffers

Marek Olšák maraeo at gmail.com
Thu Feb 8 15:17:29 UTC 2018


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

Non-MRT cases always translate blend state for 1 color buffer only.
MRT cases only check and translate blend state for enabled color buffers.

This also avoids an assertion failure in translate_blend for:
  dEQP-GLES31.functional.draw_buffers_indexed.overwrite_common.common_advanced_blend_eq_buffer_blend_eq
---
 src/mesa/state_tracker/st_atom_blend.c       | 21 +++++++++++++--------
 src/mesa/state_tracker/st_atom_framebuffer.c |  1 +
 src/mesa/state_tracker/st_atom_list.h        |  2 +-
 src/mesa/state_tracker/st_context.h          |  1 +
 4 files changed, 16 insertions(+), 9 deletions(-)

diff --git a/src/mesa/state_tracker/st_atom_blend.c b/src/mesa/state_tracker/st_atom_blend.c
index 2a8da75..57400e2 100644
--- a/src/mesa/state_tracker/st_atom_blend.c
+++ b/src/mesa/state_tracker/st_atom_blend.c
@@ -105,59 +105,64 @@ translate_blend(GLenum blend)
    default:
       assert("invalid GL token in translate_blend()" == NULL);
       return 0;
    }
 }
 
 /**
  * Figure out if colormasks are different per rt.
  */
 static GLboolean
-colormask_per_rt(const struct gl_context *ctx)
+colormask_per_rt(const struct gl_context *ctx, unsigned num_cb)
 {
+   GLbitfield full_mask = _mesa_replicate_colormask(0xf, num_cb);
    GLbitfield repl_mask0 =
       _mesa_replicate_colormask(GET_COLORMASK(ctx->Color.ColorMask, 0),
-                                ctx->Const.MaxDrawBuffers);
+                                num_cb);
 
-   return ctx->Color.ColorMask != repl_mask0;
+   return (ctx->Color.ColorMask & full_mask) != repl_mask0;
 }
 
 /**
  * Figure out if blend enables/state are different per rt.
  */
 static GLboolean
-blend_per_rt(const struct gl_context *ctx)
+blend_per_rt(const struct gl_context *ctx, unsigned num_cb)
 {
-   if (ctx->Color.BlendEnabled &&
-      (ctx->Color.BlendEnabled != ((1U << ctx->Const.MaxDrawBuffers) - 1))) {
+   GLbitfield cb_mask = u_bit_consecutive(0, num_cb);
+   GLbitfield blend_enabled = ctx->Color.BlendEnabled & cb_mask;
+
+   if (blend_enabled && blend_enabled != cb_mask) {
       /* This can only happen if GL_EXT_draw_buffers2 is enabled */
       return GL_TRUE;
    }
    if (ctx->Color._BlendFuncPerBuffer || ctx->Color._BlendEquationPerBuffer) {
       /* this can only happen if GL_ARB_draw_buffers_blend is enabled */
       return GL_TRUE;
    }
    return GL_FALSE;
 }
 
 void
 st_update_blend( struct st_context *st )
 {
    struct pipe_blend_state *blend = &st->state.blend;
    const struct gl_context *ctx = st->ctx;
+   unsigned num_cb = st->state.fb_num_cb;
    unsigned num_state = 1;
    unsigned i, j;
 
    memset(blend, 0, sizeof(*blend));
 
-   if (blend_per_rt(ctx) || colormask_per_rt(ctx)) {
-      num_state = ctx->Const.MaxDrawBuffers;
+   if (num_cb > 1 &&
+       (blend_per_rt(ctx, num_cb) || colormask_per_rt(ctx, num_cb))) {
+      num_state = num_cb;
       blend->independent_blend_enable = 1;
    }
 
    for (i = 0; i < num_state; i++)
       blend->rt[i].colormask = GET_COLORMASK(ctx->Color.ColorMask, i);
 
    if (ctx->Color.ColorLogicOpEnabled) {
       /* logicop enabled */
       blend->logicop_enable = 1;
       blend->logicop_func = ctx->Color._LogicOp;
diff --git a/src/mesa/state_tracker/st_atom_framebuffer.c b/src/mesa/state_tracker/st_atom_framebuffer.c
index acbe980..a29f5b3 100644
--- a/src/mesa/state_tracker/st_atom_framebuffer.c
+++ b/src/mesa/state_tracker/st_atom_framebuffer.c
@@ -209,11 +209,12 @@ st_update_framebuffer_state( struct st_context *st )
       framebuffer.width = 0;
    if (framebuffer.height == USHRT_MAX)
       framebuffer.height = 0;
 
    cso_set_framebuffer(st->cso_context, &framebuffer);
 
    st->state.fb_width = framebuffer.width;
    st->state.fb_height = framebuffer.height;
    st->state.fb_num_samples = util_framebuffer_get_num_samples(&framebuffer);
    st->state.fb_num_layers = util_framebuffer_get_num_layers(&framebuffer);
+   st->state.fb_num_cb = framebuffer.nr_cbufs;
 }
diff --git a/src/mesa/state_tracker/st_atom_list.h b/src/mesa/state_tracker/st_atom_list.h
index 8f50a72..5391d47 100644
--- a/src/mesa/state_tracker/st_atom_list.h
+++ b/src/mesa/state_tracker/st_atom_list.h
@@ -3,21 +3,20 @@ ST_STATE(ST_NEW_DSA, st_update_depth_stencil_alpha)
 ST_STATE(ST_NEW_CLIP_STATE, st_update_clip)
 
 ST_STATE(ST_NEW_FS_STATE, st_update_fp)
 ST_STATE(ST_NEW_GS_STATE, st_update_gp)
 ST_STATE(ST_NEW_TES_STATE, st_update_tep)
 ST_STATE(ST_NEW_TCS_STATE, st_update_tcp)
 ST_STATE(ST_NEW_VS_STATE, st_update_vp)
 
 ST_STATE(ST_NEW_POLY_STIPPLE, st_update_polygon_stipple)
 ST_STATE(ST_NEW_WINDOW_RECTANGLES, st_update_window_rectangles)
-ST_STATE(ST_NEW_BLEND, st_update_blend)
 ST_STATE(ST_NEW_BLEND_COLOR, st_update_blend_color)
 
 ST_STATE(ST_NEW_VS_SAMPLER_VIEWS, st_update_vertex_textures)
 ST_STATE(ST_NEW_FS_SAMPLER_VIEWS, st_update_fragment_textures)
 ST_STATE(ST_NEW_GS_SAMPLER_VIEWS, st_update_geometry_textures)
 ST_STATE(ST_NEW_TCS_SAMPLER_VIEWS, st_update_tessctrl_textures)
 ST_STATE(ST_NEW_TES_SAMPLER_VIEWS, st_update_tesseval_textures)
 
 /* Non-compute samplers. */
 ST_STATE(ST_NEW_VS_SAMPLERS, st_update_vertex_samplers) /* depends on update_*_texture for swizzle */
@@ -26,20 +25,21 @@ ST_STATE(ST_NEW_TES_SAMPLERS, st_update_tesseval_samplers) /* depends on update_
 ST_STATE(ST_NEW_GS_SAMPLERS, st_update_geometry_samplers) /* depends on update_*_texture for swizzle */
 ST_STATE(ST_NEW_FS_SAMPLERS, st_update_fragment_samplers) /* depends on update_*_texture for swizzle */
 
 ST_STATE(ST_NEW_VS_IMAGES, st_bind_vs_images)
 ST_STATE(ST_NEW_TCS_IMAGES, st_bind_tcs_images)
 ST_STATE(ST_NEW_TES_IMAGES, st_bind_tes_images)
 ST_STATE(ST_NEW_GS_IMAGES, st_bind_gs_images)
 ST_STATE(ST_NEW_FS_IMAGES, st_bind_fs_images)
 
 ST_STATE(ST_NEW_FB_STATE, st_update_framebuffer_state) /* depends on update_*_texture and bind_*_images */
+ST_STATE(ST_NEW_BLEND, st_update_blend) /* depends on update_framebuffer_state */
 ST_STATE(ST_NEW_RASTERIZER, st_update_rasterizer) /* depends on update_framebuffer_state */
 ST_STATE(ST_NEW_SAMPLE_MASK, st_update_sample_mask) /* depends on update_framebuffer_state */
 ST_STATE(ST_NEW_SAMPLE_SHADING, st_update_sample_shading)
 ST_STATE(ST_NEW_SCISSOR, st_update_scissor) /* depends on update_framebuffer_state */
 ST_STATE(ST_NEW_VIEWPORT, st_update_viewport) /* depends on update_framebuffer_state */
 
 ST_STATE(ST_NEW_VS_CONSTANTS, st_update_vs_constants)
 ST_STATE(ST_NEW_TCS_CONSTANTS, st_update_tcs_constants)
 ST_STATE(ST_NEW_TES_CONSTANTS, st_update_tes_constants)
 ST_STATE(ST_NEW_GS_CONSTANTS, st_update_gs_constants)
diff --git a/src/mesa/state_tracker/st_context.h b/src/mesa/state_tracker/st_context.h
index 660c993..9f2480e 100644
--- a/src/mesa/state_tracker/st_context.h
+++ b/src/mesa/state_tracker/st_context.h
@@ -157,20 +157,21 @@ struct st_context
       GLuint num_sampler_views[PIPE_SHADER_TYPES];
       struct pipe_clip_state clip;
       struct {
          void *ptr;
          unsigned size;
       } constants[PIPE_SHADER_TYPES];
       unsigned fb_width;
       unsigned fb_height;
       unsigned fb_num_samples;
       unsigned fb_num_layers;
+      unsigned fb_num_cb;
       unsigned num_viewports;
       struct pipe_scissor_state scissor[PIPE_MAX_VIEWPORTS];
       struct pipe_viewport_state viewport[PIPE_MAX_VIEWPORTS];
       struct {
          unsigned num;
          boolean include;
          struct pipe_scissor_state rects[PIPE_MAX_WINDOW_RECTANGLES];
       } window_rects;
 
       GLuint poly_stipple[32];  /**< In OpenGL's bottom-to-top order */
-- 
2.7.4



More information about the mesa-dev mailing list