52: Gfx examples framework r=grovesNL a=kvark

Fixes #37 
It's not functional yet, I think it needs a proper resize event handler. We can do this incrementally.

Co-authored-by: Dzmitry Malyshau <kvarkus@gmail.com>
This commit is contained in:
bors[bot] 2019-02-04 15:01:14 +00:00
commit 8ebaae7a3f
19 changed files with 1136 additions and 74 deletions

107
Cargo.lock generated
View File

@ -40,6 +40,11 @@ dependencies = [
"num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "arrayref"
version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "arrayvec"
version = "0.4.10"
@ -105,6 +110,20 @@ name = "block"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "block-buffer"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"arrayref 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"byte-tools 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "byte-tools"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "byteorder"
version = "1.3.1"
@ -135,6 +154,16 @@ name = "cfg-if"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "cgmath"
version = "0.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"approx 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "clap"
version = "2.32.0"
@ -157,6 +186,14 @@ dependencies = [
"bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "cmake"
version = "0.1.35"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cc 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "cocoa"
version = "0.18.4"
@ -215,6 +252,14 @@ dependencies = [
"syn 0.15.26 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "digest"
version = "0.7.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"generic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "dlib"
version = "0.4.1"
@ -269,6 +314,11 @@ dependencies = [
"synstructure 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "fake-simd"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "foreign-types"
version = "0.3.2"
@ -309,6 +359,14 @@ name = "gcc"
version = "0.3.55"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "generic-array"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "gfx-backend-dx11"
version = "0.1.0"
@ -391,6 +449,18 @@ dependencies = [
"xcb 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "gfx-examples"
version = "0.1.0"
dependencies = [
"cgmath 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)",
"env_logger 0.5.13 (registry+https://github.com/rust-lang/crates.io-index)",
"glsl-to-spirv 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"wgpu 0.1.0",
"wgpu-native 0.1.0",
]
[[package]]
name = "gfx-hal"
version = "0.1.0"
@ -401,6 +471,16 @@ dependencies = [
"fxhash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "glsl-to-spirv"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cmake 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)",
"sha2 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
"tempfile 3.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "humantime"
version = "1.2.0"
@ -902,6 +982,17 @@ dependencies = [
"serde 1.0.85 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "sha2"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"block-buffer 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
"byte-tools 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"digest 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)",
"fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "shared_library"
version = "0.1.9"
@ -1056,6 +1147,11 @@ dependencies = [
"serde 1.0.85 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "typenum"
version = "1.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "ucd-util"
version = "0.1.3"
@ -1300,6 +1396,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum android_glue 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "000444226fcff248f2bc4c7625be32c63caccfecc2723a2b9f78a7487a49c407"
"checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b"
"checksum approx 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3c57ff1a5b00753647aebbbcf4ea67fa1e711a65ea7a30eb90dbf07de2485aee"
"checksum arrayref 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "0d382e583f07208808f6b1249e60848879ba3543f57c32277bf52d69c2f0f0ee"
"checksum arrayvec 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)" = "92c7fb76bc8826a8b33b4ee5bb07a247a81e76764ab4d55e8f73e3a4d8808c71"
"checksum ash 0.24.4 (registry+https://github.com/rust-lang/crates.io-index)" = "11f080bc0414ee1b6b959442cb36478d56c6e6b9bb2b04079a5048d9acc91a30"
"checksum atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "9a7d5b8723950951411ee34d271d99dddcc2035a16ab25310ea2c8cfd4369652"
@ -1308,35 +1405,43 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum backtrace-sys 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)" = "797c830ac25ccc92a7f8a7b9862bde440715531514594a6154e3d4a54dd769b6"
"checksum bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "228047a76f468627ca71776ecdebd732a3423081fcf5125585bcd7c49886ce12"
"checksum block 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a"
"checksum block-buffer 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a076c298b9ecdb530ed9d967e74a6027d6a7478924520acddcddc24c1c8ab3ab"
"checksum byte-tools 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "560c32574a12a89ecd91f5e742165893f86e3ab98d21f8ea548658eb9eef5f40"
"checksum byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a019b10a2a7cdeb292db131fc8113e57ea2a908f6e7894b0c3c671893b65dbeb"
"checksum cbindgen 0.6.8 (git+https://github.com/eqrion/cbindgen?rev=2932819)" = "<none>"
"checksum cc 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)" = "bb4a8b715cb4597106ea87c7c84b2f1d452c7492033765df7f32651e66fcf749"
"checksum cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "082bb9b28e00d3c9d39cc03e64ce4cea0f1bb9b3fde493f0cbc008472d22bdf4"
"checksum cgmath 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)" = "283944cdecc44bf0b8dd010ec9af888d3b4f142844fdbe026c20ef68148d6fe7"
"checksum clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b957d88f4b6a63b9d70d5f454ac8011819c6efa7727858f458ab71c756ce2d3e"
"checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f"
"checksum cmake 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)" = "6ec65ee4f9c9d16f335091d23693457ed4928657ba4982289d7fafee03bc614a"
"checksum cocoa 0.18.4 (registry+https://github.com/rust-lang/crates.io-index)" = "cf79daa4e11e5def06e55306aa3601b87de6b5149671529318da048f67cdd77b"
"checksum core-foundation 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4e2640d6d0bf22e82bed1b73c6aef8d5dd31e5abe6666c57e6d45e2649f4f887"
"checksum core-foundation-sys 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e7ca8a5221364ef15ce201e8ed2f609fc312682a8f4e0e3d4aa5879764e0fa3b"
"checksum core-graphics 0.17.3 (registry+https://github.com/rust-lang/crates.io-index)" = "56790968ab1c8a1202a102e6de05fc6e1ec87da99e4e93e9a7d13efbfc1e95a9"
"checksum d3d12 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4fda5547c55c93b070d59108464bbfd7d9da9563b2ce78fceefc6430e972a420"
"checksum derivative 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6073e9676dbebdddeabaeb63e3b7cefd23c86f5c41d381ee1237cc77b1079898"
"checksum digest 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)" = "03b072242a8cbaf9c145665af9d250c59af3b958f83ed6824e13533cf76d5b90"
"checksum dlib 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "77e51249a9d823a4cb79e3eca6dcd756153e8ed0157b6c04775d04bf1b13b76a"
"checksum downcast-rs 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "18df8ce4470c189d18aa926022da57544f31e154631eb4cfe796aea97051fe6c"
"checksum env_logger 0.5.13 (registry+https://github.com/rust-lang/crates.io-index)" = "15b0a4d2e39f8420210be8b27eeda28029729e2fd4291019455016c348240c38"
"checksum failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "795bd83d3abeb9220f257e597aa0080a508b27533824adf336529648f6abf7e2"
"checksum failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "ea1063915fd7ef4309e222a5a07cf9c319fb9c7836b1f89b85458672dbb127e1"
"checksum fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed"
"checksum foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1"
"checksum foreign-types-shared 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b"
"checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82"
"checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7"
"checksum fxhash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c"
"checksum gcc 0.3.55 (registry+https://github.com/rust-lang/crates.io-index)" = "8f5f3913fa0bfe7ee1fd8248b6b9f42a5af4b9d65ec2dd2c3c26132b950ecfc2"
"checksum generic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ef25c5683767570c2bbd7deba372926a55eaae9982d7726ee2a1050239d45b9d"
"checksum gfx-backend-dx11 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7751e630a3472d96b1a0ce9cd6742f2e17c0f71a6e833f822b914a11f89bd7db"
"checksum gfx-backend-dx12 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2c373f40998da0fd605a7a90ce8d775a8cbcb06558edc2ea9740df1db2077686"
"checksum gfx-backend-empty 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6bb068297aed95a014abaa01738986c2ed5d08c5f9f152c992300c415e9b917c"
"checksum gfx-backend-metal 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "68fa011e32280f7566bddbb736734291b685c812087c99bc848d6ac7ae3e0b7f"
"checksum gfx-backend-vulkan 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "982c618fd9ddeea7e68b2d872b9b6cf13024fc7d4033ba90f0e54ac0d33c798f"
"checksum gfx-hal 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "84c470bce77fcaaea6854858682a99026ff796b880b0ca30511593a6b2bc77c0"
"checksum glsl-to-spirv 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "28caebc98746d507603a2d3df66dcbe04e41d4febad0320f3eec1ef72b6bbef1"
"checksum humantime 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3ca7e5f2e110db35f93b837c81797f3714500b81d517bf20c431b16d3ca4f114"
"checksum itoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1306f3464951f30e30d12373d31c79fbd52d236e5e896fd92f96ec7babbbe60b"
"checksum lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "76f033c7ad61445c5b347c7382dd1237847eb1bce590fe50365dcb33d546be73"
@ -1398,6 +1503,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum serde 1.0.85 (registry+https://github.com/rust-lang/crates.io-index)" = "534b8b91a95e0f71bca3ed5824752d558da048d4248c91af873b63bd60519752"
"checksum serde_derive 1.0.58 (registry+https://github.com/rust-lang/crates.io-index)" = "ac38f51a52a556cd17545798e29536885fb1a3fa63d6399f5ef650f4a7d35901"
"checksum serde_json 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)" = "4b90a9fbe1211e57d3e1c15670f1cb00802988fb23a1a4aad7a2b63544f1920e"
"checksum sha2 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9eb6be24e4c23a84d7184280d2722f7f2731fcdd4a9d886efbfe4413e4847ea0"
"checksum shared_library 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "5a9e7e0f2bfae24d8a5b5a66c5b257a83c7412304311512a0c054cd5e619da11"
"checksum smallvec 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)" = "88aea073965ab29f6edb5493faf96ad662fb18aa9eeb186a3b7057951605ed15"
"checksum smithay-client-toolkit 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "d858330eeed4efaf71c560555e2a6a0597d01b7d52685c3cc964ab1cc360f8c6"
@ -1415,6 +1521,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum textwrap 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "307686869c93e71f94da64286f9a9524c0f308a9e1c87a583de8e9c9039ad3f6"
"checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b"
"checksum toml 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)" = "758664fc71a3a69038656bee8b6be6477d2a6c315a6b81f7081f591bffa4111f"
"checksum typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "612d636f949607bdf9b123b4a6f6d966dedf3ff669f7f045890d3a4a73948169"
"checksum ucd-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "535c204ee4d8434478593480b8f86ab45ec9aae0e83c568ca81abf0fd0e88f86"
"checksum unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "882386231c45df4700b275c7ff55b6f3698780a650026380e72dabe76fa46526"
"checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"

View File

@ -4,4 +4,5 @@ members = [
"wgpu-bindings",
"wgpu-rs",
"examples",
"gfx-examples",
]

View File

@ -9,7 +9,7 @@ fn main() {
let adapter = instance.get_adapter(&wgpu::AdapterDescriptor {
power_preference: wgpu::PowerPreference::LowPower,
});
let device = adapter.create_device(&wgpu::DeviceDescriptor {
let mut device = adapter.create_device(&wgpu::DeviceDescriptor {
extensions: wgpu::Extensions {
anisotropic_filtering: false,
},
@ -54,6 +54,8 @@ fn main() {
},
blend_states: &[&blend_state0],
depth_stencil_state: &depth_stencil_state,
index_format: wgpu::IndexFormat::Uint16,
vertex_buffers: &[],
});
#[cfg(feature = "winit")]
@ -68,7 +70,7 @@ fn main() {
.to_physical(window.get_hidpi_factor());
let surface = instance.create_surface(&window);
let swap_chain = device.create_swap_chain(&surface, &wgpu::SwapChainDescriptor {
let mut swap_chain = device.create_swap_chain(&surface, &wgpu::SwapChainDescriptor {
usage: wgpu::TextureUsageFlags::OUTPUT_ATTACHMENT,
format: wgpu::TextureFormat::B8g8r8a8Unorm,
width: size.width as u32,
@ -95,12 +97,12 @@ fn main() {
_ => {}
}
let (_, view) = swap_chain.get_next_texture();
let frame = swap_chain.get_next_texture();
let mut cmd_buf = device.create_command_buffer(&wgpu::CommandBufferDescriptor { todo: 0 });
{
let mut rpass = cmd_buf.begin_render_pass(&wgpu::RenderPassDescriptor {
color_attachments: &[wgpu::RenderPassColorAttachmentDescriptor {
attachment: &view,
attachment: &frame.view,
load_op: wgpu::LoadOp::Clear,
store_op: wgpu::StoreOp::Store,
clear_color: wgpu::Color::GREEN,
@ -116,7 +118,6 @@ fn main() {
.get_queue()
.submit(&[cmd_buf]);
swap_chain.present();
ControlFlow::Continue
});
}

28
gfx-examples/Cargo.toml Normal file
View File

@ -0,0 +1,28 @@
[package]
name = "gfx-examples"
version = "0.1.0"
authors = [
"Dzmitry Malyshau <kvark@mozilla.com>",
"Joshua Groves <josh@joshgroves.com>",
]
edition = "2018"
publish = false
[[bin]]
name = "cube"
path = "src/cube.rs"
[features]
default = []
metal = ["wgpu-native/gfx-backend-metal"]
dx11 = ["wgpu-native/gfx-backend-dx11"]
dx12 = ["wgpu-native/gfx-backend-dx12"]
vulkan = ["wgpu-native/gfx-backend-vulkan"]
[dependencies]
wgpu-native = { path = "../wgpu-native" }
wgpu = { path = "../wgpu-rs", features = ["winit"] }
cgmath = "0.17"
env_logger = "0.5"
glsl-to-spirv = "0.1"
log = "0.4"

6
gfx-examples/README.md Normal file
View File

@ -0,0 +1,6 @@
# gfx pre-ll examples
The original gfx-rs examples had grown over several years, but then were abandoned owhen the gfx API was changed to match Vulkan:
https://github.com/gfx-rs/gfx/tree/pre-ll/examples
wgpu-rs is considered to be the spiritual successor of gfx pre-ll, so this is the new home for the examples.

View File

@ -0,0 +1,12 @@
#version 450
layout(location = 0) in vec2 v_TexCoord;
layout(location = 0) out vec4 o_Target;
layout(set = 0, binding = 1) uniform texture2D t_Color;
layout(set = 0, binding = 2) uniform sampler s_Color;
void main() {
vec4 tex = texture(sampler2D(t_Color, s_Color), v_TexCoord);
float mag = length(v_TexCoord-vec2(0.5));
o_Target = mix(tex, vec4(0.0), mag*mag);
}

View File

@ -0,0 +1,14 @@
#version 450
layout(location = 0) in vec4 a_Pos;
layout(location = 1) in vec2 a_TexCoord;
layout(location = 0) out vec2 v_TexCoord;
layout(set = 0, binding = 0) uniform Locals {
mat4 u_Transform;
};
void main() {
v_TexCoord = a_TexCoord;
gl_Position = u_Transform * a_Pos;
}

331
gfx-examples/src/cube.rs Normal file
View File

@ -0,0 +1,331 @@
mod framework;
#[derive(Clone)]
struct Vertex {
pos: [f32; 4],
tex_coord: [f32; 2],
}
fn vertex(pos: [i8; 3], tc: [i8; 2]) -> Vertex {
Vertex {
pos: [pos[0] as f32, pos[1] as f32, pos[2] as f32, 1.0],
tex_coord: [tc[0] as f32, tc[1] as f32],
}
}
fn create_vertices() -> (Vec<Vertex>, Vec<u16>) {
let vertex_data = [
// top (0, 0, 1)
vertex([-1, -1, 1], [0, 0]),
vertex([ 1, -1, 1], [1, 0]),
vertex([ 1, 1, 1], [1, 1]),
vertex([-1, 1, 1], [0, 1]),
// bottom (0, 0, -1)
vertex([-1, 1, -1], [1, 0]),
vertex([ 1, 1, -1], [0, 0]),
vertex([ 1, -1, -1], [0, 1]),
vertex([-1, -1, -1], [1, 1]),
// right (1, 0, 0)
vertex([ 1, -1, -1], [0, 0]),
vertex([ 1, 1, -1], [1, 0]),
vertex([ 1, 1, 1], [1, 1]),
vertex([ 1, -1, 1], [0, 1]),
// left (-1, 0, 0)
vertex([-1, -1, 1], [1, 0]),
vertex([-1, 1, 1], [0, 0]),
vertex([-1, 1, -1], [0, 1]),
vertex([-1, -1, -1], [1, 1]),
// front (0, 1, 0)
vertex([ 1, 1, -1], [1, 0]),
vertex([-1, 1, -1], [0, 0]),
vertex([-1, 1, 1], [0, 1]),
vertex([ 1, 1, 1], [1, 1]),
// back (0, -1, 0)
vertex([ 1, -1, 1], [0, 0]),
vertex([-1, -1, 1], [1, 0]),
vertex([-1, -1, -1], [1, 1]),
vertex([ 1, -1, -1], [0, 1]),
];
let index_data: &[u16] = &[
0, 1, 2, 2, 3, 0, // top
4, 5, 6, 6, 7, 4, // bottom
8, 9, 10, 10, 11, 8, // right
12, 13, 14, 14, 15, 12, // left
16, 17, 18, 18, 19, 16, // front
20, 21, 22, 22, 23, 20, // back
];
(vertex_data.to_vec(), index_data.to_vec())
}
fn create_texels(size: usize) -> Vec<u8> {
use std::iter;
(0 .. size * size)
.flat_map(|id| {
// get high five for recognizing this ;)
let cx = 3.0*(id % size) as f32 / (size - 1) as f32 - 2.0;
let cy = 2.0*(id / size) as f32 / (size - 1) as f32 - 1.0;
let (mut x, mut y, mut count) = (cx, cy, 0);
while count < 0xFF && x*x + y*y < 4.0 {
let old_x = x;
x = x * x - y * y + cx;
y = 2.0 * old_x * y + cy;
count += 1;
}
iter::once(0xFF - (count * 5) as u8)
.chain(iter::once(0xFF - (count * 15) as u8))
.chain(iter::once(0xFF - (count * 50) as u8))
.chain(iter::once(1))
})
.collect()
}
struct Cube {
vertex_buf: wgpu::Buffer,
index_buf: wgpu::Buffer,
index_count: usize,
bind_group: wgpu::BindGroup,
pipeline: wgpu::RenderPipeline,
}
impl framework::Example for Cube {
fn init(device: &mut wgpu::Device, sc_desc: &wgpu::SwapChainDescriptor) -> Self {
use std::mem;
let mut init_command_buf = device.create_command_buffer(&wgpu::CommandBufferDescriptor {
todo: 0,
});
// Create the vertex and index buffers
let vertex_size = mem::size_of::<Vertex>();
let (vertex_data, index_data) = create_vertices();
let vertex_buf = device.create_buffer(&wgpu::BufferDescriptor {
size: (vertex_data.len() * vertex_size) as u32,
usage: wgpu::BufferUsageFlags::VERTEX | wgpu::BufferUsageFlags::TRANSFER_DST,
});
vertex_buf.set_sub_data(0, framework::cast_slice(&vertex_data));
let index_buf = device.create_buffer(&wgpu::BufferDescriptor {
size: (index_data.len() * 2) as u32,
usage: wgpu::BufferUsageFlags::INDEX | wgpu::BufferUsageFlags::TRANSFER_DST,
});
index_buf.set_sub_data(0, framework::cast_slice(&index_data));
// Create pipeline layout
let bind_group_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
bindings: &[
wgpu::BindGroupLayoutBinding {
binding: 0,
visibility: wgpu::ShaderStageFlags::VERTEX,
ty: wgpu::BindingType::UniformBuffer,
},
wgpu::BindGroupLayoutBinding {
binding: 1,
visibility: wgpu::ShaderStageFlags::FRAGMENT,
ty: wgpu::BindingType::SampledTexture,
},
wgpu::BindGroupLayoutBinding {
binding: 2,
visibility: wgpu::ShaderStageFlags::FRAGMENT,
ty: wgpu::BindingType::Sampler,
},
],
});
let pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
bind_group_layouts: &[&bind_group_layout],
});
// Create the texture
let size = 256u32;
let texels = create_texels(size as usize);
let texture_extent = wgpu::Extent3d {
width: size,
height: size,
depth: 1,
};
let texture = device.create_texture(&wgpu::TextureDescriptor {
size: texture_extent,
array_size: 1,
dimension: wgpu::TextureDimension::D2,
format: wgpu::TextureFormat::R8g8b8a8Unorm,
usage: wgpu::TextureUsageFlags::SAMPLED | wgpu::TextureUsageFlags::TRANSFER_DST
});
let texture_view = texture.create_default_texture_view();
let temp_buf = device.create_buffer(&wgpu::BufferDescriptor {
size: texels.len() as u32,
usage: wgpu::BufferUsageFlags::TRANSFER_SRC | wgpu::BufferUsageFlags::TRANSFER_DST
});
temp_buf.set_sub_data(0, &texels);
init_command_buf.copy_buffer_to_texture(
wgpu::BufferCopyView {
buffer: &temp_buf,
offset: 0,
row_pitch: 4 * size,
image_height: size,
},
wgpu::TextureCopyView {
texture: &texture,
level: 0,
slice: 0,
origin: wgpu::Origin3d {
x: 0.0,
y: 0.0,
z: 0.0,
},
},
texture_extent,
);
// Create other resources
let sampler = device.create_sampler(&wgpu::SamplerDescriptor {
r_address_mode: wgpu::AddressMode::ClampToEdge,
s_address_mode: wgpu::AddressMode::ClampToEdge,
t_address_mode: wgpu::AddressMode::ClampToEdge,
mag_filter: wgpu::FilterMode::Nearest,
min_filter: wgpu::FilterMode::Linear,
mipmap_filter: wgpu::FilterMode::Nearest,
lod_min_clamp: -100.0,
lod_max_clamp: 100.0,
max_anisotropy: 0,
compare_function: wgpu::CompareFunction::Always,
border_color: wgpu::BorderColor::TransparentBlack,
});
let uniform_buf = device.create_buffer(&wgpu::BufferDescriptor {
size: 64,
usage: wgpu::BufferUsageFlags::UNIFORM | wgpu::BufferUsageFlags::TRANSFER_DST,
});
{
let aspect_ratio = sc_desc.width as f32 / sc_desc.height as f32;
let mx_projection = cgmath::perspective(cgmath::Deg(45f32), aspect_ratio, 1.0, 10.0);
let mx_view = cgmath::Matrix4::look_at(
cgmath::Point3::new(1.5f32, -5.0, 3.0),
cgmath::Point3::new(0f32, 0.0, 0.0),
cgmath::Vector3::unit_z(),
);
let mx_total = mx_projection * mx_view;
let mx_raw: &[f32; 16] = mx_total.as_ref();
uniform_buf.set_sub_data(0, framework::cast_slice(&mx_raw[..]));
}
// Create bind group
let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
layout: &bind_group_layout,
bindings: &[
wgpu::Binding {
binding: 0,
resource: wgpu::BindingResource::Buffer {
buffer: &uniform_buf,
range: 0 .. 64,
},
},
wgpu::Binding {
binding: 1,
resource: wgpu::BindingResource::TextureView(&texture_view),
},
wgpu::Binding {
binding: 2,
resource: wgpu::BindingResource::Sampler(&sampler),
},
],
});
// Create the render pipeline
let vs_bytes = framework::load_glsl("cube.vert", wgpu::ShaderStage::Vertex);
let fs_bytes = framework::load_glsl("cube.frag", wgpu::ShaderStage::Fragment);
let vs_module = device.create_shader_module(&vs_bytes);
let fs_module = device.create_shader_module(&fs_bytes);
let blend_state0 = device.create_blend_state(&wgpu::BlendStateDescriptor::REPLACE);
let depth_stencil_state =
device.create_depth_stencil_state(&wgpu::DepthStencilStateDescriptor::IGNORE);
let pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
layout: &pipeline_layout,
stages: &[
wgpu::PipelineStageDescriptor {
module: &vs_module,
stage: wgpu::ShaderStage::Vertex,
entry_point: "main",
},
wgpu::PipelineStageDescriptor {
module: &fs_module,
stage: wgpu::ShaderStage::Fragment,
entry_point: "main",
},
],
primitive_topology: wgpu::PrimitiveTopology::TriangleList,
attachments_state: wgpu::AttachmentsState {
color_attachments: &[wgpu::Attachment {
format: sc_desc.format,
samples: 1,
}],
depth_stencil_attachment: None,
},
blend_states: &[&blend_state0],
depth_stencil_state: &depth_stencil_state,
index_format: wgpu::IndexFormat::Uint16,
vertex_buffers: &[
wgpu::VertexBufferDescriptor {
stride: vertex_size as u32,
step_mode: wgpu::InputStepMode::Vertex,
attributes: &[
wgpu::VertexAttributeDescriptor {
attribute_index: 0,
format: wgpu::VertexFormat::FloatR32G32B32A32,
offset: 0,
},
wgpu::VertexAttributeDescriptor {
attribute_index: 1,
format: wgpu::VertexFormat::FloatR32G32,
offset: 4 * 4,
},
],
},
],
});
// Done
device.get_queue().submit(&[init_command_buf]);
Cube {
vertex_buf,
index_buf,
index_count: index_data.len(),
bind_group,
pipeline,
}
}
fn update(&mut self, _event: framework::winit::WindowEvent) {
}
fn render(&mut self, frame: &wgpu::SwapChainOutput, device: &mut wgpu::Device) {
let mut cmd_buf = device.create_command_buffer(&wgpu::CommandBufferDescriptor { todo: 0 });
{
let mut rpass = cmd_buf.begin_render_pass(&wgpu::RenderPassDescriptor {
color_attachments: &[wgpu::RenderPassColorAttachmentDescriptor {
attachment: &frame.view,
load_op: wgpu::LoadOp::Clear,
store_op: wgpu::StoreOp::Store,
clear_color: wgpu::Color { r: 0.1, g: 0.2, b: 0.3, a: 1.0 },
}],
depth_stencil_attachment: None,
});
rpass.set_pipeline(&self.pipeline);
rpass.set_bind_group(0, &self.bind_group);
rpass.set_index_buffer(&self.index_buf, 0);
rpass.set_vertex_buffers(&[(&self.vertex_buf, 0)]);
rpass.draw_indexed(0 .. self.index_count as u32, 0, 0..1);
rpass.end_pass();
}
device
.get_queue()
.submit(&[cmd_buf]);
}
}
fn main() {
framework::run::<Cube>("cube");
}

View File

@ -0,0 +1,112 @@
pub use wgpu_native::winit;
use log::info;
pub fn cast_slice<T>(data: &[T]) -> &[u8] {
use std::mem::size_of;
use std::slice::from_raw_parts;
unsafe {
from_raw_parts(data.as_ptr() as *const u8, data.len() * size_of::<T>())
}
}
pub fn load_glsl(name: &str, stage: wgpu::ShaderStage) -> Vec<u8> {
use std::fs::read_to_string;
use std::io::Read;
use std::path::PathBuf;
let ty = match stage {
wgpu::ShaderStage::Vertex => glsl_to_spirv::ShaderType::Vertex,
wgpu::ShaderStage::Fragment => glsl_to_spirv::ShaderType::Fragment,
wgpu::ShaderStage::Compute => glsl_to_spirv::ShaderType::Compute,
};
let path = PathBuf::from("data").join(name);
let code = read_to_string(path).unwrap();
let mut output = glsl_to_spirv::compile(&code, ty).unwrap();
let mut spv = Vec::new();
output.read_to_end(&mut spv).unwrap();
spv
}
pub trait Example {
fn init(device: &mut wgpu::Device, sc_desc: &wgpu::SwapChainDescriptor) -> Self;
fn update(&mut self, event: winit::WindowEvent);
fn render(&mut self, frame: &wgpu::SwapChainOutput, device: &mut wgpu::Device);
}
pub fn run<E: Example>(title: &str) {
use wgpu_native::winit::{
Event, ElementState, EventsLoop, KeyboardInput, Window, WindowEvent, VirtualKeyCode
};
info!("Initializing the device...");
env_logger::init();
let instance = wgpu::Instance::new();
let adapter = instance.get_adapter(&wgpu::AdapterDescriptor {
power_preference: wgpu::PowerPreference::LowPower,
});
let mut device = adapter.create_device(&wgpu::DeviceDescriptor {
extensions: wgpu::Extensions {
anisotropic_filtering: false,
},
});
info!("Initializing the window...");
let mut events_loop = EventsLoop::new();
let window = Window::new(&events_loop).unwrap();
window.set_title(title);
let size = window
.get_inner_size()
.unwrap()
.to_physical(window.get_hidpi_factor());
let surface = instance.create_surface(&window);
let sc_desc = wgpu::SwapChainDescriptor {
usage: wgpu::TextureUsageFlags::OUTPUT_ATTACHMENT,
format: wgpu::TextureFormat::B8g8r8a8Unorm,
width: size.width as u32,
height: size.height as u32,
};
let mut swap_chain = device.create_swap_chain(&surface, &sc_desc);
info!("Initializing the example...");
let mut example = E::init(&mut device, &sc_desc);
info!("Entering render loop...");
let mut running = true;
while running {
events_loop.poll_events(|event| {
match event {
Event::WindowEvent {
event: WindowEvent::Resized(size),
..
} => {
let physical = size.to_physical(window.get_hidpi_factor());
info!("Resized to {:?}", physical);
}
Event::WindowEvent { event, .. } => match event {
WindowEvent::KeyboardInput {
input: KeyboardInput {
virtual_keycode: Some(VirtualKeyCode::Escape),
state: ElementState::Pressed,
..
},
..
} |
WindowEvent::CloseRequested => {
running = false;
}
_ => {
example.update(event);
}
}
_ => ()
}
});
let frame = swap_chain.get_next_texture();
example.render(&frame, &mut device);
}
}

View File

@ -9,6 +9,13 @@
#include <stdint.h>
#include <stdlib.h>
typedef enum {
WGPUAddressMode_ClampToEdge = 0,
WGPUAddressMode_Repeat = 1,
WGPUAddressMode_MirrorRepeat = 2,
WGPUAddressMode_ClampToBorderColor = 3,
} WGPUAddressMode;
typedef enum {
WGPUBindingType_UniformBuffer = 0,
WGPUBindingType_Sampler = 1,
@ -40,6 +47,12 @@ typedef enum {
WGPUBlendOperation_Max = 4,
} WGPUBlendOperation;
typedef enum {
WGPUBorderColor_TransparentBlack = 0,
WGPUBorderColor_OpaqueBlack = 1,
WGPUBorderColor_OpaqueWhite = 2,
} WGPUBorderColor;
typedef enum {
WGPUCompareFunction_Never = 0,
WGPUCompareFunction_Less = 1,
@ -51,6 +64,21 @@ typedef enum {
WGPUCompareFunction_Always = 7,
} WGPUCompareFunction;
typedef enum {
WGPUFilterMode_Nearest = 0,
WGPUFilterMode_Linear = 1,
} WGPUFilterMode;
typedef enum {
WGPUIndexFormat_Uint16 = 0,
WGPUIndexFormat_Uint32 = 1,
} WGPUIndexFormat;
typedef enum {
WGPUInputStepMode_Vertex = 0,
WGPUInputStepMode_Instance = 1,
} WGPUInputStepMode;
typedef enum {
WGPULoadOp_Clear = 0,
WGPULoadOp_Load = 1,
@ -113,6 +141,13 @@ typedef enum {
WGPUTextureViewDimension_D3,
} WGPUTextureViewDimension;
typedef enum {
WGPUVertexFormat_FloatR32G32B32A32 = 0,
WGPUVertexFormat_FloatR32G32B32 = 1,
WGPUVertexFormat_FloatR32G32 = 2,
WGPUVertexFormat_FloatR32 = 3,
} WGPUVertexFormat;
typedef WGPUId WGPUDeviceId;
typedef WGPUId WGPUAdapterId;
@ -165,6 +200,34 @@ typedef struct {
const WGPURenderPassDepthStencilAttachmentDescriptor_TextureViewId *depth_stencil_attachment;
} WGPURenderPassDescriptor;
typedef struct {
WGPUBufferId buffer;
uint32_t offset;
uint32_t row_pitch;
uint32_t image_height;
} WGPUBufferCopyView;
typedef WGPUId WGPUTextureId;
typedef struct {
float x;
float y;
float z;
} WGPUOrigin3d;
typedef struct {
WGPUTextureId texture;
uint32_t level;
uint32_t slice;
WGPUOrigin3d origin;
} WGPUTextureCopyView;
typedef struct {
uint32_t width;
uint32_t height;
uint32_t depth;
} WGPUExtent3d;
typedef WGPUId WGPUBindGroupId;
typedef WGPUId WGPUComputePipelineId;
@ -306,6 +369,27 @@ typedef struct {
const WGPUAttachment *depth_stencil_attachment;
} WGPUAttachmentsState;
typedef uint32_t WGPUShaderAttributeIndex;
typedef struct {
uint32_t offset;
WGPUVertexFormat format;
WGPUShaderAttributeIndex attribute_index;
} WGPUVertexAttributeDescriptor;
typedef struct {
uint32_t stride;
WGPUInputStepMode step_mode;
const WGPUVertexAttributeDescriptor *attributes;
uintptr_t attributes_count;
} WGPUVertexBufferDescriptor;
typedef struct {
WGPUIndexFormat index_format;
const WGPUVertexBufferDescriptor *vertex_buffers;
uintptr_t vertex_buffers_count;
} WGPUVertexBufferStateDescriptor;
typedef struct {
WGPUPipelineLayoutId layout;
const WGPUPipelineStageDescriptor *stages;
@ -315,8 +399,23 @@ typedef struct {
const WGPUBlendStateId *blend_states;
uintptr_t blend_states_length;
WGPUDepthStencilStateId depth_stencil_state;
WGPUVertexBufferStateDescriptor vertex_buffer_state;
} WGPURenderPipelineDescriptor;
typedef struct {
WGPUAddressMode r_address_mode;
WGPUAddressMode s_address_mode;
WGPUAddressMode t_address_mode;
WGPUFilterMode mag_filter;
WGPUFilterMode min_filter;
WGPUFilterMode mipmap_filter;
float lod_min_clamp;
float lod_max_clamp;
uint32_t max_anisotropy;
WGPUCompareFunction compare_function;
WGPUBorderColor border_color;
} WGPUSamplerDescriptor;
typedef struct {
const uint8_t *bytes;
uintptr_t length;
@ -339,14 +438,6 @@ typedef struct {
uint32_t height;
} WGPUSwapChainDescriptor;
typedef WGPUId WGPUTextureId;
typedef struct {
uint32_t width;
uint32_t height;
uint32_t depth;
} WGPUExtent3d;
typedef struct {
WGPUExtent3d size;
uint32_t array_size;
@ -444,6 +535,8 @@ typedef struct {
#define WGPUTextureUsageFlags_TRANSFER_SRC 1
#define WGPUTextureUsageFlags_UNINITIALIZED 65535
#define WGPUTrackPermit_EXTEND (WGPUTrackPermit){ .bits = 1 }
#define WGPUTrackPermit_REPLACE (WGPUTrackPermit){ .bits = 2 }
@ -463,6 +556,11 @@ WGPUComputePassId wgpu_command_buffer_begin_compute_pass(WGPUCommandBufferId com
WGPURenderPassId wgpu_command_buffer_begin_render_pass(WGPUCommandBufferId command_buffer_id,
WGPURenderPassDescriptor desc);
void wgpu_command_buffer_copy_buffer_to_texture(WGPUCommandBufferId command_buffer_id,
const WGPUBufferCopyView *source,
const WGPUTextureCopyView *destination,
WGPUExtent3d copy_size);
void wgpu_compute_pass_dispatch(WGPUComputePassId pass_id, uint32_t x, uint32_t y, uint32_t z);
WGPUCommandBufferId wgpu_compute_pass_end_pass(WGPUComputePassId pass_id);
@ -498,6 +596,8 @@ WGPUPipelineLayoutId wgpu_device_create_pipeline_layout(WGPUDeviceId device_id,
WGPURenderPipelineId wgpu_device_create_render_pipeline(WGPUDeviceId device_id,
const WGPURenderPipelineDescriptor *desc);
WGPUSamplerId wgpu_device_create_sampler(WGPUDeviceId device_id, const WGPUSamplerDescriptor *desc);
WGPUShaderModuleId wgpu_device_create_shader_module(WGPUDeviceId device_id,
const WGPUShaderModuleDescriptor *desc);
@ -552,6 +652,11 @@ void wgpu_render_pass_set_index_buffer(WGPURenderPassId pass_id,
void wgpu_render_pass_set_pipeline(WGPURenderPassId pass_id, WGPURenderPipelineId pipeline_id);
void wgpu_render_pass_set_vertex_buffers(WGPURenderPassId pass_id,
const WGPUBufferId *buffer_ptr,
const uint32_t *offset_ptr,
uintptr_t count);
WGPUSwapChainOutput wgpu_swap_chain_get_next_texture(WGPUSwapChainId swap_chain_id);
void wgpu_swap_chain_present(WGPUSwapChainId swap_chain_id);

View File

@ -13,12 +13,13 @@ use crate::device::{
};
use crate::registry::{Items, HUB};
use crate::swap_chain::{SwapChainLink, SwapImageEpoch};
use crate::track::{BufferTracker, TextureTracker};
use crate::track::{BufferTracker, TextureTracker, TrackPermit, Tracktion};
use crate::{conv, resource};
use crate::{
BufferId, CommandBufferId, ComputePassId, DeviceId,
RenderPassId, TextureId, TextureViewId,
BufferUsageFlags, TextureUsageFlags, Color, Origin3d,
BufferUsageFlags, TextureUsageFlags, Color,
Extent3d, Origin3d,
LifeGuard, Stored, WeaklyStored,
B,
};
@ -33,6 +34,8 @@ use std::{iter, slice};
use std::thread::ThreadId;
const BITS_PER_BYTE: u32 = 8;
#[repr(C)]
#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
pub enum LoadOp {
@ -379,3 +382,97 @@ pub extern "C" fn wgpu_command_buffer_begin_compute_pass(
.write()
.register(ComputePass::new(raw, stored))
}
#[no_mangle]
pub extern "C" fn wgpu_command_buffer_copy_buffer_to_texture(
command_buffer_id: CommandBufferId,
source: &BufferCopyView,
destination: &TextureCopyView,
copy_size: Extent3d,
) {
let mut cmb_guard = HUB.command_buffers.write();
let cmb = cmb_guard.get_mut(command_buffer_id);
let buffer_guard = HUB.buffers.read();
let texture_guard = HUB.textures.read();
let (src_buffer, src_tracktion) = cmb.buffer_tracker
.get_with_usage(
&*buffer_guard,
source.buffer,
BufferUsageFlags::TRANSFER_SRC,
TrackPermit::REPLACE,
)
.unwrap();
let src_barrier = match src_tracktion {
Tracktion::Init |
Tracktion::Keep => None,
Tracktion::Extend { .. } => unreachable!(),
Tracktion::Replace { old } => Some(hal::memory::Barrier::Buffer {
states: conv::map_buffer_state(old) .. hal::buffer::Access::TRANSFER_WRITE,
target: &src_buffer.raw,
families: None,
range: None .. None,
}),
};
let (dst_texture, dst_tracktion) = cmb.texture_tracker
.get_with_usage(
&*texture_guard,
destination.texture,
TextureUsageFlags::TRANSFER_DST,
TrackPermit::REPLACE,
)
.unwrap();
let aspects = dst_texture.full_range.aspects;
let dst_texture_state = conv::map_texture_state(TextureUsageFlags::TRANSFER_DST, aspects);
let dst_barrier = match dst_tracktion {
Tracktion::Init |
Tracktion::Keep => None,
Tracktion::Extend { .. } => unreachable!(),
Tracktion::Replace { old } => Some(hal::memory::Barrier::Image {
states: conv::map_texture_state(old, aspects) .. dst_texture_state,
target: &dst_texture.raw,
families: None,
range: dst_texture.full_range.clone(),
}),
};
if let Some(ref link) = dst_texture.swap_chain_link {
cmb.swap_chain_links.push(SwapChainLink {
swap_chain_id: link.swap_chain_id.clone(),
epoch: *link.epoch.lock(),
image_index: link.image_index,
});
}
let bytes_per_texel = conv::map_texture_format(dst_texture.format)
.surface_desc().bits as u32 / BITS_PER_BYTE;
let buffer_width = source.row_pitch / bytes_per_texel;
assert_eq!(source.row_pitch % bytes_per_texel, 0);
let region = hal::command::BufferImageCopy {
buffer_offset: source.offset as hal::buffer::Offset,
buffer_width,
buffer_height: source.image_height,
image_layers: hal::image::SubresourceLayers {
aspects, //TODO
level: destination.level as hal::image::Level,
layers: destination.slice as u16 .. destination.slice as u16 + 1,
},
image_offset: conv::map_origin(destination.origin),
image_extent: conv::map_extent(copy_size),
};
let cmb_raw = cmb.raw.last_mut().unwrap();
unsafe {
cmb_raw.pipeline_barrier(
all_buffer_stages() .. all_image_stages(),
hal::memory::Dependencies::empty(),
src_barrier.into_iter().chain(dst_barrier),
);
cmb_raw.copy_buffer_to_image(
&src_buffer.raw,
&dst_texture.raw,
dst_texture_state.1,
iter::once(region),
);
}
}

View File

@ -9,7 +9,7 @@ use crate::{
use hal::command::RawCommandBuffer;
use std::iter;
use std::{iter, slice};
pub struct RenderPass<B: hal::Backend> {
@ -87,10 +87,19 @@ pub extern "C" fn wgpu_render_pass_set_index_buffer(
#[no_mangle]
pub extern "C" fn wgpu_render_pass_set_vertex_buffers(
pass_id: RenderPassId, buffers: &[BufferId], offsets: &[u32]
pass_id: RenderPassId,
buffer_ptr: *const BufferId,
offset_ptr: *const u32,
count: usize,
) {
let mut pass_guard = HUB.render_passes.write();
let buffer_guard = HUB.buffers.read();
let buffers = unsafe {
slice::from_raw_parts(buffer_ptr, count)
};
let offsets = unsafe {
slice::from_raw_parts(offset_ptr, count)
};
let pass = pass_guard.get_mut(pass_id);
for &id in buffers {
@ -104,7 +113,6 @@ pub extern "C" fn wgpu_render_pass_set_vertex_buffers(
.unwrap();
}
assert_eq!(buffers.len(), offsets.len());
let buffers = buffers
.iter()
.map(|&id| &buffer_guard.get(id).raw)

View File

@ -1,4 +1,8 @@
use crate::{binding_model, command, pipeline, resource, Color, Extent3d};
use crate::{
binding_model, command, pipeline, resource, Color,
Extent3d, Origin3d,
};
pub fn map_buffer_usage(
usage: resource::BufferUsageFlags,
@ -100,6 +104,22 @@ pub fn map_shader_stage_flags(
value
}
pub fn map_origin(origin: Origin3d) -> hal::image::Offset {
hal::image::Offset {
x: origin.x as i32,
y: origin.y as i32,
z: origin.z as i32,
}
}
pub fn map_extent(extent: Extent3d) -> hal::image::Extent {
hal::image::Extent {
width: extent.width,
height: extent.height,
depth: extent.depth,
}
}
pub fn map_primitive_topology(primitive_topology: pipeline::PrimitiveTopology) -> hal::Primitive {
use hal::Primitive as H;
use crate::pipeline::PrimitiveTopology::*;
@ -222,7 +242,7 @@ fn map_stencil_face(
}
}
fn map_compare_function(compare_function: resource::CompareFunction) -> hal::pso::Comparison {
pub fn map_compare_function(compare_function: resource::CompareFunction) -> hal::pso::Comparison {
use hal::pso::Comparison as H;
use crate::resource::CompareFunction::*;
match compare_function {
@ -263,6 +283,17 @@ pub fn map_texture_format(texture_format: resource::TextureFormat) -> hal::forma
}
}
pub fn map_vertex_format(vertex_format: pipeline::VertexFormat) -> hal::format::Format {
use hal::format::Format as H;
use crate::pipeline::VertexFormat::*;
match vertex_format {
FloatR32G32B32A32 => H::Rgba32Float,
FloatR32G32B32 => H::Rgb32Float,
FloatR32G32 => H::Rg32Float,
FloatR32 => H::R32Float,
}
}
fn checked_u32_as_u16(value: u32) -> u16 {
assert!(value <= ::std::u16::MAX as u32);
value as u16
@ -408,3 +439,21 @@ pub fn map_load_store_ops(
pub fn map_color(color: Color) -> hal::pso::ColorValue {
[color.r, color.g, color.b, color.a]
}
pub fn map_filter(filter: resource::FilterMode) -> hal::image::Filter {
match filter {
resource::FilterMode::Nearest => hal::image::Filter::Nearest,
resource::FilterMode::Linear => hal::image::Filter::Linear,
}
}
pub fn map_wrap(address: resource::AddressMode) -> hal::image::WrapMode {
use hal::image::WrapMode as W;
use crate::resource::AddressMode as Am;
match address {
Am::ClampToEdge => W::Clamp,
Am::Repeat => W::Tile,
Am::MirrorRepeat => W::Mirror,
Am::ClampToBorderColor => W::Border,
}
}

View File

@ -6,7 +6,7 @@ use crate::{
BindGroupLayoutId, BindGroupId,
BlendStateId, BufferId, CommandBufferId, DepthStencilStateId,
AdapterId, DeviceId, PipelineLayoutId, QueueId, RenderPipelineId, ShaderModuleId,
TextureId, TextureViewId,
SamplerId, TextureId, TextureViewId,
SurfaceId, SwapChainId,
};
@ -525,6 +525,49 @@ pub extern "C" fn wgpu_texture_view_destroy(_texture_view_id: TextureViewId) {
unimplemented!()
}
#[no_mangle]
pub extern "C" fn wgpu_device_create_sampler(
device_id: DeviceId, desc: &resource::SamplerDescriptor
) -> SamplerId {
let device_guard = HUB.devices.read();
let device = &device_guard.get(device_id);
let info = hal::image::SamplerInfo {
min_filter: conv::map_filter(desc.min_filter),
mag_filter: conv::map_filter(desc.mag_filter),
mip_filter: conv::map_filter(desc.mipmap_filter),
wrap_mode: (
conv::map_wrap(desc.r_address_mode),
conv::map_wrap(desc.s_address_mode),
conv::map_wrap(desc.t_address_mode),
),
lod_bias: 0.0.into(),
lod_range: desc.lod_min_clamp.into() .. desc.lod_max_clamp.into(),
comparison: if desc.compare_function == resource::CompareFunction::Always {
None
} else {
Some(conv::map_compare_function(desc.compare_function))
},
border: hal::image::PackedColor(match desc.border_color {
resource::BorderColor::TransparentBlack => 0x00000000,
resource::BorderColor::OpaqueBlack => 0x000000FF,
resource::BorderColor::OpaqueWhite => 0xFFFFFFFF,
}),
anisotropic: hal::image::Anisotropic::Off, //TODO
};
let raw = unsafe {
device.raw
.create_sampler(info)
.unwrap()
};
HUB.samplers
.write()
.register(resource::Sampler {
raw
})
}
#[no_mangle]
pub extern "C" fn wgpu_device_create_bind_group_layout(
device_id: DeviceId,
@ -1001,11 +1044,37 @@ pub extern "C" fn wgpu_device_create_render_pipeline(
conservative: false,
};
// TODO
let vertex_buffers: Vec<hal::pso::VertexBufferDesc> = Vec::new();
// TODO
let attributes: Vec<hal::pso::AttributeDesc> = Vec::new();
let desc_vbs = unsafe {
slice::from_raw_parts(desc.vertex_buffer_state.vertex_buffers, desc.vertex_buffer_state.vertex_buffers_count)
};
let mut vertex_buffers = Vec::with_capacity(desc_vbs.len());
let mut attributes = Vec::new();
for (i, vb_state) in desc_vbs.iter().enumerate() {
if vb_state.attributes_count == 0 {
continue
}
vertex_buffers.push(hal::pso::VertexBufferDesc {
binding: i as u32,
stride: vb_state.stride,
rate: match vb_state.step_mode {
pipeline::InputStepMode::Vertex => 0,
pipeline::InputStepMode::Instance => 1,
},
});
let desc_atts = unsafe {
slice::from_raw_parts(vb_state.attributes, vb_state.attributes_count)
};
for attribute in desc_atts {
attributes.push(hal::pso::AttributeDesc {
location: attribute.attribute_index,
binding: i as u32,
element: hal::pso::Element {
format: conv::map_vertex_format(attribute.format),
offset: attribute.offset,
},
});
}
}
let input_assembler = hal::pso::InputAssemblerDesc {
primitive: conv::map_primitive_topology(desc.primitive_topology),

View File

@ -50,17 +50,33 @@ pub extern "C" fn wgpu_instance_create_surface_from_winit(
instance_id: InstanceId,
window: &winit::Window,
) -> SurfaceId {
let raw = HUB.instances
.read()
.get(instance_id)
.create_surface(window);
let surface = Surface {
raw,
};
//TODO: remove these workarounds when porting on gfx-hal 0.2
#[cfg(any(
feature = "gfx-backend-vulkan",
feature = "gfx-backend-dx11",
feature = "gfx-backend-dx12",
feature = "gfx-backend-metal"
))]
{
let raw = HUB.instances
.read()
.get(instance_id)
.create_surface(window);
let surface = Surface {
raw,
};
HUB.surfaces
.write()
.register(surface)
HUB.surfaces
.write()
.register(surface)
}
#[cfg(not(any(
feature = "gfx-backend-vulkan",
feature = "gfx-backend-dx11",
feature = "gfx-backend-dx12",
feature = "gfx-backend-metal"
)))]
unimplemented!()
}
#[allow(unused)]

View File

@ -7,6 +7,8 @@ use crate::{
use bitflags::bitflags;
pub type ShaderAttributeIndex = u32;
#[repr(C)]
#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
pub enum BlendFactor {
@ -163,28 +165,24 @@ pub enum InputStepMode {
#[repr(C)]
pub struct VertexAttributeDescriptor {
pub shader_location: u32,
pub input_slot: u32,
pub offset: u32,
pub format: VertexFormat,
pub attribute_index: ShaderAttributeIndex,
}
#[repr(C)]
pub struct VertexInputDescriptor {
pub input_slot: u32,
pub struct VertexBufferDescriptor {
pub stride: u32,
pub step_mode: InputStepMode,
pub attributes: *const VertexAttributeDescriptor,
pub attributes_count: usize,
}
#[repr(C)]
pub struct InputStateDescriptor<'a> {
pub struct VertexBufferStateDescriptor {
pub index_format: IndexFormat,
pub attributes: &'a [VertexAttributeDescriptor],
pub inputs: &'a [VertexInputDescriptor],
}
pub struct InputState {
// TODO
pub vertex_buffers: *const VertexBufferDescriptor,
pub vertex_buffers_count: usize,
}
#[repr(C)]
@ -251,6 +249,7 @@ pub struct RenderPipelineDescriptor {
pub blend_states: *const BlendStateId,
pub blend_states_length: usize,
pub depth_stencil_state: DepthStencilStateId,
pub vertex_buffer_state: VertexBufferStateDescriptor,
}
pub(crate) struct RenderPipeline<B: hal::Backend> {

View File

@ -188,7 +188,7 @@ pub struct SamplerDescriptor {
pub t_address_mode: AddressMode,
pub mag_filter: FilterMode,
pub min_filter: FilterMode,
pub mipmap_filer: FilterMode,
pub mipmap_filter: FilterMode,
pub lod_min_clamp: f32,
pub lod_max_clamp: f32,
pub max_anisotropy: u32,

View File

@ -154,13 +154,11 @@ pub extern "C" fn wgpu_swap_chain_present(
};
device.raw.reset_fence(&frame.fence).unwrap();
device.queue_group.queues[0]
.submit(submission, Some(&frame.fence));
swap_chain.raw
let queue = &mut device.queue_group.queues[0];
queue.submit(submission, Some(&frame.fence));
queue
.present(
&mut device.queue_group.queues[0],
image_index,
iter::once((&swap_chain.raw, image_index)),
iter::once(&frame.sem_present),
)
.unwrap();

View File

@ -4,16 +4,20 @@ extern crate wgpu_native as wgn;
use arrayvec::ArrayVec;
use std::ffi::CString;
use std::marker::PhantomData;
use std::ops::Range;
use std::ptr;
pub use wgn::{
AdapterDescriptor, Attachment, BindGroupLayoutBinding, BindingType, BlendStateDescriptor,
BufferDescriptor, Color, ColorWriteFlags, CommandBufferDescriptor, DepthStencilStateDescriptor,
BufferDescriptor, BufferUsageFlags,
IndexFormat, VertexFormat, InputStepMode, ShaderAttributeIndex, VertexAttributeDescriptor,
Color, ColorWriteFlags, CommandBufferDescriptor, DepthStencilStateDescriptor,
DeviceDescriptor, Extensions, Extent3d, LoadOp, Origin3d, PowerPreference, PrimitiveTopology,
RenderPassColorAttachmentDescriptor, RenderPassDepthStencilAttachmentDescriptor,
ShaderModuleDescriptor, ShaderStage, ShaderStageFlags, StoreOp, SwapChainDescriptor,
TextureDescriptor, TextureDimension, TextureFormat, TextureUsageFlags, TextureViewDescriptor,
SamplerDescriptor, AddressMode, FilterMode, CompareFunction, BorderColor,
};
pub struct Instance {
@ -112,8 +116,9 @@ pub struct ComputePass<'a> {
parent: &'a mut CommandBuffer,
}
pub struct Queue {
pub struct Queue<'a> {
id: wgn::QueueId,
_marker: PhantomData<&'a Self>,
}
pub struct BindGroupLayoutDescriptor<'a> {
@ -140,6 +145,12 @@ pub struct AttachmentsState<'a> {
pub depth_stencil_attachment: Option<Attachment>,
}
pub struct VertexBufferDescriptor<'a> {
pub stride: u32,
pub step_mode: InputStepMode,
pub attributes: &'a [VertexAttributeDescriptor],
}
pub struct RenderPipelineDescriptor<'a> {
pub layout: &'a PipelineLayout,
pub stages: &'a [PipelineStageDescriptor<'a>],
@ -147,6 +158,8 @@ pub struct RenderPipelineDescriptor<'a> {
pub attachments_state: AttachmentsState<'a>,
pub blend_states: &'a [&'a BlendState],
pub depth_stencil_state: &'a DepthStencilState,
pub index_format: IndexFormat,
pub vertex_buffers: &'a [VertexBufferDescriptor<'a>],
}
pub struct RenderPassDescriptor<'a> {
@ -155,6 +168,49 @@ pub struct RenderPassDescriptor<'a> {
Option<RenderPassDepthStencilAttachmentDescriptor<&'a TextureView>>,
}
pub struct SwapChainOutput<'a> {
pub texture: Texture,
pub view: TextureView,
swap_chain_id: &'a wgn::SwapChainId,
}
pub struct BufferCopyView<'a> {
pub buffer: &'a Buffer,
pub offset: u32,
pub row_pitch: u32,
pub image_height: u32,
}
impl<'a> BufferCopyView<'a> {
fn into_native(self) -> wgn::BufferCopyView {
wgn::BufferCopyView {
buffer: self.buffer.id,
offset: self.offset,
row_pitch: self.row_pitch,
image_height: self.image_height,
}
}
}
pub struct TextureCopyView<'a> {
pub texture: &'a Texture,
pub level: u32,
pub slice: u32,
pub origin: Origin3d,
}
impl<'a> TextureCopyView<'a> {
fn into_native(self) -> wgn::TextureCopyView {
wgn::TextureCopyView {
texture: self.texture.id,
level: self.level,
slice: self.slice,
origin: self.origin,
}
}
}
impl Instance {
pub fn new() -> Self {
Instance {
@ -197,10 +253,10 @@ impl Device {
}
}
//TODO: borrow instead of new object?
pub fn get_queue(&self) -> Queue {
pub fn get_queue(&mut self) -> Queue {
Queue {
id: wgn::wgpu_device_get_queue(self.id),
_marker: PhantomData,
}
}
@ -306,6 +362,15 @@ impl Device {
.collect::<ArrayVec<[_; 2]>>();
let temp_blend_states = desc.blend_states.iter().map(|bs| bs.id).collect::<Vec<_>>();
let temp_vertex_buffers = desc.vertex_buffers
.iter()
.map(|vbuf| wgn::VertexBufferDescriptor {
stride: vbuf.stride,
step_mode: vbuf.step_mode,
attributes: vbuf.attributes.as_ptr(),
attributes_count: vbuf.attributes.len(),
})
.collect::<Vec<_>>();
RenderPipeline {
id: wgn::wgpu_device_create_render_pipeline(
@ -328,6 +393,11 @@ impl Device {
blend_states: temp_blend_states.as_ptr(),
blend_states_length: temp_blend_states.len(),
depth_stencil_state: desc.depth_stencil_state.id,
vertex_buffer_state: wgn::VertexBufferStateDescriptor {
index_format: desc.index_format,
vertex_buffers: temp_vertex_buffers.as_ptr(),
vertex_buffers_count: temp_vertex_buffers.len(),
},
},
),
}
@ -345,6 +415,12 @@ impl Device {
}
}
pub fn create_sampler(&self, desc: &SamplerDescriptor) -> Sampler {
Sampler {
id: wgn::wgpu_device_create_sampler(self.id, desc),
}
}
pub fn create_swap_chain(&self, surface: &Surface, desc: &SwapChainDescriptor) -> SwapChain {
SwapChain {
id: wgn::wgpu_device_create_swap_chain(self.id, surface.id, desc),
@ -419,6 +495,20 @@ impl CommandBuffer {
parent: self,
}
}
pub fn copy_buffer_to_texture(
&mut self,
source: BufferCopyView,
destination: TextureCopyView,
copy_size: Extent3d,
) {
wgn::wgpu_command_buffer_copy_buffer_to_texture(
self.id,
&source.into_native(),
&destination.into_native(),
copy_size,
);
}
}
impl<'a> RenderPass<'a> {
@ -435,6 +525,25 @@ impl<'a> RenderPass<'a> {
wgn::wgpu_render_pass_set_pipeline(self.id, pipeline.id);
}
pub fn set_index_buffer(&mut self, buffer: &Buffer, offset: u32) {
wgn::wgpu_render_pass_set_index_buffer(self.id, buffer.id, offset);
}
pub fn set_vertex_buffers(&mut self, buffer_pairs: &[(&Buffer, u32)]) {
let mut buffers = Vec::new();
let mut offsets = Vec::new();
for &(buffer, offset) in buffer_pairs {
buffers.push(buffer.id);
offsets.push(offset);
}
wgn::wgpu_render_pass_set_vertex_buffers(
self.id,
buffers.as_ptr(),
offsets.as_ptr(),
buffer_pairs.len(),
);
}
pub fn draw(&mut self, vertices: Range<u32>, instances: Range<u32>) {
wgn::wgpu_render_pass_draw(
self.id,
@ -476,8 +585,8 @@ impl<'a> ComputePass<'a> {
}
}
impl Queue {
pub fn submit(&self, command_buffers: &[CommandBuffer]) {
impl<'a> Queue<'a> {
pub fn submit(&mut self, command_buffers: &[CommandBuffer]) {
wgn::wgpu_queue_submit(
self.id,
command_buffers.as_ptr() as *const _,
@ -486,19 +595,19 @@ impl Queue {
}
}
impl SwapChain {
//TODO: borrow instead of new object?
pub fn get_next_texture(&self) -> (Texture, TextureView) {
let output = wgn::wgpu_swap_chain_get_next_texture(self.id);
(
Texture {
id: output.texture_id,
},
TextureView { id: output.view_id },
)
}
pub fn present(&self) {
wgn::wgpu_swap_chain_present(self.id);
impl<'a> Drop for SwapChainOutput<'a> {
fn drop(&mut self) {
wgn::wgpu_swap_chain_present(*self.swap_chain_id);
}
}
impl SwapChain {
pub fn get_next_texture(&mut self) -> SwapChainOutput {
let output = wgn::wgpu_swap_chain_get_next_texture(self.id);
SwapChainOutput {
texture: Texture { id: output.texture_id },
view: TextureView { id: output.view_id },
swap_chain_id: &self.id,
}
}
}