|
|
|
@ -20,6 +20,7 @@ |
|
|
|
namespace OpenGL::GLShader { |
|
|
|
|
|
|
|
using Tegra::Shader::Attribute; |
|
|
|
using Tegra::Shader::AttributeUse; |
|
|
|
using Tegra::Shader::Header; |
|
|
|
using Tegra::Shader::IpaInterpMode; |
|
|
|
using Tegra::Shader::IpaMode; |
|
|
|
@ -288,34 +289,22 @@ private: |
|
|
|
code.AddNewLine(); |
|
|
|
} |
|
|
|
|
|
|
|
std::string GetInputFlags(const IpaMode& input_mode) { |
|
|
|
const IpaSampleMode sample_mode = input_mode.sampling_mode; |
|
|
|
const IpaInterpMode interp_mode = input_mode.interpolation_mode; |
|
|
|
std::string GetInputFlags(AttributeUse attribute) { |
|
|
|
std::string out; |
|
|
|
|
|
|
|
switch (interp_mode) { |
|
|
|
case IpaInterpMode::Flat: |
|
|
|
switch (attribute) { |
|
|
|
case AttributeUse::Constant: |
|
|
|
out += "flat "; |
|
|
|
break; |
|
|
|
case IpaInterpMode::Linear: |
|
|
|
case AttributeUse::ScreenLinear: |
|
|
|
out += "noperspective "; |
|
|
|
break; |
|
|
|
case IpaInterpMode::Perspective: |
|
|
|
case AttributeUse::Perspective: |
|
|
|
// Default, Smooth
|
|
|
|
break; |
|
|
|
default: |
|
|
|
UNIMPLEMENTED_MSG("Unhandled IPA interp mode: {}", static_cast<u32>(interp_mode)); |
|
|
|
} |
|
|
|
switch (sample_mode) { |
|
|
|
case IpaSampleMode::Centroid: |
|
|
|
// It can be implemented with the "centroid " keyword in GLSL
|
|
|
|
UNIMPLEMENTED_MSG("Unimplemented IPA sampler mode centroid"); |
|
|
|
break; |
|
|
|
case IpaSampleMode::Default: |
|
|
|
// Default, n/a
|
|
|
|
break; |
|
|
|
default: |
|
|
|
UNIMPLEMENTED_MSG("Unimplemented IPA sampler mode: {}", static_cast<u32>(sample_mode)); |
|
|
|
LOG_CRITICAL(HW_GPU, "Unused attribute being fetched"); |
|
|
|
UNREACHABLE(); |
|
|
|
} |
|
|
|
return out; |
|
|
|
} |
|
|
|
@ -324,16 +313,11 @@ private: |
|
|
|
const auto& attributes = ir.GetInputAttributes(); |
|
|
|
for (const auto element : attributes) { |
|
|
|
const Attribute::Index index = element.first; |
|
|
|
const IpaMode& input_mode = *element.second.begin(); |
|
|
|
if (index < Attribute::Index::Attribute_0 || index > Attribute::Index::Attribute_31) { |
|
|
|
// Skip when it's not a generic attribute
|
|
|
|
continue; |
|
|
|
} |
|
|
|
|
|
|
|
ASSERT(element.second.size() > 0); |
|
|
|
UNIMPLEMENTED_IF_MSG(element.second.size() > 1, |
|
|
|
"Multiple input flag modes are not supported in GLSL"); |
|
|
|
|
|
|
|
// TODO(bunnei): Use proper number of elements for these
|
|
|
|
u32 idx = static_cast<u32>(index) - static_cast<u32>(Attribute::Index::Attribute_0); |
|
|
|
if (stage != ShaderStage::Vertex) { |
|
|
|
@ -345,8 +329,14 @@ private: |
|
|
|
if (stage == ShaderStage::Geometry) { |
|
|
|
attr = "gs_" + attr + "[]"; |
|
|
|
} |
|
|
|
code.AddLine("layout (location = " + std::to_string(idx) + ") " + |
|
|
|
GetInputFlags(input_mode) + "in vec4 " + attr + ';'); |
|
|
|
std::string suffix; |
|
|
|
if (stage == ShaderStage::Fragment) { |
|
|
|
const auto input_mode = |
|
|
|
header.ps.GetAttributeUse(idx - GENERIC_VARYING_START_LOCATION); |
|
|
|
suffix = GetInputFlags(input_mode); |
|
|
|
} |
|
|
|
code.AddLine("layout (location = " + std::to_string(idx) + ") " + suffix + "in vec4 " + |
|
|
|
attr + ';'); |
|
|
|
} |
|
|
|
if (!attributes.empty()) |
|
|
|
code.AddNewLine(); |
|
|
|
@ -1571,4 +1561,4 @@ ProgramResult Decompile(const ShaderIR& ir, Maxwell::ShaderStage stage, const st |
|
|
|
return {decompiler.GetResult(), decompiler.GetShaderEntries()}; |
|
|
|
} |
|
|
|
|
|
|
|
} // namespace OpenGL::GLShader
|
|
|
|
} // namespace OpenGL::GLShader
|