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)
{
- foreach_list(node, &sh->ir) {
+ foreach_list(node, sh->ir) {
ir_variable *const var = ((ir_instruction *) node)->as_variable();
if ((var == NULL) || (var->mode != (unsigned) mode))
*/
bool
validate_vertex_shader_executable(struct glsl_program *prog,
- struct glsl_shader *shader)
+ struct gl_shader *shader)
{
if (shader == NULL)
return true;
}
find_assignment_visitor find("gl_Position");
- find.run(&shader->ir);
+ find.run(shader->ir);
if (!find.variable_found()) {
linker_error_printf(prog,
"vertex shader does not write to `gl_Position'\n");
*/
bool
validate_fragment_shader_executable(struct glsl_program *prog,
- struct glsl_shader *shader)
+ struct gl_shader *shader)
{
if (shader == NULL)
return true;
find_assignment_visitor frag_color("gl_FragColor");
find_assignment_visitor frag_data("gl_FragData");
- frag_color.run(&shader->ir);
- frag_data.run(&shader->ir);
+ frag_color.run(shader->ir);
+ frag_data.run(shader->ir);
if (!frag_color.variable_found() && !frag_data.variable_found()) {
linker_error_printf(prog, "fragment shader does not write to "
*/
glsl_symbol_table uniforms;
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();
if ((var == NULL) || (var->mode != ir_var_uniform))
*/
bool
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;
/* FINISHME: Figure these out dynamically. */
/* 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();
/* FINISHME: For geometry shaders, this should also look for inout
* matching outputs already in the symbol table must have the same type and
* qualifiers.
*/
- foreach_list(node, &consumer->ir) {
+ foreach_list(node, consumer->ir) {
ir_variable *const input = ((ir_instruction *) node)->as_variable();
/* FINISHME: For geometry shaders, this should also look for inout
for (unsigned i = 0; i < prog->_NumLinkedShaders; i++) {
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();
if ((var == NULL) || (var->mode != ir_var_uniform))
unsigned used_locations = (max_attribute_index >= 32)
? ~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);
/* Operate in a total of four passes.
unsigned num_attr = 0;
- foreach_list(node, &sh->ir) {
+ foreach_list(node, sh->ir) {
ir_variable *const var = ((ir_instruction *) node)->as_variable();
if ((var == NULL) || (var->mode != ir_var_in))
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. */
unsigned output_index = VERT_RESULT_VAR0;
invalidate_variable_locations(producer, ir_var_out, VERT_RESULT_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();
if ((output_var == NULL) || (output_var->mode != ir_var_out)
input_index++;
}
- foreach_list(node, &producer->ir) {
+ foreach_list(node, producer->ir) {
ir_variable *const var = ((ir_instruction *) node)->as_variable();
if ((var == NULL) || (var->mode != ir_var_out))
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();
if ((var == NULL) || (var->mode != ir_var_in))
/* 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;
- struct glsl_shader **frag_shader_list;
+ struct gl_shader **frag_shader_list;
unsigned num_frag_shaders = 0;
- vert_shader_list = (struct glsl_shader **)
- calloc(2 * prog->NumShaders, sizeof(struct glsl_shader *));
+ vert_shader_list = (struct gl_shader **)
+ calloc(2 * prog->NumShaders, sizeof(struct gl_shader *));
frag_shader_list = &vert_shader_list[prog->NumShaders];
for (unsigned i = 0; i < prog->NumShaders; i++) {
goto done;
- prog->_LinkedShaders = (struct glsl_shader **)
- calloc(2, sizeof(struct glsl_shader *));
+ prog->_LinkedShaders = (struct gl_shader **)
+ calloc(2, sizeof(struct gl_shader *));
prog->_NumLinkedShaders = 0;
if (num_vert_shaders > 0) {
struct exec_node *tail_pred;
#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()
{
make_empty();
/* Returned string will have 'ctx' as its talloc owner. */
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;
struct stat st;
ssize_t total_read = 0;
int fd = open(file_name, O_RDONLY);
- *size = 0;
if (fd < 0) {
return NULL;
}
} while (total_read < st.st_size);
text[total_read] = '\0';
- *size = total_read;
}
}
};
void
-compile_shader(struct glsl_shader *shader)
+compile_shader(struct gl_shader *shader)
{
struct _mesa_glsl_parse_state *state;
printf("\n\n");
}
- shader->ir.make_empty();
+ shader->ir = new(shader) exec_list;
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. */
if (!state->error && dump_hir) {
- _mesa_print_ir(&shader->ir, state);
+ _mesa_print_ir(shader->ir, state);
}
/* Optimization passes */
- if (!state->error && !shader->ir.is_empty()) {
+ if (!state->error && !shader->ir->is_empty()) {
bool progress;
do {
progress = false;
- progress = do_function_inlining(&shader->ir) || progress;
- progress = do_if_simplification(&shader->ir) || progress;
- progress = do_copy_propagation(&shader->ir) || progress;
- progress = do_dead_code_local(&shader->ir) || progress;
- progress = do_dead_code_unlinked(state, &shader->ir) || progress;
- progress = do_constant_variable_unlinked(&shader->ir) || progress;
- progress = do_constant_folding(&shader->ir) || progress;
- progress = do_vec_index_to_swizzle(&shader->ir) || progress;
- progress = do_swizzle_swizzle(&shader->ir) || progress;
+ progress = do_function_inlining(shader->ir) || progress;
+ progress = do_if_simplification(shader->ir) || progress;
+ progress = do_copy_propagation(shader->ir) || progress;
+ progress = do_dead_code_local(shader->ir) || progress;
+ progress = do_dead_code_unlinked(state, shader->ir) || progress;
+ progress = do_constant_variable_unlinked(shader->ir) || progress;
+ progress = do_constant_folding(shader->ir) || progress;
+ progress = do_vec_index_to_swizzle(shader->ir) || progress;
+ progress = do_swizzle_swizzle(shader->ir) || progress;
} while (progress);
}
- validate_ir_tree(&shader->ir);
+ validate_ir_tree(shader->ir);
/* Print out the resulting IR */
if (!state->error && dump_lir) {
- _mesa_print_ir(&shader->ir, state);
+ _mesa_print_ir(shader->ir, state);
}
shader->symbols = state->symbols;
assert(whole_program != NULL);
for (/* empty */; argc > optind; optind++) {
- whole_program->Shaders = (struct glsl_shader **)
+ whole_program->Shaders = (struct gl_shader **)
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);
- 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->NumShaders++;
else
usage_fail(argv[0]);
- shader->Source = load_text_file(whole_program,
- argv[optind], &shader->SourceLen);
+ shader->Source = load_text_file(whole_program, argv[optind]);
if (shader->Source == NULL) {
printf("File \"%s\" does not exist.\n", argv[optind]);
exit(EXIT_FAILURE);
#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.
*/
GLboolean DeletePending;
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.
*/
/*@{*/
unsigned _NumLinkedShaders;
- struct glsl_shader **_LinkedShaders;
+ struct gl_shader **_LinkedShaders;
/*@}*/
/** User-defined attribute bindings (glBindAttribLocation) */
struct gl_program *Program; /**< Post-compile assembly code */
GLchar *InfoLog;
struct gl_sl_pragmas Pragmas;
+
+ struct exec_list *ir;
+ struct glsl_symbol_table *symbols;
};
}
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;
struct prog_instruction *mesa_instructions, *mesa_inst;
ir_instruction **mesa_instruction_annotation;
int i;
- exec_list *instructions = &shader->ir;
struct gl_program *prog;
GLenum target;
v.prog = prog;
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,
ir_to_mesa_undef_dst, ir_to_mesa_undef);
prog->Instructions = mesa_instructions;
prog->NumInstructions = num_instructions;
- _mesa_reference_program(ctx, &shader->mesa_shader->Program, prog);
+ _mesa_reference_program(ctx, &shader->Program, prog);
return prog;
}
-/* Takes a Mesa gl shader structure and compiles it, returning our Mesa-like
- * structure with the IR and such attached.
- */
-static struct glsl_shader *
-_mesa_get_glsl_shader(GLcontext *ctx, void *mem_ctx, struct gl_shader *sh)
+extern "C" {
+
+void
+_mesa_glsl_compile_shader(GLcontext *ctx, struct gl_shader *shader)
{
- struct glsl_shader *shader = talloc_zero(mem_ctx, struct glsl_shader);
struct _mesa_glsl_parse_state *state;
- shader->Type = sh->Type;
- shader->Name = sh->Name;
- shader->RefCount = 1;
- shader->Source = sh->Source;
- shader->SourceLen = strlen(sh->Source);
- shader->mesa_shader = sh;
-
state = talloc_zero(shader, struct _mesa_glsl_parse_state);
switch (shader->Type) {
case GL_VERTEX_SHADER: state->target = vertex_shader; break;
state->scanner = NULL;
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->error = false;
state->temp_index = 0;
_mesa_glsl_lexer_dtor(state);
}
- shader->ir.make_empty();
+ shader->ir = new(shader) exec_list;
if (!state->error && !state->translation_unit.is_empty())
- _mesa_ast_to_hir(&shader->ir, state);
+ _mesa_ast_to_hir(shader->ir, state);
/* Optimization passes */
- if (!state->error && !shader->ir.is_empty()) {
+ if (!state->error && !shader->ir->is_empty()) {
bool progress;
do {
progress = false;
- progress = do_function_inlining(&shader->ir) || progress;
- progress = do_if_simplification(&shader->ir) || progress;
- progress = do_copy_propagation(&shader->ir) || progress;
- progress = do_dead_code_local(&shader->ir) || progress;
- progress = do_dead_code_unlinked(state, &shader->ir) || progress;
- progress = do_constant_variable_unlinked(&shader->ir) || progress;
- progress = do_constant_folding(&shader->ir) || progress;
- progress = do_vec_index_to_swizzle(&shader->ir) || progress;
- progress = do_swizzle_swizzle(&shader->ir) || progress;
+ progress = do_function_inlining(shader->ir) || progress;
+ progress = do_if_simplification(shader->ir) || progress;
+ progress = do_copy_propagation(shader->ir) || progress;
+ progress = do_dead_code_local(shader->ir) || progress;
+ progress = do_dead_code_unlinked(state, shader->ir) || progress;
+ progress = do_constant_variable_unlinked(shader->ir) || progress;
+ progress = do_constant_folding(shader->ir) || progress;
+ progress = do_vec_index_to_swizzle(shader->ir) || progress;
+ progress = do_swizzle_swizzle(shader->ir) || progress;
} while (progress);
}
shader->InfoLog = state->info_log;
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
{
struct glsl_program *whole_program;
unsigned int i;
-
_mesa_clear_shader_program_data(ctx, prog);
whole_program = talloc_zero(NULL, struct glsl_program);
whole_program->LinkStatus = GL_TRUE;
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);
for (i = 0; i < prog->NumShaders; i++) {
- whole_program->Shaders[i] = _mesa_get_glsl_shader(ctx, whole_program,
- prog->Shaders[i]);
+ whole_program->Shaders[i] = prog->Shaders[i];
if (!whole_program->Shaders[i]->CompileStatus) {
whole_program->InfoLog =
talloc_asprintf_append(whole_program->InfoLog,
#include "shader/prog_uniform.h"
#include "shader/shader_api.h"
#include "shader/uniforms.h"
-
+#include "talloc.h"
/**
* Allocate a new gl_shader_program object, initialize it.
{
struct gl_shader *shader;
assert(type == GL_FRAGMENT_SHADER || type == GL_VERTEX_SHADER);
- shader = CALLOC_STRUCT(gl_shader);
+ shader = talloc_zero(NULL, struct gl_shader);
if (shader) {
shader->Type = type;
shader->Name = name;
{
if (sh->Source)
free((void *) sh->Source);
- if (sh->InfoLog)
- free(sh->InfoLog);
_mesa_reference_program(ctx, &sh->Program, NULL);
- free(sh);
+ talloc_free(sh);
}