#include "main/compiler.h"
#include "ir.h"
#include "ir_visitor.h"
-#include "ir_print_visitor.h"
#include "ir_expression_flattening.h"
#include "ir_uniform.h"
#include "glsl_types.h"
#include "main/mtypes.h"
#include "main/shaderobj.h"
+#include "main/uniforms.h"
#include "program/hash_table.h"
extern "C" {
#include "main/shaderapi.h"
-#include "main/uniforms.h"
#include "program/prog_instruction.h"
#include "program/prog_optimize.h"
#include "program/prog_print.h"
#include "program/sampler.h"
}
+static int swizzle_for_size(int size);
+
+namespace {
+
class src_reg;
class dst_reg;
-static int swizzle_for_size(int size);
-
/**
* This struct is a corresponding struct to Mesa prog_src_register, with
* wider fields.
src_reg *reladdr;
};
+} /* anonymous namespace */
+
src_reg::src_reg(dst_reg reg)
{
this->file = reg.file;
this->reladdr = reg.reladdr;
}
+namespace {
+
class ir_to_mesa_instruction : public exec_node {
public:
- /* Callers of this ralloc-based new need not call delete. It's
- * easier to just ralloc_free 'ctx' (or any of its ancestors). */
- static void* operator new(size_t size, void *ctx)
- {
- void *node;
-
- node = rzalloc_size(ctx, size);
- assert(node != NULL);
-
- return node;
- }
+ DECLARE_RALLOC_CXX_OPERATORS(ir_to_mesa_instruction)
enum prog_opcode op;
dst_reg dst;
virtual void visit(ir_discard *);
virtual void visit(ir_texture *);
virtual void visit(ir_if *);
+ virtual void visit(ir_emit_vertex *);
+ virtual void visit(ir_end_primitive *);
/*@}*/
src_reg result;
void *mem_ctx;
};
+} /* anonymous namespace */
+
static src_reg undef_src = src_reg(PROGRAM_UNDEFINED, 0, NULL);
static dst_reg undef_dst = dst_reg(PROGRAM_UNDEFINED, SWIZZLE_NOOP);
* at link time.
*/
return 1;
+ case GLSL_TYPE_ATOMIC_UINT:
case GLSL_TYPE_VOID:
case GLSL_TYPE_ERROR:
case GLSL_TYPE_INTERFACE:
const ir_function_signature *sig;
exec_list empty;
- sig = ir->matching_signature(&empty);
+ sig = ir->matching_signature(NULL, &empty);
assert(sig);
this->result.file = PROGRAM_UNDEFINED;
deref->accept(this);
if (this->result.file == PROGRAM_UNDEFINED) {
- ir_print_visitor v;
printf("Failed to get tree for expression operand:\n");
- deref->accept(&v);
+ deref->print();
+ printf("\n");
exit(1);
}
this->result.file = PROGRAM_UNDEFINED;
ir->operands[operand]->accept(this);
if (this->result.file == PROGRAM_UNDEFINED) {
- ir_print_visitor v;
printf("Failed to get tree for expression operand:\n");
- ir->operands[operand]->accept(&v);
+ ir->operands[operand]->print();
+ printf("\n");
exit(1);
}
op[operand] = this->result;
case ir_binop_vector_extract:
case ir_binop_bfm:
+ case ir_triop_fma:
case ir_triop_bfi:
case ir_triop_bitfield_extract:
case ir_triop_vector_insert:
case ir_quadop_bitfield_insert:
+ case ir_binop_ldexp:
+ case ir_triop_csel:
+ case ir_binop_carry:
+ case ir_binop_borrow:
+ case ir_binop_imul_high:
assert(!"not supported");
break;
case ir_lod:
assert(!"Unexpected ir_lod opcode");
break;
+ case ir_tg4:
+ assert(!"Unexpected ir_tg4 opcode");
+ break;
+ case ir_query_levels:
+ assert(!"Unexpected ir_query_levels opcode");
+ break;
}
const glsl_type *sampler_type = ir->sampler->type;
visit_exec_list(&ir->else_instructions, this);
}
- if_inst = emit(ir->condition, OPCODE_ENDIF);
+ emit(ir->condition, OPCODE_ENDIF);
+}
+
+void
+ir_to_mesa_visitor::visit(ir_emit_vertex *ir)
+{
+ assert(!"Geometry shaders not supported.");
+}
+
+void
+ir_to_mesa_visitor::visit(ir_end_primitive *ir)
+{
+ assert(!"Geometry shaders not supported.");
}
ir_to_mesa_visitor::ir_to_mesa_visitor()
}
}
+namespace {
+
class add_uniform_to_shader : public program_resource_visitor {
public:
add_uniform_to_shader(struct gl_shader_program *shader_program,
- struct gl_program_parameter_list *params)
- : shader_program(shader_program), params(params), idx(-1)
+ struct gl_program_parameter_list *params,
+ gl_shader_type shader_type)
+ : shader_program(shader_program), params(params), idx(-1),
+ shader_type(shader_type)
{
/* empty */
}
struct gl_shader_program *shader_program;
struct gl_program_parameter_list *params;
int idx;
+ gl_shader_type shader_type;
};
+} /* anonymous namespace */
+
void
add_uniform_to_shader::visit_field(const glsl_type *type, const char *name,
bool row_major)
struct gl_uniform_storage *storage =
&this->shader_program->UniformStorage[location];
+ assert(storage->sampler[shader_type].active);
+
for (unsigned int j = 0; j < size / 4; j++)
- params->ParameterValues[index + j][0].f = storage->sampler + j;
+ params->ParameterValues[index + j][0].f =
+ storage->sampler[shader_type].index + j;
}
}
struct gl_program_parameter_list
*params)
{
- add_uniform_to_shader add(shader_program, params);
+ add_uniform_to_shader add(shader_program, params,
+ _mesa_shader_type_to_index(sh->Type));
foreach_list(node, sh->ir) {
ir_variable *var = ((ir_instruction *) node)->as_variable();
format = uniform_native;
columns = 1;
break;
+ case GLSL_TYPE_ATOMIC_UINT:
case GLSL_TYPE_ARRAY:
case GLSL_TYPE_VOID:
case GLSL_TYPE_STRUCT:
int i;
struct gl_program *prog;
GLenum target;
- const char *target_string;
+ const char *target_string = _mesa_glsl_shader_target_name(shader->Type);
struct gl_shader_compiler_options *options =
&ctx->ShaderCompilerOptions[_mesa_shader_type_to_index(shader->Type)];
switch (shader->Type) {
case GL_VERTEX_SHADER:
target = GL_VERTEX_PROGRAM_ARB;
- target_string = "vertex";
break;
case GL_FRAGMENT_SHADER:
target = GL_FRAGMENT_PROGRAM_ARB;
- target_string = "fragment";
break;
case GL_GEOMETRY_SHADER:
target = GL_GEOMETRY_PROGRAM_NV;
- target_string = "geometry";
break;
default:
assert(!"should not be reached");
*/
mesa_instructions = NULL;
- do_set_program_inouts(shader->ir, prog, shader->Type == GL_FRAGMENT_SHADER);
+ do_set_program_inouts(shader->ir, prog, shader->Type);
prog->SamplersUsed = shader->active_samplers;
prog->ShadowSamplers = shader->shadow_samplers;
|| progress;
progress = do_vec_index_to_cond_assign(ir) || progress;
+ progress = lower_vector_insert(ir, true) || progress;
} while (progress);
validate_ir_tree(ir);
linked_prog = get_mesa_program(ctx, prog, prog->_LinkedShaders[i]);
if (linked_prog) {
- static const GLenum targets[] = {
- GL_VERTEX_PROGRAM_ARB,
- GL_FRAGMENT_PROGRAM_ARB,
- GL_GEOMETRY_PROGRAM_NV
- };
-
- if (i == MESA_SHADER_VERTEX) {
- ((struct gl_vertex_program *)linked_prog)->UsesClipDistance
- = prog->Vert.UsesClipDistance;
- }
+ _mesa_copy_linked_program_data((gl_shader_type) i, prog, linked_prog);
_mesa_reference_program(ctx, &prog->_LinkedShaders[i]->Program,
linked_prog);
- if (!ctx->Driver.ProgramStringNotify(ctx, targets[i], linked_prog)) {
+ if (!ctx->Driver.ProgramStringNotify(ctx,
+ _mesa_program_index_to_target(i),
+ linked_prog)) {
return GL_FALSE;
}
}
return prog->LinkStatus;
}
-
-/**
- * Compile a GLSL shader. Called via glCompileShader().
- */
-void
-_mesa_glsl_compile_shader(struct gl_context *ctx, struct gl_shader *shader)
-{
- struct _mesa_glsl_parse_state *state =
- new(shader) _mesa_glsl_parse_state(ctx, shader->Type, shader);
-
- const char *source = shader->Source;
- /* Check if the user called glCompileShader without first calling
- * glShaderSource. This should fail to compile, but not raise a GL_ERROR.
- */
- if (source == NULL) {
- shader->CompileStatus = GL_FALSE;
- return;
- }
-
- state->error = glcpp_preprocess(state, &source, &state->info_log,
- &ctx->Extensions, ctx);
-
- if (ctx->Shader.Flags & GLSL_DUMP) {
- printf("GLSL source for %s shader %d:\n",
- _mesa_glsl_shader_target_name(state->target), shader->Name);
- printf("%s\n", shader->Source);
- }
-
- if (!state->error) {
- _mesa_glsl_lexer_ctor(state, source);
- _mesa_glsl_parse(state);
- _mesa_glsl_lexer_dtor(state);
- }
-
- ralloc_free(shader->ir);
- shader->ir = new(shader) exec_list;
- if (!state->error && !state->translation_unit.is_empty())
- _mesa_ast_to_hir(shader->ir, state);
-
- if (!state->error && !shader->ir->is_empty()) {
- validate_ir_tree(shader->ir);
- struct gl_shader_compiler_options *options =
- &ctx->ShaderCompilerOptions[_mesa_shader_type_to_index(shader->Type)];
-
- /* Do some optimization at compile time to reduce shader IR size
- * and reduce later work if the same shader is linked multiple times
- */
- while (do_common_optimization(shader->ir, false, false, 32, options))
- ;
-
- validate_ir_tree(shader->ir);
- }
-
- shader->symbols = state->symbols;
-
- shader->CompileStatus = !state->error;
- shader->InfoLog = state->info_log;
- shader->Version = state->language_version;
- memcpy(shader->builtins_to_link, state->builtins_to_link,
- sizeof(shader->builtins_to_link[0]) * state->num_builtins_to_link);
- shader->num_builtins_to_link = state->num_builtins_to_link;
-
- if (ctx->Shader.Flags & GLSL_LOG) {
- _mesa_write_shader_to_file(shader);
- }
-
- if (ctx->Shader.Flags & GLSL_DUMP) {
- if (shader->CompileStatus) {
- printf("GLSL IR for shader %d:\n", shader->Name);
- _mesa_print_ir(shader->ir, NULL);
- printf("\n\n");
- } else {
- printf("GLSL shader %d failed to compile.\n", shader->Name);
- }
- if (shader->InfoLog && shader->InfoLog[0] != 0) {
- printf("GLSL shader %d info log:\n", shader->Name);
- printf("%s\n", shader->InfoLog);
- }
- }
-
- if (shader->UniformBlocks)
- ralloc_free(shader->UniformBlocks);
- shader->NumUniformBlocks = state->num_uniform_blocks;
- shader->UniformBlocks = state->uniform_blocks;
- ralloc_steal(shader, shader->UniformBlocks);
-
- /* Retain any live IR, but trash the rest. */
- reparent_ir(shader->ir, shader->ir);
-
- ralloc_free(state);
-}
-
-
/**
* Link a GLSL shader program. Called via glLinkProgram().
*/
for (i = 0; i < prog->NumShaders; i++) {
if (!prog->Shaders[i]->CompileStatus) {
linker_error(prog, "linking with uncompiled shader");
- prog->LinkStatus = GL_FALSE;
}
}