diff options
| author | 2015-09-09 22:39:43 -0400 | |
|---|---|---|
| committer | 2016-02-05 17:17:28 -0500 | |
| commit | b0030755708849eb27fe2bf1cc481c5ab905468e (patch) | |
| tree | 966520312f4a1db78c4d36181782793d5ee62ce2 /src | |
| parent | pica: Implement fragment lighting LUTs. (diff) | |
| download | yuzu-b0030755708849eb27fe2bf1cc481c5ab905468e.tar.gz yuzu-b0030755708849eb27fe2bf1cc481c5ab905468e.tar.xz yuzu-b0030755708849eb27fe2bf1cc481c5ab905468e.zip | |
pica: Implement decoding of basic fragment lighting components.
- Diffuse
- Distance attenuation
- float16/float20 types
- Vertex Shader 'view' output
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/clipper.cpp | 2 | ||||
| -rw-r--r-- | src/video_core/pica.h | 63 | ||||
| -rw-r--r-- | src/video_core/pica_types.h | 56 | ||||
| -rw-r--r-- | src/video_core/shader/shader.cpp | 6 | ||||
| -rw-r--r-- | src/video_core/shader/shader.h | 8 |
5 files changed, 120 insertions, 15 deletions
diff --git a/src/video_core/clipper.cpp b/src/video_core/clipper.cpp index 5d609da06..3a09d62f4 100644 --- a/src/video_core/clipper.cpp +++ b/src/video_core/clipper.cpp | |||
| @@ -68,6 +68,8 @@ static void InitScreenCoordinates(OutputVertex& vtx) | |||
| 68 | 68 | ||
| 69 | float24 inv_w = float24::FromFloat32(1.f) / vtx.pos.w; | 69 | float24 inv_w = float24::FromFloat32(1.f) / vtx.pos.w; |
| 70 | vtx.color *= inv_w; | 70 | vtx.color *= inv_w; |
| 71 | vtx.view *= inv_w; | ||
| 72 | vtx.quat *= inv_w; | ||
| 71 | vtx.tc0 *= inv_w; | 73 | vtx.tc0 *= inv_w; |
| 72 | vtx.tc1 *= inv_w; | 74 | vtx.tc1 *= inv_w; |
| 73 | vtx.tc2 *= inv_w; | 75 | vtx.tc2 *= inv_w; |
diff --git a/src/video_core/pica.h b/src/video_core/pica.h index b09484de4..178a4b83f 100644 --- a/src/video_core/pica.h +++ b/src/video_core/pica.h | |||
| @@ -241,7 +241,8 @@ struct Regs { | |||
| 241 | TextureConfig texture0; | 241 | TextureConfig texture0; |
| 242 | INSERT_PADDING_WORDS(0x8); | 242 | INSERT_PADDING_WORDS(0x8); |
| 243 | BitField<0, 4, TextureFormat> texture0_format; | 243 | BitField<0, 4, TextureFormat> texture0_format; |
| 244 | INSERT_PADDING_WORDS(0x2); | 244 | BitField<0, 1, u32> fragment_lighting_enable; |
| 245 | INSERT_PADDING_WORDS(0x1); | ||
| 245 | TextureConfig texture1; | 246 | TextureConfig texture1; |
| 246 | BitField<0, 4, TextureFormat> texture1_format; | 247 | BitField<0, 4, TextureFormat> texture1_format; |
| 247 | INSERT_PADDING_WORDS(0x2); | 248 | INSERT_PADDING_WORDS(0x2); |
| @@ -645,6 +646,22 @@ struct Regs { | |||
| 645 | 646 | ||
| 646 | INSERT_PADDING_WORDS(0x20); | 647 | INSERT_PADDING_WORDS(0x20); |
| 647 | 648 | ||
| 649 | enum class LightingSampler { | ||
| 650 | Distribution0 = 0, | ||
| 651 | Distribution1 = 1, | ||
| 652 | Fresnel = 3, | ||
| 653 | Blue = 4, | ||
| 654 | Green = 5, | ||
| 655 | Red = 6, | ||
| 656 | SpotlightAttenuation = 8, | ||
| 657 | DistanceAttenuation = 16, | ||
| 658 | }; | ||
| 659 | |||
| 660 | enum class LightingLutInput { | ||
| 661 | NH = 0, // Cosine of the angle between the normal and half-angle vectors | ||
| 662 | LN = 3, // Cosine of the angle between the light and the normal vectors | ||
| 663 | }; | ||
| 664 | |||
| 648 | struct { | 665 | struct { |
| 649 | union LightColor { | 666 | union LightColor { |
| 650 | BitField< 0, 10, u32> b; | 667 | BitField< 0, 10, u32> b; |
| @@ -664,17 +681,21 @@ struct Regs { | |||
| 664 | 681 | ||
| 665 | struct { | 682 | struct { |
| 666 | // Encoded as 16-bit floating point | 683 | // Encoded as 16-bit floating point |
| 667 | u16 x; | 684 | union { |
| 668 | u16 y; | 685 | BitField< 0, 16, u32> x; |
| 669 | u16 z; | 686 | BitField<16, 16, u32> y; |
| 670 | u16 unk; | 687 | }; |
| 688 | union { | ||
| 689 | BitField< 0, 16, u32> z; | ||
| 690 | }; | ||
| 671 | 691 | ||
| 672 | INSERT_PADDING_WORDS(0x3); | 692 | INSERT_PADDING_WORDS(0x3); |
| 673 | 693 | ||
| 674 | // 1.f if 0, otherwise 0.f | 694 | union { |
| 675 | BitField<0, 1, u32> w; | 695 | BitField<0, 1, u32> w; // 1.f if 0, otherwise 0.f |
| 676 | } position; | 696 | BitField<1, 1, u32> two_sided_diffuse; // when disabled, clamp dot-product to 0 |
| 677 | 697 | }; | |
| 698 | }; | ||
| 678 | 699 | ||
| 679 | BitField<0, 20, u32> dist_atten_bias; | 700 | BitField<0, 20, u32> dist_atten_bias; |
| 680 | BitField<0, 20, u32> dist_atten_scale; | 701 | BitField<0, 20, u32> dist_atten_scale; |
| @@ -722,7 +743,27 @@ struct Regs { | |||
| 722 | // registers is written to, the behavior will be the same. | 743 | // registers is written to, the behavior will be the same. |
| 723 | u32 lut_data[8]; | 744 | u32 lut_data[8]; |
| 724 | 745 | ||
| 725 | INSERT_PADDING_WORDS(0x9); | 746 | union { |
| 747 | BitField< 1, 1, u32> d0; | ||
| 748 | BitField< 5, 1, u32> d1; | ||
| 749 | BitField< 9, 1, u32> sp; | ||
| 750 | BitField<13, 1, u32> fr; | ||
| 751 | BitField<17, 1, u32> rb; | ||
| 752 | BitField<21, 1, u32> rg; | ||
| 753 | BitField<25, 1, u32> rr; | ||
| 754 | } abs_lut_input; | ||
| 755 | |||
| 756 | union { | ||
| 757 | BitField< 0, 3, u32> d0; | ||
| 758 | BitField< 4, 3, u32> d1; | ||
| 759 | BitField< 8, 3, u32> sp; | ||
| 760 | BitField<12, 3, u32> fr; | ||
| 761 | BitField<16, 3, u32> rb; | ||
| 762 | BitField<20, 3, u32> rg; | ||
| 763 | BitField<24, 3, u32> rr; | ||
| 764 | } lut_input; | ||
| 765 | |||
| 766 | INSERT_PADDING_WORDS(0x7); | ||
| 726 | 767 | ||
| 727 | union { | 768 | union { |
| 728 | // There are 8 light enable "slots", corresponding to the total number of lights | 769 | // There are 8 light enable "slots", corresponding to the total number of lights |
| @@ -1095,6 +1136,7 @@ ASSERT_REG_POSITION(viewport_corner, 0x68); | |||
| 1095 | ASSERT_REG_POSITION(texture0_enable, 0x80); | 1136 | ASSERT_REG_POSITION(texture0_enable, 0x80); |
| 1096 | ASSERT_REG_POSITION(texture0, 0x81); | 1137 | ASSERT_REG_POSITION(texture0, 0x81); |
| 1097 | ASSERT_REG_POSITION(texture0_format, 0x8e); | 1138 | ASSERT_REG_POSITION(texture0_format, 0x8e); |
| 1139 | ASSERT_REG_POSITION(fragment_lighting_enable, 0x8f); | ||
| 1098 | ASSERT_REG_POSITION(texture1, 0x91); | 1140 | ASSERT_REG_POSITION(texture1, 0x91); |
| 1099 | ASSERT_REG_POSITION(texture1_format, 0x96); | 1141 | ASSERT_REG_POSITION(texture1_format, 0x96); |
| 1100 | ASSERT_REG_POSITION(texture2, 0x99); | 1142 | ASSERT_REG_POSITION(texture2, 0x99); |
| @@ -1109,6 +1151,7 @@ ASSERT_REG_POSITION(tev_stage5, 0xf8); | |||
| 1109 | ASSERT_REG_POSITION(tev_combiner_buffer_color, 0xfd); | 1151 | ASSERT_REG_POSITION(tev_combiner_buffer_color, 0xfd); |
| 1110 | ASSERT_REG_POSITION(output_merger, 0x100); | 1152 | ASSERT_REG_POSITION(output_merger, 0x100); |
| 1111 | ASSERT_REG_POSITION(framebuffer, 0x110); | 1153 | ASSERT_REG_POSITION(framebuffer, 0x110); |
| 1154 | ASSERT_REG_POSITION(lighting, 0x140); | ||
| 1112 | ASSERT_REG_POSITION(vertex_attributes, 0x200); | 1155 | ASSERT_REG_POSITION(vertex_attributes, 0x200); |
| 1113 | ASSERT_REG_POSITION(index_array, 0x227); | 1156 | ASSERT_REG_POSITION(index_array, 0x227); |
| 1114 | ASSERT_REG_POSITION(num_vertices, 0x228); | 1157 | ASSERT_REG_POSITION(num_vertices, 0x228); |
diff --git a/src/video_core/pica_types.h b/src/video_core/pica_types.h index de798aa81..a34421c5d 100644 --- a/src/video_core/pica_types.h +++ b/src/video_core/pica_types.h | |||
| @@ -121,4 +121,60 @@ private: | |||
| 121 | 121 | ||
| 122 | static_assert(sizeof(float24) == sizeof(float), "Shader JIT assumes float24 is implemented as a 32-bit float"); | 122 | static_assert(sizeof(float24) == sizeof(float), "Shader JIT assumes float24 is implemented as a 32-bit float"); |
| 123 | 123 | ||
| 124 | struct float16 { | ||
| 125 | // 10 bit mantissa, 5 bit exponent, 1 bit sign | ||
| 126 | // TODO: No idea if this works as intended | ||
| 127 | static float16 FromRawFloat16(u32 hex) { | ||
| 128 | float16 ret; | ||
| 129 | if ((hex & 0xFFFF) == 0) { | ||
| 130 | ret.value = 0; | ||
| 131 | } else { | ||
| 132 | u32 mantissa = hex & 0x3FF; | ||
| 133 | u32 exponent = (hex >> 10) & 0x1F; | ||
| 134 | u32 sign = (hex >> 15) & 1; | ||
| 135 | ret.value = std::pow(2.0f, (float)exponent - 15.0f) * (1.0f + mantissa * std::pow(2.0f, -10.f)); | ||
| 136 | if (sign) | ||
| 137 | ret.value = -ret.value; | ||
| 138 | } | ||
| 139 | return ret; | ||
| 140 | } | ||
| 141 | |||
| 142 | float ToFloat32() const { | ||
| 143 | return value; | ||
| 144 | } | ||
| 145 | |||
| 146 | private: | ||
| 147 | // Stored as a regular float, merely for convenience | ||
| 148 | // TODO: Perform proper arithmetic on this! | ||
| 149 | float value; | ||
| 150 | }; | ||
| 151 | |||
| 152 | struct float20 { | ||
| 153 | // 12 bit mantissa, 7 bit exponent, 1 bit sign | ||
| 154 | // TODO: No idea if this works as intended | ||
| 155 | static float20 FromRawFloat20(u32 hex) { | ||
| 156 | float20 ret; | ||
| 157 | if ((hex & 0xFFFFF) == 0) { | ||
| 158 | ret.value = 0; | ||
| 159 | } else { | ||
| 160 | u32 mantissa = hex & 0xFFF; | ||
| 161 | u32 exponent = (hex >> 12) & 0x7F; | ||
| 162 | u32 sign = (hex >> 19) & 1; | ||
| 163 | ret.value = std::pow(2.0f, (float)exponent - 63.0f) * (1.0f + mantissa * std::pow(2.0f, -12.f)); | ||
| 164 | if (sign) | ||
| 165 | ret.value = -ret.value; | ||
| 166 | } | ||
| 167 | return ret; | ||
| 168 | } | ||
| 169 | |||
| 170 | float ToFloat32() const { | ||
| 171 | return value; | ||
| 172 | } | ||
| 173 | |||
| 174 | private: | ||
| 175 | // Stored as a regular float, merely for convenience | ||
| 176 | // TODO: Perform proper arithmetic on this! | ||
| 177 | float value; | ||
| 178 | }; | ||
| 179 | |||
| 124 | } // namespace Pica | 180 | } // namespace Pica |
diff --git a/src/video_core/shader/shader.cpp b/src/video_core/shader/shader.cpp index 59f54236b..44c234ed8 100644 --- a/src/video_core/shader/shader.cpp +++ b/src/video_core/shader/shader.cpp | |||
| @@ -134,11 +134,13 @@ OutputVertex Run(UnitState<false>& state, const InputVertex& input, int num_attr | |||
| 134 | std::fmin(std::fabs(ret.color[i].ToFloat32()), 1.0f)); | 134 | std::fmin(std::fabs(ret.color[i].ToFloat32()), 1.0f)); |
| 135 | } | 135 | } |
| 136 | 136 | ||
| 137 | LOG_TRACE(Render_Software, "Output vertex: pos (%.2f, %.2f, %.2f, %.2f), quat (%.2f, %.2f, %.2f, %.2f), col(%.2f, %.2f, %.2f, %.2f), tc0(%.2f, %.2f)", | 137 | LOG_TRACE(Render_Software, "Output vertex: pos(%.2f, %.2f, %.2f, %.2f), quat(%.2f, %.2f, %.2f, %.2f), " |
| 138 | "col(%.2f, %.2f, %.2f, %.2f), tc0(%.2f, %.2f), view(%.2f, %.2f, %.2f)", | ||
| 138 | ret.pos.x.ToFloat32(), ret.pos.y.ToFloat32(), ret.pos.z.ToFloat32(), ret.pos.w.ToFloat32(), | 139 | ret.pos.x.ToFloat32(), ret.pos.y.ToFloat32(), ret.pos.z.ToFloat32(), ret.pos.w.ToFloat32(), |
| 139 | ret.quat.x.ToFloat32(), ret.quat.y.ToFloat32(), ret.quat.z.ToFloat32(), ret.quat.w.ToFloat32(), | 140 | ret.quat.x.ToFloat32(), ret.quat.y.ToFloat32(), ret.quat.z.ToFloat32(), ret.quat.w.ToFloat32(), |
| 140 | ret.color.x.ToFloat32(), ret.color.y.ToFloat32(), ret.color.z.ToFloat32(), ret.color.w.ToFloat32(), | 141 | ret.color.x.ToFloat32(), ret.color.y.ToFloat32(), ret.color.z.ToFloat32(), ret.color.w.ToFloat32(), |
| 141 | ret.tc0.u().ToFloat32(), ret.tc0.v().ToFloat32()); | 142 | ret.tc0.u().ToFloat32(), ret.tc0.v().ToFloat32(), |
| 143 | ret.view.x.ToFloat32(), ret.view.y.ToFloat32(), ret.view.z.ToFloat32()); | ||
| 142 | 144 | ||
| 143 | return ret; | 145 | return ret; |
| 144 | } | 146 | } |
diff --git a/src/video_core/shader/shader.h b/src/video_core/shader/shader.h index 1c6fa592c..f068cd93f 100644 --- a/src/video_core/shader/shader.h +++ b/src/video_core/shader/shader.h | |||
| @@ -37,17 +37,19 @@ struct OutputVertex { | |||
| 37 | Math::Vec4<float24> color; | 37 | Math::Vec4<float24> color; |
| 38 | Math::Vec2<float24> tc0; | 38 | Math::Vec2<float24> tc0; |
| 39 | Math::Vec2<float24> tc1; | 39 | Math::Vec2<float24> tc1; |
| 40 | float24 pad[6]; | 40 | INSERT_PADDING_WORDS(2); |
| 41 | Math::Vec3<float24> view; | ||
| 42 | INSERT_PADDING_WORDS(1); | ||
| 41 | Math::Vec2<float24> tc2; | 43 | Math::Vec2<float24> tc2; |
| 42 | 44 | ||
| 43 | // Padding for optimal alignment | 45 | // Padding for optimal alignment |
| 44 | float24 pad2[4]; | 46 | INSERT_PADDING_WORDS(4); |
| 45 | 47 | ||
| 46 | // Attributes used to store intermediate results | 48 | // Attributes used to store intermediate results |
| 47 | 49 | ||
| 48 | // position after perspective divide | 50 | // position after perspective divide |
| 49 | Math::Vec3<float24> screenpos; | 51 | Math::Vec3<float24> screenpos; |
| 50 | float24 pad3; | 52 | INSERT_PADDING_WORDS(1); |
| 51 | 53 | ||
| 52 | // Linear interpolation | 54 | // Linear interpolation |
| 53 | // factor: 0=this, 1=vtx | 55 | // factor: 0=this, 1=vtx |