mirror of
https://github.com/KhronosGroup/SPIRV-Tools
synced 2024-11-26 21:30:07 +00:00
Add validator checks for sparse image opcodes
This commit is contained in:
parent
12447d8465
commit
c520d43649
@ -196,7 +196,8 @@ uint32_t GetPlaneCoordSize(const ImageTypeInfo& info) {
|
||||
// the instruction uses projection coordinates.
|
||||
uint32_t GetMinCoordSize(SpvOp opcode, const ImageTypeInfo& info) {
|
||||
if (info.dim == SpvDimCube &&
|
||||
(opcode == SpvOpImageRead || opcode == SpvOpImageWrite)) {
|
||||
(opcode == SpvOpImageRead || opcode == SpvOpImageWrite ||
|
||||
opcode == SpvOpImageSparseRead)) {
|
||||
// These opcodes use UV for Cube, not direction vector.
|
||||
return 3;
|
||||
}
|
||||
@ -270,7 +271,8 @@ spv_result_t ValidateImageOperands(ValidationState_t& _,
|
||||
}
|
||||
|
||||
if (mask & SpvImageOperandsLodMask) {
|
||||
if (!is_explicit_lod && opcode != SpvOpImageFetch) {
|
||||
if (!is_explicit_lod && opcode != SpvOpImageFetch &&
|
||||
opcode != SpvOpImageSparseFetch) {
|
||||
return _.diag(SPV_ERROR_INVALID_DATA)
|
||||
<< "Image Operand Lod can only be used with ExplicitLod opcodes "
|
||||
<< "and OpImageFetch: " << spvOpcodeString(opcode);
|
||||
@ -287,14 +289,14 @@ spv_result_t ValidateImageOperands(ValidationState_t& _,
|
||||
if (is_explicit_lod) {
|
||||
if (!_.IsFloatScalarType(type_id)) {
|
||||
return _.diag(SPV_ERROR_INVALID_DATA)
|
||||
<< "Expected Image Operand Lod to be float scalar when used with "
|
||||
<< "ExplicitLod: " << spvOpcodeString(opcode);
|
||||
<< "Expected Image Operand Lod to be float scalar when used "
|
||||
<< "with ExplicitLod: " << spvOpcodeString(opcode);
|
||||
}
|
||||
} else {
|
||||
if (!_.IsIntScalarType(type_id)) {
|
||||
return _.diag(SPV_ERROR_INVALID_DATA)
|
||||
<< "Expected Image Operand Lod to be int scalar when used with "
|
||||
<< "OpImageFetch";
|
||||
<< "Expected Image Operand Lod to be int scalar when used with "
|
||||
<< "OpImageFetch";
|
||||
}
|
||||
}
|
||||
|
||||
@ -411,7 +413,9 @@ spv_result_t ValidateImageOperands(ValidationState_t& _,
|
||||
}
|
||||
|
||||
if (mask & SpvImageOperandsConstOffsetsMask) {
|
||||
if (opcode != SpvOpImageGather && opcode != SpvOpImageDrefGather) {
|
||||
if (opcode != SpvOpImageGather && opcode != SpvOpImageDrefGather &&
|
||||
opcode != SpvOpImageSparseGather &&
|
||||
opcode != SpvOpImageSparseDrefGather) {
|
||||
return _.diag(SPV_ERROR_INVALID_DATA)
|
||||
<< "Image Operand ConstOffsets can only be used with "
|
||||
"OpImageGather "
|
||||
@ -544,7 +548,8 @@ spv_result_t ValidateImageCommon(ValidationState_t& _,
|
||||
}
|
||||
}
|
||||
|
||||
if (opcode == SpvOpImageRead || opcode == SpvOpImageWrite) {
|
||||
if (opcode == SpvOpImageRead || opcode == SpvOpImageSparseRead ||
|
||||
opcode == SpvOpImageWrite) {
|
||||
if (info.sampled == 0) {
|
||||
} else if (info.sampled == 2) {
|
||||
if (info.dim == SpvDim1D && !_.HasCapability(SpvCapabilityImage1D)) {
|
||||
@ -589,6 +594,73 @@ spv_result_t ValidateImageCommon(ValidationState_t& _,
|
||||
return SPV_SUCCESS;
|
||||
}
|
||||
|
||||
// Returns true if opcode is *ImageSparse*, false otherwise.
|
||||
bool IsSparse(SpvOp opcode) {
|
||||
switch (opcode) {
|
||||
case SpvOpImageSparseSampleImplicitLod:
|
||||
case SpvOpImageSparseSampleExplicitLod:
|
||||
case SpvOpImageSparseSampleDrefImplicitLod:
|
||||
case SpvOpImageSparseSampleDrefExplicitLod:
|
||||
case SpvOpImageSparseSampleProjImplicitLod:
|
||||
case SpvOpImageSparseSampleProjExplicitLod:
|
||||
case SpvOpImageSparseSampleProjDrefImplicitLod:
|
||||
case SpvOpImageSparseSampleProjDrefExplicitLod:
|
||||
case SpvOpImageSparseFetch:
|
||||
case SpvOpImageSparseGather:
|
||||
case SpvOpImageSparseDrefGather:
|
||||
case SpvOpImageSparseTexelsResident:
|
||||
case SpvOpImageSparseRead: {
|
||||
return true;
|
||||
}
|
||||
|
||||
default: { return false; }
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Checks sparse image opcode result type and returns the second struct member.
|
||||
// Returns inst.type_id for non-sparse image opcodes.
|
||||
// Not valid for sparse image opcodes which do not return a struct.
|
||||
spv_result_t GetActualResultType(ValidationState_t& _,
|
||||
const spv_parsed_instruction_t& inst,
|
||||
uint32_t* actual_result_type) {
|
||||
const SpvOp opcode = static_cast<SpvOp>(inst.opcode);
|
||||
|
||||
if (IsSparse(opcode)) {
|
||||
const Instruction* const type_inst = _.FindDef(inst.type_id);
|
||||
assert(type_inst);
|
||||
|
||||
if (!type_inst || type_inst->opcode() != SpvOpTypeStruct) {
|
||||
return _.diag(SPV_ERROR_INVALID_DATA)
|
||||
<< spvOpcodeString(opcode)
|
||||
<< ": expected Result Type to be OpTypeStruct";
|
||||
}
|
||||
|
||||
if (type_inst->words().size() != 4 ||
|
||||
!_.IsIntScalarType(type_inst->word(2))) {
|
||||
return _.diag(SPV_ERROR_INVALID_DATA)
|
||||
<< spvOpcodeString(opcode)
|
||||
<< ": expected Result Type to be a struct containing an int "
|
||||
"scalar "
|
||||
<< "and a texel";
|
||||
}
|
||||
|
||||
*actual_result_type = type_inst->word(3);
|
||||
} else {
|
||||
*actual_result_type = inst.type_id;
|
||||
}
|
||||
|
||||
return SPV_SUCCESS;
|
||||
}
|
||||
|
||||
// Returns a string describing actual result type of an opcode.
|
||||
// Not valid for sparse image opcodes which do not return a struct.
|
||||
const char* GetActualResultTypeStr(SpvOp opcode) {
|
||||
if (IsSparse(opcode)) return "Result Type's second member";
|
||||
return "Result Type";
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
// Validates correctness of image instructions.
|
||||
@ -610,7 +682,7 @@ spv_result_t ImagePass(ValidationState_t& _,
|
||||
ImageTypeInfo info;
|
||||
if (!GetImageTypeInfo(_, inst->words[1], &info)) {
|
||||
return _.diag(SPV_ERROR_INVALID_DATA)
|
||||
<< "OpTypeImage: corrupt definition";
|
||||
<< "OpTypeImage: corrupt definition";
|
||||
}
|
||||
|
||||
const SpvOp sampled_type_opcode = _.GetIdOpcode(info.sampled_type);
|
||||
@ -618,48 +690,48 @@ spv_result_t ImagePass(ValidationState_t& _,
|
||||
sampled_type_opcode != SpvOpTypeInt &&
|
||||
sampled_type_opcode != SpvOpTypeFloat) {
|
||||
return _.diag(SPV_ERROR_INVALID_DATA)
|
||||
<< spvOpcodeString(opcode)
|
||||
<< ": expected Sampled Type to be either void or numerical scalar "
|
||||
<< "type";
|
||||
<< spvOpcodeString(opcode)
|
||||
<< ": expected Sampled Type to be either void or numerical "
|
||||
<< "scalar type";
|
||||
}
|
||||
|
||||
// Dim is checked elsewhere.
|
||||
|
||||
if (info.depth > 2) {
|
||||
return _.diag(SPV_ERROR_INVALID_DATA)
|
||||
<< spvOpcodeString(opcode)
|
||||
<< ": invalid Depth " << info.depth << " (must be 0, 1 or 2)";
|
||||
<< spvOpcodeString(opcode) << ": invalid Depth " << info.depth
|
||||
<< " (must be 0, 1 or 2)";
|
||||
}
|
||||
|
||||
if (info.arrayed > 1) {
|
||||
return _.diag(SPV_ERROR_INVALID_DATA)
|
||||
<< spvOpcodeString(opcode)
|
||||
<< ": invalid Arrayed " << info.arrayed << " (must be 0 or 1)";
|
||||
<< spvOpcodeString(opcode) << ": invalid Arrayed "
|
||||
<< info.arrayed << " (must be 0 or 1)";
|
||||
}
|
||||
|
||||
if (info.multisampled > 1) {
|
||||
return _.diag(SPV_ERROR_INVALID_DATA)
|
||||
<< spvOpcodeString(opcode)
|
||||
<< ": invalid MS " << info.multisampled << " (must be 0 or 1)";
|
||||
<< spvOpcodeString(opcode) << ": invalid MS "
|
||||
<< info.multisampled << " (must be 0 or 1)";
|
||||
}
|
||||
|
||||
if (info.sampled > 2) {
|
||||
return _.diag(SPV_ERROR_INVALID_DATA)
|
||||
<< spvOpcodeString(opcode)
|
||||
<< ": invalid Sampled " << info.sampled << " (must be 0, 1 or 2)";
|
||||
<< spvOpcodeString(opcode) << ": invalid Sampled "
|
||||
<< info.sampled << " (must be 0, 1 or 2)";
|
||||
}
|
||||
|
||||
if (info.dim == SpvDimSubpassData) {
|
||||
if (info.sampled != 2) {
|
||||
return _.diag(SPV_ERROR_INVALID_DATA)
|
||||
<< spvOpcodeString(opcode)
|
||||
<< ": Dim SubpassData requires Sampled to be 2";
|
||||
<< spvOpcodeString(opcode)
|
||||
<< ": Dim SubpassData requires Sampled to be 2";
|
||||
}
|
||||
|
||||
if (info.format != SpvImageFormatUnknown) {
|
||||
return _.diag(SPV_ERROR_INVALID_DATA)
|
||||
<< spvOpcodeString(opcode)
|
||||
<< ": Dim SubpassData requires format Unknown";
|
||||
<< spvOpcodeString(opcode)
|
||||
<< ": Dim SubpassData requires format Unknown";
|
||||
}
|
||||
}
|
||||
|
||||
@ -672,8 +744,8 @@ spv_result_t ImagePass(ValidationState_t& _,
|
||||
const uint32_t image_type = inst->words[2];
|
||||
if (_.GetIdOpcode(image_type) != SpvOpTypeImage) {
|
||||
return _.diag(SPV_ERROR_INVALID_DATA)
|
||||
<< spvOpcodeString(opcode)
|
||||
<< ": expected Image to be of type OpTypeImage";
|
||||
<< spvOpcodeString(opcode)
|
||||
<< ": expected Image to be of type OpTypeImage";
|
||||
}
|
||||
|
||||
break;
|
||||
@ -726,18 +798,27 @@ spv_result_t ImagePass(ValidationState_t& _,
|
||||
case SpvOpImageSampleImplicitLod:
|
||||
case SpvOpImageSampleExplicitLod:
|
||||
case SpvOpImageSampleProjImplicitLod:
|
||||
case SpvOpImageSampleProjExplicitLod: {
|
||||
if (!_.IsIntVectorType(result_type) &&
|
||||
!_.IsFloatVectorType(result_type)) {
|
||||
case SpvOpImageSampleProjExplicitLod:
|
||||
case SpvOpImageSparseSampleImplicitLod:
|
||||
case SpvOpImageSparseSampleExplicitLod: {
|
||||
uint32_t actual_result_type = 0;
|
||||
if (spv_result_t error =
|
||||
GetActualResultType(_, *inst, &actual_result_type)) {
|
||||
return error;
|
||||
}
|
||||
|
||||
if (!_.IsIntVectorType(actual_result_type) &&
|
||||
!_.IsFloatVectorType(actual_result_type)) {
|
||||
return _.diag(SPV_ERROR_INVALID_DATA)
|
||||
<< "Expected Result Type to be int or float vector type: "
|
||||
<< "Expected " << GetActualResultTypeStr(opcode)
|
||||
<< " to be int or float vector type: "
|
||||
<< spvOpcodeString(opcode);
|
||||
}
|
||||
|
||||
if (_.GetDimension(result_type) != 4) {
|
||||
if (_.GetDimension(actual_result_type) != 4) {
|
||||
return _.diag(SPV_ERROR_INVALID_DATA)
|
||||
<< "Expected Result Type to have 4 components: "
|
||||
<< spvOpcodeString(opcode);
|
||||
<< "Expected " << GetActualResultTypeStr(opcode)
|
||||
<< " to have 4 components: " << spvOpcodeString(opcode);
|
||||
}
|
||||
|
||||
const uint32_t image_type = _.GetOperandTypeId(inst, 2);
|
||||
@ -757,17 +838,19 @@ spv_result_t ImagePass(ValidationState_t& _,
|
||||
return result;
|
||||
|
||||
if (_.GetIdOpcode(info.sampled_type) != SpvOpTypeVoid) {
|
||||
const uint32_t result_component_type = _.GetComponentType(result_type);
|
||||
if (result_component_type != info.sampled_type) {
|
||||
const uint32_t texel_component_type =
|
||||
_.GetComponentType(actual_result_type);
|
||||
if (texel_component_type != info.sampled_type) {
|
||||
return _.diag(SPV_ERROR_INVALID_DATA)
|
||||
<< "Expected Image 'Sampled Type' to be the same as Result "
|
||||
"Type "
|
||||
<< "components: " << spvOpcodeString(opcode);
|
||||
<< "Expected Image 'Sampled Type' to be the same as "
|
||||
<< GetActualResultTypeStr(opcode)
|
||||
<< " components: " << spvOpcodeString(opcode);
|
||||
}
|
||||
}
|
||||
|
||||
const uint32_t coord_type = _.GetOperandTypeId(inst, 3);
|
||||
if (opcode == SpvOpImageSampleExplicitLod &&
|
||||
if ((opcode == SpvOpImageSampleExplicitLod ||
|
||||
opcode == SpvOpImageSparseSampleExplicitLod) &&
|
||||
_.HasCapability(SpvCapabilityKernel)) {
|
||||
if (!_.IsFloatScalarOrVectorType(coord_type) &&
|
||||
!_.IsIntScalarOrVectorType(coord_type)) {
|
||||
@ -808,11 +891,20 @@ spv_result_t ImagePass(ValidationState_t& _,
|
||||
case SpvOpImageSampleDrefImplicitLod:
|
||||
case SpvOpImageSampleDrefExplicitLod:
|
||||
case SpvOpImageSampleProjDrefImplicitLod:
|
||||
case SpvOpImageSampleProjDrefExplicitLod: {
|
||||
if (!_.IsIntScalarType(result_type) &&
|
||||
!_.IsFloatScalarType(result_type)) {
|
||||
case SpvOpImageSampleProjDrefExplicitLod:
|
||||
case SpvOpImageSparseSampleDrefImplicitLod:
|
||||
case SpvOpImageSparseSampleDrefExplicitLod: {
|
||||
uint32_t actual_result_type = 0;
|
||||
if (spv_result_t error =
|
||||
GetActualResultType(_, *inst, &actual_result_type)) {
|
||||
return error;
|
||||
}
|
||||
|
||||
if (!_.IsIntScalarType(actual_result_type) &&
|
||||
!_.IsFloatScalarType(actual_result_type)) {
|
||||
return _.diag(SPV_ERROR_INVALID_DATA)
|
||||
<< "Expected Result Type to be int or float scalar type: "
|
||||
<< "Expected " << GetActualResultTypeStr(opcode)
|
||||
<< " to be int or float scalar type: "
|
||||
<< spvOpcodeString(opcode);
|
||||
}
|
||||
|
||||
@ -832,10 +924,10 @@ spv_result_t ImagePass(ValidationState_t& _,
|
||||
if (spv_result_t result = ValidateImageCommon(_, *inst, info))
|
||||
return result;
|
||||
|
||||
if (result_type != info.sampled_type) {
|
||||
if (actual_result_type != info.sampled_type) {
|
||||
return _.diag(SPV_ERROR_INVALID_DATA)
|
||||
<< "Expected Image 'Sampled Type' to be the same as Result "
|
||||
"Type: "
|
||||
<< "Expected Image 'Sampled Type' to be the same as "
|
||||
<< GetActualResultTypeStr(opcode) << ": "
|
||||
<< spvOpcodeString(opcode);
|
||||
}
|
||||
|
||||
@ -875,18 +967,26 @@ spv_result_t ImagePass(ValidationState_t& _,
|
||||
break;
|
||||
}
|
||||
|
||||
case SpvOpImageFetch: {
|
||||
if (!_.IsIntVectorType(result_type) &&
|
||||
!_.IsFloatVectorType(result_type)) {
|
||||
case SpvOpImageFetch:
|
||||
case SpvOpImageSparseFetch: {
|
||||
uint32_t actual_result_type = 0;
|
||||
if (spv_result_t error =
|
||||
GetActualResultType(_, *inst, &actual_result_type)) {
|
||||
return error;
|
||||
}
|
||||
|
||||
if (!_.IsIntVectorType(actual_result_type) &&
|
||||
!_.IsFloatVectorType(actual_result_type)) {
|
||||
return _.diag(SPV_ERROR_INVALID_DATA)
|
||||
<< "Expected Result Type to be int or float vector type: "
|
||||
<< "Expected " << GetActualResultTypeStr(opcode)
|
||||
<< " to be int or float vector type: "
|
||||
<< spvOpcodeString(opcode);
|
||||
}
|
||||
|
||||
if (_.GetDimension(result_type) != 4) {
|
||||
if (_.GetDimension(actual_result_type) != 4) {
|
||||
return _.diag(SPV_ERROR_INVALID_DATA)
|
||||
<< "Expected Result Type to have 4 components: "
|
||||
<< spvOpcodeString(opcode);
|
||||
<< "Expected " << GetActualResultTypeStr(opcode)
|
||||
<< " to have 4 components: " << spvOpcodeString(opcode);
|
||||
}
|
||||
|
||||
const uint32_t image_type = _.GetOperandTypeId(inst, 2);
|
||||
@ -903,12 +1003,13 @@ spv_result_t ImagePass(ValidationState_t& _,
|
||||
}
|
||||
|
||||
if (_.GetIdOpcode(info.sampled_type) != SpvOpTypeVoid) {
|
||||
const uint32_t result_component_type = _.GetComponentType(result_type);
|
||||
const uint32_t result_component_type =
|
||||
_.GetComponentType(actual_result_type);
|
||||
if (result_component_type != info.sampled_type) {
|
||||
return _.diag(SPV_ERROR_INVALID_DATA)
|
||||
<< "Expected Image 'Sampled Type' to be the same as Result "
|
||||
"Type "
|
||||
<< "components: " << spvOpcodeString(opcode);
|
||||
<< "Expected Image 'Sampled Type' to be the same as "
|
||||
<< GetActualResultTypeStr(opcode)
|
||||
<< " components: " << spvOpcodeString(opcode);
|
||||
}
|
||||
}
|
||||
|
||||
@ -950,18 +1051,27 @@ spv_result_t ImagePass(ValidationState_t& _,
|
||||
}
|
||||
|
||||
case SpvOpImageGather:
|
||||
case SpvOpImageDrefGather: {
|
||||
if (!_.IsIntVectorType(result_type) &&
|
||||
!_.IsFloatVectorType(result_type)) {
|
||||
case SpvOpImageDrefGather:
|
||||
case SpvOpImageSparseGather:
|
||||
case SpvOpImageSparseDrefGather: {
|
||||
uint32_t actual_result_type = 0;
|
||||
if (spv_result_t error =
|
||||
GetActualResultType(_, *inst, &actual_result_type)) {
|
||||
return error;
|
||||
}
|
||||
|
||||
if (!_.IsIntVectorType(actual_result_type) &&
|
||||
!_.IsFloatVectorType(actual_result_type)) {
|
||||
return _.diag(SPV_ERROR_INVALID_DATA)
|
||||
<< "Expected Result Type to be int or float vector type: "
|
||||
<< "Expected " << GetActualResultTypeStr(opcode)
|
||||
<< " to be int or float vector type: "
|
||||
<< spvOpcodeString(opcode);
|
||||
}
|
||||
|
||||
if (_.GetDimension(result_type) != 4) {
|
||||
if (_.GetDimension(actual_result_type) != 4) {
|
||||
return _.diag(SPV_ERROR_INVALID_DATA)
|
||||
<< "Expected Result Type to have 4 components: "
|
||||
<< spvOpcodeString(opcode);
|
||||
<< "Expected " << GetActualResultTypeStr(opcode)
|
||||
<< " to have 4 components: " << spvOpcodeString(opcode);
|
||||
}
|
||||
|
||||
const uint32_t image_type = _.GetOperandTypeId(inst, 2);
|
||||
@ -978,13 +1088,15 @@ spv_result_t ImagePass(ValidationState_t& _,
|
||||
}
|
||||
|
||||
if (opcode == SpvOpImageDrefGather ||
|
||||
opcode == SpvOpImageSparseDrefGather ||
|
||||
_.GetIdOpcode(info.sampled_type) != SpvOpTypeVoid) {
|
||||
const uint32_t result_component_type = _.GetComponentType(result_type);
|
||||
const uint32_t result_component_type =
|
||||
_.GetComponentType(actual_result_type);
|
||||
if (result_component_type != info.sampled_type) {
|
||||
return _.diag(SPV_ERROR_INVALID_DATA)
|
||||
<< "Expected Image 'Sampled Type' to be the same as Result "
|
||||
"Type "
|
||||
<< "components: " << spvOpcodeString(opcode);
|
||||
<< "Expected Image 'Sampled Type' to be the same as "
|
||||
<< GetActualResultTypeStr(opcode)
|
||||
<< " components: " << spvOpcodeString(opcode);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1011,7 +1123,7 @@ spv_result_t ImagePass(ValidationState_t& _,
|
||||
<< spvOpcodeString(opcode);
|
||||
}
|
||||
|
||||
if (opcode == SpvOpImageGather) {
|
||||
if (opcode == SpvOpImageGather || opcode == SpvOpImageSparseGather) {
|
||||
const uint32_t component_index_type = _.GetOperandTypeId(inst, 4);
|
||||
if (!_.IsIntScalarType(component_index_type) ||
|
||||
_.GetBitWidth(component_index_type) != 32) {
|
||||
@ -1020,7 +1132,8 @@ spv_result_t ImagePass(ValidationState_t& _,
|
||||
<< spvOpcodeString(opcode);
|
||||
}
|
||||
} else {
|
||||
assert(opcode == SpvOpImageDrefGather);
|
||||
assert(opcode == SpvOpImageDrefGather ||
|
||||
opcode == SpvOpImageSparseDrefGather);
|
||||
const uint32_t dref_type = _.GetOperandTypeId(inst, 4);
|
||||
if (!_.IsFloatScalarType(dref_type) || _.GetBitWidth(dref_type) != 32) {
|
||||
return _.diag(SPV_ERROR_INVALID_DATA)
|
||||
@ -1039,21 +1152,28 @@ spv_result_t ImagePass(ValidationState_t& _,
|
||||
break;
|
||||
}
|
||||
|
||||
case SpvOpImageRead: {
|
||||
if (!_.IsIntScalarOrVectorType(result_type) &&
|
||||
!_.IsFloatScalarOrVectorType(result_type)) {
|
||||
case SpvOpImageRead:
|
||||
case SpvOpImageSparseRead: {
|
||||
uint32_t actual_result_type = 0;
|
||||
if (spv_result_t error =
|
||||
GetActualResultType(_, *inst, &actual_result_type)) {
|
||||
return error;
|
||||
}
|
||||
|
||||
if (!_.IsIntScalarOrVectorType(actual_result_type) &&
|
||||
!_.IsFloatScalarOrVectorType(actual_result_type)) {
|
||||
return _.diag(SPV_ERROR_INVALID_DATA)
|
||||
<< "Expected Result Type to be int or float scalar or vector "
|
||||
"type: "
|
||||
<< "Expected " << GetActualResultTypeStr(opcode)
|
||||
<< " to be int or float scalar or vector type: "
|
||||
<< spvOpcodeString(opcode);
|
||||
}
|
||||
|
||||
#if 0
|
||||
// TODO(atgoo@github.com) Disabled until the spec is clarified.
|
||||
if (_.GetDimension(result_type) != 4) {
|
||||
if (_.GetDimension(actual_result_type) != 4) {
|
||||
return _.diag(SPV_ERROR_INVALID_DATA)
|
||||
<< "Expected Result Type to have 4 components: "
|
||||
<< spvOpcodeString(opcode);
|
||||
<< "Expected " << GetActualResultTypeStr(opcode)
|
||||
<< " to have 4 components: " << spvOpcodeString(opcode);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -1074,16 +1194,17 @@ spv_result_t ImagePass(ValidationState_t& _,
|
||||
_.current_function().RegisterExecutionModelLimitation(
|
||||
SpvExecutionModelFragment,
|
||||
std::string("Dim SubpassData requires Fragment execution model: ") +
|
||||
spvOpcodeString(opcode));
|
||||
spvOpcodeString(opcode));
|
||||
}
|
||||
|
||||
if (_.GetIdOpcode(info.sampled_type) != SpvOpTypeVoid) {
|
||||
const uint32_t result_component_type = _.GetComponentType(result_type);
|
||||
const uint32_t result_component_type =
|
||||
_.GetComponentType(actual_result_type);
|
||||
if (result_component_type != info.sampled_type) {
|
||||
return _.diag(SPV_ERROR_INVALID_DATA)
|
||||
<< "Expected Image 'Sampled Type' to be the same as Result "
|
||||
"Type "
|
||||
<< "components: " << spvOpcodeString(opcode);
|
||||
<< "Expected Image 'Sampled Type' to be the same as "
|
||||
<< GetActualResultTypeStr(opcode)
|
||||
<< " components: " << spvOpcodeString(opcode);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1111,8 +1232,7 @@ spv_result_t ImagePass(ValidationState_t& _,
|
||||
!_.HasCapability(SpvCapabilityStorageImageReadWithoutFormat)) {
|
||||
return _.diag(SPV_ERROR_INVALID_DATA)
|
||||
<< "Capability StorageImageReadWithoutFormat is required to "
|
||||
"read "
|
||||
<< "storage image: " << spvOpcodeString(opcode);
|
||||
<< "read storage image: " << spvOpcodeString(opcode);
|
||||
}
|
||||
|
||||
if (inst->num_words <= 5) break;
|
||||
@ -1494,6 +1614,32 @@ spv_result_t ImagePass(ValidationState_t& _,
|
||||
break;
|
||||
}
|
||||
|
||||
case SpvOpImageSparseSampleProjImplicitLod:
|
||||
case SpvOpImageSparseSampleProjExplicitLod:
|
||||
case SpvOpImageSparseSampleProjDrefImplicitLod:
|
||||
case SpvOpImageSparseSampleProjDrefExplicitLod: {
|
||||
return _.diag(SPV_ERROR_INVALID_DATA)
|
||||
<< spvOpcodeString(opcode)
|
||||
<< ": instruction reserved for future use, "
|
||||
<< "use of this instruction is invalid";
|
||||
}
|
||||
|
||||
case SpvOpImageSparseTexelsResident: {
|
||||
if (!_.IsBoolScalarType(result_type)) {
|
||||
return _.diag(SPV_ERROR_INVALID_DATA)
|
||||
<< spvOpcodeString(opcode)
|
||||
<< ": expected Result Type to be bool scalar type";
|
||||
}
|
||||
|
||||
const uint32_t resident_code_type = _.GetOperandTypeId(inst, 2);
|
||||
if (!_.IsIntScalarType(resident_code_type)) {
|
||||
return _.diag(SPV_ERROR_INVALID_DATA)
|
||||
<< spvOpcodeString(opcode)
|
||||
<< ": expected Resident Code to be int scalar";
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -43,6 +43,7 @@ OpCapability Sampled1D
|
||||
OpCapability SampledRect
|
||||
OpCapability ImageQuery
|
||||
OpCapability Int64
|
||||
OpCapability SparseResidency
|
||||
)";
|
||||
|
||||
ss << capabilities_and_extensions;
|
||||
@ -97,6 +98,18 @@ OpCapability Int64
|
||||
%u32arr4 = OpTypeArray %u32 %u32_4
|
||||
%u32vec3arr4 = OpTypeArray %u32vec3 %u32_4
|
||||
|
||||
%struct_u32_f32vec4 = OpTypeStruct %u32 %f32vec4
|
||||
%struct_u64_f32vec4 = OpTypeStruct %u64 %f32vec4
|
||||
%struct_u32_u32vec4 = OpTypeStruct %u32 %u32vec4
|
||||
%struct_u32_f32vec3 = OpTypeStruct %u32 %f32vec3
|
||||
%struct_f32_f32vec4 = OpTypeStruct %f32 %f32vec4
|
||||
%struct_u32_u32 = OpTypeStruct %u32 %u32
|
||||
%struct_f32_f32 = OpTypeStruct %f32 %f32
|
||||
%struct_u32 = OpTypeStruct %u32
|
||||
%struct_u32_f32_u32 = OpTypeStruct %u32 %f32 %u32
|
||||
%struct_u32_f32vec4_u32 = OpTypeStruct %u32 %f32vec4 %u32
|
||||
%struct_u32_u32arr4 = OpTypeStruct %u32 %u32arr4
|
||||
|
||||
%u32vec2_01 = OpConstantComposite %u32vec2 %u32_0 %u32_1
|
||||
%u32vec2_12 = OpConstantComposite %u32vec2 %u32_1 %u32_2
|
||||
%u32vec3_012 = OpConstantComposite %u32vec3 %u32_0 %u32_1 %u32_2
|
||||
@ -174,7 +187,7 @@ OpCapability Int64
|
||||
|
||||
%type_image_f32_2d_0002 = OpTypeImage %f32 2D 0 0 0 2 Unknown
|
||||
%ptr_image_f32_2d_0002 = OpTypePointer UniformConstant %type_image_f32_2d_0002
|
||||
%uniform_image_f32_2d_0002 = OpVariable %ptr_image_f32_2d_0001 UniformConstant
|
||||
%uniform_image_f32_2d_0002 = OpVariable %ptr_image_f32_2d_0002 UniformConstant
|
||||
%type_sampled_image_f32_2d_0002 = OpTypeSampledImage %type_image_f32_2d_0002
|
||||
|
||||
%type_image_f32_spd_0002 = OpTypeImage %f32 SubpassData 0 0 0 2 Unknown
|
||||
@ -338,94 +351,96 @@ OpEntryPoint Fragment %main "main"
|
||||
}
|
||||
|
||||
TEST_F(ValidateImage, TypeImageWrongSampledType) {
|
||||
const std::string code = GetShaderHeader() + R"(
|
||||
const std::string code = GetShaderHeader() + R"(
|
||||
%img_type = OpTypeImage %bool 2D 0 0 0 1 Unknown
|
||||
)";
|
||||
|
||||
CompileSuccessfully(code.c_str());
|
||||
ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
|
||||
EXPECT_THAT(getDiagnosticString(), HasSubstr(
|
||||
"TypeImage: expected Sampled Type to be either void or numerical scalar "
|
||||
"type"));
|
||||
EXPECT_THAT(getDiagnosticString(),
|
||||
HasSubstr("TypeImage: expected Sampled Type to be either void or "
|
||||
"numerical scalar "
|
||||
"type"));
|
||||
}
|
||||
|
||||
TEST_F(ValidateImage, TypeImageWrongDepth) {
|
||||
const std::string code = GetShaderHeader() + R"(
|
||||
const std::string code = GetShaderHeader() + R"(
|
||||
%img_type = OpTypeImage %f32 2D 3 0 0 1 Unknown
|
||||
)";
|
||||
|
||||
CompileSuccessfully(code.c_str());
|
||||
ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
|
||||
EXPECT_THAT(getDiagnosticString(), HasSubstr(
|
||||
"TypeImage: invalid Depth 3 (must be 0, 1 or 2)"));
|
||||
EXPECT_THAT(getDiagnosticString(),
|
||||
HasSubstr("TypeImage: invalid Depth 3 (must be 0, 1 or 2)"));
|
||||
}
|
||||
|
||||
TEST_F(ValidateImage, TypeImageWrongArrayed) {
|
||||
const std::string code = GetShaderHeader() + R"(
|
||||
const std::string code = GetShaderHeader() + R"(
|
||||
%img_type = OpTypeImage %f32 2D 0 2 0 1 Unknown
|
||||
)";
|
||||
|
||||
CompileSuccessfully(code.c_str());
|
||||
ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
|
||||
EXPECT_THAT(getDiagnosticString(), HasSubstr(
|
||||
"TypeImage: invalid Arrayed 2 (must be 0 or 1)"));
|
||||
EXPECT_THAT(getDiagnosticString(),
|
||||
HasSubstr("TypeImage: invalid Arrayed 2 (must be 0 or 1)"));
|
||||
}
|
||||
|
||||
TEST_F(ValidateImage, TypeImageWrongMS) {
|
||||
const std::string code = GetShaderHeader() + R"(
|
||||
const std::string code = GetShaderHeader() + R"(
|
||||
%img_type = OpTypeImage %f32 2D 0 0 2 1 Unknown
|
||||
)";
|
||||
|
||||
CompileSuccessfully(code.c_str());
|
||||
ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
|
||||
EXPECT_THAT(getDiagnosticString(), HasSubstr(
|
||||
"TypeImage: invalid MS 2 (must be 0 or 1)"));
|
||||
EXPECT_THAT(getDiagnosticString(),
|
||||
HasSubstr("TypeImage: invalid MS 2 (must be 0 or 1)"));
|
||||
}
|
||||
|
||||
TEST_F(ValidateImage, TypeImageWrongSampled) {
|
||||
const std::string code = GetShaderHeader() + R"(
|
||||
const std::string code = GetShaderHeader() + R"(
|
||||
%img_type = OpTypeImage %f32 2D 0 0 0 3 Unknown
|
||||
)";
|
||||
|
||||
CompileSuccessfully(code.c_str());
|
||||
ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
|
||||
EXPECT_THAT(getDiagnosticString(), HasSubstr(
|
||||
"TypeImage: invalid Sampled 3 (must be 0, 1 or 2)"));
|
||||
EXPECT_THAT(getDiagnosticString(),
|
||||
HasSubstr("TypeImage: invalid Sampled 3 (must be 0, 1 or 2)"));
|
||||
}
|
||||
|
||||
TEST_F(ValidateImage, TypeImageWrongSampledForSubpassData) {
|
||||
const std::string code = GetShaderHeader("OpCapability InputAttachment\n") +
|
||||
R"(
|
||||
R"(
|
||||
%img_type = OpTypeImage %f32 SubpassData 0 0 0 1 Unknown
|
||||
)";
|
||||
|
||||
CompileSuccessfully(code.c_str());
|
||||
ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
|
||||
EXPECT_THAT(getDiagnosticString(), HasSubstr(
|
||||
"TypeImage: Dim SubpassData requires Sampled to be 2"));
|
||||
EXPECT_THAT(getDiagnosticString(),
|
||||
HasSubstr("TypeImage: Dim SubpassData requires Sampled to be 2"));
|
||||
}
|
||||
|
||||
TEST_F(ValidateImage, TypeImageWrongFormatForSubpassData) {
|
||||
const std::string code = GetShaderHeader("OpCapability InputAttachment\n") +
|
||||
R"(
|
||||
R"(
|
||||
%img_type = OpTypeImage %f32 SubpassData 0 0 0 2 Rgba32f
|
||||
)";
|
||||
|
||||
CompileSuccessfully(code.c_str());
|
||||
ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
|
||||
EXPECT_THAT(getDiagnosticString(), HasSubstr(
|
||||
"TypeImage: Dim SubpassData requires format Unknown"));
|
||||
EXPECT_THAT(getDiagnosticString(),
|
||||
HasSubstr("TypeImage: Dim SubpassData requires format Unknown"));
|
||||
}
|
||||
|
||||
TEST_F(ValidateImage, TypeSampledImageNotImage) {
|
||||
const std::string code = GetShaderHeader() + R"(
|
||||
const std::string code = GetShaderHeader() + R"(
|
||||
%simg_type = OpTypeSampledImage %f32
|
||||
)";
|
||||
|
||||
CompileSuccessfully(code.c_str());
|
||||
ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
|
||||
EXPECT_THAT(getDiagnosticString(), HasSubstr(
|
||||
"TypeSampledImage: expected Image to be of type OpTypeImage"));
|
||||
EXPECT_THAT(
|
||||
getDiagnosticString(),
|
||||
HasSubstr("TypeSampledImage: expected Image to be of type OpTypeImage"));
|
||||
}
|
||||
|
||||
TEST_F(ValidateImage, SampledImageSuccess) {
|
||||
@ -3369,8 +3384,566 @@ TEST_F(ValidateImage, ReadSubpassDataWrongExecutionModel) {
|
||||
const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
|
||||
CompileSuccessfully(GenerateShaderCode(body, extra, "Vertex").c_str());
|
||||
ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
|
||||
EXPECT_THAT(getDiagnosticString(), HasSubstr(
|
||||
"Dim SubpassData requires Fragment execution model: ImageRead"));
|
||||
EXPECT_THAT(
|
||||
getDiagnosticString(),
|
||||
HasSubstr(
|
||||
"Dim SubpassData requires Fragment execution model: ImageRead"));
|
||||
}
|
||||
|
||||
TEST_F(ValidateImage, SparseSampleImplicitLodSuccess) {
|
||||
const std::string body = R"(
|
||||
%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
|
||||
%sampler = OpLoad %type_sampler %uniform_sampler
|
||||
%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
|
||||
%res1 = OpImageSparseSampleImplicitLod %struct_u32_f32vec4 %simg %f32vec2_hh
|
||||
%res2 = OpImageSparseSampleImplicitLod %struct_u32_f32vec4 %simg %f32vec2_hh Bias %f32_0_25
|
||||
%res4 = OpImageSparseSampleImplicitLod %struct_u32_f32vec4 %simg %f32vec2_hh ConstOffset %s32vec2_01
|
||||
%res5 = OpImageSparseSampleImplicitLod %struct_u32_f32vec4 %simg %f32vec2_hh Offset %s32vec2_01
|
||||
%res6 = OpImageSparseSampleImplicitLod %struct_u32_f32vec4 %simg %f32vec2_hh MinLod %f32_0_5
|
||||
%res7 = OpImageSparseSampleImplicitLod %struct_u64_f32vec4 %simg %f32vec2_hh Bias|Offset|MinLod %f32_0_25 %s32vec2_01 %f32_0_5
|
||||
)";
|
||||
|
||||
CompileSuccessfully(GenerateShaderCode(body).c_str());
|
||||
ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
|
||||
}
|
||||
|
||||
TEST_F(ValidateImage, SparseSampleImplicitLodResultTypeNotStruct) {
|
||||
const std::string body = R"(
|
||||
%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
|
||||
%sampler = OpLoad %type_sampler %uniform_sampler
|
||||
%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
|
||||
%res1 = OpImageSparseSampleImplicitLod %f32 %simg %f32vec2_hh
|
||||
)";
|
||||
|
||||
CompileSuccessfully(GenerateShaderCode(body).c_str());
|
||||
ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
|
||||
EXPECT_THAT(getDiagnosticString(),
|
||||
HasSubstr("ImageSparseSampleImplicitLod: "
|
||||
"expected Result Type to be OpTypeStruct"));
|
||||
}
|
||||
|
||||
TEST_F(ValidateImage, SparseSampleImplicitLodResultTypeNotTwoMembers1) {
|
||||
const std::string body = R"(
|
||||
%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
|
||||
%sampler = OpLoad %type_sampler %uniform_sampler
|
||||
%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
|
||||
%res1 = OpImageSparseSampleImplicitLod %struct_u32 %simg %f32vec2_hh
|
||||
)";
|
||||
|
||||
CompileSuccessfully(GenerateShaderCode(body).c_str());
|
||||
ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
|
||||
EXPECT_THAT(getDiagnosticString(),
|
||||
HasSubstr("ImageSparseSampleImplicitLod: expected Result Type "
|
||||
"to be a struct containing an int scalar and a texel"));
|
||||
}
|
||||
|
||||
TEST_F(ValidateImage, SparseSampleImplicitLodResultTypeNotTwoMembers2) {
|
||||
const std::string body = R"(
|
||||
%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
|
||||
%sampler = OpLoad %type_sampler %uniform_sampler
|
||||
%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
|
||||
%res1 = OpImageSparseSampleImplicitLod %struct_u32_f32vec4_u32 %simg %f32vec2_hh
|
||||
)";
|
||||
|
||||
CompileSuccessfully(GenerateShaderCode(body).c_str());
|
||||
ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
|
||||
EXPECT_THAT(getDiagnosticString(),
|
||||
HasSubstr("ImageSparseSampleImplicitLod: expected Result Type "
|
||||
"to be a struct containing an int scalar and a texel"));
|
||||
}
|
||||
|
||||
TEST_F(ValidateImage, SparseSampleImplicitLodResultTypeFirstMemberNotInt) {
|
||||
const std::string body = R"(
|
||||
%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
|
||||
%sampler = OpLoad %type_sampler %uniform_sampler
|
||||
%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
|
||||
%res1 = OpImageSparseSampleImplicitLod %struct_f32_f32vec4 %simg %f32vec2_hh
|
||||
)";
|
||||
|
||||
CompileSuccessfully(GenerateShaderCode(body).c_str());
|
||||
ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
|
||||
EXPECT_THAT(getDiagnosticString(),
|
||||
HasSubstr("ImageSparseSampleImplicitLod: expected Result Type "
|
||||
"to be a struct containing an int scalar and a texel"));
|
||||
}
|
||||
|
||||
TEST_F(ValidateImage, SparseSampleImplicitLodResultTypeTexelNotVector) {
|
||||
const std::string body = R"(
|
||||
%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
|
||||
%sampler = OpLoad %type_sampler %uniform_sampler
|
||||
%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
|
||||
%res1 = OpImageSparseSampleImplicitLod %struct_u32_u32 %simg %f32vec2_hh
|
||||
)";
|
||||
|
||||
CompileSuccessfully(GenerateShaderCode(body).c_str());
|
||||
ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
|
||||
EXPECT_THAT(getDiagnosticString(),
|
||||
HasSubstr("Expected Result Type's second member to be int or "
|
||||
"float vector type: ImageSparseSampleImplicitLod"));
|
||||
}
|
||||
|
||||
TEST_F(ValidateImage, SparseSampleImplicitLodWrongNumComponentsTexel) {
|
||||
const std::string body = R"(
|
||||
%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
|
||||
%sampler = OpLoad %type_sampler %uniform_sampler
|
||||
%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
|
||||
%res1 = OpImageSparseSampleImplicitLod %struct_u32_f32vec3 %simg %f32vec2_hh
|
||||
)";
|
||||
|
||||
CompileSuccessfully(GenerateShaderCode(body).c_str());
|
||||
ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
|
||||
EXPECT_THAT(getDiagnosticString(),
|
||||
HasSubstr("Expected Result Type's second member to have 4 "
|
||||
"components: ImageSparseSampleImplicitLod"));
|
||||
}
|
||||
|
||||
TEST_F(ValidateImage, SparseSampleImplicitLodWrongComponentTypeTexel) {
|
||||
const std::string body = R"(
|
||||
%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
|
||||
%sampler = OpLoad %type_sampler %uniform_sampler
|
||||
%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
|
||||
%res1 = OpImageSparseSampleImplicitLod %struct_u32_u32vec4 %simg %f32vec2_hh
|
||||
)";
|
||||
|
||||
CompileSuccessfully(GenerateShaderCode(body).c_str());
|
||||
ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
|
||||
EXPECT_THAT(getDiagnosticString(),
|
||||
HasSubstr("Expected Image 'Sampled Type' to be the same as "
|
||||
"Result Type's second member components: "
|
||||
"ImageSparseSampleImplicitLod"));
|
||||
}
|
||||
|
||||
TEST_F(ValidateImage, SparseSampleDrefImplicitLodSuccess) {
|
||||
const std::string body = R"(
|
||||
%img = OpLoad %type_image_u32_2d_0001 %uniform_image_u32_2d_0001
|
||||
%sampler = OpLoad %type_sampler %uniform_sampler
|
||||
%simg = OpSampledImage %type_sampled_image_u32_2d_0001 %img %sampler
|
||||
%res1 = OpImageSparseSampleDrefImplicitLod %struct_u32_u32 %simg %f32vec2_hh %f32_1
|
||||
%res2 = OpImageSparseSampleDrefImplicitLod %struct_u32_u32 %simg %f32vec2_hh %f32_1 Bias %f32_0_25
|
||||
%res4 = OpImageSparseSampleDrefImplicitLod %struct_u32_u32 %simg %f32vec2_hh %f32_1 ConstOffset %s32vec2_01
|
||||
%res5 = OpImageSparseSampleDrefImplicitLod %struct_u32_u32 %simg %f32vec2_hh %f32_1 Offset %s32vec2_01
|
||||
%res6 = OpImageSparseSampleDrefImplicitLod %struct_u32_u32 %simg %f32vec2_hh %f32_1 MinLod %f32_0_5
|
||||
%res7 = OpImageSparseSampleDrefImplicitLod %struct_u32_u32 %simg %f32vec2_hh %f32_1 Bias|Offset|MinLod %f32_0_25 %s32vec2_01 %f32_0_5
|
||||
)";
|
||||
|
||||
CompileSuccessfully(GenerateShaderCode(body).c_str());
|
||||
ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
|
||||
}
|
||||
|
||||
TEST_F(ValidateImage, SparseSampleDrefImplicitLodResultTypeNotStruct) {
|
||||
const std::string body = R"(
|
||||
%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
|
||||
%sampler = OpLoad %type_sampler %uniform_sampler
|
||||
%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
|
||||
%res1 = OpImageSparseSampleDrefImplicitLod %f32 %simg %f32vec2_hh %f32_1
|
||||
)";
|
||||
|
||||
CompileSuccessfully(GenerateShaderCode(body).c_str());
|
||||
ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
|
||||
EXPECT_THAT(getDiagnosticString(),
|
||||
HasSubstr("ImageSparseSampleDrefImplicitLod: "
|
||||
"expected Result Type to be OpTypeStruct"));
|
||||
}
|
||||
|
||||
TEST_F(ValidateImage, SparseSampleDrefImplicitLodResultTypeNotTwoMembers1) {
|
||||
const std::string body = R"(
|
||||
%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
|
||||
%sampler = OpLoad %type_sampler %uniform_sampler
|
||||
%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
|
||||
%res1 = OpImageSparseSampleDrefImplicitLod %struct_u32 %simg %f32vec2_hh %f32_1
|
||||
)";
|
||||
|
||||
CompileSuccessfully(GenerateShaderCode(body).c_str());
|
||||
ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
|
||||
EXPECT_THAT(
|
||||
getDiagnosticString(),
|
||||
HasSubstr("ImageSparseSampleDrefImplicitLod: expected Result Type "
|
||||
"to be a struct containing an int scalar and a texel"));
|
||||
}
|
||||
|
||||
TEST_F(ValidateImage, SparseSampleDrefImplicitLodResultTypeNotTwoMembers2) {
|
||||
const std::string body = R"(
|
||||
%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
|
||||
%sampler = OpLoad %type_sampler %uniform_sampler
|
||||
%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
|
||||
%res1 = OpImageSparseSampleDrefImplicitLod %struct_u32_f32_u32 %simg %f32vec2_hh %f32_1
|
||||
)";
|
||||
|
||||
CompileSuccessfully(GenerateShaderCode(body).c_str());
|
||||
ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
|
||||
EXPECT_THAT(
|
||||
getDiagnosticString(),
|
||||
HasSubstr("ImageSparseSampleDrefImplicitLod: expected Result Type "
|
||||
"to be a struct containing an int scalar and a texel"));
|
||||
}
|
||||
|
||||
TEST_F(ValidateImage, SparseSampleDrefImplicitLodResultTypeFirstMemberNotInt) {
|
||||
const std::string body = R"(
|
||||
%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
|
||||
%sampler = OpLoad %type_sampler %uniform_sampler
|
||||
%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
|
||||
%res1 = OpImageSparseSampleDrefImplicitLod %struct_f32_f32 %simg %f32vec2_hh %f32_1
|
||||
)";
|
||||
|
||||
CompileSuccessfully(GenerateShaderCode(body).c_str());
|
||||
ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
|
||||
EXPECT_THAT(
|
||||
getDiagnosticString(),
|
||||
HasSubstr("ImageSparseSampleDrefImplicitLod: expected Result Type "
|
||||
"to be a struct containing an int scalar and a texel"));
|
||||
}
|
||||
|
||||
TEST_F(ValidateImage, SparseSampleDrefImplicitLodDifferentSampledType) {
|
||||
const std::string body = R"(
|
||||
%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
|
||||
%sampler = OpLoad %type_sampler %uniform_sampler
|
||||
%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
|
||||
%res1 = OpImageSparseSampleDrefImplicitLod %struct_u32_u32 %simg %f32vec2_hh %f32_1
|
||||
)";
|
||||
|
||||
CompileSuccessfully(GenerateShaderCode(body).c_str());
|
||||
ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
|
||||
EXPECT_THAT(getDiagnosticString(),
|
||||
HasSubstr("Expected Image 'Sampled Type' to be the same as "
|
||||
"Result Type's second member: "
|
||||
"ImageSparseSampleDrefImplicitLod"));
|
||||
}
|
||||
|
||||
TEST_F(ValidateImage, SparseFetchSuccess) {
|
||||
const std::string body = R"(
|
||||
%img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
|
||||
%res1 = OpImageSparseFetch %struct_u32_f32vec4 %img %u32vec2_01
|
||||
)";
|
||||
|
||||
CompileSuccessfully(GenerateShaderCode(body).c_str());
|
||||
ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
|
||||
}
|
||||
|
||||
TEST_F(ValidateImage, SparseFetchResultTypeNotStruct) {
|
||||
const std::string body = R"(
|
||||
%img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
|
||||
%res1 = OpImageSparseFetch %f32 %img %u32vec2_01
|
||||
)";
|
||||
|
||||
CompileSuccessfully(GenerateShaderCode(body).c_str());
|
||||
ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
|
||||
EXPECT_THAT(getDiagnosticString(),
|
||||
HasSubstr("ImageSparseFetch: "
|
||||
"expected Result Type to be OpTypeStruct"));
|
||||
}
|
||||
|
||||
TEST_F(ValidateImage, SparseFetchResultTypeNotTwoMembers1) {
|
||||
const std::string body = R"(
|
||||
%img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
|
||||
%res1 = OpImageSparseFetch %struct_u32 %img %u32vec2_01
|
||||
)";
|
||||
|
||||
CompileSuccessfully(GenerateShaderCode(body).c_str());
|
||||
ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
|
||||
EXPECT_THAT(getDiagnosticString(),
|
||||
HasSubstr("ImageSparseFetch: expected Result Type "
|
||||
"to be a struct containing an int scalar and a texel"));
|
||||
}
|
||||
|
||||
TEST_F(ValidateImage, SparseFetchResultTypeNotTwoMembers2) {
|
||||
const std::string body = R"(
|
||||
%img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
|
||||
%res1 = OpImageSparseFetch %struct_u32_f32vec4_u32 %img %u32vec2_01
|
||||
)";
|
||||
|
||||
CompileSuccessfully(GenerateShaderCode(body).c_str());
|
||||
ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
|
||||
EXPECT_THAT(getDiagnosticString(),
|
||||
HasSubstr("ImageSparseFetch: expected Result Type "
|
||||
"to be a struct containing an int scalar and a texel"));
|
||||
}
|
||||
|
||||
TEST_F(ValidateImage, SparseFetchResultTypeFirstMemberNotInt) {
|
||||
const std::string body = R"(
|
||||
%img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
|
||||
%res1 = OpImageSparseFetch %struct_f32_f32vec4 %img %u32vec2_01
|
||||
)";
|
||||
|
||||
CompileSuccessfully(GenerateShaderCode(body).c_str());
|
||||
ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
|
||||
EXPECT_THAT(getDiagnosticString(),
|
||||
HasSubstr("ImageSparseFetch: expected Result Type "
|
||||
"to be a struct containing an int scalar and a texel"));
|
||||
}
|
||||
|
||||
TEST_F(ValidateImage, SparseFetchResultTypeTexelNotVector) {
|
||||
const std::string body = R"(
|
||||
%img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
|
||||
%res1 = OpImageSparseFetch %struct_u32_u32 %img %u32vec2_01
|
||||
)";
|
||||
|
||||
CompileSuccessfully(GenerateShaderCode(body).c_str());
|
||||
ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
|
||||
EXPECT_THAT(getDiagnosticString(),
|
||||
HasSubstr("Expected Result Type's second member to be int or "
|
||||
"float vector type: ImageSparseFetch"));
|
||||
}
|
||||
|
||||
TEST_F(ValidateImage, SparseFetchWrongNumComponentsTexel) {
|
||||
const std::string body = R"(
|
||||
%img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
|
||||
%res1 = OpImageSparseFetch %struct_u32_f32vec3 %img %u32vec2_01
|
||||
)";
|
||||
|
||||
CompileSuccessfully(GenerateShaderCode(body).c_str());
|
||||
ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
|
||||
EXPECT_THAT(getDiagnosticString(),
|
||||
HasSubstr("Expected Result Type's second member to have 4 "
|
||||
"components: ImageSparseFetch"));
|
||||
}
|
||||
|
||||
TEST_F(ValidateImage, SparseFetchWrongComponentTypeTexel) {
|
||||
const std::string body = R"(
|
||||
%img = OpLoad %type_image_f32_rect_0001 %uniform_image_f32_rect_0001
|
||||
%res1 = OpImageSparseFetch %struct_u32_u32vec4 %img %u32vec2_01
|
||||
)";
|
||||
|
||||
CompileSuccessfully(GenerateShaderCode(body).c_str());
|
||||
ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
|
||||
EXPECT_THAT(getDiagnosticString(),
|
||||
HasSubstr("Expected Image 'Sampled Type' to be the same as "
|
||||
"Result Type's second member components: "
|
||||
"ImageSparseFetch"));
|
||||
}
|
||||
|
||||
TEST_F(ValidateImage, SparseReadSuccess) {
|
||||
const std::string body = R"(
|
||||
%img = OpLoad %type_image_f32_2d_0002 %uniform_image_f32_2d_0002
|
||||
%res1 = OpImageSparseRead %struct_u32_f32vec4 %img %u32vec2_01
|
||||
)";
|
||||
|
||||
const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
|
||||
CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
|
||||
ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
|
||||
}
|
||||
|
||||
TEST_F(ValidateImage, SparseReadResultTypeNotStruct) {
|
||||
const std::string body = R"(
|
||||
%img = OpLoad %type_image_f32_2d_0002 %uniform_image_f32_2d_0002
|
||||
%res1 = OpImageSparseRead %f32 %img %u32vec2_01
|
||||
)";
|
||||
|
||||
const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
|
||||
CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
|
||||
ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
|
||||
EXPECT_THAT(getDiagnosticString(),
|
||||
HasSubstr("ImageSparseRead: "
|
||||
"expected Result Type to be OpTypeStruct"));
|
||||
}
|
||||
|
||||
TEST_F(ValidateImage, SparseReadResultTypeNotTwoMembers1) {
|
||||
const std::string body = R"(
|
||||
%img = OpLoad %type_image_f32_2d_0002 %uniform_image_f32_2d_0002
|
||||
%res1 = OpImageSparseRead %struct_u32 %img %u32vec2_01
|
||||
)";
|
||||
|
||||
const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
|
||||
CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
|
||||
ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
|
||||
EXPECT_THAT(getDiagnosticString(),
|
||||
HasSubstr("ImageSparseRead: expected Result Type "
|
||||
"to be a struct containing an int scalar and a texel"));
|
||||
}
|
||||
|
||||
TEST_F(ValidateImage, SparseReadResultTypeNotTwoMembers2) {
|
||||
const std::string body = R"(
|
||||
%img = OpLoad %type_image_f32_2d_0002 %uniform_image_f32_2d_0002
|
||||
%res1 = OpImageSparseRead %struct_u32_f32vec4_u32 %img %u32vec2_01
|
||||
)";
|
||||
|
||||
const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
|
||||
CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
|
||||
ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
|
||||
EXPECT_THAT(getDiagnosticString(),
|
||||
HasSubstr("ImageSparseRead: expected Result Type "
|
||||
"to be a struct containing an int scalar and a texel"));
|
||||
}
|
||||
|
||||
TEST_F(ValidateImage, SparseReadResultTypeFirstMemberNotInt) {
|
||||
const std::string body = R"(
|
||||
%img = OpLoad %type_image_f32_2d_0002 %uniform_image_f32_2d_0002
|
||||
%res1 = OpImageSparseRead %struct_f32_f32vec4 %img %u32vec2_01
|
||||
)";
|
||||
|
||||
const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
|
||||
CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
|
||||
ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
|
||||
EXPECT_THAT(getDiagnosticString(),
|
||||
HasSubstr("ImageSparseRead: expected Result Type "
|
||||
"to be a struct containing an int scalar and a texel"));
|
||||
}
|
||||
|
||||
TEST_F(ValidateImage, SparseReadResultTypeTexelWrongType) {
|
||||
const std::string body = R"(
|
||||
%img = OpLoad %type_image_f32_2d_0002 %uniform_image_f32_2d_0002
|
||||
%res1 = OpImageSparseRead %struct_u32_u32arr4 %img %u32vec2_01
|
||||
)";
|
||||
|
||||
const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
|
||||
CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
|
||||
ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
|
||||
EXPECT_THAT(getDiagnosticString(),
|
||||
HasSubstr("Expected Result Type's second member to be int or "
|
||||
"float scalar or vector type: ImageSparseRead"));
|
||||
}
|
||||
|
||||
TEST_F(ValidateImage, SparseReadWrongComponentTypeTexel) {
|
||||
const std::string body = R"(
|
||||
%img = OpLoad %type_image_f32_2d_0002 %uniform_image_f32_2d_0002
|
||||
%res1 = OpImageSparseRead %struct_u32_u32vec4 %img %u32vec2_01
|
||||
)";
|
||||
|
||||
const std::string extra = "\nOpCapability StorageImageReadWithoutFormat\n";
|
||||
CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
|
||||
ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
|
||||
EXPECT_THAT(getDiagnosticString(),
|
||||
HasSubstr("Expected Image 'Sampled Type' to be the same as "
|
||||
"Result Type's second member components: "
|
||||
"ImageSparseRead"));
|
||||
}
|
||||
|
||||
TEST_F(ValidateImage, SparseGatherSuccess) {
|
||||
const std::string body = R"(
|
||||
%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
|
||||
%sampler = OpLoad %type_sampler %uniform_sampler
|
||||
%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
|
||||
%res1 = OpImageSparseGather %struct_u32_f32vec4 %simg %f32vec4_0000 %u32_1
|
||||
)";
|
||||
|
||||
CompileSuccessfully(GenerateShaderCode(body).c_str());
|
||||
ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
|
||||
}
|
||||
|
||||
TEST_F(ValidateImage, SparseGatherResultTypeNotStruct) {
|
||||
const std::string body = R"(
|
||||
%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
|
||||
%sampler = OpLoad %type_sampler %uniform_sampler
|
||||
%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
|
||||
%res1 = OpImageSparseGather %f32 %simg %f32vec2_hh %u32_1
|
||||
)";
|
||||
|
||||
CompileSuccessfully(GenerateShaderCode(body).c_str());
|
||||
ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
|
||||
EXPECT_THAT(getDiagnosticString(),
|
||||
HasSubstr("ImageSparseGather: "
|
||||
"expected Result Type to be OpTypeStruct"));
|
||||
}
|
||||
|
||||
TEST_F(ValidateImage, SparseGatherResultTypeNotTwoMembers1) {
|
||||
const std::string body = R"(
|
||||
%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
|
||||
%sampler = OpLoad %type_sampler %uniform_sampler
|
||||
%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
|
||||
%res1 = OpImageSparseGather %struct_u32 %simg %f32vec2_hh %u32_1
|
||||
)";
|
||||
|
||||
CompileSuccessfully(GenerateShaderCode(body).c_str());
|
||||
ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
|
||||
EXPECT_THAT(getDiagnosticString(),
|
||||
HasSubstr("ImageSparseGather: expected Result Type "
|
||||
"to be a struct containing an int scalar and a texel"));
|
||||
}
|
||||
|
||||
TEST_F(ValidateImage, SparseGatherResultTypeNotTwoMembers2) {
|
||||
const std::string body = R"(
|
||||
%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
|
||||
%sampler = OpLoad %type_sampler %uniform_sampler
|
||||
%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
|
||||
%res1 = OpImageSparseGather %struct_u32_f32vec4_u32 %simg %f32vec2_hh %u32_1
|
||||
)";
|
||||
|
||||
CompileSuccessfully(GenerateShaderCode(body).c_str());
|
||||
ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
|
||||
EXPECT_THAT(getDiagnosticString(),
|
||||
HasSubstr("ImageSparseGather: expected Result Type "
|
||||
"to be a struct containing an int scalar and a texel"));
|
||||
}
|
||||
|
||||
TEST_F(ValidateImage, SparseGatherResultTypeFirstMemberNotInt) {
|
||||
const std::string body = R"(
|
||||
%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
|
||||
%sampler = OpLoad %type_sampler %uniform_sampler
|
||||
%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
|
||||
%res1 = OpImageSparseGather %struct_f32_f32vec4 %simg %f32vec2_hh %u32_1
|
||||
)";
|
||||
|
||||
CompileSuccessfully(GenerateShaderCode(body).c_str());
|
||||
ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
|
||||
EXPECT_THAT(getDiagnosticString(),
|
||||
HasSubstr("ImageSparseGather: expected Result Type "
|
||||
"to be a struct containing an int scalar and a texel"));
|
||||
}
|
||||
|
||||
TEST_F(ValidateImage, SparseGatherResultTypeTexelNotVector) {
|
||||
const std::string body = R"(
|
||||
%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
|
||||
%sampler = OpLoad %type_sampler %uniform_sampler
|
||||
%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
|
||||
%res1 = OpImageSparseGather %struct_u32_u32 %simg %f32vec2_hh %u32_1
|
||||
)";
|
||||
|
||||
CompileSuccessfully(GenerateShaderCode(body).c_str());
|
||||
ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
|
||||
EXPECT_THAT(getDiagnosticString(),
|
||||
HasSubstr("Expected Result Type's second member to be int or "
|
||||
"float vector type: ImageSparseGather"));
|
||||
}
|
||||
|
||||
TEST_F(ValidateImage, SparseGatherWrongNumComponentsTexel) {
|
||||
const std::string body = R"(
|
||||
%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
|
||||
%sampler = OpLoad %type_sampler %uniform_sampler
|
||||
%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
|
||||
%res1 = OpImageSparseGather %struct_u32_f32vec3 %simg %f32vec2_hh %u32_1
|
||||
)";
|
||||
|
||||
CompileSuccessfully(GenerateShaderCode(body).c_str());
|
||||
ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
|
||||
EXPECT_THAT(getDiagnosticString(),
|
||||
HasSubstr("Expected Result Type's second member to have 4 "
|
||||
"components: ImageSparseGather"));
|
||||
}
|
||||
|
||||
TEST_F(ValidateImage, SparseGatherWrongComponentTypeTexel) {
|
||||
const std::string body = R"(
|
||||
%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
|
||||
%sampler = OpLoad %type_sampler %uniform_sampler
|
||||
%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
|
||||
%res1 = OpImageSparseGather %struct_u32_u32vec4 %simg %f32vec2_hh %u32_1
|
||||
)";
|
||||
|
||||
CompileSuccessfully(GenerateShaderCode(body).c_str());
|
||||
ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
|
||||
EXPECT_THAT(getDiagnosticString(),
|
||||
HasSubstr("Expected Image 'Sampled Type' to be the same as "
|
||||
"Result Type's second member components: "
|
||||
"ImageSparseGather"));
|
||||
}
|
||||
|
||||
TEST_F(ValidateImage, SparseTexelsResidentSuccess) {
|
||||
const std::string body = R"(
|
||||
%res1 = OpImageSparseTexelsResident %bool %u32_1
|
||||
)";
|
||||
|
||||
CompileSuccessfully(GenerateShaderCode(body).c_str());
|
||||
ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
|
||||
}
|
||||
|
||||
TEST_F(ValidateImage, SparseTexelsResidentResultTypeNotBool) {
|
||||
const std::string body = R"(
|
||||
%res1 = OpImageSparseTexelsResident %u32 %u32_1
|
||||
)";
|
||||
|
||||
CompileSuccessfully(GenerateShaderCode(body).c_str());
|
||||
ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
|
||||
EXPECT_THAT(getDiagnosticString(),
|
||||
HasSubstr("ImageSparseTexelsResident: "
|
||||
"expected Result Type to be bool scalar type"));
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
Loading…
Reference in New Issue
Block a user