summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar bunnei2015-09-09 22:39:43 -0400
committerGravatar bunnei2016-02-05 17:17:28 -0500
commitb0030755708849eb27fe2bf1cc481c5ab905468e (patch)
tree966520312f4a1db78c4d36181782793d5ee62ce2 /src
parentpica: Implement fragment lighting LUTs. (diff)
downloadyuzu-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.cpp2
-rw-r--r--src/video_core/pica.h63
-rw-r--r--src/video_core/pica_types.h56
-rw-r--r--src/video_core/shader/shader.cpp6
-rw-r--r--src/video_core/shader/shader.h8
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);
1095ASSERT_REG_POSITION(texture0_enable, 0x80); 1136ASSERT_REG_POSITION(texture0_enable, 0x80);
1096ASSERT_REG_POSITION(texture0, 0x81); 1137ASSERT_REG_POSITION(texture0, 0x81);
1097ASSERT_REG_POSITION(texture0_format, 0x8e); 1138ASSERT_REG_POSITION(texture0_format, 0x8e);
1139ASSERT_REG_POSITION(fragment_lighting_enable, 0x8f);
1098ASSERT_REG_POSITION(texture1, 0x91); 1140ASSERT_REG_POSITION(texture1, 0x91);
1099ASSERT_REG_POSITION(texture1_format, 0x96); 1141ASSERT_REG_POSITION(texture1_format, 0x96);
1100ASSERT_REG_POSITION(texture2, 0x99); 1142ASSERT_REG_POSITION(texture2, 0x99);
@@ -1109,6 +1151,7 @@ ASSERT_REG_POSITION(tev_stage5, 0xf8);
1109ASSERT_REG_POSITION(tev_combiner_buffer_color, 0xfd); 1151ASSERT_REG_POSITION(tev_combiner_buffer_color, 0xfd);
1110ASSERT_REG_POSITION(output_merger, 0x100); 1152ASSERT_REG_POSITION(output_merger, 0x100);
1111ASSERT_REG_POSITION(framebuffer, 0x110); 1153ASSERT_REG_POSITION(framebuffer, 0x110);
1154ASSERT_REG_POSITION(lighting, 0x140);
1112ASSERT_REG_POSITION(vertex_attributes, 0x200); 1155ASSERT_REG_POSITION(vertex_attributes, 0x200);
1113ASSERT_REG_POSITION(index_array, 0x227); 1156ASSERT_REG_POSITION(index_array, 0x227);
1114ASSERT_REG_POSITION(num_vertices, 0x228); 1157ASSERT_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
122static_assert(sizeof(float24) == sizeof(float), "Shader JIT assumes float24 is implemented as a 32-bit float"); 122static_assert(sizeof(float24) == sizeof(float), "Shader JIT assumes float24 is implemented as a 32-bit float");
123 123
124struct 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
146private:
147 // Stored as a regular float, merely for convenience
148 // TODO: Perform proper arithmetic on this!
149 float value;
150};
151
152struct 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
174private:
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