100 lines
3.5 KiB
C++
100 lines
3.5 KiB
C++
#include <psemek/wgpu/adapter.hpp>
|
|
#include <psemek/wgpu/external/webgpu.h>
|
|
|
|
#include <cstring>
|
|
|
|
namespace psemek::wgpu
|
|
{
|
|
|
|
std::vector<feature> adapter::enumerate_features()
|
|
{
|
|
std::size_t count = wgpuAdapterEnumerateFeatures((WGPUAdapter)get(), nullptr);
|
|
std::vector<feature> 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<device::lost_callback> 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<device::request_callback> 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);
|
|
}
|
|
|
|
}
|