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 | 89 ++++++++++++++++++++++++++++ src/mesa/drivers/dri/i965/brw_shader_cache.c | 7 +++ 3 files changed, 110 insertions(+), 1 deletion(-)
diff --git a/src/compiler/glsl/linker.cpp b/src/compiler/glsl/linker.cpp index ddc8390..56df085 100644 --- a/src/compiler/glsl/linker.cpp +++ b/src/compiler/glsl/linker.cpp @@ -4626,7 +4626,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 ed8a098..db31788 100644 --- a/src/compiler/glsl/shader_cache.cpp +++ b/src/compiler/glsl/shader_cache.cpp @@ -127,6 +127,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; @@ -330,6 +389,7 @@ write_program_resource_data(struct blob *metadata, encode_type_to_blob(metadata, var->type); blob_write_string(metadata, var->name); blob_write_uint32(metadata, var->location); + blob_write_uint32(metadata, var->component); unsigned data = var->index; data |= var->patch << 1; @@ -353,6 +413,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."); } @@ -370,6 +448,7 @@ read_program_resource_data(struct blob_reader *metadata, var->type = decode_type_from_blob(metadata); var->name = ralloc_strdup(prog, blob_read_string(metadata)); var->location = blob_read_uint32(metadata); + var->component = blob_read_uint32(metadata); unsigned data = blob_read_uint32(metadata); var->index = data & 1; @@ -389,6 +468,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."); } @@ -598,6 +683,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); @@ -695,6 +782,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 61e51a4..8b31e71 100644 --- a/src/mesa/drivers/dri/i965/brw_shader_cache.c +++ b/src/mesa/drivers/dri/i965/brw_shader_cache.c @@ -243,6 +243,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; + if (!read_and_upload(brw, cache, &binary, prog, stage)) goto FAIL; -- 2.7.4 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev