Add tests for SubgroupDispatch.

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.
This commit is contained in:
Dejan Mircevski 2016-04-21 15:46:08 -04:00
parent 2d975d54ae
commit 2ea54f5d1b
16 changed files with 270 additions and 81 deletions

View File

@ -28,6 +28,7 @@
namespace {
using spvtest::ScopedContext;
using spvtest::TextToBinaryTest;
TEST_F(TextToBinaryTest, NotPlacingResultIDAtTheBeginning) {

View 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.

View 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;

View File

@ -33,12 +33,14 @@
#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)) {}

View 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

View File

@ -37,6 +37,7 @@ namespace {
using spvtest::Concatenate;
using spvtest::MakeInstruction;
using spvtest::ScopedContext;
using spvtest::TextToBinaryTest;
using spvutils::BitwiseCast;
using ::testing::ElementsAre;

View 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

View 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.
};
TEST_P(EnumCapabilityTest, Sample) {
using EnumCapabilityTestV10 = EnumCapabilityTest<SPV_ENV_UNIVERSAL_1_0>;
using EnumCapabilityTestV11 = EnumCapabilityTest<SPV_ENV_UNIVERSAL_1_1>;
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),

View File

@ -31,6 +31,14 @@
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)};

View 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;
};
TEST_P(OpExecutionModeTest, AnyExecutionMode) {
using OpExecutionModeTestV10 = OpExecutionModeTest<SPV_ENV_UNIVERSAL_1_0>;
using OpExecutionModeTestV11 = OpExecutionModeTest<SPV_ENV_UNIVERSAL_1_1>;
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'."));

View File

@ -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

View 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;

View File

@ -27,8 +27,10 @@
// 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>
@ -37,14 +39,13 @@
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

View File

@ -27,24 +27,17 @@
// Common validation fixtures for unit tests
#include "ValidateFixtures.h"
#include "UnitSPIRV.h"
#include <functional>
#include <tuple>
#include <utility>
#include "TestFixture.h"
namespace spvtest {
template <typename T>
ValidateBase<T>::ValidateBase()
: context_(spvContextCreate(SPV_ENV_UNIVERSAL_1_0)),
binary_(),
diagnostic_() {}
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>

View 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_;
};

View File

@ -38,6 +38,7 @@
namespace {
using ::testing::ValuesIn;
using spvtest::ScopedContext;
using std::ostringstream;
using std::string;
using std::vector;