Add test case for interpolation qualifiers in HLSL.

This commit is contained in:
Hans-Kristian Arntzen 2017-03-20 09:48:43 +01:00
parent 3eed439643
commit b8bda45802
5 changed files with 112 additions and 8 deletions

View File

@ -0,0 +1,50 @@
static float4 gl_Position;
static nointerpolation float vFlat;
static centroid float vCentroid;
static sample float vSample;
static noperspective float vNoperspective;
struct Block
{
nointerpolation float vFlat : TEXCOORD4;
centroid float vCentroid : TEXCOORD5;
sample float vSample : TEXCOORD6;
noperspective float vNoperspective : TEXCOORD7;
};
static Block vout;
struct SPIRV_Cross_Output
{
float4 gl_Position : SV_Position;
nointerpolation float vFlat : TEXCOORD0;
centroid float vCentroid : TEXCOORD1;
sample float vSample : TEXCOORD2;
noperspective float vNoperspective : TEXCOORD3;
};
void vert_main()
{
gl_Position = float4(1.0f, 1.0f, 1.0f, 1.0f);
vFlat = 0.0f;
vCentroid = 1.0f;
vSample = 2.0f;
vNoperspective = 3.0f;
vout.vFlat = 0.0f;
vout.vCentroid = 1.0f;
vout.vSample = 2.0f;
vout.vNoperspective = 3.0f;
}
SPIRV_Cross_Output main(out Block stage_outputvout)
{
vert_main();
stage_outputvout = vout;
SPIRV_Cross_Output stage_output;
stage_output.gl_Position = gl_Position;
stage_output.vFlat = vFlat;
stage_output.vCentroid = vCentroid;
stage_output.vSample = vSample;
stage_output.vNoperspective = vNoperspective;
return stage_output;
}

View File

@ -0,0 +1,27 @@
#version 450
layout(location = 0) flat out float vFlat;
layout(location = 1) centroid out float vCentroid;
layout(location = 2) sample out float vSample;
layout(location = 3) noperspective out float vNoperspective;
layout(location = 4) out Block
{
flat float vFlat;
centroid float vCentroid;
sample float vSample;
noperspective float vNoperspective;
} vout;
void main()
{
gl_Position = vec4(1.0);
vFlat = 0.0;
vCentroid = 1.0;
vSample = 2.0;
vNoperspective = 3.0;
vout.vFlat = 0.0;
vout.vCentroid = 1.0;
vout.vSample = 2.0;
vout.vNoperspective = 3.0;
}

View File

@ -358,7 +358,7 @@ protected:
const char *flags_to_precision_qualifiers_glsl(const SPIRType &type, uint64_t flags);
const char *format_to_glsl(spv::ImageFormat format);
virtual std::string layout_for_member(const SPIRType &type, uint32_t index);
std::string to_interpolation_qualifiers(uint64_t flags);
virtual std::string to_interpolation_qualifiers(uint64_t flags);
uint64_t combined_decoration_for_member(const SPIRType &type, uint32_t index);
std::string layout_for_variable(const SPIRVariable &variable);
std::string to_combined_image_sampler(uint32_t image_id, uint32_t samp_id);

View File

@ -247,6 +247,27 @@ uint32_t CompilerHLSL::type_to_consumed_locations(const SPIRType &type) const
return elements;
}
string CompilerHLSL::to_interpolation_qualifiers(uint64_t flags)
{
string res;
//if (flags & (1ull << DecorationSmooth))
// res += "linear ";
if (flags & (1ull << DecorationFlat))
res += "nointerpolation ";
if (flags & (1ull << DecorationNoPerspective))
res += "noperspective ";
if (flags & (1ull << DecorationCentroid))
res += "centroid ";
if (flags & (1ull << DecorationPatch))
res += "patch "; // Seems to be different in actual HLSL.
if (flags & (1ull << DecorationSample))
res += "sample ";
if (flags & (1ull << DecorationInvariant))
res += "invariant "; // Not supported?
return res;
}
void CompilerHLSL::emit_io_block(const SPIRVariable &var)
{
auto &type = get<SPIRType>(var.basetype);
@ -259,14 +280,17 @@ void CompilerHLSL::emit_io_block(const SPIRVariable &var)
for (uint32_t i = 0; i < uint32_t(type.member_types.size()); i++)
{
string semantic;
if (get_member_decoration_mask(type.self, i) & (1ull << DecorationLocation))
if (has_member_decoration(type.self, i, DecorationLocation))
{
uint32_t location = get_member_decoration(type.self, i, DecorationLocation);
semantic = join(" : TEXCOORD", location);
}
add_member_name(type, i);
statement(member_decl(type, get<SPIRType>(type.member_types[i]), i), semantic, ";");
auto &membertype = get<SPIRType>(type.member_types[i]);
statement(to_interpolation_qualifiers(get_member_decoration_mask(type.self, i)),
variable_decl(membertype, to_member_name(type, i)), semantic, ";");
}
end_scope_decl();
@ -320,13 +344,15 @@ void CompilerHLSL::emit_interface_block_in_struct(const SPIRVariable &var, unord
{
SPIRType newtype = type;
newtype.columns = 1;
statement(variable_decl(newtype, join(name, "_", i)), " : TEXCOORD", binding_number, ";");
statement(to_interpolation_qualifiers(get_decoration_mask(var.self)),
variable_decl(newtype, join(name, "_", i)), " : TEXCOORD", binding_number, ";");
active_locations.insert(binding_number++);
}
}
else
{
statement(variable_decl(type, name), " : TEXCOORD", binding_number, ";");
statement(to_interpolation_qualifiers(get_decoration_mask(var.self)),
variable_decl(type, name), " : TEXCOORD", binding_number, ";");
// Structs and arrays should consume more locations.
uint32_t consumed_locations = type_to_consumed_locations(type);
@ -523,7 +549,7 @@ void CompilerHLSL::emit_resources()
auto &active = var.storage == StorageClassInput ? active_inputs : active_outputs;
for (uint32_t i = 0; i < uint32_t(type.member_types.size()); i++)
{
if (get_member_decoration_mask(type.self, i) & (1ull << DecorationLocation))
if (has_member_decoration(type.self, i, DecorationLocation))
{
uint32_t location = get_member_decoration(type.self, i, DecorationLocation);
active.insert(location);
@ -543,8 +569,8 @@ void CompilerHLSL::emit_resources()
// - Name comparison
// - Variable has a name
// - Fallback: ID
bool has_location_a = (get_decoration_mask(a->self) & (1ull << DecorationLocation)) != 0;
bool has_location_b = (get_decoration_mask(b->self) & (1ull << DecorationLocation)) != 0;
bool has_location_a = has_decoration(a->self, DecorationLocation);
bool has_location_b = has_decoration(b->self, DecorationLocation);
if (has_location_a && has_location_b)
{

View File

@ -68,6 +68,7 @@ private:
void emit_push_constant_block(const SPIRVariable &var) override;
void emit_uniform(const SPIRVariable &var) override;
std::string layout_for_member(const SPIRType &type, uint32_t index) override;
std::string to_interpolation_qualifiers(uint64_t flags) override;
const char *to_storage_qualifiers_glsl(const SPIRVariable &var) override;