1
    2
    3
    4
    5
    6
    7
    8
    9
   10
   11
   12
   13
   14
   15
   16
   17
   18
   19
   20
   21
   22
   23
   24
   25
   26
   27
   28
   29
   30
   31
   32
   33
   34
   35
   36
   37
   38
   39
   40
   41
   42
   43
   44
   45
   46
   47
   48
   49
   50
   51
   52
   53
   54
   55
   56
   57
   58
   59
   60
   61
   62
   63
   64
   65
   66
   67
   68
   69
   70
   71
   72
   73
   74
   75
   76
   77
   78
   79
   80
   81
   82
   83
   84
   85
   86
   87
   88
   89
   90
   91
   92
   93
   94
   95
   96
   97
   98
   99
  100
  101
  102
  103
  104
  105
  106
  107
  108
  109
  110
  111
  112
  113
  114
  115
  116
  117
  118
  119
  120
  121
  122
  123
  124
  125
  126
  127
  128
  129
  130
  131
  132
  133
  134
  135
  136
  137
  138
  139
  140
  141
  142
  143
  144
  145
  146
  147
  148
  149
  150
  151
  152
  153
  154
  155
  156
  157
  158
  159
  160
  161
  162
  163
  164
  165
  166
  167
  168
  169
  170
  171

gpu / config / gpu_blocklist_unittest.cc [blame]

// Copyright 2013 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <vector>

#include "gpu/config/gpu_blocklist.h"
#include "gpu/config/gpu_driver_bug_list_autogen.h"
#include "gpu/config/gpu_feature_type.h"
#include "gpu/config/gpu_info.h"
#include "gpu/config/software_rendering_list_autogen.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/re2/src/re2/re2.h"

namespace gpu {

class GpuBlocklistTest : public testing::Test {
 public:
  GpuBlocklistTest() = default;
  ~GpuBlocklistTest() override = default;

  const GPUInfo& gpu_info() const { return gpu_info_; }

  void RunFeatureTest(GpuFeatureType feature_type) {
    const std::array<const int, 1> kFeatureListForEntry1 = {feature_type};
    const GpuControlList::Device kDevicesForEntry1[1] = {{0x0640, 0x0}};
    const std::array<GpuControlList::Entry, 1> kTestEntries = {{{
        1,                                  // id
        "Test entry",                       // description
        base::span(kFeatureListForEntry1),  // features
        base::span<const char* const>(),    // DisabledExtensions
        base::span<const char* const>(),    // DisabledWebGLExtensions
        base::span<const uint32_t>(),       // CrBugs
        {
            GpuControlList::kOsMacosx,  // os_type
            {GpuControlList::kUnknown, GpuControlList::kVersionStyleNumerical,
             GpuControlList::kVersionSchemaCommon, nullptr,
             nullptr},                             // os_version
            0x10de,                                // vendor_id
            base::span(kDevicesForEntry1),         // Devices
            GpuControlList::kMultiGpuCategoryAny,  // multi_gpu_category
            GpuControlList::kMultiGpuStyleNone,    // multi_gpu_style
            nullptr,                               // driver info
            nullptr,                               // GL strings
            nullptr,                               // machine model info
            nullptr,                               // Intel conditions
            nullptr,                               // more conditions
        },
        base::span<GpuControlList::Conditions>(),  // exceptions
    }}};
    std::unique_ptr<GpuBlocklist> blocklist =
        GpuBlocklist::Create(kTestEntries);
    std::set<int> type =
        blocklist->MakeDecision(GpuBlocklist::kOsMacosx, "10.12.3", gpu_info());
    EXPECT_EQ(1u, type.size());
    EXPECT_EQ(1u, type.count(feature_type));
  }

 protected:
  void SetUp() override {
    gpu_info_.gpu.vendor_id = 0x10de;
    gpu_info_.gpu.device_id = 0x0640;
    gpu_info_.gpu.driver_vendor = "NVIDIA";
    gpu_info_.gpu.driver_version = "1.6.18";
    gpu_info_.machine_model_name = "MacBookPro";
    gpu_info_.machine_model_version = "7.1";
    gpu_info_.gl_vendor = "NVIDIA Corporation";
    gpu_info_.gl_renderer = "NVIDIA GeForce GT 120 OpenGL Engine";
  }

