blob: 0638cf0f49692e05f3e82409fe0f7246e15761d9 [file] [edit]
//===- HLSLSemanticSignatureMetadataTest.cpp ------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "llvm/Frontend/HLSL/SemanticSignatures.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Metadata.h"
#include "llvm/IR/Type.h"
#include "llvm/Testing/Support/Error.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
using namespace llvm;
using namespace llvm::hlsl;
namespace {
class HLSLSemanticSignatureMetadataTest : public testing::Test {
protected:
LLVMContext Ctx;
Metadata *getI32(uint32_t Val) {
return ConstantAsMetadata::get(
ConstantInt::get(Type::getInt32Ty(Ctx), Val));
}
Metadata *getI8(uint8_t Val) {
return ConstantAsMetadata::get(ConstantInt::get(Type::getInt8Ty(Ctx), Val));
}
Metadata *getStr(StringRef Val) { return MDString::get(Ctx, Val); }
MDNode *getIndices(ArrayRef<uint32_t> Indices) {
SmallVector<Metadata *> Ops;
for (uint32_t I : Indices)
Ops.push_back(getI32(I));
return MDNode::get(Ctx, Ops);
}
// Assemble a raw signature element node from the example in the spec
MDNode *getElement(uint32_t SigId, StringRef Name, uint32_t CompType,
uint32_t SemanticKind, ArrayRef<uint32_t> Indices,
uint32_t InterpMode, uint32_t Rows, uint8_t Cols,
uint32_t StartRow, uint8_t StartCol, uint8_t UsageMask,
uint8_t DynIndexMask, uint32_t GSStream) {
return MDNode::get(
Ctx, {getI32(SigId), getStr(Name), getI32(CompType),
getI32(SemanticKind), getIndices(Indices), getI32(InterpMode),
getI32(Rows), getI8(Cols), getI32(StartRow), getI8(StartCol),
getI8(UsageMask), getI8(DynIndexMask), getI32(GSStream)});
}
// Read back an integer operand
uint64_t getIntOp(const MDNode *N, unsigned I) {
return mdconst::extract<ConstantInt>(N->getOperand(I))->getZExtValue();
}
// Read back a string operand
StringRef getStrOp(const MDNode *N, unsigned I) {
return cast<MDString>(N->getOperand(I))->getString();
}
};
//===----------------------------------------------------------------------===//
// Success cases
//===----------------------------------------------------------------------===//
TEST_F(HLSLSemanticSignatureMetadataTest, StructHelpers) {
SemanticSignatureElement Elem;
Elem.SigId = 0;
Elem.CompType = dxil::ElementType::F32;
Elem.SemanticKind = dxbc::PSV::SemanticKind::Arbitrary;
Elem.Rows = 1;
EXPECT_FALSE(Elem.isAllocated());
Elem.Cols = 4;
Elem.StartRow = 0;
Elem.StartCol = 0;
EXPECT_TRUE(Elem.isAllocated());
EXPECT_EQ(Elem.getDeclaredMask(), 0xF);
}
TEST_F(HLSLSemanticSignatureMetadataTest, MetadataToElement) {
MDNode *Node = getElement(/*SigId=*/1, "TEXCOORD", /*CompType=*/9,
/*SemanticKind=*/0, /*Indices=*/{0, 1},
/*InterpMode=*/0, /*Rows=*/2, /*Cols=*/4,
/*StartRow=*/1, /*StartCol=*/0, /*UsageMask=*/0,
/*DynIndexMask=*/0, /*GSStream=*/0);
Expected<SemanticSignatureElement> Elem =
SemanticSignatureElement::fromMetadata(Node);
ASSERT_THAT_EXPECTED(Elem, Succeeded());
EXPECT_EQ(Elem->SigId, 1u);
EXPECT_EQ(Elem->SemanticName, "TEXCOORD");
EXPECT_EQ(Elem->CompType, dxil::ElementType::F32);
EXPECT_EQ(Elem->SemanticKind, dxbc::PSV::SemanticKind::Arbitrary);
EXPECT_THAT(Elem->SemanticIndices, testing::ElementsAre(0u, 1u));
EXPECT_EQ(Elem->InterpMode, dxbc::PSV::InterpolationMode::Undefined);
EXPECT_EQ(Elem->Rows, 2u);
EXPECT_EQ(Elem->Cols, 4u);
EXPECT_EQ(Elem->StartRow, 1u);
EXPECT_EQ(Elem->StartCol, 0u);
EXPECT_EQ(Elem->UsageMask, 0u);
EXPECT_EQ(Elem->DynIndexMask, 0u);
EXPECT_EQ(Elem->GSStream, 0u);
}
// SV_Target output with a non-zero usage/dynamic-index mask and semantic index
TEST_F(HLSLSemanticSignatureMetadataTest, MetadataToElementSystemValue) {
MDNode *Node = getElement(/*SigId=*/1, "SV_Target", /*CompType=*/9,
/*SemanticKind=*/16, /*Indices=*/{1},
/*InterpMode=*/0, /*Rows=*/1, /*Cols=*/4,
/*StartRow=*/1, /*StartCol=*/0, /*UsageMask=*/0x7,
/*DynIndexMask=*/0x1, /*GSStream=*/0);
Expected<SemanticSignatureElement> Elem =
SemanticSignatureElement::fromMetadata(Node);
ASSERT_THAT_EXPECTED(Elem, Succeeded());
EXPECT_EQ(Elem->SemanticName, "SV_Target");
EXPECT_EQ(Elem->SemanticKind, dxbc::PSV::SemanticKind::Target);
EXPECT_THAT(Elem->SemanticIndices, testing::ElementsAre(1u));
EXPECT_EQ(Elem->UsageMask, 0x7u);
EXPECT_EQ(Elem->DynIndexMask, 0x1u);
}
// An unallocated element uses the row/col sentinels
TEST_F(HLSLSemanticSignatureMetadataTest, MetadataToElementUnallocated) {
MDNode *Node =
getElement(/*SigId=*/0, "POSITION", /*CompType=*/9,
/*SemanticKind=*/0, /*Indices=*/{0},
/*InterpMode=*/0, /*Rows=*/1, /*Cols=*/4,
/*StartRow=*/UnallocatedRow, /*StartCol=*/UnallocatedCol,
/*UsageMask=*/0, /*DynIndexMask=*/0, /*GSStream=*/0);
Expected<SemanticSignatureElement> Elem =
SemanticSignatureElement::fromMetadata(Node);
ASSERT_THAT_EXPECTED(Elem, Succeeded());
EXPECT_EQ(Elem->StartRow, UnallocatedRow);
EXPECT_EQ(Elem->StartCol, UnallocatedCol);
EXPECT_FALSE(Elem->isAllocated());
}
// Every component type value maps onto the matching dxil::ElementType
TEST_F(HLSLSemanticSignatureMetadataTest, MetadataToElementComponentTypes) {
for (dxil::ElementType CompType :
{dxil::ElementType::I32, dxil::ElementType::U32, dxil::ElementType::F16,
dxil::ElementType::F32, dxil::ElementType::F64,
dxil::ElementType::I16}) {
MDNode *Node = getElement(
/*SigId=*/0, "A", static_cast<uint32_t>(CompType), /*SemanticKind=*/0,
/*Indices=*/{0}, /*InterpMode=*/0, /*Rows=*/1, /*Cols=*/1,
/*StartRow=*/0, /*StartCol=*/0, /*UsageMask=*/0, /*DynIndexMask=*/0,
/*GSStream=*/0);
Expected<SemanticSignatureElement> Elem =
SemanticSignatureElement::fromMetadata(Node);
ASSERT_THAT_EXPECTED(Elem, Succeeded());
EXPECT_EQ(Elem->CompType, CompType);
}
}
// Every interpolation mode value maps onto the matching enumerator
TEST_F(HLSLSemanticSignatureMetadataTest, MetadataToElementInterpModes) {
for (dxbc::PSV::InterpolationMode Mode :
{dxbc::PSV::InterpolationMode::Constant,
dxbc::PSV::InterpolationMode::Linear,
dxbc::PSV::InterpolationMode::LinearCentroid,
dxbc::PSV::InterpolationMode::LinearNoperspective,
dxbc::PSV::InterpolationMode::LinearSample}) {
MDNode *Node = getElement(
/*SigId=*/0, "A", /*CompType=*/9, /*SemanticKind=*/0, /*Indices=*/{0},
static_cast<uint32_t>(Mode), /*Rows=*/1, /*Cols=*/1, /*StartRow=*/0,
/*StartCol=*/0, /*UsageMask=*/0, /*DynIndexMask=*/0, /*GSStream=*/0);
Expected<SemanticSignatureElement> Elem =
SemanticSignatureElement::fromMetadata(Node);
ASSERT_THAT_EXPECTED(Elem, Succeeded());
EXPECT_EQ(Elem->InterpMode, Mode);
}
}
// A column-offset allocation drives the derived declared/usage masks
TEST_F(HLSLSemanticSignatureMetadataTest, MetadataToElementDerivedMasks) {
MDNode *Node = getElement(/*SigId=*/0, "SV_Position", /*CompType=*/9,
/*SemanticKind=*/3, /*Indices=*/{0},
/*InterpMode=*/4, /*Rows=*/1, /*Cols=*/2,
/*StartRow=*/0, /*StartCol=*/1, /*UsageMask=*/0x2,
/*DynIndexMask=*/0, /*GSStream=*/0);
Expected<SemanticSignatureElement> Elem =
SemanticSignatureElement::fromMetadata(Node);
ASSERT_THAT_EXPECTED(Elem, Succeeded());
EXPECT_EQ(Elem->SemanticKind, dxbc::PSV::SemanticKind::Position);
EXPECT_TRUE(Elem->isAllocated());
// ((1 << 2) - 1) << 1 == 0b0110
EXPECT_EQ(Elem->getDeclaredMask(), 0x6);
EXPECT_EQ(Elem->getAlwaysReadsMask(), 0x2);
// ~0x2 & 0x6 == 0x4
EXPECT_EQ(Elem->getNeverWritesMask(), 0x4);
}
// A geometry shader output carries a non-zero stream index
TEST_F(HLSLSemanticSignatureMetadataTest, MetadataToElementGSStream) {
MDNode *Node = getElement(/*SigId=*/0, "A", /*CompType=*/9,
/*SemanticKind=*/0, /*Indices=*/{0},
/*InterpMode=*/0, /*Rows=*/1, /*Cols=*/1,
/*StartRow=*/0, /*StartCol=*/0, /*UsageMask=*/0,
/*DynIndexMask=*/0, /*GSStream=*/3);
Expected<SemanticSignatureElement> Elem =
SemanticSignatureElement::fromMetadata(Node);
ASSERT_THAT_EXPECTED(Elem, Succeeded());
EXPECT_EQ(Elem->GSStream, 3u);
}
//===----------------------------------------------------------------------===//
// Error cases
//===----------------------------------------------------------------------===//
// A null node is not a valid signature element
TEST_F(HLSLSemanticSignatureMetadataTest, MetadataToElementNull) {
EXPECT_THAT_EXPECTED(SemanticSignatureElement::fromMetadata(nullptr),
FailedWithMessage("signature element node is null"));
}
// A node with the wrong number of operands is rejected
TEST_F(HLSLSemanticSignatureMetadataTest, MetadataToElementWrongOperandCount) {
MDNode *Node = MDNode::get(Ctx, {getI32(0), getStr("A")});
EXPECT_THAT_EXPECTED(
SemanticSignatureElement::fromMetadata(Node),
FailedWithMessage("signature element node has wrong number of operands"));
}
// A node with an operand of the wrong type is rejected
TEST_F(HLSLSemanticSignatureMetadataTest, MetadataToElementWrongOperandType) {
// Operand 0 (SigId) should be an integer, not a string
MDNode *Node = getElement(/*SigId=*/0, "A", /*CompType=*/9,
/*SemanticKind=*/0, /*Indices=*/{0},
/*InterpMode=*/0, /*Rows=*/1, /*Cols=*/1,
/*StartRow=*/0, /*StartCol=*/0, /*UsageMask=*/0,
/*DynIndexMask=*/0, /*GSStream=*/0);
SmallVector<Metadata *> Ops(Node->op_begin(), Node->op_end());
Ops[0] = getStr("not an int");
EXPECT_THAT_EXPECTED(
SemanticSignatureElement::fromMetadata(MDNode::get(Ctx, Ops)),
FailedWithMessage("expected integer operand 0"));
}
//===--------------------------------------------------------------------===//
// Per-operand range/enum validation
//===--------------------------------------------------------------------===//
// A component type outside dxil::ElementType is rejected
TEST_F(HLSLSemanticSignatureMetadataTest, MetadataToElementInvalidCompType) {
MDNode *Node = getElement(/*SigId=*/0, "A", /*CompType=*/100,
/*SemanticKind=*/0, /*Indices=*/{0},
/*InterpMode=*/0, /*Rows=*/1, /*Cols=*/1,
/*StartRow=*/0, /*StartCol=*/0, /*UsageMask=*/0,
/*DynIndexMask=*/0, /*GSStream=*/0);
EXPECT_THAT_EXPECTED(SemanticSignatureElement::fromMetadata(Node),
FailedWithMessage("invalid component type"));
}
// A semantic kind outside dxbc::PSV::SemanticKind is rejected
TEST_F(HLSLSemanticSignatureMetadataTest,
MetadataToElementInvalidSemanticKind) {
MDNode *Node = getElement(/*SigId=*/0, "A", /*CompType=*/9,
/*SemanticKind=*/100, /*Indices=*/{0},
/*InterpMode=*/0, /*Rows=*/1, /*Cols=*/1,
/*StartRow=*/0, /*StartCol=*/0, /*UsageMask=*/0,
/*DynIndexMask=*/0, /*GSStream=*/0);
EXPECT_THAT_EXPECTED(SemanticSignatureElement::fromMetadata(Node),
FailedWithMessage("invalid semantic kind"));
}
// An interpolation mode outside dxbc::PSV::InterpolationMode is rejected
TEST_F(HLSLSemanticSignatureMetadataTest, MetadataToElementInvalidInterpMode) {
MDNode *Node = getElement(/*SigId=*/0, "A", /*CompType=*/9,
/*SemanticKind=*/0, /*Indices=*/{0},
/*InterpMode=*/100, /*Rows=*/1, /*Cols=*/1,
/*StartRow=*/0, /*StartCol=*/0, /*UsageMask=*/0,
/*DynIndexMask=*/0, /*GSStream=*/0);
EXPECT_THAT_EXPECTED(SemanticSignatureElement::fromMetadata(Node),
FailedWithMessage("invalid interpolation mode"));
}
// The number of components per row must be within 1-4
TEST_F(HLSLSemanticSignatureMetadataTest, MetadataToElementInvalidCols) {
for (uint8_t Cols : {uint8_t(0), uint8_t(5)}) {
MDNode *Node = getElement(/*SigId=*/0, "A", /*CompType=*/9,
/*SemanticKind=*/0, /*Indices=*/{0},
/*InterpMode=*/0, /*Rows=*/1, Cols,
/*StartRow=*/0, /*StartCol=*/0, /*UsageMask=*/0,
/*DynIndexMask=*/0, /*GSStream=*/0);
EXPECT_THAT_EXPECTED(
SemanticSignatureElement::fromMetadata(Node),
FailedWithMessage("number of components per row must be within 1-4"));
}
}
// A start column must be within 0-3 or the unallocated sentinel
TEST_F(HLSLSemanticSignatureMetadataTest, MetadataToElementInvalidStartCol) {
MDNode *Node = getElement(/*SigId=*/0, "A", /*CompType=*/9,
/*SemanticKind=*/0, /*Indices=*/{0},
/*InterpMode=*/0, /*Rows=*/1, /*Cols=*/1,
/*StartRow=*/0, /*StartCol=*/4, /*UsageMask=*/0,
/*DynIndexMask=*/0, /*GSStream=*/0);
EXPECT_THAT_EXPECTED(
SemanticSignatureElement::fromMetadata(Node),
FailedWithMessage("start column must be within 0-3 or unallocated"));
}
// The row/col sentinels must be set together
TEST_F(HLSLSemanticSignatureMetadataTest,
MetadataToElementInvalidSentinelPair) {
MDNode *RowOnly = getElement(
/*SigId=*/0, "A", /*CompType=*/9, /*SemanticKind=*/0, /*Indices=*/{0},
/*InterpMode=*/0, /*Rows=*/1, /*Cols=*/1, /*StartRow=*/UnallocatedRow,
/*StartCol=*/0, /*UsageMask=*/0, /*DynIndexMask=*/0, /*GSStream=*/0);
EXPECT_THAT_EXPECTED(
SemanticSignatureElement::fromMetadata(RowOnly),
FailedWithMessage("start row and column sentinels must be set together"));
MDNode *ColOnly = getElement(
/*SigId=*/0, "A", /*CompType=*/9, /*SemanticKind=*/0, /*Indices=*/{0},
/*InterpMode=*/0, /*Rows=*/1, /*Cols=*/1, /*StartRow=*/0,
/*StartCol=*/UnallocatedCol, /*UsageMask=*/0, /*DynIndexMask=*/0,
/*GSStream=*/0);
EXPECT_THAT_EXPECTED(
SemanticSignatureElement::fromMetadata(ColOnly),
FailedWithMessage("start row and column sentinels must be set together"));
}
// The usage and dynamic-index masks are 4-bit values
TEST_F(HLSLSemanticSignatureMetadataTest, MetadataToElementInvalidMasks) {
MDNode *BadUsage = getElement(
/*SigId=*/0, "A", /*CompType=*/9, /*SemanticKind=*/0, /*Indices=*/{0},
/*InterpMode=*/0, /*Rows=*/1, /*Cols=*/1, /*StartRow=*/0, /*StartCol=*/0,
/*UsageMask=*/0x10, /*DynIndexMask=*/0, /*GSStream=*/0);
EXPECT_THAT_EXPECTED(SemanticSignatureElement::fromMetadata(BadUsage),
FailedWithMessage("usage mask must be a 4-bit value"));
MDNode *BadDyn = getElement(
/*SigId=*/0, "A", /*CompType=*/9, /*SemanticKind=*/0, /*Indices=*/{0},
/*InterpMode=*/0, /*Rows=*/1, /*Cols=*/1, /*StartRow=*/0, /*StartCol=*/0,
/*UsageMask=*/0, /*DynIndexMask=*/0x10, /*GSStream=*/0);
EXPECT_THAT_EXPECTED(
SemanticSignatureElement::fromMetadata(BadDyn),
FailedWithMessage("dynamic index mask must be a 4-bit value"));
}
// A geometry shader output stream index must be within 0-3
TEST_F(HLSLSemanticSignatureMetadataTest, MetadataToElementInvalidGSStream) {
MDNode *Node = getElement(/*SigId=*/0, "A", /*CompType=*/9,
/*SemanticKind=*/0, /*Indices=*/{0},
/*InterpMode=*/0, /*Rows=*/1, /*Cols=*/1,
/*StartRow=*/0, /*StartCol=*/0, /*UsageMask=*/0,
/*DynIndexMask=*/0, /*GSStream=*/4);
EXPECT_THAT_EXPECTED(
SemanticSignatureElement::fromMetadata(Node),
FailedWithMessage("geometry shader stream index must be within 0-3"));
}
// The number of semantic indices must equal the number of rows
TEST_F(HLSLSemanticSignatureMetadataTest, MetadataToElementIndicesRowMismatch) {
MDNode *Node = getElement(/*SigId=*/0, "A", /*CompType=*/9,
/*SemanticKind=*/0, /*Indices=*/{0},
/*InterpMode=*/0, /*Rows=*/2, /*Cols=*/1,
/*StartRow=*/0, /*StartCol=*/0, /*UsageMask=*/0,
/*DynIndexMask=*/0, /*GSStream=*/0);
EXPECT_THAT_EXPECTED(
SemanticSignatureElement::fromMetadata(Node),
FailedWithMessage(
"number of semantic indices must equal the number of rows"));
}
//===--------------------------------------------------------------------===//
// struct -> metadata
//===--------------------------------------------------------------------===//
// A fully populated element emits all 13 operands in order
TEST_F(HLSLSemanticSignatureMetadataTest, ElementToMetadata) {
SemanticSignatureElement Elem;
Elem.SigId = 1;
Elem.SemanticName = "TEXCOORD";
Elem.CompType = dxil::ElementType::F32;
Elem.SemanticKind = dxbc::PSV::SemanticKind::Arbitrary;
Elem.SemanticIndices = {0, 1};
Elem.InterpMode = dxbc::PSV::InterpolationMode::Undefined;
Elem.Rows = 2;
Elem.Cols = 4;
Elem.StartRow = 1;
Elem.StartCol = 0;
Elem.UsageMask = 0;
Elem.DynIndexMask = 0;
Elem.GSStream = 0;
MDNode *Node = Elem.toMetadata(Ctx);
ASSERT_EQ(Node->getNumOperands(), 13u);
EXPECT_EQ(getIntOp(Node, 0), 1u);
EXPECT_EQ(getStrOp(Node, 1), "TEXCOORD");
EXPECT_EQ(getIntOp(Node, 2), 9u);
EXPECT_EQ(getIntOp(Node, 3), 0u);
EXPECT_EQ(Node->getOperand(4).get(), getIndices({0, 1}));
EXPECT_EQ(getIntOp(Node, 5), 0u);
EXPECT_EQ(getIntOp(Node, 6), 2u);
EXPECT_EQ(getIntOp(Node, 7), 4u);
EXPECT_EQ(getIntOp(Node, 8), 1u);
EXPECT_EQ(getIntOp(Node, 9), 0u);
EXPECT_EQ(getIntOp(Node, 10), 0u);
EXPECT_EQ(getIntOp(Node, 11), 0u);
EXPECT_EQ(getIntOp(Node, 12), 0u);
}
// System value, non-zero masks and a non-zero stream index are emitted
TEST_F(HLSLSemanticSignatureMetadataTest, ElementToMetadataSystemValue) {
SemanticSignatureElement Elem;
Elem.SigId = 1;
Elem.SemanticName = "SV_Target";
Elem.CompType = dxil::ElementType::F32;
Elem.SemanticKind = dxbc::PSV::SemanticKind::Target;
Elem.SemanticIndices = {1};
Elem.Rows = 1;
Elem.Cols = 4;
Elem.StartRow = 1;
Elem.StartCol = 0;
Elem.UsageMask = 0x7;
Elem.DynIndexMask = 0x1;
Elem.GSStream = 2;
MDNode *Node = Elem.toMetadata(Ctx);
ASSERT_EQ(Node->getNumOperands(), 13u);
EXPECT_EQ(getStrOp(Node, 1), "SV_Target");
EXPECT_EQ(getIntOp(Node, 3), 16u);
EXPECT_EQ(Node->getOperand(4).get(), getIndices({1}));
EXPECT_EQ(getIntOp(Node, 10), 0x7u);
EXPECT_EQ(getIntOp(Node, 11), 0x1u);
EXPECT_EQ(getIntOp(Node, 12), 2u);
}
// An unallocated element emits the row/col sentinels
TEST_F(HLSLSemanticSignatureMetadataTest, ElementToMetadataUnallocated) {
SemanticSignatureElement Elem;
Elem.SigId = 0;
Elem.SemanticName = "POSITION";
Elem.CompType = dxil::ElementType::F32;
Elem.SemanticKind = dxbc::PSV::SemanticKind::Arbitrary;
Elem.SemanticIndices = {0};
Elem.Rows = 0;
Elem.Cols = 0;
MDNode *Node = Elem.toMetadata(Ctx);
ASSERT_EQ(Node->getNumOperands(), 13u);
EXPECT_EQ(getIntOp(Node, 8), UnallocatedRow);
EXPECT_EQ(getIntOp(Node, 9), UnallocatedCol);
}
// Emitting then parsing yields an equivalent element
TEST_F(HLSLSemanticSignatureMetadataTest, ElementRoundTrip) {
SemanticSignatureElement Elem;
Elem.SigId = 2;
Elem.SemanticName = "TEXCOORD";
Elem.CompType = dxil::ElementType::F32;
Elem.SemanticKind = dxbc::PSV::SemanticKind::Arbitrary;
Elem.SemanticIndices = {1};
Elem.InterpMode = dxbc::PSV::InterpolationMode::LinearNoperspective;
Elem.Rows = 1;
Elem.Cols = 4;
Elem.StartRow = 2;
Elem.StartCol = 0;
Elem.UsageMask = 0x7;
Elem.DynIndexMask = 0;
Elem.GSStream = 0;
Expected<SemanticSignatureElement> Parsed =
SemanticSignatureElement::fromMetadata(Elem.toMetadata(Ctx));
ASSERT_THAT_EXPECTED(Parsed, Succeeded());
EXPECT_EQ(Parsed->SigId, Elem.SigId);
EXPECT_EQ(Parsed->SemanticName, Elem.SemanticName);
EXPECT_EQ(Parsed->CompType, Elem.CompType);
EXPECT_EQ(Parsed->SemanticKind, Elem.SemanticKind);
EXPECT_THAT(Parsed->SemanticIndices,
testing::ElementsAreArray(Elem.SemanticIndices));
EXPECT_EQ(Parsed->InterpMode, Elem.InterpMode);
EXPECT_EQ(Parsed->Rows, Elem.Rows);
EXPECT_EQ(Parsed->Cols, Elem.Cols);
EXPECT_EQ(Parsed->StartRow, Elem.StartRow);
EXPECT_EQ(Parsed->StartCol, Elem.StartCol);
EXPECT_EQ(Parsed->UsageMask, Elem.UsageMask);
EXPECT_EQ(Parsed->DynIndexMask, Elem.DynIndexMask);
EXPECT_EQ(Parsed->GSStream, Elem.GSStream);
}
} // namespace