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
11 changes: 9 additions & 2 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,14 @@ jobs:
steps:
- name: Install dependencies
run: |
brew install autoconf automake libtool pkg-config check cmake sdl3
brew install autoconf automake libtool pkg-config check cmake

- name: Build SDL3
run: |
git clone --depth 1 --branch ObjectivelyGPU https://github.com/jdolan/SDL.git SDL3
cmake -S SDL3 -B SDL3/build -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=${HOMEBREW_PREFIX}
cmake --build SDL3/build -j$(sysctl -n hw.logicalcpu)
cmake --install SDL3/build

- name: Checkout Objectively
uses: actions/checkout@v6
Expand Down Expand Up @@ -67,7 +74,7 @@ jobs:

- name: Build SDL3
run: |
git clone --depth 1 --branch release-3.4.12 https://github.com/libsdl-org/SDL.git SDL3
git clone --depth 1 --branch ObjectivelyGPU https://github.com/jdolan/SDL.git SDL3
cmake -S SDL3 -B SDL3/build -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr/local
cmake --build SDL3/build -j$(nproc)
sudo cmake --install SDL3/build
Expand Down
4 changes: 1 addition & 3 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ permissions:
env:
# Objectively is a source dependency (resolved via ObjectivelyGPU.xcworkspace).
# Override to point a GPU release/branch at a specific Objectively ref.
# SDL3 / curl versions live in fetch-sdl3.sh / build-libcurl.sh, not here.
# SDL3 is the jdolan/SDL ObjectivelyGPU tag (fetch-sdl3.sh); curl lives in build-libcurl.sh.
OBJECTIVELY_REF: "main"

jobs:
Expand Down Expand Up @@ -82,7 +82,6 @@ jobs:
- name: Zip xcframeworks
working-directory: ObjectivelyGPU/Frameworks
run: |
zip -r "$GITHUB_WORKSPACE/SDL3.xcframework.zip" SDL3.xcframework
zip -r "$GITHUB_WORKSPACE/ObjectivelyGPU.xcframework.zip" ObjectivelyGPU.xcframework

