mirror of
				https://git.zaroz.cloud/nintendo-back-up/yuzu/yuzu.git
				synced 2025-05-12 00:45:25 +00:00 
			
		
		
		
	renderer_opengl: Implement HW fragment lighting LUTs within our default UBO.
This commit is contained in:
		
							parent
							
								
									afbef52516
								
							
						
					
					
						commit
						e9af70eaf3
					
				@ -1216,7 +1216,7 @@ struct State {
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        std::array<LutEntry, 256> luts[24];
 | 
			
		||||
        std::array<std::array<LutEntry, 256>, 24> luts;
 | 
			
		||||
    } lighting;
 | 
			
		||||
 | 
			
		||||
    /// Current Pica command list
 | 
			
		||||
 | 
			
		||||
@ -162,6 +162,13 @@ void RasterizerOpenGL::DrawTriangles() {
 | 
			
		||||
        state.draw.shader_dirty = false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    for (unsigned index = 0; index < Pica::g_state.lighting.luts.size(); index++) {
 | 
			
		||||
        if (uniform_block_data.lut_dirty[index]) {
 | 
			
		||||
            SyncLightingLUT(index);
 | 
			
		||||
            uniform_block_data.lut_dirty[index] = false;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (uniform_block_data.dirty) {
 | 
			
		||||
        glBufferData(GL_UNIFORM_BUFFER, sizeof(UniformData), &uniform_block_data.data, GL_STATIC_DRAW);
 | 
			
		||||
        uniform_block_data.dirty = false;
 | 
			
		||||
@ -381,6 +388,21 @@ void RasterizerOpenGL::NotifyPicaRegisterChanged(u32 id) {
 | 
			
		||||
        SyncGlobalAmbient();
 | 
			
		||||
        break;
 | 
			
		||||
 | 
			
		||||
    // Fragment lighting lookup tables
 | 
			
		||||
    case PICA_REG_INDEX_WORKAROUND(lighting.lut_data[0], 0x1c8):
 | 
			
		||||
    case PICA_REG_INDEX_WORKAROUND(lighting.lut_data[1], 0x1c9):
 | 
			
		||||
    case PICA_REG_INDEX_WORKAROUND(lighting.lut_data[2], 0x1ca):
 | 
			
		||||
    case PICA_REG_INDEX_WORKAROUND(lighting.lut_data[3], 0x1cb):
 | 
			
		||||
    case PICA_REG_INDEX_WORKAROUND(lighting.lut_data[4], 0x1cc):
 | 
			
		||||
    case PICA_REG_INDEX_WORKAROUND(lighting.lut_data[5], 0x1cd):
 | 
			
		||||
    case PICA_REG_INDEX_WORKAROUND(lighting.lut_data[6], 0x1ce):
 | 
			
		||||
    case PICA_REG_INDEX_WORKAROUND(lighting.lut_data[7], 0x1cf):
 | 
			
		||||
    {
 | 
			
		||||
        auto& lut_config = regs.lighting.lut_config;
 | 
			
		||||
        uniform_block_data.lut_dirty[lut_config.type] = true;
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -593,20 +615,23 @@ void RasterizerOpenGL::SetShader() {
 | 
			
		||||
 | 
			
		||||
        unsigned int block_index = glGetUniformBlockIndex(current_shader->shader.handle, "shader_data");
 | 
			
		||||
        glUniformBlockBinding(current_shader->shader.handle, block_index, 0);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Update uniforms
 | 
			
		||||
    SyncAlphaTest();
 | 
			
		||||
    SyncCombinerColor();
 | 
			
		||||
    auto& tev_stages = Pica::g_state.regs.GetTevStages();
 | 
			
		||||
    for (int index = 0; index < tev_stages.size(); ++index)
 | 
			
		||||
        SyncTevConstColor(index, tev_stages[index]);
 | 
			
		||||
        // Update uniforms
 | 
			
		||||
        SyncAlphaTest();
 | 
			
		||||
        SyncCombinerColor();
 | 
			
		||||
        auto& tev_stages = Pica::g_state.regs.GetTevStages();
 | 
			
		||||
        for (int index = 0; index < tev_stages.size(); ++index)
 | 
			
		||||
            SyncTevConstColor(index, tev_stages[index]);
 | 
			
		||||
 | 
			
		||||
    SyncGlobalAmbient();
 | 
			
		||||
    for (int light_index = 0; light_index < 8; light_index++) {
 | 
			
		||||
        SyncLightDiffuse(light_index);
 | 
			
		||||
        SyncLightAmbient(light_index);
 | 
			
		||||
        SyncLightPosition(light_index);
 | 
			
		||||
        for (unsigned index = 0; index < Pica::g_state.lighting.luts.size(); ++index)
 | 
			
		||||
            SyncLightingLUT(index);
 | 
			
		||||
 | 
			
		||||
        SyncGlobalAmbient();
 | 
			
		||||
        for (int light_index = 0; light_index < 8; light_index++) {
 | 
			
		||||
            SyncLightDiffuse(light_index);
 | 
			
		||||
            SyncLightAmbient(light_index);
 | 
			
		||||
            SyncLightPosition(light_index);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -796,6 +821,20 @@ void RasterizerOpenGL::SyncGlobalAmbient() {
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void RasterizerOpenGL::SyncLightingLUT(unsigned lut_index) {
 | 
			
		||||
    auto& lut = uniform_block_data.data.lighting_lut[lut_index / 4];
 | 
			
		||||
    std::array<std::array<GLfloat, 4>, 256> new_lut;
 | 
			
		||||
 | 
			
		||||
    for (int offset = 0; offset < new_lut.size(); ++offset) {
 | 
			
		||||
        new_lut[offset][lut_index & 3] = Pica::g_state.lighting.luts[lut_index][offset].ToFloat();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (new_lut != lut) {
 | 
			
		||||
        lut = new_lut;
 | 
			
		||||
        uniform_block_data.dirty = true;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void RasterizerOpenGL::SyncLightDiffuse(int light_index) {
 | 
			
		||||
    auto color = PicaToGL::LightColor(Pica::g_state.regs.lighting.light[light_index].diffuse);
 | 
			
		||||
    if (color != uniform_block_data.data.light_src[light_index].diffuse) {
 | 
			
		||||
 | 
			
		||||
@ -242,10 +242,11 @@ private:
 | 
			
		||||
        std::array<GLfloat, 3> lighting_global_ambient;
 | 
			
		||||
        INSERT_PADDING_WORDS(1);
 | 
			
		||||
        LightSrc light_src[8];
 | 
			
		||||
        std::array<std::array<std::array<GLfloat, 4>, 256>, 6> lighting_lut;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    static_assert(sizeof(UniformData) == 0x210, "The size of the UniformData structure has changed, update the structure in the shader");
 | 
			
		||||
    static_assert(sizeof(UniformData) < 16384, "UniformData structure must be less than 16kb as per the OpenGL spec");
 | 
			
		||||
    static_assert(sizeof(UniformData) == 0x6210, "The size of the UniformData structure has changed, update the structure in the shader");
 | 
			
		||||
    static_assert(sizeof(UniformData) < 32768, "UniformData structure must be less than 32kb");
 | 
			
		||||
 | 
			
		||||
    /// Reconfigure the OpenGL color texture to use the given format and dimensions
 | 
			
		||||
    void ReconfigureColorTexture(TextureInfo& texture, Pica::Regs::ColorFormat format, u32 width, u32 height);
 | 
			
		||||
@ -295,6 +296,9 @@ private:
 | 
			
		||||
    /// Syncs the lighting global ambient color to match the PICA register
 | 
			
		||||
    void SyncGlobalAmbient();
 | 
			
		||||
 | 
			
		||||
    /// Syncs the lighting lookup tables
 | 
			
		||||
    void SyncLightingLUT(unsigned index);
 | 
			
		||||
 | 
			
		||||
    /// Syncs the specified light's diffuse color to match the PICA register
 | 
			
		||||
    void SyncLightDiffuse(int light_index);
 | 
			
		||||
 | 
			
		||||
@ -346,6 +350,7 @@ private:
 | 
			
		||||
 | 
			
		||||
    struct {
 | 
			
		||||
        UniformData data;
 | 
			
		||||
        bool lut_dirty[24];
 | 
			
		||||
        bool dirty;
 | 
			
		||||
    } uniform_block_data;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -324,6 +324,7 @@ std::string GenerateFragmentShader(const PicaShaderConfig& config) {
 | 
			
		||||
#version 330 core
 | 
			
		||||
#define NUM_TEV_STAGES 6
 | 
			
		||||
#define NUM_LIGHTS 8
 | 
			
		||||
#define LIGHTING_LUT_SIZE 256
 | 
			
		||||
 | 
			
		||||
in vec4 primary_color;
 | 
			
		||||
in vec2 texcoord[3];
 | 
			
		||||
@ -345,6 +346,12 @@ layout (std140) uniform shader_data {
 | 
			
		||||
    float depth_offset;
 | 
			
		||||
    vec3 lighting_global_ambient;
 | 
			
		||||
    LightSrc light_src[NUM_LIGHTS];
 | 
			
		||||
    vec4 lighting_lut_0[LIGHTING_LUT_SIZE];
 | 
			
		||||
    vec4 lighting_lut_1[LIGHTING_LUT_SIZE];
 | 
			
		||||
    vec4 lighting_lut_2[LIGHTING_LUT_SIZE];
 | 
			
		||||
    vec4 lighting_lut_3[LIGHTING_LUT_SIZE];
 | 
			
		||||
    vec4 lighting_lut_4[LIGHTING_LUT_SIZE];
 | 
			
		||||
    vec4 lighting_lut_5[LIGHTING_LUT_SIZE];
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
uniform sampler2D tex[3];
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user