summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorxXJsonDeruloXx <danielhimebauch@gmail.com>2026-08-01 15:02:20 -0400
committerxXJsonDeruloXx <danielhimebauch@gmail.com>2026-08-01 15:02:20 -0400
commit98106c79126fc01e96b7b718977b857cb216922f (patch)
treeee3877f9ebc1e794c74511867bced4e6e6ab37b1
parentd859de9a5849f99824ba98a69d6658d9f7724bdf (diff)
downloaddecky-lsfg-vk-98106c79126fc01e96b7b718977b857cb216922f.tar.gz
decky-lsfg-vk-98106c79126fc01e96b7b718977b857cb216922f.zip
Add bionic-fg glibc x86_64 experimentagent/bionic-fg-x86_64-experiment
-rw-r--r--docs/bionic-fg-experiment.md71
-rw-r--r--justfile7
-rwxr-xr-xscripts/build_bionic_fg_x86_64.sh49
-rw-r--r--vendor/bionic-fg/.gitignore1
-rw-r--r--vendor/bionic-fg/CMakeLists.txt38
-rw-r--r--vendor/bionic-fg/README.md30
-rwxr-xr-xvendor/bionic-fg/build-linux-x86_64.sh29
-rw-r--r--vendor/bionic-fg/src/framegen_context.cpp31
-rw-r--r--vendor/bionic-fg/src/framegen_context.hpp9
-rw-r--r--vendor/bionic-fg/src/vk_layer/layer.cpp27
10 files changed, 267 insertions, 25 deletions
diff --git a/docs/bionic-fg-experiment.md b/docs/bionic-fg-experiment.md
new file mode 100644
index 0000000..e633611
--- /dev/null
+++ b/docs/bionic-fg-experiment.md
@@ -0,0 +1,71 @@
+# Bionic FG glibc experiment
+
+This branch vendors the `main` snapshot of
+[bionic-fg](https://github.com/xXJSONDeruloXx/bionic-fg) and adds a Linux/glibc
+build mode for an x86_64 Vulkan implicit layer.
+
+The vendored snapshot is based on upstream `main` at `9a81c36`; the matching
+source changes are also available on bionic-fg branch
+`agent/glibc-x86_64-layer`.
+
+The Android implementation uses AHardwareBuffer imports and JNI. The glibc
+variant omits JNI/AHardwareBuffer and uses the existing single-device path:
+swapchain images are copied into device-local frame inputs, the embedded compute
+graph runs on the application device, and generated images are copied back into
+the application swapchain. The source layer remains gated by
+`BIONIC_FG_ENABLE=1`.
+
+## Build
+
+On an x86_64 Linux/glibc environment with CMake, Vulkan headers/loader, a C++17
+compiler, pthreads, and `zip` installed:
+
+```sh
+./scripts/build_bionic_fg_x86_64.sh
+```
+
+The build stages:
+
+```text
+out/bionic-fg-x86_64/libbionic_fg.so
+out/bionic-fg-x86_64/VkLayer_BIONIC_framegen.json
+out/bionic-fg-x86_64.zip
+```
+
+The manifest expects the standard per-user Vulkan layout:
+
+```text
+~/.local/lib/libbionic_fg.so
+~/.local/share/vulkan/implicit_layer.d/VkLayer_BIONIC_framegen.json
+```
+
+For a manual smoke test, copy those two files into place, create a Bionic FG
+configuration, and launch a Vulkan application with:
+
+```sh
+export BIONIC_FG_ENABLE=1
+export BIONIC_FG_CONFIG="$HOME/.config/bionic-fg/conf.toml"
+export VK_LAYER_PATH="$HOME/.local/share/vulkan/implicit_layer.d"
+```
+
+```toml
+version = 1
+
+[global]
+enabled = true
+multiplier = 2
+flow_scale = 0.8
+model = 0
+```
+
+This is intentionally a native-layer build experiment. The existing Decky
+installer and UI still manage `lsfg-vk`; a follow-up branch should decide how a
+runtime selector, configuration namespace, and architecture/package selection
+should be exposed after testing the layer on real x86_64 Vulkan hardware.
+
+## Validation notes
+
+The produced library should be an x86-64 ELF shared object linked against the
+system Vulkan loader and glibc. A successful build alone does not establish
+frame-generation correctness; validation still requires a real x86_64 Vulkan
+driver, a swapchain application, and inspection of the layer logs/artifacts.
diff --git a/justfile b/justfile
index 54148ad..d50b220 100644
--- a/justfile
+++ b/justfile
@@ -1,5 +1,5 @@
default:
- echo "Available recipes: build, test, clean, generate-schema"
+ echo "Available recipes: build, build-bionic-fg-x86_64, test, clean, generate-schema"
generate-schema:
python3 scripts/generate_ts_schema.py
@@ -7,6 +7,9 @@ generate-schema:
build:
python3 scripts/generate_ts_schema.py && sudo rm -rf node_modules && .vscode/build.sh
+build-bionic-fg-x86_64:
+ scripts/build_bionic_fg_x86_64.sh
+
test:
scp "out/Decky LSFG-VK.zip" deck@192.168.0.6:~/Desktop
@@ -18,4 +21,4 @@ cef:
clean:
rm -rf node_modules dist
- sudo rm -rf /tmp/decky \ No newline at end of file
+ sudo rm -rf /tmp/decky
diff --git a/scripts/build_bionic_fg_x86_64.sh b/scripts/build_bionic_fg_x86_64.sh
new file mode 100755
index 0000000..ba6211d
--- /dev/null
+++ b/scripts/build_bionic_fg_x86_64.sh
@@ -0,0 +1,49 @@
+#!/usr/bin/env bash
+set -euo pipefail
+
+ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
+SOURCE_DIR="$ROOT_DIR/vendor/bionic-fg"
+BUILD_DIR="${BIONIC_FG_BUILD_DIR:-$SOURCE_DIR/build/linux-x86_64}"
+OUTPUT_DIR="${BIONIC_FG_OUTPUT_DIR:-$ROOT_DIR/out/bionic-fg-x86_64}"
+PACKAGE_PATH="${BIONIC_FG_PACKAGE_PATH:-$ROOT_DIR/out/bionic-fg-x86_64.zip}"
+
+if [[ -f "$BUILD_DIR/CMakeCache.txt" ]]; then
+ cached_source="$(sed -n 's/^CMAKE_HOME_DIRECTORY:INTERNAL=//p' "$BUILD_DIR/CMakeCache.txt")"
+ if [[ "$cached_source" != "$SOURCE_DIR" ]]; then
+ rm -rf "$BUILD_DIR"
+ fi
+fi
+
+cmake -S "$SOURCE_DIR" -B "$BUILD_DIR" \
+ -DCMAKE_BUILD_TYPE=Release
+cmake --build "$BUILD_DIR" \
+ --parallel "${CMAKE_BUILD_PARALLEL_LEVEL:-$(getconf _NPROCESSORS_ONLN 2>/dev/null || printf '2')}"
+
+LIBRARY_PATH="$BUILD_DIR/libbionic_fg.so"
+MANIFEST_PATH="$SOURCE_DIR/VkLayer_BIONIC_framegen.json"
+if [[ ! -f "$LIBRARY_PATH" ]]; then
+ printf 'Build did not produce %s\n' "$LIBRARY_PATH" >&2
+ exit 1
+fi
+
+mkdir -p "$OUTPUT_DIR"
+rm -f "$OUTPUT_DIR/libbionic_fg.so" "$OUTPUT_DIR/VkLayer_BIONIC_framegen.json" "$PACKAGE_PATH"
+cp "$LIBRARY_PATH" "$OUTPUT_DIR/libbionic_fg.so"
+cp "$MANIFEST_PATH" "$OUTPUT_DIR/VkLayer_BIONIC_framegen.json"
+
+if command -v file >/dev/null 2>&1; then
+ file "$OUTPUT_DIR/libbionic_fg.so"
+fi
+
+if command -v zip >/dev/null 2>&1; then
+ (
+ cd "$OUTPUT_DIR"
+ zip -q -j "$PACKAGE_PATH" libbionic_fg.so VkLayer_BIONIC_framegen.json
+ )
+ printf 'Package: %s\n' "$PACKAGE_PATH"
+else
+ printf 'zip is not installed; staged files remain in %s\n' "$OUTPUT_DIR"
+fi
+
+printf 'Library: %s\nManifest: %s\n' \
+ "$OUTPUT_DIR/libbionic_fg.so" "$OUTPUT_DIR/VkLayer_BIONIC_framegen.json"
diff --git a/vendor/bionic-fg/.gitignore b/vendor/bionic-fg/.gitignore
index b7cc55f..9cd38b9 100644
--- a/vendor/bionic-fg/.gitignore
+++ b/vendor/bionic-fg/.gitignore
@@ -1,4 +1,5 @@
build/
+dist/
.cxx/
.gradle/
.DS_Store
diff --git a/vendor/bionic-fg/CMakeLists.txt b/vendor/bionic-fg/CMakeLists.txt
index 5b2a8d5..e271a46 100644
--- a/vendor/bionic-fg/CMakeLists.txt
+++ b/vendor/bionic-fg/CMakeLists.txt
@@ -6,18 +6,29 @@ set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
-find_library(ANDROID_LIBRARY android)
-find_library(LOG_LIBRARY log)
-find_library(VULKAN_LIBRARY vulkan)
-
-add_library(bionic_fg SHARED
+set(BIONIC_FG_SOURCES
src/session.cpp
- src/jni_bridge.cpp
src/vulkan/vk_impl.cpp
src/framegen_context.cpp
src/vk_layer/layer.cpp
)
+if(ANDROID)
+ find_library(ANDROID_LIBRARY android REQUIRED)
+ find_library(LOG_LIBRARY log REQUIRED)
+ find_library(VULKAN_LIBRARY vulkan REQUIRED)
+ list(APPEND BIONIC_FG_SOURCES src/jni_bridge.cpp)
+elseif(UNIX AND NOT APPLE)
+ find_package(Threads REQUIRED)
+ find_package(Vulkan REQUIRED)
+else()
+ message(FATAL_ERROR "bionic-fg supports Android and glibc/Linux builds only")
+endif()
+
+add_library(bionic_fg SHARED
+ ${BIONIC_FG_SOURCES}
+)
+
target_include_directories(bionic_fg
PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/include
@@ -31,11 +42,16 @@ target_compile_options(bionic_fg PRIVATE
-fdata-sections
)
-target_link_libraries(bionic_fg
- ${ANDROID_LIBRARY}
- ${LOG_LIBRARY}
- ${VULKAN_LIBRARY}
-)
+if(ANDROID)
+ target_link_libraries(bionic_fg
+ ${ANDROID_LIBRARY}
+ ${LOG_LIBRARY}
+ ${VULKAN_LIBRARY}
+ )
+else()
+ target_compile_definitions(bionic_fg PRIVATE BFG_GLIBC=1)
+ target_link_libraries(bionic_fg PRIVATE Vulkan::Vulkan Threads::Threads dl)
+endif()
target_link_options(bionic_fg PRIVATE
-Wl,--gc-sections
diff --git a/vendor/bionic-fg/README.md b/vendor/bionic-fg/README.md
index 004dbfd..d8dfee0 100644
--- a/vendor/bionic-fg/README.md
+++ b/vendor/bionic-fg/README.md
@@ -63,6 +63,36 @@ cmake -S . -B build/android-arm64 \
cmake --build build/android-arm64 -j
```
+### Linux / glibc x86_64
+
+The glibc target omits the Android JNI and AHardwareBuffer entry points and
+uses the layer's single-device path with device-local Vulkan images. It still
+uses the same embedded shader graph and implicit-layer interception points.
+
+On an x86_64 Linux system with a C++17 compiler, Vulkan headers/loader, CMake,
+and pthreads installed:
+
+```sh
+./build-linux-x86_64.sh
+```
+
+The output is staged at `dist/linux-x86_64/`:
+
+```text
+libbionic_fg.so
+VkLayer_BIONIC_framegen.json
+```
+
+The manifest is intended for:
+
+```text
+~/.local/lib/libbionic_fg.so
+~/.local/share/vulkan/implicit_layer.d/VkLayer_BIONIC_framegen.json
+```
+
+Enable the layer for a test process with `BIONIC_FG_ENABLE=1` and point
+`BIONIC_FG_CONFIG` at a compatible `conf.toml` as described above.
+
## Shaders
The compute shaders are a clean-room reimplementation of the shader *code*:
diff --git a/vendor/bionic-fg/build-linux-x86_64.sh b/vendor/bionic-fg/build-linux-x86_64.sh
new file mode 100755
index 0000000..91a3b26
--- /dev/null
+++ b/vendor/bionic-fg/build-linux-x86_64.sh
@@ -0,0 +1,29 @@
+#!/usr/bin/env bash
+set -euo pipefail
+
+ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
+BUILD_DIR="${BIONIC_FG_BUILD_DIR:-$ROOT_DIR/build/linux-x86_64}"
+OUTPUT_DIR="${BIONIC_FG_OUTPUT_DIR:-$ROOT_DIR/dist/linux-x86_64}"
+
+if [[ -f "$BUILD_DIR/CMakeCache.txt" ]]; then
+ cached_source="$(sed -n 's/^CMAKE_HOME_DIRECTORY:INTERNAL=//p' "$BUILD_DIR/CMakeCache.txt")"
+ if [[ "$cached_source" != "$ROOT_DIR" ]]; then
+ rm -rf "$BUILD_DIR"
+ fi
+fi
+
+cmake -S "$ROOT_DIR" -B "$BUILD_DIR" \
+ -DCMAKE_BUILD_TYPE=Release
+cmake --build "$BUILD_DIR" \
+ --parallel "${CMAKE_BUILD_PARALLEL_LEVEL:-$(getconf _NPROCESSORS_ONLN 2>/dev/null || printf '2')}"
+
+mkdir -p "$OUTPUT_DIR"
+rm -f "$OUTPUT_DIR/libbionic_fg.so" "$OUTPUT_DIR/VkLayer_BIONIC_framegen.json"
+cp "$BUILD_DIR/libbionic_fg.so" "$OUTPUT_DIR/libbionic_fg.so"
+cp "$ROOT_DIR/VkLayer_BIONIC_framegen.json" "$OUTPUT_DIR/VkLayer_BIONIC_framegen.json"
+
+if command -v file >/dev/null 2>&1; then
+ file "$OUTPUT_DIR/libbionic_fg.so"
+fi
+printf 'Library: %s\nManifest: %s\n' \
+ "$OUTPUT_DIR/libbionic_fg.so" "$OUTPUT_DIR/VkLayer_BIONIC_framegen.json"
diff --git a/vendor/bionic-fg/src/framegen_context.cpp b/vendor/bionic-fg/src/framegen_context.cpp
index 47ef48e..f55fe45 100644
--- a/vendor/bionic-fg/src/framegen_context.cpp
+++ b/vendor/bionic-fg/src/framegen_context.cpp
@@ -160,6 +160,7 @@ static Pass makeModel1Pass(const vk::Device& dev,
// ─── FramegenContext::create ─────────────────────────────────────────────────
+#if defined(__ANDROID__) || defined(BFG_GLIBC)
#ifdef __ANDROID__
std::unique_ptr<FramegenContext> FramegenContext::create(
const vk::Device& device,
@@ -179,11 +180,23 @@ std::unique_ptr<FramegenContext> FramegenContext::create(
BFG_LOGE("FramegenContext::create: mismatched input AHBs or empty outputs");
return nullptr;
}
+#else
+std::unique_ptr<FramegenContext> FramegenContext::create(
+ const vk::Device& device,
+ uint32_t provisionedOutputs,
+ VkExtent2D extent, VkFormat format, const Config& cfg) {
+ if (provisionedOutputs == 0) {
+ BFG_LOGE("FramegenContext::create: no output images provisioned");
+ return nullptr;
+ }
+#endif
auto ctx = std::make_unique<FramegenContext>();
ctx->cfg_ = cfg; ctx->cfg_.sanitize();
ctx->extent_ = extent; ctx->format_ = format;
+#ifdef __ANDROID__
ctx->prevAhbPtr_ = prevAhb;
ctx->currAhbPtr_ = currAhb;
+#endif
const uint32_t W = extent.width, H = extent.height;
const uint32_t outputs = ctx->cfg_.multiplier - 1;
@@ -211,6 +224,7 @@ std::unique_ptr<FramegenContext> FramegenContext::create(
ahbInfo.usage = VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_SAMPLED_BIT
| VK_IMAGE_USAGE_TRANSFER_SRC_BIT
| VK_IMAGE_USAGE_TRANSFER_DST_BIT;
+#ifdef __ANDROID__
ctx->prevFrame_ = prevAhb ? vk::Image(ctx->device_, ahbInfo, prevAhb)
: vk::Image(ctx->device_, ahbInfo);
ctx->currFrame_ = currAhb ? vk::Image(ctx->device_, ahbInfo, currAhb)
@@ -220,6 +234,13 @@ std::unique_ptr<FramegenContext> FramegenContext::create(
ctx->outputImages_.emplace_back(
ahb ? vk::Image(ctx->device_, ahbInfo, ahb)
: vk::Image(ctx->device_, ahbInfo));
+#else
+ ctx->prevFrame_ = vk::Image(ctx->device_, ahbInfo);
+ ctx->currFrame_ = vk::Image(ctx->device_, ahbInfo);
+ ctx->outputImages_.reserve(provisionedOutputs);
+ for (uint32_t i = 0; i < provisionedOutputs; ++i)
+ ctx->outputImages_.emplace_back(ctx->device_, ahbInfo);
+#endif
if (!useModel1)
ctx->dbgFlowBuf_ = vk::Buffer(ctx->device_, kDbgProbeTexels * 8u * kDbgProbeFields,
@@ -265,7 +286,7 @@ std::unique_ptr<FramegenContext> FramegenContext::create(
std::max(1u, (e.height + 15u) / 16u)};
};
auto dLabel = [](int dispatch, int binding) -> std::string {
- char buf[16];
+ char buf[32];
std::snprintf(buf, sizeof(buf), "d%03d.b%d", dispatch, binding);
return std::string(buf);
};
@@ -577,10 +598,13 @@ void FramegenContext::rebindFrameInputs() {
void FramegenContext::swapFrameInputs() {
std::swap(prevFrame_, currFrame_);
+#ifdef __ANDROID__
std::swap(prevAhbPtr_, currAhbPtr_);
+#endif
rebindFrameInputs();
}
+#ifdef __ANDROID__
void FramegenContext::present(AHardwareBuffer* newPrev, AHardwareBuffer* newCurr) {
if (newPrev && newCurr && (newPrev != prevAhbPtr_ || newCurr != currAhbPtr_)) {
if (newPrev == currAhbPtr_ && newCurr == prevAhbPtr_) {
@@ -589,6 +613,9 @@ void FramegenContext::present(AHardwareBuffer* newPrev, AHardwareBuffer* newCurr
BFG_LOGW("FramegenContext::present: unexpected AHB input order; using existing descriptors");
}
}
+#else
+void FramegenContext::present() {
+#endif
const uint32_t W = extent_.width, H = extent_.height;
const uint32_t fi = frameIdx_ & 1u;
@@ -750,7 +777,7 @@ void FramegenContext::present(AHardwareBuffer* newPrev, AHardwareBuffer* newCurr
frameIdx_++;
}
-#endif // __ANDROID__
+#endif // __ANDROID__ || BFG_GLIBC
void FramegenContext::updateConfig(const Config& cfg) {
Config next = cfg; next.sanitize();
diff --git a/vendor/bionic-fg/src/framegen_context.hpp b/vendor/bionic-fg/src/framegen_context.hpp
index ab64fcd..4fd10d5 100644
--- a/vendor/bionic-fg/src/framegen_context.hpp
+++ b/vendor/bionic-fg/src/framegen_context.hpp
@@ -62,6 +62,7 @@ class FramegenContext {
public:
FramegenContext() = default;
+#if defined(__ANDROID__) || defined(BFG_GLIBC)
#ifdef __ANDROID__
// `device` is the application's own VkDevice (wrapped, not owned). Running
// the interpolation on the SAME device the swapchain/AHBs live on avoids the
@@ -77,6 +78,7 @@ public:
VkExtent2D extent,
VkFormat format,
const Config& cfg);
+#endif
// Single-device layer mode: the context owns device-local input/output
// images (no AHB round-trip, no external queue-family transfers); the
@@ -88,8 +90,13 @@ public:
VkFormat format,
const Config& cfg);
+#ifdef __ANDROID__
void present(AHardwareBuffer* newPrevAhb, AHardwareBuffer* newCurrAhb);
void run() { present(nullptr, nullptr); }
+#else
+ void present();
+ void run() { present(); }
+#endif
// Rotate frame inputs after a presented frame: the previous "current"
// becomes "previous" and its image is reused as the next blit target.
@@ -161,6 +168,8 @@ private:
#ifdef __ANDROID__
AHardwareBuffer* prevAhbPtr_ = nullptr;
AHardwareBuffer* currAhbPtr_ = nullptr;
+#endif
+#if defined(__ANDROID__) || defined(BFG_GLIBC)
void rebindFrameInputs();
#endif
};
diff --git a/vendor/bionic-fg/src/vk_layer/layer.cpp b/vendor/bionic-fg/src/vk_layer/layer.cpp
index 65bc6d6..e9ca742 100644
--- a/vendor/bionic-fg/src/vk_layer/layer.cpp
+++ b/vendor/bionic-fg/src/vk_layer/layer.cpp
@@ -42,8 +42,9 @@
#define BFG_LAYER(...) __android_log_print(ANDROID_LOG_INFO, BFG_LAYER_NAME, __VA_ARGS__)
#define BFG_LAYER_E(...) __android_log_print(ANDROID_LOG_ERROR, BFG_LAYER_NAME, __VA_ARGS__)
#else
-#define BFG_LAYER(...)
-#define BFG_LAYER_E(...)
+#include <cstdio>
+#define BFG_LAYER(...) do { std::fprintf(stderr, "[BionicFG] " __VA_ARGS__); std::fputc('\n', stderr); } while (0)
+#define BFG_LAYER_E(...) do { std::fprintf(stderr, "[BionicFG] ERROR: " __VA_ARGS__); std::fputc('\n', stderr); } while (0)
#endif
#if defined(__GNUC__)
@@ -376,7 +377,7 @@ struct SwapState {
std::vector<VkImage> images;
LayerConf conf;
-#ifdef __ANDROID__
+#if defined(__ANDROID__) || defined(BFG_GLIBC)
// Provisioned generated-frame slots the context is (re)built with, so a
// 2x..4x multiplier hot-reload never needs an app-side swapchain rebuild.
uint32_t provisionedOutputs = 0;
@@ -521,11 +522,13 @@ static bionic_fg::Config makeFramegenConfig(const SwapState& st, const LayerConf
return cfg;
}
-#ifdef __ANDROID__
+#if defined(__ANDROID__) || defined(BFG_GLIBC)
static std::unique_ptr<bionic_fg::FramegenContext> createFramegenContext(
const SwapState& st,
const LayerConf& conf) {
+#ifdef __ANDROID__
DisableLayerEnvGuard disableLayerForInternalVulkan;
+#endif
// Wrap the application's own device (not owned) so interpolation runs on the
// same device as the swapchain — single-device mode with context-owned
// device-local frame images (no AHB round-trip).
@@ -687,6 +690,7 @@ VKAPI_ATTR VkResult VKAPI_CALL BionicFG_EnumeratePhysicalDevices(
// ─── CreateDevice ─────────────────────────────────────────────────────────────
+#ifdef __ANDROID__
static const char* kAhbExts[] = {
"VK_ANDROID_external_memory_android_hardware_buffer",
"VK_KHR_external_memory",
@@ -696,6 +700,7 @@ static const char* kAhbExts[] = {
"VK_KHR_bind_memory2",
"VK_KHR_maintenance1",
};
+#endif
VKAPI_ATTR VkResult VKAPI_CALL BionicFG_CreateDevice(
VkPhysicalDevice physicalDevice,
@@ -714,7 +719,9 @@ VKAPI_ATTR VkResult VKAPI_CALL BionicFG_CreateDevice(
const_cast<VkLayerDeviceCreateInfo*>(linkInfo)->u.pLayerInfo =
linkInfo->u.pLayerInfo->pNext;
- // Inject AHB extensions if not present (needed for cross-device sharing)
+ VkDeviceCreateInfo dci = *pCreateInfo;
+#ifdef __ANDROID__
+ // Inject AHB extensions if not present (needed for cross-device sharing).
std::vector<const char*> exts(
pCreateInfo->ppEnabledExtensionNames,
pCreateInfo->ppEnabledExtensionNames + pCreateInfo->enabledExtensionCount);
@@ -723,9 +730,9 @@ VKAPI_ATTR VkResult VKAPI_CALL BionicFG_CreateDevice(
for (const char* x : exts) if (std::strcmp(x, e) == 0) { found = true; break; }
if (!found) exts.push_back(e);
}
- VkDeviceCreateInfo dci = *pCreateInfo;
dci.enabledExtensionCount = static_cast<uint32_t>(exts.size());
dci.ppEnabledExtensionNames = exts.data();
+#endif
// Look up the real instance that produced this physical device.
VkInstance instance = VK_NULL_HANDLE;
@@ -1079,7 +1086,7 @@ VKAPI_ATTR VkResult VKAPI_CALL BionicFG_CreateSwapchainKHR(
return VK_SUCCESS;
}
-#ifdef __ANDROID__
+#if defined(__ANDROID__) || defined(BFG_GLIBC)
auto stHolder = std::make_unique<SwapState>();
SwapState& st = *stHolder;
st.device = device;
@@ -1580,7 +1587,7 @@ VKAPI_ATTR VkResult VKAPI_CALL BionicFG_QueuePresentKHR(
return VK_ERROR_OUT_OF_DATE_KHR;
}
-#ifdef __ANDROID__
+#if defined(__ANDROID__) || defined(BFG_GLIBC)
const bool oldActive = oldConf.multiplier >= 2;
const bool newActive = newConf.multiplier >= 2;
@@ -1647,7 +1654,7 @@ VKAPI_ATTR VkResult VKAPI_CALL BionicFG_QueuePresentKHR(
if (!st.inPresent && effFpsLimit > 0) {
const int64_t targetNs = 1000000000LL / effFpsLimit;
const int64_t now = nowNs();
-#ifdef __ANDROID__
+#if defined(__ANDROID__) || defined(BFG_GLIBC)
paceDeferred = st.conf.enabled && !st.framegenForceDisabled && st.fgCtx &&
st.conf.multiplier >= 2 && st.frameCount > 0;
#endif
@@ -1733,7 +1740,7 @@ VKAPI_ATTR VkResult VKAPI_CALL BionicFG_QueuePresentKHR(
return callNextPresent(queue, pPresentInfo);
}
-#ifndef __ANDROID__
+#if !defined(__ANDROID__) && !defined(BFG_GLIBC)
return callNextPresent(queue, pPresentInfo);
#else
st.inPresent = true;