mirror of
https://git.suyu.dev/suyu/suyu
synced 2024-11-01 12:57:52 +00:00
gl_shader_decompiler: Declare all possible varyings on physical attribute usage
This commit is contained in:
parent
06b363c9b5
commit
bd81a03d9d
4 changed files with 88 additions and 27 deletions
|
@ -51,6 +51,7 @@ public:
|
|||
static constexpr std::size_t NumCBData = 16;
|
||||
static constexpr std::size_t NumVertexArrays = 32;
|
||||
static constexpr std::size_t NumVertexAttributes = 32;
|
||||
static constexpr std::size_t NumVaryings = 31;
|
||||
static constexpr std::size_t NumTextureSamplers = 32;
|
||||
static constexpr std::size_t NumClipDistances = 8;
|
||||
static constexpr std::size_t MaxShaderProgram = 6;
|
||||
|
|
|
@ -21,9 +21,18 @@ T GetInteger(GLenum pname) {
|
|||
|
||||
Device::Device() {
|
||||
uniform_buffer_alignment = GetInteger<std::size_t>(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT);
|
||||
max_vertex_attributes = GetInteger<u32>(GL_MAX_VERTEX_ATTRIBS);
|
||||
max_varyings = GetInteger<u32>(GL_MAX_VARYING_VECTORS);
|
||||
has_variable_aoffi = TestVariableAoffi();
|
||||
}
|
||||
|
||||
Device::Device(std::nullptr_t) {
|
||||
uniform_buffer_alignment = 0;
|
||||
max_vertex_attributes = 16;
|
||||
max_varyings = 15;
|
||||
has_variable_aoffi = true;
|
||||
}
|
||||
|
||||
bool Device::TestVariableAoffi() {
|
||||
const GLchar* AOFFI_TEST = R"(#version 430 core
|
||||
uniform sampler2D tex;
|
||||
|
|
|
@ -5,17 +5,27 @@
|
|||
#pragma once
|
||||
|
||||
#include <cstddef>
|
||||
#include "common/common_types.h"
|
||||
|
||||
namespace OpenGL {
|
||||
|
||||
class Device {
|
||||
public:
|
||||
Device();
|
||||
explicit Device();
|
||||
explicit Device(std::nullptr_t);
|
||||
|
||||
std::size_t GetUniformBufferAlignment() const {
|
||||
return uniform_buffer_alignment;
|
||||
}
|
||||
|
||||
u32 GetMaxVertexAttributes() const {
|
||||
return max_vertex_attributes;
|
||||
}
|
||||
|
||||
u32 GetMaxVaryings() const {
|
||||
return max_varyings;
|
||||
}
|
||||
|
||||
bool HasVariableAoffi() const {
|
||||
return has_variable_aoffi;
|
||||
}
|
||||
|
@ -24,6 +34,8 @@ private:
|
|||
static bool TestVariableAoffi();
|
||||
|
||||
std::size_t uniform_buffer_alignment{};
|
||||
u32 max_vertex_attributes{};
|
||||
u32 max_varyings{};
|
||||
bool has_variable_aoffi{};
|
||||
};
|
||||
|
||||
|
|
|
@ -316,55 +316,85 @@ private:
|
|||
}
|
||||
|
||||
void DeclareInputAttributes() {
|
||||
if (ir.HasPhysicalAttributes()) {
|
||||
const u32 num_inputs{stage == ShaderStage::Vertex ? GetNumPhysicalAttributes()
|
||||
: GetNumPhysicalVaryings()};
|
||||
for (u32 i = 0; i < num_inputs; ++i) {
|
||||
constexpr auto generic_base{static_cast<u32>(Attribute::Index::Attribute_0)};
|
||||
const auto index{static_cast<Attribute::Index>(generic_base + i)};
|
||||
DeclareInputAttribute(index);
|
||||
}
|
||||
code.AddNewLine();
|
||||
return;
|
||||
}
|
||||
|
||||
const auto& attributes = ir.GetInputAttributes();
|
||||
for (const auto index : attributes) {
|
||||
if (index < Attribute::Index::Attribute_0 || index > Attribute::Index::Attribute_31) {
|
||||
// Skip when it's not a generic attribute
|
||||
continue;
|
||||
}
|
||||
|
||||
// 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) {
|
||||
// If inputs are varyings, add an offset
|
||||
idx += GENERIC_VARYING_START_LOCATION;
|
||||
}
|
||||
|
||||
std::string attr = GetInputAttribute(index);
|
||||
if (stage == ShaderStage::Geometry) {
|
||||
attr = "gs_" + 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 + ';');
|
||||
DeclareInputAttribute(index);
|
||||
}
|
||||
if (!attributes.empty())
|
||||
code.AddNewLine();
|
||||
}
|
||||
|
||||
void DeclareInputAttribute(Attribute::Index index) {
|
||||
const u32 generic_index{static_cast<u32>(index) -
|
||||
static_cast<u32>(Attribute::Index::Attribute_0)};
|
||||
|
||||
std::string name{GetInputAttribute(index)};
|
||||
if (stage == ShaderStage::Geometry) {
|
||||
name = "gs_" + name + "[]";
|
||||
}
|
||||
std::string suffix;
|
||||
if (stage == ShaderStage::Fragment) {
|
||||
const auto input_mode{header.ps.GetAttributeUse(generic_index)};
|
||||
suffix = GetInputFlags(input_mode);
|
||||
}
|
||||
|
||||
u32 location = generic_index;
|
||||
if (stage != ShaderStage::Vertex) {
|
||||
// If inputs are varyings, add an offset
|
||||
location += GENERIC_VARYING_START_LOCATION;
|
||||
}
|
||||
|
||||
code.AddLine("layout (location = " + std::to_string(location) + ") " + suffix + "in vec4 " +
|
||||
name + ';');
|
||||
}
|
||||
|
||||
void DeclareOutputAttributes() {
|
||||
if (ir.HasPhysicalAttributes()) {
|
||||
for (u32 i = 0; i < GetNumPhysicalVaryings(); ++i) {
|
||||
constexpr auto generic_base{static_cast<u32>(Attribute::Index::Attribute_0)};
|
||||
const auto index{static_cast<Attribute::Index>(generic_base + i)};
|
||||
DeclareOutputAttribute(index);
|
||||
}
|
||||
code.AddNewLine();
|
||||
return;
|
||||
}
|
||||
|
||||
const auto& attributes = ir.GetOutputAttributes();
|
||||
for (const auto index : attributes) {
|
||||
if (index < Attribute::Index::Attribute_0 || index > Attribute::Index::Attribute_31) {
|
||||
// Skip when it's not a generic attribute
|
||||
continue;
|
||||
}
|
||||
// TODO(bunnei): Use proper number of elements for these
|
||||
const auto idx = static_cast<u32>(index) -
|
||||
static_cast<u32>(Attribute::Index::Attribute_0) +
|
||||
GENERIC_VARYING_START_LOCATION;
|
||||
code.AddLine("layout (location = " + std::to_string(idx) + ") out vec4 " +
|
||||
GetOutputAttribute(index) + ';');
|
||||
DeclareOutputAttribute(index);
|
||||
}
|
||||
if (!attributes.empty())
|
||||
code.AddNewLine();
|
||||
}
|
||||
|
||||
void DeclareOutputAttribute(Attribute::Index index) {
|
||||
const auto location{static_cast<u32>(index) -
|
||||
static_cast<u32>(Attribute::Index::Attribute_0) +
|
||||
GENERIC_VARYING_START_LOCATION};
|
||||
code.AddLine("layout (location = " + std::to_string(location) + ") out vec4 " +
|
||||
GetOutputAttribute(index) + ';');
|
||||
}
|
||||
|
||||
void DeclareConstantBuffers() {
|
||||
for (const auto& entry : ir.GetConstantBuffers()) {
|
||||
const auto [index, size] = entry;
|
||||
|
@ -1650,6 +1680,15 @@ private:
|
|||
return name + '_' + std::to_string(index) + '_' + suffix;
|
||||
}
|
||||
|
||||
u32 GetNumPhysicalAttributes() const {
|
||||
return std::min<u32>(device.GetMaxVertexAttributes(), Maxwell::NumVertexAttributes);
|
||||
}
|
||||
|
||||
u32 GetNumPhysicalVaryings() const {
|
||||
return std::min<u32>(device.GetMaxVaryings() - GENERIC_VARYING_START_LOCATION,
|
||||
Maxwell::NumVaryings);
|
||||
}
|
||||
|
||||
const Device& device;
|
||||
const ShaderIR& ir;
|
||||
const ShaderStage stage;
|
||||
|
|
Loading…
Reference in a new issue