Update to wgpu-native v29.0.1.1
All checks were successful
Run tests / Run tests (push) Successful in 7m47s

This commit is contained in:
Nikita Lisitsa 2026-07-10 17:40:56 +03:00
parent 0d54fa7f03
commit 45fbc7399c
35 changed files with 5451 additions and 1112 deletions

View file

@ -105,7 +105,7 @@ if(NOT DEFINED PSEMEK_GRAPHICS_API)
endif()
if(PSEMEK_GRAPHICS_API STREQUAL WEBGPU)
find_package(wgpu-native 27.0.2.0 REQUIRED)
find_package(wgpu-native 29.0.1.1 EXACT REQUIRED)
endif()
message(STATUS "Using graphics API ${PSEMEK_GRAPHICS_API}")

View file

@ -284,6 +284,7 @@ namespace psemek::fonts
pages_.back().texture_view = std::make_unique<wgpu::texture_view>(pages_.back().texture.create_view(wgpu::texture_view::descriptor{
.format = wgpu::texture::format::r8unorm,
.dimension = wgpu::texture_view::dimension::_2d,
.usage = wgpu::texture::usage::texture_binding,
}));
}

View file

@ -14,8 +14,9 @@ namespace psemek::wgpu
enum class feature_level : std::uint32_t
{
compatibility = 1,
core = 2,
undefined = 0x00000000,
compatibility = 0x00000001,
core = 0x00000002,
};
enum class power_preference : std::uint32_t
@ -53,13 +54,11 @@ namespace psemek::wgpu
surface compatible_surface = {};
};
enum class request_status : std::uint32_t
{
success = 0x00000001,
instance_dropped = 0x00000002,
unavailable = 0x00000003,
error = 0x00000004,
unknown = 0x00000005,
enum class request_status : std::uint32_t {
success = 0x00000001,
callback_canceled = 0x00000002,
unavailable = 0x00000003,
error = 0x00000004,
};
using request_callback = std::function<void(request_status, adapter, std::string_view)>;
@ -82,6 +81,8 @@ namespace psemek::wgpu
type adapter_type;
uint32_t vendor_id;
uint32_t device_id;
std::uint32_t subgroup_min_size;
std::uint32_t subgroup_max_size;
};
std::vector<feature> enumerate_features() const;

View file

@ -79,6 +79,7 @@ namespace psemek::wgpu
std::vector<chained_struct> chain = {};
std::uint32_t binding;
shader_stage visibility;
std::uint32_t array_size = 0;
buffer_binding_layout buffer = {};
sampler_binding_layout sampler = {};
texture_binding_layout texture = {};

View file

@ -3,6 +3,7 @@
#include <psemek/wgpu/callback_mode.hpp>
#include <psemek/wgpu/chained_struct.hpp>
#include <psemek/wgpu/detail/object.hpp>
#include <psemek/util/span.hpp>
#include <cstdint>
#include <string>
@ -47,11 +48,10 @@ namespace psemek::wgpu
enum class map_async_status : std::uint32_t
{
success = 0x00000001,
instance_dropped = 0x00000002,
error = 0x00000003,
aborted = 0x00000004,
unknown = 0x00000005,
success = 0x00000001,
callback_canceled = 0x00000002,
error = 0x00000003,
aborted = 0x00000004,
};
struct descriptor {
@ -70,6 +70,8 @@ namespace psemek::wgpu
map_state get_map_state() const;
void const * get_const_mapped_range(std::size_t offset, std::size_t size) const;
void * get_mapped_range(std::size_t offset, std::size_t size);
bool read_mapped_range(std::size_t offset, util::span<char> destination);
bool write_mapped_range(std::size_t offset, util::span<char const> source);
void map_async(callback_mode mode, map_mode flags, std::size_t offset, std::size_t size, map_callback const & callback);
void unmap();
void set_label(std::string const & label);

View file

@ -45,7 +45,6 @@ namespace psemek::wgpu
};
void * fill_chain(std::vector<chained_struct> const & chain);
void * fill_chain_out(std::vector<chained_struct> const & chain);
using chained_struct_ptr = std::shared_ptr<chained_struct_base>;

View file

@ -8,6 +8,7 @@
#include <psemek/wgpu/buffer.hpp>
#include <psemek/wgpu/query_set.hpp>
#include <psemek/wgpu/image_copy.hpp>
#include <psemek/wgpu/image_subresource_range.hpp>
#include <psemek/math/vector.hpp>
#include <vector>
@ -39,6 +40,7 @@ namespace psemek::wgpu
void pop_debug_group();
void resolve_query_set(query_set const & query_set, std::uint32_t first_query, std::uint32_t query_count, buffer const & destination, std::uint64_t destination_offset);
void write_timestamp(query_set const & query_set, std::uint32_t query_index);
void clear_texture(texture const & texture, image_subresource_range const & range);
command_buffer finish(command_buffer::descriptor const & desc);
void set_label(std::string const & label);

View file

@ -31,7 +31,9 @@ namespace psemek::wgpu
void set_pipeline(compute_pipeline const & pipeline);
void dispatch_workgroups(math::vector<std::uint32_t, 3> const & workgroup_count);
void dispatch_workgroups_indirect(buffer const & indirect_buffer, std::uint64_t offset);
void set_push_constants(std::uint32_t offset, util::span<char const> data);
void set_immediates(std::uint32_t offset, util::span<char const> data);
void begin_pipeline_statistics_query(query_set const & query_set, std::uint32_t query_index);
void end_pipeline_statistics_query();
void write_timestamp(query_set const & query_set, std::uint32_t query_index);
void insert_debug_marker(std::string const & marker_label);
void push_debug_group(std::string const & group_label);

View file

