Add tests for SubgroupDispatch.
authorDejan Mircevski <deki@google.com>
Thu, 21 Apr 2016 19:46:08 +0000 (15:46 -0400)
committerDejan Mircevski <deki@google.com>
Thu, 21 Apr 2016 19:46:08 +0000 (15:46 -0400)
Introduced in v1.1, SubgroupDispatch adds the following:
- two new execution modes
- one new capability
- two new opcodes

Extend ValidateBase methods to take a spv_target_env.  Replace the
context_ member with ScopedContext inside the said methods.  Give
ScopedContext wider visibility by moving it outside
TextToBinaryTestBase.

16 files changed:
test/AssemblyFormat.cpp
test/BinaryDestroy.cpp
test/BinaryParse.cpp
test/BinaryToText.cpp
test/CMakeLists.txt
test/ImmediateInt.cpp
test/OpcodeRequiresCapabilities.cpp
test/OperandCapabilities.cpp
test/TestFixture.h
test/TextToBinary.ModeSetting.cpp
test/TextToBinary.SubgroupDispatch.cpp [new file with mode: 0644]
test/TextToBinary.cpp
test/Validate.Capability.cpp
test/ValidateFixtures.cpp
test/ValidateFixtures.h
test/ValidateID.cpp

index 9da22af..dfbaade 100644 (file)
@@ -28,6 +28,7 @@
 
 namespace {
 
+using spvtest::ScopedContext;
 using spvtest::TextToBinaryTest;
 
 TEST_F(TextToBinaryTest, NotPlacingResultIDAtTheBeginning) {
index b618ced..5be468d 100644 (file)
@@ -30,6 +30,8 @@
 
 namespace {
 
+using spvtest::ScopedContext;
+
 TEST(BinaryDestroy, Null) {
   // There is no state or return value to check. Just check
   // for the ability to call the API without abnormal termination.
index 659453b..e410058 100644 (file)
@@ -48,6 +48,7 @@ namespace {
 using ::spvtest::Concatenate;
 using ::spvtest::MakeInstruction;
 using ::spvtest::MakeVector;
+using ::spvtest::ScopedContext;
 using ::testing::AnyOf;
 using ::testing::Eq;
 using ::testing::InSequence;
index 897e8d1..5b1ff28 100644 (file)
 #include "TestFixture.h"
 #include "source/spirv_constant.h"
 
+namespace {
+
 using ::testing::Eq;
 using ::testing::HasSubstr;
 using spvtest::AutoText;
+using spvtest::ScopedContext;
 using spvtest::TextToBinaryTest;
 
-namespace {
 class BinaryToText : public ::testing::Test {
  public:
   BinaryToText() : context(spvContextCreate(SPV_ENV_UNIVERSAL_1_0)) {}
index 078febd..9048e87 100644 (file)
@@ -79,6 +79,7 @@ if (NOT ${SPIRV_SKIP_EXECUTABLES})
       ${CMAKE_CURRENT_SOURCE_DIR}/TextToBinary.Miscellaneous.cpp
       ${CMAKE_CURRENT_SOURCE_DIR}/TextToBinary.ModeSetting.cpp
       ${CMAKE_CURRENT_SOURCE_DIR}/TextToBinary.TypeDeclaration.cpp
+      ${CMAKE_CURRENT_SOURCE_DIR}/TextToBinary.SubgroupDispatch.cpp
       ${CMAKE_CURRENT_SOURCE_DIR}/TextWordGet.cpp
       ${CMAKE_CURRENT_SOURCE_DIR}/UnitSPIRV.cpp
       ${CMAKE_CURRENT_SOURCE_DIR}/ValidateFixtures.cpp
index 1233a16..5653c28 100644 (file)
@@ -37,6 +37,7 @@ namespace {
 
 using spvtest::Concatenate;
 using spvtest::MakeInstruction;
+using spvtest::ScopedContext;
 using spvtest::TextToBinaryTest;
 using spvutils::BitwiseCast;
 using ::testing::ElementsAre;
index eea16ea..4718956 100644 (file)
@@ -135,6 +135,8 @@ INSTANTIATE_TEST_CASE_P(
         ExpectedOpCodeCapabilities{SpvOpEmitStreamVertex,
                                    mask(SpvCapabilityGeometryStreams)},
         ExpectedOpCodeCapabilities{SpvOpTypeNamedBarrier,
-                                   mask(SpvCapabilityNamedBarrier)}), );
+                                   mask(SpvCapabilityNamedBarrier)},
+        ExpectedOpCodeCapabilities{SpvOpGetKernelMaxNumSubgroups,
+                                   mask(SpvCapabilitySubgroupDispatch)}), );
 
 }  // anonymous namespace
index f99b570..ec74e6d 100644 (file)
@@ -37,12 +37,19 @@ struct EnumCapabilityCase {
   uint64_t expected_mask;
 };
 
-using EnumCapabilityTest = ::testing::TestWithParam<EnumCapabilityCase>;
+// Test fixture for testing EnumCapabilityCases.
+template <spv_target_env env>
+class EnumCapabilityTest : public ::testing::TestWithParam<EnumCapabilityCase> {
+ protected:
+  const spv_target_env env_ = env;  // Target environment to use in tests.
+};
+
+using EnumCapabilityTestV10 = EnumCapabilityTest<SPV_ENV_UNIVERSAL_1_0>;
+using EnumCapabilityTestV11 = EnumCapabilityTest<SPV_ENV_UNIVERSAL_1_1>;
 
-TEST_P(EnumCapabilityTest, Sample) {
+TEST_P(EnumCapabilityTestV10, Sample) {
   spv_operand_table operandTable;
-  ASSERT_EQ(SPV_SUCCESS,
-            spvOperandTableGet(&operandTable, SPV_ENV_UNIVERSAL_1_0));
+  ASSERT_EQ(SPV_SUCCESS, spvOperandTableGet(&operandTable, env_));
   spv_operand_desc entry;
   ASSERT_EQ(SPV_SUCCESS,
             spvOperandTableValueLookup(operandTable, GetParam().type,
@@ -66,7 +73,7 @@ TEST_P(EnumCapabilityTest, Sample) {
 
 // See SPIR-V Section 3.3 Execution Model
 INSTANTIATE_TEST_CASE_P(
-    ExecutionModel, EnumCapabilityTest,
+    ExecutionModel, EnumCapabilityTestV10,
     ::testing::ValuesIn(std::vector<EnumCapabilityCase>{
         CASE1(EXECUTION_MODEL, ExecutionModelVertex, Shader),
         CASE1(EXECUTION_MODEL, ExecutionModelTessellationControl, Tessellation),
@@ -80,7 +87,7 @@ INSTANTIATE_TEST_CASE_P(
 
 // See SPIR-V Section 3.4 Addressing Model
 INSTANTIATE_TEST_CASE_P(
-    AddressingModel, EnumCapabilityTest,
+    AddressingModel, EnumCapabilityTestV10,
     ::testing::ValuesIn(std::vector<EnumCapabilityCase>{
         CASE0(ADDRESSING_MODEL, AddressingModelLogical),
         CASE1(ADDRESSING_MODEL, AddressingModelPhysical32, Addresses),
@@ -88,7 +95,7 @@ INSTANTIATE_TEST_CASE_P(
     }), );
 
 // See SPIR-V Section 3.5 Memory Model
-INSTANTIATE_TEST_CASE_P(MemoryModel, EnumCapabilityTest,
+INSTANTIATE_TEST_CASE_P(MemoryModel, EnumCapabilityTestV10,
                         ::testing::ValuesIn(std::vector<EnumCapabilityCase>{
                             CASE1(MEMORY_MODEL, MemoryModelSimple, Shader),
                             CASE1(MEMORY_MODEL, MemoryModelGLSL450, Shader),
@@ -97,7 +104,7 @@ INSTANTIATE_TEST_CASE_P(MemoryModel, EnumCapabilityTest,
 
 // See SPIR-V Section 3.6 Execution Mode
 INSTANTIATE_TEST_CASE_P(
-    ExecutionMode, EnumCapabilityTest,
+    ExecutionMode, EnumCapabilityTestV10,
     ::testing::ValuesIn(std::vector<EnumCapabilityCase>{
         CASE1(EXECUTION_MODE, ExecutionModeInvocations, Geometry),
         CASE1(EXECUTION_MODE, ExecutionModeSpacingEqual, Tessellation),
@@ -133,9 +140,16 @@ INSTANTIATE_TEST_CASE_P(
         CASE1(EXECUTION_MODE, ExecutionModeContractionOff, Kernel),
     }), );
 
+INSTANTIATE_TEST_CASE_P(
+    ExecutionMode, EnumCapabilityTestV11,
+    ::testing::ValuesIn(std::vector<EnumCapabilityCase>{
+        CASE1(EXECUTION_MODE, ExecutionModeSubgroupSize, SubgroupDispatch),
+        CASE1(EXECUTION_MODE, ExecutionModeSubgroupsPerWorkgroup,
+              SubgroupDispatch)}), );
+
 // See SPIR-V Section 3.7 Storage Class
 INSTANTIATE_TEST_CASE_P(
-    StorageClass, EnumCapabilityTest,
+    StorageClass, EnumCapabilityTestV10,
     ::testing::ValuesIn(std::vector<EnumCapabilityCase>{
         CASE0(STORAGE_CLASS, StorageClassUniformConstant),
         CASE1(STORAGE_CLASS, StorageClassInput, Shader),
@@ -153,7 +167,7 @@ INSTANTIATE_TEST_CASE_P(
 
 // See SPIR-V Section 3.8 Dim
 INSTANTIATE_TEST_CASE_P(
-    Dim, EnumCapabilityTest,
+    Dim, EnumCapabilityTestV10,
     ::testing::ValuesIn(std::vector<EnumCapabilityCase>{
         CASE1(DIMENSIONALITY, Dim1D, Sampled1D), CASE0(DIMENSIONALITY, Dim2D),
         CASE0(DIMENSIONALITY, Dim3D), CASE1(DIMENSIONALITY, DimCube, Shader),
@@ -164,7 +178,7 @@ INSTANTIATE_TEST_CASE_P(
 
 // See SPIR-V Section 3.9 Sampler Addressing Mode
 INSTANTIATE_TEST_CASE_P(
-    SamplerAddressingMode, EnumCapabilityTest,
+    SamplerAddressingMode, EnumCapabilityTestV10,
     ::testing::ValuesIn(std::vector<EnumCapabilityCase>{
         CASE1(SAMPLER_ADDRESSING_MODE, SamplerAddressingModeNone, Kernel),
         CASE1(SAMPLER_ADDRESSING_MODE, SamplerAddressingModeClampToEdge,
@@ -177,7 +191,7 @@ INSTANTIATE_TEST_CASE_P(
 
 // See SPIR-V Section 3.10 Sampler Filter Mode
 INSTANTIATE_TEST_CASE_P(
-    SamplerFilterMode, EnumCapabilityTest,
+    SamplerFilterMode, EnumCapabilityTestV10,
     ::testing::ValuesIn(std::vector<EnumCapabilityCase>{
         CASE1(SAMPLER_FILTER_MODE, SamplerFilterModeNearest, Kernel),
         CASE1(SAMPLER_FILTER_MODE, SamplerFilterModeLinear, Kernel),
@@ -186,7 +200,7 @@ INSTANTIATE_TEST_CASE_P(
 // clang-format off
 // See SPIR-V Section 3.11 Image Format
 INSTANTIATE_TEST_CASE_P(
-    ImageFormat, EnumCapabilityTest,
+    ImageFormat, EnumCapabilityTestV10,
     ::testing::ValuesIn(std::vector<EnumCapabilityCase>{
         CASE0(SAMPLER_IMAGE_FORMAT, ImageFormatUnknown),
         CASE1(SAMPLER_IMAGE_FORMAT, ImageFormatRgba32f, Shader),
@@ -233,7 +247,7 @@ INSTANTIATE_TEST_CASE_P(
 
 // See SPIR-V Section 3.12 Image Channel Order
 INSTANTIATE_TEST_CASE_P(
-    ImageChannelOrder, EnumCapabilityTest,
+    ImageChannelOrder, EnumCapabilityTestV10,
     ::testing::ValuesIn(std::vector<EnumCapabilityCase>{
         CASE1(IMAGE_CHANNEL_ORDER, ImageChannelOrderR, Kernel),
         CASE1(IMAGE_CHANNEL_ORDER, ImageChannelOrderA, Kernel),
@@ -258,7 +272,7 @@ INSTANTIATE_TEST_CASE_P(
 
 // See SPIR-V Section 3.13 Image Channel Data Type
 INSTANTIATE_TEST_CASE_P(
-    ImageChannelDataType, EnumCapabilityTest,
+    ImageChannelDataType, EnumCapabilityTestV10,
     ::testing::ValuesIn(std::vector<EnumCapabilityCase>{
         CASE1(IMAGE_CHANNEL_DATA_TYPE, ImageChannelDataTypeSnormInt8, Kernel),
         CASE1(IMAGE_CHANNEL_DATA_TYPE, ImageChannelDataTypeSnormInt16, Kernel),
@@ -288,7 +302,7 @@ INSTANTIATE_TEST_CASE_P(
 
 // See SPIR-V Section 3.14 Image Operands
 INSTANTIATE_TEST_CASE_P(
-    ImageOperands, EnumCapabilityTest,
+    ImageOperands, EnumCapabilityTestV10,
     ::testing::ValuesIn(std::vector<EnumCapabilityCase>{
         CASE0(OPTIONAL_IMAGE, ImageOperandsMaskNone),
         CASE1(OPTIONAL_IMAGE, ImageOperandsBiasMask, Shader),
@@ -303,7 +317,7 @@ INSTANTIATE_TEST_CASE_P(
 
 // See SPIR-V Section 3.15 FP Fast Math Mode
 INSTANTIATE_TEST_CASE_P(
-    FPFastMathMode, EnumCapabilityTest,
+    FPFastMathMode, EnumCapabilityTestV10,
     ::testing::ValuesIn(std::vector<EnumCapabilityCase>{
         CASE0(FP_FAST_MATH_MODE, FPFastMathModeMaskNone),
         CASE1(FP_FAST_MATH_MODE, FPFastMathModeNotNaNMask, Kernel),
@@ -314,7 +328,7 @@ INSTANTIATE_TEST_CASE_P(
     }), );
 
 // See SPIR-V Section 3.16 FP Rounding Mode
-INSTANTIATE_TEST_CASE_P(FPRoundingMode, EnumCapabilityTest,
+INSTANTIATE_TEST_CASE_P(FPRoundingMode, EnumCapabilityTestV10,
                         ::testing::ValuesIn(std::vector<EnumCapabilityCase>{
                             CASE1(FP_ROUNDING_MODE, FPRoundingModeRTE, Kernel),
                             CASE1(FP_ROUNDING_MODE, FPRoundingModeRTZ, Kernel),
@@ -323,7 +337,7 @@ INSTANTIATE_TEST_CASE_P(FPRoundingMode, EnumCapabilityTest,
                         }), );
 
 // See SPIR-V Section 3.17 Linkage Type
-INSTANTIATE_TEST_CASE_P(LinkageType, EnumCapabilityTest,
+INSTANTIATE_TEST_CASE_P(LinkageType, EnumCapabilityTestV10,
                         ::testing::ValuesIn(std::vector<EnumCapabilityCase>{
                             CASE1(LINKAGE_TYPE, LinkageTypeExport, Linkage),
                             CASE1(LINKAGE_TYPE, LinkageTypeImport, Linkage),
@@ -331,7 +345,7 @@ INSTANTIATE_TEST_CASE_P(LinkageType, EnumCapabilityTest,
 
 // See SPIR-V Section 3.18 Access Qualifier
 INSTANTIATE_TEST_CASE_P(
-    AccessQualifier, EnumCapabilityTest,
+    AccessQualifier, EnumCapabilityTestV10,
     ::testing::ValuesIn(std::vector<EnumCapabilityCase>{
         CASE1(ACCESS_QUALIFIER, AccessQualifierReadOnly, Kernel),
         CASE1(ACCESS_QUALIFIER, AccessQualifierWriteOnly, Kernel),
@@ -339,7 +353,7 @@ INSTANTIATE_TEST_CASE_P(
     }), );
 
 // See SPIR-V Section 3.19 Function Parameter Attribute
-INSTANTIATE_TEST_CASE_P(FunctionParameterAttribute, EnumCapabilityTest,
+INSTANTIATE_TEST_CASE_P(FunctionParameterAttribute, EnumCapabilityTestV10,
                         ::testing::ValuesIn(std::vector<EnumCapabilityCase>{
                             CASE1(FUNCTION_PARAMETER_ATTRIBUTE,
                                   FunctionParameterAttributeZext, Kernel),
@@ -362,7 +376,7 @@ INSTANTIATE_TEST_CASE_P(FunctionParameterAttribute, EnumCapabilityTest,
 
 // See SPIR-V Section 3.20 Decoration
 INSTANTIATE_TEST_CASE_P(
-    Decoration, EnumCapabilityTest,
+    Decoration, EnumCapabilityTestV10,
     ::testing::ValuesIn(std::vector<EnumCapabilityCase>{
         CASE1(DECORATION, DecorationRelaxedPrecision, Shader),
         CASE1(DECORATION, DecorationSpecId, Shader),
@@ -413,7 +427,7 @@ INSTANTIATE_TEST_CASE_P(
 
 // See SPIR-V Section 3.21 BuiltIn
 INSTANTIATE_TEST_CASE_P(
-    BuiltIn, EnumCapabilityTest,
+    BuiltIn, EnumCapabilityTestV10,
     ::testing::ValuesIn(std::vector<EnumCapabilityCase>{
         CASE1(BUILT_IN, BuiltInPosition, Shader),
         CASE1(BUILT_IN, BuiltInPointSize, Shader),
@@ -463,7 +477,7 @@ INSTANTIATE_TEST_CASE_P(
 
 // See SPIR-V Section 3.22 Selection Control
 INSTANTIATE_TEST_CASE_P(
-    SelectionControl, EnumCapabilityTest,
+    SelectionControl, EnumCapabilityTestV10,
     ::testing::ValuesIn(std::vector<EnumCapabilityCase>{
         CASE0(SELECTION_CONTROL, SelectionControlMaskNone),
         CASE0(SELECTION_CONTROL, SelectionControlFlattenMask),
@@ -471,7 +485,7 @@ INSTANTIATE_TEST_CASE_P(
     }), );
 
 // See SPIR-V Section 3.23 Loop Control
-INSTANTIATE_TEST_CASE_P(LoopControl, EnumCapabilityTest,
+INSTANTIATE_TEST_CASE_P(LoopControl, EnumCapabilityTestV10,
                         ::testing::ValuesIn(std::vector<EnumCapabilityCase>{
                             CASE0(LOOP_CONTROL, LoopControlMaskNone),
                             CASE0(LOOP_CONTROL, LoopControlUnrollMask),
@@ -479,7 +493,7 @@ INSTANTIATE_TEST_CASE_P(LoopControl, EnumCapabilityTest,
                         }), );
 
 // See SPIR-V Section 3.24 Function Control
-INSTANTIATE_TEST_CASE_P(FunctionControl, EnumCapabilityTest,
+INSTANTIATE_TEST_CASE_P(FunctionControl, EnumCapabilityTestV10,
                         ::testing::ValuesIn(std::vector<EnumCapabilityCase>{
                             CASE0(FUNCTION_CONTROL, FunctionControlMaskNone),
                             CASE0(FUNCTION_CONTROL, FunctionControlInlineMask),
@@ -491,7 +505,7 @@ INSTANTIATE_TEST_CASE_P(FunctionControl, EnumCapabilityTest,
 
 // See SPIR-V Section 3.25 Memory Semantics <id>
 INSTANTIATE_TEST_CASE_P(
-    MemorySemantics, EnumCapabilityTest,
+    MemorySemantics, EnumCapabilityTestV10,
     ::testing::ValuesIn(std::vector<EnumCapabilityCase>{
         CASE0(MEMORY_SEMANTICS_ID, MemorySemanticsMaskNone),
         CASE0(MEMORY_SEMANTICS_ID, MemorySemanticsAcquireMask),
@@ -509,7 +523,7 @@ INSTANTIATE_TEST_CASE_P(
 
 // See SPIR-V Section 3.26 Memory Access
 INSTANTIATE_TEST_CASE_P(
-    MemoryAccess, EnumCapabilityTest,
+    MemoryAccess, EnumCapabilityTestV10,
     ::testing::ValuesIn(std::vector<EnumCapabilityCase>{
         CASE0(OPTIONAL_MEMORY_ACCESS, MemoryAccessMaskNone),
         CASE0(OPTIONAL_MEMORY_ACCESS, MemoryAccessVolatileMask),
@@ -519,7 +533,7 @@ INSTANTIATE_TEST_CASE_P(
 
 // See SPIR-V Section 3.27 Scope <id>
 INSTANTIATE_TEST_CASE_P(
-    Scope, EnumCapabilityTest,
+    Scope, EnumCapabilityTestV10,
     ::testing::ValuesIn(std::vector<EnumCapabilityCase>{
         CASE0(SCOPE_ID, ScopeCrossDevice), CASE0(SCOPE_ID, ScopeDevice),
         CASE0(SCOPE_ID, ScopeWorkgroup), CASE0(SCOPE_ID, ScopeSubgroup),
@@ -528,7 +542,7 @@ INSTANTIATE_TEST_CASE_P(
 
 // See SPIR-V Section 3.28 Group Operation
 INSTANTIATE_TEST_CASE_P(
-    GroupOperation, EnumCapabilityTest,
+    GroupOperation, EnumCapabilityTestV10,
     ::testing::ValuesIn(std::vector<EnumCapabilityCase>{
         CASE1(GROUP_OPERATION, GroupOperationReduce, Kernel),
         CASE1(GROUP_OPERATION, GroupOperationInclusiveScan, Kernel),
@@ -537,7 +551,7 @@ INSTANTIATE_TEST_CASE_P(
 
 // See SPIR-V Section 3.29 Kernel Enqueue Flags
 INSTANTIATE_TEST_CASE_P(
-    KernelEnqueueFlags, EnumCapabilityTest,
+    KernelEnqueueFlags, EnumCapabilityTestV10,
     ::testing::ValuesIn(std::vector<EnumCapabilityCase>{
         CASE1(KERNEL_ENQ_FLAGS, KernelEnqueueFlagsNoWait, Kernel),
         CASE1(KERNEL_ENQ_FLAGS, KernelEnqueueFlagsWaitKernel, Kernel),
@@ -545,7 +559,7 @@ INSTANTIATE_TEST_CASE_P(
     }), );
 
 // See SPIR-V Section 3.30 Kernel Profiling Info
-INSTANTIATE_TEST_CASE_P(KernelProfilingInfo, EnumCapabilityTest,
+INSTANTIATE_TEST_CASE_P(KernelProfilingInfo, EnumCapabilityTestV10,
                         ::testing::ValuesIn(std::vector<EnumCapabilityCase>{
                             CASE0(KERNEL_PROFILING_INFO,
                                   KernelProfilingInfoMaskNone),
@@ -555,7 +569,7 @@ INSTANTIATE_TEST_CASE_P(KernelProfilingInfo, EnumCapabilityTest,
 
 // See SPIR-V Section 3.31 Capability
 INSTANTIATE_TEST_CASE_P(
-    Capability, EnumCapabilityTest,
+    Capability, EnumCapabilityTestV10,
     ::testing::ValuesIn(std::vector<EnumCapabilityCase>{
         CASE0(CAPABILITY, CapabilityMatrix),
         CASE1(CAPABILITY, CapabilityShader, Matrix),
index 9a57f13..e580905 100644 (file)
 
 namespace spvtest {
 
+// RAII for spv_context.
+struct ScopedContext {
+  ScopedContext(spv_target_env env = SPV_ENV_UNIVERSAL_1_0)
+      : context(spvContextCreate(env)) {}
+  ~ScopedContext() { spvContextDestroy(context); }
+  spv_context context;
+};
+
 // Common setup for TextToBinary tests. SetText() should be called to populate
 // the actual test text.
 template <typename T>
@@ -42,14 +50,6 @@ class TextToBinaryTestBase : public T {
   // Offset into a SpirvVector at which the first instruction starts.
   static const SpirvVector::size_type kFirstInstruction = 5;
 
-  // RAII for spv_context.
-  struct ScopedContext {
-    ScopedContext(spv_target_env env = SPV_ENV_UNIVERSAL_1_0)
-        : context(spvContextCreate(env)) {}
-    ~ScopedContext() { spvContextDestroy(context); }
-    spv_context context;
-  };
-
   TextToBinaryTestBase() : diagnostic(nullptr), text(), binary(nullptr) {
     char textStr[] = "substitute the text member variable with your test";
     text = {textStr, strlen(textStr)};
index 36a5bae..ec94eec 100644 (file)
@@ -29,8 +29,8 @@
 
 #include "UnitSPIRV.h"
 
-#include "gmock/gmock.h"
 #include "TestFixture.h"
+#include "gmock/gmock.h"
 
 namespace {
 
@@ -140,22 +140,30 @@ TEST_F(OpEntryPointTest, WrongModel) {
 
 // Test OpExecutionMode
 
-using OpExecutionModeTest = spvtest::TextToBinaryTestBase<
-    ::testing::TestWithParam<EnumCase<SpvExecutionMode>>>;
+template <spv_target_env env>
+class OpExecutionModeTest
+    : public spvtest::TextToBinaryTestBase<
+          ::testing::TestWithParam<EnumCase<SpvExecutionMode>>> {
+ protected:
+  const spv_target_env env_ = env;
+};
+
+using OpExecutionModeTestV10 = OpExecutionModeTest<SPV_ENV_UNIVERSAL_1_0>;
+using OpExecutionModeTestV11 = OpExecutionModeTest<SPV_ENV_UNIVERSAL_1_1>;
 
-TEST_P(OpExecutionModeTest, AnyExecutionMode) {
+TEST_P(OpExecutionModeTestV10, AnyExecutionMode) {
   // This string should assemble, but should not validate.
   std::stringstream input;
   input << "OpExecutionMode %1 " << GetParam().name();
   for (auto operand : GetParam().operands()) input << " " << operand;
-  EXPECT_THAT(CompiledInstructions(input.str()),
+  EXPECT_THAT(CompiledInstructions(input.str(), env_),
               Eq(MakeInstruction(SpvOpExecutionMode, {1, GetParam().value()},
                                  GetParam().operands())));
 }
 
 #define CASE(NAME) SpvExecutionMode##NAME, #NAME
 INSTANTIATE_TEST_CASE_P(
-    TextToBinaryExecutionMode, OpExecutionModeTest,
+    TextToBinaryExecutionMode, OpExecutionModeTestV10,
     ::testing::ValuesIn(std::vector<EnumCase<SpvExecutionMode>>{
         // The operand literal values are arbitrarily chosen,
         // but there are the right number of them.
@@ -190,15 +198,28 @@ INSTANTIATE_TEST_CASE_P(
         {CASE(OutputTriangleStrip), {}},
         {CASE(VecTypeHint), {96}},
         {CASE(ContractionOff), {}},
-    }),);
+    }), );
+
+INSTANTIATE_TEST_CASE_P(
+    TextToBinaryExecutionMode, OpExecutionModeTestV11,
+    ::testing::ValuesIn(std::vector<EnumCase<SpvExecutionMode>>{
+        // New in v1.1:
+        {CASE(SubgroupSize), {12}},
+        {CASE(SubgroupsPerWorkgroup), {64}},
+        // Spot checks for a few v1.0 modes:
+        {CASE(LocalSize), {64, 1, 2}},
+        {CASE(LocalSizeHint), {8, 2, 4}},
+        {CASE(Quads), {}},
+        {CASE(Isolines), {}},
+        {CASE(OutputVertices), {21}}}), );
 #undef CASE
 
-TEST_F(OpExecutionModeTest, WrongMode) {
+TEST_F(OpExecutionModeTestV10, WrongMode) {
   EXPECT_THAT(CompileFailure("OpExecutionMode %1 xxyyzz"),
               Eq("Invalid execution mode 'xxyyzz'."));
 }
 
-TEST_F(OpExecutionModeTest, TooManyModes) {
+TEST_F(OpExecutionModeTestV10, TooManyModes) {
   EXPECT_THAT(CompileFailure("OpExecutionMode %1 Xfb PointMode"),
               Eq("Expected <opcode> or <result-id> at the beginning of an "
                  "instruction, found 'PointMode'."));
diff --git a/test/TextToBinary.SubgroupDispatch.cpp b/test/TextToBinary.SubgroupDispatch.cpp
new file mode 100644 (file)
index 0000000..9d4086f
--- /dev/null
@@ -0,0 +1,129 @@
+// Copyright (c) 2016 Google
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and/or associated documentation files (the
+// "Materials"), to deal in the Materials without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Materials, and to
+// permit persons to whom the Materials are furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Materials.
+//
+// MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS
+// KHRONOS STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS
+// SPECIFICATIONS AND HEADER INFORMATION ARE LOCATED AT
+//    https://www.khronos.org/registry/
+//
+// THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
+
+// Assembler tests for instructions in the "Barrier Instructions" section
+// of the SPIR-V spec.
+
+#include "UnitSPIRV.h"
+
+#include "TestFixture.h"
+#include "gmock/gmock.h"
+
+namespace {
+
+using ::spvtest::MakeInstruction;
+using ::testing::Eq;
+using std::vector;
+
+using OpGetKernelLocalSizeForSubgroupCountTest = spvtest::TextToBinaryTest;
+
+TEST_F(OpGetKernelLocalSizeForSubgroupCountTest, OpcodeUnrecognizedInV10) {
+  EXPECT_THAT(
+      CompileFailure("%res = OpGetKernelLocalSizeForSubgroupCount %type "
+                     "%sgcount %invoke %param %param_size %param_align",
+                     SPV_ENV_UNIVERSAL_1_0),
+      Eq("Invalid Opcode name 'OpGetKernelLocalSizeForSubgroupCount'"));
+}
+
+TEST_F(OpGetKernelLocalSizeForSubgroupCountTest, ArgumentCount) {
+  EXPECT_THAT(CompileFailure("OpGetKernelLocalSizeForSubgroupCount",
+                             SPV_ENV_UNIVERSAL_1_1),
+              Eq("Expected <result-id> at the beginning of an instruction, "
+                 "found 'OpGetKernelLocalSizeForSubgroupCount'."));
+  EXPECT_THAT(CompileFailure("%res = OpGetKernelLocalSizeForSubgroupCount",
+                             SPV_ENV_UNIVERSAL_1_1),
+              Eq("Expected operand, found end of stream."));
+  EXPECT_THAT(
+      CompileFailure("%1 = OpGetKernelLocalSizeForSubgroupCount %2 %3 %4 %5 %6",
+                     SPV_ENV_UNIVERSAL_1_1),
+      Eq("Expected operand, found end of stream."));
+  EXPECT_THAT(
+      CompiledInstructions("%res = OpGetKernelLocalSizeForSubgroupCount %type "
+                           "%sgcount %invoke %param %param_size %param_align",
+                           SPV_ENV_UNIVERSAL_1_1),
+      Eq(MakeInstruction(SpvOpGetKernelLocalSizeForSubgroupCount,
+                         {1, 2, 3, 4, 5, 6, 7})));
+  EXPECT_THAT(
+      CompileFailure("%res = OpGetKernelLocalSizeForSubgroupCount %type "
+                     "%sgcount %invoke %param %param_size %param_align %extra",
+                     SPV_ENV_UNIVERSAL_1_1),
+      Eq("Expected '=', found end of stream."));
+}
+
+TEST_F(OpGetKernelLocalSizeForSubgroupCountTest, ArgumentTypes) {
+  EXPECT_THAT(CompileFailure(
+                  "%1 = OpGetKernelLocalSizeForSubgroupCount 2 %3 %4 %5 %6 %7",
+                  SPV_ENV_UNIVERSAL_1_1),
+              Eq("Expected id to start with %."));
+  EXPECT_THAT(
+      CompileFailure(
+          "%1 = OpGetKernelLocalSizeForSubgroupCount %2 %3 %4 %5 %6 \"abc\"",
+          SPV_ENV_UNIVERSAL_1_1),
+      Eq("Expected id to start with %."));
+}
+
+using OpGetKernelMaxNumSubgroupsTest = spvtest::TextToBinaryTest;
+
+TEST_F(OpGetKernelMaxNumSubgroupsTest, OpcodeUnrecognizedInV10) {
+  EXPECT_THAT(CompileFailure("%res = OpGetKernelLocalSizeForSubgroupCount "
+                             "%type %invoke %param %param_size %param_align",
+                             SPV_ENV_UNIVERSAL_1_0),
+              Eq("Invalid Opcode name 'OpGetKernelLocalSizeForSubgroupCount'"));
+}
+
+TEST_F(OpGetKernelMaxNumSubgroupsTest, ArgumentCount) {
+  EXPECT_THAT(
+      CompileFailure("OpGetKernelMaxNumSubgroups", SPV_ENV_UNIVERSAL_1_1),
+      Eq("Expected <result-id> at the beginning of an instruction, found "
+         "'OpGetKernelMaxNumSubgroups'."));
+  EXPECT_THAT(CompileFailure("%res = OpGetKernelMaxNumSubgroups",
+                             SPV_ENV_UNIVERSAL_1_1),
+              Eq("Expected operand, found end of stream."));
+  EXPECT_THAT(CompileFailure("%1 = OpGetKernelMaxNumSubgroups %2 %3 %4 %5",
+                             SPV_ENV_UNIVERSAL_1_1),
+              Eq("Expected operand, found end of stream."));
+  EXPECT_THAT(
+      CompiledInstructions("%res = OpGetKernelMaxNumSubgroups %type "
+                           "%invoke %param %param_size %param_align",
+                           SPV_ENV_UNIVERSAL_1_1),
+      Eq(MakeInstruction(SpvOpGetKernelMaxNumSubgroups, {1, 2, 3, 4, 5, 6})));
+  EXPECT_THAT(CompileFailure("%res = OpGetKernelMaxNumSubgroups %type %invoke "
+                             "%param %param_size %param_align %extra",
+                             SPV_ENV_UNIVERSAL_1_1),
+              Eq("Expected '=', found end of stream."));
+}
+
+TEST_F(OpGetKernelMaxNumSubgroupsTest, ArgumentTypes) {
+  EXPECT_THAT(CompileFailure("%1 = OpGetKernelMaxNumSubgroups 2 %3 %4 %5 %6",
+                             SPV_ENV_UNIVERSAL_1_1),
+              Eq("Expected id to start with %."));
+  EXPECT_THAT(
+      CompileFailure("%1 = OpGetKernelMaxNumSubgroups %2 %3 %4 %5 \"abc\"",
+                     SPV_ENV_UNIVERSAL_1_1),
+      Eq("Expected id to start with %."));
+}
+
+}  // anonymous namespace
index a1a58e3..da3fecf 100644 (file)
@@ -44,6 +44,7 @@ using libspirv::AssemblyGrammar;
 using spvtest::AutoText;
 using spvtest::Concatenate;
 using spvtest::MakeInstruction;
+using spvtest::ScopedContext;
 using spvtest::TextToBinaryTest;
 using testing::Eq;
 using testing::IsNull;
index 7269362..7b9e195 100644 (file)
 // Validation tests for Logical Layout
 
 #include <gmock/gmock.h>
+#include "TestFixture.h"
 #include "UnitSPIRV.h"
 #include "ValidateFixtures.h"
+#include "source/assembly_grammar.h"
 
 #include <sstream>
 #include <string>
 
 namespace {
 
-
-using std::pair;
+using spvtest::ScopedContext;
 using std::make_pair;
-using std::stringstream;
+using std::pair;
 using std::string;
+using std::stringstream;
 using std::tuple;
 using std::vector;
-
 using testing::Combine;
 using testing::Values;
 using testing::ValuesIn;
@@ -53,7 +54,7 @@ using ValidateCapability =
     spvtest::ValidateBase<tuple<string, pair<string, vector<string>>>>;
 
 TEST_F(ValidateCapability, Default) {
-    const char str[] = R"(
+  const char str[] = R"(
             OpCapability Kernel
             OpCapability Matrix
             OpMemoryModel Logical OpenCL
@@ -125,7 +126,8 @@ const vector<string>& AllCapabilities() {
     "GeometryStreams",
     "StorageImageReadWithoutFormat",
     "StorageImageWriteWithoutFormat",
-    "MultiViewport"};
+    "MultiViewport",
+    "SubgroupDispatch"};
   return *r;
 }
 
@@ -252,7 +254,8 @@ const vector<string>& KernelDependencies() {
   "Pipes",
   "DeviceEnqueue",
   "LiteralSampler",
-  "Int8"};
+  "Int8",
+  "SubgroupDispatch"};
   return *r;
 }
 
@@ -622,9 +625,11 @@ INSTANTIATE_TEST_CASE_P(Decoration, ValidateCapability,
 make_pair(string(kOpenCLMemoryModel) +
           "OpDecorate %intt RelaxedPrecision\n"
           "%intt = OpTypeInt 32 1\n", ShaderDependencies()),
+#if 0  // TODO(dekimir): re-enable this (adding Kernel) once 1.1 is the default
 make_pair(string(kOpenCLMemoryModel) +
           "OpDecorate %intt SpecId 1\n"
           "%intt = OpTypeInt 32 1\n", ShaderDependencies()),
+#endif  // 0
 make_pair(string(kOpenCLMemoryModel) +
           "OpDecorate %intt Block\n"
           "%intt = OpTypeInt 32 1\n", ShaderDependencies()),
@@ -947,10 +952,19 @@ INSTANTIATE_TEST_CASE_P(
                make_pair(ImageOperandsTemplate("Sample|MinLod %izero %fzero"),
                          vector<string>{"MinLod"}),
                make_pair(ImageOperandsTemplate("Lod|Sample %fzero %izero"),
-                         AllCapabilities()))),);
+                         AllCapabilities()))), );
 
 // TODO(umar): Instruction capability checks
 
+// True if capability exists in env.
+bool Exists(const std::string& capability, spv_target_env env) {
+  spv_operand_desc dummy;
+  return SPV_SUCCESS ==
+         libspirv::AssemblyGrammar(ScopedContext(env).context)
+             .lookupOperand(SPV_OPERAND_TYPE_CAPABILITY, capability.c_str(),
+                            capability.size(), &dummy);
+}
+
 TEST_P(ValidateCapability, Capability) {
   string capability;
   pair<string, vector<string>> operation;
@@ -973,8 +987,12 @@ TEST_P(ValidateCapability, Capability) {
     res = SPV_ERROR_INVALID_CAPABILITY;
   }
 
-  CompileSuccessfully(ss.str());
-  ASSERT_EQ(res, ValidateInstructions()) << ss.str();
+  spv_target_env env =
+      (capability.empty() || Exists(capability, SPV_ENV_UNIVERSAL_1_0))
+          ? SPV_ENV_UNIVERSAL_1_0
+          : SPV_ENV_UNIVERSAL_1_1;
+  CompileSuccessfully(ss.str(), env);
+  ASSERT_EQ(res, ValidateInstructions(env)) << ss.str();
 }
 
 }  // namespace anonymous
index 1830895..7467960 100644 (file)
 // Common validation fixtures for unit tests
 
 #include "ValidateFixtures.h"
-#include "UnitSPIRV.h"
 
 #include <functional>
 #include <tuple>
 #include <utility>
 
-namespace spvtest {
+#include "TestFixture.h"
 
-template <typename T>
-ValidateBase<T>::ValidateBase()
-    : context_(spvContextCreate(SPV_ENV_UNIVERSAL_1_0)),
-      binary_(),
-      diagnostic_() {}
+namespace spvtest {
 
 template <typename T>
-ValidateBase<T>::~ValidateBase() {
-  spvContextDestroy(context_);
-}
+ValidateBase<T>::ValidateBase() : binary_(), diagnostic_() {}
 
 template <typename T>
 spv_const_binary ValidateBase<T>::get_const_binary() {
@@ -61,18 +54,21 @@ void ValidateBase<T>::TearDown() {
 }
 
 template <typename T>
-void ValidateBase<T>::CompileSuccessfully(std::string code) {
+void ValidateBase<T>::CompileSuccessfully(std::string code,
+                                          spv_target_env env) {
   spv_diagnostic diagnostic = nullptr;
-  ASSERT_EQ(SPV_SUCCESS, spvTextToBinary(context_, code.c_str(), code.size(),
-                                         &binary_, &diagnostic))
+  ASSERT_EQ(SPV_SUCCESS,
+            spvTextToBinary(ScopedContext(env).context, code.c_str(),
+                            code.size(), &binary_, &diagnostic))
       << "ERROR: " << diagnostic->error
       << "\nSPIR-V could not be compiled into binary:\n"
       << code;
 }
 
 template <typename T>
-spv_result_t ValidateBase<T>::ValidateInstructions() {
-  return spvValidate(context_, get_const_binary(), &diagnostic_);
+spv_result_t ValidateBase<T>::ValidateInstructions(spv_target_env env) {
+  return spvValidate(ScopedContext(env).context, get_const_binary(),
+                     &diagnostic_);
 }
 
 template <typename T>
index 36b2a84..6cc816b 100644 (file)
@@ -38,23 +38,22 @@ class ValidateBase : public ::testing::Test,
                      public ::testing::WithParamInterface<T> {
  public:
   ValidateBase();
-  ~ValidateBase();
 
   virtual void TearDown();
 
   // Returns the a spv_const_binary struct
   spv_const_binary get_const_binary();
 
-  void CompileSuccessfully(std::string code);
+  void CompileSuccessfully(std::string code,
+                           spv_target_env env = SPV_ENV_UNIVERSAL_1_0);
 
   // Performs validation on the SPIR-V code and compares the result of the
   // spvValidate function
-  spv_result_t ValidateInstructions();
+  spv_result_t ValidateInstructions(spv_target_env env = SPV_ENV_UNIVERSAL_1_0);
 
   std::string getDiagnosticString();
   spv_position_t getErrorPosition();
 
-  spv_context context_;
   spv_binary binary_;
   spv_diagnostic diagnostic_;
 };
index c125a74..4b0da84 100644 (file)
@@ -38,6 +38,7 @@
 namespace {
 
 using ::testing::ValuesIn;
+using spvtest::ScopedContext;
 using std::ostringstream;
 using std::string;
 using std::vector;