From 7b6a7d7dfb92d7a6d3537ea8b0339c2170d7eb84 Mon Sep 17 00:00:00 2001 From: Tony Wasserka Date: Sun, 3 Aug 2014 01:46:47 +0200 Subject: Pica/GPU: Change hardware registers to use physical addresses rather than virtual ones. This cleans up the mess that address reading/writing had become and makes the code a *lot* more sensible. This adds a physical<->virtual address converter to mem_map.h. For further accuracy, we will want to properly extend this to support a wider range of address regions. For now, this makes simply homebrew applications work in a good manner though. --- src/video_core/pica.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/video_core/pica.h') diff --git a/src/video_core/pica.h b/src/video_core/pica.h index d64559d72..858335d44 100644 --- a/src/video_core/pica.h +++ b/src/video_core/pica.h @@ -45,7 +45,7 @@ struct Regs { INSERT_PADDING_WORDS(0x41); BitField<0, 24, u32> viewport_size_x; - INSERT_PADDING_WORDS(1); + INSERT_PADDING_WORDS(0x1); BitField<0, 24, u32> viewport_size_y; INSERT_PADDING_WORDS(0x1bc); -- cgit v1.2.3 From 98ad16a45b9441a54d80e67425ac3ddee24f08dc Mon Sep 17 00:00:00 2001 From: Tony Wasserka Date: Sun, 27 Jul 2014 20:08:42 +0200 Subject: Pica: Add float24 structure. 24-bit floating points are used internally for calculations on the GPU, however the current code will still emulate that with 32-bit floating points. In the future we might want to accurately perform the calculations with correct bitness in the future, but for now we just wrap the calculations around this class. --- src/video_core/pica.h | 75 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) (limited to 'src/video_core/pica.h') diff --git a/src/video_core/pica.h b/src/video_core/pica.h index 858335d44..24b39a3ad 100644 --- a/src/video_core/pica.h +++ b/src/video_core/pica.h @@ -161,6 +161,81 @@ ASSERT_REG_POSITION(vertex_descriptor, 0x200); // 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), "Invalid total size of register set"); + +struct float24 { + static float24 FromFloat32(float val) { + float24 ret; + ret.value = val; + return ret; + } + + // 16 bit mantissa, 7 bit exponent, 1 bit sign + // TODO: No idea if this works as intended + static float24 FromRawFloat24(u32 hex) { + float24 ret; + if ((hex & 0xFFFFFF) == 0) { + ret.value = 0; + } else { + u32 mantissa = hex & 0xFFFF; + u32 exponent = (hex >> 16) & 0x7F; + u32 sign = hex >> 23; + ret.value = powf(2.0f, (float)exponent-63.0f) * (1.0f + mantissa * powf(2.0f, -16.f)); + if (sign) + ret.value = -ret.value; + } + return ret; + } + + // Not recommended for anything but logging + float ToFloat32() const { + return value; + } + + float24 operator * (const float24& flt) const { + return float24::FromFloat32(ToFloat32() * flt.ToFloat32()); + } + + float24 operator / (const float24& flt) const { + return float24::FromFloat32(ToFloat32() / flt.ToFloat32()); + } + + float24 operator + (const float24& flt) const { + return float24::FromFloat32(ToFloat32() + flt.ToFloat32()); + } + + float24 operator - (const float24& flt) const { + return float24::FromFloat32(ToFloat32() - flt.ToFloat32()); + } + + float24 operator - () const { + return float24::FromFloat32(-ToFloat32()); + } + + bool operator < (const float24& flt) const { + return ToFloat32() < flt.ToFloat32(); + } + + bool operator > (const float24& flt) const { + return ToFloat32() > flt.ToFloat32(); + } + + bool operator >= (const float24& flt) const { + return ToFloat32() >= flt.ToFloat32(); + } + + bool operator <= (const float24& flt) const { + return ToFloat32() <= flt.ToFloat32(); + } + +private: + float24() = default; + + // Stored as a regular float, merely for convenience + // TODO: Perform proper arithmetic on this! + float value; +}; + + union CommandHeader { CommandHeader(u32 h) : hex(h) {} -- cgit v1.2.3 From 76a586de4952df6d8dd9db9d97716c00690cebdd Mon Sep 17 00:00:00 2001 From: Tony Wasserka Date: Sat, 26 Jul 2014 14:42:46 +0200 Subject: Pica: Add command processor. --- src/video_core/pica.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/video_core/pica.h') diff --git a/src/video_core/pica.h b/src/video_core/pica.h index 24b39a3ad..0e231c6c9 100644 --- a/src/video_core/pica.h +++ b/src/video_core/pica.h @@ -161,6 +161,8 @@ ASSERT_REG_POSITION(vertex_descriptor, 0x200); // 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), "Invalid total size of register set"); +extern Regs registers; // TODO: Not sure if we want to have one global instance for this + struct float24 { static float24 FromFloat32(float val) { -- cgit v1.2.3 From 1a43f694777d356349c1e8a76eded883937efb87 Mon Sep 17 00:00:00 2001 From: Tony Wasserka Date: Sat, 26 Jul 2014 15:17:37 +0200 Subject: Pica: Add register definition for vertex loading and rendering. --- src/video_core/pica.h | 161 +++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 128 insertions(+), 33 deletions(-) (limited to 'src/video_core/pica.h') diff --git a/src/video_core/pica.h b/src/video_core/pica.h index 0e231c6c9..5bd7f416e 100644 --- a/src/video_core/pica.h +++ b/src/video_core/pica.h @@ -11,6 +11,8 @@ #include "common/bit_field.h" #include "common/common_types.h" +#include "core/mem_map.h" + namespace Pica { // Returns index corresponding to the Regs member labeled by field_name @@ -50,7 +52,7 @@ struct Regs { INSERT_PADDING_WORDS(0x1bc); - union { + struct { enum class Format : u64 { BYTE = 0, UBYTE = 1, @@ -58,36 +60,127 @@ struct Regs { FLOAT = 3, }; - BitField< 0, 2, Format> format0; - BitField< 2, 2, u64> size0; // number of elements minus 1 - BitField< 4, 2, Format> format1; - BitField< 6, 2, u64> size1; - BitField< 8, 2, Format> format2; - BitField<10, 2, u64> size2; - BitField<12, 2, Format> format3; - BitField<14, 2, u64> size3; - BitField<16, 2, Format> format4; - BitField<18, 2, u64> size4; - BitField<20, 2, Format> format5; - BitField<22, 2, u64> size5; - BitField<24, 2, Format> format6; - BitField<26, 2, u64> size6; - BitField<28, 2, Format> format7; - BitField<30, 2, u64> size7; - BitField<32, 2, Format> format8; - BitField<34, 2, u64> size8; - BitField<36, 2, Format> format9; - BitField<38, 2, u64> size9; - BitField<40, 2, Format> format10; - BitField<42, 2, u64> size10; - BitField<44, 2, Format> format11; - BitField<46, 2, u64> size11; - - BitField<48, 12, u64> attribute_mask; - BitField<60, 4, u64> num_attributes; // number of total attributes minus 1 - } vertex_descriptor; - - INSERT_PADDING_WORDS(0xfe); + BitField<0, 29, u32> base_address; + + inline u32 GetBaseAddress() const { + // TODO: Ugly, should fix PhysicalToVirtualAddress instead + return (base_address * 8) - Memory::FCRAM_PADDR + Memory::HEAP_GSP_VADDR; + } + + // Descriptor for internal vertex attributes + union { + BitField< 0, 2, Format> format0; // size of one element + BitField< 2, 2, u64> size0; // number of elements minus 1 + BitField< 4, 2, Format> format1; + BitField< 6, 2, u64> size1; + BitField< 8, 2, Format> format2; + BitField<10, 2, u64> size2; + BitField<12, 2, Format> format3; + BitField<14, 2, u64> size3; + BitField<16, 2, Format> format4; + BitField<18, 2, u64> size4; + BitField<20, 2, Format> format5; + BitField<22, 2, u64> size5; + BitField<24, 2, Format> format6; + BitField<26, 2, u64> size6; + BitField<28, 2, Format> format7; + BitField<30, 2, u64> size7; + BitField<32, 2, Format> format8; + BitField<34, 2, u64> size8; + BitField<36, 2, Format> format9; + BitField<38, 2, u64> size9; + BitField<40, 2, Format> format10; + BitField<42, 2, u64> size10; + BitField<44, 2, Format> format11; + BitField<46, 2, u64> size11; + + BitField<48, 12, u64> attribute_mask; + + // number of total attributes minus 1 + BitField<60, 4, u64> num_extra_attributes; + }; + + inline Format GetFormat(int n) const { + Format formats[] = { + format0, format1, format2, format3, + format4, format5, format6, format7, + format8, format9, format10, format11 + }; + return formats[n]; + } + + inline int GetNumElements(int n) const { + int sizes[] = { + size0, size1, size2, size3, + size4, size5, size6, size7, + size8, size9, size10, size11 + }; + return sizes[n]+1; + } + + inline int GetElementSizeInBytes(int n) const { + return (GetFormat(n) == Format::FLOAT) ? 4 : + (GetFormat(n) == Format::SHORT) ? 2 : 1; + } + + inline int GetStride(int n) const { + return GetNumElements(n) * GetElementSizeInBytes(n); + } + + inline int GetNumTotalAttributes() const { + return num_extra_attributes+1; + } + + // Attribute loaders map the source vertex data to input attributes + // This e.g. allows to load different attributes from different memory locations + struct Loader { + // Source attribute data offset from the base address + u32 data_offset; + + union { + BitField< 0, 4, u64> comp0; + BitField< 4, 4, u64> comp1; + BitField< 8, 4, u64> comp2; + BitField<12, 4, u64> comp3; + BitField<16, 4, u64> comp4; + BitField<20, 4, u64> comp5; + BitField<24, 4, u64> comp6; + BitField<28, 4, u64> comp7; + BitField<32, 4, u64> comp8; + BitField<36, 4, u64> comp9; + BitField<40, 4, u64> comp10; + BitField<44, 4, u64> comp11; + + // bytes for a single vertex in this loader + BitField<48, 8, u64> byte_count; + + BitField<60, 4, u64> component_count; + }; + + inline int GetComponent(int n) const { + int components[] = { + comp0, comp1, comp2, comp3, + comp4, comp5, comp6, comp7, + comp8, comp9, comp10, comp11 + }; + return components[n]; + } + } attribute_loaders[12]; + } vertex_attributes; + + struct { + enum IndexFormat : u32 { + BYTE = 0, + SHORT = 1, + }; + + union { + BitField<0, 31, u32> offset; // relative to base attribute address + BitField<31, 1, IndexFormat> format; + }; + } index_array; + + INSERT_PADDING_WORDS(0xd8); #undef INSERT_PADDING_WORDS_HELPER1 #undef INSERT_PADDING_WORDS_HELPER2 @@ -112,7 +205,8 @@ struct Regs { ADD_FIELD(viewport_size_x); ADD_FIELD(viewport_size_y); - ADD_FIELD(vertex_descriptor); + ADD_FIELD(vertex_attributes); + ADD_FIELD(index_array); #undef ADD_FIELD #endif // _MSC_VER @@ -153,7 +247,8 @@ private: ASSERT_REG_POSITION(viewport_size_x, 0x41); ASSERT_REG_POSITION(viewport_size_y, 0x43); -ASSERT_REG_POSITION(vertex_descriptor, 0x200); +ASSERT_REG_POSITION(vertex_attributes, 0x200); +ASSERT_REG_POSITION(index_array, 0x227); #undef ASSERT_REG_POSITION #endif // !defined(_MSC_VER) -- cgit v1.2.3 From d443f0a92183c94eaa0c33dddbb450eb8fe2fd07 Mon Sep 17 00:00:00 2001 From: Tony Wasserka Date: Sat, 26 Jul 2014 16:19:11 +0200 Subject: Pica: Implement vertex loading. --- src/video_core/pica.h | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) (limited to 'src/video_core/pica.h') diff --git a/src/video_core/pica.h b/src/video_core/pica.h index 5bd7f416e..faf124c3d 100644 --- a/src/video_core/pica.h +++ b/src/video_core/pica.h @@ -64,7 +64,7 @@ struct Regs { inline u32 GetBaseAddress() const { // TODO: Ugly, should fix PhysicalToVirtualAddress instead - return (base_address * 8) - Memory::FCRAM_PADDR + Memory::HEAP_GSP_VADDR; + return DecodeAddressRegister(base_address) - Memory::FCRAM_PADDR + Memory::HEAP_GSP_VADDR; } // Descriptor for internal vertex attributes @@ -110,12 +110,12 @@ struct Regs { } inline int GetNumElements(int n) const { - int sizes[] = { + u64 sizes[] = { size0, size1, size2, size3, size4, size5, size6, size7, size8, size9, size10, size11 }; - return sizes[n]+1; + return (int)sizes[n]+1; } inline int GetElementSizeInBytes(int n) const { @@ -128,7 +128,7 @@ struct Regs { } inline int GetNumTotalAttributes() const { - return num_extra_attributes+1; + return (int)num_extra_attributes+1; } // Attribute loaders map the source vertex data to input attributes @@ -158,12 +158,12 @@ struct Regs { }; inline int GetComponent(int n) const { - int components[] = { + u64 components[] = { comp0, comp1, comp2, comp3, comp4, comp5, comp6, comp7, comp8, comp9, comp10, comp11 }; - return components[n]; + return (int)components[n]; } } attribute_loaders[12]; } vertex_attributes; @@ -180,7 +180,16 @@ struct Regs { }; } index_array; - INSERT_PADDING_WORDS(0xd8); + // Number of vertices to render + u32 num_vertices; + + INSERT_PADDING_WORDS(0x5); + + // These two trigger rendering of triangles + u32 trigger_draw; + u32 trigger_draw_indexed; + + INSERT_PADDING_WORDS(0xd0); #undef INSERT_PADDING_WORDS_HELPER1 #undef INSERT_PADDING_WORDS_HELPER2 @@ -207,6 +216,9 @@ struct Regs { ADD_FIELD(viewport_size_y); ADD_FIELD(vertex_attributes); ADD_FIELD(index_array); + ADD_FIELD(num_vertices); + ADD_FIELD(trigger_draw); + ADD_FIELD(trigger_draw_indexed); #undef ADD_FIELD #endif // _MSC_VER @@ -249,6 +261,9 @@ ASSERT_REG_POSITION(viewport_size_x, 0x41); ASSERT_REG_POSITION(viewport_size_y, 0x43); ASSERT_REG_POSITION(vertex_attributes, 0x200); ASSERT_REG_POSITION(index_array, 0x227); +ASSERT_REG_POSITION(num_vertices, 0x228); +ASSERT_REG_POSITION(trigger_draw, 0x22e); +ASSERT_REG_POSITION(trigger_draw_indexed, 0x22f); #undef ASSERT_REG_POSITION #endif // !defined(_MSC_VER) -- cgit v1.2.3 From c52651261916b136f2ea4ff022fb9cead5a73a93 Mon Sep 17 00:00:00 2001 From: Tony Wasserka Date: Sat, 26 Jul 2014 19:17:09 +0200 Subject: Pica: Add vertex shader implementation. --- src/video_core/pica.h | 137 ++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 132 insertions(+), 5 deletions(-) (limited to 'src/video_core/pica.h') diff --git a/src/video_core/pica.h b/src/video_core/pica.h index faf124c3d..42303a585 100644 --- a/src/video_core/pica.h +++ b/src/video_core/pica.h @@ -50,7 +50,39 @@ struct Regs { INSERT_PADDING_WORDS(0x1); BitField<0, 24, u32> viewport_size_y; - INSERT_PADDING_WORDS(0x1bc); + INSERT_PADDING_WORDS(0xc); + + union { + // Maps components of output vertex attributes to semantics + enum Semantic : u32 + { + POSITION_X = 0, + POSITION_Y = 1, + POSITION_Z = 2, + POSITION_W = 3, + + COLOR_R = 8, + COLOR_G = 9, + COLOR_B = 10, + COLOR_A = 11, + + TEXCOORD0_U = 12, + TEXCOORD0_V = 13, + TEXCOORD1_U = 14, + TEXCOORD1_V = 15, + TEXCOORD2_U = 22, + TEXCOORD2_V = 23, + + INVALID = 31, + }; + + BitField< 0, 5, Semantic> map_x; + BitField< 8, 5, Semantic> map_y; + BitField<16, 5, Semantic> map_z; + BitField<24, 5, Semantic> map_w; + } vs_output_attributes[7]; + + INSERT_PADDING_WORDS(0x1a9); struct { enum class Format : u64 { @@ -133,7 +165,7 @@ struct Regs { // Attribute loaders map the source vertex data to input attributes // This e.g. allows to load different attributes from different memory locations - struct Loader { + struct { // Source attribute data offset from the base address u32 data_offset; @@ -189,7 +221,90 @@ struct Regs { u32 trigger_draw; u32 trigger_draw_indexed; - INSERT_PADDING_WORDS(0xd0); + INSERT_PADDING_WORDS(0x8a); + + // Offset to shader program entry point (in words) + BitField<0, 16, u32> vs_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) { + 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]; + } + } vs_input_register_map; + + INSERT_PADDING_WORDS(0x3); + + struct { + enum Format : u32 + { + FLOAT24 = 0, + FLOAT32 = 1 + }; + + bool IsFloat32() const { + return format == FLOAT32; + } + + 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; + + BitField<31, 1, Format> format; + }; + + // 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]; + + } vs_uniform_setup; + + INSERT_PADDING_WORDS(0x2); + + struct { + u32 begin_load; + + // 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; + + INSERT_PADDING_WORDS(0x1); + + // 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 { + u32 begin_load; + + // 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; + + INSERT_PADDING_WORDS(0x22); #undef INSERT_PADDING_WORDS_HELPER1 #undef INSERT_PADDING_WORDS_HELPER2 @@ -219,6 +334,11 @@ struct Regs { ADD_FIELD(num_vertices); ADD_FIELD(trigger_draw); ADD_FIELD(trigger_draw_indexed); + 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 #endif // _MSC_VER @@ -259,17 +379,25 @@ private: ASSERT_REG_POSITION(viewport_size_x, 0x41); ASSERT_REG_POSITION(viewport_size_y, 0x43); +ASSERT_REG_POSITION(vs_output_attributes[0], 0x50); +ASSERT_REG_POSITION(vs_output_attributes[1], 0x51); ASSERT_REG_POSITION(vertex_attributes, 0x200); ASSERT_REG_POSITION(index_array, 0x227); ASSERT_REG_POSITION(num_vertices, 0x228); ASSERT_REG_POSITION(trigger_draw, 0x22e); ASSERT_REG_POSITION(trigger_draw_indexed, 0x22f); +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); #undef ASSERT_REG_POSITION #endif // !defined(_MSC_VER) // 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), "Invalid total size of register set"); +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"); extern Regs registers; // TODO: Not sure if we want to have one global instance for this @@ -347,7 +475,6 @@ private: float value; }; - union CommandHeader { CommandHeader(u32 h) : hex(h) {} -- cgit v1.2.3 From 9a76a2d0611fc0c35b665fb886d437e8f4d5b4df Mon Sep 17 00:00:00 2001 From: Tony Wasserka Date: Sun, 27 Jul 2014 14:58:30 +0200 Subject: Pica: Add primitive assembly stage. --- src/video_core/pica.h | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) (limited to 'src/video_core/pica.h') diff --git a/src/video_core/pica.h b/src/video_core/pica.h index 42303a585..6bbd3ce33 100644 --- a/src/video_core/pica.h +++ b/src/video_core/pica.h @@ -221,7 +221,18 @@ struct Regs { u32 trigger_draw; u32 trigger_draw_indexed; - INSERT_PADDING_WORDS(0x8a); + INSERT_PADDING_WORDS(0x2e); + + enum class TriangleTopology : u32 { + List = 0, + Strip = 1, + Fan = 2, + ListIndexed = 3, // TODO: No idea if this is correct + }; + + BitField<8, 2, TriangleTopology> triangle_topology; + + INSERT_PADDING_WORDS(0x5b); // Offset to shader program entry point (in words) BitField<0, 16, u32> vs_main_offset; @@ -334,6 +345,7 @@ struct Regs { ADD_FIELD(num_vertices); ADD_FIELD(trigger_draw); ADD_FIELD(trigger_draw_indexed); + ADD_FIELD(triangle_topology); ADD_FIELD(vs_main_offset); ADD_FIELD(vs_input_register_map); ADD_FIELD(vs_uniform_setup); @@ -386,6 +398,7 @@ ASSERT_REG_POSITION(index_array, 0x227); ASSERT_REG_POSITION(num_vertices, 0x228); ASSERT_REG_POSITION(trigger_draw, 0x22e); ASSERT_REG_POSITION(trigger_draw_indexed, 0x22f); +ASSERT_REG_POSITION(triangle_topology, 0x25e); ASSERT_REG_POSITION(vs_main_offset, 0x2ba); ASSERT_REG_POSITION(vs_input_register_map, 0x2bb); ASSERT_REG_POSITION(vs_uniform_setup, 0x2c0); -- cgit v1.2.3 From 94aa9da562457e1fed4911d1cda770c3e42bd419 Mon Sep 17 00:00:00 2001 From: Tony Wasserka Date: Sun, 27 Jul 2014 17:34:11 +0200 Subject: Pica: Add triangle clipper. --- src/video_core/pica.h | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) (limited to 'src/video_core/pica.h') diff --git a/src/video_core/pica.h b/src/video_core/pica.h index 6bbd3ce33..1ced0d323 100644 --- a/src/video_core/pica.h +++ b/src/video_core/pica.h @@ -50,7 +50,12 @@ struct Regs { INSERT_PADDING_WORDS(0x1); BitField<0, 24, u32> viewport_size_y; - INSERT_PADDING_WORDS(0xc); + INSERT_PADDING_WORDS(0x9); + + BitField<0, 24, u32> viewport_depth_range; // float24 + BitField<0, 24, u32> viewport_depth_far_plane; // float24 + + INSERT_PADDING_WORDS(0x1); union { // Maps components of output vertex attributes to semantics @@ -82,7 +87,14 @@ struct Regs { BitField<24, 5, Semantic> map_w; } vs_output_attributes[7]; - INSERT_PADDING_WORDS(0x1a9); + INSERT_PADDING_WORDS(0x11); + + union { + BitField< 0, 16, u32> x; + BitField<16, 16, u32> y; + } viewport_corner; + + INSERT_PADDING_WORDS(0x197); struct { enum class Format : u64 { @@ -340,6 +352,9 @@ struct Regs { ADD_FIELD(viewport_size_x); ADD_FIELD(viewport_size_y); + ADD_FIELD(viewport_depth_range); + ADD_FIELD(viewport_depth_far_plane); + ADD_FIELD(viewport_corner); ADD_FIELD(vertex_attributes); ADD_FIELD(index_array); ADD_FIELD(num_vertices); @@ -391,8 +406,11 @@ private: ASSERT_REG_POSITION(viewport_size_x, 0x41); ASSERT_REG_POSITION(viewport_size_y, 0x43); +ASSERT_REG_POSITION(viewport_depth_range, 0x4d); +ASSERT_REG_POSITION(viewport_depth_far_plane, 0x4e); ASSERT_REG_POSITION(vs_output_attributes[0], 0x50); ASSERT_REG_POSITION(vs_output_attributes[1], 0x51); +ASSERT_REG_POSITION(viewport_corner, 0x68); ASSERT_REG_POSITION(vertex_attributes, 0x200); ASSERT_REG_POSITION(index_array, 0x227); ASSERT_REG_POSITION(num_vertices, 0x228); -- cgit v1.2.3 From 94d742fe172ba933af321bfb0e02889b40d0c179 Mon Sep 17 00:00:00 2001 From: Tony Wasserka Date: Sun, 27 Jul 2014 18:02:35 +0200 Subject: Pica: Add basic rasterizer. --- src/video_core/pica.h | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 51 insertions(+), 1 deletion(-) (limited to 'src/video_core/pica.h') diff --git a/src/video_core/pica.h b/src/video_core/pica.h index 1ced0d323..81af57336 100644 --- a/src/video_core/pica.h +++ b/src/video_core/pica.h @@ -94,7 +94,55 @@ struct Regs { BitField<16, 16, u32> y; } viewport_corner; - INSERT_PADDING_WORDS(0x197); + INSERT_PADDING_WORDS(0xa7); + + struct { + enum ColorFormat : u32 { + RGBA8 = 0, + RGB8 = 1, + RGBA5551 = 2, + RGB565 = 3, + RGBA4 = 4, + }; + + INSERT_PADDING_WORDS(0x6); + + u32 depth_format; + u32 color_format; + + INSERT_PADDING_WORDS(0x4); + + u32 depth_buffer_address; + u32 color_buffer_address; + + union { + // Apparently, the framebuffer width is stored as expected, + // while the height is stored as the actual height minus one. + // Hence, don't access these fields directly but use the accessors + // GetWidth() and GetHeight() instead. + BitField< 0, 11, u32> width; + BitField<12, 10, u32> height; + }; + + INSERT_PADDING_WORDS(0x1); + + inline u32 GetColorBufferAddress() const { + return Memory::PhysicalToVirtualAddress(DecodeAddressRegister(color_buffer_address)); + } + inline u32 GetDepthBufferAddress() const { + return Memory::PhysicalToVirtualAddress(DecodeAddressRegister(depth_buffer_address)); + } + + inline u32 GetWidth() const { + return width; + } + + inline u32 GetHeight() const { + return height + 1; + } + } framebuffer; + + INSERT_PADDING_WORDS(0xe0); struct { enum class Format : u64 { @@ -355,6 +403,7 @@ struct Regs { ADD_FIELD(viewport_depth_range); ADD_FIELD(viewport_depth_far_plane); ADD_FIELD(viewport_corner); + ADD_FIELD(framebuffer); ADD_FIELD(vertex_attributes); ADD_FIELD(index_array); ADD_FIELD(num_vertices); @@ -411,6 +460,7 @@ ASSERT_REG_POSITION(viewport_depth_far_plane, 0x4e); ASSERT_REG_POSITION(vs_output_attributes[0], 0x50); ASSERT_REG_POSITION(vs_output_attributes[1], 0x51); ASSERT_REG_POSITION(viewport_corner, 0x68); +ASSERT_REG_POSITION(framebuffer, 0x110); ASSERT_REG_POSITION(vertex_attributes, 0x200); ASSERT_REG_POSITION(index_array, 0x227); ASSERT_REG_POSITION(num_vertices, 0x228); -- cgit v1.2.3