glsl2: Move our data from a glsl_shader* on the side to the main gl_shader *.
This saves recompiling at link time. gl_shader->ir is made a pointer so that we don't have to bring exec_list into mtypes.h.
This commit is contained in:
@@ -128,10 +128,10 @@ linker_error_printf(glsl_program *prog, const char *fmt, ...)
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
invalidate_variable_locations(glsl_shader *sh, enum ir_variable_mode mode,
|
invalidate_variable_locations(gl_shader *sh, enum ir_variable_mode mode,
|
||||||
int generic_base)
|
int generic_base)
|
||||||
{
|
{
|
||||||
foreach_list(node, &sh->ir) {
|
foreach_list(node, sh->ir) {
|
||||||
ir_variable *const var = ((ir_instruction *) node)->as_variable();
|
ir_variable *const var = ((ir_instruction *) node)->as_variable();
|
||||||
|
|
||||||
if ((var == NULL) || (var->mode != (unsigned) mode))
|
if ((var == NULL) || (var->mode != (unsigned) mode))
|
||||||
@@ -187,7 +187,7 @@ count_attribute_slots(const glsl_type *t)
|
|||||||
*/
|
*/
|
||||||
bool
|
bool
|
||||||
validate_vertex_shader_executable(struct glsl_program *prog,
|
validate_vertex_shader_executable(struct glsl_program *prog,
|
||||||
struct glsl_shader *shader)
|
struct gl_shader *shader)
|
||||||
{
|
{
|
||||||
if (shader == NULL)
|
if (shader == NULL)
|
||||||
return true;
|
return true;
|
||||||
@@ -198,7 +198,7 @@ validate_vertex_shader_executable(struct glsl_program *prog,
|
|||||||
}
|
}
|
||||||
|
|
||||||
find_assignment_visitor find("gl_Position");
|
find_assignment_visitor find("gl_Position");
|
||||||
find.run(&shader->ir);
|
find.run(shader->ir);
|
||||||
if (!find.variable_found()) {
|
if (!find.variable_found()) {
|
||||||
linker_error_printf(prog,
|
linker_error_printf(prog,
|
||||||
"vertex shader does not write to `gl_Position'\n");
|
"vertex shader does not write to `gl_Position'\n");
|
||||||
@@ -216,7 +216,7 @@ validate_vertex_shader_executable(struct glsl_program *prog,
|
|||||||
*/
|
*/
|
||||||
bool
|
bool
|
||||||
validate_fragment_shader_executable(struct glsl_program *prog,
|
validate_fragment_shader_executable(struct glsl_program *prog,
|
||||||
struct glsl_shader *shader)
|
struct gl_shader *shader)
|
||||||
{
|
{
|
||||||
if (shader == NULL)
|
if (shader == NULL)
|
||||||
return true;
|
return true;
|
||||||
@@ -229,8 +229,8 @@ validate_fragment_shader_executable(struct glsl_program *prog,
|
|||||||
find_assignment_visitor frag_color("gl_FragColor");
|
find_assignment_visitor frag_color("gl_FragColor");
|
||||||
find_assignment_visitor frag_data("gl_FragData");
|
find_assignment_visitor frag_data("gl_FragData");
|
||||||
|
|
||||||
frag_color.run(&shader->ir);
|
frag_color.run(shader->ir);
|
||||||
frag_data.run(&shader->ir);
|
frag_data.run(shader->ir);
|
||||||
|
|
||||||
if (!frag_color.variable_found() && !frag_data.variable_found()) {
|
if (!frag_color.variable_found() && !frag_data.variable_found()) {
|
||||||
linker_error_printf(prog, "fragment shader does not write to "
|
linker_error_printf(prog, "fragment shader does not write to "
|
||||||
@@ -259,7 +259,7 @@ cross_validate_uniforms(struct glsl_program *prog)
|
|||||||
*/
|
*/
|
||||||
glsl_symbol_table uniforms;
|
glsl_symbol_table uniforms;
|
||||||
for (unsigned i = 0; i < prog->_NumLinkedShaders; i++) {
|
for (unsigned i = 0; i < prog->_NumLinkedShaders; i++) {
|
||||||
foreach_list(node, &prog->_LinkedShaders[i]->ir) {
|
foreach_list(node, prog->_LinkedShaders[i]->ir) {
|
||||||
ir_variable *const var = ((ir_instruction *) node)->as_variable();
|
ir_variable *const var = ((ir_instruction *) node)->as_variable();
|
||||||
|
|
||||||
if ((var == NULL) || (var->mode != ir_var_uniform))
|
if ((var == NULL) || (var->mode != ir_var_uniform))
|
||||||
@@ -309,7 +309,7 @@ cross_validate_uniforms(struct glsl_program *prog)
|
|||||||
*/
|
*/
|
||||||
bool
|
bool
|
||||||
cross_validate_outputs_to_inputs(struct glsl_program *prog,
|
cross_validate_outputs_to_inputs(struct glsl_program *prog,
|
||||||
glsl_shader *producer, glsl_shader *consumer)
|
gl_shader *producer, gl_shader *consumer)
|
||||||
{
|
{
|
||||||
glsl_symbol_table parameters;
|
glsl_symbol_table parameters;
|
||||||
/* FINISHME: Figure these out dynamically. */
|
/* FINISHME: Figure these out dynamically. */
|
||||||
@@ -318,7 +318,7 @@ cross_validate_outputs_to_inputs(struct glsl_program *prog,
|
|||||||
|
|
||||||
/* Find all shader outputs in the "producer" stage.
|
/* Find all shader outputs in the "producer" stage.
|
||||||
*/
|
*/
|
||||||
foreach_list(node, &producer->ir) {
|
foreach_list(node, producer->ir) {
|
||||||
ir_variable *const var = ((ir_instruction *) node)->as_variable();
|
ir_variable *const var = ((ir_instruction *) node)->as_variable();
|
||||||
|
|
||||||
/* FINISHME: For geometry shaders, this should also look for inout
|
/* FINISHME: For geometry shaders, this should also look for inout
|
||||||
@@ -335,7 +335,7 @@ cross_validate_outputs_to_inputs(struct glsl_program *prog,
|
|||||||
* matching outputs already in the symbol table must have the same type and
|
* matching outputs already in the symbol table must have the same type and
|
||||||
* qualifiers.
|
* qualifiers.
|
||||||
*/
|
*/
|
||||||
foreach_list(node, &consumer->ir) {
|
foreach_list(node, consumer->ir) {
|
||||||
ir_variable *const input = ((ir_instruction *) node)->as_variable();
|
ir_variable *const input = ((ir_instruction *) node)->as_variable();
|
||||||
|
|
||||||
/* FINISHME: For geometry shaders, this should also look for inout
|
/* FINISHME: For geometry shaders, this should also look for inout
|
||||||
@@ -423,7 +423,7 @@ assign_uniform_locations(struct glsl_program *prog)
|
|||||||
for (unsigned i = 0; i < prog->_NumLinkedShaders; i++) {
|
for (unsigned i = 0; i < prog->_NumLinkedShaders; i++) {
|
||||||
unsigned next_position = 0;
|
unsigned next_position = 0;
|
||||||
|
|
||||||
foreach_list(node, &prog->_LinkedShaders[i]->ir) {
|
foreach_list(node, prog->_LinkedShaders[i]->ir) {
|
||||||
ir_variable *const var = ((ir_instruction *) node)->as_variable();
|
ir_variable *const var = ((ir_instruction *) node)->as_variable();
|
||||||
|
|
||||||
if ((var == NULL) || (var->mode != ir_var_uniform))
|
if ((var == NULL) || (var->mode != ir_var_uniform))
|
||||||
@@ -540,7 +540,7 @@ assign_attribute_locations(glsl_program *prog, unsigned max_attribute_index)
|
|||||||
unsigned used_locations = (max_attribute_index >= 32)
|
unsigned used_locations = (max_attribute_index >= 32)
|
||||||
? ~0 : ~((1 << max_attribute_index) - 1);
|
? ~0 : ~((1 << max_attribute_index) - 1);
|
||||||
|
|
||||||
glsl_shader *const sh = prog->_LinkedShaders[0];
|
gl_shader *const sh = prog->_LinkedShaders[0];
|
||||||
assert(sh->Type == GL_VERTEX_SHADER);
|
assert(sh->Type == GL_VERTEX_SHADER);
|
||||||
|
|
||||||
/* Operate in a total of four passes.
|
/* Operate in a total of four passes.
|
||||||
@@ -644,7 +644,7 @@ assign_attribute_locations(glsl_program *prog, unsigned max_attribute_index)
|
|||||||
|
|
||||||
unsigned num_attr = 0;
|
unsigned num_attr = 0;
|
||||||
|
|
||||||
foreach_list(node, &sh->ir) {
|
foreach_list(node, sh->ir) {
|
||||||
ir_variable *const var = ((ir_instruction *) node)->as_variable();
|
ir_variable *const var = ((ir_instruction *) node)->as_variable();
|
||||||
|
|
||||||
if ((var == NULL) || (var->mode != ir_var_in))
|
if ((var == NULL) || (var->mode != ir_var_in))
|
||||||
@@ -694,7 +694,7 @@ assign_attribute_locations(glsl_program *prog, unsigned max_attribute_index)
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
assign_varying_locations(glsl_shader *producer, glsl_shader *consumer)
|
assign_varying_locations(gl_shader *producer, gl_shader *consumer)
|
||||||
{
|
{
|
||||||
/* FINISHME: Set dynamically when geometry shader support is added. */
|
/* FINISHME: Set dynamically when geometry shader support is added. */
|
||||||
unsigned output_index = VERT_RESULT_VAR0;
|
unsigned output_index = VERT_RESULT_VAR0;
|
||||||
@@ -714,7 +714,7 @@ assign_varying_locations(glsl_shader *producer, glsl_shader *consumer)
|
|||||||
invalidate_variable_locations(producer, ir_var_out, VERT_RESULT_VAR0);
|
invalidate_variable_locations(producer, ir_var_out, VERT_RESULT_VAR0);
|
||||||
invalidate_variable_locations(consumer, ir_var_in, FRAG_ATTRIB_VAR0);
|
invalidate_variable_locations(consumer, ir_var_in, FRAG_ATTRIB_VAR0);
|
||||||
|
|
||||||
foreach_list(node, &producer->ir) {
|
foreach_list(node, producer->ir) {
|
||||||
ir_variable *const output_var = ((ir_instruction *) node)->as_variable();
|
ir_variable *const output_var = ((ir_instruction *) node)->as_variable();
|
||||||
|
|
||||||
if ((output_var == NULL) || (output_var->mode != ir_var_out)
|
if ((output_var == NULL) || (output_var->mode != ir_var_out)
|
||||||
@@ -740,7 +740,7 @@ assign_varying_locations(glsl_shader *producer, glsl_shader *consumer)
|
|||||||
input_index++;
|
input_index++;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach_list(node, &producer->ir) {
|
foreach_list(node, producer->ir) {
|
||||||
ir_variable *const var = ((ir_instruction *) node)->as_variable();
|
ir_variable *const var = ((ir_instruction *) node)->as_variable();
|
||||||
|
|
||||||
if ((var == NULL) || (var->mode != ir_var_out))
|
if ((var == NULL) || (var->mode != ir_var_out))
|
||||||
@@ -752,7 +752,7 @@ assign_varying_locations(glsl_shader *producer, glsl_shader *consumer)
|
|||||||
var->shader_out = (var->location != -1);
|
var->shader_out = (var->location != -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach_list(node, &consumer->ir) {
|
foreach_list(node, consumer->ir) {
|
||||||
ir_variable *const var = ((ir_instruction *) node)->as_variable();
|
ir_variable *const var = ((ir_instruction *) node)->as_variable();
|
||||||
|
|
||||||
if ((var == NULL) || (var->mode != ir_var_in))
|
if ((var == NULL) || (var->mode != ir_var_in))
|
||||||
@@ -780,13 +780,13 @@ link_shaders(struct glsl_program *prog)
|
|||||||
|
|
||||||
/* Separate the shaders into groups based on their type.
|
/* Separate the shaders into groups based on their type.
|
||||||
*/
|
*/
|
||||||
struct glsl_shader **vert_shader_list;
|
struct gl_shader **vert_shader_list;
|
||||||
unsigned num_vert_shaders = 0;
|
unsigned num_vert_shaders = 0;
|
||||||
struct glsl_shader **frag_shader_list;
|
struct gl_shader **frag_shader_list;
|
||||||
unsigned num_frag_shaders = 0;
|
unsigned num_frag_shaders = 0;
|
||||||
|
|
||||||
vert_shader_list = (struct glsl_shader **)
|
vert_shader_list = (struct gl_shader **)
|
||||||
calloc(2 * prog->NumShaders, sizeof(struct glsl_shader *));
|
calloc(2 * prog->NumShaders, sizeof(struct gl_shader *));
|
||||||
frag_shader_list = &vert_shader_list[prog->NumShaders];
|
frag_shader_list = &vert_shader_list[prog->NumShaders];
|
||||||
|
|
||||||
for (unsigned i = 0; i < prog->NumShaders; i++) {
|
for (unsigned i = 0; i < prog->NumShaders; i++) {
|
||||||
@@ -817,8 +817,8 @@ link_shaders(struct glsl_program *prog)
|
|||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
|
|
||||||
prog->_LinkedShaders = (struct glsl_shader **)
|
prog->_LinkedShaders = (struct gl_shader **)
|
||||||
calloc(2, sizeof(struct glsl_shader *));
|
calloc(2, sizeof(struct gl_shader *));
|
||||||
prog->_NumLinkedShaders = 0;
|
prog->_NumLinkedShaders = 0;
|
||||||
|
|
||||||
if (num_vert_shaders > 0) {
|
if (num_vert_shaders > 0) {
|
||||||
|
@@ -272,6 +272,25 @@ struct exec_list {
|
|||||||
struct exec_node *tail_pred;
|
struct exec_node *tail_pred;
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
/* Callers of this talloc-based new need not call delete. It's
|
||||||
|
* easier to just talloc_free 'ctx' (or any of its ancestors). */
|
||||||
|
static void* operator new(size_t size, void *ctx)
|
||||||
|
{
|
||||||
|
void *node;
|
||||||
|
|
||||||
|
node = talloc_size(ctx, size);
|
||||||
|
assert(node != NULL);
|
||||||
|
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If the user *does* call delete, that's OK, we will just
|
||||||
|
* talloc_free in that case. */
|
||||||
|
static void operator delete(void *node)
|
||||||
|
{
|
||||||
|
talloc_free(node);
|
||||||
|
}
|
||||||
|
|
||||||
exec_list()
|
exec_list()
|
||||||
{
|
{
|
||||||
make_empty();
|
make_empty();
|
||||||
|
@@ -38,14 +38,13 @@
|
|||||||
|
|
||||||
/* Returned string will have 'ctx' as its talloc owner. */
|
/* Returned string will have 'ctx' as its talloc owner. */
|
||||||
static char *
|
static char *
|
||||||
load_text_file(void *ctx, const char *file_name, size_t *size)
|
load_text_file(void *ctx, const char *file_name)
|
||||||
{
|
{
|
||||||
char *text = NULL;
|
char *text = NULL;
|
||||||
struct stat st;
|
struct stat st;
|
||||||
ssize_t total_read = 0;
|
ssize_t total_read = 0;
|
||||||
int fd = open(file_name, O_RDONLY);
|
int fd = open(file_name, O_RDONLY);
|
||||||
|
|
||||||
*size = 0;
|
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -70,7 +69,6 @@ load_text_file(void *ctx, const char *file_name, size_t *size)
|
|||||||
} while (total_read < st.st_size);
|
} while (total_read < st.st_size);
|
||||||
|
|
||||||
text[total_read] = '\0';
|
text[total_read] = '\0';
|
||||||
*size = total_read;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -102,7 +100,7 @@ const struct option compiler_opts[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
void
|
void
|
||||||
compile_shader(struct glsl_shader *shader)
|
compile_shader(struct gl_shader *shader)
|
||||||
{
|
{
|
||||||
struct _mesa_glsl_parse_state *state;
|
struct _mesa_glsl_parse_state *state;
|
||||||
|
|
||||||
@@ -145,40 +143,40 @@ compile_shader(struct glsl_shader *shader)
|
|||||||
printf("\n\n");
|
printf("\n\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
shader->ir.make_empty();
|
shader->ir = new(shader) exec_list;
|
||||||
if (!state->error && !state->translation_unit.is_empty())
|
if (!state->error && !state->translation_unit.is_empty())
|
||||||
_mesa_ast_to_hir(&shader->ir, state);
|
_mesa_ast_to_hir(shader->ir, state);
|
||||||
|
|
||||||
validate_ir_tree(&shader->ir);
|
validate_ir_tree(shader->ir);
|
||||||
|
|
||||||
/* Print out the unoptimized IR. */
|
/* Print out the unoptimized IR. */
|
||||||
if (!state->error && dump_hir) {
|
if (!state->error && dump_hir) {
|
||||||
_mesa_print_ir(&shader->ir, state);
|
_mesa_print_ir(shader->ir, state);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Optimization passes */
|
/* Optimization passes */
|
||||||
if (!state->error && !shader->ir.is_empty()) {
|
if (!state->error && !shader->ir->is_empty()) {
|
||||||
bool progress;
|
bool progress;
|
||||||
do {
|
do {
|
||||||
progress = false;
|
progress = false;
|
||||||
|
|
||||||
progress = do_function_inlining(&shader->ir) || progress;
|
progress = do_function_inlining(shader->ir) || progress;
|
||||||
progress = do_if_simplification(&shader->ir) || progress;
|
progress = do_if_simplification(shader->ir) || progress;
|
||||||
progress = do_copy_propagation(&shader->ir) || progress;
|
progress = do_copy_propagation(shader->ir) || progress;
|
||||||
progress = do_dead_code_local(&shader->ir) || progress;
|
progress = do_dead_code_local(shader->ir) || progress;
|
||||||
progress = do_dead_code_unlinked(state, &shader->ir) || progress;
|
progress = do_dead_code_unlinked(state, shader->ir) || progress;
|
||||||
progress = do_constant_variable_unlinked(&shader->ir) || progress;
|
progress = do_constant_variable_unlinked(shader->ir) || progress;
|
||||||
progress = do_constant_folding(&shader->ir) || progress;
|
progress = do_constant_folding(shader->ir) || progress;
|
||||||
progress = do_vec_index_to_swizzle(&shader->ir) || progress;
|
progress = do_vec_index_to_swizzle(shader->ir) || progress;
|
||||||
progress = do_swizzle_swizzle(&shader->ir) || progress;
|
progress = do_swizzle_swizzle(shader->ir) || progress;
|
||||||
} while (progress);
|
} while (progress);
|
||||||
}
|
}
|
||||||
|
|
||||||
validate_ir_tree(&shader->ir);
|
validate_ir_tree(shader->ir);
|
||||||
|
|
||||||
/* Print out the resulting IR */
|
/* Print out the resulting IR */
|
||||||
if (!state->error && dump_lir) {
|
if (!state->error && dump_lir) {
|
||||||
_mesa_print_ir(&shader->ir, state);
|
_mesa_print_ir(shader->ir, state);
|
||||||
}
|
}
|
||||||
|
|
||||||
shader->symbols = state->symbols;
|
shader->symbols = state->symbols;
|
||||||
@@ -214,12 +212,12 @@ main(int argc, char **argv)
|
|||||||
assert(whole_program != NULL);
|
assert(whole_program != NULL);
|
||||||
|
|
||||||
for (/* empty */; argc > optind; optind++) {
|
for (/* empty */; argc > optind; optind++) {
|
||||||
whole_program->Shaders = (struct glsl_shader **)
|
whole_program->Shaders = (struct gl_shader **)
|
||||||
talloc_realloc(whole_program, whole_program->Shaders,
|
talloc_realloc(whole_program, whole_program->Shaders,
|
||||||
struct glsl_shader *, whole_program->NumShaders + 1);
|
struct gl_shader *, whole_program->NumShaders + 1);
|
||||||
assert(whole_program->Shaders != NULL);
|
assert(whole_program->Shaders != NULL);
|
||||||
|
|
||||||
struct glsl_shader *shader = talloc_zero(whole_program, glsl_shader);
|
struct gl_shader *shader = talloc_zero(whole_program, gl_shader);
|
||||||
|
|
||||||
whole_program->Shaders[whole_program->NumShaders] = shader;
|
whole_program->Shaders[whole_program->NumShaders] = shader;
|
||||||
whole_program->NumShaders++;
|
whole_program->NumShaders++;
|
||||||
@@ -238,8 +236,7 @@ main(int argc, char **argv)
|
|||||||
else
|
else
|
||||||
usage_fail(argv[0]);
|
usage_fail(argv[0]);
|
||||||
|
|
||||||
shader->Source = load_text_file(whole_program,
|
shader->Source = load_text_file(whole_program, argv[optind]);
|
||||||
argv[optind], &shader->SourceLen);
|
|
||||||
if (shader->Source == NULL) {
|
if (shader->Source == NULL) {
|
||||||
printf("File \"%s\" does not exist.\n", argv[optind]);
|
printf("File \"%s\" does not exist.\n", argv[optind]);
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
|
@@ -29,24 +29,6 @@ extern "C" {
|
|||||||
#include "shader/prog_uniform.h"
|
#include "shader/prog_uniform.h"
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Based on gl_shader in Mesa's mtypes.h.
|
|
||||||
*/
|
|
||||||
struct glsl_shader {
|
|
||||||
GLenum Type;
|
|
||||||
GLuint Name;
|
|
||||||
GLint RefCount;
|
|
||||||
GLboolean DeletePending;
|
|
||||||
GLboolean CompileStatus;
|
|
||||||
const GLchar *Source; /**< Source code string */
|
|
||||||
size_t SourceLen;
|
|
||||||
GLchar *InfoLog;
|
|
||||||
|
|
||||||
struct exec_list ir;
|
|
||||||
struct glsl_symbol_table *symbols;
|
|
||||||
struct gl_shader *mesa_shader;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Based on gl_shader_program in Mesa's mtypes.h.
|
* Based on gl_shader_program in Mesa's mtypes.h.
|
||||||
*/
|
*/
|
||||||
@@ -57,14 +39,14 @@ struct glsl_program {
|
|||||||
GLboolean DeletePending;
|
GLboolean DeletePending;
|
||||||
|
|
||||||
GLuint NumShaders; /**< number of attached shaders */
|
GLuint NumShaders; /**< number of attached shaders */
|
||||||
struct glsl_shader **Shaders; /**< List of attached the shaders */
|
struct gl_shader **Shaders; /**< List of attached the shaders */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Per-stage shaders resulting from the first stage of linking.
|
* Per-stage shaders resulting from the first stage of linking.
|
||||||
*/
|
*/
|
||||||
/*@{*/
|
/*@{*/
|
||||||
unsigned _NumLinkedShaders;
|
unsigned _NumLinkedShaders;
|
||||||
struct glsl_shader **_LinkedShaders;
|
struct gl_shader **_LinkedShaders;
|
||||||
/*@}*/
|
/*@}*/
|
||||||
|
|
||||||
/** User-defined attribute bindings (glBindAttribLocation) */
|
/** User-defined attribute bindings (glBindAttribLocation) */
|
||||||
|
@@ -1966,6 +1966,9 @@ struct gl_shader
|
|||||||
struct gl_program *Program; /**< Post-compile assembly code */
|
struct gl_program *Program; /**< Post-compile assembly code */
|
||||||
GLchar *InfoLog;
|
GLchar *InfoLog;
|
||||||
struct gl_sl_pragmas Pragmas;
|
struct gl_sl_pragmas Pragmas;
|
||||||
|
|
||||||
|
struct exec_list *ir;
|
||||||
|
struct glsl_symbol_table *symbols;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@@ -1561,13 +1561,12 @@ link_uniforms_to_shared_uniform_list(struct gl_uniform_list *uniforms,
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct gl_program *
|
struct gl_program *
|
||||||
get_mesa_program(GLcontext *ctx, void *mem_ctx, struct glsl_shader *shader)
|
get_mesa_program(GLcontext *ctx, void *mem_ctx, struct gl_shader *shader)
|
||||||
{
|
{
|
||||||
ir_to_mesa_visitor v;
|
ir_to_mesa_visitor v;
|
||||||
struct prog_instruction *mesa_instructions, *mesa_inst;
|
struct prog_instruction *mesa_instructions, *mesa_inst;
|
||||||
ir_instruction **mesa_instruction_annotation;
|
ir_instruction **mesa_instruction_annotation;
|
||||||
int i;
|
int i;
|
||||||
exec_list *instructions = &shader->ir;
|
|
||||||
struct gl_program *prog;
|
struct gl_program *prog;
|
||||||
GLenum target;
|
GLenum target;
|
||||||
|
|
||||||
@@ -1587,7 +1586,7 @@ get_mesa_program(GLcontext *ctx, void *mem_ctx, struct glsl_shader *shader)
|
|||||||
v.prog = prog;
|
v.prog = prog;
|
||||||
|
|
||||||
v.mem_ctx = talloc_new(NULL);
|
v.mem_ctx = talloc_new(NULL);
|
||||||
visit_exec_list(instructions, &v);
|
visit_exec_list(shader->ir, &v);
|
||||||
v.ir_to_mesa_emit_op1(NULL, OPCODE_END,
|
v.ir_to_mesa_emit_op1(NULL, OPCODE_END,
|
||||||
ir_to_mesa_undef_dst, ir_to_mesa_undef);
|
ir_to_mesa_undef_dst, ir_to_mesa_undef);
|
||||||
|
|
||||||
@@ -1635,26 +1634,17 @@ get_mesa_program(GLcontext *ctx, void *mem_ctx, struct glsl_shader *shader)
|
|||||||
prog->Instructions = mesa_instructions;
|
prog->Instructions = mesa_instructions;
|
||||||
prog->NumInstructions = num_instructions;
|
prog->NumInstructions = num_instructions;
|
||||||
|
|
||||||
_mesa_reference_program(ctx, &shader->mesa_shader->Program, prog);
|
_mesa_reference_program(ctx, &shader->Program, prog);
|
||||||
|
|
||||||
return prog;
|
return prog;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Takes a Mesa gl shader structure and compiles it, returning our Mesa-like
|
extern "C" {
|
||||||
* structure with the IR and such attached.
|
|
||||||
*/
|
|
||||||
static struct glsl_shader *
|
|
||||||
_mesa_get_glsl_shader(GLcontext *ctx, void *mem_ctx, struct gl_shader *sh)
|
|
||||||
{
|
|
||||||
struct glsl_shader *shader = talloc_zero(mem_ctx, struct glsl_shader);
|
|
||||||
struct _mesa_glsl_parse_state *state;
|
|
||||||
|
|
||||||
shader->Type = sh->Type;
|
void
|
||||||
shader->Name = sh->Name;
|
_mesa_glsl_compile_shader(GLcontext *ctx, struct gl_shader *shader)
|
||||||
shader->RefCount = 1;
|
{
|
||||||
shader->Source = sh->Source;
|
struct _mesa_glsl_parse_state *state;
|
||||||
shader->SourceLen = strlen(sh->Source);
|
|
||||||
shader->mesa_shader = sh;
|
|
||||||
|
|
||||||
state = talloc_zero(shader, struct _mesa_glsl_parse_state);
|
state = talloc_zero(shader, struct _mesa_glsl_parse_state);
|
||||||
switch (shader->Type) {
|
switch (shader->Type) {
|
||||||
@@ -1665,7 +1655,7 @@ _mesa_get_glsl_shader(GLcontext *ctx, void *mem_ctx, struct gl_shader *sh)
|
|||||||
|
|
||||||
state->scanner = NULL;
|
state->scanner = NULL;
|
||||||
state->translation_unit.make_empty();
|
state->translation_unit.make_empty();
|
||||||
state->symbols = new(mem_ctx) glsl_symbol_table;
|
state->symbols = new(shader) glsl_symbol_table;
|
||||||
state->info_log = talloc_strdup(shader, "");
|
state->info_log = talloc_strdup(shader, "");
|
||||||
state->error = false;
|
state->error = false;
|
||||||
state->temp_index = 0;
|
state->temp_index = 0;
|
||||||
@@ -1686,25 +1676,25 @@ _mesa_get_glsl_shader(GLcontext *ctx, void *mem_ctx, struct gl_shader *sh)
|
|||||||
_mesa_glsl_lexer_dtor(state);
|
_mesa_glsl_lexer_dtor(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
shader->ir.make_empty();
|
shader->ir = new(shader) exec_list;
|
||||||
if (!state->error && !state->translation_unit.is_empty())
|
if (!state->error && !state->translation_unit.is_empty())
|
||||||
_mesa_ast_to_hir(&shader->ir, state);
|
_mesa_ast_to_hir(shader->ir, state);
|
||||||
|
|
||||||
/* Optimization passes */
|
/* Optimization passes */
|
||||||
if (!state->error && !shader->ir.is_empty()) {
|
if (!state->error && !shader->ir->is_empty()) {
|
||||||
bool progress;
|
bool progress;
|
||||||
do {
|
do {
|
||||||
progress = false;
|
progress = false;
|
||||||
|
|
||||||
progress = do_function_inlining(&shader->ir) || progress;
|
progress = do_function_inlining(shader->ir) || progress;
|
||||||
progress = do_if_simplification(&shader->ir) || progress;
|
progress = do_if_simplification(shader->ir) || progress;
|
||||||
progress = do_copy_propagation(&shader->ir) || progress;
|
progress = do_copy_propagation(shader->ir) || progress;
|
||||||
progress = do_dead_code_local(&shader->ir) || progress;
|
progress = do_dead_code_local(shader->ir) || progress;
|
||||||
progress = do_dead_code_unlinked(state, &shader->ir) || progress;
|
progress = do_dead_code_unlinked(state, shader->ir) || progress;
|
||||||
progress = do_constant_variable_unlinked(&shader->ir) || progress;
|
progress = do_constant_variable_unlinked(shader->ir) || progress;
|
||||||
progress = do_constant_folding(&shader->ir) || progress;
|
progress = do_constant_folding(shader->ir) || progress;
|
||||||
progress = do_vec_index_to_swizzle(&shader->ir) || progress;
|
progress = do_vec_index_to_swizzle(shader->ir) || progress;
|
||||||
progress = do_swizzle_swizzle(&shader->ir) || progress;
|
progress = do_swizzle_swizzle(shader->ir) || progress;
|
||||||
} while (progress);
|
} while (progress);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1714,23 +1704,6 @@ _mesa_get_glsl_shader(GLcontext *ctx, void *mem_ctx, struct gl_shader *sh)
|
|||||||
shader->InfoLog = state->info_log;
|
shader->InfoLog = state->info_log;
|
||||||
|
|
||||||
talloc_free(state);
|
talloc_free(state);
|
||||||
|
|
||||||
return shader;
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" {
|
|
||||||
|
|
||||||
void
|
|
||||||
_mesa_glsl_compile_shader(GLcontext *ctx, struct gl_shader *sh)
|
|
||||||
{
|
|
||||||
struct glsl_shader *shader;
|
|
||||||
TALLOC_CTX *mem_ctx = talloc_new(NULL);
|
|
||||||
|
|
||||||
shader = _mesa_get_glsl_shader(ctx, mem_ctx, sh);
|
|
||||||
|
|
||||||
sh->CompileStatus = shader->CompileStatus;
|
|
||||||
sh->InfoLog = strdup(shader->InfoLog);
|
|
||||||
talloc_free(mem_ctx);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -1738,18 +1711,16 @@ _mesa_glsl_link_shader(GLcontext *ctx, struct gl_shader_program *prog)
|
|||||||
{
|
{
|
||||||
struct glsl_program *whole_program;
|
struct glsl_program *whole_program;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
_mesa_clear_shader_program_data(ctx, prog);
|
_mesa_clear_shader_program_data(ctx, prog);
|
||||||
|
|
||||||
whole_program = talloc_zero(NULL, struct glsl_program);
|
whole_program = talloc_zero(NULL, struct glsl_program);
|
||||||
whole_program->LinkStatus = GL_TRUE;
|
whole_program->LinkStatus = GL_TRUE;
|
||||||
whole_program->NumShaders = prog->NumShaders;
|
whole_program->NumShaders = prog->NumShaders;
|
||||||
whole_program->Shaders = talloc_array(whole_program, struct glsl_shader *,
|
whole_program->Shaders = talloc_array(whole_program, struct gl_shader *,
|
||||||
prog->NumShaders);
|
prog->NumShaders);
|
||||||
|
|
||||||
for (i = 0; i < prog->NumShaders; i++) {
|
for (i = 0; i < prog->NumShaders; i++) {
|
||||||
whole_program->Shaders[i] = _mesa_get_glsl_shader(ctx, whole_program,
|
whole_program->Shaders[i] = prog->Shaders[i];
|
||||||
prog->Shaders[i]);
|
|
||||||
if (!whole_program->Shaders[i]->CompileStatus) {
|
if (!whole_program->Shaders[i]->CompileStatus) {
|
||||||
whole_program->InfoLog =
|
whole_program->InfoLog =
|
||||||
talloc_asprintf_append(whole_program->InfoLog,
|
talloc_asprintf_append(whole_program->InfoLog,
|
||||||
|
@@ -44,7 +44,7 @@
|
|||||||
#include "shader/prog_uniform.h"
|
#include "shader/prog_uniform.h"
|
||||||
#include "shader/shader_api.h"
|
#include "shader/shader_api.h"
|
||||||
#include "shader/uniforms.h"
|
#include "shader/uniforms.h"
|
||||||
|
#include "talloc.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allocate a new gl_shader_program object, initialize it.
|
* Allocate a new gl_shader_program object, initialize it.
|
||||||
@@ -253,7 +253,7 @@ _mesa_new_shader(GLcontext *ctx, GLuint name, GLenum type)
|
|||||||
{
|
{
|
||||||
struct gl_shader *shader;
|
struct gl_shader *shader;
|
||||||
assert(type == GL_FRAGMENT_SHADER || type == GL_VERTEX_SHADER);
|
assert(type == GL_FRAGMENT_SHADER || type == GL_VERTEX_SHADER);
|
||||||
shader = CALLOC_STRUCT(gl_shader);
|
shader = talloc_zero(NULL, struct gl_shader);
|
||||||
if (shader) {
|
if (shader) {
|
||||||
shader->Type = type;
|
shader->Type = type;
|
||||||
shader->Name = name;
|
shader->Name = name;
|
||||||
@@ -268,10 +268,8 @@ _mesa_free_shader(GLcontext *ctx, struct gl_shader *sh)
|
|||||||
{
|
{
|
||||||
if (sh->Source)
|
if (sh->Source)
|
||||||
free((void *) sh->Source);
|
free((void *) sh->Source);
|
||||||
if (sh->InfoLog)
|
|
||||||
free(sh->InfoLog);
|
|
||||||
_mesa_reference_program(ctx, &sh->Program, NULL);
|
_mesa_reference_program(ctx, &sh->Program, NULL);
|
||||||
free(sh);
|
talloc_free(sh);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user