gl_shader_decompiler: Abstract generic attribute operations

This commit is contained in:
ReinUsesLisp 2019-04-30 00:18:28 -03:00
parent bd81a03d9d
commit b7d412c99b

View file

@ -134,6 +134,19 @@ bool IsPrecise(Node node) {
return false; return false;
} }
constexpr bool IsGenericAttribute(Attribute::Index index) {
return index >= Attribute::Index::Attribute_0 && index <= Attribute::Index::Attribute_31;
}
constexpr Attribute::Index ToGenericAttribute(u32 value) {
return static_cast<Attribute::Index>(value + static_cast<u32>(Attribute::Index::Attribute_0));
}
u32 GetGenericAttributeIndex(Attribute::Index index) {
ASSERT(IsGenericAttribute(index));
return static_cast<u32>(index) - static_cast<u32>(Attribute::Index::Attribute_0);
}
class GLSLDecompiler final { class GLSLDecompiler final {
public: public:
explicit GLSLDecompiler(const Device& device, const ShaderIR& ir, ShaderStage stage, explicit GLSLDecompiler(const Device& device, const ShaderIR& ir, ShaderStage stage,
@ -320,9 +333,7 @@ private:
const u32 num_inputs{stage == ShaderStage::Vertex ? GetNumPhysicalAttributes() const u32 num_inputs{stage == ShaderStage::Vertex ? GetNumPhysicalAttributes()
: GetNumPhysicalVaryings()}; : GetNumPhysicalVaryings()};
for (u32 i = 0; i < num_inputs; ++i) { for (u32 i = 0; i < num_inputs; ++i) {
constexpr auto generic_base{static_cast<u32>(Attribute::Index::Attribute_0)}; DeclareInputAttribute(ToGenericAttribute(i));
const auto index{static_cast<Attribute::Index>(generic_base + i)};
DeclareInputAttribute(index);
} }
code.AddNewLine(); code.AddNewLine();
return; return;
@ -330,24 +341,22 @@ private:
const auto& attributes = ir.GetInputAttributes(); const auto& attributes = ir.GetInputAttributes();
for (const auto index : attributes) { for (const auto index : attributes) {
if (index < Attribute::Index::Attribute_0 || index > Attribute::Index::Attribute_31) { if (IsGenericAttribute(index)) {
// Skip when it's not a generic attribute
continue;
}
DeclareInputAttribute(index); DeclareInputAttribute(index);
} }
}
if (!attributes.empty()) if (!attributes.empty())
code.AddNewLine(); code.AddNewLine();
} }
void DeclareInputAttribute(Attribute::Index index) { void DeclareInputAttribute(Attribute::Index index) {
const u32 generic_index{static_cast<u32>(index) - const u32 generic_index{GetGenericAttributeIndex(index)};
static_cast<u32>(Attribute::Index::Attribute_0)};
std::string name{GetInputAttribute(index)}; std::string name{GetInputAttribute(index)};
if (stage == ShaderStage::Geometry) { if (stage == ShaderStage::Geometry) {
name = "gs_" + name + "[]"; name = "gs_" + name + "[]";
} }
std::string suffix; std::string suffix;
if (stage == ShaderStage::Fragment) { if (stage == ShaderStage::Fragment) {
const auto input_mode{header.ps.GetAttributeUse(generic_index)}; const auto input_mode{header.ps.GetAttributeUse(generic_index)};
@ -367,9 +376,7 @@ private:
void DeclareOutputAttributes() { void DeclareOutputAttributes() {
if (ir.HasPhysicalAttributes()) { if (ir.HasPhysicalAttributes()) {
for (u32 i = 0; i < GetNumPhysicalVaryings(); ++i) { for (u32 i = 0; i < GetNumPhysicalVaryings(); ++i) {
constexpr auto generic_base{static_cast<u32>(Attribute::Index::Attribute_0)}; DeclareOutputAttribute(ToGenericAttribute(i));
const auto index{static_cast<Attribute::Index>(generic_base + i)};
DeclareOutputAttribute(index);
} }
code.AddNewLine(); code.AddNewLine();
return; return;
@ -377,20 +384,16 @@ private:
const auto& attributes = ir.GetOutputAttributes(); const auto& attributes = ir.GetOutputAttributes();
for (const auto index : attributes) { for (const auto index : attributes) {
if (index < Attribute::Index::Attribute_0 || index > Attribute::Index::Attribute_31) { if (IsGenericAttribute(index)) {
// Skip when it's not a generic attribute
continue;
}
DeclareOutputAttribute(index); DeclareOutputAttribute(index);
} }
}
if (!attributes.empty()) if (!attributes.empty())
code.AddNewLine(); code.AddNewLine();
} }
void DeclareOutputAttribute(Attribute::Index index) { void DeclareOutputAttribute(Attribute::Index index) {
const auto location{static_cast<u32>(index) - const u32 location{GetGenericAttributeIndex(index) + GENERIC_VARYING_START_LOCATION};
static_cast<u32>(Attribute::Index::Attribute_0) +
GENERIC_VARYING_START_LOCATION};
code.AddLine("layout (location = " + std::to_string(location) + ") out vec4 " + code.AddLine("layout (location = " + std::to_string(location) + ") out vec4 " +
GetOutputAttribute(index) + ';'); GetOutputAttribute(index) + ';');
} }
@ -569,8 +572,7 @@ private:
UNIMPLEMENTED_MSG("Unmanaged FrontFacing element={}", element); UNIMPLEMENTED_MSG("Unmanaged FrontFacing element={}", element);
return "0"; return "0";
default: default:
if (attribute >= Attribute::Index::Attribute_0 && if (IsGenericAttribute(attribute)) {
attribute <= Attribute::Index::Attribute_31) {
return GeometryPass(GetInputAttribute(attribute)) + GetSwizzle(element); return GeometryPass(GetInputAttribute(attribute)) + GetSwizzle(element);
} }
break; break;
@ -873,8 +875,7 @@ private:
case Attribute::Index::ClipDistances4567: case Attribute::Index::ClipDistances4567:
return "gl_ClipDistance[" + std::to_string(abuf->GetElement() + 4) + ']'; return "gl_ClipDistance[" + std::to_string(abuf->GetElement() + 4) + ']';
default: default:
if (attribute >= Attribute::Index::Attribute_0 && if (IsGenericAttribute(attribute)) {
attribute <= Attribute::Index::Attribute_31) {
return GetOutputAttribute(attribute) + GetSwizzle(abuf->GetElement()); return GetOutputAttribute(attribute) + GetSwizzle(abuf->GetElement());
} }
UNIMPLEMENTED_MSG("Unhandled output attribute: {}", UNIMPLEMENTED_MSG("Unhandled output attribute: {}",
@ -1631,15 +1632,11 @@ private:
} }
std::string GetInputAttribute(Attribute::Index attribute) const { std::string GetInputAttribute(Attribute::Index attribute) const {
const auto index{static_cast<u32>(attribute) - return GetDeclarationWithSuffix(GetGenericAttributeIndex(attribute), "input_attr");
static_cast<u32>(Attribute::Index::Attribute_0)};
return GetDeclarationWithSuffix(index, "input_attr");
} }
std::string GetOutputAttribute(Attribute::Index attribute) const { std::string GetOutputAttribute(Attribute::Index attribute) const {
const auto index{static_cast<u32>(attribute) - return GetDeclarationWithSuffix(GetGenericAttributeIndex(attribute), "output_attr");
static_cast<u32>(Attribute::Index::Attribute_0)};
return GetDeclarationWithSuffix(index, "output_attr");
} }
std::string GetConstBuffer(u32 index) const { std::string GetConstBuffer(u32 index) const {