GPU: Move the Maxwell3D macro uploading code to the inside of the Maxwell3D processor.

It doesn't belong in the PFIFO handler.
This commit is contained in:
Subv 2018-04-23 20:01:29 -05:00
parent e2f2a49d2d
commit a994446b6e
4 changed files with 23 additions and 40 deletions

View file

@ -24,9 +24,6 @@ namespace Tegra {
enum class BufferMethods { enum class BufferMethods {
BindObject = 0, BindObject = 0,
SetGraphMacroCode = 0x45,
SetGraphMacroCodeArg = 0x46,
SetGraphMacroEntry = 0x47,
CountBufferMethods = 0x40, CountBufferMethods = 0x40,
}; };
@ -36,28 +33,6 @@ void GPU::WriteReg(u32 method, u32 subchannel, u32 value, u32 remaining_params)
"{:08X} remaining params {}", "{:08X} remaining params {}",
method, subchannel, value, remaining_params); method, subchannel, value, remaining_params);
if (method == static_cast<u32>(BufferMethods::SetGraphMacroEntry)) {
// Prepare to upload a new macro, reset the upload counter.
NGLOG_DEBUG(HW_GPU, "Uploading GPU macro {:08X}", value);
current_macro_entry = value;
current_macro_code.clear();
return;
}
if (method == static_cast<u32>(BufferMethods::SetGraphMacroCodeArg)) {
// Append a new code word to the current macro.
current_macro_code.push_back(value);
// There are no more params remaining, submit the code to the 3D engine.
if (remaining_params == 0) {
maxwell_3d->SubmitMacroCode(current_macro_entry, std::move(current_macro_code));
current_macro_entry = InvalidGraphMacroEntry;
current_macro_code.clear();
}
return;
}
if (method == static_cast<u32>(BufferMethods::BindObject)) { if (method == static_cast<u32>(BufferMethods::BindObject)) {
// Bind the current subchannel to the desired engine id. // Bind the current subchannel to the desired engine id.
NGLOG_DEBUG(HW_GPU, "Binding subchannel {} to engine {}", subchannel, value); NGLOG_DEBUG(HW_GPU, "Binding subchannel {} to engine {}", subchannel, value);

View file

@ -22,10 +22,6 @@ constexpr u32 MacroRegistersStart = 0xE00;
Maxwell3D::Maxwell3D(MemoryManager& memory_manager) Maxwell3D::Maxwell3D(MemoryManager& memory_manager)
: memory_manager(memory_manager), macro_interpreter(*this) {} : memory_manager(memory_manager), macro_interpreter(*this) {}
void Maxwell3D::SubmitMacroCode(u32 entry, std::vector<u32> code) {
uploaded_macros[entry * 2 + MacroRegistersStart] = std::move(code);
}
void Maxwell3D::CallMacroMethod(u32 method, std::vector<u32> parameters) { void Maxwell3D::CallMacroMethod(u32 method, std::vector<u32> parameters) {
auto macro_code = uploaded_macros.find(method); auto macro_code = uploaded_macros.find(method);
// The requested macro must have been uploaded already. // The requested macro must have been uploaded already.
@ -75,6 +71,10 @@ void Maxwell3D::WriteReg(u32 method, u32 value, u32 remaining_params) {
regs.reg_array[method] = value; regs.reg_array[method] = value;
switch (method) { switch (method) {
case MAXWELL3D_REG_INDEX(macros.data): {
ProcessMacroUpload(value);
break;
}
case MAXWELL3D_REG_INDEX(code_address.code_address_high): case MAXWELL3D_REG_INDEX(code_address.code_address_high):
case MAXWELL3D_REG_INDEX(code_address.code_address_low): { case MAXWELL3D_REG_INDEX(code_address.code_address_low): {
// Note: For some reason games (like Puyo Puyo Tetris) seem to write 0 to the CODE_ADDRESS // Note: For some reason games (like Puyo Puyo Tetris) seem to write 0 to the CODE_ADDRESS
@ -141,6 +141,12 @@ 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);
}
void Maxwell3D::ProcessQueryGet() { void Maxwell3D::ProcessQueryGet() {
GPUVAddr sequence_address = regs.query.QueryAddress(); GPUVAddr sequence_address = regs.query.QueryAddress();
// Since the sequence address is given as a GPU VAddr, we have to convert it to an application // Since the sequence address is given as a GPU VAddr, we have to convert it to an application

View file

@ -322,7 +322,15 @@ public:
union { union {
struct { struct {
INSERT_PADDING_WORDS(0x200); INSERT_PADDING_WORDS(0x45);
struct {
INSERT_PADDING_WORDS(1);
u32 data;
u32 entry;
} macros;
INSERT_PADDING_WORDS(0x1B8);
struct { struct {
u32 address_high; u32 address_high;
@ -637,9 +645,6 @@ public:
/// Write the value to the register identified by method. /// Write the value to the register identified by method.
void WriteReg(u32 method, u32 value, u32 remaining_params); void WriteReg(u32 method, u32 value, u32 remaining_params);
/// Uploads the code for a GPU macro program associated with the specified entry.
void SubmitMacroCode(u32 entry, std::vector<u32> code);
/// Returns a list of enabled textures for the specified shader stage. /// Returns a list of enabled textures for the specified shader stage.
std::vector<Texture::FullTextureInfo> GetStageTextures(Regs::ShaderStage stage) const; std::vector<Texture::FullTextureInfo> GetStageTextures(Regs::ShaderStage stage) const;
@ -670,6 +675,9 @@ private:
*/ */
void CallMacroMethod(u32 method, std::vector<u32> parameters); void CallMacroMethod(u32 method, std::vector<u32> parameters);
/// Handles writes to the macro uploading registers.
void ProcessMacroUpload(u32 data);
/// Handles a write to the QUERY_GET register. /// Handles a write to the QUERY_GET register.
void ProcessQueryGet(); void ProcessQueryGet();
@ -687,6 +695,7 @@ private:
static_assert(offsetof(Maxwell3D::Regs, field_name) == position * 4, \ static_assert(offsetof(Maxwell3D::Regs, field_name) == position * 4, \
"Field " #field_name " has invalid position") "Field " #field_name " has invalid position")
ASSERT_REG_POSITION(macros, 0x45);
ASSERT_REG_POSITION(rt, 0x200); ASSERT_REG_POSITION(rt, 0x200);
ASSERT_REG_POSITION(viewport_transform[0], 0x280); ASSERT_REG_POSITION(viewport_transform[0], 0x280);
ASSERT_REG_POSITION(viewport, 0x300); ASSERT_REG_POSITION(viewport, 0x300);

View file

@ -86,8 +86,6 @@ public:
} }
private: private:
static constexpr u32 InvalidGraphMacroEntry = 0xFFFFFFFF;
/// Writes a single register in the engine bound to the specified subchannel /// Writes a single register in the engine bound to the specified subchannel
void WriteReg(u32 method, u32 subchannel, u32 value, u32 remaining_params); void WriteReg(u32 method, u32 subchannel, u32 value, u32 remaining_params);
@ -100,11 +98,6 @@ private:
std::unique_ptr<Engines::Fermi2D> fermi_2d; std::unique_ptr<Engines::Fermi2D> fermi_2d;
/// Compute engine /// Compute engine
std::unique_ptr<Engines::MaxwellCompute> maxwell_compute; std::unique_ptr<Engines::MaxwellCompute> maxwell_compute;
/// Entry of the macro that is currently being uploaded
u32 current_macro_entry = InvalidGraphMacroEntry;
/// Code being uploaded for the current macro
std::vector<u32> current_macro_code;
}; };
} // namespace Tegra } // namespace Tegra