summaryrefslogtreecommitdiff
path: root/src/video_core/vertex_shader.h
diff options
context:
space:
mode:
authorGravatar bunnei2014-12-20 12:40:06 -0500
committerGravatar bunnei2014-12-20 12:40:06 -0500
commitacabd7be82b4174a3adab0771df6320bdbc5a85b (patch)
treec47c2f68f50005bfb5c4003831f3977aec0be3ca /src/video_core/vertex_shader.h
parentMerge pull request #315 from chinhodado/master (diff)
parentPica/VertexShader: Promote a log message to critical status. (diff)
downloadyuzu-acabd7be82b4174a3adab0771df6320bdbc5a85b.tar.gz
yuzu-acabd7be82b4174a3adab0771df6320bdbc5a85b.tar.xz
yuzu-acabd7be82b4174a3adab0771df6320bdbc5a85b.zip
Merge pull request #284 from neobrain/pica_progress
Pica progress: Texturing, shaders, cleanups & more
Diffstat (limited to 'src/video_core/vertex_shader.h')
-rw-r--r--src/video_core/vertex_shader.h223
1 files changed, 11 insertions, 212 deletions
diff --git a/src/video_core/vertex_shader.h b/src/video_core/vertex_shader.h
index bfb6fb6e3..047dde046 100644
--- a/src/video_core/vertex_shader.h
+++ b/src/video_core/vertex_shader.h
@@ -27,15 +27,18 @@ struct OutputVertex {
27 Math::Vec4<float24> dummy; // quaternions (not implemented, yet) 27 Math::Vec4<float24> dummy; // quaternions (not implemented, yet)
28 Math::Vec4<float24> color; 28 Math::Vec4<float24> color;
29 Math::Vec2<float24> tc0; 29 Math::Vec2<float24> tc0;
30 Math::Vec2<float24> tc1;
31 float24 pad[6];
32 Math::Vec2<float24> tc2;
30 33
31 // Padding for optimal alignment 34 // Padding for optimal alignment
32 float24 pad[14]; 35 float24 pad2[4];
33 36
34 // Attributes used to store intermediate results 37 // Attributes used to store intermediate results
35 38
36 // position after perspective divide 39 // position after perspective divide
37 Math::Vec3<float24> screenpos; 40 Math::Vec3<float24> screenpos;
38 float24 pad2; 41 float24 pad3;
39 42
40 // Linear interpolation 43 // Linear interpolation
41 // factor: 0=this, 1=vtx 44 // factor: 0=this, 1=vtx
@@ -44,6 +47,8 @@ struct OutputVertex {
44 47
45 // TODO: Should perform perspective correct interpolation here... 48 // TODO: Should perform perspective correct interpolation here...
46 tc0 = tc0 * factor + vtx.tc0 * (float24::FromFloat32(1) - factor); 49 tc0 = tc0 * factor + vtx.tc0 * (float24::FromFloat32(1) - factor);
50 tc1 = tc1 * factor + vtx.tc1 * (float24::FromFloat32(1) - factor);
51 tc2 = tc2 * factor + vtx.tc2 * (float24::FromFloat32(1) - factor);
47 52
48 screenpos = screenpos * factor + vtx.screenpos * (float24::FromFloat32(1) - factor); 53 screenpos = screenpos * factor + vtx.screenpos * (float24::FromFloat32(1) - factor);
49 54
@@ -61,222 +66,16 @@ struct OutputVertex {
61static_assert(std::is_pod<OutputVertex>::value, "Structure is not POD"); 66static_assert(std::is_pod<OutputVertex>::value, "Structure is not POD");
62static_assert(sizeof(OutputVertex) == 32 * sizeof(float), "OutputVertex has invalid size"); 67static_assert(sizeof(OutputVertex) == 32 * sizeof(float), "OutputVertex has invalid size");
63 68
64union Instruction {
65 enum class OpCode : u32 {
66 ADD = 0x0,
67 DP3 = 0x1,
68 DP4 = 0x2,
69
70 MUL = 0x8,
71
72 MAX = 0xC,
73 MIN = 0xD,
74 RCP = 0xE,
75 RSQ = 0xF,
76
77 MOV = 0x13,
78
79 RET = 0x21,
80 FLS = 0x22, // Flush
81 CALL = 0x24,
82 };
83
84 std::string GetOpCodeName() const {
85 std::map<OpCode, std::string> map = {
86 { OpCode::ADD, "ADD" },
87 { OpCode::DP3, "DP3" },
88 { OpCode::DP4, "DP4" },
89 { OpCode::MUL, "MUL" },
90 { OpCode::MAX, "MAX" },
91 { OpCode::MIN, "MIN" },
92 { OpCode::RCP, "RCP" },
93 { OpCode::RSQ, "RSQ" },
94 { OpCode::MOV, "MOV" },
95 { OpCode::RET, "RET" },
96 { OpCode::FLS, "FLS" },
97 };
98 auto it = map.find(opcode);
99 if (it == map.end())
100 return "UNK";
101 else
102 return it->second;
103 }
104
105 u32 hex;
106
107 BitField<0x1a, 0x6, OpCode> opcode;
108
109 // General notes:
110 //
111 // When two input registers are used, one of them uses a 5-bit index while the other
112 // one uses a 7-bit index. This is because at most one floating point uniform may be used
113 // as an input.
114
115
116 // Format used e.g. by arithmetic instructions and comparisons
117 // "src1" and "src2" specify register indices (i.e. indices referring to groups of 4 floats),
118 // while "dest" addresses individual floats.
119 union {
120 BitField<0x00, 0x5, u32> operand_desc_id;
121
122 template<class BitFieldType>
123 struct SourceRegister : BitFieldType {
124 enum RegisterType {
125 Input,
126 Temporary,
127 FloatUniform
128 };
129
130 RegisterType GetRegisterType() const {
131 if (BitFieldType::Value() < 0x10)
132 return Input;
133 else if (BitFieldType::Value() < 0x20)
134 return Temporary;
135 else
136 return FloatUniform;
137 }
138
139 int GetIndex() const {
140 if (GetRegisterType() == Input)
141 return BitFieldType::Value();
142 else if (GetRegisterType() == Temporary)
143 return BitFieldType::Value() - 0x10;
144 else // if (GetRegisterType() == FloatUniform)
145 return BitFieldType::Value() - 0x20;
146 }
147
148 std::string GetRegisterName() const {
149 std::map<RegisterType, std::string> type = {
150 { Input, "i" },
151 { Temporary, "t" },
152 { FloatUniform, "f" },
153 };
154 return type[GetRegisterType()] + std::to_string(GetIndex());
155 }
156 };
157
158 SourceRegister<BitField<0x07, 0x5, u32>> src2;
159 SourceRegister<BitField<0x0c, 0x7, u32>> src1;
160
161 struct : BitField<0x15, 0x5, u32>
162 {
163 enum RegisterType {
164 Output,
165 Temporary,
166 Unknown
167 };
168 RegisterType GetRegisterType() const {
169 if (Value() < 0x8)
170 return Output;
171 else if (Value() < 0x10)
172 return Unknown;
173 else
174 return Temporary;
175 }
176 int GetIndex() const {
177 if (GetRegisterType() == Output)
178 return Value();
179 else if (GetRegisterType() == Temporary)
180 return Value() - 0x10;
181 else
182 return Value();
183 }
184 std::string GetRegisterName() const {
185 std::map<RegisterType, std::string> type = {
186 { Output, "o" },
187 { Temporary, "t" },
188 { Unknown, "u" }
189 };
190 return type[GetRegisterType()] + std::to_string(GetIndex());
191 }
192 } dest;
193 } common;
194
195 // Format used for flow control instructions ("if")
196 union {
197 BitField<0x00, 0x8, u32> num_instructions;
198 BitField<0x0a, 0xc, u32> offset_words;
199 } flow_control;
200};
201static_assert(std::is_standard_layout<Instruction>::value, "Structure is not using standard layout!");
202
203union SwizzlePattern {
204 u32 hex;
205
206 enum class Selector : u32 {
207 x = 0,
208 y = 1,
209 z = 2,
210 w = 3
211 };
212
213 Selector GetSelectorSrc1(int comp) const {
214 Selector selectors[] = {
215 src1_selector_0, src1_selector_1, src1_selector_2, src1_selector_3
216 };
217 return selectors[comp];
218 }
219
220 Selector GetSelectorSrc2(int comp) const {
221 Selector selectors[] = {
222 src2_selector_0, src2_selector_1, src2_selector_2, src2_selector_3
223 };
224 return selectors[comp];
225 }
226
227 bool DestComponentEnabled(int i) const {
228 return (dest_mask & (0x8 >> i)) != 0;
229 }
230
231 std::string SelectorToString(bool src2) const {
232 std::map<Selector, std::string> map = {
233 { Selector::x, "x" },
234 { Selector::y, "y" },
235 { Selector::z, "z" },
236 { Selector::w, "w" }
237 };
238 std::string ret;
239 for (int i = 0; i < 4; ++i) {
240 ret += map.at(src2 ? GetSelectorSrc2(i) : GetSelectorSrc1(i));
241 }
242 return ret;
243 }
244
245 std::string DestMaskToString() const {
246 std::string ret;
247 for (int i = 0; i < 4; ++i) {
248 if (!DestComponentEnabled(i))
249 ret += "_";
250 else
251 ret += "xyzw"[i];
252 }
253 return ret;
254 }
255
256 // Components of "dest" that should be written to: LSB=dest.w, MSB=dest.x
257 BitField< 0, 4, u32> dest_mask;
258
259 BitField< 4, 1, u32> negate; // negates src1
260
261 BitField< 5, 2, Selector> src1_selector_3;
262 BitField< 7, 2, Selector> src1_selector_2;
263 BitField< 9, 2, Selector> src1_selector_1;
264 BitField<11, 2, Selector> src1_selector_0;
265
266 BitField<14, 2, Selector> src2_selector_3;
267 BitField<16, 2, Selector> src2_selector_2;
268 BitField<18, 2, Selector> src2_selector_1;
269 BitField<20, 2, Selector> src2_selector_0;
270
271 BitField<31, 1, u32> flag; // not sure what this means, maybe it's the sign?
272};
273
274void SubmitShaderMemoryChange(u32 addr, u32 value); 69void SubmitShaderMemoryChange(u32 addr, u32 value);
275void SubmitSwizzleDataChange(u32 addr, u32 value); 70void SubmitSwizzleDataChange(u32 addr, u32 value);
276 71
277OutputVertex RunShader(const InputVertex& input, int num_attributes); 72OutputVertex RunShader(const InputVertex& input, int num_attributes);
278 73
279Math::Vec4<float24>& GetFloatUniform(u32 index); 74Math::Vec4<float24>& GetFloatUniform(u32 index);
75bool& GetBoolUniform(u32 index);
76
77const std::array<u32, 1024>& GetShaderBinary();
78const std::array<u32, 1024>& GetSwizzlePatterns();
280 79
281} // namespace 80} // namespace
282 81