Skip to content

Commit e152004

Browse files
authored
spirv-val: Derivative instructions with half (#6652)
GL_AMD_gpu_shader_half_float allows us to use half type in derivative instructions. But the corresponding extension of SPIR-V appears to only explicitly allow half type for interpolation function, doesn't mention derivative functions. Recently, one PR in SPIRV-Registry was updated this extension, and updated spec to match the behavior of GLSLang. GLSLang extension: https://registry.khronos.org/OpenGL/extensions/AMD/AMD_gpu_shader_half_float.txt Extension update: KhronosGroup/SPIRV-Registry#403
1 parent 2ec8457 commit e152004

2 files changed

Lines changed: 34 additions & 2 deletions

File tree

source/val/validate_derivatives.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,15 @@ spv_result_t DerivativesPass(ValidationState_t& _, const Instruction* inst) {
4545
<< spvOpcodeString(opcode);
4646
}
4747
if (!_.ContainsSizedIntOrFloatType(result_type, spv::Op::OpTypeFloat,
48-
32)) {
48+
32) &&
49+
(!_.HasExtension(kSPV_AMD_gpu_shader_half_float) ||
50+
!_.ContainsSizedIntOrFloatType(result_type, spv::Op::OpTypeFloat,
51+
16))) {
4952
return _.diag(SPV_ERROR_INVALID_DATA, inst)
50-
<< "Result type component width must be 32 bits";
53+
<< "Result type component width must be "
54+
<< (_.HasExtension(kSPV_AMD_gpu_shader_half_float)
55+
? "16 bits or 32 bits"
56+
: "32 bits");
5157
}
5258

5359
const uint32_t p_type = _.GetOperandTypeId(inst, 2);

test/val/val_derivatives_test.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,19 @@ OpFunctionEnd
188188

189189
using ValidateHalfDerivatives = spvtest::ValidateBase<std::string>;
190190

191+
TEST_P(ValidateHalfDerivatives, ScalarSuccess) {
192+
const std::string op = GetParam();
193+
const std::string body = "%val = " + op + " %f16 %f16_0\n";
194+
const std::string capabilities_and_extensions = R"(
195+
OpCapability Float16
196+
OpExtension "SPV_AMD_gpu_shader_half_float"
197+
)";
198+
199+
CompileSuccessfully(
200+
GenerateShaderCode(body, capabilities_and_extensions).c_str());
201+
ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
202+
}
203+
191204
TEST_P(ValidateHalfDerivatives, ScalarFailure) {
192205
const std::string op = GetParam();
193206
const std::string body = "%val = " + op + " %f16 %f16_0\n";
@@ -199,6 +212,19 @@ TEST_P(ValidateHalfDerivatives, ScalarFailure) {
199212
HasSubstr("Result type component width must be 32 bits"));
200213
}
201214

215+
TEST_P(ValidateHalfDerivatives, VectorSuccess) {
216+
const std::string op = GetParam();
217+
const std::string body = "%val = " + op + " %f16vec4 %f16vec4_0\n";
218+
const std::string capabilities_and_extensions = R"(
219+
OpCapability Float16
220+
OpExtension "SPV_AMD_gpu_shader_half_float"
221+
)";
222+
223+
CompileSuccessfully(
224+
GenerateShaderCode(body, capabilities_and_extensions).c_str());
225+
ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
226+
}
227+
202228
TEST_P(ValidateHalfDerivatives, VectorFailure) {
203229
const std::string op = GetParam();
204230
const std::string body = "%val = " + op + " %f16vec4 %f16vec4_0\n";

0 commit comments

Comments
 (0)