Merge pull request #3542 from namkazt/patch-10
Implement MME shadow RAM
This commit is contained in:
		
						commit
						7981910746
					
				@ -98,6 +98,8 @@ void Maxwell3D::InitializeRegisterDefaults() {
 | 
				
			|||||||
    regs.framebuffer_srgb = 1;
 | 
					    regs.framebuffer_srgb = 1;
 | 
				
			||||||
    regs.front_face = Maxwell3D::Regs::FrontFace::ClockWise;
 | 
					    regs.front_face = Maxwell3D::Regs::FrontFace::ClockWise;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    shadow_state = regs;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    mme_inline[MAXWELL3D_REG_INDEX(draw.vertex_end_gl)] = true;
 | 
					    mme_inline[MAXWELL3D_REG_INDEX(draw.vertex_end_gl)] = true;
 | 
				
			||||||
    mme_inline[MAXWELL3D_REG_INDEX(draw.vertex_begin_gl)] = true;
 | 
					    mme_inline[MAXWELL3D_REG_INDEX(draw.vertex_begin_gl)] = true;
 | 
				
			||||||
    mme_inline[MAXWELL3D_REG_INDEX(vertex_buffer.count)] = true;
 | 
					    mme_inline[MAXWELL3D_REG_INDEX(vertex_buffer.count)] = true;
 | 
				
			||||||
@ -160,8 +162,17 @@ void Maxwell3D::CallMethod(const GPU::MethodCall& method_call) {
 | 
				
			|||||||
    ASSERT_MSG(method < Regs::NUM_REGS,
 | 
					    ASSERT_MSG(method < Regs::NUM_REGS,
 | 
				
			||||||
               "Invalid Maxwell3D register, increase the size of the Regs structure");
 | 
					               "Invalid Maxwell3D register, increase the size of the Regs structure");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (regs.reg_array[method] != method_call.argument) {
 | 
					    u32 arg = method_call.argument;
 | 
				
			||||||
        regs.reg_array[method] = method_call.argument;
 | 
					    // Keep track of the register value in shadow_state when requested.
 | 
				
			||||||
 | 
					    if (shadow_state.shadow_ram_control == Regs::ShadowRamControl::Track ||
 | 
				
			||||||
 | 
					        shadow_state.shadow_ram_control == Regs::ShadowRamControl::TrackWithFilter) {
 | 
				
			||||||
 | 
					        shadow_state.reg_array[method] = arg;
 | 
				
			||||||
 | 
					    } else if (shadow_state.shadow_ram_control == Regs::ShadowRamControl::Replay) {
 | 
				
			||||||
 | 
					        arg = shadow_state.reg_array[method];
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (regs.reg_array[method] != arg) {
 | 
				
			||||||
 | 
					        regs.reg_array[method] = arg;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        for (const auto& table : dirty.tables) {
 | 
					        for (const auto& table : dirty.tables) {
 | 
				
			||||||
            dirty.flags[table[method]] = true;
 | 
					            dirty.flags[table[method]] = true;
 | 
				
			||||||
@ -169,12 +180,16 @@ void Maxwell3D::CallMethod(const GPU::MethodCall& method_call) {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    switch (method) {
 | 
					    switch (method) {
 | 
				
			||||||
 | 
					    case MAXWELL3D_REG_INDEX(shadow_ram_control): {
 | 
				
			||||||
 | 
					        shadow_state.shadow_ram_control = static_cast<Regs::ShadowRamControl>(method_call.argument);
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    case MAXWELL3D_REG_INDEX(macros.data): {
 | 
					    case MAXWELL3D_REG_INDEX(macros.data): {
 | 
				
			||||||
        ProcessMacroUpload(method_call.argument);
 | 
					        ProcessMacroUpload(arg);
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    case MAXWELL3D_REG_INDEX(macros.bind): {
 | 
					    case MAXWELL3D_REG_INDEX(macros.bind): {
 | 
				
			||||||
        ProcessMacroBind(method_call.argument);
 | 
					        ProcessMacroBind(arg);
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    case MAXWELL3D_REG_INDEX(firmware[4]): {
 | 
					    case MAXWELL3D_REG_INDEX(firmware[4]): {
 | 
				
			||||||
@ -250,7 +265,7 @@ void Maxwell3D::CallMethod(const GPU::MethodCall& method_call) {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
    case MAXWELL3D_REG_INDEX(data_upload): {
 | 
					    case MAXWELL3D_REG_INDEX(data_upload): {
 | 
				
			||||||
        const bool is_last_call = method_call.IsLastCall();
 | 
					        const bool is_last_call = method_call.IsLastCall();
 | 
				
			||||||
        upload_state.ProcessData(method_call.argument, is_last_call);
 | 
					        upload_state.ProcessData(arg, is_last_call);
 | 
				
			||||||
        if (is_last_call) {
 | 
					        if (is_last_call) {
 | 
				
			||||||
            OnMemoryWrite();
 | 
					            OnMemoryWrite();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
				
			|||||||
@ -531,6 +531,17 @@ public:
 | 
				
			|||||||
            Fill = 0x1b02,
 | 
					            Fill = 0x1b02,
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        enum class ShadowRamControl : u32 {
 | 
				
			||||||
 | 
					            // write value to shadow ram
 | 
				
			||||||
 | 
					            Track = 0,
 | 
				
			||||||
 | 
					            // write value to shadow ram ( with validation ??? )
 | 
				
			||||||
 | 
					            TrackWithFilter = 1,
 | 
				
			||||||
 | 
					            // only write to real hw register
 | 
				
			||||||
 | 
					            Passthrough = 2,
 | 
				
			||||||
 | 
					            // write value from shadow ram to real hw register
 | 
				
			||||||
 | 
					            Replay = 3,
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        struct RenderTargetConfig {
 | 
					        struct RenderTargetConfig {
 | 
				
			||||||
            u32 address_high;
 | 
					            u32 address_high;
 | 
				
			||||||
            u32 address_low;
 | 
					            u32 address_low;
 | 
				
			||||||
@ -674,7 +685,9 @@ public:
 | 
				
			|||||||
                    u32 bind;
 | 
					                    u32 bind;
 | 
				
			||||||
                } macros;
 | 
					                } macros;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                INSERT_UNION_PADDING_WORDS(0x17);
 | 
					                ShadowRamControl shadow_ram_control;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                INSERT_UNION_PADDING_WORDS(0x16);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                Upload::Registers upload;
 | 
					                Upload::Registers upload;
 | 
				
			||||||
                struct {
 | 
					                struct {
 | 
				
			||||||
@ -1263,7 +1276,12 @@ public:
 | 
				
			|||||||
            };
 | 
					            };
 | 
				
			||||||
            std::array<u32, NUM_REGS> reg_array;
 | 
					            std::array<u32, NUM_REGS> reg_array;
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
    } regs{};
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Regs regs{};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Store temporary hw register values, used by some calls to restore state after a operation
 | 
				
			||||||
 | 
					    Regs shadow_state;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    static_assert(sizeof(Regs) == Regs::NUM_REGS * sizeof(u32), "Maxwell3D Regs has wrong size");
 | 
					    static_assert(sizeof(Regs) == Regs::NUM_REGS * sizeof(u32), "Maxwell3D Regs has wrong size");
 | 
				
			||||||
    static_assert(std::is_trivially_copyable_v<Regs>, "Maxwell3D Regs must be trivially copyable");
 | 
					    static_assert(std::is_trivially_copyable_v<Regs>, "Maxwell3D Regs must be trivially copyable");
 | 
				
			||||||
@ -1458,6 +1476,7 @@ private:
 | 
				
			|||||||
                  "Field " #field_name " has invalid position")
 | 
					                  "Field " #field_name " has invalid position")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ASSERT_REG_POSITION(macros, 0x45);
 | 
					ASSERT_REG_POSITION(macros, 0x45);
 | 
				
			||||||
 | 
					ASSERT_REG_POSITION(shadow_ram_control, 0x49);
 | 
				
			||||||
ASSERT_REG_POSITION(upload, 0x60);
 | 
					ASSERT_REG_POSITION(upload, 0x60);
 | 
				
			||||||
ASSERT_REG_POSITION(exec_upload, 0x6C);
 | 
					ASSERT_REG_POSITION(exec_upload, 0x6C);
 | 
				
			||||||
ASSERT_REG_POSITION(data_upload, 0x6D);
 | 
					ASSERT_REG_POSITION(data_upload, 0x6D);
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user