зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1795311 - Use the new shmem classes in the WebGPU buffer impl. r=jgilbert
Depends on D159398 Differential Revision: https://phabricator.services.mozilla.com/D159399
This commit is contained in:
Родитель
a1971c2e74
Коммит
84411fce11
|
@ -43,9 +43,11 @@ NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(Buffer)
|
|||
NS_IMPL_CYCLE_COLLECTION_TRACE_END
|
||||
|
||||
Buffer::Buffer(Device* const aParent, RawId aId, BufferAddress aSize,
|
||||
uint32_t aUsage, ipc::Shmem&& aShmem)
|
||||
: ChildOf(aParent), mId(aId), mSize(aSize), mUsage(aUsage), mShmem(aShmem) {
|
||||
uint32_t aUsage, ipc::WritableSharedMemoryMapping&& aShmem)
|
||||
: ChildOf(aParent), mId(aId), mSize(aSize), mUsage(aUsage) {
|
||||
mozilla::HoldJSObjects(this);
|
||||
mShmem =
|
||||
std::make_shared<ipc::WritableSharedMemoryMapping>(std::move(aShmem));
|
||||
MOZ_ASSERT(mParent);
|
||||
}
|
||||
|
||||
|
@ -58,14 +60,16 @@ already_AddRefed<Buffer> Buffer::Create(Device* aDevice, RawId aDeviceId,
|
|||
const dom::GPUBufferDescriptor& aDesc,
|
||||
ErrorResult& aRv) {
|
||||
if (aDevice->IsLost()) {
|
||||
RefPtr<Buffer> buffer =
|
||||
new Buffer(aDevice, 0, aDesc.mSize, 0, ipc::Shmem());
|
||||
RefPtr<Buffer> buffer = new Buffer(aDevice, 0, aDesc.mSize, 0,
|
||||
ipc::WritableSharedMemoryMapping());
|
||||
return buffer.forget();
|
||||
}
|
||||
|
||||
RefPtr<WebGPUChild> actor = aDevice->GetBridge();
|
||||
|
||||
ipc::Shmem shmem;
|
||||
auto handle = ipc::UnsafeSharedMemoryHandle();
|
||||
auto mapping = ipc::WritableSharedMemoryMapping();
|
||||
|
||||
bool hasMapFlags = aDesc.mUsage & (dom::GPUBufferUsage_Binding::MAP_WRITE |
|
||||
dom::GPUBufferUsage_Binding::MAP_READ);
|
||||
if (hasMapFlags || aDesc.mMappedAtCreation) {
|
||||
|
@ -75,29 +79,28 @@ already_AddRefed<Buffer> Buffer::Create(Device* aDevice, RawId aDeviceId,
|
|||
return nullptr;
|
||||
}
|
||||
size_t size = checked.value();
|
||||
if (size == 0) {
|
||||
// Can't send zero-sized shmems.
|
||||
size = 1;
|
||||
}
|
||||
|
||||
if (!actor->AllocUnsafeShmem(size, &shmem)) {
|
||||
auto maybeShmem = ipc::UnsafeSharedMemoryHandle::CreateAndMap(size);
|
||||
|
||||
if (maybeShmem.isNothing()) {
|
||||
aRv.ThrowAbortError(
|
||||
nsPrintfCString("Unable to allocate shmem of size %" PRIuPTR, size));
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
handle = std::move(maybeShmem.ref().first);
|
||||
mapping = std::move(maybeShmem.ref().second);
|
||||
|
||||
MOZ_RELEASE_ASSERT(mapping.Size() >= size);
|
||||
|
||||
// zero out memory
|
||||
memset(shmem.get<uint8_t>(), 0, size);
|
||||
memset(mapping.Bytes().data(), 0, size);
|
||||
}
|
||||
|
||||
MaybeShmem maybeShmem = mozilla::null_t();
|
||||
if (shmem.IsReadable()) {
|
||||
maybeShmem = shmem;
|
||||
}
|
||||
RawId id = actor->DeviceCreateBuffer(aDeviceId, aDesc, std::move(maybeShmem));
|
||||
RawId id = actor->DeviceCreateBuffer(aDeviceId, aDesc, std::move(handle));
|
||||
|
||||
RefPtr<Buffer> buffer =
|
||||
new Buffer(aDevice, id, aDesc.mSize, aDesc.mUsage, std::move(shmem));
|
||||
new Buffer(aDevice, id, aDesc.mSize, aDesc.mUsage, std::move(mapping));
|
||||
if (aDesc.mMappedAtCreation) {
|
||||
// Mapped at creation's raison d'être is write access, since the buffer is
|
||||
// being created and there isn't anything interesting to read in it yet.
|
||||
|
@ -212,10 +215,17 @@ already_AddRefed<dom::Promise> Buffer::MapAsync(
|
|||
return promise.forget();
|
||||
}
|
||||
|
||||
static void ExternalBufferFreeCallback(void* aContents, void* aUserData) {
|
||||
Unused << aContents;
|
||||
auto shm = static_cast<std::shared_ptr<ipc::WritableSharedMemoryMapping>*>(
|
||||
aUserData);
|
||||
delete shm;
|
||||
}
|
||||
|
||||
void Buffer::GetMappedRange(JSContext* aCx, uint64_t aOffset,
|
||||
const dom::Optional<uint64_t>& aSize,
|
||||
JS::Rooted<JSObject*>* aObject, ErrorResult& aRv) {
|
||||
if (!mMapped || !mShmem.IsReadable()) {
|
||||
if (!mMapped) {
|
||||
aRv.ThrowInvalidStateError("Buffer is not mapped");
|
||||
return;
|
||||
}
|
||||
|
@ -233,8 +243,15 @@ void Buffer::GetMappedRange(JSContext* aCx, uint64_t aOffset,
|
|||
return;
|
||||
}
|
||||
|
||||
auto* const arrayBuffer = GetDevice().CreateExternalArrayBuffer(
|
||||
aCx, checkedOffset.value(), checkedSize.value(), mShmem);
|
||||
auto offset = checkedOffset.value();
|
||||
auto size = checkedSize.value();
|
||||
auto span = mShmem->Bytes().Subspan(offset, size);
|
||||
|
||||
std::shared_ptr<ipc::WritableSharedMemoryMapping>* userData =
|
||||
new std::shared_ptr<ipc::WritableSharedMemoryMapping>(mShmem);
|
||||
auto* const arrayBuffer = JS::NewExternalArrayBuffer(
|
||||
aCx, size, span.data(), &ExternalBufferFreeCallback, userData);
|
||||
|
||||
if (!arrayBuffer) {
|
||||
aRv.NoteJSContextException(aCx);
|
||||
return;
|
||||
|
@ -293,8 +310,8 @@ void Buffer::Unmap(JSContext* aCx, ErrorResult& aRv) {
|
|||
if (!hasMapFlags) {
|
||||
// We get here if the buffer was mapped at creation without map flags.
|
||||
// It won't be possible to map the buffer again so we can get rid of
|
||||
// our shmem handle on this side. The parent side will deallocate it.
|
||||
mShmem = ipc::Shmem();
|
||||
// our shmem on this side.
|
||||
mShmem = std::make_shared<ipc::WritableSharedMemoryMapping>();
|
||||
}
|
||||
|
||||
if (!GetDevice().IsLost()) {
|
||||
|
|
|
@ -8,10 +8,11 @@
|
|||
|
||||
#include "js/RootingAPI.h"
|
||||
#include "mozilla/dom/Nullable.h"
|
||||
#include "mozilla/ipc/Shmem.h"
|
||||
#include "mozilla/webgpu/WebGPUTypes.h"
|
||||
#include "nsTArray.h"
|
||||
#include "ObjectModel.h"
|
||||
#include "mozilla/ipc/RawShmem.h"
|
||||
#include <memory>
|
||||
|
||||
namespace mozilla {
|
||||
class ErrorResult;
|
||||
|
@ -22,9 +23,6 @@ template <typename T>
|
|||
class Optional;
|
||||
} // namespace dom
|
||||
|
||||
namespace ipc {
|
||||
class Shmem;
|
||||
} // namespace ipc
|
||||
namespace webgpu {
|
||||
|
||||
class Device;
|
||||
|
@ -63,7 +61,7 @@ class Buffer final : public ObjectBase, public ChildOf<Device> {
|
|||
|
||||
private:
|
||||
Buffer(Device* const aParent, RawId aId, BufferAddress aSize, uint32_t aUsage,
|
||||
ipc::Shmem&& aShmem);
|
||||
ipc::WritableSharedMemoryMapping&& aShmem);
|
||||
virtual ~Buffer();
|
||||
Device& GetDevice() { return *mParent; }
|
||||
void Drop();
|
||||
|
@ -83,7 +81,7 @@ class Buffer final : public ObjectBase, public ChildOf<Device> {
|
|||
RefPtr<dom::Promise> mMapRequest;
|
||||
// mShmem does not point to a shared memory segment if the buffer is not
|
||||
// mappable.
|
||||
ipc::Shmem mShmem;
|
||||
std::shared_ptr<ipc::WritableSharedMemoryMapping> mShmem;
|
||||
};
|
||||
|
||||
} // namespace webgpu
|
||||
|
|
|
@ -13,6 +13,7 @@ using dom::GPUCommandBufferDescriptor from "mozilla/dom/WebGPUBinding.h";
|
|||
using dom::GPUBufferDescriptor from "mozilla/dom/WebGPUBinding.h";
|
||||
using MaybeScopedError from "mozilla/webgpu/WebGPUTypes.h";
|
||||
using WebGPUCompilationMessage from "mozilla/webgpu/WebGPUTypes.h";
|
||||
[MoveOnly] using class mozilla::ipc::UnsafeSharedMemoryHandle from "mozilla/ipc/RawShmem.h";
|
||||
|
||||
include "mozilla/ipc/ByteBufUtils.h";
|
||||
include "mozilla/layers/LayersMessageUtils.h";
|
||||
|
@ -40,7 +41,7 @@ parent:
|
|||
async CommandEncoderAction(RawId selfId, RawId aDeviceId, ByteBuf buf);
|
||||
async BumpImplicitBindGroupLayout(RawId pipelineId, bool isCompute, uint32_t index, RawId assignId);
|
||||
|
||||
async CreateBuffer(RawId deviceId, RawId bufferId, GPUBufferDescriptor desc, MaybeShmem shmem);
|
||||
async CreateBuffer(RawId deviceId, RawId bufferId, GPUBufferDescriptor desc, UnsafeSharedMemoryHandle shm);
|
||||
|
||||
async InstanceRequestAdapter(GPURequestAdapterOptions options, RawId[] ids) returns (ByteBuf byteBuf);
|
||||
async AdapterRequestDevice(RawId selfId, ByteBuf buf, RawId newId) returns (bool success);
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include "DeviceLostInfo.h"
|
||||
#include "Sampler.h"
|
||||
#include "CompilationInfo.h"
|
||||
#include "mozilla/ipc/RawShmem.h"
|
||||
|
||||
namespace mozilla::webgpu {
|
||||
|
||||
|
@ -356,9 +357,9 @@ Maybe<DeviceRequest> WebGPUChild::AdapterRequestDevice(
|
|||
|
||||
RawId WebGPUChild::DeviceCreateBuffer(RawId aSelfId,
|
||||
const dom::GPUBufferDescriptor& aDesc,
|
||||
MaybeShmem&& aShmem) {
|
||||
ipc::UnsafeSharedMemoryHandle&& aShmem) {
|
||||
RawId bufferId = ffi::wgpu_client_make_buffer_id(mClient.get(), aSelfId);
|
||||
if (!SendCreateBuffer(aSelfId, bufferId, aDesc, aShmem)) {
|
||||
if (!SendCreateBuffer(aSelfId, bufferId, aDesc, std::move(aShmem))) {
|
||||
MOZ_CRASH("IPC failure");
|
||||
}
|
||||
return bufferId;
|
||||
|
|
|
@ -12,6 +12,9 @@
|
|||
#include "mozilla/webgpu/ffi/wgpu.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace ipc {
|
||||
class UnsafeSharedMemoryHandle;
|
||||
} // namespace ipc
|
||||
namespace dom {
|
||||
struct GPURequestAdapterOptions;
|
||||
} // namespace dom
|
||||
|
@ -64,7 +67,7 @@ class WebGPUChild final : public PWebGPUChild, public SupportsWeakPtr {
|
|||
RawId aSelfId, const dom::GPUDeviceDescriptor& aDesc,
|
||||
ffi::WGPULimits* aLimits);
|
||||
RawId DeviceCreateBuffer(RawId aSelfId, const dom::GPUBufferDescriptor& aDesc,
|
||||
MaybeShmem&& aShmem);
|
||||
ipc::UnsafeSharedMemoryHandle&& aShmem);
|
||||
RawId DeviceCreateTexture(RawId aSelfId,
|
||||
const dom::GPUTextureDescriptor& aDesc);
|
||||
RawId TextureCreateView(RawId aSelfId, RawId aDeviceId,
|
||||
|
|
|
@ -346,22 +346,26 @@ WebGPUParent::BufferMapData* WebGPUParent::GetBufferMapData(RawId aBufferId) {
|
|||
return &iter->second;
|
||||
}
|
||||
|
||||
ipc::IPCResult WebGPUParent::RecvCreateBuffer(RawId aDeviceId, RawId aBufferId,
|
||||
dom::GPUBufferDescriptor&& aDesc,
|
||||
MaybeShmem&& aShmem) {
|
||||
ipc::IPCResult WebGPUParent::RecvCreateBuffer(
|
||||
RawId aDeviceId, RawId aBufferId, dom::GPUBufferDescriptor&& aDesc,
|
||||
ipc::UnsafeSharedMemoryHandle&& aShmem) {
|
||||
webgpu::StringHelper label(aDesc.mLabel);
|
||||
|
||||
if (aShmem.type() == MaybeShmem::TShmem) {
|
||||
bool hasMapFlags = aDesc.mUsage & (dom::GPUBufferUsage_Binding::MAP_WRITE |
|
||||
dom::GPUBufferUsage_Binding::MAP_READ);
|
||||
auto shmem =
|
||||
ipc::WritableSharedMemoryMapping::Open(std::move(aShmem)).value();
|
||||
|
||||
bool hasMapFlags = aDesc.mUsage & (dom::GPUBufferUsage_Binding::MAP_WRITE |
|
||||
dom::GPUBufferUsage_Binding::MAP_READ);
|
||||
if (hasMapFlags || aDesc.mMappedAtCreation) {
|
||||
uint64_t offset = 0;
|
||||
uint64_t size = 0;
|
||||
if (aDesc.mMappedAtCreation) {
|
||||
size = aDesc.mSize;
|
||||
MOZ_RELEASE_ASSERT(aShmem.get_Shmem().Size<uint8_t>() >= size);
|
||||
MOZ_RELEASE_ASSERT(shmem.Size() >= aDesc.mSize);
|
||||
}
|
||||
mSharedMemoryMap[aBufferId] = {aShmem.get_Shmem(), hasMapFlags, offset,
|
||||
size};
|
||||
|
||||
BufferMapData data = {std::move(shmem), hasMapFlags, offset, size};
|
||||
mSharedMemoryMap.insert({aBufferId, std::move(data)});
|
||||
}
|
||||
|
||||
ErrorBuffer error;
|
||||
|
@ -436,10 +440,10 @@ static void MapCallback(ffi::WGPUBufferMapAsyncStatus status,
|
|||
const auto src = ffi::wgpu_server_buffer_get_mapped_range(
|
||||
req->mContext, req->mBufferId, offset, size);
|
||||
|
||||
MOZ_RELEASE_ASSERT(mapData->mShmem.Size<uint8_t>() >= offset + size);
|
||||
MOZ_RELEASE_ASSERT(mapData->mShmem.Size() >= offset + size);
|
||||
if (src.ptr != nullptr && src.length >= size) {
|
||||
auto dstPtr = mapData->mShmem.get<uint8_t>() + offset;
|
||||
memcpy(dstPtr, src.ptr, size);
|
||||
auto dst = mapData->mShmem.Bytes().Subspan(offset, size);
|
||||
memcpy(dst.data(), src.ptr, size);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -509,16 +513,16 @@ ipc::IPCResult WebGPUParent::RecvBufferUnmap(RawId aDeviceId, RawId aBufferId,
|
|||
uint64_t offset = mapData->mMappedOffset;
|
||||
uint64_t size = mapData->mMappedSize;
|
||||
|
||||
uint8_t* srcPtr = mapData->mShmem.get<uint8_t>() + offset;
|
||||
|
||||
const auto mapped = ffi::wgpu_server_buffer_get_mapped_range(
|
||||
mContext.get(), aBufferId, offset, size);
|
||||
|
||||
if (mapped.ptr != nullptr && mapped.length >= size) {
|
||||
auto shmSize = mapData->mShmem.Size<uint8_t>();
|
||||
auto shmSize = mapData->mShmem.Size();
|
||||
MOZ_RELEASE_ASSERT(offset <= shmSize);
|
||||
MOZ_RELEASE_ASSERT(size <= shmSize - offset);
|
||||
memcpy(mapped.ptr, srcPtr, size);
|
||||
|
||||
auto src = mapData->mShmem.Bytes().Subspan(offset, size);
|
||||
memcpy(mapped.ptr, src.data(), size);
|
||||
}
|
||||
|
||||
mapData->mMappedOffset = 0;
|
||||
|
@ -541,7 +545,6 @@ ipc::IPCResult WebGPUParent::RecvBufferUnmap(RawId aDeviceId, RawId aBufferId,
|
|||
void WebGPUParent::DeallocBufferShmem(RawId aBufferId) {
|
||||
const auto iter = mSharedMemoryMap.find(aBufferId);
|
||||
if (iter != mSharedMemoryMap.end()) {
|
||||
DeallocShmem(iter->second.mShmem);
|
||||
mSharedMemoryMap.erase(iter);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include "mozilla/webgpu/ffi/wgpu.h"
|
||||
#include "mozilla/webgpu/PWebGPUParent.h"
|
||||
#include "mozilla/webrender/WebRenderAPI.h"
|
||||
#include "mozilla/ipc/RawShmem.h"
|
||||
#include "WebGPUTypes.h"
|
||||
#include "base/timer.h"
|
||||
|
||||
|
@ -37,7 +38,7 @@ class WebGPUParent final : public PWebGPUParent {
|
|||
ipc::IPCResult RecvDeviceDestroy(RawId aDeviceId);
|
||||
ipc::IPCResult RecvCreateBuffer(RawId aDeviceId, RawId aBufferId,
|
||||
dom::GPUBufferDescriptor&& aDesc,
|
||||
MaybeShmem&& aShmem);
|
||||
ipc::UnsafeSharedMemoryHandle&& aShmem);
|
||||
ipc::IPCResult RecvBufferReturnShmem(RawId aBufferId, Shmem&& aShmem);
|
||||
ipc::IPCResult RecvBufferMap(RawId aBufferId, uint32_t aMode,
|
||||
uint64_t aOffset, uint64_t size,
|
||||
|
@ -107,7 +108,7 @@ class WebGPUParent final : public PWebGPUParent {
|
|||
void ActorDestroy(ActorDestroyReason aWhy) override;
|
||||
|
||||
struct BufferMapData {
|
||||
Shmem mShmem;
|
||||
ipc::WritableSharedMemoryMapping mShmem;
|
||||
// True if buffer's usage has MAP_READ or MAP_WRITE set.
|
||||
bool mHasMapFlags;
|
||||
uint64_t mMappedOffset;
|
||||
|
|
Загрузка…
Ссылка в новой задаче