Img2Num C++ (Internal Developer Docs) dev
API Documentation
Loading...
Searching...
No Matches
GPU Class Reference
+ Collaboration diagram for GPU:

Public Member Functions

const wgpu::Device & get_device ()
 
const wgpu::Instance & get_instance ()
 
const wgpu::Queue & get_queue ()
 
bool is_initialized ()
 
 GPU (const GPU &)=delete
 
GPU & operator= (const GPU &)=delete
 
 GPU (GPU &&)=delete
 
GPU & operator= (GPU &&)=delete
 
std::string readWGSLFile (std::string_view shader_id)
 
wgpu::ComputePipeline createPipeline (const std::string &filename, const std::string &label)
 
void init_gpu ()
 

Static Public Member Functions

static GPU & getClassInstance ()
 
static uint32_t getAlignedBytesPerRow (uint32_t width, uint32_t bytesPerPixel=4)
 
static void printShaderError (wgpu::ShaderModule shaderModule)
 

Private Member Functions

bool validate_device ()
 

Private Attributes

wgpu::Instance instance
 
wgpu::Adapter adapter
 
wgpu::Device device
 
wgpu::Queue queue
 
bool adapter_ready = false
 
bool device_ready = false
 
bool gpu_initialized = false
 

Detailed Description

Definition at line 21 of file gpu.h.

Constructor & Destructor Documentation

◆ ~GPU()

GPU::~GPU ( )
inline

Definition at line 273 of file gpu.h.

273 {
274 device = nullptr;
275 adapter = nullptr;
276 queue = nullptr;
277 instance = nullptr;
278 gpu_initialized = false;
279 };

Member Function Documentation

◆ createPipeline()

wgpu::ComputePipeline GPU::createPipeline ( const std::string &  filename,
const std::string &  label 
)
inline

Definition at line 89 of file gpu.h.

89 {
90 wgpu::ShaderSourceWGSL wgsl;
91 std::string shaderCode = readWGSLFile(filename);
92 wgsl.code = shaderCode.c_str();
93 wgpu::ShaderModuleDescriptor md = {};
94 md.nextInChain = &wgsl;
95 md.label = label.c_str();
96 wgpu::ShaderModule sm = device.CreateShaderModule(&md);
97
98 wgpu::ComputePipelineDescriptor cpd = {};
99 cpd.compute.module = sm;
100 cpd.compute.entryPoint = "main";
101 return device.CreateComputePipeline(&cpd);
102 };

◆ get_device()

const wgpu::Device & GPU::get_device ( )
inline

Definition at line 54 of file gpu.h.

54 {
55 return device;
56 }

◆ get_instance()

const wgpu::Instance & GPU::get_instance ( )
inline

Definition at line 58 of file gpu.h.

58 {
59 return instance;
60 }

◆ get_queue()

const wgpu::Queue & GPU::get_queue ( )
inline

Definition at line 62 of file gpu.h.

62 {
63 return queue;
64 }

◆ getAlignedBytesPerRow()

static uint32_t GPU::getAlignedBytesPerRow ( uint32_t  width,
uint32_t  bytesPerPixel = 4 
)
inlinestatic

Definition at line 104 of file gpu.h.

104 {
105 uint32_t unaligned = width * bytesPerPixel;
106 uint32_t align = 256;
107 return (unaligned + align - 1) & ~(align - 1);
108 };

◆ getClassInstance()

static GPU & GPU::getClassInstance ( )
inlinestatic

Definition at line 49 of file gpu.h.

49 {
50 static GPU gpuInstance;
51 return gpuInstance;
52 }
Definition gpu.h:21

◆ init_gpu()

void GPU::init_gpu ( )
inline

Definition at line 134 of file gpu.h.

