Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 26 additions & 2 deletions .github/workflows/ios-bundle.yml
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,24 @@ jobs:
- name: Install host build tools (Homebrew)
run: brew install meson ninja pkgconf cmake

- name: The guest's Vulkan for iOS (hackios-xnu-kernel tools/gfxstream/mk-vk.sh ios; it needs Xcode's clang)
env:
KERNEL_REF: ${{ inputs.kernel_ref }}
run: |
git clone -q --filter=blob:none https://github.com/Scion-Project/hackios-xnu-kernel.git "$RUNNER_TEMP/k"
git -C "$RUNNER_TEMP/k" checkout -q "$KERNEL_REF"
VK_BUILD="$RUNNER_TEMP/vk" bash "$RUNNER_TEMP/k/tools/gfxstream/mk-vk.sh" ios
mkdir -p "$RUNNER_TEMP/vk-out"
cp "$RUNNER_TEMP/vk/out-ios/libhakios.vk.dylib" "$RUNNER_TEMP/vk/out-ios/vk_test" "$RUNNER_TEMP/vk-out/"
ls -la "$RUNNER_TEMP/vk-out"

- uses: actions/upload-artifact@v4.6.0
with:
name: scion-vk-for-bundle
path: ${{ runner.temp }}/vk-out
if-no-files-found: error
retention-days: 1

- name: Point Gradle at the SDK
run: echo "sdk.dir=$ANDROID_SDK_ROOT" > local.properties

Expand Down Expand Up @@ -232,12 +250,18 @@ jobs:
working-directory: /mnt/w/k
run: avf/shim/build.sh && ls -la avf/shim/out/Image

- name: The small root and the system image (userland/build.sh GL=gfx REST=1)
- uses: actions/download-artifact@v4
with:
name: scion-vk-for-bundle
path: /mnt/w/vk

- name: The small root and the system image (userland/build.sh GL=gfx REST=1, with the guest's Vulkan)
working-directory: /mnt/w/k
run: |
(source ./xnu-env.sh && cd userland && GL=gfx REST=1 bash build.sh) > "$W/userland.log" 2>&1 ||
(source ./xnu-env.sh && cd userland && GL=gfx REST=1 VK_DIR="$W/vk" bash build.sh) > "$W/userland.log" 2>&1 ||
{ tail -100 "$W/userland.log"; exit 1; }
tail -5 "$W/userland.log"
grep -a 'guest.s Vulkan' "$W/userland.log" || { echo "::error::the root has no Vulkan library"; exit 1; }
ls -la userland/root.apfs userland/system.apfs

- uses: actions/download-artifact@v4
Expand Down
42 changes: 34 additions & 8 deletions app/src/main/cpp/scgpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -128,9 +128,21 @@ struct sr_fence { uint32_t flags; uint64_t fence_id; uint32_t ctx_id; uint8_t ri
#define SR_PARAM_FENCE_CALLBACK 3
#define SR_PARAM_WIN0_WIDTH 4
#define SR_PARAM_WIN0_HEIGHT 5
#define SR_PARAM_RENDERER_FEATURES 11
#define SR_FLAGS_USE_EGL (1u << 0)
#define SR_FLAGS_SURFACELESS (1u << 3)
#define SR_FLAGS_USE_GLES (1u << 4)
#define SR_FLAGS_USE_VK (1u << 5)
#define CAPSET_GFXSTREAM_VULKAN 3

/*
* Vulkan for the guest (hackios-xnu-kernel tools/gfxstream/VULKAN.md): gfxstream's Vulkan decoder on the phone's
* own driver, the guest's Vulkan stream on the same pipe as its GL. The guest cannot map host memory here, so
* host-visible memory is a guest copy moved on flush and invalidate: VirtioGpuNext off, and no insistence on a
* coherent cached memory type, which that leaves none of. On by default; debug.scion.vk=0 turns it off, and a
* renderer that will not start with it starts as before, GL alone.
*/
static const char vk_features[] = "VirtioGpuNext:disabled,VulkanEnsureCachedCoherentMemoryAvailable:disabled";

static struct {
int (*init)(struct sr_param *, uint64_t);
Expand Down Expand Up @@ -159,7 +171,7 @@ static struct {
volatile struct scgpu_header *h;
int fb_w, fb_h;
pthread_t thread;
int running, renderer_up;
int running, renderer_up, vulkan;
volatile int stop;
pthread_mutex_t window_lock;
ANativeWindow *window;
Expand Down Expand Up @@ -348,14 +360,15 @@ handle_cmd(const uint8_t *cmd, uint32_t len, uint32_t max, uint8_t *resp)
struct resp_capset_info r;
NEED(c);
memcpy(&c, cmd, sizeof(c));
if (c.capset_index != 0) {
err = -ENOENT; /* one capset: gfxstream's GLES */
/* gfxstream's GLES, then its Vulkan when the renderer has it */
if (c.capset_index > (S.vulkan ? 1u : 0u)) {
err = -ENOENT;
break;
}
memset(&r, 0, sizeof(r));
r.hdr.type = RESP_OK_CAPSET_INFO;
r.capset_id = CAPSET_GFXSTREAM_GLES;
sr.get_cap_set(CAPSET_GFXSTREAM_GLES, &r.capset_max_version, &r.capset_max_size);
r.capset_id = c.capset_index == 0 ? CAPSET_GFXSTREAM_GLES : CAPSET_GFXSTREAM_VULKAN;
sr.get_cap_set(r.capset_id, &r.capset_max_version, &r.capset_max_size);
memcpy(resp, &r, sizeof(r));
return sizeof(r);
}
Expand Down Expand Up @@ -857,27 +870,40 @@ Java_io_github_dylanneve1_iosonpixel_avf_ScgpuNative_start(JNIEnv *env, jclass c
return -1;
}
if (!S.renderer_up) {
char vk_prop[PROP_VALUE_MAX] = "";
int vk = !(__system_property_get("debug.scion.vk", vk_prop) > 0 && vk_prop[0] == '0');
struct sr_param params[] = {
{ SR_PARAM_USER_DATA, 0 },
{ SR_PARAM_RENDERER_FLAGS, SR_FLAGS_USE_EGL | SR_FLAGS_SURFACELESS | SR_FLAGS_USE_GLES },
{ SR_PARAM_RENDERER_FLAGS, SR_FLAGS_USE_EGL | SR_FLAGS_SURFACELESS | SR_FLAGS_USE_GLES |
(vk ? SR_FLAGS_USE_VK : 0) },
{ SR_PARAM_FENCE_CALLBACK, (uint64_t)(uintptr_t)fence_cb },
{ SR_PARAM_WIN0_WIDTH, (uint64_t)fb_w },
{ SR_PARAM_WIN0_HEIGHT, (uint64_t)fb_h },
{ SR_PARAM_RENDERER_FEATURES, (uint64_t)(uintptr_t)vk_features }, /* last: dropped without Vulkan */
};
int rc = sr.init(params, sizeof(params) / sizeof(params[0]));
uint64_t n = sizeof(params) / sizeof(params[0]) - (vk ? 0 : 1);
int rc = sr.init(params, n);
if (rc != 0 && vk) {
ERR("stream_renderer_init with Vulkan: %d; starting it again for GL alone", rc);
vk = 0;
params[1].value &= ~(uint64_t)SR_FLAGS_USE_VK;
rc = sr.init(params, n - 1);
}
if (rc != 0) {
ERR("stream_renderer_init: %d", rc);
return -4;
}
LOG("renderer up: GL%s", vk ? " and Vulkan" : " (Vulkan off: debug.scion.vk=0, or it would not start)");
S.renderer_up = 1;
S.vulkan = vk;
}
S.h = (volatile struct scgpu_header *)S.base;
memset(S.base, 0, SCGPU_POOL_OFF);
S.h->magic = SCGPU_MAGIC;
S.h->version = SCGPU_VERSION;
S.h->size = S.size;
S.h->features_lo = (1u << F_VIRGL) | (1u << F_CONTEXT_INIT);
S.h->num_capsets = 1;
S.h->num_capsets = S.vulkan ? 2 : 1;
S.commands = S.errors = S.busy_ns = 0;
S.rings_in = S.rings_out = S.sleeps = 0;
S.records = S.record_bytes = 0;
Expand Down
Loading