- name: Create release
Expand All @@ -92,7 +91,6 @@ jobs:
gh release create ${{ github.ref_name }} \
--title "ObjectivelyGPU ${{ github.ref_name }}" \
--generate-notes \
"$GITHUB_WORKSPACE/SDL3.xcframework.zip" \
"$GITHUB_WORKSPACE/ObjectivelyGPU.xcframework.zip"
env:
GH_TOKEN: ${{ github.token }}
24 changes: 24 additions & 0 deletions Documentation/install.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,30 @@ Tagged releases are published on the [GitHub releases page](https://github.com/j
* [Objectively](https://github.com/jdolan/Objectively) >= 2.0.0
* [SDL3](https://github.com/libsdl-org/SDL) >= 3.2.0

### SDL3 and occlusion queries

`QueryPool` requires the SDL_gpu query API (`SDL_GPU_QUERY_API`), which upstream SDL does not ship yet. The
`ObjectivelyGPU` tag in [jdolan/SDL](https://github.com/jdolan/SDL) carries it, and CI for ObjectivelyGPU,
ObjectivelyMVC and Quetoo MUST build against that tag. Against any other SDL3, ObjectivelyGPU still builds, but
`QueryPool.c` emits a compiler warning and occlusion queries are disabled.

* Linux and macOS (autotools): build SDL from source with
`git clone --branch ObjectivelyGPU https://github.com/jdolan/SDL.git`.
* macOS and iOS (Xcode): `Frameworks/fetch-sdl3.sh` downloads `SDL3.xcframework` from the tag's release. It
records the tag's commit, and downloads again if the tag moves.
* Windows (Visual Studio): `ObjectivelyGPU.vs15/sdl3.targets` downloads `SDL3-devel-VC.zip` from the tag's
release on first build. Delete `ObjectivelyGPU.vs15/libs/` to pick up a moved tag.

To change the SDL3 revision for the whole stack, move the tag, then publish its artifacts. The publish run
MUST finish before any consumer builds, because until then the release still serves the previous assets.
`fetch-sdl3.sh` refuses a release that was built from another commit.

```sh
git tag -f ObjectivelyGPU <rev> && git push -f origin ObjectivelyGPU
gh workflow run objectivelygpu.yml -R jdolan/SDL
gh run watch -R jdolan/SDL --exit-status "$(gh run list -R jdolan/SDL -w objectivelygpu.yml -L 1 --json databaseId -q '.[0].databaseId')"
```

## Building

```sh
Expand Down
62 changes: 34 additions & 28 deletions Frameworks/fetch-sdl3.sh
Original file line number Diff line number Diff line change
@@ -1,40 +1,44 @@
#!/usr/bin/env bash
#
# fetch-sdl3.sh — downloads the official SDL3 Apple xcframework from libsdl.org
# on demand and caches it under Frameworks/.
# fetch-sdl3.sh — downloads SDL3.xcframework from the jdolan/SDL release for SDL3_TAG and caches it
# under Frameworks/.
#
# This mirrors the Windows VS build (ObjectivelyGPU.vs15/sdl3.targets): CI and
# local developers share a single code path. The download is cached at
# Frameworks/SDL3.xcframework.stable, and Frameworks/SDL3.xcframework is a
# symlink to it. This indirection lets link-sdl3-local.sh (and use-sdl3.sh)
# repoint that same symlink at a locally-built SDL3 checkout without disturbing
# this cache. Bump SDL3_VERSION to upgrade; delete
# Frameworks/SDL3.xcframework.stable to force a re-download.
# The whole stack (ObjectivelyGPU, ObjectivelyMVC, Quetoo) pins SDL3 to one tag in jdolan/SDL, which
# carries the SDL_gpu query API. The tag's commit SHA is stored next to the cache, so moving the tag
# causes a new download. The release notes name the commit its assets were built from; if that is
# not the tag's commit, the publish workflow has not run for the moved tag yet, and this script
# fails. This mirrors ObjectivelyGPU.vs15/sdl3.targets on Windows.
#
set -euo pipefail

SDL3_VERSION="${SDL3_VERSION:-3.4.2}"
SDL3_REPO="${SDL3_REPO:-jdolan/SDL}"
SDL3_TAG="${SDL3_TAG:-ObjectivelyGPU}"

SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
STABLE="$SCRIPT_DIR/SDL3.xcframework.stable"
XCFRAMEWORK="$SCRIPT_DIR/SDL3.xcframework"
STAMP="$SCRIPT_DIR/SDL3.xcframework.sha"

# Migrate a pre-existing plain directory (from before the .stable split) in place.
if [ -d "$XCFRAMEWORK" ] && [ ! -L "$XCFRAMEWORK" ]; then
mv "$XCFRAMEWORK" "$STABLE"
sha="$(git ls-remote "https://github.com/$SDL3_REPO.git" "refs/tags/$SDL3_TAG" "refs/tags/$SDL3_TAG^{}" | tail -1 | cut -f1)"
if [ -z "$sha" ]; then
echo "error: tag $SDL3_TAG not found in $SDL3_REPO" >&2
exit 1
fi

# Point the symlink at the stable cache, creating/replacing it as needed.
relink() {
ln -sfn "$(basename "$STABLE")" "$XCFRAMEWORK"
cached() {
[ -d "$XCFRAMEWORK" ] && [ ! -L "$XCFRAMEWORK" ] && [ "$(cat "$STAMP" 2>/dev/null)" = "$sha" ]
}

# Already cached? Just make sure the symlink points at it and we're done.
if [ -d "$STABLE" ]; then
relink
if cached; then
exit 0
fi

released="$(curl -fsSL "https://api.github.com/repos/$SDL3_REPO/releases/tags/$SDL3_TAG" | grep -Eo 'at [0-9a-f]{40}' | head -1 | cut -c4- || true)"
if [ "$released" != "$sha" ]; then
echo "error: the $SDL3_TAG release of $SDL3_REPO was built from ${released:-an unknown commit}, not $sha" >&2
echo "error: run: gh workflow run objectivelygpu.yml -R $SDL3_REPO" >&2
exit 1
fi

# Serialize concurrent invocations (parallel target builds) on a lock dir,
# the shell equivalent of the Global mutex used by sdl3.targets on Windows.
LOCK="$SCRIPT_DIR/.sdl3.lock"
Expand All @@ -53,17 +57,16 @@ cleanup() {
trap cleanup EXIT

# Re-check after acquiring the lock; another build may have just finished.
if [ -d "$STABLE" ]; then
relink
if cached; then
exit 0
fi

DMG_URL="https://github.com/libsdl-org/SDL/releases/download/release-$SDL3_VERSION/SDL3-$SDL3_VERSION.dmg"
DMG_URL="https://github.com/$SDL3_REPO/releases/download/$SDL3_TAG/SDL3.dmg"

echo "==> Downloading SDL3 $SDL3_VERSION"
echo "==> Downloading SDL3 $SDL3_REPO@$SDL3_TAG ($sha)"
curl -fL --retry 3 "$DMG_URL" -o "$TMP/SDL3.dmg"

echo "==> Mounting SDL3 $SDL3_VERSION"
echo "==> Mounting SDL3.dmg"
mkdir -p "$MNT"
hdiutil attach "$TMP/SDL3.dmg" -nobrowse -quiet -mountpoint "$MNT"

Expand All @@ -73,8 +76,11 @@ if [ -z "$src" ]; then
exit 1
fi

# Replace the cache, and the .stable/.local directories of the former use-sdl3.sh layout.
echo "==> Caching SDL3.xcframework"
cp -R "$src" "$STABLE"
relink
rm -f "$STAMP"
rm -rf "$XCFRAMEWORK" "$SCRIPT_DIR/SDL3.xcframework.stable" "$SCRIPT_DIR/SDL3.xcframework.local"
cp -R "$src" "$XCFRAMEWORK"
echo "$sha" > "$STAMP"
Comment thread
jdolan marked this conversation as resolved.

echo "==> SDL3.xcframework $SDL3_VERSION ready at Frameworks/SDL3.xcframework"
echo "==> SDL3.xcframework $SDL3_TAG ready at Frameworks/SDL3.xcframework"
82 changes: 0 additions & 82 deletions Frameworks/link-sdl3-local.sh

This file was deleted.

50 changes: 0 additions & 50 deletions Frameworks/use-sdl3.sh

This file was deleted.

19 changes: 10 additions & 9 deletions ObjectivelyGPU.vs15/sdl3.targets
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,16 @@
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

<!--
Fetches the official SDL3 VC development libraries from libsdl.org and wires
them into the compiler and linker search paths. This mirrors what CI does,
so local developers and CI share a single code path: the libraries are
downloaded once, on demand, and cached under libs/ (which is .gitignored).
Bump SDL3Version to upgrade; delete libs/ to force a re-download.
Fetches the SDL3 VC development libraries from the jdolan/SDL release for
SDL3Tag and wires them into the compiler and linker search paths. The
whole stack pins SDL3 to this tag, which carries the SDL_gpu query API.
This mirrors what CI does, so local developers and CI share a single code
path: the libraries are downloaded once, on demand, and cached under libs/
(which is .gitignored). Delete libs/ to pick up a moved tag.
-->
<PropertyGroup>
<SDL3Version>3.4.12</SDL3Version>
<SDL3Dir>$(MSBuildThisFileDirectory)libs\SDL3-$(SDL3Version)\</SDL3Dir>
<SDL3Tag>ObjectivelyGPU</SDL3Tag>
<SDL3Dir>$(MSBuildThisFileDirectory)libs\SDL3-$(SDL3Tag)\</SDL3Dir>
<SDL3LibArch Condition="'$(Platform)' == 'Win32'">x86</SDL3LibArch>
<SDL3LibArch Condition="'$(SDL3LibArch)' == ''">x64</SDL3LibArch>
</PropertyGroup>
Expand All @@ -23,9 +24,9 @@
<Target Name="DownloadSDL3"
BeforeTargets="ClCompile"
Condition="!Exists('$(SDL3Dir)include\SDL3\SDL.h')">
<Message Importance="high" Text="Downloading SDL3 $(SDL3Version) development libraries..." />
<Message Importance="high" Text="Downloading SDL3 $(SDL3Tag) development libraries..." />
<Exec WorkingDirectory="$(MSBuildThisFileDirectory)"
Command="powershell -NoProfile -ExecutionPolicy Bypass -Command &quot;$ErrorActionPreference = 'Stop'; $m = New-Object System.Threading.Mutex($false, 'Global\ObjectivelySDL3'); [void]$m.WaitOne(); try { if (-not (Test-Path '$(SDL3Dir)include\SDL3\SDL.h')) { New-Item -ItemType Directory -Force libs | Out-Null; Invoke-WebRequest -Uri 'https://github.com/libsdl-org/SDL/releases/download/release-$(SDL3Version)/SDL3-devel-$(SDL3Version)-VC.zip' -OutFile 'libs\sdl3.zip'; Expand-Archive -Force 'libs\sdl3.zip' 'libs'; Remove-Item 'libs\sdl3.zip' } } finally { $m.ReleaseMutex() }&quot;" />
Command="powershell -NoProfile -ExecutionPolicy Bypass -Command &quot;$ErrorActionPreference = 'Stop'; $m = New-Object System.Threading.Mutex($false, 'Global\ObjectivelySDL3'); [void]$m.WaitOne(); try { if (-not (Test-Path '$(SDL3Dir)include\SDL3\SDL.h')) { New-Item -ItemType Directory -Force libs | Out-Null; Invoke-WebRequest -Uri 'https://github.com/jdolan/SDL/releases/download/$(SDL3Tag)/SDL3-devel-VC.zip' -OutFile 'libs\sdl3.zip'; Remove-Item -Recurse -Force -ErrorAction SilentlyContinue 'libs\sdl3'; Expand-Archive -Force 'libs\sdl3.zip' 'libs\sdl3'; $d = %40(Get-ChildItem -Directory 'libs\sdl3'); if ($d.Count -ne 1) { throw 'SDL3-devel-VC.zip: expected one top-level directory' }; Remove-Item -Recurse -Force -ErrorAction SilentlyContinue '$(SDL3Dir.TrimEnd('\'))'; Move-Item $d[0].FullName '$(SDL3Dir.TrimEnd('\'))'; Remove-Item -Recurse 'libs\sdl3', 'libs\sdl3.zip' } } finally { $m.ReleaseMutex() }&quot;" />
</Target>

</Project>
6 changes: 1 addition & 5 deletions ObjectivelyGPU.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -202,8 +202,6 @@
CE1643412FF47B7D00863996 /* guide.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = guide.md; sourceTree = "<group>"; };
CE1643422FF47B7D00863996 /* Hello.gif */ = {isa = PBXFileReference; lastKnownFileType = image.gif; path = Hello.gif; sourceTree = "<group>"; };
CE1643432FF47B7D00863996 /* HelloCompute.gif */ = {isa = PBXFileReference; lastKnownFileType = image.gif; path = HelloCompute.gif; sourceTree = "<group>"; };
CE6049BB30055F5700B1C1E3 /* link-sdl3-local.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; name = "link-sdl3-local.sh"; path = "Frameworks/link-sdl3-local.sh"; sourceTree = "<group>"; };
CE6049BC30055F5700B1C1E3 /* use-sdl3.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; name = "use-sdl3.sh"; path = "Frameworks/use-sdl3.sh"; sourceTree = "<group>"; };
CEA0030000000000000000F0 /* Objectively.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = Objectively.framework; sourceTree = BUILT_PRODUCTS_DIR; };
CEBA3F5E2FF30F1E00758CA6 /* Texture.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Texture.h; sourceTree = "<group>"; };
CEBA3F5F2FF30F1E00758CA6 /* Texture.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = Texture.c; sourceTree = "<group>"; };
Expand All @@ -217,7 +215,7 @@
CEBA3F692FF3211F00758CA6 /* Shader.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Shader.h; sourceTree = "<group>"; };
CEBA3F6A2FF3211F00758CA6 /* Shader.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = Shader.c; sourceTree = "<group>"; };
CEBA3F742FF330A700758CA6 /* ComputePipeline.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = ComputePipeline.c; sourceTree = "<group>"; };
CEBA3F7C2FF36E2300758CA6 /* fetch-sdl3.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = "fetch-sdl3.sh"; sourceTree = "<group>"; };
CEBA3F7C2FF36E2300758CA6 /* fetch-sdl3.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; name = "fetch-sdl3.sh"; path = "Frameworks/fetch-sdl3.sh"; sourceTree = "<group>"; };
CECF83942FEF65EB00CB0CCA /* Makefile.am */ = {isa = PBXFileReference; lastKnownFileType = text; path = Makefile.am; sourceTree = "<group>"; };
CECF83952FEF65FF00CB0CCA /* Makefile.am */ = {isa = PBXFileReference; lastKnownFileType = text; path = Makefile.am; sourceTree = "<group>"; };
CECF83962FEF65FF00CB0CCA /* ObjectivelyGPU.pc.in */ = {isa = PBXFileReference; lastKnownFileType = text; path = ObjectivelyGPU.pc.in; sourceTree = "<group>"; };
Expand Down Expand Up @@ -386,9 +384,7 @@
children = (
CEA0030000000000000000F0 /* Objectively.framework */,
AA000000000000000000EE01 /* SDL3.xcframework */,
CE6049BB30055F5700B1C1E3 /* link-sdl3-local.sh */,
CEBA3F7C2FF36E2300758CA6 /* fetch-sdl3.sh */,
CE6049BC30055F5700B1C1E3 /* use-sdl3.sh */,
);
name = Frameworks;
sourceTree = "<group>";
Expand Down
8 changes: 8 additions & 0 deletions Sources/ObjectivelyGPU/QueryPool.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,14 @@
#include "QueryPool.h"
#include "RenderDevice.h"

#ifndef SDL_GPU_QUERY_API
#if defined(_MSC_VER)
#pragma message("SDL3 lacks SDL_GPU_QUERY_API: occlusion queries are disabled")
#else
#warning "SDL3 lacks SDL_GPU_QUERY_API: occlusion queries are disabled"
#endif
#endif

#define _Class _QueryPool

#pragma mark - Object
Expand Down
Loading
Loading