From 4ff3d8e72f3fd0ca33e68a509557e44a2710a7ba Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Sun, 15 Mar 2020 20:49:35 -0300 Subject: [PATCH 1/5] shader/shader_ir: Change declare output attribute to a switch --- src/video_core/shader/shader_ir.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/video_core/shader/shader_ir.cpp b/src/video_core/shader/shader_ir.cpp index 425927777f..bc75d400ea 100644 --- a/src/video_core/shader/shader_ir.cpp +++ b/src/video_core/shader/shader_ir.cpp @@ -106,7 +106,8 @@ Node ShaderIR::GetPhysicalInputAttribute(Tegra::Shader::Register physical_addres } Node ShaderIR::GetOutputAttribute(Attribute::Index index, u64 element, Node buffer) { - if (index == Attribute::Index::LayerViewportPointSize) { + switch (index) { + case Attribute::Index::LayerViewportPointSize: switch (element) { case 0: UNIMPLEMENTED(); @@ -121,8 +122,8 @@ Node ShaderIR::GetOutputAttribute(Attribute::Index index, u64 element, Node buff uses_point_size = true; break; } - } - if (index == Attribute::Index::TessCoordInstanceIDVertexID) { + break; + case Attribute::Index::TessCoordInstanceIDVertexID: switch (element) { case 2: uses_instance_id = true; @@ -130,18 +131,17 @@ Node ShaderIR::GetOutputAttribute(Attribute::Index index, u64 element, Node buff case 3: uses_vertex_id = true; break; - default: - break; } - } - if (index == Attribute::Index::ClipDistances0123 || - index == Attribute::Index::ClipDistances4567) { + break; + case Attribute::Index::ClipDistances0123: + case Attribute::Index::ClipDistances4567: { const auto clip_index = static_cast((index == Attribute::Index::ClipDistances4567 ? 1 : 0) + element); used_clip_distances.at(clip_index) = true; + break; + } } used_output_attributes.insert(index); - return MakeNode(index, static_cast(element), std::move(buffer)); } From fd3d4d53e17e3d9cc2b0b2de78e0af9fcc091d55 Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Sun, 15 Mar 2020 20:50:20 -0300 Subject: [PATCH 2/5] shader/shader_ir: Fix clip distance usage stores --- src/video_core/shader/shader_ir.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/video_core/shader/shader_ir.cpp b/src/video_core/shader/shader_ir.cpp index bc75d400ea..32bb284526 100644 --- a/src/video_core/shader/shader_ir.cpp +++ b/src/video_core/shader/shader_ir.cpp @@ -135,8 +135,7 @@ Node ShaderIR::GetOutputAttribute(Attribute::Index index, u64 element, Node buff break; case Attribute::Index::ClipDistances0123: case Attribute::Index::ClipDistances4567: { - const auto clip_index = - static_cast((index == Attribute::Index::ClipDistances4567 ? 1 : 0) + element); + const u64 clip_index = (index == Attribute::Index::ClipDistances4567 ? 4 : 0) + element; used_clip_distances.at(clip_index) = true; break; } From bba58f7272cc29a74bd775891443044a4472d886 Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Sun, 15 Mar 2020 21:00:51 -0300 Subject: [PATCH 3/5] shader/shader_ir: Track usage in input attribute and of legacy varyings --- src/video_core/engines/shader_bytecode.h | 6 ++ src/video_core/shader/shader_ir.cpp | 84 ++++++++++++++---------- src/video_core/shader/shader_ir.h | 8 +++ 3 files changed, 64 insertions(+), 34 deletions(-) diff --git a/src/video_core/engines/shader_bytecode.h b/src/video_core/engines/shader_bytecode.h index c9bc83cd7d..4cd0c07a79 100644 --- a/src/video_core/engines/shader_bytecode.h +++ b/src/video_core/engines/shader_bytecode.h @@ -82,6 +82,10 @@ union Attribute { Position = 7, Attribute_0 = 8, Attribute_31 = 39, + FrontColor = 40, + FrontSecondaryColor = 41, + BackColor = 42, + BackSecondaryColor = 43, ClipDistances0123 = 44, ClipDistances4567 = 45, PointCoord = 46, @@ -89,6 +93,8 @@ union Attribute { // shader, and a tuple of (TessCoord.x, TessCoord.y, TessCoord.z, ~) when inside a Tess Eval // shader. TessCoordInstanceIDVertexID = 47, + TexCoord_0 = 48, + TexCoord_7 = 55, // This attribute contains a tuple of (Unk, Unk, Unk, gl_FrontFacing) when inside a fragment // shader. It is unknown what the other values contain. FrontFacing = 63, diff --git a/src/video_core/shader/shader_ir.cpp b/src/video_core/shader/shader_ir.cpp index 32bb284526..baf7188d28 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) { } Node ShaderIR::GetInputAttribute(Attribute::Index index, u64 element, Node buffer) { + MarkAttributeUsage(index, element); used_input_attributes.emplace(index); return MakeNode(index, static_cast(element), std::move(buffer)); } @@ -106,40 +107,7 @@ Node ShaderIR::GetPhysicalInputAttribute(Tegra::Shader::Register physical_addres } Node ShaderIR::GetOutputAttribute(Attribute::Index index, u64 element, Node buffer) { - switch (index) { - case Attribute::Index::LayerViewportPointSize: - switch (element) { - case 0: - UNIMPLEMENTED(); - break; - case 1: - uses_layer = true; - break; - case 2: - uses_viewport_index = true; - break; - case 3: - uses_point_size = true; - break; - } - break; - case Attribute::Index::TessCoordInstanceIDVertexID: - switch (element) { - case 2: - uses_instance_id = true; - break; - case 3: - uses_vertex_id = true; - break; - } - break; - case Attribute::Index::ClipDistances0123: - case Attribute::Index::ClipDistances4567: { - const u64 clip_index = (index == Attribute::Index::ClipDistances4567 ? 4 : 0) + element; - used_clip_distances.at(clip_index) = true; - break; - } - } + MarkAttributeUsage(index, element); used_output_attributes.insert(index); return MakeNode(index, static_cast(element), std::move(buffer)); } @@ -451,6 +419,54 @@ Node ShaderIR::BitfieldInsert(Node base, Node insert, u32 offset, u32 bits) { Immediate(bits)); } +void ShaderIR::MarkAttributeUsage(Attribute::Index index, u64 element) { + switch (index) { + case Attribute::Index::LayerViewportPointSize: + switch (element) { + case 0: + UNIMPLEMENTED(); + break; + case 1: + uses_layer = true; + break; + case 2: + uses_viewport_index = true; + break; + case 3: + uses_point_size = true; + break; + } + break; + case Attribute::Index::TessCoordInstanceIDVertexID: + switch (element) { + case 2: + uses_instance_id = true; + break; + case 3: + uses_vertex_id = true; + break; + } + break; + case Attribute::Index::ClipDistances0123: + case Attribute::Index::ClipDistances4567: { + const u64 clip_index = (index == Attribute::Index::ClipDistances4567 ? 4 : 0) + element; + used_clip_distances.at(clip_index) = true; + break; + } + case Attribute::Index::FrontColor: + case Attribute::Index::FrontSecondaryColor: + case Attribute::Index::BackColor: + case Attribute::Index::BackSecondaryColor: + uses_legacy_varyings = true; + break; + default: + if (index >= Attribute::Index::TexCoord_0 && index <= Attribute::Index::TexCoord_7) { + uses_legacy_varyings = true; + } + break; + } +} + std::size_t ShaderIR::DeclareAmend(Node new_amend) { const std::size_t id = amend_code.size(); 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 dde036b408..80fc9b82cc 100644 --- a/src/video_core/shader/shader_ir.h +++ b/src/video_core/shader/shader_ir.h @@ -137,6 +137,10 @@ public: return uses_vertex_id; } + bool UsesLegacyVaryings() const { + return uses_legacy_varyings; + } + bool UsesWarps() const { return uses_warps; } @@ -343,6 +347,9 @@ private: /// Inserts a sequence of bits from a node Node BitfieldInsert(Node base, Node insert, u32 offset, u32 bits); + /// Marks the usage of a input or output attribute. + void MarkAttributeUsage(Tegra::Shader::Attribute::Index index, u64 element); + void WriteTexInstructionFloat(NodeBlock& bb, Tegra::Shader::Instruction instr, const Node4& components); @@ -443,6 +450,7 @@ private: bool uses_physical_attributes{}; // Shader uses AL2P or physical attribute read/writes bool uses_instance_id{}; bool uses_vertex_id{}; + bool uses_legacy_varyings{}; bool uses_warps{}; bool uses_indexed_samplers{}; From c71e618ddbbd85c8f890c361d4998e7b30e49bcc Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Sun, 15 Mar 2020 21:03:54 -0300 Subject: [PATCH 4/5] gl_shader_decompiler: Implement legacy varyings Legacy varyings are special attributes carried over in hardware from the OpenGL 1 and OpenGL 2 days. These were generally used instead of the generic attributes we use today. They are deprecated or removed from most APIs, but Nvidia still ships them in hardware. To implement these, this commit maps them 1:1 to OpenGL compatibility. --- .../renderer_opengl/gl_shader_decompiler.cpp | 63 +++++++++++++++++-- 1 file changed, 57 insertions(+), 6 deletions(-) diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp index 3adf7f0cb7..f53d7021e9 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) { return index >= Attribute::Index::Attribute_0 && index <= Attribute::Index::Attribute_31; } +constexpr bool IsLegacyTexCoord(Attribute::Index index) { + return static_cast(index) >= static_cast(Attribute::Index::TexCoord_0) && + static_cast(index) <= static_cast(Attribute::Index::TexCoord_7); +} + constexpr Attribute::Index ToGenericAttribute(u64 value) { return static_cast(value + static_cast(Attribute::Index::Attribute_0)); } +constexpr int GetLegacyTexCoordIndex(Attribute::Index index) { + return static_cast(index) - static_cast(Attribute::Index::TexCoord_0); +} + u32 GetGenericAttributeIndex(Attribute::Index index) { ASSERT(IsGenericAttribute(index)); return static_cast(index) - static_cast(Attribute::Index::Attribute_0); @@ -502,7 +511,7 @@ private: if (!identifier.empty()) { code.AddLine("// {}", identifier); } - code.AddLine("#version 440 core"); + code.AddLine("#version 440 {}", ir.UsesLegacyVaryings() ? "compatibility" : "core"); code.AddLine("#extension GL_ARB_separate_shader_objects : enable"); if (device.HasShaderBallot()) { code.AddLine("#extension GL_ARB_shader_ballot : require"); @@ -564,6 +573,16 @@ private: if (stage != ShaderType::Fragment) { return; } + if (ir.UsesLegacyVaryings()) { + code.AddLine("in gl_PerFragment {{"); + ++code.scope; + code.AddLine("vec4 gl_TexCoord[8];"); + code.AddLine("vec4 gl_Color;"); + code.AddLine("vec4 gl_SecondaryColor;"); + --code.scope; + code.AddLine("}};"); + } + for (u32 rt = 0; rt < Maxwell::NumRenderTargets; ++rt) { code.AddLine("layout (location = {}) out vec4 frag_color{};", rt, rt); } @@ -628,6 +647,14 @@ private: code.AddLine("int gl_VertexID;"); } + if (ir.UsesLegacyVaryings()) { + code.AddLine("vec4 gl_TexCoord[8];"); + code.AddLine("vec4 gl_FrontColor;"); + code.AddLine("vec4 gl_FrontSecondaryColor;"); + code.AddLine("vec4 gl_BackColor;"); + code.AddLine("vec4 gl_BackSecondaryColor;"); + } + --code.scope; code.AddLine("}};"); code.AddNewLine(); @@ -1131,6 +1158,10 @@ private: default: UNREACHABLE(); } + case Attribute::Index::FrontColor: + return {"gl_Color"s + GetSwizzle(element), Type::Float}; + case Attribute::Index::FrontSecondaryColor: + return {"gl_SecondaryColor"s + GetSwizzle(element), Type::Float}; case Attribute::Index::PointCoord: switch (element) { case 0: @@ -1171,6 +1202,12 @@ private: return {GeometryPass(GetGenericInputAttribute(attribute)) + GetSwizzle(element), Type::Float}; } + if (IsLegacyTexCoord(attribute)) { + UNIMPLEMENTED_IF(stage == ShaderType::Geometry); + return {fmt::format("gl_TexCoord[{}]{}", GetLegacyTexCoordIndex(attribute), + GetSwizzle(element)), + Type::Float}; + } break; } UNIMPLEMENTED_MSG("Unhandled input attribute: {}", static_cast(attribute)); @@ -1209,11 +1246,12 @@ private: } std::optional GetOutputAttribute(const AbufNode* abuf) { + const u32 element = abuf->GetElement(); switch (const auto attribute = abuf->GetIndex()) { case Attribute::Index::Position: - return {{"gl_Position"s + GetSwizzle(abuf->GetElement()), Type::Float}}; + return {{"gl_Position"s + GetSwizzle(element), Type::Float}}; case Attribute::Index::LayerViewportPointSize: - switch (abuf->GetElement()) { + switch (element) { case 0: UNIMPLEMENTED(); return {}; @@ -1231,13 +1269,26 @@ private: return {{"gl_PointSize", Type::Float}}; } return {}; + case Attribute::Index::FrontColor: + return {{"gl_FrontColor"s + GetSwizzle(element), Type::Float}}; + case Attribute::Index::FrontSecondaryColor: + return {{"gl_FrontSecondaryColor"s + GetSwizzle(element), Type::Float}}; + case Attribute::Index::BackColor: + return {{"gl_BackColor"s + GetSwizzle(element), Type::Float}}; + case Attribute::Index::BackSecondaryColor: + return {{"gl_BackSecondaryColor"s + GetSwizzle(element), Type::Float}}; case Attribute::Index::ClipDistances0123: - return {{fmt::format("gl_ClipDistance[{}]", abuf->GetElement()), Type::Float}}; + return {{fmt::format("gl_ClipDistance[{}]", element), Type::Float}}; case Attribute::Index::ClipDistances4567: - return {{fmt::format("gl_ClipDistance[{}]", abuf->GetElement() + 4), Type::Float}}; + return {{fmt::format("gl_ClipDistance[{}]", element + 4), Type::Float}}; default: if (IsGenericAttribute(attribute)) { - return {{GetGenericOutputAttribute(attribute, abuf->GetElement()), Type::Float}}; + return {{GetGenericOutputAttribute(attribute, element), Type::Float}}; + } + if (IsLegacyTexCoord(attribute)) { + return {{fmt::format("gl_TexCoord[{}]{}", GetLegacyTexCoordIndex(attribute), + GetSwizzle(element)), + Type::Float}}; } UNIMPLEMENTED_MSG("Unhandled output attribute: {}", static_cast(attribute)); return {}; From 704373040f5b1ad9c7423f895e189e57d6a61cfe Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Wed, 18 Mar 2020 01:28:41 -0300 Subject: [PATCH 5/5] gl_shader_decompiler: Don't redeclare gl_VertexID and gl_InstanceID --- src/video_core/renderer_opengl/gl_shader_decompiler.cpp | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp index f53d7021e9..e6ae8041b9 100644 --- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp +++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp @@ -639,14 +639,6 @@ private: code.AddLine("float gl_PointSize;"); } - if (ir.UsesInstanceId()) { - code.AddLine("int gl_InstanceID;"); - } - - if (ir.UsesVertexId()) { - code.AddLine("int gl_VertexID;"); - } - if (ir.UsesLegacyVaryings()) { code.AddLine("vec4 gl_TexCoord[8];"); code.AddLine("vec4 gl_FrontColor;");