@ -24,27 +24,32 @@
namespace psemek::wgpu
{
enum class feature : std::uint32_t {
undefined = 0x00000000,
depth_clip_control = 0x00000001,
depth32_float_stencil8 = 0x00000002,
timestamp_query = 0x00000003,
texture_compression_BC = 0x00000004,
texture_compression_BC_sliced_3D = 0x00000005,
texture_compression_ETC2 = 0x00000006,
texture_compression_ASTC = 0x00000007,
texture_compression_ASTC_sliced_3D = 0x00000008,
indirect_first_instance = 0x00000009,
shader_f16 = 0x0000000A,
rg11b10_ufloat_renderable = 0x0000000B,
bgra8_unorm_storage = 0x0000000C,
float32_filterable = 0x0000000D,
float32_blendable = 0x0000000E,
clip_distances = 0x0000000F,
dual_source_blending = 0x00000010,
enum class feature : std::uint32_t
{
core_features_and_limits = 0x00000001,
depth_clip_control = 0x00000002,
depth32_float_stencil8 = 0x00000003,
texture_compression_bc = 0x00000004,
texture_compression_bc_sliced_3D = 0x00000005,
texture_compression_etc2 = 0x00000006,
texture_compression_astc = 0x00000007,
texture_compression_astc_sliced_3D = 0x00000008,
timestamp_query = 0x00000009,
indirect_first_instance = 0x0000000A,
shader_f16 = 0x0000000B,
rg11b10_ufloat_renderable = 0x0000000C,
bgra8_unorm_storage = 0x0000000D,
float32_filterable = 0x0000000E,
float32_blendable = 0x0000000F,
clip_distances = 0x00000010,
dual_source_blending = 0x00000011,
subgroupd = 0x00000012,
texture_formats_tier1 = 0x00000013,
texture_formats_tier2 = 0x00000014,
primitive_index = 0x00000015,
texture_component_swizzle = 0x00000016,
push_constants = 0x00030001,
immediates = 0x00030001,
texture_adapter_specific_format_features = 0x00030002,
multi_draw_indirect_count = 0x00030004,
vertex_writable_storage = 0x00030005,
@ -57,17 +62,20 @@ namespace psemek::wgpu
texture_compression_astc_hdr = 0x0003000c,
mappable_primary_buffers = 0x0003000e,
buffer_binding_array = 0x0003000f,
uniform_buffer_and_storage_texture_array_non_uniform_indexing = 0x00030010,
storage_texture_array_non_uniform_indexing = 0x00030010,
address_mode_clamp_to_zero = 0x00030011,
address_mode_clamp_to_border = 0x00030012,
polygon_mode_line = 0x00030013,
polygon_mode_point = 0x00030014,
conservative_rasterization = 0x00030015,
spirv_shader_passthrough = 0x00030017,
clear_texture = 0x00030016,
multiview = 0x00030018,
vertex_attribute64bit = 0x00030019,
texture_format_nv12 = 0x0003001a,
ray_query = 0x0003001c,
shader_f64 = 0x0003001d,
shader_i16 = 0x0003001e,
shader_primitive_index = 0x0003001f,
shader_early_depth_test = 0x00030020,
subgroup = 0x00030021,
subgroup_vertex = 0x00030022,
@ -75,6 +83,22 @@ namespace psemek::wgpu
timestamp_query_inside_encoders = 0x00030024,
timestamp_query_inside_passes = 0x00030025,
shader_int64 = 0x00030026,
shader_float32_atomic = 0x00030027,
texture_atomic = 0x00030028,
texture_format_p010 = 0x00030029,
pipeline_cache = 0x0003002b,
shader_int64_atomic_min_max = 0x0003002c,
shader_int64_atomic_all_ops = 0x0003002d,
texture_int64_atomic = 0x00030030,
shader_barycentrics = 0x00030037,
selective_multiview = 0x00030038,
multisample_array = 0x0003003a,
cooperative_matrix = 0x0003003b,
shader_per_vertex = 0x0003003c,
shader_draw_index = 0x0003003d,
acceleration_structure_binding_array = 0x0003003e,
memory_decoration_coherent = 0x0003003f,
memory_decoration_volatile = 0x00030040,
};
struct limits
@ -104,27 +128,27 @@ namespace psemek::wgpu
std::uint32_t max_inter_stage_shader_variables = 15;
std::uint32_t max_color_attachments = 1;
std::uint32_t max_color_attachment_bytes_per_sample = 4;
std::uint32_t max_compute_workgroup_storage_size = 16384;
std::uint32_t max_compute_invocations_per_workgroup = 256;
std::uint32_t max_compute_workgroup_size_x = 256;
std::uint32_t max_compute_workgroup_size_y = 256;
std::uint32_t max_compute_workgroup_size_z = 64;
std::uint32_t max_compute_workgroups_per_dimension = 65535;
std::uint32_t max_immediate_size = 128;
};
struct native_limits
{
std::uint32_t max_push_constant_size = 0;
std::uint32_t max_non_sampler_bindings = 0;
};
enum class create_pipeline_async_status : std::uint32_t
{
success = 0x00000001,
instance_dropped = 0x00000002,
validation_error = 0x00000003,
internal_error = 0x00000004,
unknown = 0x00000005,
success = 0x00000001,
callback_canceled = 0x00000002,
validation_error = 0x00000003,
internal_error = 0x00000004,
};
enum class error_filter : std::uint32_t
@ -145,9 +169,9 @@ namespace psemek::wgpu
enum class pop_error_scope_status : std::uint32_t
{
success = 0x00000001,
instance_dropped = 0x00000002,
empty_stack = 0x00000003,
success = 0x00000001,
callback_canceled = 0x00000002,
error = 0x00000003,
};
struct device
@ -157,10 +181,10 @@ namespace psemek::wgpu
enum class lost_reason : std::uint32_t
{
unknown = 0x00000001,
destroyed = 0x00000002,
instance_dropped = 0x00000003,
failed_creation = 0x00000004,
unknown = 0x00000001,
destroyed = 0x00000002,
callback_canceled = 0x00000003,
failed_creation = 0x00000004,
};
using lost_callback = std::function<void(lost_reason, std::string_view)>;
@ -186,10 +210,9 @@ namespace psemek::wgpu
enum class request_status : std::uint32_t
{
success = 0x00000001,
instance_dropped = 0x00000002,
error = 0x00000003,
unknown = 0x00000004,
success = 0x00000001,
callback_canceled = 0x00000002,
error = 0x00000003,
};
using request_callback = std::function<void(request_status, device, std::string const & message)>;
@ -212,6 +235,7 @@ namespace psemek::wgpu
render_bundle_encoder create_render_bundle_encoder(render_bundle_encoder::descriptor const & desc);
sampler create_sampler(sampler::descriptor const & desc);
shader_module create_shader_module(shader_module::descriptor const & desc);
shader_module create_shader_module_trusted(shader_module::descriptor const & desc, shader_module::runtime_checks runtime_checks);
texture create_texture(texture::descriptor const & desc);
void destroy();
std::vector<feature> enumerate_features() const;
@ -220,6 +244,8 @@ namespace psemek::wgpu
void push_error_scope(error_filter filter);
void pop_error_scope(callback_mode mode, pop_error_callback const & callback);
void set_label(std::string const & label);
bool start_graphics_debugger_capture();
void stop_graphics_debugger_capture();
static void reference(void * ptr);
static void release(void * ptr);

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,16 @@
#pragma once
#include <psemek/wgpu/texture.hpp>
namespace psemek::wgpu
{
struct image_subresource_range {
texture::aspect aspect;
std::uint32_t base_mip_level = 0;
std::uint32_t mip_level_count = 1;
std::uint32_t base_array_layer = 0;
std::uint32_t array_layer_count = 1;
};
}

View file

@ -15,11 +15,28 @@ namespace psemek::wgpu
// TODO: add WGPUFuture stuff when it's supported in wgpu-native
enum class feature : std::uint32_t
{
timed_wait_any = 0x00000001,
shader_source_spirv = 0x00000002,
multiple_devices_per_adapter = 0x00000003,
};
struct limits
{
std::size_t timed_wait_any_max_count;
};
struct descriptor
{
std::vector<chained_struct> chain = {};
std::vector<feature> required_features = {};
std::optional<limits> required_limits = {};
};
static std::vector<feature> get_features();
static limits get_limits();
static instance create(descriptor const & desc);
void process_events();

View file

@ -10,13 +10,6 @@
namespace psemek::wgpu
{
struct push_constant_range
{
shader_stage stages;
std::uint32_t start;
std::uint32_t end;
};
struct pipeline_layout
: detail::object<pipeline_layout>
{
@ -27,11 +20,7 @@ namespace psemek::wgpu
std::vector<chained_struct> chain = {};
std::string label = {};
std::vector<bind_group_layout> layouts;
};
struct extras
{
std::vector<push_constant_range> ranges;
std::uint32_t immediate_size = 0;
};
void set_label(std::string const & label);
@ -47,6 +36,4 @@ namespace psemek::wgpu
friend struct device;
};
detail::chained_struct_ptr to_chained_struct(pipeline_layout::extras && value);
}

View file

@ -30,19 +30,19 @@ namespace psemek::wgpu
enum class work_done_status : std::uint32_t
{
success = 0x00000001,
instance_dropped = 0x00000002,
error = 0x00000003,
unknown = 0x00000004,
success = 0x00000001,
callback_canceled = 0x00000002,
error = 0x00000003,
};
using work_done_callback = std::function<void(work_done_status)>;
using work_done_callback = std::function<void(work_done_status, std::string_view)>;
void submit(std::vector<command_buffer> const & commands);
void write_buffer(buffer const & buffer, std::uint64_t offset, util::span<char const> data);
void write_texture(texel_copy_texture_info const & dest, util::span<char const> data, texel_copy_buffer_layout const & data_layout, math::vector<std::uint32_t, 3> const & write_size);
void on_submitted_work_done(callback_mode mode, work_done_callback const & callback);
void set_label(std::string const & label);
float get_timestamp_period();
static void reference(void * ptr);
static void release(void * ptr);

View file

@ -80,7 +80,7 @@ namespace psemek::wgpu
void set_scissor_rect(math::box<std::uint32_t, 2> const & rect);
void set_blend_constant(math::vector<double, 4> const & color);
void set_stencil_reference(std::uint32_t reference);
void set_push_constants(shader_stage stages, std::uint32_t offset, util::span<char const> data);
void set_immediates(std::uint32_t offset, util::span<char const> data);
void draw(std::uint32_t vertex_count, std::uint32_t instance_count, std::uint32_t first_vertex, std::uint32_t first_instance);
void draw_indexed(std::uint32_t index_count, std::uint32_t instance_count, std::uint32_t first_index, std::uint32_t base_vertex, std::uint32_t first_instance);
void draw_indirect(buffer const & indirect_buffer, std::uint64_t offset);
@ -92,6 +92,8 @@ namespace psemek::wgpu
void execute_bundles(std::vector<render_bundle> const & bundles);
void begin_occlusion_query(std::uint32_t query_index);
void end_occlusion_query();
void begin_pipeline_statistics_query(query_set const & query_set, std::uint32_t query_index);
void end_pipeline_statistics_query();
void write_timestamp(query_set const & query_set, std::uint32_t query_index);
void insert_debug_marker(std::string_view marker_label);
void push_debug_group(std::string_view group_label);

View file

@ -19,10 +19,9 @@ namespace psemek::wgpu
enum class vertex_step_mode : std::uint32_t
{
vertex_buffer_not_used = 0x00000000,
undefined = 0x00000001,
vertex = 0x00000002,
instance = 0x00000003,
undefined = 0x00000000,
vertex = 0x00000001,
instance = 0x00000002,
};
enum class vertex_format : std::uint32_t

View file

@ -17,6 +17,8 @@ namespace psemek::wgpu
clamp_to_edge = 0x00000001,
repeat = 0x00000002,
mirror_repeat = 0x00000003,
clamp_to_border = 0x00000004,
};
enum class filter_mode : std::uint32_t
@ -65,6 +67,20 @@ namespace psemek::wgpu
std::uint16_t max_anisotropy = 1;
};
enum class border_color : std::uint32_t
{
undefined = 0x00000000,
transparent_black = 0x00000001,
opaque_black = 0x00000002,
opaque_white = 0x00000003,
zero = 0x00000004,
};
struct extras
{
sampler::border_color border_color;
};
void set_label(std::string const & label);
static void reference(void * ptr);
@ -78,4 +94,6 @@ namespace psemek::wgpu
friend struct device;
};
detail::chained_struct_ptr to_chained_struct(sampler::extras const & value);
}

View file

@ -22,10 +22,8 @@ namespace psemek::wgpu
enum class compilation_info_request_status : std::uint32_t
{
success = 0x00000001,
instance_dropped = 0x00000002,
error = 0x00000003,
unknown = 0x00000004,
success = 0x00000001,
callback_cancelled = 0x00000002,
};
enum class compilation_message_type : std::uint32_t
@ -81,6 +79,15 @@ namespace psemek::wgpu
std::vector<define> defines = {};
};
enum class runtime_checks : std::uint64_t
{
bounds_checks = 0x0000000000000001,
force_loop_bounding = 0x0000000000000002,
ray_query_initialization_tracking = 0x0000000000000004,
task_shader_dispatch_tracking = 0x0000000000000008,
mesh_shader_primitive_indices_clamp = 0x0000000000000010,
};
using compilation_info_callback = std::function<void(compilation_info_request_status, compilation_info const &)>;
void get_compilation_info(callback_mode mode, compilation_info_callback const & callback) const;
@ -97,6 +104,11 @@ namespace psemek::wgpu
friend struct device;
};
inline shader_module::runtime_checks operator | (shader_module::runtime_checks c1, shader_module::runtime_checks c2)
{
return static_cast<shader_module::runtime_checks>(static_cast<std::uint64_t>(c1) | static_cast<std::uint64_t>(c2));
}
detail::chained_struct_ptr to_chained_struct(shader_module::spirv_descriptor const & value);
detail::chained_struct_ptr to_chained_struct(shader_module::wgsl_descriptor const & value);
detail::chained_struct_ptr to_chained_struct(shader_module::glsl_descriptor && value);

View file

@ -14,6 +14,18 @@ namespace psemek::wgpu
struct adapter;
enum class predefined_color_space : std::uint32_t
{
srgb = 0x00000001,
display_p3 = 0x00000002,
};
enum class tone_mapping_mode : std::uint32_t
{
standard = 0x00000001,
extended = 0x00000002,
};
struct surface
: detail::object<surface>
{
@ -79,15 +91,21 @@ namespace psemek::wgpu
timeout = 0x00000003,
outdated = 0x00000004,
lost = 0x00000005,
out_of_memory = 0x00000006,
device_lost = 0x00000007,
error = 0x00000008,
error = 0x00000006,
occluded = 0x00030001,
};
wgpu::texture texture;
enum status status;
};
struct color_management
{
predefined_color_space color_space = predefined_color_space::srgb;
wgpu::tone_mapping_mode tone_mapping_mode = wgpu::tone_mapping_mode::standard;
};
void configure(configuration const & conf);
capabilities get_capabilities(adapter const & adapter) const;
current_texture get_current_texture() const;
@ -140,6 +158,7 @@ namespace psemek::wgpu
};
detail::chained_struct_ptr to_chained_struct(surface::configuration::extras const & value);
detail::chained_struct_ptr to_chained_struct(surface::color_management const & value);
detail::chained_struct_ptr to_chained_struct(surface::from_android_native_window const & value);
detail::chained_struct_ptr to_chained_struct(surface::from_metal_layer const & value);
detail::chained_struct_ptr to_chained_struct(surface::from_wayland_surface const & value);

View file

