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.
This commit is contained in:
parent
d08457f879
commit
de0ab806df
4 changed files with 55 additions and 27 deletions
|
@ -43,15 +43,17 @@ void Maxwell3D::CallMacroMethod(u32 method, std::vector<u32> parameters) {
|
|||
// Reset the current macro.
|
||||
executing_macro = 0;
|
||||
|
||||
// The requested macro must have been uploaded already.
|
||||
auto macro_code = uploaded_macros.find(method);
|
||||
if (macro_code == uploaded_macros.end()) {
|
||||
LOG_ERROR(HW_GPU, "Macro {:04X} was not uploaded", method);
|
||||
// Lookup the macro offset
|
||||
const u32 entry{(method - MacroRegistersStart) >> 1};
|
||||
const auto& search{macro_offsets.find(entry)};
|
||||
if (search == macro_offsets.end()) {
|
||||
LOG_CRITICAL(HW_GPU, "macro not found for method 0x{:X}!", method);
|
||||
UNREACHABLE();
|
||||
return;
|
||||
}
|
||||
|
||||
// Execute the current macro.
|
||||
macro_interpreter.Execute(macro_code->second, std::move(parameters));
|
||||
macro_interpreter.Execute(search->second, std::move(parameters));
|
||||
}
|
||||
|
||||
void Maxwell3D::WriteReg(u32 method, u32 value, u32 remaining_params) {
|
||||
|
@ -97,6 +99,10 @@ void Maxwell3D::WriteReg(u32 method, u32 value, u32 remaining_params) {
|
|||
ProcessMacroUpload(value);
|
||||
break;
|
||||
}
|
||||
case MAXWELL3D_REG_INDEX(macros.bind): {
|
||||
ProcessMacroBind(value);
|
||||
break;
|
||||
}
|
||||
case MAXWELL3D_REG_INDEX(const_buffer.cb_data[0]):
|
||||
case MAXWELL3D_REG_INDEX(const_buffer.cb_data[1]):
|
||||
case MAXWELL3D_REG_INDEX(const_buffer.cb_data[2]):
|
||||
|
@ -158,9 +164,13 @@ void Maxwell3D::WriteReg(u32 method, u32 value, u32 remaining_params) {
|
|||
}
|
||||
|
||||
void Maxwell3D::ProcessMacroUpload(u32 data) {
|
||||
// Store the uploaded macro code to interpret them when they're called.
|
||||
auto& macro = uploaded_macros[regs.macros.entry * 2 + MacroRegistersStart];
|
||||
macro.push_back(data);
|
||||
ASSERT_MSG(regs.macros.upload_address < macro_memory.size(),
|
||||
"upload_address exceeded macro_memory size!");
|
||||
macro_memory[regs.macros.upload_address++] = data;
|
||||
}
|
||||
|
||||
void Maxwell3D::ProcessMacroBind(u32 data) {
|
||||
macro_offsets[regs.macros.entry] = data;
|
||||
}
|
||||
|
||||
void Maxwell3D::ProcessQueryGet() {
|
||||
|
|
|
@ -475,12 +475,13 @@ public:
|
|||
INSERT_PADDING_WORDS(0x45);
|
||||
|
||||
struct {
|
||||
INSERT_PADDING_WORDS(1);
|
||||
u32 upload_address;
|
||||
u32 data;
|
||||
u32 entry;
|
||||
u32 bind;
|
||||
} macros;
|
||||
|
||||
INSERT_PADDING_WORDS(0x189);
|
||||
INSERT_PADDING_WORDS(0x188);
|
||||
|
||||
u32 tfb_enabled;
|
||||
|
||||
|
@ -994,12 +995,25 @@ public:
|
|||
/// Returns the texture information for a specific texture in a specific shader stage.
|
||||
Texture::FullTextureInfo GetStageTexture(Regs::ShaderStage stage, std::size_t offset) const;
|
||||
|
||||
/// Memory for macro code - it's undetermined how big this is, however 1MB is much larger than
|
||||
/// we've seen used.
|
||||
using MacroMemory = std::array<u32, 0x40000>;
|
||||
|
||||
/// Gets a reference to macro memory.
|
||||
const MacroMemory& GetMacroMemory() const {
|
||||
return macro_memory;
|
||||
}
|
||||
|
||||
private:
|
||||
void InitializeRegisterDefaults();
|
||||
|
||||
VideoCore::RasterizerInterface& rasterizer;
|
||||
|
||||
std::unordered_map<u32, std::vector<u32>> uploaded_macros;
|
||||
/// Start offsets of each macro in macro_memory
|
||||
std::unordered_map<u32, u32> macro_offsets;
|
||||
|
||||
/// Memory for macro code
|
||||
MacroMemory macro_memory;
|
||||
|
||||
/// Macro method that is currently being executed / being fed parameters.
|
||||
u32 executing_macro = 0;
|
||||
|
@ -1022,9 +1036,12 @@ private:
|
|||
*/
|
||||
void CallMacroMethod(u32 method, std::vector<u32> parameters);
|
||||
|
||||
/// Handles writes to the macro uploading registers.
|
||||
/// Handles writes to the macro uploading register.
|
||||
void ProcessMacroUpload(u32 data);
|
||||
|
||||
/// Handles writes to the macro bind register.
|
||||
void ProcessMacroBind(u32 data);
|
||||
|
||||
/// Handles a write to the CLEAR_BUFFERS register.
|
||||
void ProcessClearBuffers();
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue