mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-23 22:00:13 +01:00
mesa: glGet: fix parameter lookup for apps using multiple APIs
The glGet hash was initialized only once for a single GL API, even if the application later created a context for a different API. This resulted in glGet failing for otherwise valid parameters in a context if that parameter was invalid in another context created earlier. Fix this by using a separate hash table for each API. Signed-off-by: Imre Deak <imre.deak@intel.com> Reviewed-by: Brian Paul <brianp@vmware.com> Reviewed-by: Oliver McFadden <oliver.mcfadden@linux.intel.com>
This commit is contained in:
parent
7182a1fc5e
commit
2ad4a47547
3 changed files with 32 additions and 17 deletions
|
|
@ -404,9 +404,6 @@ one_time_init( struct gl_context *ctx )
|
||||||
|
|
||||||
_mesa_get_cpu_features();
|
_mesa_get_cpu_features();
|
||||||
|
|
||||||
/* context dependence is never a one-time thing... */
|
|
||||||
_mesa_init_get_hash(ctx);
|
|
||||||
|
|
||||||
for (i = 0; i < 256; i++) {
|
for (i = 0; i < 256; i++) {
|
||||||
_mesa_ubyte_to_float_color_tab[i] = (float) i / 255.0F;
|
_mesa_ubyte_to_float_color_tab[i] = (float) i / 255.0F;
|
||||||
}
|
}
|
||||||
|
|
@ -425,6 +422,8 @@ one_time_init( struct gl_context *ctx )
|
||||||
|
|
||||||
/* per-API one-time init */
|
/* per-API one-time init */
|
||||||
if (!(api_init_mask & (1 << ctx->API))) {
|
if (!(api_init_mask & (1 << ctx->API))) {
|
||||||
|
_mesa_init_get_hash(ctx);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This is fine as ES does not use the remap table, but it may not be
|
* This is fine as ES does not use the remap table, but it may not be
|
||||||
* future-proof. We cannot always initialize the remap table because
|
* future-proof. We cannot always initialize the remap table because
|
||||||
|
|
|
||||||
|
|
@ -1385,29 +1385,37 @@ static const struct value_desc values[] = {
|
||||||
* collisions for any enum (typical numbers). And the code is very
|
* collisions for any enum (typical numbers). And the code is very
|
||||||
* simple, even though it feels a little magic. */
|
* simple, even though it feels a little magic. */
|
||||||
|
|
||||||
static unsigned short table[1024];
|
static unsigned short table[API_LAST + 1][1024];
|
||||||
static const int prime_factor = 89, prime_step = 281;
|
static const int prime_factor = 89, prime_step = 281;
|
||||||
|
|
||||||
#ifdef GET_DEBUG
|
#ifdef GET_DEBUG
|
||||||
static void
|
static void
|
||||||
print_table_stats(void)
|
print_table_stats(int api)
|
||||||
{
|
{
|
||||||
int i, j, collisions[11], count, hash, mask;
|
int i, j, collisions[11], count, hash, mask;
|
||||||
const struct value_desc *d;
|
const struct value_desc *d;
|
||||||
|
const char *api_names[] = {
|
||||||
|
[API_OPENGL] = "GL",
|
||||||
|
[API_OPENGL_CORE] = "GL_CORE",
|
||||||
|
[API_OPENGLES] = "GLES",
|
||||||
|
[API_OPENGLES2] = "GLES2",
|
||||||
|
};
|
||||||
|
const char *api_name;
|
||||||
|
|
||||||
|
api_name = api < Elements(api_names) ? api_names[api] : "N/A";
|
||||||
count = 0;
|
count = 0;
|
||||||
mask = Elements(table) - 1;
|
mask = Elements(table[api]) - 1;
|
||||||
memset(collisions, 0, sizeof collisions);
|
memset(collisions, 0, sizeof collisions);
|
||||||
|
|
||||||
for (i = 0; i < Elements(table); i++) {
|
for (i = 0; i < Elements(table[api]); i++) {
|
||||||
if (!table[i])
|
if (!table[api][i])
|
||||||
continue;
|
continue;
|
||||||
count++;
|
count++;
|
||||||
d = &values[table[i]];
|
d = &values[table[api][i]];
|
||||||
hash = (d->pname * prime_factor);
|
hash = (d->pname * prime_factor);
|
||||||
j = 0;
|
j = 0;
|
||||||
while (1) {
|
while (1) {
|
||||||
if (values[table[hash & mask]].pname == d->pname)
|
if (values[table[api][hash & mask]].pname == d->pname)
|
||||||
break;
|
break;
|
||||||
hash += prime_step;
|
hash += prime_step;
|
||||||
j++;
|
j++;
|
||||||
|
|
@ -1419,7 +1427,8 @@ print_table_stats(void)
|
||||||
collisions[10]++;
|
collisions[10]++;
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("number of enums: %d (total %d)\n", count, Elements(values));
|
printf("number of enums for %s: %d (total %ld)\n",
|
||||||
|
api_name, count, Elements(values));
|
||||||
for (i = 0; i < Elements(collisions) - 1; i++)
|
for (i = 0; i < Elements(collisions) - 1; i++)
|
||||||
if (collisions[i] > 0)
|
if (collisions[i] > 0)
|
||||||
printf(" %d enums with %d %scollisions\n",
|
printf(" %d enums with %d %scollisions\n",
|
||||||
|
|
@ -1438,10 +1447,13 @@ print_table_stats(void)
|
||||||
void _mesa_init_get_hash(struct gl_context *ctx)
|
void _mesa_init_get_hash(struct gl_context *ctx)
|
||||||
{
|
{
|
||||||
int i, hash, index, mask;
|
int i, hash, index, mask;
|
||||||
|
int api;
|
||||||
int api_mask = 0, api_bit;
|
int api_mask = 0, api_bit;
|
||||||
|
|
||||||
mask = Elements(table) - 1;
|
api = ctx->API;
|
||||||
api_bit = 1 << ctx->API;
|
|
||||||
|
mask = Elements(table[api]) - 1;
|
||||||
|
api_bit = 1 << api;
|
||||||
|
|
||||||
for (i = 0; i < Elements(values); i++) {
|
for (i = 0; i < Elements(values); i++) {
|
||||||
if (values[i].type == TYPE_API_MASK) {
|
if (values[i].type == TYPE_API_MASK) {
|
||||||
|
|
@ -1454,8 +1466,8 @@ void _mesa_init_get_hash(struct gl_context *ctx)
|
||||||
hash = (values[i].pname * prime_factor) & mask;
|
hash = (values[i].pname * prime_factor) & mask;
|
||||||
while (1) {
|
while (1) {
|
||||||
index = hash & mask;
|
index = hash & mask;
|
||||||
if (!table[index]) {
|
if (!table[api][index]) {
|
||||||
table[index] = i;
|
table[api][index] = i;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
hash += prime_step;
|
hash += prime_step;
|
||||||
|
|
@ -1986,11 +1998,13 @@ find_value(const char *func, GLenum pname, void **p, union value *v)
|
||||||
struct gl_texture_unit *unit;
|
struct gl_texture_unit *unit;
|
||||||
int mask, hash;
|
int mask, hash;
|
||||||
const struct value_desc *d;
|
const struct value_desc *d;
|
||||||
|
int api;
|
||||||
|
|
||||||
mask = Elements(table) - 1;
|
api = ctx->API;
|
||||||
|
mask = Elements(table[api]) - 1;
|
||||||
hash = (pname * prime_factor);
|
hash = (pname * prime_factor);
|
||||||
while (1) {
|
while (1) {
|
||||||
d = &values[table[hash & mask]];
|
d = &values[table[api][hash & mask]];
|
||||||
|
|
||||||
/* If the enum isn't valid, the hash walk ends with index 0,
|
/* If the enum isn't valid, the hash walk ends with index 0,
|
||||||
* which is the API mask entry at the beginning of values[]. */
|
* which is the API mask entry at the beginning of values[]. */
|
||||||
|
|
|
||||||
|
|
@ -3341,6 +3341,8 @@ typedef enum
|
||||||
API_OPENGLES,
|
API_OPENGLES,
|
||||||
API_OPENGLES2,
|
API_OPENGLES2,
|
||||||
API_OPENGL_CORE,
|
API_OPENGL_CORE,
|
||||||
|
|
||||||
|
API_LAST = API_OPENGL_CORE,
|
||||||
} gl_api;
|
} gl_api;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue