[Mesa-dev] [PATCH 17/19] mesa: fill out the ARB_shader_subroutine APIs

2015-07-09 Thread Dave Airlie
From: Dave Airlie airl...@redhat.com

This fleshes out the APIs, using the program resource
APIs where they should match.

It also sets the default values to valid subroutines.

Signed-off-by: Dave Airlie airl...@redhat.com
---
 src/mesa/main/shaderapi.c | 457 +-
 src/mesa/main/shaderapi.h |   3 +
 2 files changed, 457 insertions(+), 3 deletions(-)

diff --git a/src/mesa/main/shaderapi.c b/src/mesa/main/shaderapi.c
index 48ab217..1a46749 100644
--- a/src/mesa/main/shaderapi.c
+++ b/src/mesa/main/shaderapi.c
@@ -1071,6 +1071,7 @@ _mesa_use_program(struct gl_context *ctx, struct 
gl_shader_program *shProg)
   use_shader_program(ctx, i, shProg, ctx-Shader);
_mesa_active_program(ctx, shProg, glUseProgram);
 
+   _mesa_shader_program_init_subroutine_defaults(shProg);
if (ctx-Driver.UseProgram)
   ctx-Driver.UseProgram(ctx, shProg);
 }
@@ -1993,15 +1994,75 @@ GLint GLAPIENTRY
 _mesa_GetSubroutineUniformLocation(GLuint program, GLenum shadertype,
const GLchar *name)
 {
-   return -1;
-}
+   GET_CURRENT_CONTEXT(ctx);
+   const char *api_name = glGetSubroutineUniformLocation;
+   struct gl_shader_program *shProg;
+   GLenum resource_type;
+   gl_shader_stage stage;
+
+   if (!ctx-Extensions.ARB_shader_subroutine) {
+  _mesa_error(ctx, GL_INVALID_OPERATION, api_name);
+  return -1;
+   }
+
+   if (!_mesa_validate_shader_target(ctx, shadertype)) {
+  _mesa_error(ctx, GL_INVALID_OPERATION, api_name);
+  return -1;
+   }
 
+   shProg = _mesa_lookup_shader_program_err(ctx, program, api_name);
+   if (!shProg)
+  return -1;
+
+   stage = _mesa_shader_enum_to_shader_stage(shadertype);
+   if (!shProg-_LinkedShaders[stage]) {
+  _mesa_error(ctx, GL_INVALID_OPERATION, api_name);
+  return -1;
+   }
+
+   resource_type = _mesa_shader_stage_to_subroutine_uniform(stage);
+   return _mesa_program_resource_location(shProg, resource_type, name);
+}
 
 GLuint GLAPIENTRY
 _mesa_GetSubroutineIndex(GLuint program, GLenum shadertype,
  const GLchar *name)
 {
-   return GL_INVALID_INDEX;
+   GET_CURRENT_CONTEXT(ctx);
+   const char *api_name = glGetSubroutineIndex;
+   struct gl_shader_program *shProg;
+   struct gl_program_resource *res;
+   GLenum resource_type;
+   gl_shader_stage stage;
+
+   if (!ctx-Extensions.ARB_shader_subroutine) {
+  _mesa_error(ctx, GL_INVALID_OPERATION, api_name);
+  return -1;
+   }
+
+   if (!_mesa_validate_shader_target(ctx, shadertype)) {
+  _mesa_error(ctx, GL_INVALID_OPERATION, api_name);
+  return -1;
+   }
+
+   shProg = _mesa_lookup_shader_program_err(ctx, program, api_name);
+   if (!shProg)
+  return -1;
+
+   stage = _mesa_shader_enum_to_shader_stage(shadertype);
+   if (!shProg-_LinkedShaders[stage]) {
+  _mesa_error(ctx, GL_INVALID_OPERATION, api_name);
+  return -1;
+   }
+
+   resource_type = _mesa_shader_stage_to_subroutine(stage);
+   res = _mesa_program_resource_find_name(shProg, resource_type, name);
+   if (!res) {
+  _mesa_error(ctx, GL_INVALID_OPERATION, api_name);
+ return -1;
+   }
+
+   return _mesa_program_resource_index(shProg, res);
 }
 
 
@@ -2009,6 +2070,91 @@ GLvoid GLAPIENTRY
 _mesa_GetActiveSubroutineUniformiv(GLuint program, GLenum shadertype,
GLuint index, GLenum pname, GLint *values)
 {
+   GET_CURRENT_CONTEXT(ctx);
+   const char *api_name = glGetActiveSubroutineUniformiv;
+   struct gl_shader_program *shProg;
+   struct gl_shader *sh;
+   gl_shader_stage stage;
+   struct gl_program_resource *res;
+   const struct gl_uniform_storage *uni;
+   GLenum resource_type;
+   int count, i, j;
+   if (!ctx-Extensions.ARB_shader_subroutine) {
+  _mesa_error(ctx, GL_INVALID_OPERATION, api_name);
+  return;
+   }
+
+   if (!_mesa_validate_shader_target(ctx, shadertype)) {
+  _mesa_error(ctx, GL_INVALID_OPERATION, api_name);
+  return;
+   }
+
+   shProg = _mesa_lookup_shader_program_err(ctx, program, api_name);
+   if (!shProg)
+  return;
+
+   stage = _mesa_shader_enum_to_shader_stage(shadertype);
+   resource_type = _mesa_shader_stage_to_subroutine_uniform(stage);
+
+   sh = shProg-_LinkedShaders[stage];
+   if (!sh) {
+  _mesa_error(ctx, GL_INVALID_OPERATION, api_name);
+  return;
+   }
+
+   switch (pname) {
+   case GL_NUM_COMPATIBLE_SUBROUTINES: {
+  res = _mesa_program_resource_find_index(shProg, resource_type, index);
+  if (res) {
+ uni = res-Data;
+ count = 0;
+ for (i = 0; i  sh-NumSubroutineFunctions; i++) {
+struct gl_subroutine_function *fn = sh-SubroutineFunctions[i];
+for (j = 0; j  fn-num_compat_types; j++) {
+   if (fn-types[j] == uni-type) {
+  count++;
+  break;
+   }
+}
+ }
+ values[0] = count;
+  }
+  break;
+   }
+   case GL_COMPATIBLE_SUBROUTINES: {
+  res = 

[Mesa-dev] [PATCH 17/19] mesa: fill out the ARB_shader_subroutine APIs

2015-05-31 Thread Dave Airlie
From: Dave Airlie airl...@redhat.com

This fleshes out the APIs, using the program resource
APIs where they should match.

It also sets the default values to valid subroutines.

Signed-off-by: Dave Airlie airl...@redhat.com
---
 src/mesa/main/shaderapi.c | 457 +-
 src/mesa/main/shaderapi.h |   3 +
 2 files changed, 457 insertions(+), 3 deletions(-)

diff --git a/src/mesa/main/shaderapi.c b/src/mesa/main/shaderapi.c
index 1165776..69c080c 100644
--- a/src/mesa/main/shaderapi.c
+++ b/src/mesa/main/shaderapi.c
@@ -1071,6 +1071,7 @@ _mesa_use_program(struct gl_context *ctx, struct 
gl_shader_program *shProg)
   use_shader_program(ctx, i, shProg, ctx-Shader);
_mesa_active_program(ctx, shProg, glUseProgram);
 
+   _mesa_shader_program_init_subroutine_defaults(shProg);
if (ctx-Driver.UseProgram)
   ctx-Driver.UseProgram(ctx, shProg);
 }
@@ -1993,15 +1994,75 @@ GLint GLAPIENTRY
 _mesa_GetSubroutineUniformLocation(GLuint program, GLenum shadertype,
const GLchar *name)
 {
-   return -1;
-}
+   GET_CURRENT_CONTEXT(ctx);
+   const char *api_name = glGetSubroutineUniformLocation;
+   struct gl_shader_program *shProg;
+   GLenum resource_type;
+   gl_shader_stage stage;
+
+   if (!ctx-Extensions.ARB_shader_subroutine) {
+  _mesa_error(ctx, GL_INVALID_OPERATION, api_name);
+  return -1;
+   }
+
+   if (!_mesa_validate_shader_target(ctx, shadertype)) {
+  _mesa_error(ctx, GL_INVALID_OPERATION, api_name);
+  return -1;
+   }
 
+   shProg = _mesa_lookup_shader_program_err(ctx, program, api_name);
+   if (!shProg)
+  return -1;
+
+   stage = _mesa_shader_enum_to_shader_stage(shadertype);
+   if (!shProg-_LinkedShaders[stage]) {
+  _mesa_error(ctx, GL_INVALID_OPERATION, api_name);
+  return -1;
+   }
+
+   resource_type = _mesa_shader_stage_to_subroutine_uniform(stage);
+   return _mesa_program_resource_location(shProg, resource_type, name);
+}
 
 GLuint GLAPIENTRY
 _mesa_GetSubroutineIndex(GLuint program, GLenum shadertype,
  const GLchar *name)
 {
-   return GL_INVALID_INDEX;
+   GET_CURRENT_CONTEXT(ctx);
+   const char *api_name = glGetSubroutineIndex;
+   struct gl_shader_program *shProg;
+   struct gl_program_resource *res;
+   GLenum resource_type;
+   gl_shader_stage stage;
+
+   if (!ctx-Extensions.ARB_shader_subroutine) {
+  _mesa_error(ctx, GL_INVALID_OPERATION, api_name);
+  return -1;
+   }
+
+   if (!_mesa_validate_shader_target(ctx, shadertype)) {
+  _mesa_error(ctx, GL_INVALID_OPERATION, api_name);
+  return -1;
+   }
+
+   shProg = _mesa_lookup_shader_program_err(ctx, program, api_name);
+   if (!shProg)
+  return -1;
+
+   stage = _mesa_shader_enum_to_shader_stage(shadertype);
+   if (!shProg-_LinkedShaders[stage]) {
+  _mesa_error(ctx, GL_INVALID_OPERATION, api_name);
+  return -1;
+   }
+
+   resource_type = _mesa_shader_stage_to_subroutine(stage);
+   res = _mesa_program_resource_find_name(shProg, resource_type, name);
+   if (!res) {
+  _mesa_error(ctx, GL_INVALID_OPERATION, api_name);
+ return -1;
+   }
+
+   return _mesa_program_resource_index(shProg, res);
 }
 
 
@@ -2009,6 +2070,91 @@ GLvoid GLAPIENTRY
 _mesa_GetActiveSubroutineUniformiv(GLuint program, GLenum shadertype,
GLuint index, GLenum pname, GLint *values)
 {
+   GET_CURRENT_CONTEXT(ctx);
+   const char *api_name = glGetActiveSubroutineUniformiv;
+   struct gl_shader_program *shProg;
+   struct gl_shader *sh;
+   gl_shader_stage stage;
+   struct gl_program_resource *res;
+   const struct gl_uniform_storage *uni;
+   GLenum resource_type;
+   int count, i, j;
+   if (!ctx-Extensions.ARB_shader_subroutine) {
+  _mesa_error(ctx, GL_INVALID_OPERATION, api_name);
+  return;
+   }
+
+   if (!_mesa_validate_shader_target(ctx, shadertype)) {
+  _mesa_error(ctx, GL_INVALID_OPERATION, api_name);
+  return;
+   }
+
+   shProg = _mesa_lookup_shader_program_err(ctx, program, api_name);
+   if (!shProg)
+  return;
+
+   stage = _mesa_shader_enum_to_shader_stage(shadertype);
+   resource_type = _mesa_shader_stage_to_subroutine_uniform(stage);
+
+   sh = shProg-_LinkedShaders[stage];
+   if (!sh) {
+  _mesa_error(ctx, GL_INVALID_OPERATION, api_name);
+  return;
+   }
+
+   switch (pname) {
+   case GL_NUM_COMPATIBLE_SUBROUTINES: {
+  res = _mesa_program_resource_find_index(shProg, resource_type, index);
+  if (res) {
+ uni = res-Data;
+ count = 0;
+ for (i = 0; i  sh-NumSubroutineFunctions; i++) {
+struct gl_subroutine_function *fn = sh-SubroutineFunctions[i];
+for (j = 0; j  fn-num_compat_types; j++) {
+   if (fn-types[j] == uni-type) {
+  count++;
+  break;
+   }
+}
+ }
+ values[0] = count;
+  }
+  break;
+   }
+   case GL_COMPATIBLE_SUBROUTINES: {
+  res =