summaryrefslogtreecommitdiff
path: root/src/video_core/engines
diff options
context:
space:
mode:
authorGravatar bunnei2018-10-29 23:36:03 -0400
committerGravatar bunnei2018-10-31 23:29:21 -0400
commitde0ab806df4575df93068e128d911dabbf396d2c (patch)
treeae9ce164967cd5bcfa824a1b7f0330957c792824 /src/video_core/engines
parentMerge pull request #1604 from FearlessTobi/port-4369 (diff)
downloadyuzu-de0ab806df4575df93068e128d911dabbf396d2c.tar.gz
yuzu-de0ab806df4575df93068e128d911dabbf396d2c.tar.xz
yuzu-de0ab806df4575df93068e128d911dabbf396d2c.zip
maxwell_3d: Restructure macro upload to use a single macro code memory.
- Fixes an issue where macros could be skipped. - Fixes rendering of distant objects in Super Mario Odyssey.
Diffstat (limited to 'src/video_core/engines')
-rw-r--r--src/video_core/engines/maxwell_3d.cpp26
-rw-r--r--src/video_core/engines/maxwell_3d.h25
2 files changed, 39 insertions, 12 deletions
diff --git a/src/video_core/engines/maxwell_3d.cpp b/src/video_core/engines/maxwell_3d.cpp
index 7357d20d1..d79c50919 100644
--- a/src/video_core/engines/maxwell_3d.cpp
+++ b/src/video_core/engines/maxwell_3d.cpp
@@ -43,15 +43,17 @@ void Maxwell3D::CallMacroMethod(u32 method, std::vector<u32> parameters) {
43 // Reset the current macro. 43 // Reset the current macro.
44 executing_macro = 0; 44 executing_macro = 0;
45 45
46 // The requested macro must have been uploaded already. 46 // Lookup the macro offset
47 auto macro_code = uploaded_macros.find(method); 47 const u32 entry{(method - MacroRegistersStart) >> 1};
48 if (macro_code == uploaded_macros.end()) { 48 const auto& search{macro_offsets.find(entry)};
49 LOG_ERROR(HW_GPU, "Macro {:04X} was not uploaded", method); 49 if (search == macro_offsets.end()) {
50 LOG_CRITICAL(HW_GPU, "macro not found for method 0x{:X}!", method);
51 UNREACHABLE();
50 return; 52 return;
51 } 53 }
52 54
53 // Execute the current macro. 55 // Execute the current macro.
54 macro_interpreter.Execute(macro_code->second, std::move(parameters)); 56 macro_interpreter.Execute(search->second, std::move(parameters));
55} 57}
56 58
57void Maxwell3D::WriteReg(u32 method, u32 value, u32 remaining_params) { 59void Maxwell3D::WriteReg(u32 method, u32 value, u32 remaining_params) {
@@ -97,6 +99,10 @@ void Maxwell3D::WriteReg(u32 method, u32 value, u32 remaining_params) {
97 ProcessMacroUpload(value); 99 ProcessMacroUpload(value);
98 break; 100 break;
99 } 101 }
102 case MAXWELL3D_REG_INDEX(macros.bind): {
103 ProcessMacroBind(value);
104 break;
105 }
100 case MAXWELL3D_REG_INDEX(const_buffer.cb_data[0]): 106 case MAXWELL3D_REG_INDEX(const_buffer.cb_data[0]):
101 case MAXWELL3D_REG_INDEX(const_buffer.cb_data[1]): 107 case MAXWELL3D_REG_INDEX(const_buffer.cb_data[1]):
102 case MAXWELL3D_REG_INDEX(const_buffer.cb_data[2]): 108 case MAXWELL3D_REG_INDEX(const_buffer.cb_data[2]):
@@ -158,9 +164,13 @@ void Maxwell3D::WriteReg(u32 method, u32 value, u32 remaining_params) {
158} 164}
159 165
160void Maxwell3D::ProcessMacroUpload(u32 data) { 166void Maxwell3D::ProcessMacroUpload(u32 data) {
161 // Store the uploaded macro code to interpret them when they're called. 167 ASSERT_MSG(regs.macros.upload_address < macro_memory.size(),
162 auto& macro = uploaded_macros[regs.macros.entry * 2 + MacroRegistersStart]; 168 "upload_address exceeded macro_memory size!");
163 macro.push_back(data); 169 macro_memory[regs.macros.upload_address++] = data;
170}
171
172void Maxwell3D::ProcessMacroBind(u32 data) {
173 macro_offsets[regs.macros.entry] = data;
164} 174}
165 175
166void Maxwell3D::ProcessQueryGet() { 176void Maxwell3D::ProcessQueryGet() {
diff --git a/src/video_core/engines/maxwell_3d.h b/src/video_core/engines/maxwell_3d.h
index 443affc36..50873813e 100644
--- a/src/video_core/engines/maxwell_3d.h
+++ b/src/video_core/engines/maxwell_3d.h
@@ -475,12 +475,13 @@ public:
475 INSERT_PADDING_WORDS(0x45); 475 INSERT_PADDING_WORDS(0x45);
476 476
477 struct { 477 struct {
478 INSERT_PADDING_WORDS(1); 478 u32 upload_address;
479 u32 data; 479 u32 data;
480 u32 entry; 480 u32 entry;
481 u32 bind;
481 } macros; 482 } macros;
482 483
483 INSERT_PADDING_WORDS(0x189); 484 INSERT_PADDING_WORDS(0x188);
484 485
485 u32 tfb_enabled; 486 u32 tfb_enabled;
486 487
@@ -994,12 +995,25 @@ public:
994 /// Returns the texture information for a specific texture in a specific shader stage. 995 /// Returns the texture information for a specific texture in a specific shader stage.
995 Texture::FullTextureInfo GetStageTexture(Regs::ShaderStage stage, std::size_t offset) const; 996 Texture::FullTextureInfo GetStageTexture(Regs::ShaderStage stage, std::size_t offset) const;
996 997
998 /// Memory for macro code - it's undetermined how big this is, however 1MB is much larger than
999 /// we've seen used.
1000 using MacroMemory = std::array<u32, 0x40000>;
1001
1002 /// Gets a reference to macro memory.
1003 const MacroMemory& GetMacroMemory() const {
1004 return macro_memory;
1005 }
1006
997private: 1007private:
998 void InitializeRegisterDefaults(); 1008 void InitializeRegisterDefaults();
999 1009
1000 VideoCore::RasterizerInterface& rasterizer; 1010 VideoCore::RasterizerInterface& rasterizer;
1001 1011
1002 std::unordered_map<u32, std::vector<u32>> uploaded_macros; 1012 /// Start offsets of each macro in macro_memory
1013 std::unordered_map<u32, u32> macro_offsets;
1014
1015 /// Memory for macro code
1016 MacroMemory macro_memory;
1003 1017
1004 /// Macro method that is currently being executed / being fed parameters. 1018 /// Macro method that is currently being executed / being fed parameters.
1005 u32 executing_macro = 0; 1019 u32 executing_macro = 0;
@@ -1022,9 +1036,12 @@ private:
1022 */ 1036 */
1023 void CallMacroMethod(u32 method, std::vector<u32> parameters); 1037 void CallMacroMethod(u32 method, std::vector<u32> parameters);
1024 1038
1025 /// Handles writes to the macro uploading registers. 1039 /// Handles writes to the macro uploading register.
1026 void ProcessMacroUpload(u32 data); 1040 void ProcessMacroUpload(u32 data);
1027 1041
1042 /// Handles writes to the macro bind register.
1043 void ProcessMacroBind(u32 data);
1044
1028 /// Handles a write to the CLEAR_BUFFERS register. 1045 /// Handles a write to the CLEAR_BUFFERS register.
1029 void ProcessClearBuffers(); 1046 void ProcessClearBuffers();
1030 1047