X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Fglsl%2Fspirv.cpp;h=c9062efa12ae7aee7dfb54ca6638d64ca57b3da8;hb=25629675e83449d986ef8896e830db562a8ae64e;hp=39aa9a0672a72159ec7952cc668c004e9714bd5b;hpb=b125c684e2c2feb86845f051285fe666d8ebfc76;p=libs%2Fgl.git diff --git a/source/glsl/spirv.cpp b/source/glsl/spirv.cpp index 39aa9a06..c9062efa 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); @@ -1673,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); @@ -1699,10 +1715,10 @@ 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()) + auto i = find_member(*layout_ql, string("binding"), &Layout::Qualifier::name); + if(i!=layout_ql->end()) writer.write_op_decorate(block_id, DECO_BINDING, i->value); } } @@ -1817,6 +1833,7 @@ 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); @@ -1848,6 +1865,8 @@ 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.get_current_block()) @@ -1858,6 +1877,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; @@ -1872,8 +1892,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++;