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

Code before:

bool WebGPUDriver::isParallelShaderCompileSupported() {
    return false;
}

bool WebGPUDriver::isDepthStencilResolveSupported() {
    return false;
}

bool WebGPUDriver::isDepthStencilBlitSupported(const TextureFormat format) {
    return true;
}

bool WebGPUDriver::isProtectedTexturesSupported() {
    return true;
}

bool WebGPUDriver::isDepthClampSupported() {
    return false;
}

bool WebGPUDriver::isWorkaroundNeeded(Workaround) {
    return false;
}

FeatureLevel WebGPUDriver::getFeatureLevel() {
    //todo
    return FeatureLevel::FEATURE_LEVEL_1;
}

math::float2 WebGPUDriver::getClipSpaceParams() {
    return math::float2{ 1.0f, 0.0f };
}

uint8_t WebGPUDriver::getMaxDrawBuffers() {
    return MRT::MAX_SUPPORTED_RENDER_TARGET_COUNT;
}

size_t WebGPUDriver::getMaxUniformBufferSize() {
    return mDeviceLimits.maxUniformBufferBindingSize;
}

size_t WebGPUDriver::getMaxTextureSize(const SamplerType target) {
    size_t result = 2048u;
    switch (target) {
        case SamplerType::SAMPLER_2D:
        case SamplerType::SAMPLER_2D_ARRAY:
        case SamplerType::SAMPLER_EXTERNAL:
        case SamplerType::SAMPLER_CUBEMAP:
        case SamplerType::SAMPLER_CUBEMAP_ARRAY:
            result = mDeviceLimits.maxTextureDimension2D;

Review comment (performance):
@pixelflinger @poweifeng @bejado This change certainly informs Filament what feature level the WebGPU backend driver can support at runtime, but it does not address how we configure our use of the GPU when the backend gets created, namely the device settings/limits/features. @pixelflinger, maybe I am misremembering, but I thought you mentioned something earlier about honoring the requested feature level the client requests when creating the Engine instance, that we both ensure we can support the minimum requirements for the level IN ADDITION to not requesting/using more resources than required for that level. Today, we basically request a WebGPU adapter and configure a device as if feature level 3 is requested (e.g. "give me everything you have"). This would imply that we may have different required/optional features and different limits per feature level that we would use when requesting a WebGPU adapter and creating a properly configured device for it. Is that correct? If so, do we have an example elsewhere where we do this? Or, maybe we do not have enough information at this stage to properly handle that functionality?

Or is limiting the use resource utilization ultimately handled in the Filament layer above the drivers/backends? In which case, what we have makes sense.

Also, related to this, we always prefer the `HighPerformance` power preference to `LowPower` when selecting an adapter _(see [WebGPUPlatform.cpp ~lines 513-561, the selectPreferredAdapter(...) function](https://github.com/google/filament/blob/29ed42fa9814b18725c1d547adb63d1504d6ebfc/filament/backend/src/webgpu/platform/WebGPUPlatform.cpp#L513-L561) for more detail)_. Should this depend on desktop vs mobile?

Code after:

bool WebGPUDriver::isParallelShaderCompileSupported() {
    return false;
}

bool WebGPUDriver::isDepthStencilResolveSupported() {
    return false;
}

bool WebGPUDriver::isDepthStencilBlitSupported(const TextureFormat format) {
    return true;
}

bool WebGPUDriver::isProtectedTexturesSupported() {
    return true;
}

bool WebGPUDriver::isDepthClampSupported() {
    return false;
}

bool WebGPUDriver::isWorkaroundNeeded(Workaround) {
    return false;
}

FeatureLevel WebGPUDriver::getFeatureLevel() {

    // If the max sampler counts do not meet FeatureLevel2 standards, then this is an FeatureLevel1
    // device.
    const auto& featureLevel2 = FEATURE_LEVEL_CAPS[+FeatureLevel::FEATURE_LEVEL_2];
    if (mDeviceLimits.maxSamplersPerShaderStage < featureLevel2.MAX_VERTEX_SAMPLER_COUNT ||
            mDeviceLimits.maxSamplersPerShaderStage < featureLevel2.MAX_FRAGMENT_SAMPLER_COUNT) {
        return FeatureLevel::FEATURE_LEVEL_1;
    }

    // If the max sampler counts do not meet FeatureLevel3 standards, then this is an FeatureLevel2
    // device.
    const auto& featureLevel3 = FEATURE_LEVEL_CAPS[+FeatureLevel::FEATURE_LEVEL_3];
    if (mDeviceLimits.maxSamplersPerShaderStage < featureLevel3.MAX_VERTEX_SAMPLER_COUNT ||
            mDeviceLimits.maxSamplersPerShaderStage < featureLevel3.MAX_FRAGMENT_SAMPLER_COUNT) {
        return FeatureLevel::FEATURE_LEVEL_2;
    }
    return FeatureLevel::FEATURE_LEVEL_3;
}

math::float2 WebGPUDriver::getClipSpaceParams() {
    return math::float2{ 1.0f, 0.0f };
}

uint8_t WebGPUDriver::getMaxDrawBuffers() {
    return MRT::MAX_SUPPORTED_RENDER_TARGET_COUNT;