@ -12,6 +12,17 @@
namespace psemek::wgpu
{
enum class component_swizzle : std::uint32_t
{
undefined = 0x00000000,
zero = 0x00000001,
one = 0x00000002,
r = 0x00000003,
g = 0x00000004,
b = 0x00000005,
a = 0x00000006,
};
struct texture
: detail::object<texture>
{
@ -19,124 +30,124 @@ namespace psemek::wgpu
enum class format : std::uint32_t
{
undefined = 0x00000000,
r8unorm = 0x00000001,
r8snorm = 0x00000002,
r8uint = 0x00000003,
r8sint = 0x00000004,
r16uint = 0x00000005,
r16sint = 0x00000006,
r16float = 0x00000007,
rg8unorm = 0x00000008,
rg8snorm = 0x00000009,
rg8uint = 0x0000000a,
rg8sint = 0x0000000b,
r32float = 0x0000000c,
r32uint = 0x0000000d,
r32sint = 0x0000000e,
rg16uint = 0x0000000f,
rg16sint = 0x00000010,
rg16float = 0x00000011,
rgba8unorm = 0x00000012,
rgba8unorm_srgb = 0x00000013,
rgba8snorm = 0x00000014,
rgba8uint = 0x00000015,
rgba8sint = 0x00000016,
bgra8unorm = 0x00000017,
bgra8unorm_srgb = 0x00000018,
rgb10a2uint = 0x00000019,
rgb10a2unorm = 0x0000001a,
rg11b10ufloat = 0x0000001b,
rgb9e5ufloat = 0x0000001c,
rg32float = 0x0000001d,
rg32uint = 0x0000001e,
rg32sint = 0x0000001f,
rgba16uint = 0x00000020,
rgba16sint = 0x00000021,
rgba16float = 0x00000022,
rgba32float = 0x00000023,
rgba32uint = 0x00000024,
rgba32sint = 0x00000025,
stencil8 = 0x00000026,
depth16unorm = 0x00000027,
depth24plus = 0x00000028,
depth24plusstencil8 = 0x00000029,
depth32float = 0x0000002a,
depth32floatstencil8 = 0x0000002b,
bc1rgbaunorm = 0x0000002c,
bc1rgbaunorm_srgb = 0x0000002d,
bc2rgbaunorm = 0x0000002e,
bc2rgbaunorm_srgb = 0x0000002f,
bc3rgbaunorm = 0x00000030,
bc3rgbaunorm_srgb = 0x00000031,
bc4runorm = 0x00000032,
bc4rsnorm = 0x00000033,
bc5rgunorm = 0x00000034,
bc5rgsnorm = 0x00000035,
bc6hrgbufloat = 0x00000036,
bc6hrgbfloat = 0x00000037,
bc7rgbaunorm = 0x00000038,
bc7rgbaunorm_srgb = 0x00000039,
etc2rgb8unorm = 0x0000003a,
etc2rgb8unorm_srgb = 0x0000003b,
etc2rgb8a1unorm = 0x0000003c,
etc2rgb8a1unorm_srgb = 0x0000003d,
etc2rgba8unorm = 0x0000003e,
etc2rgba8unorm_srgb = 0x0000003f,
eacr11unorm = 0x00000040,
eacr11snorm = 0x00000041,
eacrg11unorm = 0x00000042,
eacrg11snorm = 0x00000043,
astc4x4unorm = 0x00000044,
astc4x4unorm_srgb = 0x00000045,
astc5x4unorm = 0x00000046,
astc5x4unorm_srgb = 0x00000047,
astc5x5unorm = 0x00000048,
astc5x5unorm_srgb = 0x00000049,
astc6x5unorm = 0x0000004a,
astc6x5unorm_srgb = 0x0000004b,
astc6x6unorm = 0x0000004c,
astc6x6unorm_srgb = 0x0000004d,
astc8x5unorm = 0x0000004e,
astc8x5unorm_srgb = 0x0000004f,
astc8x6unorm = 0x00000050,
astc8x6unorm_srgb = 0x00000051,
astc8x8unorm = 0x00000052,
astc8x8unorm_srgb = 0x00000053,
astc10x5unorm = 0x00000054,
astc10x5unorm_srgb = 0x00000055,
astc10x6unorm = 0x00000056,
astc10x6unorm_srgb = 0x00000057,
astc10x8unorm = 0x00000058,
astc10x8unorm_srgb = 0x00000059,
astc10x10unorm = 0x0000005a,
astc10x10unorm_srgb = 0x0000005b,
astc12x10unorm = 0x0000005c,
astc12x10unorm_srgb = 0x0000005d,
astc12x12unorm = 0x0000005e,
astc12x12unorm_srgb = 0x0000005f,
// texture_format16bit_norm
r16unorm = 0x00030001,
r16snorm = 0x00030002,
rg16unorm = 0x00030003,
rg16snorm = 0x00030004,
rgba16unorm = 0x00030005,
rgba16snorm = 0x00030006,
undefined = 0x00000000,
r8unorm = 0x00000001,
r8snorm = 0x00000002,
r8uint = 0x00000003,
r8sint = 0x00000004,
r16unorm = 0x00000005,
r16snorm = 0x00000006,
r16uint = 0x00000007,
r16sint = 0x00000008,
r16float = 0x00000009,
rg8unorm = 0x0000000a,
rg8snorm = 0x0000000b,
rg8uint = 0x0000000c,
rg8sint = 0x0000000d,
r32float = 0x0000000e,
r32uint = 0x0000000f,
r32sint = 0x00000010,
rg16unorm = 0x00000011,
rg16snorm = 0x00000012,
rg16uint = 0x00000013,
rg16sint = 0x00000014,
rg16float = 0x00000015,
rgba8unorm = 0x00000016,
rgba8unorm_srgb = 0x00000017,
rgba8snorm = 0x00000018,
rgba8uint = 0x00000019,
rgba8sint = 0x0000001a,
bgra8unorm = 0x0000001b,
bgra8unorm_srgb = 0x0000001c,
rgb10a2uint = 0x0000001d,
rgb10a2unorm = 0x0000001e,
rg11b10ufloat = 0x0000001f,
rgb9e5ufloat = 0x00000020,
rg32float = 0x00000021,
rg32uint = 0x00000022,
rg32sint = 0x00000023,
rgba16unorm = 0x00000024,
rgba16snorm = 0x00000025,
rgba16uint = 0x00000026,
rgba16sint = 0x00000027,
rgba16float = 0x00000028,
rgba32float = 0x00000029,
rgba32uint = 0x0000002a,
rgba32sint = 0x0000002b,
stencil8 = 0x0000002c,
depth16unorm = 0x0000002d,
depth24plus = 0x0000002e,
depth24plusstencil8 = 0x0000002f,
depth32float = 0x00000030,
depth32floatstencil8 = 0x00000031,
bc1rgbaunorm = 0x00000032,
bc1rgbaunorm_srgb = 0x00000033,
bc2rgbaunorm = 0x00000034,
bc2rgbaunorm_srgb = 0x00000035,
bc3rgbaunorm = 0x00000036,
bc3rgbaunorm_srgb = 0x00000037,
bc4runorm = 0x00000038,
bc4rsnorm = 0x00000039,
bc5rgunorm = 0x0000003a,
bc5rgsnorm = 0x0000003b,
bc6hrgbufloat = 0x0000003c,
bc6hrgbfloat = 0x0000003d,
bc7rgbaunorm = 0x0000003e,
bc7rgbaunorm_srgb = 0x0000003f,
etc2rgb8unorm = 0x00000040,
etc2rgb8unorm_srgb = 0x00000041,
etc2rgb8a1unorm = 0x00000042,
etc2rgb8a1unorm_srgb = 0x00000043,
etc2rgba8unorm = 0x00000044,
etc2rgba8unorm_srgb = 0x00000045,
eacr11unorm = 0x00000046,
eacr11snorm = 0x00000047,
eacrg11unorm = 0x00000048,
eacrg11snorm = 0x00000049,
astc4x4unorm = 0x0000004a,
astc4x4unorm_srgb = 0x0000004b,
astc5x4unorm = 0x0000004c,
astc5x4unorm_srgb = 0x0000004d,
astc5x5unorm = 0x0000004e,
astc5x5unorm_srgb = 0x0000004f,
astc6x5unorm = 0x00000050,
astc6x5unorm_srgb = 0x00000051,
astc6x6unorm = 0x00000052,
astc6x6unorm_srgb = 0x00000053,
astc8x5unorm = 0x00000054,
astc8x5unorm_srgb = 0x00000055,
astc8x6unorm = 0x00000056,
astc8x6unorm_srgb = 0x00000057,
astc8x8unorm = 0x00000058,
astc8x8unorm_srgb = 0x00000059,
astc10x5unorm = 0x0000005a,
astc10x5unorm_srgb = 0x0000005b,
astc10x6unorm = 0x0000005c,
astc10x6unorm_srgb = 0x0000005d,
astc10x8unorm = 0x0000005e,
astc10x8unorm_srgb = 0x0000005f,
astc10x10unorm = 0x00000060,
astc10x10unorm_srgb = 0x00000061,
astc12x10unorm = 0x00000062,
astc12x10unorm_srgb = 0x00000063,
astc12x12unorm = 0x00000064,
astc12x12unorm_srgb = 0x00000065,
// texture_format_nv12
nv12 = 0x00030007,
// texture_format_p010
p010 = 0x00030008,
};
enum class usage : std::uint64_t
{
none = 0x00000000,
copy_src = 0x00000001,
copy_dst = 0x00000002,
texture_binding = 0x00000004,
storage_binding = 0x00000008,
render_attachment = 0x00000010,
none = 0x00000000,
copy_src = 0x00000001,
copy_dst = 0x00000002,
texture_binding = 0x00000004,
storage_binding = 0x00000008,
render_attachment = 0x00000010,
transient_attachment = 0x00000020,
};
enum class dimension : std::uint32_t
@ -179,6 +190,16 @@ namespace psemek::wgpu
std::vector<enum format> view_formats = {};
};
// NB: swizzling is not implemented in wgpu yet
// https://github.com/gfx-rs/wgpu/issues/1028
struct component_swizzle
{
wgpu::component_swizzle r = wgpu::component_swizzle::r;
wgpu::component_swizzle g = wgpu::component_swizzle::g;
wgpu::component_swizzle b = wgpu::component_swizzle::b;
wgpu::component_swizzle a = wgpu::component_swizzle::a;
};
texture_view create_view(texture_view::descriptor const & desc);
void destroy();
std::uint32_t get_width() const;
@ -213,6 +234,7 @@ namespace psemek::wgpu
std::uint32_t base_array_layer = 0;
std::uint32_t array_layer_count = 1;
texture::aspect aspect = texture::aspect::all;
texture::usage usage;
};
inline texture::usage operator | (texture::usage u1, texture::usage u2)
@ -220,6 +242,8 @@ namespace psemek::wgpu
return static_cast<texture::usage>(static_cast<unsigned int>(u1) | static_cast<unsigned int>(u2));
}
detail::chained_struct_ptr to_chained_struct(texture::component_swizzle const & value);
std::size_t memory_usage(std::uint32_t width, std::uint32_t height, std::uint32_t depth, texture::format format);
std::size_t memory_usage(texture const & texture);

View file

@ -53,6 +53,7 @@ namespace psemek::wgpu
result.max_compute_workgroup_size_y = limits.maxComputeWorkgroupSizeY;
result.max_compute_workgroup_size_z = limits.maxComputeWorkgroupSizeZ;
result.max_compute_workgroups_per_dimension = limits.maxComputeWorkgroupsPerDimension;
result.max_immediate_size = limits.maxImmediateSize;
return result;
}
@ -71,6 +72,8 @@ namespace psemek::wgpu
.adapter_type = (type)info.adapterType,
.vendor_id = info.vendorID,
.device_id = info.deviceID,
.subgroup_min_size = info.subgroupMinSize,
.subgroup_max_size = info.subgroupMaxSize,
};
}
@ -84,7 +87,7 @@ namespace psemek::wgpu
WGPULimits limits = {};
if (descriptor.required_limits)
{
limits.nextInChain = (WGPUChainedStructOut *)detail::fill_chain_out(descriptor.required_limits->chain);
limits.nextInChain = (WGPUChainedStruct *)detail::fill_chain(descriptor.required_limits->chain);
limits.maxTextureDimension1D = descriptor.required_limits->limits.max_texture_dimension_1D;
limits.maxTextureDimension2D = descriptor.required_limits->limits.max_texture_dimension_2D;
@ -117,15 +120,16 @@ namespace psemek::wgpu
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;
limits.maxImmediateSize = descriptor.required_limits->limits.max_immediate_size;
}
WGPUDeviceDescriptor device_desc = {};
device_desc.nextInChain = (WGPUChainedStruct const *)detail::fill_chain(descriptor.chain);
device_desc.nextInChain = (WGPUChainedStruct *)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.nextInChain = (WGPUChainedStruct *)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 *)

View file

