summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/common/vector_math.h12
-rw-r--r--src/core/memory.cpp17
-rw-r--r--src/video_core/swrasterizer/clipper.cpp2
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
35namespace Math { 36namespace 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