Render random circles

Poor performance but it renders something.
This commit is contained in:
Raph Levien 2020-04-17 21:18:39 -07:00
parent 3c35899a2f
commit 957f710b91
6 changed files with 150 additions and 19 deletions

72
Cargo.lock generated
View file

@ -58,6 +58,17 @@ dependencies = [
"byteorder",
]
[[package]]
name = "getrandom"
version = "0.1.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7abc8dd8451921606d809ba32e95b6111925cd2906060d2dcc29c070220503eb"
dependencies = [
"cfg-if",
"libc",
"wasi",
]
[[package]]
name = "inflate"
version = "0.4.5"
@ -67,6 +78,12 @@ dependencies = [
"adler32",
]
[[package]]
name = "libc"
version = "0.2.69"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "99e85c08494b21a9054e7fe1374a732aeadaff3980b6990b94bfd3a70f690005"
[[package]]
name = "libloading"
version = "0.5.2"
@ -82,7 +99,9 @@ name = "piet-gpu"
version = "0.1.0"
dependencies = [
"piet-gpu-hal",
"piet-gpu-types",
"png",
"rand",
]
[[package]]
@ -120,6 +139,12 @@ dependencies = [
"inflate",
]
[[package]]
name = "ppv-lite86"
version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "74490b50b9fbe561ac330df47c08f3f33073d2d00c150f719147d7c54522fa1b"
[[package]]
name = "proc-macro2"
version = "1.0.10"
@ -138,6 +163,47 @@ dependencies = [
"proc-macro2",
]
[[package]]
name = "rand"
version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03"
dependencies = [
"getrandom",
"libc",
"rand_chacha",
"rand_core",
"rand_hc",
]
[[package]]
name = "rand_chacha"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402"
dependencies = [
"ppv-lite86",
"rand_core",
]
[[package]]
name = "rand_core"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19"
dependencies = [
"getrandom",
]
[[package]]
name = "rand_hc"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c"
dependencies = [
"rand_core",
]
[[package]]
name = "syn"
version = "1.0.17"
@ -155,6 +221,12 @@ version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c"
[[package]]
name = "wasi"
version = "0.9.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
[[package]]
name = "winapi"
version = "0.3.8"

View file

@ -71,9 +71,10 @@ fn gen_derive_def(name: &str, size: usize, def: &LayoutTypeDef) -> proc_macro2::
field_encoders.extend(field_encoder);
args.push(field_id);
}
let tag = variant_ix as u32;
let case = quote! {
#name_id::#variant_id(#(#args),*) => {
buf[0..4].copy_from_slice(&#variant_ix.to_le_bytes());
buf[0..4].copy_from_slice(&#tag.to_le_bytes());
#field_encoders
}
};

View file

@ -9,5 +9,9 @@ edition = "2018"
[dependencies.piet-gpu-hal]
path = "../piet-gpu-hal"
[dependencies.piet-gpu-types]
path = "../piet-gpu-types"
[dependencies]
png = "0.16.2"
rand = "0.7.3"

View file

@ -23,9 +23,10 @@ layout(set = 0, binding = 1) buffer ImageBuf {
#define IMAGE_HEIGHT 1535
void main() {
uvec2 xy = gl_GlobalInvocationID.xy;
vec2 uv = vec2(xy) * vec2(1.0 / IMAGE_WIDTH, 1.0 / IMAGE_HEIGHT);
vec4 rgba = vec4(uv.xyy, 1.0);
uvec2 xy_uint = gl_GlobalInvocationID.xy;
vec2 xy = vec2(xy_uint);
vec2 uv = xy * vec2(1.0 / IMAGE_WIDTH, 1.0 / IMAGE_HEIGHT);
vec3 rgb = uv.xyy;
// Render the scene. Right now, every pixel traverses the scene graph,
// which is horribly wasteful, but the goal is to get *some* output and
@ -33,21 +34,21 @@ void main() {
SimpleGroup group = SimpleGroup_read(SimpleGroupRef(0));
for (uint i = 0; i < group.n_items; i++) {
// Writing this out by hand is illuminating the need for array access
// in piet-gpu-derive. There is some support in the `_index` functions,
// but those are only generated for structs, not for `Ref` or other
// types.
PietItemRef item_ref = PietItemRef(scene[(group.items.offset >> 2) + i]);
PietItemRef item_ref = PietItem_index(group.items, i);
uint tag = PietItem_tag(item_ref);
tag = PietItem_Circle;
if (tag == PietItem_Circle) {
PietCircle = PietItem_Circle_read(item_ref);
PietCircle circle = PietItem_Circle_read(item_ref);
float r = length(xy + vec2(0.5, 0.5) - circle.center.xy);
float alpha = clamp(circle.radius - r, 0.0, 1.0);
vec4 fg_rgba = unpackUnorm4x8(circle.rgba_color);
// TODO: sRGB
rgb = mix(rgb, fg_rgba.rgb, alpha * fg_rgba.a);
}
}
uvec4 s = uvec4(round(rgba * 255.0));
uint rgba_packed = s.x | (s.y << 8) | (s.z << 16) | (s.w << 24);
image[xy.y * IMAGE_WIDTH + xy.x] = rgba_packed;
if (xy.y == 0 && xy.x < 8) {
image[xy.x] = scene[xy.x];
}
// TODO: sRGB
uvec4 s = uvec4(round(vec4(rgb, 1.0) * 255.0));
uint rgba_packed = s.r | (s.g << 8) | (s.b << 16) | (s.a << 24);
image[xy_uint.y * IMAGE_WIDTH + xy_uint.x] = rgba_packed;
}

Binary file not shown.

View file

@ -2,25 +2,78 @@ use std::path::Path;
use std::fs::File;
use std::io::BufWriter;
use rand::{Rng, RngCore};
use piet_gpu_hal::vulkan::VkInstance;
use piet_gpu_hal::{CmdBuf, Device, MemFlags};
use piet_gpu_types::encoder::{Encode, Encoder};
use piet_gpu_types::scene::{Bbox, PietCircle, PietItem, Point, SimpleGroup};
const WIDTH: usize = 2048;
const HEIGHT: usize = 1536;
const TILE_W: usize = 16;
const TILE_H: usize = 16;
const N_CIRCLES: usize = 100;
fn make_scene() -> Vec<u8> {
let mut rng = rand::thread_rng();
let mut encoder = Encoder::new();
let _reserve_root = encoder.alloc_chunk(SimpleGroup::fixed_size() as u32);
let mut items = Vec::new();
let mut bboxes = Vec::new();
for _ in 0..N_CIRCLES {
let circle = PietCircle {
rgba_color: rng.next_u32(),
center: Point {
xy: [rng.gen_range(0.0, WIDTH as f32), rng.gen_range(0.0, HEIGHT as f32)],
},
radius: rng.gen_range(0.0, 50.0),
};
items.push(PietItem::Circle(circle));
let bbox = Bbox {
// TODO: real bbox
bbox: [0, 0, 0, 0],
};
bboxes.push(bbox);
}
let n_items = bboxes.len() as u32;
let bboxes = bboxes.encode(&mut encoder).transmute();
let items = items.encode(&mut encoder).transmute();
let simple_group = SimpleGroup {
n_items,
bboxes,
items,
};
simple_group.encode_to(&mut encoder.buf_mut()[0..SimpleGroup::fixed_size()]);
// We should avoid this clone.
encoder.buf().to_owned()
}
#[allow(unused)]
fn dump_scene(buf: &[u8]) {
for i in 0..(buf.len() / 4) {
let mut buf_u32 = [0u8; 4];
buf_u32.copy_from_slice(&buf[i * 4 .. i * 4 + 4]);
println!("{:4x}: {:8x}", i * 4, u32::from_le_bytes(buf_u32));
}
}
fn main() {
let instance = VkInstance::new().unwrap();
unsafe {
let device = instance.device().unwrap();
let mem_flags = MemFlags::host_coherent();
let src = (0..256).map(|x| x + 1).collect::<Vec<u32>>();
let scene = make_scene();
//dump_scene(&scene);
let scene_buf = device
.create_buffer(std::mem::size_of_val(&src[..]) as u64, mem_flags)
.create_buffer(std::mem::size_of_val(&scene[..]) as u64, mem_flags)
.unwrap();
device.write_buffer(&scene_buf, &src).unwrap();
device.write_buffer(&scene_buf, &scene).unwrap();
let image_buf = device
.create_buffer((WIDTH * HEIGHT * 4) as u64, mem_flags)
.unwrap();