diff options
-rwxr-xr-x | .travis-deps.sh | 2 | ||||
-rw-r--r-- | CMakeLists.txt | 180 | ||||
-rw-r--r-- | externals/CMakeLists.txt | 52 | ||||
-rw-r--r-- | externals/cryptopp/CMakeLists.txt | 6 | ||||
-rw-r--r-- | externals/glad/CMakeLists.txt | 3 | ||||
-rw-r--r-- | externals/inih/CMakeLists.txt | 1 | ||||
-rw-r--r-- | src/audio_core/CMakeLists.txt | 5 | ||||
-rw-r--r-- | src/citra/CMakeLists.txt | 6 | ||||
-rw-r--r-- | src/citra_qt/CMakeLists.txt | 2 | ||||
-rw-r--r-- | src/common/CMakeLists.txt | 1 | ||||
-rw-r--r-- | src/core/CMakeLists.txt | 6 | ||||
-rw-r--r-- | src/input_common/CMakeLists.txt | 3 | ||||
-rw-r--r-- | src/tests/CMakeLists.txt | 6 | ||||
-rw-r--r-- | src/video_core/CMakeLists.txt | 7 | ||||
-rw-r--r-- | src/video_core/regs_texturing.h | 27 | ||||
-rw-r--r-- | src/video_core/swrasterizer/rasterizer.cpp | 53 |
16 files changed, 237 insertions, 123 deletions
diff --git a/.travis-deps.sh b/.travis-deps.sh index 1404fe19f..451886984 100755 --- a/.travis-deps.sh +++ b/.travis-deps.sh @@ -11,7 +11,7 @@ if [ "$TRAVIS_OS_NAME" = "linux" -o -z "$TRAVIS_OS_NAME" ]; then if [ ! -e $HOME/.local/bin/cmake ]; then echo "CMake not found in the cache, get and extract it..." - curl -L http://www.cmake.org/files/v3.2/cmake-3.2.0-Linux-i386.tar.gz \ + curl -L http://www.cmake.org/files/v3.6/cmake-3.6.3-Linux-x86_64.tar.gz \ | tar -xz -C $HOME/.local --strip-components=1 else echo "Using cached CMake" diff --git a/CMakeLists.txt b/CMakeLists.txt index 121b0f2f8..1f0af2d41 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,20 +1,25 @@ -# CMake 3.2 required for cmake to know the right flags for CXX standard on OSX -cmake_minimum_required(VERSION 3.2) -set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${PROJECT_SOURCE_DIR}/CMakeModules) +# CMake 3.6 required for FindBoost to define IMPORTED libs properly on unknown Boost versions +cmake_minimum_required(VERSION 3.6) +list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/CMakeModules") +list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/externals/cmake-modules") -function(download_bundled_external remote_path lib_name prefix_var) - set(prefix "${CMAKE_BINARY_DIR}/externals/${lib_name}") - if (NOT EXISTS "${prefix}") - message(STATUS "Downloading binaries for ${lib_name}...") - file(DOWNLOAD - https://github.com/citra-emu/ext-windows-bin/raw/master/${remote_path}${lib_name}.7z - "${CMAKE_BINARY_DIR}/externals/${lib_name}.7z" SHOW_PROGRESS) - execute_process(COMMAND ${CMAKE_COMMAND} -E tar xf "${CMAKE_BINARY_DIR}/externals/${lib_name}.7z" - WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/externals") - endif() - message(STATUS "Using bundled binaries at ${prefix}") - set(${prefix_var} "${prefix}" PARENT_SCOPE) -endfunction() +project(citra) + +option(ENABLE_SDL2 "Enable the SDL2 frontend" ON) +option(CITRA_USE_BUNDLED_SDL2 "Download bundled SDL2 binaries" OFF) + +option(ENABLE_QT "Enable the Qt frontend" ON) +option(CITRA_USE_BUNDLED_QT "Download bundled Qt binaries" OFF) + +if(NOT EXISTS ${CMAKE_SOURCE_DIR}/.git/hooks/pre-commit) + message(STATUS "Copying pre-commit hook") + file(COPY hooks/pre-commit + DESTINATION ${CMAKE_SOURCE_DIR}/.git/hooks) +endif() + + +# Detect current compilation architecture and create standard definitions +# ======================================================================= include(CheckSymbolExists) function(detect_architecture symbol arch) @@ -33,20 +38,6 @@ function(detect_architecture symbol arch) endif() endfunction() -project(citra) - -option(ENABLE_SDL2 "Enable the SDL2 frontend" ON) -option(CITRA_USE_BUNDLED_SDL2 "Download bundled SDL2 binaries" OFF) - -option(ENABLE_QT "Enable the Qt frontend" ON) -option(CITRA_USE_BUNDLED_QT "Download bundled Qt binaries" OFF) - -if(NOT EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/.git/hooks/pre-commit) - message(STATUS "Copying pre-commit hook") - file(COPY hooks/pre-commit - DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/.git/hooks) -endif() - if (MSVC) detect_architecture("_M_AMD64" x86_64) detect_architecture("_M_IX86" x86) @@ -63,6 +54,10 @@ if (NOT DEFINED ARCHITECTURE) endif() message(STATUS "Target architecture: ${ARCHITECTURE}") + +# Configure compilation flags +# =========================== + set(CMAKE_CXX_STANDARD 14) set(CMAKE_CXX_STANDARD_REQUIRED ON) @@ -130,28 +125,44 @@ add_definitions(-DSINGLETHREADED) set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS $<$<CONFIG:Debug>:_DEBUG> $<$<NOT:$<CONFIG:Debug>>:NDEBUG>) + +# System imported libraries +# ====================== + +# This function downloads a binary library package from our external repo. +# Params: +# remote_path: path to the file to download, relative to the remote repository root +# prefix_var: name of a variable which will be set with the path to the extracted contents +function(download_bundled_external remote_path lib_name prefix_var) + set(prefix "${CMAKE_BINARY_DIR}/externals/${lib_name}") + if (NOT EXISTS "${prefix}") + message(STATUS "Downloading binaries for ${lib_name}...") + file(DOWNLOAD + https://github.com/citra-emu/ext-windows-bin/raw/master/${remote_path}${lib_name}.7z + "${CMAKE_BINARY_DIR}/externals/${lib_name}.7z" SHOW_PROGRESS) + execute_process(COMMAND ${CMAKE_COMMAND} -E tar xf "${CMAKE_BINARY_DIR}/externals/${lib_name}.7z" + WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/externals") + endif() + message(STATUS "Using bundled binaries at ${prefix}") + set(${prefix_var} "${prefix}" PARENT_SCOPE) +endfunction() + find_package(PNG QUIET) -if (PNG_FOUND) - add_definitions(-DHAVE_PNG) -else() +if (NOT PNG_FOUND) message(STATUS "libpng not found. Some debugging features have been disabled.") endif() -find_package(Boost 1.57.0 QUIET) +find_package(Boost 1.63.0 QUIET) if (NOT Boost_FOUND) - message(STATUS "Boost 1.57.0 or newer not found, falling back to externals") - set(Boost_INCLUDE_DIR "${CMAKE_SOURCE_DIR}/externals/boost") -endif() -include_directories(${Boost_INCLUDE_DIR}) - -# Include bundled CMake modules -list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/externals/cmake-modules") + message(STATUS "Boost 1.63.0 or newer not found, falling back to externals") -find_package(OpenGL REQUIRED) -include_directories(${OPENGL_INCLUDE_DIR}) + set(BOOST_ROOT "${CMAKE_SOURCE_DIR}/externals/boost") + set(Boost_NO_SYSTEM_PATHS OFF) + find_package(Boost QUIET REQUIRED) +endif() # Prefer the -pthread flag on Linux. -set (THREADS_PREFER_PTHREAD_FLAG ON) +set(THREADS_PREFER_PTHREAD_FLAG ON) find_package(Threads REQUIRED) if (ENABLE_SDL2) @@ -174,10 +185,43 @@ if (ENABLE_SDL2) else() find_package(SDL2 REQUIRED) endif() + + if (SDL2_FOUND) + # TODO(yuriks): Make FindSDL2.cmake export an IMPORTED library instead + add_library(SDL2 INTERFACE) + target_link_libraries(SDL2 INTERFACE "${SDL2_LIBRARY}") + target_include_directories(SDL2 INTERFACE "${SDL2_INCLUDE_DIR}") + endif() else() set(SDL2_FOUND NO) endif() +if (ENABLE_QT) + if (CITRA_USE_BUNDLED_QT) + if (MSVC14 AND ARCHITECTURE_x86_64) + set(QT_VER qt-5.7-msvc2015_64) + else() + message(FATAL_ERROR "No bundled Qt binaries for your toolchain. Disable CITRA_USE_BUNDLED_QT and provide your own.") + endif() + + if (DEFINED QT_VER) + download_bundled_external("qt/" ${QT_VER} QT_PREFIX) + endif() + + set(QT_PREFIX_HINT HINTS "${QT_PREFIX}") + else() + # Passing an empty HINTS seems to cause default system paths to get ignored in CMake 2.8 so + # make sure to not pass anything if we don't have one. + set(QT_PREFIX_HINT) + endif() + + find_package(Qt5 REQUIRED COMPONENTS Widgets OpenGL ${QT_PREFIX_HINT}) +endif() + + +# Platform-specific library requirements +# ====================================== + IF (APPLE) FIND_LIBRARY(COCOA_LIBRARY Cocoa) # Umbrella framework for everything GUI-related set(PLATFORM_LIBRARIES ${COCOA_LIBRARY} ${IOKIT_LIBRARY} ${COREVIDEO_LIBRARY}) @@ -206,28 +250,9 @@ if (UNIX OR MINGW) endif() endif() -if (ENABLE_QT) - if (CITRA_USE_BUNDLED_QT) - if (MSVC14 AND ARCHITECTURE_x86_64) - set(QT_VER qt-5.7-msvc2015_64) - else() - message(FATAL_ERROR "No bundled Qt binaries for your toolchain. Disable CITRA_USE_BUNDLED_QT and provide your own.") - endif() - - if (DEFINED QT_VER) - download_bundled_external("qt/" ${QT_VER} QT_PREFIX) - endif() - set(QT_PREFIX_HINT HINTS "${QT_PREFIX}") - else() - # Passing an empty HINTS seems to cause default system paths to get ignored in CMake 2.8 so - # make sure to not pass anything if we don't have one. - set(QT_PREFIX_HINT) - endif() - - find_package(Qt5 REQUIRED COMPONENTS Widgets OpenGL ${QT_PREFIX_HINT}) - set(CITRA_QT_LIBS Qt5::Widgets Qt5::OpenGL) -endif() +# Include source code +# =================== # This function should be passed a list of all files in a target. It will automatically generate # file groups following the directory hierarchy, so that the layout of the files in IDEs matches the @@ -251,30 +276,13 @@ get_git_head_revision(GIT_REF_SPEC GIT_REV) git_describe(GIT_DESC --always --long --dirty) git_branch_name(GIT_BRANCH) -set(INI_PREFIX "${CMAKE_CURRENT_SOURCE_DIR}/externals/inih") -include_directories(${INI_PREFIX}) -add_subdirectory(${INI_PREFIX}) - add_subdirectory(externals) - -option(DYNARMIC_TESTS OFF) -set(DYNARMIC_NO_BUNDLED_FMT ON) -add_subdirectory(externals/dynarmic) - -add_subdirectory(externals/glad) -include_directories(externals/microprofile) -include_directories(externals/nihstro/include) - -if (MSVC) - add_subdirectory(externals/getopt) -endif() - -# process subdirectories -add_subdirectory(externals/soundtouch) - +add_subdirectory(src) enable_testing() -add_subdirectory(src) + +# Installation instructions +# ========================= # Install freedesktop.org metadata files, following those specifications: # http://standards.freedesktop.org/desktop-entry-spec/desktop-entry-spec-latest.html diff --git a/externals/CMakeLists.txt b/externals/CMakeLists.txt index 57fc5d566..1e04931ee 100644 --- a/externals/CMakeLists.txt +++ b/externals/CMakeLists.txt @@ -1,12 +1,52 @@ +# Definitions for all external bundled libraries + +# Catch +add_library(catch-single-include INTERFACE) +target_include_directories(catch-single-include INTERFACE catch/single_include) + +# Crypto++ +add_subdirectory(cryptopp) + +# Dynarmic +# Dynarmic will skip defining xbyak if it's already defined, we then define it below +add_library(xbyak INTERFACE) +option(DYNARMIC_TESTS OFF) +set(DYNARMIC_NO_BUNDLED_FMT ON) +add_subdirectory(dynarmic) + +# libfmt +add_subdirectory(fmt) + +# getopt +if (MSVC) + add_subdirectory(getopt) +endif() + +# Glad +add_subdirectory(glad) + +# inih +add_subdirectory(inih) + +# MicroProfile +add_library(microprofile INTERFACE) +target_include_directories(microprofile INTERFACE ./microprofile) + +# Nihstro +add_library(nihstro-headers INTERFACE) +target_include_directories(nihstro-headers INTERFACE ./nihstro/include) + +# SoundTouch +add_subdirectory(soundtouch) +# The SoundTouch target doesn't export the necessary include paths as properties by default +target_include_directories(SoundTouch INTERFACE ./soundtouch/include) + # Xbyak if (ARCHITECTURE_x86_64) - add_library(xbyak INTERFACE) - target_include_directories(xbyak INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/xbyak/xbyak) + # Defined before "dynarmic" above + # add_library(xbyak INTERFACE) + target_include_directories(xbyak INTERFACE ./xbyak/xbyak) if (NOT MSVC) target_compile_options(xbyak INTERFACE -fno-operator-names) endif() endif() - -add_subdirectory(cryptopp) - -add_subdirectory(fmt) diff --git a/externals/cryptopp/CMakeLists.txt b/externals/cryptopp/CMakeLists.txt index 653af1e4b..864de18bb 100644 --- a/externals/cryptopp/CMakeLists.txt +++ b/externals/cryptopp/CMakeLists.txt @@ -10,6 +10,7 @@ # - disabled installation # - disabled documentation # - configured to build a static library only +# - adds include directories to the library target include(TestBigEndian) include(CheckCXXCompilerFlag) @@ -148,14 +149,15 @@ endif() # Compile targets #============================================================================ add_library(cryptopp STATIC ${cryptopp_SOURCES}) +target_include_directories(cryptopp INTERFACE .) #============================================================================ # Third-party libraries #============================================================================ if(WIN32) - target_link_libraries(cryptopp ws2_32) + target_link_libraries(cryptopp PRIVATE ws2_32) endif() find_package(Threads) -target_link_libraries(cryptopp ${CMAKE_THREAD_LIBS_INIT}) +target_link_libraries(cryptopp PRIVATE ${CMAKE_THREAD_LIBS_INIT}) diff --git a/externals/glad/CMakeLists.txt b/externals/glad/CMakeLists.txt index a97d4aa73..6d35a844b 100644 --- a/externals/glad/CMakeLists.txt +++ b/externals/glad/CMakeLists.txt @@ -9,6 +9,7 @@ set(HEADERS create_directory_groups(${SRCS} ${HEADERS}) add_library(glad STATIC ${SRCS} ${HEADERS}) target_include_directories(glad PUBLIC "include/") + if ("${CMAKE_SYSTEM_NAME}" MATCHES "Linux") - target_link_libraries(glad dl) + target_link_libraries(glad PRIVATE dl) endif() diff --git a/externals/inih/CMakeLists.txt b/externals/inih/CMakeLists.txt index c87f78bfc..cff36a581 100644 --- a/externals/inih/CMakeLists.txt +++ b/externals/inih/CMakeLists.txt @@ -9,3 +9,4 @@ set(HEADERS create_directory_groups(${SRCS} ${HEADERS}) add_library(inih ${SRCS} ${HEADERS}) +target_include_directories(inih INTERFACE .) diff --git a/src/audio_core/CMakeLists.txt b/src/audio_core/CMakeLists.txt index c571213fc..0ad86bb7a 100644 --- a/src/audio_core/CMakeLists.txt +++ b/src/audio_core/CMakeLists.txt @@ -27,12 +27,9 @@ set(HEADERS time_stretch.h ) -include_directories(../../externals/soundtouch/include) - if(SDL2_FOUND) set(SRCS ${SRCS} sdl2_sink.cpp) set(HEADERS ${HEADERS} sdl2_sink.h) - include_directories(${SDL2_INCLUDE_DIR}) endif() create_directory_groups(${SRCS} ${HEADERS}) @@ -42,6 +39,6 @@ target_link_libraries(audio_core PUBLIC common core) target_link_libraries(audio_core PRIVATE SoundTouch) if(SDL2_FOUND) - target_link_libraries(audio_core PRIVATE ${SDL2_LIBRARY}) + target_link_libraries(audio_core PRIVATE SDL2) target_compile_definitions(audio_core PRIVATE HAVE_SDL2) endif() diff --git a/src/citra/CMakeLists.txt b/src/citra/CMakeLists.txt index 9eddb342b..d72d2b5f4 100644 --- a/src/citra/CMakeLists.txt +++ b/src/citra/CMakeLists.txt @@ -15,15 +15,13 @@ set(HEADERS create_directory_groups(${SRCS} ${HEADERS}) -include_directories(${SDL2_INCLUDE_DIR}) - add_executable(citra ${SRCS} ${HEADERS}) target_link_libraries(citra PRIVATE common core input_common) -target_link_libraries(citra PRIVATE ${SDL2_LIBRARY} ${OPENGL_gl_LIBRARY} inih glad) +target_link_libraries(citra PRIVATE inih glad) if (MSVC) target_link_libraries(citra PRIVATE getopt) endif() -target_link_libraries(citra PRIVATE ${PLATFORM_LIBRARIES} Threads::Threads) +target_link_libraries(citra PRIVATE ${PLATFORM_LIBRARIES} SDL2 Threads::Threads) if(UNIX AND NOT APPLE) install(TARGETS citra RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}/bin") diff --git a/src/citra_qt/CMakeLists.txt b/src/citra_qt/CMakeLists.txt index 809e0b938..4841cbf05 100644 --- a/src/citra_qt/CMakeLists.txt +++ b/src/citra_qt/CMakeLists.txt @@ -92,7 +92,7 @@ else() add_executable(citra-qt ${SRCS} ${HEADERS} ${UI_HDRS}) endif() target_link_libraries(citra-qt PRIVATE audio_core common core input_common video_core) -target_link_libraries(citra-qt PRIVATE ${OPENGL_gl_LIBRARY} ${CITRA_QT_LIBS} glad) +target_link_libraries(citra-qt PRIVATE Boost::boost glad nihstro-headers Qt5::OpenGL Qt5::Widgets) target_link_libraries(citra-qt PRIVATE ${PLATFORM_LIBRARIES} Threads::Threads) if(UNIX AND NOT APPLE) diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index a33a8cdbe..7e83e64b0 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt @@ -95,6 +95,7 @@ endif() create_directory_groups(${SRCS} ${HEADERS}) add_library(common STATIC ${SRCS} ${HEADERS}) +target_link_libraries(common PUBLIC Boost::boost microprofile) if (ARCHITECTURE_x86_64) target_link_libraries(common PRIVATE xbyak) endif() diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index bc3b429b3..d66139c9c 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -378,11 +378,7 @@ set(HEADERS telemetry_session.h ) -include_directories(../../externals/dynarmic/include) -include_directories(../../externals/cryptopp) - create_directory_groups(${SRCS} ${HEADERS}) - add_library(core STATIC ${SRCS} ${HEADERS}) target_link_libraries(core PUBLIC common PRIVATE audio_core video_core) -target_link_libraries(core PRIVATE cryptopp dynarmic) +target_link_libraries(core PUBLIC Boost::boost PRIVATE cryptopp dynarmic) diff --git a/src/input_common/CMakeLists.txt b/src/input_common/CMakeLists.txt index 5b306e42e..e3e36ada7 100644 --- a/src/input_common/CMakeLists.txt +++ b/src/input_common/CMakeLists.txt @@ -13,7 +13,6 @@ set(HEADERS if(SDL2_FOUND) set(SRCS ${SRCS} sdl/sdl.cpp) set(HEADERS ${HEADERS} sdl/sdl.h) - include_directories(${SDL2_INCLUDE_DIR}) endif() create_directory_groups(${SRCS} ${HEADERS}) @@ -22,6 +21,6 @@ add_library(input_common STATIC ${SRCS} ${HEADERS}) target_link_libraries(input_common PUBLIC core PRIVATE common) if(SDL2_FOUND) - target_link_libraries(input_common PRIVATE ${SDL2_LIBRARY}) + target_link_libraries(input_common PRIVATE SDL2) target_compile_definitions(input_common PRIVATE HAVE_SDL2) endif() diff --git a/src/tests/CMakeLists.txt b/src/tests/CMakeLists.txt index 85f2f2985..00d7c636a 100644 --- a/src/tests/CMakeLists.txt +++ b/src/tests/CMakeLists.txt @@ -10,11 +10,9 @@ set(HEADERS create_directory_groups(${SRCS} ${HEADERS}) -include_directories(../../externals/catch/single_include/) - add_executable(tests ${SRCS} ${HEADERS}) target_link_libraries(tests PRIVATE common core) target_link_libraries(tests PRIVATE glad) # To support linker work-around -target_link_libraries(tests PRIVATE ${PLATFORM_LIBRARIES} Threads::Threads) +target_link_libraries(tests PRIVATE ${PLATFORM_LIBRARIES} catch-single-include Threads::Threads) -add_test(NAME tests COMMAND $<TARGET_FILE:tests>) +add_test(NAME tests COMMAND tests) diff --git a/src/video_core/CMakeLists.txt b/src/video_core/CMakeLists.txt index e455f03bd..0961a3251 100644 --- a/src/video_core/CMakeLists.txt +++ b/src/video_core/CMakeLists.txt @@ -80,14 +80,13 @@ create_directory_groups(${SRCS} ${HEADERS}) add_library(video_core STATIC ${SRCS} ${HEADERS}) target_link_libraries(video_core PUBLIC common core) -target_link_libraries(video_core PRIVATE glad) +target_link_libraries(video_core PRIVATE glad nihstro-headers) if (ARCHITECTURE_x86_64) target_link_libraries(video_core PRIVATE xbyak) endif() if (PNG_FOUND) - target_link_libraries(video_core PRIVATE ${PNG_LIBRARIES}) - target_include_directories(video_core PRIVATE ${PNG_INCLUDE_DIRS}) - target_compile_definitions(video_core PRIVATE ${PNG_DEFINITIONS}) + target_link_libraries(video_core PRIVATE PNG::PNG) + target_compile_definitions(video_core PRIVATE HAVE_PNG) endif() diff --git a/src/video_core/regs_texturing.h b/src/video_core/regs_texturing.h index e4038b41b..3f5355fa9 100644 --- a/src/video_core/regs_texturing.h +++ b/src/video_core/regs_texturing.h @@ -133,7 +133,32 @@ struct TexturingRegs { BitField<16, 1, u32> clear_texture_cache; // TODO: unimplemented } main_config; TextureConfig texture0; - INSERT_PADDING_WORDS(0x8); + + enum class CubeFace { + PositiveX = 0, + NegativeX = 1, + PositiveY = 2, + NegativeY = 3, + PositiveZ = 4, + NegativeZ = 5, + }; + + BitField<0, 22, u32> cube_address[5]; + + PAddr GetCubePhysicalAddress(CubeFace face) const { + PAddr address = texture0.address; + if (face != CubeFace::PositiveX) { + // Bits [22:27] from the main texture address is shared with all cubemap additional + // addresses. + auto& face_addr = cube_address[static_cast<size_t>(face) - 1]; + address &= ~face_addr.mask; + address |= face_addr; + } + // A multiplier of 8 is also needed in the same way as the main address. + return address * 8; + } + + INSERT_PADDING_WORDS(0x3); BitField<0, 4, TextureFormat> texture0_format; BitField<0, 1, u32> fragment_lighting_enable; INSERT_PADDING_WORDS(0x1); diff --git a/src/video_core/swrasterizer/rasterizer.cpp b/src/video_core/swrasterizer/rasterizer.cpp index e9edf0360..8b7b1defb 100644 --- a/src/video_core/swrasterizer/rasterizer.cpp +++ b/src/video_core/swrasterizer/rasterizer.cpp @@ -5,6 +5,7 @@ #include <algorithm> #include <array> #include <cmath> +#include <tuple> #include "common/assert.h" #include "common/bit_field.h" #include "common/color.h" @@ -70,6 +71,49 @@ static int SignedArea(const Math::Vec2<Fix12P4>& vtx1, const Math::Vec2<Fix12P4> return Math::Cross(vec1, vec2).z; }; +/// Convert a 3D vector for cube map coordinates to 2D texture coordinates along with the face name +static std::tuple<float24, float24, PAddr> ConvertCubeCoord(float24 u, float24 v, float24 w, + const TexturingRegs& regs) { + const float abs_u = std::abs(u.ToFloat32()); + const float abs_v = std::abs(v.ToFloat32()); + const float abs_w = std::abs(w.ToFloat32()); + float24 x, y, z; + PAddr addr; + if (abs_u > abs_v && abs_u > abs_w) { + if (u > float24::FromFloat32(0)) { + addr = regs.GetCubePhysicalAddress(TexturingRegs::CubeFace::PositiveX); + y = -v; + } else { + addr = regs.GetCubePhysicalAddress(TexturingRegs::CubeFace::NegativeX); + y = v; + } + x = -w; + z = u; + } else if (abs_v > abs_w) { + if (v > float24::FromFloat32(0)) { + addr = regs.GetCubePhysicalAddress(TexturingRegs::CubeFace::PositiveY); + x = u; + } else { + addr = regs.GetCubePhysicalAddress(TexturingRegs::CubeFace::NegativeY); + x = -u; + } + y = w; + z = v; + } else { + if (w > float24::FromFloat32(0)) { + addr = regs.GetCubePhysicalAddress(TexturingRegs::CubeFace::PositiveZ); + y = -v; + } else { + addr = regs.GetCubePhysicalAddress(TexturingRegs::CubeFace::NegativeZ); + y = v; + } + x = u; + z = w; + } + const float24 half = float24::FromFloat32(0.5f); + return std::make_tuple(x / z * half + half, y / z * half + half, addr); +} + MICROPROFILE_DEFINE(GPU_Rasterization, "GPU", "Rasterization", MP_RGB(50, 50, 240)); /** @@ -284,10 +328,16 @@ static void ProcessTriangleInternal(const Vertex& v0, const Vertex& v1, const Ve // Only unit 0 respects the texturing type (according to 3DBrew) // TODO: Refactor so cubemaps and shadowmaps can be handled + PAddr texture_address = texture.config.GetPhysicalAddress(); if (i == 0) { switch (texture.config.type) { case TexturingRegs::TextureConfig::Texture2D: break; + case TexturingRegs::TextureConfig::TextureCube: { + auto w = GetInterpolatedAttribute(v0.tc0_w, v1.tc0_w, v2.tc0_w); + std::tie(u, v, texture_address) = ConvertCubeCoord(u, v, w, regs.texturing); + break; + } case TexturingRegs::TextureConfig::Projection2D: { auto tc0_w = GetInterpolatedAttribute(v0.tc0_w, v1.tc0_w, v2.tc0_w); u /= tc0_w; @@ -322,8 +372,7 @@ static void ProcessTriangleInternal(const Vertex& v0, const Vertex& v1, const Ve t = texture.config.height - 1 - GetWrappedTexCoord(texture.config.wrap_t, t, texture.config.height); - u8* texture_data = - Memory::GetPhysicalPointer(texture.config.GetPhysicalAddress()); + const u8* texture_data = Memory::GetPhysicalPointer(texture_address); auto info = Texture::TextureInfo::FromPicaRegister(texture.config, texture.format); |