[Mesa-dev] [PATCH 1/2] st/mesa: adjust blending modes if we don't have destination alpha

Brian Paul brianp at vmware.com
Tue Apr 28 17:17:41 PDT 2015


On 04/28/2015 05:52 PM, Ilia Mirkin wrote:
> On Tue, Apr 28, 2015 at 7:52 PM, Brian Paul <brianp at vmware.com> wrote:
>> On 04/28/2015 04:35 PM, Ilia Mirkin wrote:
>>>
>>> On Tue, Apr 28, 2015 at 6:26 PM, Ilia Mirkin <imirkin at alum.mit.edu> wrote:
>>>>
>>>> Reviewed-by: Ilia Mirkin <imirkin at alum.mit.edu>
>>>
>>>
>>> aaaactually....
>>>
>>>>
>>>> Awesome! Now I can go remove this set of hacks from freedreno. And
>>>> this fixes the same issue in nouveau. Thanks for doing it the real way
>>>> :)
>>>>
>>>> On Tue, Apr 28, 2015 at 6:16 PM, Brian Paul <brianp at vmware.com> wrote:
>>>>>
>>>>> If the user requested a GL_RGB texture but the driver actually allocated
>>>>> an RGBA texture, the alpha values in the texture may not be defined.
>>>>>
>>>>> If we later bind the texture as a color target and try to blend into
>>>>> it with GL_DST_ALPHA or GL_ONE_MINUS_DST_ALPHA we may blend with
>>>>> undefined alpha values when, in fact, the dest alpha value should be
>>>>> one.
>>>>> So replace GL_DST_ALPHA/GL_ONE_MINUS_DST_ALPHA with GL_ONE/GL_ZERO.
>>>>>
>>>>> Fixes the piglit fbo-blending-formats test for some GL_RGB formats
>>>>> with the VMware driver.  Also tested with llvmpipe.
>>>>> ---
>>>>>    src/mesa/state_tracker/st_atom_blend.c | 38
>>>>> +++++++++++++++++++++++++---------
>>>>>    1 file changed, 28 insertions(+), 10 deletions(-)
>>>>>
>>>>> diff --git a/src/mesa/state_tracker/st_atom_blend.c
>>>>> b/src/mesa/state_tracker/st_atom_blend.c
>>>>> index 6bb4077..30bff7a 100644
>>>>> --- a/src/mesa/state_tracker/st_atom_blend.c
>>>>> +++ b/src/mesa/state_tracker/st_atom_blend.c
>>>>> @@ -44,10 +44,21 @@
>>>>>    /**
>>>>>     * Convert GLenum blend tokens to pipe tokens.
>>>>>     * Both blend factors and blend funcs are accepted.
>>>>> + * \param destBaseFormat  the base format of the render target, such as
>>>>> + *                        GL_RGBA, GL_RGB, GL_RED, GL_ALPHA, etc.
>>>>>     */
>>>>>    static GLuint
>>>>> -translate_blend(GLenum blend)
>>>>> +translate_blend(GLenum blend, GLenum destBaseFormat)
>>>>>    {
>>>>> +   /* If we don't have destination alpha and the blend factor is either
>>>>> +    * GL_DST_ALPHA or GL_ONE_MINUS_DST_ALPHA then we use
>>>>> +    * PIPE_BLENDFACTOR_ONE or _ZERO instead.
>>>>> +    */
>>>>> +   const bool haveDstA = (destBaseFormat == GL_RGBA ||
>>>>> +                          destBaseFormat == GL_ALPHA ||
>>>>> +                          destBaseFormat == GL_INTENSITY ||
>>>>> +                          destBaseFormat == GL_LUMINANCE_ALPHA);
>>>>> +
>>>>>       switch (blend) {
>>>>>       /* blend functions */
>>>>>       case GL_FUNC_ADD:
>>>>> @@ -69,7 +80,7 @@ translate_blend(GLenum blend)
>>>>>       case GL_SRC_ALPHA:
>>>>>          return PIPE_BLENDFACTOR_SRC_ALPHA;
>>>>>       case GL_DST_ALPHA:
>>>>> -      return PIPE_BLENDFACTOR_DST_ALPHA;
>>>>> +      return haveDstA ? PIPE_BLENDFACTOR_DST_ALPHA :
>>>>> PIPE_BLENDFACTOR_ONE;
>>>>>       case GL_DST_COLOR:
>>>>>          return PIPE_BLENDFACTOR_DST_COLOR;
>>>>>       case GL_SRC_ALPHA_SATURATE:
>>>>> @@ -91,7 +102,7 @@ translate_blend(GLenum blend)
>>>>>       case GL_ONE_MINUS_DST_COLOR:
>>>>>          return PIPE_BLENDFACTOR_INV_DST_COLOR;
>>>>>       case GL_ONE_MINUS_DST_ALPHA:
>>>>> -      return PIPE_BLENDFACTOR_INV_DST_ALPHA;
>>>>> +      return haveDstA ? PIPE_BLENDFACTOR_INV_DST_ALPHA :
>>>>> PIPE_BLENDFACTOR_ZERO;
>>>>>       case GL_ONE_MINUS_CONSTANT_COLOR:
>>>>>          return PIPE_BLENDFACTOR_INV_CONST_COLOR;
>>>>>       case GL_ONE_MINUS_CONSTANT_ALPHA:
>>>>> @@ -208,14 +219,21 @@ update_blend( struct st_context *st )
>>>>>       else if (ctx->Color.BlendEnabled) {
>>>>>          /* blending enabled */
>>>>>          for (i = 0, j = 0; i < num_state; i++) {
>>>>> +         const struct gl_renderbuffer *rb;
>>>>> +         GLenum baseFormat;
>>>>>
>>>>>             blend->rt[i].blend_enable = (ctx->Color.BlendEnabled >> i) &
>>>>> 0x1;
>>>>>
>>>>>             if (ctx->Extensions.ARB_draw_buffers_blend)
>>>>>                j = i;
>>>>>
>>>>> +         /* _NEW_BUFFERS */
>>>>> +         /* Get the base format of the render target */
>>>>> +         rb = ctx->DrawBuffer->_ColorDrawBuffers[j];
>>>
>>>
>>> That's the wrong render target, no? You need the i'th render target.
>>
>>
>> Ah, I think you're right.
>>
>> BTW, I think there's more i/j mix-ups in this code (independent of this
>> patch).  I'll send a separate patch for that after I check the specs.
>>
>>
>>> And what happens if I'm not using independent blend but one of the
>>> RT's is RGB while the other is RGBA?
>>
>>
>> Yeah, there's no simple fix for that, AFAIK.
>
> Well, presumably if the driver supports independent blend, you could
> turn that on? If the driver doesn't do independent blend, then you're
> SOL, but you should at least leave the DST_ALPHA setting alone...

If we have independent blend, the patch takes care of this.  I assumed 
you were asking about the RGBA+RGB case if we don't have independent 
blend.  I guess I'm not too concerned about that for now.  Off-hand, I 
doubt we have any piglit tests that really exercise mixed buffer 
formats.  And I don't have time to write them myself right now.

-Brian




More information about the mesa-dev mailing list