diff options
Diffstat (limited to 'src/video_core/pica.h')
-rw-r--r-- | src/video_core/pica.h | 224 |
1 files changed, 123 insertions, 101 deletions
diff --git a/src/video_core/pica.h b/src/video_core/pica.h index 2b7ad206b..38599a7a3 100644 --- a/src/video_core/pica.h +++ b/src/video_core/pica.h @@ -119,6 +119,11 @@ struct Regs { MirroredRepeat = 3, }; + enum TextureFilter : u32 { + Nearest = 0, + Linear = 1 + }; + union { BitField< 0, 8, u32> r; BitField< 8, 8, u32> g; @@ -132,8 +137,10 @@ struct Regs { }; union { - BitField< 8, 2, WrapMode> wrap_s; - BitField<12, 2, WrapMode> wrap_t; + BitField< 1, 1, TextureFilter> mag_filter; + BitField< 2, 1, TextureFilter> min_filter; + BitField< 8, 2, WrapMode> wrap_t; + BitField<12, 2, WrapMode> wrap_s; }; INSERT_PADDING_WORDS(0x1); @@ -200,6 +207,7 @@ struct Regs { case TextureFormat::IA8: return 4; + case TextureFormat::I4: case TextureFormat::A4: return 1; @@ -784,112 +792,119 @@ struct Regs { INSERT_PADDING_WORDS(0x20); enum class TriangleTopology : u32 { - List = 0, - Strip = 1, - Fan = 2, - ListIndexed = 3, // TODO: No idea if this is correct + List = 0, + Strip = 1, + Fan = 2, + Shader = 3, // Programmable setup unit implemented in a geometry shader }; BitField<8, 2, TriangleTopology> triangle_topology; - INSERT_PADDING_WORDS(0x51); + INSERT_PADDING_WORDS(0x21); - BitField<0, 16, u32> vs_bool_uniforms; - union { - BitField< 0, 8, u32> x; - BitField< 8, 8, u32> y; - BitField<16, 8, u32> z; - BitField<24, 8, u32> w; - } vs_int_uniforms[4]; + struct ShaderConfig { + BitField<0, 16, u32> bool_uniforms; - INSERT_PADDING_WORDS(0x5); + union { + BitField< 0, 8, u32> x; + BitField< 8, 8, u32> y; + BitField<16, 8, u32> z; + BitField<24, 8, u32> w; + } int_uniforms[4]; - // Offset to shader program entry point (in words) - BitField<0, 16, u32> vs_main_offset; + INSERT_PADDING_WORDS(0x5); - union { - BitField< 0, 4, u64> attribute0_register; - BitField< 4, 4, u64> attribute1_register; - BitField< 8, 4, u64> attribute2_register; - BitField<12, 4, u64> attribute3_register; - BitField<16, 4, u64> attribute4_register; - BitField<20, 4, u64> attribute5_register; - BitField<24, 4, u64> attribute6_register; - BitField<28, 4, u64> attribute7_register; - BitField<32, 4, u64> attribute8_register; - BitField<36, 4, u64> attribute9_register; - BitField<40, 4, u64> attribute10_register; - BitField<44, 4, u64> attribute11_register; - BitField<48, 4, u64> attribute12_register; - BitField<52, 4, u64> attribute13_register; - BitField<56, 4, u64> attribute14_register; - BitField<60, 4, u64> attribute15_register; - - int GetRegisterForAttribute(int attribute_index) const { - u64 fields[] = { - attribute0_register, attribute1_register, attribute2_register, attribute3_register, - attribute4_register, attribute5_register, attribute6_register, attribute7_register, - attribute8_register, attribute9_register, attribute10_register, attribute11_register, - attribute12_register, attribute13_register, attribute14_register, attribute15_register, + // Offset to shader program entry point (in words) + BitField<0, 16, u32> main_offset; + + union { + BitField< 0, 4, u64> attribute0_register; + BitField< 4, 4, u64> attribute1_register; + BitField< 8, 4, u64> attribute2_register; + BitField<12, 4, u64> attribute3_register; + BitField<16, 4, u64> attribute4_register; + BitField<20, 4, u64> attribute5_register; + BitField<24, 4, u64> attribute6_register; + BitField<28, 4, u64> attribute7_register; + BitField<32, 4, u64> attribute8_register; + BitField<36, 4, u64> attribute9_register; + BitField<40, 4, u64> attribute10_register; + BitField<44, 4, u64> attribute11_register; + BitField<48, 4, u64> attribute12_register; + BitField<52, 4, u64> attribute13_register; + BitField<56, 4, u64> attribute14_register; + BitField<60, 4, u64> attribute15_register; + + int GetRegisterForAttribute(int attribute_index) const { + u64 fields[] = { + attribute0_register, attribute1_register, attribute2_register, attribute3_register, + attribute4_register, attribute5_register, attribute6_register, attribute7_register, + attribute8_register, attribute9_register, attribute10_register, attribute11_register, + attribute12_register, attribute13_register, attribute14_register, attribute15_register, + }; + return (int)fields[attribute_index]; + } + } input_register_map; + + // OUTMAP_MASK, 0x28E, CODETRANSFER_END + INSERT_PADDING_WORDS(0x3); + + struct { + enum Format : u32 + { + FLOAT24 = 0, + FLOAT32 = 1 }; - return (int)fields[attribute_index]; - } - } vs_input_register_map; - INSERT_PADDING_WORDS(0x3); + bool IsFloat32() const { + return format == FLOAT32; + } - struct { - enum Format : u32 - { - FLOAT24 = 0, - FLOAT32 = 1 - }; + union { + // Index of the next uniform to write to + // TODO: ctrulib uses 8 bits for this, however that seems to yield lots of invalid indices + // TODO: Maybe the uppermost index is for the geometry shader? Investigate! + BitField<0, 7, u32> index; - bool IsFloat32() const { - return format == FLOAT32; - } + BitField<31, 1, Format> format; + }; - union { - // Index of the next uniform to write to - // TODO: ctrulib uses 8 bits for this, however that seems to yield lots of invalid indices - BitField<0, 7, u32> index; + // Writing to these registers sets the current uniform. + u32 set_value[8]; - BitField<31, 1, Format> format; - }; + } uniform_setup; - // Writing to these registers sets the "current" uniform. - // TODO: It's not clear how the hardware stores what the "current" uniform is. - u32 set_value[8]; + INSERT_PADDING_WORDS(0x2); - } vs_uniform_setup; + struct { + // Offset of the next instruction to write code to. + // Incremented with each instruction write. + u32 offset; - INSERT_PADDING_WORDS(0x2); + // Writing to these registers sets the "current" word in the shader program. + u32 set_word[8]; + } program; - struct { - // Offset of the next instruction to write code to. - // Incremented with each instruction write. - u32 offset; + INSERT_PADDING_WORDS(0x1); - // Writing to these registers sets the "current" word in the shader program. - // TODO: It's not clear how the hardware stores what the "current" word is. - u32 set_word[8]; - } vs_program; + // This register group is used to load an internal table of swizzling patterns, + // which are indexed by each shader instruction to specify vector component swizzling. + struct { + // Offset of the next swizzle pattern to write code to. + // Incremented with each instruction write. + u32 offset; - INSERT_PADDING_WORDS(0x1); + // Writing to these registers sets the current swizzle pattern in the table. + u32 set_word[8]; + } swizzle_patterns; - // This register group is used to load an internal table of swizzling patterns, - // which are indexed by each shader instruction to specify vector component swizzling. - struct { - // Offset of the next swizzle pattern to write code to. - // Incremented with each instruction write. - u32 offset; + INSERT_PADDING_WORDS(0x2); + }; - // Writing to these registers sets the "current" swizzle pattern in the table. - // TODO: It's not clear how the hardware stores what the "current" swizzle pattern is. - u32 set_word[8]; - } vs_swizzle_patterns; + ShaderConfig gs; + ShaderConfig vs; - INSERT_PADDING_WORDS(0x22); + INSERT_PADDING_WORDS(0x20); // Map register indices to names readable by humans // Used for debugging purposes, so performance is not an issue here @@ -936,13 +951,20 @@ struct Regs { ADD_FIELD(vs_default_attributes_setup); ADD_FIELD(command_buffer); ADD_FIELD(triangle_topology); - ADD_FIELD(vs_bool_uniforms); - ADD_FIELD(vs_int_uniforms); - ADD_FIELD(vs_main_offset); - ADD_FIELD(vs_input_register_map); - ADD_FIELD(vs_uniform_setup); - ADD_FIELD(vs_program); - ADD_FIELD(vs_swizzle_patterns); + ADD_FIELD(gs.bool_uniforms); + ADD_FIELD(gs.int_uniforms); + ADD_FIELD(gs.main_offset); + ADD_FIELD(gs.input_register_map); + ADD_FIELD(gs.uniform_setup); + ADD_FIELD(gs.program); + ADD_FIELD(gs.swizzle_patterns); + ADD_FIELD(vs.bool_uniforms); + ADD_FIELD(vs.int_uniforms); + ADD_FIELD(vs.main_offset); + ADD_FIELD(vs.input_register_map); + ADD_FIELD(vs.uniform_setup); + ADD_FIELD(vs.program); + ADD_FIELD(vs.swizzle_patterns); #undef ADD_FIELD @@ -1014,17 +1036,14 @@ ASSERT_REG_POSITION(trigger_draw_indexed, 0x22f); ASSERT_REG_POSITION(vs_default_attributes_setup, 0x232); ASSERT_REG_POSITION(command_buffer, 0x238); ASSERT_REG_POSITION(triangle_topology, 0x25e); -ASSERT_REG_POSITION(vs_bool_uniforms, 0x2b0); -ASSERT_REG_POSITION(vs_int_uniforms, 0x2b1); -ASSERT_REG_POSITION(vs_main_offset, 0x2ba); -ASSERT_REG_POSITION(vs_input_register_map, 0x2bb); -ASSERT_REG_POSITION(vs_uniform_setup, 0x2c0); -ASSERT_REG_POSITION(vs_program, 0x2cb); -ASSERT_REG_POSITION(vs_swizzle_patterns, 0x2d5); +ASSERT_REG_POSITION(gs, 0x280); +ASSERT_REG_POSITION(vs, 0x2b0); #undef ASSERT_REG_POSITION #endif // !defined(_MSC_VER) +static_assert(sizeof(Regs::ShaderConfig) == 0x30 * sizeof(u32), "ShaderConfig structure has incorrect size"); + // The total number of registers is chosen arbitrarily, but let's make sure it's not some odd value anyway. static_assert(sizeof(Regs) <= 0x300 * sizeof(u32), "Register set structure larger than it should be"); static_assert(sizeof(Regs) >= 0x300 * sizeof(u32), "Register set structure smaller than it should be"); @@ -1134,7 +1153,7 @@ struct State { Regs regs; /// Vertex shader memory - struct { + struct ShaderSetup { struct { Math::Vec4<float24> f[96]; std::array<bool, 16> b; @@ -1145,7 +1164,10 @@ struct State { std::array<u32, 1024> program_code; std::array<u32, 1024> swizzle_data; - } vs; + }; + + ShaderSetup vs; + ShaderSetup gs; /// Current Pica command list struct { |