psemek/libs/wgpu/source/instance.cpp
lisyarus 45fbc7399c
All checks were successful
Run tests / Run tests (push) Successful in 7m47s
Update to wgpu-native v29.0.1.1
2026-07-10 17:40:56 +03:00

109 lines
3.5 KiB
C++

#include <psemek/wgpu/instance.hpp>
#include <psemek/wgpu/detail/string_view.hpp>
#include <psemek/wgpu/detail/status.hpp>
#include <psemek/wgpu/external/webgpu.h>
#include <psemek/wgpu/external/wgpu.h>
#include <psemek/util/not_implemented.hpp>
namespace psemek::wgpu
{
namespace
{
struct extras
{};
detail::chained_struct_ptr to_chained_struct(extras const &)
{
WGPUInstanceExtras chained = {};
chained.chain.sType = (WGPUSType)WGPUSType_InstanceExtras;
chained.backends = WGPUInstanceBackend_Primary;
chained.flags = WGPUInstanceFlag_Empty;
return detail::make_chained_struct(chained);
}
}
std::vector<instance::feature> instance::get_features()
{
// TODO: implement via wgpuGetInstanceFeatures
// Unclear how the array size is returned
util::not_implemented();
}
instance::limits instance::get_limits()
{
WGPUInstanceLimits limits;
detail::check_status("wgpuGetInstanceLimits", wgpuGetInstanceLimits(&limits));
return {
.timed_wait_any_max_count = limits.timedWaitAnyMaxCount,
};
}
instance instance::create(descriptor const & desc)
{
std::vector<chained_struct> chain = desc.chain;
chain.push_back(extras{});
WGPUInstanceDescriptor descriptor = {};
descriptor.nextInChain = (WGPUChainedStruct *)detail::fill_chain(chain);
descriptor.requiredFeatureCount = desc.required_features.size();
descriptor.requiredFeatures = (WGPUInstanceFeatureName const *)desc.required_features.data();
WGPUInstanceLimits limits;
if (desc.required_limits)
{
limits.timedWaitAnyMaxCount = desc.required_limits->timed_wait_any_max_count;
descriptor.requiredLimits = &limits;
}
return instance(wgpuCreateInstance(&descriptor));
}
void instance::process_events()
{
wgpuInstanceProcessEvents((WGPUInstance)get());
}
surface instance::create_surface(surface::descriptor const & desc)
{
WGPUSurfaceDescriptor descriptor = {};
descriptor.nextInChain = (WGPUChainedStruct *)detail::fill_chain(desc.chain);
descriptor.label = detail::to_string_view(desc.label);
return surface{wgpuInstanceCreateSurface((WGPUInstance)get(), &descriptor)};
}
void instance::request_adapter(callback_mode mode, adapter::request_options const & request_options, adapter::request_callback callback)
{
WGPURequestAdapterOptions options = {};
options.nextInChain = (WGPUChainedStruct *)detail::fill_chain(request_options.chain);
options.featureLevel = (WGPUFeatureLevel)request_options.feature_level;
options.powerPreference = (WGPUPowerPreference)request_options.power_preference;
options.forceFallbackAdapter = request_options.force_fallback_adapter;
options.backendType = (WGPUBackendType)request_options.backend_type;
options.compatibleSurface = (WGPUSurface)request_options.compatible_surface.get();
WGPURequestAdapterCallbackInfo callback_info = {};
callback_info.mode = (WGPUCallbackMode)mode;
callback_info.callback = [](WGPURequestAdapterStatus status, WGPUAdapter adapter, WGPUStringView message, void * userdata, void *)
{
std::unique_ptr<adapter::request_callback> callback{(adapter::request_callback *)userdata};
if (*callback) (*callback)(adapter::request_status{status}, wgpu::adapter(adapter), std::string_view(message.data, message.length));
};
callback_info.userdata1 = new adapter::request_callback(callback);
wgpuInstanceRequestAdapter((WGPUInstance)get(), &options, callback_info);
}
void instance::reference(void * ptr)
{
wgpuInstanceAddRef((WGPUInstance)ptr);
}
void instance::release(void * ptr)
{
wgpuInstanceRelease((WGPUInstance)ptr);
}
}