Skip to content

Commit

Permalink
Add Vulkan video extensions
Browse files Browse the repository at this point in the history
  • Loading branch information
KyleMayes committed Oct 17, 2023
1 parent 0fbd184 commit b7bfa1e
Show file tree
Hide file tree
Showing 24 changed files with 15,417 additions and 119 deletions.
26 changes: 25 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -123,20 +123,44 @@ jobs:
check-bindings:
name: Check - Bindings
runs-on: ubuntu-latest
env:
RUST_LOG: info
RUST_VERSION: 1.72.0
BINDGEN_VERSION: 0.68.1
steps:
# Checkout
- name: Checkout Repository
uses: actions/checkout@v2
# Dependencies
- name: Install LLVM and Clang
uses: KyleMayes/install-llvm-action@v1
with:
version: 16
- name: Install Java
uses: actions/setup-java@v1
with:
java-version: 14
- name: Install Rust
uses: actions-rs/toolchain@v1
with:
toolchain: ${{ env.RUST_VERSION }}
- name: Cache bindgen
id: cache-bindgen
uses: actions/cache@v2
with:
path: ~/.cargo/bin/bindgen
key: ${{ runner.os }}-${{ env.RUST_VERSION }}-${{ env.BINDGEN_VERSION }}
- name: Install bindgen
uses: actions-rs/cargo@v1
if: steps.cache-bindgen.outputs.cache-hit != 'true'
with:
command: install
args: bindgen-cli --version ${{ env.BINDGEN_VERSION }}
# Check
- 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 }}
if: ${{ failure() }}
24 changes: 24 additions & 0 deletions .github/workflows/update.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,39 @@ jobs:
update-bindings:
name: Update - Bindings
runs-on: ubuntu-latest
env:
RUST_LOG: info
RUST_VERSION: 1.72.0
BINDGEN_VERSION: 0.68.1
steps:
# Checkout
- name: Checkout Repository
uses: actions/checkout@v2
# Dependencies
- name: Install LLVM and Clang
uses: KyleMayes/install-llvm-action@v1
with:
version: 16
- name: Install Java
uses: actions/setup-java@v1
with:
java-version: 14
- name: Install Rust
uses: actions-rs/toolchain@v1
with:
toolchain: ${{ env.RUST_VERSION }}
- name: Cache bindgen
id: cache-bindgen
uses: actions/cache@v2
with:
path: ~/.cargo/bin/bindgen
key: ${{ runner.os }}-${{ env.RUST_VERSION }}-${{ env.BINDGEN_VERSION }}
- name: Install bindgen
uses: actions-rs/cargo@v1
if: steps.cache-bindgen.outputs.cache-hit != 'true'
with:
command: install
args: bindgen-cli --version ${{ env.BINDGEN_VERSION }}
# Update
- name: Update Bindings
working-directory: ./generator
Expand Down
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
- Make all extendable output structs parameters in command wrappers (see [#213](https://github.com/KyleMayes/vulkanalia/issues/213) for details)

### Added
- Added support for Vulkan video extensions
- Added `vulkanalia::prelude::v1_3` module (a prelude module for Vulkan 1.3+)

### Bindings Updates
Expand Down Expand Up @@ -222,7 +223,7 @@
- Fixed composite bitflag values (e.g., `CullModeFlags::FRONT_AND_BACK`)

### Changed
- Bumped MSRV to 1.51
- Bumped MSRV to 1.64
- Added `Send` and `Sync` requirement to `Loader` error type
- Changed type of stored layer names to `vk::ExtensionName` instead of `CString`
- Added constants, constructor, and additional conversions to `Version`
Expand Down
6 changes: 5 additions & 1 deletion generator/src/main/kotlin/com/kylemayes/generator/Input.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,16 @@ import org.kohsuke.github.GHCommit
import java.nio.file.Files

private val registryPath = RepositoryPath("KhronosGroup/Vulkan-Docs", "main", "xml/vk.xml")
private val videoPath = RepositoryPath("KhronosGroup/Vulkan-Headers", "main", "include/vk_video")

/** The generator inputs pulled from GitHub repositories. */
data class RepositoryInputs(
/** The Vulkan API registry. */
val registry: RepositoryInput<String>,
/** The Vulkan video headers. */
val video: RepositoryInput<Map<String, String>>,
) {
val list = listOf(registry)
val list = listOf(registry, video)

/** Updates the locally tracked commits to match the latest commits. */
fun updateLocal(context: GeneratorContext) {
Expand All @@ -25,6 +28,7 @@ fun getRepositoryInputs(context: GeneratorContext): RepositoryInputs {
val locals = getLocalCommitHashes(context)
return RepositoryInputs(
registry = getRepositoryInput(context, locals, registryPath, ::getFile),
video = getRepositoryInput(context, locals, videoPath, ::getDirectory),
)
}

Expand Down
13 changes: 11 additions & 2 deletions generator/src/main/kotlin/com/kylemayes/generator/Main.kt
Original file line number Diff line number Diff line change
Expand Up @@ -75,9 +75,13 @@ class Check : CliktCommand(help = "Checks generated Vulkan bindings") {
val xml = log.time("Fetch Registry") { inputs.registry.local.lazy.value }
val registry = log.time("Parse Registry") { parseRegistry(xml) }

// Headers (video)

val video = log.time("Fetch Video Headers") { inputs.video.local.lazy.value }

// Generate

val files = log.time("Generate Files") { generateRustFiles(registry) }
val files = log.time("Generate Files") { generateRustFiles(registry, video) }

// Check

Expand Down Expand Up @@ -142,9 +146,14 @@ class Update : CliktCommand(help = "Updates generated Vulkan bindings") {
val xml = log.time("Fetch Registry") { xmlVersion.lazy.value }
val registry = log.time("Parse Registry") { parseRegistry(xml) }

// Headers (video)

val videoVersion = if (skipUpgrade) { inputs.video.local } else { inputs.video.latest }
val video = log.time("Fetch Video Headers") { videoVersion.lazy.value }

// Generate

val files = log.time("Generate Files") { generateRustFiles(registry) }
val files = log.time("Generate Files") { generateRustFiles(registry, video) }

// Check

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import com.kylemayes.generator.generate.file.generateExtensionTraits
import com.kylemayes.generator.generate.file.generateExtensions
import com.kylemayes.generator.generate.file.generateFunctions
import com.kylemayes.generator.generate.file.generateHandles
import com.kylemayes.generator.generate.file.generateHeaders
import com.kylemayes.generator.generate.file.generateMacros
import com.kylemayes.generator.generate.file.generateResultEnums
import com.kylemayes.generator.generate.file.generateStructs
Expand All @@ -27,8 +28,17 @@ import java.nio.file.Path

private val log = KotlinLogging.logger { /* */ }

/** Generates Rust files for a Vulkan API registry. */
fun generateRustFiles(registry: Registry) = listOf(
/** The additional `bindgen` options for the Vulkan video headers. */
private val videoOptions = listOf(
"--allowlist-item", "StdVideo.*",
"--allowlist-item", "STD_VIDEO_.*",
"--no-prepend-enum-name",
"--default-enum-style", "newtype_global",
"--with-derive-custom-enum", ".*=Default",
)

/** Generates Rust files for a Vulkan API registry and Vulkan video headers. */
fun generateRustFiles(registry: Registry, video: Map<String, String>) = listOf(
generateRustFile("vulkanalia-sys", "bitmasks.rs", registry.generateBitmasks()),
generateRustFile("vulkanalia-sys", "commands.rs", registry.generateCommands()),
generateRustFile("vulkanalia-sys", "constants.rs", registry.generateConstants()),
Expand All @@ -40,6 +50,7 @@ fun generateRustFiles(registry: Registry) = listOf(
generateRustFile("vulkanalia-sys", "structs.rs", registry.generateStructs()),
generateRustFile("vulkanalia-sys", "typedefs.rs", registry.generateTypedefs()),
generateRustFile("vulkanalia-sys", "unions.rs", registry.generateUnions()),
generateRustFile("vulkanalia-sys", "video.rs", generateHeaders("video", video, videoOptions)),
generateRustFile("vulkanalia", "vk/builders.rs", registry.generateBuilders()),
generateRustFile("vulkanalia", "vk/chains.rs", registry.generateChains()),
generateRustFile("vulkanalia", "vk/commands.rs", registry.generateCommandStructs()),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// SPDX-License-Identifier: Apache-2.0

package com.kylemayes.generator.generate.file

import com.kylemayes.generator.support.bindgen
import com.kylemayes.generator.support.time
import mu.KotlinLogging
import kotlin.io.path.ExperimentalPathApi
import kotlin.io.path.createTempDirectory
import kotlin.io.path.deleteRecursively
import kotlin.io.path.writeText

private val log = KotlinLogging.logger { /* */ }

/** Generates a Rust module using `bindgen` for a collection of C/C++ headers. */
@OptIn(ExperimentalPathApi::class)
fun generateHeaders(name: String, headers: Map<String, String>, options: List<String> = emptyList()): String {
if (headers.isEmpty()) {
return ""
}

val tmp = createTempDirectory("vk-headers")
headers.forEach { tmp.resolve(it.key).writeText(it.value) }

val input = tmp.resolve("__input.h")
input.writeText(headers.keys.joinToString("\n") { "#include \"$it\"" })

val bindings = log.time("Generate Headers ($name)") {
bindgen(
"--verbose",
"--rust-target=1.64",
"--use-core",
"--no-layout-tests",
*options.toTypedArray(),
input.toString(),
)
}

tmp.deleteRecursively()

// Hack to ensure consistent enum types on Windows and non-Windows.
return bindings.replace("(pub ::core::ffi::c_uint);", "(pub ::core::ffi::c_int);")
}
Original file line number Diff line number Diff line change
Expand Up @@ -607,7 +607,14 @@ fun Type.isStringArray() = getElement()?.getIdentifier()?.original == "char"

/** A C/C++ identifier type. */
data class IdentifierType(val identifier: Identifier) : Type {
override fun generate() = primitives.getOrDefault(identifier.value, identifier.value)
override fun generate() = if (identifier.value.startsWith("StdVideo")) {
// Types from the Vulkan video headers are prefixed with `StdVideo`
// and are in a separate `video` module from the registry types.
"video::${identifier.value}"
} else {
primitives.getOrDefault(identifier.value, identifier.value)
}

override fun generateDefault() = "${generate()}::default()"
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,21 +28,7 @@ fun Registry.filterEntities(): Registry {
// ===============================================

/** Vulkan extensions that are specifically not supported by `vulkanalia`. */
private val unsupportedExtensions = setOf(
// Video extensions depend on a bunch of types not defined in the Vulkan
// API registry but instead live in some additional Vulkan headers. Maybe
// support could be added using `bindgen` to generate Rust types from these
// additional Vulkan headers?
"VK_EXT_video_decode_h264",
"VK_EXT_video_decode_h265",
"VK_EXT_video_encode_h264",
"VK_EXT_video_encode_h265",
"VK_KHR_video_decode_h264",
"VK_KHR_video_decode_h265",
"VK_KHR_video_decode_queue",
"VK_KHR_video_encode_queue",
"VK_KHR_video_queue",
)
private val unsupportedExtensions = emptySet<String>()

/** Gets whether a Vulkan extension is supported by `vulkanalia`. */
private fun Extension.isSupported() =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import com.kylemayes.generator.support.toPascalCase
* `%VERSION%` which should be replaced with the crate version in use.
*/
fun Registry.indexEntities(): String {
generateRustFiles(this)
generateRustFiles(this, emptyMap())
val entities = manualUrls.toMutableList()

entities.addEntity("vk::make_version", "/vk/fn.make_version.html")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ import kotlin.time.Duration.Companion.seconds

private val log = KotlinLogging.logger { /* */ }

/** Executes the `bindgen` command and returns the output. */
fun bindgen(vararg args: String): String = execute("bindgen", arrayOf(*args))

/** Executes the `git` command and prints the output. */
fun git(vararg args: String) {
println("> git ${args.joinToString(" ")}")
Expand Down
Loading

0 comments on commit b7bfa1e

Please sign in to comment.