mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-05 13:58:04 +02:00
mesa: glGetProgramInterfaceiv
Patch adds required helper functions to shaderapi.h and
the actual implementation.
v2: code cleanup (Ilia Mirkin)
fix array size fo xfb varyings
validate programInterface and throw error
v3: put GL_MAX_NUM_COMPATIBLE_SUBROUTINES where
it belongs
corresponding Piglit test:
arb_program_interface_query-getprograminterfaceiv
Signed-off-by: Tapani Pälli <tapani.palli@intel.com>
Reviewed-by: Martin Peres <martin.peres@linux.intel.com>
This commit is contained in:
parent
c796ce4108
commit
4d3b98bc58
3 changed files with 185 additions and 0 deletions
|
|
@ -23,12 +23,131 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#include "main/enums.h"
|
||||
#include "main/macros.h"
|
||||
#include "main/mtypes.h"
|
||||
#include "main/shaderapi.h"
|
||||
#include "main/shaderobj.h"
|
||||
#include "program_resource.h"
|
||||
|
||||
static bool
|
||||
supported_interface_enum(GLenum iface)
|
||||
{
|
||||
switch (iface) {
|
||||
case GL_UNIFORM:
|
||||
case GL_UNIFORM_BLOCK:
|
||||
case GL_PROGRAM_INPUT:
|
||||
case GL_PROGRAM_OUTPUT:
|
||||
case GL_TRANSFORM_FEEDBACK_VARYING:
|
||||
case GL_ATOMIC_COUNTER_BUFFER:
|
||||
return true;
|
||||
case GL_VERTEX_SUBROUTINE:
|
||||
case GL_TESS_CONTROL_SUBROUTINE:
|
||||
case GL_TESS_EVALUATION_SUBROUTINE:
|
||||
case GL_GEOMETRY_SUBROUTINE:
|
||||
case GL_FRAGMENT_SUBROUTINE:
|
||||
case GL_COMPUTE_SUBROUTINE:
|
||||
case GL_VERTEX_SUBROUTINE_UNIFORM:
|
||||
case GL_TESS_CONTROL_SUBROUTINE_UNIFORM:
|
||||
case GL_TESS_EVALUATION_SUBROUTINE_UNIFORM:
|
||||
case GL_GEOMETRY_SUBROUTINE_UNIFORM:
|
||||
case GL_FRAGMENT_SUBROUTINE_UNIFORM:
|
||||
case GL_COMPUTE_SUBROUTINE_UNIFORM:
|
||||
case GL_BUFFER_VARIABLE:
|
||||
case GL_SHADER_STORAGE_BLOCK:
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void GLAPIENTRY
|
||||
_mesa_GetProgramInterfaceiv(GLuint program, GLenum programInterface,
|
||||
GLenum pname, GLint *params)
|
||||
{
|
||||
GET_CURRENT_CONTEXT(ctx);
|
||||
unsigned i;
|
||||
struct gl_shader_program *shProg =
|
||||
_mesa_lookup_shader_program_err(ctx, program,
|
||||
"glGetProgramInterfaceiv");
|
||||
if (!shProg)
|
||||
return;
|
||||
|
||||
if (!params) {
|
||||
_mesa_error(ctx, GL_INVALID_OPERATION,
|
||||
"glGetProgramInterfaceiv(params NULL)");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Validate interface. */
|
||||
if (!supported_interface_enum(programInterface)) {
|
||||
_mesa_error(ctx, GL_INVALID_OPERATION, "glGetProgramInterfaceiv(%s)",
|
||||
_mesa_lookup_enum_by_nr(programInterface));
|
||||
return;
|
||||
}
|
||||
|
||||
/* Validate pname against interface. */
|
||||
switch(pname) {
|
||||
case GL_ACTIVE_RESOURCES:
|
||||
for (i = 0, *params = 0; i < shProg->NumProgramResourceList; i++)
|
||||
if (shProg->ProgramResourceList[i].Type == programInterface)
|
||||
(*params)++;
|
||||
break;
|
||||
case GL_MAX_NAME_LENGTH:
|
||||
if (programInterface == GL_ATOMIC_COUNTER_BUFFER) {
|
||||
_mesa_error(ctx, GL_INVALID_OPERATION,
|
||||
"glGetProgramInterfaceiv(%s pname %s)",
|
||||
_mesa_lookup_enum_by_nr(programInterface),
|
||||
_mesa_lookup_enum_by_nr(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->NumProgramResourceList; i++) {
|
||||
if (shProg->ProgramResourceList[i].Type != programInterface)
|
||||
continue;
|
||||
const char *name =
|
||||
_mesa_program_resource_name(&shProg->ProgramResourceList[i]);
|
||||
unsigned array_size =
|
||||
_mesa_program_resource_array_size(&shProg->ProgramResourceList[i]);
|
||||
*params = MAX2(*params, strlen(name) + (array_size ? 3 : 0) + 1);
|
||||
}
|
||||
break;
|
||||
case GL_MAX_NUM_ACTIVE_VARIABLES:
|
||||
switch (programInterface) {
|
||||
case GL_UNIFORM_BLOCK:
|
||||
for (i = 0, *params = 0; i < shProg->NumProgramResourceList; i++) {
|
||||
if (shProg->ProgramResourceList[i].Type == programInterface) {
|
||||
struct gl_uniform_block *block =
|
||||
(struct gl_uniform_block *)
|
||||
shProg->ProgramResourceList[i].Data;
|
||||
*params = MAX2(*params, block->NumUniforms);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case GL_ATOMIC_COUNTER_BUFFER:
|
||||
for (i = 0, *params = 0; i < shProg->NumProgramResourceList; i++) {
|
||||
if (shProg->ProgramResourceList[i].Type == programInterface) {
|
||||
struct gl_active_atomic_buffer *buffer =
|
||||
(struct gl_active_atomic_buffer *)
|
||||
shProg->ProgramResourceList[i].Data;
|
||||
*params = MAX2(*params, buffer->NumUniforms);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
_mesa_error(ctx, GL_INVALID_OPERATION,
|
||||
"glGetProgramInterfaceiv(%s pname %s)",
|
||||
_mesa_lookup_enum_by_nr(programInterface),
|
||||
_mesa_lookup_enum_by_nr(pname));
|
||||
};
|
||||
break;
|
||||
case GL_MAX_NUM_COMPATIBLE_SUBROUTINES:
|
||||
default:
|
||||
_mesa_error(ctx, GL_INVALID_OPERATION,
|
||||
"glGetProgramInterfaceiv(pname %s)",
|
||||
_mesa_lookup_enum_by_nr(pname));
|
||||
}
|
||||
}
|
||||
|
||||
GLuint GLAPIENTRY
|
||||
|
|
|
|||
|
|
@ -34,11 +34,29 @@
|
|||
#include "shaderobj.h"
|
||||
#include "program/hash_table.h"
|
||||
#include "../glsl/program.h"
|
||||
#include "uniforms.h"
|
||||
#include "main/enums.h"
|
||||
|
||||
extern "C" {
|
||||
#include "shaderapi.h"
|
||||
}
|
||||
|
||||
/**
|
||||
* Declare convenience functions to return resource data in a given type.
|
||||
* Warning! this is not type safe so be *very* careful when using these.
|
||||
*/
|
||||
#define DECL_RESOURCE_FUNC(name, type) \
|
||||
const type * RESOURCE_ ## name (gl_program_resource *res) { \
|
||||
assert(res->Data); \
|
||||
return (type *) res->Data; \
|
||||
}
|
||||
|
||||
DECL_RESOURCE_FUNC(VAR, ir_variable);
|
||||
DECL_RESOURCE_FUNC(UBO, gl_uniform_block);
|
||||
DECL_RESOURCE_FUNC(UNI, gl_uniform_storage);
|
||||
DECL_RESOURCE_FUNC(ATC, gl_active_atomic_buffer);
|
||||
DECL_RESOURCE_FUNC(XFB, gl_transform_feedback_varying_info);
|
||||
|
||||
void GLAPIENTRY
|
||||
_mesa_BindAttribLocation(GLhandleARB program, GLuint index,
|
||||
const GLcharARB *name)
|
||||
|
|
@ -498,3 +516,44 @@ _mesa_GetFragDataLocation(GLuint program, const GLchar *name)
|
|||
|
||||
return -1;
|
||||
}
|
||||
|
||||
const char*
|
||||
_mesa_program_resource_name(struct gl_program_resource *res)
|
||||
{
|
||||
switch (res->Type) {
|
||||
case GL_UNIFORM_BLOCK:
|
||||
return RESOURCE_UBO(res)->Name;
|
||||
case GL_TRANSFORM_FEEDBACK_VARYING:
|
||||
return RESOURCE_XFB(res)->Name;
|
||||
case GL_PROGRAM_INPUT:
|
||||
case GL_PROGRAM_OUTPUT:
|
||||
return RESOURCE_VAR(res)->name;
|
||||
case GL_UNIFORM:
|
||||
return RESOURCE_UNI(res)->name;
|
||||
default:
|
||||
assert(!"support for resource type not implemented");
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
unsigned
|
||||
_mesa_program_resource_array_size(struct gl_program_resource *res)
|
||||
{
|
||||
switch (res->Type) {
|
||||
case GL_TRANSFORM_FEEDBACK_VARYING:
|
||||
return RESOURCE_XFB(res)->Size > 1 ?
|
||||
RESOURCE_XFB(res)->Size : 0;
|
||||
case GL_PROGRAM_INPUT:
|
||||
case GL_PROGRAM_OUTPUT:
|
||||
return RESOURCE_VAR(res)->data.max_array_access;
|
||||
case GL_UNIFORM:
|
||||
return RESOURCE_UNI(res)->array_elements;
|
||||
case GL_ATOMIC_COUNTER_BUFFER:
|
||||
case GL_UNIFORM_BLOCK:
|
||||
return 0;
|
||||
default:
|
||||
assert(!"support for resource type not implemented");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -219,6 +219,13 @@ extern GLuint GLAPIENTRY
|
|||
_mesa_CreateShaderProgramv(GLenum type, GLsizei count,
|
||||
const GLchar* const *strings);
|
||||
|
||||
/* GL_ARB_program_resource_query */
|
||||
extern const char*
|
||||
_mesa_program_resource_name(struct gl_program_resource *res);
|
||||
|
||||
extern unsigned
|
||||
_mesa_program_resource_array_size(struct gl_program_resource *res);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue