Use input/output structs for HLSL
This commit is contained in:
parent
45270f618f
commit
02fd8e92ab
152
spirv_hlsl.cpp
152
spirv_hlsl.cpp
@ -20,6 +20,158 @@ using namespace spv;
|
||||
using namespace spirv_cross;
|
||||
using namespace std;
|
||||
|
||||
void CompilerHLSL::emit_header()
|
||||
{
|
||||
auto &execution = get_entry_point();
|
||||
|
||||
for (auto &header : header_lines)
|
||||
statement(header);
|
||||
|
||||
statement("");
|
||||
}
|
||||
|
||||
void CompilerHLSL::emit_interface_block(const SPIRVariable &var, uint32_t &binding_number)
|
||||
{
|
||||
auto &execution = get_entry_point();
|
||||
auto &type = get<SPIRType>(var.basetype);
|
||||
|
||||
const char* binding = "TEXCOORD";
|
||||
if (is_builtin_variable(var) || var.remapped_variable)
|
||||
{
|
||||
binding = "COLOR";
|
||||
}
|
||||
|
||||
add_resource_name(var.self);
|
||||
statement(layout_for_variable(var), variable_decl(var), " : ", binding, binding_number, ";");
|
||||
|
||||
if (!is_builtin_variable(var) && !var.remapped_variable)
|
||||
{
|
||||
++binding_number;
|
||||
}
|
||||
}
|
||||
|
||||
void CompilerHLSL::emit_resources()
|
||||
{
|
||||
auto &execution = get_entry_point();
|
||||
|
||||
// Emit PLS blocks if we have such variables.
|
||||
if (!pls_inputs.empty() || !pls_outputs.empty())
|
||||
emit_pls();
|
||||
|
||||
// Output all basic struct types which are not Block or BufferBlock as these are declared inplace
|
||||
// when such variables are instantiated.
|
||||
for (auto &id : ids)
|
||||
{
|
||||
if (id.get_type() == TypeType)
|
||||
{
|
||||
auto &type = id.get<SPIRType>();
|
||||
if (type.basetype == SPIRType::Struct && type.array.empty() && !type.pointer &&
|
||||
(meta[type.self].decoration.decoration_flags &
|
||||
((1ull << DecorationBlock) | (1ull << DecorationBufferBlock))) == 0)
|
||||
{
|
||||
emit_struct(type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool emitted = false;
|
||||
|
||||
// Output Uniform Constants (values, samplers, images, etc).
|
||||
for (auto &id : ids)
|
||||
{
|
||||
if (id.get_type() == TypeVariable)
|
||||
{
|
||||
auto &var = id.get<SPIRVariable>();
|
||||
auto &type = get<SPIRType>(var.basetype);
|
||||
|
||||
if (var.storage != StorageClassFunction && !is_builtin_variable(var) && !var.remapped_variable &&
|
||||
type.pointer &&
|
||||
(type.storage == StorageClassUniformConstant || type.storage == StorageClassAtomicCounter))
|
||||
{
|
||||
emit_uniform(var);
|
||||
emitted = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (emitted)
|
||||
statement("");
|
||||
emitted = false;
|
||||
|
||||
if (execution.model == ExecutionModelVertex)
|
||||
{
|
||||
statement("struct InputVert");
|
||||
}
|
||||
else
|
||||
{
|
||||
statement("struct InputFrag");
|
||||
}
|
||||
begin_scope();
|
||||
uint32_t binding_number = 0;
|
||||
for (auto &id : ids)
|
||||
{
|
||||
if (id.get_type() == TypeVariable)
|
||||
{
|
||||
auto &var = id.get<SPIRVariable>();
|
||||
auto &type = get<SPIRType>(var.basetype);
|
||||
|
||||
if (var.storage != StorageClassFunction && !var.remapped_variable &&
|
||||
type.pointer && var.storage == StorageClassInput &&
|
||||
interface_variable_exists_in_entry_point(var.self))
|
||||
{
|
||||
emit_interface_block(var, binding_number);
|
||||
emitted = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
end_scope_decl();
|
||||
statement("");
|
||||
|
||||
if (execution.model == ExecutionModelVertex)
|
||||
{
|
||||
statement("struct OutputVert");
|
||||
}
|
||||
else
|
||||
{
|
||||
statement("struct OutputFrag");
|
||||
}
|
||||
begin_scope();
|
||||
binding_number = 0;
|
||||
for (auto &id : ids)
|
||||
{
|
||||
if (id.get_type() == TypeVariable)
|
||||
{
|
||||
auto &var = id.get<SPIRVariable>();
|
||||
auto &type = get<SPIRType>(var.basetype);
|
||||
|
||||
if (var.storage != StorageClassFunction && !var.remapped_variable &&
|
||||
type.pointer && var.storage == StorageClassOutput &&
|
||||
interface_variable_exists_in_entry_point(var.self))
|
||||
{
|
||||
emit_interface_block(var, binding_number);
|
||||
emitted = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
end_scope_decl();
|
||||
statement("");
|
||||
|
||||
// Global variables.
|
||||
for (auto global : global_variables)
|
||||
{
|
||||
auto &var = get<SPIRVariable>(global);
|
||||
if (var.storage != StorageClassOutput)
|
||||
{
|
||||
add_resource_name(var.self);
|
||||
statement("static ", variable_decl(var), ";");
|
||||
emitted = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (emitted)
|
||||
statement("");
|
||||
}
|
||||
|
||||
string CompilerHLSL::compile()
|
||||
{
|
||||
// Do not deal with ES-isms like precision, older extensions and such.
|
||||
|
@ -33,7 +33,9 @@ namespace spirv_cross
|
||||
std::string compile() override;
|
||||
|
||||
private:
|
||||
|
||||
void emit_header() override;
|
||||
void emit_resources();
|
||||
void emit_interface_block(const SPIRVariable &type, uint32_t &binding_number);
|
||||
};
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user