For now this disables the shader cache when transform feedback is enabled via the GL API. --- src/compiler/glsl/linker.cpp | 15 ++++- src/compiler/glsl/shader_cache.cpp | 87 ++++++++++++++++++++++++++++ src/mesa/drivers/dri/i965/brw_shader_cache.c | 7 +++ 3 files changed, 108 insertions(+), 1 deletion(-)
diff --git a/src/compiler/glsl/linker.cpp b/src/compiler/glsl/linker.cpp index d71f96c..13336f8 100644 --- a/src/compiler/glsl/linker.cpp +++ b/src/compiler/glsl/linker.cpp @@ -4629,7 +4629,20 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog, unsigned int num_explicit_uniform_locs = 0; #ifdef ENABLE_SHADER_CACHE - if (!is_cache_fallback && 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 (!is_cache_fallback && !skip_cache && + shader_cache_read_program_metadata(ctx, prog)) return; #endif diff --git a/src/compiler/glsl/shader_cache.cpp b/src/compiler/glsl/shader_cache.cpp index 0020963..66506af 100644 --- a/src/compiler/glsl/shader_cache.cpp +++ b/src/compiler/glsl/shader_cache.cpp @@ -126,6 +126,65 @@ decode_type_from_blob(struct blob_reader *blob) } static void +write_xfb(struct blob *metadata, struct gl_shader_program *prog) +{ + struct gl_transform_feedback_info *ltf = &prog->LinkedTransformFeedback; + + 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 *prog) +{ + struct gl_transform_feedback_info *ltf = &prog->LinkedTransformFeedback; + + 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) { uint32_t i; @@ -343,6 +402,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->LinkedTransformFeedback.Buffers[i].Binding) { + blob_write_uint32(metadata, i); + break; + } + } + break; + case GL_TRANSFORM_FEEDBACK_VARYING: + for (int i = 0; i < prog->LinkedTransformFeedback.NumVarying; i++) { + if (strcmp(((gl_transform_feedback_varying_info *)res->Data)->Name, + prog->LinkedTransformFeedback.Varyings[i].Name) == 0) { + blob_write_uint32(metadata, i); + break; + } + } + break; default: assert(!"Support for writting resource not yet implemented."); } @@ -379,6 +456,12 @@ read_program_resource_data(struct blob_reader *metadata, case GL_UNIFORM: res->Data = &prog->UniformStorage[blob_read_uint32(metadata)]; break; + case GL_TRANSFORM_FEEDBACK_BUFFER: + res->Data = &prog->LinkedTransformFeedback.Buffers[blob_read_uint32(metadata)]; + break; + case GL_TRANSFORM_FEEDBACK_VARYING: + res->Data = &prog->LinkedTransformFeedback.Varyings[blob_read_uint32(metadata)]; + break; default: assert(!"Support for reading resource not yet implemented."); } @@ -584,6 +667,8 @@ shader_cache_write_program_metadata(struct gl_context *ctx, metadata = blob_create(NULL); + write_xfb(metadata, prog); + write_uniforms(metadata, prog); write_hash_tables(metadata, prog); @@ -681,6 +766,8 @@ shader_cache_read_program_metadata(struct gl_context *ctx, assert(prog->UniformStorage == NULL); + read_xfb(&metadata, prog); + read_uniforms(&metadata, prog); read_hash_tables(&metadata, prog); diff --git a/src/mesa/drivers/dri/i965/brw_shader_cache.c b/src/mesa/drivers/dri/i965/brw_shader_cache.c index aceaf32..f64269e 100644 --- a/src/mesa/drivers/dri/i965/brw_shader_cache.c +++ b/src/mesa/drivers/dri/i965/brw_shader_cache.c @@ -210,6 +210,13 @@ upload_cached_program(struct brw_context *brw, gl_shader_stage stage) if (prog == NULL) return; + /* FIXME: For now we don't read from the cache if transform feedback is + * enabled via the API. However the shader cache does support transform + * feedback when enabled via in shader xfb qualifiers. + */ + if (prog->TransformFeedback.NumVarying > 0) + return; + brw_vs_populate_key(brw, &vs_key); switch (stage) { case MESA_SHADER_VERTEX: -- 2.7.4 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev