From 57855a1701474c65b8dd95d0c312d02fae8fe1a6 Mon Sep 17 00:00:00 2001 From: Jannik Vogel Date: Wed, 11 May 2016 13:39:28 +0200 Subject: [PATCH] Pica: Add fog state --- src/video_core/command_processor.cpp | 14 ++++++++ src/video_core/pica.h | 53 +++++++++++++++++++++------- src/video_core/pica_state.h | 16 +++++++-- 3 files changed, 69 insertions(+), 14 deletions(-) diff --git a/src/video_core/command_processor.cpp b/src/video_core/command_processor.cpp index 19e03adf4..689859049 100644 --- a/src/video_core/command_processor.cpp +++ b/src/video_core/command_processor.cpp @@ -423,6 +423,20 @@ static void WritePicaReg(u32 id, u32 value, u32 mask) { break; } + case PICA_REG_INDEX_WORKAROUND(fog_lut_data[0], 0xe8): + case PICA_REG_INDEX_WORKAROUND(fog_lut_data[1], 0xe9): + case PICA_REG_INDEX_WORKAROUND(fog_lut_data[2], 0xea): + case PICA_REG_INDEX_WORKAROUND(fog_lut_data[3], 0xeb): + case PICA_REG_INDEX_WORKAROUND(fog_lut_data[4], 0xec): + case PICA_REG_INDEX_WORKAROUND(fog_lut_data[5], 0xed): + case PICA_REG_INDEX_WORKAROUND(fog_lut_data[6], 0xee): + case PICA_REG_INDEX_WORKAROUND(fog_lut_data[7], 0xef): + { + g_state.fog.lut[regs.fog_lut_offset % 128].raw = value; + regs.fog_lut_offset.Assign(regs.fog_lut_offset + 1); + break; + } + default: break; } diff --git a/src/video_core/pica.h b/src/video_core/pica.h index 544ea037f..09702d46a 100644 --- a/src/video_core/pica.h +++ b/src/video_core/pica.h @@ -401,22 +401,47 @@ struct Regs { TevStageConfig tev_stage3; INSERT_PADDING_WORDS(0x3); + enum class FogMode : u32 { + None = 0, + Fog = 5, + Gas = 7, + }; + union { - // Tev stages 0-3 write their output to the combiner buffer if the corresponding bit in - // these masks are set - BitField< 8, 4, u32> update_mask_rgb; - BitField<12, 4, u32> update_mask_a; + BitField<0, 3, FogMode> fog_mode; + BitField<16, 1, u32> fog_flip; - bool TevStageUpdatesCombinerBufferColor(unsigned stage_index) const { - return (stage_index < 4) && (update_mask_rgb & (1 << stage_index)); - } + union { + // Tev stages 0-3 write their output to the combiner buffer if the corresponding bit in + // these masks are set + BitField< 8, 4, u32> update_mask_rgb; + BitField<12, 4, u32> update_mask_a; - bool TevStageUpdatesCombinerBufferAlpha(unsigned stage_index) const { - return (stage_index < 4) && (update_mask_a & (1 << stage_index)); - } - } tev_combiner_buffer_input; + bool TevStageUpdatesCombinerBufferColor(unsigned stage_index) const { + return (stage_index < 4) && (update_mask_rgb & (1 << stage_index)); + } + + bool TevStageUpdatesCombinerBufferAlpha(unsigned stage_index) const { + return (stage_index < 4) && (update_mask_a & (1 << stage_index)); + } + } tev_combiner_buffer_input; + }; + + union { + u32 raw; + BitField< 0, 8, u32> r; + BitField< 8, 8, u32> g; + BitField<16, 8, u32> b; + } fog_color; + + INSERT_PADDING_WORDS(0x4); + + BitField<0, 16, u32> fog_lut_offset; + + INSERT_PADDING_WORDS(0x1); + + u32 fog_lut_data[8]; - INSERT_PADDING_WORDS(0xf); TevStageConfig tev_stage4; INSERT_PADDING_WORDS(0x3); TevStageConfig tev_stage5; @@ -1318,6 +1343,10 @@ ASSERT_REG_POSITION(tev_stage1, 0xc8); ASSERT_REG_POSITION(tev_stage2, 0xd0); ASSERT_REG_POSITION(tev_stage3, 0xd8); ASSERT_REG_POSITION(tev_combiner_buffer_input, 0xe0); +ASSERT_REG_POSITION(fog_mode, 0xe0); +ASSERT_REG_POSITION(fog_color, 0xe1); +ASSERT_REG_POSITION(fog_lut_offset, 0xe6); +ASSERT_REG_POSITION(fog_lut_data, 0xe8); ASSERT_REG_POSITION(tev_stage4, 0xf0); ASSERT_REG_POSITION(tev_stage5, 0xf8); ASSERT_REG_POSITION(tev_combiner_buffer_color, 0xfd); diff --git a/src/video_core/pica_state.h b/src/video_core/pica_state.h index 495174c25..01f4285a8 100644 --- a/src/video_core/pica_state.h +++ b/src/video_core/pica_state.h @@ -33,10 +33,10 @@ struct State { u32 raw; // LUT value, encoded as 12-bit fixed point, with 12 fraction bits - BitField< 0, 12, u32> value; + BitField< 0, 12, u32> value; // 0.0.12 fixed point // Used by HW for efficient interpolation, Citra does not use these - BitField<12, 12, u32> difference; + BitField<12, 12, s32> difference; // 1.0.11 fixed point float ToFloat() { return static_cast(value) / 4095.f; @@ -46,6 +46,18 @@ struct State { std::array, 24> luts; } lighting; + struct { + union LutEntry { + // Used for raw access + u32 raw; + + BitField< 0, 13, s32> difference; // 1.1.11 fixed point + BitField<13, 11, u32> value; // 0.0.11 fixed point + }; + + std::array lut; + } fog; + /// Current Pica command list struct { const u32* head_ptr;