Commit 6fa22882 authored by Jiawei Shao's avatar Jiawei Shao Committed by Commit Bot

WebGPU: Implement returning adapter properties from GPU process

This patch implements sending the adapter properties from GPU process to
the renderer process in the call of adapter.RequestAdapter().

At the client side of WebGPU command buffer, before sending the request
of RequestAdapter() to the server side, a callback is saved in a map
whose key is the serial number of the request. After selecting the
preferred adapter, the GPU process will send the id and properties of
the adapter to the rendering process, the related callback will be
called to create the GPUAdapter object in Blink with the information
about this adapter from the GPU process.

BUG=chromium:996713

Change-Id: I81e252559a7d256213f4bf93405d63cd0e6fa02b
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1897475Reviewed-by: default avatarCorentin Wallez <cwallez@chromium.org>
Reviewed-by: default avatarZhenyao Mo <zmo@chromium.org>
Reviewed-by: default avatarKai Ninomiya <kainino@chromium.org>
Reviewed-by: default avatarAustin Eng <enga@chromium.org>
Commit-Queue: Jiawei Shao <jiawei.shao@intel.com>
Cr-Commit-Position: refs/heads/master@{#716963}
parent 60e3aac0
......@@ -20,6 +20,7 @@ _NAMED_TYPE_INFO = {
'PowerPreference': {
'type': 'PowerPreference',
'valid': [
'PowerPreference::kDefault',
'PowerPreference::kHighPerformance',
'PowerPreference::kLowPower',
],
......@@ -62,7 +63,8 @@ _FUNCTION_INFO = {
},
'RequestAdapter': {
'impl_func': False,
'cmd_args': 'uint32_t power_preference'
'internal': True,
'cmd_args': 'uint32_t request_adapter_serial, uint32_t power_preference'
},
}
......
......@@ -43,10 +43,11 @@ void DissociateMailbox(GLuint texture_id, GLuint texture_generation) {
}
}
void RequestAdapter(uint32_t power_preference) {
void RequestAdapter(uint32_t request_adapter_serial,
uint32_t power_preference) {
webgpu::cmds::RequestAdapter* c = GetCmdSpace<webgpu::cmds::RequestAdapter>();
if (c) {
c->Init(power_preference);
c->Init(request_adapter_serial, power_preference);
}
}
......
......@@ -259,6 +259,32 @@ void WebGPUImplementation::OnGpuControlReturnData(
NOTREACHED();
}
break;
case DawnReturnDataType::kRequestedDawnAdapterProperties: {
const cmds::DawnReturnAdapterInfo* returned_adapter_info =
reinterpret_cast<const cmds::DawnReturnAdapterInfo*>(
dawnReturnDataBody);
GLuint request_adapter_serial =
returned_adapter_info->adapter_ids.request_adapter_serial;
auto request_callback_iter =
request_adapter_callback_map_.find(request_adapter_serial);
if (request_callback_iter == request_adapter_callback_map_.end()) {
// TODO(jiawei.shao@intel.com): Lose the context.
NOTREACHED();
break;
}
auto& request_callback = request_callback_iter->second;
GLuint adapter_service_id =
returned_adapter_info->adapter_ids.adapter_service_id;
WGPUDeviceProperties adapter_properties = {};
const volatile char* deserialized_buffer =
reinterpret_cast<const volatile char*>(
returned_adapter_info->deserialized_buffer);
dawn_wire::DeserializeWGPUDeviceProperties(&adapter_properties,
deserialized_buffer);
std::move(request_callback).Run(adapter_service_id, adapter_properties);
request_adapter_callback_map_.erase(request_callback_iter);
} break;
default:
// TODO(jiawei.shao@intel.com): Lose the context.
NOTREACHED();
......@@ -365,11 +391,30 @@ ReservedTexture WebGPUImplementation::ReserveTexture(WGPUDevice device) {
#endif
}
void WebGPUImplementation::RequestAdapter(PowerPreference power_preference) {
GPU_CLIENT_SINGLE_THREAD_CHECK();
GPU_CLIENT_LOG("[" << GetLogPrefix() << "] wgRequestAdapter("
<< static_cast<uint32_t>(power_preference) << ")");
helper_->RequestAdapter(static_cast<uint32_t>(power_preference));
uint32_t WebGPUImplementation::NextRequestAdapterSerial() {
return ++request_adapter_serial_;
}
bool WebGPUImplementation::RequestAdapterAsync(
PowerPreference power_preference,
base::OnceCallback<void(uint32_t, const WGPUDeviceProperties&)>
request_adapter_callback) {
uint32_t request_adapter_serial = NextRequestAdapterSerial();
// Avoid the overflow of request_adapter_serial and old slot being reused.
if (request_adapter_callback_map_.find(request_adapter_serial) !=
request_adapter_callback_map_.end()) {
return false;
}
helper_->RequestAdapter(request_adapter_serial,
static_cast<uint32_t>(power_preference));
helper_->Flush();
request_adapter_callback_map_[request_adapter_serial] =
std::move(request_adapter_callback);
return true;
}
} // namespace webgpu
......
......@@ -119,10 +119,15 @@ class WEBGPU_EXPORT WebGPUImplementation final
void FlushCommands() override;
WGPUDevice GetDefaultDevice() override;
ReservedTexture ReserveTexture(WGPUDevice device) override;
bool RequestAdapterAsync(
PowerPreference power_preference,
base::OnceCallback<void(uint32_t, const WGPUDeviceProperties&)>
request_adapter_callback) override;
private:
const char* GetLogPrefix() const { return "webgpu"; }
void CheckGLError() {}
uint32_t NextRequestAdapterSerial();
WebGPUCmdHelper* helper_;
#if BUILDFLAG(USE_DAWN)
......@@ -137,6 +142,12 @@ class WEBGPU_EXPORT WebGPUImplementation final
LogSettings log_settings_;
base::flat_map<
uint32_t,
base::OnceCallback<void(uint32_t, const WGPUDeviceProperties&)>>
request_adapter_callback_map_;
uint32_t request_adapter_serial_ = 0;
DISALLOW_COPY_AND_ASSIGN(WebGPUImplementation);
};
......
......@@ -22,7 +22,4 @@ void AssociateMailbox(GLuint device_id,
void DissociateMailbox(GLuint texture_id, GLuint texture_generation) override;
void RequestAdapter(PowerPreference power_preference =
PowerPreference::kHighPerformance) override;
#endif // GPU_COMMAND_BUFFER_CLIENT_WEBGPU_IMPLEMENTATION_AUTOGEN_H_
......@@ -39,15 +39,4 @@ TEST_F(WebGPUImplementationTest, DissociateMailbox) {
gl_->DissociateMailbox(1, 2);
EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
}
TEST_F(WebGPUImplementationTest, RequestAdapter) {
struct Cmds {
cmds::RequestAdapter cmd;
};
Cmds expected;
expected.cmd.Init(1);
gl_->RequestAdapter(PowerPreference::kHighPerformance);
EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
}
#endif // GPU_COMMAND_BUFFER_CLIENT_WEBGPU_IMPLEMENTATION_UNITTEST_AUTOGEN_H_
......@@ -8,6 +8,7 @@
#include <dawn/dawn_proc_table.h>
#include <dawn/webgpu.h>
#include "base/callback.h"
#include "gpu/command_buffer/client/interface_base.h"
#include "gpu/command_buffer/common/webgpu_cmd_enums.h"
......@@ -29,6 +30,10 @@ class WebGPUInterface : public InterfaceBase {
virtual void FlushCommands() = 0;
virtual WGPUDevice GetDefaultDevice() = 0;
virtual ReservedTexture ReserveTexture(WGPUDevice device) = 0;
virtual bool RequestAdapterAsync(
PowerPreference power_preference,
base::OnceCallback<void(uint32_t, const WGPUDeviceProperties&)>
request_adapter_callback) = 0;
// Include the auto-generated part of this class. We split this because
// it means we can easily edit the non-auto generated parts right here in
......
......@@ -21,6 +21,4 @@ virtual void AssociateMailbox(GLuint device_id,
const GLbyte* mailbox) = 0;
virtual void DissociateMailbox(GLuint texture_id,
GLuint texture_generation) = 0;
virtual void RequestAdapter(
PowerPreference power_preference = PowerPreference::kHighPerformance) = 0;
#endif // GPU_COMMAND_BUFFER_CLIENT_WEBGPU_INTERFACE_AUTOGEN_H_
......@@ -29,6 +29,12 @@ WGPUDevice WebGPUInterfaceStub::GetDefaultDevice() {
ReservedTexture WebGPUInterfaceStub::ReserveTexture(WGPUDevice device) {
return {nullptr, 0, 0};
}
bool WebGPUInterfaceStub::RequestAdapterAsync(
PowerPreference power_preference,
base::OnceCallback<void(uint32_t, const WGPUDeviceProperties&)>
request_adapter_callback) {
return false;
}
// Include the auto-generated part of this class. We split this because
// it means we can easily edit the non-auto generated parts right here in
......
......@@ -27,6 +27,10 @@ class WebGPUInterfaceStub : public WebGPUInterface {
void FlushCommands() override;
WGPUDevice GetDefaultDevice() override;
ReservedTexture ReserveTexture(WGPUDevice device) override;
bool RequestAdapterAsync(
PowerPreference power_preference,
base::OnceCallback<void(uint32_t, const WGPUDeviceProperties&)>
request_adapter_callback) override;
// Include the auto-generated part of this class. We split this because
// it means we can easily edit the non-auto generated parts right here in
......
......@@ -19,5 +19,4 @@ void AssociateMailbox(GLuint device_id,
GLuint usage,
const GLbyte* mailbox) override;
void DissociateMailbox(GLuint texture_id, GLuint texture_generation) override;
void RequestAdapter(PowerPreference power_preference) override;
#endif // GPU_COMMAND_BUFFER_CLIENT_WEBGPU_INTERFACE_STUB_AUTOGEN_H_
......@@ -20,6 +20,4 @@ void WebGPUInterfaceStub::AssociateMailbox(GLuint /* device_id */,
const GLbyte* /* mailbox */) {}
void WebGPUInterfaceStub::DissociateMailbox(GLuint /* texture_id */,
GLuint /* texture_generation */) {}
void WebGPUInterfaceStub::RequestAdapter(
PowerPreference /* power_preference */) {}
#endif // GPU_COMMAND_BUFFER_CLIENT_WEBGPU_INTERFACE_STUB_IMPL_AUTOGEN_H_
......@@ -11,11 +11,13 @@ namespace webgpu {
enum class PowerPreference : uint32_t {
kLowPower,
kHighPerformance,
kDefault,
kNumPowerPreferences
};
enum class DawnReturnDataType : uint32_t {
kDawnCommands,
kRequestedDawnAdapterProperties,
kNumDawnReturnDataType
};
......
......@@ -31,6 +31,26 @@ static_assert(
sizeof(DawnReturnDataHeader) % GPU_DAWN_RETURN_DATA_ALIGNMENT == 0,
"DawnReturnDataHeader must align to GPU_DAWN_RETURN_DATA_ALIGNMENT");
struct alignas(GPU_DAWN_RETURN_DATA_ALIGNMENT) DawnReturnAdapterIDs {
uint32_t request_adapter_serial;
uint32_t adapter_service_id;
};
static_assert(
sizeof(DawnReturnAdapterIDs) % GPU_DAWN_RETURN_DATA_ALIGNMENT == 0,
"DawnReturnAdapterIDs must align to GPU_DAWN_RETURN_DATA_ALIGNMENT");
struct alignas(GPU_DAWN_RETURN_DATA_ALIGNMENT) DawnReturnAdapterInfo {
DawnReturnAdapterIDs adapter_ids;
char deserialized_buffer[];
};
static_assert(offsetof(DawnReturnAdapterInfo, deserialized_buffer) %
GPU_DAWN_RETURN_DATA_ALIGNMENT ==
0,
"The offset of deserialized_buffer must align to "
"GPU_DAWN_RETURN_DATA_ALIGNMENT");
// Command buffer is GPU_COMMAND_BUFFER_ENTRY_ALIGNMENT byte aligned.
#pragma pack(push, 4)
static_assert(GPU_COMMAND_BUFFER_ENTRY_ALIGNMENT == 4,
......
......@@ -176,25 +176,32 @@ struct RequestAdapter {
void SetHeader() { header.SetCmd<ValueType>(); }
void Init(uint32_t _power_preference) {
void Init(uint32_t _request_adapter_serial, uint32_t _power_preference) {
SetHeader();
request_adapter_serial = _request_adapter_serial;
power_preference = _power_preference;
}
void* Set(void* cmd, uint32_t _power_preference) {
static_cast<ValueType*>(cmd)->Init(_power_preference);
void* Set(void* cmd,
uint32_t _request_adapter_serial,
uint32_t _power_preference) {
static_cast<ValueType*>(cmd)->Init(_request_adapter_serial,
_power_preference);
return NextCmdAddress<ValueType>(cmd);
}
gpu::CommandHeader header;
uint32_t request_adapter_serial;
uint32_t power_preference;
};
static_assert(sizeof(RequestAdapter) == 8,
"size of RequestAdapter should be 8");
static_assert(sizeof(RequestAdapter) == 12,
"size of RequestAdapter should be 12");
static_assert(offsetof(RequestAdapter, header) == 0,
"offset of RequestAdapter header should be 0");
static_assert(offsetof(RequestAdapter, power_preference) == 4,
"offset of RequestAdapter power_preference should be 4");
static_assert(offsetof(RequestAdapter, request_adapter_serial) == 4,
"offset of RequestAdapter request_adapter_serial should be 4");
static_assert(offsetof(RequestAdapter, power_preference) == 8,
"offset of RequestAdapter power_preference should be 8");
#endif // GPU_COMMAND_BUFFER_COMMON_WEBGPU_CMD_FORMAT_AUTOGEN_H_
......@@ -81,11 +81,13 @@ TEST_F(WebGPUFormatTest, DissociateMailbox) {
TEST_F(WebGPUFormatTest, RequestAdapter) {
cmds::RequestAdapter& cmd = *GetBufferAs<cmds::RequestAdapter>();
void* next_cmd = cmd.Set(&cmd, static_cast<uint32_t>(11));
void* next_cmd =
cmd.Set(&cmd, static_cast<uint32_t>(11), static_cast<uint32_t>(12));
EXPECT_EQ(static_cast<uint32_t>(cmds::RequestAdapter::kCmdId),
cmd.header.command);
EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
EXPECT_EQ(static_cast<uint32_t>(11), cmd.power_preference);
EXPECT_EQ(static_cast<uint32_t>(11), cmd.request_adapter_serial);
EXPECT_EQ(static_cast<uint32_t>(12), cmd.power_preference);
CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
}
......
......@@ -12,6 +12,7 @@
#define GPU_COMMAND_BUFFER_SERVICE_WEBGPU_CMD_VALIDATION_IMPLEMENTATION_AUTOGEN_H_
static const PowerPreference valid_power_preference_table[] = {
PowerPreference::kDefault,
PowerPreference::kHighPerformance,
PowerPreference::kLowPower,
};
......
......@@ -45,6 +45,9 @@ class WireServerCommandSerializer : public dawn_wire::CommandSerializer {
~WireServerCommandSerializer() override = default;
void* GetCmdSpace(size_t size) final;
bool Flush() final;
void SendAdapterProperties(uint32_t request_adapter_serial,
uint32_t adapter_server_id,
const dawn_native::Adapter& adapter);
private:
DecoderClient* client_;
......@@ -107,12 +110,48 @@ bool WireServerCommandSerializer::Flush() {
return true;
}
void WireServerCommandSerializer::SendAdapterProperties(
uint32_t request_adapter_serial,
uint32_t adapter_service_id,
const dawn_native::Adapter& adapter) {
WGPUDeviceProperties adapter_properties = adapter.GetAdapterProperties();
size_t serialized_adapter_properties_size =
dawn_wire::SerializedWGPUDevicePropertiesSize(&adapter_properties);
std::vector<char> serialized_buffer(sizeof(cmds::DawnReturnDataHeader) +
sizeof(cmds::DawnReturnAdapterIDs) +
serialized_adapter_properties_size);
// Set Dawn return data header
reinterpret_cast<cmds::DawnReturnDataHeader*>(serialized_buffer.data())
->return_data_type = DawnReturnDataType::kRequestedDawnAdapterProperties;
// Set adapter ids
cmds::DawnReturnAdapterInfo* return_adapter_info =
reinterpret_cast<cmds::DawnReturnAdapterInfo*>(
serialized_buffer.data() + sizeof(cmds::DawnReturnDataHeader));
return_adapter_info->adapter_ids.request_adapter_serial =
request_adapter_serial;
return_adapter_info->adapter_ids.adapter_service_id = adapter_service_id;
// Set serialized adapter properties
dawn_wire::SerializeWGPUDeviceProperties(
&adapter_properties, return_adapter_info->deserialized_buffer);
client_->HandleReturnData(base::make_span(
reinterpret_cast<const uint8_t*>(serialized_buffer.data()),
serialized_buffer.size()));
}
dawn_native::DeviceType PowerPreferenceToDawnDeviceType(
PowerPreference power_preference) {
switch (power_preference) {
case PowerPreference::kLowPower:
return dawn_native::DeviceType::IntegratedGPU;
case PowerPreference::kHighPerformance:
// Currently for simplicity we always choose discrete GPU as the device
// related to default power preference.
case PowerPreference::kDefault:
return dawn_native::DeviceType::DiscreteGPU;
default:
NOTREACHED();
......@@ -351,10 +390,9 @@ class WebGPUDecoderImpl final : public WebGPUDecoder {
void DiscoverAdapters();
dawn_native::Adapter GetPreferredAdapter(
PowerPreference power_preference) const;
int32_t GetPreferredAdapterIndex(PowerPreference power_preference) const;
error::Error InitDawnDeviceAndSetWireServer(dawn_native::Adapter* adapter);
error::Error InitDawnDeviceAndSetWireServer(int32_t requested_adapter_index);
std::unique_ptr<SharedImageRepresentationFactory>
shared_image_representation_factory_;
......@@ -434,8 +472,8 @@ ContextResult WebGPUDecoderImpl::Initialize() {
}
error::Error WebGPUDecoderImpl::InitDawnDeviceAndSetWireServer(
dawn_native::Adapter* adapter) {
DCHECK(adapter != nullptr && (*adapter));
int32_t requested_adapter_index) {
DCHECK_LE(0, requested_adapter_index);
// TODO(jiawei.shao@intel.com): support multiple Dawn devices.
if (wgpu_device_ != nullptr) {
......@@ -443,7 +481,9 @@ error::Error WebGPUDecoderImpl::InitDawnDeviceAndSetWireServer(
return error::kNoError;
}
wgpu_device_ = adapter->CreateDevice();
DCHECK_LT(static_cast<size_t>(requested_adapter_index),
dawn_adapters_.size());
wgpu_device_ = dawn_adapters_[requested_adapter_index].CreateDevice();
if (wgpu_device_ == nullptr) {
return error::kLostContext;
}
......@@ -484,32 +524,33 @@ void WebGPUDecoderImpl::DiscoverAdapters() {
}
}
dawn_native::Adapter WebGPUDecoderImpl::GetPreferredAdapter(
int32_t WebGPUDecoderImpl::GetPreferredAdapterIndex(
PowerPreference power_preference) const {
dawn_native::DeviceType preferred_device_type =
PowerPreferenceToDawnDeviceType(power_preference);
dawn_native::Adapter discrete_gpu_adapter = {};
dawn_native::Adapter integrated_gpu_adapter = {};
dawn_native::Adapter cpu_adapter = {};
dawn_native::Adapter unknown_adapter = {};
int32_t discrete_gpu_adapter_index = -1;
int32_t integrated_gpu_adapter_index = -1;
int32_t cpu_adapter_index = -1;
int32_t unknown_adapter_index = -1;
for (const dawn_native::Adapter& adapter : dawn_adapters_) {
for (int32_t i = 0; i < static_cast<int32_t>(dawn_adapters_.size()); ++i) {
const dawn_native::Adapter& adapter = dawn_adapters_[i];
if (adapter.GetDeviceType() == preferred_device_type) {
return adapter;
return i;
}
switch (adapter.GetDeviceType()) {
case dawn_native::DeviceType::DiscreteGPU:
discrete_gpu_adapter = adapter;
discrete_gpu_adapter_index = i;
break;
case dawn_native::DeviceType::IntegratedGPU:
integrated_gpu_adapter = adapter;
integrated_gpu_adapter_index = i;
break;
case dawn_native::DeviceType::CPU:
cpu_adapter = adapter;
cpu_adapter_index = i;
break;
case dawn_native::DeviceType::Unknown:
unknown_adapter = adapter;
unknown_adapter_index = i;
break;
default:
NOTREACHED();
......@@ -518,19 +559,19 @@ dawn_native::Adapter WebGPUDecoderImpl::GetPreferredAdapter(
}
// For now, we always prefer the discrete GPU
if (discrete_gpu_adapter) {
return discrete_gpu_adapter;
if (discrete_gpu_adapter_index >= 0) {
return discrete_gpu_adapter_index;
}
if (integrated_gpu_adapter) {
return integrated_gpu_adapter;
if (integrated_gpu_adapter_index >= 0) {
return integrated_gpu_adapter_index;
}
if (cpu_adapter) {
return cpu_adapter;
if (cpu_adapter_index >= 0) {
return cpu_adapter_index;
}
if (unknown_adapter) {
return unknown_adapter;
if (unknown_adapter_index >= 0) {
return unknown_adapter_index;
}
return dawn_native::Adapter();
return -1;
}
const char* WebGPUDecoderImpl::GetCommandName(unsigned int command_id) const {
......@@ -614,14 +655,22 @@ error::Error WebGPUDecoderImpl::HandleRequestAdapter(
PowerPreference power_preference =
static_cast<PowerPreference>(c.power_preference);
dawn_native::Adapter requested_adapter =
GetPreferredAdapter(power_preference);
if (!requested_adapter) {
int32_t requested_adapter_index = GetPreferredAdapterIndex(power_preference);
if (requested_adapter_index < 0) {
return error::kLostContext;
}
// Currently we treat the index of the adapter in dawn_adapters_ as the id of
// the adapter in the server side.
DCHECK_LT(static_cast<size_t>(requested_adapter_index),
dawn_adapters_.size());
const dawn_native::Adapter& adapter = dawn_adapters_[requested_adapter_index];
wire_serializer_->SendAdapterProperties(
static_cast<uint32_t>(c.request_adapter_serial),
static_cast<uint32_t>(requested_adapter_index), adapter);
// TODO(jiawei.shao@intel.com): support creating device with device descriptor
return InitDawnDeviceAndSetWireServer(&requested_adapter);
return InitDawnDeviceAndSetWireServer(requested_adapter_index);
}
error::Error WebGPUDecoderImpl::HandleDawnCommands(
......
......@@ -49,14 +49,17 @@ class WebGPUDecoderTest : public ::testing::Test {
gl_context_->MakeCurrent(gl_surface_.get());
decoder_client_.reset(new FakeDecoderClient());
command_buffer_service_.reset(new FakeCommandBufferServiceBase());
decoder_.reset(WebGPUDecoder::Create(nullptr, command_buffer_service_.get(),
&shared_image_manager_, nullptr,
&outputter_));
decoder_.reset(WebGPUDecoder::Create(
decoder_client_.get(), command_buffer_service_.get(),
&shared_image_manager_, nullptr, &outputter_));
ASSERT_EQ(decoder_->Initialize(), ContextResult::kSuccess);
constexpr uint32_t kadapter_client_id = 0;
cmds::RequestAdapter requestAdapterCmd;
requestAdapterCmd.Init(
kadapter_client_id,
static_cast<uint32_t>(webgpu::PowerPreference::kHighPerformance));
ASSERT_EQ(error::kNoError, ExecuteCmd(requestAdapterCmd));
......@@ -108,6 +111,7 @@ class WebGPUDecoderTest : public ::testing::Test {
protected:
std::unique_ptr<FakeCommandBufferServiceBase> command_buffer_service_;
std::unique_ptr<WebGPUDecoder> decoder_;
std::unique_ptr<FakeDecoderClient> decoder_client_;
gles2::TraceOutputter outputter_;
SharedImageManager shared_image_manager_;
std::unique_ptr<SharedImageFactory> factory_;
......
......@@ -19,6 +19,13 @@
namespace gpu {
namespace {
void OnRequestAdapterCallback(uint32_t adapter_server_id,
const WGPUDeviceProperties& properties) {}
} // anonymous namespace
WebGPUTest::Options::Options() = default;
WebGPUTest::WebGPUTest() = default;
......@@ -84,7 +91,9 @@ void WebGPUTest::Initialize(const Options& options) {
image_factory, channel_manager);
ASSERT_EQ(result, ContextResult::kSuccess);
webgpu()->RequestAdapter(webgpu::PowerPreference::kHighPerformance);
ASSERT_TRUE(
webgpu()->RequestAdapterAsync(webgpu::PowerPreference::kDefault,
base::Bind(&OnRequestAdapterCallback)));
DawnProcTable procs = webgpu()->GetProcs();
dawnProcSetProcs(&procs);
......
......@@ -9,4 +9,4 @@
GL_APICALL void GL_APIENTRY wgDawnCommands (const char* commands, size_t size);
GL_APICALL void GL_APIENTRY wgAssociateMailbox (GLuint device_id, GLuint device_generation, GLuint id, GLuint generation, GLuint usage, const GLbyte* mailbox);
GL_APICALL void GL_APIENTRY wgDissociateMailbox (GLuint texture_id, GLuint texture_generation);
GL_APICALL void GL_APIENTRY wgRequestAdapter (EnumClassPowerPreference power_preference = PowerPreference::kHighPerformance);
GL_APICALL void GL_APIENTRY wgRequestAdapter (GLuint request_adapter_serial, EnumClassPowerPreference power_preference = PowerPreference::kDefault);
......@@ -10,6 +10,7 @@
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/public/platform/web_graphics_context_3d_provider.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
#include "third_party/blink/renderer/core/dom/dom_exception.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
#include "third_party/blink/renderer/core/inspector/console_message.h"
#include "third_party/blink/renderer/modules/webgpu/gpu_adapter.h"
......@@ -100,6 +101,14 @@ void GPU::ContextDestroyed(ExecutionContext* execution_context) {
dawn_control_client_->Destroy();
}
void GPU::OnRequestAdapterCallback(ScriptPromiseResolver* resolver,
uint32_t adapter_server_id,
const WGPUDeviceProperties& properties) {
GPUAdapter* adapter = GPUAdapter::Create("Default", adapter_server_id,
properties, dawn_control_client_);
resolver->Resolve(adapter);
}
ScriptPromise GPU::requestAdapter(ScriptState* script_state,
const GPURequestAdapterOptions* options) {
auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
......@@ -111,10 +120,15 @@ ScriptPromise GPU::requestAdapter(ScriptState* script_state,
if (options->powerPreference() == "low-power") {
power_preference = gpu::webgpu::PowerPreference::kLowPower;
}
GPUAdapter* adapter =
GPUAdapter::Create("Default", power_preference, dawn_control_client_);
resolver->Resolve(adapter);
if (!dawn_control_client_->GetInterface()->RequestAdapterAsync(
power_preference,
WTF::Bind(&GPU::OnRequestAdapterCallback, WrapPersistent(this),
WrapPersistent(resolver)))) {
resolver->Reject(MakeGarbageCollected<DOMException>(
DOMExceptionCode::kOperationError, "Fail to request GPUAdapter"));
}
return promise;
}
......
......@@ -11,9 +11,12 @@
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
struct WGPUDeviceProperties;
namespace blink {
class GPURequestAdapterOptions;
class ScriptPromiseResolver;
class ScriptState;
class WebGraphicsContext3DProvider;
class DawnControlClientHolder;
......@@ -39,6 +42,10 @@ class GPU final : public ScriptWrappable, public ContextLifecycleObserver {
const GPURequestAdapterOptions* options);
private:
void OnRequestAdapterCallback(ScriptPromiseResolver* resolver,
uint32_t adapter_server_id,
const WGPUDeviceProperties& properties);
scoped_refptr<DawnControlClientHolder> dawn_control_client_;
DISALLOW_COPY_AND_ASSIGN(GPU);
......
......@@ -13,24 +13,27 @@ namespace blink {
// static
GPUAdapter* GPUAdapter::Create(
const String& name,
gpu::webgpu::PowerPreference power_preference,
uint32_t adapter_service_id,
const WGPUDeviceProperties& properties,
scoped_refptr<DawnControlClientHolder> dawn_control_client) {
return MakeGarbageCollected<GPUAdapter>(name, power_preference,
return MakeGarbageCollected<GPUAdapter>(name, adapter_service_id, properties,
std::move(dawn_control_client));
}
GPUAdapter::GPUAdapter(
const String& name,
gpu::webgpu::PowerPreference power_preference,
uint32_t adapter_service_id,
const WGPUDeviceProperties& properties,
scoped_refptr<DawnControlClientHolder> dawn_control_client)
: DawnObjectBase(dawn_control_client), name_(name) {
dawn_control_client->GetInterface()->RequestAdapter(power_preference);
// TODO(jiawei.shao@intel.com): add GPUExtensions as a member of GPUAdapter
}
const String& GPUAdapter::name() const {
return name_;
}
// TODO(jiawei.shao@intel.com) request device with adapter_server_id
ScriptPromise GPUAdapter::requestDevice(ScriptState* script_state,
const GPUDeviceDescriptor* descriptor) {
auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
......
......@@ -23,10 +23,12 @@ class GPUAdapter final : public ScriptWrappable, public DawnObjectBase {
public:
static GPUAdapter* Create(
const String& name,
gpu::webgpu::PowerPreference power_preference,
uint32_t adapter_service_id,
const WGPUDeviceProperties& properties,
scoped_refptr<DawnControlClientHolder> dawn_control_client);
GPUAdapter(const String& name,
gpu::webgpu::PowerPreference power_preference,
uint32_t adapter_service_id,
const WGPUDeviceProperties& properties,
scoped_refptr<DawnControlClientHolder> dawn_control_client);
const String& name() const;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment