diff options
| author | 2014-08-11 22:21:54 -0400 | |
|---|---|---|
| committer | 2014-08-11 22:21:54 -0400 | |
| commit | a3e029fad0610d9e045b79cdc545dec3e7327ff7 (patch) | |
| tree | 76f32e7dc447e661f9f34303609cf4aed23d7a5b /src/video_core | |
| parent | Merge pull request #40 from bentley/master (diff) | |
| parent | Remove the fancy RegisterSet class introduced in 4c2bff61e. (diff) | |
| download | yuzu-a3e029fad0610d9e045b79cdc545dec3e7327ff7.tar.gz yuzu-a3e029fad0610d9e045b79cdc545dec3e7327ff7.tar.xz yuzu-a3e029fad0610d9e045b79cdc545dec3e7327ff7.zip | |
Merge pull request #38 from neobrain/replace_registerset
Remove the fancy RegisterSet class introduced in 4c2bff61e.
Diffstat (limited to 'src/video_core')
| -rw-r--r-- | src/video_core/pica.h | 242 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/renderer_opengl.cpp | 4 |
2 files changed, 146 insertions, 100 deletions
diff --git a/src/video_core/pica.h b/src/video_core/pica.h index f0fa3aba9..d64559d72 100644 --- a/src/video_core/pica.h +++ b/src/video_core/pica.h | |||
| @@ -4,127 +4,173 @@ | |||
| 4 | 4 | ||
| 5 | #pragma once | 5 | #pragma once |
| 6 | 6 | ||
| 7 | #include <cstddef> | ||
| 7 | #include <initializer_list> | 8 | #include <initializer_list> |
| 8 | #include <map> | 9 | #include <map> |
| 9 | 10 | ||
| 10 | #include "common/bit_field.h" | 11 | #include "common/bit_field.h" |
| 11 | #include "common/common_types.h" | 12 | #include "common/common_types.h" |
| 12 | #include "common/register_set.h" | ||
| 13 | 13 | ||
| 14 | namespace Pica { | 14 | namespace Pica { |
| 15 | 15 | ||
| 16 | // Returns index corresponding to the Regs member labeled by field_name | ||
| 17 | // TODO: Due to Visual studio bug 209229, offsetof does not return constant expressions | ||
| 18 | // when used with array elements (e.g. PICA_REG_INDEX(vs_uniform_setup.set_value[1])). | ||
| 19 | // For details cf. https://connect.microsoft.com/VisualStudio/feedback/details/209229/offsetof-does-not-produce-a-constant-expression-for-array-members | ||
| 20 | // Hopefully, this will be fixed sometime in the future. | ||
| 21 | // For lack of better alternatives, we currently hardcode the offsets when constant | ||
| 22 | // expressions are needed via PICA_REG_INDEX_WORKAROUND (on sane compilers, static_asserts | ||
| 23 | // will then make sure the offsets indeed match the automatically calculated ones). | ||
| 24 | #define PICA_REG_INDEX(field_name) (offsetof(Pica::Regs, field_name) / sizeof(u32)) | ||
| 25 | #if defined(_MSC_VER) | ||
| 26 | #define PICA_REG_INDEX_WORKAROUND(field_name, backup_workaround_index) (backup_workaround_index) | ||
| 27 | #else | ||
| 28 | // NOTE: Yeah, hacking in a static_assert here just to workaround the lacking MSVC compiler | ||
| 29 | // really is this annoying. This macro just forwards its first argument to PICA_REG_INDEX | ||
| 30 | // and then performs a (no-op) cast to size_t iff the second argument matches the expected | ||
| 31 | // field offset. Otherwise, the compiler will fail to compile this code. | ||
| 32 | #define PICA_REG_INDEX_WORKAROUND(field_name, backup_workaround_index) \ | ||
| 33 | ((typename std::enable_if<backup_workaround_index == PICA_REG_INDEX(field_name), size_t>::type)PICA_REG_INDEX(field_name)) | ||
| 34 | #endif // _MSC_VER | ||
| 35 | |||
| 16 | struct Regs { | 36 | struct Regs { |
| 17 | enum Id : u32 { | 37 | |
| 18 | ViewportSizeX = 0x41, | 38 | // helper macro to properly align structure members. |
| 19 | ViewportInvSizeX = 0x42, | 39 | // Calling INSERT_PADDING_WORDS will add a new member variable with a name like "pad121", |
| 20 | ViewportSizeY = 0x43, | 40 | // depending on the current source line to make sure variable names are unique. |
| 21 | ViewportInvSizeY = 0x44, | 41 | #define INSERT_PADDING_WORDS_HELPER1(x, y) x ## y |
| 22 | ViewportCorner = 0x68, | 42 | #define INSERT_PADDING_WORDS_HELPER2(x, y) INSERT_PADDING_WORDS_HELPER1(x, y) |
| 23 | DepthBufferFormat = 0x116, | 43 | #define INSERT_PADDING_WORDS(num_words) u32 INSERT_PADDING_WORDS_HELPER2(pad, __LINE__)[(num_words)]; |
| 24 | ColorBufferFormat = 0x117, | 44 | |
| 25 | DepthBufferAddress = 0x11C, | 45 | INSERT_PADDING_WORDS(0x41); |
| 26 | ColorBufferAddress = 0x11D, | 46 | |
| 27 | ColorBufferSize = 0x11E, | 47 | BitField<0, 24, u32> viewport_size_x; |
| 28 | 48 | INSERT_PADDING_WORDS(1); | |
| 29 | VertexArrayBaseAddr = 0x200, | 49 | BitField<0, 24, u32> viewport_size_y; |
| 30 | VertexDescriptor = 0x201, // 0x202 | 50 | |
| 31 | VertexAttributeOffset = 0x203, // 0x206,0x209,0x20C,0x20F,0x212,0x215,0x218,0x21B,0x21E,0x221,0x224 | 51 | INSERT_PADDING_WORDS(0x1bc); |
| 32 | VertexAttributeInfo0 = 0x204, // 0x207,0x20A,0x20D,0x210,0x213,0x216,0x219,0x21C,0x21F,0x222,0x225 | 52 | |
| 33 | VertexAttributeInfo1 = 0x205, // 0x208,0x20B,0x20E,0x211,0x214,0x217,0x21A,0x21D,0x220,0x223,0x226 | 53 | union { |
| 34 | 54 | enum class Format : u64 { | |
| 35 | NumIds = 0x300, | 55 | BYTE = 0, |
| 36 | }; | 56 | UBYTE = 1, |
| 37 | 57 | SHORT = 2, | |
| 38 | template<Id id> | 58 | FLOAT = 3, |
| 39 | union Struct; | 59 | }; |
| 60 | |||
| 61 | BitField< 0, 2, Format> format0; | ||
| 62 | BitField< 2, 2, u64> size0; // number of elements minus 1 | ||
| 63 | BitField< 4, 2, Format> format1; | ||
| 64 | BitField< 6, 2, u64> size1; | ||
| 65 | BitField< 8, 2, Format> format2; | ||
| 66 | BitField<10, 2, u64> size2; | ||
| 67 | BitField<12, 2, Format> format3; | ||
| 68 | BitField<14, 2, u64> size3; | ||
| 69 | BitField<16, 2, Format> format4; | ||
| 70 | BitField<18, 2, u64> size4; | ||
| 71 | BitField<20, 2, Format> format5; | ||
| 72 | BitField<22, 2, u64> size5; | ||
| 73 | BitField<24, 2, Format> format6; | ||
| 74 | BitField<26, 2, u64> size6; | ||
| 75 | BitField<28, 2, Format> format7; | ||
| 76 | BitField<30, 2, u64> size7; | ||
| 77 | BitField<32, 2, Format> format8; | ||
| 78 | BitField<34, 2, u64> size8; | ||
| 79 | BitField<36, 2, Format> format9; | ||
| 80 | BitField<38, 2, u64> size9; | ||
| 81 | BitField<40, 2, Format> format10; | ||
| 82 | BitField<42, 2, u64> size10; | ||
| 83 | BitField<44, 2, Format> format11; | ||
| 84 | BitField<46, 2, u64> size11; | ||
| 85 | |||
| 86 | BitField<48, 12, u64> attribute_mask; | ||
| 87 | BitField<60, 4, u64> num_attributes; // number of total attributes minus 1 | ||
| 88 | } vertex_descriptor; | ||
| 89 | |||
| 90 | INSERT_PADDING_WORDS(0xfe); | ||
| 91 | |||
| 92 | #undef INSERT_PADDING_WORDS_HELPER1 | ||
| 93 | #undef INSERT_PADDING_WORDS_HELPER2 | ||
| 94 | #undef INSERT_PADDING_WORDS | ||
| 95 | |||
| 96 | // Map register indices to names readable by humans | ||
| 97 | // Used for debugging purposes, so performance is not an issue here | ||
| 98 | static std::string GetCommandName(int index) { | ||
| 99 | std::map<u32, std::string> map; | ||
| 100 | Regs regs; | ||
| 101 | |||
| 102 | // TODO: MSVC does not support using offsetof() on non-static data members even though this | ||
| 103 | // is technically allowed since C++11. Hence, this functionality is disabled until | ||
| 104 | // MSVC properly supports it. | ||
| 105 | #ifndef _MSC_VER | ||
| 106 | #define ADD_FIELD(name) \ | ||
| 107 | do { \ | ||
| 108 | map.insert({PICA_REG_INDEX(name), #name}); \ | ||
| 109 | for (u32 i = PICA_REG_INDEX(name) + 1; i < PICA_REG_INDEX(name) + sizeof(regs.name) / 4; ++i) \ | ||
| 110 | map.insert({i, #name + std::string("+") + std::to_string(i-PICA_REG_INDEX(name))}); \ | ||
| 111 | } while(false) | ||
| 112 | |||
| 113 | ADD_FIELD(viewport_size_x); | ||
| 114 | ADD_FIELD(viewport_size_y); | ||
| 115 | ADD_FIELD(vertex_descriptor); | ||
| 116 | |||
| 117 | #undef ADD_FIELD | ||
| 118 | #endif // _MSC_VER | ||
| 119 | |||
| 120 | // Return empty string if no match is found | ||
| 121 | return map[index]; | ||
| 122 | } | ||
| 123 | |||
| 124 | static inline int NumIds() { | ||
| 125 | return sizeof(Regs) / sizeof(u32); | ||
| 126 | } | ||
| 127 | |||
| 128 | u32& operator [] (int index) const { | ||
| 129 | u32* content = (u32*)this; | ||
| 130 | return content[index]; | ||
| 131 | } | ||
| 132 | |||
| 133 | u32& operator [] (int index) { | ||
| 134 | u32* content = (u32*)this; | ||
| 135 | return content[index]; | ||
| 136 | } | ||
| 137 | |||
| 138 | private: | ||
| 139 | /* | ||
| 140 | * Most physical addresses which Pica registers refer to are 8-byte aligned. | ||
| 141 | * This function should be used to get the address from a raw register value. | ||
| 142 | */ | ||
| 143 | static inline u32 DecodeAddressRegister(u32 register_value) { | ||
| 144 | return register_value * 8; | ||
| 145 | } | ||
| 40 | }; | 146 | }; |
| 41 | 147 | ||
| 42 | static inline Regs::Id VertexAttributeOffset(int n) | 148 | // TODO: MSVC does not support using offsetof() on non-static data members even though this |
| 43 | { | 149 | // is technically allowed since C++11. This macro should be enabled once MSVC adds |
| 44 | return static_cast<Regs::Id>(0x203 + 3*n); | 150 | // support for that. |
| 45 | } | 151 | #ifndef _MSC_VER |
| 152 | #define ASSERT_REG_POSITION(field_name, position) static_assert(offsetof(Regs, field_name) == position * 4, "Field "#field_name" has invalid position") | ||
| 153 | |||
| 154 | ASSERT_REG_POSITION(viewport_size_x, 0x41); | ||
| 155 | ASSERT_REG_POSITION(viewport_size_y, 0x43); | ||
| 156 | ASSERT_REG_POSITION(vertex_descriptor, 0x200); | ||
| 46 | 157 | ||
| 47 | static inline Regs::Id VertexAttributeInfo0(int n) | 158 | #undef ASSERT_REG_POSITION |
| 48 | { | 159 | #endif // !defined(_MSC_VER) |
| 49 | return static_cast<Regs::Id>(0x204 + 3*n); | ||
| 50 | } | ||
| 51 | 160 | ||
| 52 | static inline Regs::Id VertexAttributeInfo1(int n) | 161 | // The total number of registers is chosen arbitrarily, but let's make sure it's not some odd value anyway. |
| 53 | { | 162 | static_assert(sizeof(Regs) == 0x300 * sizeof(u32), "Invalid total size of register set"); |
| 54 | return static_cast<Regs::Id>(0x205 + 3*n); | ||
| 55 | } | ||
| 56 | 163 | ||
| 57 | union CommandHeader { | 164 | union CommandHeader { |
| 58 | CommandHeader(u32 h) : hex(h) {} | 165 | CommandHeader(u32 h) : hex(h) {} |
| 59 | 166 | ||
| 60 | u32 hex; | 167 | u32 hex; |
| 61 | 168 | ||
| 62 | BitField< 0, 16, Regs::Id> cmd_id; | 169 | BitField< 0, 16, u32> cmd_id; |
| 63 | BitField<16, 4, u32> parameter_mask; | 170 | BitField<16, 4, u32> parameter_mask; |
| 64 | BitField<20, 11, u32> extra_data_length; | 171 | BitField<20, 11, u32> extra_data_length; |
| 65 | BitField<31, 1, u32> group_commands; | 172 | BitField<31, 1, u32> group_commands; |
| 66 | }; | 173 | }; |
| 67 | 174 | ||
| 68 | static std::map<Regs::Id, const char*> command_names = { | ||
| 69 | {Regs::ViewportSizeX, "ViewportSizeX" }, | ||
| 70 | {Regs::ViewportInvSizeX, "ViewportInvSizeX" }, | ||
| 71 | {Regs::ViewportSizeY, "ViewportSizeY" }, | ||
| 72 | {Regs::ViewportInvSizeY, "ViewportInvSizeY" }, | ||
| 73 | {Regs::ViewportCorner, "ViewportCorner" }, | ||
| 74 | {Regs::DepthBufferFormat, "DepthBufferFormat" }, | ||
| 75 | {Regs::ColorBufferFormat, "ColorBufferFormat" }, | ||
| 76 | {Regs::DepthBufferAddress, "DepthBufferAddress" }, | ||
| 77 | {Regs::ColorBufferAddress, "ColorBufferAddress" }, | ||
| 78 | {Regs::ColorBufferSize, "ColorBufferSize" }, | ||
| 79 | }; | ||
| 80 | |||
| 81 | template<> | ||
| 82 | union Regs::Struct<Regs::ViewportSizeX> { | ||
| 83 | BitField<0, 24, u32> value; | ||
| 84 | }; | ||
| 85 | |||
| 86 | template<> | ||
| 87 | union Regs::Struct<Regs::ViewportSizeY> { | ||
| 88 | BitField<0, 24, u32> value; | ||
| 89 | }; | ||
| 90 | |||
| 91 | template<> | ||
| 92 | union Regs::Struct<Regs::VertexDescriptor> { | ||
| 93 | enum class Format : u64 { | ||
| 94 | BYTE = 0, | ||
| 95 | UBYTE = 1, | ||
| 96 | SHORT = 2, | ||
| 97 | FLOAT = 3, | ||
| 98 | }; | ||
| 99 | |||
| 100 | BitField< 0, 2, Format> format0; | ||
| 101 | BitField< 2, 2, u64> size0; // number of elements minus 1 | ||
| 102 | BitField< 4, 2, Format> format1; | ||
| 103 | BitField< 6, 2, u64> size1; | ||
| 104 | BitField< 8, 2, Format> format2; | ||
| 105 | BitField<10, 2, u64> size2; | ||
| 106 | BitField<12, 2, Format> format3; | ||
| 107 | BitField<14, 2, u64> size3; | ||
| 108 | BitField<16, 2, Format> format4; | ||
| 109 | BitField<18, 2, u64> size4; | ||
| 110 | BitField<20, 2, Format> format5; | ||
| 111 | BitField<22, 2, u64> size5; | ||
| 112 | BitField<24, 2, Format> format6; | ||
| 113 | BitField<26, 2, u64> size6; | ||
| 114 | BitField<28, 2, Format> format7; | ||
| 115 | BitField<30, 2, u64> size7; | ||
| 116 | BitField<32, 2, Format> format8; | ||
| 117 | BitField<34, 2, u64> size8; | ||
| 118 | BitField<36, 2, Format> format9; | ||
| 119 | BitField<38, 2, u64> size9; | ||
| 120 | BitField<40, 2, Format> format10; | ||
| 121 | BitField<42, 2, u64> size10; | ||
| 122 | BitField<44, 2, Format> format11; | ||
| 123 | BitField<46, 2, u64> size11; | ||
| 124 | |||
| 125 | BitField<48, 12, u64> attribute_mask; | ||
| 126 | BitField<60, 4, u64> num_attributes; // number of total attributes minus 1 | ||
| 127 | }; | ||
| 128 | |||
| 129 | 175 | ||
| 130 | } // namespace | 176 | } // namespace |
diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp index d0a8ec1da..02b174562 100644 --- a/src/video_core/renderer_opengl/renderer_opengl.cpp +++ b/src/video_core/renderer_opengl/renderer_opengl.cpp | |||
| @@ -78,8 +78,8 @@ void RendererOpenGL::FlipFramebuffer(const u8* in, u8* out) { | |||
| 78 | */ | 78 | */ |
| 79 | void RendererOpenGL::RenderXFB(const common::Rect& src_rect, const common::Rect& dst_rect) { | 79 | void RendererOpenGL::RenderXFB(const common::Rect& src_rect, const common::Rect& dst_rect) { |
| 80 | 80 | ||
| 81 | const auto& framebuffer_top = GPU::g_regs.Get<GPU::Regs::FramebufferTop>(); | 81 | const auto& framebuffer_top = GPU::g_regs.framebuffer_config[0]; |
| 82 | const auto& framebuffer_sub = GPU::g_regs.Get<GPU::Regs::FramebufferBottom>(); | 82 | const auto& framebuffer_sub = GPU::g_regs.framebuffer_config[1]; |
| 83 | const u32 active_fb_top = (framebuffer_top.active_fb == 1) | 83 | const u32 active_fb_top = (framebuffer_top.active_fb == 1) |
| 84 | ? framebuffer_top.address_left2 | 84 | ? framebuffer_top.address_left2 |
| 85 | : framebuffer_top.address_left1; | 85 | : framebuffer_top.address_left1; |