Commit db26d1d5 authored by Jiawei Shao's avatar Jiawei Shao Committed by Commit Bot

WebGPU: Encapsulate WGPUDevice and wire server into one object

This patch puts WGPUDevice, wire_server_ and wire_seralizer_ and all the
operations related to these objects into one object
DawnDeviceAndWireServer as one of the preparations of supporting
multiple devices in one WebGPU context.

BUG=chromium:996713

Change-Id: I65fe5abe54a79394ca7d68a2c0ea8f41b0e1ac93
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2050324Reviewed-by: default avatarKai Ninomiya <kainino@chromium.org>
Reviewed-by: default avatarZhenyao Mo <zmo@chromium.org>
Reviewed-by: default avatarAustin Eng <enga@chromium.org>
Commit-Queue: Jiawei Shao <jiawei.shao@intel.com>
Cr-Commit-Position: refs/heads/master@{#742463}
parent ac63420b
...@@ -132,6 +132,80 @@ dawn_native::DeviceType PowerPreferenceToDawnDeviceType( ...@@ -132,6 +132,80 @@ dawn_native::DeviceType PowerPreferenceToDawnDeviceType(
} }
} }
class DawnDeviceAndWireServer {
public:
DawnDeviceAndWireServer(
DecoderClient* client,
WGPUDevice wgpu_device,
DawnServiceMemoryTransferService* memory_transfer_service);
~DawnDeviceAndWireServer();
WGPUDevice GetWGPUDevice() const;
void PerformPollingWork();
error::Error HandleDawnCommands(const volatile char* dawn_commands,
size_t size);
bool InjectTexture(WGPUTexture texture, uint32_t id, uint32_t generation);
private:
WGPUDevice wgpu_device_ = nullptr;
std::unique_ptr<dawn_wire::WireServer> wire_server_;
std::unique_ptr<WireServerCommandSerializer> wire_serializer_;
const DawnProcTable dawn_procs_;
};
DawnDeviceAndWireServer::DawnDeviceAndWireServer(
DecoderClient* client,
WGPUDevice wgpu_device,
DawnServiceMemoryTransferService* memory_transfer_service)
: wgpu_device_(wgpu_device),
wire_serializer_(std::make_unique<WireServerCommandSerializer>(client)),
dawn_procs_(dawn_native::GetProcs()) {
DCHECK(client);
DCHECK(wgpu_device);
DCHECK(memory_transfer_service);
dawn_wire::WireServerDescriptor descriptor = {};
descriptor.device = wgpu_device_;
descriptor.procs = &dawn_procs_;
descriptor.serializer = wire_serializer_.get();
descriptor.memoryTransferService = memory_transfer_service;
wire_server_ = std::make_unique<dawn_wire::WireServer>(descriptor);
}
DawnDeviceAndWireServer::~DawnDeviceAndWireServer() {
// Reset the wire server first so all objects are destroyed before the
// device.
// TODO(enga): Handle Device/Context lost.
wire_server_ = nullptr;
dawn_procs_.deviceRelease(wgpu_device_);
}
WGPUDevice DawnDeviceAndWireServer::GetWGPUDevice() const {
return wgpu_device_;
}
void DawnDeviceAndWireServer::PerformPollingWork() {
dawn_procs_.deviceTick(wgpu_device_);
wire_serializer_->Flush();
}
error::Error DawnDeviceAndWireServer::HandleDawnCommands(
const volatile char* dawn_commands,
size_t size) {
if (!wire_server_->HandleCommands(dawn_commands, size)) {
NOTREACHED();
return error::kLostContext;
}
wire_serializer_->Flush();
return error::kNoError;
}
bool DawnDeviceAndWireServer::InjectTexture(WGPUTexture texture,
uint32_t id,
uint32_t generation) {
return wire_server_->InjectTexture(texture, id, generation);
}
} // namespace } // namespace
class WebGPUDecoderImpl final : public WebGPUDecoder { class WebGPUDecoderImpl final : public WebGPUDecoder {
...@@ -217,10 +291,8 @@ class WebGPUDecoderImpl final : public WebGPUDecoder { ...@@ -217,10 +291,8 @@ class WebGPUDecoderImpl final : public WebGPUDecoder {
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("gpu.dawn"), TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("gpu.dawn"),
"WebGPUDecoderImpl::PerformPollingWork"); "WebGPUDecoderImpl::PerformPollingWork");
// TODO(jiawei.shao@intel.com): support multiple Dawn devices. // TODO(jiawei.shao@intel.com): support multiple Dawn devices.
if (wgpu_device_) { if (dawn_device_and_wire_server_) {
dawn_procs_.deviceTick(wgpu_device_); dawn_device_and_wire_server_->PerformPollingWork();
DCHECK(wire_serializer_);
wire_serializer_->Flush();
} }
} }
...@@ -393,14 +465,11 @@ class WebGPUDecoderImpl final : public WebGPUDecoder { ...@@ -393,14 +465,11 @@ class WebGPUDecoderImpl final : public WebGPUDecoder {
std::unique_ptr<SharedImageRepresentationAndAccess>> std::unique_ptr<SharedImageRepresentationAndAccess>>
associated_shared_image_map_; associated_shared_image_map_;
std::unique_ptr<DawnDeviceAndWireServer> dawn_device_and_wire_server_;
std::unique_ptr<dawn_platform::Platform> dawn_platform_; std::unique_ptr<dawn_platform::Platform> dawn_platform_;
std::unique_ptr<WireServerCommandSerializer> wire_serializer_;
std::unique_ptr<DawnServiceMemoryTransferService> memory_transfer_service_; std::unique_ptr<DawnServiceMemoryTransferService> memory_transfer_service_;
std::unique_ptr<dawn_native::Instance> dawn_instance_; std::unique_ptr<dawn_native::Instance> dawn_instance_;
std::vector<dawn_native::Adapter> dawn_adapters_; std::vector<dawn_native::Adapter> dawn_adapters_;
DawnProcTable dawn_procs_;
WGPUDevice wgpu_device_ = nullptr;
std::unique_ptr<dawn_wire::WireServer> wire_server_;
DISALLOW_COPY_AND_ASSIGN(WebGPUDecoderImpl); DISALLOW_COPY_AND_ASSIGN(WebGPUDecoderImpl);
}; };
...@@ -440,21 +509,13 @@ WebGPUDecoderImpl::WebGPUDecoderImpl( ...@@ -440,21 +509,13 @@ WebGPUDecoderImpl::WebGPUDecoderImpl(
memory_tracker)), memory_tracker)),
dawn_platform_(new DawnPlatform()), dawn_platform_(new DawnPlatform()),
memory_transfer_service_(new DawnServiceMemoryTransferService(this)), memory_transfer_service_(new DawnServiceMemoryTransferService(this)),
dawn_instance_(new dawn_native::Instance()), dawn_instance_(new dawn_native::Instance()) {
dawn_procs_(dawn_native::GetProcs()) {
dawn_instance_->SetPlatform(dawn_platform_.get()); dawn_instance_->SetPlatform(dawn_platform_.get());
} }
WebGPUDecoderImpl::~WebGPUDecoderImpl() { WebGPUDecoderImpl::~WebGPUDecoderImpl() {
associated_shared_image_map_.clear(); associated_shared_image_map_.clear();
dawn_device_and_wire_server_ = nullptr;
if (wgpu_device_ != nullptr) {
// Reset the wire server first so all objects are destroyed before the
// device.
// TODO(enga): Handle Device/Context lost.
wire_server_ = nullptr;
dawn_procs_.deviceRelease(wgpu_device_);
}
} }
ContextResult WebGPUDecoderImpl::Initialize() { ContextResult WebGPUDecoderImpl::Initialize() {
...@@ -468,9 +529,7 @@ error::Error WebGPUDecoderImpl::InitDawnDeviceAndSetWireServer( ...@@ -468,9 +529,7 @@ error::Error WebGPUDecoderImpl::InitDawnDeviceAndSetWireServer(
DCHECK_LE(0, requested_adapter_index); DCHECK_LE(0, requested_adapter_index);
// TODO(jiawei.shao@intel.com): support multiple Dawn devices. // TODO(jiawei.shao@intel.com): support multiple Dawn devices.
if (wgpu_device_ != nullptr) { if (dawn_device_and_wire_server_ != nullptr) {
DCHECK(wire_server_);
DCHECK(wire_serializer_);
return error::kNoError; return error::kNoError;
} }
...@@ -482,21 +541,14 @@ error::Error WebGPUDecoderImpl::InitDawnDeviceAndSetWireServer( ...@@ -482,21 +541,14 @@ error::Error WebGPUDecoderImpl::InitDawnDeviceAndSetWireServer(
device_descriptor.requiredExtensions.push_back("texture_compression_bc"); device_descriptor.requiredExtensions.push_back("texture_compression_bc");
} }
wgpu_device_ = WGPUDevice wgpu_device =
dawn_adapters_[requested_adapter_index].CreateDevice(&device_descriptor); dawn_adapters_[requested_adapter_index].CreateDevice(&device_descriptor);
if (wgpu_device_ == nullptr) { if (wgpu_device == nullptr) {
return error::kInvalidArguments; return error::kInvalidArguments;
} }
wire_serializer_ = std::make_unique<WireServerCommandSerializer>(client()); dawn_device_and_wire_server_ = std::make_unique<DawnDeviceAndWireServer>(
client(), wgpu_device, memory_transfer_service_.get());
dawn_wire::WireServerDescriptor descriptor = {};
descriptor.device = wgpu_device_;
descriptor.procs = &dawn_procs_;
descriptor.serializer = wire_serializer_.get();
descriptor.memoryTransferService = memory_transfer_service_.get();
wire_server_ = std::make_unique<dawn_wire::WireServer>(descriptor);
return error::kNoError; return error::kNoError;
} }
...@@ -506,14 +558,14 @@ void WebGPUDecoderImpl::DiscoverAdapters() { ...@@ -506,14 +558,14 @@ void WebGPUDecoderImpl::DiscoverAdapters() {
std::vector<dawn_native::Adapter> adapters = dawn_instance_->GetAdapters(); std::vector<dawn_native::Adapter> adapters = dawn_instance_->GetAdapters();
for (const dawn_native::Adapter& adapter : adapters) { for (const dawn_native::Adapter& adapter : adapters) {
#if defined(OS_WIN) #if defined(OS_WIN)
// On Windows 10, we pick D3D12 backend because the rest of Chromium renders // On Windows 10, we pick D3D12 backend because the rest of Chromium renders
// with D3D11. By the same token, we pick the first adapter because ANGLE also // with D3D11. By the same token, we pick the first adapter because ANGLE
// picks the first adapter. Later, we'll need to centralize adapter picking // also picks the first adapter. Later, we'll need to centralize adapter
// such that Dawn and ANGLE are told which adapter to use by Chromium. If we // picking such that Dawn and ANGLE are told which adapter to use by
// decide to handle multiple adapters, code on the Chromium side will need to // Chromium. If we decide to handle multiple adapters, code on the Chromium
// change to do appropriate cross adapter copying to make this happen, either // side will need to change to do appropriate cross adapter copying to make
// manually or by using DirectComposition. // this happen, either manually or by using DirectComposition.
if (adapter.GetBackendType() == dawn_native::BackendType::D3D12) { if (adapter.GetBackendType() == dawn_native::BackendType::D3D12) {
#else #else
if (adapter.GetBackendType() != dawn_native::BackendType::Null && if (adapter.GetBackendType() != dawn_native::BackendType::Null &&
adapter.GetBackendType() != dawn_native::BackendType::OpenGL) { adapter.GetBackendType() != dawn_native::BackendType::OpenGL) {
...@@ -522,7 +574,7 @@ void WebGPUDecoderImpl::DiscoverAdapters() { ...@@ -522,7 +574,7 @@ void WebGPUDecoderImpl::DiscoverAdapters() {
#if defined(OS_WIN) #if defined(OS_WIN)
break; break;
#endif #endif
} }
} }
} }
...@@ -780,13 +832,7 @@ error::Error WebGPUDecoderImpl::HandleDawnCommands( ...@@ -780,13 +832,7 @@ error::Error WebGPUDecoderImpl::HandleDawnCommands(
TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("gpu.dawn"), TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("gpu.dawn"),
"WebGPUDecoderImpl::HandleDawnCommands", "bytes", size); "WebGPUDecoderImpl::HandleDawnCommands", "bytes", size);
if (!wire_server_->HandleCommands(shm_commands, size)) { return dawn_device_and_wire_server_->HandleDawnCommands(shm_commands, size);
NOTREACHED();
return error::kLostContext;
}
DCHECK(wire_serializer_);
wire_serializer_->Flush();
return error::kNoError;
} }
error::Error WebGPUDecoderImpl::HandleAssociateMailboxImmediate( error::Error WebGPUDecoderImpl::HandleAssociateMailboxImmediate(
...@@ -834,8 +880,10 @@ error::Error WebGPUDecoderImpl::HandleAssociateMailboxImmediate( ...@@ -834,8 +880,10 @@ error::Error WebGPUDecoderImpl::HandleAssociateMailboxImmediate(
WGPUTextureUsage wgpu_usage = static_cast<WGPUTextureUsage>(usage); WGPUTextureUsage wgpu_usage = static_cast<WGPUTextureUsage>(usage);
// Create a WGPUTexture from the mailbox. // Create a WGPUTexture from the mailbox.
WGPUDevice wgpu_device = dawn_device_and_wire_server_->GetWGPUDevice();
DCHECK(wgpu_device);
std::unique_ptr<SharedImageRepresentationDawn> shared_image = std::unique_ptr<SharedImageRepresentationDawn> shared_image =
shared_image_representation_factory_->ProduceDawn(mailbox, wgpu_device_); shared_image_representation_factory_->ProduceDawn(mailbox, wgpu_device);
if (!shared_image) { if (!shared_image) {
DLOG(ERROR) << "AssociateMailbox: Couldn't produce shared image"; DLOG(ERROR) << "AssociateMailbox: Couldn't produce shared image";
return error::kInvalidArguments; return error::kInvalidArguments;
...@@ -854,8 +902,8 @@ error::Error WebGPUDecoderImpl::HandleAssociateMailboxImmediate( ...@@ -854,8 +902,8 @@ error::Error WebGPUDecoderImpl::HandleAssociateMailboxImmediate(
// Inject the texture in the dawn_wire::Server and remember which shared image // Inject the texture in the dawn_wire::Server and remember which shared image
// it is associated with. // it is associated with.
if (!wire_server_->InjectTexture(shared_image_access->texture(), id, if (!dawn_device_and_wire_server_->InjectTexture(
generation)) { shared_image_access->texture(), id, generation)) {
DLOG(ERROR) << "AssociateMailbox: Invalid texture ID"; DLOG(ERROR) << "AssociateMailbox: Invalid texture ID";
return error::kInvalidArguments; return error::kInvalidArguments;
} }
......
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