LibGL: Implement glGetShaderiv

This commit is contained in:
Stephan Unverwerth 2022-08-28 16:19:42 +02:00 committed by Andrew Kaster
parent 69171e7a05
commit 424e0a2792
Notes: sideshowbarker 2024-07-17 03:01:54 +09:00
7 changed files with 87 additions and 0 deletions

View file

@ -44,10 +44,16 @@ TEST_CASE(0001_program_creation)
vertex_shader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertex_shader, 1, &vertex_shader_source, nullptr);
glCompileShader(vertex_shader);
GLint vertex_shader_compile_status;
glGetShaderiv(vertex_shader, GL_COMPILE_STATUS, &vertex_shader_compile_status);
EXPECT_EQ(vertex_shader_compile_status, GL_TRUE);
fragment_shader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragment_shader, 1, &fragment_shader_source, nullptr);
glCompileShader(fragment_shader);
GLint fragment_shader_compile_status;
glGetShaderiv(fragment_shader, GL_COMPILE_STATUS, &fragment_shader_compile_status);
EXPECT_EQ(fragment_shader_compile_status, GL_TRUE);
program = glCreateProgram();
glAttachShader(program, vertex_shader);

View file

@ -603,6 +603,11 @@ extern "C" {
// Programmable pipeline
#define GL_FRAGMENT_SHADER 0x8B30
#define GL_VERTEX_SHADER 0x8B31
#define GL_SHADER_TYPE 0x8B4F
#define GL_DELETE_STATUS 0x8B80
#define GL_COMPILE_STATUS 0x8B81
#define GL_INFO_LOG_LENGTH 0x8B84
#define GL_SHADER_SOURCE_LENGTH 0x8B88
GLAPI void glBegin(GLenum mode);
GLAPI void glClear(GLbitfield mask);
@ -820,6 +825,7 @@ GLAPI GLuint glCreateShader(GLenum shader_type);
GLAPI void glDeleteShader(GLuint shader);
GLAPI void glShaderSource(GLuint shader, GLsizei count, GLchar const** string, GLint const* length);
GLAPI void glCompileShader(GLuint shader);
GLAPI void glGetShaderiv(GLuint shader, GLenum pname, GLint* params);
GLAPI GLuint glCreateProgram();
GLAPI void glDeleteProgram(GLuint program);

View file

@ -504,6 +504,11 @@ GLubyte const* glGetString(GLenum name)
return g_gl_context->gl_get_string(name);
}
void glGetShaderiv(GLuint shader, GLenum pname, GLint* params)
{
g_gl_context->gl_get_shader(shader, pname, params);
}
void glGetTexImage(GLenum target, GLint level, GLenum format, GLenum type, void* pixels)
{
g_gl_context->gl_get_tex_image(target, level, format, type, pixels);

View file

@ -234,6 +234,7 @@ public:
void gl_delete_shader(GLuint shader);
void gl_shader_source(GLuint shader, GLsizei count, GLchar const** string, GLint const* length);
void gl_compile_shader(GLuint shader);
void gl_get_shader(GLuint shader, GLenum pname, GLint* params);
GLuint gl_create_program();
void gl_delete_program(GLuint program);

View file

@ -70,6 +70,48 @@ void GLContext::gl_compile_shader(GLuint shader)
(void)it->value->compile();
}
void GLContext::gl_get_shader(GLuint shader, GLenum pname, GLint* params)
{
RETURN_WITH_ERROR_IF(pname != GL_SHADER_TYPE
&& pname != GL_DELETE_STATUS
&& pname != GL_COMPILE_STATUS
&& pname != GL_INFO_LOG_LENGTH
&& pname != GL_SHADER_SOURCE_LENGTH,
GL_INVALID_ENUM);
// FIXME: implement check "GL_INVALID_VALUE is generated if shader is not a value generated by OpenGL."
// FIXME: implement check "GL_INVALID_OPERATION is generated if pname is GL_COMPILE_STATUS, GL_INFO_LOG_LENGTH, or GL_SHADER_SOURCE_LENGTH but a shader compiler is not supported."
auto it = m_allocated_shaders.find(shader);
RETURN_WITH_ERROR_IF(it == m_allocated_shaders.end(), GL_INVALID_OPERATION);
switch (pname) {
case GL_SHADER_TYPE:
*params = it->value->type();
break;
case GL_DELETE_STATUS:
// FIXME: Return the actual delete status once we implement this missing feature
*params = GL_FALSE;
break;
case GL_COMPILE_STATUS:
*params = it->value->compile_status() ? GL_TRUE : GL_FALSE;
break;
case GL_INFO_LOG_LENGTH:
*params = it->value->info_log_length();
break;
case GL_SHADER_SOURCE_LENGTH:
*params = it->value->combined_source_length();
break;
default:
VERIFY_NOT_REACHED();
}
}
GLuint GLContext::gl_create_program()
{
GLuint program_name;

View file

@ -28,4 +28,26 @@ ErrorOr<void> Shader::compile()
return {};
}
size_t Shader::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;
}
size_t Shader::combined_source_length() const
{
if (m_sources.is_empty())
return 0;
size_t combined_size = 0;
for (auto source : m_sources)
combined_size += source.bytes().size();
// Per the spec we return the size including the null terminator
return combined_size + 1;
}
}

View file

@ -8,6 +8,7 @@
#include <AK/Error.h>
#include <AK/NonnullRefPtr.h>
#include <AK/Optional.h>
#include <AK/RefCounted.h>
#include <AK/RefPtr.h>
#include <AK/String.h>
@ -27,6 +28,9 @@ public:
GLenum type() const { return m_type; }
bool compile_status() const { return m_compile_status; }
size_t info_log_length() const;
size_t combined_source_length() const;
private:
explicit Shader(GLenum shader_type)
: m_type { shader_type }
@ -36,6 +40,7 @@ private:
Vector<String> m_sources;
GLenum m_type;
bool m_compile_status { false };
Optional<String> m_info_log;
};
}