 private:
  GPUInfo gpu_info_;
};

#define GPU_BLOCKLIST_FEATURE_TEST(test_name, feature_type) \
  TEST_F(GpuBlocklistTest, test_name) { RunFeatureTest(feature_type); }

GPU_BLOCKLIST_FEATURE_TEST(Accelerated2DCanvas,
                           GPU_FEATURE_TYPE_ACCELERATED_2D_CANVAS)

GPU_BLOCKLIST_FEATURE_TEST(AcceleratedWebGL, GPU_FEATURE_TYPE_ACCELERATED_WEBGL)

GPU_BLOCKLIST_FEATURE_TEST(AcceleratedVideoDecode,
                           GPU_FEATURE_TYPE_ACCELERATED_VIDEO_DECODE)

GPU_BLOCKLIST_FEATURE_TEST(AcceleratedVideoEncode,
                           GPU_FEATURE_TYPE_ACCELERATED_VIDEO_ENCODE)

GPU_BLOCKLIST_FEATURE_TEST(GpuRasterization,
                           GPU_FEATURE_TYPE_GPU_TILE_RASTERIZATION)

GPU_BLOCKLIST_FEATURE_TEST(WebGL2, GPU_FEATURE_TYPE_ACCELERATED_WEBGL2)

GPU_BLOCKLIST_FEATURE_TEST(GL, GPU_FEATURE_TYPE_ACCELERATED_GL)

GPU_BLOCKLIST_FEATURE_TEST(Vulkan, GPU_FEATURE_TYPE_VULKAN)

GPU_BLOCKLIST_FEATURE_TEST(AcceleratedWebGPU,
                           GPU_FEATURE_TYPE_ACCELERATED_WEBGPU)

GPU_BLOCKLIST_FEATURE_TEST(SkiaGraphite, GPU_FEATURE_TYPE_SKIA_GRAPHITE)

GPU_BLOCKLIST_FEATURE_TEST(WebNN, GPU_FEATURE_TYPE_WEBNN)

// Test for invariant "Assume the newly last added entry has the largest ID".
// See GpuControlList::GpuControlList.
// It checks software_rendering_list.json
TEST_F(GpuBlocklistTest, TestBlocklistIsValid) {
  std::unique_ptr<GpuBlocklist> list(GpuBlocklist::Create());
  uint32_t max_entry_id = list->max_entry_id();

  std::vector<uint32_t> indices(list->num_entries());
  int current = 0;
  std::generate(indices.begin(), indices.end(),
                [¤t]() { return current++; });

  auto entries = list->GetEntryIDsFromIndices(indices);
  auto real_max_entry_id = *std::max_element(entries.begin(), entries.end());
  EXPECT_EQ(real_max_entry_id, max_entry_id);
}

void TestBlockList(base::span<const GpuControlList::Entry> entries) {
  for (const auto& entry : entries) {
    if (const auto* gl_strings = entry.conditions.gl_strings) {
      if (gl_strings->gl_vendor) {
        EXPECT_TRUE(RE2(gl_strings->gl_vendor).ok())
            << "gl_vendor=" << gl_strings->gl_vendor;
      }
      if (gl_strings->gl_renderer) {
        EXPECT_TRUE(RE2(gl_strings->gl_renderer).ok())
            << "gl_renderer=" << gl_strings->gl_renderer;
      }
      if (gl_strings->gl_extensions) {
        EXPECT_TRUE(RE2(gl_strings->gl_extensions).ok())
            << "gl_extensions=" << gl_strings->gl_extensions;
      }
      if (gl_strings->gl_version) {
        EXPECT_TRUE(RE2(gl_strings->gl_version).ok())
            << "gl_version=" << gl_strings->gl_version;
      }
    }
    for (const auto& conditions : entry.exceptions) {
      if (const auto* gl_strings = conditions.gl_strings) {
        if (gl_strings->gl_vendor) {
          EXPECT_TRUE(RE2(gl_strings->gl_vendor).ok())
              << "gl_vendor=" << gl_strings->gl_vendor;
        }
        if (gl_strings->gl_renderer) {
          EXPECT_TRUE(RE2(gl_strings->gl_renderer).ok())
              << "gl_renderer=" << gl_strings->gl_renderer;
        }
        if (gl_strings->gl_extensions) {
          EXPECT_TRUE(RE2(gl_strings->gl_extensions).ok())
              << "gl_extensions=" << gl_strings->gl_extensions;
        }
        if (gl_strings->gl_version) {
          EXPECT_TRUE(RE2(gl_strings->gl_version).ok())
              << "gl_version=" << gl_strings->gl_version;
        }
      }
    }
  }
}

// It checks software_rendering_list.json
TEST_F(GpuBlocklistTest, VerifyGLStrings) {
  TestBlockList(GetSoftwareRenderingListEntries());
  TestBlockList(GetGpuDriverBugListEntries());
}

}  // namespace gpu