Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 9 additions & 2 deletions impeller/compiler/compiler.cc
Original file line number Diff line number Diff line change
Expand Up @@ -156,11 +156,15 @@ static CompilerBackend CreateGLSLCompiler(const spirv_cross::ParsedIR& ir,
sl_options.force_zero_initialized_variables = true;
sl_options.vertex.fixup_clipspace = true;
if (source_options.target_platform == TargetPlatform::kOpenGLES ||
source_options.target_platform == TargetPlatform::kRuntimeStageGLES) {
source_options.target_platform == TargetPlatform::kRuntimeStageGLES ||
source_options.target_platform == TargetPlatform::kRuntimeStageGLES3) {
sl_options.version = source_options.gles_language_version > 0
? source_options.gles_language_version
: 100;
sl_options.es = true;
if (source_options.target_platform == TargetPlatform::kRuntimeStageGLES3) {
sl_options.version = 300;
}
if (source_options.require_framebuffer_fetch &&
source_options.type == SourceType::kFragmentShader) {
gl_compiler->remap_ext_framebuffer_fetch(0, 0, true);
Expand Down Expand Up @@ -202,6 +206,7 @@ static bool EntryPointMustBeNamedMain(TargetPlatform platform) {
case TargetPlatform::kOpenGLES:
case TargetPlatform::kOpenGLDesktop:
case TargetPlatform::kRuntimeStageGLES:
case TargetPlatform::kRuntimeStageGLES3:
return true;
}
FML_UNREACHABLE();
Expand All @@ -224,6 +229,7 @@ static CompilerBackend CreateCompiler(const spirv_cross::ParsedIR& ir,
case TargetPlatform::kOpenGLES:
case TargetPlatform::kOpenGLDesktop:
case TargetPlatform::kRuntimeStageGLES:
case TargetPlatform::kRuntimeStageGLES3:
compiler = CreateGLSLCompiler(ir, source_options);
break;
case TargetPlatform::kSkSL:
Expand Down Expand Up @@ -317,7 +323,8 @@ Compiler::Compiler(const std::shared_ptr<const fml::Mapping>& source_mapping,
spirv_options.target = target;
} break;
case TargetPlatform::kRuntimeStageMetal:
case TargetPlatform::kRuntimeStageGLES: {
case TargetPlatform::kRuntimeStageGLES:
case TargetPlatform::kRuntimeStageGLES3: {
SPIRVCompilerTargetEnv target;

target.env = shaderc_target_env::shaderc_target_env_opengl;
Expand Down
1 change: 1 addition & 0 deletions impeller/compiler/impellerc_main.cc
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,7 @@ static bool OutputDepfile(const Compiler& compiler, const Switches& switches) {
case TargetPlatform::kOpenGLDesktop:
case TargetPlatform::kRuntimeStageMetal:
case TargetPlatform::kRuntimeStageGLES:
case TargetPlatform::kRuntimeStageGLES3:
case TargetPlatform::kRuntimeStageVulkan:
case TargetPlatform::kSkSL:
case TargetPlatform::kVulkan:
Expand Down
2 changes: 2 additions & 0 deletions impeller/compiler/reflector.cc
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,8 @@ static std::optional<RuntimeStageBackend> GetRuntimeStageBackend(
return RuntimeStageBackend::kMetal;
case TargetPlatform::kRuntimeStageGLES:
return RuntimeStageBackend::kOpenGLES;
case TargetPlatform::kRuntimeStageGLES3:
return RuntimeStageBackend::kOpenGLES3;
case TargetPlatform::kRuntimeStageVulkan:
return RuntimeStageBackend::kVulkan;
case TargetPlatform::kSkSL:
Expand Down
5 changes: 5 additions & 0 deletions impeller/compiler/runtime_stage_data.cc
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,8 @@ static std::string RuntimeStageBackendToString(RuntimeStageBackend backend) {
return "opengles";
case RuntimeStageBackend::kVulkan:
return "vulkan";
case RuntimeStageBackend::kOpenGLES3:
return "opengles3";
}
}

Expand Down Expand Up @@ -384,6 +386,9 @@ RuntimeStageData::CreateMultiStageFlatbuffer() const {
case RuntimeStageBackend::kVulkan:
runtime_stages->vulkan = std::move(runtime_stage);
break;
case RuntimeStageBackend::kOpenGLES3:
runtime_stages->opengles3 = std::move(runtime_stage);
break;
}
}
return runtime_stages;
Expand Down
1 change: 1 addition & 0 deletions impeller/compiler/switches.cc
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ static const std::map<std::string, TargetPlatform> kKnownRuntimeStages = {
{"sksl", TargetPlatform::kSkSL},
{"runtime-stage-metal", TargetPlatform::kRuntimeStageMetal},
{"runtime-stage-gles", TargetPlatform::kRuntimeStageGLES},
{"runtime-stage-gles3", TargetPlatform::kRuntimeStageGLES3},
{"runtime-stage-vulkan", TargetPlatform::kRuntimeStageVulkan},
};

Expand Down
9 changes: 9 additions & 0 deletions impeller/compiler/types.cc
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,8 @@ std::string TargetPlatformToString(TargetPlatform platform) {
return "RuntimeStageMetal";
case TargetPlatform::kRuntimeStageGLES:
return "RuntimeStageGLES";
case TargetPlatform::kRuntimeStageGLES3:
return "RuntimeStageGLES3";
case TargetPlatform::kRuntimeStageVulkan:
return "RuntimeStageVulkan";
case TargetPlatform::kSkSL:
Expand Down Expand Up @@ -146,6 +148,7 @@ bool TargetPlatformNeedsReflection(TargetPlatform platform) {
case TargetPlatform::kOpenGLDesktop:
case TargetPlatform::kRuntimeStageMetal:
case TargetPlatform::kRuntimeStageGLES:
case TargetPlatform::kRuntimeStageGLES3:
case TargetPlatform::kRuntimeStageVulkan:
case TargetPlatform::kVulkan:
return true;
Expand Down Expand Up @@ -221,6 +224,7 @@ spirv_cross::CompilerMSL::Options::Platform TargetPlatformToMSLPlatform(
case TargetPlatform::kOpenGLES:
case TargetPlatform::kOpenGLDesktop:
case TargetPlatform::kRuntimeStageGLES:
case TargetPlatform::kRuntimeStageGLES3:
case TargetPlatform::kRuntimeStageVulkan:
case TargetPlatform::kVulkan:
case TargetPlatform::kUnknown:
Expand Down Expand Up @@ -255,6 +259,7 @@ std::string TargetPlatformSLExtension(TargetPlatform platform) {
case TargetPlatform::kOpenGLES:
case TargetPlatform::kOpenGLDesktop:
case TargetPlatform::kRuntimeStageGLES:
case TargetPlatform::kRuntimeStageGLES3:
return "glsl";
case TargetPlatform::kVulkan:
case TargetPlatform::kRuntimeStageVulkan:
Expand All @@ -268,6 +273,7 @@ bool TargetPlatformIsOpenGL(TargetPlatform platform) {
case TargetPlatform::kOpenGLES:
case TargetPlatform::kOpenGLDesktop:
case TargetPlatform::kRuntimeStageGLES:
case TargetPlatform::kRuntimeStageGLES3:
return true;
case TargetPlatform::kMetalDesktop:
case TargetPlatform::kRuntimeStageMetal:
Expand All @@ -292,6 +298,7 @@ bool TargetPlatformIsMetal(TargetPlatform platform) {
case TargetPlatform::kOpenGLES:
case TargetPlatform::kOpenGLDesktop:
case TargetPlatform::kRuntimeStageGLES:
case TargetPlatform::kRuntimeStageGLES3:
case TargetPlatform::kRuntimeStageVulkan:
case TargetPlatform::kVulkan:
return false;
Expand All @@ -312,6 +319,7 @@ bool TargetPlatformIsVulkan(TargetPlatform platform) {
case TargetPlatform::kOpenGLES:
case TargetPlatform::kOpenGLDesktop:
case TargetPlatform::kRuntimeStageGLES:
case TargetPlatform::kRuntimeStageGLES3:
return false;
}
FML_UNREACHABLE();
Expand All @@ -322,6 +330,7 @@ bool TargetPlatformBundlesSkSL(TargetPlatform platform) {
case TargetPlatform::kSkSL:
case TargetPlatform::kRuntimeStageMetal:
case TargetPlatform::kRuntimeStageGLES:
case TargetPlatform::kRuntimeStageGLES3:
case TargetPlatform::kRuntimeStageVulkan:
return true;
case TargetPlatform::kMetalDesktop:
Expand Down
1 change: 1 addition & 0 deletions impeller/compiler/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ enum class TargetPlatform {
kVulkan,
kRuntimeStageMetal,
kRuntimeStageGLES,
kRuntimeStageGLES3,
kRuntimeStageVulkan,
kSkSL,
};
Expand Down
1 change: 1 addition & 0 deletions impeller/core/runtime_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ enum class RuntimeStageBackend {
kSkSL,
kMetal,
kOpenGLES,
kOpenGLES3,
kVulkan,
};

Expand Down
176 changes: 114 additions & 62 deletions impeller/renderer/backend/gles/buffer_bindings_gles.cc
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,38 @@ bool BufferBindingsGLES::ReadUniformsBindings(const ProcTableGLES& gl,
if (!gl.IsProgram(program)) {
return false;
}
program_handle_ = program;
if (gl.GetDescription()->GetGlVersion().IsAtLeast(Version{3, 0, 0})) {
return ReadUniformsBindingsV3(gl, program);
}
return ReadUniformsBindingsV2(gl, program);
}

bool BufferBindingsGLES::ReadUniformsBindingsV3(const ProcTableGLES& gl,
GLuint program) {
program_handle_ = program;
GLint uniform_blocks = 0;
gl.GetProgramiv(program, GL_ACTIVE_UNIFORM_BLOCKS, &uniform_blocks);
for (GLint i = 0; i < uniform_blocks; i++) {
GLint name_length = 0;
gl.GetActiveUniformBlockiv(program, i, GL_UNIFORM_BLOCK_NAME_LENGTH,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Paranoid note: Does the name include the NULL terminator?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

&name_length);

std::vector<GLchar> name;
name.resize(name_length);
GLint length;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Like name_length above, zero this out so an error in the next call doesn't leave garbage in the variable that you will later use to create a string.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

gl.GetActiveUniformBlockName(program, i, name_length, &length, name.data());

GLuint block_index = gl.GetUniformBlockIndex(program, name.data());
ubo_locations_[std::string{name.data(), static_cast<size_t>(length)}] =
std::make_pair(block_index, i);
}
use_ubo_ = true;
return ReadUniformsBindingsV2(gl, program);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nicely done.

}

bool BufferBindingsGLES::ReadUniformsBindingsV2(const ProcTableGLES& gl,
GLuint program) {
GLint max_name_size = 0;
gl.GetProgramiv(program, GL_ACTIVE_UNIFORM_MAX_LENGTH, &max_name_size);

Expand Down Expand Up @@ -138,6 +170,9 @@ bool BufferBindingsGLES::ReadUniformsBindings(const ProcTableGLES& gl,

auto location = gl.GetUniformLocation(program, name.data());
if (location == -1) {
if (use_ubo_) {
continue;
}
VALIDATION_LOG << "Could not query the location of an active uniform.";
return false;
}
Expand Down Expand Up @@ -183,12 +218,13 @@ bool BufferBindingsGLES::BindUniformData(const ProcTableGLES& gl,
const Bindings& vertex_bindings,
const Bindings& fragment_bindings) {
for (const auto& buffer : vertex_bindings.buffers) {
if (!BindUniformBuffer(gl, buffer.view)) {
if (!BindUniformBuffer(gl, buffer.view, /*force_v2=*/false)) {
return false;
}
}
for (const auto& buffer : fragment_bindings.buffers) {
if (!BindUniformBuffer(gl, buffer.view)) {
if (!BindUniformBuffer(gl, buffer.view,
/*force_v2=*/buffer.view.IsDynamic())) {
return false;
}
}
Expand Down Expand Up @@ -274,7 +310,44 @@ const std::vector<GLint>& BufferBindingsGLES::ComputeUniformLocations(
}

bool BufferBindingsGLES::BindUniformBuffer(const ProcTableGLES& gl,
const BufferResource& buffer) {
const BufferResource& buffer,
bool force_v2) {
if (use_ubo_ && !force_v2) {
return BindUniformBufferV3(gl, buffer);
}
return BindUniformBufferV2(gl, buffer);
}

bool BufferBindingsGLES::BindUniformBufferV3(const ProcTableGLES& gl,
const BufferResource& buffer) {
const ShaderMetadata* metadata = buffer.GetMetadata();
const DeviceBuffer* device_buffer = buffer.resource.GetBuffer();
if (!device_buffer) {
VALIDATION_LOG << "Device buffer not found.";
return false;
}
const DeviceBufferGLES& device_buffer_gles =
DeviceBufferGLES::Cast(*device_buffer);

const auto& [block_index, binding_point] = ubo_locations_[metadata->name];
gl.UniformBlockBinding(program_handle_, block_index, binding_point);

if (!device_buffer_gles.BindAndUploadDataIfNecessary(
DeviceBufferGLES::BindingType::kUniformBuffer)) {
return false;
}
auto handle = device_buffer_gles.GetHandle();
if (!handle.has_value()) {
return false;
}
gl.BindBufferRange(GL_UNIFORM_BUFFER, binding_point, handle.value(),
buffer.resource.GetRange().offset,
buffer.resource.GetRange().length);
return true;
}

bool BufferBindingsGLES::BindUniformBufferV2(const ProcTableGLES& gl,
const BufferResource& buffer) {
const ShaderMetadata* metadata = buffer.GetMetadata();
const DeviceBuffer* device_buffer = buffer.resource.GetBuffer();
if (!device_buffer) {
Expand Down Expand Up @@ -323,65 +396,44 @@ bool BufferBindingsGLES::BindUniformBuffer(const ProcTableGLES& gl,
reinterpret_cast<const GLfloat*>(array_element_buffer.data());
}

switch (member.type) {
case ShaderType::kFloat:
switch (member.size) {
case sizeof(Matrix):
gl.UniformMatrix4fv(location, // location
element_count, // count
GL_FALSE, // normalize
buffer_data // data
);
continue;
case sizeof(Vector4):
gl.Uniform4fv(location, // location
element_count, // count
buffer_data // data
);
continue;
case sizeof(Vector3):
gl.Uniform3fv(location, // location
element_count, // count
buffer_data // data
);
continue;
case sizeof(Vector2):
gl.Uniform2fv(location, // location
element_count, // count
buffer_data // data
);
continue;
case sizeof(Scalar):
gl.Uniform1fv(location, // location
element_count, // count
buffer_data // data
);
continue;
}
VALIDATION_LOG << "Size " << member.size
<< " could not be mapped ShaderType::kFloat for key: "
<< member.name;
case ShaderType::kBoolean:
case ShaderType::kSignedByte:
case ShaderType::kUnsignedByte:
case ShaderType::kSignedShort:
case ShaderType::kUnsignedShort:
case ShaderType::kSignedInt:
case ShaderType::kUnsignedInt:
case ShaderType::kSignedInt64:
case ShaderType::kUnsignedInt64:
case ShaderType::kAtomicCounter:
case ShaderType::kUnknown:
case ShaderType::kVoid:
case ShaderType::kHalfFloat:
case ShaderType::kDouble:
case ShaderType::kStruct:
case ShaderType::kImage:
case ShaderType::kSampledImage:
case ShaderType::kSampler:
VALIDATION_LOG << "Could not bind uniform buffer data for key: "
<< member.name << " : " << static_cast<int>(member.type);
return false;
if (member.type != ShaderType::kFloat) {
VALIDATION_LOG << "Could not bind uniform buffer data for key: "
<< member.name << " : " << static_cast<int>(member.type);
return false;
}

switch (member.size) {
case sizeof(Matrix):
gl.UniformMatrix4fv(location, // location
element_count, // count
GL_FALSE, // normalize
buffer_data // data
);
continue;
case sizeof(Vector4):
gl.Uniform4fv(location, // location
element_count, // count
buffer_data // data
);
continue;
case sizeof(Vector3):
gl.Uniform3fv(location, // location
element_count, // count
buffer_data // data
);
continue;
case sizeof(Vector2):
gl.Uniform2fv(location, // location
element_count, // count
buffer_data // data
);
continue;
case sizeof(Scalar):
gl.Uniform1fv(location, // location
element_count, // count
buffer_data // data
);
continue;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps add the default: case that logs the member type so we don't silently ignore stuff? But yeah, at this point, probably all types have shaken out.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

}
}
return true;
Expand Down
Loading