Merge remote-tracking branch 'origin/trunk' into opt-parser

This commit is contained in:
Folkert 2021-03-12 03:47:49 +01:00
commit 9c95392cc6
19 changed files with 1134 additions and 678 deletions

1337
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -8,7 +8,7 @@ install-other-libs:
FROM +prep-debian
RUN apt -y install wget git
RUN apt -y install libxcb-shape0-dev libxcb-xfixes0-dev # for editor clipboard
RUN apt -y install libc++-dev libc++abi-dev libunwind-dev pkg-config libx11-dev zlib1g-dev
RUN apt -y install libc++-dev libc++abi-dev g++ libunwind-dev pkg-config libx11-dev zlib1g-dev
install-zig-llvm-valgrind-clippy-rustfmt:
FROM +install-other-libs
@ -30,10 +30,10 @@ install-zig-llvm-valgrind-clippy-rustfmt:
RUN wget https://sourceware.org/pub/valgrind/valgrind-3.16.1.tar.bz2
RUN tar -xf valgrind-3.16.1.tar.bz2
# need to cd every time, every command starts at WORKDIR
RUN cd valgrind-3.16.1; ./autogen.sh
RUN cd valgrind-3.16.1; ./configure --disable-dependency-tracking
RUN cd valgrind-3.16.1; make -j`nproc`
RUN cd valgrind-3.16.1; make install
RUN cd valgrind-3.16.1 && ./autogen.sh
RUN cd valgrind-3.16.1 && ./configure --disable-dependency-tracking
RUN cd valgrind-3.16.1 && make -j`nproc`
RUN cd valgrind-3.16.1 && make install
# clippy
RUN rustup component add clippy
# rustfmt
@ -75,16 +75,16 @@ save-cache:
FROM +install-zig-llvm-valgrind-clippy-rustfmt
COPY +prepare-cache/recipe.json ./
RUN --mount=type=cache,target=$SCCACHE_DIR \
cargo chef cook; sccache --show-stats # for clippy
cargo chef cook && sccache --show-stats # for clippy
RUN --mount=type=cache,target=$SCCACHE_DIR \
cargo chef cook --release --tests; sccache --show-stats
cargo chef cook --release --tests && sccache --show-stats
SAVE ARTIFACT target
SAVE ARTIFACT $CARGO_HOME cargo_home
test-zig:
FROM +install-zig-llvm-valgrind-clippy-rustfmt
COPY --dir compiler/builtins/bitcode ./
RUN cd bitcode; ./run-tests.sh;
RUN cd bitcode && ./run-tests.sh
check-clippy:
FROM +copy-dirs-and-cache
@ -101,7 +101,7 @@ test-rust:
FROM +copy-dirs-and-cache
ENV RUST_BACKTRACE=1
RUN --mount=type=cache,target=$SCCACHE_DIR \
cargo test --release; sccache --show-stats
cargo test --release && sccache --show-stats
test-all:
BUILD +test-zig

View File

@ -114,6 +114,7 @@ pub const RocList = extern struct {
const Caller1 = fn (?[*]u8, ?[*]u8, ?[*]u8) callconv(.C) void;
const Caller2 = fn (?[*]u8, ?[*]u8, ?[*]u8, ?[*]u8) callconv(.C) void;
const Caller3 = fn (?[*]u8, ?[*]u8, ?[*]u8, ?[*]u8, ?[*]u8) callconv(.C) void;
pub fn listMap(list: RocList, transform: Opaque, caller: Caller1, alignment: usize, old_element_width: usize, new_element_width: usize) callconv(.C) RocList {
if (list.bytes) |source_ptr| {
@ -213,6 +214,129 @@ pub fn listMap2(list1: RocList, list2: RocList, transform: Opaque, caller: Calle
}
}
pub fn listMap3(list1: RocList, list2: RocList, list3: RocList, transform: Opaque, caller: Caller3, alignment: usize, a_width: usize, b_width: usize, c_width: usize, d_width: usize, dec_a: Dec, dec_b: Dec, dec_c: Dec) callconv(.C) RocList {
const smaller_length = std.math.min(list1.len(), list2.len());
const output_length = std.math.min(smaller_length, list3.len());
if (list1.bytes) |source_a| {
if (list2.bytes) |source_b| {
if (list3.bytes) |source_c| {
const output = RocList.allocate(std.heap.c_allocator, alignment, output_length, d_width);
const target_ptr = output.bytes orelse unreachable;
var i: usize = 0;
while (i < output_length) : (i += 1) {
const element_a = source_a + i * a_width;
const element_b = source_b + i * b_width;
const element_c = source_c + i * c_width;
const target = target_ptr + i * d_width;
caller(transform, element_a, element_b, element_c, target);
}
// if the lists don't have equal length, we must consume the remaining elements
// In this case we consume by (recursively) decrementing the elements
if (list1.len() > output_length) {
i = output_length;
while (i < list1.len()) : (i += 1) {
const element_a = source_a + i * a_width;
dec_a(element_a);
}
}
if (list2.len() > output_length) {
i = output_length;
while (i < list2.len()) : (i += 1) {
const element_b = source_b + i * b_width;
dec_b(element_b);
}
}
if (list3.len() > output_length) {
i = output_length;
while (i < list3.len()) : (i += 1) {
const element_c = source_c + i * c_width;
dec_c(element_c);
}
}
utils.decref(std.heap.c_allocator, alignment, list1.bytes, list1.len() * a_width);
utils.decref(std.heap.c_allocator, alignment, list2.bytes, list2.len() * b_width);
utils.decref(std.heap.c_allocator, alignment, list3.bytes, list3.len() * c_width);
return output;
} else {
// consume list1 elements (we know there is at least one because the list1.bytes pointer is non-null
var i: usize = 0;
while (i < list1.len()) : (i += 1) {
const element_a = source_a + i * a_width;
dec_a(element_a);
}
utils.decref(std.heap.c_allocator, alignment, list1.bytes, list1.len() * a_width);
// consume list2 elements (we know there is at least one because the list1.bytes pointer is non-null
i = 0;
while (i < list2.len()) : (i += 1) {
const element_b = source_b + i * b_width;
dec_b(element_b);
}
utils.decref(std.heap.c_allocator, alignment, list2.bytes, list2.len() * b_width);
return RocList.empty();
}
} else {
// consume list1 elements (we know there is at least one because the list1.bytes pointer is non-null
var i: usize = 0;
while (i < list1.len()) : (i += 1) {
const element_a = source_a + i * a_width;
dec_a(element_a);
}
utils.decref(std.heap.c_allocator, alignment, list1.bytes, list1.len() * a_width);
// consume list3 elements (if any)
if (list3.bytes) |source_c| {
i = 0;
while (i < list2.len()) : (i += 1) {
const element_c = source_c + i * c_width;
dec_c(element_c);
}
utils.decref(std.heap.c_allocator, alignment, list3.bytes, list3.len() * c_width);
}
return RocList.empty();
}
} else {
// consume list2 elements (if any)
if (list2.bytes) |source_b| {
var i: usize = 0;
while (i < list2.len()) : (i += 1) {
const element_b = source_b + i * b_width;
dec_b(element_b);
}
utils.decref(std.heap.c_allocator, alignment, list2.bytes, list2.len() * b_width);
}
// consume list3 elements (if any)
if (list3.bytes) |source_c| {
var i: usize = 0;
while (i < list2.len()) : (i += 1) {
const element_c = source_c + i * c_width;
dec_c(element_c);
}
utils.decref(std.heap.c_allocator, alignment, list3.bytes, list3.len() * c_width);
}
return RocList.empty();
}
}
pub fn listKeepIf(list: RocList, transform: Opaque, caller: Caller1, alignment: usize, element_width: usize, inc: Inc, dec: Dec) callconv(.C) RocList {
if (list.bytes) |source_ptr| {
const size = list.len();

View File

@ -8,6 +8,7 @@ const list = @import("list.zig");
comptime {
exportListFn(list.listMap, "map");
exportListFn(list.listMap2, "map2");
exportListFn(list.listMap3, "map3");
exportListFn(list.listMapWithIndex, "map_with_index");
exportListFn(list.listKeepIf, "keep_if");
exportListFn(list.listWalk, "walk");

View File

@ -64,6 +64,7 @@ pub const SET_FROM_LIST: &str = "roc_builtins.dict.set_from_list";
pub const LIST_MAP: &str = "roc_builtins.list.map";
pub const LIST_MAP2: &str = "roc_builtins.list.map2";
pub const LIST_MAP3: &str = "roc_builtins.list.map3";
pub const LIST_MAP_WITH_INDEX: &str = "roc_builtins.list.map_with_index";
pub const LIST_KEEP_IF: &str = "roc_builtins.list.keep_if";
pub const LIST_KEEP_OKS: &str = "roc_builtins.list.keep_oks";

View File

@ -817,6 +817,21 @@ pub fn types() -> MutMap<Symbol, (SolvedType, Region)> {
)
});
// map3 : List a, List b, List c, (a, b, c -> d) -> List d
add_type(Symbol::LIST_MAP3, {
let_tvars! {a, b, c, d, cvar};
top_level_function(
vec![
list_type(flex(a)),
list_type(flex(b)),
list_type(flex(c)),
closure(vec![flex(a), flex(b), flex(c)], cvar, Box::new(flex(d))),
],
Box::new(list_type(flex(d))),
)
});
// append : List elem, elem -> List elem
add_type(
Symbol::LIST_APPEND,

View File

@ -81,6 +81,7 @@ pub fn builtin_defs_map(symbol: Symbol, var_store: &mut VarStore) -> Option<Def>
LIST_JOIN => list_join,
LIST_MAP => list_map,
LIST_MAP2 => list_map2,
LIST_MAP3 => list_map3,
LIST_MAP_WITH_INDEX => list_map_with_index,
LIST_KEEP_IF => list_keep_if,
LIST_KEEP_OKS => list_keep_oks,
@ -218,6 +219,7 @@ pub fn builtin_defs(var_store: &mut VarStore) -> MutMap<Symbol, Def> {
Symbol::LIST_JOIN => list_join,
Symbol::LIST_MAP => list_map,
Symbol::LIST_MAP2 => list_map2,
Symbol::LIST_MAP3 => list_map3,
Symbol::LIST_MAP_WITH_INDEX => list_map_with_index,
Symbol::LIST_KEEP_IF => list_keep_if,
Symbol::LIST_KEEP_OKS => list_keep_oks,
@ -370,6 +372,38 @@ fn lowlevel_3(symbol: Symbol, op: LowLevel, var_store: &mut VarStore) -> Def {
)
}
fn lowlevel_4(symbol: Symbol, op: LowLevel, var_store: &mut VarStore) -> Def {
let arg1_var = var_store.fresh();
let arg2_var = var_store.fresh();
let arg3_var = var_store.fresh();
let arg4_var = var_store.fresh();
let ret_var = var_store.fresh();
let body = RunLowLevel {
op,
args: vec![
(arg1_var, Var(Symbol::ARG_1)),
(arg2_var, Var(Symbol::ARG_2)),
(arg3_var, Var(Symbol::ARG_3)),
(arg4_var, Var(Symbol::ARG_4)),
],
ret_var,
};
defn(
symbol,
vec![
(arg1_var, Symbol::ARG_1),
(arg2_var, Symbol::ARG_2),
(arg3_var, Symbol::ARG_3),
(arg4_var, Symbol::ARG_4),
],
var_store,
body,
ret_var,
)
}
/// Num.maxInt : Int
fn num_max_int(symbol: Symbol, var_store: &mut VarStore) -> Def {
let int_var = var_store.fresh();
@ -2122,6 +2156,11 @@ fn list_map2(symbol: Symbol, var_store: &mut VarStore) -> Def {
lowlevel_3(symbol, LowLevel::ListMap2, var_store)
}
/// List.map3 : List a, List b, (a, b -> c) -> List c
fn list_map3(symbol: Symbol, var_store: &mut VarStore) -> Def {
lowlevel_4(symbol, LowLevel::ListMap3, var_store)
}
/// Dict.hashTestOnly : k, v -> Nat
pub fn dict_hash_test_only(symbol: Symbol, var_store: &mut VarStore) -> Def {
lowlevel_2(symbol, LowLevel::Hash, var_store)

View File

@ -7,8 +7,8 @@ use crate::llvm::build_hash::generic_hash;
use crate::llvm::build_list::{
allocate_list, empty_list, empty_polymorphic_list, list_append, list_concat, list_contains,
list_get_unsafe, list_join, list_keep_errs, list_keep_if, list_keep_oks, list_len, list_map,
list_map2, list_map_with_index, list_prepend, list_repeat, list_reverse, list_set, list_single,
list_sum, list_walk, list_walk_backwards,
list_map2, list_map3, list_map_with_index, list_prepend, list_repeat, list_reverse, list_set,
list_single, list_sum, list_walk, list_walk_backwards,
};
use crate::llvm::build_str::{
str_concat, str_count_graphemes, str_ends_with, str_from_float, str_from_int, str_from_utf8,
@ -3746,6 +3746,38 @@ fn run_low_level<'a, 'ctx, 'env>(
_ => unreachable!("invalid list layout"),
}
}
ListMap3 => {
debug_assert_eq!(args.len(), 4);
let (list1, list1_layout) = load_symbol_and_layout(scope, &args[0]);
let (list2, list2_layout) = load_symbol_and_layout(scope, &args[1]);
let (list3, list3_layout) = load_symbol_and_layout(scope, &args[2]);
let (func, func_layout) = load_symbol_and_layout(scope, &args[3]);
match (list1_layout, list2_layout, list3_layout) {
(
Layout::Builtin(Builtin::List(_, element1_layout)),
Layout::Builtin(Builtin::List(_, element2_layout)),
Layout::Builtin(Builtin::List(_, element3_layout)),
) => list_map3(
env,
layout_ids,
func,
func_layout,
list1,
list2,
list3,
element1_layout,
element2_layout,
element3_layout,
),
(Layout::Builtin(Builtin::EmptyList), _, _)
| (_, Layout::Builtin(Builtin::EmptyList), _)
| (_, _, Layout::Builtin(Builtin::EmptyList)) => empty_list(env),
_ => unreachable!("invalid list layout"),
}
}
ListMapWithIndex => {
// List.map : List before, (before -> after) -> List after
debug_assert_eq!(args.len(), 2);

View File

@ -1305,6 +1305,114 @@ pub fn list_map2<'a, 'ctx, 'env>(
)
}
pub fn list_map3<'a, 'ctx, 'env>(
env: &Env<'a, 'ctx, 'env>,
layout_ids: &mut LayoutIds<'a>,
transform: BasicValueEnum<'ctx>,
transform_layout: &Layout<'a>,
list1: BasicValueEnum<'ctx>,
list2: BasicValueEnum<'ctx>,
list3: BasicValueEnum<'ctx>,
element1_layout: &Layout<'a>,
element2_layout: &Layout<'a>,
element3_layout: &Layout<'a>,
) -> BasicValueEnum<'ctx> {
let builder = env.builder;
let return_layout = match transform_layout {
Layout::FunctionPointer(_, ret) => ret,
Layout::Closure(_, _, ret) => ret,
_ => unreachable!("not a callable layout"),
};
let u8_ptr = env.context.i8_type().ptr_type(AddressSpace::Generic);
let list1_i128 = complex_bitcast(
env.builder,
list1,
env.context.i128_type().into(),
"to_i128",
);
let list2_i128 = complex_bitcast(
env.builder,
list2,
env.context.i128_type().into(),
"to_i128",
);
let list3_i128 = complex_bitcast(
env.builder,
list3,
env.context.i128_type().into(),
"to_i128",
);
let transform_ptr = builder.build_alloca(transform.get_type(), "transform_ptr");
env.builder.build_store(transform_ptr, transform);
let argument_layouts = [
element1_layout.clone(),
element2_layout.clone(),
element3_layout.clone(),
];
let stepper_caller =
build_transform_caller(env, layout_ids, transform_layout, &argument_layouts)
.as_global_value()
.as_pointer_value();
let a_width = env
.ptr_int()
.const_int(element1_layout.stack_size(env.ptr_bytes) as u64, false);
let b_width = env
.ptr_int()
.const_int(element2_layout.stack_size(env.ptr_bytes) as u64, false);
let c_width = env
.ptr_int()
.const_int(element3_layout.stack_size(env.ptr_bytes) as u64, false);
let d_width = env
.ptr_int()
.const_int(return_layout.stack_size(env.ptr_bytes) as u64, false);
let alignment = return_layout.alignment_bytes(env.ptr_bytes);
let alignment_iv = env.ptr_int().const_int(alignment as u64, false);
let dec_a = build_dec_wrapper(env, layout_ids, element1_layout);
let dec_b = build_dec_wrapper(env, layout_ids, element2_layout);
let dec_c = build_dec_wrapper(env, layout_ids, element3_layout);
let output = call_bitcode_fn(
env,
&[
list1_i128,
list2_i128,
list3_i128,
env.builder
.build_bitcast(transform_ptr, u8_ptr, "to_opaque"),
stepper_caller.into(),
alignment_iv.into(),
a_width.into(),
b_width.into(),
c_width.into(),
d_width.into(),
dec_a.as_global_value().as_pointer_value().into(),
dec_b.as_global_value().as_pointer_value().into(),
dec_c.as_global_value().as_pointer_value().into(),
],
bitcode::LIST_MAP3,
);
complex_bitcast(
env.builder,
output,
collection(env.context, env.ptr_bytes).into(),
"from_i128",
)
}
/// List.concat : List elem, List elem -> List elem
pub fn list_concat<'a, 'ctx, 'env>(
env: &Env<'a, 'ctx, 'env>,

View File

@ -28,6 +28,7 @@ pub enum LowLevel {
ListJoin,
ListMap,
ListMap2,
ListMap3,
ListMapWithIndex,
ListKeepIf,
ListWalk,

View File

@ -910,6 +910,7 @@ define_builtins! {
22 LIST_KEEP_ERRS: "keepErrs"
23 LIST_MAP_WITH_INDEX: "mapWithIndex"
24 LIST_MAP2: "map2"
25 LIST_MAP3: "map3"
}
5 RESULT: "Result" => {
0 RESULT_RESULT: "Result" imported // the Result.Result type alias

View File

@ -652,6 +652,7 @@ pub fn lowlevel_borrow_signature(arena: &Bump, op: LowLevel) -> &[bool] {
ListJoin => arena.alloc_slice_copy(&[irrelevant]),
ListMap | ListMapWithIndex => arena.alloc_slice_copy(&[owned, irrelevant]),
ListMap2 => arena.alloc_slice_copy(&[owned, owned, irrelevant]),
ListMap3 => arena.alloc_slice_copy(&[owned, owned, owned, irrelevant]),
ListKeepIf | ListKeepOks | ListKeepErrs => arena.alloc_slice_copy(&[owned, borrowed]),
ListContains => arena.alloc_slice_copy(&[borrowed, irrelevant]),
ListWalk => arena.alloc_slice_copy(&[owned, irrelevant, owned]),

View File

@ -568,6 +568,36 @@ fn list_map_closure() {
);
}
#[test]
fn list_map3_group() {
assert_evals_to!(
indoc!(
r#"
List.map3 [1,2,3] [3,2,1] [2,1,3] (\a, b, c -> Group a b c)
"#
),
RocList::from_slice(&[(1, 3, 2), (2, 2, 1), (3, 1, 3)]),
RocList<(i64, i64, i64)>
);
}
#[test]
fn list_map3_different_length() {
assert_evals_to!(
indoc!(
r#"
List.map3
["a", "b", "d"]
["b", "x"]
["c"]
(\a, b, c -> Str.concat a (Str.concat b c))
"#
),
RocList::from_slice(&[RocStr::from_slice("abc".as_bytes()),]),
RocList<RocStr>
);
}
#[test]
fn list_map2_pair() {
assert_evals_to!(

View File

@ -19,29 +19,29 @@ roc_fmt = { path = "../compiler/fmt" }
roc_reporting = { path = "../compiler/reporting" }
# TODO switch to clap 3.0.0 once it's out. Tried adding clap = "~3.0.0-beta.1" and cargo wouldn't accept it
ven_graph = { path = "../vendor/pathfinding" }
im = "14" # im and im-rc should always have the same version!
im-rc = "14" # im and im-rc should always have the same version!
im = "15" # im and im-rc should always have the same version!
im-rc = "15" # im and im-rc should always have the same version!
bumpalo = { version = "3.2", features = ["collections"] }
inlinable_string = "0.1"
arraystring = "0.3.0"
libc = "0.2"
page_size = "0.4"
winit = "0.22"
wgpu = "0.6"
winit = "0.24"
wgpu = "0.7"
glyph_brush = "0.7"
log = "0.4"
zerocopy = "0.3"
env_logger = "0.7"
env_logger = "0.8"
futures = "0.3"
wgpu_glyph = "0.10"
cgmath = "0.17.0"
wgpu_glyph = "0.11"
cgmath = "0.18.0"
snafu = { version = "0.6", features = ["backtraces"] }
colored = "2"
pest = "2.1"
pest_derive = "2.1"
ropey = "1.2.0"
copypasta = "0.7.1"
indoc = "0.3.3"
indoc = "1.0"
palette = "0.5"
confy = { git = 'https://github.com/rust-cli/confy', features = [
"yaml_conf"
@ -53,10 +53,10 @@ version = "1.4"
features = ["derive"]
[dev-dependencies]
pretty_assertions = "0.5.1"
pretty_assertions = "0.6"
maplit = "1.0.1"
quickcheck = "0.8"
quickcheck_macros = "0.8"
quickcheck = "1.0"
quickcheck_macros = "1.0"
criterion = "0.3"
rand = "0.8.2"

View File

@ -66,6 +66,7 @@ e.g. you have a test `calculate_sum_test` that only uses the function `add`, whe
* When refactoring;
- Cutting and pasting code to a new file should automatically add imports to the new file and delete them from the old file.
- Ability to link e.g. variable name in comments to actual variable name. Comment is automatically updated when variable name is changed.
- When updating dependencies with breaking changes; show similar diffs from github projects that have succesfully updated that dependency.
- AST backed renaming, changing variable/function/type name should change it all over the codebase.
* Automatically create all "arms" when pattern matching after entering `when var is` based on the type.
- All `when ... is` should be updated if the type is changed, e.g. adding Indigo to the Color type should add an arm everywhere where `when color is` is used.

View File

@ -88,9 +88,9 @@ fn run_event_loop(file_path_opt: Option<&Path>) -> Result<(), Box<dyn Error>> {
adapter
.request_device(
&wgpu::DeviceDescriptor {
label: None,
features: wgpu::Features::empty(),
limits: wgpu::Limits::default(),
shader_validation: false,
},
None,
)
@ -108,12 +108,12 @@ fn run_event_loop(file_path_opt: Option<&Path>) -> Result<(), Box<dyn Error>> {
let mut size = window.inner_size();
let swap_chain_descr = wgpu::SwapChainDescriptor {
usage: wgpu::TextureUsage::OUTPUT_ATTACHMENT,
usage: wgpu::TextureUsage::RENDER_ATTACHMENT,
format: render_format,
width: size.width,
height: size.height,
//Immediate may cause tearing, change present_mode if this becomes a problem
present_mode: wgpu::PresentMode::Immediate,
// TODO go back to Immediate
present_mode: wgpu::PresentMode::Fifo,
};
let mut swap_chain = gpu_device.create_swap_chain(&surface, &swap_chain_descr);
@ -182,12 +182,12 @@ fn run_event_loop(file_path_opt: Option<&Path>) -> Result<(), Box<dyn Error>> {
swap_chain = gpu_device.create_swap_chain(
&surface,
&wgpu::SwapChainDescriptor {
usage: wgpu::TextureUsage::OUTPUT_ATTACHMENT,
usage: wgpu::TextureUsage::RENDER_ATTACHMENT,
format: render_format,
width: size.width,
height: size.height,
//Immediate may cause tearing, change present_mode if this becomes a problem
present_mode: wgpu::PresentMode::Immediate,
// TODO go back to Immediate
present_mode: wgpu::PresentMode::Fifo,
},
);
@ -376,7 +376,10 @@ fn draw_all_rects(
render_pass.set_pipeline(&rect_resources.pipeline);
render_pass.set_bind_group(0, &rect_resources.ortho.bind_group, &[]);
render_pass.set_vertex_buffer(0, rect_buffers.vertex_buffer.slice(..));
render_pass.set_index_buffer(rect_buffers.index_buffer.slice(..));
render_pass.set_index_buffer(
rect_buffers.index_buffer.slice(..),
wgpu::IndexFormat::Uint32,
);
render_pass.draw_indexed(0..rect_buffers.num_rects, 0, 0..1);
} else {
// need to begin render pass to clear screen
@ -403,6 +406,7 @@ fn begin_render_pass<'a>(
},
}],
depth_stencil_attachment: None,
label: None,
})
}

View File

@ -91,8 +91,9 @@ pub fn init_ortho(
entries: &[BindGroupLayoutEntry {
binding: 0,
visibility: ShaderStage::VERTEX,
ty: wgpu::BindingType::UniformBuffer {
dynamic: false,
ty: wgpu::BindingType::Buffer {
ty: wgpu::BufferBindingType::Uniform,
has_dynamic_offset: false,
min_binding_size: None,
},
count: None,
@ -104,7 +105,7 @@ pub fn init_ortho(
layout: &ortho_bind_group_layout,
entries: &[wgpu::BindGroupEntry {
binding: 0,
resource: wgpu::BindingResource::Buffer(ortho_buffer.slice(..)),
resource: ortho_buffer.as_entire_binding(),
}],
label: Some("Ortho bind group"),
});

View File

@ -21,9 +21,8 @@ pub fn make_rect_pipeline(
&gpu_device,
&pipeline_layout,
swap_chain_descr.format,
&[Vertex::DESC],
wgpu::include_spirv!("../shaders/rect.vert.spv"),
wgpu::include_spirv!("../shaders/rect.frag.spv"),
&wgpu::include_spirv!("../shaders/rect.vert.spv"),
&wgpu::include_spirv!("../shaders/rect.frag.spv"),
);
RectResources { pipeline, ortho }
@ -33,9 +32,8 @@ pub fn create_render_pipeline(
device: &wgpu::Device,
layout: &wgpu::PipelineLayout,
color_format: wgpu::TextureFormat,
vertex_descs: &[wgpu::VertexBufferDescriptor],
vs_src: wgpu::ShaderModuleSource,
fs_src: wgpu::ShaderModuleSource,
vs_src: &wgpu::ShaderModuleDescriptor,
fs_src: &wgpu::ShaderModuleDescriptor,
) -> wgpu::RenderPipeline {
let vs_module = device.create_shader_module(vs_src);
let fs_module = device.create_shader_module(fs_src);
@ -43,29 +41,27 @@ pub fn create_render_pipeline(
device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
label: Some("Render pipeline"),
layout: Some(&layout),
vertex_stage: wgpu::ProgrammableStageDescriptor {
vertex: wgpu::VertexState {
module: &vs_module,
entry_point: "main",
buffers: &[Vertex::DESC],
},
fragment_stage: Some(wgpu::ProgrammableStageDescriptor {
fragment: Some(wgpu::FragmentState {
module: &fs_module,
entry_point: "main",
targets: &[wgpu::ColorTargetState {
format: color_format,
color_blend: wgpu::BlendState::REPLACE,
alpha_blend: wgpu::BlendState::REPLACE,
write_mask: wgpu::ColorWrite::ALL,
}],
}),
rasterization_state: None,
primitive_topology: wgpu::PrimitiveTopology::TriangleList,
color_states: &[wgpu::ColorStateDescriptor {
format: color_format,
color_blend: wgpu::BlendDescriptor::REPLACE,
alpha_blend: wgpu::BlendDescriptor::REPLACE,
write_mask: wgpu::ColorWrite::ALL,
}],
depth_stencil_state: None,
sample_count: 1,
sample_mask: !0,
alpha_to_coverage_enabled: false,
vertex_state: wgpu::VertexStateDescriptor {
index_format: wgpu::IndexFormat::Uint32,
vertex_buffers: vertex_descs,
primitive: wgpu::PrimitiveState::default(),
depth_stencil: None,
multisample: wgpu::MultisampleState {
count: 1,
mask: !0,
alpha_to_coverage_enabled: false,
},
})
}

View File

@ -13,18 +13,18 @@ unsafe impl bytemuck::Zeroable for Vertex {}
impl Vertex {
pub const SIZE: wgpu::BufferAddress = std::mem::size_of::<Self>() as wgpu::BufferAddress;
pub const DESC: wgpu::VertexBufferDescriptor<'static> = wgpu::VertexBufferDescriptor {
stride: Self::SIZE,
pub const DESC: wgpu::VertexBufferLayout<'static> = wgpu::VertexBufferLayout {
array_stride: Self::SIZE,
step_mode: wgpu::InputStepMode::Vertex,
attributes: &[
// position
wgpu::VertexAttributeDescriptor {
wgpu::VertexAttribute {
offset: 0,
shader_location: 0,
format: wgpu::VertexFormat::Float2,
},
// color
wgpu::VertexAttributeDescriptor {
wgpu::VertexAttribute {
offset: std::mem::size_of::<[f32; 2]>() as wgpu::BufferAddress,
shader_location: 1,
format: wgpu::VertexFormat::Float4,