2022-08-28 10:36:31 +02:00
|
|
|
/*
|
|
|
|
|
* Copyright (c) 2022, Stephan Unverwerth <s.unverwerth@serenityos.org>
|
|
|
|
|
*
|
|
|
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
|
|
|
|
*/
|
|
|
|
|
|
2022-08-28 11:47:58 +02:00
|
|
|
#include <LibGL/GL/gl.h>
|
2022-08-28 10:36:31 +02:00
|
|
|
#include <LibGL/Shaders/Program.h>
|
2022-08-28 19:24:58 +02:00
|
|
|
#include <LibGLSL/Linker.h>
|
2022-08-28 10:36:31 +02:00
|
|
|
|
|
|
|
|
namespace GL {
|
|
|
|
|
|
|
|
|
|
NonnullRefPtr<Program> Program::create()
|
|
|
|
|
{
|
|
|
|
|
return adopt_ref(*new Program());
|
|
|
|
|
}
|
|
|
|
|
|
2022-08-28 11:47:58 +02:00
|
|
|
bool Program::is_shader_attached(Shader const& shader) const
|
2022-08-28 10:36:31 +02:00
|
|
|
{
|
2022-08-28 11:47:58 +02:00
|
|
|
switch (shader.type()) {
|
|
|
|
|
case GL_VERTEX_SHADER:
|
|
|
|
|
return m_vertex_shaders.contains_slow(shader);
|
|
|
|
|
case GL_FRAGMENT_SHADER:
|
|
|
|
|
return m_fragment_shaders.contains_slow(shader);
|
|
|
|
|
default:
|
|
|
|
|
VERIFY_NOT_REACHED();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ErrorOr<void> Program::attach_shader(Shader& shader)
|
|
|
|
|
{
|
|
|
|
|
if (is_shader_attached(shader))
|
|
|
|
|
return Error::from_string_literal("Trying to attach a shader that is already attached");
|
|
|
|
|
|
|
|
|
|
switch (shader.type()) {
|
|
|
|
|
case GL_VERTEX_SHADER:
|
|
|
|
|
TRY(m_vertex_shaders.try_append(shader));
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case GL_FRAGMENT_SHADER:
|
|
|
|
|
TRY(m_fragment_shaders.try_append(shader));
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
VERIFY_NOT_REACHED();
|
|
|
|
|
}
|
|
|
|
|
|
2022-08-28 10:36:31 +02:00
|
|
|
return {};
|
|
|
|
|
}
|
|
|
|
|
|
2022-09-14 23:48:10 +02:00
|
|
|
ErrorOr<void> Program::link(GPU::Device& device)
|
2022-08-28 10:36:31 +02:00
|
|
|
{
|
2023-01-20 07:45:02 -05:00
|
|
|
m_info_log = String {};
|
2022-08-28 19:24:58 +02:00
|
|
|
|
|
|
|
|
GLSL::Linker linker;
|
|
|
|
|
|
|
|
|
|
// Link vertex shader objects
|
|
|
|
|
|
|
|
|
|
Vector<GLSL::ObjectFile const*> vertex_shader_object_files;
|
|
|
|
|
for (auto vertex_shader : m_vertex_shaders)
|
|
|
|
|
vertex_shader_object_files.append(vertex_shader->object_file());
|
|
|
|
|
|
|
|
|
|
auto linked_vertex_shader_or_error = linker.link(vertex_shader_object_files);
|
|
|
|
|
|
|
|
|
|
if (linked_vertex_shader_or_error.is_error()) {
|
|
|
|
|
m_link_status = false;
|
|
|
|
|
m_info_log = linker.messages();
|
2023-02-09 13:26:53 -05:00
|
|
|
return linked_vertex_shader_or_error.release_error();
|
2022-08-28 19:24:58 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
m_linked_vertex_shader = linked_vertex_shader_or_error.release_value();
|
|
|
|
|
|
|
|
|
|
// Link fragment shader objects
|
|
|
|
|
|
|
|
|
|
Vector<GLSL::ObjectFile const*> fragment_shader_object_files;
|
|
|
|
|
for (auto fragment_shader : m_fragment_shaders)
|
|
|
|
|
fragment_shader_object_files.append(fragment_shader->object_file());
|
|
|
|
|
|
|
|
|
|
auto linked_fragment_shader_or_error = linker.link(fragment_shader_object_files);
|
|
|
|
|
|
|
|
|
|
if (linked_fragment_shader_or_error.is_error()) {
|
|
|
|
|
m_link_status = false;
|
|
|
|
|
m_info_log = linker.messages();
|
2023-02-09 13:26:53 -05:00
|
|
|
return linked_fragment_shader_or_error.release_error();
|
2022-08-28 19:24:58 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
m_linked_fragment_shader = linked_fragment_shader_or_error.release_value();
|
|
|
|
|
|
2022-10-29 12:23:22 +02:00
|
|
|
m_gpu_vertex_shader = TRY(device.create_shader(m_linked_vertex_shader->intermediate_shader_representation()));
|
|
|
|
|
m_gpu_fragment_shader = TRY(device.create_shader(m_linked_fragment_shader->intermediate_shader_representation()));
|
2022-09-14 23:48:10 +02:00
|
|
|
|
2022-08-28 14:29:32 +02:00
|
|
|
m_link_status = true;
|
2022-08-28 10:36:31 +02:00
|
|
|
return {};
|
|
|
|
|
}
|
|
|
|
|
|
2022-08-28 16:34:17 +02:00
|
|
|
size_t Program::info_log_length() const
|
|
|
|
|
{
|
|
|
|
|
if (!m_info_log.has_value())
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
// Per the spec we return the size including the null terminator
|
|
|
|
|
return m_info_log.value().bytes().size() + 1;
|
|
|
|
|
}
|
|
|
|
|
|
2022-08-28 10:36:31 +02:00
|
|
|
}
|