@ -37,6 +37,16 @@ namespace psemek::wgpu
return wgpuBufferGetMappedRange((WGPUBuffer)get(), offset, size);
}
bool buffer::read_mapped_range(std::size_t offset, util::span<char> destination)
{
return wgpuBufferReadMappedRange((WGPUBuffer)get(), offset, destination.data(), destination.size()) == WGPUStatus_Success;
}
bool buffer::write_mapped_range(std::size_t offset, util::span<char const> source)
{
return wgpuBufferWriteMappedRange((WGPUBuffer)get(), offset, source.data(), source.size()) == WGPUStatus_Success;
}
void buffer::map_async(callback_mode mode, map_mode flags, std::size_t offset, std::size_t size, map_callback const & callback)
{
WGPUBufferMapCallbackInfo callback_info = {};

View file

@ -30,30 +30,4 @@ namespace psemek::wgpu::detail
return first;
}
void * fill_chain_out(std::vector<chained_struct> const & chain)
{
WGPUChainedStructOut * first = nullptr;
WGPUChainedStructOut * current = nullptr;
for (auto const & s : chain)
{
auto p = (WGPUChainedStructOut *)s.ptr();
if (!first)
{
first = p;
current = p;
}
else
{
current->next = p;
current = p;
}
}
if (current)
current->next = nullptr;
return first;
}
}

View file

@ -1,13 +1,14 @@
#include <psemek/wgpu/command_encoder.hpp>
#include <psemek/wgpu/detail/string_view.hpp>
#include <psemek/wgpu/external/webgpu.h>
#include <psemek/wgpu/external/wgpu.h>
namespace psemek::wgpu
{
compute_pass_encoder command_encoder::begin_compute_pass(compute_pass_encoder::descriptor const & desc)
{
WGPUComputePassTimestampWrites timestamp_writes = {};
WGPUPassTimestampWrites timestamp_writes = {};
if (desc.timestamp_writes)
{
timestamp_writes.querySet = (WGPUQuerySet)desc.timestamp_writes->query_set.get();
@ -16,7 +17,7 @@ namespace psemek::wgpu
}
WGPUComputePassDescriptor descriptor = {};
descriptor.nextInChain = (WGPUChainedStruct const *)detail::fill_chain(desc.chain);
descriptor.nextInChain = (WGPUChainedStruct *)detail::fill_chain(desc.chain);
descriptor.label = detail::to_string_view(desc.label);
descriptor.timestampWrites = desc.timestamp_writes ? &timestamp_writes : nullptr;
@ -29,7 +30,7 @@ namespace psemek::wgpu
for (auto const & src : desc.color_attachments)
{
auto & dst = color_attachments.emplace_back();
dst.nextInChain = (WGPUChainedStruct const *)detail::fill_chain(src.chain);
dst.nextInChain = (WGPUChainedStruct *)detail::fill_chain(src.chain);
dst.view = (WGPUTextureView)src.view.get();
dst.depthSlice = src.depth_slice.value_or(WGPU_DEPTH_SLICE_UNDEFINED);
dst.resolveTarget = (WGPUTextureView)src.resolve_target.get();
@ -52,7 +53,7 @@ namespace psemek::wgpu
depth_stencil_attachment.stencilReadOnly = desc.depth_stencil_attachment->stencil_read_only ? 1 : 0;
}
WGPURenderPassTimestampWrites timestamp_writes = {};
WGPUPassTimestampWrites timestamp_writes = {};
if (desc.timestamp_writes)
{
timestamp_writes.querySet = (WGPUQuerySet)desc.timestamp_writes->query_set.get();
@ -61,7 +62,7 @@ namespace psemek::wgpu
}
WGPURenderPassDescriptor descriptor = {};
descriptor.nextInChain = (WGPUChainedStruct const *)detail::fill_chain(desc.chain);
descriptor.nextInChain = (WGPUChainedStruct *)detail::fill_chain(desc.chain);
descriptor.label = detail::to_string_view(desc.label);
descriptor.colorAttachmentCount = color_attachments.size();
descriptor.colorAttachments = color_attachments.data();
@ -158,10 +159,21 @@ namespace psemek::wgpu
wgpuCommandEncoderWriteTimestamp((WGPUCommandEncoder)get(), (WGPUQuerySet)query_set.get(), query_index);
}
void command_encoder::clear_texture(texture const & texture, image_subresource_range const & range)
{
WGPUImageSubresourceRange subresource_range;
subresource_range.aspect = (WGPUTextureAspect)range.aspect;
subresource_range.baseMipLevel = range.base_mip_level;
subresource_range.mipLevelCount = range.mip_level_count;
subresource_range.baseArrayLayer = range.base_array_layer;
subresource_range.arrayLayerCount= range.array_layer_count;
wgpuCommandEncoderClearTexture((WGPUCommandEncoder)get(), (WGPUTexture)texture.get(), &subresource_range);
}
command_buffer command_encoder::finish(command_buffer::descriptor const & desc)
{
WGPUCommandBufferDescriptor descriptor = {};
descriptor.nextInChain = (WGPUChainedStruct const *)detail::fill_chain(desc.chain);
descriptor.nextInChain = (WGPUChainedStruct *)detail::fill_chain(desc.chain);
descriptor.label = detail::to_string_view(desc.label);
return command_buffer(wgpuCommandEncoderFinish((WGPUCommandEncoder)get(), &descriptor));
}

View file

@ -26,9 +26,19 @@ namespace psemek::wgpu
wgpuComputePassEncoderDispatchWorkgroupsIndirect((WGPUComputePassEncoder)get(), (WGPUBuffer)indirect_buffer.get(), offset);
}
void compute_pass_encoder::set_push_constants(std::uint32_t offset, util::span<char const> data)
void compute_pass_encoder::set_immediates(std::uint32_t offset, util::span<char const> data)
{
wgpuComputePassEncoderSetPushConstants((WGPUComputePassEncoder)get(), offset, data.size(), data.data());
wgpuComputePassEncoderSetImmediates((WGPUComputePassEncoder)get(), offset, data.data(), data.size());
}
void compute_pass_encoder::begin_pipeline_statistics_query(query_set const & query_set, std::uint32_t query_index)
{
wgpuComputePassEncoderBeginPipelineStatisticsQuery((WGPUComputePassEncoder)get(), (WGPUQuerySet)query_set.get(), query_index);
}
void compute_pass_encoder::end_pipeline_statistics_query()
{
wgpuComputePassEncoderEndPipelineStatisticsQuery((WGPUComputePassEncoder)get());
}
void compute_pass_encoder::write_timestamp(query_set const & query_set, std::uint32_t query_index)

View file

