diff --git a/lib/sdl3/SDL/README.md b/lib/sdl3/SDL/README.md index 4222ba1..3ca7de0 100644 --- a/lib/sdl3/SDL/README.md +++ b/lib/sdl3/SDL/README.md @@ -9,7 +9,7 @@ This is a port of [SDL](https://libsdl.org/) to the Zig build system, packaged f ## Usage -Requires Zig 0.14.0 or 0.15.0-dev (master). +Requires Zig 0.14.1 or 0.15.0-dev (master). ```sh zig fetch --save git+https://github.com/castholm/SDL.git @@ -21,6 +21,7 @@ const sdl_dep = b.dependency("sdl", .{ .optimize = optimize, //.preferred_linkage = .static, //.strip = null, + //.sanitize_c = null, //.pic = null, //.lto = null, //.emscripten_pthreads = false, @@ -79,7 +80,7 @@ When building for non-native macOS targets (for example for x86-64 from an AArch ```sh sysroot_path=$(xcrun --sdk macosx --show-sdk-path) -zig build -Dtarget=x86_64-macos-none --sysroot "$sysroot_path" +zig build -Dtarget=x86_64-macos --sysroot "$sysroot_path" ``` ### Emscripten (web) @@ -103,7 +104,7 @@ When building for Emscripten, you need to provide a path to the Emscripten sysro ```sh cache_path=$(em-config CACHE) sysroot_path="$cache_path/sysroot" -zig build -Dtarget=wasm32-emscripten-musl --sysroot "$sysroot_path" +zig build -Dtarget=wasm32-emscripten --sysroot "$sysroot_path" ``` Depending on the state of your Emscripten cache, you might need to run `embuilder build sysroot` to ensure that the Emscripten sysroot is built before you run `zig build`. diff --git a/lib/sdl3/SDL/build.zig b/lib/sdl3/SDL/build.zig index 97e50dd..50fc25c 100644 --- a/lib/sdl3/SDL/build.zig +++ b/lib/sdl3/SDL/build.zig @@ -3,15 +3,15 @@ const std = @import("std"); -pub const version: std.SemanticVersion = .{ .major = 3, .minor = 2, .patch = 10 }; +pub const version: std.SemanticVersion = .{ .major = 3, .minor = 2, .patch = 16 }; const formatted_version = std.fmt.comptimePrint("SDL3-{}", .{version}); -pub const vendor_info = "https://github.com/castholm/SDL 0.2.1"; +pub const vendor_info = "https://github.com/castholm/SDL 0.2.4"; pub const revision = formatted_version ++ " (" ++ vendor_info ++ ")"; pub fn build(b: *std.Build) void { const target = b.standardTargetOptions(.{}); const optimize = b.standardOptimizeOption(.{}); - var preferred_linkage: std.builtin.LinkMode = b.option( + const preferred_linkage = b.option( std.builtin.LinkMode, "preferred_linkage", "Prefer building statically or dynamically linked libraries (default: static)", @@ -20,23 +20,50 @@ pub fn build(b: *std.Build) void { "preferred_link_mode", "Deprecated; use 'preferred_linkage' instead", ) orelse .static; - - preferred_linkage = .dynamic; const strip = b.option( bool, "strip", "Strip debug symbols (default: varies)", ); + const sanitize_c = b.option( + enum { off, trap, full }, // TODO: Change to std.zig.SanitizeC after 0.15 + "sanitize_c", + "Detect C undefined behavior (default: varies)", + ); + const legacy_sanitize_c_field = @FieldType(std.Build.Module.CreateOptions, "sanitize_c") == ?bool; + const resolved_sanitize_c = if (sanitize_c) |x| switch (legacy_sanitize_c_field) { + true => switch (x) { + .off => false, + .trap, .full => true, + }, + false => @as(std.zig.SanitizeC, switch (x) { + .off => .off, + .trap => .trap, + .full => .full, + }), + } else null; const pic = b.option( bool, "pic", "Produce position-independent code (default: varies)", ); const lto = b.option( - bool, + enum { true, false, none, full, thin }, // TODO: Change to std.zig.LtoMode after 0.15 "lto", "Perform link time optimization (default: varies)", ); + const legacy_lto_field = !@hasField(std.Build.Step.Compile, "lto"); + const resolved_lto = if (lto) |x| switch (legacy_lto_field) { + true => switch (x) { + .false, .none => false, + .true, .full, .thin => true, + }, + false => @as(std.zig.LtoMode, switch (x) { + .false, .none => .none, + .true, .full => .full, + .thin => .thin, + }), + } else null; const emscripten_pthreads = b.option( bool, "emscripten_pthreads", @@ -52,11 +79,12 @@ pub fn build(b: *std.Build) void { var linux = false; var linux_deps_values: ?LinuxDepsValues = null; var macos = false; - var macos_system_include_path: ?std.Build.LazyPath = null; - var macos_system_framework_path: ?std.Build.LazyPath = null; - var macos_library_path: ?std.Build.LazyPath = null; var emscripten = false; - var emscripten_system_include_path: ?std.Build.LazyPath = null; + var system_include_path: ?std.Build.LazyPath = null; + var system_framework_path: ?std.Build.LazyPath = null; + var library_path: ?std.Build.LazyPath = null; + var glibc = false; + var musl = false; switch (target.result.os.tag) { .windows => { windows = true; @@ -66,13 +94,15 @@ pub fn build(b: *std.Build) void { if (b.lazyImport(@This(), "sdl_linux_deps")) |build_zig| { linux_deps_values = LinuxDepsValues.fromBuildZig(b, build_zig); } + glibc = target.result.abi.isGnu(); + musl = target.result.abi.isMusl(); }, .macos => { macos = true; if (b.sysroot) |sysroot| { - macos_system_include_path = .{ .cwd_relative = b.pathJoin(&.{ sysroot, "usr/include" }) }; - macos_system_framework_path = .{ .cwd_relative = b.pathJoin(&.{ sysroot, "System/Library/Frameworks" }) }; - macos_library_path = .{ .cwd_relative = "/usr/lib" }; // ??? + system_include_path = .{ .cwd_relative = b.pathJoin(&.{ sysroot, "usr/include" }) }; + system_framework_path = .{ .cwd_relative = b.pathJoin(&.{ sysroot, "System/Library/Frameworks" }) }; + library_path = .{ .cwd_relative = "/usr/lib" }; // ??? } else if (!target.query.isNative()) { std.log.err("'--sysroot' is required when building SDL for non-native macOS targets", .{}); std.process.exit(1); @@ -81,7 +111,7 @@ pub fn build(b: *std.Build) void { .emscripten => { emscripten = true; if (b.sysroot) |sysroot| { - emscripten_system_include_path = .{ .cwd_relative = b.pathJoin(&.{ sysroot, "include" }) }; + system_include_path = .{ .cwd_relative = b.pathJoin(&.{ sysroot, "include" }) }; } else { std.log.err("'--sysroot' is required when building SDL for Emscripten", .{}); std.process.exit(1); @@ -147,8 +177,8 @@ pub fn build(b: *std.Build) void { .HAVE_WCSTOL = windows or linux or macos or emscripten, .HAVE_STRLEN = windows or linux or macos or emscripten, .HAVE_STRNLEN = windows or linux or macos or emscripten, - .HAVE_STRLCPY = macos or emscripten, - .HAVE_STRLCAT = macos or emscripten, + .HAVE_STRLCPY = linux and musl or macos or emscripten, + .HAVE_STRLCAT = linux and musl or macos or emscripten, .HAVE_STRPBRK = windows or linux or macos or emscripten, .HAVE__STRREV = windows, .HAVE_INDEX = linux or macos or emscripten, @@ -199,10 +229,10 @@ pub fn build(b: *std.Build) void { .HAVE_FMOD = windows or linux or macos or emscripten, .HAVE_FMODF = windows or linux or macos or emscripten, .HAVE_ISINF = windows or linux or macos or emscripten, - .HAVE_ISINFF = linux or emscripten, + .HAVE_ISINFF = linux and !musl or emscripten, .HAVE_ISINF_FLOAT_MACRO = windows or linux or macos or emscripten, .HAVE_ISNAN = windows or linux or macos or emscripten, - .HAVE_ISNANF = linux or emscripten, + .HAVE_ISNANF = linux and !musl or emscripten, .HAVE_ISNAN_FLOAT_MACRO = windows or linux or macos or emscripten, .HAVE_LOG = windows or linux or macos or emscripten, .HAVE_LOGF = windows or linux or macos or emscripten, @@ -227,9 +257,9 @@ pub fn build(b: *std.Build) void { .HAVE_TRUNC = windows or linux or macos or emscripten, .HAVE_TRUNCF = windows or linux or macos or emscripten, .HAVE__FSEEKI64 = windows, - .HAVE_FOPEN64 = windows or linux or emscripten, + .HAVE_FOPEN64 = windows or linux and !musl or emscripten, .HAVE_FSEEKO = windows or linux or macos or emscripten, - .HAVE_FSEEKO64 = windows or linux or emscripten, + .HAVE_FSEEKO64 = windows or linux and !musl or emscripten, .HAVE_MEMFD_CREATE = linux, .HAVE_POSIX_FALLOCATE = linux or emscripten, .HAVE_SIGACTION = linux or macos or emscripten, @@ -543,10 +573,11 @@ pub fn build(b: *std.Build) void { .optimize = optimize, .link_libc = true, .strip = strip, + .sanitize_c = resolved_sanitize_c, .pic = pic, }); const sdl_lib = b.addLibrary(.{ - .linkage = .dynamic, //if (emscripten) .static else preferred_linkage, + .linkage = if (emscripten) .static else preferred_linkage, .name = "SDL3", .root_module = sdl_mod, .version = .{ @@ -556,7 +587,11 @@ pub fn build(b: *std.Build) void { }, .use_llvm = if (emscripten) true else null, }); - sdl_lib.want_lto = lto; + if (legacy_lto_field) { + sdl_lib.want_lto = resolved_lto; + } else { + sdl_lib.lto = resolved_lto; + } sdl_mod.addCMacro("USING_GENERATED_CONFIG_H", "1"); sdl_mod.addCMacro("SDL_BUILD_MAJOR_VERSION", std.fmt.comptimePrint("{}", .{version.major})); @@ -583,25 +618,26 @@ pub fn build(b: *std.Build) void { if (linux_deps_values) |deps_values| { sdl_mod.addIncludePath(deps_values.dependency.path("src")); sdl_mod.addSystemIncludePath(deps_values.dependency.path("include")); - if (target.result.cpu.arch == .x86_64 and target.result.abi.isGnu()) { + // Currently, the only difference between these two sets of target-specific headers + // is that the x86_64 one defines G_VA_COPY_AS_ARRAY and the aarch64 one doesn't. + if (target.result.cpu.arch == .x86_64 and glibc) { sdl_mod.addSystemIncludePath(deps_values.dependency.path("include/x86_64-linux-gnu")); } - if (target.result.cpu.arch == .aarch64 and target.result.abi.isGnu()) { + // TODO: musl targets can piggyback off of the aarch64-linux-gnu headers for now because + // they are identical to their x86_64-linux-musl and aarch64-linux-musl equivalents. + if (target.result.cpu.arch == .aarch64 or target.result.cpu.arch == .x86_64 and musl) { sdl_mod.addSystemIncludePath(deps_values.dependency.path("include/aarch64-linux-gnu")); } } - if (macos_system_include_path) |path| { + if (system_include_path) |path| { sdl_mod.addSystemIncludePath(path); } - if (macos_system_framework_path) |path| { + if (system_framework_path) |path| { sdl_mod.addSystemFrameworkPath(path); } - if (macos_library_path) |path| { + if (library_path) |path| { sdl_mod.addLibraryPath(path); } - if (emscripten_system_include_path) |path| { - sdl_mod.addSystemIncludePath(path); - } var sdl_c_flags: std.BoundedArray([]const u8, common_c_flags.len + 3) = .{}; sdl_c_flags.appendSliceAssumeCapacity(&common_c_flags); @@ -804,6 +840,7 @@ pub fn build(b: *std.Build) void { .optimize = optimize, .link_libc = true, .strip = strip, + .sanitize_c = resolved_sanitize_c, .pic = pic, }); const sdl_uclibc_lib = b.addLibrary(.{ @@ -811,7 +848,11 @@ pub fn build(b: *std.Build) void { .name = "SDL_uclib", .root_module = sdl_uclibc_mod, }); - sdl_uclibc_lib.want_lto = lto; + if (legacy_lto_field) { + sdl_uclibc_lib.want_lto = resolved_lto; + } else { + sdl_uclibc_lib.lto = resolved_lto; + } sdl_uclibc_mod.addCMacro("USING_GENERATED_CONFIG_H", "1"); @@ -1290,6 +1331,7 @@ pub fn build(b: *std.Build) void { .optimize = optimize, .link_libc = true, .strip = strip, + .sanitize_c = resolved_sanitize_c, .pic = pic, }); const sdl_test_lib = b.addLibrary(.{ @@ -1298,12 +1340,16 @@ pub fn build(b: *std.Build) void { .root_module = sdl_test_mod, .use_llvm = if (emscripten) true else null, }); - sdl_test_lib.want_lto = lto; + if (legacy_lto_field) { + sdl_test_lib.want_lto = resolved_lto; + } else { + sdl_test_lib.lto = resolved_lto; + } sdl_test_mod.addConfigHeader(build_config_h); sdl_test_mod.addConfigHeader(revision_h); sdl_test_mod.addIncludePath(b.path("include")); - if (emscripten_system_include_path) |path| { + if (system_include_path) |path| { sdl_test_mod.addSystemIncludePath(path); } diff --git a/lib/sdl3/SDL/build.zig.zon b/lib/sdl3/SDL/build.zig.zon index 53c8db7..7be8c1b 100644 --- a/lib/sdl3/SDL/build.zig.zon +++ b/lib/sdl3/SDL/build.zig.zon @@ -3,9 +3,9 @@ .{ .name = .sdl, - .version = "0.2.1+3.2.10", + .version = "0.2.4+3.2.16", .fingerprint = 0xec638ccbf427e2ee, - .minimum_zig_version = "0.14.0", + .minimum_zig_version = "0.14.1", .dependencies = .{ .sdl_linux_deps = .{ .url = "git+https://github.com/castholm/SDL_linux_deps.git#085212f286621835f2638cb0cfff078fe515341a", diff --git a/lib/sdl3/SDL/include/SDL3/SDL.h b/lib/sdl3/SDL/include/SDL3/SDL.h index 9d21688..ed1b324 100644 --- a/lib/sdl3/SDL/include/SDL3/SDL.h +++ b/lib/sdl3/SDL/include/SDL3/SDL.h @@ -20,7 +20,7 @@ */ /** - * Main include header for the SDL library, version 3.2.10 + * Main include header for the SDL library, version 3.2.16 * * It is almost always best to include just this one header instead of * picking out individual headers included here. There are exceptions to diff --git a/lib/sdl3/SDL/include/SDL3/SDL_events.h b/lib/sdl3/SDL/include/SDL3/SDL_events.h index 56a2194..d267f05 100644 --- a/lib/sdl3/SDL/include/SDL3/SDL_events.h +++ b/lib/sdl3/SDL/include/SDL3/SDL_events.h @@ -492,6 +492,8 @@ typedef struct SDL_MouseWheelEvent SDL_MouseWheelDirection direction; /**< Set to one of the SDL_MOUSEWHEEL_* defines. When FLIPPED the values in X and Y will be opposite. Multiply by -1 to change them back */ float mouse_x; /**< X coordinate, relative to window */ float mouse_y; /**< Y coordinate, relative to window */ + Sint32 integer_x; /**< The amount scrolled horizontally, accumulated to whole scroll "ticks" (added in 3.2.12) */ + Sint32 integer_y; /**< The amount scrolled vertically, accumulated to whole scroll "ticks" (added in 3.2.12) */ } SDL_MouseWheelEvent; /** diff --git a/lib/sdl3/SDL/include/SDL3/SDL_gpu.h b/lib/sdl3/SDL/include/SDL3/SDL_gpu.h index ffddb80..b616619 100644 --- a/lib/sdl3/SDL/include/SDL3/SDL_gpu.h +++ b/lib/sdl3/SDL/include/SDL3/SDL_gpu.h @@ -2231,7 +2231,7 @@ extern SDL_DECLSPEC const char * SDLCALL SDL_GetGPUDriver(int index); /** * Returns the name of the backend used to create this GPU context. - + * * \param device a GPU context to query. * \returns the name of the device's driver, or NULL on error. * @@ -2467,9 +2467,9 @@ extern SDL_DECLSPEC SDL_GPUShader * SDLCALL SDL_CreateGPUShader( * - `SDL_PROP_GPU_TEXTURE_CREATE_D3D12_CLEAR_DEPTH_FLOAT`: (Direct3D 12 only) * if the texture usage is SDL_GPU_TEXTUREUSAGE_DEPTH_STENCIL_TARGET, clear * the texture to a depth of this value. Defaults to zero. - * - `SDL_PROP_GPU_TEXTURE_CREATE_D3D12_CLEAR_STENCIL_UINT8`: (Direct3D 12 + * - `SDL_PROP_GPU_TEXTURE_CREATE_D3D12_CLEAR_STENCIL_NUMBER`: (Direct3D 12 * only) if the texture usage is SDL_GPU_TEXTUREUSAGE_DEPTH_STENCIL_TARGET, - * clear the texture to a stencil of this value. Defaults to zero. + * clear the texture to a stencil of this Uint8 value. Defaults to zero. * - `SDL_PROP_GPU_TEXTURE_CREATE_NAME_STRING`: a name that can be displayed * in debugging tools. * @@ -2495,13 +2495,13 @@ extern SDL_DECLSPEC SDL_GPUTexture * SDLCALL SDL_CreateGPUTexture( SDL_GPUDevice *device, const SDL_GPUTextureCreateInfo *createinfo); -#define SDL_PROP_GPU_TEXTURE_CREATE_D3D12_CLEAR_R_FLOAT "SDL.gpu.texture.create.d3d12.clear.r" -#define SDL_PROP_GPU_TEXTURE_CREATE_D3D12_CLEAR_G_FLOAT "SDL.gpu.texture.create.d3d12.clear.g" -#define SDL_PROP_GPU_TEXTURE_CREATE_D3D12_CLEAR_B_FLOAT "SDL.gpu.texture.create.d3d12.clear.b" -#define SDL_PROP_GPU_TEXTURE_CREATE_D3D12_CLEAR_A_FLOAT "SDL.gpu.texture.create.d3d12.clear.a" -#define SDL_PROP_GPU_TEXTURE_CREATE_D3D12_CLEAR_DEPTH_FLOAT "SDL.gpu.texture.create.d3d12.clear.depth" -#define SDL_PROP_GPU_TEXTURE_CREATE_D3D12_CLEAR_STENCIL_UINT8 "SDL.gpu.texture.create.d3d12.clear.stencil" -#define SDL_PROP_GPU_TEXTURE_CREATE_NAME_STRING "SDL.gpu.texture.create.name" +#define SDL_PROP_GPU_TEXTURE_CREATE_D3D12_CLEAR_R_FLOAT "SDL.gpu.texture.create.d3d12.clear.r" +#define SDL_PROP_GPU_TEXTURE_CREATE_D3D12_CLEAR_G_FLOAT "SDL.gpu.texture.create.d3d12.clear.g" +#define SDL_PROP_GPU_TEXTURE_CREATE_D3D12_CLEAR_B_FLOAT "SDL.gpu.texture.create.d3d12.clear.b" +#define SDL_PROP_GPU_TEXTURE_CREATE_D3D12_CLEAR_A_FLOAT "SDL.gpu.texture.create.d3d12.clear.a" +#define SDL_PROP_GPU_TEXTURE_CREATE_D3D12_CLEAR_DEPTH_FLOAT "SDL.gpu.texture.create.d3d12.clear.depth" +#define SDL_PROP_GPU_TEXTURE_CREATE_D3D12_CLEAR_STENCIL_NUMBER "SDL.gpu.texture.create.d3d12.clear.stencil" +#define SDL_PROP_GPU_TEXTURE_CREATE_NAME_STRING "SDL.gpu.texture.create.name" /** * Creates a buffer object to be used in graphics or compute workflows. @@ -3775,7 +3775,7 @@ extern SDL_DECLSPEC void SDLCALL SDL_ReleaseWindowFromGPUDevice( * supported via SDL_WindowSupportsGPUPresentMode / * SDL_WindowSupportsGPUSwapchainComposition prior to calling this function. * - * SDL_GPU_PRESENTMODE_VSYNC and SDL_GPU_SWAPCHAINCOMPOSITION_SDR are always + * SDL_GPU_PRESENTMODE_VSYNC with SDL_GPU_SWAPCHAINCOMPOSITION_SDR are always * supported. * * \param device a GPU context. diff --git a/lib/sdl3/SDL/include/SDL3/SDL_hints.h b/lib/sdl3/SDL/include/SDL3/SDL_hints.h index 9c8ad3f..a081535 100644 --- a/lib/sdl3/SDL/include/SDL3/SDL_hints.h +++ b/lib/sdl3/SDL/include/SDL3/SDL_hints.h @@ -1074,8 +1074,8 @@ extern "C" { * * By default, SDL will try all available GPU backends in a reasonable order * until it finds one that can work, but this hint allows the app or user to - * force a specific target, such as "direct3d11" if, say, your hardware - * supports D3D12 but want to try using D3D11 instead. + * force a specific target, such as "direct3d12" if, say, your hardware + * supports Vulkan but you want to try using D3D12 instead. * * This hint should be set before any GPU functions are called. * @@ -2026,8 +2026,8 @@ extern "C" { * * The variable can be set to the following values: * - * - "0": RAWINPUT drivers are not used. - * - "1": RAWINPUT drivers are used. (default) + * - "0": RAWINPUT drivers are not used. (default) + * - "1": RAWINPUT drivers are used. * * This hint should be set before SDL is initialized. * diff --git a/lib/sdl3/SDL/include/SDL3/SDL_init.h b/lib/sdl3/SDL/include/SDL3/SDL_init.h index adf0de8..27ebe4b 100644 --- a/lib/sdl3/SDL/include/SDL3/SDL_init.h +++ b/lib/sdl3/SDL/include/SDL3/SDL_init.h @@ -79,7 +79,7 @@ typedef Uint32 SDL_InitFlags; #define SDL_INIT_AUDIO 0x00000010u /**< `SDL_INIT_AUDIO` implies `SDL_INIT_EVENTS` */ #define SDL_INIT_VIDEO 0x00000020u /**< `SDL_INIT_VIDEO` implies `SDL_INIT_EVENTS`, should be initialized on the main thread */ -#define SDL_INIT_JOYSTICK 0x00000200u /**< `SDL_INIT_JOYSTICK` implies `SDL_INIT_EVENTS`, should be initialized on the same thread as SDL_INIT_VIDEO on Windows if you don't set SDL_HINT_JOYSTICK_THREAD */ +#define SDL_INIT_JOYSTICK 0x00000200u /**< `SDL_INIT_JOYSTICK` implies `SDL_INIT_EVENTS` */ #define SDL_INIT_HAPTIC 0x00001000u #define SDL_INIT_GAMEPAD 0x00002000u /**< `SDL_INIT_GAMEPAD` implies `SDL_INIT_JOYSTICK` */ #define SDL_INIT_EVENTS 0x00004000u diff --git a/lib/sdl3/SDL/include/SDL3/SDL_pixels.h b/lib/sdl3/SDL/include/SDL3/SDL_pixels.h index 4127ac0..39596c1 100644 --- a/lib/sdl3/SDL/include/SDL3/SDL_pixels.h +++ b/lib/sdl3/SDL/include/SDL3/SDL_pixels.h @@ -517,7 +517,7 @@ typedef enum SDL_PackedLayout * ABGR32, define a platform-independent encoding into bytes in the order * specified. For example, in RGB24 data, each pixel is encoded in 3 bytes * (red, green, blue) in that order, and in ABGR32 data, each pixel is - * encoded in 4 bytes alpha, blue, green, red) in that order. Use these + * encoded in 4 bytes (alpha, blue, green, red) in that order. Use these * names if the property of a format that is important to you is the order * of the bytes in memory or on disk. * - Names with a bit count per component, such as ARGB8888 and XRGB1555, are diff --git a/lib/sdl3/SDL/include/SDL3/SDL_render.h b/lib/sdl3/SDL/include/SDL3/SDL_render.h index 3352545..c9d184c 100644 --- a/lib/sdl3/SDL/include/SDL3/SDL_render.h +++ b/lib/sdl3/SDL/include/SDL3/SDL_render.h @@ -1607,8 +1607,7 @@ extern SDL_DECLSPEC bool SDLCALL SDL_GetRenderViewport(SDL_Renderer *renderer, S * Return whether an explicit rectangle was set as the viewport. * * This is useful if you're saving and restoring the viewport and want to know - * whether you should restore a specific rectangle or NULL. Note that the - * viewport is always reset when changing rendering targets. + * whether you should restore a specific rectangle or NULL. * * Each render target has its own viewport. This function checks the viewport * for the current render target. diff --git a/lib/sdl3/SDL/include/SDL3/SDL_stdinc.h b/lib/sdl3/SDL/include/SDL3/SDL_stdinc.h index b2728da..7df253f 100644 --- a/lib/sdl3/SDL/include/SDL3/SDL_stdinc.h +++ b/lib/sdl3/SDL/include/SDL3/SDL_stdinc.h @@ -4656,7 +4656,7 @@ extern SDL_DECLSPEC float SDLCALL SDL_atanf(float x); * * Domain: `-INF <= x <= INF`, `-INF <= y <= INF` * - * Range: `-Pi/2 <= y <= Pi/2` + * Range: `-Pi <= y <= Pi` * * This function operates on double-precision floating point values, use * SDL_atan2f for single-precision floats. @@ -4692,7 +4692,7 @@ extern SDL_DECLSPEC double SDLCALL SDL_atan2(double y, double x); * * Domain: `-INF <= x <= INF`, `-INF <= y <= INF` * - * Range: `-Pi/2 <= y <= Pi/2` + * Range: `-Pi <= y <= Pi` * * This function operates on single-precision floating point values, use * SDL_atan2 for double-precision floats. @@ -5974,8 +5974,12 @@ size_t wcslcpy(wchar_t *dst, const wchar_t *src, size_t size); size_t wcslcat(wchar_t *dst, const wchar_t *src, size_t size); #endif +#ifndef _WIN32 /* strdup is not ANSI but POSIX, and its prototype might be hidden... */ +/* not for windows: might conflict with string.h where strdup may have + * dllimport attribute: https://github.com/libsdl-org/SDL/issues/12948 */ char *strdup(const char *str); +#endif /* Starting LLVM 16, the analyser errors out if these functions do not have their prototype defined (clang-diagnostic-implicit-function-declaration) */ diff --git a/lib/sdl3/SDL/include/SDL3/SDL_surface.h b/lib/sdl3/SDL/include/SDL3/SDL_surface.h index 7bff7cf..15fce04 100644 --- a/lib/sdl3/SDL/include/SDL3/SDL_surface.h +++ b/lib/sdl3/SDL/include/SDL3/SDL_surface.h @@ -1135,9 +1135,6 @@ extern SDL_DECLSPEC bool SDLCALL SDL_FillSurfaceRects(SDL_Surface *dst, const SD * If either `srcrect` or `dstrect` are NULL, the entire surface (`src` or * `dst`) is copied while ensuring clipping to `dst->clip_rect`. * - * The final blit rectangles are saved in `srcrect` and `dstrect` after all - * clipping is performed. - * * The blit function should not be called on a locked surface. * * The blit semantics for surfaces with and without blending and colorkey are @@ -1282,10 +1279,11 @@ extern SDL_DECLSPEC bool SDLCALL SDL_BlitSurfaceUncheckedScaled(SDL_Surface *src * * \param src the SDL_Surface structure to be copied from. * \param srcrect the SDL_Rect structure representing the rectangle to be - * copied, may not be NULL. + * copied, or NULL to copy the entire surface. * \param dst the SDL_Surface structure that is the blit target. * \param dstrect the SDL_Rect structure representing the target rectangle in - * the destination surface, may not be NULL. + * the destination surface, or NULL to fill the entire + * destination surface. * \param scaleMode the SDL_ScaleMode to be used. * \returns true on success or false on failure; call SDL_GetError() for more * information. diff --git a/lib/sdl3/SDL/include/SDL3/SDL_version.h b/lib/sdl3/SDL/include/SDL3/SDL_version.h index a3b6ae8..435b3f9 100644 --- a/lib/sdl3/SDL/include/SDL3/SDL_version.h +++ b/lib/sdl3/SDL/include/SDL3/SDL_version.h @@ -62,7 +62,7 @@ extern "C" { * * \since This macro is available since SDL 3.2.0. */ -#define SDL_MICRO_VERSION 10 +#define SDL_MICRO_VERSION 16 /** * This macro turns the version numbers into a numeric value. diff --git a/lib/sdl3/SDL/include/SDL3/SDL_video.h b/lib/sdl3/SDL/include/SDL3/SDL_video.h index a7afc32..877b9ad 100644 --- a/lib/sdl3/SDL/include/SDL3/SDL_video.h +++ b/lib/sdl3/SDL/include/SDL3/SDL_video.h @@ -426,10 +426,10 @@ typedef SDL_EGLint *(SDLCALL *SDL_EGLIntArrayCallback)(void *userdata, SDL_EGLDi */ typedef enum SDL_GLAttr { - SDL_GL_RED_SIZE, /**< the minimum number of bits for the red channel of the color buffer; defaults to 3. */ - SDL_GL_GREEN_SIZE, /**< the minimum number of bits for the green channel of the color buffer; defaults to 3. */ - SDL_GL_BLUE_SIZE, /**< the minimum number of bits for the blue channel of the color buffer; defaults to 2. */ - SDL_GL_ALPHA_SIZE, /**< the minimum number of bits for the alpha channel of the color buffer; defaults to 0. */ + SDL_GL_RED_SIZE, /**< the minimum number of bits for the red channel of the color buffer; defaults to 8. */ + SDL_GL_GREEN_SIZE, /**< the minimum number of bits for the green channel of the color buffer; defaults to 8. */ + SDL_GL_BLUE_SIZE, /**< the minimum number of bits for the blue channel of the color buffer; defaults to 8. */ + SDL_GL_ALPHA_SIZE, /**< the minimum number of bits for the alpha channel of the color buffer; defaults to 8. */ SDL_GL_BUFFER_SIZE, /**< the minimum number of bits for frame buffer size; defaults to 0. */ SDL_GL_DOUBLEBUFFER, /**< whether the output is single or double buffered; defaults to double buffering on. */ SDL_GL_DEPTH_SIZE, /**< the minimum number of bits in the depth buffer; defaults to 16. */ @@ -1041,6 +1041,10 @@ extern SDL_DECLSPEC SDL_Window ** SDLCALL SDL_GetWindows(int *count); /** * Create a window with the specified dimensions and flags. * + * The window size is a request and may be different than expected based on + * the desktop layout and window manager policies. Your application should be + * prepared to handle a window of any size. + * * `flags` may be any of the following OR'd together: * * - `SDL_WINDOW_FULLSCREEN`: fullscreen window at desktop resolution @@ -1127,6 +1131,10 @@ extern SDL_DECLSPEC SDL_Window * SDLCALL SDL_CreateWindow(const char *title, int /** * Create a child popup window of the specified parent window. * + * The window size is a request and may be different than expected based on + * the desktop layout and window manager policies. Your application should be + * prepared to handle a window of any size. + * * The flags parameter **must** contain at least one of the following: * * - `SDL_WINDOW_TOOLTIP`: The popup window is a tooltip and will not pass any @@ -1189,6 +1197,10 @@ extern SDL_DECLSPEC SDL_Window * SDLCALL SDL_CreatePopupWindow(SDL_Window *paren /** * Create a window with the specified properties. * + * The window size is a request and may be different than expected based on + * the desktop layout and window manager policies. Your application should be + * prepared to handle a window of any size. + * * These are the supported properties: * * - `SDL_PROP_WINDOW_CREATE_ALWAYS_ON_TOP_BOOLEAN`: true if the window should diff --git a/lib/sdl3/SDL/include/SDL3/clangParserLog.log b/lib/sdl3/SDL/include/SDL3/clangParserLog.log deleted file mode 100644 index c2fc67b..0000000 --- a/lib/sdl3/SDL/include/SDL3/clangParserLog.log +++ /dev/null @@ -1,8038 +0,0 @@ -2025-05-19 19:52:57,465 - cheader2json.cheader_reader - INFO - Clang successfully parsed the C header files! -2025-05-19 19:52:57,466 - cheader2json.cheader_reader - DEBUG - The clang parser result: -{ - "0": { - "brief_comment": null, - "end_line": 307, - "kind": "MACRO_DEFINITION", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_gpu_h_", - "start_line": 307, - "type": "Invalid", - "value": "SDL_gpu_h_" - }, - "1": { - "brief_comment": null, - "end_line": 309, - "kind": "INCLUSION_DIRECTIVE", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL3/SDL_stdinc.h", - "start_line": 309, - "type": "Invalid" - }, - "2": { - "brief_comment": null, - "end_line": 310, - "kind": "INCLUSION_DIRECTIVE", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL3/SDL_pixels.h", - "start_line": 310, - "type": "Invalid" - }, - "3": { - "brief_comment": null, - "end_line": 311, - "kind": "INCLUSION_DIRECTIVE", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL3/SDL_properties.h", - "start_line": 311, - "type": "Invalid" - }, - "4": { - "brief_comment": null, - "end_line": 312, - "kind": "INCLUSION_DIRECTIVE", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL3/SDL_rect.h", - "start_line": 312, - "type": "Invalid" - }, - "5": { - "brief_comment": null, - "end_line": 313, - "kind": "INCLUSION_DIRECTIVE", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL3/SDL_surface.h", - "start_line": 313, - "type": "Invalid" - }, - "6": { - "brief_comment": null, - "end_line": 314, - "kind": "INCLUSION_DIRECTIVE", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL3/SDL_video.h", - "start_line": 314, - "type": "Invalid" - }, - "7": { - "brief_comment": null, - "end_line": 316, - "kind": "INCLUSION_DIRECTIVE", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL3/SDL_begin_code.h", - "start_line": 316, - "type": "Invalid" - }, - "8": { - "brief_comment": null, - "end_line": 823, - "kind": "MACRO_DEFINITION", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_TEXTUREUSAGE_SAMPLER", - "start_line": 823, - "type": "Invalid", - "value": ")" - }, - "9": { - "brief_comment": null, - "end_line": 824, - "kind": "MACRO_DEFINITION", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_TEXTUREUSAGE_COLOR_TARGET", - "start_line": 824, - "type": "Invalid", - "value": ")" - }, - "10": { - "brief_comment": null, - "end_line": 825, - "kind": "MACRO_DEFINITION", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_TEXTUREUSAGE_DEPTH_STENCIL_TARGET", - "start_line": 825, - "type": "Invalid", - "value": ")" - }, - "11": { - "brief_comment": null, - "end_line": 826, - "kind": "MACRO_DEFINITION", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_TEXTUREUSAGE_GRAPHICS_STORAGE_READ", - "start_line": 826, - "type": "Invalid", - "value": ")" - }, - "12": { - "brief_comment": null, - "end_line": 827, - "kind": "MACRO_DEFINITION", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_TEXTUREUSAGE_COMPUTE_STORAGE_READ", - "start_line": 827, - "type": "Invalid", - "value": ")" - }, - "13": { - "brief_comment": null, - "end_line": 828, - "kind": "MACRO_DEFINITION", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_TEXTUREUSAGE_COMPUTE_STORAGE_WRITE", - "start_line": 828, - "type": "Invalid", - "value": ")" - }, - "14": { - "brief_comment": null, - "end_line": 829, - "kind": "MACRO_DEFINITION", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_TEXTUREUSAGE_COMPUTE_STORAGE_SIMULTANEOUS_READ_WRITE", - "start_line": 829, - "type": "Invalid", - "value": ")" - }, - "15": { - "brief_comment": null, - "end_line": 903, - "kind": "MACRO_DEFINITION", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_BUFFERUSAGE_VERTEX", - "start_line": 903, - "type": "Invalid", - "value": ")" - }, - "16": { - "brief_comment": null, - "end_line": 904, - "kind": "MACRO_DEFINITION", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_BUFFERUSAGE_INDEX", - "start_line": 904, - "type": "Invalid", - "value": ")" - }, - "17": { - "brief_comment": null, - "end_line": 905, - "kind": "MACRO_DEFINITION", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_BUFFERUSAGE_INDIRECT", - "start_line": 905, - "type": "Invalid", - "value": ")" - }, - "18": { - "brief_comment": null, - "end_line": 906, - "kind": "MACRO_DEFINITION", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_BUFFERUSAGE_GRAPHICS_STORAGE_READ", - "start_line": 906, - "type": "Invalid", - "value": ")" - }, - "19": { - "brief_comment": null, - "end_line": 907, - "kind": "MACRO_DEFINITION", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_BUFFERUSAGE_COMPUTE_STORAGE_READ", - "start_line": 907, - "type": "Invalid", - "value": ")" - }, - "20": { - "brief_comment": null, - "end_line": 908, - "kind": "MACRO_DEFINITION", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_BUFFERUSAGE_COMPUTE_STORAGE_WRITE", - "start_line": 908, - "type": "Invalid", - "value": ")" - }, - "21": { - "brief_comment": null, - "end_line": 950, - "kind": "MACRO_DEFINITION", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_SHADERFORMAT_INVALID", - "start_line": 950, - "type": "Invalid", - "value": 0 - }, - "22": { - "brief_comment": null, - "end_line": 951, - "kind": "MACRO_DEFINITION", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_SHADERFORMAT_PRIVATE", - "start_line": 951, - "type": "Invalid", - "value": ")" - }, - "23": { - "brief_comment": null, - "end_line": 952, - "kind": "MACRO_DEFINITION", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_SHADERFORMAT_SPIRV", - "start_line": 952, - "type": "Invalid", - "value": ")" - }, - "24": { - "brief_comment": null, - "end_line": 953, - "kind": "MACRO_DEFINITION", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_SHADERFORMAT_DXBC", - "start_line": 953, - "type": "Invalid", - "value": ")" - }, - "25": { - "brief_comment": null, - "end_line": 954, - "kind": "MACRO_DEFINITION", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_SHADERFORMAT_DXIL", - "start_line": 954, - "type": "Invalid", - "value": ")" - }, - "26": { - "brief_comment": null, - "end_line": 955, - "kind": "MACRO_DEFINITION", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_SHADERFORMAT_MSL", - "start_line": 955, - "type": "Invalid", - "value": ")" - }, - "27": { - "brief_comment": null, - "end_line": 956, - "kind": "MACRO_DEFINITION", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_SHADERFORMAT_METALLIB", - "start_line": 956, - "type": "Invalid", - "value": ")" - }, - "28": { - "brief_comment": null, - "end_line": 1178, - "kind": "MACRO_DEFINITION", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_COLORCOMPONENT_R", - "start_line": 1178, - "type": "Invalid", - "value": ")" - }, - "29": { - "brief_comment": null, - "end_line": 1179, - "kind": "MACRO_DEFINITION", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_COLORCOMPONENT_G", - "start_line": 1179, - "type": "Invalid", - "value": ")" - }, - "30": { - "brief_comment": null, - "end_line": 1180, - "kind": "MACRO_DEFINITION", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_COLORCOMPONENT_B", - "start_line": 1180, - "type": "Invalid", - "value": ")" - }, - "31": { - "brief_comment": null, - "end_line": 1181, - "kind": "MACRO_DEFINITION", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_COLORCOMPONENT_A", - "start_line": 1181, - "type": "Invalid", - "value": ")" - }, - "32": { - "brief_comment": null, - "end_line": 2180, - "kind": "MACRO_DEFINITION", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_PROP_GPU_DEVICE_CREATE_DEBUGMODE_BOOLEAN", - "start_line": 2180, - "type": "Invalid", - "value": "SDL.gpu.device.create.debugmode" - }, - "33": { - "brief_comment": null, - "end_line": 2181, - "kind": "MACRO_DEFINITION", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_PROP_GPU_DEVICE_CREATE_PREFERLOWPOWER_BOOLEAN", - "start_line": 2181, - "type": "Invalid", - "value": "SDL.gpu.device.create.preferlowpower" - }, - "34": { - "brief_comment": null, - "end_line": 2182, - "kind": "MACRO_DEFINITION", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_PROP_GPU_DEVICE_CREATE_NAME_STRING", - "start_line": 2182, - "type": "Invalid", - "value": "SDL.gpu.device.create.name" - }, - "35": { - "brief_comment": null, - "end_line": 2183, - "kind": "MACRO_DEFINITION", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_PROP_GPU_DEVICE_CREATE_SHADERS_PRIVATE_BOOLEAN", - "start_line": 2183, - "type": "Invalid", - "value": "SDL.gpu.device.create.shaders.private" - }, - "36": { - "brief_comment": null, - "end_line": 2184, - "kind": "MACRO_DEFINITION", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_PROP_GPU_DEVICE_CREATE_SHADERS_SPIRV_BOOLEAN", - "start_line": 2184, - "type": "Invalid", - "value": "SDL.gpu.device.create.shaders.spirv" - }, - "37": { - "brief_comment": null, - "end_line": 2185, - "kind": "MACRO_DEFINITION", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_PROP_GPU_DEVICE_CREATE_SHADERS_DXBC_BOOLEAN", - "start_line": 2185, - "type": "Invalid", - "value": "SDL.gpu.device.create.shaders.dxbc" - }, - "38": { - "brief_comment": null, - "end_line": 2186, - "kind": "MACRO_DEFINITION", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_PROP_GPU_DEVICE_CREATE_SHADERS_DXIL_BOOLEAN", - "start_line": 2186, - "type": "Invalid", - "value": "SDL.gpu.device.create.shaders.dxil" - }, - "39": { - "brief_comment": null, - "end_line": 2187, - "kind": "MACRO_DEFINITION", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_PROP_GPU_DEVICE_CREATE_SHADERS_MSL_BOOLEAN", - "start_line": 2187, - "type": "Invalid", - "value": "SDL.gpu.device.create.shaders.msl" - }, - "40": { - "brief_comment": null, - "end_line": 2188, - "kind": "MACRO_DEFINITION", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_PROP_GPU_DEVICE_CREATE_SHADERS_METALLIB_BOOLEAN", - "start_line": 2188, - "type": "Invalid", - "value": "SDL.gpu.device.create.shaders.metallib" - }, - "41": { - "brief_comment": null, - "end_line": 2189, - "kind": "MACRO_DEFINITION", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_PROP_GPU_DEVICE_CREATE_D3D12_SEMANTIC_NAME_STRING", - "start_line": 2189, - "type": "Invalid", - "value": "SDL.gpu.device.create.d3d12.semantic" - }, - "42": { - "brief_comment": null, - "end_line": 2304, - "kind": "MACRO_DEFINITION", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_PROP_GPU_COMPUTEPIPELINE_CREATE_NAME_STRING", - "start_line": 2304, - "type": "Invalid", - "value": "SDL.gpu.computepipeline.create.name" - }, - "43": { - "brief_comment": null, - "end_line": 2331, - "kind": "MACRO_DEFINITION", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_PROP_GPU_GRAPHICSPIPELINE_CREATE_NAME_STRING", - "start_line": 2331, - "type": "Invalid", - "value": "SDL.gpu.graphicspipeline.create.name" - }, - "44": { - "brief_comment": null, - "end_line": 2358, - "kind": "MACRO_DEFINITION", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_PROP_GPU_SAMPLER_CREATE_NAME_STRING", - "start_line": 2358, - "type": "Invalid", - "value": "SDL.gpu.sampler.create.name" - }, - "45": { - "brief_comment": null, - "end_line": 2437, - "kind": "MACRO_DEFINITION", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_PROP_GPU_SHADER_CREATE_NAME_STRING", - "start_line": 2437, - "type": "Invalid", - "value": "SDL.gpu.shader.create.name" - }, - "46": { - "brief_comment": null, - "end_line": 2498, - "kind": "MACRO_DEFINITION", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_PROP_GPU_TEXTURE_CREATE_D3D12_CLEAR_R_FLOAT", - "start_line": 2498, - "type": "Invalid", - "value": "SDL.gpu.texture.create.d3d12.clear.r" - }, - "47": { - "brief_comment": null, - "end_line": 2499, - "kind": "MACRO_DEFINITION", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_PROP_GPU_TEXTURE_CREATE_D3D12_CLEAR_G_FLOAT", - "start_line": 2499, - "type": "Invalid", - "value": "SDL.gpu.texture.create.d3d12.clear.g" - }, - "48": { - "brief_comment": null, - "end_line": 2500, - "kind": "MACRO_DEFINITION", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_PROP_GPU_TEXTURE_CREATE_D3D12_CLEAR_B_FLOAT", - "start_line": 2500, - "type": "Invalid", - "value": "SDL.gpu.texture.create.d3d12.clear.b" - }, - "49": { - "brief_comment": null, - "end_line": 2501, - "kind": "MACRO_DEFINITION", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_PROP_GPU_TEXTURE_CREATE_D3D12_CLEAR_A_FLOAT", - "start_line": 2501, - "type": "Invalid", - "value": "SDL.gpu.texture.create.d3d12.clear.a" - }, - "50": { - "brief_comment": null, - "end_line": 2502, - "kind": "MACRO_DEFINITION", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_PROP_GPU_TEXTURE_CREATE_D3D12_CLEAR_DEPTH_FLOAT", - "start_line": 2502, - "type": "Invalid", - "value": "SDL.gpu.texture.create.d3d12.clear.depth" - }, - "51": { - "brief_comment": null, - "end_line": 2503, - "kind": "MACRO_DEFINITION", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_PROP_GPU_TEXTURE_CREATE_D3D12_CLEAR_STENCIL_UINT8", - "start_line": 2503, - "type": "Invalid", - "value": "SDL.gpu.texture.create.d3d12.clear.stencil" - }, - "52": { - "brief_comment": null, - "end_line": 2504, - "kind": "MACRO_DEFINITION", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_PROP_GPU_TEXTURE_CREATE_NAME_STRING", - "start_line": 2504, - "type": "Invalid", - "value": "SDL.gpu.texture.create.name" - }, - "53": { - "brief_comment": null, - "end_line": 2554, - "kind": "MACRO_DEFINITION", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_PROP_GPU_BUFFER_CREATE_NAME_STRING", - "start_line": 2554, - "type": "Invalid", - "value": "SDL.gpu.buffer.create.name" - }, - "54": { - "brief_comment": null, - "end_line": 2587, - "kind": "MACRO_DEFINITION", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_PROP_GPU_TRANSFERBUFFER_CREATE_NAME_STRING", - "start_line": 2587, - "type": "Invalid", - "value": "SDL.gpu.transferbuffer.create.name" - }, - "55": { - "brief_comment": null, - "end_line": 4211, - "kind": "INCLUSION_DIRECTIVE", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL3/SDL_close_code.h", - "start_line": 4211, - "type": "Invalid" - }, - "56": { - "brief_comment": null, - "end_line": 328, - "kind": "STRUCT_DECL", - "location": "SDL_gpu.h", - "members": {}, - "result_type": "Invalid", - "spelling": "SDL_GPUDevice", - "start_line": 328, - "type": "Record" - }, - "57": { - "brief_comment": "An opaque handle representing the SDL_GPU context.", - "end_line": 328, - "kind": "TYPEDEF_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPUDevice", - "start_line": 328, - "type": "struct SDL_GPUDevice" - }, - "58": { - "brief_comment": null, - "end_line": 352, - "kind": "STRUCT_DECL", - "location": "SDL_gpu.h", - "members": {}, - "result_type": "Invalid", - "spelling": "SDL_GPUBuffer", - "start_line": 352, - "type": "Record" - }, - "59": { - "brief_comment": "An opaque handle representing a buffer.", - "end_line": 352, - "kind": "TYPEDEF_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPUBuffer", - "start_line": 352, - "type": "struct SDL_GPUBuffer" - }, - "60": { - "brief_comment": null, - "end_line": 370, - "kind": "STRUCT_DECL", - "location": "SDL_gpu.h", - "members": {}, - "result_type": "Invalid", - "spelling": "SDL_GPUTransferBuffer", - "start_line": 370, - "type": "Record" - }, - "61": { - "brief_comment": "An opaque handle representing a transfer buffer.", - "end_line": 370, - "kind": "TYPEDEF_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPUTransferBuffer", - "start_line": 370, - "type": "struct SDL_GPUTransferBuffer" - }, - "62": { - "brief_comment": null, - "end_line": 390, - "kind": "STRUCT_DECL", - "location": "SDL_gpu.h", - "members": {}, - "result_type": "Invalid", - "spelling": "SDL_GPUTexture", - "start_line": 390, - "type": "Record" - }, - "63": { - "brief_comment": "An opaque handle representing a texture.", - "end_line": 390, - "kind": "TYPEDEF_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPUTexture", - "start_line": 390, - "type": "struct SDL_GPUTexture" - }, - "64": { - "brief_comment": null, - "end_line": 402, - "kind": "STRUCT_DECL", - "location": "SDL_gpu.h", - "members": {}, - "result_type": "Invalid", - "spelling": "SDL_GPUSampler", - "start_line": 402, - "type": "Record" - }, - "65": { - "brief_comment": "An opaque handle representing a sampler.", - "end_line": 402, - "kind": "TYPEDEF_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPUSampler", - "start_line": 402, - "type": "struct SDL_GPUSampler" - }, - "66": { - "brief_comment": null, - "end_line": 413, - "kind": "STRUCT_DECL", - "location": "SDL_gpu.h", - "members": {}, - "result_type": "Invalid", - "spelling": "SDL_GPUShader", - "start_line": 413, - "type": "Record" - }, - "67": { - "brief_comment": "An opaque handle representing a compiled shader object.", - "end_line": 413, - "kind": "TYPEDEF_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPUShader", - "start_line": 413, - "type": "struct SDL_GPUShader" - }, - "68": { - "brief_comment": null, - "end_line": 426, - "kind": "STRUCT_DECL", - "location": "SDL_gpu.h", - "members": {}, - "result_type": "Invalid", - "spelling": "SDL_GPUComputePipeline", - "start_line": 426, - "type": "Record" - }, - "69": { - "brief_comment": "An opaque handle representing a compute pipeline.", - "end_line": 426, - "kind": "TYPEDEF_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPUComputePipeline", - "start_line": 426, - "type": "struct SDL_GPUComputePipeline" - }, - "70": { - "brief_comment": null, - "end_line": 439, - "kind": "STRUCT_DECL", - "location": "SDL_gpu.h", - "members": {}, - "result_type": "Invalid", - "spelling": "SDL_GPUGraphicsPipeline", - "start_line": 439, - "type": "Record" - }, - "71": { - "brief_comment": "An opaque handle representing a graphics pipeline.", - "end_line": 439, - "kind": "TYPEDEF_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPUGraphicsPipeline", - "start_line": 439, - "type": "struct SDL_GPUGraphicsPipeline" - }, - "72": { - "brief_comment": null, - "end_line": 464, - "kind": "STRUCT_DECL", - "location": "SDL_gpu.h", - "members": {}, - "result_type": "Invalid", - "spelling": "SDL_GPUCommandBuffer", - "start_line": 464, - "type": "Record" - }, - "73": { - "brief_comment": "An opaque handle representing a command buffer.", - "end_line": 464, - "kind": "TYPEDEF_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPUCommandBuffer", - "start_line": 464, - "type": "struct SDL_GPUCommandBuffer" - }, - "74": { - "brief_comment": null, - "end_line": 477, - "kind": "STRUCT_DECL", - "location": "SDL_gpu.h", - "members": {}, - "result_type": "Invalid", - "spelling": "SDL_GPURenderPass", - "start_line": 477, - "type": "Record" - }, - "75": { - "brief_comment": "An opaque handle representing a render pass.", - "end_line": 477, - "kind": "TYPEDEF_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPURenderPass", - "start_line": 477, - "type": "struct SDL_GPURenderPass" - }, - "76": { - "brief_comment": null, - "end_line": 490, - "kind": "STRUCT_DECL", - "location": "SDL_gpu.h", - "members": {}, - "result_type": "Invalid", - "spelling": "SDL_GPUComputePass", - "start_line": 490, - "type": "Record" - }, - "77": { - "brief_comment": "An opaque handle representing a compute pass.", - "end_line": 490, - "kind": "TYPEDEF_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPUComputePass", - "start_line": 490, - "type": "struct SDL_GPUComputePass" - }, - "78": { - "brief_comment": null, - "end_line": 503, - "kind": "STRUCT_DECL", - "location": "SDL_gpu.h", - "members": {}, - "result_type": "Invalid", - "spelling": "SDL_GPUCopyPass", - "start_line": 503, - "type": "Record" - }, - "79": { - "brief_comment": "An opaque handle representing a copy pass.", - "end_line": 503, - "kind": "TYPEDEF_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPUCopyPass", - "start_line": 503, - "type": "struct SDL_GPUCopyPass" - }, - "80": { - "brief_comment": null, - "end_line": 515, - "kind": "STRUCT_DECL", - "location": "SDL_gpu.h", - "members": {}, - "result_type": "Invalid", - "spelling": "SDL_GPUFence", - "start_line": 515, - "type": "Record" - }, - "81": { - "brief_comment": "An opaque handle representing a fence.", - "end_line": 515, - "kind": "TYPEDEF_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPUFence", - "start_line": 515, - "type": "struct SDL_GPUFence" - }, - "82": { - "brief_comment": "Specifies the primitive topology of a graphics pipeline.", - "end_line": 545, - "enumerations": { - "0": { - "brief_comment": "A series of separate triangles.", - "end_line": 540, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_PRIMITIVETYPE_TRIANGLELIST", - "start_line": 540, - "type": "Int", - "value": 0 - }, - "1": { - "brief_comment": "A series of connected triangles.", - "end_line": 541, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_PRIMITIVETYPE_TRIANGLESTRIP", - "start_line": 541, - "type": "Int", - "value": 1 - }, - "2": { - "brief_comment": "A series of separate lines.", - "end_line": 542, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_PRIMITIVETYPE_LINELIST", - "start_line": 542, - "type": "Int", - "value": 2 - }, - "3": { - "brief_comment": "A series of connected lines.", - "end_line": 543, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_PRIMITIVETYPE_LINESTRIP", - "start_line": 543, - "type": "Int", - "value": 3 - }, - "4": { - "brief_comment": "A series of separate points.", - "end_line": 544, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_PRIMITIVETYPE_POINTLIST", - "start_line": 544, - "type": "Int", - "value": 4 - } - }, - "kind": "ENUM_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPUPrimitiveType", - "start_line": 538, - "type": "Enum" - }, - "83": { - "brief_comment": "Specifies the primitive topology of a graphics pipeline.", - "end_line": 545, - "kind": "TYPEDEF_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPUPrimitiveType", - "start_line": 538, - "type": "enum SDL_GPUPrimitiveType" - }, - "84": { - "brief_comment": "Specifies how the contents of a texture attached to a render pass are treated at the beginning of the render pass.", - "end_line": 560, - "enumerations": { - "0": { - "brief_comment": "The previous contents of the texture will be preserved.", - "end_line": 557, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_LOADOP_LOAD", - "start_line": 557, - "type": "Int", - "value": 0 - }, - "1": { - "brief_comment": "The contents of the texture will be cleared to a color.", - "end_line": 558, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_LOADOP_CLEAR", - "start_line": 558, - "type": "Int", - "value": 1 - }, - "2": { - "brief_comment": "The previous contents of the texture need not be preserved. The contents will be undefined.", - "end_line": 559, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_LOADOP_DONT_CARE", - "start_line": 559, - "type": "Int", - "value": 2 - } - }, - "kind": "ENUM_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPULoadOp", - "start_line": 555, - "type": "Enum" - }, - "85": { - "brief_comment": "Specifies how the contents of a texture attached to a render pass are treated at the beginning of the render pass.", - "end_line": 560, - "kind": "TYPEDEF_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPULoadOp", - "start_line": 555, - "type": "enum SDL_GPULoadOp" - }, - "86": { - "brief_comment": "Specifies how the contents of a texture attached to a render pass are treated at the end of the render pass.", - "end_line": 576, - "enumerations": { - "0": { - "brief_comment": "The contents generated during the render pass will be written to memory.", - "end_line": 572, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_STOREOP_STORE", - "start_line": 572, - "type": "Int", - "value": 0 - }, - "1": { - "brief_comment": "The contents generated during the render pass are not needed and may be discarded. The contents will be undefined.", - "end_line": 573, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_STOREOP_DONT_CARE", - "start_line": 573, - "type": "Int", - "value": 1 - }, - "2": { - "brief_comment": "The multisample contents generated during the render pass will be resolved to a non-multisample texture. The contents in the multisample texture may then be discarded and will be undefined.", - "end_line": 574, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_STOREOP_RESOLVE", - "start_line": 574, - "type": "Int", - "value": 2 - }, - "3": { - "brief_comment": "The multisample contents generated during the render pass will be resolved to a non-multisample texture. The contents in the multisample texture will be written to memory.", - "end_line": 575, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_STOREOP_RESOLVE_AND_STORE", - "start_line": 575, - "type": "Int", - "value": 3 - } - }, - "kind": "ENUM_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPUStoreOp", - "start_line": 570, - "type": "Enum" - }, - "87": { - "brief_comment": "Specifies how the contents of a texture attached to a render pass are treated at the end of the render pass.", - "end_line": 576, - "kind": "TYPEDEF_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPUStoreOp", - "start_line": 570, - "type": "enum SDL_GPUStoreOp" - }, - "88": { - "brief_comment": "Specifies the size of elements in an index buffer.", - "end_line": 589, - "enumerations": { - "0": { - "brief_comment": "The index elements are 16-bit.", - "end_line": 587, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_INDEXELEMENTSIZE_16BIT", - "start_line": 587, - "type": "Int", - "value": 0 - }, - "1": { - "brief_comment": "The index elements are 32-bit.", - "end_line": 588, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_INDEXELEMENTSIZE_32BIT", - "start_line": 588, - "type": "Int", - "value": 1 - } - }, - "kind": "ENUM_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPUIndexElementSize", - "start_line": 585, - "type": "Enum" - }, - "89": { - "brief_comment": "Specifies the size of elements in an index buffer.", - "end_line": 589, - "kind": "TYPEDEF_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPUIndexElementSize", - "start_line": 585, - "type": "enum SDL_GPUIndexElementSize" - }, - "90": { - "brief_comment": "Specifies the pixel format of a texture.", - "end_line": 799, - "enumerations": { - "0": { - "brief_comment": null, - "end_line": 678, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_TEXTUREFORMAT_INVALID", - "start_line": 678, - "type": "Int", - "value": 0 - }, - "1": { - "brief_comment": null, - "end_line": 681, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_TEXTUREFORMAT_A8_UNORM", - "start_line": 681, - "type": "Int", - "value": 1 - }, - "2": { - "brief_comment": null, - "end_line": 682, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_TEXTUREFORMAT_R8_UNORM", - "start_line": 682, - "type": "Int", - "value": 2 - }, - "3": { - "brief_comment": null, - "end_line": 683, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_TEXTUREFORMAT_R8G8_UNORM", - "start_line": 683, - "type": "Int", - "value": 3 - }, - "4": { - "brief_comment": null, - "end_line": 684, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_TEXTUREFORMAT_R8G8B8A8_UNORM", - "start_line": 684, - "type": "Int", - "value": 4 - }, - "5": { - "brief_comment": null, - "end_line": 685, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_TEXTUREFORMAT_R16_UNORM", - "start_line": 685, - "type": "Int", - "value": 5 - }, - "6": { - "brief_comment": null, - "end_line": 686, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_TEXTUREFORMAT_R16G16_UNORM", - "start_line": 686, - "type": "Int", - "value": 6 - }, - "7": { - "brief_comment": null, - "end_line": 687, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_TEXTUREFORMAT_R16G16B16A16_UNORM", - "start_line": 687, - "type": "Int", - "value": 7 - }, - "8": { - "brief_comment": null, - "end_line": 688, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_TEXTUREFORMAT_R10G10B10A2_UNORM", - "start_line": 688, - "type": "Int", - "value": 8 - }, - "9": { - "brief_comment": null, - "end_line": 689, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_TEXTUREFORMAT_B5G6R5_UNORM", - "start_line": 689, - "type": "Int", - "value": 9 - }, - "10": { - "brief_comment": null, - "end_line": 690, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_TEXTUREFORMAT_B5G5R5A1_UNORM", - "start_line": 690, - "type": "Int", - "value": 10 - }, - "11": { - "brief_comment": null, - "end_line": 691, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_TEXTUREFORMAT_B4G4R4A4_UNORM", - "start_line": 691, - "type": "Int", - "value": 11 - }, - "12": { - "brief_comment": null, - "end_line": 692, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_TEXTUREFORMAT_B8G8R8A8_UNORM", - "start_line": 692, - "type": "Int", - "value": 12 - }, - "13": { - "brief_comment": null, - "end_line": 694, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_TEXTUREFORMAT_BC1_RGBA_UNORM", - "start_line": 694, - "type": "Int", - "value": 13 - }, - "14": { - "brief_comment": null, - "end_line": 695, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_TEXTUREFORMAT_BC2_RGBA_UNORM", - "start_line": 695, - "type": "Int", - "value": 14 - }, - "15": { - "brief_comment": null, - "end_line": 696, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_TEXTUREFORMAT_BC3_RGBA_UNORM", - "start_line": 696, - "type": "Int", - "value": 15 - }, - "16": { - "brief_comment": null, - "end_line": 697, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_TEXTUREFORMAT_BC4_R_UNORM", - "start_line": 697, - "type": "Int", - "value": 16 - }, - "17": { - "brief_comment": null, - "end_line": 698, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_TEXTUREFORMAT_BC5_RG_UNORM", - "start_line": 698, - "type": "Int", - "value": 17 - }, - "18": { - "brief_comment": null, - "end_line": 699, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_TEXTUREFORMAT_BC7_RGBA_UNORM", - "start_line": 699, - "type": "Int", - "value": 18 - }, - "19": { - "brief_comment": null, - "end_line": 701, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_TEXTUREFORMAT_BC6H_RGB_FLOAT", - "start_line": 701, - "type": "Int", - "value": 19 - }, - "20": { - "brief_comment": null, - "end_line": 703, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_TEXTUREFORMAT_BC6H_RGB_UFLOAT", - "start_line": 703, - "type": "Int", - "value": 20 - }, - "21": { - "brief_comment": null, - "end_line": 705, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_TEXTUREFORMAT_R8_SNORM", - "start_line": 705, - "type": "Int", - "value": 21 - }, - "22": { - "brief_comment": null, - "end_line": 706, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_TEXTUREFORMAT_R8G8_SNORM", - "start_line": 706, - "type": "Int", - "value": 22 - }, - "23": { - "brief_comment": null, - "end_line": 707, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_TEXTUREFORMAT_R8G8B8A8_SNORM", - "start_line": 707, - "type": "Int", - "value": 23 - }, - "24": { - "brief_comment": null, - "end_line": 708, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_TEXTUREFORMAT_R16_SNORM", - "start_line": 708, - "type": "Int", - "value": 24 - }, - "25": { - "brief_comment": null, - "end_line": 709, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_TEXTUREFORMAT_R16G16_SNORM", - "start_line": 709, - "type": "Int", - "value": 25 - }, - "26": { - "brief_comment": null, - "end_line": 710, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_TEXTUREFORMAT_R16G16B16A16_SNORM", - "start_line": 710, - "type": "Int", - "value": 26 - }, - "27": { - "brief_comment": null, - "end_line": 712, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_TEXTUREFORMAT_R16_FLOAT", - "start_line": 712, - "type": "Int", - "value": 27 - }, - "28": { - "brief_comment": null, - "end_line": 713, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_TEXTUREFORMAT_R16G16_FLOAT", - "start_line": 713, - "type": "Int", - "value": 28 - }, - "29": { - "brief_comment": null, - "end_line": 714, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_TEXTUREFORMAT_R16G16B16A16_FLOAT", - "start_line": 714, - "type": "Int", - "value": 29 - }, - "30": { - "brief_comment": null, - "end_line": 715, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_TEXTUREFORMAT_R32_FLOAT", - "start_line": 715, - "type": "Int", - "value": 30 - }, - "31": { - "brief_comment": null, - "end_line": 716, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_TEXTUREFORMAT_R32G32_FLOAT", - "start_line": 716, - "type": "Int", - "value": 31 - }, - "32": { - "brief_comment": null, - "end_line": 717, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_TEXTUREFORMAT_R32G32B32A32_FLOAT", - "start_line": 717, - "type": "Int", - "value": 32 - }, - "33": { - "brief_comment": null, - "end_line": 719, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_TEXTUREFORMAT_R11G11B10_UFLOAT", - "start_line": 719, - "type": "Int", - "value": 33 - }, - "34": { - "brief_comment": null, - "end_line": 721, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_TEXTUREFORMAT_R8_UINT", - "start_line": 721, - "type": "Int", - "value": 34 - }, - "35": { - "brief_comment": null, - "end_line": 722, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_TEXTUREFORMAT_R8G8_UINT", - "start_line": 722, - "type": "Int", - "value": 35 - }, - "36": { - "brief_comment": null, - "end_line": 723, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_TEXTUREFORMAT_R8G8B8A8_UINT", - "start_line": 723, - "type": "Int", - "value": 36 - }, - "37": { - "brief_comment": null, - "end_line": 724, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_TEXTUREFORMAT_R16_UINT", - "start_line": 724, - "type": "Int", - "value": 37 - }, - "38": { - "brief_comment": null, - "end_line": 725, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_TEXTUREFORMAT_R16G16_UINT", - "start_line": 725, - "type": "Int", - "value": 38 - }, - "39": { - "brief_comment": null, - "end_line": 726, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_TEXTUREFORMAT_R16G16B16A16_UINT", - "start_line": 726, - "type": "Int", - "value": 39 - }, - "40": { - "brief_comment": null, - "end_line": 727, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_TEXTUREFORMAT_R32_UINT", - "start_line": 727, - "type": "Int", - "value": 40 - }, - "41": { - "brief_comment": null, - "end_line": 728, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_TEXTUREFORMAT_R32G32_UINT", - "start_line": 728, - "type": "Int", - "value": 41 - }, - "42": { - "brief_comment": null, - "end_line": 729, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_TEXTUREFORMAT_R32G32B32A32_UINT", - "start_line": 729, - "type": "Int", - "value": 42 - }, - "43": { - "brief_comment": null, - "end_line": 731, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_TEXTUREFORMAT_R8_INT", - "start_line": 731, - "type": "Int", - "value": 43 - }, - "44": { - "brief_comment": null, - "end_line": 732, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_TEXTUREFORMAT_R8G8_INT", - "start_line": 732, - "type": "Int", - "value": 44 - }, - "45": { - "brief_comment": null, - "end_line": 733, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_TEXTUREFORMAT_R8G8B8A8_INT", - "start_line": 733, - "type": "Int", - "value": 45 - }, - "46": { - "brief_comment": null, - "end_line": 734, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_TEXTUREFORMAT_R16_INT", - "start_line": 734, - "type": "Int", - "value": 46 - }, - "47": { - "brief_comment": null, - "end_line": 735, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_TEXTUREFORMAT_R16G16_INT", - "start_line": 735, - "type": "Int", - "value": 47 - }, - "48": { - "brief_comment": null, - "end_line": 736, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_TEXTUREFORMAT_R16G16B16A16_INT", - "start_line": 736, - "type": "Int", - "value": 48 - }, - "49": { - "brief_comment": null, - "end_line": 737, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_TEXTUREFORMAT_R32_INT", - "start_line": 737, - "type": "Int", - "value": 49 - }, - "50": { - "brief_comment": null, - "end_line": 738, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_TEXTUREFORMAT_R32G32_INT", - "start_line": 738, - "type": "Int", - "value": 50 - }, - "51": { - "brief_comment": null, - "end_line": 739, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_TEXTUREFORMAT_R32G32B32A32_INT", - "start_line": 739, - "type": "Int", - "value": 51 - }, - "52": { - "brief_comment": null, - "end_line": 741, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_TEXTUREFORMAT_R8G8B8A8_UNORM_SRGB", - "start_line": 741, - "type": "Int", - "value": 52 - }, - "53": { - "brief_comment": null, - "end_line": 742, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_TEXTUREFORMAT_B8G8R8A8_UNORM_SRGB", - "start_line": 742, - "type": "Int", - "value": 53 - }, - "54": { - "brief_comment": null, - "end_line": 744, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_TEXTUREFORMAT_BC1_RGBA_UNORM_SRGB", - "start_line": 744, - "type": "Int", - "value": 54 - }, - "55": { - "brief_comment": null, - "end_line": 745, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_TEXTUREFORMAT_BC2_RGBA_UNORM_SRGB", - "start_line": 745, - "type": "Int", - "value": 55 - }, - "56": { - "brief_comment": null, - "end_line": 746, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_TEXTUREFORMAT_BC3_RGBA_UNORM_SRGB", - "start_line": 746, - "type": "Int", - "value": 56 - }, - "57": { - "brief_comment": null, - "end_line": 747, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_TEXTUREFORMAT_BC7_RGBA_UNORM_SRGB", - "start_line": 747, - "type": "Int", - "value": 57 - }, - "58": { - "brief_comment": null, - "end_line": 749, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_TEXTUREFORMAT_D16_UNORM", - "start_line": 749, - "type": "Int", - "value": 58 - }, - "59": { - "brief_comment": null, - "end_line": 750, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_TEXTUREFORMAT_D24_UNORM", - "start_line": 750, - "type": "Int", - "value": 59 - }, - "60": { - "brief_comment": null, - "end_line": 751, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_TEXTUREFORMAT_D32_FLOAT", - "start_line": 751, - "type": "Int", - "value": 60 - }, - "61": { - "brief_comment": null, - "end_line": 752, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_TEXTUREFORMAT_D24_UNORM_S8_UINT", - "start_line": 752, - "type": "Int", - "value": 61 - }, - "62": { - "brief_comment": null, - "end_line": 753, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_TEXTUREFORMAT_D32_FLOAT_S8_UINT", - "start_line": 753, - "type": "Int", - "value": 62 - }, - "63": { - "brief_comment": null, - "end_line": 755, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_TEXTUREFORMAT_ASTC_4x4_UNORM", - "start_line": 755, - "type": "Int", - "value": 63 - }, - "64": { - "brief_comment": null, - "end_line": 756, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_TEXTUREFORMAT_ASTC_5x4_UNORM", - "start_line": 756, - "type": "Int", - "value": 64 - }, - "65": { - "brief_comment": null, - "end_line": 757, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_TEXTUREFORMAT_ASTC_5x5_UNORM", - "start_line": 757, - "type": "Int", - "value": 65 - }, - "66": { - "brief_comment": null, - "end_line": 758, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_TEXTUREFORMAT_ASTC_6x5_UNORM", - "start_line": 758, - "type": "Int", - "value": 66 - }, - "67": { - "brief_comment": null, - "end_line": 759, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_TEXTUREFORMAT_ASTC_6x6_UNORM", - "start_line": 759, - "type": "Int", - "value": 67 - }, - "68": { - "brief_comment": null, - "end_line": 760, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_TEXTUREFORMAT_ASTC_8x5_UNORM", - "start_line": 760, - "type": "Int", - "value": 68 - }, - "69": { - "brief_comment": null, - "end_line": 761, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_TEXTUREFORMAT_ASTC_8x6_UNORM", - "start_line": 761, - "type": "Int", - "value": 69 - }, - "70": { - "brief_comment": null, - "end_line": 762, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_TEXTUREFORMAT_ASTC_8x8_UNORM", - "start_line": 762, - "type": "Int", - "value": 70 - }, - "71": { - "brief_comment": null, - "end_line": 763, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_TEXTUREFORMAT_ASTC_10x5_UNORM", - "start_line": 763, - "type": "Int", - "value": 71 - }, - "72": { - "brief_comment": null, - "end_line": 764, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_TEXTUREFORMAT_ASTC_10x6_UNORM", - "start_line": 764, - "type": "Int", - "value": 72 - }, - "73": { - "brief_comment": null, - "end_line": 765, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_TEXTUREFORMAT_ASTC_10x8_UNORM", - "start_line": 765, - "type": "Int", - "value": 73 - }, - "74": { - "brief_comment": null, - "end_line": 766, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_TEXTUREFORMAT_ASTC_10x10_UNORM", - "start_line": 766, - "type": "Int", - "value": 74 - }, - "75": { - "brief_comment": null, - "end_line": 767, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_TEXTUREFORMAT_ASTC_12x10_UNORM", - "start_line": 767, - "type": "Int", - "value": 75 - }, - "76": { - "brief_comment": null, - "end_line": 768, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_TEXTUREFORMAT_ASTC_12x12_UNORM", - "start_line": 768, - "type": "Int", - "value": 76 - }, - "77": { - "brief_comment": null, - "end_line": 770, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_TEXTUREFORMAT_ASTC_4x4_UNORM_SRGB", - "start_line": 770, - "type": "Int", - "value": 77 - }, - "78": { - "brief_comment": null, - "end_line": 771, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_TEXTUREFORMAT_ASTC_5x4_UNORM_SRGB", - "start_line": 771, - "type": "Int", - "value": 78 - }, - "79": { - "brief_comment": null, - "end_line": 772, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_TEXTUREFORMAT_ASTC_5x5_UNORM_SRGB", - "start_line": 772, - "type": "Int", - "value": 79 - }, - "80": { - "brief_comment": null, - "end_line": 773, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_TEXTUREFORMAT_ASTC_6x5_UNORM_SRGB", - "start_line": 773, - "type": "Int", - "value": 80 - }, - "81": { - "brief_comment": null, - "end_line": 774, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_TEXTUREFORMAT_ASTC_6x6_UNORM_SRGB", - "start_line": 774, - "type": "Int", - "value": 81 - }, - "82": { - "brief_comment": null, - "end_line": 775, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_TEXTUREFORMAT_ASTC_8x5_UNORM_SRGB", - "start_line": 775, - "type": "Int", - "value": 82 - }, - "83": { - "brief_comment": null, - "end_line": 776, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_TEXTUREFORMAT_ASTC_8x6_UNORM_SRGB", - "start_line": 776, - "type": "Int", - "value": 83 - }, - "84": { - "brief_comment": null, - "end_line": 777, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_TEXTUREFORMAT_ASTC_8x8_UNORM_SRGB", - "start_line": 777, - "type": "Int", - "value": 84 - }, - "85": { - "brief_comment": null, - "end_line": 778, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_TEXTUREFORMAT_ASTC_10x5_UNORM_SRGB", - "start_line": 778, - "type": "Int", - "value": 85 - }, - "86": { - "brief_comment": null, - "end_line": 779, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_TEXTUREFORMAT_ASTC_10x6_UNORM_SRGB", - "start_line": 779, - "type": "Int", - "value": 86 - }, - "87": { - "brief_comment": null, - "end_line": 780, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_TEXTUREFORMAT_ASTC_10x8_UNORM_SRGB", - "start_line": 780, - "type": "Int", - "value": 87 - }, - "88": { - "brief_comment": null, - "end_line": 781, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_TEXTUREFORMAT_ASTC_10x10_UNORM_SRGB", - "start_line": 781, - "type": "Int", - "value": 88 - }, - "89": { - "brief_comment": null, - "end_line": 782, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_TEXTUREFORMAT_ASTC_12x10_UNORM_SRGB", - "start_line": 782, - "type": "Int", - "value": 89 - }, - "90": { - "brief_comment": null, - "end_line": 783, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_TEXTUREFORMAT_ASTC_12x12_UNORM_SRGB", - "start_line": 783, - "type": "Int", - "value": 90 - }, - "91": { - "brief_comment": null, - "end_line": 785, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_TEXTUREFORMAT_ASTC_4x4_FLOAT", - "start_line": 785, - "type": "Int", - "value": 91 - }, - "92": { - "brief_comment": null, - "end_line": 786, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_TEXTUREFORMAT_ASTC_5x4_FLOAT", - "start_line": 786, - "type": "Int", - "value": 92 - }, - "93": { - "brief_comment": null, - "end_line": 787, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_TEXTUREFORMAT_ASTC_5x5_FLOAT", - "start_line": 787, - "type": "Int", - "value": 93 - }, - "94": { - "brief_comment": null, - "end_line": 788, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_TEXTUREFORMAT_ASTC_6x5_FLOAT", - "start_line": 788, - "type": "Int", - "value": 94 - }, - "95": { - "brief_comment": null, - "end_line": 789, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_TEXTUREFORMAT_ASTC_6x6_FLOAT", - "start_line": 789, - "type": "Int", - "value": 95 - }, - "96": { - "brief_comment": null, - "end_line": 790, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_TEXTUREFORMAT_ASTC_8x5_FLOAT", - "start_line": 790, - "type": "Int", - "value": 96 - }, - "97": { - "brief_comment": null, - "end_line": 791, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_TEXTUREFORMAT_ASTC_8x6_FLOAT", - "start_line": 791, - "type": "Int", - "value": 97 - }, - "98": { - "brief_comment": null, - "end_line": 792, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_TEXTUREFORMAT_ASTC_8x8_FLOAT", - "start_line": 792, - "type": "Int", - "value": 98 - }, - "99": { - "brief_comment": null, - "end_line": 793, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_TEXTUREFORMAT_ASTC_10x5_FLOAT", - "start_line": 793, - "type": "Int", - "value": 99 - }, - "100": { - "brief_comment": null, - "end_line": 794, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_TEXTUREFORMAT_ASTC_10x6_FLOAT", - "start_line": 794, - "type": "Int", - "value": 100 - }, - "101": { - "brief_comment": null, - "end_line": 795, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_TEXTUREFORMAT_ASTC_10x8_FLOAT", - "start_line": 795, - "type": "Int", - "value": 101 - }, - "102": { - "brief_comment": null, - "end_line": 796, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_TEXTUREFORMAT_ASTC_10x10_FLOAT", - "start_line": 796, - "type": "Int", - "value": 102 - }, - "103": { - "brief_comment": null, - "end_line": 797, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_TEXTUREFORMAT_ASTC_12x10_FLOAT", - "start_line": 797, - "type": "Int", - "value": 103 - }, - "104": { - "brief_comment": null, - "end_line": 798, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_TEXTUREFORMAT_ASTC_12x12_FLOAT", - "start_line": 798, - "type": "Int", - "value": 104 - } - }, - "kind": "ENUM_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPUTextureFormat", - "start_line": 676, - "type": "Enum" - }, - "91": { - "brief_comment": "Specifies the pixel format of a texture.", - "end_line": 799, - "kind": "TYPEDEF_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPUTextureFormat", - "start_line": 676, - "type": "enum SDL_GPUTextureFormat" - }, - "92": { - "brief_comment": "Specifies how a texture is intended to be used by the client.", - "end_line": 821, - "kind": "TYPEDEF_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPUTextureUsageFlags", - "start_line": 821, - "type": "int" - }, - "93": { - "brief_comment": "Specifies the type of a texture.", - "end_line": 845, - "enumerations": { - "0": { - "brief_comment": "The texture is a 2-dimensional image.", - "end_line": 840, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_TEXTURETYPE_2D", - "start_line": 840, - "type": "Int", - "value": 0 - }, - "1": { - "brief_comment": "The texture is a 2-dimensional array image.", - "end_line": 841, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_TEXTURETYPE_2D_ARRAY", - "start_line": 841, - "type": "Int", - "value": 1 - }, - "2": { - "brief_comment": "The texture is a 3-dimensional image.", - "end_line": 842, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_TEXTURETYPE_3D", - "start_line": 842, - "type": "Int", - "value": 2 - }, - "3": { - "brief_comment": "The texture is a cube image.", - "end_line": 843, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_TEXTURETYPE_CUBE", - "start_line": 843, - "type": "Int", - "value": 3 - }, - "4": { - "brief_comment": "The texture is a cube array image.", - "end_line": 844, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_TEXTURETYPE_CUBE_ARRAY", - "start_line": 844, - "type": "Int", - "value": 4 - } - }, - "kind": "ENUM_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPUTextureType", - "start_line": 838, - "type": "Enum" - }, - "94": { - "brief_comment": "Specifies the type of a texture.", - "end_line": 845, - "kind": "TYPEDEF_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPUTextureType", - "start_line": 838, - "type": "enum SDL_GPUTextureType" - }, - "95": { - "brief_comment": "Specifies the sample count of a texture.", - "end_line": 864, - "enumerations": { - "0": { - "brief_comment": "No multisampling.", - "end_line": 860, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_SAMPLECOUNT_1", - "start_line": 860, - "type": "Int", - "value": 0 - }, - "1": { - "brief_comment": "MSAA 2x", - "end_line": 861, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_SAMPLECOUNT_2", - "start_line": 861, - "type": "Int", - "value": 1 - }, - "2": { - "brief_comment": "MSAA 4x", - "end_line": 862, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_SAMPLECOUNT_4", - "start_line": 862, - "type": "Int", - "value": 2 - }, - "3": { - "brief_comment": "MSAA 8x", - "end_line": 863, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_SAMPLECOUNT_8", - "start_line": 863, - "type": "Int", - "value": 3 - } - }, - "kind": "ENUM_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPUSampleCount", - "start_line": 858, - "type": "Enum" - }, - "96": { - "brief_comment": "Specifies the sample count of a texture.", - "end_line": 864, - "kind": "TYPEDEF_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPUSampleCount", - "start_line": 858, - "type": "enum SDL_GPUSampleCount" - }, - "97": { - "brief_comment": "Specifies the face of a cube map.", - "end_line": 882, - "enumerations": { - "0": { - "brief_comment": null, - "end_line": 876, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_CUBEMAPFACE_POSITIVEX", - "start_line": 876, - "type": "Int", - "value": 0 - }, - "1": { - "brief_comment": null, - "end_line": 877, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_CUBEMAPFACE_NEGATIVEX", - "start_line": 877, - "type": "Int", - "value": 1 - }, - "2": { - "brief_comment": null, - "end_line": 878, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_CUBEMAPFACE_POSITIVEY", - "start_line": 878, - "type": "Int", - "value": 2 - }, - "3": { - "brief_comment": null, - "end_line": 879, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_CUBEMAPFACE_NEGATIVEY", - "start_line": 879, - "type": "Int", - "value": 3 - }, - "4": { - "brief_comment": null, - "end_line": 880, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_CUBEMAPFACE_POSITIVEZ", - "start_line": 880, - "type": "Int", - "value": 4 - }, - "5": { - "brief_comment": null, - "end_line": 881, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_CUBEMAPFACE_NEGATIVEZ", - "start_line": 881, - "type": "Int", - "value": 5 - } - }, - "kind": "ENUM_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPUCubeMapFace", - "start_line": 874, - "type": "Enum" - }, - "98": { - "brief_comment": "Specifies the face of a cube map.", - "end_line": 882, - "kind": "TYPEDEF_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPUCubeMapFace", - "start_line": 874, - "type": "enum SDL_GPUCubeMapFace" - }, - "99": { - "brief_comment": "Specifies how a buffer is intended to be used by the client.", - "end_line": 901, - "kind": "TYPEDEF_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPUBufferUsageFlags", - "start_line": 901, - "type": "int" - }, - "100": { - "brief_comment": "Specifies how a transfer buffer is intended to be used by the client.", - "end_line": 924, - "enumerations": { - "0": { - "brief_comment": null, - "end_line": 922, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_TRANSFERBUFFERUSAGE_UPLOAD", - "start_line": 922, - "type": "Int", - "value": 0 - }, - "1": { - "brief_comment": null, - "end_line": 923, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_TRANSFERBUFFERUSAGE_DOWNLOAD", - "start_line": 923, - "type": "Int", - "value": 1 - } - }, - "kind": "ENUM_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPUTransferBufferUsage", - "start_line": 920, - "type": "Enum" - }, - "101": { - "brief_comment": "Specifies how a transfer buffer is intended to be used by the client.", - "end_line": 924, - "kind": "TYPEDEF_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPUTransferBufferUsage", - "start_line": 920, - "type": "enum SDL_GPUTransferBufferUsage" - }, - "102": { - "brief_comment": "Specifies which stage a shader program corresponds to.", - "end_line": 937, - "enumerations": { - "0": { - "brief_comment": null, - "end_line": 935, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_SHADERSTAGE_VERTEX", - "start_line": 935, - "type": "Int", - "value": 0 - }, - "1": { - "brief_comment": null, - "end_line": 936, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_SHADERSTAGE_FRAGMENT", - "start_line": 936, - "type": "Int", - "value": 1 - } - }, - "kind": "ENUM_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPUShaderStage", - "start_line": 933, - "type": "Enum" - }, - "103": { - "brief_comment": "Specifies which stage a shader program corresponds to.", - "end_line": 937, - "kind": "TYPEDEF_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPUShaderStage", - "start_line": 933, - "type": "enum SDL_GPUShaderStage" - }, - "104": { - "brief_comment": "Specifies the format of shader code.", - "end_line": 948, - "kind": "TYPEDEF_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPUShaderFormat", - "start_line": 948, - "type": "int" - }, - "105": { - "brief_comment": "Specifies the format of a vertex attribute.", - "end_line": 1022, - "enumerations": { - "0": { - "brief_comment": null, - "end_line": 967, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_VERTEXELEMENTFORMAT_INVALID", - "start_line": 967, - "type": "Int", - "value": 0 - }, - "1": { - "brief_comment": null, - "end_line": 970, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_VERTEXELEMENTFORMAT_INT", - "start_line": 970, - "type": "Int", - "value": 1 - }, - "2": { - "brief_comment": null, - "end_line": 971, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_VERTEXELEMENTFORMAT_INT2", - "start_line": 971, - "type": "Int", - "value": 2 - }, - "3": { - "brief_comment": null, - "end_line": 972, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_VERTEXELEMENTFORMAT_INT3", - "start_line": 972, - "type": "Int", - "value": 3 - }, - "4": { - "brief_comment": null, - "end_line": 973, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_VERTEXELEMENTFORMAT_INT4", - "start_line": 973, - "type": "Int", - "value": 4 - }, - "5": { - "brief_comment": null, - "end_line": 976, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_VERTEXELEMENTFORMAT_UINT", - "start_line": 976, - "type": "Int", - "value": 5 - }, - "6": { - "brief_comment": null, - "end_line": 977, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_VERTEXELEMENTFORMAT_UINT2", - "start_line": 977, - "type": "Int", - "value": 6 - }, - "7": { - "brief_comment": null, - "end_line": 978, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_VERTEXELEMENTFORMAT_UINT3", - "start_line": 978, - "type": "Int", - "value": 7 - }, - "8": { - "brief_comment": null, - "end_line": 979, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_VERTEXELEMENTFORMAT_UINT4", - "start_line": 979, - "type": "Int", - "value": 8 - }, - "9": { - "brief_comment": null, - "end_line": 982, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_VERTEXELEMENTFORMAT_FLOAT", - "start_line": 982, - "type": "Int", - "value": 9 - }, - "10": { - "brief_comment": null, - "end_line": 983, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_VERTEXELEMENTFORMAT_FLOAT2", - "start_line": 983, - "type": "Int", - "value": 10 - }, - "11": { - "brief_comment": null, - "end_line": 984, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_VERTEXELEMENTFORMAT_FLOAT3", - "start_line": 984, - "type": "Int", - "value": 11 - }, - "12": { - "brief_comment": null, - "end_line": 985, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_VERTEXELEMENTFORMAT_FLOAT4", - "start_line": 985, - "type": "Int", - "value": 12 - }, - "13": { - "brief_comment": null, - "end_line": 988, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_VERTEXELEMENTFORMAT_BYTE2", - "start_line": 988, - "type": "Int", - "value": 13 - }, - "14": { - "brief_comment": null, - "end_line": 989, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_VERTEXELEMENTFORMAT_BYTE4", - "start_line": 989, - "type": "Int", - "value": 14 - }, - "15": { - "brief_comment": null, - "end_line": 992, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_VERTEXELEMENTFORMAT_UBYTE2", - "start_line": 992, - "type": "Int", - "value": 15 - }, - "16": { - "brief_comment": null, - "end_line": 993, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_VERTEXELEMENTFORMAT_UBYTE4", - "start_line": 993, - "type": "Int", - "value": 16 - }, - "17": { - "brief_comment": null, - "end_line": 996, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_VERTEXELEMENTFORMAT_BYTE2_NORM", - "start_line": 996, - "type": "Int", - "value": 17 - }, - "18": { - "brief_comment": null, - "end_line": 997, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_VERTEXELEMENTFORMAT_BYTE4_NORM", - "start_line": 997, - "type": "Int", - "value": 18 - }, - "19": { - "brief_comment": null, - "end_line": 1000, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_VERTEXELEMENTFORMAT_UBYTE2_NORM", - "start_line": 1000, - "type": "Int", - "value": 19 - }, - "20": { - "brief_comment": null, - "end_line": 1001, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_VERTEXELEMENTFORMAT_UBYTE4_NORM", - "start_line": 1001, - "type": "Int", - "value": 20 - }, - "21": { - "brief_comment": null, - "end_line": 1004, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_VERTEXELEMENTFORMAT_SHORT2", - "start_line": 1004, - "type": "Int", - "value": 21 - }, - "22": { - "brief_comment": null, - "end_line": 1005, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_VERTEXELEMENTFORMAT_SHORT4", - "start_line": 1005, - "type": "Int", - "value": 22 - }, - "23": { - "brief_comment": null, - "end_line": 1008, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_VERTEXELEMENTFORMAT_USHORT2", - "start_line": 1008, - "type": "Int", - "value": 23 - }, - "24": { - "brief_comment": null, - "end_line": 1009, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_VERTEXELEMENTFORMAT_USHORT4", - "start_line": 1009, - "type": "Int", - "value": 24 - }, - "25": { - "brief_comment": null, - "end_line": 1012, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_VERTEXELEMENTFORMAT_SHORT2_NORM", - "start_line": 1012, - "type": "Int", - "value": 25 - }, - "26": { - "brief_comment": null, - "end_line": 1013, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_VERTEXELEMENTFORMAT_SHORT4_NORM", - "start_line": 1013, - "type": "Int", - "value": 26 - }, - "27": { - "brief_comment": null, - "end_line": 1016, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_VERTEXELEMENTFORMAT_USHORT2_NORM", - "start_line": 1016, - "type": "Int", - "value": 27 - }, - "28": { - "brief_comment": null, - "end_line": 1017, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_VERTEXELEMENTFORMAT_USHORT4_NORM", - "start_line": 1017, - "type": "Int", - "value": 28 - }, - "29": { - "brief_comment": null, - "end_line": 1020, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_VERTEXELEMENTFORMAT_HALF2", - "start_line": 1020, - "type": "Int", - "value": 29 - }, - "30": { - "brief_comment": null, - "end_line": 1021, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_VERTEXELEMENTFORMAT_HALF4", - "start_line": 1021, - "type": "Int", - "value": 30 - } - }, - "kind": "ENUM_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPUVertexElementFormat", - "start_line": 965, - "type": "Enum" - }, - "106": { - "brief_comment": "Specifies the format of a vertex attribute.", - "end_line": 1022, - "kind": "TYPEDEF_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPUVertexElementFormat", - "start_line": 965, - "type": "enum SDL_GPUVertexElementFormat" - }, - "107": { - "brief_comment": "Specifies the rate at which vertex attributes are pulled from buffers.", - "end_line": 1035, - "enumerations": { - "0": { - "brief_comment": "Attribute addressing is a function of the vertex index.", - "end_line": 1033, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_VERTEXINPUTRATE_VERTEX", - "start_line": 1033, - "type": "Int", - "value": 0 - }, - "1": { - "brief_comment": "Attribute addressing is a function of the instance index.", - "end_line": 1034, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_VERTEXINPUTRATE_INSTANCE", - "start_line": 1034, - "type": "Int", - "value": 1 - } - }, - "kind": "ENUM_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPUVertexInputRate", - "start_line": 1031, - "type": "Enum" - }, - "108": { - "brief_comment": "Specifies the rate at which vertex attributes are pulled from buffers.", - "end_line": 1035, - "kind": "TYPEDEF_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPUVertexInputRate", - "start_line": 1031, - "type": "enum SDL_GPUVertexInputRate" - }, - "109": { - "brief_comment": "Specifies the fill mode of the graphics pipeline.", - "end_line": 1048, - "enumerations": { - "0": { - "brief_comment": "Polygons will be rendered via rasterization.", - "end_line": 1046, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_FILLMODE_FILL", - "start_line": 1046, - "type": "Int", - "value": 0 - }, - "1": { - "brief_comment": "Polygon edges will be drawn as line segments.", - "end_line": 1047, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_FILLMODE_LINE", - "start_line": 1047, - "type": "Int", - "value": 1 - } - }, - "kind": "ENUM_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPUFillMode", - "start_line": 1044, - "type": "Enum" - }, - "110": { - "brief_comment": "Specifies the fill mode of the graphics pipeline.", - "end_line": 1048, - "kind": "TYPEDEF_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPUFillMode", - "start_line": 1044, - "type": "enum SDL_GPUFillMode" - }, - "111": { - "brief_comment": "Specifies the facing direction in which triangle faces will be culled.", - "end_line": 1062, - "enumerations": { - "0": { - "brief_comment": "No triangles are culled.", - "end_line": 1059, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_CULLMODE_NONE", - "start_line": 1059, - "type": "Int", - "value": 0 - }, - "1": { - "brief_comment": "Front-facing triangles are culled.", - "end_line": 1060, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_CULLMODE_FRONT", - "start_line": 1060, - "type": "Int", - "value": 1 - }, - "2": { - "brief_comment": "Back-facing triangles are culled.", - "end_line": 1061, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_CULLMODE_BACK", - "start_line": 1061, - "type": "Int", - "value": 2 - } - }, - "kind": "ENUM_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPUCullMode", - "start_line": 1057, - "type": "Enum" - }, - "112": { - "brief_comment": "Specifies the facing direction in which triangle faces will be culled.", - "end_line": 1062, - "kind": "TYPEDEF_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPUCullMode", - "start_line": 1057, - "type": "enum SDL_GPUCullMode" - }, - "113": { - "brief_comment": "Specifies the vertex winding that will cause a triangle to be determined to be front-facing.", - "end_line": 1076, - "enumerations": { - "0": { - "brief_comment": "A triangle with counter-clockwise vertex winding will be considered front-facing.", - "end_line": 1074, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_FRONTFACE_COUNTER_CLOCKWISE", - "start_line": 1074, - "type": "Int", - "value": 0 - }, - "1": { - "brief_comment": "A triangle with clockwise vertex winding will be considered front-facing.", - "end_line": 1075, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_FRONTFACE_CLOCKWISE", - "start_line": 1075, - "type": "Int", - "value": 1 - } - }, - "kind": "ENUM_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPUFrontFace", - "start_line": 1072, - "type": "Enum" - }, - "114": { - "brief_comment": "Specifies the vertex winding that will cause a triangle to be determined to be front-facing.", - "end_line": 1076, - "kind": "TYPEDEF_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPUFrontFace", - "start_line": 1072, - "type": "enum SDL_GPUFrontFace" - }, - "115": { - "brief_comment": "Specifies a comparison operator for depth, stencil and sampler operations.", - "end_line": 1096, - "enumerations": { - "0": { - "brief_comment": null, - "end_line": 1087, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_COMPAREOP_INVALID", - "start_line": 1087, - "type": "Int", - "value": 0 - }, - "1": { - "brief_comment": "The comparison always evaluates false.", - "end_line": 1088, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_COMPAREOP_NEVER", - "start_line": 1088, - "type": "Int", - "value": 1 - }, - "2": { - "brief_comment": "The comparison evaluates reference < test.", - "end_line": 1089, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_COMPAREOP_LESS", - "start_line": 1089, - "type": "Int", - "value": 2 - }, - "3": { - "brief_comment": "The comparison evaluates reference == test.", - "end_line": 1090, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_COMPAREOP_EQUAL", - "start_line": 1090, - "type": "Int", - "value": 3 - }, - "4": { - "brief_comment": "The comparison evaluates reference <= test.", - "end_line": 1091, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_COMPAREOP_LESS_OR_EQUAL", - "start_line": 1091, - "type": "Int", - "value": 4 - }, - "5": { - "brief_comment": "The comparison evaluates reference > test.", - "end_line": 1092, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_COMPAREOP_GREATER", - "start_line": 1092, - "type": "Int", - "value": 5 - }, - "6": { - "brief_comment": "The comparison evaluates reference != test.", - "end_line": 1093, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_COMPAREOP_NOT_EQUAL", - "start_line": 1093, - "type": "Int", - "value": 6 - }, - "7": { - "brief_comment": "The comparison evalutes reference >= test.", - "end_line": 1094, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_COMPAREOP_GREATER_OR_EQUAL", - "start_line": 1094, - "type": "Int", - "value": 7 - }, - "8": { - "brief_comment": "The comparison always evaluates true.", - "end_line": 1095, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_COMPAREOP_ALWAYS", - "start_line": 1095, - "type": "Int", - "value": 8 - } - }, - "kind": "ENUM_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPUCompareOp", - "start_line": 1085, - "type": "Enum" - }, - "116": { - "brief_comment": "Specifies a comparison operator for depth, stencil and sampler operations.", - "end_line": 1096, - "kind": "TYPEDEF_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPUCompareOp", - "start_line": 1085, - "type": "enum SDL_GPUCompareOp" - }, - "117": { - "brief_comment": "Specifies what happens to a stored stencil value if stencil tests fail or pass.", - "end_line": 1117, - "enumerations": { - "0": { - "brief_comment": null, - "end_line": 1108, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_STENCILOP_INVALID", - "start_line": 1108, - "type": "Int", - "value": 0 - }, - "1": { - "brief_comment": "Keeps the current value.", - "end_line": 1109, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_STENCILOP_KEEP", - "start_line": 1109, - "type": "Int", - "value": 1 - }, - "2": { - "brief_comment": "Sets the value to 0.", - "end_line": 1110, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_STENCILOP_ZERO", - "start_line": 1110, - "type": "Int", - "value": 2 - }, - "3": { - "brief_comment": "Sets the value to reference.", - "end_line": 1111, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_STENCILOP_REPLACE", - "start_line": 1111, - "type": "Int", - "value": 3 - }, - "4": { - "brief_comment": "Increments the current value and clamps to the maximum value.", - "end_line": 1112, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_STENCILOP_INCREMENT_AND_CLAMP", - "start_line": 1112, - "type": "Int", - "value": 4 - }, - "5": { - "brief_comment": "Decrements the current value and clamps to 0.", - "end_line": 1113, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_STENCILOP_DECREMENT_AND_CLAMP", - "start_line": 1113, - "type": "Int", - "value": 5 - }, - "6": { - "brief_comment": "Bitwise-inverts the current value.", - "end_line": 1114, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_STENCILOP_INVERT", - "start_line": 1114, - "type": "Int", - "value": 6 - }, - "7": { - "brief_comment": "Increments the current value and wraps back to 0.", - "end_line": 1115, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_STENCILOP_INCREMENT_AND_WRAP", - "start_line": 1115, - "type": "Int", - "value": 7 - }, - "8": { - "brief_comment": "Decrements the current value and wraps to the maximum value.", - "end_line": 1116, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_STENCILOP_DECREMENT_AND_WRAP", - "start_line": 1116, - "type": "Int", - "value": 8 - } - }, - "kind": "ENUM_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPUStencilOp", - "start_line": 1106, - "type": "Enum" - }, - "118": { - "brief_comment": "Specifies what happens to a stored stencil value if stencil tests fail or pass.", - "end_line": 1117, - "kind": "TYPEDEF_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPUStencilOp", - "start_line": 1106, - "type": "enum SDL_GPUStencilOp" - }, - "119": { - "brief_comment": "Specifies the operator to be used when pixels in a render target are blended with existing pixels in the texture.", - "end_line": 1138, - "enumerations": { - "0": { - "brief_comment": null, - "end_line": 1132, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_BLENDOP_INVALID", - "start_line": 1132, - "type": "Int", - "value": 0 - }, - "1": { - "brief_comment": "(source * source_factor) + (destination * destination_factor)", - "end_line": 1133, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_BLENDOP_ADD", - "start_line": 1133, - "type": "Int", - "value": 1 - }, - "2": { - "brief_comment": "(source * source_factor) - (destination * destination_factor)", - "end_line": 1134, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_BLENDOP_SUBTRACT", - "start_line": 1134, - "type": "Int", - "value": 2 - }, - "3": { - "brief_comment": "(destination * destination_factor) - (source * source_factor)", - "end_line": 1135, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_BLENDOP_REVERSE_SUBTRACT", - "start_line": 1135, - "type": "Int", - "value": 3 - }, - "4": { - "brief_comment": "min(source, destination)", - "end_line": 1136, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_BLENDOP_MIN", - "start_line": 1136, - "type": "Int", - "value": 4 - }, - "5": { - "brief_comment": "max(source, destination)", - "end_line": 1137, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_BLENDOP_MAX", - "start_line": 1137, - "type": "Int", - "value": 5 - } - }, - "kind": "ENUM_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPUBlendOp", - "start_line": 1130, - "type": "Enum" - }, - "120": { - "brief_comment": "Specifies the operator to be used when pixels in a render target are blended with existing pixels in the texture.", - "end_line": 1138, - "kind": "TYPEDEF_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPUBlendOp", - "start_line": 1130, - "type": "enum SDL_GPUBlendOp" - }, - "121": { - "brief_comment": "Specifies a blending factor to be used when pixels in a render target are blended with existing pixels in the texture.", - "end_line": 1167, - "enumerations": { - "0": { - "brief_comment": null, - "end_line": 1153, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_BLENDFACTOR_INVALID", - "start_line": 1153, - "type": "Int", - "value": 0 - }, - "1": { - "brief_comment": "0", - "end_line": 1154, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_BLENDFACTOR_ZERO", - "start_line": 1154, - "type": "Int", - "value": 1 - }, - "2": { - "brief_comment": "1", - "end_line": 1155, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_BLENDFACTOR_ONE", - "start_line": 1155, - "type": "Int", - "value": 2 - }, - "3": { - "brief_comment": "source color", - "end_line": 1156, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_BLENDFACTOR_SRC_COLOR", - "start_line": 1156, - "type": "Int", - "value": 3 - }, - "4": { - "brief_comment": "1 - source color", - "end_line": 1157, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_BLENDFACTOR_ONE_MINUS_SRC_COLOR", - "start_line": 1157, - "type": "Int", - "value": 4 - }, - "5": { - "brief_comment": "destination color", - "end_line": 1158, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_BLENDFACTOR_DST_COLOR", - "start_line": 1158, - "type": "Int", - "value": 5 - }, - "6": { - "brief_comment": "1 - destination color", - "end_line": 1159, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_BLENDFACTOR_ONE_MINUS_DST_COLOR", - "start_line": 1159, - "type": "Int", - "value": 6 - }, - "7": { - "brief_comment": "source alpha", - "end_line": 1160, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_BLENDFACTOR_SRC_ALPHA", - "start_line": 1160, - "type": "Int", - "value": 7 - }, - "8": { - "brief_comment": "1 - source alpha", - "end_line": 1161, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_BLENDFACTOR_ONE_MINUS_SRC_ALPHA", - "start_line": 1161, - "type": "Int", - "value": 8 - }, - "9": { - "brief_comment": "destination alpha", - "end_line": 1162, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_BLENDFACTOR_DST_ALPHA", - "start_line": 1162, - "type": "Int", - "value": 9 - }, - "10": { - "brief_comment": "1 - destination alpha", - "end_line": 1163, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_BLENDFACTOR_ONE_MINUS_DST_ALPHA", - "start_line": 1163, - "type": "Int", - "value": 10 - }, - "11": { - "brief_comment": "blend constant", - "end_line": 1164, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_BLENDFACTOR_CONSTANT_COLOR", - "start_line": 1164, - "type": "Int", - "value": 11 - }, - "12": { - "brief_comment": "1 - blend constant", - "end_line": 1165, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_BLENDFACTOR_ONE_MINUS_CONSTANT_COLOR", - "start_line": 1165, - "type": "Int", - "value": 12 - }, - "13": { - "brief_comment": "min(source alpha, 1 - destination alpha)", - "end_line": 1166, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_BLENDFACTOR_SRC_ALPHA_SATURATE", - "start_line": 1166, - "type": "Int", - "value": 13 - } - }, - "kind": "ENUM_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPUBlendFactor", - "start_line": 1151, - "type": "Enum" - }, - "122": { - "brief_comment": "Specifies a blending factor to be used when pixels in a render target are blended with existing pixels in the texture.", - "end_line": 1167, - "kind": "TYPEDEF_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPUBlendFactor", - "start_line": 1151, - "type": "enum SDL_GPUBlendFactor" - }, - "123": { - "brief_comment": "Specifies which color components are written in a graphics pipeline.", - "end_line": 1176, - "kind": "TYPEDEF_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPUColorComponentFlags", - "start_line": 1176, - "type": "int" - }, - "124": { - "brief_comment": "Specifies a filter operation used by a sampler.", - "end_line": 1194, - "enumerations": { - "0": { - "brief_comment": "Point filtering.", - "end_line": 1192, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_FILTER_NEAREST", - "start_line": 1192, - "type": "Int", - "value": 0 - }, - "1": { - "brief_comment": "Linear filtering.", - "end_line": 1193, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_FILTER_LINEAR", - "start_line": 1193, - "type": "Int", - "value": 1 - } - }, - "kind": "ENUM_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPUFilter", - "start_line": 1190, - "type": "Enum" - }, - "125": { - "brief_comment": "Specifies a filter operation used by a sampler.", - "end_line": 1194, - "kind": "TYPEDEF_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPUFilter", - "start_line": 1190, - "type": "enum SDL_GPUFilter" - }, - "126": { - "brief_comment": "Specifies a mipmap mode used by a sampler.", - "end_line": 1207, - "enumerations": { - "0": { - "brief_comment": "Point filtering.", - "end_line": 1205, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_SAMPLERMIPMAPMODE_NEAREST", - "start_line": 1205, - "type": "Int", - "value": 0 - }, - "1": { - "brief_comment": "Linear filtering.", - "end_line": 1206, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_SAMPLERMIPMAPMODE_LINEAR", - "start_line": 1206, - "type": "Int", - "value": 1 - } - }, - "kind": "ENUM_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPUSamplerMipmapMode", - "start_line": 1203, - "type": "Enum" - }, - "127": { - "brief_comment": "Specifies a mipmap mode used by a sampler.", - "end_line": 1207, - "kind": "TYPEDEF_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPUSamplerMipmapMode", - "start_line": 1203, - "type": "enum SDL_GPUSamplerMipmapMode" - }, - "128": { - "brief_comment": "Specifies behavior of texture sampling when the coordinates exceed the 0-1 range.", - "end_line": 1222, - "enumerations": { - "0": { - "brief_comment": "Specifies that the coordinates will wrap around.", - "end_line": 1219, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_SAMPLERADDRESSMODE_REPEAT", - "start_line": 1219, - "type": "Int", - "value": 0 - }, - "1": { - "brief_comment": "Specifies that the coordinates will wrap around mirrored.", - "end_line": 1220, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_SAMPLERADDRESSMODE_MIRRORED_REPEAT", - "start_line": 1220, - "type": "Int", - "value": 1 - }, - "2": { - "brief_comment": "Specifies that the coordinates will clamp to the 0-1 range.", - "end_line": 1221, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_SAMPLERADDRESSMODE_CLAMP_TO_EDGE", - "start_line": 1221, - "type": "Int", - "value": 2 - } - }, - "kind": "ENUM_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPUSamplerAddressMode", - "start_line": 1217, - "type": "Enum" - }, - "129": { - "brief_comment": "Specifies behavior of texture sampling when the coordinates exceed the 0-1 range.", - "end_line": 1222, - "kind": "TYPEDEF_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPUSamplerAddressMode", - "start_line": 1217, - "type": "enum SDL_GPUSamplerAddressMode" - }, - "130": { - "brief_comment": "Specifies the timing that will be used to present swapchain textures to the OS.", - "end_line": 1254, - "enumerations": { - "0": { - "brief_comment": null, - "end_line": 1251, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_PRESENTMODE_VSYNC", - "start_line": 1251, - "type": "Int", - "value": 0 - }, - "1": { - "brief_comment": null, - "end_line": 1252, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_PRESENTMODE_IMMEDIATE", - "start_line": 1252, - "type": "Int", - "value": 1 - }, - "2": { - "brief_comment": null, - "end_line": 1253, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_PRESENTMODE_MAILBOX", - "start_line": 1253, - "type": "Int", - "value": 2 - } - }, - "kind": "ENUM_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPUPresentMode", - "start_line": 1249, - "type": "Enum" - }, - "131": { - "brief_comment": "Specifies the timing that will be used to present swapchain textures to the OS.", - "end_line": 1254, - "kind": "TYPEDEF_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPUPresentMode", - "start_line": 1249, - "type": "enum SDL_GPUPresentMode" - }, - "132": { - "brief_comment": "Specifies the texture format and colorspace of the swapchain textures.", - "end_line": 1288, - "enumerations": { - "0": { - "brief_comment": null, - "end_line": 1284, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_SWAPCHAINCOMPOSITION_SDR", - "start_line": 1284, - "type": "Int", - "value": 0 - }, - "1": { - "brief_comment": null, - "end_line": 1285, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_SWAPCHAINCOMPOSITION_SDR_LINEAR", - "start_line": 1285, - "type": "Int", - "value": 1 - }, - "2": { - "brief_comment": null, - "end_line": 1286, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_SWAPCHAINCOMPOSITION_HDR_EXTENDED_LINEAR", - "start_line": 1286, - "type": "Int", - "value": 2 - }, - "3": { - "brief_comment": null, - "end_line": 1287, - "kind": "ENUM_CONSTANT_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPU_SWAPCHAINCOMPOSITION_HDR10_ST2084", - "start_line": 1287, - "type": "Int", - "value": 3 - } - }, - "kind": "ENUM_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPUSwapchainComposition", - "start_line": 1282, - "type": "Enum" - }, - "133": { - "brief_comment": "Specifies the texture format and colorspace of the swapchain textures.", - "end_line": 1288, - "kind": "TYPEDEF_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPUSwapchainComposition", - "start_line": 1282, - "type": "enum SDL_GPUSwapchainComposition" - }, - "134": { - "brief_comment": "A structure specifying a viewport.", - "end_line": 1307, - "kind": "STRUCT_DECL", - "location": "SDL_gpu.h", - "members": { - "0": { - "brief_comment": "The left offset of the viewport.", - "end_line": 1301, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "x", - "start_line": 1301, - "type": "Float" - }, - "1": { - "brief_comment": "The top offset of the viewport.", - "end_line": 1302, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "y", - "start_line": 1302, - "type": "Float" - }, - "2": { - "brief_comment": "The width of the viewport.", - "end_line": 1303, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "w", - "start_line": 1303, - "type": "Float" - }, - "3": { - "brief_comment": "The height of the viewport.", - "end_line": 1304, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "h", - "start_line": 1304, - "type": "Float" - }, - "4": { - "brief_comment": "The minimum depth of the viewport.", - "end_line": 1305, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "min_depth", - "start_line": 1305, - "type": "Float" - }, - "5": { - "brief_comment": "The maximum depth of the viewport.", - "end_line": 1306, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "max_depth", - "start_line": 1306, - "type": "Float" - } - }, - "result_type": "Invalid", - "spelling": "SDL_GPUViewport", - "start_line": 1299, - "type": "Record" - }, - "135": { - "brief_comment": "A structure specifying a viewport.", - "end_line": 1307, - "kind": "TYPEDEF_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPUViewport", - "start_line": 1299, - "type": "struct SDL_GPUViewport" - }, - "136": { - "brief_comment": "A structure specifying parameters related to transferring data to or from a texture.", - "end_line": 1324, - "kind": "STRUCT_DECL", - "location": "SDL_gpu.h", - "members": { - "0": { - "brief_comment": "The transfer buffer used in the transfer operation.", - "end_line": 1320, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "transfer_buffer", - "start_line": 1320, - "type": "Pointer" - }, - "1": { - "brief_comment": "The starting byte of the image data in the transfer buffer.", - "end_line": 1321, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "offset", - "start_line": 1321, - "type": "Int" - }, - "2": { - "brief_comment": "The number of pixels from one row to the next.", - "end_line": 1322, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "pixels_per_row", - "start_line": 1322, - "type": "Int" - }, - "3": { - "brief_comment": "The number of rows from one layer/depth-slice to the next.", - "end_line": 1323, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "rows_per_layer", - "start_line": 1323, - "type": "Int" - } - }, - "result_type": "Invalid", - "spelling": "SDL_GPUTextureTransferInfo", - "start_line": 1318, - "type": "Record" - }, - "137": { - "brief_comment": "A structure specifying parameters related to transferring data to or from a texture.", - "end_line": 1324, - "kind": "TYPEDEF_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPUTextureTransferInfo", - "start_line": 1318, - "type": "struct SDL_GPUTextureTransferInfo" - }, - "138": { - "brief_comment": "A structure specifying a location in a transfer buffer.", - "end_line": 1340, - "kind": "STRUCT_DECL", - "location": "SDL_gpu.h", - "members": { - "0": { - "brief_comment": "The transfer buffer used in the transfer operation.", - "end_line": 1338, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "transfer_buffer", - "start_line": 1338, - "type": "Pointer" - }, - "1": { - "brief_comment": "The starting byte of the buffer data in the transfer buffer.", - "end_line": 1339, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "offset", - "start_line": 1339, - "type": "Int" - } - }, - "result_type": "Invalid", - "spelling": "SDL_GPUTransferBufferLocation", - "start_line": 1336, - "type": "Record" - }, - "139": { - "brief_comment": "A structure specifying a location in a transfer buffer.", - "end_line": 1340, - "kind": "TYPEDEF_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPUTransferBufferLocation", - "start_line": 1336, - "type": "struct SDL_GPUTransferBufferLocation" - }, - "140": { - "brief_comment": "A structure specifying a location in a texture.", - "end_line": 1359, - "kind": "STRUCT_DECL", - "location": "SDL_gpu.h", - "members": { - "0": { - "brief_comment": "The texture used in the copy operation.", - "end_line": 1353, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "texture", - "start_line": 1353, - "type": "Pointer" - }, - "1": { - "brief_comment": "The mip level index of the location.", - "end_line": 1354, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "mip_level", - "start_line": 1354, - "type": "Int" - }, - "2": { - "brief_comment": "The layer index of the location.", - "end_line": 1355, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "layer", - "start_line": 1355, - "type": "Int" - }, - "3": { - "brief_comment": "The left offset of the location.", - "end_line": 1356, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "x", - "start_line": 1356, - "type": "Int" - }, - "4": { - "brief_comment": "The top offset of the location.", - "end_line": 1357, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "y", - "start_line": 1357, - "type": "Int" - }, - "5": { - "brief_comment": "The front offset of the location.", - "end_line": 1358, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "z", - "start_line": 1358, - "type": "Int" - } - }, - "result_type": "Invalid", - "spelling": "SDL_GPUTextureLocation", - "start_line": 1351, - "type": "Record" - }, - "141": { - "brief_comment": "A structure specifying a location in a texture.", - "end_line": 1359, - "kind": "TYPEDEF_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPUTextureLocation", - "start_line": 1351, - "type": "struct SDL_GPUTextureLocation" - }, - "142": { - "brief_comment": "A structure specifying a region of a texture.", - "end_line": 1383, - "kind": "STRUCT_DECL", - "location": "SDL_gpu.h", - "members": { - "0": { - "brief_comment": "The texture used in the copy operation.", - "end_line": 1374, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "texture", - "start_line": 1374, - "type": "Pointer" - }, - "1": { - "brief_comment": "The mip level index to transfer.", - "end_line": 1375, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "mip_level", - "start_line": 1375, - "type": "Int" - }, - "2": { - "brief_comment": "The layer index to transfer.", - "end_line": 1376, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "layer", - "start_line": 1376, - "type": "Int" - }, - "3": { - "brief_comment": "The left offset of the region.", - "end_line": 1377, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "x", - "start_line": 1377, - "type": "Int" - }, - "4": { - "brief_comment": "The top offset of the region.", - "end_line": 1378, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "y", - "start_line": 1378, - "type": "Int" - }, - "5": { - "brief_comment": "The front offset of the region.", - "end_line": 1379, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "z", - "start_line": 1379, - "type": "Int" - }, - "6": { - "brief_comment": "The width of the region.", - "end_line": 1380, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "w", - "start_line": 1380, - "type": "Int" - }, - "7": { - "brief_comment": "The height of the region.", - "end_line": 1381, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "h", - "start_line": 1381, - "type": "Int" - }, - "8": { - "brief_comment": "The depth of the region.", - "end_line": 1382, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "d", - "start_line": 1382, - "type": "Int" - } - }, - "result_type": "Invalid", - "spelling": "SDL_GPUTextureRegion", - "start_line": 1372, - "type": "Record" - }, - "143": { - "brief_comment": "A structure specifying a region of a texture.", - "end_line": 1383, - "kind": "TYPEDEF_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPUTextureRegion", - "start_line": 1372, - "type": "struct SDL_GPUTextureRegion" - }, - "144": { - "brief_comment": "A structure specifying a region of a texture used in the blit operation.", - "end_line": 1401, - "kind": "STRUCT_DECL", - "location": "SDL_gpu.h", - "members": { - "0": { - "brief_comment": "The texture.", - "end_line": 1394, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "texture", - "start_line": 1394, - "type": "Pointer" - }, - "1": { - "brief_comment": "The mip level index of the region.", - "end_line": 1395, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "mip_level", - "start_line": 1395, - "type": "Int" - }, - "2": { - "brief_comment": "The layer index or depth plane of the region. This value is treated as a layer index on 2D array and cube textures, and as a depth plane on 3D textures.", - "end_line": 1396, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "layer_or_depth_plane", - "start_line": 1396, - "type": "Int" - }, - "3": { - "brief_comment": "The left offset of the region.", - "end_line": 1397, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "x", - "start_line": 1397, - "type": "Int" - }, - "4": { - "brief_comment": "The top offset of the region.", - "end_line": 1398, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "y", - "start_line": 1398, - "type": "Int" - }, - "5": { - "brief_comment": "The width of the region.", - "end_line": 1399, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "w", - "start_line": 1399, - "type": "Int" - }, - "6": { - "brief_comment": "The height of the region.", - "end_line": 1400, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "h", - "start_line": 1400, - "type": "Int" - } - }, - "result_type": "Invalid", - "spelling": "SDL_GPUBlitRegion", - "start_line": 1392, - "type": "Record" - }, - "145": { - "brief_comment": "A structure specifying a region of a texture used in the blit operation.", - "end_line": 1401, - "kind": "TYPEDEF_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPUBlitRegion", - "start_line": 1392, - "type": "struct SDL_GPUBlitRegion" - }, - "146": { - "brief_comment": "A structure specifying a location in a buffer.", - "end_line": 1416, - "kind": "STRUCT_DECL", - "location": "SDL_gpu.h", - "members": { - "0": { - "brief_comment": "The buffer.", - "end_line": 1414, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "buffer", - "start_line": 1414, - "type": "Pointer" - }, - "1": { - "brief_comment": "The starting byte within the buffer.", - "end_line": 1415, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "offset", - "start_line": 1415, - "type": "Int" - } - }, - "result_type": "Invalid", - "spelling": "SDL_GPUBufferLocation", - "start_line": 1412, - "type": "Record" - }, - "147": { - "brief_comment": "A structure specifying a location in a buffer.", - "end_line": 1416, - "kind": "TYPEDEF_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPUBufferLocation", - "start_line": 1412, - "type": "struct SDL_GPUBufferLocation" - }, - "148": { - "brief_comment": "A structure specifying a region of a buffer.", - "end_line": 1433, - "kind": "STRUCT_DECL", - "location": "SDL_gpu.h", - "members": { - "0": { - "brief_comment": "The buffer.", - "end_line": 1430, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "buffer", - "start_line": 1430, - "type": "Pointer" - }, - "1": { - "brief_comment": "The starting byte within the buffer.", - "end_line": 1431, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "offset", - "start_line": 1431, - "type": "Int" - }, - "2": { - "brief_comment": "The size in bytes of the region.", - "end_line": 1432, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "size", - "start_line": 1432, - "type": "Int" - } - }, - "result_type": "Invalid", - "spelling": "SDL_GPUBufferRegion", - "start_line": 1428, - "type": "Record" - }, - "149": { - "brief_comment": "A structure specifying a region of a buffer.", - "end_line": 1433, - "kind": "TYPEDEF_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPUBufferRegion", - "start_line": 1428, - "type": "struct SDL_GPUBufferRegion" - }, - "150": { - "brief_comment": "A structure specifying the parameters of an indirect draw command.", - "end_line": 1455, - "kind": "STRUCT_DECL", - "location": "SDL_gpu.h", - "members": { - "0": { - "brief_comment": "The number of vertices to draw.", - "end_line": 1451, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "num_vertices", - "start_line": 1451, - "type": "Int" - }, - "1": { - "brief_comment": "The number of instances to draw.", - "end_line": 1452, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "num_instances", - "start_line": 1452, - "type": "Int" - }, - "2": { - "brief_comment": "The index of the first vertex to draw.", - "end_line": 1453, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "first_vertex", - "start_line": 1453, - "type": "Int" - }, - "3": { - "brief_comment": "The ID of the first instance to draw.", - "end_line": 1454, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "first_instance", - "start_line": 1454, - "type": "Int" - } - }, - "result_type": "Invalid", - "spelling": "SDL_GPUIndirectDrawCommand", - "start_line": 1449, - "type": "Record" - }, - "151": { - "brief_comment": "A structure specifying the parameters of an indirect draw command.", - "end_line": 1455, - "kind": "TYPEDEF_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPUIndirectDrawCommand", - "start_line": 1449, - "type": "struct SDL_GPUIndirectDrawCommand" - }, - "152": { - "brief_comment": "A structure specifying the parameters of an indexed indirect draw command.", - "end_line": 1478, - "kind": "STRUCT_DECL", - "location": "SDL_gpu.h", - "members": { - "0": { - "brief_comment": "The number of indices to draw per instance.", - "end_line": 1473, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "num_indices", - "start_line": 1473, - "type": "Int" - }, - "1": { - "brief_comment": "The number of instances to draw.", - "end_line": 1474, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "num_instances", - "start_line": 1474, - "type": "Int" - }, - "2": { - "brief_comment": "The base index within the index buffer.", - "end_line": 1475, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "first_index", - "start_line": 1475, - "type": "Int" - }, - "3": { - "brief_comment": "The value added to the vertex index before indexing into the vertex buffer.", - "end_line": 1476, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "vertex_offset", - "start_line": 1476, - "type": "Int" - }, - "4": { - "brief_comment": "The ID of the first instance to draw.", - "end_line": 1477, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "first_instance", - "start_line": 1477, - "type": "Int" - } - }, - "result_type": "Invalid", - "spelling": "SDL_GPUIndexedIndirectDrawCommand", - "start_line": 1471, - "type": "Record" - }, - "153": { - "brief_comment": "A structure specifying the parameters of an indexed indirect draw command.", - "end_line": 1478, - "kind": "TYPEDEF_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPUIndexedIndirectDrawCommand", - "start_line": 1471, - "type": "struct SDL_GPUIndexedIndirectDrawCommand" - }, - "154": { - "brief_comment": "A structure specifying the parameters of an indexed dispatch command.", - "end_line": 1492, - "kind": "STRUCT_DECL", - "location": "SDL_gpu.h", - "members": { - "0": { - "brief_comment": "The number of local workgroups to dispatch in the X dimension.", - "end_line": 1489, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "groupcount_x", - "start_line": 1489, - "type": "Int" - }, - "1": { - "brief_comment": "The number of local workgroups to dispatch in the Y dimension.", - "end_line": 1490, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "groupcount_y", - "start_line": 1490, - "type": "Int" - }, - "2": { - "brief_comment": "The number of local workgroups to dispatch in the Z dimension.", - "end_line": 1491, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "groupcount_z", - "start_line": 1491, - "type": "Int" - } - }, - "result_type": "Invalid", - "spelling": "SDL_GPUIndirectDispatchCommand", - "start_line": 1487, - "type": "Record" - }, - "155": { - "brief_comment": "A structure specifying the parameters of an indexed dispatch command.", - "end_line": 1492, - "kind": "TYPEDEF_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPUIndirectDispatchCommand", - "start_line": 1487, - "type": "struct SDL_GPUIndirectDispatchCommand" - }, - "156": { - "brief_comment": "A structure specifying the parameters of a sampler.", - "end_line": 1529, - "kind": "STRUCT_DECL", - "location": "SDL_gpu.h", - "members": { - "0": { - "brief_comment": "The minification filter to apply to lookups.", - "end_line": 1512, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "min_filter", - "start_line": 1512, - "type": "SDL_GPUFilter" - }, - "1": { - "brief_comment": "The magnification filter to apply to lookups.", - "end_line": 1513, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "mag_filter", - "start_line": 1513, - "type": "SDL_GPUFilter" - }, - "2": { - "brief_comment": "The mipmap filter to apply to lookups.", - "end_line": 1514, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "mipmap_mode", - "start_line": 1514, - "type": "SDL_GPUSamplerMipmapMode" - }, - "3": { - "brief_comment": "The addressing mode for U coordinates outside [0, 1).", - "end_line": 1515, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "address_mode_u", - "start_line": 1515, - "type": "SDL_GPUSamplerAddressMode" - }, - "4": { - "brief_comment": "The addressing mode for V coordinates outside [0, 1).", - "end_line": 1516, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "address_mode_v", - "start_line": 1516, - "type": "SDL_GPUSamplerAddressMode" - }, - "5": { - "brief_comment": "The addressing mode for W coordinates outside [0, 1).", - "end_line": 1517, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "address_mode_w", - "start_line": 1517, - "type": "SDL_GPUSamplerAddressMode" - }, - "6": { - "brief_comment": "The bias to be added to mipmap LOD calculation.", - "end_line": 1518, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "mip_lod_bias", - "start_line": 1518, - "type": "Float" - }, - "7": { - "brief_comment": "The anisotropy value clamp used by the sampler. If enable_anisotropy is false, this is ignored.", - "end_line": 1519, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "max_anisotropy", - "start_line": 1519, - "type": "Float" - }, - "8": { - "brief_comment": "The comparison operator to apply to fetched data before filtering.", - "end_line": 1520, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "compare_op", - "start_line": 1520, - "type": "SDL_GPUCompareOp" - }, - "9": { - "brief_comment": "Clamps the minimum of the computed LOD value.", - "end_line": 1521, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "min_lod", - "start_line": 1521, - "type": "Float" - }, - "10": { - "brief_comment": "Clamps the maximum of the computed LOD value.", - "end_line": 1522, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "max_lod", - "start_line": 1522, - "type": "Float" - }, - "11": { - "brief_comment": "true to enable anisotropic filtering.", - "end_line": 1523, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "enable_anisotropy", - "start_line": 1523, - "type": "Int" - }, - "12": { - "brief_comment": "true to enable comparison against a reference value during lookups.", - "end_line": 1524, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "enable_compare", - "start_line": 1524, - "type": "Int" - }, - "13": { - "brief_comment": null, - "end_line": 1525, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "padding1", - "start_line": 1525, - "type": "Int" - }, - "14": { - "brief_comment": null, - "end_line": 1526, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "padding2", - "start_line": 1526, - "type": "Int" - }, - "15": { - "brief_comment": "A properties ID for extensions. Should be 0 if no extensions are needed.", - "end_line": 1528, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "props", - "start_line": 1528, - "type": "Int" - } - }, - "result_type": "Invalid", - "spelling": "SDL_GPUSamplerCreateInfo", - "start_line": 1510, - "type": "Record" - }, - "157": { - "brief_comment": "A structure specifying the parameters of a sampler.", - "end_line": 1529, - "kind": "TYPEDEF_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPUSamplerCreateInfo", - "start_line": 1510, - "type": "struct SDL_GPUSamplerCreateInfo" - }, - "158": { - "brief_comment": "A structure specifying the parameters of vertex buffers used in a graphics pipeline.", - "end_line": 1555, - "kind": "STRUCT_DECL", - "location": "SDL_gpu.h", - "members": { - "0": { - "brief_comment": "The binding slot of the vertex buffer.", - "end_line": 1551, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "slot", - "start_line": 1551, - "type": "Int" - }, - "1": { - "brief_comment": "The byte pitch between consecutive elements of the vertex buffer.", - "end_line": 1552, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "pitch", - "start_line": 1552, - "type": "Int" - }, - "2": { - "brief_comment": "Whether attribute addressing is a function of the vertex index or instance index.", - "end_line": 1553, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "input_rate", - "start_line": 1553, - "type": "SDL_GPUVertexInputRate" - }, - "3": { - "brief_comment": "Reserved for future use. Must be set to 0.", - "end_line": 1554, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "instance_step_rate", - "start_line": 1554, - "type": "Int" - } - }, - "result_type": "Invalid", - "spelling": "SDL_GPUVertexBufferDescription", - "start_line": 1549, - "type": "Record" - }, - "159": { - "brief_comment": "A structure specifying the parameters of vertex buffers used in a graphics pipeline.", - "end_line": 1555, - "kind": "TYPEDEF_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPUVertexBufferDescription", - "start_line": 1549, - "type": "struct SDL_GPUVertexBufferDescription" - }, - "160": { - "brief_comment": "A structure specifying a vertex attribute.", - "end_line": 1575, - "kind": "STRUCT_DECL", - "location": "SDL_gpu.h", - "members": { - "0": { - "brief_comment": "The shader input location index.", - "end_line": 1571, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "location", - "start_line": 1571, - "type": "Int" - }, - "1": { - "brief_comment": "The binding slot of the associated vertex buffer.", - "end_line": 1572, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "buffer_slot", - "start_line": 1572, - "type": "Int" - }, - "2": { - "brief_comment": "The size and type of the attribute data.", - "end_line": 1573, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "format", - "start_line": 1573, - "type": "SDL_GPUVertexElementFormat" - }, - "3": { - "brief_comment": "The byte offset of this attribute relative to the start of the vertex element.", - "end_line": 1574, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "offset", - "start_line": 1574, - "type": "Int" - } - }, - "result_type": "Invalid", - "spelling": "SDL_GPUVertexAttribute", - "start_line": 1569, - "type": "Record" - }, - "161": { - "brief_comment": "A structure specifying a vertex attribute.", - "end_line": 1575, - "kind": "TYPEDEF_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPUVertexAttribute", - "start_line": 1569, - "type": "struct SDL_GPUVertexAttribute" - }, - "162": { - "brief_comment": "A structure specifying the parameters of a graphics pipeline vertex input state.", - "end_line": 1593, - "kind": "STRUCT_DECL", - "location": "SDL_gpu.h", - "members": { - "0": { - "brief_comment": "A pointer to an array of vertex buffer descriptions.", - "end_line": 1589, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "vertex_buffer_descriptions", - "start_line": 1589, - "type": "Pointer" - }, - "1": { - "brief_comment": "The number of vertex buffer descriptions in the above array.", - "end_line": 1590, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "num_vertex_buffers", - "start_line": 1590, - "type": "Int" - }, - "2": { - "brief_comment": "A pointer to an array of vertex attribute descriptions.", - "end_line": 1591, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "vertex_attributes", - "start_line": 1591, - "type": "Pointer" - }, - "3": { - "brief_comment": "The number of vertex attribute descriptions in the above array.", - "end_line": 1592, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "num_vertex_attributes", - "start_line": 1592, - "type": "Int" - } - }, - "result_type": "Invalid", - "spelling": "SDL_GPUVertexInputState", - "start_line": 1587, - "type": "Record" - }, - "163": { - "brief_comment": "A structure specifying the parameters of a graphics pipeline vertex input state.", - "end_line": 1593, - "kind": "TYPEDEF_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPUVertexInputState", - "start_line": 1587, - "type": "struct SDL_GPUVertexInputState" - }, - "164": { - "brief_comment": "A structure specifying the stencil operation state of a graphics pipeline.", - "end_line": 1608, - "kind": "STRUCT_DECL", - "location": "SDL_gpu.h", - "members": { - "0": { - "brief_comment": "The action performed on samples that fail the stencil test.", - "end_line": 1604, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "fail_op", - "start_line": 1604, - "type": "SDL_GPUStencilOp" - }, - "1": { - "brief_comment": "The action performed on samples that pass the depth and stencil tests.", - "end_line": 1605, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "pass_op", - "start_line": 1605, - "type": "SDL_GPUStencilOp" - }, - "2": { - "brief_comment": "The action performed on samples that pass the stencil test and fail the depth test.", - "end_line": 1606, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "depth_fail_op", - "start_line": 1606, - "type": "SDL_GPUStencilOp" - }, - "3": { - "brief_comment": "The comparison operator used in the stencil test.", - "end_line": 1607, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "compare_op", - "start_line": 1607, - "type": "SDL_GPUCompareOp" - } - }, - "result_type": "Invalid", - "spelling": "SDL_GPUStencilOpState", - "start_line": 1602, - "type": "Record" - }, - "165": { - "brief_comment": "A structure specifying the stencil operation state of a graphics pipeline.", - "end_line": 1608, - "kind": "TYPEDEF_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPUStencilOpState", - "start_line": 1602, - "type": "struct SDL_GPUStencilOpState" - }, - "166": { - "brief_comment": "A structure specifying the blend state of a color target.", - "end_line": 1630, - "kind": "STRUCT_DECL", - "location": "SDL_gpu.h", - "members": { - "0": { - "brief_comment": "The value to be multiplied by the source RGB value.", - "end_line": 1619, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "src_color_blendfactor", - "start_line": 1619, - "type": "SDL_GPUBlendFactor" - }, - "1": { - "brief_comment": "The value to be multiplied by the destination RGB value.", - "end_line": 1620, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "dst_color_blendfactor", - "start_line": 1620, - "type": "SDL_GPUBlendFactor" - }, - "2": { - "brief_comment": "The blend operation for the RGB components.", - "end_line": 1621, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "color_blend_op", - "start_line": 1621, - "type": "SDL_GPUBlendOp" - }, - "3": { - "brief_comment": "The value to be multiplied by the source alpha.", - "end_line": 1622, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "src_alpha_blendfactor", - "start_line": 1622, - "type": "SDL_GPUBlendFactor" - }, - "4": { - "brief_comment": "The value to be multiplied by the destination alpha.", - "end_line": 1623, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "dst_alpha_blendfactor", - "start_line": 1623, - "type": "SDL_GPUBlendFactor" - }, - "5": { - "brief_comment": "The blend operation for the alpha component.", - "end_line": 1624, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "alpha_blend_op", - "start_line": 1624, - "type": "SDL_GPUBlendOp" - }, - "6": { - "brief_comment": "A bitmask specifying which of the RGBA components are enabled for writing. Writes to all channels if enable_color_write_mask is false.", - "end_line": 1625, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "color_write_mask", - "start_line": 1625, - "type": "SDL_GPUColorComponentFlags" - }, - "7": { - "brief_comment": "Whether blending is enabled for the color target.", - "end_line": 1626, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "enable_blend", - "start_line": 1626, - "type": "Int" - }, - "8": { - "brief_comment": "Whether the color write mask is enabled.", - "end_line": 1627, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "enable_color_write_mask", - "start_line": 1627, - "type": "Int" - }, - "9": { - "brief_comment": null, - "end_line": 1628, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "padding1", - "start_line": 1628, - "type": "Int" - }, - "10": { - "brief_comment": null, - "end_line": 1629, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "padding2", - "start_line": 1629, - "type": "Int" - } - }, - "result_type": "Invalid", - "spelling": "SDL_GPUColorTargetBlendState", - "start_line": 1617, - "type": "Record" - }, - "167": { - "brief_comment": "A structure specifying the blend state of a color target.", - "end_line": 1630, - "kind": "TYPEDEF_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPUColorTargetBlendState", - "start_line": 1617, - "type": "struct SDL_GPUColorTargetBlendState" - }, - "168": { - "brief_comment": "A structure specifying code and metadata for creating a shader object.", - "end_line": 1653, - "kind": "STRUCT_DECL", - "location": "SDL_gpu.h", - "members": { - "0": { - "brief_comment": "The size in bytes of the code pointed to.", - "end_line": 1642, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "code_size", - "start_line": 1642, - "type": "size_t" - }, - "1": { - "brief_comment": "A pointer to shader code.", - "end_line": 1643, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "code", - "start_line": 1643, - "type": "Pointer" - }, - "2": { - "brief_comment": "A pointer to a null-terminated UTF-8 string specifying the entry point function name for the shader.", - "end_line": 1644, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "entrypoint", - "start_line": 1644, - "type": "Pointer" - }, - "3": { - "brief_comment": "The format of the shader code.", - "end_line": 1645, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "format", - "start_line": 1645, - "type": "SDL_GPUShaderFormat" - }, - "4": { - "brief_comment": "The stage the shader program corresponds to.", - "end_line": 1646, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "stage", - "start_line": 1646, - "type": "SDL_GPUShaderStage" - }, - "5": { - "brief_comment": "The number of samplers defined in the shader.", - "end_line": 1647, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "num_samplers", - "start_line": 1647, - "type": "Int" - }, - "6": { - "brief_comment": "The number of storage textures defined in the shader.", - "end_line": 1648, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "num_storage_textures", - "start_line": 1648, - "type": "Int" - }, - "7": { - "brief_comment": "The number of storage buffers defined in the shader.", - "end_line": 1649, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "num_storage_buffers", - "start_line": 1649, - "type": "Int" - }, - "8": { - "brief_comment": "The number of uniform buffers defined in the shader.", - "end_line": 1650, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "num_uniform_buffers", - "start_line": 1650, - "type": "Int" - }, - "9": { - "brief_comment": "A properties ID for extensions. Should be 0 if no extensions are needed.", - "end_line": 1652, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "props", - "start_line": 1652, - "type": "Int" - } - }, - "result_type": "Invalid", - "spelling": "SDL_GPUShaderCreateInfo", - "start_line": 1640, - "type": "Record" - }, - "169": { - "brief_comment": "A structure specifying code and metadata for creating a shader object.", - "end_line": 1653, - "kind": "TYPEDEF_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPUShaderCreateInfo", - "start_line": 1640, - "type": "struct SDL_GPUShaderCreateInfo" - }, - "170": { - "brief_comment": "A structure specifying the parameters of a texture.", - "end_line": 1682, - "kind": "STRUCT_DECL", - "location": "SDL_gpu.h", - "members": { - "0": { - "brief_comment": "The base dimensionality of the texture.", - "end_line": 1672, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "type", - "start_line": 1672, - "type": "SDL_GPUTextureType" - }, - "1": { - "brief_comment": "The pixel format of the texture.", - "end_line": 1673, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "format", - "start_line": 1673, - "type": "SDL_GPUTextureFormat" - }, - "2": { - "brief_comment": "How the texture is intended to be used by the client.", - "end_line": 1674, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "usage", - "start_line": 1674, - "type": "SDL_GPUTextureUsageFlags" - }, - "3": { - "brief_comment": "The width of the texture.", - "end_line": 1675, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "width", - "start_line": 1675, - "type": "Int" - }, - "4": { - "brief_comment": "The height of the texture.", - "end_line": 1676, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "height", - "start_line": 1676, - "type": "Int" - }, - "5": { - "brief_comment": "The layer count or depth of the texture. This value is treated as a layer count on 2D array textures, and as a depth value on 3D textures.", - "end_line": 1677, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "layer_count_or_depth", - "start_line": 1677, - "type": "Int" - }, - "6": { - "brief_comment": "The number of mip levels in the texture.", - "end_line": 1678, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "num_levels", - "start_line": 1678, - "type": "Int" - }, - "7": { - "brief_comment": "The number of samples per texel. Only applies if the texture is used as a render target.", - "end_line": 1679, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "sample_count", - "start_line": 1679, - "type": "SDL_GPUSampleCount" - }, - "8": { - "brief_comment": "A properties ID for extensions. Should be 0 if no extensions are needed.", - "end_line": 1681, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "props", - "start_line": 1681, - "type": "Int" - } - }, - "result_type": "Invalid", - "spelling": "SDL_GPUTextureCreateInfo", - "start_line": 1670, - "type": "Record" - }, - "171": { - "brief_comment": "A structure specifying the parameters of a texture.", - "end_line": 1682, - "kind": "TYPEDEF_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPUTextureCreateInfo", - "start_line": 1670, - "type": "struct SDL_GPUTextureCreateInfo" - }, - "172": { - "brief_comment": "A structure specifying the parameters of a buffer.", - "end_line": 1701, - "kind": "STRUCT_DECL", - "location": "SDL_gpu.h", - "members": { - "0": { - "brief_comment": "How the buffer is intended to be used by the client.", - "end_line": 1697, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "usage", - "start_line": 1697, - "type": "SDL_GPUBufferUsageFlags" - }, - "1": { - "brief_comment": "The size in bytes of the buffer.", - "end_line": 1698, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "size", - "start_line": 1698, - "type": "Int" - }, - "2": { - "brief_comment": "A properties ID for extensions. Should be 0 if no extensions are needed.", - "end_line": 1700, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "props", - "start_line": 1700, - "type": "Int" - } - }, - "result_type": "Invalid", - "spelling": "SDL_GPUBufferCreateInfo", - "start_line": 1695, - "type": "Record" - }, - "173": { - "brief_comment": "A structure specifying the parameters of a buffer.", - "end_line": 1701, - "kind": "TYPEDEF_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPUBufferCreateInfo", - "start_line": 1695, - "type": "struct SDL_GPUBufferCreateInfo" - }, - "174": { - "brief_comment": "A structure specifying the parameters of a transfer buffer.", - "end_line": 1716, - "kind": "STRUCT_DECL", - "location": "SDL_gpu.h", - "members": { - "0": { - "brief_comment": "How the transfer buffer is intended to be used by the client.", - "end_line": 1712, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "usage", - "start_line": 1712, - "type": "SDL_GPUTransferBufferUsage" - }, - "1": { - "brief_comment": "The size in bytes of the transfer buffer.", - "end_line": 1713, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "size", - "start_line": 1713, - "type": "Int" - }, - "2": { - "brief_comment": "A properties ID for extensions. Should be 0 if no extensions are needed.", - "end_line": 1715, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "props", - "start_line": 1715, - "type": "Int" - } - }, - "result_type": "Invalid", - "spelling": "SDL_GPUTransferBufferCreateInfo", - "start_line": 1710, - "type": "Record" - }, - "175": { - "brief_comment": "A structure specifying the parameters of a transfer buffer.", - "end_line": 1716, - "kind": "TYPEDEF_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPUTransferBufferCreateInfo", - "start_line": 1710, - "type": "struct SDL_GPUTransferBufferCreateInfo" - }, - "176": { - "brief_comment": "A structure specifying the parameters of the graphics pipeline rasterizer state.", - "end_line": 1748, - "kind": "STRUCT_DECL", - "location": "SDL_gpu.h", - "members": { - "0": { - "brief_comment": "Whether polygons will be filled in or drawn as lines.", - "end_line": 1738, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "fill_mode", - "start_line": 1738, - "type": "SDL_GPUFillMode" - }, - "1": { - "brief_comment": "The facing direction in which triangles will be culled.", - "end_line": 1739, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "cull_mode", - "start_line": 1739, - "type": "SDL_GPUCullMode" - }, - "2": { - "brief_comment": "The vertex winding that will cause a triangle to be determined as front-facing.", - "end_line": 1740, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "front_face", - "start_line": 1740, - "type": "SDL_GPUFrontFace" - }, - "3": { - "brief_comment": "A scalar factor controlling the depth value added to each fragment.", - "end_line": 1741, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "depth_bias_constant_factor", - "start_line": 1741, - "type": "Float" - }, - "4": { - "brief_comment": "The maximum depth bias of a fragment.", - "end_line": 1742, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "depth_bias_clamp", - "start_line": 1742, - "type": "Float" - }, - "5": { - "brief_comment": "A scalar factor applied to a fragment's slope in depth calculations.", - "end_line": 1743, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "depth_bias_slope_factor", - "start_line": 1743, - "type": "Float" - }, - "6": { - "brief_comment": "true to bias fragment depth values.", - "end_line": 1744, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "enable_depth_bias", - "start_line": 1744, - "type": "Int" - }, - "7": { - "brief_comment": "true to enable depth clip, false to enable depth clamp.", - "end_line": 1745, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "enable_depth_clip", - "start_line": 1745, - "type": "Int" - }, - "8": { - "brief_comment": null, - "end_line": 1746, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "padding1", - "start_line": 1746, - "type": "Int" - }, - "9": { - "brief_comment": null, - "end_line": 1747, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "padding2", - "start_line": 1747, - "type": "Int" - } - }, - "result_type": "Invalid", - "spelling": "SDL_GPURasterizerState", - "start_line": 1736, - "type": "Record" - }, - "177": { - "brief_comment": "A structure specifying the parameters of the graphics pipeline rasterizer state.", - "end_line": 1748, - "kind": "TYPEDEF_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPURasterizerState", - "start_line": 1736, - "type": "struct SDL_GPURasterizerState" - }, - "178": { - "brief_comment": "A structure specifying the parameters of the graphics pipeline multisample state.", - "end_line": 1766, - "kind": "STRUCT_DECL", - "location": "SDL_gpu.h", - "members": { - "0": { - "brief_comment": "The number of samples to be used in rasterization.", - "end_line": 1760, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "sample_count", - "start_line": 1760, - "type": "SDL_GPUSampleCount" - }, - "1": { - "brief_comment": "Reserved for future use. Must be set to 0.", - "end_line": 1761, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "sample_mask", - "start_line": 1761, - "type": "Int" - }, - "2": { - "brief_comment": "Reserved for future use. Must be set to false.", - "end_line": 1762, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "enable_mask", - "start_line": 1762, - "type": "Int" - }, - "3": { - "brief_comment": null, - "end_line": 1763, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "padding1", - "start_line": 1763, - "type": "Int" - }, - "4": { - "brief_comment": null, - "end_line": 1764, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "padding2", - "start_line": 1764, - "type": "Int" - }, - "5": { - "brief_comment": null, - "end_line": 1765, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "padding3", - "start_line": 1765, - "type": "Int" - } - }, - "result_type": "Invalid", - "spelling": "SDL_GPUMultisampleState", - "start_line": 1758, - "type": "Record" - }, - "179": { - "brief_comment": "A structure specifying the parameters of the graphics pipeline multisample state.", - "end_line": 1766, - "kind": "TYPEDEF_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPUMultisampleState", - "start_line": 1758, - "type": "struct SDL_GPUMultisampleState" - }, - "180": { - "brief_comment": "A structure specifying the parameters of the graphics pipeline depth stencil state.", - "end_line": 1789, - "kind": "STRUCT_DECL", - "location": "SDL_gpu.h", - "members": { - "0": { - "brief_comment": "The comparison operator used for depth testing.", - "end_line": 1778, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "compare_op", - "start_line": 1778, - "type": "SDL_GPUCompareOp" - }, - "1": { - "brief_comment": "The stencil op state for back-facing triangles.", - "end_line": 1779, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "back_stencil_state", - "start_line": 1779, - "type": "SDL_GPUStencilOpState" - }, - "2": { - "brief_comment": "The stencil op state for front-facing triangles.", - "end_line": 1780, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "front_stencil_state", - "start_line": 1780, - "type": "SDL_GPUStencilOpState" - }, - "3": { - "brief_comment": "Selects the bits of the stencil values participating in the stencil test.", - "end_line": 1781, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "compare_mask", - "start_line": 1781, - "type": "Int" - }, - "4": { - "brief_comment": "Selects the bits of the stencil values updated by the stencil test.", - "end_line": 1782, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "write_mask", - "start_line": 1782, - "type": "Int" - }, - "5": { - "brief_comment": "true enables the depth test.", - "end_line": 1783, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "enable_depth_test", - "start_line": 1783, - "type": "Int" - }, - "6": { - "brief_comment": "true enables depth writes. Depth writes are always disabled when enable_depth_test is false.", - "end_line": 1784, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "enable_depth_write", - "start_line": 1784, - "type": "Int" - }, - "7": { - "brief_comment": "true enables the stencil test.", - "end_line": 1785, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "enable_stencil_test", - "start_line": 1785, - "type": "Int" - }, - "8": { - "brief_comment": null, - "end_line": 1786, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "padding1", - "start_line": 1786, - "type": "Int" - }, - "9": { - "brief_comment": null, - "end_line": 1787, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "padding2", - "start_line": 1787, - "type": "Int" - }, - "10": { - "brief_comment": null, - "end_line": 1788, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "padding3", - "start_line": 1788, - "type": "Int" - } - }, - "result_type": "Invalid", - "spelling": "SDL_GPUDepthStencilState", - "start_line": 1776, - "type": "Record" - }, - "181": { - "brief_comment": "A structure specifying the parameters of the graphics pipeline depth stencil state.", - "end_line": 1789, - "kind": "TYPEDEF_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPUDepthStencilState", - "start_line": 1776, - "type": "struct SDL_GPUDepthStencilState" - }, - "182": { - "brief_comment": "A structure specifying the parameters of color targets used in a graphics pipeline.", - "end_line": 1803, - "kind": "STRUCT_DECL", - "location": "SDL_gpu.h", - "members": { - "0": { - "brief_comment": "The pixel format of the texture to be used as a color target.", - "end_line": 1801, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "format", - "start_line": 1801, - "type": "SDL_GPUTextureFormat" - }, - "1": { - "brief_comment": "The blend state to be used for the color target.", - "end_line": 1802, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "blend_state", - "start_line": 1802, - "type": "SDL_GPUColorTargetBlendState" - } - }, - "result_type": "Invalid", - "spelling": "SDL_GPUColorTargetDescription", - "start_line": 1799, - "type": "Record" - }, - "183": { - "brief_comment": "A structure specifying the parameters of color targets used in a graphics pipeline.", - "end_line": 1803, - "kind": "TYPEDEF_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPUColorTargetDescription", - "start_line": 1799, - "type": "struct SDL_GPUColorTargetDescription" - }, - "184": { - "brief_comment": "A structure specifying the descriptions of render targets used in a graphics pipeline.", - "end_line": 1824, - "kind": "STRUCT_DECL", - "location": "SDL_gpu.h", - "members": { - "0": { - "brief_comment": "A pointer to an array of color target descriptions.", - "end_line": 1817, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "color_target_descriptions", - "start_line": 1817, - "type": "Pointer" - }, - "1": { - "brief_comment": "The number of color target descriptions in the above array.", - "end_line": 1818, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "num_color_targets", - "start_line": 1818, - "type": "Int" - }, - "2": { - "brief_comment": "The pixel format of the depth-stencil target. Ignored if has_depth_stencil_target is false.", - "end_line": 1819, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "depth_stencil_format", - "start_line": 1819, - "type": "SDL_GPUTextureFormat" - }, - "3": { - "brief_comment": "true specifies that the pipeline uses a depth-stencil target.", - "end_line": 1820, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "has_depth_stencil_target", - "start_line": 1820, - "type": "Int" - }, - "4": { - "brief_comment": null, - "end_line": 1821, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "padding1", - "start_line": 1821, - "type": "Int" - }, - "5": { - "brief_comment": null, - "end_line": 1822, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "padding2", - "start_line": 1822, - "type": "Int" - }, - "6": { - "brief_comment": null, - "end_line": 1823, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "padding3", - "start_line": 1823, - "type": "Int" - } - }, - "result_type": "Invalid", - "spelling": "SDL_GPUGraphicsPipelineTargetInfo", - "start_line": 1815, - "type": "Record" - }, - "185": { - "brief_comment": "A structure specifying the descriptions of render targets used in a graphics pipeline.", - "end_line": 1824, - "kind": "TYPEDEF_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPUGraphicsPipelineTargetInfo", - "start_line": 1815, - "type": "struct SDL_GPUGraphicsPipelineTargetInfo" - }, - "186": { - "brief_comment": "A structure specifying the parameters of a graphics pipeline state.", - "end_line": 1852, - "kind": "STRUCT_DECL", - "location": "SDL_gpu.h", - "members": { - "0": { - "brief_comment": "The vertex shader used by the graphics pipeline.", - "end_line": 1842, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "vertex_shader", - "start_line": 1842, - "type": "Pointer" - }, - "1": { - "brief_comment": "The fragment shader used by the graphics pipeline.", - "end_line": 1843, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "fragment_shader", - "start_line": 1843, - "type": "Pointer" - }, - "2": { - "brief_comment": "The vertex layout of the graphics pipeline.", - "end_line": 1844, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "vertex_input_state", - "start_line": 1844, - "type": "SDL_GPUVertexInputState" - }, - "3": { - "brief_comment": "The primitive topology of the graphics pipeline.", - "end_line": 1845, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "primitive_type", - "start_line": 1845, - "type": "SDL_GPUPrimitiveType" - }, - "4": { - "brief_comment": "The rasterizer state of the graphics pipeline.", - "end_line": 1846, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "rasterizer_state", - "start_line": 1846, - "type": "SDL_GPURasterizerState" - }, - "5": { - "brief_comment": "The multisample state of the graphics pipeline.", - "end_line": 1847, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "multisample_state", - "start_line": 1847, - "type": "SDL_GPUMultisampleState" - }, - "6": { - "brief_comment": "The depth-stencil state of the graphics pipeline.", - "end_line": 1848, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "depth_stencil_state", - "start_line": 1848, - "type": "SDL_GPUDepthStencilState" - }, - "7": { - "brief_comment": "Formats and blend modes for the render targets of the graphics pipeline.", - "end_line": 1849, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "target_info", - "start_line": 1849, - "type": "SDL_GPUGraphicsPipelineTargetInfo" - }, - "8": { - "brief_comment": "A properties ID for extensions. Should be 0 if no extensions are needed.", - "end_line": 1851, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "props", - "start_line": 1851, - "type": "Int" - } - }, - "result_type": "Invalid", - "spelling": "SDL_GPUGraphicsPipelineCreateInfo", - "start_line": 1840, - "type": "Record" - }, - "187": { - "brief_comment": "A structure specifying the parameters of a graphics pipeline state.", - "end_line": 1852, - "kind": "TYPEDEF_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPUGraphicsPipelineCreateInfo", - "start_line": 1840, - "type": "struct SDL_GPUGraphicsPipelineCreateInfo" - }, - "188": { - "brief_comment": "A structure specifying the parameters of a compute pipeline state.", - "end_line": 1879, - "kind": "STRUCT_DECL", - "location": "SDL_gpu.h", - "members": { - "0": { - "brief_comment": "The size in bytes of the compute shader code pointed to.", - "end_line": 1864, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "code_size", - "start_line": 1864, - "type": "size_t" - }, - "1": { - "brief_comment": "A pointer to compute shader code.", - "end_line": 1865, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "code", - "start_line": 1865, - "type": "Pointer" - }, - "2": { - "brief_comment": "A pointer to a null-terminated UTF-8 string specifying the entry point function name for the shader.", - "end_line": 1866, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "entrypoint", - "start_line": 1866, - "type": "Pointer" - }, - "3": { - "brief_comment": "The format of the compute shader code.", - "end_line": 1867, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "format", - "start_line": 1867, - "type": "SDL_GPUShaderFormat" - }, - "4": { - "brief_comment": "The number of samplers defined in the shader.", - "end_line": 1868, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "num_samplers", - "start_line": 1868, - "type": "Int" - }, - "5": { - "brief_comment": "The number of readonly storage textures defined in the shader.", - "end_line": 1869, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "num_readonly_storage_textures", - "start_line": 1869, - "type": "Int" - }, - "6": { - "brief_comment": "The number of readonly storage buffers defined in the shader.", - "end_line": 1870, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "num_readonly_storage_buffers", - "start_line": 1870, - "type": "Int" - }, - "7": { - "brief_comment": "The number of read-write storage textures defined in the shader.", - "end_line": 1871, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "num_readwrite_storage_textures", - "start_line": 1871, - "type": "Int" - }, - "8": { - "brief_comment": "The number of read-write storage buffers defined in the shader.", - "end_line": 1872, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "num_readwrite_storage_buffers", - "start_line": 1872, - "type": "Int" - }, - "9": { - "brief_comment": "The number of uniform buffers defined in the shader.", - "end_line": 1873, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "num_uniform_buffers", - "start_line": 1873, - "type": "Int" - }, - "10": { - "brief_comment": "The number of threads in the X dimension. This should match the value in the shader.", - "end_line": 1874, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "threadcount_x", - "start_line": 1874, - "type": "Int" - }, - "11": { - "brief_comment": "The number of threads in the Y dimension. This should match the value in the shader.", - "end_line": 1875, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "threadcount_y", - "start_line": 1875, - "type": "Int" - }, - "12": { - "brief_comment": "The number of threads in the Z dimension. This should match the value in the shader.", - "end_line": 1876, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "threadcount_z", - "start_line": 1876, - "type": "Int" - }, - "13": { - "brief_comment": "A properties ID for extensions. Should be 0 if no extensions are needed.", - "end_line": 1878, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "props", - "start_line": 1878, - "type": "Int" - } - }, - "result_type": "Invalid", - "spelling": "SDL_GPUComputePipelineCreateInfo", - "start_line": 1862, - "type": "Record" - }, - "189": { - "brief_comment": "A structure specifying the parameters of a compute pipeline state.", - "end_line": 1879, - "kind": "TYPEDEF_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPUComputePipelineCreateInfo", - "start_line": 1862, - "type": "struct SDL_GPUComputePipelineCreateInfo" - }, - "190": { - "brief_comment": "A structure specifying the parameters of a color target used by a render pass.", - "end_line": 1931, - "kind": "STRUCT_DECL", - "location": "SDL_gpu.h", - "members": { - "0": { - "brief_comment": "The texture that will be used as a color target by a render pass.", - "end_line": 1918, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "texture", - "start_line": 1918, - "type": "Pointer" - }, - "1": { - "brief_comment": "The mip level to use as a color target.", - "end_line": 1919, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "mip_level", - "start_line": 1919, - "type": "Int" - }, - "2": { - "brief_comment": "The layer index or depth plane to use as a color target. This value is treated as a layer index on 2D array and cube textures, and as a depth plane on 3D textures.", - "end_line": 1920, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "layer_or_depth_plane", - "start_line": 1920, - "type": "Int" - }, - "3": { - "brief_comment": "The color to clear the color target to at the start of the render pass. Ignored if SDL_GPU_LOADOP_CLEAR is not used.", - "end_line": 1921, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "clear_color", - "start_line": 1921, - "type": "Int" - }, - "4": { - "brief_comment": "What is done with the contents of the color target at the beginning of the render pass.", - "end_line": 1922, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "load_op", - "start_line": 1922, - "type": "SDL_GPULoadOp" - }, - "5": { - "brief_comment": "What is done with the results of the render pass.", - "end_line": 1923, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "store_op", - "start_line": 1923, - "type": "SDL_GPUStoreOp" - }, - "6": { - "brief_comment": "The texture that will receive the results of a multisample resolve operation. Ignored if a RESOLVE* store_op is not used.", - "end_line": 1924, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "resolve_texture", - "start_line": 1924, - "type": "Pointer" - }, - "7": { - "brief_comment": "The mip level of the resolve texture to use for the resolve operation. Ignored if a RESOLVE* store_op is not used.", - "end_line": 1925, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "resolve_mip_level", - "start_line": 1925, - "type": "Int" - }, - "8": { - "brief_comment": "The layer index of the resolve texture to use for the resolve operation. Ignored if a RESOLVE* store_op is not used.", - "end_line": 1926, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "resolve_layer", - "start_line": 1926, - "type": "Int" - }, - "9": { - "brief_comment": "true cycles the texture if the texture is bound and load_op is not LOAD", - "end_line": 1927, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "cycle", - "start_line": 1927, - "type": "Int" - }, - "10": { - "brief_comment": "true cycles the resolve texture if the resolve texture is bound. Ignored if a RESOLVE* store_op is not used.", - "end_line": 1928, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "cycle_resolve_texture", - "start_line": 1928, - "type": "Int" - }, - "11": { - "brief_comment": null, - "end_line": 1929, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "padding1", - "start_line": 1929, - "type": "Int" - }, - "12": { - "brief_comment": null, - "end_line": 1930, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "padding2", - "start_line": 1930, - "type": "Int" - } - }, - "result_type": "Invalid", - "spelling": "SDL_GPUColorTargetInfo", - "start_line": 1916, - "type": "Record" - }, - "191": { - "brief_comment": "A structure specifying the parameters of a color target used by a render pass.", - "end_line": 1931, - "kind": "TYPEDEF_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPUColorTargetInfo", - "start_line": 1916, - "type": "struct SDL_GPUColorTargetInfo" - }, - "192": { - "brief_comment": "A structure specifying the parameters of a depth-stencil target used by a render pass.", - "end_line": 1989, - "kind": "STRUCT_DECL", - "location": "SDL_gpu.h", - "members": { - "0": { - "brief_comment": "The texture that will be used as the depth stencil target by the render pass.", - "end_line": 1979, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "texture", - "start_line": 1979, - "type": "Pointer" - }, - "1": { - "brief_comment": "The value to clear the depth component to at the beginning of the render pass. Ignored if SDL_GPU_LOADOP_CLEAR is not used.", - "end_line": 1980, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "clear_depth", - "start_line": 1980, - "type": "Float" - }, - "2": { - "brief_comment": "What is done with the depth contents at the beginning of the render pass.", - "end_line": 1981, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "load_op", - "start_line": 1981, - "type": "SDL_GPULoadOp" - }, - "3": { - "brief_comment": "What is done with the depth results of the render pass.", - "end_line": 1982, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "store_op", - "start_line": 1982, - "type": "SDL_GPUStoreOp" - }, - "4": { - "brief_comment": "What is done with the stencil contents at the beginning of the render pass.", - "end_line": 1983, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "stencil_load_op", - "start_line": 1983, - "type": "SDL_GPULoadOp" - }, - "5": { - "brief_comment": "What is done with the stencil results of the render pass.", - "end_line": 1984, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "stencil_store_op", - "start_line": 1984, - "type": "SDL_GPUStoreOp" - }, - "6": { - "brief_comment": "true cycles the texture if the texture is bound and any load ops are not LOAD", - "end_line": 1985, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "cycle", - "start_line": 1985, - "type": "Int" - }, - "7": { - "brief_comment": "The value to clear the stencil component to at the beginning of the render pass. Ignored if SDL_GPU_LOADOP_CLEAR is not used.", - "end_line": 1986, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "clear_stencil", - "start_line": 1986, - "type": "Int" - }, - "8": { - "brief_comment": null, - "end_line": 1987, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "padding1", - "start_line": 1987, - "type": "Int" - }, - "9": { - "brief_comment": null, - "end_line": 1988, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "padding2", - "start_line": 1988, - "type": "Int" - } - }, - "result_type": "Invalid", - "spelling": "SDL_GPUDepthStencilTargetInfo", - "start_line": 1977, - "type": "Record" - }, - "193": { - "brief_comment": "A structure specifying the parameters of a depth-stencil target used by a render pass.", - "end_line": 1989, - "kind": "TYPEDEF_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPUDepthStencilTargetInfo", - "start_line": 1977, - "type": "struct SDL_GPUDepthStencilTargetInfo" - }, - "194": { - "brief_comment": "A structure containing parameters for a blit command.", - "end_line": 2009, - "kind": "STRUCT_DECL", - "location": "SDL_gpu.h", - "members": { - "0": { - "brief_comment": "The source region for the blit.", - "end_line": 1999, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "source", - "start_line": 1999, - "type": "SDL_GPUBlitRegion" - }, - "1": { - "brief_comment": "The destination region for the blit.", - "end_line": 2000, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "destination", - "start_line": 2000, - "type": "SDL_GPUBlitRegion" - }, - "2": { - "brief_comment": "What is done with the contents of the destination before the blit.", - "end_line": 2001, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "load_op", - "start_line": 2001, - "type": "SDL_GPULoadOp" - }, - "3": { - "brief_comment": "The color to clear the destination region to before the blit. Ignored if load_op is not SDL_GPU_LOADOP_CLEAR.", - "end_line": 2002, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "clear_color", - "start_line": 2002, - "type": "Int" - }, - "4": { - "brief_comment": "The flip mode for the source region.", - "end_line": 2003, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "flip_mode", - "start_line": 2003, - "type": "Int" - }, - "5": { - "brief_comment": "The filter mode used when blitting.", - "end_line": 2004, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "filter", - "start_line": 2004, - "type": "SDL_GPUFilter" - }, - "6": { - "brief_comment": "true cycles the destination texture if it is already bound.", - "end_line": 2005, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "cycle", - "start_line": 2005, - "type": "Int" - }, - "7": { - "brief_comment": null, - "end_line": 2006, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "padding1", - "start_line": 2006, - "type": "Int" - }, - "8": { - "brief_comment": null, - "end_line": 2007, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "padding2", - "start_line": 2007, - "type": "Int" - }, - "9": { - "brief_comment": null, - "end_line": 2008, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "padding3", - "start_line": 2008, - "type": "Int" - } - }, - "result_type": "Invalid", - "spelling": "SDL_GPUBlitInfo", - "start_line": 1998, - "type": "Record" - }, - "195": { - "brief_comment": "A structure containing parameters for a blit command.", - "end_line": 2009, - "kind": "TYPEDEF_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPUBlitInfo", - "start_line": 1998, - "type": "struct SDL_GPUBlitInfo" - }, - "196": { - "brief_comment": "A structure specifying parameters in a buffer binding call.", - "end_line": 2025, - "kind": "STRUCT_DECL", - "location": "SDL_gpu.h", - "members": { - "0": { - "brief_comment": "The buffer to bind. Must have been created with SDL_GPU_BUFFERUSAGE_VERTEX for SDL_BindGPUVertexBuffers, or SDL_GPU_BUFFERUSAGE_INDEX for SDL_BindGPUIndexBuffer.", - "end_line": 2023, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "buffer", - "start_line": 2023, - "type": "Pointer" - }, - "1": { - "brief_comment": "The starting byte of the data to bind in the buffer.", - "end_line": 2024, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "offset", - "start_line": 2024, - "type": "Int" - } - }, - "result_type": "Invalid", - "spelling": "SDL_GPUBufferBinding", - "start_line": 2021, - "type": "Record" - }, - "197": { - "brief_comment": "A structure specifying parameters in a buffer binding call.", - "end_line": 2025, - "kind": "TYPEDEF_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPUBufferBinding", - "start_line": 2021, - "type": "struct SDL_GPUBufferBinding" - }, - "198": { - "brief_comment": "A structure specifying parameters in a sampler binding call.", - "end_line": 2039, - "kind": "STRUCT_DECL", - "location": "SDL_gpu.h", - "members": { - "0": { - "brief_comment": "The texture to bind. Must have been created with SDL_GPU_TEXTUREUSAGE_SAMPLER.", - "end_line": 2037, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "texture", - "start_line": 2037, - "type": "Pointer" - }, - "1": { - "brief_comment": "The sampler to bind.", - "end_line": 2038, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "sampler", - "start_line": 2038, - "type": "Pointer" - } - }, - "result_type": "Invalid", - "spelling": "SDL_GPUTextureSamplerBinding", - "start_line": 2035, - "type": "Record" - }, - "199": { - "brief_comment": "A structure specifying parameters in a sampler binding call.", - "end_line": 2039, - "kind": "TYPEDEF_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPUTextureSamplerBinding", - "start_line": 2035, - "type": "struct SDL_GPUTextureSamplerBinding" - }, - "200": { - "brief_comment": "A structure specifying parameters related to binding buffers in a compute pass.", - "end_line": 2056, - "kind": "STRUCT_DECL", - "location": "SDL_gpu.h", - "members": { - "0": { - "brief_comment": "The buffer to bind. Must have been created with SDL_GPU_BUFFERUSAGE_COMPUTE_STORAGE_WRITE.", - "end_line": 2051, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "buffer", - "start_line": 2051, - "type": "Pointer" - }, - "1": { - "brief_comment": "true cycles the buffer if it is already bound.", - "end_line": 2052, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "cycle", - "start_line": 2052, - "type": "Int" - }, - "2": { - "brief_comment": null, - "end_line": 2053, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "padding1", - "start_line": 2053, - "type": "Int" - }, - "3": { - "brief_comment": null, - "end_line": 2054, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "padding2", - "start_line": 2054, - "type": "Int" - }, - "4": { - "brief_comment": null, - "end_line": 2055, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "padding3", - "start_line": 2055, - "type": "Int" - } - }, - "result_type": "Invalid", - "spelling": "SDL_GPUStorageBufferReadWriteBinding", - "start_line": 2049, - "type": "Record" - }, - "201": { - "brief_comment": "A structure specifying parameters related to binding buffers in a compute pass.", - "end_line": 2056, - "kind": "TYPEDEF_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPUStorageBufferReadWriteBinding", - "start_line": 2049, - "type": "struct SDL_GPUStorageBufferReadWriteBinding" - }, - "202": { - "brief_comment": "A structure specifying parameters related to binding textures in a compute pass.", - "end_line": 2075, - "kind": "STRUCT_DECL", - "location": "SDL_gpu.h", - "members": { - "0": { - "brief_comment": "The texture to bind. Must have been created with SDL_GPU_TEXTUREUSAGE_COMPUTE_STORAGE_WRITE or SDL_GPU_TEXTUREUSAGE_COMPUTE_STORAGE_SIMULTANEOUS_READ_WRITE.", - "end_line": 2068, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "texture", - "start_line": 2068, - "type": "Pointer" - }, - "1": { - "brief_comment": "The mip level index to bind.", - "end_line": 2069, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "mip_level", - "start_line": 2069, - "type": "Int" - }, - "2": { - "brief_comment": "The layer index to bind.", - "end_line": 2070, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "layer", - "start_line": 2070, - "type": "Int" - }, - "3": { - "brief_comment": "true cycles the texture if it is already bound.", - "end_line": 2071, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "cycle", - "start_line": 2071, - "type": "Int" - }, - "4": { - "brief_comment": null, - "end_line": 2072, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "padding1", - "start_line": 2072, - "type": "Int" - }, - "5": { - "brief_comment": null, - "end_line": 2073, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "padding2", - "start_line": 2073, - "type": "Int" - }, - "6": { - "brief_comment": null, - "end_line": 2074, - "kind": "FIELD_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "padding3", - "start_line": 2074, - "type": "Int" - } - }, - "result_type": "Invalid", - "spelling": "SDL_GPUStorageTextureReadWriteBinding", - "start_line": 2066, - "type": "Record" - }, - "203": { - "brief_comment": "A structure specifying parameters related to binding textures in a compute pass.", - "end_line": 2075, - "kind": "TYPEDEF_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPUStorageTextureReadWriteBinding", - "start_line": 2066, - "type": "struct SDL_GPUStorageTextureReadWriteBinding" - }, - "204": { - "brief_comment": "Checks for GPU runtime support.", - "end_line": 2094, - "kind": "VAR_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "bool", - "start_line": 2094, - "type": "Int", - "value": "bool" - }, - "205": { - "brief_comment": "Checks for GPU runtime support.", - "end_line": 2108, - "kind": "VAR_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "bool", - "start_line": 2108, - "type": "Int", - "value": "bool" - }, - "206": { - "brief_comment": "Creates a GPU context.", - "end_line": 2129, - "kind": "VAR_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPUDevice", - "start_line": 2129, - "type": "Int", - "value": "SDL_GPUDevice" - }, - "207": { - "brief_comment": "Creates a GPU context.", - "end_line": 2177, - "kind": "VAR_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPUDevice", - "start_line": 2177, - "type": "Int", - "value": "SDL_GPUDevice" - }, - "208": { - "brief_comment": "Destroys a GPU context previously returned by SDL_CreateGPUDevice.", - "end_line": 2200, - "kind": "VAR_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDLCALL", - "start_line": 2200, - "type": "Int", - "value": "SDLCALL" - }, - "209": { - "brief_comment": "Get the number of GPU drivers compiled into SDL.", - "end_line": 2211, - "kind": "VAR_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDLCALL", - "start_line": 2211, - "type": "Int", - "value": "SDLCALL" - }, - "210": { - "brief_comment": "Get the name of a built in GPU driver.", - "end_line": 2230, - "kind": "VAR_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDLCALL", - "start_line": 2230, - "type": "Pointer", - "value": "SDLCALL" - }, - "211": { - "brief_comment": "Returns the name of the backend used to create this GPU context.", - "end_line": 2240, - "kind": "VAR_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDLCALL", - "start_line": 2240, - "type": "Pointer", - "value": "SDLCALL" - }, - "212": { - "brief_comment": "Returns the supported shader formats for this GPU context.", - "end_line": 2251, - "kind": "VAR_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPUShaderFormat", - "start_line": 2251, - "type": "Int", - "value": "SDL_GPUShaderFormat" - }, - "213": { - "brief_comment": "Creates a pipeline object to be used in a compute workflow.", - "end_line": 2300, - "kind": "VAR_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPUComputePipeline", - "start_line": 2300, - "type": "Int", - "value": "SDL_GPUComputePipeline" - }, - "214": { - "brief_comment": "Creates a pipeline object to be used in a graphics workflow.", - "end_line": 2327, - "kind": "VAR_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPUGraphicsPipeline", - "start_line": 2327, - "type": "Int", - "value": "SDL_GPUGraphicsPipeline" - }, - "215": { - "brief_comment": "Creates a sampler object to be used when binding textures in a graphics workflow.", - "end_line": 2354, - "kind": "VAR_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPUSampler", - "start_line": 2354, - "type": "Int", - "value": "SDL_GPUSampler" - }, - "216": { - "brief_comment": "Creates a shader to be used when creating a graphics pipeline.", - "end_line": 2433, - "kind": "VAR_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPUShader", - "start_line": 2433, - "type": "Int", - "value": "SDL_GPUShader" - }, - "217": { - "brief_comment": "Creates a texture object to be used in graphics or compute workflows.", - "end_line": 2494, - "kind": "VAR_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPUTexture", - "start_line": 2494, - "type": "Int", - "value": "SDL_GPUTexture" - }, - "218": { - "brief_comment": "Creates a buffer object to be used in graphics or compute workflows.", - "end_line": 2550, - "kind": "VAR_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPUBuffer", - "start_line": 2550, - "type": "Int", - "value": "SDL_GPUBuffer" - }, - "219": { - "brief_comment": "Creates a transfer buffer to be used when uploading to or downloading from graphics resources.", - "end_line": 2583, - "kind": "VAR_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPUTransferBuffer", - "start_line": 2583, - "type": "Int", - "value": "SDL_GPUTransferBuffer" - }, - "220": { - "brief_comment": "Sets an arbitrary string constant to label a buffer.", - "end_line": 2608, - "kind": "VAR_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDLCALL", - "start_line": 2608, - "type": "Int", - "value": "SDLCALL" - }, - "221": { - "brief_comment": "Sets an arbitrary string constant to label a texture.", - "end_line": 2631, - "kind": "VAR_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDLCALL", - "start_line": 2631, - "type": "Int", - "value": "SDLCALL" - }, - "222": { - "brief_comment": "Inserts an arbitrary string label into the command buffer callstream.", - "end_line": 2646, - "kind": "VAR_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDLCALL", - "start_line": 2646, - "type": "Int", - "value": "SDLCALL" - }, - "223": { - "brief_comment": "Begins a debug group with an arbitary name.", - "end_line": 2671, - "kind": "VAR_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDLCALL", - "start_line": 2671, - "type": "Int", - "value": "SDLCALL" - }, - "224": { - "brief_comment": "Ends the most-recently pushed debug group.", - "end_line": 2684, - "kind": "VAR_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDLCALL", - "start_line": 2684, - "type": "Int", - "value": "SDLCALL" - }, - "225": { - "brief_comment": "Frees the given texture as soon as it is safe to do so.", - "end_line": 2699, - "kind": "VAR_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDLCALL", - "start_line": 2699, - "type": "Int", - "value": "SDLCALL" - }, - "226": { - "brief_comment": "Frees the given sampler as soon as it is safe to do so.", - "end_line": 2713, - "kind": "VAR_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDLCALL", - "start_line": 2713, - "type": "Int", - "value": "SDLCALL" - }, - "227": { - "brief_comment": "Frees the given buffer as soon as it is safe to do so.", - "end_line": 2727, - "kind": "VAR_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDLCALL", - "start_line": 2727, - "type": "Int", - "value": "SDLCALL" - }, - "228": { - "brief_comment": "Frees the given transfer buffer as soon as it is safe to do so.", - "end_line": 2741, - "kind": "VAR_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDLCALL", - "start_line": 2741, - "type": "Int", - "value": "SDLCALL" - }, - "229": { - "brief_comment": "Frees the given compute pipeline as soon as it is safe to do so.", - "end_line": 2755, - "kind": "VAR_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDLCALL", - "start_line": 2755, - "type": "Int", - "value": "SDLCALL" - }, - "230": { - "brief_comment": "Frees the given shader as soon as it is safe to do so.", - "end_line": 2769, - "kind": "VAR_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDLCALL", - "start_line": 2769, - "type": "Int", - "value": "SDLCALL" - }, - "231": { - "brief_comment": "Frees the given graphics pipeline as soon as it is safe to do so.", - "end_line": 2783, - "kind": "VAR_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDLCALL", - "start_line": 2783, - "type": "Int", - "value": "SDLCALL" - }, - "232": { - "brief_comment": "Acquire a command buffer.", - "end_line": 2811, - "kind": "VAR_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPUCommandBuffer", - "start_line": 2811, - "type": "Int", - "value": "SDL_GPUCommandBuffer" - }, - "233": { - "brief_comment": "Pushes data to a vertex uniform slot on the command buffer.", - "end_line": 2832, - "kind": "VAR_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDLCALL", - "start_line": 2832, - "type": "Int", - "value": "SDLCALL" - }, - "234": { - "brief_comment": "Pushes data to a fragment uniform slot on the command buffer.", - "end_line": 2854, - "kind": "VAR_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDLCALL", - "start_line": 2854, - "type": "Int", - "value": "SDLCALL" - }, - "235": { - "brief_comment": "Pushes data to a uniform slot on the command buffer.", - "end_line": 2876, - "kind": "VAR_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDLCALL", - "start_line": 2876, - "type": "Int", - "value": "SDLCALL" - }, - "236": { - "brief_comment": "Begins a render pass on a command buffer.", - "end_line": 2909, - "kind": "VAR_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPURenderPass", - "start_line": 2909, - "type": "Int", - "value": "SDL_GPURenderPass" - }, - "237": { - "brief_comment": "Binds a graphics pipeline on a render pass to be used in rendering.", - "end_line": 2925, - "kind": "VAR_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDLCALL", - "start_line": 2925, - "type": "Int", - "value": "SDLCALL" - }, - "238": { - "brief_comment": "Sets the current viewport state on a command buffer.", - "end_line": 2937, - "kind": "VAR_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDLCALL", - "start_line": 2937, - "type": "Int", - "value": "SDLCALL" - }, - "239": { - "brief_comment": "Sets the current scissor state on a command buffer.", - "end_line": 2949, - "kind": "VAR_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDLCALL", - "start_line": 2949, - "type": "Int", - "value": "SDLCALL" - }, - "240": { - "brief_comment": "Sets the current blend constants on a command buffer.", - "end_line": 2964, - "kind": "VAR_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDLCALL", - "start_line": 2964, - "type": "Int", - "value": "SDLCALL" - }, - "241": { - "brief_comment": "Sets the current stencil reference value on a command buffer.", - "end_line": 2976, - "kind": "VAR_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDLCALL", - "start_line": 2976, - "type": "Int", - "value": "SDLCALL" - }, - "242": { - "brief_comment": "Binds vertex buffers on a command buffer for use with subsequent draw calls.", - "end_line": 2992, - "kind": "VAR_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDLCALL", - "start_line": 2992, - "type": "Int", - "value": "SDLCALL" - }, - "243": { - "brief_comment": "Binds an index buffer on a command buffer for use with subsequent draw calls.", - "end_line": 3009, - "kind": "VAR_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDLCALL", - "start_line": 3009, - "type": "Int", - "value": "SDLCALL" - }, - "244": { - "brief_comment": "Binds texture-sampler pairs for use on the vertex shader.", - "end_line": 3033, - "kind": "VAR_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDLCALL", - "start_line": 3033, - "type": "Int", - "value": "SDLCALL" - }, - "245": { - "brief_comment": "Binds storage textures for use on the vertex shader.", - "end_line": 3057, - "kind": "VAR_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDLCALL", - "start_line": 3057, - "type": "Int", - "value": "SDLCALL" - }, - "246": { - "brief_comment": "Binds storage buffers for use on the vertex shader.", - "end_line": 3081, - "kind": "VAR_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDLCALL", - "start_line": 3081, - "type": "Int", - "value": "SDLCALL" - }, - "247": { - "brief_comment": "Binds texture-sampler pairs for use on the fragment shader.", - "end_line": 3106, - "kind": "VAR_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDLCALL", - "start_line": 3106, - "type": "Int", - "value": "SDLCALL" - }, - "248": { - "brief_comment": "Binds storage textures for use on the fragment shader.", - "end_line": 3130, - "kind": "VAR_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDLCALL", - "start_line": 3130, - "type": "Int", - "value": "SDLCALL" - }, - "249": { - "brief_comment": "Binds storage buffers for use on the fragment shader.", - "end_line": 3154, - "kind": "VAR_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDLCALL", - "start_line": 3154, - "type": "Int", - "value": "SDLCALL" - }, - "250": { - "brief_comment": "Draws data using bound graphics state with an index buffer and instancing enabled.", - "end_line": 3185, - "kind": "VAR_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDLCALL", - "start_line": 3185, - "type": "Int", - "value": "SDLCALL" - }, - "251": { - "brief_comment": "Draws data using bound graphics state.", - "end_line": 3213, - "kind": "VAR_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDLCALL", - "start_line": 3213, - "type": "Int", - "value": "SDLCALL" - }, - "252": { - "brief_comment": "Draws data using bound graphics state and with draw parameters set from a buffer.", - "end_line": 3236, - "kind": "VAR_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDLCALL", - "start_line": 3236, - "type": "Int", - "value": "SDLCALL" - }, - "253": { - "brief_comment": "Draws data using bound graphics state with an index buffer enabled and with draw parameters set from a buffer.", - "end_line": 3258, - "kind": "VAR_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDLCALL", - "start_line": 3258, - "type": "Int", - "value": "SDLCALL" - }, - "254": { - "brief_comment": "Ends the given render pass.", - "end_line": 3274, - "kind": "VAR_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDLCALL", - "start_line": 3274, - "type": "Int", - "value": "SDLCALL" - }, - "255": { - "brief_comment": "Begins a compute pass on a command buffer.", - "end_line": 3316, - "kind": "VAR_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPUComputePass", - "start_line": 3316, - "type": "Int", - "value": "SDL_GPUComputePass" - }, - "256": { - "brief_comment": "Binds a compute pipeline on a command buffer for use in compute dispatch.", - "end_line": 3331, - "kind": "VAR_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDLCALL", - "start_line": 3331, - "type": "Int", - "value": "SDLCALL" - }, - "257": { - "brief_comment": "Binds texture-sampler pairs for use on the compute shader.", - "end_line": 3354, - "kind": "VAR_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDLCALL", - "start_line": 3354, - "type": "Int", - "value": "SDLCALL" - }, - "258": { - "brief_comment": "Binds storage textures as readonly for use on the compute pipeline.", - "end_line": 3378, - "kind": "VAR_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDLCALL", - "start_line": 3378, - "type": "Int", - "value": "SDLCALL" - }, - "259": { - "brief_comment": "Binds storage buffers as readonly for use on the compute pipeline.", - "end_line": 3402, - "kind": "VAR_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDLCALL", - "start_line": 3402, - "type": "Int", - "value": "SDLCALL" - }, - "260": { - "brief_comment": "Dispatches compute work.", - "end_line": 3428, - "kind": "VAR_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDLCALL", - "start_line": 3428, - "type": "Int", - "value": "SDLCALL" - }, - "261": { - "brief_comment": "Dispatches compute work with parameters set from a buffer.", - "end_line": 3452, - "kind": "VAR_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDLCALL", - "start_line": 3452, - "type": "Int", - "value": "SDLCALL" - }, - "262": { - "brief_comment": "Ends the current compute pass.", - "end_line": 3467, - "kind": "VAR_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDLCALL", - "start_line": 3467, - "type": "Int", - "value": "SDLCALL" - }, - "263": { - "brief_comment": "Maps a transfer buffer into application address space.", - "end_line": 3487, - "kind": "VAR_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDLCALL", - "start_line": 3487, - "type": "Pointer", - "value": "SDLCALL" - }, - "264": { - "brief_comment": "Unmaps a previously mapped transfer buffer.", - "end_line": 3500, - "kind": "VAR_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDLCALL", - "start_line": 3500, - "type": "Int", - "value": "SDLCALL" - }, - "265": { - "brief_comment": "Begins a copy pass on a command buffer.", - "end_line": 3518, - "kind": "VAR_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPUCopyPass", - "start_line": 3518, - "type": "Int", - "value": "SDL_GPUCopyPass" - }, - "266": { - "brief_comment": "Uploads data from a transfer buffer to a texture.", - "end_line": 3538, - "kind": "VAR_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDLCALL", - "start_line": 3538, - "type": "Int", - "value": "SDLCALL" - }, - "267": { - "brief_comment": "Uploads data from a transfer buffer to a buffer.", - "end_line": 3558, - "kind": "VAR_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDLCALL", - "start_line": 3558, - "type": "Int", - "value": "SDLCALL" - }, - "268": { - "brief_comment": "Performs a texture-to-texture copy.", - "end_line": 3581, - "kind": "VAR_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDLCALL", - "start_line": 3581, - "type": "Int", - "value": "SDLCALL" - }, - "269": { - "brief_comment": "Performs a buffer-to-buffer copy.", - "end_line": 3605, - "kind": "VAR_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDLCALL", - "start_line": 3605, - "type": "Int", - "value": "SDLCALL" - }, - "270": { - "brief_comment": "Copies data from a texture to a transfer buffer on the GPU timeline.", - "end_line": 3625, - "kind": "VAR_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDLCALL", - "start_line": 3625, - "type": "Int", - "value": "SDLCALL" - }, - "271": { - "brief_comment": "Copies data from a buffer to a transfer buffer on the GPU timeline.", - "end_line": 3642, - "kind": "VAR_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDLCALL", - "start_line": 3642, - "type": "Int", - "value": "SDLCALL" - }, - "272": { - "brief_comment": "Ends the current copy pass.", - "end_line": 3654, - "kind": "VAR_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDLCALL", - "start_line": 3654, - "type": "Int", - "value": "SDLCALL" - }, - "273": { - "brief_comment": "Generates mipmaps for the given texture.", - "end_line": 3667, - "kind": "VAR_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDLCALL", - "start_line": 3667, - "type": "Int", - "value": "SDLCALL" - }, - "274": { - "brief_comment": "Blits from a source texture region to a destination texture region.", - "end_line": 3681, - "kind": "VAR_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDLCALL", - "start_line": 3681, - "type": "Int", - "value": "SDLCALL" - }, - "275": { - "brief_comment": "Determines whether a swapchain composition is supported by the window.", - "end_line": 3701, - "kind": "VAR_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "bool", - "start_line": 3701, - "type": "Int", - "value": "bool" - }, - "276": { - "brief_comment": "Determines whether a presentation mode is supported by the window.", - "end_line": 3720, - "kind": "VAR_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "bool", - "start_line": 3720, - "type": "Int", - "value": "bool" - }, - "277": { - "brief_comment": "Claims a window, creating a swapchain structure for it.", - "end_line": 3752, - "kind": "VAR_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "bool", - "start_line": 3752, - "type": "Int", - "value": "bool" - }, - "278": { - "brief_comment": "Unclaims a window, destroying its swapchain structure.", - "end_line": 3766, - "kind": "VAR_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDLCALL", - "start_line": 3766, - "type": "Int", - "value": "SDLCALL" - }, - "279": { - "brief_comment": "Changes the swapchain parameters for the given claimed window.", - "end_line": 3793, - "kind": "VAR_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "bool", - "start_line": 3793, - "type": "Int", - "value": "bool" - }, - "280": { - "brief_comment": "Configures the maximum allowed number of frames in flight.", - "end_line": 3824, - "kind": "VAR_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "bool", - "start_line": 3824, - "type": "Int", - "value": "bool" - }, - "281": { - "brief_comment": "Obtains the texture format of the swapchain for the given window.", - "end_line": 3839, - "kind": "VAR_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPUTextureFormat", - "start_line": 3839, - "type": "Int", - "value": "SDL_GPUTextureFormat" - }, - "282": { - "brief_comment": "Acquire a texture to use in presentation.", - "end_line": 3889, - "kind": "VAR_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "bool", - "start_line": 3889, - "type": "Int", - "value": "bool" - }, - "283": { - "brief_comment": "Blocks the thread until a swapchain texture is available to be acquired.", - "end_line": 3913, - "kind": "VAR_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "bool", - "start_line": 3913, - "type": "Int", - "value": "bool" - }, - "284": { - "brief_comment": "Blocks the thread until a swapchain texture is available to be acquired, and then acquires it.", - "end_line": 3959, - "kind": "VAR_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "bool", - "start_line": 3959, - "type": "Int", - "value": "bool" - }, - "285": { - "brief_comment": "Submits a command buffer so its commands can be processed on the GPU.", - "end_line": 3987, - "kind": "VAR_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "bool", - "start_line": 3987, - "type": "Int", - "value": "bool" - }, - "286": { - "brief_comment": "Submits a command buffer so its commands can be processed on the GPU, and acquires a fence associated with the command buffer.", - "end_line": 4014, - "kind": "VAR_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDL_GPUFence", - "start_line": 4014, - "type": "Int", - "value": "SDL_GPUFence" - }, - "287": { - "brief_comment": "Cancels a command buffer.", - "end_line": 4039, - "kind": "VAR_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "bool", - "start_line": 4039, - "type": "Int", - "value": "bool" - }, - "288": { - "brief_comment": "Blocks the thread until the GPU is completely idle.", - "end_line": 4053, - "kind": "VAR_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "bool", - "start_line": 4053, - "type": "Int", - "value": "bool" - }, - "289": { - "brief_comment": "Blocks the thread until the given fences are signaled.", - "end_line": 4072, - "kind": "VAR_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "bool", - "start_line": 4072, - "type": "Int", - "value": "bool" - }, - "290": { - "brief_comment": "Checks the status of a fence.", - "end_line": 4089, - "kind": "VAR_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "bool", - "start_line": 4089, - "type": "Int", - "value": "bool" - }, - "291": { - "brief_comment": "Releases a fence obtained from SDL_SubmitGPUCommandBufferAndAcquireFence.", - "end_line": 4105, - "kind": "VAR_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "SDLCALL", - "start_line": 4105, - "type": "Int", - "value": "SDLCALL" - }, - "292": { - "brief_comment": "Obtains the texel block size for a texture format.", - "end_line": 4121, - "kind": "VAR_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "Uint32", - "start_line": 4121, - "type": "Int", - "value": "Uint32" - }, - "293": { - "brief_comment": "Determines whether a texture format is supported for a given type and usage.", - "end_line": 4136, - "kind": "VAR_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "bool", - "start_line": 4136, - "type": "Int", - "value": "bool" - }, - "294": { - "brief_comment": "Determines if a sample count for a texture format is supported.", - "end_line": 4152, - "kind": "VAR_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "bool", - "start_line": 4152, - "type": "Int", - "value": "bool" - }, - "295": { - "brief_comment": "Calculate the size in bytes of a texture format with dimensions.", - "end_line": 4168, - "kind": "VAR_DECL", - "location": "SDL_gpu.h", - "result_type": "Invalid", - "spelling": "Uint32", - "start_line": 4168, - "type": "Int", - "value": "Uint32" - } -} -{ - "functions": {} -} diff --git a/lib/sdl3/SDL/src/SDL_hints.c b/lib/sdl3/SDL/src/SDL_hints.c index 9c4ccd4..a10598f 100644 --- a/lib/sdl3/SDL/src/SDL_hints.c +++ b/lib/sdl3/SDL/src/SDL_hints.c @@ -22,6 +22,10 @@ #include "SDL_hints_c.h" +#ifdef SDL_PLATFORM_ANDROID +#include "core/android/SDL_android.h" +#endif + typedef struct SDL_HintWatch { SDL_HintCallback callback; @@ -147,6 +151,13 @@ bool SDL_SetHintWithPriority(const char *name, const char *value, SDL_HintPriori } } +#ifdef SDL_PLATFORM_ANDROID + if (SDL_strcmp(name, SDL_HINT_ANDROID_ALLOW_RECREATE_ACTIVITY) == 0) { + // Special handling for this hint, which needs to persist outside the normal application flow + Android_SetAllowRecreateActivity(SDL_GetStringBoolean(value, false)); + } +#endif // SDL_PLATFORM_ANDROID + SDL_UnlockProperties(hints); return result; @@ -185,6 +196,17 @@ bool SDL_ResetHint(const char *name) result = true; } +#ifdef SDL_PLATFORM_ANDROID + if (SDL_strcmp(name, SDL_HINT_ANDROID_ALLOW_RECREATE_ACTIVITY) == 0) { + // Special handling for this hint, which needs to persist outside the normal application flow + if (env) { + Android_SetAllowRecreateActivity(SDL_GetStringBoolean(env, false)); + } else { + Android_SetAllowRecreateActivity(false); + } + } +#endif // SDL_PLATFORM_ANDROID + SDL_UnlockProperties(hints); return result; @@ -210,6 +232,17 @@ static void SDLCALL ResetHintsCallback(void *userdata, SDL_PropertiesID hints, c SDL_free(hint->value); hint->value = NULL; hint->priority = SDL_HINT_DEFAULT; + +#ifdef SDL_PLATFORM_ANDROID + if (SDL_strcmp(name, SDL_HINT_ANDROID_ALLOW_RECREATE_ACTIVITY) == 0) { + // Special handling for this hint, which needs to persist outside the normal application flow + if (env) { + Android_SetAllowRecreateActivity(SDL_GetStringBoolean(env, false)); + } else { + Android_SetAllowRecreateActivity(false); + } + } +#endif // SDL_PLATFORM_ANDROID } void SDL_ResetHints(void) diff --git a/lib/sdl3/SDL/src/SDL_internal.h b/lib/sdl3/SDL/src/SDL_internal.h index a345252..8fcd96a 100644 --- a/lib/sdl3/SDL/src/SDL_internal.h +++ b/lib/sdl3/SDL/src/SDL_internal.h @@ -265,6 +265,12 @@ extern "C" { #include "SDL_utils_c.h" #include "SDL_hashtable.h" +#define PUSH_SDL_ERROR() \ + { char *_error = SDL_strdup(SDL_GetError()); + +#define POP_SDL_ERROR() \ + SDL_SetError("%s", _error); SDL_free(_error); } + // Do any initialization that needs to happen before threads are started extern void SDL_InitMainThread(void); diff --git a/lib/sdl3/SDL/src/SDL_utils.c b/lib/sdl3/SDL/src/SDL_utils.c index 8d32143..f209074 100644 --- a/lib/sdl3/SDL/src/SDL_utils.c +++ b/lib/sdl3/SDL/src/SDL_utils.c @@ -403,6 +403,10 @@ const char *SDL_GetPersistentString(const char *string) static int PrefixMatch(const char *a, const char *b) { int matchlen = 0; + // Fixes the "HORI HORl Taiko No Tatsujin Drum Controller" + if (SDL_strncmp(a, "HORI ", 5) == 0 && SDL_strncmp(b, "HORl ", 5) == 0) { + return 5; + } while (*a && *b) { if (SDL_tolower((unsigned char)*a++) == SDL_tolower((unsigned char)*b++)) { ++matchlen; @@ -424,8 +428,8 @@ char *SDL_CreateDeviceName(Uint16 vendor, Uint16 product, const char *vendor_nam { "ASTRO Gaming", "ASTRO" }, { "Bensussen Deutsch & Associates,Inc.(BDA)", "BDA" }, { "Guangzhou Chicken Run Network Technology Co., Ltd.", "GameSir" }, - { "HORI CO.,LTD", "HORI" }, { "HORI CO.,LTD.", "HORI" }, + { "HORI CO.,LTD", "HORI" }, { "Mad Catz Inc.", "Mad Catz" }, { "Nintendo Co., Ltd.", "Nintendo" }, { "NVIDIA Corporation ", "" }, diff --git a/lib/sdl3/SDL/src/audio/SDL_audio.c b/lib/sdl3/SDL/src/audio/SDL_audio.c index cf817e4..fbe6e22 100644 --- a/lib/sdl3/SDL/src/audio/SDL_audio.c +++ b/lib/sdl3/SDL/src/audio/SDL_audio.c @@ -410,6 +410,7 @@ static SDL_LogicalAudioDevice *ObtainLogicalAudioDevice(SDL_AudioDeviceID devid, SDL_LockRWLockForReading(current_audio.device_hash_lock); SDL_FindInHashTable(current_audio.device_hash, (const void *) (uintptr_t) devid, (const void **) &logdev); if (logdev) { + SDL_assert(logdev->instance_id == devid); device = logdev->physical_device; SDL_assert(device != NULL); RefPhysicalAudioDevice(device); // reference it, in case the logical device migrates to a new default. @@ -459,6 +460,7 @@ static SDL_AudioDevice *ObtainPhysicalAudioDevice(SDL_AudioDeviceID devid) // ! } else { SDL_LockRWLockForReading(current_audio.device_hash_lock); SDL_FindInHashTable(current_audio.device_hash, (const void *) (uintptr_t) devid, (const void **) &device); + SDL_assert(device->instance_id == devid); SDL_UnlockRWLock(current_audio.device_hash_lock); if (!device) { @@ -883,6 +885,7 @@ static bool SDLCALL FindLowestDeviceID(void *userdata, const SDL_HashTable *tabl if (isphysical && (devid_recording == data->recording) && (devid < data->highest)) { data->highest = devid; data->result = (SDL_AudioDevice *) value; + SDL_assert(data->result->instance_id == devid); } return true; // keep iterating. } @@ -1051,7 +1054,10 @@ static bool SDLCALL DestroyOnePhysicalAudioDevice(void *userdata, const SDL_Hash const SDL_AudioDeviceID devid = (SDL_AudioDeviceID) (uintptr_t) key; const bool isphysical = !!(devid & (1<<1)); if (isphysical) { - DestroyPhysicalAudioDevice((SDL_AudioDevice *) value); + SDL_AudioDevice *dev = (SDL_AudioDevice *) value; + + SDL_assert(dev->instance_id == devid); + DestroyPhysicalAudioDevice(dev); } return true; // keep iterating. } @@ -1464,6 +1470,7 @@ static bool SDLCALL FindAudioDeviceByCallback(void *userdata, const SDL_HashTabl SDL_AudioDevice *device = (SDL_AudioDevice *) value; if (data->callback(device, data->userdata)) { // found it? data->retval = device; + SDL_assert(data->retval->instance_id == devid); return false; // stop iterating, we found it. } } @@ -1502,12 +1509,33 @@ SDL_AudioDevice *SDL_FindPhysicalAudioDeviceByHandle(void *handle) const char *SDL_GetAudioDeviceName(SDL_AudioDeviceID devid) { + // bit #1 of devid is set for physical devices and unset for logical. + const bool islogical = !(devid & (1<<1)); const char *result = NULL; - SDL_AudioDevice *device = ObtainPhysicalAudioDevice(devid); - if (device) { - result = SDL_GetPersistentString(device->name); + const void *vdev = NULL; + + if (!SDL_GetCurrentAudioDriver()) { + SDL_SetError("Audio subsystem is not initialized"); + } else { + // This does not call ObtainPhysicalAudioDevice() because the device's name never changes, so + // it doesn't have to lock the whole device. However, just to make sure the device pointer itself + // remains valid (in case the device is unplugged at the wrong moment), we hold the + // device_hash_lock while we copy the string. + SDL_LockRWLockForReading(current_audio.device_hash_lock); + SDL_FindInHashTable(current_audio.device_hash, (const void *) (uintptr_t) devid, &vdev); + if (!vdev) { + SDL_SetError("Invalid audio device instance ID"); + } else if (islogical) { + const SDL_LogicalAudioDevice *logdev = (const SDL_LogicalAudioDevice *) vdev; + SDL_assert(logdev->instance_id == devid); + result = SDL_GetPersistentString(logdev->physical_device->name); + } else { + const SDL_AudioDevice *device = (const SDL_AudioDevice *) vdev; + SDL_assert(device->instance_id == devid); + result = SDL_GetPersistentString(device->name); + } + SDL_UnlockRWLock(current_audio.device_hash_lock); } - ReleaseAudioDevice(device); return result; } @@ -1715,13 +1743,18 @@ static bool OpenPhysicalAudioDevice(SDL_AudioDevice *device, const SDL_AudioSpec SDL_copyp(&spec, inspec ? inspec : &device->default_spec); PrepareAudioFormat(device->recording, &spec); - /* We allow the device format to change if it's better than the current settings (by various definitions of "better"). This prevents - something low quality, like an old game using S8/8000Hz audio, from ruining a music thing playing at CD quality that tries to open later. - (or some VoIP library that opens for mono output ruining your surround-sound game because it got there first). + /* We impose a simple minimum on device formats. This prevents something low quality, like an old game using S8/8000Hz audio, + from ruining a music thing playing at CD quality that tries to open later, or some VoIP library that opens for mono output + ruining your surround-sound game because it got there first. These are just requests! The backend may change any of these values during OpenDevice method! */ - device->spec.format = (SDL_AUDIO_BITSIZE(device->default_spec.format) >= SDL_AUDIO_BITSIZE(spec.format)) ? device->default_spec.format : spec.format; - device->spec.freq = SDL_max(device->default_spec.freq, spec.freq); - device->spec.channels = SDL_max(device->default_spec.channels, spec.channels); + + const SDL_AudioFormat minimum_format = device->recording ? DEFAULT_AUDIO_RECORDING_FORMAT : DEFAULT_AUDIO_PLAYBACK_FORMAT; + const int minimum_channels = device->recording ? DEFAULT_AUDIO_RECORDING_CHANNELS : DEFAULT_AUDIO_PLAYBACK_CHANNELS; + const int minimum_freq = device->recording ? DEFAULT_AUDIO_RECORDING_FREQUENCY : DEFAULT_AUDIO_PLAYBACK_FREQUENCY; + + device->spec.format = (SDL_AUDIO_BITSIZE(minimum_format) >= SDL_AUDIO_BITSIZE(spec.format)) ? minimum_format : spec.format; + device->spec.channels = SDL_max(minimum_channels, spec.channels); + device->spec.freq = SDL_max(minimum_freq, spec.freq); device->sample_frames = SDL_GetDefaultSampleFramesFromFreq(device->spec.freq); SDL_UpdatedAudioDeviceFormat(device); // start this off sane. diff --git a/lib/sdl3/SDL/src/audio/aaudio/SDL_aaudio.c b/lib/sdl3/SDL/src/audio/aaudio/SDL_aaudio.c index 3360bec..5436be0 100644 --- a/lib/sdl3/SDL/src/audio/aaudio/SDL_aaudio.c +++ b/lib/sdl3/SDL/src/audio/aaudio/SDL_aaudio.c @@ -308,6 +308,12 @@ static bool BuildAAudioStream(SDL_AudioDevice *device) ctx.AAudioStreamBuilder_setFormat(builder, format); ctx.AAudioStreamBuilder_setSampleRate(builder, device->spec.freq); ctx.AAudioStreamBuilder_setChannelCount(builder, device->spec.channels); + + // If no specific buffer size has been requested, the device will pick the optimal + if(SDL_GetHint(SDL_HINT_AUDIO_DEVICE_SAMPLE_FRAMES)) { + ctx.AAudioStreamBuilder_setBufferCapacityInFrames(builder, 2 * device->sample_frames); // AAudio requires that the buffer capacity is at least + ctx.AAudioStreamBuilder_setFramesPerDataCallback(builder, device->sample_frames); // twice the size of the data callback buffer size + } const aaudio_direction_t direction = (recording ? AAUDIO_DIRECTION_INPUT : AAUDIO_DIRECTION_OUTPUT); ctx.AAudioStreamBuilder_setDirection(builder, direction); @@ -366,7 +372,7 @@ static bool BuildAAudioStream(SDL_AudioDevice *device) hidden->processed_bytes = 0; hidden->callback_bytes = 0; - hidden->semaphore = SDL_CreateSemaphore(recording ? 0 : hidden->num_buffers); + hidden->semaphore = SDL_CreateSemaphore(recording ? 0 : hidden->num_buffers - 1); if (!hidden->semaphore) { LOGI("SDL Failed SDL_CreateSemaphore %s recording:%d", SDL_GetError(), recording); return false; diff --git a/lib/sdl3/SDL/src/audio/aaudio/SDL_aaudiofuncs.h b/lib/sdl3/SDL/src/audio/aaudio/SDL_aaudiofuncs.h index 0298821..1d9f710 100644 --- a/lib/sdl3/SDL/src/audio/aaudio/SDL_aaudiofuncs.h +++ b/lib/sdl3/SDL/src/audio/aaudio/SDL_aaudiofuncs.h @@ -31,7 +31,7 @@ SDL_PROC_UNUSED(void, AAudioStreamBuilder_setSamplesPerFrame, (AAudioStreamBuild SDL_PROC(void, AAudioStreamBuilder_setFormat, (AAudioStreamBuilder * builder, aaudio_format_t format)) SDL_PROC_UNUSED(void, AAudioStreamBuilder_setSharingMode, (AAudioStreamBuilder * builder, aaudio_sharing_mode_t sharingMode)) SDL_PROC(void, AAudioStreamBuilder_setDirection, (AAudioStreamBuilder * builder, aaudio_direction_t direction)) -SDL_PROC_UNUSED(void, AAudioStreamBuilder_setBufferCapacityInFrames, (AAudioStreamBuilder * builder, int32_t numFrames)) +SDL_PROC(void, AAudioStreamBuilder_setBufferCapacityInFrames, (AAudioStreamBuilder * builder, int32_t numFrames)) SDL_PROC(void, AAudioStreamBuilder_setPerformanceMode, (AAudioStreamBuilder * builder, aaudio_performance_mode_t mode)) SDL_PROC_UNUSED(void, AAudioStreamBuilder_setUsage, (AAudioStreamBuilder * builder, aaudio_usage_t usage)) // API 28 SDL_PROC_UNUSED(void, AAudioStreamBuilder_setContentType, (AAudioStreamBuilder * builder, aaudio_content_type_t contentType)) // API 28 diff --git a/lib/sdl3/SDL/src/audio/emscripten/SDL_emscriptenaudio.c b/lib/sdl3/SDL/src/audio/emscripten/SDL_emscriptenaudio.c index 55fb5b4..46b8b76 100644 --- a/lib/sdl3/SDL/src/audio/emscripten/SDL_emscriptenaudio.c +++ b/lib/sdl3/SDL/src/audio/emscripten/SDL_emscriptenaudio.c @@ -189,7 +189,7 @@ static bool EMSCRIPTENAUDIO_OpenDevice(SDL_AudioDevice *device) } // limit to native freq - device->spec.freq = EM_ASM_INT({ return Module['SDL3'].audioContext.sampleRate; }); + device->spec.freq = MAIN_THREAD_EM_ASM_INT({ return Module['SDL3'].audioContext.sampleRate; }); device->sample_frames = SDL_GetDefaultSampleFramesFromFreq(device->spec.freq) * 2; // double the buffer size, some browsers need more, and we'll just have to live with the latency. SDL_UpdatedAudioDeviceFormat(device); diff --git a/lib/sdl3/SDL/src/audio/pipewire/SDL_pipewire.c b/lib/sdl3/SDL/src/audio/pipewire/SDL_pipewire.c index 32c93f6..6004feb 100644 --- a/lib/sdl3/SDL/src/audio/pipewire/SDL_pipewire.c +++ b/lib/sdl3/SDL/src/audio/pipewire/SDL_pipewire.c @@ -1118,7 +1118,13 @@ static bool PIPEWIRE_OpenDevice(SDL_AudioDevice *device) stream_name = SDL_GetHint(SDL_HINT_AUDIO_DEVICE_STREAM_NAME); if (!stream_name || *stream_name == '\0') { - stream_name = "Audio Stream"; + if (app_name) { + stream_name = app_name; + } else if (app_id) { + stream_name = app_id; + } else { + stream_name = "SDL Audio Stream"; + } } /* diff --git a/lib/sdl3/SDL/src/audio/pulseaudio/SDL_pulseaudio.c b/lib/sdl3/SDL/src/audio/pulseaudio/SDL_pulseaudio.c index 69e8c1a..4d618a6 100644 --- a/lib/sdl3/SDL/src/audio/pulseaudio/SDL_pulseaudio.c +++ b/lib/sdl3/SDL/src/audio/pulseaudio/SDL_pulseaudio.c @@ -672,7 +672,8 @@ static bool PULSEAUDIO_OpenDevice(SDL_AudioDevice *device) paspec.rate = device->spec.freq; // Reduced prebuffering compared to the defaults. - paattr.fragsize = device->buffer_size; // despite the name, this is only used for recording devices, according to PulseAudio docs! + + paattr.fragsize = device->buffer_size * 2; // despite the name, this is only used for recording devices, according to PulseAudio docs! (times 2 because we want _more_ than our buffer size sent from the server at a time, which helps some drivers). paattr.tlength = device->buffer_size; paattr.prebuf = -1; paattr.maxlength = -1; diff --git a/lib/sdl3/SDL/src/audio/vita/SDL_vitaaudio.c b/lib/sdl3/SDL/src/audio/vita/SDL_vitaaudio.c index e194f21..86e8a69 100644 --- a/lib/sdl3/SDL/src/audio/vita/SDL_vitaaudio.c +++ b/lib/sdl3/SDL/src/audio/vita/SDL_vitaaudio.c @@ -130,7 +130,8 @@ static bool VITAAUD_OpenDevice(SDL_AudioDevice *device) static bool VITAAUD_PlayDevice(SDL_AudioDevice *device, const Uint8 *buffer, int buffer_size) { - return (sceAudioOutOutput(device->hidden->port, buffer) == 0); + // sceAudioOutOutput returns amount of samples queued or < 0 on error + return (sceAudioOutOutput(device->hidden->port, buffer) >= 0); } // This function waits until it is possible to write a full sound buffer diff --git a/lib/sdl3/SDL/src/camera/emscripten/SDL_camera_emscripten.c b/lib/sdl3/SDL/src/camera/emscripten/SDL_camera_emscripten.c index fa2a511..36418c5 100644 --- a/lib/sdl3/SDL/src/camera/emscripten/SDL_camera_emscripten.c +++ b/lib/sdl3/SDL/src/camera/emscripten/SDL_camera_emscripten.c @@ -61,7 +61,7 @@ static SDL_CameraFrameResult EMSCRIPTENCAMERA_AcquireFrame(SDL_Camera *device, S SDL3.camera.ctx2d.drawImage(SDL3.camera.video, 0, 0, w, h); const imgrgba = SDL3.camera.ctx2d.getImageData(0, 0, w, h).data; - Module.HEAPU8.set(imgrgba, rgba); + HEAPU8.set(imgrgba, rgba); return 1; }, device->actual_spec.width, device->actual_spec.height, rgba); diff --git a/lib/sdl3/SDL/src/core/android/SDL_android.c b/lib/sdl3/SDL/src/core/android/SDL_android.c index daf0f29..1cc9ccd 100644 --- a/lib/sdl3/SDL/src/core/android/SDL_android.c +++ b/lib/sdl3/SDL/src/core/android/SDL_android.c @@ -371,6 +371,7 @@ static jmethodID midShowTextInput; static jmethodID midSupportsRelativeMouse; static jmethodID midOpenFileDescriptor; static jmethodID midShowFileDialog; +static jmethodID midGetPreferredLocales; // audio manager static jclass mAudioManagerClass; @@ -660,6 +661,7 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeSetupJNI)(JNIEnv *env, jclass cl midSupportsRelativeMouse = (*env)->GetStaticMethodID(env, mActivityClass, "supportsRelativeMouse", "()Z"); midOpenFileDescriptor = (*env)->GetStaticMethodID(env, mActivityClass, "openFileDescriptor", "(Ljava/lang/String;Ljava/lang/String;)I"); midShowFileDialog = (*env)->GetStaticMethodID(env, mActivityClass, "showFileDialog", "([Ljava/lang/String;ZZI)Z"); + midGetPreferredLocales = (*env)->GetStaticMethodID(env, mActivityClass, "getPreferredLocales", "()Ljava/lang/String;"); if (!midClipboardGetText || !midClipboardHasText || @@ -691,7 +693,8 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeSetupJNI)(JNIEnv *env, jclass cl !midShowTextInput || !midSupportsRelativeMouse || !midOpenFileDescriptor || - !midShowFileDialog) { + !midShowFileDialog || + !midGetPreferredLocales) { __android_log_print(ANDROID_LOG_WARN, "SDL", "Missing some Java callbacks, do you have the latest version of SDLActivity.java?"); } @@ -751,6 +754,8 @@ JNIEXPORT void JNICALL SDL_JAVA_CONTROLLER_INTERFACE(nativeSetupJNI)(JNIEnv *env typedef int (*SDL_main_func)(int argc, char *argv[]); static int run_count = 0; +static bool allow_recreate_activity; +static bool allow_recreate_activity_set; JNIEXPORT int JNICALL SDL_JAVA_INTERFACE(nativeCheckSDLThreadCounter)( JNIEnv *env, jclass jcls) @@ -760,10 +765,16 @@ JNIEXPORT int JNICALL SDL_JAVA_INTERFACE(nativeCheckSDLThreadCounter)( return tmp; } +void Android_SetAllowRecreateActivity(bool enabled) +{ + allow_recreate_activity = enabled; + allow_recreate_activity_set = true; +} + JNIEXPORT jboolean JNICALL SDL_JAVA_INTERFACE(nativeAllowRecreateActivity)( JNIEnv *env, jclass jcls) { - return SDL_GetHintBoolean(SDL_HINT_ANDROID_ALLOW_RECREATE_ACTIVITY, false); + return allow_recreate_activity; } JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeInitMainThread)( @@ -1526,6 +1537,14 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeSetenv)( // Note that we call setenv() directly to avoid affecting SDL environments setenv(utfname, utfvalue, 1); // This should NOT be SDL_setenv() + if (SDL_strcmp(utfname, SDL_HINT_ANDROID_ALLOW_RECREATE_ACTIVITY) == 0) { + // Special handling for this hint, which needs to persist outside the normal application flow + // Only set this the first time we run, in case it's been set by the application via SDL_SetHint() + if (!allow_recreate_activity_set) { + Android_SetAllowRecreateActivity(SDL_GetStringBoolean(utfvalue, false)); + } + } + (*env)->ReleaseStringUTFChars(env, name, utfname); (*env)->ReleaseStringUTFChars(env, value, utfvalue); } @@ -2569,65 +2588,22 @@ bool Android_JNI_ShowToast(const char *message, int duration, int gravity, int x bool Android_JNI_GetLocale(char *buf, size_t buflen) { - AConfiguration *cfg; - - SDL_assert(buflen > 6); - - // Need to re-create the asset manager if locale has changed (SDL_EVENT_LOCALE_CHANGED) - Internal_Android_Destroy_AssetManager(); - - if (!asset_manager) { - Internal_Android_Create_AssetManager(); - } - - if (!asset_manager) { - return false; - } - - cfg = AConfiguration_new(); - if (!cfg) { - return false; - } - - { - char language[2] = {}; - char country[2] = {}; - size_t id = 0; - - AConfiguration_fromAssetManager(cfg, asset_manager); - AConfiguration_getLanguage(cfg, language); - AConfiguration_getCountry(cfg, country); - - // Indonesian is "id" according to ISO 639.2, but on Android is "in" because of Java backwards compatibility - if (language[0] == 'i' && language[1] == 'n') { - language[1] = 'd'; - } - - // copy language (not null terminated) - if (language[0]) { - buf[id++] = language[0]; - if (language[1]) { - buf[id++] = language[1]; + bool result = false; + if (buf && buflen > 0) { + *buf = '\0'; + JNIEnv *env = Android_JNI_GetEnv(); + jstring string = (jstring)(*env)->CallStaticObjectMethod(env, mActivityClass, midGetPreferredLocales); + if (string) { + const char *utf8string = (*env)->GetStringUTFChars(env, string, NULL); + if (utf8string) { + result = true; + SDL_strlcpy(buf, utf8string, buflen); + (*env)->ReleaseStringUTFChars(env, string, utf8string); } + (*env)->DeleteLocalRef(env, string); } - - buf[id++] = '_'; - - // copy country (not null terminated) - if (country[0]) { - buf[id++] = country[0]; - if (country[1]) { - buf[id++] = country[1]; - } - } - - buf[id++] = '\0'; - SDL_assert(id <= buflen); } - - AConfiguration_delete(cfg); - - return true; + return result; } bool Android_JNI_OpenURL(const char *url) diff --git a/lib/sdl3/SDL/src/core/android/SDL_android.h b/lib/sdl3/SDL/src/core/android/SDL_android.h index 3541c2a..620639c 100644 --- a/lib/sdl3/SDL/src/core/android/SDL_android.h +++ b/lib/sdl3/SDL/src/core/android/SDL_android.h @@ -55,6 +55,8 @@ bool Android_WaitLifecycleEvent(SDL_AndroidLifecycleEvent *event, Sint64 timeout void Android_LockActivityMutex(void); void Android_UnlockActivityMutex(void); +void Android_SetAllowRecreateActivity(bool enabled); + // Interface from the SDL library into the Android Java activity extern void Android_JNI_SetActivityTitle(const char *title); extern void Android_JNI_SetWindowStyle(bool fullscreen); diff --git a/lib/sdl3/SDL/src/core/windows/version.rc b/lib/sdl3/SDL/src/core/windows/version.rc index 4f94933..3492918 100644 --- a/lib/sdl3/SDL/src/core/windows/version.rc +++ b/lib/sdl3/SDL/src/core/windows/version.rc @@ -9,8 +9,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US // VS_VERSION_INFO VERSIONINFO - FILEVERSION 3,2,10,0 - PRODUCTVERSION 3,2,10,0 + FILEVERSION 3,2,16,0 + PRODUCTVERSION 3,2,16,0 FILEFLAGSMASK 0x3fL FILEFLAGS 0x0L FILEOS 0x40004L @@ -23,12 +23,12 @@ BEGIN BEGIN VALUE "CompanyName", "\0" VALUE "FileDescription", "SDL\0" - VALUE "FileVersion", "3, 2, 10, 0\0" + VALUE "FileVersion", "3, 2, 16, 0\0" VALUE "InternalName", "SDL\0" VALUE "LegalCopyright", "Copyright (C) 2025 Sam Lantinga\0" VALUE "OriginalFilename", "SDL3.dll\0" VALUE "ProductName", "Simple DirectMedia Layer\0" - VALUE "ProductVersion", "3, 2, 10, 0\0" + VALUE "ProductVersion", "3, 2, 16, 0\0" END END BLOCK "VarFileInfo" diff --git a/lib/sdl3/SDL/src/cpuinfo/SDL_cpuinfo.c b/lib/sdl3/SDL/src/cpuinfo/SDL_cpuinfo.c index 81d1e91..b836532 100644 --- a/lib/sdl3/SDL/src/cpuinfo/SDL_cpuinfo.c +++ b/lib/sdl3/SDL/src/cpuinfo/SDL_cpuinfo.c @@ -115,7 +115,11 @@ #define CPU_CFG2_LSX (1 << 6) #define CPU_CFG2_LASX (1 << 7) -#if defined(SDL_ALTIVEC_BLITTERS) && defined(HAVE_SETJMP) && !defined(SDL_PLATFORM_MACOS) && !defined(SDL_PLATFORM_OPENBSD) && !defined(SDL_PLATFORM_FREEBSD) +#if !defined(SDL_CPUINFO_DISABLED) && \ + !((defined(SDL_PLATFORM_MACOS) && (defined(__ppc__) || defined(__ppc64__))) || (defined(SDL_PLATFORM_OPENBSD) && defined(__powerpc__))) && \ + !(defined(SDL_PLATFORM_FREEBSD) && defined(__powerpc__)) && \ + !(defined(SDL_PLATFORM_LINUX) && defined(__powerpc__) && defined(HAVE_GETAUXVAL)) && \ + defined(SDL_ALTIVEC_BLITTERS) && defined(HAVE_SETJMP) /* This is the brute force way of detecting instruction sets... the idea is borrowed from the libmpeg2 library - thanks! */ @@ -344,6 +348,8 @@ static int CPU_haveAltiVec(void) elf_aux_info(AT_HWCAP, &cpufeatures, sizeof(cpufeatures)); altivec = cpufeatures & PPC_FEATURE_HAS_ALTIVEC; return altivec; +#elif defined(SDL_PLATFORM_LINUX) && defined(__powerpc__) && defined(HAVE_GETAUXVAL) + altivec = getauxval(AT_HWCAP) & PPC_FEATURE_HAS_ALTIVEC; #elif defined(SDL_ALTIVEC_BLITTERS) && defined(HAVE_SETJMP) void (*handler)(int sig); handler = signal(SIGILL, illegal_instruction); diff --git a/lib/sdl3/SDL/src/dialog/cocoa/SDL_cocoadialog.m b/lib/sdl3/SDL/src/dialog/cocoa/SDL_cocoadialog.m index fb9c5ad..64b2fdf 100644 --- a/lib/sdl3/SDL/src/dialog/cocoa/SDL_cocoadialog.m +++ b/lib/sdl3/SDL/src/dialog/cocoa/SDL_cocoadialog.m @@ -27,6 +27,35 @@ #import #import +static void AddFileExtensionType(NSMutableArray *types, const char *pattern_ptr) +{ + if (!*pattern_ptr) { + return; // in case the string had an extra ';' at the end. + } + + // -[UTType typeWithFilenameExtension] will return nil if there's a period in the string. It's better to + // allow too many files than not allow the one the user actually needs, so just take the part after the '.' + const char *dot = SDL_strrchr(pattern_ptr, '.'); + NSString *extstr = [NSString stringWithFormat: @"%s", dot ? (dot + 1) : pattern_ptr]; + if (@available(macOS 11.0, *)) { + UTType *uttype = [UTType typeWithFilenameExtension:extstr]; + if (uttype) { // still failed? Don't add the pattern. This is what the pre-macOS11 path does internally anyhow. + [types addObject:uttype]; + } + } else { + [types addObject:extstr]; + } +} + +static void ReactivateAfterDialog(void) +{ + for (NSRunningApplication *i in [NSRunningApplication runningApplicationsWithBundleIdentifier:@"com.apple.dock"]) { + [i activateWithOptions:0]; + break; + } + [NSApp activateIgnoringOtherApps:YES]; +} + void SDL_SYS_ShowFileDialogWithProperties(SDL_FileDialogType type, SDL_DialogFileCallback callback, void *userdata, SDL_PropertiesID props) { SDL_Window* window = SDL_GetPointerProperty(props, SDL_PROP_FILE_DIALOG_WINDOW_POINTER, NULL); @@ -87,7 +116,7 @@ void SDL_SYS_ShowFileDialogWithProperties(SDL_FileDialogType type, SDL_DialogFil if (filters) { // On macOS 11.0 and up, this is an array of UTType. Prior to that, it's an array of NSString - NSMutableArray *types = [[NSMutableArray alloc] initWithCapacity:nfilters ]; + NSMutableArray *types = [[NSMutableArray alloc] initWithCapacity:nfilters]; int has_all_files = 0; for (int i = 0; i < nfilters; i++) { @@ -102,21 +131,14 @@ void SDL_SYS_ShowFileDialogWithProperties(SDL_FileDialogType type, SDL_DialogFil for (char *c = pattern; *c; c++) { if (*c == ';') { *c = '\0'; - if(@available(macOS 11.0, *)) { - [types addObject: [UTType typeWithFilenameExtension:[NSString stringWithFormat: @"%s", pattern_ptr]]]; - } else { - [types addObject: [NSString stringWithFormat: @"%s", pattern_ptr]]; - } + AddFileExtensionType(types, pattern_ptr); pattern_ptr = c + 1; } else if (*c == '*') { has_all_files = 1; } } - if(@available(macOS 11.0, *)) { - [types addObject: [UTType typeWithFilenameExtension:[NSString stringWithFormat: @"%s", pattern_ptr]]]; - } else { - [types addObject: [NSString stringWithFormat: @"%s", pattern_ptr]]; - } + + AddFileExtensionType(types, pattern_ptr); // get the last piece of the string. SDL_free(pattern); } @@ -163,6 +185,8 @@ void SDL_SYS_ShowFileDialogWithProperties(SDL_FileDialogType type, SDL_DialogFil const char *files[1] = { NULL }; callback(userdata, files, -1); } + + ReactivateAfterDialog(); }]; } else { if ([dialog runModal] == NSModalResponseOK) { @@ -182,6 +206,7 @@ void SDL_SYS_ShowFileDialogWithProperties(SDL_FileDialogType type, SDL_DialogFil const char *files[1] = { NULL }; callback(userdata, files, -1); } + ReactivateAfterDialog(); } } diff --git a/lib/sdl3/SDL/src/dialog/windows/SDL_windowsdialog.c b/lib/sdl3/SDL/src/dialog/windows/SDL_windowsdialog.c index 2de224f..364753c 100644 --- a/lib/sdl3/SDL/src/dialog/windows/SDL_windowsdialog.c +++ b/lib/sdl3/SDL/src/dialog/windows/SDL_windowsdialog.c @@ -261,7 +261,7 @@ void windows_ShowFileDialog(void *ptr) chosen_files_list[nfiles] = NULL; - if (WideCharToMultiByte(CP_UTF8, 0, file_ptr, -1, chosen_folder, MAX_PATH, NULL, NULL) >= MAX_PATH) { + if (WideCharToMultiByte(CP_UTF8, 0, file_ptr, -1, chosen_folder, MAX_PATH, NULL, NULL) == 0) { SDL_SetError("Path too long or invalid character in path"); SDL_free(chosen_files_list); callback(userdata, NULL, -1); @@ -273,7 +273,7 @@ void windows_ShowFileDialog(void *ptr) SDL_strlcpy(chosen_file, chosen_folder, MAX_PATH); chosen_file[chosen_folder_size] = '\\'; - file_ptr += SDL_strlen(chosen_folder) + 1; + file_ptr += SDL_wcslen(file_ptr) + 1; while (*file_ptr) { nfiles++; @@ -295,7 +295,7 @@ void windows_ShowFileDialog(void *ptr) int diff = ((int) chosen_folder_size) + 1; - if (WideCharToMultiByte(CP_UTF8, 0, file_ptr, -1, chosen_file + diff, MAX_PATH - diff, NULL, NULL) >= MAX_PATH - diff) { + if (WideCharToMultiByte(CP_UTF8, 0, file_ptr, -1, chosen_file + diff, MAX_PATH - diff, NULL, NULL) == 0) { SDL_SetError("Path too long or invalid character in path"); for (size_t i = 0; i < nfiles - 1; i++) { @@ -308,7 +308,7 @@ void windows_ShowFileDialog(void *ptr) return; } - file_ptr += SDL_strlen(chosen_file) + 1 - diff; + file_ptr += SDL_wcslen(file_ptr) + 1; chosen_files_list[nfiles - 1] = SDL_strdup(chosen_file); @@ -516,6 +516,14 @@ static void ShowFileDialog(SDL_DialogFileCallback callback, void *userdata, SDL_ filters_str = win_get_filters(filters, nfilters); + DWORD flags = 0; + if (allow_many) { + flags |= OFN_ALLOWMULTISELECT; + } + if (is_save) { + flags |= OFN_OVERWRITEPROMPT; + } + if (!filters_str && filters) { callback(userdata, NULL, -1); SDL_free(args); @@ -526,7 +534,7 @@ static void ShowFileDialog(SDL_DialogFileCallback callback, void *userdata, SDL_ args->filters_str = filters_str; args->default_file = default_location ? SDL_strdup(default_location) : NULL; args->parent = window; - args->flags = allow_many ? OFN_ALLOWMULTISELECT : 0; + args->flags = flags; args->callback = callback; args->userdata = userdata; args->title = title ? SDL_strdup(title) : NULL; diff --git a/lib/sdl3/SDL/src/events/SDL_events.c b/lib/sdl3/SDL/src/events/SDL_events.c index 349d575..a151740 100644 --- a/lib/sdl3/SDL/src/events/SDL_events.c +++ b/lib/sdl3/SDL/src/events/SDL_events.c @@ -633,9 +633,10 @@ static void SDL_LogEvent(const SDL_Event *event) #undef PRINT_MBUTTON_EVENT SDL_EVENT_CASE(SDL_EVENT_MOUSE_WHEEL) - (void)SDL_snprintf(details, sizeof(details), " (timestamp=%u windowid=%u which=%u x=%g y=%g direction=%s)", + (void)SDL_snprintf(details, sizeof(details), " (timestamp=%u windowid=%u which=%u x=%g y=%g integer_x=%d integer_y=%d direction=%s)", (uint)event->wheel.timestamp, (uint)event->wheel.windowID, (uint)event->wheel.which, event->wheel.x, event->wheel.y, + (int)event->wheel.integer_x, (int)event->wheel.integer_y, event->wheel.direction == SDL_MOUSEWHEEL_NORMAL ? "normal" : "flipped"); break; @@ -1076,16 +1077,11 @@ static void SDL_SendWakeupEvent(void) return; } - SDL_LockMutex(_this->wakeup_lock); - { - if (_this->wakeup_window) { - _this->SendWakeupEvent(_this, _this->wakeup_window); - - // No more wakeup events needed until we enter a new wait - _this->wakeup_window = NULL; - } + // We only want to do this once while waiting for an event, so set it to NULL atomically here + SDL_Window *wakeup_window = (SDL_Window *)SDL_SetAtomicPointer(&_this->wakeup_window, NULL); + if (wakeup_window) { + _this->SendWakeupEvent(_this, wakeup_window); } - SDL_UnlockMutex(_this->wakeup_lock); #endif } @@ -1379,9 +1375,7 @@ bool SDL_RunOnMainThread(SDL_MainThreadCallback callback, void *userdata, bool w return true; } - // Maximum wait of 30 seconds to prevent deadlocking forever - const Sint32 MAX_CALLBACK_WAIT = 30 * 1000; - SDL_WaitSemaphoreTimeout(entry->semaphore, MAX_CALLBACK_WAIT); + SDL_WaitSemaphore(entry->semaphore); switch (SDL_GetAtomicInt(&entry->state)) { case SDL_MAIN_CALLBACK_COMPLETE: @@ -1525,18 +1519,7 @@ static int SDL_WaitEventTimeout_Device(SDL_VideoDevice *_this, SDL_Window *wakeu */ SDL_PumpEventsInternal(true); - SDL_LockMutex(_this->wakeup_lock); - { - status = SDL_PeepEvents(event, 1, SDL_GETEVENT, SDL_EVENT_FIRST, SDL_EVENT_LAST); - // If status == 0 we are going to block so wakeup will be needed. - if (status == 0) { - _this->wakeup_window = wakeup_window; - } else { - _this->wakeup_window = NULL; - } - } - SDL_UnlockMutex(_this->wakeup_lock); - + status = SDL_PeepEvents(event, 1, SDL_GETEVENT, SDL_EVENT_FIRST, SDL_EVENT_LAST); if (status < 0) { // Got an error: return break; @@ -1549,8 +1532,6 @@ static int SDL_WaitEventTimeout_Device(SDL_VideoDevice *_this, SDL_Window *wakeu if (timeoutNS > 0) { Sint64 elapsed = SDL_GetTicksNS() - start; if (elapsed >= timeoutNS) { - // Set wakeup_window to NULL without holding the lock. - _this->wakeup_window = NULL; return 0; } loop_timeoutNS = (timeoutNS - elapsed); @@ -1563,9 +1544,9 @@ static int SDL_WaitEventTimeout_Device(SDL_VideoDevice *_this, SDL_Window *wakeu loop_timeoutNS = poll_intervalNS; } } + SDL_SetAtomicPointer(&_this->wakeup_window, wakeup_window); status = _this->WaitEventTimeout(_this, loop_timeoutNS); - // Set wakeup_window to NULL without holding the lock. - _this->wakeup_window = NULL; + SDL_SetAtomicPointer(&_this->wakeup_window, NULL); if (status == 0 && poll_intervalNS != SDL_MAX_SINT64 && loop_timeoutNS == poll_intervalNS) { // We may have woken up to poll. Try again continue; @@ -1823,7 +1804,7 @@ void SDL_SetEventEnabled(Uint32 type, bool enabled) Uint8 lo = (type & 0xff); if (SDL_disabled_events[hi] && - (SDL_disabled_events[hi]->bits[lo / 32] & (1 << (lo & 31)))) { + (SDL_disabled_events[hi]->bits[lo / 32] & (1U << (lo & 31)))) { current_state = false; } else { current_state = true; @@ -1832,7 +1813,7 @@ void SDL_SetEventEnabled(Uint32 type, bool enabled) if ((enabled != false) != current_state) { if (enabled) { SDL_assert(SDL_disabled_events[hi] != NULL); - SDL_disabled_events[hi]->bits[lo / 32] &= ~(1 << (lo & 31)); + SDL_disabled_events[hi]->bits[lo / 32] &= ~(1U << (lo & 31)); // Gamepad events depend on joystick events switch (type) { @@ -1863,7 +1844,7 @@ void SDL_SetEventEnabled(Uint32 type, bool enabled) } // Out of memory, nothing we can do... if (SDL_disabled_events[hi]) { - SDL_disabled_events[hi]->bits[lo / 32] |= (1 << (lo & 31)); + SDL_disabled_events[hi]->bits[lo / 32] |= (1U << (lo & 31)); SDL_FlushEvent(type); } } @@ -1882,7 +1863,7 @@ bool SDL_EventEnabled(Uint32 type) Uint8 lo = (type & 0xff); if (SDL_disabled_events[hi] && - (SDL_disabled_events[hi]->bits[lo / 32] & (1 << (lo & 31)))) { + (SDL_disabled_events[hi]->bits[lo / 32] & (1U << (lo & 31)))) { return false; } else { return true; diff --git a/lib/sdl3/SDL/src/events/SDL_mouse.c b/lib/sdl3/SDL/src/events/SDL_mouse.c index 777733f..92f9913 100644 --- a/lib/sdl3/SDL/src/events/SDL_mouse.c +++ b/lib/sdl3/SDL/src/events/SDL_mouse.c @@ -138,21 +138,25 @@ static void SDLCALL SDL_TouchMouseEventsChanged(void *userdata, const char *name #ifdef SDL_PLATFORM_VITA static void SDLCALL SDL_VitaTouchMouseDeviceChanged(void *userdata, const char *name, const char *oldValue, const char *hint) { + Uint8 vita_touch_mouse_device = 1; + SDL_Mouse *mouse = (SDL_Mouse *)userdata; if (hint) { switch (*hint) { - default: case '0': - mouse->vita_touch_mouse_device = 1; + vita_touch_mouse_device = 1; break; case '1': - mouse->vita_touch_mouse_device = 2; + vita_touch_mouse_device = 2; break; case '2': - mouse->vita_touch_mouse_device = 3; + vita_touch_mouse_device = 3; + break; + default: break; } } + mouse->vita_touch_mouse_device = vita_touch_mouse_device; } #endif @@ -1022,18 +1026,14 @@ void SDL_SendMouseWheel(Uint64 timestamp, SDL_Window *window, SDL_MouseID mouseI SDL_SetMouseFocus(window); } - // Accumulate fractional wheel motion if integer mode is enabled - if (mouse->integer_mode_flags & 2) { - mouse->integer_mode_residual_scroll_x = SDL_modff(mouse->integer_mode_residual_scroll_x + x, &x); - mouse->integer_mode_residual_scroll_y = SDL_modff(mouse->integer_mode_residual_scroll_y + y, &y); - } - if (x == 0.0f && y == 0.0f) { return; } // Post the event, if desired if (SDL_EventEnabled(SDL_EVENT_MOUSE_WHEEL)) { + float integer_x, integer_y; + if (!mouse->relative_mode || mouse->warp_emulation_active) { // We're not in relative mode, so all mouse events are global mouse events mouseID = SDL_GLOBAL_MOUSE_ID; @@ -1044,11 +1044,26 @@ void SDL_SendMouseWheel(Uint64 timestamp, SDL_Window *window, SDL_MouseID mouseI event.common.timestamp = timestamp; event.wheel.windowID = mouse->focus ? mouse->focus->id : 0; event.wheel.which = mouseID; - event.wheel.x = x; - event.wheel.y = y; event.wheel.direction = direction; event.wheel.mouse_x = mouse->x; event.wheel.mouse_y = mouse->y; + + mouse->residual_scroll_x = SDL_modff(mouse->residual_scroll_x + x, &integer_x); + event.wheel.integer_x = (Sint32)integer_x; + + mouse->residual_scroll_y = SDL_modff(mouse->residual_scroll_y + y, &integer_y); + event.wheel.integer_y = (Sint32)integer_y; + + // Return the accumulated values in x/y when integer wheel mode is enabled. + // This is necessary for compatibility with sdl2-compat 2.32.54. + if (mouse->integer_mode_flags & 2) { + event.wheel.x = integer_x; + event.wheel.y = integer_y; + } else { + event.wheel.x = x; + event.wheel.y = y; + } + SDL_PushEvent(&event); } } diff --git a/lib/sdl3/SDL/src/events/SDL_mouse_c.h b/lib/sdl3/SDL/src/events/SDL_mouse_c.h index dd9a0c1..5927b8b 100644 --- a/lib/sdl3/SDL/src/events/SDL_mouse_c.h +++ b/lib/sdl3/SDL/src/events/SDL_mouse_c.h @@ -95,8 +95,6 @@ typedef struct Uint8 integer_mode_flags; // 1 to enable mouse quantization, 2 to enable wheel quantization float integer_mode_residual_motion_x; float integer_mode_residual_motion_y; - float integer_mode_residual_scroll_x; - float integer_mode_residual_scroll_y; // Data common to all mice SDL_Window *focus; @@ -105,6 +103,8 @@ typedef struct float x_accu; float y_accu; float last_x, last_y; // the last reported x and y coordinates + float residual_scroll_x; + float residual_scroll_y; double click_motion_x; double click_motion_y; bool has_position; diff --git a/lib/sdl3/SDL/src/events/SDL_pen.c b/lib/sdl3/SDL/src/events/SDL_pen.c index 1ef7062..cd3730c 100644 --- a/lib/sdl3/SDL/src/events/SDL_pen.c +++ b/lib/sdl3/SDL/src/events/SDL_pen.c @@ -565,10 +565,19 @@ void SDL_SendPenButton(Uint64 timestamp, SDL_PenID instance_id, SDL_Window *wind event.pbutton.down = down; SDL_PushEvent(&event); - if (window && (pen_touching == instance_id)) { + if (window && (!pen_touching || (pen_touching == instance_id))) { SDL_Mouse *mouse = SDL_GetMouse(); if (mouse && mouse->pen_mouse_events) { - SDL_SendMouseButton(timestamp, window, SDL_PEN_MOUSEID, button + 1, down); + static const Uint8 mouse_buttons[] = { + SDL_BUTTON_LEFT, + SDL_BUTTON_RIGHT, + SDL_BUTTON_MIDDLE, + SDL_BUTTON_X1, + SDL_BUTTON_X2 + }; + if (button < SDL_arraysize(mouse_buttons)) { + SDL_SendMouseButton(timestamp, window, SDL_PEN_MOUSEID, mouse_buttons[button], down); + } } } } diff --git a/lib/sdl3/SDL/src/gpu/SDL_gpu.c b/lib/sdl3/SDL/src/gpu/SDL_gpu.c index b7ca696..e1ad66c 100644 --- a/lib/sdl3/SDL/src/gpu/SDL_gpu.c +++ b/lib/sdl3/SDL/src/gpu/SDL_gpu.c @@ -56,15 +56,47 @@ } #define CHECK_RENDERPASS \ - if (!((Pass *)render_pass)->in_progress) { \ + if (!((RenderPass *)render_pass)->in_progress) { \ SDL_assert_release(!"Render pass not in progress!"); \ return; \ } -#define CHECK_GRAPHICS_PIPELINE_BOUND \ - if (!((CommandBufferCommonHeader *)RENDERPASS_COMMAND_BUFFER)->graphics_pipeline_bound) { \ - SDL_assert_release(!"Graphics pipeline not bound!"); \ - return; \ +#define CHECK_SAMPLER_TEXTURES \ + RenderPass *rp = (RenderPass *)render_pass; \ + for (Uint32 color_target_index = 0; color_target_index < rp->num_color_targets; color_target_index += 1) { \ + for (Uint32 texture_sampler_index = 0; texture_sampler_index < num_bindings; texture_sampler_index += 1) { \ + if (rp->color_targets[color_target_index] == texture_sampler_bindings[texture_sampler_index].texture) { \ + SDL_assert_release(!"Texture cannot be simultaneously bound as a color target and a sampler!"); \ + } \ + } \ + } \ + \ + for (Uint32 texture_sampler_index = 0; texture_sampler_index < num_bindings; texture_sampler_index += 1) { \ + if (rp->depth_stencil_target != NULL && rp->depth_stencil_target == texture_sampler_bindings[texture_sampler_index].texture) { \ + SDL_assert_release(!"Texture cannot be simultaneously bound as a depth stencil target and a sampler!"); \ + } \ + } + +#define CHECK_STORAGE_TEXTURES \ + RenderPass *rp = (RenderPass *)render_pass; \ + for (Uint32 color_target_index = 0; color_target_index < rp->num_color_targets; color_target_index += 1) { \ + for (Uint32 texture_sampler_index = 0; texture_sampler_index < num_bindings; texture_sampler_index += 1) { \ + if (rp->color_targets[color_target_index] == storage_textures[texture_sampler_index]) { \ + SDL_assert_release(!"Texture cannot be simultaneously bound as a color target and a storage texture!"); \ + } \ + } \ + } \ + \ + for (Uint32 texture_sampler_index = 0; texture_sampler_index < num_bindings; texture_sampler_index += 1) { \ + if (rp->depth_stencil_target != NULL && rp->depth_stencil_target == storage_textures[texture_sampler_index]) { \ + SDL_assert_release(!"Texture cannot be simultaneously bound as a depth stencil target and a storage texture!"); \ + } \ + } + +#define CHECK_GRAPHICS_PIPELINE_BOUND \ + if (!((RenderPass *)render_pass)->graphics_pipeline) { \ + SDL_assert_release(!"Graphics pipeline not bound!"); \ + return; \ } #define CHECK_COMPUTEPASS \ @@ -74,7 +106,7 @@ } #define CHECK_COMPUTE_PIPELINE_BOUND \ - if (!((CommandBufferCommonHeader *)COMPUTEPASS_COMMAND_BUFFER)->compute_pipeline_bound) { \ + if (!((ComputePass *)compute_pass)->compute_pipeline) { \ SDL_assert_release(!"Compute pipeline not bound!"); \ return; \ } @@ -137,23 +169,137 @@ ((CommandBufferCommonHeader *)command_buffer)->device #define RENDERPASS_COMMAND_BUFFER \ - ((Pass *)render_pass)->command_buffer + ((RenderPass *)render_pass)->command_buffer #define RENDERPASS_DEVICE \ ((CommandBufferCommonHeader *)RENDERPASS_COMMAND_BUFFER)->device +#define RENDERPASS_BOUND_PIPELINE \ + ((RenderPass *)render_pass)->graphics_pipeline + #define COMPUTEPASS_COMMAND_BUFFER \ ((Pass *)compute_pass)->command_buffer #define COMPUTEPASS_DEVICE \ ((CommandBufferCommonHeader *)COMPUTEPASS_COMMAND_BUFFER)->device +#define COMPUTEPASS_BOUND_PIPELINE \ + ((ComputePass *)compute_pass)->compute_pipeline + #define COPYPASS_COMMAND_BUFFER \ ((Pass *)copy_pass)->command_buffer #define COPYPASS_DEVICE \ ((CommandBufferCommonHeader *)COPYPASS_COMMAND_BUFFER)->device +static bool TextureFormatIsComputeWritable[] = { + false, // INVALID + false, // A8_UNORM + true, // R8_UNORM + true, // R8G8_UNORM + true, // R8G8B8A8_UNORM + true, // R16_UNORM + true, // R16G16_UNORM + true, // R16G16B16A16_UNORM + true, // R10G10B10A2_UNORM + false, // B5G6R5_UNORM + false, // B5G5R5A1_UNORM + false, // B4G4R4A4_UNORM + false, // B8G8R8A8_UNORM + false, // BC1_UNORM + false, // BC2_UNORM + false, // BC3_UNORM + false, // BC4_UNORM + false, // BC5_UNORM + false, // BC7_UNORM + false, // BC6H_FLOAT + false, // BC6H_UFLOAT + true, // R8_SNORM + true, // R8G8_SNORM + true, // R8G8B8A8_SNORM + true, // R16_SNORM + true, // R16G16_SNORM + true, // R16G16B16A16_SNORM + true, // R16_FLOAT + true, // R16G16_FLOAT + true, // R16G16B16A16_FLOAT + true, // R32_FLOAT + true, // R32G32_FLOAT + true, // R32G32B32A32_FLOAT + true, // R11G11B10_UFLOAT + true, // R8_UINT + true, // R8G8_UINT + true, // R8G8B8A8_UINT + true, // R16_UINT + true, // R16G16_UINT + true, // R16G16B16A16_UINT + true, // R32_UINT + true, // R32G32_UINT + true, // R32G32B32A32_UINT + true, // R8_INT + true, // R8G8_INT + true, // R8G8B8A8_INT + true, // R16_INT + true, // R16G16_INT + true, // R16G16B16A16_INT + true, // R32_INT + true, // R32G32_INT + true, // R32G32B32A32_INT + false, // R8G8B8A8_UNORM_SRGB + false, // B8G8R8A8_UNORM_SRGB + false, // BC1_UNORM_SRGB + false, // BC3_UNORM_SRGB + false, // BC3_UNORM_SRGB + false, // BC7_UNORM_SRGB + false, // D16_UNORM + false, // D24_UNORM + false, // D32_FLOAT + false, // D24_UNORM_S8_UINT + false, // D32_FLOAT_S8_UINT + false, // ASTC_4x4_UNORM + false, // ASTC_5x4_UNORM + false, // ASTC_5x5_UNORM + false, // ASTC_6x5_UNORM + false, // ASTC_6x6_UNORM + false, // ASTC_8x5_UNORM + false, // ASTC_8x6_UNORM + false, // ASTC_8x8_UNORM + false, // ASTC_10x5_UNORM + false, // ASTC_10x6_UNORM + false, // ASTC_10x8_UNORM + false, // ASTC_10x10_UNORM + false, // ASTC_12x10_UNORM + false, // ASTC_12x12_UNORM + false, // ASTC_4x4_UNORM_SRGB + false, // ASTC_5x4_UNORM_SRGB + false, // ASTC_5x5_UNORM_SRGB + false, // ASTC_6x5_UNORM_SRGB + false, // ASTC_6x6_UNORM_SRGB + false, // ASTC_8x5_UNORM_SRGB + false, // ASTC_8x6_UNORM_SRGB + false, // ASTC_8x8_UNORM_SRGB + false, // ASTC_10x5_UNORM_SRGB + false, // ASTC_10x6_UNORM_SRGB + false, // ASTC_10x8_UNORM_SRGB + false, // ASTC_10x10_UNORM_SRGB + false, // ASTC_12x10_UNORM_SRGB + false, // ASTC_12x12_UNORM_SRGB + false, // ASTC_4x4_FLOAT + false, // ASTC_5x4_FLOAT + false, // ASTC_5x5_FLOAT + false, // ASTC_6x5_FLOAT + false, // ASTC_6x6_FLOAT + false, // ASTC_8x5_FLOAT + false, // ASTC_8x6_FLOAT + false, // ASTC_8x8_FLOAT + false, // ASTC_10x5_FLOAT + false, // ASTC_10x6_FLOAT + false, // ASTC_10x8_FLOAT + false, // ASTC_10x10_FLOAT + false, // ASTC_12x10_FLOAT + false // ASTC_12x12_FLOAT +}; + // Drivers #ifndef SDL_GPU_DISABLED @@ -371,6 +517,73 @@ void SDL_GPU_BlitCommon( SDL_EndGPURenderPass(render_pass); } +static void SDL_GPU_CheckGraphicsBindings(SDL_GPURenderPass *render_pass) +{ + RenderPass *rp = (RenderPass *)render_pass; + GraphicsPipelineCommonHeader *pipeline = (GraphicsPipelineCommonHeader *)RENDERPASS_BOUND_PIPELINE; + for (Uint32 i = 0; i < pipeline->num_vertex_samplers; i += 1) { + if (!rp->vertex_sampler_bound[i]) { + SDL_assert_release(!"Missing vertex sampler binding!"); + } + } + for (Uint32 i = 0; i < pipeline->num_vertex_storage_textures; i += 1) { + if (!rp->vertex_storage_texture_bound[i]) { + SDL_assert_release(!"Missing vertex storage texture binding!"); + } + } + for (Uint32 i = 0; i < pipeline->num_vertex_storage_buffers; i += 1) { + if (!rp->vertex_storage_buffer_bound[i]) { + SDL_assert_release(!"Missing vertex storage buffer binding!"); + } + } + for (Uint32 i = 0; i < pipeline->num_fragment_samplers; i += 1) { + if (!rp->fragment_sampler_bound[i]) { + SDL_assert_release(!"Missing fragment sampler binding!"); + } + } + for (Uint32 i = 0; i < pipeline->num_fragment_storage_textures; i += 1) { + if (!rp->fragment_storage_texture_bound[i]) { + SDL_assert_release(!"Missing fragment storage texture binding!"); + } + } + for (Uint32 i = 0; i < pipeline->num_fragment_storage_buffers; i += 1) { + if (!rp->fragment_storage_buffer_bound[i]) { + SDL_assert_release(!"Missing fragment storage buffer binding!"); + } + } +} + +static void SDL_GPU_CheckComputeBindings(SDL_GPUComputePass *compute_pass) +{ + ComputePass *cp = (ComputePass *)compute_pass; + ComputePipelineCommonHeader *pipeline = (ComputePipelineCommonHeader *)COMPUTEPASS_BOUND_PIPELINE; + for (Uint32 i = 0; i < pipeline->numSamplers; i += 1) { + if (!cp->sampler_bound[i]) { + SDL_assert_release(!"Missing compute sampler binding!"); + } + } + for (Uint32 i = 0; i < pipeline->numReadonlyStorageTextures; i += 1) { + if (!cp->read_only_storage_texture_bound[i]) { + SDL_assert_release(!"Missing compute readonly storage texture binding!"); + } + } + for (Uint32 i = 0; i < pipeline->numReadonlyStorageBuffers; i += 1) { + if (!cp->read_only_storage_buffer_bound[i]) { + SDL_assert_release(!"Missing compute readonly storage buffer binding!"); + } + } + for (Uint32 i = 0; i < pipeline->numReadWriteStorageTextures; i += 1) { + if (!cp->read_write_storage_texture_bound[i]) { + SDL_assert_release(!"Missing compute read-write storage texture binding!"); + } + } + for (Uint32 i = 0; i < pipeline->numReadWriteStorageBuffers; i += 1) { + if (!cp->read_write_storage_buffer_bound[i]) { + SDL_assert_release(!"Missing compute read-write storage buffer bbinding!"); + } + } +} + // Driver Functions #ifndef SDL_GPU_DISABLED @@ -532,7 +745,6 @@ SDL_GPUDevice *SDL_CreateGPUDeviceWithProperties(SDL_PropertiesID props) result = selectedBackend->CreateDevice(debug_mode, preferLowPower, props); if (result != NULL) { result->backend = selectedBackend->name; - result->shader_formats = selectedBackend->shader_formats; result->debug_mode = debug_mode; } } @@ -721,6 +933,13 @@ bool SDL_GPUTextureSupportsFormat( CHECK_TEXTUREFORMAT_ENUM_INVALID(format, false) } + if ((usage & SDL_GPU_TEXTUREUSAGE_COMPUTE_STORAGE_WRITE) || + (usage & SDL_GPU_TEXTUREUSAGE_COMPUTE_STORAGE_SIMULTANEOUS_READ_WRITE)) { + if (!TextureFormatIsComputeWritable[format]) { + return false; + } + } + return device->SupportsTextureFormat( device->driverData, format, @@ -1343,15 +1562,29 @@ SDL_GPUCommandBuffer *SDL_AcquireGPUCommandBuffer( commandBufferHeader = (CommandBufferCommonHeader *)command_buffer; commandBufferHeader->device = device; commandBufferHeader->render_pass.command_buffer = command_buffer; - commandBufferHeader->render_pass.in_progress = false; - commandBufferHeader->graphics_pipeline_bound = false; commandBufferHeader->compute_pass.command_buffer = command_buffer; - commandBufferHeader->compute_pass.in_progress = false; - commandBufferHeader->compute_pipeline_bound = false; commandBufferHeader->copy_pass.command_buffer = command_buffer; - commandBufferHeader->copy_pass.in_progress = false; - commandBufferHeader->swapchain_texture_acquired = false; - commandBufferHeader->submitted = false; + + if (device->debug_mode) { + commandBufferHeader->render_pass.in_progress = false; + commandBufferHeader->render_pass.graphics_pipeline = NULL; + commandBufferHeader->compute_pass.in_progress = false; + commandBufferHeader->compute_pass.compute_pipeline = NULL; + commandBufferHeader->copy_pass.in_progress = false; + commandBufferHeader->swapchain_texture_acquired = false; + commandBufferHeader->submitted = false; + SDL_zeroa(commandBufferHeader->render_pass.vertex_sampler_bound); + SDL_zeroa(commandBufferHeader->render_pass.vertex_storage_texture_bound); + SDL_zeroa(commandBufferHeader->render_pass.vertex_storage_buffer_bound); + SDL_zeroa(commandBufferHeader->render_pass.fragment_sampler_bound); + SDL_zeroa(commandBufferHeader->render_pass.fragment_storage_texture_bound); + SDL_zeroa(commandBufferHeader->render_pass.fragment_storage_buffer_bound); + SDL_zeroa(commandBufferHeader->compute_pass.sampler_bound); + SDL_zeroa(commandBufferHeader->compute_pass.read_only_storage_texture_bound); + SDL_zeroa(commandBufferHeader->compute_pass.read_only_storage_buffer_bound); + SDL_zeroa(commandBufferHeader->compute_pass.read_write_storage_texture_bound); + SDL_zeroa(commandBufferHeader->compute_pass.read_write_storage_buffer_bound); + } return command_buffer; } @@ -1469,30 +1702,47 @@ SDL_GPURenderPass *SDL_BeginGPURenderPass( if (color_target_infos[i].cycle && color_target_infos[i].load_op == SDL_GPU_LOADOP_LOAD) { SDL_assert_release(!"Cannot cycle color target when load op is LOAD!"); + return NULL; } if (color_target_infos[i].store_op == SDL_GPU_STOREOP_RESOLVE || color_target_infos[i].store_op == SDL_GPU_STOREOP_RESOLVE_AND_STORE) { if (color_target_infos[i].resolve_texture == NULL) { SDL_assert_release(!"Store op is RESOLVE or RESOLVE_AND_STORE but resolve_texture is NULL!"); + return NULL; } else { TextureCommonHeader *resolveTextureHeader = (TextureCommonHeader *)color_target_infos[i].resolve_texture; if (textureHeader->info.sample_count == SDL_GPU_SAMPLECOUNT_1) { SDL_assert_release(!"Store op is RESOLVE or RESOLVE_AND_STORE but texture is not multisample!"); + return NULL; } if (resolveTextureHeader->info.sample_count != SDL_GPU_SAMPLECOUNT_1) { SDL_assert_release(!"Resolve texture must have a sample count of 1!"); + return NULL; } if (resolveTextureHeader->info.format != textureHeader->info.format) { SDL_assert_release(!"Resolve texture must have the same format as its corresponding color target!"); + return NULL; } if (resolveTextureHeader->info.type == SDL_GPU_TEXTURETYPE_3D) { SDL_assert_release(!"Resolve texture must not be of TEXTURETYPE_3D!"); + return NULL; } if (!(resolveTextureHeader->info.usage & SDL_GPU_TEXTUREUSAGE_COLOR_TARGET)) { SDL_assert_release(!"Resolve texture usage must include COLOR_TARGET!"); + return NULL; } } } + + if (color_target_infos[i].layer_or_depth_plane >= textureHeader->info.layer_count_or_depth) { + SDL_assert_release(!"Color target layer index must be less than the texture's layer count!"); + return NULL; + } + + if (color_target_infos[i].mip_level >= textureHeader->info.num_levels) { + SDL_assert_release(!"Color target mip level must be less than the texture's level count!"); + return NULL; + } } if (depth_stencil_target_info != NULL) { @@ -1500,10 +1750,12 @@ SDL_GPURenderPass *SDL_BeginGPURenderPass( TextureCommonHeader *textureHeader = (TextureCommonHeader *)depth_stencil_target_info->texture; if (!(textureHeader->info.usage & SDL_GPU_TEXTUREUSAGE_DEPTH_STENCIL_TARGET)) { SDL_assert_release(!"Depth target must have been created with the DEPTH_STENCIL_TARGET usage flag!"); + return NULL; } if (depth_stencil_target_info->cycle && (depth_stencil_target_info->load_op == SDL_GPU_LOADOP_LOAD || depth_stencil_target_info->stencil_load_op == SDL_GPU_LOADOP_LOAD)) { SDL_assert_release(!"Cannot cycle depth target when load op or stencil load op is LOAD!"); + return NULL; } if (depth_stencil_target_info->store_op == SDL_GPU_STOREOP_RESOLVE || @@ -1511,6 +1763,7 @@ SDL_GPURenderPass *SDL_BeginGPURenderPass( depth_stencil_target_info->store_op == SDL_GPU_STOREOP_RESOLVE_AND_STORE || depth_stencil_target_info->stencil_store_op == SDL_GPU_STOREOP_RESOLVE_AND_STORE) { SDL_assert_release(!"RESOLVE store ops are not supported for depth-stencil targets!"); + return NULL; } } } @@ -1522,7 +1775,18 @@ SDL_GPURenderPass *SDL_BeginGPURenderPass( depth_stencil_target_info); commandBufferHeader = (CommandBufferCommonHeader *)command_buffer; - commandBufferHeader->render_pass.in_progress = true; + + if (COMMAND_BUFFER_DEVICE->debug_mode) { + commandBufferHeader->render_pass.in_progress = true; + for (Uint32 i = 0; i < num_color_targets; i += 1) { + commandBufferHeader->render_pass.color_targets[i] = color_target_infos[i].texture; + } + commandBufferHeader->render_pass.num_color_targets = num_color_targets; + if (depth_stencil_target_info != NULL) { + commandBufferHeader->render_pass.depth_stencil_target = depth_stencil_target_info->texture; + } + } + return (SDL_GPURenderPass *)&(commandBufferHeader->render_pass); } @@ -1530,8 +1794,6 @@ void SDL_BindGPUGraphicsPipeline( SDL_GPURenderPass *render_pass, SDL_GPUGraphicsPipeline *graphics_pipeline) { - CommandBufferCommonHeader *commandBufferHeader; - if (render_pass == NULL) { SDL_InvalidParamError("render_pass"); return; @@ -1545,8 +1807,10 @@ void SDL_BindGPUGraphicsPipeline( RENDERPASS_COMMAND_BUFFER, graphics_pipeline); - commandBufferHeader = (CommandBufferCommonHeader *)RENDERPASS_COMMAND_BUFFER; - commandBufferHeader->graphics_pipeline_bound = true; + + if (RENDERPASS_DEVICE->debug_mode) { + RENDERPASS_BOUND_PIPELINE = graphics_pipeline; + } } void SDL_SetGPUViewport( @@ -1696,6 +1960,15 @@ void SDL_BindGPUVertexSamplers( if (RENDERPASS_DEVICE->debug_mode) { CHECK_RENDERPASS + + if (!((CommandBufferCommonHeader*)RENDERPASS_COMMAND_BUFFER)->ignore_render_pass_texture_validation) + { + CHECK_SAMPLER_TEXTURES + } + + for (Uint32 i = 0; i < num_bindings; i += 1) { + ((RenderPass *)render_pass)->vertex_sampler_bound[first_slot + i] = true; + } } RENDERPASS_DEVICE->BindVertexSamplers( @@ -1722,6 +1995,11 @@ void SDL_BindGPUVertexStorageTextures( if (RENDERPASS_DEVICE->debug_mode) { CHECK_RENDERPASS + CHECK_STORAGE_TEXTURES + + for (Uint32 i = 0; i < num_bindings; i += 1) { + ((RenderPass *)render_pass)->vertex_storage_texture_bound[first_slot + i] = true; + } } RENDERPASS_DEVICE->BindVertexStorageTextures( @@ -1748,6 +2026,10 @@ void SDL_BindGPUVertexStorageBuffers( if (RENDERPASS_DEVICE->debug_mode) { CHECK_RENDERPASS + + for (Uint32 i = 0; i < num_bindings; i += 1) { + ((RenderPass *)render_pass)->vertex_storage_buffer_bound[first_slot + i] = true; + } } RENDERPASS_DEVICE->BindVertexStorageBuffers( @@ -1774,6 +2056,14 @@ void SDL_BindGPUFragmentSamplers( if (RENDERPASS_DEVICE->debug_mode) { CHECK_RENDERPASS + + if (!((CommandBufferCommonHeader*)RENDERPASS_COMMAND_BUFFER)->ignore_render_pass_texture_validation) { + CHECK_SAMPLER_TEXTURES + } + + for (Uint32 i = 0; i < num_bindings; i += 1) { + ((RenderPass *)render_pass)->fragment_sampler_bound[first_slot + i] = true; + } } RENDERPASS_DEVICE->BindFragmentSamplers( @@ -1800,6 +2090,11 @@ void SDL_BindGPUFragmentStorageTextures( if (RENDERPASS_DEVICE->debug_mode) { CHECK_RENDERPASS + CHECK_STORAGE_TEXTURES + + for (Uint32 i = 0; i < num_bindings; i += 1) { + ((RenderPass *)render_pass)->fragment_storage_texture_bound[first_slot + i] = true; + } } RENDERPASS_DEVICE->BindFragmentStorageTextures( @@ -1826,6 +2121,10 @@ void SDL_BindGPUFragmentStorageBuffers( if (RENDERPASS_DEVICE->debug_mode) { CHECK_RENDERPASS + + for (Uint32 i = 0; i < num_bindings; i += 1) { + ((RenderPass *)render_pass)->fragment_storage_buffer_bound[first_slot + i] = true; + } } RENDERPASS_DEVICE->BindFragmentStorageBuffers( @@ -1851,6 +2150,7 @@ void SDL_DrawGPUIndexedPrimitives( if (RENDERPASS_DEVICE->debug_mode) { CHECK_RENDERPASS CHECK_GRAPHICS_PIPELINE_BOUND + SDL_GPU_CheckGraphicsBindings(render_pass); } RENDERPASS_DEVICE->DrawIndexedPrimitives( @@ -1877,6 +2177,7 @@ void SDL_DrawGPUPrimitives( if (RENDERPASS_DEVICE->debug_mode) { CHECK_RENDERPASS CHECK_GRAPHICS_PIPELINE_BOUND + SDL_GPU_CheckGraphicsBindings(render_pass); } RENDERPASS_DEVICE->DrawPrimitives( @@ -1905,6 +2206,7 @@ void SDL_DrawGPUPrimitivesIndirect( if (RENDERPASS_DEVICE->debug_mode) { CHECK_RENDERPASS CHECK_GRAPHICS_PIPELINE_BOUND + SDL_GPU_CheckGraphicsBindings(render_pass); } RENDERPASS_DEVICE->DrawPrimitivesIndirect( @@ -1932,6 +2234,7 @@ void SDL_DrawGPUIndexedPrimitivesIndirect( if (RENDERPASS_DEVICE->debug_mode) { CHECK_RENDERPASS CHECK_GRAPHICS_PIPELINE_BOUND + SDL_GPU_CheckGraphicsBindings(render_pass); } RENDERPASS_DEVICE->DrawIndexedPrimitivesIndirect( @@ -1945,6 +2248,7 @@ void SDL_EndGPURenderPass( SDL_GPURenderPass *render_pass) { CommandBufferCommonHeader *commandBufferCommonHeader; + commandBufferCommonHeader = (CommandBufferCommonHeader *)RENDERPASS_COMMAND_BUFFER; if (render_pass == NULL) { SDL_InvalidParamError("render_pass"); @@ -1958,9 +2262,22 @@ void SDL_EndGPURenderPass( RENDERPASS_DEVICE->EndRenderPass( RENDERPASS_COMMAND_BUFFER); - commandBufferCommonHeader = (CommandBufferCommonHeader *)RENDERPASS_COMMAND_BUFFER; - commandBufferCommonHeader->render_pass.in_progress = false; - commandBufferCommonHeader->graphics_pipeline_bound = false; + if (RENDERPASS_DEVICE->debug_mode) { + commandBufferCommonHeader->render_pass.in_progress = false; + for (Uint32 i = 0; i < MAX_COLOR_TARGET_BINDINGS; i += 1) + { + commandBufferCommonHeader->render_pass.color_targets[i] = NULL; + } + commandBufferCommonHeader->render_pass.num_color_targets = 0; + commandBufferCommonHeader->render_pass.depth_stencil_target = NULL; + commandBufferCommonHeader->render_pass.graphics_pipeline = NULL; + SDL_zeroa(commandBufferCommonHeader->render_pass.vertex_sampler_bound); + SDL_zeroa(commandBufferCommonHeader->render_pass.vertex_storage_texture_bound); + SDL_zeroa(commandBufferCommonHeader->render_pass.vertex_storage_buffer_bound); + SDL_zeroa(commandBufferCommonHeader->render_pass.fragment_sampler_bound); + SDL_zeroa(commandBufferCommonHeader->render_pass.fragment_storage_texture_bound); + SDL_zeroa(commandBufferCommonHeader->render_pass.fragment_storage_buffer_bound); + } } // Compute Pass @@ -2004,6 +2321,16 @@ SDL_GPUComputePass *SDL_BeginGPUComputePass( SDL_assert_release(!"Texture must be created with COMPUTE_STORAGE_WRITE or COMPUTE_STORAGE_SIMULTANEOUS_READ_WRITE flag"); return NULL; } + + if (storage_texture_bindings[i].layer >= header->info.layer_count_or_depth) { + SDL_assert_release(!"Storage texture layer index must be less than the texture's layer count!"); + return NULL; + } + + if (storage_texture_bindings[i].mip_level >= header->info.num_levels) { + SDL_assert_release(!"Storage texture mip level must be less than the texture's level count!"); + return NULL; + } } // TODO: validate buffer usage? @@ -2017,7 +2344,19 @@ SDL_GPUComputePass *SDL_BeginGPUComputePass( num_storage_buffer_bindings); commandBufferHeader = (CommandBufferCommonHeader *)command_buffer; - commandBufferHeader->compute_pass.in_progress = true; + + if (COMMAND_BUFFER_DEVICE->debug_mode) { + commandBufferHeader->compute_pass.in_progress = true; + + for (Uint32 i = 0; i < num_storage_texture_bindings; i += 1) { + commandBufferHeader->compute_pass.read_write_storage_texture_bound[i] = true; + } + + for (Uint32 i = 0; i < num_storage_buffer_bindings; i += 1) { + commandBufferHeader->compute_pass.read_write_storage_buffer_bound[i] = true; + } + } + return (SDL_GPUComputePass *)&(commandBufferHeader->compute_pass); } @@ -2025,8 +2364,6 @@ void SDL_BindGPUComputePipeline( SDL_GPUComputePass *compute_pass, SDL_GPUComputePipeline *compute_pipeline) { - CommandBufferCommonHeader *commandBufferHeader; - if (compute_pass == NULL) { SDL_InvalidParamError("compute_pass"); return; @@ -2044,8 +2381,10 @@ void SDL_BindGPUComputePipeline( COMPUTEPASS_COMMAND_BUFFER, compute_pipeline); - commandBufferHeader = (CommandBufferCommonHeader *)COMPUTEPASS_COMMAND_BUFFER; - commandBufferHeader->compute_pipeline_bound = true; + + if (COMPUTEPASS_DEVICE->debug_mode) { + COMPUTEPASS_BOUND_PIPELINE = compute_pipeline; + } } void SDL_BindGPUComputeSamplers( @@ -2065,6 +2404,10 @@ void SDL_BindGPUComputeSamplers( if (COMPUTEPASS_DEVICE->debug_mode) { CHECK_COMPUTEPASS + + for (Uint32 i = 0; i < num_bindings; i += 1) { + ((ComputePass *)compute_pass)->sampler_bound[first_slot + i] = true; + } } COMPUTEPASS_DEVICE->BindComputeSamplers( @@ -2091,6 +2434,10 @@ void SDL_BindGPUComputeStorageTextures( if (COMPUTEPASS_DEVICE->debug_mode) { CHECK_COMPUTEPASS + + for (Uint32 i = 0; i < num_bindings; i += 1) { + ((ComputePass *)compute_pass)->read_only_storage_texture_bound[first_slot + i] = true; + } } COMPUTEPASS_DEVICE->BindComputeStorageTextures( @@ -2117,6 +2464,10 @@ void SDL_BindGPUComputeStorageBuffers( if (COMPUTEPASS_DEVICE->debug_mode) { CHECK_COMPUTEPASS + + for (Uint32 i = 0; i < num_bindings; i += 1) { + ((ComputePass *)compute_pass)->read_only_storage_buffer_bound[first_slot + i] = true; + } } COMPUTEPASS_DEVICE->BindComputeStorageBuffers( @@ -2140,6 +2491,7 @@ void SDL_DispatchGPUCompute( if (COMPUTEPASS_DEVICE->debug_mode) { CHECK_COMPUTEPASS CHECK_COMPUTE_PIPELINE_BOUND + SDL_GPU_CheckComputeBindings(compute_pass); } COMPUTEPASS_DEVICE->DispatchCompute( @@ -2162,6 +2514,7 @@ void SDL_DispatchGPUComputeIndirect( if (COMPUTEPASS_DEVICE->debug_mode) { CHECK_COMPUTEPASS CHECK_COMPUTE_PIPELINE_BOUND + SDL_GPU_CheckComputeBindings(compute_pass); } COMPUTEPASS_DEVICE->DispatchComputeIndirect( @@ -2187,9 +2540,16 @@ void SDL_EndGPUComputePass( COMPUTEPASS_DEVICE->EndComputePass( COMPUTEPASS_COMMAND_BUFFER); - commandBufferCommonHeader = (CommandBufferCommonHeader *)COMPUTEPASS_COMMAND_BUFFER; - commandBufferCommonHeader->compute_pass.in_progress = false; - commandBufferCommonHeader->compute_pipeline_bound = false; + if (COMPUTEPASS_DEVICE->debug_mode) { + commandBufferCommonHeader = (CommandBufferCommonHeader *)COMPUTEPASS_COMMAND_BUFFER; + commandBufferCommonHeader->compute_pass.in_progress = false; + commandBufferCommonHeader->compute_pass.compute_pipeline = false; + SDL_zeroa(commandBufferCommonHeader->compute_pass.sampler_bound); + SDL_zeroa(commandBufferCommonHeader->compute_pass.read_only_storage_texture_bound); + SDL_zeroa(commandBufferCommonHeader->compute_pass.read_only_storage_buffer_bound); + SDL_zeroa(commandBufferCommonHeader->compute_pass.read_write_storage_texture_bound); + SDL_zeroa(commandBufferCommonHeader->compute_pass.read_write_storage_buffer_bound); + } } // TransferBuffer Data @@ -2247,7 +2607,11 @@ SDL_GPUCopyPass *SDL_BeginGPUCopyPass( command_buffer); commandBufferHeader = (CommandBufferCommonHeader *)command_buffer; - commandBufferHeader->copy_pass.in_progress = true; + + if (COMMAND_BUFFER_DEVICE->debug_mode) { + commandBufferHeader->copy_pass.in_progress = true; + } + return (SDL_GPUCopyPass *)&(commandBufferHeader->copy_pass); } @@ -2498,7 +2862,9 @@ void SDL_EndGPUCopyPass( COPYPASS_DEVICE->EndCopyPass( COPYPASS_COMMAND_BUFFER); - ((CommandBufferCommonHeader *)COPYPASS_COMMAND_BUFFER)->copy_pass.in_progress = false; + if (COPYPASS_DEVICE->debug_mode) { + ((CommandBufferCommonHeader *)COPYPASS_COMMAND_BUFFER)->copy_pass.in_progress = false; + } } void SDL_GenerateMipmapsForGPUTexture( @@ -2528,11 +2894,19 @@ void SDL_GenerateMipmapsForGPUTexture( SDL_assert_release(!"GenerateMipmaps texture must be created with SAMPLER and COLOR_TARGET usage flags!"); return; } + + CommandBufferCommonHeader *commandBufferHeader = (CommandBufferCommonHeader *)command_buffer; + commandBufferHeader->ignore_render_pass_texture_validation = true; } COMMAND_BUFFER_DEVICE->GenerateMipmaps( command_buffer, texture); + + if (COMMAND_BUFFER_DEVICE->debug_mode) { + CommandBufferCommonHeader *commandBufferHeader = (CommandBufferCommonHeader *)command_buffer; + commandBufferHeader->ignore_render_pass_texture_validation = false; + } } void SDL_BlitGPUTexture( diff --git a/lib/sdl3/SDL/src/gpu/SDL_sysgpu.h b/lib/sdl3/SDL/src/gpu/SDL_sysgpu.h index 6de1765..8469d94 100644 --- a/lib/sdl3/SDL/src/gpu/SDL_sysgpu.h +++ b/lib/sdl3/SDL/src/gpu/SDL_sysgpu.h @@ -24,6 +24,21 @@ #ifndef SDL_GPU_DRIVER_H #define SDL_GPU_DRIVER_H +// GraphicsDevice Limits + +#define MAX_TEXTURE_SAMPLERS_PER_STAGE 16 +#define MAX_STORAGE_TEXTURES_PER_STAGE 8 +#define MAX_STORAGE_BUFFERS_PER_STAGE 8 +#define MAX_UNIFORM_BUFFERS_PER_STAGE 4 +#define MAX_COMPUTE_WRITE_TEXTURES 8 +#define MAX_COMPUTE_WRITE_BUFFERS 8 +#define UNIFORM_BUFFER_SIZE 32768 +#define MAX_VERTEX_BUFFERS 16 +#define MAX_VERTEX_ATTRIBUTES 16 +#define MAX_COLOR_TARGET_BINDINGS 4 +#define MAX_PRESENT_COUNT 16 +#define MAX_FRAMES_IN_FLIGHT 3 + // Common Structs typedef struct Pass @@ -32,16 +47,51 @@ typedef struct Pass bool in_progress; } Pass; +typedef struct ComputePass +{ + SDL_GPUCommandBuffer *command_buffer; + bool in_progress; + + SDL_GPUComputePipeline *compute_pipeline; + + bool sampler_bound[MAX_TEXTURE_SAMPLERS_PER_STAGE]; + bool read_only_storage_texture_bound[MAX_STORAGE_TEXTURES_PER_STAGE]; + bool read_only_storage_buffer_bound[MAX_STORAGE_BUFFERS_PER_STAGE]; + bool read_write_storage_texture_bound[MAX_COMPUTE_WRITE_TEXTURES]; + bool read_write_storage_buffer_bound[MAX_COMPUTE_WRITE_BUFFERS]; +} ComputePass; + +typedef struct RenderPass +{ + SDL_GPUCommandBuffer *command_buffer; + bool in_progress; + SDL_GPUTexture *color_targets[MAX_COLOR_TARGET_BINDINGS]; + Uint32 num_color_targets; + SDL_GPUTexture *depth_stencil_target; + + SDL_GPUGraphicsPipeline *graphics_pipeline; + + bool vertex_sampler_bound[MAX_TEXTURE_SAMPLERS_PER_STAGE]; + bool vertex_storage_texture_bound[MAX_STORAGE_TEXTURES_PER_STAGE]; + bool vertex_storage_buffer_bound[MAX_STORAGE_BUFFERS_PER_STAGE]; + + bool fragment_sampler_bound[MAX_TEXTURE_SAMPLERS_PER_STAGE]; + bool fragment_storage_texture_bound[MAX_STORAGE_TEXTURES_PER_STAGE]; + bool fragment_storage_buffer_bound[MAX_STORAGE_BUFFERS_PER_STAGE]; +} RenderPass; + typedef struct CommandBufferCommonHeader { SDL_GPUDevice *device; - Pass render_pass; - bool graphics_pipeline_bound; - Pass compute_pass; - bool compute_pipeline_bound; + + RenderPass render_pass; + ComputePass compute_pass; + Pass copy_pass; bool swapchain_texture_acquired; bool submitted; + // used to avoid tripping assert on GenerateMipmaps + bool ignore_render_pass_texture_validation; } CommandBufferCommonHeader; typedef struct TextureCommonHeader @@ -49,6 +99,29 @@ typedef struct TextureCommonHeader SDL_GPUTextureCreateInfo info; } TextureCommonHeader; +typedef struct GraphicsPipelineCommonHeader +{ + Uint32 num_vertex_samplers; + Uint32 num_vertex_storage_textures; + Uint32 num_vertex_storage_buffers; + Uint32 num_vertex_uniform_buffers; + + Uint32 num_fragment_samplers; + Uint32 num_fragment_storage_textures; + Uint32 num_fragment_storage_buffers; + Uint32 num_fragment_uniform_buffers; +} GraphicsPipelineCommonHeader; + +typedef struct ComputePipelineCommonHeader +{ + Uint32 numSamplers; + Uint32 numReadonlyStorageTextures; + Uint32 numReadonlyStorageBuffers; + Uint32 numReadWriteStorageTextures; + Uint32 numReadWriteStorageBuffers; + Uint32 numUniformBuffers; +} ComputePipelineCommonHeader; + typedef struct BlitFragmentUniforms { // texcoord space @@ -136,6 +209,7 @@ static inline Sint32 Texture_GetBlockWidth( case SDL_GPU_TEXTUREFORMAT_BC6H_RGB_FLOAT: case SDL_GPU_TEXTUREFORMAT_BC6H_RGB_UFLOAT: case SDL_GPU_TEXTUREFORMAT_BC1_RGBA_UNORM_SRGB: + case SDL_GPU_TEXTUREFORMAT_BC2_RGBA_UNORM_SRGB: case SDL_GPU_TEXTUREFORMAT_BC3_RGBA_UNORM_SRGB: case SDL_GPU_TEXTUREFORMAT_BC7_RGBA_UNORM_SRGB: case SDL_GPU_TEXTUREFORMAT_ASTC_4x4_UNORM: @@ -253,6 +327,7 @@ static inline Sint32 Texture_GetBlockHeight( case SDL_GPU_TEXTUREFORMAT_BC6H_RGB_FLOAT: case SDL_GPU_TEXTUREFORMAT_BC6H_RGB_UFLOAT: case SDL_GPU_TEXTUREFORMAT_BC1_RGBA_UNORM_SRGB: + case SDL_GPU_TEXTUREFORMAT_BC2_RGBA_UNORM_SRGB: case SDL_GPU_TEXTUREFORMAT_BC3_RGBA_UNORM_SRGB: case SDL_GPU_TEXTUREFORMAT_BC7_RGBA_UNORM_SRGB: case SDL_GPU_TEXTUREFORMAT_ASTC_5x4_UNORM: @@ -385,21 +460,6 @@ static inline Uint32 BytesPerRow( return blocksPerRow * SDL_GPUTextureFormatTexelBlockSize(format); } -// GraphicsDevice Limits - -#define MAX_TEXTURE_SAMPLERS_PER_STAGE 16 -#define MAX_STORAGE_TEXTURES_PER_STAGE 8 -#define MAX_STORAGE_BUFFERS_PER_STAGE 8 -#define MAX_UNIFORM_BUFFERS_PER_STAGE 4 -#define MAX_COMPUTE_WRITE_TEXTURES 8 -#define MAX_COMPUTE_WRITE_BUFFERS 8 -#define UNIFORM_BUFFER_SIZE 32768 -#define MAX_VERTEX_BUFFERS 16 -#define MAX_VERTEX_ATTRIBUTES 16 -#define MAX_COLOR_TARGET_BINDINGS 4 -#define MAX_PRESENT_COUNT 16 -#define MAX_FRAMES_IN_FLIGHT 3 - // Internal Macros #define EXPAND_ARRAY_IF_NEEDED(arr, elementType, newCount, capacity, newCapacity) \ diff --git a/lib/sdl3/SDL/src/gpu/d3d12/SDL_gpu_d3d12.c b/lib/sdl3/SDL/src/gpu/d3d12/SDL_gpu_d3d12.c index be13d8d..a922159 100644 --- a/lib/sdl3/SDL/src/gpu/d3d12/SDL_gpu_d3d12.c +++ b/lib/sdl3/SDL/src/gpu/d3d12/SDL_gpu_d3d12.c @@ -475,6 +475,115 @@ static DXGI_FORMAT SDLToD3D12_DepthFormat[] = { }; SDL_COMPILE_TIME_ASSERT(SDLToD3D12_DepthFormat, SDL_arraysize(SDLToD3D12_DepthFormat) == SDL_GPU_TEXTUREFORMAT_MAX_ENUM_VALUE); +static DXGI_FORMAT SDLToD3D12_TypelessFormat[] = { + DXGI_FORMAT_UNKNOWN, // INVALID + DXGI_FORMAT_UNKNOWN, // A8_UNORM + DXGI_FORMAT_UNKNOWN, // R8_UNORM + DXGI_FORMAT_UNKNOWN, // R8G8_UNORM + DXGI_FORMAT_UNKNOWN, // R8G8B8A8_UNORM + DXGI_FORMAT_UNKNOWN, // R16_UNORM + DXGI_FORMAT_UNKNOWN, // R16G16_UNORM + DXGI_FORMAT_UNKNOWN, // R16G16B16A16_UNORM + DXGI_FORMAT_UNKNOWN, // R10G10B10A2_UNORM + DXGI_FORMAT_UNKNOWN, // B5G6R5_UNORM + DXGI_FORMAT_UNKNOWN, // B5G5R5A1_UNORM + DXGI_FORMAT_UNKNOWN, // B4G4R4A4_UNORM + DXGI_FORMAT_UNKNOWN, // B8G8R8A8_UNORM + DXGI_FORMAT_UNKNOWN, // BC1_UNORM + DXGI_FORMAT_UNKNOWN, // BC2_UNORM + DXGI_FORMAT_UNKNOWN, // BC3_UNORM + DXGI_FORMAT_UNKNOWN, // BC4_UNORM + DXGI_FORMAT_UNKNOWN, // BC5_UNORM + DXGI_FORMAT_UNKNOWN, // BC7_UNORM + DXGI_FORMAT_UNKNOWN, // BC6H_FLOAT + DXGI_FORMAT_UNKNOWN, // BC6H_UFLOAT + DXGI_FORMAT_UNKNOWN, // R8_SNORM + DXGI_FORMAT_UNKNOWN, // R8G8_SNORM + DXGI_FORMAT_UNKNOWN, // R8G8B8A8_SNORM + DXGI_FORMAT_UNKNOWN, // R16_SNORM + DXGI_FORMAT_UNKNOWN, // R16G16_SNORM + DXGI_FORMAT_UNKNOWN, // R16G16B16A16_SNORM + DXGI_FORMAT_UNKNOWN, // R16_FLOAT + DXGI_FORMAT_UNKNOWN, // R16G16_FLOAT + DXGI_FORMAT_UNKNOWN, // R16G16B16A16_FLOAT + DXGI_FORMAT_UNKNOWN, // R32_FLOAT + DXGI_FORMAT_UNKNOWN, // R32G32_FLOAT + DXGI_FORMAT_UNKNOWN, // R32G32B32A32_FLOAT + DXGI_FORMAT_UNKNOWN, // R11G11B10_UFLOAT + DXGI_FORMAT_UNKNOWN, // R8_UINT + DXGI_FORMAT_UNKNOWN, // R8G8_UINT + DXGI_FORMAT_UNKNOWN, // R8G8B8A8_UINT + DXGI_FORMAT_UNKNOWN, // R16_UINT + DXGI_FORMAT_UNKNOWN, // R16G16_UINT + DXGI_FORMAT_UNKNOWN, // R16G16B16A16_UINT + DXGI_FORMAT_UNKNOWN, // R32_UINT + DXGI_FORMAT_UNKNOWN, // R32G32_UINT + DXGI_FORMAT_UNKNOWN, // R32G32B32A32_UINT + DXGI_FORMAT_UNKNOWN, // R8_INT + DXGI_FORMAT_UNKNOWN, // R8G8_INT + DXGI_FORMAT_UNKNOWN, // R8G8B8A8_INT + DXGI_FORMAT_UNKNOWN, // R16_INT + DXGI_FORMAT_UNKNOWN, // R16G16_INT + DXGI_FORMAT_UNKNOWN, // R16G16B16A16_INT + DXGI_FORMAT_UNKNOWN, // R32_INT + DXGI_FORMAT_UNKNOWN, // R32G32_INT + DXGI_FORMAT_UNKNOWN, // R32G32B32A32_INT + DXGI_FORMAT_UNKNOWN, // R8G8B8A8_UNORM_SRGB + DXGI_FORMAT_UNKNOWN, // B8G8R8A8_UNORM_SRGB + DXGI_FORMAT_UNKNOWN, // BC1_UNORM_SRGB + DXGI_FORMAT_UNKNOWN, // BC2_UNORM_SRGB + DXGI_FORMAT_UNKNOWN, // BC3_UNORM_SRGB + DXGI_FORMAT_UNKNOWN, // BC7_UNORM_SRGB + DXGI_FORMAT_R16_TYPELESS, // D16_UNORM + DXGI_FORMAT_R24G8_TYPELESS, // D24_UNORM + DXGI_FORMAT_R32_TYPELESS, // D32_FLOAT + DXGI_FORMAT_R24G8_TYPELESS, // D24_UNORM_S8_UINT + DXGI_FORMAT_R32G8X24_TYPELESS, // D32_FLOAT_S8_UINT + DXGI_FORMAT_UNKNOWN, // ASTC_4x4_UNORM + DXGI_FORMAT_UNKNOWN, // ASTC_5x4_UNORM + DXGI_FORMAT_UNKNOWN, // ASTC_5x5_UNORM + DXGI_FORMAT_UNKNOWN, // ASTC_6x5_UNORM + DXGI_FORMAT_UNKNOWN, // ASTC_6x6_UNORM + DXGI_FORMAT_UNKNOWN, // ASTC_8x5_UNORM + DXGI_FORMAT_UNKNOWN, // ASTC_8x6_UNORM + DXGI_FORMAT_UNKNOWN, // ASTC_8x8_UNORM + DXGI_FORMAT_UNKNOWN, // ASTC_10x5_UNORM + DXGI_FORMAT_UNKNOWN, // ASTC_10x6_UNORM + DXGI_FORMAT_UNKNOWN, // ASTC_10x8_UNORM + DXGI_FORMAT_UNKNOWN, // ASTC_10x10_UNORM + DXGI_FORMAT_UNKNOWN, // ASTC_12x10_UNORM + DXGI_FORMAT_UNKNOWN, // ASTC_12x12_UNORM + DXGI_FORMAT_UNKNOWN, // ASTC_4x4_UNORM_SRGB + DXGI_FORMAT_UNKNOWN, // ASTC_5x4_UNORM_SRGB + DXGI_FORMAT_UNKNOWN, // ASTC_5x5_UNORM_SRGB + DXGI_FORMAT_UNKNOWN, // ASTC_6x5_UNORM_SRGB + DXGI_FORMAT_UNKNOWN, // ASTC_6x6_UNORM_SRGB + DXGI_FORMAT_UNKNOWN, // ASTC_8x5_UNORM_SRGB + DXGI_FORMAT_UNKNOWN, // ASTC_8x6_UNORM_SRGB + DXGI_FORMAT_UNKNOWN, // ASTC_8x8_UNORM_SRGB + DXGI_FORMAT_UNKNOWN, // ASTC_10x5_UNORM_SRGB + DXGI_FORMAT_UNKNOWN, // ASTC_10x6_UNORM_SRGB + DXGI_FORMAT_UNKNOWN, // ASTC_10x8_UNORM_SRGB + DXGI_FORMAT_UNKNOWN, // ASTC_10x10_UNORM_SRGB + DXGI_FORMAT_UNKNOWN, // ASTC_12x10_UNORM_SRGB + DXGI_FORMAT_UNKNOWN, // ASTC_12x12_UNORM_SRGB + DXGI_FORMAT_UNKNOWN, // ASTC_4x4_FLOAT + DXGI_FORMAT_UNKNOWN, // ASTC_5x4_FLOAT + DXGI_FORMAT_UNKNOWN, // ASTC_5x5_FLOAT + DXGI_FORMAT_UNKNOWN, // ASTC_6x5_FLOAT + DXGI_FORMAT_UNKNOWN, // ASTC_6x6_FLOAT + DXGI_FORMAT_UNKNOWN, // ASTC_8x5_FLOAT + DXGI_FORMAT_UNKNOWN, // ASTC_8x6_FLOAT + DXGI_FORMAT_UNKNOWN, // ASTC_8x8_FLOAT + DXGI_FORMAT_UNKNOWN, // ASTC_10x5_FLOAT + DXGI_FORMAT_UNKNOWN, // ASTC_10x6_FLOAT + DXGI_FORMAT_UNKNOWN, // ASTC_10x8_FLOAT + DXGI_FORMAT_UNKNOWN, // ASTC_10x10_FLOAT + DXGI_FORMAT_UNKNOWN, // ASTC_12x10_FLOAT + DXGI_FORMAT_UNKNOWN, // ASTC_12x12_FLOAT +}; +SDL_COMPILE_TIME_ASSERT(SDLToD3D12_TypelessFormat, SDL_arraysize(SDLToD3D12_TypelessFormat) == SDL_GPU_TEXTUREFORMAT_MAX_ENUM_VALUE); + static D3D12_COMPARISON_FUNC SDLToD3D12_CompareOp[] = { D3D12_COMPARISON_FUNC_NEVER, // INVALID D3D12_COMPARISON_FUNC_NEVER, // NEVER @@ -906,26 +1015,38 @@ struct D3D12CommandBuffer Uint32 vertexBufferOffsets[MAX_VERTEX_BUFFERS]; Uint32 vertexBufferCount; - D3D12Texture *vertexSamplerTextures[MAX_TEXTURE_SAMPLERS_PER_STAGE]; - D3D12Sampler *vertexSamplers[MAX_TEXTURE_SAMPLERS_PER_STAGE]; - D3D12Texture *vertexStorageTextures[MAX_STORAGE_TEXTURES_PER_STAGE]; - D3D12Buffer *vertexStorageBuffers[MAX_STORAGE_BUFFERS_PER_STAGE]; + D3D12_CPU_DESCRIPTOR_HANDLE vertexSamplerTextureDescriptorHandles[MAX_TEXTURE_SAMPLERS_PER_STAGE]; + D3D12_CPU_DESCRIPTOR_HANDLE vertexSamplerDescriptorHandles[MAX_TEXTURE_SAMPLERS_PER_STAGE]; + D3D12_CPU_DESCRIPTOR_HANDLE vertexStorageTextureDescriptorHandles[MAX_STORAGE_TEXTURES_PER_STAGE]; + D3D12_CPU_DESCRIPTOR_HANDLE vertexStorageBufferDescriptorHandles[MAX_STORAGE_BUFFERS_PER_STAGE]; + D3D12UniformBuffer *vertexUniformBuffers[MAX_UNIFORM_BUFFERS_PER_STAGE]; - D3D12Texture *fragmentSamplerTextures[MAX_TEXTURE_SAMPLERS_PER_STAGE]; - D3D12Sampler *fragmentSamplers[MAX_TEXTURE_SAMPLERS_PER_STAGE]; - D3D12Texture *fragmentStorageTextures[MAX_STORAGE_TEXTURES_PER_STAGE]; - D3D12Buffer *fragmentStorageBuffers[MAX_STORAGE_BUFFERS_PER_STAGE]; + D3D12_CPU_DESCRIPTOR_HANDLE fragmentSamplerTextureDescriptorHandles[MAX_TEXTURE_SAMPLERS_PER_STAGE]; + D3D12_CPU_DESCRIPTOR_HANDLE fragmentSamplerDescriptorHandles[MAX_TEXTURE_SAMPLERS_PER_STAGE]; + D3D12_CPU_DESCRIPTOR_HANDLE fragmentStorageTextureDescriptorHandles[MAX_STORAGE_TEXTURES_PER_STAGE]; + D3D12_CPU_DESCRIPTOR_HANDLE fragmentStorageBufferDescriptorHandles[MAX_STORAGE_BUFFERS_PER_STAGE]; + D3D12UniformBuffer *fragmentUniformBuffers[MAX_UNIFORM_BUFFERS_PER_STAGE]; - D3D12Texture *computeSamplerTextures[MAX_TEXTURE_SAMPLERS_PER_STAGE]; - D3D12Sampler *computeSamplers[MAX_TEXTURE_SAMPLERS_PER_STAGE]; + D3D12_CPU_DESCRIPTOR_HANDLE computeSamplerTextureDescriptorHandles[MAX_TEXTURE_SAMPLERS_PER_STAGE]; + D3D12_CPU_DESCRIPTOR_HANDLE computeSamplerDescriptorHandles[MAX_TEXTURE_SAMPLERS_PER_STAGE]; + D3D12_CPU_DESCRIPTOR_HANDLE computeReadOnlyStorageTextureDescriptorHandles[MAX_STORAGE_TEXTURES_PER_STAGE]; + D3D12_CPU_DESCRIPTOR_HANDLE computeReadOnlyStorageBufferDescriptorHandles[MAX_STORAGE_BUFFERS_PER_STAGE]; + + // Track these separately because barriers can happen mid compute pass D3D12Texture *computeReadOnlyStorageTextures[MAX_STORAGE_TEXTURES_PER_STAGE]; D3D12Buffer *computeReadOnlyStorageBuffers[MAX_STORAGE_BUFFERS_PER_STAGE]; + + D3D12_CPU_DESCRIPTOR_HANDLE computeReadWriteStorageTextureDescriptorHandles[MAX_COMPUTE_WRITE_TEXTURES]; + D3D12_CPU_DESCRIPTOR_HANDLE computeReadWriteStorageBufferDescriptorHandles[MAX_COMPUTE_WRITE_BUFFERS]; + + // Track these separately because they are bound when the compute pass begins D3D12TextureSubresource *computeReadWriteStorageTextureSubresources[MAX_COMPUTE_WRITE_TEXTURES]; Uint32 computeReadWriteStorageTextureSubresourceCount; D3D12Buffer *computeReadWriteStorageBuffers[MAX_COMPUTE_WRITE_BUFFERS]; Uint32 computeReadWriteStorageBufferCount; + D3D12UniformBuffer *computeUniformBuffers[MAX_UNIFORM_BUFFERS_PER_STAGE]; // Resource tracking @@ -989,22 +1110,14 @@ typedef struct D3D12GraphicsRootSignature struct D3D12GraphicsPipeline { + GraphicsPipelineCommonHeader header; + ID3D12PipelineState *pipelineState; D3D12GraphicsRootSignature *rootSignature; SDL_GPUPrimitiveType primitiveType; Uint32 vertexStrides[MAX_VERTEX_BUFFERS]; - Uint32 vertexSamplerCount; - Uint32 vertexUniformBufferCount; - Uint32 vertexStorageBufferCount; - Uint32 vertexStorageTextureCount; - - Uint32 fragmentSamplerCount; - Uint32 fragmentUniformBufferCount; - Uint32 fragmentStorageBufferCount; - Uint32 fragmentStorageTextureCount; - SDL_AtomicInt referenceCount; }; @@ -1023,16 +1136,11 @@ typedef struct D3D12ComputeRootSignature struct D3D12ComputePipeline { + ComputePipelineCommonHeader header; + ID3D12PipelineState *pipelineState; D3D12ComputeRootSignature *rootSignature; - Uint32 numSamplers; - Uint32 numReadOnlyStorageTextures; - Uint32 numReadOnlyStorageBuffers; - Uint32 numReadWriteStorageTextures; - Uint32 numReadWriteStorageBuffers; - Uint32 numUniformBuffers; - SDL_AtomicInt referenceCount; }; @@ -2777,12 +2885,12 @@ static SDL_GPUComputePipeline *D3D12_CreateComputePipeline( computePipeline->pipelineState = pipelineState; computePipeline->rootSignature = rootSignature; - computePipeline->numSamplers = createinfo->num_samplers; - computePipeline->numReadOnlyStorageTextures = createinfo->num_readonly_storage_textures; - computePipeline->numReadOnlyStorageBuffers = createinfo->num_readonly_storage_buffers; - computePipeline->numReadWriteStorageTextures = createinfo->num_readwrite_storage_textures; - computePipeline->numReadWriteStorageBuffers = createinfo->num_readwrite_storage_buffers; - computePipeline->numUniformBuffers = createinfo->num_uniform_buffers; + computePipeline->header.numSamplers = createinfo->num_samplers; + computePipeline->header.numReadonlyStorageTextures = createinfo->num_readonly_storage_textures; + computePipeline->header.numReadonlyStorageBuffers = createinfo->num_readonly_storage_buffers; + computePipeline->header.numReadWriteStorageTextures = createinfo->num_readwrite_storage_textures; + computePipeline->header.numReadWriteStorageBuffers = createinfo->num_readwrite_storage_buffers; + computePipeline->header.numUniformBuffers = createinfo->num_uniform_buffers; SDL_SetAtomicInt(&computePipeline->referenceCount, 0); if (renderer->debug_mode && SDL_HasProperty(createinfo->props, SDL_PROP_GPU_COMPUTEPIPELINE_CREATE_NAME_STRING)) { @@ -3063,15 +3171,15 @@ static SDL_GPUGraphicsPipeline *D3D12_CreateGraphicsPipeline( pipeline->primitiveType = createinfo->primitive_type; - pipeline->vertexSamplerCount = vertShader->num_samplers; - pipeline->vertexStorageTextureCount = vertShader->numStorageTextures; - pipeline->vertexStorageBufferCount = vertShader->numStorageBuffers; - pipeline->vertexUniformBufferCount = vertShader->numUniformBuffers; + pipeline->header.num_vertex_samplers = vertShader->num_samplers; + pipeline->header.num_vertex_storage_textures = vertShader->numStorageTextures; + pipeline->header.num_vertex_storage_buffers = vertShader->numStorageBuffers; + pipeline->header.num_vertex_uniform_buffers = vertShader->numUniformBuffers; - pipeline->fragmentSamplerCount = fragShader->num_samplers; - pipeline->fragmentStorageTextureCount = fragShader->numStorageTextures; - pipeline->fragmentStorageBufferCount = fragShader->numStorageBuffers; - pipeline->fragmentUniformBufferCount = fragShader->numUniformBuffers; + pipeline->header.num_fragment_samplers = fragShader->num_samplers; + pipeline->header.num_fragment_storage_textures = fragShader->numStorageTextures; + pipeline->header.num_fragment_storage_buffers = fragShader->numStorageBuffers; + pipeline->header.num_fragment_uniform_buffers = fragShader->numUniformBuffers; SDL_SetAtomicInt(&pipeline->referenceCount, 0); @@ -3188,6 +3296,10 @@ static D3D12Texture *D3D12_INTERNAL_CreateTexture( D3D12_CLEAR_VALUE clearValue; DXGI_FORMAT format; bool useClearValue = false; + bool needsSRV = + (createinfo->usage & SDL_GPU_TEXTUREUSAGE_SAMPLER) || + (createinfo->usage & SDL_GPU_TEXTUREUSAGE_GRAPHICS_STORAGE_READ) || + (createinfo->usage & SDL_GPU_TEXTUREUSAGE_COMPUTE_STORAGE_READ); bool needsUAV = (createinfo->usage & SDL_GPU_TEXTUREUSAGE_COMPUTE_STORAGE_WRITE) || (createinfo->usage & SDL_GPU_TEXTUREUSAGE_COMPUTE_STORAGE_SIMULTANEOUS_READ_WRITE); @@ -3207,6 +3319,7 @@ static D3D12Texture *D3D12_INTERNAL_CreateTexture( if (createinfo->usage & SDL_GPU_TEXTUREUSAGE_COLOR_TARGET) { resourceFlags |= D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET; useClearValue = true; + clearValue.Format = format; clearValue.Color[0] = SDL_GetFloatProperty(createinfo->props, SDL_PROP_GPU_TEXTURE_CREATE_D3D12_CLEAR_R_FLOAT, 0); clearValue.Color[1] = SDL_GetFloatProperty(createinfo->props, SDL_PROP_GPU_TEXTURE_CREATE_D3D12_CLEAR_G_FLOAT, 0); clearValue.Color[2] = SDL_GetFloatProperty(createinfo->props, SDL_PROP_GPU_TEXTURE_CREATE_D3D12_CLEAR_B_FLOAT, 0); @@ -3216,9 +3329,10 @@ static D3D12Texture *D3D12_INTERNAL_CreateTexture( if (createinfo->usage & SDL_GPU_TEXTUREUSAGE_DEPTH_STENCIL_TARGET) { resourceFlags |= D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL; useClearValue = true; + clearValue.Format = SDLToD3D12_DepthFormat[createinfo->format]; clearValue.DepthStencil.Depth = SDL_GetFloatProperty(createinfo->props, SDL_PROP_GPU_TEXTURE_CREATE_D3D12_CLEAR_DEPTH_FLOAT, 0); - clearValue.DepthStencil.Stencil = (UINT8)SDL_GetNumberProperty(createinfo->props, SDL_PROP_GPU_TEXTURE_CREATE_D3D12_CLEAR_STENCIL_UINT8, 0); - format = SDLToD3D12_DepthFormat[createinfo->format]; + clearValue.DepthStencil.Stencil = (UINT8)SDL_GetNumberProperty(createinfo->props, SDL_PROP_GPU_TEXTURE_CREATE_D3D12_CLEAR_STENCIL_NUMBER, 0); + format = needsSRV ? SDLToD3D12_TypelessFormat[createinfo->format] : SDLToD3D12_DepthFormat[createinfo->format]; } if (needsUAV) { @@ -3235,7 +3349,7 @@ static D3D12Texture *D3D12_INTERNAL_CreateTexture( if (createinfo->type != SDL_GPU_TEXTURETYPE_3D) { desc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D; - desc.Alignment = isSwapchainTexture ? 0 : D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT; + desc.Alignment = isSwapchainTexture ? 0 : isMultisample ? D3D12_DEFAULT_MSAA_RESOURCE_PLACEMENT_ALIGNMENT : D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT; desc.Width = createinfo->width; desc.Height = createinfo->height; desc.DepthOrArraySize = (UINT16)createinfo->layer_count_or_depth; @@ -3260,7 +3374,6 @@ static D3D12Texture *D3D12_INTERNAL_CreateTexture( } initialState = isSwapchainTexture ? D3D12_RESOURCE_STATE_PRESENT : D3D12_INTERNAL_DefaultTextureResourceState(createinfo->usage); - clearValue.Format = desc.Format; res = ID3D12Device_CreateCommittedResource( renderer->device, @@ -3280,9 +3393,7 @@ static D3D12Texture *D3D12_INTERNAL_CreateTexture( texture->resource = handle; // Create the SRV if applicable - if ((createinfo->usage & SDL_GPU_TEXTUREUSAGE_SAMPLER) || - (createinfo->usage & SDL_GPU_TEXTUREUSAGE_GRAPHICS_STORAGE_READ) || - (createinfo->usage & SDL_GPU_TEXTUREUSAGE_COMPUTE_STORAGE_READ)) { + if (needsSRV) { D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc; D3D12_INTERNAL_AssignStagingDescriptorHandle( @@ -3483,7 +3594,9 @@ static SDL_GPUTexture *D3D12_CreateTexture( // Copy properties so we don't lose information when the client destroys them container->header.info = *createinfo; container->header.info.props = SDL_CreateProperties(); - SDL_CopyProperties(createinfo->props, container->header.info.props); + if (createinfo->props) { + SDL_CopyProperties(createinfo->props, container->header.info.props); + } container->textureCapacity = 1; container->textureCount = 1; @@ -4523,14 +4636,14 @@ static void D3D12_BindGraphicsPipeline( d3d12CommandBuffer->needFragmentUniformBufferBind[i] = true; } - for (i = 0; i < pipeline->vertexUniformBufferCount; i += 1) { + for (i = 0; i < pipeline->header.num_vertex_uniform_buffers; i += 1) { if (d3d12CommandBuffer->vertexUniformBuffers[i] == NULL) { d3d12CommandBuffer->vertexUniformBuffers[i] = D3D12_INTERNAL_AcquireUniformBufferFromPool( d3d12CommandBuffer); } } - for (i = 0; i < pipeline->fragmentUniformBufferCount; i += 1) { + for (i = 0; i < pipeline->header.num_fragment_uniform_buffers; i += 1) { if (d3d12CommandBuffer->fragmentUniformBuffers[i] == NULL) { d3d12CommandBuffer->fragmentUniformBuffers[i] = D3D12_INTERNAL_AcquireUniformBufferFromPool( d3d12CommandBuffer); @@ -4597,21 +4710,21 @@ static void D3D12_BindVertexSamplers( D3D12TextureContainer *container = (D3D12TextureContainer *)textureSamplerBindings[i].texture; D3D12Sampler *sampler = (D3D12Sampler *)textureSamplerBindings[i].sampler; - if (d3d12CommandBuffer->vertexSamplers[firstSlot + i] != sampler) { + if (d3d12CommandBuffer->vertexSamplerDescriptorHandles[firstSlot + i].ptr != sampler->handle.cpuHandle.ptr) { D3D12_INTERNAL_TrackSampler( d3d12CommandBuffer, sampler); - d3d12CommandBuffer->vertexSamplers[firstSlot + i] = sampler; + d3d12CommandBuffer->vertexSamplerDescriptorHandles[firstSlot + i] = sampler->handle.cpuHandle; d3d12CommandBuffer->needVertexSamplerBind = true; } - if (d3d12CommandBuffer->vertexSamplerTextures[firstSlot + i] != container->activeTexture) { + if (d3d12CommandBuffer->vertexSamplerTextureDescriptorHandles[firstSlot + i].ptr != container->activeTexture->srvHandle.cpuHandle.ptr) { D3D12_INTERNAL_TrackTexture( d3d12CommandBuffer, container->activeTexture); - d3d12CommandBuffer->vertexSamplerTextures[firstSlot + i] = container->activeTexture; + d3d12CommandBuffer->vertexSamplerTextureDescriptorHandles[firstSlot + i] = container->activeTexture->srvHandle.cpuHandle; d3d12CommandBuffer->needVertexSamplerBind = true; } } @@ -4629,10 +4742,10 @@ static void D3D12_BindVertexStorageTextures( D3D12TextureContainer *container = (D3D12TextureContainer *)storageTextures[i]; D3D12Texture *texture = container->activeTexture; - if (d3d12CommandBuffer->vertexStorageTextures[firstSlot + i] != texture) { + if (d3d12CommandBuffer->vertexStorageTextureDescriptorHandles[firstSlot + i].ptr != texture->srvHandle.cpuHandle.ptr) { D3D12_INTERNAL_TrackTexture(d3d12CommandBuffer, texture); - d3d12CommandBuffer->vertexStorageTextures[firstSlot + i] = texture; + d3d12CommandBuffer->vertexStorageTextureDescriptorHandles[firstSlot + i] = texture->srvHandle.cpuHandle; d3d12CommandBuffer->needVertexStorageTextureBind = true; } } @@ -4648,12 +4761,12 @@ static void D3D12_BindVertexStorageBuffers( for (Uint32 i = 0; i < numBindings; i += 1) { D3D12BufferContainer *container = (D3D12BufferContainer *)storageBuffers[i]; - if (d3d12CommandBuffer->vertexStorageBuffers[firstSlot + i] != container->activeBuffer) { + if (d3d12CommandBuffer->vertexStorageBufferDescriptorHandles[firstSlot + i].ptr != container->activeBuffer->srvDescriptor.cpuHandle.ptr) { D3D12_INTERNAL_TrackBuffer( d3d12CommandBuffer, container->activeBuffer); - d3d12CommandBuffer->vertexStorageBuffers[firstSlot + i] = container->activeBuffer; + d3d12CommandBuffer->vertexStorageBufferDescriptorHandles[firstSlot + i] = container->activeBuffer->srvDescriptor.cpuHandle; d3d12CommandBuffer->needVertexStorageBufferBind = true; } } @@ -4671,21 +4784,21 @@ static void D3D12_BindFragmentSamplers( D3D12TextureContainer *container = (D3D12TextureContainer *)textureSamplerBindings[i].texture; D3D12Sampler *sampler = (D3D12Sampler *)textureSamplerBindings[i].sampler; - if (d3d12CommandBuffer->fragmentSamplers[firstSlot + i] != sampler) { + if (d3d12CommandBuffer->fragmentSamplerDescriptorHandles[firstSlot + i].ptr != sampler->handle.cpuHandle.ptr) { D3D12_INTERNAL_TrackSampler( d3d12CommandBuffer, sampler); - d3d12CommandBuffer->fragmentSamplers[firstSlot + i] = sampler; + d3d12CommandBuffer->fragmentSamplerDescriptorHandles[firstSlot + i] = sampler->handle.cpuHandle; d3d12CommandBuffer->needFragmentSamplerBind = true; } - if (d3d12CommandBuffer->fragmentSamplerTextures[firstSlot + i] != container->activeTexture) { + if (d3d12CommandBuffer->fragmentSamplerTextureDescriptorHandles[firstSlot + i].ptr != container->activeTexture->srvHandle.cpuHandle.ptr) { D3D12_INTERNAL_TrackTexture( d3d12CommandBuffer, container->activeTexture); - d3d12CommandBuffer->fragmentSamplerTextures[firstSlot + i] = container->activeTexture; + d3d12CommandBuffer->fragmentSamplerTextureDescriptorHandles[firstSlot + i] = container->activeTexture->srvHandle.cpuHandle; d3d12CommandBuffer->needFragmentSamplerBind = true; } } @@ -4703,10 +4816,10 @@ static void D3D12_BindFragmentStorageTextures( D3D12TextureContainer *container = (D3D12TextureContainer *)storageTextures[i]; D3D12Texture *texture = container->activeTexture; - if (d3d12CommandBuffer->fragmentStorageTextures[firstSlot + i] != texture) { + if (d3d12CommandBuffer->fragmentStorageTextureDescriptorHandles[firstSlot + i].ptr != texture->srvHandle.cpuHandle.ptr) { D3D12_INTERNAL_TrackTexture(d3d12CommandBuffer, texture); - d3d12CommandBuffer->fragmentStorageTextures[firstSlot + i] = texture; + d3d12CommandBuffer->fragmentStorageTextureDescriptorHandles[firstSlot + i] = texture->srvHandle.cpuHandle; d3d12CommandBuffer->needFragmentStorageTextureBind = true; } } @@ -4723,12 +4836,12 @@ static void D3D12_BindFragmentStorageBuffers( for (Uint32 i = 0; i < numBindings; i += 1) { D3D12BufferContainer *container = (D3D12BufferContainer *)storageBuffers[i]; - if (d3d12CommandBuffer->fragmentStorageBuffers[firstSlot + i] != container->activeBuffer) { + if (d3d12CommandBuffer->fragmentStorageBufferDescriptorHandles[firstSlot + i].ptr != container->activeBuffer->srvDescriptor.cpuHandle.ptr) { D3D12_INTERNAL_TrackBuffer( d3d12CommandBuffer, container->activeBuffer); - d3d12CommandBuffer->fragmentStorageBuffers[firstSlot + i] = container->activeBuffer; + d3d12CommandBuffer->fragmentStorageBufferDescriptorHandles[firstSlot + i] = container->activeBuffer->srvDescriptor.cpuHandle; d3d12CommandBuffer->needFragmentStorageBufferBind = true; } } @@ -4809,15 +4922,19 @@ static void D3D12_INTERNAL_WriteGPUDescriptors( gpuBaseDescriptor->ptr = heap->descriptorHeapGPUStart.ptr + (heap->currentDescriptorIndex * heap->descriptorSize); for (Uint32 i = 0; i < resourceHandleCount; i += 1) { - ID3D12Device_CopyDescriptorsSimple( - commandBuffer->renderer->device, - 1, - gpuHeapCpuHandle, - resourceDescriptorHandles[i], - heapType); + // This will crash the driver if it gets a null handle! Cool! + if (resourceDescriptorHandles[i].ptr != 0) + { + ID3D12Device_CopyDescriptorsSimple( + commandBuffer->renderer->device, + 1, + gpuHeapCpuHandle, + resourceDescriptorHandles[i], + heapType); - heap->currentDescriptorIndex += 1; - gpuHeapCpuHandle.ptr += heap->descriptorSize; + heap->currentDescriptorIndex += 1; + gpuHeapCpuHandle.ptr += heap->descriptorSize; + } } } @@ -4847,19 +4964,21 @@ static void D3D12_INTERNAL_BindGraphicsResources( 0, commandBuffer->vertexBufferCount, vertexBufferViews); + + commandBuffer->needVertexBufferBind = false; } if (commandBuffer->needVertexSamplerBind) { - if (graphicsPipeline->vertexSamplerCount > 0) { - for (Uint32 i = 0; i < graphicsPipeline->vertexSamplerCount; i += 1) { - cpuHandles[i] = commandBuffer->vertexSamplers[i]->handle.cpuHandle; + if (graphicsPipeline->header.num_vertex_samplers > 0) { + for (Uint32 i = 0; i < graphicsPipeline->header.num_vertex_samplers; i += 1) { + cpuHandles[i] = commandBuffer->vertexSamplerDescriptorHandles[i]; } D3D12_INTERNAL_WriteGPUDescriptors( commandBuffer, D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER, cpuHandles, - graphicsPipeline->vertexSamplerCount, + graphicsPipeline->header.num_vertex_samplers, &gpuDescriptorHandle); ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable( @@ -4867,15 +4986,15 @@ static void D3D12_INTERNAL_BindGraphicsResources( graphicsPipeline->rootSignature->vertexSamplerRootIndex, gpuDescriptorHandle); - for (Uint32 i = 0; i < graphicsPipeline->vertexSamplerCount; i += 1) { - cpuHandles[i] = commandBuffer->vertexSamplerTextures[i]->srvHandle.cpuHandle; + for (Uint32 i = 0; i < graphicsPipeline->header.num_vertex_samplers; i += 1) { + cpuHandles[i] = commandBuffer->vertexSamplerTextureDescriptorHandles[i]; } D3D12_INTERNAL_WriteGPUDescriptors( commandBuffer, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, cpuHandles, - graphicsPipeline->vertexSamplerCount, + graphicsPipeline->header.num_vertex_samplers, &gpuDescriptorHandle); ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable( @@ -4887,16 +5006,16 @@ static void D3D12_INTERNAL_BindGraphicsResources( } if (commandBuffer->needVertexStorageTextureBind) { - if (graphicsPipeline->vertexStorageTextureCount > 0) { - for (Uint32 i = 0; i < graphicsPipeline->vertexStorageTextureCount; i += 1) { - cpuHandles[i] = commandBuffer->vertexStorageTextures[i]->srvHandle.cpuHandle; + if (graphicsPipeline->header.num_vertex_storage_textures > 0) { + for (Uint32 i = 0; i < graphicsPipeline->header.num_vertex_storage_textures; i += 1) { + cpuHandles[i] = commandBuffer->vertexStorageTextureDescriptorHandles[i]; } D3D12_INTERNAL_WriteGPUDescriptors( commandBuffer, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, cpuHandles, - graphicsPipeline->vertexStorageTextureCount, + graphicsPipeline->header.num_vertex_storage_textures, &gpuDescriptorHandle); ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable( @@ -4908,16 +5027,16 @@ static void D3D12_INTERNAL_BindGraphicsResources( } if (commandBuffer->needVertexStorageBufferBind) { - if (graphicsPipeline->vertexStorageBufferCount > 0) { - for (Uint32 i = 0; i < graphicsPipeline->vertexStorageBufferCount; i += 1) { - cpuHandles[i] = commandBuffer->vertexStorageBuffers[i]->srvDescriptor.cpuHandle; + if (graphicsPipeline->header.num_vertex_storage_buffers > 0) { + for (Uint32 i = 0; i < graphicsPipeline->header.num_vertex_storage_buffers; i += 1) { + cpuHandles[i] = commandBuffer->vertexStorageBufferDescriptorHandles[i]; } D3D12_INTERNAL_WriteGPUDescriptors( commandBuffer, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, cpuHandles, - graphicsPipeline->vertexStorageBufferCount, + graphicsPipeline->header.num_vertex_storage_buffers, &gpuDescriptorHandle); ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable( @@ -4930,7 +5049,7 @@ static void D3D12_INTERNAL_BindGraphicsResources( for (Uint32 i = 0; i < MAX_UNIFORM_BUFFERS_PER_STAGE; i += 1) { if (commandBuffer->needVertexUniformBufferBind[i]) { - if (graphicsPipeline->vertexUniformBufferCount > i) { + if (graphicsPipeline->header.num_vertex_uniform_buffers > i) { ID3D12GraphicsCommandList_SetGraphicsRootConstantBufferView( commandBuffer->graphicsCommandList, graphicsPipeline->rootSignature->vertexUniformBufferRootIndex[i], @@ -4941,16 +5060,16 @@ static void D3D12_INTERNAL_BindGraphicsResources( } if (commandBuffer->needFragmentSamplerBind) { - if (graphicsPipeline->fragmentSamplerCount > 0) { - for (Uint32 i = 0; i < graphicsPipeline->fragmentSamplerCount; i += 1) { - cpuHandles[i] = commandBuffer->fragmentSamplers[i]->handle.cpuHandle; + if (graphicsPipeline->header.num_fragment_samplers > 0) { + for (Uint32 i = 0; i < graphicsPipeline->header.num_fragment_samplers; i += 1) { + cpuHandles[i] = commandBuffer->fragmentSamplerDescriptorHandles[i]; } D3D12_INTERNAL_WriteGPUDescriptors( commandBuffer, D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER, cpuHandles, - graphicsPipeline->fragmentSamplerCount, + graphicsPipeline->header.num_fragment_samplers, &gpuDescriptorHandle); ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable( @@ -4958,15 +5077,15 @@ static void D3D12_INTERNAL_BindGraphicsResources( graphicsPipeline->rootSignature->fragmentSamplerRootIndex, gpuDescriptorHandle); - for (Uint32 i = 0; i < graphicsPipeline->fragmentSamplerCount; i += 1) { - cpuHandles[i] = commandBuffer->fragmentSamplerTextures[i]->srvHandle.cpuHandle; + for (Uint32 i = 0; i < graphicsPipeline->header.num_fragment_samplers; i += 1) { + cpuHandles[i] = commandBuffer->fragmentSamplerTextureDescriptorHandles[i]; } D3D12_INTERNAL_WriteGPUDescriptors( commandBuffer, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, cpuHandles, - graphicsPipeline->fragmentSamplerCount, + graphicsPipeline->header.num_fragment_samplers, &gpuDescriptorHandle); ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable( @@ -4978,16 +5097,16 @@ static void D3D12_INTERNAL_BindGraphicsResources( } if (commandBuffer->needFragmentStorageTextureBind) { - if (graphicsPipeline->fragmentStorageTextureCount > 0) { - for (Uint32 i = 0; i < graphicsPipeline->fragmentStorageTextureCount; i += 1) { - cpuHandles[i] = commandBuffer->fragmentStorageTextures[i]->srvHandle.cpuHandle; + if (graphicsPipeline->header.num_fragment_storage_textures > 0) { + for (Uint32 i = 0; i < graphicsPipeline->header.num_fragment_storage_textures; i += 1) { + cpuHandles[i] = commandBuffer->fragmentStorageTextureDescriptorHandles[i]; } D3D12_INTERNAL_WriteGPUDescriptors( commandBuffer, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, cpuHandles, - graphicsPipeline->fragmentStorageTextureCount, + graphicsPipeline->header.num_fragment_storage_textures, &gpuDescriptorHandle); ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable( @@ -4999,16 +5118,16 @@ static void D3D12_INTERNAL_BindGraphicsResources( } if (commandBuffer->needFragmentStorageBufferBind) { - if (graphicsPipeline->fragmentStorageBufferCount > 0) { - for (Uint32 i = 0; i < graphicsPipeline->fragmentStorageBufferCount; i += 1) { - cpuHandles[i] = commandBuffer->fragmentStorageBuffers[i]->srvDescriptor.cpuHandle; + if (graphicsPipeline->header.num_fragment_storage_buffers > 0) { + for (Uint32 i = 0; i < graphicsPipeline->header.num_fragment_storage_buffers; i += 1) { + cpuHandles[i] = commandBuffer->fragmentStorageBufferDescriptorHandles[i]; } D3D12_INTERNAL_WriteGPUDescriptors( commandBuffer, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, cpuHandles, - graphicsPipeline->fragmentStorageBufferCount, + graphicsPipeline->header.num_fragment_storage_buffers, &gpuDescriptorHandle); ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable( @@ -5021,7 +5140,7 @@ static void D3D12_INTERNAL_BindGraphicsResources( for (Uint32 i = 0; i < MAX_UNIFORM_BUFFERS_PER_STAGE; i += 1) { if (commandBuffer->needFragmentUniformBufferBind[i]) { - if (graphicsPipeline->fragmentUniformBufferCount > i) { + if (graphicsPipeline->header.num_fragment_uniform_buffers > i) { ID3D12GraphicsCommandList_SetGraphicsRootConstantBufferView( commandBuffer->graphicsCommandList, graphicsPipeline->rootSignature->fragmentUniformBufferRootIndex[i], @@ -5186,15 +5305,15 @@ static void D3D12_EndRenderPass( SDL_zeroa(d3d12CommandBuffer->vertexBufferOffsets); d3d12CommandBuffer->vertexBufferCount = 0; - SDL_zeroa(d3d12CommandBuffer->vertexSamplerTextures); - SDL_zeroa(d3d12CommandBuffer->vertexSamplers); - SDL_zeroa(d3d12CommandBuffer->vertexStorageTextures); - SDL_zeroa(d3d12CommandBuffer->vertexStorageBuffers); + SDL_zeroa(d3d12CommandBuffer->vertexSamplerTextureDescriptorHandles); + SDL_zeroa(d3d12CommandBuffer->vertexSamplerDescriptorHandles); + SDL_zeroa(d3d12CommandBuffer->vertexStorageTextureDescriptorHandles); + SDL_zeroa(d3d12CommandBuffer->vertexStorageBufferDescriptorHandles); - SDL_zeroa(d3d12CommandBuffer->fragmentSamplerTextures); - SDL_zeroa(d3d12CommandBuffer->fragmentSamplers); - SDL_zeroa(d3d12CommandBuffer->fragmentStorageTextures); - SDL_zeroa(d3d12CommandBuffer->fragmentStorageBuffers); + SDL_zeroa(d3d12CommandBuffer->fragmentSamplerTextureDescriptorHandles); + SDL_zeroa(d3d12CommandBuffer->fragmentSamplerDescriptorHandles); + SDL_zeroa(d3d12CommandBuffer->fragmentStorageTextureDescriptorHandles); + SDL_zeroa(d3d12CommandBuffer->fragmentStorageBufferDescriptorHandles); } // Compute Pass @@ -5228,6 +5347,7 @@ static void D3D12_BeginComputePass( D3D12_RESOURCE_STATE_UNORDERED_ACCESS); d3d12CommandBuffer->computeReadWriteStorageTextureSubresources[i] = subresource; + d3d12CommandBuffer->computeReadWriteStorageTextureDescriptorHandles[i] = subresource->uavHandle.cpuHandle; D3D12_INTERNAL_TrackTexture( d3d12CommandBuffer, @@ -5246,6 +5366,7 @@ static void D3D12_BeginComputePass( D3D12_RESOURCE_STATE_UNORDERED_ACCESS); d3d12CommandBuffer->computeReadWriteStorageBuffers[i] = buffer; + d3d12CommandBuffer->computeReadWriteStorageBufferDescriptorHandles[i] = buffer->uavDescriptor.cpuHandle; D3D12_INTERNAL_TrackBuffer( d3d12CommandBuffer, @@ -5287,7 +5408,7 @@ static void D3D12_BindComputePipeline( d3d12CommandBuffer->needComputeUniformBufferBind[i] = true; } - for (Uint32 i = 0; i < pipeline->numUniformBuffers; i += 1) { + for (Uint32 i = 0; i < pipeline->header.numUniformBuffers; i += 1) { if (d3d12CommandBuffer->computeUniformBuffers[i] == NULL) { d3d12CommandBuffer->computeUniformBuffers[i] = D3D12_INTERNAL_AcquireUniformBufferFromPool( d3d12CommandBuffer); @@ -5297,9 +5418,9 @@ static void D3D12_BindComputePipeline( D3D12_INTERNAL_TrackComputePipeline(d3d12CommandBuffer, pipeline); // Bind write-only resources after setting root signature - if (pipeline->numReadWriteStorageTextures > 0) { - for (Uint32 i = 0; i < pipeline->numReadWriteStorageTextures; i += 1) { - cpuHandles[i] = d3d12CommandBuffer->computeReadWriteStorageTextureSubresources[i]->uavHandle.cpuHandle; + if (pipeline->header.numReadWriteStorageTextures > 0) { + for (Uint32 i = 0; i < pipeline->header.numReadWriteStorageTextures; i += 1) { + cpuHandles[i] = d3d12CommandBuffer->computeReadWriteStorageTextureDescriptorHandles[i]; } D3D12_INTERNAL_WriteGPUDescriptors( @@ -5315,9 +5436,9 @@ static void D3D12_BindComputePipeline( gpuDescriptorHandle); } - if (pipeline->numReadWriteStorageBuffers > 0) { - for (Uint32 i = 0; i < pipeline->numReadWriteStorageBuffers; i += 1) { - cpuHandles[i] = d3d12CommandBuffer->computeReadWriteStorageBuffers[i]->uavDescriptor.cpuHandle; + if (pipeline->header.numReadWriteStorageBuffers > 0) { + for (Uint32 i = 0; i < pipeline->header.numReadWriteStorageBuffers; i += 1) { + cpuHandles[i] = d3d12CommandBuffer->computeReadWriteStorageBufferDescriptorHandles[i]; } D3D12_INTERNAL_WriteGPUDescriptors( @@ -5346,21 +5467,21 @@ static void D3D12_BindComputeSamplers( D3D12TextureContainer *container = (D3D12TextureContainer *)textureSamplerBindings[i].texture; D3D12Sampler *sampler = (D3D12Sampler *)textureSamplerBindings[i].sampler; - if (d3d12CommandBuffer->computeSamplers[firstSlot + i] != sampler) { + if (d3d12CommandBuffer->computeSamplerDescriptorHandles[firstSlot + i].ptr != sampler->handle.cpuHandle.ptr) { D3D12_INTERNAL_TrackSampler( d3d12CommandBuffer, (D3D12Sampler *)textureSamplerBindings[i].sampler); - d3d12CommandBuffer->computeSamplers[firstSlot + i] = (D3D12Sampler *)textureSamplerBindings[i].sampler; + d3d12CommandBuffer->computeSamplerDescriptorHandles[firstSlot + i] = sampler->handle.cpuHandle; d3d12CommandBuffer->needComputeSamplerBind = true; } - if (d3d12CommandBuffer->computeSamplerTextures[firstSlot + i] != container->activeTexture) { + if (d3d12CommandBuffer->computeSamplerTextureDescriptorHandles[firstSlot + i].ptr != container->activeTexture->srvHandle.cpuHandle.ptr) { D3D12_INTERNAL_TrackTexture( d3d12CommandBuffer, container->activeTexture); - d3d12CommandBuffer->computeSamplerTextures[firstSlot + i] = container->activeTexture; + d3d12CommandBuffer->computeSamplerTextureDescriptorHandles[firstSlot + i] = container->activeTexture->srvHandle.cpuHandle; d3d12CommandBuffer->needComputeSamplerBind = true; } } @@ -5397,6 +5518,7 @@ static void D3D12_BindComputeStorageTextures( container->activeTexture); d3d12CommandBuffer->computeReadOnlyStorageTextures[firstSlot + i] = container->activeTexture; + d3d12CommandBuffer->computeReadOnlyStorageTextureDescriptorHandles[firstSlot + i] = container->activeTexture->srvHandle.cpuHandle; d3d12CommandBuffer->needComputeReadOnlyStorageTextureBind = true; } } @@ -5434,6 +5556,7 @@ static void D3D12_BindComputeStorageBuffers( buffer); d3d12CommandBuffer->computeReadOnlyStorageBuffers[firstSlot + i] = buffer; + d3d12CommandBuffer->computeReadOnlyStorageBufferDescriptorHandles[firstSlot + i] = buffer->srvDescriptor.cpuHandle; d3d12CommandBuffer->needComputeReadOnlyStorageBufferBind = true; } } @@ -5469,16 +5592,16 @@ static void D3D12_INTERNAL_BindComputeResources( D3D12_GPU_DESCRIPTOR_HANDLE gpuDescriptorHandle; if (commandBuffer->needComputeSamplerBind) { - if (computePipeline->numSamplers > 0) { - for (Uint32 i = 0; i < computePipeline->numSamplers; i += 1) { - cpuHandles[i] = commandBuffer->computeSamplers[i]->handle.cpuHandle; + if (computePipeline->header.numSamplers > 0) { + for (Uint32 i = 0; i < computePipeline->header.numSamplers; i += 1) { + cpuHandles[i] = commandBuffer->computeSamplerDescriptorHandles[i]; } D3D12_INTERNAL_WriteGPUDescriptors( commandBuffer, D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER, cpuHandles, - computePipeline->numSamplers, + computePipeline->header.numSamplers, &gpuDescriptorHandle); ID3D12GraphicsCommandList_SetComputeRootDescriptorTable( @@ -5486,15 +5609,15 @@ static void D3D12_INTERNAL_BindComputeResources( computePipeline->rootSignature->samplerRootIndex, gpuDescriptorHandle); - for (Uint32 i = 0; i < computePipeline->numSamplers; i += 1) { - cpuHandles[i] = commandBuffer->computeSamplerTextures[i]->srvHandle.cpuHandle; + for (Uint32 i = 0; i < computePipeline->header.numSamplers; i += 1) { + cpuHandles[i] = commandBuffer->computeSamplerTextureDescriptorHandles[i]; } D3D12_INTERNAL_WriteGPUDescriptors( commandBuffer, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, cpuHandles, - computePipeline->numSamplers, + computePipeline->header.numSamplers, &gpuDescriptorHandle); ID3D12GraphicsCommandList_SetComputeRootDescriptorTable( @@ -5506,16 +5629,16 @@ static void D3D12_INTERNAL_BindComputeResources( } if (commandBuffer->needComputeReadOnlyStorageTextureBind) { - if (computePipeline->numReadOnlyStorageTextures > 0) { - for (Uint32 i = 0; i < computePipeline->numReadOnlyStorageTextures; i += 1) { - cpuHandles[i] = commandBuffer->computeReadOnlyStorageTextures[i]->srvHandle.cpuHandle; + if (computePipeline->header.numReadonlyStorageTextures > 0) { + for (Uint32 i = 0; i < computePipeline->header.numReadonlyStorageTextures; i += 1) { + cpuHandles[i] = commandBuffer->computeReadOnlyStorageTextureDescriptorHandles[i]; } D3D12_INTERNAL_WriteGPUDescriptors( commandBuffer, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, cpuHandles, - computePipeline->numReadOnlyStorageTextures, + computePipeline->header.numReadonlyStorageTextures, &gpuDescriptorHandle); ID3D12GraphicsCommandList_SetComputeRootDescriptorTable( @@ -5527,16 +5650,16 @@ static void D3D12_INTERNAL_BindComputeResources( } if (commandBuffer->needComputeReadOnlyStorageBufferBind) { - if (computePipeline->numReadOnlyStorageBuffers > 0) { - for (Uint32 i = 0; i < computePipeline->numReadOnlyStorageBuffers; i += 1) { - cpuHandles[i] = commandBuffer->computeReadOnlyStorageBuffers[i]->srvDescriptor.cpuHandle; + if (computePipeline->header.numReadonlyStorageBuffers > 0) { + for (Uint32 i = 0; i < computePipeline->header.numReadonlyStorageBuffers; i += 1) { + cpuHandles[i] = commandBuffer->computeReadOnlyStorageBufferDescriptorHandles[i]; } D3D12_INTERNAL_WriteGPUDescriptors( commandBuffer, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, cpuHandles, - computePipeline->numReadOnlyStorageBuffers, + computePipeline->header.numReadonlyStorageBuffers, &gpuDescriptorHandle); ID3D12GraphicsCommandList_SetComputeRootDescriptorTable( @@ -5549,7 +5672,7 @@ static void D3D12_INTERNAL_BindComputeResources( for (Uint32 i = 0; i < MAX_UNIFORM_BUFFERS_PER_STAGE; i += 1) { if (commandBuffer->needComputeUniformBufferBind[i]) { - if (computePipeline->numUniformBuffers > i) { + if (computePipeline->header.numUniformBuffers > i) { ID3D12GraphicsCommandList_SetComputeRootConstantBufferView( commandBuffer->graphicsCommandList, computePipeline->rootSignature->uniformBufferRootIndex[i], @@ -5648,8 +5771,11 @@ static void D3D12_EndComputePass( } } - SDL_zeroa(d3d12CommandBuffer->computeSamplerTextures); - SDL_zeroa(d3d12CommandBuffer->computeSamplers); + SDL_zeroa(d3d12CommandBuffer->computeSamplerTextureDescriptorHandles); + SDL_zeroa(d3d12CommandBuffer->computeSamplerDescriptorHandles); + + SDL_zeroa(d3d12CommandBuffer->computeReadWriteStorageTextureDescriptorHandles); + SDL_zeroa(d3d12CommandBuffer->computeReadWriteStorageBufferDescriptorHandles); d3d12CommandBuffer->currentComputePipeline = NULL; } @@ -7238,20 +7364,22 @@ static SDL_GPUCommandBuffer *D3D12_AcquireCommandBuffer( SDL_zeroa(commandBuffer->vertexBufferOffsets); commandBuffer->vertexBufferCount = 0; - SDL_zeroa(commandBuffer->vertexSamplerTextures); - SDL_zeroa(commandBuffer->vertexSamplers); - SDL_zeroa(commandBuffer->vertexStorageTextures); - SDL_zeroa(commandBuffer->vertexStorageBuffers); + SDL_zeroa(commandBuffer->vertexSamplerTextureDescriptorHandles); + SDL_zeroa(commandBuffer->vertexSamplerDescriptorHandles); + SDL_zeroa(commandBuffer->vertexStorageTextureDescriptorHandles); + SDL_zeroa(commandBuffer->vertexStorageBufferDescriptorHandles); SDL_zeroa(commandBuffer->vertexUniformBuffers); - SDL_zeroa(commandBuffer->fragmentSamplerTextures); - SDL_zeroa(commandBuffer->fragmentSamplers); - SDL_zeroa(commandBuffer->fragmentStorageTextures); - SDL_zeroa(commandBuffer->fragmentStorageBuffers); + SDL_zeroa(commandBuffer->fragmentSamplerTextureDescriptorHandles); + SDL_zeroa(commandBuffer->fragmentSamplerDescriptorHandles); + SDL_zeroa(commandBuffer->fragmentStorageTextureDescriptorHandles); + SDL_zeroa(commandBuffer->fragmentStorageBufferDescriptorHandles); SDL_zeroa(commandBuffer->fragmentUniformBuffers); - SDL_zeroa(commandBuffer->computeSamplerTextures); - SDL_zeroa(commandBuffer->computeSamplers); + SDL_zeroa(commandBuffer->computeSamplerTextureDescriptorHandles); + SDL_zeroa(commandBuffer->computeSamplerDescriptorHandles); + SDL_zeroa(commandBuffer->computeReadOnlyStorageTextureDescriptorHandles); + SDL_zeroa(commandBuffer->computeReadOnlyStorageBufferDescriptorHandles); SDL_zeroa(commandBuffer->computeReadOnlyStorageTextures); SDL_zeroa(commandBuffer->computeReadOnlyStorageBuffers); SDL_zeroa(commandBuffer->computeReadWriteStorageTextureSubresources); @@ -8100,8 +8228,7 @@ static void D3D12_INTERNAL_InitBlitResources( shaderCreateInfo.code = (Uint8 *)D3D12_FullscreenVert; shaderCreateInfo.code_size = sizeof(D3D12_FullscreenVert); shaderCreateInfo.stage = SDL_GPU_SHADERSTAGE_VERTEX; - shaderCreateInfo.format = SDL_GPU_SHADERFORMAT_DXBC; - shaderCreateInfo.entrypoint = "main"; + shaderCreateInfo.format = SDL_GPU_SHADERFORMAT_DXIL; renderer->blitVertexShader = D3D12_CreateShader( (SDL_GPURenderer *)renderer, @@ -8338,38 +8465,38 @@ static bool D3D12_PrepareDriver(SDL_VideoDevice *_this) } #if !(defined(SDL_PLATFORM_XBOXONE) || defined(SDL_PLATFORM_XBOXSERIES)) && defined(HAVE_IDXGIINFOQUEUE) -static void D3D12_INTERNAL_TryInitializeDXGIDebug(D3D12Renderer *renderer) +static bool D3D12_INTERNAL_TryInitializeDXGIDebug(D3D12Renderer *renderer) { PFN_DXGI_GET_DEBUG_INTERFACE DXGIGetDebugInterfaceFunc; HRESULT res; renderer->dxgidebug_dll = SDL_LoadObject(DXGIDEBUG_DLL); if (renderer->dxgidebug_dll == NULL) { - SDL_LogWarn(SDL_LOG_CATEGORY_GPU, "Could not find " DXGIDEBUG_DLL); - return; + return false; } DXGIGetDebugInterfaceFunc = (PFN_DXGI_GET_DEBUG_INTERFACE)SDL_LoadFunction( renderer->dxgidebug_dll, DXGI_GET_DEBUG_INTERFACE_FUNC); if (DXGIGetDebugInterfaceFunc == NULL) { - SDL_LogWarn(SDL_LOG_CATEGORY_GPU, "Could not load function: " DXGI_GET_DEBUG_INTERFACE_FUNC); - return; + return false; } res = DXGIGetDebugInterfaceFunc(&D3D_IID_IDXGIDebug, (void **)&renderer->dxgiDebug); if (FAILED(res)) { - SDL_LogWarn(SDL_LOG_CATEGORY_GPU, "Could not get IDXGIDebug interface"); + return false; } res = DXGIGetDebugInterfaceFunc(&D3D_IID_IDXGIInfoQueue, (void **)&renderer->dxgiInfoQueue); if (FAILED(res)) { - SDL_LogWarn(SDL_LOG_CATEGORY_GPU, "Could not get IDXGIInfoQueue interface"); + return false; } + + return true; } #endif -static void D3D12_INTERNAL_TryInitializeD3D12Debug(D3D12Renderer *renderer) +static bool D3D12_INTERNAL_TryInitializeD3D12Debug(D3D12Renderer *renderer) { PFN_D3D12_GET_DEBUG_INTERFACE D3D12GetDebugInterfaceFunc; HRESULT res; @@ -8378,21 +8505,20 @@ static void D3D12_INTERNAL_TryInitializeD3D12Debug(D3D12Renderer *renderer) renderer->d3d12_dll, D3D12_GET_DEBUG_INTERFACE_FUNC); if (D3D12GetDebugInterfaceFunc == NULL) { - SDL_LogWarn(SDL_LOG_CATEGORY_GPU, "Could not load function: " D3D12_GET_DEBUG_INTERFACE_FUNC); - return; + return false; } res = D3D12GetDebugInterfaceFunc(D3D_GUID(D3D_IID_ID3D12Debug), (void **)&renderer->d3d12Debug); if (FAILED(res)) { - SDL_LogWarn(SDL_LOG_CATEGORY_GPU, "Could not get ID3D12Debug interface"); - return; + return false; } ID3D12Debug_EnableDebugLayer(renderer->d3d12Debug); + return true; } #if !(defined(SDL_PLATFORM_XBOXONE) || defined(SDL_PLATFORM_XBOXSERIES)) -static bool D3D12_INTERNAL_TryInitializeD3D12DebugInfoQueue(D3D12Renderer *renderer) +static void D3D12_INTERNAL_TryInitializeD3D12DebugInfoQueue(D3D12Renderer *renderer) { ID3D12InfoQueue *infoQueue = NULL; D3D12_MESSAGE_SEVERITY severities[] = { D3D12_MESSAGE_SEVERITY_INFO }; @@ -8404,7 +8530,7 @@ static bool D3D12_INTERNAL_TryInitializeD3D12DebugInfoQueue(D3D12Renderer *rende D3D_GUID(D3D_IID_ID3D12InfoQueue), (void **)&infoQueue); if (FAILED(res)) { - CHECK_D3D12_ERROR_AND_RETURN("Failed to convert ID3D12Device to ID3D12InfoQueue", false); + return; } SDL_zero(filter); @@ -8420,8 +8546,6 @@ static bool D3D12_INTERNAL_TryInitializeD3D12DebugInfoQueue(D3D12Renderer *rende true); ID3D12InfoQueue_Release(infoQueue); - - return true; } static void WINAPI D3D12_INTERNAL_OnD3D12DebugInfoMsg( @@ -8570,9 +8694,12 @@ static SDL_GPUDevice *D3D12_CreateDevice(bool debugMode, bool preferLowPower, SD #ifdef HAVE_IDXGIINFOQUEUE // Initialize the DXGI debug layer, if applicable + bool hasDxgiDebug = false; if (debugMode) { - D3D12_INTERNAL_TryInitializeDXGIDebug(renderer); + hasDxgiDebug = D3D12_INTERNAL_TryInitializeDXGIDebug(renderer); } +#else + bool hasDxgiDebug = true; #endif // Load the CreateDXGIFactory1 function @@ -8705,7 +8832,27 @@ static SDL_GPUDevice *D3D12_CreateDevice(bool debugMode, bool preferLowPower, SD // Initialize the D3D12 debug layer, if applicable if (debugMode) { - D3D12_INTERNAL_TryInitializeD3D12Debug(renderer); + bool hasD3d12Debug = D3D12_INTERNAL_TryInitializeD3D12Debug(renderer); +#if (defined(SDL_PLATFORM_XBOXONE) || defined(SDL_PLATFORM_XBOXSERIES)) + if (hasD3d12Debug) { + SDL_LogInfo( + SDL_LOG_CATEGORY_GPU, + "Validation layers enabled, expect debug level performance!"); +#else + if (hasDxgiDebug && hasD3d12Debug) { + SDL_LogInfo( + SDL_LOG_CATEGORY_GPU, + "Validation layers enabled, expect debug level performance!"); + } else if (hasDxgiDebug || hasD3d12Debug) { + SDL_LogWarn( + SDL_LOG_CATEGORY_GPU, + "Validation layers partially enabled, some warnings may not be available"); +#endif + } else { + SDL_LogWarn( + SDL_LOG_CATEGORY_GPU, + "Validation layers not found, continuing without validation"); + } } // Create the D3D12Device @@ -8752,9 +8899,7 @@ static SDL_GPUDevice *D3D12_CreateDevice(bool debugMode, bool preferLowPower, SD // Initialize the D3D12 debug info queue, if applicable if (debugMode) { - if (!D3D12_INTERNAL_TryInitializeD3D12DebugInfoQueue(renderer)) { - return NULL; - } + D3D12_INTERNAL_TryInitializeD3D12DebugInfoQueue(renderer); D3D12_INTERNAL_TryInitializeD3D12DebugInfoLogger(renderer); } #endif @@ -9035,8 +9180,23 @@ static SDL_GPUDevice *D3D12_CreateDevice(bool debugMode, bool preferLowPower, SD return NULL; } + SDL_GPUShaderFormat shaderFormats = SDL_GPU_SHADERFORMAT_DXBC; + + D3D12_FEATURE_DATA_SHADER_MODEL shaderModel; + shaderModel.HighestShaderModel = D3D_SHADER_MODEL_6_0; + + res = ID3D12Device_CheckFeatureSupport( + renderer->device, + D3D12_FEATURE_SHADER_MODEL, + &shaderModel, + sizeof(shaderModel)); + if (SUCCEEDED(res) && shaderModel.HighestShaderModel >= D3D_SHADER_MODEL_6_0) { + shaderFormats |= SDL_GPU_SHADERFORMAT_DXIL; + } + ASSIGN_DRIVER(D3D12) result->driverData = (SDL_GPURenderer *)renderer; + result->shader_formats = shaderFormats; result->debug_mode = debugMode; renderer->sdlGPUDevice = result; diff --git a/lib/sdl3/SDL/src/gpu/metal/SDL_gpu_metal.m b/lib/sdl3/SDL/src/gpu/metal/SDL_gpu_metal.m index 4ab1020..7c2aefe 100644 --- a/lib/sdl3/SDL/src/gpu/metal/SDL_gpu_metal.m +++ b/lib/sdl3/SDL/src/gpu/metal/SDL_gpu_metal.m @@ -476,33 +476,21 @@ typedef struct MetalShader typedef struct MetalGraphicsPipeline { + GraphicsPipelineCommonHeader header; + id handle; SDL_GPURasterizerState rasterizerState; SDL_GPUPrimitiveType primitiveType; id depth_stencil_state; - - Uint32 vertexSamplerCount; - Uint32 vertexUniformBufferCount; - Uint32 vertexStorageBufferCount; - Uint32 vertexStorageTextureCount; - - Uint32 fragmentSamplerCount; - Uint32 fragmentUniformBufferCount; - Uint32 fragmentStorageBufferCount; - Uint32 fragmentStorageTextureCount; } MetalGraphicsPipeline; typedef struct MetalComputePipeline { + ComputePipelineCommonHeader header; + id handle; - Uint32 numSamplers; - Uint32 numReadonlyStorageTextures; - Uint32 numReadWriteStorageTextures; - Uint32 numReadonlyStorageBuffers; - Uint32 numReadWriteStorageBuffers; - Uint32 numUniformBuffers; Uint32 threadcountX; Uint32 threadcountY; Uint32 threadcountZ; @@ -840,6 +828,10 @@ static MetalLibraryFunction METAL_INTERNAL_CompileShader( dispatch_data_t data; id function; + if (!entrypoint) { + entrypoint = "main0"; + } + if (format == SDL_GPU_SHADERFORMAT_MSL) { NSString *codeString = [[NSString alloc] initWithBytes:code @@ -1055,12 +1047,12 @@ static SDL_GPUComputePipeline *METAL_CreateComputePipeline( pipeline = SDL_calloc(1, sizeof(MetalComputePipeline)); pipeline->handle = handle; - pipeline->numSamplers = createinfo->num_samplers; - pipeline->numReadonlyStorageTextures = createinfo->num_readonly_storage_textures; - pipeline->numReadWriteStorageTextures = createinfo->num_readwrite_storage_textures; - pipeline->numReadonlyStorageBuffers = createinfo->num_readonly_storage_buffers; - pipeline->numReadWriteStorageBuffers = createinfo->num_readwrite_storage_buffers; - pipeline->numUniformBuffers = createinfo->num_uniform_buffers; + pipeline->header.numSamplers = createinfo->num_samplers; + pipeline->header.numReadonlyStorageTextures = createinfo->num_readonly_storage_textures; + pipeline->header.numReadWriteStorageTextures = createinfo->num_readwrite_storage_textures; + pipeline->header.numReadonlyStorageBuffers = createinfo->num_readonly_storage_buffers; + pipeline->header.numReadWriteStorageBuffers = createinfo->num_readwrite_storage_buffers; + pipeline->header.numUniformBuffers = createinfo->num_uniform_buffers; pipeline->threadcountX = createinfo->threadcount_x; pipeline->threadcountY = createinfo->threadcount_y; pipeline->threadcountZ = createinfo->threadcount_z; @@ -1203,14 +1195,14 @@ static SDL_GPUGraphicsPipeline *METAL_CreateGraphicsPipeline( result->depth_stencil_state = depthStencilState; result->rasterizerState = createinfo->rasterizer_state; result->primitiveType = createinfo->primitive_type; - result->vertexSamplerCount = vertexShader->numSamplers; - result->vertexUniformBufferCount = vertexShader->numUniformBuffers; - result->vertexStorageBufferCount = vertexShader->numStorageBuffers; - result->vertexStorageTextureCount = vertexShader->numStorageTextures; - result->fragmentSamplerCount = fragmentShader->numSamplers; - result->fragmentUniformBufferCount = fragmentShader->numUniformBuffers; - result->fragmentStorageBufferCount = fragmentShader->numStorageBuffers; - result->fragmentStorageTextureCount = fragmentShader->numStorageTextures; + result->header.num_vertex_samplers = vertexShader->numSamplers; + result->header.num_vertex_uniform_buffers = vertexShader->numUniformBuffers; + result->header.num_vertex_storage_buffers = vertexShader->numStorageBuffers; + result->header.num_vertex_storage_textures = vertexShader->numStorageTextures; + result->header.num_fragment_samplers = fragmentShader->numSamplers; + result->header.num_fragment_uniform_buffers = fragmentShader->numUniformBuffers; + result->header.num_fragment_storage_buffers = fragmentShader->numStorageBuffers; + result->header.num_fragment_storage_textures = fragmentShader->numStorageTextures; return (SDL_GPUGraphicsPipeline *)result; } } @@ -1494,7 +1486,9 @@ static SDL_GPUTexture *METAL_CreateTexture( // Copy properties so we don't lose information when the client destroys them container->header.info = *createinfo; container->header.info.props = SDL_CreateProperties(); - SDL_CopyProperties(createinfo->props, container->header.info.props); + if (createinfo->props) { + SDL_CopyProperties(createinfo->props, container->header.info.props); + } container->activeTexture = texture; container->textureCapacity = 1; @@ -2406,14 +2400,14 @@ static void METAL_BindGraphicsPipeline( metalCommandBuffer->needFragmentUniformBufferBind[i] = true; } - for (i = 0; i < pipeline->vertexUniformBufferCount; i += 1) { + for (i = 0; i < pipeline->header.num_vertex_uniform_buffers; i += 1) { if (metalCommandBuffer->vertexUniformBuffers[i] == NULL) { metalCommandBuffer->vertexUniformBuffers[i] = METAL_INTERNAL_AcquireUniformBufferFromPool( metalCommandBuffer); } } - for (i = 0; i < pipeline->fragmentUniformBufferCount; i += 1) { + for (i = 0; i < pipeline->header.num_fragment_uniform_buffers; i += 1) { if (metalCommandBuffer->fragmentUniformBuffers[i] == NULL) { metalCommandBuffer->fragmentUniformBuffers[i] = METAL_INTERNAL_AcquireUniformBufferFromPool( metalCommandBuffer); @@ -2644,11 +2638,11 @@ static void METAL_INTERNAL_BindGraphicsResources( // Vertex Samplers+Textures if (commandBuffer->needVertexSamplerBind) { - if (graphicsPipeline->vertexSamplerCount > 0) { + if (graphicsPipeline->header.num_vertex_samplers > 0) { [commandBuffer->renderEncoder setVertexSamplerStates:commandBuffer->vertexSamplers - withRange:NSMakeRange(0, graphicsPipeline->vertexSamplerCount)]; + withRange:NSMakeRange(0, graphicsPipeline->header.num_vertex_samplers)]; [commandBuffer->renderEncoder setVertexTextures:commandBuffer->vertexTextures - withRange:NSMakeRange(0, graphicsPipeline->vertexSamplerCount)]; + withRange:NSMakeRange(0, graphicsPipeline->header.num_vertex_samplers)]; } commandBuffer->needVertexSamplerBind = false; } @@ -2656,10 +2650,10 @@ static void METAL_INTERNAL_BindGraphicsResources( // Vertex Storage Textures if (commandBuffer->needVertexStorageTextureBind) { - if (graphicsPipeline->vertexStorageTextureCount > 0) { + if (graphicsPipeline->header.num_vertex_storage_textures > 0) { [commandBuffer->renderEncoder setVertexTextures:commandBuffer->vertexStorageTextures - withRange:NSMakeRange(graphicsPipeline->vertexSamplerCount, - graphicsPipeline->vertexStorageTextureCount)]; + withRange:NSMakeRange(graphicsPipeline->header.num_vertex_samplers, + graphicsPipeline->header.num_vertex_storage_textures)]; } commandBuffer->needVertexStorageTextureBind = false; } @@ -2667,20 +2661,20 @@ static void METAL_INTERNAL_BindGraphicsResources( // Vertex Storage Buffers if (commandBuffer->needVertexStorageBufferBind) { - if (graphicsPipeline->vertexStorageBufferCount > 0) { + if (graphicsPipeline->header.num_vertex_storage_buffers > 0) { [commandBuffer->renderEncoder setVertexBuffers:commandBuffer->vertexStorageBuffers offsets:offsets - withRange:NSMakeRange(graphicsPipeline->vertexUniformBufferCount, - graphicsPipeline->vertexStorageBufferCount)]; + withRange:NSMakeRange(graphicsPipeline->header.num_vertex_uniform_buffers, + graphicsPipeline->header.num_vertex_storage_buffers)]; } commandBuffer->needVertexStorageBufferBind = false; } // Vertex Uniform Buffers - for (Uint32 i = 0; i < graphicsPipeline->vertexUniformBufferCount; i += 1) { + for (Uint32 i = 0; i < graphicsPipeline->header.num_vertex_uniform_buffers; i += 1) { if (commandBuffer->needVertexUniformBufferBind[i]) { - if (graphicsPipeline->vertexUniformBufferCount > i) { + if (graphicsPipeline->header.num_vertex_uniform_buffers > i) { [commandBuffer->renderEncoder setVertexBuffer:commandBuffer->vertexUniformBuffers[i]->handle offset:commandBuffer->vertexUniformBuffers[i]->drawOffset @@ -2693,11 +2687,11 @@ static void METAL_INTERNAL_BindGraphicsResources( // Fragment Samplers+Textures if (commandBuffer->needFragmentSamplerBind) { - if (graphicsPipeline->fragmentSamplerCount > 0) { + if (graphicsPipeline->header.num_fragment_samplers > 0) { [commandBuffer->renderEncoder setFragmentSamplerStates:commandBuffer->fragmentSamplers - withRange:NSMakeRange(0, graphicsPipeline->fragmentSamplerCount)]; + withRange:NSMakeRange(0, graphicsPipeline->header.num_fragment_samplers)]; [commandBuffer->renderEncoder setFragmentTextures:commandBuffer->fragmentTextures - withRange:NSMakeRange(0, graphicsPipeline->fragmentSamplerCount)]; + withRange:NSMakeRange(0, graphicsPipeline->header.num_fragment_samplers)]; } commandBuffer->needFragmentSamplerBind = false; } @@ -2705,10 +2699,10 @@ static void METAL_INTERNAL_BindGraphicsResources( // Fragment Storage Textures if (commandBuffer->needFragmentStorageTextureBind) { - if (graphicsPipeline->fragmentStorageTextureCount > 0) { + if (graphicsPipeline->header.num_fragment_storage_textures > 0) { [commandBuffer->renderEncoder setFragmentTextures:commandBuffer->fragmentStorageTextures - withRange:NSMakeRange(graphicsPipeline->fragmentSamplerCount, - graphicsPipeline->fragmentStorageTextureCount)]; + withRange:NSMakeRange(graphicsPipeline->header.num_fragment_samplers, + graphicsPipeline->header.num_fragment_storage_textures)]; } commandBuffer->needFragmentStorageTextureBind = false; } @@ -2716,20 +2710,20 @@ static void METAL_INTERNAL_BindGraphicsResources( // Fragment Storage Buffers if (commandBuffer->needFragmentStorageBufferBind) { - if (graphicsPipeline->fragmentStorageBufferCount > 0) { + if (graphicsPipeline->header.num_fragment_storage_buffers > 0) { [commandBuffer->renderEncoder setFragmentBuffers:commandBuffer->fragmentStorageBuffers offsets:offsets - withRange:NSMakeRange(graphicsPipeline->fragmentUniformBufferCount, - graphicsPipeline->fragmentStorageBufferCount)]; + withRange:NSMakeRange(graphicsPipeline->header.num_fragment_uniform_buffers, + graphicsPipeline->header.num_fragment_storage_buffers)]; } commandBuffer->needFragmentStorageBufferBind = false; } // Fragment Uniform Buffers - for (Uint32 i = 0; i < graphicsPipeline->fragmentUniformBufferCount; i += 1) { + for (Uint32 i = 0; i < graphicsPipeline->header.num_fragment_uniform_buffers; i += 1) { if (commandBuffer->needFragmentUniformBufferBind[i]) { - if (graphicsPipeline->fragmentUniformBufferCount > i) { + if (graphicsPipeline->header.num_fragment_uniform_buffers > i) { [commandBuffer->renderEncoder setFragmentBuffer:commandBuffer->fragmentUniformBuffers[i]->handle offset:commandBuffer->fragmentUniformBuffers[i]->drawOffset @@ -2748,38 +2742,38 @@ static void METAL_INTERNAL_BindComputeResources( NSUInteger offsets[MAX_STORAGE_BUFFERS_PER_STAGE] = { 0 }; if (commandBuffer->needComputeSamplerBind) { - if (computePipeline->numSamplers > 0) { + if (computePipeline->header.numSamplers > 0) { [commandBuffer->computeEncoder setTextures:commandBuffer->computeSamplerTextures - withRange:NSMakeRange(0, computePipeline->numSamplers)]; + withRange:NSMakeRange(0, computePipeline->header.numSamplers)]; [commandBuffer->computeEncoder setSamplerStates:commandBuffer->computeSamplers - withRange:NSMakeRange(0, computePipeline->numSamplers)]; + withRange:NSMakeRange(0, computePipeline->header.numSamplers)]; } commandBuffer->needComputeSamplerBind = false; } if (commandBuffer->needComputeReadOnlyStorageTextureBind) { - if (computePipeline->numReadonlyStorageTextures > 0) { + if (computePipeline->header.numReadonlyStorageTextures > 0) { [commandBuffer->computeEncoder setTextures:commandBuffer->computeReadOnlyTextures withRange:NSMakeRange( - computePipeline->numSamplers, - computePipeline->numReadonlyStorageTextures)]; + computePipeline->header.numSamplers, + computePipeline->header.numReadonlyStorageTextures)]; } commandBuffer->needComputeReadOnlyStorageTextureBind = false; } if (commandBuffer->needComputeReadOnlyStorageBufferBind) { - if (computePipeline->numReadonlyStorageBuffers > 0) { + if (computePipeline->header.numReadonlyStorageBuffers > 0) { [commandBuffer->computeEncoder setBuffers:commandBuffer->computeReadOnlyBuffers offsets:offsets - withRange:NSMakeRange(computePipeline->numUniformBuffers, - computePipeline->numReadonlyStorageBuffers)]; + withRange:NSMakeRange(computePipeline->header.numUniformBuffers, + computePipeline->header.numReadonlyStorageBuffers)]; } commandBuffer->needComputeReadOnlyStorageBufferBind = false; } for (Uint32 i = 0; i < MAX_UNIFORM_BUFFERS_PER_STAGE; i += 1) { if (commandBuffer->needComputeUniformBufferBind[i]) { - if (computePipeline->numUniformBuffers > i) { + if (computePipeline->header.numUniformBuffers > i) { [commandBuffer->computeEncoder setBuffer:commandBuffer->computeUniformBuffers[i]->handle offset:commandBuffer->computeUniformBuffers[i]->drawOffset @@ -3127,7 +3121,7 @@ static void METAL_BindComputePipeline( metalCommandBuffer->needComputeUniformBufferBind[i] = true; } - for (Uint32 i = 0; i < pipeline->numUniformBuffers; i += 1) { + for (Uint32 i = 0; i < pipeline->header.numUniformBuffers; i += 1) { if (metalCommandBuffer->computeUniformBuffers[i] == NULL) { metalCommandBuffer->computeUniformBuffers[i] = METAL_INTERNAL_AcquireUniformBufferFromPool( metalCommandBuffer); @@ -3135,22 +3129,22 @@ static void METAL_BindComputePipeline( } // Bind write-only resources - if (pipeline->numReadWriteStorageTextures > 0) { + if (pipeline->header.numReadWriteStorageTextures > 0) { [metalCommandBuffer->computeEncoder setTextures:metalCommandBuffer->computeReadWriteTextures withRange:NSMakeRange( - pipeline->numSamplers + - pipeline->numReadonlyStorageTextures, - pipeline->numReadWriteStorageTextures)]; + pipeline->header.numSamplers + + pipeline->header.numReadonlyStorageTextures, + pipeline->header.numReadWriteStorageTextures)]; } NSUInteger offsets[MAX_COMPUTE_WRITE_BUFFERS] = { 0 }; - if (pipeline->numReadWriteStorageBuffers > 0) { + if (pipeline->header.numReadWriteStorageBuffers > 0) { [metalCommandBuffer->computeEncoder setBuffers:metalCommandBuffer->computeReadWriteBuffers offsets:offsets withRange:NSMakeRange( - pipeline->numUniformBuffers + - pipeline->numReadonlyStorageBuffers, - pipeline->numReadWriteStorageBuffers)]; + pipeline->header.numUniformBuffers + + pipeline->header.numReadonlyStorageBuffers, + pipeline->header.numReadWriteStorageBuffers)]; } } } @@ -4564,6 +4558,7 @@ static SDL_GPUDevice *METAL_CreateDevice(bool debugMode, bool preferLowPower, SD SDL_GPUDevice *result = SDL_calloc(1, sizeof(SDL_GPUDevice)); ASSIGN_DRIVER(METAL) result->driverData = (SDL_GPURenderer *)renderer; + result->shader_formats = SDL_GPU_SHADERFORMAT_MSL | SDL_GPU_SHADERFORMAT_METALLIB; renderer->sdlGPUDevice = result; return result; diff --git a/lib/sdl3/SDL/src/gpu/vulkan/SDL_gpu_vulkan.c b/lib/sdl3/SDL/src/gpu/vulkan/SDL_gpu_vulkan.c index 7ea1036..4467ef8 100644 --- a/lib/sdl3/SDL/src/gpu/vulkan/SDL_gpu_vulkan.c +++ b/lib/sdl3/SDL/src/gpu/vulkan/SDL_gpu_vulkan.c @@ -606,7 +606,7 @@ typedef struct VulkanSampler typedef struct VulkanShader { VkShaderModule shaderModule; - const char *entrypointName; + char *entrypointName; SDL_GPUShaderStage stage; Uint32 numSamplers; Uint32 numStorageTextures; @@ -732,7 +732,7 @@ typedef struct WindowData // Synchronization primitives VkSemaphore imageAvailableSemaphore[MAX_FRAMES_IN_FLIGHT]; - VkSemaphore renderFinishedSemaphore[MAX_FRAMES_IN_FLIGHT]; + VkSemaphore *renderFinishedSemaphore; SDL_GPUFence *inFlightFences[MAX_FRAMES_IN_FLIGHT]; Uint32 frameCounter; @@ -822,13 +822,13 @@ typedef struct DescriptorSetLayout typedef struct GraphicsPipelineResourceLayoutHashTableKey { Uint32 vertexSamplerCount; - Uint32 vertexStorageBufferCount; Uint32 vertexStorageTextureCount; + Uint32 vertexStorageBufferCount; Uint32 vertexUniformBufferCount; Uint32 fragmentSamplerCount; - Uint32 fragmentStorageBufferCount; Uint32 fragmentStorageTextureCount; + Uint32 fragmentStorageBufferCount; Uint32 fragmentUniformBufferCount; } GraphicsPipelineResourceLayoutHashTableKey; @@ -846,18 +846,20 @@ typedef struct VulkanGraphicsPipelineResourceLayout DescriptorSetLayout *descriptorSetLayouts[4]; Uint32 vertexSamplerCount; - Uint32 vertexStorageBufferCount; Uint32 vertexStorageTextureCount; + Uint32 vertexStorageBufferCount; Uint32 vertexUniformBufferCount; Uint32 fragmentSamplerCount; - Uint32 fragmentStorageBufferCount; Uint32 fragmentStorageTextureCount; + Uint32 fragmentStorageBufferCount; Uint32 fragmentUniformBufferCount; } VulkanGraphicsPipelineResourceLayout; typedef struct VulkanGraphicsPipeline { + GraphicsPipelineCommonHeader header; + VkPipeline pipeline; SDL_GPUPrimitiveType primitiveType; @@ -901,6 +903,8 @@ typedef struct VulkanComputePipelineResourceLayout typedef struct VulkanComputePipeline { + ComputePipelineCommonHeader header; + VkShaderModule shaderModule; VkPipeline pipeline; VulkanComputePipelineResourceLayout *resourceLayout; @@ -1038,25 +1042,33 @@ typedef struct VulkanCommandBuffer Uint32 vertexBufferCount; bool needVertexBufferBind; - VulkanTexture *vertexSamplerTextures[MAX_TEXTURE_SAMPLERS_PER_STAGE]; - VulkanSampler *vertexSamplers[MAX_TEXTURE_SAMPLERS_PER_STAGE]; - VulkanTexture *vertexStorageTextures[MAX_STORAGE_TEXTURES_PER_STAGE]; - VulkanBuffer *vertexStorageBuffers[MAX_STORAGE_BUFFERS_PER_STAGE]; + VkImageView vertexSamplerTextureViewBindings[MAX_TEXTURE_SAMPLERS_PER_STAGE]; + VkSampler vertexSamplerBindings[MAX_TEXTURE_SAMPLERS_PER_STAGE]; + VkImageView vertexStorageTextureViewBindings[MAX_STORAGE_TEXTURES_PER_STAGE]; + VkBuffer vertexStorageBufferBindings[MAX_STORAGE_BUFFERS_PER_STAGE]; - VulkanTexture *fragmentSamplerTextures[MAX_TEXTURE_SAMPLERS_PER_STAGE]; - VulkanSampler *fragmentSamplers[MAX_TEXTURE_SAMPLERS_PER_STAGE]; - VulkanTexture *fragmentStorageTextures[MAX_STORAGE_TEXTURES_PER_STAGE]; - VulkanBuffer *fragmentStorageBuffers[MAX_STORAGE_BUFFERS_PER_STAGE]; + VkImageView fragmentSamplerTextureViewBindings[MAX_TEXTURE_SAMPLERS_PER_STAGE]; + VkSampler fragmentSamplerBindings[MAX_TEXTURE_SAMPLERS_PER_STAGE]; + VkImageView fragmentStorageTextureViewBindings[MAX_STORAGE_TEXTURES_PER_STAGE]; + VkBuffer fragmentStorageBufferBindings[MAX_STORAGE_BUFFERS_PER_STAGE]; + VkImageView computeSamplerTextureViewBindings[MAX_TEXTURE_SAMPLERS_PER_STAGE]; + VkSampler computeSamplerBindings[MAX_TEXTURE_SAMPLERS_PER_STAGE]; + VkImageView readOnlyComputeStorageTextureViewBindings[MAX_STORAGE_TEXTURES_PER_STAGE]; + VkBuffer readOnlyComputeStorageBufferBindings[MAX_STORAGE_BUFFERS_PER_STAGE]; + + // Track these separately because barriers can happen mid compute pass + VulkanTexture *readOnlyComputeStorageTextures[MAX_STORAGE_TEXTURES_PER_STAGE]; + VulkanBuffer *readOnlyComputeStorageBuffers[MAX_STORAGE_BUFFERS_PER_STAGE]; + + VkImageView readWriteComputeStorageTextureViewBindings[MAX_COMPUTE_WRITE_TEXTURES]; + VkBuffer readWriteComputeStorageBufferBindings[MAX_COMPUTE_WRITE_BUFFERS]; + + // Track these separately because they are barriered when the compute pass begins VulkanTextureSubresource *readWriteComputeStorageTextureSubresources[MAX_COMPUTE_WRITE_TEXTURES]; Uint32 readWriteComputeStorageTextureSubresourceCount; VulkanBuffer *readWriteComputeStorageBuffers[MAX_COMPUTE_WRITE_BUFFERS]; - VulkanTexture *computeSamplerTextures[MAX_TEXTURE_SAMPLERS_PER_STAGE]; - VulkanSampler *computeSamplers[MAX_TEXTURE_SAMPLERS_PER_STAGE]; - VulkanTexture *readOnlyComputeStorageTextures[MAX_STORAGE_TEXTURES_PER_STAGE]; - VulkanBuffer *readOnlyComputeStorageBuffers[MAX_STORAGE_BUFFERS_PER_STAGE]; - // Uniform buffers VulkanUniformBuffer *vertexUniformBuffers[MAX_UNIFORM_BUFFERS_PER_STAGE]; @@ -1206,6 +1218,9 @@ struct VulkanRenderer SDL_Mutex *acquireUniformBufferLock; SDL_Mutex *renderPassFetchLock; SDL_Mutex *framebufferFetchLock; + SDL_Mutex *graphicsPipelineLayoutFetchLock; + SDL_Mutex *computePipelineLayoutFetchLock; + SDL_Mutex *descriptorSetLayoutFetchLock; SDL_Mutex *windowLock; Uint8 defragInProgress; @@ -1223,7 +1238,7 @@ struct VulkanRenderer // Forward declarations -static bool VULKAN_INTERNAL_DefragmentMemory(VulkanRenderer *renderer); +static bool VULKAN_INTERNAL_DefragmentMemory(VulkanRenderer *renderer, VulkanCommandBuffer *commandBuffer); static bool VULKAN_INTERNAL_BeginCommandBuffer(VulkanRenderer *renderer, VulkanCommandBuffer *commandBuffer); static void VULKAN_ReleaseWindow(SDL_GPURenderer *driverData, SDL_Window *window); static bool VULKAN_Wait(SDL_GPURenderer *driverData); @@ -1255,6 +1270,7 @@ static inline const char *VkErrorMessages(VkResult code) ERR_TO_STR(VK_ERROR_FULL_SCREEN_EXCLUSIVE_MODE_LOST_EXT) ERR_TO_STR(VK_SUBOPTIMAL_KHR) ERR_TO_STR(VK_ERROR_NATIVE_WINDOW_IN_USE_KHR) + ERR_TO_STR(VK_ERROR_INVALID_SHADER_NV) default: return "Unhandled VkResult!"; } @@ -3175,7 +3191,7 @@ static void VULKAN_INTERNAL_DestroyShader( vulkanShader->shaderModule, NULL); - SDL_free((void *)vulkanShader->entrypointName); + SDL_free(vulkanShader->entrypointName); SDL_free(vulkanShader); } @@ -3213,7 +3229,6 @@ static void VULKAN_INTERNAL_DestroySwapchain( SDL_free(windowData->textureContainers[i].activeTexture->subresources); SDL_free(windowData->textureContainers[i].activeTexture); } - windowData->imageCount = 0; SDL_free(windowData->textureContainers); windowData->textureContainers = NULL; @@ -3242,7 +3257,8 @@ static void VULKAN_INTERNAL_DestroySwapchain( NULL); windowData->imageAvailableSemaphore[i] = VK_NULL_HANDLE; } - + } + for (i = 0; i < windowData->imageCount; i += 1) { if (windowData->renderFinishedSemaphore[i]) { renderer->vkDestroySemaphore( renderer->logicalDevice, @@ -3251,6 +3267,10 @@ static void VULKAN_INTERNAL_DestroySwapchain( windowData->renderFinishedSemaphore[i] = VK_NULL_HANDLE; } } + SDL_free(windowData->renderFinishedSemaphore); + windowData->renderFinishedSemaphore = NULL; + + windowData->imageCount = 0; } static void VULKAN_INTERNAL_DestroyGraphicsPipelineResourceLayout( @@ -3750,10 +3770,13 @@ static DescriptorSetLayout *VULKAN_INTERNAL_FetchDescriptorSetLayout( key.writeStorageBufferCount = writeStorageBufferCount; key.uniformBufferCount = uniformBufferCount; + SDL_LockMutex(renderer->descriptorSetLayoutFetchLock); + if (SDL_FindInHashTable( renderer->descriptorSetLayoutHashTable, (const void *)&key, (const void **)&layout)) { + SDL_UnlockMutex(renderer->descriptorSetLayoutFetchLock); return layout; } @@ -3836,7 +3859,10 @@ static DescriptorSetLayout *VULKAN_INTERNAL_FetchDescriptorSetLayout( NULL, &descriptorSetLayout); - CHECK_VULKAN_ERROR_AND_RETURN(vulkanResult, vkCreateDescriptorSetLayout, NULL); + if (vulkanResult != VK_SUCCESS) { + SDL_UnlockMutex(renderer->descriptorSetLayoutFetchLock); + CHECK_VULKAN_ERROR_AND_RETURN(vulkanResult, vkCreateDescriptorSetLayout, NULL); + } layout = SDL_malloc(sizeof(DescriptorSetLayout)); layout->descriptorSetLayout = descriptorSetLayout; @@ -3858,6 +3884,7 @@ static DescriptorSetLayout *VULKAN_INTERNAL_FetchDescriptorSetLayout( (const void *)allocedKey, (const void *)layout, true); + SDL_UnlockMutex(renderer->descriptorSetLayoutFetchLock); return layout; } @@ -3878,10 +3905,14 @@ static VulkanGraphicsPipelineResourceLayout *VULKAN_INTERNAL_FetchGraphicsPipeli key.fragmentStorageTextureCount = fragmentShader->numStorageTextures; key.fragmentStorageBufferCount = fragmentShader->numStorageBuffers; key.fragmentUniformBufferCount = fragmentShader->numUniformBuffers; + + SDL_LockMutex(renderer->graphicsPipelineLayoutFetchLock); + if (SDL_FindInHashTable( renderer->graphicsPipelineResourceLayoutHashTable, (const void *)&key, (const void **)&pipelineResourceLayout)) { + SDL_UnlockMutex(renderer->graphicsPipelineLayoutFetchLock); return pipelineResourceLayout; } @@ -3964,6 +3995,7 @@ static VulkanGraphicsPipelineResourceLayout *VULKAN_INTERNAL_FetchGraphicsPipeli if (vulkanResult != VK_SUCCESS) { VULKAN_INTERNAL_DestroyGraphicsPipelineResourceLayout(renderer, pipelineResourceLayout); + SDL_UnlockMutex(renderer->graphicsPipelineLayoutFetchLock); CHECK_VULKAN_ERROR_AND_RETURN(vulkanResult, vkCreatePipelineLayout, NULL); } @@ -3975,6 +4007,7 @@ static VulkanGraphicsPipelineResourceLayout *VULKAN_INTERNAL_FetchGraphicsPipeli (const void *)allocedKey, (const void *)pipelineResourceLayout, true); + SDL_UnlockMutex(renderer->graphicsPipelineLayoutFetchLock); return pipelineResourceLayout; } @@ -3993,10 +4026,13 @@ static VulkanComputePipelineResourceLayout *VULKAN_INTERNAL_FetchComputePipeline key.readWriteStorageBufferCount = createinfo->num_readwrite_storage_buffers; key.uniformBufferCount = createinfo->num_uniform_buffers; + SDL_LockMutex(renderer->computePipelineLayoutFetchLock); + if (SDL_FindInHashTable( renderer->computePipelineResourceLayoutHashTable, (const void *)&key, (const void **)&pipelineResourceLayout)) { + SDL_UnlockMutex(renderer->computePipelineLayoutFetchLock); return pipelineResourceLayout; } @@ -4065,6 +4101,7 @@ static VulkanComputePipelineResourceLayout *VULKAN_INTERNAL_FetchComputePipeline if (vulkanResult != VK_SUCCESS) { VULKAN_INTERNAL_DestroyComputePipelineResourceLayout(renderer, pipelineResourceLayout); + SDL_UnlockMutex(renderer->computePipelineLayoutFetchLock); CHECK_VULKAN_ERROR_AND_RETURN(vulkanResult, vkCreatePipelineLayout, NULL); } @@ -4076,6 +4113,7 @@ static VulkanComputePipelineResourceLayout *VULKAN_INTERNAL_FetchComputePipeline (const void *)allocedKey, (const void *)pipelineResourceLayout, true); + SDL_UnlockMutex(renderer->computePipelineLayoutFetchLock); return pipelineResourceLayout; } @@ -4790,6 +4828,12 @@ static Uint32 VULKAN_INTERNAL_CreateSwapchain( CHECK_VULKAN_ERROR_AND_RETURN(vulkanResult, vkCreateSemaphore, false); } + windowData->inFlightFences[i] = NULL; + } + + windowData->renderFinishedSemaphore = SDL_malloc( + sizeof(VkSemaphore) * windowData->imageCount); + for (i = 0; i < windowData->imageCount; i += 1) { vulkanResult = renderer->vkCreateSemaphore( renderer->logicalDevice, &semaphoreCreateInfo, @@ -4809,8 +4853,6 @@ static Uint32 VULKAN_INTERNAL_CreateSwapchain( windowData->swapchain = VK_NULL_HANDLE; CHECK_VULKAN_ERROR_AND_RETURN(vulkanResult, vkCreateSemaphore, false); } - - windowData->inFlightFences[i] = NULL; } windowData->needsSwapchainRecreate = false; @@ -4946,6 +4988,9 @@ static void VULKAN_DestroyDevice( SDL_DestroyMutex(renderer->acquireUniformBufferLock); SDL_DestroyMutex(renderer->renderPassFetchLock); SDL_DestroyMutex(renderer->framebufferFetchLock); + SDL_DestroyMutex(renderer->graphicsPipelineLayoutFetchLock); + SDL_DestroyMutex(renderer->computePipelineLayoutFetchLock); + SDL_DestroyMutex(renderer->descriptorSetLayoutFetchLock); SDL_DestroyMutex(renderer->windowLock); renderer->vkDestroyDevice(renderer->logicalDevice, NULL); @@ -5093,8 +5138,8 @@ static void VULKAN_INTERNAL_BindGraphicsDescriptorSets( currentWriteDescriptorSet->pTexelBufferView = NULL; currentWriteDescriptorSet->pBufferInfo = NULL; - imageInfos[imageInfoCount].sampler = commandBuffer->vertexSamplers[i]->sampler; - imageInfos[imageInfoCount].imageView = commandBuffer->vertexSamplerTextures[i]->fullView; + imageInfos[imageInfoCount].sampler = commandBuffer->vertexSamplerBindings[i]; + imageInfos[imageInfoCount].imageView = commandBuffer->vertexSamplerTextureViewBindings[i]; imageInfos[imageInfoCount].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; currentWriteDescriptorSet->pImageInfo = &imageInfos[imageInfoCount]; @@ -5117,7 +5162,7 @@ static void VULKAN_INTERNAL_BindGraphicsDescriptorSets( currentWriteDescriptorSet->pBufferInfo = NULL; imageInfos[imageInfoCount].sampler = VK_NULL_HANDLE; - imageInfos[imageInfoCount].imageView = commandBuffer->vertexStorageTextures[i]->fullView; + imageInfos[imageInfoCount].imageView = commandBuffer->vertexStorageTextureViewBindings[i]; imageInfos[imageInfoCount].imageLayout = VK_IMAGE_LAYOUT_GENERAL; currentWriteDescriptorSet->pImageInfo = &imageInfos[imageInfoCount]; @@ -5139,7 +5184,7 @@ static void VULKAN_INTERNAL_BindGraphicsDescriptorSets( currentWriteDescriptorSet->pTexelBufferView = NULL; currentWriteDescriptorSet->pImageInfo = NULL; - bufferInfos[bufferInfoCount].buffer = commandBuffer->vertexStorageBuffers[i]->buffer; + bufferInfos[bufferInfoCount].buffer = commandBuffer->vertexStorageBufferBindings[i]; bufferInfos[bufferInfoCount].offset = 0; bufferInfos[bufferInfoCount].range = VK_WHOLE_SIZE; @@ -5212,8 +5257,8 @@ static void VULKAN_INTERNAL_BindGraphicsDescriptorSets( currentWriteDescriptorSet->pTexelBufferView = NULL; currentWriteDescriptorSet->pBufferInfo = NULL; - imageInfos[imageInfoCount].sampler = commandBuffer->fragmentSamplers[i]->sampler; - imageInfos[imageInfoCount].imageView = commandBuffer->fragmentSamplerTextures[i]->fullView; + imageInfos[imageInfoCount].sampler = commandBuffer->fragmentSamplerBindings[i]; + imageInfos[imageInfoCount].imageView = commandBuffer->fragmentSamplerTextureViewBindings[i]; imageInfos[imageInfoCount].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; currentWriteDescriptorSet->pImageInfo = &imageInfos[imageInfoCount]; @@ -5236,7 +5281,7 @@ static void VULKAN_INTERNAL_BindGraphicsDescriptorSets( currentWriteDescriptorSet->pBufferInfo = NULL; imageInfos[imageInfoCount].sampler = VK_NULL_HANDLE; - imageInfos[imageInfoCount].imageView = commandBuffer->fragmentStorageTextures[i]->fullView; + imageInfos[imageInfoCount].imageView = commandBuffer->fragmentStorageTextureViewBindings[i]; imageInfos[imageInfoCount].imageLayout = VK_IMAGE_LAYOUT_GENERAL; currentWriteDescriptorSet->pImageInfo = &imageInfos[imageInfoCount]; @@ -5258,7 +5303,7 @@ static void VULKAN_INTERNAL_BindGraphicsDescriptorSets( currentWriteDescriptorSet->pTexelBufferView = NULL; currentWriteDescriptorSet->pImageInfo = NULL; - bufferInfos[bufferInfoCount].buffer = commandBuffer->fragmentStorageBuffers[i]->buffer; + bufferInfos[bufferInfoCount].buffer = commandBuffer->fragmentStorageBufferBindings[i]; bufferInfos[bufferInfoCount].offset = 0; bufferInfos[bufferInfoCount].range = VK_WHOLE_SIZE; @@ -5602,6 +5647,7 @@ static void VULKAN_PopDebugGroup( static VulkanTexture *VULKAN_INTERNAL_CreateTexture( VulkanRenderer *renderer, + bool transitionToDefaultLayout, const SDL_GPUTextureCreateInfo *createinfo) { VkResult vulkanResult; @@ -5829,15 +5875,17 @@ static VulkanTexture *VULKAN_INTERNAL_CreateTexture( &nameInfo); } - // Let's transition to the default barrier state, because for some reason Vulkan doesn't let us do that with initialLayout. - VulkanCommandBuffer *barrierCommandBuffer = (VulkanCommandBuffer *)VULKAN_AcquireCommandBuffer((SDL_GPURenderer *)renderer); - VULKAN_INTERNAL_TextureTransitionToDefaultUsage( - renderer, - barrierCommandBuffer, - VULKAN_TEXTURE_USAGE_MODE_UNINITIALIZED, - texture); - VULKAN_INTERNAL_TrackTexture(barrierCommandBuffer, texture); - VULKAN_Submit((SDL_GPUCommandBuffer *)barrierCommandBuffer); + if (transitionToDefaultLayout) { + // Let's transition to the default barrier state, because for some reason Vulkan doesn't let us do that with initialLayout. + VulkanCommandBuffer *barrierCommandBuffer = (VulkanCommandBuffer *)VULKAN_AcquireCommandBuffer((SDL_GPURenderer *)renderer); + VULKAN_INTERNAL_TextureTransitionToDefaultUsage( + renderer, + barrierCommandBuffer, + VULKAN_TEXTURE_USAGE_MODE_UNINITIALIZED, + texture); + VULKAN_INTERNAL_TrackTexture(barrierCommandBuffer, texture); + VULKAN_Submit((SDL_GPUCommandBuffer *)barrierCommandBuffer); + } return texture; } @@ -5887,6 +5935,7 @@ static void VULKAN_INTERNAL_CycleActiveBuffer( static void VULKAN_INTERNAL_CycleActiveTexture( VulkanRenderer *renderer, + VulkanCommandBuffer *commandBuffer, VulkanTextureContainer *container) { VulkanTexture *texture; @@ -5904,8 +5953,15 @@ static void VULKAN_INTERNAL_CycleActiveTexture( // No texture is available, generate a new one. texture = VULKAN_INTERNAL_CreateTexture( renderer, + false, &container->header.info); + VULKAN_INTERNAL_TextureTransitionToDefaultUsage( + renderer, + commandBuffer, + VULKAN_TEXTURE_USAGE_MODE_UNINITIALIZED, + texture); + if (!texture) { return; } @@ -5969,6 +6025,7 @@ static VulkanTextureSubresource *VULKAN_INTERNAL_PrepareTextureSubresourceForWri SDL_GetAtomicInt(&textureContainer->activeTexture->referenceCount) > 0) { VULKAN_INTERNAL_CycleActiveTexture( renderer, + commandBuffer, textureContainer); textureSubresource = VULKAN_INTERNAL_FetchTextureSubresource( @@ -6520,6 +6577,16 @@ static SDL_GPUGraphicsPipeline *VULKAN_CreateGraphicsPipeline( &nameInfo); } + // Put this data in the pipeline we can do validation in gpu.c + graphicsPipeline->header.num_vertex_samplers = graphicsPipeline->resourceLayout->vertexSamplerCount; + graphicsPipeline->header.num_vertex_storage_buffers = graphicsPipeline->resourceLayout->vertexStorageBufferCount; + graphicsPipeline->header.num_vertex_storage_textures = graphicsPipeline->resourceLayout->vertexStorageTextureCount; + graphicsPipeline->header.num_vertex_uniform_buffers = graphicsPipeline->resourceLayout->vertexUniformBufferCount; + graphicsPipeline->header.num_fragment_samplers = graphicsPipeline->resourceLayout->fragmentSamplerCount; + graphicsPipeline->header.num_fragment_storage_buffers = graphicsPipeline->resourceLayout->fragmentStorageBufferCount; + graphicsPipeline->header.num_fragment_storage_textures = graphicsPipeline->resourceLayout->fragmentStorageTextureCount; + graphicsPipeline->header.num_fragment_uniform_buffers = graphicsPipeline->resourceLayout->fragmentUniformBufferCount; + return (SDL_GPUGraphicsPipeline *)graphicsPipeline; } @@ -6614,6 +6681,14 @@ static SDL_GPUComputePipeline *VULKAN_CreateComputePipeline( &nameInfo); } + // Track these here for debug layer + vulkanComputePipeline->header.numSamplers = vulkanComputePipeline->resourceLayout->numSamplers; + vulkanComputePipeline->header.numReadonlyStorageTextures = vulkanComputePipeline->resourceLayout->numReadonlyStorageTextures; + vulkanComputePipeline->header.numReadonlyStorageBuffers = vulkanComputePipeline->resourceLayout->numReadonlyStorageBuffers; + vulkanComputePipeline->header.numReadWriteStorageTextures = vulkanComputePipeline->resourceLayout->numReadWriteStorageTextures; + vulkanComputePipeline->header.numReadWriteStorageBuffers = vulkanComputePipeline->resourceLayout->numReadWriteStorageBuffers; + vulkanComputePipeline->header.numUniformBuffers = vulkanComputePipeline->resourceLayout->numUniformBuffers; + return (SDL_GPUComputePipeline *)vulkanComputePipeline; } @@ -6682,7 +6757,6 @@ static SDL_GPUShader *VULKAN_CreateShader( VkResult vulkanResult; VkShaderModuleCreateInfo vkShaderModuleCreateInfo; VulkanRenderer *renderer = (VulkanRenderer *)driverData; - size_t entryPointNameLength; vulkanShader = SDL_malloc(sizeof(VulkanShader)); vkShaderModuleCreateInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; @@ -6702,10 +6776,11 @@ static SDL_GPUShader *VULKAN_CreateShader( CHECK_VULKAN_ERROR_AND_RETURN(vulkanResult, vkCreateShaderModule, NULL); } - entryPointNameLength = SDL_strlen(createinfo->entrypoint) + 1; - vulkanShader->entrypointName = SDL_malloc(entryPointNameLength); - SDL_utf8strlcpy((char *)vulkanShader->entrypointName, createinfo->entrypoint, entryPointNameLength); - + const char *entrypoint = createinfo->entrypoint; + if (!entrypoint) { + entrypoint = "main"; + } + vulkanShader->entrypointName = SDL_strdup(entrypoint); vulkanShader->stage = createinfo->stage; vulkanShader->numSamplers = createinfo->num_samplers; vulkanShader->numStorageTextures = createinfo->num_storage_textures; @@ -6751,6 +6826,7 @@ static SDL_GPUTexture *VULKAN_CreateTexture( texture = VULKAN_INTERNAL_CreateTexture( renderer, + true, createinfo); if (texture == NULL) { @@ -6762,7 +6838,9 @@ static SDL_GPUTexture *VULKAN_CreateTexture( // Copy properties so we don't lose information when the client destroys them container->header.info = *createinfo; container->header.info.props = SDL_CreateProperties(); - SDL_CopyProperties(createinfo->props, container->header.info.props); + if (createinfo->props) { + SDL_CopyProperties(createinfo->props, container->header.info.props); + } container->canBeCycled = true; container->activeTexture = texture; @@ -6925,7 +7003,7 @@ static void VULKAN_INTERNAL_ReleaseBuffer( renderer->buffersToDestroy[renderer->buffersToDestroyCount] = vulkanBuffer; renderer->buffersToDestroyCount += 1; - vulkanBuffer->markedForDestroy = 1; + vulkanBuffer->markedForDestroy = true; vulkanBuffer->container = NULL; SDL_UnlockMutex(renderer->disposeLock); @@ -7409,21 +7487,21 @@ static void VULKAN_BindVertexSamplers( VulkanTextureContainer *textureContainer = (VulkanTextureContainer *)textureSamplerBindings[i].texture; VulkanSampler *sampler = (VulkanSampler *)textureSamplerBindings[i].sampler; - if (vulkanCommandBuffer->vertexSamplers[firstSlot + i] != sampler) { + if (vulkanCommandBuffer->vertexSamplerBindings[firstSlot + i] != sampler->sampler) { VULKAN_INTERNAL_TrackSampler( vulkanCommandBuffer, (VulkanSampler *)textureSamplerBindings[i].sampler); - vulkanCommandBuffer->vertexSamplers[firstSlot + i] = (VulkanSampler *)textureSamplerBindings[i].sampler; + vulkanCommandBuffer->vertexSamplerBindings[firstSlot + i] = sampler->sampler; vulkanCommandBuffer->needNewVertexResourceDescriptorSet = true; } - if (vulkanCommandBuffer->vertexSamplerTextures[firstSlot + i] != textureContainer->activeTexture) { + if (vulkanCommandBuffer->vertexSamplerTextureViewBindings[firstSlot + i] != textureContainer->activeTexture->fullView) { VULKAN_INTERNAL_TrackTexture( vulkanCommandBuffer, textureContainer->activeTexture); - vulkanCommandBuffer->vertexSamplerTextures[firstSlot + i] = textureContainer->activeTexture; + vulkanCommandBuffer->vertexSamplerTextureViewBindings[firstSlot + i] = textureContainer->activeTexture->fullView; vulkanCommandBuffer->needNewVertexResourceDescriptorSet = true; } } @@ -7440,12 +7518,12 @@ static void VULKAN_BindVertexStorageTextures( for (Uint32 i = 0; i < numBindings; i += 1) { VulkanTextureContainer *textureContainer = (VulkanTextureContainer *)storageTextures[i]; - if (vulkanCommandBuffer->vertexStorageTextures[firstSlot + i] != textureContainer->activeTexture) { + if (vulkanCommandBuffer->vertexStorageTextureViewBindings[firstSlot + i] != textureContainer->activeTexture->fullView) { VULKAN_INTERNAL_TrackTexture( vulkanCommandBuffer, textureContainer->activeTexture); - vulkanCommandBuffer->vertexStorageTextures[firstSlot + i] = textureContainer->activeTexture; + vulkanCommandBuffer->vertexStorageTextureViewBindings[firstSlot + i] = textureContainer->activeTexture->fullView; vulkanCommandBuffer->needNewVertexResourceDescriptorSet = true; } } @@ -7462,12 +7540,12 @@ static void VULKAN_BindVertexStorageBuffers( for (Uint32 i = 0; i < numBindings; i += 1) { VulkanBufferContainer *bufferContainer = (VulkanBufferContainer *)storageBuffers[i]; - if (vulkanCommandBuffer->vertexStorageBuffers[firstSlot + i] != bufferContainer->activeBuffer) { + if (vulkanCommandBuffer->vertexStorageBufferBindings[firstSlot + i] != bufferContainer->activeBuffer->buffer) { VULKAN_INTERNAL_TrackBuffer( vulkanCommandBuffer, bufferContainer->activeBuffer); - vulkanCommandBuffer->vertexStorageBuffers[firstSlot + i] = bufferContainer->activeBuffer; + vulkanCommandBuffer->vertexStorageBufferBindings[firstSlot + i] = bufferContainer->activeBuffer->buffer; vulkanCommandBuffer->needNewVertexResourceDescriptorSet = true; } } @@ -7485,21 +7563,21 @@ static void VULKAN_BindFragmentSamplers( VulkanTextureContainer *textureContainer = (VulkanTextureContainer *)textureSamplerBindings[i].texture; VulkanSampler *sampler = (VulkanSampler *)textureSamplerBindings[i].sampler; - if (vulkanCommandBuffer->fragmentSamplers[firstSlot + i] != sampler) { + if (vulkanCommandBuffer->fragmentSamplerBindings[firstSlot + i] != sampler->sampler) { VULKAN_INTERNAL_TrackSampler( vulkanCommandBuffer, (VulkanSampler *)textureSamplerBindings[i].sampler); - vulkanCommandBuffer->fragmentSamplers[firstSlot + i] = (VulkanSampler *)textureSamplerBindings[i].sampler; + vulkanCommandBuffer->fragmentSamplerBindings[firstSlot + i] = sampler->sampler; vulkanCommandBuffer->needNewFragmentResourceDescriptorSet = true; } - if (vulkanCommandBuffer->fragmentSamplerTextures[firstSlot + i] != textureContainer->activeTexture) { + if (vulkanCommandBuffer->fragmentSamplerTextureViewBindings[firstSlot + i] != textureContainer->activeTexture->fullView) { VULKAN_INTERNAL_TrackTexture( vulkanCommandBuffer, textureContainer->activeTexture); - vulkanCommandBuffer->fragmentSamplerTextures[firstSlot + i] = textureContainer->activeTexture; + vulkanCommandBuffer->fragmentSamplerTextureViewBindings[firstSlot + i] = textureContainer->activeTexture->fullView; vulkanCommandBuffer->needNewFragmentResourceDescriptorSet = true; } } @@ -7516,12 +7594,12 @@ static void VULKAN_BindFragmentStorageTextures( for (Uint32 i = 0; i < numBindings; i += 1) { VulkanTextureContainer *textureContainer = (VulkanTextureContainer *)storageTextures[i]; - if (vulkanCommandBuffer->fragmentStorageTextures[firstSlot + i] != textureContainer->activeTexture) { + if (vulkanCommandBuffer->fragmentStorageTextureViewBindings[firstSlot + i] != textureContainer->activeTexture->fullView) { VULKAN_INTERNAL_TrackTexture( vulkanCommandBuffer, textureContainer->activeTexture); - vulkanCommandBuffer->fragmentStorageTextures[firstSlot + i] = textureContainer->activeTexture; + vulkanCommandBuffer->fragmentStorageTextureViewBindings[firstSlot + i] = textureContainer->activeTexture->fullView; vulkanCommandBuffer->needNewFragmentResourceDescriptorSet = true; } } @@ -7540,12 +7618,12 @@ static void VULKAN_BindFragmentStorageBuffers( for (i = 0; i < numBindings; i += 1) { bufferContainer = (VulkanBufferContainer *)storageBuffers[i]; - if (vulkanCommandBuffer->fragmentStorageBuffers[firstSlot + i] != bufferContainer->activeBuffer) { + if (vulkanCommandBuffer->fragmentStorageBufferBindings[firstSlot + i] != bufferContainer->activeBuffer->buffer) { VULKAN_INTERNAL_TrackBuffer( vulkanCommandBuffer, bufferContainer->activeBuffer); - vulkanCommandBuffer->fragmentStorageBuffers[firstSlot + i] = bufferContainer->activeBuffer; + vulkanCommandBuffer->fragmentStorageBufferBindings[firstSlot + i] = bufferContainer->activeBuffer->buffer; vulkanCommandBuffer->needNewFragmentResourceDescriptorSet = true; } } @@ -7943,11 +8021,11 @@ static void VULKAN_BindVertexBuffers( for (Uint32 i = 0; i < numBindings; i += 1) { VulkanBuffer *buffer = ((VulkanBufferContainer *)bindings[i].buffer)->activeBuffer; - if (vulkanCommandBuffer->vertexBuffers[i] != buffer->buffer || vulkanCommandBuffer->vertexBufferOffsets[i] != bindings[i].offset) { + if (vulkanCommandBuffer->vertexBuffers[firstSlot + i] != buffer->buffer || vulkanCommandBuffer->vertexBufferOffsets[firstSlot + i] != bindings[i].offset) { VULKAN_INTERNAL_TrackBuffer(vulkanCommandBuffer, buffer); - vulkanCommandBuffer->vertexBuffers[i] = buffer->buffer; - vulkanCommandBuffer->vertexBufferOffsets[i] = bindings[i].offset; + vulkanCommandBuffer->vertexBuffers[firstSlot + i] = buffer->buffer; + vulkanCommandBuffer->vertexBufferOffsets[firstSlot + i] = bindings[i].offset; vulkanCommandBuffer->needVertexBufferBind = true; } } @@ -8059,15 +8137,15 @@ static void VULKAN_EndRenderPass( SDL_zeroa(vulkanCommandBuffer->vertexBufferOffsets); vulkanCommandBuffer->vertexBufferCount = 0; - SDL_zeroa(vulkanCommandBuffer->vertexSamplers); - SDL_zeroa(vulkanCommandBuffer->vertexSamplerTextures); - SDL_zeroa(vulkanCommandBuffer->vertexStorageTextures); - SDL_zeroa(vulkanCommandBuffer->vertexStorageBuffers); + SDL_zeroa(vulkanCommandBuffer->vertexSamplerBindings); + SDL_zeroa(vulkanCommandBuffer->vertexSamplerTextureViewBindings); + SDL_zeroa(vulkanCommandBuffer->vertexStorageTextureViewBindings); + SDL_zeroa(vulkanCommandBuffer->vertexStorageBufferBindings); - SDL_zeroa(vulkanCommandBuffer->fragmentSamplers); - SDL_zeroa(vulkanCommandBuffer->fragmentSamplerTextures); - SDL_zeroa(vulkanCommandBuffer->fragmentStorageTextures); - SDL_zeroa(vulkanCommandBuffer->fragmentStorageBuffers); + SDL_zeroa(vulkanCommandBuffer->fragmentSamplerBindings); + SDL_zeroa(vulkanCommandBuffer->fragmentSamplerTextureViewBindings); + SDL_zeroa(vulkanCommandBuffer->fragmentStorageTextureViewBindings); + SDL_zeroa(vulkanCommandBuffer->fragmentStorageBufferBindings); } static void VULKAN_BeginComputePass( @@ -8097,6 +8175,7 @@ static void VULKAN_BeginComputePass( VULKAN_TEXTURE_USAGE_MODE_COMPUTE_STORAGE_READ_WRITE); vulkanCommandBuffer->readWriteComputeStorageTextureSubresources[i] = subresource; + vulkanCommandBuffer->readWriteComputeStorageTextureViewBindings[i] = subresource->computeWriteView; VULKAN_INTERNAL_TrackTexture( vulkanCommandBuffer, @@ -8110,9 +8189,10 @@ static void VULKAN_BeginComputePass( vulkanCommandBuffer, bufferContainer, storageBufferBindings[i].cycle, - VULKAN_BUFFER_USAGE_MODE_COMPUTE_STORAGE_READ); + VULKAN_BUFFER_USAGE_MODE_COMPUTE_STORAGE_READ_WRITE); vulkanCommandBuffer->readWriteComputeStorageBuffers[i] = buffer; + vulkanCommandBuffer->readWriteComputeStorageBufferBindings[i] = buffer->buffer; VULKAN_INTERNAL_TrackBuffer( vulkanCommandBuffer, @@ -8164,21 +8244,21 @@ static void VULKAN_BindComputeSamplers( VulkanTextureContainer *textureContainer = (VulkanTextureContainer *)textureSamplerBindings[i].texture; VulkanSampler *sampler = (VulkanSampler *)textureSamplerBindings[i].sampler; - if (vulkanCommandBuffer->computeSamplers[firstSlot + i] != sampler) { + if (vulkanCommandBuffer->computeSamplerBindings[firstSlot + i] != sampler->sampler) { VULKAN_INTERNAL_TrackSampler( vulkanCommandBuffer, sampler); - vulkanCommandBuffer->computeSamplers[firstSlot + i] = sampler; + vulkanCommandBuffer->computeSamplerBindings[firstSlot + i] = sampler->sampler; vulkanCommandBuffer->needNewComputeReadOnlyDescriptorSet = true; } - if (vulkanCommandBuffer->computeSamplerTextures[firstSlot + i] != textureContainer->activeTexture) { + if (vulkanCommandBuffer->computeSamplerTextureViewBindings[firstSlot + i] != textureContainer->activeTexture->fullView) { VULKAN_INTERNAL_TrackTexture( vulkanCommandBuffer, textureContainer->activeTexture); - vulkanCommandBuffer->computeSamplerTextures[firstSlot + i] = textureContainer->activeTexture; + vulkanCommandBuffer->computeSamplerTextureViewBindings[firstSlot + i] = textureContainer->activeTexture->fullView; vulkanCommandBuffer->needNewComputeReadOnlyDescriptorSet = true; } } @@ -8219,6 +8299,7 @@ static void VULKAN_BindComputeStorageTextures( textureContainer->activeTexture); vulkanCommandBuffer->readOnlyComputeStorageTextures[firstSlot + i] = textureContainer->activeTexture; + vulkanCommandBuffer->readOnlyComputeStorageTextureViewBindings[firstSlot + i] = textureContainer->activeTexture->fullView; vulkanCommandBuffer->needNewComputeReadOnlyDescriptorSet = true; } } @@ -8258,6 +8339,7 @@ static void VULKAN_BindComputeStorageBuffers( bufferContainer->activeBuffer); vulkanCommandBuffer->readOnlyComputeStorageBuffers[firstSlot + i] = bufferContainer->activeBuffer; + vulkanCommandBuffer->readOnlyComputeStorageBufferBindings[firstSlot + i] = bufferContainer->activeBuffer->buffer; vulkanCommandBuffer->needNewComputeReadOnlyDescriptorSet = true; } } @@ -8332,8 +8414,8 @@ static void VULKAN_INTERNAL_BindComputeDescriptorSets( currentWriteDescriptorSet->pTexelBufferView = NULL; currentWriteDescriptorSet->pBufferInfo = NULL; - imageInfos[imageInfoCount].sampler = commandBuffer->computeSamplers[i]->sampler; - imageInfos[imageInfoCount].imageView = commandBuffer->computeSamplerTextures[i]->fullView; + imageInfos[imageInfoCount].sampler = commandBuffer->computeSamplerBindings[i]; + imageInfos[imageInfoCount].imageView = commandBuffer->computeSamplerTextureViewBindings[i]; imageInfos[imageInfoCount].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; currentWriteDescriptorSet->pImageInfo = &imageInfos[imageInfoCount]; @@ -8356,7 +8438,7 @@ static void VULKAN_INTERNAL_BindComputeDescriptorSets( currentWriteDescriptorSet->pBufferInfo = NULL; imageInfos[imageInfoCount].sampler = VK_NULL_HANDLE; - imageInfos[imageInfoCount].imageView = commandBuffer->readOnlyComputeStorageTextures[i]->fullView; + imageInfos[imageInfoCount].imageView = commandBuffer->readOnlyComputeStorageTextureViewBindings[i]; imageInfos[imageInfoCount].imageLayout = VK_IMAGE_LAYOUT_GENERAL; currentWriteDescriptorSet->pImageInfo = &imageInfos[imageInfoCount]; @@ -8378,7 +8460,7 @@ static void VULKAN_INTERNAL_BindComputeDescriptorSets( currentWriteDescriptorSet->pTexelBufferView = NULL; currentWriteDescriptorSet->pImageInfo = NULL; - bufferInfos[bufferInfoCount].buffer = commandBuffer->readOnlyComputeStorageBuffers[i]->buffer; + bufferInfos[bufferInfoCount].buffer = commandBuffer->readOnlyComputeStorageBufferBindings[i]; bufferInfos[bufferInfoCount].offset = 0; bufferInfos[bufferInfoCount].range = VK_WHOLE_SIZE; @@ -8413,7 +8495,7 @@ static void VULKAN_INTERNAL_BindComputeDescriptorSets( currentWriteDescriptorSet->pBufferInfo = NULL; imageInfos[imageInfoCount].sampler = VK_NULL_HANDLE; - imageInfos[imageInfoCount].imageView = commandBuffer->readWriteComputeStorageTextureSubresources[i]->computeWriteView; + imageInfos[imageInfoCount].imageView = commandBuffer->readWriteComputeStorageTextureViewBindings[i]; imageInfos[imageInfoCount].imageLayout = VK_IMAGE_LAYOUT_GENERAL; currentWriteDescriptorSet->pImageInfo = &imageInfos[imageInfoCount]; @@ -8435,7 +8517,7 @@ static void VULKAN_INTERNAL_BindComputeDescriptorSets( currentWriteDescriptorSet->pTexelBufferView = NULL; currentWriteDescriptorSet->pImageInfo = NULL; - bufferInfos[bufferInfoCount].buffer = commandBuffer->readWriteComputeStorageBuffers[i]->buffer; + bufferInfos[bufferInfoCount].buffer = commandBuffer->readWriteComputeStorageBufferBindings[i]; bufferInfos[bufferInfoCount].offset = 0; bufferInfos[bufferInfoCount].range = VK_WHOLE_SIZE; @@ -8602,9 +8684,12 @@ static void VULKAN_EndComputePass( } } - // we don't need a barrier because sampler state is always the default if sampler bit is set - SDL_zeroa(vulkanCommandBuffer->computeSamplerTextures); - SDL_zeroa(vulkanCommandBuffer->computeSamplers); + // we don't need a barrier for sampler resources because sampler state is always the default if sampler bit is set + SDL_zeroa(vulkanCommandBuffer->computeSamplerTextureViewBindings); + SDL_zeroa(vulkanCommandBuffer->computeSamplerBindings); + + SDL_zeroa(vulkanCommandBuffer->readWriteComputeStorageTextureViewBindings); + SDL_zeroa(vulkanCommandBuffer->readWriteComputeStorageBufferBindings); vulkanCommandBuffer->currentComputePipeline = NULL; @@ -9470,21 +9555,23 @@ static SDL_GPUCommandBuffer *VULKAN_AcquireCommandBuffer( SDL_zeroa(commandBuffer->vertexBufferOffsets); commandBuffer->vertexBufferCount = 0; - SDL_zeroa(commandBuffer->vertexSamplerTextures); - SDL_zeroa(commandBuffer->vertexSamplers); - SDL_zeroa(commandBuffer->vertexStorageTextures); - SDL_zeroa(commandBuffer->vertexStorageBuffers); + SDL_zeroa(commandBuffer->vertexSamplerTextureViewBindings); + SDL_zeroa(commandBuffer->vertexSamplerBindings); + SDL_zeroa(commandBuffer->vertexStorageTextureViewBindings); + SDL_zeroa(commandBuffer->vertexStorageBufferBindings); - SDL_zeroa(commandBuffer->fragmentSamplerTextures); - SDL_zeroa(commandBuffer->fragmentSamplers); - SDL_zeroa(commandBuffer->fragmentStorageTextures); - SDL_zeroa(commandBuffer->fragmentStorageBuffers); + SDL_zeroa(commandBuffer->fragmentSamplerTextureViewBindings); + SDL_zeroa(commandBuffer->fragmentSamplerBindings); + SDL_zeroa(commandBuffer->fragmentStorageTextureViewBindings); + SDL_zeroa(commandBuffer->fragmentStorageBufferBindings); SDL_zeroa(commandBuffer->readWriteComputeStorageTextureSubresources); commandBuffer->readWriteComputeStorageTextureSubresourceCount = 0; SDL_zeroa(commandBuffer->readWriteComputeStorageBuffers); - SDL_zeroa(commandBuffer->computeSamplerTextures); - SDL_zeroa(commandBuffer->computeSamplers); + SDL_zeroa(commandBuffer->computeSamplerTextureViewBindings); + SDL_zeroa(commandBuffer->computeSamplerBindings); + SDL_zeroa(commandBuffer->readOnlyComputeStorageTextureViewBindings); + SDL_zeroa(commandBuffer->readOnlyComputeStorageBufferBindings); SDL_zeroa(commandBuffer->readOnlyComputeStorageTextures); SDL_zeroa(commandBuffer->readOnlyComputeStorageBuffers); @@ -9981,7 +10068,7 @@ static bool VULKAN_INTERNAL_AcquireSwapchainTexture( } vulkanCommandBuffer->signalSemaphores[vulkanCommandBuffer->signalSemaphoreCount] = - windowData->renderFinishedSemaphore[windowData->frameCounter]; + windowData->renderFinishedSemaphore[swapchainImageIndex]; vulkanCommandBuffer->signalSemaphoreCount += 1; *swapchainTexture = (SDL_GPUTexture *)swapchainTextureContainer; @@ -10445,7 +10532,9 @@ static bool VULKAN_Submit( Uint32 swapchainImageIndex; VulkanTextureSubresource *swapchainTextureSubresource; VulkanMemorySubAllocator *allocator; - bool presenting = false; + bool performCleanups = + (renderer->claimedWindowCount > 0 && vulkanCommandBuffer->presentDataCount > 0) || + renderer->claimedWindowCount == 0; SDL_LockMutex(renderer->submitLock); @@ -10468,6 +10557,15 @@ static bool VULKAN_Submit( swapchainTextureSubresource); } + if (performCleanups && + renderer->allocationsToDefragCount > 0 && + !renderer->defragInProgress) { + if (!VULKAN_INTERNAL_DefragmentMemory(renderer, vulkanCommandBuffer)) + { + SDL_LogError(SDL_LOG_CATEGORY_GPU, "%s", "Failed to defragment memory, likely OOM!"); + } + } + if (!VULKAN_INTERNAL_EndCommandBuffer(renderer, vulkanCommandBuffer)) { SDL_UnlockMutex(renderer->submitLock); return false; @@ -10505,17 +10603,13 @@ static bool VULKAN_Submit( } // Present, if applicable - bool result = true; - for (Uint32 j = 0; j < vulkanCommandBuffer->presentDataCount; j += 1) { - presenting = true; - presentData = &vulkanCommandBuffer->presentDatas[j]; presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR; presentInfo.pNext = NULL; presentInfo.pWaitSemaphores = - &presentData->windowData->renderFinishedSemaphore[presentData->windowData->frameCounter]; + &presentData->windowData->renderFinishedSemaphore[presentData->swapchainImageIndex]; presentInfo.waitSemaphoreCount = 1; presentInfo.pSwapchains = &presentData->windowData->swapchain; presentInfo.swapchainCount = 1; @@ -10547,60 +10641,50 @@ static bool VULKAN_Submit( (presentData->windowData->frameCounter + 1) % renderer->allowedFramesInFlight; } - // Check if we can perform any cleanups + if (performCleanups) { + for (Sint32 i = renderer->submittedCommandBufferCount - 1; i >= 0; i -= 1) { + vulkanResult = renderer->vkGetFenceStatus( + renderer->logicalDevice, + renderer->submittedCommandBuffers[i]->inFlightFence->fence); - for (Sint32 i = renderer->submittedCommandBufferCount - 1; i >= 0; i -= 1) { - vulkanResult = renderer->vkGetFenceStatus( - renderer->logicalDevice, - renderer->submittedCommandBuffers[i]->inFlightFence->fence); - - if (vulkanResult == VK_SUCCESS) { - VULKAN_INTERNAL_CleanCommandBuffer( - renderer, - renderer->submittedCommandBuffers[i], - false); - } - } - - if (renderer->checkEmptyAllocations) { - SDL_LockMutex(renderer->allocatorLock); - - for (Uint32 i = 0; i < VK_MAX_MEMORY_TYPES; i += 1) { - allocator = &renderer->memoryAllocator->subAllocators[i]; - - for (Sint32 j = allocator->allocationCount - 1; j >= 0; j -= 1) { - if (allocator->allocations[j]->usedRegionCount == 0) { - VULKAN_INTERNAL_DeallocateMemory( - renderer, - allocator, - j); - } + if (vulkanResult == VK_SUCCESS) { + VULKAN_INTERNAL_CleanCommandBuffer( + renderer, + renderer->submittedCommandBuffers[i], + false); } } - renderer->checkEmptyAllocations = false; + if (renderer->checkEmptyAllocations) { + SDL_LockMutex(renderer->allocatorLock); - SDL_UnlockMutex(renderer->allocatorLock); - } + for (Uint32 i = 0; i < VK_MAX_MEMORY_TYPES; i += 1) { + allocator = &renderer->memoryAllocator->subAllocators[i]; - // Check pending destroys - VULKAN_INTERNAL_PerformPendingDestroys(renderer); + for (Sint32 j = allocator->allocationCount - 1; j >= 0; j -= 1) { + if (allocator->allocations[j]->usedRegionCount == 0) { + VULKAN_INTERNAL_DeallocateMemory( + renderer, + allocator, + j); + } + } + } - // Defrag! - if ( - presenting && - renderer->allocationsToDefragCount > 0 && - !renderer->defragInProgress) { - result = VULKAN_INTERNAL_DefragmentMemory(renderer); + renderer->checkEmptyAllocations = false; + + SDL_UnlockMutex(renderer->allocatorLock); + } + + VULKAN_INTERNAL_PerformPendingDestroys(renderer); } // Mark command buffer as submitted - // This must happen after defrag, because it will try to acquire new command buffers. VULKAN_INTERNAL_ReleaseCommandBuffer(vulkanCommandBuffer); SDL_UnlockMutex(renderer->submitLock); - return result; + return true; } static bool VULKAN_Cancel( @@ -10627,43 +10711,28 @@ static bool VULKAN_Cancel( } static bool VULKAN_INTERNAL_DefragmentMemory( - VulkanRenderer *renderer) + VulkanRenderer *renderer, + VulkanCommandBuffer *commandBuffer) { - VulkanMemoryAllocation *allocation; - VulkanMemoryUsedRegion *currentRegion; - VulkanBuffer *newBuffer; - VulkanTexture *newTexture; - VkBufferCopy bufferCopy; - VkImageCopy imageCopy; - VulkanCommandBuffer *commandBuffer; - VulkanTextureSubresource *srcSubresource; - VulkanTextureSubresource *dstSubresource; - Uint32 i, subresourceIndex; - renderer->defragInProgress = 1; - - commandBuffer = (VulkanCommandBuffer *)VULKAN_AcquireCommandBuffer((SDL_GPURenderer *)renderer); - if (commandBuffer == NULL) { - return false; - } commandBuffer->isDefrag = 1; SDL_LockMutex(renderer->allocatorLock); - allocation = renderer->allocationsToDefrag[renderer->allocationsToDefragCount - 1]; + VulkanMemoryAllocation *allocation = renderer->allocationsToDefrag[renderer->allocationsToDefragCount - 1]; renderer->allocationsToDefragCount -= 1; /* For each used region in the allocation * create a new resource, copy the data * and re-point the resource containers */ - for (i = 0; i < allocation->usedRegionCount; i += 1) { - currentRegion = allocation->usedRegions[i]; + for (Uint32 i = 0; i < allocation->usedRegionCount; i += 1) { + VulkanMemoryUsedRegion *currentRegion = allocation->usedRegions[i]; if (currentRegion->isBuffer && !currentRegion->vulkanBuffer->markedForDestroy) { currentRegion->vulkanBuffer->usage |= VK_BUFFER_USAGE_TRANSFER_DST_BIT; - newBuffer = VULKAN_INTERNAL_CreateBuffer( + VulkanBuffer *newBuffer = VULKAN_INTERNAL_CreateBuffer( renderer, currentRegion->vulkanBuffer->size, currentRegion->vulkanBuffer->usage, @@ -10673,6 +10742,7 @@ static bool VULKAN_INTERNAL_DefragmentMemory( if (newBuffer == NULL) { SDL_UnlockMutex(renderer->allocatorLock); + SDL_LogError(SDL_LOG_CATEGORY_GPU, "%s", "Failed to allocate defrag buffer!"); return false; } @@ -10691,6 +10761,7 @@ static bool VULKAN_INTERNAL_DefragmentMemory( VULKAN_BUFFER_USAGE_MODE_COPY_DESTINATION, newBuffer); + VkBufferCopy bufferCopy; bufferCopy.srcOffset = 0; bufferCopy.dstOffset = 0; bufferCopy.size = currentRegion->resourceSize; @@ -10730,20 +10801,22 @@ static bool VULKAN_INTERNAL_DefragmentMemory( VULKAN_INTERNAL_ReleaseBuffer(renderer, currentRegion->vulkanBuffer); } else if (!currentRegion->isBuffer && !currentRegion->vulkanTexture->markedForDestroy) { - newTexture = VULKAN_INTERNAL_CreateTexture( + VulkanTexture *newTexture = VULKAN_INTERNAL_CreateTexture( renderer, + false, ¤tRegion->vulkanTexture->container->header.info); if (newTexture == NULL) { SDL_UnlockMutex(renderer->allocatorLock); + SDL_LogError(SDL_LOG_CATEGORY_GPU, "%s", "Failed to allocate defrag buffer!"); return false; } SDL_GPUTextureCreateInfo info = currentRegion->vulkanTexture->container->header.info; - for (subresourceIndex = 0; subresourceIndex < currentRegion->vulkanTexture->subresourceCount; subresourceIndex += 1) { + for (Uint32 subresourceIndex = 0; subresourceIndex < currentRegion->vulkanTexture->subresourceCount; subresourceIndex += 1) { // copy subresource if necessary - srcSubresource = ¤tRegion->vulkanTexture->subresources[subresourceIndex]; - dstSubresource = &newTexture->subresources[subresourceIndex]; + VulkanTextureSubresource *srcSubresource = ¤tRegion->vulkanTexture->subresources[subresourceIndex]; + VulkanTextureSubresource *dstSubresource = &newTexture->subresources[subresourceIndex]; VULKAN_INTERNAL_TextureSubresourceTransitionFromDefaultUsage( renderer, @@ -10751,12 +10824,14 @@ static bool VULKAN_INTERNAL_DefragmentMemory( VULKAN_TEXTURE_USAGE_MODE_COPY_SOURCE, srcSubresource); - VULKAN_INTERNAL_TextureSubresourceTransitionFromDefaultUsage( + VULKAN_INTERNAL_TextureSubresourceMemoryBarrier( renderer, commandBuffer, + VULKAN_TEXTURE_USAGE_MODE_UNINITIALIZED, VULKAN_TEXTURE_USAGE_MODE_COPY_DESTINATION, dstSubresource); + VkImageCopy imageCopy; imageCopy.srcOffset.x = 0; imageCopy.srcOffset.y = 0; imageCopy.srcOffset.z = 0; @@ -10808,8 +10883,7 @@ static bool VULKAN_INTERNAL_DefragmentMemory( SDL_UnlockMutex(renderer->allocatorLock); - return VULKAN_Submit( - (SDL_GPUCommandBuffer *)commandBuffer); + return true; } // Format Info @@ -11574,7 +11648,7 @@ static bool VULKAN_PrepareDriver(SDL_VideoDevice *_this) { // Set up dummy VulkanRenderer VulkanRenderer *renderer; - Uint8 result; + bool result = false; if (_this->Vulkan_CreateSurface == NULL) { return false; @@ -11584,16 +11658,16 @@ static bool VULKAN_PrepareDriver(SDL_VideoDevice *_this) return false; } - renderer = (VulkanRenderer *)SDL_malloc(sizeof(VulkanRenderer)); - SDL_memset(renderer, '\0', sizeof(VulkanRenderer)); - - result = VULKAN_INTERNAL_PrepareVulkan(renderer); - - if (result) { - renderer->vkDestroyInstance(renderer->instance, NULL); + renderer = (VulkanRenderer *)SDL_calloc(1, sizeof(*renderer)); + if (renderer) { + result = VULKAN_INTERNAL_PrepareVulkan(renderer); + if (result) { + renderer->vkDestroyInstance(renderer->instance, NULL); + } + SDL_free(renderer); } - SDL_free(renderer); SDL_Vulkan_UnloadLibrary(); + return result; } @@ -11609,8 +11683,12 @@ static SDL_GPUDevice *VULKAN_CreateDevice(bool debugMode, bool preferLowPower, S return NULL; } - renderer = (VulkanRenderer *)SDL_malloc(sizeof(VulkanRenderer)); - SDL_memset(renderer, '\0', sizeof(VulkanRenderer)); + renderer = (VulkanRenderer *)SDL_calloc(1, sizeof(*renderer)); + if (!renderer) { + SDL_Vulkan_UnloadLibrary(); + return false; + } + renderer->debugMode = debugMode; renderer->preferLowPower = preferLowPower; renderer->allowedFramesInFlight = 2; @@ -11654,6 +11732,7 @@ static SDL_GPUDevice *VULKAN_CreateDevice(bool debugMode, bool preferLowPower, S ASSIGN_DRIVER(VULKAN) result->driverData = (SDL_GPURenderer *)renderer; + result->shader_formats = SDL_GPU_SHADERFORMAT_SPIRV; /* * Create initial swapchain array @@ -11673,6 +11752,9 @@ static SDL_GPUDevice *VULKAN_CreateDevice(bool debugMode, bool preferLowPower, S renderer->acquireUniformBufferLock = SDL_CreateMutex(); renderer->renderPassFetchLock = SDL_CreateMutex(); renderer->framebufferFetchLock = SDL_CreateMutex(); + renderer->graphicsPipelineLayoutFetchLock = SDL_CreateMutex(); + renderer->computePipelineLayoutFetchLock = SDL_CreateMutex(); + renderer->descriptorSetLayoutFetchLock = SDL_CreateMutex(); renderer->windowLock = SDL_CreateMutex(); /* @@ -11733,7 +11815,7 @@ static SDL_GPUDevice *VULKAN_CreateDevice(bool debugMode, bool preferLowPower, S renderer->renderPassHashTable = SDL_CreateHashTable( 0, // !!! FIXME: a real guess here, for a _minimum_ if not a maximum, could be useful. - false, // manually synchronized due to timing + false, // manually synchronized due to lookup timing VULKAN_INTERNAL_RenderPassHashFunction, VULKAN_INTERNAL_RenderPassHashKeyMatch, VULKAN_INTERNAL_RenderPassHashDestroy, @@ -11749,7 +11831,7 @@ static SDL_GPUDevice *VULKAN_CreateDevice(bool debugMode, bool preferLowPower, S renderer->graphicsPipelineResourceLayoutHashTable = SDL_CreateHashTable( 0, // !!! FIXME: a real guess here, for a _minimum_ if not a maximum, could be useful. - true, // thread-safe + false, // manually synchronized due to lookup timing VULKAN_INTERNAL_GraphicsPipelineResourceLayoutHashFunction, VULKAN_INTERNAL_GraphicsPipelineResourceLayoutHashKeyMatch, VULKAN_INTERNAL_GraphicsPipelineResourceLayoutHashDestroy, @@ -11757,7 +11839,7 @@ static SDL_GPUDevice *VULKAN_CreateDevice(bool debugMode, bool preferLowPower, S renderer->computePipelineResourceLayoutHashTable = SDL_CreateHashTable( 0, // !!! FIXME: a real guess here, for a _minimum_ if not a maximum, could be useful. - true, // thread-safe + false, // manually synchronized due to lookup timing VULKAN_INTERNAL_ComputePipelineResourceLayoutHashFunction, VULKAN_INTERNAL_ComputePipelineResourceLayoutHashKeyMatch, VULKAN_INTERNAL_ComputePipelineResourceLayoutHashDestroy, @@ -11765,7 +11847,7 @@ static SDL_GPUDevice *VULKAN_CreateDevice(bool debugMode, bool preferLowPower, S renderer->descriptorSetLayoutHashTable = SDL_CreateHashTable( 0, // !!! FIXME: a real guess here, for a _minimum_ if not a maximum, could be useful. - true, // thread-safe + false, // manually synchronized due to lookup timing VULKAN_INTERNAL_DescriptorSetLayoutHashFunction, VULKAN_INTERNAL_DescriptorSetLayoutHashKeyMatch, VULKAN_INTERNAL_DescriptorSetLayoutHashDestroy, diff --git a/lib/sdl3/SDL/src/hidapi/SDL_hidapi.c b/lib/sdl3/SDL/src/hidapi/SDL_hidapi.c index b14b75e..2378db6 100644 --- a/lib/sdl3/SDL/src/hidapi/SDL_hidapi.c +++ b/lib/sdl3/SDL/src/hidapi/SDL_hidapi.c @@ -807,6 +807,8 @@ typedef struct LIBUSB_hid_device_ LIBUSB_hid_device; #define hid_send_feature_report LIBUSB_hid_send_feature_report #define hid_set_nonblocking LIBUSB_hid_set_nonblocking #define hid_write LIBUSB_hid_write +#define hid_version LIBUSB_hid_version +#define hid_version_str LIBUSB_hid_version_str #define input_report LIBUSB_input_report #define make_path LIBUSB_make_path #define new_hid_device LIBUSB_new_hid_device diff --git a/lib/sdl3/SDL/src/hidapi/SDL_hidapi_windows.h b/lib/sdl3/SDL/src/hidapi/SDL_hidapi_windows.h index c29122b..91f71c2 100644 --- a/lib/sdl3/SDL/src/hidapi/SDL_hidapi_windows.h +++ b/lib/sdl3/SDL/src/hidapi/SDL_hidapi_windows.h @@ -62,6 +62,10 @@ #define wcsstr SDL_wcsstr #define wcstol SDL_wcstol +// These functions conflict when linking both SDL and hidapi statically +#define hid_winapi_descriptor_reconstruct_pp_data SDL_hid_winapi_descriptor_reconstruct_pp_data +#define hid_winapi_get_container_id SDL_hid_winapi_get_container_id + #undef HIDAPI_H__ #include "windows/hid.c" #define HAVE_PLATFORM_BACKEND 1 diff --git a/lib/sdl3/SDL/src/hidapi/libusb/hid.c b/lib/sdl3/SDL/src/hidapi/libusb/hid.c index f4b1ccb..c911f7e 100644 --- a/lib/sdl3/SDL/src/hidapi/libusb/hid.c +++ b/lib/sdl3/SDL/src/hidapi/libusb/hid.c @@ -1238,6 +1238,7 @@ static void init_xbox360(libusb_device_handle *device_handle, unsigned short idV (void)conf_desc; if ((idVendor == 0x05ac && idProduct == 0x055b) /* Gamesir-G3w */ || + (idVendor == 0x20d6 && idProduct == 0x4010) /* PowerA Battle Dragon Advanced Wireless Controller */ || idVendor == 0x0f0d /* Hori Xbox controllers */) { unsigned char data[20]; diff --git a/lib/sdl3/SDL/src/joystick/SDL_gamepad.c b/lib/sdl3/SDL/src/joystick/SDL_gamepad.c index 9e8659d..385e890 100644 --- a/lib/sdl3/SDL/src/joystick/SDL_gamepad.c +++ b/lib/sdl3/SDL/src/joystick/SDL_gamepad.c @@ -775,13 +775,7 @@ static GamepadMapping_t *SDL_CreateMappingForHIDAPIGamepad(SDL_GUID guid) // All other gamepads have the standard set of 19 buttons and 6 axes SDL_strlcat(mapping_string, "a:b0,b:b1,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,", sizeof(mapping_string)); - if (SDL_IsJoystickXboxSeriesX(vendor, product)) { - // XBox Series X Controllers have a share button under the guide button - SDL_strlcat(mapping_string, "misc1:b11,", sizeof(mapping_string)); - } else if (SDL_IsJoystickXboxOneElite(vendor, product)) { - // XBox One Elite Controllers have 4 back paddle buttons - SDL_strlcat(mapping_string, "paddle1:b11,paddle2:b13,paddle3:b12,paddle4:b14,", sizeof(mapping_string)); - } else if (SDL_IsJoystickSteamController(vendor, product)) { + if (SDL_IsJoystickSteamController(vendor, product)) { // Steam controllers have 2 back paddle buttons SDL_strlcat(mapping_string, "paddle1:b12,paddle2:b11,", sizeof(mapping_string)); } else if (SDL_IsJoystickNintendoSwitchPro(vendor, product) || @@ -822,6 +816,15 @@ static GamepadMapping_t *SDL_CreateMappingForHIDAPIGamepad(SDL_GUID guid) SDL_strlcat(mapping_string, "paddle1:b16,paddle2:b15,paddle3:b14,paddle4:b13,", sizeof(mapping_string)); } break; + case SDL_GAMEPAD_TYPE_XBOXONE: + if (SDL_IsJoystickXboxOneElite(vendor, product)) { + // XBox One Elite Controllers have 4 back paddle buttons + SDL_strlcat(mapping_string, "paddle1:b11,paddle2:b13,paddle3:b12,paddle4:b14,", sizeof(mapping_string)); + } else if (SDL_IsJoystickXboxSeriesX(vendor, product)) { + // XBox Series X Controllers have a share button under the guide button + SDL_strlcat(mapping_string, "misc1:b11,", sizeof(mapping_string)); + } + break; default: if (vendor == 0 && product == 0) { // This is a Bluetooth Nintendo Switch Pro controller @@ -2751,6 +2754,7 @@ SDL_Gamepad *SDL_OpenGamepad(SDL_JoystickID instance_id) gamepad->joystick = SDL_OpenJoystick(instance_id); if (!gamepad->joystick) { + SDL_SetObjectValid(gamepad, SDL_OBJECT_TYPE_GAMEPAD, false); SDL_free(gamepad); SDL_UnlockJoysticks(); return NULL; @@ -2759,6 +2763,7 @@ SDL_Gamepad *SDL_OpenGamepad(SDL_JoystickID instance_id) if (gamepad->joystick->naxes) { gamepad->last_match_axis = (SDL_GamepadBinding **)SDL_calloc(gamepad->joystick->naxes, sizeof(*gamepad->last_match_axis)); if (!gamepad->last_match_axis) { + SDL_SetObjectValid(gamepad, SDL_OBJECT_TYPE_GAMEPAD, false); SDL_CloseJoystick(gamepad->joystick); SDL_free(gamepad); SDL_UnlockJoysticks(); @@ -2768,6 +2773,7 @@ SDL_Gamepad *SDL_OpenGamepad(SDL_JoystickID instance_id) if (gamepad->joystick->nhats) { gamepad->last_hat_mask = (Uint8 *)SDL_calloc(gamepad->joystick->nhats, sizeof(*gamepad->last_hat_mask)); if (!gamepad->last_hat_mask) { + SDL_SetObjectValid(gamepad, SDL_OBJECT_TYPE_GAMEPAD, false); SDL_CloseJoystick(gamepad->joystick); SDL_free(gamepad->last_match_axis); SDL_free(gamepad); diff --git a/lib/sdl3/SDL/src/joystick/SDL_gamepad_db.h b/lib/sdl3/SDL/src/joystick/SDL_gamepad_db.h index 64e2dd7..a0f8ea8 100644 --- a/lib/sdl3/SDL/src/joystick/SDL_gamepad_db.h +++ b/lib/sdl3/SDL/src/joystick/SDL_gamepad_db.h @@ -215,7 +215,7 @@ static const char *s_GamepadMappings[] = { "03000000362800000100000000000000,OUYA Game Controller,a:b0,b:b3,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,guide:b14,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:b13,rightx:a3,righty:a4,x:b1,y:b2,", "03000000782300000a10000000000000,Onlive Wireless Controller,a:b15,b:b14,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b5,leftshoulder:b11,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a3,righty:a4,start:b6,x:b13,y:b12,", "030000006b14000001a1000000000000,Orange Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b2,y:b3,", - "0300000009120000072f000000000000,OrangeFox86 DreamPicoPort,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:-a2,leftx:a0,lefty:a1,righttrigger:-a5,start:b11,x:b3,y:b4,", + "0300000009120000072f000000000000,OrangeFox86 DreamPicoPort,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:-a2,leftx:a0,lefty:a1,rightx:a3,righty:a4,righttrigger:-a5,start:b11,x:b3,y:b4,", "03000000120c0000f60e000000000000,P4 Wired Gamepad,a:b1,b:b2,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b5,lefttrigger:b7,rightshoulder:b4,righttrigger:b6,start:b9,x:b0,y:b3,", "030000006f0e00000901000000000000,PDP Versus Fighting Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,", "03000000632500002306000000000000,PS Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,", @@ -421,7 +421,7 @@ static const char *s_GamepadMappings[] = { "030000004b120000014d000000010000,NYKO AIRFLO EX,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b2,y:b3,", "030000007e0500000920000000000000,Nintendo Switch Pro Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,", "050000007e05000009200000ff070000,Nintendo Switch Pro Controller,a:b1,b:b0,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b10,x:b3,y:b2,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", - "0300000009120000072f000000010000,OrangeFox86 DreamPicoPort,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a2,leftx:a0,lefty:a1,righttrigger:a5,start:b11,x:b3,y:b4,", + "0300000009120000072f000000010000,OrangeFox86 DreamPicoPort,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a2,leftx:a0,lefty:a1,rightx:a3,righty:a4,righttrigger:a5,start:b11,x:b3,y:b4,", "030000006f0e00000901000002010000,PDP Versus Fighting Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,", "030000004c0500006802000000000000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,", "030000004c0500006802000000010000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,", @@ -553,6 +553,7 @@ static const char *s_GamepadMappings[] = { "03000000341a000005f7000010010000,GameCube {HuiJia USB box},a:b1,b:b2,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b0,y:b3,", "03000000bc2000000055000011010000,GameSir G3w,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,", "0500000049190000020400001b010000,GameSir T4 Pro,crc:8283,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b23,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,", + "03000000373500009710000001020000,GameSir-K1 FLUX,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b15,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,", "03000000ac0500001a06000011010000,GameSir-T3 2.02,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b15,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,", "0500000047532047616d657061640000,GameStop Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,", "03000000c01100000140000011010000,GameStop PS4 Fun Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,", @@ -867,7 +868,9 @@ static const char *s_GamepadMappings[] = { "05000000ac05000001000000ff076d01,*,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b10,x:b2,y:b3,", "05000000ac050000020000004f066d02,*,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b6,leftshoulder:b4,rightshoulder:b5,x:b2,y:b3,", "05000000ac05000004000000a8986d04,8BitDo Micro gamepad,a:b1,b:b0,back:b4,dpdown:b7,dpleft:b8,dpright:b9,dpup:b10,guide:b2,leftshoulder:b11,lefttrigger:b12,rightshoulder:b13,righttrigger:b14,start:b3,x:b6,y:b5,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "05000000ac05000004000000fd216d04,8BitDo Pro 2,crc:ac95,a:b3,b:b2,back:b6,dpdown:b9,dpleft:b10,dpright:b11,dpup:b12,guide:b4,leftshoulder:b13,leftstick:b14,lefttrigger:+a2,leftx:a0,lefty:a1~,paddle1:b1,paddle2:b0,rightshoulder:b16,rightstick:b17,righttrigger:+a5,rightx:a3,righty:a4~,start:b5,x:b8,y:b7,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", "05000000ac050000040000003b8a6d04,8BitDo SN30 Pro+,crc:3e00,a:b1,b:b0,back:b4,dpdown:b7,dpleft:b8,dpright:b9,dpup:b10,guide:b2,leftshoulder:b11,leftstick:b12,lefttrigger:b13,leftx:a0,lefty:a1~,rightshoulder:b14,rightstick:b15,righttrigger:b16,rightx:a2,righty:a3~,start:b3,x:b6,y:b5,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "05000000ac05000004000000209f6d04,8Bitdo SN30 Pro,crc:40d6,a:b1,b:b0,back:b4,dpdown:b7,dpleft:b8,dpright:b9,dpup:b10,guide:b2,leftshoulder:b11,leftstick:b12,lefttrigger:b13,leftx:a0,lefty:a1~,rightshoulder:b14,rightstick:b15,righttrigger:b16,rightx:a2,righty:a3~,start:b3,x:b6,y:b5,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", "050000008a35000003010000ff070000,Backbone One,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b10,x:b2,y:b3,", "050000008a35000004010000ff070000,Backbone One,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b10,x:b2,y:b3,", "050000007e050000062000000f060000,Nintendo Switch Joy-Con (L),+leftx:h0.2,+lefty:h0.4,-leftx:h0.8,-lefty:h0.1,a:b0,b:b2,leftshoulder:b4,rightshoulder:b5,x:b1,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", @@ -904,7 +907,7 @@ static const char *s_GamepadMappings[] = { "0000000050535669746120436f6e7400,PSVita Controller,crc:d598,a:b2,b:b1,back:b10,dpdown:b6,dpleft:b7,dpright:b9,dpup:b8,leftshoulder:b4,leftstick:b14,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b15,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b3,y:b0,", #endif #ifdef SDL_JOYSTICK_N3DS - "000000004e696e74656e646f20334400,Nintendo 3DS,crc:3210,a:b0,b:b1,back:b2,dpdown:b7,dpleft:b5,dpright:b4,dpup:b6,leftshoulder:b9,lefttrigger:b14,leftx:a0,lefty:a1,rightshoulder:b8,righttrigger:b15,rightx:a2,righty:a3,start:b3,x:b10,y:b11,", + "000000004e696e74656e646f20334400,Nintendo 3DS,crc:3210,a:b1,b:b0,back:b2,dpdown:b7,dpleft:b5,dpright:b4,dpup:b6,leftshoulder:b9,lefttrigger:b14,leftx:a0,lefty:a1,rightshoulder:b8,righttrigger:b15,rightx:a2,righty:a3,start:b3,x:b11,y:b10,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", #endif NULL }; diff --git a/lib/sdl3/SDL/src/joystick/SDL_joystick.c b/lib/sdl3/SDL/src/joystick/SDL_joystick.c index 78c64b7..9215768 100644 --- a/lib/sdl3/SDL/src/joystick/SDL_joystick.c +++ b/lib/sdl3/SDL/src/joystick/SDL_joystick.c @@ -277,6 +277,7 @@ static Uint32 initial_blacklist_devices[] = { MAKE_VIDPID(0x1532, 0x0282), // Razer Huntsman Mini Analog, non-functional DInput device MAKE_VIDPID(0x26ce, 0x01a2), // ASRock LED Controller MAKE_VIDPID(0x20d6, 0x0002), // PowerA Enhanced Wireless Controller for Nintendo Switch (charging port only) + MAKE_VIDPID(0x3434, 0x0211), // Keychron K1 Pro System Control }; static SDL_vidpid_list blacklist_devices = { SDL_HINT_JOYSTICK_BLACKLIST_DEVICES, 0, 0, NULL, @@ -289,7 +290,17 @@ static Uint32 initial_flightstick_devices[] = { MAKE_VIDPID(0x044f, 0x0402), // HOTAS Warthog Joystick MAKE_VIDPID(0x044f, 0xb10a), // ThrustMaster, Inc. T.16000M Joystick MAKE_VIDPID(0x046d, 0xc215), // Logitech Extreme 3D + MAKE_VIDPID(0x0583, 0x6258), // Padix USB joystick with viewfinder + MAKE_VIDPID(0x0583, 0x688f), // Padix QF-688uv Windstorm Pro + MAKE_VIDPID(0x0583, 0x7070), // Padix QF-707u Bazooka + MAKE_VIDPID(0x0583, 0xa019), // Padix USB vibration joystick with viewfinder + MAKE_VIDPID(0x0583, 0xa131), // Padix USB Wireless 2.4GHz + MAKE_VIDPID(0x0583, 0xa209), // Padix MetalStrike ForceFeedback + MAKE_VIDPID(0x0583, 0xb010), // Padix MetalStrike Pro + MAKE_VIDPID(0x0583, 0xb012), // Padix Wireless MetalStrike + MAKE_VIDPID(0x0583, 0xb013), // Padix USB Wireless 2.4GHZ MAKE_VIDPID(0x0738, 0x2221), // Saitek Pro Flight X-56 Rhino Stick + MAKE_VIDPID(0x10f5, 0x7084), // Turtle Beach VelocityOne MAKE_VIDPID(0x231d, 0x0126), // Gunfighter Mk.III 'Space Combat Edition' (right) MAKE_VIDPID(0x231d, 0x0127), // Gunfighter Mk.III 'Space Combat Edition' (left) MAKE_VIDPID(0x362c, 0x0001), // Yawman Arrow @@ -331,6 +342,7 @@ static SDL_vidpid_list rog_gamepad_mice = { static Uint32 initial_throttle_devices[] = { MAKE_VIDPID(0x044f, 0x0404), // HOTAS Warthog Throttle MAKE_VIDPID(0x0738, 0xa221), // Saitek Pro Flight X-56 Rhino Throttle + MAKE_VIDPID(0x10f5, 0x7085), // Turtle Beach VelocityOne Throttle }; static SDL_vidpid_list throttle_devices = { SDL_HINT_JOYSTICK_THROTTLE_DEVICES, 0, 0, NULL, @@ -374,6 +386,14 @@ static Uint32 initial_wheel_devices[] = { MAKE_VIDPID(0x046d, 0xca03), // Logitech Momo Racing MAKE_VIDPID(0x0483, 0x0522), // Simagic Wheelbase (including M10, Alpha Mini, Alpha, Alpha U) MAKE_VIDPID(0x0483, 0xa355), // VRS DirectForce Pro Wheel Base + MAKE_VIDPID(0x0583, 0xa132), // Padix USB Wireless 2.4GHz Wheelpad + MAKE_VIDPID(0x0583, 0xa133), // Padix USB Wireless 2.4GHz Wheel + MAKE_VIDPID(0x0583, 0xa202), // Padix Force Feedback Wheel + MAKE_VIDPID(0x0583, 0xb002), // Padix Vibration USB Wheel + MAKE_VIDPID(0x0583, 0xb005), // Padix USB Wheel + MAKE_VIDPID(0x0583, 0xb008), // Padix USB Wireless 2.4GHz Wheel + MAKE_VIDPID(0x0583, 0xb009), // Padix USB Wheel + MAKE_VIDPID(0x0583, 0xb018), // Padix TW6 Wheel MAKE_VIDPID(0x0eb7, 0x0001), // Fanatec ClubSport Wheel Base V2 MAKE_VIDPID(0x0eb7, 0x0004), // Fanatec ClubSport Wheel Base V2.5 MAKE_VIDPID(0x0eb7, 0x0005), // Fanatec CSL Elite Wheel Base+ (PS4) @@ -1122,7 +1142,11 @@ SDL_Joystick *SDL_OpenJoystick(SDL_JoystickID instance_id) joystick->attached = true; joystick->led_expiration = SDL_GetTicks(); joystick->battery_percent = -1; +#ifdef SDL_JOYSTICK_VIRTUAL joystick->is_virtual = (driver == &SDL_VIRTUAL_JoystickDriver); +#else + joystick->is_virtual = false; +#endif if (!driver->Open(joystick, device_index)) { SDL_SetObjectValid(joystick, SDL_OBJECT_TYPE_JOYSTICK, false); @@ -1166,9 +1190,35 @@ SDL_Joystick *SDL_OpenJoystick(SDL_JoystickID instance_id) // If this joystick is known to have all zero centered axes, skip the auto-centering code if (SDL_JoystickAxesCenteredAtZero(joystick)) { - int i; + for (int i = 0; i < joystick->naxes; ++i) { + joystick->axes[i].has_initial_value = true; + } + } - for (i = 0; i < joystick->naxes; ++i) { + // We know the initial values for HIDAPI and XInput joysticks + if ((SDL_IsJoystickHIDAPI(joystick->guid) || + SDL_IsJoystickXInput(joystick->guid) || + SDL_IsJoystickRAWINPUT(joystick->guid) || + SDL_IsJoystickWGI(joystick->guid)) && + joystick->naxes >= SDL_GAMEPAD_AXIS_COUNT) { + int left_trigger, right_trigger; + if (SDL_IsJoystickXInput(joystick->guid)) { + left_trigger = 2; + right_trigger = 5; + } else { + left_trigger = SDL_GAMEPAD_AXIS_LEFT_TRIGGER; + right_trigger = SDL_GAMEPAD_AXIS_RIGHT_TRIGGER; + } + for (int i = 0; i < SDL_GAMEPAD_AXIS_COUNT; ++i) { + int initial_value; + if (i == left_trigger || i == right_trigger) { + initial_value = SDL_MIN_SINT16; + } else { + initial_value = 0; + } + joystick->axes[i].value = initial_value; + joystick->axes[i].zero = initial_value; + joystick->axes[i].initial_value = initial_value; joystick->axes[i].has_initial_value = true; } } @@ -1814,6 +1864,14 @@ bool SDL_RumbleJoystickTriggers(SDL_Joystick *joystick, Uint16 left_rumble, Uint result = true; } else { result = joystick->driver->RumbleTriggers(joystick, left_rumble, right_rumble); + if (result) { + joystick->trigger_rumble_resend = SDL_GetTicks() + SDL_RUMBLE_RESEND_MS; + if (joystick->trigger_rumble_resend == 0) { + joystick->trigger_rumble_resend = 1; + } + } else { + joystick->trigger_rumble_resend = 0; + } } if (result) { @@ -1824,6 +1882,7 @@ bool SDL_RumbleJoystickTriggers(SDL_Joystick *joystick, Uint16 left_rumble, Uint joystick->trigger_rumble_expiration = SDL_GetTicks() + SDL_min(duration_ms, SDL_MAX_RUMBLE_DURATION_MS); } else { joystick->trigger_rumble_expiration = 0; + joystick->trigger_rumble_resend = 0; } } } @@ -2478,6 +2537,15 @@ void SDL_UpdateJoysticks(void) if (joystick->trigger_rumble_expiration && now >= joystick->trigger_rumble_expiration) { SDL_RumbleJoystickTriggers(joystick, 0, 0, 0); + joystick->trigger_rumble_resend = 0; + } + + if (joystick->trigger_rumble_resend && now >= joystick->trigger_rumble_resend) { + joystick->driver->RumbleTriggers(joystick, joystick->left_trigger_rumble, joystick->right_trigger_rumble); + joystick->trigger_rumble_resend = now + SDL_RUMBLE_RESEND_MS; + if (joystick->trigger_rumble_resend == 0) { + joystick->trigger_rumble_resend = 1; + } } } @@ -2858,7 +2926,8 @@ bool SDL_IsJoystickXboxSeriesX(Uint16 vendor_id, Uint16 product_id) } if (vendor_id == USB_VENDOR_HORI) { if (product_id == USB_PRODUCT_HORI_FIGHTING_COMMANDER_OCTA_SERIES_X || - product_id == USB_PRODUCT_HORI_HORIPAD_PRO_SERIES_X) { + product_id == USB_PRODUCT_HORI_HORIPAD_PRO_SERIES_X || + product_id == USB_PRODUCT_HORI_TAIKO_DRUM_CONTROLLER) { return true; } } diff --git a/lib/sdl3/SDL/src/joystick/SDL_sysjoystick.h b/lib/sdl3/SDL/src/joystick/SDL_sysjoystick.h index f8f2d1a..041ebc3 100644 --- a/lib/sdl3/SDL/src/joystick/SDL_sysjoystick.h +++ b/lib/sdl3/SDL/src/joystick/SDL_sysjoystick.h @@ -113,6 +113,7 @@ struct SDL_Joystick Uint16 left_trigger_rumble _guarded; Uint16 right_trigger_rumble _guarded; Uint64 trigger_rumble_expiration _guarded; + Uint64 trigger_rumble_resend _guarded; Uint8 led_red _guarded; Uint8 led_green _guarded; diff --git a/lib/sdl3/SDL/src/joystick/hidapi/SDL_hidapijoystick.c b/lib/sdl3/SDL/src/joystick/hidapi/SDL_hidapijoystick.c index 6293519..c7607ae 100644 --- a/lib/sdl3/SDL/src/joystick/hidapi/SDL_hidapijoystick.c +++ b/lib/sdl3/SDL/src/joystick/hidapi/SDL_hidapijoystick.c @@ -751,11 +751,12 @@ bool HIDAPI_JoystickConnected(SDL_HIDAPI_Device *device, SDL_JoystickID *pJoysti ++SDL_HIDAPI_numjoysticks; - SDL_PrivateJoystickAdded(joystickID); - if (pJoystickID) { *pJoystickID = joystickID; } + + SDL_PrivateJoystickAdded(joystickID); + return true; } @@ -1051,6 +1052,11 @@ static bool HIDAPI_CreateCombinedJoyCons(void) info.usage = USB_USAGE_GENERIC_GAMEPAD; info.manufacturer_string = L"Nintendo"; info.product_string = L"Switch Joy-Con (L/R)"; + if (children[0]->is_bluetooth || children[1]->is_bluetooth) { + info.bus_type = SDL_HID_API_BUS_BLUETOOTH; + } else { + info.bus_type = SDL_HID_API_BUS_USB; + } combined = HIDAPI_AddDevice(&info, 2, children); if (combined && combined->driver) { diff --git a/lib/sdl3/SDL/src/joystick/usb_ids.h b/lib/sdl3/SDL/src/joystick/usb_ids.h index 794beb8..15c1bb7 100644 --- a/lib/sdl3/SDL/src/joystick/usb_ids.h +++ b/lib/sdl3/SDL/src/joystick/usb_ids.h @@ -76,6 +76,7 @@ #define USB_PRODUCT_HORI_FIGHTING_STICK_ALPHA_PS5 0x0184 #define USB_PRODUCT_HORI_STEAM_CONTROLLER 0x01AB #define USB_PRODUCT_HORI_STEAM_CONTROLLER_BT 0x0196 +#define USB_PRODUCT_HORI_TAIKO_DRUM_CONTROLLER 0x01b2 #define USB_PRODUCT_LOGITECH_F310 0xc216 #define USB_PRODUCT_LOGITECH_CHILLSTREAM 0xcad1 #define USB_PRODUCT_MADCATZ_SAITEK_SIDE_PANEL_CONTROL_DECK 0x2218 diff --git a/lib/sdl3/SDL/src/joystick/windows/SDL_rawinputjoystick.c b/lib/sdl3/SDL/src/joystick/windows/SDL_rawinputjoystick.c index 3e2b270..8590d9a 100644 --- a/lib/sdl3/SDL/src/joystick/windows/SDL_rawinputjoystick.c +++ b/lib/sdl3/SDL/src/joystick/windows/SDL_rawinputjoystick.c @@ -158,6 +158,7 @@ struct joystick_hwdata Uint8 wgi_correlation_count; Uint8 wgi_uncorrelate_count; WindowsGamingInputGamepadState *wgi_slot; + struct __x_ABI_CWindows_CGaming_CInput_CGamepadVibration vibration; #endif bool triggers_rumbling; @@ -449,7 +450,6 @@ typedef struct WindowsGamingInputGamepadState bool used; // Is currently mapped to an SDL device bool connected; // Just used during update to track disconnected Uint8 correlation_id; - struct __x_ABI_CWindows_CGaming_CInput_CGamepadVibration vibration; } WindowsGamingInputGamepadState; static struct @@ -1030,7 +1030,7 @@ static bool RAWINPUT_JoystickInit(void) { SDL_assert(!SDL_RAWINPUT_inited); - if (!SDL_GetHintBoolean(SDL_HINT_JOYSTICK_RAWINPUT, true)) { + if (!SDL_GetHintBoolean(SDL_HINT_JOYSTICK_RAWINPUT, false)) { return true; } @@ -1482,12 +1482,11 @@ static bool RAWINPUT_JoystickRumble(SDL_Joystick *joystick, Uint16 low_frequency #ifdef SDL_JOYSTICK_RAWINPUT_WGI // Save off the motor state in case trigger rumble is started - WindowsGamingInputGamepadState *gamepad_state = ctx->wgi_slot; - HRESULT hr; - gamepad_state->vibration.LeftMotor = (DOUBLE)low_frequency_rumble / SDL_MAX_UINT16; - gamepad_state->vibration.RightMotor = (DOUBLE)high_frequency_rumble / SDL_MAX_UINT16; + ctx->vibration.LeftMotor = (DOUBLE)low_frequency_rumble / SDL_MAX_UINT16; + ctx->vibration.RightMotor = (DOUBLE)high_frequency_rumble / SDL_MAX_UINT16; if (!rumbled && ctx->wgi_correlated) { - hr = __x_ABI_CWindows_CGaming_CInput_CIGamepad_put_Vibration(gamepad_state->gamepad, gamepad_state->vibration); + WindowsGamingInputGamepadState *gamepad_state = ctx->wgi_slot; + HRESULT hr = __x_ABI_CWindows_CGaming_CInput_CIGamepad_put_Vibration(gamepad_state->gamepad, ctx->vibration); if (SUCCEEDED(hr)) { rumbled = true; } @@ -1509,12 +1508,11 @@ static bool RAWINPUT_JoystickRumbleTriggers(SDL_Joystick *joystick, Uint16 left_ #ifdef SDL_JOYSTICK_RAWINPUT_WGI RAWINPUT_DeviceContext *ctx = joystick->hwdata; + ctx->vibration.LeftTrigger = (DOUBLE)left_rumble / SDL_MAX_UINT16; + ctx->vibration.RightTrigger = (DOUBLE)right_rumble / SDL_MAX_UINT16; if (ctx->wgi_correlated) { WindowsGamingInputGamepadState *gamepad_state = ctx->wgi_slot; - HRESULT hr; - gamepad_state->vibration.LeftTrigger = (DOUBLE)left_rumble / SDL_MAX_UINT16; - gamepad_state->vibration.RightTrigger = (DOUBLE)right_rumble / SDL_MAX_UINT16; - hr = __x_ABI_CWindows_CGaming_CInput_CIGamepad_put_Vibration(gamepad_state->gamepad, gamepad_state->vibration); + HRESULT hr = __x_ABI_CWindows_CGaming_CInput_CIGamepad_put_Vibration(gamepad_state->gamepad, ctx->vibration); if (!SUCCEEDED(hr)) { return SDL_SetError("Setting vibration failed: 0x%lx", hr); } diff --git a/lib/sdl3/SDL/src/process/windows/SDL_windowsprocess.c b/lib/sdl3/SDL/src/process/windows/SDL_windowsprocess.c index c1aee5c..221d36d 100644 --- a/lib/sdl3/SDL/src/process/windows/SDL_windowsprocess.c +++ b/lib/sdl3/SDL/src/process/windows/SDL_windowsprocess.c @@ -304,6 +304,7 @@ bool SDL_SYS_CreateProcessWithProperties(SDL_Process *process, SDL_PropertiesID if (stderr_option == SDL_PROCESS_STDIO_INHERITED) { stderr_option = SDL_PROCESS_STDIO_NULL; } + creation_flags |= CREATE_NO_WINDOW; } switch (stdin_option) { @@ -329,7 +330,7 @@ bool SDL_SYS_CreateProcessWithProperties(SDL_Process *process, SDL_PropertiesID startup_info.hStdInput = stdin_pipe[READ_END]; break; case SDL_PROCESS_STDIO_NULL: - startup_info.hStdInput = CreateFile(TEXT("\\\\.\\NUL"), GENERIC_ALL, 0, &security_attributes, OPEN_EXISTING, 0, NULL); + startup_info.hStdInput = CreateFile(TEXT("\\\\.\\NUL"), (GENERIC_READ | GENERIC_WRITE), 0, &security_attributes, OPEN_EXISTING, 0, NULL); break; case SDL_PROCESS_STDIO_INHERITED: default: @@ -366,7 +367,7 @@ bool SDL_SYS_CreateProcessWithProperties(SDL_Process *process, SDL_PropertiesID startup_info.hStdOutput = stdout_pipe[WRITE_END]; break; case SDL_PROCESS_STDIO_NULL: - startup_info.hStdOutput = CreateFile(TEXT("\\\\.\\NUL"), GENERIC_ALL, 0, &security_attributes, OPEN_EXISTING, 0, NULL); + startup_info.hStdOutput = CreateFile(TEXT("\\\\.\\NUL"), (GENERIC_READ | GENERIC_WRITE), 0, &security_attributes, OPEN_EXISTING, 0, NULL); break; case SDL_PROCESS_STDIO_INHERITED: default: @@ -412,7 +413,7 @@ bool SDL_SYS_CreateProcessWithProperties(SDL_Process *process, SDL_PropertiesID startup_info.hStdError = stderr_pipe[WRITE_END]; break; case SDL_PROCESS_STDIO_NULL: - startup_info.hStdError = CreateFile(TEXT("\\\\.\\NUL"), GENERIC_ALL, 0, &security_attributes, OPEN_EXISTING, 0, NULL); + startup_info.hStdError = CreateFile(TEXT("\\\\.\\NUL"), (GENERIC_READ | GENERIC_WRITE), 0, &security_attributes, OPEN_EXISTING, 0, NULL); break; case SDL_PROCESS_STDIO_INHERITED: default: diff --git a/lib/sdl3/SDL/src/render/SDL_render.c b/lib/sdl3/SDL/src/render/SDL_render.c index 60024b8..1292c1b 100644 --- a/lib/sdl3/SDL/src/render/SDL_render.c +++ b/lib/sdl3/SDL/src/render/SDL_render.c @@ -1658,8 +1658,6 @@ SDL_Texture *SDL_CreateTextureFromSurface(SDL_Renderer *renderer, SDL_Surface *s } } - surface_colorspace = SDL_GetSurfaceColorspace(surface); - // Try to have the best pixel format for the texture // No alpha, but a colorkey => promote to alpha if (!SDL_ISPIXELFORMAT_ALPHA(surface->format) && SDL_SurfaceHasColorKey(surface)) { @@ -1721,6 +1719,9 @@ SDL_Texture *SDL_CreateTextureFromSurface(SDL_Renderer *renderer, SDL_Surface *s } } + surface_colorspace = SDL_GetSurfaceColorspace(surface); + texture_colorspace = surface_colorspace; + if (surface_colorspace == SDL_COLORSPACE_SRGB_LINEAR || SDL_COLORSPACETRANSFER(surface_colorspace) == SDL_TRANSFER_CHARACTERISTICS_PQ) { if (SDL_ISPIXELFORMAT_FLOAT(format)) { @@ -2572,7 +2573,7 @@ static void UpdateLogicalPresentation(SDL_Renderer *renderer) const float logical_h = view->logical_h; int iwidth, iheight; - if (renderer->target) { + if (!is_main_view && renderer->target) { iwidth = (int)renderer->target->w; iheight = (int)renderer->target->h; } else { @@ -3930,8 +3931,7 @@ bool SDL_RenderTexture(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_F real_srcrect.w = (float)texture->w; real_srcrect.h = (float)texture->h; if (srcrect) { - if (!SDL_GetRectIntersectionFloat(srcrect, &real_srcrect, &real_srcrect) || - real_srcrect.w == 0.0f || real_srcrect.h == 0.0f) { + if (!SDL_GetRectIntersectionFloat(srcrect, &real_srcrect, &real_srcrect)) { return true; } } diff --git a/lib/sdl3/SDL/src/render/gpu/SDL_render_gpu.c b/lib/sdl3/SDL/src/render/gpu/SDL_render_gpu.c index 5269429..d5f2775 100644 --- a/lib/sdl3/SDL/src/render/gpu/SDL_render_gpu.c +++ b/lib/sdl3/SDL/src/render/gpu/SDL_render_gpu.c @@ -445,7 +445,6 @@ static void GPU_InvalidateCachedState(SDL_Renderer *renderer) { GPU_RenderData *data = (GPU_RenderData *)renderer->internal; - data->state.render_target = NULL; data->state.scissor_enabled = false; } diff --git a/lib/sdl3/SDL/src/render/metal/SDL_render_metal.m b/lib/sdl3/SDL/src/render/metal/SDL_render_metal.m index 3bba129..e11fe1c 100644 --- a/lib/sdl3/SDL/src/render/metal/SDL_render_metal.m +++ b/lib/sdl3/SDL/src/render/metal/SDL_render_metal.m @@ -79,15 +79,10 @@ static const size_t CONSTANTS_OFFSET_DECODE_BT2020_LIMITED = ALIGN_CONSTANTS(16, static const size_t CONSTANTS_OFFSET_DECODE_BT2020_FULL = ALIGN_CONSTANTS(16, CONSTANTS_OFFSET_DECODE_BT2020_LIMITED + sizeof(float) * 4 * 4); static const size_t CONSTANTS_LENGTH = CONSTANTS_OFFSET_DECODE_BT2020_FULL + sizeof(float) * 4 * 4; -// Sampler types -typedef enum -{ - SDL_METAL_SAMPLER_NEAREST_CLAMP, - SDL_METAL_SAMPLER_NEAREST_WRAP, - SDL_METAL_SAMPLER_LINEAR_CLAMP, - SDL_METAL_SAMPLER_LINEAR_WRAP, - SDL_NUM_METAL_SAMPLERS -} SDL_METAL_sampler_type; +#define RENDER_SAMPLER_HASHKEY(scale_mode, address_u, address_v) \ + (((scale_mode == SDL_SCALEMODE_NEAREST) << 0) | \ + ((address_u == SDL_TEXTURE_ADDRESS_WRAP) << 1) | \ + ((address_v == SDL_TEXTURE_ADDRESS_WRAP) << 2)) typedef enum SDL_MetalVertexFunction { @@ -139,7 +134,7 @@ typedef struct METAL_ShaderPipelines @property(nonatomic, retain) id mtlcmdencoder; @property(nonatomic, retain) id mtllibrary; @property(nonatomic, retain) id mtlbackbuffer; -@property(nonatomic, retain) NSMutableArray> *mtlsamplers; +@property(nonatomic, retain) NSMutableDictionary> *mtlsamplers; @property(nonatomic, retain) id mtlbufconstants; @property(nonatomic, retain) id mtlbufquadindices; @property(nonatomic, assign) SDL_MetalView mtlview; @@ -1295,6 +1290,9 @@ typedef struct __unsafe_unretained id vertex_buffer; size_t constants_offset; SDL_Texture *texture; + SDL_ScaleMode texture_scale_mode; + SDL_TextureAddressMode texture_address_mode_u; + SDL_TextureAddressMode texture_address_mode_v; bool cliprect_dirty; bool cliprect_enabled; SDL_Rect cliprect; @@ -1452,6 +1450,58 @@ static bool SetDrawState(SDL_Renderer *renderer, const SDL_RenderCommand *cmd, c return true; } +static id GetSampler(SDL3METAL_RenderData *data, SDL_ScaleMode scale_mode, SDL_TextureAddressMode address_u, SDL_TextureAddressMode address_v) +{ + NSNumber *key = [NSNumber numberWithInteger:RENDER_SAMPLER_HASHKEY(scale_mode, address_u, address_v)]; + id mtlsampler = data.mtlsamplers[key]; + if (mtlsampler == nil) { + MTLSamplerDescriptor *samplerdesc; + samplerdesc = [[MTLSamplerDescriptor alloc] init]; + switch (scale_mode) { + case SDL_SCALEMODE_NEAREST: + samplerdesc.minFilter = MTLSamplerMinMagFilterNearest; + samplerdesc.magFilter = MTLSamplerMinMagFilterNearest; + break; + case SDL_SCALEMODE_LINEAR: + samplerdesc.minFilter = MTLSamplerMinMagFilterLinear; + samplerdesc.magFilter = MTLSamplerMinMagFilterLinear; + break; + default: + SDL_SetError("Unknown scale mode: %d", scale_mode); + return nil; + } + switch (address_u) { + case SDL_TEXTURE_ADDRESS_CLAMP: + samplerdesc.sAddressMode = MTLSamplerAddressModeClampToEdge; + break; + case SDL_TEXTURE_ADDRESS_WRAP: + samplerdesc.sAddressMode = MTLSamplerAddressModeRepeat; + break; + default: + SDL_SetError("Unknown texture address mode: %d", address_u); + return nil; + } + switch (address_v) { + case SDL_TEXTURE_ADDRESS_CLAMP: + samplerdesc.tAddressMode = MTLSamplerAddressModeClampToEdge; + break; + case SDL_TEXTURE_ADDRESS_WRAP: + samplerdesc.tAddressMode = MTLSamplerAddressModeRepeat; + break; + default: + SDL_SetError("Unknown texture address mode: %d", address_v); + return nil; + } + mtlsampler = [data.mtldevice newSamplerStateWithDescriptor:samplerdesc]; + if (mtlsampler == nil) { + SDL_SetError("Couldn't create sampler"); + return nil; + } + data.mtlsamplers[key] = mtlsampler; + } + return mtlsampler; +} + static bool SetCopyState(SDL_Renderer *renderer, const SDL_RenderCommand *cmd, const size_t constants_offset, id mtlbufvertex, METAL_DrawStateCache *statecache) { @@ -1467,33 +1517,6 @@ static bool SetCopyState(SDL_Renderer *renderer, const SDL_RenderCommand *cmd, c } if (texture != statecache->texture) { - id mtlsampler; - - if (cmd->data.draw.texture_scale_mode == SDL_SCALEMODE_NEAREST) { - switch (cmd->data.draw.texture_address_mode) { - case SDL_TEXTURE_ADDRESS_CLAMP: - mtlsampler = data.mtlsamplers[SDL_METAL_SAMPLER_NEAREST_CLAMP]; - break; - case SDL_TEXTURE_ADDRESS_WRAP: - mtlsampler = data.mtlsamplers[SDL_METAL_SAMPLER_NEAREST_WRAP]; - break; - default: - return SDL_SetError("Unknown texture address mode: %d", cmd->data.draw.texture_address_mode); - } - } else { - switch (cmd->data.draw.texture_address_mode) { - case SDL_TEXTURE_ADDRESS_CLAMP: - mtlsampler = data.mtlsamplers[SDL_METAL_SAMPLER_LINEAR_CLAMP]; - break; - case SDL_TEXTURE_ADDRESS_WRAP: - mtlsampler = data.mtlsamplers[SDL_METAL_SAMPLER_LINEAR_WRAP]; - break; - default: - return SDL_SetError("Unknown texture address mode: %d", cmd->data.draw.texture_address_mode); - } - } - [data.mtlcmdencoder setFragmentSamplerState:mtlsampler atIndex:0]; - [data.mtlcmdencoder setFragmentTexture:texturedata.mtltexture atIndex:0]; #ifdef SDL_HAVE_YUV if (texturedata.yuv || texturedata.nv12) { @@ -1503,6 +1526,20 @@ static bool SetCopyState(SDL_Renderer *renderer, const SDL_RenderCommand *cmd, c #endif statecache->texture = texture; } + + if (cmd->data.draw.texture_scale_mode != statecache->texture_scale_mode || + cmd->data.draw.texture_address_mode != statecache->texture_address_mode_u || + cmd->data.draw.texture_address_mode != statecache->texture_address_mode_v) { + id mtlsampler = GetSampler(data, cmd->data.draw.texture_scale_mode, cmd->data.draw.texture_address_mode, cmd->data.draw.texture_address_mode); + if (mtlsampler == nil) { + return false; + } + [data.mtlcmdencoder setFragmentSamplerState:mtlsampler atIndex:0]; + + statecache->texture_scale_mode = cmd->data.draw.texture_scale_mode; + statecache->texture_address_mode_u = cmd->data.draw.texture_address_mode; + statecache->texture_address_mode_v = cmd->data.draw.texture_address_mode; + } return true; } @@ -1523,6 +1560,9 @@ static bool METAL_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd statecache.vertex_buffer = nil; statecache.constants_offset = CONSTANTS_OFFSET_INVALID; statecache.texture = NULL; + statecache.texture_scale_mode = SDL_SCALEMODE_INVALID; + statecache.texture_address_mode_u = SDL_TEXTURE_ADDRESS_INVALID; + statecache.texture_address_mode_v = SDL_TEXTURE_ADDRESS_INVALID; statecache.shader_constants_dirty = true; statecache.cliprect_dirty = true; statecache.viewport_dirty = true; @@ -1883,7 +1923,6 @@ static bool METAL_CreateRenderer(SDL_Renderer *renderer, SDL_Window *window, SDL int maxtexsize, quadcount = UINT16_MAX / 4; UInt16 *indexdata; size_t indicessize = sizeof(UInt16) * quadcount * 6; - MTLSamplerDescriptor *samplerdesc; id mtlcmdqueue; id mtllibrary; id mtlbufconstantstaging, mtlbufquadindicesstaging, mtlbufconstants, mtlbufquadindices; @@ -2043,27 +2082,7 @@ static bool METAL_CreateRenderer(SDL_Renderer *renderer, SDL_Window *window, SDL data.allpipelines = NULL; ChooseShaderPipelines(data, MTLPixelFormatBGRA8Unorm); - static struct - { - MTLSamplerMinMagFilter filter; - MTLSamplerAddressMode address; - } samplerParams[] = { - { MTLSamplerMinMagFilterNearest, MTLSamplerAddressModeClampToEdge }, - { MTLSamplerMinMagFilterNearest, MTLSamplerAddressModeRepeat }, - { MTLSamplerMinMagFilterLinear, MTLSamplerAddressModeClampToEdge }, - { MTLSamplerMinMagFilterLinear, MTLSamplerAddressModeRepeat }, - }; - SDL_COMPILE_TIME_ASSERT(samplerParams_SIZE, SDL_arraysize(samplerParams) == SDL_NUM_METAL_SAMPLERS); - - data.mtlsamplers = [[NSMutableArray> alloc] init]; - samplerdesc = [[MTLSamplerDescriptor alloc] init]; - for (int i = 0; i < SDL_arraysize(samplerParams); ++i) { - samplerdesc.minFilter = samplerParams[i].filter; - samplerdesc.magFilter = samplerParams[i].filter; - samplerdesc.sAddressMode = samplerParams[i].address; - samplerdesc.tAddressMode = samplerParams[i].address; - [data.mtlsamplers addObject:[data.mtldevice newSamplerStateWithDescriptor:samplerdesc]]; - } + data.mtlsamplers = [[NSMutableDictionary> alloc] init]; mtlbufconstantstaging = [data.mtldevice newBufferWithLength:CONSTANTS_LENGTH options:MTLResourceStorageModeShared]; diff --git a/lib/sdl3/SDL/src/render/ps2/SDL_render_ps2.c b/lib/sdl3/SDL/src/render/ps2/SDL_render_ps2.c index 713192c..f414fbd 100644 --- a/lib/sdl3/SDL/src/render/ps2/SDL_render_ps2.c +++ b/lib/sdl3/SDL/src/render/ps2/SDL_render_ps2.c @@ -60,7 +60,7 @@ typedef struct static int vsync_sema_id = 0; // PRIVATE METHODS -static int vsync_handler(void) +static int vsync_handler(int reason) { iSignalSema(vsync_sema_id); diff --git a/lib/sdl3/SDL/src/storage/SDL_storage.c b/lib/sdl3/SDL/src/storage/SDL_storage.c index 75952ff..7c395b3 100644 --- a/lib/sdl3/SDL/src/storage/SDL_storage.c +++ b/lib/sdl3/SDL/src/storage/SDL_storage.c @@ -34,6 +34,9 @@ static TitleStorageBootStrap *titlebootstrap[] = { static UserStorageBootStrap *userbootstrap[] = { #ifdef SDL_STORAGE_STEAM &STEAM_userbootstrap, +#endif +#ifdef SDL_STORAGE_PRIVATE + &PRIVATE_userbootstrap, #endif &GENERIC_userbootstrap, NULL diff --git a/lib/sdl3/SDL/src/storage/SDL_sysstorage.h b/lib/sdl3/SDL/src/storage/SDL_sysstorage.h index 57d60d6..f047e55 100644 --- a/lib/sdl3/SDL/src/storage/SDL_sysstorage.h +++ b/lib/sdl3/SDL/src/storage/SDL_sysstorage.h @@ -44,6 +44,7 @@ extern TitleStorageBootStrap GENERIC_titlebootstrap; // Steam does not have title storage APIs extern UserStorageBootStrap GENERIC_userbootstrap; +extern UserStorageBootStrap PRIVATE_userbootstrap; extern UserStorageBootStrap STEAM_userbootstrap; extern SDL_Storage *GENERIC_OpenFileStorage(const char *path); diff --git a/lib/sdl3/SDL/src/tray/unix/SDL_tray.c b/lib/sdl3/SDL/src/tray/unix/SDL_tray.c index dc2d0ca..e8a7b0d 100644 --- a/lib/sdl3/SDL/src/tray/unix/SDL_tray.c +++ b/lib/sdl3/SDL/src/tray/unix/SDL_tray.c @@ -58,8 +58,8 @@ typedef enum static gulong (*g_signal_connect_data)(gpointer instance, const gchar *detailed_signal, GCallback c_handler, gpointer data, GClosureNotify destroy_data, GConnectFlags connect_flags); static void (*g_object_unref)(gpointer object); static gchar *(*g_mkdtemp)(gchar *template); -gpointer (*g_object_ref_sink)(gpointer object); -gpointer (*g_object_ref)(gpointer object); +static gpointer (*g_object_ref_sink)(gpointer object); +static gpointer (*g_object_ref)(gpointer object); // glib_typeof requires compiler-specific code and includes that are too complex // to be worth copy-pasting here @@ -541,7 +541,7 @@ SDL_TrayMenu *SDL_CreateTraySubmenu(SDL_TrayEntry *entry) return NULL; } - entry->submenu->menu = (GtkMenuShell *)gtk_menu_new(); + entry->submenu->menu = g_object_ref_sink(gtk_menu_new()); entry->submenu->parent_tray = NULL; entry->submenu->parent_entry = entry; entry->submenu->nEntries = 0; diff --git a/lib/sdl3/SDL/src/tray/windows/SDL_tray.c b/lib/sdl3/SDL/src/tray/windows/SDL_tray.c index 18008ee..15021ac 100644 --- a/lib/sdl3/SDL/src/tray/windows/SDL_tray.c +++ b/lib/sdl3/SDL/src/tray/windows/SDL_tray.c @@ -544,7 +544,7 @@ void SDL_SetTrayEntryLabel(SDL_TrayEntry *entry, const char *label) mii.dwTypeData = label_w; mii.cch = (UINT) SDL_wcslen(label_w); - if (!SetMenuItemInfoW(entry->parent->hMenu, (UINT) entry->id, TRUE, &mii)) { + if (!SetMenuItemInfoW(entry->parent->hMenu, (UINT) entry->id, FALSE, &mii)) { SDL_SetError("Couldn't update tray entry label"); } diff --git a/lib/sdl3/SDL/src/video/SDL_blit_auto.h b/lib/sdl3/SDL/src/video/SDL_blit_auto.h index cd3f0d8..329ffe5 100644 --- a/lib/sdl3/SDL/src/video/SDL_blit_auto.h +++ b/lib/sdl3/SDL/src/video/SDL_blit_auto.h @@ -20,12 +20,13 @@ 3. This notice may not be removed or altered from any source distribution. */ #include "SDL_internal.h" -#include "SDL_blit.h" #ifdef SDL_HAVE_BLIT_AUTO /* *INDENT-OFF* */ // clang-format off +#include "SDL_blit.h" + extern SDL_BlitFuncEntry SDL_GeneratedBlitFuncTable[]; /* *INDENT-ON* */ // clang-format on diff --git a/lib/sdl3/SDL/src/video/SDL_surface.c b/lib/sdl3/SDL/src/video/SDL_surface.c index e6f13b8..73049a5 100644 --- a/lib/sdl3/SDL/src/video/SDL_surface.c +++ b/lib/sdl3/SDL/src/video/SDL_surface.c @@ -1101,9 +1101,9 @@ bool SDL_BlitSurfaceScaled(SDL_Surface *src, const SDL_Rect *srcrect, SDL_Surfac int dst_w, dst_h; // Make sure the surfaces aren't locked - if (!SDL_SurfaceValid(src)) { + if (!SDL_SurfaceValid(src) || !src->pixels) { return SDL_InvalidParamError("src"); - } else if (!SDL_SurfaceValid(dst)) { + } else if (!SDL_SurfaceValid(dst) || !dst->pixels) { return SDL_InvalidParamError("dst"); } else if ((src->flags & SDL_SURFACE_LOCKED) || (dst->flags & SDL_SURFACE_LOCKED)) { return SDL_SetError("Surfaces must not be locked during blit"); @@ -1133,6 +1133,13 @@ bool SDL_BlitSurfaceScaled(SDL_Surface *src, const SDL_Rect *srcrect, SDL_Surfac return SDL_BlitSurface(src, srcrect, dst, dstrect); } + if (src_w == 0) { + src_w = 1; + } + if (src_h == 0) { + src_h = 1; + } + scaling_w = (double)dst_w / src_w; scaling_h = (double)dst_h / src_h; diff --git a/lib/sdl3/SDL/src/video/SDL_sysvideo.h b/lib/sdl3/SDL/src/video/SDL_sysvideo.h index 6da8bd2..ad5bed2 100644 --- a/lib/sdl3/SDL/src/video/SDL_sysvideo.h +++ b/lib/sdl3/SDL/src/video/SDL_sysvideo.h @@ -396,8 +396,7 @@ struct SDL_VideoDevice bool checked_texture_framebuffer; bool is_dummy; bool suspend_screensaver; - SDL_Window *wakeup_window; - SDL_Mutex *wakeup_lock; // Initialized only if WaitEventTimeout/SendWakeupEvent are supported + void *wakeup_window; int num_displays; SDL_VideoDisplay **displays; SDL_Rect desktop_bounds; diff --git a/lib/sdl3/SDL/src/video/SDL_video.c b/lib/sdl3/SDL/src/video/SDL_video.c index 725bbc8..db38a19 100644 --- a/lib/sdl3/SDL/src/video/SDL_video.c +++ b/lib/sdl3/SDL/src/video/SDL_video.c @@ -1731,12 +1731,25 @@ SDL_VideoDisplay *SDL_GetVideoDisplayForFullscreenWindow(SDL_Window *window) return SDL_GetVideoDisplay(displayID); } +#define SDL_PROP_SDL2_COMPAT_WINDOW_PREFERRED_FULLSCREEN_DISPLAY "sdl2-compat.window.preferred_fullscreen_display" + SDL_DisplayID SDL_GetDisplayForWindow(SDL_Window *window) { SDL_DisplayID displayID = 0; CHECK_WINDOW_MAGIC(window, 0); + /* sdl2-compat calls this function to get a display on which to make the window fullscreen, + * so pass it the preferred fullscreen display ID in a property. + */ + SDL_PropertiesID window_props = SDL_GetWindowProperties(window); + SDL_VideoDisplay *fs_display = SDL_GetVideoDisplayForFullscreenWindow(window); + if (fs_display) { + SDL_SetNumberProperty(window_props, SDL_PROP_SDL2_COMPAT_WINDOW_PREFERRED_FULLSCREEN_DISPLAY, fs_display->id); + } else { + SDL_ClearProperty(window_props, SDL_PROP_SDL2_COMPAT_WINDOW_PREFERRED_FULLSCREEN_DISPLAY); + } + // An explicit fullscreen display overrides all if (window->flags & SDL_WINDOW_FULLSCREEN) { displayID = window->current_fullscreen_mode.displayID; @@ -2500,7 +2513,9 @@ SDL_Window *SDL_CreateWindowWithProperties(SDL_PropertiesID props) SDL_UpdateWindowHierarchy(window, parent); if (_this->CreateSDLWindow && !_this->CreateSDLWindow(_this, window, props)) { + PUSH_SDL_ERROR() SDL_DestroyWindow(window); + POP_SDL_ERROR() return NULL; } @@ -2748,7 +2763,7 @@ SDL_Window *SDL_GetWindowFromID(SDL_WindowID id) } } } - SDL_SetError("Invalid window ID"); \ + SDL_SetError("Invalid window ID"); return NULL; } @@ -4266,9 +4281,7 @@ void SDL_DestroyWindow(SDL_Window *window) _this->current_glwin = NULL; } - if (_this->wakeup_window == window) { - _this->wakeup_window = NULL; - } + SDL_CompareAndSwapAtomicPointer(&_this->wakeup_window, window, NULL); // Now invalidate magic SDL_SetObjectValid(window, SDL_OBJECT_TYPE_WINDOW, false); @@ -5021,8 +5034,7 @@ bool SDL_GL_GetAttribute(SDL_GLAttr attr, int *value) } if (fbo_type != GL_NONE) { glGetFramebufferAttachmentParameterivFunc(GL_FRAMEBUFFER, attachment, attachmentattrib, (GLint *)value); - } - else { + } else { *value = 0; } if (glBindFramebufferFunc && (current_fbo != 0)) { @@ -5253,7 +5265,7 @@ bool SDL_GL_SwapWindow(SDL_Window *window) bool SDL_GL_DestroyContext(SDL_GLContext context) { if (!_this) { - return SDL_UninitializedVideo(); \ + return SDL_UninitializedVideo(); } if (!context) { return SDL_InvalidParamError("context"); diff --git a/lib/sdl3/SDL/src/video/cocoa/SDL_cocoaclipboard.m b/lib/sdl3/SDL/src/video/cocoa/SDL_cocoaclipboard.m index 42c2ad6..7039ff6 100644 --- a/lib/sdl3/SDL/src/video/cocoa/SDL_cocoaclipboard.m +++ b/lib/sdl3/SDL/src/video/cocoa/SDL_cocoaclipboard.m @@ -158,6 +158,17 @@ bool Cocoa_SetClipboardData(SDL_VideoDevice *_this) @autoreleasepool { SDL_CocoaVideoData *data = (__bridge SDL_CocoaVideoData *)_this->internal; NSPasteboard *pasteboard = [NSPasteboard generalPasteboard]; + + // SetClipboardText specialization so text is available after the app quits + if (_this->clipboard_callback && _this->num_clipboard_mime_types == 1) { + if (SDL_strncmp(_this->clipboard_mime_types[0], "text/plain;charset=utf-8", 24) == 0) { + [pasteboard declareTypes:@[ NSPasteboardTypeString ] owner:nil]; + [pasteboard setString:@((char *)_this->clipboard_userdata) forType:NSPasteboardTypeString]; + data.clipboard_count = [pasteboard changeCount]; + return true; + } + } + NSPasteboardItem *newItem = [NSPasteboardItem new]; NSMutableArray *utiTypes = [NSMutableArray new]; Cocoa_PasteboardDataProvider *provider = [[Cocoa_PasteboardDataProvider alloc] initWith: _this->clipboard_callback userData: _this->clipboard_userdata]; diff --git a/lib/sdl3/SDL/src/video/cocoa/SDL_cocoamouse.m b/lib/sdl3/SDL/src/video/cocoa/SDL_cocoamouse.m index 530ca0c..f8f5829 100644 --- a/lib/sdl3/SDL/src/video/cocoa/SDL_cocoamouse.m +++ b/lib/sdl3/SDL/src/video/cocoa/SDL_cocoamouse.m @@ -450,12 +450,18 @@ void Cocoa_HandleMouseEvent(SDL_VideoDevice *_this, NSEvent *event) // All events except NSEventTypeMouseExited can only happen if the window // has mouse focus, so we'll always set the focus even if we happen to miss // NSEventTypeMouseEntered, which apparently happens if the window is - // created under the mouse on macOS 12.7 + // created under the mouse on macOS 12.7. But, only set the focus if + // the event acutally has a non-NULL window, otherwise what would happen + // is that after an NSEventTypeMouseEntered there would sometimes be + // NSEventTypeMouseMoved without a window causing us to suppress subsequent + // mouse move events. NSEventType event_type = [event type]; if (event_type == NSEventTypeMouseExited) { Cocoa_MouseFocus = NULL; } else { - Cocoa_MouseFocus = [event window]; + if ([event window] != NULL) { + Cocoa_MouseFocus = [event window]; + } } switch (event_type) { diff --git a/lib/sdl3/SDL/src/video/cocoa/SDL_cocoavideo.m b/lib/sdl3/SDL/src/video/cocoa/SDL_cocoavideo.m index 81baf78..aed193d 100644 --- a/lib/sdl3/SDL/src/video/cocoa/SDL_cocoavideo.m +++ b/lib/sdl3/SDL/src/video/cocoa/SDL_cocoavideo.m @@ -49,9 +49,6 @@ static void Cocoa_VideoQuit(SDL_VideoDevice *_this); static void Cocoa_DeleteDevice(SDL_VideoDevice *device) { @autoreleasepool { - if (device->wakeup_lock) { - SDL_DestroyMutex(device->wakeup_lock); - } CFBridgingRelease(device->internal); SDL_free(device); } @@ -81,7 +78,6 @@ static SDL_VideoDevice *Cocoa_CreateDevice(void) return NULL; } device->internal = (SDL_VideoData *)CFBridgingRetain(data); - device->wakeup_lock = SDL_CreateMutex(); device->system_theme = Cocoa_GetSystemTheme(); // Set the function pointers diff --git a/lib/sdl3/SDL/src/video/cocoa/SDL_cocoawindow.m b/lib/sdl3/SDL/src/video/cocoa/SDL_cocoawindow.m index c5d88b1..7be564a 100644 --- a/lib/sdl3/SDL/src/video/cocoa/SDL_cocoawindow.m +++ b/lib/sdl3/SDL/src/video/cocoa/SDL_cocoawindow.m @@ -2022,6 +2022,7 @@ static void Cocoa_SendMouseButtonClicks(SDL_Mouse *mouse, NSEvent *theEvent, SDL @interface SDL3View : NSView { SDL_Window *_sdlWindow; + NSTrackingArea *_trackingArea; // only used on macOS <= 11.0 } - (void)setSDLWindow:(SDL_Window *)window; @@ -2033,6 +2034,7 @@ static void Cocoa_SendMouseButtonClicks(SDL_Mouse *mouse, NSEvent *theEvent, SDL - (BOOL)acceptsFirstMouse:(NSEvent *)theEvent; - (BOOL)wantsUpdateLayer; - (void)updateLayer; +- (void)updateTrackingAreas; @end @implementation SDL3View @@ -2104,15 +2106,62 @@ static void Cocoa_SendMouseButtonClicks(SDL_Mouse *mouse, NSEvent *theEvent, SDL - (BOOL)acceptsFirstMouse:(NSEvent *)theEvent { - if (SDL_GetHint(SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH)) { + if (_sdlWindow->flags & SDL_WINDOW_POPUP_MENU) { + return YES; + } else if (SDL_GetHint(SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH)) { return SDL_GetHintBoolean(SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH, false); } else { return SDL_GetHintBoolean("SDL_MAC_MOUSE_FOCUS_CLICKTHROUGH", false); } } +- (void)updateTrackingAreas +{ + [super updateTrackingAreas]; + + if (@available(macOS 12.0, *)) { + // we (currently) use the tracking areas as a workaround for older macOSes, but we might be safe everywhere... + } else { + SDL_CocoaWindowData *windata = (__bridge SDL_CocoaWindowData *)_sdlWindow->internal; + if (_trackingArea) { + [self removeTrackingArea:_trackingArea]; + } + _trackingArea = [[NSTrackingArea alloc] initWithRect:[self bounds] options:NSTrackingMouseEnteredAndExited|NSTrackingActiveAlways owner:windata.listener userInfo:nil]; + [self addTrackingArea:_trackingArea]; + } +} @end +static void Cocoa_UpdateMouseFocus() +{ + const NSPoint mouseLocation = [NSEvent mouseLocation]; + + // Find the topmost window under the pointer and send a motion event if it is an SDL window. + [NSApp enumerateWindowsWithOptions:NSWindowListOrderedFrontToBack + usingBlock:^(NSWindow *nswin, BOOL *stop) { + NSRect r = [nswin contentRectForFrameRect:[nswin frame]]; + if (NSPointInRect(mouseLocation, r)) { + SDL_VideoDevice *vid = SDL_GetVideoDevice(); + SDL_Window *sdlwindow; + for (sdlwindow = vid->windows; sdlwindow; sdlwindow = sdlwindow->next) { + if (nswin == ((__bridge SDL_CocoaWindowData *)sdlwindow->internal).nswindow) { + break; + } + } + *stop = YES; + if (sdlwindow) { + int wx, wy; + SDL_RelativeToGlobalForWindow(sdlwindow, sdlwindow->x, sdlwindow->y, &wx, &wy); + + // Calculate the cursor coordinates relative to the window. + const float dx = mouseLocation.x - wx; + const float dy = (CGDisplayPixelsHigh(kCGDirectMainDisplay) - mouseLocation.y) - wy; + SDL_SendMouseMotion(0, sdlwindow, SDL_GLOBAL_MOUSE_ID, false, dx, dy); + } + } + }]; +} + static bool SetupWindowData(SDL_VideoDevice *_this, SDL_Window *window, NSWindow *nswindow, NSView *nsview) { @autoreleasepool { @@ -2210,8 +2259,10 @@ static bool SetupWindowData(SDL_VideoDevice *_this, SDL_Window *window, NSWindow } else { if (window->flags & SDL_WINDOW_TOOLTIP) { [nswindow setIgnoresMouseEvents:YES]; - } else if (window->flags & SDL_WINDOW_POPUP_MENU) { + [nswindow setAcceptsMouseMovedEvents:NO]; + } else if ((window->flags & SDL_WINDOW_POPUP_MENU) && !(window->flags & SDL_WINDOW_HIDDEN)) { Cocoa_SetKeyboardFocus(window, window->parent == SDL_GetKeyboardFocus()); + Cocoa_UpdateMouseFocus(); } } @@ -2531,8 +2582,8 @@ void Cocoa_SetWindowMaximumSize(SDL_VideoDevice *_this, SDL_Window *window) SDL_CocoaWindowData *windata = (__bridge SDL_CocoaWindowData *)window->internal; NSSize maxSize; - maxSize.width = window->max_w; - maxSize.height = window->max_h; + maxSize.width = window->max_w ? window->max_w : CGFLOAT_MAX; + maxSize.height = window->max_h ? window->max_h : CGFLOAT_MAX; [windata.nswindow setContentMaxSize:maxSize]; } @@ -2596,6 +2647,9 @@ void Cocoa_ShowWindow(SDL_VideoDevice *_this, SDL_Window *window) [nswindow orderWindow:NSWindowBelow relativeTo:[[NSApp keyWindow] windowNumber]]; } } + } else if (window->flags & SDL_WINDOW_POPUP_MENU) { + Cocoa_SetKeyboardFocus(window, window->parent == SDL_GetKeyboardFocus()); + Cocoa_UpdateMouseFocus(); } } [nswindow setIsVisible:YES]; @@ -2643,6 +2697,7 @@ void Cocoa_HideWindow(SDL_VideoDevice *_this, SDL_Window *window) } Cocoa_SetKeyboardFocus(new_focus, set_focus); + Cocoa_UpdateMouseFocus(); } else if (window->parent && waskey) { /* Key status is not automatically set on the parent when a child is hidden. Check if the * child window was key, and set the first visible parent to be key if so. diff --git a/lib/sdl3/SDL/src/video/emscripten/SDL_emscriptenframebuffer.c b/lib/sdl3/SDL/src/video/emscripten/SDL_emscriptenframebuffer.c index 503fac6..89fae73 100644 --- a/lib/sdl3/SDL/src/video/emscripten/SDL_emscriptenframebuffer.c +++ b/lib/sdl3/SDL/src/video/emscripten/SDL_emscriptenframebuffer.c @@ -78,7 +78,7 @@ bool Emscripten_UpdateWindowFramebuffer(SDL_VideoDevice *_this, SDL_Window *wind if (!Module['SDL3']) Module['SDL3'] = {}; var SDL3 = Module['SDL3']; if (SDL3.ctxCanvas !== canvas) { - SDL3.ctx = Module['createContext'](canvas, false, true); + SDL3.ctx = Browser.createContext(canvas, false, true); SDL3.ctxCanvas = canvas; } if (SDL3.w !== w || SDL3.h !== h || SDL3.imageCtx !== SDL3.ctx) { diff --git a/lib/sdl3/SDL/src/video/emscripten/SDL_emscriptenopengles.c b/lib/sdl3/SDL/src/video/emscripten/SDL_emscriptenopengles.c index 227cdc5..bb490bb 100644 --- a/lib/sdl3/SDL/src/video/emscripten/SDL_emscriptenopengles.c +++ b/lib/sdl3/SDL/src/video/emscripten/SDL_emscriptenopengles.c @@ -101,7 +101,7 @@ SDL_GLContext Emscripten_GLES_CreateContext(SDL_VideoDevice *_this, SDL_Window * context = emscripten_webgl_create_context(window_data->canvas_id, &attribs); - if (context < 0) { + if (!context) { SDL_SetError("Could not create webgl context"); return NULL; } diff --git a/lib/sdl3/SDL/src/video/emscripten/SDL_emscriptenvideo.c b/lib/sdl3/SDL/src/video/emscripten/SDL_emscriptenvideo.c index 1496268..e735ee8 100644 --- a/lib/sdl3/SDL/src/video/emscripten/SDL_emscriptenvideo.c +++ b/lib/sdl3/SDL/src/video/emscripten/SDL_emscriptenvideo.c @@ -64,7 +64,7 @@ static SDL_SystemTheme Emscripten_GetSystemTheme(void) /* Technically, light theme can mean explicit light theme or no preference. https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-color-scheme#syntax */ - int theme_code = EM_ASM_INT({ + int theme_code = MAIN_THREAD_EM_ASM_INT({ if (!window.matchMedia) { return -1; } diff --git a/lib/sdl3/SDL/src/video/kmsdrm/SDL_kmsdrmvideo.c b/lib/sdl3/SDL/src/video/kmsdrm/SDL_kmsdrmvideo.c index be1db82..adca91c 100644 --- a/lib/sdl3/SDL/src/video/kmsdrm/SDL_kmsdrmvideo.c +++ b/lib/sdl3/SDL/src/video/kmsdrm/SDL_kmsdrmvideo.c @@ -1368,9 +1368,14 @@ bool KMSDRM_CreateSurfaces(SDL_VideoDevice *_this, SDL_Window *window) windata->gs = KMSDRM_gbm_surface_create(viddata->gbm_dev, dispdata->mode.hdisplay, dispdata->mode.vdisplay, surface_fmt, surface_flags); - + if (!windata->gs && errno == ENOSYS) { + // Try again without the scanout flags, needed on NVIDIA drivers + windata->gs = KMSDRM_gbm_surface_create(viddata->gbm_dev, + dispdata->mode.hdisplay, dispdata->mode.vdisplay, + surface_fmt, 0); + } if (!windata->gs) { - return SDL_SetError("Could not create GBM surface"); + return SDL_SetError("Could not create GBM surface: %s", strerror(errno)); } /* We can't get the EGL context yet because SDL_CreateRenderer has not been called, @@ -1729,9 +1734,9 @@ bool KMSDRM_CreateWindow(SDL_VideoDevice *_this, SDL_Window *window, SDL_Propert } /* Create the window surfaces with the size we have just chosen. - Needs the window diverdata in place. */ + Needs the window driverdata in place. */ if (!KMSDRM_CreateSurfaces(_this, window)) { - return SDL_SetError("Can't window GBM/EGL surfaces on window creation."); + return false; } } // NON-Vulkan block ends. diff --git a/lib/sdl3/SDL/src/video/psp/SDL_pspvideo.c b/lib/sdl3/SDL/src/video/psp/SDL_pspvideo.c index 2458235..afdb6bb 100644 --- a/lib/sdl3/SDL/src/video/psp/SDL_pspvideo.c +++ b/lib/sdl3/SDL/src/video/psp/SDL_pspvideo.c @@ -118,6 +118,8 @@ static SDL_VideoDevice *PSP_Create(void) device->PumpEvents = PSP_PumpEvents; + device->device_caps = VIDEO_DEVICE_CAPS_FULLSCREEN_ONLY; + return device; } diff --git a/lib/sdl3/SDL/src/video/stb_image.h b/lib/sdl3/SDL/src/video/stb_image.h index f22de1b..f7c7101 100644 --- a/lib/sdl3/SDL/src/video/stb_image.h +++ b/lib/sdl3/SDL/src/video/stb_image.h @@ -100,7 +100,7 @@ RECENT REVISION HISTORY: Bug & warning fixes Marc LeBlanc David Woo Guillaume George Martins Mozeiko Christpher Lloyd Jerry Jansson Joseph Thomson Blazej Dariusz Roszkowski - Phil Jordan Dave Moore Roy Eltham + Phil Jordan Henner Zeller Dave Moore Roy Eltham Hayaki Saito Nathan Reed Won Chun Luke Graham Johan Duparc Nick Verigakis the Horde3D community Thomas Ruf Ronny Chevalier github:rlyeh @@ -1914,6 +1914,7 @@ static unsigned char *stbi__convert_format(unsigned char *data, int img_n, int r int i,j; unsigned char *good; + if (data == NULL) return data; if (req_comp == img_n) return data; STBI_ASSERT(req_comp >= 1 && req_comp <= 4); diff --git a/lib/sdl3/SDL/src/video/uikit/SDL_uikitmessagebox.m b/lib/sdl3/SDL/src/video/uikit/SDL_uikitmessagebox.m index a57b3f7..b96f5fd 100644 --- a/lib/sdl3/SDL/src/video/uikit/SDL_uikitmessagebox.m +++ b/lib/sdl3/SDL/src/video/uikit/SDL_uikitmessagebox.m @@ -124,31 +124,30 @@ static BOOL UIKit_ShowMessageBoxAlertController(const SDL_MessageBoxData *messag return YES; } -static void UIKit_ShowMessageBoxImpl(const SDL_MessageBoxData *messageboxdata, int *buttonID, int *result) +typedef struct UIKit_ShowMessageBoxData +{ + const SDL_MessageBoxData *messageboxdata; + int *buttonID; + bool result; +} UIKit_ShowMessageBoxData; + +static void SDLCALL UIKit_ShowMessageBoxMainThreadCallback(void *userdata) { @autoreleasepool { - if (UIKit_ShowMessageBoxAlertController(messageboxdata, buttonID)) { - *result = true; - } else { - *result = SDL_SetError("Could not show message box."); - } + UIKit_ShowMessageBoxData *data = (UIKit_ShowMessageBoxData *) userdata; + data->result = UIKit_ShowMessageBoxAlertController(data->messageboxdata, data->buttonID); } } bool UIKit_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonID) { - @autoreleasepool { - __block int result = true; - - if ([NSThread isMainThread]) { - UIKit_ShowMessageBoxImpl(messageboxdata, buttonID, &result); - } else { - dispatch_sync(dispatch_get_main_queue(), ^{ - UIKit_ShowMessageBoxImpl(messageboxdata, buttonID, &result); - }); - } - return result; + UIKit_ShowMessageBoxData data = { messageboxdata, buttonID, false }; + if (!SDL_RunOnMainThread(UIKit_ShowMessageBoxMainThreadCallback, &data, true)) { + return false; + } else if (!data.result) { + return SDL_SetError("Could not show message box."); } + return true; } #endif // SDL_VIDEO_DRIVER_UIKIT diff --git a/lib/sdl3/SDL/src/video/uikit/SDL_uikitview.m b/lib/sdl3/SDL/src/video/uikit/SDL_uikitview.m index ba3b09b..ed649b1 100644 --- a/lib/sdl3/SDL/src/video/uikit/SDL_uikitview.m +++ b/lib/sdl3/SDL/src/video/uikit/SDL_uikitview.m @@ -240,7 +240,7 @@ extern int SDL_AppleTVRemoteOpenedAsJoystick; int i; SDL_MouseButtonFlags buttons = SDL_GetMouseState(NULL, NULL); - for (i = 0; i < MAX_MOUSE_BUTTONS; ++i) { + for (i = 1; i <= MAX_MOUSE_BUTTONS; ++i) { if (buttons & SDL_BUTTON_MASK(i)) { SDL_SendMouseButton(UIKit_GetEventTimestamp([touch timestamp]), sdlwindow, SDL_GLOBAL_MOUSE_ID, (Uint8)i, false); } diff --git a/lib/sdl3/SDL/src/video/vita/SDL_vitavideo.c b/lib/sdl3/SDL/src/video/vita/SDL_vitavideo.c index 6b5dbd7..3455dba 100644 --- a/lib/sdl3/SDL/src/video/vita/SDL_vitavideo.c +++ b/lib/sdl3/SDL/src/video/vita/SDL_vitavideo.c @@ -153,6 +153,8 @@ static SDL_VideoDevice *VITA_Create(void) device->PumpEvents = VITA_PumpEvents; + device->device_caps = VIDEO_DEVICE_CAPS_FULLSCREEN_ONLY; + return device; } diff --git a/lib/sdl3/SDL/src/video/vita/SDL_vitavideo.h b/lib/sdl3/SDL/src/video/vita/SDL_vitavideo.h index 268bed8..f5b397b 100644 --- a/lib/sdl3/SDL/src/video/vita/SDL_vitavideo.h +++ b/lib/sdl3/SDL/src/video/vita/SDL_vitavideo.h @@ -60,8 +60,6 @@ extern SDL_Window *Vita_Window; // Display and window functions extern bool VITA_VideoInit(SDL_VideoDevice *_this); extern void VITA_VideoQuit(SDL_VideoDevice *_this); -extern bool VITA_GetDisplayModes(SDL_VideoDevice *_this, SDL_VideoDisplay *display); -extern bool VITA_SetDisplayMode(SDL_VideoDevice *_this, SDL_VideoDisplay *display, SDL_DisplayMode *mode); extern bool VITA_CreateWindow(SDL_VideoDevice *_this, SDL_Window *window, SDL_PropertiesID create_props); extern void VITA_SetWindowTitle(SDL_VideoDevice *_this, SDL_Window *window); extern bool VITA_SetWindowPosition(SDL_VideoDevice *_this, SDL_Window *window); diff --git a/lib/sdl3/SDL/src/video/wayland/SDL_waylandevents.c b/lib/sdl3/SDL/src/video/wayland/SDL_waylandevents.c index 06d1aeb..291a467 100644 --- a/lib/sdl3/SDL/src/video/wayland/SDL_waylandevents.c +++ b/lib/sdl3/SDL/src/video/wayland/SDL_waylandevents.c @@ -163,16 +163,9 @@ static bool Wayland_SurfaceHasActiveTouches(struct wl_surface *surface) static Uint64 Wayland_GetEventTimestamp(Uint64 nsTimestamp) { - static Uint64 last; - static Uint64 timestamp_offset; + static Uint64 timestamp_offset = 0; const Uint64 now = SDL_GetTicksNS(); - if (nsTimestamp < last) { - // 32-bit timer rollover, bump the offset - timestamp_offset += SDL_MS_TO_NS(0x100000000LLU); - } - last = nsTimestamp; - if (!timestamp_offset) { timestamp_offset = (now - nsTimestamp); } @@ -196,19 +189,24 @@ static const struct zwp_input_timestamps_v1_listener timestamp_listener = { Wayland_input_timestamp_listener }; +static Uint64 Wayland_EventTimestampMSToNS(Uint32 wl_timestamp_ms) +{ + static Uint64 timestamp_offset = 0; + static Uint32 last = 0; + + // Handle 32-bit timer rollover. + if (wl_timestamp_ms < last) { + timestamp_offset += SDL_MS_TO_NS(SDL_UINT64_C(0x100000000)); + } + last = wl_timestamp_ms; + + return SDL_MS_TO_NS(wl_timestamp_ms) + timestamp_offset; +} + static Uint64 Wayland_GetKeyboardTimestamp(struct SDL_WaylandInput *input, Uint32 wl_timestamp_ms) { if (wl_timestamp_ms) { - return Wayland_GetEventTimestamp(input->keyboard_timestamp_ns ? input->keyboard_timestamp_ns : SDL_MS_TO_NS(wl_timestamp_ms)); - } - - return 0; -} - -static Uint64 Wayland_GetKeyboardTimestampRaw(struct SDL_WaylandInput *input, Uint32 wl_timestamp_ms) -{ - if (wl_timestamp_ms) { - return input->keyboard_timestamp_ns ? input->keyboard_timestamp_ns : SDL_MS_TO_NS(wl_timestamp_ms); + return Wayland_GetEventTimestamp(input->keyboard_timestamp_ns ? input->keyboard_timestamp_ns : Wayland_EventTimestampMSToNS(wl_timestamp_ms)); } return 0; @@ -217,7 +215,7 @@ static Uint64 Wayland_GetKeyboardTimestampRaw(struct SDL_WaylandInput *input, Ui static Uint64 Wayland_GetPointerTimestamp(struct SDL_WaylandInput *input, Uint32 wl_timestamp_ms) { if (wl_timestamp_ms) { - return Wayland_GetEventTimestamp(input->pointer_timestamp_ns ? input->pointer_timestamp_ns : SDL_MS_TO_NS(wl_timestamp_ms)); + return Wayland_GetEventTimestamp(input->pointer_timestamp_ns ? input->pointer_timestamp_ns : Wayland_EventTimestampMSToNS(wl_timestamp_ms)); } return 0; @@ -226,7 +224,7 @@ static Uint64 Wayland_GetPointerTimestamp(struct SDL_WaylandInput *input, Uint32 Uint64 Wayland_GetTouchTimestamp(struct SDL_WaylandInput *input, Uint32 wl_timestamp_ms) { if (wl_timestamp_ms) { - return Wayland_GetEventTimestamp(input->touch_timestamp_ns ? input->touch_timestamp_ns : SDL_MS_TO_NS(wl_timestamp_ms)); + return Wayland_GetEventTimestamp(input->touch_timestamp_ns ? input->touch_timestamp_ns : Wayland_EventTimestampMSToNS(wl_timestamp_ms)); } return 0; @@ -269,10 +267,11 @@ void Wayland_CreateCursorShapeDevice(struct SDL_WaylandInput *input) static bool keyboard_repeat_handle(SDL_WaylandKeyboardRepeat *repeat_info, Uint64 elapsed) { bool ret = false; + while (elapsed >= repeat_info->next_repeat_ns) { if (repeat_info->scancode != SDL_SCANCODE_UNKNOWN) { - const Uint64 timestamp = repeat_info->wl_press_time_ns + repeat_info->next_repeat_ns; - SDL_SendKeyboardKeyIgnoreModifiers(Wayland_GetEventTimestamp(timestamp), repeat_info->keyboard_id, repeat_info->key, repeat_info->scancode, true); + const Uint64 timestamp = repeat_info->base_time_ns + repeat_info->next_repeat_ns; + SDL_SendKeyboardKeyIgnoreModifiers(timestamp, repeat_info->keyboard_id, repeat_info->key, repeat_info->scancode, true); } if (repeat_info->text[0]) { SDL_SendKeyboardText(repeat_info->text); @@ -291,8 +290,8 @@ static void keyboard_repeat_clear(SDL_WaylandKeyboardRepeat *repeat_info) repeat_info->is_key_down = false; } -static void keyboard_repeat_set(SDL_WaylandKeyboardRepeat *repeat_info, Uint32 keyboard_id, uint32_t key, Uint64 wl_press_time_ns, - uint32_t scancode, bool has_text, char text[8]) +static void keyboard_repeat_set(SDL_WaylandKeyboardRepeat *repeat_info, Uint32 keyboard_id, uint32_t key, Uint32 wl_press_time_ms, + Uint64 base_time_ns, uint32_t scancode, bool has_text, char text[8]) { if (!repeat_info->is_initialized || !repeat_info->repeat_rate) { return; @@ -300,12 +299,13 @@ static void keyboard_repeat_set(SDL_WaylandKeyboardRepeat *repeat_info, Uint32 k repeat_info->is_key_down = true; repeat_info->keyboard_id = keyboard_id; repeat_info->key = key; - repeat_info->wl_press_time_ns = wl_press_time_ns; + repeat_info->wl_press_time_ms = wl_press_time_ms; + repeat_info->base_time_ns = base_time_ns; repeat_info->sdl_press_time_ns = SDL_GetTicksNS(); repeat_info->next_repeat_ns = SDL_MS_TO_NS(repeat_info->repeat_delay_ms); repeat_info->scancode = scancode; if (has_text) { - SDL_copyp(repeat_info->text, text); + SDL_memcpy(repeat_info->text, text, sizeof(repeat_info->text)); } else { repeat_info->text[0] = '\0'; } @@ -598,11 +598,11 @@ static void pointer_handle_leave(void *data, struct wl_pointer *pointer, wind->sdlwindow->flags &= ~SDL_WINDOW_MOUSE_CAPTURE; input->buttons_pressed = 0; - SDL_SendMouseButton(Wayland_GetPointerTimestamp(input, 0), wind->sdlwindow, input->pointer_id, SDL_BUTTON_LEFT, false); - SDL_SendMouseButton(Wayland_GetPointerTimestamp(input, 0), wind->sdlwindow, input->pointer_id, SDL_BUTTON_RIGHT, false); - SDL_SendMouseButton(Wayland_GetPointerTimestamp(input, 0), wind->sdlwindow, input->pointer_id, SDL_BUTTON_MIDDLE, false); - SDL_SendMouseButton(Wayland_GetPointerTimestamp(input, 0), wind->sdlwindow, input->pointer_id, SDL_BUTTON_X1, false); - SDL_SendMouseButton(Wayland_GetPointerTimestamp(input, 0), wind->sdlwindow, input->pointer_id, SDL_BUTTON_X2, false); + SDL_SendMouseButton(0, wind->sdlwindow, input->pointer_id, SDL_BUTTON_LEFT, false); + SDL_SendMouseButton(0, wind->sdlwindow, input->pointer_id, SDL_BUTTON_RIGHT, false); + SDL_SendMouseButton(0, wind->sdlwindow, input->pointer_id, SDL_BUTTON_MIDDLE, false); + SDL_SendMouseButton(0, wind->sdlwindow, input->pointer_id, SDL_BUTTON_X1, false); + SDL_SendMouseButton(0, wind->sdlwindow, input->pointer_id, SDL_BUTTON_X2, false); } /* A pointer leave event may be emitted if the compositor hides the pointer in response to receiving a touch event. @@ -1199,7 +1199,7 @@ static void touch_handler_motion(void *data, struct wl_touch *touch, uint32_t ti const float x = (float)wl_fixed_to_double(fx) / window_data->current.logical_width; const float y = (float)wl_fixed_to_double(fy) / window_data->current.logical_height; - SDL_SendTouchMotion(Wayland_GetPointerTimestamp(input, timestamp), (SDL_TouchID)(uintptr_t)touch, + SDL_SendTouchMotion(Wayland_GetTouchTimestamp(input, timestamp), (SDL_TouchID)(uintptr_t)touch, (SDL_FingerID)(id + 1), window_data->sdlwindow, x, y, 1.0f); } } @@ -1855,7 +1855,7 @@ static void keyboard_handle_key(void *data, struct wl_keyboard *keyboard, char text[8]; bool has_text = false; bool handled_by_ime = false; - const Uint64 timestamp_raw_ns = Wayland_GetKeyboardTimestampRaw(input, time); + const Uint64 timestamp_ns = Wayland_GetKeyboardTimestamp(input, time); Wayland_UpdateImplicitGrabSerial(input, serial); @@ -1871,7 +1871,8 @@ static void keyboard_handle_key(void *data, struct wl_keyboard *keyboard, * Using SDL_GetTicks would be wrong, as it would report when the release event is processed, * which may be off if the application hasn't pumped events for a while. */ - keyboard_repeat_handle(&input->keyboard_repeat, timestamp_raw_ns - input->keyboard_repeat.wl_press_time_ns); + const Uint64 elapsed = SDL_MS_TO_NS(time - input->keyboard_repeat.wl_press_time_ms); + keyboard_repeat_handle(&input->keyboard_repeat, elapsed); keyboard_repeat_clear(&input->keyboard_repeat); } keyboard_input_get_text(text, input, key, false, &handled_by_ime); @@ -1879,9 +1880,8 @@ static void keyboard_handle_key(void *data, struct wl_keyboard *keyboard, const SDL_Scancode scancode = Wayland_GetScancodeForKey(input, key); Wayland_HandleModifierKeys(input, scancode, state == WL_KEYBOARD_KEY_STATE_PRESSED); - Uint64 timestamp = Wayland_GetKeyboardTimestamp(input, time); - SDL_SendKeyboardKeyIgnoreModifiers(timestamp, input->keyboard_id, key, scancode, state == WL_KEYBOARD_KEY_STATE_PRESSED); + SDL_SendKeyboardKeyIgnoreModifiers(timestamp_ns, input->keyboard_id, key, scancode, state == WL_KEYBOARD_KEY_STATE_PRESSED); if (state == WL_KEYBOARD_KEY_STATE_PRESSED) { if (has_text && !(SDL_GetModState() & (SDL_KMOD_CTRL | SDL_KMOD_ALT))) { @@ -1890,7 +1890,7 @@ static void keyboard_handle_key(void *data, struct wl_keyboard *keyboard, } } if (input->xkb.keymap && WAYLAND_xkb_keymap_key_repeats(input->xkb.keymap, key + 8)) { - keyboard_repeat_set(&input->keyboard_repeat, input->keyboard_id, key, timestamp_raw_ns, scancode, has_text, text); + keyboard_repeat_set(&input->keyboard_repeat, input->keyboard_id, key, time, timestamp_ns, scancode, has_text, text); } } } @@ -2951,7 +2951,7 @@ static void tablet_tool_handle_frame(void *data, struct zwp_tablet_tool_v2 *tool return; // Not a pen we report on. } - const Uint64 timestamp = Wayland_GetEventTimestamp(SDL_MS_TO_NS(time)); + const Uint64 timestamp = Wayland_GetEventTimestamp(Wayland_EventTimestampMSToNS(time)); const SDL_PenID instance_id = sdltool->instance_id; SDL_Window *window = sdltool->tool_focus; diff --git a/lib/sdl3/SDL/src/video/wayland/SDL_waylandevents_c.h b/lib/sdl3/SDL/src/video/wayland/SDL_waylandevents_c.h index 6158882..d961b37 100644 --- a/lib/sdl3/SDL/src/video/wayland/SDL_waylandevents_c.h +++ b/lib/sdl3/SDL/src/video/wayland/SDL_waylandevents_c.h @@ -49,17 +49,18 @@ typedef struct SDL_WaylandTabletInput typedef struct { - int32_t repeat_rate; // Repeat rate in range of [1, 1000] character(s) per second - int32_t repeat_delay_ms; // Time to first repeat event in milliseconds - Uint32 keyboard_id; // ID of the source keyboard. + Sint32 repeat_rate; // Repeat rate in range of [1, 1000] character(s) per second + Sint32 repeat_delay_ms; // Time to first repeat event in milliseconds + Uint32 keyboard_id; // ID of the source keyboard. bool is_initialized; bool is_key_down; - uint32_t key; - Uint64 wl_press_time_ns; // Key press time as reported by the Wayland API + Uint32 key; + Uint32 wl_press_time_ms; // Key press time as reported by the Wayland API in milliseconds + Uint64 base_time_ns; // Key press time as reported by the Wayland API in nanoseconds Uint64 sdl_press_time_ns; // Key press time expressed in SDL ticks Uint64 next_repeat_ns; // Next repeat event in nanoseconds - uint32_t scancode; + Uint32 scancode; char text[8]; } SDL_WaylandKeyboardRepeat; diff --git a/lib/sdl3/SDL/src/video/wayland/SDL_waylandkeyboard.c b/lib/sdl3/SDL/src/video/wayland/SDL_waylandkeyboard.c index df1628c..6712f9d 100644 --- a/lib/sdl3/SDL/src/video/wayland/SDL_waylandkeyboard.c +++ b/lib/sdl3/SDL/src/video/wayland/SDL_waylandkeyboard.c @@ -58,7 +58,7 @@ bool Wayland_StartTextInput(SDL_VideoDevice *_this, SDL_Window *window, SDL_Prop if (internal->text_input_manager) { if (input && input->text_input) { - const SDL_Rect *rect = &input->text_input->cursor_rect; + const SDL_Rect *rect = &input->text_input->text_input_rect; enum zwp_text_input_v3_content_hint hint = ZWP_TEXT_INPUT_V3_CONTENT_HINT_NONE; enum zwp_text_input_v3_content_purpose purpose; @@ -125,12 +125,21 @@ bool Wayland_StartTextInput(SDL_VideoDevice *_this, SDL_Window *window, SDL_Prop // Now that it's enabled, set the input properties zwp_text_input_v3_set_content_type(input->text_input->text_input, hint, purpose); if (!SDL_RectEmpty(rect)) { - // This gets reset on enable so we have to cache it + SDL_WindowData *wind = window->internal; + const SDL_Rect scaled_rect = { + (int)SDL_floor(window->text_input_rect.x / wind->pointer_scale.x), + (int)SDL_floor(window->text_input_rect.y / wind->pointer_scale.y), + (int)SDL_ceil(window->text_input_rect.w / wind->pointer_scale.x), + (int)SDL_ceil(window->text_input_rect.h / wind->pointer_scale.y) + }; + const int scaled_cursor = (int)SDL_floor(window->text_input_cursor / wind->pointer_scale.x); + + // Clamp the x value so it doesn't run too far past the end of the text input area. zwp_text_input_v3_set_cursor_rectangle(input->text_input->text_input, - rect->x, - rect->y, - rect->w, - rect->h); + SDL_min(scaled_rect.x + scaled_cursor, scaled_rect.x + scaled_rect.w), + scaled_rect.y, + 1, + scaled_rect.h); } zwp_text_input_v3_commit(input->text_input->text_input); } @@ -174,13 +183,24 @@ bool Wayland_UpdateTextInputArea(SDL_VideoDevice *_this, SDL_Window *window) if (internal->text_input_manager) { struct SDL_WaylandInput *input = internal->input; if (input && input->text_input) { - if (!SDL_RectsEqual(&window->text_input_rect, &input->text_input->cursor_rect)) { - SDL_copyp(&input->text_input->cursor_rect, &window->text_input_rect); + SDL_WindowData *wind = window->internal; + const SDL_Rect scaled_rect = { + (int)SDL_floor(window->text_input_rect.x / wind->pointer_scale.x), + (int)SDL_floor(window->text_input_rect.y / wind->pointer_scale.y), + (int)SDL_ceil(window->text_input_rect.w / wind->pointer_scale.x), + (int)SDL_ceil(window->text_input_rect.h / wind->pointer_scale.y) + }; + const int scaled_cursor = (int)SDL_floor(window->text_input_cursor / wind->pointer_scale.x); + if (!SDL_RectsEqual(&scaled_rect, &input->text_input->text_input_rect) || scaled_cursor != input->text_input->text_input_cursor) { + SDL_copyp(&input->text_input->text_input_rect, &scaled_rect); + input->text_input->text_input_cursor = scaled_cursor; + + // Clamp the x value so it doesn't run too far past the end of the text input area. zwp_text_input_v3_set_cursor_rectangle(input->text_input->text_input, - window->text_input_rect.x, - window->text_input_rect.y, - window->text_input_rect.w, - window->text_input_rect.h); + SDL_min(scaled_rect.x + scaled_cursor, scaled_rect.x + scaled_rect.w), + scaled_rect.y, + 1, + scaled_rect.h); zwp_text_input_v3_commit(input->text_input->text_input); } } diff --git a/lib/sdl3/SDL/src/video/wayland/SDL_waylandkeyboard.h b/lib/sdl3/SDL/src/video/wayland/SDL_waylandkeyboard.h index f570edb..a1ea076 100644 --- a/lib/sdl3/SDL/src/video/wayland/SDL_waylandkeyboard.h +++ b/lib/sdl3/SDL/src/video/wayland/SDL_waylandkeyboard.h @@ -26,7 +26,8 @@ typedef struct SDL_WaylandTextInput { struct zwp_text_input_v3 *text_input; - SDL_Rect cursor_rect; + SDL_Rect text_input_rect; + int text_input_cursor; bool has_preedit; } SDL_WaylandTextInput; diff --git a/lib/sdl3/SDL/src/video/wayland/SDL_waylandvideo.c b/lib/sdl3/SDL/src/video/wayland/SDL_waylandvideo.c index 4301953..47971e6 100644 --- a/lib/sdl3/SDL/src/video/wayland/SDL_waylandvideo.c +++ b/lib/sdl3/SDL/src/video/wayland/SDL_waylandvideo.c @@ -446,9 +446,6 @@ static void Wayland_DeleteDevice(SDL_VideoDevice *device) WAYLAND_wl_display_disconnect(data->display); SDL_ClearProperty(SDL_GetGlobalProperties(), SDL_PROP_GLOBAL_VIDEO_WAYLAND_WL_DISPLAY_POINTER); } - if (device->wakeup_lock) { - SDL_DestroyMutex(device->wakeup_lock); - } SDL_free(data); SDL_free(device); SDL_WAYLAND_UnloadSymbols(); @@ -589,7 +586,6 @@ static SDL_VideoDevice *Wayland_CreateDevice(bool require_preferred_protocols) } device->internal = data; - device->wakeup_lock = SDL_CreateMutex(); // Set the function pointers device->VideoInit = Wayland_VideoInit; diff --git a/lib/sdl3/SDL/src/video/wayland/SDL_waylandwindow.c b/lib/sdl3/SDL/src/video/wayland/SDL_waylandwindow.c index 523d2e4..1fea144 100644 --- a/lib/sdl3/SDL/src/video/wayland/SDL_waylandwindow.c +++ b/lib/sdl3/SDL/src/video/wayland/SDL_waylandwindow.c @@ -2055,6 +2055,10 @@ void Wayland_ShowWindow(SDL_VideoDevice *_this, SDL_Window *window) struct wl_callback *cb = wl_display_sync(_this->internal->display); wl_callback_add_listener(cb, &show_hide_sync_listener, (void*)((uintptr_t)window->id)); + data->showing_window = true; + SDL_SendWindowEvent(window, SDL_EVENT_WINDOW_SHOWN, 0, 0); + data->showing_window = false; + // Send an exposure event to signal that the client should draw. if (data->shell_surface_status == WAYLAND_SHELL_SURFACE_STATUS_WAITING_FOR_FRAME) { SDL_SendWindowEvent(window, SDL_EVENT_WINDOW_EXPOSED, 0, 0); @@ -2277,6 +2281,11 @@ SDL_FullscreenResult Wayland_SetWindowFullscreen(SDL_VideoDevice *_this, SDL_Win return SDL_FULLSCREEN_FAILED; } + // Drop fullscreen leave requests when showing the window. + if (wind->showing_window && fullscreen == SDL_FULLSCREEN_OP_LEAVE) { + return SDL_FULLSCREEN_SUCCEEDED; + } + if (wind->show_hide_sync_required) { WAYLAND_wl_display_roundtrip(_this->internal->display); } @@ -2331,6 +2340,11 @@ void Wayland_RestoreWindow(SDL_VideoDevice *_this, SDL_Window *window) { SDL_WindowData *wind = window->internal; + // Drop restore requests when showing the window. + if (wind->showing_window) { + return; + } + // Not currently fullscreen or maximized, and no state pending; nothing to do. if (!(window->flags & (SDL_WINDOW_FULLSCREEN | SDL_WINDOW_MAXIMIZED)) && !wind->fullscreen_deadline_count && !wind->maximized_restored_deadline_count) { diff --git a/lib/sdl3/SDL/src/video/wayland/SDL_waylandwindow.h b/lib/sdl3/SDL/src/video/wayland/SDL_waylandwindow.h index 619fd79..ee27f33 100644 --- a/lib/sdl3/SDL/src/video/wayland/SDL_waylandwindow.h +++ b/lib/sdl3/SDL/src/video/wayland/SDL_waylandwindow.h @@ -198,6 +198,7 @@ struct SDL_WindowData bool is_fullscreen; bool fullscreen_exclusive; bool drop_fullscreen_requests; + bool showing_window; bool fullscreen_was_positioned; bool show_hide_sync_required; bool scale_to_display; diff --git a/lib/sdl3/SDL/src/video/windows/SDL_windowsevents.c b/lib/sdl3/SDL/src/video/windows/SDL_windowsevents.c index 175e221..837e0eb 100644 --- a/lib/sdl3/SDL/src/video/windows/SDL_windowsevents.c +++ b/lib/sdl3/SDL/src/video/windows/SDL_windowsevents.c @@ -352,7 +352,7 @@ static void WIN_UpdateMouseCapture(void) } } -static void WIN_UpdateFocus(SDL_Window *window, bool expect_focus) +static void WIN_UpdateFocus(SDL_Window *window, bool expect_focus, DWORD pos) { SDL_WindowData *data = window->internal; HWND hwnd = data->hwnd; @@ -389,7 +389,8 @@ static void WIN_UpdateFocus(SDL_Window *window, bool expect_focus) // In relative mode we are guaranteed to have mouse focus if we have keyboard focus if (!SDL_GetMouse()->relative_mode) { - GetCursorPos(&cursorPos); + cursorPos.x = (LONG)GET_X_LPARAM(pos); + cursorPos.y = (LONG)GET_Y_LPARAM(pos); ScreenToClient(hwnd, &cursorPos); SDL_SendMouseMotion(WIN_GetEventTimestamp(), window, SDL_GLOBAL_MOUSE_ID, false, (float)cursorPos.x, (float)cursorPos.y); } @@ -472,11 +473,6 @@ static SDL_MOUSE_EVENT_SOURCE GetMouseMessageSource(ULONG extrainfo) return SDL_MOUSE_EVENT_SOURCE_PEN; } } - /* Sometimes WM_INPUT events won't have the correct touch signature, - so we have to rely purely on the touch bit being set. */ - if (SDL_TouchDevicesAvailable() && extrainfo & 0x80) { - return SDL_MOUSE_EVENT_SOURCE_TOUCH; - } return SDL_MOUSE_EVENT_SOURCE_MOUSE; } #endif // !defined(SDL_PLATFORM_XBOXONE) && !defined(SDL_PLATFORM_XBOXSERIES) @@ -614,7 +610,8 @@ static void WIN_HandleRawMouseInput(Uint64 timestamp, SDL_VideoData *data, HANDL return; } - if (GetMouseMessageSource(rawmouse->ulExtraInformation) != SDL_MOUSE_EVENT_SOURCE_MOUSE) { + if (GetMouseMessageSource(rawmouse->ulExtraInformation) != SDL_MOUSE_EVENT_SOURCE_MOUSE || + (SDL_TouchDevicesAvailable() && (rawmouse->ulExtraInformation & 0x80) == 0x80)) { return; } @@ -1235,22 +1232,19 @@ LRESULT CALLBACK WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lPara case WM_NCACTIVATE: { // Don't immediately clip the cursor in case we're clicking minimize/maximize buttons - // This is the only place that this flag is set. This causes all subsequent calls to - // WIN_UpdateClipCursor for this window to be no-ops in this frame's message-pumping. - // This flag is unset at the end of message pumping each frame for every window, and - // should never be carried over between frames. - data->skip_update_clipcursor = true; + data->postpone_clipcursor = true; + data->clipcursor_queued = true; /* Update the focus here, since it's possible to get WM_ACTIVATE and WM_SETFOCUS without actually being the foreground window, but this appears to get called in all cases where the global foreground window changes to and from this window. */ - WIN_UpdateFocus(data->window, !!wParam); + WIN_UpdateFocus(data->window, !!wParam, GetMessagePos()); } break; case WM_ACTIVATE: { // Update the focus in case we changed focus to a child window and then away from the application - WIN_UpdateFocus(data->window, !!LOWORD(wParam)); + WIN_UpdateFocus(data->window, !!LOWORD(wParam), GetMessagePos()); } break; case WM_MOUSEACTIVATE: @@ -1273,14 +1267,14 @@ LRESULT CALLBACK WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lPara case WM_SETFOCUS: { // Update the focus in case it's changing between top-level windows in the same application - WIN_UpdateFocus(data->window, true); + WIN_UpdateFocus(data->window, true, GetMessagePos()); } break; case WM_KILLFOCUS: case WM_ENTERIDLE: { // Update the focus in case it's changing between top-level windows in the same application - WIN_UpdateFocus(data->window, false); + WIN_UpdateFocus(data->window, false, GetMessagePos()); } break; case WM_POINTERENTER: @@ -1361,8 +1355,10 @@ LRESULT CALLBACK WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lPara const Uint64 timestamp = WIN_GetEventTimestamp(); SDL_Window *window = data->window; + const bool istouching = IS_POINTER_INCONTACT_WPARAM(wParam) && IS_POINTER_FIRSTBUTTON_WPARAM(wParam); + // if lifting off, do it first, so any motion changes don't cause app issues. - if (msg == WM_POINTERUP) { + if (!istouching) { SDL_SendPenTouch(timestamp, pen, window, (pen_info.penFlags & PEN_FLAG_INVERTED) != 0, false); } @@ -1392,7 +1388,7 @@ LRESULT CALLBACK WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lPara } // if setting down, do it last, so the pen is positioned correctly from the first contact. - if (msg == WM_POINTERDOWN) { + if (istouching) { SDL_SendPenTouch(timestamp, pen, window, (pen_info.penFlags & PEN_FLAG_INVERTED) != 0, true); } @@ -1408,9 +1404,8 @@ LRESULT CALLBACK WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lPara window->flags & (SDL_WINDOW_MOUSE_RELATIVE_MODE | SDL_WINDOW_MOUSE_GRABBED) || (window->mouse_rect.w > 0 && window->mouse_rect.h > 0) ); - if (wish_clip_cursor) { - data->skip_update_clipcursor = false; - WIN_UpdateClipCursor(window); + if (wish_clip_cursor) { // queue clipcursor refresh on pump finish + data->clipcursor_queued = true; } } @@ -1435,6 +1430,7 @@ LRESULT CALLBACK WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lPara SDL_SendMouseMotion(WIN_GetEventTimestamp(), window, SDL_GLOBAL_MOUSE_ID, false, (float)GET_X_LPARAM(lParam), (float)GET_Y_LPARAM(lParam)); } } + } break; case WM_LBUTTONUP: @@ -1498,8 +1494,10 @@ LRESULT CALLBACK WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lPara if (!(data->window->flags & SDL_WINDOW_MOUSE_CAPTURE)) { if (SDL_GetMouseFocus() == data->window && !SDL_GetMouse()->relative_mode && !IsIconic(hwnd)) { SDL_Mouse *mouse; + DWORD pos = GetMessagePos(); POINT cursorPos; - GetCursorPos(&cursorPos); + cursorPos.x = GET_X_LPARAM(pos); + cursorPos.y = GET_Y_LPARAM(pos); ScreenToClient(hwnd, &cursorPos); mouse = SDL_GetMouse(); if (!mouse->was_touch_mouse_events) { // we're not a touch handler causing a mouse leave? @@ -1638,7 +1636,7 @@ LRESULT CALLBACK WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lPara // Reference: https://gamedev.net/forums/topic/672094-keeping-things-moving-during-win32-moveresize-events/5254386/ if (SendMessage(hwnd, WM_NCHITTEST, wParam, lParam) == HTCAPTION) { POINT cursorPos; - GetCursorPos(&cursorPos); + GetCursorPos(&cursorPos); // want the most current pos so as to not cause position change ScreenToClient(hwnd, &cursorPos); PostMessage(hwnd, WM_MOUSEMOVE, 0, cursorPos.x | (((Uint32)((Sint16)cursorPos.y)) << 16)); } @@ -1852,6 +1850,9 @@ LRESULT CALLBACK WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lPara data->initial_size_rect.bottom = data->window->y + data->window->h; SetTimer(hwnd, (UINT_PTR)SDL_IterateMainCallbacks, USER_TIMER_MINIMUM, NULL); + + // Reset the keyboard, as we won't get any key up events during the modal loop + SDL_ResetKeyboard(); } } break; @@ -2590,13 +2591,27 @@ void WIN_PumpEvents(SDL_VideoDevice *_this) } } - // Update the clipping rect in case someone else has stolen it + // fire queued clipcursor refreshes if (_this) { SDL_Window *window = _this->windows; while (window) { + bool refresh_clipcursor = false; SDL_WindowData *data = window->internal; - if (data && data->skip_update_clipcursor) { - data->skip_update_clipcursor = false; + if (data) { + refresh_clipcursor = data->clipcursor_queued; + data->clipcursor_queued = false; // Must be cleared unconditionally. + data->postpone_clipcursor = false; // Must be cleared unconditionally. + // Must happen before UpdateClipCursor. + // Although its occurrence currently + // always coincides with the queuing of + // clipcursor, it is logically distinct + // and this coincidence might no longer + // be true in the future. + // Ergo this placement concordantly + // conveys its unconditionality + // vis-a-vis the queuing of clipcursor. + } + if (refresh_clipcursor) { WIN_UpdateClipCursor(window); } window = window->next; diff --git a/lib/sdl3/SDL/src/video/windows/SDL_windowsvideo.c b/lib/sdl3/SDL/src/video/windows/SDL_windowsvideo.c index 6103d52..841a9ec 100644 --- a/lib/sdl3/SDL/src/video/windows/SDL_windowsvideo.c +++ b/lib/sdl3/SDL/src/video/windows/SDL_windowsvideo.c @@ -120,9 +120,6 @@ static void WIN_DeleteDevice(SDL_VideoDevice *device) SDL_UnloadObject(data->dxgiDLL); } #endif - if (device->wakeup_lock) { - SDL_DestroyMutex(device->wakeup_lock); - } SDL_free(device->internal->rawinput); SDL_free(device->internal); SDL_free(device); @@ -148,7 +145,6 @@ static SDL_VideoDevice *WIN_CreateDevice(void) return NULL; } device->internal = data; - device->wakeup_lock = SDL_CreateMutex(); device->system_theme = WIN_GetSystemTheme(); #if !defined(SDL_PLATFORM_XBOXONE) && !defined(SDL_PLATFORM_XBOXSERIES) diff --git a/lib/sdl3/SDL/src/video/windows/SDL_windowswindow.c b/lib/sdl3/SDL/src/video/windows/SDL_windowswindow.c index 18820f1..da752c0 100644 --- a/lib/sdl3/SDL/src/video/windows/SDL_windowswindow.c +++ b/lib/sdl3/SDL/src/video/windows/SDL_windowswindow.c @@ -348,6 +348,10 @@ bool WIN_SetWindowPositionInternal(SDL_Window *window, UINT flags, SDL_WindowRec // Update any child windows for (child_window = window->first_child; child_window; child_window = child_window->next_sibling) { + if (!child_window->internal) { + // This child window is not yet fully initialized. + continue; + } if (!WIN_SetWindowPositionInternal(child_window, flags, SDL_WINDOWRECT_CURRENT)) { result = false; } @@ -1028,8 +1032,9 @@ void WIN_GetWindowSizeInPixels(SDL_VideoDevice *_this, SDL_Window *window, int * void WIN_ShowWindow(SDL_VideoDevice *_this, SDL_Window *window) { + SDL_WindowData *data = window->internal; + HWND hwnd = data->hwnd; DWORD style; - HWND hwnd; bool bActivate = SDL_GetHintBoolean(SDL_HINT_WINDOW_ACTIVATE_WHEN_SHOWN, true); @@ -1038,17 +1043,30 @@ void WIN_ShowWindow(SDL_VideoDevice *_this, SDL_Window *window) WIN_SetWindowPosition(_this, window); } - hwnd = window->internal->hwnd; + // If the window isn't borderless and will be fullscreen, use the borderless style to hide the initial borders. + if (window->pending_flags & SDL_WINDOW_FULLSCREEN) { + if (!(window->flags & SDL_WINDOW_BORDERLESS)) { + window->flags |= SDL_WINDOW_BORDERLESS; + style = GetWindowLong(hwnd, GWL_STYLE); + style &= ~STYLE_MASK; + style |= GetWindowStyle(window); + SetWindowLong(hwnd, GWL_STYLE, style); + window->flags &= ~SDL_WINDOW_BORDERLESS; + } + } style = GetWindowLong(hwnd, GWL_EXSTYLE); if (style & WS_EX_NOACTIVATE) { bActivate = false; } + + data->showing_window = true; if (bActivate) { ShowWindow(hwnd, SW_SHOW); } else { // Use SetWindowPos instead of ShowWindow to avoid activating the parent window if this is a child window SetWindowPos(hwnd, NULL, 0, 0, 0, 0, window->internal->copybits_flag | SWP_SHOWWINDOW | SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_NOOWNERZORDER); } + data->showing_window = false; if (window->flags & SDL_WINDOW_POPUP_MENU && bActivate) { WIN_SetKeyboardFocus(window, window->parent == SDL_GetKeyboardFocus()); @@ -1207,10 +1225,12 @@ void WIN_RestoreWindow(SDL_VideoDevice *_this, SDL_Window *window) { SDL_WindowData *data = window->internal; if (!(window->flags & SDL_WINDOW_FULLSCREEN)) { - HWND hwnd = data->hwnd; - data->expected_resize = true; - ShowWindow(hwnd, SW_RESTORE); - data->expected_resize = false; + if (!data->showing_window || window->flags & (SDL_WINDOW_MAXIMIZED | SDL_WINDOW_MINIMIZED)) { + HWND hwnd = data->hwnd; + data->expected_resize = true; + ShowWindow(hwnd, SW_RESTORE); + data->expected_resize = false; + } } else { data->windowed_mode_was_maximized = false; } @@ -1218,18 +1238,22 @@ void WIN_RestoreWindow(SDL_VideoDevice *_this, SDL_Window *window) static void WIN_UpdateCornerRoundingForHWND(SDL_VideoDevice *_this, HWND hwnd, DWM_WINDOW_CORNER_PREFERENCE cornerPref) { +#if !defined(SDL_PLATFORM_XBOXONE) && !defined(SDL_PLATFORM_XBOXSERIES) SDL_VideoData *videodata = _this->internal; if (videodata->DwmSetWindowAttribute) { videodata->DwmSetWindowAttribute(hwnd, DWMWA_WINDOW_CORNER_PREFERENCE, &cornerPref, sizeof(cornerPref)); } +#endif } static void WIN_UpdateBorderColorForHWND(SDL_VideoDevice *_this, HWND hwnd, COLORREF colorRef) { +#if !defined(SDL_PLATFORM_XBOXONE) && !defined(SDL_PLATFORM_XBOXSERIES) SDL_VideoData *videodata = _this->internal; if (videodata->DwmSetWindowAttribute) { videodata->DwmSetWindowAttribute(hwnd, DWMWA_BORDER_COLOR, &colorRef, sizeof(colorRef)); } +#endif } /** @@ -1591,7 +1615,7 @@ void WIN_UnclipCursorForWindow(SDL_Window *window) { void WIN_UpdateClipCursor(SDL_Window *window) { SDL_WindowData *data = window->internal; - if (data->in_title_click || data->focus_click_pending || data->skip_update_clipcursor) { + if (data->in_title_click || data->focus_click_pending || data->postpone_clipcursor) { return; } diff --git a/lib/sdl3/SDL/src/video/windows/SDL_windowswindow.h b/lib/sdl3/SDL/src/video/windows/SDL_windowswindow.h index 3d1aaed..73eea72 100644 --- a/lib/sdl3/SDL/src/video/windows/SDL_windowswindow.h +++ b/lib/sdl3/SDL/src/video/windows/SDL_windowswindow.h @@ -78,11 +78,13 @@ struct SDL_WindowData bool in_border_change; bool in_title_click; Uint8 focus_click_pending; - bool skip_update_clipcursor; + bool postpone_clipcursor; + bool clipcursor_queued; bool windowed_mode_was_maximized; bool in_window_deactivation; bool force_ws_maximizebox; bool disable_move_size_events; + bool showing_window; int in_modal_loop; RECT initial_size_rect; RECT cursor_clipped_rect; // last successfully committed clipping rect for this window diff --git a/lib/sdl3/SDL/src/video/x11/SDL_x11dyn.h b/lib/sdl3/SDL/src/video/x11/SDL_x11dyn.h index e9831fc..7cd1e0e 100644 --- a/lib/sdl3/SDL/src/video/x11/SDL_x11dyn.h +++ b/lib/sdl3/SDL/src/video/x11/SDL_x11dyn.h @@ -71,6 +71,9 @@ #ifdef SDL_VIDEO_DRIVER_X11_XSHAPE #include #endif +#ifdef SDL_VIDEO_DRIVER_X11_XTEST +#include +#endif #ifdef __cplusplus extern "C" { diff --git a/lib/sdl3/SDL/src/video/x11/SDL_x11events.c b/lib/sdl3/SDL/src/video/x11/SDL_x11events.c index e674b9a..84e4662 100644 --- a/lib/sdl3/SDL/src/video/x11/SDL_x11events.c +++ b/lib/sdl3/SDL/src/video/x11/SDL_x11events.c @@ -506,17 +506,32 @@ static void X11_DispatchFocusOut(SDL_VideoDevice *_this, SDL_WindowData *data) static void X11_DispatchMapNotify(SDL_WindowData *data) { SDL_Window *window = data->window; - SDL_SendWindowEvent(window, SDL_EVENT_WINDOW_RESTORED, 0, 0); + SDL_SendWindowEvent(window, SDL_EVENT_WINDOW_SHOWN, 0, 0); - if (!(window->flags & SDL_WINDOW_HIDDEN) && (window->flags & SDL_WINDOW_INPUT_FOCUS)) { + data->was_shown = true; + + // This may be sent when restoring a minimized window. + if (window->flags & SDL_WINDOW_MINIMIZED) { + SDL_SendWindowEvent(window, SDL_EVENT_WINDOW_RESTORED, 0, 0); + SDL_SendWindowEvent(data->window, SDL_EVENT_WINDOW_EXPOSED, 0, 0); + } + + if (window->flags & SDL_WINDOW_INPUT_FOCUS) { SDL_UpdateWindowGrab(window); } } static void X11_DispatchUnmapNotify(SDL_WindowData *data) { - SDL_SendWindowEvent(data->window, SDL_EVENT_WINDOW_HIDDEN, 0, 0); - SDL_SendWindowEvent(data->window, SDL_EVENT_WINDOW_MINIMIZED, 0, 0); + SDL_Window *window = data->window; + + // This may be sent when minimizing a window. + if (!window->is_hiding) { + SDL_SendWindowEvent(data->window, SDL_EVENT_WINDOW_MINIMIZED, 0, 0); + SDL_SendWindowEvent(data->window, SDL_EVENT_WINDOW_OCCLUDED, 0, 0); + } else { + SDL_SendWindowEvent(window, SDL_EVENT_WINDOW_HIDDEN, 0, 0); + } } static void DispatchWindowMove(SDL_VideoDevice *_this, const SDL_WindowData *data, const SDL_Point *point) @@ -1096,6 +1111,41 @@ void X11_GetBorderValues(SDL_WindowData *data) } } +void X11_EmitConfigureNotifyEvents(SDL_WindowData *data, XConfigureEvent *xevent) +{ + if (xevent->x != data->last_xconfigure.x || + xevent->y != data->last_xconfigure.y) { + if (!data->size_move_event_flags) { + SDL_Window *w; + int x = xevent->x; + int y = xevent->y; + + data->pending_operation &= ~X11_PENDING_OP_MOVE; + SDL_GlobalToRelativeForWindow(data->window, x, y, &x, &y); + SDL_SendWindowEvent(data->window, SDL_EVENT_WINDOW_MOVED, x, y); + + for (w = data->window->first_child; w; w = w->next_sibling) { + // Don't update hidden child popup windows, their relative position doesn't change + if (SDL_WINDOW_IS_POPUP(w) && !(w->flags & SDL_WINDOW_HIDDEN)) { + X11_UpdateWindowPosition(w, true); + } + } + } + } + + if (xevent->width != data->last_xconfigure.width || + xevent->height != data->last_xconfigure.height) { + if (!data->size_move_event_flags) { + data->pending_operation &= ~X11_PENDING_OP_RESIZE; + SDL_SendWindowEvent(data->window, SDL_EVENT_WINDOW_RESIZED, + xevent->width, + xevent->height); + } + } + + SDL_copyp(&data->last_xconfigure, xevent); +} + static void X11_DispatchEvent(SDL_VideoDevice *_this, XEvent *xevent) { SDL_VideoData *videodata = _this->internal; @@ -1291,8 +1341,10 @@ static void X11_DispatchEvent(SDL_VideoDevice *_this, XEvent *xevent) SDL_SendMouseMotion(0, data->window, SDL_GLOBAL_MOUSE_ID, false, (float)xevent->xcrossing.x, (float)xevent->xcrossing.y); } - // We ungrab in LeaveNotify, so we may need to grab again here - SDL_UpdateWindowGrab(data->window); + // We ungrab in LeaveNotify, so we may need to grab again here, but not if captured, as the capture can be lost. + if (!(data->window->flags & SDL_WINDOW_MOUSE_CAPTURE)) { + SDL_UpdateWindowGrab(data->window); + } X11_ProcessHitTest(_this, data, mouse->last_x, mouse->last_y, true); } break; @@ -1320,7 +1372,7 @@ static void X11_DispatchEvent(SDL_VideoDevice *_this, XEvent *xevent) xevent->xcrossing.detail != NotifyInferior) { /* In order for interaction with the window decorations and menu to work properly - on Mutter, we need to ungrab the keyboard when the the mouse leaves. */ + on Mutter, we need to ungrab the keyboard when the mouse leaves. */ if (!(data->window->flags & SDL_WINDOW_FULLSCREEN)) { X11_SetWindowKeyboardGrab(_this, data->window, false); } @@ -1447,9 +1499,8 @@ static void X11_DispatchEvent(SDL_VideoDevice *_this, XEvent *xevent) xevent->xconfigure.x, xevent->xconfigure.y, xevent->xconfigure.width, xevent->xconfigure.height); #endif - // Real configure notify events are relative to the parent, synthetic events are absolute. - if (!xevent->xconfigure.send_event) - { + // Real configure notify events are relative to the parent, synthetic events are absolute. + if (!xevent->xconfigure.send_event) { unsigned int NumChildren; Window ChildReturn, Root, Parent; Window *Children; @@ -1462,41 +1513,23 @@ static void X11_DispatchEvent(SDL_VideoDevice *_this, XEvent *xevent) &ChildReturn); } - if (xevent->xconfigure.x != data->last_xconfigure.x || - xevent->xconfigure.y != data->last_xconfigure.y) { - if (!data->size_move_event_flags) { - SDL_Window *w; - int x = xevent->xconfigure.x; - int y = xevent->xconfigure.y; + /* Xfce sends ConfigureNotify before PropertyNotify when toggling fullscreen and maximized, which + * is backwards from every other window manager, as well as what is expected by SDL and its clients. + * Defer emitting the size/move events until the corresponding PropertyNotify arrives. + */ + const Uint32 changed = X11_GetNetWMState(_this, data->window, xevent->xproperty.window) ^ data->window->flags; + if (changed & (SDL_WINDOW_FULLSCREEN | SDL_WINDOW_MAXIMIZED)) { + SDL_copyp(&data->pending_xconfigure, &xevent->xconfigure); + data->emit_size_move_after_property_notify = true; + } - data->pending_operation &= ~X11_PENDING_OP_MOVE; - SDL_GlobalToRelativeForWindow(data->window, x, y, &x, &y); - SDL_SendWindowEvent(data->window, SDL_EVENT_WINDOW_MOVED, x, y); - - for (w = data->window->first_child; w; w = w->next_sibling) { - // Don't update hidden child popup windows, their relative position doesn't change - if (SDL_WINDOW_IS_POPUP(w) && !(w->flags & SDL_WINDOW_HIDDEN)) { - X11_UpdateWindowPosition(w, true); - } - } - } + if (!data->emit_size_move_after_property_notify) { + X11_EmitConfigureNotifyEvents(data, &xevent->xconfigure); } #ifdef SDL_VIDEO_DRIVER_X11_XSYNC X11_HandleConfigure(data->window, &xevent->xconfigure); #endif /* SDL_VIDEO_DRIVER_X11_XSYNC */ - - if (xevent->xconfigure.width != data->last_xconfigure.width || - xevent->xconfigure.height != data->last_xconfigure.height) { - if (!data->size_move_event_flags) { - data->pending_operation &= ~X11_PENDING_OP_RESIZE; - SDL_SendWindowEvent(data->window, SDL_EVENT_WINDOW_RESIZED, - xevent->xconfigure.width, - xevent->xconfigure.height); - } - } - - data->last_xconfigure = xevent->xconfigure; } break; // Have we been requested to quit (or another client message?) @@ -1782,19 +1815,15 @@ static void X11_DispatchEvent(SDL_VideoDevice *_this, XEvent *xevent) if (xevent->xproperty.atom == data->videodata->atoms._NET_WM_STATE) { /* Get the new state from the window manager. - Compositing window managers can alter visibility of windows - without ever mapping / unmapping them, so we handle that here, - because they use the NETWM protocol to notify us of changes. + * Compositing window managers can alter visibility of windows + * without ever mapping / unmapping them, so we handle that here, + * because they use the NETWM protocol to notify us of changes. */ const SDL_WindowFlags flags = X11_GetNetWMState(_this, data->window, xevent->xproperty.window); const SDL_WindowFlags changed = flags ^ data->window->flags; - if ((changed & (SDL_WINDOW_HIDDEN | SDL_WINDOW_FULLSCREEN)) != 0) { - if (flags & SDL_WINDOW_HIDDEN) { - X11_DispatchUnmapNotify(data); - } else { - X11_DispatchMapNotify(data); - } + if ((changed & SDL_WINDOW_HIDDEN) && !(flags & SDL_WINDOW_HIDDEN)) { + X11_DispatchMapNotify(data); } if (!SDL_WINDOW_IS_POPUP(data->window)) { @@ -1805,6 +1834,8 @@ static void X11_DispatchEvent(SDL_VideoDevice *_this, XEvent *xevent) if (!(flags & SDL_WINDOW_MINIMIZED)) { const bool commit = SDL_memcmp(&data->window->current_fullscreen_mode, &data->requested_fullscreen_mode, sizeof(SDL_DisplayMode)) != 0; + // Ensure the maximized flag is cleared before entering fullscreen. + SDL_SendWindowEvent(data->window, SDL_EVENT_WINDOW_RESTORED, 0, 0); SDL_SendWindowEvent(data->window, SDL_EVENT_WINDOW_ENTER_FULLSCREEN, 0, 0); if (commit) { /* This was initiated by the compositor, or the mode was changed between the request and the window @@ -1896,6 +1927,10 @@ static void X11_DispatchEvent(SDL_VideoDevice *_this, XEvent *xevent) } } } + if (data->emit_size_move_after_property_notify) { + X11_EmitConfigureNotifyEvents(data, &data->pending_xconfigure); + data->emit_size_move_after_property_notify = false; + } if ((flags & SDL_WINDOW_INPUT_FOCUS)) { if (data->pending_move) { DispatchWindowMove(_this, data, &data->pending_move_point); diff --git a/lib/sdl3/SDL/src/video/x11/SDL_x11keyboard.c b/lib/sdl3/SDL/src/video/x11/SDL_x11keyboard.c index c48e829..2534092 100644 --- a/lib/sdl3/SDL/src/video/x11/SDL_x11keyboard.c +++ b/lib/sdl3/SDL/src/video/x11/SDL_x11keyboard.c @@ -762,7 +762,9 @@ void X11_ShowScreenKeyboard(SDL_VideoDevice *_this, SDL_Window *window, SDL_Prop break; } (void)SDL_snprintf(deeplink, sizeof(deeplink), - "steam://open/keyboard?XPosition=0&YPosition=0&Width=0&Height=0&Mode=%d", + "steam://open/keyboard?XPosition=%i&YPosition=%i&Width=%i&Height=%i&Mode=%d", + window->text_input_rect.x, window->text_input_rect.y, + window->text_input_rect.w, window->text_input_rect.h, mode); SDL_OpenURL(deeplink); videodata->steam_keyboard_open = true; diff --git a/lib/sdl3/SDL/src/video/x11/SDL_x11messagebox.c b/lib/sdl3/SDL/src/video/x11/SDL_x11messagebox.c index 8aa1c6a..ab2174e 100644 --- a/lib/sdl3/SDL/src/video/x11/SDL_x11messagebox.c +++ b/lib/sdl3/SDL/src/video/x11/SDL_x11messagebox.c @@ -425,6 +425,13 @@ static bool X11_MessageBoxCreateWindow(SDL_MessageBoxDataX11 *data) Display *display = data->display; SDL_WindowData *windowdata = NULL; const SDL_MessageBoxData *messageboxdata = data->messageboxdata; +#ifdef SDL_VIDEO_DRIVER_X11_XRANDR +#ifdef XRANDR_DISABLED_BY_DEFAULT + const bool use_xrandr_by_default = false; +#else + const bool use_xrandr_by_default = true; +#endif +#endif if (messageboxdata->window) { SDL_DisplayData *displaydata = SDL_GetDisplayDriverDataForWindow(messageboxdata->window); @@ -497,7 +504,17 @@ static bool X11_MessageBoxCreateWindow(SDL_MessageBoxDataX11 *data) const SDL_DisplayData *dpydata = dpy->internal; x = dpydata->x + ((dpy->current_mode->w - data->dialog_width) / 2); y = dpydata->y + ((dpy->current_mode->h - data->dialog_height) / 3); - } else { // oh well. This will misposition on a multi-head setup. Init first next time. + } +#ifdef SDL_VIDEO_DRIVER_X11_XRANDR + else if (SDL_GetHintBoolean(SDL_HINT_VIDEO_X11_XRANDR, use_xrandr_by_default)) { + XRRScreenResources *screen = X11_XRRGetScreenResourcesCurrent(display, DefaultRootWindow(display)); + XRRCrtcInfo *crtc_info = X11_XRRGetCrtcInfo(display, screen, screen->crtcs[0]); + x = (crtc_info->width - data->dialog_width) / 2; + y = (crtc_info->height - data->dialog_height) / 3; + } +#endif + else { + // oh well. This will misposition on a multi-head setup. Init first next time. x = (DisplayWidth(display, data->screen) - data->dialog_width) / 2; y = (DisplayHeight(display, data->screen) - data->dialog_height) / 3; } diff --git a/lib/sdl3/SDL/src/video/x11/SDL_x11pen.c b/lib/sdl3/SDL/src/video/x11/SDL_x11pen.c index f16da51..c29c629 100644 --- a/lib/sdl3/SDL/src/video/x11/SDL_x11pen.c +++ b/lib/sdl3/SDL/src/video/x11/SDL_x11pen.c @@ -283,14 +283,16 @@ static X11_PenHandle *X11_MaybeAddPen(SDL_VideoDevice *_this, const XIDeviceInfo X11_PenHandle *X11_MaybeAddPenByDeviceID(SDL_VideoDevice *_this, int deviceid) { - SDL_VideoData *data = _this->internal; - int num_device_info = 0; - XIDeviceInfo *device_info = X11_XIQueryDevice(data->display, deviceid, &num_device_info); - if (device_info) { - SDL_assert(num_device_info == 1); - X11_PenHandle *handle = X11_MaybeAddPen(_this, device_info); - X11_XIFreeDeviceInfo(device_info); - return handle; + if (X11_Xinput2IsInitialized()) { + SDL_VideoData *data = _this->internal; + int num_device_info = 0; + XIDeviceInfo *device_info = X11_XIQueryDevice(data->display, deviceid, &num_device_info); + if (device_info) { + SDL_assert(num_device_info == 1); + X11_PenHandle *handle = X11_MaybeAddPen(_this, device_info); + X11_XIFreeDeviceInfo(device_info); + return handle; + } } return NULL; } @@ -306,6 +308,10 @@ void X11_RemovePenByDeviceID(int deviceid) void X11_InitPen(SDL_VideoDevice *_this) { + if (!X11_Xinput2IsInitialized()) { + return; // we need XIQueryDevice() for this. + } + SDL_VideoData *data = _this->internal; #define LOOKUP_PEN_ATOM(X) X11_XInternAtom(data->display, X, False) diff --git a/lib/sdl3/SDL/src/video/x11/SDL_x11video.c b/lib/sdl3/SDL/src/video/x11/SDL_x11video.c index 75862db..86f5b86 100644 --- a/lib/sdl3/SDL/src/video/x11/SDL_x11video.c +++ b/lib/sdl3/SDL/src/video/x11/SDL_x11video.c @@ -63,9 +63,6 @@ static void X11_DeleteDevice(SDL_VideoDevice *device) X11_XCloseDisplay(data->request_display); } SDL_free(data->windowlist); - if (device->wakeup_lock) { - SDL_DestroyMutex(device->wakeup_lock); - } SDL_free(device->internal); SDL_free(device); @@ -78,23 +75,6 @@ static bool X11_IsXWayland(Display *d) return X11_XQueryExtension(d, "XWAYLAND", &opcode, &event, &error) == True; } -static bool X11_CheckCurrentDesktop(const char *name) -{ - SDL_Environment *env = SDL_GetEnvironment(); - - const char *desktopVar = SDL_GetEnvironmentVariable(env, "DESKTOP_SESSION"); - if (desktopVar && SDL_strcasecmp(desktopVar, name) == 0) { - return true; - } - - desktopVar = SDL_GetEnvironmentVariable(env, "XDG_CURRENT_DESKTOP"); - if (desktopVar && SDL_strcasestr(desktopVar, name)) { - return true; - } - - return false; -} - static SDL_VideoDevice *X11_CreateDevice(void) { SDL_VideoDevice *device; @@ -146,8 +126,6 @@ static SDL_VideoDevice *X11_CreateDevice(void) return NULL; } - device->wakeup_lock = SDL_CreateMutex(); - #ifdef X11_DEBUG X11_XSynchronize(data->display, True); #endif @@ -275,17 +253,11 @@ static SDL_VideoDevice *X11_CreateDevice(void) device->device_caps = VIDEO_DEVICE_CAPS_HAS_POPUP_WINDOW_SUPPORT; - /* Openbox doesn't send the new window dimensions when entering fullscreen, so the events must be synthesized. - * This is otherwise not wanted, as it can break fullscreen window positioning on multi-monitor configurations. - */ - if (!X11_CheckCurrentDesktop("openbox")) { - device->device_caps |= VIDEO_DEVICE_CAPS_SENDS_DISPLAY_CHANGES; - } - data->is_xwayland = X11_IsXWayland(x11_display); if (data->is_xwayland) { device->device_caps |= VIDEO_DEVICE_CAPS_MODE_SWITCHING_EMULATED | - VIDEO_DEVICE_CAPS_DISABLE_MOUSE_WARP_ON_FULLSCREEN_TRANSITIONS; + VIDEO_DEVICE_CAPS_DISABLE_MOUSE_WARP_ON_FULLSCREEN_TRANSITIONS | + VIDEO_DEVICE_CAPS_SENDS_FULLSCREEN_DIMENSIONS; } return device; diff --git a/lib/sdl3/SDL/src/video/x11/SDL_x11window.c b/lib/sdl3/SDL/src/video/x11/SDL_x11window.c index e96a5ac..3a6b4ae 100644 --- a/lib/sdl3/SDL/src/video/x11/SDL_x11window.c +++ b/lib/sdl3/SDL/src/video/x11/SDL_x11window.c @@ -534,7 +534,7 @@ bool X11_CreateWindow(SDL_VideoDevice *_this, SDL_Window *window, SDL_Properties } const bool force_override_redirect = SDL_GetHintBoolean(SDL_HINT_X11_FORCE_OVERRIDE_REDIRECT, false); - const bool use_resize_sync = !(window->flags & SDL_WINDOW_VULKAN); /* doesn't work well with Vulkan */ + const bool use_resize_sync = !!(window->flags & SDL_WINDOW_OPENGL); // Doesn't work well with Vulkan SDL_WindowData *windowdata; Display *display = data->display; int screen = displaydata->screen; @@ -934,6 +934,75 @@ static int X11_CatchAnyError(Display *d, XErrorEvent *e) return 0; } +static void X11_ExternalResizeMoveSync(SDL_Window *window) +{ + SDL_WindowData *data = window->internal; + Display *display = data->videodata->display; + int (*prev_handler)(Display *, XErrorEvent *); + unsigned int childCount; + Window childReturn, root, parent; + Window *children; + XWindowAttributes attrs; + Uint64 timeout = 0; + int x, y; + const bool send_move = !!(data->pending_operation & X11_PENDING_OP_MOVE); + const bool send_resize = !!(data->pending_operation & X11_PENDING_OP_RESIZE); + + X11_XSync(display, False); + X11_XQueryTree(display, data->xwindow, &root, &parent, &children, &childCount); + prev_handler = X11_XSetErrorHandler(X11_CatchAnyError); + + /* Wait a brief time to see if the window manager decided to let the move or resize happen. + * If the window changes at all, even to an unexpected value, we break out. + */ + timeout = SDL_GetTicksNS() + SDL_MS_TO_NS(100); + while (true) { + caught_x11_error = false; + X11_XSync(display, False); + X11_XGetWindowAttributes(display, data->xwindow, &attrs); + X11_XTranslateCoordinates(display, parent, DefaultRootWindow(display), + attrs.x, attrs.y, &x, &y, &childReturn); + SDL_GlobalToRelativeForWindow(window, x, y, &x, &y); + + if (!caught_x11_error) { + if ((data->pending_operation & X11_PENDING_OP_MOVE) && (x == data->expected.x + data->border_left && y == data->expected.y + data->border_top)) { + data->pending_operation &= ~X11_PENDING_OP_MOVE; + } + if ((data->pending_operation & X11_PENDING_OP_RESIZE) && (attrs.width == data->expected.w && attrs.height == data->expected.h)) { + data->pending_operation &= ~X11_PENDING_OP_RESIZE; + } + + if (data->pending_operation == X11_PENDING_OP_NONE) { + break; + } + } + + if (SDL_GetTicksNS() >= timeout) { + // Timed out without the expected values. Update the requested data so future sync calls won't block. + data->pending_operation &= ~(X11_PENDING_OP_MOVE | X11_PENDING_OP_RESIZE); + data->expected.x = x; + data->expected.y = y; + data->expected.w = attrs.width; + data->expected.h = attrs.height; + break; + } + + SDL_Delay(10); + } + + if (!caught_x11_error) { + if (send_move) { + SDL_SendWindowEvent(window, SDL_EVENT_WINDOW_MOVED, x, y); + } + if (send_resize) { + SDL_SendWindowEvent(window, SDL_EVENT_WINDOW_RESIZED, attrs.width, attrs.height); + } + } + + X11_XSetErrorHandler(prev_handler); + caught_x11_error = false; +} + /* Wait a brief time, or not, to see if the window manager decided to move/resize the window. * Send MOVED and RESIZED window events */ static bool X11_SyncWindowTimeout(SDL_VideoDevice *_this, SDL_Window *window, Uint64 param_timeout) @@ -1214,9 +1283,10 @@ void X11_SetWindowSize(SDL_VideoDevice *_this, SDL_Window *window) X11_XGetWMNormalHints(display, data->xwindow, sizehints, &userhints); - sizehints->min_width = sizehints->max_width = window->pending.w; - sizehints->min_height = sizehints->max_height = window->pending.h; + data->expected.w = sizehints->min_width = sizehints->max_width = window->pending.w; + data->expected.h = sizehints->min_height = sizehints->max_height = window->pending.h; sizehints->flags |= PMinSize | PMaxSize; + data->pending_operation |= X11_PENDING_OP_RESIZE; X11_XSetWMNormalHints(display, data->xwindow, sizehints); @@ -1504,6 +1574,12 @@ void X11_ShowWindow(SDL_VideoDevice *_this, SDL_Window *window) X11_PumpEvents(_this); data->size_move_event_flags = 0; + /* A MapNotify or PropertyNotify may not have arrived, so ensure that the shown event is dispatched + * to apply pending state before clearing the flag. + */ + SDL_SendWindowEvent(window, SDL_EVENT_WINDOW_SHOWN, 0, 0); + data->was_shown = true; + // If a configure event was received (type is non-zero), send the final window size and coordinates. if (data->last_xconfigure.type) { int x, y; @@ -1695,6 +1771,11 @@ void X11_MinimizeWindow(SDL_VideoDevice *_this, SDL_Window *window) void X11_RestoreWindow(SDL_VideoDevice *_this, SDL_Window *window) { + // Don't restore the window the first time it is being shown. + if (!window->internal->was_shown) { + return; + } + if (window->internal->pending_operation & (X11_PENDING_OP_FULLSCREEN | X11_PENDING_OP_MAXIMIZE | X11_PENDING_OP_MINIMIZE)) { SDL_SyncWindow(window); } @@ -1729,6 +1810,10 @@ static SDL_FullscreenResult X11_SetWindowFullscreenViaWM(SDL_VideoDevice *_this, Atom _NET_WM_STATE = data->videodata->atoms._NET_WM_STATE; Atom _NET_WM_STATE_FULLSCREEN = data->videodata->atoms._NET_WM_STATE_FULLSCREEN; + if (!data->was_shown && fullscreen == SDL_FULLSCREEN_OP_LEAVE) { + return SDL_FULLSCREEN_SUCCEEDED; + } + if (X11_IsWindowMapped(_this, window)) { XEvent e; @@ -2223,6 +2308,15 @@ void X11_ShowWindowSystemMenu(SDL_Window *window, int x, int y) bool X11_SyncWindow(SDL_VideoDevice *_this, SDL_Window *window) { + SDL_WindowData *data = window->internal; + + // If the window is external and has only a pending resize or move event, use the special external sync path to avoid processing events. + if ((window->flags & SDL_WINDOW_EXTERNAL) && + (data->pending_operation & ~(X11_PENDING_OP_RESIZE | X11_PENDING_OP_MOVE)) == X11_PENDING_OP_NONE) { + X11_ExternalResizeMoveSync(window); + return true; + } + const Uint64 current_time = SDL_GetTicksNS(); Uint64 timeout = 0; diff --git a/lib/sdl3/SDL/src/video/x11/SDL_x11window.h b/lib/sdl3/SDL/src/video/x11/SDL_x11window.h index f1a73ab..ce90ed3 100644 --- a/lib/sdl3/SDL/src/video/x11/SDL_x11window.h +++ b/lib/sdl3/SDL/src/video/x11/SDL_x11window.h @@ -68,6 +68,7 @@ struct SDL_WindowData bool pending_move; SDL_Point pending_move_point; XConfigureEvent last_xconfigure; + XConfigureEvent pending_xconfigure; struct SDL_VideoData *videodata; unsigned long user_time; Atom xdnd_req; @@ -115,6 +116,8 @@ struct SDL_WindowData bool previous_borders_nonzero; bool toggle_borders; bool fullscreen_borders_forced_on; + bool was_shown; + bool emit_size_move_after_property_notify; SDL_HitTestResult hit_test_result; XPoint xim_spot; diff --git a/lib/sdl3/build.zig b/lib/sdl3/build.zig index 1c23f07..43b0a74 100644 --- a/lib/sdl3/build.zig +++ b/lib/sdl3/build.zig @@ -3,6 +3,7 @@ const std = @import("std"); pub fn addShaderDefinition( b: *std.Build, comptime sdl3Path: []const u8, + target: std.Build.ResolvedTarget, optimize: std.builtin.OptimizeMode, shaderName: []const u8, jsonPath: std.Build.LazyPath, @@ -16,7 +17,7 @@ pub fn addShaderDefinition( const module = b.createModule(.{ .root_source_file = reflectedZigOut, .optimize = optimize }); const dep = b.dependency("shaderTypes", .{ - .target = b.graph.host, + .target = target, .optimize = optimize, }); module.addImport("shaderTypes", dep.module("shaderTypes")); @@ -28,11 +29,12 @@ pub fn shaderDefintion( b: *std.Build, module: *std.Build.Module, comptime sdl3Path: []const u8, + target: std.Build.ResolvedTarget, optimize: std.builtin.OptimizeMode, shaderName: []const u8, jsonPath: std.Build.LazyPath, ) void { - const mod = addShaderDefinition(b, sdl3Path, optimize, shaderName, jsonPath); + const mod = addShaderDefinition(b, sdl3Path, target, optimize, shaderName, jsonPath); module.addImport(shaderName, mod); } @@ -67,7 +69,7 @@ pub fn build(b: *std.Build) void { mod.addImport("shaderTypes", shaderTypes.module("shaderTypes")); mod.addIncludePath(b.path("SDL/include")); - // mod.linkLibrary(sdl3_lib); + mod.linkLibrary(sdl3_lib); const test_step = b.step("test", "run unit tests for sdl3"); const tests = b.addExecutable(.{ @@ -80,11 +82,12 @@ pub fn build(b: *std.Build) void { tests.root_module.addImport("sdl3", mod); - const vertexDefinitions = addShaderDefinition(b, ".", optimize, "hello-triangle.vert", b.path("content/hello-triangle.vert.json")); + const vertexDefinitions = addShaderDefinition(b, ".", target, optimize, "hello-triangle.vert", b.path("content/hello-triangle.vert.json")); tests.root_module.addImport("hello-triangle.vert", vertexDefinitions); const runArtifact = b.addRunArtifact(tests); test_step.dependOn(&runArtifact.step); + b.installArtifact(sdl3_lib); b.installArtifact(tests); } diff --git a/lib/sdl3/content/_cooked/dxil/hello-triangle.vert.dxil b/lib/sdl3/content/_cooked/dxil/hello-triangle.vert.dxil index 75815cc..a29b0fe 100644 Binary files a/lib/sdl3/content/_cooked/dxil/hello-triangle.vert.dxil and b/lib/sdl3/content/_cooked/dxil/hello-triangle.vert.dxil differ diff --git a/lib/sdl3/content/_cooked/msl/hello-triangle.vert.msl b/lib/sdl3/content/_cooked/msl/hello-triangle.vert.msl index 715ac92..564cda3 100644 --- a/lib/sdl3/content/_cooked/msl/hello-triangle.vert.msl +++ b/lib/sdl3/content/_cooked/msl/hello-triangle.vert.msl @@ -3,14 +3,6 @@ using namespace metal; -struct type_TransformBuffer -{ - float4x4 modelMatrix; - float4x4 viewMatrix; - float4x4 projectionMatrix; - float time; -}; - struct Scene { float4 color; @@ -21,19 +13,8 @@ struct type_StructuredBuffer_Scene Scene _m0[1]; }; -struct Scene2 -{ - float4 color; - float4 lmfao; -}; - -struct type_StructuredBuffer_Scene2 -{ - Scene2 _m0[1]; -}; - -constant float2 _40 = {}; -constant float4 _41 = {}; +constant float2 _30 = {}; +constant float4 _31 = {}; struct main0_out { @@ -41,45 +22,45 @@ struct main0_out float4 gl_Position [[position]]; }; -vertex main0_out main0(constant type_TransformBuffer& TransformBuffer [[buffer(0)]], const device type_StructuredBuffer_Scene& test [[buffer(1)]], const device type_StructuredBuffer_Scene2& test2 [[buffer(2)]], uint gl_VertexIndex [[vertex_id]]) +vertex main0_out main0(const device type_StructuredBuffer_Scene& test [[buffer(0)]], uint gl_VertexIndex [[vertex_id]]) { main0_out out = {}; - float4 _68; - float2 _69; + float4 _58; + float2 _59; if (gl_VertexIndex == 0u) { - _68 = test._m0[0u].color; - _69 = float2(-1.0); + _58 = test._m0[0u].color; + _59 = float2(-1.0); } else { - float4 _66; - float2 _67; + float4 _56; + float2 _57; if (gl_VertexIndex == 1u) { - _66 = test2._m0[1u].color; - _67 = float2(1.0, -1.0); + _56 = test._m0[1u].color; + _57 = float2(1.0, -1.0); } else { - bool _58 = gl_VertexIndex == 2u; - float4 _63; - if (_58) + bool _48 = gl_VertexIndex == 2u; + float4 _53; + if (_48) { - _63 = test._m0[2u].color; + _53 = test._m0[2u].color; } else { - _63 = _41; + _53 = _31; } - _66 = _63; - _67 = select(_40, float2(0.0, 1.0), bool2(_58)); + _56 = _53; + _57 = select(_30, float2(0.0, 1.0), bool2(_48)); } - _68 = _66; - _69 = _67; + _58 = _56; + _59 = _57; } - out.out_var_TEXCOORD0 = _68; - out.gl_Position = TransformBuffer.modelMatrix * float4(_69, 0.0, 1.0); + out.out_var_TEXCOORD0 = _58; + out.gl_Position = float4(_59, 0.0, 1.0); return out; } diff --git a/lib/sdl3/content/_cooked/spv/hello-triangle.vert.spv b/lib/sdl3/content/_cooked/spv/hello-triangle.vert.spv index 613ba1d..203031d 100644 Binary files a/lib/sdl3/content/_cooked/spv/hello-triangle.vert.spv and b/lib/sdl3/content/_cooked/spv/hello-triangle.vert.spv differ diff --git a/lib/sdl3/content/hello-triangle.vert.hlsl b/lib/sdl3/content/hello-triangle.vert.hlsl index 78e2585..66931b6 100644 --- a/lib/sdl3/content/hello-triangle.vert.hlsl +++ b/lib/sdl3/content/hello-triangle.vert.hlsl @@ -9,27 +9,12 @@ struct Output float4 Position : SV_Position; }; -struct Scene2 -{ - float4 color; - float4 lmfao; -}; - struct Scene { float4 color; }; -cbuffer TransformBuffer : register(b0, space1) -{ - float4x4 modelMatrix; - float4x4 viewMatrix; - float4x4 projectionMatrix; - float time; -}; - StructuredBuffer test: register(t0, space0); -StructuredBuffer test2: register(t1, space0); Output main(Input input) { @@ -45,7 +30,7 @@ Output main(Input input) if (input.VertexIndex == 1) { pos = float2(1.0f, -1.0f); - output.Color = test2[1].color; + output.Color = test[1].color; } else { @@ -56,6 +41,6 @@ Output main(Input input) } } } - output.Position = mul(modelMatrix, float4(pos, 0.0f, 1.0f)); + output.Position = float4(pos, 0.0f, 1.0f); return output; } diff --git a/lib/sdl3/content/hello-triangle.vert.json b/lib/sdl3/content/hello-triangle.vert.json index 6d5fadb..ac9907b 100644 --- a/lib/sdl3/content/hello-triangle.vert.json +++ b/lib/sdl3/content/hello-triangle.vert.json @@ -6,38 +6,7 @@ } ], "types" : { - "_5" : { - "name" : "type.TransformBuffer", - "members" : [ - { - "name" : "modelMatrix", - "type" : "mat4", - "offset" : 0, - "matrix_stride" : 16, - "row_major" : true - }, - { - "name" : "viewMatrix", - "type" : "mat4", - "offset" : 64, - "matrix_stride" : 16, - "row_major" : true - }, - { - "name" : "projectionMatrix", - "type" : "mat4", - "offset" : 128, - "matrix_stride" : 16, - "row_major" : true - }, - { - "name" : "time", - "type" : "float", - "offset" : 192 - } - ] - }, - "_8" : { + "_6" : { "name" : "Scene", "members" : [ { @@ -47,12 +16,12 @@ } ] }, - "_7" : { + "_5" : { "name" : "type.StructuredBuffer.Scene", "members" : [ { "name" : "_m0", - "type" : "_8", + "type" : "_6", "array" : [ 0 ], @@ -63,38 +32,6 @@ "array_stride" : 16 } ] - }, - "_11" : { - "name" : "Scene2", - "members" : [ - { - "name" : "color", - "type" : "vec4", - "offset" : 0 - }, - { - "name" : "lmfao", - "type" : "vec4", - "offset" : 16 - } - ] - }, - "_10" : { - "name" : "type.StructuredBuffer.Scene2", - "members" : [ - { - "name" : "_m0", - "type" : "_11", - "array" : [ - 0 - ], - "array_size_is_literal" : [ - true - ], - "offset" : 0, - "array_stride" : 32 - } - ] } }, "outputs" : [ @@ -106,29 +43,12 @@ ], "ssbos" : [ { - "type" : "_7", + "type" : "_5", "name" : "test", "readonly" : true, "block_size" : 0, "set" : 0, "binding" : 0 - }, - { - "type" : "_10", - "name" : "test2", - "readonly" : true, - "block_size" : 0, - "set" : 0, - "binding" : 1 - } - ], - "ubos" : [ - { - "type" : "_5", - "name" : "type.TransformBuffer", - "block_size" : 196, - "set" : 1, - "binding" : 0 } ] } \ No newline at end of file diff --git a/lib/sdl3/shadercross/bin/linux/libSDL3.so.0 b/lib/sdl3/shadercross/bin/linux/libSDL3.so.0 new file mode 100644 index 0000000..eb06824 Binary files /dev/null and b/lib/sdl3/shadercross/bin/linux/libSDL3.so.0 differ diff --git a/lib/sdl3/shadercross/bin/linux/libdxcompiler.so b/lib/sdl3/shadercross/bin/linux/libdxcompiler.so new file mode 100644 index 0000000..cc453d4 Binary files /dev/null and b/lib/sdl3/shadercross/bin/linux/libdxcompiler.so differ diff --git a/lib/sdl3/shadercross/bin/linux/libspirv-cross-c-shared.so.0 b/lib/sdl3/shadercross/bin/linux/libspirv-cross-c-shared.so.0 new file mode 100644 index 0000000..e50dede Binary files /dev/null and b/lib/sdl3/shadercross/bin/linux/libspirv-cross-c-shared.so.0 differ diff --git a/lib/sdl3/shadercross/bin/linux/shadercross b/lib/sdl3/shadercross/bin/linux/shadercross new file mode 100644 index 0000000..2dfcad9 Binary files /dev/null and b/lib/sdl3/shadercross/bin/linux/shadercross differ diff --git a/lib/sdl3/src/samples/hello-triangle.zig b/lib/sdl3/src/samples/hello-triangle.zig index c90936b..bc47227 100644 --- a/lib/sdl3/src/samples/hello-triangle.zig +++ b/lib/sdl3/src/samples/hello-triangle.zig @@ -21,6 +21,11 @@ colorBuffer: *gpu.GPUBuffer = undefined, colorBufferTransfer: *gpu.GPUTransferBuffer = undefined, totalTime: f64 = 0.0, +pub fn print(comptime fmt: []const u8, args: anytype) void { + const writer = std.io.getStdOut().writer(); + writer.print(">>> " ++ fmt ++ "\n", args) catch return; +} + pub fn create(allocator: std.mem.Allocator) !*@This() { const self = try allocator.create(@This()); self.* = .{ @@ -46,14 +51,14 @@ pub fn startContext(self: *@This()) !void { .shaderformatSpirv = true, .shaderformatDxil = true, .shaderformatMsl = true, - }, true, null); + }, false, null); if (!self.device.claimWindowForGPUDevice(self.window)) return error.UnableToClaimGpu; const formats = self.device.getGPUShaderFormats(); - std.debug.print("SDL Context Loaded: {}\n", .{formats}); + print("SDL Context Loaded: {}\n", .{formats}); if (formats.shaderformatSpirv) { self.shaderpath = "./content/_cooked/spv"; // shaderformatSpirv self.shadersuffix = ".spv"; @@ -87,17 +92,17 @@ pub fn startContext(self: *@This()) !void { pci.rasterizer_state.fill_mode = .fillmodeFill; self.pipeline = self.device.createGPUGraphicsPipeline(&pci); - self.colorBuffer = self.device.createGPUBuffer(&.{ - .usage = .{ .bufferusageVertex = true }, - .size = 8192 * 2, - .props = 0, - }); + // self.colorBuffer = self.device.createGPUBuffer(&.{ + // .usage = .{ .bufferusageVertex = true, .bufferusageGraphicsStorageRead = true }, + // .size = 8192 * 2, + // .props = 0, + // }); - self.colorBufferTransfer = self.device.createGPUTransferBuffer(&.{ - .usage = .transferbufferusageUpload, - .size = 8192 * 2, - .props = 0, - }); + // self.colorBufferTransfer = self.device.createGPUTransferBuffer(&.{ + // .usage = .transferbufferusageUpload, + // .size = 8192 * 2, + // .props = 0, + // }); } pub fn loadFileAlloc(filename: []const u8, comptime alignment: usize, allocator: std.mem.Allocator) ![]u8 { @@ -123,7 +128,7 @@ pub fn loadShader( const spath = try std.fmt.allocPrintZ(self.allocator, "{s}/{s}{s}", .{ self.shaderpath, shaderName, self.shadersuffix }); defer self.allocator.free(spath); - std.debug.print("loading shader {s}\n", .{spath}); + print("loading shader {s}\n", .{spath}); const fileContents = try loadFileAlloc(spath, 8, self.allocator); defer self.allocator.free(fileContents); @@ -139,13 +144,12 @@ pub fn loadShader( .num_uniform_buffers = num_uniform_buffers, // The number of uniform buffers defined in the shader. .props = 0, }; - std.debug.print("hello_triangle_vert.Scene => sizeof() = {d}", .{@sizeOf(hello_triangle_vert.Scene)}); return self.device.createGPUShader(&sci); } pub fn loop(self: *@This()) !void { - std.debug.print("loop started\n", .{}); + print("loop started\n", .{}); try self.startContext(); while (self.running) { const dt = @as(f64, @floatFromInt(self.timer.lap())) / 1000 / 1000 / 1000; @@ -170,7 +174,7 @@ fn update(self: *@This(), dt: f64) void { } self.draw(dt); - std.debug.print("frametime {d:.3}ms (fps: {d:.1})\r", .{ dt * 1000, 1 / dt }); + print("frametime {d:.3}ms (fps: {d:.1})\r", .{ dt * 1000, 1 / dt }); } pub fn draw(self: *@This(), dt: f64) void { @@ -178,27 +182,27 @@ pub fn draw(self: *@This(), dt: f64) void { const cmd = self.device.acquireGPUCommandBuffer(); var swapchain_texture: *gpu.GPUTexture = undefined; - { - const buffer = self.device.mapGPUTransferBuffer(self.colorBufferTransfer, true); + // { + // const buffer = self.device.mapGPUTransferBuffer(self.colorBufferTransfer, true); - var b: [*][4]f32 = @ptrCast(@alignCast(buffer)); + // var b: [*][4]f32 = @ptrCast(@alignCast(buffer)); - b[0] = .{ @floatCast(std.math.sin(self.totalTime * 3 * 2 + 0.8) * 0.2 + 0.8), 0.4, 0.4, 1.0 }; - b[1] = .{ 0.4, @floatCast(std.math.sin(self.totalTime * 2 * 2 + 0.3) * 0.2 + 0.8), 0.4, 1.0 }; - b[2] = .{ 0.4, 0.4, @floatCast(std.math.sin(self.totalTime * 4 * 2) * 0.2 + 0.8), 1.0 }; + // b[0] = .{ @floatCast(std.math.sin(self.totalTime * 3 * 2 + 0.8) * 0.2 + 0.8), 0.4, 0.4, 1.0 }; + // b[1] = .{ 0.4, @floatCast(std.math.sin(self.totalTime * 2 * 2 + 0.3) * 0.2 + 0.8), 0.4, 1.0 }; + // b[2] = .{ 0.4, 0.4, @floatCast(std.math.sin(self.totalTime * 4 * 2) * 0.2 + 0.8), 1.0 }; - self.device.unmapGPUTransferBuffer(self.colorBufferTransfer); - } + // self.device.unmapGPUTransferBuffer(self.colorBufferTransfer); + // } - { - const copyPass = cmd.beginGPUCopyPass(); - defer copyPass.endGPUCopyPass(); - copyPass.uploadToGPUBuffer(&.{ .transfer_buffer = self.colorBufferTransfer, .offset = 0 }, &.{ - .buffer = self.colorBuffer, - .offset = 0, - .size = 4 * 12, - }, true); - } + // { + // const copyPass = cmd.beginGPUCopyPass(); + // defer copyPass.endGPUCopyPass(); + // copyPass.uploadToGPUBuffer(&.{ .transfer_buffer = self.colorBufferTransfer, .offset = 0 }, &.{ + // .buffer = self.colorBuffer, + // .offset = 0, + // .size = 4 * 12, + // }, true); + // } if (cmd.waitAndAcquireGPUSwapchainTexture(self.window, &swapchain_texture, null, null)) { var targetInfo: gpu.GPUColorTargetInfo = std.mem.zeroes(gpu.GPUColorTargetInfo); @@ -215,7 +219,7 @@ pub fn draw(self: *@This(), dt: f64) void { renderpass.endGPURenderPass(); } - std.debug.print("rendering time: {d:.3}ms ", .{self.frameStamp()}); + print("rendering time: {d:.3}ms ", .{self.frameStamp()}); _ = cmd.submitGPUCommandBuffer(); } @@ -228,7 +232,7 @@ pub fn destroy(self: *@This()) void { } pub fn main() !void { - std.debug.print("hello world... n", .{}); + print("hello world... n", .{}); const app = try create(std.heap.c_allocator); try app.loop(); defer app.destroy();