Compare commits
380
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7f3ae3d574 | ||
|
|
80f82acdf8 | ||
|
|
78146bb14c | ||
|
|
c61f97dbce | ||
|
|
c823f837c0 | ||
|
|
f8252fcc91 | ||
|
|
98ed8b98b1 | ||
|
|
5f5a73a8f6 | ||
|
|
50be2a7e56 | ||
|
|
4fdbac7207 | ||
|
|
8199076878 | ||
|
|
c49de41ef3 | ||
|
|
ad5681c45b | ||
|
|
daf76f1ff6 | ||
|
|
cdff4b2bb5 | ||
|
|
d3a1a97db8 | ||
|
|
962464629d | ||
|
|
3291c2e560 | ||
|
|
b797a84b5d | ||
|
|
45b0460019 | ||
|
|
5d0919855e | ||
|
|
6d2d283954 | ||
|
|
49db06b604 | ||
|
|
85012b6074 | ||
|
|
14271c72f3 | ||
|
|
d73922e407 | ||
|
|
c8d23a5f01 | ||
|
|
4d8c8cdeda | ||
|
|
148d8c4995 | ||
|
|
4ae517e24e | ||
|
|
1fd4703907 | ||
|
|
024221d448 | ||
|
|
bfe046b60f | ||
|
|
1bfa90cb1f | ||
|
|
0c2e3308a5 | ||
|
|
11fc77b704 | ||
|
|
28af0d58c6 | ||
|
|
bca544448f | ||
|
|
badbf8da4e | ||
|
|
b140291cd0 | ||
|
|
70b12c1b1b | ||
|
|
2bbd74b4b6 | ||
|
|
add176e538 | ||
|
|
86384afbcf | ||
|
|
328f833d51 | ||
|
|
a002a6313e | ||
|
|
4fc5405f16 | ||
|
|
16d9f7316f | ||
|
|
95977f41b7 | ||
|
|
3302162ede | ||
|
|
29f857fed6 | ||
|
|
492ed877ea | ||
|
|
b1959ecf23 | ||
|
|
928454cbfe | ||
|
|
36b306a36c | ||
|
|
92570af7d3 | ||
|
|
5a9050aea3 | ||
|
|
3d9f4c3328 | ||
|
|
04ceb2d4a0 | ||
|
|
e6987e2452 | ||
|
|
4cd6df1997 | ||
|
|
9163913305 | ||
|
|
b3f4ba0725 | ||
|
|
354bda8dde | ||
|
|
8ccbfdf368 | ||
|
|
19b646849c | ||
|
|
48a83d69cc | ||
|
|
ec682cc794 | ||
|
|
d2d655b41f | ||
|
|
d6021b7d89 | ||
|
|
8dcb6db823 | ||
|
|
d0cfcf10bb | ||
|
|
dd791f6838 | ||
|
|
988714beb9 | ||
|
|
78756540cb | ||
|
|
205b5c9f44 | ||
|
|
bca30aafed | ||
|
|
840d5c16d2 | ||
|
|
25b9a686b0 | ||
|
|
54c2f2c3f7 | ||
|
|
b9cf5f08db | ||
|
|
c7a36fa3c9 | ||
|
|
73ca5f53e7 | ||
|
|
2be2fb4918 | ||
|
|
fec1dd4a8b | ||
|
|
2a3a8f736c | ||
|
|
d3aff13aa3 | ||
|
|
54fb312a2c | ||
|
|
20aa0ad1c5 | ||
|
|
ff667d35f2 | ||
|
|
ff9599fb7e | ||
|
|
0448f20394 | ||
|
|
db07924104 | ||
|
|
e60acdc477 | ||
|
|
d69f658835 | ||
|
|
3eb9328d3e | ||
|
|
a8589a8422 | ||
|
|
0bdaaf6c76 | ||
|
|
390197d3aa | ||
|
|
9fafba49dc | ||
|
|
5d47efe7fb | ||
|
|
824234accc | ||
|
|
6519158ae5 | ||
|
|
00718d60d2 | ||
|
|
18c2e179ee | ||
|
|
21ae008fc2 | ||
|
|
97a8bb44e6 | ||
|
|
5d33fce898 | ||
|
|
bb5df96f69 | ||
|
|
12b97944f3 | ||
|
|
0f17fbe1ca | ||
|
|
c3480ca99c | ||
|
|
936d94c2ee | ||
|
|
6cb55ebd46 | ||
|
|
482c5130eb | ||
|
|
066bcc5204 | ||
|
|
21baa27bea | ||
|
|
93fd4a1c80 | ||
|
|
7135779599 | ||
|
|
62c151d044 | ||
|
|
11d38fc23b | ||
|
|
d027f0ae6e | ||
|
|
44290c204e | ||
|
|
0b69860af6 | ||
|
|
e7a1ae0ea5 | ||
|
|
7af36d6c40 | ||
|
|
d1ae1163dd | ||
|
|
b2cf5729b4 | ||
|
|
11b8dd76db | ||
|
|
56507a6122 | ||
|
|
8d4324cba2 | ||
|
|
35408a2126 | ||
|
|
e5b9dfd181 | ||
|
|
e8a5d07e5e | ||
|
|
8c1daf0caf | ||
|
|
ad2b211f75 | ||
|
|
414ae344af | ||
|
|
71af2c020c | ||
|
|
e755f50072 | ||
|
|
a0b8275e9c | ||
|
|
ea362839b1 | ||
|
|
e7dd5d841b | ||
|
|
5594d03da0 | ||
|
|
f2ae66b64f | ||
|
|
393d99338f | ||
|
|
4d88280931 | ||
|
|
e8cc359b5e | ||
|
|
3b4a198655 | ||
|
|
03dd1520a3 | ||
|
|
a6fd74fa3b | ||
|
|
03b36bac94 | ||
|
|
a96677bdf6 | ||
|
|
67f89d0a2b | ||
|
|
f6de8877ec | ||
|
|
7c189b1f17 | ||
|
|
a7947080c0 | ||
|
|
08c82a3781 | ||
|
|
589aea50c2 | ||
|
|
72acd7c9df | ||
|
|
1a70d1158e | ||
|
|
ae915c6516 | ||
|
|
54d573332e | ||
|
|
0204a69f6b | ||
|
|
b2689ff76a | ||
|
|
611940fb80 | ||
|
|
16c0329a2a | ||
|
|
2743716132 | ||
|
|
a744eee993 | ||
|
|
0e24267eb5 | ||
|
|
f4d6043aa4 | ||
|
|
9fb9bd31a3 | ||
|
|
c3828bb0a3 | ||
|
|
40371f0907 | ||
|
|
94f9434564 | ||
|
|
bfaf247d30 | ||
|
|
2287c43b59 | ||
|
|
15cc0f5f91 | ||
|
|
68e0108b1c | ||
|
|
7b3796bc39 | ||
|
|
b5bc6d2cc4 | ||
|
|
0d1d4ea1f9 | ||
|
|
1a48f897f2 | ||
|
|
2b42789de6 | ||
|
|
b9c1da10ba | ||
|
|
56f5a76696 | ||
|
|
c7e8977e60 | ||
|
|
e6ba3612db | ||
|
|
5e77fb314c | ||
|
|
1a2841deb1 | ||
|
|
688637eca8 | ||
|
|
85d1d70ca1 | ||
|
|
09356c709a | ||
|
|
07b9e86d02 | ||
|
|
8e46e5d8b4 | ||
|
|
96292a5b46 | ||
|
|
ffa618c00b | ||
|
|
291b9b3c82 | ||
|
|
ec45117f0f | ||
|
|
0d7aff9c56 | ||
|
|
d31b239288 | ||
|
|
b1cadf0e99 | ||
|
|
c1f67585e6 | ||
|
|
93988e28c0 | ||
|
|
edef6e66e9 | ||
|
|
e3f47809c4 | ||
|
|
f759e7ac59 | ||
|
|
544eb2c5a9 | ||
|
|
30e3eba20a | ||
|
|
f0e85a2a9c | ||
|
|
106af5b46a | ||
|
|
522716ed90 | ||
|
|
a65fbb0211 | ||
|
|
46ec859bd1 | ||
|
|
2a7aa4eae4 | ||
|
|
c31ddf021e | ||
|
|
eaa2a8239f | ||
|
|
d313ecb737 | ||
|
|
64b2af0340 | ||
|
|
58d0702948 | ||
|
|
707717e94b | ||
|
|
a140bba55a | ||
|
|
f4ddacacd0 | ||
|
|
ebba656bdb | ||
|
|
b78c61d67a | ||
|
|
4210aa61e1 | ||
|
|
d8a345d924 | ||
|
|
b8dc9767da | ||
|
|
1ab01b9367 | ||
|
|
ee371ff740 | ||
|
|
ef58dd77ca | ||
|
|
e6a7121904 | ||
|
|
a6ed8ab59d | ||
|
|
bd40d0ded1 | ||
|
|
68bfcb6c54 | ||
|
|
0d01efca52 | ||
|
|
0e65e04ce1 | ||
|
|
58d351fe98 | ||
|
|
9b71f18141 | ||
|
|
554f08bac3 | ||
|
|
913813a933 | ||
|
|
4e34c771e4 | ||
|
|
9995174e68 | ||
|
|
5a0197d430 | ||
|
|
4a55143e15 | ||
|
|
87c9bc1b1f | ||
|
|
16a57b70f7 | ||
|
|
69564cd0b1 | ||
|
|
da648b00e7 | ||
|
|
5886d90308 | ||
|
|
e84df0cad1 | ||
|
|
e482904111 | ||
|
|
b8ee44ca6a | ||
|
|
4a4abe4240 | ||
|
|
fe47f5cc30 | ||
|
|
5b64be0810 | ||
|
|
17656d051b | ||
|
|
233fce456a | ||
|
|
5290bb036c | ||
|
|
2bff72b4f6 | ||
|
|
08ebeaee5c | ||
|
|
12b56f5447 | ||
|
|
165b86e7b7 | ||
|
|
608101a185 | ||
|
|
554bee6aae | ||
|
|
3e0ce51067 | ||
|
|
7261c43342 | ||
|
|
ad57c6ea37 | ||
|
|
caecff650d | ||
|
|
f6300be4b2 | ||
|
|
bde5687a3c | ||
|
|
0f3504f78d | ||
|
|
0aaa0321cc | ||
|
|
caaaf52583 | ||
|
|
56449f167d | ||
|
|
c7325228dc | ||
|
|
079967afa5 | ||
|
|
2ed55b614c | ||
|
|
28721e3cd2 | ||
|
|
9d9845d063 | ||
|
|
a96dc76831 | ||
|
|
ad8e517227 | ||
|
|
8d578d590f | ||
|
|
6b4a211374 | ||
|
|
55b023c961 | ||
|
|
e2d0fe3e2f | ||
|
|
6b56ff7a97 | ||
|
|
67f796ebde | ||
|
|
06da7490fc | ||
|
|
af83c442d3 | ||
|
|
d726e98596 | ||
|
|
c9a6709bd2 | ||
|
|
25816bea41 | ||
|
|
e0f6e96da0 | ||
|
|
57de46ae7e | ||
|
|
59693c8996 | ||
|
|
f0efffc093 | ||
|
|
1b41cd759c | ||
|
|
d42a1402e8 | ||
|
|
5c44678d55 | ||
|
|
0638fd58ce | ||
|
|
cb662b6730 | ||
|
|
e874c7515e | ||
|
|
2ba797576b | ||
|
|
180b454d61 | ||
|
|
6ce7ae77b1 | ||
|
|
abbaf95cf0 | ||
|
|
1081b70951 | ||
|
|
4f51f956ad | ||
|
|
b076f4b590 | ||
|
|
91180f8cb4 | ||
|
|
99aa859362 | ||
|
|
31267feb03 | ||
|
|
6a5bac72cb | ||
|
|
2ed5062950 | ||
|
|
0b0b02c5a1 | ||
|
|
28c71368a1 | ||
|
|
25bd4285ab | ||
|
|
180171cad6 | ||
|
|
bc3eeecf7f | ||
|
|
9178d14519 | ||
|
|
6cd35f5b72 | ||
|
|
72d5eb0ecb | ||
|
|
5cf924420d | ||
|
|
290574e6f6 | ||
|
|
d9db975b4b | ||
|
|
e5c0e5efa7 | ||
|
|
26a1aae098 | ||
|
|
ab114490fc | ||
|
|
9546c54286 | ||
|
|
4d3cdb70b5 | ||
|
|
a66816a72f | ||
|
|
c925f72562 | ||
|
|
ef97329f41 | ||
|
|
195f709eda | ||
|
|
eb57d94ec5 | ||
|
|
d6212ae839 | ||
|
|
b494897b3d | ||
|
|
559d4415eb | ||
|
|
49e9134774 | ||
|
|
9571b0ece8 | ||
|
|
b55cfaf90b | ||
|
|
509168856f | ||
|
|
24fa2722c3 | ||
|
|
142700f909 | ||
|
|
f3611681df | ||
|
|
7f0a5d6a10 | ||
|
|
2001cc15d5 | ||
|
|
8d604353a5 | ||
|
|
8410e11ecb | ||
|
|
9f8161bf4a | ||
|
|
c038d6f7f8 | ||
|
|
2fff37fffc | ||
|
|
6feb86be71 | ||
|
|
ed22220bc6 | ||
|
|
219cb1a59d | ||
|
|
71bd25a893 | ||
|
|
01ef4c46a1 | ||
|
|
64f728ec48 | ||
|
|
ba10adf1fb | ||
|
|
c18aa99358 | ||
|
|
3498412611 | ||
|
|
8c1b3ff210 | ||
|
|
1870052af6 | ||
|
|
3b1e3d5176 | ||
|
|
cdf26c6e97 | ||
|
|
9f1a1405a6 | ||
|
|
6e97d8d1b3 | ||
|
|
9d9a24d325 | ||
|
|
0897f4a7d1 | ||
|
|
5aec645191 | ||
|
|
07c33068f3 | ||
|
|
d684e5d57e | ||
|
|
219500d95c | ||
|
|
810addf7ae | ||
|
|
4ef077ca52 | ||
|
|
7d2275c4dc | ||
|
|
cbd8917047 | ||
|
|
c98a19401c | ||
|
|
434836c480 | ||
|
|
50d02ad732 |
No files matched your search
@@ -20,7 +20,6 @@ class AppleArch(Enum):
|
||||
class MsvcArch(Enum):
|
||||
X86 = "x86"
|
||||
X64 = "x64"
|
||||
Arm32 = "arm"
|
||||
Arm64 = "arm64"
|
||||
|
||||
|
||||
@@ -31,7 +30,9 @@ class JobOs(Enum):
|
||||
Ubuntu22_04 = "ubuntu-22.04"
|
||||
Ubuntu24_04 = "ubuntu-24.04"
|
||||
Ubuntu24_04_arm = "ubuntu-24.04-arm"
|
||||
Macos13 = "macos-13"
|
||||
Macos14 = "macos-14" # macOS Sonoma (2023)
|
||||
Macos15 = "macos-15" # macOS Sequoia (2024)
|
||||
Macos26 = "macos-26" # macOS Tahoe (2025)
|
||||
|
||||
|
||||
class SdlPlatform(Enum):
|
||||
@@ -54,6 +55,7 @@ class SdlPlatform(Enum):
|
||||
Riscos = "riscos"
|
||||
FreeBSD = "freebsd"
|
||||
NetBSD = "netbsd"
|
||||
OpenBSD = "openbsd"
|
||||
|
||||
|
||||
class Msys2Platform(Enum):
|
||||
@@ -108,7 +110,6 @@ JOB_SPECS = {
|
||||
"msvc-x86": JobSpec(name="Windows (MSVC, x86)", os=JobOs.WindowsLatest, platform=SdlPlatform.Msvc, artifact="SDL-VC-x86", msvc_arch=MsvcArch.X86, msvc_project="VisualC/SDL.sln", ),
|
||||
"msvc-clang-x64": JobSpec(name="Windows (MSVC, clang-cl x64)", os=JobOs.WindowsLatest, platform=SdlPlatform.Msvc, artifact="SDL-clang-cl-x64", msvc_arch=MsvcArch.X64, clang_cl=True, ),
|
||||
"msvc-clang-x86": JobSpec(name="Windows (MSVC, clang-cl x86)", os=JobOs.WindowsLatest, platform=SdlPlatform.Msvc, artifact="SDL-clang-cl-x86", msvc_arch=MsvcArch.X86, clang_cl=True, ),
|
||||
"msvc-arm32": JobSpec(name="Windows (MSVC, ARM)", os=JobOs.WindowsLatest, platform=SdlPlatform.Msvc, artifact="SDL-VC-arm32", msvc_arch=MsvcArch.Arm32, ),
|
||||
"msvc-arm64": JobSpec(name="Windows (MSVC, ARM64)", os=JobOs.WindowsLatest, platform=SdlPlatform.Msvc, artifact="SDL-VC-arm64", msvc_arch=MsvcArch.Arm64, ),
|
||||
"msvc-gdk-x64": JobSpec(name="GDK (MSVC, x64)", os=JobOs.WindowsLatest, platform=SdlPlatform.Msvc, artifact="SDL-VC-GDK", msvc_arch=MsvcArch.X64, msvc_project="VisualC-GDK/SDL.sln", gdk=True, no_cmake=True, ),
|
||||
"ubuntu-22.04": JobSpec(name="Ubuntu 22.04", os=JobOs.Ubuntu22_04, platform=SdlPlatform.Linux, artifact="SDL-ubuntu22.04", ),
|
||||
@@ -116,7 +117,7 @@ JOB_SPECS = {
|
||||
"steamrt-sniper": JobSpec(name="Steam Linux Runtime (Sniper)", os=JobOs.UbuntuLatest, platform=SdlPlatform.Linux, artifact="SDL-slrsniper", container="registry.gitlab.steamos.cloud/steamrt/sniper/sdk:beta", ),
|
||||
"ubuntu-intel-icx": JobSpec(name="Ubuntu 22.04 (Intel oneAPI)", os=JobOs.Ubuntu22_04, platform=SdlPlatform.Linux, artifact="SDL-ubuntu22.04-oneapi", intel=IntelCompiler.Icx, ),
|
||||
"ubuntu-intel-icc": JobSpec(name="Ubuntu 22.04 (Intel Compiler)", os=JobOs.Ubuntu22_04, platform=SdlPlatform.Linux, artifact="SDL-ubuntu22.04-icc", intel=IntelCompiler.Icc, ),
|
||||
"macos-framework-x64": JobSpec(name="MacOS (Framework) (x64)", os=JobOs.Macos13, platform=SdlPlatform.MacOS, artifact="SDL-macos-framework", apple_framework=True, apple_archs={AppleArch.Aarch64, AppleArch.X86_64, }, xcode=True, ),
|
||||
"macos-framework-x64": JobSpec(name="MacOS (Framework) (x64)", os=JobOs.Macos14, platform=SdlPlatform.MacOS, artifact="SDL-macos-framework", apple_framework=True, apple_archs={AppleArch.Aarch64, AppleArch.X86_64, }, xcode=True, ),
|
||||
"macos-framework-arm64": JobSpec(name="MacOS (Framework) (arm64)", os=JobOs.MacosLatest, platform=SdlPlatform.MacOS, artifact=None, apple_framework=True, apple_archs={AppleArch.Aarch64, AppleArch.X86_64, }, ),
|
||||
"macos-gnu-arm64": JobSpec(name="MacOS (GNU prefix)", os=JobOs.MacosLatest, platform=SdlPlatform.MacOS, artifact="SDL-macos-arm64-gnu", apple_framework=False, apple_archs={AppleArch.Aarch64, }, ),
|
||||
"ios": JobSpec(name="iOS (CMake & xcode)", os=JobOs.MacosLatest, platform=SdlPlatform.Ios, artifact="SDL-ios-arm64", xcode=True, ),
|
||||
@@ -137,6 +138,7 @@ JOB_SPECS = {
|
||||
"vita-pvr": JobSpec(name="Sony PlayStation Vita (GLES w/ PVR_PSP2)", os=JobOs.UbuntuLatest, platform=SdlPlatform.Vita, artifact="SDL-vita-pvr", container="vitasdk/vitasdk:latest", vita_gles=VitaGLES.Pvr, ),
|
||||
"riscos": JobSpec(name="RISC OS", os=JobOs.UbuntuLatest, platform=SdlPlatform.Riscos, artifact="SDL-riscos", container="riscosdotinfo/riscos-gccsdk-4.7:latest", ),
|
||||
"netbsd": JobSpec(name="NetBSD", os=JobOs.UbuntuLatest, platform=SdlPlatform.NetBSD, artifact="SDL-netbsd-x64", ),
|
||||
"openbsd": JobSpec(name="OpenBSD", os=JobOs.UbuntuLatest, platform=SdlPlatform.OpenBSD, artifact="SDL-openbsd-x64", ),
|
||||
"freebsd": JobSpec(name="FreeBSD", os=JobOs.UbuntuLatest, platform=SdlPlatform.FreeBSD, artifact="SDL-freebsd-x64", ),
|
||||
}
|
||||
|
||||
@@ -174,6 +176,7 @@ class JobDetails:
|
||||
brew_packages: list[str] = dataclasses.field(default_factory=list)
|
||||
cmake_toolchain_file: str = ""
|
||||
cmake_arguments: list[str] = dataclasses.field(default_factory=list)
|
||||
cmake_generator: str = "Ninja"
|
||||
cmake_build_arguments: list[str] = dataclasses.field(default_factory=list)
|
||||
clang_tidy: bool = True
|
||||
cppflags: list[str] = dataclasses.field(default_factory=list)
|
||||
@@ -222,6 +225,7 @@ class JobDetails:
|
||||
check_sources: bool = False
|
||||
setup_python: bool = False
|
||||
pypi_packages: list[str] = dataclasses.field(default_factory=list)
|
||||
binutils_strings: str = "strings"
|
||||
|
||||
def to_workflow(self, enable_artifacts: bool) -> dict[str, str|bool]:
|
||||
data = {
|
||||
@@ -255,6 +259,7 @@ class JobDetails:
|
||||
"cflags": my_shlex_join(self.cppflags + self.cflags),
|
||||
"cxxflags": my_shlex_join(self.cppflags + self.cxxflags),
|
||||
"ldflags": my_shlex_join(self.ldflags),
|
||||
"cmake-generator": self.cmake_generator,
|
||||
"cmake-toolchain-file": self.cmake_toolchain_file,
|
||||
"clang-tidy": self.clang_tidy,
|
||||
"cmake-arguments": my_shlex_join(self.cmake_arguments),
|
||||
@@ -289,6 +294,7 @@ class JobDetails:
|
||||
"check-sources": self.check_sources,
|
||||
"setup-python": self.setup_python,
|
||||
"pypi-packages": my_shlex_join(self.pypi_packages),
|
||||
"binutils-strings": self.binutils_strings,
|
||||
}
|
||||
return {k: v for k, v in data.items() if v != ""}
|
||||
|
||||
@@ -403,10 +409,6 @@ def spec_to_job(spec: JobSpec, key: str, trackmem_symbol_names: bool) -> JobDeta
|
||||
job.msvc_vcvars_arch = "x64_x86"
|
||||
case MsvcArch.X64:
|
||||
job.msvc_vcvars_arch = "x64"
|
||||
case MsvcArch.Arm32:
|
||||
job.msvc_vcvars_arch = "x64_arm"
|
||||
job.msvc_vcvars_sdk = "10.0.22621.0" # 10.0.26100.0 dropped ARM32 um and ucrt libraries
|
||||
job.run_tests = False
|
||||
case MsvcArch.Arm64:
|
||||
job.msvc_vcvars_arch = "x64_arm64"
|
||||
job.run_tests = False
|
||||
@@ -514,9 +516,10 @@ def spec_to_job(spec: JobSpec, key: str, trackmem_symbol_names: bool) -> JobDeta
|
||||
job.ccache = True
|
||||
job.apt_packages = []
|
||||
job.brew_packages.extend((
|
||||
"ccache",
|
||||
"ninja",
|
||||
))
|
||||
if job.ccache:
|
||||
job.brew_packages.append("ccache")
|
||||
if job.clang_tidy:
|
||||
job.brew_packages.append("llvm")
|
||||
if spec.xcode:
|
||||
@@ -550,6 +553,10 @@ def spec_to_job(spec: JobSpec, key: str, trackmem_symbol_names: bool) -> JobDeta
|
||||
"testmultiaudio-apk",
|
||||
"testsprite-apk",
|
||||
]
|
||||
|
||||
# -fPIC is required after updating NDK from 21 to 28
|
||||
job.cflags.append("-fPIC")
|
||||
job.cxxflags.append("-fPIC")
|
||||
case SdlPlatform.Emscripten:
|
||||
job.clang_tidy = False # clang-tidy does not understand -gsource-map
|
||||
job.shared = False
|
||||
@@ -675,13 +682,16 @@ def spec_to_job(spec: JobSpec, key: str, trackmem_symbol_names: bool) -> JobDeta
|
||||
job.shared_lib = SharedLibType.SO_0
|
||||
job.static_lib = StaticLibType.A
|
||||
case SdlPlatform.N3ds:
|
||||
job.ccache = True
|
||||
job.cmake_generator = "Unix Makefiles"
|
||||
job.cmake_build_arguments.append("-j$(nproc)")
|
||||
job.ccache = False
|
||||
job.shared = False
|
||||
job.apt_packages = ["ccache", "ninja-build", "binutils"]
|
||||
job.apt_packages = []
|
||||
job.clang_tidy = False
|
||||
job.run_tests = False
|
||||
job.cc_from_cmake = True
|
||||
job.cmake_toolchain_file = "${DEVKITPRO}/cmake/3DS.cmake"
|
||||
job.binutils_strings = "/opt/devkitpro/devkitARM/bin/arm-none-eabi-strings"
|
||||
job.static_lib = StaticLibType.A
|
||||
case SdlPlatform.Msys2:
|
||||
job.ccache = True
|
||||
@@ -713,7 +723,7 @@ def spec_to_job(spec: JobSpec, key: str, trackmem_symbol_names: bool) -> JobDeta
|
||||
))
|
||||
job.cmake_toolchain_file = "/home/riscos/env/toolchain-riscos.cmake"
|
||||
job.static_lib = StaticLibType.A
|
||||
case SdlPlatform.FreeBSD | SdlPlatform.NetBSD:
|
||||
case SdlPlatform.FreeBSD | SdlPlatform.NetBSD | SdlPlatform.OpenBSD:
|
||||
job.cpactions = True
|
||||
job.no_cmake = True
|
||||
job.run_tests = False
|
||||
@@ -723,7 +733,7 @@ def spec_to_job(spec: JobSpec, key: str, trackmem_symbol_names: bool) -> JobDeta
|
||||
match spec.platform:
|
||||
case SdlPlatform.FreeBSD:
|
||||
job.cpactions_os = "freebsd"
|
||||
job.cpactions_version = "14.2"
|
||||
job.cpactions_version = "14.3"
|
||||
job.cpactions_arch = "x86-64"
|
||||
job.cpactions_setup_cmd = "sudo pkg update"
|
||||
job.cpactions_install_cmd = "sudo pkg install -y cmake ninja pkgconf libXcursor libXext libXinerama libXi libXfixes libXrandr libXScrnSaver libXxf86vm wayland wayland-protocols libxkbcommon mesa-libs libglvnd evdev-proto libinotify alsa-lib jackit pipewire pulseaudio sndio dbus zh-fcitx ibus libudev-devd"
|
||||
@@ -737,6 +747,12 @@ def spec_to_job(spec: JobSpec, key: str, trackmem_symbol_names: bool) -> JobDeta
|
||||
job.cpactions_arch = "x86-64"
|
||||
job.cpactions_setup_cmd = "export PATH=\"/usr/pkg/sbin:/usr/pkg/bin:/sbin:$PATH\"; export PKG_CONFIG_PATH=\"/usr/pkg/lib/pkgconfig\";export PKG_PATH=\"https://cdn.netBSD.org/pub/pkgsrc/packages/NetBSD/$(uname -p)/$(uname -r|cut -f \"1 2\" -d.)/All/\";echo \"PKG_PATH=$PKG_PATH\";echo \"uname -a -> \"$(uname -a)\"\";sudo -E sysctl -w security.pax.aslr.enabled=0;sudo -E sysctl -w security.pax.aslr.global=0;sudo -E pkgin clean;sudo -E pkgin update"
|
||||
job.cpactions_install_cmd = "sudo -E pkgin -y install cmake dbus pkgconf ninja-build pulseaudio libxkbcommon wayland wayland-protocols libinotify libusb1"
|
||||
case SdlPlatform.OpenBSD:
|
||||
job.cpactions_os = "openbsd"
|
||||
job.cpactions_version = "7.7"
|
||||
job.cpactions_arch = "x86-64"
|
||||
job.cpactions_setup_cmd = "sudo pkg_add -u"
|
||||
job.cpactions_install_cmd = "sudo pkg_add cmake ninja pkgconf wayland wayland-protocols libxkbcommon libinotify pulseaudio dbus ibus"
|
||||
case _:
|
||||
raise ValueError(f"Unsupported platform={spec.platform}")
|
||||
|
||||
|
||||
@@ -75,8 +75,8 @@ jobs:
|
||||
if: ${{ matrix.platform.android-ndk }}
|
||||
id: setup-ndk
|
||||
with:
|
||||
local-cache: true
|
||||
ndk-version: r21e
|
||||
local-cache: false
|
||||
ndk-version: r28c
|
||||
- name: 'Configure Android NDK variables'
|
||||
if: ${{ matrix.platform.android-ndk }}
|
||||
shell: sh
|
||||
@@ -201,7 +201,7 @@ jobs:
|
||||
#shell: ${{ matrix.platform.shell }}
|
||||
run: |
|
||||
${{ matrix.platform.source-cmd }}
|
||||
${{ matrix.platform.cmake-config-emulator }} cmake -S . -B build -GNinja \
|
||||
${{ matrix.platform.cmake-config-emulator }} cmake -S . -B build -G "${{ matrix.platform.cmake-generator }}" \
|
||||
-Wdeprecated -Wdev -Werror \
|
||||
${{ matrix.platform.cmake-toolchain-file != '' && format('-DCMAKE_TOOLCHAIN_FILE={0}', matrix.platform.cmake-toolchain-file) || '' }} \
|
||||
-DSDL_WERROR=${{ matrix.platform.werror }} \
|
||||
@@ -232,9 +232,9 @@ jobs:
|
||||
run: |
|
||||
echo "This should show us the SDL_REVISION"
|
||||
echo "Shared library:"
|
||||
${{ (matrix.platform.shared-lib && format('strings build/{0} | grep "Github Workflow"', matrix.platform.shared-lib)) || 'echo "<Shared library not supported by platform>"' }}
|
||||
${{ (matrix.platform.shared-lib && format('{0} build/{1} | grep "Github Workflow"', matrix.platform.binutils-strings, matrix.platform.shared-lib)) || 'echo "<Shared library not supported by platform>"' }}
|
||||
echo "Static library:"
|
||||
${{ (matrix.platform.static-lib && format('strings build/{0} | grep "Github Workflow"', matrix.platform.static-lib)) || 'echo "<Static library not supported by platform>"' }}
|
||||
${{ (matrix.platform.static-lib && format('{0} build/{1} | grep "Github Workflow"', matrix.platform.binutils-strings, matrix.platform.static-lib)) || 'echo "<Static library not supported by platform>"' }}
|
||||
- name: 'Run build-time tests (CMake)'
|
||||
id: tests
|
||||
if: ${{ !matrix.platform.no-cmake && matrix.platform.run-tests }}
|
||||
@@ -321,7 +321,7 @@ jobs:
|
||||
- name: 'Build (cross-platform-actions, BSD)'
|
||||
id: cpactions
|
||||
if: ${{ matrix.platform.cpactions }}
|
||||
uses: cross-platform-actions/action@v0.27.0
|
||||
uses: cross-platform-actions/action@v0.29.0
|
||||
with:
|
||||
operating_system: '${{ matrix.platform.cpactions-os }}'
|
||||
architecture: '${{ matrix.platform.cpactions-arch }}'
|
||||
@@ -406,6 +406,14 @@ jobs:
|
||||
build-scripts/test-versioning.sh
|
||||
python build-scripts/check_android_jni.py
|
||||
python build-scripts/check_stdlib_usage.py
|
||||
- name: 'Verify alignment of Android test apks'
|
||||
if: ${{ matrix.platform.android-ndk && !matrix.platform.no-cmake }}
|
||||
run: |
|
||||
find ./ -iname '*.apk' | xargs -L1 ./build-scripts/check_elf_alignment.sh
|
||||
- name: 'Verify alignment of Android .so files'
|
||||
if: ${{ matrix.platform.android-ndk && !matrix.platform.no-cmake }}
|
||||
run: |
|
||||
find ./ -iname '*.so' | xargs -L1 ./build-scripts/check_elf_alignment.sh
|
||||
- name: 'Upload binary package'
|
||||
uses: actions/upload-artifact@v4
|
||||
if: ${{ always() && matrix.platform.artifact != '' && (steps.package.outcome == 'success' || steps.cpactions.outcome == 'success') && (matrix.platform.enable-artifacts || steps.tests.outcome == 'failure') }}
|
||||
@@ -428,4 +436,4 @@ jobs:
|
||||
with:
|
||||
if-no-files-found: error
|
||||
name: '${{ matrix.platform.artifact }}-apks'
|
||||
path: build/test/*.apk
|
||||
path: build/test/*.apk
|
||||
@@ -204,10 +204,22 @@ jobs:
|
||||
-DCMAKE_PREFIX_PATH="${{ steps.mount.outputs.mount_point }}" \
|
||||
-DCMAKE_SYSTEM_NAME=iOS \
|
||||
-DCMAKE_OSX_ARCHITECTURES="arm64" \
|
||||
-DCMAKE_OSX_DEPLOYMENT_TARGET=11.0 \
|
||||
-DCMAKE_OSX_DEPLOYMENT_TARGET=11.0 \
|
||||
-Werror=dev \
|
||||
-B build_ios
|
||||
cmake --build build_ios --config Release --verbose
|
||||
|
||||
cmake -S "${{ steps.src.outputs.path }}/cmake/test" \
|
||||
-DTEST_FULL=FALSE \
|
||||
-DTEST_STATIC=FALSE \
|
||||
-DTEST_TEST=FALSE \
|
||||
-DCMAKE_PREFIX_PATH="${{ steps.mount.outputs.mount_point }}/SDL3.xcframework/ios-arm64" \
|
||||
-DCMAKE_SYSTEM_NAME=iOS \
|
||||
-DCMAKE_OSX_ARCHITECTURES="arm64" \
|
||||
-DCMAKE_OSX_DEPLOYMENT_TARGET=11.0 \
|
||||
-Werror=dev \
|
||||
-B build_ios2
|
||||
cmake --build build_ios2 --config Release --verbose
|
||||
- name: 'CMake (configure + build) tvOS'
|
||||
run: |
|
||||
cmake -S "${{ steps.src.outputs.path }}/cmake/test" \
|
||||
@@ -217,10 +229,22 @@ jobs:
|
||||
-DCMAKE_PREFIX_PATH="${{ steps.mount.outputs.mount_point }}" \
|
||||
-DCMAKE_SYSTEM_NAME=tvOS \
|
||||
-DCMAKE_OSX_ARCHITECTURES="arm64" \
|
||||
-DCMAKE_OSX_DEPLOYMENT_TARGET=11.0 \
|
||||
-DCMAKE_OSX_DEPLOYMENT_TARGET=11.0 \
|
||||
-Werror=dev \
|
||||
-B build_tvos
|
||||
cmake --build build_tvos --config Release --verbose
|
||||
|
||||
cmake -S "${{ steps.src.outputs.path }}/cmake/test" \
|
||||
-DTEST_FULL=FALSE \
|
||||
-DTEST_STATIC=FALSE \
|
||||
-DTEST_TEST=FALSE \
|
||||
-DCMAKE_PREFIX_PATH="${{ steps.mount.outputs.mount_point }}/SDL3.xcframework/tvos-arm64" \
|
||||
-DCMAKE_SYSTEM_NAME=tvOS \
|
||||
-DCMAKE_OSX_ARCHITECTURES="arm64" \
|
||||
-DCMAKE_OSX_DEPLOYMENT_TARGET=11.0 \
|
||||
-Werror=dev \
|
||||
-B build_tvos2
|
||||
cmake --build build_tvos2 --config Release --verbose
|
||||
- name: 'CMake (configure + build) iOS simulator'
|
||||
run: |
|
||||
sysroot=$(xcodebuild -version -sdk iphonesimulator Path)
|
||||
@@ -237,6 +261,19 @@ jobs:
|
||||
-Werror=dev \
|
||||
-B build_ios_simulator
|
||||
cmake --build build_ios_simulator --config Release --verbose
|
||||
|
||||
cmake -S "${{ steps.src.outputs.path }}/cmake/test" \
|
||||
-DTEST_FULL=FALSE \
|
||||
-DTEST_STATIC=FALSE \
|
||||
-DTEST_TEST=FALSE \
|
||||
-DCMAKE_PREFIX_PATH="${{ steps.mount.outputs.mount_point }}/SDL3.xcframework/ios-arm64_x86_64-simulator" \
|
||||
-DCMAKE_SYSTEM_NAME=iOS \
|
||||
-DCMAKE_OSX_ARCHITECTURES="arm64;x86_64" \
|
||||
-DCMAKE_OSX_SYSROOT="${sysroot}" \
|
||||
-DCMAKE_OSX_DEPLOYMENT_TARGET=11.0 \
|
||||
-Werror=dev \
|
||||
-B build_ios_simulator2
|
||||
cmake --build build_ios_simulator2 --config Release --verbose
|
||||
- name: 'CMake (configure + build) tvOS simulator'
|
||||
run: |
|
||||
sysroot=$(xcodebuild -version -sdk appletvsimulator Path)
|
||||
@@ -254,9 +291,22 @@ jobs:
|
||||
-B build_tvos_simulator
|
||||
cmake --build build_tvos_simulator --config Release --verbose
|
||||
|
||||
cmake -S "${{ steps.src.outputs.path }}/cmake/test" \
|
||||
-DTEST_FULL=FALSE \
|
||||
-DTEST_STATIC=FALSE \
|
||||
-DTEST_TEST=FALSE \
|
||||
-DCMAKE_PREFIX_PATH="${{ steps.mount.outputs.mount_point }}/SDL3.xcframework/tvos-arm64_x86_64-simulator" \
|
||||
-DCMAKE_SYSTEM_NAME=tvOS \
|
||||
-DCMAKE_OSX_ARCHITECTURES="arm64;x86_64" \
|
||||
-DCMAKE_OSX_SYSROOT="${sysroot}" \
|
||||
-DCMAKE_OSX_DEPLOYMENT_TARGET=11.0 \
|
||||
-Werror=dev \
|
||||
-B build_tvos_simulator2
|
||||
cmake --build build_tvos_simulator2 --config Release --verbose
|
||||
|
||||
msvc:
|
||||
needs: [src]
|
||||
runs-on: windows-2019
|
||||
runs-on: windows-2025
|
||||
outputs:
|
||||
VC-x86: ${{ steps.releaser.outputs.VC-x86 }}
|
||||
VC-x64: ${{ steps.releaser.outputs.VC-x64 }}
|
||||
@@ -532,10 +582,11 @@ jobs:
|
||||
with:
|
||||
sparse-checkout: 'build-scripts/build-release.py'
|
||||
- name: 'Setup Android NDK'
|
||||
id: setup-ndk
|
||||
uses: nttld/setup-ndk@v1
|
||||
with:
|
||||
local-cache: true
|
||||
ndk-version: r21e
|
||||
local-cache: false
|
||||
ndk-version: r28c
|
||||
- name: 'Setup Java JDK'
|
||||
uses: actions/setup-java@v4
|
||||
with:
|
||||
@@ -561,6 +612,8 @@ jobs:
|
||||
run: |
|
||||
python build-scripts/build-release.py \
|
||||
--actions android \
|
||||
--android-api 21 \
|
||||
--android-ndk-home "${{ steps.setup-ndk.outputs.ndk-path }}" \
|
||||
--commit ${{ inputs.commit }} \
|
||||
--root "${{ steps.tar.outputs.path }}" \
|
||||
--github \
|
||||
@@ -607,8 +660,14 @@ jobs:
|
||||
python "${{ needs.src.outputs.project }}-${{ needs.src.outputs.version }}.aar" -o /tmp/SDL3-android
|
||||
echo "prefix=/tmp/SDL3-android" >>$GITHUB_OUTPUT
|
||||
echo "sdl3-aar=/tmp/${{ needs.src.outputs.project }}-${{ needs.src.outputs.version }}.aar" >>$GITHUB_OUTPUT
|
||||
- name: 'Verify alignment of libSDL3.so (arm64-v8a/x86_64)'
|
||||
run: |
|
||||
set -e
|
||||
${{ steps.src.outputs.path }}/build-scripts/check_elf_alignment.sh ${{ steps.sdk.outputs.prefix }}/lib/arm64-v8a/libSDL3.so
|
||||
${{ steps.src.outputs.path }}/build-scripts/check_elf_alignment.sh ${{ steps.sdk.outputs.prefix }}/lib/x86_64/libSDL3.so
|
||||
- name: 'CMake (configure + build) x86, x64, arm32, arm64'
|
||||
run: |
|
||||
set -e
|
||||
android_abis="x86 x86_64 armeabi-v7a arm64-v8a"
|
||||
for android_abi in ${android_abis}; do
|
||||
echo "Configuring ${android_abi}..."
|
||||
|
||||
+92
-69
@@ -5,7 +5,7 @@ if(NOT DEFINED CMAKE_BUILD_TYPE)
|
||||
endif()
|
||||
|
||||
# See docs/release_checklist.md
|
||||
project(SDL3 LANGUAGES C VERSION "3.2.12")
|
||||
project(SDL3 LANGUAGES C VERSION "3.2.28")
|
||||
|
||||
if(CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR)
|
||||
set(SDL3_MAINPROJECT ON)
|
||||
@@ -79,6 +79,12 @@ include("${SDL3_SOURCE_DIR}/cmake/PreseedEmscriptenCache.cmake")
|
||||
|
||||
SDL_DetectCompiler()
|
||||
SDL_DetectTargetCPUArchitectures(SDL_CPUS)
|
||||
if(APPLE AND CMAKE_OSX_ARCHITECTURES)
|
||||
list(LENGTH CMAKE_OSX_ARCHITECTURES _num_arches)
|
||||
if(_num_arches GREATER 1)
|
||||
set(APPLE_MULTIARCH TRUE)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Increment this if there is an incompatible change - but if that happens,
|
||||
# we should rename the library from SDL3 to SDL4, at which point this would
|
||||
@@ -183,26 +189,6 @@ if(MSVC)
|
||||
set(SDL_RELOCATABLE_DEFAULT ON)
|
||||
endif()
|
||||
|
||||
if(MSVC)
|
||||
if(NOT SDL_LIBC)
|
||||
# Make sure /RTC1 is disabled, otherwise it will use functions from the CRT
|
||||
foreach(flag_var
|
||||
CMAKE_C_FLAGS CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE
|
||||
CMAKE_C_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELWITHDEBINFO)
|
||||
string(REGEX REPLACE "/RTC(su|[1su])" "" ${flag_var} "${${flag_var}}")
|
||||
endforeach(flag_var)
|
||||
endif()
|
||||
|
||||
if(MSVC_CLANG)
|
||||
# clang-cl treats /W4 as '-Wall -Wextra' -- we don't need -Wextra
|
||||
foreach(flag_var
|
||||
CMAKE_C_FLAGS CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE
|
||||
CMAKE_C_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELWITHDEBINFO)
|
||||
string(REGEX REPLACE "/W4" "/W3" ${flag_var} "${${flag_var}}")
|
||||
endforeach(flag_var)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
set(SDL_SHARED_DEFAULT ON)
|
||||
set(SDL_STATIC_DEFAULT ON)
|
||||
|
||||
@@ -370,7 +356,7 @@ dep_option(SDL_WASAPI "Use the Windows WASAPI audio driver" ON "WIN
|
||||
dep_option(SDL_RENDER_D3D "Enable the Direct3D 9 render driver" ON "SDL_RENDER;SDL_DIRECTX" OFF)
|
||||
dep_option(SDL_RENDER_D3D11 "Enable the Direct3D 11 render driver" ON "SDL_RENDER;SDL_DIRECTX" OFF)
|
||||
dep_option(SDL_RENDER_D3D12 "Enable the Direct3D 12 render driver" ON "SDL_RENDER;SDL_DIRECTX" OFF)
|
||||
dep_option(SDL_RENDER_METAL "Enable the Metal render driver" ON "SDL_RENDER;${APPLE}" OFF)
|
||||
dep_option(SDL_RENDER_METAL "Enable the Metal render driver" ON "SDL_RENDER;APPLE" OFF)
|
||||
dep_option(SDL_RENDER_GPU "Enable the SDL_GPU render driver" ON "SDL_RENDER;SDL_GPU" OFF)
|
||||
dep_option(SDL_VIVANTE "Use Vivante EGL video driver" ON "${UNIX_SYS};SDL_CPU_ARM32" OFF)
|
||||
dep_option(SDL_VULKAN "Enable Vulkan support" ON "SDL_VIDEO;ANDROID OR APPLE OR LINUX OR FREEBSD OR WINDOWS" OFF)
|
||||
@@ -421,6 +407,29 @@ if(SDL_PRESEED)
|
||||
SDL_Preseed_CMakeCache()
|
||||
endif()
|
||||
|
||||
if(MSVC)
|
||||
if(NOT SDL_LIBC)
|
||||
# Make sure /RTC1 is disabled, otherwise it will use functions from the CRT
|
||||
foreach(flag_var
|
||||
CMAKE_C_FLAGS CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE
|
||||
CMAKE_C_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELWITHDEBINFO
|
||||
CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE
|
||||
CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO)
|
||||
string(REGEX REPLACE "/RTC(su|[1su])" "" ${flag_var} "${${flag_var}}")
|
||||
endforeach(flag_var)
|
||||
set(CMAKE_MSVC_RUNTIME_CHECKS "")
|
||||
endif()
|
||||
|
||||
if(MSVC_CLANG)
|
||||
# clang-cl treats /W4 as '-Wall -Wextra' -- we don't need -Wextra
|
||||
foreach(flag_var
|
||||
CMAKE_C_FLAGS CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE
|
||||
CMAKE_C_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELWITHDEBINFO)
|
||||
string(REGEX REPLACE "/W4" "/W3" ${flag_var} "${${flag_var}}")
|
||||
endforeach(flag_var)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(SDL_SHARED)
|
||||
add_library(SDL3-shared SHARED)
|
||||
add_library(SDL3::SDL3-shared ALIAS SDL3-shared)
|
||||
@@ -634,6 +643,11 @@ if(MSVC)
|
||||
# Mark SDL3.dll as compatible with Control-flow Enforcement Technology (CET)
|
||||
sdl_shared_link_options("-CETCOMPAT")
|
||||
endif()
|
||||
|
||||
# for VS >= 17.14 targeting ARM64: inline the Interlocked funcs
|
||||
if(MSVC_VERSION GREATER 1943 AND SDL_CPU_ARM64 AND NOT SDL_LIBC)
|
||||
sdl_compile_options(PRIVATE "/forceInterlockedFunctions-")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(CMAKE_C_COMPILER_ID STREQUAL "MSVC")
|
||||
@@ -650,7 +664,7 @@ if(SDL_ASSEMBLY)
|
||||
if(USE_GCC OR USE_CLANG OR USE_INTELCC)
|
||||
string(APPEND CMAKE_REQUIRED_FLAGS " -mmmx")
|
||||
endif()
|
||||
check_c_source_compiles("
|
||||
check_x86_source_compiles([==[
|
||||
#include <mmintrin.h>
|
||||
void ints_add(int *dest, int *a, int *b, unsigned size) {
|
||||
for (; size >= 2; size -= 2, dest += 2, a += 2, b += 2) {
|
||||
@@ -660,7 +674,7 @@ if(SDL_ASSEMBLY)
|
||||
int main(int argc, char *argv[]) {
|
||||
ints_add((int*)0, (int*)0, (int*)0, 0);
|
||||
return 0;
|
||||
}" COMPILER_SUPPORTS_MMX)
|
||||
}]==] COMPILER_SUPPORTS_MMX)
|
||||
cmake_pop_check_state()
|
||||
if(COMPILER_SUPPORTS_MMX)
|
||||
set(HAVE_MMX TRUE)
|
||||
@@ -671,7 +685,7 @@ if(SDL_ASSEMBLY)
|
||||
if(USE_GCC OR USE_CLANG OR USE_INTELCC)
|
||||
string(APPEND CMAKE_REQUIRED_FLAGS " -msse")
|
||||
endif()
|
||||
check_c_source_compiles("
|
||||
check_x86_source_compiles([==[
|
||||
#include <xmmintrin.h>
|
||||
void floats_add(float *dest, float *a, float *b, unsigned size) {
|
||||
for (; size >= 4; size -= 4, dest += 4, a += 4, b += 4) {
|
||||
@@ -681,7 +695,7 @@ if(SDL_ASSEMBLY)
|
||||
int main(int argc, char **argv) {
|
||||
floats_add((float*)0, (float*)0, (float*)0, 0);
|
||||
return 0;
|
||||
}" COMPILER_SUPPORTS_SSE)
|
||||
}]==] COMPILER_SUPPORTS_SSE)
|
||||
cmake_pop_check_state()
|
||||
if(COMPILER_SUPPORTS_SSE)
|
||||
set(HAVE_SSE TRUE)
|
||||
@@ -692,7 +706,7 @@ if(SDL_ASSEMBLY)
|
||||
if(USE_GCC OR USE_CLANG OR USE_INTELCC)
|
||||
string(APPEND CMAKE_REQUIRED_FLAGS " -msse2")
|
||||
endif()
|
||||
check_c_source_compiles("
|
||||
check_x86_source_compiles([==[
|
||||
#include <emmintrin.h>
|
||||
void doubles_add(double *dest, double *a, double *b, unsigned size) {
|
||||
for (; size >= 4; size -= 4, dest += 4, a += 4, b += 4) {
|
||||
@@ -702,7 +716,7 @@ if(SDL_ASSEMBLY)
|
||||
int main(int argc, char **argv) {
|
||||
doubles_add((double*)0, (double*)0, (double*)0, 0);
|
||||
return 0;
|
||||
}" COMPILER_SUPPORTS_SSE2)
|
||||
}]==] COMPILER_SUPPORTS_SSE2)
|
||||
cmake_pop_check_state()
|
||||
if(COMPILER_SUPPORTS_SSE2)
|
||||
set(HAVE_SSE2 TRUE)
|
||||
@@ -713,7 +727,7 @@ if(SDL_ASSEMBLY)
|
||||
if(USE_GCC OR USE_CLANG OR USE_INTELCC)
|
||||
string(APPEND CMAKE_REQUIRED_FLAGS " -msse3")
|
||||
endif()
|
||||
check_c_source_compiles("
|
||||
check_x86_source_compiles([==[
|
||||
#include <pmmintrin.h>
|
||||
void ints_add(int *dest, int *a, int *b, unsigned size) {
|
||||
for (; size >= 4; size -= 4, dest += 4, a += 4, b += 4) {
|
||||
@@ -723,7 +737,7 @@ if(SDL_ASSEMBLY)
|
||||
int main(int argc, char **argv) {
|
||||
ints_add((int*)0, (int*)0, (int*)0, 0);
|
||||
return 0;
|
||||
}" COMPILER_SUPPORTS_SSE3)
|
||||
}]==] COMPILER_SUPPORTS_SSE3)
|
||||
cmake_pop_check_state()
|
||||
if(COMPILER_SUPPORTS_SSE3)
|
||||
set(HAVE_SSE3 TRUE)
|
||||
@@ -734,7 +748,7 @@ if(SDL_ASSEMBLY)
|
||||
if(USE_GCC OR USE_CLANG OR USE_INTELCC)
|
||||
string(APPEND CMAKE_REQUIRED_FLAGS " -msse4.1")
|
||||
endif()
|
||||
check_c_source_compiles("
|
||||
check_x86_source_compiles([==[
|
||||
#include <smmintrin.h>
|
||||
void ints_mul(int *dest, int *a, int *b, unsigned size) {
|
||||
for (; size >= 4; size -= 4, dest += 4, a += 4, b += 4) {
|
||||
@@ -744,7 +758,7 @@ if(SDL_ASSEMBLY)
|
||||
int main(int argc, char **argv) {
|
||||
ints_mul((int*)0, (int*)0, (int*)0, 0);
|
||||
return 0;
|
||||
}" COMPILER_SUPPORTS_SSE4_1)
|
||||
}]==] COMPILER_SUPPORTS_SSE4_1)
|
||||
cmake_pop_check_state()
|
||||
if(COMPILER_SUPPORTS_SSE4_1)
|
||||
set(HAVE_SSE4_1 TRUE)
|
||||
@@ -753,21 +767,16 @@ if(SDL_ASSEMBLY)
|
||||
if(SDL_SSE4_2)
|
||||
cmake_push_check_state()
|
||||
if(USE_GCC OR USE_CLANG OR USE_INTELCC)
|
||||
string(APPEND CMAKE_REQUIRED_FLAGS " -msse4.2 -mcrc32")
|
||||
string(APPEND CMAKE_REQUIRED_FLAGS " -msse4.2")
|
||||
endif()
|
||||
check_c_source_compiles("
|
||||
check_x86_source_compiles([==[
|
||||
#include <nmmintrin.h>
|
||||
unsigned calc_crc32c(const char *text, unsigned len) {
|
||||
unsigned crc32c = ~0;
|
||||
for (; len >= 4; len -= 4, text += 4) {
|
||||
crc32c = (unsigned)_mm_crc32_u32(crc32c, *(unsigned*)text);
|
||||
}
|
||||
return crc32c;
|
||||
}
|
||||
__m128i bitmask;
|
||||
char data[16];
|
||||
int main(int argc, char **argv) {
|
||||
calc_crc32c(\"SDL_SSE4\",8);
|
||||
bitmask = _mm_cmpgt_epi64(_mm_set1_epi64x(0), _mm_loadu_si128((void*)data));
|
||||
return 0;
|
||||
}" COMPILER_SUPPORTS_SSE4_2)
|
||||
}]==] COMPILER_SUPPORTS_SSE4_2)
|
||||
cmake_pop_check_state()
|
||||
if(COMPILER_SUPPORTS_SSE4_2)
|
||||
set(HAVE_SSE4_2 TRUE)
|
||||
@@ -778,7 +787,7 @@ if(SDL_ASSEMBLY)
|
||||
if(USE_GCC OR USE_CLANG OR USE_INTELCC)
|
||||
string(APPEND CMAKE_REQUIRED_FLAGS " -mavx")
|
||||
endif()
|
||||
check_c_source_compiles("
|
||||
check_x86_source_compiles([==[
|
||||
#include <immintrin.h>
|
||||
void floats_add(float *dest, float *a, float *b, unsigned size) {
|
||||
for (; size >= 8; size -= 8, dest += 8, a += 8, b += 8) {
|
||||
@@ -788,7 +797,7 @@ if(SDL_ASSEMBLY)
|
||||
int main(int argc, char **argv) {
|
||||
floats_add((float*)0, (float*)0, (float*)0, 0);
|
||||
return 0;
|
||||
}" COMPILER_SUPPORTS_AVX)
|
||||
}]==] COMPILER_SUPPORTS_AVX)
|
||||
cmake_pop_check_state()
|
||||
if(COMPILER_SUPPORTS_AVX)
|
||||
set(HAVE_AVX TRUE)
|
||||
@@ -799,7 +808,7 @@ if(SDL_ASSEMBLY)
|
||||
if(USE_GCC OR USE_CLANG OR USE_INTELCC)
|
||||
string(APPEND CMAKE_REQUIRED_FLAGS " -mavx2")
|
||||
endif()
|
||||
check_c_source_compiles("
|
||||
check_x86_source_compiles([==[
|
||||
#include <immintrin.h>
|
||||
void ints_add(int *dest, int *a, int *b, unsigned size) {
|
||||
for (; size >= 8; size -= 8, dest += 8, a += 8, b += 8) {
|
||||
@@ -809,7 +818,7 @@ if(SDL_ASSEMBLY)
|
||||
int main(int argc, char **argv) {
|
||||
ints_add((int*)0, (int*)0, (int*)0, 0);
|
||||
return 0;
|
||||
}" COMPILER_SUPPORTS_AVX2)
|
||||
}]==] COMPILER_SUPPORTS_AVX2)
|
||||
cmake_pop_check_state()
|
||||
if(COMPILER_SUPPORTS_AVX2)
|
||||
set(HAVE_AVX2 TRUE)
|
||||
@@ -820,7 +829,7 @@ if(SDL_ASSEMBLY)
|
||||
if(USE_GCC OR USE_CLANG OR USE_INTELCC)
|
||||
string(APPEND CMAKE_REQUIRED_FLAGS " -mavx512f")
|
||||
endif()
|
||||
check_c_source_compiles("
|
||||
check_x86_source_compiles([==[
|
||||
#include <immintrin.h>
|
||||
void floats_add(float *dest, float *a, float *b, unsigned size) {
|
||||
for (; size >= 16; size -= 16, dest += 16, a += 16, b += 16) {
|
||||
@@ -830,7 +839,7 @@ if(SDL_ASSEMBLY)
|
||||
int main(int argc, char **argv) {
|
||||
floats_add((float*)0, (float*)0, (float*)0, 0);
|
||||
return 0;
|
||||
}" COMPILER_SUPPORTS_AVX512F)
|
||||
}]==] COMPILER_SUPPORTS_AVX512F)
|
||||
cmake_pop_check_state()
|
||||
if(COMPILER_SUPPORTS_AVX512F)
|
||||
set(HAVE_AVX512F TRUE)
|
||||
@@ -838,18 +847,17 @@ if(SDL_ASSEMBLY)
|
||||
endif()
|
||||
|
||||
if(SDL_ARMNEON)
|
||||
check_c_source_compiles("
|
||||
#include <arm_neon.h>
|
||||
void floats_add(float *dest, float *a, float *b, unsigned size) {
|
||||
for (; size >= 4; size -= 4, dest += 4, a += 4, b += 4) {
|
||||
vst1q_f32(dest, vaddq_f32(vld1q_f32(a), vld1q_f32(b)));
|
||||
}
|
||||
check_arm_source_compiles([==[
|
||||
#include <arm_neon.h>
|
||||
void floats_add(float *dest, float *a, float *b, unsigned size) {
|
||||
for (; size >= 4; size -= 4, dest += 4, a += 4, b += 4) {
|
||||
vst1q_f32(dest, vaddq_f32(vld1q_f32(a), vld1q_f32(b)));
|
||||
}
|
||||
int main(int argc, char *argv[]) {
|
||||
floats_add((float*)0, (float*)0, (float*)0, 0);
|
||||
return 0;
|
||||
}" COMPILER_SUPPORTS_ARMNEON)
|
||||
|
||||
}
|
||||
int main(int argc, char *argv[]) {
|
||||
floats_add((float*)0, (float*)0, (float*)0, 0);
|
||||
return 0;
|
||||
}]==] COMPILER_SUPPORTS_ARMNEON)
|
||||
if(COMPILER_SUPPORTS_ARMNEON)
|
||||
set(HAVE_ARMNEON TRUE)
|
||||
endif()
|
||||
@@ -890,7 +898,17 @@ if(SDL_ASSEMBLY)
|
||||
cmake_pop_check_state()
|
||||
|
||||
if(COMPILER_SUPPORTS_LSX AND HAVE_LSXINTRIN_H)
|
||||
set_property(SOURCE "${SDL3_SOURCE_DIR}/src/video/yuv2rgb/yuv_rgb_lsx.c" APPEND PROPERTY COMPILE_OPTIONS "-mlsx")
|
||||
set_property(SOURCE
|
||||
"${SDL3_SOURCE_DIR}/src/video/yuv2rgb/yuv_rgb_lsx.c"
|
||||
"${SDL3_SOURCE_DIR}/src/video/SDL_blit_A.c"
|
||||
"${SDL3_SOURCE_DIR}/src/video/SDL_fillrect.c"
|
||||
APPEND PROPERTY COMPILE_OPTIONS "-mlsx")
|
||||
|
||||
set_property(SOURCE
|
||||
"${SDL3_SOURCE_DIR}/src/video/yuv2rgb/yuv_rgb_lsx.c"
|
||||
"${SDL3_SOURCE_DIR}/src/video/SDL_blit_A.c"
|
||||
"${SDL3_SOURCE_DIR}/src/video/SDL_fillrect.c"
|
||||
PROPERTY SKIP_PRECOMPILE_HEADERS 1)
|
||||
set(HAVE_LSX TRUE)
|
||||
endif()
|
||||
endif()
|
||||
@@ -1052,8 +1070,10 @@ if(SDL_LIBC)
|
||||
cmake_push_check_state()
|
||||
if(MSVC)
|
||||
string(APPEND CMAKE_REQUIRED_FLAGS " -we4244 -WX") # 'conversion' conversion from 'type1' to 'type2', possible loss of data
|
||||
else()
|
||||
elseif(HAVE_GCC_WFLOAT_CONVERSION)
|
||||
string(APPEND CMAKE_REQUIRED_FLAGS " -Wfloat-conversion -Werror")
|
||||
else()
|
||||
string(APPEND CMAKE_REQUIRED_FLAGS " -Wconversion -Werror")
|
||||
endif()
|
||||
foreach(math_fn isinf isnan)
|
||||
string(TOUPPER "${math_fn}" MATH_FN)
|
||||
@@ -1091,6 +1111,7 @@ if(SDL_LIBC)
|
||||
check_symbol_exists(gethostname "unistd.h" HAVE_GETHOSTNAME)
|
||||
check_symbol_exists(getpagesize "unistd.h" HAVE_GETPAGESIZE)
|
||||
check_symbol_exists(sigaction "signal.h" HAVE_SIGACTION)
|
||||
check_symbol_exists(sigtimedwait "signal.h" HAVE_SIGTIMEDWAIT)
|
||||
check_symbol_exists(setjmp "setjmp.h" HAVE_SETJMP)
|
||||
check_symbol_exists(nanosleep "time.h" HAVE_NANOSLEEP)
|
||||
check_symbol_exists(gmtime_r "time.h" HAVE_GMTIME_R)
|
||||
@@ -1336,9 +1357,7 @@ if(ANDROID)
|
||||
set(HAVE_SDL_HAPTIC TRUE)
|
||||
endif()
|
||||
|
||||
if(SDL_HIDAPI)
|
||||
CheckHIDAPI()
|
||||
endif()
|
||||
CheckHIDAPI()
|
||||
|
||||
if(SDL_JOYSTICK)
|
||||
set(SDL_JOYSTICK_ANDROID 1)
|
||||
@@ -1480,6 +1499,9 @@ if(ANDROID)
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
if(TARGET SDL3-static)
|
||||
target_link_options(SDL3-static INTERFACE "-Wl,-u,JNI_OnLoad")
|
||||
endif()
|
||||
|
||||
elseif(EMSCRIPTEN)
|
||||
# Hide noisy warnings that intend to aid mostly during initial stages of porting a new
|
||||
@@ -1905,7 +1927,7 @@ elseif(WINDOWS)
|
||||
target_compile_options(SDL_uclibc PRIVATE $<$<COMPILE_LANGUAGE:C,CXX>:/GS-> $<$<COMPILE_LANGUAGE:C,CXX>:/Gs1048576>)
|
||||
if(SDL_CPU_X86)
|
||||
target_compile_options(SDL3-shared PRIVATE "/arch:SSE")
|
||||
target_compile_options(SDL3-SDL_uclibc PRIVATE "/arch:SSE")
|
||||
target_compile_options(SDL_uclibc PRIVATE "/arch:SSE")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
@@ -2954,7 +2976,7 @@ if(WINDOWS)
|
||||
sdl_glob_sources("${SDL3_SOURCE_DIR}/src/process/windows/*.c")
|
||||
set(SDL_PROCESS_WINDOWS 1)
|
||||
set(HAVE_SDL_PROCESS TRUE)
|
||||
else()
|
||||
elseif(NOT ANDROID)
|
||||
check_c_source_compiles("
|
||||
#include <spawn.h>
|
||||
#include <unistd.h>
|
||||
@@ -3144,14 +3166,15 @@ endforeach()
|
||||
if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/REVISION.txt")
|
||||
file(STRINGS "${CMAKE_CURRENT_SOURCE_DIR}/REVISION.txt" revisions)
|
||||
list(GET revisions 0 revisions_0)
|
||||
string(STRIP "${revisions_0}" SDL_REVISION)
|
||||
string(STRIP "${revisions_0}" revisions_0_stripped)
|
||||
set(SDL_REVISION "SDL-${revisions_0_stripped}")
|
||||
else()
|
||||
set(SDL_REVISION "" CACHE STRING "Custom SDL revision (only used when REVISION.txt does not exist)")
|
||||
endif()
|
||||
if(NOT SDL_REVISION)
|
||||
# If SDL_REVISION is not overrided, use git to describe
|
||||
git_describe(SDL_REVISION_GIT)
|
||||
set(SDL_REVISION "SDL3-${SDL3_VERSION}-${SDL_REVISION_GIT}")
|
||||
set(SDL_REVISION "SDL-${SDL3_VERSION}-${SDL_REVISION_GIT}")
|
||||
endif()
|
||||
|
||||
execute_process(COMMAND "${CMAKE_COMMAND}" -E make_directory "${SDL3_BINARY_DIR}/include-revision/SDL3")
|
||||
|
||||
@@ -781,7 +781,6 @@
|
||||
<ClCompile Include="..\..\src\render\opengl\SDL_shaders_gl.c" />
|
||||
<ClCompile Include="..\..\src\render\opengles2\SDL_render_gles2.c" />
|
||||
<ClCompile Include="..\..\src\render\opengles2\SDL_shaders_gles2.c" />
|
||||
<ClCompile Include="..\..\src\render\SDL_d3dmath.c" />
|
||||
<ClCompile Include="..\..\src\render\SDL_render.c" />
|
||||
<ClCompile Include="..\..\src\render\SDL_render_unsupported.c" />
|
||||
<ClCompile Include="..\..\src\render\SDL_yuv_sw.c" />
|
||||
|
||||
@@ -108,7 +108,6 @@
|
||||
<ClCompile Include="..\..\src\render\opengl\SDL_shaders_gl.c" />
|
||||
<ClCompile Include="..\..\src\render\opengles2\SDL_render_gles2.c" />
|
||||
<ClCompile Include="..\..\src\render\opengles2\SDL_shaders_gles2.c" />
|
||||
<ClCompile Include="..\..\src\render\SDL_d3dmath.c" />
|
||||
<ClCompile Include="..\..\src\render\SDL_render.c" />
|
||||
<ClCompile Include="..\..\src\render\SDL_render_unsupported.c" />
|
||||
<ClCompile Include="..\..\src\render\SDL_yuv_sw.c" />
|
||||
|
||||
@@ -627,7 +627,6 @@
|
||||
<ClCompile Include="..\..\src\render\opengl\SDL_shaders_gl.c" />
|
||||
<ClCompile Include="..\..\src\render\opengles2\SDL_render_gles2.c" />
|
||||
<ClCompile Include="..\..\src\render\opengles2\SDL_shaders_gles2.c" />
|
||||
<ClCompile Include="..\..\src\render\SDL_d3dmath.c" />
|
||||
<ClCompile Include="..\..\src\render\SDL_render.c" />
|
||||
<ClCompile Include="..\..\src\render\SDL_render_unsupported.c" />
|
||||
<ClCompile Include="..\..\src\render\SDL_yuv_sw.c" />
|
||||
|
||||
@@ -1460,7 +1460,6 @@
|
||||
<ClCompile Include="..\..\src\sensor\windows\SDL_windowssensor.c">
|
||||
<Filter>sensor\windows</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\render\SDL_d3dmath.c">
|
||||
<Filter>render</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\render\SDL_render.c">
|
||||
|
||||
@@ -19,10 +19,10 @@
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>FMWK</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>3.2.12</string>
|
||||
<string>3.2.28</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>SDLX</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>3.2.12</string>
|
||||
<string>3.2.28</string>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -292,7 +292,6 @@
|
||||
A7D8BA2523E2514400DCD162 /* SDL_drawpoint.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8FC23E2514000DCD162 /* SDL_drawpoint.c */; };
|
||||
A7D8BA2B23E2514400DCD162 /* SDL_blendfillrect.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8FD23E2514000DCD162 /* SDL_blendfillrect.c */; };
|
||||
A7D8BA3123E2514400DCD162 /* SDL_rotate.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8FE23E2514000DCD162 /* SDL_rotate.h */; };
|
||||
A7D8BA3723E2514400DCD162 /* SDL_d3dmath.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8FF23E2514000DCD162 /* SDL_d3dmath.c */; };
|
||||
A7D8BA4923E2514400DCD162 /* SDL_render_gles2.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A90423E2514000DCD162 /* SDL_render_gles2.c */; };
|
||||
A7D8BA4F23E2514400DCD162 /* SDL_shaders_gles2.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A90523E2514000DCD162 /* SDL_shaders_gles2.h */; };
|
||||
A7D8BA5523E2514400DCD162 /* SDL_gles2funcs.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A90623E2514000DCD162 /* SDL_gles2funcs.h */; };
|
||||
@@ -869,7 +868,6 @@
|
||||
A7D8A8FC23E2514000DCD162 /* SDL_drawpoint.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_drawpoint.c; sourceTree = "<group>"; };
|
||||
A7D8A8FD23E2514000DCD162 /* SDL_blendfillrect.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_blendfillrect.c; sourceTree = "<group>"; };
|
||||
A7D8A8FE23E2514000DCD162 /* SDL_rotate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_rotate.h; sourceTree = "<group>"; };
|
||||
A7D8A8FF23E2514000DCD162 /* SDL_d3dmath.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_d3dmath.c; sourceTree = "<group>"; };
|
||||
A7D8A90423E2514000DCD162 /* SDL_render_gles2.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_render_gles2.c; sourceTree = "<group>"; };
|
||||
A7D8A90523E2514000DCD162 /* SDL_shaders_gles2.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_shaders_gles2.h; sourceTree = "<group>"; };
|
||||
A7D8A90623E2514000DCD162 /* SDL_gles2funcs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_gles2funcs.h; sourceTree = "<group>"; };
|
||||
@@ -2135,7 +2133,6 @@
|
||||
A7D8A90C23E2514000DCD162 /* opengl */,
|
||||
A7D8A90323E2514000DCD162 /* opengles2 */,
|
||||
A7D8A8EF23E2514000DCD162 /* software */,
|
||||
A7D8A8FF23E2514000DCD162 /* SDL_d3dmath.c */,
|
||||
A7D8A8DC23E2514000DCD162 /* SDL_d3dmath.h */,
|
||||
A7D8A8DB23E2514000DCD162 /* SDL_render.c */,
|
||||
E4F7981D2AD8D86A00669F54 /* SDL_render_unsupported.c */,
|
||||
@@ -2833,7 +2830,7 @@
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "# Build an xcframework with both device and simulator files for all platforms.\n# Adapted from an answer in\n# https://developer.apple.com/forums/thread/666335?answerId=685927022#685927022\n\nif [ \"$XCODE_VERSION_ACTUAL\" -lt 1100 ]\nthen\n echo \"error: Building an xcframework requires Xcode 11 minimum.\"\n exit 1\nfi\n\nFRAMEWORK_NAME=\"SDL3\"\nPROJECT_NAME=\"SDL\"\nSCHEME=\"SDL3\"\n\nMACOS_ARCHIVE_PATH=\"${BUILD_DIR}/${CONFIGURATION}/${FRAMEWORK_NAME}-macosx.xcarchive\"\nIOS_SIMULATOR_ARCHIVE_PATH=\"${BUILD_DIR}/${CONFIGURATION}/${FRAMEWORK_NAME}-iphonesimulator.xcarchive\"\nIOS_DEVICE_ARCHIVE_PATH=\"${BUILD_DIR}/${CONFIGURATION}/${FRAMEWORK_NAME}-iphoneos.xcarchive\"\nTVOS_SIMULATOR_ARCHIVE_PATH=\"${BUILD_DIR}/${CONFIGURATION}/${FRAMEWORK_NAME}-appletvsimulator.xcarchive\"\nTVOS_DEVICE_ARCHIVE_PATH=\"${BUILD_DIR}/${CONFIGURATION}/${FRAMEWORK_NAME}-appletvos.xcarchive\"\n\nOUTPUT_DIR=\"./build/\"\n\n# macOS\nxcodebuild archive \\\n ONLY_ACTIVE_ARCH=NO \\\n -scheme \"${SCHEME}\" \\\n -project \"${PROJECT_NAME}.xcodeproj\" \\\n -archivePath ${MACOS_ARCHIVE_PATH} \\\n -destination 'generic/platform=macOS,name=Any Mac' \\\n BUILD_LIBRARY_FOR_DISTRIBUTION=YES \\\n SKIP_INSTALL=NO || exit $?\n \n# iOS simulator\nxcodebuild archive \\\n ONLY_ACTIVE_ARCH=NO \\\n -scheme \"${SCHEME}\" \\\n -project \"${PROJECT_NAME}.xcodeproj\" \\\n -archivePath ${IOS_SIMULATOR_ARCHIVE_PATH} \\\n -destination 'generic/platform=iOS Simulator' \\\n BUILD_LIBRARY_FOR_DISTRIBUTION=YES \\\n SKIP_INSTALL=NO || exit $?\n\n# iOS device\nxcodebuild archive \\\n -scheme \"${SCHEME}\" \\\n -project \"${PROJECT_NAME}.xcodeproj\" \\\n -archivePath ${IOS_DEVICE_ARCHIVE_PATH} \\\n -destination 'generic/platform=iOS' \\\n BUILD_LIBRARY_FOR_DISTRIBUTION=YES \\\n SKIP_INSTALL=NO || exit $?\n\n# tvOS simulator\nxcodebuild archive \\\n ONLY_ACTIVE_ARCH=NO \\\n -scheme \"${SCHEME}\" \\\n -project \"${PROJECT_NAME}.xcodeproj\" \\\n -archivePath ${TVOS_SIMULATOR_ARCHIVE_PATH} \\\n -destination 'generic/platform=tvOS Simulator' \\\n BUILD_LIBRARY_FOR_DISTRIBUTION=YES \\\n SKIP_INSTALL=NO || exit $?\n\n# tvOS device\nxcodebuild archive \\\n -scheme \"${SCHEME}\" \\\n -project \"${PROJECT_NAME}.xcodeproj\" \\\n -archivePath ${TVOS_DEVICE_ARCHIVE_PATH} \\\n -destination 'generic/platform=tvOS' \\\n BUILD_LIBRARY_FOR_DISTRIBUTION=YES \\\n SKIP_INSTALL=NO || exit $?\n\n# Clean-up any existing instance of this xcframework from the Products directory\nrm -rf \"${OUTPUT_DIR}${FRAMEWORK_NAME}.xcframework\"\n\n# Create final xcframework\nxcodebuild -create-xcframework \\\n -framework \"${MACOS_ARCHIVE_PATH}\"/Products/Library/Frameworks/${FRAMEWORK_NAME}.framework \\\n -framework \"${IOS_DEVICE_ARCHIVE_PATH}\"/Products/Library/Frameworks/${FRAMEWORK_NAME}.framework \\\n -framework \"${IOS_SIMULATOR_ARCHIVE_PATH}\"/Products/Library/Frameworks/${FRAMEWORK_NAME}.framework \\\n -framework \"${TVOS_DEVICE_ARCHIVE_PATH}\"/Products/Library/Frameworks/${FRAMEWORK_NAME}.framework \\\n -framework \"${TVOS_SIMULATOR_ARCHIVE_PATH}\"/Products/Library/Frameworks/${FRAMEWORK_NAME}.framework \\\n -output ${OUTPUT_DIR}/${FRAMEWORK_NAME}.xcframework\n\n# Ensure git doesn't pick up on our Products folder. \nrm -rf ${OUTPUT_DIR}/.gitignore\necho \"*\" >> ${OUTPUT_DIR}/.gitignore\n";
|
||||
shellScript = "# Build an xcframework with both device and simulator files for all platforms.\n# Adapted from an answer in\n# https://developer.apple.com/forums/thread/666335?answerId=685927022#685927022\n\nif [ \"$XCODE_VERSION_ACTUAL\" -lt 1100 ]\nthen\n echo \"error: Building an xcframework requires Xcode 11 minimum.\"\n exit 1\nfi\n\nFRAMEWORK_NAME=\"SDL3\"\nPROJECT_NAME=\"SDL\"\nSCHEME=\"SDL3\"\n\nMACOS_ARCHIVE_PATH=\"${BUILD_DIR}/${CONFIGURATION}/${FRAMEWORK_NAME}-macosx.xcarchive\"\nIOS_SIMULATOR_ARCHIVE_PATH=\"${BUILD_DIR}/${CONFIGURATION}/${FRAMEWORK_NAME}-iphonesimulator.xcarchive\"\nIOS_DEVICE_ARCHIVE_PATH=\"${BUILD_DIR}/${CONFIGURATION}/${FRAMEWORK_NAME}-iphoneos.xcarchive\"\nTVOS_SIMULATOR_ARCHIVE_PATH=\"${BUILD_DIR}/${CONFIGURATION}/${FRAMEWORK_NAME}-appletvsimulator.xcarchive\"\nTVOS_DEVICE_ARCHIVE_PATH=\"${BUILD_DIR}/${CONFIGURATION}/${FRAMEWORK_NAME}-appletvos.xcarchive\"\n\nOUTPUT_DIR=\"./build/\"\n\n# macOS\nxcodebuild archive \\\n ONLY_ACTIVE_ARCH=NO \\\n -scheme \"${SCHEME}\" \\\n -project \"${PROJECT_NAME}.xcodeproj\" \\\n -archivePath ${MACOS_ARCHIVE_PATH} \\\n -destination 'generic/platform=macOS,name=Any Mac' \\\n BUILD_LIBRARY_FOR_DISTRIBUTION=YES \\\n SKIP_INSTALL=NO || exit $?\n \n# iOS simulator\nxcodebuild archive \\\n ONLY_ACTIVE_ARCH=NO \\\n -scheme \"${SCHEME}\" \\\n -project \"${PROJECT_NAME}.xcodeproj\" \\\n -archivePath ${IOS_SIMULATOR_ARCHIVE_PATH} \\\n -destination 'generic/platform=iOS Simulator' \\\n BUILD_LIBRARY_FOR_DISTRIBUTION=YES \\\n SKIP_INSTALL=NO || exit $?\n\n# iOS device\nxcodebuild archive \\\n -scheme \"${SCHEME}\" \\\n -project \"${PROJECT_NAME}.xcodeproj\" \\\n -archivePath ${IOS_DEVICE_ARCHIVE_PATH} \\\n -destination 'generic/platform=iOS' \\\n BUILD_LIBRARY_FOR_DISTRIBUTION=YES \\\n SKIP_INSTALL=NO || exit $?\n\n# tvOS simulator\nxcodebuild archive \\\n ONLY_ACTIVE_ARCH=NO \\\n -scheme \"${SCHEME}\" \\\n -project \"${PROJECT_NAME}.xcodeproj\" \\\n -archivePath ${TVOS_SIMULATOR_ARCHIVE_PATH} \\\n -destination 'generic/platform=tvOS Simulator' \\\n BUILD_LIBRARY_FOR_DISTRIBUTION=YES \\\n SKIP_INSTALL=NO || exit $?\n\n# tvOS device\nxcodebuild archive \\\n -scheme \"${SCHEME}\" \\\n -project \"${PROJECT_NAME}.xcodeproj\" \\\n -archivePath ${TVOS_DEVICE_ARCHIVE_PATH} \\\n -destination 'generic/platform=tvOS' \\\n BUILD_LIBRARY_FOR_DISTRIBUTION=YES \\\n SKIP_INSTALL=NO || exit $?\n\n# Clean-up any existing instance of this xcframework from the Products directory\nrm -rf \"${OUTPUT_DIR}${FRAMEWORK_NAME}.xcframework\"\n\n# Create final xcframework\nxcodebuild -create-xcframework \\\n -framework \"${MACOS_ARCHIVE_PATH}\"/Products/Library/Frameworks/${FRAMEWORK_NAME}.framework \\\n -debug-symbols \"${MACOS_ARCHIVE_PATH}\"/dSYMs/$FRAMEWORK_NAME.framework.dSYM \\\n -framework \"${IOS_DEVICE_ARCHIVE_PATH}\"/Products/Library/Frameworks/${FRAMEWORK_NAME}.framework \\\n -debug-symbols \"${IOS_DEVICE_ARCHIVE_PATH}\"/dSYMs/$FRAMEWORK_NAME.framework.dSYM \\\n -framework \"${IOS_SIMULATOR_ARCHIVE_PATH}\"/Products/Library/Frameworks/${FRAMEWORK_NAME}.framework \\\n -debug-symbols \"${IOS_SIMULATOR_ARCHIVE_PATH}\"/dSYMs/$FRAMEWORK_NAME.framework.dSYM \\\n -framework \"${TVOS_DEVICE_ARCHIVE_PATH}\"/Products/Library/Frameworks/${FRAMEWORK_NAME}.framework \\\n -debug-symbols \"${TVOS_DEVICE_ARCHIVE_PATH}\"/dSYMs/$FRAMEWORK_NAME.framework.dSYM \\\n -framework \"${TVOS_SIMULATOR_ARCHIVE_PATH}\"/Products/Library/Frameworks/${FRAMEWORK_NAME}.framework \\\n -debug-symbols \"${TVOS_SIMULATOR_ARCHIVE_PATH}\"/dSYMs/$FRAMEWORK_NAME.framework.dSYM \\\n -output ${OUTPUT_DIR}/${FRAMEWORK_NAME}.xcframework\n\n# Ensure git doesn't pick up on our Products folder. \nrm -rf ${OUTPUT_DIR}/.gitignore\necho \"*\" >> ${OUTPUT_DIR}/.gitignore\n";
|
||||
};
|
||||
/* End PBXShellScriptBuildPhase section */
|
||||
|
||||
@@ -2903,7 +2900,6 @@
|
||||
A7D8BBE723E2574800DCD162 /* SDL_uikitviewcontroller.m in Sources */,
|
||||
A7D8ADF223E2514100DCD162 /* SDL_blit_A.c in Sources */,
|
||||
A7D8BBDD23E2574800DCD162 /* SDL_uikitmodes.m in Sources */,
|
||||
A7D8BA3723E2514400DCD162 /* SDL_d3dmath.c in Sources */,
|
||||
F3A9AE9C2C8A13C100AAC390 /* SDL_pipeline_gpu.c in Sources */,
|
||||
75E0915A241EA924004729E1 /* SDL_virtualjoystick.c in Sources */,
|
||||
F338A11A2D1B37E4007CDFDF /* SDL_tray.c in Sources */,
|
||||
@@ -3086,7 +3082,7 @@
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
DEPLOYMENT_POSTPROCESSING = YES;
|
||||
DYLIB_COMPATIBILITY_VERSION = 201.0.0;
|
||||
DYLIB_CURRENT_VERSION = 201.12.0;
|
||||
DYLIB_CURRENT_VERSION = 201.28.0;
|
||||
DYLIB_INSTALL_NAME_BASE = "@rpath";
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
GCC_ALTIVEC_EXTENSIONS = YES;
|
||||
@@ -3121,7 +3117,7 @@
|
||||
"@loader_path/Frameworks",
|
||||
);
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.13;
|
||||
MARKETING_VERSION = 3.2.12;
|
||||
MARKETING_VERSION = 3.2.28;
|
||||
OTHER_LDFLAGS = "$(CONFIG_FRAMEWORK_LDFLAGS)";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = org.libsdl.SDL3;
|
||||
PRODUCT_NAME = SDL3;
|
||||
@@ -3138,6 +3134,8 @@
|
||||
baseConfigurationReference = F3F7BE3B2CBD79D200C984AF /* config.xcconfig */;
|
||||
buildSettings = {
|
||||
CLANG_LINK_OBJC_RUNTIME = NO;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
|
||||
OTHER_LDFLAGS = "-liconv";
|
||||
SUPPORTS_MACCATALYST = YES;
|
||||
};
|
||||
@@ -3150,7 +3148,7 @@
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
DYLIB_COMPATIBILITY_VERSION = 201.0.0;
|
||||
DYLIB_CURRENT_VERSION = 201.12.0;
|
||||
DYLIB_CURRENT_VERSION = 201.28.0;
|
||||
DYLIB_INSTALL_NAME_BASE = "@rpath";
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
ENABLE_TESTABILITY = YES;
|
||||
@@ -3182,7 +3180,7 @@
|
||||
"@loader_path/Frameworks",
|
||||
);
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.13;
|
||||
MARKETING_VERSION = 3.2.12;
|
||||
MARKETING_VERSION = 3.2.28;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
OTHER_LDFLAGS = "$(CONFIG_FRAMEWORK_LDFLAGS)";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = org.libsdl.SDL3;
|
||||
@@ -3200,6 +3198,8 @@
|
||||
baseConfigurationReference = F3F7BE3B2CBD79D200C984AF /* config.xcconfig */;
|
||||
buildSettings = {
|
||||
CLANG_LINK_OBJC_RUNTIME = NO;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
|
||||
OTHER_LDFLAGS = "-liconv";
|
||||
SUPPORTS_MACCATALYST = YES;
|
||||
};
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
Title SDL 3.2.12
|
||||
Title SDL 3.2.28
|
||||
Version 1
|
||||
Description SDL Library for macOS (http://www.libsdl.org)
|
||||
DefaultLocation /Library/Frameworks
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
# SDL3 CMake configuration file:
|
||||
# This file is meant to be placed in Resources/CMake of a SDL3 framework
|
||||
# This file is meant to be placed in Resources/CMake of a SDL3 framework for macOS,
|
||||
# or in the CMake directory of a SDL3 framework for iOS / tvOS / visionOS.
|
||||
|
||||
# INTERFACE_LINK_OPTIONS needs CMake 3.12
|
||||
cmake_minimum_required(VERSION 3.12)
|
||||
cmake_minimum_required(VERSION 3.12...4.0)
|
||||
|
||||
include(FeatureSummary)
|
||||
set_package_properties(SDL3 PROPERTIES
|
||||
@@ -31,16 +32,31 @@ endmacro()
|
||||
|
||||
set(SDL3_FOUND TRUE)
|
||||
|
||||
# Compute the installation prefix relative to this file.
|
||||
set(_sdl3_framework_path "${CMAKE_CURRENT_LIST_DIR}") # > /SDL3.framework/Resources/CMake/
|
||||
get_filename_component(_sdl3_framework_path "${_sdl3_framework_path}" REALPATH) # > /SDL3.framework/Versions/Current/Resources/CMake
|
||||
get_filename_component(_sdl3_framework_path "${_sdl3_framework_path}" REALPATH) # > /SDL3.framework/Versions/A/Resources/CMake/
|
||||
get_filename_component(_sdl3_framework_path "${_sdl3_framework_path}" PATH) # > /SDL3.framework/Versions/A/Resources/
|
||||
get_filename_component(_sdl3_framework_path "${_sdl3_framework_path}" PATH) # > /SDL3.framework/Versions/A/
|
||||
get_filename_component(_sdl3_framework_path "${_sdl3_framework_path}" PATH) # > /SDL3.framework/Versions/
|
||||
get_filename_component(_sdl3_framework_path "${_sdl3_framework_path}" PATH) # > /SDL3.framework/
|
||||
get_filename_component(_sdl3_framework_parent_path "${_sdl3_framework_path}" PATH) # > /
|
||||
# Compute the installation prefix relative to this file:
|
||||
# search upwards for the .framework directory
|
||||
set(_current_path "${CMAKE_CURRENT_LIST_DIR}")
|
||||
get_filename_component(_current_path "${_current_path}" REALPATH)
|
||||
set(_sdl3_framework_path "")
|
||||
|
||||
while(NOT _sdl3_framework_path)
|
||||
if(IS_DIRECTORY "${_current_path}" AND "${_current_path}" MATCHES "/SDL3\\.framework$")
|
||||
set(_sdl3_framework_path "${_current_path}")
|
||||
break()
|
||||
endif()
|
||||
get_filename_component(_next_current_path "${_current_path}" DIRECTORY)
|
||||
if("${_current_path}" STREQUAL "${_next_current_path}")
|
||||
break()
|
||||
endif()
|
||||
set(_current_path "${_next_current_path}")
|
||||
endwhile()
|
||||
unset(_current_path)
|
||||
unset(_next_current_path)
|
||||
|
||||
if(NOT _sdl3_framework_path)
|
||||
message(FATAL_ERROR "Could not find SDL3.framework root from ${CMAKE_CURRENT_LIST_DIR}")
|
||||
endif()
|
||||
|
||||
get_filename_component(_sdl3_framework_parent_path "${_sdl3_framework_path}" PATH)
|
||||
|
||||
# All targets are created, even when some might not be requested though COMPONENTS.
|
||||
# This is done for compatibility with CMake generated SDL3-target.cmake files.
|
||||
|
||||
@@ -1,16 +1,26 @@
|
||||
# based on the files generated by CMake's write_basic_package_version_file
|
||||
|
||||
# SDL CMake version configuration file:
|
||||
# This file is meant to be placed in Resources/CMake of a SDL3 framework
|
||||
# This file is meant to be placed in Resources/CMake of a SDL3 framework for macOS,
|
||||
# or in the CMake directory of a SDL3 framework for iOS / tvOS / visionOS.
|
||||
|
||||
cmake_minimum_required(VERSION 3.12)
|
||||
cmake_minimum_required(VERSION 3.12...4.0)
|
||||
|
||||
if(NOT EXISTS "${CMAKE_CURRENT_LIST_DIR}/../../Headers/SDL_version.h")
|
||||
message(AUTHOR_WARNING "Could not find SDL_version.h. This script is meant to be placed in the Resources/CMake directory of SDL2.framework")
|
||||
# Find SDL_version.h
|
||||
set(_sdl_version_h_path "")
|
||||
if(EXISTS "${CMAKE_CURRENT_LIST_DIR}/../../Headers/SDL_version.h")
|
||||
set(_sdl_version_h_path "${CMAKE_CURRENT_LIST_DIR}/../../Headers/SDL_version.h")
|
||||
elseif(EXISTS "${CMAKE_CURRENT_LIST_DIR}/../Headers/SDL_version.h")
|
||||
set(_sdl_version_h_path "${CMAKE_CURRENT_LIST_DIR}/../Headers/SDL_version.h")
|
||||
endif()
|
||||
|
||||
if(NOT _sdl_version_h_path)
|
||||
message(AUTHOR_WARNING "Could not find SDL_version.h. This script is meant to be placed in the Resources/CMake directory or the CMake directory of SDL3.framework.")
|
||||
set(PACKAGE_VERSION_UNSUITABLE TRUE)
|
||||
return()
|
||||
endif()
|
||||
|
||||
file(READ "${CMAKE_CURRENT_LIST_DIR}/../../Headers/SDL_version.h" _sdl_version_h)
|
||||
file(READ "${_sdl_version_h_path}" _sdl_version_h)
|
||||
string(REGEX MATCH "#define[ \t]+SDL_MAJOR_VERSION[ \t]+([0-9]+)" _sdl_major_re "${_sdl_version_h}")
|
||||
set(_sdl_major "${CMAKE_MATCH_1}")
|
||||
string(REGEX MATCH "#define[ \t]+SDL_MINOR_VERSION[ \t]+([0-9]+)" _sdl_minor_re "${_sdl_version_h}")
|
||||
@@ -21,9 +31,12 @@ if(_sdl_major_re AND _sdl_minor_re AND _sdl_micro_re)
|
||||
set(PACKAGE_VERSION "${_sdl_major}.${_sdl_minor}.${_sdl_micro}")
|
||||
else()
|
||||
message(AUTHOR_WARNING "Could not extract version from SDL_version.h.")
|
||||
set(PACKAGE_VERSION_UNSUITABLE TRUE)
|
||||
return()
|
||||
endif()
|
||||
|
||||
unset(_sdl_version_h)
|
||||
unset(_sdl_version_h_path)
|
||||
unset(_sdl_major_re)
|
||||
unset(_sdl_major)
|
||||
unset(_sdl_minor_re)
|
||||
|
||||
@@ -92,7 +92,7 @@ if(NOT TARGET SDL3::Headers)
|
||||
add_library(SDL3::Headers INTERFACE IMPORTED)
|
||||
set_target_properties(SDL3::Headers
|
||||
PROPERTIES
|
||||
INTERFACE_COMPILE_OPTIONS "SHELL:-F \"${_sdl3_framework_parent_path}\""
|
||||
INTERFACE_COMPILE_OPTIONS "-F${_sdl3_framework_parent_path}"
|
||||
)
|
||||
endif()
|
||||
set(SDL3_Headers_FOUND TRUE)
|
||||
|
||||
@@ -16,6 +16,7 @@ set(_sdl3_version_h "${_sdl3_framework}/Headers/SDL_version.h")
|
||||
|
||||
if(NOT EXISTS "${_sdl3_version_h}")
|
||||
message(AUTHOR_WARNING "Cannot not find ${_sdl3_framework}. This script is meant to be placed in share/cmake/SDL3, next to SDL3.xcframework")
|
||||
set(PACKAGE_VERSION_UNSUITABLE TRUE)
|
||||
return()
|
||||
endif()
|
||||
|
||||
@@ -36,6 +37,7 @@ if(_sdl_major_re AND _sdl_minor_re AND _sdl_micro_re)
|
||||
set(PACKAGE_VERSION "${_sdl_major}.${_sdl_minor}.${_sdl_micro}")
|
||||
else()
|
||||
message(AUTHOR_WARNING "Could not extract version from SDL_version.h.")
|
||||
set(PACKAGE_VERSION_UNSUITABLE TRUE)
|
||||
return()
|
||||
endif()
|
||||
|
||||
|
||||
@@ -7,4 +7,4 @@
|
||||
APP_ABI := armeabi-v7a arm64-v8a x86 x86_64
|
||||
|
||||
# Min runtime API level
|
||||
APP_PLATFORM=android-16
|
||||
APP_PLATFORM=android-21
|
||||
+2
@@ -51,6 +51,8 @@
|
||||
boolean supportsRelativeMouse();
|
||||
int openFileDescriptor(java.lang.String, java.lang.String);
|
||||
boolean showFileDialog(java.lang.String[], boolean, boolean, int);
|
||||
java.lang.String getPreferredLocales();
|
||||
java.lang.String formatLocale(java.util.Locale);
|
||||
}
|
||||
|
||||
-keep,includedescriptorclasses,allowoptimization class org.libsdl.app.HIDDeviceManager {
|
||||
|
||||
@@ -23,6 +23,7 @@ import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.LocaleList;
|
||||
import android.os.Message;
|
||||
import android.os.ParcelFileDescriptor;
|
||||
import android.util.DisplayMetrics;
|
||||
@@ -60,7 +61,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
|
||||
private static final String TAG = "SDL";
|
||||
private static final int SDL_MAJOR_VERSION = 3;
|
||||
private static final int SDL_MINOR_VERSION = 2;
|
||||
private static final int SDL_MICRO_VERSION = 12;
|
||||
private static final int SDL_MICRO_VERSION = 28;
|
||||
/*
|
||||
// Display InputType.SOURCE/CLASS of events and devices
|
||||
//
|
||||
@@ -1127,6 +1128,11 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
|
||||
int orientation_landscape = -1;
|
||||
int orientation_portrait = -1;
|
||||
|
||||
if (w <= 1 || h <= 1) {
|
||||
// Invalid width/height, ignore this request
|
||||
return;
|
||||
}
|
||||
|
||||
/* If set, hint "explicitly controls which UI orientations are allowed". */
|
||||
if (hint.contains("LandscapeRight") && hint.contains("LandscapeLeft")) {
|
||||
orientation_landscape = ActivityInfo.SCREEN_ORIENTATION_USER_LANDSCAPE;
|
||||
@@ -2116,6 +2122,44 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
|
||||
int requestCode;
|
||||
boolean multipleChoice;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called by SDL using JNI.
|
||||
*/
|
||||
public static String getPreferredLocales() {
|
||||
String result = "";
|
||||
if (Build.VERSION.SDK_INT >= 24 /* Android 7 (N) */) {
|
||||
LocaleList locales = LocaleList.getAdjustedDefault();
|
||||
for (int i = 0; i < locales.size(); i++) {
|
||||
if (i != 0) result += ",";
|
||||
result += formatLocale(locales.get(i));
|
||||
}
|
||||
} else if (mCurrentLocale != null) {
|
||||
result = formatLocale(mCurrentLocale);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static String formatLocale(Locale locale) {
|
||||
String result = "";
|
||||
String lang = "";
|
||||
if (locale.getLanguage() == "in") {
|
||||
// Indonesian is "id" according to ISO 639.2, but on Android is "in" because of Java backwards compatibility
|
||||
lang = "id";
|
||||
} else if (locale.getLanguage() == "") {
|
||||
// Make sure language is never empty
|
||||
lang = "und";
|
||||
} else {
|
||||
lang = locale.getLanguage();
|
||||
}
|
||||
|
||||
if (locale.getCountry() == "") {
|
||||
result = lang;
|
||||
} else {
|
||||
result = lang + "_" + locale.getCountry();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2157,7 +2201,11 @@ class SDLClipboardHandler implements
|
||||
}
|
||||
|
||||
public boolean clipboardHasText() {
|
||||
return mClipMgr.hasPrimaryClip();
|
||||
if (Build.VERSION.SDK_INT >= 28 /* Android 9 (P) */) {
|
||||
return mClipMgr.hasPrimaryClip();
|
||||
} else {
|
||||
return mClipMgr.hasText();
|
||||
}
|
||||
}
|
||||
|
||||
public String clipboardGetText() {
|
||||
@@ -2175,10 +2223,19 @@ class SDLClipboardHandler implements
|
||||
}
|
||||
|
||||
public void clipboardSetText(String string) {
|
||||
mClipMgr.removePrimaryClipChangedListener(this);
|
||||
ClipData clip = ClipData.newPlainText(null, string);
|
||||
mClipMgr.setPrimaryClip(clip);
|
||||
mClipMgr.addPrimaryClipChangedListener(this);
|
||||
mClipMgr.removePrimaryClipChangedListener(this);
|
||||
if (string.isEmpty()) {
|
||||
if (Build.VERSION.SDK_INT >= 28 /* Android 9 (P) */) {
|
||||
mClipMgr.clearPrimaryClip();
|
||||
} else {
|
||||
ClipData clip = ClipData.newPlainText(null, "");
|
||||
mClipMgr.setPrimaryClip(clip);
|
||||
}
|
||||
} else {
|
||||
ClipData clip = ClipData.newPlainText(null, string);
|
||||
mClipMgr.setPrimaryClip(clip);
|
||||
}
|
||||
mClipMgr.addPrimaryClipChangedListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -15,6 +15,7 @@ import android.view.Display;
|
||||
import android.view.InputDevice;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.PointerIcon;
|
||||
import android.view.Surface;
|
||||
import android.view.SurfaceHolder;
|
||||
import android.view.SurfaceView;
|
||||
@@ -362,6 +363,16 @@ public class SDLSurface extends SurfaceView implements SurfaceHolder.Callback,
|
||||
}
|
||||
}
|
||||
|
||||
// Prevent android internal NullPointerException (https://github.com/libsdl-org/SDL/issues/13306)
|
||||
@Override
|
||||
public PointerIcon onResolvePointerIcon(MotionEvent event, int pointerIndex) {
|
||||
try {
|
||||
return super.onResolvePointerIcon(event, pointerIndex);
|
||||
} catch (NullPointerException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// Captured pointer events for API 26.
|
||||
public boolean onCapturedPointerEvent(MotionEvent event)
|
||||
{
|
||||
|
||||
@@ -542,6 +542,7 @@ class AndroidApiVersion:
|
||||
def __repr__(self) -> str:
|
||||
return f"<{self.name} ({'.'.join(str(v) for v in self.ints)})>"
|
||||
|
||||
ANDROID_ABI_EXTRA_LINK_OPTIONS = {}
|
||||
|
||||
class Releaser:
|
||||
def __init__(self, release_info: dict, commit: str, revision: str, root: Path, dist_path: Path, section_printer: SectionPrinter, executer: Executer, cmake_generator: str, deps_path: Path, overwrite: bool, github: bool, fast: bool):
|
||||
@@ -1013,6 +1014,7 @@ class Releaser:
|
||||
android_devel_file_tree = ArchiveFileTree()
|
||||
|
||||
for android_abi in android_abis:
|
||||
extra_link_options = ANDROID_ABI_EXTRA_LINK_OPTIONS.get(android_abi, "")
|
||||
with self.section_printer.group(f"Building for Android {android_api} {android_abi}"):
|
||||
build_dir = self.root / "build-android" / f"{android_abi}-build"
|
||||
install_dir = self.root / "install-android" / f"{android_abi}-install"
|
||||
@@ -1023,8 +1025,12 @@ class Releaser:
|
||||
"cmake",
|
||||
"-S", str(self.root),
|
||||
"-B", str(build_dir),
|
||||
f'''-DCMAKE_C_FLAGS="-ffile-prefix-map={self.root}=/src/{self.project}"''',
|
||||
f'''-DCMAKE_CXX_FLAGS="-ffile-prefix-map={self.root}=/src/{self.project}"''',
|
||||
# NDK 21e does not support -ffile-prefix-map
|
||||
# f'''-DCMAKE_C_FLAGS="-ffile-prefix-map={self.root}=/src/{self.project}"''',
|
||||
# f'''-DCMAKE_CXX_FLAGS="-ffile-prefix-map={self.root}=/src/{self.project}"''',
|
||||
f"-DANDROID_USE_LEGACY_TOOLCHAIN=0",
|
||||
f"-DCMAKE_EXE_LINKER_FLAGS={extra_link_options}",
|
||||
f"-DCMAKE_SHARED_LINKER_FLAGS={extra_link_options}",
|
||||
f"-DCMAKE_TOOLCHAIN_FILE={cmake_toolchain_file}",
|
||||
f"-DCMAKE_PREFIX_PATH={str(android_deps_path)}",
|
||||
f"-DCMAKE_FIND_ROOT_PATH_MODE_PACKAGE=BOTH",
|
||||
@@ -1121,8 +1127,7 @@ class Releaser:
|
||||
for dep, depinfo in self.release_info.get("dependencies", {}).items():
|
||||
startswith = depinfo["startswith"]
|
||||
dep_repo = depinfo["repo"]
|
||||
# FIXME: dropped "--exclude-pre-releases"
|
||||
dep_string_data = self.executer.check_output(["gh", "-R", dep_repo, "release", "list", "--exclude-drafts", "--json", "name,createdAt,tagName", "--jq", f'[.[]|select(.name|startswith("{startswith}"))]|max_by(.createdAt)']).strip()
|
||||
dep_string_data = self.executer.check_output(["gh", "-R", dep_repo, "release", "list", "--exclude-drafts", "--exclude-pre-releases", "--json", "name,createdAt,tagName", "--jq", f'[.[]|select(.name|startswith("{startswith}"))]|max_by(.createdAt)']).strip()
|
||||
dep_data = json.loads(dep_string_data)
|
||||
dep_tag = dep_data["tagName"]
|
||||
dep_version = dep_data["name"]
|
||||
@@ -1512,7 +1517,7 @@ def main(argv=None) -> int:
|
||||
if args.android_home is None or not Path(args.android_home).is_dir():
|
||||
parser.error("Invalid $ANDROID_HOME or --android-home: must be a directory containing the Android SDK")
|
||||
if args.android_ndk_home is None or not Path(args.android_ndk_home).is_dir():
|
||||
parser.error("Invalid $ANDROID_NDK_HOME or --android_ndk_home: must be a directory containing the Android NDK")
|
||||
parser.error("Invalid $ANDROID_NDK_HOME or --android-ndk-home: must be a directory containing the Android NDK")
|
||||
if args.android_api is None:
|
||||
with section_printer.group("Detect Android APIS"):
|
||||
args.android_api = releaser._detect_android_api(android_home=args.android_home)
|
||||
@@ -1530,7 +1535,7 @@ def main(argv=None) -> int:
|
||||
parser.error("Invalid --android-api, and/or could not be detected")
|
||||
android_api_path = Path(args.android_home) / f"platforms/{args.android_api.name}"
|
||||
if not android_api_path.is_dir():
|
||||
parser.error(f"Android API directory does not exist ({android_api_path})")
|
||||
logger.warning(f"Android API directory does not exist ({android_api_path})")
|
||||
with section_printer.group("Android arguments"):
|
||||
print(f"android_home = {args.android_home}")
|
||||
print(f"android_ndk_home = {args.android_ndk_home}")
|
||||
|
||||
Executable
+127
@@ -0,0 +1,127 @@
|
||||
#!/bin/bash
|
||||
progname="${0##*/}"
|
||||
progname="${progname%.sh}"
|
||||
|
||||
# usage: check_elf_alignment.sh [path to *.so files|path to *.apk]
|
||||
|
||||
cleanup_trap() {
|
||||
if [ -n "${tmp}" -a -d "${tmp}" ]; then
|
||||
rm -rf ${tmp}
|
||||
fi
|
||||
exit $1
|
||||
}
|
||||
|
||||
usage() {
|
||||
echo "Host side script to check the ELF alignment of shared libraries."
|
||||
echo "Shared libraries are reported ALIGNED when their ELF regions are"
|
||||
echo "16 KB or 64 KB aligned. Otherwise they are reported as UNALIGNED."
|
||||
echo
|
||||
echo "Usage: ${progname} [input-path|input-APK|input-APEX]"
|
||||
}
|
||||
|
||||
if [ ${#} -ne 1 ]; then
|
||||
usage
|
||||
exit
|
||||
fi
|
||||
|
||||
case ${1} in
|
||||
--help | -h | -\?)
|
||||
usage
|
||||
exit
|
||||
;;
|
||||
|
||||
*)
|
||||
dir="${1}"
|
||||
;;
|
||||
esac
|
||||
|
||||
if ! [ -f "${dir}" -o -d "${dir}" ]; then
|
||||
echo "Invalid file: ${dir}" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ "${dir}" == *.apk ]]; then
|
||||
trap 'cleanup_trap' EXIT
|
||||
|
||||
echo
|
||||
echo "Recursively analyzing $dir"
|
||||
echo
|
||||
|
||||
if { zipalign --help 2>&1 | grep -q "\-P <pagesize_kb>"; }; then
|
||||
echo "=== APK zip-alignment ==="
|
||||
zipalign -v -c -P 16 4 "${dir}" | egrep 'lib/arm64-v8a|lib/x86_64|Verification'
|
||||
echo "========================="
|
||||
else
|
||||
echo "NOTICE: Zip alignment check requires build-tools version 35.0.0-rc3 or higher."
|
||||
echo " You can install the latest build-tools by running the below command"
|
||||
echo " and updating your \$PATH:"
|
||||
echo
|
||||
echo " sdkmanager \"build-tools;35.0.0-rc3\""
|
||||
fi
|
||||
|
||||
dir_filename=$(basename "${dir}")
|
||||
tmp=$(mktemp -d -t "${dir_filename%.apk}_out_XXXXX")
|
||||
unzip "${dir}" lib/* -d "${tmp}" >/dev/null 2>&1
|
||||
dir="${tmp}"
|
||||
fi
|
||||
|
||||
if [[ "${dir}" == *.apex ]]; then
|
||||
trap 'cleanup_trap' EXIT
|
||||
|
||||
echo
|
||||
echo "Recursively analyzing $dir"
|
||||
echo
|
||||
|
||||
dir_filename=$(basename "${dir}")
|
||||
tmp=$(mktemp -d -t "${dir_filename%.apex}_out_XXXXX")
|
||||
deapexer extract "${dir}" "${tmp}" || { echo "Failed to deapex." && exit 1; }
|
||||
dir="${tmp}"
|
||||
fi
|
||||
|
||||
RED="\e[31m"
|
||||
GREEN="\e[32m"
|
||||
ENDCOLOR="\e[0m"
|
||||
|
||||
unaligned_libs=()
|
||||
unaligned_critical_libs=()
|
||||
|
||||
echo
|
||||
echo "=== ELF alignment ==="
|
||||
|
||||
matches="$(find "${dir}" -type f)"
|
||||
IFS=$'\n'
|
||||
for match in $matches; do
|
||||
# We could recursively call this script or rewrite it to though.
|
||||
[[ "${match}" == *".apk" ]] && echo "WARNING: doesn't recursively inspect .apk file: ${match}"
|
||||
[[ "${match}" == *".apex" ]] && echo "WARNING: doesn't recursively inspect .apex file: ${match}"
|
||||
|
||||
[[ $(file "${match}") == *"ELF"* ]] || continue
|
||||
|
||||
res="$(objdump -p "${match}" | grep LOAD | awk '{ print $NF }' | head -1)"
|
||||
if [[ $res =~ 2\*\*(1[4-9]|[2-9][0-9]|[1-9][0-9]{2,}) ]]; then
|
||||
echo -e "${match}: ${GREEN}ALIGNED${ENDCOLOR} ($res)"
|
||||
else
|
||||
unaligned_libs+=("${match}")
|
||||
# Check if this is a critical architecture (arm64-v8a or x86_64)
|
||||
if [[ "${match}" == *"arm64-v8a"* ]] || [[ "${match}" == *"x86_64"* ]]; then
|
||||
unaligned_critical_libs+=("${match}")
|
||||
echo -e "${match}: ${RED}UNALIGNED${ENDCOLOR} ($res)"
|
||||
else
|
||||
echo -e "${match}: UNALIGNED ($res)"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
if [ ${#unaligned_libs[@]} -gt 0 ]; then
|
||||
echo -e "Found ${#unaligned_libs[@]} unaligned libs (only arm64-v8a/x86_64 libs need to be aligned).${ENDCOLOR}"
|
||||
fi
|
||||
echo "====================="
|
||||
|
||||
# Exit with appropriate code: 1 if critical unaligned libs found, 0 otherwise
|
||||
if [ ${#unaligned_critical_libs[@]} -gt 0 ]; then
|
||||
echo -e "${RED}Found ${#unaligned_critical_libs[@]} critical unaligned libs.${ENDCOLOR}"
|
||||
exit 1
|
||||
else
|
||||
echo -e "${GREEN}ELF Verification Successful${ENDCOLOR}"
|
||||
exit 0
|
||||
fi
|
||||
@@ -183,7 +183,7 @@
|
||||
],
|
||||
"api-minimum": 21,
|
||||
"api-target": 35,
|
||||
"ndk-minimum": 21,
|
||||
"ndk-minimum": 28,
|
||||
"aar-files": {
|
||||
"": [
|
||||
"android-project/app/proguard-rules.pro:proguard.txt",
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# libtool assumes that the compiler can handle the -fPIC flag
|
||||
# This isn't always true (for example, nasm can't handle it)
|
||||
command=""
|
||||
while [ $# -gt 0 ]; do
|
||||
case "$1" in
|
||||
-?PIC)
|
||||
# Ignore -fPIC and -DPIC options
|
||||
;;
|
||||
-fno-common)
|
||||
# Ignore -fPIC and -DPIC options
|
||||
;;
|
||||
*)
|
||||
command="$command $1"
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
echo $command
|
||||
exec $command
|
||||
@@ -424,7 +424,11 @@ sub dewikify_chunk {
|
||||
$str .= "\n```$codelang\n$code\n```\n";
|
||||
}
|
||||
} elsif ($dewikify_mode eq 'manpage') {
|
||||
$str =~ s/\./\\[char46]/gms; # make sure these can't become control codes.
|
||||
# make sure these can't become part of roff syntax.
|
||||
$str =~ s/\./\\[char46]/gms;
|
||||
$str =~ s/"/\\(dq/gms;
|
||||
$str =~ s/'/\\(aq/gms;
|
||||
|
||||
if ($wikitype eq 'mediawiki') {
|
||||
# Dump obvious wikilinks.
|
||||
if (defined $apiprefixregex) {
|
||||
@@ -449,33 +453,52 @@ sub dewikify_chunk {
|
||||
# bullets
|
||||
$str =~ s/^\* /\n\\\(bu /gm;
|
||||
} elsif ($wikitype eq 'md') {
|
||||
# bullets
|
||||
$str =~ s/^\- /\n\\(bu /gm;
|
||||
# merge paragraphs
|
||||
$str =~ s/^[ \t]+//gm;
|
||||
$str =~ s/([^\-\n])\n([^\-\n])/$1 $2/g;
|
||||
$str =~ s/\n\n/\n.PP\n/g;
|
||||
|
||||
# Dump obvious wikilinks.
|
||||
if (defined $apiprefixregex) {
|
||||
$str =~ s/\[(\`?$apiprefixregex[a-zA-Z0-9_]+\`?)\]\($apiprefixregex[a-zA-Z0-9_]+\)/\n.BR $1\n/gms;
|
||||
my $apr = $apiprefixregex;
|
||||
if(!($apr =~ /\A\(.*\)\Z/s)) {
|
||||
# we're relying on the apiprefixregex having a capturing group.
|
||||
$apr = "(" . $apr . ")";
|
||||
}
|
||||
$str =~ s/(\S*?)\[\`?($apr[a-zA-Z0-9_]+)\`?\]\($apr[a-zA-Z0-9_]+\)(\S*)\s*/\n.BR "" "$1" "$2" "$5"\n/gm;
|
||||
# handle cases like "[x](x), [y](y), [z](z)" being separated.
|
||||
while($str =~ s/(\.BR[^\n]*)\n\n\.BR/$1\n.BR/gm) {}
|
||||
}
|
||||
|
||||
# links
|
||||
$str =~ s/\[(.*?)]\((https?\:\/\/.*?)\)/\n.URL "$2" "$1"\n/g;
|
||||
|
||||
# <code></code> is also popular. :/
|
||||
$str =~ s/\s*\`(.*?)\`\s*/\n.BR $1\n/gms;
|
||||
$str =~ s/\s*(\S*?)\`([^\n]*?)\`(\S*)\s*/\n.BR "" "$1" "$2" "$3"\n/gms;
|
||||
|
||||
# bold+italic (this looks bad, just make it bold).
|
||||
$str =~ s/\s*\*\*\*(.*?)\*\*\*\s*/\n.B $1\n/gms;
|
||||
$str =~ s/\s*(\S*?)\*\*\*([^\n]*?)\*\*\*(\S*)\s*/\n.BR "" "$1" "$2" "$3"\n/gms;
|
||||
|
||||
# bold
|
||||
$str =~ s/\s*\*\*(.*?)\*\*\s*/\n.B $1\n/gms;
|
||||
$str =~ s/\s*(\S*?)\*\*([^\n]*?)\*\*(\S*)\s*/\n.BR "" "$1" "$2" "$3"\n/gms;
|
||||
|
||||
# italic
|
||||
$str =~ s/\s*\*(.*?)\*\s*/\n.I $1\n/gms;
|
||||
|
||||
# bullets
|
||||
$str =~ s/^\- /\n\\\(bu /gm;
|
||||
$str =~ s/\s*(\S*?)\*([^\n]*?)\*(\S*)\s*/\n.IR "" "$1" "$2" "$3"\n/gms;
|
||||
}
|
||||
|
||||
# cleanup unnecessary quotes
|
||||
$str =~ s/(\.[IB]R?)(.*?) ""\n/$1$2\n/gm;
|
||||
$str =~ s/(\.[IB]R?) "" ""(.*?)\n/$1$2\n/gm;
|
||||
$str =~ s/"(\S+)"/$1/gm;
|
||||
# cleanup unnecessary whitespace
|
||||
$str =~ s/ +\n/\n/gm;
|
||||
|
||||
if (defined $code) {
|
||||
$code =~ s/\A\n+//gms;
|
||||
$code =~ s/\n+\Z//gms;
|
||||
$code =~ s/\\/\\(rs/gms;
|
||||
if ($dewikify_manpage_code_indent) {
|
||||
$str .= "\n.IP\n"
|
||||
} else {
|
||||
@@ -580,7 +603,7 @@ sub dewikify {
|
||||
$retval .= dewikify_chunk($wikitype, $1, $2, $3);
|
||||
}
|
||||
} elsif ($wikitype eq 'md') {
|
||||
while ($str =~ s/\A(.*?)\n```(.*?)\n(.*?)\n```\n//ms) {
|
||||
while ($str =~ s/\A(.*?)\n?```(.*?)\n(.*?)\n```\n//ms) {
|
||||
$retval .= dewikify_chunk($wikitype, $1, $2, $3);
|
||||
}
|
||||
}
|
||||
@@ -2765,7 +2788,6 @@ __EOF__
|
||||
my $wikitype = $wikitypes{$sym};
|
||||
my $sectionsref = $wikisyms{$sym};
|
||||
my $remarks = $sectionsref->{'Remarks'};
|
||||
my $params = $sectionsref->{'Function Parameters'};
|
||||
my $returns = $sectionsref->{'Return Value'};
|
||||
my $version = $sectionsref->{'Version'};
|
||||
my $threadsafety = $sectionsref->{'Thread Safety'};
|
||||
@@ -2773,6 +2795,23 @@ __EOF__
|
||||
my $examples = $sectionsref->{'Code Examples'};
|
||||
my $deprecated = $sectionsref->{'Deprecated'};
|
||||
my $headerfile = $manpageheaderfiletext;
|
||||
|
||||
my $params = undef;
|
||||
|
||||
if ($symtype == -1) { # category documentation block.
|
||||
# nothing to be done here.
|
||||
} elsif (($symtype == 1) || (($symtype == 5))) { # we'll assume a typedef (5) with a \param is a function pointer typedef.
|
||||
$params = $sectionsref->{'Function Parameters'};
|
||||
} elsif ($symtype == 2) {
|
||||
$params = $sectionsref->{'Macro Parameters'};
|
||||
} elsif ($symtype == 3) {
|
||||
$params = $sectionsref->{'Fields'};
|
||||
} elsif ($symtype == 4) {
|
||||
$params = $sectionsref->{'Values'};
|
||||
} else {
|
||||
die("Unexpected symtype $symtype");
|
||||
}
|
||||
|
||||
$headerfile =~ s/\%fname\%/$headersymslocation{$sym}/g;
|
||||
$headerfile .= "\n";
|
||||
|
||||
@@ -2839,18 +2878,22 @@ __EOF__
|
||||
$str .= dewikify($wikitype, $deprecated) . "\n";
|
||||
}
|
||||
|
||||
my $incfile = $mainincludefname;
|
||||
if (defined $headerfile) {
|
||||
$str .= ".SH HEADER FILE\n";
|
||||
$str .= dewikify($wikitype, $headerfile) . "\n";
|
||||
if($headerfile =~ /Defined in (.*)/) {
|
||||
$incfile = $1;
|
||||
}
|
||||
}
|
||||
|
||||
$str .= ".SH SYNOPSIS\n";
|
||||
$str .= ".nf\n";
|
||||
$str .= ".B #include \\(dq$mainincludefname\\(dq\n";
|
||||
$str .= ".B #include <$incfile>\n";
|
||||
$str .= ".PP\n";
|
||||
|
||||
my @decllines = split /\n/, $decl;
|
||||
foreach (@decllines) {
|
||||
$_ =~ s/\\/\\(rs/g; # fix multiline macro defs
|
||||
$_ =~ s/"/\\(dq/g;
|
||||
$str .= ".BI \"$_\n";
|
||||
}
|
||||
$str .= ".fi\n";
|
||||
@@ -2938,8 +2981,11 @@ __EOF__
|
||||
}
|
||||
|
||||
if (defined $returns) {
|
||||
# Chop datatype in parentheses off the front.
|
||||
if(!($returns =~ s/\A\([^\[]*\[[^\]]*\]\([^\)]*\)[^\)]*\) //ms)) {
|
||||
$returns =~ s/\A\([^\)]*\) //ms;
|
||||
}
|
||||
$returns = dewikify($wikitype, $returns);
|
||||
$returns =~ s/\A\(.*?\)\s*//; # Chop datatype in parentheses off the front.
|
||||
$str .= ".SH RETURN VALUE\n";
|
||||
$str .= "$returns\n";
|
||||
}
|
||||
@@ -2975,6 +3021,8 @@ __EOF__
|
||||
s/\A\/*//;
|
||||
s/\A\.BR\s+//; # dewikify added this, but we want to handle it.
|
||||
s/\A\.I\s+//; # dewikify added this, but we want to handle it.
|
||||
s/\A\.PP\s*//; # dewikify added this, but we want to handle it.
|
||||
s/\\\(bu//; # dewikify added this, but we want to handle it.
|
||||
s/\A\s*[\:\*\-]\s*//;
|
||||
s/\A\s+//;
|
||||
s/\s+\Z//;
|
||||
|
||||
@@ -1,16 +1,21 @@
|
||||
# Helper for Find modules
|
||||
|
||||
function(get_flags_from_pkg_config _library _pc_prefix _out_prefix)
|
||||
if("${_library}" MATCHES "${CMAKE_STATIC_LIBRARY_SUFFIX}$")
|
||||
set(_cflags ${_pc_prefix}_STATIC_CFLAGS_OTHER)
|
||||
set(_link_libraries ${_pc_prefix}_STATIC_LIBRARIES)
|
||||
set(_link_options ${_pc_prefix}_STATIC_LDFLAGS_OTHER)
|
||||
set(_library_dirs ${_pc_prefix}_STATIC_LIBRARY_DIRS)
|
||||
if(MINGW)
|
||||
set(re_shared_suffix ".dll.a$")
|
||||
else()
|
||||
set(re_shared_suffix "${CMAKE_SHARED_LIBRARY_SUFFIX}$")
|
||||
endif()
|
||||
if("${_library}" MATCHES "${re_shared_suffix}")
|
||||
set(_cflags ${_pc_prefix}_CFLAGS_OTHER)
|
||||
set(_link_libraries ${_pc_prefix}_LIBRARIES)
|
||||
set(_link_options ${_pc_prefix}_LDFLAGS_OTHER)
|
||||
set(_library_dirs ${_pc_prefix}_LIBRARY_DIRS)
|
||||
else()
|
||||
set(_cflags ${_pc_prefix}_STATIC_CFLAGS_OTHER)
|
||||
set(_link_libraries ${_pc_prefix}_STATIC_LIBRARIES)
|
||||
set(_link_options ${_pc_prefix}_STATIC_LDFLAGS_OTHER)
|
||||
set(_library_dirs ${_pc_prefix}_STATIC_LIBRARY_DIRS)
|
||||
endif()
|
||||
|
||||
# The *_LIBRARIES lists always start with the library itself
|
||||
|
||||
@@ -1077,6 +1077,14 @@ endmacro()
|
||||
|
||||
# Check for HIDAPI support
|
||||
macro(CheckHIDAPI)
|
||||
if(ANDROID)
|
||||
enable_language(CXX)
|
||||
sdl_sources("${SDL3_SOURCE_DIR}/src/hidapi/android/hid.cpp")
|
||||
endif()
|
||||
if(IOS OR TVOS)
|
||||
sdl_sources("${SDL3_SOURCE_DIR}/src/hidapi/ios/hid.m")
|
||||
set(SDL_FRAMEWORK_COREBLUETOOTH 1)
|
||||
endif()
|
||||
if(SDL_HIDAPI)
|
||||
set(HAVE_HIDAPI ON)
|
||||
if(SDL_HIDAPI_LIBUSB)
|
||||
@@ -1109,14 +1117,6 @@ macro(CheckHIDAPI)
|
||||
endif()
|
||||
|
||||
if(HAVE_HIDAPI)
|
||||
if(ANDROID)
|
||||
enable_language(CXX)
|
||||
sdl_sources("${SDL3_SOURCE_DIR}/src/hidapi/android/hid.cpp")
|
||||
endif()
|
||||
if(IOS OR TVOS)
|
||||
sdl_sources("${SDL3_SOURCE_DIR}/src/hidapi/ios/hid.m")
|
||||
set(SDL_FRAMEWORK_COREBLUETOOTH 1)
|
||||
endif()
|
||||
set(HAVE_SDL_HIDAPI TRUE)
|
||||
|
||||
if(SDL_JOYSTICK AND SDL_HIDAPI_JOYSTICK)
|
||||
|
||||
@@ -160,3 +160,63 @@ function(SDL_AddCommonCompilerFlags TARGET)
|
||||
endif()
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
function(check_x86_source_compiles BODY VAR)
|
||||
if(ARGN)
|
||||
message(FATAL_ERROR "Unknown arguments: ${ARGN}")
|
||||
endif()
|
||||
if(APPLE_MULTIARCH AND (SDL_CPU_X86 OR SDL_CPU_X64))
|
||||
set(test_conditional 1)
|
||||
else()
|
||||
set(test_conditional 0)
|
||||
endif()
|
||||
check_c_source_compiles("
|
||||
#if ${test_conditional}
|
||||
# if defined(__i386__) || defined(__x86_64__)
|
||||
# define test_enabled 1
|
||||
# else
|
||||
# define test_enabled 0 /* feign success in Apple multi-arch configs */
|
||||
# endif
|
||||
#else /* test normally */
|
||||
# define test_enabled 1
|
||||
#endif
|
||||
#if test_enabled
|
||||
${BODY}
|
||||
#else
|
||||
int main(int argc, char *argv[]) {
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
return 0;
|
||||
}
|
||||
#endif" ${VAR})
|
||||
endfunction()
|
||||
|
||||
function(check_arm_source_compiles BODY VAR)
|
||||
if(ARGN)
|
||||
message(FATAL_ERROR "Unknown arguments: ${ARGN}")
|
||||
endif()
|
||||
if(APPLE_MULTIARCH AND (SDL_CPU_ARM32 OR SDL_CPU_ARM64))
|
||||
set(test_conditional 1)
|
||||
else()
|
||||
set(test_conditional 0)
|
||||
endif()
|
||||
check_c_source_compiles("
|
||||
#if ${test_conditional}
|
||||
# if defined(__arm__) || defined(__aarch64__)
|
||||
# define test_enabled 1
|
||||
# else
|
||||
# define test_enabled 0 /* feign success in Apple multi-arch configs */
|
||||
# endif
|
||||
#else /* test normally */
|
||||
# define test_enabled 1
|
||||
#endif
|
||||
#if test_enabled
|
||||
${BODY}
|
||||
#else
|
||||
int main(int argc, char *argv[]) {
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
return 0;
|
||||
}
|
||||
#endif" ${VAR})
|
||||
endfunction()
|
||||
+3
-3
@@ -4,15 +4,15 @@ function(SDL_DetectTargetCPUArchitectures DETECTED_ARCHS)
|
||||
|
||||
if(APPLE AND CMAKE_OSX_ARCHITECTURES)
|
||||
foreach(known_arch IN LISTS known_archs)
|
||||
set(SDL_CPU_${known_arch} "0")
|
||||
set(SDL_CPU_${known_arch} "0" PARENT_SCOPE)
|
||||
endforeach()
|
||||
set(detected_archs)
|
||||
foreach(osx_arch IN LISTS CMAKE_OSX_ARCHITECTURES)
|
||||
if(osx_arch STREQUAL "x86_64")
|
||||
set(SDL_CPU_X64 "1")
|
||||
set(SDL_CPU_X64 "1" PARENT_SCOPE)
|
||||
list(APPEND detected_archs "X64")
|
||||
elseif(osx_arch STREQUAL "arm64")
|
||||
set(SDL_CPU_ARM64 "1")
|
||||
set(SDL_CPU_ARM64 "1" PARENT_SCOPE)
|
||||
list(APPEND detected_archs "ARM64")
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
@@ -131,7 +131,7 @@ function(sdl_compile_options)
|
||||
target_compile_options(SDL3-static ${visibility} ${escaped_opts})
|
||||
endif()
|
||||
if(NOT ARGS_NO_EXPORT AND (ARGS_PUBLIC OR ARGS_INTERFACE))
|
||||
set_property(TARGET SDL3-collector APPEND PROPERTY INTERFACE_COMPILE_COMPILE_OPTIONS "${ARGS_UNPARSED_ARGUMENTS}")
|
||||
set_property(TARGET SDL3-collector APPEND PROPERTY INTERFACE_COMPILE_OPTIONS "${ARGS_UNPARSED_ARGUMENTS}")
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
|
||||
@@ -49,7 +49,7 @@ NSApplicationDelegate implementation:
|
||||
```objc
|
||||
- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender
|
||||
{
|
||||
if (SDL_GetEventState(SDL_EVENT_QUIT) == SDL_ENABLE) {
|
||||
if (SDL_EventEnabled(SDL_EVENT_QUIT)) {
|
||||
SDL_Event event;
|
||||
SDL_zero(event);
|
||||
event.type = SDL_EVENT_QUIT;
|
||||
@@ -61,7 +61,7 @@ NSApplicationDelegate implementation:
|
||||
|
||||
- (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename
|
||||
{
|
||||
if (SDL_GetEventState(SDL_EVENT_DROP_FILE) == SDL_ENABLE) {
|
||||
if (SDL_EventEnabled(SDL_EVENT_DROP_FILE)) {
|
||||
SDL_Event event;
|
||||
SDL_zero(event);
|
||||
event.type = SDL_EVENT_DROP_FILE;
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
- [macOS](README-macos.md)
|
||||
- [NetBSD](README-bsd.md)
|
||||
- [Nintendo Switch](README-switch.md)
|
||||
- [Nintendo 3DS](README-3ds.md)
|
||||
- [Nintendo 3DS](README-n3ds.md)
|
||||
- [OpenBSD](README-bsd.md)
|
||||
- [PlayStation 2](README-ps2.md)
|
||||
- [PlayStation 4](README-ps4.md)
|
||||
|
||||
+1
-1
@@ -20,7 +20,7 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* Main include header for the SDL library, version 3.2.12
|
||||
* Main include header for the SDL library, version 3.2.28
|
||||
*
|
||||
* It is almost always best to include just this one header instead of
|
||||
* picking out individual headers included here. There are exceptions to
|
||||
|
||||
@@ -126,7 +126,7 @@ extern "C" {
|
||||
*/
|
||||
#define SDL_TriggerBreakpoint() TriggerABreakpointInAPlatformSpecificManner
|
||||
|
||||
#elif defined(_MSC_VER) && _MSC_VER >= 1310
|
||||
#elif defined(__MINGW32__) || (defined(_MSC_VER) && _MSC_VER >= 1310)
|
||||
/* Don't include intrin.h here because it contains C++ code */
|
||||
extern void __cdecl __debugbreak(void);
|
||||
#define SDL_TriggerBreakpoint() __debugbreak()
|
||||
@@ -362,7 +362,7 @@ extern SDL_DECLSPEC SDL_AssertState SDLCALL SDL_ReportAssertion(SDL_AssertData *
|
||||
#define SDL_enabled_assert(condition) \
|
||||
do { \
|
||||
while ( !(condition) ) { \
|
||||
static struct SDL_AssertData sdl_assert_data = { 0, 0, #condition, 0, 0, 0, 0 }; \
|
||||
static struct SDL_AssertData sdl_assert_data = { false, 0, #condition, NULL, 0, NULL, NULL }; \
|
||||
const SDL_AssertState sdl_assert_state = SDL_ReportAssertion(&sdl_assert_data, SDL_FUNCTION, SDL_FILE, SDL_LINE); \
|
||||
if (sdl_assert_state == SDL_ASSERTION_RETRY) { \
|
||||
continue; /* go again. */ \
|
||||
|
||||
@@ -942,7 +942,10 @@ extern SDL_DECLSPEC void SDLCALL SDL_CloseAudioDevice(SDL_AudioDeviceID devid);
|
||||
* Binding a stream to a device will set its output format for playback
|
||||
* devices, and its input format for recording devices, so they match the
|
||||
* device's settings. The caller is welcome to change the other end of the
|
||||
* stream's format at any time with SDL_SetAudioStreamFormat().
|
||||
* stream's format at any time with SDL_SetAudioStreamFormat(). If the other
|
||||
* end of the stream's format has never been set (the audio stream was created
|
||||
* with a NULL audio spec), this function will set it to match the device
|
||||
* end's format.
|
||||
*
|
||||
* \param devid an audio device to bind a stream to.
|
||||
* \param streams an array of audio streams to bind.
|
||||
@@ -1021,7 +1024,7 @@ extern SDL_DECLSPEC void SDLCALL SDL_UnbindAudioStream(SDL_AudioStream *stream);
|
||||
/**
|
||||
* Query an audio stream for its currently-bound device.
|
||||
*
|
||||
* This reports the audio device that an audio stream is currently bound to.
|
||||
* This reports the logical audio device that an audio stream is currently bound to.
|
||||
*
|
||||
* If not bound, or invalid, this returns zero, which is not a valid device
|
||||
* ID.
|
||||
|
||||
@@ -119,7 +119,7 @@ typedef struct SDL_CameraSpec
|
||||
int width; /**< Frame width */
|
||||
int height; /**< Frame height */
|
||||
int framerate_numerator; /**< Frame rate numerator ((num / denom) == FPS, (denom / num) == duration in seconds) */
|
||||
int framerate_denominator; /**< Frame rate demoninator ((num / denom) == FPS, (denom / num) == duration in seconds) */
|
||||
int framerate_denominator; /**< Frame rate denominator ((num / denom) == FPS, (denom / num) == duration in seconds) */
|
||||
} SDL_CameraSpec;
|
||||
|
||||
/**
|
||||
|
||||
@@ -106,7 +106,7 @@ extern SDL_DECLSPEC bool SDLCALL SDL_SetClipboardText(const char *text);
|
||||
/**
|
||||
* Get UTF-8 text from the clipboard.
|
||||
*
|
||||
* This functions returns an empty string if there was not enough memory left
|
||||
* This function returns an empty string if there is not enough memory left
|
||||
* for a copy of the clipboard's content.
|
||||
*
|
||||
* \returns the clipboard text on success or an empty string on failure; call
|
||||
@@ -155,7 +155,7 @@ extern SDL_DECLSPEC bool SDLCALL SDL_SetPrimarySelectionText(const char *text);
|
||||
/**
|
||||
* Get UTF-8 text from the primary selection.
|
||||
*
|
||||
* This functions returns an empty string if there was not enough memory left
|
||||
* This function returns an empty string if there is not enough memory left
|
||||
* for a copy of the primary selection's content.
|
||||
*
|
||||
* \returns the primary selection text on success or an empty string on
|
||||
@@ -194,15 +194,14 @@ extern SDL_DECLSPEC bool SDLCALL SDL_HasPrimarySelectionText(void);
|
||||
* clipboard is cleared or new data is set. The clipboard is automatically
|
||||
* cleared in SDL_Quit().
|
||||
*
|
||||
* \param userdata a pointer to provided user data.
|
||||
* \param userdata a pointer to the provided user data.
|
||||
* \param mime_type the requested mime-type.
|
||||
* \param size a pointer filled in with the length of the returned data.
|
||||
* \returns a pointer to the data for the provided mime-type. Returning NULL
|
||||
* or setting length to 0 will cause no data to be sent to the
|
||||
* "receiver". It is up to the receiver to handle this. Essentially
|
||||
* returning no data is more or less undefined behavior and may cause
|
||||
* breakage in receiving applications. The returned data will not be
|
||||
* freed so it needs to be retained and dealt with internally.
|
||||
* or setting the length to 0 will cause zero length data to be sent
|
||||
* to the "receiver", which should be able to handle this. The
|
||||
* returned data will not be freed, so it needs to be retained and
|
||||
* dealt with internally.
|
||||
*
|
||||
* \since This function is available since SDL 3.2.0.
|
||||
*
|
||||
@@ -211,10 +210,10 @@ extern SDL_DECLSPEC bool SDLCALL SDL_HasPrimarySelectionText(void);
|
||||
typedef const void *(SDLCALL *SDL_ClipboardDataCallback)(void *userdata, const char *mime_type, size_t *size);
|
||||
|
||||
/**
|
||||
* Callback function that will be called when the clipboard is cleared, or new
|
||||
* Callback function that will be called when the clipboard is cleared, or when new
|
||||
* data is set.
|
||||
*
|
||||
* \param userdata a pointer to provided user data.
|
||||
* \param userdata a pointer to the provided user data.
|
||||
*
|
||||
* \since This function is available since SDL 3.2.0.
|
||||
*
|
||||
@@ -231,7 +230,7 @@ typedef void (SDLCALL *SDL_ClipboardCleanupCallback)(void *userdata);
|
||||
* respond with the data for the requested mime-type.
|
||||
*
|
||||
* The size of text data does not include any terminator, and the text does
|
||||
* not need to be null terminated (e.g. you can directly copy a portion of a
|
||||
* not need to be null-terminated (e.g., you can directly copy a portion of a
|
||||
* document).
|
||||
*
|
||||
* \param callback a function pointer to the function that provides the
|
||||
@@ -239,7 +238,7 @@ typedef void (SDLCALL *SDL_ClipboardCleanupCallback)(void *userdata);
|
||||
* \param cleanup a function pointer to the function that cleans up the
|
||||
* clipboard data.
|
||||
* \param userdata an opaque pointer that will be forwarded to the callbacks.
|
||||
* \param mime_types a list of mime-types that are being offered.
|
||||
* \param mime_types a list of mime-types that are being offered. SDL copies the given list.
|
||||
* \param num_mime_types the number of mime-types in the mime_types list.
|
||||
* \returns true on success or false on failure; call SDL_GetError() for more
|
||||
* information.
|
||||
@@ -269,10 +268,10 @@ extern SDL_DECLSPEC bool SDLCALL SDL_SetClipboardData(SDL_ClipboardDataCallback
|
||||
extern SDL_DECLSPEC bool SDLCALL SDL_ClearClipboardData(void);
|
||||
|
||||
/**
|
||||
* Get the data from clipboard for a given mime type.
|
||||
* Get the data from the clipboard for a given mime type.
|
||||
*
|
||||
* The size of text data does not include the terminator, but the text is
|
||||
* guaranteed to be null terminated.
|
||||
* guaranteed to be null-terminated.
|
||||
*
|
||||
* \param mime_type the mime type to read from the clipboard.
|
||||
* \param size a pointer filled in with the length of the returned data.
|
||||
@@ -292,8 +291,8 @@ extern SDL_DECLSPEC void * SDLCALL SDL_GetClipboardData(const char *mime_type, s
|
||||
/**
|
||||
* Query whether there is data in the clipboard for the provided mime type.
|
||||
*
|
||||
* \param mime_type the mime type to check for data for.
|
||||
* \returns true if there exists data in clipboard for the provided mime type,
|
||||
* \param mime_type the mime type to check for data.
|
||||
* \returns true if data exists in the clipboard for the provided mime type,
|
||||
* false if it does not.
|
||||
*
|
||||
* \threadsafety This function should only be called on the main thread.
|
||||
@@ -310,7 +309,7 @@ extern SDL_DECLSPEC bool SDLCALL SDL_HasClipboardData(const char *mime_type);
|
||||
*
|
||||
* \param num_mime_types a pointer filled with the number of mime types, may
|
||||
* be NULL.
|
||||
* \returns a null terminated array of strings with mime types, or NULL on
|
||||
* \returns a null-terminated array of strings with mime types, or NULL on
|
||||
* failure; call SDL_GetError() for more information. This should be
|
||||
* freed with SDL_free() when it is no longer needed.
|
||||
*
|
||||
|
||||
@@ -46,7 +46,7 @@
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1400)
|
||||
/* As of Clang 11, '_m_prefetchw' is conflicting with the winnt.h's version,
|
||||
so we define the needed '_m_prefetch' here as a pseudo-header, until the issue is fixed. */
|
||||
#ifdef __clang__
|
||||
#if defined(__clang__) && !SDL_HAS_BUILTIN(_m_prefetch)
|
||||
#ifndef __PRFCHWINTRIN_H
|
||||
#define __PRFCHWINTRIN_H
|
||||
static __inline__ void __attribute__((__always_inline__, __nodebug__))
|
||||
@@ -128,7 +128,7 @@ _m_prefetch(void *__P)
|
||||
* \sa SDL_BIG_ENDIAN
|
||||
*/
|
||||
#define SDL_BYTEORDER SDL_LIL_ENDIAN___or_maybe___SDL_BIG_ENDIAN
|
||||
#elif defined(SDL_PLATFORM_LINUX)
|
||||
#elif defined(SDL_PLATFORM_LINUX) || defined(__GLIBC__)
|
||||
#include <endian.h>
|
||||
#define SDL_BYTEORDER __BYTE_ORDER
|
||||
#elif defined(SDL_PLATFORM_SOLARIS)
|
||||
@@ -486,7 +486,7 @@ SDL_FORCE_INLINE Uint32 SDL_Swap32(Uint32 x) { return x_but_byteswapped; }
|
||||
*
|
||||
* \since This function is available since SDL 3.2.0.
|
||||
*/
|
||||
SDL_FORCE_INLINE Uint32 SDL_Swap64(Uint64 x) { return x_but_byteswapped; }
|
||||
SDL_FORCE_INLINE Uint64 SDL_Swap64(Uint64 x) { return x_but_byteswapped; }
|
||||
|
||||
/**
|
||||
* Swap a 16-bit value from littleendian to native byte order.
|
||||
|
||||
@@ -1043,7 +1043,7 @@ typedef union SDL_Event
|
||||
} SDL_Event;
|
||||
|
||||
/* Make sure we haven't broken binary compatibility */
|
||||
SDL_COMPILE_TIME_ASSERT(SDL_Event, sizeof(SDL_Event) == sizeof(((SDL_Event *)NULL)->padding));
|
||||
SDL_COMPILE_TIME_ASSERT(SDL_Event, sizeof(SDL_Event) == sizeof((SDL_static_cast(SDL_Event *, NULL))->padding));
|
||||
|
||||
|
||||
/* Function prototypes */
|
||||
|
||||
@@ -224,8 +224,8 @@
|
||||
* - `drawIndirectFirstInstance`
|
||||
*
|
||||
* **D3D12:** Supported on Windows 10 or newer, Xbox One (GDK), and Xbox
|
||||
* Series X|S (GDK). Requires a GPU that supports DirectX 12 Feature Level
|
||||
* 11_1.
|
||||
* Series X|S (GDK). Requires a GPU that supports DirectX 12 Feature Level 11_0 and
|
||||
* Resource Binding Tier 2 or above.
|
||||
*
|
||||
* **Metal:** Supported on macOS 10.14+ and iOS/tvOS 13.0+. Hardware
|
||||
* requirements vary by operating system:
|
||||
@@ -1091,7 +1091,7 @@ typedef enum SDL_GPUCompareOp
|
||||
SDL_GPU_COMPAREOP_LESS_OR_EQUAL, /**< The comparison evaluates reference <= test. */
|
||||
SDL_GPU_COMPAREOP_GREATER, /**< The comparison evaluates reference > test. */
|
||||
SDL_GPU_COMPAREOP_NOT_EQUAL, /**< The comparison evaluates reference != test. */
|
||||
SDL_GPU_COMPAREOP_GREATER_OR_EQUAL, /**< The comparison evalutes reference >= test. */
|
||||
SDL_GPU_COMPAREOP_GREATER_OR_EQUAL, /**< The comparison evaluates reference >= test. */
|
||||
SDL_GPU_COMPAREOP_ALWAYS /**< The comparison always evaluates true. */
|
||||
} SDL_GPUCompareOp;
|
||||
|
||||
@@ -1549,7 +1549,7 @@ typedef struct SDL_GPUSamplerCreateInfo
|
||||
typedef struct SDL_GPUVertexBufferDescription
|
||||
{
|
||||
Uint32 slot; /**< The binding slot of the vertex buffer. */
|
||||
Uint32 pitch; /**< The byte pitch between consecutive elements of the vertex buffer. */
|
||||
Uint32 pitch; /**< The size of a single element + the offset between elements. */
|
||||
SDL_GPUVertexInputRate input_rate; /**< Whether attribute addressing is a function of the vertex index or instance index. */
|
||||
Uint32 instance_step_rate; /**< Reserved for future use. Must be set to 0. */
|
||||
} SDL_GPUVertexBufferDescription;
|
||||
@@ -2648,7 +2648,7 @@ extern SDL_DECLSPEC void SDLCALL SDL_InsertGPUDebugLabel(
|
||||
const char *text);
|
||||
|
||||
/**
|
||||
* Begins a debug group with an arbitary name.
|
||||
* Begins a debug group with an arbitrary name.
|
||||
*
|
||||
* Used for denoting groups of calls when viewing the command buffer
|
||||
* callstream in a graphics debugging tool.
|
||||
|
||||
@@ -595,7 +595,7 @@ extern "C" {
|
||||
* A variable that limits what CPU features are available.
|
||||
*
|
||||
* By default, SDL marks all features the current CPU supports as available.
|
||||
* This hint allows to limit these to a subset.
|
||||
* This hint allows the enabled features to be limited to a subset.
|
||||
*
|
||||
* When the hint is unset, or empty, SDL will enable all detected CPU
|
||||
* features.
|
||||
@@ -2026,8 +2026,8 @@ extern "C" {
|
||||
*
|
||||
* The variable can be set to the following values:
|
||||
*
|
||||
* - "0": RAWINPUT drivers are not used.
|
||||
* - "1": RAWINPUT drivers are used. (default)
|
||||
* - "0": RAWINPUT drivers are not used. (default)
|
||||
* - "1": RAWINPUT drivers are used.
|
||||
*
|
||||
* This hint should be set before SDL is initialized.
|
||||
*
|
||||
@@ -2126,8 +2126,8 @@ extern "C" {
|
||||
*
|
||||
* The variable can be set to the following values:
|
||||
*
|
||||
* - "0": WGI is not used.
|
||||
* - "1": WGI is used. (default)
|
||||
* - "0": WGI is not used. (default)
|
||||
* - "1": WGI is used.
|
||||
*
|
||||
* This hint should be set before SDL is initialized.
|
||||
*
|
||||
|
||||
@@ -79,7 +79,7 @@ typedef Uint32 SDL_InitFlags;
|
||||
|
||||
#define SDL_INIT_AUDIO 0x00000010u /**< `SDL_INIT_AUDIO` implies `SDL_INIT_EVENTS` */
|
||||
#define SDL_INIT_VIDEO 0x00000020u /**< `SDL_INIT_VIDEO` implies `SDL_INIT_EVENTS`, should be initialized on the main thread */
|
||||
#define SDL_INIT_JOYSTICK 0x00000200u /**< `SDL_INIT_JOYSTICK` implies `SDL_INIT_EVENTS`, should be initialized on the same thread as SDL_INIT_VIDEO on Windows if you don't set SDL_HINT_JOYSTICK_THREAD */
|
||||
#define SDL_INIT_JOYSTICK 0x00000200u /**< `SDL_INIT_JOYSTICK` implies `SDL_INIT_EVENTS` */
|
||||
#define SDL_INIT_HAPTIC 0x00001000u
|
||||
#define SDL_INIT_GAMEPAD 0x00002000u /**< `SDL_INIT_GAMEPAD` implies `SDL_INIT_JOYSTICK` */
|
||||
#define SDL_INIT_EVENTS 0x00004000u
|
||||
|
||||
@@ -280,12 +280,14 @@ _m_prefetch(void *__P)
|
||||
* \sa SDL_TARGETING
|
||||
*/
|
||||
#define SDL_HAS_TARGET_ATTRIBS
|
||||
|
||||
#elif defined(__loongarch64) && defined(__GNUC__) && (__GNUC__ >= 15)
|
||||
/* LoongArch requires GCC 15+ for target attribute support */
|
||||
# define SDL_HAS_TARGET_ATTRIBS
|
||||
#elif defined(__clang__) && defined(__has_attribute)
|
||||
# if __has_attribute(target)
|
||||
# define SDL_HAS_TARGET_ATTRIBS
|
||||
# endif
|
||||
#elif defined(__GNUC__) && (__GNUC__ + (__GNUC_MINOR__ >= 9) > 4) /* gcc >= 4.9 */
|
||||
#elif defined(__GNUC__) && !defined(__loongarch64) && (__GNUC__ + (__GNUC_MINOR__ >= 9) > 4) /* gcc >= 4.9 */
|
||||
# define SDL_HAS_TARGET_ATTRIBS
|
||||
#elif defined(__ICC) && __ICC >= 1600
|
||||
# define SDL_HAS_TARGET_ATTRIBS
|
||||
|
||||
@@ -360,7 +360,7 @@ extern SDL_DECLSPEC void SDLCALL SDL_LockMutex(SDL_Mutex *mutex) SDL_ACQUIRE(mut
|
||||
* \sa SDL_LockMutex
|
||||
* \sa SDL_UnlockMutex
|
||||
*/
|
||||
extern SDL_DECLSPEC bool SDLCALL SDL_TryLockMutex(SDL_Mutex *mutex) SDL_TRY_ACQUIRE(0, mutex);
|
||||
extern SDL_DECLSPEC bool SDLCALL SDL_TryLockMutex(SDL_Mutex *mutex) SDL_TRY_ACQUIRE(true, mutex);
|
||||
|
||||
/**
|
||||
* Unlock the mutex.
|
||||
@@ -559,7 +559,7 @@ extern SDL_DECLSPEC void SDLCALL SDL_LockRWLockForWriting(SDL_RWLock *rwlock) SD
|
||||
* \sa SDL_TryLockRWLockForWriting
|
||||
* \sa SDL_UnlockRWLock
|
||||
*/
|
||||
extern SDL_DECLSPEC bool SDLCALL SDL_TryLockRWLockForReading(SDL_RWLock *rwlock) SDL_TRY_ACQUIRE_SHARED(0, rwlock);
|
||||
extern SDL_DECLSPEC bool SDLCALL SDL_TryLockRWLockForReading(SDL_RWLock *rwlock) SDL_TRY_ACQUIRE_SHARED(true, rwlock);
|
||||
|
||||
/**
|
||||
* Try to lock a read/write lock _for writing_ without blocking.
|
||||
@@ -589,7 +589,7 @@ extern SDL_DECLSPEC bool SDLCALL SDL_TryLockRWLockForReading(SDL_RWLock *rwlock)
|
||||
* \sa SDL_TryLockRWLockForReading
|
||||
* \sa SDL_UnlockRWLock
|
||||
*/
|
||||
extern SDL_DECLSPEC bool SDLCALL SDL_TryLockRWLockForWriting(SDL_RWLock *rwlock) SDL_TRY_ACQUIRE(0, rwlock);
|
||||
extern SDL_DECLSPEC bool SDLCALL SDL_TryLockRWLockForWriting(SDL_RWLock *rwlock) SDL_TRY_ACQUIRE(true, rwlock);
|
||||
|
||||
/**
|
||||
* Unlock the read/write lock.
|
||||
|
||||
@@ -517,7 +517,7 @@ typedef enum SDL_PackedLayout
|
||||
* ABGR32, define a platform-independent encoding into bytes in the order
|
||||
* specified. For example, in RGB24 data, each pixel is encoded in 3 bytes
|
||||
* (red, green, blue) in that order, and in ABGR32 data, each pixel is
|
||||
* encoded in 4 bytes alpha, blue, green, red) in that order. Use these
|
||||
* encoded in 4 bytes (alpha, blue, green, red) in that order. Use these
|
||||
* names if the property of a format that is important to you is the order
|
||||
* of the bytes in memory or on disk.
|
||||
* - Names with a bit count per component, such as ARGB8888 and XRGB1555, are
|
||||
|
||||
@@ -125,10 +125,10 @@ typedef struct SDL_FRect
|
||||
*/
|
||||
SDL_FORCE_INLINE void SDL_RectToFRect(const SDL_Rect *rect, SDL_FRect *frect)
|
||||
{
|
||||
frect->x = (float)rect->x;
|
||||
frect->y = (float)rect->y;
|
||||
frect->w = (float)rect->w;
|
||||
frect->h = (float)rect->h;
|
||||
frect->x = SDL_static_cast(float, rect->x);
|
||||
frect->y = SDL_static_cast(float, rect->y);
|
||||
frect->w = SDL_static_cast(float, rect->w);
|
||||
frect->h = SDL_static_cast(float, rect->h);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -2612,7 +2612,7 @@ extern SDL_DECLSPEC bool SDLCALL SDL_RenderDebugText(SDL_Renderer *renderer, flo
|
||||
* Draw debug text to an SDL_Renderer.
|
||||
*
|
||||
* This function will render a printf()-style format string to a renderer.
|
||||
* Note that this is a convinence function for debugging, with severe
|
||||
* Note that this is a convenience function for debugging, with severe
|
||||
* limitations, and is not intended to be used for production apps and games.
|
||||
*
|
||||
* For the full list of limitations and other useful information, see
|
||||
|
||||
@@ -208,7 +208,7 @@ typedef enum SDL_Scancode
|
||||
|
||||
SDL_SCANCODE_NONUSBACKSLASH = 100, /**< This is the additional key that ISO
|
||||
* keyboards have over ANSI ones,
|
||||
* located between left shift and Y.
|
||||
* located between left shift and Z.
|
||||
* Produces GRAVE ACCENT and TILDE in a
|
||||
* US or UK Mac layout, REVERSE SOLIDUS
|
||||
* (backslash) and VERTICAL LINE in a
|
||||
|
||||
@@ -138,7 +138,8 @@ typedef enum SDL_SensorType
|
||||
SDL_SENSOR_ACCEL_L, /**< Accelerometer for left Joy-Con controller and Wii nunchuk */
|
||||
SDL_SENSOR_GYRO_L, /**< Gyroscope for left Joy-Con controller */
|
||||
SDL_SENSOR_ACCEL_R, /**< Accelerometer for right Joy-Con controller */
|
||||
SDL_SENSOR_GYRO_R /**< Gyroscope for right Joy-Con controller */
|
||||
SDL_SENSOR_GYRO_R, /**< Gyroscope for right Joy-Con controller */
|
||||
SDL_SENSOR_COUNT
|
||||
} SDL_SensorType;
|
||||
|
||||
|
||||
|
||||
+15
-15
@@ -1164,7 +1164,7 @@ typedef struct SDL_alignment_test
|
||||
void *b;
|
||||
} SDL_alignment_test;
|
||||
SDL_COMPILE_TIME_ASSERT(struct_alignment, sizeof(SDL_alignment_test) == (2 * sizeof(void *)));
|
||||
SDL_COMPILE_TIME_ASSERT(two_s_complement, (int)~(int)0 == (int)(-1));
|
||||
SDL_COMPILE_TIME_ASSERT(two_s_complement, SDL_static_cast(int, ~SDL_static_cast(int, 0)) == SDL_static_cast(int, -1));
|
||||
#endif /* DOXYGEN_SHOULD_IGNORE_THIS */
|
||||
/** \endcond */
|
||||
|
||||
@@ -3426,7 +3426,7 @@ extern SDL_DECLSPEC size_t SDLCALL SDL_utf8strnlen(const char *str, size_t bytes
|
||||
* Convert an integer into a string.
|
||||
*
|
||||
* This requires a radix to specified for string format. Specifying 10
|
||||
* produces a decimal number, 16 hexidecimal, etc. Must be in the range of 2
|
||||
* produces a decimal number, 16 hexadecimal, etc. Must be in the range of 2
|
||||
* to 36.
|
||||
*
|
||||
* Note that this function will overflow a buffer if `str` is not large enough
|
||||
@@ -3454,7 +3454,7 @@ extern SDL_DECLSPEC char * SDLCALL SDL_itoa(int value, char *str, int radix);
|
||||
* Convert an unsigned integer into a string.
|
||||
*
|
||||
* This requires a radix to specified for string format. Specifying 10
|
||||
* produces a decimal number, 16 hexidecimal, etc. Must be in the range of 2
|
||||
* produces a decimal number, 16 hexadecimal, etc. Must be in the range of 2
|
||||
* to 36.
|
||||
*
|
||||
* Note that this function will overflow a buffer if `str` is not large enough
|
||||
@@ -3482,7 +3482,7 @@ extern SDL_DECLSPEC char * SDLCALL SDL_uitoa(unsigned int value, char *str, int
|
||||
* Convert a long integer into a string.
|
||||
*
|
||||
* This requires a radix to specified for string format. Specifying 10
|
||||
* produces a decimal number, 16 hexidecimal, etc. Must be in the range of 2
|
||||
* produces a decimal number, 16 hexadecimal, etc. Must be in the range of 2
|
||||
* to 36.
|
||||
*
|
||||
* Note that this function will overflow a buffer if `str` is not large enough
|
||||
@@ -3510,7 +3510,7 @@ extern SDL_DECLSPEC char * SDLCALL SDL_ltoa(long value, char *str, int radix);
|
||||
* Convert an unsigned long integer into a string.
|
||||
*
|
||||
* This requires a radix to specified for string format. Specifying 10
|
||||
* produces a decimal number, 16 hexidecimal, etc. Must be in the range of 2
|
||||
* produces a decimal number, 16 hexadecimal, etc. Must be in the range of 2
|
||||
* to 36.
|
||||
*
|
||||
* Note that this function will overflow a buffer if `str` is not large enough
|
||||
@@ -3540,7 +3540,7 @@ extern SDL_DECLSPEC char * SDLCALL SDL_ultoa(unsigned long value, char *str, int
|
||||
* Convert a long long integer into a string.
|
||||
*
|
||||
* This requires a radix to specified for string format. Specifying 10
|
||||
* produces a decimal number, 16 hexidecimal, etc. Must be in the range of 2
|
||||
* produces a decimal number, 16 hexadecimal, etc. Must be in the range of 2
|
||||
* to 36.
|
||||
*
|
||||
* Note that this function will overflow a buffer if `str` is not large enough
|
||||
@@ -3568,7 +3568,7 @@ extern SDL_DECLSPEC char * SDLCALL SDL_lltoa(long long value, char *str, int rad
|
||||
* Convert an unsigned long long integer into a string.
|
||||
*
|
||||
* This requires a radix to specified for string format. Specifying 10
|
||||
* produces a decimal number, 16 hexidecimal, etc. Must be in the range of 2
|
||||
* produces a decimal number, 16 hexadecimal, etc. Must be in the range of 2
|
||||
* to 36.
|
||||
*
|
||||
* Note that this function will overflow a buffer if `str` is not large enough
|
||||
@@ -3923,7 +3923,7 @@ extern SDL_DECLSPEC int SDLCALL SDL_strcasecmp(const char *str1, const char *str
|
||||
extern SDL_DECLSPEC int SDLCALL SDL_strncasecmp(const char *str1, const char *str2, size_t maxlen);
|
||||
|
||||
/**
|
||||
* Searches a string for the first occurence of any character contained in a
|
||||
* Searches a string for the first occurrence of any character contained in a
|
||||
* breakset, and returns a pointer from the string to that character.
|
||||
*
|
||||
* \param str The null-terminated string to be searched. Must not be NULL, and
|
||||
@@ -3931,7 +3931,7 @@ extern SDL_DECLSPEC int SDLCALL SDL_strncasecmp(const char *str1, const char *st
|
||||
* \param breakset A null-terminated string containing the list of characters
|
||||
* to look for. Must not be NULL, and must not overlap with
|
||||
* `str`.
|
||||
* \returns A pointer to the location, in str, of the first occurence of a
|
||||
* \returns A pointer to the location, in str, of the first occurrence of a
|
||||
* character present in the breakset, or NULL if none is found.
|
||||
*
|
||||
* \threadsafety It is safe to call this function from any thread.
|
||||
@@ -4656,7 +4656,7 @@ extern SDL_DECLSPEC float SDLCALL SDL_atanf(float x);
|
||||
*
|
||||
* Domain: `-INF <= x <= INF`, `-INF <= y <= INF`
|
||||
*
|
||||
* Range: `-Pi/2 <= y <= Pi/2`
|
||||
* Range: `-Pi <= y <= Pi`
|
||||
*
|
||||
* This function operates on double-precision floating point values, use
|
||||
* SDL_atan2f for single-precision floats.
|
||||
@@ -4692,7 +4692,7 @@ extern SDL_DECLSPEC double SDLCALL SDL_atan2(double y, double x);
|
||||
*
|
||||
* Domain: `-INF <= x <= INF`, `-INF <= y <= INF`
|
||||
*
|
||||
* Range: `-Pi/2 <= y <= Pi/2`
|
||||
* Range: `-Pi <= y <= Pi`
|
||||
*
|
||||
* This function operates on single-precision floating point values, use
|
||||
* SDL_atan2 for double-precision floats.
|
||||
@@ -5821,7 +5821,7 @@ extern SDL_DECLSPEC int SDLCALL SDL_iconv_close(SDL_iconv_t cd);
|
||||
* This function converts text between encodings, reading from and writing to
|
||||
* a buffer.
|
||||
*
|
||||
* It returns the number of succesful conversions on success. On error,
|
||||
* It returns the number of successful conversions on success. On error,
|
||||
* SDL_ICONV_E2BIG is returned when the output buffer is too small, or
|
||||
* SDL_ICONV_EILSEQ is returned when an invalid input sequence is encountered,
|
||||
* or SDL_ICONV_EINVAL is returned when an incomplete input sequence is
|
||||
@@ -5921,7 +5921,7 @@ extern SDL_DECLSPEC char * SDLCALL SDL_iconv_string(const char *tocode,
|
||||
*
|
||||
* \since This macro is available since SDL 3.2.0.
|
||||
*/
|
||||
#define SDL_iconv_utf8_ucs2(S) (Uint16 *)SDL_iconv_string("UCS-2", "UTF-8", S, SDL_strlen(S)+1)
|
||||
#define SDL_iconv_utf8_ucs2(S) SDL_reinterpret_cast(Uint16 *, SDL_iconv_string("UCS-2", "UTF-8", S, SDL_strlen(S)+1))
|
||||
|
||||
/**
|
||||
* Convert a UTF-8 string to UCS-4.
|
||||
@@ -5935,7 +5935,7 @@ extern SDL_DECLSPEC char * SDLCALL SDL_iconv_string(const char *tocode,
|
||||
*
|
||||
* \since This macro is available since SDL 3.2.0.
|
||||
*/
|
||||
#define SDL_iconv_utf8_ucs4(S) (Uint32 *)SDL_iconv_string("UCS-4", "UTF-8", S, SDL_strlen(S)+1)
|
||||
#define SDL_iconv_utf8_ucs4(S) SDL_reinterpret_cast(Uint32 *, SDL_iconv_string("UCS-4", "UTF-8", S, SDL_strlen(S)+1))
|
||||
|
||||
/**
|
||||
* Convert a wchar_t string to UTF-8.
|
||||
@@ -5949,7 +5949,7 @@ extern SDL_DECLSPEC char * SDLCALL SDL_iconv_string(const char *tocode,
|
||||
*
|
||||
* \since This macro is available since SDL 3.2.0.
|
||||
*/
|
||||
#define SDL_iconv_wchar_utf8(S) SDL_iconv_string("UTF-8", "WCHAR_T", (char *)S, (SDL_wcslen(S)+1)*sizeof(wchar_t))
|
||||
#define SDL_iconv_wchar_utf8(S) SDL_iconv_string("UTF-8", "WCHAR_T", SDL_reinterpret_cast(const char *, S), (SDL_wcslen(S)+1)*sizeof(wchar_t))
|
||||
|
||||
|
||||
/* force builds using Clang's static analysis tools to use literal C runtime
|
||||
|
||||
@@ -1279,10 +1279,11 @@ extern SDL_DECLSPEC bool SDLCALL SDL_BlitSurfaceUncheckedScaled(SDL_Surface *src
|
||||
*
|
||||
* \param src the SDL_Surface structure to be copied from.
|
||||
* \param srcrect the SDL_Rect structure representing the rectangle to be
|
||||
* copied, may not be NULL.
|
||||
* copied, or NULL to copy the entire surface.
|
||||
* \param dst the SDL_Surface structure that is the blit target.
|
||||
* \param dstrect the SDL_Rect structure representing the target rectangle in
|
||||
* the destination surface, may not be NULL.
|
||||
* the destination surface, or NULL to fill the entire
|
||||
* destination surface.
|
||||
* \param scaleMode the SDL_ScaleMode to be used.
|
||||
* \returns true on success or false on failure; call SDL_GetError() for more
|
||||
* information.
|
||||
|
||||
@@ -62,7 +62,7 @@ extern "C" {
|
||||
*
|
||||
* \since This macro is available since SDL 3.2.0.
|
||||
*/
|
||||
#define SDL_MICRO_VERSION 12
|
||||
#define SDL_MICRO_VERSION 28
|
||||
|
||||
/**
|
||||
* This macro turns the version numbers into a numeric value.
|
||||
|
||||
@@ -1167,6 +1167,15 @@ extern SDL_DECLSPEC SDL_Window * SDLCALL SDL_CreateWindow(const char *title, int
|
||||
* Popup windows implicitly do not have a border/decorations and do not appear
|
||||
* on the taskbar/dock or in lists of windows such as alt-tab menus.
|
||||
*
|
||||
* By default, popup window positions will automatically be constrained to keep
|
||||
* the entire window within display bounds. This can be overridden with the
|
||||
* `SDL_PROP_WINDOW_CREATE_CONSTRAIN_POPUP_BOOLEAN` property.
|
||||
*
|
||||
* By default, popup menus will automatically grab keyboard focus from the parent
|
||||
* when shown. This behavior can be overridden by setting the `SDL_WINDOW_NOT_FOCUSABLE`
|
||||
* flag, setting the `SDL_PROP_WINDOW_CREATE_FOCUSABLE_BOOLEAN` property to false, or
|
||||
* toggling it after creation via the `SDL_SetWindowFocusable()` function.
|
||||
*
|
||||
* If a parent window is hidden or destroyed, any child popup windows will be
|
||||
* recursively hidden or destroyed as well. Child popup windows not explicitly
|
||||
* hidden will be restored when the parent is shown.
|
||||
@@ -1207,6 +1216,9 @@ extern SDL_DECLSPEC SDL_Window * SDLCALL SDL_CreatePopupWindow(SDL_Window *paren
|
||||
* be always on top
|
||||
* - `SDL_PROP_WINDOW_CREATE_BORDERLESS_BOOLEAN`: true if the window has no
|
||||
* window decoration
|
||||
* - `SDL_PROP_WINDOW_CREATE_CONSTRAIN_POPUP_BOOLEAN`: true if the "tooltip" and
|
||||
* "menu" window types should be automatically constrained to be entirely within
|
||||
* display bounds (default), false if no constraints on the position are desired.
|
||||
* - `SDL_PROP_WINDOW_CREATE_EXTERNAL_GRAPHICS_CONTEXT_BOOLEAN`: true if the
|
||||
* window will be used with an externally managed graphics context.
|
||||
* - `SDL_PROP_WINDOW_CREATE_FOCUSABLE_BOOLEAN`: true if the window should
|
||||
@@ -1321,6 +1333,7 @@ extern SDL_DECLSPEC SDL_Window * SDLCALL SDL_CreateWindowWithProperties(SDL_Prop
|
||||
|
||||
#define SDL_PROP_WINDOW_CREATE_ALWAYS_ON_TOP_BOOLEAN "SDL.window.create.always_on_top"
|
||||
#define SDL_PROP_WINDOW_CREATE_BORDERLESS_BOOLEAN "SDL.window.create.borderless"
|
||||
#define SDL_PROP_WINDOW_CREATE_CONSTRAIN_POPUP_BOOLEAN "SDL.window.create.constrain_popup"
|
||||
#define SDL_PROP_WINDOW_CREATE_FOCUSABLE_BOOLEAN "SDL.window.create.focusable"
|
||||
#define SDL_PROP_WINDOW_CREATE_EXTERNAL_GRAPHICS_CONTEXT_BOOLEAN "SDL.window.create.external_graphics_context"
|
||||
#define SDL_PROP_WINDOW_CREATE_FLAGS_NUMBER "SDL.window.create.flags"
|
||||
@@ -1460,7 +1473,7 @@ extern SDL_DECLSPEC SDL_Window * SDLCALL SDL_GetWindowParent(SDL_Window *window)
|
||||
* - `SDL_PROP_WINDOW_COCOA_WINDOW_POINTER`: the `(__unsafe_unretained)`
|
||||
* NSWindow associated with the window
|
||||
* - `SDL_PROP_WINDOW_COCOA_METAL_VIEW_TAG_NUMBER`: the NSInteger tag
|
||||
* assocated with metal views on the window
|
||||
* associated with metal views on the window
|
||||
*
|
||||
* On OpenVR:
|
||||
*
|
||||
|
||||
@@ -51,14 +51,14 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Avoid including vulkan.h, don't define VkInstance if it's already included */
|
||||
#ifdef VULKAN_H_
|
||||
/* Avoid including vulkan_core.h, don't define VkInstance if it's already included */
|
||||
#ifdef VULKAN_CORE_H_
|
||||
#define NO_SDL_VULKAN_TYPEDEFS
|
||||
#endif
|
||||
#ifndef NO_SDL_VULKAN_TYPEDEFS
|
||||
#define VK_DEFINE_HANDLE(object) typedef struct object##_T* object;
|
||||
|
||||
#if defined(__LP64__) || defined(_WIN64) || defined(__x86_64__) || defined(_M_X64) || defined(__ia64) || defined (_M_IA64) || defined(__aarch64__) || defined(__powerpc64__)
|
||||
#if defined(__LP64__) || defined(_WIN64) || (defined(__x86_64__) && !defined(__ILP32__)) || defined(_M_X64) || defined(__ia64) || defined (_M_IA64) || defined(__aarch64__) || defined(__powerpc64__) || (defined(__riscv) && __riscv_xlen == 64)
|
||||
#define VK_DEFINE_NON_DISPATCHABLE_HANDLE(object) typedef struct object##_T *object;
|
||||
#else
|
||||
#define VK_DEFINE_NON_DISPATCHABLE_HANDLE(object) typedef uint64_t object;
|
||||
|
||||
@@ -174,6 +174,7 @@
|
||||
#cmakedefine HAVE_MEMFD_CREATE 1
|
||||
#cmakedefine HAVE_POSIX_FALLOCATE 1
|
||||
#cmakedefine HAVE_SIGACTION 1
|
||||
#cmakedefine HAVE_SIGTIMEDWAIT 1
|
||||
#cmakedefine HAVE_SA_SIGACTION 1
|
||||
#cmakedefine HAVE_ST_MTIM 1
|
||||
#cmakedefine HAVE_SETJMP 1
|
||||
|
||||
@@ -111,6 +111,9 @@ typedef unsigned int uintptr_t;
|
||||
# define SDL_DISABLE_AVX 1
|
||||
#endif
|
||||
|
||||
#define HAVE_STDARG_H 1
|
||||
#define HAVE_STDDEF_H 1
|
||||
|
||||
/* This can be disabled to avoid C runtime dependencies and manifest requirements */
|
||||
#ifndef HAVE_LIBC
|
||||
#define HAVE_LIBC 1
|
||||
@@ -122,8 +125,6 @@ typedef unsigned int uintptr_t;
|
||||
#define HAVE_LIMITS_H 1
|
||||
#define HAVE_MATH_H 1
|
||||
#define HAVE_SIGNAL_H 1
|
||||
#define HAVE_STDARG_H 1
|
||||
#define HAVE_STDDEF_H 1
|
||||
#define HAVE_STDIO_H 1
|
||||
#define HAVE_STDLIB_H 1
|
||||
#define HAVE_STRING_H 1
|
||||
@@ -153,7 +154,6 @@ typedef unsigned int uintptr_t;
|
||||
#define HAVE_STRCMP 1
|
||||
#define HAVE_STRNCMP 1
|
||||
#define HAVE_STRPBRK 1
|
||||
#define HAVE_VSSCANF 1
|
||||
#define HAVE_VSNPRINTF 1
|
||||
#define HAVE_ACOS 1
|
||||
#define HAVE_ASIN 1
|
||||
@@ -211,10 +211,7 @@ typedef unsigned int uintptr_t;
|
||||
#if _MSC_VER >= 1400
|
||||
#define HAVE__FSEEKI64 1
|
||||
#endif
|
||||
#endif /* _MSC_VER */
|
||||
#else
|
||||
#define HAVE_STDARG_H 1
|
||||
#define HAVE_STDDEF_H 1
|
||||
#endif /* _MSC_VER */
|
||||
#endif
|
||||
|
||||
/* Enable various audio drivers */
|
||||
|
||||
@@ -65,7 +65,7 @@
|
||||
|
||||
// Initialization/Cleanup routines
|
||||
#include "timer/SDL_timer_c.h"
|
||||
#ifdef SDL_VIDEO_DRIVER_WINDOWS
|
||||
#ifdef SDL_PLATFORM_WINDOWS
|
||||
extern bool SDL_HelperWindowCreate(void);
|
||||
extern void SDL_HelperWindowDestroy(void);
|
||||
#endif
|
||||
@@ -317,7 +317,7 @@ bool SDL_InitSubSystem(SDL_InitFlags flags)
|
||||
SDL_DBus_Init();
|
||||
#endif
|
||||
|
||||
#ifdef SDL_VIDEO_DRIVER_WINDOWS
|
||||
#ifdef SDL_PLATFORM_WINDOWS
|
||||
if (flags & (SDL_INIT_HAPTIC | SDL_INIT_JOYSTICK)) {
|
||||
if (!SDL_HelperWindowCreate()) {
|
||||
goto quit_and_error;
|
||||
@@ -653,7 +653,7 @@ void SDL_Quit(void)
|
||||
SDL_bInMainQuit = true;
|
||||
|
||||
// Quit all subsystems
|
||||
#ifdef SDL_VIDEO_DRIVER_WINDOWS
|
||||
#ifdef SDL_PLATFORM_WINDOWS
|
||||
SDL_HelperWindowDestroy();
|
||||
#endif
|
||||
SDL_QuitSubSystem(SDL_INIT_EVERYTHING);
|
||||
|
||||
@@ -265,6 +265,12 @@ extern "C" {
|
||||
#include "SDL_utils_c.h"
|
||||
#include "SDL_hashtable.h"
|
||||
|
||||
#define PUSH_SDL_ERROR() \
|
||||
{ char *_error = SDL_strdup(SDL_GetError());
|
||||
|
||||
#define POP_SDL_ERROR() \
|
||||
SDL_SetError("%s", _error); SDL_free(_error); }
|
||||
|
||||
// Do any initialization that needs to happen before threads are started
|
||||
extern void SDL_InitMainThread(void);
|
||||
|
||||
|
||||
+64
-20
@@ -410,6 +410,7 @@ static SDL_LogicalAudioDevice *ObtainLogicalAudioDevice(SDL_AudioDeviceID devid,
|
||||
SDL_LockRWLockForReading(current_audio.device_hash_lock);
|
||||
SDL_FindInHashTable(current_audio.device_hash, (const void *) (uintptr_t) devid, (const void **) &logdev);
|
||||
if (logdev) {
|
||||
SDL_assert(logdev->instance_id == devid);
|
||||
device = logdev->physical_device;
|
||||
SDL_assert(device != NULL);
|
||||
RefPhysicalAudioDevice(device); // reference it, in case the logical device migrates to a new default.
|
||||
@@ -459,6 +460,7 @@ static SDL_AudioDevice *ObtainPhysicalAudioDevice(SDL_AudioDeviceID devid) // !
|
||||
} else {
|
||||
SDL_LockRWLockForReading(current_audio.device_hash_lock);
|
||||
SDL_FindInHashTable(current_audio.device_hash, (const void *) (uintptr_t) devid, (const void **) &device);
|
||||
SDL_assert(device->instance_id == devid);
|
||||
SDL_UnlockRWLock(current_audio.device_hash_lock);
|
||||
|
||||
if (!device) {
|
||||
@@ -883,6 +885,7 @@ static bool SDLCALL FindLowestDeviceID(void *userdata, const SDL_HashTable *tabl
|
||||
if (isphysical && (devid_recording == data->recording) && (devid < data->highest)) {
|
||||
data->highest = devid;
|
||||
data->result = (SDL_AudioDevice *) value;
|
||||
SDL_assert(data->result->instance_id == devid);
|
||||
}
|
||||
return true; // keep iterating.
|
||||
}
|
||||
@@ -1051,7 +1054,10 @@ static bool SDLCALL DestroyOnePhysicalAudioDevice(void *userdata, const SDL_Hash
|
||||
const SDL_AudioDeviceID devid = (SDL_AudioDeviceID) (uintptr_t) key;
|
||||
const bool isphysical = !!(devid & (1<<1));
|
||||
if (isphysical) {
|
||||
DestroyPhysicalAudioDevice((SDL_AudioDevice *) value);
|
||||
SDL_AudioDevice *dev = (SDL_AudioDevice *) value;
|
||||
|
||||
SDL_assert(dev->instance_id == devid);
|
||||
DestroyPhysicalAudioDevice(dev);
|
||||
}
|
||||
return true; // keep iterating.
|
||||
}
|
||||
@@ -1147,7 +1153,10 @@ bool SDL_PlaybackAudioThreadIterate(SDL_AudioDevice *device)
|
||||
// We should have updated this elsewhere if the format changed!
|
||||
SDL_assert(SDL_AudioSpecsEqual(&stream->dst_spec, &device->spec, NULL, NULL));
|
||||
|
||||
SDL_assert(stream->src_spec.format != SDL_AUDIO_UNKNOWN);
|
||||
|
||||
const int br = SDL_GetAtomicInt(&logdev->paused) ? 0 : SDL_GetAudioStreamDataAdjustGain(stream, device_buffer, buffer_size, logdev->gain);
|
||||
|
||||
if (br < 0) { // Probably OOM. Kill the audio device; the whole thing is likely dying soon anyhow.
|
||||
failed = true;
|
||||
SDL_memset(device_buffer, device->silence_value, buffer_size); // just supply silence to the device before we die.
|
||||
@@ -1189,6 +1198,8 @@ bool SDL_PlaybackAudioThreadIterate(SDL_AudioDevice *device)
|
||||
// We should have updated this elsewhere if the format changed!
|
||||
SDL_assert(SDL_AudioSpecsEqual(&stream->dst_spec, &outspec, NULL, NULL));
|
||||
|
||||
SDL_assert(stream->src_spec.format != SDL_AUDIO_UNKNOWN);
|
||||
|
||||
/* this will hold a lock on `stream` while getting. We don't explicitly lock the streams
|
||||
for iterating here because the binding linked list can only change while the device lock is held.
|
||||
(we _do_ lock the stream during binding/unbinding to make sure that two threads can't try to bind
|
||||
@@ -1243,7 +1254,11 @@ void SDL_PlaybackAudioThreadShutdown(SDL_AudioDevice *device)
|
||||
const int frames = device->buffer_size / SDL_AUDIO_FRAMESIZE(device->spec);
|
||||
// Wait for the audio to drain if device didn't die.
|
||||
if (!SDL_GetAtomicInt(&device->zombie)) {
|
||||
SDL_Delay(((frames * 1000) / device->spec.freq) * 2);
|
||||
int delay = ((frames * 1000) / device->spec.freq) * 2;
|
||||
if (delay > 100) {
|
||||
delay = 100;
|
||||
}
|
||||
SDL_Delay(delay);
|
||||
}
|
||||
current_audio.impl.ThreadDeinit(device);
|
||||
SDL_AudioThreadFinalize(device);
|
||||
@@ -1324,6 +1339,7 @@ bool SDL_RecordingAudioThreadIterate(SDL_AudioDevice *device)
|
||||
SDL_assert(stream->src_spec.format == ((logdev->postmix || (logdev->gain != 1.0f)) ? SDL_AUDIO_F32 : device->spec.format));
|
||||
SDL_assert(stream->src_spec.channels == device->spec.channels);
|
||||
SDL_assert(stream->src_spec.freq == device->spec.freq);
|
||||
SDL_assert(stream->dst_spec.format != SDL_AUDIO_UNKNOWN);
|
||||
|
||||
void *final_buf = output_buffer;
|
||||
|
||||
@@ -1385,6 +1401,7 @@ static int SDLCALL RecordingAudioThread(void *devicep) // thread entry point
|
||||
typedef struct CountAudioDevicesData
|
||||
{
|
||||
int devs_seen;
|
||||
int devs_skipped;
|
||||
const int num_devices;
|
||||
SDL_AudioDeviceID *result;
|
||||
const bool recording;
|
||||
@@ -1400,7 +1417,13 @@ static bool SDLCALL CountAudioDevices(void *userdata, const SDL_HashTable *table
|
||||
const bool isphysical = !!(devid & (1<<1));
|
||||
if (isphysical && (devid_recording == data->recording)) {
|
||||
SDL_assert(data->devs_seen < data->num_devices);
|
||||
data->result[data->devs_seen++] = devid;
|
||||
SDL_AudioDevice *device = (SDL_AudioDevice *) value; // this is normally risky, but we hold the device_hash_lock here.
|
||||
const bool zombie = SDL_GetAtomicInt(&device->zombie) != 0;
|
||||
if (zombie) {
|
||||
data->devs_skipped++;
|
||||
} else {
|
||||
data->result[data->devs_seen++] = devid;
|
||||
}
|
||||
}
|
||||
return true; // keep iterating.
|
||||
}
|
||||
@@ -1416,10 +1439,11 @@ static SDL_AudioDeviceID *GetAudioDevices(int *count, bool recording)
|
||||
num_devices = SDL_GetAtomicInt(recording ? ¤t_audio.recording_device_count : ¤t_audio.playback_device_count);
|
||||
result = (SDL_AudioDeviceID *) SDL_malloc((num_devices + 1) * sizeof (SDL_AudioDeviceID));
|
||||
if (result) {
|
||||
CountAudioDevicesData data = { 0, num_devices, result, recording };
|
||||
CountAudioDevicesData data = { 0, 0, num_devices, result, recording };
|
||||
SDL_IterateHashTable(current_audio.device_hash, CountAudioDevices, &data);
|
||||
SDL_assert(data.devs_seen == num_devices);
|
||||
result[data.devs_seen] = 0; // null-terminated.
|
||||
SDL_assert((data.devs_seen + data.devs_skipped) == num_devices);
|
||||
num_devices = data.devs_seen; // might be less if we skipped any.
|
||||
result[num_devices] = 0; // null-terminated.
|
||||
}
|
||||
}
|
||||
SDL_UnlockRWLock(current_audio.device_hash_lock);
|
||||
@@ -1464,6 +1488,7 @@ static bool SDLCALL FindAudioDeviceByCallback(void *userdata, const SDL_HashTabl
|
||||
SDL_AudioDevice *device = (SDL_AudioDevice *) value;
|
||||
if (data->callback(device, data->userdata)) { // found it?
|
||||
data->retval = device;
|
||||
SDL_assert(data->retval->instance_id == devid);
|
||||
return false; // stop iterating, we found it.
|
||||
}
|
||||
}
|
||||
@@ -1502,8 +1527,10 @@ SDL_AudioDevice *SDL_FindPhysicalAudioDeviceByHandle(void *handle)
|
||||
|
||||
const char *SDL_GetAudioDeviceName(SDL_AudioDeviceID devid)
|
||||
{
|
||||
// bit #1 of devid is set for physical devices and unset for logical.
|
||||
const bool islogical = !(devid & (1<<1));
|
||||
const char *result = NULL;
|
||||
SDL_AudioDevice *device = NULL;
|
||||
const void *vdev = NULL;
|
||||
|
||||
if (!SDL_GetCurrentAudioDriver()) {
|
||||
SDL_SetError("Audio subsystem is not initialized");
|
||||
@@ -1513,10 +1540,16 @@ const char *SDL_GetAudioDeviceName(SDL_AudioDeviceID devid)
|
||||
// remains valid (in case the device is unplugged at the wrong moment), we hold the
|
||||
// device_hash_lock while we copy the string.
|
||||
SDL_LockRWLockForReading(current_audio.device_hash_lock);
|
||||
SDL_FindInHashTable(current_audio.device_hash, (const void *) (uintptr_t) devid, (const void **) &device);
|
||||
if (!device) {
|
||||
SDL_FindInHashTable(current_audio.device_hash, (const void *) (uintptr_t) devid, &vdev);
|
||||
if (!vdev) {
|
||||
SDL_SetError("Invalid audio device instance ID");
|
||||
} else if (islogical) {
|
||||
const SDL_LogicalAudioDevice *logdev = (const SDL_LogicalAudioDevice *) vdev;
|
||||
SDL_assert(logdev->instance_id == devid);
|
||||
result = SDL_GetPersistentString(logdev->physical_device->name);
|
||||
} else {
|
||||
const SDL_AudioDevice *device = (const SDL_AudioDevice *) vdev;
|
||||
SDL_assert(device->instance_id == devid);
|
||||
result = SDL_GetPersistentString(device->name);
|
||||
}
|
||||
SDL_UnlockRWLock(current_audio.device_hash_lock);
|
||||
@@ -1552,7 +1585,9 @@ int *SDL_GetAudioDeviceChannelMap(SDL_AudioDeviceID devid, int *count)
|
||||
SDL_AudioDevice *device = ObtainPhysicalAudioDeviceDefaultAllowed(devid);
|
||||
if (device) {
|
||||
channels = device->spec.channels;
|
||||
result = SDL_ChannelMapDup(device->chmap, channels);
|
||||
if (channels > 0 && device->chmap) {
|
||||
result = SDL_ChannelMapDup(device->chmap, channels);
|
||||
}
|
||||
}
|
||||
ReleaseAudioDevice(device);
|
||||
|
||||
@@ -1728,13 +1763,18 @@ static bool OpenPhysicalAudioDevice(SDL_AudioDevice *device, const SDL_AudioSpec
|
||||
SDL_copyp(&spec, inspec ? inspec : &device->default_spec);
|
||||
PrepareAudioFormat(device->recording, &spec);
|
||||
|
||||
/* We allow the device format to change if it's better than the current settings (by various definitions of "better"). This prevents
|
||||
something low quality, like an old game using S8/8000Hz audio, from ruining a music thing playing at CD quality that tries to open later.
|
||||
(or some VoIP library that opens for mono output ruining your surround-sound game because it got there first).
|
||||
/* We impose a simple minimum on device formats. This prevents something low quality, like an old game using S8/8000Hz audio,
|
||||
from ruining a music thing playing at CD quality that tries to open later, or some VoIP library that opens for mono output
|
||||
ruining your surround-sound game because it got there first.
|
||||
These are just requests! The backend may change any of these values during OpenDevice method! */
|
||||
device->spec.format = (SDL_AUDIO_BITSIZE(device->default_spec.format) >= SDL_AUDIO_BITSIZE(spec.format)) ? device->default_spec.format : spec.format;
|
||||
device->spec.freq = SDL_max(device->default_spec.freq, spec.freq);
|
||||
device->spec.channels = SDL_max(device->default_spec.channels, spec.channels);
|
||||
|
||||
const SDL_AudioFormat minimum_format = device->recording ? DEFAULT_AUDIO_RECORDING_FORMAT : DEFAULT_AUDIO_PLAYBACK_FORMAT;
|
||||
const int minimum_channels = device->recording ? DEFAULT_AUDIO_RECORDING_CHANNELS : DEFAULT_AUDIO_PLAYBACK_CHANNELS;
|
||||
const int minimum_freq = device->recording ? DEFAULT_AUDIO_RECORDING_FREQUENCY : DEFAULT_AUDIO_PLAYBACK_FREQUENCY;
|
||||
|
||||
device->spec.format = (SDL_AUDIO_BITSIZE(minimum_format) >= SDL_AUDIO_BITSIZE(spec.format)) ? minimum_format : spec.format;
|
||||
device->spec.channels = SDL_max(minimum_channels, spec.channels);
|
||||
device->spec.freq = SDL_max(minimum_freq, spec.freq);
|
||||
device->sample_frames = SDL_GetDefaultSampleFramesFromFreq(device->spec.freq);
|
||||
SDL_UpdatedAudioDeviceFormat(device); // start this off sane.
|
||||
|
||||
@@ -1945,10 +1985,6 @@ bool SDL_BindAudioStreams(SDL_AudioDeviceID devid, SDL_AudioStream * const *stre
|
||||
} else if (logdev->simplified) {
|
||||
result = SDL_SetError("Cannot change stream bindings on device opened with SDL_OpenAudioDeviceStream");
|
||||
} else {
|
||||
|
||||
// !!! FIXME: We'll set the device's side's format below, but maybe we should refuse to bind a stream if the app's side doesn't have a format set yet.
|
||||
// !!! FIXME: Actually, why do we allow there to be an invalid format, again?
|
||||
|
||||
// make sure start of list is sane.
|
||||
SDL_assert(!logdev->bound_streams || (logdev->bound_streams->prev_binding == NULL));
|
||||
|
||||
@@ -1983,9 +2019,17 @@ bool SDL_BindAudioStreams(SDL_AudioDeviceID devid, SDL_AudioStream * const *stre
|
||||
|
||||
if (result) {
|
||||
// Now that everything is verified, chain everything together.
|
||||
const bool recording = device->recording;
|
||||
for (int i = 0; i < num_streams; i++) {
|
||||
SDL_AudioStream *stream = streams[i];
|
||||
if (stream) { // shouldn't be NULL, but just in case...
|
||||
// if the stream never had its non-device-end format set, just set it to the device end's format.
|
||||
if (recording && (stream->dst_spec.format == SDL_AUDIO_UNKNOWN)) {
|
||||
SDL_copyp(&stream->dst_spec, &device->spec);
|
||||
} else if (!recording && (stream->src_spec.format == SDL_AUDIO_UNKNOWN)) {
|
||||
SDL_copyp(&stream->src_spec, &device->spec);
|
||||
}
|
||||
|
||||
stream->bound_device = logdev;
|
||||
stream->prev_binding = NULL;
|
||||
stream->next_binding = logdev->bound_streams;
|
||||
|
||||
@@ -537,8 +537,10 @@ static void SDL_TARGETING("ssse3") SDL_Convert_Swap32_SSSE3(Uint32* dst, const U
|
||||
// behavior. However, the compiler support for this pragma is bad.
|
||||
#if defined(__clang__)
|
||||
#if __clang_major__ >= 12
|
||||
#if defined(__aarch64__)
|
||||
#pragma STDC FENV_ACCESS ON
|
||||
#endif
|
||||
#endif
|
||||
#elif defined(_MSC_VER)
|
||||
#pragma fenv_access (on)
|
||||
#elif defined(__GNUC__)
|
||||
@@ -814,8 +816,10 @@ static void SDL_Convert_Swap32_NEON(Uint32* dst, const Uint32* src, int num_samp
|
||||
|
||||
#if defined(__clang__)
|
||||
#if __clang_major__ >= 12
|
||||
#if defined(__aarch64__)
|
||||
#pragma STDC FENV_ACCESS DEFAULT
|
||||
#endif
|
||||
#endif
|
||||
#elif defined(_MSC_VER)
|
||||
#pragma fenv_access (off)
|
||||
#elif defined(__GNUC__)
|
||||
|
||||
+11
-2
@@ -1775,6 +1775,7 @@ static bool WaveLoad(SDL_IOStream *src, WaveFile *file, SDL_AudioSpec *spec, Uin
|
||||
int result;
|
||||
Uint32 chunkcount = 0;
|
||||
Uint32 chunkcountlimit = 10000;
|
||||
const Sint64 flen = SDL_GetIOSize(src); // this might be -1 if the IOStream can't determine the total size.
|
||||
const char *hint;
|
||||
Sint64 RIFFstart, RIFFend, lastchunkpos;
|
||||
bool RIFFlengthknown = false;
|
||||
@@ -1883,6 +1884,14 @@ static bool WaveLoad(SDL_IOStream *src, WaveFile *file, SDL_AudioSpec *spec, Uin
|
||||
fmtchunk = *chunk;
|
||||
}
|
||||
} else if (chunk->fourcc == DATA) {
|
||||
/* If the data chunk is bigger than the file, it might be corrupt
|
||||
or the file is truncated. Try to recover by clamping the file
|
||||
size. This also means a malicious file can't allocate 4 gigabytes
|
||||
for the chunks without actually supplying a 4 gigabyte file. */
|
||||
if ((flen > 0) && ((chunk->position + chunk->length) > flen)) {
|
||||
chunk->length = (Uint32) (flen - chunk->position);
|
||||
}
|
||||
|
||||
/* Only use the first data chunk. Handling the wavl list madness
|
||||
* may require a different approach.
|
||||
*/
|
||||
@@ -2114,8 +2123,8 @@ bool SDL_LoadWAV_IO(SDL_IOStream *src, bool closeio, SDL_AudioSpec *spec, Uint8
|
||||
result = WaveLoad(src, &file, spec, audio_buf, audio_len);
|
||||
if (!result) {
|
||||
SDL_free(*audio_buf);
|
||||
audio_buf = NULL;
|
||||
audio_len = 0;
|
||||
*audio_buf = NULL;
|
||||
*audio_len = 0;
|
||||
}
|
||||
|
||||
// Cleanup
|
||||
|
||||
@@ -308,6 +308,12 @@ static bool BuildAAudioStream(SDL_AudioDevice *device)
|
||||
ctx.AAudioStreamBuilder_setFormat(builder, format);
|
||||
ctx.AAudioStreamBuilder_setSampleRate(builder, device->spec.freq);
|
||||
ctx.AAudioStreamBuilder_setChannelCount(builder, device->spec.channels);
|
||||
|
||||
// If no specific buffer size has been requested, the device will pick the optimal
|
||||
if(SDL_GetHint(SDL_HINT_AUDIO_DEVICE_SAMPLE_FRAMES)) {
|
||||
ctx.AAudioStreamBuilder_setBufferCapacityInFrames(builder, 2 * device->sample_frames); // AAudio requires that the buffer capacity is at least
|
||||
ctx.AAudioStreamBuilder_setFramesPerDataCallback(builder, device->sample_frames); // twice the size of the data callback buffer size
|
||||
}
|
||||
|
||||
const aaudio_direction_t direction = (recording ? AAUDIO_DIRECTION_INPUT : AAUDIO_DIRECTION_OUTPUT);
|
||||
ctx.AAudioStreamBuilder_setDirection(builder, direction);
|
||||
|
||||
@@ -31,7 +31,7 @@ SDL_PROC_UNUSED(void, AAudioStreamBuilder_setSamplesPerFrame, (AAudioStreamBuild
|
||||
SDL_PROC(void, AAudioStreamBuilder_setFormat, (AAudioStreamBuilder * builder, aaudio_format_t format))
|
||||
SDL_PROC_UNUSED(void, AAudioStreamBuilder_setSharingMode, (AAudioStreamBuilder * builder, aaudio_sharing_mode_t sharingMode))
|
||||
SDL_PROC(void, AAudioStreamBuilder_setDirection, (AAudioStreamBuilder * builder, aaudio_direction_t direction))
|
||||
SDL_PROC_UNUSED(void, AAudioStreamBuilder_setBufferCapacityInFrames, (AAudioStreamBuilder * builder, int32_t numFrames))
|
||||
SDL_PROC(void, AAudioStreamBuilder_setBufferCapacityInFrames, (AAudioStreamBuilder * builder, int32_t numFrames))
|
||||
SDL_PROC(void, AAudioStreamBuilder_setPerformanceMode, (AAudioStreamBuilder * builder, aaudio_performance_mode_t mode))
|
||||
SDL_PROC_UNUSED(void, AAudioStreamBuilder_setUsage, (AAudioStreamBuilder * builder, aaudio_usage_t usage)) // API 28
|
||||
SDL_PROC_UNUSED(void, AAudioStreamBuilder_setContentType, (AAudioStreamBuilder * builder, aaudio_content_type_t contentType)) // API 28
|
||||
|
||||
@@ -461,8 +461,6 @@ static void ALSA_CloseDevice(SDL_AudioDevice *device)
|
||||
{
|
||||
if (device->hidden) {
|
||||
if (device->hidden->pcm) {
|
||||
// Wait for the submitted audio to drain. ALSA_snd_pcm_drop() can hang, so don't use that.
|
||||
SDL_Delay(((device->sample_frames * 1000) / device->spec.freq) * 2);
|
||||
ALSA_snd_pcm_close(device->hidden->pcm);
|
||||
}
|
||||
SDL_free(device->hidden->mixbuf);
|
||||
@@ -1156,7 +1154,7 @@ static bool ALSA_OpenDevice(SDL_AudioDevice *device)
|
||||
#if SDL_ALSA_DEBUG
|
||||
snd_pcm_uframes_t bufsize;
|
||||
ALSA_snd_pcm_hw_params_get_buffer_size(cfg_ctx.hwparams, &bufsize);
|
||||
SDL_LogError(SDL_LOG_CATEGORY_AUDIO,
|
||||
SDL_LogDebug(SDL_LOG_CATEGORY_AUDIO,
|
||||
"ALSA: period size = %ld, periods = %u, buffer size = %lu",
|
||||
cfg_ctx.persize, cfg_ctx.periods, bufsize);
|
||||
#endif
|
||||
|
||||
@@ -420,7 +420,8 @@ static bool UpdateAudioSession(SDL_AudioDevice *device, bool open, bool allow_pl
|
||||
|
||||
hint = SDL_GetHint(SDL_HINT_AUDIO_CATEGORY);
|
||||
if (hint) {
|
||||
if (SDL_strcasecmp(hint, "AVAudioSessionCategoryAmbient") == 0) {
|
||||
if (SDL_strcasecmp(hint, "AVAudioSessionCategoryAmbient") == 0 ||
|
||||
SDL_strcasecmp(hint, "ambient") == 0) {
|
||||
category = AVAudioSessionCategoryAmbient;
|
||||
} else if (SDL_strcasecmp(hint, "AVAudioSessionCategorySoloAmbient") == 0) {
|
||||
category = AVAudioSessionCategorySoloAmbient;
|
||||
|
||||
@@ -206,7 +206,7 @@ static void DSOUND_DetectDevices(SDL_AudioDevice **default_playback, SDL_AudioDe
|
||||
{
|
||||
#ifdef HAVE_MMDEVICEAPI_H
|
||||
if (SupportsIMMDevice) {
|
||||
SDL_IMMDevice_EnumerateEndpoints(default_playback, default_recording);
|
||||
SDL_IMMDevice_EnumerateEndpoints(default_playback, default_recording, SDL_AUDIO_UNKNOWN);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
|
||||
@@ -189,7 +189,7 @@ static bool EMSCRIPTENAUDIO_OpenDevice(SDL_AudioDevice *device)
|
||||
}
|
||||
|
||||
// limit to native freq
|
||||
device->spec.freq = EM_ASM_INT({ return Module['SDL3'].audioContext.sampleRate; });
|
||||
device->spec.freq = MAIN_THREAD_EM_ASM_INT({ return Module['SDL3'].audioContext.sampleRate; });
|
||||
device->sample_frames = SDL_GetDefaultSampleFramesFromFreq(device->spec.freq) * 2; // double the buffer size, some browsers need more, and we'll just have to live with the latency.
|
||||
|
||||
SDL_UpdatedAudioDeviceFormat(device);
|
||||
|
||||
@@ -426,28 +426,33 @@ static void OPENSLES_DestroyPCMPlayer(SDL_AudioDevice *device)
|
||||
|
||||
static bool OPENSLES_CreatePCMPlayer(SDL_AudioDevice *device)
|
||||
{
|
||||
/* If we want to add floating point audio support (requires API level 21)
|
||||
it can be done as described here:
|
||||
https://developer.android.com/ndk/guides/audio/opensl/android-extensions.html#floating-point
|
||||
*/
|
||||
/* according to https://developer.android.com/ndk/guides/audio/opensl/opensl-for-android,
|
||||
Android's OpenSL ES only supports Uint8 and _littleendian_ Sint16.
|
||||
(and float32, with an extension we use, below.) */
|
||||
if (SDL_GetAndroidSDKVersion() >= 21) {
|
||||
const SDL_AudioFormat *closefmts = SDL_ClosestAudioFormats(device->spec.format);
|
||||
SDL_AudioFormat test_format;
|
||||
while ((test_format = *(closefmts++)) != 0) {
|
||||
if (SDL_AUDIO_ISSIGNED(test_format)) {
|
||||
switch (test_format) {
|
||||
case SDL_AUDIO_U8:
|
||||
case SDL_AUDIO_S16LE:
|
||||
case SDL_AUDIO_F32:
|
||||
break;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (!test_format) {
|
||||
// Didn't find a compatible format :
|
||||
LOGI("No compatible audio format, using signed 16-bit audio");
|
||||
test_format = SDL_AUDIO_S16;
|
||||
LOGI("No compatible audio format, using signed 16-bit LE audio");
|
||||
test_format = SDL_AUDIO_S16LE;
|
||||
}
|
||||
device->spec.format = test_format;
|
||||
} else {
|
||||
// Just go with signed 16-bit audio as it's the most compatible
|
||||
device->spec.format = SDL_AUDIO_S16;
|
||||
device->spec.format = SDL_AUDIO_S16LE;
|
||||
}
|
||||
|
||||
// Update the fragment size as size in bytes
|
||||
|
||||
@@ -114,7 +114,7 @@ static bool PSPAUDIO_PlayDevice(SDL_AudioDevice *device, const Uint8 *buffer, in
|
||||
} else {
|
||||
rc = sceAudioOutputPannedBlocking(device->hidden->channel, PSP_AUDIO_VOLUME_MAX, PSP_AUDIO_VOLUME_MAX, (void *) buffer);
|
||||
}
|
||||
return (rc == 0);
|
||||
return (rc >= 0);
|
||||
}
|
||||
|
||||
static bool PSPAUDIO_WaitDevice(SDL_AudioDevice *device)
|
||||
|
||||
@@ -269,19 +269,9 @@ static const char *getAppName(void)
|
||||
return SDL_GetAppMetadataProperty(SDL_PROP_APP_METADATA_NAME_STRING);
|
||||
}
|
||||
|
||||
static void ThreadedMainloopSignal(void)
|
||||
{
|
||||
PULSEAUDIO_pa_threaded_mainloop_signal(pulseaudio_threaded_mainloop, 0); // alert waiting threads to unblock.
|
||||
|
||||
// we need to kill any SDL_SetError state; we didn't create this thread
|
||||
// so its SDL TLS slot will leak otherwise, so we do this every time
|
||||
// we're (presumably) losing control of the thread.
|
||||
SDL_CleanupTLS();
|
||||
}
|
||||
|
||||
static void OperationStateChangeCallback(pa_operation *o, void *userdata)
|
||||
{
|
||||
ThreadedMainloopSignal(); // just signal any waiting code, it can look up the details.
|
||||
PULSEAUDIO_pa_threaded_mainloop_signal(pulseaudio_threaded_mainloop, 0); // just signal any waiting code, it can look up the details.
|
||||
}
|
||||
|
||||
/* This function assume you are holding `mainloop`'s lock. The operation is unref'd in here, assuming
|
||||
@@ -323,7 +313,7 @@ static void DisconnectFromPulseServer(void)
|
||||
|
||||
static void PulseContextStateChangeCallback(pa_context *context, void *userdata)
|
||||
{
|
||||
ThreadedMainloopSignal(); // just signal any waiting code, it can look up the details.
|
||||
PULSEAUDIO_pa_threaded_mainloop_signal(pulseaudio_threaded_mainloop, 0); // just signal any waiting code, it can look up the details.
|
||||
}
|
||||
|
||||
static bool ConnectToPulseServer(void)
|
||||
@@ -410,7 +400,7 @@ static void WriteCallback(pa_stream *p, size_t nbytes, void *userdata)
|
||||
struct SDL_PrivateAudioData *h = (struct SDL_PrivateAudioData *)userdata;
|
||||
//SDL_Log("PULSEAUDIO WRITE CALLBACK! nbytes=%u", (unsigned int) nbytes);
|
||||
h->bytes_requested += nbytes;
|
||||
ThreadedMainloopSignal();
|
||||
PULSEAUDIO_pa_threaded_mainloop_signal(pulseaudio_threaded_mainloop, 0);
|
||||
}
|
||||
|
||||
// This function waits until it is possible to write a full sound buffer
|
||||
@@ -481,7 +471,7 @@ static Uint8 *PULSEAUDIO_GetDeviceBuf(SDL_AudioDevice *device, int *buffer_size)
|
||||
static void ReadCallback(pa_stream *p, size_t nbytes, void *userdata)
|
||||
{
|
||||
//SDL_Log("PULSEAUDIO READ CALLBACK! nbytes=%u", (unsigned int) nbytes);
|
||||
ThreadedMainloopSignal(); // the recording code queries what it needs, we just need to signal to end any wait
|
||||
PULSEAUDIO_pa_threaded_mainloop_signal(pulseaudio_threaded_mainloop, 0); // the recording code queries what it needs, we just need to signal to end any wait
|
||||
}
|
||||
|
||||
static bool PULSEAUDIO_WaitRecordingDevice(SDL_AudioDevice *device)
|
||||
@@ -602,7 +592,72 @@ static void PULSEAUDIO_CloseDevice(SDL_AudioDevice *device)
|
||||
|
||||
static void PulseStreamStateChangeCallback(pa_stream *stream, void *userdata)
|
||||
{
|
||||
ThreadedMainloopSignal(); // just signal any waiting code, it can look up the details.
|
||||
PULSEAUDIO_pa_threaded_mainloop_signal(pulseaudio_threaded_mainloop, 0); // just signal any waiting code, it can look up the details.
|
||||
}
|
||||
|
||||
// Channel maps that match the order in SDL_Audio.h
|
||||
static const pa_channel_position_t Pulse_map_1[] = { PA_CHANNEL_POSITION_MONO };
|
||||
static const pa_channel_position_t Pulse_map_2[] = { PA_CHANNEL_POSITION_FRONT_LEFT, PA_CHANNEL_POSITION_FRONT_RIGHT };
|
||||
|
||||
static const pa_channel_position_t Pulse_map_3[] = { PA_CHANNEL_POSITION_FRONT_LEFT, PA_CHANNEL_POSITION_FRONT_RIGHT,
|
||||
PA_CHANNEL_POSITION_LFE };
|
||||
|
||||
static const pa_channel_position_t Pulse_map_4[] = { PA_CHANNEL_POSITION_FRONT_LEFT, PA_CHANNEL_POSITION_FRONT_RIGHT,
|
||||
PA_CHANNEL_POSITION_REAR_LEFT, PA_CHANNEL_POSITION_REAR_RIGHT };
|
||||
|
||||
static const pa_channel_position_t Pulse_map_5[] = { PA_CHANNEL_POSITION_FRONT_LEFT, PA_CHANNEL_POSITION_FRONT_RIGHT,
|
||||
PA_CHANNEL_POSITION_LFE,
|
||||
PA_CHANNEL_POSITION_REAR_LEFT, PA_CHANNEL_POSITION_REAR_RIGHT };
|
||||
|
||||
static const pa_channel_position_t Pulse_map_6[] = { PA_CHANNEL_POSITION_FRONT_LEFT, PA_CHANNEL_POSITION_FRONT_RIGHT,
|
||||
PA_CHANNEL_POSITION_FRONT_CENTER, PA_CHANNEL_POSITION_LFE,
|
||||
PA_CHANNEL_POSITION_REAR_LEFT, PA_CHANNEL_POSITION_REAR_RIGHT };
|
||||
|
||||
static const pa_channel_position_t Pulse_map_7[] = { PA_CHANNEL_POSITION_FRONT_LEFT, PA_CHANNEL_POSITION_FRONT_RIGHT,
|
||||
PA_CHANNEL_POSITION_FRONT_CENTER, PA_CHANNEL_POSITION_LFE,
|
||||
PA_CHANNEL_POSITION_REAR_CENTER,
|
||||
PA_CHANNEL_POSITION_SIDE_LEFT, PA_CHANNEL_POSITION_SIDE_RIGHT };
|
||||
|
||||
static const pa_channel_position_t Pulse_map_8[] = { PA_CHANNEL_POSITION_FRONT_LEFT, PA_CHANNEL_POSITION_FRONT_RIGHT,
|
||||
PA_CHANNEL_POSITION_FRONT_CENTER, PA_CHANNEL_POSITION_LFE,
|
||||
PA_CHANNEL_POSITION_REAR_LEFT, PA_CHANNEL_POSITION_REAR_RIGHT,
|
||||
PA_CHANNEL_POSITION_SIDE_LEFT, PA_CHANNEL_POSITION_SIDE_RIGHT };
|
||||
|
||||
#define COPY_CHANNEL_MAP(c) SDL_memcpy(pacmap->map, Pulse_map_##c, sizeof(Pulse_map_##c))
|
||||
|
||||
static void PulseCreateChannelMap(pa_channel_map *pacmap, uint8_t channels)
|
||||
{
|
||||
SDL_assert(channels <= PA_CHANNELS_MAX);
|
||||
|
||||
pacmap->channels = channels;
|
||||
|
||||
switch (channels) {
|
||||
case 1:
|
||||
COPY_CHANNEL_MAP(1);
|
||||
break;
|
||||
case 2:
|
||||
COPY_CHANNEL_MAP(2);
|
||||
break;
|
||||
case 3:
|
||||
COPY_CHANNEL_MAP(3);
|
||||
break;
|
||||
case 4:
|
||||
COPY_CHANNEL_MAP(4);
|
||||
break;
|
||||
case 5:
|
||||
COPY_CHANNEL_MAP(5);
|
||||
break;
|
||||
case 6:
|
||||
COPY_CHANNEL_MAP(6);
|
||||
break;
|
||||
case 7:
|
||||
COPY_CHANNEL_MAP(7);
|
||||
break;
|
||||
case 8:
|
||||
COPY_CHANNEL_MAP(8);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static bool PULSEAUDIO_OpenDevice(SDL_AudioDevice *device)
|
||||
@@ -682,7 +737,8 @@ static bool PULSEAUDIO_OpenDevice(SDL_AudioDevice *device)
|
||||
paspec.rate = device->spec.freq;
|
||||
|
||||
// Reduced prebuffering compared to the defaults.
|
||||
paattr.fragsize = device->buffer_size; // despite the name, this is only used for recording devices, according to PulseAudio docs!
|
||||
|
||||
paattr.fragsize = device->buffer_size * 2; // despite the name, this is only used for recording devices, according to PulseAudio docs! (times 2 because we want _more_ than our buffer size sent from the server at a time, which helps some drivers).
|
||||
paattr.tlength = device->buffer_size;
|
||||
paattr.prebuf = -1;
|
||||
paattr.maxlength = -1;
|
||||
@@ -692,9 +748,8 @@ static bool PULSEAUDIO_OpenDevice(SDL_AudioDevice *device)
|
||||
PULSEAUDIO_pa_threaded_mainloop_lock(pulseaudio_threaded_mainloop);
|
||||
|
||||
const char *name = SDL_GetHint(SDL_HINT_AUDIO_DEVICE_STREAM_NAME);
|
||||
// The SDL ALSA output hints us that we use Windows' channel mapping
|
||||
// https://bugzilla.libsdl.org/show_bug.cgi?id=110
|
||||
PULSEAUDIO_pa_channel_map_init_auto(&pacmap, device->spec.channels, PA_CHANNEL_MAP_WAVEEX);
|
||||
|
||||
PulseCreateChannelMap(&pacmap, device->spec.channels);
|
||||
|
||||
h->stream = PULSEAUDIO_pa_stream_new(
|
||||
pulseaudio_context,
|
||||
@@ -803,7 +858,7 @@ static void SinkInfoCallback(pa_context *c, const pa_sink_info *i, int is_last,
|
||||
if (i) {
|
||||
AddPulseAudioDevice(false, i->description, i->name, i->index, &i->sample_spec);
|
||||
}
|
||||
ThreadedMainloopSignal();
|
||||
PULSEAUDIO_pa_threaded_mainloop_signal(pulseaudio_threaded_mainloop, 0);
|
||||
}
|
||||
|
||||
// This is called when PulseAudio adds a recording ("source") device.
|
||||
@@ -813,7 +868,7 @@ static void SourceInfoCallback(pa_context *c, const pa_source_info *i, int is_la
|
||||
if (i && (include_monitors || (i->monitor_of_sink == PA_INVALID_INDEX))) {
|
||||
AddPulseAudioDevice(true, i->description, i->name, i->index, &i->sample_spec);
|
||||
}
|
||||
ThreadedMainloopSignal();
|
||||
PULSEAUDIO_pa_threaded_mainloop_signal(pulseaudio_threaded_mainloop, 0);
|
||||
}
|
||||
|
||||
static void ServerInfoCallback(pa_context *c, const pa_server_info *i, void *data)
|
||||
@@ -838,7 +893,7 @@ static void ServerInfoCallback(pa_context *c, const pa_server_info *i, void *dat
|
||||
}
|
||||
}
|
||||
|
||||
ThreadedMainloopSignal();
|
||||
PULSEAUDIO_pa_threaded_mainloop_signal(pulseaudio_threaded_mainloop, 0);
|
||||
}
|
||||
|
||||
static bool FindAudioDeviceByIndex(SDL_AudioDevice *device, void *userdata)
|
||||
@@ -882,7 +937,7 @@ static void HotplugCallback(pa_context *c, pa_subscription_event_type_t t, uint3
|
||||
SDL_AudioDeviceDisconnected(SDL_FindPhysicalAudioDeviceByCallback(FindAudioDeviceByIndex, (void *)(uintptr_t)idx));
|
||||
}
|
||||
}
|
||||
ThreadedMainloopSignal();
|
||||
PULSEAUDIO_pa_threaded_mainloop_signal(pulseaudio_threaded_mainloop, 0);
|
||||
}
|
||||
|
||||
static bool CheckDefaultDevice(const bool changed, char *device_path)
|
||||
|
||||
@@ -130,7 +130,8 @@ static bool VITAAUD_OpenDevice(SDL_AudioDevice *device)
|
||||
|
||||
static bool VITAAUD_PlayDevice(SDL_AudioDevice *device, const Uint8 *buffer, int buffer_size)
|
||||
{
|
||||
return (sceAudioOutOutput(device->hidden->port, buffer) == 0);
|
||||
// sceAudioOutOutput returns amount of samples queued or < 0 on error
|
||||
return (sceAudioOutOutput(device->hidden->port, buffer) >= 0);
|
||||
}
|
||||
|
||||
// This function waits until it is possible to write a full sound buffer
|
||||
|
||||
@@ -337,7 +337,7 @@ typedef struct
|
||||
static bool mgmtthrtask_DetectDevices(void *userdata)
|
||||
{
|
||||
mgmtthrtask_DetectDevicesData *data = (mgmtthrtask_DetectDevicesData *)userdata;
|
||||
SDL_IMMDevice_EnumerateEndpoints(data->default_playback, data->default_recording);
|
||||
SDL_IMMDevice_EnumerateEndpoints(data->default_playback, data->default_recording, SDL_AUDIO_F32);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -814,7 +814,7 @@ static void ANDROIDCAMERA_Deinitialize(void)
|
||||
static bool ANDROIDCAMERA_Init(SDL_CameraDriverImpl *impl)
|
||||
{
|
||||
// !!! FIXME: slide this off into a subroutine
|
||||
// system libraries are in android-24 and later; we currently target android-16 and later, so check if they exist at runtime.
|
||||
// system libraries are in android-24 and later; we currently target android-21 and later, so check if they exist at runtime.
|
||||
void *libcamera2 = dlopen("libcamera2ndk.so", RTLD_NOW | RTLD_LOCAL);
|
||||
if (!libcamera2) {
|
||||
SDL_Log("CAMERA: libcamera2ndk.so can't be loaded: %s", dlerror());
|
||||
|
||||
@@ -61,7 +61,7 @@ static SDL_CameraFrameResult EMSCRIPTENCAMERA_AcquireFrame(SDL_Camera *device, S
|
||||
|
||||
SDL3.camera.ctx2d.drawImage(SDL3.camera.video, 0, 0, w, h);
|
||||
const imgrgba = SDL3.camera.ctx2d.getImageData(0, 0, w, h).data;
|
||||
Module.HEAPU8.set(imgrgba, rgba);
|
||||
HEAPU8.set(imgrgba, rgba);
|
||||
|
||||
return 1;
|
||||
}, device->actual_spec.width, device->actual_spec.height, rgba);
|
||||
|
||||
@@ -570,7 +570,7 @@ static bool V4L2_OpenDevice(SDL_Camera *device, const SDL_CameraSpec *spec)
|
||||
setfps.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||
if (xioctl(fd, VIDIOC_G_PARM, &setfps) == 0) {
|
||||
if ( (setfps.parm.capture.timeperframe.denominator != spec->framerate_numerator) ||
|
||||
(setfps.parm.capture.timeperframe.numerator = spec->framerate_denominator) ) {
|
||||
(setfps.parm.capture.timeperframe.numerator != spec->framerate_denominator) ) {
|
||||
setfps.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||
setfps.parm.capture.timeperframe.numerator = spec->framerate_denominator;
|
||||
setfps.parm.capture.timeperframe.denominator = spec->framerate_numerator;
|
||||
|
||||
@@ -207,7 +207,6 @@ Sint32 JNI_OnLoad(void *vm, void *reserved)
|
||||
{
|
||||
(void)vm;
|
||||
(void)reserved;
|
||||
SDL_Unsupported();
|
||||
return -1; // JNI_ERR
|
||||
return 0x00010004; // JNI_VERSION_1_4
|
||||
}
|
||||
#endif
|
||||
@@ -371,6 +371,7 @@ static jmethodID midShowTextInput;
|
||||
static jmethodID midSupportsRelativeMouse;
|
||||
static jmethodID midOpenFileDescriptor;
|
||||
static jmethodID midShowFileDialog;
|
||||
static jmethodID midGetPreferredLocales;
|
||||
|
||||
// audio manager
|
||||
static jclass mAudioManagerClass;
|
||||
@@ -660,6 +661,7 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeSetupJNI)(JNIEnv *env, jclass cl
|
||||
midSupportsRelativeMouse = (*env)->GetStaticMethodID(env, mActivityClass, "supportsRelativeMouse", "()Z");
|
||||
midOpenFileDescriptor = (*env)->GetStaticMethodID(env, mActivityClass, "openFileDescriptor", "(Ljava/lang/String;Ljava/lang/String;)I");
|
||||
midShowFileDialog = (*env)->GetStaticMethodID(env, mActivityClass, "showFileDialog", "([Ljava/lang/String;ZZI)Z");
|
||||
midGetPreferredLocales = (*env)->GetStaticMethodID(env, mActivityClass, "getPreferredLocales", "()Ljava/lang/String;");
|
||||
|
||||
if (!midClipboardGetText ||
|
||||
!midClipboardHasText ||
|
||||
@@ -691,7 +693,8 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeSetupJNI)(JNIEnv *env, jclass cl
|
||||
!midShowTextInput ||
|
||||
!midSupportsRelativeMouse ||
|
||||
!midOpenFileDescriptor ||
|
||||
!midShowFileDialog) {
|
||||
!midShowFileDialog ||
|
||||
!midGetPreferredLocales) {
|
||||
__android_log_print(ANDROID_LOG_WARN, "SDL", "Missing some Java callbacks, do you have the latest version of SDLActivity.java?");
|
||||
}
|
||||
|
||||
@@ -1077,7 +1080,8 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeAddTouch)(
|
||||
{
|
||||
const char *utfname = (*env)->GetStringUTFChars(env, name, NULL);
|
||||
|
||||
SDL_AddTouch((SDL_TouchID)touchId, SDL_TOUCH_DEVICE_DIRECT, utfname);
|
||||
SDL_AddTouch(Android_ConvertJavaTouchID(touchId),
|
||||
SDL_TOUCH_DEVICE_DIRECT, utfname);
|
||||
|
||||
(*env)->ReleaseStringUTFChars(env, name, utfname);
|
||||
}
|
||||
@@ -1725,18 +1729,24 @@ static bool Android_JNI_ExceptionOccurred(bool silent)
|
||||
exceptionName = (jstring)(*env)->CallObjectMethod(env, exceptionClass, mid);
|
||||
exceptionNameUTF8 = (*env)->GetStringUTFChars(env, exceptionName, 0);
|
||||
|
||||
(*env)->DeleteLocalRef(env, classClass);
|
||||
|
||||
mid = (*env)->GetMethodID(env, exceptionClass, "getMessage", "()Ljava/lang/String;");
|
||||
exceptionMessage = (jstring)(*env)->CallObjectMethod(env, exception, mid);
|
||||
|
||||
(*env)->DeleteLocalRef(env, exceptionClass);
|
||||
|
||||
if (exceptionMessage != NULL) {
|
||||
const char *exceptionMessageUTF8 = (*env)->GetStringUTFChars(env, exceptionMessage, 0);
|
||||
SDL_SetError("%s: %s", exceptionNameUTF8, exceptionMessageUTF8);
|
||||
(*env)->ReleaseStringUTFChars(env, exceptionMessage, exceptionMessageUTF8);
|
||||
(*env)->DeleteLocalRef(env, exceptionMessage);
|
||||
} else {
|
||||
SDL_SetError("%s", exceptionNameUTF8);
|
||||
}
|
||||
|
||||
(*env)->ReleaseStringUTFChars(env, exceptionName, exceptionNameUTF8);
|
||||
(*env)->DeleteLocalRef(env, exceptionName);
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -2160,7 +2170,7 @@ bool Android_JNI_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *b
|
||||
mid = (*env)->GetMethodID(env, clazz,
|
||||
"messageboxShowMessageBox", "(ILjava/lang/String;Ljava/lang/String;[I[I[Ljava/lang/String;[I)I");
|
||||
*buttonID = (*env)->CallIntMethod(env, context, mid,
|
||||
messageboxdata->flags,
|
||||
(jint)messageboxdata->flags,
|
||||
title,
|
||||
message,
|
||||
button_flags,
|
||||
@@ -2414,7 +2424,7 @@ const char *SDL_GetAndroidCachePath(void)
|
||||
// fileObj = context.getExternalFilesDir();
|
||||
mid = (*env)->GetMethodID(env, (*env)->GetObjectClass(env, context),
|
||||
"getCacheDir", "()Ljava/io/File;");
|
||||
fileObject = (*env)->CallObjectMethod(env, context, mid, NULL);
|
||||
fileObject = (*env)->CallObjectMethod(env, context, mid);
|
||||
if (!fileObject) {
|
||||
SDL_SetError("Couldn't get cache directory");
|
||||
LocalReferenceHolder_Cleanup(&refs);
|
||||
@@ -2585,65 +2595,22 @@ bool Android_JNI_ShowToast(const char *message, int duration, int gravity, int x
|
||||
|
||||
bool Android_JNI_GetLocale(char *buf, size_t buflen)
|
||||
{
|
||||
AConfiguration *cfg;
|
||||
|
||||
SDL_assert(buflen > 6);
|
||||
|
||||
// Need to re-create the asset manager if locale has changed (SDL_EVENT_LOCALE_CHANGED)
|
||||
Internal_Android_Destroy_AssetManager();
|
||||
|
||||
if (!asset_manager) {
|
||||
Internal_Android_Create_AssetManager();
|
||||
}
|
||||
|
||||
if (!asset_manager) {
|
||||
return false;
|
||||
}
|
||||
|
||||
cfg = AConfiguration_new();
|
||||
if (!cfg) {
|
||||
return false;
|
||||
}
|
||||
|
||||
{
|
||||
char language[2] = {};
|
||||
char country[2] = {};
|
||||
size_t id = 0;
|
||||
|
||||
AConfiguration_fromAssetManager(cfg, asset_manager);
|
||||
AConfiguration_getLanguage(cfg, language);
|
||||
AConfiguration_getCountry(cfg, country);
|
||||
|
||||
// Indonesian is "id" according to ISO 639.2, but on Android is "in" because of Java backwards compatibility
|
||||
if (language[0] == 'i' && language[1] == 'n') {
|
||||
language[1] = 'd';
|
||||
}
|
||||
|
||||
// copy language (not null terminated)
|
||||
if (language[0]) {
|
||||
buf[id++] = language[0];
|
||||
if (language[1]) {
|
||||
buf[id++] = language[1];
|
||||
bool result = false;
|
||||
if (buf && buflen > 0) {
|
||||
*buf = '\0';
|
||||
JNIEnv *env = Android_JNI_GetEnv();
|
||||
jstring string = (jstring)(*env)->CallStaticObjectMethod(env, mActivityClass, midGetPreferredLocales);
|
||||
if (string) {
|
||||
const char *utf8string = (*env)->GetStringUTFChars(env, string, NULL);
|
||||
if (utf8string) {
|
||||
result = true;
|
||||
SDL_strlcpy(buf, utf8string, buflen);
|
||||
(*env)->ReleaseStringUTFChars(env, string, utf8string);
|
||||
}
|
||||
(*env)->DeleteLocalRef(env, string);
|
||||
}
|
||||
|
||||
buf[id++] = '_';
|
||||
|
||||
// copy country (not null terminated)
|
||||
if (country[0]) {
|
||||
buf[id++] = country[0];
|
||||
if (country[1]) {
|
||||
buf[id++] = country[1];
|
||||
}
|
||||
}
|
||||
|
||||
buf[id++] = '\0';
|
||||
SDL_assert(id <= buflen);
|
||||
}
|
||||
|
||||
AConfiguration_delete(cfg);
|
||||
|
||||
return true;
|
||||
return result;
|
||||
}
|
||||
|
||||
bool Android_JNI_OpenURL(const char *url)
|
||||
@@ -2807,6 +2774,7 @@ bool Android_JNI_OpenFileDialog(
|
||||
if (filters) {
|
||||
jclass stringClass = (*env)->FindClass(env, "java/lang/String");
|
||||
filtersArray = (*env)->NewObjectArray(env, nfilters, stringClass, NULL);
|
||||
(*env)->DeleteLocalRef(env, stringClass);
|
||||
|
||||
// Convert to string
|
||||
for (int i = 0; i < nfilters; i++) {
|
||||
|
||||
@@ -105,7 +105,7 @@ bool GDK_RegisterChangeNotifications(void)
|
||||
SDL_LogDebug(SDL_LOG_CATEGORY_APPLICATION, "[GDK] in RegisterAppConstrainedChangeNotification handler");
|
||||
SDL_VideoDevice *_this = SDL_GetVideoDevice();
|
||||
if (_this) {
|
||||
if (constrained) {
|
||||
if (constrained && !((_this->windows) && _this->windows->text_input_active)) {
|
||||
SDL_SetKeyboardFocus(NULL);
|
||||
} else {
|
||||
SDL_SetKeyboardFocus(_this->windows);
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include "SDL_fcitx.h"
|
||||
#include "../../video/SDL_sysvideo.h"
|
||||
#include "../../events/SDL_keyboard_c.h"
|
||||
#include "../../core/unix/SDL_appid.h"
|
||||
#include "SDL_dbus.h"
|
||||
|
||||
#ifdef SDL_VIDEO_DRIVER_X11
|
||||
@@ -53,32 +54,14 @@ typedef struct FcitxClient
|
||||
|
||||
static FcitxClient fcitx_client;
|
||||
|
||||
static char *GetAppName(void)
|
||||
static const char *GetAppName(void)
|
||||
{
|
||||
#if defined(SDL_PLATFORM_LINUX) || defined(SDL_PLATFORM_FREEBSD)
|
||||
char *spot;
|
||||
char procfile[1024];
|
||||
char linkfile[1024];
|
||||
int linksize;
|
||||
|
||||
#ifdef SDL_PLATFORM_LINUX
|
||||
(void)SDL_snprintf(procfile, sizeof(procfile), "/proc/%d/exe", getpid());
|
||||
#elif defined(SDL_PLATFORM_FREEBSD)
|
||||
(void)SDL_snprintf(procfile, sizeof(procfile), "/proc/%d/file", getpid());
|
||||
#endif
|
||||
linksize = readlink(procfile, linkfile, sizeof(linkfile) - 1);
|
||||
if (linksize > 0) {
|
||||
linkfile[linksize] = '\0';
|
||||
spot = SDL_strrchr(linkfile, '/');
|
||||
if (spot) {
|
||||
return SDL_strdup(spot + 1);
|
||||
} else {
|
||||
return SDL_strdup(linkfile);
|
||||
}
|
||||
const char *exe_name = SDL_GetExeName();
|
||||
if (exe_name) {
|
||||
return exe_name;
|
||||
}
|
||||
#endif // SDL_PLATFORM_LINUX || SDL_PLATFORM_FREEBSD
|
||||
|
||||
return SDL_strdup("SDL_App");
|
||||
return "SDL_App";
|
||||
}
|
||||
|
||||
static size_t Fcitx_GetPreeditString(SDL_DBusContext *dbus,
|
||||
@@ -281,7 +264,7 @@ static bool FcitxCreateInputContext(SDL_DBusContext *dbus, const char *appname,
|
||||
|
||||
static bool FcitxClientCreateIC(FcitxClient *client)
|
||||
{
|
||||
char *appname = GetAppName();
|
||||
const char *appname = GetAppName();
|
||||
char *ic_path = NULL;
|
||||
SDL_DBusContext *dbus = client->dbus;
|
||||
|
||||
@@ -290,8 +273,6 @@ static bool FcitxClientCreateIC(FcitxClient *client)
|
||||
ic_path = NULL; // just in case.
|
||||
}
|
||||
|
||||
SDL_free(appname);
|
||||
|
||||
if (ic_path) {
|
||||
SDL_free(client->ic_path);
|
||||
client->ic_path = SDL_strdup(ic_path);
|
||||
|
||||
@@ -120,7 +120,7 @@ void SDL_IMMDevice_FreeDeviceHandle(SDL_AudioDevice *device)
|
||||
}
|
||||
}
|
||||
|
||||
static SDL_AudioDevice *SDL_IMMDevice_Add(const bool recording, const char *devname, WAVEFORMATEXTENSIBLE *fmt, LPCWSTR devid, GUID *dsoundguid)
|
||||
static SDL_AudioDevice *SDL_IMMDevice_Add(const bool recording, const char *devname, WAVEFORMATEXTENSIBLE *fmt, LPCWSTR devid, GUID *dsoundguid, SDL_AudioFormat force_format)
|
||||
{
|
||||
/* You can have multiple endpoints on a device that are mutually exclusive ("Speakers" vs "Line Out" or whatever).
|
||||
In a perfect world, things that are unplugged won't be in this collection. The only gotcha is probably for
|
||||
@@ -162,7 +162,7 @@ static SDL_AudioDevice *SDL_IMMDevice_Add(const bool recording, const char *devn
|
||||
SDL_zero(spec);
|
||||
spec.channels = (Uint8)fmt->Format.nChannels;
|
||||
spec.freq = fmt->Format.nSamplesPerSec;
|
||||
spec.format = SDL_WaveFormatExToSDLFormat((WAVEFORMATEX *)fmt);
|
||||
spec.format = (force_format != SDL_AUDIO_UNKNOWN) ? force_format : SDL_WaveFormatExToSDLFormat((WAVEFORMATEX *)fmt);
|
||||
|
||||
device = SDL_AddAudioDevice(recording, devname, &spec, handle);
|
||||
if (!device) {
|
||||
@@ -183,6 +183,7 @@ typedef struct SDLMMNotificationClient
|
||||
{
|
||||
const IMMNotificationClientVtbl *lpVtbl;
|
||||
SDL_AtomicInt refcount;
|
||||
SDL_AudioFormat force_format;
|
||||
} SDLMMNotificationClient;
|
||||
|
||||
static HRESULT STDMETHODCALLTYPE SDLMMNotificationClient_QueryInterface(IMMNotificationClient *client, REFIID iid, void **ppv)
|
||||
@@ -241,6 +242,7 @@ static HRESULT STDMETHODCALLTYPE SDLMMNotificationClient_OnDeviceRemoved(IMMNoti
|
||||
|
||||
static HRESULT STDMETHODCALLTYPE SDLMMNotificationClient_OnDeviceStateChanged(IMMNotificationClient *iclient, LPCWSTR pwstrDeviceId, DWORD dwNewState)
|
||||
{
|
||||
SDLMMNotificationClient *client = (SDLMMNotificationClient *)iclient;
|
||||
IMMDevice *device = NULL;
|
||||
|
||||
if (SUCCEEDED(IMMDeviceEnumerator_GetDevice(enumerator, pwstrDeviceId, &device))) {
|
||||
@@ -255,7 +257,7 @@ static HRESULT STDMETHODCALLTYPE SDLMMNotificationClient_OnDeviceStateChanged(IM
|
||||
GUID dsoundguid;
|
||||
GetMMDeviceInfo(device, &utf8dev, &fmt, &dsoundguid);
|
||||
if (utf8dev) {
|
||||
SDL_IMMDevice_Add(recording, utf8dev, &fmt, pwstrDeviceId, &dsoundguid);
|
||||
SDL_IMMDevice_Add(recording, utf8dev, &fmt, pwstrDeviceId, &dsoundguid, client->force_format);
|
||||
SDL_free(utf8dev);
|
||||
}
|
||||
} else {
|
||||
@@ -286,7 +288,7 @@ static const IMMNotificationClientVtbl notification_client_vtbl = {
|
||||
SDLMMNotificationClient_OnPropertyValueChanged
|
||||
};
|
||||
|
||||
static SDLMMNotificationClient notification_client = { ¬ification_client_vtbl, { 1 } };
|
||||
static SDLMMNotificationClient notification_client = { ¬ification_client_vtbl, { 1 }, SDL_AUDIO_UNKNOWN };
|
||||
|
||||
bool SDL_IMMDevice_Init(const SDL_IMMDevice_callbacks *callbacks)
|
||||
{
|
||||
@@ -363,7 +365,7 @@ bool SDL_IMMDevice_Get(SDL_AudioDevice *device, IMMDevice **immdevice, bool reco
|
||||
return true;
|
||||
}
|
||||
|
||||
static void EnumerateEndpointsForFlow(const bool recording, SDL_AudioDevice **default_device)
|
||||
static void EnumerateEndpointsForFlow(const bool recording, SDL_AudioDevice **default_device, SDL_AudioFormat force_format)
|
||||
{
|
||||
/* Note that WASAPI separates "adapter devices" from "audio endpoint devices"
|
||||
...one adapter device ("SoundBlaster Pro") might have multiple endpoint devices ("Speakers", "Line-Out"). */
|
||||
@@ -405,7 +407,7 @@ static void EnumerateEndpointsForFlow(const bool recording, SDL_AudioDevice **de
|
||||
SDL_zero(dsoundguid);
|
||||
GetMMDeviceInfo(immdevice, &devname, &fmt, &dsoundguid);
|
||||
if (devname) {
|
||||
SDL_AudioDevice *sdldevice = SDL_IMMDevice_Add(recording, devname, &fmt, devid, &dsoundguid);
|
||||
SDL_AudioDevice *sdldevice = SDL_IMMDevice_Add(recording, devname, &fmt, devid, &dsoundguid, force_format);
|
||||
if (default_device && default_devid && SDL_wcscmp(default_devid, devid) == 0) {
|
||||
*default_device = sdldevice;
|
||||
}
|
||||
@@ -422,10 +424,12 @@ static void EnumerateEndpointsForFlow(const bool recording, SDL_AudioDevice **de
|
||||
IMMDeviceCollection_Release(collection);
|
||||
}
|
||||
|
||||
void SDL_IMMDevice_EnumerateEndpoints(SDL_AudioDevice **default_playback, SDL_AudioDevice **default_recording)
|
||||
void SDL_IMMDevice_EnumerateEndpoints(SDL_AudioDevice **default_playback, SDL_AudioDevice **default_recording, SDL_AudioFormat force_format)
|
||||
{
|
||||
EnumerateEndpointsForFlow(false, default_playback);
|
||||
EnumerateEndpointsForFlow(true, default_recording);
|
||||
EnumerateEndpointsForFlow(false, default_playback, force_format);
|
||||
EnumerateEndpointsForFlow(true, default_recording, force_format);
|
||||
|
||||
notification_client.force_format = force_format;
|
||||
|
||||
// if this fails, we just won't get hotplug events. Carry on anyhow.
|
||||
IMMDeviceEnumerator_RegisterEndpointNotificationCallback(enumerator, (IMMNotificationClient *)¬ification_client);
|
||||
|
||||
@@ -37,7 +37,7 @@ typedef struct SDL_IMMDevice_callbacks
|
||||
bool SDL_IMMDevice_Init(const SDL_IMMDevice_callbacks *callbacks);
|
||||
void SDL_IMMDevice_Quit(void);
|
||||
bool SDL_IMMDevice_Get(struct SDL_AudioDevice *device, IMMDevice **immdevice, bool recording);
|
||||
void SDL_IMMDevice_EnumerateEndpoints(struct SDL_AudioDevice **default_playback, struct SDL_AudioDevice **default_recording);
|
||||
void SDL_IMMDevice_EnumerateEndpoints(struct SDL_AudioDevice **default_playback, struct SDL_AudioDevice **default_recording, SDL_AudioFormat force_format);
|
||||
LPGUID SDL_IMMDevice_GetDirectSoundGUID(struct SDL_AudioDevice *device);
|
||||
LPCWSTR SDL_IMMDevice_GetDevID(struct SDL_AudioDevice *device);
|
||||
void SDL_IMMDevice_FreeDeviceHandle(struct SDL_AudioDevice *device);
|
||||
|
||||
@@ -53,6 +53,78 @@ typedef enum RO_INIT_TYPE
|
||||
#define WC_ERR_INVALID_CHARS 0x00000080
|
||||
#endif
|
||||
|
||||
// Fake window to help with DirectInput events.
|
||||
HWND SDL_HelperWindow = NULL;
|
||||
static const TCHAR *SDL_HelperWindowClassName = TEXT("SDLHelperWindowInputCatcher");
|
||||
static const TCHAR *SDL_HelperWindowName = TEXT("SDLHelperWindowInputMsgWindow");
|
||||
static ATOM SDL_HelperWindowClass = 0;
|
||||
|
||||
/*
|
||||
* Creates a HelperWindow used for DirectInput.
|
||||
*/
|
||||
bool SDL_HelperWindowCreate(void)
|
||||
{
|
||||
HINSTANCE hInstance = GetModuleHandle(NULL);
|
||||
WNDCLASS wce;
|
||||
|
||||
// Make sure window isn't created twice.
|
||||
if (SDL_HelperWindow != NULL) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Create the class.
|
||||
SDL_zero(wce);
|
||||
wce.lpfnWndProc = DefWindowProc;
|
||||
wce.lpszClassName = SDL_HelperWindowClassName;
|
||||
wce.hInstance = hInstance;
|
||||
|
||||
// Register the class.
|
||||
SDL_HelperWindowClass = RegisterClass(&wce);
|
||||
if (SDL_HelperWindowClass == 0 && GetLastError() != ERROR_CLASS_ALREADY_EXISTS) {
|
||||
return WIN_SetError("Unable to create Helper Window Class");
|
||||
}
|
||||
|
||||
// Create the window.
|
||||
SDL_HelperWindow = CreateWindowEx(0, SDL_HelperWindowClassName,
|
||||
SDL_HelperWindowName,
|
||||
WS_OVERLAPPED, CW_USEDEFAULT,
|
||||
CW_USEDEFAULT, CW_USEDEFAULT,
|
||||
CW_USEDEFAULT, HWND_MESSAGE, NULL,
|
||||
hInstance, NULL);
|
||||
if (!SDL_HelperWindow) {
|
||||
UnregisterClass(SDL_HelperWindowClassName, hInstance);
|
||||
return WIN_SetError("Unable to create Helper Window");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Destroys the HelperWindow previously created with SDL_HelperWindowCreate.
|
||||
*/
|
||||
void SDL_HelperWindowDestroy(void)
|
||||
{
|
||||
HINSTANCE hInstance = GetModuleHandle(NULL);
|
||||
|
||||
// Destroy the window.
|
||||
if (SDL_HelperWindow != NULL) {
|
||||
if (DestroyWindow(SDL_HelperWindow) == 0) {
|
||||
WIN_SetError("Unable to destroy Helper Window");
|
||||
return;
|
||||
}
|
||||
SDL_HelperWindow = NULL;
|
||||
}
|
||||
|
||||
// Unregister the class.
|
||||
if (SDL_HelperWindowClass != 0) {
|
||||
if ((UnregisterClass(SDL_HelperWindowClassName, hInstance)) == 0) {
|
||||
WIN_SetError("Unable to destroy Helper Window Class");
|
||||
return;
|
||||
}
|
||||
SDL_HelperWindowClass = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Sets an error message based on an HRESULT
|
||||
bool WIN_SetErrorFromHRESULT(const char *prefix, HRESULT hr)
|
||||
{
|
||||
@@ -198,6 +270,24 @@ static BOOL IsWindowsVersionOrGreater(WORD wMajorVersion, WORD wMinorVersion, WO
|
||||
return result;
|
||||
#endif
|
||||
|
||||
BOOL WIN_IsWine(void)
|
||||
{
|
||||
static bool checked;
|
||||
static bool is_wine;
|
||||
|
||||
if (!checked) {
|
||||
HMODULE ntdll = LoadLibrary(TEXT("ntdll.dll"));
|
||||
if (ntdll) {
|
||||
if (GetProcAddress(ntdll, "wine_get_version") != NULL) {
|
||||
is_wine = true;
|
||||
}
|
||||
FreeLibrary(ntdll);
|
||||
}
|
||||
checked = true;
|
||||
}
|
||||
return is_wine;
|
||||
}
|
||||
|
||||
// this is the oldest thing we run on (and we may lose support for this in SDL3 at any time!),
|
||||
// so there's no "OrGreater" as that would always be TRUE. The other functions are here to
|
||||
// ask "can we support a specific feature?" but this function is here to ask "do we need to do
|
||||
|
||||
@@ -133,6 +133,9 @@ extern void WIN_CoUninitialize(void);
|
||||
extern HRESULT WIN_RoInitialize(void);
|
||||
extern void WIN_RoUninitialize(void);
|
||||
|
||||
// Returns true if we're running on Wine
|
||||
extern BOOL WIN_IsWine(void);
|
||||
|
||||
// Returns true if we're running on Windows XP (any service pack). DOES NOT CHECK XP "OR GREATER"!
|
||||
extern BOOL WIN_IsWindowsXP(void);
|
||||
|
||||
|
||||
@@ -9,8 +9,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 3,2,12,0
|
||||
PRODUCTVERSION 3,2,12,0
|
||||
FILEVERSION 3,2,28,0
|
||||
PRODUCTVERSION 3,2,28,0
|
||||
FILEFLAGSMASK 0x3fL
|
||||
FILEFLAGS 0x0L
|
||||
FILEOS 0x40004L
|
||||
@@ -23,12 +23,12 @@ BEGIN
|
||||
BEGIN
|
||||
VALUE "CompanyName", "\0"
|
||||
VALUE "FileDescription", "SDL\0"
|
||||
VALUE "FileVersion", "3, 2, 12, 0\0"
|
||||
VALUE "FileVersion", "3, 2, 28, 0\0"
|
||||
VALUE "InternalName", "SDL\0"
|
||||
VALUE "LegalCopyright", "Copyright (C) 2025 Sam Lantinga\0"
|
||||
VALUE "OriginalFilename", "SDL3.dll\0"
|
||||
VALUE "ProductName", "Simple DirectMedia Layer\0"
|
||||
VALUE "ProductVersion", "3, 2, 12, 0\0"
|
||||
VALUE "ProductVersion", "3, 2, 28, 0\0"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
|
||||
@@ -115,7 +115,11 @@
|
||||
#define CPU_CFG2_LSX (1 << 6)
|
||||
#define CPU_CFG2_LASX (1 << 7)
|
||||
|
||||
#if defined(SDL_ALTIVEC_BLITTERS) && defined(HAVE_SETJMP) && !defined(SDL_PLATFORM_MACOS) && !defined(SDL_PLATFORM_OPENBSD) && !defined(SDL_PLATFORM_FREEBSD)
|
||||
#if !defined(SDL_CPUINFO_DISABLED) && \
|
||||
!((defined(SDL_PLATFORM_MACOS) && (defined(__ppc__) || defined(__ppc64__))) || (defined(SDL_PLATFORM_OPENBSD) && defined(__powerpc__))) && \
|
||||
!(defined(SDL_PLATFORM_FREEBSD) && defined(__powerpc__)) && \
|
||||
!(defined(SDL_PLATFORM_LINUX) && defined(__powerpc__) && defined(HAVE_GETAUXVAL)) && \
|
||||
defined(SDL_ALTIVEC_BLITTERS) && defined(HAVE_SETJMP)
|
||||
/* This is the brute force way of detecting instruction sets...
|
||||
the idea is borrowed from the libmpeg2 library - thanks!
|
||||
*/
|
||||
@@ -344,6 +348,8 @@ static int CPU_haveAltiVec(void)
|
||||
elf_aux_info(AT_HWCAP, &cpufeatures, sizeof(cpufeatures));
|
||||
altivec = cpufeatures & PPC_FEATURE_HAS_ALTIVEC;
|
||||
return altivec;
|
||||
#elif defined(SDL_PLATFORM_LINUX) && defined(__powerpc__) && defined(HAVE_GETAUXVAL)
|
||||
altivec = getauxval(AT_HWCAP) & PPC_FEATURE_HAS_ALTIVEC;
|
||||
#elif defined(SDL_ALTIVEC_BLITTERS) && defined(HAVE_SETJMP)
|
||||
void (*handler)(int sig);
|
||||
handler = signal(SIGILL, illegal_instruction);
|
||||
|
||||
@@ -27,6 +27,8 @@
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#import <UniformTypeIdentifiers/UTType.h>
|
||||
|
||||
extern void Cocoa_SetWindowHasModalDialog(SDL_Window *window, bool has_modal);
|
||||
|
||||
static void AddFileExtensionType(NSMutableArray *types, const char *pattern_ptr)
|
||||
{
|
||||
if (!*pattern_ptr) {
|
||||
@@ -163,6 +165,9 @@ void SDL_SYS_ShowFileDialogWithProperties(SDL_FileDialogType type, SDL_DialogFil
|
||||
|
||||
if (window) {
|
||||
w = (__bridge NSWindow *)SDL_GetPointerProperty(SDL_GetWindowProperties(window), SDL_PROP_WINDOW_COCOA_WINDOW_POINTER, NULL);
|
||||
if (w) {
|
||||
Cocoa_SetWindowHasModalDialog(window, true);
|
||||
}
|
||||
}
|
||||
|
||||
if (w) {
|
||||
@@ -186,6 +191,7 @@ void SDL_SYS_ShowFileDialogWithProperties(SDL_FileDialogType type, SDL_DialogFil
|
||||
callback(userdata, files, -1);
|
||||
}
|
||||
|
||||
Cocoa_SetWindowHasModalDialog(window, false);
|
||||
ReactivateAfterDialog();
|
||||
}];
|
||||
} else {
|
||||
@@ -206,6 +212,7 @@ void SDL_SYS_ShowFileDialogWithProperties(SDL_FileDialogType type, SDL_DialogFil
|
||||
const char *files[1] = { NULL };
|
||||
callback(userdata, files, -1);
|
||||
}
|
||||
|
||||
ReactivateAfterDialog();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -261,7 +261,7 @@ void windows_ShowFileDialog(void *ptr)
|
||||
|
||||
chosen_files_list[nfiles] = NULL;
|
||||
|
||||
if (WideCharToMultiByte(CP_UTF8, 0, file_ptr, -1, chosen_folder, MAX_PATH, NULL, NULL) >= MAX_PATH) {
|
||||
if (WideCharToMultiByte(CP_UTF8, 0, file_ptr, -1, chosen_folder, MAX_PATH, NULL, NULL) == 0) {
|
||||
SDL_SetError("Path too long or invalid character in path");
|
||||
SDL_free(chosen_files_list);
|
||||
callback(userdata, NULL, -1);
|
||||
@@ -273,7 +273,7 @@ void windows_ShowFileDialog(void *ptr)
|
||||
SDL_strlcpy(chosen_file, chosen_folder, MAX_PATH);
|
||||
chosen_file[chosen_folder_size] = '\\';
|
||||
|
||||
file_ptr += SDL_strlen(chosen_folder) + 1;
|
||||
file_ptr += SDL_wcslen(file_ptr) + 1;
|
||||
|
||||
while (*file_ptr) {
|
||||
nfiles++;
|
||||
@@ -295,7 +295,7 @@ void windows_ShowFileDialog(void *ptr)
|
||||
|
||||
int diff = ((int) chosen_folder_size) + 1;
|
||||
|
||||
if (WideCharToMultiByte(CP_UTF8, 0, file_ptr, -1, chosen_file + diff, MAX_PATH - diff, NULL, NULL) >= MAX_PATH - diff) {
|
||||
if (WideCharToMultiByte(CP_UTF8, 0, file_ptr, -1, chosen_file + diff, MAX_PATH - diff, NULL, NULL) == 0) {
|
||||
SDL_SetError("Path too long or invalid character in path");
|
||||
|
||||
for (size_t i = 0; i < nfiles - 1; i++) {
|
||||
@@ -308,7 +308,7 @@ void windows_ShowFileDialog(void *ptr)
|
||||
return;
|
||||
}
|
||||
|
||||
file_ptr += SDL_strlen(chosen_file) + 1 - diff;
|
||||
file_ptr += SDL_wcslen(file_ptr) + 1;
|
||||
|
||||
chosen_files_list[nfiles - 1] = SDL_strdup(chosen_file);
|
||||
|
||||
|
||||
+11
-26
@@ -1077,16 +1077,11 @@ static void SDL_SendWakeupEvent(void)
|
||||
return;
|
||||
}
|
||||
|
||||
SDL_LockMutex(_this->wakeup_lock);
|
||||
{
|
||||
if (_this->wakeup_window) {
|
||||
_this->SendWakeupEvent(_this, _this->wakeup_window);
|
||||
|
||||
// No more wakeup events needed until we enter a new wait
|
||||
_this->wakeup_window = NULL;
|
||||
}
|
||||
// We only want to do this once while waiting for an event, so set it to NULL atomically here
|
||||
SDL_Window *wakeup_window = (SDL_Window *)SDL_SetAtomicPointer(&_this->wakeup_window, NULL);
|
||||
if (wakeup_window) {
|
||||
_this->SendWakeupEvent(_this, wakeup_window);
|
||||
}
|
||||
SDL_UnlockMutex(_this->wakeup_lock);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -1113,7 +1108,8 @@ static int SDL_PeepEventsInternal(SDL_Event *events, int numevents, SDL_EventAct
|
||||
if (action == SDL_ADDEVENT) {
|
||||
if (!events) {
|
||||
SDL_UnlockMutex(SDL_EventQ.lock);
|
||||
return SDL_InvalidParamError("events");
|
||||
SDL_InvalidParamError("events");
|
||||
return -1;
|
||||
}
|
||||
for (i = 0; i < numevents; ++i) {
|
||||
used += SDL_AddEvent(&events[i]);
|
||||
@@ -1524,18 +1520,7 @@ static int SDL_WaitEventTimeout_Device(SDL_VideoDevice *_this, SDL_Window *wakeu
|
||||
*/
|
||||
SDL_PumpEventsInternal(true);
|
||||
|
||||
SDL_LockMutex(_this->wakeup_lock);
|
||||
{
|
||||
status = SDL_PeepEvents(event, 1, SDL_GETEVENT, SDL_EVENT_FIRST, SDL_EVENT_LAST);
|
||||
// If status == 0 we are going to block so wakeup will be needed.
|
||||
if (status == 0) {
|
||||
_this->wakeup_window = wakeup_window;
|
||||
} else {
|
||||
_this->wakeup_window = NULL;
|
||||
}
|
||||
}
|
||||
SDL_UnlockMutex(_this->wakeup_lock);
|
||||
|
||||
status = SDL_PeepEvents(event, 1, SDL_GETEVENT, SDL_EVENT_FIRST, SDL_EVENT_LAST);
|
||||
if (status < 0) {
|
||||
// Got an error: return
|
||||
break;
|
||||
@@ -1548,8 +1533,6 @@ static int SDL_WaitEventTimeout_Device(SDL_VideoDevice *_this, SDL_Window *wakeu
|
||||
if (timeoutNS > 0) {
|
||||
Sint64 elapsed = SDL_GetTicksNS() - start;
|
||||
if (elapsed >= timeoutNS) {
|
||||
// Set wakeup_window to NULL without holding the lock.
|
||||
_this->wakeup_window = NULL;
|
||||
return 0;
|
||||
}
|
||||
loop_timeoutNS = (timeoutNS - elapsed);
|
||||
@@ -1562,9 +1545,9 @@ static int SDL_WaitEventTimeout_Device(SDL_VideoDevice *_this, SDL_Window *wakeu
|
||||
loop_timeoutNS = poll_intervalNS;
|
||||
}
|
||||
}
|
||||
SDL_SetAtomicPointer(&_this->wakeup_window, wakeup_window);
|
||||
status = _this->WaitEventTimeout(_this, loop_timeoutNS);
|
||||
// Set wakeup_window to NULL without holding the lock.
|
||||
_this->wakeup_window = NULL;
|
||||
SDL_SetAtomicPointer(&_this->wakeup_window, NULL);
|
||||
if (status == 0 && poll_intervalNS != SDL_MAX_SINT64 && loop_timeoutNS == poll_intervalNS) {
|
||||
// We may have woken up to poll. Try again
|
||||
continue;
|
||||
@@ -1664,6 +1647,8 @@ bool SDL_WaitEventTimeoutNS(SDL_Event *event, Sint64 timeoutNS)
|
||||
|
||||
#ifdef SDL_PLATFORM_ANDROID
|
||||
for (;;) {
|
||||
SDL_PumpEventsInternal(true);
|
||||
|
||||
if (SDL_PeepEvents(event, 1, SDL_GETEVENT, SDL_EVENT_FIRST, SDL_EVENT_LAST) > 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
+12
-12
@@ -333,6 +333,18 @@ bool SDL_SetKeyboardFocus(SDL_Window *window)
|
||||
}
|
||||
}
|
||||
|
||||
// See if the current window has lost focus
|
||||
if (keyboard->focus && keyboard->focus != window) {
|
||||
SDL_SendWindowEvent(keyboard->focus, SDL_EVENT_WINDOW_FOCUS_LOST, 0, 0);
|
||||
|
||||
// Ensures IME compositions are committed
|
||||
if (SDL_TextInputActive(keyboard->focus)) {
|
||||
if (video && video->StopTextInput) {
|
||||
video->StopTextInput(video, keyboard->focus);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (keyboard->focus && !window) {
|
||||
// We won't get anymore keyboard messages, so reset keyboard state
|
||||
SDL_ResetKeyboard();
|
||||
@@ -351,18 +363,6 @@ bool SDL_SetKeyboardFocus(SDL_Window *window)
|
||||
}
|
||||
}
|
||||
|
||||
// See if the current window has lost focus
|
||||
if (keyboard->focus && keyboard->focus != window) {
|
||||
SDL_SendWindowEvent(keyboard->focus, SDL_EVENT_WINDOW_FOCUS_LOST, 0, 0);
|
||||
|
||||
// Ensures IME compositions are committed
|
||||
if (SDL_TextInputActive(keyboard->focus)) {
|
||||
if (video && video->StopTextInput) {
|
||||
video->StopTextInput(video, keyboard->focus);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
keyboard->focus = window;
|
||||
|
||||
if (keyboard->focus) {
|
||||
|
||||
@@ -138,21 +138,25 @@ static void SDLCALL SDL_TouchMouseEventsChanged(void *userdata, const char *name
|
||||
#ifdef SDL_PLATFORM_VITA
|
||||
static void SDLCALL SDL_VitaTouchMouseDeviceChanged(void *userdata, const char *name, const char *oldValue, const char *hint)
|
||||
{
|
||||
Uint8 vita_touch_mouse_device = 1;
|
||||
|
||||
SDL_Mouse *mouse = (SDL_Mouse *)userdata;
|
||||
if (hint) {
|
||||
switch (*hint) {
|
||||
default:
|
||||
case '0':
|
||||
mouse->vita_touch_mouse_device = 1;
|
||||
vita_touch_mouse_device = 1;
|
||||
break;
|
||||
case '1':
|
||||
mouse->vita_touch_mouse_device = 2;
|
||||
vita_touch_mouse_device = 2;
|
||||
break;
|
||||
case '2':
|
||||
mouse->vita_touch_mouse_device = 3;
|
||||
vita_touch_mouse_device = 3;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
mouse->vita_touch_mouse_device = vita_touch_mouse_device;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -46,8 +46,10 @@ static bool send_foregrounding_pending = false;
|
||||
|
||||
static void SDL_HandleSIG(int sig)
|
||||
{
|
||||
// Reset the signal handler
|
||||
#ifndef HAVE_SIGACTION
|
||||
// Reset the signal handler if it was installed with signal()
|
||||
(void)signal(sig, SDL_HandleSIG);
|
||||
#endif
|
||||
|
||||
// Send a quit event next time the event loop pumps.
|
||||
// We can't send it in signal handler; SDL_malloc() might be interrupted!
|
||||
|
||||
@@ -77,9 +77,6 @@ bool SDL_SendWindowEvent(SDL_Window *window, SDL_EventType windowevent, int data
|
||||
}
|
||||
SDL_assert(SDL_ObjectValid(window, SDL_OBJECT_TYPE_WINDOW));
|
||||
|
||||
if (window->is_destroying && windowevent != SDL_EVENT_WINDOW_DESTROYED) {
|
||||
return false;
|
||||
}
|
||||
switch (windowevent) {
|
||||
case SDL_EVENT_WINDOW_SHOWN:
|
||||
if (!(window->flags & SDL_WINDOW_HIDDEN)) {
|
||||
@@ -212,6 +209,10 @@ bool SDL_SendWindowEvent(SDL_Window *window, SDL_EventType windowevent, int data
|
||||
break;
|
||||
}
|
||||
|
||||
if (window->is_destroying && windowevent != SDL_EVENT_WINDOW_DESTROYED) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Post the event, if desired
|
||||
SDL_Event event;
|
||||
event.type = windowevent;
|
||||
|
||||
@@ -371,10 +371,10 @@ static const SDL_Scancode xfree86_scancode_table2[] = {
|
||||
/* 188, 0x0bc */ SDL_SCANCODE_F18, // XF86Launch9
|
||||
/* 189, 0x0bd */ SDL_SCANCODE_F19, // NoSymbol
|
||||
/* 190, 0x0be */ SDL_SCANCODE_F20, // XF86AudioMicMute
|
||||
/* 191, 0x0bf */ SDL_SCANCODE_UNKNOWN, // XF86TouchpadToggle
|
||||
/* 192, 0x0c0 */ SDL_SCANCODE_UNKNOWN, // XF86TouchpadOn
|
||||
/* 193, 0x0c1 */ SDL_SCANCODE_UNKNOWN, // XF86TouchpadOff
|
||||
/* 194, 0x0c2 */ SDL_SCANCODE_UNKNOWN, // NoSymbol
|
||||
/* 191, 0x0bf */ SDL_SCANCODE_F21, // XF86TouchpadToggle
|
||||
/* 192, 0x0c0 */ SDL_SCANCODE_F22, // XF86TouchpadOn
|
||||
/* 193, 0x0c1 */ SDL_SCANCODE_F23, // XF86TouchpadOff
|
||||
/* 194, 0x0c2 */ SDL_SCANCODE_F24, // NoSymbol
|
||||
/* 195, 0x0c3 */ SDL_SCANCODE_MODE, // Mode_switch
|
||||
/* 196, 0x0c4 */ SDL_SCANCODE_UNKNOWN, // NoSymbol
|
||||
/* 197, 0x0c5 */ SDL_SCANCODE_UNKNOWN, // NoSymbol
|
||||
|
||||
@@ -78,7 +78,7 @@ static char *search_path_for_binary(const char *bin)
|
||||
char *envr;
|
||||
size_t alloc_size;
|
||||
char *exe = NULL;
|
||||
char *start = envr;
|
||||
char *start;
|
||||
char *ptr;
|
||||
|
||||
if (!envr_real) {
|
||||
@@ -86,7 +86,7 @@ static char *search_path_for_binary(const char *bin)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
envr = SDL_strdup(envr_real);
|
||||
start = envr = SDL_strdup(envr_real);
|
||||
if (!envr) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
+388
-46
@@ -61,6 +61,10 @@
|
||||
return; \
|
||||
}
|
||||
|
||||
#if 0
|
||||
// The below validation is too aggressive, since there are advanced situations
|
||||
// where this is legal. This is being temporarily disabled for further review.
|
||||
// See: https://github.com/libsdl-org/SDL/issues/13871
|
||||
#define CHECK_SAMPLER_TEXTURES \
|
||||
RenderPass *rp = (RenderPass *)render_pass; \
|
||||
for (Uint32 color_target_index = 0; color_target_index < rp->num_color_targets; color_target_index += 1) { \
|
||||
@@ -92,11 +96,15 @@
|
||||
SDL_assert_release(!"Texture cannot be simultaneously bound as a depth stencil target and a storage texture!"); \
|
||||
} \
|
||||
}
|
||||
#else
|
||||
#define CHECK_SAMPLER_TEXTURES
|
||||
#define CHECK_STORAGE_TEXTURES
|
||||
#endif
|
||||
|
||||
#define CHECK_GRAPHICS_PIPELINE_BOUND \
|
||||
if (!((CommandBufferCommonHeader *)RENDERPASS_COMMAND_BUFFER)->graphics_pipeline_bound) { \
|
||||
SDL_assert_release(!"Graphics pipeline not bound!"); \
|
||||
return; \
|
||||
#define CHECK_GRAPHICS_PIPELINE_BOUND \
|
||||
if (!((RenderPass *)render_pass)->graphics_pipeline) { \
|
||||
SDL_assert_release(!"Graphics pipeline not bound!"); \
|
||||
return; \
|
||||
}
|
||||
|
||||
#define CHECK_COMPUTEPASS \
|
||||
@@ -106,7 +114,7 @@
|
||||
}
|
||||
|
||||
#define CHECK_COMPUTE_PIPELINE_BOUND \
|
||||
if (!((CommandBufferCommonHeader *)COMPUTEPASS_COMMAND_BUFFER)->compute_pipeline_bound) { \
|
||||
if (!((ComputePass *)compute_pass)->compute_pipeline) { \
|
||||
SDL_assert_release(!"Compute pipeline not bound!"); \
|
||||
return; \
|
||||
}
|
||||
@@ -174,18 +182,132 @@
|
||||
#define RENDERPASS_DEVICE \
|
||||
((CommandBufferCommonHeader *)RENDERPASS_COMMAND_BUFFER)->device
|
||||
|
||||
#define RENDERPASS_BOUND_PIPELINE \
|
||||
((RenderPass *)render_pass)->graphics_pipeline
|
||||
|
||||
#define COMPUTEPASS_COMMAND_BUFFER \
|
||||
((Pass *)compute_pass)->command_buffer
|
||||
|
||||
#define COMPUTEPASS_DEVICE \
|
||||
((CommandBufferCommonHeader *)COMPUTEPASS_COMMAND_BUFFER)->device
|
||||
|
||||
#define COMPUTEPASS_BOUND_PIPELINE \
|
||||
((ComputePass *)compute_pass)->compute_pipeline
|
||||
|
||||
#define COPYPASS_COMMAND_BUFFER \
|
||||
((Pass *)copy_pass)->command_buffer
|
||||
|
||||
#define COPYPASS_DEVICE \
|
||||
((CommandBufferCommonHeader *)COPYPASS_COMMAND_BUFFER)->device
|
||||
|
||||
static bool TextureFormatIsComputeWritable[] = {
|
||||
false, // INVALID
|
||||
false, // A8_UNORM
|
||||
true, // R8_UNORM
|
||||
true, // R8G8_UNORM
|
||||
true, // R8G8B8A8_UNORM
|
||||
true, // R16_UNORM
|
||||
true, // R16G16_UNORM
|
||||
true, // R16G16B16A16_UNORM
|
||||
true, // R10G10B10A2_UNORM
|
||||
false, // B5G6R5_UNORM
|
||||
false, // B5G5R5A1_UNORM
|
||||
false, // B4G4R4A4_UNORM
|
||||
false, // B8G8R8A8_UNORM
|
||||
false, // BC1_UNORM
|
||||
false, // BC2_UNORM
|
||||
false, // BC3_UNORM
|
||||
false, // BC4_UNORM
|
||||
false, // BC5_UNORM
|
||||
false, // BC7_UNORM
|
||||
false, // BC6H_FLOAT
|
||||
false, // BC6H_UFLOAT
|
||||
true, // R8_SNORM
|
||||
true, // R8G8_SNORM
|
||||
true, // R8G8B8A8_SNORM
|
||||
true, // R16_SNORM
|
||||
true, // R16G16_SNORM
|
||||
true, // R16G16B16A16_SNORM
|
||||
true, // R16_FLOAT
|
||||
true, // R16G16_FLOAT
|
||||
true, // R16G16B16A16_FLOAT
|
||||
true, // R32_FLOAT
|
||||
true, // R32G32_FLOAT
|
||||
true, // R32G32B32A32_FLOAT
|
||||
true, // R11G11B10_UFLOAT
|
||||
true, // R8_UINT
|
||||
true, // R8G8_UINT
|
||||
true, // R8G8B8A8_UINT
|
||||
true, // R16_UINT
|
||||
true, // R16G16_UINT
|
||||
true, // R16G16B16A16_UINT
|
||||
true, // R32_UINT
|
||||
true, // R32G32_UINT
|
||||
true, // R32G32B32A32_UINT
|
||||
true, // R8_INT
|
||||
true, // R8G8_INT
|
||||
true, // R8G8B8A8_INT
|
||||
true, // R16_INT
|
||||
true, // R16G16_INT
|
||||
true, // R16G16B16A16_INT
|
||||
true, // R32_INT
|
||||
true, // R32G32_INT
|
||||
true, // R32G32B32A32_INT
|
||||
false, // R8G8B8A8_UNORM_SRGB
|
||||
false, // B8G8R8A8_UNORM_SRGB
|
||||
false, // BC1_UNORM_SRGB
|
||||
false, // BC3_UNORM_SRGB
|
||||
false, // BC3_UNORM_SRGB
|
||||
false, // BC7_UNORM_SRGB
|
||||
false, // D16_UNORM
|
||||
false, // D24_UNORM
|
||||
false, // D32_FLOAT
|
||||
false, // D24_UNORM_S8_UINT
|
||||
false, // D32_FLOAT_S8_UINT
|
||||
false, // ASTC_4x4_UNORM
|
||||
false, // ASTC_5x4_UNORM
|
||||
false, // ASTC_5x5_UNORM
|
||||
false, // ASTC_6x5_UNORM
|
||||
false, // ASTC_6x6_UNORM
|
||||
false, // ASTC_8x5_UNORM
|
||||
false, // ASTC_8x6_UNORM
|
||||
false, // ASTC_8x8_UNORM
|
||||
false, // ASTC_10x5_UNORM
|
||||
false, // ASTC_10x6_UNORM
|
||||
false, // ASTC_10x8_UNORM
|
||||
false, // ASTC_10x10_UNORM
|
||||
false, // ASTC_12x10_UNORM
|
||||
false, // ASTC_12x12_UNORM
|
||||
false, // ASTC_4x4_UNORM_SRGB
|
||||
false, // ASTC_5x4_UNORM_SRGB
|
||||
false, // ASTC_5x5_UNORM_SRGB
|
||||
false, // ASTC_6x5_UNORM_SRGB
|
||||
false, // ASTC_6x6_UNORM_SRGB
|
||||
false, // ASTC_8x5_UNORM_SRGB
|
||||
false, // ASTC_8x6_UNORM_SRGB
|
||||
false, // ASTC_8x8_UNORM_SRGB
|
||||
false, // ASTC_10x5_UNORM_SRGB
|
||||
false, // ASTC_10x6_UNORM_SRGB
|
||||
false, // ASTC_10x8_UNORM_SRGB
|
||||
false, // ASTC_10x10_UNORM_SRGB
|
||||
false, // ASTC_12x10_UNORM_SRGB
|
||||
false, // ASTC_12x12_UNORM_SRGB
|
||||
false, // ASTC_4x4_FLOAT
|
||||
false, // ASTC_5x4_FLOAT
|
||||
false, // ASTC_5x5_FLOAT
|
||||
false, // ASTC_6x5_FLOAT
|
||||
false, // ASTC_6x6_FLOAT
|
||||
false, // ASTC_8x5_FLOAT
|
||||
false, // ASTC_8x6_FLOAT
|
||||
false, // ASTC_8x8_FLOAT
|
||||
false, // ASTC_10x5_FLOAT
|
||||
false, // ASTC_10x6_FLOAT
|
||||
false, // ASTC_10x8_FLOAT
|
||||
false, // ASTC_10x10_FLOAT
|
||||
false, // ASTC_12x10_FLOAT
|
||||
false // ASTC_12x12_FLOAT
|
||||
};
|
||||
|
||||
// Drivers
|
||||
|
||||
#ifndef SDL_GPU_DISABLED
|
||||
@@ -403,6 +525,73 @@ void SDL_GPU_BlitCommon(
|
||||
SDL_EndGPURenderPass(render_pass);
|
||||
}
|
||||
|
||||
static void SDL_GPU_CheckGraphicsBindings(SDL_GPURenderPass *render_pass)
|
||||
{
|
||||
RenderPass *rp = (RenderPass *)render_pass;
|
||||
GraphicsPipelineCommonHeader *pipeline = (GraphicsPipelineCommonHeader *)RENDERPASS_BOUND_PIPELINE;
|
||||
for (Uint32 i = 0; i < pipeline->num_vertex_samplers; i += 1) {
|
||||
if (!rp->vertex_sampler_bound[i]) {
|
||||
SDL_assert_release(!"Missing vertex sampler binding!");
|
||||
}
|
||||
}
|
||||
for (Uint32 i = 0; i < pipeline->num_vertex_storage_textures; i += 1) {
|
||||
if (!rp->vertex_storage_texture_bound[i]) {
|
||||
SDL_assert_release(!"Missing vertex storage texture binding!");
|
||||
}
|
||||
}
|
||||
for (Uint32 i = 0; i < pipeline->num_vertex_storage_buffers; i += 1) {
|
||||
if (!rp->vertex_storage_buffer_bound[i]) {
|
||||
SDL_assert_release(!"Missing vertex storage buffer binding!");
|
||||
}
|
||||
}
|
||||
for (Uint32 i = 0; i < pipeline->num_fragment_samplers; i += 1) {
|
||||
if (!rp->fragment_sampler_bound[i]) {
|
||||
SDL_assert_release(!"Missing fragment sampler binding!");
|
||||
}
|
||||
}
|
||||
for (Uint32 i = 0; i < pipeline->num_fragment_storage_textures; i += 1) {
|
||||
if (!rp->fragment_storage_texture_bound[i]) {
|
||||
SDL_assert_release(!"Missing fragment storage texture binding!");
|
||||
}
|
||||
}
|
||||
for (Uint32 i = 0; i < pipeline->num_fragment_storage_buffers; i += 1) {
|
||||
if (!rp->fragment_storage_buffer_bound[i]) {
|
||||
SDL_assert_release(!"Missing fragment storage buffer binding!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void SDL_GPU_CheckComputeBindings(SDL_GPUComputePass *compute_pass)
|
||||
{
|
||||
ComputePass *cp = (ComputePass *)compute_pass;
|
||||
ComputePipelineCommonHeader *pipeline = (ComputePipelineCommonHeader *)COMPUTEPASS_BOUND_PIPELINE;
|
||||
for (Uint32 i = 0; i < pipeline->numSamplers; i += 1) {
|
||||
if (!cp->sampler_bound[i]) {
|
||||
SDL_assert_release(!"Missing compute sampler binding!");
|
||||
}
|
||||
}
|
||||
for (Uint32 i = 0; i < pipeline->numReadonlyStorageTextures; i += 1) {
|
||||
if (!cp->read_only_storage_texture_bound[i]) {
|
||||
SDL_assert_release(!"Missing compute readonly storage texture binding!");
|
||||
}
|
||||
}
|
||||
for (Uint32 i = 0; i < pipeline->numReadonlyStorageBuffers; i += 1) {
|
||||
if (!cp->read_only_storage_buffer_bound[i]) {
|
||||
SDL_assert_release(!"Missing compute readonly storage buffer binding!");
|
||||
}
|
||||
}
|
||||
for (Uint32 i = 0; i < pipeline->numReadWriteStorageTextures; i += 1) {
|
||||
if (!cp->read_write_storage_texture_bound[i]) {
|
||||
SDL_assert_release(!"Missing compute read-write storage texture binding!");
|
||||
}
|
||||
}
|
||||
for (Uint32 i = 0; i < pipeline->numReadWriteStorageBuffers; i += 1) {
|
||||
if (!cp->read_write_storage_buffer_bound[i]) {
|
||||
SDL_assert_release(!"Missing compute read-write storage buffer bbinding!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Driver Functions
|
||||
|
||||
#ifndef SDL_GPU_DISABLED
|
||||
@@ -564,7 +753,6 @@ SDL_GPUDevice *SDL_CreateGPUDeviceWithProperties(SDL_PropertiesID props)
|
||||
result = selectedBackend->CreateDevice(debug_mode, preferLowPower, props);
|
||||
if (result != NULL) {
|
||||
result->backend = selectedBackend->name;
|
||||
result->shader_formats = selectedBackend->shader_formats;
|
||||
result->debug_mode = debug_mode;
|
||||
}
|
||||
}
|
||||
@@ -753,6 +941,13 @@ bool SDL_GPUTextureSupportsFormat(
|
||||
CHECK_TEXTUREFORMAT_ENUM_INVALID(format, false)
|
||||
}
|
||||
|
||||
if ((usage & SDL_GPU_TEXTUREUSAGE_COMPUTE_STORAGE_WRITE) ||
|
||||
(usage & SDL_GPU_TEXTUREUSAGE_COMPUTE_STORAGE_SIMULTANEOUS_READ_WRITE)) {
|
||||
if (!TextureFormatIsComputeWritable[format]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return device->SupportsTextureFormat(
|
||||
device->driverData,
|
||||
format,
|
||||
@@ -1125,6 +1320,12 @@ SDL_GPUBuffer *SDL_CreateGPUBuffer(
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (device->debug_mode) {
|
||||
if (createinfo->size < 4) {
|
||||
SDL_assert_release(!"Cannot create a buffer with size less than 4 bytes!");
|
||||
}
|
||||
}
|
||||
|
||||
const char *debugName = SDL_GetStringProperty(createinfo->props, SDL_PROP_GPU_BUFFER_CREATE_NAME_STRING, NULL);
|
||||
|
||||
return device->CreateBuffer(
|
||||
@@ -1375,15 +1576,30 @@ SDL_GPUCommandBuffer *SDL_AcquireGPUCommandBuffer(
|
||||
commandBufferHeader = (CommandBufferCommonHeader *)command_buffer;
|
||||
commandBufferHeader->device = device;
|
||||
commandBufferHeader->render_pass.command_buffer = command_buffer;
|
||||
commandBufferHeader->render_pass.in_progress = false;
|
||||
commandBufferHeader->graphics_pipeline_bound = false;
|
||||
commandBufferHeader->compute_pass.command_buffer = command_buffer;
|
||||
commandBufferHeader->compute_pass.in_progress = false;
|
||||
commandBufferHeader->compute_pipeline_bound = false;
|
||||
commandBufferHeader->copy_pass.command_buffer = command_buffer;
|
||||
commandBufferHeader->copy_pass.in_progress = false;
|
||||
commandBufferHeader->swapchain_texture_acquired = false;
|
||||
commandBufferHeader->submitted = false;
|
||||
|
||||
if (device->debug_mode) {
|
||||
commandBufferHeader->render_pass.in_progress = false;
|
||||
commandBufferHeader->render_pass.graphics_pipeline = NULL;
|
||||
commandBufferHeader->compute_pass.in_progress = false;
|
||||
commandBufferHeader->compute_pass.compute_pipeline = NULL;
|
||||
commandBufferHeader->copy_pass.in_progress = false;
|
||||
commandBufferHeader->swapchain_texture_acquired = false;
|
||||
commandBufferHeader->submitted = false;
|
||||
commandBufferHeader->ignore_render_pass_texture_validation = false;
|
||||
SDL_zeroa(commandBufferHeader->render_pass.vertex_sampler_bound);
|
||||
SDL_zeroa(commandBufferHeader->render_pass.vertex_storage_texture_bound);
|
||||
SDL_zeroa(commandBufferHeader->render_pass.vertex_storage_buffer_bound);
|
||||
SDL_zeroa(commandBufferHeader->render_pass.fragment_sampler_bound);
|
||||
SDL_zeroa(commandBufferHeader->render_pass.fragment_storage_texture_bound);
|
||||
SDL_zeroa(commandBufferHeader->render_pass.fragment_storage_buffer_bound);
|
||||
SDL_zeroa(commandBufferHeader->compute_pass.sampler_bound);
|
||||
SDL_zeroa(commandBufferHeader->compute_pass.read_only_storage_texture_bound);
|
||||
SDL_zeroa(commandBufferHeader->compute_pass.read_only_storage_buffer_bound);
|
||||
SDL_zeroa(commandBufferHeader->compute_pass.read_write_storage_texture_bound);
|
||||
SDL_zeroa(commandBufferHeader->compute_pass.read_write_storage_buffer_bound);
|
||||
}
|
||||
|
||||
return command_buffer;
|
||||
}
|
||||
@@ -1501,30 +1717,47 @@ SDL_GPURenderPass *SDL_BeginGPURenderPass(
|
||||
|
||||
if (color_target_infos[i].cycle && color_target_infos[i].load_op == SDL_GPU_LOADOP_LOAD) {
|
||||
SDL_assert_release(!"Cannot cycle color target when load op is LOAD!");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (color_target_infos[i].store_op == SDL_GPU_STOREOP_RESOLVE || color_target_infos[i].store_op == SDL_GPU_STOREOP_RESOLVE_AND_STORE) {
|
||||
if (color_target_infos[i].resolve_texture == NULL) {
|
||||
SDL_assert_release(!"Store op is RESOLVE or RESOLVE_AND_STORE but resolve_texture is NULL!");
|
||||
return NULL;
|
||||
} else {
|
||||
TextureCommonHeader *resolveTextureHeader = (TextureCommonHeader *)color_target_infos[i].resolve_texture;
|
||||
if (textureHeader->info.sample_count == SDL_GPU_SAMPLECOUNT_1) {
|
||||
SDL_assert_release(!"Store op is RESOLVE or RESOLVE_AND_STORE but texture is not multisample!");
|
||||
return NULL;
|
||||
}
|
||||
if (resolveTextureHeader->info.sample_count != SDL_GPU_SAMPLECOUNT_1) {
|
||||
SDL_assert_release(!"Resolve texture must have a sample count of 1!");
|
||||
return NULL;
|
||||
}
|
||||
if (resolveTextureHeader->info.format != textureHeader->info.format) {
|
||||
SDL_assert_release(!"Resolve texture must have the same format as its corresponding color target!");
|
||||
return NULL;
|
||||
}
|
||||
if (resolveTextureHeader->info.type == SDL_GPU_TEXTURETYPE_3D) {
|
||||
SDL_assert_release(!"Resolve texture must not be of TEXTURETYPE_3D!");
|
||||
return NULL;
|
||||
}
|
||||
if (!(resolveTextureHeader->info.usage & SDL_GPU_TEXTUREUSAGE_COLOR_TARGET)) {
|
||||
SDL_assert_release(!"Resolve texture usage must include COLOR_TARGET!");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (color_target_infos[i].layer_or_depth_plane >= textureHeader->info.layer_count_or_depth) {
|
||||
SDL_assert_release(!"Color target layer index must be less than the texture's layer count!");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (color_target_infos[i].mip_level >= textureHeader->info.num_levels) {
|
||||
SDL_assert_release(!"Color target mip level must be less than the texture's level count!");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (depth_stencil_target_info != NULL) {
|
||||
@@ -1532,10 +1765,12 @@ SDL_GPURenderPass *SDL_BeginGPURenderPass(
|
||||
TextureCommonHeader *textureHeader = (TextureCommonHeader *)depth_stencil_target_info->texture;
|
||||
if (!(textureHeader->info.usage & SDL_GPU_TEXTUREUSAGE_DEPTH_STENCIL_TARGET)) {
|
||||
SDL_assert_release(!"Depth target must have been created with the DEPTH_STENCIL_TARGET usage flag!");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (depth_stencil_target_info->cycle && (depth_stencil_target_info->load_op == SDL_GPU_LOADOP_LOAD || depth_stencil_target_info->stencil_load_op == SDL_GPU_LOADOP_LOAD)) {
|
||||
SDL_assert_release(!"Cannot cycle depth target when load op or stencil load op is LOAD!");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (depth_stencil_target_info->store_op == SDL_GPU_STOREOP_RESOLVE ||
|
||||
@@ -1543,6 +1778,7 @@ SDL_GPURenderPass *SDL_BeginGPURenderPass(
|
||||
depth_stencil_target_info->store_op == SDL_GPU_STOREOP_RESOLVE_AND_STORE ||
|
||||
depth_stencil_target_info->stencil_store_op == SDL_GPU_STOREOP_RESOLVE_AND_STORE) {
|
||||
SDL_assert_release(!"RESOLVE store ops are not supported for depth-stencil targets!");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1554,14 +1790,20 @@ SDL_GPURenderPass *SDL_BeginGPURenderPass(
|
||||
depth_stencil_target_info);
|
||||
|
||||
commandBufferHeader = (CommandBufferCommonHeader *)command_buffer;
|
||||
commandBufferHeader->render_pass.in_progress = true;
|
||||
for (Uint32 i = 0; i < num_color_targets; i += 1) {
|
||||
commandBufferHeader->render_pass.color_targets[i] = color_target_infos[i].texture;
|
||||
}
|
||||
commandBufferHeader->render_pass.num_color_targets = num_color_targets;
|
||||
if (depth_stencil_target_info != NULL) {
|
||||
commandBufferHeader->render_pass.depth_stencil_target = depth_stencil_target_info->texture;
|
||||
|
||||
if (COMMAND_BUFFER_DEVICE->debug_mode) {
|
||||
commandBufferHeader->render_pass.in_progress = true;
|
||||
for (Uint32 i = 0; i < num_color_targets; i += 1) {
|
||||
commandBufferHeader->render_pass.color_targets[i] = color_target_infos[i].texture;
|
||||
}
|
||||
commandBufferHeader->render_pass.num_color_targets = num_color_targets;
|
||||
if (depth_stencil_target_info != NULL) {
|
||||
commandBufferHeader->render_pass.depth_stencil_target = depth_stencil_target_info->texture;
|
||||
} else {
|
||||
commandBufferHeader->render_pass.depth_stencil_target = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return (SDL_GPURenderPass *)&(commandBufferHeader->render_pass);
|
||||
}
|
||||
|
||||
@@ -1569,8 +1811,6 @@ void SDL_BindGPUGraphicsPipeline(
|
||||
SDL_GPURenderPass *render_pass,
|
||||
SDL_GPUGraphicsPipeline *graphics_pipeline)
|
||||
{
|
||||
CommandBufferCommonHeader *commandBufferHeader;
|
||||
|
||||
if (render_pass == NULL) {
|
||||
SDL_InvalidParamError("render_pass");
|
||||
return;
|
||||
@@ -1584,8 +1824,10 @@ void SDL_BindGPUGraphicsPipeline(
|
||||
RENDERPASS_COMMAND_BUFFER,
|
||||
graphics_pipeline);
|
||||
|
||||
commandBufferHeader = (CommandBufferCommonHeader *)RENDERPASS_COMMAND_BUFFER;
|
||||
commandBufferHeader->graphics_pipeline_bound = true;
|
||||
|
||||
if (RENDERPASS_DEVICE->debug_mode) {
|
||||
RENDERPASS_BOUND_PIPELINE = graphics_pipeline;
|
||||
}
|
||||
}
|
||||
|
||||
void SDL_SetGPUViewport(
|
||||
@@ -1735,7 +1977,15 @@ void SDL_BindGPUVertexSamplers(
|
||||
|
||||
if (RENDERPASS_DEVICE->debug_mode) {
|
||||
CHECK_RENDERPASS
|
||||
CHECK_SAMPLER_TEXTURES
|
||||
|
||||
if (!((CommandBufferCommonHeader*)RENDERPASS_COMMAND_BUFFER)->ignore_render_pass_texture_validation)
|
||||
{
|
||||
CHECK_SAMPLER_TEXTURES
|
||||
}
|
||||
|
||||
for (Uint32 i = 0; i < num_bindings; i += 1) {
|
||||
((RenderPass *)render_pass)->vertex_sampler_bound[first_slot + i] = true;
|
||||
}
|
||||
}
|
||||
|
||||
RENDERPASS_DEVICE->BindVertexSamplers(
|
||||
@@ -1763,6 +2013,10 @@ void SDL_BindGPUVertexStorageTextures(
|
||||
if (RENDERPASS_DEVICE->debug_mode) {
|
||||
CHECK_RENDERPASS
|
||||
CHECK_STORAGE_TEXTURES
|
||||
|
||||
for (Uint32 i = 0; i < num_bindings; i += 1) {
|
||||
((RenderPass *)render_pass)->vertex_storage_texture_bound[first_slot + i] = true;
|
||||
}
|
||||
}
|
||||
|
||||
RENDERPASS_DEVICE->BindVertexStorageTextures(
|
||||
@@ -1789,6 +2043,10 @@ void SDL_BindGPUVertexStorageBuffers(
|
||||
|
||||
if (RENDERPASS_DEVICE->debug_mode) {
|
||||
CHECK_RENDERPASS
|
||||
|
||||
for (Uint32 i = 0; i < num_bindings; i += 1) {
|
||||
((RenderPass *)render_pass)->vertex_storage_buffer_bound[first_slot + i] = true;
|
||||
}
|
||||
}
|
||||
|
||||
RENDERPASS_DEVICE->BindVertexStorageBuffers(
|
||||
@@ -1815,7 +2073,14 @@ void SDL_BindGPUFragmentSamplers(
|
||||
|
||||
if (RENDERPASS_DEVICE->debug_mode) {
|
||||
CHECK_RENDERPASS
|
||||
CHECK_SAMPLER_TEXTURES
|
||||
|
||||
if (!((CommandBufferCommonHeader*)RENDERPASS_COMMAND_BUFFER)->ignore_render_pass_texture_validation) {
|
||||
CHECK_SAMPLER_TEXTURES
|
||||
}
|
||||
|
||||
for (Uint32 i = 0; i < num_bindings; i += 1) {
|
||||
((RenderPass *)render_pass)->fragment_sampler_bound[first_slot + i] = true;
|
||||
}
|
||||
}
|
||||
|
||||
RENDERPASS_DEVICE->BindFragmentSamplers(
|
||||
@@ -1843,6 +2108,10 @@ void SDL_BindGPUFragmentStorageTextures(
|
||||
if (RENDERPASS_DEVICE->debug_mode) {
|
||||
CHECK_RENDERPASS
|
||||
CHECK_STORAGE_TEXTURES
|
||||
|
||||
for (Uint32 i = 0; i < num_bindings; i += 1) {
|
||||
((RenderPass *)render_pass)->fragment_storage_texture_bound[first_slot + i] = true;
|
||||
}
|
||||
}
|
||||
|
||||
RENDERPASS_DEVICE->BindFragmentStorageTextures(
|
||||
@@ -1869,6 +2138,10 @@ void SDL_BindGPUFragmentStorageBuffers(
|
||||
|
||||
if (RENDERPASS_DEVICE->debug_mode) {
|
||||
CHECK_RENDERPASS
|
||||
|
||||
for (Uint32 i = 0; i < num_bindings; i += 1) {
|
||||
((RenderPass *)render_pass)->fragment_storage_buffer_bound[first_slot + i] = true;
|
||||
}
|
||||
}
|
||||
|
||||
RENDERPASS_DEVICE->BindFragmentStorageBuffers(
|
||||
@@ -1894,6 +2167,7 @@ void SDL_DrawGPUIndexedPrimitives(
|
||||
if (RENDERPASS_DEVICE->debug_mode) {
|
||||
CHECK_RENDERPASS
|
||||
CHECK_GRAPHICS_PIPELINE_BOUND
|
||||
SDL_GPU_CheckGraphicsBindings(render_pass);
|
||||
}
|
||||
|
||||
RENDERPASS_DEVICE->DrawIndexedPrimitives(
|
||||
@@ -1920,6 +2194,7 @@ void SDL_DrawGPUPrimitives(
|
||||
if (RENDERPASS_DEVICE->debug_mode) {
|
||||
CHECK_RENDERPASS
|
||||
CHECK_GRAPHICS_PIPELINE_BOUND
|
||||
SDL_GPU_CheckGraphicsBindings(render_pass);
|
||||
}
|
||||
|
||||
RENDERPASS_DEVICE->DrawPrimitives(
|
||||
@@ -1948,6 +2223,7 @@ void SDL_DrawGPUPrimitivesIndirect(
|
||||
if (RENDERPASS_DEVICE->debug_mode) {
|
||||
CHECK_RENDERPASS
|
||||
CHECK_GRAPHICS_PIPELINE_BOUND
|
||||
SDL_GPU_CheckGraphicsBindings(render_pass);
|
||||
}
|
||||
|
||||
RENDERPASS_DEVICE->DrawPrimitivesIndirect(
|
||||
@@ -1975,6 +2251,7 @@ void SDL_DrawGPUIndexedPrimitivesIndirect(
|
||||
if (RENDERPASS_DEVICE->debug_mode) {
|
||||
CHECK_RENDERPASS
|
||||
CHECK_GRAPHICS_PIPELINE_BOUND
|
||||
SDL_GPU_CheckGraphicsBindings(render_pass);
|
||||
}
|
||||
|
||||
RENDERPASS_DEVICE->DrawIndexedPrimitivesIndirect(
|
||||
@@ -1987,13 +2264,14 @@ void SDL_DrawGPUIndexedPrimitivesIndirect(
|
||||
void SDL_EndGPURenderPass(
|
||||
SDL_GPURenderPass *render_pass)
|
||||
{
|
||||
CommandBufferCommonHeader *commandBufferCommonHeader;
|
||||
|
||||
if (render_pass == NULL) {
|
||||
SDL_InvalidParamError("render_pass");
|
||||
return;
|
||||
}
|
||||
|
||||
CommandBufferCommonHeader *commandBufferCommonHeader;
|
||||
commandBufferCommonHeader = (CommandBufferCommonHeader *)RENDERPASS_COMMAND_BUFFER;
|
||||
|
||||
if (RENDERPASS_DEVICE->debug_mode) {
|
||||
CHECK_RENDERPASS
|
||||
}
|
||||
@@ -2001,15 +2279,22 @@ void SDL_EndGPURenderPass(
|
||||
RENDERPASS_DEVICE->EndRenderPass(
|
||||
RENDERPASS_COMMAND_BUFFER);
|
||||
|
||||
commandBufferCommonHeader = (CommandBufferCommonHeader *)RENDERPASS_COMMAND_BUFFER;
|
||||
commandBufferCommonHeader->render_pass.in_progress = false;
|
||||
for (Uint32 i = 0; i < MAX_COLOR_TARGET_BINDINGS; i += 1)
|
||||
{
|
||||
commandBufferCommonHeader->render_pass.color_targets[i] = NULL;
|
||||
if (RENDERPASS_DEVICE->debug_mode) {
|
||||
commandBufferCommonHeader->render_pass.in_progress = false;
|
||||
for (Uint32 i = 0; i < MAX_COLOR_TARGET_BINDINGS; i += 1)
|
||||
{
|
||||
commandBufferCommonHeader->render_pass.color_targets[i] = NULL;
|
||||
}
|
||||
commandBufferCommonHeader->render_pass.num_color_targets = 0;
|
||||
commandBufferCommonHeader->render_pass.depth_stencil_target = NULL;
|
||||
commandBufferCommonHeader->render_pass.graphics_pipeline = NULL;
|
||||
SDL_zeroa(commandBufferCommonHeader->render_pass.vertex_sampler_bound);
|
||||
SDL_zeroa(commandBufferCommonHeader->render_pass.vertex_storage_texture_bound);
|
||||
SDL_zeroa(commandBufferCommonHeader->render_pass.vertex_storage_buffer_bound);
|
||||
SDL_zeroa(commandBufferCommonHeader->render_pass.fragment_sampler_bound);
|
||||
SDL_zeroa(commandBufferCommonHeader->render_pass.fragment_storage_texture_bound);
|
||||
SDL_zeroa(commandBufferCommonHeader->render_pass.fragment_storage_buffer_bound);
|
||||
}
|
||||
commandBufferCommonHeader->render_pass.num_color_targets = 0;
|
||||
commandBufferCommonHeader->render_pass.depth_stencil_target = NULL;
|
||||
commandBufferCommonHeader->graphics_pipeline_bound = false;
|
||||
}
|
||||
|
||||
// Compute Pass
|
||||
@@ -2053,6 +2338,16 @@ SDL_GPUComputePass *SDL_BeginGPUComputePass(
|
||||
SDL_assert_release(!"Texture must be created with COMPUTE_STORAGE_WRITE or COMPUTE_STORAGE_SIMULTANEOUS_READ_WRITE flag");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (storage_texture_bindings[i].layer >= header->info.layer_count_or_depth) {
|
||||
SDL_assert_release(!"Storage texture layer index must be less than the texture's layer count!");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (storage_texture_bindings[i].mip_level >= header->info.num_levels) {
|
||||
SDL_assert_release(!"Storage texture mip level must be less than the texture's level count!");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: validate buffer usage?
|
||||
@@ -2066,7 +2361,19 @@ SDL_GPUComputePass *SDL_BeginGPUComputePass(
|
||||
num_storage_buffer_bindings);
|
||||
|
||||
commandBufferHeader = (CommandBufferCommonHeader *)command_buffer;
|
||||
commandBufferHeader->compute_pass.in_progress = true;
|
||||
|
||||
if (COMMAND_BUFFER_DEVICE->debug_mode) {
|
||||
commandBufferHeader->compute_pass.in_progress = true;
|
||||
|
||||
for (Uint32 i = 0; i < num_storage_texture_bindings; i += 1) {
|
||||
commandBufferHeader->compute_pass.read_write_storage_texture_bound[i] = true;
|
||||
}
|
||||
|
||||
for (Uint32 i = 0; i < num_storage_buffer_bindings; i += 1) {
|
||||
commandBufferHeader->compute_pass.read_write_storage_buffer_bound[i] = true;
|
||||
}
|
||||
}
|
||||
|
||||
return (SDL_GPUComputePass *)&(commandBufferHeader->compute_pass);
|
||||
}
|
||||
|
||||
@@ -2074,8 +2381,6 @@ void SDL_BindGPUComputePipeline(
|
||||
SDL_GPUComputePass *compute_pass,
|
||||
SDL_GPUComputePipeline *compute_pipeline)
|
||||
{
|
||||
CommandBufferCommonHeader *commandBufferHeader;
|
||||
|
||||
if (compute_pass == NULL) {
|
||||
SDL_InvalidParamError("compute_pass");
|
||||
return;
|
||||
@@ -2093,8 +2398,10 @@ void SDL_BindGPUComputePipeline(
|
||||
COMPUTEPASS_COMMAND_BUFFER,
|
||||
compute_pipeline);
|
||||
|
||||
commandBufferHeader = (CommandBufferCommonHeader *)COMPUTEPASS_COMMAND_BUFFER;
|
||||
commandBufferHeader->compute_pipeline_bound = true;
|
||||
|
||||
if (COMPUTEPASS_DEVICE->debug_mode) {
|
||||
COMPUTEPASS_BOUND_PIPELINE = compute_pipeline;
|
||||
}
|
||||
}
|
||||
|
||||
void SDL_BindGPUComputeSamplers(
|
||||
@@ -2114,6 +2421,10 @@ void SDL_BindGPUComputeSamplers(
|
||||
|
||||
if (COMPUTEPASS_DEVICE->debug_mode) {
|
||||
CHECK_COMPUTEPASS
|
||||
|
||||
for (Uint32 i = 0; i < num_bindings; i += 1) {
|
||||
((ComputePass *)compute_pass)->sampler_bound[first_slot + i] = true;
|
||||
}
|
||||
}
|
||||
|
||||
COMPUTEPASS_DEVICE->BindComputeSamplers(
|
||||
@@ -2140,6 +2451,10 @@ void SDL_BindGPUComputeStorageTextures(
|
||||
|
||||
if (COMPUTEPASS_DEVICE->debug_mode) {
|
||||
CHECK_COMPUTEPASS
|
||||
|
||||
for (Uint32 i = 0; i < num_bindings; i += 1) {
|
||||
((ComputePass *)compute_pass)->read_only_storage_texture_bound[first_slot + i] = true;
|
||||
}
|
||||
}
|
||||
|
||||
COMPUTEPASS_DEVICE->BindComputeStorageTextures(
|
||||
@@ -2166,6 +2481,10 @@ void SDL_BindGPUComputeStorageBuffers(
|
||||
|
||||
if (COMPUTEPASS_DEVICE->debug_mode) {
|
||||
CHECK_COMPUTEPASS
|
||||
|
||||
for (Uint32 i = 0; i < num_bindings; i += 1) {
|
||||
((ComputePass *)compute_pass)->read_only_storage_buffer_bound[first_slot + i] = true;
|
||||
}
|
||||
}
|
||||
|
||||
COMPUTEPASS_DEVICE->BindComputeStorageBuffers(
|
||||
@@ -2189,6 +2508,7 @@ void SDL_DispatchGPUCompute(
|
||||
if (COMPUTEPASS_DEVICE->debug_mode) {
|
||||
CHECK_COMPUTEPASS
|
||||
CHECK_COMPUTE_PIPELINE_BOUND
|
||||
SDL_GPU_CheckComputeBindings(compute_pass);
|
||||
}
|
||||
|
||||
COMPUTEPASS_DEVICE->DispatchCompute(
|
||||
@@ -2211,6 +2531,7 @@ void SDL_DispatchGPUComputeIndirect(
|
||||
if (COMPUTEPASS_DEVICE->debug_mode) {
|
||||
CHECK_COMPUTEPASS
|
||||
CHECK_COMPUTE_PIPELINE_BOUND
|
||||
SDL_GPU_CheckComputeBindings(compute_pass);
|
||||
}
|
||||
|
||||
COMPUTEPASS_DEVICE->DispatchComputeIndirect(
|
||||
@@ -2236,9 +2557,16 @@ void SDL_EndGPUComputePass(
|
||||
COMPUTEPASS_DEVICE->EndComputePass(
|
||||
COMPUTEPASS_COMMAND_BUFFER);
|
||||
|
||||
commandBufferCommonHeader = (CommandBufferCommonHeader *)COMPUTEPASS_COMMAND_BUFFER;
|
||||
commandBufferCommonHeader->compute_pass.in_progress = false;
|
||||
commandBufferCommonHeader->compute_pipeline_bound = false;
|
||||
if (COMPUTEPASS_DEVICE->debug_mode) {
|
||||
commandBufferCommonHeader = (CommandBufferCommonHeader *)COMPUTEPASS_COMMAND_BUFFER;
|
||||
commandBufferCommonHeader->compute_pass.in_progress = false;
|
||||
commandBufferCommonHeader->compute_pass.compute_pipeline = NULL;
|
||||
SDL_zeroa(commandBufferCommonHeader->compute_pass.sampler_bound);
|
||||
SDL_zeroa(commandBufferCommonHeader->compute_pass.read_only_storage_texture_bound);
|
||||
SDL_zeroa(commandBufferCommonHeader->compute_pass.read_only_storage_buffer_bound);
|
||||
SDL_zeroa(commandBufferCommonHeader->compute_pass.read_write_storage_texture_bound);
|
||||
SDL_zeroa(commandBufferCommonHeader->compute_pass.read_write_storage_buffer_bound);
|
||||
}
|
||||
}
|
||||
|
||||
// TransferBuffer Data
|
||||
@@ -2296,7 +2624,11 @@ SDL_GPUCopyPass *SDL_BeginGPUCopyPass(
|
||||
command_buffer);
|
||||
|
||||
commandBufferHeader = (CommandBufferCommonHeader *)command_buffer;
|
||||
commandBufferHeader->copy_pass.in_progress = true;
|
||||
|
||||
if (COMMAND_BUFFER_DEVICE->debug_mode) {
|
||||
commandBufferHeader->copy_pass.in_progress = true;
|
||||
}
|
||||
|
||||
return (SDL_GPUCopyPass *)&(commandBufferHeader->copy_pass);
|
||||
}
|
||||
|
||||
@@ -2547,7 +2879,9 @@ void SDL_EndGPUCopyPass(
|
||||
COPYPASS_DEVICE->EndCopyPass(
|
||||
COPYPASS_COMMAND_BUFFER);
|
||||
|
||||
((CommandBufferCommonHeader *)COPYPASS_COMMAND_BUFFER)->copy_pass.in_progress = false;
|
||||
if (COPYPASS_DEVICE->debug_mode) {
|
||||
((CommandBufferCommonHeader *)COPYPASS_COMMAND_BUFFER)->copy_pass.in_progress = false;
|
||||
}
|
||||
}
|
||||
|
||||
void SDL_GenerateMipmapsForGPUTexture(
|
||||
@@ -2577,11 +2911,19 @@ void SDL_GenerateMipmapsForGPUTexture(
|
||||
SDL_assert_release(!"GenerateMipmaps texture must be created with SAMPLER and COLOR_TARGET usage flags!");
|
||||
return;
|
||||
}
|
||||
|
||||
CommandBufferCommonHeader *commandBufferHeader = (CommandBufferCommonHeader *)command_buffer;
|
||||
commandBufferHeader->ignore_render_pass_texture_validation = true;
|
||||
}
|
||||
|
||||
COMMAND_BUFFER_DEVICE->GenerateMipmaps(
|
||||
command_buffer,
|
||||
texture);
|
||||
|
||||
if (COMMAND_BUFFER_DEVICE->debug_mode) {
|
||||
CommandBufferCommonHeader *commandBufferHeader = (CommandBufferCommonHeader *)command_buffer;
|
||||
commandBufferHeader->ignore_render_pass_texture_validation = false;
|
||||
}
|
||||
}
|
||||
|
||||
void SDL_BlitGPUTexture(
|
||||
|
||||
+55
-4
@@ -35,7 +35,7 @@
|
||||
#define UNIFORM_BUFFER_SIZE 32768
|
||||
#define MAX_VERTEX_BUFFERS 16
|
||||
#define MAX_VERTEX_ATTRIBUTES 16
|
||||
#define MAX_COLOR_TARGET_BINDINGS 4
|
||||
#define MAX_COLOR_TARGET_BINDINGS 8
|
||||
#define MAX_PRESENT_COUNT 16
|
||||
#define MAX_FRAMES_IN_FLIGHT 3
|
||||
|
||||
@@ -47,6 +47,20 @@ typedef struct Pass
|
||||
bool in_progress;
|
||||
} Pass;
|
||||
|
||||
typedef struct ComputePass
|
||||
{
|
||||
SDL_GPUCommandBuffer *command_buffer;
|
||||
bool in_progress;
|
||||
|
||||
SDL_GPUComputePipeline *compute_pipeline;
|
||||
|
||||
bool sampler_bound[MAX_TEXTURE_SAMPLERS_PER_STAGE];
|
||||
bool read_only_storage_texture_bound[MAX_STORAGE_TEXTURES_PER_STAGE];
|
||||
bool read_only_storage_buffer_bound[MAX_STORAGE_BUFFERS_PER_STAGE];
|
||||
bool read_write_storage_texture_bound[MAX_COMPUTE_WRITE_TEXTURES];
|
||||
bool read_write_storage_buffer_bound[MAX_COMPUTE_WRITE_BUFFERS];
|
||||
} ComputePass;
|
||||
|
||||
typedef struct RenderPass
|
||||
{
|
||||
SDL_GPUCommandBuffer *command_buffer;
|
||||
@@ -54,18 +68,30 @@ typedef struct RenderPass
|
||||
SDL_GPUTexture *color_targets[MAX_COLOR_TARGET_BINDINGS];
|
||||
Uint32 num_color_targets;
|
||||
SDL_GPUTexture *depth_stencil_target;
|
||||
|
||||
SDL_GPUGraphicsPipeline *graphics_pipeline;
|
||||
|
||||
bool vertex_sampler_bound[MAX_TEXTURE_SAMPLERS_PER_STAGE];
|
||||
bool vertex_storage_texture_bound[MAX_STORAGE_TEXTURES_PER_STAGE];
|
||||
bool vertex_storage_buffer_bound[MAX_STORAGE_BUFFERS_PER_STAGE];
|
||||
|
||||
bool fragment_sampler_bound[MAX_TEXTURE_SAMPLERS_PER_STAGE];
|
||||
bool fragment_storage_texture_bound[MAX_STORAGE_TEXTURES_PER_STAGE];
|
||||
bool fragment_storage_buffer_bound[MAX_STORAGE_BUFFERS_PER_STAGE];
|
||||
} RenderPass;
|
||||
|
||||
typedef struct CommandBufferCommonHeader
|
||||
{
|
||||
SDL_GPUDevice *device;
|
||||
|
||||
RenderPass render_pass;
|
||||
bool graphics_pipeline_bound;
|
||||
Pass compute_pass;
|
||||
bool compute_pipeline_bound;
|
||||
ComputePass compute_pass;
|
||||
|
||||
Pass copy_pass;
|
||||
bool swapchain_texture_acquired;
|
||||
bool submitted;
|
||||
// used to avoid tripping assert on GenerateMipmaps
|
||||
bool ignore_render_pass_texture_validation;
|
||||
} CommandBufferCommonHeader;
|
||||
|
||||
typedef struct TextureCommonHeader
|
||||
@@ -73,6 +99,29 @@ typedef struct TextureCommonHeader
|
||||
SDL_GPUTextureCreateInfo info;
|
||||
} TextureCommonHeader;
|
||||
|
||||
typedef struct GraphicsPipelineCommonHeader
|
||||
{
|
||||
Uint32 num_vertex_samplers;
|
||||
Uint32 num_vertex_storage_textures;
|
||||
Uint32 num_vertex_storage_buffers;
|
||||
Uint32 num_vertex_uniform_buffers;
|
||||
|
||||
Uint32 num_fragment_samplers;
|
||||
Uint32 num_fragment_storage_textures;
|
||||
Uint32 num_fragment_storage_buffers;
|
||||
Uint32 num_fragment_uniform_buffers;
|
||||
} GraphicsPipelineCommonHeader;
|
||||
|
||||
typedef struct ComputePipelineCommonHeader
|
||||
{
|
||||
Uint32 numSamplers;
|
||||
Uint32 numReadonlyStorageTextures;
|
||||
Uint32 numReadonlyStorageBuffers;
|
||||
Uint32 numReadWriteStorageTextures;
|
||||
Uint32 numReadWriteStorageBuffers;
|
||||
Uint32 numUniformBuffers;
|
||||
} ComputePipelineCommonHeader;
|
||||
|
||||
typedef struct BlitFragmentUniforms
|
||||
{
|
||||
// texcoord space
|
||||
@@ -160,6 +209,7 @@ static inline Sint32 Texture_GetBlockWidth(
|
||||
case SDL_GPU_TEXTUREFORMAT_BC6H_RGB_FLOAT:
|
||||
case SDL_GPU_TEXTUREFORMAT_BC6H_RGB_UFLOAT:
|
||||
case SDL_GPU_TEXTUREFORMAT_BC1_RGBA_UNORM_SRGB:
|
||||
case SDL_GPU_TEXTUREFORMAT_BC2_RGBA_UNORM_SRGB:
|
||||
case SDL_GPU_TEXTUREFORMAT_BC3_RGBA_UNORM_SRGB:
|
||||
case SDL_GPU_TEXTUREFORMAT_BC7_RGBA_UNORM_SRGB:
|
||||
case SDL_GPU_TEXTUREFORMAT_ASTC_4x4_UNORM:
|
||||
@@ -277,6 +327,7 @@ static inline Sint32 Texture_GetBlockHeight(
|
||||
case SDL_GPU_TEXTUREFORMAT_BC6H_RGB_FLOAT:
|
||||
case SDL_GPU_TEXTUREFORMAT_BC6H_RGB_UFLOAT:
|
||||
case SDL_GPU_TEXTUREFORMAT_BC1_RGBA_UNORM_SRGB:
|
||||
case SDL_GPU_TEXTUREFORMAT_BC2_RGBA_UNORM_SRGB:
|
||||
case SDL_GPU_TEXTUREFORMAT_BC3_RGBA_UNORM_SRGB:
|
||||
case SDL_GPU_TEXTUREFORMAT_BC7_RGBA_UNORM_SRGB:
|
||||
case SDL_GPU_TEXTUREFORMAT_ASTC_5x4_UNORM:
|
||||
|
||||
+269
-165
@@ -109,8 +109,8 @@
|
||||
#define DXGI_GET_DEBUG_INTERFACE_FUNC "DXGIGetDebugInterface"
|
||||
#define D3D12_GET_DEBUG_INTERFACE_FUNC "D3D12GetDebugInterface"
|
||||
#define WINDOW_PROPERTY_DATA "SDL_GPUD3D12WindowPropertyData"
|
||||
#define D3D_FEATURE_LEVEL_CHOICE D3D_FEATURE_LEVEL_11_1
|
||||
#define D3D_FEATURE_LEVEL_CHOICE_STR "11_1"
|
||||
#define D3D_FEATURE_LEVEL_CHOICE D3D_FEATURE_LEVEL_11_0
|
||||
#define D3D_FEATURE_LEVEL_CHOICE_STR "11_0"
|
||||
#define MAX_ROOT_SIGNATURE_PARAMETERS 64
|
||||
#define D3D12_FENCE_UNSIGNALED_VALUE 0
|
||||
#define D3D12_FENCE_SIGNAL_VALUE 1
|
||||
@@ -876,7 +876,7 @@ struct D3D12Renderer
|
||||
SDL_SharedObject *d3d12_dll;
|
||||
ID3D12Device *device;
|
||||
PFN_D3D12_SERIALIZE_ROOT_SIGNATURE D3D12SerializeRootSignature_func;
|
||||
const char *semantic;
|
||||
char *semantic;
|
||||
SDL_iconv_t iconv;
|
||||
|
||||
ID3D12CommandQueue *commandQueue;
|
||||
@@ -991,6 +991,10 @@ struct D3D12CommandBuffer
|
||||
// Set at acquire time
|
||||
D3D12DescriptorHeap *gpuDescriptorHeaps[D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER + 1];
|
||||
|
||||
D3D12DescriptorHeap **usedDescriptorHeaps;
|
||||
Uint32 usedDescriptorHeapCount;
|
||||
Uint32 usedDescriptorHeapCapacity;
|
||||
|
||||
D3D12UniformBuffer **usedUniformBuffers;
|
||||
Uint32 usedUniformBufferCount;
|
||||
Uint32 usedUniformBufferCapacity;
|
||||
@@ -1015,26 +1019,38 @@ struct D3D12CommandBuffer
|
||||
Uint32 vertexBufferOffsets[MAX_VERTEX_BUFFERS];
|
||||
Uint32 vertexBufferCount;
|
||||
|
||||
D3D12Texture *vertexSamplerTextures[MAX_TEXTURE_SAMPLERS_PER_STAGE];
|
||||
D3D12Sampler *vertexSamplers[MAX_TEXTURE_SAMPLERS_PER_STAGE];
|
||||
D3D12Texture *vertexStorageTextures[MAX_STORAGE_TEXTURES_PER_STAGE];
|
||||
D3D12Buffer *vertexStorageBuffers[MAX_STORAGE_BUFFERS_PER_STAGE];
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE vertexSamplerTextureDescriptorHandles[MAX_TEXTURE_SAMPLERS_PER_STAGE];
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE vertexSamplerDescriptorHandles[MAX_TEXTURE_SAMPLERS_PER_STAGE];
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE vertexStorageTextureDescriptorHandles[MAX_STORAGE_TEXTURES_PER_STAGE];
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE vertexStorageBufferDescriptorHandles[MAX_STORAGE_BUFFERS_PER_STAGE];
|
||||
|
||||
D3D12UniformBuffer *vertexUniformBuffers[MAX_UNIFORM_BUFFERS_PER_STAGE];
|
||||
|
||||
D3D12Texture *fragmentSamplerTextures[MAX_TEXTURE_SAMPLERS_PER_STAGE];
|
||||
D3D12Sampler *fragmentSamplers[MAX_TEXTURE_SAMPLERS_PER_STAGE];
|
||||
D3D12Texture *fragmentStorageTextures[MAX_STORAGE_TEXTURES_PER_STAGE];
|
||||
D3D12Buffer *fragmentStorageBuffers[MAX_STORAGE_BUFFERS_PER_STAGE];
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE fragmentSamplerTextureDescriptorHandles[MAX_TEXTURE_SAMPLERS_PER_STAGE];
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE fragmentSamplerDescriptorHandles[MAX_TEXTURE_SAMPLERS_PER_STAGE];
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE fragmentStorageTextureDescriptorHandles[MAX_STORAGE_TEXTURES_PER_STAGE];
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE fragmentStorageBufferDescriptorHandles[MAX_STORAGE_BUFFERS_PER_STAGE];
|
||||
|
||||
D3D12UniformBuffer *fragmentUniformBuffers[MAX_UNIFORM_BUFFERS_PER_STAGE];
|
||||
|
||||
D3D12Texture *computeSamplerTextures[MAX_TEXTURE_SAMPLERS_PER_STAGE];
|
||||
D3D12Sampler *computeSamplers[MAX_TEXTURE_SAMPLERS_PER_STAGE];
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE computeSamplerTextureDescriptorHandles[MAX_TEXTURE_SAMPLERS_PER_STAGE];
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE computeSamplerDescriptorHandles[MAX_TEXTURE_SAMPLERS_PER_STAGE];
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE computeReadOnlyStorageTextureDescriptorHandles[MAX_STORAGE_TEXTURES_PER_STAGE];
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE computeReadOnlyStorageBufferDescriptorHandles[MAX_STORAGE_BUFFERS_PER_STAGE];
|
||||
|
||||
// Track these separately because barriers can happen mid compute pass
|
||||
D3D12Texture *computeReadOnlyStorageTextures[MAX_STORAGE_TEXTURES_PER_STAGE];
|
||||
D3D12Buffer *computeReadOnlyStorageBuffers[MAX_STORAGE_BUFFERS_PER_STAGE];
|
||||
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE computeReadWriteStorageTextureDescriptorHandles[MAX_COMPUTE_WRITE_TEXTURES];
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE computeReadWriteStorageBufferDescriptorHandles[MAX_COMPUTE_WRITE_BUFFERS];
|
||||
|
||||
// Track these separately because they are bound when the compute pass begins
|
||||
D3D12TextureSubresource *computeReadWriteStorageTextureSubresources[MAX_COMPUTE_WRITE_TEXTURES];
|
||||
Uint32 computeReadWriteStorageTextureSubresourceCount;
|
||||
D3D12Buffer *computeReadWriteStorageBuffers[MAX_COMPUTE_WRITE_BUFFERS];
|
||||
Uint32 computeReadWriteStorageBufferCount;
|
||||
|
||||
D3D12UniformBuffer *computeUniformBuffers[MAX_UNIFORM_BUFFERS_PER_STAGE];
|
||||
|
||||
// Resource tracking
|
||||
@@ -1098,22 +1114,14 @@ typedef struct D3D12GraphicsRootSignature
|
||||
|
||||
struct D3D12GraphicsPipeline
|
||||
{
|
||||
GraphicsPipelineCommonHeader header;
|
||||
|
||||
ID3D12PipelineState *pipelineState;
|
||||
D3D12GraphicsRootSignature *rootSignature;
|
||||
SDL_GPUPrimitiveType primitiveType;
|
||||
|
||||
Uint32 vertexStrides[MAX_VERTEX_BUFFERS];
|
||||
|
||||
Uint32 vertexSamplerCount;
|
||||
Uint32 vertexUniformBufferCount;
|
||||
Uint32 vertexStorageBufferCount;
|
||||
Uint32 vertexStorageTextureCount;
|
||||
|
||||
Uint32 fragmentSamplerCount;
|
||||
Uint32 fragmentUniformBufferCount;
|
||||
Uint32 fragmentStorageBufferCount;
|
||||
Uint32 fragmentStorageTextureCount;
|
||||
|
||||
SDL_AtomicInt referenceCount;
|
||||
};
|
||||
|
||||
@@ -1132,16 +1140,11 @@ typedef struct D3D12ComputeRootSignature
|
||||
|
||||
struct D3D12ComputePipeline
|
||||
{
|
||||
ComputePipelineCommonHeader header;
|
||||
|
||||
ID3D12PipelineState *pipelineState;
|
||||
D3D12ComputeRootSignature *rootSignature;
|
||||
|
||||
Uint32 numSamplers;
|
||||
Uint32 numReadOnlyStorageTextures;
|
||||
Uint32 numReadOnlyStorageBuffers;
|
||||
Uint32 numReadWriteStorageTextures;
|
||||
Uint32 numReadWriteStorageBuffers;
|
||||
Uint32 numUniformBuffers;
|
||||
|
||||
SDL_AtomicInt referenceCount;
|
||||
};
|
||||
|
||||
@@ -1195,7 +1198,6 @@ struct D3D12UniformBuffer
|
||||
D3D12Buffer *buffer;
|
||||
Uint32 writeOffset;
|
||||
Uint32 drawOffset;
|
||||
Uint32 currentBlockSize;
|
||||
};
|
||||
|
||||
// Forward function declarations
|
||||
@@ -1442,6 +1444,8 @@ static void D3D12_INTERNAL_ReleaseTextureContainer(
|
||||
container->textures[i]);
|
||||
}
|
||||
|
||||
SDL_DestroyProperties(container->header.info.props);
|
||||
|
||||
// Containers are just client handles, so we can destroy immediately
|
||||
if (container->debugName) {
|
||||
SDL_free(container->debugName);
|
||||
@@ -1588,6 +1592,7 @@ static void D3D12_INTERNAL_DestroyCommandBuffer(D3D12CommandBuffer *commandBuffe
|
||||
SDL_free(commandBuffer->usedSamplers);
|
||||
SDL_free(commandBuffer->usedGraphicsPipelines);
|
||||
SDL_free(commandBuffer->usedComputePipelines);
|
||||
SDL_free(commandBuffer->usedDescriptorHeaps);
|
||||
SDL_free(commandBuffer->usedUniformBuffers);
|
||||
SDL_free(commandBuffer->textureDownloads);
|
||||
SDL_free(commandBuffer);
|
||||
@@ -1734,6 +1739,7 @@ static void D3D12_INTERNAL_DestroyRenderer(D3D12Renderer *renderer)
|
||||
SDL_DestroyMutex(renderer->windowLock);
|
||||
SDL_DestroyMutex(renderer->fenceLock);
|
||||
SDL_DestroyMutex(renderer->disposeLock);
|
||||
SDL_free(renderer->semantic);
|
||||
SDL_free(renderer);
|
||||
}
|
||||
|
||||
@@ -2284,6 +2290,28 @@ static bool D3D12_INTERNAL_ExpandStagingDescriptorPool(
|
||||
return true;
|
||||
}
|
||||
|
||||
static void D3D12_INTERNAL_TrackGPUDescriptorHeap(
|
||||
D3D12CommandBuffer *commandBuffer,
|
||||
D3D12DescriptorHeap *descriptorHeap)
|
||||
{
|
||||
Uint32 i;
|
||||
for (i = 0; i < commandBuffer->usedDescriptorHeapCount; i += 1) {
|
||||
if (commandBuffer->usedDescriptorHeaps[i] == descriptorHeap) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (commandBuffer->usedDescriptorHeapCount == commandBuffer->usedDescriptorHeapCapacity) {
|
||||
commandBuffer->usedDescriptorHeapCapacity += 1;
|
||||
commandBuffer->usedDescriptorHeaps = (D3D12DescriptorHeap **)SDL_realloc(
|
||||
commandBuffer->usedDescriptorHeaps,
|
||||
commandBuffer->usedDescriptorHeapCapacity * sizeof(D3D12DescriptorHeap *));
|
||||
}
|
||||
|
||||
commandBuffer->usedDescriptorHeaps[commandBuffer->usedDescriptorHeapCount] = descriptorHeap;
|
||||
commandBuffer->usedDescriptorHeapCount += 1;
|
||||
}
|
||||
|
||||
static D3D12DescriptorHeap *D3D12_INTERNAL_AcquireGPUDescriptorHeapFromPool(
|
||||
D3D12CommandBuffer *commandBuffer,
|
||||
D3D12_DESCRIPTOR_HEAP_TYPE descriptorHeapType)
|
||||
@@ -2305,6 +2333,7 @@ static D3D12DescriptorHeap *D3D12_INTERNAL_AcquireGPUDescriptorHeapFromPool(
|
||||
}
|
||||
SDL_UnlockMutex(pool->lock);
|
||||
|
||||
D3D12_INTERNAL_TrackGPUDescriptorHeap(commandBuffer, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -2886,12 +2915,12 @@ static SDL_GPUComputePipeline *D3D12_CreateComputePipeline(
|
||||
|
||||
computePipeline->pipelineState = pipelineState;
|
||||
computePipeline->rootSignature = rootSignature;
|
||||
computePipeline->numSamplers = createinfo->num_samplers;
|
||||
computePipeline->numReadOnlyStorageTextures = createinfo->num_readonly_storage_textures;
|
||||
computePipeline->numReadOnlyStorageBuffers = createinfo->num_readonly_storage_buffers;
|
||||
computePipeline->numReadWriteStorageTextures = createinfo->num_readwrite_storage_textures;
|
||||
computePipeline->numReadWriteStorageBuffers = createinfo->num_readwrite_storage_buffers;
|
||||
computePipeline->numUniformBuffers = createinfo->num_uniform_buffers;
|
||||
computePipeline->header.numSamplers = createinfo->num_samplers;
|
||||
computePipeline->header.numReadonlyStorageTextures = createinfo->num_readonly_storage_textures;
|
||||
computePipeline->header.numReadonlyStorageBuffers = createinfo->num_readonly_storage_buffers;
|
||||
computePipeline->header.numReadWriteStorageTextures = createinfo->num_readwrite_storage_textures;
|
||||
computePipeline->header.numReadWriteStorageBuffers = createinfo->num_readwrite_storage_buffers;
|
||||
computePipeline->header.numUniformBuffers = createinfo->num_uniform_buffers;
|
||||
SDL_SetAtomicInt(&computePipeline->referenceCount, 0);
|
||||
|
||||
if (renderer->debug_mode && SDL_HasProperty(createinfo->props, SDL_PROP_GPU_COMPUTEPIPELINE_CREATE_NAME_STRING)) {
|
||||
@@ -3172,15 +3201,15 @@ static SDL_GPUGraphicsPipeline *D3D12_CreateGraphicsPipeline(
|
||||
|
||||
pipeline->primitiveType = createinfo->primitive_type;
|
||||
|
||||
pipeline->vertexSamplerCount = vertShader->num_samplers;
|
||||
pipeline->vertexStorageTextureCount = vertShader->numStorageTextures;
|
||||
pipeline->vertexStorageBufferCount = vertShader->numStorageBuffers;
|
||||
pipeline->vertexUniformBufferCount = vertShader->numUniformBuffers;
|
||||
pipeline->header.num_vertex_samplers = vertShader->num_samplers;
|
||||
pipeline->header.num_vertex_storage_textures = vertShader->numStorageTextures;
|
||||
pipeline->header.num_vertex_storage_buffers = vertShader->numStorageBuffers;
|
||||
pipeline->header.num_vertex_uniform_buffers = vertShader->numUniformBuffers;
|
||||
|
||||
pipeline->fragmentSamplerCount = fragShader->num_samplers;
|
||||
pipeline->fragmentStorageTextureCount = fragShader->numStorageTextures;
|
||||
pipeline->fragmentStorageBufferCount = fragShader->numStorageBuffers;
|
||||
pipeline->fragmentUniformBufferCount = fragShader->numUniformBuffers;
|
||||
pipeline->header.num_fragment_samplers = fragShader->num_samplers;
|
||||
pipeline->header.num_fragment_storage_textures = fragShader->numStorageTextures;
|
||||
pipeline->header.num_fragment_storage_buffers = fragShader->numStorageBuffers;
|
||||
pipeline->header.num_fragment_uniform_buffers = fragShader->numUniformBuffers;
|
||||
|
||||
SDL_SetAtomicInt(&pipeline->referenceCount, 0);
|
||||
|
||||
@@ -3350,7 +3379,7 @@ static D3D12Texture *D3D12_INTERNAL_CreateTexture(
|
||||
|
||||
if (createinfo->type != SDL_GPU_TEXTURETYPE_3D) {
|
||||
desc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
|
||||
desc.Alignment = isSwapchainTexture ? 0 : D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT;
|
||||
desc.Alignment = isSwapchainTexture ? 0 : isMultisample ? D3D12_DEFAULT_MSAA_RESOURCE_PLACEMENT_ALIGNMENT : D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT;
|
||||
desc.Width = createinfo->width;
|
||||
desc.Height = createinfo->height;
|
||||
desc.DepthOrArraySize = (UINT16)createinfo->layer_count_or_depth;
|
||||
@@ -4497,7 +4526,6 @@ static D3D12UniformBuffer *D3D12_INTERNAL_AcquireUniformBufferFromPool(
|
||||
|
||||
SDL_UnlockMutex(renderer->acquireUniformBufferLock);
|
||||
|
||||
uniformBuffer->currentBlockSize = 0;
|
||||
uniformBuffer->drawOffset = 0;
|
||||
uniformBuffer->writeOffset = 0;
|
||||
|
||||
@@ -4536,6 +4564,7 @@ static void D3D12_INTERNAL_PushUniformData(
|
||||
Uint32 length)
|
||||
{
|
||||
D3D12UniformBuffer *uniformBuffer;
|
||||
Uint32 blockSize;
|
||||
|
||||
if (shaderStage == SDL_GPU_SHADERSTAGE_VERTEX) {
|
||||
if (commandBuffer->vertexUniformBuffers[slotIndex] == NULL) {
|
||||
@@ -4560,13 +4589,13 @@ static void D3D12_INTERNAL_PushUniformData(
|
||||
return;
|
||||
}
|
||||
|
||||
uniformBuffer->currentBlockSize =
|
||||
blockSize =
|
||||
D3D12_INTERNAL_Align(
|
||||
length,
|
||||
256);
|
||||
|
||||
// If there is no more room, acquire a new uniform buffer
|
||||
if (uniformBuffer->writeOffset + uniformBuffer->currentBlockSize >= UNIFORM_BUFFER_SIZE) {
|
||||
if (uniformBuffer->writeOffset + blockSize >= UNIFORM_BUFFER_SIZE) {
|
||||
ID3D12Resource_Unmap(
|
||||
uniformBuffer->buffer->handle,
|
||||
0,
|
||||
@@ -4596,7 +4625,7 @@ static void D3D12_INTERNAL_PushUniformData(
|
||||
data,
|
||||
length);
|
||||
|
||||
uniformBuffer->writeOffset += uniformBuffer->currentBlockSize;
|
||||
uniformBuffer->writeOffset += blockSize;
|
||||
|
||||
if (shaderStage == SDL_GPU_SHADERSTAGE_VERTEX) {
|
||||
commandBuffer->needVertexUniformBufferBind[slotIndex] = true;
|
||||
@@ -4637,14 +4666,14 @@ static void D3D12_BindGraphicsPipeline(
|
||||
d3d12CommandBuffer->needFragmentUniformBufferBind[i] = true;
|
||||
}
|
||||
|
||||
for (i = 0; i < pipeline->vertexUniformBufferCount; i += 1) {
|
||||
for (i = 0; i < pipeline->header.num_vertex_uniform_buffers; i += 1) {
|
||||
if (d3d12CommandBuffer->vertexUniformBuffers[i] == NULL) {
|
||||
d3d12CommandBuffer->vertexUniformBuffers[i] = D3D12_INTERNAL_AcquireUniformBufferFromPool(
|
||||
d3d12CommandBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < pipeline->fragmentUniformBufferCount; i += 1) {
|
||||
for (i = 0; i < pipeline->header.num_fragment_uniform_buffers; i += 1) {
|
||||
if (d3d12CommandBuffer->fragmentUniformBuffers[i] == NULL) {
|
||||
d3d12CommandBuffer->fragmentUniformBuffers[i] = D3D12_INTERNAL_AcquireUniformBufferFromPool(
|
||||
d3d12CommandBuffer);
|
||||
@@ -4711,21 +4740,21 @@ static void D3D12_BindVertexSamplers(
|
||||
D3D12TextureContainer *container = (D3D12TextureContainer *)textureSamplerBindings[i].texture;
|
||||
D3D12Sampler *sampler = (D3D12Sampler *)textureSamplerBindings[i].sampler;
|
||||
|
||||
if (d3d12CommandBuffer->vertexSamplers[firstSlot + i] != sampler) {
|
||||
if (d3d12CommandBuffer->vertexSamplerDescriptorHandles[firstSlot + i].ptr != sampler->handle.cpuHandle.ptr) {
|
||||
D3D12_INTERNAL_TrackSampler(
|
||||
d3d12CommandBuffer,
|
||||
sampler);
|
||||
|
||||
d3d12CommandBuffer->vertexSamplers[firstSlot + i] = sampler;
|
||||
d3d12CommandBuffer->vertexSamplerDescriptorHandles[firstSlot + i] = sampler->handle.cpuHandle;
|
||||
d3d12CommandBuffer->needVertexSamplerBind = true;
|
||||
}
|
||||
|
||||
if (d3d12CommandBuffer->vertexSamplerTextures[firstSlot + i] != container->activeTexture) {
|
||||
if (d3d12CommandBuffer->vertexSamplerTextureDescriptorHandles[firstSlot + i].ptr != container->activeTexture->srvHandle.cpuHandle.ptr) {
|
||||
D3D12_INTERNAL_TrackTexture(
|
||||
d3d12CommandBuffer,
|
||||
container->activeTexture);
|
||||
|
||||
d3d12CommandBuffer->vertexSamplerTextures[firstSlot + i] = container->activeTexture;
|
||||
d3d12CommandBuffer->vertexSamplerTextureDescriptorHandles[firstSlot + i] = container->activeTexture->srvHandle.cpuHandle;
|
||||
d3d12CommandBuffer->needVertexSamplerBind = true;
|
||||
}
|
||||
}
|
||||
@@ -4743,10 +4772,10 @@ static void D3D12_BindVertexStorageTextures(
|
||||
D3D12TextureContainer *container = (D3D12TextureContainer *)storageTextures[i];
|
||||
D3D12Texture *texture = container->activeTexture;
|
||||
|
||||
if (d3d12CommandBuffer->vertexStorageTextures[firstSlot + i] != texture) {
|
||||
if (d3d12CommandBuffer->vertexStorageTextureDescriptorHandles[firstSlot + i].ptr != texture->srvHandle.cpuHandle.ptr) {
|
||||
D3D12_INTERNAL_TrackTexture(d3d12CommandBuffer, texture);
|
||||
|
||||
d3d12CommandBuffer->vertexStorageTextures[firstSlot + i] = texture;
|
||||
d3d12CommandBuffer->vertexStorageTextureDescriptorHandles[firstSlot + i] = texture->srvHandle.cpuHandle;
|
||||
d3d12CommandBuffer->needVertexStorageTextureBind = true;
|
||||
}
|
||||
}
|
||||
@@ -4762,12 +4791,12 @@ static void D3D12_BindVertexStorageBuffers(
|
||||
|
||||
for (Uint32 i = 0; i < numBindings; i += 1) {
|
||||
D3D12BufferContainer *container = (D3D12BufferContainer *)storageBuffers[i];
|
||||
if (d3d12CommandBuffer->vertexStorageBuffers[firstSlot + i] != container->activeBuffer) {
|
||||
if (d3d12CommandBuffer->vertexStorageBufferDescriptorHandles[firstSlot + i].ptr != container->activeBuffer->srvDescriptor.cpuHandle.ptr) {
|
||||
D3D12_INTERNAL_TrackBuffer(
|
||||
d3d12CommandBuffer,
|
||||
container->activeBuffer);
|
||||
|
||||
d3d12CommandBuffer->vertexStorageBuffers[firstSlot + i] = container->activeBuffer;
|
||||
d3d12CommandBuffer->vertexStorageBufferDescriptorHandles[firstSlot + i] = container->activeBuffer->srvDescriptor.cpuHandle;
|
||||
d3d12CommandBuffer->needVertexStorageBufferBind = true;
|
||||
}
|
||||
}
|
||||
@@ -4785,21 +4814,21 @@ static void D3D12_BindFragmentSamplers(
|
||||
D3D12TextureContainer *container = (D3D12TextureContainer *)textureSamplerBindings[i].texture;
|
||||
D3D12Sampler *sampler = (D3D12Sampler *)textureSamplerBindings[i].sampler;
|
||||
|
||||
if (d3d12CommandBuffer->fragmentSamplers[firstSlot + i] != sampler) {
|
||||
if (d3d12CommandBuffer->fragmentSamplerDescriptorHandles[firstSlot + i].ptr != sampler->handle.cpuHandle.ptr) {
|
||||
D3D12_INTERNAL_TrackSampler(
|
||||
d3d12CommandBuffer,
|
||||
sampler);
|
||||
|
||||
d3d12CommandBuffer->fragmentSamplers[firstSlot + i] = sampler;
|
||||
d3d12CommandBuffer->fragmentSamplerDescriptorHandles[firstSlot + i] = sampler->handle.cpuHandle;
|
||||
d3d12CommandBuffer->needFragmentSamplerBind = true;
|
||||
}
|
||||
|
||||
if (d3d12CommandBuffer->fragmentSamplerTextures[firstSlot + i] != container->activeTexture) {
|
||||
if (d3d12CommandBuffer->fragmentSamplerTextureDescriptorHandles[firstSlot + i].ptr != container->activeTexture->srvHandle.cpuHandle.ptr) {
|
||||
D3D12_INTERNAL_TrackTexture(
|
||||
d3d12CommandBuffer,
|
||||
container->activeTexture);
|
||||
|
||||
d3d12CommandBuffer->fragmentSamplerTextures[firstSlot + i] = container->activeTexture;
|
||||
d3d12CommandBuffer->fragmentSamplerTextureDescriptorHandles[firstSlot + i] = container->activeTexture->srvHandle.cpuHandle;
|
||||
d3d12CommandBuffer->needFragmentSamplerBind = true;
|
||||
}
|
||||
}
|
||||
@@ -4817,10 +4846,10 @@ static void D3D12_BindFragmentStorageTextures(
|
||||
D3D12TextureContainer *container = (D3D12TextureContainer *)storageTextures[i];
|
||||
D3D12Texture *texture = container->activeTexture;
|
||||
|
||||
if (d3d12CommandBuffer->fragmentStorageTextures[firstSlot + i] != texture) {
|
||||
if (d3d12CommandBuffer->fragmentStorageTextureDescriptorHandles[firstSlot + i].ptr != texture->srvHandle.cpuHandle.ptr) {
|
||||
D3D12_INTERNAL_TrackTexture(d3d12CommandBuffer, texture);
|
||||
|
||||
d3d12CommandBuffer->fragmentStorageTextures[firstSlot + i] = texture;
|
||||
d3d12CommandBuffer->fragmentStorageTextureDescriptorHandles[firstSlot + i] = texture->srvHandle.cpuHandle;
|
||||
d3d12CommandBuffer->needFragmentStorageTextureBind = true;
|
||||
}
|
||||
}
|
||||
@@ -4837,12 +4866,12 @@ static void D3D12_BindFragmentStorageBuffers(
|
||||
for (Uint32 i = 0; i < numBindings; i += 1) {
|
||||
D3D12BufferContainer *container = (D3D12BufferContainer *)storageBuffers[i];
|
||||
|
||||
if (d3d12CommandBuffer->fragmentStorageBuffers[firstSlot + i] != container->activeBuffer) {
|
||||
if (d3d12CommandBuffer->fragmentStorageBufferDescriptorHandles[firstSlot + i].ptr != container->activeBuffer->srvDescriptor.cpuHandle.ptr) {
|
||||
D3D12_INTERNAL_TrackBuffer(
|
||||
d3d12CommandBuffer,
|
||||
container->activeBuffer);
|
||||
|
||||
d3d12CommandBuffer->fragmentStorageBuffers[firstSlot + i] = container->activeBuffer;
|
||||
d3d12CommandBuffer->fragmentStorageBufferDescriptorHandles[firstSlot + i] = container->activeBuffer->srvDescriptor.cpuHandle;
|
||||
d3d12CommandBuffer->needFragmentStorageBufferBind = true;
|
||||
}
|
||||
}
|
||||
@@ -4923,15 +4952,19 @@ static void D3D12_INTERNAL_WriteGPUDescriptors(
|
||||
gpuBaseDescriptor->ptr = heap->descriptorHeapGPUStart.ptr + (heap->currentDescriptorIndex * heap->descriptorSize);
|
||||
|
||||
for (Uint32 i = 0; i < resourceHandleCount; i += 1) {
|
||||
ID3D12Device_CopyDescriptorsSimple(
|
||||
commandBuffer->renderer->device,
|
||||
1,
|
||||
gpuHeapCpuHandle,
|
||||
resourceDescriptorHandles[i],
|
||||
heapType);
|
||||
// This will crash the driver if it gets a null handle! Cool!
|
||||
if (resourceDescriptorHandles[i].ptr != 0)
|
||||
{
|
||||
ID3D12Device_CopyDescriptorsSimple(
|
||||
commandBuffer->renderer->device,
|
||||
1,
|
||||
gpuHeapCpuHandle,
|
||||
resourceDescriptorHandles[i],
|
||||
heapType);
|
||||
|
||||
heap->currentDescriptorIndex += 1;
|
||||
gpuHeapCpuHandle.ptr += heap->descriptorSize;
|
||||
heap->currentDescriptorIndex += 1;
|
||||
gpuHeapCpuHandle.ptr += heap->descriptorSize;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4961,19 +4994,21 @@ static void D3D12_INTERNAL_BindGraphicsResources(
|
||||
0,
|
||||
commandBuffer->vertexBufferCount,
|
||||
vertexBufferViews);
|
||||
|
||||
commandBuffer->needVertexBufferBind = false;
|
||||
}
|
||||
|
||||
if (commandBuffer->needVertexSamplerBind) {
|
||||
if (graphicsPipeline->vertexSamplerCount > 0) {
|
||||
for (Uint32 i = 0; i < graphicsPipeline->vertexSamplerCount; i += 1) {
|
||||
cpuHandles[i] = commandBuffer->vertexSamplers[i]->handle.cpuHandle;
|
||||
if (graphicsPipeline->header.num_vertex_samplers > 0) {
|
||||
for (Uint32 i = 0; i < graphicsPipeline->header.num_vertex_samplers; i += 1) {
|
||||
cpuHandles[i] = commandBuffer->vertexSamplerDescriptorHandles[i];
|
||||
}
|
||||
|
||||
D3D12_INTERNAL_WriteGPUDescriptors(
|
||||
commandBuffer,
|
||||
D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER,
|
||||
cpuHandles,
|
||||
graphicsPipeline->vertexSamplerCount,
|
||||
graphicsPipeline->header.num_vertex_samplers,
|
||||
&gpuDescriptorHandle);
|
||||
|
||||
ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable(
|
||||
@@ -4981,15 +5016,15 @@ static void D3D12_INTERNAL_BindGraphicsResources(
|
||||
graphicsPipeline->rootSignature->vertexSamplerRootIndex,
|
||||
gpuDescriptorHandle);
|
||||
|
||||
for (Uint32 i = 0; i < graphicsPipeline->vertexSamplerCount; i += 1) {
|
||||
cpuHandles[i] = commandBuffer->vertexSamplerTextures[i]->srvHandle.cpuHandle;
|
||||
for (Uint32 i = 0; i < graphicsPipeline->header.num_vertex_samplers; i += 1) {
|
||||
cpuHandles[i] = commandBuffer->vertexSamplerTextureDescriptorHandles[i];
|
||||
}
|
||||
|
||||
D3D12_INTERNAL_WriteGPUDescriptors(
|
||||
commandBuffer,
|
||||
D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV,
|
||||
cpuHandles,
|
||||
graphicsPipeline->vertexSamplerCount,
|
||||
graphicsPipeline->header.num_vertex_samplers,
|
||||
&gpuDescriptorHandle);
|
||||
|
||||
ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable(
|
||||
@@ -5001,16 +5036,16 @@ static void D3D12_INTERNAL_BindGraphicsResources(
|
||||
}
|
||||
|
||||
if (commandBuffer->needVertexStorageTextureBind) {
|
||||
if (graphicsPipeline->vertexStorageTextureCount > 0) {
|
||||
for (Uint32 i = 0; i < graphicsPipeline->vertexStorageTextureCount; i += 1) {
|
||||
cpuHandles[i] = commandBuffer->vertexStorageTextures[i]->srvHandle.cpuHandle;
|
||||
if (graphicsPipeline->header.num_vertex_storage_textures > 0) {
|
||||
for (Uint32 i = 0; i < graphicsPipeline->header.num_vertex_storage_textures; i += 1) {
|
||||
cpuHandles[i] = commandBuffer->vertexStorageTextureDescriptorHandles[i];
|
||||
}
|
||||
|
||||
D3D12_INTERNAL_WriteGPUDescriptors(
|
||||
commandBuffer,
|
||||
D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV,
|
||||
cpuHandles,
|
||||
graphicsPipeline->vertexStorageTextureCount,
|
||||
graphicsPipeline->header.num_vertex_storage_textures,
|
||||
&gpuDescriptorHandle);
|
||||
|
||||
ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable(
|
||||
@@ -5022,16 +5057,16 @@ static void D3D12_INTERNAL_BindGraphicsResources(
|
||||
}
|
||||
|
||||
if (commandBuffer->needVertexStorageBufferBind) {
|
||||
if (graphicsPipeline->vertexStorageBufferCount > 0) {
|
||||
for (Uint32 i = 0; i < graphicsPipeline->vertexStorageBufferCount; i += 1) {
|
||||
cpuHandles[i] = commandBuffer->vertexStorageBuffers[i]->srvDescriptor.cpuHandle;
|
||||
if (graphicsPipeline->header.num_vertex_storage_buffers > 0) {
|
||||
for (Uint32 i = 0; i < graphicsPipeline->header.num_vertex_storage_buffers; i += 1) {
|
||||
cpuHandles[i] = commandBuffer->vertexStorageBufferDescriptorHandles[i];
|
||||
}
|
||||
|
||||
D3D12_INTERNAL_WriteGPUDescriptors(
|
||||
commandBuffer,
|
||||
D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV,
|
||||
cpuHandles,
|
||||
graphicsPipeline->vertexStorageBufferCount,
|
||||
graphicsPipeline->header.num_vertex_storage_buffers,
|
||||
&gpuDescriptorHandle);
|
||||
|
||||
ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable(
|
||||
@@ -5044,7 +5079,7 @@ static void D3D12_INTERNAL_BindGraphicsResources(
|
||||
|
||||
for (Uint32 i = 0; i < MAX_UNIFORM_BUFFERS_PER_STAGE; i += 1) {
|
||||
if (commandBuffer->needVertexUniformBufferBind[i]) {
|
||||
if (graphicsPipeline->vertexUniformBufferCount > i) {
|
||||
if (graphicsPipeline->header.num_vertex_uniform_buffers > i) {
|
||||
ID3D12GraphicsCommandList_SetGraphicsRootConstantBufferView(
|
||||
commandBuffer->graphicsCommandList,
|
||||
graphicsPipeline->rootSignature->vertexUniformBufferRootIndex[i],
|
||||
@@ -5055,16 +5090,16 @@ static void D3D12_INTERNAL_BindGraphicsResources(
|
||||
}
|
||||
|
||||
if (commandBuffer->needFragmentSamplerBind) {
|
||||
if (graphicsPipeline->fragmentSamplerCount > 0) {
|
||||
for (Uint32 i = 0; i < graphicsPipeline->fragmentSamplerCount; i += 1) {
|
||||
cpuHandles[i] = commandBuffer->fragmentSamplers[i]->handle.cpuHandle;
|
||||
if (graphicsPipeline->header.num_fragment_samplers > 0) {
|
||||
for (Uint32 i = 0; i < graphicsPipeline->header.num_fragment_samplers; i += 1) {
|
||||
cpuHandles[i] = commandBuffer->fragmentSamplerDescriptorHandles[i];
|
||||
}
|
||||
|
||||
D3D12_INTERNAL_WriteGPUDescriptors(
|
||||
commandBuffer,
|
||||
D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER,
|
||||
cpuHandles,
|
||||
graphicsPipeline->fragmentSamplerCount,
|
||||
graphicsPipeline->header.num_fragment_samplers,
|
||||
&gpuDescriptorHandle);
|
||||
|
||||
ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable(
|
||||
@@ -5072,15 +5107,15 @@ static void D3D12_INTERNAL_BindGraphicsResources(
|
||||
graphicsPipeline->rootSignature->fragmentSamplerRootIndex,
|
||||
gpuDescriptorHandle);
|
||||
|
||||
for (Uint32 i = 0; i < graphicsPipeline->fragmentSamplerCount; i += 1) {
|
||||
cpuHandles[i] = commandBuffer->fragmentSamplerTextures[i]->srvHandle.cpuHandle;
|
||||
for (Uint32 i = 0; i < graphicsPipeline->header.num_fragment_samplers; i += 1) {
|
||||
cpuHandles[i] = commandBuffer->fragmentSamplerTextureDescriptorHandles[i];
|
||||
}
|
||||
|
||||
D3D12_INTERNAL_WriteGPUDescriptors(
|
||||
commandBuffer,
|
||||
D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV,
|
||||
cpuHandles,
|
||||
graphicsPipeline->fragmentSamplerCount,
|
||||
graphicsPipeline->header.num_fragment_samplers,
|
||||
&gpuDescriptorHandle);
|
||||
|
||||
ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable(
|
||||
@@ -5092,16 +5127,16 @@ static void D3D12_INTERNAL_BindGraphicsResources(
|
||||
}
|
||||
|
||||
if (commandBuffer->needFragmentStorageTextureBind) {
|
||||
if (graphicsPipeline->fragmentStorageTextureCount > 0) {
|
||||
for (Uint32 i = 0; i < graphicsPipeline->fragmentStorageTextureCount; i += 1) {
|
||||
cpuHandles[i] = commandBuffer->fragmentStorageTextures[i]->srvHandle.cpuHandle;
|
||||
if (graphicsPipeline->header.num_fragment_storage_textures > 0) {
|
||||
for (Uint32 i = 0; i < graphicsPipeline->header.num_fragment_storage_textures; i += 1) {
|
||||
cpuHandles[i] = commandBuffer->fragmentStorageTextureDescriptorHandles[i];
|
||||
}
|
||||
|
||||
D3D12_INTERNAL_WriteGPUDescriptors(
|
||||
commandBuffer,
|
||||
D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV,
|
||||
cpuHandles,
|
||||
graphicsPipeline->fragmentStorageTextureCount,
|
||||
graphicsPipeline->header.num_fragment_storage_textures,
|
||||
&gpuDescriptorHandle);
|
||||
|
||||
ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable(
|
||||
@@ -5113,16 +5148,16 @@ static void D3D12_INTERNAL_BindGraphicsResources(
|
||||
}
|
||||
|
||||
if (commandBuffer->needFragmentStorageBufferBind) {
|
||||
if (graphicsPipeline->fragmentStorageBufferCount > 0) {
|
||||
for (Uint32 i = 0; i < graphicsPipeline->fragmentStorageBufferCount; i += 1) {
|
||||
cpuHandles[i] = commandBuffer->fragmentStorageBuffers[i]->srvDescriptor.cpuHandle;
|
||||
if (graphicsPipeline->header.num_fragment_storage_buffers > 0) {
|
||||
for (Uint32 i = 0; i < graphicsPipeline->header.num_fragment_storage_buffers; i += 1) {
|
||||
cpuHandles[i] = commandBuffer->fragmentStorageBufferDescriptorHandles[i];
|
||||
}
|
||||
|
||||
D3D12_INTERNAL_WriteGPUDescriptors(
|
||||
commandBuffer,
|
||||
D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV,
|
||||
cpuHandles,
|
||||
graphicsPipeline->fragmentStorageBufferCount,
|
||||
graphicsPipeline->header.num_fragment_storage_buffers,
|
||||
&gpuDescriptorHandle);
|
||||
|
||||
ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable(
|
||||
@@ -5135,7 +5170,7 @@ static void D3D12_INTERNAL_BindGraphicsResources(
|
||||
|
||||
for (Uint32 i = 0; i < MAX_UNIFORM_BUFFERS_PER_STAGE; i += 1) {
|
||||
if (commandBuffer->needFragmentUniformBufferBind[i]) {
|
||||
if (graphicsPipeline->fragmentUniformBufferCount > i) {
|
||||
if (graphicsPipeline->header.num_fragment_uniform_buffers > i) {
|
||||
ID3D12GraphicsCommandList_SetGraphicsRootConstantBufferView(
|
||||
commandBuffer->graphicsCommandList,
|
||||
graphicsPipeline->rootSignature->fragmentUniformBufferRootIndex[i],
|
||||
@@ -5300,15 +5335,15 @@ static void D3D12_EndRenderPass(
|
||||
SDL_zeroa(d3d12CommandBuffer->vertexBufferOffsets);
|
||||
d3d12CommandBuffer->vertexBufferCount = 0;
|
||||
|
||||
SDL_zeroa(d3d12CommandBuffer->vertexSamplerTextures);
|
||||
SDL_zeroa(d3d12CommandBuffer->vertexSamplers);
|
||||
SDL_zeroa(d3d12CommandBuffer->vertexStorageTextures);
|
||||
SDL_zeroa(d3d12CommandBuffer->vertexStorageBuffers);
|
||||
SDL_zeroa(d3d12CommandBuffer->vertexSamplerTextureDescriptorHandles);
|
||||
SDL_zeroa(d3d12CommandBuffer->vertexSamplerDescriptorHandles);
|
||||
SDL_zeroa(d3d12CommandBuffer->vertexStorageTextureDescriptorHandles);
|
||||
SDL_zeroa(d3d12CommandBuffer->vertexStorageBufferDescriptorHandles);
|
||||
|
||||
SDL_zeroa(d3d12CommandBuffer->fragmentSamplerTextures);
|
||||
SDL_zeroa(d3d12CommandBuffer->fragmentSamplers);
|
||||
SDL_zeroa(d3d12CommandBuffer->fragmentStorageTextures);
|
||||
SDL_zeroa(d3d12CommandBuffer->fragmentStorageBuffers);
|
||||
SDL_zeroa(d3d12CommandBuffer->fragmentSamplerTextureDescriptorHandles);
|
||||
SDL_zeroa(d3d12CommandBuffer->fragmentSamplerDescriptorHandles);
|
||||
SDL_zeroa(d3d12CommandBuffer->fragmentStorageTextureDescriptorHandles);
|
||||
SDL_zeroa(d3d12CommandBuffer->fragmentStorageBufferDescriptorHandles);
|
||||
}
|
||||
|
||||
// Compute Pass
|
||||
@@ -5342,6 +5377,7 @@ static void D3D12_BeginComputePass(
|
||||
D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
|
||||
|
||||
d3d12CommandBuffer->computeReadWriteStorageTextureSubresources[i] = subresource;
|
||||
d3d12CommandBuffer->computeReadWriteStorageTextureDescriptorHandles[i] = subresource->uavHandle.cpuHandle;
|
||||
|
||||
D3D12_INTERNAL_TrackTexture(
|
||||
d3d12CommandBuffer,
|
||||
@@ -5360,6 +5396,7 @@ static void D3D12_BeginComputePass(
|
||||
D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
|
||||
|
||||
d3d12CommandBuffer->computeReadWriteStorageBuffers[i] = buffer;
|
||||
d3d12CommandBuffer->computeReadWriteStorageBufferDescriptorHandles[i] = buffer->uavDescriptor.cpuHandle;
|
||||
|
||||
D3D12_INTERNAL_TrackBuffer(
|
||||
d3d12CommandBuffer,
|
||||
@@ -5401,7 +5438,7 @@ static void D3D12_BindComputePipeline(
|
||||
d3d12CommandBuffer->needComputeUniformBufferBind[i] = true;
|
||||
}
|
||||
|
||||
for (Uint32 i = 0; i < pipeline->numUniformBuffers; i += 1) {
|
||||
for (Uint32 i = 0; i < pipeline->header.numUniformBuffers; i += 1) {
|
||||
if (d3d12CommandBuffer->computeUniformBuffers[i] == NULL) {
|
||||
d3d12CommandBuffer->computeUniformBuffers[i] = D3D12_INTERNAL_AcquireUniformBufferFromPool(
|
||||
d3d12CommandBuffer);
|
||||
@@ -5411,9 +5448,9 @@ static void D3D12_BindComputePipeline(
|
||||
D3D12_INTERNAL_TrackComputePipeline(d3d12CommandBuffer, pipeline);
|
||||
|
||||
// Bind write-only resources after setting root signature
|
||||
if (pipeline->numReadWriteStorageTextures > 0) {
|
||||
for (Uint32 i = 0; i < pipeline->numReadWriteStorageTextures; i += 1) {
|
||||
cpuHandles[i] = d3d12CommandBuffer->computeReadWriteStorageTextureSubresources[i]->uavHandle.cpuHandle;
|
||||
if (pipeline->header.numReadWriteStorageTextures > 0) {
|
||||
for (Uint32 i = 0; i < pipeline->header.numReadWriteStorageTextures; i += 1) {
|
||||
cpuHandles[i] = d3d12CommandBuffer->computeReadWriteStorageTextureDescriptorHandles[i];
|
||||
}
|
||||
|
||||
D3D12_INTERNAL_WriteGPUDescriptors(
|
||||
@@ -5429,9 +5466,9 @@ static void D3D12_BindComputePipeline(
|
||||
gpuDescriptorHandle);
|
||||
}
|
||||
|
||||
if (pipeline->numReadWriteStorageBuffers > 0) {
|
||||
for (Uint32 i = 0; i < pipeline->numReadWriteStorageBuffers; i += 1) {
|
||||
cpuHandles[i] = d3d12CommandBuffer->computeReadWriteStorageBuffers[i]->uavDescriptor.cpuHandle;
|
||||
if (pipeline->header.numReadWriteStorageBuffers > 0) {
|
||||
for (Uint32 i = 0; i < pipeline->header.numReadWriteStorageBuffers; i += 1) {
|
||||
cpuHandles[i] = d3d12CommandBuffer->computeReadWriteStorageBufferDescriptorHandles[i];
|
||||
}
|
||||
|
||||
D3D12_INTERNAL_WriteGPUDescriptors(
|
||||
@@ -5460,21 +5497,21 @@ static void D3D12_BindComputeSamplers(
|
||||
D3D12TextureContainer *container = (D3D12TextureContainer *)textureSamplerBindings[i].texture;
|
||||
D3D12Sampler *sampler = (D3D12Sampler *)textureSamplerBindings[i].sampler;
|
||||
|
||||
if (d3d12CommandBuffer->computeSamplers[firstSlot + i] != sampler) {
|
||||
if (d3d12CommandBuffer->computeSamplerDescriptorHandles[firstSlot + i].ptr != sampler->handle.cpuHandle.ptr) {
|
||||
D3D12_INTERNAL_TrackSampler(
|
||||
d3d12CommandBuffer,
|
||||
(D3D12Sampler *)textureSamplerBindings[i].sampler);
|
||||
|
||||
d3d12CommandBuffer->computeSamplers[firstSlot + i] = (D3D12Sampler *)textureSamplerBindings[i].sampler;
|
||||
d3d12CommandBuffer->computeSamplerDescriptorHandles[firstSlot + i] = sampler->handle.cpuHandle;
|
||||
d3d12CommandBuffer->needComputeSamplerBind = true;
|
||||
}
|
||||
|
||||
if (d3d12CommandBuffer->computeSamplerTextures[firstSlot + i] != container->activeTexture) {
|
||||
if (d3d12CommandBuffer->computeSamplerTextureDescriptorHandles[firstSlot + i].ptr != container->activeTexture->srvHandle.cpuHandle.ptr) {
|
||||
D3D12_INTERNAL_TrackTexture(
|
||||
d3d12CommandBuffer,
|
||||
container->activeTexture);
|
||||
|
||||
d3d12CommandBuffer->computeSamplerTextures[firstSlot + i] = container->activeTexture;
|
||||
d3d12CommandBuffer->computeSamplerTextureDescriptorHandles[firstSlot + i] = container->activeTexture->srvHandle.cpuHandle;
|
||||
d3d12CommandBuffer->needComputeSamplerBind = true;
|
||||
}
|
||||
}
|
||||
@@ -5511,6 +5548,7 @@ static void D3D12_BindComputeStorageTextures(
|
||||
container->activeTexture);
|
||||
|
||||
d3d12CommandBuffer->computeReadOnlyStorageTextures[firstSlot + i] = container->activeTexture;
|
||||
d3d12CommandBuffer->computeReadOnlyStorageTextureDescriptorHandles[firstSlot + i] = container->activeTexture->srvHandle.cpuHandle;
|
||||
d3d12CommandBuffer->needComputeReadOnlyStorageTextureBind = true;
|
||||
}
|
||||
}
|
||||
@@ -5548,6 +5586,7 @@ static void D3D12_BindComputeStorageBuffers(
|
||||
buffer);
|
||||
|
||||
d3d12CommandBuffer->computeReadOnlyStorageBuffers[firstSlot + i] = buffer;
|
||||
d3d12CommandBuffer->computeReadOnlyStorageBufferDescriptorHandles[firstSlot + i] = buffer->srvDescriptor.cpuHandle;
|
||||
d3d12CommandBuffer->needComputeReadOnlyStorageBufferBind = true;
|
||||
}
|
||||
}
|
||||
@@ -5583,16 +5622,16 @@ static void D3D12_INTERNAL_BindComputeResources(
|
||||
D3D12_GPU_DESCRIPTOR_HANDLE gpuDescriptorHandle;
|
||||
|
||||
if (commandBuffer->needComputeSamplerBind) {
|
||||
if (computePipeline->numSamplers > 0) {
|
||||
for (Uint32 i = 0; i < computePipeline->numSamplers; i += 1) {
|
||||
cpuHandles[i] = commandBuffer->computeSamplers[i]->handle.cpuHandle;
|
||||
if (computePipeline->header.numSamplers > 0) {
|
||||
for (Uint32 i = 0; i < computePipeline->header.numSamplers; i += 1) {
|
||||
cpuHandles[i] = commandBuffer->computeSamplerDescriptorHandles[i];
|
||||
}
|
||||
|
||||
D3D12_INTERNAL_WriteGPUDescriptors(
|
||||
commandBuffer,
|
||||
D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER,
|
||||
cpuHandles,
|
||||
computePipeline->numSamplers,
|
||||
computePipeline->header.numSamplers,
|
||||
&gpuDescriptorHandle);
|
||||
|
||||
ID3D12GraphicsCommandList_SetComputeRootDescriptorTable(
|
||||
@@ -5600,15 +5639,15 @@ static void D3D12_INTERNAL_BindComputeResources(
|
||||
computePipeline->rootSignature->samplerRootIndex,
|
||||
gpuDescriptorHandle);
|
||||
|
||||
for (Uint32 i = 0; i < computePipeline->numSamplers; i += 1) {
|
||||
cpuHandles[i] = commandBuffer->computeSamplerTextures[i]->srvHandle.cpuHandle;
|
||||
for (Uint32 i = 0; i < computePipeline->header.numSamplers; i += 1) {
|
||||
cpuHandles[i] = commandBuffer->computeSamplerTextureDescriptorHandles[i];
|
||||
}
|
||||
|
||||
D3D12_INTERNAL_WriteGPUDescriptors(
|
||||
commandBuffer,
|
||||
D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV,
|
||||
cpuHandles,
|
||||
computePipeline->numSamplers,
|
||||
computePipeline->header.numSamplers,
|
||||
&gpuDescriptorHandle);
|
||||
|
||||
ID3D12GraphicsCommandList_SetComputeRootDescriptorTable(
|
||||
@@ -5620,16 +5659,16 @@ static void D3D12_INTERNAL_BindComputeResources(
|
||||
}
|
||||
|
||||
if (commandBuffer->needComputeReadOnlyStorageTextureBind) {
|
||||
if (computePipeline->numReadOnlyStorageTextures > 0) {
|
||||
for (Uint32 i = 0; i < computePipeline->numReadOnlyStorageTextures; i += 1) {
|
||||
cpuHandles[i] = commandBuffer->computeReadOnlyStorageTextures[i]->srvHandle.cpuHandle;
|
||||
if (computePipeline->header.numReadonlyStorageTextures > 0) {
|
||||
for (Uint32 i = 0; i < computePipeline->header.numReadonlyStorageTextures; i += 1) {
|
||||
cpuHandles[i] = commandBuffer->computeReadOnlyStorageTextureDescriptorHandles[i];
|
||||
}
|
||||
|
||||
D3D12_INTERNAL_WriteGPUDescriptors(
|
||||
commandBuffer,
|
||||
D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV,
|
||||
cpuHandles,
|
||||
computePipeline->numReadOnlyStorageTextures,
|
||||
computePipeline->header.numReadonlyStorageTextures,
|
||||
&gpuDescriptorHandle);
|
||||
|
||||
ID3D12GraphicsCommandList_SetComputeRootDescriptorTable(
|
||||
@@ -5641,16 +5680,16 @@ static void D3D12_INTERNAL_BindComputeResources(
|
||||
}
|
||||
|
||||
if (commandBuffer->needComputeReadOnlyStorageBufferBind) {
|
||||
if (computePipeline->numReadOnlyStorageBuffers > 0) {
|
||||
for (Uint32 i = 0; i < computePipeline->numReadOnlyStorageBuffers; i += 1) {
|
||||
cpuHandles[i] = commandBuffer->computeReadOnlyStorageBuffers[i]->srvDescriptor.cpuHandle;
|
||||
if (computePipeline->header.numReadonlyStorageBuffers > 0) {
|
||||
for (Uint32 i = 0; i < computePipeline->header.numReadonlyStorageBuffers; i += 1) {
|
||||
cpuHandles[i] = commandBuffer->computeReadOnlyStorageBufferDescriptorHandles[i];
|
||||
}
|
||||
|
||||
D3D12_INTERNAL_WriteGPUDescriptors(
|
||||
commandBuffer,
|
||||
D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV,
|
||||
cpuHandles,
|
||||
computePipeline->numReadOnlyStorageBuffers,
|
||||
computePipeline->header.numReadonlyStorageBuffers,
|
||||
&gpuDescriptorHandle);
|
||||
|
||||
ID3D12GraphicsCommandList_SetComputeRootDescriptorTable(
|
||||
@@ -5663,7 +5702,7 @@ static void D3D12_INTERNAL_BindComputeResources(
|
||||
|
||||
for (Uint32 i = 0; i < MAX_UNIFORM_BUFFERS_PER_STAGE; i += 1) {
|
||||
if (commandBuffer->needComputeUniformBufferBind[i]) {
|
||||
if (computePipeline->numUniformBuffers > i) {
|
||||
if (computePipeline->header.numUniformBuffers > i) {
|
||||
ID3D12GraphicsCommandList_SetComputeRootConstantBufferView(
|
||||
commandBuffer->graphicsCommandList,
|
||||
computePipeline->rootSignature->uniformBufferRootIndex[i],
|
||||
@@ -5762,8 +5801,11 @@ static void D3D12_EndComputePass(
|
||||
}
|
||||
}
|
||||
|
||||
SDL_zeroa(d3d12CommandBuffer->computeSamplerTextures);
|
||||
SDL_zeroa(d3d12CommandBuffer->computeSamplers);
|
||||
SDL_zeroa(d3d12CommandBuffer->computeSamplerTextureDescriptorHandles);
|
||||
SDL_zeroa(d3d12CommandBuffer->computeSamplerDescriptorHandles);
|
||||
|
||||
SDL_zeroa(d3d12CommandBuffer->computeReadWriteStorageTextureDescriptorHandles);
|
||||
SDL_zeroa(d3d12CommandBuffer->computeReadWriteStorageBufferDescriptorHandles);
|
||||
|
||||
d3d12CommandBuffer->currentComputePipeline = NULL;
|
||||
}
|
||||
@@ -5911,7 +5953,7 @@ static void D3D12_UploadToTexture(
|
||||
SDL_memcpy(
|
||||
temporaryBuffer->mapPointer + (sliceIndex * rowsPerSlice) + (rowIndex * alignedRowPitch),
|
||||
transferBufferContainer->activeBuffer->mapPointer + source->offset + (sliceIndex * bytesPerSlice) + (rowIndex * rowPitch),
|
||||
alignedRowPitch);
|
||||
rowPitch);
|
||||
}
|
||||
Uint32 offset = source->offset + (sliceIndex * bytesPerSlice) + ((rowsPerSlice - 1) * rowPitch);
|
||||
SDL_memcpy(
|
||||
@@ -7267,6 +7309,11 @@ static bool D3D12_INTERNAL_AllocateCommandBuffer(
|
||||
commandBuffer->usedComputePipelines = (D3D12ComputePipeline **)SDL_calloc(
|
||||
commandBuffer->usedComputePipelineCapacity, sizeof(D3D12ComputePipeline *));
|
||||
|
||||
commandBuffer->usedDescriptorHeapCapacity = 4;
|
||||
commandBuffer->usedDescriptorHeapCount = 0;
|
||||
commandBuffer->usedDescriptorHeaps = (D3D12DescriptorHeap **)SDL_calloc(
|
||||
commandBuffer->usedDescriptorHeapCapacity, sizeof(D3D12DescriptorHeap *));
|
||||
|
||||
commandBuffer->usedUniformBufferCapacity = 4;
|
||||
commandBuffer->usedUniformBufferCount = 0;
|
||||
commandBuffer->usedUniformBuffers = (D3D12UniformBuffer **)SDL_calloc(
|
||||
@@ -7352,20 +7399,22 @@ static SDL_GPUCommandBuffer *D3D12_AcquireCommandBuffer(
|
||||
SDL_zeroa(commandBuffer->vertexBufferOffsets);
|
||||
commandBuffer->vertexBufferCount = 0;
|
||||
|
||||
SDL_zeroa(commandBuffer->vertexSamplerTextures);
|
||||
SDL_zeroa(commandBuffer->vertexSamplers);
|
||||
SDL_zeroa(commandBuffer->vertexStorageTextures);
|
||||
SDL_zeroa(commandBuffer->vertexStorageBuffers);
|
||||
SDL_zeroa(commandBuffer->vertexSamplerTextureDescriptorHandles);
|
||||
SDL_zeroa(commandBuffer->vertexSamplerDescriptorHandles);
|
||||
SDL_zeroa(commandBuffer->vertexStorageTextureDescriptorHandles);
|
||||
SDL_zeroa(commandBuffer->vertexStorageBufferDescriptorHandles);
|
||||
SDL_zeroa(commandBuffer->vertexUniformBuffers);
|
||||
|
||||
SDL_zeroa(commandBuffer->fragmentSamplerTextures);
|
||||
SDL_zeroa(commandBuffer->fragmentSamplers);
|
||||
SDL_zeroa(commandBuffer->fragmentStorageTextures);
|
||||
SDL_zeroa(commandBuffer->fragmentStorageBuffers);
|
||||
SDL_zeroa(commandBuffer->fragmentSamplerTextureDescriptorHandles);
|
||||
SDL_zeroa(commandBuffer->fragmentSamplerDescriptorHandles);
|
||||
SDL_zeroa(commandBuffer->fragmentStorageTextureDescriptorHandles);
|
||||
SDL_zeroa(commandBuffer->fragmentStorageBufferDescriptorHandles);
|
||||
SDL_zeroa(commandBuffer->fragmentUniformBuffers);
|
||||
|
||||
SDL_zeroa(commandBuffer->computeSamplerTextures);
|
||||
SDL_zeroa(commandBuffer->computeSamplers);
|
||||
SDL_zeroa(commandBuffer->computeSamplerTextureDescriptorHandles);
|
||||
SDL_zeroa(commandBuffer->computeSamplerDescriptorHandles);
|
||||
SDL_zeroa(commandBuffer->computeReadOnlyStorageTextureDescriptorHandles);
|
||||
SDL_zeroa(commandBuffer->computeReadOnlyStorageBufferDescriptorHandles);
|
||||
SDL_zeroa(commandBuffer->computeReadOnlyStorageTextures);
|
||||
SDL_zeroa(commandBuffer->computeReadOnlyStorageBuffers);
|
||||
SDL_zeroa(commandBuffer->computeReadWriteStorageTextureSubresources);
|
||||
@@ -7686,13 +7735,13 @@ static bool D3D12_INTERNAL_CleanCommandBuffer(
|
||||
NULL);
|
||||
CHECK_D3D12_ERROR_AND_RETURN("Could not reset command list", false);
|
||||
|
||||
// Return descriptor heaps to pool
|
||||
D3D12_INTERNAL_ReturnGPUDescriptorHeapToPool(
|
||||
renderer,
|
||||
commandBuffer->gpuDescriptorHeaps[D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV]);
|
||||
D3D12_INTERNAL_ReturnGPUDescriptorHeapToPool(
|
||||
renderer,
|
||||
commandBuffer->gpuDescriptorHeaps[D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER]);
|
||||
// Return descriptor heaps to pool, pools own their own locks
|
||||
for (i = 0; i < commandBuffer->usedDescriptorHeapCount; i += 1) {
|
||||
D3D12_INTERNAL_ReturnGPUDescriptorHeapToPool(
|
||||
renderer,
|
||||
commandBuffer->usedDescriptorHeaps[i]);
|
||||
}
|
||||
commandBuffer->usedDescriptorHeapCount = 0;
|
||||
|
||||
commandBuffer->gpuDescriptorHeaps[D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV] = NULL;
|
||||
commandBuffer->gpuDescriptorHeaps[D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER] = NULL;
|
||||
@@ -8338,6 +8387,7 @@ static bool D3D12_PrepareDriver(SDL_VideoDevice *_this)
|
||||
IDXGIFactory4 *factory4;
|
||||
IDXGIFactory6 *factory6;
|
||||
IDXGIAdapter1 *adapter;
|
||||
bool supports_64UAVs = false;
|
||||
|
||||
// Can we load D3D12?
|
||||
|
||||
@@ -8426,12 +8476,39 @@ static bool D3D12_PrepareDriver(SDL_VideoDevice *_this)
|
||||
return false;
|
||||
}
|
||||
|
||||
SDL_COMPILE_TIME_ASSERT(featurelevel, D3D_FEATURE_LEVEL_CHOICE < D3D_FEATURE_LEVEL_11_1);
|
||||
|
||||
// Check feature level 11_1 first, guarantees 64+ UAVs unlike 11_0 Tier1
|
||||
res = D3D12CreateDeviceFunc(
|
||||
(IUnknown *)adapter,
|
||||
D3D_FEATURE_LEVEL_CHOICE,
|
||||
D3D_FEATURE_LEVEL_11_1,
|
||||
D3D_GUID(D3D_IID_ID3D12Device),
|
||||
(void **)&device);
|
||||
|
||||
if (SUCCEEDED(res)) {
|
||||
supports_64UAVs = true;
|
||||
} else {
|
||||
res = D3D12CreateDeviceFunc(
|
||||
(IUnknown *)adapter,
|
||||
D3D_FEATURE_LEVEL_CHOICE,
|
||||
D3D_GUID(D3D_IID_ID3D12Device),
|
||||
(void **)&device);
|
||||
|
||||
if (SUCCEEDED(res)) {
|
||||
D3D12_FEATURE_DATA_D3D12_OPTIONS featureOptions;
|
||||
SDL_zero(featureOptions);
|
||||
|
||||
res = ID3D12Device_CheckFeatureSupport(
|
||||
device,
|
||||
D3D12_FEATURE_D3D12_OPTIONS,
|
||||
&featureOptions,
|
||||
sizeof(featureOptions));
|
||||
if (SUCCEEDED(res) && featureOptions.ResourceBindingTier >= D3D12_RESOURCE_BINDING_TIER_2) {
|
||||
supports_64UAVs = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (SUCCEEDED(res)) {
|
||||
ID3D12Device_Release(device);
|
||||
}
|
||||
@@ -8441,6 +8518,11 @@ static bool D3D12_PrepareDriver(SDL_VideoDevice *_this)
|
||||
SDL_UnloadObject(d3d12Dll);
|
||||
SDL_UnloadObject(dxgiDll);
|
||||
|
||||
if (!supports_64UAVs) {
|
||||
SDL_LogWarn(SDL_LOG_CATEGORY_GPU, "D3D12: Tier 2 Resource binding is not supported");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (FAILED(res)) {
|
||||
SDL_LogWarn(SDL_LOG_CATEGORY_GPU, "D3D12: Could not create D3D12Device with feature level " D3D_FEATURE_LEVEL_CHOICE_STR);
|
||||
return false;
|
||||
@@ -8819,6 +8901,12 @@ static SDL_GPUDevice *D3D12_CreateDevice(bool debugMode, bool preferLowPower, SD
|
||||
// Initialize the D3D12 debug layer, if applicable
|
||||
if (debugMode) {
|
||||
bool hasD3d12Debug = D3D12_INTERNAL_TryInitializeD3D12Debug(renderer);
|
||||
#if (defined(SDL_PLATFORM_XBOXONE) || defined(SDL_PLATFORM_XBOXSERIES))
|
||||
if (hasD3d12Debug) {
|
||||
SDL_LogInfo(
|
||||
SDL_LOG_CATEGORY_GPU,
|
||||
"Validation layers enabled, expect debug level performance!");
|
||||
#else
|
||||
if (hasDxgiDebug && hasD3d12Debug) {
|
||||
SDL_LogInfo(
|
||||
SDL_LOG_CATEGORY_GPU,
|
||||
@@ -8827,6 +8915,7 @@ static SDL_GPUDevice *D3D12_CreateDevice(bool debugMode, bool preferLowPower, SD
|
||||
SDL_LogWarn(
|
||||
SDL_LOG_CATEGORY_GPU,
|
||||
"Validation layers partially enabled, some warnings may not be available");
|
||||
#endif
|
||||
} else {
|
||||
SDL_LogWarn(
|
||||
SDL_LOG_CATEGORY_GPU,
|
||||
@@ -9124,7 +9213,7 @@ static SDL_GPUDevice *D3D12_CreateDevice(bool debugMode, bool preferLowPower, SD
|
||||
renderer->debug_mode = debugMode;
|
||||
renderer->allowedFramesInFlight = 2;
|
||||
|
||||
renderer->semantic = SDL_GetStringProperty(props, SDL_PROP_GPU_DEVICE_CREATE_D3D12_SEMANTIC_NAME_STRING, "TEXCOORD");
|
||||
renderer->semantic = SDL_strdup(SDL_GetStringProperty(props, SDL_PROP_GPU_DEVICE_CREATE_D3D12_SEMANTIC_NAME_STRING, "TEXCOORD"));
|
||||
|
||||
// Blit resources
|
||||
D3D12_INTERNAL_InitBlitResources(renderer);
|
||||
@@ -9159,8 +9248,23 @@ static SDL_GPUDevice *D3D12_CreateDevice(bool debugMode, bool preferLowPower, SD
|
||||
return NULL;
|
||||
}
|
||||
|
||||
SDL_GPUShaderFormat shaderFormats = SDL_GPU_SHADERFORMAT_DXBC;
|
||||
|
||||
D3D12_FEATURE_DATA_SHADER_MODEL shaderModel;
|
||||
shaderModel.HighestShaderModel = D3D_SHADER_MODEL_6_0;
|
||||
|
||||
res = ID3D12Device_CheckFeatureSupport(
|
||||
renderer->device,
|
||||
D3D12_FEATURE_SHADER_MODEL,
|
||||
&shaderModel,
|
||||
sizeof(shaderModel));
|
||||
if (SUCCEEDED(res) && shaderModel.HighestShaderModel >= D3D_SHADER_MODEL_6_0) {
|
||||
shaderFormats |= SDL_GPU_SHADERFORMAT_DXIL;
|
||||
}
|
||||
|
||||
ASSIGN_DRIVER(D3D12)
|
||||
result->driverData = (SDL_GPURenderer *)renderer;
|
||||
result->shader_formats = shaderFormats;
|
||||
result->debug_mode = debugMode;
|
||||
renderer->sdlGPUDevice = result;
|
||||
|
||||
|
||||
@@ -476,33 +476,21 @@ typedef struct MetalShader
|
||||
|
||||
typedef struct MetalGraphicsPipeline
|
||||
{
|
||||
GraphicsPipelineCommonHeader header;
|
||||
|
||||
id<MTLRenderPipelineState> handle;
|
||||
|
||||
SDL_GPURasterizerState rasterizerState;
|
||||
SDL_GPUPrimitiveType primitiveType;
|
||||
|
||||
id<MTLDepthStencilState> depth_stencil_state;
|
||||
|
||||
Uint32 vertexSamplerCount;
|
||||
Uint32 vertexUniformBufferCount;
|
||||
Uint32 vertexStorageBufferCount;
|
||||
Uint32 vertexStorageTextureCount;
|
||||
|
||||
Uint32 fragmentSamplerCount;
|
||||
Uint32 fragmentUniformBufferCount;
|
||||
Uint32 fragmentStorageBufferCount;
|
||||
Uint32 fragmentStorageTextureCount;
|
||||
} MetalGraphicsPipeline;
|
||||
|
||||
typedef struct MetalComputePipeline
|
||||
{
|
||||
ComputePipelineCommonHeader header;
|
||||
|
||||
id<MTLComputePipelineState> handle;
|
||||
Uint32 numSamplers;
|
||||
Uint32 numReadonlyStorageTextures;
|
||||
Uint32 numReadWriteStorageTextures;
|
||||
Uint32 numReadonlyStorageBuffers;
|
||||
Uint32 numReadWriteStorageBuffers;
|
||||
Uint32 numUniformBuffers;
|
||||
Uint32 threadcountX;
|
||||
Uint32 threadcountY;
|
||||
Uint32 threadcountZ;
|
||||
@@ -900,6 +888,7 @@ static void METAL_INTERNAL_DestroyTextureContainer(
|
||||
container->textures[i]->handle = nil;
|
||||
SDL_free(container->textures[i]);
|
||||
}
|
||||
SDL_DestroyProperties(container->header.info.props);
|
||||
if (container->debugName != NULL) {
|
||||
SDL_free(container->debugName);
|
||||
}
|
||||
@@ -1059,12 +1048,12 @@ static SDL_GPUComputePipeline *METAL_CreateComputePipeline(
|
||||
|
||||
pipeline = SDL_calloc(1, sizeof(MetalComputePipeline));
|
||||
pipeline->handle = handle;
|
||||
pipeline->numSamplers = createinfo->num_samplers;
|
||||
pipeline->numReadonlyStorageTextures = createinfo->num_readonly_storage_textures;
|
||||
pipeline->numReadWriteStorageTextures = createinfo->num_readwrite_storage_textures;
|
||||
pipeline->numReadonlyStorageBuffers = createinfo->num_readonly_storage_buffers;
|
||||
pipeline->numReadWriteStorageBuffers = createinfo->num_readwrite_storage_buffers;
|
||||
pipeline->numUniformBuffers = createinfo->num_uniform_buffers;
|
||||
pipeline->header.numSamplers = createinfo->num_samplers;
|
||||
pipeline->header.numReadonlyStorageTextures = createinfo->num_readonly_storage_textures;
|
||||
pipeline->header.numReadWriteStorageTextures = createinfo->num_readwrite_storage_textures;
|
||||
pipeline->header.numReadonlyStorageBuffers = createinfo->num_readonly_storage_buffers;
|
||||
pipeline->header.numReadWriteStorageBuffers = createinfo->num_readwrite_storage_buffers;
|
||||
pipeline->header.numUniformBuffers = createinfo->num_uniform_buffers;
|
||||
pipeline->threadcountX = createinfo->threadcount_x;
|
||||
pipeline->threadcountY = createinfo->threadcount_y;
|
||||
pipeline->threadcountZ = createinfo->threadcount_z;
|
||||
@@ -1207,14 +1196,14 @@ static SDL_GPUGraphicsPipeline *METAL_CreateGraphicsPipeline(
|
||||
result->depth_stencil_state = depthStencilState;
|
||||
result->rasterizerState = createinfo->rasterizer_state;
|
||||
result->primitiveType = createinfo->primitive_type;
|
||||
result->vertexSamplerCount = vertexShader->numSamplers;
|
||||
result->vertexUniformBufferCount = vertexShader->numUniformBuffers;
|
||||
result->vertexStorageBufferCount = vertexShader->numStorageBuffers;
|
||||
result->vertexStorageTextureCount = vertexShader->numStorageTextures;
|
||||
result->fragmentSamplerCount = fragmentShader->numSamplers;
|
||||
result->fragmentUniformBufferCount = fragmentShader->numUniformBuffers;
|
||||
result->fragmentStorageBufferCount = fragmentShader->numStorageBuffers;
|
||||
result->fragmentStorageTextureCount = fragmentShader->numStorageTextures;
|
||||
result->header.num_vertex_samplers = vertexShader->numSamplers;
|
||||
result->header.num_vertex_uniform_buffers = vertexShader->numUniformBuffers;
|
||||
result->header.num_vertex_storage_buffers = vertexShader->numStorageBuffers;
|
||||
result->header.num_vertex_storage_textures = vertexShader->numStorageTextures;
|
||||
result->header.num_fragment_samplers = fragmentShader->numSamplers;
|
||||
result->header.num_fragment_uniform_buffers = fragmentShader->numUniformBuffers;
|
||||
result->header.num_fragment_storage_buffers = fragmentShader->numStorageBuffers;
|
||||
result->header.num_fragment_storage_textures = fragmentShader->numStorageTextures;
|
||||
return (SDL_GPUGraphicsPipeline *)result;
|
||||
}
|
||||
}
|
||||
@@ -1789,7 +1778,8 @@ static void METAL_UploadToTexture(
|
||||
copyFromBuffer:bufferContainer->activeBuffer->handle
|
||||
sourceOffset:source->offset
|
||||
sourceBytesPerRow:BytesPerRow(destination->w, textureContainer->header.info.format)
|
||||
sourceBytesPerImage:SDL_CalculateGPUTextureFormatSize(textureContainer->header.info.format, destination->w, destination->h, destination->d)
|
||||
// sourceBytesPerImage expects the stride between 2D images (slices) of a 3D texture, not the size of the entire region
|
||||
sourceBytesPerImage:SDL_CalculateGPUTextureFormatSize(textureContainer->header.info.format, destination->w, destination->h, 1)
|
||||
sourceSize:MTLSizeMake(destination->w, destination->h, destination->d)
|
||||
toTexture:metalTexture->handle
|
||||
destinationSlice:destination->layer
|
||||
@@ -2412,14 +2402,14 @@ static void METAL_BindGraphicsPipeline(
|
||||
metalCommandBuffer->needFragmentUniformBufferBind[i] = true;
|
||||
}
|
||||
|
||||
for (i = 0; i < pipeline->vertexUniformBufferCount; i += 1) {
|
||||
for (i = 0; i < pipeline->header.num_vertex_uniform_buffers; i += 1) {
|
||||
if (metalCommandBuffer->vertexUniformBuffers[i] == NULL) {
|
||||
metalCommandBuffer->vertexUniformBuffers[i] = METAL_INTERNAL_AcquireUniformBufferFromPool(
|
||||
metalCommandBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < pipeline->fragmentUniformBufferCount; i += 1) {
|
||||
for (i = 0; i < pipeline->header.num_fragment_uniform_buffers; i += 1) {
|
||||
if (metalCommandBuffer->fragmentUniformBuffers[i] == NULL) {
|
||||
metalCommandBuffer->fragmentUniformBuffers[i] = METAL_INTERNAL_AcquireUniformBufferFromPool(
|
||||
metalCommandBuffer);
|
||||
@@ -2650,11 +2640,11 @@ static void METAL_INTERNAL_BindGraphicsResources(
|
||||
// Vertex Samplers+Textures
|
||||
|
||||
if (commandBuffer->needVertexSamplerBind) {
|
||||
if (graphicsPipeline->vertexSamplerCount > 0) {
|
||||
if (graphicsPipeline->header.num_vertex_samplers > 0) {
|
||||
[commandBuffer->renderEncoder setVertexSamplerStates:commandBuffer->vertexSamplers
|
||||
withRange:NSMakeRange(0, graphicsPipeline->vertexSamplerCount)];
|
||||
withRange:NSMakeRange(0, graphicsPipeline->header.num_vertex_samplers)];
|
||||
[commandBuffer->renderEncoder setVertexTextures:commandBuffer->vertexTextures
|
||||
withRange:NSMakeRange(0, graphicsPipeline->vertexSamplerCount)];
|
||||
withRange:NSMakeRange(0, graphicsPipeline->header.num_vertex_samplers)];
|
||||
}
|
||||
commandBuffer->needVertexSamplerBind = false;
|
||||
}
|
||||
@@ -2662,10 +2652,10 @@ static void METAL_INTERNAL_BindGraphicsResources(
|
||||
// Vertex Storage Textures
|
||||
|
||||
if (commandBuffer->needVertexStorageTextureBind) {
|
||||
if (graphicsPipeline->vertexStorageTextureCount > 0) {
|
||||
if (graphicsPipeline->header.num_vertex_storage_textures > 0) {
|
||||
[commandBuffer->renderEncoder setVertexTextures:commandBuffer->vertexStorageTextures
|
||||
withRange:NSMakeRange(graphicsPipeline->vertexSamplerCount,
|
||||
graphicsPipeline->vertexStorageTextureCount)];
|
||||
withRange:NSMakeRange(graphicsPipeline->header.num_vertex_samplers,
|
||||
graphicsPipeline->header.num_vertex_storage_textures)];
|
||||
}
|
||||
commandBuffer->needVertexStorageTextureBind = false;
|
||||
}
|
||||
@@ -2673,20 +2663,20 @@ static void METAL_INTERNAL_BindGraphicsResources(
|
||||
// Vertex Storage Buffers
|
||||
|
||||
if (commandBuffer->needVertexStorageBufferBind) {
|
||||
if (graphicsPipeline->vertexStorageBufferCount > 0) {
|
||||
if (graphicsPipeline->header.num_vertex_storage_buffers > 0) {
|
||||
[commandBuffer->renderEncoder setVertexBuffers:commandBuffer->vertexStorageBuffers
|
||||
offsets:offsets
|
||||
withRange:NSMakeRange(graphicsPipeline->vertexUniformBufferCount,
|
||||
graphicsPipeline->vertexStorageBufferCount)];
|
||||
withRange:NSMakeRange(graphicsPipeline->header.num_vertex_uniform_buffers,
|
||||
graphicsPipeline->header.num_vertex_storage_buffers)];
|
||||
}
|
||||
commandBuffer->needVertexStorageBufferBind = false;
|
||||
}
|
||||
|
||||
// Vertex Uniform Buffers
|
||||
|
||||
for (Uint32 i = 0; i < graphicsPipeline->vertexUniformBufferCount; i += 1) {
|
||||
for (Uint32 i = 0; i < graphicsPipeline->header.num_vertex_uniform_buffers; i += 1) {
|
||||
if (commandBuffer->needVertexUniformBufferBind[i]) {
|
||||
if (graphicsPipeline->vertexUniformBufferCount > i) {
|
||||
if (graphicsPipeline->header.num_vertex_uniform_buffers > i) {
|
||||
[commandBuffer->renderEncoder
|
||||
setVertexBuffer:commandBuffer->vertexUniformBuffers[i]->handle
|
||||
offset:commandBuffer->vertexUniformBuffers[i]->drawOffset
|
||||
@@ -2699,11 +2689,11 @@ static void METAL_INTERNAL_BindGraphicsResources(
|
||||
// Fragment Samplers+Textures
|
||||
|
||||
if (commandBuffer->needFragmentSamplerBind) {
|
||||
if (graphicsPipeline->fragmentSamplerCount > 0) {
|
||||
if (graphicsPipeline->header.num_fragment_samplers > 0) {
|
||||
[commandBuffer->renderEncoder setFragmentSamplerStates:commandBuffer->fragmentSamplers
|
||||
withRange:NSMakeRange(0, graphicsPipeline->fragmentSamplerCount)];
|
||||
withRange:NSMakeRange(0, graphicsPipeline->header.num_fragment_samplers)];
|
||||
[commandBuffer->renderEncoder setFragmentTextures:commandBuffer->fragmentTextures
|
||||
withRange:NSMakeRange(0, graphicsPipeline->fragmentSamplerCount)];
|
||||
withRange:NSMakeRange(0, graphicsPipeline->header.num_fragment_samplers)];
|
||||
}
|
||||
commandBuffer->needFragmentSamplerBind = false;
|
||||
}
|
||||
@@ -2711,10 +2701,10 @@ static void METAL_INTERNAL_BindGraphicsResources(
|
||||
// Fragment Storage Textures
|
||||
|
||||
if (commandBuffer->needFragmentStorageTextureBind) {
|
||||
if (graphicsPipeline->fragmentStorageTextureCount > 0) {
|
||||
if (graphicsPipeline->header.num_fragment_storage_textures > 0) {
|
||||
[commandBuffer->renderEncoder setFragmentTextures:commandBuffer->fragmentStorageTextures
|
||||
withRange:NSMakeRange(graphicsPipeline->fragmentSamplerCount,
|
||||
graphicsPipeline->fragmentStorageTextureCount)];
|
||||
withRange:NSMakeRange(graphicsPipeline->header.num_fragment_samplers,
|
||||
graphicsPipeline->header.num_fragment_storage_textures)];
|
||||
}
|
||||
commandBuffer->needFragmentStorageTextureBind = false;
|
||||
}
|
||||
@@ -2722,20 +2712,20 @@ static void METAL_INTERNAL_BindGraphicsResources(
|
||||
// Fragment Storage Buffers
|
||||
|
||||
if (commandBuffer->needFragmentStorageBufferBind) {
|
||||
if (graphicsPipeline->fragmentStorageBufferCount > 0) {
|
||||
if (graphicsPipeline->header.num_fragment_storage_buffers > 0) {
|
||||
[commandBuffer->renderEncoder setFragmentBuffers:commandBuffer->fragmentStorageBuffers
|
||||
offsets:offsets
|
||||
withRange:NSMakeRange(graphicsPipeline->fragmentUniformBufferCount,
|
||||
graphicsPipeline->fragmentStorageBufferCount)];
|
||||
withRange:NSMakeRange(graphicsPipeline->header.num_fragment_uniform_buffers,
|
||||
graphicsPipeline->header.num_fragment_storage_buffers)];
|
||||
}
|
||||
commandBuffer->needFragmentStorageBufferBind = false;
|
||||
}
|
||||
|
||||
// Fragment Uniform Buffers
|
||||
|
||||
for (Uint32 i = 0; i < graphicsPipeline->fragmentUniformBufferCount; i += 1) {
|
||||
for (Uint32 i = 0; i < graphicsPipeline->header.num_fragment_uniform_buffers; i += 1) {
|
||||
if (commandBuffer->needFragmentUniformBufferBind[i]) {
|
||||
if (graphicsPipeline->fragmentUniformBufferCount > i) {
|
||||
if (graphicsPipeline->header.num_fragment_uniform_buffers > i) {
|
||||
[commandBuffer->renderEncoder
|
||||
setFragmentBuffer:commandBuffer->fragmentUniformBuffers[i]->handle
|
||||
offset:commandBuffer->fragmentUniformBuffers[i]->drawOffset
|
||||
@@ -2754,38 +2744,38 @@ static void METAL_INTERNAL_BindComputeResources(
|
||||
NSUInteger offsets[MAX_STORAGE_BUFFERS_PER_STAGE] = { 0 };
|
||||
|
||||
if (commandBuffer->needComputeSamplerBind) {
|
||||
if (computePipeline->numSamplers > 0) {
|
||||
if (computePipeline->header.numSamplers > 0) {
|
||||
[commandBuffer->computeEncoder setTextures:commandBuffer->computeSamplerTextures
|
||||
withRange:NSMakeRange(0, computePipeline->numSamplers)];
|
||||
withRange:NSMakeRange(0, computePipeline->header.numSamplers)];
|
||||
[commandBuffer->computeEncoder setSamplerStates:commandBuffer->computeSamplers
|
||||
withRange:NSMakeRange(0, computePipeline->numSamplers)];
|
||||
withRange:NSMakeRange(0, computePipeline->header.numSamplers)];
|
||||
}
|
||||
commandBuffer->needComputeSamplerBind = false;
|
||||
}
|
||||
|
||||
if (commandBuffer->needComputeReadOnlyStorageTextureBind) {
|
||||
if (computePipeline->numReadonlyStorageTextures > 0) {
|
||||
if (computePipeline->header.numReadonlyStorageTextures > 0) {
|
||||
[commandBuffer->computeEncoder setTextures:commandBuffer->computeReadOnlyTextures
|
||||
withRange:NSMakeRange(
|
||||
computePipeline->numSamplers,
|
||||
computePipeline->numReadonlyStorageTextures)];
|
||||
computePipeline->header.numSamplers,
|
||||
computePipeline->header.numReadonlyStorageTextures)];
|
||||
}
|
||||
commandBuffer->needComputeReadOnlyStorageTextureBind = false;
|
||||
}
|
||||
|
||||
if (commandBuffer->needComputeReadOnlyStorageBufferBind) {
|
||||
if (computePipeline->numReadonlyStorageBuffers > 0) {
|
||||
if (computePipeline->header.numReadonlyStorageBuffers > 0) {
|
||||
[commandBuffer->computeEncoder setBuffers:commandBuffer->computeReadOnlyBuffers
|
||||
offsets:offsets
|
||||
withRange:NSMakeRange(computePipeline->numUniformBuffers,
|
||||
computePipeline->numReadonlyStorageBuffers)];
|
||||
withRange:NSMakeRange(computePipeline->header.numUniformBuffers,
|
||||
computePipeline->header.numReadonlyStorageBuffers)];
|
||||
}
|
||||
commandBuffer->needComputeReadOnlyStorageBufferBind = false;
|
||||
}
|
||||
|
||||
for (Uint32 i = 0; i < MAX_UNIFORM_BUFFERS_PER_STAGE; i += 1) {
|
||||
if (commandBuffer->needComputeUniformBufferBind[i]) {
|
||||
if (computePipeline->numUniformBuffers > i) {
|
||||
if (computePipeline->header.numUniformBuffers > i) {
|
||||
[commandBuffer->computeEncoder
|
||||
setBuffer:commandBuffer->computeUniformBuffers[i]->handle
|
||||
offset:commandBuffer->computeUniformBuffers[i]->drawOffset
|
||||
@@ -3133,7 +3123,7 @@ static void METAL_BindComputePipeline(
|
||||
metalCommandBuffer->needComputeUniformBufferBind[i] = true;
|
||||
}
|
||||
|
||||
for (Uint32 i = 0; i < pipeline->numUniformBuffers; i += 1) {
|
||||
for (Uint32 i = 0; i < pipeline->header.numUniformBuffers; i += 1) {
|
||||
if (metalCommandBuffer->computeUniformBuffers[i] == NULL) {
|
||||
metalCommandBuffer->computeUniformBuffers[i] = METAL_INTERNAL_AcquireUniformBufferFromPool(
|
||||
metalCommandBuffer);
|
||||
@@ -3141,22 +3131,22 @@ static void METAL_BindComputePipeline(
|
||||
}
|
||||
|
||||
// Bind write-only resources
|
||||
if (pipeline->numReadWriteStorageTextures > 0) {
|
||||
if (pipeline->header.numReadWriteStorageTextures > 0) {
|
||||
[metalCommandBuffer->computeEncoder setTextures:metalCommandBuffer->computeReadWriteTextures
|
||||
withRange:NSMakeRange(
|
||||
pipeline->numSamplers +
|
||||
pipeline->numReadonlyStorageTextures,
|
||||
pipeline->numReadWriteStorageTextures)];
|
||||
pipeline->header.numSamplers +
|
||||
pipeline->header.numReadonlyStorageTextures,
|
||||
pipeline->header.numReadWriteStorageTextures)];
|
||||
}
|
||||
|
||||
NSUInteger offsets[MAX_COMPUTE_WRITE_BUFFERS] = { 0 };
|
||||
if (pipeline->numReadWriteStorageBuffers > 0) {
|
||||
if (pipeline->header.numReadWriteStorageBuffers > 0) {
|
||||
[metalCommandBuffer->computeEncoder setBuffers:metalCommandBuffer->computeReadWriteBuffers
|
||||
offsets:offsets
|
||||
withRange:NSMakeRange(
|
||||
pipeline->numUniformBuffers +
|
||||
pipeline->numReadonlyStorageBuffers,
|
||||
pipeline->numReadWriteStorageBuffers)];
|
||||
pipeline->header.numUniformBuffers +
|
||||
pipeline->header.numReadonlyStorageBuffers,
|
||||
pipeline->header.numReadWriteStorageBuffers)];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4570,6 +4560,7 @@ static SDL_GPUDevice *METAL_CreateDevice(bool debugMode, bool preferLowPower, SD
|
||||
SDL_GPUDevice *result = SDL_calloc(1, sizeof(SDL_GPUDevice));
|
||||
ASSIGN_DRIVER(METAL)
|
||||
result->driverData = (SDL_GPURenderer *)renderer;
|
||||
result->shader_formats = SDL_GPU_SHADERFORMAT_MSL | SDL_GPU_SHADERFORMAT_METALLIB;
|
||||
renderer->sdlGPUDevice = result;
|
||||
|
||||
return result;
|
||||
|
||||
+247
-126
@@ -732,7 +732,7 @@ typedef struct WindowData
|
||||
|
||||
// Synchronization primitives
|
||||
VkSemaphore imageAvailableSemaphore[MAX_FRAMES_IN_FLIGHT];
|
||||
VkSemaphore renderFinishedSemaphore[MAX_FRAMES_IN_FLIGHT];
|
||||
VkSemaphore *renderFinishedSemaphore;
|
||||
SDL_GPUFence *inFlightFences[MAX_FRAMES_IN_FLIGHT];
|
||||
|
||||
Uint32 frameCounter;
|
||||
@@ -822,13 +822,13 @@ typedef struct DescriptorSetLayout
|
||||
typedef struct GraphicsPipelineResourceLayoutHashTableKey
|
||||
{
|
||||
Uint32 vertexSamplerCount;
|
||||
Uint32 vertexStorageBufferCount;
|
||||
Uint32 vertexStorageTextureCount;
|
||||
Uint32 vertexStorageBufferCount;
|
||||
Uint32 vertexUniformBufferCount;
|
||||
|
||||
Uint32 fragmentSamplerCount;
|
||||
Uint32 fragmentStorageBufferCount;
|
||||
Uint32 fragmentStorageTextureCount;
|
||||
Uint32 fragmentStorageBufferCount;
|
||||
Uint32 fragmentUniformBufferCount;
|
||||
} GraphicsPipelineResourceLayoutHashTableKey;
|
||||
|
||||
@@ -846,18 +846,20 @@ typedef struct VulkanGraphicsPipelineResourceLayout
|
||||
DescriptorSetLayout *descriptorSetLayouts[4];
|
||||
|
||||
Uint32 vertexSamplerCount;
|
||||
Uint32 vertexStorageBufferCount;
|
||||
Uint32 vertexStorageTextureCount;
|
||||
Uint32 vertexStorageBufferCount;
|
||||
Uint32 vertexUniformBufferCount;
|
||||
|
||||
Uint32 fragmentSamplerCount;
|
||||
Uint32 fragmentStorageBufferCount;
|
||||
Uint32 fragmentStorageTextureCount;
|
||||
Uint32 fragmentStorageBufferCount;
|
||||
Uint32 fragmentUniformBufferCount;
|
||||
} VulkanGraphicsPipelineResourceLayout;
|
||||
|
||||
typedef struct VulkanGraphicsPipeline
|
||||
{
|
||||
GraphicsPipelineCommonHeader header;
|
||||
|
||||
VkPipeline pipeline;
|
||||
SDL_GPUPrimitiveType primitiveType;
|
||||
|
||||
@@ -901,6 +903,8 @@ typedef struct VulkanComputePipelineResourceLayout
|
||||
|
||||
typedef struct VulkanComputePipeline
|
||||
{
|
||||
ComputePipelineCommonHeader header;
|
||||
|
||||
VkShaderModule shaderModule;
|
||||
VkPipeline pipeline;
|
||||
VulkanComputePipelineResourceLayout *resourceLayout;
|
||||
@@ -1038,25 +1042,33 @@ typedef struct VulkanCommandBuffer
|
||||
Uint32 vertexBufferCount;
|
||||
bool needVertexBufferBind;
|
||||
|
||||
VulkanTexture *vertexSamplerTextures[MAX_TEXTURE_SAMPLERS_PER_STAGE];
|
||||
VulkanSampler *vertexSamplers[MAX_TEXTURE_SAMPLERS_PER_STAGE];
|
||||
VulkanTexture *vertexStorageTextures[MAX_STORAGE_TEXTURES_PER_STAGE];
|
||||
VulkanBuffer *vertexStorageBuffers[MAX_STORAGE_BUFFERS_PER_STAGE];
|
||||
VkImageView vertexSamplerTextureViewBindings[MAX_TEXTURE_SAMPLERS_PER_STAGE];
|
||||
VkSampler vertexSamplerBindings[MAX_TEXTURE_SAMPLERS_PER_STAGE];
|
||||
VkImageView vertexStorageTextureViewBindings[MAX_STORAGE_TEXTURES_PER_STAGE];
|
||||
VkBuffer vertexStorageBufferBindings[MAX_STORAGE_BUFFERS_PER_STAGE];
|
||||
|
||||
VulkanTexture *fragmentSamplerTextures[MAX_TEXTURE_SAMPLERS_PER_STAGE];
|
||||
VulkanSampler *fragmentSamplers[MAX_TEXTURE_SAMPLERS_PER_STAGE];
|
||||
VulkanTexture *fragmentStorageTextures[MAX_STORAGE_TEXTURES_PER_STAGE];
|
||||
VulkanBuffer *fragmentStorageBuffers[MAX_STORAGE_BUFFERS_PER_STAGE];
|
||||
VkImageView fragmentSamplerTextureViewBindings[MAX_TEXTURE_SAMPLERS_PER_STAGE];
|
||||
VkSampler fragmentSamplerBindings[MAX_TEXTURE_SAMPLERS_PER_STAGE];
|
||||
VkImageView fragmentStorageTextureViewBindings[MAX_STORAGE_TEXTURES_PER_STAGE];
|
||||
VkBuffer fragmentStorageBufferBindings[MAX_STORAGE_BUFFERS_PER_STAGE];
|
||||
|
||||
VkImageView computeSamplerTextureViewBindings[MAX_TEXTURE_SAMPLERS_PER_STAGE];
|
||||
VkSampler computeSamplerBindings[MAX_TEXTURE_SAMPLERS_PER_STAGE];
|
||||
VkImageView readOnlyComputeStorageTextureViewBindings[MAX_STORAGE_TEXTURES_PER_STAGE];
|
||||
VkBuffer readOnlyComputeStorageBufferBindings[MAX_STORAGE_BUFFERS_PER_STAGE];
|
||||
|
||||
// Track these separately because barriers can happen mid compute pass
|
||||
VulkanTexture *readOnlyComputeStorageTextures[MAX_STORAGE_TEXTURES_PER_STAGE];
|
||||
VulkanBuffer *readOnlyComputeStorageBuffers[MAX_STORAGE_BUFFERS_PER_STAGE];
|
||||
|
||||
VkImageView readWriteComputeStorageTextureViewBindings[MAX_COMPUTE_WRITE_TEXTURES];
|
||||
VkBuffer readWriteComputeStorageBufferBindings[MAX_COMPUTE_WRITE_BUFFERS];
|
||||
|
||||
// Track these separately because they are barriered when the compute pass begins
|
||||
VulkanTextureSubresource *readWriteComputeStorageTextureSubresources[MAX_COMPUTE_WRITE_TEXTURES];
|
||||
Uint32 readWriteComputeStorageTextureSubresourceCount;
|
||||
VulkanBuffer *readWriteComputeStorageBuffers[MAX_COMPUTE_WRITE_BUFFERS];
|
||||
|
||||
VulkanTexture *computeSamplerTextures[MAX_TEXTURE_SAMPLERS_PER_STAGE];
|
||||
VulkanSampler *computeSamplers[MAX_TEXTURE_SAMPLERS_PER_STAGE];
|
||||
VulkanTexture *readOnlyComputeStorageTextures[MAX_STORAGE_TEXTURES_PER_STAGE];
|
||||
VulkanBuffer *readOnlyComputeStorageBuffers[MAX_STORAGE_BUFFERS_PER_STAGE];
|
||||
|
||||
// Uniform buffers
|
||||
|
||||
VulkanUniformBuffer *vertexUniformBuffers[MAX_UNIFORM_BUFFERS_PER_STAGE];
|
||||
@@ -1096,6 +1108,7 @@ typedef struct VulkanCommandBuffer
|
||||
VulkanFenceHandle *inFlightFence;
|
||||
bool autoReleaseFence;
|
||||
|
||||
bool swapchainRequested;
|
||||
bool isDefrag; // Whether this CB was created for defragging
|
||||
} VulkanCommandBuffer;
|
||||
|
||||
@@ -1130,6 +1143,7 @@ struct VulkanRenderer
|
||||
VulkanExtensions supports;
|
||||
bool supportsDebugUtils;
|
||||
bool supportsColorspace;
|
||||
bool supportsPhysicalDeviceProperties2;
|
||||
bool supportsFillModeNonSolid;
|
||||
bool supportsMultiDrawIndirect;
|
||||
|
||||
@@ -1265,13 +1279,20 @@ static inline const char *VkErrorMessages(VkResult code)
|
||||
#undef ERR_TO_STR
|
||||
}
|
||||
|
||||
#define SET_ERROR_AND_RETURN(fmt, msg, ret) \
|
||||
#define SET_ERROR(fmt, msg) \
|
||||
do { \
|
||||
if (renderer->debugMode) { \
|
||||
SDL_LogError(SDL_LOG_CATEGORY_GPU, fmt, msg); \
|
||||
} \
|
||||
SDL_SetError((fmt), (msg)); \
|
||||
return ret; \
|
||||
} while (0)
|
||||
|
||||
#define SET_STRING_ERROR(msg) SET_ERROR("%s", msg)
|
||||
|
||||
#define SET_ERROR_AND_RETURN(fmt, msg, ret) \
|
||||
do { \
|
||||
SET_ERROR(fmt, msg); \
|
||||
return ret; \
|
||||
} while (0)
|
||||
|
||||
#define SET_STRING_ERROR_AND_RETURN(msg, ret) SET_ERROR_AND_RETURN("%s", msg, ret)
|
||||
@@ -3217,7 +3238,6 @@ static void VULKAN_INTERNAL_DestroySwapchain(
|
||||
SDL_free(windowData->textureContainers[i].activeTexture->subresources);
|
||||
SDL_free(windowData->textureContainers[i].activeTexture);
|
||||
}
|
||||
windowData->imageCount = 0;
|
||||
|
||||
SDL_free(windowData->textureContainers);
|
||||
windowData->textureContainers = NULL;
|
||||
@@ -3246,7 +3266,8 @@ static void VULKAN_INTERNAL_DestroySwapchain(
|
||||
NULL);
|
||||
windowData->imageAvailableSemaphore[i] = VK_NULL_HANDLE;
|
||||
}
|
||||
|
||||
}
|
||||
for (i = 0; i < windowData->imageCount; i += 1) {
|
||||
if (windowData->renderFinishedSemaphore[i]) {
|
||||
renderer->vkDestroySemaphore(
|
||||
renderer->logicalDevice,
|
||||
@@ -3255,6 +3276,10 @@ static void VULKAN_INTERNAL_DestroySwapchain(
|
||||
windowData->renderFinishedSemaphore[i] = VK_NULL_HANDLE;
|
||||
}
|
||||
}
|
||||
SDL_free(windowData->renderFinishedSemaphore);
|
||||
windowData->renderFinishedSemaphore = NULL;
|
||||
|
||||
windowData->imageCount = 0;
|
||||
}
|
||||
|
||||
static void VULKAN_INTERNAL_DestroyGraphicsPipelineResourceLayout(
|
||||
@@ -4812,6 +4837,12 @@ static Uint32 VULKAN_INTERNAL_CreateSwapchain(
|
||||
CHECK_VULKAN_ERROR_AND_RETURN(vulkanResult, vkCreateSemaphore, false);
|
||||
}
|
||||
|
||||
windowData->inFlightFences[i] = NULL;
|
||||
}
|
||||
|
||||
windowData->renderFinishedSemaphore = SDL_malloc(
|
||||
sizeof(VkSemaphore) * windowData->imageCount);
|
||||
for (i = 0; i < windowData->imageCount; i += 1) {
|
||||
vulkanResult = renderer->vkCreateSemaphore(
|
||||
renderer->logicalDevice,
|
||||
&semaphoreCreateInfo,
|
||||
@@ -4831,8 +4862,6 @@ static Uint32 VULKAN_INTERNAL_CreateSwapchain(
|
||||
windowData->swapchain = VK_NULL_HANDLE;
|
||||
CHECK_VULKAN_ERROR_AND_RETURN(vulkanResult, vkCreateSemaphore, false);
|
||||
}
|
||||
|
||||
windowData->inFlightFences[i] = NULL;
|
||||
}
|
||||
|
||||
windowData->needsSwapchainRecreate = false;
|
||||
@@ -5118,8 +5147,8 @@ static void VULKAN_INTERNAL_BindGraphicsDescriptorSets(
|
||||
currentWriteDescriptorSet->pTexelBufferView = NULL;
|
||||
currentWriteDescriptorSet->pBufferInfo = NULL;
|
||||
|
||||
imageInfos[imageInfoCount].sampler = commandBuffer->vertexSamplers[i]->sampler;
|
||||
imageInfos[imageInfoCount].imageView = commandBuffer->vertexSamplerTextures[i]->fullView;
|
||||
imageInfos[imageInfoCount].sampler = commandBuffer->vertexSamplerBindings[i];
|
||||
imageInfos[imageInfoCount].imageView = commandBuffer->vertexSamplerTextureViewBindings[i];
|
||||
imageInfos[imageInfoCount].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
||||
|
||||
currentWriteDescriptorSet->pImageInfo = &imageInfos[imageInfoCount];
|
||||
@@ -5142,7 +5171,7 @@ static void VULKAN_INTERNAL_BindGraphicsDescriptorSets(
|
||||
currentWriteDescriptorSet->pBufferInfo = NULL;
|
||||
|
||||
imageInfos[imageInfoCount].sampler = VK_NULL_HANDLE;
|
||||
imageInfos[imageInfoCount].imageView = commandBuffer->vertexStorageTextures[i]->fullView;
|
||||
imageInfos[imageInfoCount].imageView = commandBuffer->vertexStorageTextureViewBindings[i];
|
||||
imageInfos[imageInfoCount].imageLayout = VK_IMAGE_LAYOUT_GENERAL;
|
||||
|
||||
currentWriteDescriptorSet->pImageInfo = &imageInfos[imageInfoCount];
|
||||
@@ -5164,7 +5193,7 @@ static void VULKAN_INTERNAL_BindGraphicsDescriptorSets(
|
||||
currentWriteDescriptorSet->pTexelBufferView = NULL;
|
||||
currentWriteDescriptorSet->pImageInfo = NULL;
|
||||
|
||||
bufferInfos[bufferInfoCount].buffer = commandBuffer->vertexStorageBuffers[i]->buffer;
|
||||
bufferInfos[bufferInfoCount].buffer = commandBuffer->vertexStorageBufferBindings[i];
|
||||
bufferInfos[bufferInfoCount].offset = 0;
|
||||
bufferInfos[bufferInfoCount].range = VK_WHOLE_SIZE;
|
||||
|
||||
@@ -5237,8 +5266,8 @@ static void VULKAN_INTERNAL_BindGraphicsDescriptorSets(
|
||||
currentWriteDescriptorSet->pTexelBufferView = NULL;
|
||||
currentWriteDescriptorSet->pBufferInfo = NULL;
|
||||
|
||||
imageInfos[imageInfoCount].sampler = commandBuffer->fragmentSamplers[i]->sampler;
|
||||
imageInfos[imageInfoCount].imageView = commandBuffer->fragmentSamplerTextures[i]->fullView;
|
||||
imageInfos[imageInfoCount].sampler = commandBuffer->fragmentSamplerBindings[i];
|
||||
imageInfos[imageInfoCount].imageView = commandBuffer->fragmentSamplerTextureViewBindings[i];
|
||||
imageInfos[imageInfoCount].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
||||
|
||||
currentWriteDescriptorSet->pImageInfo = &imageInfos[imageInfoCount];
|
||||
@@ -5261,7 +5290,7 @@ static void VULKAN_INTERNAL_BindGraphicsDescriptorSets(
|
||||
currentWriteDescriptorSet->pBufferInfo = NULL;
|
||||
|
||||
imageInfos[imageInfoCount].sampler = VK_NULL_HANDLE;
|
||||
imageInfos[imageInfoCount].imageView = commandBuffer->fragmentStorageTextures[i]->fullView;
|
||||
imageInfos[imageInfoCount].imageView = commandBuffer->fragmentStorageTextureViewBindings[i];
|
||||
imageInfos[imageInfoCount].imageLayout = VK_IMAGE_LAYOUT_GENERAL;
|
||||
|
||||
currentWriteDescriptorSet->pImageInfo = &imageInfos[imageInfoCount];
|
||||
@@ -5283,7 +5312,7 @@ static void VULKAN_INTERNAL_BindGraphicsDescriptorSets(
|
||||
currentWriteDescriptorSet->pTexelBufferView = NULL;
|
||||
currentWriteDescriptorSet->pImageInfo = NULL;
|
||||
|
||||
bufferInfos[bufferInfoCount].buffer = commandBuffer->fragmentStorageBuffers[i]->buffer;
|
||||
bufferInfos[bufferInfoCount].buffer = commandBuffer->fragmentStorageBufferBindings[i];
|
||||
bufferInfos[bufferInfoCount].offset = 0;
|
||||
bufferInfos[bufferInfoCount].range = VK_WHOLE_SIZE;
|
||||
|
||||
@@ -5864,7 +5893,10 @@ static VulkanTexture *VULKAN_INTERNAL_CreateTexture(
|
||||
VULKAN_TEXTURE_USAGE_MODE_UNINITIALIZED,
|
||||
texture);
|
||||
VULKAN_INTERNAL_TrackTexture(barrierCommandBuffer, texture);
|
||||
VULKAN_Submit((SDL_GPUCommandBuffer *)barrierCommandBuffer);
|
||||
if (!VULKAN_Submit((SDL_GPUCommandBuffer *)barrierCommandBuffer)) {
|
||||
VULKAN_INTERNAL_DestroyTexture(renderer, texture);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return texture;
|
||||
@@ -6061,7 +6093,6 @@ static VkRenderPass VULKAN_INTERNAL_CreateRenderPass(
|
||||
colorAttachmentReferences[colorAttachmentReferenceCount].layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||
|
||||
attachmentDescriptionCount += 1;
|
||||
colorAttachmentReferenceCount += 1;
|
||||
|
||||
if (colorTargetInfos[i].store_op == SDL_GPU_STOREOP_RESOLVE || colorTargetInfos[i].store_op == SDL_GPU_STOREOP_RESOLVE_AND_STORE) {
|
||||
VulkanTextureContainer *resolveContainer = (VulkanTextureContainer *)colorTargetInfos[i].resolve_texture;
|
||||
@@ -6076,12 +6107,16 @@ static VkRenderPass VULKAN_INTERNAL_CreateRenderPass(
|
||||
attachmentDescriptions[attachmentDescriptionCount].initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||
attachmentDescriptions[attachmentDescriptionCount].finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||
|
||||
resolveReferences[resolveReferenceCount].attachment = attachmentDescriptionCount;
|
||||
resolveReferences[resolveReferenceCount].layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||
resolveReferences[colorAttachmentReferenceCount].attachment = attachmentDescriptionCount;
|
||||
resolveReferences[colorAttachmentReferenceCount].layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||
|
||||
attachmentDescriptionCount += 1;
|
||||
resolveReferenceCount += 1;
|
||||
} else {
|
||||
resolveReferences[colorAttachmentReferenceCount].attachment = VK_ATTACHMENT_UNUSED;
|
||||
}
|
||||
|
||||
colorAttachmentReferenceCount += 1;
|
||||
}
|
||||
|
||||
subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
|
||||
@@ -6557,6 +6592,16 @@ static SDL_GPUGraphicsPipeline *VULKAN_CreateGraphicsPipeline(
|
||||
&nameInfo);
|
||||
}
|
||||
|
||||
// Put this data in the pipeline we can do validation in gpu.c
|
||||
graphicsPipeline->header.num_vertex_samplers = graphicsPipeline->resourceLayout->vertexSamplerCount;
|
||||
graphicsPipeline->header.num_vertex_storage_buffers = graphicsPipeline->resourceLayout->vertexStorageBufferCount;
|
||||
graphicsPipeline->header.num_vertex_storage_textures = graphicsPipeline->resourceLayout->vertexStorageTextureCount;
|
||||
graphicsPipeline->header.num_vertex_uniform_buffers = graphicsPipeline->resourceLayout->vertexUniformBufferCount;
|
||||
graphicsPipeline->header.num_fragment_samplers = graphicsPipeline->resourceLayout->fragmentSamplerCount;
|
||||
graphicsPipeline->header.num_fragment_storage_buffers = graphicsPipeline->resourceLayout->fragmentStorageBufferCount;
|
||||
graphicsPipeline->header.num_fragment_storage_textures = graphicsPipeline->resourceLayout->fragmentStorageTextureCount;
|
||||
graphicsPipeline->header.num_fragment_uniform_buffers = graphicsPipeline->resourceLayout->fragmentUniformBufferCount;
|
||||
|
||||
return (SDL_GPUGraphicsPipeline *)graphicsPipeline;
|
||||
}
|
||||
|
||||
@@ -6651,6 +6696,14 @@ static SDL_GPUComputePipeline *VULKAN_CreateComputePipeline(
|
||||
&nameInfo);
|
||||
}
|
||||
|
||||
// Track these here for debug layer
|
||||
vulkanComputePipeline->header.numSamplers = vulkanComputePipeline->resourceLayout->numSamplers;
|
||||
vulkanComputePipeline->header.numReadonlyStorageTextures = vulkanComputePipeline->resourceLayout->numReadonlyStorageTextures;
|
||||
vulkanComputePipeline->header.numReadonlyStorageBuffers = vulkanComputePipeline->resourceLayout->numReadonlyStorageBuffers;
|
||||
vulkanComputePipeline->header.numReadWriteStorageTextures = vulkanComputePipeline->resourceLayout->numReadWriteStorageTextures;
|
||||
vulkanComputePipeline->header.numReadWriteStorageBuffers = vulkanComputePipeline->resourceLayout->numReadWriteStorageBuffers;
|
||||
vulkanComputePipeline->header.numUniformBuffers = vulkanComputePipeline->resourceLayout->numUniformBuffers;
|
||||
|
||||
return (SDL_GPUComputePipeline *)vulkanComputePipeline;
|
||||
}
|
||||
|
||||
@@ -6913,6 +6966,8 @@ static void VULKAN_ReleaseTexture(
|
||||
VULKAN_INTERNAL_ReleaseTexture(renderer, vulkanTextureContainer->textures[i]);
|
||||
}
|
||||
|
||||
SDL_DestroyProperties(vulkanTextureContainer->header.info.props);
|
||||
|
||||
// Containers are just client handles, so we can destroy immediately
|
||||
if (vulkanTextureContainer->debugName != NULL) {
|
||||
SDL_free(vulkanTextureContainer->debugName);
|
||||
@@ -7114,6 +7169,8 @@ static VkRenderPass VULKAN_INTERNAL_FetchRenderPass(
|
||||
key.sampleCount = VK_SAMPLE_COUNT_1_BIT;
|
||||
if (numColorTargets > 0) {
|
||||
key.sampleCount = SDLToVK_SampleCount[((VulkanTextureContainer *)colorTargetInfos[0].texture)->header.info.sample_count];
|
||||
} else if (numColorTargets == 0 && depthStencilTargetInfo != NULL) {
|
||||
key.sampleCount = SDLToVK_SampleCount[((VulkanTextureContainer *)depthStencilTargetInfo->texture)->header.info.sample_count];
|
||||
}
|
||||
|
||||
key.numColorTargets = numColorTargets;
|
||||
@@ -7449,21 +7506,21 @@ static void VULKAN_BindVertexSamplers(
|
||||
VulkanTextureContainer *textureContainer = (VulkanTextureContainer *)textureSamplerBindings[i].texture;
|
||||
VulkanSampler *sampler = (VulkanSampler *)textureSamplerBindings[i].sampler;
|
||||
|
||||
if (vulkanCommandBuffer->vertexSamplers[firstSlot + i] != sampler) {
|
||||
if (vulkanCommandBuffer->vertexSamplerBindings[firstSlot + i] != sampler->sampler) {
|
||||
VULKAN_INTERNAL_TrackSampler(
|
||||
vulkanCommandBuffer,
|
||||
(VulkanSampler *)textureSamplerBindings[i].sampler);
|
||||
|
||||
vulkanCommandBuffer->vertexSamplers[firstSlot + i] = (VulkanSampler *)textureSamplerBindings[i].sampler;
|
||||
vulkanCommandBuffer->vertexSamplerBindings[firstSlot + i] = sampler->sampler;
|
||||
vulkanCommandBuffer->needNewVertexResourceDescriptorSet = true;
|
||||
}
|
||||
|
||||
if (vulkanCommandBuffer->vertexSamplerTextures[firstSlot + i] != textureContainer->activeTexture) {
|
||||
if (vulkanCommandBuffer->vertexSamplerTextureViewBindings[firstSlot + i] != textureContainer->activeTexture->fullView) {
|
||||
VULKAN_INTERNAL_TrackTexture(
|
||||
vulkanCommandBuffer,
|
||||
textureContainer->activeTexture);
|
||||
|
||||
vulkanCommandBuffer->vertexSamplerTextures[firstSlot + i] = textureContainer->activeTexture;
|
||||
vulkanCommandBuffer->vertexSamplerTextureViewBindings[firstSlot + i] = textureContainer->activeTexture->fullView;
|
||||
vulkanCommandBuffer->needNewVertexResourceDescriptorSet = true;
|
||||
}
|
||||
}
|
||||
@@ -7480,12 +7537,12 @@ static void VULKAN_BindVertexStorageTextures(
|
||||
for (Uint32 i = 0; i < numBindings; i += 1) {
|
||||
VulkanTextureContainer *textureContainer = (VulkanTextureContainer *)storageTextures[i];
|
||||
|
||||
if (vulkanCommandBuffer->vertexStorageTextures[firstSlot + i] != textureContainer->activeTexture) {
|
||||
if (vulkanCommandBuffer->vertexStorageTextureViewBindings[firstSlot + i] != textureContainer->activeTexture->fullView) {
|
||||
VULKAN_INTERNAL_TrackTexture(
|
||||
vulkanCommandBuffer,
|
||||
textureContainer->activeTexture);
|
||||
|
||||
vulkanCommandBuffer->vertexStorageTextures[firstSlot + i] = textureContainer->activeTexture;
|
||||
vulkanCommandBuffer->vertexStorageTextureViewBindings[firstSlot + i] = textureContainer->activeTexture->fullView;
|
||||
vulkanCommandBuffer->needNewVertexResourceDescriptorSet = true;
|
||||
}
|
||||
}
|
||||
@@ -7502,12 +7559,12 @@ static void VULKAN_BindVertexStorageBuffers(
|
||||
for (Uint32 i = 0; i < numBindings; i += 1) {
|
||||
VulkanBufferContainer *bufferContainer = (VulkanBufferContainer *)storageBuffers[i];
|
||||
|
||||
if (vulkanCommandBuffer->vertexStorageBuffers[firstSlot + i] != bufferContainer->activeBuffer) {
|
||||
if (vulkanCommandBuffer->vertexStorageBufferBindings[firstSlot + i] != bufferContainer->activeBuffer->buffer) {
|
||||
VULKAN_INTERNAL_TrackBuffer(
|
||||
vulkanCommandBuffer,
|
||||
bufferContainer->activeBuffer);
|
||||
|
||||
vulkanCommandBuffer->vertexStorageBuffers[firstSlot + i] = bufferContainer->activeBuffer;
|
||||
vulkanCommandBuffer->vertexStorageBufferBindings[firstSlot + i] = bufferContainer->activeBuffer->buffer;
|
||||
vulkanCommandBuffer->needNewVertexResourceDescriptorSet = true;
|
||||
}
|
||||
}
|
||||
@@ -7525,21 +7582,21 @@ static void VULKAN_BindFragmentSamplers(
|
||||
VulkanTextureContainer *textureContainer = (VulkanTextureContainer *)textureSamplerBindings[i].texture;
|
||||
VulkanSampler *sampler = (VulkanSampler *)textureSamplerBindings[i].sampler;
|
||||
|
||||
if (vulkanCommandBuffer->fragmentSamplers[firstSlot + i] != sampler) {
|
||||
if (vulkanCommandBuffer->fragmentSamplerBindings[firstSlot + i] != sampler->sampler) {
|
||||
VULKAN_INTERNAL_TrackSampler(
|
||||
vulkanCommandBuffer,
|
||||
(VulkanSampler *)textureSamplerBindings[i].sampler);
|
||||
|
||||
vulkanCommandBuffer->fragmentSamplers[firstSlot + i] = (VulkanSampler *)textureSamplerBindings[i].sampler;
|
||||
vulkanCommandBuffer->fragmentSamplerBindings[firstSlot + i] = sampler->sampler;
|
||||
vulkanCommandBuffer->needNewFragmentResourceDescriptorSet = true;
|
||||
}
|
||||
|
||||
if (vulkanCommandBuffer->fragmentSamplerTextures[firstSlot + i] != textureContainer->activeTexture) {
|
||||
if (vulkanCommandBuffer->fragmentSamplerTextureViewBindings[firstSlot + i] != textureContainer->activeTexture->fullView) {
|
||||
VULKAN_INTERNAL_TrackTexture(
|
||||
vulkanCommandBuffer,
|
||||
textureContainer->activeTexture);
|
||||
|
||||
vulkanCommandBuffer->fragmentSamplerTextures[firstSlot + i] = textureContainer->activeTexture;
|
||||
vulkanCommandBuffer->fragmentSamplerTextureViewBindings[firstSlot + i] = textureContainer->activeTexture->fullView;
|
||||
vulkanCommandBuffer->needNewFragmentResourceDescriptorSet = true;
|
||||
}
|
||||
}
|
||||
@@ -7556,12 +7613,12 @@ static void VULKAN_BindFragmentStorageTextures(
|
||||
for (Uint32 i = 0; i < numBindings; i += 1) {
|
||||
VulkanTextureContainer *textureContainer = (VulkanTextureContainer *)storageTextures[i];
|
||||
|
||||
if (vulkanCommandBuffer->fragmentStorageTextures[firstSlot + i] != textureContainer->activeTexture) {
|
||||
if (vulkanCommandBuffer->fragmentStorageTextureViewBindings[firstSlot + i] != textureContainer->activeTexture->fullView) {
|
||||
VULKAN_INTERNAL_TrackTexture(
|
||||
vulkanCommandBuffer,
|
||||
textureContainer->activeTexture);
|
||||
|
||||
vulkanCommandBuffer->fragmentStorageTextures[firstSlot + i] = textureContainer->activeTexture;
|
||||
vulkanCommandBuffer->fragmentStorageTextureViewBindings[firstSlot + i] = textureContainer->activeTexture->fullView;
|
||||
vulkanCommandBuffer->needNewFragmentResourceDescriptorSet = true;
|
||||
}
|
||||
}
|
||||
@@ -7580,12 +7637,12 @@ static void VULKAN_BindFragmentStorageBuffers(
|
||||
for (i = 0; i < numBindings; i += 1) {
|
||||
bufferContainer = (VulkanBufferContainer *)storageBuffers[i];
|
||||
|
||||
if (vulkanCommandBuffer->fragmentStorageBuffers[firstSlot + i] != bufferContainer->activeBuffer) {
|
||||
if (vulkanCommandBuffer->fragmentStorageBufferBindings[firstSlot + i] != bufferContainer->activeBuffer->buffer) {
|
||||
VULKAN_INTERNAL_TrackBuffer(
|
||||
vulkanCommandBuffer,
|
||||
bufferContainer->activeBuffer);
|
||||
|
||||
vulkanCommandBuffer->fragmentStorageBuffers[firstSlot + i] = bufferContainer->activeBuffer;
|
||||
vulkanCommandBuffer->fragmentStorageBufferBindings[firstSlot + i] = bufferContainer->activeBuffer->buffer;
|
||||
vulkanCommandBuffer->needNewFragmentResourceDescriptorSet = true;
|
||||
}
|
||||
}
|
||||
@@ -7858,15 +7915,17 @@ static void VULKAN_BeginRenderPass(
|
||||
|
||||
clearValues = SDL_stack_alloc(VkClearValue, clearCount);
|
||||
|
||||
for (i = 0; i < totalColorAttachmentCount; i += 1) {
|
||||
clearValues[i].color.float32[0] = colorTargetInfos[i].clear_color.r;
|
||||
clearValues[i].color.float32[1] = colorTargetInfos[i].clear_color.g;
|
||||
clearValues[i].color.float32[2] = colorTargetInfos[i].clear_color.b;
|
||||
clearValues[i].color.float32[3] = colorTargetInfos[i].clear_color.a;
|
||||
int clearIndex = 0;
|
||||
for (i = 0; i < numColorTargets; i += 1) {
|
||||
clearValues[clearIndex].color.float32[0] = colorTargetInfos[i].clear_color.r;
|
||||
clearValues[clearIndex].color.float32[1] = colorTargetInfos[i].clear_color.g;
|
||||
clearValues[clearIndex].color.float32[2] = colorTargetInfos[i].clear_color.b;
|
||||
clearValues[clearIndex].color.float32[3] = colorTargetInfos[i].clear_color.a;
|
||||
clearIndex += 1;
|
||||
|
||||
if (colorTargetInfos[i].store_op == SDL_GPU_STOREOP_RESOLVE || colorTargetInfos[i].store_op == SDL_GPU_STOREOP_RESOLVE_AND_STORE) {
|
||||
// Skip over the resolve texture, we're not clearing it
|
||||
i += 1;
|
||||
clearIndex += 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8099,15 +8158,15 @@ static void VULKAN_EndRenderPass(
|
||||
SDL_zeroa(vulkanCommandBuffer->vertexBufferOffsets);
|
||||
vulkanCommandBuffer->vertexBufferCount = 0;
|
||||
|
||||
SDL_zeroa(vulkanCommandBuffer->vertexSamplers);
|
||||
SDL_zeroa(vulkanCommandBuffer->vertexSamplerTextures);
|
||||
SDL_zeroa(vulkanCommandBuffer->vertexStorageTextures);
|
||||
SDL_zeroa(vulkanCommandBuffer->vertexStorageBuffers);
|
||||
SDL_zeroa(vulkanCommandBuffer->vertexSamplerBindings);
|
||||
SDL_zeroa(vulkanCommandBuffer->vertexSamplerTextureViewBindings);
|
||||
SDL_zeroa(vulkanCommandBuffer->vertexStorageTextureViewBindings);
|
||||
SDL_zeroa(vulkanCommandBuffer->vertexStorageBufferBindings);
|
||||
|
||||
SDL_zeroa(vulkanCommandBuffer->fragmentSamplers);
|
||||
SDL_zeroa(vulkanCommandBuffer->fragmentSamplerTextures);
|
||||
SDL_zeroa(vulkanCommandBuffer->fragmentStorageTextures);
|
||||
SDL_zeroa(vulkanCommandBuffer->fragmentStorageBuffers);
|
||||
SDL_zeroa(vulkanCommandBuffer->fragmentSamplerBindings);
|
||||
SDL_zeroa(vulkanCommandBuffer->fragmentSamplerTextureViewBindings);
|
||||
SDL_zeroa(vulkanCommandBuffer->fragmentStorageTextureViewBindings);
|
||||
SDL_zeroa(vulkanCommandBuffer->fragmentStorageBufferBindings);
|
||||
}
|
||||
|
||||
static void VULKAN_BeginComputePass(
|
||||
@@ -8137,6 +8196,7 @@ static void VULKAN_BeginComputePass(
|
||||
VULKAN_TEXTURE_USAGE_MODE_COMPUTE_STORAGE_READ_WRITE);
|
||||
|
||||
vulkanCommandBuffer->readWriteComputeStorageTextureSubresources[i] = subresource;
|
||||
vulkanCommandBuffer->readWriteComputeStorageTextureViewBindings[i] = subresource->computeWriteView;
|
||||
|
||||
VULKAN_INTERNAL_TrackTexture(
|
||||
vulkanCommandBuffer,
|
||||
@@ -8150,9 +8210,10 @@ static void VULKAN_BeginComputePass(
|
||||
vulkanCommandBuffer,
|
||||
bufferContainer,
|
||||
storageBufferBindings[i].cycle,
|
||||
VULKAN_BUFFER_USAGE_MODE_COMPUTE_STORAGE_READ);
|
||||
VULKAN_BUFFER_USAGE_MODE_COMPUTE_STORAGE_READ_WRITE);
|
||||
|
||||
vulkanCommandBuffer->readWriteComputeStorageBuffers[i] = buffer;
|
||||
vulkanCommandBuffer->readWriteComputeStorageBufferBindings[i] = buffer->buffer;
|
||||
|
||||
VULKAN_INTERNAL_TrackBuffer(
|
||||
vulkanCommandBuffer,
|
||||
@@ -8204,21 +8265,21 @@ static void VULKAN_BindComputeSamplers(
|
||||
VulkanTextureContainer *textureContainer = (VulkanTextureContainer *)textureSamplerBindings[i].texture;
|
||||
VulkanSampler *sampler = (VulkanSampler *)textureSamplerBindings[i].sampler;
|
||||
|
||||
if (vulkanCommandBuffer->computeSamplers[firstSlot + i] != sampler) {
|
||||
if (vulkanCommandBuffer->computeSamplerBindings[firstSlot + i] != sampler->sampler) {
|
||||
VULKAN_INTERNAL_TrackSampler(
|
||||
vulkanCommandBuffer,
|
||||
sampler);
|
||||
|
||||
vulkanCommandBuffer->computeSamplers[firstSlot + i] = sampler;
|
||||
vulkanCommandBuffer->computeSamplerBindings[firstSlot + i] = sampler->sampler;
|
||||
vulkanCommandBuffer->needNewComputeReadOnlyDescriptorSet = true;
|
||||
}
|
||||
|
||||
if (vulkanCommandBuffer->computeSamplerTextures[firstSlot + i] != textureContainer->activeTexture) {
|
||||
if (vulkanCommandBuffer->computeSamplerTextureViewBindings[firstSlot + i] != textureContainer->activeTexture->fullView) {
|
||||
VULKAN_INTERNAL_TrackTexture(
|
||||
vulkanCommandBuffer,
|
||||
textureContainer->activeTexture);
|
||||
|
||||
vulkanCommandBuffer->computeSamplerTextures[firstSlot + i] = textureContainer->activeTexture;
|
||||
vulkanCommandBuffer->computeSamplerTextureViewBindings[firstSlot + i] = textureContainer->activeTexture->fullView;
|
||||
vulkanCommandBuffer->needNewComputeReadOnlyDescriptorSet = true;
|
||||
}
|
||||
}
|
||||
@@ -8259,6 +8320,7 @@ static void VULKAN_BindComputeStorageTextures(
|
||||
textureContainer->activeTexture);
|
||||
|
||||
vulkanCommandBuffer->readOnlyComputeStorageTextures[firstSlot + i] = textureContainer->activeTexture;
|
||||
vulkanCommandBuffer->readOnlyComputeStorageTextureViewBindings[firstSlot + i] = textureContainer->activeTexture->fullView;
|
||||
vulkanCommandBuffer->needNewComputeReadOnlyDescriptorSet = true;
|
||||
}
|
||||
}
|
||||
@@ -8298,6 +8360,7 @@ static void VULKAN_BindComputeStorageBuffers(
|
||||
bufferContainer->activeBuffer);
|
||||
|
||||
vulkanCommandBuffer->readOnlyComputeStorageBuffers[firstSlot + i] = bufferContainer->activeBuffer;
|
||||
vulkanCommandBuffer->readOnlyComputeStorageBufferBindings[firstSlot + i] = bufferContainer->activeBuffer->buffer;
|
||||
vulkanCommandBuffer->needNewComputeReadOnlyDescriptorSet = true;
|
||||
}
|
||||
}
|
||||
@@ -8372,8 +8435,8 @@ static void VULKAN_INTERNAL_BindComputeDescriptorSets(
|
||||
currentWriteDescriptorSet->pTexelBufferView = NULL;
|
||||
currentWriteDescriptorSet->pBufferInfo = NULL;
|
||||
|
||||
imageInfos[imageInfoCount].sampler = commandBuffer->computeSamplers[i]->sampler;
|
||||
imageInfos[imageInfoCount].imageView = commandBuffer->computeSamplerTextures[i]->fullView;
|
||||
imageInfos[imageInfoCount].sampler = commandBuffer->computeSamplerBindings[i];
|
||||
imageInfos[imageInfoCount].imageView = commandBuffer->computeSamplerTextureViewBindings[i];
|
||||
imageInfos[imageInfoCount].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
||||
|
||||
currentWriteDescriptorSet->pImageInfo = &imageInfos[imageInfoCount];
|
||||
@@ -8396,7 +8459,7 @@ static void VULKAN_INTERNAL_BindComputeDescriptorSets(
|
||||
currentWriteDescriptorSet->pBufferInfo = NULL;
|
||||
|
||||
imageInfos[imageInfoCount].sampler = VK_NULL_HANDLE;
|
||||
imageInfos[imageInfoCount].imageView = commandBuffer->readOnlyComputeStorageTextures[i]->fullView;
|
||||
imageInfos[imageInfoCount].imageView = commandBuffer->readOnlyComputeStorageTextureViewBindings[i];
|
||||
imageInfos[imageInfoCount].imageLayout = VK_IMAGE_LAYOUT_GENERAL;
|
||||
|
||||
currentWriteDescriptorSet->pImageInfo = &imageInfos[imageInfoCount];
|
||||
@@ -8418,7 +8481,7 @@ static void VULKAN_INTERNAL_BindComputeDescriptorSets(
|
||||
currentWriteDescriptorSet->pTexelBufferView = NULL;
|
||||
currentWriteDescriptorSet->pImageInfo = NULL;
|
||||
|
||||
bufferInfos[bufferInfoCount].buffer = commandBuffer->readOnlyComputeStorageBuffers[i]->buffer;
|
||||
bufferInfos[bufferInfoCount].buffer = commandBuffer->readOnlyComputeStorageBufferBindings[i];
|
||||
bufferInfos[bufferInfoCount].offset = 0;
|
||||
bufferInfos[bufferInfoCount].range = VK_WHOLE_SIZE;
|
||||
|
||||
@@ -8453,7 +8516,7 @@ static void VULKAN_INTERNAL_BindComputeDescriptorSets(
|
||||
currentWriteDescriptorSet->pBufferInfo = NULL;
|
||||
|
||||
imageInfos[imageInfoCount].sampler = VK_NULL_HANDLE;
|
||||
imageInfos[imageInfoCount].imageView = commandBuffer->readWriteComputeStorageTextureSubresources[i]->computeWriteView;
|
||||
imageInfos[imageInfoCount].imageView = commandBuffer->readWriteComputeStorageTextureViewBindings[i];
|
||||
imageInfos[imageInfoCount].imageLayout = VK_IMAGE_LAYOUT_GENERAL;
|
||||
|
||||
currentWriteDescriptorSet->pImageInfo = &imageInfos[imageInfoCount];
|
||||
@@ -8475,7 +8538,7 @@ static void VULKAN_INTERNAL_BindComputeDescriptorSets(
|
||||
currentWriteDescriptorSet->pTexelBufferView = NULL;
|
||||
currentWriteDescriptorSet->pImageInfo = NULL;
|
||||
|
||||
bufferInfos[bufferInfoCount].buffer = commandBuffer->readWriteComputeStorageBuffers[i]->buffer;
|
||||
bufferInfos[bufferInfoCount].buffer = commandBuffer->readWriteComputeStorageBufferBindings[i];
|
||||
bufferInfos[bufferInfoCount].offset = 0;
|
||||
bufferInfos[bufferInfoCount].range = VK_WHOLE_SIZE;
|
||||
|
||||
@@ -8550,7 +8613,7 @@ static void VULKAN_INTERNAL_BindComputeDescriptorSets(
|
||||
dynamicOffsetCount,
|
||||
dynamicOffsets);
|
||||
|
||||
commandBuffer->needNewVertexUniformOffsets = false;
|
||||
commandBuffer->needNewComputeUniformOffsets = false;
|
||||
}
|
||||
|
||||
static void VULKAN_DispatchCompute(
|
||||
@@ -8642,9 +8705,12 @@ static void VULKAN_EndComputePass(
|
||||
}
|
||||
}
|
||||
|
||||
// we don't need a barrier because sampler state is always the default if sampler bit is set
|
||||
SDL_zeroa(vulkanCommandBuffer->computeSamplerTextures);
|
||||
SDL_zeroa(vulkanCommandBuffer->computeSamplers);
|
||||
// we don't need a barrier for sampler resources because sampler state is always the default if sampler bit is set
|
||||
SDL_zeroa(vulkanCommandBuffer->computeSamplerTextureViewBindings);
|
||||
SDL_zeroa(vulkanCommandBuffer->computeSamplerBindings);
|
||||
|
||||
SDL_zeroa(vulkanCommandBuffer->readWriteComputeStorageTextureViewBindings);
|
||||
SDL_zeroa(vulkanCommandBuffer->readWriteComputeStorageBufferBindings);
|
||||
|
||||
vulkanCommandBuffer->currentComputePipeline = NULL;
|
||||
|
||||
@@ -9350,6 +9416,8 @@ static bool VULKAN_INTERNAL_AllocateCommandBuffer(
|
||||
commandBuffer->usedUniformBuffers = SDL_malloc(
|
||||
commandBuffer->usedUniformBufferCapacity * sizeof(VulkanUniformBuffer *));
|
||||
|
||||
commandBuffer->swapchainRequested = false;
|
||||
|
||||
// Pool it!
|
||||
|
||||
vulkanCommandPool->inactiveCommandBuffers[vulkanCommandPool->inactiveCommandBufferCount] = commandBuffer;
|
||||
@@ -9460,7 +9528,8 @@ static SDL_GPUCommandBuffer *VULKAN_AcquireCommandBuffer(
|
||||
VulkanCommandBuffer *commandBuffer =
|
||||
VULKAN_INTERNAL_GetInactiveCommandBufferFromPool(renderer, threadID);
|
||||
|
||||
commandBuffer->descriptorSetCache = VULKAN_INTERNAL_AcquireDescriptorSetCache(renderer);
|
||||
DescriptorSetCache *descriptorSetCache =
|
||||
VULKAN_INTERNAL_AcquireDescriptorSetCache(renderer);
|
||||
|
||||
SDL_UnlockMutex(renderer->acquireCommandBufferLock);
|
||||
|
||||
@@ -9468,6 +9537,8 @@ static SDL_GPUCommandBuffer *VULKAN_AcquireCommandBuffer(
|
||||
return NULL;
|
||||
}
|
||||
|
||||
commandBuffer->descriptorSetCache = descriptorSetCache;
|
||||
|
||||
// Reset state
|
||||
|
||||
commandBuffer->currentComputePipeline = NULL;
|
||||
@@ -9510,26 +9581,29 @@ static SDL_GPUCommandBuffer *VULKAN_AcquireCommandBuffer(
|
||||
SDL_zeroa(commandBuffer->vertexBufferOffsets);
|
||||
commandBuffer->vertexBufferCount = 0;
|
||||
|
||||
SDL_zeroa(commandBuffer->vertexSamplerTextures);
|
||||
SDL_zeroa(commandBuffer->vertexSamplers);
|
||||
SDL_zeroa(commandBuffer->vertexStorageTextures);
|
||||
SDL_zeroa(commandBuffer->vertexStorageBuffers);
|
||||
SDL_zeroa(commandBuffer->vertexSamplerTextureViewBindings);
|
||||
SDL_zeroa(commandBuffer->vertexSamplerBindings);
|
||||
SDL_zeroa(commandBuffer->vertexStorageTextureViewBindings);
|
||||
SDL_zeroa(commandBuffer->vertexStorageBufferBindings);
|
||||
|
||||
SDL_zeroa(commandBuffer->fragmentSamplerTextures);
|
||||
SDL_zeroa(commandBuffer->fragmentSamplers);
|
||||
SDL_zeroa(commandBuffer->fragmentStorageTextures);
|
||||
SDL_zeroa(commandBuffer->fragmentStorageBuffers);
|
||||
SDL_zeroa(commandBuffer->fragmentSamplerTextureViewBindings);
|
||||
SDL_zeroa(commandBuffer->fragmentSamplerBindings);
|
||||
SDL_zeroa(commandBuffer->fragmentStorageTextureViewBindings);
|
||||
SDL_zeroa(commandBuffer->fragmentStorageBufferBindings);
|
||||
|
||||
SDL_zeroa(commandBuffer->readWriteComputeStorageTextureSubresources);
|
||||
commandBuffer->readWriteComputeStorageTextureSubresourceCount = 0;
|
||||
SDL_zeroa(commandBuffer->readWriteComputeStorageBuffers);
|
||||
SDL_zeroa(commandBuffer->computeSamplerTextures);
|
||||
SDL_zeroa(commandBuffer->computeSamplers);
|
||||
SDL_zeroa(commandBuffer->computeSamplerTextureViewBindings);
|
||||
SDL_zeroa(commandBuffer->computeSamplerBindings);
|
||||
SDL_zeroa(commandBuffer->readOnlyComputeStorageTextureViewBindings);
|
||||
SDL_zeroa(commandBuffer->readOnlyComputeStorageBufferBindings);
|
||||
SDL_zeroa(commandBuffer->readOnlyComputeStorageTextures);
|
||||
SDL_zeroa(commandBuffer->readOnlyComputeStorageBuffers);
|
||||
|
||||
commandBuffer->autoReleaseFence = true;
|
||||
|
||||
commandBuffer->swapchainRequested = false;
|
||||
commandBuffer->isDefrag = 0;
|
||||
|
||||
/* Reset the command buffer here to avoid resets being called
|
||||
@@ -9616,6 +9690,13 @@ static bool VULKAN_INTERNAL_OnWindowResize(void *userdata, SDL_Event *e)
|
||||
data->swapchainCreateHeight = e->window.data2;
|
||||
}
|
||||
|
||||
#ifdef SDL_PLATFORM_ANDROID
|
||||
if (e->type == SDL_EVENT_DID_ENTER_BACKGROUND) {
|
||||
data = VULKAN_INTERNAL_FetchWindowData(w);
|
||||
data->needsSwapchainRecreate = true;
|
||||
}
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -9878,6 +9959,14 @@ static bool VULKAN_INTERNAL_AcquireSwapchainTexture(
|
||||
SET_STRING_ERROR_AND_RETURN("Cannot acquire a swapchain texture from an unclaimed window!", false);
|
||||
}
|
||||
|
||||
// The command buffer is flagged for cleanup when the swapchain is requested as a cleanup timing mechanism
|
||||
vulkanCommandBuffer->swapchainRequested = true;
|
||||
|
||||
if (window->flags & SDL_WINDOW_HIDDEN) {
|
||||
// Edge case, texture is filled in with NULL but not an error
|
||||
return true;
|
||||
}
|
||||
|
||||
// If window data marked as needing swapchain recreate, try to recreate
|
||||
if (windowData->needsSwapchainRecreate) {
|
||||
Uint32 recreateSwapchainResult = VULKAN_INTERNAL_RecreateSwapchain(renderer, windowData);
|
||||
@@ -9895,13 +9984,6 @@ static bool VULKAN_INTERNAL_AcquireSwapchainTexture(
|
||||
}
|
||||
}
|
||||
|
||||
if (swapchainTextureWidth) {
|
||||
*swapchainTextureWidth = windowData->width;
|
||||
}
|
||||
if (swapchainTextureHeight) {
|
||||
*swapchainTextureHeight = windowData->height;
|
||||
}
|
||||
|
||||
if (windowData->inFlightFences[windowData->frameCounter] != NULL) {
|
||||
if (block) {
|
||||
// If we are blocking, just wait for the fence!
|
||||
@@ -9953,6 +10035,14 @@ static bool VULKAN_INTERNAL_AcquireSwapchainTexture(
|
||||
}
|
||||
}
|
||||
|
||||
if (swapchainTextureWidth) {
|
||||
*swapchainTextureWidth = windowData->width;
|
||||
}
|
||||
|
||||
if (swapchainTextureHeight) {
|
||||
*swapchainTextureHeight = windowData->height;
|
||||
}
|
||||
|
||||
swapchainTextureContainer = &windowData->textureContainers[swapchainImageIndex];
|
||||
|
||||
// We need a special execution dependency with pWaitDstStageMask or image transition can start before acquire finishes
|
||||
@@ -10021,7 +10111,7 @@ static bool VULKAN_INTERNAL_AcquireSwapchainTexture(
|
||||
}
|
||||
|
||||
vulkanCommandBuffer->signalSemaphores[vulkanCommandBuffer->signalSemaphoreCount] =
|
||||
windowData->renderFinishedSemaphore[windowData->frameCounter];
|
||||
windowData->renderFinishedSemaphore[swapchainImageIndex];
|
||||
vulkanCommandBuffer->signalSemaphoreCount += 1;
|
||||
|
||||
*swapchainTexture = (SDL_GPUTexture *)swapchainTextureContainer;
|
||||
@@ -10330,6 +10420,7 @@ static void VULKAN_INTERNAL_CleanCommandBuffer(
|
||||
commandBuffer->presentDataCount = 0;
|
||||
commandBuffer->waitSemaphoreCount = 0;
|
||||
commandBuffer->signalSemaphoreCount = 0;
|
||||
commandBuffer->swapchainRequested = false;
|
||||
|
||||
// Reset defrag state
|
||||
|
||||
@@ -10427,11 +10518,18 @@ static bool VULKAN_Wait(
|
||||
VkResult result;
|
||||
Sint32 i;
|
||||
|
||||
SDL_LockMutex(renderer->submitLock);
|
||||
|
||||
result = renderer->vkDeviceWaitIdle(renderer->logicalDevice);
|
||||
|
||||
CHECK_VULKAN_ERROR_AND_RETURN(result, vkDeviceWaitIdle, false);
|
||||
|
||||
SDL_LockMutex(renderer->submitLock);
|
||||
if (result != VK_SUCCESS) {
|
||||
if (renderer->debugMode) {
|
||||
SDL_LogError(SDL_LOG_CATEGORY_GPU, "%s %s", "vkDeviceWaitIdle", VkErrorMessages(result));
|
||||
}
|
||||
SDL_SetError("%s %s", "vkDeviceWaitIdle", VkErrorMessages(result));
|
||||
SDL_UnlockMutex(renderer->submitLock);
|
||||
return false;
|
||||
}
|
||||
|
||||
for (i = renderer->submittedCommandBufferCount - 1; i >= 0; i -= 1) {
|
||||
commandBuffer = renderer->submittedCommandBuffers[i];
|
||||
@@ -10486,7 +10584,7 @@ static bool VULKAN_Submit(
|
||||
VulkanTextureSubresource *swapchainTextureSubresource;
|
||||
VulkanMemorySubAllocator *allocator;
|
||||
bool performCleanups =
|
||||
(renderer->claimedWindowCount > 0 && vulkanCommandBuffer->presentDataCount > 0) ||
|
||||
(renderer->claimedWindowCount > 0 && vulkanCommandBuffer->swapchainRequested) ||
|
||||
renderer->claimedWindowCount == 0;
|
||||
|
||||
SDL_LockMutex(renderer->submitLock);
|
||||
@@ -10562,7 +10660,7 @@ static bool VULKAN_Submit(
|
||||
presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
|
||||
presentInfo.pNext = NULL;
|
||||
presentInfo.pWaitSemaphores =
|
||||
&presentData->windowData->renderFinishedSemaphore[presentData->windowData->frameCounter];
|
||||
&presentData->windowData->renderFinishedSemaphore[presentData->swapchainImageIndex];
|
||||
presentInfo.waitSemaphoreCount = 1;
|
||||
presentInfo.pSwapchains = &presentData->windowData->swapchain;
|
||||
presentInfo.swapchainCount = 1;
|
||||
@@ -10578,7 +10676,13 @@ static bool VULKAN_Submit(
|
||||
presentData->windowData->inFlightFences[presentData->windowData->frameCounter] = (SDL_GPUFence*)vulkanCommandBuffer->inFlightFence;
|
||||
(void)SDL_AtomicIncRef(&vulkanCommandBuffer->inFlightFence->referenceCount);
|
||||
|
||||
if (presentResult == VK_SUBOPTIMAL_KHR || presentResult == VK_ERROR_OUT_OF_DATE_KHR) {
|
||||
// On the Android platform, VK_SUBOPTIMAL_KHR is returned whenever the device is rotated. We'll just ignore this for now.
|
||||
#ifndef SDL_PLATFORM_ANDROID
|
||||
if (presentResult == VK_SUBOPTIMAL_KHR) {
|
||||
presentData->windowData->needsSwapchainRecreate = true;
|
||||
}
|
||||
#endif
|
||||
if (presentResult == VK_ERROR_OUT_OF_DATE_KHR) {
|
||||
presentData->windowData->needsSwapchainRecreate = true;
|
||||
}
|
||||
} else {
|
||||
@@ -10956,7 +11060,8 @@ static Uint8 VULKAN_INTERNAL_CheckInstanceExtensions(
|
||||
const char **requiredExtensions,
|
||||
Uint32 requiredExtensionsLength,
|
||||
bool *supportsDebugUtils,
|
||||
bool *supportsColorspace)
|
||||
bool *supportsColorspace,
|
||||
bool *supportsPhysicalDeviceProperties2)
|
||||
{
|
||||
Uint32 extensionCount, i;
|
||||
VkExtensionProperties *availableExtensions;
|
||||
@@ -10995,6 +11100,12 @@ static Uint8 VULKAN_INTERNAL_CheckInstanceExtensions(
|
||||
availableExtensions,
|
||||
extensionCount);
|
||||
|
||||
// Only needed for KHR_driver_properties!
|
||||
*supportsPhysicalDeviceProperties2 = SupportsInstanceExtension(
|
||||
VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME,
|
||||
availableExtensions,
|
||||
extensionCount);
|
||||
|
||||
SDL_free(availableExtensions);
|
||||
return allExtensionsSupported;
|
||||
}
|
||||
@@ -11105,10 +11216,6 @@ static Uint8 VULKAN_INTERNAL_CreateInstance(VulkanRenderer *renderer)
|
||||
instanceExtensionCount + 4);
|
||||
SDL_memcpy((void *)instanceExtensionNames, originalInstanceExtensionNames, instanceExtensionCount * sizeof(const char *));
|
||||
|
||||
// Core since 1.1
|
||||
instanceExtensionNames[instanceExtensionCount++] =
|
||||
VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME;
|
||||
|
||||
#ifdef SDL_PLATFORM_APPLE
|
||||
instanceExtensionNames[instanceExtensionCount++] =
|
||||
VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME;
|
||||
@@ -11119,7 +11226,8 @@ static Uint8 VULKAN_INTERNAL_CreateInstance(VulkanRenderer *renderer)
|
||||
instanceExtensionNames,
|
||||
instanceExtensionCount,
|
||||
&renderer->supportsDebugUtils,
|
||||
&renderer->supportsColorspace)) {
|
||||
&renderer->supportsColorspace,
|
||||
&renderer->supportsPhysicalDeviceProperties2)) {
|
||||
SDL_stack_free((char *)instanceExtensionNames);
|
||||
SET_STRING_ERROR_AND_RETURN("Required Vulkan instance extensions not supported", false);
|
||||
}
|
||||
@@ -11141,6 +11249,12 @@ static Uint8 VULKAN_INTERNAL_CreateInstance(VulkanRenderer *renderer)
|
||||
VK_EXT_SWAPCHAIN_COLOR_SPACE_EXTENSION_NAME;
|
||||
}
|
||||
|
||||
if (renderer->supportsPhysicalDeviceProperties2) {
|
||||
// Append KHR_physical_device_properties2 extension
|
||||
instanceExtensionNames[instanceExtensionCount++] =
|
||||
VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME;
|
||||
}
|
||||
|
||||
createInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
|
||||
createInfo.pNext = NULL;
|
||||
createInfo.flags = createFlags;
|
||||
@@ -11601,7 +11715,7 @@ static bool VULKAN_PrepareDriver(SDL_VideoDevice *_this)
|
||||
{
|
||||
// Set up dummy VulkanRenderer
|
||||
VulkanRenderer *renderer;
|
||||
Uint8 result;
|
||||
bool result = false;
|
||||
|
||||
if (_this->Vulkan_CreateSurface == NULL) {
|
||||
return false;
|
||||
@@ -11611,16 +11725,16 @@ static bool VULKAN_PrepareDriver(SDL_VideoDevice *_this)
|
||||
return false;
|
||||
}
|
||||
|
||||
renderer = (VulkanRenderer *)SDL_malloc(sizeof(VulkanRenderer));
|
||||
SDL_memset(renderer, '\0', sizeof(VulkanRenderer));
|
||||
|
||||
result = VULKAN_INTERNAL_PrepareVulkan(renderer);
|
||||
|
||||
if (result) {
|
||||
renderer->vkDestroyInstance(renderer->instance, NULL);
|
||||
renderer = (VulkanRenderer *)SDL_calloc(1, sizeof(*renderer));
|
||||
if (renderer) {
|
||||
result = VULKAN_INTERNAL_PrepareVulkan(renderer);
|
||||
if (result) {
|
||||
renderer->vkDestroyInstance(renderer->instance, NULL);
|
||||
}
|
||||
SDL_free(renderer);
|
||||
}
|
||||
SDL_free(renderer);
|
||||
SDL_Vulkan_UnloadLibrary();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -11636,16 +11750,21 @@ static SDL_GPUDevice *VULKAN_CreateDevice(bool debugMode, bool preferLowPower, S
|
||||
return NULL;
|
||||
}
|
||||
|
||||
renderer = (VulkanRenderer *)SDL_malloc(sizeof(VulkanRenderer));
|
||||
SDL_memset(renderer, '\0', sizeof(VulkanRenderer));
|
||||
renderer = (VulkanRenderer *)SDL_calloc(1, sizeof(*renderer));
|
||||
if (!renderer) {
|
||||
SDL_Vulkan_UnloadLibrary();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
renderer->debugMode = debugMode;
|
||||
renderer->preferLowPower = preferLowPower;
|
||||
renderer->allowedFramesInFlight = 2;
|
||||
|
||||
if (!VULKAN_INTERNAL_PrepareVulkan(renderer)) {
|
||||
SET_STRING_ERROR("Failed to initialize Vulkan!");
|
||||
SDL_free(renderer);
|
||||
SDL_Vulkan_UnloadLibrary();
|
||||
SET_STRING_ERROR_AND_RETURN("Failed to initialize Vulkan!", NULL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
SDL_LogInfo(SDL_LOG_CATEGORY_GPU, "SDL_GPU Driver: Vulkan");
|
||||
@@ -11671,16 +11790,18 @@ static SDL_GPUDevice *VULKAN_CreateDevice(bool debugMode, bool preferLowPower, S
|
||||
|
||||
if (!VULKAN_INTERNAL_CreateLogicalDevice(
|
||||
renderer)) {
|
||||
SET_STRING_ERROR("Failed to create logical device!");
|
||||
SDL_free(renderer);
|
||||
SDL_Vulkan_UnloadLibrary();
|
||||
SET_STRING_ERROR_AND_RETURN("Failed to create logical device!", NULL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// FIXME: just move this into this function
|
||||
result = (SDL_GPUDevice *)SDL_malloc(sizeof(SDL_GPUDevice));
|
||||
result = (SDL_GPUDevice *)SDL_calloc(1, sizeof(SDL_GPUDevice));
|
||||
ASSIGN_DRIVER(VULKAN)
|
||||
|
||||
result->driverData = (SDL_GPURenderer *)renderer;
|
||||
result->shader_formats = SDL_GPU_SHADERFORMAT_SPIRV;
|
||||
|
||||
/*
|
||||
* Create initial swapchain array
|
||||
|
||||
@@ -1117,13 +1117,12 @@ bool SDL_SYS_HapticResume(SDL_Haptic *haptic)
|
||||
*/
|
||||
bool SDL_SYS_HapticStopAll(SDL_Haptic *haptic)
|
||||
{
|
||||
int i, ret;
|
||||
int i;
|
||||
|
||||
// Linux does not support this natively so we have to loop.
|
||||
for (i = 0; i < haptic->neffects; i++) {
|
||||
if (haptic->effects[i].hweffect != NULL) {
|
||||
ret = SDL_SYS_HapticStopEffect(haptic, &haptic->effects[i]);
|
||||
if (ret < 0) {
|
||||
if (!SDL_SYS_HapticStopEffect(haptic, &haptic->effects[i])) {
|
||||
return SDL_SetError("Haptic: Error while trying to stop all playing effects.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,11 +31,7 @@
|
||||
/*
|
||||
* External stuff.
|
||||
*/
|
||||
#ifdef SDL_VIDEO_DRIVER_WINDOWS
|
||||
extern HWND SDL_HelperWindow;
|
||||
#else
|
||||
static const HWND SDL_HelperWindow = NULL;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Internal stuff.
|
||||
|
||||
Loaded 100 of 228 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user