#include #include #include namespace psemek::wgpu { std::vector adapter::enumerate_features() { std::size_t count = wgpuAdapterEnumerateFeatures((WGPUAdapter)get(), nullptr); std::vector result(count); wgpuAdapterEnumerateFeatures((WGPUAdapter)get(), (WGPUFeatureName *)result.data()); return result; } limits adapter::get_limits() { WGPUSupportedLimits limits = {}; wgpuAdapterGetLimits((WGPUAdapter)get(), &limits); // TODO: support out chain wgpu::limits result; static_assert(sizeof(result) == sizeof(limits.limits)); std::memcpy(&result, &limits.limits, sizeof(result)); return result; } adapter::properties adapter::get_properties() { WGPUAdapterProperties props; wgpuAdapterGetProperties((WGPUAdapter)get(), &props); return { .vendor_id = props.vendorID, .vendor_name = props.vendorName, .architecture = props.architecture, .device_id = props.deviceID, .name = props.name, .driver_description = props.driverDescription, .adapter_type = (adapter::type)props.adapterType, .backend_type = (backend_type)props.backendType, }; } bool adapter::has_feature(feature feature) { return wgpuAdapterHasFeature((WGPUAdapter)get(), (WGPUFeatureName)feature); } void adapter::request_device(device::descriptor const & descriptor, device::request_callback const & callback) { WGPURequiredLimits limits = {}; if (descriptor.required_limits) { static_assert(sizeof(limits.limits) == sizeof(descriptor.required_limits->limits)); limits.nextInChain = (WGPUChainedStruct const *)detail::fill_chain(descriptor.required_limits->chain); std::memcpy(&limits.limits, &descriptor.required_limits->limits, sizeof(limits.limits)); } auto device_lost_userdata = new device::lost_callback(descriptor.lost_callback); auto device_lost_real_callback = [](WGPUDeviceLostReason reason, char const * message, void * userdata) { std::unique_ptr callback((device::lost_callback *)userdata); if (*callback) (*callback)((device::lost_reason)reason, message ? message : ""); }; WGPUDeviceDescriptor device_desc = {}; device_desc.nextInChain = (WGPUChainedStruct const *)detail::fill_chain(descriptor.chain); device_desc.label = descriptor.label.data(); device_desc.requiredFeatureCount = descriptor.required_features.size(); device_desc.requiredFeatures = (WGPUFeatureName const *)descriptor.required_features.data(); device_desc.requiredLimits = descriptor.required_limits ? &limits : nullptr; device_desc.defaultQueue.nextInChain = (WGPUChainedStruct const *)detail::fill_chain(descriptor.default_queue.chain); device_desc.defaultQueue.label = descriptor.default_queue.label.data(); device_desc.deviceLostCallback = device_lost_real_callback; device_desc.deviceLostUserdata = device_lost_userdata; auto userdata = new device::request_callback(callback); auto real_callback = [](WGPURequestDeviceStatus status, WGPUDevice device, char const * message, void * userdata) { std::unique_ptr callback{(device::request_callback *)userdata}; if (*callback) (*callback)((device::request_status)status, wgpu::device(device), message ? message : ""); }; wgpuAdapterRequestDevice((WGPUAdapter)get(), &device_desc, real_callback, userdata); } void adapter::reference(void * ptr) { wgpuAdapterReference((WGPUAdapter)ptr); } void adapter::release(void * ptr) { wgpuAdapterRelease((WGPUAdapter)ptr); } }