[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:
parent
747f5fff1e
commit
12518fac13
@ -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:
|
||||
|
@ -20,6 +20,7 @@ if (enable_unittests) {
|
||||
"filter_shader.frag",
|
||||
"missing_size.frag",
|
||||
"missing_texture.frag",
|
||||
"vec3_uniform.frag",
|
||||
]
|
||||
|
||||
group("general_shaders") {
|
||||
|
@ -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);
|
||||
}
|
@ -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');
|
||||
|
Loading…
x
Reference in New Issue
Block a user