summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to '')
-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 {
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/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) {
return index >= Attribute::Index::Attribute_0 && index <= Attribute::Index::Attribute_31;
}
+constexpr bool IsLegacyTexCoord(Attribute::Index index) {
+ return static_cast<int>(index) >= static_cast<int>(Attribute::Index::TexCoord_0) &&
+ static_cast<int>(index) <= static_cast<int>(Attribute::Index::TexCoord_7);
+}
+
constexpr Attribute::Index ToGenericAttribute(u64 value) {
return static_cast<Attribute::Index>(value + static_cast<u64>(Attribute::Index::Attribute_0));
}
+constexpr int GetLegacyTexCoordIndex(Attribute::Index index) {
+ return static_cast<int>(index) - static_cast<int>(Attribute::Index::TexCoord_0);
+}
+
u32 GetGenericAttributeIndex(Attribute::Index index) {
ASSERT(IsGenericAttribute(index));
return static_cast<u32>(index) - static_cast<u32>(Attribute::Index::Attribute_0);
@@ -498,7 +507,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");
@@ -561,6 +570,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);
}
@@ -617,12 +636,12 @@ 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;");
+ code.AddLine("vec4 gl_FrontSecondaryColor;");
+ code.AddLine("vec4 gl_BackColor;");
+ code.AddLine("vec4 gl_BackSecondaryColor;");
}
--code.scope;
@@ -1128,6 +1147,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:
@@ -1168,6 +1191,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<u32>(attribute));
@@ -1206,11 +1235,12 @@ private:
}
std::optional<Expression> 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 {};
@@ -1228,13 +1258,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<u32>(attribute));
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) {
}
Node ShaderIR::GetInputAttribute(Attribute::Index index, u64 element, Node buffer) {
+ MarkAttributeUsage(index, element);
used_input_attributes.emplace(index);
return MakeNode<AbufNode>(index, static_cast<u32>(element), std::move(buffer));
}
@@ -106,42 +107,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 (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;
- }
- }
- if (index == Attribute::Index::TessCoordInstanceIDVertexID) {
- switch (element) {
- case 2:
- uses_instance_id = true;
- break;
- case 3:
- uses_vertex_id = true;
- break;
- default:
- break;
- }
- }
- if (index == Attribute::Index::ClipDistances0123 ||
- index == Attribute::Index::ClipDistances4567) {
- const auto clip_index =
- static_cast<u32>((index == Attribute::Index::ClipDistances4567 ? 1 : 0) + element);
- used_clip_distances.at(clip_index) = true;
- }
+ MarkAttributeUsage(index, element);
used_output_attributes.insert(index);
-
return MakeNode<AbufNode>(index, static_cast<u32>(element), std::move(buffer));
}
@@ -452,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 dde036b40..80fc9b82c 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{};