diff --git a/include/libspirv/libspirv.h b/include/libspirv/libspirv.h index 4c9c700f4..f0e7b7942 100644 --- a/include/libspirv/libspirv.h +++ b/include/libspirv/libspirv.h @@ -158,6 +158,7 @@ typedef enum spv_operand_type_t { SPV_OPERAND_TYPE_DIMENSIONALITY, SPV_OPERAND_TYPE_SAMPLER_ADDRESSING_MODE, SPV_OPERAND_TYPE_SAMPLER_FILTER_MODE, + SPV_OPERAND_TYPE_SAMPLER_IMAGE_FORMAT, SPV_OPERAND_TYPE_FP_FAST_MATH_MODE, SPV_OPERAND_TYPE_FP_ROUNDING_MODE, SPV_OPERAND_TYPE_LINKAGE_TYPE, @@ -169,7 +170,10 @@ typedef enum spv_operand_type_t { SPV_OPERAND_TYPE_LOOP_CONTROL, SPV_OPERAND_TYPE_FUNCTION_CONTROL, SPV_OPERAND_TYPE_MEMORY_SEMANTICS, + + // The ID for an execution scope value. SPV_OPERAND_TYPE_EXECUTION_SCOPE, + SPV_OPERAND_TYPE_GROUP_OPERATION, SPV_OPERAND_TYPE_KERNEL_ENQ_FLAGS, SPV_OPERAND_TYPE_KERNEL_PROFILING_INFO, diff --git a/source/opcode.cpp b/source/opcode.cpp index 8701eaf9b..3c0c2f724 100644 --- a/source/opcode.cpp +++ b/source/opcode.cpp @@ -115,7 +115,7 @@ spv_operand_type_t convertOperandClassToType(spv::Op opcode, case OperandDimensionality: return SPV_OPERAND_TYPE_DIMENSIONALITY; case OperandSamplerAddressingMode: return SPV_OPERAND_TYPE_SAMPLER_ADDRESSING_MODE; case OperandSamplerFilterMode: return SPV_OPERAND_TYPE_SAMPLER_FILTER_MODE; - case OperandSamplerImageFormat: return SPV_OPERAND_TYPE_NONE; //TODO + case OperandSamplerImageFormat: return SPV_OPERAND_TYPE_SAMPLER_IMAGE_FORMAT; case OperandImageChannelOrder: return SPV_OPERAND_TYPE_NONE; //TODO case OperandImageChannelDataType: return SPV_OPERAND_TYPE_NONE; //TODO case OperandImageOperands: return SPV_OPERAND_TYPE_NONE; //TODO diff --git a/source/operand.cpp b/source/operand.cpp index 372cfd7cf..819f5917f 100644 --- a/source/operand.cpp +++ b/source/operand.cpp @@ -410,6 +410,62 @@ static const spv_operand_desc_t samplerFilterModeEntries[] = { {SPV_OPERAND_TYPE_NONE}}, }; +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) \ + { \ + #NAME, ImageFormat##NAME, SPV_OPCODE_FLAGS_CAPABILITIES, CapabilityShader, \ + { \ + 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), + // clang-format on +#undef CASE +}; + static const spv_operand_desc_t fpFastMathModeEntries[] = { {"None", FPFastMathModeMaskNone, @@ -1333,6 +1389,9 @@ static const spv_operand_desc_group_t opcodeEntryTypes[] = { {SPV_OPERAND_TYPE_SAMPLER_FILTER_MODE, sizeof(samplerFilterModeEntries) / sizeof(spv_operand_desc_t), samplerFilterModeEntries}, + {SPV_OPERAND_TYPE_SAMPLER_IMAGE_FORMAT, + sizeof(samplerImageFormatEntries) / sizeof(spv_operand_desc_t), + samplerImageFormatEntries}, {SPV_OPERAND_TYPE_FP_FAST_MATH_MODE, sizeof(fpFastMathModeEntries) / sizeof(spv_operand_desc_t), fpFastMathModeEntries}, @@ -1477,6 +1536,8 @@ const char *spvOperandTypeStr(spv_operand_type_t type) { return "addressing mode"; case SPV_OPERAND_TYPE_SAMPLER_FILTER_MODE: return "sampler filter mode"; + case SPV_OPERAND_TYPE_SAMPLER_IMAGE_FORMAT: + return "sampler image format"; case SPV_OPERAND_TYPE_FP_FAST_MATH_MODE: return "floating pointer fast math mode"; case SPV_OPERAND_TYPE_FP_ROUNDING_MODE: diff --git a/test/TextToBinary.TypeDeclaration.cpp b/test/TextToBinary.TypeDeclaration.cpp index 3525e3ba0..bd111a1f2 100644 --- a/test/TextToBinary.TypeDeclaration.cpp +++ b/test/TextToBinary.TypeDeclaration.cpp @@ -44,7 +44,100 @@ struct EnumCase { const std::string name; }; -// Test OpTypePipe +// Test Dim enums via OpTypeImage + +using DimTest = test_fixture::TextToBinaryTestBase< + ::testing::TestWithParam>>; + +TEST_P(DimTest, AnyDim) { + std::string input = "%imageType = OpTypeImage %sampledType " + + GetParam().name + " 2 3 0 4 Rgba8"; + EXPECT_THAT( + CompiledInstructions(input), + Eq(MakeInstruction(spv::OpTypeImage, {1, 2, GetParam().value, 2, 3, 0, 4, + spv::ImageFormatRgba8}))); +} + +// clang-format off +#define CASE(NAME) {spv::Dim##NAME, #NAME} +INSTANTIATE_TEST_CASE_P( + TextToBinaryDim, DimTest, + ::testing::ValuesIn(std::vector>{ + CASE(1D), + CASE(2D), + CASE(3D), + CASE(Cube), + CASE(Rect), + CASE(Buffer), + // TODO(dneto): Rev32 adds InputTarget. + })); +#undef CASE +// clang-format on + +// Test ImageFormat enums via OpTypeImage + +using ImageFormatTest = test_fixture::TextToBinaryTestBase< + ::testing::TestWithParam>>; + +TEST_P(ImageFormatTest, AnyImageFormat) { + std::string input = + "%imageType = OpTypeImage %sampledType 1D 2 3 0 4 " + GetParam().name; + EXPECT_THAT(CompiledInstructions(input), + Eq(MakeInstruction(spv::OpTypeImage, {1, 2, spv::Dim1D, 2, 3, 0, + 4, GetParam().value}))); +} + +// clang-format off +#define CASE(NAME) {spv::ImageFormat##NAME, #NAME} +INSTANTIATE_TEST_CASE_P( + TextToBinaryImageFormat, ImageFormatTest, + ::testing::ValuesIn(std::vector>{ + 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), + // TODO(dneto): Rev32 adds InputTarget. + })); +#undef CASE +// clang-format on + +// Test AccessQualifier enums via OpTypePipe. using OpTypePipeTest = test_fixture::TextToBinaryTestBase< ::testing::TestWithParam>>; @@ -69,6 +162,9 @@ INSTANTIATE_TEST_CASE_P( #undef CASE // clang-format on +// TODO(dneto): error message test for sampler addressing mode +// TODO(dneto): error message test for sampler image format + // TODO(dneto): OpTypeVoid // TODO(dneto): OpTypeBool // TODO(dneto): OpTypeInt