[Mesa-dev] [PATCH 5/6] st/mesa: set correct PIPE_CLEAR_COLORn flags

Marek Olšák maraeo at gmail.com
Fri Dec 6 07:39:20 PST 2013


We can easily change the functions, so that they take pipe_box instead
of pipe_surface. It's not a problem. The state tracker or gallium/util
will have to provide a fallback path for compressed and
non-renderable formats anyway.

Marek

On Fri, Dec 6, 2013 at 2:29 PM, Roland Scheidegger <sroland at vmware.com> wrote:
> Oh I wasn't aware of that extension.
> It seems though those functions aren't quite ideally suited for that
> neither. First, they require surfaces, whereas the OpenGL extension is
> done specifically so the texture may be cleared even if the texture is
> non-renderable (hence surface creation may fail).
> Second, the functions do not allow to specify depth/zoffset currently as
> they always clear all attached layers.
> Those should be fixable though I guess.
>
> Roland
>
> Am 05.12.2013 23:02, schrieb Marek Olšák:
>> We'll probably use clear_render_target for GL_ARB_clear_texture (GL
>> 4.4), so it will be useful finally.
>>
>> Marek
>>
>> On Thu, Dec 5, 2013 at 10:49 PM, Roland Scheidegger <sroland at vmware.com> wrote:
>>> Am 05.12.2013 18:53, schrieb Marek Olšák:
>>>> From: Marek Olšák <marek.olsak at amd.com>
>>>>
>>>> This also fixes the clear_with_quad function for glClearBuffer.
>>>> ---
>>>>  src/mesa/state_tracker/st_cb_clear.c | 37 +++++++++++++++++++++++++-----------
>>>>  1 file changed, 26 insertions(+), 11 deletions(-)
>>>>
>>>> diff --git a/src/mesa/state_tracker/st_cb_clear.c b/src/mesa/state_tracker/st_cb_clear.c
>>>> index 5a7a00c..887e58b 100644
>>>> --- a/src/mesa/state_tracker/st_cb_clear.c
>>>> +++ b/src/mesa/state_tracker/st_cb_clear.c
>>>> @@ -213,8 +213,7 @@ draw_quad(struct st_context *st,
>>>>   * ctx->DrawBuffer->_X/Ymin/max fields.
>>>>   */
>>>>  static void
>>>> -clear_with_quad(struct gl_context *ctx,
>>>> -                GLboolean color, GLboolean depth, GLboolean stencil)
>>>> +clear_with_quad(struct gl_context *ctx, unsigned clear_buffers)
>>>>  {
>>>>     struct st_context *st = st_context(ctx);
>>>>     const struct gl_framebuffer *fb = ctx->DrawBuffer;
>>>> @@ -253,7 +252,7 @@ clear_with_quad(struct gl_context *ctx,
>>>>     {
>>>>        struct pipe_blend_state blend;
>>>>        memset(&blend, 0, sizeof(blend));
>>>> -      if (color) {
>>>> +      if (clear_buffers & PIPE_CLEAR_COLOR) {
>>>>           int num_buffers = ctx->Extensions.EXT_draw_buffers2 ?
>>>>                             ctx->DrawBuffer->_NumColorDrawBuffers : 1;
>>>>           int i;
>>>> @@ -261,6 +260,9 @@ clear_with_quad(struct gl_context *ctx,
>>>>           blend.independent_blend_enable = num_buffers > 1;
>>>>
>>>>           for (i = 0; i < num_buffers; i++) {
>>>> +            if (!(clear_buffers & (PIPE_CLEAR_COLOR0 << i)))
>>>> +               continue;
>>>> +
>>>>              if (ctx->Color.ColorMask[i][0])
>>>>                 blend.rt[i].colormask |= PIPE_MASK_R;
>>>>              if (ctx->Color.ColorMask[i][1])
>>>> @@ -281,13 +283,13 @@ clear_with_quad(struct gl_context *ctx,
>>>>     {
>>>>        struct pipe_depth_stencil_alpha_state depth_stencil;
>>>>        memset(&depth_stencil, 0, sizeof(depth_stencil));
>>>> -      if (depth) {
>>>> +      if (clear_buffers & PIPE_CLEAR_DEPTH) {
>>>>           depth_stencil.depth.enabled = 1;
>>>>           depth_stencil.depth.writemask = 1;
>>>>           depth_stencil.depth.func = PIPE_FUNC_ALWAYS;
>>>>        }
>>>>
>>>> -      if (stencil) {
>>>> +      if (clear_buffers & PIPE_CLEAR_STENCIL) {
>>>>           struct pipe_stencil_ref stencil_ref;
>>>>           memset(&stencil_ref, 0, sizeof(stencil_ref));
>>>>           depth_stencil.stencil[0].enabled = 1;
>>>> @@ -371,6 +373,19 @@ is_scissor_enabled(struct gl_context *ctx, struct gl_renderbuffer *rb)
>>>>
>>>>
>>>>  /**
>>>> + * Return if all of the color channels are masked.
>>>> + */
>>>> +static INLINE GLboolean
>>>> +is_color_disabled(struct gl_context *ctx, int i)
>>>> +{
>>>> +   return !ctx->Color.ColorMask[i][0] &&
>>>> +          !ctx->Color.ColorMask[i][1] &&
>>>> +          !ctx->Color.ColorMask[i][2] &&
>>>> +          !ctx->Color.ColorMask[i][3];
>>>> +}
>>> Technically you could also return true if not all channels are masked,
>>> as long as these channels don't exist in the rb. I guess though that gets
>>> a bit too complicated...
>>>
>>>
>>>> +
>>>> +/**
>>>>   * Return if any of the color channels are masked.
>>>>   */
>>>>  static INLINE GLboolean
>>>> @@ -427,11 +442,14 @@ st_Clear(struct gl_context *ctx, GLbitfield mask)
>>>>              if (!strb || !strb->surface)
>>>>                 continue;
>>>>
>>>> +            if (is_color_disabled(ctx, colormask_index))
>>>> +               continue;
>>>> +
>>>>              if (is_scissor_enabled(ctx, rb) ||
>>>>                  is_color_masked(ctx, colormask_index))
>>>> -               quad_buffers |= PIPE_CLEAR_COLOR;
>>>> +               quad_buffers |= PIPE_CLEAR_COLOR0 << i;
>>>>              else
>>>> -               clear_buffers |= PIPE_CLEAR_COLOR;
>>>> +               clear_buffers |= PIPE_CLEAR_COLOR0 << i;
>>>>           }
>>>>        }
>>>>     }
>>>> @@ -464,10 +482,7 @@ st_Clear(struct gl_context *ctx, GLbitfield mask)
>>>>      */
>>>>     if (quad_buffers) {
>>>>        quad_buffers |= clear_buffers;
>>>> -      clear_with_quad(ctx,
>>>> -                      quad_buffers & PIPE_CLEAR_COLOR,
>>>> -                      quad_buffers & PIPE_CLEAR_DEPTH,
>>>> -                      quad_buffers & PIPE_CLEAR_STENCIL);
>>>> +      clear_with_quad(ctx, quad_buffers);
>>>>     } else if (clear_buffers) {
>>>>        /* We can't translate the clear color to the colorbuffer format,
>>>>         * because different colorbuffers may have different formats.
>>>>
>>>
>>> Series makes sense to me if you don't want to use the
>>> clear_render_target() function for that instead. And I guess the latter
>>> hasn't many supporters...
>>>
>>> Roland


More information about the mesa-dev mailing list