|
|
|
@ -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;
|
|
|
|
|