[Mesa-dev] [PATCH 2/7] st/mesa: use pipe_blend_state::srgb_enable if the driver supports it

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


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

Some places need more changes because pipe_surface::format is never sRGB
now.
---
 src/mesa/state_tracker/st_atom.c             |  2 +-
 src/mesa/state_tracker/st_atom.h             |  7 ++++---
 src/mesa/state_tracker/st_atom_blend.c       |  3 +++
 src/mesa/state_tracker/st_atom_framebuffer.c | 11 +++++++++--
 src/mesa/state_tracker/st_atom_list.h        |  2 +-
 src/mesa/state_tracker/st_cb_blit.c          | 12 ++++++++++++
 src/mesa/state_tracker/st_cb_clear.c         |  3 +++
 src/mesa/state_tracker/st_cb_fbo.c           |  4 +++-
 src/mesa/state_tracker/st_context.c          |  8 +++++++-
 src/mesa/state_tracker/st_context.h          |  2 ++
 10 files changed, 45 insertions(+), 9 deletions(-)

diff --git a/src/mesa/state_tracker/st_atom.c b/src/mesa/state_tracker/st_atom.c
index bcfbcf8..52c781f 100644
--- a/src/mesa/state_tracker/st_atom.c
+++ b/src/mesa/state_tracker/st_atom.c
@@ -175,21 +175,21 @@ void st_validate_state( struct st_context *st, enum st_pipeline pipeline )
          st->gfx_shaders_may_be_dirty = false;
       }
 
       st_manager_validate_framebuffers(st);
 
       pipeline_mask = ST_PIPELINE_RENDER_STATE_MASK;
       break;
 
    case ST_PIPELINE_CLEAR:
       st_manager_validate_framebuffers(st);
-      pipeline_mask = ST_PIPELINE_CLEAR_STATE_MASK;
+      pipeline_mask = ST_PIPELINE_CLEAR_STATE_MASK(st);
       break;
 
    case ST_PIPELINE_UPDATE_FRAMEBUFFER:
       st_manager_validate_framebuffers(st);
       pipeline_mask = ST_PIPELINE_UPDATE_FB_STATE_MASK;
       break;
 
    case ST_PIPELINE_COMPUTE: {
       struct st_compute_program *old_cp = st->cp;
       struct gl_program *new_cp = ctx->ComputeProgram._Current;
diff --git a/src/mesa/state_tracker/st_atom.h b/src/mesa/state_tracker/st_atom.h
index 663bc06..1843d48 100644
--- a/src/mesa/state_tracker/st_atom.h
+++ b/src/mesa/state_tracker/st_atom.h
@@ -139,20 +139,21 @@ enum {
                                  ST_NEW_SAMPLERS | \
                                  ST_NEW_CONSTANTS | \
                                  ST_NEW_UNIFORM_BUFFER | \
                                  ST_NEW_ATOMIC_BUFFER | \
                                  ST_NEW_STORAGE_BUFFER | \
                                  ST_NEW_IMAGE_UNITS)
 
 /* All state flags within each group: */
 #define ST_PIPELINE_RENDER_STATE_MASK  (ST_NEW_CS_STATE - 1)
 #define ST_PIPELINE_COMPUTE_STATE_MASK (0xffllu << ST_NEW_CS_STATE_INDEX)
-#define ST_PIPELINE_CLEAR_STATE_MASK (ST_NEW_FB_STATE | \
-                                      ST_NEW_SCISSOR | \
-                                      ST_NEW_WINDOW_RECTANGLES)
+#define ST_PIPELINE_CLEAR_STATE_MASK(st) (ST_NEW_FB_STATE | \
+                                          (st->has_srgb_enable ? ST_NEW_BLEND : 0) | \
+                                          ST_NEW_SCISSOR | \
+                                          ST_NEW_WINDOW_RECTANGLES)
 /* For ReadPixels, ReadBuffer, GetSamplePosition: */
 #define ST_PIPELINE_UPDATE_FB_STATE_MASK (ST_NEW_FB_STATE)
 
 #define ST_ALL_STATES_MASK (ST_PIPELINE_RENDER_STATE_MASK | \
                             ST_PIPELINE_COMPUTE_STATE_MASK)
 
 #endif
