diff --git a/.gitignore b/.gitignore index b0bc906ca8..e391987ab1 100644 --- a/.gitignore +++ b/.gitignore @@ -65,7 +65,7 @@ desc.txt Logs Memstick -memstick +memstick* Cheats /git-version.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index d8b2386deb..55d9eb146a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,9 +3,9 @@ cmake_minimum_required(VERSION 3.6) project(PPSSPP) #This is supposed to work but doesn't! -if (NOT ANDROID) -set(CMAKE_CXX_STANDARD 11) -set(CMAKE_CXX_STANDARD_REQUIRED ON) +if(NOT ANDROID) + set(CMAKE_CXX_STANDARD 11) + set(CMAKE_CXX_STANDARD_REQUIRED ON) endif() enable_language(ASM) @@ -13,64 +13,60 @@ list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/Modules) add_definitions(-D__STDC_CONSTANT_MACROS) - if(${CMAKE_CXX_COMPILER_ID} STREQUAL "Clang") - set(CLANG ON) - message("Clang enabled") + set(CLANG ON) + message("Clang enabled") endif() if(FORCED_CPU) - message("Detected CPU (${CMAKE_SYSTEM_PROCESSOR}) overridden as: ${FORCED_CPU}") - set(CMAKE_SYSTEM_PROCESSOR ${FORCED_CPU}) + message("Detected CPU (${CMAKE_SYSTEM_PROCESSOR}) overridden as: ${FORCED_CPU}") + set(CMAKE_SYSTEM_PROCESSOR ${FORCED_CPU}) endif() # Detect CPU from CMAKE configuration. Toolchains should set this up if(CMAKE_SYSTEM_PROCESSOR) if(${CMAKE_SYSTEM_PROCESSOR} MATCHES "^arm") - set(ARM ON) - if(UNIX AND NOT APPLE) - execute_process(COMMAND cat /proc/cpuinfo OUTPUT_VARIABLE OUTSTR) - string(FIND "${OUTSTR}" "ODROID-XU" pos) - if(NOT (pos LESS 0)) - add_compile_options(-mfloat-abi=hard -marm -mtune=cortex-a15.cortex-a7 -mcpu=cortex-a15 -fomit-frame-pointer) - set(ARM_NO_VULKAN ON) - endif() + set(ARM_DEVICE ON) + if(UNIX AND NOT APPLE) + execute_process(COMMAND cat /proc/cpuinfo OUTPUT_VARIABLE OUTSTR) + string(FIND "${OUTSTR}" "ODROID-XU" pos) + if(NOT (pos LESS 0)) + add_compile_options(-mfloat-abi=hard -marm -mtune=cortex-a15.cortex-a7 -mcpu=cortex-a15 -fomit-frame-pointer) + set(ARM_NO_VULKAN ON) endif() + endif() if(${CMAKE_SYSTEM_PROCESSOR} MATCHES "^armv7") - set(ARMV7 ON) + set(ARMV7_DEVICE ON) add_compile_options(-mfpu=neon) # Horrifying workaround for bug in android cmake stuff for asm files - if (ANDROID) + if(ANDROID) set(CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS} -target armv7a-none-linux-android") endif() endif() elseif(${CMAKE_SYSTEM_PROCESSOR} MATCHES "^aarch64") - set(ARM64 ON) - add_definitions(-DARM64) + set(ARM64 ON) + add_definitions(-DARM64) elseif(${CMAKE_SYSTEM_PROCESSOR} MATCHES "^amd64" OR ${CMAKE_SYSTEM_PROCESSOR} MATCHES "^x86_64" OR ${CMAKE_SYSTEM_PROCESSOR} MATCHES "^AMD64") - set(X86 ON) - set(X86_64 ON) + set(X86_DEVICE ON) + set(X86_64_DEVICE ON) elseif(${CMAKE_SYSTEM_PROCESSOR} MATCHES "^x86" OR ${CMAKE_SYSTEM_PROCESSOR} MATCHES "i.86") - set(X86 ON) + set(X86_DEVICE ON) elseif(${CMAKE_SYSTEM_PROCESSOR} MATCHES "^mips") - set(MIPS ON) + set(MIPS_DEVICE ON) else() - message("Unknown CMAKE_SYSTEM_PROCESSOR: ${CMAKE_SYSTEM_PROCESSOR}") + message("Unknown CMAKE_SYSTEM_PROCESSOR: ${CMAKE_SYSTEM_PROCESSOR}") endif() endif() include(ccache) -# Remove soon? -set(USE_FFMPEG ON) - # the libraries in the ffmpeg/ directory are not compatible with mingw if(MINGW AND NOT DEFINED USE_SYSTEM_FFMPEG) set(USE_SYSTEM_FFMPEG ON) endif() if(NOT ANDROID AND NOT IOS) - if(ARM OR SIMULATOR) + if(ARM_DEVICE OR SIMULATOR) set(USING_EGL ON) endif() endif() @@ -93,10 +89,6 @@ if(ANDROID OR WIN32 OR (UNIX AND NOT APPLE AND NOT ARM_NO_VULKAN)) set(VULKAN ON) endif() -if(NOT DEFINED HEADLESS) - set(HEADLESS OFF) -endif() - if(GOLD) add_definitions(-DGOLD) message("Gold Build") @@ -104,24 +96,19 @@ else() message("Normal Build") endif() -# Doesn't link on some platforms -#if(NOT DEFINED UNITTEST) -# set(UNITTEST OFF) -#endif() - # User-editable options (go into CMakeCache.txt) # :: Processors -option(ARMV7 "Set to ON if targeting an ARMv7 processor" ${ARMV7}) -option(ARM "Set to ON if targeting an ARM processor" ${ARM}) -option(MIPS "Set to ON if targeting a MIPS processor" ${MIPS}) -option(X86 "Set to ON if targeting an X86 processor" ${X86}) -option(X86_64 "Set to ON if targeting an X86_64 processor" ${X86_64}) +option(ARMV7 "Set to ON if targeting an ARMv7 processor" ${ARMV7_DEVICE}) +option(ARM "Set to ON if targeting an ARM processor" ${ARM_DEVICE}) +option(MIPS "Set to ON if targeting a MIPS processor" ${MIPS_DEVICE}) +option(X86 "Set to ON if targeting an X86 processor" ${X86_DEVICE}) +option(X86_64 "Set to ON if targeting an X86_64 processor" ${X86_64_DEVICE}) # :: Environments option(USING_EGL "Set to ON if target environment uses EGL" ${USING_EGL}) option(USING_FBDEV "Set to ON if target environment uses fbdev (eg. Pandora)" ${USING_FBDEV}) option(USING_GLES2 "Set to ON if target device uses OpenGL ES 2.0" ${USING_GLES2}) -option(RASPBIAN "Set to ON to workaround threading issues when building for ARMV7 on Raspbian" ${RASPBIAN}) option(USING_X11_VULKAN "Set to OFF if target environment doesn't use X11 for Vulkan" ON) +option(USE_WAYLAND_WSI "Enable or disable Wayland WSI support for Vulkan" ON) # :: Frontends option(USING_QT_UI "Set to ON if you wish to use the Qt frontend wrapper" ${USING_QT_UI}) option(MOBILE_DEVICE "Set to ON when targeting a mobile device" ${MOBILE_DEVICE}) @@ -130,11 +117,11 @@ option(UNITTEST "Set to ON to generate the unittest target" ${UNITTEST}) option(SIMULATOR "Set to ON when targeting an x86 simulator of an ARM platform" ${SIMULATOR}) option(LIBRETRO "Set to ON to generate the libretro target" OFF) # :: Options -option(USE_FFMPEG "Build with FFMPEG support" ${USE_FFMPEG}) +option(USE_FFMPEG "Build with FFMPEG support" ON) +option(USE_DISCORD "Build with Discord support" ON) option(USE_SYSTEM_SNAPPY "Dynamically link against system snappy" ${USE_SYSTEM_SNAPPY}) option(USE_SYSTEM_FFMPEG "Dynamically link against system FFMPEG" ${USE_SYSTEM_FFMPEG}) option(USE_SYSTEM_LIBZIP "Dynamically link against system libzip" ${USE_SYSTEM_LIBZIP}) -option(USE_WAYLAND_WSI "Set to ON to require Wayland support for Vulkan" ${USE_WAYLAND_WSI}) option(USE_ADDRESS_SANITIZER "Use Clang memory sanitizer" ${USE_ADDRESS_SANITIZER}) if(UNIX AND NOT (APPLE OR ANDROID) AND VULKAN) @@ -145,13 +132,14 @@ if(UNIX AND NOT (APPLE OR ANDROID) AND VULKAN) message("NOT using X11 for Vulkan") endif() # add_definitions(-DVK_USE_PLATFORM_XCB_KHR) - find_package(Wayland) - if (USE_WAYLAND_WSI AND NOT WAYLAND_FOUND) - message(FATAL_ERROR "Could not find libwayland, but USE_WAYLAND_WSI was enabled. Failing.") - endif() - if (WAYLAND_FOUND) - include_directories(${WAYLAND_INCLUDE_DIR}) - add_definitions(-DVK_USE_PLATFORM_WAYLAND_KHR) + if(USE_WAYLAND_WSI) + find_package(Wayland) + if(NOT WAYLAND_FOUND) + message(STATUS "Could not find Wayland libraries, disabling Wayland WSI support for Vulkan.") + else() + include_directories(${WAYLAND_INCLUDE_DIR}) + add_definitions(-DVK_USE_PLATFORM_WAYLAND_KHR) + endif() endif() endif() @@ -182,6 +170,10 @@ if(NOT OPENGL_LIBRARIES AND USING_GLES2) set(OPENGL_LIBRARIES GLESv2 EGL) endif() +if(NOT OPENGL_LIBRARIES) + find_package(OpenGL REQUIRED) +endif() + if(USING_EGL) if(NOT EGL_LIBRARIES) set(EGL_LIBRARIES EGL) @@ -189,10 +181,6 @@ if(USING_EGL) set(OPENGL_LIBRARIES ${OPENGL_LIBRARIES} ${EGL_LIBRARIES}) endif() -if(NOT OPENGL_LIBRARIES) - find_package(OpenGL REQUIRED) -endif() - find_package(SDL2) include(FindThreads) @@ -215,7 +203,7 @@ if(MOBILE_DEVICE) add_definitions(-DMOBILE_DEVICE) endif() -if (NOT CMAKE_BUILD_TYPE) +if(NOT CMAKE_BUILD_TYPE) message(STATUS "No build type selected, default to Release") set(CMAKE_BUILD_TYPE "Release") endif() @@ -245,10 +233,10 @@ if(ARM64) message("Generating for ARMv8, ${CMAKE_BUILD_TYPE}") endif() if(NOT MSVC) - if (ANDROID) + if(ANDROID) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++11") endif() - if (CLANG) + if(CLANG) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-switch -Wno-uninitialized") endif() @@ -280,7 +268,7 @@ if(NOT MSVC) # Don't compile with strict aliasing, we're not 100% aliasing-safe add_compile_options(-fno-strict-aliasing) - if (${CMAKE_C_COMPILER_ID} STREQUAL "Intel") + if(${CMAKE_C_COMPILER_ID} STREQUAL "Intel") set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -parallel -fopenmp") else() add_compile_options(-ffast-math) @@ -304,7 +292,7 @@ if(NOT MSVC) set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LIBRARY "libc++") elseif(NOT ANDROID) # TODO: See if we can get rid of no-psabi - if (NOT ${CMAKE_C_COMPILER_ID} STREQUAL "Intel" AND NOT ${CMAKE_CXX_COMPILER_ID} STREQUAL "Clang") + if(NOT ${CMAKE_C_COMPILER_ID} STREQUAL "Intel" AND NOT ${CMAKE_CXX_COMPILER_ID} STREQUAL "Clang") add_definitions(-Wno-psabi) endif() add_definitions(-D_XOPEN_SOURCE=700) @@ -359,14 +347,16 @@ set(CommonX86 Common/x64Analyzer.cpp Common/x64Analyzer.h Common/x64Emitter.cpp - Common/x64Emitter.h) + Common/x64Emitter.h +) source_group(x86 FILES ${CommonX86}) set(CommonARM Common/ArmCPUDetect.cpp Common/ArmEmitter.h Common/ArmEmitter.cpp - Common/ColorConvNEON.cpp) + Common/ColorConvNEON.cpp +) source_group(ARM FILES ${CommonARM}) set(CommonARM64 @@ -374,30 +364,32 @@ set(CommonARM64 Common/Arm64Emitter.cpp Common/ArmEmitter.h Common/ArmEmitter.cpp - Core/Util/DisArm64.cpp) + Core/Util/DisArm64.cpp +) source_group(ARM64 FILES ${CommonARM64}) set(CommonMIPS Common/MipsCPUDetect.cpp Common/MipsEmitter.cpp - Common/MipsEmitter.h) + Common/MipsEmitter.h +) source_group(MIPS FILES ${CommonMIPS}) if(NOT (X86 OR ARM OR MIPS)) set(CommonFake Common/FakeCPUDetect.cpp - Common/FakeEmitter.h) + Common/FakeEmitter.h + ) source_group(Fake FILES ${CommonFake}) endif() set(CommonWindows Common/stdafx.cpp - Common/stdafx.h) + Common/stdafx.h +) source_group(Windows FILES ${CommonWindows}) set(CommonVulkan ${CommonExtra} - Common/Vulkan/SPIRVDisasm.cpp - Common/Vulkan/SPIRVDisasm.h Common/Vulkan/VulkanContext.cpp Common/Vulkan/VulkanContext.h Common/Vulkan/VulkanDebug.cpp @@ -407,7 +399,8 @@ set(CommonVulkan ${CommonExtra} Common/Vulkan/VulkanLoader.cpp Common/Vulkan/VulkanLoader.h Common/Vulkan/VulkanMemory.cpp - Common/Vulkan/VulkanMemory.h) + Common/Vulkan/VulkanMemory.h +) add_library(Common STATIC ${CommonX86} @@ -454,7 +447,8 @@ add_library(Common STATIC Common/ThreadPools.h Common/ThreadSafeList.h Common/Timer.cpp - Common/Timer.h) + Common/Timer.h +) add_subdirectory(ext) @@ -480,7 +474,7 @@ if(TARGET SDL2::SDL2) target_link_libraries(Common SDL2::SDL2) endif() -if(USING_GLES2) +if(USING_GLES2 OR (USING_EGL AND NOT USING_FBDEV)) find_package(X11) endif() @@ -491,56 +485,57 @@ add_library(gason STATIC add_library(rg_etc1 STATIC ext/native/ext/rg_etc1/rg_etc1.cpp - ext/native/ext/rg_etc1/rg_etc1.h) + ext/native/ext/rg_etc1/rg_etc1.h +) include_directories(ext/native/ext/rg_etc1) if(USE_FFMPEG) - if(NOT FFMPEG_DIR) - if(NOT USE_SYSTEM_FFMPEG) - if(ANDROID) - if(ARMV7) - set(PLATFORM_ARCH "android/armv7") - elseif(ARM64) - set(PLATFORM_ARCH "android/arm64") - elseif(X86_64) - set(PLATFORM_ARCH "android/x86_64") - elseif(X86) - set(PLATFORM_ARCH "android/x86") - endif() - elseif(IOS) - set(PLATFORM_ARCH "ios/universal") - elseif(MACOSX) - set(PLATFORM_ARCH "macosx/x86_64") - elseif(LINUX) - if(ARMV7) - set(PLATFORM_ARCH "linux/armv7") - elseif(ARM64) - set(PLATFORM_ARCH "linux/aarch64") - elseif(ARM) - set(PLATFORM_ARCH "linux/arm") - elseif(MIPS) - set(PLATFORM_ARCH "linux/mips32") - elseif(CMAKE_SIZEOF_VOID_P EQUAL 8) - set(PLATFORM_ARCH "linux/x86_64") - elseif(X86) - set(PLATFORM_ARCH "linux/x86") - endif() - elseif(WIN32) - if(X86_64) - set(PLATFORM_ARCH "Windows/x86_64") - elseif(X86) - set(PLATFORM_ARCH "Windows/x86") - endif() - endif() - if(PLATFORM_ARCH) - set(FFMPEG_DIR "ffmpeg/${PLATFORM_ARCH}") - else() - message("Couldn't find an internal FFmpeg build, using system FFmpeg instead") - endif() - endif() - endif() + if(NOT FFMPEG_DIR) + if(NOT USE_SYSTEM_FFMPEG) + if(ANDROID) + if(ARMV7) + set(PLATFORM_ARCH "android/armv7") + elseif(ARM64) + set(PLATFORM_ARCH "android/arm64") + elseif(X86_64) + set(PLATFORM_ARCH "android/x86_64") + elseif(X86) + set(PLATFORM_ARCH "android/x86") + endif() + elseif(IOS) + set(PLATFORM_ARCH "ios/universal") + elseif(MACOSX) + set(PLATFORM_ARCH "macosx/x86_64") + elseif(LINUX) + if(ARMV7) + set(PLATFORM_ARCH "linux/armv7") + elseif(ARM64) + set(PLATFORM_ARCH "linux/aarch64") + elseif(ARM) + set(PLATFORM_ARCH "linux/arm") + elseif(MIPS) + set(PLATFORM_ARCH "linux/mips32") + elseif(CMAKE_SIZEOF_VOID_P EQUAL 8) + set(PLATFORM_ARCH "linux/x86_64") + elseif(X86) + set(PLATFORM_ARCH "linux/x86") + endif() + elseif(WIN32) + if(X86_64) + set(PLATFORM_ARCH "Windows/x86_64") + elseif(X86) + set(PLATFORM_ARCH "Windows/x86") + endif() + endif() + if(PLATFORM_ARCH) + set(FFMPEG_DIR "ffmpeg/${PLATFORM_ARCH}") + else() + message("Couldn't find an internal FFmpeg build, using system FFmpeg instead") + endif() + endif() + endif() - find_package(FFmpeg REQUIRED avcodec avformat avutil swresample swscale) + find_package(FFmpeg REQUIRED avcodec avformat avutil swresample swscale) endif(USE_FFMPEG) find_package(ZLIB) @@ -588,7 +583,7 @@ add_library(cityhash STATIC ) include_directories(ext/cityhash) -if (NOT MSVC) +if(NOT MSVC) # These can be fast even for debug. set_target_properties(udis86 PROPERTIES COMPILE_FLAGS "-O3") set_target_properties(cityhash PROPERTIES COMPILE_FLAGS "-O3") @@ -657,7 +652,8 @@ else() ext/native/ext/libzip/zip_unchange.c ext/native/ext/libzip/zip_unchange_all.c ext/native/ext/libzip/zip_unchange_archive.c - ext/native/ext/libzip/zip_unchange_data.c) + ext/native/ext/libzip/zip_unchange_data.c + ) target_link_libraries(libzip) include_directories(ext/native/ext/libzip) set(LIBZIP_LIBRARY libzip) @@ -668,15 +664,15 @@ find_path(PNG_PNG_INCLUDE_DIR NAMES "libpng17/png.h") find_library(PNG_LIBRARY NAMES png17 libpng17) find_package(PackageHandleStandardArgs) find_package_handle_standard_args(PNG REQUIRED_VARS PNG_LIBRARY PNG_PNG_INCLUDE_DIR) -if (PNG_FOUND) +if(PNG_FOUND) include_directories(${PNG_PNG_INCLUDE_DIR}) else() if(ARM) set(PNG_ARM_INCLUDES - ext/native/ext/libpng17/arm/arm_init.c - ext/native/ext/libpng17/arm/filter_neon.S - ext/native/ext/libpng17/arm/filter_neon_intrinsics.c - ) + ext/native/ext/libpng17/arm/arm_init.c + ext/native/ext/libpng17/arm/filter_neon.S + ext/native/ext/libpng17/arm/filter_neon_intrinsics.c + ) endif() add_library(png17 STATIC ext/native/ext/libpng17/pngconf.h @@ -701,7 +697,8 @@ else() ext/native/ext/libpng17/pngwrite.c ext/native/ext/libpng17/pngwtran.c ext/native/ext/libpng17/pngwutil.c - ${PNG_ARM_INCLUDES} ) + ${PNG_ARM_INCLUDES} + ) set(PNG_LIBRARY png17) include_directories(ext/native/ext) endif() @@ -710,13 +707,14 @@ set(nativeExtra) set(nativeExtraLibs) if(ANDROID) - set(nativeExtra ${nativeExtra} - Common/GL/GLInterface/EGLAndroid.cpp - Common/GL/GLInterface/EGLAndroid.h - Common/GL/GLInterface/EGL.cpp - Common/GL/GLInterface/EGL.h - Common/GL/GLInterface/GLInterface.cpp - Common/GL/GLInterfaceBase.h) + set(nativeExtra ${nativeExtra} + Common/GL/GLInterface/EGLAndroid.cpp + Common/GL/GLInterface/EGLAndroid.h + Common/GL/GLInterface/EGL.cpp + Common/GL/GLInterface/EGL.h + Common/GL/GLInterface/GLInterface.cpp + Common/GL/GLInterfaceBase.h + ) set(nativeExtra ${nativeExtra} ext/native/base/NativeApp.h @@ -731,7 +729,8 @@ if(ANDROID) android/jni/native_audio.cpp android/jni/native_audio.h android/jni/native-audio-so.cpp - android/jni/native-audio-so.h) + android/jni/native-audio-so.h + ) # No target elseif(IOS) set(nativeExtra ${nativeExtra} @@ -750,7 +749,8 @@ elseif(IOS) ios/SubtleVolume.mm ios/iCade/iCadeReaderView.h ios/iCade/iCadeReaderView.m - ios/iCade/iCadeState.h) + ios/iCade/iCadeState.h + ) set(nativeExtraLibs ${nativeExtraLibs} "-framework Foundation -framework MediaPlayer -framework AudioToolbox -framework CoreGraphics -framework QuartzCore -framework UIKit -framework GLKit -framework OpenAL -framework AVFoundation") if(EXISTS "${CMAKE_IOS_SDK_ROOT}/System/Library/Frameworks/GameController.framework") set(nativeExtraLibs ${nativeExtraLibs} "-weak_framework GameController") @@ -770,34 +770,38 @@ elseif(IOS) set(TargetBin PPSSPP) elseif(USING_QT_UI) - set(CMAKE_AUTOMOC ON) - find_package(Qt5 COMPONENTS OpenGL Gui Core) - if(NOT SDL2_FOUND) - find_package(Qt5 COMPONENTS Multimedia) - endif(NOT SDL2_FOUND) - list(APPEND NativeAppSource - Qt/QtMain.cpp - Qt/QtMain.h - Qt/QtHost.cpp - Qt/QtHost.h - Qt/mainwindow.cpp - Qt/mainwindow.h - ) - add_definitions(-DUSING_QT_UI) - include_directories(${CMAKE_CURRENT_BINARY_DIR} Qt) + set(CMAKE_AUTOMOC ON) + find_package(Qt5 COMPONENTS OpenGL Gui Core) + if(NOT SDL2_FOUND) + find_package(Qt5 COMPONENTS Multimedia) + endif(NOT SDL2_FOUND) + list(APPEND NativeAppSource + Qt/QtMain.cpp + Qt/QtMain.h + Qt/QtHost.cpp + Qt/QtHost.h + Qt/mainwindow.cpp + Qt/mainwindow.h + ) + add_definitions(-DUSING_QT_UI) + if(USING_GLES2) + add_definitions(-DQT_OPENGL_ES -DQT_OPENGL_ES_2) + endif() + include_directories(${CMAKE_CURRENT_BINARY_DIR} Qt) set(nativeExtraLibs ${nativeExtraLibs} Qt5::OpenGL Qt5::Gui Qt5::Core) set(TargetBin PPSSPPQt) - # Enable SDL if found - if (SDL2_FOUND) - add_definitions(-DSDL) - set(nativeExtra ${nativeExtra} - SDL/SDLJoystick.h - SDL/SDLJoystick.cpp) - set(nativeExtraLibs ${nativeExtraLibs} SDL2::SDL2) - else(SDL2_FOUND) - set(nativeExtraLibs ${nativeExtraLibs} Qt5::Multimedia) - endif() + # Enable SDL if found + if(SDL2_FOUND) + add_definitions(-DSDL) + set(nativeExtra ${nativeExtra} + SDL/SDLJoystick.h + SDL/SDLJoystick.cpp + ) + set(nativeExtraLibs ${nativeExtraLibs} SDL2::SDL2) + else(SDL2_FOUND) + set(nativeExtraLibs ${nativeExtraLibs} Qt5::Multimedia) + endif() elseif(WIN32) # Don't care about SDL. @@ -807,25 +811,26 @@ elseif(WIN32) else() link_directories(dx9sdk/Lib/x86) endif() - set(nativeExtra ${nativeExtra} ext/native/base/logging.cpp) + set(nativeExtra ${nativeExtra} ext/native/base/logging.cpp) elseif(TARGET SDL2::SDL2) - set(TargetBin PPSSPPSDL) - # Require SDL - add_definitions(-DSDL) - set(nativeExtra ${nativeExtra} - SDL/SDLJoystick.h - SDL/SDLJoystick.cpp - SDL/SDLMain.cpp - SDL/SDLGLGraphicsContext.cpp - SDL/SDLVulkanGraphicsContext.cpp) - set(nativeExtraLibs ${nativeExtraLibs} SDL2::SDL2) - if(APPLE) - set(nativeExtra ${nativeExtra} SDL/SDLMain.h SDL/SDLMain.mm) - set(nativeExtraLibs ${nativeExtraLibs} ${COCOA_LIBRARY}) - elseif(USING_EGL) - set(nativeExtraLibs ${nativeExtraLibs} pthread) - endif() - set(TargetBin PPSSPPSDL) + set(TargetBin PPSSPPSDL) + # Require SDL + add_definitions(-DSDL) + set(nativeExtra ${nativeExtra} + SDL/SDLJoystick.h + SDL/SDLJoystick.cpp + SDL/SDLMain.cpp + SDL/SDLGLGraphicsContext.cpp + SDL/SDLVulkanGraphicsContext.cpp + ) + set(nativeExtraLibs ${nativeExtraLibs} SDL2::SDL2) + if(APPLE) + set(nativeExtra ${nativeExtra} SDL/SDLMain.h SDL/SDLMain.mm) + set(nativeExtraLibs ${nativeExtraLibs} ${COCOA_LIBRARY}) + elseif(USING_EGL) + set(nativeExtraLibs ${nativeExtraLibs} pthread) + endif() + set(TargetBin PPSSPPSDL) else() message(FATAL_ERROR "Could not find SDL2. Failing.") endif() @@ -845,6 +850,7 @@ list(APPEND NativeAppSource UI/PauseScreen.cpp UI/GameScreen.cpp UI/GameSettingsScreen.cpp + UI/GPUDriverTestScreen.cpp UI/TiltAnalogSettingsScreen.cpp UI/TiltEventProcessor.cpp UI/TouchControlLayoutScreen.cpp @@ -861,12 +867,13 @@ list(APPEND NativeAppSource UI/ProfilerDraw.cpp UI/ui_atlas.cpp UI/TextureUtil.cpp - UI/ComboKeyMappingScreen.cpp) + UI/ComboKeyMappingScreen.cpp +) if(ANDROID) - if (ARM) + if(ARM) set(NativeAppSource ${NativeAppSource} android/jni/ArmEmitterTest.cpp) - elseif (ARM64) + elseif(ARM64) set(NativeAppSource ${NativeAppSource} android/jni/Arm64EmitterTest.cpp) endif() set(nativeExtra ${nativeExtra} ${NativeAppSource}) @@ -878,7 +885,8 @@ set(THIN3D_PLATFORMS ext/native/thin3d/thin3d_gl.cpp ext/native/thin3d/GLQueueRunner.cpp ext/native/thin3d/GLQueueRunner.h ext/native/thin3d/DataFormatGL.cpp - ext/native/thin3d/DataFormatGL.h) + ext/native/thin3d/DataFormatGL.h +) set(THIN3D_PLATFORMS ${THIN3D_PLATFORMS} ext/native/thin3d/thin3d_vulkan.cpp @@ -886,16 +894,18 @@ set(THIN3D_PLATFORMS ${THIN3D_PLATFORMS} ext/native/thin3d/VulkanRenderManager.h ext/native/thin3d/VulkanQueueRunner.cpp ext/native/thin3d/VulkanQueueRunner.h - ext/native/thin3d/DataFormat.h) + ext/native/thin3d/DataFormat.h +) if(WIN32) - set(THIN3D_PLATFORMS ${THIN3D_PLATFORMS} - ext/native/thin3d/thin3d_d3d9.cpp - ext/native/thin3d/thin3d_d3d11.cpp - ext/native/thin3d/d3dx9_loader.cpp - ext/native/thin3d/d3dx9_loader.h - ext/native/thin3d/d3d11_loader.cpp - ext/native/thin3d/d3d11_loader.h) + set(THIN3D_PLATFORMS ${THIN3D_PLATFORMS} + ext/native/thin3d/thin3d_d3d9.cpp + ext/native/thin3d/thin3d_d3d11.cpp + ext/native/thin3d/d3dx9_loader.cpp + ext/native/thin3d/d3dx9_loader.h + ext/native/thin3d/d3d11_loader.cpp + ext/native/thin3d/d3d11_loader.h + ) endif() add_library(native STATIC @@ -1052,21 +1062,22 @@ add_library(native STATIC ext/native/ext/jpge/jpgd.cpp ext/native/ext/jpge/jpgd.h ext/native/ext/jpge/jpge.cpp - ext/native/ext/jpge/jpge.h) + ext/native/ext/jpge/jpge.h +) include_directories(ext/native) -if (LINUX AND NOT ANDROID) - SET(RT_LIB rt) +if(LINUX AND NOT ANDROID) + set(RT_LIB rt) endif() -SET(ATOMIC_LIB) +set(ATOMIC_LIB) if(ANDROID) - SET(ATOMIC_LIB atomic) + set(ATOMIC_LIB atomic) endif() target_link_libraries(native ${LIBZIP_LIBRARY} ${PNG_LIBRARY} ${ZLIB_LIBRARY} rg_etc1 gason udis86 ${RT_LIB} ${nativeExtraLibs} ${ATOMIC_LIB}) if(TARGET Ext::GLEW) - target_link_libraries(native Ext::GLEW) + target_link_libraries(native Ext::GLEW) endif() if(ANDROID) @@ -1088,7 +1099,8 @@ add_library(kirk STATIC ext/libkirk/bn.c ext/libkirk/ec.c ext/libkirk/kirk_engine.c - ext/libkirk/kirk_engine.h) + ext/libkirk/kirk_engine.h +) include_directories(ext/libkirk) add_library(sfmt19937 STATIC @@ -1133,7 +1145,7 @@ set(CoreExtra ${CoreExtra} Core/MIPS/IR/IRPassSimplify.h Core/MIPS/IR/IRRegCache.cpp Core/MIPS/IR/IRRegCache.h - ) +) list(APPEND CoreExtra Core/MIPS/ARM/ArmAsm.cpp @@ -1169,7 +1181,8 @@ list(APPEND CoreExtra Core/MIPS/ARM64/Arm64RegCacheFPU.cpp Core/MIPS/ARM64/Arm64RegCacheFPU.h GPU/Common/VertexDecoderArm64.cpp - Core/Util/DisArm64.cpp) + Core/Util/DisArm64.cpp +) list(APPEND CoreExtra Core/MIPS/x86/Asm.cpp @@ -1197,17 +1210,19 @@ list(APPEND CoreExtra GPU/Common/VertexDecoderFake.cpp ) -if (NOT MOBILE_DEVICE) +if(NOT MOBILE_DEVICE) set(CoreExtra ${CoreExtra} Core/AVIDump.cpp Core/AVIDump.h Core/WaveFile.cpp - Core/WaveFile.h) + Core/WaveFile.h + ) endif() set(GPU_GLES GPU/GLES/DepalettizeShaderGLES.cpp GPU/GLES/DepalettizeShaderGLES.h + GPU/GLES/DepthBufferGLES.cpp GPU/GLES/GPU_GLES.cpp GPU/GLES/GPU_GLES.h GPU/GLES/FragmentShaderGeneratorGLES.cpp @@ -1232,7 +1247,7 @@ set(GPU_GLES ) set(GPU_VULKAN - GPU/Vulkan/DepalettizeShaderVulkan.cpp + GPU/Vulkan/DepalettizeShaderVulkan.cpp GPU/Vulkan/DepalettizeShaderVulkan.h GPU/Vulkan/DebugVisVulkan.cpp GPU/Vulkan/DebugVisVulkan.h @@ -1262,7 +1277,7 @@ set(GPU_VULKAN ) set(GPU_D3D9 - GPU/Directx9/DepalettizeShaderDX9.cpp + GPU/Directx9/DepalettizeShaderDX9.cpp GPU/Directx9/DepalettizeShaderDX9.h GPU/Directx9/DrawEngineDX9.cpp GPU/Directx9/DrawEngineDX9.h @@ -1286,7 +1301,7 @@ set(GPU_D3D9 ) set(GPU_D3D11 - GPU/D3D11/DepalettizeShaderD3D11.cpp + GPU/D3D11/DepalettizeShaderD3D11.cpp GPU/D3D11/DepalettizeShaderD3D11.h GPU/D3D11/DrawEngineD3D11.cpp GPU/D3D11/DrawEngineD3D11.h @@ -1395,7 +1410,8 @@ set(GPU_SOURCES GPU/Software/SoftGpu.h GPU/Software/TransformUnit.cpp GPU/Software/TransformUnit.h - GPU/ge_constants.h) + GPU/ge_constants.h +) # 'ppsspp_jni' on ANDROID, 'Core' everywhere else # SHARED on ANDROID, STATIC everywhere else @@ -1733,13 +1749,14 @@ add_library(${CoreLibName} ${CoreLinkType} ${CORE_NEON} ${GPU_SOURCES} ext/disarm.cpp - git-version.cpp) + git-version.cpp +) if(ANDROID) - set(CoreExtraLibs ${CoreExtraLibs} android) - if(X86_64) - set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-Bsymbolic") - endif() + set(CoreExtraLibs ${CoreExtraLibs} android) + if(X86_64) + set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-Bsymbolic") + endif() endif() set(CoreExtraLibs ${CoreExtraLibs} armips) @@ -1753,27 +1770,28 @@ set(CoreExtraLibs ${CoreExtraLibs} armips) set(GlslangLibs glslang OGLCompiler OSDependent SPIRV SPVRemapper spirv-cross-glsl) if(WIN32) - set(GlslangLibs ${GlslangLibs} spirv-cross-hlsl) + set(GlslangLibs ${GlslangLibs} spirv-cross-hlsl) endif() target_link_libraries(${CoreLibName} Common native kirk cityhash sfmt19937 xbrz xxhash ${GlslangLibs} ${CoreExtraLibs} ${OPENGL_LIBRARIES} ${X11_LIBRARIES} ${CMAKE_DL_LIBS}) if(FFmpeg_FOUND) - target_compile_definitions(${CoreLibName} PRIVATE USE_FFMPEG=1) - target_link_libraries(${CoreLibName} - FFmpeg::avcodec - FFmpeg::avformat - FFmpeg::avutil - FFmpeg::swresample - FFmpeg::swscale - ${ZLIB_LIBRARY} - ) + target_compile_definitions(${CoreLibName} PRIVATE USE_FFMPEG=1) + target_link_libraries(${CoreLibName} + FFmpeg::avcodec + FFmpeg::avformat + FFmpeg::avutil + FFmpeg::swresample + FFmpeg::swscale + ${ZLIB_LIBRARY} + ) endif() # Discord integration -if(NOT IOS) -target_link_libraries(${CoreLibName} discord-rpc) +if(USE_DISCORD AND NOT IOS) + add_definitions(-DUSE_DISCORD=1) + target_link_libraries(${CoreLibName} discord-rpc) endif() setup_target_project(${CoreLibName} Core) @@ -1885,7 +1903,8 @@ set(WindowsFiles Windows/ppsspp.rc Windows/resource.h Windows/stdafx.cpp - Windows/stdafx.h) + Windows/stdafx.h +) list(APPEND LinkCommon ${CoreLibName} ${CMAKE_THREAD_LIBS_INIT}) @@ -1908,7 +1927,10 @@ set(NativeAssets assets/ppge_atlas.zim assets/rargray.png assets/unknown.png - assets/zip.png) + assets/zip.png + source_assets/image/logo.png + source_assets/image/icon_regular_72.png +) if(HEADLESS) @@ -1919,9 +1941,9 @@ if(HEADLESS) headless/Compare.cpp headless/Compare.h headless/SDLHeadlessHost.cpp - headless/SDLHeadlessHost.h) - target_link_libraries(PPSSPPHeadless - ${COCOA_LIBRARY} ${LinkCommon}) + headless/SDLHeadlessHost.h + ) + target_link_libraries(PPSSPPHeadless ${COCOA_LIBRARY} ${LinkCommon}) setup_target_project(PPSSPPHeadless headless) endif() @@ -1936,8 +1958,7 @@ if(UNITTEST) Core/MIPS/ARM/ArmRegCache.cpp Core/MIPS/ARM/ArmRegCacheFPU.cpp ) - target_link_libraries(unitTest - ${COCOA_LIBRARY} ${LinkCommon} Common) + target_link_libraries(unitTest ${COCOA_LIBRARY} ${LinkCommon} Common) setup_target_project(unitTest unittest) endif() @@ -1945,12 +1966,12 @@ if(LIBRETRO) add_subdirectory(libretro) endif() -if (TargetBin) - if (IOS OR APPLE) - if (APPLE AND NOT IOS) - set(ICON_PATH_ABS ${CMAKE_CURRENT_SOURCE_DIR}/icons/ppsspp.icns) - set( MACOSX_BUNDLE_ICON_FILE ppsspp.icns ) - set_source_files_properties(${ICON_PATH_ABS} PROPERTIES MACOSX_PACKAGE_LOCATION "Resources") +if(TargetBin) + if(IOS OR APPLE) + if(APPLE AND NOT IOS) + set(ICON_PATH_ABS ${CMAKE_CURRENT_SOURCE_DIR}/icons/ppsspp.icns) + set(MACOSX_BUNDLE_ICON_FILE ppsspp.icns) + set_source_files_properties(${ICON_PATH_ABS} PROPERTIES MACOSX_PACKAGE_LOCATION "Resources") endif() # TODO: there must a native way to copy these. @@ -1960,17 +1981,17 @@ if (TargetBin) file(GLOB_RECURSE LANG_FILES assets/lang/*) file(GLOB_RECURSE SHADER_FILES assets/shaders/*) - if (APPLE AND NOT IOS) - set_source_files_properties(${NativeAssets} PROPERTIES MACOSX_PACKAGE_LOCATION "MacOS/assets") - set_source_files_properties(${FLASH0_FILES} PROPERTIES MACOSX_PACKAGE_LOCATION "MacOS/assets/flash0/font") - set_source_files_properties(${LANG_FILES} PROPERTIES MACOSX_PACKAGE_LOCATION "MacOS/assets/lang") - set_source_files_properties(${SHADER_FILES} PROPERTIES MACOSX_PACKAGE_LOCATION "MacOS/assets/shaders") + if(APPLE AND NOT IOS) + set_source_files_properties(${NativeAssets} PROPERTIES MACOSX_PACKAGE_LOCATION "MacOS/assets") + set_source_files_properties(${FLASH0_FILES} PROPERTIES MACOSX_PACKAGE_LOCATION "MacOS/assets/flash0/font") + set_source_files_properties(${LANG_FILES} PROPERTIES MACOSX_PACKAGE_LOCATION "MacOS/assets/lang") + set_source_files_properties(${SHADER_FILES} PROPERTIES MACOSX_PACKAGE_LOCATION "MacOS/assets/shaders") endif() - if (IOS) - add_executable(${TargetBin} MACOSX_BUNDLE ${ICON_PATH_ABS} ${NativeAssets} ${SHADER_FILES} ${FLASH0_FILES} ${LANG_FILES} ${NativeAppSource} "ios/Launch Screen.storyboard") + if(IOS) + add_executable(${TargetBin} MACOSX_BUNDLE ${ICON_PATH_ABS} ${NativeAssets} ${SHADER_FILES} ${FLASH0_FILES} ${LANG_FILES} ${NativeAppSource} "ios/Launch Screen.storyboard") else() - add_executable(${TargetBin} MACOSX_BUNDLE ${ICON_PATH_ABS} ${NativeAssets} ${SHADER_FILES} ${FLASH0_FILES} ${LANG_FILES} ${NativeAppSource}) + add_executable(${TargetBin} MACOSX_BUNDLE ${ICON_PATH_ABS} ${NativeAssets} ${SHADER_FILES} ${FLASH0_FILES} ${LANG_FILES} ${NativeAppSource}) endif() elseif(WIN32) add_executable(${TargetBin} WIN32 ${NativeAppSource}) @@ -1988,8 +2009,8 @@ endif() # installs if(NOT ANDROID) -file(INSTALL ${NativeAssets} DESTINATION assets) -file(INSTALL assets/flash0 DESTINATION assets) + file(INSTALL ${NativeAssets} DESTINATION assets) + file(INSTALL assets/flash0 DESTINATION assets) endif() # packaging and code signing if(IOS) @@ -2000,7 +2021,7 @@ if(IOS) file(INSTALL ${IOSAssets} DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/assets) file(GLOB IOSAssets ios/assets/Default-568h@*.png) file(INSTALL ${IOSAssets} DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) - if (IOS_DEBUG) + if(IOS_DEBUG) file(INSTALL pspautotests DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/assets) endif() set(RSRC_XIB_FILES assets/Icon@2x.png) @@ -2008,11 +2029,11 @@ if(IOS) set_source_files_properties(${RSRC_XIB_FILES} PROPERTIES MACOSX_PACKAGE_LOCATION Resources ) - if(CMAKE_GENERATOR STREQUAL "Xcode") - set(APP_DIR_NAME "$(TARGET_BUILD_DIR)/$(FULL_PRODUCT_NAME)") - else() - set(APP_DIR_NAME "$") - endif() + if(CMAKE_GENERATOR STREQUAL "Xcode") + set(APP_DIR_NAME "$(TARGET_BUILD_DIR)/$(FULL_PRODUCT_NAME)") + else() + set(APP_DIR_NAME "$") + endif() add_custom_command(TARGET PPSSPP POST_BUILD COMMAND mkdir -p \"${APP_DIR_NAME}\" COMMAND tar -c -C ${CMAKE_CURRENT_BINARY_DIR} --exclude .DS_Store --exclude .git assets *.png | tar -x -C \"${APP_DIR_NAME}\" @@ -2023,8 +2044,8 @@ if(IOS) RESOURCE "ios/Launch Screen.storyboard" XCODE_ATTRIBUTE_IPHONEOS_DEPLOYMENT_TARGET ${DEPLOYMENT_TARGET} XCODE_ATTRIBUTE_TARGETED_DEVICE_FAMILY "iPhone/iPad" - XCODE_ATTRIBUTE_CLANG_ENABLE_OBJC_ARC YES - XCODE_ATTRIBUTE_ENABLE_BITCODE NO - XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "-" + XCODE_ATTRIBUTE_CLANG_ENABLE_OBJC_ARC YES + XCODE_ATTRIBUTE_ENABLE_BITCODE NO + XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "-" ) endif() diff --git a/Common/Common.vcxproj b/Common/Common.vcxproj index 1c378870d1..5f4fa1688e 100644 --- a/Common/Common.vcxproj +++ b/Common/Common.vcxproj @@ -80,6 +80,7 @@ true false false + ProgramDatabase Windows @@ -107,6 +108,7 @@ true false false + ProgramDatabase Windows @@ -242,7 +244,6 @@ - @@ -314,7 +315,6 @@ - @@ -331,4 +331,4 @@ - \ No newline at end of file + diff --git a/Common/Common.vcxproj.filters b/Common/Common.vcxproj.filters index b49c83fd1f..bad1776855 100644 --- a/Common/Common.vcxproj.filters +++ b/Common/Common.vcxproj.filters @@ -58,9 +58,6 @@ - - Vulkan - Vulkan @@ -119,9 +116,6 @@ GL\GLInterface - - Vulkan - Vulkan @@ -155,4 +149,4 @@ {c14d66ef-5f7c-4565-975a-72774e7ccfb9} - \ No newline at end of file + diff --git a/Common/FileUtil.cpp b/Common/FileUtil.cpp index c6a19a2c00..c6fbd73eff 100644 --- a/Common/FileUtil.cpp +++ b/Common/FileUtil.cpp @@ -30,6 +30,7 @@ #ifdef _WIN32 #include "CommonWindows.h" +#include #include // for SHGetFolderPath #include #include // for GetSaveFileName @@ -121,7 +122,11 @@ std::string ResolvePath(const std::string &path) { std::wstring input = ConvertUTF8ToWString(path); if (getFinalPathNameByHandleW) { +#if PPSSPP_PLATFORM(UWP) + HANDLE hFile = CreateFile2(input.c_str(), GENERIC_READ, FILE_SHARE_READ, OPEN_EXISTING, nullptr); +#else HANDLE hFile = CreateFile(input.c_str(), GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, nullptr); +#endif if (hFile == INVALID_HANDLE_VALUE) { wcscpy_s(buf, BUF_SIZE - 1, input.c_str()); } else { @@ -336,7 +341,7 @@ bool CreateFullPath(const std::string &path) return true; } std::string subPath = fullPath.substr(0, position); - if (!File::Exists(subPath)) + if (position != 0 && !File::Exists(subPath)) File::CreateDir(subPath); // A safety check @@ -647,7 +652,6 @@ bool DeleteDirRecursively(const std::string &directory) if (hFind == INVALID_HANDLE_VALUE) { - FindClose(hFind); return false; } @@ -656,17 +660,16 @@ bool DeleteDirRecursively(const std::string &directory) { const std::string virtualName = ConvertWStringToUTF8(ffd.cFileName); #else - struct dirent dirent, *result = NULL; + struct dirent *result = NULL; DIR *dirp = opendir(directory.c_str()); if (!dirp) return false; // non windows loop - while (!readdir_r(dirp, &dirent, &result) && result) + while ((result = readdir(dirp))) { const std::string virtualName = result->d_name; #endif - // check for "." and ".." if (((virtualName[0] == '.') && (virtualName[1] == '\0')) || ((virtualName[0] == '.') && (virtualName[1] == '.') && @@ -678,10 +681,11 @@ bool DeleteDirRecursively(const std::string &directory) { if (!DeleteDirRecursively(newPath)) { - #ifndef _WIN32 +#ifndef _WIN32 closedir(dirp); - #endif - +#else + FindClose(hFind); +#endif return false; } } @@ -689,10 +693,11 @@ bool DeleteDirRecursively(const std::string &directory) { if (!File::Delete(newPath)) { - #ifndef _WIN32 +#ifndef _WIN32 closedir(dirp); - #endif - +#else + FindClose(hFind); +#endif return false; } } @@ -704,8 +709,7 @@ bool DeleteDirRecursively(const std::string &directory) } closedir(dirp); #endif - File::DeleteDir(directory); - return true; + return File::DeleteDir(directory); #endif } @@ -718,13 +722,11 @@ void CopyDir(const std::string &source_path, const std::string &dest_path) if (!File::Exists(source_path)) return; if (!File::Exists(dest_path)) File::CreateFullPath(dest_path); - struct dirent_large { struct dirent entry; char padding[FILENAME_MAX+1]; }; - struct dirent_large diren; struct dirent *result = NULL; DIR *dirp = opendir(source_path.c_str()); if (!dirp) return; - while (!readdir_r(dirp, (dirent*) &diren, &result) && result) + while ((result = readdir(dirp))) { const std::string virtualName(result->d_name); // check for "." and ".." diff --git a/Common/OSVersion.cpp b/Common/OSVersion.cpp index eb65b3fabf..1103fb8ad6 100644 --- a/Common/OSVersion.cpp +++ b/Common/OSVersion.cpp @@ -7,6 +7,7 @@ #endif #include +#include #include "OSVersion.h" #include "Common/CommonWindows.h" diff --git a/Common/StringUtils.cpp b/Common/StringUtils.cpp index 1946d0df92..c1289720b0 100644 --- a/Common/StringUtils.cpp +++ b/Common/StringUtils.cpp @@ -95,4 +95,20 @@ bool SplitPath(const std::string& full_path, std::string* _pPath, std::string* _ *_pExtension = full_path.substr(fname_end); return true; -} \ No newline at end of file +} + +std::string GetFilenameFromPath(std::string full_path) { + size_t pos; +#ifdef _WIN32 + pos = full_path.rfind('\\'); + if (pos != std::string::npos) { + return full_path.substr(pos + 1); + } +#endif + pos = full_path.rfind('/'); + if (pos != std::string::npos) { + return full_path.substr(pos + 1); + } + // No directory components, just return the full path. + return full_path; +} diff --git a/Common/StringUtils.h b/Common/StringUtils.h index 5b53423a03..58d433697c 100644 --- a/Common/StringUtils.h +++ b/Common/StringUtils.h @@ -45,3 +45,5 @@ inline void CharArrayFromFormat(char (& out)[Count], const char* format, ...) // "C:/Windows/winhelp.exe" to "C:/Windows/", "winhelp", ".exe" bool SplitPath(const std::string& full_path, std::string* _pPath, std::string* _pFilename, std::string* _pExtension); + +std::string GetFilenameFromPath(std::string full_path); diff --git a/Common/Vulkan/SPIRVDisasm.cpp b/Common/Vulkan/SPIRVDisasm.cpp deleted file mode 100644 index 4d7a24c2cb..0000000000 --- a/Common/Vulkan/SPIRVDisasm.cpp +++ /dev/null @@ -1,617 +0,0 @@ -#include - -#include "Common/StringUtils.h" -#include "Common/Vulkan/SPIRVDisasm.h" -#include "ext/vulkan/spirv.hpp" - -#define WRITE p+=sprintf - -struct SpirvID { - std::string name; - int opcode; -}; - -struct OpInfo { - const char *name; - const char *extra; -}; - -static const char *executionModelNames[] = { - "Vertex", // 0, - "TessellationControl", // 1, - "TessellationEvaluation", // 2, - "Geometry", // 3, - "Fragment", // 4, - "GLCompute", // 5, - "Kernel", // 6, -}; - -static const char *storageClassNames[] = { - "UniformConstant", - "Input", - "Uniform", - "Output", - "Workgroup", - "CrossWorkgroup", - "Private", - "Function", - "Generic", - "PushConstant", - "AtomicCounter", - "Image", -}; - -static const char *decorationNames[] = { - "RelaxedPrecision", // 0, - "SpecId", // 1, - "Block", // 2, - "BufferBlock", // 3, - "RowMajor", // 4, - "ColMajor", // 5, - "ArrayStride", // 6, - "MatrixStride", // 7, - "GLSLShared", // 8, - "GLSLPacked", // 9, - "CPacked", // 10, - "BuiltIn", // 11, - nullptr, // 12 - "NoPerspective", // 13, - "Flat", // 14, - "Patch", // 15, - "Centroid", // 16, - "Sample", // 17, - "Invariant", // 18, - "Restrict", // 19, - "Aliased", // 20, - "Volatile", // 21, - "Constant", // 22, - "Coherent", // 23, - "NonWritable", // 24, - "NonReadable", // 25, - "Uniform", // 26, - nullptr, // 27 - "SaturatedConversion", // 28, - "Stream", // 29, - "Location", // 30, - "Component", // 31, - "Index", // 32, - "Binding", // 33, - "DescriptorSet", // 34, - "Offset", // 35, - "XfbBuffer", // 36, - "XfbStride", // 37, - "FuncParamAttr", // 38, - "FPRoundingMode", // 39, - "FPFastMathMode", // 40, - "LinkageAttributes", // 41, - "NoContraction", // 42, - "InputAttachmentIndex", // 43, - "Alignment", // 44, -}; - -static const OpInfo opInfo[] = { - {"Nop"}, // 0, - {"Undef"}, // 1, - {"SourceContinued"}, // 2, - {"Source"}, // 3, - {"SourceExtension"}, // 4, - {"Name"}, // 5, - {"MemberName"}, // 6, - {"String"}, // 7, - {"Line"}, // 8, - {nullptr}, // 9 - {"Extension"}, // 10, - {"ExtInstImport"}, // 11, - {"ExtInst"}, // 12, - {nullptr}, // 13 - {"MemoryModel"}, // 14, - {"EntryPoint"}, // 15, - {"ExecutionMode"}, // 16, - {"Capability"}, // 17, - {nullptr}, // 18 - {"TypeVoid"}, // 19, - {"TypeBool"}, // 20, - {"TypeInt"}, // 21, - {"TypeFloat"}, // 22, - {"TypeVector"}, // 23, - {"TypeMatrix"}, // 24, - {"TypeImage"}, // 25, - {"TypeSampler"}, // 26, - {"TypeSampledImage"}, // 27, - {"TypeArray"}, // 28, - {"TypeRuntimeArray"}, // 29, - {"TypeStruct"}, // 30, - {"TypeOpaque"}, // 31, - {"TypePointer"}, // 32, - {"TypeFunction"}, // 33, - {"TypeEvent"}, // 34, - {"TypeDeviceEvent"}, // 35, - {"TypeReserveId"}, // 36, - {"TypeQueue"}, // 37, - {"TypePipe"}, // 38, - {"TypeForwardPointer"}, // 39, - {nullptr}, // 40 - {"ConstantTrue"}, // 41, - {"ConstantFalse"}, // 42, - {"Constant"}, // 43, - {"ConstantComposite"}, // 44, - {"ConstantSampler"}, // 45, - {"ConstantNull"}, // 46, - {nullptr}, // 47 - {"SpecConstantTrue"}, // 48, - {"SpecConstantFalse"}, // 49, - {"SpecConstant"}, // 50, - {"SpecConstantComposite"}, // 51, - {"SpecConstantOp"}, // 52, - {nullptr}, // 53 - {"Function"}, // 54, - {"FunctionParameter"}, // 55, - {"FunctionEnd"}, // 56, - {"FunctionCall"}, // 57, - {nullptr}, // 58 - {"Variable"}, // 59, - {"ImageTexelPointer"}, // 60, - {"Load"}, // 61, - {"Store"}, // 62, - {"CopyMemory"}, // 63, - {"CopyMemorySized"}, // 64, - {"AccessChain"}, // 65, - {"InBoundsAccessChain"}, // 66, - {"PtrAccessChain"}, // 67, - {"ArrayLength"}, // 68, - {"GenericPtrMemSemantics"}, // 69, - {"InBoundsPtrAccessChain"}, // 70, - {"Decorate"}, // 71, - {"MemberDecorate"}, // 72, - {"DecorationGroup"}, // 73, - {"GroupDecorate"}, // 74, - {"GroupMemberDecorate"}, // 75, - {nullptr}, // 76 - {"VectorExtractDynamic"}, // 77, - {"VectorInsertDynamic"}, // 78, - {"VectorShuffle"}, // 79, - {"CompositeConstruct"}, // 80, - {"CompositeExtract"}, // 81, - {"CompositeInsert"}, // 82, - {"CopyObject"}, // 83, - {"Transpose"}, // 84, - {nullptr}, // 85 - {"SampledImage"}, // 86, - {"ImageSampleImplicitLod"}, // 87, - {"ImageSampleExplicitLod"}, // 88, - {"ImageSampleDrefImplicitLod"}, // 89, - {"ImageSampleDrefExplicitLod"}, // 90, - {"ImageSampleProjImplicitLod"}, // 91, - {"ImageSampleProjExplicitLod"}, // 92, - {"ImageSampleProjDrefImplicitLod"}, // 93, - {"ImageSampleProjDrefExplicitLod"}, // 94, - {"ImageFetch"}, // 95, - {"ImageGather"}, // 96, - {"ImageDrefGather"}, // 97, - {"ImageRead"}, // 98, - {"ImageWrite"}, // 99, - {"Image"}, // 100, - {"ImageQueryFormat"}, // 101, - {"ImageQueryOrder"}, // 102, - {"ImageQuerySizeLod"}, // 103, - {"ImageQuerySize"}, // 104, - {"ImageQueryLod"}, // 105, - {"ImageQueryLevels"}, // 106, - {"ImageQuerySamples"}, // 107, - {nullptr}, // 108 - {"ConvertFToU"}, // 109, - {"ConvertFToS"}, // 110, - {"ConvertSToF"}, // 111, - {"ConvertUToF"}, // 112, - {"UConvert"}, // 113, - {"SConvert"}, // 114, - {"FConvert"}, // 115, - {"QuantizeToF16"}, // 116, - {"ConvertPtrToU"}, // 117, - {"SatConvertSToU"}, // 118, - {"SatConvertUToS"}, // 119, - {"ConvertUToPtr"}, // 120, - {"PtrCastToGeneric"}, // 121, - {"GenericCastToPtr"}, // 122, - {"GenericCastToPtrExplicit"}, // 123, - {"Bitcast"}, // 124, - {nullptr}, // 125 - {"SNegate"}, // 126, - {"FNegate"}, // 127, - {"IAdd"}, // 128, - {"FAdd", "+"}, // 129, - {"ISub"}, // 130, - {"FSub", "-"}, // 131, - {"IMul"}, // 132, - {"FMul", "*"}, // 133, - {"UDiv"}, // 134, - {"SDiv"}, // 135, - {"FDiv", "/"}, // 136, - {"UMod"}, // 137, - {"SRem"}, // 138, - {"SMod"}, // 139, - {"FRem"}, // 140, - {"FMod", "%"}, // 141, - {"VectorTimesScalar"}, // 142, - {"MatrixTimesScalar"}, // 143, - {"VectorTimesMatrix"}, // 144, - {"MatrixTimesVector"}, // 145, - {"MatrixTimesMatrix"}, // 146, - {"OuterProduct"}, // 147, - {"Dot", " dot "}, // 148, - {"IAddCarry"}, // 149, - {"ISubBorrow"}, // 150, - {"UMulExtended"}, // 151, - {"SMulExtended"}, // 152, - {nullptr}, // 153 - {"Any"}, // 154, - {"All"}, // 155, - {"IsNan"}, // 156, - {"IsInf"}, // 157, - {"IsFinite"}, // 158, - {"IsNormal"}, // 159, - {"SignBitSet"}, // 160, - {"LessOrGreater"}, // 161, - {"Ordered"}, // 162, - {"Unordered"}, // 163, - {"LogicalEqual"}, // 164, - {"LogicalNotEqual"}, // 165, - {"LogicalOr"}, // 166, - {"LogicalAnd"}, // 167, - {"LogicalNot"}, // 168, - {"Select"}, // 169, - {"IEqual"}, // 170, - {"INotEqual"}, // 171, - {"UGreaterThan"}, // 172, - {"SGreaterThan"}, // 173, - {"UGreaterThanEqual"}, // 174, - {"SGreaterThanEqual"}, // 175, - {"ULessThan"}, // 176, - {"SLessThan"}, // 177, - {"ULessThanEqual"}, // 178, - {"SLessThanEqual"}, // 179, - {"FOrdEqual", "=="}, // 180, - {"FUnordEqual", "=="}, // 181, - {"FOrdNotEqual", "!="}, // 182, - {"FUnordNotEqual", "!="}, // 183, - {"FOrdLessThan"}, // 184, - {"FUnordLessThan"}, // 185, - {"FOrdGreaterThan"}, // 186, - {"FUnordGreaterThan"}, // 187, - {"FOrdLessThanEqual"}, // 188, - {"FUnordLessThanEqual"}, // 189, - {"FOrdGreaterThanEqual"}, // 190, - {"FUnordGreaterThanEqual"}, // 191, - { nullptr }, // 192 - { nullptr }, // 193 - {"ShiftRightLogical"}, // 194, - {"ShiftRightArithmetic"}, // 195, - {"ShiftLeftLogical"}, // 196, - {"BitwiseOr", "|"}, // 197, - {"BitwiseXor", "^"}, // 198, - {"BitwiseAnd", "&"}, // 199, - {"Not", "~"}, // 200, - {"BitFieldInsert"}, // 201, - {"BitFieldSExtract"}, // 202, - {"BitFieldUExtract"}, // 203, - {"BitReverse"}, // 204, - {"BitCount"}, // 205, - {nullptr}, - {"DPdx"}, // 207, - {"DPdy"}, // 208, - {"Fwidth"}, // 209, - {"DPdxFine"}, // 210, - {"DPdyFine"}, // 211, - {"FwidthFine"}, // 212, - {"DPdxCoarse"}, // 213, - {"DPdyCoarse"}, // 214, - {"FwidthCoarse"}, // 215, - {nullptr}, // 216 - {nullptr}, // 217 - {"EmitVertex"}, // 218, - {"EndPrimitive"}, // 219, - {"EmitStreamVertex"}, // 220, - {"EndStreamPrimitive"}, // 221, - {nullptr}, // 222 - {nullptr}, // 223 - {"ControlBarrier"}, // 224, - {"MemoryBarrier"}, // 225, - {nullptr}, // 226 - {"AtomicLoad"}, // 227, - {"AtomicStore"}, // 228, - {"AtomicExchange"}, // 229, - {"AtomicCompareExchange"}, // 230, - {"AtomicCompareExchangeWeak"}, // 231, - {"AtomicIIncrement"}, // 232, - {"AtomicIDecrement"}, // 233, - {"AtomicIAdd"}, // 234, - {"AtomicISub"}, // 235, - {"AtomicSMin"}, // 236, - {"AtomicUMin"}, // 237, - {"AtomicSMax"}, // 238, - {"AtomicUMax"}, // 239, - {"AtomicAnd"}, // 240, - {"AtomicOr"}, // 241, - {"AtomicXor"}, // 242, - { nullptr }, // 243, - { nullptr }, // 244, - {"Phi"}, // 245, - {"LoopMerge"}, // 246, - {"SelectionMerge"}, // 247, - {"Label"}, // 248, - {"Branch"}, // 249, - {"BranchConditional"}, // 250, - {"Switch"}, // 251, - {"Kill"}, // 252, - {"Return"}, // 253, - {"ReturnValue"}, // 254, - {"Unreachable"}, // 255, - {"LifetimeStart"}, // 256, - {"LifetimeStop"}, // 257, - { nullptr }, - {"GroupAsyncCopy"}, // 259, - {"GroupWaitEvents"}, // 260, - {"GroupAll"}, // 261, - {"GroupAny"}, // 262, - {"GroupBroadcast"}, // 263, - {"GroupIAdd"}, // 264, - {"GroupFAdd"}, // 265, - {"GroupFMin"}, // 266, - {"GroupUMin"}, // 267, - {"GroupSMin"}, // 268, - {"GroupFMax"}, // 269, - {"GroupUMax"}, // 270, - {"GroupSMax"}, // 271, - {nullptr}, // 272 - {nullptr}, // 273 - {"ReadPipe"}, // 274, - {"WritePipe"}, // 275, - {"ReservedReadPipe"}, // 276, - {"ReservedWritePipe"}, // 277, - {"ReserveReadPipePackets"}, // 278, - {"ReserveWritePipePackets"}, // 279, - {"CommitReadPipe"}, // 280, - {"CommitWritePipe"}, // 281, - {"IsValidReserveId"}, // 282, - {"GetNumPipePackets"}, // 283, - {"GetMaxPipePackets"}, // 284, - {"GroupReserveReadPipePackets"}, // 285, - {"GroupReserveWritePipePackets"}, // 286, - {"GroupCommitReadPipe"}, // 287, - {"GroupCommitWritePipe"}, // 288, - { nullptr }, // 289 - { nullptr }, // 290 - {"EnqueueMarker"}, // 291, - {"EnqueueKernel"}, // 292, - {"GetKernelNDrangeSubGroupCount"}, // 293, - {"GetKernelNDrangeMaxSubGroupSize"}, // 294, - {"GetKernelWorkGroupSize"}, // 295, - {"GetKernelPreferredWorkGroupSizeMultiple"}, // 296, - {"RetainEvent"}, // 297, - {"ReleaseEvent"}, // 298, - {"CreateUserEvent"}, // 299, - {"IsValidEvent"}, // 300, - {"SetUserEventStatus"}, // 301, - {"CaptureEventProfilingInfo"}, // 302, - {"GetDefaultQueue"}, // 303, - {"BuildNDRange"}, // 304, - {"ImageSparseSampleImplicitLod"}, // 305, - {"ImageSparseSampleExplicitLod"}, // 306, - {"ImageSparseSampleDrefImplicitLod"}, // 307, - {"ImageSparseSampleDrefExplicitLod"}, // 308, - {"ImageSparseSampleProjImplicitLod"}, // 309, - {"ImageSparseSampleProjExplicitLod"}, // 310, - {"ImageSparseSampleProjDrefImplicitLod"}, // 311, - {"ImageSparseSampleProjDrefExplicitLod"}, // 312, - {"ImageSparseFetch"}, // 313, - {"ImageSparseGather"}, // 314, - {"ImageSparseDrefGather"}, // 315, - {"ImageSparseTexelsResident"}, // 316, - {"NoLine"}, // 317, - {"AtomicFlagTestAndSet"}, // 318, - {"AtomicFlagClear"}, // 319, -}; - -static std::string ReadSpirvString(const std::vector &spirv, int offset, int *outOffset = nullptr) { - bool done = false; - std::string temp; - while (!done) { - uint32_t data = spirv[offset++]; - for (int i = 0; i < 4; i++) { - char c = (char)(data & 0xff); - if (!c) { - done = true; - break; - } - temp.push_back(data); - data >>= 8; - } - if (offset == (int)spirv.size()) - break; - } - if (outOffset) - *outOffset = offset; - return temp; -} - -bool DisassembleSPIRV(std::vector spirv, std::string *output) { - if (spirv.size() < 10) { - *output = "Too small"; - return false; - } - uint32_t magic = spirv[0]; - uint32_t version = spirv[1]; - uint32_t generator = spirv[2]; - - int bound = (int)spirv[3]; // Max ID used in file. - // spirv[4] is reserved for schema. - std::vector ids; - ids.resize(bound); - for (int i = 0; i < bound; i++) { - ids[i].name = StringFromFormat("%%%d", i); - } - - if (magic != 0x07230203) { - *output = "Not SPIRV"; - return false; - } - - int indent = 0; - - char *buffer = new char[1024 * 1024]; - char *p = buffer; - - WRITE(p, "// ======= SPIR-V version %08x =======\n// Max ID: %d\n", version, bound); // GLSL ES - - int i = 5; - while (i < (int)spirv.size()) { - uint32_t d = spirv[i]; - int wordCount = d >> 16; - int opcode = d & 0xFFFF; - // Force to a valid index in the array. - const OpInfo &op = opInfo[opcode >= (int)ARRAY_SIZE(opInfo) ? 0 : opcode]; - int target = (i < (int)spirv.size() - 1) ? spirv[(i + 1)] : 0; // Not always, but used often enough that we get it here. - int source, source2, resType; - std::string name; - switch (opcode) { - case spv::OpTypeVoid: - case spv::OpTypeBool: - case spv::OpTypeInt: - case spv::OpTypeFloat: - case spv::OpTypeMatrix: - case spv::OpTypeImage: - case spv::OpTypeSampler: - case spv::OpTypeSampledImage: - case spv::OpTypeRuntimeArray: - case spv::OpTypeOpaque: - case spv::OpTypePointer: - case spv::OpTypeFunction: - case spv::OpTypeEvent: - case spv::OpTypeDeviceEvent: - case spv::OpTypeReserveId: - case spv::OpTypeQueue: - case spv::OpTypePipe: - case spv::OpTypeForwardPointer: - ids[target].name = op.name + 4; // Remove "Type" - ids[target].opcode = opcode; - break; - case spv::OpTypeVector: - source = spirv[i + 2]; - source2 = spirv[i + 3]; - ids[target].name = ids[source].name + StringFromFormat("%d", source2); - break; - case spv::OpTypeArray: - source = spirv[i + 2]; - source2 = spirv[i + 3]; - ids[target].name = ids[source].name + "[" + ids[source2].name + "]"; - break; - case spv::OpTypeStruct: - { - ids[target].name = "struct" + ids[target].name; - WRITE(p, "struct {\n"); - if (wordCount == 3) { - source = spirv[i + 2]; - WRITE(p, " %s\n", ids[source].name.c_str()); - } else { - int numMembers = (wordCount - 2) / 2; - for (int m = 0; m < numMembers; m++) { - int id = spirv[i + 2 + m]; - int type = spirv[i + 2 + m + numMembers]; - WRITE(p, " %s %s;\n", ids[type].name.c_str(), ids[id].name.c_str()); - } - } - WRITE(p, "};\n"); - } - break; - case spv::OpVariable: - resType = spirv[i + 1]; - target = spirv[i + 2]; - source = spirv[i + 3]; - source2 = spirv[i + 4]; - ids[target].name = storageClassNames[source]; - break; - case spv::OpDecorate: - source = spirv[i + 2]; - ids[target].name += std::string("[") + decorationNames[source] + "]"; - break; - case spv::OpName: - ids[target].name = ReadSpirvString(spirv, i + 2); - // WRITE(p, "Name %d: '%s'\n", target, ids[target].name.c_str()); - break; - case spv::OpMemberName: - break; - case spv::OpStore: - source = spirv[i + 2]; - WRITE(p, "Store(%s, %s)\n", ids[target].name.c_str(), ids[source].name.c_str()); - break; - case spv::OpLoad: - resType = spirv[i + 1]; - target = spirv[i + 2]; - source = spirv[i + 3]; - WRITE(p, "%s (%s) := Load(%s)\n", ids[target].name.c_str(), ids[resType].name.c_str(), ids[source].name.c_str()); - break; - case spv::OpFAdd: - case spv::OpFMul: - case spv::OpFDiv: - case spv::OpFSub: - resType = spirv[i + 2]; - source = spirv[i + 3]; - source2 = spirv[i + 4]; - WRITE(p, "%s (%s) := %s %s %s\n", ids[target].name.c_str(), ids[resType].name.c_str(), ids[source].name.c_str(), op.extra, ids[source2].name.c_str()); - break; - - case spv::OpCapability: - case spv::OpMemoryModel: - case spv::OpExtInstImport: - case spv::OpExecutionMode: - case spv::OpGroupAsyncCopy: - case spv::OpSource: - case spv::OpExtension: - // hide these for now - break; - - case spv::OpEntryPoint: - source = spirv[i + 1]; - source2 = spirv[i + 2]; - name = ReadSpirvString(spirv, i + 3); - WRITE(p, "EntryPoint %s: '%s' %s : %s\n", executionModelNames[target], ids[source].name.c_str(), ids[source2].name.c_str(), name.c_str()); - break; - - case spv::OpFunction: - resType = spirv[i + 1]; - target = spirv[i + 2]; - source = spirv[i + 3]; - ids[target].name = ids[resType].name + "()"; - WRITE(p, "Function %s {\n", ids[target].name.c_str()); - break; - - case spv::OpLabel: - WRITE(p, "label %s:\n", ids[target].name.c_str()); - break; - - case spv::OpReturnValue: - WRITE(p, "return %s\n", ids[target].name.c_str()); - break; - - case spv::OpReturn: - WRITE(p, "return\n"); - break; - - case spv::OpFunctionEnd: - WRITE(p, "}\n"); - break; - - case spv::OpSourceExtension: - break; - - default: - WRITE(p, "%s (%d data words)\n", op.name, wordCount - 1); - break; - } - i += wordCount; - } - - *output = buffer; - delete[] buffer; - return true; -} diff --git a/Common/Vulkan/SPIRVDisasm.h b/Common/Vulkan/SPIRVDisasm.h deleted file mode 100644 index d5d036fbb4..0000000000 --- a/Common/Vulkan/SPIRVDisasm.h +++ /dev/null @@ -1,10 +0,0 @@ -#pragma once - -#include -#include -#include - -// Mostly just a toy to understand SPIR-V better. Not an accurate SPIR-V disassembler, -// and the result will not reassemble. - -bool DisassembleSPIRV(std::vector spirv, std::string *output); \ No newline at end of file diff --git a/Common/Vulkan/VulkanContext.cpp b/Common/Vulkan/VulkanContext.cpp index 299641d268..c71d9edbbe 100644 --- a/Common/Vulkan/VulkanContext.cpp +++ b/Common/Vulkan/VulkanContext.cpp @@ -60,7 +60,7 @@ static const char *validationLayers[] = { std::string VulkanVendorString(uint32_t vendorId) { switch (vendorId) { case VULKAN_VENDOR_INTEL: return "Intel"; - case VULKAN_VENDOR_NVIDIA: return "nVidia"; + case VULKAN_VENDOR_NVIDIA: return "NVIDIA"; case VULKAN_VENDOR_AMD: return "AMD"; case VULKAN_VENDOR_ARM: return "ARM"; case VULKAN_VENDOR_QUALCOMM: return "Qualcomm"; @@ -77,6 +77,8 @@ const char *PresentModeString(VkPresentModeKHR presentMode) { case VK_PRESENT_MODE_MAILBOX_KHR: return "MAILBOX"; case VK_PRESENT_MODE_FIFO_KHR: return "FIFO"; case VK_PRESENT_MODE_FIFO_RELAXED_KHR: return "FIFO_RELAXED"; + case VK_PRESENT_MODE_SHARED_DEMAND_REFRESH_KHR: return "SHARED_DEMAND_REFRESH_KHR"; + case VK_PRESENT_MODE_SHARED_CONTINUOUS_REFRESH_KHR: return "SHARED_CONTINUOUS_REFRESH_KHR"; default: return "UNKNOWN"; } } @@ -120,9 +122,6 @@ VkResult VulkanContext::CreateInstance(const CreateInfo &info) { //#if defined(VK_USE_PLATFORM_XCB_KHR) // instance_extensions_enabled_.push_back(VK_KHR_XCB_SURFACE_EXTENSION_NAME); //#endif -//#if defined(VK_USE_PLATFORM_MIR_KHR) -// instance_extensions_enabled_.push_back(VK_KHR_MIR_SURFACE_EXTENSION_NAME); -//#endif #if defined(VK_USE_PLATFORM_WAYLAND_KHR) if (IsInstanceExtensionAvailable(VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME)) { instance_extensions_enabled_.push_back(VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME); @@ -131,18 +130,32 @@ VkResult VulkanContext::CreateInstance(const CreateInfo &info) { #endif if (flags_ & VULKAN_FLAG_VALIDATE) { - if (IsInstanceExtensionAvailable(VK_EXT_DEBUG_REPORT_EXTENSION_NAME)) { + if (IsInstanceExtensionAvailable(VK_EXT_DEBUG_UTILS_EXTENSION_NAME)) { + // Enable the validation layers + for (size_t i = 0; i < ARRAY_SIZE(validationLayers); i++) { + instance_layer_names_.push_back(validationLayers[i]); + device_layer_names_.push_back(validationLayers[i]); + } + instance_extensions_enabled_.push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME); + extensionsLookup_.EXT_debug_utils = true; + } else if (IsInstanceExtensionAvailable(VK_EXT_DEBUG_REPORT_EXTENSION_NAME)) { for (size_t i = 0; i < ARRAY_SIZE(validationLayers); i++) { instance_layer_names_.push_back(validationLayers[i]); device_layer_names_.push_back(validationLayers[i]); } instance_extensions_enabled_.push_back(VK_EXT_DEBUG_REPORT_EXTENSION_NAME); + extensionsLookup_.EXT_debug_report = true; } else { ELOG("Validation layer extension not available - not enabling Vulkan validation."); flags_ &= ~VULKAN_FLAG_VALIDATE; } } + if (IsInstanceExtensionAvailable(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) { + instance_extensions_enabled_.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); + extensionsLookup_.KHR_get_physical_device_properties2 = true; + } + // Validate that all the instance extensions we ask for are actually available. for (auto ext : instance_extensions_enabled_) { if (!IsInstanceExtensionAvailable(ext)) @@ -190,7 +203,7 @@ VkResult VulkanContext::CreateInstance(const CreateInfo &info) { return res; } - VulkanLoadInstanceFunctions(instance_); + VulkanLoadInstanceFunctions(instance_, extensionsLookup_); if (!CheckLayers(instance_layer_properties_, instance_layer_names_)) { WLOG("CheckLayers for instance failed"); // init_error_ = "Failed to validate instance layers"; @@ -222,8 +235,25 @@ VkResult VulkanContext::CreateInstance(const CreateInfo &info) { return res; } - for (uint32_t i = 0; i < gpu_count; i++) { - vkGetPhysicalDeviceProperties(physical_devices_[i], &physicalDeviceProperties_[i]); + if (extensionsLookup_.KHR_get_physical_device_properties2) { + for (uint32_t i = 0; i < gpu_count; i++) { + VkPhysicalDeviceProperties2 props2{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2}; + VkPhysicalDevicePushDescriptorPropertiesKHR pushProps{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PUSH_DESCRIPTOR_PROPERTIES_KHR}; + VkPhysicalDeviceExternalMemoryHostPropertiesEXT extHostMemProps{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_MEMORY_HOST_PROPERTIES_EXT}; + props2.pNext = &pushProps; + pushProps.pNext = &extHostMemProps; + vkGetPhysicalDeviceProperties2KHR(physical_devices_[i], &props2); + // Don't want bad pointers sitting around. + props2.pNext = nullptr; + pushProps.pNext = nullptr; + physicalDeviceProperties_[i].properties = props2.properties; + physicalDeviceProperties_[i].pushDescriptorProperties = pushProps; + physicalDeviceProperties_[i].externalMemoryHostProperties = extHostMemProps; + } + } else { + for (uint32_t i = 0; i < gpu_count; i++) { + vkGetPhysicalDeviceProperties(physical_devices_[i], &physicalDeviceProperties_[i].properties); + } } return VK_SUCCESS; } @@ -423,7 +453,7 @@ bool VulkanContext::CheckLayers(const std::vector &layer_props, int VulkanContext::GetPhysicalDeviceByName(std::string name) { for (size_t i = 0; i < physical_devices_.size(); i++) { - if (physicalDeviceProperties_[i].deviceName == name) + if (physicalDeviceProperties_[i].properties.deviceName == name) return (int)i; } return -1; @@ -505,41 +535,56 @@ void VulkanContext::ChooseDevice(int physical_device) { ELOG("Could not find a usable depth stencil format."); } - // This is as good a place as any to do this + // This is as good a place as any to do this. vkGetPhysicalDeviceMemoryProperties(physical_devices_[physical_device_], &memory_properties); + ILOG("Memory Types (%d):", memory_properties.memoryTypeCount); + for (int i = 0; i < (int)memory_properties.memoryTypeCount; i++) { + // Don't bother printing dummy memory types. + if (!memory_properties.memoryTypes[i].propertyFlags) + continue; + ILOG(" %d: Heap %d; Flags: %s%s%s%s ", i, memory_properties.memoryTypes[i].heapIndex, + (memory_properties.memoryTypes[i].propertyFlags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) ? "DEVICE_LOCAL " : "", + (memory_properties.memoryTypes[i].propertyFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) ? "HOST_VISIBLE " : "", + (memory_properties.memoryTypes[i].propertyFlags & VK_MEMORY_PROPERTY_HOST_CACHED_BIT) ? "HOST_CACHED " : "", + (memory_properties.memoryTypes[i].propertyFlags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT) ? "HOST_COHERENT " : ""); + } // Optional features - vkGetPhysicalDeviceFeatures(physical_devices_[physical_device_], &featuresAvailable_); - memset(&featuresEnabled_, 0, sizeof(featuresEnabled_)); + if (extensionsLookup_.KHR_get_physical_device_properties2) { + VkPhysicalDeviceFeatures2 features2{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2_KHR}; + vkGetPhysicalDeviceFeatures2KHR(physical_devices_[physical_device_], &features2); + deviceFeatures_.available = features2.features; + } else { + vkGetPhysicalDeviceFeatures(physical_devices_[physical_device_], &deviceFeatures_.available); + } + + deviceFeatures_.enabled = {}; // Enable a few safe ones if they are available. - if (featuresAvailable_.dualSrcBlend && physicalDeviceProperties_[physical_device_].vendorID != VULKAN_VENDOR_QUALCOMM) { - featuresEnabled_.dualSrcBlend = true; + if (deviceFeatures_.available.dualSrcBlend) { + deviceFeatures_.enabled.dualSrcBlend = true; } - if (featuresAvailable_.largePoints) { - featuresEnabled_.largePoints = true; + if (deviceFeatures_.available.largePoints) { + deviceFeatures_.enabled.largePoints = true; } - if (featuresAvailable_.wideLines) { - featuresEnabled_.wideLines = true; + if (deviceFeatures_.available.wideLines) { + deviceFeatures_.enabled.wideLines = true; } - if (featuresAvailable_.geometryShader) { - featuresEnabled_.geometryShader = true; + if (deviceFeatures_.available.logicOp) { + deviceFeatures_.enabled.logicOp = true; } - if (featuresAvailable_.logicOp) { - featuresEnabled_.logicOp = true; + if (deviceFeatures_.available.depthClamp) { + deviceFeatures_.enabled.depthClamp = true; } - if (featuresAvailable_.depthClamp) { - featuresEnabled_.depthClamp = true; + if (deviceFeatures_.available.depthBounds) { + deviceFeatures_.enabled.depthBounds = true; } - if (featuresAvailable_.depthBounds) { - featuresEnabled_.depthBounds = true; - } - if (featuresAvailable_.samplerAnisotropy) { - featuresEnabled_.samplerAnisotropy = true; + if (deviceFeatures_.available.samplerAnisotropy) { + deviceFeatures_.enabled.samplerAnisotropy = true; } // For easy wireframe mode, someday. - if (featuresEnabled_.fillModeNonSolid) { - featuresEnabled_.fillModeNonSolid = true; + if (deviceFeatures_.available.fillModeNonSolid) { + deviceFeatures_.enabled.fillModeNonSolid = true; } GetDeviceLayerExtensionList(nullptr, device_extension_properties_); @@ -563,8 +608,8 @@ VkResult VulkanContext::CreateDevice() { return VK_ERROR_INITIALIZATION_FAILED; } - VkDeviceQueueCreateInfo queue_info{ VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO }; - float queue_priorities[1] = { 1.0f }; + VkDeviceQueueCreateInfo queue_info{VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO}; + float queue_priorities[1] = {1.0f}; queue_info.queueCount = 1; queue_info.pQueuePriorities = queue_priorities; bool found = false; @@ -577,7 +622,25 @@ VkResult VulkanContext::CreateDevice() { } assert(found); - deviceExtensionsLookup_.DEDICATED_ALLOCATION = EnableDeviceExtension(VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME); + extensionsLookup_.KHR_maintenance1 = EnableDeviceExtension(VK_KHR_MAINTENANCE1_EXTENSION_NAME); + extensionsLookup_.KHR_maintenance2 = EnableDeviceExtension(VK_KHR_MAINTENANCE2_EXTENSION_NAME); + extensionsLookup_.KHR_maintenance3 = EnableDeviceExtension(VK_KHR_MAINTENANCE3_EXTENSION_NAME); + extensionsLookup_.KHR_multiview = EnableDeviceExtension(VK_KHR_MULTIVIEW_EXTENSION_NAME); + + if (EnableDeviceExtension(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME)) { + extensionsLookup_.KHR_get_memory_requirements2 = true; + extensionsLookup_.KHR_dedicated_allocation = EnableDeviceExtension(VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME); + } + if (EnableDeviceExtension(VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME)) { + if (EnableDeviceExtension(VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME)) { + extensionsLookup_.EXT_external_memory_host = EnableDeviceExtension(VK_EXT_EXTERNAL_MEMORY_HOST_EXTENSION_NAME); + } + } + if (EnableDeviceExtension(VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME)) { + extensionsLookup_.KHR_create_renderpass2 = true; + extensionsLookup_.KHR_depth_stencil_resolve = EnableDeviceExtension(VK_KHR_DEPTH_STENCIL_RESOLVE_EXTENSION_NAME); + } + extensionsLookup_.EXT_shader_stencil_export = EnableDeviceExtension(VK_EXT_SHADER_STENCIL_EXPORT_EXTENSION_NAME); VkDeviceCreateInfo device_info{ VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO }; device_info.queueCreateInfoCount = 1; @@ -586,13 +649,14 @@ VkResult VulkanContext::CreateDevice() { device_info.ppEnabledLayerNames = device_info.enabledLayerCount ? device_layer_names_.data() : nullptr; device_info.enabledExtensionCount = (uint32_t)device_extensions_enabled_.size(); device_info.ppEnabledExtensionNames = device_info.enabledExtensionCount ? device_extensions_enabled_.data() : nullptr; - device_info.pEnabledFeatures = &featuresEnabled_; + device_info.pEnabledFeatures = &deviceFeatures_.enabled; + VkResult res = vkCreateDevice(physical_devices_[physical_device_], &device_info, nullptr, &device_); if (res != VK_SUCCESS) { init_error_ = "Unable to create Vulkan device"; ELOG("Unable to create Vulkan device"); } else { - VulkanLoadDeviceFunctions(device_); + VulkanLoadDeviceFunctions(device_, extensionsLookup_); } ILOG("Device created.\n"); VulkanSetAvailable(true); @@ -608,13 +672,11 @@ VkResult VulkanContext::InitDebugMsgCallback(PFN_vkDebugReportCallbackEXT dbgFun } ILOG("Registering debug report callback"); - VkDebugReportCallbackCreateInfoEXT cb = {}; - cb.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT; - cb.pNext = nullptr; + VkDebugReportCallbackCreateInfoEXT cb{VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT}; cb.flags = bits; cb.pfnCallback = dbgFunc; cb.pUserData = userdata; - VkResult res = dyn_vkCreateDebugReportCallbackEXT(instance_, &cb, nullptr, &msg_callback); + VkResult res = vkCreateDebugReportCallbackEXT(instance_, &cb, nullptr, &msg_callback); switch (res) { case VK_SUCCESS: msg_callbacks.push_back(msg_callback); @@ -628,49 +690,66 @@ VkResult VulkanContext::InitDebugMsgCallback(PFN_vkDebugReportCallbackEXT dbgFun } void VulkanContext::DestroyDebugMsgCallback() { + if (!extensionsLookup_.EXT_debug_report) + return; while (msg_callbacks.size() > 0) { - dyn_vkDestroyDebugReportCallbackEXT(instance_, msg_callbacks.back(), nullptr); + vkDestroyDebugReportCallbackEXT(instance_, msg_callbacks.back(), nullptr); msg_callbacks.pop_back(); } } -void VulkanContext::InitSurface(WindowSystem winsys, void *data1, void *data2, int width, int height) { +VkResult VulkanContext::InitDebugUtilsCallback(PFN_vkDebugUtilsMessengerCallbackEXT callback, int bits, void *userdata) { + VkDebugUtilsMessengerCreateInfoEXT callback1{VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT}; + callback1.messageSeverity = bits; + callback1.messageType = VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT; + callback1.pfnUserCallback = callback; + callback1.pUserData = userdata; + VkDebugUtilsMessengerEXT messenger; + VkResult res = vkCreateDebugUtilsMessengerEXT(instance_, &callback1, nullptr, &messenger); + if (res != VK_SUCCESS) { + ELOG("Failed to register debug callback with vkCreateDebugUtilsMessengerEXT"); + // Do error handling for VK_ERROR_OUT_OF_MEMORY + } else { + ILOG("Debug callback registered with vkCreateDebugUtilsMessengerEXT."); + utils_callbacks.push_back(messenger); + } + return res; +} + +void VulkanContext::DestroyDebugUtilsCallback() { + if (!extensionsLookup_.EXT_debug_utils) + return; + while (utils_callbacks.size() > 0) { + vkDestroyDebugUtilsMessengerEXT(instance_, utils_callbacks.back(), nullptr); + utils_callbacks.pop_back(); + } +} + + +VkResult VulkanContext::InitSurface(WindowSystem winsys, void *data1, void *data2) { winsys_ = winsys; winsysData1_ = data1; winsysData2_ = data2; - ReinitSurface(width, height); + return ReinitSurface(); } -void VulkanContext::ReinitSurface(int width, int height) { +VkResult VulkanContext::ReinitSurface() { if (surface_ != VK_NULL_HANDLE) { - ILOG("Destroying Vulkan surface (%d, %d)", width_, height_); + ILOG("Destroying Vulkan surface (%d, %d)", swapChainExtent_.width, swapChainExtent_.height); vkDestroySurfaceKHR(instance_, surface_, nullptr); surface_ = VK_NULL_HANDLE; } - ILOG("Creating Vulkan surface (%d, %d)", width, height); + ILOG("Creating Vulkan surface for window"); switch (winsys_) { #ifdef _WIN32 case WINDOWSYSTEM_WIN32: { - HINSTANCE connection = (HINSTANCE)winsysData1_; - HWND window = (HWND)winsysData2_; - - if (width < 0 || height < 0) - { - RECT rc; - GetClientRect(window, &rc); - width = rc.right - rc.left; - height = rc.bottom - rc.top; - } - VkWin32SurfaceCreateInfoKHR win32{ VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR }; win32.flags = 0; - win32.hwnd = window; - win32.hinstance = connection; - VkResult res = vkCreateWin32SurfaceKHR(instance_, &win32, nullptr, &surface_); - assert(res == VK_SUCCESS); - break; + win32.hwnd = (HWND)winsysData2_; + win32.hinstance = (HINSTANCE)winsysData1_; + return vkCreateWin32SurfaceKHR(instance_, &win32, nullptr, &surface_); } #endif #if defined(__ANDROID__) @@ -680,54 +759,44 @@ void VulkanContext::ReinitSurface(int width, int height) { VkAndroidSurfaceCreateInfoKHR android{ VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR }; android.flags = 0; android.window = wnd; - VkResult res = vkCreateAndroidSurfaceKHR(instance_, &android, nullptr, &surface_); - assert(res == VK_SUCCESS); - break; + return vkCreateAndroidSurfaceKHR(instance_, &android, nullptr, &surface_); } #endif #if defined(VK_USE_PLATFORM_XLIB_KHR) case WINDOWSYSTEM_XLIB: { - VkXlibSurfaceCreateInfoKHR xlib = { VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR }; + VkXlibSurfaceCreateInfoKHR xlib{ VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR }; xlib.flags = 0; xlib.dpy = (Display *)winsysData1_; xlib.window = (Window)winsysData2_; - VkResult res = vkCreateXlibSurfaceKHR(instance_, &xlib, nullptr, &surface_); - assert(res == VK_SUCCESS); - break; + return vkCreateXlibSurfaceKHR(instance_, &xlib, nullptr, &surface_); } #endif #if defined(VK_USE_PLATFORM_XCB_KHR) case WINDOWSYSTEM_XCB: { - VkXCBSurfaceCreateInfoKHR xcb = { VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR }; + VkXCBSurfaceCreateInfoKHR xcb{ VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR }; xcb.flags = 0; xcb.connection = (Connection *)winsysData1_; xcb.window = (Window)(uintptr_t)winsysData2_; - VkResult res = vkCreateXcbSurfaceKHR(instance_, &xcb, nullptr, &surface_); - assert(res == VK_SUCCESS); - break; + return vkCreateXcbSurfaceKHR(instance_, &xcb, nullptr, &surface_); } #endif #if defined(VK_USE_PLATFORM_WAYLAND_KHR) case WINDOWSYSTEM_WAYLAND: { - VkWaylandSurfaceCreateInfoKHR wayland = { VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR }; + VkWaylandSurfaceCreateInfoKHR wayland{ VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR }; wayland.flags = 0; wayland.display = (wl_display *)winsysData1_; wayland.surface = (wl_surface *)winsysData2_; - VkResult res = vkCreateWaylandSurfaceKHR(instance_, &wayland, nullptr, &surface_); - assert(res == VK_SUCCESS); - break; + return vkCreateWaylandSurfaceKHR(instance_, &wayland, nullptr, &surface_); } #endif default: _assert_msg_(G3D, false, "Vulkan support for chosen window system not implemented"); - break; + return VK_ERROR_INITIALIZATION_FAILED; } - width_ = width; - height_ = height; } bool VulkanContext::InitQueue() { @@ -818,6 +887,14 @@ bool VulkanContext::InitQueue() { return true; } +int clamp(int x, int a, int b) { + if (x < a) + return a; + if (x > b) + return b; + return x; +} + bool VulkanContext::InitSwapchain() { VkResult res = vkGetPhysicalDeviceSurfaceCapabilitiesKHR(physical_devices_[physical_device_], surface_, &surfCapabilities_); assert(res == VK_SUCCESS); @@ -829,19 +906,20 @@ bool VulkanContext::InitSwapchain() { res = vkGetPhysicalDeviceSurfacePresentModesKHR(physical_devices_[physical_device_], surface_, &presentModeCount, presentModes); assert(res == VK_SUCCESS); - VkExtent2D swapChainExtent; - // width and height are either both -1, or both not -1. - if (surfCapabilities_.currentExtent.width == (uint32_t)-1) { - // If the surface size is undefined, the size is set to - // the size of the images requested. - ILOG("initSwapchain: %dx%d", width_, height_); - swapChainExtent.width = width_; - swapChainExtent.height = height_; - } else { - // If the surface size is defined, the swap chain size must match - swapChainExtent = surfCapabilities_.currentExtent; + ILOG("surfCapabilities_.currentExtent: %dx%d", surfCapabilities_.currentExtent.width, surfCapabilities_.currentExtent.height); + ILOG("surfCapabilities_.minImageExtent: %dx%d", surfCapabilities_.minImageExtent.width, surfCapabilities_.minImageExtent.height); + ILOG("surfCapabilities_.maxImageExtent: %dx%d", surfCapabilities_.maxImageExtent.width, surfCapabilities_.maxImageExtent.height); + + swapChainExtent_.width = clamp(surfCapabilities_.currentExtent.width, surfCapabilities_.minImageExtent.width, surfCapabilities_.maxImageExtent.width); + swapChainExtent_.height = clamp(surfCapabilities_.currentExtent.height, surfCapabilities_.minImageExtent.height, surfCapabilities_.maxImageExtent.height); + + if (physicalDeviceProperties_[physical_device_].properties.vendorID == VULKAN_VENDOR_IMGTEC) { + // Swap chain width hack to avoid issue #11743 (PowerVR driver bug). + swapChainExtent_.width &= ~31; } + ILOG("swapChainExtent: %dx%d", swapChainExtent_.width, swapChainExtent_.height); + // TODO: Find a better way to specify the prioritized present mode while being able // to fall back in a sensible way. VkPresentModeKHR swapchainPresentMode = VK_PRESENT_MODE_MAX_ENUM_KHR; @@ -891,13 +969,13 @@ bool VulkanContext::InitSwapchain() { preTransform = surfCapabilities_.currentTransform; } - VkSwapchainCreateInfoKHR swap_chain_info = { VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR }; + VkSwapchainCreateInfoKHR swap_chain_info{ VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR }; swap_chain_info.surface = surface_; swap_chain_info.minImageCount = desiredNumberOfSwapChainImages; swap_chain_info.imageFormat = swapchainFormat_; swap_chain_info.imageColorSpace = VK_COLORSPACE_SRGB_NONLINEAR_KHR; - swap_chain_info.imageExtent.width = swapChainExtent.width; - swap_chain_info.imageExtent.height = swapChainExtent.height; + swap_chain_info.imageExtent.width = swapChainExtent_.width; + swap_chain_info.imageExtent.height = swapChainExtent_.height; swap_chain_info.preTransform = preTransform; swap_chain_info.imageArrayLayers = 1; swap_chain_info.presentMode = swapchainPresentMode; @@ -1241,3 +1319,24 @@ void VulkanDeleteList::PerformDeletes(VkDevice device) { } descSetLayouts_.clear(); } + +void VulkanContext::GetImageMemoryRequirements(VkImage image, VkMemoryRequirements *mem_reqs, bool *dedicatedAllocation) { + if (DeviceExtensions().KHR_dedicated_allocation) { + VkImageMemoryRequirementsInfo2KHR memReqInfo2{VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2_KHR}; + memReqInfo2.image = image; + + VkMemoryRequirements2KHR memReq2 = {VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2_KHR}; + VkMemoryDedicatedRequirementsKHR memDedicatedReq{VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS_KHR}; + memReq2.pNext = &memDedicatedReq; + + vkGetImageMemoryRequirements2KHR(GetDevice(), &memReqInfo2, &memReq2); + + *mem_reqs = memReq2.memoryRequirements; + *dedicatedAllocation = + (memDedicatedReq.requiresDedicatedAllocation != VK_FALSE) || + (memDedicatedReq.prefersDedicatedAllocation != VK_FALSE); + } else { + vkGetImageMemoryRequirements(GetDevice(), image, mem_reqs); + *dedicatedAllocation = false; + } +} diff --git a/Common/Vulkan/VulkanContext.h b/Common/Vulkan/VulkanContext.h index e58824cd26..01761aab6b 100644 --- a/Common/Vulkan/VulkanContext.h +++ b/Common/Vulkan/VulkanContext.h @@ -101,11 +101,6 @@ private: std::vector callbacks_; }; -// For fast extension-enabled checks. -struct VulkanDeviceExtensions { - bool DEDICATED_ALLOCATION; -}; - // Useful for debugging on ARM Mali. This eliminates transaction elimination // which can cause artifacts if you get barriers wrong (or if there are driver bugs). // Cost is reduced performance on some GPU architectures. @@ -142,8 +137,9 @@ public: VulkanDeleteList &Delete() { return globalDeleteList_; } // The parameters are whatever the chosen window system wants. - void InitSurface(WindowSystem winsys, void *data1, void *data2, int width = -1, int height = -1); - void ReinitSurface(int width = -1, int height = -1); + // The extents will be automatically determined. + VkResult InitSurface(WindowSystem winsys, void *data1, void *data2); + VkResult ReinitSurface(); bool InitQueue(); bool InitObjects(); @@ -160,15 +156,19 @@ public: VkFence CreateFence(bool presignalled); bool CreateShaderModule(const std::vector &spirv, VkShaderModule *shaderModule); - int GetBackbufferWidth() { return width_; } - int GetBackbufferHeight() { return height_; } + int GetBackbufferWidth() { return (int)swapChainExtent_.width; } + int GetBackbufferHeight() { return (int)swapChainExtent_.height; } void BeginFrame(); void EndFrame(); bool MemoryTypeFromProperties(uint32_t typeBits, VkFlags requirements_mask, uint32_t *typeIndex); - VkResult InitDebugMsgCallback(PFN_vkDebugReportCallbackEXT dbgFunc, int bits, void *userdata = nullptr); + VkResult InitDebugUtilsCallback(PFN_vkDebugUtilsMessengerCallbackEXT callback, int bits, void *userdata); + void DestroyDebugUtilsCallback(); + + // Legacy reporting + VkResult InitDebugMsgCallback(PFN_vkDebugReportCallbackEXT dbgFunc, int bits, void *userdata); void DestroyDebugMsgCallback(); VkPhysicalDevice GetPhysicalDevice(int n = 0) const { @@ -189,7 +189,15 @@ public: return graphics_queue_family_index_; } - const VkPhysicalDeviceProperties &GetPhysicalDeviceProperties(int i) const { + struct PhysicalDeviceProps { + VkPhysicalDeviceProperties properties; + VkPhysicalDevicePushDescriptorPropertiesKHR pushDescriptorProperties; + VkPhysicalDeviceExternalMemoryHostPropertiesEXT externalMemoryHostProperties; + }; + + const PhysicalDeviceProps &GetPhysicalDeviceProperties(int i = -1) const { + if (i < 0) + i = GetCurrentPhysicalDevice(); return physicalDeviceProperties_[i]; } @@ -205,8 +213,13 @@ public: const std::vector &GetDeviceExtensionsEnabled() const { return device_extensions_enabled_; } - const VkPhysicalDeviceFeatures &GetFeaturesAvailable() const { return featuresAvailable_; } - const VkPhysicalDeviceFeatures &GetFeaturesEnabled() const { return featuresEnabled_; } + + struct PhysicalDeviceFeatures { + VkPhysicalDeviceFeatures available{}; + VkPhysicalDeviceFeatures enabled{}; + }; + + const PhysicalDeviceFeatures &GetDeviceFeatures() const { return deviceFeatures_; } const VulkanPhysicalDeviceInfo &GetDeviceInfo() const { return deviceInfo_; } const VkSurfaceCapabilitiesKHR &GetSurfaceCapabilities() const { return surfCapabilities_; } @@ -247,7 +260,9 @@ public: MAX_INFLIGHT_FRAMES = 3, }; - const VulkanDeviceExtensions &DeviceExtensions() { return deviceExtensionsLookup_; } + const VulkanDeviceExtensions &DeviceExtensions() { return extensionsLookup_; } + + void GetImageMemoryRequirements(VkImage image, VkMemoryRequirements *mem_reqs, bool *dedicatedAllocation); private: // A layer can expose extensions, keep track of those extensions here. @@ -281,23 +296,23 @@ private: std::vector device_extensions_enabled_; std::vector device_extension_properties_; - VulkanDeviceExtensions deviceExtensionsLookup_{}; + VulkanDeviceExtensions extensionsLookup_{}; std::vector physical_devices_; int physical_device_ = -1; uint32_t graphics_queue_family_index_ = -1; - std::vector physicalDeviceProperties_{}; + std::vector physicalDeviceProperties_{}; std::vector queue_props; VkPhysicalDeviceMemoryProperties memory_properties{}; // Custom collection of things that are good to know VulkanPhysicalDeviceInfo deviceInfo_{}; - // Swap chain - int width_ = 0; - int height_ = 0; + // Swap chain extent + VkExtent2D swapChainExtent_{}; + int flags_ = 0; int inflightFrames_ = MAX_INFLIGHT_FRAMES; @@ -314,14 +329,14 @@ private: VulkanDeleteList globalDeleteList_; std::vector msg_callbacks; + std::vector utils_callbacks; VkSwapchainKHR swapchain_ = VK_NULL_HANDLE; VkFormat swapchainFormat_; uint32_t queue_count = 0; - VkPhysicalDeviceFeatures featuresAvailable_{}; - VkPhysicalDeviceFeatures featuresEnabled_{}; + PhysicalDeviceFeatures deviceFeatures_; VkSurfaceCapabilitiesKHR surfCapabilities_{}; diff --git a/Common/Vulkan/VulkanDebug.cpp b/Common/Vulkan/VulkanDebug.cpp index 0ee407b735..be7512b738 100644 --- a/Common/Vulkan/VulkanDebug.cpp +++ b/Common/Vulkan/VulkanDebug.cpp @@ -56,7 +56,7 @@ const char *ObjTypeToString(VkDebugReportObjectTypeEXT type) { } } -VkBool32 VKAPI_CALL Vulkan_Dbg(VkDebugReportFlagsEXT msgFlags, VkDebugReportObjectTypeEXT objType, uint64_t srcObject, size_t location, int32_t msgCode, const char* pLayerPrefix, const char* pMsg, void *pUserData) { +VkBool32 VKAPI_CALL VulkanDebugReportCallback(VkDebugReportFlagsEXT msgFlags, VkDebugReportObjectTypeEXT objType, uint64_t srcObject, size_t location, int32_t msgCode, const char* pLayerPrefix, const char* pMsg, void *pUserData) { const VulkanLogOptions *options = (const VulkanLogOptions *)pUserData; std::ostringstream message; @@ -73,8 +73,6 @@ VkBool32 VKAPI_CALL Vulkan_Dbg(VkDebugReportFlagsEXT msgFlags, VkDebugReportObje } message << "[" << pLayerPrefix << "] " << ObjTypeToString(objType) << " Code " << msgCode << " : " << pMsg << "\n"; - if (msgCode == 2) // Useless perf warning ("Vertex attribute at location X not consumed by vertex shader") - return false; if (msgCode == 64) // Another useless perf warning that will be seen less and less as we optimize - vkCmdClearAttachments() issued on command buffer object 0x00000195296C6D40 prior to any Draw Cmds. It is recommended you use RenderPass LOAD_OP_CLEAR on Attachments prior to any Draw. return false; if (msgCode == 5) @@ -105,3 +103,59 @@ VkBool32 VKAPI_CALL Vulkan_Dbg(VkDebugReportFlagsEXT msgFlags, VkDebugReportObje // keep that behavior here. return false; } + +VkBool32 VKAPI_CALL VulkanDebugUtilsCallback( + VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity, + VkDebugUtilsMessageTypeFlagsEXT messageType, + const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData, + void* pUserData) { + const VulkanLogOptions *options = (const VulkanLogOptions *)pUserData; + std::ostringstream message; + + const char *pMessage = pCallbackData->pMessage; + int messageCode = pCallbackData->messageIdNumber; + const char *pLayerPrefix = ""; + if (messageSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT) { + message << "ERROR("; + } else if (messageSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT) { + message << "WARNING("; + } else if (messageSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT) { + message << "INFO("; + } else if (messageSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT) { + message << "VERBOSE("; + } + + if (messageType & VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT) { + message << "perf"; + } else if (messageType & VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT) { + message << "general"; + } else if (messageType & VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT) { + message << "validation"; + } + message << ":" << pCallbackData->messageIdNumber << ") " << pMessage << "\n"; + +#ifdef _WIN32 + std::string msg = message.str(); + OutputDebugStringA(msg.c_str()); + if (messageSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT) { + if (options->breakOnError && IsDebuggerPresent()) { + DebugBreak(); + } + if (options->msgBoxOnError) { + MessageBoxA(NULL, pMessage, "Alert", MB_OK); + } + } else if (messageSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT) { + // Don't break on perf warnings for now, even with a debugger. We log them at least. + if (options->breakOnWarning && IsDebuggerPresent() && 0 == (messageType & VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT)) { + DebugBreak(); + } + } +#endif + + // false indicates that layer should not bail-out of an + // API call that had validation failures. This may mean that the + // app dies inside the driver due to invalid parameter(s). + // That's what would happen without validation layers, so we'll + // keep that behavior here. + return false; +} diff --git a/Common/Vulkan/VulkanDebug.h b/Common/Vulkan/VulkanDebug.h index 21a4e671bb..10cb70d8ed 100644 --- a/Common/Vulkan/VulkanDebug.h +++ b/Common/Vulkan/VulkanDebug.h @@ -25,4 +25,5 @@ struct VulkanLogOptions { bool msgBoxOnError; }; -VkBool32 VKAPI_CALL Vulkan_Dbg(VkDebugReportFlagsEXT msgFlags, VkDebugReportObjectTypeEXT objType, uint64_t srcObject, size_t location, int32_t msgCode, const char* pLayerPrefix, const char* pMsg, void *pUserData); +VkBool32 VKAPI_CALL VulkanDebugReportCallback(VkDebugReportFlagsEXT msgFlags, VkDebugReportObjectTypeEXT objType, uint64_t srcObject, size_t location, int32_t msgCode, const char* pLayerPrefix, const char* pMsg, void *pUserData); +VkBool32 VKAPI_CALL VulkanDebugUtilsCallback(VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity, VkDebugUtilsMessageTypeFlagsEXT messageType, const VkDebugUtilsMessengerCallbackDataEXT *pCallbackData, void *pUserData); diff --git a/Common/Vulkan/VulkanImage.cpp b/Common/Vulkan/VulkanImage.cpp index 4528e4b375..4c4d2fcff1 100644 --- a/Common/Vulkan/VulkanImage.cpp +++ b/Common/Vulkan/VulkanImage.cpp @@ -67,15 +67,19 @@ bool VulkanTexture::CreateDirect(VkCommandBuffer cmd, int w, int h, int numMips, VkResult res = vkCreateImage(vulkan_->GetDevice(), &image_create_info, NULL, &image_); if (res != VK_SUCCESS) { _assert_(res == VK_ERROR_OUT_OF_HOST_MEMORY || res == VK_ERROR_OUT_OF_DEVICE_MEMORY || res == VK_ERROR_TOO_MANY_OBJECTS); + ELOG("vkCreateImage failed: %s", VulkanResultToString(res)); return false; } VkMemoryRequirements mem_reqs{}; - vkGetImageMemoryRequirements(vulkan_->GetDevice(), image_, &mem_reqs); + bool dedicatedAllocation = false; + vulkan_->GetImageMemoryRequirements(image_, &mem_reqs, &dedicatedAllocation); - if (allocator_) { + if (allocator_ && !dedicatedAllocation) { offset_ = allocator_->Allocate(mem_reqs, &mem_, Tag()); if (offset_ == VulkanDeviceAllocator::ALLOCATE_FAILED) { + ELOG("Image memory allocation failed (mem_reqs.size=%d, typebits=%08x", (int)mem_reqs.size, (int)mem_reqs.memoryTypeBits); + // Destructor will take care of the image. return false; } } else { @@ -83,16 +87,21 @@ bool VulkanTexture::CreateDirect(VkCommandBuffer cmd, int w, int h, int numMips, mem_alloc.memoryTypeIndex = 0; mem_alloc.allocationSize = mem_reqs.size; + VkMemoryDedicatedAllocateInfoKHR dedicatedAllocateInfo{VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO_KHR}; + if (dedicatedAllocation) { + dedicatedAllocateInfo.image = image_; + mem_alloc.pNext = &dedicatedAllocateInfo; + } + // Find memory type - don't specify any mapping requirements bool pass = vulkan_->MemoryTypeFromProperties(mem_reqs.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, &mem_alloc.memoryTypeIndex); _assert_(pass); res = vkAllocateMemory(vulkan_->GetDevice(), &mem_alloc, NULL, &mem_); if (res != VK_SUCCESS) { + ELOG("vkAllocateMemory failed: %s", VulkanResultToString(res)); _assert_msg_(G3D, res != VK_ERROR_TOO_MANY_OBJECTS, "Too many Vulkan memory objects!"); _assert_(res == VK_ERROR_OUT_OF_HOST_MEMORY || res == VK_ERROR_OUT_OF_DEVICE_MEMORY || res == VK_ERROR_TOO_MANY_OBJECTS); - vkDestroyImage(vulkan_->GetDevice(), image_, nullptr); - image_ = VK_NULL_HANDLE; return false; } @@ -101,6 +110,7 @@ bool VulkanTexture::CreateDirect(VkCommandBuffer cmd, int w, int h, int numMips, res = vkBindImageMemory(vulkan_->GetDevice(), image_, mem_, offset_); if (res != VK_SUCCESS) { + ELOG("vkBindImageMemory failed: %s", VulkanResultToString(res)); // This leaks the image and memory. Should not really happen though... _assert_(res == VK_ERROR_OUT_OF_HOST_MEMORY || res == VK_ERROR_OUT_OF_DEVICE_MEMORY || res == VK_ERROR_TOO_MANY_OBJECTS); return false; @@ -144,6 +154,7 @@ bool VulkanTexture::CreateDirect(VkCommandBuffer cmd, int w, int h, int numMips, res = vkCreateImageView(vulkan_->GetDevice(), &view_info, NULL, &view_); if (res != VK_SUCCESS) { + ELOG("vkCreateImageView failed: %s", VulkanResultToString(res)); // This leaks the image. _assert_(res == VK_ERROR_OUT_OF_HOST_MEMORY || res == VK_ERROR_OUT_OF_DEVICE_MEMORY || res == VK_ERROR_TOO_MANY_OBJECTS); return false; diff --git a/Common/Vulkan/VulkanLoader.cpp b/Common/Vulkan/VulkanLoader.cpp index 04755dc555..aedcfd639b 100644 --- a/Common/Vulkan/VulkanLoader.cpp +++ b/Common/Vulkan/VulkanLoader.cpp @@ -193,9 +193,22 @@ PFN_vkAcquireNextImageKHR vkAcquireNextImageKHR; PFN_vkQueuePresentKHR vkQueuePresentKHR; // And the DEBUG_REPORT extension. We dynamically load this. -PFN_vkCreateDebugReportCallbackEXT dyn_vkCreateDebugReportCallbackEXT; -PFN_vkDestroyDebugReportCallbackEXT dyn_vkDestroyDebugReportCallbackEXT; +PFN_vkCreateDebugReportCallbackEXT vkCreateDebugReportCallbackEXT; +PFN_vkDestroyDebugReportCallbackEXT vkDestroyDebugReportCallbackEXT; +PFN_vkCreateDebugUtilsMessengerEXT vkCreateDebugUtilsMessengerEXT; +PFN_vkDestroyDebugUtilsMessengerEXT vkDestroyDebugUtilsMessengerEXT; +PFN_vkCmdBeginDebugUtilsLabelEXT vkCmdBeginDebugUtilsLabelEXT; +PFN_vkCmdEndDebugUtilsLabelEXT vkCmdEndDebugUtilsLabelEXT; +PFN_vkCmdInsertDebugUtilsLabelEXT vkCmdInsertDebugUtilsLabelEXT; +PFN_vkSetDebugUtilsObjectNameEXT vkSetDebugUtilsObjectNameEXT; +PFN_vkSetDebugUtilsObjectTagEXT vkSetDebugUtilsObjectTagEXT; + +PFN_vkGetMemoryHostPointerPropertiesEXT vkGetMemoryHostPointerPropertiesEXT; +PFN_vkGetBufferMemoryRequirements2KHR vkGetBufferMemoryRequirements2KHR; +PFN_vkGetImageMemoryRequirements2KHR vkGetImageMemoryRequirements2KHR; +PFN_vkGetPhysicalDeviceProperties2KHR vkGetPhysicalDeviceProperties2KHR; +PFN_vkGetPhysicalDeviceFeatures2KHR vkGetPhysicalDeviceFeatures2KHR; #ifdef _WIN32 static HINSTANCE vulkanLibrary; @@ -246,6 +259,7 @@ bool VulkanMayBeAvailable() { // Do a hyper minimal initialization and teardown to figure out if there's any chance // that any sort of Vulkan will be usable. + PFN_vkEnumerateInstanceExtensionProperties localEnumerateInstanceExtensionProperties = LOAD_GLOBAL_FUNC_LOCAL(lib, vkEnumerateInstanceExtensionProperties); PFN_vkCreateInstance localCreateInstance = LOAD_GLOBAL_FUNC_LOCAL(lib, vkCreateInstance); PFN_vkEnumeratePhysicalDevices localEnumerate = LOAD_GLOBAL_FUNC_LOCAL(lib, vkEnumeratePhysicalDevices); PFN_vkDestroyInstance localDestroyInstance = LOAD_GLOBAL_FUNC_LOCAL(lib, vkDestroyInstance); @@ -256,22 +270,60 @@ bool VulkanMayBeAvailable() { VkApplicationInfo info{ VK_STRUCTURE_TYPE_APPLICATION_INFO }; std::vector devices; bool anyGood = false; - const char *instanceExtensions[1]{}; + const char *instanceExtensions[2]{}; VkInstance instance = VK_NULL_HANDLE; VkResult res; uint32_t physicalDeviceCount = 0; - - if (!localCreateInstance || !localEnumerate || !localDestroyInstance || !localGetPhysicalDeviceProperties) - goto bail; + uint32_t instanceExtCount = 1; + bool surfaceExtensionFound = false; + bool platformSurfaceExtensionFound = false; + std::vector instanceExts; + instanceExtensions[ci.enabledExtensionCount++] = VK_KHR_SURFACE_EXTENSION_NAME; #ifdef _WIN32 - instanceExtensions[0] = VK_KHR_WIN32_SURFACE_EXTENSION_NAME; - ci.enabledExtensionCount = 1; + const char * const platformSurfaceExtension = VK_KHR_WIN32_SURFACE_EXTENSION_NAME; #elif defined(__ANDROID__) - instanceExtensions[0] = VK_KHR_ANDROID_SURFACE_EXTENSION_NAME; - ci.enabledExtensionCount = 1; + const char *platformSurfaceExtension = VK_KHR_ANDROID_SURFACE_EXTENSION_NAME; +#else + const char *platformSurfaceExtension = 0; #endif + if (!localEnumerateInstanceExtensionProperties || !localCreateInstance || !localEnumerate || !localDestroyInstance || !localGetPhysicalDeviceProperties) + goto bail; + + res = localEnumerateInstanceExtensionProperties(nullptr, &instanceExtCount, nullptr); + // Maximum paranoia. + if (res != VK_SUCCESS) { + ELOG("Enumerating VK extensions failed."); + goto bail; + } + if (instanceExtCount == 0) { + ELOG("No VK instance extensions - won't be able to present."); + goto bail; + } + instanceExts.resize(instanceExtCount); + res = localEnumerateInstanceExtensionProperties(nullptr, &instanceExtCount, instanceExts.data()); + if (res != VK_SUCCESS) { + ELOG("Enumerating VK extensions failed."); + goto bail; + } + + if (platformSurfaceExtension) { + for (auto iter : instanceExts) { + if (!strcmp(iter.extensionName, platformSurfaceExtension)) { + instanceExtensions[ci.enabledExtensionCount++] = platformSurfaceExtension; + platformSurfaceExtensionFound = true; + break; + } else if (!strcmp(iter.extensionName, VK_KHR_SURFACE_EXTENSION_NAME)) { + surfaceExtensionFound = true; + } + } + if (!platformSurfaceExtensionFound || !surfaceExtensionFound) { + ELOG("Platform surface extension not found"); + goto bail; + } + } + ci.ppEnabledExtensionNames = instanceExtensions; ci.enabledLayerCount = 0; info.apiVersion = VK_API_VERSION_1_0; @@ -372,7 +424,7 @@ bool VulkanLoad() { return true; } -void VulkanLoadInstanceFunctions(VkInstance instance) { +void VulkanLoadInstanceFunctions(VkInstance instance, const VulkanDeviceExtensions &enabledExtensions) { // OK, let's use the above functions to get the rest. LOAD_INSTANCE_FUNC(instance, vkDestroyInstance); LOAD_INSTANCE_FUNC(instance, vkEnumeratePhysicalDevices); @@ -532,8 +584,25 @@ void VulkanLoadInstanceFunctions(VkInstance instance) { LOAD_INSTANCE_FUNC(instance, vkDestroySurfaceKHR); - dyn_vkCreateDebugReportCallbackEXT = (PFN_vkCreateDebugReportCallbackEXT)vkGetInstanceProcAddr(instance, "vkCreateDebugReportCallbackEXT"); - dyn_vkDestroyDebugReportCallbackEXT = (PFN_vkDestroyDebugReportCallbackEXT)vkGetInstanceProcAddr(instance, "vkDestroyDebugReportCallbackEXT"); + if (enabledExtensions.KHR_get_physical_device_properties2) { + LOAD_INSTANCE_FUNC(instance, vkGetPhysicalDeviceProperties2KHR); + LOAD_INSTANCE_FUNC(instance, vkGetPhysicalDeviceFeatures2KHR); + } + + if (enabledExtensions.EXT_debug_report) { + LOAD_INSTANCE_FUNC(instance, vkCreateDebugReportCallbackEXT); + LOAD_INSTANCE_FUNC(instance, vkDestroyDebugReportCallbackEXT); + } + + if (enabledExtensions.EXT_debug_utils) { + LOAD_INSTANCE_FUNC(instance, vkCreateDebugUtilsMessengerEXT); + LOAD_INSTANCE_FUNC(instance, vkDestroyDebugUtilsMessengerEXT); + LOAD_INSTANCE_FUNC(instance, vkCmdBeginDebugUtilsLabelEXT); + LOAD_INSTANCE_FUNC(instance, vkCmdEndDebugUtilsLabelEXT); + LOAD_INSTANCE_FUNC(instance, vkCmdInsertDebugUtilsLabelEXT); + LOAD_INSTANCE_FUNC(instance, vkSetDebugUtilsObjectNameEXT); + LOAD_INSTANCE_FUNC(instance, vkSetDebugUtilsObjectTagEXT); + } WLOG("Vulkan instance functions loaded."); } @@ -541,7 +610,7 @@ void VulkanLoadInstanceFunctions(VkInstance instance) { // On some implementations, loading functions (that have Device as their first parameter) via vkGetDeviceProcAddr may // increase performance - but then these function pointers will only work on that specific device. Thus, this loader is not very // good for multi-device. -void VulkanLoadDeviceFunctions(VkDevice device) { +void VulkanLoadDeviceFunctions(VkDevice device, const VulkanDeviceExtensions &enabledExtensions) { WLOG("Vulkan device functions loaded."); // TODO: Move more functions VulkanLoadInstanceFunctions to here. LOAD_DEVICE_FUNC(device, vkCreateSwapchainKHR); @@ -549,6 +618,13 @@ void VulkanLoadDeviceFunctions(VkDevice device) { LOAD_DEVICE_FUNC(device, vkGetSwapchainImagesKHR); LOAD_DEVICE_FUNC(device, vkAcquireNextImageKHR); LOAD_DEVICE_FUNC(device, vkQueuePresentKHR); + if (enabledExtensions.EXT_external_memory_host) { + LOAD_DEVICE_FUNC(device, vkGetMemoryHostPointerPropertiesEXT); + } + if (enabledExtensions.KHR_dedicated_allocation) { + LOAD_DEVICE_FUNC(device, vkGetBufferMemoryRequirements2KHR); + LOAD_DEVICE_FUNC(device, vkGetImageMemoryRequirements2KHR); + } } void VulkanFree() { diff --git a/Common/Vulkan/VulkanLoader.h b/Common/Vulkan/VulkanLoader.h index 680fbe46ac..3d1ccae86b 100644 --- a/Common/Vulkan/VulkanLoader.h +++ b/Common/Vulkan/VulkanLoader.h @@ -197,15 +197,48 @@ extern PFN_vkQueuePresentKHR vkQueuePresentKHR; // And the DEBUG_REPORT extension. Since we load this dynamically even in static // linked mode, we have to rename it :( -extern PFN_vkCreateDebugReportCallbackEXT dyn_vkCreateDebugReportCallbackEXT; -extern PFN_vkDestroyDebugReportCallbackEXT dyn_vkDestroyDebugReportCallbackEXT; +extern PFN_vkCreateDebugReportCallbackEXT vkCreateDebugReportCallbackEXT; +extern PFN_vkDestroyDebugReportCallbackEXT vkDestroyDebugReportCallbackEXT; +extern PFN_vkCreateDebugUtilsMessengerEXT vkCreateDebugUtilsMessengerEXT; +extern PFN_vkDestroyDebugUtilsMessengerEXT vkDestroyDebugUtilsMessengerEXT; +extern PFN_vkCmdBeginDebugUtilsLabelEXT vkCmdBeginDebugUtilsLabelEXT; +extern PFN_vkCmdEndDebugUtilsLabelEXT vkCmdEndDebugUtilsLabelEXT; +extern PFN_vkCmdInsertDebugUtilsLabelEXT vkCmdInsertDebugUtilsLabelEXT; +extern PFN_vkSetDebugUtilsObjectNameEXT vkSetDebugUtilsObjectNameEXT; +extern PFN_vkSetDebugUtilsObjectTagEXT vkSetDebugUtilsObjectTagEXT; + +// Assorted other extensions. +extern PFN_vkGetBufferMemoryRequirements2KHR vkGetBufferMemoryRequirements2KHR; +extern PFN_vkGetImageMemoryRequirements2KHR vkGetImageMemoryRequirements2KHR; +extern PFN_vkGetMemoryHostPointerPropertiesEXT vkGetMemoryHostPointerPropertiesEXT; +extern PFN_vkGetPhysicalDeviceProperties2KHR vkGetPhysicalDeviceProperties2KHR; +extern PFN_vkGetPhysicalDeviceFeatures2KHR vkGetPhysicalDeviceFeatures2KHR; + + +// For fast extension-enabled checks. +struct VulkanDeviceExtensions { + bool EXT_debug_report; + bool EXT_debug_utils; + bool KHR_maintenance1; // required for KHR_create_renderpass2 + bool KHR_maintenance2; + bool KHR_maintenance3; + bool KHR_multiview; // required for KHR_create_renderpass2 + bool KHR_get_memory_requirements2; + bool KHR_dedicated_allocation; + bool KHR_create_renderpass2; + bool EXT_external_memory_host; + bool KHR_get_physical_device_properties2; + bool KHR_depth_stencil_resolve; + bool EXT_shader_stencil_export; + // bool EXT_depth_range_unrestricted; // Allows depth outside [0.0, 1.0] in 32-bit float depth buffers. +}; // Way to do a quick check before even attempting to load. bool VulkanMayBeAvailable(); void VulkanSetAvailable(bool available); bool VulkanLoad(); -void VulkanLoadInstanceFunctions(VkInstance instance); -void VulkanLoadDeviceFunctions(VkDevice device); +void VulkanLoadInstanceFunctions(VkInstance instance, const VulkanDeviceExtensions &enabledExtensions); +void VulkanLoadDeviceFunctions(VkDevice device, const VulkanDeviceExtensions &enabledExtensions); void VulkanFree(); diff --git a/Common/Vulkan/VulkanMemory.cpp b/Common/Vulkan/VulkanMemory.cpp index a6457af0b2..2b13be2e01 100644 --- a/Common/Vulkan/VulkanMemory.cpp +++ b/Common/Vulkan/VulkanMemory.cpp @@ -191,14 +191,8 @@ size_t VulkanDeviceAllocator::Allocate(const VkMemoryRequirements &reqs, VkDevic assert(!destroyed_); uint32_t memoryTypeIndex; bool pass = vulkan_->MemoryTypeFromProperties(reqs.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, &memoryTypeIndex); - assert(pass); if (!pass) { - return ALLOCATE_FAILED; - } - if (memoryTypeIndex_ == UNDEFINED_MEMORY_TYPE) { - memoryTypeIndex_ = memoryTypeIndex; - } else if (memoryTypeIndex_ != memoryTypeIndex) { - assert(memoryTypeIndex_ == memoryTypeIndex); + ELOG("Failed to pick an appropriate memory type (req: %08x)", reqs.memoryTypeBits); return ALLOCATE_FAILED; } @@ -213,6 +207,8 @@ size_t VulkanDeviceAllocator::Allocate(const VkMemoryRequirements &reqs, VkDevic // This helps us "creep forward", and also spend less time allocating. const size_t actualSlab = (lastSlab_ + i) % numSlabs; Slab &slab = slabs_[actualSlab]; + if (slab.memoryTypeIndex != memoryTypeIndex) + continue; size_t start = slab.nextFree; while (start < slab.usage.size()) { @@ -227,7 +223,7 @@ size_t VulkanDeviceAllocator::Allocate(const VkMemoryRequirements &reqs, VkDevic } // Okay, we couldn't fit it into any existing slabs. We need a new one. - if (!AllocateSlab(size)) { + if (!AllocateSlab(size, memoryTypeIndex)) { return ALLOCATE_FAILED; } @@ -401,16 +397,17 @@ void VulkanDeviceAllocator::ExecuteFree(FreeInfo *userdata) { delete userdata; } -bool VulkanDeviceAllocator::AllocateSlab(VkDeviceSize minBytes) { +bool VulkanDeviceAllocator::AllocateSlab(VkDeviceSize minBytes, int memoryTypeIndex) { assert(!destroyed_); if (!slabs_.empty() && minSlabSize_ < maxSlabSize_) { // We're allocating an additional slab, so rachet up its size. + // TODO: Maybe should not do this when we are allocating a new slab due to memoryTypeIndex not matching? minSlabSize_ <<= 1; } VkMemoryAllocateInfo alloc{ VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO }; alloc.allocationSize = minSlabSize_; - alloc.memoryTypeIndex = memoryTypeIndex_; + alloc.memoryTypeIndex = memoryTypeIndex; while (alloc.allocationSize < minBytes) { alloc.allocationSize <<= 1; @@ -427,6 +424,7 @@ bool VulkanDeviceAllocator::AllocateSlab(VkDeviceSize minBytes) { slabs_.resize(slabs_.size() + 1); Slab &slab = slabs_[slabs_.size() - 1]; + slab.memoryTypeIndex = memoryTypeIndex; slab.deviceMemory = deviceMemory; slab.usage.resize((size_t)(alloc.allocationSize >> SLAB_GRAIN_SHIFT)); diff --git a/Common/Vulkan/VulkanMemory.h b/Common/Vulkan/VulkanMemory.h index 05d892cd1b..ef14de80ed 100644 --- a/Common/Vulkan/VulkanMemory.h +++ b/Common/Vulkan/VulkanMemory.h @@ -174,6 +174,7 @@ private: struct Slab { VkDeviceMemory deviceMemory; + uint32_t memoryTypeIndex = UNDEFINED_MEMORY_TYPE; std::vector usage; std::unordered_map allocSizes; std::unordered_map tags; @@ -200,7 +201,7 @@ private: freeInfo->allocator->ExecuteFree(freeInfo); // this deletes freeInfo } - bool AllocateSlab(VkDeviceSize minBytes); + bool AllocateSlab(VkDeviceSize minBytes, int memoryTypeIndex); bool AllocateFromSlab(Slab &slab, size_t &start, size_t blocks, const std::string &tag); void Decimate(); void DoTouch(VkDeviceMemory deviceMemory, size_t offset); @@ -212,6 +213,5 @@ private: size_t lastSlab_ = 0; size_t minSlabSize_; const size_t maxSlabSize_; - uint32_t memoryTypeIndex_ = UNDEFINED_MEMORY_TYPE; bool destroyed_ = false; }; diff --git a/Core/Compatibility.cpp b/Core/Compatibility.cpp index 1183f32ed1..f9de4e41c5 100644 --- a/Core/Compatibility.cpp +++ b/Core/Compatibility.cpp @@ -69,6 +69,10 @@ void Compatibility::CheckSettings(IniFile &iniFile, const std::string &gameID) { CheckSetting(iniFile, gameID, "MGS2AcidHack", &flags_.MGS2AcidHack); CheckSetting(iniFile, gameID, "SonicRivalsHack", &flags_.SonicRivalsHack); CheckSetting(iniFile, gameID, "AdhocHackDisableNBSwitch", &flags_.AdhocHackDisableNBSwitch); + CheckSetting(iniFile, gameID, "BlockTransferAllowCreateFB", &flags_.BlockTransferAllowCreateFB); + CheckSetting(iniFile, gameID, "YugiohSaveFix", &flags_.YugiohSaveFix); + CheckSetting(iniFile, gameID, "ForceUMDDelay", &flags_.ForceUMDDelay); + CheckSetting(iniFile, gameID, "ForceMax60FPS", &flags_.ForceMax60FPS); } void Compatibility::CheckSetting(IniFile &iniFile, const std::string &gameID, const char *option, bool *flag) { diff --git a/Core/Compatibility.h b/Core/Compatibility.h index e023ba380e..65c89b637d 100644 --- a/Core/Compatibility.h +++ b/Core/Compatibility.h @@ -69,6 +69,10 @@ struct CompatFlags { bool MGS2AcidHack; bool SonicRivalsHack; bool AdhocHackDisableNBSwitch; + bool BlockTransferAllowCreateFB; + bool YugiohSaveFix; + bool ForceUMDDelay; + bool ForceMax60FPS; }; class IniFile; diff --git a/Core/Config.cpp b/Core/Config.cpp index 734dafc3a7..00ad1b7ccc 100644 --- a/Core/Config.cpp +++ b/Core/Config.cpp @@ -474,6 +474,7 @@ static ConfigSetting cpuSettings[] = { ConfigSetting("HideSlowWarnings", &g_Config.bHideSlowWarnings, true, true, false), ConfigSetting("HideStateWarnings", &g_Config.bHideStateWarnings, false, true, false), ConfigSetting("PreloadFunctions", &g_Config.bPreloadFunctions, false, true, true), + ConfigSetting("JitDisableFlags", &g_Config.uJitDisableFlags, (uint32_t)0, true, true), ReportedConfigSetting("CPUSpeed", &g_Config.iLockedCPUSpeed, 0, true, true), ConfigSetting(false), @@ -543,12 +544,6 @@ static int DefaultAndroidHwScale() { } static int DefaultGPUBackend() { -#if PPSSPP_PLATFORM(WINDOWS) || PPSSPP_PLATFORM(ANDROID) - // Where supported, let's use Vulkan. - if (VulkanMayBeAvailable()) { - return (int)GPUBackend::VULKAN; - } -#endif #if PPSSPP_PLATFORM(WINDOWS) // If no Vulkan, use Direct3D 11 on Windows 8+ (most importantly 10.) if (DoesVersionMatchWindows(6, 2, 0, 0, true)) { @@ -617,6 +612,7 @@ static ConfigSetting graphicsSettings[] = { #ifdef _WIN32 ConfigSetting("D3D11Device", &g_Config.sD3D11Device, "", true, false), #endif + ConfigSetting("VendorBugChecksEnabled", &g_Config.bVendorBugChecksEnabled, true, false, false), ReportedConfigSetting("RenderingMode", &g_Config.iRenderingMode, &DefaultRenderingMode, true, true), ConfigSetting("SoftwareRenderer", &g_Config.bSoftwareRendering, false, true, true), ReportedConfigSetting("HardwareTransform", &g_Config.bHardwareTransform, true, true, true), @@ -628,6 +624,7 @@ static ConfigSetting graphicsSettings[] = { ReportedConfigSetting("AndroidHwScale", &g_Config.iAndroidHwScale, &DefaultAndroidHwScale), ReportedConfigSetting("HighQualityDepth", &g_Config.bHighQualityDepth, true, true, true), ReportedConfigSetting("FrameSkip", &g_Config.iFrameSkip, 0, true, true), + ReportedConfigSetting("FrameSkipType", &g_Config.iFrameSkipType, 0, true, true), ReportedConfigSetting("AutoFrameSkip", &g_Config.bAutoFrameSkip, false, true, true), ConfigSetting("FrameRate", &g_Config.iFpsLimit1, 0, true, true), ConfigSetting("FrameRate2", &g_Config.iFpsLimit2, -1, true, true), @@ -635,7 +632,6 @@ static ConfigSetting graphicsSettings[] = { #if defined(USING_WIN_UI) ConfigSetting("RestartRequired", &g_Config.bRestartRequired, false, false), #endif - ReportedConfigSetting("ForceMaxEmulatedFPS", &g_Config.iForceMaxEmulatedFPS, 60, true, true), ConfigSetting("RefreshAt60Hz", &g_Config.bRefreshAt60Hz, false, true, true), // Most low-performance (and many high performance) mobile GPUs do not support aniso anyway so defaulting to 4 is fine. @@ -659,7 +655,6 @@ static ConfigSetting graphicsSettings[] = { ConfigSetting("SustainedPerformanceMode", &g_Config.bSustainedPerformanceMode, false, true, true), ConfigSetting("MipMap", &g_Config.bMipMap, true, true, true), - ReportedConfigSetting("TrueColor", &g_Config.bTrueColor, true, true, true), ReportedConfigSetting("ReplaceTextures", &g_Config.bReplaceTextures, true, true, true), ReportedConfigSetting("SaveNewTextures", &g_Config.bSaveNewTextures, false, true, true), ReportedConfigSetting("IgnoreTextureFilenames", &g_Config.bIgnoreTextureFilenames, true, true, false), @@ -669,11 +664,9 @@ static ConfigSetting graphicsSettings[] = { ReportedConfigSetting("TexDeposterize", &g_Config.bTexDeposterize, false, true, true), ReportedConfigSetting("TexRealtime", &g_Config.bRealtimeTexScaling, false, true, true), ConfigSetting("VSyncInterval", &g_Config.bVSync, true, true, true), - ReportedConfigSetting("DisableStencilTest", &g_Config.bDisableStencilTest, false, true, true), ReportedConfigSetting("BloomHack", &g_Config.iBloomHack, 2, true, true), // Not really a graphics setting... - ReportedConfigSetting("TimerHack", &g_Config.bTimerHack, &DefaultTimerHack, true, true), ReportedConfigSetting("SplineBezierQuality", &g_Config.iSplineBezierQuality, 2, true, true), ReportedConfigSetting("HardwareTessellation", &g_Config.bHardwareTessellation, false, true, true), ReportedConfigSetting("PostShader", &g_Config.sPostShaderName, "Off", true, true), diff --git a/Core/Config.h b/Core/Config.h index 6a61e2bafb..8985f573af 100644 --- a/Core/Config.h +++ b/Core/Config.h @@ -98,6 +98,7 @@ public: bool bHideSlowWarnings; bool bHideStateWarnings; bool bPreloadFunctions; + uint32_t uJitDisableFlags; bool bVulkanMultithreading; bool bSeparateSASThread; @@ -139,6 +140,7 @@ public: bool bHardwareTransform; // only used in the GLES backend bool bSoftwareSkinning; // may speed up some games bool bShaderDepal; + bool bVendorBugChecksEnabled; int iRenderingMode; // 0 = non-buffered rendering 1 = buffered rendering int iTexFiltering; // 1 = off , 2 = nearest , 3 = linear , 4 = linear(CG) @@ -151,6 +153,7 @@ public: bool bSustainedPerformanceMode; // Android: Slows clocks down to avoid overheating/speed fluctuations. bool bVSync; int iFrameSkip; + int iFrameSkipType; bool bAutoFrameSkip; bool bFrameSkipUnthrottle; @@ -194,9 +197,7 @@ public: bool bEnableCheats; bool bReloadCheats; int iCwCheatRefreshRate; - bool bDisableStencilTest; int iBloomHack; //0 = off, 1 = safe, 2 = balanced, 3 = aggressive - bool bTimerHack; bool bBlockTransferGPU; bool bDisableSlowFramebufEffects; bool bFragmentTestCache; diff --git a/Core/Core.vcxproj b/Core/Core.vcxproj index c5a39b54be..34d117cf66 100644 --- a/Core/Core.vcxproj +++ b/Core/Core.vcxproj @@ -79,6 +79,7 @@ false MultiThreadedDebug Common/DbgNew.h + ProgramDatabase true @@ -101,6 +102,7 @@ false MultiThreadedDebug Common/DbgNew.h + ProgramDatabase true diff --git a/Core/CoreTiming.cpp b/Core/CoreTiming.cpp index f8b355e417..0e80ddc3a7 100644 --- a/Core/CoreTiming.cpp +++ b/Core/CoreTiming.cpp @@ -120,15 +120,8 @@ u64 GetGlobalTimeUsScaled() { s64 ticksSinceLast = GetTicks() - lastGlobalTimeTicks; int freq = GetClockFrequencyMHz(); - if (g_Config.bTimerHack) { - float vps; - __DisplayGetVPS(&vps); - if (vps > 4.0f) - freq *= (vps / (g_Config.bRefreshAt60Hz ? 60.0f : 59.94f)); - } s64 usSinceLast = ticksSinceLast / freq; return lastGlobalTimeUs + usSinceLast; - } u64 GetGlobalTimeUs() diff --git a/Core/Debugger/WebSocket/WebSocketUtils.h b/Core/Debugger/WebSocket/WebSocketUtils.h index 85dca3f4a8..ac75838583 100644 --- a/Core/Debugger/WebSocket/WebSocketUtils.h +++ b/Core/Debugger/WebSocket/WebSocketUtils.h @@ -24,6 +24,13 @@ #include "net/websocket_server.h" #include "Common/Log.h" +#include "ppsspp_config.h" + +#if PPSSPP_PLATFORM(UWP) +// Enum name overlapped with UWP macro, quick hack to disable it +#undef OPTIONAL +#endif + using namespace json; static inline void DebuggerJsonAddTicket(JsonWriter &writer, const JsonGet &data) { diff --git a/Core/FileLoaders/CachingFileLoader.cpp b/Core/FileLoaders/CachingFileLoader.cpp index 597fafadcc..61a7459045 100644 --- a/Core/FileLoaders/CachingFileLoader.cpp +++ b/Core/FileLoaders/CachingFileLoader.cpp @@ -25,12 +25,12 @@ // Takes ownership of backend. CachingFileLoader::CachingFileLoader(FileLoader *backend) - : backend_(backend) { + : ProxiedFileLoader(backend) { } void CachingFileLoader::Prepare() { std::call_once(preparedFlag_, [this](){ - filesize_ = backend_->FileSize(); + filesize_ = ProxiedFileLoader::FileSize(); if (filesize_ > 0) { InitCache(); } @@ -41,27 +41,25 @@ CachingFileLoader::~CachingFileLoader() { if (filesize_ > 0) { ShutdownCache(); } - // Takes ownership. - delete backend_; } bool CachingFileLoader::Exists() { if (exists_ == -1) { - exists_ = backend_->Exists() ? 1 : 0; + exists_ = ProxiedFileLoader::Exists() ? 1 : 0; } return exists_ == 1; } bool CachingFileLoader::ExistsFast() { if (exists_ == -1) { - return backend_->ExistsFast(); + return ProxiedFileLoader::ExistsFast(); } return exists_ == 1; } bool CachingFileLoader::IsDirectory() { if (isDirectory_ == -1) { - isDirectory_ = backend_->IsDirectory() ? 1 : 0; + isDirectory_ = ProxiedFileLoader::IsDirectory() ? 1 : 0; } return isDirectory_ == 1; } @@ -71,10 +69,6 @@ s64 CachingFileLoader::FileSize() { return filesize_; } -std::string CachingFileLoader::Path() const { - return backend_->Path(); -} - size_t CachingFileLoader::ReadAt(s64 absolutePos, size_t bytes, void *data, Flags flags) { Prepare(); if (absolutePos >= filesize_) { @@ -288,11 +282,3 @@ void CachingFileLoader::StartReadAhead(s64 pos) { }); th.detach(); } - -bool CachingFileLoader::IsRemote() { - return backend_->IsRemote(); -} - -void CachingFileLoader::Cancel() { - backend_->Cancel(); -} diff --git a/Core/FileLoaders/CachingFileLoader.h b/Core/FileLoaders/CachingFileLoader.h index 03d3aa726e..97fe0aa682 100644 --- a/Core/FileLoaders/CachingFileLoader.h +++ b/Core/FileLoaders/CachingFileLoader.h @@ -23,25 +23,21 @@ #include "Common/CommonTypes.h" #include "Core/Loaders.h" -class CachingFileLoader : public FileLoader { +class CachingFileLoader : public ProxiedFileLoader { public: CachingFileLoader(FileLoader *backend); ~CachingFileLoader() override; - bool IsRemote() override; bool Exists() override; bool ExistsFast() override; bool IsDirectory() override; s64 FileSize() override; - std::string Path() const override; size_t ReadAt(s64 absolutePos, size_t bytes, size_t count, void *data, Flags flags = Flags::NONE) override { return ReadAt(absolutePos, bytes * count, data, flags) / bytes; } size_t ReadAt(s64 absolutePos, size_t bytes, void *data, Flags flags = Flags::NONE) override; - void Cancel() override; - private: void Prepare(); void InitCache(); @@ -61,7 +57,6 @@ private: }; s64 filesize_ = 0; - FileLoader *backend_; int exists_ = -1; int isDirectory_ = -1; u64 generation_; diff --git a/Core/FileLoaders/DiskCachingFileLoader.cpp b/Core/FileLoaders/DiskCachingFileLoader.cpp index b098df4866..bb48ad3dbf 100644 --- a/Core/FileLoaders/DiskCachingFileLoader.cpp +++ b/Core/FileLoaders/DiskCachingFileLoader.cpp @@ -41,12 +41,12 @@ std::mutex DiskCachingFileLoader::cachesMutex_; // Takes ownership of backend. DiskCachingFileLoader::DiskCachingFileLoader(FileLoader *backend) - : backend_(backend) { + : ProxiedFileLoader(backend) { } void DiskCachingFileLoader::Prepare() { std::call_once(preparedFlag_, [this]() { - filesize_ = backend_->FileSize(); + filesize_ = ProxiedFileLoader::FileSize(); if (filesize_ > 0) { InitCache(); } @@ -57,13 +57,11 @@ DiskCachingFileLoader::~DiskCachingFileLoader() { if (filesize_ > 0) { ShutdownCache(); } - // Takes ownership. - delete backend_; } bool DiskCachingFileLoader::Exists() { Prepare(); - return backend_->Exists(); + return ProxiedFileLoader::Exists(); } bool DiskCachingFileLoader::ExistsFast() { @@ -72,19 +70,11 @@ bool DiskCachingFileLoader::ExistsFast() { return true; } -bool DiskCachingFileLoader::IsDirectory() { - return backend_->IsDirectory(); -} - s64 DiskCachingFileLoader::FileSize() { Prepare(); return filesize_; } -std::string DiskCachingFileLoader::Path() const { - return backend_->Path(); -} - size_t DiskCachingFileLoader::ReadAt(s64 absolutePos, size_t bytes, void *data, Flags flags) { Prepare(); size_t readSize; @@ -115,14 +105,6 @@ size_t DiskCachingFileLoader::ReadAt(s64 absolutePos, size_t bytes, void *data, return readSize; } -bool DiskCachingFileLoader::IsRemote() { - return backend_->IsRemote(); -} - -void DiskCachingFileLoader::Cancel() { - backend_->Cancel(); -} - std::vector DiskCachingFileLoader::GetCachedPathsInUse() { std::lock_guard guard(cachesMutex_); @@ -139,7 +121,7 @@ std::vector DiskCachingFileLoader::GetCachedPathsInUse() { void DiskCachingFileLoader::InitCache() { std::lock_guard guard(cachesMutex_); - std::string path = backend_->Path(); + std::string path = ProxiedFileLoader::Path(); auto &entry = caches_[path]; if (!entry) { entry = new DiskCachingFileLoaderCache(path, filesize_); @@ -155,7 +137,7 @@ void DiskCachingFileLoader::ShutdownCache() { if (cache_->Release()) { // If it ran out of counts, delete it. delete cache_; - caches_.erase(backend_->Path()); + caches_.erase(ProxiedFileLoader::Path()); } cache_ = nullptr; } diff --git a/Core/FileLoaders/DiskCachingFileLoader.h b/Core/FileLoaders/DiskCachingFileLoader.h index e396ff5736..622ffb0f07 100644 --- a/Core/FileLoaders/DiskCachingFileLoader.h +++ b/Core/FileLoaders/DiskCachingFileLoader.h @@ -27,25 +27,20 @@ class DiskCachingFileLoaderCache; -class DiskCachingFileLoader : public FileLoader { +class DiskCachingFileLoader : public ProxiedFileLoader { public: DiskCachingFileLoader(FileLoader *backend); ~DiskCachingFileLoader() override; - bool IsRemote() override; bool Exists() override; bool ExistsFast() override; - bool IsDirectory() override; s64 FileSize() override; - std::string Path() const override; size_t ReadAt(s64 absolutePos, size_t bytes, size_t count, void *data, Flags flags = Flags::NONE) override { return ReadAt(absolutePos, bytes * count, data, flags) / bytes; } size_t ReadAt(s64 absolutePos, size_t bytes, void *data, Flags flags = Flags::NONE) override; - void Cancel() override; - static std::vector GetCachedPathsInUse(); private: @@ -55,7 +50,6 @@ private: std::once_flag preparedFlag_; s64 filesize_ = 0; - FileLoader *backend_; DiskCachingFileLoaderCache *cache_ = nullptr; // We don't support concurrent disk cache access (we use memory cached indexes.) diff --git a/Core/FileLoaders/HTTPFileLoader.cpp b/Core/FileLoaders/HTTPFileLoader.cpp index 4dda285844..9c14f5b9fb 100644 --- a/Core/FileLoaders/HTTPFileLoader.cpp +++ b/Core/FileLoaders/HTTPFileLoader.cpp @@ -28,17 +28,23 @@ HTTPFileLoader::HTTPFileLoader(const std::string &filename) void HTTPFileLoader::Prepare() { std::call_once(preparedFlag_, [this](){ if (!client_.Resolve(url_.Host().c_str(), url_.Port())) { - // TODO: Should probably set some flag? + ERROR_LOG(LOADER, "HTTP request failed, unable to resolve: %s port %d", url_.Host().c_str(), url_.Port()); + latestError_ = "Could not connect (name not resolved)"; return; } + client_.SetDataTimeout(20.0); Connect(); if (!connected_) { + ERROR_LOG(LOADER, "HTTP request failed, failed to connect: %s port %d", url_.Host().c_str(), url_.Port()); + latestError_ = "Could not connect (refused to connect)"; return; } int err = client_.SendRequest("HEAD", url_.Resource().c_str()); if (err < 0) { + ERROR_LOG(LOADER, "HTTP request failed, failed to send request: %s port %d", url_.Host().c_str(), url_.Port()); + latestError_ = "Could not connect (could not request data)"; Disconnect(); return; } @@ -49,6 +55,7 @@ void HTTPFileLoader::Prepare() { if (code != 200) { // Leave size at 0, invalid. ERROR_LOG(LOADER, "HTTP request failed, got %03d for %s", code, filename_.c_str()); + latestError_ = "Could not connect (invalid response)"; Disconnect(); return; } @@ -138,6 +145,7 @@ size_t HTTPFileLoader::ReadAt(s64 absolutePos, size_t bytes, void *data, Flags f int err = client_.SendRequest("GET", url_.Resource().c_str(), requestHeaders, nullptr); if (err < 0) { + latestError_ = "Invalid response reading data"; Disconnect(); return 0; } @@ -147,6 +155,7 @@ size_t HTTPFileLoader::ReadAt(s64 absolutePos, size_t bytes, void *data, Flags f int code = client_.ReadResponseHeaders(&readbuf, responseHeaders); if (code != 206) { ERROR_LOG(LOADER, "HTTP server did not respond with range, received code=%03d", code); + latestError_ = "Invalid response reading data"; Disconnect(); return 0; } @@ -185,6 +194,7 @@ size_t HTTPFileLoader::ReadAt(s64 absolutePos, size_t bytes, void *data, Flags f if (!supportedResponse) { ERROR_LOG(LOADER, "HTTP server did not respond with the range we wanted."); + latestError_ = "Invalid response reading data"; return 0; } diff --git a/Core/FileLoaders/HTTPFileLoader.h b/Core/FileLoaders/HTTPFileLoader.h index ab4773604f..d853153177 100644 --- a/Core/FileLoaders/HTTPFileLoader.h +++ b/Core/FileLoaders/HTTPFileLoader.h @@ -48,6 +48,10 @@ public: cancelConnect_ = true; } + std::string LatestError() const override { + return latestError_; + } + private: void Prepare(); @@ -67,6 +71,7 @@ private: std::string filename_; bool connected_ = false; bool cancelConnect_ = false; + const char *latestError_ = ""; std::once_flag preparedFlag_; std::mutex readAtMutex_; diff --git a/Core/FileLoaders/RamCachingFileLoader.cpp b/Core/FileLoaders/RamCachingFileLoader.cpp index ccaa3c7bef..4b934cebdf 100644 --- a/Core/FileLoaders/RamCachingFileLoader.cpp +++ b/Core/FileLoaders/RamCachingFileLoader.cpp @@ -28,7 +28,7 @@ // Takes ownership of backend. RamCachingFileLoader::RamCachingFileLoader(FileLoader *backend) - : backend_(backend) { + : ProxiedFileLoader(backend) { filesize_ = backend->FileSize(); if (filesize_ > 0) { InitCache(); @@ -39,27 +39,25 @@ RamCachingFileLoader::~RamCachingFileLoader() { if (filesize_ > 0) { ShutdownCache(); } - // Takes ownership. - delete backend_; } bool RamCachingFileLoader::Exists() { if (exists_ == -1) { - exists_ = backend_->Exists() ? 1 : 0; + exists_ = ProxiedFileLoader::Exists() ? 1 : 0; } return exists_ == 1; } bool RamCachingFileLoader::ExistsFast() { if (exists_ == -1) { - return backend_->ExistsFast(); + return ProxiedFileLoader::ExistsFast(); } return exists_ == 1; } bool RamCachingFileLoader::IsDirectory() { if (isDirectory_ == -1) { - isDirectory_ = backend_->IsDirectory() ? 1 : 0; + isDirectory_ = ProxiedFileLoader::IsDirectory() ? 1 : 0; } return isDirectory_ == 1; } @@ -68,10 +66,6 @@ s64 RamCachingFileLoader::FileSize() { return filesize_; } -std::string RamCachingFileLoader::Path() const { - return backend_->Path(); -} - size_t RamCachingFileLoader::ReadAt(s64 absolutePos, size_t bytes, void *data, Flags flags) { size_t readSize = 0; if (cache_ == nullptr || (flags & Flags::HINT_UNCACHED) != 0) { @@ -129,7 +123,7 @@ void RamCachingFileLoader::Cancel() { aheadCancel_ = true; } - backend_->Cancel(); + ProxiedFileLoader::Cancel(); } size_t RamCachingFileLoader::ReadFromCache(s64 pos, size_t bytes, void *data) { @@ -270,7 +264,3 @@ u32 RamCachingFileLoader::NextAheadBlock() { return 0xFFFFFFFF; } - -bool RamCachingFileLoader::IsRemote() { - return backend_->IsRemote(); -} diff --git a/Core/FileLoaders/RamCachingFileLoader.h b/Core/FileLoaders/RamCachingFileLoader.h index 624305155a..60ca2afc91 100644 --- a/Core/FileLoaders/RamCachingFileLoader.h +++ b/Core/FileLoaders/RamCachingFileLoader.h @@ -23,17 +23,15 @@ #include "Common/CommonTypes.h" #include "Core/Loaders.h" -class RamCachingFileLoader : public FileLoader { +class RamCachingFileLoader : public ProxiedFileLoader { public: RamCachingFileLoader(FileLoader *backend); ~RamCachingFileLoader() override; - bool IsRemote() override; bool Exists() override; bool ExistsFast() override; bool IsDirectory() override; s64 FileSize() override; - std::string Path() const override; size_t ReadAt(s64 absolutePos, size_t bytes, size_t count, void *data, Flags flags = Flags::NONE) override { return ReadAt(absolutePos, bytes * count, data, flags) / bytes; @@ -59,7 +57,6 @@ private: }; s64 filesize_ = 0; - FileLoader *backend_; u8 *cache_ = nullptr; int exists_ = -1; int isDirectory_ = -1; diff --git a/Core/FileLoaders/RetryingFileLoader.cpp b/Core/FileLoaders/RetryingFileLoader.cpp index 4ce1da0261..b986d76bc9 100644 --- a/Core/FileLoaders/RetryingFileLoader.cpp +++ b/Core/FileLoaders/RetryingFileLoader.cpp @@ -19,47 +19,38 @@ // Takes ownership of backend. RetryingFileLoader::RetryingFileLoader(FileLoader *backend) - : backend_(backend) { -} - -RetryingFileLoader::~RetryingFileLoader() { - // Takes ownership. - delete backend_; + : ProxiedFileLoader(backend) { } bool RetryingFileLoader::Exists() { - if (!backend_->Exists()) { + if (!ProxiedFileLoader::Exists()) { // Retry once, immediately. - return backend_->Exists(); + return ProxiedFileLoader::Exists(); } return true; } bool RetryingFileLoader::ExistsFast() { - if (!backend_->ExistsFast()) { + if (!ProxiedFileLoader::ExistsFast()) { // Retry once, immediately. - return backend_->ExistsFast(); + return ProxiedFileLoader::ExistsFast(); } return true; } bool RetryingFileLoader::IsDirectory() { // Can't tell if it's an error either way. - return backend_->IsDirectory(); + return ProxiedFileLoader::IsDirectory(); } s64 RetryingFileLoader::FileSize() { - s64 filesize = backend_->FileSize(); + s64 filesize = ProxiedFileLoader::FileSize(); if (filesize == 0) { - return backend_->FileSize(); + return ProxiedFileLoader::FileSize(); } return filesize; } -std::string RetryingFileLoader::Path() const { - return backend_->Path(); -} - size_t RetryingFileLoader::ReadAt(s64 absolutePos, size_t bytes, void *data, Flags flags) { size_t readSize = backend_->ReadAt(absolutePos, bytes, data, flags); @@ -72,11 +63,3 @@ size_t RetryingFileLoader::ReadAt(s64 absolutePos, size_t bytes, void *data, Fla return readSize; } - -bool RetryingFileLoader::IsRemote() { - return backend_->IsRemote(); -} - -void RetryingFileLoader::Cancel() { - backend_->Cancel(); -} diff --git a/Core/FileLoaders/RetryingFileLoader.h b/Core/FileLoaders/RetryingFileLoader.h index 5c8cb59292..c13edba926 100644 --- a/Core/FileLoaders/RetryingFileLoader.h +++ b/Core/FileLoaders/RetryingFileLoader.h @@ -20,29 +20,22 @@ #include "Common/CommonTypes.h" #include "Core/Loaders.h" -class RetryingFileLoader : public FileLoader { +class RetryingFileLoader : public ProxiedFileLoader { public: RetryingFileLoader(FileLoader *backend); - ~RetryingFileLoader() override; - bool IsRemote() override; bool Exists() override; bool ExistsFast() override; bool IsDirectory() override; s64 FileSize() override; - std::string Path() const override; size_t ReadAt(s64 absolutePos, size_t bytes, size_t count, void *data, Flags flags = Flags::NONE) override { return ReadAt(absolutePos, bytes * count, data, flags) / bytes; } size_t ReadAt(s64 absolutePos, size_t bytes, void *data, Flags flags = Flags::NONE) override; - void Cancel() override; - private: enum { MAX_RETRIES = 3, }; - - FileLoader *backend_; }; diff --git a/Core/FileSystems/DirectoryFileSystem.cpp b/Core/FileSystems/DirectoryFileSystem.cpp index 27a15f352e..40810d1fae 100644 --- a/Core/FileSystems/DirectoryFileSystem.cpp +++ b/Core/FileSystems/DirectoryFileSystem.cpp @@ -66,9 +66,6 @@ static bool FixFilenameCase(const std::string &path, std::string &filename) } //TODO: lookup filename in cache for "path" - - struct dirent_large { struct dirent entry; char padding[FILENAME_MAX+1]; } diren; - struct dirent_large; struct dirent *result = NULL; DIR *dirp = opendir(path.c_str()); @@ -77,7 +74,7 @@ static bool FixFilenameCase(const std::string &path, std::string &filename) bool retValue = false; - while (!readdir_r(dirp, (dirent*) &diren, &result) && result) + while ((result = readdir(dirp))) { if (strlen(result->d_name) != filenameSize) continue; @@ -281,8 +278,10 @@ bool DirectoryFileHandle::Open(std::string &basePath, std::string &fileName, Fil #if HOST_IS_CASE_SENSITIVE if (!success && !(access & FILEACCESS_CREATE)) { - if (!FixPathCase(basePath,fileName, FPC_PATH_MUST_EXIST) ) - return 0; // or go on and attempt (for a better error code than just 0?) + if (!FixPathCase(basePath, fileName, FPC_PATH_MUST_EXIST)) { + error = SCE_KERNEL_ERROR_ERRNO_FILE_NOT_FOUND; + return false; + } fullName = GetLocalPath(basePath,fileName); const char *fullNameC = fullName.c_str(); diff --git a/Core/HLE/ReplaceTables.cpp b/Core/HLE/ReplaceTables.cpp index dec3f24636..e64adef5fa 100644 --- a/Core/HLE/ReplaceTables.cpp +++ b/Core/HLE/ReplaceTables.cpp @@ -661,7 +661,7 @@ static int Hook_hexyzforce_monoclome_thread() { static int Hook_starocean_write_stencil() { const u32 fb_address = currentMIPS->r[MIPS_REG_T7]; - if (Memory::IsVRAMAddress(fb_address) && !g_Config.bDisableStencilTest) { + if (Memory::IsVRAMAddress(fb_address)) { gpu->PerformStencilUpload(fb_address, 0x00088000); } return 0; diff --git a/Core/HLE/sceDisplay.cpp b/Core/HLE/sceDisplay.cpp index 7b2fcf20bd..78d186f777 100644 --- a/Core/HLE/sceDisplay.cpp +++ b/Core/HLE/sceDisplay.cpp @@ -503,6 +503,18 @@ static void DoFrameDropLogging(float scaledTimestep) { } } +static int CalculateFrameSkip() { + int frameSkipNum; + if (g_Config.iFrameSkipType == 1) { + // Calculate the frames to skip dynamically using the set percentage of the current fps + frameSkipNum = ceil( flips * (static_cast(g_Config.iFrameSkip) / 100.00) ); + } else { + // Use the set number of frames to skip + frameSkipNum = g_Config.iFrameSkip; + } + return frameSkipNum; +} + // Let's collect all the throttling and frameskipping logic here. static void DoFrameTiming(bool &throttle, bool &skipFrame, float timestep) { PROFILE_THIS_SCOPE("timing"); @@ -553,15 +565,16 @@ static void DoFrameTiming(bool &throttle, bool &skipFrame, float timestep) { // Auto-frameskip automatically if speed limit is set differently than the default. bool useAutoFrameskip = g_Config.bAutoFrameSkip && g_Config.iRenderingMode != FB_NON_BUFFERED_MODE; bool forceFrameskip = (fpsLimiter == FPSLimit::CUSTOM1 && g_Config.iFpsLimit1 > 60) || (fpsLimiter == FPSLimit::CUSTOM2 && g_Config.iFpsLimit2 > 60); + int frameSkipNum = CalculateFrameSkip(); if (g_Config.bAutoFrameSkip || forceFrameskip) { // autoframeskip // Argh, we are falling behind! Let's skip a frame and see if we catch up. if (curFrameTime > nextFrameTime && doFrameSkip) { skipFrame = true; } - } else if (g_Config.iFrameSkip >= 1) { + } else if (frameSkipNum >= 1) { // fixed frameskip - if (numSkippedFrames >= g_Config.iFrameSkip) + if (numSkippedFrames >= frameSkipNum) skipFrame = false; else skipFrame = true; @@ -734,9 +747,10 @@ void __DisplayFlip(int cyclesLate) { DoFrameTiming(throttle, skipFrame, (float)numVBlanksSinceFlip * timePerVblank); int maxFrameskip = 8; + int frameSkipNum = CalculateFrameSkip(); if (throttle) { // 4 here means 1 drawn, 4 skipped - so 12 fps minimum. - maxFrameskip = g_Config.iFrameSkip; + maxFrameskip = frameSkipNum; } if (numSkippedFrames >= maxFrameskip || GPURecord::IsActivePending()) { skipFrame = false; @@ -914,7 +928,7 @@ u32 sceDisplaySetFramebuf(u32 topaddr, int linesize, int pixelformat, int sync) s64 delayCycles = 0; // Don't count transitions between display off and display on. - if (topaddr != 0 && topaddr != framebuf.topaddr && framebuf.topaddr != 0 && g_Config.iForceMaxEmulatedFPS > 0) { + if (topaddr != 0 && topaddr != framebuf.topaddr && framebuf.topaddr != 0 && PSP_CoreParameter().compat.flags().ForceMax60FPS) { // sceDisplaySetFramebuf() isn't supposed to delay threads at all. This is a hack. // So let's only delay when it's more than 1ms. const s64 FLIP_DELAY_CYCLES_MIN = usToCycles(1000); @@ -928,7 +942,7 @@ u32 sceDisplaySetFramebuf(u32 topaddr, int linesize, int pixelformat, int sync) u64 now = CoreTiming::GetTicks(); s64 cyclesAhead = nextFlipCycles - now; if (cyclesAhead > FLIP_DELAY_CYCLES_MIN) { - if (lastFlipsTooFrequent >= FLIP_DELAY_MIN_FLIPS && gpuStats.numClears > 0) { + if (lastFlipsTooFrequent >= FLIP_DELAY_MIN_FLIPS) { delayCycles = cyclesAhead; } else { ++lastFlipsTooFrequent; @@ -938,7 +952,7 @@ u32 sceDisplaySetFramebuf(u32 topaddr, int linesize, int pixelformat, int sync) } // 1001 to account for NTSC timing (59.94 fps.) - u64 expected = msToCycles(g_Config.bRefreshAt60Hz ? 1000 : 1001) / g_Config.iForceMaxEmulatedFPS - LEEWAY_CYCLES_PER_FLIP; + u64 expected = msToCycles(g_Config.bRefreshAt60Hz ? 1000 : 1001) / 60 - LEEWAY_CYCLES_PER_FLIP; lastFlipCycles = now; nextFlipCycles = std::max(lastFlipCycles, nextFlipCycles) + expected; } diff --git a/Core/HLE/sceIo.cpp b/Core/HLE/sceIo.cpp index 3bf8c721c6..254b4f3509 100644 --- a/Core/HLE/sceIo.cpp +++ b/Core/HLE/sceIo.cpp @@ -253,6 +253,14 @@ public: u64 __IoCompleteAsyncIO(FileNode *f); +static int GetIOTimingMethod() { + if (PSP_CoreParameter().compat.flags().ForceUMDDelay) { + return IOTIMING_REALISTIC; + } else { + return g_Config.iIOTimingMethod; + } +} + static void TellFsThreadEnded (SceUID threadID) { pspFileSystem.ThreadEnded(threadID); } @@ -339,7 +347,8 @@ static void __IoAsyncNotify(u64 userdata, int cyclesLate) { return; } - if (g_Config.iIOTimingMethod == IOTIMING_HOST) { + int ioTimingMethod = GetIOTimingMethod(); + if (ioTimingMethod == IOTIMING_HOST) { // Not all async operations actually queue up. Maybe should separate them? if (!ioManager.HasResult(f->handle) && ioManager.HasOperation(f->handle)) { // Try again in another 0.5ms until the IO completes on the host. @@ -347,7 +356,7 @@ static void __IoAsyncNotify(u64 userdata, int cyclesLate) { return; } __IoCompleteAsyncIO(f); - } else if (g_Config.iIOTimingMethod == IOTIMING_REALISTIC) { + } else if (ioTimingMethod == IOTIMING_REALISTIC) { u64 finishTicks = __IoCompleteAsyncIO(f); if (finishTicks > CoreTiming::GetTicks()) { // Reschedule for later, since we now know how long it ought to take. @@ -396,13 +405,14 @@ static void __IoSyncNotify(u64 userdata, int cyclesLate) { return; } - if (g_Config.iIOTimingMethod == IOTIMING_HOST) { + int ioTimingMethod = GetIOTimingMethod(); + if (ioTimingMethod == IOTIMING_HOST) { if (!ioManager.HasResult(f->handle)) { // Try again in another 0.5ms until the IO completes on the host. CoreTiming::ScheduleEvent(usToCycles(500) - cyclesLate, syncNotifyEvent, userdata); return; } - } else if (g_Config.iIOTimingMethod == IOTIMING_REALISTIC) { + } else if (ioTimingMethod == IOTIMING_REALISTIC) { u64 finishTicks = ioManager.ResultFinishTicks(f->handle); if (finishTicks > CoreTiming::GetTicks()) { // Reschedule for later when the result should finish. @@ -723,7 +733,8 @@ static u32 sceKernelStderr() { u64 __IoCompleteAsyncIO(FileNode *f) { PROFILE_THIS_SCOPE("io_rw"); - if (g_Config.iIOTimingMethod == IOTIMING_REALISTIC) { + int ioTimingMethod = GetIOTimingMethod(); + if (ioTimingMethod == IOTIMING_REALISTIC) { u64 finishTicks = ioManager.ResultFinishTicks(f->handle); if (finishTicks > CoreTiming::GetTicks()) { return finishTicks; @@ -921,7 +932,7 @@ static bool __IoRead(int &result, int id, u32 data_addr, int size, int &us) { ioManager.ScheduleOperation(ev); return false; } else { - if (g_Config.iIOTimingMethod != IOTIMING_REALISTIC) { + if (GetIOTimingMethod() != IOTIMING_REALISTIC) { result = (int) pspFileSystem.ReadFile(f->handle, data, size); } else { result = (int) pspFileSystem.ReadFile(f->handle, data, size, us); @@ -991,7 +1002,7 @@ static u32 sceIoReadAsync(int id, u32 data_addr, int size) { int us; bool complete = __IoRead(result, id, data_addr, size, us); if (complete) { - f->asyncResult = result; + f->asyncResult = (s64)result; DEBUG_LOG(SCEIO, "%llx=sceIoReadAsync(%d, %08x, %x)", f->asyncResult, id, data_addr, size); } else { DEBUG_LOG(SCEIO, "sceIoReadAsync(%d, %08x, %x): deferring result", id, data_addr, size); @@ -1056,7 +1067,7 @@ static bool __IoWrite(int &result, int id, u32 data_addr, int size, int &us) { ioManager.ScheduleOperation(ev); return false; } else { - if (g_Config.iIOTimingMethod != IOTIMING_REALISTIC) { + if (GetIOTimingMethod() != IOTIMING_REALISTIC) { result = (int) pspFileSystem.WriteFile(f->handle, (u8 *) data_ptr, size); } else { result = (int) pspFileSystem.WriteFile(f->handle, (u8 *) data_ptr, size, us); @@ -1125,7 +1136,7 @@ static u32 sceIoWriteAsync(int id, u32 data_addr, int size) { int us; bool complete = __IoWrite(result, id, data_addr, size, us); if (complete) { - f->asyncResult = result; + f->asyncResult = (s64)result; DEBUG_LOG(SCEIO, "%llx=sceIoWriteAsync(%d, %08x, %x)", f->asyncResult, id, data_addr, size); } else { DEBUG_LOG(SCEIO, "sceIoWriteAsync(%d, %08x, %x): deferring result", id, data_addr, size); @@ -1935,7 +1946,7 @@ static u32 sceIoOpenAsync(const char *filename, int flags, int mode) f = new FileNode(); f->handle = kernelObjects.Create(f); f->fullpath = filename; - f->asyncResult = error == 0 ? SCE_KERNEL_ERROR_ERRNO_FILE_NOT_FOUND : error; + f->asyncResult = error == 0 ? (s64)SCE_KERNEL_ERROR_ERRNO_FILE_NOT_FOUND : (s64)error; f->closePending = true; fd = __IoAllocFd(f); diff --git a/Core/HLE/sceKernelInterrupt.cpp b/Core/HLE/sceKernelInterrupt.cpp index 9513d2d019..862e9eeb8d 100644 --- a/Core/HLE/sceKernelInterrupt.cpp +++ b/Core/HLE/sceKernelInterrupt.cpp @@ -684,7 +684,9 @@ const HLEFunction Kernel_Library[] = static u32 sysclib_memcpy(u32 dst, u32 src, u32 size) { ERROR_LOG(SCEKERNEL, "Untested sysclib_memcpy(dest=%08x, src=%08x, size=%i)", dst, src, size); - memcpy(Memory::GetPointer(dst), Memory::GetPointer(src), size); + if (Memory::IsValidRange(dst, size) && Memory::IsValidRange(src, size)) { + memcpy(Memory::GetPointer(dst), Memory::GetPointer(src), size); + } return dst; } diff --git a/Core/HLE/sceKernelModule.cpp b/Core/HLE/sceKernelModule.cpp index fe5cd6acf5..55366beef4 100644 --- a/Core/HLE/sceKernelModule.cpp +++ b/Core/HLE/sceKernelModule.cpp @@ -84,13 +84,14 @@ enum { }; // This is a workaround for misbehaving homebrew (like TBL's Suicide Barbie (Final)). -static const char *lieAboutSuccessModules[] = { +static const char * const lieAboutSuccessModules[] = { "flash0:/kd/audiocodec.prx", + "flash0:/kd/audiocodec_260.prx", "flash0:/kd/libatrac3plus.prx", "disc0:/PSP_GAME/SYSDIR/UPDATE/EBOOT.BIN", }; -static const char *blacklistedModules[] = { +static const char * const blacklistedModules[] = { "sceATRAC3plus_Library", "sceFont_Library", "SceFont_Library", diff --git a/Core/HLE/sceMpeg.cpp b/Core/HLE/sceMpeg.cpp index e6bd1e0680..a76a216fa4 100644 --- a/Core/HLE/sceMpeg.cpp +++ b/Core/HLE/sceMpeg.cpp @@ -1599,7 +1599,6 @@ static int sceMpegGetAvcAu(u32 mpeg, u32 streamId, u32 auAddr, u32 attrAddr) Memory::Write_U32(1, attrAddr); } - DEBUG_LOG(ME, "%x=sceMpegGetAvcAu(%08x, %08x, %08x, %08x)", result, mpeg, streamId, auAddr, attrAddr); // TODO: sceMpegGetAvcAu seems to modify esSize, and delay when it's > 1000 or something. // There's definitely more to it, but ultimately it seems games should expect it to delay randomly. @@ -1664,6 +1663,7 @@ static int sceMpegGetAtracAu(u32 mpeg, u32 streamId, u32 auAddr, u32 attrAddr) // Instead, let's abuse it to keep track of the stream number. if (streamInfo != ctx->streamMap.end()) { atracAu.esBuffer = streamInfo->second.num; + ctx->mediaengine->setAudioStream(streamInfo->second.num); } int result = 0; diff --git a/Core/HLE/sceMpeg.h b/Core/HLE/sceMpeg.h index ca310bf409..bf5b0dfcce 100644 --- a/Core/HLE/sceMpeg.h +++ b/Core/HLE/sceMpeg.h @@ -49,7 +49,7 @@ static const int PSMF_AUDIO_STREAM_ID = 0xBD; struct SceMpegAu { s64_le pts; // presentation time stamp s64_le dts; // decode time stamp - u32_le esBuffer; + u32_le esBuffer; // WARNING: We abuse this to keep track of the stream number! u32_le esSize; void read(u32 addr); diff --git a/Core/HLE/sceUsbGps.h b/Core/HLE/sceUsbGps.h index 7c2671fb9c..c9f1b7e8f0 100644 --- a/Core/HLE/sceUsbGps.h +++ b/Core/HLE/sceUsbGps.h @@ -22,8 +22,7 @@ void Register_sceUsbGps(); void __UsbGpsInit(); void __UsbGpsDoState(PointerWrap &p); -#pragma pack(push) -#pragma pack(1) +#pragma pack(push, 1) typedef struct { short year; diff --git a/Core/HLE/sceUtility.cpp b/Core/HLE/sceUtility.cpp index 6b5b89d75f..1a9c994701 100644 --- a/Core/HLE/sceUtility.cpp +++ b/Core/HLE/sceUtility.cpp @@ -26,6 +26,7 @@ #include "Core/MIPS/MIPS.h" #include "Core/Reporting.h" #include "Core/Config.h" +#include "Core/System.h" #include "Core/HLE/sceKernel.h" #include "Core/HLE/sceKernelMemory.h" @@ -185,8 +186,14 @@ static int sceUtilitySavedataInitStart(u32 paramAddr) { if (currentDialogActive && currentDialogType != UTILITY_DIALOG_SAVEDATA) { - WARN_LOG(SCEUTILITY, "sceUtilitySavedataInitStart(%08x): wrong dialog type", paramAddr); - return SCE_ERROR_UTILITY_WRONG_TYPE; + if (PSP_CoreParameter().compat.flags().YugiohSaveFix) + { + WARN_LOG(SCEUTILITY, "Yugioh Savedata Correction"); + } + else { + WARN_LOG(SCEUTILITY, "sceUtilitySavedataInitStart(%08x): wrong dialog type", paramAddr); + return SCE_ERROR_UTILITY_WRONG_TYPE; + } } oldStatus = 100; diff --git a/Core/Loaders.cpp b/Core/Loaders.cpp index c901a1245a..14bc31973d 100644 --- a/Core/Loaders.cpp +++ b/Core/Loaders.cpp @@ -294,7 +294,9 @@ bool LoadFile(FileLoader **fileLoaderPtr, std::string *error_string) { case IdentifiedFileType::ERROR_IDENTIFYING: ERROR_LOG(LOADER, "Could not read file"); - *error_string = "Error reading file"; + *error_string = fileLoader ? fileLoader->LatestError() : ""; + if (error_string->empty()) + *error_string = "Error reading file"; break; case IdentifiedFileType::ARCHIVE_RAR: diff --git a/Core/Loaders.h b/Core/Loaders.h index f0e83adab4..527fa52f5b 100644 --- a/Core/Loaders.h +++ b/Core/Loaders.h @@ -93,6 +93,48 @@ public: // Cancel any operations that might block, if possible. virtual void Cancel() { } + + virtual std::string LatestError() const { + return ""; + } +}; + +class ProxiedFileLoader : public FileLoader { +public: + ProxiedFileLoader(FileLoader *backend) : backend_(backend) { + } + ~ProxiedFileLoader() override { + // Takes ownership. + delete backend_; + } + + bool IsRemote() override { + return backend_->IsRemote(); + } + bool Exists() override { + return backend_->Exists(); + } + bool ExistsFast() override { + return backend_->ExistsFast(); + } + bool IsDirectory() override { + return backend_->IsDirectory(); + } + s64 FileSize() override { + return backend_->FileSize(); + } + std::string Path() const override { + return backend_->Path(); + } + void Cancel() override { + backend_->Cancel(); + } + std::string LatestError() const override { + return backend_->LatestError(); + } + +protected: + FileLoader *backend_; }; inline u32 operator & (const FileLoader::Flags &a, const FileLoader::Flags &b) { diff --git a/Core/MIPS/ARM/ArmCompALU.cpp b/Core/MIPS/ARM/ArmCompALU.cpp index 13788a5d93..66d12ed8a9 100644 --- a/Core/MIPS/ARM/ArmCompALU.cpp +++ b/Core/MIPS/ARM/ArmCompALU.cpp @@ -43,7 +43,7 @@ using namespace MIPSAnalyst; // Currently known non working ones should have DISABLE. // #define CONDITIONAL_DISABLE { Comp_Generic(op); return; } -#define CONDITIONAL_DISABLE ; +#define CONDITIONAL_DISABLE(flag) if (jo.Disabled(JitDisable::flag)) { Comp_Generic(op); return; } #define DISABLE { Comp_Generic(op); return; } namespace MIPSComp @@ -72,7 +72,7 @@ namespace MIPSComp void ArmJit::Comp_IType(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(ALU_IMM); s32 simm = (s32)(s16)(op & 0xFFFF); // sign extension u32 uimm = op & 0xFFFF; u32 suimm = (u32)(s32)simm; @@ -150,7 +150,7 @@ namespace MIPSComp void ArmJit::Comp_RType2(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(ALU_BIT); MIPSGPReg rs = _RS; MIPSGPReg rd = _RD; @@ -234,7 +234,7 @@ namespace MIPSComp void ArmJit::Comp_RType3(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(ALU); MIPSGPReg rt = _RT; MIPSGPReg rs = _RS; MIPSGPReg rd = _RD; @@ -502,7 +502,7 @@ namespace MIPSComp void ArmJit::Comp_ShiftType(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(ALU); MIPSGPReg rs = _RS; MIPSGPReg rd = _RD; int fd = _FD; @@ -529,7 +529,7 @@ namespace MIPSComp void ArmJit::Comp_Special3(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(ALU_BIT); MIPSGPReg rs = _RS; MIPSGPReg rt = _RT; @@ -591,7 +591,7 @@ namespace MIPSComp void ArmJit::Comp_Allegrex(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(ALU_BIT); MIPSGPReg rt = _RT; MIPSGPReg rd = _RD; // Don't change $zr. @@ -645,7 +645,7 @@ namespace MIPSComp void ArmJit::Comp_Allegrex2(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(ALU_BIT); MIPSGPReg rt = _RT; MIPSGPReg rd = _RD; // Don't change $zr. @@ -677,7 +677,7 @@ namespace MIPSComp void ArmJit::Comp_MulDivType(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(MULDIV); MIPSGPReg rt = _RT; MIPSGPReg rs = _RS; MIPSGPReg rd = _RD; diff --git a/Core/MIPS/ARM/ArmCompFPU.cpp b/Core/MIPS/ARM/ArmCompFPU.cpp index f4ec293382..cc49148d61 100644 --- a/Core/MIPS/ARM/ArmCompFPU.cpp +++ b/Core/MIPS/ARM/ArmCompFPU.cpp @@ -44,7 +44,7 @@ // Currently known non working ones should have DISABLE. // #define CONDITIONAL_DISABLE { Comp_Generic(op); return; } -#define CONDITIONAL_DISABLE ; +#define CONDITIONAL_DISABLE(flag) if (jo.Disabled(JitDisable::flag)) { Comp_Generic(op); return; } #define DISABLE { Comp_Generic(op); return; } namespace MIPSComp @@ -54,7 +54,7 @@ namespace MIPSComp void ArmJit::Comp_FPU3op(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(FPU); int ft = _FT; int fs = _FS; @@ -92,7 +92,7 @@ extern int logBlocks; void ArmJit::Comp_FPULS(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(LSU_FPU); CheckMemoryBreakpoint(); s32 offset = (s16)(op & 0xFFFF); @@ -193,7 +193,7 @@ void ArmJit::Comp_FPULS(MIPSOpcode op) } void ArmJit::Comp_FPUComp(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(FPU_COMP); int opc = op & 0xF; if (opc >= 8) opc -= 8; // alias @@ -258,7 +258,7 @@ void ArmJit::Comp_FPUComp(MIPSOpcode op) { } void ArmJit::Comp_FPU2op(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(FPU); int fs = _FS; int fd = _FD; @@ -350,7 +350,7 @@ void ArmJit::Comp_FPU2op(MIPSOpcode op) { void ArmJit::Comp_mxc1(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(FPU_XFER); int fs = _FS; MIPSGPReg rt = _RT; diff --git a/Core/MIPS/ARM/ArmCompLoadStore.cpp b/Core/MIPS/ARM/ArmCompLoadStore.cpp index 16a3753fd2..bc81e33116 100644 --- a/Core/MIPS/ARM/ArmCompLoadStore.cpp +++ b/Core/MIPS/ARM/ArmCompLoadStore.cpp @@ -42,7 +42,7 @@ // Currently known non working ones should have DISABLE. // #define CONDITIONAL_DISABLE { Comp_Generic(op); return; } -#define CONDITIONAL_DISABLE ; +#define CONDITIONAL_DISABLE(flag) if (jo.Disabled(JitDisable::flag)) { Comp_Generic(op); return; } #define DISABLE { Comp_Generic(op); return; } namespace MIPSComp @@ -111,14 +111,14 @@ namespace MIPSComp } void ArmJit::Comp_ITypeMemLR(MIPSOpcode op, bool load) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(LSU); CheckMemoryBreakpoint(); int offset = (signed short)(op & 0xFFFF); MIPSGPReg rt = _RT; MIPSGPReg rs = _RS; int o = op >> 26; - if (!js.inDelaySlot) { + if (!js.inDelaySlot && !jo.Disabled(JitDisable::LSU_UNALIGNED)) { // Optimisation: Combine to single unaligned load/store bool isLeft = (o == 34 || o == 42); CheckMemoryBreakpoint(1); @@ -260,7 +260,7 @@ namespace MIPSComp void ArmJit::Comp_ITypeMem(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(LSU); CheckMemoryBreakpoint(); int offset = (signed short)(op&0xFFFF); bool load = false; diff --git a/Core/MIPS/ARM/ArmCompVFPU.cpp b/Core/MIPS/ARM/ArmCompVFPU.cpp index c171424075..9d2bcfe611 100644 --- a/Core/MIPS/ARM/ArmCompVFPU.cpp +++ b/Core/MIPS/ARM/ArmCompVFPU.cpp @@ -40,7 +40,7 @@ // Currently known non working ones should have DISABLE. // #define CONDITIONAL_DISABLE { fpr.ReleaseSpillLocksAndDiscardTemps(); Comp_Generic(op); return; } -#define CONDITIONAL_DISABLE ; +#define CONDITIONAL_DISABLE(flag) if (jo.Disabled(JitDisable::flag)) { Comp_Generic(op); return; } #define DISABLE { fpr.ReleaseSpillLocksAndDiscardTemps(); Comp_Generic(op); return; } #define NEON_IF_AVAILABLE(func) { if (jo.useNEONVFPU) { func(op); return; } } @@ -87,7 +87,7 @@ namespace MIPSComp void ArmJit::Comp_VPFX(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_XFER); int data = op & 0xFFFFF; int regnum = (op >> 24) & 3; switch (regnum) { @@ -225,7 +225,7 @@ namespace MIPSComp void ArmJit::Comp_SV(MIPSOpcode op) { NEON_IF_AVAILABLE(CompNEON_SV); - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(LSU_VFPU); CheckMemoryBreakpoint(); s32 offset = (signed short)(op & 0xFFFC); @@ -332,7 +332,7 @@ namespace MIPSComp void ArmJit::Comp_SVQ(MIPSOpcode op) { NEON_IF_AVAILABLE(CompNEON_SVQ); - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(LSU_VFPU); CheckMemoryBreakpoint(); int imm = (signed short)(op&0xFFFC); @@ -478,7 +478,7 @@ namespace MIPSComp void ArmJit::Comp_VVectorInit(MIPSOpcode op) { NEON_IF_AVAILABLE(CompNEON_VVectorInit); - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_XFER); // WARNING: No prefix support! if (js.HasUnknownPrefix()) { DISABLE; @@ -515,7 +515,7 @@ namespace MIPSComp void ArmJit::Comp_VIdt(MIPSOpcode op) { NEON_IF_AVAILABLE(CompNEON_VIdt); - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_XFER); if (js.HasUnknownPrefix()) { DISABLE; } @@ -553,7 +553,7 @@ namespace MIPSComp void ArmJit::Comp_VMatrixInit(MIPSOpcode op) { NEON_IF_AVAILABLE(CompNEON_VMatrixInit); - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_XFER); if (js.HasUnknownPrefix()) { // Don't think matrix init ops care about prefixes. // DISABLE; @@ -601,7 +601,7 @@ namespace MIPSComp void ArmJit::Comp_VHdp(MIPSOpcode op) { NEON_IF_AVAILABLE(CompNEON_VHdp); - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_VEC); if (js.HasUnknownPrefix()) { DISABLE; } @@ -644,7 +644,7 @@ namespace MIPSComp void ArmJit::Comp_Vhoriz(MIPSOpcode op) { NEON_IF_AVAILABLE(CompNEON_Vhoriz); - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_VEC); if (js.HasUnknownPrefix()) { DISABLE; } @@ -687,7 +687,7 @@ namespace MIPSComp void ArmJit::Comp_VDot(MIPSOpcode op) { NEON_IF_AVAILABLE(CompNEON_VDot); - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_VEC); if (js.HasUnknownPrefix()) { DISABLE; } @@ -724,7 +724,7 @@ namespace MIPSComp void ArmJit::Comp_VecDo3(MIPSOpcode op) { NEON_IF_AVAILABLE(CompNEON_VecDo3); - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_VEC); if (js.HasUnknownPrefix()) { DISABLE; } @@ -884,7 +884,7 @@ namespace MIPSComp void ArmJit::Comp_VV2Op(MIPSOpcode op) { NEON_IF_AVAILABLE(CompNEON_VV2Op); - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_VEC); if (js.HasUnknownPrefix()) { DISABLE; } @@ -1077,7 +1077,7 @@ namespace MIPSComp void ArmJit::Comp_Vi2f(MIPSOpcode op) { NEON_IF_AVAILABLE(CompNEON_Vi2f); - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_VEC); if (js.HasUnknownPrefix()) { DISABLE; } @@ -1124,7 +1124,7 @@ namespace MIPSComp void ArmJit::Comp_Vh2f(MIPSOpcode op) { NEON_IF_AVAILABLE(CompNEON_Vh2f); - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_VEC); if (js.HasUnknownPrefix()) { DISABLE; } @@ -1186,7 +1186,7 @@ namespace MIPSComp void ArmJit::Comp_Vf2i(MIPSOpcode op) { NEON_IF_AVAILABLE(CompNEON_Vf2i); - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_VEC); if (js.HasUnknownPrefix()) { DISABLE; @@ -1256,7 +1256,7 @@ namespace MIPSComp void ArmJit::Comp_Mftv(MIPSOpcode op) { NEON_IF_AVAILABLE(CompNEON_Mftv); - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_XFER); int imm = op & 0xFF; MIPSGPReg rt = _RT; @@ -1331,7 +1331,7 @@ namespace MIPSComp void ArmJit::Comp_Vmfvc(MIPSOpcode op) { NEON_IF_AVAILABLE(CompNEON_Vmtvc); - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_XFER); int vs = _VS; int imm = op & 0xFF; @@ -1350,7 +1350,7 @@ namespace MIPSComp void ArmJit::Comp_Vmtvc(MIPSOpcode op) { NEON_IF_AVAILABLE(CompNEON_Vmtvc); - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_XFER); int vs = _VS; int imm = op & 0xFF; @@ -1377,7 +1377,7 @@ namespace MIPSComp void ArmJit::Comp_Vmmov(MIPSOpcode op) { NEON_IF_AVAILABLE(CompNEON_Vmmov); - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_MTX); // This probably ignores prefixes for all sane intents and purposes. if (_VS == _VD) { @@ -1415,7 +1415,7 @@ namespace MIPSComp void ArmJit::Comp_VScl(MIPSOpcode op) { NEON_IF_AVAILABLE(CompNEON_VScl); - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_VEC); if (js.HasUnknownPrefix()) { DISABLE; } @@ -1464,7 +1464,7 @@ namespace MIPSComp } void ArmJit::Comp_Vmmul(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_MTX); if (js.HasUnknownPrefix()) { DISABLE; } @@ -1513,7 +1513,7 @@ namespace MIPSComp void ArmJit::Comp_Vtfm(MIPSOpcode op) { NEON_IF_AVAILABLE(CompNEON_Vtfm); - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_MTX); if (js.HasUnknownPrefix()) { DISABLE; } @@ -1584,7 +1584,7 @@ namespace MIPSComp void ArmJit::Comp_Vi2x(MIPSOpcode op) { NEON_IF_AVAILABLE(CompNEON_Vi2x); - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_VEC); if (js.HasUnknownPrefix()) { DISABLE; } @@ -1662,7 +1662,7 @@ namespace MIPSComp void ArmJit::Comp_Vx2i(MIPSOpcode op) { NEON_IF_AVAILABLE(CompNEON_Vx2i); - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_VEC); if (js.HasUnknownPrefix()) { DISABLE; } @@ -1751,7 +1751,7 @@ namespace MIPSComp void ArmJit::Comp_VCrossQuat(MIPSOpcode op) { NEON_IF_AVAILABLE(CompNEON_VCrossQuat); // This op does not support prefixes anyway. - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_VEC); if (js.HasUnknownPrefix()) DISABLE; @@ -1831,7 +1831,7 @@ namespace MIPSComp void ArmJit::Comp_Vcmp(MIPSOpcode op) { NEON_IF_AVAILABLE(CompNEON_Vcmp); - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_COMP); if (js.HasUnknownPrefix()) DISABLE; @@ -2019,7 +2019,7 @@ namespace MIPSComp void ArmJit::Comp_Vcmov(MIPSOpcode op) { NEON_IF_AVAILABLE(CompNEON_Vcmov); - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_COMP); if (js.HasUnknownPrefix()) { DISABLE; } @@ -2070,7 +2070,7 @@ namespace MIPSComp void ArmJit::Comp_Viim(MIPSOpcode op) { NEON_IF_AVAILABLE(CompNEON_Viim); - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_XFER); if (js.HasUnknownPrefix()) { DISABLE; } @@ -2088,7 +2088,7 @@ namespace MIPSComp void ArmJit::Comp_Vfim(MIPSOpcode op) { NEON_IF_AVAILABLE(CompNEON_Vfim); - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_XFER); if (js.HasUnknownPrefix()) { DISABLE; } @@ -2108,7 +2108,7 @@ namespace MIPSComp void ArmJit::Comp_Vcst(MIPSOpcode op) { NEON_IF_AVAILABLE(CompNEON_Vcst); - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_XFER); if (js.HasUnknownPrefix()) { DISABLE; } @@ -2178,7 +2178,7 @@ namespace MIPSComp void ArmJit::Comp_VRot(MIPSOpcode op) { NEON_IF_AVAILABLE(CompNEON_VRot); // VRot probably doesn't accept prefixes anyway. - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_VEC); if (js.HasUnknownPrefix()) { DISABLE; } @@ -2244,7 +2244,7 @@ namespace MIPSComp void ArmJit::Comp_Vsgn(MIPSOpcode op) { NEON_IF_AVAILABLE(CompNEON_Vsgn); - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_VEC); if (js.HasUnknownPrefix()) { DISABLE; } @@ -2293,7 +2293,7 @@ namespace MIPSComp void ArmJit::Comp_Vocp(MIPSOpcode op) { NEON_IF_AVAILABLE(CompNEON_Vocp); - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_VEC); if (js.HasUnknownPrefix()) { DISABLE; } diff --git a/Core/MIPS/ARM/ArmCompVFPUNEON.cpp b/Core/MIPS/ARM/ArmCompVFPUNEON.cpp index 9f04436bf4..945d993849 100644 --- a/Core/MIPS/ARM/ArmCompVFPUNEON.cpp +++ b/Core/MIPS/ARM/ArmCompVFPUNEON.cpp @@ -53,7 +53,7 @@ // Currently known non working ones should have DISABLE. // #define CONDITIONAL_DISABLE { fpr.ReleaseSpillLocksAndDiscardTemps(); Comp_Generic(op); return; } -#define CONDITIONAL_DISABLE ; +#define CONDITIONAL_DISABLE(flag) if (jo.Disabled(JitDisable::flag)) { Comp_Generic(op); return; } #define DISABLE { fpr.ReleaseSpillLocksAndDiscardTemps(); Comp_Generic(op); return; } #define DISABLE_UNKNOWN_PREFIX { WLOG("DISABLE: Unknown Prefix in %s", __FUNCTION__); fpr.ReleaseSpillLocksAndDiscardTemps(); Comp_Generic(op); return; } @@ -82,7 +82,7 @@ static const float zero = 0.0f; void ArmJit::CompNEON_VecDo3(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_VEC); if (js.HasUnknownPrefix()) { DISABLE_UNKNOWN_PREFIX; } @@ -158,7 +158,7 @@ void ArmJit::CompNEON_VecDo3(MIPSOpcode op) { // #define CONDITIONAL_DISABLE { fpr.ReleaseSpillLocksAndDiscardTemps(); Comp_Generic(op); return; } void ArmJit::CompNEON_SV(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(LSU_VFPU); CheckMemoryBreakpoint(); // Remember to use single lane stores here and not VLDR/VSTR - switching usage @@ -276,7 +276,7 @@ inline int MIPS_GET_VQVT(u32 op) { } void ArmJit::CompNEON_SVQ(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(LSU_VFPU); CheckMemoryBreakpoint(); int offset = (signed short)(op & 0xFFFC); @@ -425,7 +425,7 @@ void ArmJit::CompNEON_SVQ(MIPSOpcode op) { } void ArmJit::CompNEON_VVectorInit(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_XFER); // WARNING: No prefix support! if (js.HasUnknownPrefix()) { DISABLE_UNKNOWN_PREFIX; @@ -450,7 +450,7 @@ void ArmJit::CompNEON_VVectorInit(MIPSOpcode op) { } void ArmJit::CompNEON_VDot(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_VEC); if (js.HasUnknownPrefix()) { DISABLE_UNKNOWN_PREFIX; } @@ -484,7 +484,7 @@ void ArmJit::CompNEON_VDot(MIPSOpcode op) { void ArmJit::CompNEON_VHdp(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_VEC); if (js.HasUnknownPrefix()) { DISABLE_UNKNOWN_PREFIX; } @@ -496,7 +496,7 @@ void ArmJit::CompNEON_VHdp(MIPSOpcode op) { } void ArmJit::CompNEON_VScl(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_VEC); if (js.HasUnknownPrefix()) { DISABLE_UNKNOWN_PREFIX; } @@ -515,7 +515,7 @@ void ArmJit::CompNEON_VScl(MIPSOpcode op) { } void ArmJit::CompNEON_VV2Op(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_VEC); if (js.HasUnknownPrefix()) { DISABLE_UNKNOWN_PREFIX; } @@ -666,7 +666,7 @@ void ArmJit::CompNEON_VV2Op(MIPSOpcode op) { } void ArmJit::CompNEON_Mftv(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_XFER); int imm = op & 0xFF; MIPSGPReg rt = _RT; switch ((op >> 21) & 0x1f) { @@ -746,7 +746,7 @@ void ArmJit::CompNEON_Vmfvc(MIPSOpcode op) { } void ArmJit::CompNEON_Vmtvc(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_XFER); int vs = _VS; int imm = op & 0xFF; @@ -767,7 +767,7 @@ void ArmJit::CompNEON_Vmtvc(MIPSOpcode op) { } void ArmJit::CompNEON_VMatrixInit(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_XFER); MatrixSize msz = GetMtxSize(op); int n = GetMatrixSide(msz); @@ -828,7 +828,7 @@ void ArmJit::CompNEON_VMatrixInit(MIPSOpcode op) { } void ArmJit::CompNEON_Vmmov(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_MTX); if (_VS == _VD) { // A lot of these no-op matrix moves in Wipeout... Just drop the instruction entirely. return; @@ -856,7 +856,7 @@ void ArmJit::CompNEON_Vmmov(MIPSOpcode op) { } void ArmJit::CompNEON_Vmmul(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_MTX); MatrixSize msz = GetMtxSize(op); int n = GetMatrixSide(msz); @@ -895,7 +895,7 @@ void ArmJit::CompNEON_Vmmul(MIPSOpcode op) { } void ArmJit::CompNEON_Vmscl(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_MTX); MatrixSize msz = GetMtxSize(op); @@ -920,7 +920,7 @@ void ArmJit::CompNEON_Vmscl(MIPSOpcode op) { } void ArmJit::CompNEON_Vtfm(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_MTX); if (js.HasUnknownPrefix()) { DISABLE; } @@ -986,7 +986,7 @@ void ArmJit::CompNEON_Vf2i(MIPSOpcode op) { } void ArmJit::CompNEON_Vi2f(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_VEC); if (js.HasUnknownPrefix()) { DISABLE; } @@ -1012,6 +1012,7 @@ void ArmJit::CompNEON_Vi2f(MIPSOpcode op) { } void ArmJit::CompNEON_Vh2f(MIPSOpcode op) { + CONDITIONAL_DISABLE(VFPU_VEC); if (!cpu_info.bHalf) { // No hardware support for half-to-float, fallback to interpreter // TODO: Translate the fast SSE solution to standard integer/VFP stuff @@ -1045,7 +1046,7 @@ void ArmJit::CompNEON_Vh2f(MIPSOpcode op) { } void ArmJit::CompNEON_Vcst(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_XFER); if (js.HasUnknownPrefix()) { DISABLE_UNKNOWN_PREFIX; } @@ -1063,7 +1064,7 @@ void ArmJit::CompNEON_Vcst(MIPSOpcode op) { } void ArmJit::CompNEON_Vhoriz(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_VEC); if (js.HasUnknownPrefix()) { DISABLE_UNKNOWN_PREFIX; } @@ -1102,7 +1103,7 @@ void ArmJit::CompNEON_Vhoriz(MIPSOpcode op) { } void ArmJit::CompNEON_VRot(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_VEC); if (js.HasUnknownPrefix()) { DISABLE_UNKNOWN_PREFIX; @@ -1121,7 +1122,7 @@ void ArmJit::CompNEON_VRot(MIPSOpcode op) { } void ArmJit::CompNEON_VIdt(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_XFER); if (js.HasUnknownPrefix()) { DISABLE_UNKNOWN_PREFIX; } @@ -1167,7 +1168,7 @@ void ArmJit::CompNEON_VIdt(MIPSOpcode op) { } void ArmJit::CompNEON_Vcmp(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_COMP); if (js.HasUnknownPrefix()) DISABLE; @@ -1298,7 +1299,7 @@ void ArmJit::CompNEON_Vcmp(MIPSOpcode op) { } void ArmJit::CompNEON_Vcmov(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_COMP); if (js.HasUnknownPrefix()) { DISABLE; } @@ -1341,7 +1342,7 @@ void ArmJit::CompNEON_Vcmov(MIPSOpcode op) { } void ArmJit::CompNEON_Viim(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_XFER); if (js.HasUnknownPrefix()) { DISABLE; } @@ -1358,7 +1359,7 @@ void ArmJit::CompNEON_Viim(MIPSOpcode op) { } void ArmJit::CompNEON_Vfim(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_XFER); if (js.HasUnknownPrefix()) { DISABLE; } @@ -1379,7 +1380,7 @@ void ArmJit::CompNEON_Vfim(MIPSOpcode op) { // https://code.google.com/p/bullet/source/browse/branches/PhysicsEffects/include/vecmath/neon/vectormath_neon_assembly_implementations.S?r=2488 void ArmJit::CompNEON_VCrossQuat(MIPSOpcode op) { // This op does not support prefixes anyway. - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_VEC); if (js.HasUnknownPrefix()) { DISABLE_UNKNOWN_PREFIX; } @@ -1427,7 +1428,7 @@ void ArmJit::CompNEON_Vsgn(MIPSOpcode op) { } void ArmJit::CompNEON_Vocp(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_VEC); if (js.HasUnknownPrefix()) { DISABLE; } diff --git a/Core/MIPS/ARM/ArmJit.cpp b/Core/MIPS/ARM/ArmJit.cpp index 87bb801087..b41707f285 100644 --- a/Core/MIPS/ARM/ArmJit.cpp +++ b/Core/MIPS/ARM/ArmJit.cpp @@ -46,7 +46,7 @@ using namespace ArmJitConstants; -static void DisassembleArm(const u8 *data, int size) { +void DisassembleArm(const u8 *data, int size) { char temp[256]; for (int i = 0; i < size; i += 4) { const u32 *codePtr = (const u32 *)(data + i); diff --git a/Core/MIPS/ARM64/Arm64CompALU.cpp b/Core/MIPS/ARM64/Arm64CompALU.cpp index 48572f3d96..aa3ffb577e 100644 --- a/Core/MIPS/ARM64/Arm64CompALU.cpp +++ b/Core/MIPS/ARM64/Arm64CompALU.cpp @@ -44,7 +44,7 @@ using namespace MIPSAnalyst; // Currently known non working ones should have DISABLE. // #define CONDITIONAL_DISABLE { Comp_Generic(op); return; } -#define CONDITIONAL_DISABLE ; +#define CONDITIONAL_DISABLE(flag) if (jo.Disabled(JitDisable::flag)) { Comp_Generic(op); return; } #define DISABLE { Comp_Generic(op); return; } namespace MIPSComp { @@ -70,7 +70,7 @@ void Arm64Jit::CompImmLogic(MIPSGPReg rs, MIPSGPReg rt, u32 uimm, void (ARM64XEm } void Arm64Jit::Comp_IType(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(ALU_IMM); s32 simm = (s32)(s16)(op & 0xFFFF); // sign extension u32 uimm = op & 0xFFFF; u32 suimm = (u32)(s32)simm; @@ -146,7 +146,7 @@ void Arm64Jit::Comp_IType(MIPSOpcode op) { } void Arm64Jit::Comp_RType2(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(ALU_BIT); MIPSGPReg rs = _RS; MIPSGPReg rd = _RD; @@ -234,7 +234,7 @@ void Arm64Jit::CompType3(MIPSGPReg rd, MIPSGPReg rs, MIPSGPReg rt, void (ARM64XE } void Arm64Jit::Comp_RType3(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(ALU); MIPSGPReg rt = _RT; MIPSGPReg rs = _RS; @@ -406,7 +406,7 @@ void Arm64Jit::CompShiftVar(MIPSOpcode op, Arm64Gen::ShiftType shiftType) { } void Arm64Jit::Comp_ShiftType(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(ALU); MIPSGPReg rs = _RS; MIPSGPReg rd = _RD; int fd = _FD; @@ -431,7 +431,7 @@ void Arm64Jit::Comp_ShiftType(MIPSOpcode op) { } void Arm64Jit::Comp_Special3(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(ALU_BIT); MIPSGPReg rs = _RS; MIPSGPReg rt = _RT; @@ -479,7 +479,7 @@ void Arm64Jit::Comp_Special3(MIPSOpcode op) { } void Arm64Jit::Comp_Allegrex(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(ALU_BIT); MIPSGPReg rt = _RT; MIPSGPReg rd = _RD; // Don't change $zr. @@ -529,7 +529,7 @@ void Arm64Jit::Comp_Allegrex(MIPSOpcode op) { } void Arm64Jit::Comp_Allegrex2(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(ALU_BIT); MIPSGPReg rt = _RT; MIPSGPReg rd = _RD; // Don't change $zr. @@ -560,7 +560,7 @@ void Arm64Jit::Comp_Allegrex2(MIPSOpcode op) { } void Arm64Jit::Comp_MulDivType(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(MULDIV); MIPSGPReg rt = _RT; MIPSGPReg rs = _RS; MIPSGPReg rd = _RD; diff --git a/Core/MIPS/ARM64/Arm64CompFPU.cpp b/Core/MIPS/ARM64/Arm64CompFPU.cpp index 55298ae577..98121615b1 100644 --- a/Core/MIPS/ARM64/Arm64CompFPU.cpp +++ b/Core/MIPS/ARM64/Arm64CompFPU.cpp @@ -52,7 +52,7 @@ // Currently known non working ones should have DISABLE. // #define CONDITIONAL_DISABLE { Comp_Generic(op); return; } -#define CONDITIONAL_DISABLE ; +#define CONDITIONAL_DISABLE(flag) if (jo.Disabled(JitDisable::flag)) { Comp_Generic(op); return; } #define DISABLE { Comp_Generic(op); return; } namespace MIPSComp { @@ -60,7 +60,7 @@ namespace MIPSComp { using namespace Arm64JitConstants; void Arm64Jit::Comp_FPU3op(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(FPU); int ft = _FT; int fs = _FS; @@ -80,7 +80,7 @@ void Arm64Jit::Comp_FPU3op(MIPSOpcode op) { void Arm64Jit::Comp_FPULS(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(LSU_FPU); CheckMemoryBreakpoint(); // Surprisingly, these work fine alraedy. @@ -152,7 +152,7 @@ void Arm64Jit::Comp_FPULS(MIPSOpcode op) } void Arm64Jit::Comp_FPUComp(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(FPU_COMP); int opc = op & 0xF; if (opc >= 8) opc -= 8; // alias @@ -198,7 +198,7 @@ void Arm64Jit::Comp_FPUComp(MIPSOpcode op) { } void Arm64Jit::Comp_FPU2op(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(FPU); int fs = _FS; int fd = _FD; @@ -301,7 +301,7 @@ void Arm64Jit::Comp_FPU2op(MIPSOpcode op) { void Arm64Jit::Comp_mxc1(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(FPU_XFER); int fs = _FS; MIPSGPReg rt = _RT; diff --git a/Core/MIPS/ARM64/Arm64CompLoadStore.cpp b/Core/MIPS/ARM64/Arm64CompLoadStore.cpp index 7b962f0e95..f28074c2e9 100644 --- a/Core/MIPS/ARM64/Arm64CompLoadStore.cpp +++ b/Core/MIPS/ARM64/Arm64CompLoadStore.cpp @@ -42,7 +42,7 @@ // Currently known non working ones should have DISABLE. // #define CONDITIONAL_DISABLE { Comp_Generic(op); return; } -#define CONDITIONAL_DISABLE ; +#define CONDITIONAL_DISABLE(flag) if (jo.Disabled(JitDisable::flag)) { Comp_Generic(op); return; } #define DISABLE { Comp_Generic(op); return; } namespace MIPSComp { @@ -110,14 +110,14 @@ namespace MIPSComp { } void Arm64Jit::Comp_ITypeMemLR(MIPSOpcode op, bool load) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(LSU); CheckMemoryBreakpoint(); int offset = (signed short)(op & 0xFFFF); MIPSGPReg rt = _RT; MIPSGPReg rs = _RS; int o = op >> 26; - if (!js.inDelaySlot) { + if (!js.inDelaySlot && !jo.Disabled(JitDisable::LSU_UNALIGNED)) { // Optimisation: Combine to single unaligned load/store bool isLeft = (o == 34 || o == 42); CheckMemoryBreakpoint(1); @@ -256,7 +256,7 @@ namespace MIPSComp { } void Arm64Jit::Comp_ITypeMem(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(LSU); CheckMemoryBreakpoint(); int offset = (signed short)(op & 0xFFFF); diff --git a/Core/MIPS/ARM64/Arm64CompVFPU.cpp b/Core/MIPS/ARM64/Arm64CompVFPU.cpp index 7799dfbfa4..88ba5df94a 100644 --- a/Core/MIPS/ARM64/Arm64CompVFPU.cpp +++ b/Core/MIPS/ARM64/Arm64CompVFPU.cpp @@ -38,7 +38,7 @@ // Currently known non working ones should have DISABLE. // #define CONDITIONAL_DISABLE { fpr.ReleaseSpillLocksAndDiscardTemps(); Comp_Generic(op); return; } -#define CONDITIONAL_DISABLE ; +#define CONDITIONAL_DISABLE(flag) if (jo.Disabled(JitDisable::flag)) { Comp_Generic(op); return; } #define DISABLE { fpr.ReleaseSpillLocksAndDiscardTemps(); Comp_Generic(op); return; } #define _RS MIPS_GET_RS(op) @@ -80,7 +80,7 @@ namespace MIPSComp { } void Arm64Jit::Comp_VPFX(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_XFER); int data = op & 0xFFFFF; int regnum = (op >> 24) & 3; switch (regnum) { @@ -201,7 +201,7 @@ namespace MIPSComp { } void Arm64Jit::Comp_SV(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(LSU_VFPU); CheckMemoryBreakpoint(); s32 offset = (signed short)(op & 0xFFFC); @@ -275,7 +275,7 @@ namespace MIPSComp { } void Arm64Jit::Comp_SVQ(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(LSU_VFPU); CheckMemoryBreakpoint(); int imm = (signed short)(op&0xFFFC); @@ -359,7 +359,7 @@ namespace MIPSComp { } void Arm64Jit::Comp_VVectorInit(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_XFER); // WARNING: No prefix support! if (js.HasUnknownPrefix()) { DISABLE; @@ -393,7 +393,7 @@ namespace MIPSComp { } void Arm64Jit::Comp_VIdt(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_XFER); if (js.HasUnknownPrefix()) { DISABLE; } @@ -428,7 +428,7 @@ namespace MIPSComp { } void Arm64Jit::Comp_VMatrixInit(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_XFER); if (js.HasUnknownPrefix()) { // Don't think matrix init ops care about prefixes. // DISABLE; @@ -475,7 +475,7 @@ namespace MIPSComp { } void Arm64Jit::Comp_VHdp(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_VEC); if (js.HasUnknownPrefix()) { DISABLE; } @@ -517,7 +517,7 @@ namespace MIPSComp { alignas(16) static const float vavg_table[4] = { 1.0f, 1.0f / 2.0f, 1.0f / 3.0f, 1.0f / 4.0f }; void Arm64Jit::Comp_Vhoriz(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_VEC); if (js.HasUnknownPrefix()) { DISABLE; } @@ -559,7 +559,7 @@ namespace MIPSComp { } void Arm64Jit::Comp_VDot(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_VEC); if (js.HasUnknownPrefix()) { DISABLE; } @@ -595,7 +595,7 @@ namespace MIPSComp { } void Arm64Jit::Comp_VecDo3(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_VEC); if (js.HasUnknownPrefix()) { DISABLE; } @@ -744,7 +744,7 @@ namespace MIPSComp { } void Arm64Jit::Comp_VV2Op(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_VEC); if (js.HasUnknownPrefix()) { DISABLE; } @@ -884,7 +884,7 @@ namespace MIPSComp { } void Arm64Jit::Comp_Vi2f(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_VEC); if (js.HasUnknownPrefix()) { DISABLE; } @@ -931,7 +931,7 @@ namespace MIPSComp { } void Arm64Jit::Comp_Vh2f(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_VEC); if (js.HasUnknownPrefix()) { DISABLE; } @@ -978,6 +978,7 @@ namespace MIPSComp { } void Arm64Jit::Comp_Mftv(MIPSOpcode op) { + CONDITIONAL_DISABLE(VFPU_XFER); int imm = op & 0xFF; MIPSGPReg rt = _RT; switch ((op >> 21) & 0x1f) { @@ -1063,7 +1064,7 @@ namespace MIPSComp { } void Arm64Jit::Comp_Vmfvc(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_XFER); int vs = _VS; int imm = op & 0xFF; @@ -1081,7 +1082,7 @@ namespace MIPSComp { } void Arm64Jit::Comp_Vmtvc(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_XFER); int vs = _VS; int imm = op & 0xFF; @@ -1107,7 +1108,7 @@ namespace MIPSComp { } void Arm64Jit::Comp_Vmmov(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_MTX); // This probably ignores prefixes for all sane intents and purposes. if (_VS == _VD) { @@ -1144,7 +1145,7 @@ namespace MIPSComp { } void Arm64Jit::Comp_VScl(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_VEC); if (js.HasUnknownPrefix()) { DISABLE; } @@ -1193,7 +1194,7 @@ namespace MIPSComp { } void Arm64Jit::Comp_Vmmul(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_MTX); if (js.HasUnknownPrefix()) { DISABLE; } @@ -1239,7 +1240,7 @@ namespace MIPSComp { } void Arm64Jit::Comp_Vtfm(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_MTX); if (js.HasUnknownPrefix()) { DISABLE; } @@ -1307,7 +1308,7 @@ namespace MIPSComp { } void Arm64Jit::Comp_Vi2x(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_VEC); if (js.HasUnknownPrefix()) DISABLE; @@ -1376,7 +1377,7 @@ namespace MIPSComp { } void Arm64Jit::Comp_Vx2i(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_VEC); if (js.HasUnknownPrefix()) DISABLE; @@ -1471,7 +1472,7 @@ namespace MIPSComp { void Arm64Jit::Comp_VCrossQuat(MIPSOpcode op) { // This op does not support prefixes anyway. - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_VEC); if (js.HasUnknownPrefix()) DISABLE; @@ -1550,7 +1551,7 @@ namespace MIPSComp { } void Arm64Jit::Comp_Vcmp(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_COMP); if (js.HasUnknownPrefix()) DISABLE; @@ -1727,7 +1728,7 @@ namespace MIPSComp { } void Arm64Jit::Comp_Vcmov(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_COMP); if (js.HasUnknownPrefix()) { DISABLE; } @@ -1778,7 +1779,7 @@ namespace MIPSComp { } void Arm64Jit::Comp_Viim(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_XFER); if (js.HasUnknownPrefix()) { DISABLE; } @@ -1795,7 +1796,7 @@ namespace MIPSComp { } void Arm64Jit::Comp_Vfim(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_XFER); if (js.HasUnknownPrefix()) { DISABLE; } @@ -1814,7 +1815,7 @@ namespace MIPSComp { } void Arm64Jit::Comp_Vcst(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_XFER); if (js.HasUnknownPrefix()) { DISABLE; } @@ -1882,7 +1883,7 @@ namespace MIPSComp { // calling the math library. void Arm64Jit::Comp_VRot(MIPSOpcode op) { // VRot probably doesn't accept prefixes anyway. - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_VEC); if (js.HasUnknownPrefix()) { DISABLE; } @@ -1943,7 +1944,7 @@ namespace MIPSComp { } void Arm64Jit::Comp_Vocp(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_VEC); if (js.HasUnknownPrefix()) { DISABLE; } diff --git a/Core/MIPS/IR/IRCompALU.cpp b/Core/MIPS/IR/IRCompALU.cpp index 70fa758dac..2622ea1b9d 100644 --- a/Core/MIPS/IR/IRCompALU.cpp +++ b/Core/MIPS/IR/IRCompALU.cpp @@ -38,14 +38,14 @@ // Currently known non working ones should have DISABLE. // #define CONDITIONAL_DISABLE { Comp_Generic(op); return; } -#define CONDITIONAL_DISABLE ; +#define CONDITIONAL_DISABLE(flag) if (opts.disableFlags & (uint32_t)JitDisable::flag) { Comp_Generic(op); return; } #define DISABLE { Comp_Generic(op); return; } #define INVALIDOP { Comp_Generic(op); return; } namespace MIPSComp { void IRFrontend::Comp_IType(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(ALU_IMM); s32 simm = (s32)_IMM16; // sign extension u32 uimm = (u16)_IMM16; @@ -87,7 +87,7 @@ void IRFrontend::Comp_IType(MIPSOpcode op) { } void IRFrontend::Comp_RType2(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(ALU_BIT); MIPSGPReg rs = _RS; MIPSGPReg rd = _RD; @@ -111,7 +111,7 @@ void IRFrontend::Comp_RType2(MIPSOpcode op) { } void IRFrontend::Comp_RType3(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(ALU); MIPSGPReg rt = _RT; MIPSGPReg rs = _RS; @@ -197,7 +197,7 @@ void IRFrontend::CompShiftVar(MIPSOpcode op, IROp shiftOp) { } void IRFrontend::Comp_ShiftType(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(ALU); MIPSGPReg rs = _RS; MIPSGPReg rd = _RD; int sa = _SA; @@ -222,7 +222,7 @@ void IRFrontend::Comp_ShiftType(MIPSOpcode op) { } void IRFrontend::Comp_Special3(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(ALU_BIT); MIPSGPReg rs = _RS; MIPSGPReg rt = _RT; @@ -265,7 +265,7 @@ void IRFrontend::Comp_Special3(MIPSOpcode op) { void IRFrontend::Comp_Allegrex(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(ALU_BIT); MIPSGPReg rt = _RT; MIPSGPReg rd = _RD; @@ -293,7 +293,7 @@ void IRFrontend::Comp_Allegrex(MIPSOpcode op) { } void IRFrontend::Comp_Allegrex2(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(ALU_BIT); MIPSGPReg rt = _RT; MIPSGPReg rd = _RD; @@ -315,7 +315,7 @@ void IRFrontend::Comp_Allegrex2(MIPSOpcode op) { } void IRFrontend::Comp_MulDivType(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(MULDIV); MIPSGPReg rt = _RT; MIPSGPReg rs = _RS; MIPSGPReg rd = _RD; diff --git a/Core/MIPS/IR/IRCompFPU.cpp b/Core/MIPS/IR/IRCompFPU.cpp index ce01c7ff75..0392fb2795 100644 --- a/Core/MIPS/IR/IRCompFPU.cpp +++ b/Core/MIPS/IR/IRCompFPU.cpp @@ -49,14 +49,14 @@ // Currently known non working ones should have DISABLE. // #define CONDITIONAL_DISABLE { Comp_Generic(op); return; } -#define CONDITIONAL_DISABLE ; +#define CONDITIONAL_DISABLE(flag) if (opts.disableFlags & (uint32_t)JitDisable::flag) { Comp_Generic(op); return; } #define DISABLE { Comp_Generic(op); return; } #define INVALIDOP { Comp_Generic(op); return; } namespace MIPSComp { void IRFrontend::Comp_FPU3op(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(FPU); int ft = _FT; int fs = _FS; @@ -74,7 +74,7 @@ void IRFrontend::Comp_FPU3op(MIPSOpcode op) { } void IRFrontend::Comp_FPULS(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(LSU_FPU); s32 offset = _IMM16; int ft = _FT; MIPSGPReg rs = _RS; @@ -97,7 +97,7 @@ void IRFrontend::Comp_FPULS(MIPSOpcode op) { } void IRFrontend::Comp_FPUComp(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(FPU_COMP); int opc = op & 0xF; if (opc >= 8) opc -= 8; // alias @@ -139,7 +139,7 @@ void IRFrontend::Comp_FPUComp(MIPSOpcode op) { } void IRFrontend::Comp_FPU2op(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(FPU); int fs = _FS; int fd = _FD; @@ -185,7 +185,7 @@ void IRFrontend::Comp_FPU2op(MIPSOpcode op) { } void IRFrontend::Comp_mxc1(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(FPU_XFER); int fs = _FS; MIPSGPReg rt = _RT; diff --git a/Core/MIPS/IR/IRCompLoadStore.cpp b/Core/MIPS/IR/IRCompLoadStore.cpp index 4ef50d5e0b..a8ed9d8166 100644 --- a/Core/MIPS/IR/IRCompLoadStore.cpp +++ b/Core/MIPS/IR/IRCompLoadStore.cpp @@ -39,13 +39,13 @@ // Currently known non working ones should have DISABLE. // #define CONDITIONAL_DISABLE { Comp_Generic(op); return; } -#define CONDITIONAL_DISABLE ; +#define CONDITIONAL_DISABLE(flag) if (opts.disableFlags & (uint32_t)JitDisable::flag) { Comp_Generic(op); return; } #define DISABLE { Comp_Generic(op); return; } #define INVALIDOP { Comp_Generic(op); return; } namespace MIPSComp { void IRFrontend::Comp_ITypeMem(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(LSU); int offset = _IMM16; MIPSGPReg rt = _RT; @@ -106,7 +106,7 @@ namespace MIPSComp { } void IRFrontend::Comp_Cache(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(LSU); // int imm = (s16)(op & 0xFFFF); // int rs = _RS; diff --git a/Core/MIPS/IR/IRCompVFPU.cpp b/Core/MIPS/IR/IRCompVFPU.cpp index 63fe98b033..0b61953b3c 100644 --- a/Core/MIPS/IR/IRCompVFPU.cpp +++ b/Core/MIPS/IR/IRCompVFPU.cpp @@ -35,7 +35,7 @@ // Currently known non working ones should have DISABLE. // #define CONDITIONAL_DISABLE { Comp_Generic(op); return; } -#define CONDITIONAL_DISABLE ; +#define CONDITIONAL_DISABLE(flag) if (opts.disableFlags & (uint32_t)JitDisable::flag) { Comp_Generic(op); return; } #define DISABLE { Comp_Generic(op); return; } #define INVALIDOP { Comp_Generic(op); return; } @@ -109,7 +109,7 @@ namespace MIPSComp { } void IRFrontend::Comp_VPFX(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_XFER); int data = op & 0xFFFFF; int regnum = (op >> 24) & 3; switch (regnum) { @@ -274,7 +274,7 @@ namespace MIPSComp { } void IRFrontend::Comp_SV(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(LSU_VFPU); s32 offset = (signed short)(op & 0xFFFC); int vt = ((op >> 16) & 0x1f) | ((op & 3) << 5); MIPSGPReg rs = _RS; @@ -296,7 +296,7 @@ namespace MIPSComp { } void IRFrontend::Comp_SVQ(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(LSU_VFPU); int imm = (signed short)(op & 0xFFFC); int vt = (((op >> 16) & 0x1f)) | ((op & 1) << 5); MIPSGPReg rs = _RS; @@ -342,7 +342,7 @@ namespace MIPSComp { } void IRFrontend::Comp_VVectorInit(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_XFER); if (js.HasUnknownPrefix()) { DISABLE; } @@ -368,7 +368,7 @@ namespace MIPSComp { } void IRFrontend::Comp_VIdt(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_XFER); if (js.HasUnknownPrefix()) { DISABLE; } @@ -406,7 +406,7 @@ namespace MIPSComp { } void IRFrontend::Comp_VMatrixInit(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_XFER); MatrixSize sz = GetMtxSize(op); if (sz != M_4x4) { DISABLE; @@ -447,7 +447,7 @@ namespace MIPSComp { } void IRFrontend::Comp_VHdp(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_VEC); if (js.HasUnknownPrefix()) { DISABLE; } @@ -487,7 +487,7 @@ namespace MIPSComp { alignas(16) static const float vavg_table[4] = { 1.0f, 1.0f / 2.0f, 1.0f / 3.0f, 1.0f / 4.0f }; void IRFrontend::Comp_Vhoriz(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_VEC); if (js.HasUnknownPrefix()) DISABLE; @@ -524,7 +524,7 @@ namespace MIPSComp { } void IRFrontend::Comp_VDot(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_VEC); if (js.HasUnknownPrefix()) { DISABLE; } @@ -562,7 +562,7 @@ namespace MIPSComp { } void IRFrontend::Comp_VecDo3(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_VEC); if (js.HasUnknownPrefix()) DISABLE; @@ -721,7 +721,7 @@ namespace MIPSComp { } void IRFrontend::Comp_VV2Op(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_VEC); if (js.HasUnknownPrefix()) DISABLE; @@ -847,7 +847,7 @@ namespace MIPSComp { } void IRFrontend::Comp_Vi2f(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_VEC); if (js.HasUnknownPrefix()) { DISABLE; } @@ -894,7 +894,7 @@ namespace MIPSComp { } void IRFrontend::Comp_Vh2f(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_VEC); // Vector expand half to float // d[N*2] = float(lowerhalf(s[N])), d[N*2+1] = float(upperhalf(s[N])) @@ -903,7 +903,7 @@ namespace MIPSComp { } void IRFrontend::Comp_Vf2i(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_VEC); // Vector float to integer // d[N] = int(S[N] * mult) @@ -913,7 +913,7 @@ namespace MIPSComp { } void IRFrontend::Comp_Mftv(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_XFER); int imm = op & 0xFF; MIPSGPReg rt = _RT; @@ -966,7 +966,7 @@ namespace MIPSComp { } void IRFrontend::Comp_Vmfvc(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_XFER); // Vector Move from vector control reg (no prefixes) // S[0] = VFPU_CTRL[i] @@ -982,7 +982,7 @@ namespace MIPSComp { } void IRFrontend::Comp_Vmtvc(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_XFER); // Vector Move to vector control reg (no prefixes) // VFPU_CTRL[i] = S[0] @@ -1004,7 +1004,7 @@ namespace MIPSComp { } void IRFrontend::Comp_Vmmov(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_MTX); // Matrix move (no prefixes) // D[N,M] = S[N,M] @@ -1061,7 +1061,7 @@ namespace MIPSComp { } void IRFrontend::Comp_Vmscl(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_MTX); // Matrix scale, matrix by scalar (no prefixes) // d[N,M] = s[N,M] * t[0] @@ -1099,7 +1099,7 @@ namespace MIPSComp { } void IRFrontend::Comp_VScl(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_VEC); if (js.HasUnknownPrefix()) { DISABLE; } @@ -1173,7 +1173,7 @@ namespace MIPSComp { // This may or may not be a win when using the IR interpreter... // Many more instructions to interpret. void IRFrontend::Comp_Vmmul(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_MTX); // Matrix multiply (no prefixes) // D[0 .. N,0 .. M] = S[0 .. N, 0 .. M] * T[0 .. N,0 .. M] @@ -1256,7 +1256,7 @@ namespace MIPSComp { } void IRFrontend::Comp_Vtfm(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_MTX); // Vertex transform, vector by matrix (no prefixes) // d[N] = s[N*m .. N*m + n-1] dot t[0 .. n-1] @@ -1358,7 +1358,7 @@ namespace MIPSComp { } void IRFrontend::Comp_VCrs(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_VEC); if (js.HasUnknownPrefix()) { DISABLE; } @@ -1372,7 +1372,7 @@ namespace MIPSComp { } void IRFrontend::Comp_VDet(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_VEC); if (js.HasUnknownPrefix()) { DISABLE; } @@ -1385,7 +1385,7 @@ namespace MIPSComp { } void IRFrontend::Comp_Vi2x(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_VEC); if (js.HasUnknownPrefix()) DISABLE; @@ -1470,7 +1470,7 @@ namespace MIPSComp { } void IRFrontend::Comp_Vx2i(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_VEC); if (js.HasUnknownPrefix()) DISABLE; @@ -1570,7 +1570,7 @@ namespace MIPSComp { } void IRFrontend::Comp_VCrossQuat(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_VEC); // TODO: Does this instruction even look at prefixes at all? if (js.HasUnknownPrefix()) DISABLE; @@ -1627,7 +1627,7 @@ namespace MIPSComp { } void IRFrontend::Comp_Vcmp(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_COMP); if (js.HasUnknownPrefix()) DISABLE; @@ -1651,7 +1651,7 @@ namespace MIPSComp { } void IRFrontend::Comp_Vcmov(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_COMP); if (js.HasUnknownPrefix()) { DISABLE; } @@ -1690,7 +1690,7 @@ namespace MIPSComp { } void IRFrontend::Comp_Viim(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_XFER); if (js.HasUnknownPrefix()) DISABLE; @@ -1705,7 +1705,7 @@ namespace MIPSComp { } void IRFrontend::Comp_Vfim(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_XFER); if (js.HasUnknownPrefix()) DISABLE; @@ -1723,7 +1723,7 @@ namespace MIPSComp { } void IRFrontend::Comp_Vcst(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_XFER); if (js.HasUnknownPrefix()) DISABLE; @@ -1747,7 +1747,7 @@ namespace MIPSComp { // Very heavily used by FF:CC. Should be replaced by a fast approximation instead of // calling the math library. void IRFrontend::Comp_VRot(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_VEC); if (!js.HasNoPrefix()) { // Prefixes work strangely for this: // * They never apply to cos (whether d or s prefixes.) @@ -1797,7 +1797,7 @@ namespace MIPSComp { } void IRFrontend::Comp_Vsgn(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_VEC); if (js.HasUnknownPrefix()) { DISABLE; } @@ -1835,7 +1835,7 @@ namespace MIPSComp { } void IRFrontend::Comp_Vocp(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_VEC); if (js.HasUnknownPrefix()) { DISABLE; } @@ -1872,7 +1872,7 @@ namespace MIPSComp { } void IRFrontend::Comp_ColorConv(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_VEC); if (js.HasUnknownPrefix()) DISABLE; @@ -1883,7 +1883,7 @@ namespace MIPSComp { } void IRFrontend::Comp_Vbfy(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_VEC); if (js.HasUnknownPrefix()) DISABLE; diff --git a/Core/MIPS/IR/IRInst.h b/Core/MIPS/IR/IRInst.h index cccc1ba55b..a5ec8a8434 100644 --- a/Core/MIPS/IR/IRInst.h +++ b/Core/MIPS/IR/IRInst.h @@ -369,6 +369,7 @@ private: }; struct IROptions { + uint32_t disableFlags; bool unalignedLoadStore; }; diff --git a/Core/MIPS/IR/IRJit.cpp b/Core/MIPS/IR/IRJit.cpp index 63114371e4..ec9a2fdabb 100644 --- a/Core/MIPS/IR/IRJit.cpp +++ b/Core/MIPS/IR/IRJit.cpp @@ -44,7 +44,8 @@ IRJit::IRJit(MIPSState *mips) : frontend_(mips->HasDefaultPrefix()), mips_(mips) InitIR(); IROptions opts{}; - opts.unalignedLoadStore = true; + opts.disableFlags = g_Config.uJitDisableFlags; + opts.unalignedLoadStore = opts.disableFlags & (uint32_t)JitDisable::LSU_UNALIGNED; frontend_.SetOptions(opts); } diff --git a/Core/MIPS/JitCommon/JitState.cpp b/Core/MIPS/JitCommon/JitState.cpp index 7a603daf50..895589cadf 100644 --- a/Core/MIPS/JitCommon/JitState.cpp +++ b/Core/MIPS/JitCommon/JitState.cpp @@ -16,35 +16,38 @@ // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. #include "Common/CPUDetect.h" +#include "Core/Config.h" #include "Core/MIPS/JitCommon/JitState.h" #include "Common/MemoryUtil.h" namespace MIPSComp { JitOptions::JitOptions() { + disableFlags = g_Config.uJitDisableFlags; + // x86 - enableVFPUSIMD = true; + enableVFPUSIMD = !Disabled(JitDisable::SIMD); // Set by Asm if needed. reserveR15ForAsm = false; // ARM/ARM64 useBackJump = false; useForwardJump = false; - cachePointers = true; + cachePointers = !Disabled(JitDisable::CACHE_POINTERS); // ARM only downcountInRegister = true; useNEONVFPU = false; // true - if (!cpu_info.bNEON) + if (!cpu_info.bNEON || Disabled(JitDisable::SIMD)) useNEONVFPU = false; //ARM64 - useASIMDVFPU = false; // true + useASIMDVFPU = false; // !Disabled(JitDisable::SIMD); // Common // We can get block linking to work with W^X by doing even more unprotect/re-protect, but let's try without first. // enableBlocklink = !PlatformIsWXExclusive(); // Revert to this line if block linking is slow in W^X mode - enableBlocklink = true; + enableBlocklink = !Disabled(JitDisable::BLOCKLINK); immBranches = false; continueBranches = false; continueJumps = false; @@ -53,9 +56,13 @@ namespace MIPSComp { useStaticAlloc = false; enablePointerify = false; #if PPSSPP_ARCH(ARM64) - useStaticAlloc = true; + useStaticAlloc = !Disabled(JitDisable::STATIC_ALLOC); // iOS/etc. may disable at runtime if Memory::base is not nicely aligned. - enablePointerify = true; + enablePointerify = !Disabled(JitDisable::POINTERIFY); #endif } + + bool JitOptions::Disabled(JitDisable bit) { + return (disableFlags & (uint32_t)bit) != 0; + } } diff --git a/Core/MIPS/JitCommon/JitState.h b/Core/MIPS/JitCommon/JitState.h index 6d2c8d0937..ac16bcf7da 100644 --- a/Core/MIPS/JitCommon/JitState.h +++ b/Core/MIPS/JitCommon/JitState.h @@ -173,9 +173,42 @@ namespace MIPSComp { } }; + enum class JitDisable { + ALU = 0x0001, + ALU_IMM = 0x0002, + ALU_BIT = 0x0004, + MULDIV = 0x0008, + + FPU = 0x0010, + FPU_COMP = 0x0040, + FPU_XFER = 0x0080, + + VFPU_VEC = 0x0100, + VFPU_MTX = 0x0200, + VFPU_COMP = 0x0400, + VFPU_XFER = 0x0800, + + LSU = 0x1000, + LSU_UNALIGNED = 0x2000, + LSU_FPU = 0x4000, + LSU_VFPU = 0x8000, + + SIMD = 0x00100000, + BLOCKLINK = 0x00200000, + POINTERIFY = 0x00400000, + STATIC_ALLOC = 0x00800000, + CACHE_POINTERS = 0x01000000, + + ALL_FLAGS = 0x01FFFFFF, + }; + struct JitOptions { JitOptions(); + bool Disabled(JitDisable bit); + + uint32_t disableFlags; + // x86 bool enableVFPUSIMD; bool reserveR15ForAsm; diff --git a/Core/MIPS/MIPSAnalyst.cpp b/Core/MIPS/MIPSAnalyst.cpp index 43e5019a66..7a3459f808 100644 --- a/Core/MIPS/MIPSAnalyst.cpp +++ b/Core/MIPS/MIPSAnalyst.cpp @@ -1531,7 +1531,7 @@ skip: } // lw, sh, ... - if ((opInfo & IN_MEM) || (opInfo & OUT_MEM)) { + if (!IsSyscall(op) && (opInfo & (IN_MEM | OUT_MEM)) != 0) { info.isDataAccess = true; switch (opInfo & MEMTYPE_MASK) { case MEMTYPE_BYTE: diff --git a/Core/MIPS/x86/CompALU.cpp b/Core/MIPS/x86/CompALU.cpp index 6019d82d73..456695b575 100644 --- a/Core/MIPS/x86/CompALU.cpp +++ b/Core/MIPS/x86/CompALU.cpp @@ -40,8 +40,8 @@ using namespace MIPSAnalyst; // All functions should have CONDITIONAL_DISABLE, so we can narrow things down to a file quickly. // Currently known non working ones should have DISABLE. -// #define CONDITIONAL_DISABLE { Comp_Generic(op); return; } -#define CONDITIONAL_DISABLE ; +// #define CONDITIONAL_DISABLE(ignore) { Comp_Generic(op); return; } +#define CONDITIONAL_DISABLE(flag) if (jo.Disabled(JitDisable::flag)) { Comp_Generic(op); return; } #define DISABLE { Comp_Generic(op); return; } namespace MIPSComp @@ -74,7 +74,7 @@ namespace MIPSComp void Jit::Comp_IType(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(ALU_IMM); s32 simm = (s32)_IMM16; // sign extension u32 uimm = op & 0xFFFF; u32 suimm = (u32)(s32)simm; @@ -197,7 +197,7 @@ namespace MIPSComp void Jit::Comp_RType2(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(ALU_BIT); MIPSGPReg rs = _RS; MIPSGPReg rd = _RD; @@ -378,7 +378,7 @@ namespace MIPSComp void Jit::Comp_RType3(MIPSOpcode op) { - CONDITIONAL_DISABLE + CONDITIONAL_DISABLE(ALU); MIPSGPReg rt = _RT; MIPSGPReg rs = _RS; @@ -668,7 +668,7 @@ namespace MIPSComp void Jit::Comp_ShiftType(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(ALU); int rs = (op>>21) & 0x1F; MIPSGPReg rd = _RD; int fd = (op>>6) & 0x1F; @@ -696,7 +696,7 @@ namespace MIPSComp void Jit::Comp_Special3(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(ALU_BIT); MIPSGPReg rs = _RS; MIPSGPReg rt = _RT; @@ -786,7 +786,7 @@ namespace MIPSComp void Jit::Comp_Allegrex(MIPSOpcode op) { - CONDITIONAL_DISABLE + CONDITIONAL_DISABLE(ALU_BIT); MIPSGPReg rt = _RT; MIPSGPReg rd = _RD; // Don't change $zr. @@ -894,7 +894,7 @@ namespace MIPSComp void Jit::Comp_Allegrex2(MIPSOpcode op) { - CONDITIONAL_DISABLE + CONDITIONAL_DISABLE(ALU_BIT); MIPSGPReg rt = _RT; MIPSGPReg rd = _RD; // Don't change $zr. @@ -938,7 +938,7 @@ namespace MIPSComp void Jit::Comp_MulDivType(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(MULDIV); MIPSGPReg rt = _RT; MIPSGPReg rs = _RS; MIPSGPReg rd = _RD; diff --git a/Core/MIPS/x86/CompFPU.cpp b/Core/MIPS/x86/CompFPU.cpp index 664490966e..1220f2a382 100644 --- a/Core/MIPS/x86/CompFPU.cpp +++ b/Core/MIPS/x86/CompFPU.cpp @@ -42,7 +42,7 @@ // Currently known non working ones should have DISABLE. // #define CONDITIONAL_DISABLE { Comp_Generic(op); return; } -#define CONDITIONAL_DISABLE ; +#define CONDITIONAL_DISABLE(flag) if (jo.Disabled(JitDisable::flag)) { Comp_Generic(op); return; } #define DISABLE { Comp_Generic(op); return; } namespace MIPSComp { @@ -86,7 +86,7 @@ void Jit::CompFPTriArith(MIPSOpcode op, void (XEmitter::*arith)(X64Reg reg, OpAr } void Jit::Comp_FPU3op(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(FPU); switch (op & 0x3f) { case 0: CompFPTriArith(op, &XEmitter::ADDSS, false); break; //F(fd) = F(fs) + F(ft); //add case 1: CompFPTriArith(op, &XEmitter::SUBSS, true); break; //F(fd) = F(fs) - F(ft); //sub @@ -99,7 +99,7 @@ void Jit::Comp_FPU3op(MIPSOpcode op) { } void Jit::Comp_FPULS(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(LSU_FPU); s32 offset = _IMM16; int ft = _FT; MIPSGPReg rs = _RS; @@ -174,7 +174,7 @@ void Jit::CompFPComp(int lhs, int rhs, u8 compare, bool allowNaN) { } void Jit::Comp_FPUComp(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(FPU_COMP); int fs = _FS; int ft = _FT; @@ -226,7 +226,7 @@ void Jit::Comp_FPUComp(MIPSOpcode op) { } void Jit::Comp_FPU2op(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(FPU); int fs = _FS; int fd = _FD; @@ -355,7 +355,7 @@ void Jit::Comp_FPU2op(MIPSOpcode op) { } void Jit::Comp_mxc1(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(FPU_XFER); int fs = _FS; MIPSGPReg rt = _RT; diff --git a/Core/MIPS/x86/CompLoadStore.cpp b/Core/MIPS/x86/CompLoadStore.cpp index 28112c0bfc..5182c7fdc2 100644 --- a/Core/MIPS/x86/CompLoadStore.cpp +++ b/Core/MIPS/x86/CompLoadStore.cpp @@ -42,7 +42,7 @@ // Currently known non working ones should have DISABLE. // #define CONDITIONAL_DISABLE { Comp_Generic(op); return; } -#define CONDITIONAL_DISABLE ; +#define CONDITIONAL_DISABLE(flag) if (jo.Disabled(JitDisable::flag)) { Comp_Generic(op); return; } #define DISABLE { Comp_Generic(op); return; } namespace MIPSComp { @@ -50,7 +50,7 @@ namespace MIPSComp { void Jit::CompITypeMemRead(MIPSOpcode op, u32 bits, void (XEmitter::*mov)(int, int, X64Reg, OpArg), const void *safeFunc) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(LSU); int offset = _IMM16; MIPSGPReg rt = _RT; MIPSGPReg rs = _RS; @@ -81,7 +81,7 @@ namespace MIPSComp { void Jit::CompITypeMemWrite(MIPSOpcode op, u32 bits, const void *safeFunc) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(LSU); int offset = _IMM16; MIPSGPReg rt = _RT; MIPSGPReg rs = _RS; @@ -137,7 +137,7 @@ namespace MIPSComp { void Jit::CompITypeMemUnpairedLR(MIPSOpcode op, bool isStore) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(LSU); int o = op>>26; int offset = _IMM16; MIPSGPReg rt = _RT; @@ -193,7 +193,7 @@ namespace MIPSComp { void Jit::CompITypeMemUnpairedLRInner(MIPSOpcode op, X64Reg shiftReg) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(LSU); int o = op>>26; MIPSGPReg rt = _RT; @@ -285,7 +285,7 @@ namespace MIPSComp { void Jit::Comp_ITypeMem(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(LSU); int offset = _IMM16; MIPSGPReg rt = _RT; MIPSGPReg rs = _RS; @@ -334,7 +334,7 @@ namespace MIPSComp { MIPSOpcode nextOp = GetOffsetInstruction(1); // Looking for lwr rd, offset-3(rs) which makes a pair. u32 desiredOp = ((op & 0xFFFF0000) + (4 << 26)) + (offset - 3); - if (!js.inDelaySlot && nextOp == desiredOp) + if (!js.inDelaySlot && nextOp == desiredOp && !jo.Disabled(JitDisable::LSU_UNALIGNED)) { EatInstruction(nextOp); // nextOp has the correct address. @@ -350,7 +350,7 @@ namespace MIPSComp { MIPSOpcode nextOp = GetOffsetInstruction(1); // Looking for lwl rd, offset+3(rs) which makes a pair. u32 desiredOp = ((op & 0xFFFF0000) - (4 << 26)) + (offset + 3); - if (!js.inDelaySlot && nextOp == desiredOp) + if (!js.inDelaySlot && nextOp == desiredOp && !jo.Disabled(JitDisable::LSU_UNALIGNED)) { EatInstruction(nextOp); // op has the correct address. @@ -366,7 +366,7 @@ namespace MIPSComp { MIPSOpcode nextOp = GetOffsetInstruction(1); // Looking for swr rd, offset-3(rs) which makes a pair. u32 desiredOp = ((op & 0xFFFF0000) + (4 << 26)) + (offset - 3); - if (!js.inDelaySlot && nextOp == desiredOp) + if (!js.inDelaySlot && nextOp == desiredOp && !jo.Disabled(JitDisable::LSU_UNALIGNED)) { EatInstruction(nextOp); // nextOp has the correct address. @@ -382,7 +382,7 @@ namespace MIPSComp { MIPSOpcode nextOp = GetOffsetInstruction(1); // Looking for swl rd, offset+3(rs) which makes a pair. u32 desiredOp = ((op & 0xFFFF0000) - (4 << 26)) + (offset + 3); - if (!js.inDelaySlot && nextOp == desiredOp) + if (!js.inDelaySlot && nextOp == desiredOp && !jo.Disabled(JitDisable::LSU_UNALIGNED)) { EatInstruction(nextOp); // op has the correct address. diff --git a/Core/MIPS/x86/CompVFPU.cpp b/Core/MIPS/x86/CompVFPU.cpp index 62076afe6a..d74a1f8e3a 100644 --- a/Core/MIPS/x86/CompVFPU.cpp +++ b/Core/MIPS/x86/CompVFPU.cpp @@ -42,7 +42,7 @@ // Currently known non working ones should have DISABLE. // #define CONDITIONAL_DISABLE { fpr.ReleaseSpillLocks(); Comp_Generic(op); return; } -#define CONDITIONAL_DISABLE ; +#define CONDITIONAL_DISABLE(flag) if (jo.Disabled(JitDisable::flag)) { Comp_Generic(op); return; } #define DISABLE { fpr.ReleaseSpillLocks(); Comp_Generic(op); return; } #define _RS MIPS_GET_RS(op) @@ -74,7 +74,7 @@ alignas(16) const float identityMatrix[4][4] = { { 1.0f, 0, 0, 0 }, { 0, 1.0f, 0 void Jit::Comp_VPFX(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_XFER); int data = op & 0xFFFFF; int regnum = (op >> 24) & 3; switch (regnum) { @@ -239,7 +239,7 @@ bool IsOverlapSafe(int dreg, int di, int sn, u8 sregs[], int tn = 0, u8 tregs[] alignas(16) static u32 ssLoadStoreTemp; void Jit::Comp_SV(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(LSU_VFPU); s32 imm = (signed short)(op&0xFFFC); int vt = ((op >> 16) & 0x1f) | ((op & 3) << 5); @@ -294,7 +294,7 @@ void Jit::Comp_SV(MIPSOpcode op) { } void Jit::Comp_SVQ(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(LSU_VFPU); int imm = (signed short)(op&0xFFFC); int vt = (((op >> 16) & 0x1f)) | ((op&1) << 5); @@ -502,7 +502,7 @@ void Jit::Comp_SVQ(MIPSOpcode op) { } void Jit::Comp_VVectorInit(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_XFER); if (js.HasUnknownPrefix()) DISABLE; @@ -557,7 +557,7 @@ void Jit::Comp_VVectorInit(MIPSOpcode op) { } void Jit::Comp_VIdt(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_XFER); if (js.HasUnknownPrefix()) DISABLE; @@ -608,7 +608,7 @@ void Jit::Comp_VIdt(MIPSOpcode op) { } void Jit::Comp_VDot(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_VEC); if (js.HasUnknownPrefix()) DISABLE; @@ -739,7 +739,7 @@ void Jit::Comp_VDot(MIPSOpcode op) { void Jit::Comp_VHdp(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_VEC); if (js.HasUnknownPrefix()) DISABLE; @@ -788,7 +788,7 @@ void Jit::Comp_VHdp(MIPSOpcode op) { } void Jit::Comp_VCrossQuat(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_VEC); if (js.HasUnknownPrefix()) DISABLE; @@ -921,7 +921,7 @@ void Jit::Comp_VCrossQuat(MIPSOpcode op) { } void Jit::Comp_Vcmov(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_COMP); if (js.HasUnknownPrefix()) DISABLE; @@ -997,7 +997,7 @@ static s32 DoVmaxSS(s32 treg) { } void Jit::Comp_VecDo3(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_VEC); if (js.HasUnknownPrefix()) DISABLE; @@ -1269,7 +1269,7 @@ alignas(16) static const u32 vcmpMask[4][4] = { }; void Jit::Comp_Vcmp(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_COMP); if (js.HasUnknownPrefix()) DISABLE; @@ -1512,7 +1512,7 @@ extern const float mulTableVi2f[32] = { }; void Jit::Comp_Vi2f(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_VEC); if (js.HasUnknownPrefix()) DISABLE; @@ -1599,7 +1599,7 @@ void Jit::Comp_Vi2f(MIPSOpcode op) { // Translation of ryg's half_to_float5_SSE2 void Jit::Comp_Vh2f(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_VEC); if (js.HasUnknownPrefix()) DISABLE; @@ -1688,7 +1688,7 @@ alignas(16) static s8 vc2i_shuffle[16] = { -1, -1, -1, 0, -1, -1, -1, 1, -1, - alignas(16) static s8 vuc2i_shuffle[16] = { 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3 }; void Jit::Comp_Vx2i(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_VEC); if (js.HasUnknownPrefix()) DISABLE; @@ -1811,7 +1811,7 @@ static const float half = 0.5f; static const double maxMinIntAsDouble[2] = { (double)0x7fffffff, (double)(int)0x80000000 }; // that's not equal to 0x80000000 void Jit::Comp_Vf2i(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_VEC); if (js.HasUnknownPrefix()) DISABLE; @@ -1920,7 +1920,7 @@ void Jit::Comp_Vf2i(MIPSOpcode op) { } void Jit::Comp_Vcst(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_XFER); if (js.HasUnknownPrefix()) DISABLE; @@ -1957,7 +1957,7 @@ void Jit::Comp_Vcst(MIPSOpcode op) { } void Jit::Comp_Vsgn(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_VEC); if (js.HasUnknownPrefix()) DISABLE; @@ -2018,7 +2018,7 @@ void Jit::Comp_Vsgn(MIPSOpcode op) { } void Jit::Comp_Vocp(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_VEC); if (js.HasUnknownPrefix()) DISABLE; @@ -2067,7 +2067,7 @@ void Jit::Comp_Vocp(MIPSOpcode op) { } void Jit::Comp_Vbfy(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_VEC); if (js.HasUnknownPrefix()) DISABLE; @@ -2181,7 +2181,7 @@ void SinCosNegSin(SinCosArg angle, float *output) { } void Jit::Comp_VV2Op(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_VEC); if (js.HasUnknownPrefix()) DISABLE; @@ -2419,7 +2419,7 @@ void Jit::Comp_VV2Op(MIPSOpcode op) { } void Jit::Comp_Mftv(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_XFER); int imm = op & 0xFF; MIPSGPReg rt = _RT; @@ -2509,7 +2509,7 @@ void Jit::Comp_Mftv(MIPSOpcode op) { } void Jit::Comp_Vmfvc(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_XFER); int vs = _VS; int imm = op & 0xFF; if (imm >= 128 && imm < 128 + VFPU_CTRL_MAX) { @@ -2525,7 +2525,7 @@ void Jit::Comp_Vmfvc(MIPSOpcode op) { } void Jit::Comp_Vmtvc(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_XFER); int vs = _VS; int imm = op & 0xFF; if (imm >= 128 && imm < 128 + VFPU_CTRL_MAX) { @@ -2549,7 +2549,7 @@ void Jit::Comp_Vmtvc(MIPSOpcode op) { } void Jit::Comp_VMatrixInit(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_XFER); if (js.HasUnknownPrefix()) DISABLE; @@ -2632,7 +2632,7 @@ void Jit::Comp_VMatrixInit(MIPSOpcode op) { } void Jit::Comp_Vmmov(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_MTX); // TODO: This probably ignores prefixes? if (js.HasUnknownPrefix()) @@ -2718,7 +2718,7 @@ void Jit::Comp_Vmmov(MIPSOpcode op) { } void Jit::Comp_VScl(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_VEC); if (js.HasUnknownPrefix()) DISABLE; @@ -2780,7 +2780,7 @@ void Jit::Comp_VScl(MIPSOpcode op) { } void Jit::Comp_Vmmul(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_MTX); // TODO: This probably ignores prefixes? if (js.HasUnknownPrefix()) @@ -2974,7 +2974,7 @@ void Jit::Comp_Vmmul(MIPSOpcode op) { } void Jit::Comp_Vmscl(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_MTX); // TODO: This op probably ignores prefixes? if (js.HasUnknownPrefix()) @@ -3020,7 +3020,7 @@ void Jit::Comp_Vmscl(MIPSOpcode op) { } void Jit::Comp_Vtfm(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_MTX); // TODO: This probably ignores prefixes? Or maybe uses D? if (js.HasUnknownPrefix()) @@ -3163,7 +3163,7 @@ alignas(16) static const s8 vi2xc_shuffle[16] = { 3, 7, 11, 15, -1, -1, -1, -1, alignas(16) static const s8 vi2xs_shuffle[16] = { 2, 3, 6, 7, 10, 11, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1 }; void Jit::Comp_Vi2x(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_VEC); if (js.HasUnknownPrefix()) DISABLE; @@ -3295,7 +3295,7 @@ void Jit::Comp_Vi2x(MIPSOpcode op) { alignas(16) static const float vavg_table[4] = { 1.0f, 1.0f / 2.0f, 1.0f / 3.0f, 1.0f / 4.0f }; void Jit::Comp_Vhoriz(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_VEC); if (js.HasUnknownPrefix()) DISABLE; @@ -3412,7 +3412,7 @@ void Jit::Comp_Vhoriz(MIPSOpcode op) { } void Jit::Comp_Viim(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_XFER); if (js.HasUnknownPrefix()) DISABLE; @@ -3435,7 +3435,7 @@ void Jit::Comp_Viim(MIPSOpcode op) { } void Jit::Comp_Vfim(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_XFER); if (js.HasUnknownPrefix()) DISABLE; @@ -3497,7 +3497,7 @@ void Jit::CompVrotShuffle(u8 *dregs, int imm, int n, bool negSin) { // Very heavily used by FF:CC void Jit::Comp_VRot(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_VEC); if (js.HasUnknownPrefix()) { DISABLE; } @@ -3569,7 +3569,7 @@ void Jit::Comp_VRot(MIPSOpcode op) { } void Jit::Comp_ColorConv(MIPSOpcode op) { - CONDITIONAL_DISABLE; + CONDITIONAL_DISABLE(VFPU_VEC); if (js.HasUnknownPrefix()) DISABLE; diff --git a/Core/Reporting.cpp b/Core/Reporting.cpp index a927c55510..6393a80f4a 100644 --- a/Core/Reporting.cpp +++ b/Core/Reporting.cpp @@ -458,12 +458,12 @@ namespace Reporting bool IsSupported() { // Disabled when using certain hacks, because they make for poor reports. - if (g_Config.bTimerHack) - return false; if (CheatsInEffect()) return false; if (g_Config.iLockedCPUSpeed != 0) return false; + if (g_Config.uJitDisableFlags != 0) + return false; // Don't allow builds without version info from git. They're useless for reporting. if (strcmp(PPSSPP_GIT_VERSION, "unknown") == 0) return false; diff --git a/Core/SaveState.cpp b/Core/SaveState.cpp index 5613cc9258..9f7f3f0913 100644 --- a/Core/SaveState.cpp +++ b/Core/SaveState.cpp @@ -241,6 +241,7 @@ namespace SaveState static bool needsProcess = false; static std::vector pending; static std::mutex mutex; + static int screenshotFailures = 0; static bool hasLoadedState = false; static const int STALE_STATE_USES = 2; // 4 hours of total gameplay since the virtual PSP started the game. @@ -250,6 +251,7 @@ namespace SaveState // TODO: Should this be configurable? static const int REWIND_NUM_STATES = 20; + static const int SCREENSHOT_FAILURE_RETRIES = 15; static StateRingbuffer rewindStates(REWIND_NUM_STATES); // TODO: Any reason for this to be configurable? const static float rewindMaxWallFrequency = 1.0f; @@ -857,6 +859,12 @@ namespace SaveState callbackResult = tempResult ? Status::SUCCESS : Status::FAILURE; if (!tempResult) { ERROR_LOG(SAVESTATE, "Failed to take a screenshot for the savestate! %s", op.filename.c_str()); + if (screenshotFailures++ < SCREENSHOT_FAILURE_RETRIES) { + // Requeue for next frame. + SaveScreenshot(op.filename, op.callback, op.cbUserData); + } + } else { + screenshotFailures = 0; } break; } diff --git a/GPU/Common/DepalettizeShaderCommon.cpp b/GPU/Common/DepalettizeShaderCommon.cpp index e691f25459..09615ed8b8 100644 --- a/GPU/Common/DepalettizeShaderCommon.cpp +++ b/GPU/Common/DepalettizeShaderCommon.cpp @@ -51,7 +51,7 @@ void GenerateDepalShader300(char *buffer, GEBufferFormat pixelFormat, ShaderLang WRITE(p, "precision mediump float;\n"); WRITE(p, "precision highp int;\n"); } else { - WRITE(p, "#version 330\n"); + WRITE(p, "#version %d\n", gl_extensions.GLSLVersion()); } WRITE(p, "in vec2 v_texcoord0;\n"); WRITE(p, "out vec4 fragColor0;\n"); @@ -252,7 +252,7 @@ void GenerateDepalShaderFloat(char *buffer, GEBufferFormat pixelFormat, ShaderLa WRITE(p, "#version 100\n"); WRITE(p, "precision mediump float;\n"); } else { - WRITE(p, "#version 110\n"); + WRITE(p, "#version %d\n", gl_extensions.GLSLVersion()); } WRITE(p, "varying vec2 v_texcoord0;\n"); WRITE(p, "uniform sampler2D tex;\n"); diff --git a/GPU/Common/DrawEngineCommon.cpp b/GPU/Common/DrawEngineCommon.cpp index 60c250533a..1540ab5bb2 100644 --- a/GPU/Common/DrawEngineCommon.cpp +++ b/GPU/Common/DrawEngineCommon.cpp @@ -521,7 +521,7 @@ void DrawEngineCommon::DecodeVertsStep(u8 *dest, int &i, int &decodedVerts) { decodedVerts += indexUpperBound - indexLowerBound + 1; bool clockwise = true; - if (dc.cullMode != -1 && gstate.isCullEnabled() && gstate.getCullMode() != dc.cullMode) { + if (gstate.isCullEnabled() && gstate.getCullMode() != dc.cullMode) { clockwise = false; } indexGen.AddPrim(dc.prim, dc.vertexCount, clockwise); @@ -549,7 +549,7 @@ void DrawEngineCommon::DecodeVertsStep(u8 *dest, int &i, int &decodedVerts) { case GE_VTYPE_IDX_8BIT >> GE_VTYPE_IDX_SHIFT: for (int j = i; j <= lastMatch; j++) { bool clockwise = true; - if (drawCalls[j].cullMode != -1 && gstate.isCullEnabled() && gstate.getCullMode() != drawCalls[j].cullMode) { + if (gstate.isCullEnabled() && gstate.getCullMode() != drawCalls[j].cullMode) { clockwise = false; } indexGen.TranslatePrim(drawCalls[j].prim, drawCalls[j].vertexCount, (const u8 *)drawCalls[j].inds, indexLowerBound, clockwise); @@ -558,7 +558,7 @@ void DrawEngineCommon::DecodeVertsStep(u8 *dest, int &i, int &decodedVerts) { case GE_VTYPE_IDX_16BIT >> GE_VTYPE_IDX_SHIFT: for (int j = i; j <= lastMatch; j++) { bool clockwise = true; - if (drawCalls[j].cullMode != -1 && gstate.isCullEnabled() && gstate.getCullMode() != drawCalls[j].cullMode) { + if (gstate.isCullEnabled() && gstate.getCullMode() != drawCalls[j].cullMode) { clockwise = false; } indexGen.TranslatePrim(drawCalls[j].prim, drawCalls[j].vertexCount, (const u16_le *)drawCalls[j].inds, indexLowerBound, clockwise); @@ -567,7 +567,7 @@ void DrawEngineCommon::DecodeVertsStep(u8 *dest, int &i, int &decodedVerts) { case GE_VTYPE_IDX_32BIT >> GE_VTYPE_IDX_SHIFT: for (int j = i; j <= lastMatch; j++) { bool clockwise = true; - if (drawCalls[j].cullMode != -1 && gstate.isCullEnabled() && gstate.getCullMode() != drawCalls[j].cullMode) { + if (gstate.isCullEnabled() && gstate.getCullMode() != drawCalls[j].cullMode) { clockwise = false; } indexGen.TranslatePrim(drawCalls[j].prim, drawCalls[j].vertexCount, (const u32_le *)drawCalls[j].inds, indexLowerBound, clockwise); @@ -731,10 +731,30 @@ void DrawEngineCommon::SubmitPrim(void *verts, void *inds, GEPrimitiveType prim, } if (prim == GE_PRIM_RECTANGLES && (gstate.getTextureAddress(0) & 0x3FFFFFFF) == (gstate.getFrameBufAddress() & 0x3FFFFFFF)) { - // Rendertarget == texture? - if (!g_Config.bDisableSlowFramebufEffects) { - gstate_c.Dirty(DIRTY_TEXTURE_PARAMS); - DispatchFlush(); + // Rendertarget == texture? Shouldn't happen. Still, try some mitigations. + gstate_c.Dirty(DIRTY_TEXTURE_PARAMS); + DispatchFlush(); + } +} + +void TessellationDataTransfer::CopyControlPoints(float *pos, float *tex, float *col, int posStride, int texStride, int colStride, const SimpleVertex *const *points, int size, u32 vertType) { + bool hasColor = (vertType & GE_VTYPE_COL_MASK) != 0; + bool hasTexCoord = (vertType & GE_VTYPE_TC_MASK) != 0; + + for (int i = 0; i < size; ++i) { + memcpy(pos, points[i]->pos.AsArray(), 3 * sizeof(float)); + pos += posStride; + } + if (hasTexCoord) { + for (int i = 0; i < size; ++i) { + memcpy(tex, points[i]->uv, 2 * sizeof(float)); + tex += texStride; + } + } + if (hasColor) { + for (int i = 0; i < size; ++i) { + memcpy(col, Vec4f::FromRGBA(points[i]->color_32).AsArray(), 4 * sizeof(float)); + col += colStride; } } } diff --git a/GPU/Common/DrawEngineCommon.h b/GPU/Common/DrawEngineCommon.h index 353b3dd7d0..ac735f90cf 100644 --- a/GPU/Common/DrawEngineCommon.h +++ b/GPU/Common/DrawEngineCommon.h @@ -54,6 +54,7 @@ namespace Spline { struct Weight2D; } class TessellationDataTransfer { public: + virtual ~TessellationDataTransfer() {} void CopyControlPoints(float *pos, float *tex, float *col, int posStride, int texStride, int colStride, const SimpleVertex *const *points, int size, u32 vertType); virtual void SendDataToShader(const SimpleVertex *const *points, int size_u, int size_v, u32 vertType, const Spline::Weight2D &weights) = 0; }; @@ -74,15 +75,15 @@ public: // This would seem to be unnecessary now, but is still required for splines/beziers to work in the software backend since SubmitPrim // is different. Should probably refactor that. // Note that vertTypeID should be computed using GetVertTypeID(). - virtual void DispatchSubmitPrim(void *verts, void *inds, GEPrimitiveType prim, int vertexCount, u32 vertTypeID, int *bytesRead) { - SubmitPrim(verts, inds, prim, vertexCount, vertTypeID, -1, bytesRead); + virtual void DispatchSubmitPrim(void *verts, void *inds, GEPrimitiveType prim, int vertexCount, u32 vertTypeID, int cullMode, int *bytesRead) { + SubmitPrim(verts, inds, prim, vertexCount, vertTypeID, cullMode, bytesRead); } bool TestBoundingBox(void* control_points, int vertexCount, u32 vertType, int *bytesRead); void SubmitPrim(void *verts, void *inds, GEPrimitiveType prim, int vertexCount, u32 vertTypeID, int cullMode, int *bytesRead); - void SubmitSpline(const void *control_points, const void *indices, int tess_u, int tess_v, int count_u, int count_v, int type_u, int type_v, GEPatchPrimType prim_type, bool computeNormals, bool patchFacing, u32 vertType, int *bytesRead); - void SubmitBezier(const void *control_points, const void *indices, int tess_u, int tess_v, int count_u, int count_v, GEPatchPrimType prim_type, bool computeNormals, bool patchFacing, u32 vertType, int *bytesRead); + template + void SubmitCurve(const void *control_points, const void *indices, Surface &surface, u32 vertType, int *bytesRead, const char *scope); void ClearSplineBezierWeights(); std::vector DebugGetVertexLoaderIDs(); @@ -130,7 +131,6 @@ protected: // Vertex collector buffers u8 *decoded = nullptr; u16 *decIndex = nullptr; - u8 *splineBuffer = nullptr; // Cached vertex decoders u32 lastVType_ = -1; diff --git a/GPU/Common/FramebufferCommon.cpp b/GPU/Common/FramebufferCommon.cpp index 67f04fbba9..70b8de50b8 100644 --- a/GPU/Common/FramebufferCommon.cpp +++ b/GPU/Common/FramebufferCommon.cpp @@ -39,6 +39,7 @@ #include "GPU/Common/FramebufferCommon.h" #include "GPU/Common/PostShader.h" #include "GPU/Common/TextureCacheCommon.h" +#include "GPU/Debugger/Record.h" #include "GPU/GPUInterface.h" #include "GPU/GPUState.h" @@ -147,14 +148,13 @@ void FramebufferManagerCommon::Init() { bool FramebufferManagerCommon::UpdateSize() { const bool newRender = renderWidth_ != (float)PSP_CoreParameter().renderWidth || renderHeight_ != (float)PSP_CoreParameter().renderHeight; - const bool newSettings = bloomHack_ != g_Config.iBloomHack || trueColor_ != g_Config.bTrueColor || useBufferedRendering_ != (g_Config.iRenderingMode != FB_NON_BUFFERED_MODE); + const bool newSettings = bloomHack_ != g_Config.iBloomHack || useBufferedRendering_ != (g_Config.iRenderingMode != FB_NON_BUFFERED_MODE); renderWidth_ = (float)PSP_CoreParameter().renderWidth; renderHeight_ = (float)PSP_CoreParameter().renderHeight; pixelWidth_ = PSP_CoreParameter().pixelWidth; pixelHeight_ = PSP_CoreParameter().pixelHeight; bloomHack_ = g_Config.iBloomHack; - trueColor_ = g_Config.bTrueColor; useBufferedRendering_ = g_Config.iRenderingMode != FB_NON_BUFFERED_MODE; return newRender || newSettings; @@ -169,27 +169,24 @@ void FramebufferManagerCommon::SetDisplayFramebuffer(u32 framebuf, u32 stride, G displayFramebufPtr_ = framebuf; displayStride_ = stride; displayFormat_ = format; + GPURecord::NotifyDisplay(framebuf, stride, format); } VirtualFramebuffer *FramebufferManagerCommon::GetVFBAt(u32 addr) { + addr &= 0x3FFFFFFF; VirtualFramebuffer *match = nullptr; for (size_t i = 0; i < vfbs_.size(); ++i) { VirtualFramebuffer *v = vfbs_[i]; - if (MaskedEqual(v->fb_address, addr)) { + if (v->fb_address == addr) { // Could check w too but whatever if (match == nullptr || match->last_frame_render < v->last_frame_render) { match = v; } } } - return match; } -bool FramebufferManagerCommon::MaskedEqual(u32 addr1, u32 addr2) { - return (addr1 & 0x03FFFFFF) == (addr2 & 0x03FFFFFF); -} - u32 FramebufferManagerCommon::FramebufferByteSize(const VirtualFramebuffer *vfb) const { return vfb->fb_stride * vfb->height * (vfb->format == GE_FORMAT_8888 ? 4 : 2); } @@ -255,11 +252,10 @@ void FramebufferManagerCommon::EstimateDrawingSize(u32 fb_address, GEBufferForma if (viewport_width != region_width) { // The majority of the time, these are equal. If not, let's check what we know. - const u32 fb_normalized_address = fb_address | 0x44000000; u32 nearest_address = 0xFFFFFFFF; for (size_t i = 0; i < vfbs_.size(); ++i) { - const u32 other_address = vfbs_[i]->fb_address | 0x44000000; - if (other_address > fb_normalized_address && other_address < nearest_address) { + const u32 other_address = vfbs_[i]->fb_address & 0x3FFFFFFF; + if (other_address > fb_address && other_address < nearest_address) { nearest_address = other_address; } } @@ -268,7 +264,7 @@ void FramebufferManagerCommon::EstimateDrawingSize(u32 fb_address, GEBufferForma // This catches some cases where we can know this. // Hmm. The problem is that we could only catch it for the first of two buffers... const u32 bpp = fb_format == GE_FORMAT_8888 ? 4 : 2; - int avail_height = (nearest_address - fb_normalized_address) / (fb_stride * bpp); + int avail_height = (nearest_address - fb_address) / (fb_stride * bpp); if (avail_height < drawing_height && avail_height == region_height) { drawing_width = std::min(region_width, fb_stride); drawing_height = avail_height; @@ -284,11 +280,10 @@ void FramebufferManagerCommon::EstimateDrawingSize(u32 fb_address, GEBufferForma } void GetFramebufferHeuristicInputs(FramebufferHeuristicParams *params, const GPUgstate &gstate) { - params->fb_addr = gstate.getFrameBufAddress(); - params->fb_address = gstate.getFrameBufRawAddress(); + params->fb_address = (gstate.getFrameBufRawAddress() & 0x3FFFFFFF) | 0x04000000; // GetFramebufferHeuristicInputs is only called from rendering, and thus, it's VRAM. params->fb_stride = gstate.FrameBufStride(); - params->z_address = gstate.getDepthBufRawAddress(); + params->z_address = (gstate.getDepthBufRawAddress() & 0x3FFFFFFF) | 0x04000000; params->z_stride = gstate.DepthBufStride(); params->fmt = gstate.FrameBufFormat(); @@ -350,6 +345,13 @@ VirtualFramebuffer *FramebufferManagerCommon::DoSetRenderFrameBuffer(const Frame vfb->fb_stride = params.fb_stride; vfb->format = params.fmt; } + + if (vfb->z_address == 0 && vfb->z_stride == 0) { + // Got one that was created by CreateRAMFramebuffer. Since it has no depth buffer, + // we just recreate it immediately. + ResizeFramebufFBO(vfb, vfb->width, vfb->height, true); + } + // Keep track, but this isn't really used. vfb->z_stride = params.z_stride; // Heuristic: In throughmode, a higher height could be used. Let's avoid shrinking the buffer. @@ -420,8 +422,7 @@ VirtualFramebuffer *FramebufferManagerCommon::DoSetRenderFrameBuffer(const Frame // None found? Create one. if (!vfb) { - vfb = new VirtualFramebuffer(); - memset(vfb, 0, sizeof(VirtualFramebuffer)); + vfb = new VirtualFramebuffer{}; vfb->fbo = nullptr; vfb->fb_address = params.fb_address; vfb->fb_stride = params.fb_stride; @@ -442,9 +443,9 @@ VirtualFramebuffer *FramebufferManagerCommon::DoSetRenderFrameBuffer(const Frame SetColorUpdated(vfb, skipDrawReason); u32 byteSize = FramebufferByteSize(vfb); - u32 fb_address_mem = (params.fb_address & 0x3FFFFFFF) | 0x04000000; - if (Memory::IsVRAMAddress(fb_address_mem) && fb_address_mem + byteSize > framebufRangeEnd_) { - framebufRangeEnd_ = fb_address_mem + byteSize; + // FB heuristics always produce an address in VRAM (this is during rendering) so we don't need to poke in the 0x04000000 flag here. + if (Memory::IsVRAMAddress(params.fb_address) && params.fb_address + byteSize > framebufRangeEnd_) { + framebufRangeEnd_ = params.fb_address + byteSize; } ResizeFramebufFBO(vfb, drawing_width, drawing_height, true); @@ -458,8 +459,8 @@ VirtualFramebuffer *FramebufferManagerCommon::DoSetRenderFrameBuffer(const Frame currentRenderVfb_ = vfb; if (useBufferedRendering_ && !g_Config.bDisableSlowFramebufEffects) { - gpu->PerformMemoryUpload(fb_address_mem, byteSize); - NotifyStencilUpload(fb_address_mem, byteSize, true); + gpu->PerformMemoryUpload(params.fb_address, byteSize); + NotifyStencilUpload(params.fb_address, byteSize, true); // TODO: Is it worth trying to upload the depth buffer? } @@ -589,7 +590,7 @@ void FramebufferManagerCommon::NotifyRenderFramebufferSwitched(VirtualFramebuffe shaderManager_->DirtyLastShader(); // Copy depth pixel value from the read framebuffer to the draw framebuffer - if (prevVfb && !g_Config.bDisableSlowFramebufEffects) { + if (prevVfb) { bool hasNewerDepth = prevVfb->last_frame_depth_render != 0 && prevVfb->last_frame_depth_render >= vfb->last_frame_depth_updated; if (!prevVfb->fbo || !vfb->fbo || !useBufferedRendering_ || !hasNewerDepth || isClearingDepth) { // If depth wasn't updated, then we're at least "two degrees" away from the data. @@ -682,7 +683,8 @@ void FramebufferManagerCommon::NotifyVideoUpload(u32 addr, int size, int width, } void FramebufferManagerCommon::UpdateFromMemory(u32 addr, int size, bool safe) { - addr &= ~0x40000000; + // Take off the uncached flag from the address. Not to be confused with the start of VRAM. + addr &= 0x3FFFFFFF; // TODO: Could go through all FBOs, but probably not important? // TODO: Could also check for inner changes, but video is most important. bool isDisplayBuf = addr == DisplayFramebufAddr() || addr == PrevDisplayFramebufAddr(); @@ -693,7 +695,7 @@ void FramebufferManagerCommon::UpdateFromMemory(u32 addr, int size, bool safe) { for (size_t i = 0; i < vfbs_.size(); ++i) { VirtualFramebuffer *vfb = vfbs_[i]; - if (MaskedEqual(vfb->fb_address, addr)) { + if (vfb->fb_address == addr) { FlushBeforeCopy(); if (useBufferedRendering_ && vfb->fbo) { @@ -702,7 +704,7 @@ void FramebufferManagerCommon::UpdateFromMemory(u32 addr, int size, bool safe) { // If we're not rendering to it, format may be wrong. Use displayFormat_ instead. fmt = displayFormat_; } - DrawPixels(vfb, 0, 0, Memory::GetPointer(addr | 0x04000000), fmt, vfb->fb_stride, vfb->width, vfb->height); + DrawPixels(vfb, 0, 0, Memory::GetPointer(addr), fmt, vfb->fb_stride, vfb->width, vfb->height); SetColorUpdated(vfb, gstate_c.skipDrawReason); } else { INFO_LOG(FRAMEBUF, "Invalidating FBO for %08x (%i x %i x %i)", vfb->fb_address, vfb->width, vfb->height, vfb->format); @@ -868,11 +870,13 @@ void FramebufferManagerCommon::CopyDisplayToOutput() { VirtualFramebuffer *vfb = GetVFBAt(displayFramebufPtr_); if (!vfb) { - // Let's search for a framebuf within this range. - const u32 addr = (displayFramebufPtr_ & 0x03FFFFFF) | 0x04000000; + // Let's search for a framebuf within this range. Note that we also look for + // "framebuffers" sitting in RAM so we only take off the kernel and uncached bits of the address + // when comparing. + const u32 addr = displayFramebufPtr_ & 0x3FFFFFFF; for (size_t i = 0; i < vfbs_.size(); ++i) { VirtualFramebuffer *v = vfbs_[i]; - const u32 v_addr = (v->fb_address & 0x03FFFFFF) | 0x04000000; + const u32 v_addr = v->fb_address & 0x3FFFFFFF; const u32 v_size = FramebufferByteSize(v); if (addr >= v_addr && addr < v_addr + v_size) { const u32 dstBpp = v->format == GE_FORMAT_8888 ? 4 : 2; @@ -909,14 +913,6 @@ void FramebufferManagerCommon::CopyDisplayToOutput() { if (!vfb) { if (Memory::IsValidAddress(displayFramebufPtr_)) { // The game is displaying something directly from RAM. In GTA, it's decoded video. - - // First check that it's not a known RAM copy of a VRAM framebuffer though, as in MotoGP - for (auto iter = knownFramebufferRAMCopies_.begin(); iter != knownFramebufferRAMCopies_.end(); ++iter) { - if (iter->second == displayFramebufPtr_) { - vfb = GetVFBAt(iter->first); - } - } - if (!vfb) { shaderManager_->DirtyLastShader(); if (useBufferedRendering_) { @@ -1156,30 +1152,10 @@ void FramebufferManagerCommon::ResizeFramebufFBO(VirtualFramebuffer *vfb, int w, SetRenderSize(vfb); - bool trueColor = trueColor_; - if (PSP_CoreParameter().compat.flags().Force04154000Download && vfb->fb_address == 0x00154000) { - trueColor = true; - } - - if (trueColor) { - vfb->colorDepth = Draw::FBO_8888; - } else { - switch (vfb->format) { - case GE_FORMAT_4444: - vfb->colorDepth = Draw::FBO_4444; - break; - case GE_FORMAT_5551: - vfb->colorDepth = Draw::FBO_5551; - break; - case GE_FORMAT_565: - vfb->colorDepth = Draw::FBO_565; - break; - case GE_FORMAT_8888: - default: - vfb->colorDepth = Draw::FBO_8888; - break; - } - } + // During hardware rendering, we always render at full color depth even if the game wouldn't on real hardware. + // It's not worth the trouble trying to support lower bit-depth rendering, just + // more cases to test that nobody will ever use. + vfb->colorDepth = Draw::FBO_8888; textureCache_->ForgetLastTexture(); @@ -1203,7 +1179,7 @@ void FramebufferManagerCommon::ResizeFramebufFBO(VirtualFramebuffer *vfb, int w, draw_->BindFramebufferAsRenderTarget(vfb->fbo, { Draw::RPAction::CLEAR, Draw::RPAction::CLEAR, Draw::RPAction::CLEAR }); // GLES resets the blend state on clears. gstate_c.Dirty(DIRTY_BLEND_STATE); - if (!skipCopy && !g_Config.bDisableSlowFramebufEffects) { + if (!skipCopy) { BlitFramebuffer(vfb, 0, 0, &old, 0, 0, std::min((u16)oldWidth, std::min(vfb->bufferWidth, vfb->width)), std::min((u16)oldHeight, std::min(vfb->height, vfb->bufferHeight)), 0); } } @@ -1223,6 +1199,8 @@ void FramebufferManagerCommon::ResizeFramebufFBO(VirtualFramebuffer *vfb, int w, } } +// This is called from detected memcopies only. Not block transfers. +// MotoGP goes this path so we need to catch those copies here. bool FramebufferManagerCommon::NotifyFramebufferCopy(u32 src, u32 dst, int size, bool isMemset, u32 skipDrawReason) { if (size == 0) { return false; @@ -1243,7 +1221,8 @@ bool FramebufferManagerCommon::NotifyFramebufferCopy(u32 src, u32 dst, int size, continue; } - const u32 vfb_address = (0x04000000 | vfb->fb_address) & 0x3FFFFFFF; + // We only remove the kernel and uncached bits when comparing. + const u32 vfb_address = vfb->fb_address & 0x3FFFFFFF; const u32 vfb_size = FramebufferByteSize(vfb); const u32 vfb_bpp = vfb->format == GE_FORMAT_8888 ? 4 : 2; const u32 vfb_byteStride = vfb->fb_stride * vfb_bpp; @@ -1282,15 +1261,6 @@ bool FramebufferManagerCommon::NotifyFramebufferCopy(u32 src, u32 dst, int size, } } - if (srcBuffer && srcY == 0 && srcH == srcBuffer->height && !dstBuffer) { - // MotoGP workaround - it copies a framebuffer to memory and then displays it. - // TODO: It's rare anyway, but the game could modify the RAM and then we'd display the wrong thing. - // Unfortunately, that would force 1x render resolution. - if (Memory::IsRAMAddress(dst)) { - knownFramebufferRAMCopies_.insert(std::pair(src, dst)); - } - } - if (!useBufferedRendering_) { // If we're copying into a recently used display buf, it's probably destined for the screen. if (srcBuffer || (dstBuffer != displayFramebuf_ && dstBuffer != prevDisplayFramebuf_)) { @@ -1298,17 +1268,23 @@ bool FramebufferManagerCommon::NotifyFramebufferCopy(u32 src, u32 dst, int size, } } + if (!dstBuffer && srcBuffer && PSP_CoreParameter().compat.flags().BlockTransferAllowCreateFB) { + dstBuffer = CreateRAMFramebuffer(dst, srcBuffer->width, srcBuffer->height, srcBuffer->fb_stride, srcBuffer->format); + dstY = 0; + } + if (dstBuffer) { + dstBuffer->last_frame_used = gpuStats.numFlips; + } + if (dstBuffer && srcBuffer && !isMemset) { if (srcBuffer == dstBuffer) { WARN_LOG_REPORT_ONCE(dstsrccpy, G3D, "Intra-buffer memcpy (not supported) %08x -> %08x", src, dst); } else { WARN_LOG_REPORT_ONCE(dstnotsrccpy, G3D, "Inter-buffer memcpy %08x -> %08x", src, dst); // Just do the blit! - if (g_Config.bBlockTransferGPU) { - BlitFramebuffer(dstBuffer, 0, dstY, srcBuffer, 0, srcY, srcBuffer->width, srcH, 0); - SetColorUpdated(dstBuffer, skipDrawReason); - RebindFramebuffer(); - } + BlitFramebuffer(dstBuffer, 0, dstY, srcBuffer, 0, srcY, srcBuffer->width, srcH, 0); + SetColorUpdated(dstBuffer, skipDrawReason); + RebindFramebuffer(); } return false; } else if (dstBuffer) { @@ -1316,15 +1292,12 @@ bool FramebufferManagerCommon::NotifyFramebufferCopy(u32 src, u32 dst, int size, gpuStats.numClears++; } WARN_LOG_ONCE(btucpy, G3D, "Memcpy fbo upload %08x -> %08x", src, dst); - if (g_Config.bBlockTransferGPU) { - FlushBeforeCopy(); - const u8 *srcBase = Memory::GetPointerUnchecked(src); - DrawPixels(dstBuffer, 0, dstY, srcBase, dstBuffer->format, dstBuffer->fb_stride, dstBuffer->width, dstH); - SetColorUpdated(dstBuffer, skipDrawReason); - RebindFramebuffer(); - // This is a memcpy, let's still copy just in case. - return false; - } + FlushBeforeCopy(); + const u8 *srcBase = Memory::GetPointerUnchecked(src); + DrawPixels(dstBuffer, 0, dstY, srcBase, dstBuffer->format, dstBuffer->fb_stride, dstBuffer->width, dstH); + SetColorUpdated(dstBuffer, skipDrawReason); + RebindFramebuffer(); + // This is a memcpy, let's still copy just in case. return false; } else if (srcBuffer) { WARN_LOG_ONCE(btdcpy, G3D, "Memcpy fbo download %08x -> %08x", src, dst); @@ -1341,7 +1314,8 @@ bool FramebufferManagerCommon::NotifyFramebufferCopy(u32 src, u32 dst, int size, } } -void FramebufferManagerCommon::FindTransferFramebuffers(VirtualFramebuffer *&dstBuffer, VirtualFramebuffer *&srcBuffer, u32 dstBasePtr, int dstStride, int &dstX, int &dstY, u32 srcBasePtr, int srcStride, int &srcX, int &srcY, int &srcWidth, int &srcHeight, int &dstWidth, int &dstHeight, int bpp) const { +// Can't be const, in case it has to create a vfb unfortunately. +void FramebufferManagerCommon::FindTransferFramebuffers(VirtualFramebuffer *&dstBuffer, VirtualFramebuffer *&srcBuffer, u32 dstBasePtr, int dstStride, int &dstX, int &dstY, u32 srcBasePtr, int srcStride, int &srcX, int &srcY, int &srcWidth, int &srcHeight, int &dstWidth, int &dstHeight, int bpp) { u32 dstYOffset = -1; u32 dstXOffset = -1; u32 srcYOffset = -1; @@ -1354,7 +1328,7 @@ void FramebufferManagerCommon::FindTransferFramebuffers(VirtualFramebuffer *&dst for (size_t i = 0; i < vfbs_.size(); ++i) { VirtualFramebuffer *vfb = vfbs_[i]; - const u32 vfb_address = (0x04000000 | vfb->fb_address) & 0x3FFFFFFF; + const u32 vfb_address = vfb->fb_address & 0x3FFFFFFF; const u32 vfb_size = FramebufferByteSize(vfb); const u32 vfb_bpp = vfb->format == GE_FORMAT_8888 ? 4 : 2; const u32 vfb_byteStride = vfb->fb_stride * vfb_bpp; @@ -1421,6 +1395,16 @@ void FramebufferManagerCommon::FindTransferFramebuffers(VirtualFramebuffer *&dst } } + if (!dstBuffer && PSP_CoreParameter().compat.flags().BlockTransferAllowCreateFB) { + GEBufferFormat ramFormat = bpp == 4 ? GE_FORMAT_8888 : GE_FORMAT_5551; + // TODO: We don't really know the 16-bit format here.. at all. Can only guess when it gets used later! + // But actually, the format of the source buffer is probably not a bad guess.. + dstBuffer = CreateRAMFramebuffer(dstBasePtr, dstWidth, dstHeight, dstStride, ramFormat); + } + + if (dstBuffer) + dstBuffer->last_frame_used = gpuStats.numFlips; + if (dstYOffset != (u32)-1) { dstY += dstYOffset; dstX += dstXOffset; @@ -1431,6 +1415,38 @@ void FramebufferManagerCommon::FindTransferFramebuffers(VirtualFramebuffer *&dst } } +VirtualFramebuffer *FramebufferManagerCommon::CreateRAMFramebuffer(uint32_t fbAddress, int width, int height, int stride, GEBufferFormat format) { + float renderWidthFactor = renderWidth_ / 480.0f; + float renderHeightFactor = renderHeight_ / 272.0f; + + // A target for the destination is missing - so just create one! + // Make sure this one would be found by the algorithm above so we wouldn't + // create a new one each frame. + VirtualFramebuffer *vfb = new VirtualFramebuffer{}; + vfb->fbo = nullptr; + vfb->fb_address = fbAddress; // NOTE - not necessarily in VRAM! + vfb->fb_stride = stride; + vfb->z_address = 0; // marks that if anyone tries to render to this framebuffer, it should be dropped and recreated. + vfb->z_stride = 0; + vfb->width = std::max(width, stride); + vfb->height = height; + vfb->newWidth = vfb->width; + vfb->newHeight = vfb->height; + vfb->lastFrameNewSize = gpuStats.numFlips; + vfb->renderWidth = (u16)(vfb->width * renderWidthFactor); + vfb->renderHeight = (u16)(vfb->height * renderHeightFactor); + vfb->bufferWidth = vfb->width; + vfb->bufferHeight = vfb->height; + vfb->format = format; + vfb->drawnFormat = GE_FORMAT_8888; + vfb->usageFlags = FB_USAGE_RENDERTARGET; + SetColorUpdated(vfb, 0); + textureCache_->NotifyFramebuffer(vfb->fb_address, vfb, NOTIFY_FB_CREATED); + vfb->fbo = draw_->CreateFramebuffer({ vfb->renderWidth, vfb->renderHeight, 1, 1, true, (Draw::FBColorDepth)vfb->colorDepth }); + vfbs_.push_back(vfb); + return vfb; +} + // 1:1 pixel sides buffers, we resize buffers to these before we read them back. VirtualFramebuffer *FramebufferManagerCommon::FindDownloadTempBuffer(VirtualFramebuffer *vfb) { // For now we'll keep these on the same struct as the ones that can get displayed @@ -1619,29 +1635,23 @@ bool FramebufferManagerCommon::NotifyBlockTransferBefore(u32 dstBasePtr, int dst if (srcBuffer == dstBuffer) { if (srcX != dstX || srcY != dstY) { WARN_LOG_ONCE(dstsrc, G3D, "Intra-buffer block transfer %08x -> %08x", srcBasePtr, dstBasePtr); - if (g_Config.bBlockTransferGPU) { - FlushBeforeCopy(); - BlitFramebuffer(dstBuffer, dstX, dstY, srcBuffer, srcX, srcY, dstWidth, dstHeight, bpp); - RebindFramebuffer(); - SetColorUpdated(dstBuffer, skipDrawReason); - return true; - } - } else { - // Ignore, nothing to do. Tales of Phantasia X does this by accident. - if (g_Config.bBlockTransferGPU) { - return true; - } - } - } else { - WARN_LOG_ONCE(dstnotsrc, G3D, "Inter-buffer block transfer %08x -> %08x", srcBasePtr, dstBasePtr); - // Just do the blit! - if (g_Config.bBlockTransferGPU) { FlushBeforeCopy(); BlitFramebuffer(dstBuffer, dstX, dstY, srcBuffer, srcX, srcY, dstWidth, dstHeight, bpp); RebindFramebuffer(); SetColorUpdated(dstBuffer, skipDrawReason); - return true; // No need to actually do the memory copy behind, probably. + return true; + } else { + // Ignore, nothing to do. Tales of Phantasia X does this by accident. + return true; } + } else { + WARN_LOG_ONCE(dstnotsrc, G3D, "Inter-buffer block transfer %08x -> %08x", srcBasePtr, dstBasePtr); + // Just do the blit! + FlushBeforeCopy(); + BlitFramebuffer(dstBuffer, dstX, dstY, srcBuffer, srcX, srcY, dstWidth, dstHeight, bpp); + RebindFramebuffer(); + SetColorUpdated(dstBuffer, skipDrawReason); + return true; // No need to actually do the memory copy behind, probably. } return false; } else if (dstBuffer) { @@ -1699,26 +1709,24 @@ void FramebufferManagerCommon::NotifyBlockTransferAfter(u32 dstBasePtr, int dstS if (dstBuffer && !srcBuffer) { WARN_LOG_ONCE(btu, G3D, "Block transfer upload %08x -> %08x", srcBasePtr, dstBasePtr); - if (g_Config.bBlockTransferGPU) { - FlushBeforeCopy(); - const u8 *srcBase = Memory::GetPointerUnchecked(srcBasePtr) + (srcX + srcY * srcStride) * bpp; - int dstBpp = dstBuffer->format == GE_FORMAT_8888 ? 4 : 2; - float dstXFactor = (float)bpp / dstBpp; - if (dstWidth > dstBuffer->width || dstHeight > dstBuffer->height) { - // The buffer isn't big enough, and we have a clear hint of size. Resize. - // This happens in Valkyrie Profile when uploading video at the ending. - ResizeFramebufFBO(dstBuffer, dstWidth, dstHeight, false, true); - // Make sure we don't flop back and forth. - dstBuffer->newWidth = std::max(dstWidth, (int)dstBuffer->width); - dstBuffer->newHeight = std::max(dstHeight, (int)dstBuffer->height); - dstBuffer->lastFrameNewSize = gpuStats.numFlips; - // Resizing may change the viewport/etc. - gstate_c.Dirty(DIRTY_VIEWPORTSCISSOR_STATE | DIRTY_CULLRANGE); - } - DrawPixels(dstBuffer, static_cast(dstX * dstXFactor), dstY, srcBase, dstBuffer->format, static_cast(srcStride * dstXFactor), static_cast(dstWidth * dstXFactor), dstHeight); - SetColorUpdated(dstBuffer, skipDrawReason); - RebindFramebuffer(); + FlushBeforeCopy(); + const u8 *srcBase = Memory::GetPointerUnchecked(srcBasePtr) + (srcX + srcY * srcStride) * bpp; + int dstBpp = dstBuffer->format == GE_FORMAT_8888 ? 4 : 2; + float dstXFactor = (float)bpp / dstBpp; + if (dstWidth > dstBuffer->width || dstHeight > dstBuffer->height) { + // The buffer isn't big enough, and we have a clear hint of size. Resize. + // This happens in Valkyrie Profile when uploading video at the ending. + ResizeFramebufFBO(dstBuffer, dstWidth, dstHeight, false, true); + // Make sure we don't flop back and forth. + dstBuffer->newWidth = std::max(dstWidth, (int)dstBuffer->width); + dstBuffer->newHeight = std::max(dstHeight, (int)dstBuffer->height); + dstBuffer->lastFrameNewSize = gpuStats.numFlips; + // Resizing may change the viewport/etc. + gstate_c.Dirty(DIRTY_VIEWPORTSCISSOR_STATE | DIRTY_CULLRANGE); } + DrawPixels(dstBuffer, static_cast(dstX * dstXFactor), dstY, srcBase, dstBuffer->format, static_cast(srcStride * dstXFactor), static_cast(dstWidth * dstXFactor), dstHeight); + SetColorUpdated(dstBuffer, skipDrawReason); + RebindFramebuffer(); } } } @@ -1917,7 +1925,7 @@ bool FramebufferManagerCommon::GetFramebuffer(u32 fb_address, int fb_stride, GEB if (!vfb) { // If there's no vfb and we're drawing there, must be memory? - buffer = GPUDebugBuffer(Memory::GetPointer(fb_address | 0x04000000), fb_stride, 512, format); + buffer = GPUDebugBuffer(Memory::GetPointer(fb_address), fb_stride, 512, format); return true; } @@ -1971,7 +1979,7 @@ bool FramebufferManagerCommon::GetDepthbuffer(u32 fb_address, int fb_stride, u32 if (!vfb) { // If there's no vfb and we're drawing there, must be memory? - buffer = GPUDebugBuffer(Memory::GetPointer(z_address | 0x04000000), z_stride, 512, GPU_DBG_FORMAT_16BIT); + buffer = GPUDebugBuffer(Memory::GetPointer(z_address), z_stride, 512, GPU_DBG_FORMAT_16BIT); return true; } @@ -2007,7 +2015,7 @@ bool FramebufferManagerCommon::GetStencilbuffer(u32 fb_address, int fb_stride, G if (!vfb) { // If there's no vfb and we're drawing there, must be memory? // TODO: Actually get the stencil. - buffer = GPUDebugBuffer(Memory::GetPointer(fb_address | 0x04000000), fb_stride, 512, GPU_DBG_FORMAT_8888); + buffer = GPUDebugBuffer(Memory::GetPointer(fb_address), fb_stride, 512, GPU_DBG_FORMAT_8888); return true; } @@ -2059,7 +2067,7 @@ void FramebufferManagerCommon::PackFramebufferSync_(VirtualFramebuffer *vfb, int return; } - const u32 fb_address = (0x04000000) | vfb->fb_address; + const u32 fb_address = vfb->fb_address & 0x3FFFFFFF; Draw::DataFormat destFormat = GEFormatToThin3D(vfb->format); const int dstBpp = (int)DataFormatSizeInBytes(destFormat); diff --git a/GPU/Common/FramebufferCommon.h b/GPU/Common/FramebufferCommon.h index 4f19debd01..9a954c1975 100644 --- a/GPU/Common/FramebufferCommon.h +++ b/GPU/Common/FramebufferCommon.h @@ -119,7 +119,6 @@ struct VirtualFramebuffer { }; struct FramebufferHeuristicParams { - u32 fb_addr; u32 fb_address; int fb_stride; u32 z_address; @@ -147,6 +146,8 @@ enum BindFramebufferColorFlags { BINDFBCOLOR_MAY_COPY = 1, BINDFBCOLOR_MAY_COPY_WITH_UV = 3, BINDFBCOLOR_APPLY_TEX_OFFSET = 4, + // Used when rendering to a temporary surface (e.g. not the current render target.) + BINDFBCOLOR_FORCE_SELF = 8, }; enum DrawTextureFlags { @@ -243,10 +244,10 @@ public: size_t NumVFBs() const { return vfbs_.size(); } u32 PrevDisplayFramebufAddr() { - return prevDisplayFramebuf_ ? (0x04000000 | prevDisplayFramebuf_->fb_address) : 0; + return prevDisplayFramebuf_ ? prevDisplayFramebuf_->fb_address : 0; } u32 DisplayFramebufAddr() { - return displayFramebuf_ ? (0x04000000 | displayFramebuf_->fb_address) : 0; + return displayFramebuf_ ? displayFramebuf_->fb_address : 0; } u32 DisplayFramebufStride() { @@ -332,7 +333,6 @@ protected: void EstimateDrawingSize(u32 fb_address, GEBufferFormat fb_format, int viewport_width, int viewport_height, int region_width, int region_height, int scissor_width, int scissor_height, int fb_stride, int &drawing_width, int &drawing_height); u32 FramebufferByteSize(const VirtualFramebuffer *vfb) const; - static bool MaskedEqual(u32 addr1, u32 addr2); void NotifyRenderFramebufferCreated(VirtualFramebuffer *vfb); void NotifyRenderFramebufferUpdated(VirtualFramebuffer *vfb, bool vfbFormatChanged); @@ -346,10 +346,12 @@ protected: bool ShouldDownloadFramebuffer(const VirtualFramebuffer *vfb) const; void DownloadFramebufferOnSwitch(VirtualFramebuffer *vfb); - void FindTransferFramebuffers(VirtualFramebuffer *&dstBuffer, VirtualFramebuffer *&srcBuffer, u32 dstBasePtr, int dstStride, int &dstX, int &dstY, u32 srcBasePtr, int srcStride, int &srcX, int &srcY, int &srcWidth, int &srcHeight, int &dstWidth, int &dstHeight, int bpp) const; + void FindTransferFramebuffers(VirtualFramebuffer *&dstBuffer, VirtualFramebuffer *&srcBuffer, u32 dstBasePtr, int dstStride, int &dstX, int &dstY, u32 srcBasePtr, int srcStride, int &srcX, int &srcY, int &srcWidth, int &srcHeight, int &dstWidth, int &dstHeight, int bpp); VirtualFramebuffer *FindDownloadTempBuffer(VirtualFramebuffer *vfb); virtual bool CreateDownloadTempBuffer(VirtualFramebuffer *nvfb) = 0; virtual void UpdateDownloadTempBuffer(VirtualFramebuffer *nvfb) = 0; + + VirtualFramebuffer *CreateRAMFramebuffer(uint32_t fbAddress, int width, int height, int stride, GEBufferFormat format); void OptimizeDownloadRange(VirtualFramebuffer *vfb, int &x, int &y, int &w, int &h); void UpdateFramebufUsage(VirtualFramebuffer *vfb); @@ -393,7 +395,6 @@ protected: std::vector vfbs_; std::vector bvfbs_; // blitting framebuffers (for download) - std::set> knownFramebufferRAMCopies_; bool gameUsesSequentialCopies_ = false; @@ -403,7 +404,6 @@ protected: int pixelWidth_; int pixelHeight_; int bloomHack_ = 0; - bool trueColor_ = false; // Used by post-processing shaders std::vector extraFBOs_; diff --git a/GPU/Common/GPUStateUtils.cpp b/GPU/Common/GPUStateUtils.cpp index d1a75d9ec9..445414a078 100644 --- a/GPU/Common/GPUStateUtils.cpp +++ b/GPU/Common/GPUStateUtils.cpp @@ -40,6 +40,17 @@ bool CanUseHardwareTransform(int prim) { return !gstate.isModeThrough() && prim != GE_PRIM_RECTANGLES; } +bool IsStencilTestOutputDisabled() { + // The mask applies on all stencil ops. + if (gstate.isStencilTestEnabled() && (gstate.pmska & 0xFF) != 0xFF) { + if (gstate.FrameBufFormat() == GE_FORMAT_565) { + return true; + } + return gstate.getStencilOpZPass() == GE_STENCILOP_KEEP && gstate.getStencilOpZFail() == GE_STENCILOP_KEEP && gstate.getStencilOpSFail() == GE_STENCILOP_KEEP; + } + return true; +} + bool NeedsTestDiscard() { // We assume this is called only when enabled and not trivially true (may also be for color testing.) if (gstate.isStencilTestEnabled() && (gstate.pmska & 0xFF) != 0xFF) @@ -170,7 +181,7 @@ const bool nonAlphaDestFactors[16] = { }; ReplaceAlphaType ReplaceAlphaWithStencil(ReplaceBlendType replaceBlend) { - if (!gstate.isStencilTestEnabled() || gstate.isModeClear()) { + if (IsStencilTestOutputDisabled() || gstate.isModeClear()) { return REPLACE_ALPHA_NO; } @@ -510,7 +521,7 @@ float DepthSliceFactor() { } // This is used for float values which might not be integers, but are in the integer scale of 65535. -static float ToScaledDepthFromInteger(float z) { +float ToScaledDepthFromIntegerScale(float z) { if (!gstate_c.Supports(GPU_SUPPORTS_ACCURATE_DEPTH)) { return z * (1.0f / 65535.0f); } @@ -526,10 +537,6 @@ static float ToScaledDepthFromInteger(float z) { } } -float ToScaledDepth(u16 z) { - return ToScaledDepthFromInteger((float)(int)z); -} - float FromScaledDepth(float z) { if (!gstate_c.Supports(GPU_SUPPORTS_ACCURATE_DEPTH)) { return z * 65535.0f; @@ -595,8 +602,8 @@ void ConvertViewportAndScissor(bool useBufferedRendering, float renderWidth, flo out.viewportY = renderY + displayOffsetY; out.viewportW = curRTWidth * renderWidthFactor; out.viewportH = curRTHeight * renderHeightFactor; - out.depthRangeMin = ToScaledDepthFromInteger(0); - out.depthRangeMax = ToScaledDepthFromInteger(65536); + out.depthRangeMin = ToScaledDepthFromIntegerScale(0); + out.depthRangeMax = ToScaledDepthFromIntegerScale(65536); } else { // These we can turn into a glViewport call, offset by offsetX and offsetY. Math after. float vpXScale = gstate.getViewportXScale(); @@ -705,11 +712,11 @@ void ConvertViewportAndScissor(bool useBufferedRendering, float renderWidth, flo if (!gstate_c.Supports(GPU_SUPPORTS_ACCURATE_DEPTH)) { zScale = 1.0f; zOffset = 0.0f; - out.depthRangeMin = ToScaledDepthFromInteger(vpZCenter - vpZScale); - out.depthRangeMax = ToScaledDepthFromInteger(vpZCenter + vpZScale); + out.depthRangeMin = ToScaledDepthFromIntegerScale(vpZCenter - vpZScale); + out.depthRangeMax = ToScaledDepthFromIntegerScale(vpZCenter + vpZScale); } else { - out.depthRangeMin = ToScaledDepthFromInteger(minz); - out.depthRangeMax = ToScaledDepthFromInteger(maxz); + out.depthRangeMin = ToScaledDepthFromIntegerScale(minz); + out.depthRangeMax = ToScaledDepthFromIntegerScale(maxz); } // OpenGL will clamp these for us anyway, and Direct3D will error if not clamped. @@ -996,7 +1003,7 @@ void ConvertBlendState(GenericBlendState &blendState, bool allowShaderBlend) { int constantAlpha = 255; BlendFactor constantAlphaGL = BlendFactor::ONE; - if (gstate.isStencilTestEnabled() && replaceAlphaWithStencil == REPLACE_ALPHA_NO) { + if (!IsStencilTestOutputDisabled() && replaceAlphaWithStencil == REPLACE_ALPHA_NO) { switch (ReplaceAlphaWithStencilType()) { case STENCIL_VALUE_UNIFORM: constantAlpha = gstate.getStencilTestRef(); @@ -1164,7 +1171,7 @@ void ConvertBlendState(GenericBlendState &blendState, bool allowShaderBlend) { blendState.setFactors(glBlendFuncA, glBlendFuncB, BlendFactor::ONE, BlendFactor::ZERO); break; } - } else if (gstate.isStencilTestEnabled()) { + } else if (!IsStencilTestOutputDisabled()) { switch (ReplaceAlphaWithStencilType()) { case STENCIL_VALUE_KEEP: blendState.setFactors(glBlendFuncA, glBlendFuncB, BlendFactor::ZERO, BlendFactor::ONE); @@ -1332,7 +1339,7 @@ static void ConvertStencilFunc5551(GenericStencilFuncState &state) { } void ConvertStencilFuncState(GenericStencilFuncState &state) { - state.enabled = gstate.isStencilTestEnabled() && !g_Config.bDisableStencilTest; + state.enabled = gstate.isStencilTestEnabled(); if (!state.enabled) return; diff --git a/GPU/Common/GPUStateUtils.h b/GPU/Common/GPUStateUtils.h index f6a4e11c21..6cf95f84b7 100644 --- a/GPU/Common/GPUStateUtils.h +++ b/GPU/Common/GPUStateUtils.h @@ -45,6 +45,7 @@ bool IsColorTestAgainstZero(); bool IsColorTestTriviallyTrue(); bool IsAlphaTestAgainstZero(); bool NeedsTestDiscard(); +bool IsStencilTestOutputDisabled(); StencilValueType ReplaceAlphaWithStencilType(); ReplaceAlphaType ReplaceAlphaWithStencil(ReplaceBlendType replaceBlend); @@ -71,7 +72,7 @@ struct ViewportAndScissor { bool dirtyDepth; }; void ConvertViewportAndScissor(bool useBufferedRendering, float renderWidth, float renderHeight, int bufferWidth, int bufferHeight, ViewportAndScissor &out); -float ToScaledDepth(u16 z); +float ToScaledDepthFromIntegerScale(float z); float FromScaledDepth(float z); float DepthSliceFactor(); diff --git a/GPU/Common/IndexGenerator.cpp b/GPU/Common/IndexGenerator.cpp index 9c1b13d42d..d339fb4790 100644 --- a/GPU/Common/IndexGenerator.cpp +++ b/GPU/Common/IndexGenerator.cpp @@ -77,6 +77,10 @@ void IndexGenerator::AddList(int numVerts, bool clockwise) { count_ += numVerts; prim_ = GE_PRIM_TRIANGLES; seenPrims_ |= 1 << GE_PRIM_TRIANGLES; + if (!clockwise) { + // Make sure we don't treat this as pure. + seenPrims_ |= 1 << GE_PRIM_TRIANGLE_STRIP; + } } void IndexGenerator::AddStrip(int numVerts, bool clockwise) { @@ -96,7 +100,7 @@ void IndexGenerator::AddStrip(int numVerts, bool clockwise) { if (numTris > 0) count_ += numTris * 3; // This is so we can detect one single strip by just looking at seenPrims_. - if (!seenPrims_) { + if (!seenPrims_ && clockwise) { seenPrims_ = 1 << GE_PRIM_TRIANGLE_STRIP; prim_ = GE_PRIM_TRIANGLE_STRIP; pureCount_ = numVerts; @@ -123,6 +127,10 @@ void IndexGenerator::AddFan(int numVerts, bool clockwise) { count_ += numTris * 3; prim_ = GE_PRIM_TRIANGLES; seenPrims_ |= 1 << GE_PRIM_TRIANGLE_FAN; + if (!clockwise) { + // Make sure we don't treat this as pure. + seenPrims_ |= 1 << GE_PRIM_TRIANGLE_STRIP; + } } //Lines @@ -218,7 +226,7 @@ void IndexGenerator::TranslateList(int numInds, const ITypeLE *inds, int indexOf indexOffset = index_ - indexOffset; // We only bother doing this minor optimization in triangle list, since it's by far the most // common operation that can benefit. - if (sizeof(ITypeLE) == sizeof(inds_[0]) && indexOffset == 0) { + if (sizeof(ITypeLE) == sizeof(inds_[0]) && indexOffset == 0 && clockwise) { memcpy(inds_, inds, numInds * sizeof(ITypeLE)); inds_ += numInds; count_ += numInds; diff --git a/GPU/Common/ShaderCommon.h b/GPU/Common/ShaderCommon.h index b18f69839c..a00c5a72af 100644 --- a/GPU/Common/ShaderCommon.h +++ b/GPU/Common/ShaderCommon.h @@ -19,6 +19,10 @@ #include +namespace Draw { + class DrawContext; +} + enum ShaderLanguage { GLSL_140, GLSL_300, @@ -117,10 +121,13 @@ enum : uint64_t { class ShaderManagerCommon { public: - ShaderManagerCommon() {} + ShaderManagerCommon(Draw::DrawContext *draw) : draw_(draw) {} virtual ~ShaderManagerCommon() {} virtual void DirtyLastShader() = 0; + +protected: + Draw::DrawContext *draw_ = nullptr; }; struct TBuiltInResource; diff --git a/GPU/Common/ShaderId.cpp b/GPU/Common/ShaderId.cpp index e7ed0b4e87..f3a8e09228 100644 --- a/GPU/Common/ShaderId.cpp +++ b/GPU/Common/ShaderId.cpp @@ -1,6 +1,7 @@ #include #include +#include "thin3d/thin3d.h" #include "Common/StringUtils.h" #include "Core/Config.h" @@ -60,7 +61,7 @@ std::string VertexShaderDesc(const ShaderID &id) { } void ComputeVertexShaderID(ShaderID *id_out, u32 vertType, bool useHWTransform) { - bool isModeThrough = gstate.isModeThrough(); + bool isModeThrough = (vertType & GE_VTYPE_THROUGH) != 0; bool doTexture = gstate.isTextureMapEnabled() && !gstate.isModeClear(); bool doTextureTransform = gstate.getUVGenMode() == GE_TEXMAP_TEXTURE_MATRIX; bool doShadeMapping = doTexture && (gstate.getUVGenMode() == GE_TEXMAP_ENVIRONMENT_MAP); @@ -72,6 +73,7 @@ void ComputeVertexShaderID(ShaderID *id_out, u32 vertType, bool useHWTransform) bool doBezier = gstate_c.bezier; bool doSpline = gstate_c.spline; + // These are the original vertType's values (normalized will always have colors, etc.) bool hasColorTess = (gstate.vertType & GE_VTYPE_COL_MASK) != 0 && (doBezier || doSpline); bool hasTexcoordTess = (gstate.vertType & GE_VTYPE_TC_MASK) != 0 && (doBezier || doSpline); bool hasNormalTess = (gstate.vertType & GE_VTYPE_NRM_MASK) != 0 && (doBezier || doSpline); @@ -115,18 +117,15 @@ void ComputeVertexShaderID(ShaderID *id_out, u32 vertType, bool useHWTransform) id.SetBits(VS_BIT_WEIGHT_FMTSCALE, 2, (vertType & GE_VTYPE_WEIGHT_MASK) >> GE_VTYPE_WEIGHT_SHIFT); } - // Okay, d[1] coming up. ============== - if (gstate.isLightingEnabled() || doShadeMapping) { - // doShadeMapping is stored as UVGenMode, so this is enough for isLightingEnabled. - if (gstate.isLightingEnabled()) { - id.SetBits(VS_BIT_MATERIAL_UPDATE, 3, gstate.getMaterialUpdate() & 7); - id.SetBit(VS_BIT_LIGHTING_ENABLE); - } + if (gstate.isLightingEnabled()) { + // doShadeMapping is stored as UVGenMode, and light type doesn't matter for shade mapping. + id.SetBits(VS_BIT_MATERIAL_UPDATE, 3, gstate.getMaterialUpdate() & 7); + id.SetBit(VS_BIT_LIGHTING_ENABLE); // Light bits for (int i = 0; i < 4; i++) { - bool chanEnabled = gstate.isLightChanEnabled(i) != 0 && gstate.isLightingEnabled(); + bool chanEnabled = gstate.isLightChanEnabled(i) != 0; id.SetBit(VS_BIT_LIGHT0_ENABLE + i, chanEnabled); - if (chanEnabled || (doShadeMapping && (gstate.getUVLS0() == i || gstate.getUVLS1() == i))) { + if (chanEnabled) { id.SetBits(VS_BIT_LIGHT0_COMP + 4 * i, 2, gstate.getLightComputation(i)); id.SetBits(VS_BIT_LIGHT0_TYPE + 4 * i, 2, gstate.getLightType(i)); } @@ -201,8 +200,10 @@ std::string FragmentShaderDesc(const ShaderID &id) { case STENCIL_VALUE_INCR_8: desc << "StenIncr8 "; break; case STENCIL_VALUE_DECR_4: desc << "StenDecr4 "; break; case STENCIL_VALUE_DECR_8: desc << "StenDecr4 "; break; - default: desc << "StenUnknown"; break; + default: desc << "StenUnknown "; break; } + } else if (id.Bit(FS_BIT_REPLACE_ALPHA_WITH_STENCIL_TYPE)) { + desc << "StenOff "; } if (id.Bit(FS_BIT_DO_TEXTURE)) { switch (id.Bits(FS_BIT_TEXFUNC, 3)) { @@ -225,7 +226,7 @@ std::string FragmentShaderDesc(const ShaderID &id) { // Here we must take all the bits of the gstate that determine what the fragment shader will // look like, and concatenate them together into an ID. -void ComputeFragmentShaderID(ShaderID *id_out) { +void ComputeFragmentShaderID(ShaderID *id_out, const Draw::Bugs &bugs) { ShaderID id; if (gstate.isModeClear()) { // We only need one clear shader, so let's ignore the rest of the bits. @@ -309,6 +310,12 @@ void ComputeFragmentShaderID(ShaderID *id_out) { id.SetBit(FS_BIT_FLATSHADE, doFlatShading); id.SetBit(FS_BIT_SHADER_DEPAL, useShaderDepal); + + if (g_Config.bVendorBugChecksEnabled) { + if (bugs.Has(Draw::Bugs::NO_DEPTH_CANNOT_DISCARD_STENCIL)) { + id.SetBit(FS_BIT_NO_DEPTH_CANNOT_DISCARD_STENCIL, !IsStencilTestOutputDisabled() && !gstate.isDepthWriteEnabled()); + } + } } *id_out = id; diff --git a/GPU/Common/ShaderId.h b/GPU/Common/ShaderId.h index 573da9c3f3..ec57b0273f 100644 --- a/GPU/Common/ShaderId.h +++ b/GPU/Common/ShaderId.h @@ -87,7 +87,8 @@ enum { FS_BIT_FLATSHADE = 46, FS_BIT_BGRA_TEXTURE = 47, FS_BIT_TEST_DISCARD_TO_ZERO = 48, - // 49+ are free. + FS_BIT_NO_DEPTH_CANNOT_DISCARD_STENCIL = 49, + // 50+ are free. }; struct ShaderID { @@ -175,12 +176,15 @@ struct FShaderID : ShaderID { } }; +namespace Draw { +class Bugs; +} + -bool CanUseHardwareTransform(int prim); void ComputeVertexShaderID(ShaderID *id, uint32_t vertexType, bool useHWTransform); // Generates a compact string that describes the shader. Useful in a list to get an overview // of the current flora of shaders. std::string VertexShaderDesc(const ShaderID &id); -void ComputeFragmentShaderID(ShaderID *id); +void ComputeFragmentShaderID(ShaderID *id, const Draw::Bugs &bugs); std::string FragmentShaderDesc(const ShaderID &id); diff --git a/GPU/Common/ShaderUniforms.cpp b/GPU/Common/ShaderUniforms.cpp index fe29673107..f549f53af4 100644 --- a/GPU/Common/ShaderUniforms.cpp +++ b/GPU/Common/ShaderUniforms.cpp @@ -42,9 +42,27 @@ void CalcCullRange(float minValues[4], float maxValues[4], bool flipViewport, bo return (pspViewport - gstate_c.vpYOffset) * heightScale; }; auto reverseViewportZ = [hasNegZ](float z) { - float pspViewport = (z - gstate.getViewportZCenter()) * (1.0f / gstate.getViewportZScale()); - // Differs from GLES: depth is 0 to 1, not -1 to 1. - float realViewport = (pspViewport - gstate_c.vpZOffset) * gstate_c.vpDepthScale; + float vpZScale = gstate.getViewportZScale(); + float vpZCenter = gstate.getViewportZCenter(); + + float scale, center; + if (gstate_c.Supports(GPU_SUPPORTS_ACCURATE_DEPTH)) { + // These are just the reverse of the formulas in GPUStateUtils. + float halfActualZRange = vpZScale * (1.0f / gstate_c.vpDepthScale); + float minz = -((gstate_c.vpZOffset * halfActualZRange) - vpZCenter) - halfActualZRange; + + // In accurate depth mode, we're comparing against a value scaled to (minz, maxz). + // And minz might be very negative, (e.g. if we're clamping in that direction.) + scale = halfActualZRange; + center = minz + halfActualZRange; + } else { + // In old-style depth mode, we're comparing against a value scaled to viewport. + // (and possibly incorrectly clipped against it.) + scale = vpZScale; + center = vpZCenter; + } + + float realViewport = (z - center) * (1.0f / scale); return hasNegZ ? realViewport : (realViewport * 0.5f + 0.5f); }; auto sortPair = [](float a, float b) { diff --git a/GPU/Common/SoftwareTransformCommon.cpp b/GPU/Common/SoftwareTransformCommon.cpp index fc943993b4..4a77731f00 100644 --- a/GPU/Common/SoftwareTransformCommon.cpp +++ b/GPU/Common/SoftwareTransformCommon.cpp @@ -191,9 +191,9 @@ void SoftwareTransform( fog_slope = std::signbit(fog_slope) ? -65535.0f : 65535.0f; } - int colorIndOffset = 0; + int provokeIndOffset = 0; if (params->provokeFlatFirst) { - colorIndOffset = ColorIndexOffset(prim, gstate.getShadeMode(), gstate.isModeClear()); + provokeIndOffset = ColorIndexOffset(prim, gstate.getShadeMode(), gstate.isModeClear()); } VertexReader reader(decoded, decVtxFormat, vertType); @@ -206,8 +206,8 @@ void SoftwareTransform( reader.ReadPos(vert.pos); if (reader.hasColor0()) { - if (colorIndOffset != 0 && index + colorIndOffset < maxIndex) { - reader.Goto(index + colorIndOffset); + if (provokeIndOffset != 0 && index + provokeIndOffset < maxIndex) { + reader.Goto(index + provokeIndOffset); reader.ReadColor0_8888(vert.color0); reader.Goto(index); } else { @@ -247,10 +247,24 @@ void SoftwareTransform( Vec3f worldnormal(0, 0, 1); reader.ReadPos(pos); + float ruv[2] = { 0.0f, 0.0f }; + if (reader.hasUV()) + reader.ReadUV(ruv); + + // Read all the provoking vertex values here. + Vec4f unlitColor; + if (provokeIndOffset != 0 && index + provokeIndOffset < maxIndex) + reader.Goto(index + provokeIndOffset); + if (reader.hasColor0()) + reader.ReadColor0(unlitColor.AsArray()); + else + unlitColor = Vec4f::FromRGBA(gstate.getMaterialAmbientRGBA()); + if (reader.hasNormal()) + reader.ReadNrm(normal.AsArray()); + if (!skinningEnabled) { Vec3ByMatrix43(out, pos, gstate.worldMatrix); if (reader.hasNormal()) { - reader.ReadNrm(normal.AsArray()); if (gstate.areNormalsReversed()) { normal = -normal; } @@ -259,9 +273,9 @@ void SoftwareTransform( } } else { float weights[8]; + // TODO: For flat, are weights from the provoking used for color/normal? + reader.Goto(index); reader.ReadWeights(weights); - if (reader.hasNormal()) - reader.ReadNrm(normal.AsArray()); // Skinning Vec3f psum(0, 0, 0); @@ -291,20 +305,7 @@ void SoftwareTransform( } } - // Perform lighting here if enabled. don't need to check through, it's checked above. - Vec4f unlitColor = Vec4f(1, 1, 1, 1); - if (reader.hasColor0()) { - if (colorIndOffset != 0 && index + colorIndOffset < maxIndex) { - reader.Goto(index + colorIndOffset); - reader.ReadColor0(&unlitColor.x); - reader.Goto(index); - } else { - reader.ReadColor0(&unlitColor.x); - } - } else { - unlitColor = Vec4f::FromRGBA(gstate.getMaterialAmbientRGBA()); - } - + // Perform lighting here if enabled. if (gstate.isLightingEnabled()) { float litColor0[4]; float litColor1[4]; @@ -338,10 +339,6 @@ void SoftwareTransform( } } - float ruv[2] = {0.0f, 0.0f}; - if (reader.hasUV()) - reader.ReadUV(ruv); - // Perform texture coordinate generation after the transform and lighting - one style of UV depends on lights. switch (gstate.getUVGenMode()) { case GE_TEXMAP_TEXTURE_COORDS: // UV mapping @@ -354,6 +351,8 @@ void SoftwareTransform( case GE_TEXMAP_TEXTURE_MATRIX: { + // TODO: What's the correct behavior with flat shading? Provoked normal or real normal? + // Projection mapping Vec3f source; switch (gstate.getUVProjMode()) { @@ -391,8 +390,23 @@ void SoftwareTransform( case GE_TEXMAP_ENVIRONMENT_MAP: // Shade mapping - use two light sources to generate U and V. { - Vec3f lightpos0 = Vec3f(&lighter.lpos[gstate.getUVLS0() * 3]).Normalized(); - Vec3f lightpos1 = Vec3f(&lighter.lpos[gstate.getUVLS1() * 3]).Normalized(); + auto getLPosFloat = [&](int l, int i) { + return getFloat24(gstate.lpos[l * 3 + i]); + }; + auto getLPos = [&](int l) { + return Vec3f(getLPosFloat(l, 0), getLPosFloat(l, 1), getLPosFloat(l, 2)); + }; + auto calcShadingLPos = [&](int l) { + Vec3f pos = getLPos(l); + if (pos.Length2() == 0.0f) { + return Vec3f(0.0f, 0.0f, 1.0f); + } else { + return pos.Normalized(); + } + }; + // Might not have lighting enabled, so don't use lighter. + Vec3f lightpos0 = calcShadingLPos(gstate.getUVLS0()); + Vec3f lightpos1 = calcShadingLPos(gstate.getUVLS1()); uv[0] = (1.0f + Dot(lightpos0, worldnormal))/2.0f; uv[1] = (1.0f + Dot(lightpos1, worldnormal))/2.0f; @@ -446,7 +460,7 @@ void SoftwareTransform( if (params->allowSeparateAlphaClear || (alphaMatchesColor && depthMatchesStencil)) { result->color = transformed[1].color0_32; // Need to rescale from a [0, 1] float. This is the final transformed value. - result->depth = ToScaledDepth((s16)(int)(transformed[1].z * 65535.0f)); + result->depth = ToScaledDepthFromIntegerScale((int)(transformed[1].z * 65535.0f)); result->action = SW_CLEAR; gpuStats.numClears++; return; diff --git a/GPU/Common/SplineCommon.cpp b/GPU/Common/SplineCommon.cpp index 77427b99ee..436e7d87c2 100644 --- a/GPU/Common/SplineCommon.cpp +++ b/GPU/Common/SplineCommon.cpp @@ -488,106 +488,23 @@ void DrawEngineCommon::ClearSplineBezierWeights() { Spline3DWeight::weightsCache.Clear(); } -void DrawEngineCommon::SubmitSpline(const void *control_points, const void *indices, int tess_u, int tess_v, int count_u, int count_v, int type_u, int type_v, GEPatchPrimType prim_type, bool computeNormals, bool patchFacing, u32 vertType, int *bytesRead) { - PROFILE_THIS_SCOPE("spline"); - DispatchFlush(); +// Specialize to make instance (to avoid link error). +template void DrawEngineCommon::SubmitCurve(const void *control_points, const void *indices, BezierSurface &surface, u32 vertType, int *bytesRead, const char *scope); +template void DrawEngineCommon::SubmitCurve(const void *control_points, const void *indices, SplineSurface &surface, u32 vertType, int *bytesRead, const char *scope); - // Real hardware seems to draw nothing when given < 4 either U or V. - if (count_u < 4 || count_v < 4) - return; - - SimpleBufferManager managedBuf(decoded, DECODED_VERTEX_BUFFER_SIZE / 2); - - int num_points = count_u * count_v; - u16 index_lower_bound = 0; - u16 index_upper_bound = num_points - 1; - IndexConverter ConvertIndex(vertType, indices); - if (indices) - GetIndexBounds(indices, num_points, vertType, &index_lower_bound, &index_upper_bound); - - VertexDecoder *origVDecoder = GetVertexDecoder((vertType & 0xFFFFFF) | (gstate.getUVGenMode() << 24)); - *bytesRead = num_points * origVDecoder->VertexSize(); - - // Simplify away bones and morph before proceeding - SimpleVertex *simplified_control_points = (SimpleVertex *)managedBuf.Allocate(sizeof(SimpleVertex) * (index_upper_bound + 1)); - u8 *temp_buffer = managedBuf.Allocate(sizeof(SimpleVertex) * num_points); - - u32 origVertType = vertType; - vertType = NormalizeVertices((u8 *)simplified_control_points, temp_buffer, (u8 *)control_points, index_lower_bound, index_upper_bound, vertType); - - VertexDecoder *vdecoder = GetVertexDecoder(vertType); - - int vertexSize = vdecoder->VertexSize(); - if (vertexSize != sizeof(SimpleVertex)) { - ERROR_LOG(G3D, "Something went really wrong, vertex size: %i vs %i", vertexSize, (int)sizeof(SimpleVertex)); - } - - // Make an array of pointers to the control points, to get rid of indices. - const SimpleVertex **points = (const SimpleVertex **)managedBuf.Allocate(sizeof(SimpleVertex *) * num_points); - for (int idx = 0; idx < num_points; idx++) - points[idx] = simplified_control_points + (indices ? ConvertIndex(idx) : idx); - - OutputBuffers output; - output.vertices = (SimpleVertex *)(decoded + DECODED_VERTEX_BUFFER_SIZE / 2); - output.indices = decIndex; - output.count = 0; - - SplineSurface surface; - surface.tess_u = tess_u; - surface.tess_v = tess_v; - surface.type_u = type_u; - surface.type_v = type_v; - surface.num_points_u = count_u; - surface.num_points_v = count_v; - surface.num_patches_u = count_u - 3; - surface.num_patches_v = count_v - 3; - surface.primType = prim_type; - surface.patchFacing = patchFacing; - surface.Init(DECODED_VERTEX_BUFFER_SIZE / 2 / vertexSize); - - if (CanUseHardwareTessellation(prim_type)) { - HardwareTessellation(output, surface, origVertType, points, tessDataTransfer); - } else { - ControlPoints cpoints(points, num_points, managedBuf); - SoftwareTessellation(output, surface, origVertType, cpoints); - } - - u32 vertTypeWithIndex16 = (vertType & ~GE_VTYPE_IDX_MASK) | GE_VTYPE_IDX_16BIT; - - UVScale prevUVScale; - if ((origVertType & GE_VTYPE_TC_MASK) != 0) { - // We scaled during Normalize already so let's turn it off when drawing. - prevUVScale = gstate_c.uv; - gstate_c.uv.uScale = 1.0f; - gstate_c.uv.vScale = 1.0f; - gstate_c.uv.uOff = 0.0f; - gstate_c.uv.vOff = 0.0f; - } - - uint32_t vertTypeID = GetVertTypeID(vertTypeWithIndex16, gstate.getUVGenMode()); - - int generatedBytesRead; - DispatchSubmitPrim(output.vertices, output.indices, PatchPrimToPrim(prim_type), output.count, vertTypeID, &generatedBytesRead); - - DispatchFlush(); - - if ((origVertType & GE_VTYPE_TC_MASK) != 0) { - gstate_c.uv = prevUVScale; - } -} - -void DrawEngineCommon::SubmitBezier(const void *control_points, const void *indices, int tess_u, int tess_v, int count_u, int count_v, GEPatchPrimType prim_type, bool computeNormals, bool patchFacing, u32 vertType, int *bytesRead) { - PROFILE_THIS_SCOPE("bezier"); +template +void DrawEngineCommon::SubmitCurve(const void *control_points, const void *indices, Surface &surface, u32 vertType, int *bytesRead, const char *scope) { + PROFILE_THIS_SCOPE(scope); DispatchFlush(); // Real hardware seems to draw nothing when given < 4 either U or V. // This would result in num_patches_u / num_patches_v being 0. - if (count_u < 4 || count_v < 4) + if (surface.num_points_u < 4 || surface.num_points_v < 4) return; SimpleBufferManager managedBuf(decoded, DECODED_VERTEX_BUFFER_SIZE / 2); - int num_points = count_u * count_v; + int num_points = surface.num_points_u * surface.num_points_v; u16 index_lower_bound = 0; u16 index_upper_bound = num_points - 1; IndexConverter ConvertIndex(vertType, indices); @@ -600,7 +517,16 @@ void DrawEngineCommon::SubmitBezier(const void *control_points, const void *indi // Simplify away bones and morph before proceeding // There are normally not a lot of control points so just splitting decoded should be reasonably safe, although not great. SimpleVertex *simplified_control_points = (SimpleVertex *)managedBuf.Allocate(sizeof(SimpleVertex) * (index_upper_bound + 1)); + if (!simplified_control_points) { + ERROR_LOG(G3D, "Failed to allocate space for simplified control points, skipping curve draw"); + return; + } + u8 *temp_buffer = managedBuf.Allocate(sizeof(SimpleVertex) * num_points); + if (!temp_buffer) { + ERROR_LOG(G3D, "Failed to allocate space for temp buffer, skipping curve draw"); + return; + } u32 origVertType = vertType; vertType = NormalizeVertices((u8 *)simplified_control_points, temp_buffer, (u8 *)control_points, index_lower_bound, index_upper_bound, vertType); @@ -614,6 +540,10 @@ void DrawEngineCommon::SubmitBezier(const void *control_points, const void *indi // Make an array of pointers to the control points, to get rid of indices. const SimpleVertex **points = (const SimpleVertex **)managedBuf.Allocate(sizeof(SimpleVertex *) * num_points); + if (!points) { + ERROR_LOG(G3D, "Failed to allocate space for control point pointers, skipping curve draw"); + return; + } for (int idx = 0; idx < num_points; idx++) points[idx] = simplified_control_points + (indices ? ConvertIndex(idx) : idx); @@ -622,18 +552,9 @@ void DrawEngineCommon::SubmitBezier(const void *control_points, const void *indi output.indices = decIndex; output.count = 0; - BezierSurface surface; - surface.tess_u = tess_u; - surface.tess_v = tess_v; - surface.num_points_u = count_u; - surface.num_points_v = count_v; - surface.num_patches_u = (count_u - 1) / 3; - surface.num_patches_v = (count_v - 1) / 3; - surface.primType = prim_type; - surface.patchFacing = patchFacing; surface.Init(DECODED_VERTEX_BUFFER_SIZE / 2 / vertexSize); - if (CanUseHardwareTessellation(prim_type)) { + if (CanUseHardwareTessellation(surface.primType)) { HardwareTessellation(output, surface, origVertType, points, tessDataTransfer); } else { ControlPoints cpoints(points, num_points, managedBuf); @@ -654,7 +575,7 @@ void DrawEngineCommon::SubmitBezier(const void *control_points, const void *indi uint32_t vertTypeID = GetVertTypeID(vertTypeWithIndex16, gstate.getUVGenMode()); int generatedBytesRead; - DispatchSubmitPrim(output.vertices, output.indices, PatchPrimToPrim(prim_type), output.count, vertTypeID, &generatedBytesRead); + DispatchSubmitPrim(output.vertices, output.indices, PatchPrimToPrim(surface.primType), output.count, vertTypeID, gstate.getCullMode(), &generatedBytesRead); DispatchFlush(); diff --git a/GPU/Common/TextureCacheCommon.cpp b/GPU/Common/TextureCacheCommon.cpp index 1bf2ee344c..b2d40d1d9c 100644 --- a/GPU/Common/TextureCacheCommon.cpp +++ b/GPU/Common/TextureCacheCommon.cpp @@ -642,9 +642,10 @@ void TextureCacheCommon::HandleTextureChange(TexCacheEntry *const entry, const c } void TextureCacheCommon::NotifyFramebuffer(u32 address, VirtualFramebuffer *framebuffer, FramebufferNotification msg) { - // Must be in VRAM so | 0x04000000 it is. Also, ignore memory mirrors. + // Mask to ignore the Z memory mirrors if the address is in VRAM. // These checks are mainly to reduce scanning all textures. - const u32 addr = (address | 0x04000000) & 0x3F9FFFFF; + const u32 mirrorMask = 0x00600000; + const u32 addr = Memory::IsVRAMAddress(address) ? (address & ~mirrorMask) : address; const u32 bpp = framebuffer->format == GE_FORMAT_8888 ? 4 : 2; const u64 cacheKey = (u64)addr << 32; // If it has a clut, those are the low 32 bits, so it'll be inside this range. @@ -756,10 +757,13 @@ bool TextureCacheCommon::AttachFramebuffer(TexCacheEntry *entry, u32 address, Vi AttachedFramebufferInfo fbInfo = { 0 }; - const u64 mirrorMask = 0x00600000; - // Must be in VRAM so | 0x04000000 it is. Also, ignore memory mirrors. - const u32 addr = (address | 0x04000000) & 0x3FFFFFFF & ~mirrorMask; - const u32 texaddr = ((entry->addr + texaddrOffset) & ~mirrorMask); + const u32 mirrorMask = 0x00600000; + u32 addr = address & 0x3FFFFFFF; + u32 texaddr = entry->addr + texaddrOffset; + if (entry->addr & 0x04000000) { + addr &= ~mirrorMask; + texaddr &= ~mirrorMask; + } const bool noOffset = texaddr == addr; const bool exactMatch = noOffset && entry->format < 4; const u32 w = 1 << ((entry->dim >> 0) & 0xf); @@ -1002,7 +1006,7 @@ void TextureCacheCommon::LoadClut(u32 clutAddr, u32 loadBytes) { clutRenderOffset_ = MAX_CLUT_OFFSET; for (size_t i = 0, n = fbCache_.size(); i < n; ++i) { auto framebuffer = fbCache_[i]; - const u32 fb_address = framebuffer->fb_address | 0x04000000; + const u32 fb_address = framebuffer->fb_address & 0x3FFFFFFF; const u32 bpp = framebuffer->drawnFormat == GE_FORMAT_8888 ? 4 : 2; u32 offset = clutFramebufAddr - fb_address; diff --git a/GPU/Common/TextureDecoder.cpp b/GPU/Common/TextureDecoder.cpp index ea2df36d89..9e896872fe 100644 --- a/GPU/Common/TextureDecoder.cpp +++ b/GPU/Common/TextureDecoder.cpp @@ -348,41 +348,36 @@ static inline u32 makecol(int r, int g, int b, int a) { return (a << 24) | (r << 16) | (g << 8) | b; } -static inline int mul_3_8(int c) { - // This is 3/8 * c = 4/8 * c - 1/8 * c. - return (c >> 1) - (c >> 3); +static inline int mix_2_3(int c1, int c2) { + return (c1 + c1 + c2) / 3; } // This could probably be done faster by decoding two or four blocks at a time with SSE/NEON. void DXTDecoder::DecodeColors(const DXT1Block *src, bool ignore1bitAlpha) { u16 c1 = src->color1; u16 c2 = src->color2; - int red1 = Convert5To8(c1 & 0x1F); - int red2 = Convert5To8(c2 & 0x1F); - int green1 = Convert6To8((c1 >> 5) & 0x3F); - int green2 = Convert6To8((c2 >> 5) & 0x3F); - int blue1 = Convert5To8((c1 >> 11) & 0x1F); - int blue2 = Convert5To8((c2 >> 11) & 0x1F); + int red1 = (c1 << 3) & 0xF8; + int red2 = (c2 << 3) & 0xF8; + int green1 = (c1 >> 3) & 0xFC; + int green2 = (c2 >> 3) & 0xFC; + int blue1 = (c1 >> 8) & 0xF8; + int blue2 = (c2 >> 8) & 0xF8; // Keep alpha zero for non-DXT1 to skip masking the colors. int alpha = ignore1bitAlpha ? 0 : 255; colors_[0] = makecol(red1, green1, blue1, alpha); colors_[1] = makecol(red2, green2, blue2, alpha); - if (c1 > c2 || ignore1bitAlpha) { - int red3 = mul_3_8(red2 - red1); - int green3 = mul_3_8(green2 - green1); - int blue3 = mul_3_8(blue2 - blue1); - colors_[2] = makecol(red1 + red3, green1 + green3, blue1 + blue3, alpha); - colors_[3] = makecol(red2 - red3, green2 - green3, blue2 - blue3, alpha); + if (c1 > c2) { + colors_[2] = makecol(mix_2_3(red1, red2), mix_2_3(green1, green2), mix_2_3(blue1, blue2), alpha); + colors_[3] = makecol(mix_2_3(red2, red1), mix_2_3(green2, green1), mix_2_3(blue2, blue1), alpha); } else { - // Average - int red3 = (red1 + red2 + 1) / 2; - int green3 = (green1 + green2 + 1) / 2; - int blue3 = (blue1 + blue2 + 1) / 2; - colors_[2] = makecol(red3, green3, blue3, 255); - // Color2 but transparent - colors_[3] = makecol(red2, green2, blue2, 0); + // Average - these are always left shifted, so no need to worry about ties. + int red3 = (red1 + red2) / 2; + int green3 = (green1 + green2) / 2; + int blue3 = (blue1 + blue2) / 2; + colors_[2] = makecol(red3, green3, blue3, alpha); + colors_[3] = makecol(0, 0, 0, 0); } } @@ -390,13 +385,13 @@ static inline u8 lerp8(const DXT5Block *src, int n) { // These weights translate alpha1/alpha2 to fixed 8.8 point, pre-divided by 7. int weight1 = ((7 - n) << 8) / 7; int weight2 = (n << 8) / 7; - return (u8)((src->alpha1 * weight1 + src->alpha2 * weight2) >> 8); + return (u8)((src->alpha1 * weight1 + src->alpha2 * weight2 + 255) >> 8); } static inline u8 lerp6(const DXT5Block *src, int n) { int weight1 = ((5 - n) << 8) / 5; int weight2 = (n << 8) / 5; - return (u8)((src->alpha1 * weight1 + src->alpha2 * weight2) >> 8); + return (u8)((src->alpha1 * weight1 + src->alpha2 * weight2 + 255) >> 8); } void DXTDecoder::DecodeAlphaDXT5(const DXT5Block *src) { @@ -436,8 +431,7 @@ void DXTDecoder::WriteColorsDXT3(u32 *dst, const DXT3Block *src, int pitch, int int colordata = src->color.lines[y]; u32 alphadata = src->alphaLines[y]; for (int x = 0; x < 4; x++) { - const u8 a4 = alphadata & 0xF; - dst[x] = colors_[colordata & 3] | (a4 << 24) | (a4 << 28); + dst[x] = colors_[colordata & 3] | (alphadata << 28); colordata >>= 2; alphadata >>= 4; } diff --git a/GPU/Common/TextureDecoder.h b/GPU/Common/TextureDecoder.h index 30054168bd..35ffa8400f 100644 --- a/GPU/Common/TextureDecoder.h +++ b/GPU/Common/TextureDecoder.h @@ -49,7 +49,7 @@ void DoUnswizzleTex16Basic(const u8 *texptr, u32 *ydestp, int bxc, int byc, u32 #define DoReliableHash32 XXH32 #define DoReliableHash64 XXH64 -#ifdef _M_X64 +#if defined(_M_X64) || defined(ARM64) #define DoReliableHash XXH64 typedef u64 ReliableHashType; #else @@ -58,7 +58,7 @@ typedef u32 ReliableHashType; #endif // For ARM64, NEON is mandatory, so we also statically link. -#elif PPSSPP_ARCH(ARM64) +#elif PPSSPP_ARCH(ARM64) || defined(ARM64) #define DoQuickTexHash QuickTexHashNEON #define StableQuickTexHash QuickTexHashNEON #define DoUnswizzleTex16 DoUnswizzleTex16NEON diff --git a/GPU/Common/TransformCommon.cpp b/GPU/Common/TransformCommon.cpp index a80b2769e5..7e74f321a7 100644 --- a/GPU/Common/TransformCommon.cpp +++ b/GPU/Common/TransformCommon.cpp @@ -107,9 +107,9 @@ void Lighter::Light(float colorOut0[4], float colorOut1[4], const float colorIn[ Vec3f lightDir(0, 0, 0); if (type == GE_LIGHTTYPE_DIRECTIONAL) - toLight = Vec3f(&lpos[l * 3]); // lightdir is for spotlights + toLight = Vec3Packedf(&lpos[l * 3]); // lightdir is for spotlights else - toLight = Vec3f(&lpos[l * 3]) - pos; + toLight = Vec3Packedf(&lpos[l * 3]) - pos; bool doSpecular = gstate.isUsingSpecularLight(l); bool poweredDiffuse = gstate.isUsingPoweredDiffuseLight(l); @@ -139,7 +139,7 @@ void Lighter::Light(float colorOut0[4], float colorOut1[4], const float colorIn[ break; case GE_LIGHTTYPE_SPOT: case GE_LIGHTTYPE_UNKNOWN: - lightDir = Vec3f(&ldir[l * 3]); + lightDir = Vec3Packedf(&ldir[l * 3]); angle = Dot(toLight.Normalized(), lightDir.Normalized()); if (angle >= lcutoff[l]) lightScale = clamp(1.0f / (latt[l * 3] + latt[l * 3 + 1] * distanceToLight + latt[l * 3 + 2] * distanceToLight*distanceToLight), 0.0f, 1.0f) * powf(angle, lconv[l]); diff --git a/GPU/D3D11/DepalettizeShaderD3D11.cpp b/GPU/D3D11/DepalettizeShaderD3D11.cpp index 88520f404b..834b2a5a3e 100644 --- a/GPU/D3D11/DepalettizeShaderD3D11.cpp +++ b/GPU/D3D11/DepalettizeShaderD3D11.cpp @@ -33,21 +33,22 @@ #define SHADERLOG #endif -static const char *depalVShaderHLSL = -"struct VS_IN {\n" -" float3 a_position : POSITION;\n" -" float2 a_texcoord0 : TEXCOORD0;\n" -"};\n" -"struct VS_OUT {\n" -" float2 Texcoord : TEXCOORD0;\n" -" float4 Position : SV_Position;\n" -"};\n" -"VS_OUT main(VS_IN input) {\n" -" VS_OUT output;\n" -" output.Texcoord = input.a_texcoord0;\n" -" output.Position = float4(input.a_position, 1.0);\n" -" return output;\n" -"}\n"; +static const char *depalVShaderHLSL = R"( +struct VS_IN { + float3 a_position : POSITION; + float2 a_texcoord0 : TEXCOORD0; +}; +struct VS_OUT { + float2 Texcoord : TEXCOORD0; + float4 Position : SV_Position; +}; +VS_OUT main(VS_IN input) { + VS_OUT output; + output.Texcoord = input.a_texcoord0; + output.Position = float4(input.a_position, 1.0); + return output; +} +)"; static const D3D11_INPUT_ELEMENT_DESC g_DepalVertexElements[] = { { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, }, diff --git a/GPU/D3D11/DrawEngineD3D11.cpp b/GPU/D3D11/DrawEngineD3D11.cpp index e7752017dc..3e52cf83ef 100644 --- a/GPU/D3D11/DrawEngineD3D11.cpp +++ b/GPU/D3D11/DrawEngineD3D11.cpp @@ -137,6 +137,8 @@ void DrawEngineD3D11::DestroyDeviceObjects() { ClearTrackedVertexArrays(); ClearInputLayoutMap(); delete tessDataTransferD3D11; + tessDataTransferD3D11 = nullptr; + tessDataTransfer = nullptr; delete pushVerts_; delete pushInds_; depthStencilCache_.Iterate([&](const uint64_t &key, ID3D11DepthStencilState *ds) { @@ -655,7 +657,7 @@ rotateVBO: int scissorX2 = gstate.getScissorX2() + 1; int scissorY2 = gstate.getScissorY2() + 1; framebufferManager_->SetSafeSize(scissorX2, scissorY2); - if (g_Config.bBlockTransferGPU && (gstate_c.featureFlags & GPU_USE_CLEAR_RAM_HACK) && gstate.isClearModeColorMask() && (gstate.isClearModeAlphaMask() || gstate.FrameBufFormat() == GE_FORMAT_565)) { + if ((gstate_c.featureFlags & GPU_USE_CLEAR_RAM_HACK) && gstate.isClearModeColorMask() && (gstate.isClearModeAlphaMask() || gstate.FrameBufFormat() == GE_FORMAT_565)) { int scissorX1 = gstate.getScissorX1(); int scissorY1 = gstate.getScissorY1(); framebufferManager_->ApplyClearToMemory(scissorX1, scissorY1, scissorX2, scissorY2, clearColor); diff --git a/GPU/D3D11/FramebufferManagerD3D11.cpp b/GPU/D3D11/FramebufferManagerD3D11.cpp index bb6ee6b660..785db51eb5 100644 --- a/GPU/D3D11/FramebufferManagerD3D11.cpp +++ b/GPU/D3D11/FramebufferManagerD3D11.cpp @@ -512,9 +512,6 @@ static void CopyPixelDepthOnly(u32 *dstp, const u32 *srcp, size_t c) { } void FramebufferManagerD3D11::BlitFramebufferDepth(VirtualFramebuffer *src, VirtualFramebuffer *dst) { - if (g_Config.bDisableSlowFramebufEffects) { - return; - } bool matchingDepthBuffer = src->z_address == dst->z_address && src->z_stride != 0 && dst->z_stride != 0; bool matchingSize = src->width == dst->width && src->height == dst->height; bool matchingRenderSize = src->renderWidth == dst->renderWidth && src->renderHeight == dst->renderHeight; @@ -537,7 +534,7 @@ void FramebufferManagerD3D11::BindFramebufferAsColorTexture(int stage, VirtualFr // currentRenderVfb_ will always be set when this is called, except from the GE debugger. // Let's just not bother with the copy in that case. bool skipCopy = (flags & BINDFBCOLOR_MAY_COPY) == 0; - if (GPUStepping::IsStepping() || g_Config.bDisableSlowFramebufEffects) { + if (GPUStepping::IsStepping()) { skipCopy = true; } // Currently rendering to this framebuffer. Need to make a copy. @@ -553,7 +550,7 @@ void FramebufferManagerD3D11::BindFramebufferAsColorTexture(int stage, VirtualFr } else { draw_->BindFramebufferAsTexture(framebuffer->fbo, stage, Draw::FB_COLOR_BIT, 0); } - } else if (framebuffer != currentRenderVfb_) { + } else if (framebuffer != currentRenderVfb_ || (flags & BINDFBCOLOR_FORCE_SELF) != 0) { draw_->BindFramebufferAsTexture(framebuffer->fbo, stage, Draw::FB_COLOR_BIT, 0); } else { ERROR_LOG_REPORT_ONCE(d3d11SelfTexture, G3D, "Attempting to texture from target (src=%08x / target=%08x / flags=%d)", framebuffer->fb_address, currentRenderVfb_->fb_address, flags); @@ -687,7 +684,7 @@ void FramebufferManagerD3D11::PackDepthbuffer(VirtualFramebuffer *vfb, int x, in return; } - const u32 z_address = (0x04000000) | vfb->z_address; + const u32 z_address = vfb->z_address; // TODO } diff --git a/GPU/D3D11/GPU_D3D11.cpp b/GPU/D3D11/GPU_D3D11.cpp index e29f46e296..e0ee48ef05 100644 --- a/GPU/D3D11/GPU_D3D11.cpp +++ b/GPU/D3D11/GPU_D3D11.cpp @@ -77,7 +77,7 @@ GPU_D3D11::GPU_D3D11(GraphicsContext *gfxCtx, Draw::DrawContext *draw) stockD3D11.Create(device_); - shaderManagerD3D11_ = new ShaderManagerD3D11(device_, context_, featureLevel); + shaderManagerD3D11_ = new ShaderManagerD3D11(draw, device_, context_, featureLevel); framebufferManagerD3D11_ = new FramebufferManagerD3D11(draw); framebufferManager_ = framebufferManagerD3D11_; textureCacheD3D11_ = new TextureCacheD3D11(draw); diff --git a/GPU/D3D11/ShaderManagerD3D11.cpp b/GPU/D3D11/ShaderManagerD3D11.cpp index acc4e7160f..4bd4154c3e 100644 --- a/GPU/D3D11/ShaderManagerD3D11.cpp +++ b/GPU/D3D11/ShaderManagerD3D11.cpp @@ -27,6 +27,7 @@ #include "math/math_util.h" #include "math/dataconv.h" #include "file/vfs.h" +#include "thin3d/thin3d.h" #include "util/text/utf8.h" #include "Common/Common.h" #include "Core/Config.h" @@ -96,9 +97,9 @@ ShaderManagerD3D11::ShaderManagerD3D11(ID3D11Device *device, ID3D11DeviceContext memset(&ub_lights, 0, sizeof(ub_lights)); memset(&ub_bones, 0, sizeof(ub_bones)); - INFO_LOG(G3D, "sizeof(ub_base): %d", (int)sizeof(ub_base)); - INFO_LOG(G3D, "sizeof(ub_lights): %d", (int)sizeof(ub_lights)); - INFO_LOG(G3D, "sizeof(ub_bones): %d", (int)sizeof(ub_bones)); + static_assert(sizeof(ub_base) <= 512, "ub_base grew too big"); + static_assert(sizeof(ub_lights) <= 512, "ub_lights grew too big"); + static_assert(sizeof(ub_bones) <= 384, "ub_bones grew too big"); D3D11_BUFFER_DESC desc{sizeof(ub_base), D3D11_USAGE_DYNAMIC, D3D11_BIND_CONSTANT_BUFFER, D3D11_CPU_ACCESS_WRITE }; ASSERT_SUCCESS(device_->CreateBuffer(&desc, nullptr, &push_base)); @@ -195,7 +196,7 @@ void ShaderManagerD3D11::GetShaders(int prim, u32 vertType, D3D11VertexShader ** if (gstate_c.IsDirty(DIRTY_FRAGMENTSHADER_STATE)) { gstate_c.Clean(DIRTY_FRAGMENTSHADER_STATE); - ComputeFragmentShaderID(&FSID); + ComputeFragmentShaderID(&FSID, draw_->GetBugs()); } else { FSID = lastFSID_; } diff --git a/GPU/D3D11/ShaderManagerD3D11.h b/GPU/D3D11/ShaderManagerD3D11.h index 4b7702946c..fa98fce347 100644 --- a/GPU/D3D11/ShaderManagerD3D11.h +++ b/GPU/D3D11/ShaderManagerD3D11.h @@ -81,7 +81,7 @@ class D3D11PushBuffer; class ShaderManagerD3D11 : public ShaderManagerCommon { public: - ShaderManagerD3D11(ID3D11Device *device, ID3D11DeviceContext *context, D3D_FEATURE_LEVEL featureLevel); + ShaderManagerD3D11(Draw::DrawContext *draw, ID3D11Device *device, ID3D11DeviceContext *context, D3D_FEATURE_LEVEL featureLevel); ~ShaderManagerD3D11(); void GetShaders(int prim, u32 vertType, D3D11VertexShader **vshader, D3D11FragmentShader **fshader, bool useHWTransform); diff --git a/GPU/D3D11/StateMappingD3D11.cpp b/GPU/D3D11/StateMappingD3D11.cpp index 5a4321becf..672f319c9a 100644 --- a/GPU/D3D11/StateMappingD3D11.cpp +++ b/GPU/D3D11/StateMappingD3D11.cpp @@ -223,7 +223,7 @@ void DrawEngineD3D11::ApplyDrawState(int prim) { #endif // Let's not write to alpha if stencil isn't enabled. - if (!gstate.isStencilTestEnabled()) { + if (IsStencilTestOutputDisabled()) { amask = false; } else { // If the stencil type is set to KEEP, we shouldn't write to the stencil/alpha channel. diff --git a/GPU/D3D11/StencilBufferD3D11.cpp b/GPU/D3D11/StencilBufferD3D11.cpp index f489f5838a..7c9e791cca 100644 --- a/GPU/D3D11/StencilBufferD3D11.cpp +++ b/GPU/D3D11/StencilBufferD3D11.cpp @@ -71,6 +71,7 @@ VS_OUT main(VS_IN In) { // TODO : If SV_StencilRef is available (D3D11.3) then this can be done in a single pass. bool FramebufferManagerD3D11::NotifyStencilUpload(u32 addr, int size, bool skipZero) { + addr &= 0x3FFFFFFF; if (!MayIntersectFramebuffer(addr)) { return false; } @@ -78,7 +79,7 @@ bool FramebufferManagerD3D11::NotifyStencilUpload(u32 addr, int size, bool skipZ VirtualFramebuffer *dstBuffer = 0; for (size_t i = 0; i < vfbs_.size(); ++i) { VirtualFramebuffer *vfb = vfbs_[i]; - if (MaskedEqual(vfb->fb_address, addr)) { + if (vfb->fb_address == addr) { dstBuffer = vfb; } } diff --git a/GPU/D3D11/TextureCacheD3D11.cpp b/GPU/D3D11/TextureCacheD3D11.cpp index 5c2259a183..f23752cc3d 100644 --- a/GPU/D3D11/TextureCacheD3D11.cpp +++ b/GPU/D3D11/TextureCacheD3D11.cpp @@ -277,7 +277,7 @@ public: }; TextureShaderApplierD3D11(ID3D11DeviceContext *context, ID3D11PixelShader *pshader, ID3D11Buffer *dynamicBuffer, float bufferW, float bufferH, int renderW, int renderH, float xoff, float yoff) - : context_(context), pshader_(pshader), bufferW_(bufferW), bufferH_(bufferH), renderW_(renderW), renderH_(renderH) { + : context_(context), pshader_(pshader), vbuffer_(dynamicBuffer), bufferW_(bufferW), bufferH_(bufferH), renderW_(renderW), renderH_(renderH) { static const Pos pos[4] = { { -1, 1, 0 }, { 1, 1, 0 }, @@ -297,11 +297,6 @@ public: verts_[i].pos.y += yoff; verts_[i].uv = uv[i]; } - D3D11_MAPPED_SUBRESOURCE map; - context->Map(dynamicBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &map); - memcpy(map.pData, &verts_[0], 4 * 5 * sizeof(float)); - context->Unmap(dynamicBuffer, 0); - vbuffer_ = dynamicBuffer; } void ApplyBounds(const KnownVertexBounds &bounds, u32 uoff, u32 voff, float xoff, float yoff) { @@ -320,28 +315,34 @@ public: const float left = u1 * invHalfWidth - 1.0f + xoff; const float right = u2 * invHalfWidth - 1.0f + xoff; - const float top = v1 * invHalfHeight - 1.0f + yoff; - const float bottom = v2 * invHalfHeight - 1.0f + yoff; + const float top = (bufferH_ - v1) * invHalfHeight - 1.0f + yoff; + const float bottom = (bufferH_ - v2) * invHalfHeight - 1.0f + yoff; + float z = 0.0f; - // Points are: BL, BR, TL, TR. - verts_[0].pos = Pos(left, bottom, z); - verts_[1].pos = Pos(right, bottom, z); - verts_[2].pos = Pos(left, top, z); - verts_[3].pos = Pos(right, top, z); + verts_[0].pos = Pos(left, top, z); + verts_[1].pos = Pos(right, top, z); + verts_[2].pos = Pos(left, bottom, z); + verts_[3].pos = Pos(right, bottom, z); // And also the UVs, same order. const float uvleft = u1 * invWidth; const float uvright = u2 * invWidth; const float uvtop = v1 * invHeight; const float uvbottom = v2 * invHeight; - verts_[0].uv = UV(uvleft, uvbottom); - verts_[1].uv = UV(uvright, uvbottom); - verts_[2].uv = UV(uvleft, uvtop); - verts_[3].uv = UV(uvright, uvtop); + + verts_[0].uv = UV(uvleft, uvtop); + verts_[1].uv = UV(uvright, uvtop); + verts_[2].uv = UV(uvleft, uvbottom); + verts_[3].uv = UV(uvright, uvbottom); // We need to reapply the texture next time since we cropped UV. gstate_c.Dirty(DIRTY_TEXTURE_PARAMS); } + + D3D11_MAPPED_SUBRESOURCE map; + context_->Map(vbuffer_, 0, D3D11_MAP_WRITE_DISCARD, 0, &map); + memcpy(map.pData, &verts_[0], 4 * 5 * sizeof(float)); + context_->Unmap(vbuffer_, 0); } void Use(ID3D11VertexShader *vshader, ID3D11InputLayout *decl) { @@ -398,11 +399,11 @@ void TextureCacheD3D11::ApplyTextureFramebuffer(TexCacheEntry *entry, VirtualFra shaderApply.ApplyBounds(gstate_c.vertBounds, gstate_c.curTextureXOffset, gstate_c.curTextureYOffset, xoff, yoff); shaderApply.Use(depalShaderCache_->GetDepalettizeVertexShader(), depalShaderCache_->GetInputLayout()); + draw_->BindFramebufferAsRenderTarget(depalFBO, { Draw::RPAction::DONT_CARE, Draw::RPAction::DONT_CARE, Draw::RPAction::DONT_CARE }); context_->PSSetShaderResources(3, 1, &clutTexture); context_->PSSetSamplers(3, 1, &stockD3D11.samplerPoint2DWrap); - framebufferManagerD3D11_->BindFramebufferAsColorTexture(0, framebuffer, BINDFBCOLOR_SKIP_COPY); + framebufferManagerD3D11_->BindFramebufferAsColorTexture(0, framebuffer, BINDFBCOLOR_SKIP_COPY | BINDFBCOLOR_FORCE_SELF); context_->PSSetSamplers(0, 1, &stockD3D11.samplerPoint2DWrap); - draw_->BindFramebufferAsRenderTarget(depalFBO, { Draw::RPAction::DONT_CARE, Draw::RPAction::DONT_CARE, Draw::RPAction::DONT_CARE }); shaderApply.Shade(); framebufferManagerD3D11_->RebindFramebuffer(); diff --git a/GPU/Debugger/Debugger.cpp b/GPU/Debugger/Debugger.cpp index 088836c2ff..2d5da1af3a 100644 --- a/GPU/Debugger/Debugger.cpp +++ b/GPU/Debugger/Debugger.cpp @@ -25,6 +25,11 @@ namespace GPUDebug { static bool active = false; static bool inited = false; static BreakNext breakNext = BreakNext::NONE; +static int breakAtCount = -1; + +static int primsLastFrame = 0; +static int primsThisFrame = 0; +static int thisFlipNum = 0; static void Init() { if (!inited) { @@ -40,6 +45,7 @@ void SetActive(bool flag) { active = flag; if (!active) { breakNext = BreakNext::NONE; + breakAtCount = -1; GPUStepping::ResumeFromStepping(); } } @@ -51,9 +57,10 @@ bool IsActive() { void SetBreakNext(BreakNext next) { SetActive(true); breakNext = next; + breakAtCount = -1; if (next == BreakNext::TEX) { GPUBreakpoints::AddTextureChangeTempBreakpoint(); - } else if (next == BreakNext::PRIM) { + } else if (next == BreakNext::PRIM || next == BreakNext::COUNT) { GPUBreakpoints::AddCmdBreakpoint(GE_CMD_PRIM, true); GPUBreakpoints::AddCmdBreakpoint(GE_CMD_BEZIER, true); GPUBreakpoints::AddCmdBreakpoint(GE_CMD_SPLINE, true); @@ -64,11 +71,39 @@ void SetBreakNext(BreakNext next) { GPUStepping::ResumeFromStepping(); } +void SetBreakCount(int c, bool relative) { + if (relative) { + breakAtCount = primsThisFrame + c; + } else { + breakAtCount = c; + } +} + +static bool IsBreakpoint(u32 pc, u32 op) { + if (breakNext == BreakNext::OP) { + return true; + } else if (breakNext == BreakNext::COUNT) { + return primsThisFrame == breakAtCount; + } else { + return GPUBreakpoints::IsBreakpoint(pc, op); + } +} + void NotifyCommand(u32 pc) { if (!active) return; u32 op = Memory::ReadUnchecked_U32(pc); - if (breakNext == BreakNext::OP || GPUBreakpoints::IsBreakpoint(pc, op)) { + u32 cmd = op >> 24; + if (thisFlipNum != gpuStats.numFlips) { + primsLastFrame = primsThisFrame; + primsThisFrame = 0; + thisFlipNum = gpuStats.numFlips; + } + if (cmd == GE_CMD_PRIM || cmd == GE_CMD_BEZIER || cmd == GE_CMD_SPLINE) { + primsThisFrame++; + } + + if (IsBreakpoint(pc, op)) { GPUBreakpoints::ClearTempBreakpoints(); auto info = gpuDebug->DissassembleOp(pc); @@ -100,4 +135,12 @@ void NotifyTextureAttachment(u32 texaddr) { return; } +int PrimsThisFrame() { + return primsThisFrame; +} + +int PrimsLastFrame() { + return primsLastFrame; +} + } diff --git a/GPU/Debugger/Debugger.h b/GPU/Debugger/Debugger.h index 2a45f93ba0..15be467cda 100644 --- a/GPU/Debugger/Debugger.h +++ b/GPU/Debugger/Debugger.h @@ -30,12 +30,14 @@ enum class BreakNext { FRAME, PRIM, CURVE, + COUNT, }; void SetActive(bool flag); bool IsActive(); void SetBreakNext(BreakNext next); +void SetBreakCount(int c, bool relative = false); // While debugging is active, these may block. void NotifyCommand(u32 pc); @@ -43,4 +45,7 @@ void NotifyDraw(); void NotifyDisplay(u32 framebuf, u32 stride, int format); void NotifyTextureAttachment(u32 texaddr); +int PrimsThisFrame(); +int PrimsLastFrame(); + } diff --git a/GPU/Debugger/Record.cpp b/GPU/Debugger/Record.cpp index 1fa237a600..0014d5eddf 100644 --- a/GPU/Debugger/Record.cpp +++ b/GPU/Debugger/Record.cpp @@ -1,4 +1,4 @@ -ï»ż// Copyright (c) 2017- PPSSPP Project. +// Copyright (c) 2017- PPSSPP Project. // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include "base/stringutil.h" @@ -43,11 +44,15 @@ namespace GPURecord { static const char *HEADER = "PPSSPPGE"; -static const int VERSION = 2; +// Version 1: Uncompressed +// Version 2: Uses snappy +// Version 3: Adds FRAMEBUF0-FRAMEBUF9 +static const int VERSION = 3; +static const int MIN_VERSION = 2; static bool active = false; static bool nextFrame = false; -static bool writePending = false; +static int flipLastAction = -1; static std::function writeCallback; enum class CommandType : u8 { @@ -70,6 +75,15 @@ enum class CommandType : u8 { TEXTURE5 = 0x15, TEXTURE6 = 0x16, TEXTURE7 = 0x17, + + FRAMEBUF0 = 0x18, + FRAMEBUF1 = 0x19, + FRAMEBUF2 = 0x1A, + FRAMEBUF3 = 0x1B, + FRAMEBUF4 = 0x1C, + FRAMEBUF5 = 0x1D, + FRAMEBUF6 = 0x1E, + FRAMEBUF7 = 0x1F, }; #pragma pack(push, 1) @@ -86,6 +100,7 @@ static std::vector pushbuf; static std::vector commands; static std::vector lastRegisters; static std::vector lastTextures; +static std::set lastRenderTargets; // TODO: Maybe move execute to another file? class DumpExecute { @@ -109,6 +124,7 @@ private: void MemcpyDest(u32 ptr, u32 sz); void Memcpy(u32 ptr, u32 sz); void Texture(int level, u32 ptr, u32 sz); + void Framebuf(int level, u32 ptr, u32 sz); void Display(u32 ptr, u32 sz); u32 execMemcpyDest = 0; @@ -358,7 +374,7 @@ static void FlushRegisters() { static std::string GenRecordingFilename() { const std::string dumpDir = GetSysDirectory(DIRECTORY_DUMP); - const std::string prefix = dumpDir + "/" + g_paramSFO.GetDiscID(); + const std::string prefix = dumpDir + g_paramSFO.GetDiscID(); File::CreateFullPath(dumpDir); @@ -372,24 +388,13 @@ static std::string GenRecordingFilename() { return StringFromFormat("%s_%04d.ppdmp", prefix.c_str(), 9999); } -static void EmitDisplayBuf() { - struct DisplayBufData { - PSPPointer topaddr; - u32 linesize, pixelFormat; - }; - - DisplayBufData disp{}; - __DisplayGetFramebuf(&disp.topaddr, &disp.linesize, &disp.pixelFormat, 0); - - u32 ptr = (u32)pushbuf.size(); - u32 sz = (u32)sizeof(disp); - pushbuf.resize(pushbuf.size() + sz); - memcpy(pushbuf.data() + ptr, &disp, sz); - - commands.push_back({CommandType::DISPLAY, sz, ptr}); -} - static void BeginRecording() { + active = true; + nextFrame = false; + lastTextures.clear(); + lastRenderTargets.clear(); + flipLastAction = gpuStats.numFlips; + u32 ptr = (u32)pushbuf.size(); u32 sz = 512 * 4; pushbuf.resize(pushbuf.size() + sz); @@ -412,7 +417,6 @@ static void WriteCompressed(FILE *fp, const void *p, size_t sz) { static std::string WriteRecording() { FlushRegisters(); - EmitDisplayBuf(); const std::string filename = GenRecordingFilename(); @@ -528,13 +532,36 @@ static void EmitTextureData(int level, u32 texaddr) { int bufw = GetTextureBufw(level, texaddr, format); int extraw = w > bufw ? w - bufw : 0; u32 sizeInRAM = (textureBitsPerPixel[format] * (bufw * h + extraw)) / 8; + const bool isTarget = lastRenderTargets.find(texaddr) != lastRenderTargets.end(); + CommandType type = CommandType((int)CommandType::TEXTURE0 + level); + const u8 *p = Memory::GetPointerUnchecked(texaddr); u32 bytes = Memory::ValidSize(texaddr, sizeInRAM); - if (Memory::IsValidAddress(texaddr)) { - FlushRegisters(); + std::vector framebufData; - CommandType type = CommandType((int)CommandType::TEXTURE0 + level); - const u8 *p = Memory::GetPointerUnchecked(texaddr); + if (Memory::IsVRAMAddress(texaddr)) { + struct FramebufData { + u32 addr; + int bufw; + u32 flags; + u32 pad; + }; + + // The isTarget flag is mostly used for replay of dumps on a PSP. + u32 flags = isTarget ? 1 : 0; + FramebufData framebuf{ texaddr, bufw, flags }; + framebufData.resize(sizeof(framebuf) + bytes); + memcpy(&framebufData[0], &framebuf, sizeof(framebuf)); + memcpy(&framebufData[sizeof(framebuf)], p, bytes); + p = &framebufData[0]; + + // Okay, now we'll just emit this instead. + type = CommandType((int)CommandType::FRAMEBUF0 + level); + bytes += (u32)sizeof(framebuf); + } + + if (bytes > 0) { + FlushRegisters(); // Dumps are huge - let's try to find this already emitted. for (u32 prevptr : lastTextures) { @@ -559,6 +586,9 @@ static void FlushPrimState(int vcount) { // TODO: Eventually, how do we handle texturing from framebuf/zbuf? // TODO: Do we need to preload color/depth/stencil (in case from last frame)? + lastRenderTargets.insert(PSP_GetVidMemBase() | gstate.getFrameBufRawAddress()); + lastRenderTargets.insert(PSP_GetVidMemBase() | gstate.getDepthBufRawAddress()); + // We re-flush textures always in case the game changed them... kinda expensive. // TODO: Dirty textures on transfer/stall/etc. somehow? // TODO: Or maybe de-dup by validating if it has changed? @@ -579,10 +609,10 @@ static void FlushPrimState(int vcount) { u32 vbytes = 0; GetVertDataSizes(vcount, indices, vbytes, ibytes); - if (indices) { + if (indices && ibytes > 0) { EmitCommandWithRAM(CommandType::INDICES, indices, ibytes); } - if (verts) { + if (verts && vbytes > 0) { EmitCommandWithRAM(CommandType::VERTICES, verts, vbytes); } } @@ -607,7 +637,9 @@ static void EmitTransfer(u32 op) { u32 srcBytes = ((srcY + height - 1) * srcStride + (srcX + width)) * bpp; srcBytes = Memory::ValidSize(srcBasePtr, srcBytes); - EmitCommandWithRAM(CommandType::TRANSFERSRC, Memory::GetPointerUnchecked(srcBasePtr), srcBytes); + if (srcBytes != 0) { + EmitCommandWithRAM(CommandType::TRANSFERSRC, Memory::GetPointerUnchecked(srcBasePtr), srcBytes); + } lastRegisters.push_back(op); } @@ -617,7 +649,9 @@ static void EmitClut(u32 op) { u32 bytes = (op & 0x3F) * 32; bytes = Memory::ValidSize(addr, bytes); - EmitCommandWithRAM(CommandType::CLUT, Memory::GetPointerUnchecked(addr), bytes); + if (bytes != 0) { + EmitCommandWithRAM(CommandType::CLUT, Memory::GetPointerUnchecked(addr), bytes); + } lastRegisters.push_back(op); } @@ -647,6 +681,7 @@ bool IsActivePending() { bool Activate() { if (!nextFrame) { nextFrame = true; + flipLastAction = gpuStats.numFlips; return true; } return false; @@ -663,8 +698,8 @@ static void FinishRecording() { pushbuf.clear(); NOTICE_LOG(SYSTEM, "Recording finished"); - writePending = false; active = false; + flipLastAction = gpuStats.numFlips; if (writeCallback) writeCallback(filename); @@ -675,10 +710,6 @@ void NotifyCommand(u32 pc) { if (!active) { return; } - if (writePending) { - FinishRecording(); - return; - } const u32 op = Memory::Read_U32(pc); const GECommand cmd = GECommand(op >> 24); @@ -739,7 +770,9 @@ void NotifyMemcpy(u32 dest, u32 src, u32 sz) { memcpy(pushbuf.data() + cmd.ptr, &dest, sizeof(dest)); sz = Memory::ValidSize(dest, sz); - EmitCommandWithRAM(CommandType::MEMCPYDATA, Memory::GetPointer(dest), sz); + if (sz != 0) { + EmitCommandWithRAM(CommandType::MEMCPYDATA, Memory::GetPointer(dest), sz); + } } } @@ -771,17 +804,66 @@ void NotifyUpload(u32 dest, u32 sz) { NotifyMemcpy(dest, dest, sz); } -void NotifyFrame() { - if (active && !writePending && !commands.empty()) { - // Delay write until the first command of the next frame, so we get the right display buf. - NOTICE_LOG(SYSTEM, "Recording complete - waiting to get display buffer"); +void NotifyDisplay(u32 framebuf, int stride, int fmt) { + bool writePending = false; + if (active && !commands.empty()) { writePending = true; } if (nextFrame && (gstate_c.skipDrawReason & SKIPDRAW_SKIPFRAME) == 0) { - NOTICE_LOG(SYSTEM, "Recording starting..."); - active = true; - nextFrame = false; - lastTextures.clear(); + NOTICE_LOG(SYSTEM, "Recording starting on display..."); + BeginRecording(); + } + if (!active) { + return; + } + + struct DisplayBufData { + PSPPointer topaddr; + int linesize, pixelFormat; + }; + + DisplayBufData disp{ framebuf, stride, fmt }; + + FlushRegisters(); + u32 ptr = (u32)pushbuf.size(); + u32 sz = (u32)sizeof(disp); + pushbuf.resize(pushbuf.size() + sz); + memcpy(pushbuf.data() + ptr, &disp, sz); + + commands.push_back({ CommandType::DISPLAY, sz, ptr }); + + if (writePending) { + NOTICE_LOG(SYSTEM, "Recording complete on display"); + FinishRecording(); + } +} + +void NotifyFrame() { + const bool noDisplayAction = flipLastAction + 4 < gpuStats.numFlips; + // We do this only to catch things that don't call NotifyDisplay. + if (active && !commands.empty() && noDisplayAction) { + NOTICE_LOG(SYSTEM, "Recording complete on frame"); + + struct DisplayBufData { + PSPPointer topaddr; + u32 linesize, pixelFormat; + }; + + DisplayBufData disp; + __DisplayGetFramebuf(&disp.topaddr, &disp.linesize, &disp.pixelFormat, 0); + + FlushRegisters(); + u32 ptr = (u32)pushbuf.size(); + u32 sz = (u32)sizeof(disp); + pushbuf.resize(pushbuf.size() + sz); + memcpy(pushbuf.data() + ptr, &disp, sz); + + commands.push_back({ CommandType::DISPLAY, sz, ptr }); + + FinishRecording(); + } + if (nextFrame && (gstate_c.skipDrawReason & SKIPDRAW_SKIPFRAME) == 0 && noDisplayAction) { + NOTICE_LOG(SYSTEM, "Recording starting on frame..."); BeginRecording(); } } @@ -790,7 +872,10 @@ void DumpExecute::SyncStall() { gpu->UpdateStall(execListID, execListPos); s64 listTicks = gpu->GetListTicks(execListID); if (listTicks != -1) { - currentMIPS->downcount -= listTicks - CoreTiming::GetTicks(); + s64 nowTicks = CoreTiming::GetTicks(); + if (listTicks > nowTicks) { + currentMIPS->downcount -= listTicks - nowTicks; + } } // Make sure downcount doesn't overflow. @@ -977,10 +1062,37 @@ void DumpExecute::Texture(int level, u32 ptr, u32 sz) { execListQueue.push_back((addrCmd << 24) | (psp & 0x00FFFFFF)); } +void DumpExecute::Framebuf(int level, u32 ptr, u32 sz) { + struct FramebufData { + u32 addr; + int bufw; + u32 flags; + u32 pad; + }; + + FramebufData *framebuf = (FramebufData *)(pushbuf.data() + ptr); + + u32 bufwCmd = GE_CMD_TEXBUFWIDTH0 + level; + u32 addrCmd = GE_CMD_TEXADDR0 + level; + execListQueue.push_back((bufwCmd << 24) | ((framebuf->addr >> 8) & 0x00FF0000) | framebuf->bufw); + execListQueue.push_back((addrCmd << 24) | (framebuf->addr & 0x00FFFFFF)); + lastBufw_[level] = framebuf->bufw; + + // And now also copy the data into VRAM (in case it wasn't actually rendered.) + u32 headerSize = (u32)sizeof(FramebufData); + u32 pspSize = sz - headerSize; + const bool isTarget = (framebuf->flags & 1) != 0; + // Could potentially always skip if !isTarget, but playing it safe for offset texture behavior. + if (Memory::IsValidRange(framebuf->addr, pspSize) && (!isTarget || !g_Config.bSoftwareRendering)) { + // Intentionally don't trigger an upload here. + Memory::MemcpyUnchecked(framebuf->addr, pushbuf.data() + ptr + headerSize, pspSize); + } +} + void DumpExecute::Display(u32 ptr, u32 sz) { struct DisplayBufData { PSPPointer topaddr; - u32 linesize, pixelFormat; + int linesize, pixelFormat; }; DisplayBufData *disp = (DisplayBufData *)(pushbuf.data() + ptr); @@ -1055,6 +1167,17 @@ bool DumpExecute::Run() { Texture((int)cmd.type - (int)CommandType::TEXTURE0, cmd.ptr, cmd.sz); break; + case CommandType::FRAMEBUF0: + case CommandType::FRAMEBUF1: + case CommandType::FRAMEBUF2: + case CommandType::FRAMEBUF3: + case CommandType::FRAMEBUF4: + case CommandType::FRAMEBUF5: + case CommandType::FRAMEBUF6: + case CommandType::FRAMEBUF7: + Framebuf((int)cmd.type - (int)CommandType::FRAMEBUF0, cmd.ptr, cmd.sz); + break; + case CommandType::DISPLAY: Display(cmd.ptr, cmd.sz); break; @@ -1097,7 +1220,7 @@ bool RunMountedReplay(const std::string &filename) { pspFileSystem.ReadFile(fp, header, sizeof(header)); pspFileSystem.ReadFile(fp, (u8 *)&version, sizeof(version)); - if (memcmp(header, HEADER, sizeof(header)) != 0 || version != VERSION) { + if (memcmp(header, HEADER, sizeof(header)) != 0 || version > VERSION || version < MIN_VERSION) { ERROR_LOG(SYSTEM, "Invalid GE dump or unsupported version"); pspFileSystem.CloseFile(fp); return false; diff --git a/GPU/Debugger/Record.h b/GPU/Debugger/Record.h index 230b361d19..020ce2ca8c 100644 --- a/GPU/Debugger/Record.h +++ b/GPU/Debugger/Record.h @@ -1,4 +1,4 @@ -ï»ż// Copyright (c) 2017- PPSSPP Project. +// Copyright (c) 2017- PPSSPP Project. // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -33,6 +33,7 @@ void NotifyCommand(u32 pc); void NotifyMemcpy(u32 dest, u32 src, u32 sz); void NotifyMemset(u32 dest, int v, u32 sz); void NotifyUpload(u32 dest, u32 sz); +void NotifyDisplay(u32 addr, int stride, int fmt); void NotifyFrame(); bool RunMountedReplay(const std::string &filename); diff --git a/GPU/Debugger/Stepping.cpp b/GPU/Debugger/Stepping.cpp index b277496556..bf5ddb4834 100644 --- a/GPU/Debugger/Stepping.cpp +++ b/GPU/Debugger/Stepping.cpp @@ -38,6 +38,7 @@ enum PauseAction { }; static bool isStepping; +// Number of times we've entered stepping, to detect a resume asynchronously. static int stepCounter = 0; static std::mutex pauseLock; diff --git a/GPU/Directx9/DepalettizeShaderDX9.cpp b/GPU/Directx9/DepalettizeShaderDX9.cpp index 08824b7a98..2365e41d58 100644 --- a/GPU/Directx9/DepalettizeShaderDX9.cpp +++ b/GPU/Directx9/DepalettizeShaderDX9.cpp @@ -36,21 +36,22 @@ static const int DEPAL_TEXTURE_OLD_AGE = 120; #define SHADERLOG #endif -static const char *depalVShaderHLSL = -"struct VS_IN {\n" -" float3 a_position : POSITION;\n" -" float2 a_texcoord0 : TEXCOORD0;\n" -"};\n" -"struct VS_OUT {\n" -" float4 Position : POSITION;\n" -" float2 Texcoord : TEXCOORD0;\n" -"};\n" -"VS_OUT main(VS_IN input) {\n" -" VS_OUT output;\n" -" output.Texcoord = input.a_texcoord0;\n" -" output.Position = float4(input.a_position, 1.0);\n" -" return output;\n" -"}\n"; +static const char *depalVShaderHLSL = R"( +struct VS_IN { + float3 a_position : POSITION; + float2 a_texcoord0 : TEXCOORD0; +}; +struct VS_OUT { + float4 Position : POSITION; + float2 Texcoord : TEXCOORD0; +}; +VS_OUT main(VS_IN input) { + VS_OUT output; + output.Texcoord = input.a_texcoord0; + output.Position = float4(input.a_position, 1.0); + return output; +} +)"; DepalShaderCacheDX9::DepalShaderCacheDX9(Draw::DrawContext *draw) : vertexShader_(nullptr) { device_ = (LPDIRECT3DDEVICE9)draw->GetNativeObject(Draw::NativeObject::DEVICE); diff --git a/GPU/Directx9/DrawEngineDX9.cpp b/GPU/Directx9/DrawEngineDX9.cpp index 0f1c0b62d3..9d02936e71 100644 --- a/GPU/Directx9/DrawEngineDX9.cpp +++ b/GPU/Directx9/DrawEngineDX9.cpp @@ -593,7 +593,7 @@ rotateVBO: int scissorX2 = gstate.getScissorX2() + 1; int scissorY2 = gstate.getScissorY2() + 1; framebufferManager_->SetSafeSize(scissorX2, scissorY2); - if (g_Config.bBlockTransferGPU && (gstate_c.featureFlags & GPU_USE_CLEAR_RAM_HACK) && gstate.isClearModeColorMask() && (gstate.isClearModeAlphaMask() || gstate.FrameBufFormat() == GE_FORMAT_565)) { + if ((gstate_c.featureFlags & GPU_USE_CLEAR_RAM_HACK) && gstate.isClearModeColorMask() && (gstate.isClearModeAlphaMask() || gstate.FrameBufFormat() == GE_FORMAT_565)) { int scissorX1 = gstate.getScissorX1(); int scissorY1 = gstate.getScissorY1(); framebufferManager_->ApplyClearToMemory(scissorX1, scissorY1, scissorX2, scissorY2, clearColor); diff --git a/GPU/Directx9/FramebufferDX9.cpp b/GPU/Directx9/FramebufferDX9.cpp index 88bddb3bee..f364685813 100644 --- a/GPU/Directx9/FramebufferDX9.cpp +++ b/GPU/Directx9/FramebufferDX9.cpp @@ -47,34 +47,33 @@ namespace DX9 { -static const char * vscode = - "struct VS_IN {\n" - " float4 ObjPos : POSITION;\n" - " float2 Uv : TEXCOORD0;\n" - "};" - "struct VS_OUT {\n" - " float4 ProjPos : POSITION;\n" - " float2 Uv : TEXCOORD0;\n" - "};\n" - "VS_OUT main( VS_IN In ) {\n" - " VS_OUT Out;\n" - " Out.ProjPos = In.ObjPos;\n" - " Out.Uv = In.Uv;\n" - " return Out;\n" - "}\n"; +static const char *vscode = R"( +struct VS_IN { + float4 ObjPos : POSITION; + float2 Uv : TEXCOORD0; +};" +struct VS_OUT { + float4 ProjPos : POSITION; + float2 Uv : TEXCOORD0; +}; +VS_OUT main( VS_IN In ) { + VS_OUT Out; + Out.ProjPos = In.ObjPos; + Out.Uv = In.Uv; + return Out; +} +)"; -//-------------------------------------------------------------------------------------- -// Pixel shader -//-------------------------------------------------------------------------------------- -static const char * pscode = - "sampler s: register(s0);\n" - "struct PS_IN {\n" - " float2 Uv : TEXCOORD0;\n" - "};\n" - "float4 main( PS_IN In ) : COLOR {\n" - " float4 c = tex2D(s, In.Uv);\n" - " return c;\n" - "}\n"; +static const char *pscode = R"( +sampler s: register(s0); +struct PS_IN { + float2 Uv : TEXCOORD0; +}; +float4 main( PS_IN In ) : COLOR { + float4 c = tex2D(s, In.Uv); + return c; +} +)"; static const D3DVERTEXELEMENT9 g_FramebufferVertexElements[] = { { 0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 }, @@ -395,10 +394,6 @@ static const D3DVERTEXELEMENT9 g_FramebufferVertexElements[] = { } void FramebufferManagerDX9::BlitFramebufferDepth(VirtualFramebuffer *src, VirtualFramebuffer *dst) { - if (g_Config.bDisableSlowFramebufEffects) { - return; - } - bool matchingDepthBuffer = src->z_address == dst->z_address && src->z_stride != 0 && dst->z_stride != 0; bool matchingSize = src->width == dst->width && src->height == dst->height; if (matchingDepthBuffer && matchingSize) { @@ -451,10 +446,10 @@ static const D3DVERTEXELEMENT9 g_FramebufferVertexElements[] = { // currentRenderVfb_ will always be set when this is called, except from the GE debugger. // Let's just not bother with the copy in that case. bool skipCopy = (flags & BINDFBCOLOR_MAY_COPY) == 0; - if (GPUStepping::IsStepping() || g_Config.bDisableSlowFramebufEffects) { + if (GPUStepping::IsStepping()) { skipCopy = true; } - if (!skipCopy && currentRenderVfb_ && framebuffer->fb_address == gstate.getFrameBufRawAddress()) { + if (!skipCopy && framebuffer == currentRenderVfb_) { // TODO: Maybe merge with bvfbs_? Not sure if those could be packing, and they're created at a different size. Draw::Framebuffer *renderCopy = GetTempFBO(TempFBO::COPY, framebuffer->renderWidth, framebuffer->renderHeight, (Draw::FBColorDepth)framebuffer->colorDepth); if (renderCopy) { @@ -585,7 +580,7 @@ static const D3DVERTEXELEMENT9 g_FramebufferVertexElements[] = { return; } - const u32 fb_address = (0x04000000) | vfb->fb_address; + const u32 fb_address = vfb->fb_address & 0x3FFFFFFF; const int dstBpp = vfb->format == GE_FORMAT_8888 ? 4 : 2; // We always need to convert from the framebuffer native format. @@ -627,7 +622,7 @@ static const D3DVERTEXELEMENT9 g_FramebufferVertexElements[] = { } // We always read the depth buffer in 24_8 format. - const u32 z_address = (0x04000000) | vfb->z_address; + const u32 z_address = vfb->z_address; DEBUG_LOG(FRAMEBUF, "Reading depthbuffer to mem at %08x for vfb=%08x", z_address, vfb->fb_address); @@ -732,7 +727,7 @@ static const D3DVERTEXELEMENT9 g_FramebufferVertexElements[] = { if (!vfb) { // If there's no vfb and we're drawing there, must be memory? - buffer = GPUDebugBuffer(Memory::GetPointer(fb_address | 0x04000000), fb_stride, 512, fb_format); + buffer = GPUDebugBuffer(Memory::GetPointer(fb_address), fb_stride, 512, fb_format); return true; } LPDIRECT3DSURFACE9 renderTarget = vfb->fbo ? (LPDIRECT3DSURFACE9)draw_->GetFramebufferAPITexture(vfb->fbo, Draw::FB_COLOR_BIT | Draw::FB_SURFACE_BIT, 0) : nullptr; @@ -809,7 +804,7 @@ static const D3DVERTEXELEMENT9 g_FramebufferVertexElements[] = { if (!vfb) { // If there's no vfb and we're drawing there, must be memory? - buffer = GPUDebugBuffer(Memory::GetPointer(z_address | 0x04000000), z_stride, 512, GPU_DBG_FORMAT_16BIT); + buffer = GPUDebugBuffer(Memory::GetPointer(z_address), z_stride, 512, GPU_DBG_FORMAT_16BIT); return true; } @@ -847,7 +842,7 @@ static const D3DVERTEXELEMENT9 g_FramebufferVertexElements[] = { if (!vfb) { // If there's no vfb and we're drawing there, must be memory? - buffer = GPUDebugBuffer(Memory::GetPointer(vfb->z_address | 0x04000000), vfb->z_stride, 512, GPU_DBG_FORMAT_16BIT); + buffer = GPUDebugBuffer(Memory::GetPointer(vfb->z_address), vfb->z_stride, 512, GPU_DBG_FORMAT_16BIT); return true; } diff --git a/GPU/Directx9/GPU_DX9.cpp b/GPU/Directx9/GPU_DX9.cpp index 24d1f69671..62b3caf1c2 100644 --- a/GPU/Directx9/GPU_DX9.cpp +++ b/GPU/Directx9/GPU_DX9.cpp @@ -61,7 +61,7 @@ GPU_DX9::GPU_DX9(GraphicsContext *gfxCtx, Draw::DrawContext *draw) lastVsync_ = g_Config.bVSync ? 1 : 0; dxstate.SetVSyncInterval(g_Config.bVSync); - shaderManagerDX9_ = new ShaderManagerDX9(device_); + shaderManagerDX9_ = new ShaderManagerDX9(draw, device_); framebufferManagerDX9_ = new FramebufferManagerDX9(draw); framebufferManager_ = framebufferManagerDX9_; textureCacheDX9_ = new TextureCacheDX9(draw); @@ -106,6 +106,63 @@ GPU_DX9::GPU_DX9(GraphicsContext *gfxCtx, Draw::DrawContext *draw) } } +// TODO: Move this detection elsewhere when it's needed elsewhere, not before. It's ugly. +// Source: https://envytools.readthedocs.io/en/latest/hw/pciid.html#gf100 +enum NVIDIAGeneration { + NV_PRE_KEPLER, + NV_KEPLER, + NV_MAXWELL, + NV_PASCAL, + NV_VOLTA, + NV_TURING, // or later +}; + +static NVIDIAGeneration NVIDIAGetDeviceGeneration(int deviceID) { + if (deviceID >= 0x1180 && deviceID <= 0x11bf) + return NV_KEPLER; // GK104 + if (deviceID >= 0x11c0 && deviceID <= 0x11fa) + return NV_KEPLER; // GK106 + if (deviceID >= 0x0fc0 && deviceID <= 0x0fff) + return NV_KEPLER; // GK107 + if (deviceID >= 0x1003 && deviceID <= 0x1028) + return NV_KEPLER; // GK110(B) + if (deviceID >= 0x1280 && deviceID <= 0x12ba) + return NV_KEPLER; // GK208 + if (deviceID >= 0x1381 && deviceID <= 0x13b0) + return NV_MAXWELL; // GM107 + if (deviceID >= 0x1340 && deviceID <= 0x134d) + return NV_MAXWELL; // GM108 + if (deviceID >= 0x13c0 && deviceID <= 0x13d9) + return NV_MAXWELL; // GM204 + if (deviceID >= 0x1401 && deviceID <= 0x1427) + return NV_MAXWELL; // GM206 + if (deviceID >= 0x15f7 && deviceID <= 0x15f9) + return NV_PASCAL; // GP100 + if (deviceID >= 0x15f7 && deviceID <= 0x15f9) + return NV_PASCAL; // GP100 + if (deviceID >= 0x1b00 && deviceID <= 0x1b38) + return NV_PASCAL; // GP102 + if (deviceID >= 0x1b80 && deviceID <= 0x1be1) + return NV_PASCAL; // GP104 + if (deviceID >= 0x1c02 && deviceID <= 0x1c62) + return NV_PASCAL; // GP106 + if (deviceID >= 0x1c81 && deviceID <= 0x1c92) + return NV_PASCAL; // GP107 + if (deviceID >= 0x1d01 && deviceID <= 0x1d12) + return NV_PASCAL; // GP108 + if (deviceID >= 0x1d81 && deviceID <= 0x1dba) + return NV_VOLTA; // GV100 + if (deviceID >= 0x1e02 && deviceID <= 0x1e3c) + return NV_TURING; // TU102 + if (deviceID >= 0x1e82 && deviceID <= 0x1ed0) + return NV_TURING; // TU104 + if (deviceID >= 0x1f02 && deviceID <= 0x1f51) + return NV_TURING; // TU104 + if (deviceID >= 0x1e02) + return NV_TURING; // More TU models or later, probably. + return NV_PRE_KEPLER; +} + void GPU_DX9::CheckGPUFeatures() { u32 features = 0; features |= GPU_SUPPORTS_16BIT_FORMATS; @@ -119,9 +176,21 @@ void GPU_DX9::CheckGPUFeatures() { features |= GPU_SUPPORTS_ACCURATE_DEPTH; } - // VS range culling causes problems on Intel. - if (vendor != Draw::GPUVendor::VENDOR_INTEL) { + // VS range culling (killing triangles in the vertex shader using NaN) causes problems on Intel. + // Also causes problems on old NVIDIA. + switch (vendor) { + case Draw::GPUVendor::VENDOR_INTEL: + break; + case Draw::GPUVendor::VENDOR_NVIDIA: + // Older NVIDIAs don't seem to like NaNs in their DX9 vertex shaders. + // No idea if KEPLER is the right cutoff, but let's go with it. + if (NVIDIAGetDeviceGeneration(draw_->GetDeviceCaps().deviceID) >= NV_KEPLER) { + features |= GPU_SUPPORTS_VS_RANGE_CULLING; + } + break; + default: features |= GPU_SUPPORTS_VS_RANGE_CULLING; + break; } D3DCAPS9 caps; diff --git a/GPU/Directx9/ShaderManagerDX9.cpp b/GPU/Directx9/ShaderManagerDX9.cpp index f667d6111a..f7a00e505e 100644 --- a/GPU/Directx9/ShaderManagerDX9.cpp +++ b/GPU/Directx9/ShaderManagerDX9.cpp @@ -27,6 +27,7 @@ #include "math/lin/matrix4x4.h" #include "math/math_util.h" #include "math/dataconv.h" +#include "thin3d/thin3d.h" #include "util/text/utf8.h" #include "Common/Common.h" @@ -510,7 +511,8 @@ void ShaderManagerDX9::VSUpdateUniforms(u64 dirtyUniforms) { } } -ShaderManagerDX9::ShaderManagerDX9(LPDIRECT3DDEVICE9 device) : device_(device), lastVShader_(nullptr), lastPShader_(nullptr) { +ShaderManagerDX9::ShaderManagerDX9(Draw::DrawContext *draw, LPDIRECT3DDEVICE9 device) + : ShaderManagerCommon(draw), device_(device), lastVShader_(nullptr), lastPShader_(nullptr) { codeBuffer_ = new char[16384 * 2]; } @@ -565,7 +567,7 @@ VSShader *ShaderManagerDX9::ApplyShader(int prim, u32 vertType) { FShaderID FSID; if (gstate_c.IsDirty(DIRTY_FRAGMENTSHADER_STATE)) { gstate_c.Clean(DIRTY_FRAGMENTSHADER_STATE); - ComputeFragmentShaderID(&FSID); + ComputeFragmentShaderID(&FSID, draw_->GetBugs()); } else { FSID = lastFSID_; } diff --git a/GPU/Directx9/ShaderManagerDX9.h b/GPU/Directx9/ShaderManagerDX9.h index 68fefdccc6..b59efe0175 100644 --- a/GPU/Directx9/ShaderManagerDX9.h +++ b/GPU/Directx9/ShaderManagerDX9.h @@ -77,7 +77,7 @@ protected: class ShaderManagerDX9 : public ShaderManagerCommon { public: - ShaderManagerDX9(LPDIRECT3DDEVICE9 device); + ShaderManagerDX9(Draw::DrawContext *draw, LPDIRECT3DDEVICE9 device); ~ShaderManagerDX9(); void ClearCache(bool deleteThem); // TODO: deleteThem currently not respected diff --git a/GPU/Directx9/StateMappingDX9.cpp b/GPU/Directx9/StateMappingDX9.cpp index 1577201d20..936cbb7666 100644 --- a/GPU/Directx9/StateMappingDX9.cpp +++ b/GPU/Directx9/StateMappingDX9.cpp @@ -181,7 +181,7 @@ void DrawEngineDX9::ApplyDrawState(int prim) { #endif // Let's not write to alpha if stencil isn't enabled. - if (!gstate.isStencilTestEnabled()) { + if (IsStencilTestOutputDisabled()) { amask = false; } else { // If the stencil type is set to KEEP, we shouldn't write to the stencil/alpha channel. @@ -194,8 +194,6 @@ void DrawEngineDX9::ApplyDrawState(int prim) { } } - bool enableStencilTest = !g_Config.bDisableStencilTest; - if (gstate_c.IsDirty(DIRTY_RASTER_STATE)) { gstate_c.Clean(DIRTY_RASTER_STATE); // Set Dither @@ -231,7 +229,7 @@ void DrawEngineDX9::ApplyDrawState(int prim) { // Stencil Test bool alphaMask = gstate.isClearModeAlphaMask(); - if (alphaMask && enableStencilTest) { + if (alphaMask) { dxstate.stencilTest.enable(); dxstate.stencilOp.set(D3DSTENCILOP_REPLACE, D3DSTENCILOP_REPLACE, D3DSTENCILOP_REPLACE); dxstate.stencilFunc.set(D3DCMP_ALWAYS, 255, 0xFF); diff --git a/GPU/Directx9/StencilBufferDX9.cpp b/GPU/Directx9/StencilBufferDX9.cpp index 6f51582cf2..49c73c2821 100644 --- a/GPU/Directx9/StencilBufferDX9.cpp +++ b/GPU/Directx9/StencilBufferDX9.cpp @@ -33,38 +33,41 @@ namespace DX9 { #define STR_HELPER(x) #x #define STR(x) STR_HELPER(x) -static const char *stencil_ps = -"sampler tex: register(s0);\n" +static const char *stencil_ps = R"( +sampler tex: register(s0); // TODO: Don't use fixed registers? Or don't overlap? -"float4 u_stencilValue : register(c" STR(CONST_PS_STENCILVALUE) ");\n" -"struct PS_IN {\n" -" float2 v_texcoord0 : TEXCOORD0;\n" -"};\n" -"float roundAndScaleTo255f(in float x) { return floor(x * 255.99); }\n" -"float4 main(PS_IN In) : COLOR {\n" -" float4 index = tex2D(tex, In.v_texcoord0);\n" -" float shifted = roundAndScaleTo255f(index.a) / roundAndScaleTo255f(u_stencilValue.x);\n" -" clip(fmod(floor(shifted), 2.0) - 0.99);\n" -" return index.aaaa;\n" -"}\n"; +float4 u_stencilValue : register(c)" STR(CONST_PS_STENCILVALUE) R"(); +struct PS_IN { + float2 v_texcoord0 : TEXCOORD0; +}; +float roundAndScaleTo255f(in float x) { return floor(x * 255.99); } +float4 main(PS_IN In) : COLOR { + float4 index = tex2D(tex, In.v_texcoord0); + float shifted = roundAndScaleTo255f(index.a) / roundAndScaleTo255f(u_stencilValue.x); + clip(fmod(floor(shifted), 2.0) - 0.99); + return index.aaaa; +} +)"; -static const char *stencil_vs = -"struct VS_IN {\n" -" float4 a_position : POSITION;\n" -" float2 a_texcoord0 : TEXCOORD0;\n" -"};\n" -"struct VS_OUT {\n" -" float4 position : POSITION;\n" -" float2 v_texcoord0 : TEXCOORD0;\n" -"};\n" -"VS_OUT main(VS_IN In) {\n" -" VS_OUT Out;\n" -" Out.position = In.a_position;\n" -" Out.v_texcoord0 = In.a_texcoord0;\n" -" return Out;\n" -"}\n"; +static const char *stencil_vs = R"( +struct VS_IN { + float4 a_position : POSITION; + float2 a_texcoord0 : TEXCOORD0; +}; +struct VS_OUT { + float4 position : POSITION; + float2 v_texcoord0 : TEXCOORD0; +}; +VS_OUT main(VS_IN In) { + VS_OUT Out; + Out.position = In.a_position; + Out.v_texcoord0 = In.a_texcoord0; + return Out; +} +)"; bool FramebufferManagerDX9::NotifyStencilUpload(u32 addr, int size, bool skipZero) { + addr &= 0x3FFFFFFF; if (!MayIntersectFramebuffer(addr)) { return false; } @@ -72,7 +75,7 @@ bool FramebufferManagerDX9::NotifyStencilUpload(u32 addr, int size, bool skipZer VirtualFramebuffer *dstBuffer = 0; for (size_t i = 0; i < vfbs_.size(); ++i) { VirtualFramebuffer *vfb = vfbs_[i]; - if (MaskedEqual(vfb->fb_address, addr)) { + if (vfb->fb_address == addr) { dstBuffer = vfb; } } diff --git a/GPU/Directx9/TextureCacheDX9.cpp b/GPU/Directx9/TextureCacheDX9.cpp index 872d559232..13032603d8 100644 --- a/GPU/Directx9/TextureCacheDX9.cpp +++ b/GPU/Directx9/TextureCacheDX9.cpp @@ -320,14 +320,14 @@ public: static const Pos pos[4] = { {-1, 1, 0}, { 1, 1, 0}, - { 1, -1, 0}, {-1, -1, 0}, + { 1, -1, 0}, }; static const UV uv[4] = { {0, 0}, {1, 0}, - {1, 1}, {0, 1}, + {1, 1}, }; for (int i = 0; i < 4; ++i) { @@ -354,25 +354,25 @@ public: const float left = u1 * invHalfWidth - 1.0f + xoff; const float right = u2 * invHalfWidth - 1.0f + xoff; - const float top = v1 * invHalfHeight - 1.0f + yoff; - const float bottom = v2 * invHalfHeight - 1.0f + yoff; + const float top = (bufferH_ - v1) * invHalfHeight - 1.0f + yoff; + const float bottom = (bufferH_ - v2) * invHalfHeight - 1.0f + yoff; float z = 0.0f; - // Points are: BL, BR, TR, TL. - verts_[0].pos = Pos(left, bottom, z); - verts_[1].pos = Pos(right, bottom, z); - verts_[2].pos = Pos(right, top, z); - verts_[3].pos = Pos(left, top, z); + verts_[0].pos = Pos(left, top, z); + verts_[1].pos = Pos(right, top, z); + verts_[2].pos = Pos(left, bottom, z); + verts_[3].pos = Pos(right, bottom, z); // And also the UVs, same order. const float uvleft = u1 * invWidth; const float uvright = u2 * invWidth; const float uvtop = v1 * invHeight; const float uvbottom = v2 * invHeight; - verts_[0].uv = UV(uvleft, uvbottom); - verts_[1].uv = UV(uvright, uvbottom); - verts_[2].uv = UV(uvright, uvtop); - verts_[3].uv = UV(uvleft, uvtop); + + verts_[0].uv = UV(uvleft, uvtop); + verts_[1].uv = UV(uvright, uvtop); + verts_[2].uv = UV(uvleft, uvbottom); + verts_[3].uv = UV(uvright, uvbottom); // We need to reapply the texture next time since we cropped UV. gstate_c.Dirty(DIRTY_TEXTURE_PARAMS); @@ -396,7 +396,7 @@ public: D3DVIEWPORT9 vp{ 0, 0, (DWORD)renderW_, (DWORD)renderH_, 0.0f, 1.0f }; device_->SetViewport(&vp); - HRESULT hr = device_->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, verts_, (3 + 2) * sizeof(float)); + HRESULT hr = device_->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, verts_, (3 + 2) * sizeof(float)); if (FAILED(hr)) { ERROR_LOG_REPORT(G3D, "Depal render failed: %08x", hr); } @@ -442,7 +442,7 @@ void TextureCacheDX9::ApplyTextureFramebuffer(TexCacheEntry *entry, VirtualFrame device_->SetSamplerState(1, D3DSAMP_MAGFILTER, D3DTEXF_POINT); device_->SetSamplerState(1, D3DSAMP_MIPFILTER, D3DTEXF_NONE); - framebufferManagerDX9_->BindFramebufferAsColorTexture(0, framebuffer, BINDFBCOLOR_SKIP_COPY); + framebufferManagerDX9_->BindFramebufferAsColorTexture(0, framebuffer, BINDFBCOLOR_SKIP_COPY | BINDFBCOLOR_FORCE_SELF); device_->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_POINT); device_->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_POINT); device_->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_NONE); diff --git a/GPU/Directx9/VertexShaderGeneratorDX9.cpp b/GPU/Directx9/VertexShaderGeneratorDX9.cpp index c1227a4536..751f1ed24b 100644 --- a/GPU/Directx9/VertexShaderGeneratorDX9.cpp +++ b/GPU/Directx9/VertexShaderGeneratorDX9.cpp @@ -160,7 +160,7 @@ void GenerateVertexShaderHLSL(const VShaderID &id, char *buffer, ShaderLanguage WRITE(p, "float3 u_lightambient%i : register(c%i);\n", i, CONST_VS_LIGHTAMBIENT + i); WRITE(p, "float3 u_lightdiffuse%i : register(c%i);\n", i, CONST_VS_LIGHTDIFFUSE + i); - if (comp != GE_LIGHTCOMP_ONLYDIFFUSE) { + if (comp == GE_LIGHTCOMP_BOTH) { WRITE(p, "float3 u_lightspecular%i : register(c%i);\n", i, CONST_VS_LIGHTSPECULAR + i); } } @@ -540,7 +540,7 @@ void GenerateVertexShaderHLSL(const VShaderID &id, char *buffer, ShaderLanguage if (doLight[i] != LIGHT_FULL) continue; diffuseIsZero = false; - if (comp != GE_LIGHTCOMP_ONLYDIFFUSE) + if (comp == GE_LIGHTCOMP_BOTH) specularIsZero = false; if (type != GE_LIGHTTYPE_DIRECTIONAL) distanceNeeded = true; @@ -583,17 +583,17 @@ void GenerateVertexShaderHLSL(const VShaderID &id, char *buffer, ShaderLanguage WRITE(p, " toLight /= distance;\n"); } - bool doSpecular = comp != GE_LIGHTCOMP_ONLYDIFFUSE; - bool poweredDiffuse = comp == GE_LIGHTCOMP_BOTHWITHPOWDIFFUSE; + bool doSpecular = comp == GE_LIGHTCOMP_BOTH; + bool poweredDiffuse = comp == GE_LIGHTCOMP_ONLYPOWDIFFUSE; - WRITE(p, " ldot = max(dot(toLight, worldnormal), 0.0);\n"); + WRITE(p, " ldot = dot(toLight, worldnormal);\n"); if (poweredDiffuse) { // pow(0.0, 0.0) may be undefined, but the PSP seems to treat it as 1.0. // Seen in Tales of the World: Radiant Mythology (#2424.) - WRITE(p, " if (ldot == 0.0 && u_matspecular.a == 0.0) {\n"); + WRITE(p, " if (u_matspecular.a == 0.0) {\n"); WRITE(p, " ldot = 1.0;\n"); WRITE(p, " } else {\n"); - WRITE(p, " ldot = pow(ldot, u_matspecular.a);\n"); + WRITE(p, " ldot = pow(max(ldot, 0.0), u_matspecular.a);\n"); WRITE(p, " }\n"); } @@ -609,9 +609,9 @@ void GenerateVertexShaderHLSL(const VShaderID &id, char *buffer, ShaderLanguage break; case GE_LIGHTTYPE_SPOT: case GE_LIGHTTYPE_UNKNOWN: - WRITE(p, " angle = dot(normalize(u_lightdir%i), toLight);\n", i); + WRITE(p, " angle = length(u_lightdir%i) == 0.0 ? 0.0 : dot(normalize(u_lightdir%i), toLight);\n", i, i); WRITE(p, " if (angle >= u_lightangle_spotCoef%i.x) {\n", i); - WRITE(p, " lightScale = clamp(1.0 / dot(u_lightatt%i, float3(1.0, distance, distance*distance)), 0.0, 1.0) * pow(angle, u_lightangle_spotCoef%i.y);\n", i, i); + WRITE(p, " lightScale = clamp(1.0 / dot(u_lightatt%i, float3(1.0, distance, distance*distance)), 0.0, 1.0) * (u_lightangle_spotCoef%i.y == 0.0 ? 1.0 : pow(angle, u_lightangle_spotCoef%i.y));\n", i, i, i); WRITE(p, " } else {\n"); WRITE(p, " lightScale = 0.0;\n"); WRITE(p, " }\n"); @@ -621,11 +621,18 @@ void GenerateVertexShaderHLSL(const VShaderID &id, char *buffer, ShaderLanguage break; } - WRITE(p, " diffuse = (u_lightdiffuse%i * %s) * ldot;\n", i, diffuseStr); + WRITE(p, " diffuse = (u_lightdiffuse%i * %s) * max(ldot, 0.0);\n", i, diffuseStr); if (doSpecular) { - WRITE(p, " ldot = dot(normalize(toLight + float3(0.0, 0.0, 1.0)), worldnormal);\n"); - WRITE(p, " if (ldot > 0.0)\n"); - WRITE(p, " lightSum1 += u_lightspecular%i * %s * (pow(ldot, u_matspecular.a) %s);\n", i, specularStr, timesLightScale); + WRITE(p, " if (ldot >= 0.0) {\n"); + WRITE(p, " ldot = dot(normalize(toLight + float3(0.0, 0.0, 1.0)), worldnormal);\n"); + WRITE(p, " if (u_matspecular.a == 0.0) {\n"); + WRITE(p, " ldot = 1.0;\n"); + WRITE(p, " } else {\n"); + WRITE(p, " ldot = pow(max(ldot, 0.0), u_matspecular.a);\n"); + WRITE(p, " }\n"); + WRITE(p, " if (ldot > 0.0)\n"); + WRITE(p, " lightSum1 += u_lightspecular%i * %s * ldot %s;\n", i, specularStr, timesLightScale); + WRITE(p, " }\n"); } WRITE(p, " lightSum0.rgb += (u_lightambient%i * %s.rgb + diffuse)%s;\n", i, ambientStr, timesLightScale); } @@ -719,7 +726,11 @@ void GenerateVertexShaderHLSL(const VShaderID &id, char *buffer, ShaderLanguage break; case GE_TEXMAP_ENVIRONMENT_MAP: // Shade mapping - use dots from light sources. - WRITE(p, " Out.v_texcoord = float3(u_uvscaleoffset.xy * float2(1.0 + dot(normalize(u_lightpos%i), worldnormal), 1.0 + dot(normalize(u_lightpos%i), worldnormal)) * 0.5, 1.0);\n", ls0, ls1); + { + std::string lightFactor0 = StringFromFormat("(length(u_lightpos%i) == 0.0 ? worldnormal.z : dot(normalize(u_lightpos%i), worldnormal))", ls0, ls0); + std::string lightFactor1 = StringFromFormat("(length(u_lightpos%i) == 0.0 ? worldnormal.z : dot(normalize(u_lightpos%i), worldnormal))", ls1, ls1); + WRITE(p, " Out.v_texcoord = float3(u_uvscaleoffset.xy * float2(1.0 + %s, 1.0 + %s) * 0.5, 1.0);\n", lightFactor0.c_str(), lightFactor1.c_str()); + } break; default: diff --git a/GPU/GLES/DepalettizeShaderGLES.cpp b/GPU/GLES/DepalettizeShaderGLES.cpp index b18ddd5876..c973909c79 100644 --- a/GPU/GLES/DepalettizeShaderGLES.cpp +++ b/GPU/GLES/DepalettizeShaderGLES.cpp @@ -25,31 +25,34 @@ #include "GPU/GLES/TextureCacheGLES.h" #include "GPU/Common/DepalettizeShaderCommon.h" -static const char *depalVShader100 = -"#ifdef GL_ES\n" -"precision highp float;\n" -"#endif\n" -"attribute vec4 a_position;\n" -"attribute vec2 a_texcoord0;\n" -"varying vec2 v_texcoord0;\n" -"void main() {\n" -" v_texcoord0 = a_texcoord0;\n" -" gl_Position = a_position;\n" -"}\n"; +static const char *depalVShader100 = R"( +#ifdef GL_ES +precision highp float; +#endif +attribute vec4 a_position; +attribute vec2 a_texcoord0; +varying vec2 v_texcoord0; +void main() { + v_texcoord0 = a_texcoord0; + gl_Position = a_position; +} +)"; -static const char *depalVShader300 = -"#ifdef GL_ES\n" -"precision highp float;\n" -"#endif\n" -"in vec4 a_position;\n" -"in vec2 a_texcoord0;\n" -"out vec2 v_texcoord0;\n" -"void main() {\n" -" v_texcoord0 = a_texcoord0;\n" -" gl_Position = a_position;\n" -"}\n"; +static const char *depalVShader300 = R"( +#ifdef GL_ES +precision highp float; +#endif +in vec4 a_position; +in vec2 a_texcoord0; +out vec2 v_texcoord0; +void main() { + v_texcoord0 = a_texcoord0; + gl_Position = a_position; +} +)"; DepalShaderCacheGLES::DepalShaderCacheGLES(Draw::DrawContext *draw) { + _assert_(draw); render_ = (GLRenderManager *)draw->GetNativeObject(Draw::NativeObject::RENDER_MANAGER); // Pre-build the vertex program useGL3_ = gl_extensions.GLES3 || gl_extensions.VersionGEThan(3, 3); @@ -57,9 +60,6 @@ DepalShaderCacheGLES::DepalShaderCacheGLES(Draw::DrawContext *draw) { // Use the floating point path, it just can't handle the math. useGL3_ = false; } - - vertexShaderFailed_ = false; - vertexShader_ = 0; } DepalShaderCacheGLES::~DepalShaderCacheGLES() { @@ -75,8 +75,9 @@ bool DepalShaderCacheGLES::CreateVertexShader() { std::string prelude; if (gl_extensions.IsGLES) { prelude = useGL3_ ? "#version 300 es\n" : "#version 100\n"; - } else if (useGL3_) { - prelude = "#version 330\n"; + } else { + // We need to add a corresponding #version. Apple drivers fail without an exact match. + prelude = StringFromFormat("#version %d\n", gl_extensions.GLSLVersion()); } vertexShader_ = render_->CreateShader(GL_VERTEX_SHADER, prelude + src, "depal"); return true; diff --git a/GPU/GLES/DepalettizeShaderGLES.h b/GPU/GLES/DepalettizeShaderGLES.h index e183ba22b0..c93ef87fc0 100644 --- a/GPU/GLES/DepalettizeShaderGLES.h +++ b/GPU/GLES/DepalettizeShaderGLES.h @@ -64,8 +64,8 @@ private: GLRenderManager *render_; bool useGL3_; - bool vertexShaderFailed_; - GLRShader *vertexShader_; + bool vertexShaderFailed_ = false; + GLRShader *vertexShader_ = nullptr; std::map cache_; std::map texCache_; }; diff --git a/GPU/GLES/DepthBufferGLES.cpp b/GPU/GLES/DepthBufferGLES.cpp new file mode 100644 index 0000000000..cf399cff87 --- /dev/null +++ b/GPU/GLES/DepthBufferGLES.cpp @@ -0,0 +1,198 @@ +// Copyright (c) 2012- PPSSPP Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0 or later versions. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official git repository and contact information can be found at +// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. + +#include +#include "gfx_es2/gpu_features.h" +#include "Core/ConfigValues.h" +#include "Core/Reporting.h" +#include "GPU/Common/GPUStateUtils.h" +#include "GPU/GLES/DrawEngineGLES.h" +#include "GPU/GLES/FramebufferManagerGLES.h" +#include "GPU/GLES/ShaderManagerGLES.h" +#include "GPU/GLES/TextureCacheGLES.h" + +static const char *depth_dl_fs = R"( +#ifdef GL_ES +#ifdef GL_FRAGMENT_PRECISION_HIGH +precision highp float; +#else +precision mediump float; +#endif +#endif +#if __VERSION__ >= 130 +#define varying in +#define texture2D texture +#define gl_FragColor fragColor0 +out vec4 fragColor0; +#endif +varying vec2 v_texcoord0; +uniform vec2 u_depthFactor; +uniform vec4 u_depthShift; +uniform vec4 u_depthTo8; +uniform sampler2D tex; +void main() { + float depth = texture2D(tex, v_texcoord0).r; + // At this point, clamped maps [0, 1] to [0, 65535]. + float clamped = clamp((depth + u_depthFactor.x) * u_depthFactor.y, 0.0, 1.0); + + vec4 enc = u_depthShift * clamped; + enc = floor(mod(enc, 256.0)) * u_depthTo8; + enc = enc * u_depthTo8; + // Let's ignore the bits outside 16 bit precision. + gl_FragColor = enc.yzww; +} +)"; + +static const char *depth_vs = R"( +#ifdef GL_ES +precision highp float; +#endif +#if __VERSION__ >= 130 +#define attribute in +#define varying out +#endif +attribute vec4 a_position; +attribute vec2 a_texcoord0; +varying vec2 v_texcoord0; +void main() { + v_texcoord0 = a_texcoord0; + gl_Position = a_position; +} +)"; + +void FramebufferManagerGLES::PackDepthbuffer(VirtualFramebuffer *vfb, int x, int y, int w, int h) { + if (!vfb->fbo) { + ERROR_LOG_REPORT_ONCE(vfbfbozero, SCEGE, "PackDepthbuffer: vfb->fbo == 0"); + return; + } + + // Pixel size always 4 here because we always request float + const u32 bufSize = vfb->z_stride * (h - y) * 4; + const u32 z_address = vfb->z_address; + const int packWidth = std::min(vfb->z_stride, std::min(x + w, (int)vfb->width)); + + if (!convBuf_ || convBufSize_ < bufSize) { + delete[] convBuf_; + convBuf_ = new u8[bufSize]; + convBufSize_ = bufSize; + } + + DEBUG_LOG(FRAMEBUF, "Reading depthbuffer to mem at %08x for vfb=%08x", z_address, vfb->fb_address); + + // TODO: On desktop, we can just directly download, but for now testing. + const bool useColorPath = true; // gl_extensions.IsGLES; + bool format16Bit = false; + + if (useColorPath) { + if (!depthDownloadProgram_) { + std::string errorString; + static std::string vs_code, fs_code; + vs_code = ApplyGLSLPrelude(depth_vs, GL_VERTEX_SHADER); + fs_code = ApplyGLSLPrelude(depth_dl_fs, GL_FRAGMENT_SHADER); + std::vector shaders; + shaders.push_back(render_->CreateShader(GL_VERTEX_SHADER, vs_code, "depth_dl")); + shaders.push_back(render_->CreateShader(GL_FRAGMENT_SHADER, fs_code, "depth_dl")); + std::vector semantics; + semantics.push_back({ 0, "a_position" }); + semantics.push_back({ 1, "a_texcoord0" }); + std::vector queries; + queries.push_back({ &u_depthDownloadTex, "tex" }); + queries.push_back({ &u_depthDownloadFactor, "u_depthFactor" }); + queries.push_back({ &u_depthDownloadShift, "u_depthShift" }); + queries.push_back({ &u_depthDownloadTo8, "u_depthTo8" }); + std::vector inits; + inits.push_back({ &u_depthDownloadTex, 0, TEX_SLOT_PSP_TEXTURE }); + depthDownloadProgram_ = render_->CreateProgram(shaders, semantics, queries, inits, false); + for (auto iter : shaders) { + render_->DeleteShader(iter); + } + if (!depthDownloadProgram_) { + ERROR_LOG_REPORT(G3D, "Failed to compile depthDownloadProgram! This shouldn't happen.\n%s", errorString.c_str()); + } + } + + shaderManagerGL_->DirtyLastShader(); + auto *blitFBO = GetTempFBO(TempFBO::COPY, vfb->renderWidth, vfb->renderHeight, Draw::FBO_8888); + draw_->BindFramebufferAsRenderTarget(blitFBO, { Draw::RPAction::CLEAR, Draw::RPAction::DONT_CARE, Draw::RPAction::DONT_CARE }); + render_->SetViewport({ 0, 0, (float)vfb->renderWidth, (float)vfb->renderHeight, 0.0f, 1.0f }); + textureCacheGL_->ForgetLastTexture(); + + // We must bind the program after starting the render pass, and set the color mask after clearing. + render_->SetScissor({ 0, 0, vfb->renderWidth, vfb->renderHeight }); + render_->SetDepth(false, false, GL_ALWAYS); + render_->SetRaster(false, GL_CCW, GL_FRONT, GL_FALSE); + render_->BindProgram(depthDownloadProgram_); + + if (!gstate_c.Supports(GPU_SUPPORTS_ACCURATE_DEPTH)) { + float factors[] = { 0.0f, 1.0f }; + render_->SetUniformF(&u_depthDownloadFactor, 2, factors); + } else { + const float factor = DepthSliceFactor(); + float factors[] = { -0.5f * (factor - 1.0f) * (1.0f / factor), factor }; + render_->SetUniformF(&u_depthDownloadFactor, 2, factors); + } + float shifts[] = { 16777215.0f, 16777215.0f / 256.0f, 16777215.0f / 65536.0f, 16777215.0f / 16777216.0f }; + render_->SetUniformF(&u_depthDownloadShift, 4, shifts); + float to8[] = { 1.0f / 255.0f, 1.0f / 255.0f, 1.0f / 255.0f, 1.0f / 255.0f }; + render_->SetUniformF(&u_depthDownloadTo8, 4, to8); + + draw_->BindFramebufferAsTexture(vfb->fbo, TEX_SLOT_PSP_TEXTURE, Draw::FB_DEPTH_BIT, 0); + float u1 = 1.0f; + float v1 = 1.0f; + DrawActiveTexture(x, y, w, h, vfb->renderWidth, vfb->renderHeight, 0.0f, 0.0f, u1, v1, ROTATION_LOCKED_HORIZONTAL, DRAWTEX_NEAREST); + + draw_->CopyFramebufferToMemorySync(blitFBO, Draw::FB_COLOR_BIT, 0, y, packWidth, h, Draw::DataFormat::R8G8B8A8_UNORM, convBuf_, vfb->z_stride); + // TODO: Use 4444 so we can copy lines directly? + format16Bit = true; + } else { + draw_->CopyFramebufferToMemorySync(vfb->fbo, Draw::FB_DEPTH_BIT, 0, y, packWidth, h, Draw::DataFormat::D32F, convBuf_, vfb->z_stride); + format16Bit = false; + } + + int dstByteOffset = y * vfb->z_stride * sizeof(u16); + u16 *depth = (u16 *)Memory::GetPointer(z_address + dstByteOffset); + u32_le *packed32 = (u32_le *)convBuf_; + GLfloat *packedf = (GLfloat *)convBuf_; + + int totalPixels = h == 1 ? packWidth : vfb->z_stride * h; + if (format16Bit) { + for (int yp = 0; yp < h; ++yp) { + int row_offset = vfb->z_stride * yp; + for (int xp = 0; xp < packWidth; ++xp) { + const int i = row_offset + xp; + depth[i] = packed32[i] & 0xFFFF; + } + } + } else { + for (int yp = 0; yp < h; ++yp) { + int row_offset = vfb->z_stride * yp; + for (int xp = 0; xp < packWidth; ++xp) { + const int i = row_offset + xp; + float scaled = FromScaledDepth(packedf[i]); + if (scaled <= 0.0f) { + depth[i] = 0; + } else if (scaled >= 65535.0f) { + depth[i] = 65535; + } else { + depth[i] = (int)scaled; + } + } + } + } + + gstate_c.Dirty(DIRTY_BLEND_STATE | DIRTY_RASTER_STATE | DIRTY_DEPTHSTENCIL_STATE | DIRTY_VIEWPORTSCISSOR_STATE); +} diff --git a/GPU/GLES/DrawEngineGLES.cpp b/GPU/GLES/DrawEngineGLES.cpp index 6702a53578..4ea5dd4237 100644 --- a/GPU/GLES/DrawEngineGLES.cpp +++ b/GPU/GLES/DrawEngineGLES.cpp @@ -311,7 +311,7 @@ void DrawEngineGLES::DoFlush() { gstate_c.Clean(DIRTY_TEXTURE_IMAGE | DIRTY_TEXTURE_PARAMS); textureNeedsApply = true; } else if (g_Config.bDirtyClearRSelf && gstate.getTextureAddress(0) == ((gstate.getFrameBufRawAddress() | 0x04000000) & 0x3FFFFFFF)) { - // This catches the case of clearing a texture. + // This catches the case of clearing a texture. (#10957) gstate_c.Dirty(DIRTY_TEXTURE_IMAGE); } @@ -609,8 +609,6 @@ rotateVBO: if (alphaMask) target |= GL_STENCIL_BUFFER_BIT; if (depthMask) target |= GL_DEPTH_BUFFER_BIT; - int scissorX1 = gstate.getScissorX1(); - int scissorY1 = gstate.getScissorY1(); int scissorX2 = gstate.getScissorX2() + 1; int scissorY2 = gstate.getScissorY2() + 1; @@ -618,7 +616,9 @@ rotateVBO: framebufferManager_->SetColorUpdated(gstate_c.skipDrawReason); framebufferManager_->SetSafeSize(scissorX2, scissorY2); - if (g_Config.bBlockTransferGPU && (gstate_c.featureFlags & GPU_USE_CLEAR_RAM_HACK) && colorMask && (alphaMask || gstate.FrameBufFormat() == GE_FORMAT_565)) { + if ((gstate_c.featureFlags & GPU_USE_CLEAR_RAM_HACK) && colorMask && (alphaMask || gstate.FrameBufFormat() == GE_FORMAT_565)) { + int scissorX1 = gstate.getScissorX1(); + int scissorY1 = gstate.getScissorY1(); framebufferManager_->ApplyClearToMemory(scissorX1, scissorY1, scissorX2, scissorY2, clearColor); } gstate_c.Dirty(DIRTY_BLEND_STATE); // Make sure the color mask gets re-applied. diff --git a/GPU/GLES/FramebufferManagerGLES.cpp b/GPU/GLES/FramebufferManagerGLES.cpp index 6ddf06b3bd..b34c4b5572 100644 --- a/GPU/GLES/FramebufferManagerGLES.cpp +++ b/GPU/GLES/FramebufferManagerGLES.cpp @@ -48,34 +48,36 @@ #include "GPU/GLES/DrawEngineGLES.h" #include "GPU/GLES/ShaderManagerGLES.h" -static const char tex_fs[] = - "#if __VERSION__ >= 130\n" - "#define varying in\n" - "#define texture2D texture\n" - "#define gl_FragColor fragColor0\n" - "out vec4 fragColor0;\n" - "#endif\n" - "#ifdef GL_ES\n" - "precision mediump float;\n" - "#endif\n" - "uniform sampler2D sampler0;\n" - "varying vec2 v_texcoord0;\n" - "void main() {\n" - " gl_FragColor = texture2D(sampler0, v_texcoord0);\n" - "}\n"; +static const char tex_fs[] = R"( +#if __VERSION__ >= 130 +#define varying in +#define texture2D texture +#define gl_FragColor fragColor0 +out vec4 fragColor0; +#endif +#ifdef GL_ES +precision mediump float; +#endif +uniform sampler2D sampler0; +varying vec2 v_texcoord0; +void main() { + gl_FragColor = texture2D(sampler0, v_texcoord0); +} +)"; -static const char basic_vs[] = - "#if __VERSION__ >= 130\n" - "#define attribute in\n" - "#define varying out\n" - "#endif\n" - "attribute vec4 a_position;\n" - "attribute vec2 a_texcoord0;\n" - "varying vec2 v_texcoord0;\n" - "void main() {\n" - " v_texcoord0 = a_texcoord0;\n" - " gl_Position = a_position;\n" - "}\n"; +static const char basic_vs[] = R"( +#if __VERSION__ >= 130 +#define attribute in +#define varying out +#endif +attribute vec4 a_position; +attribute vec2 a_texcoord0; +varying vec2 v_texcoord0; +void main() { + v_texcoord0 = a_texcoord0; + gl_Position = a_position; +} +)"; void FramebufferManagerGLES::CompileDraw2DProgram() { if (!draw2dprogram_) { @@ -324,6 +326,10 @@ void FramebufferManagerGLES::DestroyDeviceObjects() { render_->DeleteProgram(stencilUploadProgram_); stencilUploadProgram_ = nullptr; } + if (depthDownloadProgram_) { + render_->DeleteProgram(depthDownloadProgram_); + depthDownloadProgram_ = nullptr; + } } FramebufferManagerGLES::~FramebufferManagerGLES() { @@ -480,10 +486,6 @@ void FramebufferManagerGLES::ReformatFramebufferFrom(VirtualFramebuffer *vfb, GE } void FramebufferManagerGLES::BlitFramebufferDepth(VirtualFramebuffer *src, VirtualFramebuffer *dst) { - if (g_Config.bDisableSlowFramebufEffects) { - return; - } - bool matchingDepthBuffer = src->z_address == dst->z_address && src->z_stride != 0 && dst->z_stride != 0; bool matchingSize = src->width == dst->width && src->height == dst->height; @@ -510,10 +512,10 @@ void FramebufferManagerGLES::BindFramebufferAsColorTexture(int stage, VirtualFra // currentRenderVfb_ will always be set when this is called, except from the GE debugger. // Let's just not bother with the copy in that case. bool skipCopy = (flags & BINDFBCOLOR_MAY_COPY) == 0; - if (GPUStepping::IsStepping() || g_Config.bDisableSlowFramebufEffects) { + if (GPUStepping::IsStepping()) { skipCopy = true; } - if (!skipCopy && currentRenderVfb_ && framebuffer->fb_address == gstate.getFrameBufRawAddress()) { + if (!skipCopy && framebuffer == currentRenderVfb_) { // TODO: Maybe merge with bvfbs_? Not sure if those could be packing, and they're created at a different size. Draw::Framebuffer *renderCopy = GetTempFBO(TempFBO::COPY, framebuffer->renderWidth, framebuffer->renderHeight, (Draw::FBColorDepth)framebuffer->colorDepth); if (renderCopy) { @@ -650,48 +652,6 @@ void FramebufferManagerGLES::BlitFramebuffer(VirtualFramebuffer *dst, int dstX, gstate_c.Dirty(DIRTY_VIEWPORTSCISSOR_STATE | DIRTY_BLEND_STATE | DIRTY_RASTER_STATE); } -void FramebufferManagerGLES::PackDepthbuffer(VirtualFramebuffer *vfb, int x, int y, int w, int h) { - if (!vfb->fbo) { - ERROR_LOG_REPORT_ONCE(vfbfbozero, SCEGE, "PackDepthbuffer: vfb->fbo == 0"); - return; - } - - // Pixel size always 4 here because we always request float - const u32 bufSize = vfb->z_stride * (h - y) * 4; - const u32 z_address = (0x04000000) | vfb->z_address; - const int packWidth = std::min(vfb->z_stride, std::min(x + w, (int)vfb->width)); - - if (!convBuf_ || convBufSize_ < bufSize) { - delete [] convBuf_; - convBuf_ = new u8[bufSize]; - convBufSize_ = bufSize; - } - - DEBUG_LOG(FRAMEBUF, "Reading depthbuffer to mem at %08x for vfb=%08x", z_address, vfb->fb_address); - - draw_->CopyFramebufferToMemorySync(vfb->fbo, Draw::FB_DEPTH_BIT, 0, y, packWidth, h, Draw::DataFormat::D32F, convBuf_, vfb->z_stride); - - int dstByteOffset = y * vfb->z_stride * sizeof(u16); - u16 *depth = (u16 *)Memory::GetPointer(z_address + dstByteOffset); - GLfloat *packed = (GLfloat *)convBuf_; - - int totalPixels = h == 1 ? packWidth : vfb->z_stride * h; - for (int yp = 0; yp < h; ++yp) { - int row_offset = vfb->z_stride * yp; - for (int xp = 0; xp < packWidth; ++xp) { - const int i = row_offset + xp; - float scaled = FromScaledDepth(packed[i]); - if (scaled <= 0.0f) { - depth[i] = 0; - } else if (scaled >= 65535.0f) { - depth[i] = 65535; - } else { - depth[i] = (int)scaled; - } - } - } -} - void FramebufferManagerGLES::EndFrame() { } diff --git a/GPU/GLES/FramebufferManagerGLES.h b/GPU/GLES/FramebufferManagerGLES.h index 8c0be0ac1e..aa6486c822 100644 --- a/GPU/GLES/FramebufferManagerGLES.h +++ b/GPU/GLES/FramebufferManagerGLES.h @@ -103,6 +103,12 @@ private: int u_stencilUploadTex = -1; int u_stencilValue = -1; int u_postShaderTex = -1; + + GLRProgram *depthDownloadProgram_ = nullptr; + int u_depthDownloadTex = -1; + int u_depthDownloadFactor = -1; + int u_depthDownloadShift = -1; + int u_depthDownloadTo8 = -1; // Cached uniform locs int u_draw2d_tex = -1; diff --git a/GPU/GLES/GPU_GLES.cpp b/GPU/GLES/GPU_GLES.cpp index cde3291767..bb54322f7f 100644 --- a/GPU/GLES/GPU_GLES.cpp +++ b/GPU/GLES/GPU_GLES.cpp @@ -142,49 +142,18 @@ GPU_GLES::~GPU_GLES() { delete textureCacheGL_; } -static constexpr int MakeIntelSimpleVer(int v1, int v2, int v3) { - return (v1 << 16) | (v2 << 8) | v3; -} - -static bool HasIntelDualSrcBug(int versions[4]) { - // Intel uses a confusing set of at least 3 version numbering schemes. This is the one given to OpenGL. - switch (MakeIntelSimpleVer(versions[0], versions[1], versions[2])) { - case MakeIntelSimpleVer(9, 17, 10): - case MakeIntelSimpleVer(9, 18, 10): - return false; - case MakeIntelSimpleVer(10, 18, 10): - return versions[3] < 4061; - case MakeIntelSimpleVer(10, 18, 14): - return versions[3] < 4080; - default: - // Older than above didn't support dual src anyway, newer should have the fix. - return false; - } -} - // Take the raw GL extension and versioning data and turn into feature flags. void GPU_GLES::CheckGPUFeatures() { u32 features = 0; features |= GPU_SUPPORTS_16BIT_FORMATS; - features |= GPU_SUPPORTS_VS_RANGE_CULLING; + + if (!draw_->GetBugs().Has(Draw::Bugs::BROKEN_NAN_IN_CONDITIONAL)) { + features |= GPU_SUPPORTS_VS_RANGE_CULLING; + } if (gl_extensions.ARB_blend_func_extended || gl_extensions.EXT_blend_func_extended) { - if (!gl_extensions.VersionGEThan(3, 0, 0)) { - // Don't use this extension on sub 3.0 OpenGL versions as it does not seem reliable - } else if (gl_extensions.gpuVendor == GPU_VENDOR_INTEL) { - // Also on Intel, see https://github.com/hrydgard/ppsspp/issues/10117 - // TODO: Remove entirely sometime reasonably far in driver years after 2015. - const std::string ver = draw_->GetInfoString(Draw::InfoField::APIVERSION); - int versions[4]{}; - if (sscanf(ver.c_str(), "Build %d.%d.%d.%d", &versions[0], &versions[1], &versions[2], &versions[3]) == 4) { - if (!HasIntelDualSrcBug(versions)) { - features |= GPU_SUPPORTS_DUALSOURCE_BLEND; - } - } else { - features |= GPU_SUPPORTS_DUALSOURCE_BLEND; - } - } else { + if (!g_Config.bVendorBugChecksEnabled || !draw_->GetBugs().Has(Draw::Bugs::DUAL_SOURCE_BLENDING_BROKEN)) { features |= GPU_SUPPORTS_DUALSOURCE_BLEND; } } diff --git a/GPU/GLES/ShaderManagerGLES.cpp b/GPU/GLES/ShaderManagerGLES.cpp index 2a20129766..585a6cf459 100644 --- a/GPU/GLES/ShaderManagerGLES.cpp +++ b/GPU/GLES/ShaderManagerGLES.cpp @@ -28,11 +28,12 @@ #include "base/timeutil.h" #include "gfx/gl_debug_log.h" #include "gfx_es2/gpu_features.h" -#include "thin3d/GLRenderManager.h" #include "i18n/i18n.h" #include "math/math_util.h" #include "math/lin/matrix4x4.h" #include "profiler/profiler.h" +#include "thin3d/thin3d.h" +#include "thin3d/GLRenderManager.h" #include "Common/FileUtil.h" #include "Core/Config.h" @@ -571,7 +572,7 @@ void LinkedShader::UpdateUniforms(u32 vertType, const ShaderID &vsid) { } ShaderManagerGLES::ShaderManagerGLES(Draw::DrawContext *draw) - : lastShader_(nullptr), shaderSwitchDirtyUniforms_(0), diskCacheDirty_(false), fsCache_(16), vsCache_(16) { + : ShaderManagerCommon(draw), lastShader_(nullptr), shaderSwitchDirtyUniforms_(0), diskCacheDirty_(false), fsCache_(16), vsCache_(16) { render_ = (GLRenderManager *)draw->GetNativeObject(Draw::NativeObject::RENDER_MANAGER); codeBuffer_ = new char[16384]; lastFSID_.set_invalid(); @@ -610,6 +611,7 @@ void ShaderManagerGLES::DeviceLost() { void ShaderManagerGLES::DeviceRestore(Draw::DrawContext *draw) { render_ = (GLRenderManager *)draw->GetNativeObject(Draw::NativeObject::RENDER_MANAGER); + draw_ = draw; } void ShaderManagerGLES::DirtyShader() { @@ -701,7 +703,7 @@ LinkedShader *ShaderManagerGLES::ApplyFragmentShader(VShaderID VSID, Shader *vs, FShaderID FSID; if (gstate_c.IsDirty(DIRTY_FRAGMENTSHADER_STATE)) { gstate_c.Clean(DIRTY_FRAGMENTSHADER_STATE); - ComputeFragmentShaderID(&FSID); + ComputeFragmentShaderID(&FSID, draw_->GetBugs()); } else { FSID = lastFSID_; } @@ -826,7 +828,7 @@ std::string ShaderManagerGLES::DebugGetShaderString(std::string id, DebugShaderT // as sometimes these features might have an effect on the ID bits. #define CACHE_HEADER_MAGIC 0x83277592 -#define CACHE_VERSION 12 +#define CACHE_VERSION 13 struct CacheHeader { uint32_t magic; uint32_t version; diff --git a/GPU/GLES/StateMappingGLES.cpp b/GPU/GLES/StateMappingGLES.cpp index ec256cd842..e6636b87e2 100644 --- a/GPU/GLES/StateMappingGLES.cpp +++ b/GPU/GLES/StateMappingGLES.cpp @@ -143,7 +143,7 @@ void DrawEngineGLES::ApplyDrawState(int prim) { // amask is needed for both stencil and blend state so we keep it outside for now bool amask = (gstate.pmska & 0xFF) < 128; // Let's not write to alpha if stencil isn't enabled. - if (!gstate.isStencilTestEnabled()) { + if (IsStencilTestOutputDisabled()) { amask = false; } else { // If the stencil type is set to KEEP, we shouldn't write to the stencil/alpha channel. @@ -271,13 +271,12 @@ void DrawEngineGLES::ApplyDrawState(int prim) { if (gstate_c.IsDirty(DIRTY_DEPTHSTENCIL_STATE)) { gstate_c.Clean(DIRTY_DEPTHSTENCIL_STATE); - bool enableStencilTest = !g_Config.bDisableStencilTest; if (gstate.isModeClear()) { // Depth Test if (gstate.isClearModeDepthMask()) { framebufferManager_->SetDepthUpdated(); } - renderManager->SetStencilFunc(gstate.isClearModeAlphaMask() && enableStencilTest, GL_ALWAYS, 0xFF, 0xFF); + renderManager->SetStencilFunc(gstate.isClearModeAlphaMask(), GL_ALWAYS, 0xFF, 0xFF); renderManager->SetStencilOp(0xFF, GL_REPLACE, GL_REPLACE, GL_REPLACE); renderManager->SetDepth(true, gstate.isClearModeDepthMask() ? true : false, GL_ALWAYS); } else { diff --git a/GPU/GLES/StencilBufferGLES.cpp b/GPU/GLES/StencilBufferGLES.cpp index dee08b4577..2e13c35885 100644 --- a/GPU/GLES/StencilBufferGLES.cpp +++ b/GPU/GLES/StencilBufferGLES.cpp @@ -20,48 +20,56 @@ #include "Core/ConfigValues.h" #include "Core/Reporting.h" #include "GPU/Common/StencilCommon.h" +#include "GPU/GLES/DrawEngineGLES.h" #include "GPU/GLES/FramebufferManagerGLES.h" #include "GPU/GLES/ShaderManagerGLES.h" #include "GPU/GLES/TextureCacheGLES.h" -static const char *stencil_fs = -"#ifdef GL_ES\n" -"precision highp float;\n" -"#endif\n" -"#if __VERSION__ >= 130\n" -"#define varying in\n" -"#define texture2D texture\n" -"#define gl_FragColor fragColor0\n" -"out vec4 fragColor0;\n" -"#endif\n" -"varying vec2 v_texcoord0;\n" -"uniform float u_stencilValue;\n" -"uniform sampler2D tex;\n" -"float roundAndScaleTo255f(in float x) { return floor(x * 255.99); }\n" -"void main() {\n" -" vec4 index = texture2D(tex, v_texcoord0);\n" -" gl_FragColor = vec4(index.a);\n" -" float shifted = roundAndScaleTo255f(index.a) / roundAndScaleTo255f(u_stencilValue);\n" -" if (mod(floor(shifted), 2.0) < 0.99) discard;\n" -"}\n"; +static const char *stencil_fs = R"( +#ifdef GL_ES +#ifdef GL_FRAGMENT_PRECISION_HIGH +precision highp float; +#else +precision mediump float; // just hope it's enough.. +#endif +#endif +#if __VERSION__ >= 130 +#define varying in +#define texture2D texture +#define gl_FragColor fragColor0 +out vec4 fragColor0; +#endif +varying vec2 v_texcoord0; +uniform float u_stencilValue; +uniform sampler2D tex; +float roundAndScaleTo255f(in float x) { return floor(x * 255.99); } +void main() { + vec4 index = texture2D(tex, v_texcoord0); + gl_FragColor = vec4(index.a); + float shifted = roundAndScaleTo255f(index.a) / roundAndScaleTo255f(u_stencilValue); + if (mod(floor(shifted), 2.0) < 0.99) discard; +} +)"; -static const char *stencil_vs = -"#ifdef GL_ES\n" -"precision highp float;\n" -"#endif\n" -"#if __VERSION__ >= 130\n" -"#define attribute in\n" -"#define varying out\n" -"#endif\n" -"attribute vec4 a_position;\n" -"attribute vec2 a_texcoord0;\n" -"varying vec2 v_texcoord0;\n" -"void main() {\n" -" v_texcoord0 = a_texcoord0;\n" -" gl_Position = a_position;\n" -"}\n"; +static const char *stencil_vs = R"( +#ifdef GL_ES +precision highp float; +#endif +#if __VERSION__ >= 130 +#define attribute in +#define varying out +#endif +attribute vec4 a_position; +attribute vec2 a_texcoord0; +varying vec2 v_texcoord0; +void main() { + v_texcoord0 = a_texcoord0; + gl_Position = a_position; +} +)"; bool FramebufferManagerGLES::NotifyStencilUpload(u32 addr, int size, bool skipZero) { + addr &= 0x3FFFFFFF; if (!MayIntersectFramebuffer(addr)) { return false; } @@ -69,7 +77,7 @@ bool FramebufferManagerGLES::NotifyStencilUpload(u32 addr, int size, bool skipZe VirtualFramebuffer *dstBuffer = 0; for (size_t i = 0; i < vfbs_.size(); ++i) { VirtualFramebuffer *vfb = vfbs_[i]; - if (MaskedEqual(vfb->fb_address, addr)) { + if (vfb->fb_address == addr) { dstBuffer = vfb; } } @@ -136,7 +144,7 @@ bool FramebufferManagerGLES::NotifyStencilUpload(u32 addr, int size, bool skipZe queries.push_back({ &u_stencilUploadTex, "tex" }); queries.push_back({ &u_stencilValue, "u_stencilValue" }); std::vector inits; - inits.push_back({ &u_stencilUploadTex, 0, 0 }); + inits.push_back({ &u_stencilUploadTex, 0, TEX_SLOT_PSP_TEXTURE }); stencilUploadProgram_ = render_->CreateProgram(shaders, semantics, queries, inits, false); for (auto iter : shaders) { render_->DeleteShader(iter); diff --git a/GPU/GLES/TextureCacheGLES.cpp b/GPU/GLES/TextureCacheGLES.cpp index 62dad30b5f..4c2ba52c49 100644 --- a/GPU/GLES/TextureCacheGLES.cpp +++ b/GPU/GLES/TextureCacheGLES.cpp @@ -484,7 +484,7 @@ void TextureCacheGLES::ApplyTextureFramebuffer(TexCacheEntry *entry, VirtualFram shaderApply.ApplyBounds(gstate_c.vertBounds, gstate_c.curTextureXOffset, gstate_c.curTextureYOffset); shaderApply.Use(render_, drawEngine_, shadeInputLayout_); - framebufferManagerGL_->BindFramebufferAsColorTexture(0, framebuffer, BINDFBCOLOR_SKIP_COPY); + framebufferManagerGL_->BindFramebufferAsColorTexture(0, framebuffer, BINDFBCOLOR_SKIP_COPY | BINDFBCOLOR_FORCE_SELF); render_->BindTexture(TEX_SLOT_CLUT, clutTexture); render_->SetTextureSampler(TEX_SLOT_CLUT, GL_REPEAT, GL_CLAMP_TO_EDGE, GL_NEAREST, GL_NEAREST, 0.0f); @@ -679,7 +679,7 @@ void TextureCacheGLES::BuildTexture(TexCacheEntry *const entry) { } } else { // Avoid PowerVR driver bug - if (canAutoGen && w > 1 && h > 1 && !(h > w && (gl_extensions.bugs & BUG_PVR_GENMIPMAP_HEIGHT_GREATER))) { // Really! only seems to fail if height > width + if (canAutoGen && w > 1 && h > 1 && !(h > w && draw_->GetBugs().Has(Draw::Bugs::PVR_GENMIPMAP_HEIGHT_GREATER))) { // Really! only seems to fail if height > width // NOTICE_LOG(G3D, "Generating mipmap for texture sized %dx%d%d", w, h, (int)format); genMips = true; } else { diff --git a/GPU/GLES/VertexShaderGeneratorGLES.cpp b/GPU/GLES/VertexShaderGeneratorGLES.cpp index d786debca5..123f394061 100644 --- a/GPU/GLES/VertexShaderGeneratorGLES.cpp +++ b/GPU/GLES/VertexShaderGeneratorGLES.cpp @@ -309,7 +309,7 @@ void GenerateVertexShader(const VShaderID &id, char *buffer, uint32_t *attrMask, WRITE(p, "uniform lowp vec3 u_lightambient%i;\n", i); WRITE(p, "uniform lowp vec3 u_lightdiffuse%i;\n", i); - if (comp != GE_LIGHTCOMP_ONLYDIFFUSE) { + if (comp == GE_LIGHTCOMP_BOTH) { WRITE(p, "uniform lowp vec3 u_lightspecular%i;\n", i); } } @@ -636,7 +636,7 @@ void GenerateVertexShader(const VShaderID &id, char *buffer, uint32_t *attrMask, if (doLight[i] != LIGHT_FULL) continue; diffuseIsZero = false; - if (comp != GE_LIGHTCOMP_ONLYDIFFUSE) + if (comp == GE_LIGHTCOMP_BOTH) specularIsZero = false; if (type != GE_LIGHTTYPE_DIRECTIONAL) distanceNeeded = true; @@ -679,17 +679,17 @@ void GenerateVertexShader(const VShaderID &id, char *buffer, uint32_t *attrMask, WRITE(p, " toLight /= distance;\n"); } - bool doSpecular = comp != GE_LIGHTCOMP_ONLYDIFFUSE; - bool poweredDiffuse = comp == GE_LIGHTCOMP_BOTHWITHPOWDIFFUSE; + bool doSpecular = comp == GE_LIGHTCOMP_BOTH; + bool poweredDiffuse = comp == GE_LIGHTCOMP_ONLYPOWDIFFUSE; - WRITE(p, " ldot = max(dot(toLight, worldnormal), 0.0);\n"); + WRITE(p, " ldot = dot(toLight, worldnormal);\n"); if (poweredDiffuse) { // pow(0.0, 0.0) may be undefined, but the PSP seems to treat it as 1.0. // Seen in Tales of the World: Radiant Mythology (#2424.) - WRITE(p, " if (ldot == 0.0 && u_matspecular.a == 0.0) {\n"); + WRITE(p, " if (u_matspecular.a == 0.0) {\n"); WRITE(p, " ldot = 1.0;\n"); WRITE(p, " } else {\n"); - WRITE(p, " ldot = pow(ldot, u_matspecular.a);\n"); + WRITE(p, " ldot = pow(max(ldot, 0.0), u_matspecular.a);\n"); WRITE(p, " }\n"); } @@ -705,9 +705,9 @@ void GenerateVertexShader(const VShaderID &id, char *buffer, uint32_t *attrMask, break; case GE_LIGHTTYPE_SPOT: case GE_LIGHTTYPE_UNKNOWN: - WRITE(p, " angle = dot(normalize(u_lightdir%i), toLight);\n", i); + WRITE(p, " angle = length(u_lightdir%i) == 0.0 ? 0.0 : dot(normalize(u_lightdir%i), toLight);\n", i, i); WRITE(p, " if (angle >= u_lightangle_spotCoef%i.x) {\n", i); - WRITE(p, " lightScale = clamp(1.0 / dot(u_lightatt%i, vec3(1.0, distance, distance*distance)), 0.0, 1.0) * pow(angle, u_lightangle_spotCoef%i.y);\n", i, i); + WRITE(p, " lightScale = clamp(1.0 / dot(u_lightatt%i, vec3(1.0, distance, distance*distance)), 0.0, 1.0) * (u_lightangle_spotCoef%i.y == 0.0 ? 1.0 : pow(angle, u_lightangle_spotCoef%i.y));\n", i, i, i); WRITE(p, " } else {\n"); WRITE(p, " lightScale = 0.0;\n"); WRITE(p, " }\n"); @@ -717,11 +717,18 @@ void GenerateVertexShader(const VShaderID &id, char *buffer, uint32_t *attrMask, break; } - WRITE(p, " diffuse = (u_lightdiffuse%i * %s) * ldot;\n", i, diffuseStr); + WRITE(p, " diffuse = (u_lightdiffuse%i * %s) * max(ldot, 0.0);\n", i, diffuseStr); if (doSpecular) { - WRITE(p, " ldot = dot(normalize(toLight + vec3(0.0, 0.0, 1.0)), worldnormal);\n"); - WRITE(p, " if (ldot > 0.0)\n"); - WRITE(p, " lightSum1 += u_lightspecular%i * %s * (pow(ldot, u_matspecular.a) %s);\n", i, specularStr, timesLightScale); + WRITE(p, " if (ldot >= 0.0) {\n"); + WRITE(p, " ldot = dot(normalize(toLight + vec3(0.0, 0.0, 1.0)), worldnormal);\n"); + WRITE(p, " if (u_matspecular.a == 0.0) {\n"); + WRITE(p, " ldot = 1.0;\n"); + WRITE(p, " } else {\n"); + WRITE(p, " ldot = pow(max(ldot, 0.0), u_matspecular.a);\n"); + WRITE(p, " }\n"); + WRITE(p, " if (ldot > 0.0)\n"); + WRITE(p, " lightSum1 += u_lightspecular%i * %s * ldot %s;\n", i, specularStr, timesLightScale); + WRITE(p, " }\n"); } WRITE(p, " lightSum0.rgb += (u_lightambient%i * %s.rgb + diffuse)%s;\n", i, ambientStr, timesLightScale); } @@ -816,7 +823,11 @@ void GenerateVertexShader(const VShaderID &id, char *buffer, uint32_t *attrMask, break; case GE_TEXMAP_ENVIRONMENT_MAP: // Shade mapping - use dots from light sources. - WRITE(p, " v_texcoord = vec3(u_uvscaleoffset.xy * vec2(1.0 + dot(normalize(u_lightpos%i), worldnormal), 1.0 + dot(normalize(u_lightpos%i), worldnormal)) * 0.5, 1.0);\n", ls0, ls1); + { + std::string lightFactor0 = StringFromFormat("(length(u_lightpos%i) == 0.0 ? worldnormal.z : dot(normalize(u_lightpos%i), worldnormal))", ls0, ls0); + std::string lightFactor1 = StringFromFormat("(length(u_lightpos%i) == 0.0 ? worldnormal.z : dot(normalize(u_lightpos%i), worldnormal))", ls1, ls1); + WRITE(p, " v_texcoord = vec3(u_uvscaleoffset.xy * vec2(1.0 + %s, 1.0 + %s) * 0.5, 1.0);\n", lightFactor0.c_str(), lightFactor1.c_str()); + } break; default: diff --git a/GPU/GPU.cpp b/GPU/GPU.cpp index e7026973b4..2fe380d3c1 100644 --- a/GPU/GPU.cpp +++ b/GPU/GPU.cpp @@ -61,6 +61,7 @@ bool GPU_IsReady() { } bool GPU_Init(GraphicsContext *ctx, Draw::DrawContext *draw) { + _assert_(draw || PSP_CoreParameter().gpuCore == GPUCORE_NULL); #if PPSSPP_PLATFORM(UWP) SetGPU(new GPU_D3D11(ctx, draw)); return true; diff --git a/GPU/GPU.vcxproj b/GPU/GPU.vcxproj index b531442bb8..13264c837c 100644 --- a/GPU/GPU.vcxproj +++ b/GPU/GPU.vcxproj @@ -94,6 +94,7 @@ false MultiThreadedDebug Common/DbgNew.h + ProgramDatabase true @@ -116,6 +117,7 @@ _CRTDBG_MAP_ALLOC;USING_WIN_UI;_CRT_SECURE_NO_WARNINGS;WIN32;_ARCH_64=1;_M_X64=1;_DEBUG;_LIB;_UNICODE;UNICODE;%(PreprocessorDefinitions) MultiThreadedDebug Common/DbgNew.h + ProgramDatabase true @@ -337,6 +339,7 @@ + diff --git a/GPU/GPU.vcxproj.filters b/GPU/GPU.vcxproj.filters index 1710c3f790..76b0113d10 100644 --- a/GPU/GPU.vcxproj.filters +++ b/GPU/GPU.vcxproj.filters @@ -548,5 +548,8 @@ Debugger + + GLES + \ No newline at end of file diff --git a/GPU/GPUCommon.cpp b/GPU/GPUCommon.cpp index 5116e5a08e..6c1117c8be 100644 --- a/GPU/GPUCommon.cpp +++ b/GPU/GPUCommon.cpp @@ -118,10 +118,10 @@ const CommonCommandTableEntry commonCommandTable[] = { { GE_CMD_BLENDFIXEDA, FLAG_FLUSHBEFOREONCHANGE, DIRTY_BLEND_STATE | DIRTY_FRAGMENTSHADER_STATE }, { GE_CMD_BLENDFIXEDB, FLAG_FLUSHBEFOREONCHANGE, DIRTY_BLEND_STATE | DIRTY_FRAGMENTSHADER_STATE }, { GE_CMD_MASKRGB, FLAG_FLUSHBEFOREONCHANGE, DIRTY_BLEND_STATE | DIRTY_FRAGMENTSHADER_STATE }, - { GE_CMD_MASKALPHA, FLAG_FLUSHBEFOREONCHANGE, DIRTY_BLEND_STATE | DIRTY_FRAGMENTSHADER_STATE }, + { GE_CMD_MASKALPHA, FLAG_FLUSHBEFOREONCHANGE, DIRTY_BLEND_STATE | DIRTY_FRAGMENTSHADER_STATE | DIRTY_DEPTHSTENCIL_STATE }, { GE_CMD_ZTEST, FLAG_FLUSHBEFOREONCHANGE, DIRTY_DEPTHSTENCIL_STATE }, - { GE_CMD_ZTESTENABLE, FLAG_FLUSHBEFOREONCHANGE, DIRTY_DEPTHSTENCIL_STATE }, - { GE_CMD_ZWRITEDISABLE, FLAG_FLUSHBEFOREONCHANGE, DIRTY_DEPTHSTENCIL_STATE }, + { GE_CMD_ZTESTENABLE, FLAG_FLUSHBEFOREONCHANGE, DIRTY_DEPTHSTENCIL_STATE | DIRTY_FRAGMENTSHADER_STATE }, + { GE_CMD_ZWRITEDISABLE, FLAG_FLUSHBEFOREONCHANGE, DIRTY_DEPTHSTENCIL_STATE | DIRTY_FRAGMENTSHADER_STATE }, { GE_CMD_LOGICOP, FLAG_FLUSHBEFOREONCHANGE, DIRTY_BLEND_STATE | DIRTY_FRAGMENTSHADER_STATE }, { GE_CMD_LOGICOPENABLE, FLAG_FLUSHBEFOREONCHANGE, DIRTY_BLEND_STATE | DIRTY_FRAGMENTSHADER_STATE }, @@ -1544,7 +1544,7 @@ void GPUCommon::Execute_Prim(u32 op, u32 diff) { } void *verts = Memory::GetPointerUnchecked(gstate_c.vertexAddr); - void *inds = 0; + void *inds = nullptr; u32 vertexType = gstate.vertType; if ((vertexType & GE_VTYPE_IDX_MASK) != GE_VTYPE_IDX_NONE) { u32 indexAddr = gstate_c.indexAddr; @@ -1569,7 +1569,7 @@ void GPUCommon::Execute_Prim(u32 op, u32 diff) { UpdateUVScaleOffset(); // cull mode - int cullMode = gstate.isCullEnabled() ? gstate.getCullMode() : -1; + int cullMode = gstate.getCullMode(); uint32_t vertTypeID = GetVertTypeID(vertexType, gstate.getUVGenMode()); drawEngineCommon_->SubmitPrim(verts, inds, prim, count, vertTypeID, cullMode, &bytesRead); @@ -1609,20 +1609,14 @@ void GPUCommon::Execute_Prim(u32 op, u32 diff) { } GEPrimitiveType newPrim = static_cast((data >> 16) & 7); + SetDrawType(DRAW_PRIM, newPrim); // TODO: more efficient updating of verts/inds verts = Memory::GetPointerUnchecked(gstate_c.vertexAddr); - inds = 0; + inds = nullptr; if ((vertexType & GE_VTYPE_IDX_MASK) != GE_VTYPE_IDX_NONE) { inds = Memory::GetPointerUnchecked(gstate_c.indexAddr); } - if (newPrim != GE_PRIM_TRIANGLE_STRIP && cullMode != -1 && cullMode != gstate.getCullMode()) { - DEBUG_LOG(G3D, "flush cull mode before prim: %d", newPrim); - drawEngineCommon_->DispatchFlush(); - gstate.cmdmem[GE_CMD_CULL] ^= 1; - gstate_c.Dirty(DIRTY_RASTER_STATE); - } - drawEngineCommon_->SubmitPrim(verts, inds, newPrim, count, vertTypeID, cullMode, &bytesRead); AdvanceVerts(vertexType, count, bytesRead); totalVertCount += count; @@ -1641,8 +1635,13 @@ void GPUCommon::Execute_Prim(u32 op, u32 diff) { break; } case GE_CMD_VADDR: + gstate.cmdmem[data >> 24] = data; gstate_c.vertexAddr = gstate_c.getRelativeAddress(data & 0x00FFFFFF); break; + case GE_CMD_IADDR: + gstate.cmdmem[data >> 24] = data; + gstate_c.indexAddr = gstate_c.getRelativeAddress(data & 0x00FFFFFF); + break; case GE_CMD_OFFSETADDR: gstate.cmdmem[GE_CMD_OFFSETADDR] = data; gstate_c.offsetAddr = data << 8; @@ -1650,12 +1649,20 @@ void GPUCommon::Execute_Prim(u32 op, u32 diff) { case GE_CMD_BASE: gstate.cmdmem[GE_CMD_BASE] = data; break; + case GE_CMD_CULLFACEENABLE: + // Earth Defence Force 2 + if (gstate.cmdmem[GE_CMD_CULLFACEENABLE] != data) { + goto bail; + } + break; case GE_CMD_CULL: - // flip face by indices for GE_PRIM_TRIANGLE_STRIP + // flip face by indices for triangles cullMode = data & 1; break; + case GE_CMD_TEXFLUSH: case GE_CMD_NOP: case GE_CMD_NOP_FF: + gstate.cmdmem[data >> 24] = data; break; case GE_CMD_BONEMATRIXNUMBER: gstate.cmdmem[GE_CMD_BONEMATRIXNUMBER] = data; @@ -1698,6 +1705,12 @@ void GPUCommon::Execute_Prim(u32 op, u32 diff) { break; } + case GE_CMD_TEXBUFWIDTH0: + case GE_CMD_TEXADDR0: + if (data != gstate.cmdmem[data >> 24]) + goto bail; + break; + default: // All other commands might need a flush or something, stop this inner loop. goto bail; @@ -1713,8 +1726,11 @@ bail: UpdatePC(currentList->pc, currentList->pc + cmdCount * 4); currentList->pc += cmdCount * 4; // flush back cull mode - if (cullMode != -1 && cullMode != gstate.getCullMode()) { + if (cullMode != gstate.getCullMode()) { + // We rewrote everything to the old cull mode, so flush first. drawEngineCommon_->DispatchFlush(); + + // Now update things for next time. gstate.cmdmem[GE_CMD_CULL] ^= 1; gstate_c.Dirty(DIRTY_RASTER_STATE); } @@ -1754,33 +1770,37 @@ void GPUCommon::Execute_Bezier(u32 op, u32 diff) { DEBUG_LOG_REPORT(G3D, "Unusual bezier/spline vtype: %08x, morph: %d, bones: %d", gstate.vertType, (gstate.vertType & GE_VTYPE_MORPHCOUNT_MASK) >> GE_VTYPE_MORPHCOUNT_SHIFT, vertTypeGetNumBoneWeights(gstate.vertType)); } - GEPatchPrimType patchPrim = gstate.getPatchPrimitiveType(); - SetDrawType(DRAW_BEZIER, PatchPrimToPrim(patchPrim)); + Spline::BezierSurface surface; + surface.tess_u = gstate.getPatchDivisionU(); + surface.tess_v = gstate.getPatchDivisionV(); + surface.num_points_u = op & 0xFF; + surface.num_points_v = (op >> 8) & 0xFF; + surface.num_patches_u = (surface.num_points_u - 1) / 3; + surface.num_patches_v = (surface.num_points_v - 1) / 3; + surface.primType = gstate.getPatchPrimitiveType(); + surface.patchFacing = gstate.patchfacing & 1; - int bz_ucount = op & 0xFF; - int bz_vcount = (op >> 8) & 0xFF; - bool computeNormals = gstate.isLightingEnabled(); - bool patchFacing = gstate.patchfacing & 1; + SetDrawType(DRAW_BEZIER, PatchPrimToPrim(surface.primType)); - if (CanUseHardwareTessellation(patchPrim)) { + if (CanUseHardwareTessellation(surface.primType)) { gstate_c.Dirty(DIRTY_VERTEXSHADER_STATE); gstate_c.bezier = true; - if (gstate_c.spline_num_points_u != bz_ucount) { + if (gstate_c.spline_num_points_u != surface.num_points_u) { gstate_c.Dirty(DIRTY_BEZIERSPLINE); - gstate_c.spline_num_points_u = bz_ucount; + gstate_c.spline_num_points_u = surface.num_points_u; } } int bytesRead = 0; UpdateUVScaleOffset(); - drawEngineCommon_->SubmitBezier(control_points, indices, gstate.getPatchDivisionU(), gstate.getPatchDivisionV(), bz_ucount, bz_vcount, patchPrim, computeNormals, patchFacing, gstate.vertType, &bytesRead); + drawEngineCommon_->SubmitCurve(control_points, indices, surface, gstate.vertType, &bytesRead, "bezier"); if (gstate_c.bezier) gstate_c.Dirty(DIRTY_VERTEXSHADER_STATE); gstate_c.bezier = false; // After drawing, we advance pointers - see SubmitPrim which does the same. - int count = bz_ucount * bz_vcount; + int count = surface.num_points_u * surface.num_points_v; AdvanceVerts(gstate.vertType, count, bytesRead); } @@ -1814,35 +1834,39 @@ void GPUCommon::Execute_Spline(u32 op, u32 diff) { DEBUG_LOG_REPORT(G3D, "Unusual bezier/spline vtype: %08x, morph: %d, bones: %d", gstate.vertType, (gstate.vertType & GE_VTYPE_MORPHCOUNT_MASK) >> GE_VTYPE_MORPHCOUNT_SHIFT, vertTypeGetNumBoneWeights(gstate.vertType)); } - int sp_ucount = op & 0xFF; - int sp_vcount = (op >> 8) & 0xFF; - int sp_utype = (op >> 16) & 0x3; - int sp_vtype = (op >> 18) & 0x3; - GEPatchPrimType patchPrim = gstate.getPatchPrimitiveType(); - SetDrawType(DRAW_SPLINE, PatchPrimToPrim(patchPrim)); - bool computeNormals = gstate.isLightingEnabled(); - bool patchFacing = gstate.patchfacing & 1; - u32 vertType = gstate.vertType; + Spline::SplineSurface surface; + surface.tess_u = gstate.getPatchDivisionU(); + surface.tess_v = gstate.getPatchDivisionV(); + surface.type_u = (op >> 16) & 0x3; + surface.type_v = (op >> 18) & 0x3; + surface.num_points_u = op & 0xFF; + surface.num_points_v = (op >> 8) & 0xFF; + surface.num_patches_u = surface.num_points_u - 3; + surface.num_patches_v = surface.num_points_v - 3; + surface.primType = gstate.getPatchPrimitiveType(); + surface.patchFacing = gstate.patchfacing & 1; - if (CanUseHardwareTessellation(patchPrim)) { + SetDrawType(DRAW_SPLINE, PatchPrimToPrim(surface.primType)); + + if (CanUseHardwareTessellation(surface.primType)) { gstate_c.Dirty(DIRTY_VERTEXSHADER_STATE); gstate_c.spline = true; - if (gstate_c.spline_num_points_u != sp_ucount) { + if (gstate_c.spline_num_points_u != surface.num_points_u) { gstate_c.Dirty(DIRTY_BEZIERSPLINE); - gstate_c.spline_num_points_u = sp_ucount; + gstate_c.spline_num_points_u = surface.num_points_u; } } int bytesRead = 0; UpdateUVScaleOffset(); - drawEngineCommon_->SubmitSpline(control_points, indices, gstate.getPatchDivisionU(), gstate.getPatchDivisionV(), sp_ucount, sp_vcount, sp_utype, sp_vtype, patchPrim, computeNormals, patchFacing, vertType, &bytesRead); + drawEngineCommon_->SubmitCurve(control_points, indices, surface, gstate.vertType, &bytesRead, "spline"); if (gstate_c.spline) gstate_c.Dirty(DIRTY_VERTEXSHADER_STATE); gstate_c.spline = false; // After drawing, we advance pointers - see SubmitPrim which does the same. - int count = sp_ucount * sp_vcount; + int count = surface.num_points_u * surface.num_points_v; AdvanceVerts(gstate.vertType, count, bytesRead); } @@ -2220,7 +2244,7 @@ void GPUCommon::FlushImm() { int bytesRead; uint32_t vertTypeID = GetVertTypeID(vtype, 0); - drawEngineCommon_->DispatchSubmitPrim(temp, nullptr, immPrim_, immCount_, vertTypeID, &bytesRead); + drawEngineCommon_->DispatchSubmitPrim(temp, nullptr, immPrim_, immCount_, vertTypeID, gstate.getCullMode(), &bytesRead); drawEngineCommon_->DispatchFlush(); // TOOD: In the future, make a special path for these. // drawEngineCommon_->DispatchSubmitImm(immBuffer_, immCount_); @@ -2614,6 +2638,7 @@ void GPUCommon::DoBlockTransfer(u32 skipDrawReason) { const u8 *src = Memory::GetPointerUnchecked(srcLineStartAddr); u8 *dst = Memory::GetPointerUnchecked(dstLineStartAddr); memcpy(dst, src, width * height * bpp); + GPURecord::NotifyMemcpy(dstLineStartAddr, srcLineStartAddr, width * height * bpp); } else { for (int y = 0; y < height; y++) { u32 srcLineStartAddr = srcBasePtr + ((y + srcY) * srcStride + srcX) * bpp; @@ -2622,6 +2647,7 @@ void GPUCommon::DoBlockTransfer(u32 skipDrawReason) { const u8 *src = Memory::GetPointerUnchecked(srcLineStartAddr); u8 *dst = Memory::GetPointerUnchecked(dstLineStartAddr); memcpy(dst, src, width * bpp); + GPURecord::NotifyMemcpy(dstLineStartAddr, srcLineStartAddr, width * bpp); } } @@ -2698,9 +2724,8 @@ void GPUCommon::InvalidateCache(u32 addr, int size, GPUInvalidationType type) { textureCache_->InvalidateAll(type); if (type != GPU_INVALIDATE_ALL && framebufferManager_->MayIntersectFramebuffer(addr)) { - // If we're doing block transfers, we shouldn't need this, and it'll only confuse us. // Vempire invalidates (with writeback) after drawing, but before blitting. - if (!g_Config.bBlockTransferGPU || type == GPU_INVALIDATE_SAFE) { + if (type == GPU_INVALIDATE_SAFE) { framebufferManager_->UpdateFromMemory(addr, size, type == GPU_INVALIDATE_SAFE); } } @@ -2723,24 +2748,24 @@ bool GPUCommon::PerformStencilUpload(u32 dest, int size) { } bool GPUCommon::GetCurrentFramebuffer(GPUDebugBuffer &buffer, GPUDebugFramebufferType type, int maxRes) { - u32 fb_address = type == GPU_DBG_FRAMEBUF_RENDER ? gstate.getFrameBufRawAddress() : framebufferManager_->DisplayFramebufAddr(); + u32 fb_address = type == GPU_DBG_FRAMEBUF_RENDER ? (gstate.getFrameBufRawAddress() | 0x04000000) : framebufferManager_->DisplayFramebufAddr(); int fb_stride = type == GPU_DBG_FRAMEBUF_RENDER ? gstate.FrameBufStride() : framebufferManager_->DisplayFramebufStride(); GEBufferFormat format = type == GPU_DBG_FRAMEBUF_RENDER ? gstate.FrameBufFormat() : framebufferManager_->DisplayFramebufFormat(); return framebufferManager_->GetFramebuffer(fb_address, fb_stride, format, buffer, maxRes); } bool GPUCommon::GetCurrentDepthbuffer(GPUDebugBuffer &buffer) { - u32 fb_address = gstate.getFrameBufRawAddress(); + u32 fb_address = gstate.getFrameBufRawAddress() | 0x04000000; int fb_stride = gstate.FrameBufStride(); - u32 z_address = gstate.getDepthBufRawAddress(); + u32 z_address = gstate.getDepthBufRawAddress() | 0x04000000; int z_stride = gstate.DepthBufStride(); return framebufferManager_->GetDepthbuffer(fb_address, fb_stride, z_address, z_stride, buffer); } bool GPUCommon::GetCurrentStencilbuffer(GPUDebugBuffer &buffer) { - u32 fb_address = gstate.getFrameBufRawAddress(); + u32 fb_address = gstate.getFrameBufRawAddress() | 0x04000000; int fb_stride = gstate.FrameBufStride(); return framebufferManager_->GetStencilbuffer(fb_address, fb_stride, buffer); diff --git a/GPU/GPUState.h b/GPU/GPUState.h index b82835d2c7..1375895199 100644 --- a/GPU/GPUState.h +++ b/GPU/GPUState.h @@ -252,6 +252,7 @@ struct GPUgstate { // Color Mask u32 getColorMask() const { return (pmskc & 0xFFFFFF) | ((pmska & 0xFF) << 24); } + u8 getStencilWriteMask() const { return pmska & 0xFF; } bool isLogicOpEnabled() const { return logicOpEnable & 1; } GELogicOp getLogicOp() const { return static_cast(lop & 0xF); } @@ -326,8 +327,8 @@ struct GPUgstate { bool isLightingEnabled() const { return lightingEnable & 1; } bool isLightChanEnabled(int chan) const { return lightEnable[chan] & 1; } GELightComputation getLightComputation(int chan) const { return static_cast(ltype[chan] & 0x3); } - bool isUsingPoweredDiffuseLight(int chan) const { return getLightComputation(chan) == GE_LIGHTCOMP_BOTHWITHPOWDIFFUSE; } - bool isUsingSpecularLight(int chan) const { return getLightComputation(chan) != GE_LIGHTCOMP_ONLYDIFFUSE; } + bool isUsingPoweredDiffuseLight(int chan) const { return getLightComputation(chan) == GE_LIGHTCOMP_ONLYPOWDIFFUSE; } + bool isUsingSpecularLight(int chan) const { return getLightComputation(chan) == GE_LIGHTCOMP_BOTH; } bool isUsingSecondaryColor() const { return lmode & 1; } GELightType getLightType(int chan) const { return static_cast((ltype[chan] >> 8) & 3); } bool isDirectionalLight(int chan) const { return getLightType(chan) == GE_LIGHTTYPE_DIRECTIONAL; } diff --git a/GPU/Null/NullGpu.cpp b/GPU/Null/NullGpu.cpp index c4b345d96e..34f6b1d77d 100644 --- a/GPU/Null/NullGpu.cpp +++ b/GPU/Null/NullGpu.cpp @@ -29,7 +29,7 @@ class NullDrawEngine : public DrawEngineCommon { public: void DispatchFlush() override { } - void DispatchSubmitPrim(void *verts, void *inds, GEPrimitiveType prim, int vertexCount, u32 vertTypeID, int *bytesRead) override { + void DispatchSubmitPrim(void *verts, void *inds, GEPrimitiveType prim, int vertexCount, u32 vertTypeID, int cullMode, int *bytesRead) override { } }; diff --git a/GPU/Software/Clipper.cpp b/GPU/Software/Clipper.cpp index 1ab91015eb..eb181ce613 100644 --- a/GPU/Software/Clipper.cpp +++ b/GPU/Software/Clipper.cpp @@ -176,10 +176,10 @@ void ProcessRect(const VertexData& v0, const VertexData& v1) } // Four triangles to do backfaces as well. Two of them will get backface culled. - ProcessTriangle(*topleft, *topright, *bottomright); - ProcessTriangle(*bottomright, *topright, *topleft); - ProcessTriangle(*bottomright, *bottomleft, *topleft); - ProcessTriangle(*topleft, *bottomleft, *bottomright); + ProcessTriangle(*topleft, *topright, *bottomright, buf[3]); + ProcessTriangle(*bottomright, *topright, *topleft, buf[3]); + ProcessTriangle(*bottomright, *bottomleft, *topleft, buf[3]); + ProcessTriangle(*topleft, *bottomleft, *bottomright, buf[3]); } else { // through mode handling VertexData buf[4]; @@ -271,10 +271,17 @@ void ProcessLine(VertexData& v0, VertexData& v1) Rasterizer::DrawLine(data[0], data[1]); } -void ProcessTriangle(VertexData& v0, VertexData& v1, VertexData& v2) -{ +void ProcessTriangle(VertexData& v0, VertexData& v1, VertexData& v2, const VertexData &provoking) { if (gstate.isModeThrough()) { - Rasterizer::DrawTriangle(v0, v1, v2); + // In case of cull reordering, make sure the right color is on the final vertex. + if (gstate.getShadeMode() == GE_SHADE_FLAT) { + VertexData corrected2 = v2; + corrected2.color0 = provoking.color0; + corrected2.color1 = provoking.color1; + Rasterizer::DrawTriangle(v0, v1, corrected2); + } else { + Rasterizer::DrawTriangle(v0, v1, v2); + } return; } @@ -339,14 +346,19 @@ void ProcessTriangle(VertexData& v0, VertexData& v1, VertexData& v2) return; } - for (int i = 0; i+3 <= numIndices; i+=3) - { - if(indices[i] != SKIP_FLAG) - { + for (int i = 0; i + 3 <= numIndices; i += 3) { + if (indices[i] != SKIP_FLAG) { VertexData data[3] = { *Vertices[indices[i]], *Vertices[indices[i+1]], *Vertices[indices[i+2]] }; data[0].screenpos = TransformUnit::ClipToScreen(data[0].clippos); data[1].screenpos = TransformUnit::ClipToScreen(data[1].clippos); data[2].screenpos = TransformUnit::ClipToScreen(data[2].clippos); + + if (gstate.getShadeMode() == GE_SHADE_FLAT) { + // So that the order of clipping doesn't matter... + data[2].color0 = provoking.color0; + data[2].color1 = provoking.color1; + } + Rasterizer::DrawTriangle(data[0], data[1], data[2]); } } diff --git a/GPU/Software/Clipper.h b/GPU/Software/Clipper.h index e0926e6248..d00262001a 100644 --- a/GPU/Software/Clipper.h +++ b/GPU/Software/Clipper.h @@ -23,7 +23,7 @@ namespace Clipper { void ProcessPoint(VertexData& v0); void ProcessLine(VertexData& v0, VertexData& v1); -void ProcessTriangle(VertexData& v0, VertexData& v1, VertexData& v2); +void ProcessTriangle(VertexData& v0, VertexData& v1, VertexData& v2, const VertexData &provoking); void ProcessRect(const VertexData& v0, const VertexData& v1); } diff --git a/GPU/Software/Lighting.cpp b/GPU/Software/Lighting.cpp index c322e381a9..5246d9124d 100644 --- a/GPU/Software/Lighting.cpp +++ b/GPU/Software/Lighting.cpp @@ -21,8 +21,22 @@ namespace Lighting { -void Process(VertexData& vertex, bool hasColor) -{ +static inline Vec3f GetLightVec(u32 lparams[12], int light) { + return Vec3(getFloat24(lparams[3 * light]), getFloat24(lparams[3 * light + 1]), getFloat24(lparams[3 * light + 2])); +} + +static inline float pspLightPow(float v, float e) { + if (e == 0.0f) { + return 1.0f; + } + if (v > 0.0f) { + return pow(v, e); + } + // Negative stays negative, so let's just return the original. + return v; +} + +void Process(VertexData& vertex, bool hasColor) { const int materialupdate = gstate.materialupdate & (hasColor ? 7 : 0); Vec3 vcol0 = vertex.color0.rgb().Cast() * Vec3::AssignToAll(1.0f / 255.0f); @@ -35,10 +49,11 @@ void Process(VertexData& vertex, bool hasColor) for (unsigned int light = 0; light < 4; ++light) { // Always calculate texture coords from lighting results if environment mapping is active // TODO: Should specular lighting should affect this, too? Doesn't in GLES. - // TODO: Not sure if this really should be done even if lighting is disabled altogether + // This should be done even if lighting is disabled altogether. if (gstate.getUVGenMode() == GE_TEXMAP_ENVIRONMENT_MAP) { - Vec3 L = Vec3(getFloat24(gstate.lpos[3 * light]), getFloat24(gstate.lpos[3 * light + 1]),getFloat24(gstate.lpos[3 * light + 2])); - float diffuse_factor = Dot(L.Normalized(), vertex.worldnormal); + Vec3 L = GetLightVec(gstate.lpos, light); + // In other words, L.Length2() == 0.0f means Dot({0, 0, 1}, worldnormal). + float diffuse_factor = L.Length2() == 0.0f ? vertex.worldnormal.z : Dot(L.Normalized(), vertex.worldnormal); if (gstate.getUVLS0() == (int)light) vertex.texturecoords.s() = (diffuse_factor + 1.f) / 2.f; @@ -57,30 +72,28 @@ void Process(VertexData& vertex, bool hasColor) // L = vector from vertex to light source // TODO: Should transfer the light positions to world/view space for these calculations? - Vec3 L = Vec3(getFloat24(gstate.lpos[3 * light]), getFloat24(gstate.lpos[3 * light + 1]),getFloat24(gstate.lpos[3 * light + 2])); + Vec3 L = GetLightVec(gstate.lpos, light); if (!gstate.isDirectionalLight(light)) { L -= vertex.worldpos; } + // TODO: Should this normalize (0, 0, 0) to (0, 0, 1)? float d = L.Normalize(); - float lka = getFloat24(gstate.latt[3 * light]); - float lkb = getFloat24(gstate.latt[3 * light + 1]); - float lkc = getFloat24(gstate.latt[3 * light + 2]); float att = 1.f; if (!gstate.isDirectionalLight(light)) { - att = 1.f / (lka + lkb * d + lkc * d * d); + att = 1.f / Dot(GetLightVec(gstate.latt, light), Vec3f(1.0f, d, d * d)); if (att > 1.f) att = 1.f; if (att < 0.f) att = 0.f; } float spot = 1.f; if (gstate.isSpotLight(light)) { - Vec3 dir = Vec3(getFloat24(gstate.ldir[3 * light]), getFloat24(gstate.ldir[3 * light + 1]),getFloat24(gstate.ldir[3 * light + 2])); - float _spot = Dot(dir.Normalized(), L); + Vec3 dir = GetLightVec(gstate.ldir, light); + float rawSpot = dir.Length2() == 0.0f ? 0.0f : Dot(dir.Normalized(), L); float cutoff = getFloat24(gstate.lcutoff[light]); - if (_spot >= cutoff) { + if (rawSpot >= cutoff) { float conv = getFloat24(gstate.lconv[light]); - spot = pow(_spot, conv); + spot = pspLightPow(rawSpot, conv); } else { spot = 0.f; } @@ -97,20 +110,14 @@ void Process(VertexData& vertex, bool hasColor) float diffuse_factor = Dot(L, vertex.worldnormal); if (gstate.isUsingPoweredDiffuseLight(light)) { float k = gstate.getMaterialSpecularCoef(); - // TODO: Validate Tales of the World: Radiant Mythology (#2424.) - // pow(0.0, 0.0) may be undefined, but the PSP seems to treat it as 1.0. - if (diffuse_factor <= 0.0f && k == 0.0f) { - diffuse_factor = 1.0f; - } else { - diffuse_factor = pow(diffuse_factor, k); - } + diffuse_factor = pspLightPow(diffuse_factor, k); } if (diffuse_factor > 0.f) { final_color += ldc * mdc * diffuse_factor * att * spot; } - if (gstate.isUsingSpecularLight(light)) { + if (gstate.isUsingSpecularLight(light) && diffuse_factor >= 0.0f) { Vec3 H = L + Vec3(0.f, 0.f, 1.f); Vec3 lsc = Vec3::FromRGB(gstate.getSpecularColor(light)); @@ -118,7 +125,7 @@ void Process(VertexData& vertex, bool hasColor) float specular_factor = Dot(H.Normalized(), vertex.worldnormal); float k = gstate.getMaterialSpecularCoef(); - specular_factor = pow(specular_factor, k); + specular_factor = pspLightPow(specular_factor, k); if (specular_factor > 0.f) { specular_color += lsc * msc * specular_factor * att * spot; diff --git a/GPU/Software/Rasterizer.cpp b/GPU/Software/Rasterizer.cpp index a507224193..ce64220294 100644 --- a/GPU/Software/Rasterizer.cpp +++ b/GPU/Software/Rasterizer.cpp @@ -199,6 +199,7 @@ static inline void GetTextureCoordinates(const VertexData& v0, const VertexData& case GE_TEXMAP_TEXTURE_COORDS: case GE_TEXMAP_UNKNOWN: case GE_TEXMAP_ENVIRONMENT_MAP: + case GE_TEXMAP_TEXTURE_MATRIX: { // TODO: What happens if vertex has no texture coordinates? // Note that for environment mapping, texture coordinates have been calculated during lighting @@ -212,39 +213,6 @@ static inline void GetTextureCoordinates(const VertexData& v0, const VertexData& t = (v0.texturecoords.t() * wq0 + v1.texturecoords.t() * wq1) * q_recip; } break; - case GE_TEXMAP_TEXTURE_MATRIX: - { - // projection mapping, TODO: Move this code to TransformUnit! - Vec3 source; - switch (gstate.getUVProjMode()) { - case GE_PROJMAP_POSITION: - source = (v0.modelpos * p + v1.modelpos * (1.0f - p)); - break; - - case GE_PROJMAP_UV: - source = Vec3f((v0.texturecoords * p + v1.texturecoords * (1.0f - p)), 0.0f); - break; - - case GE_PROJMAP_NORMALIZED_NORMAL: - source = (v0.normal.Normalized() * p + v1.normal.Normalized() * (1.0f - p)); - break; - - case GE_PROJMAP_NORMAL: - source = (v0.normal * p + v1.normal * (1.0f - p)); - break; - - default: - ERROR_LOG_REPORT(G3D, "Software: Unsupported UV projection mode %x", gstate.getUVProjMode()); - break; - } - - Mat3x3 tgen(gstate.tgenMatrix); - Vec3 stq = tgen * source + Vec3(gstate.tgenMatrix[9], gstate.tgenMatrix[10], gstate.tgenMatrix[11]); - float z_recip = 1.0f / stq.z; - s = stq.x * z_recip; - t = stq.y * z_recip; - } - break; default: ERROR_LOG_REPORT(G3D, "Software: Unsupported texture mapping mode %x!", gstate.getUVGenMode()); s = 0.0f; @@ -259,6 +227,7 @@ static inline void GetTextureCoordinates(const VertexData& v0, const VertexData& case GE_TEXMAP_TEXTURE_COORDS: case GE_TEXMAP_UNKNOWN: case GE_TEXMAP_ENVIRONMENT_MAP: + case GE_TEXMAP_TEXTURE_MATRIX: { // TODO: What happens if vertex has no texture coordinates? // Note that for environment mapping, texture coordinates have been calculated during lighting @@ -274,39 +243,6 @@ static inline void GetTextureCoordinates(const VertexData& v0, const VertexData& t = Interpolate(v0.texturecoords.t(), v1.texturecoords.t(), v2.texturecoords.t(), wq0, wq1, wq2, q_recip); } break; - case GE_TEXMAP_TEXTURE_MATRIX: - for (int i = 0; i < 4; ++i) { - // projection mapping, TODO: Move this code to TransformUnit! - Vec3 source; - switch (gstate.getUVProjMode()) { - case GE_PROJMAP_POSITION: - source = (v0.modelpos * w0[i] + v1.modelpos * w1[i] + v2.modelpos * w2[i]) * wsum_recip[i]; - break; - - case GE_PROJMAP_UV: - source = Vec3f((v0.texturecoords * w0[i] + v1.texturecoords * w1[i] + v2.texturecoords * w2[i]) * wsum_recip[i], 0.0f); - break; - - case GE_PROJMAP_NORMALIZED_NORMAL: - source = (v0.normal.Normalized() * w0[i] + v1.normal.Normalized() * w1[i] + v2.normal.Normalized() * w2[i]) * wsum_recip[i]; - break; - - case GE_PROJMAP_NORMAL: - source = (v0.normal * w0[i] + v1.normal * w1[i] + v2.normal * w2[i]) * wsum_recip[i]; - break; - - default: - ERROR_LOG_REPORT(G3D, "Software: Unsupported UV projection mode %x", gstate.getUVProjMode()); - break; - } - - Mat3x3 tgen(gstate.tgenMatrix); - Vec3 stq = tgen * source + Vec3(gstate.tgenMatrix[9], gstate.tgenMatrix[10], gstate.tgenMatrix[11]); - float z_recip = 1.0f / stq.z; - s[i] = stq.x * z_recip; - t[i] = stq.y * z_recip; - } - break; default: ERROR_LOG_REPORT(G3D, "Software: Unsupported texture mapping mode %x!", gstate.getUVGenMode()); s = Vec4::AssignToAll(0.0f); @@ -487,32 +423,33 @@ static inline bool StencilTestPassed(u8 stencil) static inline u8 ApplyStencilOp(int op, u8 old_stencil) { // TODO: Apply mask to reference or old stencil? u8 reference_stencil = gstate.getStencilTestRef(); // TODO: Apply mask? + const u8 write_mask = gstate.getStencilWriteMask(); switch (op) { case GE_STENCILOP_KEEP: return old_stencil; case GE_STENCILOP_ZERO: - return 0; + return old_stencil & write_mask; case GE_STENCILOP_REPLACE: - return reference_stencil; + return (reference_stencil & ~write_mask) | (old_stencil & write_mask); case GE_STENCILOP_INVERT: - return ~old_stencil; + return (~old_stencil & ~write_mask) | (old_stencil & write_mask); case GE_STENCILOP_INCR: switch (gstate.FrameBufFormat()) { case GE_FORMAT_8888: if (old_stencil != 0xFF) { - return old_stencil + 1; + return ((old_stencil + 1) & ~write_mask) | (old_stencil & write_mask); } return old_stencil; case GE_FORMAT_5551: - return 0xFF; + return ~write_mask | (old_stencil & write_mask); case GE_FORMAT_4444: if (old_stencil < 0xF0) { - return old_stencil + 0x10; + return ((old_stencil + 0x10) & ~write_mask) | (old_stencil & write_mask); } return old_stencil; default: @@ -524,11 +461,11 @@ static inline u8 ApplyStencilOp(int op, u8 old_stencil) { switch (gstate.FrameBufFormat()) { case GE_FORMAT_4444: if (old_stencil >= 0x10) - return old_stencil - 0x10; + return ((old_stencil - 0x10) & ~write_mask) | (old_stencil & write_mask); break; default: if (old_stencil != 0) - return old_stencil - 1; + return ((old_stencil - 1) & ~write_mask) | (old_stencil & write_mask); return old_stencil; } break; @@ -1512,39 +1449,35 @@ void ClearRectangle(const VertexData &v0, const VertexData &v1) } } - const u32 new_color = v1.color0.ToRGBA(); - u16 new_color16; - // Note: this stays 0xFFFFFFFF if keeping color and alpha, even for 16-bit. u32 keepOldMask = 0xFFFFFFFF; + if (gstate.isClearModeColorMask()) + keepOldMask &= 0xFF000000; + if (gstate.isClearModeAlphaMask()) + keepOldMask &= 0x00FFFFFF; + + // The pixel write masks are respected in clear mode. + keepOldMask |= gstate.getColorMask(); + + const u32 new_color = v1.color0.ToRGBA(); + u16 new_color16; switch (gstate.FrameBufFormat()) { case GE_FORMAT_565: new_color16 = RGBA8888ToRGB565(new_color); - if (gstate.isClearModeColorMask()) - keepOldMask = 0; + keepOldMask = keepOldMask == 0 ? 0 : (0xFFFF0000 | RGBA8888ToRGB565(keepOldMask)); break; case GE_FORMAT_5551: new_color16 = RGBA8888ToRGBA5551(new_color); - if (gstate.isClearModeColorMask()) - keepOldMask &= 0x00008000; - if (gstate.isClearModeAlphaMask()) - keepOldMask &= 0x00007FFF; + keepOldMask = keepOldMask == 0 ? 0 : (0xFFFF0000 | RGBA8888ToRGBA5551(keepOldMask)); break; case GE_FORMAT_4444: new_color16 = RGBA8888ToRGBA4444(new_color); - if (gstate.isClearModeColorMask()) - keepOldMask &= 0x0000F000; - if (gstate.isClearModeAlphaMask()) - keepOldMask &= 0x00000FFF; + keepOldMask = keepOldMask == 0 ? 0 : (0xFFFF0000 | RGBA8888ToRGBA4444(keepOldMask)); break; case GE_FORMAT_8888: - if (gstate.isClearModeColorMask()) - keepOldMask &= 0xFF000000; - if (gstate.isClearModeAlphaMask()) - keepOldMask &= 0x00FFFFFF; break; case GE_FORMAT_INVALID: @@ -1552,9 +1485,6 @@ void ClearRectangle(const VertexData &v0, const VertexData &v1) break; } - // The pixel write masks are respected in clear mode. - keepOldMask &= ~gstate.getColorMask(); - if (keepOldMask == 0) { ScreenCoords pprime(minX, minY, 0); const int stride = gstate.FrameBufStride(); diff --git a/GPU/Software/SoftGpu.cpp b/GPU/Software/SoftGpu.cpp index 2673ef4ab2..f7e29dd665 100644 --- a/GPU/Software/SoftGpu.cpp +++ b/GPU/Software/SoftGpu.cpp @@ -38,6 +38,7 @@ #include "GPU/Software/TransformUnit.h" #include "GPU/Common/DrawEngineCommon.h" #include "GPU/Common/FramebufferCommon.h" +#include "GPU/Common/SplineCommon.h" #include "GPU/Debugger/Debugger.h" #include "GPU/Debugger/Record.h" @@ -142,6 +143,7 @@ void SoftGPU::SetDisplayFramebuffer(u32 framebuf, u32 stride, GEBufferFormat for displayStride_ = stride; displayFormat_ = format; GPUDebug::NotifyDisplay(framebuf, stride, format); + GPURecord::NotifyDisplay(framebuf, stride, format); } // Copies RGBA8 data from RAM to the currently bound render target. @@ -401,20 +403,24 @@ void SoftGPU::ExecuteOp(u32 op, u32 diff) { DEBUG_LOG_REPORT(G3D, "Unusual bezier/spline vtype: %08x, morph: %d, bones: %d", gstate.vertType, (gstate.vertType & GE_VTYPE_MORPHCOUNT_MASK) >> GE_VTYPE_MORPHCOUNT_SHIFT, vertTypeGetNumBoneWeights(gstate.vertType)); } - GEPatchPrimType patchPrim = gstate.getPatchPrimitiveType(); - SetDrawType(DRAW_BEZIER, PatchPrimToPrim(patchPrim)); + Spline::BezierSurface surface; + surface.tess_u = gstate.getPatchDivisionU(); + surface.tess_v = gstate.getPatchDivisionV(); + surface.num_points_u = op & 0xFF; + surface.num_points_v = (op >> 8) & 0xFF; + surface.num_patches_u = (surface.num_points_u - 1) / 3; + surface.num_patches_v = (surface.num_points_v - 1) / 3; + surface.primType = gstate.getPatchPrimitiveType(); + surface.patchFacing = gstate.patchfacing & 1; - int bz_ucount = op & 0xFF; - int bz_vcount = (op >> 8) & 0xFF; - bool computeNormals = gstate.isLightingEnabled(); - bool patchFacing = gstate.patchfacing & 1; + SetDrawType(DRAW_BEZIER, PatchPrimToPrim(surface.primType)); int bytesRead = 0; - drawEngineCommon_->SubmitBezier(control_points, indices, gstate.getPatchDivisionU(), gstate.getPatchDivisionV(), bz_ucount, bz_vcount, patchPrim, computeNormals, patchFacing, gstate.vertType, &bytesRead); + drawEngineCommon_->SubmitCurve(control_points, indices, surface, gstate.vertType, &bytesRead, "bezier"); framebufferDirty_ = true; // After drawing, we advance pointers - see SubmitPrim which does the same. - int count = bz_ucount * bz_vcount; + int count = surface.num_points_u * surface.num_points_v; AdvanceVerts(gstate.vertType, count, bytesRead); } break; @@ -449,22 +455,26 @@ void SoftGPU::ExecuteOp(u32 op, u32 diff) { DEBUG_LOG_REPORT(G3D, "Unusual bezier/spline vtype: %08x, morph: %d, bones: %d", gstate.vertType, (gstate.vertType & GE_VTYPE_MORPHCOUNT_MASK) >> GE_VTYPE_MORPHCOUNT_SHIFT, vertTypeGetNumBoneWeights(gstate.vertType)); } - int sp_ucount = op & 0xFF; - int sp_vcount = (op >> 8) & 0xFF; - int sp_utype = (op >> 16) & 0x3; - int sp_vtype = (op >> 18) & 0x3; - GEPatchPrimType patchPrim = gstate.getPatchPrimitiveType(); - SetDrawType(DRAW_SPLINE, PatchPrimToPrim(patchPrim)); - bool computeNormals = gstate.isLightingEnabled(); - bool patchFacing = gstate.patchfacing & 1; - u32 vertType = gstate.vertType; + Spline::SplineSurface surface; + surface.tess_u = gstate.getPatchDivisionU(); + surface.tess_v = gstate.getPatchDivisionV(); + surface.type_u = (op >> 16) & 0x3; + surface.type_v = (op >> 18) & 0x3; + surface.num_points_u = op & 0xFF; + surface.num_points_v = (op >> 8) & 0xFF; + surface.num_patches_u = surface.num_points_u - 3; + surface.num_patches_v = surface.num_points_v - 3; + surface.primType = gstate.getPatchPrimitiveType(); + surface.patchFacing = gstate.patchfacing & 1; + + SetDrawType(DRAW_SPLINE, PatchPrimToPrim(surface.primType)); int bytesRead = 0; - drawEngineCommon_->SubmitSpline(control_points, indices, gstate.getPatchDivisionU(), gstate.getPatchDivisionV(), sp_ucount, sp_vcount, sp_utype, sp_vtype, patchPrim, computeNormals, patchFacing, vertType, &bytesRead); + drawEngineCommon_->SubmitCurve(control_points, indices, surface, gstate.vertType, &bytesRead, "spline"); framebufferDirty_ = true; // After drawing, we advance pointers - see SubmitPrim which does the same. - int count = sp_ucount * sp_vcount; + int count = surface.num_points_u * surface.num_points_v; AdvanceVerts(gstate.vertType, count, bytesRead); } break; diff --git a/GPU/Software/TransformUnit.cpp b/GPU/Software/TransformUnit.cpp index e72e9a85cb..3b0603fd79 100644 --- a/GPU/Software/TransformUnit.cpp +++ b/GPU/Software/TransformUnit.cpp @@ -52,7 +52,8 @@ SoftwareDrawEngine::~SoftwareDrawEngine() { void SoftwareDrawEngine::DispatchFlush() { } -void SoftwareDrawEngine::DispatchSubmitPrim(void *verts, void *inds, GEPrimitiveType prim, int vertexCount, u32 vertTypeID, int *bytesRead) { +void SoftwareDrawEngine::DispatchSubmitPrim(void *verts, void *inds, GEPrimitiveType prim, int vertexCount, u32 vertTypeID, int cullMode, int *bytesRead) { + _assert_msg_(G3D, cullMode == gstate.getCullMode(), "Mixed cull mode not supported."); transformUnit.SubmitPrimitive(verts, inds, prim, vertexCount, vertTypeID, bytesRead, this); } @@ -234,12 +235,44 @@ VertexData TransformUnit::ReadVertex(VertexReader& vreader) if (vreader.hasNormal()) { vertex.worldnormal = TransformUnit::ModelToWorldNormal(vertex.normal); - // TODO: Isn't there a flag that controls whether to normalize the normal? vertex.worldnormal /= vertex.worldnormal.Length(); } else { vertex.worldnormal = Vec3(0.0f, 0.0f, 1.0f); } + // Time to generate some texture coords. Lighting will handle shade mapping. + if (gstate.getUVGenMode() == GE_TEXMAP_TEXTURE_MATRIX) { + Vec3f source; + switch (gstate.getUVProjMode()) { + case GE_PROJMAP_POSITION: + source = vertex.modelpos; + break; + + case GE_PROJMAP_UV: + source = Vec3f(vertex.texturecoords, 0.0f); + break; + + case GE_PROJMAP_NORMALIZED_NORMAL: + source = vertex.normal.Normalized(); + break; + + case GE_PROJMAP_NORMAL: + source = vertex.normal; + break; + + default: + source = Vec3f::AssignToAll(0.0f); + ERROR_LOG_REPORT(G3D, "Software: Unsupported UV projection mode %x", gstate.getUVProjMode()); + break; + } + + // TODO: What about uv scale and offset? + Mat3x3 tgen(gstate.tgenMatrix); + Vec3 stq = tgen * source + Vec3(gstate.tgenMatrix[9], gstate.tgenMatrix[10], gstate.tgenMatrix[11]); + float z_recip = 1.0f / stq.z; + vertex.texturecoords = Vec2f(stq.x * z_recip, stq.y * z_recip); + } + Lighting::Process(vertex, vreader.hasColor0()); } else { vertex.screenpos.x = (int)(pos[0] * 16) + gstate.getOffsetX16(); @@ -342,12 +375,12 @@ void TransformUnit::SubmitPrimitive(void* vertices, void* indices, GEPrimitiveTy case GE_PRIM_TRIANGLES: { if (!gstate.isCullEnabled() || gstate.isModeClear()) { - Clipper::ProcessTriangle(data[0], data[1], data[2]); - Clipper::ProcessTriangle(data[2], data[1], data[0]); + Clipper::ProcessTriangle(data[0], data[1], data[2], data[2]); + Clipper::ProcessTriangle(data[2], data[1], data[0], data[2]); } else if (!gstate.getCullMode()) { - Clipper::ProcessTriangle(data[2], data[1], data[0]); + Clipper::ProcessTriangle(data[2], data[1], data[0], data[2]); } else { - Clipper::ProcessTriangle(data[0], data[1], data[2]); + Clipper::ProcessTriangle(data[0], data[1], data[2], data[2]); } break; } @@ -413,7 +446,8 @@ void TransformUnit::SubmitPrimitive(void* vertices, void* indices, GEPrimitiveTy vreader.Goto(vtx); } - data[(data_index++) % 3] = ReadVertex(vreader); + int provoking_index = (data_index++) % 3; + data[provoking_index] = ReadVertex(vreader); if (outside_range_flag) { // Drop all primitives containing the current vertex skip_count = 2; @@ -427,14 +461,14 @@ void TransformUnit::SubmitPrimitive(void* vertices, void* indices, GEPrimitiveTy } if (!gstate.isCullEnabled() || gstate.isModeClear()) { - Clipper::ProcessTriangle(data[0], data[1], data[2]); - Clipper::ProcessTriangle(data[2], data[1], data[0]); + Clipper::ProcessTriangle(data[0], data[1], data[2], data[provoking_index]); + Clipper::ProcessTriangle(data[2], data[1], data[0], data[provoking_index]); } else if ((!gstate.getCullMode()) ^ ((data_index - 1) % 2)) { // We need to reverse the vertex order for each second primitive, // but we additionally need to do that for every primitive if CCW cullmode is used. - Clipper::ProcessTriangle(data[2], data[1], data[0]); + Clipper::ProcessTriangle(data[2], data[1], data[0], data[provoking_index]); } else { - Clipper::ProcessTriangle(data[0], data[1], data[2]); + Clipper::ProcessTriangle(data[0], data[1], data[2], data[provoking_index]); } } break; @@ -466,7 +500,8 @@ void TransformUnit::SubmitPrimitive(void* vertices, void* indices, GEPrimitiveTy vreader.Goto(vtx); } - data[2 - ((data_index++) % 2)] = ReadVertex(vreader); + int provoking_index = 2 - ((data_index++) % 2); + data[provoking_index] = ReadVertex(vreader); if (outside_range_flag) { // Drop all primitives containing the current vertex skip_count = 2; @@ -480,14 +515,14 @@ void TransformUnit::SubmitPrimitive(void* vertices, void* indices, GEPrimitiveTy } if (!gstate.isCullEnabled() || gstate.isModeClear()) { - Clipper::ProcessTriangle(data[0], data[1], data[2]); - Clipper::ProcessTriangle(data[2], data[1], data[0]); + Clipper::ProcessTriangle(data[0], data[1], data[2], data[provoking_index]); + Clipper::ProcessTriangle(data[2], data[1], data[0], data[provoking_index]); } else if ((!gstate.getCullMode()) ^ ((data_index - 1) % 2)) { // We need to reverse the vertex order for each second primitive, // but we additionally need to do that for every primitive if CCW cullmode is used. - Clipper::ProcessTriangle(data[2], data[1], data[0]); + Clipper::ProcessTriangle(data[2], data[1], data[0], data[provoking_index]); } else { - Clipper::ProcessTriangle(data[0], data[1], data[2]); + Clipper::ProcessTriangle(data[0], data[1], data[2], data[provoking_index]); } } break; @@ -508,7 +543,7 @@ bool TransformUnit::GetCurrentSimpleVertices(int count, std::vector 0 && (gstate.vertType & GE_VTYPE_IDX_MASK) != GE_VTYPE_IDX_NONE) { const u8 *inds = Memory::GetPointer(gstate_c.indexAddr); const u16 *inds16 = (const u16 *)inds; const u32 *inds32 = (const u32 *)inds; @@ -547,12 +582,16 @@ bool TransformUnit::GetCurrentSimpleVertices(int count, std::vector temp_buffer; static std::vector simpleVertices; - temp_buffer.resize(65536 * 24 / sizeof(u32)); + temp_buffer.resize(std::max((int)indexUpperBound, 8192) * 128 / sizeof(u32)); simpleVertices.resize(indexUpperBound + 1); VertexDecoder vdecoder; VertexDecoderOptions options{}; vdecoder.SetVertexType(gstate.vertType, options); + + if (!Memory::IsValidRange(gstate_c.vertexAddr, (indexUpperBound + 1) * vdecoder.VertexSize())) + return false; + DrawEngineCommon::NormalizeVertices((u8 *)(&simpleVertices[0]), (u8 *)(&temp_buffer[0]), Memory::GetPointer(gstate_c.vertexAddr), &vdecoder, indexLowerBound, indexUpperBound, gstate.vertType); float world[16]; diff --git a/GPU/Software/TransformUnit.h b/GPU/Software/TransformUnit.h index 68beaab5e1..70c75fadd8 100644 --- a/GPU/Software/TransformUnit.h +++ b/GPU/Software/TransformUnit.h @@ -144,9 +144,9 @@ public: ~SoftwareDrawEngine(); void DispatchFlush() override; - void DispatchSubmitPrim(void *verts, void *inds, GEPrimitiveType prim, int vertexCount, u32 vertType, int *bytesRead) override; + void DispatchSubmitPrim(void *verts, void *inds, GEPrimitiveType prim, int vertexCount, u32 vertType, int cullMode, int *bytesRead) override; VertexDecoder *FindVertexDecoder(u32 vtype); TransformUnit transformUnit; -}; \ No newline at end of file +}; diff --git a/GPU/Vulkan/DebugVisVulkan.cpp b/GPU/Vulkan/DebugVisVulkan.cpp index bc0e17ad63..d93195bc16 100644 --- a/GPU/Vulkan/DebugVisVulkan.cpp +++ b/GPU/Vulkan/DebugVisVulkan.cpp @@ -37,7 +37,6 @@ void DrawAllocatorVis(UIContext *ui, GPUInterface *gpu) { int x = padding; int y = starty; int w = columnWidth; // We will double this when actually drawing to make the pixels visible. - ui->End(); ui->Begin(); diff --git a/GPU/Vulkan/DrawEngineVulkan.cpp b/GPU/Vulkan/DrawEngineVulkan.cpp index 1f417e46db..478a100923 100644 --- a/GPU/Vulkan/DrawEngineVulkan.cpp +++ b/GPU/Vulkan/DrawEngineVulkan.cpp @@ -211,7 +211,8 @@ void DrawEngineVulkan::FrameData::Destroy(VulkanContext *vulkan) { void DrawEngineVulkan::DestroyDeviceObjects() { delete tessDataTransferVulkan; - tessDataTransfer = tessDataTransferVulkan = nullptr; + tessDataTransfer = nullptr; + tessDataTransferVulkan = nullptr; for (int i = 0; i < VulkanContext::MAX_INFLIGHT_FRAMES; i++) { frame_[i].Destroy(vulkan_); @@ -355,7 +356,7 @@ VkResult DrawEngineVulkan::RecreateDescriptorPool(FrameData &frame, int newSize) dpTypes[0].type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC; dpTypes[1].descriptorCount = frame.descPoolSize * 3; // Don't use these for tess anymore, need max three per set. dpTypes[1].type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; - dpTypes[2].descriptorCount = frame.descPoolSize; + dpTypes[2].descriptorCount = frame.descPoolSize * 3; // TODO: Use a separate layout when no spline stuff is needed to reduce the need for these. dpTypes[2].type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER; VkDescriptorPoolCreateInfo dp{ VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO }; @@ -400,7 +401,6 @@ VkDescriptorSet DrawEngineVulkan::GetOrCreateDescriptorSet(VkImageView imageView VkDescriptorSet desc; VkDescriptorSetAllocateInfo descAlloc{ VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO }; - descAlloc.pNext = nullptr; descAlloc.pSetLayouts = &descriptorSetLayout_; descAlloc.descriptorPool = frame.descPool; descAlloc.descriptorSetCount = 1; @@ -968,7 +968,7 @@ void DrawEngineVulkan::DoFlush() { int scissorY2 = gstate.getScissorY2() + 1; framebufferManager_->SetSafeSize(scissorX2, scissorY2); - if (g_Config.bBlockTransferGPU && (gstate_c.featureFlags & GPU_USE_CLEAR_RAM_HACK) && gstate.isClearModeColorMask() && (gstate.isClearModeAlphaMask() || gstate.FrameBufFormat() == GE_FORMAT_565)) { + if ((gstate_c.featureFlags & GPU_USE_CLEAR_RAM_HACK) && gstate.isClearModeColorMask() && (gstate.isClearModeAlphaMask() || gstate.FrameBufFormat() == GE_FORMAT_565)) { framebufferManager_->ApplyClearToMemory(scissorX1, scissorY1, scissorX2, scissorY2, result.color); } } @@ -1022,7 +1022,7 @@ void TessellationDataTransferVulkan::SendDataToShader(const SimpleVertex *const int size = size_u * size_v; - int ssboAlignment = vulkan_->GetPhysicalDeviceProperties(vulkan_->GetCurrentPhysicalDevice()).limits.minStorageBufferOffsetAlignment; + int ssboAlignment = vulkan_->GetPhysicalDeviceProperties().properties.limits.minStorageBufferOffsetAlignment; uint8_t *data = (uint8_t *)push_->PushAligned(size * sizeof(TessData), (uint32_t *)&bufInfo_[0].offset, &bufInfo_[0].buffer, ssboAlignment); bufInfo_[0].range = size * sizeof(TessData); diff --git a/GPU/Vulkan/FragmentShaderGeneratorVulkan.cpp b/GPU/Vulkan/FragmentShaderGeneratorVulkan.cpp index afb8689610..9ce62dcb2d 100644 --- a/GPU/Vulkan/FragmentShaderGeneratorVulkan.cpp +++ b/GPU/Vulkan/FragmentShaderGeneratorVulkan.cpp @@ -85,12 +85,11 @@ bool GenerateVulkanGLSLFragmentShader(const FShaderID &id, char *buffer, uint32_ const char *shading = doFlatShading ? "flat" : ""; bool earlyFragmentTests = ((!enableAlphaTest && !enableColorTest) || testForceToZero) && !gstate_c.Supports(GPU_ROUND_FRAGMENT_DEPTH_TO_16BIT); - - bool isAdreno = vulkanVendorId == VULKAN_VENDOR_QUALCOMM; + bool useAdrenoBugWorkaround = id.Bit(FS_BIT_NO_DEPTH_CANNOT_DISCARD_STENCIL); if (earlyFragmentTests) { WRITE(p, "layout (early_fragment_tests) in;\n"); - } else if (isAdreno) { + } else if (useAdrenoBugWorkaround && !gstate_c.Supports(GPU_ROUND_FRAGMENT_DEPTH_TO_16BIT)) { WRITE(p, "layout (depth_unchanged) out float gl_FragDepth;\n"); } @@ -589,7 +588,7 @@ bool GenerateVulkanGLSLFragmentShader(const FShaderID &id, char *buffer, uint32_ WRITE(p, " z /= 2000.0;\n"); // Nasty hack to completely remove flicker in Heroes Phantasia } WRITE(p, " gl_FragDepth = z;\n"); - } else if (!earlyFragmentTests && isAdreno) { + } else if (!earlyFragmentTests && useAdrenoBugWorkaround) { // Adreno (and possibly MESA/others) apply early frag tests even with discard in the shader. // Writing depth prevents the bug, even with depth_unchanged specified. WRITE(p, " gl_FragDepth = gl_FragCoord.z;\n"); diff --git a/GPU/Vulkan/FramebufferVulkan.cpp b/GPU/Vulkan/FramebufferVulkan.cpp index 7851238090..2e87b65390 100644 --- a/GPU/Vulkan/FramebufferVulkan.cpp +++ b/GPU/Vulkan/FramebufferVulkan.cpp @@ -379,10 +379,6 @@ void FramebufferManagerVulkan::ReformatFramebufferFrom(VirtualFramebuffer *vfb, // Except for a missing rebind and silly scissor enables, identical copy of the same function in GPU_GLES - tricky parts are in thin3d. void FramebufferManagerVulkan::BlitFramebufferDepth(VirtualFramebuffer *src, VirtualFramebuffer *dst) { - if (g_Config.bDisableSlowFramebufEffects) { - return; - } - bool matchingDepthBuffer = src->z_address == dst->z_address && src->z_stride != 0 && dst->z_stride != 0; bool matchingSize = src->width == dst->width && src->height == dst->height; bool matchingRenderSize = src->renderWidth == dst->renderWidth && src->renderHeight == dst->renderHeight; @@ -408,7 +404,7 @@ VkImageView FramebufferManagerVulkan::BindFramebufferAsColorTexture(int stage, V // currentRenderVfb_ will always be set when this is called, except from the GE debugger. // Let's just not bother with the copy in that case. bool skipCopy = (flags & BINDFBCOLOR_MAY_COPY) == 0; - if (GPUStepping::IsStepping() || g_Config.bDisableSlowFramebufEffects) { + if (GPUStepping::IsStepping()) { skipCopy = true; } // Currently rendering to this framebuffer. Need to make a copy. @@ -425,7 +421,7 @@ VkImageView FramebufferManagerVulkan::BindFramebufferAsColorTexture(int stage, V draw_->BindFramebufferAsTexture(framebuffer->fbo, stage, Draw::FB_COLOR_BIT, 0); } return (VkImageView)draw_->GetNativeObject(Draw::NativeObject::BOUND_TEXTURE0_IMAGEVIEW); - } else if (framebuffer != currentRenderVfb_) { + } else if (framebuffer != currentRenderVfb_ || (flags & BINDFBCOLOR_FORCE_SELF) != 0) { draw_->BindFramebufferAsTexture(framebuffer->fbo, stage, Draw::FB_COLOR_BIT, 0); return (VkImageView)draw_->GetNativeObject(Draw::NativeObject::BOUND_TEXTURE0_IMAGEVIEW); } else { @@ -468,6 +464,13 @@ void FramebufferManagerVulkan::BlitFramebuffer(VirtualFramebuffer *dst, int dstX if (dstY + h > dst->bufferHeight) { h -= dstY + h - dst->bufferHeight; } + if (srcX + w > src->bufferWidth) { + w -= srcX + w - src->bufferWidth; + } + if (srcY + h > src->bufferHeight) { + h -= srcY + h - src->bufferHeight; + } + if (w == 0 || h == 0) return; diff --git a/GPU/Vulkan/GPU_Vulkan.cpp b/GPU/Vulkan/GPU_Vulkan.cpp index 6b81da93d1..5ad07c0ca4 100644 --- a/GPU/Vulkan/GPU_Vulkan.cpp +++ b/GPU/Vulkan/GPU_Vulkan.cpp @@ -59,7 +59,7 @@ GPU_Vulkan::GPU_Vulkan(GraphicsContext *gfxCtx, Draw::DrawContext *draw) UpdateVsyncInterval(true); CheckGPUFeatures(); - shaderManagerVulkan_ = new ShaderManagerVulkan(vulkan_); + shaderManagerVulkan_ = new ShaderManagerVulkan(draw, vulkan_); pipelineManager_ = new PipelineManagerVulkan(vulkan_); framebufferManagerVulkan_ = new FramebufferManagerVulkan(draw, vulkan_); framebufferManager_ = framebufferManagerVulkan_; @@ -95,7 +95,7 @@ GPU_Vulkan::GPU_Vulkan(GraphicsContext *gfxCtx, Draw::DrawContext *draw) UpdateVsyncInterval(true); textureCacheVulkan_->NotifyConfigChanged(); - if (vulkan_->GetFeaturesEnabled().wideLines) { + if (vulkan_->GetDeviceFeatures().enabled.wideLines) { drawEngine_.SetLineWidth(PSP_CoreParameter().renderWidth / 480.0f); } @@ -183,7 +183,7 @@ void GPU_Vulkan::CheckGPUFeatures() { features |= GPU_SUPPORTS_VS_RANGE_CULLING; - switch (vulkan_->GetPhysicalDeviceProperties(vulkan_->GetCurrentPhysicalDevice()).vendorID) { + switch (vulkan_->GetPhysicalDeviceProperties().properties.vendorID) { case VULKAN_VENDOR_AMD: // Accurate depth is required on AMD (due to reverse-Z driver bug) so we ignore the compat flag to disable it on those. See #9545 features |= GPU_SUPPORTS_ACCURATE_DEPTH; @@ -191,7 +191,7 @@ void GPU_Vulkan::CheckGPUFeatures() { case VULKAN_VENDOR_ARM: // Also required on older ARM Mali drivers, like the one on many Galaxy S7. if (!PSP_CoreParameter().compat.flags().DisableAccurateDepth || - vulkan_->GetPhysicalDeviceProperties(vulkan_->GetCurrentPhysicalDevice()).driverVersion <= VK_MAKE_VERSION(428, 811, 2674)) { + vulkan_->GetPhysicalDeviceProperties().properties.driverVersion <= VK_MAKE_VERSION(428, 811, 2674)) { features |= GPU_SUPPORTS_ACCURATE_DEPTH; } break; @@ -201,6 +201,10 @@ void GPU_Vulkan::CheckGPUFeatures() { break; } + // Might enable this later - in the first round we are mostly looking at depth/stencil/discard. + // if (g_Config.bDisableVendorBugChecks) + // features |= GPU_SUPPORTS_ACCURATE_DEPTH; + // Mandatory features on Vulkan, which may be checked in "centralized" code features |= GPU_SUPPORTS_TEXTURE_LOD_CONTROL; features |= GPU_SUPPORTS_FBO; @@ -213,33 +217,21 @@ void GPU_Vulkan::CheckGPUFeatures() { features |= GPU_SUPPORTS_VERTEX_TEXTURE_FETCH; features |= GPU_SUPPORTS_TEXTURE_FLOAT; - if (vulkan_->GetFeaturesEnabled().wideLines) { + if (vulkan_->GetDeviceFeatures().enabled.wideLines) { features |= GPU_SUPPORTS_WIDE_LINES; } - if (vulkan_->GetFeaturesEnabled().depthClamp) { + if (vulkan_->GetDeviceFeatures().enabled.depthClamp) { features |= GPU_SUPPORTS_DEPTH_CLAMP; } - if (vulkan_->GetFeaturesEnabled().dualSrcBlend) { - switch (vulkan_->GetPhysicalDeviceProperties(vulkan_->GetCurrentPhysicalDevice()).vendorID) { - // We thought we had a bug here on nVidia but turns out we accidentally #ifdef-ed out crucial - // code on Android. - case VULKAN_VENDOR_INTEL: - // Workaround for Intel driver bug. - break; - case VULKAN_VENDOR_AMD: - // See issue #10074, and also #10065 (AMD) and #10109 for the choice of the driver version to check for - if (vulkan_->GetPhysicalDeviceProperties(vulkan_->GetCurrentPhysicalDevice()).driverVersion >= 0x00407000) - features |= GPU_SUPPORTS_DUALSOURCE_BLEND; - break; - default: + if (vulkan_->GetDeviceFeatures().enabled.dualSrcBlend) { + if (!g_Config.bVendorBugChecksEnabled || !draw_->GetBugs().Has(Draw::Bugs::DUAL_SOURCE_BLENDING_BROKEN)) { features |= GPU_SUPPORTS_DUALSOURCE_BLEND; - break; } } - if (vulkan_->GetFeaturesEnabled().logicOp) { + if (vulkan_->GetDeviceFeatures().enabled.logicOp) { features |= GPU_SUPPORTS_LOGIC_OP; } - if (vulkan_->GetFeaturesEnabled().samplerAnisotropy) { + if (vulkan_->GetDeviceFeatures().enabled.samplerAnisotropy) { features |= GPU_SUPPORTS_ANISOTROPY; } @@ -257,6 +249,7 @@ void GPU_Vulkan::CheckGPUFeatures() { else if (PSP_CoreParameter().compat.flags().VertexDepthRounding) { features |= GPU_ROUND_DEPTH_TO_16BIT; } + gstate_c.featureFlags = features; } @@ -271,7 +264,7 @@ void GPU_Vulkan::BeginHostFrame() { framebufferManager_->Resized(); drawEngine_.Resized(); textureCacheVulkan_->NotifyConfigChanged(); - if (vulkan_->GetFeaturesEnabled ().wideLines) { + if (vulkan_->GetDeviceFeatures().enabled.wideLines) { drawEngine_.SetLineWidth(PSP_CoreParameter().renderWidth / 480.0f); } } @@ -318,8 +311,8 @@ void GPU_Vulkan::EndHostFrame() { // Needs to be called on GPU thread, not reporting thread. void GPU_Vulkan::BuildReportingInfo() { - const auto &props = vulkan_->GetPhysicalDeviceProperties(vulkan_->GetCurrentPhysicalDevice()); - const auto &features = vulkan_->GetFeaturesAvailable(); + const auto &props = vulkan_->GetPhysicalDeviceProperties().properties; + const auto &features = vulkan_->GetDeviceFeatures().available; #define CHECK_BOOL_FEATURE(n) do { if (features.n) { featureNames += ", " #n; } } while (false) @@ -529,7 +522,7 @@ void GPU_Vulkan::DeviceRestore() { drawEngine_.DeviceRestore(vulkan_, draw_); pipelineManager_->DeviceRestore(vulkan_); textureCacheVulkan_->DeviceRestore(vulkan_, draw_); - shaderManagerVulkan_->DeviceRestore(vulkan_); + shaderManagerVulkan_->DeviceRestore(vulkan_, draw_); depalShaderCache_.DeviceRestore(draw_, vulkan_); } diff --git a/GPU/Vulkan/PipelineManagerVulkan.cpp b/GPU/Vulkan/PipelineManagerVulkan.cpp index 837aec7ffe..27d513aa2c 100644 --- a/GPU/Vulkan/PipelineManagerVulkan.cpp +++ b/GPU/Vulkan/PipelineManagerVulkan.cpp @@ -112,12 +112,16 @@ static int SetupVertexAttribs(VkVertexInputAttributeDescription attrs[], const D return count; } -static int SetupVertexAttribsPretransformed(VkVertexInputAttributeDescription attrs[]) { +static int SetupVertexAttribsPretransformed(VkVertexInputAttributeDescription attrs[], bool needsUV, bool needsColor1) { int count = 0; VertexAttribSetup(&attrs[count++], DEC_FLOAT_4, 0, PspAttributeLocation::POSITION); - VertexAttribSetup(&attrs[count++], DEC_FLOAT_3, 16, PspAttributeLocation::TEXCOORD); + if (needsUV) { + VertexAttribSetup(&attrs[count++], DEC_FLOAT_3, 16, PspAttributeLocation::TEXCOORD); + } VertexAttribSetup(&attrs[count++], DEC_U8_4, 28, PspAttributeLocation::COLOR0); - VertexAttribSetup(&attrs[count++], DEC_U8_4, 32, PspAttributeLocation::COLOR1); + if (needsColor1) { + VertexAttribSetup(&attrs[count++], DEC_U8_4, 32, PspAttributeLocation::COLOR1); + } return count; } @@ -233,7 +237,6 @@ static VulkanPipeline *CreateVulkanPipeline(VkDevice device, VkPipelineCache pip inputAssembly.flags = 0; inputAssembly.topology = (VkPrimitiveTopology)key.topology; inputAssembly.primitiveRestartEnable = false; - int vertexStride = 0; int offset = 0; @@ -243,7 +246,9 @@ static VulkanPipeline *CreateVulkanPipeline(VkDevice device, VkPipelineCache pip attributeCount = SetupVertexAttribs(attrs, *decFmt); vertexStride = decFmt->stride; } else { - attributeCount = SetupVertexAttribsPretransformed(attrs); + bool needsUV = vs->GetID().Bit(VS_BIT_DO_TEXTURE); + bool needsColor1 = vs->GetID().Bit(VS_BIT_LMODE); + attributeCount = SetupVertexAttribsPretransformed(attrs, needsUV, needsColor1); vertexStride = 36; } @@ -676,7 +681,7 @@ bool PipelineManagerVulkan::LoadCache(FILE *file, bool loadRawPipelineCache, Sha WARN_LOG(G3D, "Bad Vulkan pipeline cache header - ignoring"); return false; } - if (0 != memcmp(header->uuid, vulkan_->GetPhysicalDeviceProperties(vulkan_->GetCurrentPhysicalDevice()).pipelineCacheUUID, VK_UUID_SIZE)) { + if (0 != memcmp(header->uuid, vulkan_->GetPhysicalDeviceProperties().properties.pipelineCacheUUID, VK_UUID_SIZE)) { // Wrong hardware/driver/etc. WARN_LOG(G3D, "Bad Vulkan pipeline cache UUID - ignoring"); return false; diff --git a/GPU/Vulkan/ShaderManagerVulkan.cpp b/GPU/Vulkan/ShaderManagerVulkan.cpp index ef0f7cf226..43dd9de1ea 100644 --- a/GPU/Vulkan/ShaderManagerVulkan.cpp +++ b/GPU/Vulkan/ShaderManagerVulkan.cpp @@ -25,6 +25,7 @@ #include "math/math_util.h" #include "math/dataconv.h" #include "profiler/profiler.h" +#include "thin3d/thin3d.h" #include "util/text/utf8.h" #include "Common/Vulkan/VulkanContext.h" #include "Common/Vulkan/VulkanMemory.h" @@ -156,17 +157,17 @@ std::string VulkanVertexShader::GetShaderString(DebugShaderStringType type) cons } } -ShaderManagerVulkan::ShaderManagerVulkan(VulkanContext *vulkan) - : vulkan_(vulkan), lastVShader_(nullptr), lastFShader_(nullptr), fsCache_(16), vsCache_(16) { +ShaderManagerVulkan::ShaderManagerVulkan(Draw::DrawContext *draw, VulkanContext *vulkan) + : ShaderManagerCommon(draw), vulkan_(vulkan), lastVShader_(nullptr), lastFShader_(nullptr), fsCache_(16), vsCache_(16) { codeBuffer_ = new char[16384]; - uboAlignment_ = vulkan_->GetPhysicalDeviceProperties(vulkan_->GetCurrentPhysicalDevice()).limits.minUniformBufferOffsetAlignment; + uboAlignment_ = vulkan_->GetPhysicalDeviceProperties().properties.limits.minUniformBufferOffsetAlignment; memset(&ub_base, 0, sizeof(ub_base)); memset(&ub_lights, 0, sizeof(ub_lights)); memset(&ub_bones, 0, sizeof(ub_bones)); - ILOG("sizeof(ub_base): %d", (int)sizeof(ub_base)); - ILOG("sizeof(ub_lights): %d", (int)sizeof(ub_lights)); - ILOG("sizeof(ub_bones): %d", (int)sizeof(ub_bones)); + static_assert(sizeof(ub_base) <= 512, "ub_base grew too big"); + static_assert(sizeof(ub_lights) <= 512, "ub_lights grew too big"); + static_assert(sizeof(ub_bones) <= 384, "ub_bones grew too big"); } ShaderManagerVulkan::~ShaderManagerVulkan() { @@ -174,9 +175,10 @@ ShaderManagerVulkan::~ShaderManagerVulkan() { delete[] codeBuffer_; } -void ShaderManagerVulkan::DeviceRestore(VulkanContext *vulkan) { +void ShaderManagerVulkan::DeviceRestore(VulkanContext *vulkan, Draw::DrawContext *draw) { vulkan_ = vulkan; - uboAlignment_ = vulkan_->GetPhysicalDeviceProperties(vulkan_->GetCurrentPhysicalDevice()).limits.minUniformBufferOffsetAlignment; + draw_ = draw; + uboAlignment_ = vulkan_->GetPhysicalDeviceProperties().properties.limits.minUniformBufferOffsetAlignment; } void ShaderManagerVulkan::Clear() { @@ -238,7 +240,7 @@ void ShaderManagerVulkan::GetShaders(int prim, u32 vertType, VulkanVertexShader FShaderID FSID; if (gstate_c.IsDirty(DIRTY_FRAGMENTSHADER_STATE)) { gstate_c.Clean(DIRTY_FRAGMENTSHADER_STATE); - ComputeFragmentShaderID(&FSID); + ComputeFragmentShaderID(&FSID, draw_->GetBugs()); } else { FSID = lastFSID_; } @@ -268,7 +270,7 @@ void ShaderManagerVulkan::GetShaders(int prim, u32 vertType, VulkanVertexShader VulkanFragmentShader *fs = fsCache_.Get(FSID); if (!fs) { - uint32_t vendorID = vulkan_->GetPhysicalDeviceProperties(vulkan_->GetCurrentPhysicalDevice()).vendorID; + uint32_t vendorID = vulkan_->GetPhysicalDeviceProperties().properties.vendorID; // Fragment shader not in cache. Let's compile it. GenerateVulkanGLSLFragmentShader(FSID, codeBuffer_, vendorID); fs = new VulkanFragmentShader(vulkan_, FSID, codeBuffer_); @@ -359,7 +361,7 @@ VulkanFragmentShader *ShaderManagerVulkan::GetFragmentShaderFromModule(VkShaderM // instantaneous. #define CACHE_HEADER_MAGIC 0xff51f420 -#define CACHE_VERSION 14 +#define CACHE_VERSION 16 struct VulkanCacheHeader { uint32_t magic; uint32_t version; @@ -390,7 +392,7 @@ bool ShaderManagerVulkan::LoadCache(FILE *f) { VulkanVertexShader *vs = new VulkanVertexShader(vulkan_, id, codeBuffer_, useHWTransform); vsCache_.Insert(id, vs); } - uint32_t vendorID = vulkan_->GetPhysicalDeviceProperties(vulkan_->GetCurrentPhysicalDevice()).vendorID; + uint32_t vendorID = vulkan_->GetPhysicalDeviceProperties().properties.vendorID; for (int i = 0; i < header.numFragmentShaders; i++) { FShaderID id; if (fread(&id, sizeof(id), 1, f) != 1) { diff --git a/GPU/Vulkan/ShaderManagerVulkan.h b/GPU/Vulkan/ShaderManagerVulkan.h index 2bcce9332b..e77d1725dc 100644 --- a/GPU/Vulkan/ShaderManagerVulkan.h +++ b/GPU/Vulkan/ShaderManagerVulkan.h @@ -83,10 +83,10 @@ class VulkanPushBuffer; class ShaderManagerVulkan : public ShaderManagerCommon { public: - ShaderManagerVulkan(VulkanContext *vulkan); + ShaderManagerVulkan(Draw::DrawContext *draw, VulkanContext *vulkan); ~ShaderManagerVulkan(); - void DeviceRestore(VulkanContext *vulkan); + void DeviceRestore(VulkanContext *vulkan, Draw::DrawContext *draw); void GetShaders(int prim, u32 vertType, VulkanVertexShader **vshader, VulkanFragmentShader **fshader, bool useHWTransform); void ClearShaders(); diff --git a/GPU/Vulkan/StateMappingVulkan.cpp b/GPU/Vulkan/StateMappingVulkan.cpp index 282b602dd8..3fef920fca 100644 --- a/GPU/Vulkan/StateMappingVulkan.cpp +++ b/GPU/Vulkan/StateMappingVulkan.cpp @@ -225,7 +225,7 @@ void DrawEngineVulkan::ConvertStateToVulkanKey(FramebufferManagerVulkan &fbManag #endif // Let's not write to alpha if stencil isn't enabled. - if (!gstate.isStencilTestEnabled()) { + if (IsStencilTestOutputDisabled()) { amask = false; } else { // If the stencil type is set to KEEP, we shouldn't write to the stencil/alpha channel. @@ -235,6 +235,20 @@ void DrawEngineVulkan::ConvertStateToVulkanKey(FramebufferManagerVulkan &fbManag } key.colorWriteMask = (rmask ? VK_COLOR_COMPONENT_R_BIT : 0) | (gmask ? VK_COLOR_COMPONENT_G_BIT : 0) | (bmask ? VK_COLOR_COMPONENT_B_BIT : 0) | (amask ? VK_COLOR_COMPONENT_A_BIT : 0); + + // Workaround proposed in #10421, for bug where the color write mask is not applied correctly on Adreno. + if ((gstate.pmskc & 0x00FFFFFF) == 0x00FFFFFF && vulkan_->GetPhysicalDeviceProperties().properties.vendorID == VULKAN_VENDOR_QUALCOMM) { + key.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT; + if (!key.blendEnable) { + key.blendEnable = true; + key.blendOpAlpha = VK_BLEND_OP_ADD; + key.srcAlpha = VK_BLEND_FACTOR_ZERO; + key.destAlpha = VK_BLEND_FACTOR_ONE; + } + key.blendOpColor = VK_BLEND_OP_ADD; + key.srcColor = VK_BLEND_FACTOR_ZERO; + key.destColor = VK_BLEND_FACTOR_ONE; + } } } diff --git a/GPU/Vulkan/StencilBufferVulkan.cpp b/GPU/Vulkan/StencilBufferVulkan.cpp index cf046fe43e..cfce98f3fb 100644 --- a/GPU/Vulkan/StencilBufferVulkan.cpp +++ b/GPU/Vulkan/StencilBufferVulkan.cpp @@ -97,6 +97,7 @@ void main() { // messing about with bitplane textures and the like. Or actually, maybe not... Let's start with // the traditional approach. bool FramebufferManagerVulkan::NotifyStencilUpload(u32 addr, int size, bool skipZero) { + addr &= 0x3FFFFFFF; if (!MayIntersectFramebuffer(addr)) { return false; } @@ -104,7 +105,7 @@ bool FramebufferManagerVulkan::NotifyStencilUpload(u32 addr, int size, bool skip VirtualFramebuffer *dstBuffer = 0; for (size_t i = 0; i < vfbs_.size(); ++i) { VirtualFramebuffer *vfb = vfbs_[i]; - if (MaskedEqual(vfb->fb_address, addr)) { + if (vfb->fb_address == addr) { dstBuffer = vfb; } } @@ -145,7 +146,7 @@ bool FramebufferManagerVulkan::NotifyStencilUpload(u32 addr, int size, bool skip if (!stencilVs_) { const char *stencil_fs_source = stencil_fs; // See comment above the stencil_fs_adreno definition. - if (vulkan_->GetPhysicalDeviceProperties(vulkan_->GetCurrentPhysicalDevice()).vendorID == VULKAN_VENDOR_QUALCOMM) + if (vulkan_->GetPhysicalDeviceProperties().properties.vendorID == VULKAN_VENDOR_QUALCOMM) stencil_fs_source = stencil_fs_adreno; stencilVs_ = CompileShaderModule(vulkan_, VK_SHADER_STAGE_VERTEX_BIT, stencil_vs, &error); diff --git a/GPU/Vulkan/TextureCacheVulkan.cpp b/GPU/Vulkan/TextureCacheVulkan.cpp index 048b536365..c41d214b28 100644 --- a/GPU/Vulkan/TextureCacheVulkan.cpp +++ b/GPU/Vulkan/TextureCacheVulkan.cpp @@ -688,7 +688,7 @@ void TextureCacheVulkan::BuildTexture(TexCacheEntry *const entry) { uint32_t bufferOffset; VkBuffer texBuf; // nvidia returns 1 but that can't be healthy... let's align by 16 as a minimum. - int pushAlignment = std::max(16, (int)vulkan_->GetPhysicalDeviceProperties(vulkan_->GetCurrentPhysicalDevice()).limits.optimalBufferCopyOffsetAlignment); + int pushAlignment = std::max(16, (int)vulkan_->GetPhysicalDeviceProperties().properties.limits.optimalBufferCopyOffsetAlignment); void *data = drawEngine_->GetPushBufferForTextureData()->PushAligned(size, &bufferOffset, &texBuf, pushAlignment); if (replaced.Valid()) { replaced.Load(i, data, stride); diff --git a/GPU/Vulkan/VertexShaderGeneratorVulkan.cpp b/GPU/Vulkan/VertexShaderGeneratorVulkan.cpp index c6ccb78125..57b9913933 100644 --- a/GPU/Vulkan/VertexShaderGeneratorVulkan.cpp +++ b/GPU/Vulkan/VertexShaderGeneratorVulkan.cpp @@ -424,7 +424,7 @@ bool GenerateVulkanGLSLVertexShader(const VShaderID &id, char *buffer) { if (doLight[i] != LIGHT_FULL) continue; diffuseIsZero = false; - if (comp != GE_LIGHTCOMP_ONLYDIFFUSE) + if (comp == GE_LIGHTCOMP_BOTH) specularIsZero = false; if (type != GE_LIGHTTYPE_DIRECTIONAL) distanceNeeded = true; @@ -461,17 +461,17 @@ bool GenerateVulkanGLSLVertexShader(const VShaderID &id, char *buffer) { WRITE(p, " toLight /= distance;\n"); } - bool doSpecular = comp != GE_LIGHTCOMP_ONLYDIFFUSE; - bool poweredDiffuse = comp == GE_LIGHTCOMP_BOTHWITHPOWDIFFUSE; + bool doSpecular = comp == GE_LIGHTCOMP_BOTH; + bool poweredDiffuse = comp == GE_LIGHTCOMP_ONLYPOWDIFFUSE; - WRITE(p, " mediump float dot%i = max(dot(toLight, worldnormal), 0.0);\n", i); + WRITE(p, " mediump float dot%i = dot(toLight, worldnormal);\n", i); if (poweredDiffuse) { // pow(0.0, 0.0) may be undefined, but the PSP seems to treat it as 1.0. // Seen in Tales of the World: Radiant Mythology (#2424.) - WRITE(p, " if (dot%i == 0.0 && light.matspecular.a == 0.0) {\n", i); + WRITE(p, " if (light.matspecular.a == 0.0) {\n"); WRITE(p, " dot%i = 1.0;\n", i); WRITE(p, " } else {\n"); - WRITE(p, " dot%i = pow(dot%i, light.matspecular.a);\n", i, i); + WRITE(p, " dot%i = pow(max(dot%i, 0.0), light.matspecular.a);\n", i, i); WRITE(p, " }\n"); } @@ -487,9 +487,9 @@ bool GenerateVulkanGLSLVertexShader(const VShaderID &id, char *buffer) { break; case GE_LIGHTTYPE_SPOT: case GE_LIGHTTYPE_UNKNOWN: - WRITE(p, " float angle%i = dot(normalize(light.dir[%i]), toLight);\n", i, i); + WRITE(p, " float angle%i = length(light.dir[%i]) == 0.0 ? 0.0 : dot(normalize(light.dir[%i]), toLight);\n", i, i, i); WRITE(p, " if (angle%i >= light.angle_spotCoef[%i].x) {\n", i, i); - WRITE(p, " lightScale = clamp(1.0 / dot(light.att[%i], vec3(1.0, distance, distance*distance)), 0.0, 1.0) * pow(angle%i, light.angle_spotCoef[%i].y);\n", i, i, i); + WRITE(p, " lightScale = clamp(1.0 / dot(light.att[%i], vec3(1.0, distance, distance*distance)), 0.0, 1.0) * (light.angle_spotCoef[%i].y == 0.0 ? 1.0 : pow(angle%i, light.angle_spotCoef[%i].y));\n", i, i, i, i); WRITE(p, " } else {\n"); WRITE(p, " lightScale = 0.0;\n"); WRITE(p, " }\n"); @@ -499,11 +499,18 @@ bool GenerateVulkanGLSLVertexShader(const VShaderID &id, char *buffer) { break; } - WRITE(p, " diffuse = (light.diffuse[%i] * %s) * dot%i;\n", i, diffuseStr, i); + WRITE(p, " diffuse = (light.diffuse[%i] * %s) * max(dot%i, 0.0);\n", i, diffuseStr, i); if (doSpecular) { - WRITE(p, " dot%i = dot(normalize(toLight + vec3(0.0, 0.0, 1.0)), worldnormal);\n", i); - WRITE(p, " if (dot%i > 0.0)\n", i); - WRITE(p, " lightSum1 += light.specular[%i] * %s * (pow(dot%i, light.matspecular.a) %s);\n", i, specularStr, i, timesLightScale); + WRITE(p, " if (dot%i >= 0.0) {\n", i); + WRITE(p, " dot%i = dot(normalize(toLight + vec3(0.0, 0.0, 1.0)), worldnormal);\n", i); + WRITE(p, " if (light.matspecular.a == 0.0) {\n"); + WRITE(p, " dot%i = 1.0;\n", i); + WRITE(p, " } else {\n"); + WRITE(p, " dot%i = pow(max(dot%i, 0.0), light.matspecular.a);\n", i, i); + WRITE(p, " }\n"); + WRITE(p, " if (dot%i > 0.0)\n", i); + WRITE(p, " lightSum1 += light.specular[%i] * %s * dot%i %s;\n", i, specularStr, i, timesLightScale); + WRITE(p, " }\n"); } WRITE(p, " lightSum0.rgb += (light.ambient[%i] * %s.rgb + diffuse)%s;\n", i, ambientStr, timesLightScale); } @@ -601,8 +608,12 @@ bool GenerateVulkanGLSLVertexShader(const VShaderID &id, char *buffer) { break; case GE_TEXMAP_ENVIRONMENT_MAP: // Shade mapping - use dots from light sources. - WRITE(p, " v_texcoord = vec3(base.uvscaleoffset.xy * vec2(1.0 + dot(normalize(light.pos[%i]), worldnormal), 1.0 + dot(normalize(light.pos[%i]), worldnormal)) * 0.5, 1.0);\n", ls0, ls1); - break; + { + std::string lightFactor0 = StringFromFormat("(length(light.pos[%i]) == 0.0 ? worldnormal.z : dot(normalize(light.pos[%i]), worldnormal))", ls0, ls0); + std::string lightFactor1 = StringFromFormat("(length(light.pos[%i]) == 0.0 ? worldnormal.z : dot(normalize(light.pos[%i]), worldnormal))", ls1, ls1); + WRITE(p, " v_texcoord = vec3(base.uvscaleoffset.xy * vec2(1.0 + %s, 1.0 + %s) * 0.5, 1.0);\n", lightFactor0.c_str(), lightFactor1.c_str()); + } + break; default: // ILLEGAL diff --git a/GPU/Vulkan/VulkanUtil.cpp b/GPU/Vulkan/VulkanUtil.cpp index d7d6223fc8..424594d641 100644 --- a/GPU/Vulkan/VulkanUtil.cpp +++ b/GPU/Vulkan/VulkanUtil.cpp @@ -160,12 +160,11 @@ VkDescriptorSet Vulkan2D::GetDescriptorSet(VkImageView tex1, VkSampler sampler1, assert(result == VK_SUCCESS); // We just don't write to the slots we don't care about. - VkWriteDescriptorSet writes[2]; - memset(writes, 0, sizeof(writes)); + VkWriteDescriptorSet writes[2]{}; // Main and sub textures int n = 0; - VkDescriptorImageInfo image1 = {}; - VkDescriptorImageInfo image2 = {}; + VkDescriptorImageInfo image1{}; + VkDescriptorImageInfo image2{}; if (tex1) { #ifdef VULKAN_USE_GENERAL_LAYOUT_FOR_COLOR image1.imageLayout = VK_IMAGE_LAYOUT_GENERAL; diff --git a/GPU/ge_constants.h b/GPU/ge_constants.h index b765af5bcb..e9509767f0 100644 --- a/GPU/ge_constants.h +++ b/GPU/ge_constants.h @@ -395,7 +395,7 @@ enum GELightComputation { GE_LIGHTCOMP_ONLYDIFFUSE = 0, GE_LIGHTCOMP_BOTH = 1, - GE_LIGHTCOMP_BOTHWITHPOWDIFFUSE = 2, + GE_LIGHTCOMP_ONLYPOWDIFFUSE = 2, }; enum GETextureFormat diff --git a/Qt/QtMain.cpp b/Qt/QtMain.cpp index ada30411ad..178f3f82c4 100644 --- a/Qt/QtMain.cpp +++ b/Qt/QtMain.cpp @@ -31,6 +31,7 @@ #include "gfx_es2/gpu_features.h" #include "math/math_util.h" #include "thread/threadutil.h" +#include "util/text/utf8.h" #include "Core/Config.h" #include "Core/ConfigValues.h" @@ -354,7 +355,34 @@ bool MainUI::event(QEvent *e) NativeKey(KeyInput(DEVICE_ID_MOUSE, ((QWheelEvent*)e)->delta()<0 ? NKCODE_EXT_MOUSEWHEEL_DOWN : NKCODE_EXT_MOUSEWHEEL_UP, KEY_DOWN)); break; case QEvent::KeyPress: - NativeKey(KeyInput(DEVICE_ID_KEYBOARD, KeyMapRawQttoNative.find(((QKeyEvent*)e)->key())->second, KEY_DOWN)); + { + auto qtKeycode = ((QKeyEvent*)e)->key(); + auto iter = KeyMapRawQttoNative.find(qtKeycode); + int nativeKeycode = 0; + if (iter != KeyMapRawQttoNative.end()) { + nativeKeycode = iter->second; + NativeKey(KeyInput(DEVICE_ID_KEYBOARD, nativeKeycode, KEY_DOWN)); + } + + // Also get the unicode value. + QString text = ((QKeyEvent*)e)->text(); + std::string str = text.toStdString(); + // Now, we don't want CHAR events for non-printable characters. Not quite sure how we'll best + // do that, but here's one attempt.... + switch (nativeKeycode) { + case NKCODE_DEL: + case NKCODE_FORWARD_DEL: + case NKCODE_TAB: + break; + default: + if (str.size()) { + int pos = 0; + int code = u8_nextchar(str.c_str(), &pos); + NativeKey(KeyInput(DEVICE_ID_KEYBOARD, code, KEY_CHAR)); + } + break; + } + } break; case QEvent::KeyRelease: NativeKey(KeyInput(DEVICE_ID_KEYBOARD, KeyMapRawQttoNative.find(((QKeyEvent*)e)->key())->second, KEY_UP)); diff --git a/Qt/QtMain.h b/Qt/QtMain.h index 58fefb6cfe..3e165a8d9f 100644 --- a/Qt/QtMain.h +++ b/Qt/QtMain.h @@ -54,7 +54,7 @@ public: SetGPUBackend(GPUBackend::OPENGL); renderManager_ = (GLRenderManager *)draw_->GetNativeObject(Draw::NativeObject::RENDER_MANAGER); bool success = draw_->CreatePresets(); - assert(success); + _assert_msg_(G3D, success, "Failed to compile preset shaders"); } ~QtGLGraphicsContext() { @@ -73,7 +73,7 @@ public: } void ThreadStart() override { - renderManager_->ThreadStart(); + renderManager_->ThreadStart(draw_); } bool ThreadFrame() override { diff --git a/Qt/mainwindow.cpp b/Qt/mainwindow.cpp index 123f6605c8..30949eb493 100644 --- a/Qt/mainwindow.cpp +++ b/Qt/mainwindow.cpp @@ -488,17 +488,18 @@ void MainWindow::createMenus() anisotropicGroup = new MenuActionGroup(this, anisotropicMenu, SLOT(anisotropicGroup_triggered(QAction *)), QStringList() << "Off" << "2x" << "4x" << "8x" << "16x", QList() << 0 << 1 << 2 << 3 << 4); - videoMenu->add(new MenuAction(this, SLOT(bufferRenderAct()), QT_TR_NOOP("&Buffered Rendering"), Qt::Key_F5)) + videoMenu->add(new MenuAction(this, SLOT(bufferRenderAct()), QT_TR_NOOP("&Buffered Rendering"))) ->addEventChecked(&g_Config.iRenderingMode); videoMenu->add(new MenuAction(this, SLOT(linearAct()), QT_TR_NOOP("&Linear Filtering"))) ->addEventChecked(&g_Config.iTexFiltering); videoMenu->addSeparator(); // - Screen Size - MenuTree* screenMenu = new MenuTree(this, videoMenu, QT_TR_NOOP("&Screen Size")); + MenuTree* screenMenu = new MenuTree(this, videoMenu, QT_TR_NOOP("&Screen Size")); screenGroup = new MenuActionGroup(this, screenMenu, SLOT(screenGroup_triggered(QAction *)), QStringList() << "1x" << "2x" << "3x" << "4x" << "5x" << "6x" << "7x" << "8x" << "9x" << "10x", - QList() << 1 << 2 << 3 << 4 << 5 << 6 << 7 << 8 << 9 << 10, - QList() << Qt::CTRL + Qt::Key_1 << Qt::CTRL + Qt::Key_2 << Qt::CTRL + Qt::Key_3 << Qt::CTRL + Qt::Key_4); + QList() << 1 << 2 << 3 << 4 << 5 << 6 << 7 << 8 << 9 << 10, + QList() << Qt::CTRL + Qt::Key_1 << Qt::CTRL + Qt::Key_2 << Qt::CTRL + Qt::Key_3 << Qt::CTRL + Qt::Key_4 << Qt::CTRL + Qt::Key_5 + << Qt::CTRL + Qt::Key_6 << Qt::CTRL + Qt::Key_7 << Qt::CTRL + Qt::Key_8 << Qt::CTRL + Qt::Key_9 << Qt::CTRL + Qt::Key_0); MenuTree* displayLayoutMenu = new MenuTree(this, videoMenu, QT_TR_NOOP("&Display Layout Options")); displayLayoutGroup = new MenuActionGroup(this, displayLayoutMenu, SLOT(displayLayoutGroup_triggered(QAction *)), @@ -511,6 +512,8 @@ void MainWindow::createMenus() ->addEventChecked(&g_Config.bVertexCache); videoMenu->add(new MenuAction(this, SLOT(frameskipAct()), QT_TR_NOOP("&Frameskip"))) ->addEventChecked(&g_Config.iFrameSkip); + videoMenu->add(new MenuAction(this, SLOT(frameskipTypeAct()), QT_TR_NOOP("&FrameSkipType"))) + ->addEventChecked(&g_Config.iFrameSkipType); optionsMenu->add(new MenuAction(this, SLOT(audioAct()), QT_TR_NOOP("&Audio"))) ->addEventChecked(&g_Config.bEnableSound); optionsMenu->addSeparator(); diff --git a/Qt/mainwindow.h b/Qt/mainwindow.h index 90ab051b91..2745d73183 100644 --- a/Qt/mainwindow.h +++ b/Qt/mainwindow.h @@ -114,6 +114,7 @@ private slots: void transformAct() { g_Config.bHardwareTransform = !g_Config.bHardwareTransform; } void vertexCacheAct() { g_Config.bVertexCache = !g_Config.bVertexCache; } void frameskipAct() { g_Config.iFrameSkip = !g_Config.iFrameSkip; } + void frameskipTypeAct() { g_Config.iFrameSkipType = !g_Config.iFrameSkipType; } // Sound void audioAct() { g_Config.bEnableSound = !g_Config.bEnableSound; } diff --git a/README.md b/README.md index e1ebeda929..d9c00dc8d8 100644 --- a/README.md +++ b/README.md @@ -30,6 +30,17 @@ No BIOS file required to play, PPSSPP is an "HLE" emulator. Default settings ba Also includes a really awful hack for MOHH2 multiplayer(MOHH1 works fine without it;p). ~ LunaMoo + +What's new in 1.7.3/1.7.4/1.7.5 +------------------- +* Fixes for a couple of common crashes +* Reverted immersive mode change temporarily to see if it helps misaligned buttons +* Change default adhoc server address + +What's new in 1.7.2 +------------------- +* Update text of "Buy PPSSPP Gold" button + What's new in 1.7.1 ------------------- * Minor crashfixes, lang updates diff --git a/SDL/SDLGLGraphicsContext.h b/SDL/SDLGLGraphicsContext.h index e0cb354701..c32d104814 100644 --- a/SDL/SDLGLGraphicsContext.h +++ b/SDL/SDLGLGraphicsContext.h @@ -32,7 +32,7 @@ public: } void ThreadStart() override { - renderManager_->ThreadStart(); + renderManager_->ThreadStart(draw_); } bool ThreadFrame() override { diff --git a/SDL/SDLMain.cpp b/SDL/SDLMain.cpp index 6dd6d2242b..db786c3f17 100644 --- a/SDL/SDLMain.cpp +++ b/SDL/SDLMain.cpp @@ -441,7 +441,7 @@ int main(int argc, char *argv[]) { } // If we're on mobile, don't try for windowed either. -#if defined(USING_GLES2) || defined(MOBILE_DEVICE) +#if defined(MOBILE_DEVICE) mode |= SDL_WINDOW_FULLSCREEN; #else mode |= SDL_WINDOW_RESIZABLE; diff --git a/SDL/SDLVulkanGraphicsContext.cpp b/SDL/SDLVulkanGraphicsContext.cpp index a29d41ac3e..123c016ef7 100644 --- a/SDL/SDLVulkanGraphicsContext.cpp +++ b/SDL/SDLVulkanGraphicsContext.cpp @@ -63,16 +63,15 @@ bool SDLVulkanGraphicsContext::Init(SDL_Window *&window, int x, int y, int mode, case SDL_SYSWM_X11: #if defined(VK_USE_PLATFORM_XLIB_KHR) vulkan_->InitSurface(WINDOWSYSTEM_XLIB, (void*)sys_info.info.x11.display, - (void *)(intptr_t)sys_info.info.x11.window, pixel_xres, pixel_yres); + (void *)(intptr_t)sys_info.info.x11.window); #elif defined(VK_USE_PLATFORM_XCB_KHR) vulkan_->InitSurface(WINDOWSYSTEM_XCB, (void*)XGetXCBConnection(sys_info.info.x11.display), - (void *)(intptr_t)sys_info.info.x11.window, pixel_xres, pixel_yres); + (void *)(intptr_t)sys_info.info.x11.window); #endif break; #if defined(VK_USE_PLATFORM_WAYLAND_KHR) case SDL_SYSWM_WAYLAND: - vulkan_->InitSurface(WINDOWSYSTEM_WAYLAND, (void*)sys_info.info.wl.display, - (void *)sys_info.info.wl.surface, pixel_xres, pixel_yres); + vulkan_->InitSurface(WINDOWSYSTEM_WAYLAND, (void*)sys_info.info.wl.display, (void *)sys_info.info.wl.surface); break; #endif default: diff --git a/UI/ControlMappingScreen.cpp b/UI/ControlMappingScreen.cpp index 5365f11638..1a9189352a 100644 --- a/UI/ControlMappingScreen.cpp +++ b/UI/ControlMappingScreen.cpp @@ -478,10 +478,9 @@ void JoystickHistoryView::Draw(UIContext &dc) { dc.Draw()->DrawImage(I_CROSS, x, y, 0.8f, colorAlpha(0xFFFFFF, alpha), ALIGN_CENTER); a++; } - dc.End(); dc.BeginNoTex(); dc.Draw()->RectOutline(bounds_.centerX() - minRadius, bounds_.centerY() - minRadius, minRadius * 2, minRadius * 2, 0x80FFFFFF); - dc.End(); + dc.Flush(); dc.Begin(); } else { dc.DrawText("N/A", bounds_.centerX(), bounds_.centerY(), 0xFFFFFFFF, ALIGN_CENTER); diff --git a/UI/CwCheatScreen.cpp b/UI/CwCheatScreen.cpp index 8a9d8533ca..0adb9b5861 100644 --- a/UI/CwCheatScreen.cpp +++ b/UI/CwCheatScreen.cpp @@ -221,7 +221,7 @@ void CwCheatScreen::ParseCheatDB(std::string line, std::vector titl continue; } loop:; - } while (fs.good() && (line[0] == '_' && line[1] != 'S') || line[0] == '/' || line[0] == '#'); + } while (fs.good() && ((line[0] == '_' && line[1] != 'S') || line[0] == '/' || line[0] == '#')); finished = true; } if (finished == true) @@ -236,7 +236,7 @@ void CwCheatScreen::ParseCheatDB(std::string line, std::vector titl File::OpenCPPFile(fs, activeCheatFile, std::ios::out | std::ios::app); auto it = title.begin(); - if ((title2[0] == '_' && title2[1] != 'S') || title2[0] == '/' || title2[0] == '#' && it != title.end() && (++it) != title.end()) { + if (((title2[0] == '_' && title2[1] != 'S') || title2[0] == '/' || title2[0] == '#') && it != title.end() && (++it) != title.end()) { fs << title[0] << "\n" << title[1]; } diff --git a/UI/DevScreens.cpp b/UI/DevScreens.cpp index 298b429d75..254183e667 100644 --- a/UI/DevScreens.cpp +++ b/UI/DevScreens.cpp @@ -37,6 +37,7 @@ #include "Core/MIPS/MIPSTables.h" #include "Core/MIPS/JitCommon/JitBlockCache.h" #include "Core/MIPS/JitCommon/JitCommon.h" +#include "Core/MIPS/JitCommon/JitState.h" #include "GPU/GPUInterface.h" #include "GPU/GPUState.h" #include "UI/MiscScreens.h" @@ -127,8 +128,6 @@ UI::EventReturn DevMenu::OnShaderView(UI::EventParams &e) { return UI::EVENT_DONE; } - - UI::EventReturn DevMenu::OnFreezeFrame(UI::EventParams &e) { if (PSP_CoreParameter().frozen) { PSP_CoreParameter().frozen = false; @@ -320,6 +319,70 @@ void LogLevelScreen::OnCompleted(DialogResult result) { } } +struct JitDisableFlag { + MIPSComp::JitDisable flag; + const char *name; +}; + +// Please do not try to translate these :) +static const JitDisableFlag jitDisableFlags[] = { + { MIPSComp::JitDisable::ALU, "ALU" }, + { MIPSComp::JitDisable::ALU_IMM, "ALU_IMM" }, + { MIPSComp::JitDisable::ALU_BIT, "ALU_BIT" }, + { MIPSComp::JitDisable::MULDIV, "MULDIV" }, + { MIPSComp::JitDisable::FPU, "FPU" }, + { MIPSComp::JitDisable::FPU_COMP, "FPU_COMP" }, + { MIPSComp::JitDisable::FPU_XFER, "FPU_XFER" }, + { MIPSComp::JitDisable::VFPU_VEC, "VFPU_VEC" }, + { MIPSComp::JitDisable::VFPU_MTX, "VFPU_MTX" }, + { MIPSComp::JitDisable::VFPU_COMP, "VFPU_COMP" }, + { MIPSComp::JitDisable::VFPU_XFER, "VFPU_XFER" }, + { MIPSComp::JitDisable::LSU, "LSU" }, + { MIPSComp::JitDisable::LSU_UNALIGNED, "LSU_UNALIGNED" }, + { MIPSComp::JitDisable::LSU_FPU, "LSU_FPU" }, + { MIPSComp::JitDisable::LSU_VFPU, "LSU_VFPU" }, + { MIPSComp::JitDisable::SIMD, "SIMD" }, + { MIPSComp::JitDisable::BLOCKLINK, "Block Linking" }, + { MIPSComp::JitDisable::POINTERIFY, "Pointerify" }, + { MIPSComp::JitDisable::STATIC_ALLOC, "Static regalloc" }, + { MIPSComp::JitDisable::CACHE_POINTERS, "Cached pointers" }, +}; + +void JitDebugScreen::CreateViews() { + using namespace UI; + + I18NCategory *di = GetI18NCategory("Dialog"); + I18NCategory *dev = GetI18NCategory("Developer"); + + root_ = new ScrollView(ORIENT_VERTICAL); + + LinearLayout *vert = root_->Add(new LinearLayout(ORIENT_VERTICAL, new LinearLayoutParams(FILL_PARENT, WRAP_CONTENT))); + vert->SetSpacing(0); + + LinearLayout *topbar = new LinearLayout(ORIENT_HORIZONTAL); + topbar->Add(new Choice(di->T("Back")))->OnClick.Handle(this, &UIScreen::OnBack); + topbar->Add(new Choice(di->T("Disable All")))->OnClick.Handle(this, &JitDebugScreen::OnDisableAll); + topbar->Add(new Choice(di->T("Enable All")))->OnClick.Handle(this, &JitDebugScreen::OnEnableAll); + + vert->Add(topbar); + vert->Add(new ItemHeader(dev->T("Disabled JIT functionality"))); + + for (auto flag : jitDisableFlags) { + // Do not add translation of these. + vert->Add(new BitCheckBox(&g_Config.uJitDisableFlags, (uint32_t)flag.flag, flag.name)); + } +} + +UI::EventReturn JitDebugScreen::OnEnableAll(UI::EventParams &e) { + g_Config.uJitDisableFlags &= ~(uint32_t)MIPSComp::JitDisable::ALL_FLAGS; + return UI::EVENT_DONE; +} + +UI::EventReturn JitDebugScreen::OnDisableAll(UI::EventParams &e) { + g_Config.uJitDisableFlags |= (uint32_t)MIPSComp::JitDisable::ALL_FLAGS; + return UI::EVENT_DONE; +} + const char *GetCompilerABI() { #if PPSSPP_ARCH(ARMV7) return "armeabi-v7a"; @@ -388,7 +451,8 @@ void SystemInfoScreen::CreateViews() { DrawContext *draw = screenManager()->getDrawContext(); - const char *apiName = gr->T(screenManager()->getDrawContext()->GetInfoString(InfoField::APINAME)); + const std::string apiNameKey = draw->GetInfoString(InfoField::APINAME); + const char *apiName = gr->T(apiNameKey); deviceSpecs->Add(new InfoItem(si->T("3D API"), apiName)); deviceSpecs->Add(new InfoItem(si->T("Vendor"), draw->GetInfoString(InfoField::VENDORSTRING))); std::string vendor = draw->GetInfoString(InfoField::VENDOR); diff --git a/UI/DevScreens.h b/UI/DevScreens.h index a95ba61c27..a6c480bc66 100644 --- a/UI/DevScreens.h +++ b/UI/DevScreens.h @@ -47,6 +47,16 @@ protected: UI::EventReturn OnToggleAudioDebug(UI::EventParams &e); }; +class JitDebugScreen : public UIDialogScreenWithBackground { +public: + JitDebugScreen() {} + virtual void CreateViews() override; + +private: + UI::EventReturn OnEnableAll(UI::EventParams &e); + UI::EventReturn OnDisableAll(UI::EventParams &e); +}; + class LogConfigScreen : public UIDialogScreenWithBackground { public: LogConfigScreen() {} diff --git a/UI/DiscordIntegration.cpp b/UI/DiscordIntegration.cpp index 54ee337e3f..176e3059a3 100644 --- a/UI/DiscordIntegration.cpp +++ b/UI/DiscordIntegration.cpp @@ -7,9 +7,13 @@ #include "DiscordIntegration.h" #include "i18n/i18n.h" -#if (PPSSPP_PLATFORM(WINDOWS) || PPSSPP_PLATFORM(MAC) || PPSSPP_PLATFORM(LINUX)) && !PPSSPP_PLATFORM(ANDROID) +#if (PPSSPP_PLATFORM(WINDOWS) || PPSSPP_PLATFORM(MAC) || PPSSPP_PLATFORM(LINUX)) && !PPSSPP_PLATFORM(ANDROID) && !PPSSPP_PLATFORM(UWP) +#ifdef _MSC_VER #define ENABLE_DISCORD +#elif USE_DISCORD +#define ENABLE_DISCORD +#endif #else @@ -98,6 +102,7 @@ void Discord::SetPresenceGame(const char *gameTitle) { std::string details = sc->T("Playing"); discordPresence.details = details.c_str(); discordPresence.startTimestamp = time(0); + discordPresence.largeImageText = "PPSSPP is the best PlayStation Portable emulator around!"; #ifdef GOLD discordPresence.largeImageKey = "icon_gold_png"; #else @@ -122,6 +127,7 @@ void Discord::SetPresenceMenu() { discordPresence.state = sc->T("In menu"); discordPresence.details = ""; discordPresence.startTimestamp = time(0); + discordPresence.largeImageText = "PPSSPP is the best PlayStation Portable emulator around!"; #ifdef GOLD discordPresence.largeImageKey = "icon_gold_png"; #else @@ -130,3 +136,12 @@ void Discord::SetPresenceMenu() { Discord_UpdatePresence(&discordPresence); #endif } + +void Discord::ClearPresence() { + if (!IsEnabled() || !initialized_) + return; + +#ifdef ENABLE_DISCORD + Discord_ClearPresence(); +#endif +} diff --git a/UI/DiscordIntegration.h b/UI/DiscordIntegration.h index cd700d59ea..a2911d6877 100644 --- a/UI/DiscordIntegration.h +++ b/UI/DiscordIntegration.h @@ -17,6 +17,7 @@ public: void SetPresenceGame(const char *gameTitle); void SetPresenceMenu(); + void ClearPresence(); private: void Init(); diff --git a/UI/EmuScreen.cpp b/UI/EmuScreen.cpp index d5b0c3eb6b..3b921164bf 100644 --- a/UI/EmuScreen.cpp +++ b/UI/EmuScreen.cpp @@ -231,6 +231,7 @@ void EmuScreen::bootGame(const std::string &filename) { if (g_Config.bSoftwareRendering) { coreParam.gpuCore = GPUCORE_SOFTWARE; } + // Preserve the existing graphics context. coreParam.graphicsContext = PSP_CoreParameter().graphicsContext; coreParam.thin3d = screenManager()->getDrawContext(); @@ -346,7 +347,11 @@ EmuScreen::~EmuScreen() { startDumping = false; } #endif - g_Discord.SetPresenceMenu(); + + if (GetUIState() == UISTATE_EXIT) + g_Discord.ClearPresence(); + else + g_Discord.SetPresenceMenu(); } void EmuScreen::dialogFinished(const Screen *dialog, DialogResult result) { @@ -1182,11 +1187,6 @@ void EmuScreen::preRender() { using namespace Draw; DrawContext *draw = screenManager()->getDrawContext(); draw->BeginFrame(); - // Let's be consistent for the entire frame. We skip the UI texture if we don't need it. - hasVisibleUI_ = hasVisibleUI(); - if (hasVisibleUI_) { - screenManager()->getUIContext()->BeginFrame(); - } // Here we do NOT bind the backbuffer or clear the screen, unless non-buffered. // The emuscreen is different than the others - we really want to allow the game to render to framebuffers // before we ever bind the backbuffer for rendering. On mobile GPUs, switching back and forth between render @@ -1285,7 +1285,8 @@ void EmuScreen::render() { if (invalid_) return; - if (hasVisibleUI_) { + if (hasVisibleUI()) { + screenManager()->getUIContext()->BeginFrame(); renderUI(); } @@ -1366,8 +1367,7 @@ void EmuScreen::renderUI() { if ((g_Config.bShowFrameProfiler || g_Config.bSimpleFrameStats) && !invalid_) { DrawProfile(*ctx); } - - ctx->End(); + ctx->Flush(); } void EmuScreen::autoLoad() { diff --git a/UI/EmuScreen.h b/UI/EmuScreen.h index 0dd44e614a..0ac62e76e7 100644 --- a/UI/EmuScreen.h +++ b/UI/EmuScreen.h @@ -80,7 +80,6 @@ private: bool invalid_; bool quit_; bool stopRender_ = false; - bool hasVisibleUI_ = true; std::string errorMessage_; // If set, pauses at the end of the frame. diff --git a/UI/GPUDriverTestScreen.cpp b/UI/GPUDriverTestScreen.cpp new file mode 100644 index 0000000000..bd9f0aa7ab --- /dev/null +++ b/UI/GPUDriverTestScreen.cpp @@ -0,0 +1,332 @@ +#include "GPUDriverTestScreen.h" +#include "i18n/i18n.h" +#include "ui/view.h" + +static const std::vector fsDiscard = { + {Draw::ShaderLanguage::GLSL_ES_200, + R"( + #ifdef GL_ES + precision lowp float; + #endif + #if __VERSION__ >= 130 + #define varying in + #define gl_FragColor fragColor0 + out vec4 fragColor0; + #endif + varying vec4 oColor0; + varying vec2 oTexCoord0; + uniform sampler2D Sampler0; + void main() { + vec4 color = texture2D(Sampler0, oTexCoord0) * oColor0; + if (color.a <= 0.0) + discard; + gl_FragColor = color; + })" + }, + {Draw::ShaderLanguage::GLSL_VULKAN, + R"(#version 140 + #extension GL_ARB_separate_shader_objects : enable + #extension GL_ARB_shading_language_420pack : enable + layout(location = 0) in vec4 oColor0; + layout(location = 1) in vec2 oTexCoord0; + layout(location = 0) out vec4 fragColor0; + layout(set = 0, binding = 1) uniform sampler2D Sampler0; + void main() { + vec4 color = texture(Sampler0, oTexCoord0) * oColor0; + if (color.a <= 0.0) + discard; + fragColor0 = color; + })" + }, +}; + +GPUDriverTestScreen::GPUDriverTestScreen() { + using namespace Draw; +} + +GPUDriverTestScreen::~GPUDriverTestScreen() { + if (discardWriteDepthStencil_) + discardWriteDepthStencil_->Release(); + if (discardWriteDepth_) + discardWriteDepth_->Release(); + if (discardWriteStencil_) + discardWriteStencil_->Release(); + + if (drawTestStencilEqualDepthAlways_) + drawTestStencilEqualDepthAlways_->Release(); + if (drawTestStencilNotEqualDepthAlways_) + drawTestStencilNotEqualDepthAlways_->Release(); + if (drawTestStencilEqual_) + drawTestStencilEqual_->Release(); + if (drawTestStencilNotEqual_) + drawTestStencilNotEqual_->Release(); + if (drawTestStencilAlwaysDepthLessEqual_) + drawTestStencilAlwaysDepthLessEqual_->Release(); + if (drawTestStencilAlwaysDepthGreater_) + drawTestStencilAlwaysDepthGreater_->Release(); + if (drawTestDepthLessEqual_) + drawTestDepthLessEqual_->Release(); + if (drawTestDepthGreater_) + drawTestDepthGreater_->Release(); + + if (discardFragShader_) + discardFragShader_->Release(); + if (samplerNearest_) + samplerNearest_->Release(); +} + +void GPUDriverTestScreen::CreateViews() { + // Don't bother with views for now. + using namespace UI; + I18NCategory *di = GetI18NCategory("Dialog"); + I18NCategory *cr = GetI18NCategory("PSPCredits"); + + AnchorLayout *anchor = new AnchorLayout(); + root_ = anchor; + + tabHolder_ = new TabHolder(ORIENT_HORIZONTAL, 30.0f, new AnchorLayoutParams(FILL_PARENT, FILL_PARENT, false)); + anchor->Add(tabHolder_); + tabHolder_->AddTab("Discard", new LinearLayout(ORIENT_VERTICAL)); + + Choice *back = new Choice(di->T("Back"), "", false, new AnchorLayoutParams(100, WRAP_CONTENT, 10, NONE, NONE, 10)); + back->OnClick.Handle(this, &UIScreen::OnBack); + anchor->Add(back); +} + +void GPUDriverTestScreen::DiscardTest() { + using namespace UI; + using namespace Draw; + if (!discardWriteDepthStencil_) { + DrawContext *draw = screenManager()->getDrawContext(); + + // Create the special shader module. + + discardFragShader_ = CreateShader(draw, Draw::ShaderStage::FRAGMENT, fsDiscard); + + InputLayout *inputLayout = ui_draw2d.CreateInputLayout(draw); + BlendState *blendOff = draw->CreateBlendState({ false, 0xF }); + + // Write depth, write stencil. + DepthStencilStateDesc dsDesc{}; + dsDesc.depthTestEnabled = true; + dsDesc.depthWriteEnabled = true; + dsDesc.depthCompare = Comparison::ALWAYS; + dsDesc.stencilEnabled = true; + dsDesc.front.compareMask = 0xFF; + dsDesc.front.compareOp = Comparison::ALWAYS; + dsDesc.front.passOp = StencilOp::REPLACE; + dsDesc.front.failOp = StencilOp::ZERO; + dsDesc.front.depthFailOp = StencilOp::ZERO; + dsDesc.front.writeMask = 0xFF; + dsDesc.back = dsDesc.front; + DepthStencilState *depthStencilWrite = draw->CreateDepthStencilState(dsDesc); + + // Write only depth. + dsDesc.stencilEnabled = false; + DepthStencilState *depthWrite = draw->CreateDepthStencilState(dsDesc); + + // Write only stencil. + dsDesc.stencilEnabled = true; + dsDesc.depthTestEnabled = false; + dsDesc.depthWriteEnabled = false; // Just in case the driver is crazy. when test is enabled, though, this should be ignored. + DepthStencilState *stencilWrite = draw->CreateDepthStencilState(dsDesc); + + // Now for the shaders that read depth and/or stencil. + + dsDesc.depthTestEnabled = true; + dsDesc.stencilEnabled = true; + dsDesc.depthCompare = Comparison::ALWAYS; + dsDesc.front.compareOp = Comparison::EQUAL; + dsDesc.back = dsDesc.front; + DepthStencilState *stencilEqualDepthAlways = draw->CreateDepthStencilState(dsDesc); + + dsDesc.depthTestEnabled = false; + dsDesc.front.compareOp = Comparison::EQUAL; + dsDesc.back = dsDesc.front; + DepthStencilState *stencilEqual = draw->CreateDepthStencilState(dsDesc); + + dsDesc.depthTestEnabled = true; + dsDesc.depthCompare = Comparison::ALWAYS; + dsDesc.front.compareOp = Comparison::NOT_EQUAL; + dsDesc.back = dsDesc.front; + DepthStencilState *stenciNotEqualDepthAlways = draw->CreateDepthStencilState(dsDesc); + + dsDesc.depthTestEnabled = false; + dsDesc.front.compareOp = Comparison::NOT_EQUAL; + dsDesc.back = dsDesc.front; + DepthStencilState *stencilNotEqual = draw->CreateDepthStencilState(dsDesc); + + dsDesc.stencilEnabled = true; + dsDesc.depthTestEnabled = true; + dsDesc.front.compareOp = Comparison::ALWAYS; + dsDesc.back = dsDesc.front; + dsDesc.depthCompare = Comparison::LESS_EQUAL; + DepthStencilState *stencilAlwaysDepthTestLessEqual = draw->CreateDepthStencilState(dsDesc); + dsDesc.depthCompare = Comparison::GREATER; + DepthStencilState *stencilAlwaysDepthTestGreater = draw->CreateDepthStencilState(dsDesc); + + dsDesc.stencilEnabled = false; + dsDesc.depthTestEnabled = true; + dsDesc.depthCompare = Comparison::LESS_EQUAL; + DepthStencilState *depthTestLessEqual = draw->CreateDepthStencilState(dsDesc); + dsDesc.depthCompare = Comparison::GREATER; + DepthStencilState *depthTestGreater = draw->CreateDepthStencilState(dsDesc); + + RasterState *rasterNoCull = draw->CreateRasterState({}); + + PipelineDesc discardDesc{ + Primitive::TRIANGLE_LIST, + { draw->GetVshaderPreset(VS_TEXTURE_COLOR_2D), discardFragShader_ }, + inputLayout, depthStencilWrite, blendOff, rasterNoCull, &vsColBufDesc, + }; + discardWriteDepthStencil_ = draw->CreateGraphicsPipeline(discardDesc); + discardDesc.depthStencil = depthWrite; + discardWriteDepth_ = draw->CreateGraphicsPipeline(discardDesc); + discardDesc.depthStencil = stencilWrite; + discardWriteStencil_ = draw->CreateGraphicsPipeline(discardDesc); + + PipelineDesc testDesc{ + Primitive::TRIANGLE_LIST, + { draw->GetVshaderPreset(VS_TEXTURE_COLOR_2D), draw->GetFshaderPreset(FS_TEXTURE_COLOR_2D) }, + inputLayout, stencilEqual, blendOff, rasterNoCull, &vsColBufDesc, + }; + drawTestStencilEqual_ = draw->CreateGraphicsPipeline(testDesc); + + testDesc.depthStencil = stencilEqualDepthAlways; + drawTestStencilEqualDepthAlways_ = draw->CreateGraphicsPipeline(testDesc); + + testDesc.depthStencil = stencilNotEqual; + drawTestStencilNotEqual_ = draw->CreateGraphicsPipeline(testDesc); + + testDesc.depthStencil = stenciNotEqualDepthAlways; + drawTestStencilNotEqualDepthAlways_ = draw->CreateGraphicsPipeline(testDesc); + + testDesc.depthStencil = stencilAlwaysDepthTestGreater; + drawTestStencilAlwaysDepthGreater_ = draw->CreateGraphicsPipeline(testDesc); + + testDesc.depthStencil = stencilAlwaysDepthTestLessEqual; + drawTestStencilAlwaysDepthLessEqual_ = draw->CreateGraphicsPipeline(testDesc); + + testDesc.depthStencil = depthTestGreater; + drawTestDepthGreater_ = draw->CreateGraphicsPipeline(testDesc); + + testDesc.depthStencil = depthTestLessEqual; + drawTestDepthLessEqual_ = draw->CreateGraphicsPipeline(testDesc); + + inputLayout->Release(); + blendOff->Release(); + depthStencilWrite->Release(); + stencilEqual->Release(); + stencilNotEqual->Release(); + stencilEqualDepthAlways->Release(); + stenciNotEqualDepthAlways->Release(); + stencilAlwaysDepthTestLessEqual->Release(); + stencilAlwaysDepthTestGreater->Release(); + depthTestLessEqual->Release(); + depthTestGreater->Release(); + rasterNoCull->Release(); + + SamplerStateDesc nearestDesc{}; + samplerNearest_ = draw->CreateSamplerState(nearestDesc); + } + + UIContext &dc = *screenManager()->getUIContext(); + Draw::DrawContext *draw = dc.GetDrawContext(); + const Bounds &bounds = dc.GetBounds(); + + static const char * const writeModeNames[] = { "Stencil+Depth", "Stencil", "Depth" }; + Pipeline *writePipelines[] = { discardWriteDepthStencil_, discardWriteStencil_, discardWriteDepth_ }; + const int numWriteModes = ARRAY_SIZE(writeModeNames); + + static const char * const testNames[] = { "Stenc", "Stenc+DepthA", "Depth", "StencA+Depth" }; + Pipeline *testPipeline1[] = { drawTestStencilEqual_, drawTestStencilEqualDepthAlways_, drawTestDepthLessEqual_, drawTestStencilAlwaysDepthLessEqual_ }; + Pipeline *testPipeline2[] = { drawTestStencilNotEqual_, drawTestStencilNotEqualDepthAlways_, drawTestDepthGreater_, drawTestStencilAlwaysDepthGreater_ }; + const int numTests = ARRAY_SIZE(testNames); + + static const bool validCombinations[numWriteModes][numTests] = { + {true, true, true, true}, + {true, true, false, false}, + {false, false, true, true}, + }; + + uint32_t textColorOK = 0xFF30FF30; + uint32_t textColorBAD = 0xFF3030FF; + uint32_t bgColorOK = 0xFF106010; + uint32_t bgColorBAD = 0xFF101060; + + // Don't want any fancy font texture stuff going on here, so use FLAG_DYNAMIC_ASCII everywhere! + + // We draw the background at Z=0.5 and the text at Z=0.9. + + // Then we draw a rectangle with a depth test or stencil test that should mask out the text. + // Plus a second rectangle with the opposite test. + + // If everything is OK, both the background and the text should be OK. + + dc.Begin(); + dc.SetFontScale(1.0f, 1.0f); + std::string apiName = screenManager()->getDrawContext()->GetInfoString(InfoField::APINAME); + std::string vendor = screenManager()->getDrawContext()->GetInfoString(InfoField::VENDORSTRING); + std::string driver = screenManager()->getDrawContext()->GetInfoString(InfoField::DRIVER); + dc.DrawText(apiName.c_str(), bounds.centerX(), 20, 0xFFFFFFFF, ALIGN_CENTER); + dc.DrawText(vendor.c_str(), bounds.centerX(), 60, 0xFFFFFFFF, ALIGN_CENTER); + dc.DrawText(driver.c_str(), bounds.centerX(), 100, 0xFFFFFFFF, ALIGN_CENTER); + dc.Flush(); + + float testW = 170.f; + float padding = 20.0f; + UI::Style style = dc.theme->itemStyle; + + float y = 150; + for (int j = 0; j < numWriteModes; j++, y += 120.f + padding) { + float x = (dc.GetBounds().w - (float)numTests * testW - (float)(numTests - 1) * padding) / 2.0f; + dc.Begin(); + dc.DrawText(writeModeNames[j], padding, y + 40, 0xFFFFFFFF, FLAG_DYNAMIC_ASCII); + dc.Flush(); + for (int i = 0; i < numTests; i++, x += testW + padding) { + if (!validCombinations[j][i]) + continue; + dc.Begin(); + Bounds bounds = { x, y + 40, testW, 70 }; + dc.DrawText(testNames[i], bounds.x, y, style.fgColor, FLAG_DYNAMIC_ASCII); + dc.Flush(); + + dc.BeginPipeline(writePipelines[j], samplerNearest_); + // Draw the rectangle with stencil value 0, depth 0.1f and the text with stencil 0xFF, depth 0.9. Then leave 0xFF as the stencil value and draw the rectangles at depth 0.5. + draw->SetStencilRef(0x0); + dc.SetCurZ(0.1f); + dc.FillRect(UI::Drawable(bgColorBAD), bounds); + // test bounds + dc.Flush(); + + draw->SetStencilRef(0xff); + dc.SetCurZ(0.9f); + dc.DrawTextRect("TEST OK", bounds, textColorBAD, ALIGN_HCENTER | ALIGN_VCENTER | FLAG_DYNAMIC_ASCII); + dc.Flush(); + + // Draw rectangle that should result in the text + dc.BeginPipeline(testPipeline1[i], samplerNearest_); + draw->SetStencilRef(0xff); + dc.SetCurZ(0.5f); + dc.FillRect(UI::Drawable(textColorOK), bounds); + dc.Flush(); + + // Draw rectangle that should result in the bg + dc.BeginPipeline(testPipeline2[i], samplerNearest_); + draw->SetStencilRef(0xff); + dc.SetCurZ(0.5f); + dc.FillRect(UI::Drawable(bgColorOK), bounds); + dc.Flush(); + } + } + dc.Flush(); +} + +void GPUDriverTestScreen::render() { + using namespace Draw; + UIScreen::render(); + + if (tabHolder_->GetCurrentTab() == 0) { + DiscardTest(); + } +} diff --git a/UI/GPUDriverTestScreen.h b/UI/GPUDriverTestScreen.h new file mode 100644 index 0000000000..bf5c56a02c --- /dev/null +++ b/UI/GPUDriverTestScreen.h @@ -0,0 +1,45 @@ +#pragma once + +#include + +#include "base/display.h" +#include "ui/ui_context.h" +#include "ui/view.h" +#include "ui/viewgroup.h" +#include "ui/ui.h" + +#include "Common/LogManager.h" +#include "UI/MiscScreens.h" +#include "thin3d/thin3d.h" + +class GPUDriverTestScreen : public UIDialogScreenWithBackground { +public: + GPUDriverTestScreen(); + ~GPUDriverTestScreen(); + + void CreateViews() override; + void render() override; + +private: + void DiscardTest(); + + Draw::ShaderModule *discardFragShader_ = nullptr; + Draw::Pipeline *discardWriteDepthStencil_ = nullptr; + Draw::Pipeline *discardWriteDepth_ = nullptr; + Draw::Pipeline *discardWriteStencil_ = nullptr; + + // Stencil test, with and without DepthAlways + Draw::Pipeline *drawTestStencilEqual_ = nullptr; + Draw::Pipeline *drawTestStencilNotEqual_ = nullptr; + Draw::Pipeline *drawTestStencilEqualDepthAlways_ = nullptr; + Draw::Pipeline *drawTestStencilNotEqualDepthAlways_ = nullptr; + + // Depth tests with and without StencilAlways + Draw::Pipeline *drawTestStencilAlwaysDepthLessEqual_ = nullptr; + Draw::Pipeline *drawTestStencilAlwaysDepthGreater_ = nullptr; + Draw::Pipeline *drawTestDepthLessEqual_ = nullptr; + Draw::Pipeline *drawTestDepthGreater_ = nullptr; + + Draw::SamplerState *samplerNearest_ = nullptr; + UI::TabHolder *tabHolder_ = nullptr; +}; diff --git a/UI/GameInfoCache.cpp b/UI/GameInfoCache.cpp index f727aa1363..c1f263c71f 100644 --- a/UI/GameInfoCache.cpp +++ b/UI/GameInfoCache.cpp @@ -742,7 +742,7 @@ void GameInfoCache::WaitUntilDone(std::shared_ptr &info) { } -// Runs on the main thread. +// Runs on the main thread. Only call from render() and similar, not update()! std::shared_ptr GameInfoCache::GetInfo(Draw::DrawContext *draw, const std::string &gamePath, int wantFlags) { std::shared_ptr info; @@ -800,7 +800,7 @@ void GameInfoCache::SetupTexture(std::shared_ptr &info, Draw::DrawCont if (tex.texture) { tex.timeLoaded = time_now_d(); } else { - ERROR_LOG(G3D, "Failed creating texture"); + ERROR_LOG(G3D, "Failed creating texture (%s)", info->GetTitle().c_str()); } } if ((info->wantFlags & GAMEINFO_WANTBGDATA) == 0) { diff --git a/UI/GameScreen.cpp b/UI/GameScreen.cpp index d10584463e..250977b329 100644 --- a/UI/GameScreen.cpp +++ b/UI/GameScreen.cpp @@ -189,8 +189,8 @@ UI::EventReturn GameScreen::OnDeleteConfig(UI::EventParams &e) return UI::EVENT_DONE; } -void GameScreen::update() { - UIScreen::update(); +void GameScreen::render() { + UIScreen::render(); I18NCategory *ga = GetI18NCategory("Game"); diff --git a/UI/GameScreen.h b/UI/GameScreen.h index 77b0c8727b..bc35ab64ea 100644 --- a/UI/GameScreen.h +++ b/UI/GameScreen.h @@ -33,7 +33,7 @@ public: GameScreen(const std::string &gamePath); ~GameScreen(); - void update() override; + void render() override; std::string tag() const override { return "game"; } diff --git a/UI/GameSettingsScreen.cpp b/UI/GameSettingsScreen.cpp index 4fcb579ae4..be06430bf1 100644 --- a/UI/GameSettingsScreen.cpp +++ b/UI/GameSettingsScreen.cpp @@ -284,7 +284,6 @@ void GameSettingsScreen::CreateViews() { graphicsSettings->Add(new PopupMultiChoice(&g_Config.iFrameSkip, gr->T("Frame Skipping"), frameSkip, 0, ARRAY_SIZE(frameSkip), gr->GetName(), screenManager())); frameSkipAuto_ = graphicsSettings->Add(new CheckBox(&g_Config.bAutoFrameSkip, gr->T("Auto FrameSkip"))); frameSkipAuto_->OnClick.Handle(this, &GameSettingsScreen::OnAutoFrameskip); - graphicsSettings->Add(new CheckBox(&cap60FPS_, gr->T("Force max 60 FPS (helps GoW)"))); } @@ -420,7 +419,7 @@ void GameSettingsScreen::CreateViews() { return UI::EVENT_CONTINUE; }); - CheckBox *tessellationHW = graphicsSettings->Add(new CheckBox(&g_Config.bHardwareTessellation, gr->T("Hardware Tessellation", "Hardware tessellation (experimental)"))); + CheckBox *tessellationHW = graphicsSettings->Add(new CheckBox(&g_Config.bHardwareTessellation, gr->T("Hardware Tessellation"))); tessellationHW->OnClick.Add([=](EventParams &e) { settingInfo_->Show(gr->T("HardwareTessellation Tip", "Uses hardware to make curves"), e.v); return UI::EVENT_CONTINUE; @@ -507,15 +506,9 @@ void GameSettingsScreen::CreateViews() { cardboardYShift->SetDisabledPtr(&g_Config.bSoftwareRendering); #endif - graphicsSettings->Add(new ItemHeader(gr->T("Hack Settings", "Hack Settings (these WILL cause glitches)"))); - CheckBox *timerHack = graphicsSettings->Add(new CheckBox(&g_Config.bTimerHack, gr->T("Timer Hack"))); - timerHack->OnClick.Add([=](EventParams &e) { - settingInfo_->Show(gr->T("TimerHack Tip", "Changes game clock based on emu speed, may break games"), e.v); - return UI::EVENT_CONTINUE; - }); + graphicsSettings->Add(new ItemHeader(gr->T("Hack Settings"))); + - CheckBox *stencilTest = graphicsSettings->Add(new CheckBox(&g_Config.bDisableStencilTest, gr->T("Disable Stencil Test"))); - stencilTest->SetDisabledPtr(&g_Config.bSoftwareRendering); static const char *bloomHackOptions[] = { "Off", "Safe", "Balanced", "Aggressive" }; PopupMultiChoice *bloomHack = graphicsSettings->Add(new PopupMultiChoice(&g_Config.iBloomHack, gr->T("Lower resolution for effects (reduces artifacts)"), bloomHackOptions, 0, ARRAY_SIZE(bloomHackOptions), gr->GetName(), screenManager())); diff --git a/UI/GameSettingsScreen.h b/UI/GameSettingsScreen.h index c3dc03a084..8a10b7093f 100644 --- a/UI/GameSettingsScreen.h +++ b/UI/GameSettingsScreen.h @@ -158,7 +158,9 @@ private: UI::EventReturn OnOpenTexturesIniFile(UI::EventParams &e); UI::EventReturn OnLogConfig(UI::EventParams &e); UI::EventReturn OnJitAffectingSetting(UI::EventParams &e); + UI::EventReturn OnJitDebugTools(UI::EventParams &e); UI::EventReturn OnRemoteDebugger(UI::EventParams &e); + UI::EventReturn OnGPUDriverTest(UI::EventParams &e); bool allowDebugger_ = false; bool canAllowDebugger_ = true; diff --git a/UI/GamepadEmu.cpp b/UI/GamepadEmu.cpp index d8c5ad0b70..a703616178 100644 --- a/UI/GamepadEmu.cpp +++ b/UI/GamepadEmu.cpp @@ -617,7 +617,7 @@ UI::ViewGroup *CreatePadLayout(float xres, float yres, bool *pause) { if (unthrottle) { unthrottle->SetAngle(180.0f); unthrottle->OnChange.Add([](UI::EventParams &e) { - if (e.a) { + if (e.a && coreState == CORE_STEPPING) { Core_EnableStepping(false); } return UI::EVENT_DONE; diff --git a/UI/InstallZipScreen.cpp b/UI/InstallZipScreen.cpp index 353a71878f..943d0c9908 100644 --- a/UI/InstallZipScreen.cpp +++ b/UI/InstallZipScreen.cpp @@ -23,6 +23,7 @@ #include "UI/ui_atlas.h" #include "file/file_util.h" +#include "Common/StringUtils.h" #include "Core/Util/GameManager.h" #include "UI/InstallZipScreen.h" #include "UI/MainScreen.h" @@ -43,8 +44,9 @@ void InstallZipScreen::CreateViews() { ViewGroup *leftColumn = new AnchorLayout(new LinearLayoutParams(1.0f)); root_->Add(leftColumn); + std::string shortFilename = GetFilenameFromPath(zipPath_); leftColumn->Add(new TextView(iz->T("Install game from ZIP file?"), ALIGN_LEFT, false, new AnchorLayoutParams(10, 10, NONE, NONE))); - leftColumn->Add(new TextView(zipPath_, ALIGN_LEFT, false, new AnchorLayoutParams(10, 60, NONE, NONE))); + leftColumn->Add(new TextView(shortFilename, ALIGN_LEFT, false, new AnchorLayoutParams(10, 60, NONE, NONE))); doneView_ = leftColumn->Add(new TextView("", new AnchorLayoutParams(10, 120, NONE, NONE))); progressBar_ = leftColumn->Add(new ProgressBar(new AnchorLayoutParams(10, 200, 200, NONE))); diff --git a/UI/MainScreen.cpp b/UI/MainScreen.cpp index b5eb4401b2..3baeaf315d 100644 --- a/UI/MainScreen.cpp +++ b/UI/MainScreen.cpp @@ -916,7 +916,8 @@ void MainScreen::CreateViews() { TextView *ver = rightColumnItems->Add(new TextView(versionString, new LinearLayoutParams(Margins(70, -6, 0, 0)))); ver->SetSmall(true); ver->SetClip(false); -#if defined(_WIN32) || defined(USING_QT_UI) +// Temporarily disabled the load button for Qt. See #11721 +#if defined(_WIN32) // || defined(USING_QT_UI) rightColumnItems->Add(new Choice(mm->T("Load","Load...")))->OnClick.Handle(this, &MainScreen::OnLoadFile); #endif rightColumnItems->Add(new Choice(mm->T("Game Settings", "Settings")))->OnClick.Handle(this, &MainScreen::OnGameSettings); diff --git a/UI/MiscScreens.cpp b/UI/MiscScreens.cpp index d9fc03f0d8..5ec61c052f 100644 --- a/UI/MiscScreens.cpp +++ b/UI/MiscScreens.cpp @@ -513,7 +513,6 @@ void LogoScreen::render() { dc.DrawText(gr->T(apiName), bounds.centerX(), ppsspp_org_y + 50, textColor, ALIGN_CENTER); #endif - dc.End(); dc.Flush(); } @@ -757,6 +756,5 @@ void CreditsScreen::render() { y += itemHeight; } - dc.End(); dc.Flush(); } diff --git a/UI/NativeApp.cpp b/UI/NativeApp.cpp index 3e554fcf1b..b97119a7ad 100644 --- a/UI/NativeApp.cpp +++ b/UI/NativeApp.cpp @@ -96,6 +96,7 @@ #include "UI/BackgroundAudio.h" #include "UI/TextureUtil.h" #include "UI/DiscordIntegration.h" +#include "UI/GPUDriverTestScreen.h" #if !defined(MOBILE_DEVICE) #include "Common/KeyMap.h" @@ -133,7 +134,6 @@ static UI::Theme ui_theme; ScreenManager *screenManager; std::string config_filename; -bool g_graphicsIniting; bool g_graphicsInited; // Really need to clean this mess of globals up... but instead I add more :P @@ -344,11 +344,14 @@ void CreateDirectoriesAndroid() { File::CreateFullPath(GetSysDirectory(DIRECTORY_SAVESTATE)); File::CreateFullPath(GetSysDirectory(DIRECTORY_GAME)); File::CreateFullPath(GetSysDirectory(DIRECTORY_SYSTEM)); + File::CreateFullPath(GetSysDirectory(DIRECTORY_TEXTURES)); - // Avoid media scanners in PPSSPP_STATE and SAVEDATA directories + // Avoid media scanners in PPSSPP_STATE and SAVEDATA directories, + // and in the root PSP directory as well. File::CreateEmptyFile(GetSysDirectory(DIRECTORY_SAVESTATE) + ".nomedia"); File::CreateEmptyFile(GetSysDirectory(DIRECTORY_SAVEDATA) + ".nomedia"); File::CreateEmptyFile(GetSysDirectory(DIRECTORY_SYSTEM) + ".nomedia"); + File::CreateEmptyFile(GetSysDirectory(DIRECTORY_TEXTURES) + ".nomedia"); } static void CheckFailedGPUBackends() { @@ -679,6 +682,9 @@ void NativeInit(int argc, const char *argv[], const char *savegame_dir, const ch screenManager->switchScreen(new LogoScreen()); } + // Easy testing + // screenManager->push(new GPUDriverTestScreen()); + if (g_Config.bRemoteShareOnStartup && g_Config.bRemoteDebuggerOnStartup) StartWebServer(WebServerFlags::ALL); else if (g_Config.bRemoteShareOnStartup) @@ -754,7 +760,6 @@ static void UIThemeInit() { void RenderOverlays(UIContext *dc, void *userdata); bool NativeInitGraphics(GraphicsContext *graphicsContext) { - g_graphicsIniting = true; ILOG("NativeInitGraphics"); _assert_msg_(G3D, graphicsContext, "No graphics context!"); @@ -831,7 +836,6 @@ bool NativeInitGraphics(GraphicsContext *graphicsContext) { gpu->DeviceRestore(); g_graphicsInited = true; - g_graphicsIniting = false; ILOG("NativeInitGraphics completed"); return true; } @@ -931,7 +935,6 @@ void RenderOverlays(UIContext *dc, void *userdata) { UI::Drawable solid(colors[i & 3]); dc->FillRect(solid, bounds); } - dc->End(); dc->Flush(); } @@ -1259,7 +1262,7 @@ void NativeMessageReceived(const char *message, const char *value) { void NativeResized() { // NativeResized can come from any thread so we just set a flag, then process it later. - if (g_graphicsInited || g_graphicsIniting) { + if (g_graphicsInited) { resized = true; } else { ILOG("NativeResized ignored, not initialized"); diff --git a/UI/RemoteISOScreen.cpp b/UI/RemoteISOScreen.cpp index 6f31533349..9ba9df4f7d 100644 --- a/UI/RemoteISOScreen.cpp +++ b/UI/RemoteISOScreen.cpp @@ -37,19 +37,59 @@ static const int REPORT_PORT = 80; static bool scanCancelled = false; static bool scanAborted = false; +static std::string RemoteSubdir() { + if (g_Config.bRemoteISOManual) { + std::string subdir = g_Config.sRemoteISOSubdir; + size_t offset = subdir.find_last_of("/"); + if (offset != subdir.length() - 1 && offset != subdir.npos) { + // Truncate everything after last / + subdir.erase(offset + 1); + } + return subdir; + } + + return "/"; +} + static bool FindServer(std::string &resultHost, int &resultPort) { http::Client http; Buffer result; int code = 500; + std::string subdir = RemoteSubdir(); + auto TryServer = [&](const std::string &host, int port) { // Don't wait as long for a connect - we need a good connection for smooth streaming anyway. // This way if it's down, we'll find the right one faster. if (http.Resolve(host.c_str(), port) && http.Connect(1, 10.0, &scanCancelled)) { + code = http.GET(subdir.c_str(), &result); http.Disconnect(); - resultHost = host; - resultPort = port; - return true; + + if (code != 200) { + return false; + } + + // Make sure this isn't just the debugger. If so, move on. + std::string listing; + std::vector items; + result.TakeAll(&listing); + SplitString(listing, '\n', items); + + bool supported = false; + for (const std::string &item : items) { + if (!RemoteISOFileSupported(item)) { + continue; + } + supported = true; + break; + } + + if (supported) { + resultHost = host; + resultPort = port; + NOTICE_LOG(HLE, "RemoteISO found: %s : %d", host.c_str(), port); + return true; + } } return false; @@ -94,7 +134,6 @@ static bool FindServer(std::string &resultHost, int &resultPort) { return false; } - std::vector servers; for (const auto pentry : entries) { JsonGet entry = pentry->value; if (scanCancelled) @@ -105,7 +144,6 @@ static bool FindServer(std::string &resultHost, int &resultPort) { char url[1024] = {}; snprintf(url, sizeof(url), "http://%s:%d", host, port); - servers.push_back(url); if (TryServer(host, port)) { return true; @@ -121,17 +159,7 @@ static bool LoadGameList(const std::string &host, int port, std::vector responseHeaders; - std::string subdir = "/"; - size_t offset; - - if (g_Config.bRemoteISOManual) { - subdir = g_Config.sRemoteISOSubdir; - offset=subdir.find_last_of("/"); - if (offset != subdir.length() - 1 && offset != subdir.npos) { - // Truncate everything after last / - subdir.erase(offset + 1); - } - } + std::string subdir = RemoteSubdir(); // Start by requesting the list of games from the server. if (http.Resolve(host.c_str(), port)) { diff --git a/UI/SavedataScreen.cpp b/UI/SavedataScreen.cpp index f8e49d8a2d..a017aa540d 100644 --- a/UI/SavedataScreen.cpp +++ b/UI/SavedataScreen.cpp @@ -323,6 +323,8 @@ void SavedataBrowser::SetSortOption(SavedataSortOption opt) { gl->SetCompare(&ByFilename, &SortDone); } else if (sortOption_ == SavedataSortOption::SIZE) { gl->SetCompare(&BySize, &SortDone); + } else if (sortOption_ == SavedataSortOption::DATE) { + gl->SetCompare(&ByDate, &SortDone); } } } @@ -345,6 +347,29 @@ bool SavedataBrowser::BySize(const UI::View *v1, const UI::View *v2) { return g1info->gameSize > g2info->gameSize; } +bool SavedataBrowser::ByDate(const UI::View *v1, const UI::View *v2) { + const SavedataButton *b1 = static_cast(v1); + const SavedataButton *b2 = static_cast(v2); + + auto getDateSeconds = [&](const SavedataButton *b) { + std::shared_ptr ginfo = g_gameInfoCache->GetInfo(nullptr, b->GamePath(), 0); + tm datetm; + bool success; + if (ginfo && ginfo->fileType == IdentifiedFileType::PSP_SAVEDATA_DIRECTORY) { + success = File::GetModifTime(b->GamePath() + "/PARAM.SFO", datetm); + } else { + success = File::GetModifTime(b->GamePath(), datetm); + } + + if (success) { + return mktime(&datetm); + } + return (time_t)0; + }; + + return getDateSeconds(b1) > getDateSeconds(b2); +} + bool SavedataBrowser::SortDone() { PrioritizedWorkQueue *wq = g_gameInfoCache->WorkQueue(); return wq->Done(); @@ -454,6 +479,7 @@ void SavedataScreen::CreateViews() { ChoiceStrip *sortStrip = new ChoiceStrip(ORIENT_HORIZONTAL, new AnchorLayoutParams(NONE, 0, 0, NONE)); sortStrip->AddChoice(sa->T("Filename")); sortStrip->AddChoice(sa->T("Size")); + sortStrip->AddChoice(sa->T("Date")); sortStrip->SetSelection((int)sortOption_); sortStrip->OnChoice.Handle(this, &SavedataScreen::OnSortClick); diff --git a/UI/SavedataScreen.h b/UI/SavedataScreen.h index 0ab3e6ed56..49da370483 100644 --- a/UI/SavedataScreen.h +++ b/UI/SavedataScreen.h @@ -29,6 +29,7 @@ enum class SavedataSortOption { FILENAME, SIZE, + DATE, }; class SavedataBrowser : public UI::LinearLayout { @@ -42,6 +43,7 @@ public: private: static bool ByFilename(const UI::View *, const UI::View *); static bool BySize(const UI::View *, const UI::View *); + static bool ByDate(const UI::View *, const UI::View *); static bool SortDone(); void Refresh(); diff --git a/UI/TextureUtil.cpp b/UI/TextureUtil.cpp index 3fdd3d82a1..fed1fb1f74 100644 --- a/UI/TextureUtil.cpp +++ b/UI/TextureUtil.cpp @@ -110,6 +110,7 @@ bool ManagedTexture::LoadFromFileData(const uint8_t *data, size_t dataSize, Imag num_levels = 1; } + // Free the old texture, if any. if (texture_) { delete texture_; texture_ = nullptr; @@ -134,7 +135,7 @@ bool ManagedTexture::LoadFromFileData(const uint8_t *data, size_t dataSize, Imag if (image[i]) free(image[i]); } - return texture_ != nullptr; + return texture_; } bool ManagedTexture::LoadFromFile(const std::string &filename, ImageFileType type, bool generateMips) { @@ -200,6 +201,11 @@ std::unique_ptr CreateTextureFromFileData(Draw::DrawContext *dra if (!draw) return std::unique_ptr(); ManagedTexture *mtex = new ManagedTexture(draw); - mtex->LoadFromFileData(data, size, type, generateMips); - return std::unique_ptr(mtex); + if (mtex->LoadFromFileData(data, size, type, generateMips)) { + return std::unique_ptr(mtex); + } else { + // Best to return a null pointer if we fail! + delete mtex; + return std::unique_ptr(); + } } diff --git a/UI/UI.vcxproj b/UI/UI.vcxproj index 4d1650482b..935362f6b6 100644 --- a/UI/UI.vcxproj +++ b/UI/UI.vcxproj @@ -32,6 +32,7 @@ + @@ -64,6 +65,7 @@ + @@ -149,6 +151,7 @@ MultiThreadedDebug Common/DbgNew.h $(EXTERNAL_COMPILE_OPTIONS) + ProgramDatabase Windows @@ -173,6 +176,7 @@ false Common/DbgNew.h $(EXTERNAL_COMPILE_OPTIONS) + ProgramDatabase Windows diff --git a/UI/UI.vcxproj.filters b/UI/UI.vcxproj.filters index 0b5c2dd240..1b79119b4e 100644 --- a/UI/UI.vcxproj.filters +++ b/UI/UI.vcxproj.filters @@ -71,6 +71,9 @@ + + Screens + @@ -143,6 +146,9 @@ + + Screens + diff --git a/UWP/.gitignore b/UWP/.gitignore index 0abc1926b8..e9662c04b3 100644 --- a/UWP/.gitignore +++ b/UWP/.gitignore @@ -3,6 +3,7 @@ Package.appxmanifest Assets x64 +ARM *.VC.db *.VC.VC.opendb ipch diff --git a/UWP/App.cpp b/UWP/App.cpp index 5950a5ada2..124905478f 100644 --- a/UWP/App.cpp +++ b/UWP/App.cpp @@ -1,4 +1,4 @@ -ï»ż#include "ppsspp_config.h" +#include "ppsspp_config.h" #include "pch.h" #include "App.h" @@ -92,6 +92,7 @@ void App::SetWindow(CoreWindow^ window) { if (Windows::Foundation::Metadata::ApiInformation::IsTypePresent("Windows.Phone.UI.Input.HardwareButtons")) { m_hardwareButtons.insert(HardwareButton::BACK); + m_isPhone = true; } Windows::UI::Core::SystemNavigationManager::GetForCurrentView()-> @@ -103,11 +104,15 @@ void App::SetWindow(CoreWindow^ window) { } bool App::HasBackButton() { - return m_hardwareButtons.find(HardwareButton::BACK) != m_hardwareButtons.end(); + return m_isPhone; } void App::App_BackRequested(Platform::Object^ sender, Windows::UI::Core::BackRequestedEventArgs^ e) { - e->Handled = m_main->OnHardwareButton(HardwareButton::BACK); + if (m_isPhone) { + e->Handled = m_main->OnHardwareButton(HardwareButton::BACK); + } else { + e->Handled = true; + } } void App::OnKeyDown(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::KeyEventArgs^ args) { @@ -262,4 +267,4 @@ void App::OnOrientationChanged(DisplayInformation^ sender, Object^ args) { void App::OnDisplayContentsInvalidated(DisplayInformation^ sender, Object^ args) { m_deviceResources->ValidateDevice(); -} \ No newline at end of file +} diff --git a/UWP/App.h b/UWP/App.h index d329ac2c20..bd1fd0b331 100644 --- a/UWP/App.h +++ b/UWP/App.h @@ -1,4 +1,4 @@ -ï»ż#pragma once +#pragma once #include @@ -102,6 +102,7 @@ namespace UWP { bool m_windowClosed; bool m_windowVisible; + bool m_isPhone = false; TouchMapper touchMap_; }; } diff --git a/UWP/Armips_UWP/Armips_UWP.vcxproj b/UWP/Armips_UWP/Armips_UWP.vcxproj new file mode 100644 index 0000000000..fabf7943e9 --- /dev/null +++ b/UWP/Armips_UWP/Armips_UWP.vcxproj @@ -0,0 +1,310 @@ + + + + + Debug + ARM + + + Debug + Win32 + + + Debug + x64 + + + Release + ARM + + + Release + Win32 + + + Release + x64 + + + + {75286959-e7a2-4cbe-8b95-bf05c9c540ff} + StaticLibrary + Armips_UWP + en-US + 14.0 + true + Windows Store + 10.0.17763.0 + 10.0.15063.0 + 10.0 + + + + StaticLibrary + true + v141 + + + StaticLibrary + true + v141 + + + StaticLibrary + true + v141 + + + StaticLibrary + false + true + v141 + + + StaticLibrary + false + true + v141 + + + StaticLibrary + false + true + v141 + + + + + + + + + + + + + + + + + + + + + + + + + + + + false + $(VC_IncludePath);$(WindowsSDK_IncludePath);$(ProjectDir)..\..\ext\armips; + + + false + $(VC_IncludePath);$(WindowsSDK_IncludePath);$(ProjectDir)..\..\ext\armips; + + + false + $(VC_IncludePath);$(WindowsSDK_IncludePath);$(ProjectDir)..\..\ext\armips; + + + false + $(VC_IncludePath);$(WindowsSDK_IncludePath);$(ProjectDir)..\..\ext\armips; + + + false + $(VC_IncludePath);$(WindowsSDK_IncludePath);$(ProjectDir)..\..\ext\armips; + + + false + $(VC_IncludePath);$(WindowsSDK_IncludePath);$(ProjectDir)..\..\ext\armips; + + + + NotUsing + false + true + + + Console + false + false + + + + + NotUsing + false + true + + + Console + false + false + + + + + NotUsing + false + false + + + Console + false + false + + + + + NotUsing + false + false + + + Console + false + false + + + + + NotUsing + false + true + + + Console + false + false + + + + + NotUsing + false + true + + + Console + false + false + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Create + Create + Create + Create + Create + Create + Create + Create + + + + + + \ No newline at end of file diff --git a/UWP/Armips_UWP/Armips_UWP.vcxproj.filters b/UWP/Armips_UWP/Armips_UWP.vcxproj.filters new file mode 100644 index 0000000000..463cc812fe --- /dev/null +++ b/UWP/Armips_UWP/Armips_UWP.vcxproj.filters @@ -0,0 +1,317 @@ +ï»ż + + + + + Archs\ARM + + + Archs\ARM + + + Archs\ARM + + + Archs\ARM + + + Archs\ARM + + + Archs\ARM + + + Archs\ARM + + + Archs\ARM + + + Archs\ARM + + + Archs\MIPS + + + Archs\MIPS + + + Archs\MIPS + + + Archs\MIPS + + + Archs\MIPS + + + Archs\MIPS + + + Archs\MIPS + + + Archs\MIPS + + + Archs\MIPS + + + Archs + + + Core\ELF + + + Core\ELF + + + Core + + + Core + + + Core + + + Core + + + Core + + + Core + + + Core + + + Core + + + Commands + + + Commands + + + Commands + + + Commands + + + Commands + + + Commands + + + Commands + + + Commands + + + Parser + + + Parser + + + Parser + + + Parser + + + Util + + + Util + + + Util + + + Util + + + Util + + + + + + + + Archs\ARM + + + Archs\ARM + + + Archs\ARM + + + Archs\ARM + + + Archs\ARM + + + Archs\ARM + + + Archs\ARM + + + Archs\ARM + + + Archs\ARM + + + Archs\MIPS + + + Archs\MIPS + + + Archs\MIPS + + + Archs\MIPS + + + Archs\MIPS + + + Archs\MIPS + + + Archs\MIPS + + + Archs\MIPS + + + Archs\MIPS + + + Archs + + + Core\ELF + + + Core\ELF + + + Core\ELF + + + Core + + + Core + + + Core + + + Core + + + Core + + + Core + + + Core + + + Core + + + Commands + + + Commands + + + Commands + + + Commands + + + Commands + + + Commands + + + Commands + + + Commands + + + Parser + + + Parser + + + Parser + + + Parser + + + Util + + + Util + + + Util + + + Util + + + Util + + + + + + {bb50e347-768c-4786-84ed-552556adbe31} + + + {1b78b12e-91fd-4345-977d-a834b2aaaa0e} + + + {bef7b4a2-b049-4d00-810c-6d8d6605c2a3} + + + {2ce1016b-f93c-48b9-abe5-d3fbbcd24780} + + + {350e6968-15a4-41a0-8db6-0c0c4167ece2} + + + {1f209da4-5400-4997-bcd1-729c3e8efc7a} + + + {51922c53-0a94-4ccf-bc91-01c49e1ab80a} + + + {019ffa9d-12b6-420e-9af3-2c02795d73c8} + + + \ No newline at end of file diff --git a/UWP/Armips_UWP/pch.cpp b/UWP/Armips_UWP/pch.cpp new file mode 100644 index 0000000000..bcb5590be1 --- /dev/null +++ b/UWP/Armips_UWP/pch.cpp @@ -0,0 +1 @@ +ï»ż#include "pch.h" diff --git a/UWP/Armips_UWP/pch.h b/UWP/Armips_UWP/pch.h new file mode 100644 index 0000000000..529bbb17fe --- /dev/null +++ b/UWP/Armips_UWP/pch.h @@ -0,0 +1,9 @@ +ï»ż#pragma once + +#include "targetver.h" + +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif + +#include diff --git a/UWP/Armips_UWP/targetver.h b/UWP/Armips_UWP/targetver.h new file mode 100644 index 0000000000..a66ecb00f1 --- /dev/null +++ b/UWP/Armips_UWP/targetver.h @@ -0,0 +1,8 @@ +ï»ż#pragma once + +// Including SDKDDKVer.h defines the highest available Windows platform. + +// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and +// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. + +#include diff --git a/UWP/CommonUWP/CommonUWP.vcxproj b/UWP/CommonUWP/CommonUWP.vcxproj index ac94b54c2e..6696b15898 100644 --- a/UWP/CommonUWP/CommonUWP.vcxproj +++ b/UWP/CommonUWP/CommonUWP.vcxproj @@ -46,9 +46,9 @@ 14.0 true Windows Store - 10.0.14393.0 + 10.0.15063.0 10.0 - 10.0.16299.0 + 10.0.17763.0 diff --git a/UWP/Content/gamecontrollerdb.txt b/UWP/Content/gamecontrollerdb.txt index 9c964ede61..6f6e6363b5 100644 --- a/UWP/Content/gamecontrollerdb.txt +++ b/UWP/Content/gamecontrollerdb.txt @@ -151,3 +151,5 @@ d814000000000000cecf000000000000,MC Cthulhu,platform:Mac OS X,leftx:,lefty:,righ 03000000a30600000901000000010000,Saitek P880,a:b2,b:b3,y:b1,x:b0,leftstick:b8,rightstick:b9,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a2,lefttrigger:b6,righttrigger:b7,platform:Linux, 030000006f0e00000103000000020000,Logic3 Controller,platform:Linux,x:b2,a:b0,b:b1,y:b3,back:b6,guide:b8,start:b7,dpleft:h0.8,dpdown:h0.0,dpdown:h0.4,dpright:h0.0,dpright:h0.2,dpup:h0.0,dpup:h0.1,leftshoulder:h0.0,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,leftstick:b9,rightstick:b10,leftx:a0,lefty:a1,rightx:a3,righty:a4, 05000000380700006652000025010000,Mad Catz C.T.R.L.R ,platform:Linux,x:b0,a:b1,b:b2,y:b3,back:b8,guide:b12,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3, +03000000380700008532000010010000,MadCatz Madcatz Fightpad,platform:Linux,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b8,leftshoulder:b4,rightshoulder:b6,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,lefttrigger:b5,righttrigger:b7, +030000000d0f0000ee00000011010000,HORI CO.,LTD. HORIPAD mini4,platform:Linux,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7, diff --git a/UWP/CoreUWP/CoreUWP.vcxproj b/UWP/CoreUWP/CoreUWP.vcxproj index 7cd70cfa70..22101489c7 100644 --- a/UWP/CoreUWP/CoreUWP.vcxproj +++ b/UWP/CoreUWP/CoreUWP.vcxproj @@ -46,9 +46,9 @@ 14.0 true Windows Store - 10.0.14393.0 + 10.0.15063.0 10.0 - 10.0.16299.0 + 10.0.17763.0 @@ -310,6 +310,19 @@ + + + + + + + + + + + + + @@ -405,6 +418,7 @@ + @@ -506,6 +520,19 @@ + + + + + + + + + + + + + @@ -599,6 +626,7 @@ + diff --git a/UWP/CoreUWP/CoreUWP.vcxproj.filters b/UWP/CoreUWP/CoreUWP.vcxproj.filters index d0efa332ed..9366bca1a1 100644 --- a/UWP/CoreUWP/CoreUWP.vcxproj.filters +++ b/UWP/CoreUWP/CoreUWP.vcxproj.filters @@ -65,6 +65,9 @@ {9c6552c2-9858-41da-a920-31ea5628d417} + + {2c71417c-cc7b-42cb-880d-ac0cb45ab5bb} + @@ -621,6 +624,49 @@ HLE + + + HLE + + + Debugger + + + Debugger\WebSocket + + + Debugger\WebSocket + + + Debugger\WebSocket + + + Debugger\WebSocket + + + Debugger\WebSocket + + + Debugger\WebSocket + + + Debugger\WebSocket + + + Debugger\WebSocket + + + Debugger\WebSocket + + + Debugger\WebSocket + + + Debugger\WebSocket + + + Debugger\WebSocket + @@ -1160,5 +1206,48 @@ HLE + + + HLE + + + Debugger + + + Debugger\WebSocket + + + Debugger\WebSocket + + + Debugger\WebSocket + + + Debugger\WebSocket + + + Debugger\WebSocket + + + Debugger\WebSocket + + + Debugger\WebSocket + + + Debugger\WebSocket + + + Debugger\WebSocket + + + Debugger\WebSocket + + + Debugger\WebSocket + + + Debugger\WebSocket + \ No newline at end of file diff --git a/UWP/GPU_UWP/GPU_UWP.vcxproj b/UWP/GPU_UWP/GPU_UWP.vcxproj index f3cfa762bf..5f674f79b2 100644 --- a/UWP/GPU_UWP/GPU_UWP.vcxproj +++ b/UWP/GPU_UWP/GPU_UWP.vcxproj @@ -46,9 +46,9 @@ 14.0 true Windows Store - 10.0.14393.0 + 10.0.15063.0 10.0 - 10.0.16299.0 + 10.0.17763.0 diff --git a/UWP/GPU_UWP/GPU_UWP.vcxproj.filters b/UWP/GPU_UWP/GPU_UWP.vcxproj.filters index 6108deb70b..5f71cb0d67 100644 --- a/UWP/GPU_UWP/GPU_UWP.vcxproj.filters +++ b/UWP/GPU_UWP/GPU_UWP.vcxproj.filters @@ -1,315 +1,114 @@ ï»ż - + - - {73b2cfa4-f51e-48f5-a9fd-2c4df203a4f0} - - - {7634891c-a60e-48d4-abdb-d8fe347dfef5} - - - {508714cf-18c6-4a82-b92d-1527d9a100f0} - - - {15dc3187-4c49-46a7-8027-6ff23564cc22} - - - {b5c82a80-e146-4133-b199-a07a427f04cc} - - - - - - Common - - - Common - - - Common - - - Common - - - Common - - - Common - - - Common - - - Common - - - Common - - - Common - - - Common - - - Common - - - Common - - - Common - - - Common - - - Common - - - Common - - - Common - - - Common - - - Common - - - Common - - - Common - - - D3D11 - - - D3D11 - - - D3D11 - - - D3D11 - - - D3D11 - - - D3D11 - - - D3D11 - - - D3D11 - - - D3D11 - - - D3D11 - - - D3D11 - - - D3D11 - - - D3D9 - - - D3D9 - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - Software - - - Software - - - Software - - - Software - - - Software - - - Debugger - - - Debugger - - - Debugger - - - Common - - - Software - - - Debugger - - - Common - + + + + + + + - - - - Common - - - Common - - - Common - - - Common - - - Common - - - Common - - - Common - - - Common - - - Common - - - Common - - - Common - - - Common - - - Common - - - Common - - - Common - - - Common - - - Common - - - Common - - - Common - - - Common - - - D3D11 - - - D3D11 - - - D3D11 - - - D3D11 - - - D3D11 - - - D3D11 - - - D3D11 - - - D3D11 - - - D3D11 - - - D3D11 - - - D3D11 - - - D3D9 - - - D3D9 - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - Software - - - Software - - - Software - - - Software - - - Software - - - Debugger - - - Debugger - - - Debugger - - - Software - - - Debugger - - - Common - + + + + + + + + \ No newline at end of file diff --git a/UWP/NativeUWP/NativeUWP.vcxproj b/UWP/NativeUWP/NativeUWP.vcxproj index da5942bbfb..b9af0a361c 100644 --- a/UWP/NativeUWP/NativeUWP.vcxproj +++ b/UWP/NativeUWP/NativeUWP.vcxproj @@ -46,9 +46,9 @@ 14.0 true Windows Store - 10.0.14393.0 + 10.0.15063.0 10.0 - 10.0.16299.0 + 10.0.17763.0 @@ -170,7 +170,7 @@ true pch.h ../..;../../ext/native/ext;../..;../../ext/native;../../ext/zlib;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) - NOMINMAX;_UNICODE;UNICODE;%(PreprocessorDefinitions) + NOMINMAX;_CRT_SECURE_NO_WARNINGS;_UNICODE;UNICODE;%(PreprocessorDefinitions) Console @@ -185,7 +185,7 @@ true pch.h ../..;../../ext/native/ext;../..;../../ext/native;../../ext/zlib;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) - NOMINMAX;_UNICODE;UNICODE;%(PreprocessorDefinitions) + NOMINMAX;_CRT_SECURE_NO_WARNINGS;_UNICODE;UNICODE;%(PreprocessorDefinitions) Console @@ -200,7 +200,7 @@ true pch.h ../..;../../ext/native/ext;../..;../../ext/native;../../ext/zlib;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) - NOMINMAX;_UNICODE;UNICODE;%(PreprocessorDefinitions) + NOMINMAX;_CRT_SECURE_NO_WARNINGS;_UNICODE;UNICODE;%(PreprocessorDefinitions) Console @@ -215,7 +215,7 @@ true pch.h ../..;../../ext/native/ext;../..;../../ext/native;../../ext/zlib;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) - NOMINMAX;_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE=1;%(ClCompile.PreprocessorDefinitions) + NOMINMAX;_CRT_SECURE_NO_WARNINGS;_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE=1;%(ClCompile.PreprocessorDefinitions) Console @@ -230,7 +230,7 @@ true pch.h ../..;../../ext/native/ext;../..;../../ext/native;../../ext/zlib;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) - NOMINMAX;_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE=1;%(ClCompile.PreprocessorDefinitions) + NOMINMAX;_CRT_SECURE_NO_WARNINGS;_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE=1;%(ClCompile.PreprocessorDefinitions) Console @@ -245,7 +245,7 @@ true pch.h ../..;../../ext/native/ext;../..;../../ext/native;../../ext/zlib;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) - NOMINMAX;_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE=1;%(ClCompile.PreprocessorDefinitions) + NOMINMAX;_CRT_SECURE_NO_WARNINGS;_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE=1;%(ClCompile.PreprocessorDefinitions) Console @@ -260,7 +260,7 @@ true pch.h ../..;../../ext/native/ext;../..;../../ext/native;../../ext/zlib;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) - NOMINMAX;_UNICODE;UNICODE;%(PreprocessorDefinitions) + NOMINMAX;_CRT_SECURE_NO_WARNINGS;_UNICODE;UNICODE;%(PreprocessorDefinitions) Console @@ -275,7 +275,7 @@ true pch.h ../..;../../ext/native/ext;../..;../../ext/native;../../ext/zlib;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) - NOMINMAX;_UNICODE;UNICODE;%(PreprocessorDefinitions) + NOMINMAX;_CRT_SECURE_NO_WARNINGS;_UNICODE;UNICODE;%(PreprocessorDefinitions) Console @@ -290,7 +290,7 @@ true pch.h ../..;../../ext/native/ext;../..;../../ext/native;../../ext/zlib;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) - NOMINMAX;_UNICODE;UNICODE;%(PreprocessorDefinitions) + NOMINMAX;_CRT_SECURE_NO_WARNINGS;_UNICODE;UNICODE;%(PreprocessorDefinitions) Console @@ -312,10 +312,12 @@ + + @@ -328,6 +330,8 @@ + + @@ -366,6 +370,7 @@ + @@ -397,8 +402,10 @@ + + @@ -1160,6 +1167,8 @@ NotUsing NotUsing + + @@ -1279,6 +1288,7 @@ + diff --git a/UWP/NativeUWP/NativeUWP.vcxproj.filters b/UWP/NativeUWP/NativeUWP.vcxproj.filters index ce9603f332..2d641216cd 100644 --- a/UWP/NativeUWP/NativeUWP.vcxproj.filters +++ b/UWP/NativeUWP/NativeUWP.vcxproj.filters @@ -55,6 +55,15 @@ {4d23e7d3-0b9b-4dbe-95df-6ab250782a66} + + {fb517d8e-e6c4-4eaf-a579-9970daa96541} + + + {6c81d960-607b-4da7-b114-a6c57dff4360} + + + {b68fe6a0-b55f-4411-91f4-63ab1eaf47a3} + @@ -448,6 +457,23 @@ math + + + + ext\gason + + + ext\rg_etc1 + + + ext\sha1 + + + net + + + data + @@ -707,5 +733,22 @@ data + + + + ext\gason + + + ext\rg_etc1 + + + ext\sha1 + + + net + + + data + \ No newline at end of file diff --git a/UWP/PPSSPP_UWP.sln b/UWP/PPSSPP_UWP.sln index 1b251ca1c7..b68bce01d5 100644 --- a/UWP/PPSSPP_UWP.sln +++ b/UWP/PPSSPP_UWP.sln @@ -1,6 +1,6 @@ Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 14 -VisualStudioVersion = 14.0.25420.1 +# Visual Studio 15 +VisualStudioVersion = 15.0.28307.136 MinimumVisualStudioVersion = 10.0.40219.1 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CommonUWP", "CommonUWP\CommonUWP.vcxproj", "{ACB316CA-3ECB-48E5-BE0A-91E72D5B0F12}" EndProject @@ -22,141 +22,167 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "glslang_UWP", "glslang_UWP\ EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SPIRVCross_UWP", "SPIRVCross_UWP\SPIRVCross_UWP.vcxproj", "{2B2D16BD-1D37-46AF-A3F8-552900951B26}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Armips_UWP", "Armips_UWP\Armips_UWP.vcxproj", "{75286959-E7A2-4CBE-8B95-BF05C9C540FF}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|ARM = Debug|ARM + Debug|ARM64 = Debug|ARM64 Debug|Win32 = Debug|Win32 Debug|x64 = Debug|x64 Release|ARM = Release|ARM + Release|ARM64 = Release|ARM64 Release|Win32 = Release|Win32 Release|x64 = Release|x64 UWP Gold|ARM = UWP Gold|ARM + UWP Gold|ARM64 = UWP Gold|ARM64 UWP Gold|Win32 = UWP Gold|Win32 UWP Gold|x64 = UWP Gold|x64 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {ACB316CA-3ECB-48E5-BE0A-91E72D5B0F12}.Debug|ARM.ActiveCfg = Debug|ARM {ACB316CA-3ECB-48E5-BE0A-91E72D5B0F12}.Debug|ARM.Build.0 = Debug|ARM + {ACB316CA-3ECB-48E5-BE0A-91E72D5B0F12}.Debug|ARM64.ActiveCfg = Debug|Win32 {ACB316CA-3ECB-48E5-BE0A-91E72D5B0F12}.Debug|Win32.ActiveCfg = Debug|Win32 {ACB316CA-3ECB-48E5-BE0A-91E72D5B0F12}.Debug|Win32.Build.0 = Debug|Win32 {ACB316CA-3ECB-48E5-BE0A-91E72D5B0F12}.Debug|x64.ActiveCfg = Debug|x64 {ACB316CA-3ECB-48E5-BE0A-91E72D5B0F12}.Debug|x64.Build.0 = Debug|x64 {ACB316CA-3ECB-48E5-BE0A-91E72D5B0F12}.Release|ARM.ActiveCfg = Release|ARM {ACB316CA-3ECB-48E5-BE0A-91E72D5B0F12}.Release|ARM.Build.0 = Release|ARM + {ACB316CA-3ECB-48E5-BE0A-91E72D5B0F12}.Release|ARM64.ActiveCfg = Release|Win32 {ACB316CA-3ECB-48E5-BE0A-91E72D5B0F12}.Release|Win32.ActiveCfg = Release|Win32 {ACB316CA-3ECB-48E5-BE0A-91E72D5B0F12}.Release|Win32.Build.0 = Release|Win32 {ACB316CA-3ECB-48E5-BE0A-91E72D5B0F12}.Release|x64.ActiveCfg = Release|x64 {ACB316CA-3ECB-48E5-BE0A-91E72D5B0F12}.Release|x64.Build.0 = Release|x64 {ACB316CA-3ECB-48E5-BE0A-91E72D5B0F12}.UWP Gold|ARM.ActiveCfg = UWP Gold|ARM {ACB316CA-3ECB-48E5-BE0A-91E72D5B0F12}.UWP Gold|ARM.Build.0 = UWP Gold|ARM + {ACB316CA-3ECB-48E5-BE0A-91E72D5B0F12}.UWP Gold|ARM64.ActiveCfg = UWP Gold|Win32 {ACB316CA-3ECB-48E5-BE0A-91E72D5B0F12}.UWP Gold|Win32.ActiveCfg = UWP Gold|Win32 {ACB316CA-3ECB-48E5-BE0A-91E72D5B0F12}.UWP Gold|Win32.Build.0 = UWP Gold|Win32 {ACB316CA-3ECB-48E5-BE0A-91E72D5B0F12}.UWP Gold|x64.ActiveCfg = UWP Gold|x64 {ACB316CA-3ECB-48E5-BE0A-91E72D5B0F12}.UWP Gold|x64.Build.0 = UWP Gold|x64 {40B76674-02DE-40EF-889B-FAD1489685E7}.Debug|ARM.ActiveCfg = Debug|ARM {40B76674-02DE-40EF-889B-FAD1489685E7}.Debug|ARM.Build.0 = Debug|ARM + {40B76674-02DE-40EF-889B-FAD1489685E7}.Debug|ARM64.ActiveCfg = Debug|Win32 {40B76674-02DE-40EF-889B-FAD1489685E7}.Debug|Win32.ActiveCfg = Debug|Win32 {40B76674-02DE-40EF-889B-FAD1489685E7}.Debug|Win32.Build.0 = Debug|Win32 {40B76674-02DE-40EF-889B-FAD1489685E7}.Debug|x64.ActiveCfg = Debug|x64 {40B76674-02DE-40EF-889B-FAD1489685E7}.Debug|x64.Build.0 = Debug|x64 {40B76674-02DE-40EF-889B-FAD1489685E7}.Release|ARM.ActiveCfg = Release|ARM {40B76674-02DE-40EF-889B-FAD1489685E7}.Release|ARM.Build.0 = Release|ARM + {40B76674-02DE-40EF-889B-FAD1489685E7}.Release|ARM64.ActiveCfg = Release|Win32 {40B76674-02DE-40EF-889B-FAD1489685E7}.Release|Win32.ActiveCfg = Release|Win32 {40B76674-02DE-40EF-889B-FAD1489685E7}.Release|Win32.Build.0 = Release|Win32 {40B76674-02DE-40EF-889B-FAD1489685E7}.Release|x64.ActiveCfg = Release|x64 {40B76674-02DE-40EF-889B-FAD1489685E7}.Release|x64.Build.0 = Release|x64 {40B76674-02DE-40EF-889B-FAD1489685E7}.UWP Gold|ARM.ActiveCfg = UWP Gold|ARM {40B76674-02DE-40EF-889B-FAD1489685E7}.UWP Gold|ARM.Build.0 = UWP Gold|ARM + {40B76674-02DE-40EF-889B-FAD1489685E7}.UWP Gold|ARM64.ActiveCfg = UWP Gold|Win32 {40B76674-02DE-40EF-889B-FAD1489685E7}.UWP Gold|Win32.ActiveCfg = UWP Gold|Win32 {40B76674-02DE-40EF-889B-FAD1489685E7}.UWP Gold|Win32.Build.0 = UWP Gold|Win32 {40B76674-02DE-40EF-889B-FAD1489685E7}.UWP Gold|x64.ActiveCfg = UWP Gold|x64 {40B76674-02DE-40EF-889B-FAD1489685E7}.UWP Gold|x64.Build.0 = UWP Gold|x64 {5D271429-C288-4534-98AF-94475D940058}.Debug|ARM.ActiveCfg = Debug|ARM {5D271429-C288-4534-98AF-94475D940058}.Debug|ARM.Build.0 = Debug|ARM + {5D271429-C288-4534-98AF-94475D940058}.Debug|ARM64.ActiveCfg = Debug|Win32 {5D271429-C288-4534-98AF-94475D940058}.Debug|Win32.ActiveCfg = Debug|Win32 {5D271429-C288-4534-98AF-94475D940058}.Debug|Win32.Build.0 = Debug|Win32 {5D271429-C288-4534-98AF-94475D940058}.Debug|x64.ActiveCfg = Debug|x64 {5D271429-C288-4534-98AF-94475D940058}.Debug|x64.Build.0 = Debug|x64 {5D271429-C288-4534-98AF-94475D940058}.Release|ARM.ActiveCfg = Release|ARM {5D271429-C288-4534-98AF-94475D940058}.Release|ARM.Build.0 = Release|ARM + {5D271429-C288-4534-98AF-94475D940058}.Release|ARM64.ActiveCfg = Release|Win32 {5D271429-C288-4534-98AF-94475D940058}.Release|Win32.ActiveCfg = Release|Win32 {5D271429-C288-4534-98AF-94475D940058}.Release|Win32.Build.0 = Release|Win32 {5D271429-C288-4534-98AF-94475D940058}.Release|x64.ActiveCfg = Release|x64 {5D271429-C288-4534-98AF-94475D940058}.Release|x64.Build.0 = Release|x64 {5D271429-C288-4534-98AF-94475D940058}.UWP Gold|ARM.ActiveCfg = UWP Gold|ARM {5D271429-C288-4534-98AF-94475D940058}.UWP Gold|ARM.Build.0 = UWP Gold|ARM + {5D271429-C288-4534-98AF-94475D940058}.UWP Gold|ARM64.ActiveCfg = UWP Gold|Win32 {5D271429-C288-4534-98AF-94475D940058}.UWP Gold|Win32.ActiveCfg = UWP Gold|Win32 {5D271429-C288-4534-98AF-94475D940058}.UWP Gold|Win32.Build.0 = UWP Gold|Win32 {5D271429-C288-4534-98AF-94475D940058}.UWP Gold|x64.ActiveCfg = UWP Gold|x64 {5D271429-C288-4534-98AF-94475D940058}.UWP Gold|x64.Build.0 = UWP Gold|x64 {935028AF-B850-4AD7-A00E-7BA84FB97D05}.Debug|ARM.ActiveCfg = Debug|ARM {935028AF-B850-4AD7-A00E-7BA84FB97D05}.Debug|ARM.Build.0 = Debug|ARM + {935028AF-B850-4AD7-A00E-7BA84FB97D05}.Debug|ARM64.ActiveCfg = Debug|Win32 {935028AF-B850-4AD7-A00E-7BA84FB97D05}.Debug|Win32.ActiveCfg = Debug|Win32 {935028AF-B850-4AD7-A00E-7BA84FB97D05}.Debug|Win32.Build.0 = Debug|Win32 {935028AF-B850-4AD7-A00E-7BA84FB97D05}.Debug|x64.ActiveCfg = Debug|x64 {935028AF-B850-4AD7-A00E-7BA84FB97D05}.Debug|x64.Build.0 = Debug|x64 {935028AF-B850-4AD7-A00E-7BA84FB97D05}.Release|ARM.ActiveCfg = Release|ARM {935028AF-B850-4AD7-A00E-7BA84FB97D05}.Release|ARM.Build.0 = Release|ARM + {935028AF-B850-4AD7-A00E-7BA84FB97D05}.Release|ARM64.ActiveCfg = Release|Win32 {935028AF-B850-4AD7-A00E-7BA84FB97D05}.Release|Win32.ActiveCfg = Release|Win32 {935028AF-B850-4AD7-A00E-7BA84FB97D05}.Release|Win32.Build.0 = Release|Win32 {935028AF-B850-4AD7-A00E-7BA84FB97D05}.Release|x64.ActiveCfg = Release|x64 {935028AF-B850-4AD7-A00E-7BA84FB97D05}.Release|x64.Build.0 = Release|x64 {935028AF-B850-4AD7-A00E-7BA84FB97D05}.UWP Gold|ARM.ActiveCfg = UWP Gold|ARM {935028AF-B850-4AD7-A00E-7BA84FB97D05}.UWP Gold|ARM.Build.0 = UWP Gold|ARM + {935028AF-B850-4AD7-A00E-7BA84FB97D05}.UWP Gold|ARM64.ActiveCfg = UWP Gold|Win32 {935028AF-B850-4AD7-A00E-7BA84FB97D05}.UWP Gold|Win32.ActiveCfg = UWP Gold|Win32 {935028AF-B850-4AD7-A00E-7BA84FB97D05}.UWP Gold|Win32.Build.0 = UWP Gold|Win32 {935028AF-B850-4AD7-A00E-7BA84FB97D05}.UWP Gold|x64.ActiveCfg = UWP Gold|x64 {935028AF-B850-4AD7-A00E-7BA84FB97D05}.UWP Gold|x64.Build.0 = UWP Gold|x64 {5FAC15BD-7397-4512-99D5-66CDC03AF5B7}.Debug|ARM.ActiveCfg = Debug|ARM {5FAC15BD-7397-4512-99D5-66CDC03AF5B7}.Debug|ARM.Build.0 = Debug|ARM + {5FAC15BD-7397-4512-99D5-66CDC03AF5B7}.Debug|ARM64.ActiveCfg = Debug|Win32 {5FAC15BD-7397-4512-99D5-66CDC03AF5B7}.Debug|Win32.ActiveCfg = Debug|Win32 {5FAC15BD-7397-4512-99D5-66CDC03AF5B7}.Debug|Win32.Build.0 = Debug|Win32 {5FAC15BD-7397-4512-99D5-66CDC03AF5B7}.Debug|x64.ActiveCfg = Debug|x64 {5FAC15BD-7397-4512-99D5-66CDC03AF5B7}.Debug|x64.Build.0 = Debug|x64 {5FAC15BD-7397-4512-99D5-66CDC03AF5B7}.Release|ARM.ActiveCfg = Release|ARM {5FAC15BD-7397-4512-99D5-66CDC03AF5B7}.Release|ARM.Build.0 = Release|ARM + {5FAC15BD-7397-4512-99D5-66CDC03AF5B7}.Release|ARM64.ActiveCfg = Release|Win32 {5FAC15BD-7397-4512-99D5-66CDC03AF5B7}.Release|Win32.ActiveCfg = Release|Win32 {5FAC15BD-7397-4512-99D5-66CDC03AF5B7}.Release|Win32.Build.0 = Release|Win32 {5FAC15BD-7397-4512-99D5-66CDC03AF5B7}.Release|x64.ActiveCfg = Release|x64 {5FAC15BD-7397-4512-99D5-66CDC03AF5B7}.Release|x64.Build.0 = Release|x64 {5FAC15BD-7397-4512-99D5-66CDC03AF5B7}.UWP Gold|ARM.ActiveCfg = UWP Gold|ARM {5FAC15BD-7397-4512-99D5-66CDC03AF5B7}.UWP Gold|ARM.Build.0 = UWP Gold|ARM + {5FAC15BD-7397-4512-99D5-66CDC03AF5B7}.UWP Gold|ARM64.ActiveCfg = UWP Gold|Win32 {5FAC15BD-7397-4512-99D5-66CDC03AF5B7}.UWP Gold|Win32.ActiveCfg = UWP Gold|Win32 {5FAC15BD-7397-4512-99D5-66CDC03AF5B7}.UWP Gold|Win32.Build.0 = UWP Gold|Win32 {5FAC15BD-7397-4512-99D5-66CDC03AF5B7}.UWP Gold|x64.ActiveCfg = UWP Gold|x64 {5FAC15BD-7397-4512-99D5-66CDC03AF5B7}.UWP Gold|x64.Build.0 = UWP Gold|x64 {2F911C05-B341-4291-8BF5-09EDECBDD5F5}.Debug|ARM.ActiveCfg = Debug|ARM {2F911C05-B341-4291-8BF5-09EDECBDD5F5}.Debug|ARM.Build.0 = Debug|ARM + {2F911C05-B341-4291-8BF5-09EDECBDD5F5}.Debug|ARM64.ActiveCfg = Debug|Win32 {2F911C05-B341-4291-8BF5-09EDECBDD5F5}.Debug|Win32.ActiveCfg = Debug|Win32 {2F911C05-B341-4291-8BF5-09EDECBDD5F5}.Debug|Win32.Build.0 = Debug|Win32 {2F911C05-B341-4291-8BF5-09EDECBDD5F5}.Debug|x64.ActiveCfg = Debug|x64 {2F911C05-B341-4291-8BF5-09EDECBDD5F5}.Debug|x64.Build.0 = Debug|x64 {2F911C05-B341-4291-8BF5-09EDECBDD5F5}.Release|ARM.ActiveCfg = Release|ARM {2F911C05-B341-4291-8BF5-09EDECBDD5F5}.Release|ARM.Build.0 = Release|ARM + {2F911C05-B341-4291-8BF5-09EDECBDD5F5}.Release|ARM64.ActiveCfg = Release|Win32 {2F911C05-B341-4291-8BF5-09EDECBDD5F5}.Release|Win32.ActiveCfg = Release|Win32 {2F911C05-B341-4291-8BF5-09EDECBDD5F5}.Release|Win32.Build.0 = Release|Win32 {2F911C05-B341-4291-8BF5-09EDECBDD5F5}.Release|x64.ActiveCfg = Release|x64 {2F911C05-B341-4291-8BF5-09EDECBDD5F5}.Release|x64.Build.0 = Release|x64 {2F911C05-B341-4291-8BF5-09EDECBDD5F5}.UWP Gold|ARM.ActiveCfg = UWP Gold|ARM {2F911C05-B341-4291-8BF5-09EDECBDD5F5}.UWP Gold|ARM.Build.0 = UWP Gold|ARM + {2F911C05-B341-4291-8BF5-09EDECBDD5F5}.UWP Gold|ARM64.ActiveCfg = UWP Gold|Win32 {2F911C05-B341-4291-8BF5-09EDECBDD5F5}.UWP Gold|Win32.ActiveCfg = UWP Gold|Win32 {2F911C05-B341-4291-8BF5-09EDECBDD5F5}.UWP Gold|Win32.Build.0 = UWP Gold|Win32 {2F911C05-B341-4291-8BF5-09EDECBDD5F5}.UWP Gold|x64.ActiveCfg = UWP Gold|x64 {2F911C05-B341-4291-8BF5-09EDECBDD5F5}.UWP Gold|x64.Build.0 = UWP Gold|x64 {DDF90203-0AAE-4F38-B589-2E9637658CE6}.Debug|ARM.ActiveCfg = Debug|ARM {DDF90203-0AAE-4F38-B589-2E9637658CE6}.Debug|ARM.Build.0 = Debug|ARM + {DDF90203-0AAE-4F38-B589-2E9637658CE6}.Debug|ARM64.ActiveCfg = Debug|Win32 {DDF90203-0AAE-4F38-B589-2E9637658CE6}.Debug|Win32.ActiveCfg = Debug|Win32 {DDF90203-0AAE-4F38-B589-2E9637658CE6}.Debug|Win32.Build.0 = Debug|Win32 {DDF90203-0AAE-4F38-B589-2E9637658CE6}.Debug|x64.ActiveCfg = Debug|x64 {DDF90203-0AAE-4F38-B589-2E9637658CE6}.Debug|x64.Build.0 = Debug|x64 {DDF90203-0AAE-4F38-B589-2E9637658CE6}.Release|ARM.ActiveCfg = Release|ARM {DDF90203-0AAE-4F38-B589-2E9637658CE6}.Release|ARM.Build.0 = Release|ARM + {DDF90203-0AAE-4F38-B589-2E9637658CE6}.Release|ARM64.ActiveCfg = Release|Win32 {DDF90203-0AAE-4F38-B589-2E9637658CE6}.Release|Win32.ActiveCfg = Release|Win32 {DDF90203-0AAE-4F38-B589-2E9637658CE6}.Release|Win32.Build.0 = Release|Win32 {DDF90203-0AAE-4F38-B589-2E9637658CE6}.Release|x64.ActiveCfg = Release|x64 {DDF90203-0AAE-4F38-B589-2E9637658CE6}.Release|x64.Build.0 = Release|x64 {DDF90203-0AAE-4F38-B589-2E9637658CE6}.UWP Gold|ARM.ActiveCfg = UWP Gold|ARM {DDF90203-0AAE-4F38-B589-2E9637658CE6}.UWP Gold|ARM.Build.0 = UWP Gold|ARM + {DDF90203-0AAE-4F38-B589-2E9637658CE6}.UWP Gold|ARM64.ActiveCfg = UWP Gold|Win32 {DDF90203-0AAE-4F38-B589-2E9637658CE6}.UWP Gold|Win32.ActiveCfg = UWP Gold|Win32 {DDF90203-0AAE-4F38-B589-2E9637658CE6}.UWP Gold|Win32.Build.0 = UWP Gold|Win32 {DDF90203-0AAE-4F38-B589-2E9637658CE6}.UWP Gold|x64.ActiveCfg = UWP Gold|x64 @@ -164,6 +190,7 @@ Global {01D7D581-09A3-4A26-94BD-A7C529B29329}.Debug|ARM.ActiveCfg = Debug|ARM {01D7D581-09A3-4A26-94BD-A7C529B29329}.Debug|ARM.Build.0 = Debug|ARM {01D7D581-09A3-4A26-94BD-A7C529B29329}.Debug|ARM.Deploy.0 = Debug|ARM + {01D7D581-09A3-4A26-94BD-A7C529B29329}.Debug|ARM64.ActiveCfg = Debug|Win32 {01D7D581-09A3-4A26-94BD-A7C529B29329}.Debug|Win32.ActiveCfg = Debug|Win32 {01D7D581-09A3-4A26-94BD-A7C529B29329}.Debug|Win32.Build.0 = Debug|Win32 {01D7D581-09A3-4A26-94BD-A7C529B29329}.Debug|Win32.Deploy.0 = Debug|Win32 @@ -173,6 +200,7 @@ Global {01D7D581-09A3-4A26-94BD-A7C529B29329}.Release|ARM.ActiveCfg = Release|ARM {01D7D581-09A3-4A26-94BD-A7C529B29329}.Release|ARM.Build.0 = Release|ARM {01D7D581-09A3-4A26-94BD-A7C529B29329}.Release|ARM.Deploy.0 = Release|ARM + {01D7D581-09A3-4A26-94BD-A7C529B29329}.Release|ARM64.ActiveCfg = Release|Win32 {01D7D581-09A3-4A26-94BD-A7C529B29329}.Release|Win32.ActiveCfg = Release|Win32 {01D7D581-09A3-4A26-94BD-A7C529B29329}.Release|Win32.Build.0 = Release|Win32 {01D7D581-09A3-4A26-94BD-A7C529B29329}.Release|Win32.Deploy.0 = Release|Win32 @@ -182,6 +210,7 @@ Global {01D7D581-09A3-4A26-94BD-A7C529B29329}.UWP Gold|ARM.ActiveCfg = UWP Gold|ARM {01D7D581-09A3-4A26-94BD-A7C529B29329}.UWP Gold|ARM.Build.0 = UWP Gold|ARM {01D7D581-09A3-4A26-94BD-A7C529B29329}.UWP Gold|ARM.Deploy.0 = UWP Gold|ARM + {01D7D581-09A3-4A26-94BD-A7C529B29329}.UWP Gold|ARM64.ActiveCfg = UWP Gold|Win32 {01D7D581-09A3-4A26-94BD-A7C529B29329}.UWP Gold|Win32.ActiveCfg = UWP Gold|Win32 {01D7D581-09A3-4A26-94BD-A7C529B29329}.UWP Gold|Win32.Build.0 = UWP Gold|Win32 {01D7D581-09A3-4A26-94BD-A7C529B29329}.UWP Gold|Win32.Deploy.0 = UWP Gold|Win32 @@ -190,42 +219,73 @@ Global {01D7D581-09A3-4A26-94BD-A7C529B29329}.UWP Gold|x64.Deploy.0 = UWP Gold|x64 {D326891E-ECE4-4B94-B5E7-8AA0A8E8ECBC}.Debug|ARM.ActiveCfg = Debug|ARM {D326891E-ECE4-4B94-B5E7-8AA0A8E8ECBC}.Debug|ARM.Build.0 = Debug|ARM + {D326891E-ECE4-4B94-B5E7-8AA0A8E8ECBC}.Debug|ARM64.ActiveCfg = Debug|Win32 {D326891E-ECE4-4B94-B5E7-8AA0A8E8ECBC}.Debug|Win32.ActiveCfg = Debug|Win32 {D326891E-ECE4-4B94-B5E7-8AA0A8E8ECBC}.Debug|Win32.Build.0 = Debug|Win32 {D326891E-ECE4-4B94-B5E7-8AA0A8E8ECBC}.Debug|x64.ActiveCfg = Debug|x64 {D326891E-ECE4-4B94-B5E7-8AA0A8E8ECBC}.Debug|x64.Build.0 = Debug|x64 {D326891E-ECE4-4B94-B5E7-8AA0A8E8ECBC}.Release|ARM.ActiveCfg = Release|ARM {D326891E-ECE4-4B94-B5E7-8AA0A8E8ECBC}.Release|ARM.Build.0 = Release|ARM + {D326891E-ECE4-4B94-B5E7-8AA0A8E8ECBC}.Release|ARM64.ActiveCfg = Release|Win32 {D326891E-ECE4-4B94-B5E7-8AA0A8E8ECBC}.Release|Win32.ActiveCfg = Release|Win32 {D326891E-ECE4-4B94-B5E7-8AA0A8E8ECBC}.Release|Win32.Build.0 = Release|Win32 {D326891E-ECE4-4B94-B5E7-8AA0A8E8ECBC}.Release|x64.ActiveCfg = Release|x64 {D326891E-ECE4-4B94-B5E7-8AA0A8E8ECBC}.Release|x64.Build.0 = Release|x64 {D326891E-ECE4-4B94-B5E7-8AA0A8E8ECBC}.UWP Gold|ARM.ActiveCfg = UWP Gold|ARM {D326891E-ECE4-4B94-B5E7-8AA0A8E8ECBC}.UWP Gold|ARM.Build.0 = UWP Gold|ARM + {D326891E-ECE4-4B94-B5E7-8AA0A8E8ECBC}.UWP Gold|ARM64.ActiveCfg = UWP Gold|Win32 {D326891E-ECE4-4B94-B5E7-8AA0A8E8ECBC}.UWP Gold|Win32.ActiveCfg = UWP Gold|Win32 {D326891E-ECE4-4B94-B5E7-8AA0A8E8ECBC}.UWP Gold|Win32.Build.0 = UWP Gold|Win32 {D326891E-ECE4-4B94-B5E7-8AA0A8E8ECBC}.UWP Gold|x64.ActiveCfg = UWP Gold|x64 {D326891E-ECE4-4B94-B5E7-8AA0A8E8ECBC}.UWP Gold|x64.Build.0 = UWP Gold|x64 {2B2D16BD-1D37-46AF-A3F8-552900951B26}.Debug|ARM.ActiveCfg = Debug|ARM {2B2D16BD-1D37-46AF-A3F8-552900951B26}.Debug|ARM.Build.0 = Debug|ARM + {2B2D16BD-1D37-46AF-A3F8-552900951B26}.Debug|ARM64.ActiveCfg = Debug|Win32 {2B2D16BD-1D37-46AF-A3F8-552900951B26}.Debug|Win32.ActiveCfg = Debug|Win32 {2B2D16BD-1D37-46AF-A3F8-552900951B26}.Debug|Win32.Build.0 = Debug|Win32 {2B2D16BD-1D37-46AF-A3F8-552900951B26}.Debug|x64.ActiveCfg = Debug|x64 {2B2D16BD-1D37-46AF-A3F8-552900951B26}.Debug|x64.Build.0 = Debug|x64 {2B2D16BD-1D37-46AF-A3F8-552900951B26}.Release|ARM.ActiveCfg = Release|ARM {2B2D16BD-1D37-46AF-A3F8-552900951B26}.Release|ARM.Build.0 = Release|ARM + {2B2D16BD-1D37-46AF-A3F8-552900951B26}.Release|ARM64.ActiveCfg = Release|Win32 {2B2D16BD-1D37-46AF-A3F8-552900951B26}.Release|Win32.ActiveCfg = Release|Win32 {2B2D16BD-1D37-46AF-A3F8-552900951B26}.Release|Win32.Build.0 = Release|Win32 {2B2D16BD-1D37-46AF-A3F8-552900951B26}.Release|x64.ActiveCfg = Release|x64 {2B2D16BD-1D37-46AF-A3F8-552900951B26}.Release|x64.Build.0 = Release|x64 {2B2D16BD-1D37-46AF-A3F8-552900951B26}.UWP Gold|ARM.ActiveCfg = UWP Gold|ARM {2B2D16BD-1D37-46AF-A3F8-552900951B26}.UWP Gold|ARM.Build.0 = UWP Gold|ARM + {2B2D16BD-1D37-46AF-A3F8-552900951B26}.UWP Gold|ARM64.ActiveCfg = UWP Gold|Win32 {2B2D16BD-1D37-46AF-A3F8-552900951B26}.UWP Gold|Win32.ActiveCfg = UWP Gold|Win32 {2B2D16BD-1D37-46AF-A3F8-552900951B26}.UWP Gold|Win32.Build.0 = UWP Gold|Win32 {2B2D16BD-1D37-46AF-A3F8-552900951B26}.UWP Gold|x64.ActiveCfg = UWP Gold|x64 {2B2D16BD-1D37-46AF-A3F8-552900951B26}.UWP Gold|x64.Build.0 = UWP Gold|x64 + {75286959-E7A2-4CBE-8B95-BF05C9C540FF}.Debug|ARM.ActiveCfg = Debug|ARM + {75286959-E7A2-4CBE-8B95-BF05C9C540FF}.Debug|ARM.Build.0 = Debug|ARM + {75286959-E7A2-4CBE-8B95-BF05C9C540FF}.Debug|ARM64.ActiveCfg = Debug|Win32 + {75286959-E7A2-4CBE-8B95-BF05C9C540FF}.Debug|Win32.ActiveCfg = Debug|Win32 + {75286959-E7A2-4CBE-8B95-BF05C9C540FF}.Debug|Win32.Build.0 = Debug|Win32 + {75286959-E7A2-4CBE-8B95-BF05C9C540FF}.Debug|x64.ActiveCfg = Debug|x64 + {75286959-E7A2-4CBE-8B95-BF05C9C540FF}.Debug|x64.Build.0 = Debug|x64 + {75286959-E7A2-4CBE-8B95-BF05C9C540FF}.Release|ARM.ActiveCfg = Release|ARM + {75286959-E7A2-4CBE-8B95-BF05C9C540FF}.Release|ARM.Build.0 = Release|ARM + {75286959-E7A2-4CBE-8B95-BF05C9C540FF}.Release|ARM64.ActiveCfg = Release|Win32 + {75286959-E7A2-4CBE-8B95-BF05C9C540FF}.Release|Win32.ActiveCfg = Release|Win32 + {75286959-E7A2-4CBE-8B95-BF05C9C540FF}.Release|Win32.Build.0 = Release|Win32 + {75286959-E7A2-4CBE-8B95-BF05C9C540FF}.Release|x64.ActiveCfg = Release|x64 + {75286959-E7A2-4CBE-8B95-BF05C9C540FF}.Release|x64.Build.0 = Release|x64 + {75286959-E7A2-4CBE-8B95-BF05C9C540FF}.UWP Gold|ARM.ActiveCfg = Release|ARM + {75286959-E7A2-4CBE-8B95-BF05C9C540FF}.UWP Gold|ARM.Build.0 = Release|ARM + {75286959-E7A2-4CBE-8B95-BF05C9C540FF}.UWP Gold|ARM64.ActiveCfg = Release|x64 + {75286959-E7A2-4CBE-8B95-BF05C9C540FF}.UWP Gold|ARM64.Build.0 = Release|x64 + {75286959-E7A2-4CBE-8B95-BF05C9C540FF}.UWP Gold|Win32.ActiveCfg = Release|Win32 + {75286959-E7A2-4CBE-8B95-BF05C9C540FF}.UWP Gold|Win32.Build.0 = Release|Win32 + {75286959-E7A2-4CBE-8B95-BF05C9C540FF}.UWP Gold|x64.ActiveCfg = Release|x64 + {75286959-E7A2-4CBE-8B95-BF05C9C540FF}.UWP Gold|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {2C8B6968-85F7-4F06-9D3D-7CD2309F5B0E} + EndGlobalSection EndGlobal diff --git a/UWP/PPSSPP_UWPMain.cpp b/UWP/PPSSPP_UWPMain.cpp index 994871cff1..b7271d5288 100644 --- a/UWP/PPSSPP_UWPMain.cpp +++ b/UWP/PPSSPP_UWPMain.cpp @@ -120,7 +120,7 @@ PPSSPP_UWPMain::PPSSPP_UWPMain(App ^app, const std::shared_ptrLocalFolder->Path->Data()); - NativeInit(1, argv, "", "", cacheFolder.c_str(), false); + NativeInit(1, argv, "", "", cacheFolder.c_str()); NativeInitGraphics(ctx_.get()); NativeResized(); @@ -322,8 +322,10 @@ void PPSSPP_UWPMain::LoadStorageFile(StorageFile ^file) { } UWPGraphicsContext::UWPGraphicsContext(std::shared_ptr resources) { + std::vector adapterNames; + draw_ = Draw::T3DCreateD3D11Context( - resources->GetD3DDevice(), resources->GetD3DDeviceContext(), resources->GetD3DDevice(), resources->GetD3DDeviceContext(), resources->GetDeviceFeatureLevel(), 0); + resources->GetD3DDevice(), resources->GetD3DDeviceContext(), resources->GetD3DDevice(), resources->GetD3DDeviceContext(), resources->GetDeviceFeatureLevel(), 0, adapterNames); bool success = draw_->CreatePresets(); assert(success); } diff --git a/UWP/SPIRVCross_UWP/SPIRVCross_UWP.vcxproj b/UWP/SPIRVCross_UWP/SPIRVCross_UWP.vcxproj index fe4a09e6a7..4c4c18f190 100644 --- a/UWP/SPIRVCross_UWP/SPIRVCross_UWP.vcxproj +++ b/UWP/SPIRVCross_UWP/SPIRVCross_UWP.vcxproj @@ -46,9 +46,9 @@ 14.0 true Windows Store - 10.0.14393.0 + 10.0.15063.0 10.0 - 10.0.16299.0 + 10.0.17763.0 @@ -169,6 +169,7 @@ false true pch.h + _UNICODE;UNICODE;%(PreprocessorDefinitions);NOMINMAX Console @@ -182,6 +183,7 @@ false true pch.h + _UNICODE;UNICODE;%(PreprocessorDefinitions);NOMINMAX Console @@ -195,6 +197,7 @@ false true pch.h + _UNICODE;UNICODE;%(PreprocessorDefinitions);NOMINMAX Console @@ -208,6 +211,7 @@ false true pch.h + _ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE=1;%(ClCompile.PreprocessorDefinitions);NOMINMAX Console @@ -221,6 +225,7 @@ false true pch.h + _ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE=1;%(ClCompile.PreprocessorDefinitions);NOMINMAX Console @@ -234,6 +239,7 @@ false true pch.h + _ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE=1;%(ClCompile.PreprocessorDefinitions);NOMINMAX Console @@ -247,6 +253,7 @@ false true pch.h + _UNICODE;UNICODE;%(PreprocessorDefinitions);NOMINMAX Console @@ -260,6 +267,7 @@ false true pch.h + _UNICODE;UNICODE;%(PreprocessorDefinitions);NOMINMAX Console @@ -273,6 +281,7 @@ false true pch.h + _UNICODE;UNICODE;%(PreprocessorDefinitions);NOMINMAX Console @@ -314,4 +323,4 @@ - + \ No newline at end of file diff --git a/UWP/SPIRVCross_UWP/SPIRVCross_UWP.vcxproj.filters b/UWP/SPIRVCross_UWP/SPIRVCross_UWP.vcxproj.filters index cedc522ec9..ae84b6bb46 100644 --- a/UWP/SPIRVCross_UWP/SPIRVCross_UWP.vcxproj.filters +++ b/UWP/SPIRVCross_UWP/SPIRVCross_UWP.vcxproj.filters @@ -13,6 +13,7 @@ + @@ -24,5 +25,6 @@ + \ No newline at end of file diff --git a/UWP/UI_UWP/UI_UWP.vcxproj b/UWP/UI_UWP/UI_UWP.vcxproj index 3b54be0228..a71aff31d9 100644 --- a/UWP/UI_UWP/UI_UWP.vcxproj +++ b/UWP/UI_UWP/UI_UWP.vcxproj @@ -46,9 +46,9 @@ 14.0 true Windows Store - 10.0.14393.0 + 10.0.15063.0 10.0 - 10.0.16299.0 + 10.0.17763.0 @@ -312,6 +312,7 @@ + @@ -346,6 +347,7 @@ + diff --git a/UWP/UI_UWP/UI_UWP.vcxproj.filters b/UWP/UI_UWP/UI_UWP.vcxproj.filters index b3ee44e3c8..89c1fdc6d8 100644 --- a/UWP/UI_UWP/UI_UWP.vcxproj.filters +++ b/UWP/UI_UWP/UI_UWP.vcxproj.filters @@ -15,6 +15,7 @@ + @@ -49,6 +50,7 @@ + diff --git a/UWP/UWP.vcxproj b/UWP/UWP.vcxproj index 5d791cfa75..d785bf6c56 100644 --- a/UWP/UWP.vcxproj +++ b/UWP/UWP.vcxproj @@ -46,10 +46,10 @@ 14.0 true Windows Store - 10.0.14393.0 + 10.0.15063.0 10.0 PPSSPP_UWP - 10.0.16299.0 + 10.0.17763.0 @@ -156,7 +156,7 @@ PPSSPP_UWP_TemporaryKey.pfx True False - Never + Never B57919568D3F60B8D25EC6856DE94173682C548C @@ -464,6 +464,9 @@ copy AssetsGold\*.* Assets /Y + + {75286959-e7a2-4cbe-8b95-bf05c9c540ff} + {acb316ca-3ecb-48e5-be0a-91e72d5b0f12} @@ -506,4 +509,4 @@ copy AssetsGold\*.* Assets /Y - + \ No newline at end of file diff --git a/UWP/UWPHost.cpp b/UWP/UWPHost.cpp index 72dd263857..8bbe1cb4a6 100644 --- a/UWP/UWPHost.cpp +++ b/UWP/UWPHost.cpp @@ -31,7 +31,6 @@ #include "UI/OnScreenDisplay.h" #include "Windows/XinputDevice.h" -#include "Windows/DSoundStream.h" #include "UWP/XAudioSoundStream.h" #include "UWP/UWPHost.h" diff --git a/UWP/XAudioSoundStream.h b/UWP/XAudioSoundStream.h index 35b26f0abf..be53b7d8d4 100644 --- a/UWP/XAudioSoundStream.h +++ b/UWP/XAudioSoundStream.h @@ -2,7 +2,8 @@ #include "Common/CommonWindows.h" #include "Core/Config.h" -#include "Windows/DSoundStream.h" + +#include "Windows/WindowsAudio.h" // Factory WindowsAudioBackend *CreateAudioBackend(AudioBackendType type); diff --git a/UWP/glslang_UWP/glslang_UWP.vcxproj b/UWP/glslang_UWP/glslang_UWP.vcxproj index 591ece0c89..13eadac609 100644 --- a/UWP/glslang_UWP/glslang_UWP.vcxproj +++ b/UWP/glslang_UWP/glslang_UWP.vcxproj @@ -46,9 +46,9 @@ 14.0 true Windows Store - 10.0.14393.0 + 10.0.15063.0 10.0 - 10.0.16299.0 + 10.0.17763.0 @@ -302,6 +302,7 @@ + @@ -347,6 +348,7 @@ + @@ -388,6 +390,7 @@ + Create Create @@ -403,4 +406,4 @@ - \ No newline at end of file + diff --git a/UWP/glslang_UWP/glslang_UWP.vcxproj.filters b/UWP/glslang_UWP/glslang_UWP.vcxproj.filters index 26316f364e..9d3fc6da3c 100644 --- a/UWP/glslang_UWP/glslang_UWP.vcxproj.filters +++ b/UWP/glslang_UWP/glslang_UWP.vcxproj.filters @@ -160,6 +160,9 @@ OGLCompilersDLL + + glslang\MachineIndependent + @@ -317,5 +320,8 @@ OGLCompilersDLL + + glslang\MachineIndependent + \ No newline at end of file diff --git a/UWP/libkirk_UWP/libkirk_UWP.vcxproj b/UWP/libkirk_UWP/libkirk_UWP.vcxproj index d993e1145e..579034284b 100644 --- a/UWP/libkirk_UWP/libkirk_UWP.vcxproj +++ b/UWP/libkirk_UWP/libkirk_UWP.vcxproj @@ -46,9 +46,9 @@ 14.0 true Windows Store - 10.0.14393.0 + 10.0.15063.0 10.0 - 10.0.16299.0 + 10.0.17763.0 diff --git a/UWP/zlib_UWP/zlib_UWP.vcxproj b/UWP/zlib_UWP/zlib_UWP.vcxproj index 347bd1ea74..48995ec5a3 100644 --- a/UWP/zlib_UWP/zlib_UWP.vcxproj +++ b/UWP/zlib_UWP/zlib_UWP.vcxproj @@ -46,9 +46,9 @@ 14.0 true Windows Store - 10.0.14393.0 + 10.0.15063.0 10.0 - 10.0.16299.0 + 10.0.17763.0 diff --git a/Windows/GEDebugger/GEDebugger.cpp b/Windows/GEDebugger/GEDebugger.cpp index f5d898eae5..207cdefdf4 100644 --- a/Windows/GEDebugger/GEDebugger.cpp +++ b/Windows/GEDebugger/GEDebugger.cpp @@ -20,6 +20,7 @@ #include #include +#include "base/stringutil.h" #include "Common/ColorConv.h" #include "Core/Config.h" #include "Core/Screenshot.h" @@ -56,13 +57,76 @@ enum PrimaryDisplayType { PRIMARY_STENCILBUF, }; +StepCountDlg::StepCountDlg(HINSTANCE _hInstance, HWND _hParent) : Dialog((LPCSTR)IDD_GEDBG_STEPCOUNT, _hInstance, _hParent) { + DialogManager::AddDlg(this); + + for (int i = 0; i < 4; i++) // Add items 1, 10, 100, 1000 + SendMessageA(GetDlgItem(m_hDlg, IDC_GEDBG_STEPCOUNT_COMBO), CB_ADDSTRING, 0, (LPARAM)std::to_string((int)pow(10, i)).c_str()); + SetWindowTextA(GetDlgItem(m_hDlg, IDC_GEDBG_STEPCOUNT_COMBO), "1"); +} + +StepCountDlg::~StepCountDlg() { + DialogManager::RemoveDlg(this); +} + +void StepCountDlg::Jump(int count, bool relative) { + if (relative && count == 0) + return; + SetBreakNext(BreakNext::COUNT); + SetBreakCount(count, relative); +}; + +BOOL StepCountDlg::DlgProc(UINT message, WPARAM wParam, LPARAM lParam) { + int count; + bool relative; + auto GetValue = [&]() { + char str[7]; // +/-99999\0 + GetWindowTextA(GetDlgItem(m_hDlg, IDC_GEDBG_STEPCOUNT_COMBO), str, 7); + relative = str[0] == '+' || str[0] == '-'; + return TryParse(str, &count); + }; + + switch (message) { + case WM_CLOSE: + Show(false); + return TRUE; + case WM_COMMAND: + switch (wParam) { + case IDC_GEDBG_STEPCOUNT_DEC: + if (GetValue()) + Jump(-abs(count), true); + return TRUE; + case IDC_GEDBG_STEPCOUNT_INC: + if (GetValue()) + Jump(abs(count), true); + return TRUE; + case IDC_GEDBG_STEPCOUNT_JUMP: + if (GetValue()) + Jump(abs(count), false); + return TRUE; + case IDOK: + if (GetValue()) + Jump(count, relative); + Show(false); + return TRUE; + case IDCANCEL: + SetFocus(m_hParent); + Show(false); + return TRUE; + } + break; + } + return FALSE; +} + void CGEDebugger::Init() { SimpleGLWindow::RegisterClass(); CtrlDisplayListView::registerClass(); } CGEDebugger::CGEDebugger(HINSTANCE _hInstance, HWND _hParent) - : Dialog((LPCSTR)IDD_GEDEBUGGER, _hInstance, _hParent) { + : Dialog((LPCSTR)IDD_GEDEBUGGER, _hInstance, _hParent) + , stepCountDlg(_hInstance, m_hDlg) { // minimum size = a little more than the default RECT windowRect; GetWindowRect(m_hDlg, &windowRect); @@ -304,6 +368,10 @@ void CGEDebugger::UpdatePreviews() { displayList->setDisplayList(list); } + wchar_t primCounter[1024]{}; + swprintf(primCounter, ARRAY_SIZE(primCounter), L"%d/%d", PrimsThisFrame(), PrimsLastFrame()); + SetDlgItemText(m_hDlg, IDC_GEDBG_PRIMCOUNTER, primCounter); + flags->Update(); lighting->Update(); textureState->Update(); @@ -666,6 +734,7 @@ BOOL CGEDebugger::DlgProc(UINT message, WPARAM wParam, LPARAM lParam) { case WM_CLOSE: GPUDebug::SetActive(false); + stepCountDlg.Show(false); Show(false); return TRUE; @@ -733,6 +802,10 @@ BOOL CGEDebugger::DlgProc(UINT message, WPARAM wParam, LPARAM lParam) { SetBreakNext(BreakNext::CURVE); break; + case IDC_GEDBG_STEPCOUNT: + stepCountDlg.Show(true); + break; + case IDC_GEDBG_BREAKTEX: { GPUDebug::SetActive(true); @@ -791,6 +864,7 @@ BOOL CGEDebugger::DlgProc(UINT message, WPARAM wParam, LPARAM lParam) { secondWindow->Clear(); SetDlgItemText(m_hDlg, IDC_GEDBG_FRAMEBUFADDR, L""); SetDlgItemText(m_hDlg, IDC_GEDBG_TEXADDR, L""); + SetDlgItemText(m_hDlg, IDC_GEDBG_PRIMCOUNTER, L""); SetBreakNext(BreakNext::NONE); break; diff --git a/Windows/GEDebugger/GEDebugger.h b/Windows/GEDebugger/GEDebugger.h index 29e19071df..d4484174a3 100644 --- a/Windows/GEDebugger/GEDebugger.h +++ b/Windows/GEDebugger/GEDebugger.h @@ -44,6 +44,16 @@ class TabMatrices; class TabStateWatch; struct GPUgstate; +class StepCountDlg : public Dialog { +public: + StepCountDlg(HINSTANCE _hInstance, HWND _hParent); + ~StepCountDlg(); +protected: + BOOL DlgProc(UINT message, WPARAM wParam, LPARAM lParam); +private: + void Jump(int count, bool relative); +}; + class CGEDebugger : public Dialog { public: CGEDebugger(HINSTANCE _hInstance, HWND _hParent); @@ -101,4 +111,6 @@ private: int previewsEnabled_ = 3; int minWidth_; int minHeight_; + + StepCountDlg stepCountDlg; }; diff --git a/Windows/GEDebugger/TabVertices.cpp b/Windows/GEDebugger/TabVertices.cpp index f1f7e2f164..bd65e87999 100644 --- a/Windows/GEDebugger/TabVertices.cpp +++ b/Windows/GEDebugger/TabVertices.cpp @@ -187,6 +187,7 @@ void CtrlVertexList::FormatVertColRaw(wchar_t *dest, int row, int col) { const u8 *pos = vert + decoder->posoff; const u8 *tc = vert + decoder->tcoff; const u8 *color = vert + decoder->coloff; + const u8 *norm = vert + decoder->nrmoff; switch (col) { case VERTEXLIST_COL_X: @@ -208,6 +209,10 @@ void CtrlVertexList::FormatVertColRaw(wchar_t *dest, int row, int col) { FormatVertColRawColor(dest, color, decoder->col); break; + case VERTEXLIST_COL_NX: FormatVertColRawType(dest, norm, decoder->nrm, 0); break; + case VERTEXLIST_COL_NY: FormatVertColRawType(dest, norm, decoder->nrm, 1); break; + case VERTEXLIST_COL_NZ: FormatVertColRawType(dest, norm, decoder->nrm, 2); break; + default: wcscpy(dest, L"Invalid"); break; diff --git a/Windows/GEDebugger/VertexPreview.cpp b/Windows/GEDebugger/VertexPreview.cpp index 79183d236f..b608754b66 100644 --- a/Windows/GEDebugger/VertexPreview.cpp +++ b/Windows/GEDebugger/VertexPreview.cpp @@ -204,7 +204,7 @@ static void ExpandBezier(int &count, int op, const std::vector &si cpoints.col = (Vec4f *)AllocateAlignedMemory(sizeof(Vec4f) * num_points, 16); cpoints.Convert(points.data(), num_points); - surface.Init(generatedVerts.size()); + surface.Init((int)generatedVerts.size()); SoftwareTessellation(output, surface, gstate.vertType, cpoints); count = output.count; @@ -256,7 +256,7 @@ static void ExpandSpline(int &count, int op, const std::vector &si cpoints.col = (Vec4f *)AllocateAlignedMemory(sizeof(Vec4f) * num_points, 16); cpoints.Convert(points.data(), num_points); - surface.Init(generatedVerts.size()); + surface.Init((int)generatedVerts.size()); SoftwareTessellation(output, surface, gstate.vertType, cpoints); count = output.count; diff --git a/Windows/GPU/D3D11Context.cpp b/Windows/GPU/D3D11Context.cpp index c5ef162b20..183a3d0529 100644 --- a/Windows/GPU/D3D11Context.cpp +++ b/Windows/GPU/D3D11Context.cpp @@ -176,7 +176,7 @@ bool D3D11Context::Init(HINSTANCE hInst, HWND wnd, std::string *error_message) { draw_ = Draw::T3DCreateD3D11Context(device_, context_, device1_, context1_, featureLevel_, hWnd_, adapterNames); SetGPUBackend(GPUBackend::DIRECT3D11, chosenAdapterName); bool success = draw_->CreatePresets(); // If we can run D3D11, there's a compiler installed. I think. - assert(success); + _assert_msg_(G3D, success, "Failed to compile preset shaders"); int width; int height; diff --git a/Windows/GPU/WindowsGLContext.cpp b/Windows/GPU/WindowsGLContext.cpp index c6c09f5e2d..0701ffa4aa 100644 --- a/Windows/GPU/WindowsGLContext.cpp +++ b/Windows/GPU/WindowsGLContext.cpp @@ -405,7 +405,7 @@ bool WindowsGLContext::InitFromRenderThread(std::string *error_message) { renderManager_ = (GLRenderManager *)draw_->GetNativeObject(Draw::NativeObject::RENDER_MANAGER); SetGPUBackend(GPUBackend::OPENGL); bool success = draw_->CreatePresets(); // if we get this far, there will always be a GLSL compiler capable of compiling these. - assert(success); + _assert_msg_(G3D, success, "Failed to compile preset shaders"); renderManager_->SetSwapFunction([&]() {::SwapBuffers(hDC); }); if (wglSwapIntervalEXT) { // glew loads wglSwapIntervalEXT if available @@ -458,7 +458,7 @@ void WindowsGLContext::Resize() { } void WindowsGLContext::ThreadStart() { - renderManager_->ThreadStart(); + renderManager_->ThreadStart(draw_); } bool WindowsGLContext::ThreadFrame() { diff --git a/Windows/GPU/WindowsVulkanContext.cpp b/Windows/GPU/WindowsVulkanContext.cpp index c0c512d7bb..fbbf1ce12d 100644 --- a/Windows/GPU/WindowsVulkanContext.cpp +++ b/Windows/GPU/WindowsVulkanContext.cpp @@ -114,12 +114,9 @@ bool WindowsVulkanContext::Init(HINSTANCE hInst, HWND hWnd, std::string *error_m if (deviceNum < 0) { deviceNum = g_Vulkan->GetBestPhysicalDevice(); if (!g_Config.sVulkanDevice.empty()) - g_Config.sVulkanDevice = g_Vulkan->GetPhysicalDeviceProperties(deviceNum).deviceName; + g_Config.sVulkanDevice = g_Vulkan->GetPhysicalDeviceProperties(deviceNum).properties.deviceName; } g_Vulkan->ChooseDevice(deviceNum); - if (g_Vulkan->EnableDeviceExtension(VK_NV_DEDICATED_ALLOCATION_EXTENSION_NAME)) { - supportsDedicatedAlloc_ = true; - } if (g_Vulkan->CreateDevice() != VK_SUCCESS) { *error_message = g_Vulkan->InitError(); delete g_Vulkan; @@ -127,8 +124,17 @@ bool WindowsVulkanContext::Init(HINSTANCE hInst, HWND hWnd, std::string *error_m return false; } if (g_validate_) { - int bits = VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT | VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT; - g_Vulkan->InitDebugMsgCallback(&Vulkan_Dbg, bits, &g_LogOptions); + if (g_Vulkan->DeviceExtensions().EXT_debug_utils) { + int bits = VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT + | VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT + | VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT + | VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT + | VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT; + g_Vulkan->InitDebugUtilsCallback(&VulkanDebugUtilsCallback, bits, &g_LogOptions); + } else { + int bits = VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT | VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT; + g_Vulkan->InitDebugMsgCallback(&VulkanDebugReportCallback, bits, &g_LogOptions); + } } g_Vulkan->InitSurface(WINDOWSYSTEM_WIN32, (void *)hInst, (void *)hWnd); if (!g_Vulkan->InitObjects()) { @@ -140,9 +146,9 @@ bool WindowsVulkanContext::Init(HINSTANCE hInst, HWND hWnd, std::string *error_m bool splitSubmit = g_Config.bGfxDebugSplitSubmit; draw_ = Draw::T3DCreateVulkanContext(g_Vulkan, splitSubmit); - SetGPUBackend(GPUBackend::VULKAN, g_Vulkan->GetPhysicalDeviceProperties(deviceNum).deviceName); + SetGPUBackend(GPUBackend::VULKAN, g_Vulkan->GetPhysicalDeviceProperties(deviceNum).properties.deviceName); bool success = draw_->CreatePresets(); - assert(success); // Doesn't fail, we include the compiler. + _assert_msg_(G3D, success, "Failed to compile preset shaders"); draw_->HandleEvent(Draw::Event::GOT_BACKBUFFER, g_Vulkan->GetBackbufferWidth(), g_Vulkan->GetBackbufferHeight()); VulkanRenderManager *renderManager = (VulkanRenderManager *)draw_->GetNativeObject(Draw::NativeObject::RENDER_MANAGER); @@ -163,6 +169,7 @@ void WindowsVulkanContext::Shutdown() { g_Vulkan->WaitUntilQueueIdle(); g_Vulkan->DestroyObjects(); g_Vulkan->DestroyDevice(); + g_Vulkan->DestroyDebugUtilsCallback(); g_Vulkan->DestroyDebugMsgCallback(); g_Vulkan->DestroyInstance(); diff --git a/Windows/GPU/WindowsVulkanContext.h b/Windows/GPU/WindowsVulkanContext.h index 6c9f0f42dd..0a00dfeab8 100644 --- a/Windows/GPU/WindowsVulkanContext.h +++ b/Windows/GPU/WindowsVulkanContext.h @@ -35,6 +35,5 @@ public: Draw::DrawContext *GetDrawContext() override { return draw_; } private: Draw::DrawContext *draw_; - bool supportsDedicatedAlloc_; }; diff --git a/Windows/MainWindow.h b/Windows/MainWindow.h index b8327da086..b10c0468f4 100644 --- a/Windows/MainWindow.h +++ b/Windows/MainWindow.h @@ -35,6 +35,9 @@ namespace MainWindow FRAMESKIP_8 = 8, FRAMESKIP_MAX = FRAMESKIP_8, + FRAMESKIPTYPE_COUNT = 0, + FRAMESKIPTYPE_PRCNT = 1, + RESOLUTION_AUTO = 0, RESOLUTION_NATIVE = 1, RESOLUTION_2X = 2, diff --git a/Windows/MainWindowMenu.cpp b/Windows/MainWindowMenu.cpp index 9999959e6c..c2769e7f85 100644 --- a/Windows/MainWindowMenu.cpp +++ b/Windows/MainWindowMenu.cpp @@ -14,6 +14,8 @@ #include "Common/Log.h" #include "Common/LogManager.h" #include "Common/ConsoleListener.h" +#include "Common/OSVersion.h" +#include "Common/Vulkan/VulkanLoader.h" #include "GPU/GLES/TextureScalerGLES.h" #include "GPU/GLES/TextureCacheGLES.h" #include "UI/OnScreenDisplay.h" @@ -45,7 +47,7 @@ namespace MainWindow { static W32Util::AsyncBrowseDialog *browseImageDialog; static bool browsePauseAfter; - static std::map initialMenuKeys; + static std::unordered_map initialMenuKeys; static std::vector availableShaders; static std::string menuLanguageID = ""; static bool menuShaderInfoLoaded = false; @@ -79,45 +81,24 @@ namespace MainWindow { EnableMenuItem(menu, ID_OPTIONS_LANGUAGE, state == UISTATE_INGAME ? MF_GRAYED : MF_ENABLED); } - // These are used as an offset - // to determine which menu item to change. - // Make sure to count(from 0) the separators too, when dealing with submenus!! - enum MenuItemPosition { - // Main menus - MENU_FILE = 0, - MENU_EMULATION = 1, - MENU_DEBUG = 2, - MENU_OPTIONS = 3, - MENU_HELP = 4, + static HMENU GetSubmenuById(HMENU menu, int menuID) { + MENUITEMINFO menuInfo{ sizeof(MENUITEMINFO), MIIM_SUBMENU }; + if (GetMenuItemInfo(menu, menuID, MF_BYCOMMAND, &menuInfo) != FALSE) { + return menuInfo.hSubMenu; + } + return nullptr; + } MENU_SIMPLEUI = 5, - // File submenus - SUBMENU_FILE_SAVESTATE_SLOT = 6, - SUBMENU_FILE_RECORD = 11, - - // Emulation submenus - SUBMENU_DISPLAY_ROTATION = 4, - - // Game Settings submenus - SUBMENU_DISPLAY_LAYOUT = 7, - SUBMENU_CUSTOM_SHADERS = 10, - SUBMENU_RENDERING_RESOLUTION = 11, - SUBMENU_WINDOW_SIZE = 12, - SUBMENU_RENDERING_BACKEND = 13, - SUBMENU_RENDERING_MODE = 14, - SUBMENU_FRAME_SKIPPING = 15, - SUBMENU_TEXTURE_FILTERING = 16, - SUBMENU_BUFFER_FILTER = 17, - SUBMENU_TEXTURE_SCALING = 18, - }; + static void EmptySubMenu(HMENU menu) { + int c = GetMenuItemCount(menu); + for (int i = 0; i < c; ++i) { + RemoveMenu(menu, i, MF_BYPOSITION); + } + } static std::string GetMenuItemText(HMENU menu, int menuID) { - MENUITEMINFO menuInfo; - memset(&menuInfo, 0, sizeof(menuInfo)); - menuInfo.cbSize = sizeof(MENUITEMINFO); - menuInfo.fMask = MIIM_STRING; - menuInfo.dwTypeData = 0; - + MENUITEMINFO menuInfo{ sizeof(menuInfo), MIIM_STRING }; std::string retVal; if (GetMenuItemInfo(menu, menuID, MF_BYCOMMAND, &menuInfo) != FALSE) { wchar_t *buffer = new wchar_t[++menuInfo.cch]; @@ -140,18 +121,14 @@ namespace MainWindow { void CreateHelpMenu(HMENU menu) { I18NCategory *des = GetI18NCategory("DesktopUI"); - const std::wstring help = ConvertUTF8ToWString(des->T("Help")); const std::wstring visitMainWebsite = ConvertUTF8ToWString(des->T("www.ppsspp.org")); const std::wstring visitForum = ConvertUTF8ToWString(des->T("PPSSPP Forums")); const std::wstring buyGold = ConvertUTF8ToWString(des->T("Buy Gold")); const std::wstring gitHub = ConvertUTF8ToWString(des->T("GitHub")); const std::wstring aboutPPSSPP = ConvertUTF8ToWString(des->T("About PPSSPP...")); - // Simply remove the old help menu and create a new one. - RemoveMenu(menu, MENU_HELP, MF_BYPOSITION); - - HMENU helpMenu = CreatePopupMenu(); - InsertMenu(menu, MENU_HELP, MF_POPUP | MF_STRING | MF_BYPOSITION, (UINT_PTR)helpMenu, help.c_str()); + HMENU helpMenu = GetSubmenuById(menu, ID_HELP_MENU); + EmptySubMenu(helpMenu); AppendMenu(helpMenu, MF_STRING | MF_BYCOMMAND, ID_HELP_OPENWEBSITE, visitMainWebsite.c_str()); AppendMenu(helpMenu, MF_STRING | MF_BYCOMMAND, ID_HELP_OPENFORUM, visitForum.c_str()); @@ -203,20 +180,12 @@ namespace MainWindow { return false; } - I18NCategory *des = GetI18NCategory("DesktopUI"); I18NCategory *ps = GetI18NCategory("PostShaders"); - const std::wstring key = ConvertUTF8ToWString(des->T("Postprocessing Shader")); - HMENU optionsMenu = GetSubMenu(menu, MENU_OPTIONS); - - HMENU shaderMenu = CreatePopupMenu(); - - RemoveMenu(optionsMenu, SUBMENU_CUSTOM_SHADERS, MF_BYPOSITION); - InsertMenu(optionsMenu, SUBMENU_CUSTOM_SHADERS, MF_POPUP | MF_STRING | MF_BYPOSITION, (UINT_PTR)shaderMenu, key.c_str()); + HMENU shaderMenu = GetSubmenuById(menu, ID_OPTIONS_SHADER_MENU); + EmptySubMenu(shaderMenu); int item = ID_SHADERS_BASE + 1; - int checkedStatus = -1; - const char *translatedShaderName = nullptr; availableShaders.clear(); @@ -225,7 +194,7 @@ namespace MainWindow { AppendMenu(shaderMenu, MF_STRING | MF_BYPOSITION | MF_GRAYED, item++, ConvertUTF8ToWString(translatedShaderName).c_str()); } else { for (auto i = info.begin(); i != info.end(); ++i) { - checkedStatus = MF_UNCHECKED; + int checkedStatus = MF_UNCHECKED; availableShaders.push_back(i->section); if (g_Config.sPostShaderName == i->section) { checkedStatus = MF_CHECKED; @@ -241,40 +210,26 @@ namespace MainWindow { return true; } - static void _TranslateMenuItem(const HMENU hMenu, const int menuIDOrPosition, const char *key, bool byCommand = false, const std::wstring& accelerator = L"") { + static void TranslateMenuItem(const HMENU hMenu, const int menuID, const std::wstring& accelerator = L"", const char *key = nullptr) { I18NCategory *des = GetI18NCategory("DesktopUI"); - std::wstring translated = ConvertUTF8ToWString(des->T(key)); + std::wstring translated; + if (key == nullptr || !strcmp(key, "")) { + translated = ConvertUTF8ToWString(des->T(GetMenuItemInitialText(hMenu, menuID))); + } else { + translated = ConvertUTF8ToWString(des->T(key)); + } translated.append(accelerator); - u32 flags = MF_STRING | (byCommand ? MF_BYCOMMAND : MF_BYPOSITION); - - ModifyMenu(hMenu, menuIDOrPosition, flags, menuIDOrPosition, translated.c_str()); - } - - void TranslateMenuItem(HMENU menu, int menuID, const std::wstring& accelerator = L"", const char *key = "") { - if (key == nullptr || !strcmp(key, "")) - _TranslateMenuItem(menu, menuID, GetMenuItemInitialText(menu, menuID).c_str(), true, accelerator); - else - _TranslateMenuItem(menu, menuID, key, true, accelerator); - } - - void TranslateMenu(HMENU menu, const char *key, const MenuItemPosition mainMenuPosition, const std::wstring& accelerator = L"") { - _TranslateMenuItem(menu, mainMenuPosition, key, false, accelerator); - } - - void TranslateSubMenu(HMENU menu, const char *key, const MenuItemPosition mainMenuItem, const MenuItemPosition subMenuItem, const std::wstring& accelerator = L"") { - _TranslateMenuItem(GetSubMenu(menu, mainMenuItem), subMenuItem, key, false, accelerator); + ModifyMenu(hMenu, menuID, MF_STRING | MF_BYCOMMAND, menuID, translated.c_str()); } void DoTranslateMenus(HWND hWnd, HMENU menu) { - // Menu headers and submenu headers don't have resource IDs, - // So we have to hardcode strings here, unfortunately. - TranslateMenu(menu, "File", MENU_FILE); - TranslateMenu(menu, "Emulation", MENU_EMULATION); - TranslateMenu(menu, "Debugging", MENU_DEBUG); - TranslateMenu(menu, "Game Settings", MENU_OPTIONS); - TranslateMenu(menu, "Help", MENU_HELP); + TranslateMenuItem(menu, ID_FILE_MENU); + TranslateMenuItem(menu, ID_EMULATION_MENU); + TranslateMenuItem(menu, ID_DEBUG_MENU); + TranslateMenuItem(menu, ID_OPTIONS_MENU); + TranslateMenuItem(menu, ID_HELP_MENU); TranslateMenu(menu, "Help", MENU_SIMPLEUI); // File menu @@ -282,20 +237,20 @@ namespace MainWindow { TranslateMenuItem(menu, ID_FILE_LOAD_DIR); TranslateMenuItem(menu, ID_FILE_LOAD_MEMSTICK); TranslateMenuItem(menu, ID_FILE_MEMSTICK); - TranslateSubMenu(menu, "Savestate Slot", MENU_FILE, SUBMENU_FILE_SAVESTATE_SLOT, L"\tF3"); + TranslateMenuItem(menu, ID_FILE_SAVESTATE_SLOT_MENU, L"\tF3"); TranslateMenuItem(menu, ID_FILE_QUICKLOADSTATE, L"\tF4"); TranslateMenuItem(menu, ID_FILE_QUICKSAVESTATE, L"\tF2"); TranslateMenuItem(menu, ID_FILE_LOADSTATEFILE); TranslateMenuItem(menu, ID_FILE_SAVESTATEFILE); - TranslateSubMenu(menu, "Record", MENU_FILE, SUBMENU_FILE_RECORD); + TranslateMenuItem(menu, ID_FILE_RECORD_MENU); TranslateMenuItem(menu, ID_FILE_EXIT, L"\tAlt+F4"); // Emulation menu TranslateMenuItem(menu, ID_EMULATION_PAUSE); TranslateMenuItem(menu, ID_EMULATION_STOP, L"\tCtrl+W"); TranslateMenuItem(menu, ID_EMULATION_RESET, L"\tCtrl+B"); - TranslateMenuItem(menu, ID_EMULATION_SWITCH_UMD, L"\tCtrl+U", "Switch UMD"); - TranslateSubMenu(menu, "Display Rotation", MENU_EMULATION, SUBMENU_DISPLAY_ROTATION); + TranslateMenuItem(menu, ID_EMULATION_SWITCH_UMD, L"\tCtrl+U"); + TranslateMenuItem(menu, ID_EMULATION_ROTATION_MENU); TranslateMenuItem(menu, ID_EMULATION_ROTATION_H); TranslateMenuItem(menu, ID_EMULATION_ROTATION_V); TranslateMenuItem(menu, ID_EMULATION_ROTATION_H_R); @@ -336,34 +291,37 @@ namespace MainWindow { // Skip display multipliers x1-x10 TranslateMenuItem(menu, ID_OPTIONS_FULLSCREEN, L"\tAlt+Return, F11"); TranslateMenuItem(menu, ID_OPTIONS_VSYNC); - TranslateSubMenu(menu, "Postprocessing Shader", MENU_OPTIONS, SUBMENU_CUSTOM_SHADERS); - TranslateSubMenu(menu, "Rendering Resolution", MENU_OPTIONS, SUBMENU_RENDERING_RESOLUTION, L"\tCtrl+1"); + TranslateMenuItem(menu, ID_OPTIONS_SHADER_MENU); + TranslateMenuItem(menu, ID_OPTIONS_SCREEN_MENU, L"\tCtrl+1"); TranslateMenuItem(menu, ID_OPTIONS_SCREENAUTO); // Skip rendering resolution 2x-5x.. - TranslateSubMenu(menu, "Window Size", MENU_OPTIONS, SUBMENU_WINDOW_SIZE); + TranslateMenuItem(menu, ID_OPTIONS_WINDOW_MENU); // Skip window size 1x-4x.. - TranslateSubMenu(menu, "Backend", MENU_OPTIONS, SUBMENU_RENDERING_BACKEND); + TranslateMenuItem(menu, ID_OPTIONS_BACKEND_MENU); TranslateMenuItem(menu, ID_OPTIONS_DIRECT3D11); TranslateMenuItem(menu, ID_OPTIONS_DIRECT3D9); TranslateMenuItem(menu, ID_OPTIONS_OPENGL); TranslateMenuItem(menu, ID_OPTIONS_VULKAN); - TranslateSubMenu(menu, "Rendering Mode", MENU_OPTIONS, SUBMENU_RENDERING_MODE); + TranslateMenuItem(menu, ID_OPTIONS_RENDERMODE_MENU); TranslateMenuItem(menu, ID_OPTIONS_NONBUFFEREDRENDERING); TranslateMenuItem(menu, ID_OPTIONS_BUFFEREDRENDERING); - TranslateSubMenu(menu, "Frame Skipping", MENU_OPTIONS, SUBMENU_FRAME_SKIPPING, L"\tF7"); + TranslateMenuItem(menu, ID_OPTIONS_FRAMESKIP_MENU, L"\tF7"); TranslateMenuItem(menu, ID_OPTIONS_FRAMESKIP_AUTO); TranslateMenuItem(menu, ID_OPTIONS_FRAMESKIP_0); + TranslateMenuItem(menu, ID_OPTIONS_FRAMESKIPTYPE_MENU); + TranslateMenuItem(menu, ID_OPTIONS_FRAMESKIPTYPE_COUNT); + TranslateMenuItem(menu, ID_OPTIONS_FRAMESKIPTYPE_PRCNT); // Skip frameskipping 1-8.. - TranslateSubMenu(menu, "Texture Filtering", MENU_OPTIONS, SUBMENU_TEXTURE_FILTERING); + TranslateMenuItem(menu, ID_OPTIONS_TEXTUREFILTERING_MENU); TranslateMenuItem(menu, ID_OPTIONS_TEXTUREFILTERING_AUTO); TranslateMenuItem(menu, ID_OPTIONS_NEARESTFILTERING); TranslateMenuItem(menu, ID_OPTIONS_LINEARFILTERING); TranslateMenuItem(menu, ID_OPTIONS_LINEARFILTERING_CG); - TranslateSubMenu(menu, "Screen Scaling Filter", MENU_OPTIONS, SUBMENU_BUFFER_FILTER); + TranslateMenuItem(menu, ID_OPTIONS_SCREENFILTER_MENU); TranslateMenuItem(menu, ID_OPTIONS_BUFLINEARFILTER); TranslateMenuItem(menu, ID_OPTIONS_BUFNEARESTFILTER); - TranslateSubMenu(menu, "Texture Scaling", MENU_OPTIONS, SUBMENU_TEXTURE_SCALING); + TranslateMenuItem(menu, ID_OPTIONS_TEXTURESCALING_MENU); TranslateMenuItem(menu, ID_TEXTURESCALING_OFF); // Skip texture scaling 2x-5x... TranslateMenuItem(menu, ID_TEXTURESCALING_XBRZ); @@ -590,6 +548,26 @@ namespace MainWindow { osm.Show(messageStream.str()); } + static void setFrameSkippingType(int fskipType = -1) { + if (fskipType >= 0 && fskipType <= 1) { + g_Config.iFrameSkipType = fskipType; + } else { + g_Config.iFrameSkipType = 0; + } + + I18NCategory *gr = GetI18NCategory("Graphics"); + + std::ostringstream messageStream; + messageStream << gr->T("Frame Skipping Type") << ":" << " "; + + if (g_Config.iFrameSkipType == 0) + messageStream << gr->T("Number of Frames"); + else + messageStream << gr->T("Percent of FPS"); + + osm.Show(messageStream.str()); + } + static void enableCheats(bool cheats) { g_Config.bEnableCheats = cheats; } @@ -755,6 +733,7 @@ namespace MainWindow { SaveState::SaveSlot(PSP_CoreParameter().fileToStart, g_Config.iCurrentStateSlot, SaveStateActionFinished); break; } + break; } case ID_OPTIONS_LANGUAGE: @@ -888,8 +867,12 @@ namespace MainWindow { case ID_OPTIONS_FRAMESKIP_7: setFrameSkipping(FRAMESKIP_7); break; case ID_OPTIONS_FRAMESKIP_8: setFrameSkipping(FRAMESKIP_MAX); break; + case ID_OPTIONS_FRAMESKIPTYPE_COUNT: setFrameSkippingType(FRAMESKIPTYPE_COUNT); break; + case ID_OPTIONS_FRAMESKIPTYPE_PRCNT: setFrameSkippingType(FRAMESKIPTYPE_PRCNT); break; + case ID_OPTIONS_FRAMESKIPDUMMY: setFrameSkipping(); + setFrameSkippingType(); break; case ID_FILE_EXIT: @@ -1027,7 +1010,7 @@ namespace MainWindow { break; case ID_OPTIONS_SHOWFPS: - g_Config.iShowFPSCounter = !g_Config.iShowFPSCounter; + g_Config.iShowFPSCounter = g_Config.iShowFPSCounter ? 0 : 3; // 3 = both speed and FPS break; case ID_OPTIONS_TEXTUREFILTERING_AUTO: setTexFiltering(TEX_FILTER_AUTO); break; @@ -1144,6 +1127,8 @@ namespace MainWindow { CHECKITEM(ID_OPTIONS_SHOWFPS, g_Config.iShowFPSCounter); CHECKITEM(ID_OPTIONS_FRAMESKIP_AUTO, g_Config.bAutoFrameSkip); CHECKITEM(ID_OPTIONS_FRAMESKIP, g_Config.iFrameSkip != FRAMESKIP_OFF); + CHECKITEM(ID_OPTIONS_FRAMESKIPTYPE_COUNT, g_Config.iFrameSkipType == FRAMESKIPTYPE_COUNT); + CHECKITEM(ID_OPTIONS_FRAMESKIPTYPE_PRCNT, g_Config.iFrameSkipType == FRAMESKIPTYPE_PRCNT); CHECKITEM(ID_OPTIONS_VSYNC, g_Config.bVSync); CHECKITEM(ID_OPTIONS_TOPMOST, g_Config.bTopMost); CHECKITEM(ID_OPTIONS_PAUSE_FOCUS, g_Config.bPauseOnLostFocus); @@ -1324,6 +1309,12 @@ namespace MainWindow { ID_OPTIONS_FRAMESKIP_7, ID_OPTIONS_FRAMESKIP_8, }; + + static const int frameskippingType[] = { + ID_OPTIONS_FRAMESKIPTYPE_COUNT, + ID_OPTIONS_FRAMESKIPTYPE_PRCNT, + }; + if (g_Config.iFrameSkip < FRAMESKIP_OFF) g_Config.iFrameSkip = FRAMESKIP_OFF; @@ -1334,6 +1325,10 @@ namespace MainWindow { CheckMenuItem(menu, frameskipping[i], MF_BYCOMMAND | ((i == g_Config.iFrameSkip) ? MF_CHECKED : MF_UNCHECKED)); } + for (int i = 0; i < ARRAY_SIZE(frameskippingType); i++) { + CheckMenuItem(menu, frameskippingType[i], MF_BYCOMMAND | ((i == g_Config.iFrameSkipType) ? MF_CHECKED : MF_UNCHECKED)); + } + static const int savestateSlot[] = { ID_FILE_SAVESTATE_SLOT_1, ID_FILE_SAVESTATE_SLOT_2, @@ -1352,12 +1347,15 @@ namespace MainWindow { CheckMenuItem(menu, savestateSlot[i], MF_BYCOMMAND | ((i == g_Config.iCurrentStateSlot) ? MF_CHECKED : MF_UNCHECKED)); } + bool allowD3D11 = DoesVersionMatchWindows(6, 0, 0, 0, true); + bool allowVulkan = VulkanMayBeAvailable(); + switch (GetGPUBackend()) { case GPUBackend::DIRECT3D9: EnableMenuItem(menu, ID_OPTIONS_DIRECT3D9, MF_GRAYED); - EnableMenuItem(menu, ID_OPTIONS_DIRECT3D11, MF_ENABLED); + EnableMenuItem(menu, ID_OPTIONS_DIRECT3D11, allowD3D11 ? MF_ENABLED : MF_GRAYED); EnableMenuItem(menu, ID_OPTIONS_OPENGL, MF_ENABLED); - EnableMenuItem(menu, ID_OPTIONS_VULKAN, MF_ENABLED); + EnableMenuItem(menu, ID_OPTIONS_VULKAN, allowVulkan ? MF_ENABLED : MF_GRAYED); CheckMenuItem(menu, ID_OPTIONS_DIRECT3D9, MF_CHECKED); CheckMenuItem(menu, ID_OPTIONS_DIRECT3D11, MF_UNCHECKED); CheckMenuItem(menu, ID_OPTIONS_OPENGL, MF_UNCHECKED); @@ -1365,9 +1363,9 @@ namespace MainWindow { break; case GPUBackend::OPENGL: EnableMenuItem(menu, ID_OPTIONS_DIRECT3D9, MF_ENABLED); - EnableMenuItem(menu, ID_OPTIONS_DIRECT3D11, MF_ENABLED); + EnableMenuItem(menu, ID_OPTIONS_DIRECT3D11, allowD3D11 ? MF_ENABLED : MF_GRAYED); EnableMenuItem(menu, ID_OPTIONS_OPENGL, MF_GRAYED); - EnableMenuItem(menu, ID_OPTIONS_VULKAN, MF_ENABLED); + EnableMenuItem(menu, ID_OPTIONS_VULKAN, allowVulkan ? MF_ENABLED : MF_GRAYED); CheckMenuItem(menu, ID_OPTIONS_DIRECT3D9, MF_UNCHECKED); CheckMenuItem(menu, ID_OPTIONS_DIRECT3D11, MF_UNCHECKED); CheckMenuItem(menu, ID_OPTIONS_OPENGL, MF_CHECKED); @@ -1375,7 +1373,7 @@ namespace MainWindow { break; case GPUBackend::VULKAN: EnableMenuItem(menu, ID_OPTIONS_DIRECT3D9, MF_ENABLED); - EnableMenuItem(menu, ID_OPTIONS_DIRECT3D11, MF_ENABLED); + EnableMenuItem(menu, ID_OPTIONS_DIRECT3D11, allowD3D11 ? MF_ENABLED : MF_GRAYED); EnableMenuItem(menu, ID_OPTIONS_OPENGL, MF_ENABLED); EnableMenuItem(menu, ID_OPTIONS_VULKAN, MF_GRAYED); CheckMenuItem(menu, ID_OPTIONS_DIRECT3D9, MF_UNCHECKED); @@ -1387,7 +1385,7 @@ namespace MainWindow { EnableMenuItem(menu, ID_OPTIONS_DIRECT3D9, MF_ENABLED); EnableMenuItem(menu, ID_OPTIONS_DIRECT3D11, MF_GRAYED); EnableMenuItem(menu, ID_OPTIONS_OPENGL, MF_ENABLED); - EnableMenuItem(menu, ID_OPTIONS_VULKAN, MF_ENABLED); + EnableMenuItem(menu, ID_OPTIONS_VULKAN, allowVulkan ? MF_ENABLED : MF_GRAYED); CheckMenuItem(menu, ID_OPTIONS_DIRECT3D9, MF_UNCHECKED); CheckMenuItem(menu, ID_OPTIONS_DIRECT3D11, MF_CHECKED); CheckMenuItem(menu, ID_OPTIONS_OPENGL, MF_UNCHECKED); diff --git a/Windows/PPSSPP.vcxproj b/Windows/PPSSPP.vcxproj index a4efbe1117..9945c91e62 100644 --- a/Windows/PPSSPP.vcxproj +++ b/Windows/PPSSPP.vcxproj @@ -1,4 +1,4 @@ - +ï»ż @@ -125,6 +125,7 @@ Sync Use Level3 + ProgramDatabase ../dx9sdk/Include/DX11;../ext;../common;..;../ext/native;../ext/glew;../ext/zlib stdafx.h;Common/DbgNew.h MultiThreadedDebug @@ -161,6 +162,7 @@ Sync Use Level3 + ProgramDatabase ../dx9sdk/Include/DX11;../ext;../common;..;../ext/native;../ext/glew;../ext/zlib stdafx.h;Common/DbgNew.h MultiThreadedDebug diff --git a/Windows/build-x64.cmd b/Windows/build-x64.cmd index 97c80e5cc4..83dfcb80bd 100644 --- a/Windows/build-x64.cmd +++ b/Windows/build-x64.cmd @@ -19,7 +19,7 @@ rem // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. if not defined vs140comntools ( echo "Visual Studio 2015 doesn't appear to be installed properly. Quitting." goto quit - ) else ( +) else ( call "%vs140comntools%\vsvars32.bat" x86_amd64 ) @@ -33,18 +33,18 @@ set DBG_PPSSPP=/m /p:Configuration=Debug;Platform=x64 call msbuild PPSSPP.sln /t:Clean %RLS_PPSSPP% call msbuild PPSSPP.sln /t:Build %RLS_PPSSPP% -if not exist %PPSSPP_ROOT%\%RELEASEX64% ( +if not exist "%PPSSPP_ROOT%\%RELEASEX64%" ( echo Release build failed. goto Quit ) call msbuild PPSSPP.sln /t:Clean %DBG_PPSSPP% /m call msbuild PPSSPP.sln /t:Build %DBG_PPSSPP% /m -if not exist %PPSSPP_ROOT%\%DEBUGX64% ( +if not exist "%PPSSPP_ROOT%\%DEBUGX64%" ( echo Debug build failed. goto Quit ) -if not exist %RELEASE_DIR%\\. ( +if not exist "%RELEASE_DIR%\\." ( mkdir %RELEASE_DIR% ) else ( rmdir /S /Q %RELEASE_DIR% diff --git a/Windows/build-x86.cmd b/Windows/build-x86.cmd index 3b6b548c16..f6c1aff8b6 100644 --- a/Windows/build-x86.cmd +++ b/Windows/build-x86.cmd @@ -19,7 +19,7 @@ rem // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. if not defined vs140comntools ( echo "Visual Studio 2015 doesn't appear to be installed properly. Quitting." goto quit - ) else ( +) else ( call "%vs140comntools%\vsvars32.bat" x86_amd64 ) @@ -39,12 +39,12 @@ if not exist %PPSSPP_ROOT%\%RELEASEX86% ( ) call msbuild PPSSPP.sln /t:Clean %DBG_PPSSPP% /m call msbuild PPSSPP.sln /t:Build %DBG_PPSSPP% /m -if not exist %PPSSPP_ROOT%\%DEBUGX86% ( +if not exist "%PPSSPP_ROOT%\%DEBUGX86%" ( echo Debug build failed. goto Quit ) -if not exist %RELEASE_DIR%\\. ( +if not exist "%RELEASE_DIR%\\." ( mkdir %RELEASE_DIR% ) else ( rmdir /S /Q %RELEASE_DIR% diff --git a/Windows/ppsspp.rc b/Windows/ppsspp.rc index 9d04872d82..90704106d7 100644 --- a/Windows/ppsspp.rc +++ b/Windows/ppsspp.rc @@ -211,14 +211,16 @@ EXSTYLE WS_EX_ACCEPTFILES | WS_EX_TOOLWINDOW CAPTION "GE" FONT 8, "MS Shell Dlg", 0, 0, 0x1 BEGIN - PUSHBUTTON "Step &Frame",IDC_GEDBG_STEPFRAME,10,2,48,14 - PUSHBUTTON "Step &Tex",IDC_GEDBG_STEPTEX,62,2,48,14 - PUSHBUTTON "Step &Draw",IDC_GEDBG_STEPDRAW,114,2,48,14 - PUSHBUTTON "Step &Prim",IDC_GEDBG_STEPPRIM,166,2,48,14 - PUSHBUTTON "Step &Curve",IDC_GEDBG_STEPCURVE,218,2,48,14 - PUSHBUTTON "Step &Into",IDC_GEDBG_STEP,270,2,48,14 - PUSHBUTTON "&Resume",IDC_GEDBG_RESUME,322,2,48,14 - PUSHBUTTON "Rec&ord",IDC_GEDBG_RECORD,440,2,48,14 + PUSHBUTTON "Step &Frame",IDC_GEDBG_STEPFRAME,10,2,44,14 + PUSHBUTTON "Step &Tex",IDC_GEDBG_STEPTEX,55,2,44,14 + PUSHBUTTON "Step &Draw",IDC_GEDBG_STEPDRAW,100,2,44,14 + PUSHBUTTON "Step &Prim",IDC_GEDBG_STEPPRIM,145,2,44,14 + PUSHBUTTON "Step &Curve",IDC_GEDBG_STEPCURVE,190,2,44,14 + PUSHBUTTON "Step &Into",IDC_GEDBG_STEP,235,2,44,14 + PUSHBUTTON "Step Cou&nt",IDC_GEDBG_STEPCOUNT,280,2,44,14 + EDITTEXT IDC_GEDBG_PRIMCOUNTER,325,4,50,12,ES_READONLY | NOT WS_BORDER + PUSHBUTTON "&Resume",IDC_GEDBG_RESUME,396,2,44,14 + PUSHBUTTON "Rec&ord",IDC_GEDBG_RECORD,444,2,44,14 CONTROL "",IDC_GEDBG_TEX,"SimpleGLWindow",WS_CHILD | WS_VISIBLE,10,20,128,128 CONTROL "",IDC_GEDBG_FRAME,"SimpleGLWindow",WS_CHILD | WS_VISIBLE,148,20,256,136 CONTROL "",IDC_GEDBG_MAINTAB,"SysTabControl32",TCS_TABS | TCS_FOCUSNEVER,10,216,480,180 @@ -233,6 +235,18 @@ BEGIN PUSHBUTTON "Break on Target...",IDC_GEDBG_BREAKTARGET,394,211,100,14 END +IDD_GEDBG_STEPCOUNT DIALOGEX 0, 0, 124, 18 +STYLE DS_SETFONT | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME +EXSTYLE WS_EX_TOOLWINDOW +CAPTION "Step Count" +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + COMBOBOX IDC_GEDBG_STEPCOUNT_COMBO,6,3,50,13,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP + PUSHBUTTON "-",IDC_GEDBG_STEPCOUNT_DEC,58,2,14,14 + PUSHBUTTON "+",IDC_GEDBG_STEPCOUNT_INC,73,2,14,14 + PUSHBUTTON "Jump",IDC_GEDBG_STEPCOUNT_JUMP,88,2,30,14 +END + IDD_GEDBG_TAB_VALUES DIALOGEX 0, 0, 316, 183 STYLE DS_SETFONT | WS_CHILD | DS_CONTROL @@ -449,18 +463,18 @@ IDI_STOPDISABLE ICON "stop1.ico" // Menu // -IDR_MENU1 MENU +IDR_MENU1 MENUEX BEGIN - POPUP "File" + POPUP "File", ID_FILE_MENU BEGIN MENUITEM "Load", ID_FILE_LOAD MENUITEM "Open Directory...", ID_FILE_LOAD_DIR MENUITEM "Open from MS:/PSP/GAME...", ID_FILE_LOAD_MEMSTICK - MENUITEM SEPARATOR + MENUITEM "", 0, MFT_SEPARATOR MENUITEM "Open Memory Stick", ID_FILE_MEMSTICK - MENUITEM SEPARATOR + MENUITEM "", 0, MFT_SEPARATOR - POPUP "Savestate Slot" + POPUP "Savestate Slot", ID_FILE_SAVESTATE_SLOT_MENU BEGIN MENUITEM "&1", ID_FILE_SAVESTATE_SLOT_1 MENUITEM "&2", ID_FILE_SAVESTATE_SLOT_2 @@ -473,24 +487,24 @@ BEGIN MENUITEM "Load State File...", ID_FILE_LOADSTATEFILE MENUITEM "Save State File...", ID_FILE_SAVESTATEFILE - POPUP "Record" + POPUP "Record", ID_FILE_RECORD_MENU BEGIN MENUITEM "Record Display", ID_FILE_DUMPFRAMES MENUITEM "Use Lossless Video Codec (FFV1)", ID_FILE_USEFFV1 - MENUITEM SEPARATOR + MENUITEM "", 0, MFT_SEPARATOR MENUITEM "Record Audio", ID_FILE_DUMPAUDIO END - MENUITEM SEPARATOR + MENUITEM "", 0, MFT_SEPARATOR MENUITEM "Exit", ID_FILE_EXIT END - POPUP "Emulation" + POPUP "Emulation", ID_EMULATION_MENU BEGIN MENUITEM "Pause", ID_EMULATION_PAUSE MENUITEM "Stop", ID_EMULATION_STOP MENUITEM "Reset", ID_EMULATION_RESET MENUITEM "Switch UMD", ID_EMULATION_SWITCH_UMD - POPUP "Display Rotation" + POPUP "Display Rotation", ID_EMULATION_ROTATION_MENU BEGIN MENUITEM "Landscape", ID_EMULATION_ROTATION_H MENUITEM "Portrait", ID_EMULATION_ROTATION_V @@ -499,22 +513,22 @@ BEGIN END END - POPUP "Debug" + POPUP "Debugging", ID_DEBUG_MENU BEGIN MENUITEM "Run", ID_TOGGLE_BREAK MENUITEM "Break on Load", ID_DEBUG_BREAKONLOAD MENUITEM "Ignore Illegal Reads/Writes", ID_DEBUG_IGNOREILLEGALREADS - MENUITEM SEPARATOR + MENUITEM "", 0, MFT_SEPARATOR MENUITEM "Load Map File...", ID_DEBUG_LOADMAPFILE MENUITEM "Save Map File...", ID_DEBUG_SAVEMAPFILE MENUITEM "Load .sym File...", ID_DEBUG_LOADSYMFILE MENUITEM "Save .sym File...", ID_DEBUG_SAVESYMFILE MENUITEM "Reset Symbol Table", ID_DEBUG_RESETSYMBOLTABLE - MENUITEM SEPARATOR + MENUITEM "", 0, MFT_SEPARATOR MENUITEM "Take Screenshot", ID_DEBUG_TAKESCREENSHOT MENUITEM "Dump Next Frame to Log", ID_DEBUG_DUMPNEXTFRAME MENUITEM "Show Debug Statistics", ID_DEBUG_SHOWDEBUGSTATISTICS - MENUITEM SEPARATOR + MENUITEM "", 0, MFT_SEPARATOR MENUITEM "Disassembly", ID_DEBUG_DISASSEMBLY MENUITEM "GE Debugger...", ID_DEBUG_GEDEBUGGER MENUITEM "Extract File...", ID_DEBUG_EXTRACTFILE @@ -522,7 +536,7 @@ BEGIN MENUITEM "Memory View...", ID_DEBUG_MEMORYVIEW END - POPUP "Options" + POPUP "Game Settings", ID_OPTIONS_MENU BEGIN MENUITEM "Keep PPSSPP On Top", ID_OPTIONS_TOPMOST MENUITEM "Pause When Not Focused", ID_OPTIONS_PAUSE_FOCUS @@ -531,11 +545,14 @@ BEGIN MENUITEM "Control Mapping...", ID_OPTIONS_CONTROLS MENUITEM "Display Layout Editor", ID_OPTIONS_DISPLAY_LAYOUT MENUITEM "More Settings...", ID_OPTIONS_MORE_SETTINGS - MENUITEM SEPARATOR + MENUITEM "", 0, MFT_SEPARATOR MENUITEM "Fullscreen", ID_OPTIONS_FULLSCREEN MENUITEM "VSync", ID_OPTIONS_VSYNC - MENUITEM "Postprocessing Shader", ID_OPTIONS_FXAA - POPUP "Rendering Resolution" + POPUP "Postprocessing Shader", ID_OPTIONS_SHADER_MENU + BEGIN + MENUITEM "", 0, MFT_SEPARATOR + END + POPUP "Rendering Resolution", ID_OPTIONS_SCREEN_MENU BEGIN MENUITEM "Auto", ID_OPTIONS_SCREENAUTO MENUITEM "&1x", ID_OPTIONS_SCREEN1X @@ -549,7 +566,7 @@ BEGIN MENUITEM "&9x", ID_OPTIONS_SCREEN9X MENUITEM "&Max", ID_OPTIONS_SCREENMAX END - POPUP "Window Size" + POPUP "Window Size", ID_OPTIONS_WINDOW_MENU BEGIN MENUITEM "&1x", ID_OPTIONS_WINDOW1X MENUITEM "&2x", ID_OPTIONS_WINDOW2X @@ -563,7 +580,7 @@ BEGIN MENUITEM "&10x", ID_OPTIONS_WINDOW10X END - POPUP "Backend" + POPUP "Backend", ID_OPTIONS_BACKEND_MENU BEGIN MENUITEM "Direct3D9", ID_OPTIONS_DIRECT3D9 MENUITEM "Direct3D11", ID_OPTIONS_DIRECT3D11 @@ -571,15 +588,15 @@ BEGIN MENUITEM "Vulkan", ID_OPTIONS_VULKAN END - POPUP "Rendering Mode" + POPUP "Rendering Mode", ID_OPTIONS_RENDERMODE_MENU BEGIN MENUITEM "Non-Buffered Rendering", ID_OPTIONS_NONBUFFEREDRENDERING MENUITEM "Buffered Rendering", ID_OPTIONS_BUFFEREDRENDERING END - POPUP "Frame Skipping" + POPUP "Frame Skipping", ID_OPTIONS_FRAMESKIP_MENU BEGIN MENUITEM "Auto", ID_OPTIONS_FRAMESKIP_AUTO - MENUITEM SEPARATOR + MENUITEM "", 0, MFT_SEPARATOR MENUITEM "Off", ID_OPTIONS_FRAMESKIP_0 MENUITEM "&1", ID_OPTIONS_FRAMESKIP_1 MENUITEM "&2", ID_OPTIONS_FRAMESKIP_2 @@ -590,20 +607,25 @@ BEGIN MENUITEM "&7", ID_OPTIONS_FRAMESKIP_7 MENUITEM "&8", ID_OPTIONS_FRAMESKIP_8 END - POPUP "Texture Filtering" + POPUP "Frame Skipping Type", ID_OPTIONS_FRAMESKIPTYPE_MENU + BEGIN + MENUITEM "Skip Number of Frames", ID_OPTIONS_FRAMESKIPTYPE_COUNT + MENUITEM "Skip Percent of FPS", ID_OPTIONS_FRAMESKIPTYPE_PRCNT + END + POPUP "Texture Filtering", ID_OPTIONS_TEXTUREFILTERING_MENU BEGIN MENUITEM "Auto", ID_OPTIONS_TEXTUREFILTERING_AUTO MENUITEM "Nearest", ID_OPTIONS_NEARESTFILTERING MENUITEM "Linear", ID_OPTIONS_LINEARFILTERING MENUITEM "Linear on FMV", ID_OPTIONS_LINEARFILTERING_CG END - POPUP "Screen Scaling Filter" + POPUP "Screen Scaling Filter", ID_OPTIONS_SCREENFILTER_MENU BEGIN MENUITEM "Linear", ID_OPTIONS_BUFLINEARFILTER MENUITEM "Nearest", ID_OPTIONS_BUFNEARESTFILTER END - POPUP "Texture Scaling" + POPUP "Texture Scaling", ID_OPTIONS_TEXTURESCALING_MENU BEGIN MENUITEM "Off", ID_TEXTURESCALING_OFF MENUITEM "Auto", ID_TEXTURESCALING_AUTO @@ -611,7 +633,7 @@ BEGIN MENUITEM "&3x", ID_TEXTURESCALING_3X MENUITEM "&4x", ID_TEXTURESCALING_4X MENUITEM "&5x", ID_TEXTURESCALING_5X - MENUITEM SEPARATOR + MENUITEM "", 0, MFT_SEPARATOR MENUITEM "xBRZ", ID_TEXTURESCALING_XBRZ MENUITEM "Hybrid", ID_TEXTURESCALING_HYBRID MENUITEM "Bicubic", ID_TEXTURESCALING_BICUBIC @@ -621,18 +643,23 @@ BEGIN MENUITEM "SABR(RS)", ID_TEXTURESCALING_SABR MENUITEM "Gaussian(RS)", ID_TEXTURESCALING_GAUSSIAN MENUITEM "Cosine(RS)", ID_TEXTURESCALING_COSINE - MENUITEM SEPARATOR + MENUITEM "", 0, MFT_SEPARATOR MENUITEM "Deposterize", ID_TEXTURESCALING_DEPOSTERIZE MENUITEM "Realtime Scaling(D3D11)", ID_TEXTURESCALING_REALTIME END MENUITEM "Hardware Transform", ID_OPTIONS_HARDWARETRANSFORM MENUITEM "Vertex Cache", ID_OPTIONS_VERTEXCACHE MENUITEM "Show FPS Counter", ID_OPTIONS_SHOWFPS - MENUITEM SEPARATOR - MENUITEM "Enable Sound", ID_EMULATION_SOUND, CHECKED - MENUITEM SEPARATOR + MENUITEM "", 0, MFT_SEPARATOR + MENUITEM "Enable Sound", ID_EMULATION_SOUND + MENUITEM "", 0, MFT_SEPARATOR MENUITEM "Enable Cheats", ID_EMULATION_CHEATS END + + POPUP "Help", ID_HELP_MENU + BEGIN + MENUITEM "", 0, MFT_SEPARATOR + END END IDR_POPUPMENUS MENU diff --git a/Windows/resource.h b/Windows/resource.h index 9ed429dcf6..a5ee7fa5be 100644 --- a/Windows/resource.h +++ b/Windows/resource.h @@ -81,6 +81,7 @@ #define IDD_DUMPMEMORY 253 #define IDD_GEDBG_TAB_VERTICES 254 #define IDD_GEDBG_TAB_MATRICES 255 +#define IDD_GEDBG_STEPCOUNT 256 #define IDC_STOPGO 1001 #define IDC_ADDRESS 1002 @@ -165,6 +166,7 @@ #define IDC_GEDBG_SHOWCLUT 1198 #define IDC_BREAKPOINT_LOG_FORMAT 1199 #define IDC_SHOWOFFSETS 1200 +#define IDC_GEDBG_PRIMCOUNTER 1201 #define ID_SHADERS_BASE 5000 @@ -288,7 +290,7 @@ #define IDC_GEDBG_LISTS_ALLLISTS 40123 #define IDC_GEDBG_LISTS_STACK 40124 #define IDC_GEDBG_LISTS_SELECTEDLIST 40125 -#define ID_OPTIONS_FXAA 40126 +#define ID_OPTIONS_SHADER_MENU 40126 #define IDC_DEBUG_BOTTOMTABS 40127 #define ID_DEBUG_HIDEBOTTOMTABS 40128 #define ID_DEBUG_TOGGLEBOTTOMTABTITLES 40129 @@ -352,6 +354,30 @@ #define ID_TEXTURESCALING_GAUSSIAN 40183 #define ID_TEXTURESCALING_COSINE 40184 #define IDC_GEDBG_STEPCURVE 40185 +#define ID_OPTIONS_FRAMESKIPTYPE_COUNT 40186 +#define ID_OPTIONS_FRAMESKIPTYPE_PRCNT 40187 +#define ID_FILE_MENU 40188 +#define ID_EMULATION_MENU 40189 +#define ID_DEBUG_MENU 40190 +#define ID_OPTIONS_MENU 40191 +#define ID_HELP_MENU 40192 +#define ID_FILE_SAVESTATE_SLOT_MENU 40193 +#define ID_FILE_RECORD_MENU 40194 +#define ID_EMULATION_ROTATION_MENU 40195 +#define ID_OPTIONS_SCREEN_MENU 40196 +#define ID_OPTIONS_WINDOW_MENU 40197 +#define ID_OPTIONS_BACKEND_MENU 40198 +#define ID_OPTIONS_RENDERMODE_MENU 40199 +#define ID_OPTIONS_FRAMESKIP_MENU 40200 +#define ID_OPTIONS_FRAMESKIPTYPE_MENU 40201 +#define ID_OPTIONS_TEXTUREFILTERING_MENU 40202 +#define ID_OPTIONS_SCREENFILTER_MENU 40203 +#define ID_OPTIONS_TEXTURESCALING_MENU 40204 +#define IDC_GEDBG_STEPCOUNT 40205 +#define IDC_GEDBG_STEPCOUNT_DEC 40206 +#define IDC_GEDBG_STEPCOUNT_INC 40207 +#define IDC_GEDBG_STEPCOUNT_JUMP 40208 +#define IDC_GEDBG_STEPCOUNT_COMBO 40209 // Dummy option to let the buffered rendering hotkey cycle through all the options. #define ID_OPTIONS_BUFFEREDRENDERINGDUMMY 40500 @@ -364,8 +390,8 @@ #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_NEXT_RESOURCE_VALUE 256 -#define _APS_NEXT_COMMAND_VALUE 40186 -#define _APS_NEXT_CONTROL_VALUE 1200 +#define _APS_NEXT_COMMAND_VALUE 40210 +#define _APS_NEXT_CONTROL_VALUE 1202 #define _APS_NEXT_SYMED_VALUE 101 #endif #endif diff --git a/android/AndroidManifest.xml b/android/AndroidManifest.xml index 18e454d348..c9e9cf2050 100644 --- a/android/AndroidManifest.xml +++ b/android/AndroidManifest.xml @@ -2,8 +2,8 @@ + android:versionCode="17050000" + android:versionName="1.7.5.0"> diff --git a/android/build.gradle b/android/build.gradle index 51b4eb9317..a42f360633 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -70,6 +70,7 @@ android { optimized { // Debug signed but optimized. minifyEnabled = false + jniDebuggable true signingConfig android.buildTypes.debug.signingConfig } release { @@ -144,6 +145,12 @@ android { afterEvaluate { android.sourceSets.main.assets.getSrcDirs().each { println it } } -dependencies { - implementation files('libs/com.bda.controller.jar') + +// F-Droid lite version can be created with : ./gradlew assembleOptimized -Pf_droid +if (project.hasProperty("f_droid")) { + project.android.sourceSets.main.java.srcDirs += 'libs/MogaStubs' +} else { + project.dependencies { + implementation files('libs/com.bda.controller.jar') + } } diff --git a/android/gradle.properties b/android/gradle.properties index d8813c3693..8bd86f6805 100644 --- a/android/gradle.properties +++ b/android/gradle.properties @@ -1,2 +1 @@ org.gradle.jvmargs=-Xmx1536M -android.enableAapt2=true diff --git a/android/jni/Android.mk b/android/jni/Android.mk index 1ed3b4eb69..a266947e42 100644 --- a/android/jni/Android.mk +++ b/android/jni/Android.mk @@ -247,6 +247,7 @@ EXEC_AND_LIB_FILES := \ $(SRC)/GPU/Debugger/Stepping.cpp \ $(SRC)/GPU/GLES/FramebufferManagerGLES.cpp \ $(SRC)/GPU/GLES/DepalettizeShaderGLES.cpp \ + $(SRC)/GPU/GLES/DepthBufferGLES.cpp.arm \ $(SRC)/GPU/GLES/GPU_GLES.cpp.arm \ $(SRC)/GPU/GLES/StencilBufferGLES.cpp.arm \ $(SRC)/GPU/GLES/TextureCacheGLES.cpp.arm \ @@ -505,6 +506,7 @@ LOCAL_SRC_FILES := \ $(SRC)/UI/GameScreen.cpp \ $(SRC)/UI/ControlMappingScreen.cpp \ $(SRC)/UI/GameSettingsScreen.cpp \ + $(SRC)/UI/GPUDriverTestScreen.cpp \ $(SRC)/UI/TiltAnalogSettingsScreen.cpp \ $(SRC)/UI/TiltEventProcessor.cpp \ $(SRC)/UI/TouchControlLayoutScreen.cpp \ diff --git a/android/jni/AndroidEGLContext.cpp b/android/jni/AndroidEGLContext.cpp index 34d21597f5..163c123fa7 100644 --- a/android/jni/AndroidEGLContext.cpp +++ b/android/jni/AndroidEGLContext.cpp @@ -52,7 +52,7 @@ bool AndroidEGLGraphicsContext::InitFromRenderThread(ANativeWindow *wnd, int des SetGPUBackend(GPUBackend::OPENGL); renderManager_ = (GLRenderManager *)draw_->GetNativeObject(Draw::NativeObject::RENDER_MANAGER); bool success = draw_->CreatePresets(); // There will always be a GLSL compiler capable of compiling these. - assert(success); + _assert_msg_(G3D, success, "Failed to compile preset shaders"); return true; } diff --git a/android/jni/AndroidEGLContext.h b/android/jni/AndroidEGLContext.h index 35ae334294..45b33f8241 100644 --- a/android/jni/AndroidEGLContext.h +++ b/android/jni/AndroidEGLContext.h @@ -21,7 +21,7 @@ public: } void ThreadStart() override { - renderManager_->ThreadStart(); + renderManager_->ThreadStart(draw_); } bool ThreadFrame() override { diff --git a/android/jni/AndroidJavaGLContext.cpp b/android/jni/AndroidJavaGLContext.cpp index aca9f8fcc9..2d463e76dc 100644 --- a/android/jni/AndroidJavaGLContext.cpp +++ b/android/jni/AndroidJavaGLContext.cpp @@ -16,6 +16,7 @@ bool AndroidJavaEGLGraphicsContext::InitFromRenderThread(ANativeWindow *wnd, int draw_ = Draw::T3DCreateGLContext(); renderManager_ = (GLRenderManager *)draw_->GetNativeObject(Draw::NativeObject::RENDER_MANAGER); bool success = draw_->CreatePresets(); + _assert_msg_(G3D, success, "Failed to compile preset shaders"); return success; } diff --git a/android/jni/AndroidJavaGLContext.h b/android/jni/AndroidJavaGLContext.h index 99db77dfcb..05d3966896 100644 --- a/android/jni/AndroidJavaGLContext.h +++ b/android/jni/AndroidJavaGLContext.h @@ -34,7 +34,7 @@ public: } void ThreadStart() override { - renderManager_->ThreadStart(); + renderManager_->ThreadStart(draw_); } bool ThreadFrame() override { diff --git a/android/jni/AndroidVulkanContext.cpp b/android/jni/AndroidVulkanContext.cpp index 128183dcc9..f20247145c 100644 --- a/android/jni/AndroidVulkanContext.cpp +++ b/android/jni/AndroidVulkanContext.cpp @@ -130,18 +130,13 @@ bool AndroidVulkanContext::InitAPI() { g_Vulkan = nullptr; return false; } + ILOG("Vulkan device created!"); return true; } bool AndroidVulkanContext::InitFromRenderThread(ANativeWindow *wnd, int desiredBackbufferSizeX, int desiredBackbufferSizeY, int backbufferFormat, int androidVersion) { - int width = desiredBackbufferSizeX; - int height = desiredBackbufferSizeY; - if (!width || !height) { - width = pixel_xres; - height = pixel_yres; - } - ILOG("InitSurfaceAndroid: width=%d height=%d", width, height); - g_Vulkan->InitSurface(WINDOWSYSTEM_ANDROID, (void *)wnd, nullptr, width, height); + ILOG("InitSurfaceAndroid: desiredwidth=%d desiredheight=%d", desiredBackbufferSizeX, desiredBackbufferSizeY); + g_Vulkan->InitSurface(WINDOWSYSTEM_ANDROID, (void *)wnd, nullptr); if (g_validate_) { int bits = VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT | VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT; g_Vulkan->InitDebugMsgCallback(&Vulkan_Dbg, bits, &g_LogOptions); @@ -152,7 +147,7 @@ bool AndroidVulkanContext::InitFromRenderThread(ANativeWindow *wnd, int desiredB draw_ = Draw::T3DCreateVulkanContext(g_Vulkan, g_Config.bGfxDebugSplitSubmit); SetGPUBackend(GPUBackend::VULKAN); success = draw_->CreatePresets(); // Doesn't fail, we ship the compiler. - assert(success); + _assert_msg_(G3D, success, "Failed to compile preset shaders"); draw_->HandleEvent(Draw::Event::GOT_BACKBUFFER, g_Vulkan->GetBackbufferWidth(), g_Vulkan->GetBackbufferHeight()); VulkanRenderManager *renderManager = (VulkanRenderManager *)draw_->GetNativeObject(Draw::NativeObject::RENDER_MANAGER); @@ -165,6 +160,7 @@ bool AndroidVulkanContext::InitFromRenderThread(ANativeWindow *wnd, int desiredB if (!success) { g_Vulkan->DestroyObjects(); g_Vulkan->DestroyDevice(); + g_Vulkan->DestroyDebugUtilsCallback(); g_Vulkan->DestroyDebugMsgCallback(); g_Vulkan->DestroyInstance(); @@ -186,6 +182,7 @@ void AndroidVulkanContext::ShutdownFromRenderThread() { void AndroidVulkanContext::Shutdown() { ILOG("Calling NativeShutdownGraphics"); g_Vulkan->DestroyDevice(); + g_Vulkan->DestroyDebugUtilsCallback(); g_Vulkan->DestroyDebugMsgCallback(); g_Vulkan->DestroyInstance(); @@ -204,7 +201,7 @@ void AndroidVulkanContext::Resize() { g_Vulkan->DestroyObjects(); // backbufferResize updated these values. TODO: Notify another way? - g_Vulkan->ReinitSurface(pixel_xres, pixel_yres); + g_Vulkan->ReinitSurface(); g_Vulkan->InitObjects(); draw_->HandleEvent(Draw::Event::GOT_BACKBUFFER, g_Vulkan->GetBackbufferWidth(), g_Vulkan->GetBackbufferHeight()); ILOG("AndroidVulkanContext::Resize end (%d, %d)", g_Vulkan->GetBackbufferWidth(), g_Vulkan->GetBackbufferHeight()); diff --git a/android/jni/app-android.cpp b/android/jni/app-android.cpp index 0a99555895..2180522782 100644 --- a/android/jni/app-android.cpp +++ b/android/jni/app-android.cpp @@ -193,6 +193,7 @@ static void EmuThreadFunc() { while (emuThreadState != (int)EmuThreadState::QUIT_REQUESTED) { UpdateRunLoopAndroid(env); } + ILOG("QUIT_REQUESTED found, left loop. Setting state to STOPPED."); emuThreadState = (int)EmuThreadState::STOPPED; NativeShutdownGraphics(); @@ -213,8 +214,8 @@ static void EmuThreadStart() { // Call EmuThreadStop first, then keep running the GPU (or eat commands) // as long as emuThreadState isn't STOPPED and/or there are still things queued up. // Only after that, call EmuThreadJoin. -static void EmuThreadStop() { - ILOG("EmuThreadStop - stopping..."); +static void EmuThreadStop(const char *caller) { + ILOG("EmuThreadStop - stopping (%s)...", caller); emuThreadState = (int)EmuThreadState::QUIT_REQUESTED; } @@ -527,15 +528,16 @@ extern "C" void Java_org_ppsspp_ppsspp_NativeApp_pause(JNIEnv *, jclass) { extern "C" void Java_org_ppsspp_ppsspp_NativeApp_shutdown(JNIEnv *, jclass) { if (renderer_inited && useCPUThread && graphicsContext) { // Only used in Java EGL path. - EmuThreadStop(); + EmuThreadStop("shutdown"); + ILOG("BeginAndroidShutdown"); graphicsContext->BeginAndroidShutdown(); // Skipping GL calls, the old context is gone. while (graphicsContext->ThreadFrame()) { ILOG("graphicsContext->ThreadFrame executed to clear buffers"); - continue; } ILOG("Joining emuthread"); EmuThreadJoin(); + ILOG("Joined emuthread"); graphicsContext->ThreadEnd(); graphicsContext->ShutdownFromRenderThread(); @@ -566,15 +568,17 @@ extern "C" void Java_org_ppsspp_ppsspp_NativeRenderer_displayInit(JNIEnv * env, // We should be running on the render thread here. std::string errorMessage; if (renderer_inited) { - // Would be really nice if we could get something on the GL thread immediately when shutting down... + // Would be really nice if we could get something on the GL thread immediately when shutting down. ILOG("NativeApp.displayInit() restoring"); if (useCPUThread) { - EmuThreadStop(); + EmuThreadStop("displayInit"); graphicsContext->BeginAndroidShutdown(); + ILOG("BeginAndroidShutdown. Looping until emu thread done..."); // Skipping GL calls here because the old context is lost. while (graphicsContext->ThreadFrame()) { continue; } + ILOG("Joining emu thread"); EmuThreadJoin(); } else { NativeShutdownGraphics(); @@ -1018,7 +1022,7 @@ retry: ILOG("Leaving EGL/Vulkan render loop."); if (useCPUThread) { - EmuThreadStop(); + EmuThreadStop("exitrenderloop"); while (graphicsContext->ThreadFrame()) { continue; } diff --git a/android/libs/MogaStubs/com/bda/controller/Controller.java b/android/libs/MogaStubs/com/bda/controller/Controller.java new file mode 100644 index 0000000000..c30cae357b --- /dev/null +++ b/android/libs/MogaStubs/com/bda/controller/Controller.java @@ -0,0 +1,39 @@ +package com.bda.controller; + +import android.app.Activity; +import android.os.Handler; +import android.view.SurfaceView; + +public class Controller { + public static final int ACTION_VERSION_MOGA = 0; + public static final int STATE_CURRENT_PRODUCT_VERSION = 1; + + static Controller sInstance; + + private Controller() {} + + public static Controller getInstance(Activity activity) { + if (sInstance == null) { + sInstance = new Controller(); + } + return sInstance; + } + public int getState(int val) { + return 0; + } + public int setListener(SurfaceView view, Handler handler) { + return 0; + } + public int init() { + return 0; + } + public int onPause() { + return 0; + } + public int onResume() { + return 0; + } + public int exit() { + return 0; + } +} diff --git a/android/libs/MogaStubs/com/bda/controller/ControllerListener.java b/android/libs/MogaStubs/com/bda/controller/ControllerListener.java new file mode 100644 index 0000000000..c1bde2b583 --- /dev/null +++ b/android/libs/MogaStubs/com/bda/controller/ControllerListener.java @@ -0,0 +1,9 @@ +package com.bda.controller; + +public interface ControllerListener { + public abstract void onKeyEvent(KeyEvent event); + + public abstract void onMotionEvent(MotionEvent event); + + public abstract void onStateEvent(StateEvent state); +} diff --git a/android/libs/MogaStubs/com/bda/controller/IControllerService.java b/android/libs/MogaStubs/com/bda/controller/IControllerService.java new file mode 100644 index 0000000000..2fe7a5c3f6 --- /dev/null +++ b/android/libs/MogaStubs/com/bda/controller/IControllerService.java @@ -0,0 +1,4 @@ +package com.bda.controller; + +public class IControllerService { +} diff --git a/android/libs/MogaStubs/com/bda/controller/KeyEvent.java b/android/libs/MogaStubs/com/bda/controller/KeyEvent.java new file mode 100644 index 0000000000..2a6a108921 --- /dev/null +++ b/android/libs/MogaStubs/com/bda/controller/KeyEvent.java @@ -0,0 +1,20 @@ +package com.bda.controller; + +public class KeyEvent { + public static final int ACTION_DOWN = 0; + public static final int ACTION_UP = 1; + public static final int KEYCODE_DPAD_UP = 2; + public static final int KEYCODE_DPAD_DOWN = 3; + public static final int KEYCODE_DPAD_LEFT = 4; + public static final int KEYCODE_DPAD_RIGHT = 5; + + public int getAction() { + return 0; + } + public int getState(int val) { + return 0; + } + public int getKeyCode() { + return 0; + } +} diff --git a/android/libs/MogaStubs/com/bda/controller/MotionEvent.java b/android/libs/MogaStubs/com/bda/controller/MotionEvent.java new file mode 100644 index 0000000000..35d8816ff2 --- /dev/null +++ b/android/libs/MogaStubs/com/bda/controller/MotionEvent.java @@ -0,0 +1,14 @@ +package com.bda.controller; + +public class MotionEvent { + public static final int AXIS_X = 0; + public static final int AXIS_Y = 1; + public static final int AXIS_Z = 2; + public static final int AXIS_RZ = 3; + public static final int AXIS_LTRIGGER = 4; + public static final int AXIS_RTRIGGER = 5; + + public int getAxisValue(int val) { + return 0; + } +} diff --git a/android/libs/MogaStubs/com/bda/controller/StateEvent.java b/android/libs/MogaStubs/com/bda/controller/StateEvent.java new file mode 100644 index 0000000000..230e8b7172 --- /dev/null +++ b/android/libs/MogaStubs/com/bda/controller/StateEvent.java @@ -0,0 +1,19 @@ +package com.bda.controller; + +public class StateEvent { + public static final int STATE_POWER_LOW = 0; + public static final int STATE_CONNECTION = 1; + + public static final int ACTION_FALSE = 0; + public static final int ACTION_TRUE = 1; + public static final int ACTION_DISCONNECTED = 2; + public static final int ACTION_CONNECTING = 3; + public static final int ACTION_CONNECTED = 4; + + public int getAction() { + return 0; + } + public int getState() { + return 0; + } +} diff --git a/android/src/org/ppsspp/ppsspp/NativeActivity.java b/android/src/org/ppsspp/ppsspp/NativeActivity.java index 319147e01d..2e1815bfe5 100644 --- a/android/src/org/ppsspp/ppsspp/NativeActivity.java +++ b/android/src/org/ppsspp/ppsspp/NativeActivity.java @@ -517,8 +517,13 @@ public abstract class NativeActivity extends Activity implements SurfaceHolder.C if (Build.MANUFACTURER == "OUYA") { mGLSurfaceView.getHolder().setFormat(PixelFormat.RGBX_8888); mGLSurfaceView.setEGLConfigChooser(new NativeEGLConfigChooser()); + } else { + // Tried to mess around with config choosers (NativeEGLConfigChooser) here but fail completely on Xperia Play. + // On the other hand, I think from ICS we should be safe to at least require 8888 and stencil... + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) { + mGLSurfaceView.setEGLConfigChooser(8, 8, 8, 8, 16, 8); + } } - // Tried to mess around with config choosers here but fail completely on Xperia Play. mGLSurfaceView.setRenderer(nativeRenderer); setContentView(mGLSurfaceView); } else { @@ -569,11 +574,6 @@ public abstract class NativeActivity extends Activity implements SurfaceHolder.C // Note that desiredSize might be 0,0 here - but that's fine when calling setFixedSize! It means auto. Log.d(TAG, "Setting fixed size " + desiredSize.x + " x " + desiredSize.y); holder.setFixedSize(desiredSize.x, desiredSize.y); - - // This may change it - but, since we're visible now, we can actually set this. - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) { - updateSystemUiVisibility(); - } } @Override diff --git a/android/src/org/ppsspp/ppsspp/NativeGLView.java b/android/src/org/ppsspp/ppsspp/NativeGLView.java index ce2e4be677..af5b738be6 100644 --- a/android/src/org/ppsspp/ppsspp/NativeGLView.java +++ b/android/src/org/ppsspp/ppsspp/NativeGLView.java @@ -18,7 +18,11 @@ import android.os.Build; import android.os.Handler; import android.util.Log; import android.view.MotionEvent; -import com.bda.controller.*; + +import com.bda.controller.Controller; +import com.bda.controller.ControllerListener; +import com.bda.controller.KeyEvent; +import com.bda.controller.StateEvent; public class NativeGLView extends GLSurfaceView implements SensorEventListener, ControllerListener { private static String TAG = "NativeGLView"; diff --git a/android/src/org/ppsspp/ppsspp/NativeRenderer.java b/android/src/org/ppsspp/ppsspp/NativeRenderer.java index 2433b2b637..31df096943 100644 --- a/android/src/org/ppsspp/ppsspp/NativeRenderer.java +++ b/android/src/org/ppsspp/ppsspp/NativeRenderer.java @@ -2,7 +2,11 @@ package org.ppsspp.ppsspp; import android.opengl.GLSurfaceView; import android.util.Log; + +import javax.microedition.khronos.egl.EGL10; import javax.microedition.khronos.egl.EGLConfig; +import javax.microedition.khronos.egl.EGLContext; +import javax.microedition.khronos.egl.EGLDisplay; import javax.microedition.khronos.opengles.GL10; public class NativeRenderer implements GLSurfaceView.Renderer { @@ -24,8 +28,25 @@ public class NativeRenderer implements GLSurfaceView.Renderer { inFrame = false; } - public void onSurfaceCreated(GL10 unused, EGLConfig config) { + public void onSurfaceCreated(GL10 gl, EGLConfig config) { Log.i(TAG, "NativeRenderer: onSurfaceCreated"); + + EGL10 egl = (EGL10)EGLContext.getEGL(); + if (egl != null) { + EGLDisplay dpy = egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY); + if (dpy != null) { + int[] val = new int[1]; + egl.eglGetConfigAttrib(dpy, config, EGL10.EGL_DEPTH_SIZE, val); + int depthBits = val[0]; + egl.eglGetConfigAttrib(dpy, config, EGL10.EGL_STENCIL_SIZE, val); + int stencilBits = val[0]; + Log.i(TAG, "EGL reports " + depthBits + " bits of depth and " + stencilBits + " bits of stencil."); + } else { + Log.e(TAG, "dpy == null"); + } + } else { + Log.e(TAG, "egl == null"); + } // Log.i(TAG, "onSurfaceCreated - EGL context is new or was lost"); // Actually, it seems that it is here we should recreate lost GL objects. displayInit(); diff --git a/android/src/org/ppsspp/ppsspp/NativeSurfaceView.java b/android/src/org/ppsspp/ppsspp/NativeSurfaceView.java index d09952b6b5..1efc71fd8e 100644 --- a/android/src/org/ppsspp/ppsspp/NativeSurfaceView.java +++ b/android/src/org/ppsspp/ppsspp/NativeSurfaceView.java @@ -16,7 +16,11 @@ import android.os.Handler; import android.util.Log; import android.view.MotionEvent; import android.view.SurfaceView; -import com.bda.controller.*; + +import com.bda.controller.Controller; +import com.bda.controller.ControllerListener; +import com.bda.controller.KeyEvent; +import com.bda.controller.StateEvent; public class NativeSurfaceView extends SurfaceView implements SensorEventListener, ControllerListener { private static String TAG = "NativeSurfaceView"; diff --git a/android/src/org/ppsspp/ppsspp/TextRenderer.java b/android/src/org/ppsspp/ppsspp/TextRenderer.java index 7ecdeb9a7f..6e753c8739 100644 --- a/android/src/org/ppsspp/ppsspp/TextRenderer.java +++ b/android/src/org/ppsspp/ppsspp/TextRenderer.java @@ -56,10 +56,15 @@ public class TextRenderer { total.y = (int) (p.descent() - p.ascent()) * lines.length + 2; // Returning a 0 size can create problems when the caller // uses the measurement to create a texture. + // Also, clamp to a reasonable maximum size. if (total.x < 1) total.x = 1; if (total.y < 1) total.y = 1; + if (total.x > 2048) + total.x = 2048; + if (total.y > 2048) + total.y = 2048; return total; } diff --git a/assets/compat.ini b/assets/compat.ini index f391dbc5da..92e41445f1 100644 --- a/assets/compat.ini +++ b/assets/compat.ini @@ -437,3 +437,81 @@ ULES00940 = true # SR2 ULJS00250 = true ULJS19048 = true NPJH50107 = true + + +[BlockTransferAllowCreateFB] +NPJH50686 = true # Digimon Adventures (JP, and English patches...) +ULJS00078 = true # MotoGP +ULUS10153 = true # MotoGP +UCES00373 = true # MotoGP + +[YugiohSaveFix] +# The cause of Yu-gi-oh series 's bad save (cannot save) are load "save status" and use cwcheat, +# but the real cause still unknown. #7914 + +# Yu-Gi-Oh! Duel Monsters GX: Tag Force +ULJM05151 = true +ULES00600 = true +ULUS10136 = true + +# Yu-Gi-Oh! Duel Monsters GX: Tag Force 2 +ULUS10302 = true +ULJM05260 = true +ULES00925 = true +ULES00926 = true + +# Yu-Gi-Oh! Duel Monsters GX: Tag Force 3 +ULES01183 = true +ULJM05373 = true + +# Yu-Gi-Oh! 5D's Tag Force 4 +ULUS10481 = true +ULJM05479 = true +ULES01362 = true + +# Yu-Gi-Oh! 5D's Tag Force 5 +ULUS10555 = true +ULJM05734 = true + +# Yu-Gi-Oh! 5D's Tag Force 6 +ULJM-05940 = true +NPJH-50794 = true + +# Yu-Gi-Oh! 5D's Tag Force +ULJM05940 = true + +# Yu-Gi-Oh! ARC-V Tag Force Special +NPJH00142 = true + +[ForceUMDDelay] +# F1 2006 won't boot at all with our standard unrealistically fast timing. +UCES00238 = true +UCJS10045 = true + +[ForceMax60FPS] +# The GOW games are very heavy and render as fast as they can. They benefit greatly from +# capping the framerate at 60fps. + +# GOW : Ghost of Sparta +UCUS98737 = true +UCAS40323 = true +NPHG00092 = true +NPEG00044 = true +NPJG00120 = true +UCJS10114 = true +UCES01401 = true +# GOW : Chains Of Olympus +UCUS98653 = true +UCUS98705 = true +UCES00842 = true +ULJM05438 = true +ULJM05348 = true +UCKS45084 = true +NPUG80325 = true +NPEG00023 = true +NPHG00028 = true +NPJG00120 = true + +# F1 2006 has extremely long loading times if we don't limit the framerate. +UCES00238 = true +UCJS10045 = true diff --git a/assets/gamecontrollerdb.txt b/assets/gamecontrollerdb.txt index fbf1009a11..885bb1c744 100644 --- a/assets/gamecontrollerdb.txt +++ b/assets/gamecontrollerdb.txt @@ -189,3 +189,5 @@ bd1200000000000015d0000000000000,Tomee SNES USB Controller,x:b3,a:b2,b:b1,y:b0,b 050000004c050000cc09000001000000,Sony DualShock 4 V2 BT,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a5,lefttrigger:a3,righttrigger:a4,platform:Linux, 03000000bc2000006412000011010000,BETOP CONTROLLER,a:b2,b:b1,y:b0,x:b3,start:b9,guide:b30,back:b8,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftshoulder:b4,rightshoulder:b5,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,platform:Linux, 05000000c82d00000161000000010000,8Bitdo SN30 Pro,platform:Linux,a:b1,b:b0,x:b4,y:b3,back:b10,guide:b2,start:b11,leftstick:b13,rightstick:b14,leftshoulder:b6,rightshoulder:b7,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a5,righttrigger:a4, +03000000380700008532000010010000,MadCatz Madcatz Fightpad,platform:Linux,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b8,leftshoulder:b4,rightshoulder:b6,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,lefttrigger:b5,righttrigger:b7, +030000000d0f0000ee00000011010000,HORI CO.,LTD. HORIPAD mini4,platform:Linux,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7, diff --git a/assets/lang b/assets/lang index f60be494a4..f97aa5d000 160000 --- a/assets/lang +++ b/assets/lang @@ -1 +1 @@ -Subproject commit f60be494a43a49fd7ff61603e132c1e24c160d88 +Subproject commit f97aa5d000b0a27e27b88b0072ccf932de506eae diff --git a/build.gradle b/build.gradle index 2b29ba2521..62ec80d1ce 100644 --- a/build.gradle +++ b/build.gradle @@ -5,7 +5,7 @@ buildscript { jcenter() } dependencies { - classpath 'com.android.tools.build:gradle:3.2.1' + classpath 'com.android.tools.build:gradle:3.3.1' } } diff --git a/ext/CMakeLists.txt b/ext/CMakeLists.txt index ade6594e8f..b259a6f059 100644 --- a/ext/CMakeLists.txt +++ b/ext/CMakeLists.txt @@ -2,7 +2,7 @@ set(ARMIPS_REGEXP OFF CACHE BOOL "" FORCE) add_subdirectory(armips) if(NOT USING_GLES2) - add_subdirectory(glew) + add_subdirectory(glew) endif() set(ENABLE_GLSLANG_BINARIES OFF CACHE BOOL "let's not build binaries we don't need" FORCE) @@ -12,6 +12,6 @@ add_subdirectory(glslang) add_subdirectory(snappy) add_subdirectory(udis86) add_subdirectory(SPIRV-Cross-build) -if(NOT IOS) -add_subdirectory(discord-rpc-build) +if(USE_DISCORD AND NOT IOS) + add_subdirectory(discord-rpc-build) endif() diff --git a/ext/SPIRV-Cross.vcxproj b/ext/SPIRV-Cross.vcxproj index a3dc1386f3..3e1003593c 100644 --- a/ext/SPIRV-Cross.vcxproj +++ b/ext/SPIRV-Cross.vcxproj @@ -94,6 +94,7 @@ false MultiThreadedDebug true + ProgramDatabase Windows @@ -109,6 +110,7 @@ false MultiThreadedDebug true + ProgramDatabase Windows diff --git a/ext/armips b/ext/armips index 9efe336728..7885552b20 160000 --- a/ext/armips +++ b/ext/armips @@ -1 +1 @@ -Subproject commit 9efe3367284d2d1eeb14fc302a2c12c36e3e255e +Subproject commit 7885552b208493a6a0f21663770c446c3ba65576 diff --git a/ext/discord-rpc-build/discord-rpc.vcxproj b/ext/discord-rpc-build/discord-rpc.vcxproj index 771c6e4f7d..0ef8d3d62a 100644 --- a/ext/discord-rpc-build/discord-rpc.vcxproj +++ b/ext/discord-rpc-build/discord-rpc.vcxproj @@ -1,4 +1,4 @@ - +ï»ż @@ -129,6 +129,7 @@ ..\discord-rpc\include;..\discord-rpc\src;..\rapidjson\include MultiThreadedDebug true + ProgramDatabase Windows @@ -144,6 +145,7 @@ ..\discord-rpc\include;..\discord-rpc\src;..\rapidjson\include MultiThreadedDebug true + ProgramDatabase Windows diff --git a/ext/glslang b/ext/glslang index 29619b2312..9983f99e87 160000 --- a/ext/glslang +++ b/ext/glslang @@ -1 +1 @@ -Subproject commit 29619b2312f7bc862221749f3f4d37c3e6a0dee2 +Subproject commit 9983f99e87ab0b6608b236ea59bcf873f90e1435 diff --git a/ext/glslang-build/Android.mk b/ext/glslang-build/Android.mk index 47e232c5cf..4b642c6586 100644 --- a/ext/glslang-build/Android.mk +++ b/ext/glslang-build/Android.mk @@ -50,6 +50,7 @@ LOCAL_SRC_FILES := \ ../glslang/SPIRV/InReadableOrder.cpp \ ../glslang/SPIRV/SpvBuilder.cpp \ ../glslang/SPIRV/SPVRemapper.cpp \ + ../glslang/SPIRV/SpvPostProcess.cpp \ ../glslang/OGLCompilersDLL/InitializeDll.cpp diff --git a/ext/glslang.vcxproj b/ext/glslang.vcxproj index 95eb3ab485..2d3af8be1d 100644 --- a/ext/glslang.vcxproj +++ b/ext/glslang.vcxproj @@ -80,6 +80,7 @@ Default glslang/glslang/OSDependent/Windows;glslang/glslang/MachineIndependent true + ProgramDatabase Windows @@ -98,6 +99,7 @@ false Default true + ProgramDatabase Windows @@ -191,6 +193,7 @@ + diff --git a/ext/glslang.vcxproj.filters b/ext/glslang.vcxproj.filters index d37c8c805e..2e0e95ab88 100644 --- a/ext/glslang.vcxproj.filters +++ b/ext/glslang.vcxproj.filters @@ -140,6 +140,9 @@ glslang + + SPIRV + diff --git a/ext/libarmips.vcxproj b/ext/libarmips.vcxproj index 4662b65ba3..411af13881 100644 --- a/ext/libarmips.vcxproj +++ b/ext/libarmips.vcxproj @@ -139,6 +139,7 @@ true + ProgramDatabase Windows @@ -159,6 +160,7 @@ true + ProgramDatabase Windows diff --git a/ext/libkirk/libkirk.vcxproj b/ext/libkirk/libkirk.vcxproj index 86f944aea9..bdaa0b01c3 100644 --- a/ext/libkirk/libkirk.vcxproj +++ b/ext/libkirk/libkirk.vcxproj @@ -77,6 +77,7 @@ false MultiThreadedDebug ../../Common/DbgNew.h + ProgramDatabase true @@ -92,6 +93,7 @@ false ../../Common/DbgNew.h _CRTDBG_MAP_ALLOC;_USING_V110_SDK71_;%(PreprocessorDefinitions) + ProgramDatabase true diff --git a/ext/native/base/NKCodeFromQt.h b/ext/native/base/NKCodeFromQt.h index 1d2dd2cb65..ee09d63417 100644 --- a/ext/native/base/NKCodeFromQt.h +++ b/ext/native/base/NKCodeFromQt.h @@ -98,5 +98,6 @@ static const std::map KeyMapRawQttoNative = InitConstMap (Qt::Key_Up, NKCODE_DPAD_UP) (Qt::Key_Right, NKCODE_DPAD_RIGHT) (Qt::Key_Down, NKCODE_DPAD_DOWN) - (Qt::Key_Back, NKCODE_BACK); + (Qt::Key_Back, NKCODE_BACK) + (Qt::Key_Backspace, NKCODE_DEL); diff --git a/ext/native/base/buffer.cpp b/ext/native/base/buffer.cpp index 9b268976bb..8e48848319 100644 --- a/ext/native/base/buffer.cpp +++ b/ext/native/base/buffer.cpp @@ -146,8 +146,12 @@ bool Buffer::FlushToFile(const char *filename) { return true; } -bool Buffer::FlushSocket(uintptr_t sock) { +bool Buffer::FlushSocket(uintptr_t sock, double timeout) { for (size_t pos = 0, end = data_.size(); pos < end; ) { + if (timeout >= 0.0 && !fd_util::WaitUntilReady(sock, timeout, true)) { + ELOG("FlushSocket timed out"); + return false; + } int sent = send(sock, &data_[pos], (int)(end - pos), MSG_NOSIGNAL); if (sent < 0) { ELOG("FlushSocket failed"); @@ -156,7 +160,7 @@ bool Buffer::FlushSocket(uintptr_t sock) { pos += sent; // Buffer full, don't spin. - if (sent == 0) { + if (sent == 0 && timeout < 0.0) { sleep_ms(1); } } diff --git a/ext/native/base/buffer.h b/ext/native/base/buffer.h index bca84d9ba7..b34901fb17 100644 --- a/ext/native/base/buffer.h +++ b/ext/native/base/buffer.h @@ -59,12 +59,12 @@ class Buffer { // Simple I/O. - // Writes the entire buffer to the file descriptor. Also resets the - // size to zero. On failure, data remains in buffer and nothing is - // written. + // Writes the entire buffer to the file descriptor. Also resets the + // size to zero. On failure, data remains in buffer and nothing is + // written. bool Flush(int fd); bool FlushToFile(const char *filename); - bool FlushSocket(uintptr_t sock); // Windows portability + bool FlushSocket(uintptr_t sock, double timeout = -1.0); // Windows portability bool ReadAll(int fd, int hintSize = 0); bool ReadAllWithProgress(int fd, int knownSize, float *progress, bool *cancelled); diff --git a/ext/native/file/file_util.cpp b/ext/native/file/file_util.cpp index be654ef9c3..0882213e9b 100644 --- a/ext/native/file/file_util.cpp +++ b/ext/native/file/file_util.cpp @@ -230,7 +230,6 @@ size_t getFilesInDir(const char *directory, std::vector *files, const WIN32_FIND_DATA ffd; HANDLE hFind = FindFirstFileEx((ConvertUTF8ToWString(directory) + L"\\*").c_str(), FindExInfoStandard, &ffd, FindExSearchNameMatch, NULL, 0); if (hFind == INVALID_HANDLE_VALUE) { - FindClose(hFind); return 0; } // windows loop @@ -238,8 +237,6 @@ size_t getFilesInDir(const char *directory, std::vector *files, const { const std::string virtualName = ConvertWStringToUTF8(ffd.cFileName); #else - struct dirent_large { struct dirent entry; char padding[FILENAME_MAX+1]; }; - struct dirent_large diren; struct dirent *result = NULL; //std::string directoryWithSlash = directory; @@ -250,7 +247,7 @@ size_t getFilesInDir(const char *directory, std::vector *files, const if (!dirp) return 0; // non windows loop - while (!readdir_r(dirp, (dirent*) &diren, &result) && result) + while ((result = readdir(dirp))) { const std::string virtualName(result->d_name); #endif diff --git a/ext/native/gfx_es2/draw_buffer.cpp b/ext/native/gfx_es2/draw_buffer.cpp index 7f343ee928..603d49ee8e 100644 --- a/ext/native/gfx_es2/draw_buffer.cpp +++ b/ext/native/gfx_es2/draw_buffer.cpp @@ -80,10 +80,6 @@ void DrawBuffer::Begin(Draw::Pipeline *program) { count_ = 0; } -void DrawBuffer::End() { - // Currently does nothing, but call it! -} - void DrawBuffer::Flush(bool set_blend_state) { using namespace Draw; if (count_ == 0) diff --git a/ext/native/gfx_es2/draw_buffer.h b/ext/native/gfx_es2/draw_buffer.h index e797152554..788e4a125f 100644 --- a/ext/native/gfx_es2/draw_buffer.h +++ b/ext/native/gfx_es2/draw_buffer.h @@ -63,7 +63,7 @@ public: ~DrawBuffer(); void Begin(Draw::Pipeline *pipeline); - void End(); + void Flush(bool set_blend_state = true); // TODO: Enforce these. Now Init is autocalled and shutdown not called. void Init(Draw::DrawContext *t3d, Draw::Pipeline *pipeline); @@ -74,8 +74,6 @@ public: int Count() const { return count_; } - void Flush(bool set_blend_state = true); - void Rect(float x, float y, float w, float h, uint32_t color, int align = ALIGN_TOPLEFT); void hLine(float x1, float y, float x2, uint32_t color); void vLine(float x, float y1, float y2, uint32_t color); @@ -99,7 +97,7 @@ public: void V(float x, float y, float z, uint32_t color, float u, float v); void V(float x, float y, uint32_t color, float u, float v) { - V(x, y, 0.0f, color, u, v); + V(x, y, curZ_, color, u, v); } void Circle(float x, float y, float radius, float thickness, int segments, float startAngle, uint32_t color, float u_mul); @@ -168,6 +166,10 @@ public: alphaStack_.pop_back(); } + void SetCurZ(float curZ) { + curZ_ = curZ; + } + private: struct Vertex { float x, y, z; @@ -193,5 +195,7 @@ private: bool inited_; float fontscalex; float fontscaley; + + float curZ_ = 0.0f; }; diff --git a/ext/native/gfx_es2/draw_text_android.cpp b/ext/native/gfx_es2/draw_text_android.cpp index 7059fab399..afb9bf6104 100644 --- a/ext/native/gfx_es2/draw_text_android.cpp +++ b/ext/native/gfx_es2/draw_text_android.cpp @@ -172,7 +172,8 @@ void TextDrawerAndroid::DrawString(DrawBuffer &target, const char *str, float x, if (iter != cache_.end()) { entry = iter->second.get(); entry->lastUsedFrame = frameCount_; - draw_->BindTexture(0, entry->texture); + if (entry->texture) + draw_->BindTexture(0, entry->texture); } else { double size = 0.0; auto iter = fontMap_.find(fontHash_); @@ -195,8 +196,10 @@ void TextDrawerAndroid::DrawString(DrawBuffer &target, const char *str, float x, env_->DeleteLocalRef(jstr); entry = new TextStringEntry(); - entry->bmWidth = entry->width = imageWidth; - entry->bmHeight = entry->height = imageHeight; + entry->bmWidth = imageWidth; + entry->width = imageWidth; + entry->bmHeight = imageHeight; + entry->height = imageHeight; entry->lastUsedFrame = frameCount_; TextureDesc desc{}; @@ -206,6 +209,7 @@ void TextDrawerAndroid::DrawString(DrawBuffer &target, const char *str, float x, desc.height = entry->bmHeight; desc.depth = 1; desc.mipLevels = 1; + desc.generateMips = false; desc.tag = "TextDrawer"; uint16_t *bitmapData = new uint16_t[entry->bmWidth * entry->bmHeight]; @@ -224,13 +228,17 @@ void TextDrawerAndroid::DrawString(DrawBuffer &target, const char *str, float x, entry->texture = draw_->CreateTexture(desc); delete[] bitmapData; cache_[key] = std::unique_ptr(entry); - draw_->BindTexture(0, entry->texture); + if (entry->texture) { + draw_->BindTexture(0, entry->texture); + } } float w = entry->bmWidth * fontScaleX_ * dpiScale_; float h = entry->bmHeight * fontScaleY_ * dpiScale_; DrawBuffer::DoAlign(align, &x, &y, &w, &h); - target.DrawTexRect(x, y, x + w, y + h, 0.0f, 0.0f, 1.0f, 1.0f, color); - target.Flush(true); + if (entry->texture) { + target.DrawTexRect(x, y, x + w, y + h, 0.0f, 0.0f, 1.0f, 1.0f, color); + target.Flush(true); + } } void TextDrawerAndroid::ClearCache() { diff --git a/ext/native/gfx_es2/gpu_features.cpp b/ext/native/gfx_es2/gpu_features.cpp index 35b1e421c9..3d81f59287 100644 --- a/ext/native/gfx_es2/gpu_features.cpp +++ b/ext/native/gfx_es2/gpu_features.cpp @@ -98,11 +98,6 @@ void ProcessGPUFeatures() { DLOG("Checking for GL driver bugs... vendor=%i model='%s'", (int)gl_extensions.gpuVendor, gl_extensions.model); - // Should be table driven instead, this is a quick hack for Galaxy Y - if (System_GetProperty(SYSPROP_NAME) == "samsung:GT-S5360") { - gl_extensions.bugs |= BUG_FBO_UNUSABLE; - } - if (gl_extensions.gpuVendor == GPU_VENDOR_IMGTEC) { if (!strcmp(gl_extensions.model, "PowerVR SGX 543") || !strcmp(gl_extensions.model, "PowerVR SGX 540") || @@ -114,13 +109,6 @@ void ProcessGPUFeatures() { WLOG("GL DRIVER BUG: PVR with bad precision"); gl_extensions.bugs |= BUG_PVR_SHADER_PRECISION_BAD; } - gl_extensions.bugs |= BUG_PVR_GENMIPMAP_HEIGHT_GREATER; - } - - // TODO: Make this check more lenient. Disabled for all right now - // because it murders performance on Mali. - if (gl_extensions.gpuVendor != GPU_VENDOR_NVIDIA) { - gl_extensions.bugs |= BUG_ANY_MAP_BUFFER_RANGE_SLOW; } } @@ -171,6 +159,8 @@ void CheckGLExtensions() { } else if (vendor == "Broadcom") { gl_extensions.gpuVendor = GPU_VENDOR_BROADCOM; // Just for reference: Galaxy Y has renderer == "VideoCore IV HW" + } else if (vendor == "Vivante Corporation") { + gl_extensions.gpuVendor = GPU_VENDOR_VIVANTE; } else { gl_extensions.gpuVendor = GPU_VENDOR_UNKNOWN; } @@ -579,7 +569,7 @@ std::string ApplyGLSLPrelude(const std::string &source, uint32_t stage) { std::string temp; std::string version = ""; if (!gl_extensions.IsGLES && gl_extensions.IsCoreContext) { - // We need to add a corresponding #version. Apple drives fail without an exact match. + // We need to add a corresponding #version. Apple drivers fail without an exact match. version = StringFromFormat("#version %d\n", gl_extensions.GLSLVersion()); } if (stage == GL_FRAGMENT_SHADER) { diff --git a/ext/native/gfx_es2/gpu_features.h b/ext/native/gfx_es2/gpu_features.h index 6764d08105..94ba18912a 100644 --- a/ext/native/gfx_es2/gpu_features.h +++ b/ext/native/gfx_es2/gpu_features.h @@ -15,15 +15,15 @@ enum { GPU_VENDOR_IMGTEC = 5, GPU_VENDOR_QUALCOMM = 6, GPU_VENDOR_BROADCOM = 7, + GPU_VENDOR_VIVANTE = 8, GPU_VENDOR_UNKNOWN = 0, }; +// TODO: Move to Draw::Bugs enum { BUG_FBO_UNUSABLE = 1, BUG_PVR_SHADER_PRECISION_BAD = 2, BUG_PVR_SHADER_PRECISION_TERRIBLE = 4, - BUG_PVR_GENMIPMAP_HEIGHT_GREATER = 8, - BUG_ANY_MAP_BUFFER_RANGE_SLOW = 16, }; // Extensions to look at using: diff --git a/ext/native/math/fast/fast_math.c b/ext/native/math/fast/fast_math.c index 5363a32830..8976122646 100644 --- a/ext/native/math/fast/fast_math.c +++ b/ext/native/math/fast/fast_math.c @@ -5,8 +5,10 @@ void InitFastMath(int enableNEON) { // Every architecture has its own define. This needs to be added to. if (enableNEON) { +#ifndef _MSC_VER #if PPSSPP_ARCH(ARM_NEON) && !PPSSPP_ARCH(ARM64) fast_matrix_mul_4x4 = &fast_matrix_mul_4x4_neon; +#endif #endif } } diff --git a/ext/native/native.vcxproj b/ext/native/native.vcxproj index 21b09ed6d7..405888b732 100644 --- a/ext/native/native.vcxproj +++ b/ext/native/native.vcxproj @@ -87,6 +87,7 @@ false MultiThreadedDebug ../../Common/DbgNew.h + ProgramDatabase Windows @@ -109,6 +110,7 @@ MultiThreadedDebug false ../../Common/DbgNew.h + ProgramDatabase Windows diff --git a/ext/native/net/http_client.cpp b/ext/native/net/http_client.cpp index 3cb6967326..22e5fb9c56 100644 --- a/ext/native/net/http_client.cpp +++ b/ext/native/net/http_client.cpp @@ -283,7 +283,7 @@ int Client::SendRequestWithData(const char *method, const char *resource, const userAgent_, otherHeaders ? otherHeaders : ""); buffer.Append(data); - bool flushed = buffer.FlushSocket(sock()); + bool flushed = buffer.FlushSocket(sock(), dataTimeout_); if (!flushed) { return -1; // TODO error code. } @@ -292,6 +292,10 @@ int Client::SendRequestWithData(const char *method, const char *resource, const int Client::ReadResponseHeaders(Buffer *readbuf, std::vector &responseHeaders, float *progress) { // Snarf all the data we can into RAM. A little unsafe but hey. + if (dataTimeout_ >= 0.0 && !fd_util::WaitUntilReady(sock(), dataTimeout_, false)) { + ELOG("HTTP headers timed out"); + return -1; + } if (readbuf->Read(sock(), 4096) < 0) { ELOG("Failed to read HTTP headers :("); return -1; diff --git a/ext/native/net/http_client.h b/ext/native/net/http_client.h index ac3d26ed97..348cf33d93 100644 --- a/ext/native/net/http_client.h +++ b/ext/native/net/http_client.h @@ -75,8 +75,14 @@ public: // If your response contains a response, you must read it. int ReadResponseEntity(Buffer *readbuf, const std::vector &responseHeaders, Buffer *output, float *progress = nullptr, bool *cancelled = nullptr); + void SetDataTimeout(double t) { + dataTimeout_ = t; + } + +protected: const char *userAgent_; const char *httpVersion_; + double dataTimeout_ = -1.0; }; // Not particularly efficient, but hey - it's a background download, that's pretty cool :P diff --git a/ext/native/net/http_server.cpp b/ext/native/net/http_server.cpp index f7cae6cd30..d6faa8558c 100644 --- a/ext/native/net/http_server.cpp +++ b/ext/native/net/http_server.cpp @@ -1,4 +1,5 @@ #include "base/timeutil.h" +#include "ppsspp_config.h" #ifdef _WIN32 @@ -23,6 +24,10 @@ #endif +#if PPSSPP_PLATFORM(UWP) +#define in6addr_any IN6ADDR_ANY_INIT +#endif + #include #include diff --git a/ext/native/net/resolve.cpp b/ext/native/net/resolve.cpp index ec7d17f1d1..60182e4d64 100644 --- a/ext/native/net/resolve.cpp +++ b/ext/native/net/resolve.cpp @@ -43,40 +43,6 @@ void Shutdown() #endif } -char *DNSResolveTry(const char *host, const char **err) -{ - struct hostent *hent; - if((hent = gethostbyname(host)) == NULL) - { - *err = "Can't get IP"; - return NULL; - } - int iplen = 15; //XXX.XXX.XXX.XXX - char *ip = (char *)malloc(iplen+1); - memset(ip, 0, iplen+1); - char *iptoa = inet_ntoa(*(in_addr *)hent->h_addr_list[0]); - if (iptoa == NULL) - { - *err = "Can't resolve host"; - free(ip); - return NULL; - } - strncpy(ip, iptoa, iplen); - return ip; -} - -char *DNSResolve(const char *host) -{ - const char *err; - char *ip = DNSResolveTry(host, &err); - if (ip == NULL) - { - perror(err); - exit(1); - } - return ip; -} - bool DNSResolve(const std::string &host, const std::string &service, addrinfo **res, std::string &error, DNSType type) { addrinfo hints = {0}; diff --git a/ext/native/net/url.cpp b/ext/native/net/url.cpp index 522adc6709..a2735cf124 100644 --- a/ext/native/net/url.cpp +++ b/ext/native/net/url.cpp @@ -20,7 +20,7 @@ void Url::Split() { host_ = url_.substr(colonSlashSlash + 3, sep - colonSlashSlash - 3); resource_ = url_.substr(sep); // include the slash! - size_t portsep = host_.find(':'); + size_t portsep = host_.rfind(':'); if (portsep != host_.npos) { port_ = atoi(host_.substr(portsep + 1).c_str()); host_ = host_.substr(0, portsep); diff --git a/ext/native/thin3d/GLQueueRunner.cpp b/ext/native/thin3d/GLQueueRunner.cpp index 49031eafca..cf4dd780dd 100644 --- a/ext/native/thin3d/GLQueueRunner.cpp +++ b/ext/native/thin3d/GLQueueRunner.cpp @@ -66,8 +66,10 @@ void GLQueueRunner::DestroyDeviceObjects() { glDeleteVertexArrays(1, &globalVAO_); } delete[] readbackBuffer_; + readbackBuffer_ = nullptr; readbackBufferSize_ = 0; delete[] tempBuffer_; + tempBuffer_ = nullptr; tempBufferSize_ = 0; CHECK_GL_ERROR_IF_DEBUG(); } @@ -171,8 +173,10 @@ void GLQueueRunner::RunInitSteps(const std::vector &steps, bool ski GLRProgram *program = step.create_program.program; program->program = glCreateProgram(); _assert_msg_(G3D, step.create_program.num_shaders > 0, "Can't create a program with zero shaders"); + bool anyFailed = false; for (int j = 0; j < step.create_program.num_shaders; j++) { _dbg_assert_msg_(G3D, step.create_program.shaders[j]->shader, "Can't create a program with a null shader"); + anyFailed = anyFailed || step.create_program.shaders[j]->failed; glAttachShader(program->program, step.create_program.shaders[j]->shader); } @@ -208,7 +212,8 @@ void GLQueueRunner::RunInitSteps(const std::vector &steps, bool ski std::string fsDesc = fs ? (fs->desc + (fs->failed ? " (failed)" : "")) : "(none)"; const char *vsCode = vs->code.c_str(); const char *fsCode = fs ? fs->code.c_str() : "(none)"; - Reporting::ReportMessage("Error in shader program link: info: %s\nfs: %s\n%s\nvs: %s\n%s", infoLog.c_str(), fsDesc.c_str(), fsCode, vsDesc.c_str(), vsCode); + if (!anyFailed) + Reporting::ReportMessage("Error in shader program link: info: %s\nfs: %s\n%s\nvs: %s\n%s", infoLog.c_str(), fsDesc.c_str(), fsCode, vsDesc.c_str(), vsCode); ELOG("Could not link program:\n %s", infoLog.c_str()); ERROR_LOG(G3D, "VS desc:\n%s", vsDesc.c_str()); @@ -244,6 +249,7 @@ void GLQueueRunner::RunInitSteps(const std::vector &steps, bool ski switch (init.type) { case 0: glUniform1i(uniform, init.value); + break; } } } @@ -383,31 +389,69 @@ void GLQueueRunner::InitCreateFramebuffer(const GLRInitStep &step) { #endif CHECK_GL_ERROR_IF_DEBUG(); + auto initFBOTexture = [&](GLRTexture &tex, GLint internalFormat, GLenum format, GLenum type, bool linear) { + glGenTextures(1, &tex.texture); + tex.target = GL_TEXTURE_2D; + tex.maxLod = 0.0f; + + // Create the surfaces. + glBindTexture(GL_TEXTURE_2D, tex.texture); + glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, fbo->width, fbo->height, 0, format, type, nullptr); + + tex.wrapS = GL_CLAMP_TO_EDGE; + tex.wrapT = GL_CLAMP_TO_EDGE; + tex.magFilter = linear ? GL_LINEAR : GL_NEAREST; + tex.minFilter = linear ? GL_LINEAR : GL_NEAREST; + tex.canWrap = isPowerOf2(fbo->width) && isPowerOf2(fbo->height); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, tex.wrapS); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, tex.wrapT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, tex.magFilter); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, tex.minFilter); + if (!gl_extensions.IsGLES || gl_extensions.GLES3) { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0); + } + }; + // Color texture is same everywhere glGenFramebuffers(1, &fbo->handle); - glGenTextures(1, &fbo->color_texture.texture); - fbo->color_texture.target = GL_TEXTURE_2D; - fbo->color_texture.maxLod = 0.0f; + initFBOTexture(fbo->color_texture, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, true); - // Create the surfaces. - glBindTexture(GL_TEXTURE_2D, fbo->color_texture.texture); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, fbo->width, fbo->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); +retry_depth: + if (!fbo->z_stencil_) { + ILOG("Creating %i x %i FBO using no depth", fbo->width, fbo->height); - fbo->color_texture.wrapS = GL_CLAMP_TO_EDGE; - fbo->color_texture.wrapT = GL_CLAMP_TO_EDGE; - fbo->color_texture.magFilter = GL_LINEAR; - fbo->color_texture.minFilter = GL_LINEAR; - fbo->color_texture.canWrap = isPowerOf2(fbo->width) && isPowerOf2(fbo->height); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, fbo->color_texture.wrapS); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, fbo->color_texture.wrapT); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, fbo->color_texture.magFilter); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, fbo->color_texture.minFilter); - if (!gl_extensions.IsGLES || gl_extensions.GLES3) { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0); - } + fbo->z_stencil_buffer = 0; + fbo->stencil_buffer = 0; + fbo->z_buffer = 0; - if (gl_extensions.IsGLES) { - if (gl_extensions.OES_packed_depth_stencil) { + // Bind it all together + glBindFramebuffer(GL_FRAMEBUFFER, fbo->handle); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fbo->color_texture.texture, 0); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0); + } else if (gl_extensions.IsGLES) { + if (gl_extensions.OES_packed_depth_stencil && (gl_extensions.OES_depth_texture || gl_extensions.GLES3)) { + ILOG("Creating %i x %i FBO using DEPTH24_STENCIL8 texture", fbo->width, fbo->height); + fbo->z_stencil_buffer = 0; + fbo->stencil_buffer = 0; + fbo->z_buffer = 0; + + if (gl_extensions.GLES3) { + initFBOTexture(fbo->z_stencil_texture, GL_DEPTH24_STENCIL8, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, false); + } else { + initFBOTexture(fbo->z_stencil_texture, GL_DEPTH_STENCIL, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, false); + } + + // Bind it all together + glBindFramebuffer(GL_FRAMEBUFFER, fbo->handle); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fbo->color_texture.texture, 0); + if (gl_extensions.GLES3) { + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, fbo->z_stencil_texture.texture, 0); + } else { + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, fbo->z_stencil_texture.texture, 0); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, fbo->z_stencil_texture.texture, 0); + } + } else if (gl_extensions.OES_packed_depth_stencil) { ILOG("Creating %i x %i FBO using DEPTH24_STENCIL8", fbo->width, fbo->height); // Standard method fbo->stencil_buffer = 0; @@ -443,6 +487,18 @@ void GLQueueRunner::InitCreateFramebuffer(const GLRInitStep &step) { glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, fbo->z_buffer); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, fbo->stencil_buffer); } + } else if (gl_extensions.VersionGEThan(3, 0)) { + ILOG("Creating %i x %i FBO using DEPTH24_STENCIL8 texture", fbo->width, fbo->height); + fbo->z_stencil_buffer = 0; + fbo->stencil_buffer = 0; + fbo->z_buffer = 0; + + initFBOTexture(fbo->z_stencil_texture, GL_DEPTH24_STENCIL8, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, false); + + // Bind it all together + glBindFramebuffer(GL_FRAMEBUFFER, fbo->handle); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fbo->color_texture.texture, 0); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, fbo->z_stencil_texture.texture, 0); } else { fbo->stencil_buffer = 0; fbo->z_buffer = 0; @@ -459,6 +515,13 @@ void GLQueueRunner::InitCreateFramebuffer(const GLRInitStep &step) { } GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); + if (status != GL_FRAMEBUFFER_COMPLETE && !fbo->z_buffer) { + CHECK_GL_ERROR_IF_DEBUG(); + // Uh oh, maybe we need a z/stencil. Platforms sometimes, right? + fbo->z_stencil_ = true; + goto retry_depth; + } + switch (status) { case GL_FRAMEBUFFER_COMPLETE: // ILOG("Framebuffer verified complete."); @@ -467,7 +530,7 @@ void GLQueueRunner::InitCreateFramebuffer(const GLRInitStep &step) { ELOG("GL_FRAMEBUFFER_UNSUPPORTED"); break; case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT: - ELOG("GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT "); + ELOG("GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT"); break; default: FLOG("Other framebuffer error: %i", status); @@ -889,10 +952,14 @@ void GLQueueRunner::PerformRenderPass(const GLRStep &step) { } if (c.bind_fb_texture.aspect == GL_COLOR_BUFFER_BIT) { if (curTex[slot] != &c.bind_fb_texture.framebuffer->color_texture) - glBindTexture(GL_TEXTURE_2D, c.bind_fb_texture.framebuffer->color_texture.texture); + glBindTexture(GL_TEXTURE_2D, c.bind_fb_texture.framebuffer->color_texture.texture); curTex[slot] = &c.bind_fb_texture.framebuffer->color_texture; + } else if (c.bind_fb_texture.aspect == GL_DEPTH_BUFFER_BIT) { + if (curTex[slot] != &c.bind_fb_texture.framebuffer->z_stencil_texture) + glBindTexture(GL_TEXTURE_2D, c.bind_fb_texture.framebuffer->z_stencil_texture.texture); + curTex[slot] = &c.bind_fb_texture.framebuffer->z_stencil_texture; } else { - // TODO: Depth texturing? + // TODO: Stencil texturing? curTex[slot] = nullptr; } CHECK_GL_ERROR_IF_DEBUG(); @@ -1241,7 +1308,7 @@ void GLQueueRunner::PerformReadback(const GLRStep &pass) { if (!gl_extensions.IsGLES || gl_extensions.GLES3) { glPixelStorei(GL_PACK_ROW_LENGTH, 0); } - if (convert) { + if (convert && tempBuffer_ && readbackBuffer_) { ConvertFromRGBA8888(readbackBuffer_, tempBuffer_, pixelStride, pixelStride, rect.w, rect.h, pass.readback.dstFormat); } @@ -1301,6 +1368,10 @@ void GLQueueRunner::CopyReadbackBuffer(int width, int height, Draw::DataFormat s // don't usually provide very optimized conversion implementations, though some do. // Just need to be careful about dithering, which may break Danganronpa. int bpp = (int)Draw::DataFormatSizeInBytes(destFormat); + if (!readbackBuffer_ || bpp <= 0 || !pixels) { + // Something went wrong during the read and no readback buffer was allocated, probably. + return; + } for (int y = 0; y < height; y++) { memcpy(pixels + y * pixelStride * bpp, readbackBuffer_ + y * width * bpp, width * bpp); } @@ -1449,36 +1520,30 @@ GLRFramebuffer::~GLRFramebuffer() { return; CHECK_GL_ERROR_IF_DEBUG(); - if (gl_extensions.ARB_framebuffer_object || gl_extensions.IsGLES) { - if (handle) { + if (handle) { + if (gl_extensions.ARB_framebuffer_object || gl_extensions.IsGLES) { glBindFramebuffer(GL_FRAMEBUFFER, handle); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0); glBindFramebuffer(GL_FRAMEBUFFER, g_defaultFBO); glDeleteFramebuffers(1, &handle); - } - if (z_stencil_buffer) - glDeleteRenderbuffers(1, &z_stencil_buffer); - if (z_buffer) - glDeleteRenderbuffers(1, &z_buffer); - if (stencil_buffer) - glDeleteRenderbuffers(1, &stencil_buffer); - } else if (gl_extensions.EXT_framebuffer_object) { #ifndef USING_GLES2 - if (handle) { + } else if (gl_extensions.EXT_framebuffer_object) { glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, handle); glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0); glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER_EXT, 0); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, g_defaultFBO); glDeleteFramebuffersEXT(1, &handle); - } - if (z_stencil_buffer) - glDeleteRenderbuffers(1, &z_stencil_buffer); - if (z_buffer) - glDeleteRenderbuffers(1, &z_buffer); - if (stencil_buffer) - glDeleteRenderbuffers(1, &stencil_buffer); #endif + } } + + // These can only be set when supported. + if (z_stencil_buffer) + glDeleteRenderbuffers(1, &z_stencil_buffer); + if (z_buffer) + glDeleteRenderbuffers(1, &z_buffer); + if (stencil_buffer) + glDeleteRenderbuffers(1, &stencil_buffer); CHECK_GL_ERROR_IF_DEBUG(); } diff --git a/ext/native/thin3d/GLRenderManager.cpp b/ext/native/thin3d/GLRenderManager.cpp index 56317029f4..8affe78c8f 100644 --- a/ext/native/thin3d/GLRenderManager.cpp +++ b/ext/native/thin3d/GLRenderManager.cpp @@ -2,6 +2,7 @@ #include "GLRenderManager.h" #include "gfx_es2/gpu_features.h" +#include "thin3d/thin3d.h" #include "thread/threadutil.h" #include "base/logging.h" #include "GPU/GPUState.h" @@ -61,10 +62,12 @@ void GLDeleter::Perform(GLRenderManager *renderManager, bool skipGLCalls) { inputLayouts.clear(); for (auto framebuffer : framebuffers) { if (skipGLCalls) { + framebuffer->handle = 0; + framebuffer->color_texture.texture = 0; + framebuffer->z_stencil_buffer = 0; + framebuffer->z_stencil_texture.texture = 0; framebuffer->z_buffer = 0; framebuffer->stencil_buffer = 0; - framebuffer->z_stencil_buffer = 0; - framebuffer->handle = 0; } delete framebuffer; } @@ -87,12 +90,13 @@ GLRenderManager::~GLRenderManager() { _assert_(deleter_.IsEmpty()); } -void GLRenderManager::ThreadStart() { +void GLRenderManager::ThreadStart(Draw::DrawContext *draw) { queueRunner_.CreateDeviceObjects(); threadFrame_ = threadInitFrame_; renderThreadId = std::this_thread::get_id(); - bool mapBuffers = (gl_extensions.bugs & BUG_ANY_MAP_BUFFER_RANGE_SLOW) == 0; + // Don't save draw, we don't want any thread safety confusion. + bool mapBuffers = draw->GetBugs().Has(Draw::Bugs::ANY_MAP_BUFFER_RANGE_SLOW); bool hasBufferStorage = gl_extensions.ARB_buffer_storage || gl_extensions.EXT_buffer_storage; if (!gl_extensions.VersionGEThan(3, 0, 0) && gl_extensions.IsGLES && !hasBufferStorage) { // Force disable if it wouldn't work anyway. @@ -108,9 +112,14 @@ void GLRenderManager::ThreadStart() { bufferStrategy_ = GLBufferStrategy::FRAME_UNMAP; break; - case GPU_VENDOR_QUALCOMM: - bufferStrategy_ = GLBufferStrategy::FLUSH_INVALIDATE_UNMAP; - break; + // Temporarily disabled because it doesn't work with task switching on Android. + // The mapped buffer seems to just be pulled out like a rug from under us, crashing + // as soon as any write happens, which can happen during shutdown since we write from the + // Emu thread which may not yet have shut down. There may be solutions to this, but for now, + // disable this strategy to avoid crashing. + //case GPU_VENDOR_QUALCOMM: + // bufferStrategy_ = GLBufferStrategy::FLUSH_INVALIDATE_UNMAP; + // break; default: bufferStrategy_ = GLBufferStrategy::SUBDATA; diff --git a/ext/native/thin3d/GLRenderManager.h b/ext/native/thin3d/GLRenderManager.h index 9cc4ca4f7d..7b38c024e8 100644 --- a/ext/native/thin3d/GLRenderManager.h +++ b/ext/native/thin3d/GLRenderManager.h @@ -19,6 +19,10 @@ class GLRInputLayout; class GLPushBuffer; +namespace Draw { +class DrawContext; +} + class GLRTexture { public: ~GLRTexture() { @@ -52,7 +56,9 @@ public: GLuint handle = 0; GLRTexture color_texture; - GLuint z_stencil_buffer = 0; // Either this is set, or the two below. + // Either z_stencil_texture, z_stencil_buffer, or (z_buffer and stencil_buffer) are set. + GLuint z_stencil_buffer = 0; + GLRTexture z_stencil_texture; GLuint z_buffer = 0; GLuint stencil_buffer = 0; @@ -363,7 +369,7 @@ public: GLRenderManager(); ~GLRenderManager(); - void ThreadStart(); + void ThreadStart(Draw::DrawContext *draw); void ThreadEnd(); bool ThreadFrame(); // Returns false to request exiting the loop. diff --git a/ext/native/thin3d/VulkanQueueRunner.cpp b/ext/native/thin3d/VulkanQueueRunner.cpp index 2e122de544..4de46705be 100644 --- a/ext/native/thin3d/VulkanQueueRunner.cpp +++ b/ext/native/thin3d/VulkanQueueRunner.cpp @@ -50,14 +50,20 @@ void VulkanQueueRunner::ResizeReadbackBuffer(VkDeviceSize requiredSize) { VkMemoryRequirements reqs{}; vkGetBufferMemoryRequirements(device, readbackBuffer_, &reqs); - VkMemoryAllocateInfo alloc{ VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO }; - alloc.allocationSize = reqs.size; + VkMemoryAllocateInfo allocInfo{ VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO }; + allocInfo.allocationSize = reqs.size; VkFlags typeReqs = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT; - bool success = vulkan_->MemoryTypeFromProperties(reqs.memoryTypeBits, typeReqs, &alloc.memoryTypeIndex); + bool success = vulkan_->MemoryTypeFromProperties(reqs.memoryTypeBits, typeReqs, &allocInfo.memoryTypeIndex); _assert_(success); - vkAllocateMemory(device, &alloc, nullptr, &readbackMemory_); + VkResult res = vkAllocateMemory(device, &allocInfo, nullptr, &readbackMemory_); + if (res != VK_SUCCESS) { + readbackMemory_ = VK_NULL_HANDLE; + vkDestroyBuffer(device, readbackBuffer_, nullptr); + readbackBuffer_ = VK_NULL_HANDLE; + return; + } uint32_t offset = 0; vkBindBufferMemory(device, readbackBuffer_, readbackMemory_, offset); } @@ -689,6 +695,7 @@ void VulkanQueueRunner::PerformRenderPass(const VKRStep &step, VkCommandBuffer c VkPipelineStageFlags dstStage{}; switch (barrier.oldLayout) { case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL: + case VK_IMAGE_LAYOUT_UNDEFINED: barrier.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_COLOR_ATTACHMENT_READ_BIT; srcStage = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; break; @@ -858,7 +865,7 @@ void VulkanQueueRunner::PerformBindFramebufferAsRenderTarget(const VKRStep &step // See pull request #10723. bool maliBugWorkaround = step.render.numDraws == 0 && step.render.color == VKRRenderPassAction::CLEAR && - vulkan_->GetPhysicalDeviceProperties(vulkan_->GetCurrentPhysicalDevice()).driverVersion == 0xaa9c4b29; + vulkan_->GetPhysicalDeviceProperties().properties.driverVersion == 0xaa9c4b29; if (maliBugWorkaround) { TransitionImageLayout2(cmd, step.render.framebuffer->color.image, 0, 1, VK_IMAGE_ASPECT_COLOR_BIT, fb->color.layout, VK_IMAGE_LAYOUT_GENERAL, @@ -1278,6 +1285,9 @@ void VulkanQueueRunner::PerformReadbackImage(const VKRStep &step, VkCommandBuffe } void VulkanQueueRunner::CopyReadbackBuffer(int width, int height, Draw::DataFormat srcFormat, Draw::DataFormat destFormat, int pixelStride, uint8_t *pixels) { + if (!readbackMemory_) + return; // Something has gone really wrong. + // Read back to the requested address in ram from buffer. void *mappedData; const size_t srcPixelSize = DataFormatSizeInBytes(srcFormat); diff --git a/ext/native/thin3d/VulkanRenderManager.cpp b/ext/native/thin3d/VulkanRenderManager.cpp index 81506a6531..dc76d4f32d 100644 --- a/ext/native/thin3d/VulkanRenderManager.cpp +++ b/ext/native/thin3d/VulkanRenderManager.cpp @@ -43,22 +43,22 @@ void CreateImage(VulkanContext *vulkan, VkCommandBuffer cmd, VKRImage &img, int vkCreateImage(vulkan->GetDevice(), &ici, nullptr, &img.image); VkMemoryRequirements memreq; - vkGetImageMemoryRequirements(vulkan->GetDevice(), img.image, &memreq); + bool dedicatedAllocation = false; + vulkan->GetImageMemoryRequirements(img.image, &memreq, &dedicatedAllocation); VkMemoryAllocateInfo alloc{ VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO }; alloc.allocationSize = memreq.size; - - // Hint to the driver that this allocation is image-specific. Some drivers benefit. - // We only bother supporting the KHR extension, not the old NV one. - VkMemoryDedicatedAllocateInfoKHR dedicated{ VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO_KHR }; - if (vulkan->DeviceExtensions().DEDICATED_ALLOCATION) { - alloc.pNext = &dedicated; - dedicated.image = img.image; + VkMemoryDedicatedAllocateInfoKHR dedicatedAllocateInfo{VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO_KHR}; + if (dedicatedAllocation) { + dedicatedAllocateInfo.image = img.image; + alloc.pNext = &dedicatedAllocateInfo; } vulkan->MemoryTypeFromProperties(memreq.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, &alloc.memoryTypeIndex); + VkResult res = vkAllocateMemory(vulkan->GetDevice(), &alloc, nullptr, &img.memory); assert(res == VK_SUCCESS); + res = vkBindImageMemory(vulkan->GetDevice(), img.image, img.memory, 0); assert(res == VK_SUCCESS); @@ -137,7 +137,7 @@ VulkanRenderManager::VulkanRenderManager(VulkanContext *vulkan) : vulkan_(vulkan queueRunner_.CreateDeviceObjects(); // Temporary AMD hack for issue #10097 - if (vulkan_->GetPhysicalDeviceProperties(vulkan_->GetCurrentPhysicalDevice()).vendorID == VULKAN_VENDOR_AMD) { + if (vulkan_->GetPhysicalDeviceProperties().properties.vendorID == VULKAN_VENDOR_AMD) { if (!g_Config.bVulkanMultithreading) { useThread_ = false; } @@ -383,7 +383,9 @@ VkCommandBuffer VulkanRenderManager::GetInitCmd() { VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT }; VkResult res = vkBeginCommandBuffer(frameData.initCmd, &begin); - _assert_(res == VK_SUCCESS); + if (res != VK_SUCCESS) { + return VK_NULL_HANDLE; + } frameData.hasInitCommands = true; } return frameData_[curFrame].initCmd; @@ -553,11 +555,6 @@ bool VulkanRenderManager::InitDepthStencilBuffer(VkCommandBuffer cmd) { image_info.usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT; image_info.flags = 0; - VkMemoryAllocateInfo mem_alloc = { VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO }; - mem_alloc.allocationSize = 0; - mem_alloc.memoryTypeIndex = 0; - - VkMemoryRequirements mem_reqs; depth_.format = depth_format; @@ -567,9 +564,20 @@ bool VulkanRenderManager::InitDepthStencilBuffer(VkCommandBuffer cmd) { if (res != VK_SUCCESS) return false; - vkGetImageMemoryRequirements(device, depth_.image, &mem_reqs); + bool dedicatedAllocation = false; + VkMemoryRequirements mem_reqs; + vulkan_->GetImageMemoryRequirements(depth_.image, &mem_reqs, &dedicatedAllocation); + VkMemoryAllocateInfo mem_alloc = {VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO}; mem_alloc.allocationSize = mem_reqs.size; + mem_alloc.memoryTypeIndex = 0; + + VkMemoryDedicatedAllocateInfoKHR dedicatedAllocateInfo{VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO_KHR}; + if (dedicatedAllocation) { + dedicatedAllocateInfo.image = depth_.image; + mem_alloc.pNext = &dedicatedAllocateInfo; + } + // Use the memory properties to determine the type of memory required pass = vulkan_->MemoryTypeFromProperties(mem_reqs.memoryTypeBits, 0, /* No requirements */ @@ -899,7 +907,11 @@ void VulkanRenderManager::Submit(int frame, bool triggerFence) { submit_info.pCommandBuffers = cmdBufs; res = vkQueueSubmit(vulkan_->GetGraphicsQueue(), 1, &submit_info, VK_NULL_HANDLE); if (res == VK_ERROR_DEVICE_LOST) { - _assert_msg_(G3D, false, "Lost the Vulkan device!"); +#ifdef _WIN32 + _assert_msg_(G3D, false, "Lost the Vulkan device! If this happens again, switch Graphics Backend from Vulkan to Direct3D11"); +#else + _assert_msg_(G3D, false, "Lost the Vulkan device! If this happens again, switch Graphics Backend from Vulkan to OpenGL"); +#endif } else { _assert_msg_(G3D, res == VK_SUCCESS, "vkQueueSubmit failed (init)! result=%s", VulkanResultToString(res)); } @@ -923,7 +935,11 @@ void VulkanRenderManager::Submit(int frame, bool triggerFence) { } res = vkQueueSubmit(vulkan_->GetGraphicsQueue(), 1, &submit_info, triggerFence ? frameData.fence : VK_NULL_HANDLE); if (res == VK_ERROR_DEVICE_LOST) { - _assert_msg_(G3D, false, "Lost the Vulkan device!"); +#ifdef _WIN32 + _assert_msg_(G3D, false, "Lost the Vulkan device! If this happens again, switch Graphics Backend from Vulkan to Direct3D11"); +#else + _assert_msg_(G3D, false, "Lost the Vulkan device! If this happens again, switch Graphics Backend from Vulkan to OpenGL"); +#endif } else { _assert_msg_(G3D, res == VK_SUCCESS, "vkQueueSubmit failed (main, split=%d)! result=%s", (int)splitSubmit_, VulkanResultToString(res)); } diff --git a/ext/native/thin3d/thin3d.cpp b/ext/native/thin3d/thin3d.cpp index ddc70e2c7e..e8ace0d6a4 100644 --- a/ext/native/thin3d/thin3d.cpp +++ b/ext/native/thin3d/thin3d.cpp @@ -101,11 +101,6 @@ bool RefCountedObject::ReleaseAssertLast() { // The Vulkan ones can be re-used with modern GL later if desired, as they're just GLSL. -struct ShaderSource { - ShaderLanguage lang; - const char *src; -}; - static const std::vector fsTexCol = { {ShaderLanguage::GLSL_ES_200, "#ifdef GL_ES\n" @@ -196,6 +191,7 @@ static const std::vector vsCol = { "attribute vec3 Position;\n" "attribute vec4 Color0;\n" "varying vec4 oColor0;\n" + "uniform mat4 WorldViewProj;\n" "void main() {\n" " gl_Position = WorldViewProj * vec4(Position, 1.0);\n" @@ -317,7 +313,7 @@ const UniformBufferDesc vsTexColBufDesc{ sizeof(VsTexColUB),{ { "WorldViewProj", 0, -1, UniformType::MATRIX4X4, 0 } } }; -static ShaderModule *CreateShader(DrawContext *draw, ShaderStage stage, const std::vector &sources) { +ShaderModule *CreateShader(DrawContext *draw, ShaderStage stage, const std::vector &sources) { uint32_t supported = draw->GetSupportedShaderLanguages(); for (auto iter : sources) { if ((uint32_t)iter.lang & supported) { diff --git a/ext/native/thin3d/thin3d.h b/ext/native/thin3d/thin3d.h index 63be93ce68..c07b6130b5 100644 --- a/ext/native/thin3d/thin3d.h +++ b/ext/native/thin3d/thin3d.h @@ -204,13 +204,8 @@ enum class ShaderLanguage { GLSL_ES_300 = 2, GLSL_410 = 4, GLSL_VULKAN = 8, - SPIRV_VULKAN = 16, HLSL_D3D9 = 32, HLSL_D3D11 = 64, - HLSL_D3D9_BYTECODE = 128, - HLSL_D3D11_BYTECODE = 256, - METAL = 512, - METAL_BYTECODE = 1024, }; enum FormatSupport { @@ -239,6 +234,7 @@ enum class GPUVendor { VENDOR_QUALCOMM, VENDOR_IMGTEC, // PowerVR VENDOR_BROADCOM, // Raspberry + VENDOR_VIVANTE, }; enum class NativeObject { @@ -320,6 +316,27 @@ struct Viewport { float MaxDepth; }; +class Bugs { +public: + bool Has(uint32_t bug) const { + return (flags_ & (1 << bug)) != 0; + } + void Infest(uint32_t bug) { + flags_ |= (1 << bug); + } + + enum : uint32_t { + NO_DEPTH_CANNOT_DISCARD_STENCIL = 0, + DUAL_SOURCE_BLENDING_BROKEN = 1, + ANY_MAP_BUFFER_RANGE_SLOW = 2, + PVR_GENMIPMAP_HEIGHT_GREATER = 3, + BROKEN_NAN_IN_CONDITIONAL = 4, + }; + +protected: + uint32_t flags_ = 0; +}; + class RefCountedObject { public: RefCountedObject() : refcount_(1) {} @@ -421,7 +438,6 @@ struct StencilSide { Comparison compareOp; uint8_t compareMask; uint8_t writeMask; - uint8_t reference; }; struct DepthStencilStateDesc { @@ -477,6 +493,8 @@ struct PipelineDesc { struct DeviceCaps { GPUVendor vendor; + uint32_t deviceID; // use caution! + DataFormat preferredDepthBufferFormat; DataFormat preferredShadowMapFormatLow; DataFormat preferredShadowMapFormatHigh; @@ -530,6 +548,8 @@ public: bool CreatePresets(); void DestroyPresets(); + Bugs GetBugs() const { return bugs_; } + virtual const DeviceCaps &GetDeviceCaps() const = 0; virtual uint32_t GetDataFormatSupport(DataFormat fmt) const = 0; virtual std::vector GetFeatureList() const { return std::vector(); } @@ -547,8 +567,8 @@ public: virtual InputLayout *CreateInputLayout(const InputLayoutDesc &desc) = 0; // Note that these DO NOT AddRef so you must not ->Release presets unless you manually AddRef them. - ShaderModule *GetVshaderPreset(VertexShaderPreset preset) { return fsPresets_[preset]; } - ShaderModule *GetFshaderPreset(FragmentShaderPreset preset) { return vsPresets_[preset]; } + ShaderModule *GetVshaderPreset(VertexShaderPreset preset) { return vsPresets_[preset]; } + ShaderModule *GetFshaderPreset(FragmentShaderPreset preset) { return fsPresets_[preset]; } // Resources virtual Buffer *CreateBuffer(size_t size, uint32_t usageFlags) = 0; @@ -593,6 +613,7 @@ public: virtual void SetScissorRect(int left, int top, int width, int height) = 0; virtual void SetViewports(int count, Viewport *viewports) = 0; virtual void SetBlendFactor(float color[4]) = 0; + virtual void SetStencilRef(uint8_t ref) = 0; virtual void BindSamplerStates(int start, int count, SamplerState **state) = 0; virtual void BindTextures(int start, int count, Texture **textures) = 0; @@ -636,13 +657,6 @@ public: virtual void HandleEvent(Event ev, int width, int height, void *param1 = nullptr, void *param2 = nullptr) = 0; - // This flushes command buffers and waits for execution at the point of the end of the last - // renderpass that wrote to the requested framebuffer. This is needed before trying to read it back - // on modern APIs like Vulkan. Ifr the framebuffer is currently being rendered to, we'll just end the render pass. - // The next draw call will automatically start up a new one. - // APIs like OpenGL won't need to implement this one. - virtual void WaitRenderCompletion(Framebuffer *fbo) {} - // Flush state like scissors etc so the caller can do its own custom drawing. virtual void FlushState() {} @@ -652,6 +666,8 @@ protected: int targetWidth_; int targetHeight_; + + Bugs bugs_; }; extern const UniformBufferDesc UBPresetDesc; @@ -667,4 +683,13 @@ struct VsColUB { }; extern const UniformBufferDesc vsColBufDesc; +// Useful utility for specifying a shader in multiple languages. + +struct ShaderSource { + ShaderLanguage lang; + const char *src; +}; + +ShaderModule *CreateShader(DrawContext *draw, ShaderStage stage, const std::vector &sources); + } // namespace Draw diff --git a/ext/native/thin3d/thin3d_d3d11.cpp b/ext/native/thin3d/thin3d_d3d11.cpp index ceba6429fc..5da05d4862 100644 --- a/ext/native/thin3d/thin3d_d3d11.cpp +++ b/ext/native/thin3d/thin3d_d3d11.cpp @@ -48,7 +48,7 @@ public: return deviceList_; } uint32_t GetSupportedShaderLanguages() const override { - return (uint32_t)ShaderLanguage::HLSL_D3D11 | (uint32_t)ShaderLanguage::HLSL_D3D11_BYTECODE; + return (uint32_t)ShaderLanguage::HLSL_D3D11; } uint32_t GetDataFormatSupport(DataFormat fmt) const override; @@ -95,6 +95,10 @@ public: blendFactorDirty_ = true; } } + void SetStencilRef(uint8_t ref) override { + stencilRef_ = ref; + stencilRefDirty_ = true; + } void Draw(int vertexCount, int offset) override; void DrawIndexed(int vertexCount, int offset) override; @@ -204,8 +208,8 @@ private: // Dynamic state float blendFactor_[4]{}; bool blendFactorDirty_ = false; - uint8_t stencilRef_; - bool stencilRefDirty_; + uint8_t stencilRef_ = 0; + bool stencilRefDirty_ = true; // Temporaries ID3D11Texture2D *packTexture_ = nullptr; @@ -263,6 +267,7 @@ D3D11DrawContext::D3D11DrawContext(ID3D11Device *device, ID3D11DeviceContext *de default: caps_.vendor = GPUVendor::VENDOR_UNKNOWN; } + caps_.deviceID = desc.DeviceId; adapter->Release(); } dxgiDevice->Release(); @@ -806,11 +811,7 @@ public: }; ShaderModule *D3D11DrawContext::CreateShaderModule(ShaderStage stage, ShaderLanguage language, const uint8_t *data, size_t dataSize) { - switch (language) { - case ShaderLanguage::HLSL_D3D11: - case ShaderLanguage::HLSL_D3D11_BYTECODE: - break; - default: + if (language != ShaderLanguage::HLSL_D3D11) { ELOG("Unsupported shader language"); return nullptr; } @@ -826,77 +827,69 @@ ShaderModule *D3D11DrawContext::CreateShaderModule(ShaderStage stage, ShaderLang std::string compiled; std::string errors; - if (language == ShaderLanguage::HLSL_D3D11) { - const char *target = nullptr; - switch (stage) { - case ShaderStage::FRAGMENT: target = fragmentModel; break; - case ShaderStage::VERTEX: target = vertexModel; break; - case ShaderStage::GEOMETRY: - if (!geometryModel) - return nullptr; - target = geometryModel; - break; - case ShaderStage::COMPUTE: - case ShaderStage::CONTROL: - case ShaderStage::EVALUATION: - default: - Crash(); - break; - } - if (!target) { + const char *target = nullptr; + switch (stage) { + case ShaderStage::FRAGMENT: target = fragmentModel; break; + case ShaderStage::VERTEX: target = vertexModel; break; + case ShaderStage::GEOMETRY: + if (!geometryModel) return nullptr; - } - - ID3DBlob *compiledCode = nullptr; - ID3DBlob *errorMsgs = nullptr; - HRESULT result = ptr_D3DCompile(data, dataSize, nullptr, nullptr, nullptr, "main", target, 0, 0, &compiledCode, &errorMsgs); - if (compiledCode) { - compiled = std::string((const char *)compiledCode->GetBufferPointer(), compiledCode->GetBufferSize()); - compiledCode->Release(); - } - if (errorMsgs) { - errors = std::string((const char *)errorMsgs->GetBufferPointer(), errorMsgs->GetBufferSize()); - ELOG("Failed compiling:\n%s\n%s", data, errors.c_str()); - errorMsgs->Release(); - } - - if (result != S_OK) { - return nullptr; - } - - // OK, we can now proceed - language = ShaderLanguage::HLSL_D3D11_BYTECODE; - data = (const uint8_t *)compiled.c_str(); - dataSize = compiled.size(); + target = geometryModel; + break; + case ShaderStage::COMPUTE: + case ShaderStage::CONTROL: + case ShaderStage::EVALUATION: + default: + Crash(); + break; + } + if (!target) { + return nullptr; } - if (language == ShaderLanguage::HLSL_D3D11_BYTECODE) { - // Easy! - D3D11ShaderModule *module = new D3D11ShaderModule(); - module->stage = stage; - module->byteCode_ = std::vector(data, data + dataSize); - HRESULT result = S_OK; - switch (stage) { - case ShaderStage::VERTEX: - result = device_->CreateVertexShader(data, dataSize, nullptr, &module->vs); - break; - case ShaderStage::FRAGMENT: - result = device_->CreatePixelShader(data, dataSize, nullptr, &module->ps); - break; - case ShaderStage::GEOMETRY: - result = device_->CreateGeometryShader(data, dataSize, nullptr, &module->gs); - break; - default: - ELOG("Unsupported shader stage"); - result = S_FALSE; - break; - } - if (result == S_OK) { - return module; - } else { - delete module; - return nullptr; - } + ID3DBlob *compiledCode = nullptr; + ID3DBlob *errorMsgs = nullptr; + HRESULT result = ptr_D3DCompile(data, dataSize, nullptr, nullptr, nullptr, "main", target, 0, 0, &compiledCode, &errorMsgs); + if (compiledCode) { + compiled = std::string((const char *)compiledCode->GetBufferPointer(), compiledCode->GetBufferSize()); + compiledCode->Release(); + } + if (errorMsgs) { + errors = std::string((const char *)errorMsgs->GetBufferPointer(), errorMsgs->GetBufferSize()); + ELOG("Failed compiling:\n%s\n%s", data, errors.c_str()); + errorMsgs->Release(); + } + + if (result != S_OK) { + return nullptr; + } + + // OK, we can now proceed + data = (const uint8_t *)compiled.c_str(); + dataSize = compiled.size(); + D3D11ShaderModule *module = new D3D11ShaderModule(); + module->stage = stage; + module->byteCode_ = std::vector(data, data + dataSize); + switch (stage) { + case ShaderStage::VERTEX: + result = device_->CreateVertexShader(data, dataSize, nullptr, &module->vs); + break; + case ShaderStage::FRAGMENT: + result = device_->CreatePixelShader(data, dataSize, nullptr, &module->ps); + break; + case ShaderStage::GEOMETRY: + result = device_->CreateGeometryShader(data, dataSize, nullptr, &module->gs); + break; + default: + ELOG("Unsupported shader stage"); + result = S_FALSE; + break; + } + if (result == S_OK) { + return module; + } else { + delete module; + return nullptr; } return nullptr; } @@ -987,7 +980,6 @@ void D3D11DrawContext::BindPipeline(Pipeline *pipeline) { curPipeline_ = dPipeline; } -// Gonna need dirtyflags soon.. void D3D11DrawContext::ApplyCurrentState() { if (curBlend_ != curPipeline_->blend || blendFactorDirty_) { context_->OMSetBlendState(curPipeline_->blend->bs, blendFactor_, 0xFFFFFFFF); diff --git a/ext/native/thin3d/thin3d_d3d9.cpp b/ext/native/thin3d/thin3d_d3d9.cpp index 8f8396798b..d5d4c45bcd 100644 --- a/ext/native/thin3d/thin3d_d3d9.cpp +++ b/ext/native/thin3d/thin3d_d3d9.cpp @@ -154,7 +154,6 @@ public: D3DSTENCILOP stencilZFail; D3DSTENCILOP stencilPass; D3DCMPFUNC stencilCompareOp; - uint8_t stencilReference; uint8_t stencilCompareMask; uint8_t stencilWriteMask; void Apply(LPDIRECT3DDEVICE9 device) { @@ -170,7 +169,6 @@ public: device->SetRenderState(D3DRS_STENCILPASS, stencilPass); device->SetRenderState(D3DRS_STENCILFUNC, stencilCompareOp); device->SetRenderState(D3DRS_STENCILMASK, stencilCompareMask); - device->SetRenderState(D3DRS_STENCILREF, stencilReference); device->SetRenderState(D3DRS_STENCILWRITEMASK, stencilWriteMask); } } @@ -465,7 +463,7 @@ public: return caps_; } uint32_t GetSupportedShaderLanguages() const override { - return (uint32_t)ShaderLanguage::HLSL_D3D9 | (uint32_t)ShaderLanguage::HLSL_D3D9_BYTECODE; + return (uint32_t)ShaderLanguage::HLSL_D3D9; } uint32_t GetDataFormatSupport(DataFormat fmt) const override; @@ -523,6 +521,7 @@ public: void SetScissorRect(int left, int top, int width, int height) override; void SetViewports(int count, Viewport *viewports) override; void SetBlendFactor(float color[4]) override; + void SetStencilRef(uint8_t ref) override; void Draw(int vertexCount, int offset) override; void DrawIndexed(int vertexCount, int offset) override; @@ -604,7 +603,7 @@ D3D9Context::D3D9Context(IDirect3D9 *d3d, IDirect3D9Ex *d3dEx, int adapterId, ID } else { strcpy(shadeLangVersion_, "N/A"); } - + caps_.deviceID = identifier_.DeviceId; caps_.multiViewport = false; caps_.anisoSupported = true; caps_.depthRangeMinusOneToOne = false; @@ -684,7 +683,6 @@ DepthStencilState *D3D9Context::CreateDepthStencilState(const DepthStencilStateD ds->stencilFail = stencilOpToD3D9[(int)desc.front.failOp]; ds->stencilZFail = stencilOpToD3D9[(int)desc.front.depthFailOp]; ds->stencilWriteMask = desc.front.writeMask; - ds->stencilReference = desc.front.reference; ds->stencilCompareMask = desc.front.compareMask; return ds; } @@ -966,6 +964,10 @@ void D3D9Context::SetBlendFactor(float color[4]) { device_->SetRenderState(D3DRS_BLENDFACTOR, r | (g << 8) | (b << 16) | (a << 24)); } +void D3D9Context::SetStencilRef(uint8_t ref) { + device_->SetRenderState(D3DRS_STENCILREF, (DWORD)ref); +} + bool D3D9ShaderModule::Compile(LPDIRECT3DDEVICE9 device, const uint8_t *data, size_t size) { LPD3DXMACRO defines = nullptr; LPD3DXINCLUDE includes = nullptr; diff --git a/ext/native/thin3d/thin3d_gl.cpp b/ext/native/thin3d/thin3d_gl.cpp index aae54b3879..a94b318bbb 100644 --- a/ext/native/thin3d/thin3d_gl.cpp +++ b/ext/native/thin3d/thin3d_gl.cpp @@ -186,19 +186,18 @@ public: bool depthTestEnabled; bool depthWriteEnabled; GLuint depthComp; - // TODO: Two-sided + // TODO: Two-sided. Although in practice, do we care? bool stencilEnabled; GLuint stencilFail; GLuint stencilZFail; GLuint stencilPass; GLuint stencilCompareOp; - uint8_t stencilReference; uint8_t stencilCompareMask; uint8_t stencilWriteMask; - void Apply(GLRenderManager *render) { + void Apply(GLRenderManager *render, uint8_t stencilRef) { render->SetDepth(depthTestEnabled, depthWriteEnabled, depthComp); - render->SetStencilFunc(stencilEnabled, stencilCompareOp, stencilReference, stencilCompareMask); + render->SetStencilFunc(stencilEnabled, stencilCompareOp, stencilRef, stencilCompareMask); render->SetStencilOp(stencilWriteMask, stencilFail, stencilZFail, stencilPass); } }; @@ -404,6 +403,15 @@ public: renderManager_.SetBlendFactor(color); } + void SetStencilRef(uint8_t ref) override { + stencilRef_ = ref; + renderManager_.SetStencilFunc( + curPipeline_->depthStencil->stencilEnabled, + curPipeline_->depthStencil->stencilCompareOp, + ref, + curPipeline_->depthStencil->stencilCompareMask); + } + void BindTextures(int start, int count, Texture **textures) override; void BindPipeline(Pipeline *pipeline) override; void BindVertexBuffers(int start, int count, Buffer **buffers, int *offsets) override { @@ -445,6 +453,7 @@ public: case GPUVendor::VENDOR_QUALCOMM: return "VENDOR_ADRENO"; case GPUVendor::VENDOR_ARM: return "VENDOR_ARM"; case GPUVendor::VENDOR_BROADCOM: return "VENDOR_BROADCOM"; + case GPUVendor::VENDOR_VIVANTE: return "VENDOR_VIVANTE"; case GPUVendor::VENDOR_UNKNOWN: default: return "VENDOR_UNKNOWN"; @@ -485,6 +494,8 @@ private: OpenGLBuffer *curIBuffer_ = nullptr; int curIBufferOffset_ = 0; + uint8_t stencilRef_ = 0; + // Frames in flight is not such a strict concept as with Vulkan until we start using glBufferStorage and fences. // But might as well have the structure ready, and can't hurt to rotate buffers. struct FrameData { @@ -493,6 +504,26 @@ private: FrameData frameData_[GLRenderManager::MAX_INFLIGHT_FRAMES]; }; +static constexpr int MakeIntelSimpleVer(int v1, int v2, int v3) { + return (v1 << 16) | (v2 << 8) | v3; +} + +static bool HasIntelDualSrcBug(int versions[4]) { + // Intel uses a confusing set of at least 3 version numbering schemes. This is the one given to OpenGL. + switch (MakeIntelSimpleVer(versions[0], versions[1], versions[2])) { + case MakeIntelSimpleVer(9, 17, 10): + case MakeIntelSimpleVer(9, 18, 10): + return false; + case MakeIntelSimpleVer(10, 18, 10): + return versions[3] < 4061; + case MakeIntelSimpleVer(10, 18, 14): + return versions[3] < 4080; + default: + // Older than above didn't support dual src anyway, newer should have the fix. + return false; + } +} + OpenGLContext::OpenGLContext() { // TODO: Detect more caps if (gl_extensions.IsGLES) { @@ -515,6 +546,7 @@ OpenGLContext::OpenGLContext() { case GPU_VENDOR_BROADCOM: caps_.vendor = GPUVendor::VENDOR_BROADCOM; break; case GPU_VENDOR_INTEL: caps_.vendor = GPUVendor::VENDOR_INTEL; break; case GPU_VENDOR_IMGTEC: caps_.vendor = GPUVendor::VENDOR_IMGTEC; break; + case GPU_VENDOR_VIVANTE: caps_.vendor = GPUVendor::VENDOR_VIVANTE; break; case GPU_VENDOR_UNKNOWN: default: caps_.vendor = GPUVendor::VENDOR_UNKNOWN; @@ -523,6 +555,38 @@ OpenGLContext::OpenGLContext() { for (int i = 0; i < GLRenderManager::MAX_INFLIGHT_FRAMES; i++) { frameData_[i].push = renderManager_.CreatePushBuffer(i, GL_ARRAY_BUFFER, 64 * 1024); } + + if (!gl_extensions.VersionGEThan(3, 0, 0)) { + // Don't use this extension on sub 3.0 OpenGL versions as it does not seem reliable. + bugs_.Infest(Bugs::DUAL_SOURCE_BLENDING_BROKEN); + } else if (caps_.vendor == GPUVendor::VENDOR_INTEL) { + // Note: this is for Intel drivers with GL3+. + // Also on Intel, see https://github.com/hrydgard/ppsspp/issues/10117 + // TODO: Remove entirely sometime reasonably far in driver years after 2015. + const std::string ver = GetInfoString(Draw::InfoField::APIVERSION); + int versions[4]{}; + if (sscanf(ver.c_str(), "Build %d.%d.%d.%d", &versions[0], &versions[1], &versions[2], &versions[3]) == 4) { + if (HasIntelDualSrcBug(versions)) { + bugs_.Infest(Bugs::DUAL_SOURCE_BLENDING_BROKEN); + } + } + } + + if (caps_.vendor == GPUVendor::VENDOR_VIVANTE || caps_.vendor == GPUVendor::VENDOR_BROADCOM) { + bugs_.Infest(Bugs::BROKEN_NAN_IN_CONDITIONAL); + } + + // TODO: Make this check more lenient. Disabled for all right now + // because it murders performance on Mali. + if (caps_.vendor != GPUVendor::VENDOR_NVIDIA) { + bugs_.Infest(Bugs::ANY_MAP_BUFFER_RANGE_SLOW); + } + + if (caps_.vendor == GPUVendor::VENDOR_IMGTEC) { + // See https://github.com/hrydgard/ppsspp/commit/8974cd675e538f4445955e3eac572a9347d84232 + // TODO: Should this workaround be removed for newer devices/drivers? + bugs_.Infest(Bugs::PVR_GENMIPMAP_HEIGHT_GREATER); + } } OpenGLContext::~OpenGLContext() { @@ -750,7 +814,6 @@ DepthStencilState *OpenGLContext::CreateDepthStencilState(const DepthStencilStat ds->stencilFail = stencilOpToGL[(int)desc.front.failOp]; ds->stencilZFail = stencilOpToGL[(int)desc.front.depthFailOp]; ds->stencilWriteMask = desc.front.writeMask; - ds->stencilReference = desc.front.reference; ds->stencilCompareMask = desc.front.compareMask; return ds; } @@ -959,7 +1022,7 @@ bool OpenGLPipeline::LinkShaders() { void OpenGLContext::BindPipeline(Pipeline *pipeline) { curPipeline_ = (OpenGLPipeline *)pipeline; curPipeline_->blend->Apply(&renderManager_); - curPipeline_->depthStencil->Apply(&renderManager_); + curPipeline_->depthStencil->Apply(&renderManager_, stencilRef_); curPipeline_->raster->Apply(&renderManager_); renderManager_.BindProgram(curPipeline_->program_); } diff --git a/ext/native/thin3d/thin3d_vulkan.cpp b/ext/native/thin3d/thin3d_vulkan.cpp index 37d6497b51..1ff74d1d5a 100644 --- a/ext/native/thin3d/thin3d_vulkan.cpp +++ b/ext/native/thin3d/thin3d_vulkan.cpp @@ -21,7 +21,6 @@ #include #include -#include "Common/Vulkan/SPIRVDisasm.h" #include "Core/Config.h" #include "base/logging.h" @@ -261,7 +260,7 @@ public: // Returns the binding offset, and the VkBuffer to bind. size_t PushUBO(VulkanPushBuffer *buf, VulkanContext *vulkan, VkBuffer *vkbuf) { - return buf->PushAligned(ubo_, uboSize_, vulkan->GetPhysicalDeviceProperties(vulkan_->GetCurrentPhysicalDevice()).limits.minUniformBufferOffsetAlignment, vkbuf); + return buf->PushAligned(ubo_, uboSize_, vulkan->GetPhysicalDeviceProperties().properties.limits.minUniformBufferOffsetAlignment, vkbuf); } int GetUniformLoc(const char *name); @@ -276,6 +275,10 @@ public: int stride[4]{}; int dynamicUniformSize = 0; + bool usesStencil = false; + uint8_t stencilWriteMask = 0xFF; + uint8_t stencilTestMask = 0xFF; + private: VulkanContext *vulkan_; uint8_t *ubo_; @@ -301,11 +304,9 @@ struct DescriptorSetKey { class VKTexture : public Texture { public: - VKTexture(VulkanContext *vulkan, VkCommandBuffer cmd, VulkanPushBuffer *pushBuffer, const TextureDesc &desc, VulkanDeviceAllocator *alloc) - : vulkan_(vulkan), mipLevels_(desc.mipLevels), format_(desc.format) { - bool result = Create(cmd, pushBuffer, desc, alloc); - _assert_(result); - } + VKTexture(VulkanContext *vulkan, VkCommandBuffer cmd, VulkanPushBuffer *pushBuffer, const TextureDesc &desc) + : vulkan_(vulkan), mipLevels_(desc.mipLevels), format_(desc.format) {} + bool Create(VkCommandBuffer cmd, VulkanPushBuffer *pushBuffer, const TextureDesc &desc, VulkanDeviceAllocator *alloc); ~VKTexture() { Destroy(); @@ -322,8 +323,6 @@ public: } private: - bool Create(VkCommandBuffer cmd, VulkanPushBuffer *pushBuffer, const TextureDesc &desc, VulkanDeviceAllocator *alloc); - void Destroy() { if (vkTex_) { vkTex_->Destroy(); @@ -335,9 +334,9 @@ private: VulkanContext *vulkan_; VulkanTexture *vkTex_ = nullptr; - int mipLevels_; + int mipLevels_ = 0; - DataFormat format_; + DataFormat format_ = DataFormat::UNDEFINED; }; class VKFramebuffer; @@ -353,12 +352,12 @@ public: std::vector GetDeviceList() const override { std::vector list; for (int i = 0; i < vulkan_->GetNumPhysicalDevices(); i++) { - list.push_back(vulkan_->GetPhysicalDeviceProperties(i).deviceName); + list.push_back(vulkan_->GetPhysicalDeviceProperties(i).properties.deviceName); } return list; } uint32_t GetSupportedShaderLanguages() const override { - return (uint32_t)ShaderLanguage::GLSL_VULKAN | (uint32_t)ShaderLanguage::SPIRV_VULKAN; + return (uint32_t)ShaderLanguage::GLSL_VULKAN; } uint32_t GetDataFormatSupport(DataFormat fmt) const override; @@ -393,6 +392,7 @@ public: void SetScissorRect(int left, int top, int width, int height) override; void SetViewports(int count, Viewport *viewports) override; void SetBlendFactor(float color[4]) override; + void SetStencilRef(uint8_t stencilRef) override; void BindSamplerStates(int start, int count, SamplerState **state) override; void BindTextures(int start, int count, Texture **textures) override; @@ -419,19 +419,19 @@ public: void DrawIndexed(int vertexCount, int offset) override; void DrawUP(const void *vdata, int vertexCount) override; + void ApplyDynamicState(); + void Clear(int mask, uint32_t colorval, float depthVal, int stencilVal) override; void BeginFrame() override; void EndFrame() override; void WipeQueue() override; - void FlushState() override { - } - void WaitRenderCompletion(Framebuffer *fbo) override; + void FlushState() override {} // From Sascha's code static std::string FormatDriverVersion(const VkPhysicalDeviceProperties &props) { - if (props.vendorID == 4318) { + if (props.vendorID == VULKAN_VENDOR_NVIDIA) { // 10 bits = major version (up to r1023) // 8 bits = minor version (up to 255) // 8 bits = secondary branch version/build version (up to 255) @@ -441,6 +441,9 @@ public: uint32_t secondaryBranch = (props.driverVersion >> 6) & 0x0ff; uint32_t tertiaryBranch = (props.driverVersion) & 0x003f; return StringFromFormat("%d.%d.%d.%d (%08x)", major, minor, secondaryBranch, tertiaryBranch, props.driverVersion); + } else if (props.vendorID == VULKAN_VENDOR_ARM) { + // ARM just puts a hash here, let's just output it as is. + return StringFromFormat("%08x", props.driverVersion); } else { // Standard scheme, use the standard macros. uint32_t major = VK_VERSION_MAJOR(props.driverVersion); @@ -454,13 +457,13 @@ public: // TODO: Make these actually query the right information switch (info) { case APINAME: return "Vulkan"; - case VENDORSTRING: return vulkan_->GetPhysicalDeviceProperties(vulkan_->GetCurrentPhysicalDevice()).deviceName; - case VENDOR: return VulkanVendorString(vulkan_->GetPhysicalDeviceProperties(vulkan_->GetCurrentPhysicalDevice()).vendorID); - case DRIVER: return FormatDriverVersion(vulkan_->GetPhysicalDeviceProperties(vulkan_->GetCurrentPhysicalDevice())); + case VENDORSTRING: return vulkan_->GetPhysicalDeviceProperties().properties.deviceName; + case VENDOR: return VulkanVendorString(vulkan_->GetPhysicalDeviceProperties().properties.vendorID); + case DRIVER: return FormatDriverVersion(vulkan_->GetPhysicalDeviceProperties().properties); case SHADELANGVERSION: return "N/A";; case APIVERSION: { - uint32_t ver = vulkan_->GetPhysicalDeviceProperties(vulkan_->GetCurrentPhysicalDevice()).apiVersion; + uint32_t ver = vulkan_->GetPhysicalDeviceProperties().properties.apiVersion; return StringFromFormat("%d.%d.%d", ver >> 22, (ver >> 12) & 0x3ff, ver & 0xfff); } default: return "?"; @@ -546,6 +549,8 @@ private: VulkanPushBuffer *push_ = nullptr; DeviceCaps caps_{}; + + uint8_t stencilRef_ = 0; }; static int GetBpp(VkFormat format) { @@ -698,6 +703,10 @@ enum class TextureState { bool VKTexture::Create(VkCommandBuffer cmd, VulkanPushBuffer *push, const TextureDesc &desc, VulkanDeviceAllocator *alloc) { // Zero-sized textures not allowed. _assert_(desc.width * desc.height * desc.depth > 0); // remember to set depth to 1! + if (desc.width * desc.height * desc.depth <= 0) { + ELOG("Bad texture dimensions %dx%dx%d", desc.width, desc.height, desc.depth); + return false; + } _assert_(push); format_ = desc.format; mipLevels_ = desc.mipLevels; @@ -742,19 +751,20 @@ bool VKTexture::Create(VkCommandBuffer cmd, VulkanPushBuffer *push, const Textur VKContext::VKContext(VulkanContext *vulkan, bool splitSubmit) : vulkan_(vulkan), caps_{}, renderManager_(vulkan) { - caps_.anisoSupported = vulkan->GetFeaturesAvailable().samplerAnisotropy != 0; - caps_.geometryShaderSupported = vulkan->GetFeaturesAvailable().geometryShader != 0; - caps_.tesselationShaderSupported = vulkan->GetFeaturesAvailable().tessellationShader != 0; - caps_.multiViewport = vulkan->GetFeaturesAvailable().multiViewport != 0; - caps_.dualSourceBlend = vulkan->GetFeaturesAvailable().dualSrcBlend != 0; - caps_.depthClampSupported = vulkan->GetFeaturesAvailable().depthClamp != 0; + caps_.anisoSupported = vulkan->GetDeviceFeatures().enabled.samplerAnisotropy != 0; + caps_.geometryShaderSupported = vulkan->GetDeviceFeatures().enabled.geometryShader != 0; + caps_.tesselationShaderSupported = vulkan->GetDeviceFeatures().enabled.tessellationShader != 0; + caps_.multiViewport = vulkan->GetDeviceFeatures().enabled.multiViewport != 0; + caps_.dualSourceBlend = vulkan->GetDeviceFeatures().enabled.dualSrcBlend != 0; + caps_.depthClampSupported = vulkan->GetDeviceFeatures().enabled.depthClamp != 0; caps_.framebufferBlitSupported = true; caps_.framebufferCopySupported = true; caps_.framebufferDepthBlitSupported = false; // Can be checked for. caps_.framebufferDepthCopySupported = true; // Will pretty much always be the case. caps_.preferredDepthBufferFormat = DataFormat::D24_S8; // TODO: Ask vulkan. - switch (vulkan->GetPhysicalDeviceProperties(vulkan_->GetCurrentPhysicalDevice()).vendorID) { + auto deviceProps = vulkan->GetPhysicalDeviceProperties(vulkan_->GetCurrentPhysicalDevice()).properties; + switch (deviceProps.vendorID) { case VULKAN_VENDOR_AMD: caps_.vendor = GPUVendor::VENDOR_AMD; break; case VULKAN_VENDOR_ARM: caps_.vendor = GPUVendor::VENDOR_ARM; break; case VULKAN_VENDOR_IMGTEC: caps_.vendor = GPUVendor::VENDOR_IMGTEC; break; @@ -765,6 +775,23 @@ VKContext::VKContext(VulkanContext *vulkan, bool splitSubmit) caps_.vendor = GPUVendor::VENDOR_UNKNOWN; } + if (caps_.vendor == GPUVendor::VENDOR_QUALCOMM) { + // Adreno 5xx devices, all known driver versions, fail to discard stencil when depth write is off. + // See: https://github.com/hrydgard/ppsspp/pull/11684 + if (deviceProps.deviceID >= 0x05000000 && deviceProps.deviceID < 0x06000000) { + bugs_.Infest(Bugs::NO_DEPTH_CANNOT_DISCARD_STENCIL); + } + } else if (caps_.vendor == GPUVendor::VENDOR_AMD) { + // See issue #10074, and also #10065 (AMD) and #10109 for the choice of the driver version to check for. + if (deviceProps.driverVersion < 0x00407000) { + bugs_.Infest(Bugs::DUAL_SOURCE_BLENDING_BROKEN); + } + } else if (caps_.vendor == GPUVendor::VENDOR_INTEL) { + // Workaround for Intel driver bug. TODO: Re-enable after some driver version + bugs_.Infest(Bugs::DUAL_SOURCE_BLENDING_BROKEN); + } + + caps_.deviceID = deviceProps.deviceID; device_ = vulkan->GetDevice(); queue_ = vulkan->GetGraphicsQueue(); @@ -866,10 +893,6 @@ void VKContext::BeginFrame() { _assert_(result == VK_SUCCESS); } -void VKContext::WaitRenderCompletion(Framebuffer *fbo) { - // TODO -} - void VKContext::EndFrame() { // Stop collecting data in the frame's data pushbuffer. push_->End(); @@ -980,18 +1003,17 @@ Pipeline *VKContext::CreateGraphicsPipeline(const PipelineDesc &desc) { inputAssembly.topology = primToVK[(int)desc.prim]; inputAssembly.primitiveRestartEnable = false; - VkDynamicState dynamics[] = { VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR }; + // We treat the three stencil states as a unit in other places, so let's do that here too. + VkDynamicState dynamics[] = { VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR, VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK, VK_DYNAMIC_STATE_STENCIL_REFERENCE, VK_DYNAMIC_STATE_STENCIL_WRITE_MASK }; VkPipelineDynamicStateCreateInfo dynamicInfo = { VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO }; - dynamicInfo.dynamicStateCount = ARRAY_SIZE(dynamics); + dynamicInfo.dynamicStateCount = depth->info.stencilTestEnable ? ARRAY_SIZE(dynamics) : 2; dynamicInfo.pDynamicStates = dynamics; - VkPipelineMultisampleStateCreateInfo ms = { VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO }; - ms.pNext = nullptr; + VkPipelineMultisampleStateCreateInfo ms{ VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO }; ms.pSampleMask = nullptr; ms.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT; - VkPipelineViewportStateCreateInfo vs = { VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO }; - vs.pNext = nullptr; + VkPipelineViewportStateCreateInfo vs{ VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO }; vs.viewportCount = 1; vs.scissorCount = 1; vs.pViewports = nullptr; // dynamic @@ -1000,8 +1022,7 @@ Pipeline *VKContext::CreateGraphicsPipeline(const PipelineDesc &desc) { VkPipelineRasterizationStateCreateInfo rs{ VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO }; raster->ToVulkan(&rs); - VkGraphicsPipelineCreateInfo info = { VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO }; - info.pNext = nullptr; + VkGraphicsPipelineCreateInfo info{ VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO }; info.flags = 0; info.stageCount = (uint32_t)stages.size(); info.pStages = stages.data(); @@ -1028,7 +1049,11 @@ Pipeline *VKContext::CreateGraphicsPipeline(const PipelineDesc &desc) { if (desc.uniformDesc) { pipeline->dynamicUniformSize = (int)desc.uniformDesc->uniformBufferSize; } - + if (depth->info.stencilTestEnable) { + pipeline->usesStencil = true; + pipeline->stencilTestMask = depth->info.front.compareMask; + pipeline->stencilWriteMask = depth->info.front.writeMask; + } return pipeline; } @@ -1054,6 +1079,12 @@ void VKContext::SetBlendFactor(float color[4]) { renderManager_.SetBlendFactor(color); } +void VKContext::SetStencilRef(uint8_t stencilRef) { + if (curPipeline_->usesStencil) + renderManager_.SetStencilParams(curPipeline_->stencilWriteMask, curPipeline_->stencilTestMask, stencilRef); + stencilRef_ = stencilRef; +} + InputLayout *VKContext::CreateInputLayout(const InputLayoutDesc &desc) { VKInputLayout *vl = new VKInputLayout(); vl->visc = { VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO }; @@ -1079,17 +1110,24 @@ InputLayout *VKContext::CreateInputLayout(const InputLayoutDesc &desc) { } Texture *VKContext::CreateTexture(const TextureDesc &desc) { - if (!push_ || !renderManager_.GetInitCmd()) { + VkCommandBuffer initCmd = renderManager_.GetInitCmd(); + if (!push_ || !initCmd) { // Too early! Fail. ELOG("Can't create textures before the first frame has started."); return nullptr; } - return new VKTexture(vulkan_, renderManager_.GetInitCmd(), push_, desc, allocator_); + VKTexture *tex = new VKTexture(vulkan_, initCmd, push_, desc); + if (tex->Create(initCmd, push_, desc, allocator_)) { + return tex; + } else { + ELOG("Failed to create texture"); + delete tex; + return nullptr; + } } static inline void CopySide(VkStencilOpState &dest, const StencilSide &src) { dest.compareMask = src.compareMask; - dest.reference = src.reference; dest.writeMask = src.writeMask; dest.compareOp = compToVK[(int)src.compareOp]; dest.failOp = stencilOpToVK[(int)src.failOp]; @@ -1102,7 +1140,7 @@ DepthStencilState *VKContext::CreateDepthStencilState(const DepthStencilStateDes ds->info.depthCompareOp = compToVK[(int)desc.depthCompare]; ds->info.depthTestEnable = desc.depthTestEnabled; ds->info.depthWriteEnable = desc.depthWriteEnabled; - ds->info.stencilTestEnable = false; + ds->info.stencilTestEnable = desc.stencilEnabled; ds->info.depthBoundsTestEnable = false; if (ds->info.stencilTestEnable) { CopySide(ds->info.front, desc.front); @@ -1190,6 +1228,13 @@ void VKContext::UpdateDynamicUniformBuffer(const void *ub, size_t size) { curPipeline_->SetDynamicUniformData(ub, size); } +void VKContext::ApplyDynamicState() { + // TODO: blend constants, stencil, viewports should be here, after bindpipeline.. + if (curPipeline_->usesStencil) { + renderManager_.SetStencilParams(curPipeline_->stencilWriteMask, curPipeline_->stencilTestMask, stencilRef_); + } +} + void VKContext::Draw(int vertexCount, int offset) { VKBuffer *vbuf = curVBuffers_[0]; @@ -1201,7 +1246,7 @@ void VKContext::Draw(int vertexCount, int offset) { VkDescriptorSet descSet = GetOrCreateDescriptorSet(vulkanUBObuf); renderManager_.BindPipeline(curPipeline_->vkpipeline); - // TODO: blend constants, stencil, viewports should be here, after bindpipeline.. + ApplyDynamicState(); renderManager_.Draw(pipelineLayout_, descSet, 1, &ubo_offset, vulkanVbuf, (int)vbBindOffset, vertexCount); } @@ -1217,7 +1262,7 @@ void VKContext::DrawIndexed(int vertexCount, int offset) { VkDescriptorSet descSet = GetOrCreateDescriptorSet(vulkanUBObuf); renderManager_.BindPipeline(curPipeline_->vkpipeline); - // TODO: blend constants, stencil, viewports should be here, after bindpipeline.. + ApplyDynamicState(); renderManager_.DrawIndexed(pipelineLayout_, descSet, 1, &ubo_offset, vulkanVbuf, (int)vbBindOffset, vulkanIbuf, (int)ibBindOffset, vertexCount, 1, VK_INDEX_TYPE_UINT32); } @@ -1229,7 +1274,7 @@ void VKContext::DrawUP(const void *vdata, int vertexCount) { VkDescriptorSet descSet = GetOrCreateDescriptorSet(vulkanUBObuf); renderManager_.BindPipeline(curPipeline_->vkpipeline); - // TODO: blend constants, stencil, viewports should be here, after bindpipeline.. + ApplyDynamicState(); renderManager_.Draw(pipelineLayout_, descSet, 1, &ubo_offset, vulkanVbuf, (int)vbBindOffset, vertexCount); } @@ -1269,8 +1314,8 @@ static const char *VulkanFormatToString(VkFormat fmt) { } std::vector VKContext::GetFeatureList() const { - const VkPhysicalDeviceFeatures &available = vulkan_->GetFeaturesAvailable(); - const VkPhysicalDeviceFeatures &enabled = vulkan_->GetFeaturesEnabled(); + const VkPhysicalDeviceFeatures &available = vulkan_->GetDeviceFeatures().available; + const VkPhysicalDeviceFeatures &enabled = vulkan_->GetDeviceFeatures().enabled; std::vector features; AddFeature(features, "dualSrcBlend", available.dualSrcBlend, enabled.dualSrcBlend); diff --git a/ext/native/ui/ui.cpp b/ext/native/ui/ui.cpp index 0ed93c504c..f8ea4f574a 100644 --- a/ext/native/ui/ui.cpp +++ b/ext/native/ui/ui.cpp @@ -15,21 +15,12 @@ DrawBuffer ui_draw2d; DrawBuffer ui_draw2d_front; -void UIBegin(Draw::Pipeline *shaderSet) { - ui_draw2d.Begin(shaderSet); - ui_draw2d_front.Begin(shaderSet); +void UIBegin(Draw::Pipeline *pipeline) { + ui_draw2d.Begin(pipeline); + ui_draw2d_front.Begin(pipeline); } void UIFlush() { ui_draw2d.Flush(); ui_draw2d_front.Flush(); } - -void UIEnd() { - ui_draw2d.End(); - ui_draw2d_front.End(); - - ui_draw2d.Flush(); - ui_draw2d_front.Flush(); -} - diff --git a/ext/native/ui/ui.h b/ext/native/ui/ui.h index 369c3ce4b1..f3e2ff327f 100644 --- a/ext/native/ui/ui.h +++ b/ext/native/ui/ui.h @@ -60,11 +60,7 @@ private: }; -// Call at start of frame +// Begins/flushes the two UI drawbuffers together. void UIBegin(Draw::Pipeline *shaderSet); - -// Call at end of frame. - -void UIEnd(); void UIFlush(); diff --git a/ext/native/ui/ui_context.cpp b/ext/native/ui/ui_context.cpp index a148a0b60d..0106888ec4 100644 --- a/ext/native/ui/ui_context.cpp +++ b/ext/native/ui/ui_context.cpp @@ -38,12 +38,14 @@ void UIContext::BeginFrame() { FLOG("Failed to load ui_atlas.zim"); } } + uidrawbufferTop_->SetCurZ(0.0f); + uidrawbuffer_->SetCurZ(0.0f); + ActivateTopScissor(); } void UIContext::Begin() { draw_->BindSamplerStates(0, 1, &sampler_); draw_->BindTexture(0, uitexture_->GetTexture()); - ActivateTopScissor(); UIBegin(ui_pipeline_); } @@ -52,24 +54,28 @@ void UIContext::BeginNoTex() { UIBegin(ui_pipeline_notex_); } +void UIContext::BeginPipeline(Draw::Pipeline *pipeline, Draw::SamplerState *samplerState) { + draw_->BindSamplerStates(0, 1, &sampler_); + draw_->BindTexture(0, uitexture_->GetTexture()); + UIBegin(pipeline); +} + void UIContext::RebindTexture() const { draw_->BindTexture(0, uitexture_->GetTexture()); } void UIContext::Flush() { if (uidrawbuffer_) { - uidrawbuffer_->End(); uidrawbuffer_->Flush(); } if (uidrawbufferTop_) { - uidrawbufferTop_->End(); uidrawbufferTop_->Flush(); } } -void UIContext::End() { - UIEnd(); - Flush(); +void UIContext::SetCurZ(float curZ) { + ui_draw2d.SetCurZ(curZ); + ui_draw2d_front.SetCurZ(curZ); } // TODO: Support transformed bounds using stencil instead. diff --git a/ext/native/ui/ui_context.h b/ext/native/ui/ui_context.h index 3b6c4d7e43..d48b5b1dbf 100644 --- a/ext/native/ui/ui_context.h +++ b/ext/native/ui/ui_context.h @@ -51,8 +51,8 @@ public: void Begin(); void BeginNoTex(); + void BeginPipeline(Draw::Pipeline *pipeline, Draw::SamplerState *samplerState); void Flush(); - void End(); void RebindTexture() const; @@ -86,6 +86,7 @@ public: void SetBounds(const Bounds &b) { bounds_ = b; } const Bounds &GetBounds() const { return bounds_; } Draw::DrawContext *GetDrawContext() { return draw_; } + void SetCurZ(float curZ); void PushTransform(const UITransform &transform); void PopTransform(); diff --git a/ext/native/ui/ui_screen.cpp b/ext/native/ui/ui_screen.cpp index 3339c8d25b..a49877327d 100644 --- a/ext/native/ui/ui_screen.cpp +++ b/ext/native/ui/ui_screen.cpp @@ -78,9 +78,9 @@ void UIScreen::preRender() { return; } draw->BeginFrame(); - screenManager()->getUIContext()->BeginFrame(); // Bind and clear the back buffer draw->BindFramebufferAsRenderTarget(nullptr, { RPAction::CLEAR, RPAction::CLEAR, RPAction::CLEAR, 0xFF000000 }); + screenManager()->getUIContext()->BeginFrame(); Draw::Viewport viewport; viewport.TopLeftX = 0; @@ -113,7 +113,6 @@ void UIScreen::render() { uiContext->Begin(); DrawBackground(*uiContext); root_->Draw(*uiContext); - uiContext->End(); uiContext->Flush(); uiContext->PopTransform(); diff --git a/ext/native/ui/view.cpp b/ext/native/ui/view.cpp index 5f1deac264..2a0fc2cbb6 100644 --- a/ext/native/ui/view.cpp +++ b/ext/native/ui/view.cpp @@ -658,10 +658,16 @@ void PopupHeader::Draw(UIContext &dc) { } } -void CheckBox::Toggle(){ +void CheckBox::Toggle() { if (toggle_) *toggle_ = !(*toggle_); -}; +} + +bool CheckBox::Toggled() const { + if (toggle_) + return *toggle_; + return false; +} EventReturn CheckBox::OnClicked(EventParams &e) { Toggle(); @@ -676,7 +682,7 @@ void CheckBox::Draw(UIContext &dc) { ClickableItem::Draw(dc); - int image = *toggle_ ? dc.theme->checkOn : dc.theme->checkOff; + int image = Toggled() ? dc.theme->checkOn : dc.theme->checkOff; float imageW, imageH; dc.Draw()->MeasureImage(image, &imageW, &imageH); @@ -703,7 +709,7 @@ float CheckBox::CalculateTextScale(const UIContext &dc, float availWidth) const } void CheckBox::GetContentDimensions(const UIContext &dc, float &w, float &h) const { - int image = *toggle_ ? dc.theme->checkOn : dc.theme->checkOff; + int image = Toggled() ? dc.theme->checkOn : dc.theme->checkOff; float imageW, imageH; dc.Draw()->MeasureImage(image, &imageW, &imageH); @@ -724,6 +730,17 @@ void CheckBox::GetContentDimensions(const UIContext &dc, float &w, float &h) con h = std::max(actualHeight, ITEM_HEIGHT); } +void BitCheckBox::Toggle() { + if (bitfield_) + *bitfield_ = *bitfield_ ^ bit_; +} + +bool BitCheckBox::Toggled() const { + if (bitfield_) + return (bit_ & *bitfield_) == bit_; + return false; +} + void Button::GetContentDimensions(const UIContext &dc, float &w, float &h) const { if (imageID_ != -1) { const AtlasImage *img = &dc.Draw()->GetAtlas()->images[imageID_]; diff --git a/ext/native/ui/view.h b/ext/native/ui/view.h index 3d89ea4d65..2ca22d1c38 100644 --- a/ext/native/ui/view.h +++ b/ext/native/ui/view.h @@ -742,7 +742,8 @@ public: EventReturn OnClicked(EventParams &e); //allow external agents to toggle the checkbox - void Toggle(); + virtual void Toggle(); + virtual bool Toggled() const; private: float CalculateTextScale(const UIContext &dc, float availWidth) const; @@ -751,6 +752,20 @@ private: std::string smallText_; }; +class BitCheckBox : public CheckBox { +public: + BitCheckBox(uint32_t *bitfield, uint32_t bit, const std::string &text, const std::string &smallText = "", LayoutParams *layoutParams = nullptr) + : CheckBox(nullptr, text, smallText, layoutParams), bitfield_(bitfield), bit_(bit) { + } + + void Toggle() override; + bool Toggled() const override; + +private: + uint32_t *bitfield_; + uint32_t bit_; +}; + // These are for generic use. class Spacer : public InertView { diff --git a/ext/vulkan/spirv.h b/ext/vulkan/spirv.h index 2be35146df..081e12b4c1 100644 --- a/ext/vulkan/spirv.h +++ b/ext/vulkan/spirv.h @@ -1,5 +1,5 @@ /* -** Copyright (c) 2014-2017 The Khronos Group Inc. +** Copyright (c) 2014-2019 The Khronos Group Inc. ** ** Permission is hereby granted, free of charge, to any person obtaining a copy ** of this software and/or associated documentation files (the "Materials"), @@ -31,13 +31,16 @@ /* ** Enumeration tokens for SPIR-V, in various styles: -** C, C++, C++11, JSON, Lua, Python +** C, C++, C++11, JSON, Lua, Python, C#, D ** ** - C will have tokens with a "Spv" prefix, e.g.: SpvSourceLanguageGLSL ** - C++ will have tokens in the "spv" name space, e.g.: spv::SourceLanguageGLSL ** - C++11 will use enum classes in the spv namespace, e.g.: spv::SourceLanguage::GLSL ** - Lua will use tables, e.g.: spv.SourceLanguage.GLSL ** - Python will use dictionaries, e.g.: spv['SourceLanguage']['GLSL'] +** - C# will use enum classes in the Specification class located in the "Spv" namespace, +** e.g.: Spv.Specification.SourceLanguage.GLSL +** - D will have tokens under the "spv" module, e.g: spv.SourceLanguage.GLSL ** ** Some tokens act like mask values, which can be OR'd together, ** while others are mutually exclusive. The mask-like ones have @@ -50,12 +53,12 @@ typedef unsigned int SpvId; -#define SPV_VERSION 0x10100 -#define SPV_REVISION 8 +#define SPV_VERSION 0x10300 +#define SPV_REVISION 6 static const unsigned int SpvMagicNumber = 0x07230203; -static const unsigned int SpvVersion = 0x00010100; -static const unsigned int SpvRevision = 8; +static const unsigned int SpvVersion = 0x00010300; +static const unsigned int SpvRevision = 6; static const unsigned int SpvOpCodeMask = 0xffff; static const unsigned int SpvWordCountShift = 16; @@ -77,6 +80,14 @@ typedef enum SpvExecutionModel_ { SpvExecutionModelFragment = 4, SpvExecutionModelGLCompute = 5, SpvExecutionModelKernel = 6, + SpvExecutionModelTaskNV = 5267, + SpvExecutionModelMeshNV = 5268, + SpvExecutionModelRayGenerationNV = 5313, + SpvExecutionModelIntersectionNV = 5314, + SpvExecutionModelAnyHitNV = 5315, + SpvExecutionModelClosestHitNV = 5316, + SpvExecutionModelMissNV = 5317, + SpvExecutionModelCallableNV = 5318, SpvExecutionModelMax = 0x7fffffff, } SpvExecutionModel; @@ -84,6 +95,7 @@ typedef enum SpvAddressingModel_ { SpvAddressingModelLogical = 0, SpvAddressingModelPhysical32 = 1, SpvAddressingModelPhysical64 = 2, + SpvAddressingModelPhysicalStorageBuffer64EXT = 5348, SpvAddressingModelMax = 0x7fffffff, } SpvAddressingModel; @@ -91,6 +103,7 @@ typedef enum SpvMemoryModel_ { SpvMemoryModelSimple = 0, SpvMemoryModelGLSL450 = 1, SpvMemoryModelOpenCL = 2, + SpvMemoryModelVulkanKHR = 3, SpvMemoryModelMax = 0x7fffffff, } SpvMemoryModel; @@ -130,8 +143,21 @@ typedef enum SpvExecutionMode_ { SpvExecutionModeFinalizer = 34, SpvExecutionModeSubgroupSize = 35, SpvExecutionModeSubgroupsPerWorkgroup = 36, + SpvExecutionModeSubgroupsPerWorkgroupId = 37, + SpvExecutionModeLocalSizeId = 38, + SpvExecutionModeLocalSizeHintId = 39, SpvExecutionModePostDepthCoverage = 4446, + SpvExecutionModeDenormPreserve = 4459, + SpvExecutionModeDenormFlushToZero = 4460, + SpvExecutionModeSignedZeroInfNanPreserve = 4461, + SpvExecutionModeRoundingModeRTE = 4462, + SpvExecutionModeRoundingModeRTZ = 4463, SpvExecutionModeStencilRefReplacingEXT = 5027, + SpvExecutionModeOutputLinesNV = 5269, + SpvExecutionModeOutputPrimitivesNV = 5270, + SpvExecutionModeDerivativeGroupQuadsNV = 5289, + SpvExecutionModeDerivativeGroupLinearNV = 5290, + SpvExecutionModeOutputTrianglesNV = 5298, SpvExecutionModeMax = 0x7fffffff, } SpvExecutionMode; @@ -149,6 +175,13 @@ typedef enum SpvStorageClass_ { SpvStorageClassAtomicCounter = 10, SpvStorageClassImage = 11, SpvStorageClassStorageBuffer = 12, + SpvStorageClassCallableDataNV = 5328, + SpvStorageClassIncomingCallableDataNV = 5329, + SpvStorageClassRayPayloadNV = 5338, + SpvStorageClassHitAttributeNV = 5339, + SpvStorageClassIncomingRayPayloadNV = 5342, + SpvStorageClassShaderRecordBufferNV = 5343, + SpvStorageClassPhysicalStorageBufferEXT = 5349, SpvStorageClassMax = 0x7fffffff, } SpvStorageClass; @@ -276,6 +309,10 @@ typedef enum SpvImageOperandsShift_ { SpvImageOperandsConstOffsetsShift = 5, SpvImageOperandsSampleShift = 6, SpvImageOperandsMinLodShift = 7, + SpvImageOperandsMakeTexelAvailableKHRShift = 8, + SpvImageOperandsMakeTexelVisibleKHRShift = 9, + SpvImageOperandsNonPrivateTexelKHRShift = 10, + SpvImageOperandsVolatileTexelKHRShift = 11, SpvImageOperandsMax = 0x7fffffff, } SpvImageOperandsShift; @@ -289,6 +326,10 @@ typedef enum SpvImageOperandsMask_ { SpvImageOperandsConstOffsetsMask = 0x00000020, SpvImageOperandsSampleMask = 0x00000040, SpvImageOperandsMinLodMask = 0x00000080, + SpvImageOperandsMakeTexelAvailableKHRMask = 0x00000100, + SpvImageOperandsMakeTexelVisibleKHRMask = 0x00000200, + SpvImageOperandsNonPrivateTexelKHRMask = 0x00000400, + SpvImageOperandsVolatileTexelKHRMask = 0x00000800, } SpvImageOperandsMask; typedef enum SpvFPFastMathModeShift_ { @@ -387,11 +428,24 @@ typedef enum SpvDecoration_ { SpvDecorationInputAttachmentIndex = 43, SpvDecorationAlignment = 44, SpvDecorationMaxByteOffset = 45, + SpvDecorationAlignmentId = 46, + SpvDecorationMaxByteOffsetId = 47, + SpvDecorationNoSignedWrap = 4469, + SpvDecorationNoUnsignedWrap = 4470, SpvDecorationExplicitInterpAMD = 4999, SpvDecorationOverrideCoverageNV = 5248, SpvDecorationPassthroughNV = 5250, SpvDecorationViewportRelativeNV = 5252, SpvDecorationSecondaryViewportRelativeNV = 5256, + SpvDecorationPerPrimitiveNV = 5271, + SpvDecorationPerViewNV = 5272, + SpvDecorationPerTaskNV = 5273, + SpvDecorationPerVertexNV = 5285, + SpvDecorationNonUniformEXT = 5300, + SpvDecorationRestrictPointerEXT = 5355, + SpvDecorationAliasedPointerEXT = 5356, + SpvDecorationHlslCounterBufferGOOGLE = 5634, + SpvDecorationHlslSemanticGOOGLE = 5635, SpvDecorationMax = 0x7fffffff, } SpvDecoration; @@ -437,10 +491,15 @@ typedef enum SpvBuiltIn_ { SpvBuiltInSubgroupLocalInvocationId = 41, SpvBuiltInVertexIndex = 42, SpvBuiltInInstanceIndex = 43, + SpvBuiltInSubgroupEqMask = 4416, SpvBuiltInSubgroupEqMaskKHR = 4416, + SpvBuiltInSubgroupGeMask = 4417, SpvBuiltInSubgroupGeMaskKHR = 4417, + SpvBuiltInSubgroupGtMask = 4418, SpvBuiltInSubgroupGtMaskKHR = 4418, + SpvBuiltInSubgroupLeMask = 4419, SpvBuiltInSubgroupLeMaskKHR = 4419, + SpvBuiltInSubgroupLtMask = 4420, SpvBuiltInSubgroupLtMaskKHR = 4420, SpvBuiltInBaseVertex = 4424, SpvBuiltInBaseInstance = 4425, @@ -460,6 +519,35 @@ typedef enum SpvBuiltIn_ { SpvBuiltInSecondaryViewportMaskNV = 5258, SpvBuiltInPositionPerViewNV = 5261, SpvBuiltInViewportMaskPerViewNV = 5262, + SpvBuiltInFullyCoveredEXT = 5264, + SpvBuiltInTaskCountNV = 5274, + SpvBuiltInPrimitiveCountNV = 5275, + SpvBuiltInPrimitiveIndicesNV = 5276, + SpvBuiltInClipDistancePerViewNV = 5277, + SpvBuiltInCullDistancePerViewNV = 5278, + SpvBuiltInLayerPerViewNV = 5279, + SpvBuiltInMeshViewCountNV = 5280, + SpvBuiltInMeshViewIndicesNV = 5281, + SpvBuiltInBaryCoordNV = 5286, + SpvBuiltInBaryCoordNoPerspNV = 5287, + SpvBuiltInFragSizeEXT = 5292, + SpvBuiltInFragmentSizeNV = 5292, + SpvBuiltInFragInvocationCountEXT = 5293, + SpvBuiltInInvocationsPerPixelNV = 5293, + SpvBuiltInLaunchIdNV = 5319, + SpvBuiltInLaunchSizeNV = 5320, + SpvBuiltInWorldRayOriginNV = 5321, + SpvBuiltInWorldRayDirectionNV = 5322, + SpvBuiltInObjectRayOriginNV = 5323, + SpvBuiltInObjectRayDirectionNV = 5324, + SpvBuiltInRayTminNV = 5325, + SpvBuiltInRayTmaxNV = 5326, + SpvBuiltInInstanceCustomIndexNV = 5327, + SpvBuiltInObjectToWorldNV = 5330, + SpvBuiltInWorldToObjectNV = 5331, + SpvBuiltInHitTNV = 5332, + SpvBuiltInHitKindNV = 5333, + SpvBuiltInIncomingRayFlagsNV = 5351, SpvBuiltInMax = 0x7fffffff, } SpvBuiltIn; @@ -518,6 +606,9 @@ typedef enum SpvMemorySemanticsShift_ { SpvMemorySemanticsCrossWorkgroupMemoryShift = 9, SpvMemorySemanticsAtomicCounterMemoryShift = 10, SpvMemorySemanticsImageMemoryShift = 11, + SpvMemorySemanticsOutputMemoryKHRShift = 12, + SpvMemorySemanticsMakeAvailableKHRShift = 13, + SpvMemorySemanticsMakeVisibleKHRShift = 14, SpvMemorySemanticsMax = 0x7fffffff, } SpvMemorySemanticsShift; @@ -533,12 +624,18 @@ typedef enum SpvMemorySemanticsMask_ { SpvMemorySemanticsCrossWorkgroupMemoryMask = 0x00000200, SpvMemorySemanticsAtomicCounterMemoryMask = 0x00000400, SpvMemorySemanticsImageMemoryMask = 0x00000800, + SpvMemorySemanticsOutputMemoryKHRMask = 0x00001000, + SpvMemorySemanticsMakeAvailableKHRMask = 0x00002000, + SpvMemorySemanticsMakeVisibleKHRMask = 0x00004000, } SpvMemorySemanticsMask; typedef enum SpvMemoryAccessShift_ { SpvMemoryAccessVolatileShift = 0, SpvMemoryAccessAlignedShift = 1, SpvMemoryAccessNontemporalShift = 2, + SpvMemoryAccessMakePointerAvailableKHRShift = 3, + SpvMemoryAccessMakePointerVisibleKHRShift = 4, + SpvMemoryAccessNonPrivatePointerKHRShift = 5, SpvMemoryAccessMax = 0x7fffffff, } SpvMemoryAccessShift; @@ -547,6 +644,9 @@ typedef enum SpvMemoryAccessMask_ { SpvMemoryAccessVolatileMask = 0x00000001, SpvMemoryAccessAlignedMask = 0x00000002, SpvMemoryAccessNontemporalMask = 0x00000004, + SpvMemoryAccessMakePointerAvailableKHRMask = 0x00000008, + SpvMemoryAccessMakePointerVisibleKHRMask = 0x00000010, + SpvMemoryAccessNonPrivatePointerKHRMask = 0x00000020, } SpvMemoryAccessMask; typedef enum SpvScope_ { @@ -555,6 +655,7 @@ typedef enum SpvScope_ { SpvScopeWorkgroup = 2, SpvScopeSubgroup = 3, SpvScopeInvocation = 4, + SpvScopeQueueFamilyKHR = 5, SpvScopeMax = 0x7fffffff, } SpvScope; @@ -562,6 +663,10 @@ typedef enum SpvGroupOperation_ { SpvGroupOperationReduce = 0, SpvGroupOperationInclusiveScan = 1, SpvGroupOperationExclusiveScan = 2, + SpvGroupOperationClusteredReduce = 3, + SpvGroupOperationPartitionedReduceNV = 6, + SpvGroupOperationPartitionedInclusiveScanNV = 7, + SpvGroupOperationPartitionedExclusiveScanNV = 8, SpvGroupOperationMax = 0x7fffffff, } SpvGroupOperation; @@ -642,6 +747,14 @@ typedef enum SpvCapability_ { SpvCapabilitySubgroupDispatch = 58, SpvCapabilityNamedBarrier = 59, SpvCapabilityPipeStorage = 60, + SpvCapabilityGroupNonUniform = 61, + SpvCapabilityGroupNonUniformVote = 62, + SpvCapabilityGroupNonUniformArithmetic = 63, + SpvCapabilityGroupNonUniformBallot = 64, + SpvCapabilityGroupNonUniformShuffle = 65, + SpvCapabilityGroupNonUniformShuffleRelative = 66, + SpvCapabilityGroupNonUniformClustered = 67, + SpvCapabilityGroupNonUniformQuad = 68, SpvCapabilitySubgroupBallotKHR = 4423, SpvCapabilityDrawParameters = 4427, SpvCapabilitySubgroupVoteKHR = 4431, @@ -657,6 +770,15 @@ typedef enum SpvCapability_ { SpvCapabilityVariablePointers = 4442, SpvCapabilityAtomicStorageOps = 4445, SpvCapabilitySampleMaskPostDepthCoverage = 4447, + SpvCapabilityStorageBuffer8BitAccess = 4448, + SpvCapabilityUniformAndStorageBuffer8BitAccess = 4449, + SpvCapabilityStoragePushConstant8 = 4450, + SpvCapabilityDenormPreserve = 4464, + SpvCapabilityDenormFlushToZero = 4465, + SpvCapabilitySignedZeroInfNanPreserve = 4466, + SpvCapabilityRoundingModeRTE = 4467, + SpvCapabilityRoundingModeRTZ = 4468, + SpvCapabilityFloat16ImageAMD = 5008, SpvCapabilityImageGatherBiasLodAMD = 5009, SpvCapabilityFragmentMaskAMD = 5010, SpvCapabilityStencilExportEXT = 5013, @@ -668,6 +790,31 @@ typedef enum SpvCapability_ { SpvCapabilityShaderViewportMaskNV = 5255, SpvCapabilityShaderStereoViewNV = 5259, SpvCapabilityPerViewAttributesNV = 5260, + SpvCapabilityFragmentFullyCoveredEXT = 5265, + SpvCapabilityMeshShadingNV = 5266, + SpvCapabilityImageFootprintNV = 5282, + SpvCapabilityFragmentBarycentricNV = 5284, + SpvCapabilityComputeDerivativeGroupQuadsNV = 5288, + SpvCapabilityFragmentDensityEXT = 5291, + SpvCapabilityShadingRateNV = 5291, + SpvCapabilityGroupNonUniformPartitionedNV = 5297, + SpvCapabilityShaderNonUniformEXT = 5301, + SpvCapabilityRuntimeDescriptorArrayEXT = 5302, + SpvCapabilityInputAttachmentArrayDynamicIndexingEXT = 5303, + SpvCapabilityUniformTexelBufferArrayDynamicIndexingEXT = 5304, + SpvCapabilityStorageTexelBufferArrayDynamicIndexingEXT = 5305, + SpvCapabilityUniformBufferArrayNonUniformIndexingEXT = 5306, + SpvCapabilitySampledImageArrayNonUniformIndexingEXT = 5307, + SpvCapabilityStorageBufferArrayNonUniformIndexingEXT = 5308, + SpvCapabilityStorageImageArrayNonUniformIndexingEXT = 5309, + SpvCapabilityInputAttachmentArrayNonUniformIndexingEXT = 5310, + SpvCapabilityUniformTexelBufferArrayNonUniformIndexingEXT = 5311, + SpvCapabilityStorageTexelBufferArrayNonUniformIndexingEXT = 5312, + SpvCapabilityRayTracingNV = 5340, + SpvCapabilityVulkanMemoryModelKHR = 5345, + SpvCapabilityVulkanMemoryModelDeviceScopeKHR = 5346, + SpvCapabilityPhysicalStorageBufferAddressesEXT = 5347, + SpvCapabilityComputeDerivativeGroupLinearNV = 5350, SpvCapabilitySubgroupShuffleINTEL = 5568, SpvCapabilitySubgroupBufferBlockIOINTEL = 5569, SpvCapabilitySubgroupImageBlockIOINTEL = 5570, @@ -979,6 +1126,42 @@ typedef enum SpvOp_ { SpvOpNamedBarrierInitialize = 328, SpvOpMemoryNamedBarrier = 329, SpvOpModuleProcessed = 330, + SpvOpExecutionModeId = 331, + SpvOpDecorateId = 332, + SpvOpGroupNonUniformElect = 333, + SpvOpGroupNonUniformAll = 334, + SpvOpGroupNonUniformAny = 335, + SpvOpGroupNonUniformAllEqual = 336, + SpvOpGroupNonUniformBroadcast = 337, + SpvOpGroupNonUniformBroadcastFirst = 338, + SpvOpGroupNonUniformBallot = 339, + SpvOpGroupNonUniformInverseBallot = 340, + SpvOpGroupNonUniformBallotBitExtract = 341, + SpvOpGroupNonUniformBallotBitCount = 342, + SpvOpGroupNonUniformBallotFindLSB = 343, + SpvOpGroupNonUniformBallotFindMSB = 344, + SpvOpGroupNonUniformShuffle = 345, + SpvOpGroupNonUniformShuffleXor = 346, + SpvOpGroupNonUniformShuffleUp = 347, + SpvOpGroupNonUniformShuffleDown = 348, + SpvOpGroupNonUniformIAdd = 349, + SpvOpGroupNonUniformFAdd = 350, + SpvOpGroupNonUniformIMul = 351, + SpvOpGroupNonUniformFMul = 352, + SpvOpGroupNonUniformSMin = 353, + SpvOpGroupNonUniformUMin = 354, + SpvOpGroupNonUniformFMin = 355, + SpvOpGroupNonUniformSMax = 356, + SpvOpGroupNonUniformUMax = 357, + SpvOpGroupNonUniformFMax = 358, + SpvOpGroupNonUniformBitwiseAnd = 359, + SpvOpGroupNonUniformBitwiseOr = 360, + SpvOpGroupNonUniformBitwiseXor = 361, + SpvOpGroupNonUniformLogicalAnd = 362, + SpvOpGroupNonUniformLogicalOr = 363, + SpvOpGroupNonUniformLogicalXor = 364, + SpvOpGroupNonUniformQuadBroadcast = 365, + SpvOpGroupNonUniformQuadSwap = 366, SpvOpSubgroupBallotKHR = 4421, SpvOpSubgroupFirstInvocationKHR = 4422, SpvOpSubgroupAllKHR = 4428, @@ -995,6 +1178,15 @@ typedef enum SpvOp_ { SpvOpGroupSMaxNonUniformAMD = 5007, SpvOpFragmentMaskFetchAMD = 5011, SpvOpFragmentFetchAMD = 5012, + SpvOpImageSampleFootprintNV = 5283, + SpvOpGroupNonUniformPartitionNV = 5296, + SpvOpWritePackedPrimitiveIndices4x8NV = 5299, + SpvOpReportIntersectionNV = 5334, + SpvOpIgnoreIntersectionNV = 5335, + SpvOpTerminateRayNV = 5336, + SpvOpTraceNV = 5337, + SpvOpTypeAccelerationStructureNV = 5341, + SpvOpExecuteCallableNV = 5344, SpvOpSubgroupShuffleINTEL = 5571, SpvOpSubgroupShuffleDownINTEL = 5572, SpvOpSubgroupShuffleUpINTEL = 5573, @@ -1003,6 +1195,8 @@ typedef enum SpvOp_ { SpvOpSubgroupBlockWriteINTEL = 5576, SpvOpSubgroupImageBlockReadINTEL = 5577, SpvOpSubgroupImageBlockWriteINTEL = 5578, + SpvOpDecorateStringGOOGLE = 5632, + SpvOpMemberDecorateStringGOOGLE = 5633, SpvOpMax = 0x7fffffff, } SpvOp; diff --git a/ext/vulkan/spirv.hpp b/ext/vulkan/spirv.hpp deleted file mode 100644 index b9ae21ecef..0000000000 --- a/ext/vulkan/spirv.hpp +++ /dev/null @@ -1,1019 +0,0 @@ -// Copyright (c) 2014-2017 The Khronos Group Inc. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and/or associated documentation files (the "Materials"), -// to deal in the Materials without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Materials, and to permit persons to whom the -// Materials are furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Materials. -// -// MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS -// STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND -// HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ -// -// THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS -// IN THE MATERIALS. - -// This header is automatically generated by the same tool that creates -// the Binary Section of the SPIR-V specification. - -// Enumeration tokens for SPIR-V, in various styles: -// C, C++, C++11, JSON, Lua, Python -// -// - C will have tokens with a "Spv" prefix, e.g.: SpvSourceLanguageGLSL -// - C++ will have tokens in the "spv" name space, e.g.: spv::SourceLanguageGLSL -// - C++11 will use enum classes in the spv namespace, e.g.: spv::SourceLanguage::GLSL -// - Lua will use tables, e.g.: spv.SourceLanguage.GLSL -// - Python will use dictionaries, e.g.: spv['SourceLanguage']['GLSL'] -// -// Some tokens act like mask values, which can be OR'd together, -// while others are mutually exclusive. The mask-like ones have -// "Mask" in their name, and a parallel enum that has the shift -// amount (1 << x) for each corresponding enumerant. - -#ifndef spirv_HPP -#define spirv_HPP - -namespace spv { - -typedef unsigned int Id; - -#define SPV_VERSION 0x10100 -#define SPV_REVISION 8 - -static const unsigned int MagicNumber = 0x07230203; -static const unsigned int Version = 0x00010100; -static const unsigned int Revision = 8; -static const unsigned int OpCodeMask = 0xffff; -static const unsigned int WordCountShift = 16; - -enum SourceLanguage { - SourceLanguageUnknown = 0, - SourceLanguageESSL = 1, - SourceLanguageGLSL = 2, - SourceLanguageOpenCL_C = 3, - SourceLanguageOpenCL_CPP = 4, - SourceLanguageHLSL = 5, - SourceLanguageMax = 0x7fffffff, -}; - -enum ExecutionModel { - ExecutionModelVertex = 0, - ExecutionModelTessellationControl = 1, - ExecutionModelTessellationEvaluation = 2, - ExecutionModelGeometry = 3, - ExecutionModelFragment = 4, - ExecutionModelGLCompute = 5, - ExecutionModelKernel = 6, - ExecutionModelMax = 0x7fffffff, -}; - -enum AddressingModel { - AddressingModelLogical = 0, - AddressingModelPhysical32 = 1, - AddressingModelPhysical64 = 2, - AddressingModelMax = 0x7fffffff, -}; - -enum MemoryModel { - MemoryModelSimple = 0, - MemoryModelGLSL450 = 1, - MemoryModelOpenCL = 2, - MemoryModelMax = 0x7fffffff, -}; - -enum ExecutionMode { - ExecutionModeInvocations = 0, - ExecutionModeSpacingEqual = 1, - ExecutionModeSpacingFractionalEven = 2, - ExecutionModeSpacingFractionalOdd = 3, - ExecutionModeVertexOrderCw = 4, - ExecutionModeVertexOrderCcw = 5, - ExecutionModePixelCenterInteger = 6, - ExecutionModeOriginUpperLeft = 7, - ExecutionModeOriginLowerLeft = 8, - ExecutionModeEarlyFragmentTests = 9, - ExecutionModePointMode = 10, - ExecutionModeXfb = 11, - ExecutionModeDepthReplacing = 12, - ExecutionModeDepthGreater = 14, - ExecutionModeDepthLess = 15, - ExecutionModeDepthUnchanged = 16, - ExecutionModeLocalSize = 17, - ExecutionModeLocalSizeHint = 18, - ExecutionModeInputPoints = 19, - ExecutionModeInputLines = 20, - ExecutionModeInputLinesAdjacency = 21, - ExecutionModeTriangles = 22, - ExecutionModeInputTrianglesAdjacency = 23, - ExecutionModeQuads = 24, - ExecutionModeIsolines = 25, - ExecutionModeOutputVertices = 26, - ExecutionModeOutputPoints = 27, - ExecutionModeOutputLineStrip = 28, - ExecutionModeOutputTriangleStrip = 29, - ExecutionModeVecTypeHint = 30, - ExecutionModeContractionOff = 31, - ExecutionModeInitializer = 33, - ExecutionModeFinalizer = 34, - ExecutionModeSubgroupSize = 35, - ExecutionModeSubgroupsPerWorkgroup = 36, - ExecutionModePostDepthCoverage = 4446, - ExecutionModeStencilRefReplacingEXT = 5027, - ExecutionModeMax = 0x7fffffff, -}; - -enum StorageClass { - StorageClassUniformConstant = 0, - StorageClassInput = 1, - StorageClassUniform = 2, - StorageClassOutput = 3, - StorageClassWorkgroup = 4, - StorageClassCrossWorkgroup = 5, - StorageClassPrivate = 6, - StorageClassFunction = 7, - StorageClassGeneric = 8, - StorageClassPushConstant = 9, - StorageClassAtomicCounter = 10, - StorageClassImage = 11, - StorageClassStorageBuffer = 12, - StorageClassMax = 0x7fffffff, -}; - -enum Dim { - Dim1D = 0, - Dim2D = 1, - Dim3D = 2, - DimCube = 3, - DimRect = 4, - DimBuffer = 5, - DimSubpassData = 6, - DimMax = 0x7fffffff, -}; - -enum SamplerAddressingMode { - SamplerAddressingModeNone = 0, - SamplerAddressingModeClampToEdge = 1, - SamplerAddressingModeClamp = 2, - SamplerAddressingModeRepeat = 3, - SamplerAddressingModeRepeatMirrored = 4, - SamplerAddressingModeMax = 0x7fffffff, -}; - -enum SamplerFilterMode { - SamplerFilterModeNearest = 0, - SamplerFilterModeLinear = 1, - SamplerFilterModeMax = 0x7fffffff, -}; - -enum ImageFormat { - ImageFormatUnknown = 0, - ImageFormatRgba32f = 1, - ImageFormatRgba16f = 2, - ImageFormatR32f = 3, - ImageFormatRgba8 = 4, - ImageFormatRgba8Snorm = 5, - ImageFormatRg32f = 6, - ImageFormatRg16f = 7, - ImageFormatR11fG11fB10f = 8, - ImageFormatR16f = 9, - ImageFormatRgba16 = 10, - ImageFormatRgb10A2 = 11, - ImageFormatRg16 = 12, - ImageFormatRg8 = 13, - ImageFormatR16 = 14, - ImageFormatR8 = 15, - ImageFormatRgba16Snorm = 16, - ImageFormatRg16Snorm = 17, - ImageFormatRg8Snorm = 18, - ImageFormatR16Snorm = 19, - ImageFormatR8Snorm = 20, - ImageFormatRgba32i = 21, - ImageFormatRgba16i = 22, - ImageFormatRgba8i = 23, - ImageFormatR32i = 24, - ImageFormatRg32i = 25, - ImageFormatRg16i = 26, - ImageFormatRg8i = 27, - ImageFormatR16i = 28, - ImageFormatR8i = 29, - ImageFormatRgba32ui = 30, - ImageFormatRgba16ui = 31, - ImageFormatRgba8ui = 32, - ImageFormatR32ui = 33, - ImageFormatRgb10a2ui = 34, - ImageFormatRg32ui = 35, - ImageFormatRg16ui = 36, - ImageFormatRg8ui = 37, - ImageFormatR16ui = 38, - ImageFormatR8ui = 39, - ImageFormatMax = 0x7fffffff, -}; - -enum ImageChannelOrder { - ImageChannelOrderR = 0, - ImageChannelOrderA = 1, - ImageChannelOrderRG = 2, - ImageChannelOrderRA = 3, - ImageChannelOrderRGB = 4, - ImageChannelOrderRGBA = 5, - ImageChannelOrderBGRA = 6, - ImageChannelOrderARGB = 7, - ImageChannelOrderIntensity = 8, - ImageChannelOrderLuminance = 9, - ImageChannelOrderRx = 10, - ImageChannelOrderRGx = 11, - ImageChannelOrderRGBx = 12, - ImageChannelOrderDepth = 13, - ImageChannelOrderDepthStencil = 14, - ImageChannelOrdersRGB = 15, - ImageChannelOrdersRGBx = 16, - ImageChannelOrdersRGBA = 17, - ImageChannelOrdersBGRA = 18, - ImageChannelOrderABGR = 19, - ImageChannelOrderMax = 0x7fffffff, -}; - -enum ImageChannelDataType { - ImageChannelDataTypeSnormInt8 = 0, - ImageChannelDataTypeSnormInt16 = 1, - ImageChannelDataTypeUnormInt8 = 2, - ImageChannelDataTypeUnormInt16 = 3, - ImageChannelDataTypeUnormShort565 = 4, - ImageChannelDataTypeUnormShort555 = 5, - ImageChannelDataTypeUnormInt101010 = 6, - ImageChannelDataTypeSignedInt8 = 7, - ImageChannelDataTypeSignedInt16 = 8, - ImageChannelDataTypeSignedInt32 = 9, - ImageChannelDataTypeUnsignedInt8 = 10, - ImageChannelDataTypeUnsignedInt16 = 11, - ImageChannelDataTypeUnsignedInt32 = 12, - ImageChannelDataTypeHalfFloat = 13, - ImageChannelDataTypeFloat = 14, - ImageChannelDataTypeUnormInt24 = 15, - ImageChannelDataTypeUnormInt101010_2 = 16, - ImageChannelDataTypeMax = 0x7fffffff, -}; - -enum ImageOperandsShift { - ImageOperandsBiasShift = 0, - ImageOperandsLodShift = 1, - ImageOperandsGradShift = 2, - ImageOperandsConstOffsetShift = 3, - ImageOperandsOffsetShift = 4, - ImageOperandsConstOffsetsShift = 5, - ImageOperandsSampleShift = 6, - ImageOperandsMinLodShift = 7, - ImageOperandsMax = 0x7fffffff, -}; - -enum ImageOperandsMask { - ImageOperandsMaskNone = 0, - ImageOperandsBiasMask = 0x00000001, - ImageOperandsLodMask = 0x00000002, - ImageOperandsGradMask = 0x00000004, - ImageOperandsConstOffsetMask = 0x00000008, - ImageOperandsOffsetMask = 0x00000010, - ImageOperandsConstOffsetsMask = 0x00000020, - ImageOperandsSampleMask = 0x00000040, - ImageOperandsMinLodMask = 0x00000080, -}; - -enum FPFastMathModeShift { - FPFastMathModeNotNaNShift = 0, - FPFastMathModeNotInfShift = 1, - FPFastMathModeNSZShift = 2, - FPFastMathModeAllowRecipShift = 3, - FPFastMathModeFastShift = 4, - FPFastMathModeMax = 0x7fffffff, -}; - -enum FPFastMathModeMask { - FPFastMathModeMaskNone = 0, - FPFastMathModeNotNaNMask = 0x00000001, - FPFastMathModeNotInfMask = 0x00000002, - FPFastMathModeNSZMask = 0x00000004, - FPFastMathModeAllowRecipMask = 0x00000008, - FPFastMathModeFastMask = 0x00000010, -}; - -enum FPRoundingMode { - FPRoundingModeRTE = 0, - FPRoundingModeRTZ = 1, - FPRoundingModeRTP = 2, - FPRoundingModeRTN = 3, - FPRoundingModeMax = 0x7fffffff, -}; - -enum LinkageType { - LinkageTypeExport = 0, - LinkageTypeImport = 1, - LinkageTypeMax = 0x7fffffff, -}; - -enum AccessQualifier { - AccessQualifierReadOnly = 0, - AccessQualifierWriteOnly = 1, - AccessQualifierReadWrite = 2, - AccessQualifierMax = 0x7fffffff, -}; - -enum FunctionParameterAttribute { - FunctionParameterAttributeZext = 0, - FunctionParameterAttributeSext = 1, - FunctionParameterAttributeByVal = 2, - FunctionParameterAttributeSret = 3, - FunctionParameterAttributeNoAlias = 4, - FunctionParameterAttributeNoCapture = 5, - FunctionParameterAttributeNoWrite = 6, - FunctionParameterAttributeNoReadWrite = 7, - FunctionParameterAttributeMax = 0x7fffffff, -}; - -enum Decoration { - DecorationRelaxedPrecision = 0, - DecorationSpecId = 1, - DecorationBlock = 2, - DecorationBufferBlock = 3, - DecorationRowMajor = 4, - DecorationColMajor = 5, - DecorationArrayStride = 6, - DecorationMatrixStride = 7, - DecorationGLSLShared = 8, - DecorationGLSLPacked = 9, - DecorationCPacked = 10, - DecorationBuiltIn = 11, - DecorationNoPerspective = 13, - DecorationFlat = 14, - DecorationPatch = 15, - DecorationCentroid = 16, - DecorationSample = 17, - DecorationInvariant = 18, - DecorationRestrict = 19, - DecorationAliased = 20, - DecorationVolatile = 21, - DecorationConstant = 22, - DecorationCoherent = 23, - DecorationNonWritable = 24, - DecorationNonReadable = 25, - DecorationUniform = 26, - DecorationSaturatedConversion = 28, - DecorationStream = 29, - DecorationLocation = 30, - DecorationComponent = 31, - DecorationIndex = 32, - DecorationBinding = 33, - DecorationDescriptorSet = 34, - DecorationOffset = 35, - DecorationXfbBuffer = 36, - DecorationXfbStride = 37, - DecorationFuncParamAttr = 38, - DecorationFPRoundingMode = 39, - DecorationFPFastMathMode = 40, - DecorationLinkageAttributes = 41, - DecorationNoContraction = 42, - DecorationInputAttachmentIndex = 43, - DecorationAlignment = 44, - DecorationMaxByteOffset = 45, - DecorationExplicitInterpAMD = 4999, - DecorationOverrideCoverageNV = 5248, - DecorationPassthroughNV = 5250, - DecorationViewportRelativeNV = 5252, - DecorationSecondaryViewportRelativeNV = 5256, - DecorationMax = 0x7fffffff, -}; - -enum BuiltIn { - BuiltInPosition = 0, - BuiltInPointSize = 1, - BuiltInClipDistance = 3, - BuiltInCullDistance = 4, - BuiltInVertexId = 5, - BuiltInInstanceId = 6, - BuiltInPrimitiveId = 7, - BuiltInInvocationId = 8, - BuiltInLayer = 9, - BuiltInViewportIndex = 10, - BuiltInTessLevelOuter = 11, - BuiltInTessLevelInner = 12, - BuiltInTessCoord = 13, - BuiltInPatchVertices = 14, - BuiltInFragCoord = 15, - BuiltInPointCoord = 16, - BuiltInFrontFacing = 17, - BuiltInSampleId = 18, - BuiltInSamplePosition = 19, - BuiltInSampleMask = 20, - BuiltInFragDepth = 22, - BuiltInHelperInvocation = 23, - BuiltInNumWorkgroups = 24, - BuiltInWorkgroupSize = 25, - BuiltInWorkgroupId = 26, - BuiltInLocalInvocationId = 27, - BuiltInGlobalInvocationId = 28, - BuiltInLocalInvocationIndex = 29, - BuiltInWorkDim = 30, - BuiltInGlobalSize = 31, - BuiltInEnqueuedWorkgroupSize = 32, - BuiltInGlobalOffset = 33, - BuiltInGlobalLinearId = 34, - BuiltInSubgroupSize = 36, - BuiltInSubgroupMaxSize = 37, - BuiltInNumSubgroups = 38, - BuiltInNumEnqueuedSubgroups = 39, - BuiltInSubgroupId = 40, - BuiltInSubgroupLocalInvocationId = 41, - BuiltInVertexIndex = 42, - BuiltInInstanceIndex = 43, - BuiltInSubgroupEqMaskKHR = 4416, - BuiltInSubgroupGeMaskKHR = 4417, - BuiltInSubgroupGtMaskKHR = 4418, - BuiltInSubgroupLeMaskKHR = 4419, - BuiltInSubgroupLtMaskKHR = 4420, - BuiltInBaseVertex = 4424, - BuiltInBaseInstance = 4425, - BuiltInDrawIndex = 4426, - BuiltInDeviceIndex = 4438, - BuiltInViewIndex = 4440, - BuiltInBaryCoordNoPerspAMD = 4992, - BuiltInBaryCoordNoPerspCentroidAMD = 4993, - BuiltInBaryCoordNoPerspSampleAMD = 4994, - BuiltInBaryCoordSmoothAMD = 4995, - BuiltInBaryCoordSmoothCentroidAMD = 4996, - BuiltInBaryCoordSmoothSampleAMD = 4997, - BuiltInBaryCoordPullModelAMD = 4998, - BuiltInFragStencilRefEXT = 5014, - BuiltInViewportMaskNV = 5253, - BuiltInSecondaryPositionNV = 5257, - BuiltInSecondaryViewportMaskNV = 5258, - BuiltInPositionPerViewNV = 5261, - BuiltInViewportMaskPerViewNV = 5262, - BuiltInMax = 0x7fffffff, -}; - -enum SelectionControlShift { - SelectionControlFlattenShift = 0, - SelectionControlDontFlattenShift = 1, - SelectionControlMax = 0x7fffffff, -}; - -enum SelectionControlMask { - SelectionControlMaskNone = 0, - SelectionControlFlattenMask = 0x00000001, - SelectionControlDontFlattenMask = 0x00000002, -}; - -enum LoopControlShift { - LoopControlUnrollShift = 0, - LoopControlDontUnrollShift = 1, - LoopControlDependencyInfiniteShift = 2, - LoopControlDependencyLengthShift = 3, - LoopControlMax = 0x7fffffff, -}; - -enum LoopControlMask { - LoopControlMaskNone = 0, - LoopControlUnrollMask = 0x00000001, - LoopControlDontUnrollMask = 0x00000002, - LoopControlDependencyInfiniteMask = 0x00000004, - LoopControlDependencyLengthMask = 0x00000008, -}; - -enum FunctionControlShift { - FunctionControlInlineShift = 0, - FunctionControlDontInlineShift = 1, - FunctionControlPureShift = 2, - FunctionControlConstShift = 3, - FunctionControlMax = 0x7fffffff, -}; - -enum FunctionControlMask { - FunctionControlMaskNone = 0, - FunctionControlInlineMask = 0x00000001, - FunctionControlDontInlineMask = 0x00000002, - FunctionControlPureMask = 0x00000004, - FunctionControlConstMask = 0x00000008, -}; - -enum MemorySemanticsShift { - MemorySemanticsAcquireShift = 1, - MemorySemanticsReleaseShift = 2, - MemorySemanticsAcquireReleaseShift = 3, - MemorySemanticsSequentiallyConsistentShift = 4, - MemorySemanticsUniformMemoryShift = 6, - MemorySemanticsSubgroupMemoryShift = 7, - MemorySemanticsWorkgroupMemoryShift = 8, - MemorySemanticsCrossWorkgroupMemoryShift = 9, - MemorySemanticsAtomicCounterMemoryShift = 10, - MemorySemanticsImageMemoryShift = 11, - MemorySemanticsMax = 0x7fffffff, -}; - -enum MemorySemanticsMask { - MemorySemanticsMaskNone = 0, - MemorySemanticsAcquireMask = 0x00000002, - MemorySemanticsReleaseMask = 0x00000004, - MemorySemanticsAcquireReleaseMask = 0x00000008, - MemorySemanticsSequentiallyConsistentMask = 0x00000010, - MemorySemanticsUniformMemoryMask = 0x00000040, - MemorySemanticsSubgroupMemoryMask = 0x00000080, - MemorySemanticsWorkgroupMemoryMask = 0x00000100, - MemorySemanticsCrossWorkgroupMemoryMask = 0x00000200, - MemorySemanticsAtomicCounterMemoryMask = 0x00000400, - MemorySemanticsImageMemoryMask = 0x00000800, -}; - -enum MemoryAccessShift { - MemoryAccessVolatileShift = 0, - MemoryAccessAlignedShift = 1, - MemoryAccessNontemporalShift = 2, - MemoryAccessMax = 0x7fffffff, -}; - -enum MemoryAccessMask { - MemoryAccessMaskNone = 0, - MemoryAccessVolatileMask = 0x00000001, - MemoryAccessAlignedMask = 0x00000002, - MemoryAccessNontemporalMask = 0x00000004, -}; - -enum Scope { - ScopeCrossDevice = 0, - ScopeDevice = 1, - ScopeWorkgroup = 2, - ScopeSubgroup = 3, - ScopeInvocation = 4, - ScopeMax = 0x7fffffff, -}; - -enum GroupOperation { - GroupOperationReduce = 0, - GroupOperationInclusiveScan = 1, - GroupOperationExclusiveScan = 2, - GroupOperationMax = 0x7fffffff, -}; - -enum KernelEnqueueFlags { - KernelEnqueueFlagsNoWait = 0, - KernelEnqueueFlagsWaitKernel = 1, - KernelEnqueueFlagsWaitWorkGroup = 2, - KernelEnqueueFlagsMax = 0x7fffffff, -}; - -enum KernelProfilingInfoShift { - KernelProfilingInfoCmdExecTimeShift = 0, - KernelProfilingInfoMax = 0x7fffffff, -}; - -enum KernelProfilingInfoMask { - KernelProfilingInfoMaskNone = 0, - KernelProfilingInfoCmdExecTimeMask = 0x00000001, -}; - -enum Capability { - CapabilityMatrix = 0, - CapabilityShader = 1, - CapabilityGeometry = 2, - CapabilityTessellation = 3, - CapabilityAddresses = 4, - CapabilityLinkage = 5, - CapabilityKernel = 6, - CapabilityVector16 = 7, - CapabilityFloat16Buffer = 8, - CapabilityFloat16 = 9, - CapabilityFloat64 = 10, - CapabilityInt64 = 11, - CapabilityInt64Atomics = 12, - CapabilityImageBasic = 13, - CapabilityImageReadWrite = 14, - CapabilityImageMipmap = 15, - CapabilityPipes = 17, - CapabilityGroups = 18, - CapabilityDeviceEnqueue = 19, - CapabilityLiteralSampler = 20, - CapabilityAtomicStorage = 21, - CapabilityInt16 = 22, - CapabilityTessellationPointSize = 23, - CapabilityGeometryPointSize = 24, - CapabilityImageGatherExtended = 25, - CapabilityStorageImageMultisample = 27, - CapabilityUniformBufferArrayDynamicIndexing = 28, - CapabilitySampledImageArrayDynamicIndexing = 29, - CapabilityStorageBufferArrayDynamicIndexing = 30, - CapabilityStorageImageArrayDynamicIndexing = 31, - CapabilityClipDistance = 32, - CapabilityCullDistance = 33, - CapabilityImageCubeArray = 34, - CapabilitySampleRateShading = 35, - CapabilityImageRect = 36, - CapabilitySampledRect = 37, - CapabilityGenericPointer = 38, - CapabilityInt8 = 39, - CapabilityInputAttachment = 40, - CapabilitySparseResidency = 41, - CapabilityMinLod = 42, - CapabilitySampled1D = 43, - CapabilityImage1D = 44, - CapabilitySampledCubeArray = 45, - CapabilitySampledBuffer = 46, - CapabilityImageBuffer = 47, - CapabilityImageMSArray = 48, - CapabilityStorageImageExtendedFormats = 49, - CapabilityImageQuery = 50, - CapabilityDerivativeControl = 51, - CapabilityInterpolationFunction = 52, - CapabilityTransformFeedback = 53, - CapabilityGeometryStreams = 54, - CapabilityStorageImageReadWithoutFormat = 55, - CapabilityStorageImageWriteWithoutFormat = 56, - CapabilityMultiViewport = 57, - CapabilitySubgroupDispatch = 58, - CapabilityNamedBarrier = 59, - CapabilityPipeStorage = 60, - CapabilitySubgroupBallotKHR = 4423, - CapabilityDrawParameters = 4427, - CapabilitySubgroupVoteKHR = 4431, - CapabilityStorageBuffer16BitAccess = 4433, - CapabilityStorageUniformBufferBlock16 = 4433, - CapabilityStorageUniform16 = 4434, - CapabilityUniformAndStorageBuffer16BitAccess = 4434, - CapabilityStoragePushConstant16 = 4435, - CapabilityStorageInputOutput16 = 4436, - CapabilityDeviceGroup = 4437, - CapabilityMultiView = 4439, - CapabilityVariablePointersStorageBuffer = 4441, - CapabilityVariablePointers = 4442, - CapabilityAtomicStorageOps = 4445, - CapabilitySampleMaskPostDepthCoverage = 4447, - CapabilityImageGatherBiasLodAMD = 5009, - CapabilityFragmentMaskAMD = 5010, - CapabilityStencilExportEXT = 5013, - CapabilityImageReadWriteLodAMD = 5015, - CapabilitySampleMaskOverrideCoverageNV = 5249, - CapabilityGeometryShaderPassthroughNV = 5251, - CapabilityShaderViewportIndexLayerEXT = 5254, - CapabilityShaderViewportIndexLayerNV = 5254, - CapabilityShaderViewportMaskNV = 5255, - CapabilityShaderStereoViewNV = 5259, - CapabilityPerViewAttributesNV = 5260, - CapabilitySubgroupShuffleINTEL = 5568, - CapabilitySubgroupBufferBlockIOINTEL = 5569, - CapabilitySubgroupImageBlockIOINTEL = 5570, - CapabilityMax = 0x7fffffff, -}; - -enum Op { - OpNop = 0, - OpUndef = 1, - OpSourceContinued = 2, - OpSource = 3, - OpSourceExtension = 4, - OpName = 5, - OpMemberName = 6, - OpString = 7, - OpLine = 8, - OpExtension = 10, - OpExtInstImport = 11, - OpExtInst = 12, - OpMemoryModel = 14, - OpEntryPoint = 15, - OpExecutionMode = 16, - OpCapability = 17, - OpTypeVoid = 19, - OpTypeBool = 20, - OpTypeInt = 21, - OpTypeFloat = 22, - OpTypeVector = 23, - OpTypeMatrix = 24, - OpTypeImage = 25, - OpTypeSampler = 26, - OpTypeSampledImage = 27, - OpTypeArray = 28, - OpTypeRuntimeArray = 29, - OpTypeStruct = 30, - OpTypeOpaque = 31, - OpTypePointer = 32, - OpTypeFunction = 33, - OpTypeEvent = 34, - OpTypeDeviceEvent = 35, - OpTypeReserveId = 36, - OpTypeQueue = 37, - OpTypePipe = 38, - OpTypeForwardPointer = 39, - OpConstantTrue = 41, - OpConstantFalse = 42, - OpConstant = 43, - OpConstantComposite = 44, - OpConstantSampler = 45, - OpConstantNull = 46, - OpSpecConstantTrue = 48, - OpSpecConstantFalse = 49, - OpSpecConstant = 50, - OpSpecConstantComposite = 51, - OpSpecConstantOp = 52, - OpFunction = 54, - OpFunctionParameter = 55, - OpFunctionEnd = 56, - OpFunctionCall = 57, - OpVariable = 59, - OpImageTexelPointer = 60, - OpLoad = 61, - OpStore = 62, - OpCopyMemory = 63, - OpCopyMemorySized = 64, - OpAccessChain = 65, - OpInBoundsAccessChain = 66, - OpPtrAccessChain = 67, - OpArrayLength = 68, - OpGenericPtrMemSemantics = 69, - OpInBoundsPtrAccessChain = 70, - OpDecorate = 71, - OpMemberDecorate = 72, - OpDecorationGroup = 73, - OpGroupDecorate = 74, - OpGroupMemberDecorate = 75, - OpVectorExtractDynamic = 77, - OpVectorInsertDynamic = 78, - OpVectorShuffle = 79, - OpCompositeConstruct = 80, - OpCompositeExtract = 81, - OpCompositeInsert = 82, - OpCopyObject = 83, - OpTranspose = 84, - OpSampledImage = 86, - OpImageSampleImplicitLod = 87, - OpImageSampleExplicitLod = 88, - OpImageSampleDrefImplicitLod = 89, - OpImageSampleDrefExplicitLod = 90, - OpImageSampleProjImplicitLod = 91, - OpImageSampleProjExplicitLod = 92, - OpImageSampleProjDrefImplicitLod = 93, - OpImageSampleProjDrefExplicitLod = 94, - OpImageFetch = 95, - OpImageGather = 96, - OpImageDrefGather = 97, - OpImageRead = 98, - OpImageWrite = 99, - OpImage = 100, - OpImageQueryFormat = 101, - OpImageQueryOrder = 102, - OpImageQuerySizeLod = 103, - OpImageQuerySize = 104, - OpImageQueryLod = 105, - OpImageQueryLevels = 106, - OpImageQuerySamples = 107, - OpConvertFToU = 109, - OpConvertFToS = 110, - OpConvertSToF = 111, - OpConvertUToF = 112, - OpUConvert = 113, - OpSConvert = 114, - OpFConvert = 115, - OpQuantizeToF16 = 116, - OpConvertPtrToU = 117, - OpSatConvertSToU = 118, - OpSatConvertUToS = 119, - OpConvertUToPtr = 120, - OpPtrCastToGeneric = 121, - OpGenericCastToPtr = 122, - OpGenericCastToPtrExplicit = 123, - OpBitcast = 124, - OpSNegate = 126, - OpFNegate = 127, - OpIAdd = 128, - OpFAdd = 129, - OpISub = 130, - OpFSub = 131, - OpIMul = 132, - OpFMul = 133, - OpUDiv = 134, - OpSDiv = 135, - OpFDiv = 136, - OpUMod = 137, - OpSRem = 138, - OpSMod = 139, - OpFRem = 140, - OpFMod = 141, - OpVectorTimesScalar = 142, - OpMatrixTimesScalar = 143, - OpVectorTimesMatrix = 144, - OpMatrixTimesVector = 145, - OpMatrixTimesMatrix = 146, - OpOuterProduct = 147, - OpDot = 148, - OpIAddCarry = 149, - OpISubBorrow = 150, - OpUMulExtended = 151, - OpSMulExtended = 152, - OpAny = 154, - OpAll = 155, - OpIsNan = 156, - OpIsInf = 157, - OpIsFinite = 158, - OpIsNormal = 159, - OpSignBitSet = 160, - OpLessOrGreater = 161, - OpOrdered = 162, - OpUnordered = 163, - OpLogicalEqual = 164, - OpLogicalNotEqual = 165, - OpLogicalOr = 166, - OpLogicalAnd = 167, - OpLogicalNot = 168, - OpSelect = 169, - OpIEqual = 170, - OpINotEqual = 171, - OpUGreaterThan = 172, - OpSGreaterThan = 173, - OpUGreaterThanEqual = 174, - OpSGreaterThanEqual = 175, - OpULessThan = 176, - OpSLessThan = 177, - OpULessThanEqual = 178, - OpSLessThanEqual = 179, - OpFOrdEqual = 180, - OpFUnordEqual = 181, - OpFOrdNotEqual = 182, - OpFUnordNotEqual = 183, - OpFOrdLessThan = 184, - OpFUnordLessThan = 185, - OpFOrdGreaterThan = 186, - OpFUnordGreaterThan = 187, - OpFOrdLessThanEqual = 188, - OpFUnordLessThanEqual = 189, - OpFOrdGreaterThanEqual = 190, - OpFUnordGreaterThanEqual = 191, - OpShiftRightLogical = 194, - OpShiftRightArithmetic = 195, - OpShiftLeftLogical = 196, - OpBitwiseOr = 197, - OpBitwiseXor = 198, - OpBitwiseAnd = 199, - OpNot = 200, - OpBitFieldInsert = 201, - OpBitFieldSExtract = 202, - OpBitFieldUExtract = 203, - OpBitReverse = 204, - OpBitCount = 205, - OpDPdx = 207, - OpDPdy = 208, - OpFwidth = 209, - OpDPdxFine = 210, - OpDPdyFine = 211, - OpFwidthFine = 212, - OpDPdxCoarse = 213, - OpDPdyCoarse = 214, - OpFwidthCoarse = 215, - OpEmitVertex = 218, - OpEndPrimitive = 219, - OpEmitStreamVertex = 220, - OpEndStreamPrimitive = 221, - OpControlBarrier = 224, - OpMemoryBarrier = 225, - OpAtomicLoad = 227, - OpAtomicStore = 228, - OpAtomicExchange = 229, - OpAtomicCompareExchange = 230, - OpAtomicCompareExchangeWeak = 231, - OpAtomicIIncrement = 232, - OpAtomicIDecrement = 233, - OpAtomicIAdd = 234, - OpAtomicISub = 235, - OpAtomicSMin = 236, - OpAtomicUMin = 237, - OpAtomicSMax = 238, - OpAtomicUMax = 239, - OpAtomicAnd = 240, - OpAtomicOr = 241, - OpAtomicXor = 242, - OpPhi = 245, - OpLoopMerge = 246, - OpSelectionMerge = 247, - OpLabel = 248, - OpBranch = 249, - OpBranchConditional = 250, - OpSwitch = 251, - OpKill = 252, - OpReturn = 253, - OpReturnValue = 254, - OpUnreachable = 255, - OpLifetimeStart = 256, - OpLifetimeStop = 257, - OpGroupAsyncCopy = 259, - OpGroupWaitEvents = 260, - OpGroupAll = 261, - OpGroupAny = 262, - OpGroupBroadcast = 263, - OpGroupIAdd = 264, - OpGroupFAdd = 265, - OpGroupFMin = 266, - OpGroupUMin = 267, - OpGroupSMin = 268, - OpGroupFMax = 269, - OpGroupUMax = 270, - OpGroupSMax = 271, - OpReadPipe = 274, - OpWritePipe = 275, - OpReservedReadPipe = 276, - OpReservedWritePipe = 277, - OpReserveReadPipePackets = 278, - OpReserveWritePipePackets = 279, - OpCommitReadPipe = 280, - OpCommitWritePipe = 281, - OpIsValidReserveId = 282, - OpGetNumPipePackets = 283, - OpGetMaxPipePackets = 284, - OpGroupReserveReadPipePackets = 285, - OpGroupReserveWritePipePackets = 286, - OpGroupCommitReadPipe = 287, - OpGroupCommitWritePipe = 288, - OpEnqueueMarker = 291, - OpEnqueueKernel = 292, - OpGetKernelNDrangeSubGroupCount = 293, - OpGetKernelNDrangeMaxSubGroupSize = 294, - OpGetKernelWorkGroupSize = 295, - OpGetKernelPreferredWorkGroupSizeMultiple = 296, - OpRetainEvent = 297, - OpReleaseEvent = 298, - OpCreateUserEvent = 299, - OpIsValidEvent = 300, - OpSetUserEventStatus = 301, - OpCaptureEventProfilingInfo = 302, - OpGetDefaultQueue = 303, - OpBuildNDRange = 304, - OpImageSparseSampleImplicitLod = 305, - OpImageSparseSampleExplicitLod = 306, - OpImageSparseSampleDrefImplicitLod = 307, - OpImageSparseSampleDrefExplicitLod = 308, - OpImageSparseSampleProjImplicitLod = 309, - OpImageSparseSampleProjExplicitLod = 310, - OpImageSparseSampleProjDrefImplicitLod = 311, - OpImageSparseSampleProjDrefExplicitLod = 312, - OpImageSparseFetch = 313, - OpImageSparseGather = 314, - OpImageSparseDrefGather = 315, - OpImageSparseTexelsResident = 316, - OpNoLine = 317, - OpAtomicFlagTestAndSet = 318, - OpAtomicFlagClear = 319, - OpImageSparseRead = 320, - OpSizeOf = 321, - OpTypePipeStorage = 322, - OpConstantPipeStorage = 323, - OpCreatePipeFromPipeStorage = 324, - OpGetKernelLocalSizeForSubgroupCount = 325, - OpGetKernelMaxNumSubgroups = 326, - OpTypeNamedBarrier = 327, - OpNamedBarrierInitialize = 328, - OpMemoryNamedBarrier = 329, - OpModuleProcessed = 330, - OpSubgroupBallotKHR = 4421, - OpSubgroupFirstInvocationKHR = 4422, - OpSubgroupAllKHR = 4428, - OpSubgroupAnyKHR = 4429, - OpSubgroupAllEqualKHR = 4430, - OpSubgroupReadInvocationKHR = 4432, - OpGroupIAddNonUniformAMD = 5000, - OpGroupFAddNonUniformAMD = 5001, - OpGroupFMinNonUniformAMD = 5002, - OpGroupUMinNonUniformAMD = 5003, - OpGroupSMinNonUniformAMD = 5004, - OpGroupFMaxNonUniformAMD = 5005, - OpGroupUMaxNonUniformAMD = 5006, - OpGroupSMaxNonUniformAMD = 5007, - OpFragmentMaskFetchAMD = 5011, - OpFragmentFetchAMD = 5012, - OpSubgroupShuffleINTEL = 5571, - OpSubgroupShuffleDownINTEL = 5572, - OpSubgroupShuffleUpINTEL = 5573, - OpSubgroupShuffleXorINTEL = 5574, - OpSubgroupBlockReadINTEL = 5575, - OpSubgroupBlockWriteINTEL = 5576, - OpSubgroupImageBlockReadINTEL = 5577, - OpSubgroupImageBlockWriteINTEL = 5578, - OpMax = 0x7fffffff, -}; - -// Overload operator| for mask bit combining - -inline ImageOperandsMask operator|(ImageOperandsMask a, ImageOperandsMask b) { return ImageOperandsMask(unsigned(a) | unsigned(b)); } -inline FPFastMathModeMask operator|(FPFastMathModeMask a, FPFastMathModeMask b) { return FPFastMathModeMask(unsigned(a) | unsigned(b)); } -inline SelectionControlMask operator|(SelectionControlMask a, SelectionControlMask b) { return SelectionControlMask(unsigned(a) | unsigned(b)); } -inline LoopControlMask operator|(LoopControlMask a, LoopControlMask b) { return LoopControlMask(unsigned(a) | unsigned(b)); } -inline FunctionControlMask operator|(FunctionControlMask a, FunctionControlMask b) { return FunctionControlMask(unsigned(a) | unsigned(b)); } -inline MemorySemanticsMask operator|(MemorySemanticsMask a, MemorySemanticsMask b) { return MemorySemanticsMask(unsigned(a) | unsigned(b)); } -inline MemoryAccessMask operator|(MemoryAccessMask a, MemoryAccessMask b) { return MemoryAccessMask(unsigned(a) | unsigned(b)); } -inline KernelProfilingInfoMask operator|(KernelProfilingInfoMask a, KernelProfilingInfoMask b) { return KernelProfilingInfoMask(unsigned(a) | unsigned(b)); } - -} // end namespace spv - -#endif // #ifndef spirv_HPP - diff --git a/ext/vulkan/spirv.hpp11 b/ext/vulkan/spirv.hpp11 deleted file mode 100644 index c345f6da98..0000000000 --- a/ext/vulkan/spirv.hpp11 +++ /dev/null @@ -1,1019 +0,0 @@ -// Copyright (c) 2014-2017 The Khronos Group Inc. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and/or associated documentation files (the "Materials"), -// to deal in the Materials without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Materials, and to permit persons to whom the -// Materials are furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Materials. -// -// MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS -// STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND -// HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ -// -// THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS -// IN THE MATERIALS. - -// This header is automatically generated by the same tool that creates -// the Binary Section of the SPIR-V specification. - -// Enumeration tokens for SPIR-V, in various styles: -// C, C++, C++11, JSON, Lua, Python -// -// - C will have tokens with a "Spv" prefix, e.g.: SpvSourceLanguageGLSL -// - C++ will have tokens in the "spv" name space, e.g.: spv::SourceLanguageGLSL -// - C++11 will use enum classes in the spv namespace, e.g.: spv::SourceLanguage::GLSL -// - Lua will use tables, e.g.: spv.SourceLanguage.GLSL -// - Python will use dictionaries, e.g.: spv['SourceLanguage']['GLSL'] -// -// Some tokens act like mask values, which can be OR'd together, -// while others are mutually exclusive. The mask-like ones have -// "Mask" in their name, and a parallel enum that has the shift -// amount (1 << x) for each corresponding enumerant. - -#ifndef spirv_HPP -#define spirv_HPP - -namespace spv { - -typedef unsigned int Id; - -#define SPV_VERSION 0x10100 -#define SPV_REVISION 8 - -static const unsigned int MagicNumber = 0x07230203; -static const unsigned int Version = 0x00010100; -static const unsigned int Revision = 8; -static const unsigned int OpCodeMask = 0xffff; -static const unsigned int WordCountShift = 16; - -enum class SourceLanguage : unsigned { - Unknown = 0, - ESSL = 1, - GLSL = 2, - OpenCL_C = 3, - OpenCL_CPP = 4, - HLSL = 5, - Max = 0x7fffffff, -}; - -enum class ExecutionModel : unsigned { - Vertex = 0, - TessellationControl = 1, - TessellationEvaluation = 2, - Geometry = 3, - Fragment = 4, - GLCompute = 5, - Kernel = 6, - Max = 0x7fffffff, -}; - -enum class AddressingModel : unsigned { - Logical = 0, - Physical32 = 1, - Physical64 = 2, - Max = 0x7fffffff, -}; - -enum class MemoryModel : unsigned { - Simple = 0, - GLSL450 = 1, - OpenCL = 2, - Max = 0x7fffffff, -}; - -enum class ExecutionMode : unsigned { - Invocations = 0, - SpacingEqual = 1, - SpacingFractionalEven = 2, - SpacingFractionalOdd = 3, - VertexOrderCw = 4, - VertexOrderCcw = 5, - PixelCenterInteger = 6, - OriginUpperLeft = 7, - OriginLowerLeft = 8, - EarlyFragmentTests = 9, - PointMode = 10, - Xfb = 11, - DepthReplacing = 12, - DepthGreater = 14, - DepthLess = 15, - DepthUnchanged = 16, - LocalSize = 17, - LocalSizeHint = 18, - InputPoints = 19, - InputLines = 20, - InputLinesAdjacency = 21, - Triangles = 22, - InputTrianglesAdjacency = 23, - Quads = 24, - Isolines = 25, - OutputVertices = 26, - OutputPoints = 27, - OutputLineStrip = 28, - OutputTriangleStrip = 29, - VecTypeHint = 30, - ContractionOff = 31, - Initializer = 33, - Finalizer = 34, - SubgroupSize = 35, - SubgroupsPerWorkgroup = 36, - PostDepthCoverage = 4446, - StencilRefReplacingEXT = 5027, - Max = 0x7fffffff, -}; - -enum class StorageClass : unsigned { - UniformConstant = 0, - Input = 1, - Uniform = 2, - Output = 3, - Workgroup = 4, - CrossWorkgroup = 5, - Private = 6, - Function = 7, - Generic = 8, - PushConstant = 9, - AtomicCounter = 10, - Image = 11, - StorageBuffer = 12, - Max = 0x7fffffff, -}; - -enum class Dim : unsigned { - Dim1D = 0, - Dim2D = 1, - Dim3D = 2, - Cube = 3, - Rect = 4, - Buffer = 5, - SubpassData = 6, - Max = 0x7fffffff, -}; - -enum class SamplerAddressingMode : unsigned { - None = 0, - ClampToEdge = 1, - Clamp = 2, - Repeat = 3, - RepeatMirrored = 4, - Max = 0x7fffffff, -}; - -enum class SamplerFilterMode : unsigned { - Nearest = 0, - Linear = 1, - Max = 0x7fffffff, -}; - -enum class ImageFormat : unsigned { - Unknown = 0, - Rgba32f = 1, - Rgba16f = 2, - R32f = 3, - Rgba8 = 4, - Rgba8Snorm = 5, - Rg32f = 6, - Rg16f = 7, - R11fG11fB10f = 8, - R16f = 9, - Rgba16 = 10, - Rgb10A2 = 11, - Rg16 = 12, - Rg8 = 13, - R16 = 14, - R8 = 15, - Rgba16Snorm = 16, - Rg16Snorm = 17, - Rg8Snorm = 18, - R16Snorm = 19, - R8Snorm = 20, - Rgba32i = 21, - Rgba16i = 22, - Rgba8i = 23, - R32i = 24, - Rg32i = 25, - Rg16i = 26, - Rg8i = 27, - R16i = 28, - R8i = 29, - Rgba32ui = 30, - Rgba16ui = 31, - Rgba8ui = 32, - R32ui = 33, - Rgb10a2ui = 34, - Rg32ui = 35, - Rg16ui = 36, - Rg8ui = 37, - R16ui = 38, - R8ui = 39, - Max = 0x7fffffff, -}; - -enum class ImageChannelOrder : unsigned { - R = 0, - A = 1, - RG = 2, - RA = 3, - RGB = 4, - RGBA = 5, - BGRA = 6, - ARGB = 7, - Intensity = 8, - Luminance = 9, - Rx = 10, - RGx = 11, - RGBx = 12, - Depth = 13, - DepthStencil = 14, - sRGB = 15, - sRGBx = 16, - sRGBA = 17, - sBGRA = 18, - ABGR = 19, - Max = 0x7fffffff, -}; - -enum class ImageChannelDataType : unsigned { - SnormInt8 = 0, - SnormInt16 = 1, - UnormInt8 = 2, - UnormInt16 = 3, - UnormShort565 = 4, - UnormShort555 = 5, - UnormInt101010 = 6, - SignedInt8 = 7, - SignedInt16 = 8, - SignedInt32 = 9, - UnsignedInt8 = 10, - UnsignedInt16 = 11, - UnsignedInt32 = 12, - HalfFloat = 13, - Float = 14, - UnormInt24 = 15, - UnormInt101010_2 = 16, - Max = 0x7fffffff, -}; - -enum class ImageOperandsShift : unsigned { - Bias = 0, - Lod = 1, - Grad = 2, - ConstOffset = 3, - Offset = 4, - ConstOffsets = 5, - Sample = 6, - MinLod = 7, - Max = 0x7fffffff, -}; - -enum class ImageOperandsMask : unsigned { - MaskNone = 0, - Bias = 0x00000001, - Lod = 0x00000002, - Grad = 0x00000004, - ConstOffset = 0x00000008, - Offset = 0x00000010, - ConstOffsets = 0x00000020, - Sample = 0x00000040, - MinLod = 0x00000080, -}; - -enum class FPFastMathModeShift : unsigned { - NotNaN = 0, - NotInf = 1, - NSZ = 2, - AllowRecip = 3, - Fast = 4, - Max = 0x7fffffff, -}; - -enum class FPFastMathModeMask : unsigned { - MaskNone = 0, - NotNaN = 0x00000001, - NotInf = 0x00000002, - NSZ = 0x00000004, - AllowRecip = 0x00000008, - Fast = 0x00000010, -}; - -enum class FPRoundingMode : unsigned { - RTE = 0, - RTZ = 1, - RTP = 2, - RTN = 3, - Max = 0x7fffffff, -}; - -enum class LinkageType : unsigned { - Export = 0, - Import = 1, - Max = 0x7fffffff, -}; - -enum class AccessQualifier : unsigned { - ReadOnly = 0, - WriteOnly = 1, - ReadWrite = 2, - Max = 0x7fffffff, -}; - -enum class FunctionParameterAttribute : unsigned { - Zext = 0, - Sext = 1, - ByVal = 2, - Sret = 3, - NoAlias = 4, - NoCapture = 5, - NoWrite = 6, - NoReadWrite = 7, - Max = 0x7fffffff, -}; - -enum class Decoration : unsigned { - RelaxedPrecision = 0, - SpecId = 1, - Block = 2, - BufferBlock = 3, - RowMajor = 4, - ColMajor = 5, - ArrayStride = 6, - MatrixStride = 7, - GLSLShared = 8, - GLSLPacked = 9, - CPacked = 10, - BuiltIn = 11, - NoPerspective = 13, - Flat = 14, - Patch = 15, - Centroid = 16, - Sample = 17, - Invariant = 18, - Restrict = 19, - Aliased = 20, - Volatile = 21, - Constant = 22, - Coherent = 23, - NonWritable = 24, - NonReadable = 25, - Uniform = 26, - SaturatedConversion = 28, - Stream = 29, - Location = 30, - Component = 31, - Index = 32, - Binding = 33, - DescriptorSet = 34, - Offset = 35, - XfbBuffer = 36, - XfbStride = 37, - FuncParamAttr = 38, - FPRoundingMode = 39, - FPFastMathMode = 40, - LinkageAttributes = 41, - NoContraction = 42, - InputAttachmentIndex = 43, - Alignment = 44, - MaxByteOffset = 45, - ExplicitInterpAMD = 4999, - OverrideCoverageNV = 5248, - PassthroughNV = 5250, - ViewportRelativeNV = 5252, - SecondaryViewportRelativeNV = 5256, - Max = 0x7fffffff, -}; - -enum class BuiltIn : unsigned { - Position = 0, - PointSize = 1, - ClipDistance = 3, - CullDistance = 4, - VertexId = 5, - InstanceId = 6, - PrimitiveId = 7, - InvocationId = 8, - Layer = 9, - ViewportIndex = 10, - TessLevelOuter = 11, - TessLevelInner = 12, - TessCoord = 13, - PatchVertices = 14, - FragCoord = 15, - PointCoord = 16, - FrontFacing = 17, - SampleId = 18, - SamplePosition = 19, - SampleMask = 20, - FragDepth = 22, - HelperInvocation = 23, - NumWorkgroups = 24, - WorkgroupSize = 25, - WorkgroupId = 26, - LocalInvocationId = 27, - GlobalInvocationId = 28, - LocalInvocationIndex = 29, - WorkDim = 30, - GlobalSize = 31, - EnqueuedWorkgroupSize = 32, - GlobalOffset = 33, - GlobalLinearId = 34, - SubgroupSize = 36, - SubgroupMaxSize = 37, - NumSubgroups = 38, - NumEnqueuedSubgroups = 39, - SubgroupId = 40, - SubgroupLocalInvocationId = 41, - VertexIndex = 42, - InstanceIndex = 43, - SubgroupEqMaskKHR = 4416, - SubgroupGeMaskKHR = 4417, - SubgroupGtMaskKHR = 4418, - SubgroupLeMaskKHR = 4419, - SubgroupLtMaskKHR = 4420, - BaseVertex = 4424, - BaseInstance = 4425, - DrawIndex = 4426, - DeviceIndex = 4438, - ViewIndex = 4440, - BaryCoordNoPerspAMD = 4992, - BaryCoordNoPerspCentroidAMD = 4993, - BaryCoordNoPerspSampleAMD = 4994, - BaryCoordSmoothAMD = 4995, - BaryCoordSmoothCentroidAMD = 4996, - BaryCoordSmoothSampleAMD = 4997, - BaryCoordPullModelAMD = 4998, - FragStencilRefEXT = 5014, - ViewportMaskNV = 5253, - SecondaryPositionNV = 5257, - SecondaryViewportMaskNV = 5258, - PositionPerViewNV = 5261, - ViewportMaskPerViewNV = 5262, - Max = 0x7fffffff, -}; - -enum class SelectionControlShift : unsigned { - Flatten = 0, - DontFlatten = 1, - Max = 0x7fffffff, -}; - -enum class SelectionControlMask : unsigned { - MaskNone = 0, - Flatten = 0x00000001, - DontFlatten = 0x00000002, -}; - -enum class LoopControlShift : unsigned { - Unroll = 0, - DontUnroll = 1, - DependencyInfinite = 2, - DependencyLength = 3, - Max = 0x7fffffff, -}; - -enum class LoopControlMask : unsigned { - MaskNone = 0, - Unroll = 0x00000001, - DontUnroll = 0x00000002, - DependencyInfinite = 0x00000004, - DependencyLength = 0x00000008, -}; - -enum class FunctionControlShift : unsigned { - Inline = 0, - DontInline = 1, - Pure = 2, - Const = 3, - Max = 0x7fffffff, -}; - -enum class FunctionControlMask : unsigned { - MaskNone = 0, - Inline = 0x00000001, - DontInline = 0x00000002, - Pure = 0x00000004, - Const = 0x00000008, -}; - -enum class MemorySemanticsShift : unsigned { - Acquire = 1, - Release = 2, - AcquireRelease = 3, - SequentiallyConsistent = 4, - UniformMemory = 6, - SubgroupMemory = 7, - WorkgroupMemory = 8, - CrossWorkgroupMemory = 9, - AtomicCounterMemory = 10, - ImageMemory = 11, - Max = 0x7fffffff, -}; - -enum class MemorySemanticsMask : unsigned { - MaskNone = 0, - Acquire = 0x00000002, - Release = 0x00000004, - AcquireRelease = 0x00000008, - SequentiallyConsistent = 0x00000010, - UniformMemory = 0x00000040, - SubgroupMemory = 0x00000080, - WorkgroupMemory = 0x00000100, - CrossWorkgroupMemory = 0x00000200, - AtomicCounterMemory = 0x00000400, - ImageMemory = 0x00000800, -}; - -enum class MemoryAccessShift : unsigned { - Volatile = 0, - Aligned = 1, - Nontemporal = 2, - Max = 0x7fffffff, -}; - -enum class MemoryAccessMask : unsigned { - MaskNone = 0, - Volatile = 0x00000001, - Aligned = 0x00000002, - Nontemporal = 0x00000004, -}; - -enum class Scope : unsigned { - CrossDevice = 0, - Device = 1, - Workgroup = 2, - Subgroup = 3, - Invocation = 4, - Max = 0x7fffffff, -}; - -enum class GroupOperation : unsigned { - Reduce = 0, - InclusiveScan = 1, - ExclusiveScan = 2, - Max = 0x7fffffff, -}; - -enum class KernelEnqueueFlags : unsigned { - NoWait = 0, - WaitKernel = 1, - WaitWorkGroup = 2, - Max = 0x7fffffff, -}; - -enum class KernelProfilingInfoShift : unsigned { - CmdExecTime = 0, - Max = 0x7fffffff, -}; - -enum class KernelProfilingInfoMask : unsigned { - MaskNone = 0, - CmdExecTime = 0x00000001, -}; - -enum class Capability : unsigned { - Matrix = 0, - Shader = 1, - Geometry = 2, - Tessellation = 3, - Addresses = 4, - Linkage = 5, - Kernel = 6, - Vector16 = 7, - Float16Buffer = 8, - Float16 = 9, - Float64 = 10, - Int64 = 11, - Int64Atomics = 12, - ImageBasic = 13, - ImageReadWrite = 14, - ImageMipmap = 15, - Pipes = 17, - Groups = 18, - DeviceEnqueue = 19, - LiteralSampler = 20, - AtomicStorage = 21, - Int16 = 22, - TessellationPointSize = 23, - GeometryPointSize = 24, - ImageGatherExtended = 25, - StorageImageMultisample = 27, - UniformBufferArrayDynamicIndexing = 28, - SampledImageArrayDynamicIndexing = 29, - StorageBufferArrayDynamicIndexing = 30, - StorageImageArrayDynamicIndexing = 31, - ClipDistance = 32, - CullDistance = 33, - ImageCubeArray = 34, - SampleRateShading = 35, - ImageRect = 36, - SampledRect = 37, - GenericPointer = 38, - Int8 = 39, - InputAttachment = 40, - SparseResidency = 41, - MinLod = 42, - Sampled1D = 43, - Image1D = 44, - SampledCubeArray = 45, - SampledBuffer = 46, - ImageBuffer = 47, - ImageMSArray = 48, - StorageImageExtendedFormats = 49, - ImageQuery = 50, - DerivativeControl = 51, - InterpolationFunction = 52, - TransformFeedback = 53, - GeometryStreams = 54, - StorageImageReadWithoutFormat = 55, - StorageImageWriteWithoutFormat = 56, - MultiViewport = 57, - SubgroupDispatch = 58, - NamedBarrier = 59, - PipeStorage = 60, - SubgroupBallotKHR = 4423, - DrawParameters = 4427, - SubgroupVoteKHR = 4431, - StorageBuffer16BitAccess = 4433, - StorageUniformBufferBlock16 = 4433, - StorageUniform16 = 4434, - UniformAndStorageBuffer16BitAccess = 4434, - StoragePushConstant16 = 4435, - StorageInputOutput16 = 4436, - DeviceGroup = 4437, - MultiView = 4439, - VariablePointersStorageBuffer = 4441, - VariablePointers = 4442, - AtomicStorageOps = 4445, - SampleMaskPostDepthCoverage = 4447, - ImageGatherBiasLodAMD = 5009, - FragmentMaskAMD = 5010, - StencilExportEXT = 5013, - ImageReadWriteLodAMD = 5015, - SampleMaskOverrideCoverageNV = 5249, - GeometryShaderPassthroughNV = 5251, - ShaderViewportIndexLayerEXT = 5254, - ShaderViewportIndexLayerNV = 5254, - ShaderViewportMaskNV = 5255, - ShaderStereoViewNV = 5259, - PerViewAttributesNV = 5260, - SubgroupShuffleINTEL = 5568, - SubgroupBufferBlockIOINTEL = 5569, - SubgroupImageBlockIOINTEL = 5570, - Max = 0x7fffffff, -}; - -enum class Op : unsigned { - OpNop = 0, - OpUndef = 1, - OpSourceContinued = 2, - OpSource = 3, - OpSourceExtension = 4, - OpName = 5, - OpMemberName = 6, - OpString = 7, - OpLine = 8, - OpExtension = 10, - OpExtInstImport = 11, - OpExtInst = 12, - OpMemoryModel = 14, - OpEntryPoint = 15, - OpExecutionMode = 16, - OpCapability = 17, - OpTypeVoid = 19, - OpTypeBool = 20, - OpTypeInt = 21, - OpTypeFloat = 22, - OpTypeVector = 23, - OpTypeMatrix = 24, - OpTypeImage = 25, - OpTypeSampler = 26, - OpTypeSampledImage = 27, - OpTypeArray = 28, - OpTypeRuntimeArray = 29, - OpTypeStruct = 30, - OpTypeOpaque = 31, - OpTypePointer = 32, - OpTypeFunction = 33, - OpTypeEvent = 34, - OpTypeDeviceEvent = 35, - OpTypeReserveId = 36, - OpTypeQueue = 37, - OpTypePipe = 38, - OpTypeForwardPointer = 39, - OpConstantTrue = 41, - OpConstantFalse = 42, - OpConstant = 43, - OpConstantComposite = 44, - OpConstantSampler = 45, - OpConstantNull = 46, - OpSpecConstantTrue = 48, - OpSpecConstantFalse = 49, - OpSpecConstant = 50, - OpSpecConstantComposite = 51, - OpSpecConstantOp = 52, - OpFunction = 54, - OpFunctionParameter = 55, - OpFunctionEnd = 56, - OpFunctionCall = 57, - OpVariable = 59, - OpImageTexelPointer = 60, - OpLoad = 61, - OpStore = 62, - OpCopyMemory = 63, - OpCopyMemorySized = 64, - OpAccessChain = 65, - OpInBoundsAccessChain = 66, - OpPtrAccessChain = 67, - OpArrayLength = 68, - OpGenericPtrMemSemantics = 69, - OpInBoundsPtrAccessChain = 70, - OpDecorate = 71, - OpMemberDecorate = 72, - OpDecorationGroup = 73, - OpGroupDecorate = 74, - OpGroupMemberDecorate = 75, - OpVectorExtractDynamic = 77, - OpVectorInsertDynamic = 78, - OpVectorShuffle = 79, - OpCompositeConstruct = 80, - OpCompositeExtract = 81, - OpCompositeInsert = 82, - OpCopyObject = 83, - OpTranspose = 84, - OpSampledImage = 86, - OpImageSampleImplicitLod = 87, - OpImageSampleExplicitLod = 88, - OpImageSampleDrefImplicitLod = 89, - OpImageSampleDrefExplicitLod = 90, - OpImageSampleProjImplicitLod = 91, - OpImageSampleProjExplicitLod = 92, - OpImageSampleProjDrefImplicitLod = 93, - OpImageSampleProjDrefExplicitLod = 94, - OpImageFetch = 95, - OpImageGather = 96, - OpImageDrefGather = 97, - OpImageRead = 98, - OpImageWrite = 99, - OpImage = 100, - OpImageQueryFormat = 101, - OpImageQueryOrder = 102, - OpImageQuerySizeLod = 103, - OpImageQuerySize = 104, - OpImageQueryLod = 105, - OpImageQueryLevels = 106, - OpImageQuerySamples = 107, - OpConvertFToU = 109, - OpConvertFToS = 110, - OpConvertSToF = 111, - OpConvertUToF = 112, - OpUConvert = 113, - OpSConvert = 114, - OpFConvert = 115, - OpQuantizeToF16 = 116, - OpConvertPtrToU = 117, - OpSatConvertSToU = 118, - OpSatConvertUToS = 119, - OpConvertUToPtr = 120, - OpPtrCastToGeneric = 121, - OpGenericCastToPtr = 122, - OpGenericCastToPtrExplicit = 123, - OpBitcast = 124, - OpSNegate = 126, - OpFNegate = 127, - OpIAdd = 128, - OpFAdd = 129, - OpISub = 130, - OpFSub = 131, - OpIMul = 132, - OpFMul = 133, - OpUDiv = 134, - OpSDiv = 135, - OpFDiv = 136, - OpUMod = 137, - OpSRem = 138, - OpSMod = 139, - OpFRem = 140, - OpFMod = 141, - OpVectorTimesScalar = 142, - OpMatrixTimesScalar = 143, - OpVectorTimesMatrix = 144, - OpMatrixTimesVector = 145, - OpMatrixTimesMatrix = 146, - OpOuterProduct = 147, - OpDot = 148, - OpIAddCarry = 149, - OpISubBorrow = 150, - OpUMulExtended = 151, - OpSMulExtended = 152, - OpAny = 154, - OpAll = 155, - OpIsNan = 156, - OpIsInf = 157, - OpIsFinite = 158, - OpIsNormal = 159, - OpSignBitSet = 160, - OpLessOrGreater = 161, - OpOrdered = 162, - OpUnordered = 163, - OpLogicalEqual = 164, - OpLogicalNotEqual = 165, - OpLogicalOr = 166, - OpLogicalAnd = 167, - OpLogicalNot = 168, - OpSelect = 169, - OpIEqual = 170, - OpINotEqual = 171, - OpUGreaterThan = 172, - OpSGreaterThan = 173, - OpUGreaterThanEqual = 174, - OpSGreaterThanEqual = 175, - OpULessThan = 176, - OpSLessThan = 177, - OpULessThanEqual = 178, - OpSLessThanEqual = 179, - OpFOrdEqual = 180, - OpFUnordEqual = 181, - OpFOrdNotEqual = 182, - OpFUnordNotEqual = 183, - OpFOrdLessThan = 184, - OpFUnordLessThan = 185, - OpFOrdGreaterThan = 186, - OpFUnordGreaterThan = 187, - OpFOrdLessThanEqual = 188, - OpFUnordLessThanEqual = 189, - OpFOrdGreaterThanEqual = 190, - OpFUnordGreaterThanEqual = 191, - OpShiftRightLogical = 194, - OpShiftRightArithmetic = 195, - OpShiftLeftLogical = 196, - OpBitwiseOr = 197, - OpBitwiseXor = 198, - OpBitwiseAnd = 199, - OpNot = 200, - OpBitFieldInsert = 201, - OpBitFieldSExtract = 202, - OpBitFieldUExtract = 203, - OpBitReverse = 204, - OpBitCount = 205, - OpDPdx = 207, - OpDPdy = 208, - OpFwidth = 209, - OpDPdxFine = 210, - OpDPdyFine = 211, - OpFwidthFine = 212, - OpDPdxCoarse = 213, - OpDPdyCoarse = 214, - OpFwidthCoarse = 215, - OpEmitVertex = 218, - OpEndPrimitive = 219, - OpEmitStreamVertex = 220, - OpEndStreamPrimitive = 221, - OpControlBarrier = 224, - OpMemoryBarrier = 225, - OpAtomicLoad = 227, - OpAtomicStore = 228, - OpAtomicExchange = 229, - OpAtomicCompareExchange = 230, - OpAtomicCompareExchangeWeak = 231, - OpAtomicIIncrement = 232, - OpAtomicIDecrement = 233, - OpAtomicIAdd = 234, - OpAtomicISub = 235, - OpAtomicSMin = 236, - OpAtomicUMin = 237, - OpAtomicSMax = 238, - OpAtomicUMax = 239, - OpAtomicAnd = 240, - OpAtomicOr = 241, - OpAtomicXor = 242, - OpPhi = 245, - OpLoopMerge = 246, - OpSelectionMerge = 247, - OpLabel = 248, - OpBranch = 249, - OpBranchConditional = 250, - OpSwitch = 251, - OpKill = 252, - OpReturn = 253, - OpReturnValue = 254, - OpUnreachable = 255, - OpLifetimeStart = 256, - OpLifetimeStop = 257, - OpGroupAsyncCopy = 259, - OpGroupWaitEvents = 260, - OpGroupAll = 261, - OpGroupAny = 262, - OpGroupBroadcast = 263, - OpGroupIAdd = 264, - OpGroupFAdd = 265, - OpGroupFMin = 266, - OpGroupUMin = 267, - OpGroupSMin = 268, - OpGroupFMax = 269, - OpGroupUMax = 270, - OpGroupSMax = 271, - OpReadPipe = 274, - OpWritePipe = 275, - OpReservedReadPipe = 276, - OpReservedWritePipe = 277, - OpReserveReadPipePackets = 278, - OpReserveWritePipePackets = 279, - OpCommitReadPipe = 280, - OpCommitWritePipe = 281, - OpIsValidReserveId = 282, - OpGetNumPipePackets = 283, - OpGetMaxPipePackets = 284, - OpGroupReserveReadPipePackets = 285, - OpGroupReserveWritePipePackets = 286, - OpGroupCommitReadPipe = 287, - OpGroupCommitWritePipe = 288, - OpEnqueueMarker = 291, - OpEnqueueKernel = 292, - OpGetKernelNDrangeSubGroupCount = 293, - OpGetKernelNDrangeMaxSubGroupSize = 294, - OpGetKernelWorkGroupSize = 295, - OpGetKernelPreferredWorkGroupSizeMultiple = 296, - OpRetainEvent = 297, - OpReleaseEvent = 298, - OpCreateUserEvent = 299, - OpIsValidEvent = 300, - OpSetUserEventStatus = 301, - OpCaptureEventProfilingInfo = 302, - OpGetDefaultQueue = 303, - OpBuildNDRange = 304, - OpImageSparseSampleImplicitLod = 305, - OpImageSparseSampleExplicitLod = 306, - OpImageSparseSampleDrefImplicitLod = 307, - OpImageSparseSampleDrefExplicitLod = 308, - OpImageSparseSampleProjImplicitLod = 309, - OpImageSparseSampleProjExplicitLod = 310, - OpImageSparseSampleProjDrefImplicitLod = 311, - OpImageSparseSampleProjDrefExplicitLod = 312, - OpImageSparseFetch = 313, - OpImageSparseGather = 314, - OpImageSparseDrefGather = 315, - OpImageSparseTexelsResident = 316, - OpNoLine = 317, - OpAtomicFlagTestAndSet = 318, - OpAtomicFlagClear = 319, - OpImageSparseRead = 320, - OpSizeOf = 321, - OpTypePipeStorage = 322, - OpConstantPipeStorage = 323, - OpCreatePipeFromPipeStorage = 324, - OpGetKernelLocalSizeForSubgroupCount = 325, - OpGetKernelMaxNumSubgroups = 326, - OpTypeNamedBarrier = 327, - OpNamedBarrierInitialize = 328, - OpMemoryNamedBarrier = 329, - OpModuleProcessed = 330, - OpSubgroupBallotKHR = 4421, - OpSubgroupFirstInvocationKHR = 4422, - OpSubgroupAllKHR = 4428, - OpSubgroupAnyKHR = 4429, - OpSubgroupAllEqualKHR = 4430, - OpSubgroupReadInvocationKHR = 4432, - OpGroupIAddNonUniformAMD = 5000, - OpGroupFAddNonUniformAMD = 5001, - OpGroupFMinNonUniformAMD = 5002, - OpGroupUMinNonUniformAMD = 5003, - OpGroupSMinNonUniformAMD = 5004, - OpGroupFMaxNonUniformAMD = 5005, - OpGroupUMaxNonUniformAMD = 5006, - OpGroupSMaxNonUniformAMD = 5007, - OpFragmentMaskFetchAMD = 5011, - OpFragmentFetchAMD = 5012, - OpSubgroupShuffleINTEL = 5571, - OpSubgroupShuffleDownINTEL = 5572, - OpSubgroupShuffleUpINTEL = 5573, - OpSubgroupShuffleXorINTEL = 5574, - OpSubgroupBlockReadINTEL = 5575, - OpSubgroupBlockWriteINTEL = 5576, - OpSubgroupImageBlockReadINTEL = 5577, - OpSubgroupImageBlockWriteINTEL = 5578, - Max = 0x7fffffff, -}; - -// Overload operator| for mask bit combining - -inline ImageOperandsMask operator|(ImageOperandsMask a, ImageOperandsMask b) { return ImageOperandsMask(unsigned(a) | unsigned(b)); } -inline FPFastMathModeMask operator|(FPFastMathModeMask a, FPFastMathModeMask b) { return FPFastMathModeMask(unsigned(a) | unsigned(b)); } -inline SelectionControlMask operator|(SelectionControlMask a, SelectionControlMask b) { return SelectionControlMask(unsigned(a) | unsigned(b)); } -inline LoopControlMask operator|(LoopControlMask a, LoopControlMask b) { return LoopControlMask(unsigned(a) | unsigned(b)); } -inline FunctionControlMask operator|(FunctionControlMask a, FunctionControlMask b) { return FunctionControlMask(unsigned(a) | unsigned(b)); } -inline MemorySemanticsMask operator|(MemorySemanticsMask a, MemorySemanticsMask b) { return MemorySemanticsMask(unsigned(a) | unsigned(b)); } -inline MemoryAccessMask operator|(MemoryAccessMask a, MemoryAccessMask b) { return MemoryAccessMask(unsigned(a) | unsigned(b)); } -inline KernelProfilingInfoMask operator|(KernelProfilingInfoMask a, KernelProfilingInfoMask b) { return KernelProfilingInfoMask(unsigned(a) | unsigned(b)); } - -} // end namespace spv - -#endif // #ifndef spirv_HPP - diff --git a/ext/vulkan/spirv.json b/ext/vulkan/spirv.json index 988d7bf3ad..3b66cd96ed 100644 --- a/ext/vulkan/spirv.json +++ b/ext/vulkan/spirv.json @@ -6,7 +6,7 @@ "Comment": [ [ - "Copyright (c) 2014-2017 The Khronos Group Inc.", + "Copyright (c) 2014-2019 The Khronos Group Inc.", "", "Permission is hereby granted, free of charge, to any person obtaining a copy", "of this software and/or associated documentation files (the \"Materials\"),", @@ -36,13 +36,16 @@ ], [ "Enumeration tokens for SPIR-V, in various styles:", - " C, C++, C++11, JSON, Lua, Python", + " C, C++, C++11, JSON, Lua, Python, C#, D", "", "- C will have tokens with a \"Spv\" prefix, e.g.: SpvSourceLanguageGLSL", "- C++ will have tokens in the \"spv\" name space, e.g.: spv::SourceLanguageGLSL", "- C++11 will use enum classes in the spv namespace, e.g.: spv::SourceLanguage::GLSL", "- Lua will use tables, e.g.: spv.SourceLanguage.GLSL", "- Python will use dictionaries, e.g.: spv['SourceLanguage']['GLSL']", + "- C# will use enum classes in the Specification class located in the \"Spv\" namespace,", + " e.g.: Spv.Specification.SourceLanguage.GLSL", + "- D will have tokens under the \"spv\" module, e.g: spv.SourceLanguage.GLSL", "", "Some tokens act like mask values, which can be OR'd together,", "while others are mutually exclusive. The mask-like ones have", @@ -51,8 +54,8 @@ ] ], "MagicNumber": 119734787, - "Version": 65792, - "Revision": 8, + "Version": 66304, + "Revision": 6, "OpCodeMask": 65535, "WordCountShift": 16 }, @@ -82,7 +85,15 @@ "Geometry": 3, "Fragment": 4, "GLCompute": 5, - "Kernel": 6 + "Kernel": 6, + "TaskNV": 5267, + "MeshNV": 5268, + "RayGenerationNV": 5313, + "IntersectionNV": 5314, + "AnyHitNV": 5315, + "ClosestHitNV": 5316, + "MissNV": 5317, + "CallableNV": 5318 } }, { @@ -92,7 +103,8 @@ { "Logical": 0, "Physical32": 1, - "Physical64": 2 + "Physical64": 2, + "PhysicalStorageBuffer64EXT": 5348 } }, { @@ -102,7 +114,8 @@ { "Simple": 0, "GLSL450": 1, - "OpenCL": 2 + "OpenCL": 2, + "VulkanKHR": 3 } }, { @@ -145,8 +158,21 @@ "Finalizer": 34, "SubgroupSize": 35, "SubgroupsPerWorkgroup": 36, + "SubgroupsPerWorkgroupId": 37, + "LocalSizeId": 38, + "LocalSizeHintId": 39, "PostDepthCoverage": 4446, - "StencilRefReplacingEXT": 5027 + "DenormPreserve": 4459, + "DenormFlushToZero": 4460, + "SignedZeroInfNanPreserve": 4461, + "RoundingModeRTE": 4462, + "RoundingModeRTZ": 4463, + "StencilRefReplacingEXT": 5027, + "OutputLinesNV": 5269, + "OutputPrimitivesNV": 5270, + "DerivativeGroupQuadsNV": 5289, + "DerivativeGroupLinearNV": 5290, + "OutputTrianglesNV": 5298 } }, { @@ -166,7 +192,14 @@ "PushConstant": 9, "AtomicCounter": 10, "Image": 11, - "StorageBuffer": 12 + "StorageBuffer": 12, + "CallableDataNV": 5328, + "IncomingCallableDataNV": 5329, + "RayPayloadNV": 5338, + "HitAttributeNV": 5339, + "IncomingRayPayloadNV": 5342, + "ShaderRecordBufferNV": 5343, + "PhysicalStorageBufferEXT": 5349 } }, { @@ -314,7 +347,11 @@ "Offset": 4, "ConstOffsets": 5, "Sample": 6, - "MinLod": 7 + "MinLod": 7, + "MakeTexelAvailableKHR": 8, + "MakeTexelVisibleKHR": 9, + "NonPrivateTexelKHR": 10, + "VolatileTexelKHR": 11 } }, { @@ -423,11 +460,24 @@ "InputAttachmentIndex": 43, "Alignment": 44, "MaxByteOffset": 45, + "AlignmentId": 46, + "MaxByteOffsetId": 47, + "NoSignedWrap": 4469, + "NoUnsignedWrap": 4470, "ExplicitInterpAMD": 4999, "OverrideCoverageNV": 5248, "PassthroughNV": 5250, "ViewportRelativeNV": 5252, - "SecondaryViewportRelativeNV": 5256 + "SecondaryViewportRelativeNV": 5256, + "PerPrimitiveNV": 5271, + "PerViewNV": 5272, + "PerTaskNV": 5273, + "PerVertexNV": 5285, + "NonUniformEXT": 5300, + "RestrictPointerEXT": 5355, + "AliasedPointerEXT": 5356, + "HlslCounterBufferGOOGLE": 5634, + "HlslSemanticGOOGLE": 5635 } }, { @@ -476,10 +526,15 @@ "SubgroupLocalInvocationId": 41, "VertexIndex": 42, "InstanceIndex": 43, + "SubgroupEqMask": 4416, "SubgroupEqMaskKHR": 4416, + "SubgroupGeMask": 4417, "SubgroupGeMaskKHR": 4417, + "SubgroupGtMask": 4418, "SubgroupGtMaskKHR": 4418, + "SubgroupLeMask": 4419, "SubgroupLeMaskKHR": 4419, + "SubgroupLtMask": 4420, "SubgroupLtMaskKHR": 4420, "BaseVertex": 4424, "BaseInstance": 4425, @@ -498,7 +553,36 @@ "SecondaryPositionNV": 5257, "SecondaryViewportMaskNV": 5258, "PositionPerViewNV": 5261, - "ViewportMaskPerViewNV": 5262 + "ViewportMaskPerViewNV": 5262, + "FullyCoveredEXT": 5264, + "TaskCountNV": 5274, + "PrimitiveCountNV": 5275, + "PrimitiveIndicesNV": 5276, + "ClipDistancePerViewNV": 5277, + "CullDistancePerViewNV": 5278, + "LayerPerViewNV": 5279, + "MeshViewCountNV": 5280, + "MeshViewIndicesNV": 5281, + "BaryCoordNV": 5286, + "BaryCoordNoPerspNV": 5287, + "FragSizeEXT": 5292, + "FragmentSizeNV": 5292, + "FragInvocationCountEXT": 5293, + "InvocationsPerPixelNV": 5293, + "LaunchIdNV": 5319, + "LaunchSizeNV": 5320, + "WorldRayOriginNV": 5321, + "WorldRayDirectionNV": 5322, + "ObjectRayOriginNV": 5323, + "ObjectRayDirectionNV": 5324, + "RayTminNV": 5325, + "RayTmaxNV": 5326, + "InstanceCustomIndexNV": 5327, + "ObjectToWorldNV": 5330, + "WorldToObjectNV": 5331, + "HitTNV": 5332, + "HitKindNV": 5333, + "IncomingRayFlagsNV": 5351 } }, { @@ -546,7 +630,10 @@ "WorkgroupMemory": 8, "CrossWorkgroupMemory": 9, "AtomicCounterMemory": 10, - "ImageMemory": 11 + "ImageMemory": 11, + "OutputMemoryKHR": 12, + "MakeAvailableKHR": 13, + "MakeVisibleKHR": 14 } }, { @@ -556,7 +643,10 @@ { "Volatile": 0, "Aligned": 1, - "Nontemporal": 2 + "Nontemporal": 2, + "MakePointerAvailableKHR": 3, + "MakePointerVisibleKHR": 4, + "NonPrivatePointerKHR": 5 } }, { @@ -568,7 +658,8 @@ "Device": 1, "Workgroup": 2, "Subgroup": 3, - "Invocation": 4 + "Invocation": 4, + "QueueFamilyKHR": 5 } }, { @@ -578,7 +669,11 @@ { "Reduce": 0, "InclusiveScan": 1, - "ExclusiveScan": 2 + "ExclusiveScan": 2, + "ClusteredReduce": 3, + "PartitionedReduceNV": 6, + "PartitionedInclusiveScanNV": 7, + "PartitionedExclusiveScanNV": 8 } }, { @@ -663,6 +758,14 @@ "SubgroupDispatch": 58, "NamedBarrier": 59, "PipeStorage": 60, + "GroupNonUniform": 61, + "GroupNonUniformVote": 62, + "GroupNonUniformArithmetic": 63, + "GroupNonUniformBallot": 64, + "GroupNonUniformShuffle": 65, + "GroupNonUniformShuffleRelative": 66, + "GroupNonUniformClustered": 67, + "GroupNonUniformQuad": 68, "SubgroupBallotKHR": 4423, "DrawParameters": 4427, "SubgroupVoteKHR": 4431, @@ -678,6 +781,15 @@ "VariablePointers": 4442, "AtomicStorageOps": 4445, "SampleMaskPostDepthCoverage": 4447, + "StorageBuffer8BitAccess": 4448, + "UniformAndStorageBuffer8BitAccess": 4449, + "StoragePushConstant8": 4450, + "DenormPreserve": 4464, + "DenormFlushToZero": 4465, + "SignedZeroInfNanPreserve": 4466, + "RoundingModeRTE": 4467, + "RoundingModeRTZ": 4468, + "Float16ImageAMD": 5008, "ImageGatherBiasLodAMD": 5009, "FragmentMaskAMD": 5010, "StencilExportEXT": 5013, @@ -689,6 +801,31 @@ "ShaderViewportMaskNV": 5255, "ShaderStereoViewNV": 5259, "PerViewAttributesNV": 5260, + "FragmentFullyCoveredEXT": 5265, + "MeshShadingNV": 5266, + "ImageFootprintNV": 5282, + "FragmentBarycentricNV": 5284, + "ComputeDerivativeGroupQuadsNV": 5288, + "FragmentDensityEXT": 5291, + "ShadingRateNV": 5291, + "GroupNonUniformPartitionedNV": 5297, + "ShaderNonUniformEXT": 5301, + "RuntimeDescriptorArrayEXT": 5302, + "InputAttachmentArrayDynamicIndexingEXT": 5303, + "UniformTexelBufferArrayDynamicIndexingEXT": 5304, + "StorageTexelBufferArrayDynamicIndexingEXT": 5305, + "UniformBufferArrayNonUniformIndexingEXT": 5306, + "SampledImageArrayNonUniformIndexingEXT": 5307, + "StorageBufferArrayNonUniformIndexingEXT": 5308, + "StorageImageArrayNonUniformIndexingEXT": 5309, + "InputAttachmentArrayNonUniformIndexingEXT": 5310, + "UniformTexelBufferArrayNonUniformIndexingEXT": 5311, + "StorageTexelBufferArrayNonUniformIndexingEXT": 5312, + "RayTracingNV": 5340, + "VulkanMemoryModelKHR": 5345, + "VulkanMemoryModelDeviceScopeKHR": 5346, + "PhysicalStorageBufferAddressesEXT": 5347, + "ComputeDerivativeGroupLinearNV": 5350, "SubgroupShuffleINTEL": 5568, "SubgroupBufferBlockIOINTEL": 5569, "SubgroupImageBlockIOINTEL": 5570 @@ -1003,6 +1140,42 @@ "OpNamedBarrierInitialize": 328, "OpMemoryNamedBarrier": 329, "OpModuleProcessed": 330, + "OpExecutionModeId": 331, + "OpDecorateId": 332, + "OpGroupNonUniformElect": 333, + "OpGroupNonUniformAll": 334, + "OpGroupNonUniformAny": 335, + "OpGroupNonUniformAllEqual": 336, + "OpGroupNonUniformBroadcast": 337, + "OpGroupNonUniformBroadcastFirst": 338, + "OpGroupNonUniformBallot": 339, + "OpGroupNonUniformInverseBallot": 340, + "OpGroupNonUniformBallotBitExtract": 341, + "OpGroupNonUniformBallotBitCount": 342, + "OpGroupNonUniformBallotFindLSB": 343, + "OpGroupNonUniformBallotFindMSB": 344, + "OpGroupNonUniformShuffle": 345, + "OpGroupNonUniformShuffleXor": 346, + "OpGroupNonUniformShuffleUp": 347, + "OpGroupNonUniformShuffleDown": 348, + "OpGroupNonUniformIAdd": 349, + "OpGroupNonUniformFAdd": 350, + "OpGroupNonUniformIMul": 351, + "OpGroupNonUniformFMul": 352, + "OpGroupNonUniformSMin": 353, + "OpGroupNonUniformUMin": 354, + "OpGroupNonUniformFMin": 355, + "OpGroupNonUniformSMax": 356, + "OpGroupNonUniformUMax": 357, + "OpGroupNonUniformFMax": 358, + "OpGroupNonUniformBitwiseAnd": 359, + "OpGroupNonUniformBitwiseOr": 360, + "OpGroupNonUniformBitwiseXor": 361, + "OpGroupNonUniformLogicalAnd": 362, + "OpGroupNonUniformLogicalOr": 363, + "OpGroupNonUniformLogicalXor": 364, + "OpGroupNonUniformQuadBroadcast": 365, + "OpGroupNonUniformQuadSwap": 366, "OpSubgroupBallotKHR": 4421, "OpSubgroupFirstInvocationKHR": 4422, "OpSubgroupAllKHR": 4428, @@ -1019,6 +1192,15 @@ "OpGroupSMaxNonUniformAMD": 5007, "OpFragmentMaskFetchAMD": 5011, "OpFragmentFetchAMD": 5012, + "OpImageSampleFootprintNV": 5283, + "OpGroupNonUniformPartitionNV": 5296, + "OpWritePackedPrimitiveIndices4x8NV": 5299, + "OpReportIntersectionNV": 5334, + "OpIgnoreIntersectionNV": 5335, + "OpTerminateRayNV": 5336, + "OpTraceNV": 5337, + "OpTypeAccelerationStructureNV": 5341, + "OpExecuteCallableNV": 5344, "OpSubgroupShuffleINTEL": 5571, "OpSubgroupShuffleDownINTEL": 5572, "OpSubgroupShuffleUpINTEL": 5573, @@ -1026,7 +1208,9 @@ "OpSubgroupBlockReadINTEL": 5575, "OpSubgroupBlockWriteINTEL": 5576, "OpSubgroupImageBlockReadINTEL": 5577, - "OpSubgroupImageBlockWriteINTEL": 5578 + "OpSubgroupImageBlockWriteINTEL": 5578, + "OpDecorateStringGOOGLE": 5632, + "OpMemberDecorateStringGOOGLE": 5633 } } ] diff --git a/ext/vulkan/spirv.lua b/ext/vulkan/spirv.lua index 44688596cd..f74224f118 100644 --- a/ext/vulkan/spirv.lua +++ b/ext/vulkan/spirv.lua @@ -1,4 +1,4 @@ --- Copyright (c) 2014-2017 The Khronos Group Inc. +-- Copyright (c) 2014-2019 The Khronos Group Inc. -- -- Permission is hereby granted, free of charge, to any person obtaining a copy -- of this software and/or associated documentation files (the "Materials"), @@ -26,13 +26,16 @@ -- the Binary Section of the SPIR-V specification. -- Enumeration tokens for SPIR-V, in various styles: --- C, C++, C++11, JSON, Lua, Python +-- C, C++, C++11, JSON, Lua, Python, C#, D -- -- - C will have tokens with a "Spv" prefix, e.g.: SpvSourceLanguageGLSL -- - C++ will have tokens in the "spv" name space, e.g.: spv::SourceLanguageGLSL -- - C++11 will use enum classes in the spv namespace, e.g.: spv::SourceLanguage::GLSL -- - Lua will use tables, e.g.: spv.SourceLanguage.GLSL -- - Python will use dictionaries, e.g.: spv['SourceLanguage']['GLSL'] +-- - C# will use enum classes in the Specification class located in the "Spv" namespace, +-- e.g.: Spv.Specification.SourceLanguage.GLSL +-- - D will have tokens under the "spv" module, e.g: spv.SourceLanguage.GLSL -- -- Some tokens act like mask values, which can be OR'd together, -- while others are mutually exclusive. The mask-like ones have @@ -41,8 +44,8 @@ spv = { MagicNumber = 0x07230203, - Version = 0x00010100, - Revision = 8, + Version = 0x00010300, + Revision = 6, OpCodeMask = 0xffff, WordCountShift = 16, @@ -63,18 +66,28 @@ spv = { Fragment = 4, GLCompute = 5, Kernel = 6, + TaskNV = 5267, + MeshNV = 5268, + RayGenerationNV = 5313, + IntersectionNV = 5314, + AnyHitNV = 5315, + ClosestHitNV = 5316, + MissNV = 5317, + CallableNV = 5318, }, AddressingModel = { Logical = 0, Physical32 = 1, Physical64 = 2, + PhysicalStorageBuffer64EXT = 5348, }, MemoryModel = { Simple = 0, GLSL450 = 1, OpenCL = 2, + VulkanKHR = 3, }, ExecutionMode = { @@ -113,8 +126,21 @@ spv = { Finalizer = 34, SubgroupSize = 35, SubgroupsPerWorkgroup = 36, + SubgroupsPerWorkgroupId = 37, + LocalSizeId = 38, + LocalSizeHintId = 39, PostDepthCoverage = 4446, + DenormPreserve = 4459, + DenormFlushToZero = 4460, + SignedZeroInfNanPreserve = 4461, + RoundingModeRTE = 4462, + RoundingModeRTZ = 4463, StencilRefReplacingEXT = 5027, + OutputLinesNV = 5269, + OutputPrimitivesNV = 5270, + DerivativeGroupQuadsNV = 5289, + DerivativeGroupLinearNV = 5290, + OutputTrianglesNV = 5298, }, StorageClass = { @@ -131,6 +157,13 @@ spv = { AtomicCounter = 10, Image = 11, StorageBuffer = 12, + CallableDataNV = 5328, + IncomingCallableDataNV = 5329, + RayPayloadNV = 5338, + HitAttributeNV = 5339, + IncomingRayPayloadNV = 5342, + ShaderRecordBufferNV = 5343, + PhysicalStorageBufferEXT = 5349, }, Dim = { @@ -251,6 +284,10 @@ spv = { ConstOffsets = 5, Sample = 6, MinLod = 7, + MakeTexelAvailableKHR = 8, + MakeTexelVisibleKHR = 9, + NonPrivateTexelKHR = 10, + VolatileTexelKHR = 11, }, ImageOperandsMask = { @@ -263,6 +300,10 @@ spv = { ConstOffsets = 0x00000020, Sample = 0x00000040, MinLod = 0x00000080, + MakeTexelAvailableKHR = 0x00000100, + MakeTexelVisibleKHR = 0x00000200, + NonPrivateTexelKHR = 0x00000400, + VolatileTexelKHR = 0x00000800, }, FPFastMathModeShift = { @@ -356,11 +397,24 @@ spv = { InputAttachmentIndex = 43, Alignment = 44, MaxByteOffset = 45, + AlignmentId = 46, + MaxByteOffsetId = 47, + NoSignedWrap = 4469, + NoUnsignedWrap = 4470, ExplicitInterpAMD = 4999, OverrideCoverageNV = 5248, PassthroughNV = 5250, ViewportRelativeNV = 5252, SecondaryViewportRelativeNV = 5256, + PerPrimitiveNV = 5271, + PerViewNV = 5272, + PerTaskNV = 5273, + PerVertexNV = 5285, + NonUniformEXT = 5300, + RestrictPointerEXT = 5355, + AliasedPointerEXT = 5356, + HlslCounterBufferGOOGLE = 5634, + HlslSemanticGOOGLE = 5635, }, BuiltIn = { @@ -405,10 +459,15 @@ spv = { SubgroupLocalInvocationId = 41, VertexIndex = 42, InstanceIndex = 43, + SubgroupEqMask = 4416, SubgroupEqMaskKHR = 4416, + SubgroupGeMask = 4417, SubgroupGeMaskKHR = 4417, + SubgroupGtMask = 4418, SubgroupGtMaskKHR = 4418, + SubgroupLeMask = 4419, SubgroupLeMaskKHR = 4419, + SubgroupLtMask = 4420, SubgroupLtMaskKHR = 4420, BaseVertex = 4424, BaseInstance = 4425, @@ -428,6 +487,35 @@ spv = { SecondaryViewportMaskNV = 5258, PositionPerViewNV = 5261, ViewportMaskPerViewNV = 5262, + FullyCoveredEXT = 5264, + TaskCountNV = 5274, + PrimitiveCountNV = 5275, + PrimitiveIndicesNV = 5276, + ClipDistancePerViewNV = 5277, + CullDistancePerViewNV = 5278, + LayerPerViewNV = 5279, + MeshViewCountNV = 5280, + MeshViewIndicesNV = 5281, + BaryCoordNV = 5286, + BaryCoordNoPerspNV = 5287, + FragSizeEXT = 5292, + FragmentSizeNV = 5292, + FragInvocationCountEXT = 5293, + InvocationsPerPixelNV = 5293, + LaunchIdNV = 5319, + LaunchSizeNV = 5320, + WorldRayOriginNV = 5321, + WorldRayDirectionNV = 5322, + ObjectRayOriginNV = 5323, + ObjectRayDirectionNV = 5324, + RayTminNV = 5325, + RayTmaxNV = 5326, + InstanceCustomIndexNV = 5327, + ObjectToWorldNV = 5330, + WorldToObjectNV = 5331, + HitTNV = 5332, + HitKindNV = 5333, + IncomingRayFlagsNV = 5351, }, SelectionControlShift = { @@ -482,6 +570,9 @@ spv = { CrossWorkgroupMemory = 9, AtomicCounterMemory = 10, ImageMemory = 11, + OutputMemoryKHR = 12, + MakeAvailableKHR = 13, + MakeVisibleKHR = 14, }, MemorySemanticsMask = { @@ -496,12 +587,18 @@ spv = { CrossWorkgroupMemory = 0x00000200, AtomicCounterMemory = 0x00000400, ImageMemory = 0x00000800, + OutputMemoryKHR = 0x00001000, + MakeAvailableKHR = 0x00002000, + MakeVisibleKHR = 0x00004000, }, MemoryAccessShift = { Volatile = 0, Aligned = 1, Nontemporal = 2, + MakePointerAvailableKHR = 3, + MakePointerVisibleKHR = 4, + NonPrivatePointerKHR = 5, }, MemoryAccessMask = { @@ -509,6 +606,9 @@ spv = { Volatile = 0x00000001, Aligned = 0x00000002, Nontemporal = 0x00000004, + MakePointerAvailableKHR = 0x00000008, + MakePointerVisibleKHR = 0x00000010, + NonPrivatePointerKHR = 0x00000020, }, Scope = { @@ -517,12 +617,17 @@ spv = { Workgroup = 2, Subgroup = 3, Invocation = 4, + QueueFamilyKHR = 5, }, GroupOperation = { Reduce = 0, InclusiveScan = 1, ExclusiveScan = 2, + ClusteredReduce = 3, + PartitionedReduceNV = 6, + PartitionedInclusiveScanNV = 7, + PartitionedExclusiveScanNV = 8, }, KernelEnqueueFlags = { @@ -600,6 +705,14 @@ spv = { SubgroupDispatch = 58, NamedBarrier = 59, PipeStorage = 60, + GroupNonUniform = 61, + GroupNonUniformVote = 62, + GroupNonUniformArithmetic = 63, + GroupNonUniformBallot = 64, + GroupNonUniformShuffle = 65, + GroupNonUniformShuffleRelative = 66, + GroupNonUniformClustered = 67, + GroupNonUniformQuad = 68, SubgroupBallotKHR = 4423, DrawParameters = 4427, SubgroupVoteKHR = 4431, @@ -615,6 +728,15 @@ spv = { VariablePointers = 4442, AtomicStorageOps = 4445, SampleMaskPostDepthCoverage = 4447, + StorageBuffer8BitAccess = 4448, + UniformAndStorageBuffer8BitAccess = 4449, + StoragePushConstant8 = 4450, + DenormPreserve = 4464, + DenormFlushToZero = 4465, + SignedZeroInfNanPreserve = 4466, + RoundingModeRTE = 4467, + RoundingModeRTZ = 4468, + Float16ImageAMD = 5008, ImageGatherBiasLodAMD = 5009, FragmentMaskAMD = 5010, StencilExportEXT = 5013, @@ -626,6 +748,31 @@ spv = { ShaderViewportMaskNV = 5255, ShaderStereoViewNV = 5259, PerViewAttributesNV = 5260, + FragmentFullyCoveredEXT = 5265, + MeshShadingNV = 5266, + ImageFootprintNV = 5282, + FragmentBarycentricNV = 5284, + ComputeDerivativeGroupQuadsNV = 5288, + FragmentDensityEXT = 5291, + ShadingRateNV = 5291, + GroupNonUniformPartitionedNV = 5297, + ShaderNonUniformEXT = 5301, + RuntimeDescriptorArrayEXT = 5302, + InputAttachmentArrayDynamicIndexingEXT = 5303, + UniformTexelBufferArrayDynamicIndexingEXT = 5304, + StorageTexelBufferArrayDynamicIndexingEXT = 5305, + UniformBufferArrayNonUniformIndexingEXT = 5306, + SampledImageArrayNonUniformIndexingEXT = 5307, + StorageBufferArrayNonUniformIndexingEXT = 5308, + StorageImageArrayNonUniformIndexingEXT = 5309, + InputAttachmentArrayNonUniformIndexingEXT = 5310, + UniformTexelBufferArrayNonUniformIndexingEXT = 5311, + StorageTexelBufferArrayNonUniformIndexingEXT = 5312, + RayTracingNV = 5340, + VulkanMemoryModelKHR = 5345, + VulkanMemoryModelDeviceScopeKHR = 5346, + PhysicalStorageBufferAddressesEXT = 5347, + ComputeDerivativeGroupLinearNV = 5350, SubgroupShuffleINTEL = 5568, SubgroupBufferBlockIOINTEL = 5569, SubgroupImageBlockIOINTEL = 5570, @@ -936,6 +1083,42 @@ spv = { OpNamedBarrierInitialize = 328, OpMemoryNamedBarrier = 329, OpModuleProcessed = 330, + OpExecutionModeId = 331, + OpDecorateId = 332, + OpGroupNonUniformElect = 333, + OpGroupNonUniformAll = 334, + OpGroupNonUniformAny = 335, + OpGroupNonUniformAllEqual = 336, + OpGroupNonUniformBroadcast = 337, + OpGroupNonUniformBroadcastFirst = 338, + OpGroupNonUniformBallot = 339, + OpGroupNonUniformInverseBallot = 340, + OpGroupNonUniformBallotBitExtract = 341, + OpGroupNonUniformBallotBitCount = 342, + OpGroupNonUniformBallotFindLSB = 343, + OpGroupNonUniformBallotFindMSB = 344, + OpGroupNonUniformShuffle = 345, + OpGroupNonUniformShuffleXor = 346, + OpGroupNonUniformShuffleUp = 347, + OpGroupNonUniformShuffleDown = 348, + OpGroupNonUniformIAdd = 349, + OpGroupNonUniformFAdd = 350, + OpGroupNonUniformIMul = 351, + OpGroupNonUniformFMul = 352, + OpGroupNonUniformSMin = 353, + OpGroupNonUniformUMin = 354, + OpGroupNonUniformFMin = 355, + OpGroupNonUniformSMax = 356, + OpGroupNonUniformUMax = 357, + OpGroupNonUniformFMax = 358, + OpGroupNonUniformBitwiseAnd = 359, + OpGroupNonUniformBitwiseOr = 360, + OpGroupNonUniformBitwiseXor = 361, + OpGroupNonUniformLogicalAnd = 362, + OpGroupNonUniformLogicalOr = 363, + OpGroupNonUniformLogicalXor = 364, + OpGroupNonUniformQuadBroadcast = 365, + OpGroupNonUniformQuadSwap = 366, OpSubgroupBallotKHR = 4421, OpSubgroupFirstInvocationKHR = 4422, OpSubgroupAllKHR = 4428, @@ -952,6 +1135,15 @@ spv = { OpGroupSMaxNonUniformAMD = 5007, OpFragmentMaskFetchAMD = 5011, OpFragmentFetchAMD = 5012, + OpImageSampleFootprintNV = 5283, + OpGroupNonUniformPartitionNV = 5296, + OpWritePackedPrimitiveIndices4x8NV = 5299, + OpReportIntersectionNV = 5334, + OpIgnoreIntersectionNV = 5335, + OpTerminateRayNV = 5336, + OpTraceNV = 5337, + OpTypeAccelerationStructureNV = 5341, + OpExecuteCallableNV = 5344, OpSubgroupShuffleINTEL = 5571, OpSubgroupShuffleDownINTEL = 5572, OpSubgroupShuffleUpINTEL = 5573, @@ -960,6 +1152,8 @@ spv = { OpSubgroupBlockWriteINTEL = 5576, OpSubgroupImageBlockReadINTEL = 5577, OpSubgroupImageBlockWriteINTEL = 5578, + OpDecorateStringGOOGLE = 5632, + OpMemberDecorateStringGOOGLE = 5633, }, } diff --git a/ext/vulkan/spirv.py b/ext/vulkan/spirv.py index d7d900cb1d..4b1a7eec1f 100644 --- a/ext/vulkan/spirv.py +++ b/ext/vulkan/spirv.py @@ -1,4 +1,4 @@ -# Copyright (c) 2014-2017 The Khronos Group Inc. +# Copyright (c) 2014-2019 The Khronos Group Inc. # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and/or associated documentation files (the "Materials"), @@ -26,13 +26,16 @@ # the Binary Section of the SPIR-V specification. # Enumeration tokens for SPIR-V, in various styles: -# C, C++, C++11, JSON, Lua, Python +# C, C++, C++11, JSON, Lua, Python, C#, D # # - C will have tokens with a "Spv" prefix, e.g.: SpvSourceLanguageGLSL # - C++ will have tokens in the "spv" name space, e.g.: spv::SourceLanguageGLSL # - C++11 will use enum classes in the spv namespace, e.g.: spv::SourceLanguage::GLSL # - Lua will use tables, e.g.: spv.SourceLanguage.GLSL # - Python will use dictionaries, e.g.: spv['SourceLanguage']['GLSL'] +# - C# will use enum classes in the Specification class located in the "Spv" namespace, +# e.g.: Spv.Specification.SourceLanguage.GLSL +# - D will have tokens under the "spv" module, e.g: spv.SourceLanguage.GLSL # # Some tokens act like mask values, which can be OR'd together, # while others are mutually exclusive. The mask-like ones have @@ -41,8 +44,8 @@ spv = { 'MagicNumber' : 0x07230203, - 'Version' : 0x00010100, - 'Revision' : 8, + 'Version' : 0x00010300, + 'Revision' : 6, 'OpCodeMask' : 0xffff, 'WordCountShift' : 16, @@ -63,18 +66,28 @@ spv = { 'Fragment' : 4, 'GLCompute' : 5, 'Kernel' : 6, + 'TaskNV' : 5267, + 'MeshNV' : 5268, + 'RayGenerationNV' : 5313, + 'IntersectionNV' : 5314, + 'AnyHitNV' : 5315, + 'ClosestHitNV' : 5316, + 'MissNV' : 5317, + 'CallableNV' : 5318, }, 'AddressingModel' : { 'Logical' : 0, 'Physical32' : 1, 'Physical64' : 2, + 'PhysicalStorageBuffer64EXT' : 5348, }, 'MemoryModel' : { 'Simple' : 0, 'GLSL450' : 1, 'OpenCL' : 2, + 'VulkanKHR' : 3, }, 'ExecutionMode' : { @@ -113,8 +126,21 @@ spv = { 'Finalizer' : 34, 'SubgroupSize' : 35, 'SubgroupsPerWorkgroup' : 36, + 'SubgroupsPerWorkgroupId' : 37, + 'LocalSizeId' : 38, + 'LocalSizeHintId' : 39, 'PostDepthCoverage' : 4446, + 'DenormPreserve' : 4459, + 'DenormFlushToZero' : 4460, + 'SignedZeroInfNanPreserve' : 4461, + 'RoundingModeRTE' : 4462, + 'RoundingModeRTZ' : 4463, 'StencilRefReplacingEXT' : 5027, + 'OutputLinesNV' : 5269, + 'OutputPrimitivesNV' : 5270, + 'DerivativeGroupQuadsNV' : 5289, + 'DerivativeGroupLinearNV' : 5290, + 'OutputTrianglesNV' : 5298, }, 'StorageClass' : { @@ -131,6 +157,13 @@ spv = { 'AtomicCounter' : 10, 'Image' : 11, 'StorageBuffer' : 12, + 'CallableDataNV' : 5328, + 'IncomingCallableDataNV' : 5329, + 'RayPayloadNV' : 5338, + 'HitAttributeNV' : 5339, + 'IncomingRayPayloadNV' : 5342, + 'ShaderRecordBufferNV' : 5343, + 'PhysicalStorageBufferEXT' : 5349, }, 'Dim' : { @@ -251,6 +284,10 @@ spv = { 'ConstOffsets' : 5, 'Sample' : 6, 'MinLod' : 7, + 'MakeTexelAvailableKHR' : 8, + 'MakeTexelVisibleKHR' : 9, + 'NonPrivateTexelKHR' : 10, + 'VolatileTexelKHR' : 11, }, 'ImageOperandsMask' : { @@ -263,6 +300,10 @@ spv = { 'ConstOffsets' : 0x00000020, 'Sample' : 0x00000040, 'MinLod' : 0x00000080, + 'MakeTexelAvailableKHR' : 0x00000100, + 'MakeTexelVisibleKHR' : 0x00000200, + 'NonPrivateTexelKHR' : 0x00000400, + 'VolatileTexelKHR' : 0x00000800, }, 'FPFastMathModeShift' : { @@ -356,11 +397,24 @@ spv = { 'InputAttachmentIndex' : 43, 'Alignment' : 44, 'MaxByteOffset' : 45, + 'AlignmentId' : 46, + 'MaxByteOffsetId' : 47, + 'NoSignedWrap' : 4469, + 'NoUnsignedWrap' : 4470, 'ExplicitInterpAMD' : 4999, 'OverrideCoverageNV' : 5248, 'PassthroughNV' : 5250, 'ViewportRelativeNV' : 5252, 'SecondaryViewportRelativeNV' : 5256, + 'PerPrimitiveNV' : 5271, + 'PerViewNV' : 5272, + 'PerTaskNV' : 5273, + 'PerVertexNV' : 5285, + 'NonUniformEXT' : 5300, + 'RestrictPointerEXT' : 5355, + 'AliasedPointerEXT' : 5356, + 'HlslCounterBufferGOOGLE' : 5634, + 'HlslSemanticGOOGLE' : 5635, }, 'BuiltIn' : { @@ -405,10 +459,15 @@ spv = { 'SubgroupLocalInvocationId' : 41, 'VertexIndex' : 42, 'InstanceIndex' : 43, + 'SubgroupEqMask' : 4416, 'SubgroupEqMaskKHR' : 4416, + 'SubgroupGeMask' : 4417, 'SubgroupGeMaskKHR' : 4417, + 'SubgroupGtMask' : 4418, 'SubgroupGtMaskKHR' : 4418, + 'SubgroupLeMask' : 4419, 'SubgroupLeMaskKHR' : 4419, + 'SubgroupLtMask' : 4420, 'SubgroupLtMaskKHR' : 4420, 'BaseVertex' : 4424, 'BaseInstance' : 4425, @@ -428,6 +487,35 @@ spv = { 'SecondaryViewportMaskNV' : 5258, 'PositionPerViewNV' : 5261, 'ViewportMaskPerViewNV' : 5262, + 'FullyCoveredEXT' : 5264, + 'TaskCountNV' : 5274, + 'PrimitiveCountNV' : 5275, + 'PrimitiveIndicesNV' : 5276, + 'ClipDistancePerViewNV' : 5277, + 'CullDistancePerViewNV' : 5278, + 'LayerPerViewNV' : 5279, + 'MeshViewCountNV' : 5280, + 'MeshViewIndicesNV' : 5281, + 'BaryCoordNV' : 5286, + 'BaryCoordNoPerspNV' : 5287, + 'FragSizeEXT' : 5292, + 'FragmentSizeNV' : 5292, + 'FragInvocationCountEXT' : 5293, + 'InvocationsPerPixelNV' : 5293, + 'LaunchIdNV' : 5319, + 'LaunchSizeNV' : 5320, + 'WorldRayOriginNV' : 5321, + 'WorldRayDirectionNV' : 5322, + 'ObjectRayOriginNV' : 5323, + 'ObjectRayDirectionNV' : 5324, + 'RayTminNV' : 5325, + 'RayTmaxNV' : 5326, + 'InstanceCustomIndexNV' : 5327, + 'ObjectToWorldNV' : 5330, + 'WorldToObjectNV' : 5331, + 'HitTNV' : 5332, + 'HitKindNV' : 5333, + 'IncomingRayFlagsNV' : 5351, }, 'SelectionControlShift' : { @@ -482,6 +570,9 @@ spv = { 'CrossWorkgroupMemory' : 9, 'AtomicCounterMemory' : 10, 'ImageMemory' : 11, + 'OutputMemoryKHR' : 12, + 'MakeAvailableKHR' : 13, + 'MakeVisibleKHR' : 14, }, 'MemorySemanticsMask' : { @@ -496,12 +587,18 @@ spv = { 'CrossWorkgroupMemory' : 0x00000200, 'AtomicCounterMemory' : 0x00000400, 'ImageMemory' : 0x00000800, + 'OutputMemoryKHR' : 0x00001000, + 'MakeAvailableKHR' : 0x00002000, + 'MakeVisibleKHR' : 0x00004000, }, 'MemoryAccessShift' : { 'Volatile' : 0, 'Aligned' : 1, 'Nontemporal' : 2, + 'MakePointerAvailableKHR' : 3, + 'MakePointerVisibleKHR' : 4, + 'NonPrivatePointerKHR' : 5, }, 'MemoryAccessMask' : { @@ -509,6 +606,9 @@ spv = { 'Volatile' : 0x00000001, 'Aligned' : 0x00000002, 'Nontemporal' : 0x00000004, + 'MakePointerAvailableKHR' : 0x00000008, + 'MakePointerVisibleKHR' : 0x00000010, + 'NonPrivatePointerKHR' : 0x00000020, }, 'Scope' : { @@ -517,12 +617,17 @@ spv = { 'Workgroup' : 2, 'Subgroup' : 3, 'Invocation' : 4, + 'QueueFamilyKHR' : 5, }, 'GroupOperation' : { 'Reduce' : 0, 'InclusiveScan' : 1, 'ExclusiveScan' : 2, + 'ClusteredReduce' : 3, + 'PartitionedReduceNV' : 6, + 'PartitionedInclusiveScanNV' : 7, + 'PartitionedExclusiveScanNV' : 8, }, 'KernelEnqueueFlags' : { @@ -600,6 +705,14 @@ spv = { 'SubgroupDispatch' : 58, 'NamedBarrier' : 59, 'PipeStorage' : 60, + 'GroupNonUniform' : 61, + 'GroupNonUniformVote' : 62, + 'GroupNonUniformArithmetic' : 63, + 'GroupNonUniformBallot' : 64, + 'GroupNonUniformShuffle' : 65, + 'GroupNonUniformShuffleRelative' : 66, + 'GroupNonUniformClustered' : 67, + 'GroupNonUniformQuad' : 68, 'SubgroupBallotKHR' : 4423, 'DrawParameters' : 4427, 'SubgroupVoteKHR' : 4431, @@ -615,6 +728,15 @@ spv = { 'VariablePointers' : 4442, 'AtomicStorageOps' : 4445, 'SampleMaskPostDepthCoverage' : 4447, + 'StorageBuffer8BitAccess' : 4448, + 'UniformAndStorageBuffer8BitAccess' : 4449, + 'StoragePushConstant8' : 4450, + 'DenormPreserve' : 4464, + 'DenormFlushToZero' : 4465, + 'SignedZeroInfNanPreserve' : 4466, + 'RoundingModeRTE' : 4467, + 'RoundingModeRTZ' : 4468, + 'Float16ImageAMD' : 5008, 'ImageGatherBiasLodAMD' : 5009, 'FragmentMaskAMD' : 5010, 'StencilExportEXT' : 5013, @@ -626,6 +748,31 @@ spv = { 'ShaderViewportMaskNV' : 5255, 'ShaderStereoViewNV' : 5259, 'PerViewAttributesNV' : 5260, + 'FragmentFullyCoveredEXT' : 5265, + 'MeshShadingNV' : 5266, + 'ImageFootprintNV' : 5282, + 'FragmentBarycentricNV' : 5284, + 'ComputeDerivativeGroupQuadsNV' : 5288, + 'FragmentDensityEXT' : 5291, + 'ShadingRateNV' : 5291, + 'GroupNonUniformPartitionedNV' : 5297, + 'ShaderNonUniformEXT' : 5301, + 'RuntimeDescriptorArrayEXT' : 5302, + 'InputAttachmentArrayDynamicIndexingEXT' : 5303, + 'UniformTexelBufferArrayDynamicIndexingEXT' : 5304, + 'StorageTexelBufferArrayDynamicIndexingEXT' : 5305, + 'UniformBufferArrayNonUniformIndexingEXT' : 5306, + 'SampledImageArrayNonUniformIndexingEXT' : 5307, + 'StorageBufferArrayNonUniformIndexingEXT' : 5308, + 'StorageImageArrayNonUniformIndexingEXT' : 5309, + 'InputAttachmentArrayNonUniformIndexingEXT' : 5310, + 'UniformTexelBufferArrayNonUniformIndexingEXT' : 5311, + 'StorageTexelBufferArrayNonUniformIndexingEXT' : 5312, + 'RayTracingNV' : 5340, + 'VulkanMemoryModelKHR' : 5345, + 'VulkanMemoryModelDeviceScopeKHR' : 5346, + 'PhysicalStorageBufferAddressesEXT' : 5347, + 'ComputeDerivativeGroupLinearNV' : 5350, 'SubgroupShuffleINTEL' : 5568, 'SubgroupBufferBlockIOINTEL' : 5569, 'SubgroupImageBlockIOINTEL' : 5570, @@ -936,6 +1083,42 @@ spv = { 'OpNamedBarrierInitialize' : 328, 'OpMemoryNamedBarrier' : 329, 'OpModuleProcessed' : 330, + 'OpExecutionModeId' : 331, + 'OpDecorateId' : 332, + 'OpGroupNonUniformElect' : 333, + 'OpGroupNonUniformAll' : 334, + 'OpGroupNonUniformAny' : 335, + 'OpGroupNonUniformAllEqual' : 336, + 'OpGroupNonUniformBroadcast' : 337, + 'OpGroupNonUniformBroadcastFirst' : 338, + 'OpGroupNonUniformBallot' : 339, + 'OpGroupNonUniformInverseBallot' : 340, + 'OpGroupNonUniformBallotBitExtract' : 341, + 'OpGroupNonUniformBallotBitCount' : 342, + 'OpGroupNonUniformBallotFindLSB' : 343, + 'OpGroupNonUniformBallotFindMSB' : 344, + 'OpGroupNonUniformShuffle' : 345, + 'OpGroupNonUniformShuffleXor' : 346, + 'OpGroupNonUniformShuffleUp' : 347, + 'OpGroupNonUniformShuffleDown' : 348, + 'OpGroupNonUniformIAdd' : 349, + 'OpGroupNonUniformFAdd' : 350, + 'OpGroupNonUniformIMul' : 351, + 'OpGroupNonUniformFMul' : 352, + 'OpGroupNonUniformSMin' : 353, + 'OpGroupNonUniformUMin' : 354, + 'OpGroupNonUniformFMin' : 355, + 'OpGroupNonUniformSMax' : 356, + 'OpGroupNonUniformUMax' : 357, + 'OpGroupNonUniformFMax' : 358, + 'OpGroupNonUniformBitwiseAnd' : 359, + 'OpGroupNonUniformBitwiseOr' : 360, + 'OpGroupNonUniformBitwiseXor' : 361, + 'OpGroupNonUniformLogicalAnd' : 362, + 'OpGroupNonUniformLogicalOr' : 363, + 'OpGroupNonUniformLogicalXor' : 364, + 'OpGroupNonUniformQuadBroadcast' : 365, + 'OpGroupNonUniformQuadSwap' : 366, 'OpSubgroupBallotKHR' : 4421, 'OpSubgroupFirstInvocationKHR' : 4422, 'OpSubgroupAllKHR' : 4428, @@ -952,6 +1135,15 @@ spv = { 'OpGroupSMaxNonUniformAMD' : 5007, 'OpFragmentMaskFetchAMD' : 5011, 'OpFragmentFetchAMD' : 5012, + 'OpImageSampleFootprintNV' : 5283, + 'OpGroupNonUniformPartitionNV' : 5296, + 'OpWritePackedPrimitiveIndices4x8NV' : 5299, + 'OpReportIntersectionNV' : 5334, + 'OpIgnoreIntersectionNV' : 5335, + 'OpTerminateRayNV' : 5336, + 'OpTraceNV' : 5337, + 'OpTypeAccelerationStructureNV' : 5341, + 'OpExecuteCallableNV' : 5344, 'OpSubgroupShuffleINTEL' : 5571, 'OpSubgroupShuffleDownINTEL' : 5572, 'OpSubgroupShuffleUpINTEL' : 5573, @@ -960,6 +1152,8 @@ spv = { 'OpSubgroupBlockWriteINTEL' : 5576, 'OpSubgroupImageBlockReadINTEL' : 5577, 'OpSubgroupImageBlockWriteINTEL' : 5578, + 'OpDecorateStringGOOGLE' : 5632, + 'OpMemberDecorateStringGOOGLE' : 5633, }, } diff --git a/ext/vulkan/vk_icd.h b/ext/vulkan/vk_icd.h index b8c7efcb6b..b935fa1786 100644 --- a/ext/vulkan/vk_icd.h +++ b/ext/vulkan/vk_icd.h @@ -44,12 +44,12 @@ #define CURRENT_LOADER_ICD_INTERFACE_VERSION 5 #define MIN_SUPPORTED_LOADER_ICD_INTERFACE_VERSION 0 #define MIN_PHYS_DEV_EXTENSION_ICD_INTERFACE_VERSION 4 -typedef VkResult (VKAPI_PTR *PFN_vkNegotiateLoaderICDInterfaceVersion)(uint32_t *pVersion); +typedef VkResult(VKAPI_PTR *PFN_vkNegotiateLoaderICDInterfaceVersion)(uint32_t *pVersion); // This is defined in vk_layer.h which will be found by the loader, but if an ICD is building against this // file directly, it won't be found. #ifndef PFN_GetPhysicalDeviceProcAddr -typedef PFN_vkVoidFunction (VKAPI_PTR *PFN_GetPhysicalDeviceProcAddr)(VkInstance instance, const char* pName); +typedef PFN_vkVoidFunction(VKAPI_PTR *PFN_GetPhysicalDeviceProcAddr)(VkInstance instance, const char *pName); #endif /* @@ -85,6 +85,9 @@ typedef enum { VK_ICD_WSI_PLATFORM_WIN32, VK_ICD_WSI_PLATFORM_XCB, VK_ICD_WSI_PLATFORM_XLIB, + VK_ICD_WSI_PLATFORM_ANDROID, + VK_ICD_WSI_PLATFORM_MACOS, + VK_ICD_WSI_PLATFORM_IOS, VK_ICD_WSI_PLATFORM_DISPLAY } VkIcdWsiPlatform; @@ -98,7 +101,7 @@ typedef struct { MirConnection *connection; MirSurface *mirSurface; } VkIcdSurfaceMir; -#endif // VK_USE_PLATFORM_MIR_KHR +#endif // VK_USE_PLATFORM_MIR_KHR #ifdef VK_USE_PLATFORM_WAYLAND_KHR typedef struct { @@ -106,7 +109,7 @@ typedef struct { struct wl_display *display; struct wl_surface *surface; } VkIcdSurfaceWayland; -#endif // VK_USE_PLATFORM_WAYLAND_KHR +#endif // VK_USE_PLATFORM_WAYLAND_KHR #ifdef VK_USE_PLATFORM_WIN32_KHR typedef struct { @@ -114,7 +117,7 @@ typedef struct { HINSTANCE hinstance; HWND hwnd; } VkIcdSurfaceWin32; -#endif // VK_USE_PLATFORM_WIN32_KHR +#endif // VK_USE_PLATFORM_WIN32_KHR #ifdef VK_USE_PLATFORM_XCB_KHR typedef struct { @@ -122,7 +125,7 @@ typedef struct { xcb_connection_t *connection; xcb_window_t window; } VkIcdSurfaceXcb; -#endif // VK_USE_PLATFORM_XCB_KHR +#endif // VK_USE_PLATFORM_XCB_KHR #ifdef VK_USE_PLATFORM_XLIB_KHR typedef struct { @@ -130,13 +133,28 @@ typedef struct { Display *dpy; Window window; } VkIcdSurfaceXlib; -#endif // VK_USE_PLATFORM_XLIB_KHR +#endif // VK_USE_PLATFORM_XLIB_KHR #ifdef VK_USE_PLATFORM_ANDROID_KHR typedef struct { - ANativeWindow* window; + VkIcdSurfaceBase base; + struct ANativeWindow *window; } VkIcdSurfaceAndroid; -#endif //VK_USE_PLATFORM_ANDROID_KHR +#endif // VK_USE_PLATFORM_ANDROID_KHR + +#ifdef VK_USE_PLATFORM_MACOS_MVK +typedef struct { + VkIcdSurfaceBase base; + const void *pView; +} VkIcdSurfaceMacOS; +#endif // VK_USE_PLATFORM_MACOS_MVK + +#ifdef VK_USE_PLATFORM_IOS_MVK +typedef struct { + VkIcdSurfaceBase base; + const void *pView; +} VkIcdSurfaceIOS; +#endif // VK_USE_PLATFORM_IOS_MVK typedef struct { VkIcdSurfaceBase base; @@ -149,4 +167,4 @@ typedef struct { VkExtent2D imageExtent; } VkIcdSurfaceDisplay; -#endif // VKICD_H +#endif // VKICD_H diff --git a/ext/vulkan/vk_layer.h b/ext/vulkan/vk_layer.h index e8300c37d4..823c88ab75 100644 --- a/ext/vulkan/vk_layer.h +++ b/ext/vulkan/vk_layer.h @@ -35,9 +35,6 @@ #define VK_LAYER_EXPORT #endif -// Definition for VkLayerDispatchTable and VkLayerInstanceDispatchTable now appear in externally generated header -#include "vk_layer_dispatch_table.h" - #define MAX_NUM_UNKNOWN_EXTS 250 // Loader-Layer version negotiation API. Versions add the following features: @@ -50,6 +47,9 @@ #define VK_CURRENT_CHAIN_VERSION 1 +// Typedef for use in the interfaces below +typedef PFN_vkVoidFunction (VKAPI_PTR *PFN_GetPhysicalDeviceProcAddr)(VkInstance instance, const char* pName); + // Version negotiation values typedef enum VkNegotiateLayerStructType { LAYER_NEGOTIATE_UNINTIALIZED = 0, diff --git a/ext/vulkan/vk_layer_dispatch_table.h b/ext/vulkan/vk_layer_dispatch_table.h deleted file mode 100644 index 572982dfd3..0000000000 --- a/ext/vulkan/vk_layer_dispatch_table.h +++ /dev/null @@ -1,507 +0,0 @@ -// *** THIS FILE IS GENERATED - DO NOT EDIT *** -// See loader_extension_generator.py for modifications - -/* - * Copyright (c) 2015-2017 The Khronos Group Inc. - * Copyright (c) 2015-2017 Valve Corporation - * Copyright (c) 2015-2017 LunarG, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * Author: Mark Lobodzinski - * Author: Mark Young - */ - -#pragma once - -typedef PFN_vkVoidFunction (VKAPI_PTR *PFN_GetPhysicalDeviceProcAddr)(VkInstance instance, const char* pName); - -// Instance function pointer dispatch table -typedef struct VkLayerInstanceDispatchTable_ { - // Manually add in GetPhysicalDeviceProcAddr entry - PFN_GetPhysicalDeviceProcAddr GetPhysicalDeviceProcAddr; - - // ---- Core 1_0 commands - PFN_vkCreateInstance CreateInstance; - PFN_vkDestroyInstance DestroyInstance; - PFN_vkEnumeratePhysicalDevices EnumeratePhysicalDevices; - PFN_vkGetPhysicalDeviceFeatures GetPhysicalDeviceFeatures; - PFN_vkGetPhysicalDeviceFormatProperties GetPhysicalDeviceFormatProperties; - PFN_vkGetPhysicalDeviceImageFormatProperties GetPhysicalDeviceImageFormatProperties; - PFN_vkGetPhysicalDeviceProperties GetPhysicalDeviceProperties; - PFN_vkGetPhysicalDeviceQueueFamilyProperties GetPhysicalDeviceQueueFamilyProperties; - PFN_vkGetPhysicalDeviceMemoryProperties GetPhysicalDeviceMemoryProperties; - PFN_vkGetInstanceProcAddr GetInstanceProcAddr; - PFN_vkCreateDevice CreateDevice; - PFN_vkEnumerateInstanceExtensionProperties EnumerateInstanceExtensionProperties; - PFN_vkEnumerateDeviceExtensionProperties EnumerateDeviceExtensionProperties; - PFN_vkEnumerateInstanceLayerProperties EnumerateInstanceLayerProperties; - PFN_vkEnumerateDeviceLayerProperties EnumerateDeviceLayerProperties; - PFN_vkGetPhysicalDeviceSparseImageFormatProperties GetPhysicalDeviceSparseImageFormatProperties; - - // ---- Core 1_1 commands - PFN_vkEnumerateInstanceVersion EnumerateInstanceVersion; - PFN_vkEnumeratePhysicalDeviceGroups EnumeratePhysicalDeviceGroups; - PFN_vkGetPhysicalDeviceFeatures2 GetPhysicalDeviceFeatures2; - PFN_vkGetPhysicalDeviceProperties2 GetPhysicalDeviceProperties2; - PFN_vkGetPhysicalDeviceFormatProperties2 GetPhysicalDeviceFormatProperties2; - PFN_vkGetPhysicalDeviceImageFormatProperties2 GetPhysicalDeviceImageFormatProperties2; - PFN_vkGetPhysicalDeviceQueueFamilyProperties2 GetPhysicalDeviceQueueFamilyProperties2; - PFN_vkGetPhysicalDeviceMemoryProperties2 GetPhysicalDeviceMemoryProperties2; - PFN_vkGetPhysicalDeviceSparseImageFormatProperties2 GetPhysicalDeviceSparseImageFormatProperties2; - PFN_vkGetPhysicalDeviceExternalBufferProperties GetPhysicalDeviceExternalBufferProperties; - PFN_vkGetPhysicalDeviceExternalFenceProperties GetPhysicalDeviceExternalFenceProperties; - PFN_vkGetPhysicalDeviceExternalSemaphoreProperties GetPhysicalDeviceExternalSemaphoreProperties; - - // ---- VK_KHR_surface extension commands - PFN_vkDestroySurfaceKHR DestroySurfaceKHR; - PFN_vkGetPhysicalDeviceSurfaceSupportKHR GetPhysicalDeviceSurfaceSupportKHR; - PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR GetPhysicalDeviceSurfaceCapabilitiesKHR; - PFN_vkGetPhysicalDeviceSurfaceFormatsKHR GetPhysicalDeviceSurfaceFormatsKHR; - PFN_vkGetPhysicalDeviceSurfacePresentModesKHR GetPhysicalDeviceSurfacePresentModesKHR; - - // ---- VK_KHR_swapchain extension commands - PFN_vkGetPhysicalDevicePresentRectanglesKHR GetPhysicalDevicePresentRectanglesKHR; - - // ---- VK_KHR_display extension commands - PFN_vkGetPhysicalDeviceDisplayPropertiesKHR GetPhysicalDeviceDisplayPropertiesKHR; - PFN_vkGetPhysicalDeviceDisplayPlanePropertiesKHR GetPhysicalDeviceDisplayPlanePropertiesKHR; - PFN_vkGetDisplayPlaneSupportedDisplaysKHR GetDisplayPlaneSupportedDisplaysKHR; - PFN_vkGetDisplayModePropertiesKHR GetDisplayModePropertiesKHR; - PFN_vkCreateDisplayModeKHR CreateDisplayModeKHR; - PFN_vkGetDisplayPlaneCapabilitiesKHR GetDisplayPlaneCapabilitiesKHR; - PFN_vkCreateDisplayPlaneSurfaceKHR CreateDisplayPlaneSurfaceKHR; - - // ---- VK_KHR_xlib_surface extension commands -#ifdef VK_USE_PLATFORM_XLIB_KHR - PFN_vkCreateXlibSurfaceKHR CreateXlibSurfaceKHR; -#endif // VK_USE_PLATFORM_XLIB_KHR -#ifdef VK_USE_PLATFORM_XLIB_KHR - PFN_vkGetPhysicalDeviceXlibPresentationSupportKHR GetPhysicalDeviceXlibPresentationSupportKHR; -#endif // VK_USE_PLATFORM_XLIB_KHR - - // ---- VK_KHR_xcb_surface extension commands -#ifdef VK_USE_PLATFORM_XCB_KHR - PFN_vkCreateXcbSurfaceKHR CreateXcbSurfaceKHR; -#endif // VK_USE_PLATFORM_XCB_KHR -#ifdef VK_USE_PLATFORM_XCB_KHR - PFN_vkGetPhysicalDeviceXcbPresentationSupportKHR GetPhysicalDeviceXcbPresentationSupportKHR; -#endif // VK_USE_PLATFORM_XCB_KHR - - // ---- VK_KHR_wayland_surface extension commands -#ifdef VK_USE_PLATFORM_WAYLAND_KHR - PFN_vkCreateWaylandSurfaceKHR CreateWaylandSurfaceKHR; -#endif // VK_USE_PLATFORM_WAYLAND_KHR -#ifdef VK_USE_PLATFORM_WAYLAND_KHR - PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR GetPhysicalDeviceWaylandPresentationSupportKHR; -#endif // VK_USE_PLATFORM_WAYLAND_KHR - - // ---- VK_KHR_mir_surface extension commands -#ifdef VK_USE_PLATFORM_MIR_KHR - PFN_vkCreateMirSurfaceKHR CreateMirSurfaceKHR; -#endif // VK_USE_PLATFORM_MIR_KHR -#ifdef VK_USE_PLATFORM_MIR_KHR - PFN_vkGetPhysicalDeviceMirPresentationSupportKHR GetPhysicalDeviceMirPresentationSupportKHR; -#endif // VK_USE_PLATFORM_MIR_KHR - - // ---- VK_KHR_android_surface extension commands -#ifdef VK_USE_PLATFORM_ANDROID_KHR - PFN_vkCreateAndroidSurfaceKHR CreateAndroidSurfaceKHR; -#endif // VK_USE_PLATFORM_ANDROID_KHR - - // ---- VK_KHR_win32_surface extension commands -#ifdef VK_USE_PLATFORM_WIN32_KHR - PFN_vkCreateWin32SurfaceKHR CreateWin32SurfaceKHR; -#endif // VK_USE_PLATFORM_WIN32_KHR -#ifdef VK_USE_PLATFORM_WIN32_KHR - PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR GetPhysicalDeviceWin32PresentationSupportKHR; -#endif // VK_USE_PLATFORM_WIN32_KHR - - // ---- VK_KHR_get_physical_device_properties2 extension commands - PFN_vkGetPhysicalDeviceFeatures2KHR GetPhysicalDeviceFeatures2KHR; - PFN_vkGetPhysicalDeviceProperties2KHR GetPhysicalDeviceProperties2KHR; - PFN_vkGetPhysicalDeviceFormatProperties2KHR GetPhysicalDeviceFormatProperties2KHR; - PFN_vkGetPhysicalDeviceImageFormatProperties2KHR GetPhysicalDeviceImageFormatProperties2KHR; - PFN_vkGetPhysicalDeviceQueueFamilyProperties2KHR GetPhysicalDeviceQueueFamilyProperties2KHR; - PFN_vkGetPhysicalDeviceMemoryProperties2KHR GetPhysicalDeviceMemoryProperties2KHR; - PFN_vkGetPhysicalDeviceSparseImageFormatProperties2KHR GetPhysicalDeviceSparseImageFormatProperties2KHR; - - // ---- VK_KHR_device_group_creation extension commands - PFN_vkEnumeratePhysicalDeviceGroupsKHR EnumeratePhysicalDeviceGroupsKHR; - - // ---- VK_KHR_external_memory_capabilities extension commands - PFN_vkGetPhysicalDeviceExternalBufferPropertiesKHR GetPhysicalDeviceExternalBufferPropertiesKHR; - - // ---- VK_KHR_external_semaphore_capabilities extension commands - PFN_vkGetPhysicalDeviceExternalSemaphorePropertiesKHR GetPhysicalDeviceExternalSemaphorePropertiesKHR; - - // ---- VK_KHR_external_fence_capabilities extension commands - PFN_vkGetPhysicalDeviceExternalFencePropertiesKHR GetPhysicalDeviceExternalFencePropertiesKHR; - - // ---- VK_KHR_get_surface_capabilities2 extension commands - PFN_vkGetPhysicalDeviceSurfaceCapabilities2KHR GetPhysicalDeviceSurfaceCapabilities2KHR; - PFN_vkGetPhysicalDeviceSurfaceFormats2KHR GetPhysicalDeviceSurfaceFormats2KHR; - - // ---- VK_EXT_debug_report extension commands - PFN_vkCreateDebugReportCallbackEXT CreateDebugReportCallbackEXT; - PFN_vkDestroyDebugReportCallbackEXT DestroyDebugReportCallbackEXT; - PFN_vkDebugReportMessageEXT DebugReportMessageEXT; - - // ---- VK_NV_external_memory_capabilities extension commands - PFN_vkGetPhysicalDeviceExternalImageFormatPropertiesNV GetPhysicalDeviceExternalImageFormatPropertiesNV; - - // ---- VK_NN_vi_surface extension commands -#ifdef VK_USE_PLATFORM_VI_NN - PFN_vkCreateViSurfaceNN CreateViSurfaceNN; -#endif // VK_USE_PLATFORM_VI_NN - - // ---- VK_NVX_device_generated_commands extension commands - PFN_vkGetPhysicalDeviceGeneratedCommandsPropertiesNVX GetPhysicalDeviceGeneratedCommandsPropertiesNVX; - - // ---- VK_EXT_direct_mode_display extension commands - PFN_vkReleaseDisplayEXT ReleaseDisplayEXT; - - // ---- VK_EXT_acquire_xlib_display extension commands -#ifdef VK_USE_PLATFORM_XLIB_XRANDR_EXT - PFN_vkAcquireXlibDisplayEXT AcquireXlibDisplayEXT; -#endif // VK_USE_PLATFORM_XLIB_XRANDR_EXT -#ifdef VK_USE_PLATFORM_XLIB_XRANDR_EXT - PFN_vkGetRandROutputDisplayEXT GetRandROutputDisplayEXT; -#endif // VK_USE_PLATFORM_XLIB_XRANDR_EXT - - // ---- VK_EXT_display_surface_counter extension commands - PFN_vkGetPhysicalDeviceSurfaceCapabilities2EXT GetPhysicalDeviceSurfaceCapabilities2EXT; - - // ---- VK_MVK_ios_surface extension commands -#ifdef VK_USE_PLATFORM_IOS_MVK - PFN_vkCreateIOSSurfaceMVK CreateIOSSurfaceMVK; -#endif // VK_USE_PLATFORM_IOS_MVK - - // ---- VK_MVK_macos_surface extension commands -#ifdef VK_USE_PLATFORM_MACOS_MVK - PFN_vkCreateMacOSSurfaceMVK CreateMacOSSurfaceMVK; -#endif // VK_USE_PLATFORM_MACOS_MVK - - // ---- VK_EXT_debug_utils extension commands - PFN_vkCreateDebugUtilsMessengerEXT CreateDebugUtilsMessengerEXT; - PFN_vkDestroyDebugUtilsMessengerEXT DestroyDebugUtilsMessengerEXT; - PFN_vkSubmitDebugUtilsMessageEXT SubmitDebugUtilsMessageEXT; - - // ---- VK_EXT_sample_locations extension commands - PFN_vkGetPhysicalDeviceMultisamplePropertiesEXT GetPhysicalDeviceMultisamplePropertiesEXT; -} VkLayerInstanceDispatchTable; - -// Device function pointer dispatch table -typedef struct VkLayerDispatchTable_ { - - // ---- Core 1_0 commands - PFN_vkGetDeviceProcAddr GetDeviceProcAddr; - PFN_vkDestroyDevice DestroyDevice; - PFN_vkGetDeviceQueue GetDeviceQueue; - PFN_vkQueueSubmit QueueSubmit; - PFN_vkQueueWaitIdle QueueWaitIdle; - PFN_vkDeviceWaitIdle DeviceWaitIdle; - PFN_vkAllocateMemory AllocateMemory; - PFN_vkFreeMemory FreeMemory; - PFN_vkMapMemory MapMemory; - PFN_vkUnmapMemory UnmapMemory; - PFN_vkFlushMappedMemoryRanges FlushMappedMemoryRanges; - PFN_vkInvalidateMappedMemoryRanges InvalidateMappedMemoryRanges; - PFN_vkGetDeviceMemoryCommitment GetDeviceMemoryCommitment; - PFN_vkBindBufferMemory BindBufferMemory; - PFN_vkBindImageMemory BindImageMemory; - PFN_vkGetBufferMemoryRequirements GetBufferMemoryRequirements; - PFN_vkGetImageMemoryRequirements GetImageMemoryRequirements; - PFN_vkGetImageSparseMemoryRequirements GetImageSparseMemoryRequirements; - PFN_vkQueueBindSparse QueueBindSparse; - PFN_vkCreateFence CreateFence; - PFN_vkDestroyFence DestroyFence; - PFN_vkResetFences ResetFences; - PFN_vkGetFenceStatus GetFenceStatus; - PFN_vkWaitForFences WaitForFences; - PFN_vkCreateSemaphore CreateSemaphore; - PFN_vkDestroySemaphore DestroySemaphore; - PFN_vkCreateEvent CreateEvent; - PFN_vkDestroyEvent DestroyEvent; - PFN_vkGetEventStatus GetEventStatus; - PFN_vkSetEvent SetEvent; - PFN_vkResetEvent ResetEvent; - PFN_vkCreateQueryPool CreateQueryPool; - PFN_vkDestroyQueryPool DestroyQueryPool; - PFN_vkGetQueryPoolResults GetQueryPoolResults; - PFN_vkCreateBuffer CreateBuffer; - PFN_vkDestroyBuffer DestroyBuffer; - PFN_vkCreateBufferView CreateBufferView; - PFN_vkDestroyBufferView DestroyBufferView; - PFN_vkCreateImage CreateImage; - PFN_vkDestroyImage DestroyImage; - PFN_vkGetImageSubresourceLayout GetImageSubresourceLayout; - PFN_vkCreateImageView CreateImageView; - PFN_vkDestroyImageView DestroyImageView; - PFN_vkCreateShaderModule CreateShaderModule; - PFN_vkDestroyShaderModule DestroyShaderModule; - PFN_vkCreatePipelineCache CreatePipelineCache; - PFN_vkDestroyPipelineCache DestroyPipelineCache; - PFN_vkGetPipelineCacheData GetPipelineCacheData; - PFN_vkMergePipelineCaches MergePipelineCaches; - PFN_vkCreateGraphicsPipelines CreateGraphicsPipelines; - PFN_vkCreateComputePipelines CreateComputePipelines; - PFN_vkDestroyPipeline DestroyPipeline; - PFN_vkCreatePipelineLayout CreatePipelineLayout; - PFN_vkDestroyPipelineLayout DestroyPipelineLayout; - PFN_vkCreateSampler CreateSampler; - PFN_vkDestroySampler DestroySampler; - PFN_vkCreateDescriptorSetLayout CreateDescriptorSetLayout; - PFN_vkDestroyDescriptorSetLayout DestroyDescriptorSetLayout; - PFN_vkCreateDescriptorPool CreateDescriptorPool; - PFN_vkDestroyDescriptorPool DestroyDescriptorPool; - PFN_vkResetDescriptorPool ResetDescriptorPool; - PFN_vkAllocateDescriptorSets AllocateDescriptorSets; - PFN_vkFreeDescriptorSets FreeDescriptorSets; - PFN_vkUpdateDescriptorSets UpdateDescriptorSets; - PFN_vkCreateFramebuffer CreateFramebuffer; - PFN_vkDestroyFramebuffer DestroyFramebuffer; - PFN_vkCreateRenderPass CreateRenderPass; - PFN_vkDestroyRenderPass DestroyRenderPass; - PFN_vkGetRenderAreaGranularity GetRenderAreaGranularity; - PFN_vkCreateCommandPool CreateCommandPool; - PFN_vkDestroyCommandPool DestroyCommandPool; - PFN_vkResetCommandPool ResetCommandPool; - PFN_vkAllocateCommandBuffers AllocateCommandBuffers; - PFN_vkFreeCommandBuffers FreeCommandBuffers; - PFN_vkBeginCommandBuffer BeginCommandBuffer; - PFN_vkEndCommandBuffer EndCommandBuffer; - PFN_vkResetCommandBuffer ResetCommandBuffer; - PFN_vkCmdBindPipeline CmdBindPipeline; - PFN_vkCmdSetViewport CmdSetViewport; - PFN_vkCmdSetScissor CmdSetScissor; - PFN_vkCmdSetLineWidth CmdSetLineWidth; - PFN_vkCmdSetDepthBias CmdSetDepthBias; - PFN_vkCmdSetBlendConstants CmdSetBlendConstants; - PFN_vkCmdSetDepthBounds CmdSetDepthBounds; - PFN_vkCmdSetStencilCompareMask CmdSetStencilCompareMask; - PFN_vkCmdSetStencilWriteMask CmdSetStencilWriteMask; - PFN_vkCmdSetStencilReference CmdSetStencilReference; - PFN_vkCmdBindDescriptorSets CmdBindDescriptorSets; - PFN_vkCmdBindIndexBuffer CmdBindIndexBuffer; - PFN_vkCmdBindVertexBuffers CmdBindVertexBuffers; - PFN_vkCmdDraw CmdDraw; - PFN_vkCmdDrawIndexed CmdDrawIndexed; - PFN_vkCmdDrawIndirect CmdDrawIndirect; - PFN_vkCmdDrawIndexedIndirect CmdDrawIndexedIndirect; - PFN_vkCmdDispatch CmdDispatch; - PFN_vkCmdDispatchIndirect CmdDispatchIndirect; - PFN_vkCmdCopyBuffer CmdCopyBuffer; - PFN_vkCmdCopyImage CmdCopyImage; - PFN_vkCmdBlitImage CmdBlitImage; - PFN_vkCmdCopyBufferToImage CmdCopyBufferToImage; - PFN_vkCmdCopyImageToBuffer CmdCopyImageToBuffer; - PFN_vkCmdUpdateBuffer CmdUpdateBuffer; - PFN_vkCmdFillBuffer CmdFillBuffer; - PFN_vkCmdClearColorImage CmdClearColorImage; - PFN_vkCmdClearDepthStencilImage CmdClearDepthStencilImage; - PFN_vkCmdClearAttachments CmdClearAttachments; - PFN_vkCmdResolveImage CmdResolveImage; - PFN_vkCmdSetEvent CmdSetEvent; - PFN_vkCmdResetEvent CmdResetEvent; - PFN_vkCmdWaitEvents CmdWaitEvents; - PFN_vkCmdPipelineBarrier CmdPipelineBarrier; - PFN_vkCmdBeginQuery CmdBeginQuery; - PFN_vkCmdEndQuery CmdEndQuery; - PFN_vkCmdResetQueryPool CmdResetQueryPool; - PFN_vkCmdWriteTimestamp CmdWriteTimestamp; - PFN_vkCmdCopyQueryPoolResults CmdCopyQueryPoolResults; - PFN_vkCmdPushConstants CmdPushConstants; - PFN_vkCmdBeginRenderPass CmdBeginRenderPass; - PFN_vkCmdNextSubpass CmdNextSubpass; - PFN_vkCmdEndRenderPass CmdEndRenderPass; - PFN_vkCmdExecuteCommands CmdExecuteCommands; - - // ---- Core 1_1 commands - PFN_vkBindBufferMemory2 BindBufferMemory2; - PFN_vkBindImageMemory2 BindImageMemory2; - PFN_vkGetDeviceGroupPeerMemoryFeatures GetDeviceGroupPeerMemoryFeatures; - PFN_vkCmdSetDeviceMask CmdSetDeviceMask; - PFN_vkCmdDispatchBase CmdDispatchBase; - PFN_vkGetImageMemoryRequirements2 GetImageMemoryRequirements2; - PFN_vkGetBufferMemoryRequirements2 GetBufferMemoryRequirements2; - PFN_vkGetImageSparseMemoryRequirements2 GetImageSparseMemoryRequirements2; - PFN_vkTrimCommandPool TrimCommandPool; - PFN_vkGetDeviceQueue2 GetDeviceQueue2; - PFN_vkCreateSamplerYcbcrConversion CreateSamplerYcbcrConversion; - PFN_vkDestroySamplerYcbcrConversion DestroySamplerYcbcrConversion; - PFN_vkCreateDescriptorUpdateTemplate CreateDescriptorUpdateTemplate; - PFN_vkDestroyDescriptorUpdateTemplate DestroyDescriptorUpdateTemplate; - PFN_vkUpdateDescriptorSetWithTemplate UpdateDescriptorSetWithTemplate; - PFN_vkGetDescriptorSetLayoutSupport GetDescriptorSetLayoutSupport; - - // ---- VK_KHR_swapchain extension commands - PFN_vkCreateSwapchainKHR CreateSwapchainKHR; - PFN_vkDestroySwapchainKHR DestroySwapchainKHR; - PFN_vkGetSwapchainImagesKHR GetSwapchainImagesKHR; - PFN_vkAcquireNextImageKHR AcquireNextImageKHR; - PFN_vkQueuePresentKHR QueuePresentKHR; - PFN_vkGetDeviceGroupPresentCapabilitiesKHR GetDeviceGroupPresentCapabilitiesKHR; - PFN_vkGetDeviceGroupSurfacePresentModesKHR GetDeviceGroupSurfacePresentModesKHR; - PFN_vkAcquireNextImage2KHR AcquireNextImage2KHR; - - // ---- VK_KHR_display_swapchain extension commands - PFN_vkCreateSharedSwapchainsKHR CreateSharedSwapchainsKHR; - - // ---- VK_KHR_device_group extension commands - PFN_vkGetDeviceGroupPeerMemoryFeaturesKHR GetDeviceGroupPeerMemoryFeaturesKHR; - PFN_vkCmdSetDeviceMaskKHR CmdSetDeviceMaskKHR; - PFN_vkCmdDispatchBaseKHR CmdDispatchBaseKHR; - - // ---- VK_KHR_maintenance1 extension commands - PFN_vkTrimCommandPoolKHR TrimCommandPoolKHR; - - // ---- VK_KHR_external_memory_win32 extension commands -#ifdef VK_USE_PLATFORM_WIN32_KHR - PFN_vkGetMemoryWin32HandleKHR GetMemoryWin32HandleKHR; -#endif // VK_USE_PLATFORM_WIN32_KHR -#ifdef VK_USE_PLATFORM_WIN32_KHR - PFN_vkGetMemoryWin32HandlePropertiesKHR GetMemoryWin32HandlePropertiesKHR; -#endif // VK_USE_PLATFORM_WIN32_KHR - - // ---- VK_KHR_external_memory_fd extension commands - PFN_vkGetMemoryFdKHR GetMemoryFdKHR; - PFN_vkGetMemoryFdPropertiesKHR GetMemoryFdPropertiesKHR; - - // ---- VK_KHR_external_semaphore_win32 extension commands -#ifdef VK_USE_PLATFORM_WIN32_KHR - PFN_vkImportSemaphoreWin32HandleKHR ImportSemaphoreWin32HandleKHR; -#endif // VK_USE_PLATFORM_WIN32_KHR -#ifdef VK_USE_PLATFORM_WIN32_KHR - PFN_vkGetSemaphoreWin32HandleKHR GetSemaphoreWin32HandleKHR; -#endif // VK_USE_PLATFORM_WIN32_KHR - - // ---- VK_KHR_external_semaphore_fd extension commands - PFN_vkImportSemaphoreFdKHR ImportSemaphoreFdKHR; - PFN_vkGetSemaphoreFdKHR GetSemaphoreFdKHR; - - // ---- VK_KHR_push_descriptor extension commands - PFN_vkCmdPushDescriptorSetKHR CmdPushDescriptorSetKHR; - PFN_vkCmdPushDescriptorSetWithTemplateKHR CmdPushDescriptorSetWithTemplateKHR; - - // ---- VK_KHR_descriptor_update_template extension commands - PFN_vkCreateDescriptorUpdateTemplateKHR CreateDescriptorUpdateTemplateKHR; - PFN_vkDestroyDescriptorUpdateTemplateKHR DestroyDescriptorUpdateTemplateKHR; - PFN_vkUpdateDescriptorSetWithTemplateKHR UpdateDescriptorSetWithTemplateKHR; - - // ---- VK_KHR_shared_presentable_image extension commands - PFN_vkGetSwapchainStatusKHR GetSwapchainStatusKHR; - - // ---- VK_KHR_external_fence_win32 extension commands -#ifdef VK_USE_PLATFORM_WIN32_KHR - PFN_vkImportFenceWin32HandleKHR ImportFenceWin32HandleKHR; -#endif // VK_USE_PLATFORM_WIN32_KHR -#ifdef VK_USE_PLATFORM_WIN32_KHR - PFN_vkGetFenceWin32HandleKHR GetFenceWin32HandleKHR; -#endif // VK_USE_PLATFORM_WIN32_KHR - - // ---- VK_KHR_external_fence_fd extension commands - PFN_vkImportFenceFdKHR ImportFenceFdKHR; - PFN_vkGetFenceFdKHR GetFenceFdKHR; - - // ---- VK_KHR_get_memory_requirements2 extension commands - PFN_vkGetImageMemoryRequirements2KHR GetImageMemoryRequirements2KHR; - PFN_vkGetBufferMemoryRequirements2KHR GetBufferMemoryRequirements2KHR; - PFN_vkGetImageSparseMemoryRequirements2KHR GetImageSparseMemoryRequirements2KHR; - - // ---- VK_KHR_sampler_ycbcr_conversion extension commands - PFN_vkCreateSamplerYcbcrConversionKHR CreateSamplerYcbcrConversionKHR; - PFN_vkDestroySamplerYcbcrConversionKHR DestroySamplerYcbcrConversionKHR; - - // ---- VK_KHR_bind_memory2 extension commands - PFN_vkBindBufferMemory2KHR BindBufferMemory2KHR; - PFN_vkBindImageMemory2KHR BindImageMemory2KHR; - - // ---- VK_KHR_maintenance3 extension commands - PFN_vkGetDescriptorSetLayoutSupportKHR GetDescriptorSetLayoutSupportKHR; - - // ---- VK_EXT_debug_marker extension commands - PFN_vkDebugMarkerSetObjectTagEXT DebugMarkerSetObjectTagEXT; - PFN_vkDebugMarkerSetObjectNameEXT DebugMarkerSetObjectNameEXT; - PFN_vkCmdDebugMarkerBeginEXT CmdDebugMarkerBeginEXT; - PFN_vkCmdDebugMarkerEndEXT CmdDebugMarkerEndEXT; - PFN_vkCmdDebugMarkerInsertEXT CmdDebugMarkerInsertEXT; - - // ---- VK_AMD_draw_indirect_count extension commands - PFN_vkCmdDrawIndirectCountAMD CmdDrawIndirectCountAMD; - PFN_vkCmdDrawIndexedIndirectCountAMD CmdDrawIndexedIndirectCountAMD; - - // ---- VK_AMD_shader_info extension commands - PFN_vkGetShaderInfoAMD GetShaderInfoAMD; - - // ---- VK_NV_external_memory_win32 extension commands -#ifdef VK_USE_PLATFORM_WIN32_KHR - PFN_vkGetMemoryWin32HandleNV GetMemoryWin32HandleNV; -#endif // VK_USE_PLATFORM_WIN32_KHR - - // ---- VK_NVX_device_generated_commands extension commands - PFN_vkCmdProcessCommandsNVX CmdProcessCommandsNVX; - PFN_vkCmdReserveSpaceForCommandsNVX CmdReserveSpaceForCommandsNVX; - PFN_vkCreateIndirectCommandsLayoutNVX CreateIndirectCommandsLayoutNVX; - PFN_vkDestroyIndirectCommandsLayoutNVX DestroyIndirectCommandsLayoutNVX; - PFN_vkCreateObjectTableNVX CreateObjectTableNVX; - PFN_vkDestroyObjectTableNVX DestroyObjectTableNVX; - PFN_vkRegisterObjectsNVX RegisterObjectsNVX; - PFN_vkUnregisterObjectsNVX UnregisterObjectsNVX; - - // ---- VK_NV_clip_space_w_scaling extension commands - PFN_vkCmdSetViewportWScalingNV CmdSetViewportWScalingNV; - - // ---- VK_EXT_display_control extension commands - PFN_vkDisplayPowerControlEXT DisplayPowerControlEXT; - PFN_vkRegisterDeviceEventEXT RegisterDeviceEventEXT; - PFN_vkRegisterDisplayEventEXT RegisterDisplayEventEXT; - PFN_vkGetSwapchainCounterEXT GetSwapchainCounterEXT; - - // ---- VK_GOOGLE_display_timing extension commands - PFN_vkGetRefreshCycleDurationGOOGLE GetRefreshCycleDurationGOOGLE; - PFN_vkGetPastPresentationTimingGOOGLE GetPastPresentationTimingGOOGLE; - - // ---- VK_EXT_discard_rectangles extension commands - PFN_vkCmdSetDiscardRectangleEXT CmdSetDiscardRectangleEXT; - - // ---- VK_EXT_hdr_metadata extension commands - PFN_vkSetHdrMetadataEXT SetHdrMetadataEXT; - - // ---- VK_EXT_debug_utils extension commands - PFN_vkSetDebugUtilsObjectNameEXT SetDebugUtilsObjectNameEXT; - PFN_vkSetDebugUtilsObjectTagEXT SetDebugUtilsObjectTagEXT; - PFN_vkQueueBeginDebugUtilsLabelEXT QueueBeginDebugUtilsLabelEXT; - PFN_vkQueueEndDebugUtilsLabelEXT QueueEndDebugUtilsLabelEXT; - PFN_vkQueueInsertDebugUtilsLabelEXT QueueInsertDebugUtilsLabelEXT; - PFN_vkCmdBeginDebugUtilsLabelEXT CmdBeginDebugUtilsLabelEXT; - PFN_vkCmdEndDebugUtilsLabelEXT CmdEndDebugUtilsLabelEXT; - PFN_vkCmdInsertDebugUtilsLabelEXT CmdInsertDebugUtilsLabelEXT; - - // ---- VK_EXT_sample_locations extension commands - PFN_vkCmdSetSampleLocationsEXT CmdSetSampleLocationsEXT; - - // ---- VK_EXT_validation_cache extension commands - PFN_vkCreateValidationCacheEXT CreateValidationCacheEXT; - PFN_vkDestroyValidationCacheEXT DestroyValidationCacheEXT; - PFN_vkMergeValidationCachesEXT MergeValidationCachesEXT; - PFN_vkGetValidationCacheDataEXT GetValidationCacheDataEXT; - - // ---- VK_EXT_external_memory_host extension commands - PFN_vkGetMemoryHostPointerPropertiesEXT GetMemoryHostPointerPropertiesEXT; - - // ---- VK_AMD_buffer_marker extension commands - PFN_vkCmdWriteBufferMarkerAMD CmdWriteBufferMarkerAMD; -} VkLayerDispatchTable; - - diff --git a/ext/vulkan/vulkan.h b/ext/vulkan/vulkan.h index d05c8490a5..a3be4af6c4 100644 --- a/ext/vulkan/vulkan.h +++ b/ext/vulkan/vulkan.h @@ -2,7 +2,7 @@ #define VULKAN_H_ 1 /* -** Copyright (c) 2015-2018 The Khronos Group Inc. +** Copyright (c) 2015-2019 The Khronos Group Inc. ** ** Licensed under the Apache License, Version 2.0 (the "License"); ** you may not use this file except in compliance with the License. @@ -24,6 +24,10 @@ #include "vulkan_android.h" #endif +#ifdef VK_USE_PLATFORM_FUCHSIA +#include +#include "vulkan_fuchsia.h" +#endif #ifdef VK_USE_PLATFORM_IOS_MVK #include "vulkan_ios.h" @@ -35,12 +39,6 @@ #endif -#ifdef VK_USE_PLATFORM_MIR_KHR -#include -#include "vulkan_mir.h" -#endif - - #ifdef VK_USE_PLATFORM_VI_NN #include "vulkan_vi.h" #endif diff --git a/ext/vulkan/vulkan_android.h b/ext/vulkan/vulkan_android.h index 5e61c0531a..e70376c886 100644 --- a/ext/vulkan/vulkan_android.h +++ b/ext/vulkan/vulkan_android.h @@ -6,7 +6,7 @@ extern "C" { #endif /* -** Copyright (c) 2015-2018 The Khronos Group Inc. +** Copyright (c) 2015-2019 The Khronos Group Inc. ** ** Licensed under the Apache License, Version 2.0 (the "License"); ** you may not use this file except in compliance with the License. @@ -53,6 +53,72 @@ VKAPI_ATTR VkResult VKAPI_CALL vkCreateAndroidSurfaceKHR( VkSurfaceKHR* pSurface); #endif +#define VK_ANDROID_external_memory_android_hardware_buffer 1 +struct AHardwareBuffer; + +#define VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_SPEC_VERSION 3 +#define VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_EXTENSION_NAME "VK_ANDROID_external_memory_android_hardware_buffer" + +typedef struct VkAndroidHardwareBufferUsageANDROID { + VkStructureType sType; + void* pNext; + uint64_t androidHardwareBufferUsage; +} VkAndroidHardwareBufferUsageANDROID; + +typedef struct VkAndroidHardwareBufferPropertiesANDROID { + VkStructureType sType; + void* pNext; + VkDeviceSize allocationSize; + uint32_t memoryTypeBits; +} VkAndroidHardwareBufferPropertiesANDROID; + +typedef struct VkAndroidHardwareBufferFormatPropertiesANDROID { + VkStructureType sType; + void* pNext; + VkFormat format; + uint64_t externalFormat; + VkFormatFeatureFlags formatFeatures; + VkComponentMapping samplerYcbcrConversionComponents; + VkSamplerYcbcrModelConversion suggestedYcbcrModel; + VkSamplerYcbcrRange suggestedYcbcrRange; + VkChromaLocation suggestedXChromaOffset; + VkChromaLocation suggestedYChromaOffset; +} VkAndroidHardwareBufferFormatPropertiesANDROID; + +typedef struct VkImportAndroidHardwareBufferInfoANDROID { + VkStructureType sType; + const void* pNext; + struct AHardwareBuffer* buffer; +} VkImportAndroidHardwareBufferInfoANDROID; + +typedef struct VkMemoryGetAndroidHardwareBufferInfoANDROID { + VkStructureType sType; + const void* pNext; + VkDeviceMemory memory; +} VkMemoryGetAndroidHardwareBufferInfoANDROID; + +typedef struct VkExternalFormatANDROID { + VkStructureType sType; + void* pNext; + uint64_t externalFormat; +} VkExternalFormatANDROID; + + +typedef VkResult (VKAPI_PTR *PFN_vkGetAndroidHardwareBufferPropertiesANDROID)(VkDevice device, const struct AHardwareBuffer* buffer, VkAndroidHardwareBufferPropertiesANDROID* pProperties); +typedef VkResult (VKAPI_PTR *PFN_vkGetMemoryAndroidHardwareBufferANDROID)(VkDevice device, const VkMemoryGetAndroidHardwareBufferInfoANDROID* pInfo, struct AHardwareBuffer** pBuffer); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkGetAndroidHardwareBufferPropertiesANDROID( + VkDevice device, + const struct AHardwareBuffer* buffer, + VkAndroidHardwareBufferPropertiesANDROID* pProperties); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetMemoryAndroidHardwareBufferANDROID( + VkDevice device, + const VkMemoryGetAndroidHardwareBufferInfoANDROID* pInfo, + struct AHardwareBuffer** pBuffer); +#endif + #ifdef __cplusplus } #endif diff --git a/ext/vulkan/vulkan_core.h b/ext/vulkan/vulkan_core.h index c115fa6616..caeecd9bed 100644 --- a/ext/vulkan/vulkan_core.h +++ b/ext/vulkan/vulkan_core.h @@ -6,7 +6,7 @@ extern "C" { #endif /* -** Copyright (c) 2015-2018 The Khronos Group Inc. +** Copyright (c) 2015-2019 The Khronos Group Inc. ** ** Licensed under the Apache License, Version 2.0 (the "License"); ** you may not use this file except in compliance with the License. @@ -43,11 +43,10 @@ extern "C" { #define VK_VERSION_MINOR(version) (((uint32_t)(version) >> 12) & 0x3ff) #define VK_VERSION_PATCH(version) ((uint32_t)(version) & 0xfff) // Version of this file -#define VK_HEADER_VERSION 70 +#define VK_HEADER_VERSION 97 #define VK_NULL_HANDLE 0 - #define VK_DEFINE_HANDLE(object) typedef struct object##_T* object; @@ -60,7 +59,6 @@ extern "C" { #define VK_DEFINE_NON_DISPATCHABLE_HANDLE(object) typedef uint64_t object; #endif #endif - typedef uint32_t VkFlags; @@ -147,7 +145,10 @@ typedef enum VkResult { VK_ERROR_INCOMPATIBLE_DISPLAY_KHR = -1000003001, VK_ERROR_VALIDATION_FAILED_EXT = -1000011001, VK_ERROR_INVALID_SHADER_NV = -1000012000, + VK_ERROR_INVALID_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT = -1000158000, + VK_ERROR_FRAGMENTATION_EXT = -1000161000, VK_ERROR_NOT_PERMITTED_EXT = -1000174001, + VK_ERROR_INVALID_DEVICE_ADDRESS_EXT = -1000244000, VK_ERROR_OUT_OF_POOL_MEMORY_KHR = VK_ERROR_OUT_OF_POOL_MEMORY, VK_ERROR_INVALID_EXTERNAL_HANDLE_KHR = VK_ERROR_INVALID_EXTERNAL_HANDLE, VK_RESULT_BEGIN_RANGE = VK_ERROR_FRAGMENTED_POOL, @@ -285,7 +286,6 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR = 1000004000, VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR = 1000005000, VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR = 1000006000, - VK_STRUCTURE_TYPE_MIR_SURFACE_CREATE_INFO_KHR = 1000007000, VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR = 1000008000, VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR = 1000009000, VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT = 1000011000, @@ -296,7 +296,11 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_IMAGE_CREATE_INFO_NV = 1000026000, VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_BUFFER_CREATE_INFO_NV = 1000026001, VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_MEMORY_ALLOCATE_INFO_NV = 1000026002, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_FEATURES_EXT = 1000028000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_PROPERTIES_EXT = 1000028001, + VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_STREAM_CREATE_INFO_EXT = 1000028002, VK_STRUCTURE_TYPE_TEXTURE_LOD_GATHER_FORMAT_PROPERTIES_AMD = 1000041000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CORNER_SAMPLED_IMAGE_FEATURES_NV = 1000050000, VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO_NV = 1000056000, VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO_NV = 1000056001, VK_STRUCTURE_TYPE_IMPORT_MEMORY_WIN32_HANDLE_INFO_NV = 1000057000, @@ -304,6 +308,8 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_WIN32_KEYED_MUTEX_ACQUIRE_RELEASE_INFO_NV = 1000058000, VK_STRUCTURE_TYPE_VALIDATION_FLAGS_EXT = 1000061000, VK_STRUCTURE_TYPE_VI_SURFACE_CREATE_INFO_NN = 1000062000, + VK_STRUCTURE_TYPE_IMAGE_VIEW_ASTC_DECODE_MODE_EXT = 1000067000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ASTC_DECODE_FEATURES_EXT = 1000067001, VK_STRUCTURE_TYPE_IMPORT_MEMORY_WIN32_HANDLE_INFO_KHR = 1000073000, VK_STRUCTURE_TYPE_EXPORT_MEMORY_WIN32_HANDLE_INFO_KHR = 1000073001, VK_STRUCTURE_TYPE_MEMORY_WIN32_HANDLE_PROPERTIES_KHR = 1000073002, @@ -319,6 +325,10 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_FD_INFO_KHR = 1000079000, VK_STRUCTURE_TYPE_SEMAPHORE_GET_FD_INFO_KHR = 1000079001, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PUSH_DESCRIPTOR_PROPERTIES_KHR = 1000080000, + VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_CONDITIONAL_RENDERING_INFO_EXT = 1000081000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CONDITIONAL_RENDERING_FEATURES_EXT = 1000081001, + VK_STRUCTURE_TYPE_CONDITIONAL_RENDERING_BEGIN_INFO_EXT = 1000081002, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT16_INT8_FEATURES_KHR = 1000082000, VK_STRUCTURE_TYPE_PRESENT_REGIONS_KHR = 1000084000, VK_STRUCTURE_TYPE_OBJECT_TABLE_CREATE_INFO_NVX = 1000086000, VK_STRUCTURE_TYPE_INDIRECT_COMMANDS_LAYOUT_CREATE_INFO_NVX = 1000086001, @@ -340,6 +350,13 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CONSERVATIVE_RASTERIZATION_PROPERTIES_EXT = 1000101000, VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_CONSERVATIVE_STATE_CREATE_INFO_EXT = 1000101001, VK_STRUCTURE_TYPE_HDR_METADATA_EXT = 1000105000, + VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2_KHR = 1000109000, + VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2_KHR = 1000109001, + VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2_KHR = 1000109002, + VK_STRUCTURE_TYPE_SUBPASS_DEPENDENCY_2_KHR = 1000109003, + VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2_KHR = 1000109004, + VK_STRUCTURE_TYPE_SUBPASS_BEGIN_INFO_KHR = 1000109005, + VK_STRUCTURE_TYPE_SUBPASS_END_INFO_KHR = 1000109006, VK_STRUCTURE_TYPE_SHARED_PRESENT_SURFACE_CAPABILITIES_KHR = 1000111000, VK_STRUCTURE_TYPE_IMPORT_FENCE_WIN32_HANDLE_INFO_KHR = 1000114000, VK_STRUCTURE_TYPE_EXPORT_FENCE_WIN32_HANDLE_INFO_KHR = 1000114001, @@ -349,6 +366,11 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SURFACE_INFO_2_KHR = 1000119000, VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_2_KHR = 1000119001, VK_STRUCTURE_TYPE_SURFACE_FORMAT_2_KHR = 1000119002, + VK_STRUCTURE_TYPE_DISPLAY_PROPERTIES_2_KHR = 1000121000, + VK_STRUCTURE_TYPE_DISPLAY_PLANE_PROPERTIES_2_KHR = 1000121001, + VK_STRUCTURE_TYPE_DISPLAY_MODE_PROPERTIES_2_KHR = 1000121002, + VK_STRUCTURE_TYPE_DISPLAY_PLANE_INFO_2_KHR = 1000121003, + VK_STRUCTURE_TYPE_DISPLAY_PLANE_CAPABILITIES_2_KHR = 1000121004, VK_STRUCTURE_TYPE_IOS_SURFACE_CREATE_INFO_MVK = 1000122000, VK_STRUCTURE_TYPE_MACOS_SURFACE_CREATE_INFO_MVK = 1000123000, VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT = 1000128000, @@ -356,8 +378,18 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_DEBUG_UTILS_LABEL_EXT = 1000128002, VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CALLBACK_DATA_EXT = 1000128003, VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT = 1000128004, + VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_USAGE_ANDROID = 1000129000, + VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_PROPERTIES_ANDROID = 1000129001, + VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_FORMAT_PROPERTIES_ANDROID = 1000129002, + VK_STRUCTURE_TYPE_IMPORT_ANDROID_HARDWARE_BUFFER_INFO_ANDROID = 1000129003, + VK_STRUCTURE_TYPE_MEMORY_GET_ANDROID_HARDWARE_BUFFER_INFO_ANDROID = 1000129004, + VK_STRUCTURE_TYPE_EXTERNAL_FORMAT_ANDROID = 1000129005, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_FILTER_MINMAX_PROPERTIES_EXT = 1000130000, VK_STRUCTURE_TYPE_SAMPLER_REDUCTION_MODE_CREATE_INFO_EXT = 1000130001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_FEATURES_EXT = 1000138000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_PROPERTIES_EXT = 1000138001, + VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_INLINE_UNIFORM_BLOCK_EXT = 1000138002, + VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_INLINE_UNIFORM_BLOCK_CREATE_INFO_EXT = 1000138003, VK_STRUCTURE_TYPE_SAMPLE_LOCATIONS_INFO_EXT = 1000143000, VK_STRUCTURE_TYPE_RENDER_PASS_SAMPLE_LOCATIONS_BEGIN_INFO_EXT = 1000143001, VK_STRUCTURE_TYPE_PIPELINE_SAMPLE_LOCATIONS_STATE_CREATE_INFO_EXT = 1000143002, @@ -369,14 +401,77 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_ADVANCED_STATE_CREATE_INFO_EXT = 1000148002, VK_STRUCTURE_TYPE_PIPELINE_COVERAGE_TO_COLOR_STATE_CREATE_INFO_NV = 1000149000, VK_STRUCTURE_TYPE_PIPELINE_COVERAGE_MODULATION_STATE_CREATE_INFO_NV = 1000152000, + VK_STRUCTURE_TYPE_DRM_FORMAT_MODIFIER_PROPERTIES_LIST_EXT = 1000158000, + VK_STRUCTURE_TYPE_DRM_FORMAT_MODIFIER_PROPERTIES_EXT = 1000158001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_DRM_FORMAT_MODIFIER_INFO_EXT = 1000158002, + VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_LIST_CREATE_INFO_EXT = 1000158003, + VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_EXPLICIT_CREATE_INFO_EXT = 1000158004, + VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_PROPERTIES_EXT = 1000158005, VK_STRUCTURE_TYPE_VALIDATION_CACHE_CREATE_INFO_EXT = 1000160000, VK_STRUCTURE_TYPE_SHADER_MODULE_VALIDATION_CACHE_CREATE_INFO_EXT = 1000160001, + VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO_EXT = 1000161000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES_EXT = 1000161001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_PROPERTIES_EXT = 1000161002, + VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_ALLOCATE_INFO_EXT = 1000161003, + VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_LAYOUT_SUPPORT_EXT = 1000161004, + VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_SHADING_RATE_IMAGE_STATE_CREATE_INFO_NV = 1000164000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADING_RATE_IMAGE_FEATURES_NV = 1000164001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADING_RATE_IMAGE_PROPERTIES_NV = 1000164002, + VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_COARSE_SAMPLE_ORDER_STATE_CREATE_INFO_NV = 1000164005, + VK_STRUCTURE_TYPE_RAY_TRACING_PIPELINE_CREATE_INFO_NV = 1000165000, + VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_INFO_NV = 1000165001, + VK_STRUCTURE_TYPE_GEOMETRY_NV = 1000165003, + VK_STRUCTURE_TYPE_GEOMETRY_TRIANGLES_NV = 1000165004, + VK_STRUCTURE_TYPE_GEOMETRY_AABB_NV = 1000165005, + VK_STRUCTURE_TYPE_BIND_ACCELERATION_STRUCTURE_MEMORY_INFO_NV = 1000165006, + VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_NV = 1000165007, + VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_INFO_NV = 1000165008, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_PROPERTIES_NV = 1000165009, + VK_STRUCTURE_TYPE_RAY_TRACING_SHADER_GROUP_CREATE_INFO_NV = 1000165011, + VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_INFO_NV = 1000165012, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_REPRESENTATIVE_FRAGMENT_TEST_FEATURES_NV = 1000166000, + VK_STRUCTURE_TYPE_PIPELINE_REPRESENTATIVE_FRAGMENT_TEST_STATE_CREATE_INFO_NV = 1000166001, VK_STRUCTURE_TYPE_DEVICE_QUEUE_GLOBAL_PRIORITY_CREATE_INFO_EXT = 1000174000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES_KHR = 1000177000, VK_STRUCTURE_TYPE_IMPORT_MEMORY_HOST_POINTER_INFO_EXT = 1000178000, VK_STRUCTURE_TYPE_MEMORY_HOST_POINTER_PROPERTIES_EXT = 1000178001, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_MEMORY_HOST_PROPERTIES_EXT = 1000178002, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_INT64_FEATURES_KHR = 1000180000, + VK_STRUCTURE_TYPE_CALIBRATED_TIMESTAMP_INFO_EXT = 1000184000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_CORE_PROPERTIES_AMD = 1000185000, + VK_STRUCTURE_TYPE_DEVICE_MEMORY_OVERALLOCATION_CREATE_INFO_AMD = 1000189000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_PROPERTIES_EXT = 1000190000, VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_DIVISOR_STATE_CREATE_INFO_EXT = 1000190001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_FEATURES_EXT = 1000190002, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES_KHR = 1000196000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT_CONTROLS_PROPERTIES_KHR = 1000197000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_STENCIL_RESOLVE_PROPERTIES_KHR = 1000199000, + VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_DEPTH_STENCIL_RESOLVE_KHR = 1000199001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COMPUTE_SHADER_DERIVATIVES_FEATURES_NV = 1000201000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MESH_SHADER_FEATURES_NV = 1000202000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MESH_SHADER_PROPERTIES_NV = 1000202001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADER_BARYCENTRIC_FEATURES_NV = 1000203000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_IMAGE_FOOTPRINT_FEATURES_NV = 1000204000, + VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_EXCLUSIVE_SCISSOR_STATE_CREATE_INFO_NV = 1000205000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXCLUSIVE_SCISSOR_FEATURES_NV = 1000205002, + VK_STRUCTURE_TYPE_CHECKPOINT_DATA_NV = 1000206000, + VK_STRUCTURE_TYPE_QUEUE_FAMILY_CHECKPOINT_PROPERTIES_NV = 1000206001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_MEMORY_MODEL_FEATURES_KHR = 1000211000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PCI_BUS_INFO_PROPERTIES_EXT = 1000212000, + VK_STRUCTURE_TYPE_IMAGEPIPE_SURFACE_CREATE_INFO_FUCHSIA = 1000214000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_FEATURES_EXT = 1000218000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_PROPERTIES_EXT = 1000218001, + VK_STRUCTURE_TYPE_RENDER_PASS_FRAGMENT_DENSITY_MAP_CREATE_INFO_EXT = 1000218002, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES_EXT = 1000221000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_BUDGET_PROPERTIES_EXT = 1000237000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PRIORITY_FEATURES_EXT = 1000238000, + VK_STRUCTURE_TYPE_MEMORY_PRIORITY_ALLOCATE_INFO_EXT = 1000238001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_ADDRESS_FEATURES_EXT = 1000244000, + VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO_EXT = 1000244001, + VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_CREATE_INFO_EXT = 1000244002, + VK_STRUCTURE_TYPE_IMAGE_STENCIL_USAGE_CREATE_INFO_EXT = 1000246000, + VK_STRUCTURE_TYPE_VALIDATION_FEATURES_EXT = 1000247000, + VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT = VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT, VK_STRUCTURE_TYPE_RENDER_PASS_MULTIVIEW_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_RENDER_PASS_MULTIVIEW_CREATE_INFO, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PROPERTIES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PROPERTIES, @@ -411,6 +506,7 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES, VK_STRUCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO, + VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES2_EXT = VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_2_EXT, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_FENCE_INFO_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_FENCE_INFO, VK_STRUCTURE_TYPE_EXTERNAL_FENCE_PROPERTIES_KHR = VK_STRUCTURE_TYPE_EXTERNAL_FENCE_PROPERTIES, VK_STRUCTURE_TYPE_EXPORT_FENCE_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_EXPORT_FENCE_CREATE_INFO, @@ -743,6 +839,7 @@ typedef enum VkImageType { typedef enum VkImageTiling { VK_IMAGE_TILING_OPTIMAL = 0, VK_IMAGE_TILING_LINEAR = 1, + VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT = 1000158000, VK_IMAGE_TILING_BEGIN_RANGE = VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_TILING_END_RANGE = VK_IMAGE_TILING_LINEAR, VK_IMAGE_TILING_RANGE_SIZE = (VK_IMAGE_TILING_LINEAR - VK_IMAGE_TILING_OPTIMAL + 1), @@ -765,6 +862,8 @@ typedef enum VkQueryType { VK_QUERY_TYPE_OCCLUSION = 0, VK_QUERY_TYPE_PIPELINE_STATISTICS = 1, VK_QUERY_TYPE_TIMESTAMP = 2, + VK_QUERY_TYPE_TRANSFORM_FEEDBACK_STREAM_EXT = 1000028004, + VK_QUERY_TYPE_ACCELERATION_STRUCTURE_COMPACTED_SIZE_NV = 1000165000, VK_QUERY_TYPE_BEGIN_RANGE = VK_QUERY_TYPE_OCCLUSION, VK_QUERY_TYPE_END_RANGE = VK_QUERY_TYPE_TIMESTAMP, VK_QUERY_TYPE_RANGE_SIZE = (VK_QUERY_TYPE_TIMESTAMP - VK_QUERY_TYPE_OCCLUSION + 1), @@ -794,6 +893,8 @@ typedef enum VkImageLayout { VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL = 1000117001, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR = 1000001002, VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR = 1000111000, + VK_IMAGE_LAYOUT_SHADING_RATE_OPTIMAL_NV = 1000164003, + VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT = 1000218000, VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL_KHR = VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL_KHR = VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL, VK_IMAGE_LAYOUT_BEGIN_RANGE = VK_IMAGE_LAYOUT_UNDEFINED, @@ -1027,6 +1128,9 @@ typedef enum VkDynamicState { VK_DYNAMIC_STATE_VIEWPORT_W_SCALING_NV = 1000087000, VK_DYNAMIC_STATE_DISCARD_RECTANGLE_EXT = 1000099000, VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_EXT = 1000143000, + VK_DYNAMIC_STATE_VIEWPORT_SHADING_RATE_PALETTE_NV = 1000164004, + VK_DYNAMIC_STATE_VIEWPORT_COARSE_SAMPLE_ORDER_NV = 1000164006, + VK_DYNAMIC_STATE_EXCLUSIVE_SCISSOR_NV = 1000205001, VK_DYNAMIC_STATE_BEGIN_RANGE = VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_END_RANGE = VK_DYNAMIC_STATE_STENCIL_REFERENCE, VK_DYNAMIC_STATE_RANGE_SIZE = (VK_DYNAMIC_STATE_STENCIL_REFERENCE - VK_DYNAMIC_STATE_VIEWPORT + 1), @@ -1089,6 +1193,8 @@ typedef enum VkDescriptorType { VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC = 8, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC = 9, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT = 10, + VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT = 1000138000, + VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_NV = 1000165000, VK_DESCRIPTOR_TYPE_BEGIN_RANGE = VK_DESCRIPTOR_TYPE_SAMPLER, VK_DESCRIPTOR_TYPE_END_RANGE = VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, VK_DESCRIPTOR_TYPE_RANGE_SIZE = (VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT - VK_DESCRIPTOR_TYPE_SAMPLER + 1), @@ -1117,6 +1223,7 @@ typedef enum VkAttachmentStoreOp { typedef enum VkPipelineBindPoint { VK_PIPELINE_BIND_POINT_GRAPHICS = 0, VK_PIPELINE_BIND_POINT_COMPUTE = 1, + VK_PIPELINE_BIND_POINT_RAY_TRACING_NV = 1000165000, VK_PIPELINE_BIND_POINT_BEGIN_RANGE = VK_PIPELINE_BIND_POINT_GRAPHICS, VK_PIPELINE_BIND_POINT_END_RANGE = VK_PIPELINE_BIND_POINT_COMPUTE, VK_PIPELINE_BIND_POINT_RANGE_SIZE = (VK_PIPELINE_BIND_POINT_COMPUTE - VK_PIPELINE_BIND_POINT_GRAPHICS + 1), @@ -1135,6 +1242,7 @@ typedef enum VkCommandBufferLevel { typedef enum VkIndexType { VK_INDEX_TYPE_UINT16 = 0, VK_INDEX_TYPE_UINT32 = 1, + VK_INDEX_TYPE_NONE_NV = 1000165000, VK_INDEX_TYPE_BEGIN_RANGE = VK_INDEX_TYPE_UINT16, VK_INDEX_TYPE_END_RANGE = VK_INDEX_TYPE_UINT32, VK_INDEX_TYPE_RANGE_SIZE = (VK_INDEX_TYPE_UINT32 - VK_INDEX_TYPE_UINT16 + 1), @@ -1188,6 +1296,7 @@ typedef enum VkObjectType { VK_OBJECT_TYPE_INDIRECT_COMMANDS_LAYOUT_NVX = 1000086001, VK_OBJECT_TYPE_DEBUG_UTILS_MESSENGER_EXT = 1000128000, VK_OBJECT_TYPE_VALIDATION_CACHE_EXT = 1000160000, + VK_OBJECT_TYPE_ACCELERATION_STRUCTURE_NV = 1000165000, VK_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_KHR = VK_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE, VK_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION_KHR = VK_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION, VK_OBJECT_TYPE_BEGIN_RANGE = VK_OBJECT_TYPE_UNKNOWN, @@ -1196,6 +1305,16 @@ typedef enum VkObjectType { VK_OBJECT_TYPE_MAX_ENUM = 0x7FFFFFFF } VkObjectType; +typedef enum VkVendorId { + VK_VENDOR_ID_VIV = 0x10001, + VK_VENDOR_ID_VSI = 0x10002, + VK_VENDOR_ID_KAZAN = 0x10003, + VK_VENDOR_ID_BEGIN_RANGE = VK_VENDOR_ID_VIV, + VK_VENDOR_ID_END_RANGE = VK_VENDOR_ID_KAZAN, + VK_VENDOR_ID_RANGE_SIZE = (VK_VENDOR_ID_KAZAN - VK_VENDOR_ID_VIV + 1), + VK_VENDOR_ID_MAX_ENUM = 0x7FFFFFFF +} VkVendorId; + typedef VkFlags VkInstanceCreateFlags; typedef enum VkFormatFeatureFlagBits { @@ -1223,6 +1342,7 @@ typedef enum VkFormatFeatureFlagBits { VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT = 0x00800000, VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_IMG = 0x00002000, VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_MINMAX_BIT_EXT = 0x00010000, + VK_FORMAT_FEATURE_FRAGMENT_DENSITY_MAP_BIT_EXT = 0x01000000, VK_FORMAT_FEATURE_TRANSFER_SRC_BIT_KHR = VK_FORMAT_FEATURE_TRANSFER_SRC_BIT, VK_FORMAT_FEATURE_TRANSFER_DST_BIT_KHR = VK_FORMAT_FEATURE_TRANSFER_DST_BIT, VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT_KHR = VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT, @@ -1245,6 +1365,8 @@ typedef enum VkImageUsageFlagBits { VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT = 0x00000020, VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT = 0x00000040, VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT = 0x00000080, + VK_IMAGE_USAGE_SHADING_RATE_IMAGE_BIT_NV = 0x00000100, + VK_IMAGE_USAGE_FRAGMENT_DENSITY_MAP_BIT_EXT = 0x00000200, VK_IMAGE_USAGE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VkImageUsageFlagBits; typedef VkFlags VkImageUsageFlags; @@ -1262,7 +1384,9 @@ typedef enum VkImageCreateFlagBits { VK_IMAGE_CREATE_EXTENDED_USAGE_BIT = 0x00000100, VK_IMAGE_CREATE_PROTECTED_BIT = 0x00000800, VK_IMAGE_CREATE_DISJOINT_BIT = 0x00000200, + VK_IMAGE_CREATE_CORNER_SAMPLED_BIT_NV = 0x00002000, VK_IMAGE_CREATE_SAMPLE_LOCATIONS_COMPATIBLE_DEPTH_BIT_EXT = 0x00001000, + VK_IMAGE_CREATE_SUBSAMPLED_BIT_EXT = 0x00004000, VK_IMAGE_CREATE_SPLIT_INSTANCE_BIND_REGIONS_BIT_KHR = VK_IMAGE_CREATE_SPLIT_INSTANCE_BIND_REGIONS_BIT, VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT_KHR = VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT, VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT_KHR = VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT, @@ -1339,7 +1463,15 @@ typedef enum VkPipelineStageFlagBits { VK_PIPELINE_STAGE_HOST_BIT = 0x00004000, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT = 0x00008000, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT = 0x00010000, + VK_PIPELINE_STAGE_TRANSFORM_FEEDBACK_BIT_EXT = 0x01000000, + VK_PIPELINE_STAGE_CONDITIONAL_RENDERING_BIT_EXT = 0x00040000, VK_PIPELINE_STAGE_COMMAND_PROCESS_BIT_NVX = 0x00020000, + VK_PIPELINE_STAGE_SHADING_RATE_IMAGE_BIT_NV = 0x00400000, + VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_NV = 0x00200000, + VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_NV = 0x02000000, + VK_PIPELINE_STAGE_TASK_SHADER_BIT_NV = 0x00080000, + VK_PIPELINE_STAGE_MESH_SHADER_BIT_NV = 0x00100000, + VK_PIPELINE_STAGE_FRAGMENT_DENSITY_PROCESS_BIT_EXT = 0x00800000, VK_PIPELINE_STAGE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VkPipelineStageFlagBits; typedef VkFlags VkPipelineStageFlags; @@ -1353,6 +1485,10 @@ typedef enum VkImageAspectFlagBits { VK_IMAGE_ASPECT_PLANE_0_BIT = 0x00000010, VK_IMAGE_ASPECT_PLANE_1_BIT = 0x00000020, VK_IMAGE_ASPECT_PLANE_2_BIT = 0x00000040, + VK_IMAGE_ASPECT_MEMORY_PLANE_0_BIT_EXT = 0x00000080, + VK_IMAGE_ASPECT_MEMORY_PLANE_1_BIT_EXT = 0x00000100, + VK_IMAGE_ASPECT_MEMORY_PLANE_2_BIT_EXT = 0x00000200, + VK_IMAGE_ASPECT_MEMORY_PLANE_3_BIT_EXT = 0x00000400, VK_IMAGE_ASPECT_PLANE_0_BIT_KHR = VK_IMAGE_ASPECT_PLANE_0_BIT, VK_IMAGE_ASPECT_PLANE_1_BIT_KHR = VK_IMAGE_ASPECT_PLANE_1_BIT, VK_IMAGE_ASPECT_PLANE_2_BIT_KHR = VK_IMAGE_ASPECT_PLANE_2_BIT, @@ -1413,6 +1549,7 @@ typedef enum VkBufferCreateFlagBits { VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT = 0x00000002, VK_BUFFER_CREATE_SPARSE_ALIASED_BIT = 0x00000004, VK_BUFFER_CREATE_PROTECTED_BIT = 0x00000008, + VK_BUFFER_CREATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT_EXT = 0x00000010, VK_BUFFER_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VkBufferCreateFlagBits; typedef VkFlags VkBufferCreateFlags; @@ -1427,10 +1564,20 @@ typedef enum VkBufferUsageFlagBits { VK_BUFFER_USAGE_INDEX_BUFFER_BIT = 0x00000040, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT = 0x00000080, VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT = 0x00000100, + VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_BUFFER_BIT_EXT = 0x00000800, + VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_COUNTER_BUFFER_BIT_EXT = 0x00001000, + VK_BUFFER_USAGE_CONDITIONAL_RENDERING_BIT_EXT = 0x00000200, + VK_BUFFER_USAGE_RAY_TRACING_BIT_NV = 0x00000400, + VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT_EXT = 0x00020000, VK_BUFFER_USAGE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VkBufferUsageFlagBits; typedef VkFlags VkBufferUsageFlags; typedef VkFlags VkBufferViewCreateFlags; + +typedef enum VkImageViewCreateFlagBits { + VK_IMAGE_VIEW_CREATE_FRAGMENT_DENSITY_MAP_DYNAMIC_BIT_EXT = 0x00000001, + VK_IMAGE_VIEW_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkImageViewCreateFlagBits; typedef VkFlags VkImageViewCreateFlags; typedef VkFlags VkShaderModuleCreateFlags; typedef VkFlags VkPipelineCacheCreateFlags; @@ -1441,6 +1588,7 @@ typedef enum VkPipelineCreateFlagBits { VK_PIPELINE_CREATE_DERIVATIVE_BIT = 0x00000004, VK_PIPELINE_CREATE_VIEW_INDEX_FROM_DEVICE_INDEX_BIT = 0x00000008, VK_PIPELINE_CREATE_DISPATCH_BASE = 0x00000010, + VK_PIPELINE_CREATE_DEFER_COMPILE_BIT_NV = 0x00000020, VK_PIPELINE_CREATE_VIEW_INDEX_FROM_DEVICE_INDEX_BIT_KHR = VK_PIPELINE_CREATE_VIEW_INDEX_FROM_DEVICE_INDEX_BIT, VK_PIPELINE_CREATE_DISPATCH_BASE_KHR = VK_PIPELINE_CREATE_DISPATCH_BASE, VK_PIPELINE_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF @@ -1457,6 +1605,14 @@ typedef enum VkShaderStageFlagBits { VK_SHADER_STAGE_COMPUTE_BIT = 0x00000020, VK_SHADER_STAGE_ALL_GRAPHICS = 0x0000001F, VK_SHADER_STAGE_ALL = 0x7FFFFFFF, + VK_SHADER_STAGE_RAYGEN_BIT_NV = 0x00000100, + VK_SHADER_STAGE_ANY_HIT_BIT_NV = 0x00000200, + VK_SHADER_STAGE_CLOSEST_HIT_BIT_NV = 0x00000400, + VK_SHADER_STAGE_MISS_BIT_NV = 0x00000800, + VK_SHADER_STAGE_INTERSECTION_BIT_NV = 0x00001000, + VK_SHADER_STAGE_CALLABLE_BIT_NV = 0x00002000, + VK_SHADER_STAGE_TASK_BIT_NV = 0x00000040, + VK_SHADER_STAGE_MESH_BIT_NV = 0x00000080, VK_SHADER_STAGE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VkShaderStageFlagBits; typedef VkFlags VkPipelineVertexInputStateCreateFlags; @@ -1488,16 +1644,24 @@ typedef VkFlags VkColorComponentFlags; typedef VkFlags VkPipelineDynamicStateCreateFlags; typedef VkFlags VkPipelineLayoutCreateFlags; typedef VkFlags VkShaderStageFlags; + +typedef enum VkSamplerCreateFlagBits { + VK_SAMPLER_CREATE_SUBSAMPLED_BIT_EXT = 0x00000001, + VK_SAMPLER_CREATE_SUBSAMPLED_COARSE_RECONSTRUCTION_BIT_EXT = 0x00000002, + VK_SAMPLER_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkSamplerCreateFlagBits; typedef VkFlags VkSamplerCreateFlags; typedef enum VkDescriptorSetLayoutCreateFlagBits { VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR = 0x00000001, + VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT_EXT = 0x00000002, VK_DESCRIPTOR_SET_LAYOUT_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VkDescriptorSetLayoutCreateFlagBits; typedef VkFlags VkDescriptorSetLayoutCreateFlags; typedef enum VkDescriptorPoolCreateFlagBits { VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT = 0x00000001, + VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT_EXT = 0x00000002, VK_DESCRIPTOR_POOL_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VkDescriptorPoolCreateFlagBits; typedef VkFlags VkDescriptorPoolCreateFlags; @@ -1536,9 +1700,17 @@ typedef enum VkAccessFlagBits { VK_ACCESS_HOST_WRITE_BIT = 0x00004000, VK_ACCESS_MEMORY_READ_BIT = 0x00008000, VK_ACCESS_MEMORY_WRITE_BIT = 0x00010000, + VK_ACCESS_TRANSFORM_FEEDBACK_WRITE_BIT_EXT = 0x02000000, + VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_READ_BIT_EXT = 0x04000000, + VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_WRITE_BIT_EXT = 0x08000000, + VK_ACCESS_CONDITIONAL_RENDERING_READ_BIT_EXT = 0x00100000, VK_ACCESS_COMMAND_PROCESS_READ_BIT_NVX = 0x00020000, VK_ACCESS_COMMAND_PROCESS_WRITE_BIT_NVX = 0x00040000, VK_ACCESS_COLOR_ATTACHMENT_READ_NONCOHERENT_BIT_EXT = 0x00080000, + VK_ACCESS_SHADING_RATE_IMAGE_READ_BIT_NV = 0x00800000, + VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_NV = 0x00200000, + VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_NV = 0x00400000, + VK_ACCESS_FRAGMENT_DENSITY_MAP_READ_BIT_EXT = 0x01000000, VK_ACCESS_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VkAccessFlagBits; typedef VkFlags VkAccessFlags; @@ -2700,6 +2872,16 @@ typedef struct VkDrawIndirectCommand { uint32_t firstInstance; } VkDrawIndirectCommand; +typedef struct VkBaseOutStructure { + VkStructureType sType; + struct VkBaseOutStructure* pNext; +} VkBaseOutStructure; + +typedef struct VkBaseInStructure { + VkStructureType sType; + const struct VkBaseInStructure* pNext; +} VkBaseInStructure; + typedef VkResult (VKAPI_PTR *PFN_vkCreateInstance)(const VkInstanceCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkInstance* pInstance); typedef void (VKAPI_PTR *PFN_vkDestroyInstance)(VkInstance instance, const VkAllocationCallbacks* pAllocator); @@ -3732,6 +3914,7 @@ typedef enum VkSubgroupFeatureFlagBits { VK_SUBGROUP_FEATURE_SHUFFLE_RELATIVE_BIT = 0x00000020, VK_SUBGROUP_FEATURE_CLUSTERED_BIT = 0x00000040, VK_SUBGROUP_FEATURE_QUAD_BIT = 0x00000080, + VK_SUBGROUP_FEATURE_PARTITIONED_BIT_NV = 0x00000100, VK_SUBGROUP_FEATURE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VkSubgroupFeatureFlagBits; typedef VkFlags VkSubgroupFeatureFlags; @@ -3767,6 +3950,7 @@ typedef enum VkExternalMemoryHandleTypeFlagBits { VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_HEAP_BIT = 0x00000020, VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_RESOURCE_BIT = 0x00000040, VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT = 0x00000200, + VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID = 0x00000400, VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT = 0x00000080, VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_MAPPED_FOREIGN_MEMORY_BIT_EXT = 0x00000100, VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT, @@ -3993,6 +4177,8 @@ typedef struct VkMemoryRequirements2 { VkMemoryRequirements memoryRequirements; } VkMemoryRequirements2; +typedef VkMemoryRequirements2 VkMemoryRequirements2KHR; + typedef struct VkSparseImageMemoryRequirements2 { VkStructureType sType; void* pNext; @@ -4205,7 +4391,7 @@ typedef struct VkDescriptorUpdateTemplateEntry { typedef struct VkDescriptorUpdateTemplateCreateInfo { VkStructureType sType; - void* pNext; + const void* pNext; VkDescriptorUpdateTemplateCreateFlags flags; uint32_t descriptorUpdateEntryCount; const VkDescriptorUpdateTemplateEntry* pDescriptorUpdateEntries; @@ -4517,7 +4703,6 @@ VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkSurfaceKHR) #define VK_KHR_SURFACE_SPEC_VERSION 25 #define VK_KHR_SURFACE_EXTENSION_NAME "VK_KHR_surface" -#define VK_COLORSPACE_SRGB_NONLINEAR_KHR VK_COLOR_SPACE_SRGB_NONLINEAR_KHR typedef enum VkColorSpaceKHR { @@ -4536,6 +4721,7 @@ typedef enum VkColorSpaceKHR { VK_COLOR_SPACE_ADOBERGB_NONLINEAR_EXT = 1000104012, VK_COLOR_SPACE_PASS_THROUGH_EXT = 1000104013, VK_COLOR_SPACE_EXTENDED_SRGB_NONLINEAR_EXT = 1000104014, + VK_COLORSPACE_SRGB_NONLINEAR_KHR = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR, VK_COLOR_SPACE_BEGIN_RANGE_KHR = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR, VK_COLOR_SPACE_END_RANGE_KHR = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR, VK_COLOR_SPACE_RANGE_SIZE_KHR = (VK_COLOR_SPACE_SRGB_NONLINEAR_KHR - VK_COLOR_SPACE_SRGB_NONLINEAR_KHR + 1), @@ -4644,6 +4830,7 @@ VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkSwapchainKHR) typedef enum VkSwapchainCreateFlagBitsKHR { VK_SWAPCHAIN_CREATE_SPLIT_INSTANCE_BIND_REGIONS_BIT_KHR = 0x00000001, VK_SWAPCHAIN_CREATE_PROTECTED_BIT_KHR = 0x00000002, + VK_SWAPCHAIN_CREATE_MUTABLE_FORMAT_BIT_KHR = 0x00000004, VK_SWAPCHAIN_CREATE_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF } VkSwapchainCreateFlagBitsKHR; typedef VkFlags VkSwapchainCreateFlagsKHR; @@ -5090,7 +5277,7 @@ VKAPI_ATTR void VKAPI_CALL vkCmdDispatchBaseKHR( #define VK_KHR_maintenance1 1 -#define VK_KHR_MAINTENANCE1_SPEC_VERSION 1 +#define VK_KHR_MAINTENANCE1_SPEC_VERSION 2 #define VK_KHR_MAINTENANCE1_EXTENSION_NAME "VK_KHR_maintenance1" typedef VkCommandPoolTrimFlags VkCommandPoolTrimFlagsKHR; @@ -5320,6 +5507,19 @@ VKAPI_ATTR void VKAPI_CALL vkCmdPushDescriptorSetWithTemplateKHR( const void* pData); #endif +#define VK_KHR_shader_float16_int8 1 +#define VK_KHR_SHADER_FLOAT16_INT8_SPEC_VERSION 1 +#define VK_KHR_SHADER_FLOAT16_INT8_EXTENSION_NAME "VK_KHR_shader_float16_int8" + +typedef struct VkPhysicalDeviceFloat16Int8FeaturesKHR { + VkStructureType sType; + void* pNext; + VkBool32 shaderFloat16; + VkBool32 shaderInt8; +} VkPhysicalDeviceFloat16Int8FeaturesKHR; + + + #define VK_KHR_16bit_storage 1 #define VK_KHR_16BIT_STORAGE_SPEC_VERSION 1 #define VK_KHR_16BIT_STORAGE_EXTENSION_NAME "VK_KHR_16bit_storage" @@ -5393,6 +5593,114 @@ VKAPI_ATTR void VKAPI_CALL vkUpdateDescriptorSetWithTemplateKHR( const void* pData); #endif +#define VK_KHR_create_renderpass2 1 +#define VK_KHR_CREATE_RENDERPASS_2_SPEC_VERSION 1 +#define VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME "VK_KHR_create_renderpass2" + +typedef struct VkAttachmentDescription2KHR { + VkStructureType sType; + const void* pNext; + VkAttachmentDescriptionFlags flags; + VkFormat format; + VkSampleCountFlagBits samples; + VkAttachmentLoadOp loadOp; + VkAttachmentStoreOp storeOp; + VkAttachmentLoadOp stencilLoadOp; + VkAttachmentStoreOp stencilStoreOp; + VkImageLayout initialLayout; + VkImageLayout finalLayout; +} VkAttachmentDescription2KHR; + +typedef struct VkAttachmentReference2KHR { + VkStructureType sType; + const void* pNext; + uint32_t attachment; + VkImageLayout layout; + VkImageAspectFlags aspectMask; +} VkAttachmentReference2KHR; + +typedef struct VkSubpassDescription2KHR { + VkStructureType sType; + const void* pNext; + VkSubpassDescriptionFlags flags; + VkPipelineBindPoint pipelineBindPoint; + uint32_t viewMask; + uint32_t inputAttachmentCount; + const VkAttachmentReference2KHR* pInputAttachments; + uint32_t colorAttachmentCount; + const VkAttachmentReference2KHR* pColorAttachments; + const VkAttachmentReference2KHR* pResolveAttachments; + const VkAttachmentReference2KHR* pDepthStencilAttachment; + uint32_t preserveAttachmentCount; + const uint32_t* pPreserveAttachments; +} VkSubpassDescription2KHR; + +typedef struct VkSubpassDependency2KHR { + VkStructureType sType; + const void* pNext; + uint32_t srcSubpass; + uint32_t dstSubpass; + VkPipelineStageFlags srcStageMask; + VkPipelineStageFlags dstStageMask; + VkAccessFlags srcAccessMask; + VkAccessFlags dstAccessMask; + VkDependencyFlags dependencyFlags; + int32_t viewOffset; +} VkSubpassDependency2KHR; + +typedef struct VkRenderPassCreateInfo2KHR { + VkStructureType sType; + const void* pNext; + VkRenderPassCreateFlags flags; + uint32_t attachmentCount; + const VkAttachmentDescription2KHR* pAttachments; + uint32_t subpassCount; + const VkSubpassDescription2KHR* pSubpasses; + uint32_t dependencyCount; + const VkSubpassDependency2KHR* pDependencies; + uint32_t correlatedViewMaskCount; + const uint32_t* pCorrelatedViewMasks; +} VkRenderPassCreateInfo2KHR; + +typedef struct VkSubpassBeginInfoKHR { + VkStructureType sType; + const void* pNext; + VkSubpassContents contents; +} VkSubpassBeginInfoKHR; + +typedef struct VkSubpassEndInfoKHR { + VkStructureType sType; + const void* pNext; +} VkSubpassEndInfoKHR; + + +typedef VkResult (VKAPI_PTR *PFN_vkCreateRenderPass2KHR)(VkDevice device, const VkRenderPassCreateInfo2KHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkRenderPass* pRenderPass); +typedef void (VKAPI_PTR *PFN_vkCmdBeginRenderPass2KHR)(VkCommandBuffer commandBuffer, const VkRenderPassBeginInfo* pRenderPassBegin, const VkSubpassBeginInfoKHR* pSubpassBeginInfo); +typedef void (VKAPI_PTR *PFN_vkCmdNextSubpass2KHR)(VkCommandBuffer commandBuffer, const VkSubpassBeginInfoKHR* pSubpassBeginInfo, const VkSubpassEndInfoKHR* pSubpassEndInfo); +typedef void (VKAPI_PTR *PFN_vkCmdEndRenderPass2KHR)(VkCommandBuffer commandBuffer, const VkSubpassEndInfoKHR* pSubpassEndInfo); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkCreateRenderPass2KHR( + VkDevice device, + const VkRenderPassCreateInfo2KHR* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkRenderPass* pRenderPass); + +VKAPI_ATTR void VKAPI_CALL vkCmdBeginRenderPass2KHR( + VkCommandBuffer commandBuffer, + const VkRenderPassBeginInfo* pRenderPassBegin, + const VkSubpassBeginInfoKHR* pSubpassBeginInfo); + +VKAPI_ATTR void VKAPI_CALL vkCmdNextSubpass2KHR( + VkCommandBuffer commandBuffer, + const VkSubpassBeginInfoKHR* pSubpassBeginInfo, + const VkSubpassEndInfoKHR* pSubpassEndInfo); + +VKAPI_ATTR void VKAPI_CALL vkCmdEndRenderPass2KHR( + VkCommandBuffer commandBuffer, + const VkSubpassEndInfoKHR* pSubpassEndInfo); +#endif + #define VK_KHR_shared_presentable_image 1 #define VK_KHR_SHARED_PRESENTABLE_IMAGE_SPEC_VERSION 1 #define VK_KHR_SHARED_PRESENTABLE_IMAGE_EXTENSION_NAME "VK_KHR_shared_presentable_image" @@ -5555,6 +5863,70 @@ typedef VkPhysicalDeviceVariablePointerFeatures VkPhysicalDeviceVariablePointerF +#define VK_KHR_get_display_properties2 1 +#define VK_KHR_GET_DISPLAY_PROPERTIES_2_SPEC_VERSION 1 +#define VK_KHR_GET_DISPLAY_PROPERTIES_2_EXTENSION_NAME "VK_KHR_get_display_properties2" + +typedef struct VkDisplayProperties2KHR { + VkStructureType sType; + void* pNext; + VkDisplayPropertiesKHR displayProperties; +} VkDisplayProperties2KHR; + +typedef struct VkDisplayPlaneProperties2KHR { + VkStructureType sType; + void* pNext; + VkDisplayPlanePropertiesKHR displayPlaneProperties; +} VkDisplayPlaneProperties2KHR; + +typedef struct VkDisplayModeProperties2KHR { + VkStructureType sType; + void* pNext; + VkDisplayModePropertiesKHR displayModeProperties; +} VkDisplayModeProperties2KHR; + +typedef struct VkDisplayPlaneInfo2KHR { + VkStructureType sType; + const void* pNext; + VkDisplayModeKHR mode; + uint32_t planeIndex; +} VkDisplayPlaneInfo2KHR; + +typedef struct VkDisplayPlaneCapabilities2KHR { + VkStructureType sType; + void* pNext; + VkDisplayPlaneCapabilitiesKHR capabilities; +} VkDisplayPlaneCapabilities2KHR; + + +typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceDisplayProperties2KHR)(VkPhysicalDevice physicalDevice, uint32_t* pPropertyCount, VkDisplayProperties2KHR* pProperties); +typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceDisplayPlaneProperties2KHR)(VkPhysicalDevice physicalDevice, uint32_t* pPropertyCount, VkDisplayPlaneProperties2KHR* pProperties); +typedef VkResult (VKAPI_PTR *PFN_vkGetDisplayModeProperties2KHR)(VkPhysicalDevice physicalDevice, VkDisplayKHR display, uint32_t* pPropertyCount, VkDisplayModeProperties2KHR* pProperties); +typedef VkResult (VKAPI_PTR *PFN_vkGetDisplayPlaneCapabilities2KHR)(VkPhysicalDevice physicalDevice, const VkDisplayPlaneInfo2KHR* pDisplayPlaneInfo, VkDisplayPlaneCapabilities2KHR* pCapabilities); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceDisplayProperties2KHR( + VkPhysicalDevice physicalDevice, + uint32_t* pPropertyCount, + VkDisplayProperties2KHR* pProperties); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceDisplayPlaneProperties2KHR( + VkPhysicalDevice physicalDevice, + uint32_t* pPropertyCount, + VkDisplayPlaneProperties2KHR* pProperties); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetDisplayModeProperties2KHR( + VkPhysicalDevice physicalDevice, + VkDisplayKHR display, + uint32_t* pPropertyCount, + VkDisplayModeProperties2KHR* pProperties); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetDisplayPlaneCapabilities2KHR( + VkPhysicalDevice physicalDevice, + const VkDisplayPlaneInfo2KHR* pDisplayPlaneInfo, + VkDisplayPlaneCapabilities2KHR* pCapabilities); +#endif + #define VK_KHR_dedicated_allocation 1 #define VK_KHR_DEDICATED_ALLOCATION_SPEC_VERSION 3 #define VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME "VK_KHR_dedicated_allocation" @@ -5585,8 +5957,6 @@ typedef VkImageMemoryRequirementsInfo2 VkImageMemoryRequirementsInfo2KHR; typedef VkImageSparseMemoryRequirementsInfo2 VkImageSparseMemoryRequirementsInfo2KHR; -typedef VkMemoryRequirements2 VkMemoryRequirements2KHR; - typedef VkSparseImageMemoryRequirements2 VkSparseImageMemoryRequirements2KHR; @@ -5710,13 +6080,187 @@ VKAPI_ATTR void VKAPI_CALL vkGetDescriptorSetLayoutSupportKHR( VkDescriptorSetLayoutSupport* pSupport); #endif +#define VK_KHR_draw_indirect_count 1 +#define VK_KHR_DRAW_INDIRECT_COUNT_SPEC_VERSION 1 +#define VK_KHR_DRAW_INDIRECT_COUNT_EXTENSION_NAME "VK_KHR_draw_indirect_count" + +typedef void (VKAPI_PTR *PFN_vkCmdDrawIndirectCountKHR)(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount, uint32_t stride); +typedef void (VKAPI_PTR *PFN_vkCmdDrawIndexedIndirectCountKHR)(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount, uint32_t stride); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkCmdDrawIndirectCountKHR( + VkCommandBuffer commandBuffer, + VkBuffer buffer, + VkDeviceSize offset, + VkBuffer countBuffer, + VkDeviceSize countBufferOffset, + uint32_t maxDrawCount, + uint32_t stride); + +VKAPI_ATTR void VKAPI_CALL vkCmdDrawIndexedIndirectCountKHR( + VkCommandBuffer commandBuffer, + VkBuffer buffer, + VkDeviceSize offset, + VkBuffer countBuffer, + VkDeviceSize countBufferOffset, + uint32_t maxDrawCount, + uint32_t stride); +#endif + +#define VK_KHR_8bit_storage 1 +#define VK_KHR_8BIT_STORAGE_SPEC_VERSION 1 +#define VK_KHR_8BIT_STORAGE_EXTENSION_NAME "VK_KHR_8bit_storage" + +typedef struct VkPhysicalDevice8BitStorageFeaturesKHR { + VkStructureType sType; + void* pNext; + VkBool32 storageBuffer8BitAccess; + VkBool32 uniformAndStorageBuffer8BitAccess; + VkBool32 storagePushConstant8; +} VkPhysicalDevice8BitStorageFeaturesKHR; + + + +#define VK_KHR_shader_atomic_int64 1 +#define VK_KHR_SHADER_ATOMIC_INT64_SPEC_VERSION 1 +#define VK_KHR_SHADER_ATOMIC_INT64_EXTENSION_NAME "VK_KHR_shader_atomic_int64" + +typedef struct VkPhysicalDeviceShaderAtomicInt64FeaturesKHR { + VkStructureType sType; + void* pNext; + VkBool32 shaderBufferInt64Atomics; + VkBool32 shaderSharedInt64Atomics; +} VkPhysicalDeviceShaderAtomicInt64FeaturesKHR; + + + +#define VK_KHR_driver_properties 1 +#define VK_MAX_DRIVER_NAME_SIZE_KHR 256 +#define VK_MAX_DRIVER_INFO_SIZE_KHR 256 +#define VK_KHR_DRIVER_PROPERTIES_SPEC_VERSION 1 +#define VK_KHR_DRIVER_PROPERTIES_EXTENSION_NAME "VK_KHR_driver_properties" + + +typedef enum VkDriverIdKHR { + VK_DRIVER_ID_AMD_PROPRIETARY_KHR = 1, + VK_DRIVER_ID_AMD_OPEN_SOURCE_KHR = 2, + VK_DRIVER_ID_MESA_RADV_KHR = 3, + VK_DRIVER_ID_NVIDIA_PROPRIETARY_KHR = 4, + VK_DRIVER_ID_INTEL_PROPRIETARY_WINDOWS_KHR = 5, + VK_DRIVER_ID_INTEL_OPEN_SOURCE_MESA_KHR = 6, + VK_DRIVER_ID_IMAGINATION_PROPRIETARY_KHR = 7, + VK_DRIVER_ID_QUALCOMM_PROPRIETARY_KHR = 8, + VK_DRIVER_ID_ARM_PROPRIETARY_KHR = 9, + VK_DRIVER_ID_GOOGLE_PASTEL_KHR = 10, + VK_DRIVER_ID_BEGIN_RANGE_KHR = VK_DRIVER_ID_AMD_PROPRIETARY_KHR, + VK_DRIVER_ID_END_RANGE_KHR = VK_DRIVER_ID_GOOGLE_PASTEL_KHR, + VK_DRIVER_ID_RANGE_SIZE_KHR = (VK_DRIVER_ID_GOOGLE_PASTEL_KHR - VK_DRIVER_ID_AMD_PROPRIETARY_KHR + 1), + VK_DRIVER_ID_MAX_ENUM_KHR = 0x7FFFFFFF +} VkDriverIdKHR; + +typedef struct VkConformanceVersionKHR { + uint8_t major; + uint8_t minor; + uint8_t subminor; + uint8_t patch; +} VkConformanceVersionKHR; + +typedef struct VkPhysicalDeviceDriverPropertiesKHR { + VkStructureType sType; + void* pNext; + VkDriverIdKHR driverID; + char driverName[VK_MAX_DRIVER_NAME_SIZE_KHR]; + char driverInfo[VK_MAX_DRIVER_INFO_SIZE_KHR]; + VkConformanceVersionKHR conformanceVersion; +} VkPhysicalDeviceDriverPropertiesKHR; + + + +#define VK_KHR_shader_float_controls 1 +#define VK_KHR_SHADER_FLOAT_CONTROLS_SPEC_VERSION 1 +#define VK_KHR_SHADER_FLOAT_CONTROLS_EXTENSION_NAME "VK_KHR_shader_float_controls" + +typedef struct VkPhysicalDeviceFloatControlsPropertiesKHR { + VkStructureType sType; + void* pNext; + VkBool32 separateDenormSettings; + VkBool32 separateRoundingModeSettings; + VkBool32 shaderSignedZeroInfNanPreserveFloat16; + VkBool32 shaderSignedZeroInfNanPreserveFloat32; + VkBool32 shaderSignedZeroInfNanPreserveFloat64; + VkBool32 shaderDenormPreserveFloat16; + VkBool32 shaderDenormPreserveFloat32; + VkBool32 shaderDenormPreserveFloat64; + VkBool32 shaderDenormFlushToZeroFloat16; + VkBool32 shaderDenormFlushToZeroFloat32; + VkBool32 shaderDenormFlushToZeroFloat64; + VkBool32 shaderRoundingModeRTEFloat16; + VkBool32 shaderRoundingModeRTEFloat32; + VkBool32 shaderRoundingModeRTEFloat64; + VkBool32 shaderRoundingModeRTZFloat16; + VkBool32 shaderRoundingModeRTZFloat32; + VkBool32 shaderRoundingModeRTZFloat64; +} VkPhysicalDeviceFloatControlsPropertiesKHR; + + + +#define VK_KHR_depth_stencil_resolve 1 +#define VK_KHR_DEPTH_STENCIL_RESOLVE_SPEC_VERSION 1 +#define VK_KHR_DEPTH_STENCIL_RESOLVE_EXTENSION_NAME "VK_KHR_depth_stencil_resolve" + + +typedef enum VkResolveModeFlagBitsKHR { + VK_RESOLVE_MODE_NONE_KHR = 0, + VK_RESOLVE_MODE_SAMPLE_ZERO_BIT_KHR = 0x00000001, + VK_RESOLVE_MODE_AVERAGE_BIT_KHR = 0x00000002, + VK_RESOLVE_MODE_MIN_BIT_KHR = 0x00000004, + VK_RESOLVE_MODE_MAX_BIT_KHR = 0x00000008, + VK_RESOLVE_MODE_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF +} VkResolveModeFlagBitsKHR; +typedef VkFlags VkResolveModeFlagsKHR; + +typedef struct VkSubpassDescriptionDepthStencilResolveKHR { + VkStructureType sType; + const void* pNext; + VkResolveModeFlagBitsKHR depthResolveMode; + VkResolveModeFlagBitsKHR stencilResolveMode; + const VkAttachmentReference2KHR* pDepthStencilResolveAttachment; +} VkSubpassDescriptionDepthStencilResolveKHR; + +typedef struct VkPhysicalDeviceDepthStencilResolvePropertiesKHR { + VkStructureType sType; + void* pNext; + VkResolveModeFlagsKHR supportedDepthResolveModes; + VkResolveModeFlagsKHR supportedStencilResolveModes; + VkBool32 independentResolveNone; + VkBool32 independentResolve; +} VkPhysicalDeviceDepthStencilResolvePropertiesKHR; + + + +#define VK_KHR_swapchain_mutable_format 1 +#define VK_KHR_SWAPCHAIN_MUTABLE_FORMAT_SPEC_VERSION 1 +#define VK_KHR_SWAPCHAIN_MUTABLE_FORMAT_EXTENSION_NAME "VK_KHR_swapchain_mutable_format" + + +#define VK_KHR_vulkan_memory_model 1 +#define VK_KHR_VULKAN_MEMORY_MODEL_SPEC_VERSION 2 +#define VK_KHR_VULKAN_MEMORY_MODEL_EXTENSION_NAME "VK_KHR_vulkan_memory_model" + +typedef struct VkPhysicalDeviceVulkanMemoryModelFeaturesKHR { + VkStructureType sType; + void* pNext; + VkBool32 vulkanMemoryModel; + VkBool32 vulkanMemoryModelDeviceScope; +} VkPhysicalDeviceVulkanMemoryModelFeaturesKHR; + + + #define VK_EXT_debug_report 1 VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDebugReportCallbackEXT) #define VK_EXT_DEBUG_REPORT_SPEC_VERSION 9 #define VK_EXT_DEBUG_REPORT_EXTENSION_NAME "VK_EXT_debug_report" -#define VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT -#define VK_DEBUG_REPORT_OBJECT_TYPE_DEBUG_REPORT_EXT VK_DEBUG_REPORT_OBJECT_TYPE_DEBUG_REPORT_CALLBACK_EXT_EXT typedef enum VkDebugReportObjectTypeEXT { @@ -5756,6 +6300,9 @@ typedef enum VkDebugReportObjectTypeEXT { VK_DEBUG_REPORT_OBJECT_TYPE_VALIDATION_CACHE_EXT_EXT = 33, VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION_EXT = 1000156000, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_EXT = 1000085000, + VK_DEBUG_REPORT_OBJECT_TYPE_ACCELERATION_STRUCTURE_NV_EXT = 1000165000, + VK_DEBUG_REPORT_OBJECT_TYPE_DEBUG_REPORT_EXT = VK_DEBUG_REPORT_OBJECT_TYPE_DEBUG_REPORT_CALLBACK_EXT_EXT, + VK_DEBUG_REPORT_OBJECT_TYPE_VALIDATION_CACHE_EXT = VK_DEBUG_REPORT_OBJECT_TYPE_VALIDATION_CACHE_EXT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_KHR_EXT = VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION_KHR_EXT = VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_BEGIN_RANGE_EXT = VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, @@ -5955,6 +6502,95 @@ typedef struct VkDedicatedAllocationMemoryAllocateInfoNV { +#define VK_EXT_transform_feedback 1 +#define VK_EXT_TRANSFORM_FEEDBACK_SPEC_VERSION 1 +#define VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME "VK_EXT_transform_feedback" + +typedef VkFlags VkPipelineRasterizationStateStreamCreateFlagsEXT; + +typedef struct VkPhysicalDeviceTransformFeedbackFeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 transformFeedback; + VkBool32 geometryStreams; +} VkPhysicalDeviceTransformFeedbackFeaturesEXT; + +typedef struct VkPhysicalDeviceTransformFeedbackPropertiesEXT { + VkStructureType sType; + void* pNext; + uint32_t maxTransformFeedbackStreams; + uint32_t maxTransformFeedbackBuffers; + VkDeviceSize maxTransformFeedbackBufferSize; + uint32_t maxTransformFeedbackStreamDataSize; + uint32_t maxTransformFeedbackBufferDataSize; + uint32_t maxTransformFeedbackBufferDataStride; + VkBool32 transformFeedbackQueries; + VkBool32 transformFeedbackStreamsLinesTriangles; + VkBool32 transformFeedbackRasterizationStreamSelect; + VkBool32 transformFeedbackDraw; +} VkPhysicalDeviceTransformFeedbackPropertiesEXT; + +typedef struct VkPipelineRasterizationStateStreamCreateInfoEXT { + VkStructureType sType; + const void* pNext; + VkPipelineRasterizationStateStreamCreateFlagsEXT flags; + uint32_t rasterizationStream; +} VkPipelineRasterizationStateStreamCreateInfoEXT; + + +typedef void (VKAPI_PTR *PFN_vkCmdBindTransformFeedbackBuffersEXT)(VkCommandBuffer commandBuffer, uint32_t firstBinding, uint32_t bindingCount, const VkBuffer* pBuffers, const VkDeviceSize* pOffsets, const VkDeviceSize* pSizes); +typedef void (VKAPI_PTR *PFN_vkCmdBeginTransformFeedbackEXT)(VkCommandBuffer commandBuffer, uint32_t firstCounterBuffer, uint32_t counterBufferCount, const VkBuffer* pCounterBuffers, const VkDeviceSize* pCounterBufferOffsets); +typedef void (VKAPI_PTR *PFN_vkCmdEndTransformFeedbackEXT)(VkCommandBuffer commandBuffer, uint32_t firstCounterBuffer, uint32_t counterBufferCount, const VkBuffer* pCounterBuffers, const VkDeviceSize* pCounterBufferOffsets); +typedef void (VKAPI_PTR *PFN_vkCmdBeginQueryIndexedEXT)(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t query, VkQueryControlFlags flags, uint32_t index); +typedef void (VKAPI_PTR *PFN_vkCmdEndQueryIndexedEXT)(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t query, uint32_t index); +typedef void (VKAPI_PTR *PFN_vkCmdDrawIndirectByteCountEXT)(VkCommandBuffer commandBuffer, uint32_t instanceCount, uint32_t firstInstance, VkBuffer counterBuffer, VkDeviceSize counterBufferOffset, uint32_t counterOffset, uint32_t vertexStride); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkCmdBindTransformFeedbackBuffersEXT( + VkCommandBuffer commandBuffer, + uint32_t firstBinding, + uint32_t bindingCount, + const VkBuffer* pBuffers, + const VkDeviceSize* pOffsets, + const VkDeviceSize* pSizes); + +VKAPI_ATTR void VKAPI_CALL vkCmdBeginTransformFeedbackEXT( + VkCommandBuffer commandBuffer, + uint32_t firstCounterBuffer, + uint32_t counterBufferCount, + const VkBuffer* pCounterBuffers, + const VkDeviceSize* pCounterBufferOffsets); + +VKAPI_ATTR void VKAPI_CALL vkCmdEndTransformFeedbackEXT( + VkCommandBuffer commandBuffer, + uint32_t firstCounterBuffer, + uint32_t counterBufferCount, + const VkBuffer* pCounterBuffers, + const VkDeviceSize* pCounterBufferOffsets); + +VKAPI_ATTR void VKAPI_CALL vkCmdBeginQueryIndexedEXT( + VkCommandBuffer commandBuffer, + VkQueryPool queryPool, + uint32_t query, + VkQueryControlFlags flags, + uint32_t index); + +VKAPI_ATTR void VKAPI_CALL vkCmdEndQueryIndexedEXT( + VkCommandBuffer commandBuffer, + VkQueryPool queryPool, + uint32_t query, + uint32_t index); + +VKAPI_ATTR void VKAPI_CALL vkCmdDrawIndirectByteCountEXT( + VkCommandBuffer commandBuffer, + uint32_t instanceCount, + uint32_t firstInstance, + VkBuffer counterBuffer, + VkDeviceSize counterBufferOffset, + uint32_t counterOffset, + uint32_t vertexStride); +#endif + #define VK_AMD_draw_indirect_count 1 #define VK_AMD_DRAW_INDIRECT_COUNT_SPEC_VERSION 1 #define VK_AMD_DRAW_INDIRECT_COUNT_EXTENSION_NAME "VK_AMD_draw_indirect_count" @@ -6060,6 +6696,18 @@ VKAPI_ATTR VkResult VKAPI_CALL vkGetShaderInfoAMD( #define VK_AMD_SHADER_IMAGE_LOAD_STORE_LOD_EXTENSION_NAME "VK_AMD_shader_image_load_store_lod" +#define VK_NV_corner_sampled_image 1 +#define VK_NV_CORNER_SAMPLED_IMAGE_SPEC_VERSION 2 +#define VK_NV_CORNER_SAMPLED_IMAGE_EXTENSION_NAME "VK_NV_corner_sampled_image" + +typedef struct VkPhysicalDeviceCornerSampledImageFeaturesNV { + VkStructureType sType; + void* pNext; + VkBool32 cornerSampledImage; +} VkPhysicalDeviceCornerSampledImageFeaturesNV; + + + #define VK_IMG_format_pvrtc 1 #define VK_IMG_FORMAT_PVRTC_SPEC_VERSION 1 #define VK_IMG_FORMAT_PVRTC_EXTENSION_NAME "VK_IMG_format_pvrtc" @@ -6142,10 +6790,10 @@ typedef enum VkValidationCheckEXT { } VkValidationCheckEXT; typedef struct VkValidationFlagsEXT { - VkStructureType sType; - const void* pNext; - uint32_t disabledValidationCheckCount; - VkValidationCheckEXT* pDisabledValidationChecks; + VkStructureType sType; + const void* pNext; + uint32_t disabledValidationCheckCount; + const VkValidationCheckEXT* pDisabledValidationChecks; } VkValidationFlagsEXT; @@ -6160,6 +6808,69 @@ typedef struct VkValidationFlagsEXT { #define VK_EXT_SHADER_SUBGROUP_VOTE_EXTENSION_NAME "VK_EXT_shader_subgroup_vote" +#define VK_EXT_astc_decode_mode 1 +#define VK_EXT_ASTC_DECODE_MODE_SPEC_VERSION 1 +#define VK_EXT_ASTC_DECODE_MODE_EXTENSION_NAME "VK_EXT_astc_decode_mode" + +typedef struct VkImageViewASTCDecodeModeEXT { + VkStructureType sType; + const void* pNext; + VkFormat decodeMode; +} VkImageViewASTCDecodeModeEXT; + +typedef struct VkPhysicalDeviceASTCDecodeFeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 decodeModeSharedExponent; +} VkPhysicalDeviceASTCDecodeFeaturesEXT; + + + +#define VK_EXT_conditional_rendering 1 +#define VK_EXT_CONDITIONAL_RENDERING_SPEC_VERSION 1 +#define VK_EXT_CONDITIONAL_RENDERING_EXTENSION_NAME "VK_EXT_conditional_rendering" + + +typedef enum VkConditionalRenderingFlagBitsEXT { + VK_CONDITIONAL_RENDERING_INVERTED_BIT_EXT = 0x00000001, + VK_CONDITIONAL_RENDERING_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF +} VkConditionalRenderingFlagBitsEXT; +typedef VkFlags VkConditionalRenderingFlagsEXT; + +typedef struct VkConditionalRenderingBeginInfoEXT { + VkStructureType sType; + const void* pNext; + VkBuffer buffer; + VkDeviceSize offset; + VkConditionalRenderingFlagsEXT flags; +} VkConditionalRenderingBeginInfoEXT; + +typedef struct VkPhysicalDeviceConditionalRenderingFeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 conditionalRendering; + VkBool32 inheritedConditionalRendering; +} VkPhysicalDeviceConditionalRenderingFeaturesEXT; + +typedef struct VkCommandBufferInheritanceConditionalRenderingInfoEXT { + VkStructureType sType; + const void* pNext; + VkBool32 conditionalRenderingEnable; +} VkCommandBufferInheritanceConditionalRenderingInfoEXT; + + +typedef void (VKAPI_PTR *PFN_vkCmdBeginConditionalRenderingEXT)(VkCommandBuffer commandBuffer, const VkConditionalRenderingBeginInfoEXT* pConditionalRenderingBegin); +typedef void (VKAPI_PTR *PFN_vkCmdEndConditionalRenderingEXT)(VkCommandBuffer commandBuffer); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkCmdBeginConditionalRenderingEXT( + VkCommandBuffer commandBuffer, + const VkConditionalRenderingBeginInfoEXT* pConditionalRenderingBegin); + +VKAPI_ATTR void VKAPI_CALL vkCmdEndConditionalRenderingEXT( + VkCommandBuffer commandBuffer); +#endif + #define VK_NVX_device_generated_commands 1 VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkObjectTableNVX) VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkIndirectCommandsLayoutNVX) @@ -6430,7 +7141,6 @@ VKAPI_ATTR VkResult VKAPI_CALL vkReleaseDisplayEXT( #define VK_EXT_display_surface_counter 1 #define VK_EXT_DISPLAY_SURFACE_COUNTER_SPEC_VERSION 1 #define VK_EXT_DISPLAY_SURFACE_COUNTER_EXTENSION_NAME "VK_EXT_display_surface_counter" -#define VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES2_EXT VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_2_EXT typedef enum VkSurfaceCounterFlagBitsEXT { @@ -6854,16 +7564,16 @@ typedef struct VkDebugUtilsMessengerCallbackDataEXT { int32_t messageIdNumber; const char* pMessage; uint32_t queueLabelCount; - VkDebugUtilsLabelEXT* pQueueLabels; + const VkDebugUtilsLabelEXT* pQueueLabels; uint32_t cmdBufLabelCount; - VkDebugUtilsLabelEXT* pCmdBufLabels; + const VkDebugUtilsLabelEXT* pCmdBufLabels; uint32_t objectCount; - VkDebugUtilsObjectNameInfoEXT* pObjects; + const VkDebugUtilsObjectNameInfoEXT* pObjects; } VkDebugUtilsMessengerCallbackDataEXT; typedef VkBool32 (VKAPI_PTR *PFN_vkDebugUtilsMessengerCallbackEXT)( VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity, - VkDebugUtilsMessageTypeFlagsEXT messageType, + VkDebugUtilsMessageTypeFlagsEXT messageTypes, const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData, void* pUserData); @@ -6984,6 +7694,42 @@ typedef struct VkPhysicalDeviceSamplerFilterMinmaxPropertiesEXT { #define VK_AMD_SHADER_FRAGMENT_MASK_EXTENSION_NAME "VK_AMD_shader_fragment_mask" +#define VK_EXT_inline_uniform_block 1 +#define VK_EXT_INLINE_UNIFORM_BLOCK_SPEC_VERSION 1 +#define VK_EXT_INLINE_UNIFORM_BLOCK_EXTENSION_NAME "VK_EXT_inline_uniform_block" + +typedef struct VkPhysicalDeviceInlineUniformBlockFeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 inlineUniformBlock; + VkBool32 descriptorBindingInlineUniformBlockUpdateAfterBind; +} VkPhysicalDeviceInlineUniformBlockFeaturesEXT; + +typedef struct VkPhysicalDeviceInlineUniformBlockPropertiesEXT { + VkStructureType sType; + void* pNext; + uint32_t maxInlineUniformBlockSize; + uint32_t maxPerStageDescriptorInlineUniformBlocks; + uint32_t maxPerStageDescriptorUpdateAfterBindInlineUniformBlocks; + uint32_t maxDescriptorSetInlineUniformBlocks; + uint32_t maxDescriptorSetUpdateAfterBindInlineUniformBlocks; +} VkPhysicalDeviceInlineUniformBlockPropertiesEXT; + +typedef struct VkWriteDescriptorSetInlineUniformBlockEXT { + VkStructureType sType; + const void* pNext; + uint32_t dataSize; + const void* pData; +} VkWriteDescriptorSetInlineUniformBlockEXT; + +typedef struct VkDescriptorPoolInlineUniformBlockCreateInfoEXT { + VkStructureType sType; + const void* pNext; + uint32_t maxInlineUniformBlockBindings; +} VkDescriptorPoolInlineUniformBlockCreateInfoEXT; + + + #define VK_EXT_shader_stencil_export 1 #define VK_EXT_SHADER_STENCIL_EXPORT_SPEC_VERSION 1 #define VK_EXT_SHADER_STENCIL_EXPORT_EXTENSION_NAME "VK_EXT_shader_stencil_export" @@ -7162,12 +7908,68 @@ typedef struct VkPipelineCoverageModulationStateCreateInfoNV { #define VK_EXT_POST_DEPTH_COVERAGE_EXTENSION_NAME "VK_EXT_post_depth_coverage" +#define VK_EXT_image_drm_format_modifier 1 +#define VK_EXT_IMAGE_DRM_FORMAT_MODIFIER_SPEC_VERSION 1 +#define VK_EXT_IMAGE_DRM_FORMAT_MODIFIER_EXTENSION_NAME "VK_EXT_image_drm_format_modifier" + +typedef struct VkDrmFormatModifierPropertiesEXT { + uint64_t drmFormatModifier; + uint32_t drmFormatModifierPlaneCount; + VkFormatFeatureFlags drmFormatModifierTilingFeatures; +} VkDrmFormatModifierPropertiesEXT; + +typedef struct VkDrmFormatModifierPropertiesListEXT { + VkStructureType sType; + void* pNext; + uint32_t drmFormatModifierCount; + VkDrmFormatModifierPropertiesEXT* pDrmFormatModifierProperties; +} VkDrmFormatModifierPropertiesListEXT; + +typedef struct VkPhysicalDeviceImageDrmFormatModifierInfoEXT { + VkStructureType sType; + const void* pNext; + uint64_t drmFormatModifier; + VkSharingMode sharingMode; + uint32_t queueFamilyIndexCount; + const uint32_t* pQueueFamilyIndices; +} VkPhysicalDeviceImageDrmFormatModifierInfoEXT; + +typedef struct VkImageDrmFormatModifierListCreateInfoEXT { + VkStructureType sType; + const void* pNext; + uint32_t drmFormatModifierCount; + const uint64_t* pDrmFormatModifiers; +} VkImageDrmFormatModifierListCreateInfoEXT; + +typedef struct VkImageDrmFormatModifierExplicitCreateInfoEXT { + VkStructureType sType; + const void* pNext; + uint64_t drmFormatModifier; + uint32_t drmFormatModifierPlaneCount; + const VkSubresourceLayout* pPlaneLayouts; +} VkImageDrmFormatModifierExplicitCreateInfoEXT; + +typedef struct VkImageDrmFormatModifierPropertiesEXT { + VkStructureType sType; + void* pNext; + uint64_t drmFormatModifier; +} VkImageDrmFormatModifierPropertiesEXT; + + +typedef VkResult (VKAPI_PTR *PFN_vkGetImageDrmFormatModifierPropertiesEXT)(VkDevice device, VkImage image, VkImageDrmFormatModifierPropertiesEXT* pProperties); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkGetImageDrmFormatModifierPropertiesEXT( + VkDevice device, + VkImage image, + VkImageDrmFormatModifierPropertiesEXT* pProperties); +#endif + #define VK_EXT_validation_cache 1 VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkValidationCacheEXT) #define VK_EXT_VALIDATION_CACHE_SPEC_VERSION 1 #define VK_EXT_VALIDATION_CACHE_EXTENSION_NAME "VK_EXT_validation_cache" -#define VK_DEBUG_REPORT_OBJECT_TYPE_VALIDATION_CACHE_EXT VK_DEBUG_REPORT_OBJECT_TYPE_VALIDATION_CACHE_EXT_EXT typedef enum VkValidationCacheHeaderVersionEXT { @@ -7225,11 +8027,530 @@ VKAPI_ATTR VkResult VKAPI_CALL vkGetValidationCacheDataEXT( void* pData); #endif +#define VK_EXT_descriptor_indexing 1 +#define VK_EXT_DESCRIPTOR_INDEXING_SPEC_VERSION 2 +#define VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME "VK_EXT_descriptor_indexing" + + +typedef enum VkDescriptorBindingFlagBitsEXT { + VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT_EXT = 0x00000001, + VK_DESCRIPTOR_BINDING_UPDATE_UNUSED_WHILE_PENDING_BIT_EXT = 0x00000002, + VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT_EXT = 0x00000004, + VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT_EXT = 0x00000008, + VK_DESCRIPTOR_BINDING_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF +} VkDescriptorBindingFlagBitsEXT; +typedef VkFlags VkDescriptorBindingFlagsEXT; + +typedef struct VkDescriptorSetLayoutBindingFlagsCreateInfoEXT { + VkStructureType sType; + const void* pNext; + uint32_t bindingCount; + const VkDescriptorBindingFlagsEXT* pBindingFlags; +} VkDescriptorSetLayoutBindingFlagsCreateInfoEXT; + +typedef struct VkPhysicalDeviceDescriptorIndexingFeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 shaderInputAttachmentArrayDynamicIndexing; + VkBool32 shaderUniformTexelBufferArrayDynamicIndexing; + VkBool32 shaderStorageTexelBufferArrayDynamicIndexing; + VkBool32 shaderUniformBufferArrayNonUniformIndexing; + VkBool32 shaderSampledImageArrayNonUniformIndexing; + VkBool32 shaderStorageBufferArrayNonUniformIndexing; + VkBool32 shaderStorageImageArrayNonUniformIndexing; + VkBool32 shaderInputAttachmentArrayNonUniformIndexing; + VkBool32 shaderUniformTexelBufferArrayNonUniformIndexing; + VkBool32 shaderStorageTexelBufferArrayNonUniformIndexing; + VkBool32 descriptorBindingUniformBufferUpdateAfterBind; + VkBool32 descriptorBindingSampledImageUpdateAfterBind; + VkBool32 descriptorBindingStorageImageUpdateAfterBind; + VkBool32 descriptorBindingStorageBufferUpdateAfterBind; + VkBool32 descriptorBindingUniformTexelBufferUpdateAfterBind; + VkBool32 descriptorBindingStorageTexelBufferUpdateAfterBind; + VkBool32 descriptorBindingUpdateUnusedWhilePending; + VkBool32 descriptorBindingPartiallyBound; + VkBool32 descriptorBindingVariableDescriptorCount; + VkBool32 runtimeDescriptorArray; +} VkPhysicalDeviceDescriptorIndexingFeaturesEXT; + +typedef struct VkPhysicalDeviceDescriptorIndexingPropertiesEXT { + VkStructureType sType; + void* pNext; + uint32_t maxUpdateAfterBindDescriptorsInAllPools; + VkBool32 shaderUniformBufferArrayNonUniformIndexingNative; + VkBool32 shaderSampledImageArrayNonUniformIndexingNative; + VkBool32 shaderStorageBufferArrayNonUniformIndexingNative; + VkBool32 shaderStorageImageArrayNonUniformIndexingNative; + VkBool32 shaderInputAttachmentArrayNonUniformIndexingNative; + VkBool32 robustBufferAccessUpdateAfterBind; + VkBool32 quadDivergentImplicitLod; + uint32_t maxPerStageDescriptorUpdateAfterBindSamplers; + uint32_t maxPerStageDescriptorUpdateAfterBindUniformBuffers; + uint32_t maxPerStageDescriptorUpdateAfterBindStorageBuffers; + uint32_t maxPerStageDescriptorUpdateAfterBindSampledImages; + uint32_t maxPerStageDescriptorUpdateAfterBindStorageImages; + uint32_t maxPerStageDescriptorUpdateAfterBindInputAttachments; + uint32_t maxPerStageUpdateAfterBindResources; + uint32_t maxDescriptorSetUpdateAfterBindSamplers; + uint32_t maxDescriptorSetUpdateAfterBindUniformBuffers; + uint32_t maxDescriptorSetUpdateAfterBindUniformBuffersDynamic; + uint32_t maxDescriptorSetUpdateAfterBindStorageBuffers; + uint32_t maxDescriptorSetUpdateAfterBindStorageBuffersDynamic; + uint32_t maxDescriptorSetUpdateAfterBindSampledImages; + uint32_t maxDescriptorSetUpdateAfterBindStorageImages; + uint32_t maxDescriptorSetUpdateAfterBindInputAttachments; +} VkPhysicalDeviceDescriptorIndexingPropertiesEXT; + +typedef struct VkDescriptorSetVariableDescriptorCountAllocateInfoEXT { + VkStructureType sType; + const void* pNext; + uint32_t descriptorSetCount; + const uint32_t* pDescriptorCounts; +} VkDescriptorSetVariableDescriptorCountAllocateInfoEXT; + +typedef struct VkDescriptorSetVariableDescriptorCountLayoutSupportEXT { + VkStructureType sType; + void* pNext; + uint32_t maxVariableDescriptorCount; +} VkDescriptorSetVariableDescriptorCountLayoutSupportEXT; + + + #define VK_EXT_shader_viewport_index_layer 1 #define VK_EXT_SHADER_VIEWPORT_INDEX_LAYER_SPEC_VERSION 1 #define VK_EXT_SHADER_VIEWPORT_INDEX_LAYER_EXTENSION_NAME "VK_EXT_shader_viewport_index_layer" +#define VK_NV_shading_rate_image 1 +#define VK_NV_SHADING_RATE_IMAGE_SPEC_VERSION 3 +#define VK_NV_SHADING_RATE_IMAGE_EXTENSION_NAME "VK_NV_shading_rate_image" + + +typedef enum VkShadingRatePaletteEntryNV { + VK_SHADING_RATE_PALETTE_ENTRY_NO_INVOCATIONS_NV = 0, + VK_SHADING_RATE_PALETTE_ENTRY_16_INVOCATIONS_PER_PIXEL_NV = 1, + VK_SHADING_RATE_PALETTE_ENTRY_8_INVOCATIONS_PER_PIXEL_NV = 2, + VK_SHADING_RATE_PALETTE_ENTRY_4_INVOCATIONS_PER_PIXEL_NV = 3, + VK_SHADING_RATE_PALETTE_ENTRY_2_INVOCATIONS_PER_PIXEL_NV = 4, + VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_PIXEL_NV = 5, + VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_2X1_PIXELS_NV = 6, + VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_1X2_PIXELS_NV = 7, + VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_2X2_PIXELS_NV = 8, + VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_4X2_PIXELS_NV = 9, + VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_2X4_PIXELS_NV = 10, + VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_4X4_PIXELS_NV = 11, + VK_SHADING_RATE_PALETTE_ENTRY_BEGIN_RANGE_NV = VK_SHADING_RATE_PALETTE_ENTRY_NO_INVOCATIONS_NV, + VK_SHADING_RATE_PALETTE_ENTRY_END_RANGE_NV = VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_4X4_PIXELS_NV, + VK_SHADING_RATE_PALETTE_ENTRY_RANGE_SIZE_NV = (VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_4X4_PIXELS_NV - VK_SHADING_RATE_PALETTE_ENTRY_NO_INVOCATIONS_NV + 1), + VK_SHADING_RATE_PALETTE_ENTRY_MAX_ENUM_NV = 0x7FFFFFFF +} VkShadingRatePaletteEntryNV; + +typedef enum VkCoarseSampleOrderTypeNV { + VK_COARSE_SAMPLE_ORDER_TYPE_DEFAULT_NV = 0, + VK_COARSE_SAMPLE_ORDER_TYPE_CUSTOM_NV = 1, + VK_COARSE_SAMPLE_ORDER_TYPE_PIXEL_MAJOR_NV = 2, + VK_COARSE_SAMPLE_ORDER_TYPE_SAMPLE_MAJOR_NV = 3, + VK_COARSE_SAMPLE_ORDER_TYPE_BEGIN_RANGE_NV = VK_COARSE_SAMPLE_ORDER_TYPE_DEFAULT_NV, + VK_COARSE_SAMPLE_ORDER_TYPE_END_RANGE_NV = VK_COARSE_SAMPLE_ORDER_TYPE_SAMPLE_MAJOR_NV, + VK_COARSE_SAMPLE_ORDER_TYPE_RANGE_SIZE_NV = (VK_COARSE_SAMPLE_ORDER_TYPE_SAMPLE_MAJOR_NV - VK_COARSE_SAMPLE_ORDER_TYPE_DEFAULT_NV + 1), + VK_COARSE_SAMPLE_ORDER_TYPE_MAX_ENUM_NV = 0x7FFFFFFF +} VkCoarseSampleOrderTypeNV; + +typedef struct VkShadingRatePaletteNV { + uint32_t shadingRatePaletteEntryCount; + const VkShadingRatePaletteEntryNV* pShadingRatePaletteEntries; +} VkShadingRatePaletteNV; + +typedef struct VkPipelineViewportShadingRateImageStateCreateInfoNV { + VkStructureType sType; + const void* pNext; + VkBool32 shadingRateImageEnable; + uint32_t viewportCount; + const VkShadingRatePaletteNV* pShadingRatePalettes; +} VkPipelineViewportShadingRateImageStateCreateInfoNV; + +typedef struct VkPhysicalDeviceShadingRateImageFeaturesNV { + VkStructureType sType; + void* pNext; + VkBool32 shadingRateImage; + VkBool32 shadingRateCoarseSampleOrder; +} VkPhysicalDeviceShadingRateImageFeaturesNV; + +typedef struct VkPhysicalDeviceShadingRateImagePropertiesNV { + VkStructureType sType; + void* pNext; + VkExtent2D shadingRateTexelSize; + uint32_t shadingRatePaletteSize; + uint32_t shadingRateMaxCoarseSamples; +} VkPhysicalDeviceShadingRateImagePropertiesNV; + +typedef struct VkCoarseSampleLocationNV { + uint32_t pixelX; + uint32_t pixelY; + uint32_t sample; +} VkCoarseSampleLocationNV; + +typedef struct VkCoarseSampleOrderCustomNV { + VkShadingRatePaletteEntryNV shadingRate; + uint32_t sampleCount; + uint32_t sampleLocationCount; + const VkCoarseSampleLocationNV* pSampleLocations; +} VkCoarseSampleOrderCustomNV; + +typedef struct VkPipelineViewportCoarseSampleOrderStateCreateInfoNV { + VkStructureType sType; + const void* pNext; + VkCoarseSampleOrderTypeNV sampleOrderType; + uint32_t customSampleOrderCount; + const VkCoarseSampleOrderCustomNV* pCustomSampleOrders; +} VkPipelineViewportCoarseSampleOrderStateCreateInfoNV; + + +typedef void (VKAPI_PTR *PFN_vkCmdBindShadingRateImageNV)(VkCommandBuffer commandBuffer, VkImageView imageView, VkImageLayout imageLayout); +typedef void (VKAPI_PTR *PFN_vkCmdSetViewportShadingRatePaletteNV)(VkCommandBuffer commandBuffer, uint32_t firstViewport, uint32_t viewportCount, const VkShadingRatePaletteNV* pShadingRatePalettes); +typedef void (VKAPI_PTR *PFN_vkCmdSetCoarseSampleOrderNV)(VkCommandBuffer commandBuffer, VkCoarseSampleOrderTypeNV sampleOrderType, uint32_t customSampleOrderCount, const VkCoarseSampleOrderCustomNV* pCustomSampleOrders); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkCmdBindShadingRateImageNV( + VkCommandBuffer commandBuffer, + VkImageView imageView, + VkImageLayout imageLayout); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetViewportShadingRatePaletteNV( + VkCommandBuffer commandBuffer, + uint32_t firstViewport, + uint32_t viewportCount, + const VkShadingRatePaletteNV* pShadingRatePalettes); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetCoarseSampleOrderNV( + VkCommandBuffer commandBuffer, + VkCoarseSampleOrderTypeNV sampleOrderType, + uint32_t customSampleOrderCount, + const VkCoarseSampleOrderCustomNV* pCustomSampleOrders); +#endif + +#define VK_NV_ray_tracing 1 +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkAccelerationStructureNV) + +#define VK_NV_RAY_TRACING_SPEC_VERSION 3 +#define VK_NV_RAY_TRACING_EXTENSION_NAME "VK_NV_ray_tracing" +#define VK_SHADER_UNUSED_NV (~0U) + + +typedef enum VkRayTracingShaderGroupTypeNV { + VK_RAY_TRACING_SHADER_GROUP_TYPE_GENERAL_NV = 0, + VK_RAY_TRACING_SHADER_GROUP_TYPE_TRIANGLES_HIT_GROUP_NV = 1, + VK_RAY_TRACING_SHADER_GROUP_TYPE_PROCEDURAL_HIT_GROUP_NV = 2, + VK_RAY_TRACING_SHADER_GROUP_TYPE_BEGIN_RANGE_NV = VK_RAY_TRACING_SHADER_GROUP_TYPE_GENERAL_NV, + VK_RAY_TRACING_SHADER_GROUP_TYPE_END_RANGE_NV = VK_RAY_TRACING_SHADER_GROUP_TYPE_PROCEDURAL_HIT_GROUP_NV, + VK_RAY_TRACING_SHADER_GROUP_TYPE_RANGE_SIZE_NV = (VK_RAY_TRACING_SHADER_GROUP_TYPE_PROCEDURAL_HIT_GROUP_NV - VK_RAY_TRACING_SHADER_GROUP_TYPE_GENERAL_NV + 1), + VK_RAY_TRACING_SHADER_GROUP_TYPE_MAX_ENUM_NV = 0x7FFFFFFF +} VkRayTracingShaderGroupTypeNV; + +typedef enum VkGeometryTypeNV { + VK_GEOMETRY_TYPE_TRIANGLES_NV = 0, + VK_GEOMETRY_TYPE_AABBS_NV = 1, + VK_GEOMETRY_TYPE_BEGIN_RANGE_NV = VK_GEOMETRY_TYPE_TRIANGLES_NV, + VK_GEOMETRY_TYPE_END_RANGE_NV = VK_GEOMETRY_TYPE_AABBS_NV, + VK_GEOMETRY_TYPE_RANGE_SIZE_NV = (VK_GEOMETRY_TYPE_AABBS_NV - VK_GEOMETRY_TYPE_TRIANGLES_NV + 1), + VK_GEOMETRY_TYPE_MAX_ENUM_NV = 0x7FFFFFFF +} VkGeometryTypeNV; + +typedef enum VkAccelerationStructureTypeNV { + VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_NV = 0, + VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_NV = 1, + VK_ACCELERATION_STRUCTURE_TYPE_BEGIN_RANGE_NV = VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_NV, + VK_ACCELERATION_STRUCTURE_TYPE_END_RANGE_NV = VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_NV, + VK_ACCELERATION_STRUCTURE_TYPE_RANGE_SIZE_NV = (VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_NV - VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_NV + 1), + VK_ACCELERATION_STRUCTURE_TYPE_MAX_ENUM_NV = 0x7FFFFFFF +} VkAccelerationStructureTypeNV; + +typedef enum VkCopyAccelerationStructureModeNV { + VK_COPY_ACCELERATION_STRUCTURE_MODE_CLONE_NV = 0, + VK_COPY_ACCELERATION_STRUCTURE_MODE_COMPACT_NV = 1, + VK_COPY_ACCELERATION_STRUCTURE_MODE_BEGIN_RANGE_NV = VK_COPY_ACCELERATION_STRUCTURE_MODE_CLONE_NV, + VK_COPY_ACCELERATION_STRUCTURE_MODE_END_RANGE_NV = VK_COPY_ACCELERATION_STRUCTURE_MODE_COMPACT_NV, + VK_COPY_ACCELERATION_STRUCTURE_MODE_RANGE_SIZE_NV = (VK_COPY_ACCELERATION_STRUCTURE_MODE_COMPACT_NV - VK_COPY_ACCELERATION_STRUCTURE_MODE_CLONE_NV + 1), + VK_COPY_ACCELERATION_STRUCTURE_MODE_MAX_ENUM_NV = 0x7FFFFFFF +} VkCopyAccelerationStructureModeNV; + +typedef enum VkAccelerationStructureMemoryRequirementsTypeNV { + VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_OBJECT_NV = 0, + VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_BUILD_SCRATCH_NV = 1, + VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_UPDATE_SCRATCH_NV = 2, + VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_BEGIN_RANGE_NV = VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_OBJECT_NV, + VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_END_RANGE_NV = VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_UPDATE_SCRATCH_NV, + VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_RANGE_SIZE_NV = (VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_UPDATE_SCRATCH_NV - VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_OBJECT_NV + 1), + VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_MAX_ENUM_NV = 0x7FFFFFFF +} VkAccelerationStructureMemoryRequirementsTypeNV; + + +typedef enum VkGeometryFlagBitsNV { + VK_GEOMETRY_OPAQUE_BIT_NV = 0x00000001, + VK_GEOMETRY_NO_DUPLICATE_ANY_HIT_INVOCATION_BIT_NV = 0x00000002, + VK_GEOMETRY_FLAG_BITS_MAX_ENUM_NV = 0x7FFFFFFF +} VkGeometryFlagBitsNV; +typedef VkFlags VkGeometryFlagsNV; + +typedef enum VkGeometryInstanceFlagBitsNV { + VK_GEOMETRY_INSTANCE_TRIANGLE_CULL_DISABLE_BIT_NV = 0x00000001, + VK_GEOMETRY_INSTANCE_TRIANGLE_FRONT_COUNTERCLOCKWISE_BIT_NV = 0x00000002, + VK_GEOMETRY_INSTANCE_FORCE_OPAQUE_BIT_NV = 0x00000004, + VK_GEOMETRY_INSTANCE_FORCE_NO_OPAQUE_BIT_NV = 0x00000008, + VK_GEOMETRY_INSTANCE_FLAG_BITS_MAX_ENUM_NV = 0x7FFFFFFF +} VkGeometryInstanceFlagBitsNV; +typedef VkFlags VkGeometryInstanceFlagsNV; + +typedef enum VkBuildAccelerationStructureFlagBitsNV { + VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_UPDATE_BIT_NV = 0x00000001, + VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_COMPACTION_BIT_NV = 0x00000002, + VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_TRACE_BIT_NV = 0x00000004, + VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_BUILD_BIT_NV = 0x00000008, + VK_BUILD_ACCELERATION_STRUCTURE_LOW_MEMORY_BIT_NV = 0x00000010, + VK_BUILD_ACCELERATION_STRUCTURE_FLAG_BITS_MAX_ENUM_NV = 0x7FFFFFFF +} VkBuildAccelerationStructureFlagBitsNV; +typedef VkFlags VkBuildAccelerationStructureFlagsNV; + +typedef struct VkRayTracingShaderGroupCreateInfoNV { + VkStructureType sType; + const void* pNext; + VkRayTracingShaderGroupTypeNV type; + uint32_t generalShader; + uint32_t closestHitShader; + uint32_t anyHitShader; + uint32_t intersectionShader; +} VkRayTracingShaderGroupCreateInfoNV; + +typedef struct VkRayTracingPipelineCreateInfoNV { + VkStructureType sType; + const void* pNext; + VkPipelineCreateFlags flags; + uint32_t stageCount; + const VkPipelineShaderStageCreateInfo* pStages; + uint32_t groupCount; + const VkRayTracingShaderGroupCreateInfoNV* pGroups; + uint32_t maxRecursionDepth; + VkPipelineLayout layout; + VkPipeline basePipelineHandle; + int32_t basePipelineIndex; +} VkRayTracingPipelineCreateInfoNV; + +typedef struct VkGeometryTrianglesNV { + VkStructureType sType; + const void* pNext; + VkBuffer vertexData; + VkDeviceSize vertexOffset; + uint32_t vertexCount; + VkDeviceSize vertexStride; + VkFormat vertexFormat; + VkBuffer indexData; + VkDeviceSize indexOffset; + uint32_t indexCount; + VkIndexType indexType; + VkBuffer transformData; + VkDeviceSize transformOffset; +} VkGeometryTrianglesNV; + +typedef struct VkGeometryAABBNV { + VkStructureType sType; + const void* pNext; + VkBuffer aabbData; + uint32_t numAABBs; + uint32_t stride; + VkDeviceSize offset; +} VkGeometryAABBNV; + +typedef struct VkGeometryDataNV { + VkGeometryTrianglesNV triangles; + VkGeometryAABBNV aabbs; +} VkGeometryDataNV; + +typedef struct VkGeometryNV { + VkStructureType sType; + const void* pNext; + VkGeometryTypeNV geometryType; + VkGeometryDataNV geometry; + VkGeometryFlagsNV flags; +} VkGeometryNV; + +typedef struct VkAccelerationStructureInfoNV { + VkStructureType sType; + const void* pNext; + VkAccelerationStructureTypeNV type; + VkBuildAccelerationStructureFlagsNV flags; + uint32_t instanceCount; + uint32_t geometryCount; + const VkGeometryNV* pGeometries; +} VkAccelerationStructureInfoNV; + +typedef struct VkAccelerationStructureCreateInfoNV { + VkStructureType sType; + const void* pNext; + VkDeviceSize compactedSize; + VkAccelerationStructureInfoNV info; +} VkAccelerationStructureCreateInfoNV; + +typedef struct VkBindAccelerationStructureMemoryInfoNV { + VkStructureType sType; + const void* pNext; + VkAccelerationStructureNV accelerationStructure; + VkDeviceMemory memory; + VkDeviceSize memoryOffset; + uint32_t deviceIndexCount; + const uint32_t* pDeviceIndices; +} VkBindAccelerationStructureMemoryInfoNV; + +typedef struct VkWriteDescriptorSetAccelerationStructureNV { + VkStructureType sType; + const void* pNext; + uint32_t accelerationStructureCount; + const VkAccelerationStructureNV* pAccelerationStructures; +} VkWriteDescriptorSetAccelerationStructureNV; + +typedef struct VkAccelerationStructureMemoryRequirementsInfoNV { + VkStructureType sType; + const void* pNext; + VkAccelerationStructureMemoryRequirementsTypeNV type; + VkAccelerationStructureNV accelerationStructure; +} VkAccelerationStructureMemoryRequirementsInfoNV; + +typedef struct VkPhysicalDeviceRayTracingPropertiesNV { + VkStructureType sType; + void* pNext; + uint32_t shaderGroupHandleSize; + uint32_t maxRecursionDepth; + uint32_t maxShaderGroupStride; + uint32_t shaderGroupBaseAlignment; + uint64_t maxGeometryCount; + uint64_t maxInstanceCount; + uint64_t maxTriangleCount; + uint32_t maxDescriptorSetAccelerationStructures; +} VkPhysicalDeviceRayTracingPropertiesNV; + + +typedef VkResult (VKAPI_PTR *PFN_vkCreateAccelerationStructureNV)(VkDevice device, const VkAccelerationStructureCreateInfoNV* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkAccelerationStructureNV* pAccelerationStructure); +typedef void (VKAPI_PTR *PFN_vkDestroyAccelerationStructureNV)(VkDevice device, VkAccelerationStructureNV accelerationStructure, const VkAllocationCallbacks* pAllocator); +typedef void (VKAPI_PTR *PFN_vkGetAccelerationStructureMemoryRequirementsNV)(VkDevice device, const VkAccelerationStructureMemoryRequirementsInfoNV* pInfo, VkMemoryRequirements2KHR* pMemoryRequirements); +typedef VkResult (VKAPI_PTR *PFN_vkBindAccelerationStructureMemoryNV)(VkDevice device, uint32_t bindInfoCount, const VkBindAccelerationStructureMemoryInfoNV* pBindInfos); +typedef void (VKAPI_PTR *PFN_vkCmdBuildAccelerationStructureNV)(VkCommandBuffer commandBuffer, const VkAccelerationStructureInfoNV* pInfo, VkBuffer instanceData, VkDeviceSize instanceOffset, VkBool32 update, VkAccelerationStructureNV dst, VkAccelerationStructureNV src, VkBuffer scratch, VkDeviceSize scratchOffset); +typedef void (VKAPI_PTR *PFN_vkCmdCopyAccelerationStructureNV)(VkCommandBuffer commandBuffer, VkAccelerationStructureNV dst, VkAccelerationStructureNV src, VkCopyAccelerationStructureModeNV mode); +typedef void (VKAPI_PTR *PFN_vkCmdTraceRaysNV)(VkCommandBuffer commandBuffer, VkBuffer raygenShaderBindingTableBuffer, VkDeviceSize raygenShaderBindingOffset, VkBuffer missShaderBindingTableBuffer, VkDeviceSize missShaderBindingOffset, VkDeviceSize missShaderBindingStride, VkBuffer hitShaderBindingTableBuffer, VkDeviceSize hitShaderBindingOffset, VkDeviceSize hitShaderBindingStride, VkBuffer callableShaderBindingTableBuffer, VkDeviceSize callableShaderBindingOffset, VkDeviceSize callableShaderBindingStride, uint32_t width, uint32_t height, uint32_t depth); +typedef VkResult (VKAPI_PTR *PFN_vkCreateRayTracingPipelinesNV)(VkDevice device, VkPipelineCache pipelineCache, uint32_t createInfoCount, const VkRayTracingPipelineCreateInfoNV* pCreateInfos, const VkAllocationCallbacks* pAllocator, VkPipeline* pPipelines); +typedef VkResult (VKAPI_PTR *PFN_vkGetRayTracingShaderGroupHandlesNV)(VkDevice device, VkPipeline pipeline, uint32_t firstGroup, uint32_t groupCount, size_t dataSize, void* pData); +typedef VkResult (VKAPI_PTR *PFN_vkGetAccelerationStructureHandleNV)(VkDevice device, VkAccelerationStructureNV accelerationStructure, size_t dataSize, void* pData); +typedef void (VKAPI_PTR *PFN_vkCmdWriteAccelerationStructuresPropertiesNV)(VkCommandBuffer commandBuffer, uint32_t accelerationStructureCount, const VkAccelerationStructureNV* pAccelerationStructures, VkQueryType queryType, VkQueryPool queryPool, uint32_t firstQuery); +typedef VkResult (VKAPI_PTR *PFN_vkCompileDeferredNV)(VkDevice device, VkPipeline pipeline, uint32_t shader); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkCreateAccelerationStructureNV( + VkDevice device, + const VkAccelerationStructureCreateInfoNV* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkAccelerationStructureNV* pAccelerationStructure); + +VKAPI_ATTR void VKAPI_CALL vkDestroyAccelerationStructureNV( + VkDevice device, + VkAccelerationStructureNV accelerationStructure, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR void VKAPI_CALL vkGetAccelerationStructureMemoryRequirementsNV( + VkDevice device, + const VkAccelerationStructureMemoryRequirementsInfoNV* pInfo, + VkMemoryRequirements2KHR* pMemoryRequirements); + +VKAPI_ATTR VkResult VKAPI_CALL vkBindAccelerationStructureMemoryNV( + VkDevice device, + uint32_t bindInfoCount, + const VkBindAccelerationStructureMemoryInfoNV* pBindInfos); + +VKAPI_ATTR void VKAPI_CALL vkCmdBuildAccelerationStructureNV( + VkCommandBuffer commandBuffer, + const VkAccelerationStructureInfoNV* pInfo, + VkBuffer instanceData, + VkDeviceSize instanceOffset, + VkBool32 update, + VkAccelerationStructureNV dst, + VkAccelerationStructureNV src, + VkBuffer scratch, + VkDeviceSize scratchOffset); + +VKAPI_ATTR void VKAPI_CALL vkCmdCopyAccelerationStructureNV( + VkCommandBuffer commandBuffer, + VkAccelerationStructureNV dst, + VkAccelerationStructureNV src, + VkCopyAccelerationStructureModeNV mode); + +VKAPI_ATTR void VKAPI_CALL vkCmdTraceRaysNV( + VkCommandBuffer commandBuffer, + VkBuffer raygenShaderBindingTableBuffer, + VkDeviceSize raygenShaderBindingOffset, + VkBuffer missShaderBindingTableBuffer, + VkDeviceSize missShaderBindingOffset, + VkDeviceSize missShaderBindingStride, + VkBuffer hitShaderBindingTableBuffer, + VkDeviceSize hitShaderBindingOffset, + VkDeviceSize hitShaderBindingStride, + VkBuffer callableShaderBindingTableBuffer, + VkDeviceSize callableShaderBindingOffset, + VkDeviceSize callableShaderBindingStride, + uint32_t width, + uint32_t height, + uint32_t depth); + +VKAPI_ATTR VkResult VKAPI_CALL vkCreateRayTracingPipelinesNV( + VkDevice device, + VkPipelineCache pipelineCache, + uint32_t createInfoCount, + const VkRayTracingPipelineCreateInfoNV* pCreateInfos, + const VkAllocationCallbacks* pAllocator, + VkPipeline* pPipelines); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetRayTracingShaderGroupHandlesNV( + VkDevice device, + VkPipeline pipeline, + uint32_t firstGroup, + uint32_t groupCount, + size_t dataSize, + void* pData); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetAccelerationStructureHandleNV( + VkDevice device, + VkAccelerationStructureNV accelerationStructure, + size_t dataSize, + void* pData); + +VKAPI_ATTR void VKAPI_CALL vkCmdWriteAccelerationStructuresPropertiesNV( + VkCommandBuffer commandBuffer, + uint32_t accelerationStructureCount, + const VkAccelerationStructureNV* pAccelerationStructures, + VkQueryType queryType, + VkQueryPool queryPool, + uint32_t firstQuery); + +VKAPI_ATTR VkResult VKAPI_CALL vkCompileDeferredNV( + VkDevice device, + VkPipeline pipeline, + uint32_t shader); +#endif + +#define VK_NV_representative_fragment_test 1 +#define VK_NV_REPRESENTATIVE_FRAGMENT_TEST_SPEC_VERSION 1 +#define VK_NV_REPRESENTATIVE_FRAGMENT_TEST_EXTENSION_NAME "VK_NV_representative_fragment_test" + +typedef struct VkPhysicalDeviceRepresentativeFragmentTestFeaturesNV { + VkStructureType sType; + void* pNext; + VkBool32 representativeFragmentTest; +} VkPhysicalDeviceRepresentativeFragmentTestFeaturesNV; + +typedef struct VkPipelineRepresentativeFragmentTestStateCreateInfoNV { + VkStructureType sType; + const void* pNext; + VkBool32 representativeFragmentTestEnable; +} VkPipelineRepresentativeFragmentTestStateCreateInfoNV; + + + #define VK_EXT_global_priority 1 #define VK_EXT_GLOBAL_PRIORITY_SPEC_VERSION 2 #define VK_EXT_GLOBAL_PRIORITY_EXTENSION_NAME "VK_EXT_global_priority" @@ -7303,8 +8624,96 @@ VKAPI_ATTR void VKAPI_CALL vkCmdWriteBufferMarkerAMD( uint32_t marker); #endif +#define VK_EXT_calibrated_timestamps 1 +#define VK_EXT_CALIBRATED_TIMESTAMPS_SPEC_VERSION 1 +#define VK_EXT_CALIBRATED_TIMESTAMPS_EXTENSION_NAME "VK_EXT_calibrated_timestamps" + + +typedef enum VkTimeDomainEXT { + VK_TIME_DOMAIN_DEVICE_EXT = 0, + VK_TIME_DOMAIN_CLOCK_MONOTONIC_EXT = 1, + VK_TIME_DOMAIN_CLOCK_MONOTONIC_RAW_EXT = 2, + VK_TIME_DOMAIN_QUERY_PERFORMANCE_COUNTER_EXT = 3, + VK_TIME_DOMAIN_BEGIN_RANGE_EXT = VK_TIME_DOMAIN_DEVICE_EXT, + VK_TIME_DOMAIN_END_RANGE_EXT = VK_TIME_DOMAIN_QUERY_PERFORMANCE_COUNTER_EXT, + VK_TIME_DOMAIN_RANGE_SIZE_EXT = (VK_TIME_DOMAIN_QUERY_PERFORMANCE_COUNTER_EXT - VK_TIME_DOMAIN_DEVICE_EXT + 1), + VK_TIME_DOMAIN_MAX_ENUM_EXT = 0x7FFFFFFF +} VkTimeDomainEXT; + +typedef struct VkCalibratedTimestampInfoEXT { + VkStructureType sType; + const void* pNext; + VkTimeDomainEXT timeDomain; +} VkCalibratedTimestampInfoEXT; + + +typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceCalibrateableTimeDomainsEXT)(VkPhysicalDevice physicalDevice, uint32_t* pTimeDomainCount, VkTimeDomainEXT* pTimeDomains); +typedef VkResult (VKAPI_PTR *PFN_vkGetCalibratedTimestampsEXT)(VkDevice device, uint32_t timestampCount, const VkCalibratedTimestampInfoEXT* pTimestampInfos, uint64_t* pTimestamps, uint64_t* pMaxDeviation); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceCalibrateableTimeDomainsEXT( + VkPhysicalDevice physicalDevice, + uint32_t* pTimeDomainCount, + VkTimeDomainEXT* pTimeDomains); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetCalibratedTimestampsEXT( + VkDevice device, + uint32_t timestampCount, + const VkCalibratedTimestampInfoEXT* pTimestampInfos, + uint64_t* pTimestamps, + uint64_t* pMaxDeviation); +#endif + +#define VK_AMD_shader_core_properties 1 +#define VK_AMD_SHADER_CORE_PROPERTIES_SPEC_VERSION 1 +#define VK_AMD_SHADER_CORE_PROPERTIES_EXTENSION_NAME "VK_AMD_shader_core_properties" + +typedef struct VkPhysicalDeviceShaderCorePropertiesAMD { + VkStructureType sType; + void* pNext; + uint32_t shaderEngineCount; + uint32_t shaderArraysPerEngineCount; + uint32_t computeUnitsPerShaderArray; + uint32_t simdPerComputeUnit; + uint32_t wavefrontsPerSimd; + uint32_t wavefrontSize; + uint32_t sgprsPerSimd; + uint32_t minSgprAllocation; + uint32_t maxSgprAllocation; + uint32_t sgprAllocationGranularity; + uint32_t vgprsPerSimd; + uint32_t minVgprAllocation; + uint32_t maxVgprAllocation; + uint32_t vgprAllocationGranularity; +} VkPhysicalDeviceShaderCorePropertiesAMD; + + + +#define VK_AMD_memory_overallocation_behavior 1 +#define VK_AMD_MEMORY_OVERALLOCATION_BEHAVIOR_SPEC_VERSION 1 +#define VK_AMD_MEMORY_OVERALLOCATION_BEHAVIOR_EXTENSION_NAME "VK_AMD_memory_overallocation_behavior" + + +typedef enum VkMemoryOverallocationBehaviorAMD { + VK_MEMORY_OVERALLOCATION_BEHAVIOR_DEFAULT_AMD = 0, + VK_MEMORY_OVERALLOCATION_BEHAVIOR_ALLOWED_AMD = 1, + VK_MEMORY_OVERALLOCATION_BEHAVIOR_DISALLOWED_AMD = 2, + VK_MEMORY_OVERALLOCATION_BEHAVIOR_BEGIN_RANGE_AMD = VK_MEMORY_OVERALLOCATION_BEHAVIOR_DEFAULT_AMD, + VK_MEMORY_OVERALLOCATION_BEHAVIOR_END_RANGE_AMD = VK_MEMORY_OVERALLOCATION_BEHAVIOR_DISALLOWED_AMD, + VK_MEMORY_OVERALLOCATION_BEHAVIOR_RANGE_SIZE_AMD = (VK_MEMORY_OVERALLOCATION_BEHAVIOR_DISALLOWED_AMD - VK_MEMORY_OVERALLOCATION_BEHAVIOR_DEFAULT_AMD + 1), + VK_MEMORY_OVERALLOCATION_BEHAVIOR_MAX_ENUM_AMD = 0x7FFFFFFF +} VkMemoryOverallocationBehaviorAMD; + +typedef struct VkDeviceMemoryOverallocationCreateInfoAMD { + VkStructureType sType; + const void* pNext; + VkMemoryOverallocationBehaviorAMD overallocationBehavior; +} VkDeviceMemoryOverallocationCreateInfoAMD; + + + #define VK_EXT_vertex_attribute_divisor 1 -#define VK_EXT_VERTEX_ATTRIBUTE_DIVISOR_SPEC_VERSION 1 +#define VK_EXT_VERTEX_ATTRIBUTE_DIVISOR_SPEC_VERSION 3 #define VK_EXT_VERTEX_ATTRIBUTE_DIVISOR_EXTENSION_NAME "VK_EXT_vertex_attribute_divisor" typedef struct VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT { @@ -7325,6 +8734,359 @@ typedef struct VkPipelineVertexInputDivisorStateCreateInfoEXT { const VkVertexInputBindingDivisorDescriptionEXT* pVertexBindingDivisors; } VkPipelineVertexInputDivisorStateCreateInfoEXT; +typedef struct VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 vertexAttributeInstanceRateDivisor; + VkBool32 vertexAttributeInstanceRateZeroDivisor; +} VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT; + + + +#define VK_NV_shader_subgroup_partitioned 1 +#define VK_NV_SHADER_SUBGROUP_PARTITIONED_SPEC_VERSION 1 +#define VK_NV_SHADER_SUBGROUP_PARTITIONED_EXTENSION_NAME "VK_NV_shader_subgroup_partitioned" + + +#define VK_NV_compute_shader_derivatives 1 +#define VK_NV_COMPUTE_SHADER_DERIVATIVES_SPEC_VERSION 1 +#define VK_NV_COMPUTE_SHADER_DERIVATIVES_EXTENSION_NAME "VK_NV_compute_shader_derivatives" + +typedef struct VkPhysicalDeviceComputeShaderDerivativesFeaturesNV { + VkStructureType sType; + void* pNext; + VkBool32 computeDerivativeGroupQuads; + VkBool32 computeDerivativeGroupLinear; +} VkPhysicalDeviceComputeShaderDerivativesFeaturesNV; + + + +#define VK_NV_mesh_shader 1 +#define VK_NV_MESH_SHADER_SPEC_VERSION 1 +#define VK_NV_MESH_SHADER_EXTENSION_NAME "VK_NV_mesh_shader" + +typedef struct VkPhysicalDeviceMeshShaderFeaturesNV { + VkStructureType sType; + void* pNext; + VkBool32 taskShader; + VkBool32 meshShader; +} VkPhysicalDeviceMeshShaderFeaturesNV; + +typedef struct VkPhysicalDeviceMeshShaderPropertiesNV { + VkStructureType sType; + void* pNext; + uint32_t maxDrawMeshTasksCount; + uint32_t maxTaskWorkGroupInvocations; + uint32_t maxTaskWorkGroupSize[3]; + uint32_t maxTaskTotalMemorySize; + uint32_t maxTaskOutputCount; + uint32_t maxMeshWorkGroupInvocations; + uint32_t maxMeshWorkGroupSize[3]; + uint32_t maxMeshTotalMemorySize; + uint32_t maxMeshOutputVertices; + uint32_t maxMeshOutputPrimitives; + uint32_t maxMeshMultiviewViewCount; + uint32_t meshOutputPerVertexGranularity; + uint32_t meshOutputPerPrimitiveGranularity; +} VkPhysicalDeviceMeshShaderPropertiesNV; + +typedef struct VkDrawMeshTasksIndirectCommandNV { + uint32_t taskCount; + uint32_t firstTask; +} VkDrawMeshTasksIndirectCommandNV; + + +typedef void (VKAPI_PTR *PFN_vkCmdDrawMeshTasksNV)(VkCommandBuffer commandBuffer, uint32_t taskCount, uint32_t firstTask); +typedef void (VKAPI_PTR *PFN_vkCmdDrawMeshTasksIndirectNV)(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, uint32_t drawCount, uint32_t stride); +typedef void (VKAPI_PTR *PFN_vkCmdDrawMeshTasksIndirectCountNV)(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount, uint32_t stride); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkCmdDrawMeshTasksNV( + VkCommandBuffer commandBuffer, + uint32_t taskCount, + uint32_t firstTask); + +VKAPI_ATTR void VKAPI_CALL vkCmdDrawMeshTasksIndirectNV( + VkCommandBuffer commandBuffer, + VkBuffer buffer, + VkDeviceSize offset, + uint32_t drawCount, + uint32_t stride); + +VKAPI_ATTR void VKAPI_CALL vkCmdDrawMeshTasksIndirectCountNV( + VkCommandBuffer commandBuffer, + VkBuffer buffer, + VkDeviceSize offset, + VkBuffer countBuffer, + VkDeviceSize countBufferOffset, + uint32_t maxDrawCount, + uint32_t stride); +#endif + +#define VK_NV_fragment_shader_barycentric 1 +#define VK_NV_FRAGMENT_SHADER_BARYCENTRIC_SPEC_VERSION 1 +#define VK_NV_FRAGMENT_SHADER_BARYCENTRIC_EXTENSION_NAME "VK_NV_fragment_shader_barycentric" + +typedef struct VkPhysicalDeviceFragmentShaderBarycentricFeaturesNV { + VkStructureType sType; + void* pNext; + VkBool32 fragmentShaderBarycentric; +} VkPhysicalDeviceFragmentShaderBarycentricFeaturesNV; + + + +#define VK_NV_shader_image_footprint 1 +#define VK_NV_SHADER_IMAGE_FOOTPRINT_SPEC_VERSION 1 +#define VK_NV_SHADER_IMAGE_FOOTPRINT_EXTENSION_NAME "VK_NV_shader_image_footprint" + +typedef struct VkPhysicalDeviceShaderImageFootprintFeaturesNV { + VkStructureType sType; + void* pNext; + VkBool32 imageFootprint; +} VkPhysicalDeviceShaderImageFootprintFeaturesNV; + + + +#define VK_NV_scissor_exclusive 1 +#define VK_NV_SCISSOR_EXCLUSIVE_SPEC_VERSION 1 +#define VK_NV_SCISSOR_EXCLUSIVE_EXTENSION_NAME "VK_NV_scissor_exclusive" + +typedef struct VkPipelineViewportExclusiveScissorStateCreateInfoNV { + VkStructureType sType; + const void* pNext; + uint32_t exclusiveScissorCount; + const VkRect2D* pExclusiveScissors; +} VkPipelineViewportExclusiveScissorStateCreateInfoNV; + +typedef struct VkPhysicalDeviceExclusiveScissorFeaturesNV { + VkStructureType sType; + void* pNext; + VkBool32 exclusiveScissor; +} VkPhysicalDeviceExclusiveScissorFeaturesNV; + + +typedef void (VKAPI_PTR *PFN_vkCmdSetExclusiveScissorNV)(VkCommandBuffer commandBuffer, uint32_t firstExclusiveScissor, uint32_t exclusiveScissorCount, const VkRect2D* pExclusiveScissors); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkCmdSetExclusiveScissorNV( + VkCommandBuffer commandBuffer, + uint32_t firstExclusiveScissor, + uint32_t exclusiveScissorCount, + const VkRect2D* pExclusiveScissors); +#endif + +#define VK_NV_device_diagnostic_checkpoints 1 +#define VK_NV_DEVICE_DIAGNOSTIC_CHECKPOINTS_SPEC_VERSION 2 +#define VK_NV_DEVICE_DIAGNOSTIC_CHECKPOINTS_EXTENSION_NAME "VK_NV_device_diagnostic_checkpoints" + +typedef struct VkQueueFamilyCheckpointPropertiesNV { + VkStructureType sType; + void* pNext; + VkPipelineStageFlags checkpointExecutionStageMask; +} VkQueueFamilyCheckpointPropertiesNV; + +typedef struct VkCheckpointDataNV { + VkStructureType sType; + void* pNext; + VkPipelineStageFlagBits stage; + void* pCheckpointMarker; +} VkCheckpointDataNV; + + +typedef void (VKAPI_PTR *PFN_vkCmdSetCheckpointNV)(VkCommandBuffer commandBuffer, const void* pCheckpointMarker); +typedef void (VKAPI_PTR *PFN_vkGetQueueCheckpointDataNV)(VkQueue queue, uint32_t* pCheckpointDataCount, VkCheckpointDataNV* pCheckpointData); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkCmdSetCheckpointNV( + VkCommandBuffer commandBuffer, + const void* pCheckpointMarker); + +VKAPI_ATTR void VKAPI_CALL vkGetQueueCheckpointDataNV( + VkQueue queue, + uint32_t* pCheckpointDataCount, + VkCheckpointDataNV* pCheckpointData); +#endif + +#define VK_EXT_pci_bus_info 1 +#define VK_EXT_PCI_BUS_INFO_SPEC_VERSION 2 +#define VK_EXT_PCI_BUS_INFO_EXTENSION_NAME "VK_EXT_pci_bus_info" + +typedef struct VkPhysicalDevicePCIBusInfoPropertiesEXT { + VkStructureType sType; + void* pNext; + uint32_t pciDomain; + uint32_t pciBus; + uint32_t pciDevice; + uint32_t pciFunction; +} VkPhysicalDevicePCIBusInfoPropertiesEXT; + + + +#define VK_EXT_fragment_density_map 1 +#define VK_EXT_FRAGMENT_DENSITY_MAP_SPEC_VERSION 1 +#define VK_EXT_FRAGMENT_DENSITY_MAP_EXTENSION_NAME "VK_EXT_fragment_density_map" + +typedef struct VkPhysicalDeviceFragmentDensityMapFeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 fragmentDensityMap; + VkBool32 fragmentDensityMapDynamic; + VkBool32 fragmentDensityMapNonSubsampledImages; +} VkPhysicalDeviceFragmentDensityMapFeaturesEXT; + +typedef struct VkPhysicalDeviceFragmentDensityMapPropertiesEXT { + VkStructureType sType; + void* pNext; + VkExtent2D minFragmentDensityTexelSize; + VkExtent2D maxFragmentDensityTexelSize; + VkBool32 fragmentDensityInvocations; +} VkPhysicalDeviceFragmentDensityMapPropertiesEXT; + +typedef struct VkRenderPassFragmentDensityMapCreateInfoEXT { + VkStructureType sType; + const void* pNext; + VkAttachmentReference fragmentDensityMapAttachment; +} VkRenderPassFragmentDensityMapCreateInfoEXT; + + + +#define VK_EXT_scalar_block_layout 1 +#define VK_EXT_SCALAR_BLOCK_LAYOUT_SPEC_VERSION 1 +#define VK_EXT_SCALAR_BLOCK_LAYOUT_EXTENSION_NAME "VK_EXT_scalar_block_layout" + +typedef struct VkPhysicalDeviceScalarBlockLayoutFeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 scalarBlockLayout; +} VkPhysicalDeviceScalarBlockLayoutFeaturesEXT; + + + +#define VK_GOOGLE_hlsl_functionality1 1 +#define VK_GOOGLE_HLSL_FUNCTIONALITY1_SPEC_VERSION 1 +#define VK_GOOGLE_HLSL_FUNCTIONALITY1_EXTENSION_NAME "VK_GOOGLE_hlsl_functionality1" + + +#define VK_GOOGLE_decorate_string 1 +#define VK_GOOGLE_DECORATE_STRING_SPEC_VERSION 1 +#define VK_GOOGLE_DECORATE_STRING_EXTENSION_NAME "VK_GOOGLE_decorate_string" + + +#define VK_EXT_memory_budget 1 +#define VK_EXT_MEMORY_BUDGET_SPEC_VERSION 1 +#define VK_EXT_MEMORY_BUDGET_EXTENSION_NAME "VK_EXT_memory_budget" + +typedef struct VkPhysicalDeviceMemoryBudgetPropertiesEXT { + VkStructureType sType; + void* pNext; + VkDeviceSize heapBudget[VK_MAX_MEMORY_HEAPS]; + VkDeviceSize heapUsage[VK_MAX_MEMORY_HEAPS]; +} VkPhysicalDeviceMemoryBudgetPropertiesEXT; + + + +#define VK_EXT_memory_priority 1 +#define VK_EXT_MEMORY_PRIORITY_SPEC_VERSION 1 +#define VK_EXT_MEMORY_PRIORITY_EXTENSION_NAME "VK_EXT_memory_priority" + +typedef struct VkPhysicalDeviceMemoryPriorityFeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 memoryPriority; +} VkPhysicalDeviceMemoryPriorityFeaturesEXT; + +typedef struct VkMemoryPriorityAllocateInfoEXT { + VkStructureType sType; + const void* pNext; + float priority; +} VkMemoryPriorityAllocateInfoEXT; + + + +#define VK_EXT_buffer_device_address 1 +typedef uint64_t VkDeviceAddress; + +#define VK_EXT_BUFFER_DEVICE_ADDRESS_SPEC_VERSION 2 +#define VK_EXT_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME "VK_EXT_buffer_device_address" + +typedef struct VkPhysicalDeviceBufferAddressFeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 bufferDeviceAddress; + VkBool32 bufferDeviceAddressCaptureReplay; + VkBool32 bufferDeviceAddressMultiDevice; +} VkPhysicalDeviceBufferAddressFeaturesEXT; + +typedef struct VkBufferDeviceAddressInfoEXT { + VkStructureType sType; + const void* pNext; + VkBuffer buffer; +} VkBufferDeviceAddressInfoEXT; + +typedef struct VkBufferDeviceAddressCreateInfoEXT { + VkStructureType sType; + const void* pNext; + VkDeviceSize deviceAddress; +} VkBufferDeviceAddressCreateInfoEXT; + + +typedef VkDeviceAddress (VKAPI_PTR *PFN_vkGetBufferDeviceAddressEXT)(VkDevice device, const VkBufferDeviceAddressInfoEXT* pInfo); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkDeviceAddress VKAPI_CALL vkGetBufferDeviceAddressEXT( + VkDevice device, + const VkBufferDeviceAddressInfoEXT* pInfo); +#endif + +#define VK_EXT_separate_stencil_usage 1 +#define VK_EXT_SEPARATE_STENCIL_USAGE_SPEC_VERSION 1 +#define VK_EXT_SEPARATE_STENCIL_USAGE_EXTENSION_NAME "VK_EXT_separate_stencil_usage" + +typedef struct VkImageStencilUsageCreateInfoEXT { + VkStructureType sType; + const void* pNext; + VkImageUsageFlags stencilUsage; +} VkImageStencilUsageCreateInfoEXT; + + + +#define VK_EXT_validation_features 1 +#define VK_EXT_VALIDATION_FEATURES_SPEC_VERSION 1 +#define VK_EXT_VALIDATION_FEATURES_EXTENSION_NAME "VK_EXT_validation_features" + + +typedef enum VkValidationFeatureEnableEXT { + VK_VALIDATION_FEATURE_ENABLE_GPU_ASSISTED_EXT = 0, + VK_VALIDATION_FEATURE_ENABLE_GPU_ASSISTED_RESERVE_BINDING_SLOT_EXT = 1, + VK_VALIDATION_FEATURE_ENABLE_BEGIN_RANGE_EXT = VK_VALIDATION_FEATURE_ENABLE_GPU_ASSISTED_EXT, + VK_VALIDATION_FEATURE_ENABLE_END_RANGE_EXT = VK_VALIDATION_FEATURE_ENABLE_GPU_ASSISTED_RESERVE_BINDING_SLOT_EXT, + VK_VALIDATION_FEATURE_ENABLE_RANGE_SIZE_EXT = (VK_VALIDATION_FEATURE_ENABLE_GPU_ASSISTED_RESERVE_BINDING_SLOT_EXT - VK_VALIDATION_FEATURE_ENABLE_GPU_ASSISTED_EXT + 1), + VK_VALIDATION_FEATURE_ENABLE_MAX_ENUM_EXT = 0x7FFFFFFF +} VkValidationFeatureEnableEXT; + +typedef enum VkValidationFeatureDisableEXT { + VK_VALIDATION_FEATURE_DISABLE_ALL_EXT = 0, + VK_VALIDATION_FEATURE_DISABLE_SHADERS_EXT = 1, + VK_VALIDATION_FEATURE_DISABLE_THREAD_SAFETY_EXT = 2, + VK_VALIDATION_FEATURE_DISABLE_API_PARAMETERS_EXT = 3, + VK_VALIDATION_FEATURE_DISABLE_OBJECT_LIFETIMES_EXT = 4, + VK_VALIDATION_FEATURE_DISABLE_CORE_CHECKS_EXT = 5, + VK_VALIDATION_FEATURE_DISABLE_UNIQUE_HANDLES_EXT = 6, + VK_VALIDATION_FEATURE_DISABLE_BEGIN_RANGE_EXT = VK_VALIDATION_FEATURE_DISABLE_ALL_EXT, + VK_VALIDATION_FEATURE_DISABLE_END_RANGE_EXT = VK_VALIDATION_FEATURE_DISABLE_UNIQUE_HANDLES_EXT, + VK_VALIDATION_FEATURE_DISABLE_RANGE_SIZE_EXT = (VK_VALIDATION_FEATURE_DISABLE_UNIQUE_HANDLES_EXT - VK_VALIDATION_FEATURE_DISABLE_ALL_EXT + 1), + VK_VALIDATION_FEATURE_DISABLE_MAX_ENUM_EXT = 0x7FFFFFFF +} VkValidationFeatureDisableEXT; + +typedef struct VkValidationFeaturesEXT { + VkStructureType sType; + const void* pNext; + uint32_t enabledValidationFeatureCount; + const VkValidationFeatureEnableEXT* pEnabledValidationFeatures; + uint32_t disabledValidationFeatureCount; + const VkValidationFeatureDisableEXT* pDisabledValidationFeatures; +} VkValidationFeaturesEXT; + #ifdef __cplusplus diff --git a/ext/vulkan/vulkan_fuchsia.h b/ext/vulkan/vulkan_fuchsia.h new file mode 100644 index 0000000000..1c335fd386 --- /dev/null +++ b/ext/vulkan/vulkan_fuchsia.h @@ -0,0 +1,58 @@ +#ifndef VULKAN_FUCHSIA_H_ +#define VULKAN_FUCHSIA_H_ 1 + +#ifdef __cplusplus +extern "C" { +#endif + +/* +** Copyright (c) 2015-2019 The Khronos Group Inc. +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + +/* +** This header is generated from the Khronos Vulkan XML API Registry. +** +*/ + + +#define VK_FUCHSIA_imagepipe_surface 1 +#define VK_FUCHSIA_IMAGEPIPE_SURFACE_SPEC_VERSION 1 +#define VK_FUCHSIA_IMAGEPIPE_SURFACE_EXTENSION_NAME "VK_FUCHSIA_imagepipe_surface" + +typedef VkFlags VkImagePipeSurfaceCreateFlagsFUCHSIA; + +typedef struct VkImagePipeSurfaceCreateInfoFUCHSIA { + VkStructureType sType; + const void* pNext; + VkImagePipeSurfaceCreateFlagsFUCHSIA flags; + zx_handle_t imagePipeHandle; +} VkImagePipeSurfaceCreateInfoFUCHSIA; + + +typedef VkResult (VKAPI_PTR *PFN_vkCreateImagePipeSurfaceFUCHSIA)(VkInstance instance, const VkImagePipeSurfaceCreateInfoFUCHSIA* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkCreateImagePipeSurfaceFUCHSIA( + VkInstance instance, + const VkImagePipeSurfaceCreateInfoFUCHSIA* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkSurfaceKHR* pSurface); +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/ext/vulkan/vulkan_ios.h b/ext/vulkan/vulkan_ios.h index a0924816d5..d221a9baad 100644 --- a/ext/vulkan/vulkan_ios.h +++ b/ext/vulkan/vulkan_ios.h @@ -6,7 +6,7 @@ extern "C" { #endif /* -** Copyright (c) 2015-2018 The Khronos Group Inc. +** Copyright (c) 2015-2019 The Khronos Group Inc. ** ** Licensed under the Apache License, Version 2.0 (the "License"); ** you may not use this file except in compliance with the License. diff --git a/ext/vulkan/vulkan_macos.h b/ext/vulkan/vulkan_macos.h index ff0b701801..5d6b6aeb9a 100644 --- a/ext/vulkan/vulkan_macos.h +++ b/ext/vulkan/vulkan_macos.h @@ -6,7 +6,7 @@ extern "C" { #endif /* -** Copyright (c) 2015-2018 The Khronos Group Inc. +** Copyright (c) 2015-2019 The Khronos Group Inc. ** ** Licensed under the Apache License, Version 2.0 (the "License"); ** you may not use this file except in compliance with the License. diff --git a/ext/vulkan/vulkan_vi.h b/ext/vulkan/vulkan_vi.h index 015166bfc6..3e37bab69a 100644 --- a/ext/vulkan/vulkan_vi.h +++ b/ext/vulkan/vulkan_vi.h @@ -6,7 +6,7 @@ extern "C" { #endif /* -** Copyright (c) 2015-2018 The Khronos Group Inc. +** Copyright (c) 2015-2019 The Khronos Group Inc. ** ** Licensed under the Apache License, Version 2.0 (the "License"); ** you may not use this file except in compliance with the License. diff --git a/ext/vulkan/vulkan_wayland.h b/ext/vulkan/vulkan_wayland.h index 5ba0827aa3..33a22de3bd 100644 --- a/ext/vulkan/vulkan_wayland.h +++ b/ext/vulkan/vulkan_wayland.h @@ -6,7 +6,7 @@ extern "C" { #endif /* -** Copyright (c) 2015-2018 The Khronos Group Inc. +** Copyright (c) 2015-2019 The Khronos Group Inc. ** ** Licensed under the Apache License, Version 2.0 (the "License"); ** you may not use this file except in compliance with the License. diff --git a/ext/vulkan/vulkan_win32.h b/ext/vulkan/vulkan_win32.h index 6a85409ebe..b9d63d47f4 100644 --- a/ext/vulkan/vulkan_win32.h +++ b/ext/vulkan/vulkan_win32.h @@ -6,7 +6,7 @@ extern "C" { #endif /* -** Copyright (c) 2015-2018 The Khronos Group Inc. +** Copyright (c) 2015-2019 The Khronos Group Inc. ** ** Licensed under the Apache License, Version 2.0 (the "License"); ** you may not use this file except in compliance with the License. diff --git a/ext/vulkan/vulkan_xcb.h b/ext/vulkan/vulkan_xcb.h index ba03600602..f21290974a 100644 --- a/ext/vulkan/vulkan_xcb.h +++ b/ext/vulkan/vulkan_xcb.h @@ -6,7 +6,7 @@ extern "C" { #endif /* -** Copyright (c) 2015-2018 The Khronos Group Inc. +** Copyright (c) 2015-2019 The Khronos Group Inc. ** ** Licensed under the Apache License, Version 2.0 (the "License"); ** you may not use this file except in compliance with the License. diff --git a/ext/vulkan/vulkan_xlib.h b/ext/vulkan/vulkan_xlib.h index e1d967e018..ce3d36ddcf 100644 --- a/ext/vulkan/vulkan_xlib.h +++ b/ext/vulkan/vulkan_xlib.h @@ -6,7 +6,7 @@ extern "C" { #endif /* -** Copyright (c) 2015-2018 The Khronos Group Inc. +** Copyright (c) 2015-2019 The Khronos Group Inc. ** ** Licensed under the Apache License, Version 2.0 (the "License"); ** you may not use this file except in compliance with the License. diff --git a/ext/vulkan/vulkan_xlib_xrandr.h b/ext/vulkan/vulkan_xlib_xrandr.h index 117d01799e..25efb077f7 100644 --- a/ext/vulkan/vulkan_xlib_xrandr.h +++ b/ext/vulkan/vulkan_xlib_xrandr.h @@ -6,7 +6,7 @@ extern "C" { #endif /* -** Copyright (c) 2015-2018 The Khronos Group Inc. +** Copyright (c) 2015-2019 The Khronos Group Inc. ** ** Licensed under the Apache License, Version 2.0 (the "License"); ** you may not use this file except in compliance with the License. diff --git a/ext/zlib/zlib.vcxproj b/ext/zlib/zlib.vcxproj index cc73897541..81d64dcaae 100644 --- a/ext/zlib/zlib.vcxproj +++ b/ext/zlib/zlib.vcxproj @@ -52,7 +52,8 @@ {F761046E-6C38-4428-A5F1-38391A37BB34} Win32Proj zlib - + + @@ -111,6 +112,7 @@ false MultiThreadedDebug ../../Common/DbgNew.h + ProgramDatabase Windows @@ -132,6 +134,7 @@ false MultiThreadedDebug ../../Common/DbgNew.h + ProgramDatabase Windows @@ -193,4 +196,4 @@ - + \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 95c68256f8..32bb5e0c8d 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Tue May 08 18:23:21 CEST 2018 +#Tue Jan 15 23:30:05 CET 2019 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.8.1-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.1-all.zip diff --git a/headless/Compare.cpp b/headless/Compare.cpp index 556bd32873..ba35b93c90 100644 --- a/headless/Compare.cpp +++ b/headless/Compare.cpp @@ -301,28 +301,44 @@ std::vector TranslateDebugBufferToCompare(const GPUDebugBuffer *buffer, u32 std::vector data; data.resize(stride * h, 0); - const u32 *pixels = (const u32 *)buffer->GetData(); + const u32 *pixels32 = (const u32 *)buffer->GetData(); + const u16 *pixels16 = (const u16 *)buffer->GetData(); int outStride = buffer->GetStride(); - if (!buffer->GetFlipped()) - { + if (!buffer->GetFlipped()) { // Bitmaps are flipped, so we have to compare backwards in this case. - pixels += outStride * (buffer->GetHeight() - 1); + int toLastRow = outStride * (buffer->GetHeight() - 1); + pixels32 += toLastRow; + pixels16 += toLastRow; outStride = -outStride; } u32 errors = 0; - for (u32 y = 0; y < safeH; ++y) - { - if (buffer->GetFormat() == GPU_DBG_FORMAT_8888) - ConvertBGRA8888ToRGBA8888(&data[y * stride], pixels, safeW); - else if (buffer->GetFormat() == GPU_DBG_FORMAT_8888_BGRA) - memcpy(&data[y * stride], pixels, safeW * sizeof(u32)); - else - { + for (u32 y = 0; y < safeH; ++y) { + switch (buffer->GetFormat()) { + case GPU_DBG_FORMAT_8888: + ConvertBGRA8888ToRGBA8888(&data[y * stride], pixels32, safeW); + break; + case GPU_DBG_FORMAT_8888_BGRA: + memcpy(&data[y * stride], pixels32, safeW * sizeof(u32)); + break; + + case GPU_DBG_FORMAT_565: + ConvertRGB565ToBGRA8888(&data[y * stride], pixels16, safeW); + break; + case GPU_DBG_FORMAT_5551: + ConvertRGBA5551ToBGRA8888(&data[y * stride], pixels16, safeW); + break; + case GPU_DBG_FORMAT_4444: + ConvertRGBA4444ToBGRA8888(&data[y * stride], pixels16, safeW); + break; + + default: data.resize(0); return data; } - pixels += outStride; + + pixels32 += outStride; + pixels16 += outStride; } return data; @@ -365,4 +381,4 @@ double CompareScreenshot(const std::vector &pixels, u32 stride, u32 w, u32 free(reference); return (double) errors / (double) (w * h); -} \ No newline at end of file +} diff --git a/headless/Headless.cpp b/headless/Headless.cpp index 0734e1d8ca..eedb509f85 100644 --- a/headless/Headless.cpp +++ b/headless/Headless.cpp @@ -354,7 +354,6 @@ int main(int argc, const char* argv[]) g_Config.bHardwareTransform = true; g_Config.iAnisotropyLevel = 0; // When testing mipmapping we really don't want this. g_Config.bVertexCache = true; - g_Config.bTrueColor = true; g_Config.iLanguage = PSP_SYSTEMPARAM_LANGUAGE_ENGLISH; g_Config.iTimeFormat = PSP_SYSTEMPARAM_TIME_FORMAT_24HR; g_Config.bEncryptSave = true; diff --git a/headless/Headless.vcxproj b/headless/Headless.vcxproj index e4412a822c..5be939c78c 100644 --- a/headless/Headless.vcxproj +++ b/headless/Headless.vcxproj @@ -102,6 +102,7 @@ false MultiThreadedDebug Common/DbgNew.h + ProgramDatabase Console @@ -133,6 +134,7 @@ false MultiThreadedDebug Common/DbgNew.h + ProgramDatabase Console diff --git a/headless/SDLHeadlessHost.cpp b/headless/SDLHeadlessHost.cpp index 1545a53f9c..c5702eabc4 100644 --- a/headless/SDLHeadlessHost.cpp +++ b/headless/SDLHeadlessHost.cpp @@ -76,7 +76,7 @@ public: } void ThreadStart() override { - renderManager_->ThreadStart(); + renderManager_->ThreadStart(draw_); } bool ThreadFrame() override { diff --git a/headless/StubHost.cpp b/headless/StubHost.cpp index dc3520013e..6569cc3b1a 100644 --- a/headless/StubHost.cpp +++ b/headless/StubHost.cpp @@ -55,7 +55,7 @@ void HeadlessHost::SendDebugScreenshot(const u8 *pixbuf, u32 w, u32 h) std::string error; double errors = CompareScreenshot(pixels, FRAME_STRIDE, FRAME_WIDTH, FRAME_HEIGHT, comparisonScreenshot_, error); if (errors < 0) - SendOrCollectDebugOutput(error); + SendOrCollectDebugOutput(error + "\n"); if (errors > 0) { diff --git a/ios/Launch Screen.storyboard b/ios/Launch Screen.storyboard index 5b0377f076..513011ac21 100644 --- a/ios/Launch Screen.storyboard +++ b/ios/Launch Screen.storyboard @@ -1,12 +1,17 @@ - + - + + + + Roboto-Condensed + + @@ -19,6 +24,37 @@ + + + + + + + + + + + + + @@ -27,4 +63,8 @@ + + + + diff --git a/ios/ViewController.mm b/ios/ViewController.mm index 3ca85ebcdf..0c5c5ae5da 100644 --- a/ios/ViewController.mm +++ b/ios/ViewController.mm @@ -42,7 +42,7 @@ public: renderManager_ = (GLRenderManager *)draw_->GetNativeObject(Draw::NativeObject::RENDER_MANAGER); SetGPUBackend(GPUBackend::OPENGL); bool success = draw_->CreatePresets(); - assert(success); + _assert_msg_(G3D, success, "Failed to compile preset shaders"); } ~IOSGraphicsContext() { delete draw_; @@ -51,7 +51,7 @@ public: return draw_; } void ThreadStart() override { - renderManager_->ThreadStart(); + renderManager_->ThreadStart(draw_); } bool ThreadFrame() override { diff --git a/libretro/LibretroD3D11Context.cpp b/libretro/LibretroD3D11Context.cpp index 7e6a939d7c..cd46e66858 100644 --- a/libretro/LibretroD3D11Context.cpp +++ b/libretro/LibretroD3D11Context.cpp @@ -1,4 +1,5 @@ +#include "Core/ConfigValues.h" #include "libretro/LibretroD3D11Context.h" #include "thin3d/d3d11_loader.h" #include @@ -17,6 +18,8 @@ bool LibretroD3D11Context::Init() { } void LibretroD3D11Context::CreateDrawContext() { + std::vector adapterNames; + if (!Libretro::environ_cb(RETRO_ENVIRONMENT_GET_HW_RENDER_INTERFACE, (void **)&d3d11_) || !d3d11_) { ERROR_LOG(G3D, "Failed to get HW rendering interface!\n"); return; @@ -35,7 +38,7 @@ void LibretroD3D11Context::CreateDrawContext() { ID3D11DeviceContext1 *context1 = nullptr; d3d11_->context->QueryInterface(__uuidof(ID3D11DeviceContext1), (void **)&context1); - draw_ = Draw::T3DCreateD3D11Context(d3d11_->device, d3d11_->context, device1, context1, d3d11_->featureLevel, NULL); + draw_ = Draw::T3DCreateD3D11Context(d3d11_->device, d3d11_->context, device1, context1, d3d11_->featureLevel, NULL, adapterNames); } void LibretroD3D11Context::DestroyDrawContext() { diff --git a/libretro/LibretroGLContext.h b/libretro/LibretroGLContext.h index 8a91044fdd..b85c8affb0 100644 --- a/libretro/LibretroGLContext.h +++ b/libretro/LibretroGLContext.h @@ -26,7 +26,7 @@ public: g_defaultFBO = hw_render_.get_current_framebuffer(); } - void ThreadStart() override { renderManager_->ThreadStart(); } + void ThreadStart() override { renderManager_->ThreadStart(draw_); } bool ThreadFrame() override { return renderManager_->ThreadFrame(); } void ThreadEnd() override { renderManager_->ThreadEnd(); } void StopThread() override { diff --git a/libretro/LibretroVulkanContext.cpp b/libretro/LibretroVulkanContext.cpp index 5cc7d4f09b..69679f16bc 100644 --- a/libretro/LibretroVulkanContext.cpp +++ b/libretro/LibretroVulkanContext.cpp @@ -134,7 +134,7 @@ void LibretroVulkanContext::CreateDrawContext() { } vk_libretro_set_hwrender_interface(vulkan); - vk->ReinitSurface(PSP_CoreParameter().pixelWidth, PSP_CoreParameter().pixelHeight); + vk->ReinitSurface(); if (!vk->InitSwapchain()) { return; diff --git a/libretro/Makefile b/libretro/Makefile index 4fdb2ea929..8970ddc036 100644 --- a/libretro/Makefile +++ b/libretro/Makefile @@ -15,9 +15,9 @@ ifeq (,$(TARGET_ARCH)) endif ifneq (,$(findstring 64,$(TARGET_ARCH))) - override TARGET_ARCH := x86_64 + TARGET_ARCH := x86_64 else ifneq (,$(findstring 86,$(TARGET_ARCH))) - override TARGET_ARCH := x86 + TARGET_ARCH := x86 endif ifeq ($(platform),) diff --git a/libretro/Makefile.common b/libretro/Makefile.common index 3bc9ab9726..1d3b805e7c 100644 --- a/libretro/Makefile.common +++ b/libretro/Makefile.common @@ -188,6 +188,7 @@ SOURCES_CXX += \ $(GPUDIR)/Software/Lighting.cpp \ $(GPUDIR)/Software/Rasterizer.cpp \ $(GPUDIR)/GLES/DepalettizeShaderGLES.cpp \ + $(GPUDIR)/GLES/DepthBufferGLES.cpp \ $(GPUDIR)/GLES/VertexShaderGeneratorGLES.cpp \ $(GPUDIR)/GLES/DrawEngineGLES.cpp \ $(GPUDIR)/GLES/GPU_GLES.cpp \ @@ -216,6 +217,7 @@ SOURCES_CXX += \ $(EXTDIR)/glslang/glslang/MachineIndependent/preprocessor/PpContext.cpp \ $(EXTDIR)/glslang/glslang/MachineIndependent/preprocessor/PpScanner.cpp \ $(EXTDIR)/glslang/glslang/MachineIndependent/preprocessor/PpTokens.cpp \ + $(EXTDIR)/glslang/glslang/MachineIndependent/attribute.cpp \ $(EXTDIR)/glslang/glslang/MachineIndependent/Constant.cpp \ $(EXTDIR)/glslang/glslang/MachineIndependent/InfoSink.cpp \ $(EXTDIR)/glslang/glslang/MachineIndependent/Initialize.cpp \ @@ -409,6 +411,7 @@ SOURCES_CXX += $(NATIVEDIR)/math/dataconv.cpp \ $(COREDIR)/HLE/sceSsl.cpp \ $(COREDIR)/HLE/sceUmd.cpp \ $(COREDIR)/HLE/sceUsb.cpp \ + $(COREDIR)/HLE/sceUsbAcc.cpp \ $(COREDIR)/HLE/sceUsbCam.cpp \ $(COREDIR)/HLE/sceUtility.cpp \ $(COREDIR)/HLE/sceVaudio.cpp \ @@ -454,6 +457,7 @@ SOURCES_CXX += $(NATIVEDIR)/math/dataconv.cpp \ $(COREDIR)/MemMap.cpp \ $(COREDIR)/MemMapFunctions.cpp \ $(COREDIR)/PSPLoaders.cpp \ + $(COREDIR)/Replay.cpp \ $(COREDIR)/Reporting.cpp \ $(COREDIR)/SaveState.cpp \ $(COREDIR)/Screenshot.cpp \ @@ -581,7 +585,6 @@ SOURCES_C += $(EXTDIR)/udis86/decode.c \ SOURCES_CXX += \ - $(COMMONDIR)/Vulkan/SPIRVDisasm.cpp \ $(COMMONDIR)/Vulkan/VulkanContext.cpp \ $(COMMONDIR)/Vulkan/VulkanDebug.cpp \ $(COMMONDIR)/Vulkan/VulkanImage.cpp \ @@ -675,7 +678,7 @@ SOURCES_C += \ endif GIT_VERSION_SRC = $(CORE_DIR)/git-version.cpp -GIT_VERSION := $(shell git describe --always || echo v1.4.2-git) +GIT_VERSION := $(shell git describe --always || echo v1.7.0-git) GIT_VERSION_NO_UPDATE = $(findstring 1,$(shell grep -s PPSSPP_GIT_VERSION_NO_UPDATE $(GIT_VERSION_SRC))) ifneq (,$(findstring $(GIT_VERSION),$(shell grep -s char $(GIT_VERSION_SRC)))) GIT_VERSION_NO_UPDATE = 1 diff --git a/libretro/libretro.cpp b/libretro/libretro.cpp index 822e4def82..d380f0e09a 100644 --- a/libretro/libretro.cpp +++ b/libretro/libretro.cpp @@ -167,10 +167,9 @@ static RetroOption ppsspp_cpu_core("ppsspp_cpu_core", "CPU Core", { { " static RetroOption ppsspp_locked_cpu_speed("ppsspp_locked_cpu_speed", "Locked CPU Speed", { { "off", 0 }, { "222MHz", 222 }, { "266MHz", 266 }, { "333MHz", 333 } }); static RetroOption ppsspp_language("ppsspp_language", "Language", { { "automatic", -1 }, { "english", PSP_SYSTEMPARAM_LANGUAGE_ENGLISH }, { "japanese", PSP_SYSTEMPARAM_LANGUAGE_JAPANESE }, { "french", PSP_SYSTEMPARAM_LANGUAGE_FRENCH }, { "spanish", PSP_SYSTEMPARAM_LANGUAGE_SPANISH }, { "german", PSP_SYSTEMPARAM_LANGUAGE_GERMAN }, { "italian", PSP_SYSTEMPARAM_LANGUAGE_ITALIAN }, { "dutch", PSP_SYSTEMPARAM_LANGUAGE_DUTCH }, { "portuguese", PSP_SYSTEMPARAM_LANGUAGE_PORTUGUESE }, { "russian", PSP_SYSTEMPARAM_LANGUAGE_RUSSIAN }, { "korean", PSP_SYSTEMPARAM_LANGUAGE_KOREAN }, { "chinese_traditional", PSP_SYSTEMPARAM_LANGUAGE_CHINESE_TRADITIONAL }, { "chinese_simplified", PSP_SYSTEMPARAM_LANGUAGE_CHINESE_SIMPLIFIED } }); static RetroOption ppsspp_rendering_mode("ppsspp_rendering_mode", "Rendering Mode", { { "buffered", FB_BUFFERED_MODE }, { "nonbuffered", FB_NON_BUFFERED_MODE } }); -static RetroOption ppsspp_true_color("ppsspp_true_color", "True Color Depth", true); static RetroOption ppsspp_auto_frameskip("ppsspp_auto_frameskip", "Auto Frameskip", false); static RetroOption ppsspp_frameskip("ppsspp_frameskip", "Frameskip", 0, 10); -static RetroOption ppsspp_force_max_fps("ppsspp_force_max_fps", "Force Max FPS", { { "disabled", 0 }, { "enabled", 60 } }); +static RetroOption ppsspp_frameskiptype("ppsspp_frameskiptype", "Frameskip Type", 0, 10); static RetroOption ppsspp_audio_latency("ppsspp_audio_latency", "Audio latency", { "low", "medium", "high" }); static RetroOption ppsspp_internal_resolution("ppsspp_internal_resolution", "Internal Resolution", 1, { "480x272", "960x544", "1440x816", "1920x1088", "2400x1360", "2880x1632", "3360x1904", "3840x2176", "4320x2448", "4800x2720" }); static RetroOption ppsspp_button_preference("ppsspp_button_preference", "Confirmation Button", { { "cross", PSP_SYSTEMPARAM_BUTTON_CROSS }, { "circle", PSP_SYSTEMPARAM_BUTTON_CIRCLE } }); @@ -179,8 +178,10 @@ static RetroOption ppsspp_block_transfer_gpu("ppsspp_block_transfer_gpu", static RetroOption ppsspp_texture_scaling_level("ppsspp_texture_scaling_level", "Texture Scaling Level", { { "1", 1 }, { "2", 2 }, { "3", 3 }, { "4", 4 }, { "5", 5 }, { "0", 0 } }); static RetroOption ppsspp_texture_scaling_type("ppsspp_texture_scaling_type", "Texture Scaling Type", { { "xbrz", TextureScalerCommon::XBRZ }, { "hybrid", TextureScalerCommon::HYBRID }, { "bicubic", TextureScalerCommon::BICUBIC }, { "hybrid_bicubic", TextureScalerCommon::HYBRID_BICUBIC }, { "4xBRZ", TextureScalerCommon::_4XBRZ }, { "XBR", TextureScalerCommon::XBR }, { "SABR", TextureScalerCommon::SABR }, { "gaussian", TextureScalerCommon::GAUSSIAN }, { "cosine", TextureScalerCommon::COSINE } }); static RetroOption ppsspp_texture_scaling_realtime("ppsspp_texture_scaling_realtime", "Realtime Texture Scaling", false); +static RetroOption ppsspp_texture_filtering("ppsspp_texture_filtering", "Texture Filtering", { { "auto", 1 }, { "nearest", 2 }, { "linear", 3 }, { "linear(FMV)", 4 } }); static RetroOption ppsspp_texture_anisotropic_filtering("ppsspp_texture_anisotropic_filtering", "Anisotropic Filtering", { "off", "1x", "2x", "4x", "8x", "16x" }); static RetroOption ppsspp_texture_deposterize("ppsspp_texture_deposterize", "Texture Deposterize", false); +static RetroOption ppsspp_texture_replacement("ppsspp_texture_replacement", "Texture Replacement", false); static RetroOption ppsspp_gpu_hardware_transform("ppsspp_gpu_hardware_transform", "GPU Hardware T&L", true); static RetroOption ppsspp_vertex_cache("ppsspp_vertex_cache", "Vertex Cache (Speedhack)", true); static RetroOption ppsspp_separate_io_thread("ppsspp_separate_io_thread", "IO Threading", false); @@ -194,10 +195,9 @@ void retro_set_environment(retro_environment_t cb) { vars.push_back(ppsspp_locked_cpu_speed.GetOptions()); vars.push_back(ppsspp_language.GetOptions()); vars.push_back(ppsspp_rendering_mode.GetOptions()); - vars.push_back(ppsspp_true_color.GetOptions()); vars.push_back(ppsspp_auto_frameskip.GetOptions()); vars.push_back(ppsspp_frameskip.GetOptions()); - vars.push_back(ppsspp_force_max_fps.GetOptions()); + vars.push_back(ppsspp_frameskiptype.GetOptions()); vars.push_back(ppsspp_audio_latency.GetOptions()); vars.push_back(ppsspp_internal_resolution.GetOptions()); vars.push_back(ppsspp_button_preference.GetOptions()); @@ -205,9 +205,11 @@ void retro_set_environment(retro_environment_t cb) { vars.push_back(ppsspp_block_transfer_gpu.GetOptions()); vars.push_back(ppsspp_texture_scaling_level.GetOptions()); vars.push_back(ppsspp_texture_scaling_type.GetOptions()); + vars.push_back(ppsspp_texture_filtering.GetOptions()); vars.push_back(ppsspp_texture_anisotropic_filtering.GetOptions()); vars.push_back(ppsspp_texture_deposterize.GetOptions()); vars.push_back(ppsspp_texture_scaling_realtime.GetOptions()); + vars.push_back(ppsspp_texture_replacement.GetOptions()); vars.push_back(ppsspp_gpu_hardware_transform.GetOptions()); vars.push_back(ppsspp_vertex_cache.GetOptions()); vars.push_back(ppsspp_separate_io_thread.GetOptions()); @@ -266,19 +268,20 @@ static void check_variables(CoreParameter &coreParam) { ppsspp_vertex_cache.Update(&g_Config.bVertexCache); ppsspp_gpu_hardware_transform.Update(&g_Config.bHardwareTransform); ppsspp_frameskip.Update(&g_Config.iFrameSkip); + ppsspp_frameskiptype.Update(&g_Config.iFrameSkipType); ppsspp_audio_latency.Update(&g_Config.iAudioLatency); - ppsspp_true_color.Update(&g_Config.bTrueColor); ppsspp_auto_frameskip.Update(&g_Config.bAutoFrameSkip); ppsspp_block_transfer_gpu.Update(&g_Config.bBlockTransferGPU); + ppsspp_texture_filtering.Update(&g_Config.iTexFiltering); ppsspp_texture_anisotropic_filtering.Update(&g_Config.iAnisotropyLevel); ppsspp_texture_deposterize.Update(&g_Config.bTexDeposterize); + ppsspp_texture_replacement.Update(&g_Config.bReplaceTextures); ppsspp_separate_io_thread.Update(&g_Config.bSeparateIOThread); ppsspp_unsafe_func_replacements.Update(&g_Config.bFuncReplacements); ppsspp_sound_speedhack.Update(&g_Config.bSoundSpeedHack); ppsspp_cheats.Update(&g_Config.bEnableCheats); ppsspp_locked_cpu_speed.Update(&g_Config.iLockedCPUSpeed); ppsspp_rendering_mode.Update(&g_Config.iRenderingMode); - ppsspp_force_max_fps.Update(&g_Config.iForceMaxEmulatedFPS); ppsspp_cpu_core.Update((CPUCore *)&g_Config.iCpuCore); ppsspp_language.Update(&g_Config.iLanguage); diff --git a/pspautotests b/pspautotests index d02ba74070..98b83d2cb0 160000 --- a/pspautotests +++ b/pspautotests @@ -1 +1 @@ -Subproject commit d02ba7407050f445edf9e908374ad4bf3b2f237b +Subproject commit 98b83d2cb06e78c6e24f287b24a89a0ef87ac53b diff --git a/unittest/UnitTests.vcxproj b/unittest/UnitTests.vcxproj index 38b7be99b3..fa377805f9 100644 --- a/unittest/UnitTests.vcxproj +++ b/unittest/UnitTests.vcxproj @@ -96,6 +96,7 @@ false MultiThreadedDebug Common/DbgNew.h + ProgramDatabase Console @@ -118,6 +119,7 @@ MultiThreadedDebug false Common/DbgNew.h + ProgramDatabase Console