mirror of
https://github.com/yuzu-mirror/yuzu
synced 2024-12-24 15:33:06 +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 NumCBData = 16;
|
||||||
static constexpr std::size_t NumVertexArrays = 32;
|
static constexpr std::size_t NumVertexArrays = 32;
|
||||||
static constexpr std::size_t NumVertexAttributes = 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 NumTextureSamplers = 32;
|
||||||
static constexpr std::size_t NumClipDistances = 8;
|
static constexpr std::size_t NumClipDistances = 8;
|
||||||
static constexpr std::size_t MaxShaderProgram = 6;
|
static constexpr std::size_t MaxShaderProgram = 6;
|
||||||
|
|
|
@ -21,9 +21,18 @@ T GetInteger(GLenum pname) {
|
||||||
|
|
||||||
Device::Device() {
|
Device::Device() {
|
||||||
uniform_buffer_alignment = GetInteger<std::size_t>(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT);
|
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();
|
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() {
|
bool Device::TestVariableAoffi() {
|
||||||
const GLchar* AOFFI_TEST = R"(#version 430 core
|
const GLchar* AOFFI_TEST = R"(#version 430 core
|
||||||
uniform sampler2D tex;
|
uniform sampler2D tex;
|
||||||
|
|
|
@ -5,17 +5,27 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
|
#include "common/common_types.h"
|
||||||
|
|
||||||
namespace OpenGL {
|
namespace OpenGL {
|
||||||
|
|
||||||
class Device {
|
class Device {
|
||||||
public:
|
public:
|
||||||
Device();
|
explicit Device();
|
||||||
|
explicit Device(std::nullptr_t);
|
||||||
|
|
||||||
std::size_t GetUniformBufferAlignment() const {
|
std::size_t GetUniformBufferAlignment() const {
|
||||||
return uniform_buffer_alignment;
|
return uniform_buffer_alignment;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u32 GetMaxVertexAttributes() const {
|
||||||
|
return max_vertex_attributes;
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 GetMaxVaryings() const {
|
||||||
|
return max_varyings;
|
||||||
|
}
|
||||||
|
|
||||||
bool HasVariableAoffi() const {
|
bool HasVariableAoffi() const {
|
||||||
return has_variable_aoffi;
|
return has_variable_aoffi;
|
||||||
}
|
}
|
||||||
|
@ -24,6 +34,8 @@ private:
|
||||||
static bool TestVariableAoffi();
|
static bool TestVariableAoffi();
|
||||||
|
|
||||||
std::size_t uniform_buffer_alignment{};
|
std::size_t uniform_buffer_alignment{};
|
||||||
|
u32 max_vertex_attributes{};
|
||||||
|
u32 max_varyings{};
|
||||||
bool has_variable_aoffi{};
|
bool has_variable_aoffi{};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -316,55 +316,85 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
void DeclareInputAttributes() {
|
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();
|
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 (index < Attribute::Index::Attribute_0 || index > Attribute::Index::Attribute_31) {
|
||||||
// Skip when it's not a generic attribute
|
// Skip when it's not a generic attribute
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
DeclareInputAttribute(index);
|
||||||
// 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 + ';');
|
|
||||||
}
|
}
|
||||||
if (!attributes.empty())
|
if (!attributes.empty())
|
||||||
code.AddNewLine();
|
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() {
|
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();
|
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 (index < Attribute::Index::Attribute_0 || index > Attribute::Index::Attribute_31) {
|
||||||
// Skip when it's not a generic attribute
|
// Skip when it's not a generic attribute
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// TODO(bunnei): Use proper number of elements for these
|
DeclareOutputAttribute(index);
|
||||||
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) + ';');
|
|
||||||
}
|
}
|
||||||
if (!attributes.empty())
|
if (!attributes.empty())
|
||||||
code.AddNewLine();
|
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() {
|
void DeclareConstantBuffers() {
|
||||||
for (const auto& entry : ir.GetConstantBuffers()) {
|
for (const auto& entry : ir.GetConstantBuffers()) {
|
||||||
const auto [index, size] = entry;
|
const auto [index, size] = entry;
|
||||||
|
@ -1650,6 +1680,15 @@ private:
|
||||||
return name + '_' + std::to_string(index) + '_' + suffix;
|
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 Device& device;
|
||||||
const ShaderIR& ir;
|
const ShaderIR& ir;
|
||||||
const ShaderStage stage;
|
const ShaderStage stage;
|
||||||
|
|
Loading…
Reference in a new issue