diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/common/vector_math.h | 12 | ||||
| -rw-r--r-- | src/core/memory.cpp | 17 | ||||
| -rw-r--r-- | src/video_core/swrasterizer/clipper.cpp | 2 |
3 files changed, 25 insertions, 6 deletions
diff --git a/src/common/vector_math.h b/src/common/vector_math.h index 6e2a5ad60..2b05f66ee 100644 --- a/src/common/vector_math.h +++ b/src/common/vector_math.h | |||
| @@ -31,6 +31,7 @@ | |||
| 31 | #pragma once | 31 | #pragma once |
| 32 | 32 | ||
| 33 | #include <cmath> | 33 | #include <cmath> |
| 34 | #include <type_traits> | ||
| 34 | 35 | ||
| 35 | namespace Math { | 36 | namespace Math { |
| 36 | 37 | ||
| @@ -90,7 +91,8 @@ public: | |||
| 90 | y -= other.y; | 91 | y -= other.y; |
| 91 | } | 92 | } |
| 92 | 93 | ||
| 93 | Vec2<decltype(-T{})> operator-() const { | 94 | template <typename U = T> |
| 95 | Vec2<std::enable_if_t<std::is_signed<U>::value, U>> operator-() const { | ||
| 94 | return MakeVec(-x, -y); | 96 | return MakeVec(-x, -y); |
| 95 | } | 97 | } |
| 96 | Vec2<decltype(T{} * T{})> operator*(const Vec2& other) const { | 98 | Vec2<decltype(T{} * T{})> operator*(const Vec2& other) const { |
| @@ -247,7 +249,8 @@ public: | |||
| 247 | z -= other.z; | 249 | z -= other.z; |
| 248 | } | 250 | } |
| 249 | 251 | ||
| 250 | Vec3<decltype(-T{})> operator-() const { | 252 | template <typename U = T> |
| 253 | Vec3<std::enable_if_t<std::is_signed<U>::value, U>> operator-() const { | ||
| 251 | return MakeVec(-x, -y, -z); | 254 | return MakeVec(-x, -y, -z); |
| 252 | } | 255 | } |
| 253 | Vec3<decltype(T{} * T{})> operator*(const Vec3& other) const { | 256 | Vec3<decltype(T{} * T{})> operator*(const Vec3& other) const { |
| @@ -462,7 +465,8 @@ public: | |||
| 462 | w -= other.w; | 465 | w -= other.w; |
| 463 | } | 466 | } |
| 464 | 467 | ||
| 465 | Vec4<decltype(-T{})> operator-() const { | 468 | template <typename U = T> |
| 469 | Vec4<std::enable_if_t<std::is_signed<U>::value, U>> operator-() const { | ||
| 466 | return MakeVec(-x, -y, -z, -w); | 470 | return MakeVec(-x, -y, -z, -w); |
| 467 | } | 471 | } |
| 468 | Vec4<decltype(T{} * T{})> operator*(const Vec4& other) const { | 472 | Vec4<decltype(T{} * T{})> operator*(const Vec4& other) const { |
| @@ -720,4 +724,4 @@ static inline Vec4<T> MakeVec(const T& x, const Vec3<T>& yzw) { | |||
| 720 | return MakeVec(x, yzw[0], yzw[1], yzw[2]); | 724 | return MakeVec(x, yzw[0], yzw[1], yzw[2]); |
| 721 | } | 725 | } |
| 722 | 726 | ||
| 723 | } // namespace | 727 | } // namespace Math |
diff --git a/src/core/memory.cpp b/src/core/memory.cpp index c42f4326b..5ea0694a9 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp | |||
| @@ -336,8 +336,15 @@ void RasterizerMarkRegionCached(PAddr start, u32 size, int count_delta) { | |||
| 336 | 336 | ||
| 337 | for (unsigned i = 0; i < num_pages; ++i, paddr += PAGE_SIZE) { | 337 | for (unsigned i = 0; i < num_pages; ++i, paddr += PAGE_SIZE) { |
| 338 | boost::optional<VAddr> maybe_vaddr = PhysicalToVirtualAddress(paddr); | 338 | boost::optional<VAddr> maybe_vaddr = PhysicalToVirtualAddress(paddr); |
| 339 | if (!maybe_vaddr) | 339 | // While the physical <-> virtual mapping is 1:1 for the regions supported by the cache, |
| 340 | // some games (like Pokemon Super Mystery Dungeon) will try to use textures that go beyond | ||
| 341 | // the end address of VRAM, causing the Virtual->Physical translation to fail when flushing | ||
| 342 | // parts of the texture. | ||
| 343 | if (!maybe_vaddr) { | ||
| 344 | LOG_ERROR(HW_Memory, | ||
| 345 | "Trying to flush a cached region to an invalid physical address %08X", paddr); | ||
| 340 | continue; | 346 | continue; |
| 347 | } | ||
| 341 | VAddr vaddr = *maybe_vaddr; | 348 | VAddr vaddr = *maybe_vaddr; |
| 342 | 349 | ||
| 343 | u8& res_count = current_page_table->cached_res_count[vaddr >> PAGE_BITS]; | 350 | u8& res_count = current_page_table->cached_res_count[vaddr >> PAGE_BITS]; |
| @@ -349,6 +356,10 @@ void RasterizerMarkRegionCached(PAddr start, u32 size, int count_delta) { | |||
| 349 | if (res_count == 0) { | 356 | if (res_count == 0) { |
| 350 | PageType& page_type = current_page_table->attributes[vaddr >> PAGE_BITS]; | 357 | PageType& page_type = current_page_table->attributes[vaddr >> PAGE_BITS]; |
| 351 | switch (page_type) { | 358 | switch (page_type) { |
| 359 | case PageType::Unmapped: | ||
| 360 | // It is not necessary for a process to have this region mapped into its address | ||
| 361 | // space, for example, a system module need not have a VRAM mapping. | ||
| 362 | break; | ||
| 352 | case PageType::Memory: | 363 | case PageType::Memory: |
| 353 | page_type = PageType::RasterizerCachedMemory; | 364 | page_type = PageType::RasterizerCachedMemory; |
| 354 | current_page_table->pointers[vaddr >> PAGE_BITS] = nullptr; | 365 | current_page_table->pointers[vaddr >> PAGE_BITS] = nullptr; |
| @@ -367,6 +378,10 @@ void RasterizerMarkRegionCached(PAddr start, u32 size, int count_delta) { | |||
| 367 | if (res_count == 0) { | 378 | if (res_count == 0) { |
| 368 | PageType& page_type = current_page_table->attributes[vaddr >> PAGE_BITS]; | 379 | PageType& page_type = current_page_table->attributes[vaddr >> PAGE_BITS]; |
| 369 | switch (page_type) { | 380 | switch (page_type) { |
| 381 | case PageType::Unmapped: | ||
| 382 | // It is not necessary for a process to have this region mapped into its address | ||
| 383 | // space, for example, a system module need not have a VRAM mapping. | ||
| 384 | break; | ||
| 370 | case PageType::RasterizerCachedMemory: { | 385 | case PageType::RasterizerCachedMemory: { |
| 371 | u8* pointer = GetPointerFromVMA(vaddr & ~PAGE_MASK); | 386 | u8* pointer = GetPointerFromVMA(vaddr & ~PAGE_MASK); |
| 372 | if (pointer == nullptr) { | 387 | if (pointer == nullptr) { |
diff --git a/src/video_core/swrasterizer/clipper.cpp b/src/video_core/swrasterizer/clipper.cpp index a52129eb7..c1ed48398 100644 --- a/src/video_core/swrasterizer/clipper.cpp +++ b/src/video_core/swrasterizer/clipper.cpp | |||
| @@ -98,7 +98,7 @@ void ProcessTriangle(const OutputVertex& v0, const OutputVertex& v1, const Outpu | |||
| 98 | 98 | ||
| 99 | auto FlipQuaternionIfOpposite = [](auto& a, const auto& b) { | 99 | auto FlipQuaternionIfOpposite = [](auto& a, const auto& b) { |
| 100 | if (Math::Dot(a, b) < float24::Zero()) | 100 | if (Math::Dot(a, b) < float24::Zero()) |
| 101 | a = -a; | 101 | a = a * float24::FromFloat32(-1.0f); |
| 102 | }; | 102 | }; |
| 103 | 103 | ||
| 104 | // Flip the quaternions if they are opposite to prevent interpolating them over the wrong | 104 | // Flip the quaternions if they are opposite to prevent interpolating them over the wrong |