summaryrefslogtreecommitdiffstats
path: root/src/mesa
diff options
context:
space:
mode:
authorGert Wollny <[email protected]>2018-11-12 12:34:26 +0100
committerEmil Velikov <[email protected]>2018-11-14 18:53:02 +0000
commite2494a9387860354051f945c7dd423a59e4ffb08 (patch)
tree94c8d06ee3b20804882877cf5418a87b9ba5dd8b /src/mesa
parent8a79c536d57fbbd77d804dc47635872c356edf9b (diff)
mesa: Reference count shaders that are used by transform feedback objects
Transform feedback objects may hold a pointer to a shader program, and at least in Gallium, this must be a valid pointer until ctx->Driver.EndTransformFeedback in glEndTransformFeedback has been called - which is conform with the spec that any program that is part of a current rendering state should only be flagged for deletion by glDeleteProgram. This was not handled properly for the transform feedback objects so that a call sequence glUseProgram(x) glBeginTransformFreedback(...) glPauseTransformFeedback(...) glDeleteProgram(x) glEndTransformFeedback(...) would result in a use after free bug. With this patch the transform feedback object also updates the reference count to the used program thereby keeping the program valid as long as the transform feedback objects links to it. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=108713 Fixes: 654587696b4234d09a6b471b70e9629cf2887c27 mesa: add end_transform_feedback() helper Signed-off-by: Gert Wollny <[email protected]> Reviewed-by: Emil Velikov <[email protected]> (cherry picked from commit caa964b422152788a95a1b248c884df8918a2bbd)
Diffstat (limited to 'src/mesa')
-rw-r--r--src/mesa/main/transformfeedback.c3
1 files changed, 3 insertions, 0 deletions
diff --git a/src/mesa/main/transformfeedback.c b/src/mesa/main/transformfeedback.c
index a46c9f94bca..8eccdc20b76 100644
--- a/src/mesa/main/transformfeedback.c
+++ b/src/mesa/main/transformfeedback.c
@@ -40,6 +40,7 @@
#include "shaderapi.h"
#include "shaderobj.h"
+#include "program/program.h"
#include "program/prog_parameter.h"
struct using_program_tuple
@@ -470,6 +471,7 @@ begin_transform_feedback(struct gl_context *ctx, GLenum mode, bool no_error)
if (obj->program != source) {
ctx->NewDriverState |= ctx->DriverFlags.NewTransformFeedbackProg;
+ _mesa_reference_program_(ctx, &obj->program, source);
obj->program = source;
}
@@ -504,6 +506,7 @@ end_transform_feedback(struct gl_context *ctx,
assert(ctx->Driver.EndTransformFeedback);
ctx->Driver.EndTransformFeedback(ctx, obj);
+ _mesa_reference_program_(ctx, &obj->program, NULL);
ctx->TransformFeedback.CurrentObject->Active = GL_FALSE;
ctx->TransformFeedback.CurrentObject->Paused = GL_FALSE;
ctx->TransformFeedback.CurrentObject->EndedAnytime = GL_TRUE;