Compare commits
2 Commits
main
...
GetMappedR
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8c1167ddb8 | ||
|
|
c9b5bfc4a4 |
@@ -316,6 +316,8 @@ if (FILAMENT_SUPPORTS_WEBGPU)
|
|||||||
src/webgpu/WebGPURenderPrimitive.h
|
src/webgpu/WebGPURenderPrimitive.h
|
||||||
src/webgpu/WebGPURenderTarget.cpp
|
src/webgpu/WebGPURenderTarget.cpp
|
||||||
src/webgpu/WebGPURenderTarget.h
|
src/webgpu/WebGPURenderTarget.h
|
||||||
|
src/webgpu/WebGPUStagePool.cpp
|
||||||
|
src/webgpu/WebGPUStagePool.h
|
||||||
src/webgpu/WebGPUStrings.h
|
src/webgpu/WebGPUStrings.h
|
||||||
src/webgpu/WebGPUSwapChain.cpp
|
src/webgpu/WebGPUSwapChain.cpp
|
||||||
src/webgpu/WebGPUSwapChain.h
|
src/webgpu/WebGPUSwapChain.h
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
#include "WebGPUConstants.h"
|
#include "WebGPUConstants.h"
|
||||||
#include "WebGPUQueueManager.h"
|
#include "WebGPUQueueManager.h"
|
||||||
|
#include "WebGPUStagePool.h"
|
||||||
|
|
||||||
#include "DriverBase.h"
|
#include "DriverBase.h"
|
||||||
#include <backend/BufferDescriptor.h>
|
#include <backend/BufferDescriptor.h>
|
||||||
@@ -29,6 +30,7 @@
|
|||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
namespace filament::backend {
|
namespace filament::backend {
|
||||||
|
|
||||||
@@ -65,7 +67,7 @@ WebGPUBufferBase::WebGPUBufferBase(wgpu::Device const& device, const wgpu::Buffe
|
|||||||
// of 4 by padding with zeros.
|
// of 4 by padding with zeros.
|
||||||
void WebGPUBufferBase::updateGPUBuffer(BufferDescriptor const& bufferDescriptor,
|
void WebGPUBufferBase::updateGPUBuffer(BufferDescriptor const& bufferDescriptor,
|
||||||
const uint32_t byteOffset, wgpu::Device const& device,
|
const uint32_t byteOffset, wgpu::Device const& device,
|
||||||
WebGPUQueueManager* const webGPUQueueManager) {
|
WebGPUQueueManager* const webGPUQueueManager, WebGPUStagePool* const webGPUStagePool) {
|
||||||
FILAMENT_CHECK_PRECONDITION(bufferDescriptor.buffer)
|
FILAMENT_CHECK_PRECONDITION(bufferDescriptor.buffer)
|
||||||
<< "updateGPUBuffer called with a null buffer";
|
<< "updateGPUBuffer called with a null buffer";
|
||||||
FILAMENT_CHECK_PRECONDITION(bufferDescriptor.size + byteOffset <= mBuffer.GetSize())
|
FILAMENT_CHECK_PRECONDITION(bufferDescriptor.size + byteOffset <= mBuffer.GetSize())
|
||||||
@@ -79,34 +81,70 @@ void WebGPUBufferBase::updateGPUBuffer(BufferDescriptor const& bufferDescriptor,
|
|||||||
// This may have some performance implications. That should be investigated later.
|
// This may have some performance implications. That should be investigated later.
|
||||||
assert_invariant(mBuffer.GetUsage() & wgpu::BufferUsage::CopyDst);
|
assert_invariant(mBuffer.GetUsage() & wgpu::BufferUsage::CopyDst);
|
||||||
|
|
||||||
// Calculate some alignment related sizes
|
// // Calculate some alignment related sizes
|
||||||
const size_t remainder = bufferDescriptor.size % FILAMENT_WEBGPU_BUFFER_SIZE_MODULUS;
|
const size_t remainder = bufferDescriptor.size % FILAMENT_WEBGPU_BUFFER_SIZE_MODULUS;
|
||||||
const size_t mainBulk = bufferDescriptor.size - remainder;
|
const size_t mainBulk = bufferDescriptor.size - remainder;
|
||||||
const size_t stagingBufferSize =
|
const size_t stagingBufferSize =
|
||||||
remainder == 0 ? bufferDescriptor.size : mainBulk + FILAMENT_WEBGPU_BUFFER_SIZE_MODULUS;
|
remainder == 0 ? bufferDescriptor.size : mainBulk + FILAMENT_WEBGPU_BUFFER_SIZE_MODULUS;
|
||||||
|
//
|
||||||
|
// // create a staging buffer
|
||||||
|
// wgpu::BufferDescriptor descriptor{
|
||||||
|
// .label = "Filament WebGPU Staging Buffer",
|
||||||
|
// .usage = wgpu::BufferUsage::MapWrite | wgpu::BufferUsage::CopySrc,
|
||||||
|
// .size = stagingBufferSize,
|
||||||
|
// .mappedAtCreation = true };
|
||||||
|
// wgpu::Buffer stagingBuffer = device.CreateBuffer(&descriptor);
|
||||||
|
MappedStage mappedStage = webGPUStagePool->acquireBuffer(stagingBufferSize);
|
||||||
|
|
||||||
// create a staging buffer
|
std::string mappedRangeIsNull = mappedStage.mappedRange
|
||||||
wgpu::BufferDescriptor descriptor{
|
? "no"
|
||||||
.label = "Filament WebGPU Staging Buffer",
|
: "yes";
|
||||||
.usage = wgpu::BufferUsage::MapWrite | wgpu::BufferUsage::CopySrc,
|
std::cout << "Run Yu: got mapped range on the staging buffer with size "
|
||||||
.size = stagingBufferSize,
|
<< mappedStage.buffer.GetSize() << " and it is null? " << mappedRangeIsNull << std::endl;
|
||||||
.mappedAtCreation = true };
|
memcpy(mappedStage.mappedRange, bufferDescriptor.buffer, bufferDescriptor.size);
|
||||||
wgpu::Buffer stagingBuffer = device.CreateBuffer(&descriptor);
|
|
||||||
|
|
||||||
void* mappedRange = stagingBuffer.GetMappedRange();
|
|
||||||
memcpy(mappedRange, bufferDescriptor.buffer, bufferDescriptor.size);
|
|
||||||
|
|
||||||
// Make sure the padded memory is set to 0 to have deterministic behaviors
|
// Make sure the padded memory is set to 0 to have deterministic behaviors
|
||||||
if (remainder != 0) {
|
// if (remainder != 0) {
|
||||||
uint8_t* paddingStart = static_cast<uint8_t*>(mappedRange) + bufferDescriptor.size;
|
// uint8_t* paddingStart = static_cast<uint8_t*>(mappedRange) + bufferDescriptor.size;
|
||||||
memset(paddingStart, 0, FILAMENT_WEBGPU_BUFFER_SIZE_MODULUS - remainder);
|
// memset(paddingStart, 0, FILAMENT_WEBGPU_BUFFER_SIZE_MODULUS - remainder);
|
||||||
}
|
// }
|
||||||
|
// size_t stagingBufferSize = stagingBuffer.GetSize();
|
||||||
|
// if (stagingBufferSize != bufferDescriptor.size) {
|
||||||
|
// assert(stagingBufferSize > bufferDescriptor.size);
|
||||||
|
// assert(stagingBufferSize % FILAMENT_WEBGPU_BUFFER_SIZE_MODULUS == 0);
|
||||||
|
// uint8_t* paddingStart = static_cast<uint8_t*>(mappedRange) + bufferDescriptor.size;
|
||||||
|
// memset(paddingStart, 0, FILAMENT_WEBGPU_BUFFER_SIZE_MODULUS - (stagingBuffer.GetSize() - bufferDescriptor.size));
|
||||||
|
// }
|
||||||
|
|
||||||
stagingBuffer.Unmap();
|
mappedStage.buffer.Unmap();
|
||||||
|
|
||||||
|
std::cout << "Run Yu: about to issue copy command with actual staging buffer of size "
|
||||||
|
<< mappedStage.buffer.GetSize() << ", and computed size of " << stagingBufferSize
|
||||||
|
<< ". The mBuffer size is " << mBuffer.GetSize() << std::endl;
|
||||||
// Copy the staging buffer contents to the destination buffer.
|
// Copy the staging buffer contents to the destination buffer.
|
||||||
webGPUQueueManager->getCommandEncoder().CopyBufferToBuffer(stagingBuffer, 0, mBuffer,
|
webGPUQueueManager->getCommandEncoder().CopyBufferToBuffer(mappedStage.buffer, 0, mBuffer,
|
||||||
byteOffset, stagingBufferSize);
|
byteOffset,
|
||||||
|
remainder == 0 ? bufferDescriptor.size
|
||||||
|
: mainBulk + FILAMENT_WEBGPU_BUFFER_SIZE_MODULUS);
|
||||||
|
webGPUQueueManager->flush();
|
||||||
|
|
||||||
|
struct UserData final {
|
||||||
|
wgpu::Buffer stagingBuffer;
|
||||||
|
WebGPUStagePool* webGPUStagePool;
|
||||||
|
};
|
||||||
|
auto userData = std::make_unique<UserData>(
|
||||||
|
UserData{ .stagingBuffer = mappedStage.buffer, .webGPUStagePool = webGPUStagePool });
|
||||||
|
mappedStage.buffer.MapAsync(
|
||||||
|
wgpu::MapMode::Write, 0, stagingBufferSize, wgpu::CallbackMode::AllowSpontaneous,
|
||||||
|
[](wgpu::MapAsyncStatus status, const char* message, UserData* userData) {
|
||||||
|
if (UTILS_LIKELY(status == wgpu::MapAsyncStatus::Success)) {
|
||||||
|
std::unique_ptr<UserData> data(static_cast<UserData*>(userData));
|
||||||
|
userData->webGPUStagePool->addBufferToPool(userData->stagingBuffer);
|
||||||
|
} else {
|
||||||
|
std::cout << "Run Yu: MAPPING UNSUCCESSFUL!!\n";
|
||||||
|
}
|
||||||
|
},
|
||||||
|
userData.release());
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace filament::backend
|
} // namespace filament::backend
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ namespace filament::backend {
|
|||||||
|
|
||||||
class BufferDescriptor;
|
class BufferDescriptor;
|
||||||
class WebGPUQueueManager;
|
class WebGPUQueueManager;
|
||||||
|
class WebGPUStagePool;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A base class for WebGPU buffer objects, providing common functionality for creating and
|
* A base class for WebGPU buffer objects, providing common functionality for creating and
|
||||||
@@ -40,7 +41,7 @@ public:
|
|||||||
* ensures the calls happen in the expected sequence.
|
* ensures the calls happen in the expected sequence.
|
||||||
*/
|
*/
|
||||||
void updateGPUBuffer(BufferDescriptor const&, uint32_t byteOffset, wgpu::Device const& device,
|
void updateGPUBuffer(BufferDescriptor const&, uint32_t byteOffset, wgpu::Device const& device,
|
||||||
WebGPUQueueManager* const webGPUQueueManager);
|
WebGPUQueueManager* const webGPUQueueManager, WebGPUStagePool* const webGPUStagePool);
|
||||||
|
|
||||||
[[nodiscard]] wgpu::Buffer const& getBuffer() const { return mBuffer; }
|
[[nodiscard]] wgpu::Buffer const& getBuffer() const { return mBuffer; }
|
||||||
|
|
||||||
|
|||||||
@@ -107,6 +107,7 @@ WebGPUDriver::WebGPUDriver(WebGPUPlatform& platform,
|
|||||||
mAdapter{ mPlatform.requestAdapter(nullptr) },
|
mAdapter{ mPlatform.requestAdapter(nullptr) },
|
||||||
mDevice{ mPlatform.requestDevice(mAdapter) },
|
mDevice{ mPlatform.requestDevice(mAdapter) },
|
||||||
mQueueManager{ mDevice },
|
mQueueManager{ mDevice },
|
||||||
|
mStagePool{ mDevice },
|
||||||
mPipelineLayoutCache{ mDevice },
|
mPipelineLayoutCache{ mDevice },
|
||||||
mPipelineCache{ mDevice },
|
mPipelineCache{ mDevice },
|
||||||
mRenderPassMipmapGenerator{ mDevice, &mQueueManager },
|
mRenderPassMipmapGenerator{ mDevice, &mQueueManager },
|
||||||
@@ -856,7 +857,7 @@ void WebGPUDriver::updateIndexBuffer(Handle<HwIndexBuffer> indexBufferHandle,
|
|||||||
// draw calls are made.
|
// draw calls are made.
|
||||||
flush();
|
flush();
|
||||||
handleCast<WebGPUIndexBuffer>(indexBufferHandle)
|
handleCast<WebGPUIndexBuffer>(indexBufferHandle)
|
||||||
->updateGPUBuffer(bufferDescriptor, byteOffset, mDevice, &mQueueManager);
|
->updateGPUBuffer(bufferDescriptor, byteOffset, mDevice, &mQueueManager, &mStagePool);
|
||||||
scheduleDestroy(std::move(bufferDescriptor));
|
scheduleDestroy(std::move(bufferDescriptor));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -867,14 +868,14 @@ void WebGPUDriver::updateBufferObject(Handle<HwBufferObject> bufferObjectHandle,
|
|||||||
// draw calls are made.
|
// draw calls are made.
|
||||||
flush();
|
flush();
|
||||||
handleCast<WebGPUBufferObject>(bufferObjectHandle)
|
handleCast<WebGPUBufferObject>(bufferObjectHandle)
|
||||||
->updateGPUBuffer(bufferDescriptor, byteOffset, mDevice, &mQueueManager);
|
->updateGPUBuffer(bufferDescriptor, byteOffset, mDevice, &mQueueManager, &mStagePool);
|
||||||
scheduleDestroy(std::move(bufferDescriptor));
|
scheduleDestroy(std::move(bufferDescriptor));
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebGPUDriver::updateBufferObjectUnsynchronized(Handle<HwBufferObject> bufferObjectHandle,
|
void WebGPUDriver::updateBufferObjectUnsynchronized(Handle<HwBufferObject> bufferObjectHandle,
|
||||||
BufferDescriptor&& bufferDescriptor, const uint32_t byteOffset) {
|
BufferDescriptor&& bufferDescriptor, const uint32_t byteOffset) {
|
||||||
handleCast<WebGPUBufferObject>(bufferObjectHandle)
|
handleCast<WebGPUBufferObject>(bufferObjectHandle)
|
||||||
->updateGPUBuffer(bufferDescriptor, byteOffset, mDevice, &mQueueManager);
|
->updateGPUBuffer(bufferDescriptor, byteOffset, mDevice, &mQueueManager, &mStagePool);
|
||||||
scheduleDestroy(std::move(bufferDescriptor));
|
scheduleDestroy(std::move(bufferDescriptor));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -25,6 +25,7 @@
|
|||||||
#include "webgpu/WebGPUPipelineLayoutCache.h"
|
#include "webgpu/WebGPUPipelineLayoutCache.h"
|
||||||
#include "webgpu/WebGPURenderPassMipmapGenerator.h"
|
#include "webgpu/WebGPURenderPassMipmapGenerator.h"
|
||||||
#include "webgpu/WebGPUQueueManager.h"
|
#include "webgpu/WebGPUQueueManager.h"
|
||||||
|
#include "webgpu/WebGPUStagePool.h"
|
||||||
#include "webgpu/utils/AsyncTaskCounter.h"
|
#include "webgpu/utils/AsyncTaskCounter.h"
|
||||||
#include <backend/platforms/WebGPUPlatform.h>
|
#include <backend/platforms/WebGPUPlatform.h>
|
||||||
|
|
||||||
@@ -81,6 +82,7 @@ private:
|
|||||||
wgpu::Device mDevice = nullptr;
|
wgpu::Device mDevice = nullptr;
|
||||||
wgpu::Limits mDeviceLimits = {};
|
wgpu::Limits mDeviceLimits = {};
|
||||||
WebGPUQueueManager mQueueManager;
|
WebGPUQueueManager mQueueManager;
|
||||||
|
WebGPUStagePool mStagePool;
|
||||||
void* mNativeWindow = nullptr;
|
void* mNativeWindow = nullptr;
|
||||||
WebGPUSwapChain* mSwapChain = nullptr;
|
WebGPUSwapChain* mSwapChain = nullptr;
|
||||||
uint64_t mNextFakeHandle = 1;
|
uint64_t mNextFakeHandle = 1;
|
||||||
|
|||||||
88
filament/backend/src/webgpu/WebGPUStagePool.cpp
Normal file
88
filament/backend/src/webgpu/WebGPUStagePool.cpp
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2025 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "WebGPUStagePool.h"
|
||||||
|
|
||||||
|
#include "WebGPUConstants.h"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
namespace filament::backend {
|
||||||
|
|
||||||
|
WebGPUStagePool::WebGPUStagePool(wgpu::Device const& device) : mDevice(device) {}
|
||||||
|
|
||||||
|
WebGPUStagePool::~WebGPUStagePool() = default;
|
||||||
|
|
||||||
|
MappedStage WebGPUStagePool::acquireBuffer(size_t requiredSize) {
|
||||||
|
std::cout << "Run Yu: required size in acquireBuffer: " << requiredSize << std::endl;
|
||||||
|
std::cout << "Run Yu: the pool size is " << mBuffers.size() << std::endl;
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(mMutex);
|
||||||
|
auto iter = mBuffers.lower_bound(requiredSize);
|
||||||
|
if (iter != mBuffers.end()) {
|
||||||
|
std::cout << "Run Yu: found buffer in the pool with size " << iter->second.GetSize()
|
||||||
|
<< std::endl;
|
||||||
|
if (iter->second.GetMapState() != wgpu::BufferMapState::Mapped) {
|
||||||
|
std::cout << "Run Yu: before GetMappedRange the buffer state is not mapped!\n";
|
||||||
|
}
|
||||||
|
MappedStage mappedStage = { .buffer = iter->second,
|
||||||
|
.mappedRange = iter->second.GetMappedRange() };
|
||||||
|
if (!mappedStage.mappedRange) {
|
||||||
|
std::cout << "Run Yu: mapped range is null in acquireBuffer!\n";
|
||||||
|
}
|
||||||
|
if (mappedStage.buffer.GetMapState() != wgpu::BufferMapState::Mapped) {
|
||||||
|
std::cout << "Run Yu: after GetMappedRange the buffer state is not mapped!\n";
|
||||||
|
}
|
||||||
|
mBuffers.erase(iter);
|
||||||
|
return mappedStage;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
wgpu::Buffer newBuffer = createNewBuffer(requiredSize);
|
||||||
|
return { .buffer = newBuffer, .mappedRange = newBuffer.GetMappedRange() };
|
||||||
|
}
|
||||||
|
|
||||||
|
void WebGPUStagePool::addBufferToPool(wgpu::Buffer buffer) {
|
||||||
|
std::lock_guard<std::mutex> lock(mMutex);
|
||||||
|
std::cout << "Run Yu: adding buffer to the pool with size " << buffer.GetSize() << std::endl;
|
||||||
|
mBuffers.insert({buffer.GetSize(), buffer});
|
||||||
|
std::cout << "Run Yu: added buffer to the pool with size " << buffer.GetSize() << std::endl;
|
||||||
|
|
||||||
|
bool allMapped = true;
|
||||||
|
for (const auto& pair : mBuffers) {
|
||||||
|
auto state = pair.second.GetMapState();
|
||||||
|
if (state != wgpu::BufferMapState::Mapped) {
|
||||||
|
allMapped = false;
|
||||||
|
std::cout << "Run Yu: the buffer with size " << pair.second.GetSize()
|
||||||
|
<< " is not mapped but somehow was added to the pool, its state is "
|
||||||
|
<< static_cast<int>(state) << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!allMapped) {
|
||||||
|
std::cout << "Run Yu: found buffers that are not mapped\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
wgpu::Buffer WebGPUStagePool::createNewBuffer(size_t bufferSize) {
|
||||||
|
std::cout << "Run Yu: creating new buffer with size " << bufferSize << std::endl;
|
||||||
|
wgpu::BufferDescriptor descriptor{
|
||||||
|
.label = "Filament WebGPU Staging Buffer",
|
||||||
|
.usage = wgpu::BufferUsage::MapWrite | wgpu::BufferUsage::CopySrc,
|
||||||
|
.size = bufferSize,
|
||||||
|
.mappedAtCreation = true };
|
||||||
|
return mDevice.CreateBuffer(&descriptor);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace filament::backend
|
||||||
49
filament/backend/src/webgpu/WebGPUStagePool.h
Normal file
49
filament/backend/src/webgpu/WebGPUStagePool.h
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2025 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef TNT_FILAMENT_BACKEND_WEBGPUSTAGEPOOL_H
|
||||||
|
#define TNT_FILAMENT_BACKEND_WEBGPUSTAGEPOOL_H
|
||||||
|
|
||||||
|
#include <webgpu/webgpu_cpp.h>
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
#include <mutex>
|
||||||
|
|
||||||
|
namespace filament::backend {
|
||||||
|
|
||||||
|
struct MappedStage {
|
||||||
|
wgpu::Buffer buffer;
|
||||||
|
void* mappedRange;
|
||||||
|
};
|
||||||
|
|
||||||
|
class WebGPUStagePool {
|
||||||
|
public:
|
||||||
|
WebGPUStagePool(wgpu::Device const& device);
|
||||||
|
~WebGPUStagePool();
|
||||||
|
|
||||||
|
MappedStage acquireBuffer(size_t requiredSize);
|
||||||
|
void addBufferToPool(wgpu::Buffer buffer);
|
||||||
|
private:
|
||||||
|
wgpu::Buffer createNewBuffer(size_t bufferSize);
|
||||||
|
std::multimap<uint32_t, wgpu::Buffer> mBuffers;
|
||||||
|
mutable std::mutex mMutex;
|
||||||
|
|
||||||
|
wgpu::Device mDevice;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // TNT_FILAMENT_BACKEND_WEBGPUSTAGEPOOL_H
|
||||||
Reference in New Issue
Block a user