166 lines
9.8 KiB
C++
166 lines
9.8 KiB
C++
#include <psemek/wgpu/adapter.hpp>
|
|
#include <psemek/wgpu/detail/string_view.hpp>
|
|
#include <psemek/wgpu/detail/status.hpp>
|
|
#include <psemek/wgpu/external/webgpu.h>
|
|
|
|
#include <cstring>
|
|
|
|
namespace psemek::wgpu
|
|
{
|
|
|
|
std::vector<feature> adapter::enumerate_features() const
|
|
{
|
|
WGPUSupportedFeatures supported_features;
|
|
wgpuAdapterGetFeatures((WGPUAdapter)get(), &supported_features);
|
|
return std::vector<feature>((feature const *)supported_features.features, (feature const *)(supported_features.features) + supported_features.featureCount);
|
|
}
|
|
|
|
limits adapter::get_limits() const
|
|
{
|
|
WGPULimits limits = {};
|
|
detail::check_status("wgpuAdapterGetLimits", wgpuAdapterGetLimits((WGPUAdapter)get(), &limits));
|
|
|
|
// TODO: support out chain
|
|
wgpu::limits result;
|
|
result.max_texture_dimension_1D = limits.maxTextureDimension1D;
|
|
result.max_texture_dimension_2D = limits.maxTextureDimension2D;
|
|
result.max_texture_dimension_3D = limits.maxTextureDimension3D;
|
|
result.max_texture_array_layers = limits.maxTextureArrayLayers;
|
|
result.max_bind_groups = limits.maxBindGroups;
|
|
result.max_bind_groups_plus_vertex_buffers = limits.maxBindGroupsPlusVertexBuffers;
|
|
result.max_bindings_per_bind_group = limits.maxBindingsPerBindGroup;
|
|
result.max_dynamic_uniform_buffers_per_pipeline_layout = limits.maxDynamicUniformBuffersPerPipelineLayout;
|
|
result.max_dynamic_storage_buffers_per_pipeline_layout = limits.maxDynamicStorageBuffersPerPipelineLayout;
|
|
result.max_sampled_textures_per_shader_stage = limits.maxSampledTexturesPerShaderStage;
|
|
result.max_samplers_per_shader_stage = limits.maxSamplersPerShaderStage;
|
|
result.max_storage_buffers_per_shader_stage = limits.maxStorageBuffersPerShaderStage;
|
|
result.max_storage_textures_per_shader_stage = limits.maxStorageTexturesPerShaderStage;
|
|
result.max_uniform_buffers_per_shader_stage = limits.maxUniformBuffersPerShaderStage;
|
|
result.max_uniform_buffer_binding_size = limits.maxUniformBufferBindingSize;
|
|
result.max_storage_buffer_binding_size = limits.maxStorageBufferBindingSize;
|
|
result.min_uniform_buffer_offset_alignment = limits.minUniformBufferOffsetAlignment;
|
|
result.min_storage_buffer_offset_alignment = limits.minStorageBufferOffsetAlignment;
|
|
result.max_vertex_buffers = limits.maxVertexBuffers;
|
|
result.max_buffer_size = limits.maxBufferSize;
|
|
result.max_vertex_attributes = limits.maxVertexAttributes;
|
|
result.max_vertex_buffer_array_stride = limits.maxVertexBufferArrayStride;
|
|
result.max_inter_stage_shader_variables = limits.maxInterStageShaderVariables;
|
|
result.max_color_attachments = limits.maxColorAttachments;
|
|
result.max_color_attachment_bytes_per_sample = limits.maxColorAttachmentBytesPerSample;
|
|
result.max_compute_workgroup_storage_size = limits.maxComputeWorkgroupStorageSize;
|
|
result.max_compute_invocations_per_workgroup = limits.maxComputeInvocationsPerWorkgroup;
|
|
result.max_compute_workgroup_size_x = limits.maxComputeWorkgroupSizeX;
|
|
result.max_compute_workgroup_size_y = limits.maxComputeWorkgroupSizeY;
|
|
result.max_compute_workgroup_size_z = limits.maxComputeWorkgroupSizeZ;
|
|
result.max_compute_workgroups_per_dimension = limits.maxComputeWorkgroupsPerDimension;
|
|
|
|
return result;
|
|
}
|
|
|
|
adapter::info adapter::get_info() const
|
|
{
|
|
WGPUAdapterInfo info;
|
|
detail::check_status("wgpuAdapterGetInfo", wgpuAdapterGetInfo((WGPUAdapter)get(), &info));
|
|
|
|
return {
|
|
.vendor = std::string_view(info.vendor.data, info.vendor.length),
|
|
.architecture = std::string_view(info.architecture.data, info.architecture.length),
|
|
.device = std::string_view(info.device.data, info.device.length),
|
|
.description = std::string_view(info.description.data, info.description.length),
|
|
.backend_type = (backend_type)info.backendType,
|
|
.adapter_type = (type)info.adapterType,
|
|
.vendor_id = info.vendorID,
|
|
.device_id = info.deviceID,
|
|
};
|
|
}
|
|
|
|
bool adapter::has_feature(feature feature) const
|
|
{
|
|
return wgpuAdapterHasFeature((WGPUAdapter)get(), (WGPUFeatureName)feature);
|
|
}
|
|
|
|
void adapter::request_device(callback_mode mode, device::descriptor const & descriptor, device::request_callback const & callback)
|
|
{
|
|
WGPULimits limits = {};
|
|
if (descriptor.required_limits)
|
|
{
|
|
limits.nextInChain = (WGPUChainedStructOut *)detail::fill_chain_out(descriptor.required_limits->chain);
|
|
|
|
limits.maxTextureDimension1D = descriptor.required_limits->limits.max_texture_dimension_1D;
|
|
limits.maxTextureDimension2D = descriptor.required_limits->limits.max_texture_dimension_2D;
|
|
limits.maxTextureDimension3D = descriptor.required_limits->limits.max_texture_dimension_3D;
|
|
limits.maxTextureArrayLayers = descriptor.required_limits->limits.max_texture_array_layers;
|
|
limits.maxBindGroups = descriptor.required_limits->limits.max_bind_groups;
|
|
limits.maxBindGroupsPlusVertexBuffers = descriptor.required_limits->limits.max_bind_groups_plus_vertex_buffers;
|
|
limits.maxBindingsPerBindGroup = descriptor.required_limits->limits.max_bindings_per_bind_group;
|
|
limits.maxDynamicUniformBuffersPerPipelineLayout = descriptor.required_limits->limits.max_dynamic_uniform_buffers_per_pipeline_layout;
|
|
limits.maxDynamicStorageBuffersPerPipelineLayout = descriptor.required_limits->limits.max_dynamic_storage_buffers_per_pipeline_layout;
|
|
limits.maxSampledTexturesPerShaderStage = descriptor.required_limits->limits.max_sampled_textures_per_shader_stage;
|
|
limits.maxSamplersPerShaderStage = descriptor.required_limits->limits.max_samplers_per_shader_stage;
|
|
limits.maxStorageBuffersPerShaderStage = descriptor.required_limits->limits.max_storage_buffers_per_shader_stage;
|
|
limits.maxStorageTexturesPerShaderStage = descriptor.required_limits->limits.max_storage_textures_per_shader_stage;
|
|
limits.maxUniformBuffersPerShaderStage = descriptor.required_limits->limits.max_uniform_buffers_per_shader_stage;
|
|
limits.maxUniformBufferBindingSize = descriptor.required_limits->limits.max_uniform_buffer_binding_size;
|
|
limits.maxStorageBufferBindingSize = descriptor.required_limits->limits.max_storage_buffer_binding_size;
|
|
limits.minUniformBufferOffsetAlignment = descriptor.required_limits->limits.min_uniform_buffer_offset_alignment;
|
|
limits.minStorageBufferOffsetAlignment = descriptor.required_limits->limits.min_storage_buffer_offset_alignment;
|
|
limits.maxVertexBuffers = descriptor.required_limits->limits.max_vertex_buffers;
|
|
limits.maxBufferSize = descriptor.required_limits->limits.max_buffer_size;
|
|
limits.maxVertexAttributes = descriptor.required_limits->limits.max_vertex_attributes;
|
|
limits.maxVertexBufferArrayStride = descriptor.required_limits->limits.max_vertex_buffer_array_stride;
|
|
limits.maxInterStageShaderVariables = descriptor.required_limits->limits.max_inter_stage_shader_variables;
|
|
limits.maxColorAttachments = descriptor.required_limits->limits.max_color_attachments;
|
|
limits.maxColorAttachmentBytesPerSample = descriptor.required_limits->limits.max_color_attachment_bytes_per_sample;
|
|
limits.maxComputeWorkgroupStorageSize = descriptor.required_limits->limits.max_compute_workgroup_storage_size;
|
|
limits.maxComputeInvocationsPerWorkgroup = descriptor.required_limits->limits.max_compute_invocations_per_workgroup;
|
|
limits.maxComputeWorkgroupSizeX = descriptor.required_limits->limits.max_compute_workgroup_size_x;
|
|
limits.maxComputeWorkgroupSizeY = descriptor.required_limits->limits.max_compute_workgroup_size_y;
|
|
limits.maxComputeWorkgroupSizeZ = descriptor.required_limits->limits.max_compute_workgroup_size_z;
|
|
limits.maxComputeWorkgroupsPerDimension = descriptor.required_limits->limits.max_compute_workgroups_per_dimension;
|
|
}
|
|
|
|
WGPUDeviceDescriptor device_desc = {};
|
|
device_desc.nextInChain = (WGPUChainedStruct const *)detail::fill_chain(descriptor.chain);
|
|
device_desc.label = detail::to_string_view(descriptor.label);
|
|
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 = detail::to_string_view(descriptor.default_queue.label);
|
|
device_desc.deviceLostCallbackInfo.mode = (WGPUCallbackMode)descriptor.lost_callback_mode;
|
|
device_desc.deviceLostCallbackInfo.callback = [](WGPUDevice const *, WGPUDeviceLostReason reason, WGPUStringView message, void * userdata, void *)
|
|
{
|
|
std::unique_ptr<device::lost_callback> callback{(device::lost_callback *)userdata};
|
|
if (*callback) (*callback)((device::lost_reason)reason, std::string(message.data, message.length));
|
|
};
|
|
device_desc.deviceLostCallbackInfo.userdata1 = new device::lost_callback(descriptor.lost_callback);
|
|
device_desc.uncapturedErrorCallbackInfo.callback = [](WGPUDevice const *, WGPUErrorType type, WGPUStringView message, void * userdata, void *)
|
|
{
|
|
auto callback = (device::uncaptured_error_callback *)userdata;
|
|
if (*callback) (*callback)((error_type)type, std::string(message.data, message.length));
|
|
};
|
|
device_desc.uncapturedErrorCallbackInfo.userdata1 = new device::uncaptured_error_callback(descriptor.uncaptured_error_callback);
|
|
|
|
WGPURequestDeviceCallbackInfo callback_info = {};
|
|
callback_info.mode = (WGPUCallbackMode)mode;
|
|
callback_info.callback = [](WGPURequestDeviceStatus status, WGPUDevice device, WGPUStringView message, void * userdata, void *)
|
|
{
|
|
std::unique_ptr<device::request_callback> callback{(device::request_callback *)userdata};
|
|
if (*callback) (*callback)((device::request_status)status, wgpu::device(device), std::string(message.data, message.length));
|
|
};
|
|
callback_info.userdata1 = new device::request_callback(callback);
|
|
|
|
wgpuAdapterRequestDevice((WGPUAdapter)get(), &device_desc, callback_info);
|
|
}
|
|
|
|
void adapter::reference(void * ptr)
|
|
{
|
|
wgpuAdapterAddRef((WGPUAdapter)ptr);
|
|
}
|
|
|
|
void adapter::release(void * ptr)
|
|
{
|
|
wgpuAdapterRelease((WGPUAdapter)ptr);
|
|
}
|
|
|
|
}
|