From f9f7a0002d0fc8e633da46a6e2880a372aec5652 Mon Sep 17 00:00:00 2001 From: Dzmitry Malyshau Date: Thu, 6 Sep 2018 08:28:05 -0400 Subject: [PATCH] Specialization with raw data --- Cargo.lock | 77 +++++++++++++++++--------- libportability-gfx/src/conv.rs | 40 -------------- libportability-gfx/src/impls.rs | 95 ++++++++++++++++++++++++--------- 3 files changed, 120 insertions(+), 92 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 335dd4a..878afb6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -48,7 +48,7 @@ name = "backtrace-sys" version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.23 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -69,7 +69,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "cc" -version = "1.0.23" +version = "1.0.24" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -230,7 +230,7 @@ dependencies = [ "atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "humantime 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "termcolor 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -248,7 +248,7 @@ name = "failure_derive" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 0.4.17 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)", "quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)", "syn 0.14.9 (registry+https://github.com/rust-lang/crates.io-index)", "synstructure 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -297,7 +297,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "gfx-backend-dx11" version = "0.1.0" -source = "git+https://github.com/gfx-rs/gfx#2b425d1708cec98da63dde1a1c8539156d577465" +source = "git+https://github.com/gfx-rs/gfx#ecf4f81c6b78f6aaea43febe674994e5a132b2b5" dependencies = [ "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "derivative 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -314,7 +314,7 @@ dependencies = [ [[package]] name = "gfx-backend-dx12" version = "0.1.0" -source = "git+https://github.com/gfx-rs/gfx#2b425d1708cec98da63dde1a1c8539156d577465" +source = "git+https://github.com/gfx-rs/gfx#ecf4f81c6b78f6aaea43febe674994e5a132b2b5" dependencies = [ "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "derivative 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -330,7 +330,7 @@ dependencies = [ [[package]] name = "gfx-backend-metal" version = "0.1.0" -source = "git+https://github.com/gfx-rs/gfx#2b425d1708cec98da63dde1a1c8539156d577465" +source = "git+https://github.com/gfx-rs/gfx#ecf4f81c6b78f6aaea43febe674994e5a132b2b5" dependencies = [ "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "block 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -339,7 +339,7 @@ dependencies = [ "foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "gfx-hal 0.1.0 (git+https://github.com/gfx-rs/gfx)", "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", - "metal 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)", + "metal 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)", "objc 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -351,7 +351,7 @@ dependencies = [ [[package]] name = "gfx-backend-vulkan" version = "0.1.0" -source = "git+https://github.com/gfx-rs/gfx#2b425d1708cec98da63dde1a1c8539156d577465" +source = "git+https://github.com/gfx-rs/gfx#ecf4f81c6b78f6aaea43febe674994e5a132b2b5" dependencies = [ "ash 0.24.4 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.2.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -368,7 +368,7 @@ dependencies = [ [[package]] name = "gfx-hal" version = "0.1.0" -source = "git+https://github.com/gfx-rs/gfx#2b425d1708cec98da63dde1a1c8539156d577465" +source = "git+https://github.com/gfx-rs/gfx#ecf4f81c6b78f6aaea43febe674994e5a132b2b5" dependencies = [ "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "failure 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -460,7 +460,7 @@ name = "libloading" version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.23 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -508,7 +508,7 @@ dependencies = [ [[package]] name = "metal" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -529,7 +529,7 @@ version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "cc 1.0.23 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", "cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -592,16 +592,17 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "lock_api 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "parking_lot_core" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -647,7 +648,7 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "0.4.17" +version = "0.4.19" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -668,7 +669,7 @@ name = "quote" version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 0.4.17 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -703,7 +704,7 @@ dependencies = [ [[package]] name = "regex" -version = "1.0.4" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "aho-corasick 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -747,11 +748,32 @@ name = "rustc-demangle" version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "rustc_version" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "scopeguard" version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "semver" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "semver-parser" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "shared_library" version = "0.1.9" @@ -790,7 +812,7 @@ name = "spirv_cross" version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.23 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -820,7 +842,7 @@ name = "syn" version = "0.14.9" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 0.4.17 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)", "quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -830,7 +852,7 @@ name = "synstructure" version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 0.4.17 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)", "quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)", "syn 0.14.9 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1162,7 +1184,7 @@ dependencies = [ "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 byteorder 1.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "90492c5858dd7d2e78691cfb89f90d273a2800fc11d98f60786e5d87e2f83781" -"checksum cc 1.0.23 (registry+https://github.com/rust-lang/crates.io-index)" = "c37f0efaa4b9b001fa6f02d4b644dee4af97d3414df07c51e3e4f015f3a3e131" +"checksum cc 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)" = "70f2a88c2e69ceee91c209d8ef25b81fc1a65f42c7f14dfd59d1fed189e514d1" "checksum cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "0c4e7bb64a8ebb0d856483e1e682ea3422f883c5f5615a90d51a2c82fe87fdd3" "checksum cgl 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "55e7ec0b74fe5897894cbc207092c577e87c52f8a59e8ca8d97ef37551f60a49" "checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" @@ -1209,7 +1231,7 @@ dependencies = [ "checksum malloc_buf 0.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb" "checksum memchr 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a3b4142ab8738a78c51896f704f83c11df047ff1bda9a92a661aa6361552d93d" "checksum memmap 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e2ffa2c986de11a9df78620c01eeaaf27d94d3ff02bf81bfcca953102dd0c6ff" -"checksum metal 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)" = "76bcb2aba806e52a685c6e55188f7b3152c2019cf6ed86725d8a268c6fecf56c" +"checksum metal 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8411e1b14691a658f4b285f980c98d1af1922dcf037ea4454288dc456ca0d1ed" "checksum nix 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d37e713a259ff641624b6cb20e3b12b2952313ba36b6823c0f16e6cfd9e5de17" "checksum objc 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "9833ab0efe5361b1e2122a0544a5d3359576911a42cb098c2e59be8650807367" "checksum objc-foundation 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1add1b659e36c9607c7aab864a76c7a4c2760cd0cd2e120f3fb8b952c7e22bf9" @@ -1218,10 +1240,10 @@ dependencies = [ "checksum osmesa-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "88cfece6e95d2e717e0872a7f53a8684712ad13822a7979bc760b9c77ec0013b" "checksum owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cdf84f41639e037b484f93433aa3897863b561ed65c6e59c7073d7c561710f37" "checksum parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "f0802bff09003b291ba756dc7e79313e51cc31667e94afbe847def490424cde5" -"checksum parking_lot_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "06a2b6aae052309c2fd2161ef58f5067bc17bb758377a0de9d4b279d603fdd8a" +"checksum parking_lot_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ad7f7e6ebdc79edff6fdcb87a55b620174f7a989e3eb31b65231f4af57f00b8c" "checksum percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831" "checksum pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)" = "676e8eb2b1b4c9043511a9b7bea0915320d7e502b0a079fb03f9635a5252b18c" -"checksum proc-macro2 0.4.17 (registry+https://github.com/rust-lang/crates.io-index)" = "7ee80fbbe0ae60bcad82d15bc59d5fe2aaebc1b83fbfb145abc8c74f8e769549" +"checksum proc-macro2 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)" = "ffe022fb8c8bd254524b0b3305906c1921fa37a84a644e29079a9e62200c3901" "checksum quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9274b940887ce9addde99c4eee6b5c44cc494b182b97e73dc8ffdcb3397fd3f0" "checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a" "checksum quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)" = "dd636425967c33af890042c483632d33fa7a18f19ad1d7ea72e8998c6ef8dea5" @@ -1229,12 +1251,15 @@ dependencies = [ "checksum rand_core 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "edecf0f94da5551fc9b492093e30b041a891657db7940ee221f9d2f66e82eef2" "checksum redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "c214e91d3ecf43e9a4e41e578973adeb14b474f2bee858742d127af75a0112b1" "checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76" -"checksum regex 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "67d0301b0c6804eca7e3c275119d0b01ff3b7ab9258a65709e608a66312a1025" +"checksum regex 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "2069749032ea3ec200ca51e4a31df41759190a88edca0d2d86ee8bedf7073341" "checksum regex-syntax 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "747ba3b235651f6e2f67dfa8bcdcd073ddb7c243cb21c442fc12395dfcac212d" "checksum remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3488ba1b9a2084d38645c4c08276a1752dcbf2c7130d74f1569681ad5d2799c5" "checksum renderdoc 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3aee9badfb4078c375d2d0479ed29c9c057b51ade78f94792ba2dcb11f343e7e" "checksum rustc-demangle 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "bcfe5b13211b4d78e5c2cadfebd7769197d95c639c35a50057eb4c05de811395" +"checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" "checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27" +"checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" +"checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" "checksum shared_library 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "5a9e7e0f2bfae24d8a5b5a66c5b257a83c7412304311512a0c054cd5e619da11" "checksum smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "153ffa32fd170e9944f7e0838edf824a754ec4c1fc64746fcc9fe1f8fa602e5d" "checksum smithay-client-toolkit 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f1609083d6bca3991a3c648d80ae16e1764d70881c3321bee1c915149073d605" diff --git a/libportability-gfx/src/conv.rs b/libportability-gfx/src/conv.rs index c97183c..b583598 100644 --- a/libportability-gfx/src/conv.rs +++ b/libportability-gfx/src/conv.rs @@ -734,43 +734,3 @@ pub fn map_pipeline_statistics(flags: VkQueryPipelineStatisticFlags) -> query::P // Vulkan and HAL flags are equal query::PipelineStatistic::from_bits_truncate(flags as u32) } - -pub fn map_specialization_info(specialization: &VkSpecializationInfo) -> Vec { - let data = unsafe { slice::from_raw_parts( - specialization.pData as *const u8, - specialization.dataSize as _, - )}; - let entries = unsafe { slice::from_raw_parts( - specialization.pMapEntries, - specialization.mapEntryCount as _, - )}; - - entries - .into_iter() - .map(|entry| { - let offset = entry.offset as usize; - pso::Specialization { - id: entry.constantID, - value: match entry.size { - 4 => pso::Constant::U32( - data[offset] as u32 | - (data[offset+1] as u32) << 8 | - (data[offset+2] as u32) << 16 | - (data[offset+3] as u32) << 24 - ), - 8 => pso::Constant::U64( - data[offset] as u64 | - (data[offset+1] as u64) << 8 | - (data[offset+2] as u64) << 16 | - (data[offset+3] as u64) << 24 | - (data[offset+4] as u64) << 32 | - (data[offset+5] as u64) << 40 | - (data[offset+6] as u64) << 48 | - (data[offset+7] as u64) << 56 - ), - size => panic!("Unexpected specialization constant size: {:?}", size), - }, - } - }) - .collect::>() -} diff --git a/libportability-gfx/src/impls.rs b/libportability-gfx/src/impls.rs index 7ef0c0c..afefc42 100644 --- a/libportability-gfx/src/impls.rs +++ b/libportability-gfx/src/impls.rs @@ -1733,8 +1733,8 @@ pub extern "C" fn gfxCreateGraphicsPipelines( slice::from_raw_parts(pCreateInfos, createInfoCount as _) }; - const NUM_SHADER_STAGES: usize = 5; - let mut specializations = Vec::with_capacity(infos.len() * NUM_SHADER_STAGES); + let mut spec_constants = Vec::new(); + let mut spec_data = Vec::new(); // Collect all information which we will borrow later. Need to work around // the borrow checker here. @@ -1742,13 +1742,24 @@ pub extern "C" fn gfxCreateGraphicsPipelines( let stages = unsafe { slice::from_raw_parts(info.pStages, info.stageCount as _) }; - specializations.extend(stages.iter().map(|stage| unsafe { - stage - .pSpecializationInfo - .as_ref() - .map(conv::map_specialization_info) - .unwrap_or_default() - })); + for stage in stages { + if let Some(spec_info) = unsafe { stage.pSpecializationInfo.as_ref() } { + let entries = unsafe { slice::from_raw_parts( + spec_info.pMapEntries, + spec_info.mapEntryCount as _, + )}; + for entry in entries { + let base = spec_data.len() as u16 + entry.offset as u16; + spec_constants.push(pso::SpecializationConstant { + id: entry.constantID, + range: base .. base + (entry.size as u16), + }); + } + spec_data.extend_from_slice(unsafe { + slice::from_raw_parts(spec_info.pData as *const u8, spec_info.dataSize as _) + }); + } + } } let mut cur_specialization = 0; @@ -1805,12 +1816,21 @@ pub extern "C" fn gfxCreateGraphicsPipelines( use super::VkShaderStageFlagBits::*; let name = unsafe { CStr::from_ptr(stage.pName) }; + let spec_count = unsafe { + stage.pSpecializationInfo + .as_ref() + .map(|spec_info| spec_info.mapEntryCount as usize) + .unwrap_or(0) + }; let entry_point = pso::EntryPoint { entry: name.to_str().unwrap(), module: &*stage.module, - specialization: &specializations[cur_specialization], + specialization: pso::Specialization { + constants: &spec_constants[cur_specialization .. cur_specialization + spec_count], + data: &spec_data, + }, }; - cur_specialization += 1; + cur_specialization += spec_count; match stage.stage { VK_SHADER_STAGE_VERTEX_BIT => { @@ -2156,29 +2176,52 @@ pub extern "C" fn gfxCreateComputePipelines( // Collect all information which we will borrow later. Need to work around // the borrow checker here. - let specializations = infos - .iter() - .map(|info| unsafe { - info.stage - .pSpecializationInfo - .as_ref() - .map(conv::map_specialization_info) - .unwrap_or_default() - }) - .collect::>(); + let mut spec_constants = Vec::new(); + let mut spec_data = Vec::new(); + // Collect all information which we will borrow later. Need to work around + // the borrow checker here. + for info in infos { + if let Some(spec_info) = unsafe { info.stage.pSpecializationInfo.as_ref() } { + let entries = unsafe { slice::from_raw_parts( + spec_info.pMapEntries, + spec_info.mapEntryCount as _, + )}; + for entry in entries { + let base = spec_data.len() as u16 + entry.offset as u16; + spec_constants.push(pso::SpecializationConstant { + id: entry.constantID, + range: base .. base + (entry.size as u16), + }); + } + spec_data.extend_from_slice(unsafe { + slice::from_raw_parts(spec_info.pData as *const u8, spec_info.dataSize as _) + }); + } + } + + let mut cur_specialization = 0; let descs = infos .iter() - .zip(&specializations) - .map(|(info, specialization)| { + .map(|info| { let name = unsafe { CStr::from_ptr(info.stage.pName) }; + let spec_count = unsafe { + info.stage.pSpecializationInfo + .as_ref() + .map(|spec_info| spec_info.mapEntryCount as usize) + .unwrap_or(0) + }; let shader = pso::EntryPoint { entry: name.to_str().unwrap(), module: &*info.stage.module, - specialization, + specialization: pso::Specialization { + constants: &spec_constants[cur_specialization .. cur_specialization + spec_count], + data: &spec_data, + }, }; - let layout = &*info.layout; + cur_specialization += spec_count; + let layout = &*info.layout; let flags = { let mut flags = pso::PipelineCreationFlags::empty(); @@ -3057,7 +3100,7 @@ pub extern "C" fn gfxCmdSetBlendConstants( mut commandBuffer: VkCommandBuffer, blendConstants: *const f32, ) { - let value = unsafe { *(blendConstants as *const hal::pso::ColorValue) }; + let value = unsafe { *(blendConstants as *const pso::ColorValue) }; commandBuffer.set_blend_constants(value); } #[inline]