[Impellerc] correctly pad arrays of vec3s in reflector. (#161697)

When processing the metadata for a struct with an array, incorporate the
padding into the layout. Previously we would register a vec3[n] array as
being 4*n bytes (including the padding), but when uploading this would
result in us writing data into the padding and then leave the rest
uninitialized. now we correctly insert a padding element between 3 byte
elements.

Fixes https://github.com/flutter/flutter/issues/161645
This commit is contained in:
Jonah Williams 2025-01-16 16:48:01 -08:00 committed by GitHub
parent 747f5fff1e
commit 12518fac13
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 53 additions and 5 deletions

View File

@ -398,12 +398,26 @@ std::shared_ptr<RuntimeStageData::Shader> Reflector::GenerateRuntimeStageData()
break;
}
case StructMember::UnderlyingType::kFloat: {
if (member.array_elements > 1) {
// For each array element member, insert 1 layout property per byte
// and 0 layout property per byte of padding
for (auto i = 0; i < member.array_elements; i++) {
for (auto j = 0u; j < member.size / sizeof(float); j++) {
struct_layout.push_back(1);
}
for (auto j = 0u; j < member.element_padding / sizeof(float);
j++) {
struct_layout.push_back(0);
}
}
} else {
size_t member_float_count = member.byte_length / sizeof(float);
float_count += member_float_count;
while (member_float_count > 0) {
struct_layout.push_back(1);
member_float_count--;
}
}
break;
}
case StructMember::UnderlyingType::kOther:

View File

@ -20,6 +20,7 @@ if (enable_unittests) {
"filter_shader.frag",
"missing_size.frag",
"missing_texture.frag",
"vec3_uniform.frag",
]
group("general_shaders") {

View File

@ -0,0 +1,15 @@
#version 320 es
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
precision highp float;
uniform vec3[4] color_array;
out vec4 fragColor;
void main() {
fragColor = vec4(color_array[3].xyz, 1);
}

View File

@ -376,6 +376,24 @@ void main() async {
}
});
test('Shader Compiler appropriately pads vec3 uniform arrays', () async {
if (!impellerEnabled) {
print('Skipped for Skia');
return;
}
final FragmentProgram program = await FragmentProgram.fromAsset('vec3_uniform.frag.iplr');
final FragmentShader shader = program.fragmentShader();
// Set the last vec3 in the uniform array to green. The shader will read this
// value, and if the uniforms were padded correctly will render green.
shader.setFloat(12, 0);
shader.setFloat(13, 1.0);
shader.setFloat(14, 0);
await _expectShaderRendersGreen(shader);
});
test('ImageFilter.shader can be applied to canvas operations', () async {
if (!impellerEnabled) {
print('Skipped for Skia');