diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/engines/shader_bytecode.h | 6 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_decompiler.cpp | 67 | ||||
| -rw-r--r-- | src/video_core/shader/shader_ir.cpp | 85 | ||||
| -rw-r--r-- | src/video_core/shader/shader_ir.h | 8 |
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 | ||
| 369 | constexpr 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 | |||
| 369 | constexpr Attribute::Index ToGenericAttribute(u64 value) { | 374 | constexpr 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 | ||
| 378 | constexpr int GetLegacyTexCoordIndex(Attribute::Index index) { | ||
| 379 | return static_cast<int>(index) - static_cast<int>(Attribute::Index::TexCoord_0); | ||
| 380 | } | ||
| 381 | |||
| 373 | u32 GetGenericAttributeIndex(Attribute::Index index) { | 382 | u32 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 | ||
| 98 | Node ShaderIR::GetInputAttribute(Attribute::Index index, u64 element, Node buffer) { | 98 | Node 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 | ||
| 108 | Node ShaderIR::GetOutputAttribute(Attribute::Index index, u64 element, Node buffer) { | 109 | Node 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 | ||
| 422 | void 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 | |||
| 455 | std::size_t ShaderIR::DeclareAmend(Node new_amend) { | 470 | std::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 | ||