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 21 of file gpu.h.

Constructor & Destructor Documentation

◆ ~GPU()

GPU::~GPU ( )
inline

Definition at line 255 of file gpu.h.

255 {
256 device = nullptr;
257 adapter = nullptr;
258 queue = nullptr;
259 instance = nullptr;
260 };

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:21

◆ init_gpu()

void GPU::init_gpu ( )
inline

Definition at line 129 of file gpu.h.

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

◆ 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) return;
116
117 for (uint32_t i = 0; i < info->messageCount; ++i) {
118 const auto& msg = info->messages[i];
119 std::cerr << "Shader Error ["
120 << (msg.type == wgpu::CompilationMessageType::Error ? "ERR" : "WARN")
121 << "]"
122 << " Line " << msg.lineNum << ":" << msg.linePos << " - "
123 << msg.message.data // .data for StringView
124 << std::endl;
125 }
126 });
127 };

◆ 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 34 of file gpu.h.

34 {
35 if (!device) 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 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: