[Mesa-dev] [PATCH 08/32] glsl: add support for caching shaders with xfb qualifiers

Nicolai Hähnle nhaehnle at gmail.com
Thu Feb 16 11:24:08 UTC 2017


On 14.02.2017 01:52, Timothy Arceri wrote:
> From: Timothy Arceri <timothy.arceri at collabora.com>
>
> For now this disables the shader cache when transform feedback is
> enabled via the GL API as we don't currently allow for it when
> generating the sha for the shader.

Reviewed-by: Nicolai Hähnle <nicolai.haehnle at amd.com>

> ---
>  src/compiler/glsl/linker.cpp       |  14 ++++-
>  src/compiler/glsl/shader_cache.cpp | 108 +++++++++++++++++++++++++++++++++++++
>  2 files changed, 121 insertions(+), 1 deletion(-)
>
> diff --git a/src/compiler/glsl/linker.cpp b/src/compiler/glsl/linker.cpp
> index 80d8314..7aaaee2 100644
> --- a/src/compiler/glsl/linker.cpp
> +++ b/src/compiler/glsl/linker.cpp
> @@ -4621,7 +4621,19 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
>        return;
>     }
>
> -   if (shader_cache_read_program_metadata(ctx, prog))
> +   /* If transform feedback used on the program then compile all shaders. */
> +   bool skip_cache = false;
> +   if (prog->TransformFeedback.NumVarying > 0) {
> +      for (unsigned i = 0; i < prog->NumShaders; i++) {
> +         if (prog->Shaders[i]->ir) {
> +            continue;
> +         }
> +         _mesa_glsl_compile_shader(ctx, prog->Shaders[i], false, false, true);
> +      }
> +      skip_cache = true;
> +   }
> +
> +   if (!skip_cache && shader_cache_read_program_metadata(ctx, prog))
>        return;
>
>     void *mem_ctx = ralloc_context(NULL); // temporary linker context
> diff --git a/src/compiler/glsl/shader_cache.cpp b/src/compiler/glsl/shader_cache.cpp
> index 6a1b56b..1349e64 100644
> --- a/src/compiler/glsl/shader_cache.cpp
> +++ b/src/compiler/glsl/shader_cache.cpp
> @@ -208,6 +208,84 @@ decode_type_from_blob(struct blob_reader *blob)
>  }
>
>  static void
> +write_xfb(struct blob *metadata, struct gl_shader_program *shProg)
> +{
> +   struct gl_program *prog = shProg->last_vert_prog;
> +
> +   if (!prog) {
> +      blob_write_uint32(metadata, ~0u);
> +      return;
> +   }
> +
> +   struct gl_transform_feedback_info *ltf = prog->sh.LinkedTransformFeedback;
> +
> +   blob_write_uint32(metadata, prog->info.stage);
> +
> +   blob_write_uint32(metadata, ltf->NumOutputs);
> +   blob_write_uint32(metadata, ltf->ActiveBuffers);
> +   blob_write_uint32(metadata, ltf->NumVarying);
> +
> +   blob_write_bytes(metadata, ltf->Outputs,
> +                    sizeof(struct gl_transform_feedback_output) *
> +                       ltf->NumOutputs);
> +
> +   for (int i = 0; i < ltf->NumVarying; i++) {
> +      blob_write_string(metadata, ltf->Varyings[i].Name);
> +      blob_write_uint32(metadata, ltf->Varyings[i].Type);
> +      blob_write_uint32(metadata, ltf->Varyings[i].BufferIndex);
> +      blob_write_uint32(metadata, ltf->Varyings[i].Size);
> +      blob_write_uint32(metadata, ltf->Varyings[i].Offset);
> +   }
> +
> +   blob_write_bytes(metadata, ltf->Buffers,
> +                    sizeof(struct gl_transform_feedback_buffer) *
> +                       MAX_FEEDBACK_BUFFERS);
> +}
> +
> +static void
> +read_xfb(struct blob_reader *metadata, struct gl_shader_program *shProg)
> +{
> +   unsigned xfb_stage = blob_read_uint32(metadata);
> +
> +   if (xfb_stage == ~0u)
> +      return;
> +
> +   struct gl_program *prog = shProg->_LinkedShaders[xfb_stage]->Program;
> +   struct gl_transform_feedback_info *ltf =
> +      rzalloc(prog, struct gl_transform_feedback_info);
> +
> +   prog->sh.LinkedTransformFeedback = ltf;
> +   shProg->last_vert_prog = prog;
> +
> +   ltf->NumOutputs = blob_read_uint32(metadata);
> +   ltf->ActiveBuffers = blob_read_uint32(metadata);
> +   ltf->NumVarying = blob_read_uint32(metadata);
> +
> +   ltf->Outputs = rzalloc_array(prog, struct gl_transform_feedback_output,
> +                                ltf->NumOutputs);
> +
> +   blob_copy_bytes(metadata, (uint8_t *) ltf->Outputs,
> +                   sizeof(struct gl_transform_feedback_output) *
> +                      ltf->NumOutputs);
> +
> +   ltf->Varyings = rzalloc_array(prog,
> +                                 struct gl_transform_feedback_varying_info,
> +                                 ltf->NumVarying);
> +
> +   for (int i = 0; i < ltf->NumVarying; i++) {
> +      ltf->Varyings[i].Name = ralloc_strdup(prog, blob_read_string(metadata));
> +      ltf->Varyings[i].Type = blob_read_uint32(metadata);
> +      ltf->Varyings[i].BufferIndex = blob_read_uint32(metadata);
> +      ltf->Varyings[i].Size = blob_read_uint32(metadata);
> +      ltf->Varyings[i].Offset = blob_read_uint32(metadata);
> +   }
> +
> +   blob_copy_bytes(metadata, (uint8_t *) ltf->Buffers,
> +                   sizeof(struct gl_transform_feedback_buffer) *
> +                      MAX_FEEDBACK_BUFFERS);
> +}
> +
> +static void
>  write_uniforms(struct blob *metadata, struct gl_shader_program *prog)
>  {
>     blob_write_uint32(metadata, prog->SamplersValidated);
> @@ -458,6 +536,24 @@ write_program_resource_data(struct blob *metadata,
>           }
>        }
>        break;
> +   case GL_TRANSFORM_FEEDBACK_BUFFER:
> +      for (unsigned i = 0; i < MAX_FEEDBACK_BUFFERS; i++) {
> +         if (((gl_transform_feedback_buffer *)res->Data)->Binding ==
> +             prog->last_vert_prog->sh.LinkedTransformFeedback->Buffers[i].Binding) {
> +            blob_write_uint32(metadata, i);
> +            break;
> +         }
> +      }
> +      break;
> +   case GL_TRANSFORM_FEEDBACK_VARYING:
> +      for (int i = 0; i < prog->last_vert_prog->sh.LinkedTransformFeedback->NumVarying; i++) {
> +         if (strcmp(((gl_transform_feedback_varying_info *)res->Data)->Name,
> +                    prog->last_vert_prog->sh.LinkedTransformFeedback->Varyings[i].Name) == 0) {
> +            blob_write_uint32(metadata, i);
> +            break;
> +         }
> +      }
> +      break;
>     default:
>        assert(!"Support for writing resource not yet implemented.");
>     }
> @@ -497,6 +593,14 @@ read_program_resource_data(struct blob_reader *metadata,
>     case GL_UNIFORM:
>        res->Data = &prog->data->UniformStorage[blob_read_uint32(metadata)];
>        break;
> +   case GL_TRANSFORM_FEEDBACK_BUFFER:
> +      res->Data = &prog->last_vert_prog->
> +         sh.LinkedTransformFeedback->Buffers[blob_read_uint32(metadata)];
> +      break;
> +   case GL_TRANSFORM_FEEDBACK_VARYING:
> +      res->Data = &prog->last_vert_prog->
> +         sh.LinkedTransformFeedback->Varyings[blob_read_uint32(metadata)];
> +      break;
>     default:
>        assert(!"Support for reading resource not yet implemented.");
>     }
> @@ -709,6 +813,8 @@ shader_cache_write_program_metadata(struct gl_context *ctx,
>        }
>     }
>
> +   write_xfb(metadata, prog);
> +
>     write_uniform_remap_table(metadata, prog);
>
>     write_program_resource_list(metadata, prog);
> @@ -814,6 +920,8 @@ shader_cache_read_program_metadata(struct gl_context *ctx,
>                                         &metadata);
>     }
>
> +   read_xfb(&metadata, prog);
> +
>     read_uniform_remap_table(&metadata, prog);
>
>     read_program_resource_list(&metadata, prog);
>



More information about the mesa-dev mailing list