Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions apps/example/ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1433,7 +1433,7 @@ PODS:
- ReactCommon/turbomodule/bridging
- ReactCommon/turbomodule/core
- Yoga
- react-native-wgpu (0.2.2):
- react-native-wgpu (0.2.3):
- DoubleConversion
- glog
- hermes-engine
Expand Down Expand Up @@ -2246,7 +2246,7 @@ SPEC CHECKSUMS:
React-microtasksnativemodule: ca2804a25fdcefffa0aa942aa23ab53b99614a34
react-native-safe-area-context: 00d03dc688ba86664be66f9e3f203fc7d747d899
react-native-skia: 443d0725a6cbbcce886edb96b591935eb3bc36d8
react-native-wgpu: e7754c8f25598bfc7e77e5938acce1445f8f2f2b
react-native-wgpu: 282b5bac022287804e6a7b064f903b4e273c7024
React-NativeModulesApple: 452b86b29fae99ed0a4015dca3ad9cd222f88abf
React-oscompat: ef5df1c734f19b8003e149317d041b8ce1f7d29c
React-perflogger: 6fd2f6811533e9c19a61e855c3033eecbf4ad2a0
Expand Down
2 changes: 1 addition & 1 deletion packages/webgpu/apple/RNWGUIKit.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,4 @@ typedef UIView RNWGPlatformView;
typedef NSView RNWGPlatformView;
#endif

#endif // PACKAGES_WEBGPU_APPLE_RNWGUIKIT_H_
#endif // PACKAGES_WEBGPU_APPLE_RNWGUIKIT_H_
6 changes: 6 additions & 0 deletions packages/webgpu/cpp/jsi/RNFHybridObject.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,12 @@ class HybridObject : public jsi::HostObject, public std::enable_shared_from_this
*/
virtual std::string toString(jsi::Runtime& runtime);

/**
* Get the memory pressure of this HostObject in bytes.
* This is used to inform the JavaScript runtime about memory usage for garbage collection.
*/
virtual size_t getMemoryPressure() { return 1024; }

private:
static constexpr auto TAG = "HybridObject";
int _instanceId = 1;
Expand Down
7 changes: 6 additions & 1 deletion packages/webgpu/cpp/jsi/RNFJSIConverter.h
Original file line number Diff line number Diff line change
Expand Up @@ -446,7 +446,12 @@ template <typename T> struct JSIConverter<T, std::enable_if_t<is_shared_ptr_to_h
throw jsi::JSError(runtime, "Cannot convert nullptr to HostObject<" + getFriendlyTypename() + ">!");
}
#endif
return jsi::Object::createFromHostObject(runtime, arg);
auto result = jsi::Object::createFromHostObject(runtime, arg);
auto memoryPressure = arg->getMemoryPressure();
if (memoryPressure > 0) {
result.setExternalMemoryPressure(runtime, memoryPressure);
}
return result;
}
};

Expand Down
7 changes: 7 additions & 0 deletions packages/webgpu/cpp/rnwgpu/api/GPUBindGroup.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,13 @@ class GPUBindGroup : public m::HybridObject {

inline const wgpu::BindGroup get() { return _instance; }

size_t getMemoryPressure() override {
// Bind groups store resource bindings and descriptor state
// They reference buffers, textures, samplers, etc.
// Estimate: 1KB per bind group (descriptor tables and binding state)
return 1024;
}

private:
wgpu::BindGroup _instance;
std::string _label;
Expand Down
7 changes: 7 additions & 0 deletions packages/webgpu/cpp/rnwgpu/api/GPUBindGroupLayout.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,13 @@ class GPUBindGroupLayout : public m::HybridObject {

inline const wgpu::BindGroupLayout get() { return _instance; }

size_t getMemoryPressure() override {
// Bind group layouts define the structure/schema for bind groups
// They store binding descriptors, types, and validation info
// Estimate: 512 bytes per layout (smaller than actual bind groups)
return 512;
}

private:
wgpu::BindGroupLayout _instance;
std::string _label;
Expand Down
2 changes: 2 additions & 0 deletions packages/webgpu/cpp/rnwgpu/api/GPUBuffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ class GPUBuffer : public m::HybridObject {

inline const wgpu::Buffer get() { return _instance; }

size_t getMemoryPressure() override { return static_cast<size_t>(getSize()); }

private:
wgpu::Buffer _instance;
std::shared_ptr<AsyncRunner> _async;
Expand Down
2 changes: 1 addition & 1 deletion packages/webgpu/cpp/rnwgpu/api/GPUCanvasContext.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#include "GPUCanvasContext.h"
#include <memory>
#include "Convertors.h"
#include "RNWebGPUManager.h"
#include <memory>

#ifdef __APPLE__
#include "dawn/native/MetalBackend.h"
Expand Down
7 changes: 7 additions & 0 deletions packages/webgpu/cpp/rnwgpu/api/GPUComputePipeline.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,13 @@ class GPUComputePipeline : public m::HybridObject {

inline const wgpu::ComputePipeline get() { return _instance; }

size_t getMemoryPressure() override {
// Compute pipelines contain compiled compute shader state and
// driver-specific optimized code
// Estimate: 16KB for a typical compute pipeline (single compute shader)
return 16 * 1024;
}

private:
wgpu::ComputePipeline _instance;
std::string _label;
Expand Down
21 changes: 21 additions & 0 deletions packages/webgpu/cpp/rnwgpu/api/GPUQuerySet.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,27 @@ class GPUQuerySet : public m::HybridObject {

inline const wgpu::QuerySet get() { return _instance; }

size_t getMemoryPressure() override {
uint32_t count = getCount();
wgpu::QueryType type = getType();

// Estimate bytes per query based on type
size_t bytesPerQuery = 8; // Default estimate
switch (type) {
case wgpu::QueryType::Occlusion:
bytesPerQuery = 8; // 64-bit counter
break;
case wgpu::QueryType::Timestamp:
bytesPerQuery = 8; // 64-bit timestamp
break;
default:
bytesPerQuery = 8; // Safe default
break;
}

return static_cast<size_t>(count) * bytesPerQuery;
}

private:
wgpu::QuerySet _instance;
std::string _label;
Expand Down
3 changes: 2 additions & 1 deletion packages/webgpu/cpp/rnwgpu/api/GPUQueue.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ void GPUQueue::writeBuffer(std::shared_ptr<GPUBuffer> buffer,

// Note that in the JS semantics of WebGPU, writeBuffer works in number of
// elements of the typed arrays.
if (dataOffsetElements > static_cast<uint64_t>(src.size / src.bytesPerElement)) {
if (dataOffsetElements >
static_cast<uint64_t>(src.size / src.bytesPerElement)) {
throw std::runtime_error("dataOffset is larger than data's size.");
return;
}
Expand Down
6 changes: 3 additions & 3 deletions packages/webgpu/cpp/rnwgpu/api/GPURenderPassEncoder.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#include <vector>
#include <string>
#include <memory>
#include <string>
#include <vector>

#include "GPURenderPassEncoder.h"
#include "Convertors.h"
Expand Down Expand Up @@ -162,4 +162,4 @@ void GPURenderPassEncoder::drawIndexedIndirect(
_instance.DrawIndexedIndirect(b, indirectOffset);
}

} // namespace rnwgpu
} // namespace rnwgpu
8 changes: 8 additions & 0 deletions packages/webgpu/cpp/rnwgpu/api/GPURenderPipeline.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,14 @@ class GPURenderPipeline : public m::HybridObject {

inline const wgpu::RenderPipeline get() { return _instance; }

size_t getMemoryPressure() override {
// Render pipelines contain compiled shader state, vertex/fragment shaders,
// render state, and driver-specific optimized code
// Estimate: 24KB for a typical render pipeline with vertex + fragment
// shaders
return 24 * 1024;
}

private:
wgpu::RenderPipeline _instance;
std::string _label;
Expand Down
2 changes: 1 addition & 1 deletion packages/webgpu/cpp/rnwgpu/api/GPUShaderModule.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#include "GPUShaderModule.h"

#include <utility>
#include <memory>
#include <utility>

namespace rnwgpu {

Expand Down
8 changes: 8 additions & 0 deletions packages/webgpu/cpp/rnwgpu/api/GPUShaderModule.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,14 @@ class GPUShaderModule : public m::HybridObject {

inline const wgpu::ShaderModule get() { return _instance; }

size_t getMemoryPressure() override {
// Estimate memory usage for compiled shader module
// Shaders can vary widely, but a reasonable estimate is 8-16KB for typical
// shaders Complex shaders (with many uniforms, textures, or computations)
// can be much larger
return 12 * 1024; // 12KB estimate for average shader
}

private:
wgpu::ShaderModule _instance;
std::shared_ptr<AsyncRunner> _async;
Expand Down
76 changes: 76 additions & 0 deletions packages/webgpu/cpp/rnwgpu/api/GPUTexture.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#pragma once

#include <algorithm>
#include <memory>
#include <string>

Expand Down Expand Up @@ -64,6 +65,81 @@ class GPUTexture : public m::HybridObject {

inline const wgpu::Texture get() { return _instance; }

size_t getMemoryPressure() override {
// Calculate approximate memory usage based on texture properties
uint32_t width = getWidth();
uint32_t height = getHeight();
uint32_t depthOrArrayLayers = getDepthOrArrayLayers();
uint32_t mipLevelCount = getMipLevelCount();
uint32_t sampleCount = getSampleCount();

// Estimate bytes per pixel based on format
// This is a simplified estimate - actual values depend on the specific
// format
size_t bytesPerPixel = 4; // Default to RGBA8 format
wgpu::TextureFormat format = getFormat();
switch (format) {
case wgpu::TextureFormat::R8Unorm:
case wgpu::TextureFormat::R8Snorm:
case wgpu::TextureFormat::R8Uint:
case wgpu::TextureFormat::R8Sint:
bytesPerPixel = 1;
break;
case wgpu::TextureFormat::R16Uint:
case wgpu::TextureFormat::R16Sint:
case wgpu::TextureFormat::R16Float:
case wgpu::TextureFormat::RG8Unorm:
case wgpu::TextureFormat::RG8Snorm:
case wgpu::TextureFormat::RG8Uint:
case wgpu::TextureFormat::RG8Sint:
bytesPerPixel = 2;
break;
case wgpu::TextureFormat::RGBA8Unorm:
case wgpu::TextureFormat::RGBA8UnormSrgb:
case wgpu::TextureFormat::RGBA8Snorm:
case wgpu::TextureFormat::RGBA8Uint:
case wgpu::TextureFormat::RGBA8Sint:
case wgpu::TextureFormat::BGRA8Unorm:
case wgpu::TextureFormat::BGRA8UnormSrgb:
case wgpu::TextureFormat::RGB10A2Unorm:
case wgpu::TextureFormat::R32Float:
case wgpu::TextureFormat::R32Uint:
case wgpu::TextureFormat::R32Sint:
case wgpu::TextureFormat::RG16Uint:
case wgpu::TextureFormat::RG16Sint:
case wgpu::TextureFormat::RG16Float:
bytesPerPixel = 4;
break;
case wgpu::TextureFormat::RG32Float:
case wgpu::TextureFormat::RG32Uint:
case wgpu::TextureFormat::RG32Sint:
case wgpu::TextureFormat::RGBA16Uint:
case wgpu::TextureFormat::RGBA16Sint:
case wgpu::TextureFormat::RGBA16Float:
bytesPerPixel = 8;
break;
case wgpu::TextureFormat::RGBA32Float:
case wgpu::TextureFormat::RGBA32Uint:
case wgpu::TextureFormat::RGBA32Sint:
bytesPerPixel = 16;
break;
default:
bytesPerPixel = 4; // Safe default
break;
}

// Calculate total memory for all mip levels
size_t totalMemory = 0;
for (uint32_t mip = 0; mip < mipLevelCount; ++mip) {
uint32_t mipWidth = std::max(1u, width >> mip);
uint32_t mipHeight = std::max(1u, height >> mip);
totalMemory += static_cast<size_t>(mipWidth) * mipHeight *
depthOrArrayLayers * bytesPerPixel * sampleCount;
}

return totalMemory;
}

private:
wgpu::Texture _instance;
std::string _label;
Expand Down
2 changes: 2 additions & 0 deletions packages/webgpu/cpp/rnwgpu/api/ImageBitmap.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ class ImageBitmap : public margelo::HybridObject {
registerHybridGetter("height", &ImageBitmap::getHeight, this);
}

size_t getMemoryPressure() override { return getSize(); }

private:
ImageData _imageData;
};
Expand Down
2 changes: 1 addition & 1 deletion packages/webgpu/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "react-native-wgpu",
"version": "0.2.2",
"version": "0.2.3",
"description": "React Native WebGPU",
"main": "lib/commonjs/index",
"module": "lib/module/index",
Expand Down
Loading