فهرست منبع

LibGL: Generate GL extension string dynamically during construction

LibGL will now generate the GL extension string in the constructor and
refer to it later on when the string is queried via glGetString().
Currently we only check whether the device supports non-power-of-two
textures and add GL_ARB_texture_non_power_of_two to the supported
extensions in that case.
Stephan Unverwerth 3 سال پیش
والد
کامیت
d3d12c2fe7
2فایلهای تغییر یافته به همراه26 افزوده شده و 3 حذف شده
  1. 21 3
      Userland/Libraries/LibGL/SoftwareGLContext.cpp
  2. 5 0
      Userland/Libraries/LibGL/SoftwareGLContext.h

+ 21 - 3
Userland/Libraries/LibGL/SoftwareGLContext.cpp

@@ -9,6 +9,7 @@
 #include <AK/Debug.h>
 #include <AK/Format.h>
 #include <AK/QuickSort.h>
+#include <AK/StringBuilder.h>
 #include <AK/TemporaryChange.h>
 #include <AK/Variant.h>
 #include <AK/Vector.h>
@@ -75,6 +76,8 @@ SoftwareGLContext::SoftwareGLContext(Gfx::Bitmap& frontbuffer)
     light0.diffuse_intensity = { 1.0f, 1.0f, 1.0f, 1.0f };
     light0.specular_intensity = { 1.0f, 1.0f, 1.0f, 1.0f };
     m_light_state_is_dirty = true;
+
+    build_extension_string();
 }
 
 Optional<ContextParameter> SoftwareGLContext::get_context_parameter(GLenum name)
@@ -431,7 +434,7 @@ GLubyte* SoftwareGLContext::gl_get_string(GLenum name)
     case GL_VERSION:
         return reinterpret_cast<GLubyte*>(const_cast<char*>("1.5"));
     case GL_EXTENSIONS:
-        return reinterpret_cast<GLubyte*>(const_cast<char*>(""));
+        return reinterpret_cast<GLubyte*>(const_cast<char*>(m_extensions.characters()));
     case GL_SHADING_LANGUAGE_VERSION:
         return reinterpret_cast<GLubyte*>(const_cast<char*>("0.0"));
     default:
@@ -924,8 +927,10 @@ void SoftwareGLContext::gl_tex_image_2d(GLenum target, GLint level, GLint intern
     RETURN_WITH_ERROR_IF(level < 0 || level > Texture2D::LOG2_MAX_TEXTURE_SIZE, GL_INVALID_VALUE);
     RETURN_WITH_ERROR_IF(width < 0 || height < 0 || width > (2 + Texture2D::MAX_TEXTURE_SIZE) || height > (2 + Texture2D::MAX_TEXTURE_SIZE), GL_INVALID_VALUE);
     // Check if width and height are a power of 2
-    RETURN_WITH_ERROR_IF((width & (width - 1)) != 0, GL_INVALID_VALUE);
-    RETURN_WITH_ERROR_IF((height & (height - 1)) != 0, GL_INVALID_VALUE);
+    if (!m_device_info.supports_npot_textures) {
+        RETURN_WITH_ERROR_IF((width & (width - 1)) != 0, GL_INVALID_VALUE);
+        RETURN_WITH_ERROR_IF((height & (height - 1)) != 0, GL_INVALID_VALUE);
+    }
     RETURN_WITH_ERROR_IF(border != 0, GL_INVALID_VALUE);
 
     if (level == 0) {
@@ -3249,6 +3254,19 @@ void SoftwareGLContext::sync_stencil_configuration()
     set_device_stencil(SoftGPU::Face::Back, m_stencil_function[Face::Back], m_stencil_operation[Face::Back]);
 }
 
+void SoftwareGLContext::build_extension_string()
+{
+    Vector<StringView> extensions;
+
+    // FIXME: npot texture support became a required core feature starting with OpenGL 2.0 (https://www.khronos.org/opengl/wiki/NPOT_Texture)
+    // Ideally we would verify if the selected device adheres to the requested OpenGL context version before context creation
+    // and refuse to create a context if it doesn't.
+    if (m_device_info.supports_npot_textures)
+        extensions.append("GL_ARB_texture_non_power_of_two");
+
+    m_extensions = String::join(" ", extensions);
+}
+
 void SoftwareGLContext::gl_lightf(GLenum light, GLenum pname, GLfloat param)
 {
     APPEND_TO_CALL_LIST_AND_RETURN_IF_NEEDED(gl_lightf, light, pname, param);

+ 5 - 0
Userland/Libraries/LibGL/SoftwareGLContext.h

@@ -157,6 +157,8 @@ private:
     void sync_light_state();
     void sync_stencil_configuration();
 
+    void build_extension_string();
+
     template<typename T>
     T* store_in_listing(T value)
     {
@@ -432,6 +434,9 @@ private:
     bool m_color_material_enabled { false };
     GLenum m_color_material_face { GL_FRONT_AND_BACK };
     GLenum m_color_material_mode { GL_AMBIENT_AND_DIFFUSE };
+
+    // GL Extension string
+    String m_extensions;
 };
 
 }