summaryrefslogtreecommitdiffstats
path: root/src/video_core/pica.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/video_core/pica.h')
-rw-r--r--src/video_core/pica.h224
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 {