Merge branch 'r3d/moltenvk' into lang/foundations
This commit is contained in:
commit
6c663cc87b
9 changed files with 254 additions and 23 deletions
10
changes/render3d-moltenvk.md
Normal file
10
changes/render3d-moltenvk.md
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
bump: minor
|
||||
type: feature
|
||||
**ludic.render3d carries MoltenVK, so a Mac program has its Vulkan driver without the SDK.**
|
||||
`native/build.sh` builds MoltenVK from a pinned tag (v1.4.2, its SHA-256 checked; its own
|
||||
dependencies at the commits its ExternalRevisions pins), thinned to arm64 and signed, into
|
||||
`lib/macos-arm64/libMoltenVK.dylib`, with its licence in `native/LICENSE-MoltenVK`. Every program
|
||||
that imports render3d links it through its rpath - the package's lib/ while developing,
|
||||
`Contents/Frameworks` in a bundle, where `ludic bundle` puts and signs it - and the loader
|
||||
(`vk_mac.ll`) now also looks for `@rpath/libMoltenVK.dylib`. An SDK loader found first still wins,
|
||||
so the validation layer can be stacked in development. `gpu_is_gl()` is gone.
|
||||
|
|
@ -46,8 +46,6 @@ function gpu_select(render3d_st: mut Render3dState) -> int {
|
|||
return render3d_st.gpu_kind
|
||||
}
|
||||
function gpu_backend(render3d_st: Render3dState) -> string { return "vulkan" }
|
||||
# always false now; kept until the game stops asking (maroon-lake src/app/boot_load.ludic)
|
||||
function gpu_is_gl(render3d_st: Render3dState) -> bool { return false }
|
||||
|
||||
# ---- render state ----------------------------------------------------------------
|
||||
# -1 = not known yet: the first set always reaches the driver, so the cache never
|
||||
|
|
|
|||
BIN
packages/ludic.render3d/lib/macos-arm64/libMoltenVK.dylib
(Stored with Git LFS)
Executable file
BIN
packages/ludic.render3d/lib/macos-arm64/libMoltenVK.dylib
(Stored with Git LFS)
Executable file
Binary file not shown.
202
packages/ludic.render3d/native/LICENSE-MoltenVK
Normal file
202
packages/ludic.render3d/native/LICENSE-MoltenVK
Normal file
|
|
@ -0,0 +1,202 @@
|
|||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
25
packages/ludic.render3d/native/build.sh
Executable file
25
packages/ludic.render3d/native/build.sh
Executable file
|
|
@ -0,0 +1,25 @@
|
|||
#!/bin/sh
|
||||
# builds lib/macos-arm64/libMoltenVK.dylib: Vulkan over Metal, which render3d draws with on a Mac.
|
||||
# MoltenVK at a pinned tag, its SHA-256 checked; its dependencies (SPIRV-Cross, SPIRV-Tools,
|
||||
# Vulkan-Headers, ...) come at the commits its own ExternalRevisions pins. Needs Xcode (not only the
|
||||
# command line tools); about fifteen minutes. Windows needs nothing: its drivers install the loader.
|
||||
set -eu
|
||||
PKG="$(cd "$(dirname "$0")/.." && pwd)"
|
||||
. "$PKG/../../tools/native/lib.sh"
|
||||
case "$(native_target)" in macos-*) ;; *) echo "ludic.render3d: nothing to build for $(native_target)"; exit 0 ;; esac
|
||||
MVK_TAG=v1.4.2
|
||||
MVK_SHA=6864db532f1dbbdb621a8d0ec13f24edae318fd9269dd3dd0cdff791334bb1cb
|
||||
SRC="$PKG/build/src/moltenvk-$MVK_TAG"
|
||||
native_fetch "$SRC" "https://github.com/KhronosGroup/MoltenVK/archive/refs/tags/$MVK_TAG.tar.gz" "$MVK_SHA"
|
||||
XCODE="${DEVELOPER_DIR:-/Applications/Xcode.app/Contents/Developer}"
|
||||
( cd "$SRC" && DEVELOPER_DIR="$XCODE" ./fetchDependencies --macos && DEVELOPER_DIR="$XCODE" make macos )
|
||||
OUT="$PKG/lib/$(native_target)"
|
||||
mkdir -p "$OUT"
|
||||
# the release is Apple silicon only: the arm64 slice, found by the executable's rpath
|
||||
lipo "$SRC/Package/Release/MoltenVK/dynamic/dylib/macOS/libMoltenVK.dylib" -thin arm64 -output "$OUT/libMoltenVK.dylib"
|
||||
install_name_tool -id @rpath/libMoltenVK.dylib "$OUT/libMoltenVK.dylib" 2>/dev/null
|
||||
# the id change breaks the signature, and Apple silicon loads no unsigned code: signed ad hoc here,
|
||||
# with the Developer ID by ludic bundle / vpk for a release
|
||||
codesign -f -s - "$OUT/libMoltenVK.dylib"
|
||||
cp "$SRC/LICENSE" "$PKG/native/LICENSE-MoltenVK"
|
||||
echo "$OUT/libMoltenVK.dylib"
|
||||
|
|
@ -1,7 +1,8 @@
|
|||
# ludic.render3d — a physically based 3D renderer over Gl.* (OpenGL 4.1 core):
|
||||
# HDRI sky + image-based lighting, a GPU-generated terrain with scanned PBR
|
||||
# materials, cascaded shadow maps, an HDR pipeline with bloom and ACES.
|
||||
# ludic.render3d — a physically based 3D renderer over Vulkan (MoltenVK on a Mac, carried here,
|
||||
# built from a pinned tag by native/build.sh): HDRI sky + image-based lighting, a GPU-generated
|
||||
# terrain with scanned PBR materials, cascaded shadow maps, an HDR pipeline with bloom and ACES.
|
||||
package "ludic.render3d"
|
||||
version "0.1.0"
|
||||
kind source
|
||||
provides "R3d"
|
||||
native "macos-arm64" "lib/macos-arm64/libMoltenVK.dylib"
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ function post_free(render3d_st: mut Render3dState) -> void {
|
|||
# Multisampled scene: 1 (temporal AA alone), 2 or 4, remade at once. Vulkan draws it into
|
||||
# multisampled renderbuffers and resolves them in a pass; a device that cannot take the count asked
|
||||
# for gets the most it can (gpu_msaa_max).
|
||||
function post_msaa_live(render3d_st: Render3dState) -> bool { return gpu_is_gl(render3d_st) or gpu_msaa_max(render3d_st) > 1 }
|
||||
function post_msaa_live(render3d_st: Render3dState) -> bool { return gpu_msaa_max(render3d_st) > 1 }
|
||||
function post_set_msaa(render3d_st: mut Render3dState, n: int) -> void {
|
||||
var want = n
|
||||
if want < 1 { want = 1 }
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ declare i32 @lvk_bind()
|
|||
@.lvk_fmt = private unnamed_addr constant [25 x i8] c"%s/lib/libvulkan.1.dylib\00"
|
||||
@.lvk_fmtm = private unnamed_addr constant [25 x i8] c"%s/lib/libMoltenVK.dylib\00"
|
||||
@.lvk_m0 = private unnamed_addr constant [49 x i8] c"@executable_path/../Frameworks/libMoltenVK.dylib\00"
|
||||
@.lvk_mr = private unnamed_addr constant [25 x i8] c"@rpath/libMoltenVK.dylib\00"
|
||||
@.lvk_m1 = private unnamed_addr constant [35 x i8] c"@executable_path/libMoltenVK.dylib\00"
|
||||
@.lvk_m2 = private unnamed_addr constant [18 x i8] c"libMoltenVK.dylib\00"
|
||||
@lvk_lib = internal global ptr null
|
||||
|
|
@ -40,8 +41,9 @@ entry:
|
|||
|
||||
; the candidates in order: a Vulkan loader first (the SDK's, so the validation layer can be
|
||||
; stacked in development), then MoltenVK itself, which exports every vk* entry point and is what
|
||||
; a bundle ships in Contents/Frameworks - no loader, no ICD json.
|
||||
@lvk_paths = internal constant [7 x ptr] [ptr @.lvk_c0, ptr @.lvk_c1, ptr @.lvk_c2, ptr @.lvk_c3, ptr @.lvk_m0, ptr @.lvk_m1, ptr @.lvk_m2]
|
||||
; a bundle ships in Contents/Frameworks - no loader, no ICD json - or, found through the
|
||||
; executable's rpath, what ludic.render3d carries (lib/macos-arm64) for every other build.
|
||||
@lvk_paths = internal constant [8 x ptr] [ptr @.lvk_c0, ptr @.lvk_c1, ptr @.lvk_c2, ptr @.lvk_c3, ptr @.lvk_m0, ptr @.lvk_mr, ptr @.lvk_m1, ptr @.lvk_m2]
|
||||
|
||||
define i32 @lvk_open() {
|
||||
entry:
|
||||
|
|
@ -50,14 +52,14 @@ entry:
|
|||
br i1 %open, label %ok, label %loop
|
||||
loop:
|
||||
%i = phi i32 [ 0, %entry ], [ %i1, %next ]
|
||||
%slot = getelementptr [7 x ptr], ptr @lvk_paths, i32 0, i32 %i
|
||||
%slot = getelementptr [8 x ptr], ptr @lvk_paths, i32 0, i32 %i
|
||||
%path = load ptr, ptr %slot
|
||||
%h = call ptr @lvk_try(ptr %path)
|
||||
%miss = icmp eq ptr %h, null
|
||||
br i1 %miss, label %next, label %got
|
||||
next:
|
||||
%i1 = add i32 %i, 1
|
||||
%more = icmp slt i32 %i1, 7
|
||||
%more = icmp slt i32 %i1, 8
|
||||
br i1 %more, label %loop, label %sdk
|
||||
got:
|
||||
store ptr %h, ptr @lvk_lib
|
||||
|
|
|
|||
|
|
@ -455,7 +455,7 @@ function lab_plate_case() -> void {
|
|||
# from the checkout's root, where the renderer's shaders and the plate are found beside it
|
||||
let work = `{tmp_dir()}/labrun`
|
||||
shell(`rm -rf {work} build/lab/probe && mkdir -p {work}`)
|
||||
if not shq(`yes '' | head -300 | {vk_env()}/usr/bin/time -l {bin} > {work}/run.out 2> {work}/time.out`) { bad2(lbl, capture_line(`tail -1 {work}/run.out`)); return }
|
||||
if not shq(`yes '' | head -300 | /usr/bin/time -l {bin} > {work}/run.out 2> {work}/time.out`) { bad2(lbl, capture_line(`tail -1 {work}/run.out`)); return }
|
||||
var n = 0
|
||||
let names = ["front", "side", "above"]
|
||||
for i in 0 .. 3 {
|
||||
|
|
@ -608,22 +608,12 @@ function headless_case(path: pointer, exp: pointer, label: pointer) -> void {
|
|||
let got = capture_line(`{out} < /dev/null`)
|
||||
if got == exp { ok(label) } else { bad2(label, `got [{got}] want [{exp}]`) }
|
||||
}
|
||||
# render3d draws with Vulkan only: on a Mac with no loader beside the binary, a run finds MoltenVK
|
||||
# through the SDK - VULKAN_SDK as set, else the newest ~/VulkanSDK/<version>/macOS
|
||||
function vk_env() -> string {
|
||||
let set = Os.env("VULKAN_SDK")
|
||||
if set != null and set != "" { return "" }
|
||||
let found = capture_line("ls -d $HOME/VulkanSDK/*/macOS 2>/dev/null | tail -1")
|
||||
if len(found) == 0 { return "" }
|
||||
# the SDK's loader finds MoltenVK only through its driver manifest
|
||||
return `VULKAN_SDK={found} VK_ICD_FILENAMES={found}/share/vulkan/icd.d/MoltenVK_icd.json `
|
||||
}
|
||||
# a program built headless whose verdict is one of its lines (the renderer logs before it)
|
||||
function headless_line_case(path: pointer, exp: pointer, label: pointer) -> void {
|
||||
let out = `{tmp_dir()}/h_{flat(path)}`
|
||||
if not shq(`bin/ludicc --headless examples/{path}.ludic -o {out} > {out}.log 2>&1`) { bad2(label, capture_line(`grep -i error {out}.log | head -1`)); return }
|
||||
let got = capture_line(`{vk_env()}{out} < /dev/null 2>&1 | grep -c '^{exp}$'`)
|
||||
if got == "1" { ok(label) } else { bad2(label, capture_line(`{vk_env()}{out} < /dev/null 2>&1 | grep -i -E 'fail|cannot' | head -1`)) }
|
||||
let got = capture_line(`{out} < /dev/null 2>&1 | grep -c '^{exp}$'`)
|
||||
if got == "1" { ok(label) } else { bad2(label, capture_line(`{out} < /dev/null 2>&1 | grep -i -E 'fail|cannot' | head -1`)) }
|
||||
}
|
||||
# ludic migrate state and components: the header names what every member needs, a field read in a
|
||||
# member is not edited, a module named like a package keeps a state of its own, and the program
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue