vulkan: properly set bool spec onst (#7125)

We wrote a bool directly into 4 bytes (as the first byte). This has two issues:
 - the other 3 bytes are not initialized
 - should be writing VK_TRUE/FALSE instead
This commit is contained in:
Powei Feng
2023-09-01 10:59:30 -07:00
parent 8cba3d4366
commit d01b29fa01
2 changed files with 21 additions and 15 deletions

View File

@@ -104,8 +104,9 @@ public:
Sampler const* samplers, size_t count) noexcept;
struct SpecializationConstant {
using Type = std::variant<int32_t, float, bool>;
uint32_t id; // id set in glsl
std::variant<int32_t, float, bool> value; // value and type
Type value; // value and type
};
Program& specializationConstants(

View File

@@ -87,21 +87,26 @@ VulkanProgram::VulkanProgram(VkDevice device, const Program& builder) noexcept :
};
for (size_t i = 0; i < specializationConstants.size(); i++) {
const uint32_t offset = uint32_t(i) * 4;
std::visit([&](auto&& arg) {
using T = std::decay_t<decltype(arg)>;
pEntries[i] = {
.constantID = specializationConstants[i].id,
.offset = offset,
// Turns out vulkan expects the size of bool to be 4 (verified through
// validation layer). So all expected types are of 4 bytes.
.size = 4,
};
T* const addr = (T*)((char*)pData + offset);
*addr = arg;
}, specializationConstants[i].value);
}
uint32_t const offset = uint32_t(i) * 4;
pEntries[i] = {
.constantID = specializationConstants[i].id,
.offset = offset,
// Note that bools are 4-bytes in Vulkan
// https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VkBool32.html
.size = 4,
};
using SpecConstant = Program::SpecializationConstant::Type;
char const* addr = (char*)pData + offset;
SpecConstant const& arg = specializationConstants[i].value;
if (std::holds_alternative<bool>(arg)) {
*((VkBool32*)addr) = std::get<bool>(arg) ? VK_TRUE : VK_FALSE;
} else if (std::holds_alternative<float>(arg)) {
*((float*)addr) = std::get<float>(arg);
} else {
*((int32_t*)addr) = std::get<int32_t>(arg);
}
}
bundle.specializationInfos = pInfo;
}