@ -20,7 +20,7 @@ namespace psemek::wgpu
for (auto const & entry_in : desc.entries)
{
auto & entry_out = entries.emplace_back();
entry_out.nextInChain = (WGPUChainedStruct const *)detail::fill_chain(entry_in.chain);
entry_out.nextInChain = (WGPUChainedStruct *)detail::fill_chain(entry_in.chain);
entry_out.binding = entry_in.binding;
entry_out.buffer = (WGPUBuffer)entry_in.buffer.get();
entry_out.offset = entry_in.offset;
@ -30,7 +30,7 @@ namespace psemek::wgpu
}
WGPUBindGroupDescriptor descriptor = {};
descriptor.nextInChain = (WGPUChainedStruct const *)detail::fill_chain(desc.chain);
descriptor.nextInChain = (WGPUChainedStruct *)detail::fill_chain(desc.chain);
descriptor.label = detail::to_string_view(desc.label);
descriptor.layout = (WGPUBindGroupLayout)desc.layout.get();
descriptor.entryCount = entries.size();
@ -45,27 +45,27 @@ namespace psemek::wgpu
for (auto const & entry_in : desc.entries)
{
auto & entry_out = entries.emplace_back();
entry_out.nextInChain = (WGPUChainedStruct const *)detail::fill_chain(entry_in.chain);
entry_out.nextInChain = (WGPUChainedStruct *)detail::fill_chain(entry_in.chain);
entry_out.binding = entry_in.binding;
entry_out.visibility = (WGPUShaderStage)entry_in.visibility;
entry_out.buffer.nextInChain = (WGPUChainedStruct const *)detail::fill_chain(entry_in.buffer.chain);
entry_out.buffer.nextInChain = (WGPUChainedStruct *)detail::fill_chain(entry_in.buffer.chain);
entry_out.buffer.type = (WGPUBufferBindingType)entry_in.buffer.type;
entry_out.buffer.hasDynamicOffset = entry_in.buffer.has_dynamic_offset;
entry_out.buffer.minBindingSize = entry_in.buffer.min_binding_size;
entry_out.sampler.nextInChain = (WGPUChainedStruct const *)detail::fill_chain(entry_in.sampler.chain);
entry_out.sampler.nextInChain = (WGPUChainedStruct *)detail::fill_chain(entry_in.sampler.chain);
entry_out.sampler.type = (WGPUSamplerBindingType)entry_in.sampler.type;
entry_out.texture.nextInChain = (WGPUChainedStruct const *)detail::fill_chain(entry_in.texture.chain);
entry_out.texture.nextInChain = (WGPUChainedStruct *)detail::fill_chain(entry_in.texture.chain);
entry_out.texture.sampleType = (WGPUTextureSampleType)entry_in.texture.sample_type;
entry_out.texture.viewDimension = (WGPUTextureViewDimension)entry_in.texture.view_dimension;
entry_out.texture.multisampled = entry_in.texture.multisampled;
entry_out.storageTexture.nextInChain = (WGPUChainedStruct const *)detail::fill_chain(entry_in.storage_texture.chain);
entry_out.storageTexture.nextInChain = (WGPUChainedStruct *)detail::fill_chain(entry_in.storage_texture.chain);
entry_out.storageTexture.access = (WGPUStorageTextureAccess)entry_in.storage_texture.access;
entry_out.storageTexture.format = (WGPUTextureFormat)entry_in.storage_texture.format;
entry_out.storageTexture.viewDimension = (WGPUTextureViewDimension)entry_in.storage_texture.view_dimension;
}
WGPUBindGroupLayoutDescriptor descriptor = {};
descriptor.nextInChain = (WGPUChainedStruct const *)detail::fill_chain(desc.chain);
descriptor.nextInChain = (WGPUChainedStruct *)detail::fill_chain(desc.chain);
descriptor.label = detail::to_string_view(desc.label);
descriptor.entryCount = entries.size();
descriptor.entries = entries.data();
@ -76,7 +76,7 @@ namespace psemek::wgpu
buffer device::create_buffer(buffer::descriptor const & desc)
{
WGPUBufferDescriptor descriptor = {};
descriptor.nextInChain = (WGPUChainedStruct const *)detail::fill_chain(desc.chain);
descriptor.nextInChain = (WGPUChainedStruct *)detail::fill_chain(desc.chain);
descriptor.label = detail::to_string_view(desc.label);
descriptor.usage = (WGPUBufferUsage)desc.usage;
descriptor.size = desc.size;
@ -87,7 +87,7 @@ namespace psemek::wgpu
command_encoder device::create_command_encoder(command_encoder::descriptor const & desc)
{
WGPUCommandEncoderDescriptor descriptor = {};
descriptor.nextInChain = (WGPUChainedStruct const *)detail::fill_chain(desc.chain);
descriptor.nextInChain = (WGPUChainedStruct *)detail::fill_chain(desc.chain);
descriptor.label = detail::to_string_view(desc.label);
return command_encoder(wgpuDeviceCreateCommandEncoder((WGPUDevice)get(), &descriptor));
}
@ -100,15 +100,15 @@ namespace psemek::wgpu
for (auto const & constant_in : desc.compute.constants)
{
auto & constant_out = constants.emplace_back();
constant_out.nextInChain = (WGPUChainedStruct const *)detail::fill_chain(constant_in.chain);
constant_out.nextInChain = (WGPUChainedStruct *)detail::fill_chain(constant_in.chain);
constant_out.key = detail::to_string_view(constant_in.key);
constant_out.value = constant_in.value;
}
descriptor.nextInChain = (WGPUChainedStruct const *)detail::fill_chain(desc.chain);
descriptor.nextInChain = (WGPUChainedStruct *)detail::fill_chain(desc.chain);
descriptor.label = detail::to_string_view(desc.label);
descriptor.layout = (WGPUPipelineLayout)desc.layout.get();
descriptor.compute.nextInChain = (WGPUChainedStruct const *)detail::fill_chain(desc.compute.chain);
descriptor.compute.nextInChain = (WGPUChainedStruct *)detail::fill_chain(desc.compute.chain);
descriptor.compute.module = (WGPUShaderModule)desc.compute.module.get();
descriptor.compute.entryPoint = detail::to_string_view(desc.compute.entry_point);
descriptor.compute.constantCount = constants.size();
@ -147,18 +147,19 @@ namespace psemek::wgpu
pipeline_layout device::create_pipeline_layout(pipeline_layout::descriptor const & desc)
{
WGPUPipelineLayoutDescriptor descriptor = {};
descriptor.nextInChain = (WGPUChainedStruct const *)detail::fill_chain(desc.chain);
descriptor.nextInChain = (WGPUChainedStruct *)detail::fill_chain(desc.chain);
descriptor.label = detail::to_string_view(desc.label);
descriptor.bindGroupLayoutCount = desc.layouts.size();
static_assert(sizeof(WGPUBindGroupLayout) == sizeof(bind_group_layout));
descriptor.bindGroupLayouts = (WGPUBindGroupLayout const *)desc.layouts.data();
descriptor.immediateSize = desc.immediate_size;
return pipeline_layout(wgpuDeviceCreatePipelineLayout((WGPUDevice)get(), &descriptor));
}
query_set device::create_query_set(query_set::descriptor const & desc)
{
WGPUQuerySetDescriptor descriptor = {};
descriptor.nextInChain = (WGPUChainedStruct const *)detail::fill_chain(desc.chain);
descriptor.nextInChain = (WGPUChainedStruct *)detail::fill_chain(desc.chain);
descriptor.label = detail::to_string_view(desc.label);
descriptor.type = (WGPUQueryType)desc.type;
descriptor.count = desc.count;
@ -177,19 +178,20 @@ namespace psemek::wgpu
WGPURenderPipelineDescriptor & descriptor,
std::vector<WGPUConstantEntry> & vertex_constants,
std::vector<WGPUVertexBufferLayout> & vertex_buffers,
std::vector<std::vector<WGPUVertexAttribute>> & vertex_attributes,
WGPUDepthStencilState & depth_stencil_state,
WGPUFragmentState & fragment_state,
std::vector<WGPUConstantEntry> & fragment_constants,
std::vector<WGPUColorTargetState> & color_targets)
{
descriptor.nextInChain = (WGPUChainedStruct const *)detail::fill_chain(desc.chain);
descriptor.nextInChain = (WGPUChainedStruct *)detail::fill_chain(desc.chain);
descriptor.label = detail::to_string_view(desc.label);
descriptor.layout = (WGPUPipelineLayout)desc.layout.get();
for (auto const & constant_in : desc.vertex.constants)
{
auto & constant_out = vertex_constants.emplace_back();
constant_out.nextInChain = (WGPUChainedStruct const *)detail::fill_chain(constant_in.chain);
constant_out.nextInChain = (WGPUChainedStruct *)detail::fill_chain(constant_in.chain);
constant_out.key = detail::to_string_view(constant_in.key);
constant_out.value = constant_in.value;
}
@ -199,12 +201,21 @@ namespace psemek::wgpu
auto & buffer_out = vertex_buffers.emplace_back();
buffer_out.arrayStride = buffer_in.array_stride;
buffer_out.stepMode = (WGPUVertexStepMode)buffer_in.step_mode;
buffer_out.attributeCount = buffer_in.attributes.size();
static_assert(sizeof(WGPUVertexAttribute) == sizeof(vertex_attribute));
buffer_out.attributes = (WGPUVertexAttribute const *)buffer_in.attributes.data();
vertex_attributes.emplace_back();
for (auto const & attribute_in : buffer_in.attributes)
{
vertex_attributes.back().push_back(WGPUVertexAttribute {
.nextInChain = nullptr,
.format = (WGPUVertexFormat)attribute_in.format,
.offset = attribute_in.offset,
.shaderLocation = attribute_in.shader_location,
});
}
buffer_out.attributeCount = vertex_attributes.back().size();
buffer_out.attributes = vertex_attributes.back().data();
}
descriptor.vertex.nextInChain = (WGPUChainedStruct const *)detail::fill_chain(desc.vertex.chain);
descriptor.vertex.nextInChain = (WGPUChainedStruct *)detail::fill_chain(desc.vertex.chain);
descriptor.vertex.module = (WGPUShaderModule)desc.vertex.module.get();
descriptor.vertex.entryPoint = detail::to_string_view(desc.vertex.entry_point);
descriptor.vertex.constantCount = vertex_constants.size();
@ -212,7 +223,7 @@ namespace psemek::wgpu
descriptor.vertex.bufferCount = vertex_buffers.size();
descriptor.vertex.buffers = vertex_buffers.data();
descriptor.primitive.nextInChain = (WGPUChainedStruct const *)detail::fill_chain(desc.primitive.chain);
descriptor.primitive.nextInChain = (WGPUChainedStruct *)detail::fill_chain(desc.primitive.chain);
descriptor.primitive.topology = (WGPUPrimitiveTopology)desc.primitive.topology;
descriptor.primitive.stripIndexFormat = (WGPUIndexFormat)desc.primitive.strip_index_format;
descriptor.primitive.frontFace = (WGPUFrontFace)desc.primitive.front_face;
@ -221,7 +232,7 @@ namespace psemek::wgpu
if (desc.depth_stencil)
{
depth_stencil_state.nextInChain = (WGPUChainedStruct const *)detail::fill_chain(desc.depth_stencil->chain);
depth_stencil_state.nextInChain = (WGPUChainedStruct *)detail::fill_chain(desc.depth_stencil->chain);
depth_stencil_state.format = (WGPUTextureFormat)desc.depth_stencil->format;
depth_stencil_state.depthWriteEnabled = to_optional_bool(desc.depth_stencil->depth_write);
depth_stencil_state.depthCompare = (WGPUCompareFunction)desc.depth_stencil->depth_compare;
@ -242,7 +253,7 @@ namespace psemek::wgpu
descriptor.depthStencil = &depth_stencil_state;
}
descriptor.multisample.nextInChain = (WGPUChainedStruct const *)detail::fill_chain(desc.multisample.chain);
descriptor.multisample.nextInChain = (WGPUChainedStruct *)detail::fill_chain(desc.multisample.chain);
descriptor.multisample.count = desc.multisample.count;
descriptor.multisample.mask = desc.multisample.mask;
descriptor.multisample.alphaToCoverageEnabled = desc.multisample.alpha_to_coverage;
@ -252,7 +263,7 @@ namespace psemek::wgpu
for (auto const & constant_in : desc.fragment->constants)
{
auto & constant_out = fragment_constants.emplace_back();
constant_out.nextInChain = (WGPUChainedStruct const *)detail::fill_chain(constant_in.chain);
constant_out.nextInChain = (WGPUChainedStruct *)detail::fill_chain(constant_in.chain);
constant_out.key = detail::to_string_view(constant_in.key);
constant_out.value = constant_in.value;
}
@ -260,14 +271,14 @@ namespace psemek::wgpu
for (auto const & target_in : desc.fragment->targets)
{
auto & target_out = color_targets.emplace_back();
target_out.nextInChain = (WGPUChainedStruct const *)detail::fill_chain(target_in.chain);
target_out.nextInChain = (WGPUChainedStruct *)detail::fill_chain(target_in.chain);
target_out.format = (WGPUTextureFormat)target_in.format;
static_assert(sizeof(WGPUBlendState) == sizeof(blend_state));
target_out.blend = (WGPUBlendState *)(target_in.blend ? &(*target_in.blend) : nullptr);
target_out.writeMask = (WGPUColorWriteMask)target_in.write_mask;
}
fragment_state.nextInChain = (WGPUChainedStruct const *)detail::fill_chain(desc.fragment->chain);
fragment_state.nextInChain = (WGPUChainedStruct *)detail::fill_chain(desc.fragment->chain);
fragment_state.module = (WGPUShaderModule)desc.fragment->module.get();
fragment_state.entryPoint = detail::to_string_view(desc.fragment->entry_point);
fragment_state.constantCount = fragment_constants.size();
@ -286,12 +297,13 @@ namespace psemek::wgpu
WGPURenderPipelineDescriptor descriptor = {};
std::vector<WGPUConstantEntry> vertex_constants;
std::vector<WGPUVertexBufferLayout> vertex_buffers;
std::vector<std::vector<WGPUVertexAttribute>> vertex_attributes;
WGPUDepthStencilState depth_stencil_state = {};
WGPUFragmentState fragment_state = {};
std::vector<WGPUConstantEntry> fragment_constants;
std::vector<WGPUColorTargetState> color_targets;
fill_render_pipeline_descriptor(desc, descriptor, vertex_constants, vertex_buffers, depth_stencil_state, fragment_state, fragment_constants, color_targets);
fill_render_pipeline_descriptor(desc, descriptor, vertex_constants, vertex_buffers, vertex_attributes, depth_stencil_state, fragment_state, fragment_constants, color_targets);
return render_pipeline(wgpuDeviceCreateRenderPipeline((WGPUDevice)get(), &descriptor));
}
@ -301,12 +313,13 @@ namespace psemek::wgpu
WGPURenderPipelineDescriptor descriptor = {};
std::vector<WGPUConstantEntry> vertex_constants;
std::vector<WGPUVertexBufferLayout> vertex_buffers;
std::vector<std::vector<WGPUVertexAttribute>> vertex_attributes;
WGPUDepthStencilState depth_stencil_state = {};
WGPUFragmentState fragment_state = {};
std::vector<WGPUConstantEntry> fragment_constants;
std::vector<WGPUColorTargetState> color_targets;
fill_render_pipeline_descriptor(desc, descriptor, vertex_constants, vertex_buffers, depth_stencil_state, fragment_state, fragment_constants, color_targets);
fill_render_pipeline_descriptor(desc, descriptor, vertex_constants, vertex_buffers, vertex_attributes, depth_stencil_state, fragment_state, fragment_constants, color_targets);
WGPUCreateRenderPipelineAsyncCallbackInfo callback_info = {};
callback_info.mode = (WGPUCallbackMode)mode;
@ -323,7 +336,7 @@ namespace psemek::wgpu
render_bundle_encoder device::create_render_bundle_encoder(render_bundle_encoder::descriptor const & desc)
{
WGPURenderBundleEncoderDescriptor descriptor = {};
descriptor.nextInChain = (WGPUChainedStruct const *)detail::fill_chain(desc.chain);
descriptor.nextInChain = (WGPUChainedStruct *)detail::fill_chain(desc.chain);
descriptor.label = detail::to_string_view(desc.label);
descriptor.colorFormatCount = desc.color_formats.size();
descriptor.colorFormats = (WGPUTextureFormat const *)desc.color_formats.data();
@ -337,7 +350,7 @@ namespace psemek::wgpu
sampler device::create_sampler(sampler::descriptor const & desc)
{
WGPUSamplerDescriptor descriptor = {};
descriptor.nextInChain = (WGPUChainedStruct const *)detail::fill_chain(desc.chain);
descriptor.nextInChain = (WGPUChainedStruct *)detail::fill_chain(desc.chain);
descriptor.label = detail::to_string_view(desc.label);
descriptor.addressModeU = (WGPUAddressMode)desc.address_mode_u;
descriptor.addressModeV = (WGPUAddressMode)desc.address_mode_v;
@ -355,15 +368,23 @@ namespace psemek::wgpu
shader_module device::create_shader_module(shader_module::descriptor const & desc)
{
WGPUShaderModuleDescriptor descriptor = {};
descriptor.nextInChain = (WGPUChainedStruct const *)detail::fill_chain(desc.chain);
descriptor.nextInChain = (WGPUChainedStruct *)detail::fill_chain(desc.chain);
descriptor.label = detail::to_string_view(desc.label);
return shader_module(wgpuDeviceCreateShaderModule((WGPUDevice)get(), &descriptor));
}
shader_module device::create_shader_module_trusted(shader_module::descriptor const & desc, shader_module::runtime_checks runtime_checks)
{
WGPUShaderModuleDescriptor descriptor = {};
descriptor.nextInChain = (WGPUChainedStruct *)detail::fill_chain(desc.chain);
descriptor.label = detail::to_string_view(desc.label);
return shader_module(wgpuDeviceCreateShaderModuleTrusted((WGPUDevice)get(), &descriptor, (WGPUShaderRuntimeChecks)runtime_checks));
}
texture device::create_texture(texture::descriptor const & desc)
{
WGPUTextureDescriptor descriptor = {};
descriptor.nextInChain = (WGPUChainedStruct const *)detail::fill_chain(desc.chain);
descriptor.nextInChain = (WGPUChainedStruct *)detail::fill_chain(desc.chain);
descriptor.label = detail::to_string_view(desc.label);
descriptor.usage = (WGPUTextureUsage)desc.usage;
descriptor.dimension = (WGPUTextureDimension)desc.dimension;
@ -429,6 +450,7 @@ namespace psemek::wgpu
result.max_compute_workgroup_size_y = limits.maxComputeWorkgroupSizeY;
result.max_compute_workgroup_size_z = limits.maxComputeWorkgroupSizeZ;
result.max_compute_workgroups_per_dimension = limits.maxComputeWorkgroupsPerDimension;
result.max_immediate_size = limits.maxImmediateSize;
return result;
}
@ -462,6 +484,16 @@ namespace psemek::wgpu
wgpuDeviceSetLabel((WGPUDevice)get(), detail::to_string_view(label));
}
bool device::start_graphics_debugger_capture()
{
return wgpuDeviceStartGraphicsDebuggerCapture((WGPUDevice)get());
}
void device::stop_graphics_debugger_capture()
{
wgpuDeviceStopGraphicsDebuggerCapture((WGPUDevice)get());
}
void device::reference(void * ptr)
{
wgpuDeviceAddRef((WGPUDevice)ptr);
@ -476,7 +508,6 @@ namespace psemek::wgpu
{
WGPUNativeLimits chained = {};
chained.chain.sType = (WGPUSType)WGPUSType_NativeLimits;
chained.maxPushConstantSize = value.max_push_constant_size;
chained.maxNonSamplerBindings = value.max_non_sampler_bindings;
return detail::make_chained_struct(chained);
}

View file

@ -1,7 +1,9 @@
#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
{
@ -17,18 +19,45 @@ namespace psemek::wgpu
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 const *)detail::fill_chain(chain);
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));
}
@ -40,7 +69,7 @@ namespace psemek::wgpu
surface instance::create_surface(surface::descriptor const & desc)
{
WGPUSurfaceDescriptor descriptor = {};
descriptor.nextInChain = (WGPUChainedStruct const *)detail::fill_chain(desc.chain);
descriptor.nextInChain = (WGPUChainedStruct *)detail::fill_chain(desc.chain);
descriptor.label = detail::to_string_view(desc.label);
return surface{wgpuInstanceCreateSurface((WGPUInstance)get(), &descriptor)};
}
@ -48,7 +77,7 @@ namespace psemek::wgpu
void instance::request_adapter(callback_mode mode, adapter::request_options const & request_options, adapter::request_callback callback)
{
WGPURequestAdapterOptions options = {};
options.nextInChain = (WGPUChainedStruct const *)detail::fill_chain(request_options.chain);
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;

View file

@ -21,14 +21,4 @@ namespace psemek::wgpu
wgpuPipelineLayoutRelease((WGPUPipelineLayout)ptr);
}
detail::chained_struct_ptr to_chained_struct(pipeline_layout::extras && value)
{
WGPUPipelineLayoutExtras chained = {};
chained.chain.sType = (WGPUSType)WGPUSType_PipelineLayoutExtras;
static_assert(sizeof(WGPUPushConstantRange) == sizeof(push_constant_range));
chained.pushConstantRangeCount = value.ranges.size();
chained.pushConstantRanges = (WGPUPushConstantRange const *)value.ranges.data();
return detail::make_chained_struct(chained, std::move(value));
}
}

