1bf215546Sopenharmony_ci/* 2bf215546Sopenharmony_ci * Mesa 3-D graphics library 3bf215546Sopenharmony_ci * 4bf215546Sopenharmony_ci * Copyright (C) 2015 Intel Corporation. All Rights Reserved. 5bf215546Sopenharmony_ci * 6bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 7bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"), 8bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation 9bf215546Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense, 10bf215546Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the 11bf215546Sopenharmony_ci * Software is furnished to do so, subject to the following conditions: 12bf215546Sopenharmony_ci * 13bf215546Sopenharmony_ci * The above copyright notice and this permission notice shall be included 14bf215546Sopenharmony_ci * in all copies or substantial portions of the Software. 15bf215546Sopenharmony_ci * 16bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 17bf215546Sopenharmony_ci * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19bf215546Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20bf215546Sopenharmony_ci * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21bf215546Sopenharmony_ci * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22bf215546Sopenharmony_ci * OTHER DEALINGS IN THE SOFTWARE. 23bf215546Sopenharmony_ci * 24bf215546Sopenharmony_ci */ 25bf215546Sopenharmony_ci 26bf215546Sopenharmony_ci#include "main/enums.h" 27bf215546Sopenharmony_ci#include "main/macros.h" 28bf215546Sopenharmony_ci#include "main/mtypes.h" 29bf215546Sopenharmony_ci#include "main/shaderapi.h" 30bf215546Sopenharmony_ci#include "main/shaderobj.h" 31bf215546Sopenharmony_ci#include "main/context.h" 32bf215546Sopenharmony_ci#include "compiler/glsl/ir_uniform.h" 33bf215546Sopenharmony_ci#include "api_exec_decl.h" 34bf215546Sopenharmony_ci 35bf215546Sopenharmony_cistatic bool 36bf215546Sopenharmony_cisupported_interface_enum(struct gl_context *ctx, GLenum iface) 37bf215546Sopenharmony_ci{ 38bf215546Sopenharmony_ci switch (iface) { 39bf215546Sopenharmony_ci case GL_UNIFORM: 40bf215546Sopenharmony_ci case GL_UNIFORM_BLOCK: 41bf215546Sopenharmony_ci case GL_PROGRAM_INPUT: 42bf215546Sopenharmony_ci case GL_PROGRAM_OUTPUT: 43bf215546Sopenharmony_ci case GL_TRANSFORM_FEEDBACK_BUFFER: 44bf215546Sopenharmony_ci case GL_TRANSFORM_FEEDBACK_VARYING: 45bf215546Sopenharmony_ci case GL_ATOMIC_COUNTER_BUFFER: 46bf215546Sopenharmony_ci case GL_BUFFER_VARIABLE: 47bf215546Sopenharmony_ci case GL_SHADER_STORAGE_BLOCK: 48bf215546Sopenharmony_ci return true; 49bf215546Sopenharmony_ci case GL_VERTEX_SUBROUTINE: 50bf215546Sopenharmony_ci case GL_FRAGMENT_SUBROUTINE: 51bf215546Sopenharmony_ci case GL_VERTEX_SUBROUTINE_UNIFORM: 52bf215546Sopenharmony_ci case GL_FRAGMENT_SUBROUTINE_UNIFORM: 53bf215546Sopenharmony_ci return _mesa_has_ARB_shader_subroutine(ctx); 54bf215546Sopenharmony_ci case GL_GEOMETRY_SUBROUTINE: 55bf215546Sopenharmony_ci case GL_GEOMETRY_SUBROUTINE_UNIFORM: 56bf215546Sopenharmony_ci return _mesa_has_geometry_shaders(ctx) && _mesa_has_ARB_shader_subroutine(ctx); 57bf215546Sopenharmony_ci case GL_COMPUTE_SUBROUTINE: 58bf215546Sopenharmony_ci case GL_COMPUTE_SUBROUTINE_UNIFORM: 59bf215546Sopenharmony_ci return _mesa_has_compute_shaders(ctx) && _mesa_has_ARB_shader_subroutine(ctx); 60bf215546Sopenharmony_ci case GL_TESS_CONTROL_SUBROUTINE: 61bf215546Sopenharmony_ci case GL_TESS_EVALUATION_SUBROUTINE: 62bf215546Sopenharmony_ci case GL_TESS_CONTROL_SUBROUTINE_UNIFORM: 63bf215546Sopenharmony_ci case GL_TESS_EVALUATION_SUBROUTINE_UNIFORM: 64bf215546Sopenharmony_ci return _mesa_has_tessellation(ctx) && _mesa_has_ARB_shader_subroutine(ctx); 65bf215546Sopenharmony_ci default: 66bf215546Sopenharmony_ci return false; 67bf215546Sopenharmony_ci } 68bf215546Sopenharmony_ci} 69bf215546Sopenharmony_ci 70bf215546Sopenharmony_cistatic struct gl_shader_program * 71bf215546Sopenharmony_cilookup_linked_program(GLuint program, const char *caller) 72bf215546Sopenharmony_ci{ 73bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 74bf215546Sopenharmony_ci struct gl_shader_program *prog = 75bf215546Sopenharmony_ci _mesa_lookup_shader_program_err(ctx, program, caller); 76bf215546Sopenharmony_ci 77bf215546Sopenharmony_ci if (!prog) 78bf215546Sopenharmony_ci return NULL; 79bf215546Sopenharmony_ci 80bf215546Sopenharmony_ci if (prog->data->LinkStatus == LINKING_FAILURE) { 81bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_OPERATION, "%s(program not linked)", 82bf215546Sopenharmony_ci caller); 83bf215546Sopenharmony_ci return NULL; 84bf215546Sopenharmony_ci } 85bf215546Sopenharmony_ci return prog; 86bf215546Sopenharmony_ci} 87bf215546Sopenharmony_ci 88bf215546Sopenharmony_civoid GLAPIENTRY 89bf215546Sopenharmony_ci_mesa_GetProgramInterfaceiv(GLuint program, GLenum programInterface, 90bf215546Sopenharmony_ci GLenum pname, GLint *params) 91bf215546Sopenharmony_ci{ 92bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 93bf215546Sopenharmony_ci 94bf215546Sopenharmony_ci if (MESA_VERBOSE & VERBOSE_API) { 95bf215546Sopenharmony_ci _mesa_debug(ctx, "glGetProgramInterfaceiv(%u, %s, %s, %p)\n", 96bf215546Sopenharmony_ci program, _mesa_enum_to_string(programInterface), 97bf215546Sopenharmony_ci _mesa_enum_to_string(pname), params); 98bf215546Sopenharmony_ci } 99bf215546Sopenharmony_ci 100bf215546Sopenharmony_ci struct gl_shader_program *shProg = 101bf215546Sopenharmony_ci _mesa_lookup_shader_program_err(ctx, program, 102bf215546Sopenharmony_ci "glGetProgramInterfaceiv"); 103bf215546Sopenharmony_ci if (!shProg) 104bf215546Sopenharmony_ci return; 105bf215546Sopenharmony_ci 106bf215546Sopenharmony_ci if (!params) { 107bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_OPERATION, 108bf215546Sopenharmony_ci "glGetProgramInterfaceiv(params NULL)"); 109bf215546Sopenharmony_ci return; 110bf215546Sopenharmony_ci } 111bf215546Sopenharmony_ci 112bf215546Sopenharmony_ci /* Validate interface. */ 113bf215546Sopenharmony_ci if (!supported_interface_enum(ctx, programInterface)) { 114bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_OPERATION, "glGetProgramInterfaceiv(%s)", 115bf215546Sopenharmony_ci _mesa_enum_to_string(programInterface)); 116bf215546Sopenharmony_ci return; 117bf215546Sopenharmony_ci } 118bf215546Sopenharmony_ci 119bf215546Sopenharmony_ci _mesa_get_program_interfaceiv(shProg, programInterface, pname, params); 120bf215546Sopenharmony_ci} 121bf215546Sopenharmony_ci 122bf215546Sopenharmony_cistatic bool 123bf215546Sopenharmony_ciis_xfb_marker(const char *str) 124bf215546Sopenharmony_ci{ 125bf215546Sopenharmony_ci static const char *markers[] = { 126bf215546Sopenharmony_ci "gl_NextBuffer", 127bf215546Sopenharmony_ci "gl_SkipComponents1", 128bf215546Sopenharmony_ci "gl_SkipComponents2", 129bf215546Sopenharmony_ci "gl_SkipComponents3", 130bf215546Sopenharmony_ci "gl_SkipComponents4", 131bf215546Sopenharmony_ci NULL 132bf215546Sopenharmony_ci }; 133bf215546Sopenharmony_ci const char **m = markers; 134bf215546Sopenharmony_ci 135bf215546Sopenharmony_ci if (strncmp(str, "gl_", 3) != 0) 136bf215546Sopenharmony_ci return false; 137bf215546Sopenharmony_ci 138bf215546Sopenharmony_ci for (; *m; m++) 139bf215546Sopenharmony_ci if (strcmp(*m, str) == 0) 140bf215546Sopenharmony_ci return true; 141bf215546Sopenharmony_ci 142bf215546Sopenharmony_ci return false; 143bf215546Sopenharmony_ci} 144bf215546Sopenharmony_ci 145bf215546Sopenharmony_ciGLuint GLAPIENTRY 146bf215546Sopenharmony_ci_mesa_GetProgramResourceIndex(GLuint program, GLenum programInterface, 147bf215546Sopenharmony_ci const GLchar *name) 148bf215546Sopenharmony_ci{ 149bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 150bf215546Sopenharmony_ci 151bf215546Sopenharmony_ci if (MESA_VERBOSE & VERBOSE_API) { 152bf215546Sopenharmony_ci _mesa_debug(ctx, "glGetProgramResourceIndex(%u, %s, %s)\n", 153bf215546Sopenharmony_ci program, _mesa_enum_to_string(programInterface), name); 154bf215546Sopenharmony_ci } 155bf215546Sopenharmony_ci 156bf215546Sopenharmony_ci unsigned array_index = 0; 157bf215546Sopenharmony_ci struct gl_program_resource *res; 158bf215546Sopenharmony_ci struct gl_shader_program *shProg = 159bf215546Sopenharmony_ci _mesa_lookup_shader_program_err(ctx, program, 160bf215546Sopenharmony_ci "glGetProgramResourceIndex"); 161bf215546Sopenharmony_ci if (!shProg || !name) 162bf215546Sopenharmony_ci return GL_INVALID_INDEX; 163bf215546Sopenharmony_ci 164bf215546Sopenharmony_ci if (!supported_interface_enum(ctx, programInterface)) { 165bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramResourceIndex(%s)", 166bf215546Sopenharmony_ci _mesa_enum_to_string(programInterface)); 167bf215546Sopenharmony_ci return GL_INVALID_INDEX; 168bf215546Sopenharmony_ci } 169bf215546Sopenharmony_ci /* 170bf215546Sopenharmony_ci * For the interface TRANSFORM_FEEDBACK_VARYING, the value INVALID_INDEX 171bf215546Sopenharmony_ci * should be returned when querying the index assigned to the special names 172bf215546Sopenharmony_ci * "gl_NextBuffer", "gl_SkipComponents1", "gl_SkipComponents2", 173bf215546Sopenharmony_ci * "gl_SkipComponents3", and "gl_SkipComponents4". 174bf215546Sopenharmony_ci */ 175bf215546Sopenharmony_ci if (programInterface == GL_TRANSFORM_FEEDBACK_VARYING && 176bf215546Sopenharmony_ci is_xfb_marker(name)) 177bf215546Sopenharmony_ci return GL_INVALID_INDEX; 178bf215546Sopenharmony_ci 179bf215546Sopenharmony_ci switch (programInterface) { 180bf215546Sopenharmony_ci case GL_TESS_CONTROL_SUBROUTINE: 181bf215546Sopenharmony_ci case GL_TESS_CONTROL_SUBROUTINE_UNIFORM: 182bf215546Sopenharmony_ci case GL_TESS_EVALUATION_SUBROUTINE: 183bf215546Sopenharmony_ci case GL_TESS_EVALUATION_SUBROUTINE_UNIFORM: 184bf215546Sopenharmony_ci case GL_COMPUTE_SUBROUTINE: 185bf215546Sopenharmony_ci case GL_COMPUTE_SUBROUTINE_UNIFORM: 186bf215546Sopenharmony_ci case GL_GEOMETRY_SUBROUTINE: 187bf215546Sopenharmony_ci case GL_GEOMETRY_SUBROUTINE_UNIFORM: 188bf215546Sopenharmony_ci case GL_VERTEX_SUBROUTINE: 189bf215546Sopenharmony_ci case GL_FRAGMENT_SUBROUTINE: 190bf215546Sopenharmony_ci case GL_VERTEX_SUBROUTINE_UNIFORM: 191bf215546Sopenharmony_ci case GL_FRAGMENT_SUBROUTINE_UNIFORM: 192bf215546Sopenharmony_ci case GL_PROGRAM_INPUT: 193bf215546Sopenharmony_ci case GL_PROGRAM_OUTPUT: 194bf215546Sopenharmony_ci case GL_UNIFORM: 195bf215546Sopenharmony_ci case GL_BUFFER_VARIABLE: 196bf215546Sopenharmony_ci case GL_TRANSFORM_FEEDBACK_VARYING: 197bf215546Sopenharmony_ci case GL_UNIFORM_BLOCK: 198bf215546Sopenharmony_ci case GL_SHADER_STORAGE_BLOCK: 199bf215546Sopenharmony_ci res = _mesa_program_resource_find_name(shProg, programInterface, name, 200bf215546Sopenharmony_ci &array_index); 201bf215546Sopenharmony_ci if (!res || array_index > 0) 202bf215546Sopenharmony_ci return GL_INVALID_INDEX; 203bf215546Sopenharmony_ci 204bf215546Sopenharmony_ci return _mesa_program_resource_index(shProg, res); 205bf215546Sopenharmony_ci case GL_ATOMIC_COUNTER_BUFFER: 206bf215546Sopenharmony_ci case GL_TRANSFORM_FEEDBACK_BUFFER: 207bf215546Sopenharmony_ci default: 208bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramResourceIndex(%s)", 209bf215546Sopenharmony_ci _mesa_enum_to_string(programInterface)); 210bf215546Sopenharmony_ci } 211bf215546Sopenharmony_ci 212bf215546Sopenharmony_ci return GL_INVALID_INDEX; 213bf215546Sopenharmony_ci} 214bf215546Sopenharmony_ci 215bf215546Sopenharmony_civoid GLAPIENTRY 216bf215546Sopenharmony_ci_mesa_GetProgramResourceName(GLuint program, GLenum programInterface, 217bf215546Sopenharmony_ci GLuint index, GLsizei bufSize, GLsizei *length, 218bf215546Sopenharmony_ci GLchar *name) 219bf215546Sopenharmony_ci{ 220bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 221bf215546Sopenharmony_ci 222bf215546Sopenharmony_ci if (MESA_VERBOSE & VERBOSE_API) { 223bf215546Sopenharmony_ci _mesa_debug(ctx, "glGetProgramResourceName(%u, %s, %u, %d, %p, %p)\n", 224bf215546Sopenharmony_ci program, _mesa_enum_to_string(programInterface), index, 225bf215546Sopenharmony_ci bufSize, length, name); 226bf215546Sopenharmony_ci } 227bf215546Sopenharmony_ci 228bf215546Sopenharmony_ci struct gl_shader_program *shProg = 229bf215546Sopenharmony_ci _mesa_lookup_shader_program_err(ctx, program, 230bf215546Sopenharmony_ci "glGetProgramResourceName"); 231bf215546Sopenharmony_ci 232bf215546Sopenharmony_ci if (!shProg || !name) 233bf215546Sopenharmony_ci return; 234bf215546Sopenharmony_ci 235bf215546Sopenharmony_ci if (programInterface == GL_ATOMIC_COUNTER_BUFFER || 236bf215546Sopenharmony_ci programInterface == GL_TRANSFORM_FEEDBACK_BUFFER || 237bf215546Sopenharmony_ci !supported_interface_enum(ctx, programInterface)) { 238bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramResourceName(%s)", 239bf215546Sopenharmony_ci _mesa_enum_to_string(programInterface)); 240bf215546Sopenharmony_ci return; 241bf215546Sopenharmony_ci } 242bf215546Sopenharmony_ci 243bf215546Sopenharmony_ci _mesa_get_program_resource_name(shProg, programInterface, index, bufSize, 244bf215546Sopenharmony_ci length, name, false, 245bf215546Sopenharmony_ci "glGetProgramResourceName"); 246bf215546Sopenharmony_ci} 247bf215546Sopenharmony_ci 248bf215546Sopenharmony_civoid GLAPIENTRY 249bf215546Sopenharmony_ci_mesa_GetProgramResourceiv(GLuint program, GLenum programInterface, 250bf215546Sopenharmony_ci GLuint index, GLsizei propCount, 251bf215546Sopenharmony_ci const GLenum *props, GLsizei bufSize, 252bf215546Sopenharmony_ci GLsizei *length, GLint *params) 253bf215546Sopenharmony_ci{ 254bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 255bf215546Sopenharmony_ci 256bf215546Sopenharmony_ci if (MESA_VERBOSE & VERBOSE_API) { 257bf215546Sopenharmony_ci _mesa_debug(ctx, "glGetProgramResourceiv(%u, %s, %u, %d, %p, %d, %p, %p)\n", 258bf215546Sopenharmony_ci program, _mesa_enum_to_string(programInterface), index, 259bf215546Sopenharmony_ci propCount, props, bufSize, length, params); 260bf215546Sopenharmony_ci } 261bf215546Sopenharmony_ci 262bf215546Sopenharmony_ci struct gl_shader_program *shProg = 263bf215546Sopenharmony_ci _mesa_lookup_shader_program_err(ctx, program, "glGetProgramResourceiv"); 264bf215546Sopenharmony_ci 265bf215546Sopenharmony_ci if (!shProg || !params) 266bf215546Sopenharmony_ci return; 267bf215546Sopenharmony_ci 268bf215546Sopenharmony_ci /* The error INVALID_VALUE is generated if <propCount> is zero. 269bf215546Sopenharmony_ci * Note that we check < 0 here because it makes sense to bail early. 270bf215546Sopenharmony_ci */ 271bf215546Sopenharmony_ci if (propCount <= 0) { 272bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_VALUE, 273bf215546Sopenharmony_ci "glGetProgramResourceiv(propCount <= 0)"); 274bf215546Sopenharmony_ci return; 275bf215546Sopenharmony_ci } 276bf215546Sopenharmony_ci 277bf215546Sopenharmony_ci _mesa_get_program_resourceiv(shProg, programInterface, index, 278bf215546Sopenharmony_ci propCount, props, bufSize, length, params); 279bf215546Sopenharmony_ci} 280bf215546Sopenharmony_ci 281bf215546Sopenharmony_ciGLint GLAPIENTRY 282bf215546Sopenharmony_ci_mesa_GetProgramResourceLocation(GLuint program, GLenum programInterface, 283bf215546Sopenharmony_ci const GLchar *name) 284bf215546Sopenharmony_ci{ 285bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 286bf215546Sopenharmony_ci 287bf215546Sopenharmony_ci if (MESA_VERBOSE & VERBOSE_API) { 288bf215546Sopenharmony_ci _mesa_debug(ctx, "glGetProgramResourceLocation(%u, %s, %s)\n", 289bf215546Sopenharmony_ci program, _mesa_enum_to_string(programInterface), name); 290bf215546Sopenharmony_ci } 291bf215546Sopenharmony_ci 292bf215546Sopenharmony_ci struct gl_shader_program *shProg = 293bf215546Sopenharmony_ci lookup_linked_program(program, "glGetProgramResourceLocation"); 294bf215546Sopenharmony_ci 295bf215546Sopenharmony_ci if (!shProg || !name) 296bf215546Sopenharmony_ci return -1; 297bf215546Sopenharmony_ci 298bf215546Sopenharmony_ci /* Validate programInterface. */ 299bf215546Sopenharmony_ci switch (programInterface) { 300bf215546Sopenharmony_ci case GL_UNIFORM: 301bf215546Sopenharmony_ci case GL_PROGRAM_INPUT: 302bf215546Sopenharmony_ci case GL_PROGRAM_OUTPUT: 303bf215546Sopenharmony_ci break; 304bf215546Sopenharmony_ci 305bf215546Sopenharmony_ci case GL_VERTEX_SUBROUTINE_UNIFORM: 306bf215546Sopenharmony_ci case GL_FRAGMENT_SUBROUTINE_UNIFORM: 307bf215546Sopenharmony_ci if (!_mesa_has_ARB_shader_subroutine(ctx)) 308bf215546Sopenharmony_ci goto fail; 309bf215546Sopenharmony_ci break; 310bf215546Sopenharmony_ci case GL_GEOMETRY_SUBROUTINE_UNIFORM: 311bf215546Sopenharmony_ci if (!_mesa_has_geometry_shaders(ctx) || !_mesa_has_ARB_shader_subroutine(ctx)) 312bf215546Sopenharmony_ci goto fail; 313bf215546Sopenharmony_ci break; 314bf215546Sopenharmony_ci case GL_COMPUTE_SUBROUTINE_UNIFORM: 315bf215546Sopenharmony_ci if (!_mesa_has_compute_shaders(ctx) || !_mesa_has_ARB_shader_subroutine(ctx)) 316bf215546Sopenharmony_ci goto fail; 317bf215546Sopenharmony_ci break; 318bf215546Sopenharmony_ci case GL_TESS_CONTROL_SUBROUTINE_UNIFORM: 319bf215546Sopenharmony_ci case GL_TESS_EVALUATION_SUBROUTINE_UNIFORM: 320bf215546Sopenharmony_ci if (!_mesa_has_tessellation(ctx) || !_mesa_has_ARB_shader_subroutine(ctx)) 321bf215546Sopenharmony_ci goto fail; 322bf215546Sopenharmony_ci break; 323bf215546Sopenharmony_ci default: 324bf215546Sopenharmony_ci goto fail; 325bf215546Sopenharmony_ci } 326bf215546Sopenharmony_ci 327bf215546Sopenharmony_ci return _mesa_program_resource_location(shProg, programInterface, name); 328bf215546Sopenharmony_cifail: 329bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramResourceLocation(%s %s)", 330bf215546Sopenharmony_ci _mesa_enum_to_string(programInterface), name); 331bf215546Sopenharmony_ci return -1; 332bf215546Sopenharmony_ci} 333bf215546Sopenharmony_ci 334bf215546Sopenharmony_ci/** 335bf215546Sopenharmony_ci * Returns output index for dual source blending. 336bf215546Sopenharmony_ci */ 337bf215546Sopenharmony_ciGLint GLAPIENTRY 338bf215546Sopenharmony_ci_mesa_GetProgramResourceLocationIndex(GLuint program, GLenum programInterface, 339bf215546Sopenharmony_ci const GLchar *name) 340bf215546Sopenharmony_ci{ 341bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 342bf215546Sopenharmony_ci 343bf215546Sopenharmony_ci if (MESA_VERBOSE & VERBOSE_API) { 344bf215546Sopenharmony_ci _mesa_debug(ctx, "glGetProgramResourceLocationIndex(%u, %s, %s)\n", 345bf215546Sopenharmony_ci program, _mesa_enum_to_string(programInterface), name); 346bf215546Sopenharmony_ci } 347bf215546Sopenharmony_ci 348bf215546Sopenharmony_ci struct gl_shader_program *shProg = 349bf215546Sopenharmony_ci lookup_linked_program(program, "glGetProgramResourceLocationIndex"); 350bf215546Sopenharmony_ci 351bf215546Sopenharmony_ci if (!shProg || !name) 352bf215546Sopenharmony_ci return -1; 353bf215546Sopenharmony_ci 354bf215546Sopenharmony_ci /* From the GL_ARB_program_interface_query spec: 355bf215546Sopenharmony_ci * 356bf215546Sopenharmony_ci * "For GetProgramResourceLocationIndex, <programInterface> must be 357bf215546Sopenharmony_ci * PROGRAM_OUTPUT." 358bf215546Sopenharmony_ci */ 359bf215546Sopenharmony_ci if (programInterface != GL_PROGRAM_OUTPUT) { 360bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_ENUM, 361bf215546Sopenharmony_ci "glGetProgramResourceLocationIndex(%s)", 362bf215546Sopenharmony_ci _mesa_enum_to_string(programInterface)); 363bf215546Sopenharmony_ci return -1; 364bf215546Sopenharmony_ci } 365bf215546Sopenharmony_ci 366bf215546Sopenharmony_ci return _mesa_program_resource_location_index(shProg, GL_PROGRAM_OUTPUT, 367bf215546Sopenharmony_ci name); 368bf215546Sopenharmony_ci} 369