]> git.tdb.fi Git - libs/gl.git/commitdiff
Generate correct OpPhi instructions for nested ternary expressions
authorMikko Rasa <tdb@tdb.fi>
Sun, 7 Nov 2021 14:06:09 +0000 (16:06 +0200)
committerMikko Rasa <tdb@tdb.fi>
Sun, 7 Nov 2021 14:10:46 +0000 (16:10 +0200)
The parent blocks must be immediate predecessors of the block containing
the OpPhi instruction.

source/glsl/spirv.cpp
source/glsl/spirvwriter.h
tests/glsl/nested_ternary.glsl [new file with mode: 0644]

index 91182a65725f3cae26a509ed588492ba08cfb881..39aa9a0672a72159ec7952cc668c004e9714bd5b 100644 (file)
@@ -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<FunctionDeclaration *> 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;
index 95db13c173ec11c819fe4ec5453546c67d82527d..8456389a48b5df36363b1b6f69bba370168edf6c 100644 (file)
@@ -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 (file)
index 0000000..8896c17
--- /dev/null
@@ -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;
+}
+*/