From 6ed931d17f41ab9b4cf075bfa217b65e524935fc Mon Sep 17 00:00:00 2001 From: Kyle Mayes Date: Tue, 10 Oct 2023 22:28:00 -0400 Subject: [PATCH 1/6] Add Vulkan 1.3 prelude module --- CHANGELOG.md | 3 +++ vulkanalia/src/lib.rs | 6 ++++++ 2 files changed, 9 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c112651..7fa4210 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,9 @@ - Added `no_std` compability for `vulkanalia` and `vulkanalia-sys` crates - Make all extendable output structs parameters in command wrappers (see [#213](https://github.com/KyleMayes/vulkanalia/issues/213) for details) +### Added +- Added `vulkanalia::prelude::v1_3` module (a prelude module for Vulkan 1.3+) + ### Bindings Updates - [September 22, 2023 Vulkan 1.3.265 spec update](https://github.com/KhronosGroup/Vulkan-Docs/commit/4871ab9e57fb07f98bf016cb10a3088924976e29) - [Add a driver ID for AGXV (Asahi) (#2238)](https://github.com/KhronosGroup/Vulkan-Docs/commit/2b587d9c4adc65429a0063704d1ed6abe79ddb78) diff --git a/vulkanalia/src/lib.rs b/vulkanalia/src/lib.rs index 3f5bdb8..c0ddffa 100644 --- a/vulkanalia/src/lib.rs +++ b/vulkanalia/src/lib.rs @@ -48,6 +48,12 @@ pub mod prelude { pub use crate::prelude::v1_1::*; pub use crate::vk::{DeviceV1_2, EntryV1_2, InstanceV1_2}; } + + /// Vulkan 1.3 prelude. + pub mod v1_3 { + pub use crate::prelude::v1_2::*; + pub use crate::vk::{DeviceV1_3, EntryV1_3, InstanceV1_3}; + } } /// The result of a executing a fallible Vulkan command. From 169099e4635f283b6c8a2f358e3459dc17165c8c Mon Sep 17 00:00:00 2001 From: Kyle Mayes Date: Mon, 16 Oct 2023 16:56:57 -0400 Subject: [PATCH 2/6] Add debug steps to workflows --- .github/workflows/ci.yml | 18 ++++++++++++++++++ .github/workflows/publish.yml | 14 ++++++++++++++ .github/workflows/update.yml | 14 +++++++++++++- 3 files changed, 45 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a2d78ad..ffff21e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -7,6 +7,16 @@ on: pull_request: branches: - master + workflow_dispatch: + inputs: + error_debug: + type: boolean + required: false + default: false + force_debug: + type: boolean + required: false + default: false jobs: @@ -40,6 +50,10 @@ jobs: with: command: build args: --manifest-path vulkanalia/Cargo.toml --no-default-features + # Debug + - name: Debug + uses: mxschmitt/action-tmate@v3 + if: ${{ (failure() && inputs.error_debug) || inputs.force_debug }} format-vulkanalia: name: Format - Vulkanalia @@ -113,3 +127,7 @@ jobs: - name: Check Bindings working-directory: ./generator run: ./gradlew run --args="--directory=.. check" + # Debug + - name: Debug + uses: mxschmitt/action-tmate@v3 + if: ${{ (failure() && inputs.error_debug) || inputs.force_debug }} diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index ef726ad..b39d3f5 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -4,6 +4,16 @@ on: push: branches: - master + workflow_dispatch: + inputs: + error_debug: + type: boolean + required: false + default: false + force_debug: + type: boolean + required: false + default: false jobs: @@ -65,3 +75,7 @@ jobs: BRANCH: gh-pages FOLDER: ./tutorial/book/book CLEAN: true + # Debug + - name: Debug + uses: mxschmitt/action-tmate@v3 + if: ${{ (failure() && inputs.error_debug) || inputs.force_debug }} diff --git a/.github/workflows/update.yml b/.github/workflows/update.yml index 31f6a3d..52d86b1 100644 --- a/.github/workflows/update.yml +++ b/.github/workflows/update.yml @@ -4,7 +4,15 @@ on: schedule: - cron: "0 21 * * *" workflow_dispatch: - inputs: {} + inputs: + error_debug: + type: boolean + required: false + default: false + force_debug: + type: boolean + required: false + default: false jobs: @@ -30,3 +38,7 @@ jobs: --token=${{ secrets.PERSONAL_ACCESS_TOKEN }} \ update \ --repo=${{ github.repository }}" + # Debug + - name: Debug + uses: mxschmitt/action-tmate@v3 + if: ${{ (failure() && inputs.error_debug) || inputs.force_debug }} From dc5fac1c41abea91195cece40a021a1604e97cac Mon Sep 17 00:00:00 2001 From: Kyle Mayes Date: Mon, 16 Oct 2023 17:02:09 -0400 Subject: [PATCH 3/6] Bump MSRV to 1.64 --- .github/workflows/ci.yml | 15 ++++++++++++--- .github/workflows/publish.yml | 2 +- CHANGELOG.md | 1 + README.md | 2 +- tutorial/book/src/development_environment.md | 2 +- tutorial/book/src/introduction.md | 2 +- 6 files changed, 17 insertions(+), 7 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ffff21e..677e2ab 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -23,6 +23,9 @@ jobs: test-vulkanalia: name: Test - Vulkanalia runs-on: ubuntu-latest + env: + RUST_LOG: info + RUST_VERSION: 1.64.0 steps: # Checkout - name: Checkout Repository @@ -31,7 +34,7 @@ jobs: - name: Install Rust uses: actions-rs/toolchain@v1 with: - toolchain: 1.51.0 + toolchain: ${{ env.RUST_VERSION }} components: clippy, rustfmt # Test - name: Cargo Test @@ -58,6 +61,9 @@ jobs: format-vulkanalia: name: Format - Vulkanalia runs-on: ubuntu-latest + env: + RUST_LOG: info + RUST_VERSION: 1.64.0 steps: # Checkout - name: Checkout Repository @@ -66,7 +72,7 @@ jobs: - name: Install Rust uses: actions-rs/toolchain@v1 with: - toolchain: 1.51.0 + toolchain: ${{ env.RUST_VERSION }} components: clippy, rustfmt # Format - name: Cargo Format @@ -78,6 +84,9 @@ jobs: clippy-vulkanalia: name: Clippy - Vulkanalia runs-on: ubuntu-latest + env: + RUST_LOG: info + RUST_VERSION: 1.64.0 steps: # Checkout - name: Checkout Repository @@ -86,7 +95,7 @@ jobs: - name: Install Rust uses: actions-rs/toolchain@v1 with: - toolchain: 1.51.0 + toolchain: ${{ env.RUST_VERSION }} components: clippy, rustfmt # Clippy - name: Cargo Clippy diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index b39d3f5..6dfe7ab 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -22,7 +22,7 @@ jobs: runs-on: ubuntu-latest env: RUST_LOG: info - RUST_VERSION: 1.51.0 + RUST_VERSION: 1.64.0 MDBOOK_VERSION: 0.4.21 steps: # Checkout diff --git a/CHANGELOG.md b/CHANGELOG.md index 7fa4210..1c05ff1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ ## [0.23.0] - UNRELEASED ### Changed +- Bumped MSRV to 1.64 - Added `no_std` compability for `vulkanalia` and `vulkanalia-sys` crates - Make all extendable output structs parameters in command wrappers (see [#213](https://github.com/KyleMayes/vulkanalia/issues/213) for details) diff --git a/README.md b/README.md index 7ce6b95..caecb3e 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![Crate](https://img.shields.io/crates/v/vulkanalia)](https://crates.io/crates/vulkanalia) [![Documentation](https://docs.rs/vulkanalia/badge.svg)](https://docs.rs/vulkanalia) [![CI](https://img.shields.io/github/actions/workflow/status/KyleMayes/vulkanalia/ci.yml?branch=master)](https://github.com/KyleMayes/vulkanalia/actions?query=workflow%3ACI) -![MSRV](https://img.shields.io/badge/MSRV-1.51.0-blue) +![MSRV](https://img.shields.io/badge/MSRV-1.64.0-blue) Vulkan bindings for Rust. diff --git a/tutorial/book/src/development_environment.md b/tutorial/book/src/development_environment.md index 2e4ef79..fbc2d48 100644 --- a/tutorial/book/src/development_environment.md +++ b/tutorial/book/src/development_environment.md @@ -1,6 +1,6 @@ # Development environment -In this chapter we'll set up your environment for developing Vulkan applications by installing the Vulkan SDK for your operating system. This tutorial assumes you already have a working Rust (1.51+) development environment. +In this chapter we'll set up your environment for developing Vulkan applications by installing the Vulkan SDK for your operating system. This tutorial assumes you already have a working Rust (1.64+) development environment. ## Cargo project diff --git a/tutorial/book/src/introduction.md b/tutorial/book/src/introduction.md index cdcd6e0..eb952f2 100644 --- a/tutorial/book/src/introduction.md +++ b/tutorial/book/src/introduction.md @@ -16,7 +16,7 @@ With that out of the way, let's cover some prerequisites for following this tuto * A graphics card and driver compatible with Vulkan ([NVIDIA](https://developer.nvidia.com/vulkan-driver), [AMD](http://www.amd.com/en-us/innovations/software-technologies/technologies-gaming/vulkan), [Intel](https://software.intel.com/en-us/blogs/2016/03/14/new-intel-vulkan-beta-1540204404-graphics-driver-for-windows-78110-1540)) * Experience with Rust -* Rust 1.51 or later +* Rust 1.64 or later * Some existing experience with 3D computer graphics This tutorial will not assume knowledge of OpenGL or Direct3D concepts, but it does require you to know the basics of 3D computer graphics. It will not explain the math behind perspective projection, for example. See [this online book](https://paroj.github.io/gltut/) for a great introduction of computer graphics concepts. Some other great computer graphics resources are: From 6b1e1c308dc8697c1d6666686c0f9b0cbbc857e8 Mon Sep 17 00:00:00 2001 From: Kyle Mayes Date: Mon, 16 Oct 2023 17:16:33 -0400 Subject: [PATCH 4/6] Remove spurious local commit update --- generator/src/main/kotlin/com/kylemayes/generator/Main.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/generator/src/main/kotlin/com/kylemayes/generator/Main.kt b/generator/src/main/kotlin/com/kylemayes/generator/Main.kt index 9cec3f7..0311e56 100644 --- a/generator/src/main/kotlin/com/kylemayes/generator/Main.kt +++ b/generator/src/main/kotlin/com/kylemayes/generator/Main.kt @@ -130,7 +130,6 @@ class Update : CliktCommand(help = "Updates generated Vulkan bindings") { override fun run() { val inputs = getRepositoryInputs(context) - inputs.updateLocal(context) if (!force && !inputs.list.any { it.stale }) { log.info { "Nothing to update." } From 70af30cb9d53d1f58bc0c604045c05d6ee6c1138 Mon Sep 17 00:00:00 2001 From: Kyle Mayes Date: Mon, 16 Oct 2023 17:16:45 -0400 Subject: [PATCH 5/6] Add slow command process logging --- .../kylemayes/generator/support/Command.kt | 13 +++++--- .../com/kylemayes/generator/support/Logger.kt | 33 +++++++++++++++++++ 2 files changed, 42 insertions(+), 4 deletions(-) diff --git a/generator/src/main/kotlin/com/kylemayes/generator/support/Command.kt b/generator/src/main/kotlin/com/kylemayes/generator/support/Command.kt index d860c3d..6e7b6da 100644 --- a/generator/src/main/kotlin/com/kylemayes/generator/support/Command.kt +++ b/generator/src/main/kotlin/com/kylemayes/generator/support/Command.kt @@ -2,9 +2,13 @@ package com.kylemayes.generator.support +import mu.KotlinLogging import java.util.concurrent.CountDownLatch import java.util.concurrent.TimeUnit import java.util.concurrent.atomic.AtomicReference +import kotlin.time.Duration.Companion.seconds + +private val log = KotlinLogging.logger { /* */ } /** Executes the `git` command and prints the output. */ fun git(vararg args: String) { @@ -13,7 +17,7 @@ fun git(vararg args: String) { } /** Executes the `rustfmt` command and returns the output. */ -fun rustfmt(rust: String) = execute("rustfmt", emptyArray(), rust) +fun rustfmt(rust: String): String = execute("rustfmt", emptyArray(), rust) /** Executes a command in a new thread (with a time limit) and returns the output. */ private fun execute(command: String, args: Array, input: String? = null): String { @@ -28,14 +32,15 @@ private fun execute(command: String, args: Array, input: String? = null) Thread.currentThread().name = "$command-thread" if (input != null) { - process.outputStream.write(input.toByteArray()) + log.slow("`$command` process stdin", 1.seconds) { process.outputStream.write(input.toByteArray()) } process.outputStream.close() } - output.set(String(process.inputStream.readAllBytes())) + val outputBytes = log.slow("`$command` process stdin", 1.seconds) { process.inputStream.readAllBytes() } + output.set(String(outputBytes)) process.inputStream.close() - process.waitFor() + log.slow("`$command` process", 2.5.seconds) { process.waitFor() } if (process.exitValue() != 0) { error("Non-zero exit code (${process.exitValue()}).") diff --git a/generator/src/main/kotlin/com/kylemayes/generator/support/Logger.kt b/generator/src/main/kotlin/com/kylemayes/generator/support/Logger.kt index 1ded263..71610a6 100644 --- a/generator/src/main/kotlin/com/kylemayes/generator/support/Logger.kt +++ b/generator/src/main/kotlin/com/kylemayes/generator/support/Logger.kt @@ -3,6 +3,8 @@ package com.kylemayes.generator.support import mu.KLogger +import java.util.concurrent.atomic.AtomicBoolean +import kotlin.time.Duration /** Times a block of code. */ fun KLogger.time(name: String, block: () -> T): T { @@ -13,3 +15,34 @@ fun KLogger.time(name: String, block: () -> T): T { info { "[ END ] $name (${elapsed}s)" } return result } + +/** Times a block of code if it is unexpectedly slow. */ +fun KLogger.slow(name: String, limit: Duration, block: () -> T): T { + val done = AtomicBoolean(false) + val slow = AtomicBoolean(false) + + val thread = Thread { + try { + Thread.sleep(limit.inWholeMilliseconds) + if (!done.get()) { + slow.set(true) + warn { "[UPDATE(SLOW)] $name is taking a while (>${limit}ms)..." } + } + } catch (_: InterruptedException) {} + } + + thread.start() + + val start = System.nanoTime() + val result = block() + + done.set(true) + thread.interrupt() + + if (slow.get()) { + val elapsed = "%.3f".format((System.nanoTime() - start) / 1_000_000_000.0) + warn { "[ END (SLOW) ] $name (${elapsed}s)" } + } + + return result +} From 8c9a127962072770011c72690c7699ef92ca37e8 Mon Sep 17 00:00:00 2001 From: Kyle Mayes Date: Mon, 16 Oct 2023 17:56:06 -0400 Subject: [PATCH 6/6] Rework command process handling --- .../kylemayes/generator/support/Command.kt | 85 ++++++++++++------- 1 file changed, 53 insertions(+), 32 deletions(-) diff --git a/generator/src/main/kotlin/com/kylemayes/generator/support/Command.kt b/generator/src/main/kotlin/com/kylemayes/generator/support/Command.kt index 6e7b6da..9c30f84 100644 --- a/generator/src/main/kotlin/com/kylemayes/generator/support/Command.kt +++ b/generator/src/main/kotlin/com/kylemayes/generator/support/Command.kt @@ -3,6 +3,7 @@ package com.kylemayes.generator.support import mu.KotlinLogging +import java.util.concurrent.ConcurrentHashMap import java.util.concurrent.CountDownLatch import java.util.concurrent.TimeUnit import java.util.concurrent.atomic.AtomicReference @@ -19,52 +20,72 @@ fun git(vararg args: String) { /** Executes the `rustfmt` command and returns the output. */ fun rustfmt(rust: String): String = execute("rustfmt", emptyArray(), rust) -/** Executes a command in a new thread (with a time limit) and returns the output. */ +/** Executes a command (with a time limit) and returns the output. */ private fun execute(command: String, args: Array, input: String? = null): String { val process = ProcessBuilder(command, *args).start() - val output = AtomicReference(null) - val error = AtomicReference(null) - val latch = CountDownLatch(1) + val errors = ConcurrentHashMap() + val latch = CountDownLatch(4) + val stdout = AtomicReference(null) + val stderr = AtomicReference(null) - val thread = Thread { + fun operation(name: String, operation: () -> Unit) = Thread { try { - Thread.currentThread().name = "$command-thread" - - if (input != null) { - log.slow("`$command` process stdin", 1.seconds) { process.outputStream.write(input.toByteArray()) } - process.outputStream.close() - } + Thread.currentThread().name = "$command-$name" + log.slow("`$command`: $name", 2.5.seconds) { operation() } + } catch (e: Throwable) { + errors[name] = e + } finally { + latch.countDown() + } + } - val outputBytes = log.slow("`$command` process stdin", 1.seconds) { process.inputStream.readAllBytes() } - output.set(String(outputBytes)) + val threads = listOf( + operation("write stdin") { + if (input != null) process.outputStream.write(input.toByteArray()) + process.outputStream.flush() + process.outputStream.close() + }, + operation("read stdout") { + stdout.set(String(process.inputStream.readAllBytes())) process.inputStream.close() + }, + operation("read stderr") { + stderr.set(String(process.errorStream.readAllBytes())) + process.errorStream.close() + }, + operation("wait") { + process.waitFor() + }, + ) + + threads.forEach { it.start() } + val countdown = latch.await(5, TimeUnit.SECONDS) - log.slow("`$command` process", 2.5.seconds) { process.waitFor() } + val stdoutValue = stdout.get() + val stderrValue = stderr.get() + val errorsValue = errors.toMap() - if (process.exitValue() != 0) { - error("Non-zero exit code (${process.exitValue()}).") + if (process.isAlive) { + log.slow("`$command`: kill", 0.5.seconds) { + try { + process.destroy() + process.waitFor(1, TimeUnit.SECONDS) + process.destroyForcibly() + } catch (e: Error) { + e.printStackTrace() } - } catch (e: Throwable) { - error.set(e) - } finally { - latch.countDown() } } - thread.start() - latch.await(5, TimeUnit.SECONDS) - - val outputValue = output.get() - val errorValue = error.get() - if (outputValue == null || errorValue != null) { - process.destroy() - process.waitFor(1, TimeUnit.SECONDS) - process.destroyForcibly() + if (stdoutValue == null || errorsValue.isNotEmpty()) { val executed = "$command ${args.joinToString(" ")}".trim() - val message = "Failed to execute command ('$executed')." - throw RuntimeException(message, errorValue ?: RuntimeException("Timed out.")) + val message = "Failed to execute command ('$executed'):\n\n[stdout]=\n$stdoutValue\n\n[stderr]=\n$stderrValue" + val error = RuntimeException(message) + if (!countdown) error.addSuppressed(RuntimeException("Timed out.")) + errorsValue.forEach { error.addSuppressed(RuntimeException(it.key, it.value)) } + throw error } - return outputValue + return stdoutValue }