134 {
135 if (gpu_initialized)
136 return;
137
138 wgpu::InstanceDescriptor instanceDesc = {};
139 instance = wgpu::CreateInstance(&instanceDesc);
140
141 if (!instance) {
142 IMG2NUM_LOG_INFO("Fatal: WebGPU instance creation failed.");
143 return;
144 }
145
146 // ---------------------------------------------------------
147 // 1. Get Adapter
148 // ---------------------------------------------------------
149 IMG2NUM_LOG_INFO("Requesting Adapter...");
150 adapter_ready = false;
151
152 instance.RequestAdapter(
153 nullptr,
154 wgpu::CallbackMode::AllowProcessEvents, // <--- ALLOW EVENTS
155 [this](wgpu::RequestAdapterStatus status, wgpu::Adapter a, wgpu::StringView msg) {
156 if (status == wgpu::RequestAdapterStatus::Success) {
157 adapter = std::move(a);
158 IMG2NUM_LOG_INFO("Adapter Acquired");
159 } else {
160 IMG2NUM_LOG_INFO(
161 "Adapter Failed: {}", std::string_view(msg.data ? msg.data : "", msg.length)
162 );
163 }
164 adapter_ready = true; // Unblock the loop
165 }
166 );
167
168 // WAIT LOOP: Yield to browser so it can actually find the adapter
169 while (!adapter_ready) {
170 instance.ProcessEvents();
171#if defined(__EMSCRIPTEN__)
172 emscripten_sleep(10); // Sleep 10ms
173#endif
174 }
175
176 if (!adapter) {
177 IMG2NUM_LOG_INFO("Fatal: Could not get WebGPU Adapter.");
178 return;
179 }
180
181 // ---------------------------------------------------------
182 // 2. Get Device
183 // ---------------------------------------------------------
184 IMG2NUM_LOG_INFO("Requesting Device...");
185 device_ready = false;
186
187 wgpu::DeviceDescriptor deviceDesc = {};
188 deviceDesc.SetUncapturedErrorCallback([](const wgpu::Device&, wgpu::ErrorType type,
189 wgpu::StringView msg) {
190 // 1. Safely extract the string using the provided length
191 std::string err_str = (msg.data && msg.length > 0) ? std::string(msg.data, msg.length)
192 : "Unknown Error (Null message)";
193
194 // 2. Print it safely
195 IMG2NUM_LOG_INFO(
196 "\n[WEBGPU FATAL ERROR] Type: {} | Msg: {}\n", static_cast<uint32_t>(type), err_str
197 );
198 });
199 deviceDesc.SetDeviceLostCallback(
200 wgpu::CallbackMode::AllowProcessEvents,
201 [](const wgpu::Device&, wgpu::DeviceLostReason reason, wgpu::StringView msg) {
202 std::string err_msg = (msg.data && msg.length > 0)
203 ? std::string(msg.data, msg.length)
204 : "Unknown device lost reason";
205 // 1. Ignore teardown cancellations so we don't log during static destruction
206 if (reason == wgpu::DeviceLostReason::CallbackCancelled) {
207 return;
208 }
209 IMG2NUM_LOG_INFO(
210 "[DEVICE LOST] Reason: {} Msg: {}", static_cast<int>(reason), err_msg
211 );
212 }
213 );
214
215 // Set maximum possible device hardware memory
216 wgpu::Limits supportedLimits;
217 wgpu::Limits requiredLimits;
218 if (adapter.GetLimits(&supportedLimits)) {
219 // nominally the device Buffer limit is 256MB
220
221 // Copy the adapter's physical limits over to your requested limits
222 requiredLimits = supportedLimits;
223
224 IMG2NUM_LOG_INFO("maxBufferSize: {}", requiredLimits.maxBufferSize);
225 IMG2NUM_LOG_INFO(
226 "maxStorageBufferBindingSize: {}", requiredLimits.maxStorageBufferBindingSize
227 );
228
229 deviceDesc.requiredLimits = &requiredLimits;
230 }
231
232 adapter.RequestDevice(
233 &deviceDesc,
234 wgpu::CallbackMode::AllowProcessEvents, // <--- ALLOW EVENTS
235 [this](wgpu::RequestDeviceStatus status, wgpu::Device d, wgpu::StringView msg) {
236 if (status == wgpu::RequestDeviceStatus::Success) {
237 device = std::move(d);
238 IMG2NUM_LOG_INFO("Device Acquired");
239 } else {
240 IMG2NUM_LOG_INFO(
241 "Device Failed: {}", msg.data && msg.length > 0
242 ? std::string(msg.data, msg.length)
243 : "Unknown error"
244 );
245 }
246 device_ready = true; // Unblock the loop
247 }
248 );
249
250 // WAIT LOOP
251 while (!device_ready) {
252 instance.ProcessEvents();
253#if defined(__EMSCRIPTEN__)
254 emscripten_sleep(10);
255#endif
256 }
257
258 if (!device) {
259 IMG2NUM_LOG_INFO("Fatal: Could not get WebGPU Device.");
260 return;
261 }
262
263 if (!validate_device()) {
264 IMG2NUM_LOG_INFO("Fatal: Could not get WebGPU Device.");
265 return;
266 }
267
268 queue = device.GetQueue();
269 gpu_initialized = true;
270 IMG2NUM_LOG_INFO("GPU Fully Initialized.");
271 };

