deps: update to SDL 3.2.16 (#3975)

This commit is contained in:
Tyler Wilding
2025-07-02 23:07:05 -04:00
committed by GitHub
parent 2d64108af5
commit 012ff7bb16
60 changed files with 1071 additions and 575 deletions
+1 -1
View File
@@ -5,7 +5,7 @@ if(NOT DEFINED CMAKE_BUILD_TYPE)
endif()
# See docs/release_checklist.md
project(SDL3 LANGUAGES C VERSION "3.2.14")
project(SDL3 LANGUAGES C VERSION "3.2.16")
if(CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR)
set(SDL3_MAINPROJECT ON)
+2 -2
View File
@@ -19,10 +19,10 @@
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>3.2.14</string>
<string>3.2.16</string>
<key>CFBundleSignature</key>
<string>SDLX</string>
<key>CFBundleVersion</key>
<string>3.2.14</string>
<string>3.2.16</string>
</dict>
</plist>
+4 -4
View File
@@ -3086,7 +3086,7 @@
CLANG_ENABLE_OBJC_ARC = YES;
DEPLOYMENT_POSTPROCESSING = YES;
DYLIB_COMPATIBILITY_VERSION = 201.0.0;
DYLIB_CURRENT_VERSION = 201.14.0;
DYLIB_CURRENT_VERSION = 201.16.0;
DYLIB_INSTALL_NAME_BASE = "@rpath";
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_ALTIVEC_EXTENSIONS = YES;
@@ -3121,7 +3121,7 @@
"@loader_path/Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 10.13;
MARKETING_VERSION = 3.2.14;
MARKETING_VERSION = 3.2.16;
OTHER_LDFLAGS = "$(CONFIG_FRAMEWORK_LDFLAGS)";
PRODUCT_BUNDLE_IDENTIFIER = org.libsdl.SDL3;
PRODUCT_NAME = SDL3;
@@ -3150,7 +3150,7 @@
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
DYLIB_COMPATIBILITY_VERSION = 201.0.0;
DYLIB_CURRENT_VERSION = 201.14.0;
DYLIB_CURRENT_VERSION = 201.16.0;
DYLIB_INSTALL_NAME_BASE = "@rpath";
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
@@ -3182,7 +3182,7 @@
"@loader_path/Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 10.13;
MARKETING_VERSION = 3.2.14;
MARKETING_VERSION = 3.2.16;
ONLY_ACTIVE_ARCH = YES;
OTHER_LDFLAGS = "$(CONFIG_FRAMEWORK_LDFLAGS)";
PRODUCT_BUNDLE_IDENTIFIER = org.libsdl.SDL3;
+1 -1
View File
@@ -1,4 +1,4 @@
Title SDL 3.2.14
Title SDL 3.2.16
Version 1
Description SDL Library for macOS (http://www.libsdl.org)
DefaultLocation /Library/Frameworks
+2
View File
@@ -51,6 +51,8 @@
boolean supportsRelativeMouse();
int openFileDescriptor(java.lang.String, java.lang.String);
boolean showFileDialog(java.lang.String[], boolean, boolean, int);
java.lang.String getPreferredLocales();
java.lang.String formatLocale(java.util.Locale);
}
-keep,includedescriptorclasses,allowoptimization class org.libsdl.app.HIDDeviceManager {
@@ -23,6 +23,7 @@ import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.LocaleList;
import android.os.Message;
import android.os.ParcelFileDescriptor;
import android.util.DisplayMetrics;
@@ -60,7 +61,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
private static final String TAG = "SDL";
private static final int SDL_MAJOR_VERSION = 3;
private static final int SDL_MINOR_VERSION = 2;
private static final int SDL_MICRO_VERSION = 14;
private static final int SDL_MICRO_VERSION = 16;
/*
// Display InputType.SOURCE/CLASS of events and devices
//
@@ -2116,6 +2117,44 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
int requestCode;
boolean multipleChoice;
}
/**
* This method is called by SDL using JNI.
*/
public static String getPreferredLocales() {
String result = "";
if (Build.VERSION.SDK_INT >= 24 /* Android 7 (N) */) {
LocaleList locales = LocaleList.getAdjustedDefault();
for (int i = 0; i < locales.size(); i++) {
if (i != 0) result += ",";
result += formatLocale(locales.get(i));
}
} else if (mCurrentLocale != null) {
result = formatLocale(mCurrentLocale);
}
return result;
}
public static String formatLocale(Locale locale) {
String result = "";
String lang = "";
if (locale.getLanguage() == "in") {
// Indonesian is "id" according to ISO 639.2, but on Android is "in" because of Java backwards compatibility
lang = "id";
} else if (locale.getLanguage() == "") {
// Make sure language is never empty
lang = "und";
} else {
lang = locale.getLanguage();
}
if (locale.getCountry() == "") {
result = lang;
} else {
result = lang + "_" + locale.getCountry();
}
return result;
}
}
/**
+1 -1
View File
@@ -11,7 +11,7 @@
- [macOS](README-macos.md)
- [NetBSD](README-bsd.md)
- [Nintendo Switch](README-switch.md)
- [Nintendo 3DS](README-3ds.md)
- [Nintendo 3DS](README-n3ds.md)
- [OpenBSD](README-bsd.md)
- [PlayStation 2](README-ps2.md)
- [PlayStation 4](README-ps4.md)
+1 -1
View File
@@ -20,7 +20,7 @@
*/
/**
* Main include header for the SDL library, version 3.2.14
* 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
+2 -2
View File
@@ -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.
*
+1 -1
View File
@@ -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
+1 -1
View File
@@ -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
+2 -2
View File
@@ -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.
+3 -2
View File
@@ -1279,10 +1279,11 @@ extern SDL_DECLSPEC bool SDLCALL SDL_BlitSurfaceUncheckedScaled(SDL_Surface *src
*
* \param src the SDL_Surface structure to be copied from.
* \param srcrect the SDL_Rect structure representing the rectangle to be
* copied, may not be NULL.
* copied, or NULL to copy the entire surface.
* \param dst the SDL_Surface structure that is the blit target.
* \param dstrect the SDL_Rect structure representing the target rectangle in
* the destination surface, may not be NULL.
* the destination surface, or NULL to fill the entire
* destination surface.
* \param scaleMode the SDL_ScaleMode to be used.
* \returns true on success or false on failure; call SDL_GetError() for more
* information.
+1 -1
View File
@@ -62,7 +62,7 @@ extern "C" {
*
* \since This macro is available since SDL 3.2.0.
*/
#define SDL_MICRO_VERSION 14
#define SDL_MICRO_VERSION 16
/**
* This macro turns the version numbers into a numeric value.
+6
View File
@@ -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);
+11 -6
View File
@@ -1743,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.
+1 -1
View File
@@ -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);
+2 -1
View File
@@ -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;
+1 -1
View File
@@ -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);
+17 -57
View File
@@ -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?");
}
@@ -2585,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)
+4 -4
View File
@@ -9,8 +9,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 3,2,14,0
PRODUCTVERSION 3,2,14,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, 14, 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, 14, 0\0"
VALUE "ProductVersion", "3, 2, 16, 0\0"
END
END
BLOCK "VarFileInfo"
+4 -4
View File
@@ -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);
+7 -25
View File
@@ -1077,16 +1077,11 @@ static void SDL_SendWakeupEvent(void)
return;
}
SDL_LockMutex(_this->wakeup_lock);
{
if (_this->wakeup_window) {
_this->SendWakeupEvent(_this, _this->wakeup_window);
// No more wakeup events needed until we enter a new wait
_this->wakeup_window = NULL;
}
// We only want to do this once while waiting for an event, so set it to NULL atomically here
SDL_Window *wakeup_window = (SDL_Window *)SDL_SetAtomicPointer(&_this->wakeup_window, NULL);
if (wakeup_window) {
_this->SendWakeupEvent(_this, wakeup_window);
}
SDL_UnlockMutex(_this->wakeup_lock);
#endif
}
@@ -1524,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;
@@ -1548,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);
@@ -1562,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;
+8 -4
View File
@@ -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
+353 -44
View File
@@ -93,10 +93,10 @@
} \
}
#define CHECK_GRAPHICS_PIPELINE_BOUND \
if (!((CommandBufferCommonHeader *)RENDERPASS_COMMAND_BUFFER)->graphics_pipeline_bound) { \
SDL_assert_release(!"Graphics pipeline not bound!"); \
return; \
#define CHECK_GRAPHICS_PIPELINE_BOUND \
if (!((RenderPass *)render_pass)->graphics_pipeline) { \
SDL_assert_release(!"Graphics pipeline not bound!"); \
return; \
}
#define CHECK_COMPUTEPASS \
@@ -106,7 +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; \
}
@@ -174,18 +174,132 @@
#define RENDERPASS_DEVICE \
((CommandBufferCommonHeader *)RENDERPASS_COMMAND_BUFFER)->device
#define RENDERPASS_BOUND_PIPELINE \
((RenderPass *)render_pass)->graphics_pipeline
#define COMPUTEPASS_COMMAND_BUFFER \
((Pass *)compute_pass)->command_buffer
#define COMPUTEPASS_DEVICE \
((CommandBufferCommonHeader *)COMPUTEPASS_COMMAND_BUFFER)->device
#define COMPUTEPASS_BOUND_PIPELINE \
((ComputePass *)compute_pass)->compute_pipeline
#define COPYPASS_COMMAND_BUFFER \
((Pass *)copy_pass)->command_buffer
#define COPYPASS_DEVICE \
((CommandBufferCommonHeader *)COPYPASS_COMMAND_BUFFER)->device
static bool TextureFormatIsComputeWritable[] = {
false, // INVALID
false, // A8_UNORM
true, // R8_UNORM
true, // R8G8_UNORM
true, // R8G8B8A8_UNORM
true, // R16_UNORM
true, // R16G16_UNORM
true, // R16G16B16A16_UNORM
true, // R10G10B10A2_UNORM
false, // B5G6R5_UNORM
false, // B5G5R5A1_UNORM
false, // B4G4R4A4_UNORM
false, // B8G8R8A8_UNORM
false, // BC1_UNORM
false, // BC2_UNORM
false, // BC3_UNORM
false, // BC4_UNORM
false, // BC5_UNORM
false, // BC7_UNORM
false, // BC6H_FLOAT
false, // BC6H_UFLOAT
true, // R8_SNORM
true, // R8G8_SNORM
true, // R8G8B8A8_SNORM
true, // R16_SNORM
true, // R16G16_SNORM
true, // R16G16B16A16_SNORM
true, // R16_FLOAT
true, // R16G16_FLOAT
true, // R16G16B16A16_FLOAT
true, // R32_FLOAT
true, // R32G32_FLOAT
true, // R32G32B32A32_FLOAT
true, // R11G11B10_UFLOAT
true, // R8_UINT
true, // R8G8_UINT
true, // R8G8B8A8_UINT
true, // R16_UINT
true, // R16G16_UINT
true, // R16G16B16A16_UINT
true, // R32_UINT
true, // R32G32_UINT
true, // R32G32B32A32_UINT
true, // R8_INT
true, // R8G8_INT
true, // R8G8B8A8_INT
true, // R16_INT
true, // R16G16_INT
true, // R16G16B16A16_INT
true, // R32_INT
true, // R32G32_INT
true, // R32G32B32A32_INT
false, // R8G8B8A8_UNORM_SRGB
false, // B8G8R8A8_UNORM_SRGB
false, // BC1_UNORM_SRGB
false, // BC3_UNORM_SRGB
false, // BC3_UNORM_SRGB
false, // BC7_UNORM_SRGB
false, // D16_UNORM
false, // D24_UNORM
false, // D32_FLOAT
false, // D24_UNORM_S8_UINT
false, // D32_FLOAT_S8_UINT
false, // ASTC_4x4_UNORM
false, // ASTC_5x4_UNORM
false, // ASTC_5x5_UNORM
false, // ASTC_6x5_UNORM
false, // ASTC_6x6_UNORM
false, // ASTC_8x5_UNORM
false, // ASTC_8x6_UNORM
false, // ASTC_8x8_UNORM
false, // ASTC_10x5_UNORM
false, // ASTC_10x6_UNORM
false, // ASTC_10x8_UNORM
false, // ASTC_10x10_UNORM
false, // ASTC_12x10_UNORM
false, // ASTC_12x12_UNORM
false, // ASTC_4x4_UNORM_SRGB
false, // ASTC_5x4_UNORM_SRGB
false, // ASTC_5x5_UNORM_SRGB
false, // ASTC_6x5_UNORM_SRGB
false, // ASTC_6x6_UNORM_SRGB
false, // ASTC_8x5_UNORM_SRGB
false, // ASTC_8x6_UNORM_SRGB
false, // ASTC_8x8_UNORM_SRGB
false, // ASTC_10x5_UNORM_SRGB
false, // ASTC_10x6_UNORM_SRGB
false, // ASTC_10x8_UNORM_SRGB
false, // ASTC_10x10_UNORM_SRGB
false, // ASTC_12x10_UNORM_SRGB
false, // ASTC_12x12_UNORM_SRGB
false, // ASTC_4x4_FLOAT
false, // ASTC_5x4_FLOAT
false, // ASTC_5x5_FLOAT
false, // ASTC_6x5_FLOAT
false, // ASTC_6x6_FLOAT
false, // ASTC_8x5_FLOAT
false, // ASTC_8x6_FLOAT
false, // ASTC_8x8_FLOAT
false, // ASTC_10x5_FLOAT
false, // ASTC_10x6_FLOAT
false, // ASTC_10x8_FLOAT
false, // ASTC_10x10_FLOAT
false, // ASTC_12x10_FLOAT
false // ASTC_12x12_FLOAT
};
// Drivers
#ifndef SDL_GPU_DISABLED
@@ -403,6 +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
@@ -564,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;
}
}
@@ -753,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,
@@ -1375,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;
}
@@ -1501,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) {
@@ -1532,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 ||
@@ -1543,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;
}
}
}
@@ -1554,14 +1775,18 @@ SDL_GPURenderPass *SDL_BeginGPURenderPass(
depth_stencil_target_info);
commandBufferHeader = (CommandBufferCommonHeader *)command_buffer;
commandBufferHeader->render_pass.in_progress = true;
for (Uint32 i = 0; i < num_color_targets; i += 1) {
commandBufferHeader->render_pass.color_targets[i] = color_target_infos[i].texture;
}
commandBufferHeader->render_pass.num_color_targets = num_color_targets;
if (depth_stencil_target_info != NULL) {
commandBufferHeader->render_pass.depth_stencil_target = depth_stencil_target_info->texture;
if (COMMAND_BUFFER_DEVICE->debug_mode) {
commandBufferHeader->render_pass.in_progress = true;
for (Uint32 i = 0; i < num_color_targets; i += 1) {
commandBufferHeader->render_pass.color_targets[i] = color_target_infos[i].texture;
}
commandBufferHeader->render_pass.num_color_targets = num_color_targets;
if (depth_stencil_target_info != NULL) {
commandBufferHeader->render_pass.depth_stencil_target = depth_stencil_target_info->texture;
}
}
return (SDL_GPURenderPass *)&(commandBufferHeader->render_pass);
}
@@ -1569,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;
@@ -1584,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(
@@ -1740,6 +1965,10 @@ void SDL_BindGPUVertexSamplers(
{
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(
@@ -1767,6 +1996,10 @@ void SDL_BindGPUVertexStorageTextures(
if (RENDERPASS_DEVICE->debug_mode) {
CHECK_RENDERPASS
CHECK_STORAGE_TEXTURES
for (Uint32 i = 0; i < num_bindings; i += 1) {
((RenderPass *)render_pass)->vertex_storage_texture_bound[first_slot + i] = true;
}
}
RENDERPASS_DEVICE->BindVertexStorageTextures(
@@ -1793,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(
@@ -1820,10 +2057,13 @@ void SDL_BindGPUFragmentSamplers(
if (RENDERPASS_DEVICE->debug_mode) {
CHECK_RENDERPASS
if (!((CommandBufferCommonHeader*)RENDERPASS_COMMAND_BUFFER)->ignore_render_pass_texture_validation)
{
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(
@@ -1851,6 +2091,10 @@ void SDL_BindGPUFragmentStorageTextures(
if (RENDERPASS_DEVICE->debug_mode) {
CHECK_RENDERPASS
CHECK_STORAGE_TEXTURES
for (Uint32 i = 0; i < num_bindings; i += 1) {
((RenderPass *)render_pass)->fragment_storage_texture_bound[first_slot + i] = true;
}
}
RENDERPASS_DEVICE->BindFragmentStorageTextures(
@@ -1877,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(
@@ -1902,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(
@@ -1928,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(
@@ -1956,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(
@@ -1983,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(
@@ -1996,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");
@@ -2009,15 +2262,22 @@ void SDL_EndGPURenderPass(
RENDERPASS_DEVICE->EndRenderPass(
RENDERPASS_COMMAND_BUFFER);
commandBufferCommonHeader = (CommandBufferCommonHeader *)RENDERPASS_COMMAND_BUFFER;
commandBufferCommonHeader->render_pass.in_progress = false;
for (Uint32 i = 0; i < MAX_COLOR_TARGET_BINDINGS; i += 1)
{
commandBufferCommonHeader->render_pass.color_targets[i] = NULL;
if (RENDERPASS_DEVICE->debug_mode) {
commandBufferCommonHeader->render_pass.in_progress = false;
for (Uint32 i = 0; i < MAX_COLOR_TARGET_BINDINGS; i += 1)
{
commandBufferCommonHeader->render_pass.color_targets[i] = NULL;
}
commandBufferCommonHeader->render_pass.num_color_targets = 0;
commandBufferCommonHeader->render_pass.depth_stencil_target = NULL;
commandBufferCommonHeader->render_pass.graphics_pipeline = NULL;
SDL_zeroa(commandBufferCommonHeader->render_pass.vertex_sampler_bound);
SDL_zeroa(commandBufferCommonHeader->render_pass.vertex_storage_texture_bound);
SDL_zeroa(commandBufferCommonHeader->render_pass.vertex_storage_buffer_bound);
SDL_zeroa(commandBufferCommonHeader->render_pass.fragment_sampler_bound);
SDL_zeroa(commandBufferCommonHeader->render_pass.fragment_storage_texture_bound);
SDL_zeroa(commandBufferCommonHeader->render_pass.fragment_storage_buffer_bound);
}
commandBufferCommonHeader->render_pass.num_color_targets = 0;
commandBufferCommonHeader->render_pass.depth_stencil_target = NULL;
commandBufferCommonHeader->graphics_pipeline_bound = false;
}
// Compute Pass
@@ -2061,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?
@@ -2074,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);
}
@@ -2082,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;
@@ -2101,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(
@@ -2122,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(
@@ -2148,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(
@@ -2174,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(
@@ -2197,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(
@@ -2219,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(
@@ -2244,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
@@ -2304,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);
}
@@ -2555,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(
+52 -3
View File
@@ -47,6 +47,20 @@ typedef struct Pass
bool in_progress;
} Pass;
typedef struct ComputePass
{
SDL_GPUCommandBuffer *command_buffer;
bool in_progress;
SDL_GPUComputePipeline *compute_pipeline;
bool sampler_bound[MAX_TEXTURE_SAMPLERS_PER_STAGE];
bool read_only_storage_texture_bound[MAX_STORAGE_TEXTURES_PER_STAGE];
bool read_only_storage_buffer_bound[MAX_STORAGE_BUFFERS_PER_STAGE];
bool read_write_storage_texture_bound[MAX_COMPUTE_WRITE_TEXTURES];
bool read_write_storage_buffer_bound[MAX_COMPUTE_WRITE_BUFFERS];
} ComputePass;
typedef struct RenderPass
{
SDL_GPUCommandBuffer *command_buffer;
@@ -54,15 +68,25 @@ typedef struct RenderPass
SDL_GPUTexture *color_targets[MAX_COLOR_TARGET_BINDINGS];
Uint32 num_color_targets;
SDL_GPUTexture *depth_stencil_target;
SDL_GPUGraphicsPipeline *graphics_pipeline;
bool vertex_sampler_bound[MAX_TEXTURE_SAMPLERS_PER_STAGE];
bool vertex_storage_texture_bound[MAX_STORAGE_TEXTURES_PER_STAGE];
bool vertex_storage_buffer_bound[MAX_STORAGE_BUFFERS_PER_STAGE];
bool fragment_sampler_bound[MAX_TEXTURE_SAMPLERS_PER_STAGE];
bool fragment_storage_texture_bound[MAX_STORAGE_TEXTURES_PER_STAGE];
bool fragment_storage_buffer_bound[MAX_STORAGE_BUFFERS_PER_STAGE];
} RenderPass;
typedef struct CommandBufferCommonHeader
{
SDL_GPUDevice *device;
RenderPass render_pass;
bool graphics_pipeline_bound;
Pass compute_pass;
bool compute_pipeline_bound;
ComputePass compute_pass;
Pass copy_pass;
bool swapchain_texture_acquired;
bool submitted;
@@ -75,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
@@ -162,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:
@@ -279,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:
+183 -147
View File
@@ -1015,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
@@ -1098,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;
};
@@ -1132,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;
};
@@ -2886,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)) {
@@ -3172,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);
@@ -3350,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;
@@ -4637,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);
@@ -4711,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;
}
}
@@ -4743,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;
}
}
@@ -4762,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;
}
}
@@ -4785,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;
}
}
@@ -4817,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;
}
}
@@ -4837,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;
}
}
@@ -4923,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;
}
}
}
@@ -4961,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(
@@ -4981,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(
@@ -5001,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(
@@ -5022,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(
@@ -5044,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],
@@ -5055,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(
@@ -5072,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(
@@ -5092,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(
@@ -5113,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(
@@ -5135,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],
@@ -5300,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
@@ -5342,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,
@@ -5360,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,
@@ -5401,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);
@@ -5411,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(
@@ -5429,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(
@@ -5460,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;
}
}
@@ -5511,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;
}
}
@@ -5548,6 +5556,7 @@ static void D3D12_BindComputeStorageBuffers(
buffer);
d3d12CommandBuffer->computeReadOnlyStorageBuffers[firstSlot + i] = buffer;
d3d12CommandBuffer->computeReadOnlyStorageBufferDescriptorHandles[firstSlot + i] = buffer->srvDescriptor.cpuHandle;
d3d12CommandBuffer->needComputeReadOnlyStorageBufferBind = true;
}
}
@@ -5583,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(
@@ -5600,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(
@@ -5620,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(
@@ -5641,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(
@@ -5663,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],
@@ -5762,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;
}
@@ -7352,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);
@@ -8819,6 +8833,12 @@ static SDL_GPUDevice *D3D12_CreateDevice(bool debugMode, bool preferLowPower, SD
// Initialize the D3D12 debug layer, if applicable
if (debugMode) {
bool hasD3d12Debug = D3D12_INTERNAL_TryInitializeD3D12Debug(renderer);
#if (defined(SDL_PLATFORM_XBOXONE) || defined(SDL_PLATFORM_XBOXSERIES))
if (hasD3d12Debug) {
SDL_LogInfo(
SDL_LOG_CATEGORY_GPU,
"Validation layers enabled, expect debug level performance!");
#else
if (hasDxgiDebug && hasD3d12Debug) {
SDL_LogInfo(
SDL_LOG_CATEGORY_GPU,
@@ -8827,6 +8847,7 @@ static SDL_GPUDevice *D3D12_CreateDevice(bool debugMode, bool preferLowPower, SD
SDL_LogWarn(
SDL_LOG_CATEGORY_GPU,
"Validation layers partially enabled, some warnings may not be available");
#endif
} else {
SDL_LogWarn(
SDL_LOG_CATEGORY_GPU,
@@ -9159,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;
+62 -73
View File
@@ -476,33 +476,21 @@ typedef struct MetalShader
typedef struct MetalGraphicsPipeline
{
GraphicsPipelineCommonHeader header;
id<MTLRenderPipelineState> handle;
SDL_GPURasterizerState rasterizerState;
SDL_GPUPrimitiveType primitiveType;
id<MTLDepthStencilState> depth_stencil_state;
Uint32 vertexSamplerCount;
Uint32 vertexUniformBufferCount;
Uint32 vertexStorageBufferCount;
Uint32 vertexStorageTextureCount;
Uint32 fragmentSamplerCount;
Uint32 fragmentUniformBufferCount;
Uint32 fragmentStorageBufferCount;
Uint32 fragmentStorageTextureCount;
} MetalGraphicsPipeline;
typedef struct MetalComputePipeline
{
ComputePipelineCommonHeader header;
id<MTLComputePipelineState> handle;
Uint32 numSamplers;
Uint32 numReadonlyStorageTextures;
Uint32 numReadWriteStorageTextures;
Uint32 numReadonlyStorageBuffers;
Uint32 numReadWriteStorageBuffers;
Uint32 numUniformBuffers;
Uint32 threadcountX;
Uint32 threadcountY;
Uint32 threadcountZ;
@@ -1059,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;
@@ -1207,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;
}
}
@@ -2412,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);
@@ -2650,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;
}
@@ -2662,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;
}
@@ -2673,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
@@ -2699,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;
}
@@ -2711,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;
}
@@ -2722,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
@@ -2754,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
@@ -3133,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);
@@ -3141,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)];
}
}
}
@@ -4570,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;
+112 -72
View File
@@ -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];
@@ -5126,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];
@@ -5150,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];
@@ -5172,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;
@@ -5245,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];
@@ -5269,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];
@@ -5291,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;
@@ -6565,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;
}
@@ -6659,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;
}
@@ -7457,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;
}
}
@@ -7488,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;
}
}
@@ -7510,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;
}
}
@@ -7533,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;
}
}
@@ -7564,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;
}
}
@@ -7588,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;
}
}
@@ -8107,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(
@@ -8145,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,
@@ -8161,6 +8192,7 @@ static void VULKAN_BeginComputePass(
VULKAN_BUFFER_USAGE_MODE_COMPUTE_STORAGE_READ_WRITE);
vulkanCommandBuffer->readWriteComputeStorageBuffers[i] = buffer;
vulkanCommandBuffer->readWriteComputeStorageBufferBindings[i] = buffer->buffer;
VULKAN_INTERNAL_TrackBuffer(
vulkanCommandBuffer,
@@ -8212,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;
}
}
@@ -8267,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;
}
}
@@ -8306,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;
}
}
@@ -8380,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];
@@ -8404,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];
@@ -8426,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;
@@ -8461,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];
@@ -8483,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;
@@ -8650,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;
@@ -9518,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);
@@ -11693,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
+3
View File
@@ -2754,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;
@@ -2762,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();
@@ -2771,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);
+28 -2
View File
@@ -1190,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;
}
}
+8 -2
View File
@@ -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) {
+1 -1
View File
@@ -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;
}
+1 -1
View File
@@ -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);
+3
View File
@@ -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
+1
View File
@@ -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);
+1 -1
View File
@@ -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;
+1 -2
View File
@@ -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;
+6 -7
View File
@@ -2513,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;
}
@@ -2761,7 +2763,7 @@ SDL_Window *SDL_GetWindowFromID(SDL_WindowID id)
}
}
}
SDL_SetError("Invalid window ID"); \
SDL_SetError("Invalid window ID");
return NULL;
}
@@ -4279,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);
@@ -5034,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)) {
@@ -5266,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");
+11
View File
@@ -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];
+8 -2
View File
@@ -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) {
-4
View File
@@ -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
+17
View File
@@ -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
@@ -2113,6 +2115,21 @@ static void Cocoa_SendMouseButtonClicks(SDL_Mouse *mouse, NSEvent *theEvent, SDL
}
}
- (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()
+1 -1
View File
@@ -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;
}
+9 -4
View File
@@ -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.
+2
View File
@@ -118,6 +118,8 @@ static SDL_VideoDevice *PSP_Create(void)
device->PumpEvents = PSP_PumpEvents;
device->device_caps = VIDEO_DEVICE_CAPS_FULLSCREEN_ONLY;
return device;
}
+2
View File
@@ -153,6 +153,8 @@ static SDL_VideoDevice *VITA_Create(void)
device->PumpEvents = VITA_PumpEvents;
device->device_caps = VIDEO_DEVICE_CAPS_FULLSCREEN_ONLY;
return device;
}
-2
View File
@@ -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);
+13 -17
View File
@@ -199,7 +199,6 @@ static Uint64 Wayland_EventTimestampMSToNS(Uint32 wl_timestamp_ms)
timestamp_offset += SDL_MS_TO_NS(SDL_UINT64_C(0x100000000));
}
last = wl_timestamp_ms;
wl_timestamp_ms += timestamp_offset;
return SDL_MS_TO_NS(wl_timestamp_ms) + timestamp_offset;
}
@@ -213,11 +212,6 @@ static Uint64 Wayland_GetKeyboardTimestamp(struct SDL_WaylandInput *input, Uint3
return 0;
}
static Uint64 Wayland_GetKeyboardTimestampRaw(struct SDL_WaylandInput *input, Uint32 wl_timestamp_ms)
{
return input->keyboard_timestamp_ns ? input->keyboard_timestamp_ns : Wayland_EventTimestampMSToNS(wl_timestamp_ms);
}
static Uint64 Wayland_GetPointerTimestamp(struct SDL_WaylandInput *input, Uint32 wl_timestamp_ms)
{
if (wl_timestamp_ms) {
@@ -273,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);
@@ -295,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;
@@ -304,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';
}
@@ -1859,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);
@@ -1875,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);
@@ -1883,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))) {
@@ -1894,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);
}
}
}
+7 -6
View File
@@ -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;
+32 -12
View File
@@ -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);
}
}
+2 -1
View File
@@ -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;
-4
View File
@@ -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;
-4
View File
@@ -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)
+3
View File
@@ -71,6 +71,9 @@
#ifdef SDL_VIDEO_DRIVER_X11_XSHAPE
#include <X11/extensions/shape.h>
#endif
#ifdef SDL_VIDEO_DRIVER_X11_XTEST
#include <X11/extensions/XTest.h>
#endif
#ifdef __cplusplus
extern "C" {
+3 -1
View File
@@ -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;
+14 -8
View File
@@ -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)
+2 -30
View File
@@ -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_FULLSCREEN_DIMENSIONS;
}
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;
+6
View File
@@ -1574,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;
+1 -1
View File
@@ -28,7 +28,7 @@ third-party/sqlite3:
third-party/fmt:
git: https://github.com/fmtlib/fmt/tree/11.1.4
third-party/SDL:
git: https://github.com/libsdl-org/SDL/tree/release-3.2.14
git: https://github.com/libsdl-org/SDL/tree/release-3.2.16
third-party/imgui:
git: https://github.com/ocornut/imgui/releases/tag/v1.91.8
third-party/tree-sitter: