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.
This commit is contained in:
lawnjelly 2023-10-09 08:12:04 +01:00 committed by Relintai
parent f45f3bbc73
commit 96d23e1f29
3 changed files with 15 additions and 2 deletions

View File

@ -135,6 +135,15 @@ void RasterizerStorageGLES2::GLWrapper::reset() {
texture_unit_table.blank(); 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 { void RasterizerStorageGLES2::bind_quad_array() const {
glBindBuffer(GL_ARRAY_BUFFER, resources.quadie); glBindBuffer(GL_ARRAY_BUFFER, resources.quadie);
glVertexAttribPointer(RS::ARRAY_VERTEX, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 4, nullptr); 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; config.depth_type = GL_UNSIGNED_INT;
// Initialize GLWrapper early on, as required for any calls to glActiveTexture. // 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); gl_wrapper.initialize(config.max_texture_image_units);
#ifdef GLES_OVER_GL #ifdef GLES_OVER_GL

View File

@ -64,6 +64,7 @@ public:
int max_vertex_texture_image_units; int max_vertex_texture_image_units;
int max_texture_image_units; int max_texture_image_units;
static const int32_t max_desired_texture_image_units = 64;
int max_texture_size; int max_texture_size;
int max_cubemap_texture_size; int max_cubemap_texture_size;
int max_viewport_dimensions[2]; int max_viewport_dimensions[2];
@ -1263,6 +1264,8 @@ public:
virtual String get_video_adapter_name() const; virtual String get_video_adapter_name() const;
virtual String get_video_adapter_vendor() 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. // 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; 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; 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;

View File

@ -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() { void ShaderGLES2::finish() {