Cleanups for HLSL vertex attribute remap.

Add CLI support as well.
This commit is contained in:
Hans-Kristian Arntzen 2017-11-13 09:46:45 +01:00
parent 7cf44099c9
commit 4f88f9750f
4 changed files with 52 additions and 40 deletions

View File

@ -465,6 +465,7 @@ struct CLIArguments
vector<string> extensions;
vector<VariableTypeRemap> variable_type_remaps;
vector<InterfaceVariableRename> interface_variable_renames;
vector<HLSLVertexAttributeRemap> hlsl_attr_remap;
string entry;
uint32_t iterations = 1;
@ -493,6 +494,7 @@ static void print_help()
"[--flatten-multidimensional-arrays] [--no-420pack-extension] "
"[--remap-variable-type <variable_name> <new_variable_type>] "
"[--rename-interface-variable <in|out> <location> <new_variable_name>] "
"[--set-hlsl-vertex-input-semantic <location> <semantic> "
"\n");
}
@ -648,11 +650,18 @@ static int main_inner(int argc, char *argv[])
cbs.add("--extension", [&args](CLIParser &parser) { args.extensions.push_back(parser.next_string()); });
cbs.add("--entry", [&args](CLIParser &parser) { args.entry = parser.next_string(); });
cbs.add("--separate-shader-objects", [&args](CLIParser &) { args.sso = true; });
cbs.add("--set-hlsl-vertex-input-semantic", [&args](CLIParser &parser) {
HLSLVertexAttributeRemap remap;
remap.location = parser.next_uint();
remap.semantic = parser.next_string();
args.hlsl_attr_remap.push_back(move(remap));
});
cbs.add("--remap", [&args](CLIParser &parser) {
string src = parser.next_string();
string dst = parser.next_string();
uint32_t components = parser.next_uint();
args.remaps.push_back({ move(src), move(dst), components });
string src = parser.next_string();
string dst = parser.next_string();
uint32_t components = parser.next_uint();
args.remaps.push_back({ move(src), move(dst), components });
});
cbs.add("--remap-variable-type", [&args](CLIParser &parser) {
@ -872,7 +881,12 @@ static int main_inner(int argc, char *argv[])
string glsl;
for (uint32_t i = 0; i < args.iterations; i++)
glsl = compiler->compile();
{
if (args.hlsl)
glsl = static_cast<CompilerHLSL *>(compiler.get())->compile(move(args.hlsl_attr_remap));
else
glsl = compiler->compile();
}
if (args.output)
write_string_to_file(args.output, glsl.c_str());

View File

@ -5,10 +5,10 @@ static float3 pos;
struct SPIRV_Cross_Input
{
float3 pos : TEXCOORD0;
float4 m_0 : TEXCOORD1;
float4 m_1 : TEXCOORD2;
float4 m_2 : TEXCOORD3;
float4 m_3 : TEXCOORD4;
float4 m_0 : TEXCOORD1_0;
float4 m_1 : TEXCOORD1_1;
float4 m_2 : TEXCOORD1_2;
float4 m_3 : TEXCOORD1_3;
};
struct SPIRV_Cross_Output

View File

@ -636,12 +636,12 @@ void CompilerHLSL::emit_interface_block_in_struct(const SPIRVariable &var, unord
auto &type = get<SPIRType>(var.basetype);
string binding;
bool use_binding_number = true;
bool use_location_number = true;
bool legacy = options.shader_model <= 30;
if (execution.model == ExecutionModelFragment && var.storage == StorageClassOutput)
{
binding = join(legacy ? "COLOR" : "SV_Target", get_decoration(var.self, DecorationLocation));
use_binding_number = false;
use_location_number = false;
}
const auto get_vacant_location = [&]() -> uint32_t {
@ -655,34 +655,32 @@ void CompilerHLSL::emit_interface_block_in_struct(const SPIRVariable &var, unord
auto &m = meta[var.self].decoration;
auto name = to_name(var.self);
if (use_binding_number)
if (use_location_number)
{
uint32_t binding_number;
uint32_t location_number;
// If an explicit location exists, use it with TEXCOORD[N] semantic.
// Otherwise, pick a vacant location.
if (m.decoration_flags & (1ull << DecorationLocation))
binding_number = m.location;
location_number = m.location;
else
binding_number = get_vacant_location();
location_number = get_vacant_location();
// Allow semantic remap if specified.
string semantic = "TEXCOORD";
uint32_t semantic_index = binding_number;
string semantic;
if (vertex_attributes.size())
for (auto &attribute : remap_vertex_attributes)
{
for (auto &attribute : vertex_attributes)
if (attribute.location == location_number)
{
if (attribute.binding == binding_number)
{
semantic = attribute.semantic;
semantic_index = attribute.semantic_index;
break;
}
semantic = attribute.semantic;
break;
}
}
if (semantic.empty())
semantic = join("TEXCOORD", location_number);
if (need_matrix_unroll && type.columns > 1)
{
if (!type.array.empty())
@ -694,19 +692,19 @@ void CompilerHLSL::emit_interface_block_in_struct(const SPIRVariable &var, unord
SPIRType newtype = type;
newtype.columns = 1;
statement(to_interpolation_qualifiers(get_decoration_mask(var.self)),
variable_decl(newtype, join(name, "_", i)), " : ", semantic, semantic_index, binding_number, ";");
active_locations.insert(binding_number++);
variable_decl(newtype, join(name, "_", i)), " : ", semantic, "_", i, ";");
active_locations.insert(location_number++);
}
}
else
{
statement(to_interpolation_qualifiers(get_decoration_mask(var.self)), variable_decl(type, name),
" : ", semantic, semantic_index, binding_number, ";");
" : ", semantic, ";");
// Structs and arrays should consume more locations.
uint32_t consumed_locations = type_to_consumed_locations(type);
for (uint32_t i = 0; i < consumed_locations; i++)
active_locations.insert(binding_number + i);
active_locations.insert(location_number + i);
}
}
else
@ -3161,13 +3159,9 @@ void CompilerHLSL::require_texture_query_variant(const SPIRType &type)
}
}
string CompilerHLSL::compile(std::vector<HLSLVertexAttr> *p_vertex_attributes)
string CompilerHLSL::compile(std::vector<HLSLVertexAttributeRemap> vertex_attributes)
{
if (p_vertex_attributes)
{
vertex_attributes = *p_vertex_attributes;
}
remap_vertex_attributes = move(vertex_attributes);
return compile();
}

View File

@ -23,11 +23,11 @@
namespace spirv_cross
{
struct HLSLVertexAttr
// Interface which remaps vertex inputs to a fixed semantic name to make linking easier.
struct HLSLVertexAttributeRemap
{
uint32_t binding;
uint32_t location;
std::string semantic;
uint32_t semantic_index;
};
class CompilerHLSL : public CompilerGLSL
@ -61,7 +61,11 @@ public:
options = opts;
}
std::string compile(std::vector<HLSLVertexAttr> *p_vertex_attributes);
// Compiles and remaps vertex attributes at specific locations to a fixed semantic.
// The default is TEXCOORD# where # denotes location.
// Matrices are unrolled to vectors with notation ${SEMANTIC}_#, where # denotes row.
// $SEMANTIC is either TEXCOORD# or a semantic name specified here.
std::string compile(std::vector<HLSLVertexAttributeRemap> vertex_attributes);
std::string compile() override;
private:
@ -141,7 +145,7 @@ private:
void emit_builtin_variables();
bool require_output = false;
bool require_input = false;
std::vector<HLSLVertexAttr> vertex_attributes;
std::vector<HLSLVertexAttributeRemap> remap_vertex_attributes;
uint32_t type_to_consumed_locations(const SPIRType &type) const;