From 464bd5fad79c59455504d10b7aa084d683817de4 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 8e6e55d6f849c42ac3a1641e91d85ce8613dbc58 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 6442e02c5daf09b1087dffb26780c03ed5d2ffd5 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 5afc397d52f71e0831fee72d6e1aca3683a3a0ef 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 f5658a9fdab5e4511a9204a4747b7f733f67d04f 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;");