diff --git a/CMakeLists.txt b/CMakeLists.txt index 1e07b0d5..58d1bef3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -176,6 +176,7 @@ if (NOT ${SPIRV_SKIP_EXECUTABLES}) ${CMAKE_CURRENT_SOURCE_DIR}/test/ImmediateInt.cpp ${CMAKE_CURRENT_SOURCE_DIR}/test/LibspirvMacros.cpp ${CMAKE_CURRENT_SOURCE_DIR}/test/NamedId.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/test/OperandCapabilities.cpp ${CMAKE_CURRENT_SOURCE_DIR}/test/OperandPattern.cpp ${CMAKE_CURRENT_SOURCE_DIR}/test/OpcodeMake.cpp ${CMAKE_CURRENT_SOURCE_DIR}/test/OpcodeRequiresCapabilities.cpp diff --git a/include/libspirv/libspirv.h b/include/libspirv/libspirv.h index 5feecdc7..43f0e52d 100644 --- a/include/libspirv/libspirv.h +++ b/include/libspirv/libspirv.h @@ -159,6 +159,8 @@ typedef enum spv_operand_type_t { SPV_OPERAND_TYPE_SAMPLER_ADDRESSING_MODE, SPV_OPERAND_TYPE_SAMPLER_FILTER_MODE, SPV_OPERAND_TYPE_SAMPLER_IMAGE_FORMAT, + SPV_OPERAND_TYPE_IMAGE_CHANNEL_ORDER, + SPV_OPERAND_TYPE_IMAGE_CHANNEL_DATA_TYPE, SPV_OPERAND_TYPE_FP_FAST_MATH_MODE, SPV_OPERAND_TYPE_FP_ROUNDING_MODE, SPV_OPERAND_TYPE_LINKAGE_TYPE, diff --git a/source/operand.cpp b/source/operand.cpp index e53c48f8..2099ab67 100644 --- a/source/operand.cpp +++ b/source/operand.cpp @@ -127,17 +127,17 @@ static const spv_operand_desc_t memoryModelEntries[] = { }; // Execution mode requiring the given capability and having no operands. -#define ExecMode0(mode, cap) \ - #mode, ExecutionMode##mode, SPV_OPCODE_FLAGS_CAPABILITIES, Capability##cap, \ - { \ - SPV_OPERAND_TYPE_NONE \ +#define ExecMode0(mode, cap) \ + #mode, ExecutionMode##mode, SPV_OPCODE_FLAGS_CAPABILITIES, \ + SPV_CAPABILITY_AS_MASK(Capability##cap), { \ + SPV_OPERAND_TYPE_NONE \ } // Execution mode requiring the given capability and having one literal number // operand. -#define ExecMode1(mode, cap) \ - #mode, ExecutionMode##mode, SPV_OPCODE_FLAGS_CAPABILITIES, Capability##cap, \ - { \ - SPV_OPERAND_TYPE_LITERAL_NUMBER, SPV_OPERAND_TYPE_NONE \ +#define ExecMode1(mode, cap) \ + #mode, ExecutionMode##mode, SPV_OPCODE_FLAGS_CAPABILITIES, \ + SPV_CAPABILITY_AS_MASK(Capability##cap), { \ + SPV_OPERAND_TYPE_LITERAL_NUMBER, SPV_OPERAND_TYPE_NONE \ } static const spv_operand_desc_t executionModeEntries[] = { {ExecMode1(Invocations, Geometry)}, @@ -251,7 +251,7 @@ static const spv_operand_desc_t storageClassEntries[] = { {"AtomicCounter", StorageClassAtomicCounter, SPV_OPCODE_FLAGS_CAPABILITIES, - SPV_CAPABILITY_AS_MASK(CapabilityShader), + SPV_CAPABILITY_AS_MASK(CapabilityAtomicStorage), {SPV_OPERAND_TYPE_NONE}}, {"Image", StorageClassImage, @@ -261,8 +261,11 @@ static const spv_operand_desc_t storageClassEntries[] = { }; static const spv_operand_desc_t dimensionalityEntries[] = { - // TODO(dneto): Update capability dependencies for Rev32 - {"1D", Dim1D, SPV_OPCODE_FLAGS_NONE, 0, {SPV_OPERAND_TYPE_NONE}}, + {"1D", + Dim1D, + SPV_OPCODE_FLAGS_CAPABILITIES, + SPV_CAPABILITY_AS_MASK(CapabilitySampled1D), + {SPV_OPERAND_TYPE_NONE}}, {"2D", Dim2D, SPV_OPCODE_FLAGS_NONE, 0, {SPV_OPERAND_TYPE_NONE}}, {"3D", Dim3D, SPV_OPCODE_FLAGS_NONE, 0, {SPV_OPERAND_TYPE_NONE}}, {"Cube", @@ -273,9 +276,13 @@ static const spv_operand_desc_t dimensionalityEntries[] = { {"Rect", DimRect, SPV_OPCODE_FLAGS_CAPABILITIES, - SPV_CAPABILITY_AS_MASK(CapabilityShader), + SPV_CAPABILITY_AS_MASK(CapabilitySampledRect), + {SPV_OPERAND_TYPE_NONE}}, + {"Buffer", + DimBuffer, + SPV_OPCODE_FLAGS_CAPABILITIES, + SPV_CAPABILITY_AS_MASK(CapabilitySampledBuffer), {SPV_OPERAND_TYPE_NONE}}, - {"Buffer", DimBuffer, SPV_OPCODE_FLAGS_NONE, 0, {SPV_OPERAND_TYPE_NONE}}, {"InputTarget", DimInputTarget, SPV_OPCODE_FLAGS_CAPABILITIES, @@ -325,61 +332,121 @@ static const spv_operand_desc_t samplerFilterModeEntries[] = { }; static const spv_operand_desc_t samplerImageFormatEntries[] = { -// In Rev31, all the cases depend on the Shader capability. -// TODO(dneto): In Rev32, many of these depend on the AdvancedFormats -// capability instead. -#define CASE(NAME) \ +#define CASE0(NAME) \ + { \ + #NAME, ImageFormat##NAME, 0, 0, { SPV_OPERAND_TYPE_NONE } \ + } +#define CASE(NAME, CAP) \ { \ #NAME, ImageFormat##NAME, SPV_OPCODE_FLAGS_CAPABILITIES, \ - SPV_CAPABILITY_AS_MASK(CapabilityShader), { \ + SPV_CAPABILITY_AS_MASK(Capability##CAP), { \ SPV_OPERAND_TYPE_NONE \ } \ } // clang-format off - CASE(Unknown), - CASE(Rgba32f), - CASE(Rgba16f), - CASE(R32f), - CASE(Rgba8), - CASE(Rgba8Snorm), - CASE(Rg32f), - CASE(Rg16f), - CASE(R11fG11fB10f), - CASE(R16f), - CASE(Rgba16), - CASE(Rgb10A2), - CASE(Rg16), - CASE(Rg8), - CASE(R16), - CASE(R8), - CASE(Rgba16Snorm), - CASE(Rg16Snorm), - CASE(Rg8Snorm), - CASE(R16Snorm), - CASE(R8Snorm), - CASE(Rgba32i), - CASE(Rgba16i), - CASE(Rgba8i), - CASE(R32i), - CASE(Rg32i), - CASE(Rg16i), - CASE(Rg8i), - CASE(R16i), - CASE(R8i), - CASE(Rgba32ui), - CASE(Rgba16ui), - CASE(Rgba8ui), - CASE(R32ui), - CASE(Rgb10a2ui), - CASE(Rg32ui), - CASE(Rg16ui), - CASE(Rg8ui), - CASE(R16ui), - CASE(R8ui), + CASE0(Unknown), + CASE(Rgba32f, Shader), + CASE(Rgba16f, Shader), + CASE(R32f, Shader), + CASE(Rgba8, Shader), + CASE(Rgba8Snorm, Shader), + CASE(Rg32f, AdvancedFormats), + CASE(Rg16f, AdvancedFormats), + CASE(R11fG11fB10f, AdvancedFormats), + CASE(R16f, AdvancedFormats), + CASE(Rgba16, AdvancedFormats), + CASE(Rgb10A2, AdvancedFormats), + CASE(Rg16, AdvancedFormats), + CASE(Rg8, AdvancedFormats), + CASE(R16, AdvancedFormats), + CASE(R8, AdvancedFormats), + CASE(Rgba16Snorm, AdvancedFormats), + CASE(Rg16Snorm, AdvancedFormats), + CASE(Rg8Snorm, AdvancedFormats), + CASE(R16Snorm, AdvancedFormats), + CASE(R8Snorm, AdvancedFormats), + CASE(Rgba32i, Shader), + CASE(Rgba16i, Shader), + CASE(Rgba8i, Shader), + CASE(R32i, Shader), + CASE(Rg32i, AdvancedFormats), + CASE(Rg16i, AdvancedFormats), + CASE(Rg8i, AdvancedFormats), + CASE(R16i, AdvancedFormats), + CASE(R8i, AdvancedFormats), + CASE(Rgba32ui, Shader), + CASE(Rgba16ui, Shader), + CASE(Rgba8ui, Shader), + CASE(R32ui, Shader), + CASE(Rgb10a2ui, AdvancedFormats), + CASE(Rg32ui, AdvancedFormats), + CASE(Rg16ui, AdvancedFormats), + CASE(Rg8ui, AdvancedFormats), + CASE(R16ui, AdvancedFormats), + CASE(R8ui, AdvancedFormats), // clang-format on #undef CASE }; +// All image channel orders depend on the Kernel capability. +#define CASE(NAME) \ + { \ + #NAME, ImageChannelOrder##NAME, SPV_OPCODE_FLAGS_CAPABILITIES, \ + SPV_CAPABILITY_AS_MASK(CapabilityKernel), { \ + SPV_OPERAND_TYPE_NONE \ + } \ + } +static const spv_operand_desc_t imageChannelOrderEntries[] = { + CASE(R), + CASE(A), + CASE(RG), + CASE(RA), + CASE(RGB), + CASE(RGBA), + CASE(BGRA), + CASE(ARGB), + CASE(Intensity), + CASE(Luminance), + CASE(Rx), + CASE(RGx), + CASE(RGBx), + CASE(Depth), + CASE(DepthStencil), + CASE(sRGB), + CASE(sRGBx), + CASE(sRGBA), + CASE(sBGRA), +}; +#undef CASE + +// All image channel data types depend on the Kernel capability. +#define CASE(NAME) \ + { \ + #NAME, ImageChannelDataType##NAME, SPV_OPCODE_FLAGS_CAPABILITIES, \ + SPV_CAPABILITY_AS_MASK(CapabilityKernel), { \ + SPV_OPERAND_TYPE_NONE \ + } \ + } +static const spv_operand_desc_t imageChannelDataTypeEntries[] = { + CASE(SnormInt8), + CASE(SnormInt16), + CASE(UnormInt8), + CASE(UnormInt16), + CASE(UnormShort565), + CASE(UnormShort555), + CASE(UnormInt101010), + CASE(SignedInt8), + CASE(SignedInt16), + CASE(SignedInt32), + CASE(UnsignedInt8), + CASE(UnsignedInt16), + CASE(UnsignedInt32), + CASE(HalfFloat), + CASE(Float), + CASE(UnormInt24), +}; +#undef CASE + // Image operand definitions. Each enum value is a mask. When that mask // bit is set, the instruction should have further ID operands. // Some mask values depend on a capability. @@ -718,12 +785,12 @@ static const spv_operand_desc_t decorationEntries[] = { {"XfbBuffer", DecorationXfbBuffer, SPV_OPCODE_FLAGS_CAPABILITIES, - SPV_CAPABILITY_AS_MASK(CapabilityShader), + SPV_CAPABILITY_AS_MASK(CapabilityTransformFeedback), {SPV_OPERAND_TYPE_LITERAL_NUMBER, SPV_OPERAND_TYPE_NONE}}, {"XfbStride", DecorationXfbStride, SPV_OPCODE_FLAGS_CAPABILITIES, - SPV_CAPABILITY_AS_MASK(CapabilityShader), + SPV_CAPABILITY_AS_MASK(CapabilityTransformFeedback), {SPV_OPERAND_TYPE_LITERAL_NUMBER, SPV_OPERAND_TYPE_NONE}}, {"FuncParamAttr", DecorationFuncParamAttr, @@ -1318,6 +1385,12 @@ static const spv_operand_desc_group_t opcodeEntryTypes[] = { {SPV_OPERAND_TYPE_SAMPLER_IMAGE_FORMAT, sizeof(samplerImageFormatEntries) / sizeof(spv_operand_desc_t), samplerImageFormatEntries}, + {SPV_OPERAND_TYPE_IMAGE_CHANNEL_ORDER, + sizeof(imageChannelOrderEntries) / sizeof(spv_operand_desc_t), + imageChannelOrderEntries}, + {SPV_OPERAND_TYPE_IMAGE_CHANNEL_DATA_TYPE, + sizeof(imageChannelDataTypeEntries) / sizeof(spv_operand_desc_t), + imageChannelDataTypeEntries}, {SPV_OPERAND_TYPE_OPTIONAL_IMAGE, sizeof(imageOperandEntries) / sizeof(spv_operand_desc_t), imageOperandEntries}, diff --git a/test/OperandCapabilities.cpp b/test/OperandCapabilities.cpp new file mode 100644 index 00000000..80099a75 --- /dev/null +++ b/test/OperandCapabilities.cpp @@ -0,0 +1,401 @@ +// Copyright (c) 2015 The Khronos Group Inc. +// +// 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. + +// Test capability dependencies for enums. + +#include "UnitSPIRV.h" + +namespace { + +// A test case for mapping an enum to a capability mask. +struct EnumCapabilityCase { + spv_operand_type_t type; + uint32_t value; + uint64_t expected_mask; +}; + +using EnumCapabilityTest = ::testing::TestWithParam; + +TEST_P(EnumCapabilityTest, Sample) { + spv_operand_table operandTable; + ASSERT_EQ(SPV_SUCCESS, spvOperandTableGet(&operandTable)); + spv_operand_desc entry; + ASSERT_EQ(SPV_SUCCESS, + spvOperandTableValueLookup(operandTable, GetParam().type, + GetParam().value, &entry)); + EXPECT_EQ(GetParam().expected_mask, entry->capabilities); +} + +#define CASE0(TYPE, VALUE) \ + { SPV_OPERAND_TYPE_##TYPE, uint32_t(spv::VALUE), 0 } +#define CASE1(TYPE, VALUE, CAP) \ + { \ + SPV_OPERAND_TYPE_##TYPE, uint32_t(spv::VALUE), \ + SPV_CAPABILITY_AS_MASK(spv::Capability##CAP) \ + } +#define CASE2(TYPE, VALUE, CAP1, CAP2) \ + { \ + SPV_OPERAND_TYPE_##TYPE, uint32_t(spv::VALUE), \ + (SPV_CAPABILITY_AS_MASK(spv::Capability##CAP1) | \ + SPV_CAPABILITY_AS_MASK(spv::Capability##CAP2)) \ + } + +// See SPIR-V Section 3.3 Execution Model +INSTANTIATE_TEST_CASE_P( + ExecutionModel, EnumCapabilityTest, + ::testing::ValuesIn( std::vector{ + CASE1(EXECUTION_MODEL, ExecutionModelVertex, Shader), + CASE1(EXECUTION_MODEL, ExecutionModelTessellationControl, Tessellation), + CASE1(EXECUTION_MODEL, ExecutionModelTessellationEvaluation, Tessellation), + CASE1(EXECUTION_MODEL, ExecutionModelGeometry, Geometry), + CASE1(EXECUTION_MODEL, ExecutionModelFragment, Shader), + CASE1(EXECUTION_MODEL, ExecutionModelGLCompute, Shader), + CASE1(EXECUTION_MODEL, ExecutionModelKernel, Kernel), + })); + +// See SPIR-V Section 3.4 Addressing Model +INSTANTIATE_TEST_CASE_P( + AddressingModel, EnumCapabilityTest, + ::testing::ValuesIn(std::vector{ + CASE0(ADDRESSING_MODEL, AddressingModelLogical), + CASE1(ADDRESSING_MODEL, AddressingModelPhysical32, Addresses), + CASE1(ADDRESSING_MODEL, AddressingModelPhysical64, Addresses), + })); + +// See SPIR-V Section 3.5 Memory Model +INSTANTIATE_TEST_CASE_P( + MemoryModel, EnumCapabilityTest, + ::testing::ValuesIn(std::vector{ + CASE1(MEMORY_MODEL, MemoryModelSimple, Shader), + CASE1(MEMORY_MODEL, MemoryModelGLSL450, Shader), + CASE1(MEMORY_MODEL, MemoryModelOpenCL, Kernel), + })); + +// See SPIR-V Section 3.6 Execution Mode +INSTANTIATE_TEST_CASE_P( + ExecutionMode, EnumCapabilityTest, + ::testing::ValuesIn(std::vector{ + CASE1(EXECUTION_MODE, ExecutionModeInvocations, Geometry), + CASE1(EXECUTION_MODE, ExecutionModeSpacingEqual, Tessellation), + CASE1(EXECUTION_MODE, ExecutionModeSpacingFractionalEven, Tessellation), + CASE1(EXECUTION_MODE, ExecutionModeSpacingFractionalOdd, Tessellation), + CASE1(EXECUTION_MODE, ExecutionModeVertexOrderCw, Tessellation), + CASE1(EXECUTION_MODE, ExecutionModeVertexOrderCcw, Tessellation), + CASE1(EXECUTION_MODE, ExecutionModePixelCenterInteger, Shader), + CASE1(EXECUTION_MODE, ExecutionModeOriginUpperLeft, Shader), + CASE1(EXECUTION_MODE, ExecutionModeOriginLowerLeft, Shader), + CASE1(EXECUTION_MODE, ExecutionModeEarlyFragmentTests, Shader), + CASE1(EXECUTION_MODE, ExecutionModePointMode, Tessellation), + CASE1(EXECUTION_MODE, ExecutionModeXfb, TransformFeedback), + CASE1(EXECUTION_MODE, ExecutionModeDepthReplacing, Shader), + CASE1(EXECUTION_MODE, ExecutionModeDepthGreater, Shader), + CASE1(EXECUTION_MODE, ExecutionModeDepthLess, Shader), + CASE1(EXECUTION_MODE, ExecutionModeDepthUnchanged, Shader), + CASE0(EXECUTION_MODE, ExecutionModeLocalSize), + CASE1(EXECUTION_MODE, ExecutionModeLocalSizeHint, Kernel), + CASE1(EXECUTION_MODE, ExecutionModeInputPoints, Geometry), + CASE1(EXECUTION_MODE, ExecutionModeInputLines, Geometry), + CASE1(EXECUTION_MODE, ExecutionModeInputLinesAdjacency, Geometry), + CASE2(EXECUTION_MODE, ExecutionModeInputTriangles, Geometry, Tessellation), + CASE1(EXECUTION_MODE, ExecutionModeInputTrianglesAdjacency, Geometry), + CASE1(EXECUTION_MODE, ExecutionModeInputQuads, Tessellation), + CASE1(EXECUTION_MODE, ExecutionModeInputIsolines, Tessellation), + CASE2(EXECUTION_MODE, ExecutionModeOutputVertices, Geometry, Tessellation), + CASE1(EXECUTION_MODE, ExecutionModeOutputPoints, Geometry), + CASE1(EXECUTION_MODE, ExecutionModeOutputLineStrip, Geometry), + CASE1(EXECUTION_MODE, ExecutionModeOutputTriangleStrip, Geometry), + CASE1(EXECUTION_MODE, ExecutionModeVecTypeHint, Kernel), + CASE1(EXECUTION_MODE, ExecutionModeContractionOff, Kernel), + CASE1(EXECUTION_MODE, ExecutionModeIndependentForwardProgress, Kernel), + })); + +// See SPIR-V Section 3.7 Storage Class +INSTANTIATE_TEST_CASE_P( + StorageClass, EnumCapabilityTest, + ::testing::ValuesIn(std::vector{ + CASE0(STORAGE_CLASS, StorageClassUniformConstant), + CASE1(STORAGE_CLASS, StorageClassInput, Shader), + CASE1(STORAGE_CLASS, StorageClassUniform, Shader), + CASE1(STORAGE_CLASS, StorageClassOutput, Shader), + CASE0(STORAGE_CLASS, StorageClassWorkgroupLocal), + CASE0(STORAGE_CLASS, StorageClassWorkgroupGlobal), + CASE1(STORAGE_CLASS, StorageClassPrivateGlobal, Shader), + CASE0(STORAGE_CLASS, StorageClassFunction), + CASE1(STORAGE_CLASS, StorageClassGeneric, Kernel), + CASE1(STORAGE_CLASS, StorageClassPushConstant, Shader), + CASE1(STORAGE_CLASS, StorageClassAtomicCounter, AtomicStorage), + CASE0(STORAGE_CLASS, StorageClassImage), + })); + +// See SPIR-V Section 3.8 Dim +INSTANTIATE_TEST_CASE_P( + Dim, EnumCapabilityTest, + ::testing::ValuesIn(std::vector{ + CASE1(DIMENSIONALITY, Dim1D, Sampled1D), + CASE0(DIMENSIONALITY, Dim2D), + CASE0(DIMENSIONALITY, Dim3D), + CASE1(DIMENSIONALITY, DimCube, Shader), + CASE1(DIMENSIONALITY, DimRect, SampledRect), + CASE1(DIMENSIONALITY, DimBuffer, SampledBuffer), + CASE1(DIMENSIONALITY, DimInputTarget, InputTarget), + })); + +// See SPIR-V Section 3.9 Sampler Addressing Mode +INSTANTIATE_TEST_CASE_P( + SamplerAddressingMode, EnumCapabilityTest, + ::testing::ValuesIn(std::vector{ + CASE1(SAMPLER_ADDRESSING_MODE, SamplerAddressingModeNone, Kernel), + CASE1(SAMPLER_ADDRESSING_MODE, SamplerAddressingModeClampToEdge, Kernel), + CASE1(SAMPLER_ADDRESSING_MODE, SamplerAddressingModeClamp, Kernel), + CASE1(SAMPLER_ADDRESSING_MODE, SamplerAddressingModeRepeat, Kernel), + CASE1(SAMPLER_ADDRESSING_MODE, SamplerAddressingModeRepeatMirrored, Kernel), + })); + +// See SPIR-V Section 3.10 Sampler Filter Mode +INSTANTIATE_TEST_CASE_P( + SamplerFilterMode, EnumCapabilityTest, + ::testing::ValuesIn(std::vector{ + CASE1(SAMPLER_FILTER_MODE, SamplerFilterModeNearest, Kernel), + CASE1(SAMPLER_FILTER_MODE, SamplerFilterModeLinear, Kernel), + })); + +// See SPIR-V Section 3.11 Image Format +INSTANTIATE_TEST_CASE_P( + ImageFormat, EnumCapabilityTest, + ::testing::ValuesIn(std::vector{ + CASE0(SAMPLER_IMAGE_FORMAT, ImageFormatUnknown), + CASE1(SAMPLER_IMAGE_FORMAT, ImageFormatRgba32f, Shader), + CASE1(SAMPLER_IMAGE_FORMAT, ImageFormatRgba16f, Shader), + CASE1(SAMPLER_IMAGE_FORMAT, ImageFormatR32f, Shader), + CASE1(SAMPLER_IMAGE_FORMAT, ImageFormatRgba8, Shader), + CASE1(SAMPLER_IMAGE_FORMAT, ImageFormatRgba8Snorm, Shader), + CASE1(SAMPLER_IMAGE_FORMAT, ImageFormatRg32f, AdvancedFormats), + CASE1(SAMPLER_IMAGE_FORMAT, ImageFormatRg16f, AdvancedFormats), + CASE1(SAMPLER_IMAGE_FORMAT, ImageFormatR11fG11fB10f, AdvancedFormats), + CASE1(SAMPLER_IMAGE_FORMAT, ImageFormatR16f, AdvancedFormats), + CASE1(SAMPLER_IMAGE_FORMAT, ImageFormatRgba16, AdvancedFormats), + CASE1(SAMPLER_IMAGE_FORMAT, ImageFormatRgb10A2, AdvancedFormats), + CASE1(SAMPLER_IMAGE_FORMAT, ImageFormatRg16, AdvancedFormats), + CASE1(SAMPLER_IMAGE_FORMAT, ImageFormatRg8, AdvancedFormats), + CASE1(SAMPLER_IMAGE_FORMAT, ImageFormatR16, AdvancedFormats), + CASE1(SAMPLER_IMAGE_FORMAT, ImageFormatR8, AdvancedFormats), + CASE1(SAMPLER_IMAGE_FORMAT, ImageFormatRgba16Snorm, AdvancedFormats), + CASE1(SAMPLER_IMAGE_FORMAT, ImageFormatRg16Snorm, AdvancedFormats), + CASE1(SAMPLER_IMAGE_FORMAT, ImageFormatRg8Snorm, AdvancedFormats), + CASE1(SAMPLER_IMAGE_FORMAT, ImageFormatR16Snorm, AdvancedFormats), + CASE1(SAMPLER_IMAGE_FORMAT, ImageFormatR8Snorm, AdvancedFormats), + CASE1(SAMPLER_IMAGE_FORMAT, ImageFormatRgba32i, Shader), + CASE1(SAMPLER_IMAGE_FORMAT, ImageFormatRgba16i, Shader), + CASE1(SAMPLER_IMAGE_FORMAT, ImageFormatRgba8i, Shader), + CASE1(SAMPLER_IMAGE_FORMAT, ImageFormatR32i, Shader), + CASE1(SAMPLER_IMAGE_FORMAT, ImageFormatRg32i, AdvancedFormats), + CASE1(SAMPLER_IMAGE_FORMAT, ImageFormatRg16i, AdvancedFormats), + CASE1(SAMPLER_IMAGE_FORMAT, ImageFormatRg8i, AdvancedFormats), + CASE1(SAMPLER_IMAGE_FORMAT, ImageFormatR16i, AdvancedFormats), + CASE1(SAMPLER_IMAGE_FORMAT, ImageFormatR8i, AdvancedFormats), + CASE1(SAMPLER_IMAGE_FORMAT, ImageFormatRgba32ui, Shader), + CASE1(SAMPLER_IMAGE_FORMAT, ImageFormatRgba16ui, Shader), + CASE1(SAMPLER_IMAGE_FORMAT, ImageFormatRgba8ui, Shader), + CASE1(SAMPLER_IMAGE_FORMAT, ImageFormatRgba8ui, Shader), + CASE1(SAMPLER_IMAGE_FORMAT, ImageFormatRgb10a2ui, AdvancedFormats), + CASE1(SAMPLER_IMAGE_FORMAT, ImageFormatRg32ui, AdvancedFormats), + CASE1(SAMPLER_IMAGE_FORMAT, ImageFormatRg16ui, AdvancedFormats), + CASE1(SAMPLER_IMAGE_FORMAT, ImageFormatRg8ui, AdvancedFormats), + CASE1(SAMPLER_IMAGE_FORMAT, ImageFormatR16ui, AdvancedFormats), + CASE1(SAMPLER_IMAGE_FORMAT, ImageFormatR8ui, AdvancedFormats), + })); + +// See SPIR-V Section 3.12 Image Channel Order +INSTANTIATE_TEST_CASE_P( + ImageChannelOrder, EnumCapabilityTest, + ::testing::ValuesIn(std::vector{ + CASE1(IMAGE_CHANNEL_ORDER, ImageChannelOrderR, Kernel), + CASE1(IMAGE_CHANNEL_ORDER, ImageChannelOrderA, Kernel), + CASE1(IMAGE_CHANNEL_ORDER, ImageChannelOrderRG, Kernel), + CASE1(IMAGE_CHANNEL_ORDER, ImageChannelOrderRA, Kernel), + CASE1(IMAGE_CHANNEL_ORDER, ImageChannelOrderRGB, Kernel), + CASE1(IMAGE_CHANNEL_ORDER, ImageChannelOrderRGBA, Kernel), + CASE1(IMAGE_CHANNEL_ORDER, ImageChannelOrderBGRA, Kernel), + CASE1(IMAGE_CHANNEL_ORDER, ImageChannelOrderARGB, Kernel), + CASE1(IMAGE_CHANNEL_ORDER, ImageChannelOrderIntensity, Kernel), + CASE1(IMAGE_CHANNEL_ORDER, ImageChannelOrderLuminance, Kernel), + CASE1(IMAGE_CHANNEL_ORDER, ImageChannelOrderRx, Kernel), + CASE1(IMAGE_CHANNEL_ORDER, ImageChannelOrderRGx, Kernel), + CASE1(IMAGE_CHANNEL_ORDER, ImageChannelOrderRGBx, Kernel), + CASE1(IMAGE_CHANNEL_ORDER, ImageChannelOrderDepth, Kernel), + CASE1(IMAGE_CHANNEL_ORDER, ImageChannelOrderDepthStencil, Kernel), + CASE1(IMAGE_CHANNEL_ORDER, ImageChannelOrdersRGB, Kernel), + CASE1(IMAGE_CHANNEL_ORDER, ImageChannelOrdersRGBx, Kernel), + CASE1(IMAGE_CHANNEL_ORDER, ImageChannelOrdersRGBA, Kernel), + CASE1(IMAGE_CHANNEL_ORDER, ImageChannelOrdersBGRA, Kernel), + })); + +// See SPIR-V Section 3.13 Image Channel Data Type +INSTANTIATE_TEST_CASE_P( + ImageChannelDataType, EnumCapabilityTest, + ::testing::ValuesIn(std::vector{ + CASE1(IMAGE_CHANNEL_DATA_TYPE, ImageChannelDataTypeSnormInt8, Kernel), + CASE1(IMAGE_CHANNEL_DATA_TYPE, ImageChannelDataTypeSnormInt16, Kernel), + CASE1(IMAGE_CHANNEL_DATA_TYPE, ImageChannelDataTypeUnormInt8, Kernel), + CASE1(IMAGE_CHANNEL_DATA_TYPE, ImageChannelDataTypeUnormInt16, Kernel), + CASE1(IMAGE_CHANNEL_DATA_TYPE, ImageChannelDataTypeUnormShort565, Kernel), + CASE1(IMAGE_CHANNEL_DATA_TYPE, ImageChannelDataTypeUnormShort555, Kernel), + CASE1(IMAGE_CHANNEL_DATA_TYPE, ImageChannelDataTypeUnormInt101010, Kernel), + CASE1(IMAGE_CHANNEL_DATA_TYPE, ImageChannelDataTypeSignedInt8, Kernel), + CASE1(IMAGE_CHANNEL_DATA_TYPE, ImageChannelDataTypeSignedInt16, Kernel), + CASE1(IMAGE_CHANNEL_DATA_TYPE, ImageChannelDataTypeSignedInt32, Kernel), + CASE1(IMAGE_CHANNEL_DATA_TYPE, ImageChannelDataTypeUnsignedInt8, Kernel), + CASE1(IMAGE_CHANNEL_DATA_TYPE, ImageChannelDataTypeUnsignedInt16, Kernel), + CASE1(IMAGE_CHANNEL_DATA_TYPE, ImageChannelDataTypeUnsignedInt32, Kernel), + CASE1(IMAGE_CHANNEL_DATA_TYPE, ImageChannelDataTypeHalfFloat, Kernel), + CASE1(IMAGE_CHANNEL_DATA_TYPE, ImageChannelDataTypeFloat, Kernel), + CASE1(IMAGE_CHANNEL_DATA_TYPE, ImageChannelDataTypeUnormInt24, Kernel), + })); + +// See SPIR-V Section 3.14 Image Operands +INSTANTIATE_TEST_CASE_P( + ImageOperands, EnumCapabilityTest, + ::testing::ValuesIn(std::vector{ + CASE0(OPTIONAL_IMAGE, ImageOperandsMaskNone), + CASE1(OPTIONAL_IMAGE, ImageOperandsBiasMask, Shader), + CASE0(OPTIONAL_IMAGE, ImageOperandsLodMask), + CASE0(OPTIONAL_IMAGE, ImageOperandsGradMask), + CASE0(OPTIONAL_IMAGE, ImageOperandsConstOffsetMask), + CASE1(OPTIONAL_IMAGE, ImageOperandsOffsetMask, ImageGatherExtended), + CASE0(OPTIONAL_IMAGE, ImageOperandsConstOffsetsMask), + CASE0(OPTIONAL_IMAGE, ImageOperandsSampleMask), + CASE1(OPTIONAL_IMAGE, ImageOperandsMinLodMask, MinLod), + })); + +// See SPIR-V Section 3.15 FP Fast Math Mode +INSTANTIATE_TEST_CASE_P( + FPFastMathMode, EnumCapabilityTest, + ::testing::ValuesIn(std::vector{ + CASE0(FP_FAST_MATH_MODE, FPFastMathModeMaskNone), + CASE1(FP_FAST_MATH_MODE, FPFastMathModeNotNaNMask, Kernel), + CASE1(FP_FAST_MATH_MODE, FPFastMathModeNotInfMask, Kernel), + CASE1(FP_FAST_MATH_MODE, FPFastMathModeNSZMask, Kernel), + CASE1(FP_FAST_MATH_MODE, FPFastMathModeAllowRecipMask, Kernel), + CASE1(FP_FAST_MATH_MODE, FPFastMathModeFastMask, Kernel), + })); + +// See SPIR-V Section 3.16 FP Rounding Mode +INSTANTIATE_TEST_CASE_P( + FPRoundingMode, EnumCapabilityTest, + ::testing::ValuesIn(std::vector{ + CASE1(FP_ROUNDING_MODE, FPRoundingModeRTE, Kernel), + CASE1(FP_ROUNDING_MODE, FPRoundingModeRTZ, Kernel), + CASE1(FP_ROUNDING_MODE, FPRoundingModeRTP, Kernel), + CASE1(FP_ROUNDING_MODE, FPRoundingModeRTN, Kernel), + })); + +// See SPIR-V Section 3.17 Linkage Type +INSTANTIATE_TEST_CASE_P( + LinkageType, EnumCapabilityTest, + ::testing::ValuesIn(std::vector{ + CASE1(LINKAGE_TYPE, LinkageTypeExport, Linkage), + CASE1(LINKAGE_TYPE, LinkageTypeImport, Linkage), + })); + +// See SPIR-V Section 3.18 Access Qualifier +INSTANTIATE_TEST_CASE_P( + AccessQualifier, EnumCapabilityTest, + ::testing::ValuesIn(std::vector{ + CASE1(ACCESS_QUALIFIER, AccessQualifierReadOnly, Kernel), + CASE1(ACCESS_QUALIFIER, AccessQualifierWriteOnly, Kernel), + CASE1(ACCESS_QUALIFIER, AccessQualifierReadWrite, Kernel), + })); + +// See SPIR-V Section 3.19 Function Parameter Attribute +INSTANTIATE_TEST_CASE_P( + FunctionParameterAttribute, EnumCapabilityTest, + ::testing::ValuesIn(std::vector{ + CASE1(FUNCTION_PARAMETER_ATTRIBUTE, FunctionParameterAttributeZext, Kernel), + CASE1(FUNCTION_PARAMETER_ATTRIBUTE, FunctionParameterAttributeSext, Kernel), + CASE1(FUNCTION_PARAMETER_ATTRIBUTE, FunctionParameterAttributeByVal, Kernel), + CASE1(FUNCTION_PARAMETER_ATTRIBUTE, FunctionParameterAttributeSret, Kernel), + CASE1(FUNCTION_PARAMETER_ATTRIBUTE, FunctionParameterAttributeNoAlias, Kernel), + CASE1(FUNCTION_PARAMETER_ATTRIBUTE, FunctionParameterAttributeNoCapture, Kernel), + CASE1(FUNCTION_PARAMETER_ATTRIBUTE, FunctionParameterAttributeNoWrite, Kernel), + CASE1(FUNCTION_PARAMETER_ATTRIBUTE, FunctionParameterAttributeNoReadWrite, Kernel), + })); + +// See SPIR-V Section 3.20 Decoration +INSTANTIATE_TEST_CASE_P( + Decoration, EnumCapabilityTest, + ::testing::ValuesIn(std::vector{ + CASE1(DECORATION, DecorationRelaxedPrecision, Shader), + CASE1(DECORATION, DecorationSpecId, Shader), + CASE1(DECORATION, DecorationBlock, Shader), + CASE1(DECORATION, DecorationBufferBlock, Shader), + CASE1(DECORATION, DecorationRowMajor, Matrix), + CASE1(DECORATION, DecorationColMajor, Matrix), + CASE1(DECORATION, DecorationArrayStride, Shader), + CASE1(DECORATION, DecorationMatrixStride, Shader), + CASE1(DECORATION, DecorationGLSLShared, Shader), + CASE1(DECORATION, DecorationGLSLPacked, Shader), + CASE1(DECORATION, DecorationCPacked, Kernel), + CASE1(DECORATION, DecorationBuiltIn, Shader), + CASE1(DECORATION, DecorationSmooth, Shader), + CASE1(DECORATION, DecorationNoPerspective, Shader), + CASE1(DECORATION, DecorationFlat, Shader), + CASE1(DECORATION, DecorationPatch, Tessellation), + CASE1(DECORATION, DecorationCentroid, Shader), + CASE1(DECORATION, DecorationSample, Shader), + CASE1(DECORATION, DecorationInvariant, Shader), + CASE0(DECORATION, DecorationRestrict), + CASE0(DECORATION, DecorationAliased), + CASE0(DECORATION, DecorationVolatile), + CASE1(DECORATION, DecorationConstant, Kernel), + CASE0(DECORATION, DecorationCoherent), + CASE0(DECORATION, DecorationNonWritable), + CASE0(DECORATION, DecorationNonReadable), + CASE1(DECORATION, DecorationUniform, Shader), + // Value 27 is an intentional gap in the spec numbering. + CASE1(DECORATION, DecorationSaturatedConversion, Kernel), + CASE1(DECORATION, DecorationStream, Geometry), + CASE1(DECORATION, DecorationLocation, Shader), + CASE1(DECORATION, DecorationComponent, Shader), + CASE1(DECORATION, DecorationIndex, Shader), + CASE1(DECORATION, DecorationBinding, Shader), + CASE1(DECORATION, DecorationDescriptorSet, Shader), + CASE0(DECORATION, DecorationOffset), + CASE1(DECORATION, DecorationXfbBuffer, TransformFeedback), + CASE1(DECORATION, DecorationXfbStride, TransformFeedback), + CASE1(DECORATION, DecorationFuncParamAttr, Kernel), + CASE1(DECORATION, DecorationFPRoundingMode, Kernel), + CASE1(DECORATION, DecorationFPFastMathMode, Kernel), + CASE1(DECORATION, DecorationLinkageAttributes, Linkage), + CASE1(DECORATION, DecorationNoContraction, Shader), + CASE1(DECORATION, DecorationInputTargetIndex, Shader), // TODO(dneto): Should be InputTarget. Fixed in 1.0 Rev 2 + CASE1(DECORATION, DecorationAlignment, Kernel), + })); + +#undef CASE0 +#undef CASE1 +#undef CASE2 + +} // anonymous namespace