KhronosGroup / VK-GL-CTS

Khronos Vulkan, OpenGL, and OpenGL ES Conformance Tests
https://www.khronos.org/
Apache License 2.0
521 stars 290 forks source link

There is no clamp in blend factor in referencerenderer #454

Closed helloyi closed 3 months ago

helloyi commented 4 months ago

The Spec

The vulkan Specification clearly states that we should clamp the fixed-point(such as VK_FORMAT_R8_SNORM) blend factor.

Vulkan® 1.1.284 - A Specification: 27.1.3. Blend Operations

If the color attachment is fixed-point, the components of the source and destination values and blend factors are each clamped to [0,1] or [-1,1] respectively for an unsigned normalized or signed normalized color attachment prior to evaluating the blend operations. If the color attachment is floating-point, no clamping occurs.

Mesa3d blend factor clamp

The processing of mesa3d should confirm this. https://gitlab.freedesktop.org/mesa/mesa/-/blob/main/src/compiler/nir/nir_lower_blend.c?ref_type=heads#L216

static nir_def *
nir_blend_factor(
   nir_builder *b,
   nir_def *raw_scalar,
   nir_def *src, nir_def *src1, nir_def *dst, nir_def *bconst,
   unsigned chan,
   enum pipe_blendfactor factor,
   enum pipe_format format)
{
   nir_def *f =
      nir_blend_factor_value(b, src, src1, dst, bconst, chan,
                             util_blendfactor_without_invert(factor));

   if (util_blendfactor_is_inverted(factor))
      f = nir_fadd_imm(b, nir_fneg(b, f), 1.0);

   if (should_clamp_factor(factor, util_format_is_snorm(format)))
      f = nir_fsat_to_format(b, f, format);

   return nir_fmul(b, raw_scalar, f);
}

But CTS referencerenderer

But there is no clamp on blendfactor in render. https://github.com/KhronosGroup/VK-GL-CTS/blob/13344922ae81cd0033e869dabcb92d2f8bf006f8/framework/referencerenderer/rrFragmentOperations.cpp#L359

void FragmentProcessor::executeBlendFactorComputeRGB (const Vec4& blendColor, const BlendState& blendRGBState)
{
#define SAMPLE_REGISTER_BLEND_FACTOR(FACTOR_NAME, FACTOR_EXPRESSION)                                                                                \
    for (int regSampleNdx = 0; regSampleNdx < SAMPLE_REGISTER_SIZE; regSampleNdx++)                                                                 \
    {                                                                                                                                               \
        if (m_sampleRegister[regSampleNdx].isAlive)                                                                                                 \
        {                                                                                                                                           \
            const Vec4& src     = m_sampleRegister[regSampleNdx].clampedBlendSrcColor;                                                              \
            const Vec4& src1    = m_sampleRegister[regSampleNdx].clampedBlendSrc1Color;                                                             \
            const Vec4& dst     = m_sampleRegister[regSampleNdx].clampedBlendDstColor;                                                              \
            DE_UNREF(src);                                                                                                                          \
            DE_UNREF(src1);                                                                                                                         \
            DE_UNREF(dst);                                                                                                                          \
                                                                                                                                                    \
            m_sampleRegister[regSampleNdx].FACTOR_NAME = (FACTOR_EXPRESSION);                                                                       \
        }                                                                                                                                           \
    }

#define SWITCH_SRC_OR_DST_FACTOR_RGB(FUNC_NAME, FACTOR_NAME)                                                                                    \
    switch (blendRGBState.FUNC_NAME)                                                                                                            \
    {                                                                                                                                           \
        case BLENDFUNC_ZERO:                        SAMPLE_REGISTER_BLEND_FACTOR(FACTOR_NAME, Vec3(0.0f))                               break;  \
        case BLENDFUNC_ONE:                         SAMPLE_REGISTER_BLEND_FACTOR(FACTOR_NAME, Vec3(1.0f))                               break;  \
        case BLENDFUNC_SRC_COLOR:                   SAMPLE_REGISTER_BLEND_FACTOR(FACTOR_NAME, src.swizzle(0,1,2))                       break;  \
        case BLENDFUNC_ONE_MINUS_SRC_COLOR:         SAMPLE_REGISTER_BLEND_FACTOR(FACTOR_NAME, Vec3(1.0f) - src.swizzle(0,1,2))          break;  \
        case BLENDFUNC_DST_COLOR:                   SAMPLE_REGISTER_BLEND_FACTOR(FACTOR_NAME, dst.swizzle(0,1,2))                       break;  \
        case BLENDFUNC_ONE_MINUS_DST_COLOR:         SAMPLE_REGISTER_BLEND_FACTOR(FACTOR_NAME, Vec3(1.0f) - dst.swizzle(0,1,2))          break;  \
        case BLENDFUNC_SRC_ALPHA:                   SAMPLE_REGISTER_BLEND_FACTOR(FACTOR_NAME, Vec3(src.w()))                            break;  \
        case BLENDFUNC_ONE_MINUS_SRC_ALPHA:         SAMPLE_REGISTER_BLEND_FACTOR(FACTOR_NAME, Vec3(1.0f - src.w()))                     break;  \
        case BLENDFUNC_DST_ALPHA:                   SAMPLE_REGISTER_BLEND_FACTOR(FACTOR_NAME, Vec3(dst.w()))                            break;  \
        case BLENDFUNC_ONE_MINUS_DST_ALPHA:         SAMPLE_REGISTER_BLEND_FACTOR(FACTOR_NAME, Vec3(1.0f - dst.w()))                     break;  \
        case BLENDFUNC_CONSTANT_COLOR:              SAMPLE_REGISTER_BLEND_FACTOR(FACTOR_NAME, blendColor.swizzle(0,1,2))                break;  \
        case BLENDFUNC_ONE_MINUS_CONSTANT_COLOR:    SAMPLE_REGISTER_BLEND_FACTOR(FACTOR_NAME, Vec3(1.0f) - blendColor.swizzle(0,1,2))   break;  \
        case BLENDFUNC_CONSTANT_ALPHA:              SAMPLE_REGISTER_BLEND_FACTOR(FACTOR_NAME, Vec3(blendColor.w()))                     break;  \
        case BLENDFUNC_ONE_MINUS_CONSTANT_ALPHA:    SAMPLE_REGISTER_BLEND_FACTOR(FACTOR_NAME, Vec3(1.0f - blendColor.w()))              break;  \
        case BLENDFUNC_SRC_ALPHA_SATURATE:          SAMPLE_REGISTER_BLEND_FACTOR(FACTOR_NAME, Vec3(de::min(src.w(), 1.0f - dst.w())))   break;  \
        case BLENDFUNC_SRC1_COLOR:                  SAMPLE_REGISTER_BLEND_FACTOR(FACTOR_NAME, src1.swizzle(0,1,2))                      break;  \
        case BLENDFUNC_ONE_MINUS_SRC1_COLOR:        SAMPLE_REGISTER_BLEND_FACTOR(FACTOR_NAME, Vec3(1.0f) - src1.swizzle(0,1,2))         break;  \
        case BLENDFUNC_SRC1_ALPHA:                  SAMPLE_REGISTER_BLEND_FACTOR(FACTOR_NAME, Vec3(src1.w()))                           break;  \
        case BLENDFUNC_ONE_MINUS_SRC1_ALPHA:        SAMPLE_REGISTER_BLEND_FACTOR(FACTOR_NAME, Vec3(1.0f - src1.w()))                    break;  \
        default:                                                                                                                                \
            DE_ASSERT(false);                                                                                                                   \
    }

    SWITCH_SRC_OR_DST_FACTOR_RGB(srcFunc, blendSrcFactorRGB)
    SWITCH_SRC_OR_DST_FACTOR_RGB(dstFunc, blendDstFactorRGB)

#undef SWITCH_SRC_OR_DST_FACTOR_RGB
#undef SAMPLE_REGISTER_BLEND_FACTOR
}

Failed case example

What matters is that I failed:

dEQP-VK.pipeIine.monolithic.blend.format.r8 snorm.states.color_z_o_sub_alpha_1msa_1msa_sub-color-1mca_o_add_alpha_sa_sc_max- color_o_ca_rsub_alpha_o_dc_max-color_cc_1mdc_rsub_alpha_sas_z_rsub

The failure occurred at VK_BLEND_FACTOR_ONE_MINUS_DST_COLOR, specifically 1-(-0.2205) = 1.2205.

Please how should I understand.

Thanks!