summaryrefslogtreecommitdiff
path: root/src/mesa/shader/slang/slang_link2.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa/shader/slang/slang_link2.c')
-rw-r--r--src/mesa/shader/slang/slang_link2.c226
1 files changed, 226 insertions, 0 deletions
diff --git a/src/mesa/shader/slang/slang_link2.c b/src/mesa/shader/slang/slang_link2.c
new file mode 100644
index 0000000000..e62cc01b3e
--- /dev/null
+++ b/src/mesa/shader/slang/slang_link2.c
@@ -0,0 +1,226 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 6.6
+ *
+ * Copyright (C) 2006 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+ * \file slang_link.c
+ * slang linker
+ * \author Michal Krol
+ */
+
+#include "imports.h"
+#include "context.h"
+#include "hash.h"
+#include "macros.h"
+#include "program.h"
+#include "shaderobjects.h"
+#include "slang_link.h"
+
+
+
+
+#define RELEASE_GENERIC(x)\
+ (**x)._unknown.Release ((struct gl2_unknown_intf **) (x))
+
+#define RELEASE_CONTAINER(x)\
+ (**x)._generic._unknown.Release ((struct gl2_unknown_intf **) (x))
+
+#define RELEASE_PROGRAM(x)\
+ (**x)._container._generic._unknown.Release ((struct gl2_unknown_intf **) (x))
+
+#define RELEASE_SHADER(x)\
+ (**x)._generic._unknown.Release ((struct gl2_unknown_intf **) (x))
+
+
+
+static struct gl2_unknown_intf **
+lookup_handle(GLcontext * ctx, GLhandleARB handle, enum gl2_uiid uiid,
+ const char *function)
+{
+ struct gl2_unknown_intf **unk;
+
+ /*
+ * Note: _mesa_HashLookup() requires non-zero input values, so the
+ * passed-in handle value must be checked beforehand.
+ */
+ if (handle == 0) {
+ _mesa_error(ctx, GL_INVALID_VALUE, function);
+ return NULL;
+ }
+ _glthread_LOCK_MUTEX(ctx->Shared->Mutex);
+ unk = (struct gl2_unknown_intf **) _mesa_HashLookup(ctx->Shared->GL2Objects,
+ handle);
+ _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);
+
+ if (unk == NULL) {
+ _mesa_error(ctx, GL_INVALID_VALUE, function);
+ }
+ else {
+ unk = (**unk).QueryInterface(unk, uiid);
+ if (unk == NULL)
+ _mesa_error(ctx, GL_INVALID_OPERATION, function);
+ }
+ return unk;
+}
+
+#define GET_GENERIC(x, handle, function)\
+ struct gl2_generic_intf **x = (struct gl2_generic_intf **)\
+ lookup_handle (ctx, handle, UIID_GENERIC, function);
+
+#define GET_CONTAINER(x, handle, function)\
+ struct gl2_container_intf **x = (struct gl2_container_intf **)\
+ lookup_handle (ctx, handle, UIID_CONTAINER, function);
+
+#define GET_PROGRAM(x, handle, function)\
+ struct gl2_program_intf **x = (struct gl2_program_intf **)\
+ lookup_handle (ctx, handle, UIID_PROGRAM, function);
+
+#define GET_SHADER(x, handle, function)\
+ struct gl2_shader_intf **x = (struct gl2_shader_intf **)\
+ lookup_handle (ctx, handle, UIID_SHADER, function);
+
+
+static void
+prelink(GLhandleARB programObj, struct gl_linked_program *linked)
+{
+ GET_CURRENT_CONTEXT(ctx);
+
+ linked->VertexProgram = NULL;
+ linked->FragmentProgram = NULL;
+
+ if (programObj != 0) {
+ GET_PROGRAM(program, programObj, "glUseProgramObjectARB(program)");
+
+ if (program == NULL)
+ return;
+
+ /* XXX terrible hack to find the real vertex/fragment programs */
+ {
+ GLuint handle;
+ GLsizei cnt, i;
+ cnt = (**program)._container.GetAttachedCount((struct gl2_container_intf **) (program));
+
+ for (i = 0; i < cnt; i++) {
+ struct gl2_generic_intf **x
+ = (**program)._container.GetAttached((struct gl2_container_intf **) program, i);
+ handle = (**x).GetName(x);
+ {
+ struct gl_program *prog;
+ GET_SHADER(sha, handle, "foo");
+ if (sha && (*sha)->Program) {
+ prog = (*sha)->Program;
+ if (prog->Target == GL_VERTEX_PROGRAM_ARB)
+ linked->VertexProgram = (struct gl_vertex_program *) prog;
+ else if (prog->Target == GL_FRAGMENT_PROGRAM_ARB)
+ linked->FragmentProgram = (struct gl_fragment_program *) prog;
+ }
+ }
+#if 0
+ if (linked->VertexProgram)
+ printf("Found vert prog %p %d\n",
+ linked->VertexProgram,
+ linked->VertexProgram->Base.NumInstructions);
+ if (linked->FragmentProgram)
+ printf("Found frag prog %p %d\n",
+ linked->FragmentProgram,
+ linked->FragmentProgram->Base.NumInstructions);
+#endif
+ RELEASE_GENERIC(x);
+ }
+ }
+
+ }
+}
+
+
+
+void
+_slang_link2(GLcontext *ctx,
+ GLhandleARB programObj,
+ struct gl_linked_program *linked)
+{
+ struct gl_vertex_program *vertProg;
+ struct gl_fragment_program *fragProg;
+
+ prelink(programObj, linked);
+
+ vertProg = linked->VertexProgram;
+ fragProg = linked->FragmentProgram;
+
+ /* free old linked data, if any */
+ if (linked->NumUniforms > 0) {
+ GLuint i;
+ for (i = 0; i < linked->NumUniforms; i++) {
+ _mesa_free((char *) linked->Uniforms[i].Name);
+ linked->Uniforms[i].Name = NULL;
+ linked->Uniforms[i].Value = NULL;
+ }
+ linked->NumUniforms = 0;
+ }
+
+ /*
+ * Find uniforms.
+ * XXX what about dups?
+ */
+ if (vertProg) {
+ GLuint i;
+ for (i = 0; i < vertProg->Base.Parameters->NumParameters; i++) {
+ struct gl_program_parameter *p
+ = vertProg->Base.Parameters->Parameters + i;
+ if (p->Name) {
+ struct gl_uniform *u = linked->Uniforms + linked->NumUniforms;
+ u->Name = _mesa_strdup(p->Name);
+ u->Value = &vertProg->Base.Parameters->ParameterValues[i][0];
+ linked->NumUniforms++;
+ assert(linked->NumUniforms < MAX_UNIFORMS);
+ }
+ }
+ }
+ if (fragProg) {
+ GLuint i;
+ for (i = 0; i < fragProg->Base.Parameters->NumParameters; i++) {
+ struct gl_program_parameter *p
+ = fragProg->Base.Parameters->Parameters + i;
+ if (p->Name) {
+ struct gl_uniform *u = linked->Uniforms + linked->NumUniforms;
+ u->Name = _mesa_strdup(p->Name);
+ u->Value = &fragProg->Base.Parameters->ParameterValues[i][0];
+ linked->NumUniforms++;
+ assert(linked->NumUniforms < MAX_UNIFORMS);
+ }
+ }
+ }
+
+ /* For varying:
+ * scan both programs for varyings, rewrite programs so they agree
+ * on locations of varyings.
+ */
+
+ /**
+ * Linking should _copy_ the vertex and fragment shader code,
+ * rewriting varying references as we go along...
+ */
+
+ linked->LinkStatus = (vertProg && fragProg);
+}
+