diff --git a/src/mesa/state_tracker/st_atom_blend.c b/src/mesa/state_tracker/st_atom_blend.c
index 7428997..85edf05 100644
--- a/src/mesa/state_tracker/st_atom_blend.c
+++ b/src/mesa/state_tracker/st_atom_blend.c
@@ -268,18 +268,21 @@ st_update_blend( struct st_context *st )
    if (ctx->Multisample.Enabled &&
        ctx->DrawBuffer->Visual.sampleBuffers > 0 &&
        !(ctx->DrawBuffer->_IntegerBuffers & 0x1)) {
       /* Unlike in gallium/d3d10 these operations are only performed
        * if both msaa is enabled and we have a multisample buffer.
        */
       blend->alpha_to_coverage = ctx->Multisample.SampleAlphaToCoverage;
       blend->alpha_to_one = ctx->Multisample.SampleAlphaToOne;
    }
 
+   if (st->has_srgb_enable && ctx->Color.sRGBEnabled)
+      blend->srgb_enable = st->state.fb_srgb_buffers;
+
    cso_set_blend(st->cso_context, blend);
 
    {
       struct pipe_blend_color bc;
       COPY_4FV(bc.color, ctx->Color.BlendColorUnclamped);
       cso_set_blend_color(st->cso_context, &bc);
    }
 }
