summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTapani Pälli <tapani.palli@intel.com>2013-10-16 19:59:39 +0300
committerTapani Pälli <tapani.palli@intel.com>2014-03-04 12:47:50 +0200
commit714a13adcbe8ac23c9816b89f97db9dd6a38caa3 (patch)
tree74ec0329a245262fa1096b84dd100549cf1590ca
parent6d6d29faf6b360a006b2d18f3ea5d732bd3d9b94 (diff)
mesa: OES_get_program_binary extension functionalityglsl_cache
Signed-off-by: Tapani Pälli <tapani.palli@intel.com>
-rw-r--r--src/mesa/main/shaderapi.c43
1 files changed, 37 insertions, 6 deletions
diff --git a/src/mesa/main/shaderapi.c b/src/mesa/main/shaderapi.c
index e2f3462af2b..91cda53c392 100644
--- a/src/mesa/main/shaderapi.c
+++ b/src/mesa/main/shaderapi.c
@@ -57,6 +57,7 @@
#include "../glsl/ir.h"
#include "../glsl/ir_uniform.h"
#include "../glsl/program.h"
+#include "../glsl/shader_cache.h"
/** Define this to enable shader substitution (see below) */
#define SHADER_SUBST 0
@@ -1665,8 +1666,25 @@ _mesa_GetProgramBinary(GLuint program, GLsizei bufSize, GLsizei *length,
if (length != NULL)
*length = 0;
- (void) binaryFormat;
- (void) binary;
+ size_t size = 0;
+ char *data = mesa_program_serialize(shProg, &size);
+
+ /* we have more data that can fit to user given buffer */
+ if (size > bufSize) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, __FUNCTION__);
+ free(data);
+ return;
+ }
+
+ if (data)
+ memcpy(binary, data, size);
+
+ free(data);
+
+ if (length != NULL)
+ *length = size;
+
+ *binaryFormat = 0;
}
void GLAPIENTRY
@@ -1680,10 +1698,23 @@ _mesa_ProgramBinary(GLuint program, GLenum binaryFormat,
if (!shProg)
return;
- (void) binaryFormat;
- (void) binary;
- (void) length;
- _mesa_error(ctx, GL_INVALID_OPERATION, __FUNCTION__);
+ if (length <= 0)
+ goto errors;
+
+ /* free possible existing data and initialize structure */
+ _mesa_free_shader_program_data(ctx, shProg);
+ _mesa_init_shader_program(ctx, shProg);
+
+ /* fill structure from a binary blob */
+ if (!mesa_program_deserialize(shProg, binary, length))
+ goto errors;
+
+errors:
+ /* on error set link status to false and clear the info log */
+ shProg->LinkStatus = GL_FALSE;
+ if (shProg->InfoLog)
+ ralloc_free(shProg->InfoLog);
+ shProg->InfoLog = ralloc_strdup(shProg, "");
}