◆ is_initialized()

bool GPU::is_initialized ( )
inline

Definition at line 66 of file gpu.h.

66 {
67 return gpu_initialized;
68 }

◆ printShaderError()

static void GPU::printShaderError ( wgpu::ShaderModule  shaderModule)
inlinestatic

Definition at line 110 of file gpu.h.

110 {
111 shaderModule.GetCompilationInfo(
112 // Callback Mode (New API Requirement)
113 wgpu::CallbackMode::AllowProcessEvents,
114 // Callback Lambda
115 [](wgpu::CompilationInfoRequestStatus status, const wgpu::CompilationInfo* info) {
116 if (status != wgpu::CompilationInfoRequestStatus::Success || !info)
117 return;
118
119 for (uint32_t i = 0; i < info->messageCount; ++i) {
120 const auto& msg = info->messages[i];
121 IMG2NUM_LOG_INFO(
122 "Shader Error [{}] Line {}:{} - {}",
123 msg.type == wgpu::CompilationMessageType::Error ? "ERR" : "WARN",
124 msg.lineNum, msg.linePos,
125 std::string_view(
126 msg.message.data ? msg.message.data : "", msg.message.length
127 )
128 );
129 }
130 }
131 );
132 };

◆ readWGSLFile()

std::string GPU::readWGSLFile ( std::string_view  shader_id)
inline

Definition at line 76 of file gpu.h.

76 {
77 // A simple linear search over 9 items is blazingly fast in C++
78 for (const auto& entry : embedded_shaders::shaders) {
79 if (entry.id == shader_id) {
80 // Safely convert the string_view back to a std::string for Dawn
81 return std::string(entry.source);
82 }
83 }
84
85 // Always good to handle the "not found" case gracefully!
86 return "";
87 }

◆ validate_device()

bool GPU::validate_device ( )
inlineprivate

Definition at line 34 of file gpu.h.

34 {
35 if (!device)
36 return false;
37
38 // Try creating a trivial buffer to ensure the device is usable
39 wgpu::BufferDescriptor desc = {};
40 desc.size = 4;
41 desc.usage = wgpu::BufferUsage::CopyDst;
42
43 wgpu::Buffer test = device.CreateBuffer(&desc);
44 return test != nullptr;
45 }

Member Data Documentation

◆ adapter

wgpu::Adapter GPU::adapter
private

Definition at line 24 of file gpu.h.

◆ adapter_ready

bool GPU::adapter_ready = false
private

Definition at line 28 of file gpu.h.

◆ device

wgpu::Device GPU::device
private

Definition at line 25 of file gpu.h.

◆ device_ready

bool GPU::device_ready = false
private

Definition at line 29 of file gpu.h.

◆ gpu_initialized

bool GPU::gpu_initialized = false
private

Definition at line 30 of file gpu.h.

◆ instance

wgpu::Instance GPU::instance
private

Definition at line 23 of file gpu.h.

◆ queue

wgpu::Queue GPU::queue
private

Definition at line 26 of file gpu.h.


The documentation for this class was generated from the following file: