Repository: google/filament
File: filament/backend/src/webgpu/WebGPUTexture.cpp (C++)

Code before:
        retUsage |= wgpu::TextureUsage::TextureBinding;
    }
    if (any(TextureUsage::BLIT_DST & fUsage)) {
        retUsage |= wgpu::TextureUsage::CopyDst;
        retUsage |= wgpu::TextureUsage::RenderAttachment;
    }
    if (any(TextureUsage::UPLOADABLE & fUsage)) {
        retUsage |= wgpu::TextureUsage::CopyDst;
    }
    if (any(TextureUsage::GEN_MIPMAPPABLE & fUsage)) {
        retUsage |= (wgpu::TextureUsage::RenderAttachment | wgpu::TextureUsage::TextureBinding);
    }
    if (any(TextureUsage::SAMPLEABLE & fUsage)) {
        retUsage |= wgpu::TextureUsage::TextureBinding;
    }
    // if needsComputeStorageSupport we need to read and write to the texture in a shader and thus
    // require CopySrc, CopyDst, TextureBinding, & StorageBinding
    if (needsComputeStorageSupport) {
        retUsage |= wgpu::TextureUsage::StorageBinding;
        retUsage |= wgpu::TextureUsage::CopySrc;
        retUsage |= wgpu::TextureUsage::CopyDst;
        retUsage |= wgpu::TextureUsage::TextureBinding;
    }

    wgpu::TextureUsage transientAttachmentNeeded = wgpu::TextureUsage::None;
    const bool useTransientAttachment =
            // Usage consists of attachment flags only.
            none(fUsage & ~TextureUsage::ALL_ATTACHMENTS) &&
            // Usage contains at least one attachment flag.
            any(fUsage & TextureUsage::ALL_ATTACHMENTS) &&
            // Depth resolve cannot use transient attachment because it uses a custom shader.
            // TODO: see VulkanDriver::isDepthStencilResolveSupported() to know when to remove this
            // restriction.
            // Note that the custom shader does not resolve stencil. We do need to move to vk 1.2
            // and above to be able to support stencil resolve (along with depth).
            !(any(fUsage & TextureUsage::DEPTH_ATTACHMENT) && samples > 1);
    if (useTransientAttachment) {
        transientAttachmentNeeded |= wgpu::TextureUsage::TransientAttachment;
    }

    // A texture that is a blit destination or render attachment will often need to be
    // a copy source for subsequent operations (e.g., mipmap generation, readbacks).
    // However, we dont need to add the CopySrc IF its a transientAttachment
    if (any((TextureUsage::BLIT_DST | TextureUsage::COLOR_ATTACHMENT | TextureUsage::DEPTH_ATTACHMENT) & fUsage)) {
        if (!useTransientAttachment)
        {
            retUsage |= wgpu::TextureUsage::CopySrc;
        }
    }

    if (needsRenderAttachmentSupport) {

Review comment (suggestion):
We should add a parameter to this function, something like `const bool transientAttachmentsSupported` and use it here, e.g.:
```cpp
const bool useTransientAttachment {
        transientAttachmentsSupported &&
        ...
```

when calling `fToWGPUTextureUsage(...)` you can pass to that parameter `device.HasFeature(wgpu::FeatureName::TransientAttachments)`

Code after:
            fFormat == filament::backend::TextureFormat::DEPTH24 ||
            fFormat == filament::backend::TextureFormat::DEPTH16) {
        return wgpu::TextureAspect::DepthOnly;
    }

    if (fFormat == filament::backend::TextureFormat::STENCIL8) {
        return wgpu::TextureAspect::StencilOnly;
    }

    if (fFormat == filament::backend::TextureFormat::DEPTH24_STENCIL8 ||
            fFormat == filament::backend::TextureFormat::DEPTH32F_STENCIL8) {
        if (isSample) {
            return wgpu::TextureAspect::DepthOnly;
        }
    }

    return wgpu::TextureAspect::All;
}

[[nodiscard]] WebGPUTexture::MipmapGenerationStrategy determineMipmapGenerationStrategy(
        const wgpu::TextureFormat format, const SamplerType samplerType, const uint8_t sampleCount,
        const uint8_t mipmapLevels) {
    if (mipmapLevels <= 1) {
        return WebGPUTexture::MipmapGenerationStrategy::NONE; // no mipmap generation needed
    }
    const WebGPURenderPassMipmapGenerator::FormatCompatibility renderPassCompatibility{
        WebGPURenderPassMipmapGenerator::getCompatibilityFor(format,
                toWebGPUTextureDimension(samplerType), sampleCount)
    };
    if (renderPassCompatibility.compatible) {
        return WebGPUTexture::MipmapGenerationStrategy::RENDER_PASS;
    }
    if (WebGPUTexture::supportsMultipleMipLevelsViaStorageBinding(format)) {
        return WebGPUTexture::MipmapGenerationStrategy::SPD_COMPUTE_PASS;
    }
    // we don't have a way to generate mipmaps for this texture, at least at this time
    return WebGPUTexture::MipmapGenerationStrategy::NONE;
}

[[nodiscard]] constexpr wgpu::Extent3D toTextureSize(const SamplerType samplerType,
        const uint32_t width, const uint32_t height, const uint32_t depth) {
    switch (samplerType) {
        case SamplerType::SAMPLER_2D:
        case SamplerType::SAMPLER_2D_ARRAY:
        case SamplerType::SAMPLER_EXTERNAL:
        case SamplerType::SAMPLER_3D:
            return { .width = width, .height = height, .depthOrArrayLayers = depth };
        case SamplerType::SAMPLER_CUBEMAP:
            return { .width = width, .height = height, .depthOrArrayLayers = 6 };
        case SamplerType::SAMPLER_CUBEMAP_ARRAY:
            return { .width = width, .height = height, .depthOrArrayLayers = depth * 6 };