From: Mikko Rasa Date: Sun, 7 Nov 2021 14:06:09 +0000 (+0200) Subject: Generate correct OpPhi instructions for nested ternary expressions X-Git-Url: http://git.tdb.fi/?p=libs%2Fgl.git;a=commitdiff_plain;h=b125c684e2c2feb86845f051285fe666d8ebfc76 Generate correct OpPhi instructions for nested ternary expressions The parent blocks must be immediate predecessors of the block containing the OpPhi instruction. --- diff --git a/source/glsl/spirv.cpp b/source/glsl/spirv.cpp index 91182a65..39aa9a06 100644 --- a/source/glsl/spirv.cpp +++ b/source/glsl/spirv.cpp @@ -1028,11 +1028,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); @@ -1819,7 +1821,7 @@ void SpirVGenerator::visit(FunctionDeclaration &func) 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); @@ -1848,7 +1850,7 @@ void SpirVGenerator::visit(Conditional &cond) 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; diff --git a/source/glsl/spirvwriter.h b/source/glsl/spirvwriter.h index 95db13c1..8456389a 100644 --- a/source/glsl/spirvwriter.h +++ b/source/glsl/spirvwriter.h @@ -61,7 +61,7 @@ public: void write_op_member_decorate(Id, unsigned, Decoration); void write_op_member_decorate(Id, unsigned, Decoration, Word); void write_op_label(Id); - bool has_current_block() const { return current_block_id; } + Id get_current_block() const { return current_block_id; } void begin_function_body(Id); void end_function_body(); void finalize(unsigned, Id); diff --git a/tests/glsl/nested_ternary.glsl b/tests/glsl/nested_ternary.glsl new file mode 100644 index 00000000..8896c17a --- /dev/null +++ b/tests/glsl/nested_ternary.glsl @@ -0,0 +1,49 @@ +uniform Colors +{ + vec4 top_left; + vec4 top_right; + vec4 bottom_left; + vec4 bottom_right; +}; + +#pragma MSP stage(vertex) +layout(location=0) in vec4 position; +void main() +{ + gl_Position = position; + passthrough; +} + +#pragma MSP stage(fragment) +layout(location=0) out vec4 frag_color; +void main() +{ + frag_color = (position.x>0 ? position.y>0 ? top_right : bottom_right : + position.y>0 ? top_left : bottom_left); +} + +/* Expected output: vertex +layout(location=0) in vec4 position; +layout(location=0) out vec4 _vs_out_position; +void main() +{ + gl_Position = position; + _vs_out_position = position; +} +*/ + +/* Expected output: fragment +layout(binding=23) uniform Colors +{ + vec4 top_left; + vec4 top_right; + vec4 bottom_left; + vec4 bottom_right; +}; +layout(location=0) out vec4 frag_color; +layout(location=0) in vec4 _vs_out_position; +void main() +{ + frag_color = _vs_out_position.x>0.0?(_vs_out_position.y>0.0?top_right:bottom_right):_vs_out_position.y>0.0?top_left:bottom_left; +} +*/