forked from suyu/suyu
Merge pull request #3520 from ReinUsesLisp/legacy-varyings
gl_shader_decompiler: Implement legacy varyings
This commit is contained in:
commit
e6aff11057
4 changed files with 119 additions and 47 deletions
|
@ -82,6 +82,10 @@ union Attribute {
|
||||||
Position = 7,
|
Position = 7,
|
||||||
Attribute_0 = 8,
|
Attribute_0 = 8,
|
||||||
Attribute_31 = 39,
|
Attribute_31 = 39,
|
||||||
|
FrontColor = 40,
|
||||||
|
FrontSecondaryColor = 41,
|
||||||
|
BackColor = 42,
|
||||||
|
BackSecondaryColor = 43,
|
||||||
ClipDistances0123 = 44,
|
ClipDistances0123 = 44,
|
||||||
ClipDistances4567 = 45,
|
ClipDistances4567 = 45,
|
||||||
PointCoord = 46,
|
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, and a tuple of (TessCoord.x, TessCoord.y, TessCoord.z, ~) when inside a Tess Eval
|
||||||
// shader.
|
// shader.
|
||||||
TessCoordInstanceIDVertexID = 47,
|
TessCoordInstanceIDVertexID = 47,
|
||||||
|
TexCoord_0 = 48,
|
||||||
|
TexCoord_7 = 55,
|
||||||
// This attribute contains a tuple of (Unk, Unk, Unk, gl_FrontFacing) when inside a fragment
|
// This attribute contains a tuple of (Unk, Unk, Unk, gl_FrontFacing) when inside a fragment
|
||||||
// shader. It is unknown what the other values contain.
|
// shader. It is unknown what the other values contain.
|
||||||
FrontFacing = 63,
|
FrontFacing = 63,
|
||||||
|
|
|
@ -366,10 +366,19 @@ constexpr bool IsGenericAttribute(Attribute::Index index) {
|
||||||
return index >= Attribute::Index::Attribute_0 && index <= Attribute::Index::Attribute_31;
|
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) {
|
constexpr Attribute::Index ToGenericAttribute(u64 value) {
|
||||||
return static_cast<Attribute::Index>(value + static_cast<u64>(Attribute::Index::Attribute_0));
|
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) {
|
u32 GetGenericAttributeIndex(Attribute::Index index) {
|
||||||
ASSERT(IsGenericAttribute(index));
|
ASSERT(IsGenericAttribute(index));
|
||||||
return static_cast<u32>(index) - static_cast<u32>(Attribute::Index::Attribute_0);
|
return static_cast<u32>(index) - static_cast<u32>(Attribute::Index::Attribute_0);
|
||||||
|
@ -498,7 +507,7 @@ private:
|
||||||
if (!identifier.empty()) {
|
if (!identifier.empty()) {
|
||||||
code.AddLine("// {}", identifier);
|
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");
|
code.AddLine("#extension GL_ARB_separate_shader_objects : enable");
|
||||||
if (device.HasShaderBallot()) {
|
if (device.HasShaderBallot()) {
|
||||||
code.AddLine("#extension GL_ARB_shader_ballot : require");
|
code.AddLine("#extension GL_ARB_shader_ballot : require");
|
||||||
|
@ -561,6 +570,16 @@ private:
|
||||||
if (stage != ShaderType::Fragment) {
|
if (stage != ShaderType::Fragment) {
|
||||||
return;
|
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) {
|
for (u32 rt = 0; rt < Maxwell::NumRenderTargets; ++rt) {
|
||||||
code.AddLine("layout (location = {}) out vec4 frag_color{};", rt, rt);
|
code.AddLine("layout (location = {}) out vec4 frag_color{};", rt, rt);
|
||||||
}
|
}
|
||||||
|
@ -617,12 +636,12 @@ private:
|
||||||
code.AddLine("float gl_PointSize;");
|
code.AddLine("float gl_PointSize;");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ir.UsesInstanceId()) {
|
if (ir.UsesLegacyVaryings()) {
|
||||||
code.AddLine("int gl_InstanceID;");
|
code.AddLine("vec4 gl_TexCoord[8];");
|
||||||
}
|
code.AddLine("vec4 gl_FrontColor;");
|
||||||
|
code.AddLine("vec4 gl_FrontSecondaryColor;");
|
||||||
if (ir.UsesVertexId()) {
|
code.AddLine("vec4 gl_BackColor;");
|
||||||
code.AddLine("int gl_VertexID;");
|
code.AddLine("vec4 gl_BackSecondaryColor;");
|
||||||
}
|
}
|
||||||
|
|
||||||
--code.scope;
|
--code.scope;
|
||||||
|
@ -1128,6 +1147,10 @@ private:
|
||||||
default:
|
default:
|
||||||
UNREACHABLE();
|
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:
|
case Attribute::Index::PointCoord:
|
||||||
switch (element) {
|
switch (element) {
|
||||||
case 0:
|
case 0:
|
||||||
|
@ -1168,6 +1191,12 @@ private:
|
||||||
return {GeometryPass(GetGenericInputAttribute(attribute)) + GetSwizzle(element),
|
return {GeometryPass(GetGenericInputAttribute(attribute)) + GetSwizzle(element),
|
||||||
Type::Float};
|
Type::Float};
|
||||||
}
|
}
|
||||||
|
if (IsLegacyTexCoord(attribute)) {
|
||||||
|
UNIMPLEMENTED_IF(stage == ShaderType::Geometry);
|
||||||
|
return {fmt::format("gl_TexCoord[{}]{}", GetLegacyTexCoordIndex(attribute),
|
||||||
|
GetSwizzle(element)),
|
||||||
|
Type::Float};
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
UNIMPLEMENTED_MSG("Unhandled input attribute: {}", static_cast<u32>(attribute));
|
UNIMPLEMENTED_MSG("Unhandled input attribute: {}", static_cast<u32>(attribute));
|
||||||
|
@ -1206,11 +1235,12 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<Expression> GetOutputAttribute(const AbufNode* abuf) {
|
std::optional<Expression> GetOutputAttribute(const AbufNode* abuf) {
|
||||||
|
const u32 element = abuf->GetElement();
|
||||||
switch (const auto attribute = abuf->GetIndex()) {
|
switch (const auto attribute = abuf->GetIndex()) {
|
||||||
case Attribute::Index::Position:
|
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:
|
case Attribute::Index::LayerViewportPointSize:
|
||||||
switch (abuf->GetElement()) {
|
switch (element) {
|
||||||
case 0:
|
case 0:
|
||||||
UNIMPLEMENTED();
|
UNIMPLEMENTED();
|
||||||
return {};
|
return {};
|
||||||
|
@ -1228,13 +1258,26 @@ private:
|
||||||
return {{"gl_PointSize", Type::Float}};
|
return {{"gl_PointSize", Type::Float}};
|
||||||
}
|
}
|
||||||
return {};
|
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:
|
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:
|
case Attribute::Index::ClipDistances4567:
|
||||||
return {{fmt::format("gl_ClipDistance[{}]", abuf->GetElement() + 4), Type::Float}};
|
return {{fmt::format("gl_ClipDistance[{}]", element + 4), Type::Float}};
|
||||||
default:
|
default:
|
||||||
if (IsGenericAttribute(attribute)) {
|
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));
|
UNIMPLEMENTED_MSG("Unhandled output attribute: {}", static_cast<u32>(attribute));
|
||||||
return {};
|
return {};
|
||||||
|
|
|
@ -96,6 +96,7 @@ Node ShaderIR::GetPredicate(bool immediate) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Node ShaderIR::GetInputAttribute(Attribute::Index index, u64 element, Node buffer) {
|
Node ShaderIR::GetInputAttribute(Attribute::Index index, u64 element, Node buffer) {
|
||||||
|
MarkAttributeUsage(index, element);
|
||||||
used_input_attributes.emplace(index);
|
used_input_attributes.emplace(index);
|
||||||
return MakeNode<AbufNode>(index, static_cast<u32>(element), std::move(buffer));
|
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) {
|
Node ShaderIR::GetOutputAttribute(Attribute::Index index, u64 element, Node buffer) {
|
||||||
if (index == Attribute::Index::LayerViewportPointSize) {
|
MarkAttributeUsage(index, element);
|
||||||
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;
|
|
||||||
}
|
|
||||||
used_output_attributes.insert(index);
|
used_output_attributes.insert(index);
|
||||||
|
|
||||||
return MakeNode<AbufNode>(index, static_cast<u32>(element), std::move(buffer));
|
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));
|
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) {
|
std::size_t ShaderIR::DeclareAmend(Node new_amend) {
|
||||||
const std::size_t id = amend_code.size();
|
const std::size_t id = amend_code.size();
|
||||||
amend_code.push_back(new_amend);
|
amend_code.push_back(new_amend);
|
||||||
|
|
|
@ -137,6 +137,10 @@ public:
|
||||||
return uses_vertex_id;
|
return uses_vertex_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool UsesLegacyVaryings() const {
|
||||||
|
return uses_legacy_varyings;
|
||||||
|
}
|
||||||
|
|
||||||
bool UsesWarps() const {
|
bool UsesWarps() const {
|
||||||
return uses_warps;
|
return uses_warps;
|
||||||
}
|
}
|
||||||
|
@ -343,6 +347,9 @@ private:
|
||||||
/// Inserts a sequence of bits from a node
|
/// Inserts a sequence of bits from a node
|
||||||
Node BitfieldInsert(Node base, Node insert, u32 offset, u32 bits);
|
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,
|
void WriteTexInstructionFloat(NodeBlock& bb, Tegra::Shader::Instruction instr,
|
||||||
const Node4& components);
|
const Node4& components);
|
||||||
|
|
||||||
|
@ -443,6 +450,7 @@ private:
|
||||||
bool uses_physical_attributes{}; // Shader uses AL2P or physical attribute read/writes
|
bool uses_physical_attributes{}; // Shader uses AL2P or physical attribute read/writes
|
||||||
bool uses_instance_id{};
|
bool uses_instance_id{};
|
||||||
bool uses_vertex_id{};
|
bool uses_vertex_id{};
|
||||||
|
bool uses_legacy_varyings{};
|
||||||
bool uses_warps{};
|
bool uses_warps{};
|
||||||
bool uses_indexed_samplers{};
|
bool uses_indexed_samplers{};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue