X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Fglsl%2Fspirv.cpp;h=20345e20ae0760de48e4bbea923e89fea7d9356b;hb=3fe1aab63922eec99d8bf6fd4fd60bec10df173c;hp=91182a65725f3cae26a509ed588492ba08cfb881;hpb=e8369afbde298a3011a341cd2d4dfed76ecd8d3b;p=libs%2Fgl.git diff --git a/source/glsl/spirv.cpp b/source/glsl/spirv.cpp index 91182a65..20345e20 100644 --- a/source/glsl/spirv.cpp +++ b/source/glsl/spirv.cpp @@ -690,6 +690,9 @@ void SpirVGenerator::visit(Swizzle &swizzle) void SpirVGenerator::visit(UnaryExpression &unary) { + if(composite_access) + return visit_isolated(unary); + unary.expression->visit(*this); char oper = unary.oper->token[0]; @@ -774,6 +777,8 @@ void SpirVGenerator::visit(BinaryExpression &binary) visit_isolated(*binary.right); return visit_composite(*binary.left, 0x400000|r_expression_result_id, *binary.type); } + else if(composite_access) + return visit_isolated(binary); if(assignment_source_id) throw internal_error("invalid binary expression in assignment target"); @@ -998,6 +1003,8 @@ void SpirVGenerator::visit(Assignment &assign) void SpirVGenerator::visit(TernaryExpression &ternary) { + if(composite_access) + return visit_isolated(ternary); if(constant_expression) { ternary.condition->visit(*this); @@ -1028,11 +1035,13 @@ void SpirVGenerator::visit(TernaryExpression &ternary) writer.write_op_label(true_label_id); ternary.true_expr->visit(*this); Id true_result_id = r_expression_result_id; + true_label_id = writer.get_current_block(); writer.write_op(content.function_body, OP_BRANCH, merge_block_id); writer.write_op_label(false_label_id); ternary.false_expr->visit(*this); Id false_result_id = r_expression_result_id; + false_label_id = writer.get_current_block(); writer.write_op_label(merge_block_id); r_expression_result_id = begin_expression(OP_PHI, get_id(*ternary.type), 4); @@ -1671,7 +1680,16 @@ void SpirVGenerator::visit(VariableDeclaration &var) void SpirVGenerator::visit(InterfaceBlock &iface) { - StorageClass storage = get_interface_storage(iface.interface, true); + const vector *layout_ql = (iface.layout ? &iface.layout->qualifiers : 0); + + bool push_const = false; + if(layout_ql) + { + auto i = find_member(*layout_ql, string("push_constant"), &Layout::Qualifier::name); + push_const = (i!=layout_ql->end()); + } + + StorageClass storage = (push_const ? STORAGE_PUSH_CONSTANT : get_interface_storage(iface.interface, true)); Id type_id; if(iface.array) type_id = get_array_type_id(*iface.struct_declaration, 0); @@ -1697,11 +1715,15 @@ void SpirVGenerator::visit(InterfaceBlock &iface) writer.write_op(content.globals, OP_VARIABLE, ptr_type_id, block_id, storage); - if(iface.layout) + if(layout_ql) { - auto i = find_member(iface.layout->qualifiers, string("binding"), &Layout::Qualifier::name); - if(i!=iface.layout->qualifiers.end()) - writer.write_op_decorate(block_id, DECO_BINDING, i->value); + for(const Layout::Qualifier &q: *layout_ql) + { + if(q.name=="set") + writer.write_op_decorate(block_id, DECO_DESCRIPTOR_SET, q.value); + else if(q.name=="binding") + writer.write_op_decorate(block_id, DECO_BINDING, q.value); + } } } @@ -1815,11 +1837,12 @@ void SpirVGenerator::visit(FunctionDeclaration &func) variable_load_ids[func.parameters[i].get()] = param_id; } + reachable = true; writer.begin_function_body(next_id++); SetForScope set_func(current_function, &func); func.body.visit(*this); - if(writer.has_current_block()) + if(writer.get_current_block()) { if(!reachable) writer.write_op(content.function_body, OP_UNREACHABLE); @@ -1846,9 +1869,11 @@ void SpirVGenerator::visit(Conditional &cond) writer.write_op(content.function_body, OP_SELECTION_MERGE, merge_block_id, 0); // Selection control (none) writer.write_op(content.function_body, OP_BRANCH_CONDITIONAL, r_expression_result_id, true_label_id, false_label_id); + std::map saved_load_ids = variable_load_ids; + writer.write_op_label(true_label_id); cond.body.visit(*this); - if(writer.has_current_block()) + if(writer.get_current_block()) writer.write_op(content.function_body, OP_BRANCH, merge_block_id); bool reachable_if_true = reachable; @@ -1856,6 +1881,7 @@ void SpirVGenerator::visit(Conditional &cond) reachable = true; if(!cond.else_body.body.empty()) { + swap(saved_load_ids, variable_load_ids); writer.write_op_label(false_label_id); cond.else_body.visit(*this); reachable |= reachable_if_true; @@ -1870,8 +1896,9 @@ void SpirVGenerator::visit(Iteration &iter) if(iter.init_statement) iter.init_statement->visit(*this); - for(VariableDeclaration *v: AssignmentCollector().apply(iter)) - variable_load_ids.erase(v); + for(Node *n: AssignmentCollector().apply(iter)) + if(VariableDeclaration *var = dynamic_cast(n)) + variable_load_ids.erase(var); Id header_id = next_id++; Id continue_id = next_id++;