View file

@ -1,6 +1,7 @@
#include <psemek/wgpu/queue.hpp>
#include <psemek/wgpu/detail/string_view.hpp>
#include <psemek/wgpu/external/webgpu.h>
#include <psemek/wgpu/external/wgpu.h>
namespace psemek::wgpu
{
@ -38,10 +39,10 @@ namespace psemek::wgpu
{
WGPUQueueWorkDoneCallbackInfo callback_info = {};
callback_info.mode = (WGPUCallbackMode)mode;
callback_info.callback = [](WGPUQueueWorkDoneStatus status, void * userdata, void *)
callback_info.callback = [](WGPUQueueWorkDoneStatus status, WGPUStringView message, void * userdata, void *)
{
std::unique_ptr<work_done_callback> callback((work_done_callback*)userdata);
if (*callback) (*callback)((work_done_status)status);
if (*callback) (*callback)((work_done_status)status, std::string_view{message.data, message.length});
};
callback_info.userdata1 = new work_done_callback(callback);
@ -53,6 +54,11 @@ namespace psemek::wgpu
wgpuQueueSetLabel((WGPUQueue)get(), detail::to_string_view(label));
}
float queue::get_timestamp_period()
{
return wgpuQueueGetTimestampPeriod((WGPUQueue)get());
}
void queue::reference(void * ptr)
{
wgpuQueueAddRef((WGPUQueue)ptr);

View file

@ -63,7 +63,7 @@ namespace psemek::wgpu
render_bundle render_bundle_encoder::finish(render_bundle::descriptor const & desc)
{
WGPURenderBundleDescriptor descriptor = {};
descriptor.nextInChain = (WGPUChainedStruct const *)detail::fill_chain(desc.chain);
descriptor.nextInChain = (WGPUChainedStruct *)detail::fill_chain(desc.chain);
descriptor.label = detail::to_string_view(desc.label);
return render_bundle(wgpuRenderBundleEncoderFinish((WGPURenderBundleEncoder)get(), &descriptor));
}

View file

@ -47,9 +47,9 @@ namespace psemek::wgpu
wgpuRenderPassEncoderSetStencilReference((WGPURenderPassEncoder)get(), reference);
}
void render_pass_encoder::set_push_constants(shader_stage stages, std::uint32_t offset, util::span<char const> data)
void render_pass_encoder::set_immediates(std::uint32_t offset, util::span<char const> data)
{
wgpuRenderPassEncoderSetPushConstants((WGPURenderPassEncoder)get(), (WGPUShaderStage)stages, offset, data.size(), data.data());
wgpuRenderPassEncoderSetImmediates((WGPURenderPassEncoder)get(), offset, data.data(), data.size());
}
void render_pass_encoder::draw(std::uint32_t vertex_count, std::uint32_t instance_count, std::uint32_t first_vertex, std::uint32_t first_instance)
@ -108,6 +108,16 @@ namespace psemek::wgpu
wgpuRenderPassEncoderEndOcclusionQuery((WGPURenderPassEncoder)get());
}
void render_pass_encoder::begin_pipeline_statistics_query(query_set const & query_set, std::uint32_t query_index)
{
wgpuRenderPassEncoderBeginPipelineStatisticsQuery((WGPURenderPassEncoder)get(), (WGPUQuerySet)query_set.get(), query_index);
}
void render_pass_encoder::end_pipeline_statistics_query()
{
wgpuRenderPassEncoderEndPipelineStatisticsQuery((WGPURenderPassEncoder)get());
}
void render_pass_encoder::write_timestamp(query_set const & query_set, std::uint32_t query_index)
{
wgpuRenderPassEncoderWriteTimestamp((WGPURenderPassEncoder)get(), (WGPUQuerySet)query_set.get(), query_index);

View file

@ -1,6 +1,8 @@
#include <psemek/wgpu/sampler.hpp>
#include <psemek/wgpu/chained_struct.hpp>
#include <psemek/wgpu/detail/string_view.hpp>
#include <psemek/wgpu/external/webgpu.h>
#include <psemek/wgpu/external/wgpu.h>
namespace psemek::wgpu
{
@ -20,4 +22,12 @@ namespace psemek::wgpu
wgpuSamplerRelease((WGPUSampler)ptr);
}
detail::chained_struct_ptr to_chained_struct(sampler::extras const & value)
{
WGPUSamplerDescriptorExtras chained;
chained.chain.sType = (WGPUSType)WGPUSType_SamplerDescriptorExtras;
chained.samplerBorderColor = (WGPUSamplerBorderColor)value.border_color;
return detail::make_chained_struct(chained);
}
}

