diff --git a/src/config.def b/src/config.def index e7ef2ffd..8b6fac2b 100644 --- a/src/config.def +++ b/src/config.def @@ -99,5 +99,6 @@ OPTION(std::string, perfetto_trace_dest, "clvk.perfetto-trace") // #if CLVK_UNIT_TESTING_ENABLED OPTION(bool, force_descriptor_set_allocation_failure, false) +OPTION(bool, force_check_capabilities_error, false) OPTION(bool, early_flush_enabled, true) #endif diff --git a/src/program.cpp b/src/program.cpp index da372602..4f2c6d27 100644 --- a/src/program.cpp +++ b/src/program.cpp @@ -1492,7 +1492,7 @@ void cvk_program::prepare_push_constant_range() { max_offset + max_offset_size}; } -bool cvk_program::check_capabilities(const cvk_device* device) const { +bool cvk_program::check_capabilities(const cvk_device* device) { // Get list of required SPIR-V capabilities. std::vector capabilities; if (!m_binary.get_capabilities(capabilities)) { @@ -1504,10 +1504,16 @@ bool cvk_program::check_capabilities(const cvk_device* device) const { for (auto c : capabilities) { cvk_info_fn("Program requires SPIR-V capability %d (%s).", c, spirv_capability_to_string(c)); - if (!device->supports_capability(c)) { - // TODO: propagate this message to the build log - cvk_error_fn("Device does not support SPIR-V capability %d (%s).", - c, spirv_capability_to_string(c)); + if (!device->supports_capability(c) +#ifdef CLVK_UNIT_TESTING_ENABLED + || config.force_check_capabilities_error() +#endif + ) { + std::stringstream error_message; + error_message << "Device does not support SPIR-V capability " << c + << " (" << spirv_capability_to_string(c) << ")."; + cvk_error_fn("%s", error_message.str().c_str()); + m_build_log += error_message.str(); return false; } } diff --git a/src/program.hpp b/src/program.hpp index 75fa824a..20fcc715 100644 --- a/src/program.hpp +++ b/src/program.hpp @@ -878,7 +878,7 @@ struct cvk_program : public _cl_program, api_object { /// Check if all of the capabilities required by the SPIR-V module are /// supported by `device`. - CHECK_RETURN bool check_capabilities(const cvk_device* device) const; + CHECK_RETURN bool check_capabilities(const cvk_device* device); uint32_t m_num_devices; cl_uint m_num_input_programs; diff --git a/tests/api/compiler.cpp b/tests/api/compiler.cpp index ce4237ec..f7044147 100644 --- a/tests/api/compiler.cpp +++ b/tests/api/compiler.cpp @@ -479,3 +479,22 @@ TEST_F(WithContext, SetUnusedSamplerArgWithInvalidObject) { cl_int err = clSetKernelArg(kernel, 0, sizeof(cl_sampler), &kern); ASSERT_EQ(err, CL_INVALID_SAMPLER); } + +#if CLVK_UNIT_TESTING_ENABLED +TEST_F(WithContext, UnsupportedCapabilities) { + static const char* source = R"( + kernel void foo() {} + )"; + + auto cfg = CLVK_CONFIG_SCOPED_OVERRIDE(force_check_capabilities_error, bool, + true, true); + auto program = CreateProgram(source); + cl_int err = + clBuildProgram(program, 1, &gDevice, nullptr, nullptr, nullptr); + ASSERT_EQ(err, CL_BUILD_PROGRAM_FAILURE); + auto build_log = GetProgramBuildLog(program); + + ASSERT_TRUE(build_log.find("Device does not support SPIR-V capability") != + std::string::npos); +} +#endif