Merge pull request #100325 from hpvb/fix-rendering-alignment

Fix several ubsan reported misaligned accesses
This commit is contained in:
Thaddeus Crews 2024-12-13 16:19:20 -06:00
commit f2c8f17906
No known key found for this signature in database
GPG Key ID: 62181B86FE9E5D84
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++;