0

WebGPU: Use Adapter GetFeatures() instead of EnumerateFeatures()

This CL supersedes the previous CL[1]. It doesn't use parent_decoder in
wire_procs.supportedFeaturesFreeMembers anymore and directly frees
memory from supported_features to avoid crash.
EnumerateFeatures proxying is not removed yet because we need to wait
until the dawn::wire::server switches over to keep the filtering for
now.

[1]: https://chromium-review.googlesource.com/c/chromium/src/+/5958567

Bug: 368672123
Change-Id: Ibc5d45c11d3530c06a4af085807a74275fcd6e25
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6011908
Reviewed-by: Maggie Chen <magchen@chromium.org>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Commit-Queue: Fr <beaufort.francois@gmail.com>
Cr-Commit-Position: refs/heads/main@{#1382537}
This commit is contained in:
François Beaufort
2024-11-13 20:02:02 +00:00
committed by Chromium LUCI CQ
parent 598611ad5e
commit d7e1e9c7d2
3 changed files with 52 additions and 12 deletions
gpu
third_party/blink/renderer/modules/webgpu

@ -375,6 +375,8 @@ class WebGPUDecoderImpl final : public WebGPUDecoder {
WGPUBool AdapterHasFeatureImpl(WGPUAdapter adapter, WGPUFeatureName feature);
size_t AdapterEnumerateFeaturesImpl(WGPUAdapter adapter,
WGPUFeatureName* features);
void AdapterGetFeaturesImpl(WGPUAdapter adapter,
WGPUSupportedFeatures* features_out);
template <typename CallbackInfo>
WGPUFuture RequestDeviceImpl(WGPUAdapter adapter,
const WGPUDeviceDescriptor* descriptor,
@ -1189,6 +1191,17 @@ WebGPUDecoderImpl::WebGPUDecoderImpl(
return parent_decoder->AdapterEnumerateFeaturesImpl(
std::forward<decltype(args)>(args)...);
};
wire_procs.adapterGetFeatures = [](auto... args) {
DCHECK(parent_decoder);
return parent_decoder->AdapterGetFeaturesImpl(
std::forward<decltype(args)>(args)...);
};
wire_procs.supportedFeaturesFreeMembers =
[](WGPUSupportedFeatures supported_features) -> void {
// We don't need any state so we don't need the parent decoder and can free
// immediately.
delete[] supported_features.features;
};
wire_procs.adapterRequestDevice2 = [](auto... args) {
DCHECK(parent_decoder);
return parent_decoder->RequestDeviceImpl(
@ -1403,6 +1416,30 @@ size_t WebGPUDecoderImpl::AdapterEnumerateFeaturesImpl(
return count;
}
void WebGPUDecoderImpl::AdapterGetFeaturesImpl(
WGPUAdapter adapter,
WGPUSupportedFeatures* features_out) {
wgpu::Adapter adapter_obj(adapter);
wgpu::SupportedFeatures supported_features;
adapter_obj.GetFeatures(&supported_features);
std::vector<wgpu::FeatureName> exposed_features;
for (uint32_t i = 0; i < supported_features.featureCount; ++i) {
wgpu::FeatureName feature = supported_features.features[i];
if (IsFeatureExposed(feature)) {
exposed_features.push_back(feature);
};
}
const size_t count = exposed_features.size();
WGPUFeatureName* features = new WGPUFeatureName[count];
uint32_t index = 0;
for (wgpu::FeatureName feature : exposed_features) {
features[index++] = static_cast<WGPUFeatureName>(feature);
}
features_out->featureCount = count;
features_out->features = features;
}
template <typename CallbackInfo>
WGPUFuture WebGPUDecoderImpl::RequestDeviceImpl(
WGPUAdapter adapter,

@ -832,6 +832,7 @@ bool CollectGpuExtraInfo(gfx::GpuExtraInfo* gpu_extra_info,
return true;
}
// TODO(crbug.com/351564777): should be UNSAFE_BUFFER_USAGE
void CollectDawnInfo(const gpu::GpuPreferences& gpu_preferences,
bool collect_metrics,
std::vector<std::string>* dawn_info_list) {
@ -956,10 +957,13 @@ void CollectDawnInfo(const gpu::GpuPreferences& gpu_preferences,
// Get supported features under required adapter toggles if Dawn
// available, or default toggles otherwise.
dawn_info_list->push_back("[Adapter Supported Features]");
std::vector<wgpu::FeatureName> features(
adapter.EnumerateFeatures(nullptr));
adapter.EnumerateFeatures(features.data());
for (wgpu::FeatureName f : features) {
wgpu::SupportedFeatures supportedFeatures;
adapter.GetFeatures(&supportedFeatures);
// SAFETY: Required from caller
const auto features =
UNSAFE_BUFFERS(base::span<const wgpu::FeatureName>(
supportedFeatures.features, supportedFeatures.featureCount));
for (const auto& f : features) {
dawn_info_list->push_back(dawn::native::GetFeatureInfo(f)->name);
}

@ -89,19 +89,18 @@ std::optional<V8GPUFeatureName::Enum> ToV8FeatureNameEnum(wgpu::FeatureName f) {
namespace {
// TODO(crbug.com/351564777): should be UNSAFE_BUFFER_USAGE
GPUSupportedFeatures* MakeFeatureNameSet(wgpu::Adapter adapter,
ExecutionContext* execution_context) {
GPUSupportedFeatures* features = MakeGarbageCollected<GPUSupportedFeatures>();
DCHECK(features->FeatureNameSet().empty());
size_t feature_count = adapter.EnumerateFeatures(nullptr);
DCHECK(feature_count <= std::numeric_limits<wtf_size_t>::max());
Vector<wgpu::FeatureName> feature_names(
static_cast<wtf_size_t>(feature_count));
adapter.EnumerateFeatures(feature_names.data());
for (wgpu::FeatureName f : feature_names) {
wgpu::SupportedFeatures supported_features;
adapter.GetFeatures(&supported_features);
// SAFETY: Required from caller
const auto features_span = UNSAFE_BUFFERS(base::span<const wgpu::FeatureName>(
supported_features.features, supported_features.featureCount));
for (const auto& f : features_span) {
auto feature_name_enum_optional = ToV8FeatureNameEnum(f);
if (feature_name_enum_optional) {
V8GPUFeatureName::Enum feature_name_enum =