/*
 * Copyright 2025 Google LLC
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "tools/graphite/dawn/GraphiteDawnToggles.h"

namespace skiatest::graphite {

wgpu::DawnTogglesDescriptor GetInstanceToggles() {
    static constexpr const char* kToggles[] = {
            // Needed for newer Dawn APIs that aren't launched in WebGPU.
            "allow_unsafe_apis",
    };
    wgpu::DawnTogglesDescriptor togglesDesc;
    togglesDesc.enabledToggleCount = std::size(kToggles);
    togglesDesc.enabledToggles = kToggles;
    return togglesDesc;
}

wgpu::DawnTogglesDescriptor GetAdapterToggles() {
    static constexpr const char* kToggles[] = {
#if defined(SK_DEBUG)
            // Setting labels on backend objects has performance overhead.
            "use_user_defined_labels_in_backend",
#else
            "skip_validation",
#endif
            // Lazy clear has performance overhead.
            "disable_lazy_clear_for_mapped_at_creation_buffer",
            // Robustness impacts performance and is always disabled when running Graphite in
            // Chrome, so this keeps Skia's tests operating closer to real-use behavior.
            "disable_robustness",
            // Validating the SPIR-V shaders generated by Tint may have some overhead, and is
            // not required for Graphite since the input is trusted.
            "enable_spirv_validation",
    };
    wgpu::DawnTogglesDescriptor togglesDesc;
    togglesDesc.enabledToggleCount = std::size(kToggles);
    togglesDesc.enabledToggles = kToggles;
    return togglesDesc;
}

void AddPreferredFeatures(const wgpu::Adapter& adapter, std::vector<wgpu::FeatureName>& features) {
    auto addFeature = [&](wgpu::FeatureName feature) {
        if (adapter.HasFeature(feature)) {
            for (auto existing : features) {
                if (existing == feature) {
                    return; // Don't re-add it if it was already in `features`
                }
            }
            features.push_back(feature);
        }
    };

    addFeature(wgpu::FeatureName::BufferMapExtendedUsages);
    addFeature(wgpu::FeatureName::DawnAllowUndefinedLoadStoreOp);
    addFeature(wgpu::FeatureName::DawnLoadResolveTexture);
    addFeature(wgpu::FeatureName::DawnPartialLoadResolveTexture);
    addFeature(wgpu::FeatureName::DawnTexelCopyBufferRowAlignment);
    addFeature(wgpu::FeatureName::DualSourceBlending);
    addFeature(wgpu::FeatureName::FramebufferFetch);
    addFeature(wgpu::FeatureName::ImplicitDeviceSynchronization);
    addFeature(wgpu::FeatureName::MSAARenderToSingleSampled);
    addFeature(wgpu::FeatureName::ShaderF16);
    addFeature(wgpu::FeatureName::TextureCompressionBC);
    addFeature(wgpu::FeatureName::TextureCompressionETC2);
    addFeature(wgpu::FeatureName::TextureFormatsTier1);
    addFeature(wgpu::FeatureName::TimestampQuery);
    addFeature(wgpu::FeatureName::TransientAttachments);
    addFeature(wgpu::FeatureName::Unorm16TextureFormats);
    addFeature(wgpu::FeatureName::RenderPassRenderArea);
}


}  // namespace skiatest::graphite
