From 96d23e1f29d5e09f7bd6de4594349d4161f8bafb Mon Sep 17 00:00:00 2001 From: lawnjelly Date: Mon, 9 Oct 2023 08:12:04 +0100 Subject: [PATCH] Fix glGet overflows by using 64 bit versions Certain glGet operations require 64 bit versions according to the GLES spec. The previous code was susceptible to overflow bugs, especially running under ANGLE. --- drivers/gles2/rasterizer_storage_gles2.cpp | 11 ++++++++++- drivers/gles2/rasterizer_storage_gles2.h | 3 +++ drivers/gles2/shader_gles2.cpp | 3 ++- 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/drivers/gles2/rasterizer_storage_gles2.cpp b/drivers/gles2/rasterizer_storage_gles2.cpp index b00c51444..2a729cb4b 100644 --- a/drivers/gles2/rasterizer_storage_gles2.cpp +++ b/drivers/gles2/rasterizer_storage_gles2.cpp @@ -135,6 +135,15 @@ void RasterizerStorageGLES2::GLWrapper::reset() { texture_unit_table.blank(); } +int32_t RasterizerStorageGLES2::safe_gl_get_integer(unsigned int p_gl_param_name, int32_t p_max_accepted) { + // There is no glGetInteger64v in the base GLES2 spec as far as I can see. + // So we will just have a capped 32 bit version for GLES2. + int32_t temp; + glGetIntegerv(p_gl_param_name, &temp); + temp = MIN(temp, p_max_accepted); + return temp; +} + void RasterizerStorageGLES2::bind_quad_array() const { glBindBuffer(GL_ARRAY_BUFFER, resources.quadie); glVertexAttribPointer(RS::ARRAY_VERTEX, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 4, nullptr); @@ -5957,7 +5966,7 @@ void RasterizerStorageGLES2::initialize() { config.depth_type = GL_UNSIGNED_INT; // Initialize GLWrapper early on, as required for any calls to glActiveTexture. - glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &config.max_texture_image_units); + config.max_texture_image_units = safe_gl_get_integer(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, Config::max_desired_texture_image_units); gl_wrapper.initialize(config.max_texture_image_units); #ifdef GLES_OVER_GL diff --git a/drivers/gles2/rasterizer_storage_gles2.h b/drivers/gles2/rasterizer_storage_gles2.h index c8f48a707..534bef940 100644 --- a/drivers/gles2/rasterizer_storage_gles2.h +++ b/drivers/gles2/rasterizer_storage_gles2.h @@ -64,6 +64,7 @@ public: int max_vertex_texture_image_units; int max_texture_image_units; + static const int32_t max_desired_texture_image_units = 64; int max_texture_size; int max_cubemap_texture_size; int max_viewport_dimensions[2]; @@ -1263,6 +1264,8 @@ public: virtual String get_video_adapter_name() const; virtual String get_video_adapter_vendor() const; + static int32_t safe_gl_get_integer(unsigned int p_gl_param_name, int32_t p_max_accepted = INT32_MAX); + // NOTE : THESE SIZES ARE IN BYTES. BUFFER SIZES MAY NOT BE SPECIFIED IN BYTES SO REMEMBER TO CONVERT THEM WHEN CALLING. void buffer_orphan_and_upload(unsigned int p_buffer_size_bytes, unsigned int p_offset_bytes, unsigned int p_data_size_bytes, const void *p_data, GLenum p_target = GL_ARRAY_BUFFER, GLenum p_usage = GL_DYNAMIC_DRAW, bool p_optional_orphan = false) const; bool safe_buffer_sub_data(unsigned int p_total_buffer_size, GLenum p_target, unsigned int p_offset, unsigned int p_data_size, const void *p_data, unsigned int &r_offset_after) const; diff --git a/drivers/gles2/shader_gles2.cpp b/drivers/gles2/shader_gles2.cpp index 72316d591..eabbeafea 100644 --- a/drivers/gles2/shader_gles2.cpp +++ b/drivers/gles2/shader_gles2.cpp @@ -559,7 +559,8 @@ void ShaderGLES2::setup( } } - glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &max_image_units); + // The upper limit must match the version used in storage. + max_image_units = RasterizerStorageGLES2::safe_gl_get_integer(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, RasterizerStorageGLES2::Config::max_desired_texture_image_units); } void ShaderGLES2::finish() {