summaryrefslogtreecommitdiff
path: root/src/video_core
diff options
context:
space:
mode:
authorGravatar bunnei2014-08-11 22:21:54 -0400
committerGravatar bunnei2014-08-11 22:21:54 -0400
commita3e029fad0610d9e045b79cdc545dec3e7327ff7 (patch)
tree76f32e7dc447e661f9f34303609cf4aed23d7a5b /src/video_core
parentMerge pull request #40 from bentley/master (diff)
parentRemove the fancy RegisterSet class introduced in 4c2bff61e. (diff)
downloadyuzu-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.h242
-rw-r--r--src/video_core/renderer_opengl/renderer_opengl.cpp4
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
14namespace Pica { 14namespace 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
16struct Regs { 36struct 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
138private:
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
42static 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
154ASSERT_REG_POSITION(viewport_size_x, 0x41);
155ASSERT_REG_POSITION(viewport_size_y, 0x43);
156ASSERT_REG_POSITION(vertex_descriptor, 0x200);
46 157
47static 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
52static 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{ 162static_assert(sizeof(Regs) == 0x300 * sizeof(u32), "Invalid total size of register set");
54 return static_cast<Regs::Id>(0x205 + 3*n);
55}
56 163
57union CommandHeader { 164union 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
68static 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
81template<>
82union Regs::Struct<Regs::ViewportSizeX> {
83 BitField<0, 24, u32> value;
84};
85
86template<>
87union Regs::Struct<Regs::ViewportSizeY> {
88 BitField<0, 24, u32> value;
89};
90
91template<>
92union 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 */
79void RendererOpenGL::RenderXFB(const common::Rect& src_rect, const common::Rect& dst_rect) { 79void 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;