CompilerMSL fix variables used in interface blocks aren't resolved correctly (#179).

This commit is contained in:
Bill Hollings 2017-05-22 21:41:19 -04:00
parent a71c547b30
commit c1b8154f2c
5 changed files with 93 additions and 4 deletions

View File

@ -0,0 +1,32 @@
#include <metal_stdlib>
#include <simd/simd.h>
using namespace metal;
struct Transform
{
float4x4 transform;
};
struct main0_in
{
float3 position [[attribute(0)]];
float4 color [[attribute(1)]];
};
struct main0_out
{
float4 VertexOut_color [[user(locn0)]];
float4 gl_Position [[position]];
float gl_PointSize [[point_size]];
float gl_ClipDistance[1] /* [[clip_distance]] built-in not yet supported under Metal. */;
};
vertex main0_out main0(main0_in in [[stage_in]], constant Transform& block [[buffer(0)]])
{
main0_out out = {};
out.gl_Position = block.transform * float4(in.position, 1.0);
out.VertexOut_color = in.color;
return out;
}

View File

@ -0,0 +1,20 @@
#version 330
uniform Transform
{
mat4 transform;
} block;
in vec3 position;
in vec4 color;
out VertexOut
{
vec4 color;
} outputs;
void main()
{
gl_Position = block.transform*vec4(position, 1.0);
outputs.color = color;
}

View File

@ -923,8 +923,34 @@ const std::string &Compiler::get_member_name(uint32_t id, uint32_t index) const
void Compiler::set_member_qualified_name(uint32_t id, uint32_t index, const std::string &name)
{
meta.at(id).members.resize(max(meta[id].members.size(), size_t(index) + 1));
meta.at(id).members[index].qualified_alias = name;
// Tunnel through pointers to get to the base type
auto *p_type = &get<SPIRType>(id);
while (p_type->pointer)
p_type = &get<SPIRType>(p_type->parent_type);
uint32_t type_id = p_type->self;
meta.at(type_id).members.resize(max(meta[type_id].members.size(), size_t(index) + 1));
meta.at(type_id).members[index].qualified_alias = name;
}
const std::string &Compiler::get_member_qualified_name(uint32_t id, uint32_t index) const
{
// Tunnel through pointers to get to the base type
auto *p_type = &get<SPIRType>(id);
while (p_type->pointer)
p_type = &get<SPIRType>(p_type->parent_type);
uint32_t type_id = p_type->self;
auto &m = meta.at(type_id);
if (index >= m.members.size())
{
static string empty;
return empty;
}
return m.members[index].qualified_alias;
}
uint32_t Compiler::get_member_decoration(uint32_t id, uint32_t index, Decoration decoration) const

View File

@ -170,6 +170,10 @@ public:
// Sets the member identifier for OpTypeStruct ID, member number "index".
void set_member_name(uint32_t id, uint32_t index, const std::string &name);
// Returns the qualified member identifier for OpTypeStruct ID, member number "index",
// or an empty string if no qualified alias exists
const std::string &get_member_qualified_name(uint32_t id, uint32_t index) const;
// Sets the qualified member identifier for OpTypeStruct ID, member number "index".
void set_member_qualified_name(uint32_t id, uint32_t index, const std::string &name);

View File

@ -3483,8 +3483,15 @@ string CompilerGLSL::access_chain_internal(uint32_t base, const uint32_t *indice
}
else
{
expr += ".";
expr += to_member_name(*type, index);
// If the member has a qualified name, use it as the entire chain
string qual_mbr_name = get_member_qualified_name(type->self, index);
if (!qual_mbr_name.empty())
expr = qual_mbr_name;
else
{
expr += ".";
expr += to_member_name(*type, index);
}
}
if (member_is_packed_type(*type, index))