[Mesa-dev] [PATCH 30/31] mesa: don't flag _NEW_PROGRAM_CONSTANTS for GLSL programs for st/mesa

Marek Olšák maraeo at gmail.com
Mon Jun 12 16:55:55 UTC 2017


From: Marek Olšák <marek.olsak at amd.com>

---
 src/mesa/main/shaderapi.c           |  8 ++++++--
 src/mesa/main/uniform_query.cpp     | 21 +++++++++++++++++++--
 src/mesa/main/uniforms.h            |  4 ++++
 src/mesa/state_tracker/st_context.c |  3 ---
 4 files changed, 29 insertions(+), 7 deletions(-)

diff --git a/src/mesa/main/shaderapi.c b/src/mesa/main/shaderapi.c
index 9f0122a..5a71240 100644
--- a/src/mesa/main/shaderapi.c
+++ b/src/mesa/main/shaderapi.c
@@ -2579,27 +2579,33 @@ _mesa_UniformSubroutinesuiv(GLenum shadertype, GLsizei count,
       _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
       return;
    }
 
    if (count != p->sh.NumSubroutineUniformRemapTable) {
       _mesa_error(ctx, GL_INVALID_VALUE, "%s", api_name);
       return;
    }
 
    i = 0;
+   bool flushed = false;
    do {
       struct gl_uniform_storage *uni = p->sh.SubroutineUniformRemapTable[i];
       if (uni == NULL) {
          i++;
          continue;
       }
 
+      if (!flushed) {
+         _mesa_flush_vertices_for_uniforms(ctx, uni);
+         flushed = true;
+      }
+
       int uni_count = uni->array_elements ? uni->array_elements : 1;
       int j, k, f;
 
       for (j = i; j < i + uni_count; j++) {
          struct gl_subroutine_function *subfn = NULL;
          if (indices[j] > p->sh.MaxSubroutineFunctionIndex) {
             _mesa_error(ctx, GL_INVALID_VALUE, "%s", api_name);
             return;
          }
 
@@ -2618,22 +2624,20 @@ _mesa_UniformSubroutinesuiv(GLenum shadertype, GLsizei count,
          }
          if (k == subfn->num_compat_types) {
             _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
             return;
          }
 
          ctx->SubroutineIndex[p->info.stage].IndexPtr[j] = indices[j];
       }
       i += uni_count;
    } while(i < count);
-
-   FLUSH_VERTICES(ctx, _NEW_PROGRAM_CONSTANTS);
 }
 
 
 GLvoid GLAPIENTRY
 _mesa_GetUniformSubroutineuiv(GLenum shadertype, GLint location,
                               GLuint *params)
 {
    GET_CURRENT_CONTEXT(ctx);
    const char *api_name = "glGetUniformSubroutineuiv";
    gl_shader_stage stage;
diff --git a/src/mesa/main/uniform_query.cpp b/src/mesa/main/uniform_query.cpp
index e6c78bf..f9ea492 100644
--- a/src/mesa/main/uniform_query.cpp
+++ b/src/mesa/main/uniform_query.cpp
@@ -991,20 +991,37 @@ validate_uniform(GLint location, GLsizei count, const GLvoid *values,
                         "glUniform1i(invalid image unit index for uniform %d)",
                         location);
             return NULL;
          }
       }
    }
 
    return uni;
 }
 
