linker: Stub-out intrastage linker
This commit is contained in:
@@ -77,9 +77,8 @@ extern "C" {
|
||||
#include "ir.h"
|
||||
#include "ir_optimization.h"
|
||||
#include "program.h"
|
||||
extern "C" {
|
||||
#include "hash_table.h"
|
||||
}
|
||||
#include "shader_api.h"
|
||||
|
||||
/**
|
||||
* Visitor that determines whether or not a variable is ever written.
|
||||
@@ -399,6 +398,53 @@ cross_validate_outputs_to_inputs(struct gl_shader_program *prog,
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Populates a shaders symbol table with all global declarations
|
||||
*/
|
||||
static void
|
||||
populate_symbol_table(gl_shader *sh)
|
||||
{
|
||||
sh->symbols = new(sh) glsl_symbol_table;
|
||||
|
||||
foreach_list(node, sh->ir) {
|
||||
ir_instruction *const inst = (ir_instruction *) node;
|
||||
ir_variable *var;
|
||||
ir_function *func;
|
||||
|
||||
if ((func = inst->as_function()) != NULL) {
|
||||
sh->symbols->add_function(func->name, func);
|
||||
} else if ((var = inst->as_variable()) != NULL) {
|
||||
sh->symbols->add_variable(var->name, var);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Combine a group of shaders for a single stage to generate a linked shader
|
||||
*
|
||||
* \note
|
||||
* If this function is supplied a single shader, it is cloned, and the new
|
||||
* shader is returned.
|
||||
*/
|
||||
static struct gl_shader *
|
||||
link_intrastage_shaders(struct gl_shader_program *prog,
|
||||
struct gl_shader **shader_list,
|
||||
unsigned num_shaders)
|
||||
{
|
||||
(void) prog;
|
||||
assert(num_shaders == 1);
|
||||
|
||||
gl_shader *const linked = _mesa_new_shader(NULL, 0, shader_list[0]->Type);
|
||||
linked->ir = new(linked) exec_list;
|
||||
clone_ir_list(linked->ir, shader_list[0]->ir);
|
||||
|
||||
populate_symbol_table(linked);
|
||||
|
||||
return linked;
|
||||
}
|
||||
|
||||
|
||||
struct uniform_node {
|
||||
exec_node link;
|
||||
struct gl_uniform *u;
|
||||
@@ -807,25 +853,32 @@ link_shaders(struct gl_shader_program *prog)
|
||||
}
|
||||
|
||||
/* FINISHME: Implement intra-stage linking. */
|
||||
assert(num_vert_shaders <= 1);
|
||||
assert(num_frag_shaders <= 1);
|
||||
prog->_NumLinkedShaders = 0;
|
||||
if (num_vert_shaders > 0) {
|
||||
gl_shader *const sh =
|
||||
link_intrastage_shaders(prog, vert_shader_list, num_vert_shaders);
|
||||
|
||||
/* Verify that each of the per-target executables is valid.
|
||||
*/
|
||||
if (!validate_vertex_shader_executable(prog, vert_shader_list[0])
|
||||
|| !validate_fragment_shader_executable(prog, frag_shader_list[0]))
|
||||
if (sh == NULL)
|
||||
goto done;
|
||||
|
||||
if (!validate_vertex_shader_executable(prog, sh))
|
||||
goto done;
|
||||
|
||||
prog->_NumLinkedShaders = 0;
|
||||
|
||||
if (num_vert_shaders > 0) {
|
||||
prog->_LinkedShaders[prog->_NumLinkedShaders] = vert_shader_list[0];
|
||||
prog->_LinkedShaders[prog->_NumLinkedShaders] = sh;
|
||||
prog->_NumLinkedShaders++;
|
||||
}
|
||||
|
||||
if (num_frag_shaders > 0) {
|
||||
prog->_LinkedShaders[prog->_NumLinkedShaders] = frag_shader_list[0];
|
||||
gl_shader *const sh =
|
||||
link_intrastage_shaders(prog, frag_shader_list, num_frag_shaders);
|
||||
|
||||
if (sh == NULL)
|
||||
goto done;
|
||||
|
||||
if (!validate_fragment_shader_executable(prog, sh))
|
||||
goto done;
|
||||
|
||||
prog->_LinkedShaders[prog->_NumLinkedShaders] = sh;
|
||||
prog->_NumLinkedShaders++;
|
||||
}
|
||||
|
||||
|
@@ -36,6 +36,25 @@
|
||||
#include "ir_print_visitor.h"
|
||||
#include "program.h"
|
||||
|
||||
extern "C" struct gl_shader *
|
||||
_mesa_new_shader(GLcontext *ctx, GLuint name, GLenum type);
|
||||
|
||||
/* Copied from shader_api.c for the stand-alone compiler.
|
||||
*/
|
||||
struct gl_shader *
|
||||
_mesa_new_shader(GLcontext *ctx, GLuint name, GLenum type)
|
||||
{
|
||||
struct gl_shader *shader;
|
||||
assert(type == GL_FRAGMENT_SHADER || type == GL_VERTEX_SHADER);
|
||||
shader = talloc_zero(NULL, struct gl_shader);
|
||||
if (shader) {
|
||||
shader->Type = type;
|
||||
shader->Name = name;
|
||||
shader->RefCount = 1;
|
||||
}
|
||||
return shader;
|
||||
}
|
||||
|
||||
/* Returned string will have 'ctx' as its talloc owner. */
|
||||
static char *
|
||||
load_text_file(void *ctx, const char *file_name)
|
||||
@@ -271,6 +290,9 @@ main(int argc, char **argv)
|
||||
printf("Info log for linking:\n%s\n", whole_program->InfoLog);
|
||||
}
|
||||
|
||||
for (unsigned i = 0; i < whole_program->_NumLinkedShaders; i++)
|
||||
talloc_free(whole_program->_LinkedShaders[i]);
|
||||
|
||||
talloc_free(whole_program);
|
||||
_mesa_glsl_release_types();
|
||||
|
||||
|
@@ -1998,20 +1998,17 @@ _mesa_glsl_link_shader(GLcontext *ctx, struct gl_shader_program *prog)
|
||||
prog->Uniforms = _mesa_new_uniform_list();
|
||||
}
|
||||
|
||||
prog->LinkStatus = prog->LinkStatus;
|
||||
|
||||
/* FINISHME: This should use the linker-generated code */
|
||||
if (prog->LinkStatus) {
|
||||
for (i = 0; i < prog->NumShaders; i++) {
|
||||
for (i = 0; i < prog->_NumLinkedShaders; i++) {
|
||||
struct gl_program *linked_prog;
|
||||
|
||||
linked_prog = get_mesa_program(ctx, prog,
|
||||
prog->Shaders[i]);
|
||||
prog->_LinkedShaders[i]);
|
||||
count_resources(linked_prog);
|
||||
|
||||
link_uniforms_to_shared_uniform_list(prog->Uniforms, linked_prog);
|
||||
|
||||
switch (prog->Shaders[i]->Type) {
|
||||
switch (prog->_LinkedShaders[i]->Type) {
|
||||
case GL_VERTEX_SHADER:
|
||||
_mesa_reference_vertprog(ctx, &prog->VertexProgram,
|
||||
(struct gl_vertex_program *)linked_prog);
|
||||
|
Reference in New Issue
Block a user