View file

@ -12,7 +12,7 @@ namespace psemek::wgpu
{
WGPUSurfaceConfiguration config = {};
config.nextInChain = (WGPUChainedStruct const *)detail::fill_chain(conf.chain);
config.nextInChain = (WGPUChainedStruct *)detail::fill_chain(conf.chain);
config.device = (WGPUDevice)conf.device.get();
config.format = (WGPUTextureFormat)conf.format;
config.usage = (WGPUTextureUsage)conf.usage;
@ -81,6 +81,15 @@ namespace psemek::wgpu
return detail::make_chained_struct(chained);
}
detail::chained_struct_ptr to_chained_struct(surface::color_management const & value)
{
WGPUSurfaceColorManagement chained = {};
chained.chain.sType = (WGPUSType)WGPUSType_SurfaceColorManagement;
chained.colorSpace = (WGPUPredefinedColorSpace)value.color_space;
chained.toneMappingMode = (WGPUToneMappingMode)value.tone_mapping_mode;
return detail::make_chained_struct(chained);
}
detail::chained_struct_ptr to_chained_struct(surface::from_android_native_window const & value)
{
WGPUSurfaceSourceAndroidNativeWindow chained = {};

View file

@ -9,7 +9,7 @@ namespace psemek::wgpu
texture_view texture::create_view(texture_view::descriptor const & desc)
{
WGPUTextureViewDescriptor descriptor = {};
descriptor.nextInChain = (WGPUChainedStruct const *)detail::fill_chain(desc.chain);
descriptor.nextInChain = (WGPUChainedStruct *)detail::fill_chain(desc.chain);
descriptor.label = detail::to_string_view(desc.label);
descriptor.format = (WGPUTextureFormat)desc.format;
descriptor.dimension = (WGPUTextureViewDimension)desc.dimension;
@ -77,6 +77,17 @@ namespace psemek::wgpu
wgpuTextureRelease((WGPUTexture)ptr);
}
detail::chained_struct_ptr to_chained_struct(texture::component_swizzle const & value)
{
WGPUTextureComponentSwizzleDescriptor chained;
chained.chain.sType = (WGPUSType)WGPUSType_TextureComponentSwizzleDescriptor;
chained.swizzle.r = (WGPUComponentSwizzle)value.r;
chained.swizzle.g = (WGPUComponentSwizzle)value.g;
chained.swizzle.b = (WGPUComponentSwizzle)value.b;
chained.swizzle.a = (WGPUComponentSwizzle)value.a;
return detail::make_chained_struct(chained);
}
std::size_t memory_usage(std::uint32_t width, std::uint32_t height, std::uint32_t depth, texture::format format)
{
std::size_t const pixels = width * height * depth;