diff --git a/.vscode/launch.json b/.vscode/launch.json index ad4c87ee..860b867e 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -5,23 +5,41 @@ "version": "0.2.0", "configurations": [ { - "name": "(Windows) Launch", - "type": "cppvsdbg", - "request": "launch", - "program": "${workspaceFolder}/target/debug/graphite.exe", - "args": [], - "stopAtEntry": false, - "cwd": "${workspaceFolder}", - "environment": [], - "externalConsole": false - }, - { - "name": "(LLDB) Launch", "type": "lldb", "request": "launch", - "program": "${workspaceFolder}/target/debug/graphite.exe", + "name": "Debug executable 'graphite'", + "cargo": { + "args": [ + "build", + "--bin=graphite", + "--package=graphite" + ], + "filter": { + "name": "graphite", + "kind": "bin" + } + }, "args": [], - "cwd": "${workspaceFolder}", + "cwd": "${workspaceFolder}" + }, + { + "type": "lldb", + "request": "launch", + "name": "Debug unit tests in executable 'graphite'", + "cargo": { + "args": [ + "test", + "--no-run", + "--bin=graphite", + "--package=graphite" + ], + "filter": { + "name": "graphite", + "kind": "bin" + } + }, + "args": [], + "cwd": "${workspaceFolder}" } ] } \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock index d884c927..57dafdd8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -49,11 +49,11 @@ checksum = "cff77d8686867eceff3105329d4698d96c2391c176d5d03adc90c7389162b5b8" [[package]] name = "ash" -version = "0.29.0" +version = "0.30.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "003d1fb2eb12eb06d4a03dbe02eea67a9fac910fa97932ab9e3a75b96a1ea5e5" +checksum = "69daec0742947f33a85931fa3cb0ce5f07929159dcbd1f0cbb5b2912e2978509" dependencies = [ - "shared_library", + "libloading", ] [[package]] @@ -130,6 +130,12 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "560c32574a12a89ecd91f5e742165893f86e3ab98d21f8ea548658eb9eef5f40" +[[package]] +name = "bytemuck" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37fa13df2292ecb479ec23aa06f4507928bef07839be9ef15281411076629431" + [[package]] name = "byteorder" version = "1.3.4" @@ -224,12 +230,6 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0dbbb57365263e881e805dc77d94697c9118fd94d8da011240555aa7b23445bd" -[[package]] -name = "colorful" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bca1619ff57dd7a56b58a8e25ef4199f123e78e503fe1653410350a1b98ae65" - [[package]] name = "copyless" version = "0.1.4" @@ -437,7 +437,7 @@ dependencies = [ "proc-macro2 1.0.10", "quote 1.0.3", "syn 1.0.18", - "synstructure 0.12.3", + "synstructure", ] [[package]] @@ -483,6 +483,97 @@ version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" +[[package]] +name = "futures" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c329ae8753502fb44ae4fc2b622fa2a94652c41e795143765ba0927f92ab780" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0c77d04ce8edd9cb903932b608268b3fffec4163dc053b3b402bf47eac1f1a8" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f25592f769825e89b92358db00d26f965761e094951ac44d3663ef25b7ac464a" + +[[package]] +name = "futures-executor" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f674f3e1bcb15b37284a90cedf55afdba482ab061c407a9c0ebbd0f3109741ba" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a638959aa96152c7a4cddf50fcb1e3fede0583b27157c26e67d6f99904090dc6" + +[[package]] +name = "futures-macro" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a5081aa3de1f7542a794a397cde100ed903b0630152d0973479018fd85423a7" +dependencies = [ + "proc-macro-hack", + "proc-macro2 1.0.10", + "quote 1.0.3", + "syn 1.0.18", +] + +[[package]] +name = "futures-sink" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3466821b4bc114d95b087b850a724c6f83115e929bc88f1fa98a3304a944c8a6" + +[[package]] +name = "futures-task" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b0a34e53cf6cdcd0178aa573aed466b646eb3db769570841fda0c7ede375a27" + +[[package]] +name = "futures-util" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22766cf25d64306bedf0384da004d05c9974ab104fcc4528f1236181c18004c5" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-utils", + "proc-macro-hack", + "proc-macro-nested", + "slab", +] + [[package]] name = "fxhash" version = "0.2.1" @@ -514,9 +605,9 @@ dependencies = [ [[package]] name = "gfx-auxil" -version = "0.1.0" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "572eee952a9a23c99cfe3e4fd95d277784058a89ac3c77ff6fa3d80a4e321919" +checksum = "3b46e6f0031330a0be08d17820f2dcaaa91cb36710a97a9500cb4f1c36e785c8" dependencies = [ "fxhash", "gfx-hal", @@ -525,19 +616,19 @@ dependencies = [ [[package]] name = "gfx-backend-dx11" -version = "0.4.6" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7527cfcd7d1eec6b99f81891293bdd2a41d044ace009717264e5f3b10ce5b86" +checksum = "b148219292624126f78245e50a9720d95ea149a415ce8ce73ab7014205301b88" dependencies = [ "bitflags", "gfx-auxil", "gfx-hal", "libloading", "log", - "parking_lot 0.10.2", + "parking_lot", "range-alloc", "raw-window-handle", - "smallvec 0.6.13", + "smallvec", "spirv_cross", "winapi 0.3.8", "wio", @@ -545,9 +636,9 @@ dependencies = [ [[package]] name = "gfx-backend-dx12" -version = "0.4.3" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "305620be6365b7dd8ef8e2bf320174f7aad4a23efb34136ee5b4d4d28bbe1714" +checksum = "a0e526746379e974501551b08958947e67a81b5ea8cdc717a000cdd72577da05" dependencies = [ "bitflags", "d3d12", @@ -556,16 +647,16 @@ dependencies = [ "log", "range-alloc", "raw-window-handle", - "smallvec 0.6.13", + "smallvec", "spirv_cross", "winapi 0.3.8", ] [[package]] name = "gfx-backend-empty" -version = "0.4.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d383e6bc48867cb37d298a20139fd1eec298f8f6d594690cd1c50ef25470cc7" +checksum = "b67bd2d7bc022b257ddbdabc5fa3b10c29c292372c3409f2b6a6e3f4e11cdb85" dependencies = [ "gfx-hal", "raw-window-handle", @@ -573,9 +664,9 @@ dependencies = [ [[package]] name = "gfx-backend-metal" -version = "0.4.5" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05b6130b9a72129ebb5c91d3d75a142a7fa54dcc112603231582e3fdc0b84247" +checksum = "cfe128c29675b5afc8acdda1dfe096d6abd5e3528059ab0b98bda8215d8beed9" dependencies = [ "arrayvec", "bitflags", @@ -590,19 +681,19 @@ dependencies = [ "log", "metal", "objc", - "parking_lot 0.10.2", + "parking_lot", "range-alloc", "raw-window-handle", - "smallvec 0.6.13", + "smallvec", "spirv_cross", "storage-map", ] [[package]] name = "gfx-backend-vulkan" -version = "0.4.3" +version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1b8d901941d1734d307dacd8e5f00c89ee8fb8e78b4dab3edd91248150b26b4" +checksum = "45ff36feae801fa23d29acd74082603a0145a697a23595757dd4e78828ab33da" dependencies = [ "arrayvec", "ash", @@ -613,20 +704,43 @@ dependencies = [ "log", "objc", "raw-window-handle", - "smallvec 0.6.13", + "smallvec", "winapi 0.3.8", "x11", ] [[package]] -name = "gfx-hal" -version = "0.4.1" +name = "gfx-descriptor" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c88981665c780447bb08eb099e1ded330754a7246719bab927ee4a949c0ba7f" +checksum = "1bf35f5d66d1bc56e63e68d7528441453f25992bd954b84309d23c659df2c5da" +dependencies = [ + "fxhash", + "gfx-hal", + "log", +] + +[[package]] +name = "gfx-hal" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc96180204064c9493e0fe4a9efeb721e0ac59fe8e1906d0c659142a93114fb1" dependencies = [ "bitflags", "raw-window-handle", - "smallvec 0.6.13", +] + +[[package]] +name = "gfx-memory" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2eed6cda674d9cd4d92229102dbd544292124533d236904f987e9afab456137" +dependencies = [ + "fxhash", + "gfx-hal", + "hibitset", + "log", + "slab", ] [[package]] @@ -654,8 +768,10 @@ dependencies = [ name = "graphite" version = "0.1.0" dependencies = [ + "bytemuck", "cgmath", "failure", + "futures", "glsl-to-spirv", "image", "palette", @@ -665,9 +781,9 @@ dependencies = [ [[package]] name = "hermit-abi" -version = "0.1.11" +version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a0d737e0f947a1864e93d33fdef4af8445a00d1ed8dc0c8ddb73139ea6abf15" +checksum = "61565ff7aaace3525556587bd2dc31d4a07071957be715e63ce7b1eccf51a8f4" dependencies = [ "libc", ] @@ -724,9 +840,9 @@ dependencies = [ [[package]] name = "jpeg-decoder" -version = "0.1.18" +version = "0.1.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0256f0aec7352539102a9efbcb75543227b7ab1117e0f95450023af730128451" +checksum = "5b47b4c4e017b01abdc5bcc126d2d1002e5a75bbe3ce73f9f4f311a916363704" dependencies = [ "byteorder", "rayon", @@ -827,6 +943,12 @@ version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00" +[[package]] +name = "memchr" +version = "2.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3728d817d99e5ac407411fa471ff9800a778d88a24685968b36824eaf4bee400" + [[package]] name = "memmap" version = "0.7.0" @@ -1042,17 +1164,6 @@ dependencies = [ "syn 1.0.18", ] -[[package]] -name = "parking_lot" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f842b1982eb6c2fe34036a4fbfb06dd185a3f5c8edfaacdf7d1ea10b07de6252" -dependencies = [ - "lock_api", - "parking_lot_core 0.6.2", - "rustc_version", -] - [[package]] name = "parking_lot" version = "0.10.2" @@ -1060,22 +1171,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3a704eb390aafdc107b0e392f56a82b668e3a71366993b5340f5833fd62505e" dependencies = [ "lock_api", - "parking_lot_core 0.7.2", -] - -[[package]] -name = "parking_lot_core" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b876b1b9e7ac6e1a74a6da34d25c42e17e8862aa409cbbbdcfc8d86c6f3bc62b" -dependencies = [ - "cfg-if", - "cloudabi", - "libc", - "redox_syscall", - "rustc_version", - "smallvec 0.6.13", - "winapi 0.3.8", + "parking_lot_core", ] [[package]] @@ -1088,10 +1184,32 @@ dependencies = [ "cloudabi", "libc", "redox_syscall", - "smallvec 1.4.0", + "smallvec", "winapi 0.3.8", ] +[[package]] +name = "peek-poke" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d93fd6a575ebf1ac2668d08443c97a22872cfb463fd8b7ddd141e9f6be59af2f" +dependencies = [ + "peek-poke-derive", +] + +[[package]] +name = "peek-poke-derive" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fb44a25c5bba983be0fc8592dfaf3e6d0935ce8be0c6b15b2a39507af34a926" +dependencies = [ + "proc-macro2 1.0.10", + "quote 1.0.3", + "syn 1.0.18", + "synstructure", + "unicode-xid 0.2.0", +] + [[package]] name = "percent-encoding" version = "2.1.0" @@ -1136,6 +1254,12 @@ dependencies = [ "siphasher", ] +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + [[package]] name = "pkg-config" version = "0.3.17" @@ -1160,6 +1284,18 @@ version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "74490b50b9fbe561ac330df47c08f3f33073d2d00c150f719147d7c54522fa1b" +[[package]] +name = "proc-macro-hack" +version = "0.5.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d659fe7c6d27f25e9d80a1a094c223f5246f6a6596453e09d7229bf42750b63" + +[[package]] +name = "proc-macro-nested" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e946095f9d3ed29ec38de908c22f95d9ac008e424c7bcae54c75a79c527c694" + [[package]] name = "proc-macro2" version = "0.4.30" @@ -1407,16 +1543,6 @@ version = "0.1.56" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84" -[[package]] -name = "relevant" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbc232e13d37f4547f5b9b42a5efc380cabe5dbc1807f8b893580640b2ab0308" -dependencies = [ - "cfg-if", - "log", -] - [[package]] name = "remove_dir_all" version = "0.5.2" @@ -1426,48 +1552,12 @@ dependencies = [ "winapi 0.3.8", ] -[[package]] -name = "rendy-descriptor" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f475bcc0505946e998590f1f0545c52ef4b559174a1b353a7ce6638def8b621e" -dependencies = [ - "gfx-hal", - "log", - "relevant", - "smallvec 0.6.13", -] - -[[package]] -name = "rendy-memory" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed492161a819feae7f27f418bb16035276ac20649c60d756699152cb5c1960ec" -dependencies = [ - "colorful", - "gfx-hal", - "hibitset", - "log", - "relevant", - "slab", - "smallvec 0.6.13", -] - [[package]] name = "rustc-demangle" version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4c691c0e608126e00913e33f0ccf3727d5fc84573623b8d65b2df340b5201783" -[[package]] -name = "rustc_version" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" -dependencies = [ - "semver", -] - [[package]] name = "rusttype" version = "0.7.9" @@ -1509,21 +1599,6 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" -[[package]] -name = "semver" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" -dependencies = [ - "semver-parser", -] - -[[package]] -name = "semver-parser" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" - [[package]] name = "sha2" version = "0.7.1" @@ -1536,16 +1611,6 @@ dependencies = [ "fake-simd", ] -[[package]] -name = "shared_library" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a9e7e0f2bfae24d8a5b5a66c5b257a83c7412304311512a0c054cd5e619da11" -dependencies = [ - "lazy_static", - "libc", -] - [[package]] name = "siphasher" version = "0.3.3" @@ -1558,15 +1623,6 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8" -[[package]] -name = "smallvec" -version = "0.6.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7b0758c52e15a8b5e3691eae6cc559f08eee9406e548a4477ba4e67770a82b6" -dependencies = [ - "maybe-uninit", -] - [[package]] name = "smallvec" version = "1.4.0" @@ -1591,9 +1647,9 @@ dependencies = [ [[package]] name = "spirv_cross" -version = "0.16.0" +version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbbe441b3ac8ec0ae6a4f05234239bd372a241ce15793eef694e8b24afc267bb" +checksum = "946216f8793f7199e3ea5b995ee8dc20a0ace1fcf46293a0ef4c17e1d046dbde" dependencies = [ "cc", "js-sys", @@ -1640,18 +1696,6 @@ dependencies = [ "unicode-xid 0.2.0", ] -[[package]] -name = "synstructure" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02353edf96d6e4dc81aea2d8490a7e9db177bf8acb0e951c24940bf866cb313f" -dependencies = [ - "proc-macro2 0.4.30", - "quote 0.6.13", - "syn 0.15.44", - "unicode-xid 0.1.0", -] - [[package]] name = "synstructure" version = "0.12.3" @@ -1853,21 +1897,24 @@ dependencies = [ [[package]] name = "wgpu" -version = "0.4.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07e9c1ff587eddd68cdf2a78889c7a2128683161c72c67b94457cf498accaf7b" +checksum = "dbf715eb8571da470b856ecc67b057221360d9fce16f3e38001b2fb158d04012" dependencies = [ "arrayvec", + "parking_lot", "raw-window-handle", + "smallvec", + "wgpu-core", "wgpu-native", - "zerocopy", + "wgpu-types", ] [[package]] -name = "wgpu-native" -version = "0.4.3" +name = "wgpu-core" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26642308af1cc9a28a24c7fc5e5408d9689c8a0c01d7117aa83d5a1ed6e83438" +checksum = "50212a35d2c20de1c421d9a0d831f494a85f9afab240e19aae499cff9d0526f2" dependencies = [ "arrayvec", "bitflags", @@ -1878,15 +1925,41 @@ dependencies = [ "gfx-backend-empty", "gfx-backend-metal", "gfx-backend-vulkan", + "gfx-descriptor", "gfx-hal", - "lazy_static", + "gfx-memory", "log", - "parking_lot 0.9.0", - "raw-window-handle", - "rendy-descriptor", - "rendy-memory", - "smallvec 0.6.13", + "parking_lot", + "peek-poke", + "smallvec", "vec_map", + "wgpu-types", +] + +[[package]] +name = "wgpu-native" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19a5051a357d071fd69c24671e0ea6d644a83c7418e47eac3511427379007403" +dependencies = [ + "arrayvec", + "lazy_static", + "libc", + "objc", + "parking_lot", + "raw-window-handle", + "wgpu-core", + "wgpu-types", +] + +[[package]] +name = "wgpu-types" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67b69dfe001a8a6b78810c7e479717cd1898b9177dbf646611fa1f258f5a2512" +dependencies = [ + "bitflags", + "peek-poke", ] [[package]] @@ -1952,7 +2025,7 @@ dependencies = [ "mio", "mio-extras", "objc", - "parking_lot 0.10.2", + "parking_lot", "percent-encoding", "raw-window-handle", "smithay-client-toolkit", @@ -2010,27 +2083,6 @@ checksum = "d089681aa106a86fade1b0128fb5daf07d5867a509ab036d99988dec80429a57" [[package]] name = "xml-rs" -version = "0.8.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bb76e5c421bbbeb8924c60c030331b345555024d56261dae8f3e786ed817c23" - -[[package]] -name = "zerocopy" -version = "0.2.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "992b9b31f80fd4a167f903f879b8ca43d6716cc368ea01df90538baa2dd34056" -dependencies = [ - "byteorder", - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b090467ecd0624026e8a6405d343ac7382592530d54881330b3fc8e400280fa5" -dependencies = [ - "proc-macro2 0.4.30", - "syn 0.15.44", - "synstructure 0.10.2", -] +checksum = "b07db065a5cf61a7e4ba64f29e67db906fb1787316516c4e6e5ff0fea1efcd8a" diff --git a/Cargo.toml b/Cargo.toml index 42a9df04..80994677 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,8 +9,10 @@ edition = "2018" [dependencies] image = "0.22" winit = "0.20" -wgpu = "0.4" +wgpu = "0.5" glsl-to-spirv = "0.1" failure = "0.1.7" cgmath = "0.17" -palette = "0.5" \ No newline at end of file +palette = "0.5" +futures = "0.3.4" +bytemuck = "1.2.0" \ No newline at end of file diff --git a/shaders/shader.frag b/shaders/shader.frag index 2327b894..d3ecc1b1 100644 --- a/shaders/shader.frag +++ b/shaders/shader.frag @@ -7,5 +7,6 @@ layout(location=0) out vec4 f_color; layout(set = 0, binding = 0) uniform sampler2D t_texture; void main() { - f_color = texture(t_texture, v_uv / textureSize(t_texture, 0) * 100); + // f_color = texture(t_texture, v_uv / textureSize(t_texture, 0) * 100); + f_color = vec4(0.0, 1.0, 0.0, 1.0); } \ No newline at end of file diff --git a/src/application.rs b/src/application.rs index ad164e3c..37da95cf 100644 --- a/src/application.rs +++ b/src/application.rs @@ -1,17 +1,17 @@ // use super::render_state::RenderState; -// use super::program_state::ProgramState; use super::color_palette::ColorPalette; use super::gui_rect::GUIRect; use super::pipeline::Pipeline; -use super::pipeline::PipelineDetails; -use super::shader_cache::ShaderCache; use super::texture::Texture; - +use super::shader_cache::ShaderCache; +use super::pipeline_cache::PipelineCache; +use super::draw_command::DrawCommand; use std::collections::VecDeque; use winit::event::*; use winit::event_loop::ControlFlow; use winit::event_loop::EventLoop; use winit::window::Window; +use futures::executor::block_on; pub struct Application { pub surface: wgpu::Surface, @@ -21,9 +21,10 @@ pub struct Application { pub swap_chain_descriptor: wgpu::SwapChainDescriptor, pub swap_chain: wgpu::SwapChain, pub shader_cache: ShaderCache, + pub pipeline_cache: PipelineCache, // pub texture_cache: TextureCache, pub gui_rect_queue: VecDeque, - pub pipeline_queue: VecDeque, + pub draw_command_queue: VecDeque, pub temp_color_toggle: bool, } @@ -33,13 +34,19 @@ impl Application { let surface = wgpu::Surface::create(window); // Represents a GPU, exposes the real GPU device and queue - let adapter = wgpu::Adapter::request(&wgpu::RequestAdapterOptions { ..Default::default() }).unwrap(); + let adapter = block_on(wgpu::Adapter::request( + &wgpu::RequestAdapterOptions { + power_preference: wgpu::PowerPreference::Default, + compatible_surface: Some(&surface), + }, + wgpu::BackendBit::PRIMARY, + )).unwrap(); // Requests the device and queue from the adapter - let requested_device = adapter.request_device(&wgpu::DeviceDescriptor { + let requested_device = block_on(adapter.request_device(&wgpu::DeviceDescriptor { extensions: wgpu::Extensions { anisotropic_filtering: false }, limits: Default::default(), - }); + })); // Connection to the physical GPU let device = requested_device.0; @@ -53,18 +60,19 @@ impl Application { format: wgpu::TextureFormat::Bgra8UnormSrgb, width: window.inner_size().width, height: window.inner_size().height, - present_mode: wgpu::PresentMode::Vsync, + present_mode: wgpu::PresentMode::Fifo, }; // Series of frame buffers with images presented to the surface let swap_chain = device.create_swap_chain(&surface, &swap_chain_descriptor); - // Cache of all loaded shaders + // Cache of all loaded shaders and the Pipeline programs they form let shader_cache = ShaderCache::new(); + let pipeline_cache = PipelineCache::new(); let gui_rect_queue = VecDeque::new(); - let pipeline_queue = VecDeque::new(); + let draw_command_queue = VecDeque::new(); Self { surface, @@ -74,28 +82,59 @@ impl Application { swap_chain_descriptor, swap_chain, shader_cache, + pipeline_cache, gui_rect_queue, - pipeline_queue, + draw_command_queue, temp_color_toggle: true, } } pub fn example(&mut self) { + // Example vertex data + const VERTICES: &[[f32; 2]] = &[ + [-0.0868241, -0.49240386], + [-0.49513406, -0.06958647], + [-0.21918549, 0.44939706], + [0.35966998, 0.3473291], + [0.44147372, -0.2347359], + ]; + const INDICES: &[u16] = &[ + 0, 1, 4, + 1, 2, 4, + 2, 3, 4, + ]; + + // Load the vertex and fragment shaders self.shader_cache.load(&self.device, "shaders/shader.vert", glsl_to_spirv::ShaderType::Vertex).unwrap(); self.shader_cache.load(&self.device, "shaders/shader.frag", glsl_to_spirv::ShaderType::Fragment).unwrap(); - let vertex_shader = self.shader_cache.get_by_path("shaders/shader.vert").unwrap(); let fragment_shader = self.shader_cache.get_by_path("shaders/shader.frag").unwrap(); - let texture_view = Texture::from_filepath(&self.device, &mut self.queue, "textures/grid.png").unwrap().view; - - let example_pipeline = Pipeline::new(&self.device, PipelineDetails { - vertex_shader, - fragment_shader, - texture_view: Some(&texture_view), + // Construct a pipeline from the shader pair and a new BindGroup that holds a new TextureView, then store the pipeline in the cache + let example_pipeline = Pipeline::new(&self.device, vertex_shader, fragment_shader); + let example_texture_view = Texture::from_filepath(&self.device, &mut self.queue, "textures/grid.png").unwrap().texture_view; + let bind_group = self.device.create_bind_group(&wgpu::BindGroupDescriptor { + layout: &example_pipeline.bind_group_layout, + bindings: &[ + wgpu::Binding { + binding: 0, + resource: wgpu::BindingResource::TextureView(&example_texture_view), + }, + // wgpu::Binding { + // binding: 1, + // resource: wgpu::BindingResource::Sampler(&texture.sampler), + // } + ], + label: None, }); + let pipeline_id = self.pipeline_cache.set("example", example_pipeline); - self.pipeline_queue.push_back(example_pipeline); + assert_eq!(pipeline_id, super::pipeline_cache::PipelineID::new(0)); + + // Create a draw command with the vertex data and bind group + let example_draw_command = DrawCommand::new(&self.device, pipeline_id, VERTICES, INDICES, bind_group); + + self.draw_command_queue.push_back(example_draw_command); } pub fn begin_lifecycle(mut self, event_loop: EventLoop<()>, window: Window) { @@ -103,31 +142,30 @@ impl Application { } pub fn main_event_loop(&mut self, event: Event<'_, T>, control_flow: &mut ControlFlow, window: &Window) { + // Wait for the next event to cause a subsequent event loop run, instead of looping instantly as a game would need + *control_flow = ControlFlow::Wait; + match event { - // Handle all window events in sequence + // Handle all window events (like input and resize) in sequence Event::WindowEvent { ref event, window_id } if window_id == window.id() => { self.window_event(event, control_flow); }, - // After handling every event and updating the GUI, request a new sequence of draw commands + // Once every event is handled and the GUI structure is updated, this requests a new sequence of draw commands Event::MainEventsCleared => { // Turn the GUI changes into draw commands added to the render pipeline queue self.redraw(); - // If any draw commands were actually added, ask the window to issue a redraw event - if !self.pipeline_queue.is_empty() { + // If any draw commands were actually added, ask the window to dispatch a redraw event + if !self.draw_command_queue.is_empty() { window.request_redraw(); } - - *control_flow = ControlFlow::Wait; }, - // Resizing or calling `window.request_redraw()` now redraws the GUI with the pipeline queue + // Resizing or calling `window.request_redraw()` renders the GUI with the queued draw commands Event::RedrawRequested(_) => { self.render(); - *control_flow = ControlFlow::Wait; }, // Catch extraneous events _ => { - *control_flow = ControlFlow::Wait; }, } } @@ -188,53 +226,72 @@ impl Application { // Render the queue of pipeline draw commands over the current window pub fn render(&mut self) { + // Get a frame buffer to render on + let frame = self.swap_chain.get_next_texture().unwrap(); + + // Generates a render pass that commands are applied to, then generates a command buffer when finished + let mut command_encoder = self.device.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None }); + + // Temporary way to swap clear color every render + let color = match self.temp_color_toggle { + true => ColorPalette::get_color_linear(ColorPalette::MildBlack), + false => ColorPalette::get_color_linear(ColorPalette::NearBlack), + }; + self.temp_color_toggle = !self.temp_color_toggle; + + // Recording of commands while in "rendering mode" that go into a command buffer + let mut render_pass = command_encoder.begin_render_pass(&wgpu::RenderPassDescriptor { + color_attachments: &[ + wgpu::RenderPassColorAttachmentDescriptor { + attachment: &frame.view, + resolve_target: None, + load_op: wgpu::LoadOp::Clear, + store_op: wgpu::StoreOp::Store, + clear_color: color, + } + ], + depth_stencil_attachment: None, + }); + + // let mut currently_set_pipeline_id = None; + + println!("Draw queue is length {}", self.draw_command_queue.len()); + // Turn the queue of pipelines each into a command buffer and submit it to the render queue - while !self.pipeline_queue.is_empty() { - // Get a frame buffer to render on - let frame = self.swap_chain.get_next_texture(); + self.draw_command_queue.iter().for_each(|command| { + // // Bind the pipeline required by the current draw command + // let new_pipeline_id = command.pipeline_id; + // if currently_set_pipeline_id == None || new_pipeline_id != currently_set_pipeline_id.unwrap() { + // currently_set_pipeline_id = Some(new_pipeline_id); + + // let pipeline = self.pipeline_cache.get_by_id(new_pipeline_id).unwrap(); + // render_pass.set_pipeline(&pipeline.render_pipeline); + // println!("Set pipeline"); + // } + + let pipeline = self.pipeline_cache.get_by_id(command.pipeline_id).unwrap(); + render_pass.set_pipeline(&pipeline.render_pipeline); - // Get the pipeline to render in this iteration - let pipeline_struct = self.pipeline_queue.pop_back().unwrap(); - - // Generates a render pass that commands are applied to, then generates a command buffer when finished - let mut command_encoder = self.device.create_command_encoder(&wgpu::CommandEncoderDescriptor { todo: 0 }); - - // Temporary way to swap clear color every render - let color = match self.temp_color_toggle { - true => ColorPalette::get_color_linear(ColorPalette::MildBlack), - false => ColorPalette::get_color_linear(ColorPalette::NearBlack), - }; - self.temp_color_toggle = !self.temp_color_toggle; - - // Recording of commands while in "rendering mode" that go into a command buffer - let mut render_pass = command_encoder.begin_render_pass(&wgpu::RenderPassDescriptor { - color_attachments: &[ - wgpu::RenderPassColorAttachmentDescriptor { - attachment: &frame.view, - resolve_target: None, - load_op: wgpu::LoadOp::Clear, - store_op: wgpu::StoreOp::Store, - clear_color: color, - } - ], - depth_stencil_attachment: None, - }); - // Commands sent to the GPU for drawing during this render pass - render_pass.set_pipeline(&pipeline_struct.render_pipeline); - render_pass.set_vertex_buffers(0, &[(&pipeline_struct.vertex_buffer, 0)]); - render_pass.set_index_buffer(&pipeline_struct.index_buffer, 0); - render_pass.set_bind_group(0, &pipeline_struct.texture_bind_group, &[]); - render_pass.draw_indexed(0..pipeline_struct.index_count, 0, 0..1); + render_pass.set_vertex_buffer(0, &command.vertex_buffer, 0, 0); + render_pass.set_index_buffer(&command.index_buffer, 0, 0); + render_pass.set_bind_group(0, &command.bind_group, &[]); - // Done sending render pass commands so we can give up mutation rights to command_encoder - drop(render_pass); + // Draw call + render_pass.draw_indexed(0..command.index_count, 0, 0..1); + println!("Draw call!"); + }); - // Turn the recording of commands into a complete command buffer - let command_buffer = command_encoder.finish(); - - // Submit the command buffer to the GPU command queue - self.queue.submit(&[command_buffer]); - } + // Done sending render pass commands so we can give up mutation rights to command_encoder + drop(render_pass); + + // Turn the recording of commands into a complete command buffer + let command_buffer = command_encoder.finish(); + + // After the draw command queue has been iterated through and used, empty it for use next frame + self.draw_command_queue.clear(); + + // Submit the command buffer to the GPU command queue + self.queue.submit(&[command_buffer]); } } diff --git a/src/draw_command.rs b/src/draw_command.rs new file mode 100644 index 00000000..6c2aef42 --- /dev/null +++ b/src/draw_command.rs @@ -0,0 +1,25 @@ +use super::pipeline_cache::PipelineID; + +pub struct DrawCommand { + pub pipeline_id: PipelineID, + pub bind_group: wgpu::BindGroup, + pub vertex_buffer: wgpu::Buffer, + pub index_buffer: wgpu::Buffer, + pub index_count: u32, +} + +impl DrawCommand { + pub fn new(device: &wgpu::Device, pipeline_id: PipelineID, vertices: &[[f32; 2]], indices: &[u16], bind_group: wgpu::BindGroup) -> Self { + let vertex_buffer = device.create_buffer_with_data(bytemuck::cast_slice(vertices), wgpu::BufferUsage::VERTEX); + let index_buffer = device.create_buffer_with_data(bytemuck::cast_slice(indices), wgpu::BufferUsage::INDEX); + let index_count = indices.len() as u32; + + Self { + pipeline_id, + bind_group, + vertex_buffer, + index_buffer, + index_count, + } + } +} \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 505cfd39..8e163d90 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,10 +1,11 @@ mod application; mod gui_rect; mod pipeline; -mod program_state; mod texture; mod color_palette; mod shader_cache; +mod pipeline_cache; +mod draw_command; use application::Application; use winit::event_loop::EventLoop; @@ -23,7 +24,6 @@ fn main() { // State managers for render pipeline and program logic // let app_render_state = RenderState::new(&mut app); - // let app_program_state = ProgramState::new(&mut app); // Begin the application lifecycle app.begin_lifecycle(event_loop, window); diff --git a/src/pipeline.rs b/src/pipeline.rs index 958901e3..d1e45888 100644 --- a/src/pipeline.rs +++ b/src/pipeline.rs @@ -1,75 +1,41 @@ -pub struct PipelineDetails<'a> { - pub vertex_shader: &'a wgpu::ShaderModule, - pub fragment_shader: &'a wgpu::ShaderModule, - pub texture_view: Option<&'a wgpu::TextureView>, -} - pub struct Pipeline { + pub bind_group_layout: wgpu::BindGroupLayout, pub render_pipeline: wgpu::RenderPipeline, - pub vertex_buffer: wgpu::Buffer, - pub index_buffer: wgpu::Buffer, - pub index_count: u32, - pub texture_bind_group: wgpu::BindGroup, } impl Pipeline { - pub fn new(device: &wgpu::Device, pipeline_details: PipelineDetails) -> Self { - let texture_bind_group_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor { + pub fn new(device: &wgpu::Device, vertex_shader: &wgpu::ShaderModule, fragment_shader: &wgpu::ShaderModule) -> Self { + let bind_group_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor { bindings: &[ - wgpu::BindGroupLayoutBinding { + wgpu::BindGroupLayoutEntry { binding: 0, visibility: wgpu::ShaderStage::FRAGMENT, ty: wgpu::BindingType::SampledTexture { - multisampled: false, dimension: wgpu::TextureViewDimension::D2, + component_type: wgpu::TextureComponentType::Float, + multisampled: false, }, }, - // wgpu::BindGroupLayoutBinding { + // wgpu::BindGroupLayoutEntry { // binding: 1, // visibility: wgpu::ShaderStage::FRAGMENT, // ty: wgpu::BindingType::Sampler, // }, ], - }); - - let texture_bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor { - layout: &texture_bind_group_layout, - bindings: &[ - wgpu::Binding { - binding: 0, - resource: wgpu::BindingResource::TextureView(pipeline_details.texture_view.unwrap()), - }, - // wgpu::Binding { - // binding: 1, - // resource: wgpu::BindingResource::Sampler(&texture.sampler), - // } - ], + label: None, }); let render_pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { - bind_group_layouts: &[&texture_bind_group_layout], + bind_group_layouts: &[&bind_group_layout], }); - - let vertex_buffer_descriptors = wgpu::VertexBufferDescriptor { - stride: std::mem::size_of::<[f32; 2]>() as wgpu::BufferAddress, - step_mode: wgpu::InputStepMode::Vertex, - attributes: &[ - wgpu::VertexAttributeDescriptor { - offset: 0, - shader_location: 0, - format: wgpu::VertexFormat::Float2, - }, - ], - }; - let render_pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor { layout: &render_pipeline_layout, vertex_stage: wgpu::ProgrammableStageDescriptor { - module: pipeline_details.vertex_shader, + module: vertex_shader, entry_point: "main", }, fragment_stage: Some(wgpu::ProgrammableStageDescriptor { - module: pipeline_details.fragment_shader, + module: fragment_shader, entry_point: "main", }), rasterization_state: Some(wgpu::RasterizationStateDescriptor { @@ -79,6 +45,7 @@ impl Pipeline { depth_bias_slope_scale: 0.0, depth_bias_clamp: 0.0, }), + primitive_topology: wgpu::PrimitiveTopology::TriangleList, color_states: &[ wgpu::ColorStateDescriptor { format: wgpu::TextureFormat::Bgra8UnormSrgb, @@ -87,39 +54,28 @@ impl Pipeline { write_mask: wgpu::ColorWrite::ALL, }, ], - primitive_topology: wgpu::PrimitiveTopology::TriangleList, depth_stencil_state: None, - index_format: wgpu::IndexFormat::Uint16, - vertex_buffers: &[vertex_buffer_descriptors], + vertex_state: wgpu::VertexStateDescriptor { + index_format: wgpu::IndexFormat::Uint16, + vertex_buffers: &[wgpu::VertexBufferDescriptor { + stride: std::mem::size_of::<[f32; 2]>() as wgpu::BufferAddress, + step_mode: wgpu::InputStepMode::Vertex, + attributes: &[wgpu::VertexAttributeDescriptor { + offset: 0, + shader_location: 0, + format: wgpu::VertexFormat::Float2, + }, + ], + }], + }, sample_count: 1, sample_mask: !0, alpha_to_coverage_enabled: false, }); - let vertex_buffer = device.create_buffer_mapped(VERTICES.len(), wgpu::BufferUsage::VERTEX).fill_from_slice(VERTICES); - let index_buffer = device.create_buffer_mapped(INDICES.len(), wgpu::BufferUsage::INDEX).fill_from_slice(INDICES); - let index_count = INDICES.len() as u32; - Self { + bind_group_layout, render_pipeline, - vertex_buffer, - index_buffer, - index_count, - texture_bind_group, } } } - -const VERTICES: &[[f32; 2]] = &[ - [-0.0868241, -0.49240386], - [-0.49513406, -0.06958647], - [-0.21918549, 0.44939706], - [0.35966998, 0.3473291], - [0.44147372, -0.2347359], -]; - -const INDICES: &[u16] = &[ - 0, 1, 4, - 1, 2, 4, - 2, 3, 4, -]; \ No newline at end of file diff --git a/src/pipeline_cache.rs b/src/pipeline_cache.rs new file mode 100644 index 00000000..350d0db2 --- /dev/null +++ b/src/pipeline_cache.rs @@ -0,0 +1,57 @@ +use std::collections::HashMap; +use super::pipeline::Pipeline; + +#[derive(Copy, Clone, PartialEq, Debug)] +pub struct PipelineID { + index: usize, +} + +impl PipelineID { + pub fn new(index: usize) -> Self { + Self { index } + } +} + +pub struct PipelineCache { + pub pipelines: Vec, + pub name_to_id: HashMap, +} + +impl PipelineCache { + pub fn new() -> Self { + let pipelines = Vec::new(); + let name_to_id = HashMap::new(); + + Self { + pipelines, + name_to_id, + } + } + + pub fn get_by_name(&self, name: &str) -> Option<&Pipeline> { + match self.name_to_id.get(name) { + Some(id) => self.pipelines.get(id.index), + None => None, + } + } + + pub fn get_by_id(&self, id: PipelineID) -> Option<&Pipeline> { + self.pipelines.get(id.index) + } + + pub fn set(&mut self, name: &str, pipeline: Pipeline) -> PipelineID { + match self.name_to_id.get(name) { + Some(id) => { + self.pipelines[id.index] = pipeline; + id.clone() + }, + None => { + let last_index = self.name_to_id.len(); + let id = PipelineID::new(last_index); + self.name_to_id.insert(String::from(name), id); + self.pipelines.push(pipeline); + id + } + } + } +} \ No newline at end of file diff --git a/src/program_state.rs b/src/program_state.rs deleted file mode 100644 index 380cf049..00000000 --- a/src/program_state.rs +++ /dev/null @@ -1,13 +0,0 @@ -use super::application::Application; - -pub struct ProgramState { - -} - -impl ProgramState { - pub fn new(application: &mut Application) -> ProgramState { - Self { - - } - } -} \ No newline at end of file diff --git a/src/shader_cache.rs b/src/shader_cache.rs index 77f4703a..510ff552 100644 --- a/src/shader_cache.rs +++ b/src/shader_cache.rs @@ -1,8 +1,14 @@ use std::collections::HashMap; -#[derive(Copy, Clone)] +#[derive(Copy, Clone, PartialEq, Debug)] pub struct ShaderID { - pub index: usize, + index: usize, +} + +impl ShaderID { + pub fn new(index: usize) -> Self { + Self { index } + } } pub struct ShaderCache { @@ -39,8 +45,8 @@ impl ShaderCache { let compiled = wgpu::read_spirv(spirv).unwrap(); let shader = device.create_shader_module(&compiled); - let length = self.path_to_id.len(); - self.path_to_id.insert(String::from(path), ShaderID { index: length }); + let last_index = self.path_to_id.len(); + self.path_to_id.insert(String::from(path), ShaderID { index: last_index }); self.shaders.push(shader); } diff --git a/src/texture.rs b/src/texture.rs index 08248766..e807f5ae 100644 --- a/src/texture.rs +++ b/src/texture.rs @@ -2,31 +2,43 @@ use image::GenericImageView; pub struct Texture { pub texture: wgpu::Texture, - pub view: wgpu::TextureView, + pub texture_view: wgpu::TextureView, pub sampler: wgpu::Sampler, } impl Texture { pub fn from_filepath(device: &wgpu::Device, queue: &mut wgpu::Queue, path: &str) -> Result { + // Read the raw bytes from the specified file let bytes = std::fs::read(path)?; + + // Construct and return a Texture from the bytes Texture::from_bytes(device, queue, &bytes[..]) } pub fn from_bytes(device: &wgpu::Device, queue: &mut wgpu::Queue, bytes: &[u8]) -> Result { - let img = image::load_from_memory(bytes)?; - Self::from_image(device, queue, &img) + // Create an image with the Image library + let image = image::load_from_memory(bytes)?; + + // Construct and return a Texture from the Image + Self::from_image(device, queue, &image) } - pub fn from_image(device: &wgpu::Device, queue: &mut wgpu::Queue, img: &image::DynamicImage) -> Result { - let rgba = img.as_rgba8().unwrap(); - let dimensions = img.dimensions(); + pub fn from_image(device: &wgpu::Device, queue: &mut wgpu::Queue, image: &image::DynamicImage) -> Result { + // Get data from image + let rgba = image.as_rgba8().unwrap(); + let dimensions = image.dimensions(); let size = wgpu::Extent3d { width: dimensions.0, height: dimensions.1, depth: 1, }; + // Create a buffer on the GPU and load it with the image pixel data + let buffer = device.create_buffer_with_data(&rgba, wgpu::BufferUsage::COPY_SRC); + + // Create an empty texture on the GPU of the correct size for the buffer let texture = device.create_texture(&wgpu::TextureDescriptor { + label: None, size, array_layer_count: 1, mip_level_count: 1, @@ -36,16 +48,14 @@ impl Texture { usage: wgpu::TextureUsage::SAMPLED | wgpu::TextureUsage::COPY_DST, }); - let buffer = device.create_buffer_mapped(rgba.len(), wgpu::BufferUsage::COPY_SRC).fill_from_slice(&rgba); - - let mut encoder = device.create_command_encoder(&Default::default()); - + // Use a command encoder to transfer the pixel data buffer into the texture + let mut encoder = device.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None }); encoder.copy_buffer_to_texture( wgpu::BufferCopyView { buffer: &buffer, offset: 0, - row_pitch: 4 * dimensions.0, - image_height: dimensions.1, + bytes_per_row: 4 * dimensions.0, + rows_per_image: dimensions.1, }, wgpu::TextureCopyView { texture: &texture, @@ -56,9 +66,14 @@ impl Texture { size, ); + // Finishing the encoding yields the resulting command buffer that is submitted to the GPU's command queue let command_buffer = encoder.finish(); + queue.submit(&[command_buffer]); + // Create the TextureView for this texture let view = texture.create_default_view(); + + // Create the Sampler for this texture let sampler = device.create_sampler(&wgpu::SamplerDescriptor { address_mode_u: wgpu::AddressMode::ClampToEdge, address_mode_v: wgpu::AddressMode::ClampToEdge, @@ -68,11 +83,9 @@ impl Texture { mipmap_filter: wgpu::FilterMode::Nearest, lod_min_clamp: -100.0, lod_max_clamp: 100.0, - compare_function: wgpu::CompareFunction::Always, + compare: wgpu::CompareFunction::Always, }); - - queue.submit(&[command_buffer]); - Ok(Self { texture, view, sampler }) + Ok(Self { texture, texture_view: view, sampler }) } } \ No newline at end of file