[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,11 +398,25 @@ std::shared_ptr<RuntimeStageData::Shader> Reflector::GenerateRuntimeStageData()
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case StructMember::UnderlyingType::kFloat: {
|
case StructMember::UnderlyingType::kFloat: {
|
||||||
size_t member_float_count = member.byte_length / sizeof(float);
|
if (member.array_elements > 1) {
|
||||||
float_count += member_float_count;
|
// For each array element member, insert 1 layout property per byte
|
||||||
while (member_float_count > 0) {
|
// and 0 layout property per byte of padding
|
||||||
struct_layout.push_back(1);
|
for (auto i = 0; i < member.array_elements; i++) {
|
||||||
member_float_count--;
|
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;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -20,6 +20,7 @@ if (enable_unittests) {
|
|||||||
"filter_shader.frag",
|
"filter_shader.frag",
|
||||||
"missing_size.frag",
|
"missing_size.frag",
|
||||||
"missing_texture.frag",
|
"missing_texture.frag",
|
||||||
|
"vec3_uniform.frag",
|
||||||
]
|
]
|
||||||
|
|
||||||
group("general_shaders") {
|
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 {
|
test('ImageFilter.shader can be applied to canvas operations', () async {
|
||||||
if (!impellerEnabled) {
|
if (!impellerEnabled) {
|
||||||
print('Skipped for Skia');
|
print('Skipped for Skia');
|
||||||
|
Loading…
x
Reference in New Issue
Block a user