summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/video_core/engines/shader_bytecode.h6
-rw-r--r--src/video_core/renderer_opengl/gl_shader_decompiler.cpp67
-rw-r--r--src/video_core/shader/shader_ir.cpp85
-rw-r--r--src/video_core/shader/shader_ir.h8
4 files changed, 119 insertions, 47 deletions
diff --git a/src/video_core/engines/shader_bytecode.h b/src/video_core/engines/shader_bytecode.h
index eba42deb4..49dc5abe0 100644
--- a/src/video_core/engines/shader_bytecode.h
+++ b/src/video_core/engines/shader_bytecode.h
@@ -82,6 +82,10 @@ union Attribute {
82 Position = 7, 82 Position = 7,
83 Attribute_0 = 8, 83 Attribute_0 = 8,
84 Attribute_31 = 39, 84 Attribute_31 = 39,
85 FrontColor = 40,
86 FrontSecondaryColor = 41,
87 BackColor = 42,
88 BackSecondaryColor = 43,
85 ClipDistances0123 = 44, 89 ClipDistances0123 = 44,
86 ClipDistances4567 = 45, 90 ClipDistances4567 = 45,
87 PointCoord = 46, 91 PointCoord = 46,
@@ -89,6 +93,8 @@ union Attribute {
89 // shader, and a tuple of (TessCoord.x, TessCoord.y, TessCoord.z, ~) when inside a Tess Eval 93 // shader, and a tuple of (TessCoord.x, TessCoord.y, TessCoord.z, ~) when inside a Tess Eval
90 // shader. 94 // shader.
91 TessCoordInstanceIDVertexID = 47, 95 TessCoordInstanceIDVertexID = 47,
96 TexCoord_0 = 48,
97 TexCoord_7 = 55,
92 // This attribute contains a tuple of (Unk, Unk, Unk, gl_FrontFacing) when inside a fragment 98 // This attribute contains a tuple of (Unk, Unk, Unk, gl_FrontFacing) when inside a fragment
93 // shader. It is unknown what the other values contain. 99 // shader. It is unknown what the other values contain.
94 FrontFacing = 63, 100 FrontFacing = 63,
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
index 2c38f57fd..8aa4a7ac9 100644
--- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
@@ -366,10 +366,19 @@ constexpr bool IsGenericAttribute(Attribute::Index index) {
366 return index >= Attribute::Index::Attribute_0 && index <= Attribute::Index::Attribute_31; 366 return index >= Attribute::Index::Attribute_0 && index <= Attribute::Index::Attribute_31;
367} 367}
368 368
369constexpr bool IsLegacyTexCoord(Attribute::Index index) {
370 return static_cast<int>(index) >= static_cast<int>(Attribute::Index::TexCoord_0) &&
371 static_cast<int>(index) <= static_cast<int>(Attribute::Index::TexCoord_7);
372}
373
369constexpr Attribute::Index ToGenericAttribute(u64 value) { 374constexpr Attribute::Index ToGenericAttribute(u64 value) {
370 return static_cast<Attribute::Index>(value + static_cast<u64>(Attribute::Index::Attribute_0)); 375 return static_cast<Attribute::Index>(value + static_cast<u64>(Attribute::Index::Attribute_0));
371} 376}
372 377
378constexpr int GetLegacyTexCoordIndex(Attribute::Index index) {
379 return static_cast<int>(index) - static_cast<int>(Attribute::Index::TexCoord_0);
380}
381
373u32 GetGenericAttributeIndex(Attribute::Index index) { 382u32 GetGenericAttributeIndex(Attribute::Index index) {
374 ASSERT(IsGenericAttribute(index)); 383 ASSERT(IsGenericAttribute(index));
375 return static_cast<u32>(index) - static_cast<u32>(Attribute::Index::Attribute_0); 384 return static_cast<u32>(index) - static_cast<u32>(Attribute::Index::Attribute_0);
@@ -498,7 +507,7 @@ private:
498 if (!identifier.empty()) { 507 if (!identifier.empty()) {
499 code.AddLine("// {}", identifier); 508 code.AddLine("// {}", identifier);
500 } 509 }
501 code.AddLine("#version 440 core"); 510 code.AddLine("#version 440 {}", ir.UsesLegacyVaryings() ? "compatibility" : "core");
502 code.AddLine("#extension GL_ARB_separate_shader_objects : enable"); 511 code.AddLine("#extension GL_ARB_separate_shader_objects : enable");
503 if (device.HasShaderBallot()) { 512 if (device.HasShaderBallot()) {
504 code.AddLine("#extension GL_ARB_shader_ballot : require"); 513 code.AddLine("#extension GL_ARB_shader_ballot : require");
@@ -561,6 +570,16 @@ private:
561 if (stage != ShaderType::Fragment) { 570 if (stage != ShaderType::Fragment) {
562 return; 571 return;
563 } 572 }
573 if (ir.UsesLegacyVaryings()) {
574 code.AddLine("in gl_PerFragment {{");
575 ++code.scope;
576 code.AddLine("vec4 gl_TexCoord[8];");
577 code.AddLine("vec4 gl_Color;");
578 code.AddLine("vec4 gl_SecondaryColor;");
579 --code.scope;
580 code.AddLine("}};");
581 }
582
564 for (u32 rt = 0; rt < Maxwell::NumRenderTargets; ++rt) { 583 for (u32 rt = 0; rt < Maxwell::NumRenderTargets; ++rt) {
565 code.AddLine("layout (location = {}) out vec4 frag_color{};", rt, rt); 584 code.AddLine("layout (location = {}) out vec4 frag_color{};", rt, rt);
566 } 585 }
@@ -617,12 +636,12 @@ private:
617 code.AddLine("float gl_PointSize;"); 636 code.AddLine("float gl_PointSize;");
618 } 637 }
619 638
620 if (ir.UsesInstanceId()) { 639 if (ir.UsesLegacyVaryings()) {
621 code.AddLine("int gl_InstanceID;"); 640 code.AddLine("vec4 gl_TexCoord[8];");
622 } 641 code.AddLine("vec4 gl_FrontColor;");
623 642 code.AddLine("vec4 gl_FrontSecondaryColor;");
624 if (ir.UsesVertexId()) { 643 code.AddLine("vec4 gl_BackColor;");
625 code.AddLine("int gl_VertexID;"); 644 code.AddLine("vec4 gl_BackSecondaryColor;");
626 } 645 }
627 646
628 --code.scope; 647 --code.scope;
@@ -1128,6 +1147,10 @@ private:
1128 default: 1147 default:
1129 UNREACHABLE(); 1148 UNREACHABLE();
1130 } 1149 }
1150 case Attribute::Index::FrontColor:
1151 return {"gl_Color"s + GetSwizzle(element), Type::Float};
1152 case Attribute::Index::FrontSecondaryColor:
1153 return {"gl_SecondaryColor"s + GetSwizzle(element), Type::Float};
1131 case Attribute::Index::PointCoord: 1154 case Attribute::Index::PointCoord:
1132 switch (element) { 1155 switch (element) {
1133 case 0: 1156 case 0:
@@ -1168,6 +1191,12 @@ private:
1168 return {GeometryPass(GetGenericInputAttribute(attribute)) + GetSwizzle(element), 1191 return {GeometryPass(GetGenericInputAttribute(attribute)) + GetSwizzle(element),
1169 Type::Float}; 1192 Type::Float};
1170 } 1193 }
1194 if (IsLegacyTexCoord(attribute)) {
1195 UNIMPLEMENTED_IF(stage == ShaderType::Geometry);
1196 return {fmt::format("gl_TexCoord[{}]{}", GetLegacyTexCoordIndex(attribute),
1197 GetSwizzle(element)),
1198 Type::Float};
1199 }
1171 break; 1200 break;
1172 } 1201 }
1173 UNIMPLEMENTED_MSG("Unhandled input attribute: {}", static_cast<u32>(attribute)); 1202 UNIMPLEMENTED_MSG("Unhandled input attribute: {}", static_cast<u32>(attribute));
@@ -1206,11 +1235,12 @@ private:
1206 } 1235 }
1207 1236
1208 std::optional<Expression> GetOutputAttribute(const AbufNode* abuf) { 1237 std::optional<Expression> GetOutputAttribute(const AbufNode* abuf) {
1238 const u32 element = abuf->GetElement();
1209 switch (const auto attribute = abuf->GetIndex()) { 1239 switch (const auto attribute = abuf->GetIndex()) {
1210 case Attribute::Index::Position: 1240 case Attribute::Index::Position:
1211 return {{"gl_Position"s + GetSwizzle(abuf->GetElement()), Type::Float}}; 1241 return {{"gl_Position"s + GetSwizzle(element), Type::Float}};
1212 case Attribute::Index::LayerViewportPointSize: 1242 case Attribute::Index::LayerViewportPointSize:
1213 switch (abuf->GetElement()) { 1243 switch (element) {
1214 case 0: 1244 case 0:
1215 UNIMPLEMENTED(); 1245 UNIMPLEMENTED();
1216 return {}; 1246 return {};
@@ -1228,13 +1258,26 @@ private:
1228 return {{"gl_PointSize", Type::Float}}; 1258 return {{"gl_PointSize", Type::Float}};
1229 } 1259 }
1230 return {}; 1260 return {};
1261 case Attribute::Index::FrontColor:
1262 return {{"gl_FrontColor"s + GetSwizzle(element), Type::Float}};
1263 case Attribute::Index::FrontSecondaryColor:
1264 return {{"gl_FrontSecondaryColor"s + GetSwizzle(element), Type::Float}};
1265 case Attribute::Index::BackColor:
1266 return {{"gl_BackColor"s + GetSwizzle(element), Type::Float}};
1267 case Attribute::Index::BackSecondaryColor:
1268 return {{"gl_BackSecondaryColor"s + GetSwizzle(element), Type::Float}};
1231 case Attribute::Index::ClipDistances0123: 1269 case Attribute::Index::ClipDistances0123:
1232 return {{fmt::format("gl_ClipDistance[{}]", abuf->GetElement()), Type::Float}}; 1270 return {{fmt::format("gl_ClipDistance[{}]", element), Type::Float}};
1233 case Attribute::Index::ClipDistances4567: 1271 case Attribute::Index::ClipDistances4567:
1234 return {{fmt::format("gl_ClipDistance[{}]", abuf->GetElement() + 4), Type::Float}}; 1272 return {{fmt::format("gl_ClipDistance[{}]", element + 4), Type::Float}};
1235 default: 1273 default:
1236 if (IsGenericAttribute(attribute)) { 1274 if (IsGenericAttribute(attribute)) {
1237 return {{GetGenericOutputAttribute(attribute, abuf->GetElement()), Type::Float}}; 1275 return {{GetGenericOutputAttribute(attribute, element), Type::Float}};
1276 }
1277 if (IsLegacyTexCoord(attribute)) {
1278 return {{fmt::format("gl_TexCoord[{}]{}", GetLegacyTexCoordIndex(attribute),
1279 GetSwizzle(element)),
1280 Type::Float}};
1238 } 1281 }
1239 UNIMPLEMENTED_MSG("Unhandled output attribute: {}", static_cast<u32>(attribute)); 1282 UNIMPLEMENTED_MSG("Unhandled output attribute: {}", static_cast<u32>(attribute));
1240 return {}; 1283 return {};
diff --git a/src/video_core/shader/shader_ir.cpp b/src/video_core/shader/shader_ir.cpp
index 425927777..baf7188d2 100644
--- a/src/video_core/shader/shader_ir.cpp
+++ b/src/video_core/shader/shader_ir.cpp
@@ -96,6 +96,7 @@ Node ShaderIR::GetPredicate(bool immediate) {
96} 96}
97 97
98Node ShaderIR::GetInputAttribute(Attribute::Index index, u64 element, Node buffer) { 98Node ShaderIR::GetInputAttribute(Attribute::Index index, u64 element, Node buffer) {
99 MarkAttributeUsage(index, element);
99 used_input_attributes.emplace(index); 100 used_input_attributes.emplace(index);
100 return MakeNode<AbufNode>(index, static_cast<u32>(element), std::move(buffer)); 101 return MakeNode<AbufNode>(index, static_cast<u32>(element), std::move(buffer));
101} 102}
@@ -106,42 +107,8 @@ Node ShaderIR::GetPhysicalInputAttribute(Tegra::Shader::Register physical_addres
106} 107}
107 108
108Node ShaderIR::GetOutputAttribute(Attribute::Index index, u64 element, Node buffer) { 109Node ShaderIR::GetOutputAttribute(Attribute::Index index, u64 element, Node buffer) {
109 if (index == Attribute::Index::LayerViewportPointSize) { 110 MarkAttributeUsage(index, element);
110 switch (element) {
111 case 0:
112 UNIMPLEMENTED();
113 break;
114 case 1:
115 uses_layer = true;
116 break;
117 case 2:
118 uses_viewport_index = true;
119 break;
120 case 3:
121 uses_point_size = true;
122 break;
123 }
124 }
125 if (index == Attribute::Index::TessCoordInstanceIDVertexID) {
126 switch (element) {
127 case 2:
128 uses_instance_id = true;
129 break;
130 case 3:
131 uses_vertex_id = true;
132 break;
133 default:
134 break;
135 }
136 }
137 if (index == Attribute::Index::ClipDistances0123 ||
138 index == Attribute::Index::ClipDistances4567) {
139 const auto clip_index =
140 static_cast<u32>((index == Attribute::Index::ClipDistances4567 ? 1 : 0) + element);
141 used_clip_distances.at(clip_index) = true;
142 }
143 used_output_attributes.insert(index); 111 used_output_attributes.insert(index);
144
145 return MakeNode<AbufNode>(index, static_cast<u32>(element), std::move(buffer)); 112 return MakeNode<AbufNode>(index, static_cast<u32>(element), std::move(buffer));
146} 113}
147 114
@@ -452,6 +419,54 @@ Node ShaderIR::BitfieldInsert(Node base, Node insert, u32 offset, u32 bits) {
452 Immediate(bits)); 419 Immediate(bits));
453} 420}
454 421
422void ShaderIR::MarkAttributeUsage(Attribute::Index index, u64 element) {
423 switch (index) {
424 case Attribute::Index::LayerViewportPointSize:
425 switch (element) {
426 case 0:
427 UNIMPLEMENTED();
428 break;
429 case 1:
430 uses_layer = true;
431 break;
432 case 2:
433 uses_viewport_index = true;
434 break;
435 case 3:
436 uses_point_size = true;
437 break;
438 }
439 break;
440 case Attribute::Index::TessCoordInstanceIDVertexID:
441 switch (element) {
442 case 2:
443 uses_instance_id = true;
444 break;
445 case 3:
446 uses_vertex_id = true;
447 break;
448 }
449 break;
450 case Attribute::Index::ClipDistances0123:
451 case Attribute::Index::ClipDistances4567: {
452 const u64 clip_index = (index == Attribute::Index::ClipDistances4567 ? 4 : 0) + element;
453 used_clip_distances.at(clip_index) = true;
454 break;
455 }
456 case Attribute::Index::FrontColor:
457 case Attribute::Index::FrontSecondaryColor:
458 case Attribute::Index::BackColor:
459 case Attribute::Index::BackSecondaryColor:
460 uses_legacy_varyings = true;
461 break;
462 default:
463 if (index >= Attribute::Index::TexCoord_0 && index <= Attribute::Index::TexCoord_7) {
464 uses_legacy_varyings = true;
465 }
466 break;
467 }
468}
469
455std::size_t ShaderIR::DeclareAmend(Node new_amend) { 470std::size_t ShaderIR::DeclareAmend(Node new_amend) {
456 const std::size_t id = amend_code.size(); 471 const std::size_t id = amend_code.size();
457 amend_code.push_back(new_amend); 472 amend_code.push_back(new_amend);
diff --git a/src/video_core/shader/shader_ir.h b/src/video_core/shader/shader_ir.h
index dde036b40..80fc9b82c 100644
--- a/src/video_core/shader/shader_ir.h
+++ b/src/video_core/shader/shader_ir.h
@@ -137,6 +137,10 @@ public:
137 return uses_vertex_id; 137 return uses_vertex_id;
138 } 138 }
139 139
140 bool UsesLegacyVaryings() const {
141 return uses_legacy_varyings;
142 }
143
140 bool UsesWarps() const { 144 bool UsesWarps() const {
141 return uses_warps; 145 return uses_warps;
142 } 146 }
@@ -343,6 +347,9 @@ private:
343 /// Inserts a sequence of bits from a node 347 /// Inserts a sequence of bits from a node
344 Node BitfieldInsert(Node base, Node insert, u32 offset, u32 bits); 348 Node BitfieldInsert(Node base, Node insert, u32 offset, u32 bits);
345 349
350 /// Marks the usage of a input or output attribute.
351 void MarkAttributeUsage(Tegra::Shader::Attribute::Index index, u64 element);
352
346 void WriteTexInstructionFloat(NodeBlock& bb, Tegra::Shader::Instruction instr, 353 void WriteTexInstructionFloat(NodeBlock& bb, Tegra::Shader::Instruction instr,
347 const Node4& components); 354 const Node4& components);
348 355
@@ -443,6 +450,7 @@ private:
443 bool uses_physical_attributes{}; // Shader uses AL2P or physical attribute read/writes 450 bool uses_physical_attributes{}; // Shader uses AL2P or physical attribute read/writes
444 bool uses_instance_id{}; 451 bool uses_instance_id{};
445 bool uses_vertex_id{}; 452 bool uses_vertex_id{};
453 bool uses_legacy_varyings{};
446 bool uses_warps{}; 454 bool uses_warps{};
447 bool uses_indexed_samplers{}; 455 bool uses_indexed_samplers{};
448 456