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
 
GPUoperator= (const GPU &)=delete
 
 GPU (GPU &&)=delete
 
GPUoperator= (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 GPUgetClassInstance ()
 
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 20 of file gpu.h.

Constructor & Destructor Documentation

◆ ~GPU()

GPU::~GPU ( )
inline

Definition at line 263 of file gpu.h.

263 {
264 device = nullptr;
265 adapter = nullptr;
266 queue = nullptr;
267 instance = nullptr;
268 gpu_initialized = false;
269 };

Member Function Documentation

◆ createPipeline()

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

Definition at line 88 of file gpu.h.

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

◆ get_device()

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

Definition at line 53 of file gpu.h.

53 {
54 return device;
55 }

◆ get_instance()

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

Definition at line 57 of file gpu.h.

57 {
58 return instance;
59 }

◆ get_queue()

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

Definition at line 61 of file gpu.h.

61 {
62 return queue;
63 }

◆ getAlignedBytesPerRow()

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

Definition at line 103 of file gpu.h.

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

◆ getClassInstance()

static GPU & GPU::getClassInstance ( )
inlinestatic

Definition at line 48 of file gpu.h.

48 {
49 static GPU gpuInstance;
50 return gpuInstance;
51 }
Definition gpu.h:20

◆ init_gpu()

void GPU::init_gpu ( )
inline

Definition at line 131 of file gpu.h.

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

◆ is_initialized()

bool GPU::is_initialized ( )
inline

Definition at line 65 of file gpu.h.

65 {
66 return gpu_initialized;
67 }

◆ printShaderError()

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

Definition at line 109 of file gpu.h.

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

◆ readWGSLFile()

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

Definition at line 75 of file gpu.h.

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

◆ validate_device()

bool GPU::validate_device ( )
inlineprivate

Definition at line 33 of file gpu.h.

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

Member Data Documentation

◆ adapter

wgpu::Adapter GPU::adapter
private

Definition at line 23 of file gpu.h.

◆ adapter_ready

bool GPU::adapter_ready = false
private

Definition at line 27 of file gpu.h.

◆ device

wgpu::Device GPU::device
private

Definition at line 24 of file gpu.h.

◆ device_ready

bool GPU::device_ready = false
private

Definition at line 28 of file gpu.h.

◆ gpu_initialized

bool GPU::gpu_initialized = false
private

Definition at line 29 of file gpu.h.

◆ instance

wgpu::Instance GPU::instance
private

Definition at line 22 of file gpu.h.

◆ queue

wgpu::Queue GPU::queue
private

Definition at line 25 of file gpu.h.


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