Repository: google/filament
File: filament/src/details/Texture.cpp (C++)

Code before:
        case SamplerType::SAMPLER_CUBEMAP_ARRAY:
            maxLevelCount = FTexture::maxLevelCount(mImpl->mWidth, mImpl->mHeight);
            break;
        case SamplerType::SAMPLER_3D:
            maxLevelCount = FTexture::maxLevelCount(std::max(
                    { mImpl->mWidth, mImpl->mHeight, mImpl->mDepth }));
            break;
    }
    mImpl->mLevels = std::min(mImpl->mLevels, maxLevelCount);

    if (mImpl->mUsage == TextureUsage::NONE) {
        mImpl->mUsage = TextureUsage::DEFAULT;
    }

    auto const& featureFlags = downcast(engine).features.engine.debug;
    if (mImpl->mLevels > 1 && (mImpl->mWidth > 1 || mImpl->mHeight > 1) && !mImpl->mExternal) {
        bool const formatMipmappable =
                downcast(engine).getDriverApi().isTextureFormatMipmappable(mImpl->mFormat);

        FILAMENT_FLAG_GUARDED_CHECK_PRECONDITION(
                formatMipmappable,
                featureFlags.assert_texture_format_mipmappable)
                << "Texture levels is > 1, but the format (" << int(mImpl->mFormat) << ") "
                << " is not mipmppable";

        if (formatMipmappable && !featureFlags.assert_texture_can_generate_mipmap) {
            // Setting this for backwards compatibility,but should remove when safe.
            mImpl->mUsage |= TextureUsage::GEN_MIPMAPPABLE;
        }
    }

    if (any(mImpl->mUsage & TextureUsage::GEN_MIPMAPPABLE)) {
        FILAMENT_CHECK_PRECONDITION(mImpl->mLevels > 1)
                << "Texture has GEN_MIPMAPPABLE usage set, but levels is 1.";
    }

    // TODO: remove in a future filament release.
    // Clients might not have known that textures that are read need to have BLIT_SRC as usages. For
    // now, we workaround the issue by making sure any color attachment can be the source of a copy
    // for readPixels().
    mImpl->mHasBlitSrc = any(mImpl->mUsage & TextureUsage::BLIT_SRC);
    if (!mImpl->mHasBlitSrc && any(mImpl->mUsage & TextureUsage::COLOR_ATTACHMENT)) {
        mImpl->mUsage |= TextureUsage::BLIT_SRC;
    }

    const bool sampleable = bool(mImpl->mUsage & TextureUsage::SAMPLEABLE);
    const bool swizzled = mImpl->mTextureIsSwizzled;
    const bool imported = mImpl->mImportedId;

    #if defined(__EMSCRIPTEN__)
    FILAMENT_CHECK_PRECONDITION(!swizzled) << "WebGL does not support texture swizzling.";

Review comment (suggestion):
if we want to do this, we should guard this whole block (From line 248) by the feature flag, because this whole code here is about "guessing" the usage flag to put. but in the future this should be explicit.

Code after:
        case SamplerType::SAMPLER_CUBEMAP_ARRAY:
            maxLevelCount = FTexture::maxLevelCount(mImpl->mWidth, mImpl->mHeight);
            break;
        case SamplerType::SAMPLER_3D:
            maxLevelCount = FTexture::maxLevelCount(std::max(
                    { mImpl->mWidth, mImpl->mHeight, mImpl->mDepth }));
            break;
    }
    mImpl->mLevels = std::min(mImpl->mLevels, maxLevelCount);

    if (mImpl->mUsage == TextureUsage::NONE) {
        mImpl->mUsage = TextureUsage::DEFAULT;
    }

    auto const& featureFlags = downcast(engine).features.engine.debug;

    bool const formatMipmappable =
            downcast(engine).getDriverApi().isTextureFormatMipmappable(mImpl->mFormat);

    FILAMENT_FLAG_GUARDED_CHECK_PRECONDITION(mImpl->mLevels == 1 || formatMipmappable,
            featureFlags.assert_texture_format_mipmappable)
            << "Texture levels is > 1 (levels=" << +mImpl->mLevels
            << " dim=" << mImpl->mWidth << "x" << mImpl->mHeight
            << ", but the format ("
            << int(mImpl->mFormat) << ") "
            << " is not mipmppable";

    // TODO: This exists for backwards compatibility, but should remove when safe.
    if (!featureFlags.assert_texture_can_generate_mipmap &&
            // Guess whether GEN_MIPMAPPABLE should be added or not based the following criteria.
            (formatMipmappable &&
                    mImpl->mLevels > 1 &&
                    (mImpl->mWidth > 1 || mImpl->mHeight > 1) &&
                    !mImpl->mExternal)) {
        mImpl->mUsage |= TextureUsage::GEN_MIPMAPPABLE;
    }

    // TODO: remove in a future filament release.
    // Clients might not have known that textures that are read need to have BLIT_SRC as usages. For
    // now, we workaround the issue by making sure any color attachment can be the source of a copy
    // for readPixels().
    mImpl->mHasBlitSrc = any(mImpl->mUsage & TextureUsage::BLIT_SRC);
    if (!mImpl->mHasBlitSrc && any(mImpl->mUsage & TextureUsage::COLOR_ATTACHMENT)) {
        mImpl->mUsage |= TextureUsage::BLIT_SRC;
    }

    const bool sampleable = bool(mImpl->mUsage & TextureUsage::SAMPLEABLE);
    const bool swizzled = mImpl->mTextureIsSwizzled;
    const bool imported = mImpl->mImportedId;

    #if defined(__EMSCRIPTEN__)