mirror of
https://github.com/bkaradzic/bgfx.git
synced 2026-02-17 20:52:36 +01:00
Updated spirv-cross.
This commit is contained in:
4
3rdparty/spirv-cross/main.cpp
vendored
4
3rdparty/spirv-cross/main.cpp
vendored
@@ -1348,6 +1348,10 @@ static string compile_iteration(const CLIArguments &args, std::vector<uint32_t>
|
|||||||
build_dummy_sampler = true;
|
build_dummy_sampler = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If we're explicitly renaming, we probably want that name to be output.
|
||||||
|
if (!args.entry_point_rename.empty())
|
||||||
|
hlsl_opts.use_entry_point_name = true;
|
||||||
|
|
||||||
hlsl_opts.support_nonzero_base_vertex_base_instance = args.hlsl_support_nonzero_base;
|
hlsl_opts.support_nonzero_base_vertex_base_instance = args.hlsl_support_nonzero_base;
|
||||||
hlsl_opts.force_storage_buffer_as_uav = args.hlsl_force_storage_buffer_as_uav;
|
hlsl_opts.force_storage_buffer_as_uav = args.hlsl_force_storage_buffer_as_uav;
|
||||||
hlsl_opts.nonwritable_uav_texture_as_srv = args.hlsl_nonwritable_uav_texture_as_srv;
|
hlsl_opts.nonwritable_uav_texture_as_srv = args.hlsl_nonwritable_uav_texture_as_srv;
|
||||||
|
|||||||
5
3rdparty/spirv-cross/spirv_cfg.hpp
vendored
5
3rdparty/spirv-cross/spirv_cfg.hpp
vendored
@@ -59,6 +59,11 @@ public:
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool is_reachable(uint32_t block) const
|
||||||
|
{
|
||||||
|
return visit_order.count(block) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t get_visit_order(uint32_t block) const
|
uint32_t get_visit_order(uint32_t block) const
|
||||||
{
|
{
|
||||||
auto itr = visit_order.find(block);
|
auto itr = visit_order.find(block);
|
||||||
|
|||||||
38
3rdparty/spirv-cross/spirv_cross.cpp
vendored
38
3rdparty/spirv-cross/spirv_cross.cpp
vendored
@@ -3744,6 +3744,7 @@ void Compiler::analyze_variable_scope(SPIRFunction &entry, AnalyzeVariableScopeA
|
|||||||
DominatorBuilder builder(cfg);
|
DominatorBuilder builder(cfg);
|
||||||
auto &blocks = var.second;
|
auto &blocks = var.second;
|
||||||
auto &type = expression_type(var.first);
|
auto &type = expression_type(var.first);
|
||||||
|
BlockID potential_continue_block = 0;
|
||||||
|
|
||||||
// Figure out which block is dominating all accesses of those variables.
|
// Figure out which block is dominating all accesses of those variables.
|
||||||
for (auto &block : blocks)
|
for (auto &block : blocks)
|
||||||
@@ -3765,14 +3766,13 @@ void Compiler::analyze_variable_scope(SPIRFunction &entry, AnalyzeVariableScopeA
|
|||||||
{
|
{
|
||||||
// The variable is used in multiple continue blocks, this is not a loop
|
// The variable is used in multiple continue blocks, this is not a loop
|
||||||
// candidate, signal that by setting block to -1u.
|
// candidate, signal that by setting block to -1u.
|
||||||
auto &potential = potential_loop_variables[var.first];
|
if (potential_continue_block == 0)
|
||||||
|
potential_continue_block = block;
|
||||||
if (potential == 0)
|
|
||||||
potential = block;
|
|
||||||
else
|
else
|
||||||
potential = ~(0u);
|
potential_continue_block = ~(0u);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
builder.add_block(block);
|
builder.add_block(block);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3781,6 +3781,34 @@ void Compiler::analyze_variable_scope(SPIRFunction &entry, AnalyzeVariableScopeA
|
|||||||
// Add it to a per-block list of variables.
|
// Add it to a per-block list of variables.
|
||||||
BlockID dominating_block = builder.get_dominator();
|
BlockID dominating_block = builder.get_dominator();
|
||||||
|
|
||||||
|
if (dominating_block && potential_continue_block != 0 && potential_continue_block != ~0u)
|
||||||
|
{
|
||||||
|
auto &inner_block = get<SPIRBlock>(dominating_block);
|
||||||
|
|
||||||
|
BlockID merge_candidate = 0;
|
||||||
|
|
||||||
|
// Analyze the dominator. If it lives in a different loop scope than the candidate continue
|
||||||
|
// block, reject the loop variable candidate.
|
||||||
|
if (inner_block.merge == SPIRBlock::MergeLoop)
|
||||||
|
merge_candidate = inner_block.merge_block;
|
||||||
|
else if (inner_block.loop_dominator != SPIRBlock::NoDominator)
|
||||||
|
merge_candidate = get<SPIRBlock>(inner_block.loop_dominator).merge_block;
|
||||||
|
|
||||||
|
if (merge_candidate != 0 && cfg.is_reachable(merge_candidate))
|
||||||
|
{
|
||||||
|
// If the merge block has a higher post-visit order, we know that continue candidate
|
||||||
|
// cannot reach the merge block, and we have two separate scopes.
|
||||||
|
if (!cfg.is_reachable(potential_continue_block) ||
|
||||||
|
cfg.get_visit_order(merge_candidate) > cfg.get_visit_order(potential_continue_block))
|
||||||
|
{
|
||||||
|
potential_continue_block = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (potential_continue_block != 0 && potential_continue_block != ~0u)
|
||||||
|
potential_loop_variables[var.first] = potential_continue_block;
|
||||||
|
|
||||||
// For variables whose dominating block is inside a loop, there is a risk that these variables
|
// For variables whose dominating block is inside a loop, there is a risk that these variables
|
||||||
// actually need to be preserved across loop iterations. We can express this by adding
|
// actually need to be preserved across loop iterations. We can express this by adding
|
||||||
// a "read" access to the loop header.
|
// a "read" access to the loop header.
|
||||||
|
|||||||
36
3rdparty/spirv-cross/spirv_glsl.cpp
vendored
36
3rdparty/spirv-cross/spirv_glsl.cpp
vendored
@@ -327,6 +327,8 @@ void CompilerGLSL::reset(uint32_t iteration_count)
|
|||||||
// Ensure that we declare phi-variable copies even if the original declaration isn't deferred
|
// Ensure that we declare phi-variable copies even if the original declaration isn't deferred
|
||||||
flushed_phi_variables.clear();
|
flushed_phi_variables.clear();
|
||||||
|
|
||||||
|
current_emitting_switch_stack.clear();
|
||||||
|
|
||||||
reset_name_caches();
|
reset_name_caches();
|
||||||
|
|
||||||
ir.for_each_typed_id<SPIRFunction>([&](uint32_t, SPIRFunction &func) {
|
ir.for_each_typed_id<SPIRFunction>([&](uint32_t, SPIRFunction &func) {
|
||||||
@@ -14895,21 +14897,32 @@ void CompilerGLSL::branch(BlockID from, BlockID to)
|
|||||||
// - Break merge target all at once ...
|
// - Break merge target all at once ...
|
||||||
|
|
||||||
// Very dirty workaround.
|
// Very dirty workaround.
|
||||||
// Switch constructs are able to break, but they cannot break out of a loop at the same time.
|
// Switch constructs are able to break, but they cannot break out of a loop at the same time,
|
||||||
|
// yet SPIR-V allows it.
|
||||||
// Only sensible solution is to make a ladder variable, which we declare at the top of the switch block,
|
// Only sensible solution is to make a ladder variable, which we declare at the top of the switch block,
|
||||||
// write to the ladder here, and defer the break.
|
// write to the ladder here, and defer the break.
|
||||||
// The loop we're breaking out of must dominate the switch block, or there is no ladder breaking case.
|
// The loop we're breaking out of must dominate the switch block, or there is no ladder breaking case.
|
||||||
if (current_emitting_switch && is_loop_break(to) &&
|
if (is_loop_break(to))
|
||||||
current_emitting_switch->loop_dominator != BlockID(SPIRBlock::NoDominator) &&
|
|
||||||
get<SPIRBlock>(current_emitting_switch->loop_dominator).merge_block == to)
|
|
||||||
{
|
{
|
||||||
if (!current_emitting_switch->need_ladder_break)
|
for (size_t n = current_emitting_switch_stack.size(); n; n--)
|
||||||
{
|
{
|
||||||
force_recompile();
|
auto *current_emitting_switch = current_emitting_switch_stack[n - 1];
|
||||||
current_emitting_switch->need_ladder_break = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
statement("_", current_emitting_switch->self, "_ladder_break = true;");
|
if (current_emitting_switch &&
|
||||||
|
current_emitting_switch->loop_dominator != BlockID(SPIRBlock::NoDominator) &&
|
||||||
|
get<SPIRBlock>(current_emitting_switch->loop_dominator).merge_block == to)
|
||||||
|
{
|
||||||
|
if (!current_emitting_switch->need_ladder_break)
|
||||||
|
{
|
||||||
|
force_recompile();
|
||||||
|
current_emitting_switch->need_ladder_break = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
statement("_", current_emitting_switch->self, "_ladder_break = true;");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
statement("break;");
|
statement("break;");
|
||||||
}
|
}
|
||||||
@@ -15594,8 +15607,7 @@ void CompilerGLSL::emit_block_chain(SPIRBlock &block)
|
|||||||
else if (type.basetype == SPIRType::Short)
|
else if (type.basetype == SPIRType::Short)
|
||||||
label_suffix = backend.int16_t_literal_suffix;
|
label_suffix = backend.int16_t_literal_suffix;
|
||||||
|
|
||||||
SPIRBlock *old_emitting_switch = current_emitting_switch;
|
current_emitting_switch_stack.push_back(&block);
|
||||||
current_emitting_switch = █
|
|
||||||
|
|
||||||
if (block.need_ladder_break)
|
if (block.need_ladder_break)
|
||||||
statement("bool _", block.self, "_ladder_break = false;");
|
statement("bool _", block.self, "_ladder_break = false;");
|
||||||
@@ -15880,7 +15892,7 @@ void CompilerGLSL::emit_block_chain(SPIRBlock &block)
|
|||||||
end_scope();
|
end_scope();
|
||||||
}
|
}
|
||||||
|
|
||||||
current_emitting_switch = old_emitting_switch;
|
current_emitting_switch_stack.pop_back();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
2
3rdparty/spirv-cross/spirv_glsl.hpp
vendored
2
3rdparty/spirv-cross/spirv_glsl.hpp
vendored
@@ -364,7 +364,7 @@ protected:
|
|||||||
virtual void emit_function_prototype(SPIRFunction &func, const Bitset &return_flags);
|
virtual void emit_function_prototype(SPIRFunction &func, const Bitset &return_flags);
|
||||||
|
|
||||||
SPIRBlock *current_emitting_block = nullptr;
|
SPIRBlock *current_emitting_block = nullptr;
|
||||||
SPIRBlock *current_emitting_switch = nullptr;
|
SmallVector<SPIRBlock *> current_emitting_switch_stack;
|
||||||
bool current_emitting_switch_fallthrough = false;
|
bool current_emitting_switch_fallthrough = false;
|
||||||
|
|
||||||
virtual void emit_instruction(const Instruction &instr);
|
virtual void emit_instruction(const Instruction &instr);
|
||||||
|
|||||||
79
3rdparty/spirv-cross/spirv_hlsl.cpp
vendored
79
3rdparty/spirv-cross/spirv_hlsl.cpp
vendored
@@ -2404,12 +2404,32 @@ string CompilerHLSL::to_func_call_arg(const SPIRFunction::Parameter &arg, uint32
|
|||||||
return arg_str;
|
return arg_str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
string CompilerHLSL::get_inner_entry_point_name() const
|
||||||
|
{
|
||||||
|
auto &execution = get_entry_point();
|
||||||
|
|
||||||
|
if (hlsl_options.use_entry_point_name)
|
||||||
|
{
|
||||||
|
auto name = join(execution.name, "_inner");
|
||||||
|
ParsedIR::sanitize_underscores(name);
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (execution.model == ExecutionModelVertex)
|
||||||
|
return "vert_main";
|
||||||
|
else if (execution.model == ExecutionModelFragment)
|
||||||
|
return "frag_main";
|
||||||
|
else if (execution.model == ExecutionModelGLCompute)
|
||||||
|
return "comp_main";
|
||||||
|
else
|
||||||
|
SPIRV_CROSS_THROW("Unsupported execution model.");
|
||||||
|
}
|
||||||
|
|
||||||
void CompilerHLSL::emit_function_prototype(SPIRFunction &func, const Bitset &return_flags)
|
void CompilerHLSL::emit_function_prototype(SPIRFunction &func, const Bitset &return_flags)
|
||||||
{
|
{
|
||||||
if (func.self != ir.default_entry_point)
|
if (func.self != ir.default_entry_point)
|
||||||
add_function_overload(func);
|
add_function_overload(func);
|
||||||
|
|
||||||
auto &execution = get_entry_point();
|
|
||||||
// Avoid shadow declarations.
|
// Avoid shadow declarations.
|
||||||
local_variable_names = resource_names;
|
local_variable_names = resource_names;
|
||||||
|
|
||||||
@@ -2430,14 +2450,7 @@ void CompilerHLSL::emit_function_prototype(SPIRFunction &func, const Bitset &ret
|
|||||||
|
|
||||||
if (func.self == ir.default_entry_point)
|
if (func.self == ir.default_entry_point)
|
||||||
{
|
{
|
||||||
if (execution.model == ExecutionModelVertex)
|
decl += get_inner_entry_point_name();
|
||||||
decl += "vert_main";
|
|
||||||
else if (execution.model == ExecutionModelFragment)
|
|
||||||
decl += "frag_main";
|
|
||||||
else if (execution.model == ExecutionModelGLCompute)
|
|
||||||
decl += "comp_main";
|
|
||||||
else
|
|
||||||
SPIRV_CROSS_THROW("Unsupported execution model.");
|
|
||||||
processing_entry_point = true;
|
processing_entry_point = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -2555,7 +2568,13 @@ void CompilerHLSL::emit_hlsl_entry_point()
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
statement(require_output ? "SPIRV_Cross_Output " : "void ", "main(", merge(arguments), ")");
|
const char *entry_point_name;
|
||||||
|
if (hlsl_options.use_entry_point_name)
|
||||||
|
entry_point_name = get_entry_point().name.c_str();
|
||||||
|
else
|
||||||
|
entry_point_name = "main";
|
||||||
|
|
||||||
|
statement(require_output ? "SPIRV_Cross_Output " : "void ", entry_point_name, "(", merge(arguments), ")");
|
||||||
begin_scope();
|
begin_scope();
|
||||||
bool legacy = hlsl_options.shader_model <= 30;
|
bool legacy = hlsl_options.shader_model <= 30;
|
||||||
|
|
||||||
@@ -2728,12 +2747,12 @@ void CompilerHLSL::emit_hlsl_entry_point()
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Run the shader.
|
// Run the shader.
|
||||||
if (execution.model == ExecutionModelVertex)
|
if (execution.model == ExecutionModelVertex ||
|
||||||
statement("vert_main();");
|
execution.model == ExecutionModelFragment ||
|
||||||
else if (execution.model == ExecutionModelFragment)
|
execution.model == ExecutionModelGLCompute)
|
||||||
statement("frag_main();");
|
{
|
||||||
else if (execution.model == ExecutionModelGLCompute)
|
statement(get_inner_entry_point_name(), "();");
|
||||||
statement("comp_main();");
|
}
|
||||||
else
|
else
|
||||||
SPIRV_CROSS_THROW("Unsupported shader stage.");
|
SPIRV_CROSS_THROW("Unsupported shader stage.");
|
||||||
|
|
||||||
@@ -4728,9 +4747,9 @@ void CompilerHLSL::emit_subgroup_op(const Instruction &i)
|
|||||||
case OpGroupNonUniformBallotBitCount:
|
case OpGroupNonUniformBallotBitCount:
|
||||||
{
|
{
|
||||||
auto operation = static_cast<GroupOperation>(ops[3]);
|
auto operation = static_cast<GroupOperation>(ops[3]);
|
||||||
|
bool forward = should_forward(ops[4]);
|
||||||
if (operation == GroupOperationReduce)
|
if (operation == GroupOperationReduce)
|
||||||
{
|
{
|
||||||
bool forward = should_forward(ops[4]);
|
|
||||||
auto left = join("countbits(", to_enclosed_expression(ops[4]), ".x) + countbits(",
|
auto left = join("countbits(", to_enclosed_expression(ops[4]), ".x) + countbits(",
|
||||||
to_enclosed_expression(ops[4]), ".y)");
|
to_enclosed_expression(ops[4]), ".y)");
|
||||||
auto right = join("countbits(", to_enclosed_expression(ops[4]), ".z) + countbits(",
|
auto right = join("countbits(", to_enclosed_expression(ops[4]), ".z) + countbits(",
|
||||||
@@ -4739,9 +4758,31 @@ void CompilerHLSL::emit_subgroup_op(const Instruction &i)
|
|||||||
inherit_expression_dependencies(id, ops[4]);
|
inherit_expression_dependencies(id, ops[4]);
|
||||||
}
|
}
|
||||||
else if (operation == GroupOperationInclusiveScan)
|
else if (operation == GroupOperationInclusiveScan)
|
||||||
SPIRV_CROSS_THROW("Cannot trivially implement BallotBitCount Inclusive Scan in HLSL.");
|
{
|
||||||
|
auto left = join("countbits(", to_enclosed_expression(ops[4]), ".x & gl_SubgroupLeMask.x) + countbits(",
|
||||||
|
to_enclosed_expression(ops[4]), ".y & gl_SubgroupLeMask.y)");
|
||||||
|
auto right = join("countbits(", to_enclosed_expression(ops[4]), ".z & gl_SubgroupLeMask.z) + countbits(",
|
||||||
|
to_enclosed_expression(ops[4]), ".w & gl_SubgroupLeMask.w)");
|
||||||
|
emit_op(result_type, id, join(left, " + ", right), forward);
|
||||||
|
if (!active_input_builtins.get(BuiltInSubgroupLeMask))
|
||||||
|
{
|
||||||
|
active_input_builtins.set(BuiltInSubgroupLeMask);
|
||||||
|
force_recompile_guarantee_forward_progress();
|
||||||
|
}
|
||||||
|
}
|
||||||
else if (operation == GroupOperationExclusiveScan)
|
else if (operation == GroupOperationExclusiveScan)
|
||||||
SPIRV_CROSS_THROW("Cannot trivially implement BallotBitCount Exclusive Scan in HLSL.");
|
{
|
||||||
|
auto left = join("countbits(", to_enclosed_expression(ops[4]), ".x & gl_SubgroupLtMask.x) + countbits(",
|
||||||
|
to_enclosed_expression(ops[4]), ".y & gl_SubgroupLtMask.y)");
|
||||||
|
auto right = join("countbits(", to_enclosed_expression(ops[4]), ".z & gl_SubgroupLtMask.z) + countbits(",
|
||||||
|
to_enclosed_expression(ops[4]), ".w & gl_SubgroupLtMask.w)");
|
||||||
|
emit_op(result_type, id, join(left, " + ", right), forward);
|
||||||
|
if (!active_input_builtins.get(BuiltInSubgroupLtMask))
|
||||||
|
{
|
||||||
|
active_input_builtins.set(BuiltInSubgroupLtMask);
|
||||||
|
force_recompile_guarantee_forward_progress();
|
||||||
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
SPIRV_CROSS_THROW("Invalid BitCount operation.");
|
SPIRV_CROSS_THROW("Invalid BitCount operation.");
|
||||||
break;
|
break;
|
||||||
|
|||||||
5
3rdparty/spirv-cross/spirv_hlsl.hpp
vendored
5
3rdparty/spirv-cross/spirv_hlsl.hpp
vendored
@@ -137,6 +137,9 @@ public:
|
|||||||
// If add_vertex_attribute_remap is used and this feature is used,
|
// If add_vertex_attribute_remap is used and this feature is used,
|
||||||
// the semantic name will be queried once per active location.
|
// the semantic name will be queried once per active location.
|
||||||
bool flatten_matrix_vertex_input_semantics = false;
|
bool flatten_matrix_vertex_input_semantics = false;
|
||||||
|
|
||||||
|
// Rather than emitting main() for the entry point, use the name in SPIR-V.
|
||||||
|
bool use_entry_point_name = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
explicit CompilerHLSL(std::vector<uint32_t> spirv_)
|
explicit CompilerHLSL(std::vector<uint32_t> spirv_)
|
||||||
@@ -374,6 +377,8 @@ private:
|
|||||||
bool builtin_translates_to_nonarray(spv::BuiltIn builtin) const override;
|
bool builtin_translates_to_nonarray(spv::BuiltIn builtin) const override;
|
||||||
|
|
||||||
std::vector<TypeID> composite_selection_workaround_types;
|
std::vector<TypeID> composite_selection_workaround_types;
|
||||||
|
|
||||||
|
std::string get_inner_entry_point_name() const;
|
||||||
};
|
};
|
||||||
} // namespace SPIRV_CROSS_NAMESPACE
|
} // namespace SPIRV_CROSS_NAMESPACE
|
||||||
|
|
||||||
|
|||||||
11
3rdparty/spirv-cross/spirv_parser.cpp
vendored
11
3rdparty/spirv-cross/spirv_parser.cpp
vendored
@@ -1020,7 +1020,16 @@ void Parser::parse(const Instruction &instruction)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ir.block_meta[current_block->next_block] &= ~ParsedIR::BLOCK_META_SELECTION_MERGE_BIT;
|
// Collapse loops if we have to.
|
||||||
|
bool collapsed_loop = current_block->true_block == current_block->merge_block &&
|
||||||
|
current_block->merge == SPIRBlock::MergeLoop;
|
||||||
|
|
||||||
|
if (collapsed_loop)
|
||||||
|
{
|
||||||
|
ir.block_meta[current_block->merge_block] &= ~ParsedIR::BLOCK_META_LOOP_MERGE_BIT;
|
||||||
|
ir.block_meta[current_block->continue_block] &= ~ParsedIR::BLOCK_META_CONTINUE_BIT;
|
||||||
|
}
|
||||||
|
|
||||||
current_block->next_block = current_block->true_block;
|
current_block->next_block = current_block->true_block;
|
||||||
current_block->condition = 0;
|
current_block->condition = 0;
|
||||||
current_block->true_block = 0;
|
current_block->true_block = 0;
|
||||||
|
|||||||
Reference in New Issue
Block a user