Fix several ubsan reported misaligned accesses

These misaligned accesses are shown in all of our CI hooks. It turned
out to not be difficult to fix.

It is likely that this will improve performance for aarch64.
This commit is contained in:
HP van Braam 2024-12-12 17:21:15 +01:00
parent 19e003bc08
commit e674379764
3 changed files with 10 additions and 5 deletions

View file

@ -3441,7 +3441,7 @@ Vector<uint8_t> RenderingDeviceDriverVulkan::shader_compile_binary_from_spirv(Ve
binary_data.shader_name_len = shader_name_utf.length();
uint32_t total_size = sizeof(uint32_t) * 3; // Header + version + main datasize;.
uint32_t total_size = sizeof(uint32_t) * 4; // Header + version + pad + main datasize;.
total_size += sizeof(ShaderBinary::Data);
total_size += STEPIFY(binary_data.shader_name_len, 4);
@ -3470,6 +3470,8 @@ Vector<uint8_t> RenderingDeviceDriverVulkan::shader_compile_binary_from_spirv(Ve
offset += sizeof(uint32_t);
encode_uint32(sizeof(ShaderBinary::Data), binptr + offset);
offset += sizeof(uint32_t);
encode_uint32(0, binptr + offset); // Pad to align ShaderBinary::Data to 8 bytes.
offset += sizeof(uint32_t);
memcpy(binptr + offset, &binary_data, sizeof(ShaderBinary::Data));
offset += sizeof(ShaderBinary::Data);
@ -3528,7 +3530,7 @@ RDD::ShaderID RenderingDeviceDriverVulkan::shader_create_from_bytecode(const Vec
uint32_t read_offset = 0;
// Consistency check.
ERR_FAIL_COND_V(binsize < sizeof(uint32_t) * 3 + sizeof(ShaderBinary::Data), ShaderID());
ERR_FAIL_COND_V(binsize < sizeof(uint32_t) * 4 + sizeof(ShaderBinary::Data), ShaderID());
ERR_FAIL_COND_V(binptr[0] != 'G' || binptr[1] != 'S' || binptr[2] != 'B' || binptr[3] != 'D', ShaderID());
uint32_t bin_version = decode_uint32(binptr + 4);
@ -3536,7 +3538,8 @@ RDD::ShaderID RenderingDeviceDriverVulkan::shader_create_from_bytecode(const Vec
uint32_t bin_data_size = decode_uint32(binptr + 8);
const ShaderBinary::Data &binary_data = *(reinterpret_cast<const ShaderBinary::Data *>(binptr + 12));
// 16, not 12, to skip alignment padding.
const ShaderBinary::Data &binary_data = *(reinterpret_cast<const ShaderBinary::Data *>(binptr + 16));
r_shader_desc.push_constant_size = binary_data.push_constant_size;
shader_info.vk_push_constant_stages = binary_data.vk_push_constant_stages_mask;
@ -3549,7 +3552,7 @@ RDD::ShaderID RenderingDeviceDriverVulkan::shader_create_from_bytecode(const Vec
r_shader_desc.compute_local_size[1] = binary_data.compute_local_size[1];
r_shader_desc.compute_local_size[2] = binary_data.compute_local_size[2];
read_offset += sizeof(uint32_t) * 3 + bin_data_size;
read_offset += sizeof(uint32_t) * 4 + bin_data_size;
if (binary_data.shader_name_len) {
r_name.parse_utf8((const char *)(binptr + read_offset), binary_data.shader_name_len);

View file

@ -405,7 +405,8 @@ private:
// Version 2: Added shader name.
// Version 3: Added writable.
// Version 4: 64-bit vertex input mask.
static const uint32_t VERSION = 4;
// Version 5: Add 4 bytes padding to align the Data struct after the change in version 4.
static const uint32_t VERSION = 5;
struct DataBinding {
uint32_t type = 0;

View file

@ -228,6 +228,7 @@ int32_t RenderingDeviceGraph::_add_to_write_list(int32_t p_command_index, Rect2i
RenderingDeviceGraph::RecordedCommand *RenderingDeviceGraph::_allocate_command(uint32_t p_command_size, int32_t &r_command_index) {
uint32_t command_data_offset = command_data.size();
command_data_offset = STEPIFY(command_data_offset, 8);
command_data_offsets.push_back(command_data_offset);
command_data.resize(command_data_offset + p_command_size);
r_command_index = command_count++;