You've already forked godot
mirror of
https://github.com/godotengine/godot.git
synced 2025-11-04 12:00:25 +00:00
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:
@@ -3441,7 +3441,7 @@ Vector<uint8_t> RenderingDeviceDriverVulkan::shader_compile_binary_from_spirv(Ve
|
|||||||
|
|
||||||
binary_data.shader_name_len = shader_name_utf.length();
|
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 += sizeof(ShaderBinary::Data);
|
||||||
|
|
||||||
total_size += STEPIFY(binary_data.shader_name_len, 4);
|
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);
|
offset += sizeof(uint32_t);
|
||||||
encode_uint32(sizeof(ShaderBinary::Data), binptr + offset);
|
encode_uint32(sizeof(ShaderBinary::Data), binptr + offset);
|
||||||
offset += sizeof(uint32_t);
|
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));
|
memcpy(binptr + offset, &binary_data, sizeof(ShaderBinary::Data));
|
||||||
offset += 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;
|
uint32_t read_offset = 0;
|
||||||
|
|
||||||
// Consistency check.
|
// 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());
|
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);
|
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);
|
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;
|
r_shader_desc.push_constant_size = binary_data.push_constant_size;
|
||||||
shader_info.vk_push_constant_stages = binary_data.vk_push_constant_stages_mask;
|
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[1] = binary_data.compute_local_size[1];
|
||||||
r_shader_desc.compute_local_size[2] = binary_data.compute_local_size[2];
|
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) {
|
if (binary_data.shader_name_len) {
|
||||||
r_name.parse_utf8((const char *)(binptr + read_offset), binary_data.shader_name_len);
|
r_name.parse_utf8((const char *)(binptr + read_offset), binary_data.shader_name_len);
|
||||||
|
|||||||
@@ -405,7 +405,8 @@ private:
|
|||||||
// Version 2: Added shader name.
|
// Version 2: Added shader name.
|
||||||
// Version 3: Added writable.
|
// Version 3: Added writable.
|
||||||
// Version 4: 64-bit vertex input mask.
|
// 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 {
|
struct DataBinding {
|
||||||
uint32_t type = 0;
|
uint32_t type = 0;
|
||||||
|
|||||||
@@ -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) {
|
RenderingDeviceGraph::RecordedCommand *RenderingDeviceGraph::_allocate_command(uint32_t p_command_size, int32_t &r_command_index) {
|
||||||
uint32_t command_data_offset = command_data.size();
|
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_offsets.push_back(command_data_offset);
|
||||||
command_data.resize(command_data_offset + p_command_size);
|
command_data.resize(command_data_offset + p_command_size);
|
||||||
r_command_index = command_count++;
|
r_command_index = command_count++;
|
||||||
|
|||||||
Reference in New Issue
Block a user