Route shader creation through renderer GL

This commit is contained in:
2026-06-03 07:03:50 +02:00
parent acdaf3bb8e
commit 1ae79ab3c1
6 changed files with 1123 additions and 67 deletions

View File

@@ -1,4 +1,5 @@
#include "renderer_gl/opengl_capabilities.h"
#include "renderer_gl/shader_bindings.h"
#include <array>
#include <limits>
@@ -1030,6 +1031,190 @@ pp::foundation::Result<std::int32_t> get_opengl_attribute_location(
dispatch.get_attrib_location(program_id, attribute_name));
}
pp::foundation::Result<OpenGlShaderCompileInfo> compile_opengl_shader_source(
std::uint32_t stage,
const char* source,
char* info_log,
std::int32_t info_log_capacity,
OpenGlShaderCompileDispatch dispatch) noexcept
{
if (dispatch.create_shader == nullptr
|| dispatch.shader_source == nullptr
|| dispatch.compile_shader == nullptr
|| dispatch.get_shader_integer == nullptr
|| dispatch.get_shader_info_log == nullptr) {
return pp::foundation::Result<OpenGlShaderCompileInfo>::failure(
pp::foundation::Status::invalid_argument("OpenGL shader compile dispatch callbacks must not be null"));
}
if (stage == 0U || source == nullptr || source[0] == '\0' || info_log == nullptr || info_log_capacity <= 0) {
return pp::foundation::Result<OpenGlShaderCompileInfo>::failure(
pp::foundation::Status::invalid_argument("OpenGL shader compile parameters are invalid"));
}
const auto shader_id = dispatch.create_shader(stage);
if (shader_id == 0U) {
return pp::foundation::Result<OpenGlShaderCompileInfo>::failure(
pp::foundation::Status::out_of_range("OpenGL shader allocation returned id 0"));
}
const char* const sources[] { source };
dispatch.shader_source(shader_id, 1, sources);
dispatch.compile_shader(shader_id);
OpenGlShaderCompileInfo info {
.shader_id = shader_id,
};
dispatch.get_shader_integer(shader_id, shader_compile_status_query(), &info.compile_status);
dispatch.get_shader_info_log(shader_id, info_log_capacity, &info.info_log_length, info_log);
return pp::foundation::Result<OpenGlShaderCompileInfo>::success(info);
}
pp::foundation::Status delete_opengl_shader(
std::uint32_t shader_id,
OpenGlShaderDeleteDispatch dispatch) noexcept
{
if (dispatch.delete_shader == nullptr) {
return pp::foundation::Status::invalid_argument("OpenGL shader delete dispatch callback must not be null");
}
if (shader_id == 0U) {
return pp::foundation::Status::success();
}
dispatch.delete_shader(shader_id);
return pp::foundation::Status::success();
}
pp::foundation::Result<OpenGlProgramLinkInfo> link_opengl_shader_program(
std::uint32_t vertex_shader_id,
std::uint32_t fragment_shader_id,
std::span<const OpenGlAttributeBinding> attribute_bindings,
char* info_log,
std::int32_t info_log_capacity,
OpenGlProgramLinkDispatch dispatch) noexcept
{
if (dispatch.create_program == nullptr
|| dispatch.attach_shader == nullptr
|| dispatch.delete_shader == nullptr
|| dispatch.link_program == nullptr
|| dispatch.get_attrib_location == nullptr
|| dispatch.bind_attrib_location == nullptr
|| dispatch.get_program_integer == nullptr
|| dispatch.get_program_info_log == nullptr) {
return pp::foundation::Result<OpenGlProgramLinkInfo>::failure(
pp::foundation::Status::invalid_argument("OpenGL program link dispatch callbacks must not be null"));
}
if (vertex_shader_id == 0U
|| fragment_shader_id == 0U
|| attribute_bindings.empty()
|| info_log == nullptr
|| info_log_capacity <= 0) {
return pp::foundation::Result<OpenGlProgramLinkInfo>::failure(
pp::foundation::Status::invalid_argument("OpenGL program link parameters are invalid"));
}
const auto program_id = dispatch.create_program();
if (program_id == 0U) {
return pp::foundation::Result<OpenGlProgramLinkInfo>::failure(
pp::foundation::Status::out_of_range("OpenGL program allocation returned id 0"));
}
dispatch.attach_shader(program_id, vertex_shader_id);
dispatch.attach_shader(program_id, fragment_shader_id);
dispatch.delete_shader(vertex_shader_id);
dispatch.delete_shader(fragment_shader_id);
dispatch.link_program(program_id);
for (const auto& binding : attribute_bindings) {
if (binding.name != nullptr && dispatch.get_attrib_location(program_id, binding.name) != -1) {
dispatch.bind_attrib_location(program_id, binding.location, binding.name);
}
}
OpenGlProgramLinkInfo info {
.program_id = program_id,
};
dispatch.link_program(program_id);
dispatch.get_program_integer(program_id, program_link_status_query(), &info.link_status);
dispatch.get_program_info_log(program_id, info_log_capacity, &info.info_log_length, info_log);
return pp::foundation::Result<OpenGlProgramLinkInfo>::success(info);
}
pp::foundation::Result<std::int32_t> query_opengl_program_integer(
std::uint32_t program_id,
std::uint32_t query,
OpenGlProgramIntegerDispatch dispatch) noexcept
{
if (dispatch.get_program_integer == nullptr) {
return pp::foundation::Result<std::int32_t>::failure(
pp::foundation::Status::invalid_argument("OpenGL program integer dispatch callback must not be null"));
}
if (program_id == 0U || query == 0U) {
return pp::foundation::Result<std::int32_t>::failure(
pp::foundation::Status::invalid_argument("OpenGL program integer parameters are invalid"));
}
std::int32_t value = 0;
dispatch.get_program_integer(program_id, query, &value);
return pp::foundation::Result<std::int32_t>::success(value);
}
pp::foundation::Result<OpenGlActiveUniformInfo> get_opengl_active_uniform(
std::uint32_t program_id,
std::uint32_t index,
char* name,
std::int32_t name_capacity,
OpenGlActiveUniformDispatch dispatch) noexcept
{
if (dispatch.get_active_uniform == nullptr) {
return pp::foundation::Result<OpenGlActiveUniformInfo>::failure(
pp::foundation::Status::invalid_argument("OpenGL active uniform dispatch callback must not be null"));
}
if (program_id == 0U || name == nullptr || name_capacity <= 0) {
return pp::foundation::Result<OpenGlActiveUniformInfo>::failure(
pp::foundation::Status::invalid_argument("OpenGL active uniform parameters are invalid"));
}
OpenGlActiveUniformInfo info {};
dispatch.get_active_uniform(
program_id,
index,
name_capacity,
&info.length,
&info.size,
&info.type,
name);
if (info.length >= 0 && info.length < name_capacity) {
name[info.length] = '\0';
} else {
name[name_capacity - 1] = '\0';
}
return pp::foundation::Result<OpenGlActiveUniformInfo>::success(info);
}
pp::foundation::Result<std::int32_t> get_opengl_uniform_location(
std::uint32_t program_id,
const char* uniform_name,
OpenGlUniformLocationDispatch dispatch) noexcept
{
if (dispatch.get_uniform_location == nullptr) {
return pp::foundation::Result<std::int32_t>::failure(
pp::foundation::Status::invalid_argument("OpenGL uniform-location dispatch callback must not be null"));
}
if (program_id == 0U || uniform_name == nullptr || uniform_name[0] == '\0') {
return pp::foundation::Result<std::int32_t>::failure(
pp::foundation::Status::invalid_argument("OpenGL uniform-location parameters are invalid"));
}
return pp::foundation::Result<std::int32_t>::success(
dispatch.get_uniform_location(program_id, uniform_name));
}
std::uint32_t extension_count_query() noexcept
{
return gl_num_extensions;