+void
+_mesa_flush_vertices_for_uniforms(struct gl_context *ctx,
+                                  const struct gl_uniform_storage *uni)
+{
+   uint64_t new_driver_state = 0;
+   unsigned mask = uni->active_shader_mask;
+
+   while (mask) {
+      unsigned index = u_bit_scan(&mask);
+
+      assert(index < MESA_SHADER_STAGES);
+      new_driver_state |= ctx->DriverFlags.NewShaderConstants[index];
+   }
+
+   FLUSH_VERTICES(ctx, new_driver_state ? 0 : _NEW_PROGRAM_CONSTANTS);
+   ctx->NewDriverState |= new_driver_state;
+}
 
 /**
  * Called via glUniform*() functions.
  */
 extern "C" void
 _mesa_uniform(GLint location, GLsizei count, const GLvoid *values,
               struct gl_context *ctx, struct gl_shader_program *shProg,
               enum glsl_base_type basicType, unsigned src_components)
 {
    unsigned offset;
@@ -1045,21 +1062,21 @@ _mesa_uniform(GLint location, GLsizei count, const GLvoid *values,
     *     element that exceeds the highest array element index used, as
     *     reported by GetActiveUniform, will be ignored by the GL."
     *
     * Clamp 'count' to a valid value.  Note that for non-arrays a count > 1
     * will have already generated an error.
     */
    if (uni->array_elements != 0) {
       count = MIN2(count, (int) (uni->array_elements - offset));
    }
 
-   FLUSH_VERTICES(ctx, _NEW_PROGRAM_CONSTANTS);
+   _mesa_flush_vertices_for_uniforms(ctx, uni);
 
    /* Store the data in the "actual type" backing storage for the uniform.
     */
    if (!uni->type->is_boolean()) {
       memcpy(&uni->storage[size_mul * components * offset], values,
              sizeof(uni->storage[0]) * components * count * size_mul);
    } else {
       const union gl_constant_value *src =
          (const union gl_constant_value *) values;
       union gl_constant_value *dst = &uni->storage[components * offset];
@@ -1222,21 +1239,21 @@ _mesa_uniform_matrix(GLint location, GLsizei count,
     *     element that exceeds the highest array element index used, as
     *     reported by GetActiveUniform, will be ignored by the GL."
     *
     * Clamp 'count' to a valid value.  Note that for non-arrays a count > 1
     * will have already generated an error.
     */
    if (uni->array_elements != 0) {
       count = MIN2(count, (int) (uni->array_elements - offset));
    }
 
-   FLUSH_VERTICES(ctx, _NEW_PROGRAM_CONSTANTS);
+   _mesa_flush_vertices_for_uniforms(ctx, uni);
 
    /* Store the data in the "actual type" backing storage for the uniform.
     */
    const unsigned elements = components * vectors;
 
    if (!transpose) {
       memcpy(&uni->storage[size_mul * elements * offset], values,
 	     sizeof(uni->storage[0]) * elements * count * size_mul);
    } else if (basicType == GLSL_TYPE_FLOAT) {
       /* Copy and transpose the matrix.
diff --git a/src/mesa/main/uniforms.h b/src/mesa/main/uniforms.h
index 21d8571..7fd1aac 100644
--- a/src/mesa/main/uniforms.h
+++ b/src/mesa/main/uniforms.h
@@ -463,20 +463,24 @@ _mesa_propagate_uniforms_to_driver_storage(struct gl_uniform_storage *uni,
 extern void
 _mesa_update_shader_textures_used(struct gl_shader_program *shProg,
 				  struct gl_program *prog);
 
 extern bool
 _mesa_sampler_uniforms_are_valid(const struct gl_shader_program *shProg,
 				 char *errMsg, size_t errMsgLength);
 extern bool
 _mesa_sampler_uniforms_pipeline_are_valid(struct gl_pipeline_object *);
 
+extern void
+_mesa_flush_vertices_for_uniforms(struct gl_context *ctx,
+                                  const struct gl_uniform_storage *uni);
+
 struct gl_builtin_uniform_element {
    const char *field;
    int tokens[STATE_LENGTH];
    int swizzle;
 };
 
 struct gl_builtin_uniform_desc {
    const char *name;
    const struct gl_builtin_uniform_element *elements;
    unsigned int num_elements;
diff --git a/src/mesa/state_tracker/st_context.c b/src/mesa/state_tracker/st_context.c
index e676a48..a81b2c2 100644
--- a/src/mesa/state_tracker/st_context.c
+++ b/src/mesa/state_tracker/st_context.c
@@ -236,23 +236,20 @@ st_invalidate_state(struct gl_context * ctx)
    if (new_state & _NEW_TEXTURE_OBJECT) {
       st->dirty |= st->active_states &
                    (ST_NEW_SAMPLER_VIEWS |
                     ST_NEW_SAMPLERS |
                     ST_NEW_IMAGE_UNITS);
       if (ctx->FragmentProgram._Current &&
           ctx->FragmentProgram._Current->ExternalSamplersUsed) {
          st->dirty |= ST_NEW_FS_STATE;
       }
    }
-
-   if (new_state & _NEW_PROGRAM_CONSTANTS)
-      st->dirty |= st->active_states & ST_NEW_CONSTANTS;
 }
 
 
 static void
 st_destroy_context_priv(struct st_context *st, bool destroy_pipe)
 {
    uint shader, i;
 
    st_destroy_atoms( st );
    st_destroy_draw( st );
-- 
2.7.4



More information about the mesa-dev mailing list