From 1f77cacd690c8d66aa0b39b00dcb5f3d6a533ebf Mon Sep 17 00:00:00 2001
From: John Kessenich <cepheus@frii.com>
Date: Tue, 24 Mar 2015 00:32:50 +0000
Subject: [PATCH] glslang -> SPIR-V: Correct code generated for
 EmitStreamVertex and EndStreamPrimitive.

git-svn-id: https://cvs.khronos.org/svn/repos/ogl/trunk/ecosystem/public/sdk/tools/glslang@30270 e7fa87d3-cd2b-0410-9028-fcbf551c1848
---
 SPIRV/GlslangToSpv.cpp | 36 +++++++++++++++++-------------------
 SPIRV/SpvBuilder.cpp   | 12 ++++++++++--
 SPIRV/SpvBuilder.h     |  3 ++-
 3 files changed, 29 insertions(+), 22 deletions(-)

diff --git a/SPIRV/GlslangToSpv.cpp b/SPIRV/GlslangToSpv.cpp
index 10e7b92e5..332c5ec55 100644
--- a/SPIRV/GlslangToSpv.cpp
+++ b/SPIRV/GlslangToSpv.cpp
@@ -736,6 +736,14 @@ bool TGlslangToSpvTraverser::visitUnary(glslang::TVisit /* visit */, glslang::TI
         }
 
         return false;
+
+    case glslang::EOpEmitStreamVertex:
+        builder.createNoResultOp(spv::OpEmitStreamVertex, operand);
+        return false;
+    case glslang::EOpEndStreamPrimitive:
+        builder.createNoResultOp(spv::OpEndStreamPrimitive, operand);
+        return false;
+
     default:
         spv::MissingFunctionality("glslang unary");
         break;
@@ -967,13 +975,7 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
     case glslang::EOpMemoryBarrierShared:
     case glslang::EOpGroupMemoryBarrier:
         noReturnValue = true;
-        // These all have 0 operands and will naturally finish up in the createIntrinsic code below for 0 operands
-        break;
-
-    case glslang::EOpEmitStreamVertex:
-    case glslang::EOpEndStreamPrimitive:
-        noReturnValue = true;
-        // These all have 1 operand and will naturally finish up in the createIntrinsic code below for 1 operand
+        // These all have 0 operands and will naturally finish up in the code below for 0 operands
         break;
 
     default:
@@ -2137,13 +2139,6 @@ spv::Id TGlslangToSpvTraverser::createUnaryOperation(glslang::TOperator op, spv:
         libCall = GLSL_STD_450::Sign;
         break;
 
-    case glslang::EOpEmitStreamVertex:
-        unaryOp = spv::OpEmitStreamVertex;
-        break;
-    case glslang::EOpEndStreamPrimitive:
-        unaryOp = spv::OpEndStreamPrimitive;
-        break;
-
     default:
         return 0;
     }
@@ -2331,12 +2326,13 @@ spv::Id TGlslangToSpvTraverser::createMiscOperation(glslang::TOperator op, spv::
     else {
         switch (operands.size()) {
         case 0:
-            id = builder.createEmptyOp(opCode);
-            break;
+            // should all be handled by visitAggregate and createNoArgOperation
+            assert(0);
+            return 0;
         case 1:
             // should all be handled by createUnaryOperation
             assert(0);
-            break;
+            return 0;
         case 2:
             id = builder.createBinOp(opCode, typeId, operands[0], operands[1]);
             break;
@@ -2362,9 +2358,11 @@ spv::Id TGlslangToSpvTraverser::createNoArgOperation(glslang::TOperator op)
 
     switch (op) {
     case glslang::EOpEmitVertex:
-        return builder.createEmptyOp(spv::OpEmitVertex);
+        builder.createNoResultOp(spv::OpEmitVertex);
+        return 0;
     case glslang::EOpEndPrimitive:
-        return builder.createEmptyOp(spv::OpEndPrimitive);
+        builder.createNoResultOp(spv::OpEndPrimitive);
+        return 0;
     case glslang::EOpBarrier:
         builder.createMemoryBarrier(spv::ExecutionScopeDevice, spv::MemorySemanticsAllMemory);
         builder.createControlBarrier(spv::ExecutionScopeDevice);
diff --git a/SPIRV/SpvBuilder.cpp b/SPIRV/SpvBuilder.cpp
index 742128407..8e2b9bcad 100644
--- a/SPIRV/SpvBuilder.cpp
+++ b/SPIRV/SpvBuilder.cpp
@@ -877,12 +877,19 @@ Id Builder::createCompositeInsert(Id object, Id composite, Id typeId, std::vecto
     return insert->getResultId();
 }
 
-Id Builder::createEmptyOp(OpCode opCode)
+// An opcode that has no operands, no result id, and no type
+void Builder::createNoResultOp(OpCode opCode)
 {
     Instruction* op = new Instruction(opCode);
     buildPoint->addInstruction(op);
+}
 
-    return op->getResultId();
+// An opcode that has one operand, no result id, and no type
+void Builder::createNoResultOp(OpCode opCode, Id operand)
+{
+    Instruction* op = new Instruction(opCode);
+    op->addIdOperand(operand);
+    buildPoint->addInstruction(op);
 }
 
 void Builder::createControlBarrier(unsigned executionScope)
@@ -900,6 +907,7 @@ void Builder::createMemoryBarrier(unsigned executionScope, unsigned memorySemant
     buildPoint->addInstruction(op);
 }
 
+// An opcode that has one operands, a result id, and a type
 Id Builder::createUnaryOp(OpCode opCode, Id typeId, Id operand)
 {
     Instruction* op = new Instruction(getUniqueId(), typeId, opCode);
diff --git a/SPIRV/SpvBuilder.h b/SPIRV/SpvBuilder.h
index f2b746c04..787d852f8 100644
--- a/SPIRV/SpvBuilder.h
+++ b/SPIRV/SpvBuilder.h
@@ -228,7 +228,8 @@ public:
     Id createCompositeInsert(Id object, Id composite, Id typeId, unsigned index);
     Id createCompositeInsert(Id object, Id composite, Id typeId, std::vector<unsigned>& indexes);
 
-    Id createEmptyOp(OpCode);
+    void createNoResultOp(OpCode);
+    void createNoResultOp(OpCode, Id operand);
     void createControlBarrier(unsigned executionScope);
     void createMemoryBarrier(unsigned executionScope, unsigned memorySemantics);
     Id createUnaryOp(OpCode, Id typeId, Id operand);
-- 
GitLab