summaryrefslogtreecommitdiff
path: root/vendor/bionic-fg/src
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 /vendor/bionic-fg/src
parentd859de9a5849f99824ba98a69d6658d9f7724bdf (diff)
downloaddecky-lsfg-vk-agent/bionic-fg-x86_64-experiment.tar.gz
decky-lsfg-vk-agent/bionic-fg-x86_64-experiment.zip
Add bionic-fg glibc x86_64 experimentagent/bionic-fg-x86_64-experiment
Diffstat (limited to 'vendor/bionic-fg/src')
-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
3 files changed, 55 insertions, 12 deletions
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;