mirror of
				https://git.suyu.dev/suyu/suyu
				synced 2025-11-03 16:39:01 -06:00 
			
		
		
		
	Merge pull request #2856 from wwylele/shader-share
pica: upload shared shader code & swizzle to both unit
This commit is contained in:
		@@ -119,27 +119,6 @@ static void WriteUniformFloatReg(ShaderRegs& config, Shader::ShaderSetup& setup,
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void WriteProgramCode(ShaderRegs& config, Shader::ShaderSetup& setup,
 | 
					 | 
				
			||||||
                             unsigned max_program_code_length, u32 value) {
 | 
					 | 
				
			||||||
    if (config.program.offset >= max_program_code_length) {
 | 
					 | 
				
			||||||
        LOG_ERROR(HW_GPU, "Invalid %s program offset %d", GetShaderSetupTypeName(setup),
 | 
					 | 
				
			||||||
                  (int)config.program.offset);
 | 
					 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
        setup.program_code[config.program.offset] = value;
 | 
					 | 
				
			||||||
        config.program.offset++;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void WriteSwizzlePatterns(ShaderRegs& config, Shader::ShaderSetup& setup, u32 value) {
 | 
					 | 
				
			||||||
    if (config.swizzle_patterns.offset >= setup.swizzle_data.size()) {
 | 
					 | 
				
			||||||
        LOG_ERROR(HW_GPU, "Invalid %s swizzle pattern offset %d", GetShaderSetupTypeName(setup),
 | 
					 | 
				
			||||||
                  (int)config.swizzle_patterns.offset);
 | 
					 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
        setup.swizzle_data[config.swizzle_patterns.offset] = value;
 | 
					 | 
				
			||||||
        config.swizzle_patterns.offset++;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void WritePicaReg(u32 id, u32 value, u32 mask) {
 | 
					static void WritePicaReg(u32 id, u32 value, u32 mask) {
 | 
				
			||||||
    auto& regs = g_state.regs;
 | 
					    auto& regs = g_state.regs;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -458,7 +437,13 @@ static void WritePicaReg(u32 id, u32 value, u32 mask) {
 | 
				
			|||||||
    case PICA_REG_INDEX_WORKAROUND(gs.program.set_word[5], 0x2a1):
 | 
					    case PICA_REG_INDEX_WORKAROUND(gs.program.set_word[5], 0x2a1):
 | 
				
			||||||
    case PICA_REG_INDEX_WORKAROUND(gs.program.set_word[6], 0x2a2):
 | 
					    case PICA_REG_INDEX_WORKAROUND(gs.program.set_word[6], 0x2a2):
 | 
				
			||||||
    case PICA_REG_INDEX_WORKAROUND(gs.program.set_word[7], 0x2a3): {
 | 
					    case PICA_REG_INDEX_WORKAROUND(gs.program.set_word[7], 0x2a3): {
 | 
				
			||||||
        WriteProgramCode(g_state.regs.gs, g_state.gs, 4096, value);
 | 
					        u32& offset = g_state.regs.gs.program.offset;
 | 
				
			||||||
 | 
					        if (offset >= 4096) {
 | 
				
			||||||
 | 
					            LOG_ERROR(HW_GPU, "Invalid GS program offset %u", offset);
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            g_state.gs.program_code[offset] = value;
 | 
				
			||||||
 | 
					            offset++;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -470,11 +455,18 @@ static void WritePicaReg(u32 id, u32 value, u32 mask) {
 | 
				
			|||||||
    case PICA_REG_INDEX_WORKAROUND(gs.swizzle_patterns.set_word[5], 0x2ab):
 | 
					    case PICA_REG_INDEX_WORKAROUND(gs.swizzle_patterns.set_word[5], 0x2ab):
 | 
				
			||||||
    case PICA_REG_INDEX_WORKAROUND(gs.swizzle_patterns.set_word[6], 0x2ac):
 | 
					    case PICA_REG_INDEX_WORKAROUND(gs.swizzle_patterns.set_word[6], 0x2ac):
 | 
				
			||||||
    case PICA_REG_INDEX_WORKAROUND(gs.swizzle_patterns.set_word[7], 0x2ad): {
 | 
					    case PICA_REG_INDEX_WORKAROUND(gs.swizzle_patterns.set_word[7], 0x2ad): {
 | 
				
			||||||
        WriteSwizzlePatterns(g_state.regs.gs, g_state.gs, value);
 | 
					        u32& offset = g_state.regs.gs.swizzle_patterns.offset;
 | 
				
			||||||
 | 
					        if (offset >= g_state.gs.swizzle_data.size()) {
 | 
				
			||||||
 | 
					            LOG_ERROR(HW_GPU, "Invalid GS swizzle pattern offset %u", offset);
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            g_state.gs.swizzle_data[offset] = value;
 | 
				
			||||||
 | 
					            offset++;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    case PICA_REG_INDEX(vs.bool_uniforms):
 | 
					    case PICA_REG_INDEX(vs.bool_uniforms):
 | 
				
			||||||
 | 
					        // TODO (wwylele): does regs.pipeline.gs_unit_exclusive_configuration affect this?
 | 
				
			||||||
        WriteUniformBoolReg(g_state.vs, g_state.regs.vs.bool_uniforms.Value());
 | 
					        WriteUniformBoolReg(g_state.vs, g_state.regs.vs.bool_uniforms.Value());
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -482,6 +474,7 @@ static void WritePicaReg(u32 id, u32 value, u32 mask) {
 | 
				
			|||||||
    case PICA_REG_INDEX_WORKAROUND(vs.int_uniforms[1], 0x2b2):
 | 
					    case PICA_REG_INDEX_WORKAROUND(vs.int_uniforms[1], 0x2b2):
 | 
				
			||||||
    case PICA_REG_INDEX_WORKAROUND(vs.int_uniforms[2], 0x2b3):
 | 
					    case PICA_REG_INDEX_WORKAROUND(vs.int_uniforms[2], 0x2b3):
 | 
				
			||||||
    case PICA_REG_INDEX_WORKAROUND(vs.int_uniforms[3], 0x2b4): {
 | 
					    case PICA_REG_INDEX_WORKAROUND(vs.int_uniforms[3], 0x2b4): {
 | 
				
			||||||
 | 
					        // TODO (wwylele): does regs.pipeline.gs_unit_exclusive_configuration affect this?
 | 
				
			||||||
        unsigned index = (id - PICA_REG_INDEX_WORKAROUND(vs.int_uniforms[0], 0x2b1));
 | 
					        unsigned index = (id - PICA_REG_INDEX_WORKAROUND(vs.int_uniforms[0], 0x2b1));
 | 
				
			||||||
        auto values = regs.vs.int_uniforms[index];
 | 
					        auto values = regs.vs.int_uniforms[index];
 | 
				
			||||||
        WriteUniformIntReg(g_state.vs, index,
 | 
					        WriteUniformIntReg(g_state.vs, index,
 | 
				
			||||||
@@ -497,6 +490,7 @@ static void WritePicaReg(u32 id, u32 value, u32 mask) {
 | 
				
			|||||||
    case PICA_REG_INDEX_WORKAROUND(vs.uniform_setup.set_value[5], 0x2c6):
 | 
					    case PICA_REG_INDEX_WORKAROUND(vs.uniform_setup.set_value[5], 0x2c6):
 | 
				
			||||||
    case PICA_REG_INDEX_WORKAROUND(vs.uniform_setup.set_value[6], 0x2c7):
 | 
					    case PICA_REG_INDEX_WORKAROUND(vs.uniform_setup.set_value[6], 0x2c7):
 | 
				
			||||||
    case PICA_REG_INDEX_WORKAROUND(vs.uniform_setup.set_value[7], 0x2c8): {
 | 
					    case PICA_REG_INDEX_WORKAROUND(vs.uniform_setup.set_value[7], 0x2c8): {
 | 
				
			||||||
 | 
					        // TODO (wwylele): does regs.pipeline.gs_unit_exclusive_configuration affect this?
 | 
				
			||||||
        WriteUniformFloatReg(g_state.regs.vs, g_state.vs, vs_float_regs_counter,
 | 
					        WriteUniformFloatReg(g_state.regs.vs, g_state.vs, vs_float_regs_counter,
 | 
				
			||||||
                             vs_uniform_write_buffer, value);
 | 
					                             vs_uniform_write_buffer, value);
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
@@ -510,7 +504,16 @@ static void WritePicaReg(u32 id, u32 value, u32 mask) {
 | 
				
			|||||||
    case PICA_REG_INDEX_WORKAROUND(vs.program.set_word[5], 0x2d1):
 | 
					    case PICA_REG_INDEX_WORKAROUND(vs.program.set_word[5], 0x2d1):
 | 
				
			||||||
    case PICA_REG_INDEX_WORKAROUND(vs.program.set_word[6], 0x2d2):
 | 
					    case PICA_REG_INDEX_WORKAROUND(vs.program.set_word[6], 0x2d2):
 | 
				
			||||||
    case PICA_REG_INDEX_WORKAROUND(vs.program.set_word[7], 0x2d3): {
 | 
					    case PICA_REG_INDEX_WORKAROUND(vs.program.set_word[7], 0x2d3): {
 | 
				
			||||||
        WriteProgramCode(g_state.regs.vs, g_state.vs, 512, value);
 | 
					        u32& offset = g_state.regs.vs.program.offset;
 | 
				
			||||||
 | 
					        if (offset >= 512) {
 | 
				
			||||||
 | 
					            LOG_ERROR(HW_GPU, "Invalid VS program offset %u", offset);
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            g_state.vs.program_code[offset] = value;
 | 
				
			||||||
 | 
					            if (!g_state.regs.pipeline.gs_unit_exclusive_configuration) {
 | 
				
			||||||
 | 
					                g_state.gs.program_code[offset] = value;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            offset++;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -522,7 +525,16 @@ static void WritePicaReg(u32 id, u32 value, u32 mask) {
 | 
				
			|||||||
    case PICA_REG_INDEX_WORKAROUND(vs.swizzle_patterns.set_word[5], 0x2db):
 | 
					    case PICA_REG_INDEX_WORKAROUND(vs.swizzle_patterns.set_word[5], 0x2db):
 | 
				
			||||||
    case PICA_REG_INDEX_WORKAROUND(vs.swizzle_patterns.set_word[6], 0x2dc):
 | 
					    case PICA_REG_INDEX_WORKAROUND(vs.swizzle_patterns.set_word[6], 0x2dc):
 | 
				
			||||||
    case PICA_REG_INDEX_WORKAROUND(vs.swizzle_patterns.set_word[7], 0x2dd): {
 | 
					    case PICA_REG_INDEX_WORKAROUND(vs.swizzle_patterns.set_word[7], 0x2dd): {
 | 
				
			||||||
        WriteSwizzlePatterns(g_state.regs.vs, g_state.vs, value);
 | 
					        u32& offset = g_state.regs.vs.swizzle_patterns.offset;
 | 
				
			||||||
 | 
					        if (offset >= g_state.vs.swizzle_data.size()) {
 | 
				
			||||||
 | 
					            LOG_ERROR(HW_GPU, "Invalid VS swizzle pattern offset %u", offset);
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            g_state.vs.swizzle_data[offset] = value;
 | 
				
			||||||
 | 
					            if (!g_state.regs.pipeline.gs_unit_exclusive_configuration) {
 | 
				
			||||||
 | 
					                g_state.gs.swizzle_data[offset] = value;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            offset++;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -202,7 +202,14 @@ struct PipelineRegs {
 | 
				
			|||||||
    /// Number of input attributes to the vertex shader minus 1
 | 
					    /// Number of input attributes to the vertex shader minus 1
 | 
				
			||||||
    BitField<0, 4, u32> max_input_attrib_index;
 | 
					    BitField<0, 4, u32> max_input_attrib_index;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    INSERT_PADDING_WORDS(2);
 | 
					    INSERT_PADDING_WORDS(1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // The shader unit 3, which can be used for both vertex and geometry shader, gets its
 | 
				
			||||||
 | 
					    // configuration depending on this register. If this is not set, unit 3 will share some
 | 
				
			||||||
 | 
					    // configuration with other units. It is known that program code and swizzle pattern uploaded
 | 
				
			||||||
 | 
					    // via regs.vs will be also uploaded to unit 3 if this is not set. Although very likely, it is
 | 
				
			||||||
 | 
					    // still unclear whether uniforms and other configuration can be also shared.
 | 
				
			||||||
 | 
					    BitField<0, 1, u32> gs_unit_exclusive_configuration;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    enum class GPUMode : u32 {
 | 
					    enum class GPUMode : u32 {
 | 
				
			||||||
        Drawing = 0,
 | 
					        Drawing = 0,
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user