mesa: move GetProgramInterfaceiv as a shader_query function

This matches how _mesa_get_program_resourceiv was done and this
makes it possible to skip some validation and shader program lookup
when calling it from glGetProgramiv.

Cc: mesa-stable
Signed-off-by: Tapani Pälli <tapani.palli@intel.com>
Reviewed-by: Marek Olšák <marek.olsak@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/14636>
This commit is contained in:
Tapani Pälli 2022-01-20 12:18:24 +02:00 committed by Marge Bot
parent 61400f8a2d
commit 1b898d78d8
4 changed files with 137 additions and 122 deletions

View file

@ -97,7 +97,6 @@ _mesa_GetProgramInterfaceiv(GLuint program, GLenum programInterface,
_mesa_enum_to_string(pname), params);
}
unsigned i;
struct gl_shader_program *shProg =
_mesa_lookup_shader_program_err(ctx, program,
"glGetProgramInterfaceiv");
@ -117,125 +116,7 @@ _mesa_GetProgramInterfaceiv(GLuint program, GLenum programInterface,
return;
}
/* Validate pname against interface. */
switch(pname) {
case GL_ACTIVE_RESOURCES:
for (i = 0, *params = 0; i < shProg->data->NumProgramResourceList; i++)
if (shProg->data->ProgramResourceList[i].Type == programInterface)
(*params)++;
break;
case GL_MAX_NAME_LENGTH:
if (programInterface == GL_ATOMIC_COUNTER_BUFFER ||
programInterface == GL_TRANSFORM_FEEDBACK_BUFFER) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"glGetProgramInterfaceiv(%s pname %s)",
_mesa_enum_to_string(programInterface),
_mesa_enum_to_string(pname));
return;
}
/* Name length consists of base name, 3 additional chars '[0]' if
* resource is an array and finally 1 char for string terminator.
*/
for (i = 0, *params = 0; i < shProg->data->NumProgramResourceList; i++) {
if (shProg->data->ProgramResourceList[i].Type != programInterface)
continue;
unsigned len =
_mesa_program_resource_name_length_array(&shProg->data->ProgramResourceList[i]);
*params = MAX2(*params, len + 1);
}
break;
case GL_MAX_NUM_ACTIVE_VARIABLES:
switch (programInterface) {
case GL_UNIFORM_BLOCK:
for (i = 0, *params = 0; i < shProg->data->NumProgramResourceList; i++) {
if (shProg->data->ProgramResourceList[i].Type == programInterface) {
struct gl_uniform_block *block =
(struct gl_uniform_block *)
shProg->data->ProgramResourceList[i].Data;
*params = MAX2(*params, block->NumUniforms);
}
}
break;
case GL_SHADER_STORAGE_BLOCK:
for (i = 0, *params = 0; i < shProg->data->NumProgramResourceList; i++) {
if (shProg->data->ProgramResourceList[i].Type == programInterface) {
struct gl_uniform_block *block =
(struct gl_uniform_block *)
shProg->data->ProgramResourceList[i].Data;
GLint block_params = 0;
for (unsigned j = 0; j < block->NumUniforms; j++) {
struct gl_program_resource *uni =
_mesa_program_resource_find_active_variable(
shProg,
GL_BUFFER_VARIABLE,
block,
j);
if (!uni)
continue;
block_params++;
}
*params = MAX2(*params, block_params);
}
}
break;
case GL_ATOMIC_COUNTER_BUFFER:
for (i = 0, *params = 0; i < shProg->data->NumProgramResourceList; i++) {
if (shProg->data->ProgramResourceList[i].Type == programInterface) {
struct gl_active_atomic_buffer *buffer =
(struct gl_active_atomic_buffer *)
shProg->data->ProgramResourceList[i].Data;
*params = MAX2(*params, buffer->NumUniforms);
}
}
break;
case GL_TRANSFORM_FEEDBACK_BUFFER:
for (i = 0, *params = 0; i < shProg->data->NumProgramResourceList; i++) {
if (shProg->data->ProgramResourceList[i].Type == programInterface) {
struct gl_transform_feedback_buffer *buffer =
(struct gl_transform_feedback_buffer *)
shProg->data->ProgramResourceList[i].Data;
*params = MAX2(*params, buffer->NumVaryings);
}
}
break;
default:
_mesa_error(ctx, GL_INVALID_OPERATION,
"glGetProgramInterfaceiv(%s pname %s)",
_mesa_enum_to_string(programInterface),
_mesa_enum_to_string(pname));
}
break;
case GL_MAX_NUM_COMPATIBLE_SUBROUTINES:
switch (programInterface) {
case GL_VERTEX_SUBROUTINE_UNIFORM:
case GL_FRAGMENT_SUBROUTINE_UNIFORM:
case GL_GEOMETRY_SUBROUTINE_UNIFORM:
case GL_COMPUTE_SUBROUTINE_UNIFORM:
case GL_TESS_CONTROL_SUBROUTINE_UNIFORM:
case GL_TESS_EVALUATION_SUBROUTINE_UNIFORM: {
for (i = 0, *params = 0; i < shProg->data->NumProgramResourceList; i++) {
if (shProg->data->ProgramResourceList[i].Type == programInterface) {
struct gl_uniform_storage *uni =
(struct gl_uniform_storage *)
shProg->data->ProgramResourceList[i].Data;
*params = MAX2(*params, uni->num_compatible_subroutines);
}
}
break;
}
default:
_mesa_error(ctx, GL_INVALID_OPERATION,
"glGetProgramInterfaceiv(%s pname %s)",
_mesa_enum_to_string(programInterface),
_mesa_enum_to_string(pname));
}
break;
default:
_mesa_error(ctx, GL_INVALID_OPERATION,
"glGetProgramInterfaceiv(pname %s)",
_mesa_enum_to_string(pname));
}
_mesa_get_program_interfaceiv(shProg, programInterface, pname, params);
}
static bool

View file

@ -1739,6 +1739,135 @@ _mesa_get_program_resourceiv(struct gl_shader_program *shProg,
*length = amount;
}
extern void
_mesa_get_program_interfaceiv(struct gl_shader_program *shProg,
GLenum programInterface, GLenum pname,
GLint *params)
{
GET_CURRENT_CONTEXT(ctx);
unsigned i;
/* Validate pname against interface. */
switch(pname) {
case GL_ACTIVE_RESOURCES:
for (i = 0, *params = 0; i < shProg->data->NumProgramResourceList; i++)
if (shProg->data->ProgramResourceList[i].Type == programInterface)
(*params)++;
break;
case GL_MAX_NAME_LENGTH:
if (programInterface == GL_ATOMIC_COUNTER_BUFFER ||
programInterface == GL_TRANSFORM_FEEDBACK_BUFFER) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"glGetProgramInterfaceiv(%s pname %s)",
_mesa_enum_to_string(programInterface),
_mesa_enum_to_string(pname));
return;
}
/* Name length consists of base name, 3 additional chars '[0]' if
* resource is an array and finally 1 char for string terminator.
*/
for (i = 0, *params = 0; i < shProg->data->NumProgramResourceList; i++) {
if (shProg->data->ProgramResourceList[i].Type != programInterface)
continue;
unsigned len =
_mesa_program_resource_name_length_array(&shProg->data->ProgramResourceList[i]);
*params = MAX2((unsigned)*params, len + 1);
}
break;
case GL_MAX_NUM_ACTIVE_VARIABLES:
switch (programInterface) {
case GL_UNIFORM_BLOCK:
for (i = 0, *params = 0; i < shProg->data->NumProgramResourceList; i++) {
if (shProg->data->ProgramResourceList[i].Type == programInterface) {
struct gl_uniform_block *block =
(struct gl_uniform_block *)
shProg->data->ProgramResourceList[i].Data;
*params = MAX2((unsigned)*params, block->NumUniforms);
}
}
break;
case GL_SHADER_STORAGE_BLOCK:
for (i = 0, *params = 0; i < shProg->data->NumProgramResourceList; i++) {
if (shProg->data->ProgramResourceList[i].Type == programInterface) {
struct gl_uniform_block *block =
(struct gl_uniform_block *)
shProg->data->ProgramResourceList[i].Data;
GLint block_params = 0;
for (unsigned j = 0; j < block->NumUniforms; j++) {
struct gl_program_resource *uni =
_mesa_program_resource_find_active_variable(
shProg,
GL_BUFFER_VARIABLE,
block,
j);
if (!uni)
continue;
block_params++;
}
*params = MAX2(*params, block_params);
}
}
break;
case GL_ATOMIC_COUNTER_BUFFER:
for (i = 0, *params = 0; i < shProg->data->NumProgramResourceList; i++) {
if (shProg->data->ProgramResourceList[i].Type == programInterface) {
struct gl_active_atomic_buffer *buffer =
(struct gl_active_atomic_buffer *)
shProg->data->ProgramResourceList[i].Data;
*params = MAX2((unsigned)*params, buffer->NumUniforms);
}
}
break;
case GL_TRANSFORM_FEEDBACK_BUFFER:
for (i = 0, *params = 0; i < shProg->data->NumProgramResourceList; i++) {
if (shProg->data->ProgramResourceList[i].Type == programInterface) {
struct gl_transform_feedback_buffer *buffer =
(struct gl_transform_feedback_buffer *)
shProg->data->ProgramResourceList[i].Data;
*params = MAX2((unsigned)*params, buffer->NumVaryings);
}
}
break;
default:
_mesa_error(ctx, GL_INVALID_OPERATION,
"glGetProgramInterfaceiv(%s pname %s)",
_mesa_enum_to_string(programInterface),
_mesa_enum_to_string(pname));
}
break;
case GL_MAX_NUM_COMPATIBLE_SUBROUTINES:
switch (programInterface) {
case GL_VERTEX_SUBROUTINE_UNIFORM:
case GL_FRAGMENT_SUBROUTINE_UNIFORM:
case GL_GEOMETRY_SUBROUTINE_UNIFORM:
case GL_COMPUTE_SUBROUTINE_UNIFORM:
case GL_TESS_CONTROL_SUBROUTINE_UNIFORM:
case GL_TESS_EVALUATION_SUBROUTINE_UNIFORM: {
for (i = 0, *params = 0; i < shProg->data->NumProgramResourceList; i++) {
if (shProg->data->ProgramResourceList[i].Type == programInterface) {
struct gl_uniform_storage *uni =
(struct gl_uniform_storage *)
shProg->data->ProgramResourceList[i].Data;
*params = MAX2((unsigned)*params, uni->num_compatible_subroutines);
}
}
break;
}
default:
_mesa_error(ctx, GL_INVALID_OPERATION,
"glGetProgramInterfaceiv(%s pname %s)",
_mesa_enum_to_string(programInterface),
_mesa_enum_to_string(pname));
}
break;
default:
_mesa_error(ctx, GL_INVALID_OPERATION,
"glGetProgramInterfaceiv(pname %s)",
_mesa_enum_to_string(pname));
}
}
static bool
validate_io(struct gl_program *producer, struct gl_program *consumer)
{

View file

@ -806,8 +806,8 @@ get_programiv(struct gl_context *ctx, GLuint program, GLenum pname,
*params = _mesa_longest_attribute_name_length(shProg);
return;
case GL_ACTIVE_UNIFORMS: {
_mesa_GetProgramInterfaceiv(program, GL_UNIFORM, GL_ACTIVE_RESOURCES,
params);
_mesa_get_program_interfaceiv(shProg, GL_UNIFORM, GL_ACTIVE_RESOURCES,
params);
return;
}
case GL_ACTIVE_UNIFORM_MAX_LENGTH: {

View file

@ -160,6 +160,11 @@ _mesa_get_program_resourceiv(struct gl_shader_program *shProg,
GLsizei bufSize, GLsizei *length,
GLint *params);
extern void
_mesa_get_program_interfaceiv(struct gl_shader_program *shProg,
GLenum programInterface, GLenum pname,
GLint *params);
extern void
_mesa_program_resource_hash_destroy(struct gl_shader_program *shProg);