diff options
| author | 2015-09-09 18:30:03 -0400 | |
|---|---|---|
| committer | 2016-02-05 17:17:26 -0500 | |
| commit | 38c7b20475cb2c718b2d126acf07dd480c9b5038 (patch) | |
| tree | 476e6d830044426d5455a66c1752dbf66cf8882d /src | |
| parent | Merge pull request #1391 from tfarley/hw-fb-sync-fix (diff) | |
| download | yuzu-38c7b20475cb2c718b2d126acf07dd480c9b5038.tar.gz yuzu-38c7b20475cb2c718b2d126acf07dd480c9b5038.tar.xz yuzu-38c7b20475cb2c718b2d126acf07dd480c9b5038.zip | |
pica: Add pica_types module and move float24 definition.
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | src/video_core/pica.h | 114 | ||||
| -rw-r--r-- | src/video_core/pica_types.h | 124 |
3 files changed, 127 insertions, 112 deletions
diff --git a/src/video_core/CMakeLists.txt b/src/video_core/CMakeLists.txt index c3d7294d5..4b5d298f3 100644 --- a/src/video_core/CMakeLists.txt +++ b/src/video_core/CMakeLists.txt | |||
| @@ -33,6 +33,7 @@ set(HEADERS | |||
| 33 | command_processor.h | 33 | command_processor.h |
| 34 | gpu_debugger.h | 34 | gpu_debugger.h |
| 35 | pica.h | 35 | pica.h |
| 36 | pica_types.h | ||
| 36 | primitive_assembly.h | 37 | primitive_assembly.h |
| 37 | rasterizer.h | 38 | rasterizer.h |
| 38 | rasterizer_interface.h | 39 | rasterizer_interface.h |
diff --git a/src/video_core/pica.h b/src/video_core/pica.h index 2f1b2dec4..b8db7869a 100644 --- a/src/video_core/pica.h +++ b/src/video_core/pica.h | |||
| @@ -16,6 +16,8 @@ | |||
| 16 | #include "common/vector_math.h" | 16 | #include "common/vector_math.h" |
| 17 | #include "common/logging/log.h" | 17 | #include "common/logging/log.h" |
| 18 | 18 | ||
| 19 | #include "pica_types.h" | ||
| 20 | |||
| 19 | namespace Pica { | 21 | namespace Pica { |
| 20 | 22 | ||
| 21 | // Returns index corresponding to the Regs member labeled by field_name | 23 | // Returns index corresponding to the Regs member labeled by field_name |
| @@ -1026,118 +1028,6 @@ static_assert(sizeof(Regs::ShaderConfig) == 0x30 * sizeof(u32), "ShaderConfig st | |||
| 1026 | static_assert(sizeof(Regs) <= 0x300 * sizeof(u32), "Register set structure larger than it should be"); | 1028 | static_assert(sizeof(Regs) <= 0x300 * sizeof(u32), "Register set structure larger than it should be"); |
| 1027 | static_assert(sizeof(Regs) >= 0x300 * sizeof(u32), "Register set structure smaller than it should be"); | 1029 | static_assert(sizeof(Regs) >= 0x300 * sizeof(u32), "Register set structure smaller than it should be"); |
| 1028 | 1030 | ||
| 1029 | struct float24 { | ||
| 1030 | static float24 FromFloat32(float val) { | ||
| 1031 | float24 ret; | ||
| 1032 | ret.value = val; | ||
| 1033 | return ret; | ||
| 1034 | } | ||
| 1035 | |||
| 1036 | // 16 bit mantissa, 7 bit exponent, 1 bit sign | ||
| 1037 | // TODO: No idea if this works as intended | ||
| 1038 | static float24 FromRawFloat24(u32 hex) { | ||
| 1039 | float24 ret; | ||
| 1040 | if ((hex & 0xFFFFFF) == 0) { | ||
| 1041 | ret.value = 0; | ||
| 1042 | } else { | ||
| 1043 | u32 mantissa = hex & 0xFFFF; | ||
| 1044 | u32 exponent = (hex >> 16) & 0x7F; | ||
| 1045 | u32 sign = hex >> 23; | ||
| 1046 | ret.value = std::pow(2.0f, (float)exponent-63.0f) * (1.0f + mantissa * std::pow(2.0f, -16.f)); | ||
| 1047 | if (sign) | ||
| 1048 | ret.value = -ret.value; | ||
| 1049 | } | ||
| 1050 | return ret; | ||
| 1051 | } | ||
| 1052 | |||
| 1053 | static float24 Zero() { | ||
| 1054 | return FromFloat32(0.f); | ||
| 1055 | } | ||
| 1056 | |||
| 1057 | // Not recommended for anything but logging | ||
| 1058 | float ToFloat32() const { | ||
| 1059 | return value; | ||
| 1060 | } | ||
| 1061 | |||
| 1062 | float24 operator * (const float24& flt) const { | ||
| 1063 | if ((this->value == 0.f && !std::isnan(flt.value)) || | ||
| 1064 | (flt.value == 0.f && !std::isnan(this->value))) | ||
| 1065 | // PICA gives 0 instead of NaN when multiplying by inf | ||
| 1066 | return Zero(); | ||
| 1067 | return float24::FromFloat32(ToFloat32() * flt.ToFloat32()); | ||
| 1068 | } | ||
| 1069 | |||
| 1070 | float24 operator / (const float24& flt) const { | ||
| 1071 | return float24::FromFloat32(ToFloat32() / flt.ToFloat32()); | ||
| 1072 | } | ||
| 1073 | |||
| 1074 | float24 operator + (const float24& flt) const { | ||
| 1075 | return float24::FromFloat32(ToFloat32() + flt.ToFloat32()); | ||
| 1076 | } | ||
| 1077 | |||
| 1078 | float24 operator - (const float24& flt) const { | ||
| 1079 | return float24::FromFloat32(ToFloat32() - flt.ToFloat32()); | ||
| 1080 | } | ||
| 1081 | |||
| 1082 | float24& operator *= (const float24& flt) { | ||
| 1083 | if ((this->value == 0.f && !std::isnan(flt.value)) || | ||
| 1084 | (flt.value == 0.f && !std::isnan(this->value))) | ||
| 1085 | // PICA gives 0 instead of NaN when multiplying by inf | ||
| 1086 | *this = Zero(); | ||
| 1087 | else value *= flt.ToFloat32(); | ||
| 1088 | return *this; | ||
| 1089 | } | ||
| 1090 | |||
| 1091 | float24& operator /= (const float24& flt) { | ||
| 1092 | value /= flt.ToFloat32(); | ||
| 1093 | return *this; | ||
| 1094 | } | ||
| 1095 | |||
| 1096 | float24& operator += (const float24& flt) { | ||
| 1097 | value += flt.ToFloat32(); | ||
| 1098 | return *this; | ||
| 1099 | } | ||
| 1100 | |||
| 1101 | float24& operator -= (const float24& flt) { | ||
| 1102 | value -= flt.ToFloat32(); | ||
| 1103 | return *this; | ||
| 1104 | } | ||
| 1105 | |||
| 1106 | float24 operator - () const { | ||
| 1107 | return float24::FromFloat32(-ToFloat32()); | ||
| 1108 | } | ||
| 1109 | |||
| 1110 | bool operator < (const float24& flt) const { | ||
| 1111 | return ToFloat32() < flt.ToFloat32(); | ||
| 1112 | } | ||
| 1113 | |||
| 1114 | bool operator > (const float24& flt) const { | ||
| 1115 | return ToFloat32() > flt.ToFloat32(); | ||
| 1116 | } | ||
| 1117 | |||
| 1118 | bool operator >= (const float24& flt) const { | ||
| 1119 | return ToFloat32() >= flt.ToFloat32(); | ||
| 1120 | } | ||
| 1121 | |||
| 1122 | bool operator <= (const float24& flt) const { | ||
| 1123 | return ToFloat32() <= flt.ToFloat32(); | ||
| 1124 | } | ||
| 1125 | |||
| 1126 | bool operator == (const float24& flt) const { | ||
| 1127 | return ToFloat32() == flt.ToFloat32(); | ||
| 1128 | } | ||
| 1129 | |||
| 1130 | bool operator != (const float24& flt) const { | ||
| 1131 | return ToFloat32() != flt.ToFloat32(); | ||
| 1132 | } | ||
| 1133 | |||
| 1134 | private: | ||
| 1135 | // Stored as a regular float, merely for convenience | ||
| 1136 | // TODO: Perform proper arithmetic on this! | ||
| 1137 | float value; | ||
| 1138 | }; | ||
| 1139 | static_assert(sizeof(float24) == sizeof(float), "Shader JIT assumes float24 is implemented as a 32-bit float"); | ||
| 1140 | |||
| 1141 | /// Struct used to describe current Pica state | 1031 | /// Struct used to describe current Pica state |
| 1142 | struct State { | 1032 | struct State { |
| 1143 | /// Pica registers | 1033 | /// Pica registers |
diff --git a/src/video_core/pica_types.h b/src/video_core/pica_types.h new file mode 100644 index 000000000..de798aa81 --- /dev/null +++ b/src/video_core/pica_types.h | |||
| @@ -0,0 +1,124 @@ | |||
| 1 | // Copyright 2015 Citra Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | #include "common/common_types.h" | ||
| 8 | |||
| 9 | namespace Pica { | ||
| 10 | |||
| 11 | struct float24 { | ||
| 12 | static float24 FromFloat32(float val) { | ||
| 13 | float24 ret; | ||
| 14 | ret.value = val; | ||
| 15 | return ret; | ||
| 16 | } | ||
| 17 | |||
| 18 | // 16 bit mantissa, 7 bit exponent, 1 bit sign | ||
| 19 | // TODO: No idea if this works as intended | ||
| 20 | static float24 FromRawFloat24(u32 hex) { | ||
| 21 | float24 ret; | ||
| 22 | if ((hex & 0xFFFFFF) == 0) { | ||
| 23 | ret.value = 0; | ||
| 24 | } else { | ||
| 25 | u32 mantissa = hex & 0xFFFF; | ||
| 26 | u32 exponent = (hex >> 16) & 0x7F; | ||
| 27 | u32 sign = hex >> 23; | ||
| 28 | ret.value = std::pow(2.0f, (float)exponent-63.0f) * (1.0f + mantissa * std::pow(2.0f, -16.f)); | ||
| 29 | if (sign) | ||
| 30 | ret.value = -ret.value; | ||
| 31 | } | ||
| 32 | return ret; | ||
| 33 | } | ||
| 34 | |||
| 35 | static float24 Zero() { | ||
| 36 | return FromFloat32(0.f); | ||
| 37 | } | ||
| 38 | |||
| 39 | // Not recommended for anything but logging | ||
| 40 | float ToFloat32() const { | ||
| 41 | return value; | ||
| 42 | } | ||
| 43 | |||
| 44 | float24 operator * (const float24& flt) const { | ||
| 45 | if ((this->value == 0.f && !std::isnan(flt.value)) || | ||
| 46 | (flt.value == 0.f && !std::isnan(this->value))) | ||
| 47 | // PICA gives 0 instead of NaN when multiplying by inf | ||
| 48 | return Zero(); | ||
| 49 | return float24::FromFloat32(ToFloat32() * flt.ToFloat32()); | ||
| 50 | } | ||
| 51 | |||
| 52 | float24 operator / (const float24& flt) const { | ||
| 53 | return float24::FromFloat32(ToFloat32() / flt.ToFloat32()); | ||
| 54 | } | ||
| 55 | |||
| 56 | float24 operator + (const float24& flt) const { | ||
| 57 | return float24::FromFloat32(ToFloat32() + flt.ToFloat32()); | ||
| 58 | } | ||
| 59 | |||
| 60 | float24 operator - (const float24& flt) const { | ||
| 61 | return float24::FromFloat32(ToFloat32() - flt.ToFloat32()); | ||
| 62 | } | ||
| 63 | |||
| 64 | float24& operator *= (const float24& flt) { | ||
| 65 | if ((this->value == 0.f && !std::isnan(flt.value)) || | ||
| 66 | (flt.value == 0.f && !std::isnan(this->value))) | ||
| 67 | // PICA gives 0 instead of NaN when multiplying by inf | ||
| 68 | *this = Zero(); | ||
| 69 | else value *= flt.ToFloat32(); | ||
| 70 | return *this; | ||
| 71 | } | ||
| 72 | |||
| 73 | float24& operator /= (const float24& flt) { | ||
| 74 | value /= flt.ToFloat32(); | ||
| 75 | return *this; | ||
| 76 | } | ||
| 77 | |||
| 78 | float24& operator += (const float24& flt) { | ||
| 79 | value += flt.ToFloat32(); | ||
| 80 | return *this; | ||
| 81 | } | ||
| 82 | |||
| 83 | float24& operator -= (const float24& flt) { | ||
| 84 | value -= flt.ToFloat32(); | ||
| 85 | return *this; | ||
| 86 | } | ||
| 87 | |||
| 88 | float24 operator - () const { | ||
| 89 | return float24::FromFloat32(-ToFloat32()); | ||
| 90 | } | ||
| 91 | |||
| 92 | bool operator < (const float24& flt) const { | ||
| 93 | return ToFloat32() < flt.ToFloat32(); | ||
| 94 | } | ||
| 95 | |||
| 96 | bool operator > (const float24& flt) const { | ||
| 97 | return ToFloat32() > flt.ToFloat32(); | ||
| 98 | } | ||
| 99 | |||
| 100 | bool operator >= (const float24& flt) const { | ||
| 101 | return ToFloat32() >= flt.ToFloat32(); | ||
| 102 | } | ||
| 103 | |||
| 104 | bool operator <= (const float24& flt) const { | ||
| 105 | return ToFloat32() <= flt.ToFloat32(); | ||
| 106 | } | ||
| 107 | |||
| 108 | bool operator == (const float24& flt) const { | ||
| 109 | return ToFloat32() == flt.ToFloat32(); | ||
| 110 | } | ||
| 111 | |||
| 112 | bool operator != (const float24& flt) const { | ||
| 113 | return ToFloat32() != flt.ToFloat32(); | ||
| 114 | } | ||
| 115 | |||
| 116 | private: | ||
| 117 | // Stored as a regular float, merely for convenience | ||
| 118 | // TODO: Perform proper arithmetic on this! | ||
| 119 | float value; | ||
| 120 | }; | ||
| 121 | |||
| 122 | static_assert(sizeof(float24) == sizeof(float), "Shader JIT assumes float24 is implemented as a 32-bit float"); | ||
| 123 | |||
| 124 | } // namespace Pica | ||