From 9b1d91b4c68477145434021ea7392c16d849ebaa Mon Sep 17 00:00:00 2001 From: David Thompson Date: Wed, 2 Oct 2024 21:22:19 -0400 Subject: First commit! --- .gitignore | 11 + COPYING | 202 ++++++++ Makefile.am | 63 +++ README.md | 46 ++ bootstrap | 3 + configure.ac | 44 ++ examples/cube.scm | 557 +++++++++++++++++++++ examples/window.scm | 7 + guix.scm | 149 ++++++ pre-inst-env.in | 28 ++ sdl3.scm | 67 +++ sdl3/bindings/error.scm | 26 + sdl3/bindings/events.scm | 750 ++++++++++++++++++++++++++++ sdl3/bindings/gpu.scm | 1190 +++++++++++++++++++++++++++++++++++++++++++++ sdl3/bindings/init.scm | 49 ++ sdl3/bindings/pixels.scm | 41 ++ sdl3/bindings/surface.scm | 36 ++ sdl3/bindings/utils.scm | 133 +++++ sdl3/bindings/video.scm | 103 ++++ sdl3/config.scm.in | 26 + sdl3/errors.scm | 54 ++ sdl3/events.scm | 43 ++ sdl3/gpu.scm | 966 ++++++++++++++++++++++++++++++++++++ sdl3/guardian.scm | 30 ++ sdl3/video.scm | 85 ++++ 25 files changed, 4709 insertions(+) create mode 100644 .gitignore create mode 100644 COPYING create mode 100644 Makefile.am create mode 100644 README.md create mode 100755 bootstrap create mode 100644 configure.ac create mode 100644 examples/cube.scm create mode 100644 examples/window.scm create mode 100644 guix.scm create mode 100644 pre-inst-env.in create mode 100644 sdl3.scm create mode 100644 sdl3/bindings/error.scm create mode 100644 sdl3/bindings/events.scm create mode 100644 sdl3/bindings/gpu.scm create mode 100644 sdl3/bindings/init.scm create mode 100644 sdl3/bindings/pixels.scm create mode 100644 sdl3/bindings/surface.scm create mode 100644 sdl3/bindings/utils.scm create mode 100644 sdl3/bindings/video.scm create mode 100644 sdl3/config.scm.in create mode 100644 sdl3/errors.scm create mode 100644 sdl3/events.scm create mode 100644 sdl3/gpu.scm create mode 100644 sdl3/guardian.scm create mode 100644 sdl3/video.scm diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..af9fe7e --- /dev/null +++ b/.gitignore @@ -0,0 +1,11 @@ +*.go +/Makefile.in +/aclocal.m4 +/autom4te.cache/ +/build-aux/ +/config.log +/configure +/pre-inst-env +/config.status +/Makefile +/sdl3/config.scm diff --git a/COPYING b/COPYING new file mode 100644 index 0000000..d645695 --- /dev/null +++ b/COPYING @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 0000000..bea7843 --- /dev/null +++ b/Makefile.am @@ -0,0 +1,63 @@ +# guile-sdl3 -- Scheme bindings for SDL3 +# Copyright © 2024 David Thompson +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +GOBJECTS = $(SOURCES:%.scm=%.go) + +nobase_mod_DATA = $(SOURCES) $(NOCOMP_SOURCES) +nobase_go_DATA = $(GOBJECTS) + +# Make sure source files are installed first, so that the mtime of +# installed compiled files is greater than that of installed source +# files. See +# +# for details. +guile_install_go_files = install-nobase_goDATA +$(guile_install_go_files): install-nobase_modDATA + +CLEANFILES = $(GOBJECTS) +EXTRA_DIST = $(SOURCES) $(NOCOMP_SOURCES) +GUILE_WARNINGS = -Wunbound-variable -Warity-mismatch -Wformat +SUFFIXES = .scm .go +.scm.go: + $(AM_V_GEN)$(top_builddir)/pre-inst-env $(GUILE_TOOLS) compile $(GUILE_WARNINGS) -o "$@" "$<" + +moddir=$(prefix)/share/guile/site/$(GUILE_EFFECTIVE_VERSION) +godir=$(libdir)/guile/$(GUILE_EFFECTIVE_VERSION)/site-ccache + +SOURCES = \ + sdl3/config.scm \ + sdl3/guardian.scm \ + sdl3/bindings/utils.scm \ + sdl3/bindings/error.scm \ + sdl3/bindings/init.scm \ + sdl3/bindings/video.scm \ + sdl3/bindings/events.scm \ + sdl3/bindings/pixels.scm \ + sdl3/bindings/surface.scm \ + sdl3/bindings/gpu.scm \ + sdl3/errors.scm \ + sdl3/video.scm \ + sdl3/events.scm \ + sdl3/gpu.scm \ + sdl3.scm + +EXTRA_DIST += \ + pre-inst-env.in \ + README \ + guix.scm \ + run-example \ + examples/hello.scm \ + examples/hello.bmp \ + examples/controller.scm diff --git a/README.md b/README.md new file mode 100644 index 0000000..e1dddef --- /dev/null +++ b/README.md @@ -0,0 +1,46 @@ +# Guile-SDL3 + +Guile-SDL3 provides Guile Scheme bindings for the SDL3 library. + +## Requirements + +- Guile >= 3.0 +- SDL3 >= 3.0.0 +- make +- pkg-config + +When building from a Git checkout, the following additional packages +are required: + +- autoconf +- automake +- texinfo + +If you use Guix, a build environment can be created by running `guix +shell`. + +## Building + +### From release tarball + +``` +./configure +make +make install +``` + +### From Git checkout + +``` +./bootstrap +./configure +make +make install +``` + +## Contributing + +In lieu of a proper issue tracker, send patches and bug reports to +. Discussion can be had on the #guile +channel on the Libera.Chat IRC network or on the guile-user mailing +lis. diff --git a/bootstrap b/bootstrap new file mode 100755 index 0000000..872167c --- /dev/null +++ b/bootstrap @@ -0,0 +1,3 @@ +#!/bin/sh + +autoreconf -vif diff --git a/configure.ac b/configure.ac new file mode 100644 index 0000000..83b8a81 --- /dev/null +++ b/configure.ac @@ -0,0 +1,44 @@ +# -*- Autoconf -*- +# +# guile-sdl3 -- Scheme bindings for SDL3 +# Copyright © 2024 David Thompson +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +AC_INIT(guile-sdl3, 0.1.0) +AC_CONFIG_SRCDIR(sdl3) +AC_CONFIG_AUX_DIR([build-aux]) +AM_INIT_AUTOMAKE([color-tests -Wall -Wno-portability foreign]) +AM_SILENT_RULES([yes]) + +AC_PATH_PROG([GUILE], [guile]) +AC_CONFIG_FILES([Makefile sdl3/config.scm]) +AC_CONFIG_FILES([pre-inst-env], [chmod +x pre-inst-env]) + +GUILE_PKG([3.0]) +GUILE_PROGS + +GUILE_MODULE_REQUIRED([bstruct]) + +# Core SDL3 +PKG_CHECK_MODULES([SDL3], [sdl3]) +PKG_CHECK_VAR([SDL3_LIBDIR], [sdl3], [libdir]) +AC_MSG_CHECKING([SDL3 library path]) +AS_IF([test "x$SDL3_LIBDIR" = "x"], [ + AC_MSG_FAILURE([unable to find SDL3 library directory]) +], [ + AC_MSG_RESULT([$SDL3_LIBDIR]) +]) +AC_SUBST([SDL3_LIBDIR]) + +AC_OUTPUT diff --git a/examples/cube.scm b/examples/cube.scm new file mode 100644 index 0000000..74e131c --- /dev/null +++ b/examples/cube.scm @@ -0,0 +1,557 @@ +;;; guile-sdl3 -- Scheme bindings for SDL3 +;;; Copyright © 2024 David Thompson +;;; +;;; Licensed under the Apache License, Version 2.0 (the "License"); +;;; you may not use this file except in compliance with the License. +;;; You may obtain a copy of the License at +;;; +;;; http://www.apache.org/licenses/LICENSE-2.0 +;;; +;;; Unless required by applicable law or agreed to in writing, software +;;; distributed under the License is distributed on an "AS IS" BASIS, +;;; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +;;; See the License for the specific language governing permissions and +;;; limitations under the License. + +;;; Commentary: +;; +;; Adapted from https://github.com/thatcosmonaut/SDL/blob/main/test/testgpu_spinning_cube.c +;; +;;; Code: + +(use-modules (bstruct) + (ice-9 match) + (rnrs bytevectors) + (sdl3) + (sdl3 events) + (sdl3 gpu) + (sdl3 video)) + +;; These SPIR-V blobs are taken directly from SDL. +(define vert-spirv + #vu8(#x03 #x02 #x23 #x07 #x00 #x00 #x01 #x00 #x0b #x00 #x08 #x00 + #x2a #x00 #x00 #x00 #x00 #x00 #x00 #x00 #x11 #x00 #x02 #x00 + #x01 #x00 #x00 #x00 #x0b #x00 #x06 #x00 #x01 #x00 #x00 #x00 + #x47 #x4c #x53 #x4c #x2e #x73 #x74 #x64 #x2e #x34 #x35 #x30 + #x00 #x00 #x00 #x00 #x0e #x00 #x03 #x00 #x00 #x00 #x00 #x00 + #x01 #x00 #x00 #x00 #x0f #x00 #x09 #x00 #x00 #x00 #x00 #x00 + #x04 #x00 #x00 #x00 #x6d #x61 #x69 #x6e #x00 #x00 #x00 #x00 + #x09 #x00 #x00 #x00 #x0c #x00 #x00 #x00 #x18 #x00 #x00 #x00 + #x22 #x00 #x00 #x00 #x03 #x00 #x03 #x00 #x02 #x00 #x00 #x00 + #xc2 #x01 #x00 #x00 #x05 #x00 #x04 #x00 #x04 #x00 #x00 #x00 + #x6d #x61 #x69 #x6e #x00 #x00 #x00 #x00 #x05 #x00 #x05 #x00 + #x09 #x00 #x00 #x00 #x6f #x75 #x74 #x5f #x63 #x6f #x6c #x6f + #x72 #x00 #x00 #x00 #x05 #x00 #x05 #x00 #x0c #x00 #x00 #x00 + #x69 #x6e #x5f #x63 #x6f #x6c #x6f #x72 #x00 #x00 #x00 #x00 + #x05 #x00 #x06 #x00 #x16 #x00 #x00 #x00 #x67 #x6c #x5f #x50 + #x65 #x72 #x56 #x65 #x72 #x74 #x65 #x78 #x00 #x00 #x00 #x00 + #x06 #x00 #x06 #x00 #x16 #x00 #x00 #x00 #x00 #x00 #x00 #x00 + #x67 #x6c #x5f #x50 #x6f #x73 #x69 #x74 #x69 #x6f #x6e #x00 + #x06 #x00 #x07 #x00 #x16 #x00 #x00 #x00 #x01 #x00 #x00 #x00 + #x67 #x6c #x5f #x50 #x6f #x69 #x6e #x74 #x53 #x69 #x7a #x65 + #x00 #x00 #x00 #x00 #x06 #x00 #x07 #x00 #x16 #x00 #x00 #x00 + #x02 #x00 #x00 #x00 #x67 #x6c #x5f #x43 #x6c #x69 #x70 #x44 + #x69 #x73 #x74 #x61 #x6e #x63 #x65 #x00 #x06 #x00 #x07 #x00 + #x16 #x00 #x00 #x00 #x03 #x00 #x00 #x00 #x67 #x6c #x5f #x43 + #x75 #x6c #x6c #x44 #x69 #x73 #x74 #x61 #x6e #x63 #x65 #x00 + #x05 #x00 #x03 #x00 #x18 #x00 #x00 #x00 #x00 #x00 #x00 #x00 + #x05 #x00 #x03 #x00 #x1c #x00 #x00 #x00 #x55 #x42 #x4f #x00 + #x06 #x00 #x07 #x00 #x1c #x00 #x00 #x00 #x00 #x00 #x00 #x00 + #x6d #x6f #x64 #x65 #x6c #x56 #x69 #x65 #x77 #x50 #x72 #x6f + #x6a #x00 #x00 #x00 #x05 #x00 #x03 #x00 #x1e #x00 #x00 #x00 + #x00 #x00 #x00 #x00 #x05 #x00 #x05 #x00 #x22 #x00 #x00 #x00 + #x69 #x6e #x5f #x70 #x6f #x73 #x69 #x74 #x69 #x6f #x6e #x00 + #x47 #x00 #x04 #x00 #x09 #x00 #x00 #x00 #x1e #x00 #x00 #x00 + #x00 #x00 #x00 #x00 #x47 #x00 #x04 #x00 #x0c #x00 #x00 #x00 + #x1e #x00 #x00 #x00 #x01 #x00 #x00 #x00 #x48 #x00 #x05 #x00 + #x16 #x00 #x00 #x00 #x00 #x00 #x00 #x00 #x0b #x00 #x00 #x00 + #x00 #x00 #x00 #x00 #x48 #x00 #x05 #x00 #x16 #x00 #x00 #x00 + #x01 #x00 #x00 #x00 #x0b #x00 #x00 #x00 #x01 #x00 #x00 #x00 + #x48 #x00 #x05 #x00 #x16 #x00 #x00 #x00 #x02 #x00 #x00 #x00 + #x0b #x00 #x00 #x00 #x03 #x00 #x00 #x00 #x48 #x00 #x05 #x00 + #x16 #x00 #x00 #x00 #x03 #x00 #x00 #x00 #x0b #x00 #x00 #x00 + #x04 #x00 #x00 #x00 #x47 #x00 #x03 #x00 #x16 #x00 #x00 #x00 + #x02 #x00 #x00 #x00 #x48 #x00 #x04 #x00 #x1c #x00 #x00 #x00 + #x00 #x00 #x00 #x00 #x05 #x00 #x00 #x00 #x48 #x00 #x05 #x00 + #x1c #x00 #x00 #x00 #x00 #x00 #x00 #x00 #x23 #x00 #x00 #x00 + #x00 #x00 #x00 #x00 #x48 #x00 #x05 #x00 #x1c #x00 #x00 #x00 + #x00 #x00 #x00 #x00 #x07 #x00 #x00 #x00 #x10 #x00 #x00 #x00 + #x47 #x00 #x03 #x00 #x1c #x00 #x00 #x00 #x02 #x00 #x00 #x00 + #x47 #x00 #x04 #x00 #x1e #x00 #x00 #x00 #x22 #x00 #x00 #x00 + #x01 #x00 #x00 #x00 #x47 #x00 #x04 #x00 #x1e #x00 #x00 #x00 + #x21 #x00 #x00 #x00 #x00 #x00 #x00 #x00 #x47 #x00 #x04 #x00 + #x22 #x00 #x00 #x00 #x1e #x00 #x00 #x00 #x00 #x00 #x00 #x00 + #x13 #x00 #x02 #x00 #x02 #x00 #x00 #x00 #x21 #x00 #x03 #x00 + #x03 #x00 #x00 #x00 #x02 #x00 #x00 #x00 #x16 #x00 #x03 #x00 + #x06 #x00 #x00 #x00 #x20 #x00 #x00 #x00 #x17 #x00 #x04 #x00 + #x07 #x00 #x00 #x00 #x06 #x00 #x00 #x00 #x04 #x00 #x00 #x00 + #x20 #x00 #x04 #x00 #x08 #x00 #x00 #x00 #x03 #x00 #x00 #x00 + #x07 #x00 #x00 #x00 #x3b #x00 #x04 #x00 #x08 #x00 #x00 #x00 + #x09 #x00 #x00 #x00 #x03 #x00 #x00 #x00 #x17 #x00 #x04 #x00 + #x0a #x00 #x00 #x00 #x06 #x00 #x00 #x00 #x03 #x00 #x00 #x00 + #x20 #x00 #x04 #x00 #x0b #x00 #x00 #x00 #x01 #x00 #x00 #x00 + #x0a #x00 #x00 #x00 #x3b #x00 #x04 #x00 #x0b #x00 #x00 #x00 + #x0c #x00 #x00 #x00 #x01 #x00 #x00 #x00 #x2b #x00 #x04 #x00 + #x06 #x00 #x00 #x00 #x0e #x00 #x00 #x00 #x00 #x00 #x80 #x3f + #x15 #x00 #x04 #x00 #x13 #x00 #x00 #x00 #x20 #x00 #x00 #x00 + #x00 #x00 #x00 #x00 #x2b #x00 #x04 #x00 #x13 #x00 #x00 #x00 + #x14 #x00 #x00 #x00 #x01 #x00 #x00 #x00 #x1c #x00 #x04 #x00 + #x15 #x00 #x00 #x00 #x06 #x00 #x00 #x00 #x14 #x00 #x00 #x00 + #x1e #x00 #x06 #x00 #x16 #x00 #x00 #x00 #x07 #x00 #x00 #x00 + #x06 #x00 #x00 #x00 #x15 #x00 #x00 #x00 #x15 #x00 #x00 #x00 + #x20 #x00 #x04 #x00 #x17 #x00 #x00 #x00 #x03 #x00 #x00 #x00 + #x16 #x00 #x00 #x00 #x3b #x00 #x04 #x00 #x17 #x00 #x00 #x00 + #x18 #x00 #x00 #x00 #x03 #x00 #x00 #x00 #x15 #x00 #x04 #x00 + #x19 #x00 #x00 #x00 #x20 #x00 #x00 #x00 #x01 #x00 #x00 #x00 + #x2b #x00 #x04 #x00 #x19 #x00 #x00 #x00 #x1a #x00 #x00 #x00 + #x00 #x00 #x00 #x00 #x18 #x00 #x04 #x00 #x1b #x00 #x00 #x00 + #x07 #x00 #x00 #x00 #x04 #x00 #x00 #x00 #x1e #x00 #x03 #x00 + #x1c #x00 #x00 #x00 #x1b #x00 #x00 #x00 #x20 #x00 #x04 #x00 + #x1d #x00 #x00 #x00 #x02 #x00 #x00 #x00 #x1c #x00 #x00 #x00 + #x3b #x00 #x04 #x00 #x1d #x00 #x00 #x00 #x1e #x00 #x00 #x00 + #x02 #x00 #x00 #x00 #x20 #x00 #x04 #x00 #x1f #x00 #x00 #x00 + #x02 #x00 #x00 #x00 #x1b #x00 #x00 #x00 #x3b #x00 #x04 #x00 + #x0b #x00 #x00 #x00 #x22 #x00 #x00 #x00 #x01 #x00 #x00 #x00 + #x36 #x00 #x05 #x00 #x02 #x00 #x00 #x00 #x04 #x00 #x00 #x00 + #x00 #x00 #x00 #x00 #x03 #x00 #x00 #x00 #xf8 #x00 #x02 #x00 + #x05 #x00 #x00 #x00 #x3d #x00 #x04 #x00 #x0a #x00 #x00 #x00 + #x0d #x00 #x00 #x00 #x0c #x00 #x00 #x00 #x51 #x00 #x05 #x00 + #x06 #x00 #x00 #x00 #x0f #x00 #x00 #x00 #x0d #x00 #x00 #x00 + #x00 #x00 #x00 #x00 #x51 #x00 #x05 #x00 #x06 #x00 #x00 #x00 + #x10 #x00 #x00 #x00 #x0d #x00 #x00 #x00 #x01 #x00 #x00 #x00 + #x51 #x00 #x05 #x00 #x06 #x00 #x00 #x00 #x11 #x00 #x00 #x00 + #x0d #x00 #x00 #x00 #x02 #x00 #x00 #x00 #x50 #x00 #x07 #x00 + #x07 #x00 #x00 #x00 #x12 #x00 #x00 #x00 #x0f #x00 #x00 #x00 + #x10 #x00 #x00 #x00 #x11 #x00 #x00 #x00 #x0e #x00 #x00 #x00 + #x3e #x00 #x03 #x00 #x09 #x00 #x00 #x00 #x12 #x00 #x00 #x00 + #x41 #x00 #x05 #x00 #x1f #x00 #x00 #x00 #x20 #x00 #x00 #x00 + #x1e #x00 #x00 #x00 #x1a #x00 #x00 #x00 #x3d #x00 #x04 #x00 + #x1b #x00 #x00 #x00 #x21 #x00 #x00 #x00 #x20 #x00 #x00 #x00 + #x3d #x00 #x04 #x00 #x0a #x00 #x00 #x00 #x23 #x00 #x00 #x00 + #x22 #x00 #x00 #x00 #x51 #x00 #x05 #x00 #x06 #x00 #x00 #x00 + #x24 #x00 #x00 #x00 #x23 #x00 #x00 #x00 #x00 #x00 #x00 #x00 + #x51 #x00 #x05 #x00 #x06 #x00 #x00 #x00 #x25 #x00 #x00 #x00 + #x23 #x00 #x00 #x00 #x01 #x00 #x00 #x00 #x51 #x00 #x05 #x00 + #x06 #x00 #x00 #x00 #x26 #x00 #x00 #x00 #x23 #x00 #x00 #x00 + #x02 #x00 #x00 #x00 #x50 #x00 #x07 #x00 #x07 #x00 #x00 #x00 + #x27 #x00 #x00 #x00 #x24 #x00 #x00 #x00 #x25 #x00 #x00 #x00 + #x26 #x00 #x00 #x00 #x0e #x00 #x00 #x00 #x91 #x00 #x05 #x00 + #x07 #x00 #x00 #x00 #x28 #x00 #x00 #x00 #x21 #x00 #x00 #x00 + #x27 #x00 #x00 #x00 #x41 #x00 #x05 #x00 #x08 #x00 #x00 #x00 + #x29 #x00 #x00 #x00 #x18 #x00 #x00 #x00 #x1a #x00 #x00 #x00 + #x3e #x00 #x03 #x00 #x29 #x00 #x00 #x00 #x28 #x00 #x00 #x00 + #xfd #x00 #x01 #x00 #x38 #x00 #x01 #x00)) +(define frag-spirv + #vu8( #x03 #x02 #x23 #x07 #x00 #x00 #x01 #x00 #x0b #x00 #x08 #x00 + #x0d #x00 #x00 #x00 #x00 #x00 #x00 #x00 #x11 #x00 #x02 #x00 + #x01 #x00 #x00 #x00 #x0b #x00 #x06 #x00 #x01 #x00 #x00 #x00 + #x47 #x4c #x53 #x4c #x2e #x73 #x74 #x64 #x2e #x34 #x35 #x30 + #x00 #x00 #x00 #x00 #x0e #x00 #x03 #x00 #x00 #x00 #x00 #x00 + #x01 #x00 #x00 #x00 #x0f #x00 #x07 #x00 #x04 #x00 #x00 #x00 + #x04 #x00 #x00 #x00 #x6d #x61 #x69 #x6e #x00 #x00 #x00 #x00 + #x09 #x00 #x00 #x00 #x0b #x00 #x00 #x00 #x10 #x00 #x03 #x00 + #x04 #x00 #x00 #x00 #x07 #x00 #x00 #x00 #x03 #x00 #x03 #x00 + #x02 #x00 #x00 #x00 #xc2 #x01 #x00 #x00 #x05 #x00 #x04 #x00 + #x04 #x00 #x00 #x00 #x6d #x61 #x69 #x6e #x00 #x00 #x00 #x00 + #x05 #x00 #x05 #x00 #x09 #x00 #x00 #x00 #x6f #x75 #x74 #x5f + #x63 #x6f #x6c #x6f #x72 #x00 #x00 #x00 #x05 #x00 #x05 #x00 + #x0b #x00 #x00 #x00 #x69 #x6e #x5f #x63 #x6f #x6c #x6f #x72 + #x00 #x00 #x00 #x00 #x47 #x00 #x04 #x00 #x09 #x00 #x00 #x00 + #x1e #x00 #x00 #x00 #x00 #x00 #x00 #x00 #x47 #x00 #x04 #x00 + #x0b #x00 #x00 #x00 #x1e #x00 #x00 #x00 #x00 #x00 #x00 #x00 + #x13 #x00 #x02 #x00 #x02 #x00 #x00 #x00 #x21 #x00 #x03 #x00 + #x03 #x00 #x00 #x00 #x02 #x00 #x00 #x00 #x16 #x00 #x03 #x00 + #x06 #x00 #x00 #x00 #x20 #x00 #x00 #x00 #x17 #x00 #x04 #x00 + #x07 #x00 #x00 #x00 #x06 #x00 #x00 #x00 #x04 #x00 #x00 #x00 + #x20 #x00 #x04 #x00 #x08 #x00 #x00 #x00 #x03 #x00 #x00 #x00 + #x07 #x00 #x00 #x00 #x3b #x00 #x04 #x00 #x08 #x00 #x00 #x00 + #x09 #x00 #x00 #x00 #x03 #x00 #x00 #x00 #x20 #x00 #x04 #x00 + #x0a #x00 #x00 #x00 #x01 #x00 #x00 #x00 #x07 #x00 #x00 #x00 + #x3b #x00 #x04 #x00 #x0a #x00 #x00 #x00 #x0b #x00 #x00 #x00 + #x01 #x00 #x00 #x00 #x36 #x00 #x05 #x00 #x02 #x00 #x00 #x00 + #x04 #x00 #x00 #x00 #x00 #x00 #x00 #x00 #x03 #x00 #x00 #x00 + #xf8 #x00 #x02 #x00 #x05 #x00 #x00 #x00 #x3d #x00 #x04 #x00 + #x07 #x00 #x00 #x00 #x0c #x00 #x00 #x00 #x0b #x00 #x00 #x00 + #x3e #x00 #x03 #x00 #x09 #x00 #x00 #x00 #x0c #x00 #x00 #x00 + #xfd #x00 #x01 #x00 #x38 #x00 #x01 #x00)) + +(define data-vert + #f32( + ;; Front face. + ;; Bottom left + -0.5 0.5 -0.5 1.0 0.0 0.0 ; red + 0.5 -0.5 -0.5 0.0 0.0 1.0 ; blue + -0.5 -0.5 -0.5 0.0 1.0 0.0 ; green + ;; Top right + -0.5 0.5 -0.5 1.0 0.0 0.0 ; red + 0.5 0.5 -0.5 1.0 1.0 0.0 ; yellow + 0.5 -0.5 -0.5 0.0 0.0 1.0 ; blue + ;; Left face + ;; Bottom left + -0.5 0.5 0.5 1.0 1.0 1.0 ; white + -0.5 -0.5 -0.5 0.0 1.0 0.0 ; green + -0.5 -0.5 0.5 0.0 1.0 1.0 ; cyan + ;; Top right + -0.5 0.5 0.5 1.0 1.0 1.0 ; white + -0.5 0.5 -0.5 1.0 0.0 0.0 ; red + -0.5 -0.5 -0.5 0.0 1.0 0.0 ; green + ;; Top face + ;; Bottom left + -0.5 0.5 0.5 1.0 1.0 1.0 ; white + 0.5 0.5 -0.5 1.0 1.0 0.0 ; yellow + -0.5 0.5 -0.5 1.0 0.0 0.0 ; red + ;; Top right + -0.5 0.5 0.5 1.0 1.0 1.0 ; white + 0.5 0.5 0.5 0.0 0.0 0.0 ; black + 0.5 0.5 -0.5 1.0 1.0 0.0 ; yellow + ;; Right face + ;; Bottom left + 0.5 0.5 -0.5 1.0 1.0 0.0 ; yellow + 0.5 -0.5 0.5 1.0 0.0 1.0 ; magenta + 0.5 -0.5 -0.5 0.0 0.0 1.0 ; blue + ;; Top right + 0.5 0.5 -0.5 1.0 1.0 0.0 ; yellow + 0.5 0.5 0.5 0.0 0.0 0.0 ; black + 0.5 -0.5 0.5 1.0 0.0 1.0 ; magenta + ;; Back face + ;; Bottom left + 0.5 0.5 0.5 0.0 0.0 0.0 ; black + -0.5 -0.5 0.5 0.0 1.0 1.0 ; cyan + 0.5 -0.5 0.5 1.0 0.0 1.0 ; magenta + ;; Top right + 0.5 0.5 0.5 0.0 0.0 0.0 ; black + -0.5 0.5 0.5 1.0 1.0 1.0 ; white + -0.5 -0.5 0.5 0.0 1.0 1.0 ; cyan + ;; Bottom face + ;; Bottom left + -0.5 -0.5 -0.5 0.0 1.0 0.0 ; green + 0.5 -0.5 0.5 1.0 0.0 1.0 ; magenta + -0.5 -0.5 0.5 0.0 1.0 1.0 ; cyan + ;; Top right + -0.5 -0.5 -0.5 0.0 1.0 0.0 ; green + 0.5 -0.5 -0.5 0.0 0.0 1.0 ; blue + 0.5 -0.5 0.5 1.0 0.0 1.0 ; magenta + )) + +;; Initialize SDL. All we need is the video subsystem. +(sdl-init '(video)) + +;; Open window. +(define window (make-window "SDL3 GPU" 800 600)) + +;; Create GPU device. +(define device (make-gpu-device '(spirv))) +(claim-window-for-gpu-device! device window) + +;; Create shaders. +(define shader-vert (make-gpu-shader device 'vertex 'spirv vert-spirv + #:uniform-buffers 1)) +(define shader-frag (make-gpu-shader device 'fragment 'spirv frag-spirv)) + +;; Create empty vertex buffer +(define nbytes-vert (bytevector-length data-vert)) +(define buffer-vert (make-gpu-buffer device nbytes-vert '(vertex))) +(set-gpu-buffer-name! device buffer-vert "vertex buffer") + +;; Create transfer buffer and copy vertex data into it. +(define buffer-transfer (make-gpu-transfer-buffer device nbytes-vert 'upload)) +(define mapped (map-gpu-transfer-buffer! device buffer-transfer nbytes-vert)) +(bytevector-copy! data-vert 0 mapped 0 nbytes-vert) +(unmap-gpu-transfer-buffer! device buffer-transfer) + +;; Upload vertex data to vertex buffer. +(define cmd (acquire-gpu-command-buffer device)) +(define copy-pass (begin-gpu-copy-pass cmd)) +(upload-to-gpu-buffer copy-pass buffer-transfer 0 buffer-vert 0 nbytes-vert) +(end-gpu-copy-pass copy-pass) +(submit-gpu-command-buffer! cmd) +(release-gpu-transfer-buffer! device buffer-transfer) + +;; Figure out our sample rate. +(define swapchain-texture-format (gpu-swapchain-texture-format device window)) +(define sample-count + (if (gpu-texture-supports-sample-count? device swapchain-texture-format 4) + 4 1)) + +;; Setup graphics pipeline. +(define color-target-desc + (make-gpu-color-target-description + #:format swapchain-texture-format)) +(define target-info + (make-gpu-graphics-pipeline-target-info + #:color-targets (vector color-target-desc) + #:depth-stencil-format 'd16-unorm)) +(define depth-stencil-state + (make-gpu-depth-stencil-state + #:compare-op 'less-or-equal)) +(define multisample-state + (make-gpu-multisample-state + #:sample-count sample-count)) +(define vertex-buffer-desc + (make-gpu-vertex-buffer-description + #:slot 0 + #:pitch (* 4 6))) +(define vertex-attrib-position + (make-gpu-vertex-attribute + #:buffer-slot 0 + #:format 'float3 + #:location 0)) +(define vertex-attrib-color + (make-gpu-vertex-attribute + #:buffer-slot 0 + #:format 'float3 + #:location 1 + #:offset (* 4 3))) +(define vertex-input-state + (make-gpu-vertex-input-state + #:vertex-buffer-descriptions (vector vertex-buffer-desc) + #:vertex-attributes (vector vertex-attrib-position + vertex-attrib-color))) +(define pipeline + (make-gpu-graphics-pipeline device + #:vertex-shader shader-vert + #:fragment-shader shader-frag + #:vertex-input-state vertex-input-state + #:multisample-state multisample-state + #:depth-stencil-state depth-stencil-state + #:target-info target-info)) + +;; Shaders can be released once the pipeline has been built. +(release-gpu-shader! device shader-vert) +(release-gpu-shader! device shader-frag) + +;; Create textures. +(define-values (width height) (window-size-in-pixels window)) +(define tex-depth + (make-gpu-texture device + #:format 'd16-unorm + #:width width + #:height height + #:sample-count sample-count + #:usage '(depth-stencil-target))) +(define tex-msaa + (make-gpu-texture device + #:format swapchain-texture-format + #:width width + #:height height + #:sample-count sample-count)) +(define tex-resolve + (make-gpu-texture device + #:format swapchain-texture-format + #:width width + #:height height + #:usage '(color-target sampler))) + +;; Transformation matrices. +(define pi 3.1415926535897932) +(define tau (* 2.0 pi)) +(define-bstruct (array 16 f32)) +(define (make-mat4) (bstruct-alloc )) +(define (make-identity-mat4) + (bstruct-alloc + + (0 1.0) (1 0.0) (2 0.0) (3 0.0) + (4 0.0) (5 1.0) (6 0.0) (7 0.0) + (8 0.0) (9 0.0) (10 1.0) (11 0.0) + (12 0.0) (13 0.0) (14 0.0) (15 1.0))) +(define (mat4-identity! m) + (bstruct-set! + m + (0 1.0) (1 0.0) (2 0.0) (3 0.0) + (4 0.0) (5 1.0) (6 0.0) (7 0.0) + (8 0.0) (9 0.0) (10 1.0) (11 0.0) + (12 0.0) (13 0.0) (14 0.0) (15 1.0))) +(define (mat4-perspective! m fovy aspect znear zfar) + (let ((f (/ 1.0 (tan (* fovy 0.5))))) + (bstruct-set! + m + (0 (/ f aspect)) (1 0.0) (2 0.0) (3 0.0) + (4 0.0) (5 f) (6 0.0) (7 0.0) + (8 0.0) (9 0.0) (10 (/ (+ znear zfar) (- znear zfar))) (11 -1.0) + (12 0.0) (13 0.0) (14 (/ (* 2.0 znear zfar) (- znear zfar))) (15 0.0)))) +(define (mat4-rotate! m angle x y z) + (let* ((c (cos angle)) + (s (sin angle)) + (xx (* x x)) + (yy (* y y)) + (zz (* z z)) + (xy (* x y)) + (xz (* x z)) + (yz (* y z))) + (bstruct-set! + m + (0 (+ xx (* c (- 1.0 xx)))) + (1 (+ (- xy (* c xy)) (* s z))) + (2 (- xz (* c xz) (* s y))) + (3 0.0) + (4 (- xy (* c xy) (* s z))) + (5 (+ yy (* c (- 1.0 yy)))) + (6 (+ (- yz (* c yz)) (* s x))) + (7 0.0) + (8 (+ (- xz (* c xz)) (* s y))) + (9 (- yz (* c yz) (* s x))) + (10 (+ zz (* c (- 1.0 zz)))) + (11 0.0) + (12 0.0) + (13 0.0) + (14 0.0) + (15 1.0)))) +(define (mat4-mult! a b c) + (let ((a0 (bstruct-ref a 0)) + (a1 (bstruct-ref a 1)) + (a2 (bstruct-ref a 2)) + (a3 (bstruct-ref a 3)) + (a4 (bstruct-ref a 4)) + (a5 (bstruct-ref a 5)) + (a6 (bstruct-ref a 6)) + (a7 (bstruct-ref a 7)) + (a8 (bstruct-ref a 8)) + (a9 (bstruct-ref a 9)) + (a10 (bstruct-ref a 10)) + (a11 (bstruct-ref a 11)) + (a12 (bstruct-ref a 12)) + (a13 (bstruct-ref a 13)) + (a14 (bstruct-ref a 14)) + (a15 (bstruct-ref a 15)) + (b0 (bstruct-ref b 0)) + (b1 (bstruct-ref b 1)) + (b2 (bstruct-ref b 2)) + (b3 (bstruct-ref b 3)) + (b4 (bstruct-ref b 4)) + (b5 (bstruct-ref b 5)) + (b6 (bstruct-ref b 6)) + (b7 (bstruct-ref b 7)) + (b8 (bstruct-ref b 8)) + (b9 (bstruct-ref b 9)) + (b10 (bstruct-ref b 10)) + (b11 (bstruct-ref b 11)) + (b12 (bstruct-ref b 12)) + (b13 (bstruct-ref b 13)) + (b14 (bstruct-ref b 14)) + (b15 (bstruct-ref b 15))) + (bstruct-set! + c + (0 (+ (* a0 b0) (* a1 b4) (* a2 b8) (* a3 b12))) + (1 (+ (* a0 b1) (* a1 b5) (* a2 b9) (* a3 b13))) + (2 (+ (* a0 b2) (* a1 b6) (* a2 b10) (* a3 b14))) + (3 (+ (* a0 b3) (* a1 b7) (* a2 b11) (* a3 b15))) + (4 (+ (* a4 b0) (* a5 b4) (* a6 b8) (* a7 b12))) + (5 (+ (* a4 b1) (* a5 b5) (* a6 b9) (* a7 b13))) + (6 (+ (* a4 b2) (* a5 b6) (* a6 b10) (* a7 b14))) + (7 (+ (* a4 b3) (* a5 b7) (* a6 b11) (* a7 b15))) + (8 (+ (* a8 b0) (* a9 b4) (* a10 b8) (* a11 b12))) + (9 (+ (* a8 b1) (* a9 b5) (* a10 b9) (* a11 b13))) + (10 (+ (* a8 b2) (* a9 b6) (* a10 b10) (* a11 b14))) + (11 (+ (* a8 b3) (* a9 b7) (* a10 b11) (* a11 b15))) + (12 (+ (* a12 b0) (* a13 b4) (* a14 b8) (* a15 b12))) + (13 (+ (* a12 b1) (* a13 b5) (* a14 b9) (* a15 b13))) + (14 (+ (* a12 b2) (* a13 b6) (* a14 b10) (* a15 b14))) + (15 (+ (* a12 b3) (* a13 b7) (* a14 b11) (* a15 b15)))))) +(define perspective (make-mat4)) +(define modelview (make-mat4)) +(define rotation (make-mat4)) +(define mvp (make-mat4)) +(define angle-x 0.0) +(define angle-y 0.0) +(define angle-z 0.0) +(define aspect-ratio (exact->inexact (/ width height))) + +;; Setup various command buffer state. +(define vertex-bindings + (vector (make-gpu-buffer-binding buffer-vert))) +(define main-color-target + (if (= sample-count 1) + (make-gpu-color-target #f #:load-op 'clear) + (make-gpu-color-target tex-msaa + #:load-op 'clear + #:store-op 'resolve + #:resolve-texture tex-resolve + #:cycle? #t + #:cycle-resolve-texture? #t))) +(define blit-info + (and (> sample-count 1) + (make-gpu-blit-info + #:source-texture tex-resolve + #:source-width width + #:source-height height + #:destination-texture tex-resolve + #:destination-width width + #:destination-height height))) +(define color-targets (vector main-color-target)) +(define depth-target + (make-gpu-depth-stencil-target tex-depth + #:load-op 'clear + #:clear-depth 1.0 + #:cycle? #t)) + +(define (render) + (define cmd (acquire-gpu-command-buffer device)) + ;; TODO: This could fail. Catch exception and try again next frame + ;; in that case. + (define-values (tex-swapchain width height) + (acquire-gpu-swapchain-texture cmd window)) + + ;; Setup transformation matrix. + (mat4-rotate! modelview angle-x 1.0 0.0 0.0) + (mat4-rotate! rotation angle-y 0.0 1.0 0.0) + (mat4-mult! modelview rotation modelview) + (mat4-rotate! rotation angle-z 0.0 1.0 0.0) + (mat4-mult! modelview rotation modelview) + (let ((z (bstruct-ref modelview 14))) + (bstruct-set! modelview (14 (- z 2.5)))) + (mat4-perspective! perspective 45.0 aspect-ratio 0.01 100.0) + (mat4-mult! modelview perspective mvp) + + ;; Setup matrix uniform buffer. + (call-with-values (lambda () (bstruct-unwrap mvp)) + (lambda (bv offset) + (push-gpu-vertex-uniform-data cmd 0 bv (bstruct-sizeof ) offset))) + + ;; Step rotation. + (set! angle-x (+ angle-x 0.03)) + (set! angle-y (+ angle-y 0.02)) + (set! angle-z (+ angle-z 0.01)) + (when (>= angle-x tau) (set! angle-x (- angle-x tau))) + (when (>= angle-y tau) (set! angle-y (- angle-y tau))) + (when (>= angle-z tau) (set! angle-z (- angle-z tau))) + + ;; Write directly to swapchain texture when not multisampling. + (when (= sample-count 1) + (set-gpu-color-target-texture! main-color-target tex-swapchain)) + + ;; Draw the cube! + (define pass (begin-gpu-render-pass cmd color-targets depth-target)) + (bind-gpu-graphics-pipeline pass pipeline) + (bind-gpu-vertex-buffers pass 0 vertex-bindings) + (draw-gpu-primitives pass 36 1) + (end-gpu-render-pass pass) + + ;; Blit to swapchain texture when multisampling. + (when (> sample-count 1) + (set-gpu-blit-info-destination-texture! blit-info tex-swapchain) + (blit-gpu-texture cmd blit-info)) + + ;; Submit commands! + (submit-gpu-command-buffer! cmd)) + +(define (handle-events) + (match (poll-event) + (#f #t) + (event + (match (event-type event) + ((or 'quit 'key-down) #f) + (_ (handle-events)))))) + +(let lp () + (when (handle-events) + (render) + (lp))) + +(release-gpu-texture! device tex-depth) +(release-gpu-texture! device tex-msaa) +(release-gpu-texture! device tex-resolve) +(release-gpu-graphics-pipeline! device pipeline) +(release-gpu-buffer! device buffer-vert) +(release-window-from-gpu-device! device window) +(destroy-gpu-device! device) +(destroy-window! window) diff --git a/examples/window.scm b/examples/window.scm new file mode 100644 index 0000000..0a4d3f0 --- /dev/null +++ b/examples/window.scm @@ -0,0 +1,7 @@ +(use-modules (sdl3) + (sdl3 video)) + +(sdl-init) +(define window (make-window "Hello" 640 480)) +(sleep 3) +(destroy-window! window) diff --git a/guix.scm b/guix.scm new file mode 100644 index 0000000..8e39021 --- /dev/null +++ b/guix.scm @@ -0,0 +1,149 @@ +;;; guile-sdl3 --- FFI bindings for SDL3 +;;; Copyright © 2024 David Thompson +;;; +;;; This file is part of guile-sdl3. +;;; +;;; Guile-sdl3 is free software; you can redistribute it and/or modify +;;; it under the terms of the GNU Lesser General Public License as +;;; published by the Free Software Foundation; either version 3 of the +;;; License, or (at your option) any later version. +;;; +;;; Guile-sdl3 is distributed in the hope that it will be useful, but +;;; WITHOUT ANY WARRANTY; without even the implied warranty of +;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;; General Public License for more details. +;;; +;;; You should have received a copy of the GNU Lesser General Public +;;; License along with guile-sdl3. If not, see +;;; . + +;;; Commentary: +;; +;; GNU Guix development package. To build and install, run: +;; +;; guix package -f guix.scm +;; +;; To use as the basis for a development environment, run: +;; +;; guix shell +;; +;;; Code: + +(use-modules (gnu packages) + (gnu packages autotools) + (gnu packages fcitx) + (gnu packages freedesktop) + (gnu packages glib) + (gnu packages guile) + (gnu packages ibus) + (gnu packages linux) + (gnu packages pkg-config) + (gnu packages pulseaudio) + (gnu packages sdl) + (gnu packages texinfo) + (gnu packages vulkan) + (gnu packages xdisorg) + (gnu packages xorg) + (guix build-system cmake) + (guix build-system gnu) + (guix gexp) + (guix git) + (guix git-download) + ((guix licenses) #:prefix license:) + (guix packages)) + +(define sdl3 + (let ((commit "596fcfa6c4fd20e5a952c0a1b0147f2fa9f69198") + (revision "1")) + (package + (inherit sdl2) + (name "sdl3") + (source + (origin + (method git-fetch) + (uri (git-reference + (url "https://github.com/libsdl-org/SDL") + (commit commit))) + (sha256 + (base32 + "0f3dx1r92crkf3l0iyf8rbmzba06dpcy90vha39i1jvdmifhyqbs")))) + (build-system cmake-build-system) + (arguments + (list + #:tests? #f + #:configure-flags + #~(list "-DSDL_KMSDRM=ON" + "-DSDL_ALSA_SHARED=OFF" + "-DSDL_PULSEAUDIO_SHARED=OFF" + "-DSDL_PIPEWIRE_SHARED=OFF" + "-DSDL_X11_SHARED=OFF" + "-DSDL_WAYLAND_SHARED=OFF" + "-DSDL_WAYLAND_LIBDECOR_SHARED=OFF" + "-DSDL_KMSDRM_SHARED=OFF" + (string-append "-DCMAKE_SHARED_LINKER_FLAGS=-Wl,-rpath," + #$(this-package-input "eudev") "/lib" + ",-rpath," + #$(this-package-input "vulkan-loader") "/lib")))) + (propagated-inputs + (list + alsa-lib + libxcursor ;enables X11 cursor support + libxkbcommon + libxrandr + pipewire + pulseaudio + wayland)) + (inputs + (list + dbus + eudev ;for discovering input devices + fcitx + glib + ibus-minimal + libdecor + vulkan-loader + wayland-protocols))))) + +(define guile-bstruct + (let ((commit "3186036e116d3e885eae3970e0cad77289d922fd") + (revision "1")) + (package + (name "guile-bstruct") + (version "0.1.0-git") + (source + (origin + (method git-fetch) + (uri (git-reference + (url "https://git.dthompson.us/guile-bstruct.git") + (commit commit))) + (sha256 + (base32 + "0128p1wdiad1sfifaa40w45899pii4mpw30aw3h1rc1dsgm6288m")))) + (build-system gnu-build-system) + (native-inputs (list automake autoconf pkg-config texinfo)) + (inputs (list guile-3.0-latest)) + (synopsis "Efficient binary structures for Guile") + (description "Guile-bstruct provides an efficient implementation of low-level binary +structures for Guile Scheme.") + (home-page "https://dthompson.us/projects/guile-bstruct.html") + (license license:asl2.0)))) + +(package + (name "guile-sdl3") + (version "0.1.0") + (source (git-checkout (url (dirname (current-filename))))) + (build-system gnu-build-system) + (arguments + '(#:make-flags '("GUILE_AUTO_COMPILE=0") + #:phases + (modify-phases %standard-phases + (add-after 'unpack 'bootstrap + (lambda _ (invoke "sh" "bootstrap")))))) + (native-inputs (list autoconf automake pkg-config texinfo)) + (inputs (list guile-3.0-latest sdl3)) + (propagated-inputs (list guile-bstruct)) + (synopsis "Guile bindings for SDL3") + (description "Guile-SDL3 provides pure Guile Scheme bindings to the SDL3 C shared +library via the foreign function interface.") + (home-page "https://git.dthompson.us/guile-sdl3.git") + (license license:asl2.0)) diff --git a/pre-inst-env.in b/pre-inst-env.in new file mode 100644 index 0000000..067e358 --- /dev/null +++ b/pre-inst-env.in @@ -0,0 +1,28 @@ +#!/bin/sh + +# guile-sdl3 -- Scheme bindings for SDL3 +# Copyright © 2024 David Thompson +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +abs_top_srcdir="`cd "@abs_top_srcdir@" > /dev/null; pwd`" +abs_top_builddir="`cd "@abs_top_builddir@" > /dev/null; pwd`" + +GUILE_LOAD_COMPILED_PATH="$abs_top_builddir${GUILE_LOAD_COMPILED_PATH:+:}$GUILE_LOAD_COMPILED_PATH" +GUILE_LOAD_PATH="$abs_top_builddir:$abs_top_srcdir${GUILE_LOAD_PATH:+:}:$GUILE_LOAD_PATH" +export GUILE_LOAD_COMPILED_PATH GUILE_LOAD_PATH + +PATH="$abs_top_builddir/scripts:$PATH" +export PATH + +exec "$@" diff --git a/sdl3.scm b/sdl3.scm new file mode 100644 index 0000000..1430116 --- /dev/null +++ b/sdl3.scm @@ -0,0 +1,67 @@ +;;; guile-sdl3 -- Scheme bindings for SDL3 +;;; Copyright © 2024 David Thompson +;;; +;;; Licensed under the Apache License, Version 2.0 (the "License"); +;;; you may not use this file except in compliance with the License. +;;; You may obtain a copy of the License at +;;; +;;; http://www.apache.org/licenses/LICENSE-2.0 +;;; +;;; Unless required by applicable law or agreed to in writing, software +;;; distributed under the License is distributed on an "AS IS" BASIS, +;;; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +;;; See the License for the specific language governing permissions and +;;; limitations under the License. + +;;; Commentary: +;; +;; SDL3 initialization and shutdown. +;; +;;; Code: + +(define-module (sdl3) + #:use-module (ice-9 match) + #:use-module (sdl3 bindings init) + #:use-module (sdl3 errors) + #:use-module (srfi srfi-1) + #:use-module (system foreign) + #:export (sdl-init + sdl-quit)) + +(define (sdl-init subsystems) + "Initialize SDL @var{subsystems}, a list of symbols. By default, all +subsystems are initialized. + +Valid subsystem names are: + +@itemize +@item @code{audio} +@item @code{video} +@item @code{joystick} +@item @code{haptic} +@item @code{gamepad} +@item @code{events} +@item @code{sensor} +@item @code{camera} +@end itemize" + (sdl-assert 'sdl-init + (SDL_Init + (fold (lambda (name prev) + (logior (match name + ('audio SDL_INIT_AUDIO) + ('video SDL_INIT_VIDEO) + ('joystick SDL_INIT_JOYSTICK) + ('haptic SDL_INIT_HAPTIC) + ('gamepad SDL_INIT_GAMEPAD) + ('events SDL_INIT_EVENTS) + ('sensor SDL_INIT_SENSOR) + ('camera SDL_INIT_CAMERA) + (_ (raise (make-sdl-error 'sdl-init + #:message "invalid subsystem name" + #:irritants (list name))))) + prev)) + 0 subsystems)))) + +(define (sdl-quit) + "Clean up all initialized subsystems." + (SDL_Quit)) diff --git a/sdl3/bindings/error.scm b/sdl3/bindings/error.scm new file mode 100644 index 0000000..71e5885 --- /dev/null +++ b/sdl3/bindings/error.scm @@ -0,0 +1,26 @@ +;;; guile-sdl3 -- Scheme bindings for SDL3 +;;; Copyright © 2024 David Thompson +;;; +;;; Licensed under the Apache License, Version 2.0 (the "License"); +;;; you may not use this file except in compliance with the License. +;;; You may obtain a copy of the License at +;;; +;;; http://www.apache.org/licenses/LICENSE-2.0 +;;; +;;; Unless required by applicable law or agreed to in writing, software +;;; distributed under the License is distributed on an "AS IS" BASIS, +;;; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +;;; See the License for the specific language governing permissions and +;;; limitations under the License. + +;;; Commentary: +;; +;; Low-level bindings for SDL_error.h. +;; +;;; Code: + +(define-module (sdl3 bindings error) + #:use-module (sdl3 bindings utils) + #:export (SDL_GetError)) + +(define-sdl SDL_GetError -> '*) diff --git a/sdl3/bindings/events.scm b/sdl3/bindings/events.scm new file mode 100644 index 0000000..f123b95 --- /dev/null +++ b/sdl3/bindings/events.scm @@ -0,0 +1,750 @@ +;;; guile-sdl3 -- Scheme bindings for SDL3 +;;; Copyright © 2024 David Thompson +;;; +;;; Licensed under the Apache License, Version 2.0 (the "License"); +;;; you may not use this file except in compliance with the License. +;;; You may obtain a copy of the License at +;;; +;;; http://www.apache.org/licenses/LICENSE-2.0 +;;; +;;; Unless required by applicable law or agreed to in writing, software +;;; distributed under the License is distributed on an "AS IS" BASIS, +;;; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +;;; See the License for the specific language governing permissions and +;;; limitations under the License. + +;;; Commentary: +;; +;; Low-level FFI binding utilities. +;; +;;; Code: + +(define-module (sdl3 bindings events) + #:use-module (bstruct) + #:use-module (sdl3 bindings utils) + #:use-module (system foreign) + #:export (SDL_EventType + symbol->event-type + event-type->symbol + SDL_EVENT_FIRST + SDL_EVENT_QUIT + SDL_EVENT_TERMINATING + SDL_EVENT_LOW_MEMORY + SDL_EVENT_WILL_ENTER_BACKGROUND + SDL_EVENT_DID_ENTER_BACKGROUND + SDL_EVENT_WILL_ENTER_FOREGROUND + SDL_EVENT_DID_ENTER_FOREGROUND + SDL_EVENT_LOCALE_CHANGED + SDL_EVENT_SYSTEM_THEME_CHANGED + SDL_EVENT_DISPLAY_ORIENTATION + SDL_EVENT_DISPLAY_ADDED + SDL_EVENT_DISPLAY_REMOVED + SDL_EVENT_DISPLAY_MOVED + SDL_EVENT_DISPLAY_DESKTOP_MODE_CHANGED + SDL_EVENT_DISPLAY_CURRENT_MODE_CHANGED + SDL_EVENT_DISPLAY_CONTENT_SCALE_CHANGED + SDL_EVENT_WINDOW_SHOWN + SDL_EVENT_WINDOW_HIDDEN + SDL_EVENT_WINDOW_EXPOSED + SDL_EVENT_WINDOW_MOVED + SDL_EVENT_WINDOW_RESIZED + SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED + SDL_EVENT_WINDOW_METAL_VIEW_RESIZED + SDL_EVENT_WINDOW_MINIMIZED + SDL_EVENT_WINDOW_MAXIMIZED + SDL_EVENT_WINDOW_RESTORED + SDL_EVENT_WINDOW_MOUSE_ENTER + SDL_EVENT_WINDOW_MOUSE_LEAVE + SDL_EVENT_WINDOW_FOCUS_GAINED + SDL_EVENT_WINDOW_FOCUS_LOST + SDL_EVENT_WINDOW_CLOSE_REQUESTED + SDL_EVENT_WINDOW_HIT_TEST + SDL_EVENT_WINDOW_ICCPROF_CHANGED + SDL_EVENT_WINDOW_DISPLAY_CHANGED + SDL_EVENT_WINDOW_DISPLAY_SCALE_CHANGED + SDL_EVENT_WINDOW_SAFE_AREA_CHANGED + SDL_EVENT_WINDOW_OCCLUDED + SDL_EVENT_WINDOW_ENTER_FULLSCREEN + SDL_EVENT_WINDOW_LEAVE_FULLSCREEN + SDL_EVENT_WINDOW_DESTROYED + SDL_EVENT_WINDOW_HDR_STATE_CHANGED + SDL_EVENT_KEY_DOWN + SDL_EVENT_KEY_UP + SDL_EVENT_TEXT_EDITING + SDL_EVENT_TEXT_INPUT + SDL_EVENT_KEYMAP_CHANGED + SDL_EVENT_KEYBOARD_ADDED + SDL_EVENT_KEYBOARD_REMOVED + SDL_EVENT_TEXT_EDITING_CANDIDATES + SDL_EVENT_MOUSE_MOTION + SDL_EVENT_MOUSE_BUTTON_DOWN + SDL_EVENT_MOUSE_BUTTON_UP + SDL_EVENT_MOUSE_WHEEL + SDL_EVENT_MOUSE_ADDED + SDL_EVENT_MOUSE_REMOVED + SDL_EVENT_JOYSTICK_AXIS_MOTION + SDL_EVENT_JOYSTICK_BALL_MOTION + SDL_EVENT_JOYSTICK_HAT_MOTION + SDL_EVENT_JOYSTICK_BUTTON_DOWN + SDL_EVENT_JOYSTICK_BUTTON_UP + SDL_EVENT_JOYSTICK_ADDED + SDL_EVENT_JOYSTICK_REMOVED + SDL_EVENT_JOYSTICK_BATTERY_UPDATED + SDL_EVENT_JOYSTICK_UPDATE_COMPLETE + SDL_EVENT_GAMEPAD_AXIS_MOTION + SDL_EVENT_GAMEPAD_BUTTON_DOWN + SDL_EVENT_GAMEPAD_BUTTON_UP + SDL_EVENT_GAMEPAD_ADDED + SDL_EVENT_GAMEPAD_REMOVED + SDL_EVENT_GAMEPAD_REMAPPED + SDL_EVENT_GAMEPAD_TOUCHPAD_DOWN + SDL_EVENT_GAMEPAD_TOUCHPAD_MOTION + SDL_EVENT_GAMEPAD_TOUCHPAD_UP + SDL_EVENT_GAMEPAD_SENSOR_UPDATE + SDL_EVENT_GAMEPAD_UPDATE_COMPLETE + SDL_EVENT_GAMEPAD_STEAM_HANDLE_UPDATED + SDL_EVENT_FINGER_DOWN + SDL_EVENT_FINGER_UP + SDL_EVENT_FINGER_MOTION + SDL_EVENT_CLIPBOARD_UPDATE + SDL_EVENT_DROP_FILE + SDL_EVENT_DROP_TEXT + SDL_EVENT_DROP_BEGIN + SDL_EVENT_DROP_COMPLETE + SDL_EVENT_DROP_POSITION + SDL_EVENT_AUDIO_DEVICE_ADDED + SDL_EVENT_AUDIO_DEVICE_REMOVED + SDL_EVENT_AUDIO_DEVICE_FORMAT_CHANGED + SDL_EVENT_SENSOR_UPDATE + SDL_EVENT_PEN_PROXIMITY_IN + SDL_EVENT_PEN_PROXIMITY_OUT + SDL_EVENT_PEN_DOWN + SDL_EVENT_PEN_UP + SDL_EVENT_PEN_BUTTON_DOWN + SDL_EVENT_PEN_BUTTON_UP + SDL_EVENT_PEN_MOTION + SDL_EVENT_PEN_AXIS + SDL_EVENT_CAMERA_DEVICE_ADDED + SDL_EVENT_CAMERA_DEVICE_REMOVED + SDL_EVENT_CAMERA_DEVICE_APPROVED + SDL_EVENT_CAMERA_DEVICE_DENIED + SDL_EVENT_RENDER_TARGETS_RESET + SDL_EVENT_RENDER_DEVICE_RESET + SDL_EVENT_POLL_SENTINEL + SDL_EVENT_DISPLAY_FIRST + SDL_EVENT_DISPLAY_LAST + SDL_EVENT_WINDOW_FIRST + SDL_EVENT_WINDOW_LAST + SDL_EVENT_USER + SDL_EVENT_LAST + SDL_EVENT_ENUM_PADDING + + SDL_CommonEvent + SDL_DisplayEvent + SDL_WindowEvent + SDL_KeyboardDeviceEvent + SDL_KeyboardEvent + SDL_TextEditingEvent + SDL_TextEditingCandidatesEvent + SDL_TextInputEvent + SDL_MouseDeviceEvent + SDL_MouseMotionEvent + SDL_MouseButtonEvent + SDL_MouseWheelEvent + SDL_JoyAxisEvent + SDL_JoyBallEvent + SDL_JoyHatEvent + SDL_JoyButtonEvent + SDL_JoyDeviceEvent + SDL_JoyBatteryEvent + SDL_GamepadAxisEvent + SDL_GamepadButtonEvent + SDL_GamepadDeviceEvent + SDL_GamepadTouchpadEvent + SDL_GamepadSensorEvent + SDL_AudioDeviceEvent + SDL_CameraDeviceEvent + SDL_TouchFingerEvent + SDL_PenProximityEvent + SDL_PenMotionEvent + SDL_PenTouchEvent + SDL_PenButtonEvent + SDL_PenAxisEvent + SDL_DropEvent + SDL_ClipboardEvent + SDL_SensorEvent + SDL_QuitEvent + SDL_UserEvent + SDL_Event + + SDL_PumpEvents + SDL_HasEvent + SDL_HasEvents + SDL_FlushEvent + SDL_FlushEvents + SDL_PollEvent + SDL_WaitEvent + SDL_WaitEventTimeout + SDL_PushEvent)) + +(define-enum SDL_EventType + symbol->event-type + event-type->symbol + (first SDL_EVENT_FIRST) + (quit SDL_EVENT_QUIT #x100) + (terminating SDL_EVENT_TERMINATING) + (low-memory SDL_EVENT_LOW_MEMORY) + (will-enter-background SDL_EVENT_WILL_ENTER_BACKGROUND) + (did-enter-background SDL_EVENT_DID_ENTER_BACKGROUND) + (will-enter-foreground SDL_EVENT_WILL_ENTER_FOREGROUND) + (did-enter-foreground SDL_EVENT_DID_ENTER_FOREGROUND) + (locale-changed SDL_EVENT_LOCALE_CHANGED) + (system-theme-changed SDL_EVENT_SYSTEM_THEME_CHANGED) + (display-orientation SDL_EVENT_DISPLAY_ORIENTATION #x151) + (display-added SDL_EVENT_DISPLAY_ADDED) + (display-removed SDL_EVENT_DISPLAY_REMOVED) + (display-moved SDL_EVENT_DISPLAY_MOVED) + (display-desktop-mode-changed SDL_EVENT_DISPLAY_DESKTOP_MODE_CHANGED) + (display-current-mode-changed SDL_EVENT_DISPLAY_CURRENT_MODE_CHANGED) + (display-content-scale-changed SDL_EVENT_DISPLAY_CONTENT_SCALE_CHANGED) + (window-shown SDL_EVENT_WINDOW_SHOWN #x202) + (window-hidden SDL_EVENT_WINDOW_HIDDEN) + (window-exposed SDL_EVENT_WINDOW_EXPOSED) + (window-moved SDL_EVENT_WINDOW_MOVED) + (window-resized SDL_EVENT_WINDOW_RESIZED) + (window-pixel-size-changed SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED) + (window-metal-view-resized SDL_EVENT_WINDOW_METAL_VIEW_RESIZED) + (window-minimized SDL_EVENT_WINDOW_MINIMIZED) + (window-maximized SDL_EVENT_WINDOW_MAXIMIZED) + (window-restored SDL_EVENT_WINDOW_RESTORED) + (window-mouse-enter SDL_EVENT_WINDOW_MOUSE_ENTER) + (window-mouse-leave SDL_EVENT_WINDOW_MOUSE_LEAVE) + (window-focus-gained SDL_EVENT_WINDOW_FOCUS_GAINED) + (window-focus-lost SDL_EVENT_WINDOW_FOCUS_LOST) + (window-close-requested SDL_EVENT_WINDOW_CLOSE_REQUESTED) + (window-hit-test SDL_EVENT_WINDOW_HIT_TEST) + (window-iccprof-changed SDL_EVENT_WINDOW_ICCPROF_CHANGED) + (window-display-changed SDL_EVENT_WINDOW_DISPLAY_CHANGED) + (window-display-scale-changed SDL_EVENT_WINDOW_DISPLAY_SCALE_CHANGED) + (window-safe-area-changed SDL_EVENT_WINDOW_SAFE_AREA_CHANGED) + (window-occluded SDL_EVENT_WINDOW_OCCLUDED) + (window-enter-fullscreen SDL_EVENT_WINDOW_ENTER_FULLSCREEN) + (window-leave-fullscreen SDL_EVENT_WINDOW_LEAVE_FULLSCREEN) + (window-destroyed SDL_EVENT_WINDOW_DESTROYED) + (window-hdr-state-changed SDL_EVENT_WINDOW_HDR_STATE_CHANGED) + (key-down SDL_EVENT_KEY_DOWN #x300) + (key-up SDL_EVENT_KEY_UP) + (text-editing SDL_EVENT_TEXT_EDITING) + (text-input SDL_EVENT_TEXT_INPUT) + (keymap-changed SDL_EVENT_KEYMAP_CHANGED) + (keyboard-added SDL_EVENT_KEYBOARD_ADDED) + (keyboard-removed SDL_EVENT_KEYBOARD_REMOVED) + (text-editing-candidates SDL_EVENT_TEXT_EDITING_CANDIDATES) + (mouse-motion SDL_EVENT_MOUSE_MOTION #x400) + (mouse-button-down SDL_EVENT_MOUSE_BUTTON_DOWN) + (mouse-button-up SDL_EVENT_MOUSE_BUTTON_UP) + (mouse-wheel SDL_EVENT_MOUSE_WHEEL) + (mouse-added SDL_EVENT_MOUSE_ADDED) + (mouse-removed SDL_EVENT_MOUSE_REMOVED) + (joystick-axis-motion SDL_EVENT_JOYSTICK_AXIS_MOTION #x600) + (joystick-ball-motion SDL_EVENT_JOYSTICK_BALL_MOTION) + (joystick-hat-motion SDL_EVENT_JOYSTICK_HAT_MOTION) + (joystick-button-down SDL_EVENT_JOYSTICK_BUTTON_DOWN) + (joystick-button-up SDL_EVENT_JOYSTICK_BUTTON_UP) + (joystick-added SDL_EVENT_JOYSTICK_ADDED) + (joystick-removed SDL_EVENT_JOYSTICK_REMOVED) + (joystick-battery-updated SDL_EVENT_JOYSTICK_BATTERY_UPDATED) + (joystick-update-complete SDL_EVENT_JOYSTICK_UPDATE_COMPLETE) + (gamepad-axis-motion SDL_EVENT_GAMEPAD_AXIS_MOTION #x650) + (gamepad-button-down SDL_EVENT_GAMEPAD_BUTTON_DOWN) + (gamepad-button-up SDL_EVENT_GAMEPAD_BUTTON_UP) + (gamepad-added SDL_EVENT_GAMEPAD_ADDED) + (gamepad-removed SDL_EVENT_GAMEPAD_REMOVED) + (gamepad-remapped SDL_EVENT_GAMEPAD_REMAPPED) + (gamepad-touchpad-down SDL_EVENT_GAMEPAD_TOUCHPAD_DOWN) + (gamepad-touchpad-motion SDL_EVENT_GAMEPAD_TOUCHPAD_MOTION) + (gamepad-touchpad-up SDL_EVENT_GAMEPAD_TOUCHPAD_UP) + (gamepad-sensor-update SDL_EVENT_GAMEPAD_SENSOR_UPDATE) + (gamepad-update-complete SDL_EVENT_GAMEPAD_UPDATE_COMPLETE) + (gamepad-steam-handle-updated SDL_EVENT_GAMEPAD_STEAM_HANDLE_UPDATED) + (finger-down SDL_EVENT_FINGER_DOWN #x700) + (finger-up SDL_EVENT_FINGER_UP) + (finger-motion SDL_EVENT_FINGER_MOTION) + (clipboard-update SDL_EVENT_CLIPBOARD_UPDATE #x900) + (drop-file SDL_EVENT_DROP_FILE #x1000) + (drop-text SDL_EVENT_DROP_TEXT) + (drop-begin SDL_EVENT_DROP_BEGIN) + (drop-complete SDL_EVENT_DROP_COMPLETE) + (drop-position SDL_EVENT_DROP_POSITION) + (audio-device-added SDL_EVENT_AUDIO_DEVICE_ADDED #x1100) + (audio-device-removed SDL_EVENT_AUDIO_DEVICE_REMOVED) + (audio-device-format-changed SDL_EVENT_AUDIO_DEVICE_FORMAT_CHANGED) + (sensor-update SDL_EVENT_SENSOR_UPDATE #x1200) + (pen-proximity-in SDL_EVENT_PEN_PROXIMITY_IN #x1300) + (pen-proximity-out SDL_EVENT_PEN_PROXIMITY_OUT) + (pen-down SDL_EVENT_PEN_DOWN) + (pen-up SDL_EVENT_PEN_UP) + (pen-button-down SDL_EVENT_PEN_BUTTON_DOWN) + (pen-button-up SDL_EVENT_PEN_BUTTON_UP) + (pen-motion SDL_EVENT_PEN_MOTION) + (pen-axis SDL_EVENT_PEN_AXIS) + (camera-device-added SDL_EVENT_CAMERA_DEVICE_ADDED #x1400) + (camera-device-removed SDL_EVENT_CAMERA_DEVICE_REMOVED) + (camera-device-approved SDL_EVENT_CAMERA_DEVICE_APPROVED) + (camera-device-denied SDL_EVENT_CAMERA_DEVICE_DENIED) + (render-targets-reset SDL_EVENT_RENDER_TARGETS_RESET #x2000) + (render-device-reset SDL_EVENT_RENDER_DEVICE_RESET) + (poll-sentinel SDL_EVENT_POLL_SENTINEL #x7F00)) + +(define SDL_EVENT_DISPLAY_FIRST SDL_EVENT_DISPLAY_ORIENTATION) +(define SDL_EVENT_DISPLAY_LAST SDL_EVENT_DISPLAY_CONTENT_SCALE_CHANGED) +(define SDL_EVENT_WINDOW_FIRST SDL_EVENT_WINDOW_SHOWN) +(define SDL_EVENT_WINDOW_LAST SDL_EVENT_WINDOW_HDR_STATE_CHANGED) +(define SDL_EVENT_USER #x8000) +(define SDL_EVENT_LAST #xFFFF) +(define SDL_EVENT_ENUM_PADDING #x7FFFFFFF) + +(define-bstruct SDL_CommonEvent + (struct + (type u32) + (reserved u32) + (timestamp u64))) + +(define-bstruct SDL_DisplayEvent + (struct + (type int) ; SDL_EventType + (reserved u32) + (timestamp u64) + (displayID u32) ; SDL_DisplayID + (data1 s32) + (data2 s32))) + +(define-bstruct SDL_WindowEvent + (struct + (type u32) + (reserved u32) + (timestamp u64) + (windowID u32) ; SDL_WindowID + (data1 s32) + (data2 s32))) + +(define-bstruct SDL_KeyboardDeviceEvent + (struct + (type u32) + (reserved u32) + (timestamp u64) + (which u32) ; SDL_KeyboardID + )) + +(define-bstruct SDL_KeyboardEvent + (struct + (type u32) + (reserved u32) + (timestamp u64) + (windowID u32) ; SDL_WindowID + (which u32) ; SDL_KeyboardID + (scancode int) ; SDL_Scancode + (key int) ; SDL_Keycode + (mod u16) ; SDL_Keymod + (raw u16) + (down u8) ; bool + (repeat u8) ; bool + )) + +(define-bstruct SDL_TextEditingEvent + (struct + (type u32) + (reserved u32) + (timestamp u64) + (windowID u32) ; SDL_WindowID + (text (* u8)) ; char* + (start s32) + (length s32))) + +(define-bstruct SDL_TextEditingCandidatesEvent + (struct + (type u32) + (reserved u32) + (timestamp u64) + (windowID u32) ; SDL_WindowID + (candidates (* u8)) + (num_candidates s32) + (selected_candidate s32) + (horizontal u8) ; bool + (_ u8) + (_ u8) + (_ u8))) + +(define-bstruct SDL_TextInputEvent + (struct + (type u32) + (reserved u32) + (timestamp u64) + (windowID u32) ; SDL_WindowID + (text (* u8)))) + +(define-bstruct SDL_MouseDeviceEvent + (struct + (type u32) + (reserved u32) + (timestamp u64) + (which u32) ; SDL_MouseID + )) + +(define-bstruct SDL_MouseMotionEvent + (struct + (type u32) + (reserved u32) + (timestamp u64) + (windowID u32) ; SDL_WindowID + (which u32) ; SDL_MouseID + (state u32) ; SDL_MouseButtonFlags + (x f32) + (y f32) + (xrel f32) + (yrel f32))) + +(define-bstruct SDL_MouseButtonEvent + (struct + (type u32) + (reserved u32) + (timestamp u64) + (windowID u32) ; SDL_WindowID + (which u32) ; SDL_MouseID + (button u8) + (down u8) ; bool + (clicks u8) + (_ u8) + (x f32) + (y f32))) + +(define-bstruct SDL_MouseWheelEvent + (struct + (type u32) + (reserved u32) + (timestamp u64) + (windowID u32) ; SDL_WindowID + (which u32) ; SDL_MouseID + (x f32) + (y f32) + (direction int) ; SDL_MouseWheelDirection + (mouse_x f32) + (mouse_y f32))) + +(define-bstruct SDL_JoyAxisEvent + (struct + (type u32) + (reserved u32) + (timestamp u64) + (which u32) ; SDL_JoystickID + (axis u8) + (_ u8) + (_ u8) + (_ u8) + (value s16) + (_ u16))) + +(define-bstruct SDL_JoyBallEvent + (struct + (type u32) + (reserved u32) + (timestamp u64) + (which u32) ; SDL_JoystickID + (ball u8) + (_ u8) + (_ u8) + (_ u8) + (xrel s32) + (yrel s32))) + +(define-bstruct SDL_JoyHatEvent + (struct + (type u32) + (reserved u32) + (timestamp u64) + (which u32) ; SDL_JoystickID + (hat u8) + (value u8) + (_ u8) + (_ u8))) + +(define-bstruct SDL_JoyButtonEvent + (struct + (type u32) + (reserved u32) + (timestamp u64) + (which u32) ; SDL_JoystickID + (button u8) + (down u8) ; bool + (_ u8) + (_ u8) + )) + +(define-bstruct SDL_JoyDeviceEvent + (struct + (type u32) + (reserved u32) + (timestamp u64) + (which u32) ; SDL_JoystickID + )) + +(define-bstruct SDL_JoyBatteryEvent + (struct + (type u32) + (reserved u32) + (timestamp u64) + (which u32) ; SDL_JoystickID + (state int) ; SDL_PowerState + (percent int))) + +(define-bstruct SDL_GamepadAxisEvent + (struct + (type u32) + (reserved u32) + (timestamp u64) + (which u32) ; SDL_JoystickID + (axis u8) + (_ u8) + (_ u8) + (_ u8) + (value s16) + (_ u16))) + +(define-bstruct SDL_GamepadButtonEvent + (struct + (type u32) + (reserved u32) + (timestamp u64) + (which u32) ; SDL_JoystickID + (button u8) + (down u8) ; bool + (_ u8) + (_ u8))) + +(define-bstruct SDL_GamepadDeviceEvent + (struct + (type u32) + (reserved u32) + (timestamp u64) + (which u32) ; SDL_JoystickID + )) + +(define-bstruct SDL_GamepadTouchpadEvent + (struct + (type u32) + (reserved u32) + (timestamp u64) + (which u32) ; SDL_JoystickID + (touchpad s32) + (finger s32) + (x f32) + (y f32) + (pressure f32))) + +(define-bstruct SDL_GamepadSensorEvent + (struct + (type u32) + (reserved u32) + (timestamp u64) + (which u32) ; SDL_JoystickID + (sensor s32) + (data (array 3 f32)) + (sensor_timestamp u64))) + +(define-bstruct SDL_AudioDeviceEvent + (struct + (type u32) + (reserved u32) + (timestamp u64) + (which u32) ; SDL_AudioDeviceID + (recording u8) ; bool + (_ u8) + (_ u8) + (_ u8))) + +(define-bstruct SDL_CameraDeviceEvent + (struct + (type u32) + (reserved u32) + (timestamp u64) + (which u32) ; SDL_CameraID + )) + +(define-bstruct SDL_TouchFingerEvent + (struct + (type u32) + (reserved u32) + (timestamp u64) + (touchID u32) ; SDL_TouchID + (fingerID u32) ; SDL_FingerID + (x f32) + (y f32) + (dx f32) + (dy f32) + (pressure f32) + (windowID u32) ; SDL_WindowID + )) + +(define-bstruct SDL_PenProximityEvent + (struct + (type u32) + (reserved u32) + (timestamp u64) + (windowID u32) ; SDL_WindowID + (which u32) ; SDL_PenID + )) + +(define-bstruct SDL_PenMotionEvent + (struct + (type u32) + (reserved u32) + (timestamp u64) + (windowID u32) ; SDL_WindowID + (which u32) ; SDL_PenID + (pen_state u32) ; SDL_PenInputFlags + )) + +(define-bstruct SDL_PenTouchEvent + (struct + (type u32) + (reserved u32) + (timestamp u64) + (windowID u32) ; SDL_WindowID + (which u32) ; SDL_PenID + (pen_state u32) ; SDL_PenInputFlags + (x f32) + (y f32) + (eraser u8) ; bool + (down u8) ; bool + )) + +(define-bstruct SDL_PenButtonEvent + (struct + (type u32) + (reserved u32) + (timestamp u64) + (windowID u32) ; SDL_WindowID + (which u32) ; SDL_PenID + (pen_state u32) ; SDL_PenInputFlags + (x f32) + (y f32) + (button u8) + (down u8) ; bool + )) + +(define-bstruct SDL_PenAxisEvent + (struct + (type u32) + (reserved u32) + (timestamp u64) + (windowID u32) ; SDL_WindowID + (which u32) ; SDL_PenID + (pen_state u32) ; SDL_PenInputFlags + (x f32) + (y f32) + (axis int) ; SDL_PenAxis + (value f32))) + +(define-bstruct SDL_DropEvent + (struct + (type u32) + (reserved u32) + (timestamp u64) + (windowID u32) ; SDL_WindowID + (x f32) + (y f32) + (source (* u8)) ; char* + (data (* u8)) ; char* + )) + +(define-bstruct SDL_ClipboardEvent + (struct + (type u32) + (reserved u32) + (timestamp u64))) + +(define-bstruct SDL_SensorEvent + (struct + (type u32) + (reserved u32) + (timestamp u64) + (which u32) ; SDL_SensorID + (data (array 6 f32)) + (sensor_timestamp u64))) + +(define-bstruct SDL_QuitEvent + (struct + (type u32) + (reserved u32) + (timestamp u64))) + +(define-bstruct SDL_UserEvent + (struct + (type u32) + (reserved u32) + (timestamp u64) + (windowID u32) ; SDL_WindowID + (code s32) + (data1 (* void)) + (data2 (* void)))) + +(define-bstruct SDL_Event + (union + (type u32) + (common SDL_CommonEvent) + (display SDL_DisplayEvent) + (window SDL_WindowEvent) + (kdevice SDL_KeyboardDeviceEvent) + (key SDL_KeyboardEvent) + (edit SDL_TextEditingEvent) + (edit_candidates SDL_TextEditingCandidatesEvent) + (text SDL_TextInputEvent) + (mdevice SDL_MouseDeviceEvent) + (motion SDL_MouseMotionEvent) + (button SDL_MouseButtonEvent) + (wheel SDL_MouseWheelEvent) + (jdevice SDL_JoyDeviceEvent) + (jaxis SDL_JoyAxisEvent) + (jball SDL_JoyBallEvent) + (jhat SDL_JoyHatEvent) + (jbutton SDL_JoyButtonEvent) + (jbattery SDL_JoyBatteryEvent) + (gdevice SDL_GamepadDeviceEvent) + (gaxis SDL_GamepadAxisEvent) + (gbutton SDL_GamepadButtonEvent) + (gtouchpad SDL_GamepadTouchpadEvent) + (gsensor SDL_GamepadSensorEvent) + (adevice SDL_AudioDeviceEvent) + (cdevice SDL_CameraDeviceEvent) + (sensor SDL_SensorEvent) + (quit SDL_QuitEvent) + (user SDL_UserEvent) + (tfinger SDL_TouchFingerEvent) + (pproximity SDL_PenProximityEvent) + (ptouch SDL_PenTouchEvent) + (pmotion SDL_PenMotionEvent) + (pbutton SDL_PenButtonEvent) + (paxis SDL_PenAxisEvent) + (drop SDL_DropEvent) + (clipboard SDL_ClipboardEvent) + (_ (array 128 u8)))) + +(define-sdl SDL_PumpEvents) +;; SDL_PeepEvents +(define-sdl SDL_HasEvent uint32 -> bool) +(define-sdl SDL_HasEvents uint32 uint32 -> bool) +(define-sdl SDL_FlushEvent uint32) +(define-sdl SDL_FlushEvents uint32 uint32) +(define-sdl SDL_PollEvent '* -> bool) +(define-sdl SDL_WaitEvent '* -> bool) +(define-sdl SDL_WaitEventTimeout '* int32 -> bool) +(define-sdl SDL_PushEvent '* -> bool) +;; SDL_SetEventFilter +;; SDL_GetEventFilter +;; SDL_AddEventWatch +;; SDL_RemoveEventWatch +;; SDL_FilterEvents +;; SDL_SetEventEnabled +;; SDL_EventEnabled +;; SDL_RegisterEvents +;; SDL_GetWindowFromEvent diff --git a/sdl3/bindings/gpu.scm b/sdl3/bindings/gpu.scm new file mode 100644 index 0000000..849e159 --- /dev/null +++ b/sdl3/bindings/gpu.scm @@ -0,0 +1,1190 @@ +;;; guile-sdl3 -- Scheme bindings for SDL3 +;;; Copyright © 2024 David Thompson +;;; +;;; Licensed under the Apache License, Version 2.0 (the "License"); +;;; you may not use this file except in compliance with the License. +;;; You may obtain a copy of the License at +;;; +;;; http://www.apache.org/licenses/LICENSE-2.0 +;;; +;;; Unless required by applicable law or agreed to in writing, software +;;; distributed under the License is distributed on an "AS IS" BASIS, +;;; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +;;; See the License for the specific language governing permissions and +;;; limitations under the License. + +;;; Commentary: +;; +;; Low-level bindings for SDL_gpu.h. +;; +;;; Code: + +(define-module (sdl3 bindings gpu) + #:use-module (bstruct) + #:use-module (sdl3 bindings utils) + #:use-module (sdl3 bindings pixels) + #:use-module (sdl3 bindings surface) + #:use-module (system foreign) + #:export (SDL_GPUPrimitiveType + symbol->gpu-primitive-type + primitive-type->symbol + SDL_GPU_PRIMITIVETYPE_TRIANGLELIST + SDL_GPU_PRIMITIVETYPE_TRIANGLESTRIP + SDL_GPU_PRIMITIVETYPE_LINELIST + SDL_GPU_PRIMITIVETYPE_LINESTRIP + SDL_GPU_PRIMITIVETYPE_POINTLIST + + SDL_GPULoadOp + symbol->gpu-load-op + gpu-load-op->symbol + SDL_GPU_LOADOP_LOAD + SDL_GPU_LOADOP_CLEAR + SDL_GPU_LOADOP_DONT_CARE + + SDL_GPUStoreOp + symbol->gpu-store-op + gpu-store-op->symbol + SDL_GPU_STOREOP_STORE + SDL_GPU_STOREOP_DONT_CARE + SDL_GPU_STOREOP_RESOLVE + SDL_GPU_STOREOP_RESOLVE_AND_STORE + + SDL_GPUIndexElementSize + symbol->gpu-index-element-size + gpu-index-element-size->symbol + SDL_GPU_INDEXELEMENTSIZE_16BIT + SDL_GPU_INDEXELEMENTSIZE_32BIT + + SDL_GPUTextureFormat + symbol->gpu-texture-format + gpu-texture-format->symbol + SDL_GPU_TEXTUREFORMAT_INVALID + SDL_GPU_TEXTUREFORMAT_A8_UNORM + SDL_GPU_TEXTUREFORMAT_R8_UNORM + SDL_GPU_TEXTUREFORMAT_R8G8_UNORM + SDL_GPU_TEXTUREFORMAT_R8G8B8A8_UNORM + SDL_GPU_TEXTUREFORMAT_R16_UNORM + SDL_GPU_TEXTUREFORMAT_R16G16_UNORM + SDL_GPU_TEXTUREFORMAT_R16G16B16A16_UNORM + SDL_GPU_TEXTUREFORMAT_R10G10B10A2_UNORM + SDL_GPU_TEXTUREFORMAT_B5G6R5_UNORM + SDL_GPU_TEXTUREFORMAT_B5G5R5A1_UNORM + SDL_GPU_TEXTUREFORMAT_B4G4R4A4_UNORM + SDL_GPU_TEXTUREFORMAT_B8G8R8A8_UNORM + SDL_GPU_TEXTUREFORMAT_BC1_RGBA_UNORM + SDL_GPU_TEXTUREFORMAT_BC2_RGBA_UNORM + SDL_GPU_TEXTUREFORMAT_BC3_RGBA_UNORM + SDL_GPU_TEXTUREFORMAT_BC4_R_UNORM + SDL_GPU_TEXTUREFORMAT_BC5_RG_UNORM + SDL_GPU_TEXTUREFORMAT_BC7_RGBA_UNORM + SDL_GPU_TEXTUREFORMAT_BC6H_RGB_FLOAT + SDL_GPU_TEXTUREFORMAT_BC6H_RGB_UFLOAT + SDL_GPU_TEXTUREFORMAT_R8_SNORM + SDL_GPU_TEXTUREFORMAT_R8G8_SNORM + SDL_GPU_TEXTUREFORMAT_R8G8B8A8_SNORM + SDL_GPU_TEXTUREFORMAT_R16_SNORM + SDL_GPU_TEXTUREFORMAT_R16G16_SNORM + SDL_GPU_TEXTUREFORMAT_R16G16B16A16_SNORM + SDL_GPU_TEXTUREFORMAT_R16_FLOAT + SDL_GPU_TEXTUREFORMAT_R16G16_FLOAT + SDL_GPU_TEXTUREFORMAT_R16G16B16A16_FLOAT + SDL_GPU_TEXTUREFORMAT_R32_FLOAT + SDL_GPU_TEXTUREFORMAT_R32G32_FLOAT + SDL_GPU_TEXTUREFORMAT_R32G32B32A32_FLOAT + SDL_GPU_TEXTUREFORMAT_R11G11B10_UFLOAT + SDL_GPU_TEXTUREFORMAT_R8_UINT + SDL_GPU_TEXTUREFORMAT_R8G8_UINT + SDL_GPU_TEXTUREFORMAT_R8G8B8A8_UINT + SDL_GPU_TEXTUREFORMAT_R16_UINT + SDL_GPU_TEXTUREFORMAT_R16G16_UINT + SDL_GPU_TEXTUREFORMAT_R16G16B16A16_UINT + SDL_GPU_TEXTUREFORMAT_R32_UINT + SDL_GPU_TEXTUREFORMAT_R32G32_UINT + SDL_GPU_TEXTUREFORMAT_R32G32B32A32_UINT + SDL_GPU_TEXTUREFORMAT_R8_INT + SDL_GPU_TEXTUREFORMAT_R8G8_INT + SDL_GPU_TEXTUREFORMAT_R8G8B8A8_INT + SDL_GPU_TEXTUREFORMAT_R16_INT + SDL_GPU_TEXTUREFORMAT_R16G16_INT + SDL_GPU_TEXTUREFORMAT_R16G16B16A16_INT + SDL_GPU_TEXTUREFORMAT_R32_INT + SDL_GPU_TEXTUREFORMAT_R32G32_INT + SDL_GPU_TEXTUREFORMAT_R32G32B32A32_INT + SDL_GPU_TEXTUREFORMAT_R8G8B8A8_UNORM_SRGB + SDL_GPU_TEXTUREFORMAT_B8G8R8A8_UNORM_SRGB + SDL_GPU_TEXTUREFORMAT_BC1_RGBA_UNORM_SRGB + SDL_GPU_TEXTUREFORMAT_BC2_RGBA_UNORM_SRGB + SDL_GPU_TEXTUREFORMAT_BC3_RGBA_UNORM_SRGB + SDL_GPU_TEXTUREFORMAT_BC7_RGBA_UNORM_SRGB + SDL_GPU_TEXTUREFORMAT_D16_UNORM + SDL_GPU_TEXTUREFORMAT_D24_UNORM + SDL_GPU_TEXTUREFORMAT_D32_FLOAT + SDL_GPU_TEXTUREFORMAT_D24_UNORM_S8_UINT + SDL_GPU_TEXTUREFORMAT_D32_FLOAT_S8_UINT + + SDL_GPUTextureUsageFlags + symbols->gpu-texture-usage-flags + gpu-texture-usage-flags->symbols + SDL_GPU_TEXTUREUSAGE_SAMPLER + SDL_GPU_TEXTUREUSAGE_COLOR_TARGET + SDL_GPU_TEXTUREUSAGE_DEPTH_STENCIL_TARGET + SDL_GPU_TEXTUREUSAGE_GRAPHICS_STORAGE_READ + SDL_GPU_TEXTUREUSAGE_COMPUTE_STORAGE_READ + SDL_GPU_TEXTUREUSAGE_COMPUTE_STORAGE_WRITE + SDL_GPU_TEXTUREUSAGE_COMPUTE_STORAGE_SIMULTANEOUS_READ_WRITE + + SDL_GPUTextureType + symbol->gpu-texture-type + gpu-texture-type->symbol + SDL_GPU_TEXTURETYPE_2D + SDL_GPU_TEXTURETYPE_2D_ARRAY + SDL_GPU_TEXTURETYPE_3D + SDL_GPU_TEXTURETYPE_CUBE + SDL_GPU_TEXTURETYPE_CUBE_ARRAY + + SDL_GPUSampleCount + int->gpu-sample-count + gpu-sample-count->int + SDL_GPU_SAMPLECOUNT_1 + SDL_GPU_SAMPLECOUNT_2 + SDL_GPU_SAMPLECOUNT_4 + SDL_GPU_SAMPLECOUNT_8 + + SDL_GPUCubeMapFace + symbol->gpu-cube-map-face + gpu-cube-map-face->symbol + SDL_GPU_CUBEMAPFACE_POSITIVEX + SDL_GPU_CUBEMAPFACE_NEGATIVEX + SDL_GPU_CUBEMAPFACE_POSITIVEY + SDL_GPU_CUBEMAPFACE_NEGATIVEY + SDL_GPU_CUBEMAPFACE_POSITIVEZ + SDL_GPU_CUBEMAPFACE_NEGATIVEZ + + SDL_GPUBufferUsageFlags + symbols->gpu-buffer-usage-flags + gpu-buffer-usage-flags->symbols + SDL_GPU_BUFFERUSAGE_VERTEX + SDL_GPU_BUFFERUSAGE_INDEX + SDL_GPU_BUFFERUSAGE_INDIRECT + SDL_GPU_BUFFERUSAGE_GRAPHICS_STORAGE_READ + SDL_GPU_BUFFERUSAGE_COMPUTE_STORAGE_READ + SDL_GPU_BUFFERUSAGE_COMPUTE_STORAGE_WRITE + + SDL_GPUTransferBufferUsage + symbol->gpu-transfer-buffer-usage + gpu-transfer-buffer-usage->symbol + SDL_GPU_TRANSFERBUFFERUSAGE_UPLOAD + SDL_GPU_TRANSFERBUFFERUSAGE_DOWNLOAD + + SDL_GPUShaderStage + symbol->gpu-shader-stage + gpu-shader-stage->symbol + SDL_GPU_SHADERSTAGE_VERTEX + SDL_GPU_SHADERSTAGE_FRAGMENT + + SDL_GPUShaderFormat + symbols->gpu-shader-format + gpu-shader-format->symbols + SDL_GPU_SHADERFORMAT_INVALID + SDL_GPU_SHADERFORMAT_PRIVATE + SDL_GPU_SHADERFORMAT_SPIRV + SDL_GPU_SHADERFORMAT_DXBC + SDL_GPU_SHADERFORMAT_DXIL + SDL_GPU_SHADERFORMAT_MSL + SDL_GPU_SHADERFORMAT_METALLIB + + SDL_GPUVertexElementFormat + symbol->gpu-vertex-element-format + gpu-vertex-element-format->symbol + SDL_GPU_VERTEXELEMENTFORMAT_INVALID + SDL_GPU_VERTEXELEMENTFORMAT_INT + SDL_GPU_VERTEXELEMENTFORMAT_INT2 + SDL_GPU_VERTEXELEMENTFORMAT_INT3 + SDL_GPU_VERTEXELEMENTFORMAT_INT4 + SDL_GPU_VERTEXELEMENTFORMAT_UINT + SDL_GPU_VERTEXELEMENTFORMAT_UINT2 + SDL_GPU_VERTEXELEMENTFORMAT_UINT3 + SDL_GPU_VERTEXELEMENTFORMAT_UINT4 + SDL_GPU_VERTEXELEMENTFORMAT_FLOAT + SDL_GPU_VERTEXELEMENTFORMAT_FLOAT2 + SDL_GPU_VERTEXELEMENTFORMAT_FLOAT3 + SDL_GPU_VERTEXELEMENTFORMAT_FLOAT4 + SDL_GPU_VERTEXELEMENTFORMAT_BYTE2 + SDL_GPU_VERTEXELEMENTFORMAT_BYTE4 + SDL_GPU_VERTEXELEMENTFORMAT_UBYTE2 + SDL_GPU_VERTEXELEMENTFORMAT_UBYTE4 + SDL_GPU_VERTEXELEMENTFORMAT_BYTE2_NORM + SDL_GPU_VERTEXELEMENTFORMAT_BYTE4_NORM + SDL_GPU_VERTEXELEMENTFORMAT_UBYTE2_NORM + SDL_GPU_VERTEXELEMENTFORMAT_UBYTE4_NORM + SDL_GPU_VERTEXELEMENTFORMAT_SHORT2 + SDL_GPU_VERTEXELEMENTFORMAT_SHORT4 + SDL_GPU_VERTEXELEMENTFORMAT_USHORT2 + SDL_GPU_VERTEXELEMENTFORMAT_USHORT4 + SDL_GPU_VERTEXELEMENTFORMAT_SHORT2_NORM + SDL_GPU_VERTEXELEMENTFORMAT_SHORT4_NORM + SDL_GPU_VERTEXELEMENTFORMAT_USHORT2_NORM + SDL_GPU_VERTEXELEMENTFORMAT_USHORT4_NORM + SDL_GPU_VERTEXELEMENTFORMAT_HALF2 + SDL_GPU_VERTEXELEMENTFORMAT_HALF4 + + SDL_GPUVertexInputRate + symbol->gpu-vertex-input-rate + gpu-vertex-input-rate->symbol + SDL_GPU_VERTEXINPUTRATE_VERTEX + SDL_GPU_VERTEXINPUTRATE_INSTANCE + + SDL_GPUFillMode + symbol->gpu-fill-mode + gpu-fill-mode->symbol + SDL_GPU_FILLMODE_FILL + SDL_GPU_FILLMODE_LINE + + SDL_GPUCullMode + symbol->gpu-cull-mode + gpu-cull-mode->symbol + SDL_GPU_CULLMODE_NONE + SDL_GPU_CULLMODE_FRONT + SDL_GPU_CULLMODE_BACK + + SDL_GPUFrontFace + symbol->gpu-front-face + gpu-front-face->symbol + SDL_GPU_FRONTFACE_COUNTER_CLOCKWISE + SDL_GPU_FRONTFACE_CLOCKWISE + + SDL_GPUCompareOp + symbol->gpu-compare-op + gpu-compare-op->symbol + SDL_GPU_COMPAREOP_INVALID + SDL_GPU_COMPAREOP_NEVER + SDL_GPU_COMPAREOP_LESS + SDL_GPU_COMPAREOP_EQUAL + SDL_GPU_COMPAREOP_LESS_OR_EQUAL + SDL_GPU_COMPAREOP_GREATER + SDL_GPU_COMPAREOP_NOT_EQUAL + SDL_GPU_COMPAREOP_GREATER_OR_EQUAL + SDL_GPU_COMPAREOP_ALWAYS + + SDL_GPUStencilOp + symbol->gpu-stencil-op + gpu-stencil-op->symbol + SDL_GPU_STENCILOP_INVALID + SDL_GPU_STENCILOP_KEEP + SDL_GPU_STENCILOP_ZERO + SDL_GPU_STENCILOP_REPLACE + SDL_GPU_STENCILOP_INCREMENT_AND_CLAMP + SDL_GPU_STENCILOP_DECREMENT_AND_CLAMP + SDL_GPU_STENCILOP_INVERT + SDL_GPU_STENCILOP_INCREMENT_AND_WRAP + SDL_GPU_STENCILOP_DECREMENT_AND_WRAP + + SDL_GPUBlendOp + symbol->gpu-blend-op + gpu-blend-op->symbol + SDL_GPU_BLENDOP_INVALID + SDL_GPU_BLENDOP_ADD + SDL_GPU_BLENDOP_SUBTRACT + SDL_GPU_BLENDOP_REVERSE_SUBTRACT + SDL_GPU_BLENDOP_MIN + SDL_GPU_BLENDOP_MAX + + SDL_GPUBlendFactor + symbol->gpu-blend-factor + gpu-blend-factor->symbol + SDL_GPU_BLENDFACTOR_INVALID + SDL_GPU_BLENDFACTOR_ZERO + SDL_GPU_BLENDFACTOR_ONE + SDL_GPU_BLENDFACTOR_SRC_COLOR + SDL_GPU_BLENDFACTOR_ONE_MINUS_SRC_COLOR + SDL_GPU_BLENDFACTOR_DST_COLOR + SDL_GPU_BLENDFACTOR_ONE_MINUS_DST_COLOR + SDL_GPU_BLENDFACTOR_SRC_ALPHA + SDL_GPU_BLENDFACTOR_ONE_MINUS_SRC_ALPHA + SDL_GPU_BLENDFACTOR_DST_ALPHA + SDL_GPU_BLENDFACTOR_ONE_MINUS_DST_ALPHA + SDL_GPU_BLENDFACTOR_CONSTANT_COLOR + SDL_GPU_BLENDFACTOR_ONE_MINUS_CONSTANT_COLOR + SDL_GPU_BLENDFACTOR_SRC_ALPHA_SATURATE + + SDL_GPUColorComponentFlags + symbols->gpu-color-component-flags + gpu-color-component-flags->symbols + SDL_GPU_COLORCOMPONENT_R + SDL_GPU_COLORCOMPONENT_G + SDL_GPU_COLORCOMPONENT_B + SDL_GPU_COLORCOMPONENT_A + + SDL_GPUFilter + symbol->gpu-filter + gpu-filter->symbol + SDL_GPU_FILTER_NEAREST + SDL_GPU_FILTER_LINEAR + + SDL_GPUSamplerMipmapMode + symbol->gpu-sampler-mipmap-mode + gpu-sampler-mipmap-mode->symbol + SDL_GPU_SAMPLERMIPMAPMODE_NEAREST + SDL_GPU_SAMPLERMIPMAPMODE_LINEAR + + SDL_GPUSamplerAddressMode + symbol->gpu-sampler-address-mode + gpu-sampler-address-mode->symbol + SDL_GPU_SAMPLERADDRESSMODE_REPEAT + SDL_GPU_SAMPLERADDRESSMODE_MIRRORED_REPEAT + SDL_GPU_SAMPLERADDRESSMODE_CLAMP_TO_EDGE + + SDL_GPUPresentMode + symbol->gpu-present-mode + gpu-present-mode->symbol + SDL_GPU_PRESENTMODE_VSYNC + SDL_GPU_PRESENTMODE_IMMEDIATE + SDL_GPU_PRESENTMODE_MAILBOX + + SDL_GPUSwapchainComposition + symbol->gpu-swapchain-composition + gpu-swapchain-composition->symbol + SDL_GPU_SWAPCHAINCOMPOSITION_SDR + SDL_GPU_SWAPCHAINCOMPOSITION_SDR_LINEAR + SDL_GPU_SWAPCHAINCOMPOSITION_HDR_EXTENDED_LINEAR + SDL_GPU_SWAPCHAINCOMPOSITION_HDR10_ST2048 + + SDL_GPUViewport + SDL_GPUTextureTransferInfo + SDL_GPUTransferBufferLocation + SDL_GPUTextureLocation + SDL_GPUTextureRegion + SDL_GPUBlitRegion + SDL_GPUBufferLocation + SDL_GPUBufferRegion + SDL_GPUVertexBufferDescription + SDL_GPUVertexAttribute + SDL_GPUVertexInputState + SDL_GPUStencilOpState + SDL_GPUColorTargetBlendState + SDL_GPUShaderCreateInfo + SDL_GPUTextureCreateInfo + SDL_GPUBufferCreateInfo + SDL_GPUTransferBufferCreateInfo + SDL_GPURasterizerState + SDL_GPUMultisampleState + SDL_GPUDepthStencilState + SDL_GPUColorTargetDescription + SDL_GPUGraphicsPipelineTargetInfo + SDL_GPUGraphicsPipelineCreateInfo + SDL_GPUComputePipelineCreateInfo + SDL_GPUColorTargetInfo + SDL_GPUDepthStencilTargetInfo + SDL_GPUBlitInfo + SDL_GPUBufferBinding + SDL_GPUTextureSamplerBinding + SDL_GPUStorageBufferReadWriteBinding + SDL_GPUStorageTextureReadWriteBinding + + gpu-device? + wrap-gpu-device + unwrap-gpu-device + gpu-device-destroyed? + set-gpu-device-destroyed! + + gpu-buffer? + wrap-gpu-buffer + unwrap-gpu-buffer + gpu-buffer-released? + set-gpu-buffer-released! + + gpu-transfer-buffer? + wrap-gpu-transfer-buffer + unwrap-gpu-transfer-buffer + gpu-transfer-buffer-released? + set-gpu-transfer-buffer-released! + + gpu-shader? + wrap-gpu-shader + unwrap-gpu-shader + gpu-shader-released? + set-gpu-shader-released! + + gpu-texture? + wrap-gpu-texture + unwrap-gpu-texture + gpu-texture-released? + set-gpu-texture-released! + + gpu-graphics-pipeline? + wrap-gpu-graphics-pipeline + unwrap-gpu-graphics-pipeline + gpu-graphics-pipeline-released? + set-gpu-graphics-pipeline-released! + + gpu-command-buffer? + wrap-gpu-command-buffer + unwrap-gpu-command-buffer + + gpu-copy-pass? + wrap-gpu-copy-pass + unwrap-gpu-copy-pass + + gpu-render-pass? + wrap-gpu-render-pass + unwrap-gpu-render-pass + + gpu-compute-pass? + wrap-gpu-compute-pass + unwrap-gpu-compute-pass + + SDL_AcquireGPUCommandBuffer + SDL_AcquireGPUSwapchainTexture + SDL_BeginGPUCopyPass + SDL_BeginGPURenderPass + SDL_BindGPUGraphicsPipeline + SDL_BindGPUVertexBuffers + SDL_BlitGPUTexture + SDL_CreateGPUBuffer + SDL_CreateGPUDevice + SDL_CreateGPUGraphicsPipeline + SDL_CreateGPUShader + SDL_CreateGPUTexture + SDL_CreateGPUTransferBuffer + SDL_ClaimWindowForGPUDevice + SDL_DestroyGPUDevice + SDL_DrawGPUPrimitives + SDL_EndGPUCopyPass + SDL_EndGPURenderPass + SDL_GetGPUDeviceDriver + SDL_GetGPUDriver + SDL_GetGPUSwapchainTextureFormat + SDL_GetNumGPUDrivers + SDL_GPUTextureSupportsSampleCount + SDL_MapGPUTransferBuffer + SDL_PushGPUVertexUniformData + SDL_PushGPUFragmentUniformData + SDL_ReleaseGPUBuffer + SDL_ReleaseGPUGraphicsPipeline + SDL_ReleaseGPUShader + SDL_ReleaseGPUTexture + SDL_ReleaseGPUTransferBuffer + SDL_ReleaseWindowFromGPUDevice + SDL_SetGPUBufferName + SDL_SubmitGPUCommandBuffer + SDL_UnmapGPUTransferBuffer + SDL_UploadToGPUBuffer)) + +(define-enum SDL_GPUPrimitiveType + symbol->gpu-primitive-type + primitive-type->symbol + (triangle-list SDL_GPU_PRIMITIVETYPE_TRIANGLELIST) + (triangle-strip SDL_GPU_PRIMITIVETYPE_TRIANGLESTRIP) + (line-list SDL_GPU_PRIMITIVETYPE_LINELIST) + (line-strip SDL_GPU_PRIMITIVETYPE_LINESTRIP) + (point-list SDL_GPU_PRIMITIVETYPE_POINTLIST)) + +(define-enum SDL_GPULoadOp + symbol->gpu-load-op + gpu-load-op->symbol + (load SDL_GPU_LOADOP_LOAD) + (clear SDL_GPU_LOADOP_CLEAR) + (dont-care SDL_GPU_LOADOP_DONT_CARE)) + +(define-enum SDL_GPUStoreOp + symbol->gpu-store-op + gpu-store-op->symbol + (store SDL_GPU_STOREOP_STORE) + (dont-care SDL_GPU_STOREOP_DONT_CARE) + (resolve SDL_GPU_STOREOP_RESOLVE) + (resolve-and-store SDL_GPU_STOREOP_RESOLVE_AND_STORE)) + +(define-enum SDL_GPUIndexElementSize + symbol->gpu-index-element-size + gpu-index-element-size->symbol + (16-bit SDL_GPU_INDEXELEMENTSIZE_16BIT) + (32-bit SDL_GPU_INDEXELEMENTSIZE_32BIT)) + +(define-enum SDL_GPUTextureFormat + symbol->gpu-texture-format + gpu-texture-format->symbol + (invalid SDL_GPU_TEXTUREFORMAT_INVALID) + (a8-unorm SDL_GPU_TEXTUREFORMAT_A8_UNORM) + (r8-unorm SDL_GPU_TEXTUREFORMAT_R8_UNORM) + (r8g8-unorm SDL_GPU_TEXTUREFORMAT_R8G8_UNORM) + (r8g8b8a8-unorm SDL_GPU_TEXTUREFORMAT_R8G8B8A8_UNORM) + (r16-unorm SDL_GPU_TEXTUREFORMAT_R16_UNORM) + (r16g16-unorm SDL_GPU_TEXTUREFORMAT_R16G16_UNORM) + (r16g16b16a16-unorm SDL_GPU_TEXTUREFORMAT_R16G16B16A16_UNORM) + (r10g10b10a2-unorm SDL_GPU_TEXTUREFORMAT_R10G10B10A2_UNORM) + (b5g6r5-unorm SDL_GPU_TEXTUREFORMAT_B5G6R5_UNORM) + (b5g5r5a1-unorm SDL_GPU_TEXTUREFORMAT_B5G5R5A1_UNORM) + (b4g4r4a4-unorm SDL_GPU_TEXTUREFORMAT_B4G4R4A4_UNORM) + (b8g8r8a8-unorm SDL_GPU_TEXTUREFORMAT_B8G8R8A8_UNORM) + (bc1-rbga-unorm SDL_GPU_TEXTUREFORMAT_BC1_RGBA_UNORM) + (bc2-rgba-unorm SDL_GPU_TEXTUREFORMAT_BC2_RGBA_UNORM) + (bc3-rgba-unorm SDL_GPU_TEXTUREFORMAT_BC3_RGBA_UNORM) + (bc4-r-unorm SDL_GPU_TEXTUREFORMAT_BC4_R_UNORM) + (bc5-rg-unorm SDL_GPU_TEXTUREFORMAT_BC5_RG_UNORM) + (bc7-rgba-unorm SDL_GPU_TEXTUREFORMAT_BC7_RGBA_UNORM) + (bc6h-rgb-float SDL_GPU_TEXTUREFORMAT_BC6H_RGB_FLOAT) + (bc6h-rgb-float SDL_GPU_TEXTUREFORMAT_BC6H_RGB_UFLOAT) + (r8-snorm SDL_GPU_TEXTUREFORMAT_R8_SNORM) + (r8g8-snorm SDL_GPU_TEXTUREFORMAT_R8G8_SNORM) + (r8g8b8a8-snorm SDL_GPU_TEXTUREFORMAT_R8G8B8A8_SNORM) + (r16-snorm SDL_GPU_TEXTUREFORMAT_R16_SNORM) + (r16g16-snorm SDL_GPU_TEXTUREFORMAT_R16G16_SNORM) + (r16g16b16a16-snorm SDL_GPU_TEXTUREFORMAT_R16G16B16A16_SNORM) + (r16-float SDL_GPU_TEXTUREFORMAT_R16_FLOAT) + (r16g16-float SDL_GPU_TEXTUREFORMAT_R16G16_FLOAT) + (r16g16b16a16-float SDL_GPU_TEXTUREFORMAT_R16G16B16A16_FLOAT) + (r32-float SDL_GPU_TEXTUREFORMAT_R32_FLOAT) + (r32g32-float SDL_GPU_TEXTUREFORMAT_R32G32_FLOAT) + (r32g32b32a32-float SDL_GPU_TEXTUREFORMAT_R32G32B32A32_FLOAT) + (r11g11b10-ufloat SDL_GPU_TEXTUREFORMAT_R11G11B10_UFLOAT) + (r8-uint SDL_GPU_TEXTUREFORMAT_R8_UINT) + (r8g8-uint SDL_GPU_TEXTUREFORMAT_R8G8_UINT) + (r8g8b8a8-uint SDL_GPU_TEXTUREFORMAT_R8G8B8A8_UINT) + (r16-uint SDL_GPU_TEXTUREFORMAT_R16_UINT) + (r16g16-uint SDL_GPU_TEXTUREFORMAT_R16G16_UINT) + (r16g16b16a16-uint SDL_GPU_TEXTUREFORMAT_R16G16B16A16_UINT) + (r32-uint SDL_GPU_TEXTUREFORMAT_R32_UINT) + (r32g32-uint SDL_GPU_TEXTUREFORMAT_R32G32_UINT) + (r32g32b32a32-uint SDL_GPU_TEXTUREFORMAT_R32G32B32A32_UINT) + (r8-int SDL_GPU_TEXTUREFORMAT_R8_INT) + (r8g8-int SDL_GPU_TEXTUREFORMAT_R8G8_INT) + (r8g8b8a8-int SDL_GPU_TEXTUREFORMAT_R8G8B8A8_INT) + (r16-int SDL_GPU_TEXTUREFORMAT_R16_INT) + (r16g16-int SDL_GPU_TEXTUREFORMAT_R16G16_INT) + (r16g16b16a16-int SDL_GPU_TEXTUREFORMAT_R16G16B16A16_INT) + (r32-int SDL_GPU_TEXTUREFORMAT_R32_INT) + (r32g32-int SDL_GPU_TEXTUREFORMAT_R32G32_INT) + (r32g32b32a32-int SDL_GPU_TEXTUREFORMAT_R32G32B32A32_INT) + (r8g8b8a8-unorm-srgb SDL_GPU_TEXTUREFORMAT_R8G8B8A8_UNORM_SRGB) + (b8g8r8a8-unorm-srgb SDL_GPU_TEXTUREFORMAT_B8G8R8A8_UNORM_SRGB) + (bc1-unorm-srgb SDL_GPU_TEXTUREFORMAT_BC1_RGBA_UNORM_SRGB) + (bc2-unorm-srgb SDL_GPU_TEXTUREFORMAT_BC2_RGBA_UNORM_SRGB) + (bc3-unorm-srgb SDL_GPU_TEXTUREFORMAT_BC3_RGBA_UNORM_SRGB) + (bc7-unorm-srgb SDL_GPU_TEXTUREFORMAT_BC7_RGBA_UNORM_SRGB) + (d16-unorm SDL_GPU_TEXTUREFORMAT_D16_UNORM) + (d24-unorm SDL_GPU_TEXTUREFORMAT_D24_UNORM) + (d32-float SDL_GPU_TEXTUREFORMAT_D32_FLOAT) + (d24-unorm-s8-uint SDL_GPU_TEXTUREFORMAT_D24_UNORM_S8_UINT) + (d32-float-s8-uint SDL_GPU_TEXTUREFORMAT_D32_FLOAT_S8_UINT)) + +(define-bitmask (SDL_GPUTextureUsageFlags uint32) + symbols->gpu-texture-usage-flags + gpu-texture-usage-flags->symbols + (sampler SDL_GPU_TEXTUREUSAGE_SAMPLER) + (color-target SDL_GPU_TEXTUREUSAGE_COLOR_TARGET) + (depth-stencil-target SDL_GPU_TEXTUREUSAGE_DEPTH_STENCIL_TARGET) + (graphics-storage-read SDL_GPU_TEXTUREUSAGE_GRAPHICS_STORAGE_READ) + (compute-storage-read SDL_GPU_TEXTUREUSAGE_COMPUTE_STORAGE_READ) + (compute-storage-write SDL_GPU_TEXTUREUSAGE_COMPUTE_STORAGE_WRITE) + (compute-storage-simultaneous-read-write + SDL_GPU_TEXTUREUSAGE_COMPUTE_STORAGE_SIMULTANEOUS_READ_WRITE)) + +(define-enum SDL_GPUTextureType + symbol->gpu-texture-type + gpu-texture-type->symbol + (2d SDL_GPU_TEXTURETYPE_2D) + (2d-array SDL_GPU_TEXTURETYPE_2D_ARRAY) + (3d SDL_GPU_TEXTURETYPE_3D) + (cube SDL_GPU_TEXTURETYPE_CUBE) + (cube-array SDL_GPU_TEXTURETYPE_CUBE_ARRAY)) + +(define-enum SDL_GPUSampleCount + int->gpu-sample-count + gpu-sample-count->int + (1 SDL_GPU_SAMPLECOUNT_1) + (2 SDL_GPU_SAMPLECOUNT_2) + (4 SDL_GPU_SAMPLECOUNT_4) + (8 SDL_GPU_SAMPLECOUNT_8)) + +(define-enum SDL_GPUCubeMapFace + symbol->gpu-cube-map-face + gpu-cube-map-face->symbol + (positive-x SDL_GPU_CUBEMAPFACE_POSITIVEX) + (negative-x SDL_GPU_CUBEMAPFACE_NEGATIVEX) + (positive-y SDL_GPU_CUBEMAPFACE_POSITIVEY) + (negative-y SDL_GPU_CUBEMAPFACE_NEGATIVEY) + (positive-z SDL_GPU_CUBEMAPFACE_POSITIVEZ) + (negative-z SDL_GPU_CUBEMAPFACE_NEGATIVEZ)) + +(define-bitmask (SDL_GPUBufferUsageFlags uint32) + symbols->gpu-buffer-usage-flags + gpu-buffer-usage-flags->symbols + (vertex SDL_GPU_BUFFERUSAGE_VERTEX) + (index SDL_GPU_BUFFERUSAGE_INDEX) + (indirect SDL_GPU_BUFFERUSAGE_INDIRECT) + (graphics-storage-read SDL_GPU_BUFFERUSAGE_GRAPHICS_STORAGE_READ) + (compute-storage-read SDL_GPU_BUFFERUSAGE_COMPUTE_STORAGE_READ) + (compute-storage-write SDL_GPU_BUFFERUSAGE_COMPUTE_STORAGE_WRITE)) + +(define-enum SDL_GPUTransferBufferUsage + symbol->gpu-transfer-buffer-usage + gpu-transfer-buffer-usage->symbol + (upload SDL_GPU_TRANSFERBUFFERUSAGE_UPLOAD) + (download SDL_GPU_TRANSFERBUFFERUSAGE_DOWNLOAD)) + +(define-enum SDL_GPUShaderStage + symbol->gpu-shader-stage + gpu-shader-stage->symbol + (vertex SDL_GPU_SHADERSTAGE_VERTEX) + (fragment SDL_GPU_SHADERSTAGE_FRAGMENT)) + +(define-bitmask (SDL_GPUShaderFormat uint32) + symbols->gpu-shader-format + gpu-shader-format->symbols + (private SDL_GPU_SHADERFORMAT_PRIVATE) + (spirv SDL_GPU_SHADERFORMAT_SPIRV) + (dxbc SDL_GPU_SHADERFORMAT_DXBC) + (dxil SDL_GPU_SHADERFORMAT_DXIL) + (msl SDL_GPU_SHADERFORMAT_MSL) + (metallib SDL_GPU_SHADERFORMAT_METALLIB)) +(define SDL_GPU_SHADERFORMAT_INVALID 0) + +(define-enum SDL_GPUVertexElementFormat + symbol->gpu-vertex-element-format + gpu-vertex-element-format->symbol + (invalid SDL_GPU_VERTEXELEMENTFORMAT_INVALID) + (int SDL_GPU_VERTEXELEMENTFORMAT_INT) + (int2 SDL_GPU_VERTEXELEMENTFORMAT_INT2) + (int3 SDL_GPU_VERTEXELEMENTFORMAT_INT3) + (int4 SDL_GPU_VERTEXELEMENTFORMAT_INT4) + (uint SDL_GPU_VERTEXELEMENTFORMAT_UINT) + (uint2 SDL_GPU_VERTEXELEMENTFORMAT_UINT2) + (uint3 SDL_GPU_VERTEXELEMENTFORMAT_UINT3) + (uint4 SDL_GPU_VERTEXELEMENTFORMAT_UINT4) + (float SDL_GPU_VERTEXELEMENTFORMAT_FLOAT) + (float2 SDL_GPU_VERTEXELEMENTFORMAT_FLOAT2) + (float3 SDL_GPU_VERTEXELEMENTFORMAT_FLOAT3) + (float4 SDL_GPU_VERTEXELEMENTFORMAT_FLOAT4) + (byte2 SDL_GPU_VERTEXELEMENTFORMAT_BYTE2) + (byte4 SDL_GPU_VERTEXELEMENTFORMAT_BYTE4) + (ubyte2 SDL_GPU_VERTEXELEMENTFORMAT_UBYTE2) + (ubyte4 SDL_GPU_VERTEXELEMENTFORMAT_UBYTE4) + (byte2-norm SDL_GPU_VERTEXELEMENTFORMAT_BYTE2_NORM) + (byte4-norm SDL_GPU_VERTEXELEMENTFORMAT_BYTE4_NORM) + (ubyte2-norm SDL_GPU_VERTEXELEMENTFORMAT_UBYTE2_NORM) + (ubyte4-norm SDL_GPU_VERTEXELEMENTFORMAT_UBYTE4_NORM) + (short2 SDL_GPU_VERTEXELEMENTFORMAT_SHORT2) + (short4 SDL_GPU_VERTEXELEMENTFORMAT_SHORT4) + (ushort2 SDL_GPU_VERTEXELEMENTFORMAT_USHORT2) + (ushort4 SDL_GPU_VERTEXELEMENTFORMAT_USHORT4) + (short2-norm SDL_GPU_VERTEXELEMENTFORMAT_SHORT2_NORM) + (short4-norm SDL_GPU_VERTEXELEMENTFORMAT_SHORT4_NORM) + (ushort2-norm SDL_GPU_VERTEXELEMENTFORMAT_USHORT2_NORM) + (ushort4-norm SDL_GPU_VERTEXELEMENTFORMAT_USHORT4_NORM) + (half2 SDL_GPU_VERTEXELEMENTFORMAT_HALF2) + (half4 SDL_GPU_VERTEXELEMENTFORMAT_HALF4)) + +(define-enum SDL_GPUVertexInputRate + symbol->gpu-vertex-input-rate + gpu-vertex-input-rate->symbol + (vertex SDL_GPU_VERTEXINPUTRATE_VERTEX) + (instance SDL_GPU_VERTEXINPUTRATE_INSTANCE)) + +(define-enum SDL_GPUFillMode + symbol->gpu-fill-mode + gpu-fill-mode->symbol + (fill SDL_GPU_FILLMODE_FILL) + (line SDL_GPU_FILLMODE_LINE)) + +(define-enum SDL_GPUCullMode + symbol->gpu-cull-mode + gpu-cull-mode->symbol + (none SDL_GPU_CULLMODE_NONE) + (front SDL_GPU_CULLMODE_FRONT) + (back SDL_GPU_CULLMODE_BACK)) + +(define-enum SDL_GPUFrontFace + symbol->gpu-front-face + gpu-front-face->symbol + (counter-clockwise SDL_GPU_FRONTFACE_COUNTER_CLOCKWISE) + (clockwise SDL_GPU_FRONTFACE_CLOCKWISE)) + +(define-enum SDL_GPUCompareOp + symbol->gpu-compare-op + gpu-compare-op->symbol + (invalid SDL_GPU_COMPAREOP_INVALID) + (never SDL_GPU_COMPAREOP_NEVER) + (less SDL_GPU_COMPAREOP_LESS) + (equal SDL_GPU_COMPAREOP_EQUAL) + (less-or-equal SDL_GPU_COMPAREOP_LESS_OR_EQUAL) + (greater SDL_GPU_COMPAREOP_GREATER) + (not-equal SDL_GPU_COMPAREOP_NOT_EQUAL) + (greater-or-equal SDL_GPU_COMPAREOP_GREATER_OR_EQUAL) + (always SDL_GPU_COMPAREOP_ALWAYS)) + +(define-enum SDL_GPUStencilOp + symbol->gpu-stencil-op + gpu-stencil-op->symbol + (invalid SDL_GPU_STENCILOP_INVALID) + (keep SDL_GPU_STENCILOP_KEEP) + (zero SDL_GPU_STENCILOP_ZERO) + (replace SDL_GPU_STENCILOP_REPLACE) + (increment-and-clamp SDL_GPU_STENCILOP_INCREMENT_AND_CLAMP) + (decrement-and-clamp SDL_GPU_STENCILOP_DECREMENT_AND_CLAMP) + (invert SDL_GPU_STENCILOP_INVERT) + (increment-and-wrap SDL_GPU_STENCILOP_INCREMENT_AND_WRAP) + (decrement-and-wrap SDL_GPU_STENCILOP_DECREMENT_AND_WRAP)) + +(define-enum SDL_GPUBlendOp + symbol->gpu-blend-op + gpu-blend-op->symbol + (invalid SDL_GPU_BLENDOP_INVALID) + (add SDL_GPU_BLENDOP_ADD) + (subtract SDL_GPU_BLENDOP_SUBTRACT) + (reverse-subtract SDL_GPU_BLENDOP_REVERSE_SUBTRACT) + (min SDL_GPU_BLENDOP_MIN) + (max SDL_GPU_BLENDOP_MAX)) + +(define-enum SDL_GPUBlendFactor + symbol->gpu-blend-factor + gpu-blend-factor->symbol + (invalid SDL_GPU_BLENDFACTOR_INVALID) + (zero SDL_GPU_BLENDFACTOR_ZERO) + (one SDL_GPU_BLENDFACTOR_ONE) + (src-color SDL_GPU_BLENDFACTOR_SRC_COLOR) + (one-minus-src-color SDL_GPU_BLENDFACTOR_ONE_MINUS_SRC_COLOR) + (dst-color SDL_GPU_BLENDFACTOR_DST_COLOR) + (one-minus-dst-color SDL_GPU_BLENDFACTOR_ONE_MINUS_DST_COLOR) + (src-alpha SDL_GPU_BLENDFACTOR_SRC_ALPHA) + (one-minus-src-alpha SDL_GPU_BLENDFACTOR_ONE_MINUS_SRC_ALPHA) + (dst-alpha SDL_GPU_BLENDFACTOR_DST_ALPHA) + (one-minus-dst-alpha SDL_GPU_BLENDFACTOR_ONE_MINUS_DST_ALPHA) + (constant-color SDL_GPU_BLENDFACTOR_CONSTANT_COLOR) + (one-minus-constant-color SDL_GPU_BLENDFACTOR_ONE_MINUS_CONSTANT_COLOR) + (alpha-saturate SDL_GPU_BLENDFACTOR_SRC_ALPHA_SATURATE)) + +(define-bitmask (SDL_GPUColorComponentFlags uint8) + symbols->gpu-color-component-flags + gpu-color-component-flags->symbols + (r SDL_GPU_COLORCOMPONENT_R) + (g SDL_GPU_COLORCOMPONENT_G) + (b SDL_GPU_COLORCOMPONENT_B) + (a SDL_GPU_COLORCOMPONENT_A)) + +(define-enum SDL_GPUFilter + symbol->gpu-filter + gpu-filter->symbol + (nearest SDL_GPU_FILTER_NEAREST) + (linear SDL_GPU_FILTER_LINEAR)) + +(define-enum SDL_GPUSamplerMipmapMode + symbol->gpu-sampler-mipmap-mode + gpu-sampler-mipmap-mode->symbol + (nearest SDL_GPU_SAMPLERMIPMAPMODE_NEAREST) + (linear SDL_GPU_SAMPLERMIPMAPMODE_LINEAR)) + +(define-enum SDL_GPUSamplerAddressMode + symbol->gpu-sampler-address-mode + gpu-sampler-address-mode->symbol + (repease SDL_GPU_SAMPLERADDRESSMODE_REPEAT) + (mirrored-repeat SDL_GPU_SAMPLERADDRESSMODE_MIRRORED_REPEAT) + (clamp-to-edge SDL_GPU_SAMPLERADDRESSMODE_CLAMP_TO_EDGE)) + +(define-enum SDL_GPUPresentMode + symbol->gpu-present-mode + gpu-present-mode->symbol + (vsync SDL_GPU_PRESENTMODE_VSYNC) + (immediate SDL_GPU_PRESENTMODE_IMMEDIATE) + (mailbox SDL_GPU_PRESENTMODE_MAILBOX)) + +(define-enum SDL_GPUSwapchainComposition + symbol->gpu-swapchain-composition + gpu-swapchain-composition->symbol + (sdr SDL_GPU_SWAPCHAINCOMPOSITION_SDR) + (sdr-linear SDL_GPU_SWAPCHAINCOMPOSITION_SDR_LINEAR) + (hdr-extended-linear SDL_GPU_SWAPCHAINCOMPOSITION_HDR_EXTENDED_LINEAR) + (hdr10-st2048 SDL_GPU_SWAPCHAINCOMPOSITION_HDR10_ST2048)) + +(define-bstruct SDL_GPUViewport + (struct + (x f32) + (y f32) + (w f32) + (h f32) + (min_depth f32) + (max_depth f32))) + +(define-bstruct SDL_GPUTextureTransferInfo + (struct + (transfer_buffer (* void)) ; SDL_GPUTransferBuffer + (offset u32) + (pixels_per_row u32) + (rows_per_layer u32))) + +(define-bstruct SDL_GPUTransferBufferLocation + (struct + (transfer_buffer (* void)) ; SDL_GPUTransferBuffer + (offset u32))) + +(define-bstruct SDL_GPUTextureLocation + (struct + (texture (* void)) ; SDL_GPUTexture + (mip_level u32) + (layer u32) + (x u32) + (y u32) + (z u32))) + +(define-bstruct SDL_GPUTextureRegion + (struct + (texture (* void)) ; SDL_GPUTexture + (mip_level u32) + (layer u32) + (x u32) + (y u32) + (z u32) + (w u32) + (h u32) + (d u32))) + +(define-bstruct SDL_GPUBlitRegion + (struct + (texture (* void)) ; SDL_GPUTexture + (mip_level u32) + (layer_or_depth_plane u32) + (x u32) + (y u32) + (w u32) + (h u32))) + +(define-bstruct SDL_GPUBufferLocation + (struct + (buffer (* void)) ; SDL_GPUBuffer + (offset u32))) + +(define-bstruct SDL_GPUBufferRegion + (struct + (buffer (* void)) ; SDL_GPUBuffer + (offset u32) + (size u32))) + +(define-bstruct SDL_GPUVertexBufferDescription + (struct + (slot u32) + (pitch u32) + (input_rate int) ; SDL_GPUVertexInputRate + (instance_step_rate u32))) + +(define-bstruct SDL_GPUVertexAttribute + (struct + (location u32) + (buffer_slot u32) + (format int) ; SDL_GPUVertexElementFormat + (offset u32))) + +(define-bstruct SDL_GPUVertexInputState + (struct + (vertex_buffer_descriptions (* SDL_GPUVertexBufferDescription)) + (num_vertex_buffers u32) + (vertex_attributes (* SDL_GPUVertexAttribute)) + (num_vertex_attributes u32))) + +(define-bstruct SDL_GPUStencilOpState + (struct + (fail_op int) ; SDL_GPUStencilOp + (pass_op int) ; SDL_GPUStencilOp + (depth_fail_op int) ; SDL_GPUStencilOp + (compare_op int) ; SDL_GPUCompareOp + )) + +(define-bstruct SDL_GPUColorTargetBlendState + (struct + (src_color_blendfactor int) ; SDL_GPUBlendFactor + (dst_color_blendfactor int) ; SDL_GPUBlendFactor + (color_blend_op int) ; SDL_GPUBlendOp + (src_alpha_blendfactor int) ; SDL_GPUBlendFactor + (dst_alpha_blendfactor int) ; SDL_GPUBlendFactor + (alpha_blend_op int) ; SDL_GPUBlendOp + (color_write_mask u8) ; SDL_GPUColorComponentFlags + (enable_blend u8) ; bool + (enable_color_write_mask u8) ; bool + (_ u8) + (_ u8))) + +(define-bstruct SDL_GPUShaderCreateInfo + (struct + (code_size size_t) + (code (* u8)) + (entrypoint (* u8)) ; char* + (format u32) ; SDL_GPUShaderFormat + (stage int) ; SDL_GPUShaderStage + (num_samplers u32) + (num_storage_textures u32) + (num_storage_buffers u32) + (num_uniform_buffers u32) + (props u32) ; SDL_PropertiesID + )) + +(define-bstruct SDL_GPUTextureCreateInfo + (struct + (type int) ; SDL_GPUTextureType + (format int) ; SDL_GPUTextureFormat + (usage u32) ; SDL_GPUTextureUsageFlags + (width u32) + (height u32) + (layer_count_or_depth u32) + (num_levels u32) + (sample_count int) ; SDL_GPUSampleCount + (props u32) ; SDL_PropertiesID + )) + +(define-bstruct SDL_GPUBufferCreateInfo + (struct + (usage u32) ; SDL_GPUBufferUsageFlags + (size u32) + (props u32) ; SDL_PropertiesID + )) + +(define-bstruct SDL_GPUTransferBufferCreateInfo + (struct + (usage u32) ; SDL_GPUTransferBufferUsage + (size u32) + (props u32) ; SDL_PropertiesID + )) + +(define-bstruct SDL_GPURasterizerState + (struct + (fill_mode int) ; SDL_GPUFillMode + (cull_mode int) ; SDL_GPUCullMode + (front_face int) ; SDL_GPUFrontFace + (depth_bias_constant_factor f32) + (depth_bias_clamp f32) + (depth_bias_slope_factor f32) + (enable_depth_bias u8) ; bool + (enable_depth_clip u8) ; bool + (_ u8) + (_ u8))) + +(define-bstruct SDL_GPUMultisampleState + (struct + (sample_count int) ; SDL_GPUSampleCount + (sample_mask u32) + (enable_mask u8) ; bool + (_ u8) + (_ u8) + (_ u8))) + +(define-bstruct SDL_GPUDepthStencilState + (struct + (compare_op u32) ; SDL_GPUCompareOp + (back_stencil_state SDL_GPUStencilOpState) + (front_stencil_state SDL_GPUStencilOpState) + (compare_mask u8) + (write_mask u8) + (enable_depth_test u8) ; bool + (enable_depth_write u8) ; bool + (enable_stencil_test u8) ; bool + (_ u8) + (_ u8) + (_ u8))) + +(define-bstruct SDL_GPUColorTargetDescription + (struct + (format u32) ; SDL_GPUTextureFormat + (blend_state SDL_GPUColorTargetBlendState))) + +(define-bstruct SDL_GPUGraphicsPipelineTargetInfo + (struct + (color_target_descriptions (* SDL_GPUColorTargetDescription)) + (num_color_targets u32) + (depth_stencil_format u32) ; SDL_GPUTextureFormat + (has_depth_stencil_target u8) ; bool + (_ u8) + (_ u8) + (_ u8))) + +(define-bstruct SDL_GPUGraphicsPipelineCreateInfo + (struct + (vertex_shader (* void)) ; SDL_GPUShader + (fragment_shader (* void)) ; SDL_GPUShader + (vertex_input_state SDL_GPUVertexInputState) + (primitive_type int) ; SDL_GPUPrimitiveType + (rasterizer_state SDL_GPURasterizerState) + (multisample_state SDL_GPUMultisampleState) + (depth_stencil_state SDL_GPUDepthStencilState) + (target_info SDL_GPUGraphicsPipelineTargetInfo) + (props u32) ; SDL_PropertiesID + )) + +(define-bstruct SDL_GPUComputePipelineCreateInfo + (struct + (code_size size_t) + (code (* u8)) + (entrypoint (* u8)) ; char + (format int) ; SDL_GPUShaderFormat + (num_samplers u32) + (num_readonly_storage_textures u32) + (num_readonly_storage_buffers u32) + (num_readwrite_storage_textures u32) + (num_readwrite_storage_buffers u32) + (num_uniform_buffers u32) + (threadcount_x u32) + (threadcount_y u32) + (threadcount_z u32) + (props u32) ; SDL_PropertiesID + )) + +(define-bstruct SDL_GPUColorTargetInfo + (struct + (texture (* void)) ; SDL_GPUTexture + (mip_level u32) + (layer_or_depth_plane u32) + (clear_color SDL_FColor) + (load_op int) ; SDL_GPULoadOp + (store_op int) ; SDL_GPUStoreOp + (resolve_texture (* void)) ; SDL_GPUTexture + (resolve_mip_level u32) + (resolve_layer u32) + (cycle u8) ; bool + (cycle_resolve_texture u8) ; bool + (_ u8) + (_ u8))) + +(define-bstruct SDL_GPUDepthStencilTargetInfo + (struct + (texture (* void)) ; SDL_GPUTexture + (clear_depth f32) + (load_op int) ; SDL_GPULoadOp + (store_op int) ; SDL_GPUStoreOp + (stencil_load_op int) ; SDL_GPULoadOp + (stencil_store_op int) ; SDL_GPUStoreOp + (cycle u8) ; bool + (clear_stencil u8) + (_ u8) + (_ u8))) + +(define-bstruct SDL_GPUBlitInfo + (struct + (source SDL_GPUBlitRegion) + (destination SDL_GPUBlitRegion) + (load_op int) ; SDL_GPULoadOp + (clear_color SDL_FColor) + (flip_mode int) ; SDL_FlipMode + (filter int) ; SDL_GPUFilter + (cycle u8) ; bool + (_ u8) + (_ u8) + (_ u8))) + +(define-bstruct SDL_GPUBufferBinding + (struct + (buffer (* void)) ; SDL_GPUBuffer + (offset u32))) + +(define-bstruct SDL_GPUTextureSamplerBinding + (struct + (texture (* void)) ; SDL_GPUTexture + (sampler (* void)) ; SDL_GPUSampler + )) + +(define-bstruct SDL_GPUStorageBufferReadWriteBinding + (struct + (buffer (* void)) ; SDL_GPUBuffer + (cycle u8) ; bool + (_ u8) + (_ u8) + (_ u8))) + +(define-bstruct SDL_GPUStorageTextureReadWriteBinding + (struct + (texture (* void)) ; SDL_GPUTexture + (mip_level u32) + (layer u32) + (cycle u8) + (_ u8) + (_ u8) + (_ u8))) + +(define-sdl-pointer-type + gpu-device? wrap-gpu-device unwrap-gpu-device + gpu-device-destroyed? set-gpu-device-destroyed! + (lambda (device port) + (display "#" port))) + +(define-sdl-pointer-type + gpu-buffer? wrap-gpu-buffer unwrap-gpu-buffer + gpu-buffer-released? set-gpu-buffer-released! + (lambda (buffer port) + (display "#" port))) + +(define-sdl-pointer-type + gpu-transfer-buffer? wrap-gpu-transfer-buffer unwrap-gpu-transfer-buffer + gpu-transfer-buffer-released? set-gpu-transfer-buffer-released! + (lambda (transfer-buffer port) + (display "#" port))) + +(define-sdl-pointer-type + gpu-shader? wrap-gpu-shader unwrap-gpu-shader + gpu-shader-released? set-gpu-shader-released! + (lambda (shader port) + (display "#" port))) + +(define-sdl-pointer-type + gpu-texture? wrap-gpu-texture unwrap-gpu-texture + gpu-texture-released? set-gpu-texture-released! + (lambda (texture port) + (format port "#" + (pointer-address (unwrap-gpu-texture texture))))) + +(define-sdl-pointer-type + gpu-graphics-pipeline? wrap-gpu-graphics-pipeline unwrap-gpu-graphics-pipeline + gpu-graphics-pipeline-released? set-gpu-graphics-pipeline-released! + (lambda (graphics-pipeline port) + (display "#" port))) + +(define-wrapped-pointer-type + gpu-command-buffer? wrap-gpu-command-buffer unwrap-gpu-command-buffer + (lambda (command-buffer port) + (display "#" port))) + +(define-wrapped-pointer-type + gpu-copy-pass? wrap-gpu-copy-pass unwrap-gpu-copy-pass + (lambda (copy-pass port) + (display "#" port))) + +(define-wrapped-pointer-type + gpu-render-pass? wrap-gpu-render-pass unwrap-gpu-render-pass + (lambda (render-pass port) + (display "#" port))) + +(define-wrapped-pointer-type + gpu-compute-pass? wrap-gpu-compute-pass unwrap-gpu-compute-pass + (lambda (compute-pass port) + (display "#" port))) + +(define-sdl SDL_AcquireGPUCommandBuffer '* -> '*) +(define-sdl SDL_AcquireGPUSwapchainTexture '* '* '* '* '* -> bool) +(define-sdl SDL_BeginGPUCopyPass '* -> '*) +(define-sdl SDL_BeginGPURenderPass '* '* uint32 '* -> '*) +(define-sdl SDL_BindGPUGraphicsPipeline '* '*) +(define-sdl SDL_BindGPUVertexBuffers '* uint32 '* uint32) +(define-sdl SDL_BlitGPUTexture '* '*) +(define-sdl SDL_CreateGPUBuffer '* '* -> '*) +(define-sdl SDL_CreateGPUDevice SDL_GPUShaderFormat bool '* -> '*) +(define-sdl SDL_CreateGPUGraphicsPipeline '* '* -> '*) +(define-sdl SDL_CreateGPUShader '* '* -> '*) +(define-sdl SDL_CreateGPUTexture '* '* -> '*) +(define-sdl SDL_CreateGPUTransferBuffer '* '* -> '*) +(define-sdl SDL_ClaimWindowForGPUDevice '* '* -> bool) +(define-sdl SDL_DestroyGPUDevice '*) +(define-sdl SDL_DrawGPUPrimitives '* uint32 uint32 uint32 uint32) +(define-sdl SDL_EndGPUCopyPass '*) +(define-sdl SDL_EndGPURenderPass '*) +(define-sdl SDL_GetGPUDeviceDriver '* -> '*) +(define-sdl SDL_GetGPUDriver int -> '*) +(define-sdl SDL_GetGPUSwapchainTextureFormat '* '* -> SDL_GPUTextureFormat) +(define-sdl SDL_GetNumGPUDrivers -> int) +(define-sdl SDL_GPUTextureSupportsSampleCount '* SDL_GPUTextureFormat SDL_GPUSampleCount -> bool) +(define-sdl SDL_MapGPUTransferBuffer '* '* bool -> '*) +(define-sdl SDL_PushGPUFragmentUniformData '* uint32 '* uint32) +(define-sdl SDL_PushGPUVertexUniformData '* uint32 '* uint32) +(define-sdl SDL_ReleaseGPUBuffer '* '*) +(define-sdl SDL_ReleaseGPUGraphicsPipeline '* '*) +(define-sdl SDL_ReleaseGPUShader '* '*) +(define-sdl SDL_ReleaseGPUTexture '* '*) +(define-sdl SDL_ReleaseGPUTransferBuffer '* '*) +(define-sdl SDL_ReleaseWindowFromGPUDevice '* '*) +(define-sdl SDL_SetGPUBufferName '* '* '*) +(define-sdl SDL_SubmitGPUCommandBuffer '* -> bool) +(define-sdl SDL_UnmapGPUTransferBuffer '* '*) +(define-sdl SDL_UploadToGPUBuffer '* '* '* bool) diff --git a/sdl3/bindings/init.scm b/sdl3/bindings/init.scm new file mode 100644 index 0000000..ac92829 --- /dev/null +++ b/sdl3/bindings/init.scm @@ -0,0 +1,49 @@ +;;; guile-sdl3 -- Scheme bindings for SDL3 +;;; Copyright © 2024 David Thompson +;;; +;;; Licensed under the Apache License, Version 2.0 (the "License"); +;;; you may not use this file except in compliance with the License. +;;; You may obtain a copy of the License at +;;; +;;; http://www.apache.org/licenses/LICENSE-2.0 +;;; +;;; Unless required by applicable law or agreed to in writing, software +;;; distributed under the License is distributed on an "AS IS" BASIS, +;;; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +;;; See the License for the specific language governing permissions and +;;; limitations under the License. + +;;; Commentary: +;; +;; Low-level bindings for SDL_init.h. +;; +;;; Code: + +(define-module (sdl3 bindings init) + #:use-module (sdl3 bindings utils) + #:use-module (system foreign) + #:export (SDL_InitFlags + SDL_INIT_AUDIO + SDL_INIT_VIDEO + SDL_INIT_JOYSTICK + SDL_INIT_HAPTIC + SDL_INIT_GAMEPAD + SDL_INIT_EVENTS + SDL_INIT_SENSOR + SDL_INIT_CAMERA + + SDL_Init + SDL_Quit)) + +(define SDL_InitFlags uint32) +(define SDL_INIT_AUDIO #x00000010) +(define SDL_INIT_VIDEO #x00000020) +(define SDL_INIT_JOYSTICK #x00000200) +(define SDL_INIT_HAPTIC #x00001000) +(define SDL_INIT_GAMEPAD #x00002000) +(define SDL_INIT_EVENTS #x00004000) +(define SDL_INIT_SENSOR #x00008000) +(define SDL_INIT_CAMERA #x00010000) + +(define-sdl SDL_Init SDL_InitFlags -> bool) +(define-sdl SDL_Quit) diff --git a/sdl3/bindings/pixels.scm b/sdl3/bindings/pixels.scm new file mode 100644 index 0000000..a1f2a28 --- /dev/null +++ b/sdl3/bindings/pixels.scm @@ -0,0 +1,41 @@ +;;; guile-sdl3 -- Scheme bindings for SDL3 +;;; Copyright © 2024 David Thompson +;;; +;;; Licensed under the Apache License, Version 2.0 (the "License"); +;;; you may not use this file except in compliance with the License. +;;; You may obtain a copy of the License at +;;; +;;; http://www.apache.org/licenses/LICENSE-2.0 +;;; +;;; Unless required by applicable law or agreed to in writing, software +;;; distributed under the License is distributed on an "AS IS" BASIS, +;;; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +;;; See the License for the specific language governing permissions and +;;; limitations under the License. + +;;; Commentary: +;; +;; Low-level bindings for SDL_pixels.h. +;; +;;; Code: + +(define-module (sdl3 bindings pixels) + #:use-module (bstruct) + #:use-module (sdl3 bindings utils) + #:use-module (system foreign) + #:export (SDL_Color + SDL_FColor)) + +(define-bstruct SDL_Color + (struct + (r u8) + (g u8) + (b u8) + (a u8))) + +(define-bstruct SDL_FColor + (struct + (r f32) + (g f32) + (b f32) + (a f32))) diff --git a/sdl3/bindings/surface.scm b/sdl3/bindings/surface.scm new file mode 100644 index 0000000..d9ebd15 --- /dev/null +++ b/sdl3/bindings/surface.scm @@ -0,0 +1,36 @@ +;;; guile-sdl3 -- Scheme bindings for SDL3 +;;; Copyright © 2024 David Thompson +;;; +;;; Licensed under the Apache License, Version 2.0 (the "License"); +;;; you may not use this file except in compliance with the License. +;;; You may obtain a copy of the License at +;;; +;;; http://www.apache.org/licenses/LICENSE-2.0 +;;; +;;; Unless required by applicable law or agreed to in writing, software +;;; distributed under the License is distributed on an "AS IS" BASIS, +;;; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +;;; See the License for the specific language governing permissions and +;;; limitations under the License. + +;;; Commentary: +;; +;; Low-level bindings for SDL_surface.h. +;; +;;; Code: + +(define-module (sdl3 bindings surface) + #:use-module (sdl3 bindings utils) + #:export (SDL_FlipMode + symbol->flip-mode + flip-mode->symbol + SDL_FLIP_NONE + SDL_FLIP_HORIZONTAL + SDL_FLIP_VERTICAL)) + +(define-enum SDL_FlipMode + symbol->flip-mode + flip-mode->symbol + (none SDL_FLIP_NONE) + (horizontal SDL_FLIP_HORIZONTAL) + (vertical SDL_FLIP_VERTICAL)) diff --git a/sdl3/bindings/utils.scm b/sdl3/bindings/utils.scm new file mode 100644 index 0000000..bdc6942 --- /dev/null +++ b/sdl3/bindings/utils.scm @@ -0,0 +1,133 @@ +;;; guile-sdl3 -- Scheme bindings for SDL3 +;;; Copyright © 2024 David Thompson +;;; +;;; Licensed under the Apache License, Version 2.0 (the "License"); +;;; you may not use this file except in compliance with the License. +;;; You may obtain a copy of the License at +;;; +;;; http://www.apache.org/licenses/LICENSE-2.0 +;;; +;;; Unless required by applicable law or agreed to in writing, software +;;; distributed under the License is distributed on an "AS IS" BASIS, +;;; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +;;; See the License for the specific language governing permissions and +;;; limitations under the License. + +;;; Commentary: +;; +;; Low-level FFI binding utilities. +;; +;;; Code: + +(define-module (sdl3 bindings utils) + #:use-module (ice-9 match) + #:use-module (sdl3 config) + #:use-module (sdl3 guardian) + #:use-module (srfi srfi-1) + #:use-module (srfi srfi-9) + #:use-module (srfi srfi-9 gnu) + #:use-module (system foreign) + #:use-module (system foreign-library) + #:export (bool + define-enum + define-bitmask + define-sdl + define-sdl-pointer-type + define-symbol<->enum + flags->bitmask)) + +;; Type aliases: +(define bool uint8) + +(define-syntax enum-case + (syntax-rules () + ((_ x) (error "no matching enum" x)) + ((_ x (var val) . rest) + (if (eq? x var) val (enum-case x . rest))))) + +(define-syntax define-enum + (lambda (stx) + (syntax-case stx () + ((_ type-name atom->enum enum->atom (atom name . id) ...) + (every identifier? #'(name ...)) + (with-syntax (((defs ...) + (let lp ((i 0) (specs #'((name . id) ...))) + (syntax-case specs () + (() '()) + (((name) . rest) + (cons #`(define name #,i) + (lp (1+ i) #'rest))) + (((name id) . rest) + (cons #`(define name id) + (lp (1+ (syntax->datum #'id)) #'rest))))))) + #'(begin + (define type-name int) + defs ... + (define (atom->enum x) + (match x ('atom name) ...)) + (define (enum->atom x) + (enum-case x (name 'atom) ...)))))))) + +(define-syntax bitmask-case + (syntax-rules () + ((_ x) (error "no matching flag" x)) + ((_ x (var val) . rest) + (let ((cont (lambda () (bitmask-case x . rest)))) + (if (zero? (logand x var)) + (cont) + (cons val (cont))))))) + +(define-syntax define-bitmask + (lambda (stx) + (syntax-case stx () + ((_ (type-name c-type) + symbols->bitmask + bitmask->symbols + (sym name) ...) + (every identifier? #'(name ...)) + (with-syntax (((defs ...) + (let lp ((i 1) (names #'(name ...))) + (syntax-case names () + (() '()) + ((name . rest) + (cons #`(define name #,i) + (lp (ash i 1) #'rest))))))) + #'(begin + (define type-name c-type) + defs ... + (define (symbols->bitmask flags) + (fold (lambda (flag result) + (logior (match flag ('sym name) ...) + result)) + 0 flags)) + (define (bitmask->symbols x) + (bitmask-case x (name 'sym) ...)))))))) + + +(define-syntax define-sdl + (lambda (stx) + (syntax-case stx (->) + ((_ name arg-type ... -> return-type) + #`(define name + (foreign-library-function %libsdl3 + #,(symbol->string (syntax->datum #'name)) + #:arg-types (list arg-type ...) + #:return-type return-type))) + ((_ name arg-type ...) + #'(define-sdl name arg-type ... -> void))))) + +(define-syntax-rule (define-sdl-pointer-type name + pred wrap unwrap + destroyed-pred set-destroyed + print + (field accessors ...) ...) + (begin + (define-record-type name + (ctor ptr) + pred + (ptr unwrap) + (destroyed? destroyed-pred set-destroyed) + (field accessors ...) ...) + (define (wrap ptr) + (sdl-protect (ctor ptr))) + (set-record-type-printer! name print))) diff --git a/sdl3/bindings/video.scm b/sdl3/bindings/video.scm new file mode 100644 index 0000000..40ee4cc --- /dev/null +++ b/sdl3/bindings/video.scm @@ -0,0 +1,103 @@ +;;; guile-sdl3 -- Scheme bindings for SDL3 +;;; Copyright © 2024 David Thompson +;;; +;;; Licensed under the Apache License, Version 2.0 (the "License"); +;;; you may not use this file except in compliance with the License. +;;; You may obtain a copy of the License at +;;; +;;; http://www.apache.org/licenses/LICENSE-2.0 +;;; +;;; Unless required by applicable law or agreed to in writing, software +;;; distributed under the License is distributed on an "AS IS" BASIS, +;;; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +;;; See the License for the specific language governing permissions and +;;; limitations under the License. + +;;; Commentary: +;; +;; Low-level bindings for SDL_video.h. +;; +;;; Code: + +(define-module (sdl3 bindings video) + #:use-module (sdl3 bindings utils) + #:use-module (system foreign) + #:export (SDL_DisplayID + SDL_WindowID + + SDL_WindowFlags + SDL_WINDOW_FULLSCREEN + SDL_WINDOW_OPENGL + SDL_WINDOW_OCCLUDED + SDL_WINDOW_HIDDEN + SDL_WINDOW_BORDERLESS + SDL_WINDOW_RESIZABLE + SDL_WINDOW_MINIMIZED + SDL_WINDOW_MAXIMIZED + SDL_WINDOW_MOUSE_GRABBED + SDL_WINDOW_INPUT_FOCUS + SDL_WINDOW_MOUSE_FOCUS + SDL_WINDOW_EXTERNAL + SDL_WINDOW_MODAL + SDL_WINDOW_HIGH_PIXEL_DENSITY + SDL_WINDOW_MOUSE_CAPTURE + SDL_WINDOW_MOUSE_RELATIVE_MODE + SDL_WINDOW_ALWAYS_ON_TOP + SDL_WINDOW_UTILITY + SDL_WINDOW_TOOLTIP + SDL_WINDOW_POPUP_MENU + SDL_WINDOW_KEYBOARD_GRABBED + SDL_WINDOW_VULKAN + SDL_WINDOW_METAL + SDL_WINDOW_TRANSPARENT + SDL_WINDOW_NOT_FOCUSABLE + + window? + wrap-window + unwrap-window + window-destroyed? + set-window-destroyed! + + SDL_CreateWindow + SDL_DestroyWindow + SDL_GetWindowSizeInPixels)) + +(define SDL_DisplayID uint32) +(define SDL_WindowID uint32) + +(define SDL_WindowFlags uint64) +(define SDL_WINDOW_FULLSCREEN #x0000000000000001) +(define SDL_WINDOW_OPENGL #x0000000000000002) +(define SDL_WINDOW_OCCLUDED #x0000000000000004) +(define SDL_WINDOW_HIDDEN #x0000000000000008) +(define SDL_WINDOW_BORDERLESS #x0000000000000010) +(define SDL_WINDOW_RESIZABLE #x0000000000000020) +(define SDL_WINDOW_MINIMIZED #x0000000000000040) +(define SDL_WINDOW_MAXIMIZED #x0000000000000080) +(define SDL_WINDOW_MOUSE_GRABBED #x0000000000000100) +(define SDL_WINDOW_INPUT_FOCUS #x0000000000000200) +(define SDL_WINDOW_MOUSE_FOCUS #x0000000000000400) +(define SDL_WINDOW_EXTERNAL #x0000000000000800) +(define SDL_WINDOW_MODAL #x0000000000001000) +(define SDL_WINDOW_HIGH_PIXEL_DENSITY #x0000000000002000) +(define SDL_WINDOW_MOUSE_CAPTURE #x0000000000004000) +(define SDL_WINDOW_MOUSE_RELATIVE_MODE #x0000000000008000) +(define SDL_WINDOW_ALWAYS_ON_TOP #x0000000000010000) +(define SDL_WINDOW_UTILITY #x0000000000020000) +(define SDL_WINDOW_TOOLTIP #x0000000000040000) +(define SDL_WINDOW_POPUP_MENU #x0000000000080000) +(define SDL_WINDOW_KEYBOARD_GRABBED #x0000000000100000) +(define SDL_WINDOW_VULKAN #x0000000010000000) +(define SDL_WINDOW_METAL #x0000000020000000) +(define SDL_WINDOW_TRANSPARENT #x0000000040000000) +(define SDL_WINDOW_NOT_FOCUSABLE #x0000000080000000) + +(define-sdl-pointer-type + window? wrap-window unwrap-window + window-destroyed? set-window-destroyed! + (lambda (window port) + (display "#" port))) + +(define-sdl SDL_CreateWindow '* int int SDL_WindowFlags -> '*) +(define-sdl SDL_DestroyWindow '*) +(define-sdl SDL_GetWindowSizeInPixels '* '* '* -> bool) diff --git a/sdl3/config.scm.in b/sdl3/config.scm.in new file mode 100644 index 0000000..5d3c614 --- /dev/null +++ b/sdl3/config.scm.in @@ -0,0 +1,26 @@ +;;; guile-sdl3 -- Scheme bindings for SDL3 +;;; Copyright © 2024 David Thompson +;;; +;;; Licensed under the Apache License, Version 2.0 (the "License"); +;;; you may not use this file except in compliance with the License. +;;; You may obtain a copy of the License at +;;; +;;; http://www.apache.org/licenses/LICENSE-2.0 +;;; +;;; Unless required by applicable law or agreed to in writing, software +;;; distributed under the License is distributed on an "AS IS" BASIS, +;;; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +;;; See the License for the specific language governing permissions and +;;; limitations under the License. + +(define-module (sdl3 config) + #:export (%libsdl3)) + +(define-syntax define-canonical + (lambda (stx) + (syntax-case stx () + ((_ name file) + (with-syntax ((file (canonicalize-path (syntax->datum #'file)))) + #'(define name file)))))) + +(define-canonical %libsdl3 "@SDL3_LIBDIR@/libSDL3.so") diff --git a/sdl3/errors.scm b/sdl3/errors.scm new file mode 100644 index 0000000..3d48647 --- /dev/null +++ b/sdl3/errors.scm @@ -0,0 +1,54 @@ +;;; guile-sdl3 -- Scheme bindings for SDL3 +;;; Copyright © 2024 David Thompson +;;; +;;; Licensed under the Apache License, Version 2.0 (the "License"); +;;; you may not use this file except in compliance with the License. +;;; You may obtain a copy of the License at +;;; +;;; http://www.apache.org/licenses/LICENSE-2.0 +;;; +;;; Unless required by applicable law or agreed to in writing, software +;;; distributed under the License is distributed on an "AS IS" BASIS, +;;; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +;;; See the License for the specific language governing permissions and +;;; limitations under the License. + +;;; Commentary: +;; +;; SDL3 errors. +;; +;;; Code: + +(define-module (sdl3 errors) + #:use-module (ice-9 exceptions) + #:use-module (sdl3 bindings error) + #:use-module (system foreign) + #:export (sdl-get-error + make-sdl-error + sdl-assert + sdl-assert-non-null)) + +(define (sdl-get-error) + (pointer->string (SDL_GetError))) + +(define-exception-type &sdl-exception &error + make-sdl-exception + sdl-exception?) + +(define* (make-sdl-error origin #:key + (message (sdl-get-error)) + (irritants '())) + (make-exception + (make-sdl-exception) + (make-exception-with-message message) + (make-exception-with-irritants irritants) + (make-exception-with-origin origin))) + +(define (sdl-assert origin bool) + (unless (eq? bool 1) + (raise-exception (make-sdl-error origin)))) + +(define (sdl-assert-non-null origin pointer) + (when (null-pointer? pointer) + (raise-exception (make-sdl-error origin))) + pointer) diff --git a/sdl3/events.scm b/sdl3/events.scm new file mode 100644 index 0000000..be0e0ef --- /dev/null +++ b/sdl3/events.scm @@ -0,0 +1,43 @@ +;;; guile-sdl3 -- Scheme bindings for SDL3 +;;; Copyright © 2024 David Thompson +;;; +;;; Licensed under the Apache License, Version 2.0 (the "License"); +;;; you may not use this file except in compliance with the License. +;;; You may obtain a copy of the License at +;;; +;;; http://www.apache.org/licenses/LICENSE-2.0 +;;; +;;; Unless required by applicable law or agreed to in writing, software +;;; distributed under the License is distributed on an "AS IS" BASIS, +;;; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +;;; See the License for the specific language governing permissions and +;;; limitations under the License. + +;;; Commentary: +;; +;; Low-level FFI binding utilities. +;; +;;; Code: + +(define-module (sdl3 events) + #:use-module (bstruct) + #:use-module (sdl3 bindings events) + #:use-module (system foreign) + #:export (event? + event-type + poll-event)) + +(define (make-event) + (bstruct-alloc SDL_Event)) + +(define (event? obj) + (bstruct? SDL_Event obj)) + +(define (event-type event) + (event-type->symbol (bstruct-ref SDL_Event event type))) + +(define (poll-event) + (and (eq? (SDL_PollEvent %null-pointer) 1) + (let ((event (make-event))) + (SDL_PollEvent (bstruct->pointer SDL_Event event)) + event))) diff --git a/sdl3/gpu.scm b/sdl3/gpu.scm new file mode 100644 index 0000000..e46a38c --- /dev/null +++ b/sdl3/gpu.scm @@ -0,0 +1,966 @@ +;;; guile-sdl3 -- Scheme bindings for SDL3 +;;; Copyright © 2024 David Thompson +;;; +;;; Licensed under the Apache License, Version 2.0 (the "License"); +;;; you may not use this file except in compliance with the License. +;;; You may obtain a copy of the License at +;;; +;;; http://www.apache.org/licenses/LICENSE-2.0 +;;; +;;; Unless required by applicable law or agreed to in writing, software +;;; distributed under the License is distributed on an "AS IS" BASIS, +;;; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +;;; See the License for the specific language governing permissions and +;;; limitations under the License. + +;;; Commentary: +;; +;; SDL3 3D rendering and GPU compute. +;; +;;; Code: + +(define-module (sdl3 gpu) + #:use-module (bstruct) + #:use-module (ice-9 match) + #:use-module (rnrs bytevectors) + #:use-module (sdl3 bindings gpu) + #:use-module (sdl3 bindings surface) + #:use-module (sdl3 bindings video) + #:use-module (sdl3 errors) + #:use-module (srfi srfi-9) + #:use-module (system foreign) + #:export (num-gpu-drivers + gpu-driver + + make-gpu-device + destroy-gpu-device! + gpu-device-driver + claim-window-for-gpu-device! + release-window-from-gpu-device! + gpu-texture-supports-sample-count? + gpu-swapchain-texture-format + + make-gpu-buffer + release-gpu-buffer! + set-gpu-buffer-name! + + make-gpu-transfer-buffer + release-gpu-transfer-buffer! + map-gpu-transfer-buffer! + unmap-gpu-transfer-buffer! + + make-gpu-shader + release-gpu-shader! + + make-gpu-texture + release-gpu-texture! + + make-gpu-vertex-buffer-description + gpu-vertex-buffer-description? + gpu-vertex-buffer-description-slot + gpu-vertex-buffer-description-pitch + gpu-vertex-buffer-description-input-rate + gpu-vertex-buffer-description-instance-step-rate + + make-gpu-vertex-attribute + gpu-vertex-attribute? + gpu-vertex-attribute-location + gpu-vertex-attribute-buffer-slot + gpu-vertex-attribute-format + gpu-vertex-attribute-offset + + make-gpu-vertex-input-state + gpu-vertex-input-state? + gpu-vertex-input-state-vertex-buffer-descriptions + gpu-vertex-input-state-vertex-attributes + + make-gpu-stencil-op-state + gpu-stencil-op-state? + gpu-stencil-op-state-fail + gpu-stencil-op-state-pass + gpu-stencil-op-state-depth-fail + gpu-stencil-op-state-compare + + make-gpu-color-target-blend-state + gpu-color-target-blend-state? + gpu-color-target-blend-state-src-color-factor + gpu-color-target-blend-state-dst-color-factor + gpu-color-target-blend-state-color-op + gpu-color-target-blend-state-src-alpha-factor + gpu-color-target-blend-state-dst-alpha-factor + gpu-color-target-blend-state-alpha-op + gpu-color-target-blend-state-color-write-mask + + make-gpu-rasterizer-state + gpu-rasterizer-state? + gpu-rasterizer-state-fill-mode + gpu-rasterizer-state-cull-mode + gpu-rasterizer-state-front-face + gpu-rasterizer-state-depth-bias-constant-factor + gpu-rasterizer-state-depth-bias-clamp + gpu-rasterizer-state-depth-bias-slope-factor + gpu-rasterizer-state-depth-clip? + + make-gpu-multisample-state + gpu-multisample-state? + gpu-multisample-state-sample-count + gpu-multisample-state-sample-mask + + make-gpu-depth-stencil-state + gpu-depth-stencil-state? + gpu-depth-stencil-state-compare-op + gpu-depth-stencil-state-back-stencil-state + gpu-depth-stencil-state-front-stencil-state + gpu-depth-stencil-state-compare-mask + gpu-depth-stencil-state-write-mask + + make-gpu-color-target-description + gpu-color-target-description? + gpu-color-target-description-format + gpu-color-target-description-blend-state + + make-gpu-graphics-pipeline-target-info + gpu-graphics-pipeline-target-info? + gpu-graphics-pipeline-target-info-color-targets + gpu-graphics-pipeline-target-info-depth-stencil-format + + make-gpu-graphics-pipeline + release-gpu-graphics-pipeline! + + acquire-gpu-command-buffer + submit-gpu-command-buffer! + acquire-gpu-swapchain-texture + push-gpu-fragment-uniform-data + push-gpu-vertex-uniform-data + make-gpu-blit-info + gpu-blit-info? + set-gpu-blit-info-source-texture! + set-gpu-blit-info-destination-texture! + blit-gpu-texture + + begin-gpu-copy-pass + end-gpu-copy-pass + upload-to-gpu-buffer + + make-gpu-color-target + set-gpu-color-target-texture! + + make-gpu-depth-stencil-target + make-gpu-buffer-binding + + begin-gpu-render-pass + end-gpu-render-pass + bind-gpu-graphics-pipeline + bind-gpu-vertex-buffers + draw-gpu-primitives) + #:re-export (gpu-device? + gpu-device-destroyed? + + gpu-buffer? + gpu-buffer-released? + + gpu-transfer-buffer? + gpu-transfer-buffer-released? + + gpu-shader? + gpu-shader-released? + + gpu-texture? + gpu-texture-released? + + gpu-graphics-pipeline? + gpu-graphics-pipeline-released? + + gpu-command-buffer? + gpu-copy-pass? + gpu-render-pass? + gpu-compute-pass?)) + +(define-syntax-rule (define-record-type* name + (constructor arg-spec ...) + pred + (field accessors ...) + ...) + (begin + (define-record-type name + (%constructor field ...) + pred + (field accessors ...) ...) + (define* (constructor arg-spec ...) + (%constructor field ...)))) + +(define-syntax-rule (bstruct-alloc-pointer type elems ...) + (bstruct->pointer type (bstruct-alloc type elems ...))) + +(define (gpu-num-gpu-drivers) + (SDL_GetNumGPUDrivers)) + +(define (gpu-driver index) + (pointer->string + (sdl-assert-non-null + 'gpu-driver + (SDL_GetGPUDriver index)))) + + +;;; +;;; Devices +;;; + +(define* (make-gpu-device shader-formats #:key debug? driver) + (wrap-gpu-device + (sdl-assert-non-null + 'make-gpu-device + (SDL_CreateGPUDevice (symbols->gpu-shader-format shader-formats) + (if debug? 1 0) + (if driver + (string->pointer driver) + %null-pointer))))) + +(define (destroy-gpu-device! device) + (unless (gpu-device-destroyed? device) + (SDL_DestroyGPUDevice (unwrap-gpu-device device)) + (set-gpu-device-destroyed! device #t))) + +(define (gpu-device-driver device) + (pointer->string + (sdl-assert-non-null + 'gpu-device-driver + (SDL_GetGPUDeviceDriver (unwrap-gpu-device device))))) + +(define (claim-window-for-gpu-device! device window) + (sdl-assert + 'claim-window-for-gpu-device! + (SDL_ClaimWindowForGPUDevice (unwrap-gpu-device device) + (unwrap-window window)))) + +(define (release-window-from-gpu-device! device window) + (SDL_ReleaseWindowFromGPUDevice (unwrap-gpu-device device) + (unwrap-window window))) + +(define (gpu-texture-supports-sample-count? device format sample-count) + (eq? (SDL_GPUTextureSupportsSampleCount (unwrap-gpu-device device) + (symbol->gpu-texture-format format) + (int->gpu-sample-count sample-count)) + 1)) + +(define (gpu-swapchain-texture-format device window) + (gpu-texture-format->symbol + (SDL_GetGPUSwapchainTextureFormat (unwrap-gpu-device device) + (unwrap-window window)))) + + +;;; +;;; Buffers +;;; + +(define (make-gpu-buffer device size usage) + (wrap-gpu-buffer + (sdl-assert-non-null + 'make-gpu-buffer + (SDL_CreateGPUBuffer (unwrap-gpu-device device) + (bstruct-alloc-pointer + SDL_GPUBufferCreateInfo + (usage (symbols->gpu-buffer-usage-flags usage)) + (size size)))))) + +(define (release-gpu-buffer! device buffer) + (unless (gpu-buffer-released? buffer) + (SDL_ReleaseGPUBuffer (unwrap-gpu-device device) + (unwrap-gpu-buffer buffer)) + (set-gpu-buffer-released! buffer #t))) + +(define (set-gpu-buffer-name! device buffer name) + (SDL_SetGPUBufferName (unwrap-gpu-device device) + (unwrap-gpu-buffer buffer) + (string->pointer name))) + + +;;; +;;; Transfer buffers +;;; + +(define (make-gpu-transfer-buffer device size usage) + (wrap-gpu-transfer-buffer + (sdl-assert-non-null + 'make-gpu-transfer-buffer + (SDL_CreateGPUTransferBuffer (unwrap-gpu-device device) + (bstruct-alloc-pointer + SDL_GPUTransferBufferCreateInfo + (usage (symbol->gpu-transfer-buffer-usage usage)) + (size size)))))) + +(define (release-gpu-transfer-buffer! device buffer) + (unless (gpu-transfer-buffer-released? buffer) + (SDL_ReleaseGPUTransferBuffer (unwrap-gpu-device device) + (unwrap-gpu-transfer-buffer buffer)) + (set-gpu-transfer-buffer-released! buffer #t))) + +(define* (map-gpu-transfer-buffer! device buffer len #:optional cycle?) + (pointer->bytevector + (sdl-assert-non-null + 'map-gpu-transfer-buffer! + (SDL_MapGPUTransferBuffer (unwrap-gpu-device device) + (unwrap-gpu-transfer-buffer buffer) + (if cycle? 1 0))) + len)) + +(define (unmap-gpu-transfer-buffer! device buffer) + (SDL_UnmapGPUTransferBuffer (unwrap-gpu-device device) + (unwrap-gpu-transfer-buffer buffer))) + + +;;; +;;; Shaders +;;; + +(define* (make-gpu-shader device stage format code #:key + (samplers 0) + (storage-buffers 0) + (uniform-buffers 0) + (entry-point "main")) + (wrap-gpu-shader + (sdl-assert-non-null + 'make-gpu-shader + (SDL_CreateGPUShader (unwrap-gpu-device device) + (bstruct-alloc-pointer + SDL_GPUShaderCreateInfo + (code_size (bytevector-length code)) + (code (bytevector->pointer code)) + (entrypoint (string->pointer entry-point)) + (format (symbols->gpu-shader-format (list format))) + (stage (symbol->gpu-shader-stage stage)) + (num_samplers samplers) + (num_storage_buffers storage-buffers) + (num_uniform_buffers uniform-buffers)))))) + +(define (release-gpu-shader! device shader) + (unless (gpu-shader-released? shader) + (SDL_ReleaseGPUShader (unwrap-gpu-device device) + (unwrap-gpu-shader shader)) + (set-gpu-shader-released! shader #t))) + + +;;; +;;; Textures +;;; + +(define* (make-gpu-texture device + #:key + (type '2d) + (format 'r8g8b8a8-unorm) + (usage '(color-target)) + (width 1) + (height 1) + (layer-count-or-depth 1) + (levels 1) + (sample-count 1)) + (wrap-gpu-texture + (sdl-assert-non-null + 'make-gpu-texture + (SDL_CreateGPUTexture (unwrap-gpu-device device) + (bstruct-alloc-pointer + SDL_GPUTextureCreateInfo + (type (symbol->gpu-texture-type type)) + (format (symbol->gpu-texture-format format)) + (usage (symbols->gpu-texture-usage-flags usage)) + (width width) + (height height) + (layer_count_or_depth layer-count-or-depth) + (num_levels levels) + (sample_count (int->gpu-sample-count sample-count))))))) + +(define (release-gpu-texture! device texture) + (unless (gpu-texture-released? texture) + (SDL_ReleaseGPUTexture (unwrap-gpu-device device) + (unwrap-gpu-texture texture)) + (set-gpu-texture-released! texture #t))) + + +;;; +;;; Graphics pipelines +;;; + +(define-record-type* + (make-gpu-vertex-buffer-description #:key slot pitch (input-rate 'vertex) (instance-step-rate 0)) + gpu-vertex-buffer-description? + (slot gpu-vertex-buffer-description-slot) + (pitch gpu-vertex-buffer-description-pitch) + (input-rate gpu-vertex-buffer-description-input-rate) + (instance-step-rate gpu-vertex-buffer-description-instance-step-rate)) + +(define-record-type* + (make-gpu-vertex-attribute #:key location buffer-slot format (offset 0)) + gpu-vertex-attribute? + (location gpu-vertex-attribute-location) + (buffer-slot gpu-vertex-attribute-buffer-slot) + (format gpu-vertex-attribute-format) + (offset gpu-vertex-attribute-offset)) + +(define-record-type* + (make-gpu-vertex-input-state #:key + (vertex-buffer-descriptions #()) + (vertex-attributes #())) + gpu-vertex-input-state? + (vertex-buffer-descriptions gpu-vertex-input-state-vertex-buffer-descriptions) + (vertex-attributes gpu-vertex-input-state-vertex-attributes)) + +(define-record-type* + (make-gpu-stencil-op-state #:key + (fail 'keep) + (pass 'keep) + (depth-fail 'keep) + (compare 'always)) + gpu-stencil-op-state? + (fail gpu-stencil-op-state-fail) + (pass gpu-stencil-op-state-pass) + (depth-fail gpu-stencil-op-state-depth-fail) + (compare gpu-stencil-op-state-compare)) + +(define-record-type* + (make-gpu-color-target-blend-state #:key + (src-color-factor 'one) + (dst-color-factor 'zero) + (color-op 'add) + (src-alpha-factor 'one) + (dst-alpha-factor 'zero) + (alpha-op 'add) + (color-write-mask '(r g b a))) + gpu-color-target-blend-state? + (src-color-factor gpu-color-target-blend-state-src-color-factor) + (dst-color-factor gpu-color-target-blend-state-dst-color-factor) + (color-op gpu-color-target-blend-state-color-op) + (src-alpha-factor gpu-color-target-blend-state-src-alpha-factor) + (dst-alpha-factor gpu-color-target-blend-state-dst-alpha-factor) + (alpha-op gpu-color-target-blend-state-alpha-op) + (color-write-mask gpu-color-target-blend-state-color-write-mask)) + +(define-record-type* + (make-gpu-rasterizer-state #:key + (fill-mode 'fill) + (cull-mode 'none) + (front-face 'counter-clockwise) + depth-bias-constant-factor + depth-bias-clamp + depth-bias-slope-factor + depth-clip?) + gpu-rasterizer-state? + (fill-mode gpu-rasterizer-state-fill-mode) + (cull-mode gpu-rasterizer-state-cull-mode) + (front-face gpu-rasterizer-state-front-face) + (depth-bias-constant-factor gpu-rasterizer-state-depth-bias-constant-factor) + (depth-bias-clamp gpu-rasterizer-state-depth-bias-clamp) + (depth-bias-slope-factor gpu-rasterizer-state-depth-bias-slope-factor) + (depth-clip? gpu-rasterizer-state-depth-clip?)) + +(define-record-type* + (make-gpu-multisample-state #:key + (sample-count 1) + (sample-mask #xffffffff)) + gpu-multisample-state? + (sample-count gpu-multisample-state-sample-count) + (sample-mask gpu-multisample-state-sample-mask)) + +(define-record-type* + (make-gpu-depth-stencil-state #:key + (compare-op 'always) + (back-stencil-state (make-gpu-stencil-op-state)) + (front-stencil-state (make-gpu-stencil-op-state)) + (compare-mask #xff) + (write-mask #xff)) + gpu-depth-stencil-state? + (compare-op gpu-depth-stencil-state-compare-op) + (back-stencil-state gpu-depth-stencil-state-back-stencil-state) + (front-stencil-state gpu-depth-stencil-state-front-stencil-state) + (compare-mask gpu-depth-stencil-state-compare-mask) + (write-mask gpu-depth-stencil-state-write-mask)) + +(define-record-type* + (make-gpu-color-target-description #:key + format + (blend-state #f)) + gpu-color-target-description? + (format gpu-color-target-description-format) + (blend-state gpu-color-target-description-blend-state)) + +(define-record-type* + (make-gpu-graphics-pipeline-target-info #:key + (color-targets #()) + depth-stencil-format) + gpu-graphics-pipeline-target-info? + (color-targets gpu-graphics-pipeline-target-info-color-targets) + (depth-stencil-format gpu-graphics-pipeline-target-info-depth-stencil-format)) + +(define* (make-gpu-graphics-pipeline device #:key + vertex-shader + fragment-shader + vertex-input-state + (primitive-type 'triangle-list) + (rasterizer-state (make-gpu-rasterizer-state)) + multisample-state + depth-stencil-state + target-info) + (match-let ((($ vertex-buffer-descriptions + vertex-attributes) + vertex-input-state) + (($ fill-mode + cull-mode + front-face + depth-bias-constant-factor + depth-bias-clamp + depth-bias-slope-factor + depth-clip?) + rasterizer-state) + (($ sample-count sample-mask) + multisample-state) + (($ compare-op + ($ back-fail + back-pass + back-depth-fail + back-compare) + ($ front-fail + front-pass + front-depth-fail + front-compare) + compare-mask + write-mask) + depth-stencil-state) + (($ color-targets + depth-stencil-format) + target-info)) + ;; Build vertex buffer description structs. + ;; TODO: bstructs should provide a macro to make this easier. + (define num-vert-descs (vector-length vertex-buffer-descriptions)) + (define vert-descs + (make-bytevector (* (bstruct-sizeof SDL_GPUVertexBufferDescription) + num-vert-descs))) + (do ((i 0 (1+ i))) + ((= i num-vert-descs)) + (match (vector-ref vertex-buffer-descriptions i) + (($ slot pitch input-rate + instance-step-rate) + (bstruct-pack! + SDL_GPUVertexBufferDescription + vert-descs + (* (bstruct-sizeof SDL_GPUVertexBufferDescription) i) + (slot slot) + (pitch pitch) + (input_rate (symbol->gpu-vertex-input-rate input-rate)) + (instance_step_rate instance-step-rate))))) + ;; Build vertex attrifbute structsl + (define num-vert-attrs (vector-length vertex-attributes)) + (define vert-attrs + (make-bytevector (* (bstruct-sizeof SDL_GPUVertexAttribute) + num-vert-attrs))) + (do ((i 0 (1+ i))) + ((= i num-vert-attrs)) + (match (vector-ref vertex-attributes i) + (($ location buffer-slot format offset) + (bstruct-pack! + SDL_GPUVertexAttribute + vert-attrs + (* (bstruct-sizeof SDL_GPUVertexAttribute) i) + (location location) + (buffer_slot buffer-slot) + (format (symbol->gpu-vertex-element-format format)) + (offset offset))))) + ;; Build color target structs. + (define num-color-targets (vector-length color-targets)) + (define color-target-descs + (make-bytevector (* (bstruct-sizeof SDL_GPUColorTargetDescription) + num-color-targets))) + (do ((i 0 (1+ i))) + ((= i num-color-targets)) + (match (vector-ref color-targets i) + (($ format #f) + (bstruct-pack! + SDL_GPUColorTargetDescription + color-target-descs + (* (bstruct-sizeof SDL_GPUColorTargetDescription) i) + (format (symbol->gpu-texture-format format)))) + (($ + format + ($ + src-color-factor + dst-color-factor + color-op + src-alpha-factor + dst-alpha-factor + alpha-op + color-write-mask)) + (bstruct-pack! + SDL_GPUColorTargetDescription + color-target-descs + (* (bstruct-sizeof SDL_GPUColorTargetDescription) i) + (format (symbol->gpu-texture-format format)) + ((blend_state src_color_blendfactor) + (symbol->gpu-blend-factor src-color-factor)) + ((blend_state dst_color_blendfactor) + (symbol->gpu-blend-factor dst-color-factor)) + ((blend_state color_blend_op) + (symbol->gpu-blend-op color-op)) + ((blend_state src_alpha_blendfactor) + (symbol->gpu-blend-factor src-alpha-factor)) + ((blend_state dst_alpha_blendfactor) + (symbol->gpu-blend-factor dst-alpha-factor)) + ((blend_state alpha_blend_op) + (symbol->gpu-blend-op alpha-op)) + ((blend_state color_write_mask) + (symbols->gpu-color-component-flags color-write-mask)) + ((blend_state enable_blend) 1) + ((blend_state enable_color_write_mask) 1))))) + ;; Build giant pipeline descriptor struct. + ;; TODO: bstructs should provide syntax for nested struct initialization + (define desc + (bstruct-alloc + SDL_GPUGraphicsPipelineCreateInfo + (vertex_shader (unwrap-gpu-shader vertex-shader)) + (fragment_shader (unwrap-gpu-shader fragment-shader)) + ((vertex_input_state vertex_buffer_descriptions) (bytevector->pointer vert-descs)) + ((vertex_input_state num_vertex_buffers) num-vert-descs) + ((vertex_input_state vertex_attributes) (bytevector->pointer vert-attrs)) + ((vertex_input_state num_vertex_attributes) num-vert-attrs) + (primitive_type (symbol->gpu-primitive-type primitive-type)) + ((rasterizer_state fill_mode) (symbol->gpu-fill-mode fill-mode)) + ((rasterizer_state cull_mode) (symbol->gpu-cull-mode cull-mode)) + ((rasterizer_state front_face) (symbol->gpu-front-face front-face)) + ((rasterizer_state enable_depth_clip) (if depth-clip? 1 0)) + ((rasterizer_state enable_depth_bias) + (if (and depth-bias-constant-factor + depth-bias-clamp + depth-bias-slope-factor) + 1 0)) + ((rasterizer_state depth_bias_constant_factor) + (or depth-bias-constant-factor 0.0)) + ((rasterizer_state depth_bias_clamp) + (or depth-bias-clamp 0.0)) + ((rasterizer_state depth_bias_slope_factor) + (or depth-bias-slope-factor 0.0)) + ((multisample_state sample_count) (int->gpu-sample-count sample-count)) + ((multisample_state sample_mask) sample-mask) + ((multisample_state enable_mask) 1) + ((depth_stencil_state compare_op) (symbol->gpu-compare-op compare-op)) + ((depth_stencil_state back_stencil_state fail_op) + (symbol->gpu-stencil-op back-fail)) + ((depth_stencil_state back_stencil_state pass_op) + (symbol->gpu-stencil-op back-pass)) + ((depth_stencil_state back_stencil_state depth_fail_op) + (symbol->gpu-stencil-op back-depth-fail)) + ((depth_stencil_state back_stencil_state compare_op) + (symbol->gpu-compare-op back-compare)) + ((depth_stencil_state front_stencil_state fail_op) + (symbol->gpu-stencil-op front-fail)) + ((depth_stencil_state front_stencil_state pass_op) + (symbol->gpu-stencil-op front-pass)) + ((depth_stencil_state front_stencil_state depth_fail_op) + (symbol->gpu-stencil-op front-depth-fail)) + ((depth_stencil_state front_stencil_state compare_op) + (symbol->gpu-compare-op front-compare)) + ((depth_stencil_state compare_mask) compare-mask) + ((depth_stencil_state write_mask) compare-mask) + ((depth_stencil_state enable_depth_test) 1) + ((depth_stencil_state enable_depth_write) 1) + ((depth_stencil_state enable_stencil_test) 0) + ((target_info color_target_descriptions) + (bytevector->pointer color-target-descs)) + ((target_info num_color_targets) num-color-targets) + ((target_info depth_stencil_format) + (symbol->gpu-texture-format depth-stencil-format)) + ((target_info has_depth_stencil_target) 1))) + (wrap-gpu-graphics-pipeline + (sdl-assert-non-null + 'make-gpu-graphics-pipeline + (SDL_CreateGPUGraphicsPipeline (unwrap-gpu-device device) + (bstruct->pointer + SDL_GPUGraphicsPipelineCreateInfo + desc)))))) + +(define (release-gpu-graphics-pipeline! device graphics-pipeline) + (unless (gpu-graphics-pipeline-released? graphics-pipeline) + (SDL_ReleaseGPUGraphicsPipeline (unwrap-gpu-device device) + (unwrap-gpu-graphics-pipeline + graphics-pipeline)) + (set-gpu-graphics-pipeline-released! graphics-pipeline #t))) + + +;;; +;;; Command buffers +;;; + +;; TODO: Do the same pointers get used over and over for buffers and +;; passes? If so we should cache them to avoid allocation of FFI +;; pointer objects. +(define (acquire-gpu-command-buffer device) + (wrap-gpu-command-buffer + (sdl-assert-non-null + 'acquire-gpu-command-buffer + (SDL_AcquireGPUCommandBuffer (unwrap-gpu-device device))))) + +(define (submit-gpu-command-buffer! cmd) + (sdl-assert + 'submit-gpu-command-buffer + (SDL_SubmitGPUCommandBuffer (unwrap-gpu-command-buffer cmd)))) + +(define-bstruct + (struct + (texture (* void)) + (width u32) + (height u32))) + +;; TODO: This gets called every frame so we need to get rid of the +;; allocation. The swapchain texture is cycled so the same pointers +;; get reused over and over. +(define (acquire-gpu-swapchain-texture cmd window) + (let ((info (bstruct-alloc ))) + (sdl-assert + 'acquire-gpu-swapchain-texture + (SDL_AcquireGPUSwapchainTexture (unwrap-gpu-command-buffer cmd) + (unwrap-window window) + (bstruct->pointer + info texture) + (bstruct->pointer + info width) + (bstruct->pointer + info height))) + (values (wrap-gpu-texture (bstruct-ref info texture)) + (bstruct-ref info width) + (bstruct-ref info height)))) + +(define* (push-gpu-fragment-uniform-data cmd slot data #:optional + (length (bytevector-length data)) + (offset 0)) + (SDL_PushGPUFragmentUniformData (unwrap-gpu-command-buffer cmd) + slot + (bytevector->pointer data offset) + length)) + +(define* (push-gpu-vertex-uniform-data cmd slot data #:optional + (length (bytevector-length data)) + (offset 0)) + (SDL_PushGPUVertexUniformData (unwrap-gpu-command-buffer cmd) + slot + (bytevector->pointer data offset) + length)) + +(define* (make-gpu-blit-info #:key + source-texture + (source-mip-level 0) + (source-layer-or-depth-plane 0) + (source-x 0) + (source-y 0) + (source-width 0) + (source-height 0) + destination-texture + (destination-mip-level 0) + (destination-layer-or-depth-plane 0) + (destination-x 0) + (destination-y 0) + (destination-width 0) + (destination-height 0) + (load-op 'dont-care) + (clear-color 'todo) + (flip-mode 'none) + (filter 'linear) + cycle?) + (bstruct-alloc + SDL_GPUBlitInfo + ((source texture) + (if source-texture + (unwrap-gpu-texture source-texture) + %null-pointer)) + ((source mip_level) source-mip-level) + ((source layer_or_depth_plane) source-layer-or-depth-plane) + ((source x) source-x) + ((source y) source-y) + ((source w) source-width) + ((source h) source-height) + ((destination texture) + (if destination-texture + (unwrap-gpu-texture destination-texture) + %null-pointer)) + ((destination mip_level) destination-mip-level) + ((destination layer_or_depth_plane) destination-layer-or-depth-plane) + ((destination x) destination-x) + ((destination y) destination-y) + ((destination w) destination-width) + ((destination h) destination-height) + (load_op (symbol->gpu-load-op load-op)) + (flip_mode (symbol->flip-mode flip-mode)) + (filter (symbol->gpu-filter filter)) + (cycle (if cycle? 1 0)))) + +(define (gpu-blit-info? obj) + (bstruct? SDL_GPUBlitInfo obj)) + +(define (set-gpu-blit-info-source-texture! blit-info texture) + (bstruct-set! SDL_GPUBlitInfo blit-info + ((source texture) (unwrap-gpu-texture texture)))) + +(define (set-gpu-blit-info-destination-texture! blit-info texture) + (bstruct-set! SDL_GPUBlitInfo blit-info + ((destination texture) (unwrap-gpu-texture texture)))) + +(define (blit-gpu-texture cmd blit-info) + (SDL_BlitGPUTexture (unwrap-gpu-command-buffer cmd) + (bstruct->pointer SDL_GPUBlitInfo blit-info))) + + +;;; +;;; Copy passes +;;; + +(define (begin-gpu-copy-pass cmd) + (wrap-gpu-copy-pass + (sdl-assert-non-null + 'begin-gpu-copy-pass + (SDL_BeginGPUCopyPass (unwrap-gpu-command-buffer cmd))))) + +(define (end-gpu-copy-pass pass) + (SDL_EndGPUCopyPass (unwrap-gpu-copy-pass pass))) + +(define* (upload-to-gpu-buffer pass source source-start target target-start + len #:optional cycle?) + (SDL_UploadToGPUBuffer (unwrap-gpu-copy-pass pass) + (bstruct-alloc-pointer + SDL_GPUTransferBufferLocation + (transfer_buffer (unwrap-gpu-transfer-buffer source)) + (offset source-start)) + (bstruct-alloc-pointer + SDL_GPUBufferRegion + (buffer (unwrap-gpu-buffer target)) + (offset target-start) + (size len)) + (if cycle? 1 0))) + + +;;; +;;; Render passes +;;; + +(define* (make-gpu-color-target texture #:key + (mip-level 0) + (layer-or-depth-plane 0) + (clear-color 'todo) + (load-op 'load) + (store-op 'store) + resolve-texture + (resolve-mip-level 0) + (resolve-layer 0) + cycle? + cycle-resolve-texture?) + (bstruct-alloc + SDL_GPUColorTargetInfo + (texture (if (gpu-texture? texture) + (unwrap-gpu-texture texture) + %null-pointer)) + (mip_level mip-level) + (layer_or_depth_plane layer-or-depth-plane) + ;; ((clear_color r) 0.6) + ;; ((clear_color g) 0.2) + ;; ((clear_color b) 0.4) + ;; ((clear_color a) 1.0) + (load_op (symbol->gpu-load-op load-op)) + (store_op (symbol->gpu-store-op store-op)) + (resolve_texture (if resolve-texture + (unwrap-gpu-texture resolve-texture) + %null-pointer)) + (resolve_mip_level resolve-mip-level) + (resolve_layer resolve-layer) + (cycle (if cycle? 1 0)) + (cycle_resolve_texture (if cycle-resolve-texture? 1 0)))) + +(define (set-gpu-color-target-texture! color-target texture) + (bstruct-set! SDL_GPUColorTargetInfo color-target + (texture (unwrap-gpu-texture texture)))) + +(define* (make-gpu-depth-stencil-target texture #:key + (clear-depth 1.0) + (load-op 'load) + (store-op 'store) + (stencil-load-op 'dont-care) + (stencil-store-op 'dont-care) + cycle? + (clear-stencil 0)) + (bstruct-alloc + SDL_GPUDepthStencilTargetInfo + (texture (unwrap-gpu-texture texture)) + (clear_depth clear-depth) + (load_op (symbol->gpu-load-op load-op)) + (store_op (symbol->gpu-store-op store-op)) + (stencil_load_op (symbol->gpu-load-op stencil-load-op)) + (stencil_store_op (symbol->gpu-store-op stencil-store-op)) + (cycle (if cycle? 1 0)) + (clear_stencil clear-stencil))) + +(define* (make-gpu-buffer-binding buffer #:optional (offset 0)) + (bstruct-alloc + SDL_GPUBufferBinding + (buffer (unwrap-gpu-buffer buffer)) + (offset offset))) + +(define (begin-gpu-render-pass cmd color-targets depth-stencil-target) + (define color-target-size (bstruct-sizeof SDL_GPUColorTargetInfo)) + (define num-color-targets (vector-length color-targets)) + (define color-target-infos + (make-bytevector (* color-target-size num-color-targets))) + (do ((i 0 (1+ i))) + ((= i num-color-targets)) + (let ((offset (* color-target-size i))) + (call-with-values + (lambda () + (bstruct-unwrap SDL_GPUColorTargetInfo + (vector-ref color-targets i))) + (lambda (bv offset*) + (bytevector-copy! bv offset* + color-target-infos offset + color-target-size))))) + (wrap-gpu-render-pass + (sdl-assert-non-null + 'begin-gpu-render-pass + (SDL_BeginGPURenderPass (unwrap-gpu-command-buffer cmd) + (bytevector->pointer color-target-infos) + num-color-targets + (bstruct->pointer + SDL_GPUDepthStencilTargetInfo + depth-stencil-target))))) + +(define (end-gpu-render-pass pass) + (SDL_EndGPURenderPass (unwrap-gpu-render-pass pass))) + +(define (bind-gpu-graphics-pipeline pass pipeline) + (SDL_BindGPUGraphicsPipeline (unwrap-gpu-render-pass pass) + (unwrap-gpu-graphics-pipeline pipeline))) + +(define (bind-gpu-vertex-buffers pass first-slot bindings) + (define binding-size (bstruct-sizeof SDL_GPUBufferBinding)) + (define num-bindings (vector-length bindings)) + (define bindings* + (make-bytevector (* binding-size num-bindings))) + (do ((i 0 (1+ i))) + ((= i num-bindings)) + (let ((offset (* binding-size i))) + (call-with-values (lambda () + (bstruct-unwrap SDL_GPUBufferBinding + (vector-ref bindings i))) + (lambda (bv offset*) + (bytevector-copy! bv offset* + bindings* offset + binding-size))))) + (SDL_BindGPUVertexBuffers (unwrap-gpu-render-pass pass) + first-slot + (bytevector->pointer bindings*) + (vector-length bindings))) + +(define* (draw-gpu-primitives pass num-vertices #:optional + (num-instances 1) + (first-vertex 0) + (first-instance 0)) + (SDL_DrawGPUPrimitives (unwrap-gpu-render-pass pass) + num-vertices + num-instances + first-vertex + first-instance)) + + +;;; +;;; Compute passes +;;; diff --git a/sdl3/guardian.scm b/sdl3/guardian.scm new file mode 100644 index 0000000..d0a812b --- /dev/null +++ b/sdl3/guardian.scm @@ -0,0 +1,30 @@ +;;; guile-sdl3 -- Scheme bindings for SDL3 +;;; Copyright © 2024 David Thompson +;;; +;;; Licensed under the Apache License, Version 2.0 (the "License"); +;;; you may not use this file except in compliance with the License. +;;; You may obtain a copy of the License at +;;; +;;; http://www.apache.org/licenses/LICENSE-2.0 +;;; +;;; Unless required by applicable law or agreed to in writing, software +;;; distributed under the License is distributed on an "AS IS" BASIS, +;;; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +;;; See the License for the specific language governing permissions and +;;; limitations under the License. + +;;; Commentary: +;; +;; SDL3 foreign object guardian. +;; +;;; Code: + +(define-module (sdl3 guardian) + #:export (sdl-guardian + sdl-protect)) + +(define sdl-guardian (make-guardian)) + +(define (sdl-protect obj) + (sdl-guardian obj) + obj) diff --git a/sdl3/video.scm b/sdl3/video.scm new file mode 100644 index 0000000..35a37c8 --- /dev/null +++ b/sdl3/video.scm @@ -0,0 +1,85 @@ +;;; guile-sdl3 -- Scheme bindings for SDL3 +;;; Copyright © 2024 David Thompson +;;; +;;; Licensed under the Apache License, Version 2.0 (the "License"); +;;; you may not use this file except in compliance with the License. +;;; You may obtain a copy of the License at +;;; +;;; http://www.apache.org/licenses/LICENSE-2.0 +;;; +;;; Unless required by applicable law or agreed to in writing, software +;;; distributed under the License is distributed on an "AS IS" BASIS, +;;; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +;;; See the License for the specific language governing permissions and +;;; limitations under the License. + +;;; Commentary: +;; +;; SDL3 display and window management. +;; +;;; Code: + +(define-module (sdl3 video) + #:use-module (rnrs bytevectors) + #:use-module (sdl3 bindings video) + #:use-module (sdl3 errors) + #:use-module (system foreign) + #:export (make-window + destroy-window! + window-size-in-pixels) + #:re-export (window? + window-destroyed?)) + +(define* (make-window title width height #:key + opengl? + vulkan? + metal? + (shown? #t) + fullscreen? + borderless? + transparent? + resizable? + (focusable? #t) + high-pixel-density? + always-on-top? + utility?) + "Open a window with the specified @var{title} and dimensions +@var{width} by @var{height} pixels and return a handle to that window." + (wrap-window + (sdl-assert-non-null + 'make-window + (SDL_CreateWindow (string->pointer title) + width height + (logior + (if opengl? SDL_WINDOW_OPENGL 0) + (if vulkan? SDL_WINDOW_VULKAN 0) + (if metal? SDL_WINDOW_METAL 0) + (if fullscreen? SDL_WINDOW_FULLSCREEN 0) + (if shown? 0 SDL_WINDOW_HIDDEN) + (if borderless? SDL_WINDOW_BORDERLESS 0) + (if transparent? SDL_WINDOW_TRANSPARENT 0) + (if resizable? SDL_WINDOW_RESIZABLE 0) + (if focusable? 0 SDL_WINDOW_NOT_FOCUSABLE) + (if high-pixel-density? SDL_WINDOW_HIGH_PIXEL_DENSITY 0) + (if always-on-top? SDL_WINDOW_ALWAYS_ON_TOP 0) + (if utility? SDL_WINDOW_UTILITY 0)))))) + +;; FIXME: SDL_DestroyWindow recursively destroys child windows. Do we +;; need to keep track of those in Scheme, then? +(define (destroy-window! window) + "Close @var{window} and make handle unusable for further window +management calls." + (unless (window-destroyed? window) + (SDL_DestroyWindow (unwrap-window window)) + (set-window-destroyed! window #t))) + +(define (window-size-in-pixels window) + (let* ((size (sizeof int)) + (bv (make-bytevector (* size 2)))) + (sdl-assert + 'window-size-in-pixels + (SDL_GetWindowSizeInPixels (unwrap-window window) + (bytevector->pointer bv) + (bytevector->pointer bv size))) + (values (bytevector-sint-ref bv 0 (native-endianness) size) + (bytevector-sint-ref bv size (native-endianness) size)))) -- cgit v1.2.3