diff --git a/src/mesa/state_tracker/st_atom_framebuffer.c b/src/mesa/state_tracker/st_atom_framebuffer.c
index acbe980..e08cac1 100644
--- a/src/mesa/state_tracker/st_atom_framebuffer.c
+++ b/src/mesa/state_tracker/st_atom_framebuffer.c
@@ -110,20 +110,21 @@ st_update_framebuffer_state( struct st_context *st )
 {
    struct pipe_framebuffer_state framebuffer;
    struct gl_framebuffer *fb = st->ctx->DrawBuffer;
    struct st_renderbuffer *strb;
    GLuint i;
 
    st_flush_bitmap_cache(st);
    st_invalidate_readpix_cache(st);
 
    st->state.fb_orientation = st_fb_orientation(fb);
+   st->state.fb_srgb_buffers = 0;
 
    /**
     * Quantize the derived default number of samples:
     *
     * A query to the driver of supported MSAA values the
     * hardware supports is done as to legalize the number
     * of application requested samples, NumSamples.
     * See commit eb9cf3c for more information.
     */
    fb->DefaultGeometry._NumSamples =
@@ -137,27 +138,33 @@ st_update_framebuffer_state( struct st_context *st )
    /* Examine Mesa's ctx->DrawBuffer->_ColorDrawBuffers state
     * to determine which surfaces to draw to
     */
    framebuffer.nr_cbufs = fb->_NumColorDrawBuffers;
 
    for (i = 0; i < fb->_NumColorDrawBuffers; i++) {
       framebuffer.cbufs[i] = NULL;
       strb = st_renderbuffer(fb->_ColorDrawBuffers[i]);
 
       if (strb) {
-         if (strb->is_rtt || (strb->texture &&
-             _mesa_get_format_color_encoding(strb->Base.Format) == GL_SRGB)) {
+         bool is_srgb =
+            _mesa_get_format_color_encoding(strb->Base.Format) == GL_SRGB;
+
+         if (strb->is_rtt ||
+             (strb->texture && !st->has_srgb_enable && is_srgb)) {
             /* rendering to a GL texture, may have to update surface */
             st_update_renderbuffer_surface(st, strb);
          }
 
          if (strb->surface) {
+            if (is_srgb)
+               st->state.fb_srgb_buffers |= 1 << i;
+
             framebuffer.cbufs[i] = strb->surface;
             update_framebuffer_size(&framebuffer, strb->surface);
          }
          strb->defined = GL_TRUE; /* we'll be drawing something */
       }
    }
 
    for (i = framebuffer.nr_cbufs; i < PIPE_MAX_COLOR_BUFS; i++) {
       framebuffer.cbufs[i] = NULL;
    }
diff --git a/src/mesa/state_tracker/st_atom_list.h b/src/mesa/state_tracker/st_atom_list.h
index 614ee90..ed20a32 100644
--- a/src/mesa/state_tracker/st_atom_list.h
+++ b/src/mesa/state_tracker/st_atom_list.h
@@ -6,21 +6,20 @@ 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_RASTERIZER, st_update_rasterizer)
 ST_STATE(ST_NEW_POLY_STIPPLE, st_update_polygon_stipple)
 ST_STATE(ST_NEW_VIEWPORT, st_update_viewport)
 ST_STATE(ST_NEW_SCISSOR, st_update_scissor)
 ST_STATE(ST_NEW_WINDOW_RECTANGLES, st_update_window_rectangles)
-ST_STATE(ST_NEW_BLEND, st_update_blend)
 
 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 */
 ST_STATE(ST_NEW_TCS_SAMPLERS, st_update_tessctrl_samplers) /* depends on update_*_texture for swizzle */
@@ -30,20 +29,21 @@ ST_STATE(ST_NEW_FS_SAMPLERS, st_update_fragment_samplers) /* depends on update_*
 
 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_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_BLEND, st_update_blend) /* 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)
 ST_STATE(ST_NEW_FS_CONSTANTS, st_update_fs_constants)
 
 ST_STATE(ST_NEW_VS_UBOS, st_bind_vs_ubos)
 ST_STATE(ST_NEW_TCS_UBOS, st_bind_tcs_ubos)
 ST_STATE(ST_NEW_TES_UBOS, st_bind_tes_ubos)
diff --git a/src/mesa/state_tracker/st_cb_blit.c b/src/mesa/state_tracker/st_cb_blit.c
index 8aa849b..92e404f 100644
--- a/src/mesa/state_tracker/st_cb_blit.c
+++ b/src/mesa/state_tracker/st_cb_blit.c
@@ -200,20 +200,24 @@ st_BlitFramebuffer(struct gl_context *ctx,
                   blit.dst.resource = dstSurf->texture;
                   blit.dst.level = dstSurf->u.tex.level;
                   blit.dst.box.z = dstSurf->u.tex.first_layer;
                   blit.dst.format = dstSurf->format;
 
                   blit.src.resource = srcObj->pt;
                   blit.src.level = srcAtt->TextureLevel;
                   blit.src.box.z = srcAtt->Zoffset + srcAtt->CubeMapFace;
                   blit.src.format = srcObj->pt->format;
 
+                  if (ctx->Color.sRGBEnabled &&
+                      _mesa_get_format_color_encoding(dstRb->Base.Format) == GL_SRGB)
+                     blit.dst.format = util_format_srgb(blit.dst.format);
+
                   if (!ctx->Color.sRGBEnabled)
                      blit.src.format = util_format_linear(blit.src.format);
 
                   st->pipe->blit(st->pipe, &blit);
                   dstRb->defined = true; /* front buffer tracking */
                }
             }
          }
       }
       else {
@@ -247,20 +251,28 @@ st_BlitFramebuffer(struct gl_context *ctx,
                   blit.dst.resource = dstSurf->texture;
                   blit.dst.level = dstSurf->u.tex.level;
                   blit.dst.box.z = dstSurf->u.tex.first_layer;
                   blit.dst.format = dstSurf->format;
 
                   blit.src.resource = srcSurf->texture;
                   blit.src.level = srcSurf->u.tex.level;
                   blit.src.box.z = srcSurf->u.tex.first_layer;
                   blit.src.format = srcSurf->format;
 
+                  if (ctx->Color.sRGBEnabled) {
+                     if (_mesa_get_format_color_encoding(dstRb->Base.Format) == GL_SRGB)
+                        blit.dst.format = util_format_srgb(blit.dst.format);
+
+                     if (_mesa_get_format_color_encoding(srcRb->Base.Format) == GL_SRGB)
+                        blit.src.format = util_format_srgb(blit.src.format);
+                  }
+
                   st->pipe->blit(st->pipe, &blit);
                   dstRb->defined = true; /* front buffer tracking */
                }
             }
          }
       }
    }
 
    if (mask & depthStencil) {
       /* depth and/or stencil blit */
diff --git a/src/mesa/state_tracker/st_cb_clear.c b/src/mesa/state_tracker/st_cb_clear.c
index cda9c71..89c7452 100644
--- a/src/mesa/state_tracker/st_cb_clear.c
+++ b/src/mesa/state_tracker/st_cb_clear.c
@@ -231,20 +231,23 @@ clear_with_quad(struct gl_context *ctx, unsigned clear_buffers)
             if (ctx->Color.ColorMask[i][1])
                blend.rt[i].colormask |= PIPE_MASK_G;
             if (ctx->Color.ColorMask[i][2])
                blend.rt[i].colormask |= PIPE_MASK_B;
             if (ctx->Color.ColorMask[i][3])
                blend.rt[i].colormask |= PIPE_MASK_A;
          }
 
          if (ctx->Color.DitherFlag)
             blend.dither = 1;
+
+         if (st->has_srgb_enable && ctx->Color.sRGBEnabled)
+            blend.srgb_enable = st->state.fb_srgb_buffers;
       }
       cso_set_blend(cso, &blend);
    }
 
    /* depth_stencil state: always pass/set to ref value */
    {
       struct pipe_depth_stencil_alpha_state depth_stencil;
       memset(&depth_stencil, 0, sizeof(depth_stencil));
       if (clear_buffers & PIPE_CLEAR_DEPTH) {
          depth_stencil.depth.enabled = 1;
diff --git a/src/mesa/state_tracker/st_cb_fbo.c b/src/mesa/state_tracker/st_cb_fbo.c
index 2559c23..1d30a25 100644
--- a/src/mesa/state_tracker/st_cb_fbo.c
+++ b/src/mesa/state_tracker/st_cb_fbo.c
@@ -384,21 +384,23 @@ st_update_renderbuffer_surface(struct st_context *st,
    unsigned rtt_width = strb->Base.Width;
    unsigned rtt_height = strb->Base.Height;
    unsigned rtt_depth = strb->Base.Depth;
 
    /*
     * For winsys fbo, it is possible that the renderbuffer is sRGB-capable but
     * the format of strb->texture is linear (because we have no control over
     * the format).  Check strb->Base.Format instead of strb->texture->format
     * to determine if the rb is sRGB-capable.
     */
-   boolean enable_srgb = st->ctx->Color.sRGBEnabled &&
+   boolean enable_srgb =
+      !st->has_srgb_enable &&
+      st->ctx->Color.sRGBEnabled &&
       _mesa_get_format_color_encoding(strb->Base.Format) == GL_SRGB;
    enum pipe_format format = resource->format;
 
    if (strb->is_rtt) {
       stTexObj = st_texture_object(strb->Base.TexImage->TexObject);
       if (stTexObj->surface_based)
          format = stTexObj->surface_format;
    }
 
    format = enable_srgb ? util_format_srgb(format) : util_format_linear(format);
diff --git a/src/mesa/state_tracker/st_context.c b/src/mesa/state_tracker/st_context.c
index a81b2c2..cbc39b1 100644
--- a/src/mesa/state_tracker/st_context.c
+++ b/src/mesa/state_tracker/st_context.c
@@ -301,20 +301,22 @@ st_create_context_priv( struct gl_context *ctx, struct pipe_context *pipe,
 
    /* state tracker needs the VBO module */
    _vbo_CreateContext(ctx);
 
    st->dirty = ST_ALL_STATES_MASK;
 
    st->has_user_constbuf =
       screen->get_param(screen, PIPE_CAP_USER_CONSTANT_BUFFERS);
    st->can_bind_const_buffer_as_vertex =
       screen->get_param(screen, PIPE_CAP_CAN_BIND_CONST_BUFFER_AS_VERTEX);
+   st->has_srgb_enable =
+      screen->get_param(screen, PIPE_CAP_BLEND_STATE_SRGB_ENABLE);
 
    /* Drivers still have to upload zero-stride vertex attribs manually
     * with the GL core profile, but they don't have to deal with any complex
     * user vertex buffer uploads.
     */
    unsigned vbuf_flags =
       ctx->API == API_OPENGL_CORE ? U_VBUF_FLAG_NO_USER_VBOS : 0;
    st->cso_context = cso_create_context(pipe, vbuf_flags);
 
    st_init_atoms( st );
@@ -488,22 +490,26 @@ static void st_init_driver_flags(struct st_context *st)
    f->NewShaderStorageBuffer = ST_NEW_STORAGE_BUFFER;
    f->NewImageUnits = ST_NEW_IMAGE_UNITS;
 
    f->NewShaderConstants[MESA_SHADER_VERTEX] = ST_NEW_VS_CONSTANTS;
    f->NewShaderConstants[MESA_SHADER_TESS_CTRL] = ST_NEW_TCS_CONSTANTS;
    f->NewShaderConstants[MESA_SHADER_TESS_EVAL] = ST_NEW_TES_CONSTANTS;
    f->NewShaderConstants[MESA_SHADER_GEOMETRY] = ST_NEW_GS_CONSTANTS;
    f->NewShaderConstants[MESA_SHADER_FRAGMENT] = ST_NEW_FS_CONSTANTS;
    f->NewShaderConstants[MESA_SHADER_COMPUTE] = ST_NEW_CS_CONSTANTS;
 
+   if (st->has_srgb_enable)
+      f->NewFramebufferSRGB = ST_NEW_BLEND;
+   else
+      f->NewFramebufferSRGB = ST_NEW_FRAMEBUFFER;
+
    f->NewWindowRectangles = ST_NEW_WINDOW_RECTANGLES;
-   f->NewFramebufferSRGB = ST_NEW_FRAMEBUFFER;
    f->NewScissorRect = ST_NEW_SCISSOR;
    f->NewScissorTest = ST_NEW_SCISSOR | ST_NEW_RASTERIZER;
    f->NewAlphaTest = ST_NEW_DSA;
    f->NewBlend = ST_NEW_BLEND;
    f->NewBlendColor = ST_NEW_BLEND; /* TODO: add an atom for blend color */
    f->NewColorMask = ST_NEW_BLEND;
    f->NewDepth = ST_NEW_DSA;
    f->NewLogicOp = ST_NEW_BLEND;
    f->NewStencil = ST_NEW_DSA;
    f->NewMultisampleEnable = ST_NEW_BLEND | ST_NEW_RASTERIZER |
diff --git a/src/mesa/state_tracker/st_context.h b/src/mesa/state_tracker/st_context.h
index cd70bf9..dc3f4c0 100644
--- a/src/mesa/state_tracker/st_context.h
+++ b/src/mesa/state_tracker/st_context.h
@@ -98,20 +98,21 @@ struct st_context
    boolean has_shader_model3;
    boolean has_etc1;
    boolean has_etc2;
    boolean prefer_blit_based_texture_transfer;
    boolean force_persample_in_shader;
    boolean has_shareable_shaders;
    boolean has_half_float_packing;
    boolean has_multi_draw_indirect;
    boolean has_user_constbuf;
    boolean can_bind_const_buffer_as_vertex;
+   boolean has_srgb_enable;
 
    /**
     * If a shader can be created when we get its source.
     * This means it has only 1 variant, not counting glBitmap and
     * glDrawPixels.
     */
    boolean shader_has_one_variant[MESA_SHADER_STAGES];
 
    boolean needs_texcoord_semantic;
    boolean apply_texture_swizzle_to_border_color;
@@ -136,20 +137,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;
+      ubyte fb_srgb_buffers;
       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;
       unsigned sample_mask;
 
       GLuint poly_stipple[32];  /**< In OpenGL's bottom-to-top order */
-- 
2.7.4



More information about the mesa-dev mailing list