mirror of
https://github.com/libretro/pcsx_rearmed.git
synced 2024-11-26 17:30:49 +00:00
merge from libretro
got tired of all the conflicts
This commit is contained in:
parent
bd701916cc
commit
79c4d4343e
3
.gitmodules
vendored
3
.gitmodules
vendored
@ -16,3 +16,6 @@
|
||||
[submodule "deps/libretro-common"]
|
||||
path = deps/libretro-common
|
||||
url = https://github.com/libretro/libretro-common.git
|
||||
[submodule "deps/mman"]
|
||||
path = deps/mman
|
||||
url = https://github.com/witwall/mman-win32
|
||||
|
36
Makefile
36
Makefile
@ -13,7 +13,7 @@ CFLAGS += -ggdb
|
||||
endif
|
||||
ifneq ($(DEBUG), 1)
|
||||
CFLAGS += -O2
|
||||
ifndef ASSERTS
|
||||
ifneq ($(ASSERTS), 1)
|
||||
CFLAGS += -DNDEBUG
|
||||
endif
|
||||
endif
|
||||
@ -77,6 +77,28 @@ OBJS += libpcsxcore/cdriso.o libpcsxcore/cdrom.o libpcsxcore/cdrom-async.o \
|
||||
libpcsxcore/sio.o libpcsxcore/spu.o libpcsxcore/gpu.o
|
||||
OBJS += libpcsxcore/gte.o libpcsxcore/gte_nf.o libpcsxcore/gte_divider.o
|
||||
#OBJS += libpcsxcore/debug.o libpcsxcore/socket.o libpcsxcore/disr3000a.o
|
||||
|
||||
ifeq ($(WANT_ZLIB),1)
|
||||
ZLIB_DIR = deps/libchdr/deps/zlib-1.3.1
|
||||
CFLAGS += -I$(ZLIB_DIR)
|
||||
OBJS += $(ZLIB_DIR)/adler32.o \
|
||||
$(ZLIB_DIR)/compress.o \
|
||||
$(ZLIB_DIR)/crc32.o \
|
||||
$(ZLIB_DIR)/deflate.o \
|
||||
$(ZLIB_DIR)/gzclose.o \
|
||||
$(ZLIB_DIR)/gzlib.o \
|
||||
$(ZLIB_DIR)/gzread.o \
|
||||
$(ZLIB_DIR)/gzwrite.o \
|
||||
$(ZLIB_DIR)/infback.o \
|
||||
$(ZLIB_DIR)/inffast.o \
|
||||
$(ZLIB_DIR)/inflate.o \
|
||||
$(ZLIB_DIR)/inftrees.o \
|
||||
$(ZLIB_DIR)/trees.o \
|
||||
$(ZLIB_DIR)/uncompr.o \
|
||||
$(ZLIB_DIR)/zutil.o
|
||||
$(ZLIB_DIR)/%.o: CFLAGS += -DHAVE_UNISTD_H
|
||||
endif
|
||||
|
||||
ifeq "$(ARCH)" "arm"
|
||||
OBJS += libpcsxcore/gte_arm.o
|
||||
endif
|
||||
@ -209,6 +231,7 @@ endif
|
||||
# builtin gpu
|
||||
OBJS += plugins/gpulib/gpu.o plugins/gpulib/vout_pl.o
|
||||
ifeq "$(BUILTIN_GPU)" "neon"
|
||||
CFLAGS += -DGPU_NEON
|
||||
OBJS += plugins/gpu_neon/psx_gpu_if.o
|
||||
plugins/gpu_neon/psx_gpu_if.o: CFLAGS += -DNEON_BUILD -DTEXTURE_CACHE_4BPP -DTEXTURE_CACHE_8BPP
|
||||
plugins/gpu_neon/psx_gpu_if.o: plugins/gpu_neon/psx_gpu/*.c
|
||||
@ -222,13 +245,20 @@ frontend/menu.o frontend/plugin_lib.o: CFLAGS += -DBUILTIN_GPU_NEON
|
||||
endif
|
||||
endif
|
||||
ifeq "$(BUILTIN_GPU)" "peops"
|
||||
CFLAGS += -DGPU_PEOPS
|
||||
# note: code is not safe for strict-aliasing? (Castlevania problems)
|
||||
plugins/dfxvideo/gpulib_if.o: CFLAGS += -fno-strict-aliasing
|
||||
plugins/dfxvideo/gpulib_if.o: plugins/dfxvideo/prim.c plugins/dfxvideo/soft.c
|
||||
OBJS += plugins/dfxvideo/gpulib_if.o
|
||||
ifeq "$(THREAD_RENDERING)" "1"
|
||||
CFLAGS += -DTHREAD_RENDERING
|
||||
OBJS += plugins/gpulib/gpulib_thread_if.o
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq "$(BUILTIN_GPU)" "unai"
|
||||
CFLAGS += -DGPU_UNAI
|
||||
CFLAGS += -DUSE_GPULIB=1
|
||||
OBJS += plugins/gpu_unai/gpulib_if.o
|
||||
ifeq "$(ARCH)" "arm"
|
||||
OBJS += plugins/gpu_unai/gpu_arm.o
|
||||
@ -249,7 +279,7 @@ CC_LINK = $(CXX)
|
||||
endif
|
||||
|
||||
# libchdr
|
||||
#ifeq "$(HAVE_CHD)" "1"
|
||||
ifeq "$(HAVE_CHD)" "1"
|
||||
LCHDR = deps/libchdr
|
||||
LCHDR_LZMA = $(LCHDR)/deps/lzma-24.05
|
||||
LCHDR_ZSTD = $(LCHDR)/deps/zstd-1.5.6/lib
|
||||
@ -283,7 +313,7 @@ $(LCHDR_ZSTD)/decompress/%.o: CFLAGS += -I$(LCHDR_ZSTD)
|
||||
$(LCHDR)/src/%.o: CFLAGS += -I$(LCHDR_ZSTD)
|
||||
libpcsxcore/cdriso.o: CFLAGS += -Wno-unused-function
|
||||
CFLAGS += -DHAVE_CHD -I$(LCHDR)/include
|
||||
#endif
|
||||
endif
|
||||
|
||||
# frontend/gui
|
||||
OBJS += frontend/cspace.o
|
||||
|
@ -1 +1,690 @@
|
||||
$(error This file is unmaintained. Please use the libretro fork: https://github.com/libretro/pcsx_rearmed)
|
||||
# Makefile for PCSX ReARMed (libretro)
|
||||
|
||||
DEBUG ?= 0
|
||||
WANT_ZLIB ?= 1
|
||||
HAVE_CHD ?= 1
|
||||
HAVE_PHYSICAL_CDROM ?= 1
|
||||
USE_ASYNC_CDROM ?= 1
|
||||
USE_LIBRETRO_VFS ?= 0
|
||||
NDRC_THREAD ?= 1
|
||||
|
||||
# Dynarec options: lightrec, ari64
|
||||
DYNAREC ?= lightrec
|
||||
|
||||
ifeq ($(platform),)
|
||||
platform = unix
|
||||
ifeq ($(shell uname -a),)
|
||||
platform = win
|
||||
else ifneq ($(findstring MINGW,$(shell uname -a)),)
|
||||
platform = win
|
||||
else ifneq ($(findstring Darwin,$(shell uname -a)),)
|
||||
platform = osx
|
||||
else ifneq ($(findstring win,$(shell uname -a)),)
|
||||
platform = win
|
||||
endif
|
||||
endif
|
||||
|
||||
CC ?= gcc
|
||||
CXX ?= g++
|
||||
AS ?= as
|
||||
LD ?= ld
|
||||
CFLAGS ?=
|
||||
|
||||
# early compiler overrides
|
||||
ifeq ($(platform),ios-arm64)
|
||||
CC = cc -arch arm64 -isysroot $(IOSSDK)
|
||||
CXX = c++ -arch arm64 -isysroot $(IOSSDK)
|
||||
else ifneq (,$(findstring ios,$(platform)))
|
||||
CC = cc -arch armv7 -isysroot $(IOSSDK)
|
||||
CXX = c++ -arch armv7 -isysroot $(IOSSDK)
|
||||
else ifeq ($(platform), tvos-arm64)
|
||||
ifeq ($(IOSSDK),)
|
||||
IOSSDK := $(shell xcodebuild -version -sdk appletvos Path)
|
||||
endif
|
||||
CC = cc -arch arm64 -isysroot $(IOSSDK)
|
||||
CXX = c++ -arch arm64 -isysroot $(IOSSDK)
|
||||
else ifeq ($(platform), osx)
|
||||
ifeq ($(CROSS_COMPILE),1)
|
||||
TARGET_RULE = -target $(LIBRETRO_APPLE_PLATFORM) -isysroot $(LIBRETRO_APPLE_ISYSROOT)
|
||||
CFLAGS += $(TARGET_RULE)
|
||||
CXXFLAGS += $(TARGET_RULE)
|
||||
LDFLAGS += $(TARGET_RULE)
|
||||
endif
|
||||
else ifeq ($(platform), psl1ght)
|
||||
ifeq ($(strip $(PS3DEV)),)
|
||||
$(error "PS3DEV env var is not set")
|
||||
endif
|
||||
CC = $(PS3DEV)/ppu/bin/ppu-gcc$(EXE_EXT)
|
||||
AR = $(PS3DEV)/ppu/bin/ppu-ar$(EXE_EXT)
|
||||
else ifeq ($(platform), psp1)
|
||||
CC = psp-gcc$(EXE_EXT)
|
||||
AR = psp-ar$(EXE_EXT)
|
||||
LD = psp-ld$(EXE_EXT)
|
||||
else ifeq ($(platform), vita)
|
||||
CC = arm-vita-eabi-gcc$(EXE_EXT)
|
||||
AR = arm-vita-eabi-ar$(EXE_EXT)
|
||||
LD = arm-vita-eabi-ld$(EXE_EXT)
|
||||
OBJCOPY = arm-vita-eabi-objcopy$(EXE_EXT)
|
||||
else ifeq ($(platform), ctr)
|
||||
ifeq ($(strip $(DEVKITARM)),)
|
||||
$(error "DEVKITARM env var is not set")
|
||||
endif
|
||||
CC = $(DEVKITARM)/bin/arm-none-eabi-gcc$(EXE_EXT)
|
||||
CXX = $(DEVKITARM)/bin/arm-none-eabi-g++$(EXE_EXT)
|
||||
AR = $(DEVKITARM)/bin/arm-none-eabi-ar$(EXE_EXT)
|
||||
LD = $(DEVKITARM)/bin/arm-none-eabi-ld$(EXE_EXT)
|
||||
OBJCOPY = $(DEVKITARM)/bin/arm-none-eabi-objcopy$(EXE_EXT)
|
||||
else ifeq ($(platform), libnx)
|
||||
export DEPSDIR := $(CURDIR)/
|
||||
ifeq ($(strip $(DEVKITPRO)),)
|
||||
$(error "DEVKITPRO env var is not set")
|
||||
endif
|
||||
include $(DEVKITPRO)/libnx/switch_rules
|
||||
SHELL := PATH=$(PATH) $(SHELL)
|
||||
LD = $(PREFIX)ld
|
||||
else ifeq ($(platform), xenon)
|
||||
CC = xenon-gcc$(EXE_EXT)
|
||||
AR = xenon-ar$(EXE_EXT)
|
||||
LD = xenon-ld$(EXE_EXT)
|
||||
else ifneq (,$(filter $(platform),ngc wii wiiu))
|
||||
ifeq ($(strip $(DEVKITPPC)),)
|
||||
$(error "DEVKITPPC env var is not set")
|
||||
endif
|
||||
CC = $(DEVKITPPC)/bin/powerpc-eabi-gcc$(EXE_EXT)
|
||||
CXX = $(DEVKITPPC)/bin/powerpc-eabi-g++$(EXE_EXT)
|
||||
AR = $(DEVKITPPC)/bin/powerpc-eabi-ar$(EXE_EXT)
|
||||
LD = $(DEVKITPPC)/bin/powerpc-eabi-ld$(EXE_EXT)
|
||||
else ifeq ($(platform), qnx)
|
||||
CC = qcc -Vgcc_ntoarmv7le
|
||||
else ifeq ($(platform), miyoo)
|
||||
CC = /opt/miyoo/usr/bin/arm-linux-gcc
|
||||
CXX = /opt/miyoo/usr/bin/arm-linux-g++
|
||||
endif
|
||||
CC_AS ?= $(CC)
|
||||
|
||||
# workaround wrong owner in libretro infra
|
||||
GIT_VERSION1 := $(shell test -d /builds/libretro/pcsx_rearmed && git rev-parse --short HEAD 2>&1)
|
||||
ifneq ($(findstring dubious ownership,$(GIT_VERSION1)),)
|
||||
DUMMY := $(shell git config --global --add safe.directory /builds/libretro/pcsx_rearmed)
|
||||
endif
|
||||
|
||||
TARGET_NAME := pcsx_rearmed
|
||||
ARCH_DETECTED := $(shell $(CC) $(CFLAGS) -dumpmachine | awk -F- '{print $$1}')
|
||||
GIT_VERSION := " $(shell git rev-parse --short HEAD || echo unknown)"
|
||||
ifneq ($(GIT_VERSION)," unknown")
|
||||
CFLAGS += -DGIT_VERSION=\"$(GIT_VERSION)\"
|
||||
endif
|
||||
ifneq ($(WANT_ZLIB),1)
|
||||
LIBZ := -lz
|
||||
endif
|
||||
LIBPTHREAD := -lpthread
|
||||
ifneq ($(findstring Haiku,$(shell uname -s)),)
|
||||
LIBDL := -lroot -lnetwork
|
||||
else
|
||||
LIBDL := -ldl
|
||||
endif
|
||||
LIBM := -lm
|
||||
MMAP_WIN32 = 0
|
||||
EXTRA_LDFLAGS =
|
||||
|
||||
# select some defaults
|
||||
ifneq (,$(findstring $(ARCH_DETECTED),arm aarch64))
|
||||
DYNAREC = ari64
|
||||
ifneq (,$(shell $(CC) -E -dD $(CFLAGS) include/arm_features.h | grep 'define __thumb__'))
|
||||
# must disable thumb as ari64 can't handle it
|
||||
CFLAGS += -marm
|
||||
endif
|
||||
ifneq (,$(shell $(CC) -E -dD $(CFLAGS) include/arm_features.h | grep 'HAVE_NEON32'))
|
||||
BUILTIN_GPU = neon
|
||||
endif
|
||||
endif
|
||||
ifneq (,$(filter $(ARCH_DETECTED),i686 x86_64 arm64 aarch64))
|
||||
BUILTIN_GPU = neon
|
||||
endif
|
||||
|
||||
# platform specific options
|
||||
|
||||
# Unix
|
||||
ifeq ($(platform), unix)
|
||||
TARGET := $(TARGET_NAME)_libretro.so
|
||||
fpic := -fPIC
|
||||
THREAD_RENDERING = 1
|
||||
ifeq ($(shell uname),Linux)
|
||||
LIGHTREC_CUSTOM_MAP := 1
|
||||
endif
|
||||
|
||||
# ODROIDN2
|
||||
else ifneq (,$(findstring CortexA73_G12B,$(platform)))
|
||||
TARGET := $(TARGET_NAME)_libretro.so
|
||||
fpic := -fPIC
|
||||
ARCH = arm64
|
||||
BUILTIN_GPU = neon
|
||||
HAVE_NEON = 1
|
||||
DYNAREC = ari64
|
||||
CFLAGS += -fomit-frame-pointer -ffast-math -DARM
|
||||
CFLAGS += -march=armv8-a+crc -mcpu=cortex-a73 -mtune=cortex-a73.cortex-a53
|
||||
|
||||
# ALLWINNER H5
|
||||
else ifneq (,$(findstring h5,$(platform)))
|
||||
TARGET := $(TARGET_NAME)_libretro.so
|
||||
fpic := -fPIC
|
||||
ARCH = arm64
|
||||
BUILTIN_GPU = neon
|
||||
HAVE_NEON = 1
|
||||
DYNAREC = ari64
|
||||
CFLAGS += -fomit-frame-pointer -ffast-math -DARM
|
||||
CFLAGS += -march=armv8-a+crc -mcpu=cortex-a53 -mtune=cortex-a53
|
||||
|
||||
else ifeq ($(platform), linux-portable)
|
||||
TARGET := $(TARGET_NAME)_libretro.so
|
||||
fpic := -fPIC -nostdlib
|
||||
EXTRA_LDFLAGS += -fPIC -nostdlib
|
||||
LIBZ :=
|
||||
LIBPTHREAD :=
|
||||
LIBDL :=
|
||||
LIBM :=
|
||||
NO_UNDEF_CHECK = 1
|
||||
LIGHTREC_CUSTOM_MAP := 1
|
||||
|
||||
# OS X
|
||||
else ifeq ($(platform), osx)
|
||||
DYNAREC := 0
|
||||
TARGET := $(TARGET_NAME)_libretro.dylib
|
||||
fpic := -fPIC
|
||||
MACSOSVER = `sw_vers -productVersion | cut -d. -f 1`
|
||||
OSXVER = `sw_vers -productVersion | cut -d. -f 2`
|
||||
OSX_LT_MAVERICKS = `(( $(OSXVER) <= 9)) && echo "YES"`
|
||||
ifeq ($(OSX_LT_MAVERICKS),YES)
|
||||
fpic += -mmacosx-version-min=10.1
|
||||
endif
|
||||
CFLAGS += $(ARCHFLAGS)
|
||||
CXXFLAGS += $(ARCHFLAGS)
|
||||
LDFLAGS += $(ARCHFLAGS)
|
||||
HAVE_PHYSICAL_CDROM = 0
|
||||
FSECTIONS_LDFLAGS = -Wl,-dead_strip
|
||||
|
||||
# iOS
|
||||
else ifneq (,$(findstring ios,$(platform)))
|
||||
TARGET := $(TARGET_NAME)_libretro_ios.dylib
|
||||
MINVERSION :=
|
||||
ifeq ($(DYNAREC),lightrec)
|
||||
# Override
|
||||
DYNAREC := 0
|
||||
endif
|
||||
fpic := -fPIC
|
||||
|
||||
ifeq ($(IOSSDK),)
|
||||
IOSSDK := $(shell xcodebuild -version -sdk iphoneos Path)
|
||||
endif
|
||||
|
||||
CFLAGS += -DIOS
|
||||
ifeq ($(platform),ios-arm64)
|
||||
ARCH := arm64
|
||||
BUILTIN_GPU = neon
|
||||
HAVE_NEON = 1
|
||||
DYNAREC = 0
|
||||
else
|
||||
ARCH := arm
|
||||
HAVE_NEON = 1
|
||||
HAVE_NEON_ASM = 1
|
||||
BUILTIN_GPU = neon
|
||||
CFLAGS += -marm -mcpu=cortex-a8 -mtune=cortex-a8 -mfpu=neon
|
||||
ASFLAGS += -marm -mcpu=cortex-a8 -mtune=cortex-a8 -mfpu=neon
|
||||
endif
|
||||
HAVE_PHYSICAL_CDROM = 0
|
||||
CC_AS = perl ./tools/gas-preprocessor.pl $(CC)
|
||||
ifeq ($(platform),$(filter $(platform),ios9 ios-arm64))
|
||||
MINVERSION = -miphoneos-version-min=8.0
|
||||
else
|
||||
MINVERSION = -miphoneos-version-min=5.0
|
||||
endif
|
||||
CFLAGS += $(MINVERSION)
|
||||
FSECTIONS_LDFLAGS = -Wl,-dead_strip
|
||||
|
||||
else ifeq ($(platform), tvos-arm64)
|
||||
TARGET := $(TARGET_NAME)_libretro_tvos.dylib
|
||||
MINVERSION :=
|
||||
ifeq ($(DYNAREC),lightrec)
|
||||
# Override
|
||||
DYNAREC := 0
|
||||
endif
|
||||
fpic := -fPIC
|
||||
|
||||
ifeq ($(IOSSDK),)
|
||||
IOSSDK := $(shell xcodebuild -version -sdk appletvos Path)
|
||||
endif
|
||||
|
||||
CFLAGS += -DIOS -DTVOS
|
||||
ARCH := arm64
|
||||
BUILTIN_GPU = neon
|
||||
HAVE_NEON = 1
|
||||
DYNAREC = 0
|
||||
HAVE_PHYSICAL_CDROM = 0
|
||||
CC_AS = perl ./tools/gas-preprocessor.pl $(CC)
|
||||
MINVERSION = -mappletvos-version-min=11.0
|
||||
CFLAGS += $(MINVERSION)
|
||||
FSECTIONS_LDFLAGS = -Wl,-dead_strip
|
||||
|
||||
# Nintendo Switch (libnx)
|
||||
else ifeq ($(platform), libnx)
|
||||
TARGET := $(TARGET_NAME)_libretro_$(platform).a
|
||||
ARCH := arm64
|
||||
HAVE_VFS_FD = 0
|
||||
CFLAGS += -O3 -fomit-frame-pointer -ffast-math -I$(DEVKITPRO)/libnx/include/ -fPIE
|
||||
CFLAGS += -specs=$(DEVKITPRO)/libnx/switch.specs -DNO_DYLIB -D__arm64__ -D__ARM_NEON__
|
||||
CFLAGS += -D__SWITCH__ -DSWITCH -DHAVE_LIBNX
|
||||
CFLAGS += -DARM -D__aarch64__=1 -march=armv8-a -mtune=cortex-a57 -mtp=soft -DHAVE_INTTYPES -DLSB_FIRST -ffast-math -mcpu=cortex-a57+crc+fp+simd
|
||||
CFLAGS += -ftree-vectorize
|
||||
CFLAGS += -Ifrontend/switch
|
||||
NO_POSIX_MEMALIGN := 1
|
||||
NO_PTHREAD=1
|
||||
NO_MMAP := 1 # for psxmem
|
||||
LIBPTHREAD :=
|
||||
WANT_ZLIB = 0
|
||||
PARTIAL_LINKING = 1
|
||||
BUILTIN_GPU = neon
|
||||
HAVE_NEON = 1
|
||||
DYNAREC = ari64
|
||||
HAVE_PHYSICAL_CDROM = 0
|
||||
|
||||
# Lakka Switch (arm64)
|
||||
else ifeq ($(platform), arm64)
|
||||
TARGET := $(TARGET_NAME)_libretro.so
|
||||
ARCH := arm64
|
||||
BUILTIN_GPU = neon
|
||||
HAVE_NEON = 1
|
||||
DYNAREC = ari64
|
||||
HAVE_PHYSICAL_CDROM = 0
|
||||
fpic := -fPIC
|
||||
CFLAGS := $(filter-out -O2, $(CFLAGS))
|
||||
CFLAGS += -O3 -ftree-vectorize
|
||||
|
||||
# Lightweight PS3 Homebrew SDK
|
||||
else ifeq ($(platform), psl1ght)
|
||||
TARGET := $(TARGET_NAME)_libretro_psl1ght.a
|
||||
CFLAGS += -DBLARGG_BIG_ENDIAN=1 -D__ppc__
|
||||
CFLAGS += -DNO_DYLIB
|
||||
NO_UNDEF_CHECK := 1
|
||||
STATIC_LINKING := 1
|
||||
NO_MMAP := 1
|
||||
NO_PTHREAD := 1
|
||||
LIBPTHREAD :=
|
||||
LIBDL :=
|
||||
NEED_SYSCONF := 1
|
||||
HAVE_PHYSICAL_CDROM = 0
|
||||
USE_ASYNC_CDROM = 0
|
||||
|
||||
# PSP
|
||||
else ifeq ($(platform), psp1)
|
||||
TARGET := $(TARGET_NAME)_libretro_psp1.a
|
||||
CFLAGS += -DPSP -G0
|
||||
HAVE_PHYSICAL_CDROM = 0
|
||||
|
||||
# Vita
|
||||
else ifeq ($(platform), vita)
|
||||
TARGET := $(TARGET_NAME)_libretro_vita.a
|
||||
CFLAGS += -DVITA
|
||||
CFLAGS += -mcpu=cortex-a9 -mtune=cortex-a9 -mfpu=neon -marm
|
||||
CFLAGS += -fsingle-precision-constant -mword-relocations -fno-unwind-tables
|
||||
CFLAGS += -fno-asynchronous-unwind-tables -ftree-vectorize -funroll-loops
|
||||
CFLAGS += -fno-optimize-sibling-calls
|
||||
CFLAGS += -I$(VITASDK)/include -Ifrontend/vita
|
||||
CFLAGS += -DNO_DYLIB
|
||||
CFLAGS_LAST += -O3
|
||||
ASFLAGS += -mcpu=cortex-a9 -mtune=cortex-a9 -mfpu=neon
|
||||
|
||||
HAVE_NEON = 1
|
||||
HAVE_NEON_ASM = 1
|
||||
BUILTIN_GPU = neon
|
||||
|
||||
DYNAREC = ari64
|
||||
ARCH = arm
|
||||
PARTIAL_LINKING = 1
|
||||
NO_PTHREAD=1
|
||||
NO_POSIX_MEMALIGN := 1
|
||||
HAVE_PHYSICAL_CDROM = 0
|
||||
|
||||
# CTR(3DS)
|
||||
else ifeq ($(platform), ctr)
|
||||
ifeq ($(strip $(CTRULIB)),)
|
||||
$(error "CTRULIB env var is not set")
|
||||
endif
|
||||
TARGET := $(TARGET_NAME)_libretro_ctr.a
|
||||
CFLAGS += -DARM11 -D_3DS -D__3DS__
|
||||
CFLAGS += -DNO_DYLIB -DGPU_UNAI_USE_FLOATMATH -DGPU_UNAI_USE_FLOAT_DIV_MULTINV
|
||||
CFLAGS += -march=armv6k -mtune=mpcore -mfloat-abi=hard -marm -mfpu=vfp -mtp=soft
|
||||
CFLAGS += -Wall -mword-relocations
|
||||
CFLAGS += -fomit-frame-pointer
|
||||
CFLAGS_LAST += -O3
|
||||
# CFLAGS += -funroll-loops # ~500K of bloat
|
||||
CFLAGS += -Ifrontend/3ds -I$(CTRULIB)/include
|
||||
CFLAGS += -Werror=implicit-function-declaration
|
||||
CFLAGS += -DHAVE_UNISTD_H
|
||||
CFLAGS += -DZ7_DECL_Int32_AS_long
|
||||
CFLAGS += -DUSE_CTRULIB_2
|
||||
|
||||
OBJS += deps/arm-mem/memcpymove-v6l.o
|
||||
OBJS += deps/arm-mem/memset-v6l.o
|
||||
OBJS += frontend/3ds/utils.o
|
||||
|
||||
BUILTIN_GPU = unai
|
||||
THREAD_RENDERING = 1
|
||||
DYNAREC = ari64
|
||||
ARCH = arm
|
||||
HAVE_NEON = 0
|
||||
PARTIAL_LINKING = 1
|
||||
WANT_ZLIB = 0
|
||||
NO_POSIX_MEMALIGN := 1
|
||||
NO_MMAP := 1 # for psxmem
|
||||
HAVE_PHYSICAL_CDROM = 0
|
||||
|
||||
# Xbox 360
|
||||
else ifeq ($(platform), xenon)
|
||||
TARGET := $(TARGET_NAME)_libretro_xenon360.a
|
||||
CFLAGS += -D__LIBXENON__ -m32 -D__ppc__
|
||||
HAVE_PHYSICAL_CDROM = 0
|
||||
|
||||
# Nintendo GC/Wii/WiiU
|
||||
else ifneq (,$(filter $(platform),ngc wii wiiu))
|
||||
TARGET := $(TARGET_NAME)_libretro_$(platform).a
|
||||
ifeq ($(platform), ngc)
|
||||
CFLAGS += -DHW_DOL -mogc
|
||||
NEED_SYSCONF := 1
|
||||
else ifeq ($(platform), wii)
|
||||
CFLAGS += -DHW_RVL -mrvl
|
||||
NEED_SYSCONF := 1
|
||||
else ifeq ($(platform), wiiu)
|
||||
# -mwup was removed in newer devkitPPC versions
|
||||
CFLAGS += -DHW_WUP
|
||||
CFLAGS += -I frontend/wiiu
|
||||
CFLAGS += -DZ7_DECL_Int32_AS_long
|
||||
LIGHTREC_CUSTOM_MAP := 1
|
||||
LIGHTREC_CUSTOM_MAP_OBJ := libpcsxcore/lightrec/mem_wiiu.o
|
||||
LIGHTREC_CODE_INV := 1
|
||||
endif
|
||||
ARCH = powerpc
|
||||
BUILTIN_GPU = peops
|
||||
CFLAGS += -D__ppc__ -D__powerpc__
|
||||
CFLAGS += -DGEKKO -mcpu=750 -meabi -mhard-float
|
||||
CFLAGS += -DNO_DYLIB
|
||||
STATIC_LINKING := 1
|
||||
THREAD_RENDERING := 0
|
||||
NO_PTHREAD := 1
|
||||
NO_MMAP := 1
|
||||
NO_POSIX_MEMALIGN := 1
|
||||
LIBDL :=
|
||||
LIBPTHREAD :=
|
||||
LIBRT :=
|
||||
HAVE_PHYSICAL_CDROM = 0
|
||||
USE_ASYNC_CDROM = 0
|
||||
|
||||
# QNX
|
||||
else ifeq ($(platform), qnx)
|
||||
TARGET := $(TARGET_NAME)_libretro_qnx.so
|
||||
fpic := -fPIC
|
||||
HAVE_NEON = 1
|
||||
HAVE_NEON_ASM = 1
|
||||
DYNAREC = ari64
|
||||
BUILTIN_GPU = neon
|
||||
ARCH = arm
|
||||
CFLAGS += -D__BLACKBERRY_QNX__ -marm -mcpu=cortex-a9 -mtune=cortex-a9 -mfpu=neon -mfloat-abi=softfp
|
||||
ASFLAGS += -mcpu=cortex-a9 -mfpu=neon -mfloat-abi=softfp
|
||||
MAIN_LDLIBS += -lsocket
|
||||
LIBPTHREAD :=
|
||||
LIBDL :=
|
||||
LIBM :=
|
||||
HAVE_PHYSICAL_CDROM = 0
|
||||
|
||||
#Raspberry Pi 1
|
||||
else ifeq ($(platform), rpi1)
|
||||
TARGET := $(TARGET_NAME)_libretro.so
|
||||
fpic := -fPIC
|
||||
CFLAGS += -marm -mcpu=arm1176jzf-s -mfpu=vfp -mfloat-abi=hard
|
||||
ASFLAGS += -mcpu=arm1176jzf-s -mfpu=vfp -mfloat-abi=hard
|
||||
HAVE_NEON = 0
|
||||
ARCH = arm
|
||||
BUILTIN_GPU = unai
|
||||
DYNAREC = ari64
|
||||
|
||||
#Raspberry Pi 2
|
||||
else ifeq ($(platform), rpi2)
|
||||
TARGET := $(TARGET_NAME)_libretro.so
|
||||
fpic := -fPIC
|
||||
CFLAGS += -marm -mcpu=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard
|
||||
ASFLAGS += -mcpu=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard
|
||||
HAVE_NEON = 1
|
||||
HAVE_NEON_ASM = 1
|
||||
ARCH = arm
|
||||
BUILTIN_GPU = neon
|
||||
DYNAREC = ari64
|
||||
|
||||
#Raspberry Pi 3
|
||||
else ifeq ($(platform), rpi3)
|
||||
TARGET := $(TARGET_NAME)_libretro.so
|
||||
fpic := -fPIC
|
||||
CFLAGS += -marm -mcpu=cortex-a53 -mfpu=neon-fp-armv8 -mfloat-abi=hard
|
||||
ASFLAGS += -mcpu=cortex-a53 -mfpu=neon-fp-armv8 -mfloat-abi=hard
|
||||
HAVE_NEON = 1
|
||||
HAVE_NEON_ASM = 1
|
||||
ARCH = arm
|
||||
BUILTIN_GPU = neon
|
||||
DYNAREC = ari64
|
||||
|
||||
#Raspberry Pi 3 with a 64bit GNU/Linux OS
|
||||
else ifeq ($(platform), rpi3_64)
|
||||
TARGET := $(TARGET_NAME)_libretro.so
|
||||
ARCH := arm64
|
||||
BUILTIN_GPU = neon
|
||||
HAVE_NEON = 1
|
||||
DYNAREC = ari64
|
||||
fpic := -fPIC
|
||||
CFLAGS += -march=armv8-a+crc+simd -mtune=cortex-a53 -ftree-vectorize
|
||||
|
||||
#Raspberry Pi 4 with a 32bit GNU/Linux OS
|
||||
else ifeq ($(platform), rpi4)
|
||||
TARGET := $(TARGET_NAME)_libretro.so
|
||||
fpic := -fPIC
|
||||
CFLAGS += -marm -mcpu=cortex-a72 -mfpu=neon-fp-armv8 -mfloat-abi=hard
|
||||
ASFLAGS += -mcpu=cortex-a72 -mfpu=neon-fp-armv8 -mfloat-abi=hard
|
||||
HAVE_NEON = 1
|
||||
HAVE_NEON_ASM = 1
|
||||
ARCH = arm
|
||||
BUILTIN_GPU = neon
|
||||
DYNAREC = ari64
|
||||
|
||||
#Raspberry Pi 4 with a 64bit GNU/Linux OS
|
||||
else ifeq ($(platform), rpi4_64)
|
||||
TARGET := $(TARGET_NAME)_libretro.so
|
||||
ARCH := arm64
|
||||
BUILTIN_GPU = neon
|
||||
HAVE_NEON = 1
|
||||
DYNAREC = ari64
|
||||
fpic := -fPIC
|
||||
CFLAGS += -march=armv8-a+crc+simd -mtune=cortex-a72 -ftree-vectorize
|
||||
|
||||
# Classic Platforms ####################
|
||||
# Platform affix = classic_<ISA>_<µARCH>
|
||||
# Help at https://modmyclassic.com/comp
|
||||
|
||||
# (armv7 a7, hard point, neon based) ###
|
||||
# NESC, SNESC, C64 mini
|
||||
else ifeq ($(platform), classic_armv7_a7)
|
||||
TARGET := $(TARGET_NAME)_libretro.so
|
||||
fpic := -fPIC
|
||||
CFLAGS += -Ofast \
|
||||
-flto=auto -fuse-linker-plugin \
|
||||
-fno-stack-protector -fno-ident -fomit-frame-pointer \
|
||||
-falign-functions=1 -falign-jumps=1 -falign-loops=1 \
|
||||
-fno-unwind-tables -fno-asynchronous-unwind-tables -fno-unroll-loops \
|
||||
-fmerge-all-constants -fno-math-errno \
|
||||
-marm -mtune=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard
|
||||
CXXFLAGS += $(CFLAGS)
|
||||
CPPFLAGS += $(CFLAGS)
|
||||
ASFLAGS += $(CFLAGS)
|
||||
HAVE_NEON = 1
|
||||
HAVE_NEON_ASM = 1
|
||||
ARCH = arm
|
||||
BUILTIN_GPU = neon
|
||||
DYNAREC = ari64
|
||||
ifeq ($(shell echo `$(CC) -dumpversion` "< 4.9" | bc -l), 1)
|
||||
CFLAGS += -march=armv7-a
|
||||
else
|
||||
CFLAGS += -march=armv7ve
|
||||
# If gcc is 5.0 or later
|
||||
ifeq ($(shell echo `$(CC) -dumpversion` ">= 5" | bc -l), 1)
|
||||
LDFLAGS += -static-libgcc -static-libstdc++
|
||||
endif
|
||||
endif
|
||||
|
||||
# (armv8 a35, hard point, neon based) ###
|
||||
# PlayStation Classic
|
||||
else ifeq ($(platform), classic_armv8_a35)
|
||||
TARGET := $(TARGET_NAME)_libretro.so
|
||||
fpic := -fPIC
|
||||
CFLAGS += -Ofast \
|
||||
-fmerge-all-constants -fno-math-errno \
|
||||
-fno-stack-protector -fomit-frame-pointer \
|
||||
-marm -mcpu=cortex-a35 -mtune=cortex-a35 -mfpu=neon-fp-armv8 -mfloat-abi=hard
|
||||
HAVE_NEON = 1
|
||||
HAVE_NEON_ASM = 1
|
||||
ARCH = arm
|
||||
BUILTIN_GPU = neon
|
||||
DYNAREC = ari64
|
||||
LDFLAGS += -static-libgcc -static-libstdc++ -fPIC
|
||||
|
||||
#######################################
|
||||
|
||||
# ARM
|
||||
else ifneq (,$(findstring armv,$(platform)))
|
||||
TARGET := $(TARGET_NAME)_libretro.so
|
||||
fpic := -fPIC
|
||||
HAVE_NEON = 0
|
||||
BUILTIN_GPU = peops
|
||||
ifneq (,$(findstring cortexa8,$(platform)))
|
||||
CFLAGS += -mcpu=cortex-a8
|
||||
ASFLAGS += -mcpu=cortex-a8
|
||||
else ifneq (,$(findstring cortexa7,$(platform)))
|
||||
CFLAGS += -mcpu=cortex-a7
|
||||
ASFLAGS += -mcpu=cortex-a7
|
||||
LIBZ :=
|
||||
else ifneq (,$(findstring cortexa9,$(platform)))
|
||||
CFLAGS += -mcpu=cortex-a9
|
||||
ASFLAGS += -mcpu=cortex-a9
|
||||
endif
|
||||
CFLAGS += -marm
|
||||
ifneq (,$(findstring neon,$(platform)))
|
||||
CFLAGS += -mfpu=neon
|
||||
ASFLAGS += -mfpu=neon
|
||||
HAVE_NEON = 1
|
||||
HAVE_NEON_ASM = 1
|
||||
BUILTIN_GPU = neon
|
||||
endif
|
||||
ifneq (,$(findstring softfloat,$(platform)))
|
||||
CFLAGS += -mfloat-abi=softfp
|
||||
ASFLAGS += -mfloat-abi=softfp
|
||||
else ifneq (,$(findstring hardfloat,$(platform)))
|
||||
CFLAGS += -mfloat-abi=hard
|
||||
ASFLAGS += -mfloat-abi=hard
|
||||
endif
|
||||
ARCH = arm
|
||||
DYNAREC = ari64
|
||||
|
||||
else ifeq ($(platform), miyoo)
|
||||
TARGET := $(TARGET_NAME)_libretro.so
|
||||
fpic := -fPIC
|
||||
CFLAGS += -mcpu=arm926ej-s -fsingle-precision-constant
|
||||
CFLAGS += -DGPU_UNAI_USE_INT_DIV_MULTINV -D_MIYOO
|
||||
ARCH = arm
|
||||
BUILTIN_GPU = unai
|
||||
DYNAREC = ari64
|
||||
HAVE_NEON = 0
|
||||
|
||||
# Emscripten
|
||||
else ifeq ($(platform), emscripten)
|
||||
TARGET := $(TARGET_NAME)_libretro_$(platform).bc
|
||||
fpic := -fPIC
|
||||
NO_MMAP = 1
|
||||
CFLAGS += -DNO_DYLIB -DNO_SOCKET
|
||||
CFLAGS += -msimd128 -ftree-vectorize
|
||||
LIBPTHREAD :=
|
||||
NO_PTHREAD=1
|
||||
DYNAREC =
|
||||
STATIC_LINKING = 1
|
||||
HAVE_PHYSICAL_CDROM = 0
|
||||
|
||||
# Windows
|
||||
else
|
||||
TARGET := $(TARGET_NAME)_libretro.dll
|
||||
PLATFORM = libretro
|
||||
MAIN_LDFLAGS += -static-libgcc -static-libstdc++
|
||||
ifneq ($(DEBUG),1)
|
||||
MAIN_LDFLAGS += -s
|
||||
endif
|
||||
CFLAGS += -D__WIN32__ -DNO_DYLIB
|
||||
MMAP_WIN32=1
|
||||
NO_PTHREAD=1
|
||||
MAIN_LDLIBS += -lws2_32
|
||||
LIBPTHREAD :=
|
||||
LIBDL :=
|
||||
LIBM :=
|
||||
USE_LIBRETRO_VFS = 1
|
||||
endif
|
||||
|
||||
CFLAGS += $(fpic)
|
||||
MAIN_LDFLAGS += -shared
|
||||
MAIN_LDLIBS += $(LIBPTHREAD) $(LIBM) $(LIBDL) $(LIBZ)
|
||||
|
||||
# enable large file support if available
|
||||
ifeq ($(shell $(CC) -E -dD $(CFLAGS) include/arm_features.h | grep __SIZEOF_LONG__ | awk '{print $$3}'),4)
|
||||
CFLAGS += -D_FILE_OFFSET_BITS=64
|
||||
endif
|
||||
|
||||
# try to autodetect stuff for the lazy
|
||||
ifndef ARCH
|
||||
ARCH = $(ARCH_DETECTED)
|
||||
endif
|
||||
ifndef HAVE_NEON_ASM
|
||||
# asm for 32bit only
|
||||
HAVE_NEON_ASM = $(shell $(CC) -E -dD $(CFLAGS) include/arm_features.h | grep -q HAVE_NEON32 && echo 1 || echo 0)
|
||||
endif
|
||||
ifeq ($(NO_UNDEF_CHECK)$(shell $(LD) -v 2> /dev/null | awk '{print $$1}'),GNU)
|
||||
ifeq (,$(findstring $(platform),win32))
|
||||
MAIN_LDFLAGS += -Wl,-version-script=frontend/libretro-version-script
|
||||
endif
|
||||
MAIN_LDFLAGS += -Wl,--no-undefined
|
||||
endif
|
||||
ifdef ALLOW_LIGHTREC_ON_ARM
|
||||
CFLAGS += -DALLOW_LIGHTREC_ON_ARM
|
||||
endif
|
||||
ifeq ($(BUILTIN_GPU),neon)
|
||||
ifneq (,$(findstring $(ARCH),x86 i686))
|
||||
CFLAGS_GPU_NEON ?= -msse2 # required
|
||||
endif
|
||||
ifeq ($(ARCH),x86_64)
|
||||
CFLAGS_GPU_NEON ?= -mssse3 # optional, for more perf
|
||||
endif
|
||||
CFLAGS += $(CFLAGS_GPU_NEON)
|
||||
endif
|
||||
|
||||
TARGET ?= libretro.so
|
||||
PLATFORM = libretro
|
||||
BUILTIN_GPU ?= peops
|
||||
SOUND_DRIVERS = libretro
|
||||
PLUGINS =
|
||||
NO_CONFIG_MAK = yes
|
||||
|
||||
$(info TARGET: $(TARGET))
|
||||
$(info platform: $(platform))
|
||||
$(info ARCH: $(ARCH))
|
||||
$(info DYNAREC: $(DYNAREC))
|
||||
$(info BUILTIN_GPU: $(BUILTIN_GPU))
|
||||
$(info CC: $(CC) : $(shell $(CC) --version | head -1))
|
||||
$(info CFLAGS: $(CFLAGS))
|
||||
$(info MAIN_LDLIBS: $(MAIN_LDLIBS))
|
||||
$(info )
|
||||
|
||||
include Makefile
|
||||
|
||||
# no special AS needed for gpu_neon
|
||||
plugins/gpu_neon/psx_gpu/psx_gpu_arm_neon.o: plugins/gpu_neon/psx_gpu/psx_gpu_arm_neon.S
|
||||
$(CC) $(CFLAGS) -c $^ -o $@
|
||||
|
1
deps/mman
vendored
Submodule
1
deps/mman
vendored
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit 2d1c576e62b99e85d99407e1a88794c6e44c3310
|
1
include/mman/sys/mman.h
Normal file
1
include/mman/sys/mman.h
Normal file
@ -0,0 +1 @@
|
||||
#include <mman.h>
|
265
jni/Android.mk
265
jni/Android.mk
@ -1 +1,264 @@
|
||||
$(error This file is unmaintained. Please use the libretro fork: https://github.com/libretro/pcsx_rearmed)
|
||||
LOCAL_PATH := $(call my-dir)
|
||||
|
||||
$(shell cd "$(LOCAL_PATH)" && ((git describe --always || echo) | sed -e 's/.*/#define REV "\0"/' > ../frontend/revision.h_))
|
||||
$(shell cd "$(LOCAL_PATH)" && (diff -q ../frontend/revision.h_ ../frontend/revision.h > /dev/null 2>&1 || cp ../frontend/revision.h_ ../frontend/revision.h))
|
||||
$(shell cd "$(LOCAL_PATH)" && (rm ../frontend/revision.h_))
|
||||
|
||||
USE_LIBRETRO_VFS ?= 0
|
||||
USE_ASYNC_CDROM ?= 1
|
||||
USE_RTHREADS ?= 0
|
||||
NDRC_THREAD ?= 1
|
||||
|
||||
ROOT_DIR := $(LOCAL_PATH)/..
|
||||
CORE_DIR := $(ROOT_DIR)/libpcsxcore
|
||||
SPU_DIR := $(ROOT_DIR)/plugins/dfsound
|
||||
GPU_DIR := $(ROOT_DIR)/plugins/gpulib
|
||||
CDR_DIR := $(ROOT_DIR)/plugins/cdrcimg
|
||||
FRONTEND_DIR := $(ROOT_DIR)/frontend
|
||||
NEON_DIR := $(ROOT_DIR)/plugins/gpu_neon
|
||||
UNAI_DIR := $(ROOT_DIR)/plugins/gpu_unai
|
||||
PEOPS_DIR := $(ROOT_DIR)/plugins/dfxvideo
|
||||
DYNAREC_DIR := $(ROOT_DIR)/libpcsxcore/new_dynarec
|
||||
DEPS_DIR := $(ROOT_DIR)/deps
|
||||
LIBRETRO_COMMON := $(DEPS_DIR)/libretro-common
|
||||
EXTRA_INCLUDES :=
|
||||
|
||||
# core
|
||||
SOURCES_C := $(CORE_DIR)/cdriso.c \
|
||||
$(CORE_DIR)/cdrom.c \
|
||||
$(CORE_DIR)/cdrom-async.c \
|
||||
$(CORE_DIR)/cheat.c \
|
||||
$(CORE_DIR)/database.c \
|
||||
$(CORE_DIR)/decode_xa.c \
|
||||
$(CORE_DIR)/mdec.c \
|
||||
$(CORE_DIR)/misc.c \
|
||||
$(CORE_DIR)/plugins.c \
|
||||
$(CORE_DIR)/ppf.c \
|
||||
$(CORE_DIR)/psxbios.c \
|
||||
$(CORE_DIR)/psxcommon.c \
|
||||
$(CORE_DIR)/psxcounters.c \
|
||||
$(CORE_DIR)/psxdma.c \
|
||||
$(CORE_DIR)/psxevents.c \
|
||||
$(CORE_DIR)/psxhw.c \
|
||||
$(CORE_DIR)/psxinterpreter.c \
|
||||
$(CORE_DIR)/psxmem.c \
|
||||
$(CORE_DIR)/r3000a.c \
|
||||
$(CORE_DIR)/sio.c \
|
||||
$(CORE_DIR)/spu.c \
|
||||
$(CORE_DIR)/gpu.c \
|
||||
$(CORE_DIR)/gte.c \
|
||||
$(CORE_DIR)/gte_nf.c \
|
||||
$(CORE_DIR)/gte_divider.c
|
||||
|
||||
# spu
|
||||
SOURCES_C += $(SPU_DIR)/dma.c \
|
||||
$(SPU_DIR)/freeze.c \
|
||||
$(SPU_DIR)/registers.c \
|
||||
$(SPU_DIR)/spu.c \
|
||||
$(SPU_DIR)/out.c \
|
||||
$(SPU_DIR)/nullsnd.c
|
||||
|
||||
# gpu
|
||||
SOURCES_C += $(GPU_DIR)/gpu.c \
|
||||
$(GPU_DIR)/vout_pl.c
|
||||
|
||||
# cdrcimg
|
||||
SOURCES_C += $(CDR_DIR)/cdrcimg.c
|
||||
|
||||
# frontend
|
||||
SOURCES_C += $(FRONTEND_DIR)/main.c \
|
||||
$(FRONTEND_DIR)/plugin.c \
|
||||
$(FRONTEND_DIR)/cspace.c \
|
||||
$(FRONTEND_DIR)/libretro.c
|
||||
|
||||
# libchdr
|
||||
LCHDR = $(DEPS_DIR)/libchdr
|
||||
LCHDR_LZMA = $(LCHDR)/deps/lzma-24.05
|
||||
LCHDR_ZSTD = $(LCHDR)/deps/zstd-1.5.6/lib
|
||||
SOURCES_C += \
|
||||
$(LCHDR)/src/libchdr_bitstream.c \
|
||||
$(LCHDR)/src/libchdr_cdrom.c \
|
||||
$(LCHDR)/src/libchdr_chd.c \
|
||||
$(LCHDR)/src/libchdr_flac.c \
|
||||
$(LCHDR)/src/libchdr_huffman.c \
|
||||
$(LCHDR_LZMA)/src/Alloc.c \
|
||||
$(LCHDR_LZMA)/src/CpuArch.c \
|
||||
$(LCHDR_LZMA)/src/Delta.c \
|
||||
$(LCHDR_LZMA)/src/LzFind.c \
|
||||
$(LCHDR_LZMA)/src/LzmaDec.c \
|
||||
$(LCHDR_LZMA)/src/LzmaEnc.c \
|
||||
$(LCHDR_LZMA)/src/Sort.c \
|
||||
$(LCHDR_ZSTD)/common/entropy_common.c \
|
||||
$(LCHDR_ZSTD)/common/error_private.c \
|
||||
$(LCHDR_ZSTD)/common/fse_decompress.c \
|
||||
$(LCHDR_ZSTD)/common/xxhash.c \
|
||||
$(LCHDR_ZSTD)/common/zstd_common.c \
|
||||
$(LCHDR_ZSTD)/decompress/huf_decompress.c \
|
||||
$(LCHDR_ZSTD)/decompress/zstd_ddict.c \
|
||||
$(LCHDR_ZSTD)/decompress/zstd_decompress_block.c \
|
||||
$(LCHDR_ZSTD)/decompress/zstd_decompress.c
|
||||
SOURCES_ASM :=
|
||||
EXTRA_INCLUDES += $(LCHDR)/include $(LCHDR_LZMA)/include $(LCHDR_ZSTD)
|
||||
COREFLAGS += -DHAVE_CHD -DZ7_ST -DZSTD_DISABLE_ASM
|
||||
ifeq (,$(call gte,$(APP_PLATFORM_LEVEL),18))
|
||||
ifneq ($(TARGET_ARCH_ABI),arm64-v8a)
|
||||
# HACK
|
||||
COREFLAGS += -Dgetauxval=0*
|
||||
endif
|
||||
endif
|
||||
|
||||
COREFLAGS += -ffast-math -funroll-loops -DHAVE_LIBRETRO -DNO_FRONTEND -DFRONTEND_SUPPORTS_RGB565 -DANDROID -DREARMED
|
||||
COREFLAGS += -DP_HAVE_MMAP=1 -DP_HAVE_PTHREAD=1 -DP_HAVE_POSIX_MEMALIGN=1
|
||||
|
||||
ifeq ($(USE_LIBRETRO_VFS),1)
|
||||
SOURCES_C += \
|
||||
$(LIBRETRO_COMMON)/compat/compat_posix_string.c \
|
||||
$(LIBRETRO_COMMON)/compat/fopen_utf8.c \
|
||||
$(LIBRETRO_COMMON)/encodings/compat_strl.c \
|
||||
$(LIBRETRO_COMMON)/encodings/encoding_utf.c \
|
||||
$(LIBRETRO_COMMON)/file/file_path.c \
|
||||
$(LIBRETRO_COMMON)/streams/file_stream.c \
|
||||
$(LIBRETRO_COMMON)/streams/file_stream_transforms.c \
|
||||
$(LIBRETRO_COMMON)/string/stdstring.c \
|
||||
$(LIBRETRO_COMMON)/time/rtime.c \
|
||||
$(LIBRETRO_COMMON)/vfs/vfs_implementation.c
|
||||
COREFLAGS += -DUSE_LIBRETRO_VFS
|
||||
endif
|
||||
EXTRA_INCLUDES += $(LIBRETRO_COMMON)/include
|
||||
|
||||
USE_RTHREADS=0
|
||||
HAVE_ARI64=0
|
||||
HAVE_LIGHTREC=0
|
||||
LIGHTREC_CUSTOM_MAP=0
|
||||
LIGHTREC_THREADED_COMPILER=0
|
||||
HAVE_GPU_NEON=0
|
||||
ifeq ($(TARGET_ARCH_ABI),armeabi-v7a)
|
||||
HAVE_ARI64=1
|
||||
HAVE_GPU_NEON=1
|
||||
else ifeq ($(TARGET_ARCH_ABI),armeabi)
|
||||
HAVE_ARI64=1
|
||||
else ifeq ($(TARGET_ARCH_ABI),arm64-v8a)
|
||||
HAVE_ARI64=1
|
||||
HAVE_GPU_NEON=1
|
||||
else ifeq ($(TARGET_ARCH_ABI),x86_64)
|
||||
HAVE_LIGHTREC=1
|
||||
HAVE_GPU_NEON=1
|
||||
else ifeq ($(TARGET_ARCH_ABI),x86)
|
||||
HAVE_LIGHTREC=1
|
||||
HAVE_GPU_NEON=1
|
||||
else
|
||||
COREFLAGS += -DDRC_DISABLE
|
||||
endif
|
||||
COREFLAGS += -DLIGHTREC_CUSTOM_MAP=$(LIGHTREC_CUSTOM_MAP)
|
||||
COREFLAGS += -DLIGHTREC_ENABLE_THREADED_COMPILER=$(LIGHTREC_THREADED_COMPILER)
|
||||
|
||||
ifeq ($(HAVE_ARI64),1)
|
||||
SOURCES_C += $(DYNAREC_DIR)/new_dynarec.c \
|
||||
$(DYNAREC_DIR)/pcsxmem.c
|
||||
ifeq ($(TARGET_ARCH_ABI),arm64-v8a)
|
||||
SOURCES_ASM += $(DYNAREC_DIR)/linkage_arm64.S
|
||||
else
|
||||
SOURCES_ASM += $(CORE_DIR)/gte_arm.S \
|
||||
$(SPU_DIR)/arm_utils.S \
|
||||
$(DYNAREC_DIR)/linkage_arm.S
|
||||
endif
|
||||
ifeq ($(NDRC_THREAD),1)
|
||||
COREFLAGS += -DNDRC_THREAD
|
||||
USE_RTHREADS := 1
|
||||
endif
|
||||
endif
|
||||
SOURCES_C += $(DYNAREC_DIR)/emu_if.c
|
||||
|
||||
ifeq ($(HAVE_LIGHTREC),1)
|
||||
COREFLAGS += -DLIGHTREC -DLIGHTREC_STATIC -DLIGHTREC_CODE_INV=0
|
||||
EXTRA_INCLUDES += $(DEPS_DIR)/lightning/include \
|
||||
$(DEPS_DIR)/lightrec \
|
||||
$(DEPS_DIR)/lightrec/tlsf \
|
||||
$(ROOT_DIR)/include/lightning \
|
||||
$(ROOT_DIR)/include/lightrec
|
||||
SOURCES_C += $(DEPS_DIR)/lightrec/blockcache.c \
|
||||
$(DEPS_DIR)/lightrec/constprop.c \
|
||||
$(DEPS_DIR)/lightrec/disassembler.c \
|
||||
$(DEPS_DIR)/lightrec/emitter.c \
|
||||
$(DEPS_DIR)/lightrec/interpreter.c \
|
||||
$(DEPS_DIR)/lightrec/lightrec.c \
|
||||
$(DEPS_DIR)/lightrec/memmanager.c \
|
||||
$(DEPS_DIR)/lightrec/optimizer.c \
|
||||
$(DEPS_DIR)/lightrec/regcache.c \
|
||||
$(DEPS_DIR)/lightrec/recompiler.c \
|
||||
$(DEPS_DIR)/lightrec/reaper.c \
|
||||
$(DEPS_DIR)/lightrec/tlsf/tlsf.c
|
||||
SOURCES_C += $(DEPS_DIR)/lightning/lib/jit_disasm.c \
|
||||
$(DEPS_DIR)/lightning/lib/jit_memory.c \
|
||||
$(DEPS_DIR)/lightning/lib/jit_names.c \
|
||||
$(DEPS_DIR)/lightning/lib/jit_note.c \
|
||||
$(DEPS_DIR)/lightning/lib/jit_print.c \
|
||||
$(DEPS_DIR)/lightning/lib/jit_size.c \
|
||||
$(DEPS_DIR)/lightning/lib/lightning.c
|
||||
SOURCES_C += $(CORE_DIR)/lightrec/plugin.c
|
||||
ifeq ($(LIGHTREC_CUSTOM_MAP),1)
|
||||
SOURCES_C += $(CORE_DIR)/lightrec/mem.c
|
||||
endif
|
||||
endif
|
||||
|
||||
|
||||
ifeq ($(HAVE_GPU_NEON),1)
|
||||
COREFLAGS += -DNEON_BUILD -DTEXTURE_CACHE_4BPP -DTEXTURE_CACHE_8BPP -DGPU_NEON
|
||||
ifeq ($(TARGET_ARCH_ABI),armeabi-v7a)
|
||||
SOURCES_ASM += $(NEON_DIR)/psx_gpu/psx_gpu_arm_neon.S
|
||||
else
|
||||
COREFLAGS += -DSIMD_BUILD
|
||||
SOURCES_C += $(NEON_DIR)/psx_gpu/psx_gpu_simd.c
|
||||
endif
|
||||
SOURCES_C += $(NEON_DIR)/psx_gpu_if.c
|
||||
else ifeq ($(TARGET_ARCH_ABI),armeabi)
|
||||
COREFLAGS += -DUSE_GPULIB=1 -DGPU_UNAI
|
||||
COREFLAGS += -DHAVE_bgr555_to_rgb565
|
||||
SOURCES_ASM += $(UNAI_DIR)/gpu_arm.S \
|
||||
$(FRONTEND_DIR)/cspace_arm.S
|
||||
SOURCES_C += $(UNAI_DIR)/gpulib_if.cpp
|
||||
else
|
||||
COREFLAGS += -fno-strict-aliasing -DGPU_PEOPS
|
||||
SOURCES_C += $(PEOPS_DIR)/gpulib_if.c
|
||||
endif
|
||||
|
||||
ifeq ($(TARGET_ARCH_ABI),armeabi-v7a)
|
||||
COREFLAGS += -DHAVE_bgr555_to_rgb565 -DHAVE_bgr888_to_x
|
||||
SOURCES_ASM += $(CORE_DIR)/gte_neon.S \
|
||||
$(FRONTEND_DIR)/cspace_neon.S
|
||||
endif
|
||||
|
||||
ifeq ($(USE_ASYNC_CDROM),1)
|
||||
COREFLAGS += -DUSE_ASYNC_CDROM
|
||||
USE_RTHREADS := 1
|
||||
endif
|
||||
ifeq ($(USE_RTHREADS),1)
|
||||
SOURCES_C += \
|
||||
$(FRONTEND_DIR)/libretro-rthreads.c \
|
||||
$(LIBRETRO_COMMON)/features/features_cpu.c
|
||||
COREFLAGS += -DHAVE_RTHREADS
|
||||
endif
|
||||
|
||||
GIT_VERSION := " $(shell git rev-parse --short HEAD || echo unknown)"
|
||||
ifneq ($(GIT_VERSION)," unknown")
|
||||
COREFLAGS += -DGIT_VERSION=\"$(GIT_VERSION)\"
|
||||
endif
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_MODULE := retro
|
||||
LOCAL_SRC_FILES := $(SOURCES_C) $(SOURCES_ASM)
|
||||
LOCAL_CFLAGS := $(COREFLAGS)
|
||||
LOCAL_C_INCLUDES := $(ROOT_DIR)/include
|
||||
LOCAL_C_INCLUDES += $(DEPS_DIR)/crypto
|
||||
LOCAL_C_INCLUDES += $(EXTRA_INCLUDES)
|
||||
LOCAL_LDFLAGS += -Wl,-version-script=$(FRONTEND_DIR)/libretro-version-script
|
||||
LOCAL_LDFLAGS += -Wl,--script=$(FRONTEND_DIR)/libretro-extern.T
|
||||
LOCAL_LDFLAGS += -Wl,--gc-sections
|
||||
LOCAL_LDLIBS := -lz -llog
|
||||
LOCAL_ARM_MODE := arm
|
||||
|
||||
ifeq ($(TARGET_ARCH_ABI),armeabi-v7a)
|
||||
LOCAL_ARM_NEON := true
|
||||
endif
|
||||
|
||||
include $(BUILD_SHARED_LIBRARY)
|
||||
|
@ -47,6 +47,6 @@ void SetupSound(void)
|
||||
}
|
||||
|
||||
out_current = &out_drivers[i];
|
||||
printf("selected sound output driver: %s\n", out_current->name);
|
||||
// printf("selected sound output driver: %s\n", out_current->name);
|
||||
}
|
||||
|
||||
|
@ -22,6 +22,22 @@
|
||||
#pragma GCC diagnostic ignored "-Wmisleading-indentation"
|
||||
#endif
|
||||
|
||||
#ifdef THREAD_RENDERING
|
||||
#include "../gpulib/gpulib_thread_if.h"
|
||||
#define do_cmd_list real_do_cmd_list
|
||||
#define renderer_init real_renderer_init
|
||||
#define renderer_finish real_renderer_finish
|
||||
#define renderer_sync_ecmds real_renderer_sync_ecmds
|
||||
#define renderer_update_caches real_renderer_update_caches
|
||||
#define renderer_flush_queues real_renderer_flush_queues
|
||||
#define renderer_set_interlace real_renderer_set_interlace
|
||||
#define renderer_set_config real_renderer_set_config
|
||||
#define renderer_notify_res_change real_renderer_notify_res_change
|
||||
#define renderer_notify_update_lace real_renderer_notify_update_lace
|
||||
#define renderer_sync real_renderer_sync
|
||||
#define ex_regs scratch_ex_regs
|
||||
#endif
|
||||
|
||||
#define u32 uint32_t
|
||||
|
||||
#define INFO_TW 0
|
||||
@ -468,6 +484,14 @@ void renderer_set_interlace(int enable, int is_odd)
|
||||
{
|
||||
}
|
||||
|
||||
void renderer_sync(void)
|
||||
{
|
||||
}
|
||||
|
||||
void renderer_notify_update_lace(int updated)
|
||||
{
|
||||
}
|
||||
|
||||
#include "../../frontend/plugin_lib.h"
|
||||
|
||||
void renderer_set_config(const struct rearmed_cbs *cbs)
|
||||
|
@ -775,3 +775,11 @@ static void fps_update(void)
|
||||
DisplayText(buf, 1);
|
||||
}
|
||||
}
|
||||
|
||||
void renderer_sync(void)
|
||||
{
|
||||
}
|
||||
|
||||
void renderer_notify_update_lace(int updated)
|
||||
{
|
||||
}
|
||||
|
@ -244,4 +244,12 @@ void renderer_set_config(const struct rearmed_cbs *cbs)
|
||||
}
|
||||
}
|
||||
|
||||
void renderer_sync(void)
|
||||
{
|
||||
}
|
||||
|
||||
void renderer_notify_update_lace(int updated)
|
||||
{
|
||||
}
|
||||
|
||||
// vim:ts=2:sw=2:expandtab
|
||||
|
@ -43,6 +43,7 @@ static void finish_vram_transfer(int is_read);
|
||||
static noinline void do_cmd_reset(void)
|
||||
{
|
||||
int dummy = 0;
|
||||
renderer_sync();
|
||||
if (unlikely(gpu.cmd_len > 0))
|
||||
do_cmd_buffer(gpu.cmd_buffer, gpu.cmd_len, &dummy, &dummy);
|
||||
gpu.cmd_len = 0;
|
||||
@ -167,6 +168,8 @@ static noinline void update_height(void)
|
||||
|
||||
static noinline void decide_frameskip(void)
|
||||
{
|
||||
*gpu.frameskip.dirty = 1;
|
||||
|
||||
if (gpu.frameskip.active)
|
||||
gpu.frameskip.cnt++;
|
||||
else {
|
||||
@ -174,7 +177,9 @@ static noinline void decide_frameskip(void)
|
||||
gpu.frameskip.frame_ready = 1;
|
||||
}
|
||||
|
||||
if (!gpu.frameskip.active && *gpu.frameskip.advice)
|
||||
if (*gpu.frameskip.force)
|
||||
gpu.frameskip.active = 1;
|
||||
else if (!gpu.frameskip.active && *gpu.frameskip.advice)
|
||||
gpu.frameskip.active = 1;
|
||||
else if (gpu.frameskip.set > 0 && gpu.frameskip.cnt < gpu.frameskip.set)
|
||||
gpu.frameskip.active = 1;
|
||||
@ -448,6 +453,8 @@ static int do_vram_io(uint32_t *data, int count, int is_read)
|
||||
int l;
|
||||
count *= 2; // operate in 16bpp pixels
|
||||
|
||||
renderer_sync();
|
||||
|
||||
if (gpu.dma.offset) {
|
||||
l = w - gpu.dma.offset;
|
||||
if (count < l)
|
||||
@ -687,6 +694,7 @@ static noinline int do_cmd_buffer(uint32_t *data, int count,
|
||||
cmd = -1; // incomplete cmd, can't consume yet
|
||||
break;
|
||||
}
|
||||
renderer_sync();
|
||||
*cycles_sum += *cycles_last;
|
||||
*cycles_last = 0;
|
||||
do_vram_copy(data + pos + 1, cycles_last);
|
||||
@ -890,12 +898,15 @@ long GPUfreeze(uint32_t type, struct GPUFreeze *freeze)
|
||||
case 1: // save
|
||||
if (gpu.cmd_len > 0)
|
||||
flush_cmd_buffer();
|
||||
|
||||
renderer_sync();
|
||||
memcpy(freeze->psxVRam, gpu.vram, 1024 * 512 * 2);
|
||||
memcpy(freeze->ulControl, gpu.regs, sizeof(gpu.regs));
|
||||
memcpy(freeze->ulControl + 0xe0, gpu.ex_regs, sizeof(gpu.ex_regs));
|
||||
freeze->ulStatus = gpu.status;
|
||||
break;
|
||||
case 0: // load
|
||||
renderer_sync();
|
||||
memcpy(gpu.vram, freeze->psxVRam, 1024 * 512 * 2);
|
||||
memcpy(gpu.regs, freeze->ulControl, sizeof(gpu.regs));
|
||||
memcpy(gpu.ex_regs, freeze->ulControl + 0xe0, sizeof(gpu.ex_regs));
|
||||
@ -929,6 +940,8 @@ void GPUupdateLace(void)
|
||||
return;
|
||||
}
|
||||
|
||||
renderer_notify_update_lace(0);
|
||||
|
||||
if (!gpu.state.fb_dirty)
|
||||
return;
|
||||
#endif
|
||||
@ -948,6 +961,7 @@ void GPUupdateLace(void)
|
||||
gpu.state.enhancement_was_active = gpu.state.enhancement_active;
|
||||
gpu.state.fb_dirty = 0;
|
||||
gpu.state.blanked = 0;
|
||||
renderer_notify_update_lace(1);
|
||||
}
|
||||
|
||||
void GPUvBlank(int is_vblank, int lcf)
|
||||
@ -984,6 +998,8 @@ void GPUrearmedCallbacks(const struct rearmed_cbs *cbs)
|
||||
{
|
||||
gpu.frameskip.set = cbs->frameskip;
|
||||
gpu.frameskip.advice = &cbs->fskip_advice;
|
||||
gpu.frameskip.force = &cbs->fskip_force;
|
||||
gpu.frameskip.dirty = (void *)&cbs->fskip_dirty;
|
||||
gpu.frameskip.active = 0;
|
||||
gpu.frameskip.frame_ready = 1;
|
||||
gpu.state.hcnt = (uint32_t *)cbs->gpu_hcnt;
|
||||
|
@ -105,9 +105,12 @@ struct psx_gpu {
|
||||
uint32_t allow:1;
|
||||
uint32_t frame_ready:1;
|
||||
const int *advice;
|
||||
const int *force;
|
||||
int *dirty;
|
||||
uint32_t last_flip_frame;
|
||||
uint32_t pending_fill[3];
|
||||
} frameskip;
|
||||
uint32_t scratch_ex_regs[8]; // for threaded rendering
|
||||
void *(*get_enhancement_bufer)
|
||||
(int *x, int *y, int *w, int *h, int *vram_h);
|
||||
uint16_t *(*get_downscale_buffer)
|
||||
@ -134,6 +137,8 @@ void renderer_flush_queues(void);
|
||||
void renderer_set_interlace(int enable, int is_odd);
|
||||
void renderer_set_config(const struct rearmed_cbs *config);
|
||||
void renderer_notify_res_change(void);
|
||||
void renderer_notify_update_lace(int updated);
|
||||
void renderer_sync(void);
|
||||
void renderer_notify_scanout_change(int x, int y);
|
||||
|
||||
int vout_init(void);
|
||||
|
563
plugins/gpulib/gpulib_thread_if.c
Normal file
563
plugins/gpulib/gpulib_thread_if.c
Normal file
@ -0,0 +1,563 @@
|
||||
/**************************************************************************
|
||||
* Copyright (C) 2020 The RetroArch Team *
|
||||
* *
|
||||
* 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; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* 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 for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02111-1307 USA. *
|
||||
***************************************************************************/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <pthread.h>
|
||||
#include "../gpulib/gpu.h"
|
||||
#include "../../frontend/plugin_lib.h"
|
||||
#include "gpu.h"
|
||||
#include "gpu_timing.h"
|
||||
#include "gpulib_thread_if.h"
|
||||
|
||||
extern void SysPrintf(const char *fmt, ...);
|
||||
|
||||
#define FALSE 0
|
||||
#define TRUE 1
|
||||
#define BOOL unsigned short
|
||||
|
||||
typedef struct {
|
||||
uint32_t *cmd_list;
|
||||
int count;
|
||||
int last_cmd;
|
||||
} video_thread_cmd;
|
||||
|
||||
#define QUEUE_SIZE 0x2000
|
||||
|
||||
typedef struct {
|
||||
size_t start;
|
||||
size_t end;
|
||||
size_t used;
|
||||
video_thread_cmd queue[QUEUE_SIZE];
|
||||
} video_thread_queue;
|
||||
|
||||
typedef struct {
|
||||
pthread_t thread;
|
||||
pthread_mutex_t queue_lock;
|
||||
pthread_cond_t cond_msg_avail;
|
||||
pthread_cond_t cond_msg_done;
|
||||
pthread_cond_t cond_queue_empty;
|
||||
video_thread_queue *queue;
|
||||
video_thread_queue *bg_queue;
|
||||
BOOL running;
|
||||
} video_thread_state;
|
||||
|
||||
static video_thread_state thread;
|
||||
static video_thread_queue queues[2];
|
||||
static int thread_rendering;
|
||||
static BOOL hold_cmds;
|
||||
static BOOL needs_display;
|
||||
static BOOL flushed;
|
||||
|
||||
extern const unsigned char cmd_lengths[];
|
||||
|
||||
static void *video_thread_main(void *arg) {
|
||||
video_thread_cmd *cmd;
|
||||
int i;
|
||||
|
||||
#ifdef _3DS
|
||||
static int processed = 0;
|
||||
#endif /* _3DS */
|
||||
|
||||
while(1) {
|
||||
int result, cycles_dummy = 0, last_cmd, start, end;
|
||||
video_thread_queue *queue;
|
||||
pthread_mutex_lock(&thread.queue_lock);
|
||||
|
||||
while (!thread.queue->used && thread.running) {
|
||||
pthread_cond_wait(&thread.cond_msg_avail, &thread.queue_lock);
|
||||
}
|
||||
|
||||
if (!thread.running) {
|
||||
pthread_mutex_unlock(&thread.queue_lock);
|
||||
break;
|
||||
}
|
||||
|
||||
queue = thread.queue;
|
||||
start = queue->start;
|
||||
end = queue->end > queue->start ? queue->end : QUEUE_SIZE;
|
||||
queue->start = end % QUEUE_SIZE;
|
||||
pthread_mutex_unlock(&thread.queue_lock);
|
||||
|
||||
for (i = start; i < end; i++) {
|
||||
cmd = &queue->queue[i];
|
||||
result = real_do_cmd_list(cmd->cmd_list, cmd->count,
|
||||
&cycles_dummy, &cycles_dummy, &last_cmd);
|
||||
if (result != cmd->count) {
|
||||
fprintf(stderr, "Processed wrong cmd count: expected %d, got %d\n", cmd->count, result);
|
||||
}
|
||||
|
||||
#ifdef _3DS
|
||||
/* Periodically yield so as not to starve other threads */
|
||||
processed += cmd->count;
|
||||
if (processed >= 512) {
|
||||
svcSleepThread(1);
|
||||
processed %= 512;
|
||||
}
|
||||
#endif /* _3DS */
|
||||
}
|
||||
|
||||
pthread_mutex_lock(&thread.queue_lock);
|
||||
queue->used -= (end - start);
|
||||
|
||||
if (!queue->used)
|
||||
pthread_cond_signal(&thread.cond_queue_empty);
|
||||
|
||||
pthread_cond_signal(&thread.cond_msg_done);
|
||||
pthread_mutex_unlock(&thread.queue_lock);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void cmd_queue_swap() {
|
||||
video_thread_queue *tmp;
|
||||
if (!thread.bg_queue->used) return;
|
||||
|
||||
pthread_mutex_lock(&thread.queue_lock);
|
||||
if (!thread.queue->used) {
|
||||
tmp = thread.queue;
|
||||
thread.queue = thread.bg_queue;
|
||||
thread.bg_queue = tmp;
|
||||
pthread_cond_signal(&thread.cond_msg_avail);
|
||||
}
|
||||
pthread_mutex_unlock(&thread.queue_lock);
|
||||
}
|
||||
|
||||
/* Waits for the main queue to completely finish. */
|
||||
void renderer_wait() {
|
||||
if (!thread.running) return;
|
||||
|
||||
/* Not completely safe, but should be fine since the render thread
|
||||
* only decreases used, and we check again inside the lock. */
|
||||
if (!thread.queue->used) {
|
||||
return;
|
||||
}
|
||||
|
||||
pthread_mutex_lock(&thread.queue_lock);
|
||||
|
||||
while (thread.queue->used) {
|
||||
pthread_cond_wait(&thread.cond_queue_empty, &thread.queue_lock);
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&thread.queue_lock);
|
||||
}
|
||||
|
||||
/* Waits for all GPU commands in both queues to finish, bringing VRAM
|
||||
* completely up-to-date. */
|
||||
void renderer_sync(void) {
|
||||
if (!thread.running) return;
|
||||
|
||||
/* Not completely safe, but should be fine since the render thread
|
||||
* only decreases used, and we check again inside the lock. */
|
||||
if (!thread.queue->used && !thread.bg_queue->used) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (thread.bg_queue->used) {
|
||||
/* When we flush the background queue, the vblank handler can't
|
||||
* know that we had a frame pending, and we delay rendering too
|
||||
* long. Force it. */
|
||||
flushed = TRUE;
|
||||
}
|
||||
|
||||
/* Flush both queues. This is necessary because gpulib could be
|
||||
* trying to process a DMA write that a command in the queue should
|
||||
* run beforehand. For example, Xenogears sprites write a black
|
||||
* rectangle over the to-be-DMA'd spot in VRAM -- if this write
|
||||
* happens after the DMA, it will clear the DMA, resulting in
|
||||
* flickering sprites. We need to be totally up-to-date. This may
|
||||
* drop a frame. */
|
||||
renderer_wait();
|
||||
cmd_queue_swap();
|
||||
hold_cmds = FALSE;
|
||||
renderer_wait();
|
||||
}
|
||||
|
||||
static void video_thread_stop() {
|
||||
int i;
|
||||
renderer_sync();
|
||||
|
||||
if (thread.running) {
|
||||
thread.running = FALSE;
|
||||
pthread_cond_signal(&thread.cond_msg_avail);
|
||||
pthread_join(thread.thread, NULL);
|
||||
}
|
||||
|
||||
pthread_mutex_destroy(&thread.queue_lock);
|
||||
pthread_cond_destroy(&thread.cond_msg_avail);
|
||||
pthread_cond_destroy(&thread.cond_msg_done);
|
||||
pthread_cond_destroy(&thread.cond_queue_empty);
|
||||
|
||||
for (i = 0; i < QUEUE_SIZE; i++) {
|
||||
video_thread_cmd *cmd = &thread.queue->queue[i];
|
||||
free(cmd->cmd_list);
|
||||
cmd->cmd_list = NULL;
|
||||
}
|
||||
|
||||
for (i = 0; i < QUEUE_SIZE; i++) {
|
||||
video_thread_cmd *cmd = &thread.bg_queue->queue[i];
|
||||
free(cmd->cmd_list);
|
||||
cmd->cmd_list = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void video_thread_start() {
|
||||
SysPrintf("Starting render thread\n");
|
||||
|
||||
thread.queue = &queues[0];
|
||||
thread.bg_queue = &queues[1];
|
||||
thread.running = TRUE;
|
||||
|
||||
if (pthread_cond_init(&thread.cond_msg_avail, NULL) ||
|
||||
pthread_cond_init(&thread.cond_msg_done, NULL) ||
|
||||
pthread_cond_init(&thread.cond_queue_empty, NULL) ||
|
||||
pthread_mutex_init(&thread.queue_lock, NULL) ||
|
||||
pthread_create(&thread.thread, NULL, video_thread_main, &thread)) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
error:
|
||||
SysPrintf("Failed to start rendering thread\n");
|
||||
thread.running = FALSE;
|
||||
video_thread_stop();
|
||||
}
|
||||
|
||||
static void video_thread_queue_cmd(uint32_t *list, int count, int last_cmd) {
|
||||
video_thread_cmd *cmd;
|
||||
uint32_t *cmd_list;
|
||||
video_thread_queue *queue;
|
||||
BOOL lock;
|
||||
|
||||
cmd_list = (uint32_t *)calloc(count, sizeof(uint32_t));
|
||||
|
||||
if (!cmd_list) {
|
||||
/* Out of memory, disable the thread and run sync from now on */
|
||||
SysPrintf("Failed to allocate render thread command list, stopping thread\n");
|
||||
video_thread_stop();
|
||||
}
|
||||
|
||||
memcpy(cmd_list, list, count * sizeof(uint32_t));
|
||||
|
||||
if (hold_cmds && thread.bg_queue->used >= QUEUE_SIZE) {
|
||||
/* If the bg queue is full, do a full sync to empty both queues
|
||||
* and clear space. This should be very rare, I've only seen it in
|
||||
* Tekken 3 post-battle-replay. */
|
||||
renderer_sync();
|
||||
}
|
||||
|
||||
if (hold_cmds) {
|
||||
queue = thread.bg_queue;
|
||||
lock = FALSE;
|
||||
} else {
|
||||
queue = thread.queue;
|
||||
lock = TRUE;
|
||||
}
|
||||
|
||||
if (lock) {
|
||||
pthread_mutex_lock(&thread.queue_lock);
|
||||
|
||||
while (queue->used >= QUEUE_SIZE) {
|
||||
pthread_cond_wait(&thread.cond_msg_done, &thread.queue_lock);
|
||||
}
|
||||
}
|
||||
|
||||
cmd = &queue->queue[queue->end];
|
||||
free(cmd->cmd_list);
|
||||
cmd->cmd_list = cmd_list;
|
||||
cmd->count = count;
|
||||
cmd->last_cmd = last_cmd;
|
||||
queue->end = (queue->end + 1) % QUEUE_SIZE;
|
||||
queue->used++;
|
||||
|
||||
if (lock) {
|
||||
pthread_cond_signal(&thread.cond_msg_avail);
|
||||
pthread_mutex_unlock(&thread.queue_lock);
|
||||
}
|
||||
}
|
||||
|
||||
/* Slice off just the part of the list that can be handled async, and
|
||||
* update ex_regs. */
|
||||
static int scan_cmd_list(uint32_t *data, int count,
|
||||
int *cycles_sum_out, int *cycles_last, int *last_cmd)
|
||||
{
|
||||
int cpu_cycles_sum = 0, cpu_cycles = *cycles_last;
|
||||
int cmd = 0, pos = 0, len, v;
|
||||
|
||||
while (pos < count) {
|
||||
uint32_t *list = data + pos;
|
||||
short *slist = (void *)list;
|
||||
cmd = LE32TOH(list[0]) >> 24;
|
||||
len = 1 + cmd_lengths[cmd];
|
||||
|
||||
switch (cmd) {
|
||||
case 0x02:
|
||||
gput_sum(cpu_cycles_sum, cpu_cycles,
|
||||
gput_fill(LE16TOH(slist[4]) & 0x3ff,
|
||||
LE16TOH(slist[5]) & 0x1ff));
|
||||
break;
|
||||
case 0x20 ... 0x23:
|
||||
gput_sum(cpu_cycles_sum, cpu_cycles, gput_poly_base());
|
||||
break;
|
||||
case 0x24 ... 0x27:
|
||||
gput_sum(cpu_cycles_sum, cpu_cycles, gput_poly_base_t());
|
||||
gpu.ex_regs[1] &= ~0x1ff;
|
||||
gpu.ex_regs[1] |= LE32TOH(list[4]) & 0x1ff;
|
||||
break;
|
||||
case 0x28 ... 0x2b:
|
||||
gput_sum(cpu_cycles_sum, cpu_cycles, gput_quad_base());
|
||||
break;
|
||||
case 0x2c ... 0x2f:
|
||||
gput_sum(cpu_cycles_sum, cpu_cycles, gput_quad_base_t());
|
||||
gpu.ex_regs[1] &= ~0x1ff;
|
||||
gpu.ex_regs[1] |= LE32TOH(list[4]) & 0x1ff;
|
||||
break;
|
||||
case 0x30 ... 0x33:
|
||||
gput_sum(cpu_cycles_sum, cpu_cycles, gput_poly_base_g());
|
||||
break;
|
||||
case 0x34 ... 0x37:
|
||||
gput_sum(cpu_cycles_sum, cpu_cycles, gput_poly_base_gt());
|
||||
gpu.ex_regs[1] &= ~0x1ff;
|
||||
gpu.ex_regs[1] |= LE32TOH(list[5]) & 0x1ff;
|
||||
break;
|
||||
case 0x38 ... 0x3b:
|
||||
gput_sum(cpu_cycles_sum, cpu_cycles, gput_quad_base_g());
|
||||
break;
|
||||
case 0x3c ... 0x3f:
|
||||
gput_sum(cpu_cycles_sum, cpu_cycles, gput_quad_base_gt());
|
||||
gpu.ex_regs[1] &= ~0x1ff;
|
||||
gpu.ex_regs[1] |= LE32TOH(list[5]) & 0x1ff;
|
||||
break;
|
||||
case 0x40 ... 0x47:
|
||||
gput_sum(cpu_cycles_sum, cpu_cycles, gput_line(0));
|
||||
break;
|
||||
case 0x48 ... 0x4F:
|
||||
for (v = 3; pos + v < count; v++)
|
||||
{
|
||||
gput_sum(cpu_cycles_sum, cpu_cycles, gput_line(0));
|
||||
if ((list[v] & 0xf000f000) == 0x50005000)
|
||||
break;
|
||||
}
|
||||
len += v - 3;
|
||||
break;
|
||||
case 0x50 ... 0x57:
|
||||
gput_sum(cpu_cycles_sum, cpu_cycles, gput_line(0));
|
||||
break;
|
||||
case 0x58 ... 0x5F:
|
||||
for (v = 4; pos + v < count; v += 2)
|
||||
{
|
||||
gput_sum(cpu_cycles_sum, cpu_cycles, gput_line(0));
|
||||
if ((list[v] & 0xf000f000) == 0x50005000)
|
||||
break;
|
||||
}
|
||||
len += v - 4;
|
||||
break;
|
||||
case 0x60 ... 0x63:
|
||||
gput_sum(cpu_cycles_sum, cpu_cycles,
|
||||
gput_sprite(LE16TOH(slist[4]) & 0x3ff,
|
||||
LE16TOH(slist[5]) & 0x1ff));
|
||||
break;
|
||||
case 0x64 ... 0x67:
|
||||
gput_sum(cpu_cycles_sum, cpu_cycles,
|
||||
gput_sprite(LE16TOH(slist[6]) & 0x3ff,
|
||||
LE16TOH(slist[7]) & 0x1ff));
|
||||
break;
|
||||
case 0x68 ... 0x6b:
|
||||
gput_sum(cpu_cycles_sum, cpu_cycles, gput_sprite(1, 1));
|
||||
break;
|
||||
case 0x70 ... 0x77:
|
||||
gput_sum(cpu_cycles_sum, cpu_cycles, gput_sprite(8, 8));
|
||||
break;
|
||||
case 0x78 ... 0x7f:
|
||||
gput_sum(cpu_cycles_sum, cpu_cycles, gput_sprite(16, 16));
|
||||
break;
|
||||
default:
|
||||
if ((cmd & 0xf8) == 0xe0)
|
||||
gpu.ex_regs[cmd & 7] = list[0];
|
||||
break;
|
||||
}
|
||||
|
||||
if (pos + len > count) {
|
||||
cmd = -1;
|
||||
break; /* incomplete cmd */
|
||||
}
|
||||
if (0x80 <= cmd && cmd <= 0xdf)
|
||||
break; /* image i/o */
|
||||
|
||||
pos += len;
|
||||
}
|
||||
|
||||
*cycles_sum_out += cpu_cycles_sum;
|
||||
*cycles_last = cpu_cycles;
|
||||
*last_cmd = cmd;
|
||||
return pos;
|
||||
}
|
||||
|
||||
int do_cmd_list(uint32_t *list, int count,
|
||||
int *cycles_sum, int *cycles_last, int *last_cmd)
|
||||
{
|
||||
int pos = 0;
|
||||
|
||||
if (thread.running) {
|
||||
pos = scan_cmd_list(list, count, cycles_sum, cycles_last, last_cmd);
|
||||
video_thread_queue_cmd(list, pos, *last_cmd);
|
||||
} else {
|
||||
pos = real_do_cmd_list(list, count, cycles_sum, cycles_last, last_cmd);
|
||||
memcpy(gpu.ex_regs, gpu.scratch_ex_regs, sizeof(gpu.ex_regs));
|
||||
}
|
||||
return pos;
|
||||
}
|
||||
|
||||
int renderer_init(void) {
|
||||
if (thread_rendering) {
|
||||
video_thread_start();
|
||||
}
|
||||
return real_renderer_init();
|
||||
}
|
||||
|
||||
void renderer_finish(void) {
|
||||
real_renderer_finish();
|
||||
|
||||
if (thread_rendering && thread.running) {
|
||||
video_thread_stop();
|
||||
}
|
||||
}
|
||||
|
||||
void renderer_sync_ecmds(uint32_t * ecmds) {
|
||||
if (thread.running) {
|
||||
int dummy = 0;
|
||||
do_cmd_list(&ecmds[1], 6, &dummy, &dummy, &dummy);
|
||||
} else {
|
||||
real_renderer_sync_ecmds(ecmds);
|
||||
}
|
||||
}
|
||||
|
||||
void renderer_update_caches(int x, int y, int w, int h, int state_changed) {
|
||||
renderer_sync();
|
||||
real_renderer_update_caches(x, y, w, h, state_changed);
|
||||
}
|
||||
|
||||
void renderer_flush_queues(void) {
|
||||
/* Called during DMA and updateLace. We want to sync if it's DMA,
|
||||
* but not if it's updateLace. Instead of syncing here, there's a
|
||||
* renderer_sync call during DMA. */
|
||||
real_renderer_flush_queues();
|
||||
}
|
||||
|
||||
/*
|
||||
* Normally all GPU commands are processed before rendering the
|
||||
* frame. For games that naturally run < 50/60fps, this is unnecessary
|
||||
* -- it forces the game to render as if it was 60fps and leaves the
|
||||
* GPU idle half the time on a 30fps game, for example.
|
||||
*
|
||||
* Allowing the renderer to wait until a frame is done before
|
||||
* rendering it would give it double, triple, or quadruple the amount
|
||||
* of time to finish before we have to wait for it.
|
||||
*
|
||||
* We can use a heuristic to figure out when to force a render.
|
||||
*
|
||||
* - If a frame isn't done when we're asked to render, wait for it and
|
||||
* put future GPU commands in a separate buffer (for the next frame)
|
||||
*
|
||||
* - If the frame is done, and had no future GPU commands, render it.
|
||||
*
|
||||
* - If we do have future GPU commands, it meant the frame took too
|
||||
* long to render and there's another frame waiting. Stop until the
|
||||
* first frame finishes, render it, and start processing the next
|
||||
* one.
|
||||
*
|
||||
* This may possibly add a frame or two of latency that shouldn't be
|
||||
* different than the real device. It may skip rendering a frame
|
||||
* entirely if a VRAM transfer happens while a frame is waiting, or in
|
||||
* games that natively run at 60fps if frames are coming in too
|
||||
* quickly to process. Depending on how the game treats "60fps," this
|
||||
* may not be noticeable.
|
||||
*/
|
||||
void renderer_notify_update_lace(int updated) {
|
||||
if (!thread.running) return;
|
||||
|
||||
if (thread_rendering == THREAD_RENDERING_SYNC) {
|
||||
renderer_sync();
|
||||
return;
|
||||
}
|
||||
|
||||
if (updated) {
|
||||
cmd_queue_swap();
|
||||
return;
|
||||
}
|
||||
|
||||
pthread_mutex_lock(&thread.queue_lock);
|
||||
if (thread.bg_queue->used || flushed) {
|
||||
/* We have commands for a future frame to run. Force a wait until
|
||||
* the current frame is finished, and start processing the next
|
||||
* frame after it's drawn (see the `updated` clause above). */
|
||||
pthread_mutex_unlock(&thread.queue_lock);
|
||||
renderer_wait();
|
||||
pthread_mutex_lock(&thread.queue_lock);
|
||||
|
||||
/* We are no longer holding commands back, so the next frame may
|
||||
* get mixed into the following frame. This is usually fine, but can
|
||||
* result in frameskip-like effects for 60fps games. */
|
||||
flushed = FALSE;
|
||||
hold_cmds = FALSE;
|
||||
needs_display = TRUE;
|
||||
gpu.state.fb_dirty = TRUE;
|
||||
} else if (thread.queue->used) {
|
||||
/* We are still drawing during a vblank. Cut off the current frame
|
||||
* by sending new commands to the background queue and skip
|
||||
* drawing our partly rendered frame to the display. */
|
||||
hold_cmds = TRUE;
|
||||
needs_display = TRUE;
|
||||
gpu.state.fb_dirty = FALSE;
|
||||
} else if (needs_display && !thread.queue->used) {
|
||||
/* We have processed all commands in the queue, render the
|
||||
* buffer. We know we have something to render, because
|
||||
* needs_display is TRUE. */
|
||||
hold_cmds = FALSE;
|
||||
needs_display = FALSE;
|
||||
gpu.state.fb_dirty = TRUE;
|
||||
} else {
|
||||
/* Everything went normally, so do the normal thing. */
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&thread.queue_lock);
|
||||
}
|
||||
|
||||
void renderer_set_interlace(int enable, int is_odd) {
|
||||
real_renderer_set_interlace(enable, is_odd);
|
||||
}
|
||||
|
||||
void renderer_set_config(const struct rearmed_cbs *cbs) {
|
||||
renderer_sync();
|
||||
thread_rendering = cbs->thread_rendering;
|
||||
if (!thread.running && thread_rendering != THREAD_RENDERING_OFF) {
|
||||
video_thread_start();
|
||||
} else if (thread.running && thread_rendering == THREAD_RENDERING_OFF) {
|
||||
video_thread_stop();
|
||||
}
|
||||
real_renderer_set_config(cbs);
|
||||
}
|
||||
|
||||
void renderer_notify_res_change(void) {
|
||||
renderer_sync();
|
||||
real_renderer_notify_res_change();
|
||||
}
|
42
plugins/gpulib/gpulib_thread_if.h
Normal file
42
plugins/gpulib/gpulib_thread_if.h
Normal file
@ -0,0 +1,42 @@
|
||||
/**************************************************************************
|
||||
* Copyright (C) 2020 The RetroArch Team *
|
||||
* *
|
||||
* 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; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* 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 for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02111-1307 USA. *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef __GPULIB_THREAD_H__
|
||||
#define __GPULIB_THREAD_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int real_do_cmd_list(uint32_t *list, int count,
|
||||
int *cycles_sum_out, int *cycles_last, int *last_cmd);
|
||||
int real_renderer_init(void);
|
||||
void real_renderer_finish(void);
|
||||
void real_renderer_sync_ecmds(uint32_t * ecmds);
|
||||
void real_renderer_update_caches(int x, int y, int w, int h, int state_changed);
|
||||
void real_renderer_flush_queues(void);
|
||||
void real_renderer_set_interlace(int enable, int is_odd);
|
||||
void real_renderer_set_config(const struct rearmed_cbs *config);
|
||||
void real_renderer_notify_res_change(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __GPULIB_THREAD_H__ */
|
Loading…
Reference in New Issue
Block a user