diff options
Diffstat (limited to 'mesalib/src')
139 files changed, 3848 insertions, 1238 deletions
diff --git a/mesalib/src/SConscript b/mesalib/src/SConscript index 146591866..a24aceaea 100644 --- a/mesalib/src/SConscript +++ b/mesalib/src/SConscript @@ -18,6 +18,11 @@ if env['hostonly']: # enable OpenGL ES support. SConscript('mapi/glapi/gen/SConscript') SConscript('mapi/glapi/SConscript') + +# Haiku C++ libGL dispatch (renderers depend on libgl) +if env['platform'] in ['haiku']: + SConscript('hgl/SConscript') + SConscript('mesa/SConscript') SConscript('mapi/vgapi/SConscript') diff --git a/mesalib/src/gallium/SConscript b/mesalib/src/gallium/SConscript index 6e27be2c0..32bbdbe56 100644 --- a/mesalib/src/gallium/SConscript +++ b/mesalib/src/gallium/SConscript @@ -119,7 +119,6 @@ if not env['embedded']: if env['platform'] == 'haiku': SConscript([ 'targets/haiku-softpipe/SConscript', - 'targets/libgl-haiku/SConscript', ]) if env['dri']: diff --git a/mesalib/src/gallium/auxiliary/util/u_clear.h b/mesalib/src/gallium/auxiliary/util/u_clear.h index 75047c16b..bd8efdb4a 100644 --- a/mesalib/src/gallium/auxiliary/util/u_clear.h +++ b/mesalib/src/gallium/auxiliary/util/u_clear.h @@ -47,7 +47,10 @@ util_clear(struct pipe_context *pipe, for (i = 0; i < framebuffer->nr_cbufs; i++) { if (buffers & (PIPE_CLEAR_COLOR0 << i)) { struct pipe_surface *ps = framebuffer->cbufs[i]; - pipe->clear_render_target(pipe, ps, color, 0, 0, ps->width, ps->height); + + if (ps) { + pipe->clear_render_target(pipe, ps, color, 0, 0, ps->width, ps->height); + } } } diff --git a/mesalib/src/gallium/auxiliary/util/u_framebuffer.c b/mesalib/src/gallium/auxiliary/util/u_framebuffer.c index 683967237..2e0ef749e 100644 --- a/mesalib/src/gallium/auxiliary/util/u_framebuffer.c +++ b/mesalib/src/gallium/auxiliary/util/u_framebuffer.c @@ -127,6 +127,9 @@ util_framebuffer_min_size(const struct pipe_framebuffer_state *fb, unsigned i; for (i = 0; i < fb->nr_cbufs; i++) { + if (!fb->cbufs[i]) + continue; + w = MIN2(w, fb->cbufs[i]->width); h = MIN2(h, fb->cbufs[i]->height); } @@ -171,3 +174,24 @@ util_framebuffer_get_num_layers(const struct pipe_framebuffer_state *fb) } return num_layers; } + + +/** + * Return the number of MSAA samples. + */ +unsigned +util_framebuffer_get_num_samples(const struct pipe_framebuffer_state *fb) +{ + unsigned i; + + for (i = 0; i < fb->nr_cbufs; i++) { + if (fb->cbufs[i]) { + return MAX2(1, fb->cbufs[i]->texture->nr_samples); + } + } + if (fb->zsbuf) { + return MAX2(1, fb->zsbuf->texture->nr_samples); + } + + return 1; +} diff --git a/mesalib/src/gallium/auxiliary/util/u_framebuffer.h b/mesalib/src/gallium/auxiliary/util/u_framebuffer.h index 0e6c98363..c73942c9c 100644 --- a/mesalib/src/gallium/auxiliary/util/u_framebuffer.h +++ b/mesalib/src/gallium/auxiliary/util/u_framebuffer.h @@ -60,6 +60,10 @@ extern unsigned util_framebuffer_get_num_layers(const struct pipe_framebuffer_state *fb); +extern unsigned +util_framebuffer_get_num_samples(const struct pipe_framebuffer_state *fb); + + #ifdef __cplusplus } #endif diff --git a/mesalib/src/glsl/ast_function.cpp b/mesalib/src/glsl/ast_function.cpp index e4c0fd1c4..2d05d0723 100644 --- a/mesalib/src/glsl/ast_function.cpp +++ b/mesalib/src/glsl/ast_function.cpp @@ -293,15 +293,10 @@ generate_call(exec_list *instructions, ir_function_signature *sig, * call takes place. Since we haven't emitted the call yet, we'll place * the post-call conversions in a temporary exec_list, and emit them later. */ - exec_list_iterator actual_iter = actual_parameters->iterator(); - exec_list_iterator formal_iter = sig->parameters.iterator(); - - while (actual_iter.has_next()) { - ir_rvalue *actual = (ir_rvalue *) actual_iter.get(); - ir_variable *formal = (ir_variable *) formal_iter.get(); - - assert(actual != NULL); - assert(formal != NULL); + foreach_two_lists(formal_node, &sig->parameters, + actual_node, actual_parameters) { + ir_rvalue *actual = (ir_rvalue *) actual_node; + ir_variable *formal = (ir_variable *) formal_node; if (formal->type->is_numeric() || formal->type->is_boolean()) { switch (formal->data.mode) { @@ -323,9 +318,6 @@ generate_call(exec_list *instructions, ir_function_signature *sig, break; } } - - actual_iter.next(); - formal_iter.next(); } /* If the function call is a constant expression, don't generate any diff --git a/mesalib/src/glsl/ast_to_hir.cpp b/mesalib/src/glsl/ast_to_hir.cpp index 91810f985..4cc8eb18d 100644 --- a/mesalib/src/glsl/ast_to_hir.cpp +++ b/mesalib/src/glsl/ast_to_hir.cpp @@ -1860,7 +1860,7 @@ ast_fully_specified_type::glsl_type(const char **name, if (type->base_type == GLSL_TYPE_FLOAT && state->es_shader - && state->target == MESA_SHADER_FRAGMENT + && state->stage == MESA_SHADER_FRAGMENT && this->qualifier.precision == ast_precision_none && state->symbols->get_variable("#default precision") == NULL) { YYLTYPE loc = this->get_location(); @@ -1882,7 +1882,7 @@ ast_fully_specified_type::glsl_type(const char **name, * this function will produce undefined results. */ static bool -is_varying_var(ir_variable *var, gl_shader_type target) +is_varying_var(ir_variable *var, gl_shader_stage target) { switch (target) { case MESA_SHADER_VERTEX: @@ -1983,18 +1983,7 @@ validate_binding_qualifier(struct _mesa_glsl_parse_state *state, * with an array of size N, all elements of the array from binding * through binding + N - 1 must be within this range." */ - unsigned limit = 0; - switch (state->target) { - case MESA_SHADER_VERTEX: - limit = ctx->Const.VertexProgram.MaxTextureImageUnits; - break; - case MESA_SHADER_GEOMETRY: - limit = ctx->Const.GeometryProgram.MaxTextureImageUnits; - break; - case MESA_SHADER_FRAGMENT: - limit = ctx->Const.FragmentProgram.MaxTextureImageUnits; - break; - } + unsigned limit = ctx->Const.Program[state->stage].MaxTextureImageUnits; if (max_index >= limit) { _mesa_glsl_error(loc, state, "layout(binding = %d) for %d samplers " @@ -2049,8 +2038,8 @@ interpret_interpolation_qualifier(const struct ast_type_qualifier *qual, } - if ((state->target == MESA_SHADER_VERTEX && mode == ir_var_shader_in) || - (state->target == MESA_SHADER_FRAGMENT && mode == ir_var_shader_out)) { + if ((state->stage == MESA_SHADER_VERTEX && mode == ir_var_shader_in) || + (state->stage == MESA_SHADER_FRAGMENT && mode == ir_var_shader_out)) { _mesa_glsl_error(loc, state, "interpolation qualifier `%s' cannot be applied to " "vertex shader inputs or fragment shader outputs", @@ -2076,7 +2065,7 @@ validate_explicit_location(const struct ast_type_qualifier *qual, * In the fragment shader only shader outputs can be given explicit * locations. */ - switch (state->target) { + switch (state->stage) { case MESA_SHADER_VERTEX: if (var->data.mode == ir_var_shader_in) { if (!state->check_explicit_attrib_location_allowed(loc, var)) @@ -2110,7 +2099,7 @@ validate_explicit_location(const struct ast_type_qualifier *qual, _mesa_glsl_error(loc, state, "%s cannot be given an explicit location in %s shader", mode_string(var), - _mesa_shader_type_to_string(state->target)); + _mesa_shader_stage_to_string(state->stage)); } else { var->data.explicit_location = true; @@ -2122,7 +2111,7 @@ validate_explicit_location(const struct ast_type_qualifier *qual, * ensures that negative values stay negative. */ if (qual->location >= 0) { - var->data.location = (state->target == MESA_SHADER_VERTEX) + var->data.location = (state->stage == MESA_SHADER_VERTEX) ? (qual->location + VERT_ATTRIB_GENERIC0) : (qual->location + FRAG_RESULT_DATA0); } else { @@ -2174,7 +2163,7 @@ apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual, if (qual->flags.q.constant || qual->flags.q.attribute || qual->flags.q.uniform - || (qual->flags.q.varying && (state->target == MESA_SHADER_FRAGMENT))) + || (qual->flags.q.varying && (state->stage == MESA_SHADER_FRAGMENT))) var->data.read_only = 1; if (qual->flags.q.centroid) @@ -2183,12 +2172,12 @@ apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual, if (qual->flags.q.sample) var->data.sample = 1; - if (qual->flags.q.attribute && state->target != MESA_SHADER_VERTEX) { + if (qual->flags.q.attribute && state->stage != MESA_SHADER_VERTEX) { var->type = glsl_type::error_type; _mesa_glsl_error(loc, state, "`attribute' variables may not be declared in the " "%s shader", - _mesa_shader_type_to_string(state->target)); + _mesa_shader_stage_to_string(state->stage)); } /* Section 6.1.1 (Function Calling Conventions) of the GLSL 1.10 spec says: @@ -2214,16 +2203,16 @@ apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual, else if (qual->flags.q.in) var->data.mode = is_parameter ? ir_var_function_in : ir_var_shader_in; else if (qual->flags.q.attribute - || (qual->flags.q.varying && (state->target == MESA_SHADER_FRAGMENT))) + || (qual->flags.q.varying && (state->stage == MESA_SHADER_FRAGMENT))) var->data.mode = ir_var_shader_in; else if (qual->flags.q.out) var->data.mode = is_parameter ? ir_var_function_out : ir_var_shader_out; - else if (qual->flags.q.varying && (state->target == MESA_SHADER_VERTEX)) + else if (qual->flags.q.varying && (state->stage == MESA_SHADER_VERTEX)) var->data.mode = ir_var_shader_out; else if (qual->flags.q.uniform) var->data.mode = ir_var_uniform; - if (!is_parameter && is_varying_var(var, state->target)) { + if (!is_parameter && is_varying_var(var, state->stage)) { /* This variable is being used to link data between shader stages (in * pre-glsl-1.30 parlance, it's a "varying"). Check that it has a type * that is allowed for such purposes. @@ -2272,7 +2261,7 @@ apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual, } if (state->all_invariant && (state->current_function == NULL)) { - switch (state->target) { + switch (state->stage) { case MESA_SHADER_VERTEX: if (var->data.mode == ir_var_shader_out) var->data.invariant = true; @@ -2599,8 +2588,8 @@ process_initializer(ir_variable *var, ast_declaration *decl, if ((var->data.mode == ir_var_shader_in) && (state->current_function == NULL)) { _mesa_glsl_error(& initializer_loc, state, "cannot initialize %s shader input / %s", - _mesa_shader_type_to_string(state->target), - (state->target == MESA_SHADER_VERTEX) + _mesa_shader_stage_to_string(state->stage), + (state->stage == MESA_SHADER_VERTEX) ? "attribute" : "varying"); } @@ -2844,12 +2833,12 @@ ast_declarator_list::hir(exec_list *instructions, _mesa_glsl_error(& loc, state, "undeclared variable `%s' cannot be marked " "invariant", decl->identifier); - } else if ((state->target == MESA_SHADER_VERTEX) + } else if ((state->stage == MESA_SHADER_VERTEX) && (earlier->data.mode != ir_var_shader_out)) { _mesa_glsl_error(& loc, state, "`%s' cannot be marked invariant, vertex shader " "outputs only", decl->identifier); - } else if ((state->target == MESA_SHADER_FRAGMENT) + } else if ((state->stage == MESA_SHADER_FRAGMENT) && (earlier->data.mode != ir_var_shader_in)) { _mesa_glsl_error(& loc, state, "`%s' cannot be marked invariant, fragment shader " @@ -3034,12 +3023,12 @@ ast_declarator_list::hir(exec_list *instructions, & loc, false); if (this->type->qualifier.flags.q.invariant) { - if ((state->target == MESA_SHADER_VERTEX) && + if ((state->stage == MESA_SHADER_VERTEX) && var->data.mode != ir_var_shader_out) { _mesa_glsl_error(& loc, state, "`%s' cannot be marked invariant, vertex shader " "outputs only", var->name); - } else if ((state->target == MESA_SHADER_FRAGMENT) && + } else if ((state->stage == MESA_SHADER_FRAGMENT) && var->data.mode != ir_var_shader_in) { /* FINISHME: Note that this doesn't work for invariant on * a function signature inval @@ -3080,7 +3069,7 @@ ast_declarator_list::hir(exec_list *instructions, } else if (var->data.mode == ir_var_shader_in) { var->data.read_only = true; - if (state->target == MESA_SHADER_VERTEX) { + if (state->stage == MESA_SHADER_VERTEX) { bool error_emitted = false; /* From page 31 (page 37 of the PDF) of the GLSL 1.50 spec: @@ -3135,7 +3124,7 @@ ast_declarator_list::hir(exec_list *instructions, "cannot have array type")) { error_emitted = true; } - } else if (state->target == MESA_SHADER_GEOMETRY) { + } else if (state->stage == MESA_SHADER_GEOMETRY) { /* From section 4.3.4 (Inputs) of the GLSL 1.50 spec: * * Geometry shader input variables get the per-vertex values @@ -3185,10 +3174,10 @@ ast_declarator_list::hir(exec_list *instructions, if (state->is_version(130, 300) && var->type->contains_integer() && var->data.interpolation != INTERP_QUALIFIER_FLAT && - ((state->target == MESA_SHADER_FRAGMENT && var->data.mode == ir_var_shader_in) - || (state->target == MESA_SHADER_VERTEX && var->data.mode == ir_var_shader_out + ((state->stage == MESA_SHADER_FRAGMENT && var->data.mode == ir_var_shader_in) + || (state->stage == MESA_SHADER_VERTEX && var->data.mode == ir_var_shader_out && state->es_shader))) { - const char *var_type = (state->target == MESA_SHADER_VERTEX) ? + const char *var_type = (state->stage == MESA_SHADER_VERTEX) ? "vertex output" : "fragment input"; _mesa_glsl_error(&loc, state, "if a %s is (or contains) " "an integer, then it must be qualified with 'flat'", @@ -3244,7 +3233,7 @@ ast_declarator_list::hir(exec_list *instructions, const char *i = this->type->qualifier.interpolation_string(); assert(i != NULL); - switch (state->target) { + switch (state->stage) { case MESA_SHADER_VERTEX: if (this->type->qualifier.flags.q.in) { _mesa_glsl_error(&loc, state, @@ -3275,13 +3264,13 @@ ast_declarator_list::hir(exec_list *instructions, if (state->is_version(130, 300) && this->type->qualifier.flags.q.centroid && this->type->qualifier.flags.q.in - && state->target == MESA_SHADER_VERTEX) { + && state->stage == MESA_SHADER_VERTEX) { _mesa_glsl_error(&loc, state, "'centroid in' cannot be used in a vertex shader"); } - if (state->target == MESA_SHADER_VERTEX + if (state->stage == MESA_SHADER_VERTEX && this->type->qualifier.flags.q.sample && this->type->qualifier.flags.q.in) { @@ -3296,7 +3285,7 @@ ast_declarator_list::hir(exec_list *instructions, * "It is an error to use auxiliary storage qualifiers or interpolation * qualifiers on an output in a fragment shader." */ - if (state->target == MESA_SHADER_FRAGMENT && + if (state->stage == MESA_SHADER_FRAGMENT && this->type->qualifier.flags.q.out && this->type->qualifier.has_auxiliary_storage()) { _mesa_glsl_error(&loc, state, @@ -3829,8 +3818,8 @@ ast_function_definition::hir(exec_list *instructions, * Add these to the symbol table. */ state->symbols->push_scope(); - foreach_iter(exec_list_iterator, iter, signature->parameters) { - ir_variable *const var = ((ir_instruction *) iter.get())->as_variable(); + foreach_list(n, &signature->parameters) { + ir_variable *const var = ((ir_instruction *) n)->as_variable(); assert(var != NULL); @@ -3954,7 +3943,7 @@ ast_jump_statement::hir(exec_list *instructions, } case ast_discard: - if (state->target != MESA_SHADER_FRAGMENT) { + if (state->stage != MESA_SHADER_FRAGMENT) { YYLTYPE loc = this->get_location(); _mesa_glsl_error(& loc, state, @@ -4492,7 +4481,7 @@ ast_type_specifier::hir(exec_list *instructions, if (type->base_type == GLSL_TYPE_FLOAT && state->es_shader - && state->target == MESA_SHADER_FRAGMENT) { + && state->stage == MESA_SHADER_FRAGMENT) { /* Section 4.5.3 (Default Precision Qualifiers) of the GLSL ES 1.00 * spec says: * @@ -4890,7 +4879,7 @@ ast_interface_block::hir(exec_list *instructions, _mesa_glsl_error(&loc, state, "redeclaration of gl_PerVertex input not allowed " "in the %s shader", - _mesa_shader_type_to_string(state->target)); + _mesa_shader_stage_to_string(state->stage)); } if (this->instance_name == NULL || strcmp(this->instance_name, "gl_in") != 0 || !this->is_array) { @@ -4907,7 +4896,7 @@ ast_interface_block::hir(exec_list *instructions, _mesa_glsl_error(&loc, state, "redeclaration of gl_PerVertex output not " "allowed in the %s shader", - _mesa_shader_type_to_string(state->target)); + _mesa_shader_stage_to_string(state->stage)); } if (this->instance_name != NULL) { _mesa_glsl_error(&loc, state, @@ -4995,7 +4984,7 @@ ast_interface_block::hir(exec_list *instructions, * variable (or input block, see interface blocks below) needs to be * declared as an array. */ - if (state->target == MESA_SHADER_GEOMETRY && !this->is_array && + if (state->stage == MESA_SHADER_GEOMETRY && !this->is_array && var_mode == ir_var_shader_in) { _mesa_glsl_error(&loc, state, "geometry shader inputs must be arrays"); } @@ -5050,7 +5039,7 @@ ast_interface_block::hir(exec_list *instructions, * geometry shader input. */ if (this->array_size == NULL && - (state->target != MESA_SHADER_GEOMETRY || !this->layout.flags.q.in)) { + (state->stage != MESA_SHADER_GEOMETRY || !this->layout.flags.q.in)) { _mesa_glsl_error(&loc, state, "only geometry shader inputs may be unsized " "instance block arrays"); @@ -5069,7 +5058,7 @@ ast_interface_block::hir(exec_list *instructions, var_mode); } - if (state->target == MESA_SHADER_GEOMETRY && var_mode == ir_var_shader_in) + if (state->stage == MESA_SHADER_GEOMETRY && var_mode == ir_var_shader_in) handle_geometry_shader_input_decl(state, loc, var); if (ir_variable *earlier = @@ -5265,7 +5254,7 @@ detect_conflicting_assignments(struct _mesa_glsl_parse_state *state, else if (strcmp(var->name, "gl_FragData") == 0) gl_FragData_assigned = true; else if (strncmp(var->name, "gl_", 3) != 0) { - if (state->target == MESA_SHADER_FRAGMENT && + if (state->stage == MESA_SHADER_FRAGMENT && var->data.mode == ir_var_shader_out) { user_defined_fs_output_assigned = true; user_defined_fs_output = var; diff --git a/mesalib/src/glsl/builtin_functions.cpp b/mesalib/src/glsl/builtin_functions.cpp index f22ace19d..b1065f48d 100644..100755 --- a/mesalib/src/glsl/builtin_functions.cpp +++ b/mesalib/src/glsl/builtin_functions.cpp @@ -77,7 +77,7 @@ always_available(const _mesa_glsl_parse_state *state) static bool compatibility_vs_only(const _mesa_glsl_parse_state *state) { - return state->target == MESA_SHADER_VERTEX && + return state->stage == MESA_SHADER_VERTEX && state->language_version <= 130 && !state->es_shader; } @@ -85,13 +85,13 @@ compatibility_vs_only(const _mesa_glsl_parse_state *state) static bool fs_only(const _mesa_glsl_parse_state *state) { - return state->target == MESA_SHADER_FRAGMENT; + return state->stage == MESA_SHADER_FRAGMENT; } static bool gs_only(const _mesa_glsl_parse_state *state) { - return state->target == MESA_SHADER_GEOMETRY; + return state->stage == MESA_SHADER_GEOMETRY; } static bool @@ -103,7 +103,7 @@ v110(const _mesa_glsl_parse_state *state) static bool v110_fs_only(const _mesa_glsl_parse_state *state) { - return !state->es_shader && state->target == MESA_SHADER_FRAGMENT; + return !state->es_shader && state->stage == MESA_SHADER_FRAGMENT; } static bool @@ -122,7 +122,7 @@ static bool v130_fs_only(const _mesa_glsl_parse_state *state) { return state->is_version(130, 300) && - state->target == MESA_SHADER_FRAGMENT; + state->stage == MESA_SHADER_FRAGMENT; } static bool @@ -155,7 +155,7 @@ lod_exists_in_stage(const _mesa_glsl_parse_state *state) * Since ARB_shader_texture_lod can only be enabled on desktop GLSL, we * don't need to explicitly check state->es_shader. */ - return state->target == MESA_SHADER_VERTEX || + return state->stage == MESA_SHADER_VERTEX || state->is_version(130, 300) || state->ARB_shader_texture_lod_enable; } @@ -223,7 +223,7 @@ texture_array_lod(const _mesa_glsl_parse_state *state) static bool fs_texture_array(const _mesa_glsl_parse_state *state) { - return state->target == MESA_SHADER_FRAGMENT && + return state->stage == MESA_SHADER_FRAGMENT && state->EXT_texture_array_enable; } @@ -243,7 +243,7 @@ texture_multisample(const _mesa_glsl_parse_state *state) static bool fs_texture_cube_map_array(const _mesa_glsl_parse_state *state) { - return state->target == MESA_SHADER_FRAGMENT && + return state->stage == MESA_SHADER_FRAGMENT && (state->is_version(400, 0) || state->ARB_texture_cube_map_array_enable); } @@ -265,7 +265,7 @@ texture_query_levels(const _mesa_glsl_parse_state *state) static bool texture_query_lod(const _mesa_glsl_parse_state *state) { - return state->target == MESA_SHADER_FRAGMENT && + return state->stage == MESA_SHADER_FRAGMENT && state->ARB_texture_query_lod_enable; } @@ -292,7 +292,7 @@ texture_gather_only(const _mesa_glsl_parse_state *state) static bool fs_oes_derivatives(const _mesa_glsl_parse_state *state) { - return state->target == MESA_SHADER_FRAGMENT && + return state->stage == MESA_SHADER_FRAGMENT && (state->is_version(110, 300) || state->OES_standard_derivatives_enable); } @@ -318,7 +318,7 @@ tex3d(const _mesa_glsl_parse_state *state) static bool fs_tex3d(const _mesa_glsl_parse_state *state) { - return state->target == MESA_SHADER_FRAGMENT && + return state->stage == MESA_SHADER_FRAGMENT && (!state->es_shader || state->OES_texture_3D_enable); } @@ -334,6 +334,12 @@ shader_atomic_counters(const _mesa_glsl_parse_state *state) return state->ARB_shader_atomic_counters_enable; } +static bool +shader_trinary_minmax(const _mesa_glsl_parse_state *state) +{ + return state->AMD_shader_trinary_minmax_enable; +} + /** @} */ /******************************************************************************/ @@ -570,6 +576,21 @@ private: ir_function_signature *_atomic_op(const char *intrinsic, builtin_available_predicate avail); + ir_function_signature *_min3(builtin_available_predicate avail, + const glsl_type *x_type, + const glsl_type *y_type, + const glsl_type *z_type); + + ir_function_signature *_max3(builtin_available_predicate avail, + const glsl_type *x_type, + const glsl_type *y_type, + const glsl_type *z_type); + + ir_function_signature *_mid3(builtin_available_predicate avail, + const glsl_type *x_type, + const glsl_type *y_type, + const glsl_type *z_type); + #undef B0 #undef B1 #undef B2 @@ -2106,6 +2127,57 @@ builtin_builder::create_builtins() shader_atomic_counters), NULL); + add_function("min3", + _min3(shader_trinary_minmax, glsl_type::float_type, glsl_type::float_type, glsl_type::float_type), + _min3(shader_trinary_minmax, glsl_type::vec2_type, glsl_type::vec2_type, glsl_type::vec2_type), + _min3(shader_trinary_minmax, glsl_type::vec3_type, glsl_type::vec3_type, glsl_type::vec3_type), + _min3(shader_trinary_minmax, glsl_type::vec4_type, glsl_type::vec4_type, glsl_type::vec4_type), + + _min3(shader_trinary_minmax, glsl_type::int_type, glsl_type::int_type, glsl_type::int_type), + _min3(shader_trinary_minmax, glsl_type::ivec2_type, glsl_type::ivec2_type, glsl_type::ivec2_type), + _min3(shader_trinary_minmax, glsl_type::ivec3_type, glsl_type::ivec3_type, glsl_type::ivec3_type), + _min3(shader_trinary_minmax, glsl_type::ivec4_type, glsl_type::ivec4_type, glsl_type::ivec4_type), + + _min3(shader_trinary_minmax, glsl_type::uint_type, glsl_type::uint_type, glsl_type::uint_type), + _min3(shader_trinary_minmax, glsl_type::uvec2_type, glsl_type::uvec2_type, glsl_type::uvec2_type), + _min3(shader_trinary_minmax, glsl_type::uvec3_type, glsl_type::uvec3_type, glsl_type::uvec3_type), + _min3(shader_trinary_minmax, glsl_type::uvec4_type, glsl_type::uvec4_type, glsl_type::uvec4_type), + NULL); + + add_function("max3", + _max3(shader_trinary_minmax, glsl_type::float_type, glsl_type::float_type, glsl_type::float_type), + _max3(shader_trinary_minmax, glsl_type::vec2_type, glsl_type::vec2_type, glsl_type::vec2_type), + _max3(shader_trinary_minmax, glsl_type::vec3_type, glsl_type::vec3_type, glsl_type::vec3_type), + _max3(shader_trinary_minmax, glsl_type::vec4_type, glsl_type::vec4_type, glsl_type::vec4_type), + + _max3(shader_trinary_minmax, glsl_type::int_type, glsl_type::int_type, glsl_type::int_type), + _max3(shader_trinary_minmax, glsl_type::ivec2_type, glsl_type::ivec2_type, glsl_type::ivec2_type), + _max3(shader_trinary_minmax, glsl_type::ivec3_type, glsl_type::ivec3_type, glsl_type::ivec3_type), + _max3(shader_trinary_minmax, glsl_type::ivec4_type, glsl_type::ivec4_type, glsl_type::ivec4_type), + + _max3(shader_trinary_minmax, glsl_type::uint_type, glsl_type::uint_type, glsl_type::uint_type), + _max3(shader_trinary_minmax, glsl_type::uvec2_type, glsl_type::uvec2_type, glsl_type::uvec2_type), + _max3(shader_trinary_minmax, glsl_type::uvec3_type, glsl_type::uvec3_type, glsl_type::uvec3_type), + _max3(shader_trinary_minmax, glsl_type::uvec4_type, glsl_type::uvec4_type, glsl_type::uvec4_type), + NULL); + + add_function("mid3", + _mid3(shader_trinary_minmax, glsl_type::float_type, glsl_type::float_type, glsl_type::float_type), + _mid3(shader_trinary_minmax, glsl_type::vec2_type, glsl_type::vec2_type, glsl_type::vec2_type), + _mid3(shader_trinary_minmax, glsl_type::vec3_type, glsl_type::vec3_type, glsl_type::vec3_type), + _mid3(shader_trinary_minmax, glsl_type::vec4_type, glsl_type::vec4_type, glsl_type::vec4_type), + + _mid3(shader_trinary_minmax, glsl_type::int_type, glsl_type::int_type, glsl_type::int_type), + _mid3(shader_trinary_minmax, glsl_type::ivec2_type, glsl_type::ivec2_type, glsl_type::ivec2_type), + _mid3(shader_trinary_minmax, glsl_type::ivec3_type, glsl_type::ivec3_type, glsl_type::ivec3_type), + _mid3(shader_trinary_minmax, glsl_type::ivec4_type, glsl_type::ivec4_type, glsl_type::ivec4_type), + + _mid3(shader_trinary_minmax, glsl_type::uint_type, glsl_type::uint_type, glsl_type::uint_type), + _mid3(shader_trinary_minmax, glsl_type::uvec2_type, glsl_type::uvec2_type, glsl_type::uvec2_type), + _mid3(shader_trinary_minmax, glsl_type::uvec3_type, glsl_type::uvec3_type, glsl_type::uvec3_type), + _mid3(shader_trinary_minmax, glsl_type::uvec4_type, glsl_type::uvec4_type, glsl_type::uvec4_type), + NULL); + #undef F #undef FI #undef FIU @@ -2326,8 +2398,8 @@ builtin_builder::call(ir_function *f, ir_variable *ret, exec_list params) { exec_list actual_params; - foreach_iter(exec_list_iterator, it, params) { - ir_variable *var = ((ir_instruction *)it.get())->as_variable(); + foreach_list(node, ¶ms) { + ir_variable *var = (ir_variable *) node; actual_params.push_tail(var_ref(var)); } @@ -3864,7 +3936,7 @@ builtin_builder::_fma_mesa(const glsl_type *type) ir_variable *c = in_var(type, "c"); MAKE_SIG(type, gpu_shader5, 3, a, b, c); - body.emit(ret(fma_mesa(a, b, c))); + body.emit(ret(ir_builder::fma(a, b, c))); return sig; } @@ -3991,6 +4063,54 @@ builtin_builder::_atomic_op(const char *intrinsic, return sig; } +ir_function_signature * +builtin_builder::_min3(builtin_available_predicate avail, + const glsl_type *x_type, const glsl_type *y_type, + const glsl_type *z_type) +{ + ir_variable *x = in_var(x_type, "x"); + ir_variable *y = in_var(y_type, "y"); + ir_variable *z = in_var(z_type, "z"); + MAKE_SIG(x_type, avail, 3, x, y, z); + + ir_expression *min3 = min2(x, min2(y,z)); + body.emit(ret(min3)); + + return sig; +} + +ir_function_signature * +builtin_builder::_max3(builtin_available_predicate avail, + const glsl_type *x_type, const glsl_type *y_type, + const glsl_type *z_type) +{ + ir_variable *x = in_var(x_type, "x"); + ir_variable *y = in_var(y_type, "y"); + ir_variable *z = in_var(z_type, "z"); + MAKE_SIG(x_type, avail, 3, x, y, z); + + ir_expression *max3 = max2(x, max2(y,z)); + body.emit(ret(max3)); + + return sig; +} + +ir_function_signature * +builtin_builder::_mid3(builtin_available_predicate avail, + const glsl_type *x_type, const glsl_type *y_type, + const glsl_type *z_type) +{ + ir_variable *x = in_var(x_type, "x"); + ir_variable *y = in_var(y_type, "y"); + ir_variable *z = in_var(z_type, "z"); + MAKE_SIG(x_type, avail, 3, x, y, z); + + ir_expression *mid3 = max2(min2(x, y), max2(min2(x, z), min2(y, z))); + body.emit(ret(mid3)); + + return sig; +} + /** @} */ /******************************************************************************/ diff --git a/mesalib/src/glsl/builtin_variables.cpp b/mesalib/src/glsl/builtin_variables.cpp index ff9acb8d0..f630923ed 100644 --- a/mesalib/src/glsl/builtin_variables.cpp +++ b/mesalib/src/glsl/builtin_variables.cpp @@ -554,9 +554,9 @@ builtin_variable_generator::generate_constants() */ if (state->is_version(0, 300)) { add_const("gl_MaxVertexOutputVectors", - state->ctx->Const.VertexProgram.MaxOutputComponents / 4); + state->ctx->Const.Program[MESA_SHADER_VERTEX].MaxOutputComponents / 4); add_const("gl_MaxFragmentInputVectors", - state->ctx->Const.FragmentProgram.MaxInputComponents / 4); + state->ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxInputComponents / 4); } else { add_const("gl_MaxVaryingVectors", state->ctx->Const.MaxVarying); @@ -876,7 +876,7 @@ builtin_variable_generator::add_varying(int slot, const glsl_type *type, const char *name, const char *name_as_gs_input) { - switch (state->target) { + switch (state->stage) { case MESA_SHADER_GEOMETRY: this->per_vertex_in.add_field(slot, type, name); /* FALLTHROUGH */ @@ -901,7 +901,7 @@ builtin_variable_generator::generate_varyings() add_varying(loc, type, name, name "In") /* gl_Position and gl_PointSize are not visible from fragment shaders. */ - if (state->target != MESA_SHADER_FRAGMENT) { + if (state->stage != MESA_SHADER_FRAGMENT) { ADD_VARYING(VARYING_SLOT_POS, vec4_t, "gl_Position"); ADD_VARYING(VARYING_SLOT_PSIZ, float_t, "gl_PointSize"); } @@ -914,7 +914,7 @@ builtin_variable_generator::generate_varyings() if (compatibility) { ADD_VARYING(VARYING_SLOT_TEX0, array(vec4_t, 0), "gl_TexCoord"); ADD_VARYING(VARYING_SLOT_FOGC, float_t, "gl_FogFragCoord"); - if (state->target == MESA_SHADER_FRAGMENT) { + if (state->stage == MESA_SHADER_FRAGMENT) { ADD_VARYING(VARYING_SLOT_COL0, vec4_t, "gl_Color"); ADD_VARYING(VARYING_SLOT_COL1, vec4_t, "gl_SecondaryColor"); } else { @@ -926,13 +926,13 @@ builtin_variable_generator::generate_varyings() } } - if (state->target == MESA_SHADER_GEOMETRY) { + if (state->stage == MESA_SHADER_GEOMETRY) { const glsl_type *per_vertex_in_type = this->per_vertex_in.construct_interface_instance(); add_variable("gl_in", array(per_vertex_in_type, 0), ir_var_shader_in, -1); } - if (state->target == MESA_SHADER_VERTEX || state->target == MESA_SHADER_GEOMETRY) { + if (state->stage == MESA_SHADER_VERTEX || state->stage == MESA_SHADER_GEOMETRY) { const glsl_type *per_vertex_out_type = this->per_vertex_out.construct_interface_instance(); const glsl_struct_field *fields = per_vertex_out_type->fields.structure; @@ -963,7 +963,7 @@ _mesa_glsl_initialize_variables(exec_list *instructions, gen.generate_varyings(); - switch (state->target) { + switch (state->stage) { case MESA_SHADER_VERTEX: gen.generate_vs_special_vars(); break; diff --git a/mesalib/src/glsl/glcpp/glcpp-parse.y b/mesalib/src/glsl/glcpp/glcpp-parse.y index ef084b639..55c498195 100644 --- a/mesalib/src/glsl/glcpp/glcpp-parse.y +++ b/mesalib/src/glsl/glcpp/glcpp-parse.y @@ -1281,6 +1281,9 @@ glcpp_parser_create (const struct gl_extensions *extensions, int api) if (extensions->ARB_shader_atomic_counters) add_builtin_define(parser, "GL_ARB_shader_atomic_counters", 1); + + if (extensions->AMD_shader_trinary_minmax) + add_builtin_define(parser, "GL_AMD_shader_trinary_minmax", 1); } } diff --git a/mesalib/src/glsl/glsl_parser.yy b/mesalib/src/glsl/glsl_parser.yy index 6cd129cae..52f674b63 100644 --- a/mesalib/src/glsl/glsl_parser.yy +++ b/mesalib/src/glsl/glsl_parser.yy @@ -2220,11 +2220,11 @@ basic_interface_block: * "It is illegal to have an input block in a vertex shader * or an output block in a fragment shader" */ - if ((state->target == MESA_SHADER_VERTEX) && $1.flags.q.in) { + if ((state->stage == MESA_SHADER_VERTEX) && $1.flags.q.in) { _mesa_glsl_error(& @1, state, "`in' interface block is not allowed for " "a vertex shader"); - } else if ((state->target == MESA_SHADER_FRAGMENT) && $1.flags.q.out) { + } else if ((state->stage == MESA_SHADER_FRAGMENT) && $1.flags.q.out) { _mesa_glsl_error(& @1, state, "`out' interface block is not allowed for " "a fragment shader"); @@ -2378,7 +2378,7 @@ layout_defaults: { void *ctx = state; $$ = NULL; - if (state->target != MESA_SHADER_GEOMETRY) { + if (state->stage != MESA_SHADER_GEOMETRY) { _mesa_glsl_error(& @1, state, "input layout qualifiers only valid in " "geometry shaders"); @@ -2406,7 +2406,7 @@ layout_defaults: | layout_qualifier OUT_TOK ';' { - if (state->target != MESA_SHADER_GEOMETRY) { + if (state->stage != MESA_SHADER_GEOMETRY) { _mesa_glsl_error(& @1, state, "out layout qualifiers only valid in " "geometry shaders"); diff --git a/mesalib/src/glsl/glsl_parser_extras.cpp b/mesalib/src/glsl/glsl_parser_extras.cpp index fc9a8b204..21dc3abd7 100644 --- a/mesalib/src/glsl/glsl_parser_extras.cpp +++ b/mesalib/src/glsl/glsl_parser_extras.cpp @@ -54,14 +54,12 @@ static unsigned known_desktop_glsl_versions[] = _mesa_glsl_parse_state::_mesa_glsl_parse_state(struct gl_context *_ctx, - GLenum target, void *mem_ctx) + gl_shader_stage stage, + void *mem_ctx) : ctx(_ctx), switch_state() { - switch (target) { - case GL_VERTEX_SHADER: this->target = MESA_SHADER_VERTEX; break; - case GL_FRAGMENT_SHADER: this->target = MESA_SHADER_FRAGMENT; break; - case GL_GEOMETRY_SHADER: this->target = MESA_SHADER_GEOMETRY; break; - } + assert(stage < MESA_SHADER_STAGES); + this->stage = stage; this->scanner = NULL; this->translation_unit.make_empty(); @@ -98,30 +96,30 @@ _mesa_glsl_parse_state::_mesa_glsl_parse_state(struct gl_context *_ctx, this->Const.MaxClipPlanes = ctx->Const.MaxClipPlanes; this->Const.MaxTextureUnits = ctx->Const.MaxTextureUnits; this->Const.MaxTextureCoords = ctx->Const.MaxTextureCoordUnits; - this->Const.MaxVertexAttribs = ctx->Const.VertexProgram.MaxAttribs; - this->Const.MaxVertexUniformComponents = ctx->Const.VertexProgram.MaxUniformComponents; - this->Const.MaxVertexTextureImageUnits = ctx->Const.VertexProgram.MaxTextureImageUnits; + this->Const.MaxVertexAttribs = ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs; + this->Const.MaxVertexUniformComponents = ctx->Const.Program[MESA_SHADER_VERTEX].MaxUniformComponents; + this->Const.MaxVertexTextureImageUnits = ctx->Const.Program[MESA_SHADER_VERTEX].MaxTextureImageUnits; this->Const.MaxCombinedTextureImageUnits = ctx->Const.MaxCombinedTextureImageUnits; - this->Const.MaxTextureImageUnits = ctx->Const.FragmentProgram.MaxTextureImageUnits; - this->Const.MaxFragmentUniformComponents = ctx->Const.FragmentProgram.MaxUniformComponents; + this->Const.MaxTextureImageUnits = ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits; + this->Const.MaxFragmentUniformComponents = ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxUniformComponents; this->Const.MinProgramTexelOffset = ctx->Const.MinProgramTexelOffset; this->Const.MaxProgramTexelOffset = ctx->Const.MaxProgramTexelOffset; this->Const.MaxDrawBuffers = ctx->Const.MaxDrawBuffers; /* 1.50 constants */ - this->Const.MaxVertexOutputComponents = ctx->Const.VertexProgram.MaxOutputComponents; - this->Const.MaxGeometryInputComponents = ctx->Const.GeometryProgram.MaxInputComponents; - this->Const.MaxGeometryOutputComponents = ctx->Const.GeometryProgram.MaxOutputComponents; - this->Const.MaxFragmentInputComponents = ctx->Const.FragmentProgram.MaxInputComponents; - this->Const.MaxGeometryTextureImageUnits = ctx->Const.GeometryProgram.MaxTextureImageUnits; + this->Const.MaxVertexOutputComponents = ctx->Const.Program[MESA_SHADER_VERTEX].MaxOutputComponents; + this->Const.MaxGeometryInputComponents = ctx->Const.Program[MESA_SHADER_GEOMETRY].MaxInputComponents; + this->Const.MaxGeometryOutputComponents = ctx->Const.Program[MESA_SHADER_GEOMETRY].MaxOutputComponents; + this->Const.MaxFragmentInputComponents = ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxInputComponents; + this->Const.MaxGeometryTextureImageUnits = ctx->Const.Program[MESA_SHADER_GEOMETRY].MaxTextureImageUnits; this->Const.MaxGeometryOutputVertices = ctx->Const.MaxGeometryOutputVertices; this->Const.MaxGeometryTotalOutputComponents = ctx->Const.MaxGeometryTotalOutputComponents; - this->Const.MaxGeometryUniformComponents = ctx->Const.GeometryProgram.MaxUniformComponents; + this->Const.MaxGeometryUniformComponents = ctx->Const.Program[MESA_SHADER_GEOMETRY].MaxUniformComponents; - this->Const.MaxVertexAtomicCounters = ctx->Const.VertexProgram.MaxAtomicCounters; - this->Const.MaxGeometryAtomicCounters = ctx->Const.GeometryProgram.MaxAtomicCounters; - this->Const.MaxFragmentAtomicCounters = ctx->Const.FragmentProgram.MaxAtomicCounters; + this->Const.MaxVertexAtomicCounters = ctx->Const.Program[MESA_SHADER_VERTEX].MaxAtomicCounters; + this->Const.MaxGeometryAtomicCounters = ctx->Const.Program[MESA_SHADER_GEOMETRY].MaxAtomicCounters; + this->Const.MaxFragmentAtomicCounters = ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxAtomicCounters; this->Const.MaxCombinedAtomicCounters = ctx->Const.MaxCombinedAtomicCounters; this->Const.MaxAtomicBufferBindings = ctx->Const.MaxAtomicBufferBindings; @@ -331,44 +329,15 @@ _mesa_glsl_parse_state::process_version_directive(YYLTYPE *locp, int version, } } -extern "C" { - -/** - * Translate a GLenum to a short shader stage name for debug printouts and - * error messages. - * - * It recognizes the PROGRAM variants of the names so it can be used - * with a struct gl_program->Target, not just a struct - * gl_shader->Type. - */ -const char * -_mesa_shader_enum_to_string(GLenum type) -{ - switch (type) { - case GL_VERTEX_SHADER: - case GL_VERTEX_PROGRAM_ARB: - return "vertex"; - case GL_FRAGMENT_SHADER: - case GL_FRAGMENT_PROGRAM_ARB: - return "fragment"; - case GL_GEOMETRY_SHADER: - return "geometry"; - default: - assert(!"Should not get here."); - return "unknown"; - } -} - -} /* extern "C" */ /** - * Translate a gl_shader_type to a short shader stage name for debug printouts - * and error messages. + * Translate a gl_shader_stage to a short shader stage name for debug + * printouts and error messages. */ const char * -_mesa_shader_type_to_string(unsigned target) +_mesa_shader_stage_to_string(unsigned stage) { - switch (target) { + switch (stage) { case MESA_SHADER_VERTEX: return "vertex"; case MESA_SHADER_FRAGMENT: return "fragment"; case MESA_SHADER_GEOMETRY: return "geometry"; @@ -543,6 +512,7 @@ static const _mesa_glsl_extension _mesa_glsl_supported_extensions[] = { EXT(ARB_texture_gather, true, false, ARB_texture_gather), EXT(ARB_shader_atomic_counters, true, false, ARB_shader_atomic_counters), EXT(ARB_sample_shading, true, false, ARB_sample_shading), + EXT(AMD_shader_trinary_minmax, true, false, dummy_true), }; #undef EXT @@ -650,11 +620,11 @@ _mesa_glsl_process_extension(const char *name, YYLTYPE *name_locp, if (behavior == extension_require) { _mesa_glsl_error(name_locp, state, fmt, - name, _mesa_shader_type_to_string(state->target)); + name, _mesa_shader_stage_to_string(state->stage)); return false; } else { _mesa_glsl_warning(name_locp, state, fmt, - name, _mesa_shader_type_to_string(state->target)); + name, _mesa_shader_stage_to_string(state->stage)); } } } @@ -1447,7 +1417,7 @@ static void set_shader_inout_layout(struct gl_shader *shader, struct _mesa_glsl_parse_state *state) { - if (shader->Type != GL_GEOMETRY_SHADER) { + if (shader->Stage != MESA_SHADER_GEOMETRY) { /* Should have been prevented by the parser. */ assert(!state->gs_input_prim_type_specified); assert(!state->out_qualifier->flags.i); @@ -1478,7 +1448,7 @@ _mesa_glsl_compile_shader(struct gl_context *ctx, struct gl_shader *shader, bool dump_ast, bool dump_hir) { struct _mesa_glsl_parse_state *state = - new(shader) _mesa_glsl_parse_state(ctx, shader->Type, shader); + new(shader) _mesa_glsl_parse_state(ctx, shader->Stage, shader); const char *source = shader->Source; state->error = glcpp_preprocess(state, &source, &state->info_log, @@ -1515,7 +1485,7 @@ _mesa_glsl_compile_shader(struct gl_context *ctx, struct gl_shader *shader, if (!state->error && !shader->ir->is_empty()) { struct gl_shader_compiler_options *options = - &ctx->ShaderCompilerOptions[_mesa_shader_type_to_index(shader->Type)]; + &ctx->ShaderCompilerOptions[shader->Stage]; /* Do some optimization at compile time to reduce shader IR size * and reduce later work if the same shader is linked multiple times diff --git a/mesalib/src/glsl/glsl_parser_extras.h b/mesalib/src/glsl/glsl_parser_extras.h index 6cfa2d661..21a27c9ea 100644 --- a/mesalib/src/glsl/glsl_parser_extras.h +++ b/mesalib/src/glsl/glsl_parser_extras.h @@ -68,7 +68,7 @@ extern void _mesa_glsl_error(YYLTYPE *locp, _mesa_glsl_parse_state *state, struct _mesa_glsl_parse_state { - _mesa_glsl_parse_state(struct gl_context *_ctx, GLenum target, + _mesa_glsl_parse_state(struct gl_context *_ctx, gl_shader_stage stage, void *mem_ctx); DECLARE_RALLOC_CXX_OPERATORS(_mesa_glsl_parse_state); @@ -169,7 +169,7 @@ struct _mesa_glsl_parse_state { bool es_shader; unsigned language_version; - gl_shader_type target; + gl_shader_stage stage; /** * Number of nested struct_specifier levels @@ -354,6 +354,8 @@ struct _mesa_glsl_parse_state { bool EXT_shader_integer_mix_warn; bool ARB_shader_atomic_counters_enable; bool ARB_shader_atomic_counters_warn; + bool AMD_shader_trinary_minmax_enable; + bool AMD_shader_trinary_minmax_warn; /*@}*/ /** Extensions supported by the OpenGL implementation. */ @@ -425,14 +427,6 @@ extern bool _mesa_glsl_process_extension(const char *name, YYLTYPE *name_locp, YYLTYPE *behavior_locp, _mesa_glsl_parse_state *state); -/** - * Get the textual name of the specified shader target (which is a - * gl_shader_type). - */ -extern const char * -_mesa_shader_type_to_string(unsigned target); - - #endif /* __cplusplus */ @@ -443,8 +437,12 @@ _mesa_shader_type_to_string(unsigned target); extern "C" { #endif +/** + * Get the textual name of the specified shader stage (which is a + * gl_shader_stage). + */ extern const char * -_mesa_shader_enum_to_string(GLenum type); +_mesa_shader_stage_to_string(unsigned stage); extern int glcpp_preprocess(void *ctx, const char **shader, char **info_log, const struct gl_extensions *extensions, struct gl_context *gl_ctx); diff --git a/mesalib/src/glsl/ir.cpp b/mesalib/src/glsl/ir.cpp index 8af58b847..77638ef26 100644 --- a/mesalib/src/glsl/ir.cpp +++ b/mesalib/src/glsl/ir.cpp @@ -1122,27 +1122,31 @@ ir_constant::has_value(const ir_constant *c) const } bool -ir_constant::is_zero() const +ir_constant::is_value(float f, int i) const { if (!this->type->is_scalar() && !this->type->is_vector()) return false; + /* Only accept boolean values for 0/1. */ + if (int(bool(i)) != i && this->type->is_boolean()) + return false; + for (unsigned c = 0; c < this->type->vector_elements; c++) { switch (this->type->base_type) { case GLSL_TYPE_FLOAT: - if (this->value.f[c] != 0.0) + if (this->value.f[c] != f) return false; break; case GLSL_TYPE_INT: - if (this->value.i[c] != 0) + if (this->value.i[c] != i) return false; break; case GLSL_TYPE_UINT: - if (this->value.u[c] != 0) + if (this->value.u[c] != unsigned(i)) return false; break; case GLSL_TYPE_BOOL: - if (this->value.b[c] != false) + if (this->value.b[c] != bool(i)) return false; break; default: @@ -1159,76 +1163,21 @@ ir_constant::is_zero() const } bool -ir_constant::is_one() const +ir_constant::is_zero() const { - if (!this->type->is_scalar() && !this->type->is_vector()) - return false; - - for (unsigned c = 0; c < this->type->vector_elements; c++) { - switch (this->type->base_type) { - case GLSL_TYPE_FLOAT: - if (this->value.f[c] != 1.0) - return false; - break; - case GLSL_TYPE_INT: - if (this->value.i[c] != 1) - return false; - break; - case GLSL_TYPE_UINT: - if (this->value.u[c] != 1) - return false; - break; - case GLSL_TYPE_BOOL: - if (this->value.b[c] != true) - return false; - break; - default: - /* The only other base types are structures, arrays, and samplers. - * Samplers cannot be constants, and the others should have been - * filtered out above. - */ - assert(!"Should not get here."); - return false; - } - } + return is_value(0.0, 0); +} - return true; +bool +ir_constant::is_one() const +{ + return is_value(1.0, 1); } bool ir_constant::is_negative_one() const { - if (!this->type->is_scalar() && !this->type->is_vector()) - return false; - - if (this->type->is_boolean()) - return false; - - for (unsigned c = 0; c < this->type->vector_elements; c++) { - switch (this->type->base_type) { - case GLSL_TYPE_FLOAT: - if (this->value.f[c] != -1.0) - return false; - break; - case GLSL_TYPE_INT: - if (this->value.i[c] != -1) - return false; - break; - case GLSL_TYPE_UINT: - if (int(this->value.u[c]) != -1) - return false; - break; - default: - /* The only other base types are structures, arrays, samplers, and - * booleans. Samplers cannot be constants, and the others should - * have been filtered out above. - */ - assert(!"Should not get here."); - return false; - } - } - - return true; + return is_value(-1.0, -1); } bool @@ -1700,13 +1649,10 @@ modes_match(unsigned a, unsigned b) const char * ir_function_signature::qualifiers_match(exec_list *params) { - exec_list_iterator iter_a = parameters.iterator(); - exec_list_iterator iter_b = params->iterator(); - /* check that the qualifiers match. */ - while (iter_a.has_next()) { - ir_variable *a = (ir_variable *)iter_a.get(); - ir_variable *b = (ir_variable *)iter_b.get(); + foreach_two_lists(a_node, &this->parameters, b_node, params) { + ir_variable *a = (ir_variable *) a_node; + ir_variable *b = (ir_variable *) b_node; if (a->data.read_only != b->data.read_only || !modes_match(a->data.mode, b->data.mode) || @@ -1717,9 +1663,6 @@ ir_function_signature::qualifiers_match(exec_list *params) /* parameter a's qualifiers don't match */ return a->name; } - - iter_a.next(); - iter_b.next(); } return NULL; } @@ -1768,8 +1711,8 @@ ir_rvalue::error_value(void *mem_ctx) void visit_exec_list(exec_list *list, ir_visitor *visitor) { - foreach_iter(exec_list_iterator, iter, *list) { - ((ir_instruction *)iter.get())->accept(visitor); + foreach_list_safe(n, list) { + ((ir_instruction *) n)->accept(visitor); } } @@ -1790,8 +1733,8 @@ steal_memory(ir_instruction *ir, void *new_ctx) */ if (constant != NULL) { if (constant->type->is_record()) { - foreach_iter(exec_list_iterator, iter, constant->components) { - ir_constant *field = (ir_constant *)iter.get(); + foreach_list(n, &constant->components) { + ir_constant *field = (ir_constant *) n; steal_memory(field, ir); } } else if (constant->type->is_array()) { diff --git a/mesalib/src/glsl/ir.h b/mesalib/src/glsl/ir.h index 780959b73..2ae8513a6 100644 --- a/mesalib/src/glsl/ir.h +++ b/mesalib/src/glsl/ir.h @@ -914,14 +914,6 @@ public: } /** - * Get an iterator for the set of function signatures - */ - exec_list_iterator iterator() - { - return signatures.iterator(); - } - - /** * Find a signature that matches a set of actual parameters, taking implicit * conversions into account. Also flags whether the match was exact. */ @@ -1018,14 +1010,6 @@ public: return this; } - /** - * Get an iterator for the instructions of the loop body - */ - exec_list_iterator iterator() - { - return body_instructions.iterator(); - } - /** List of ir_instruction that make up the body of the loop. */ exec_list body_instructions; }; @@ -1521,14 +1505,6 @@ public: virtual ir_visitor_status accept(ir_hierarchical_visitor *); /** - * Get an iterator for the set of acutal parameters - */ - exec_list_iterator iterator() - { - return actual_parameters.iterator(); - } - - /** * Get the name of the function being called. */ const char *callee_name() const @@ -2186,6 +2162,12 @@ public: */ bool has_value(const ir_constant *) const; + /** + * Return true if this ir_constant represents the given value. + * + * For vectors, this checks that each component is the given value. + */ + virtual bool is_value(float f, int i) const; virtual bool is_zero() const; virtual bool is_one() const; virtual bool is_negative_one() const; @@ -2345,7 +2327,7 @@ ir_has_call(ir_instruction *ir); extern void do_set_program_inouts(exec_list *instructions, struct gl_program *prog, - GLenum shader_type); + gl_shader_stage shader_stage); extern char * prototype_string(const glsl_type *return_type, const char *name, diff --git a/mesalib/src/glsl/ir_basic_block.cpp b/mesalib/src/glsl/ir_basic_block.cpp index 2cbc682d4..426fda2f2 100644 --- a/mesalib/src/glsl/ir_basic_block.cpp +++ b/mesalib/src/glsl/ir_basic_block.cpp @@ -58,8 +58,8 @@ void call_for_basic_blocks(exec_list *instructions, ir_instruction *leader = NULL; ir_instruction *last = NULL; - foreach_iter(exec_list_iterator, iter, *instructions) { - ir_instruction *ir = (ir_instruction *)iter.get(); + foreach_list(n, instructions) { + ir_instruction *ir = (ir_instruction *) n; ir_if *ir_if; ir_loop *ir_loop; ir_function *ir_function; @@ -90,10 +90,8 @@ void call_for_basic_blocks(exec_list *instructions, * and the body of main(). Perhaps those instructions ought * to live inside of main(). */ - foreach_iter(exec_list_iterator, fun_iter, *ir_function) { - ir_function_signature *ir_sig; - - ir_sig = (ir_function_signature *)fun_iter.get(); + foreach_list(func_node, &ir_function->signatures) { + ir_function_signature *ir_sig = (ir_function_signature *) func_node; call_for_basic_blocks(&ir_sig->body, callback, data); } diff --git a/mesalib/src/glsl/ir_builder.cpp b/mesalib/src/glsl/ir_builder.cpp index 6fd58de0e..1e0dd5419 100644 --- a/mesalib/src/glsl/ir_builder.cpp +++ b/mesalib/src/glsl/ir_builder.cpp @@ -211,6 +211,16 @@ ir_expression *sub(operand a, operand b) return expr(ir_binop_sub, a, b); } +ir_expression *min2(operand a, operand b) +{ + return expr(ir_binop_min, a, b); +} + +ir_expression *max2(operand a, operand b) +{ + return expr(ir_binop_max, a, b); +} + ir_expression *mul(operand a, operand b) { return expr(ir_binop_mul, a, b); diff --git a/mesalib/src/glsl/ir_builder.h b/mesalib/src/glsl/ir_builder.h index 52cc2168f..f00e6f3b3 100644..100755 --- a/mesalib/src/glsl/ir_builder.h +++ b/mesalib/src/glsl/ir_builder.h @@ -184,7 +184,10 @@ ir_expression *i2b(operand a); ir_expression *f2b(operand a); ir_expression *b2f(operand a); -ir_expression *fma_mesa(operand a, operand b, operand c); +ir_expression *min2(operand a, operand b); +ir_expression *max2(operand a, operand b); + +ir_expression *fma(operand a, operand b, operand c); ir_expression *lrp(operand x, operand y, operand a); ir_expression *csel(operand a, operand b, operand c); ir_expression *bitfield_insert(operand a, operand b, operand c, operand d); diff --git a/mesalib/src/glsl/ir_clone.cpp b/mesalib/src/glsl/ir_clone.cpp index 4e5cf68ca..cb732a51a 100644 --- a/mesalib/src/glsl/ir_clone.cpp +++ b/mesalib/src/glsl/ir_clone.cpp @@ -123,13 +123,13 @@ ir_if::clone(void *mem_ctx, struct hash_table *ht) const { ir_if *new_if = new(mem_ctx) ir_if(this->condition->clone(mem_ctx, ht)); - foreach_iter(exec_list_iterator, iter, this->then_instructions) { - ir_instruction *ir = (ir_instruction *)iter.get(); + foreach_list(n, &this->then_instructions) { + ir_instruction *ir = (ir_instruction *) n; new_if->then_instructions.push_tail(ir->clone(mem_ctx, ht)); } - foreach_iter(exec_list_iterator, iter, this->else_instructions) { - ir_instruction *ir = (ir_instruction *)iter.get(); + foreach_list(n, &this->else_instructions) { + ir_instruction *ir = (ir_instruction *) n; new_if->else_instructions.push_tail(ir->clone(mem_ctx, ht)); } @@ -141,8 +141,8 @@ ir_loop::clone(void *mem_ctx, struct hash_table *ht) const { ir_loop *new_loop = new(mem_ctx) ir_loop(); - foreach_iter(exec_list_iterator, iter, this->body_instructions) { - ir_instruction *ir = (ir_instruction *)iter.get(); + foreach_list(n, &this->body_instructions) { + ir_instruction *ir = (ir_instruction *) n; new_loop->body_instructions.push_tail(ir->clone(mem_ctx, ht)); } @@ -158,8 +158,8 @@ ir_call::clone(void *mem_ctx, struct hash_table *ht) const exec_list new_parameters; - foreach_iter(exec_list_iterator, iter, this->actual_parameters) { - ir_instruction *ir = (ir_instruction *)iter.get(); + foreach_list(n, &this->actual_parameters) { + ir_instruction *ir = (ir_instruction *) n; new_parameters.push_tail(ir->clone(mem_ctx, ht)); } diff --git a/mesalib/src/glsl/ir_expression_flattening.cpp b/mesalib/src/glsl/ir_expression_flattening.cpp index b44e68ca3..c1cadb122 100644 --- a/mesalib/src/glsl/ir_expression_flattening.cpp +++ b/mesalib/src/glsl/ir_expression_flattening.cpp @@ -59,8 +59,8 @@ do_expression_flattening(exec_list *instructions, { ir_expression_flattening_visitor v(predicate); - foreach_iter(exec_list_iterator, iter, *instructions) { - ir_instruction *ir = (ir_instruction *)iter.get(); + foreach_list(n, instructions) { + ir_instruction *ir = (ir_instruction *) n; ir->accept(&v); } diff --git a/mesalib/src/glsl/ir_function.cpp b/mesalib/src/glsl/ir_function.cpp index bd5318d23..40cf5894a 100644 --- a/mesalib/src/glsl/ir_function.cpp +++ b/mesalib/src/glsl/ir_function.cpp @@ -141,9 +141,8 @@ ir_function::matching_signature(_mesa_glsl_parse_state *state, * multiple ways to apply these conversions to the actual arguments of a * call such that the call can be made to match multiple signatures." */ - foreach_iter(exec_list_iterator, iter, signatures) { - ir_function_signature *const sig = - (ir_function_signature *) iter.get(); + foreach_list(n, &this->signatures) { + ir_function_signature *const sig = (ir_function_signature *) n; /* Skip over any built-ins that aren't available in this shader. */ if (sig->is_builtin() && !sig->is_builtin_available(state)) @@ -212,9 +211,8 @@ ir_function_signature * ir_function::exact_matching_signature(_mesa_glsl_parse_state *state, const exec_list *actual_parameters) { - foreach_iter(exec_list_iterator, iter, signatures) { - ir_function_signature *const sig = - (ir_function_signature *) iter.get(); + foreach_list(n, &this->signatures) { + ir_function_signature *const sig = (ir_function_signature *) n; /* Skip over any built-ins that aren't available in this shader. */ if (sig->is_builtin() && !sig->is_builtin_available(state)) diff --git a/mesalib/src/glsl/ir_print_visitor.cpp b/mesalib/src/glsl/ir_print_visitor.cpp index 01c5f7f1c..935782184 100644 --- a/mesalib/src/glsl/ir_print_visitor.cpp +++ b/mesalib/src/glsl/ir_print_visitor.cpp @@ -61,8 +61,8 @@ _mesa_print_ir(exec_list *instructions, } printf("(\n"); - foreach_iter(exec_list_iterator, iter, *instructions) { - ir_instruction *ir = (ir_instruction *)iter.get(); + foreach_list(n, instructions) { + ir_instruction *ir = (ir_instruction *) n; ir->print(); if (ir->ir_type != ir_type_function) printf("\n"); @@ -179,8 +179,8 @@ void ir_print_visitor::visit(ir_function_signature *ir) printf("(parameters\n"); indentation++; - foreach_iter(exec_list_iterator, iter, ir->parameters) { - ir_variable *const inst = (ir_variable *) iter.get(); + foreach_list(n, &ir->parameters) { + ir_variable *const inst = (ir_variable *) n; indent(); inst->accept(this); @@ -196,8 +196,8 @@ void ir_print_visitor::visit(ir_function_signature *ir) printf("(\n"); indentation++; - foreach_iter(exec_list_iterator, iter, ir->body) { - ir_instruction *const inst = (ir_instruction *) iter.get(); + foreach_list(n, &ir->body) { + ir_instruction *const inst = (ir_instruction *) n; indent(); inst->accept(this); @@ -215,8 +215,8 @@ void ir_print_visitor::visit(ir_function *ir) { printf("(function %s\n", ir->name); indentation++; - foreach_iter(exec_list_iterator, iter, *ir) { - ir_function_signature *const sig = (ir_function_signature *) iter.get(); + foreach_list(n, &ir->signatures) { + ir_function_signature *const sig = (ir_function_signature *) n; indent(); sig->accept(this); printf("\n"); @@ -440,10 +440,10 @@ ir_print_visitor::visit(ir_call *ir) if (ir->return_deref) ir->return_deref->accept(this); printf(" ("); - foreach_iter(exec_list_iterator, iter, *ir) { - ir_instruction *const inst = (ir_instruction *) iter.get(); + foreach_list(n, &ir->actual_parameters) { + ir_rvalue *const param = (ir_rvalue *) n; - inst->accept(this); + param->accept(this); } printf("))\n"); } @@ -487,8 +487,8 @@ ir_print_visitor::visit(ir_if *ir) printf("(\n"); indentation++; - foreach_iter(exec_list_iterator, iter, ir->then_instructions) { - ir_instruction *const inst = (ir_instruction *) iter.get(); + foreach_list(n, &ir->then_instructions) { + ir_instruction *const inst = (ir_instruction *) n; indent(); inst->accept(this); @@ -504,8 +504,8 @@ ir_print_visitor::visit(ir_if *ir) printf("(\n"); indentation++; - foreach_iter(exec_list_iterator, iter, ir->else_instructions) { - ir_instruction *const inst = (ir_instruction *) iter.get(); + foreach_list(n, &ir->else_instructions) { + ir_instruction *const inst = (ir_instruction *) n; indent(); inst->accept(this); @@ -526,8 +526,8 @@ ir_print_visitor::visit(ir_loop *ir) printf("(loop (\n"); indentation++; - foreach_iter(exec_list_iterator, iter, ir->body_instructions) { - ir_instruction *const inst = (ir_instruction *) iter.get(); + foreach_list(n, &ir->body_instructions) { + ir_instruction *const inst = (ir_instruction *) n; indent(); inst->accept(this); diff --git a/mesalib/src/glsl/ir_reader.cpp b/mesalib/src/glsl/ir_reader.cpp index 7970112ec..28923f3b8 100644 --- a/mesalib/src/glsl/ir_reader.cpp +++ b/mesalib/src/glsl/ir_reader.cpp @@ -170,8 +170,8 @@ ir_reader::scan_for_prototypes(exec_list *instructions, s_expression *expr) return; } - foreach_iter(exec_list_iterator, it, list->subexpressions) { - s_list *sub = SX_AS_LIST(it.get()); + foreach_list(n, &list->subexpressions) { + s_list *sub = SX_AS_LIST(n); if (sub == NULL) continue; // not a (function ...); ignore it. @@ -205,11 +205,12 @@ ir_reader::read_function(s_expression *expr, bool skip_body) assert(added); } - exec_list_iterator it = ((s_list *) expr)->subexpressions.iterator(); - it.next(); // skip "function" tag - it.next(); // skip function name - for (/* nothing */; it.has_next(); it.next()) { - s_expression *s_sig = (s_expression *) it.get(); + /* Skip over "function" tag and function name (which are guaranteed to be + * present by the above PARTIAL_MATCH call). + */ + exec_node *node = ((s_list *) expr)->subexpressions.head->next->next; + for (/* nothing */; !node->is_tail_sentinel(); node = node->next) { + s_expression *s_sig = (s_expression *) node; read_function_sig(f, s_sig, skip_body); } return added ? f : NULL; @@ -249,9 +250,10 @@ ir_reader::read_function_sig(ir_function *f, s_expression *expr, bool skip_body) exec_list hir_parameters; state->symbols->push_scope(); - exec_list_iterator it = paramlist->subexpressions.iterator(); - for (it.next() /* skip "parameters" */; it.has_next(); it.next()) { - ir_variable *var = read_declaration((s_expression *) it.get()); + /* Skip over the "parameters" tag. */ + exec_node *node = paramlist->subexpressions.head->next; + for (/* nothing */; !node->is_tail_sentinel(); node = node->next) { + ir_variable *var = read_declaration((s_expression *) node); if (var == NULL) return; @@ -315,8 +317,8 @@ ir_reader::read_instructions(exec_list *instructions, s_expression *expr, return; } - foreach_iter(exec_list_iterator, it, list->subexpressions) { - s_expression *sub = (s_expression*) it.get(); + foreach_list(n, &list->subexpressions) { + s_expression *sub = (s_expression *) n; ir_instruction *ir = read_instruction(sub, loop_ctx); if (ir != NULL) { /* Global variable declarations should be moved to the top, before @@ -403,8 +405,8 @@ ir_reader::read_declaration(s_expression *expr) ir_variable *var = new(mem_ctx) ir_variable(type, s_name->value(), ir_var_auto); - foreach_iter(exec_list_iterator, it, s_quals->subexpressions) { - s_symbol *qualifier = SX_AS_SYMBOL(it.get()); + foreach_list(n, &s_quals->subexpressions) { + s_symbol *qualifier = SX_AS_SYMBOL(n); if (qualifier == NULL) { ir_read_error(expr, "qualifier list must contain only symbols"); return NULL; @@ -656,8 +658,8 @@ ir_reader::read_call(s_expression *expr) exec_list parameters; - foreach_iter(exec_list_iterator, it, params->subexpressions) { - s_expression *expr = (s_expression*) it.get(); + foreach_list(n, ¶ms->subexpressions) { + s_expression *expr = (s_expression *) n; ir_rvalue *param = read_rvalue(expr); if (param == NULL) { ir_read_error(expr, "when reading parameter to function call"); @@ -796,8 +798,8 @@ ir_reader::read_constant(s_expression *expr) if (type->is_array()) { unsigned elements_supplied = 0; exec_list elements; - foreach_iter(exec_list_iterator, it, values->subexpressions) { - s_expression *elt = (s_expression *) it.get(); + foreach_list(n, &values->subexpressions) { + s_expression *elt = (s_expression *) n; ir_constant *ir_elt = read_constant(elt); if (ir_elt == NULL) return NULL; @@ -817,13 +819,13 @@ ir_reader::read_constant(s_expression *expr) // Read in list of values (at most 16). unsigned k = 0; - foreach_iter(exec_list_iterator, it, values->subexpressions) { + foreach_list(n, &values->subexpressions) { if (k >= 16) { ir_read_error(values, "expected at most 16 numbers"); return NULL; } - s_expression *expr = (s_expression*) it.get(); + s_expression *expr = (s_expression *) n; if (type->base_type == GLSL_TYPE_FLOAT) { s_number *value = SX_AS_NUMBER(expr); diff --git a/mesalib/src/glsl/ir_rvalue_visitor.cpp b/mesalib/src/glsl/ir_rvalue_visitor.cpp index 9d8ccd94a..fcbe9448d 100644 --- a/mesalib/src/glsl/ir_rvalue_visitor.cpp +++ b/mesalib/src/glsl/ir_rvalue_visitor.cpp @@ -123,8 +123,8 @@ ir_rvalue_base_visitor::rvalue_visit(ir_assignment *ir) ir_visitor_status ir_rvalue_base_visitor::rvalue_visit(ir_call *ir) { - foreach_iter(exec_list_iterator, iter, *ir) { - ir_rvalue *param = (ir_rvalue *)iter.get(); + foreach_list_safe(n, &ir->actual_parameters) { + ir_rvalue *param = (ir_rvalue *) n; ir_rvalue *new_param = param; handle_rvalue(&new_param); diff --git a/mesalib/src/glsl/ir_set_program_inouts.cpp b/mesalib/src/glsl/ir_set_program_inouts.cpp index 0b49eb2b6..5163eb215 100644 --- a/mesalib/src/glsl/ir_set_program_inouts.cpp +++ b/mesalib/src/glsl/ir_set_program_inouts.cpp @@ -46,10 +46,11 @@ namespace { class ir_set_program_inouts_visitor : public ir_hierarchical_visitor { public: - ir_set_program_inouts_visitor(struct gl_program *prog, GLenum shader_type) + ir_set_program_inouts_visitor(struct gl_program *prog, + gl_shader_stage shader_stage) { this->prog = prog; - this->shader_type = shader_type; + this->shader_stage = shader_stage; } ~ir_set_program_inouts_visitor() { @@ -67,7 +68,7 @@ private: bool try_mark_partial_variable(ir_variable *var, ir_rvalue *index); struct gl_program *prog; - GLenum shader_type; + gl_shader_stage shader_stage; }; } /* anonymous namespace */ @@ -124,13 +125,13 @@ void ir_set_program_inouts_visitor::mark_whole_variable(ir_variable *var) { const glsl_type *type = var->type; - if (this->shader_type == GL_GEOMETRY_SHADER && + if (this->shader_stage == MESA_SHADER_GEOMETRY && var->data.mode == ir_var_shader_in && type->is_array()) { type = type->fields.array; } mark(this->prog, var, 0, type->count_attribute_slots(), - this->shader_type == GL_FRAGMENT_SHADER); + this->shader_stage == MESA_SHADER_FRAGMENT); } /* Default handler: Mark all the locations in the variable as used. */ @@ -163,7 +164,7 @@ ir_set_program_inouts_visitor::try_mark_partial_variable(ir_variable *var, { const glsl_type *type = var->type; - if (this->shader_type == GL_GEOMETRY_SHADER && + if (this->shader_stage == MESA_SHADER_GEOMETRY && var->data.mode == ir_var_shader_in) { /* The only geometry shader input that is not an array is * gl_PrimitiveIDIn, and in that case, this code will never be reached, @@ -227,7 +228,7 @@ ir_set_program_inouts_visitor::try_mark_partial_variable(ir_variable *var, } mark(this->prog, var, index_as_constant->value.u[0] * elem_width, - elem_width, this->shader_type == GL_FRAGMENT_SHADER); + elem_width, this->shader_stage == MESA_SHADER_FRAGMENT); return true; } @@ -245,7 +246,7 @@ ir_set_program_inouts_visitor::visit_enter(ir_dereference_array *ir) */ if (ir_dereference_variable * const deref_var = inner_array->array->as_dereference_variable()) { - if (this->shader_type == GL_GEOMETRY_SHADER && + if (this->shader_stage == MESA_SHADER_GEOMETRY && deref_var->var->data.mode == ir_var_shader_in) { /* foo is a geometry shader input, so i is the vertex, and j the * part of the input we're accessing. @@ -264,7 +265,7 @@ ir_set_program_inouts_visitor::visit_enter(ir_dereference_array *ir) } else if (ir_dereference_variable * const deref_var = ir->array->as_dereference_variable()) { /* ir => foo[i], where foo is a variable. */ - if (this->shader_type == GL_GEOMETRY_SHADER && + if (this->shader_stage == MESA_SHADER_GEOMETRY && deref_var->var->data.mode == ir_var_shader_in) { /* foo is a geometry shader input, so i is the vertex, and we're * accessing the entire input. @@ -304,7 +305,7 @@ ir_set_program_inouts_visitor::visit_enter(ir_function_signature *ir) ir_visitor_status ir_set_program_inouts_visitor::visit_enter(ir_expression *ir) { - if (this->shader_type == GL_FRAGMENT_SHADER && + if (this->shader_stage == MESA_SHADER_FRAGMENT && ir->operation == ir_unop_dFdy) { gl_fragment_program *fprog = (gl_fragment_program *) prog; fprog->UsesDFdy = true; @@ -316,7 +317,7 @@ ir_visitor_status ir_set_program_inouts_visitor::visit_enter(ir_discard *) { /* discards are only allowed in fragment shaders. */ - assert(this->shader_type == GL_FRAGMENT_SHADER); + assert(this->shader_stage == MESA_SHADER_FRAGMENT); gl_fragment_program *fprog = (gl_fragment_program *) prog; fprog->UsesKill = true; @@ -334,14 +335,14 @@ ir_set_program_inouts_visitor::visit_enter(ir_texture *ir) void do_set_program_inouts(exec_list *instructions, struct gl_program *prog, - GLenum shader_type) + gl_shader_stage shader_stage) { - ir_set_program_inouts_visitor v(prog, shader_type); + ir_set_program_inouts_visitor v(prog, shader_stage); prog->InputsRead = 0; prog->OutputsWritten = 0; prog->SystemValuesRead = 0; - if (shader_type == GL_FRAGMENT_SHADER) { + if (shader_stage == MESA_SHADER_FRAGMENT) { gl_fragment_program *fprog = (gl_fragment_program *) prog; memset(fprog->InterpQualifier, 0, sizeof(fprog->InterpQualifier)); fprog->IsCentroid = 0; diff --git a/mesalib/src/glsl/ir_uniform.h b/mesalib/src/glsl/ir_uniform.h index 13faab7c0..f678c2c5c 100644 --- a/mesalib/src/glsl/ir_uniform.h +++ b/mesalib/src/glsl/ir_uniform.h @@ -116,7 +116,7 @@ struct gl_uniform_storage { * Whether this sampler is used in this shader stage. */ bool active; - } sampler[MESA_SHADER_TYPES]; + } sampler[MESA_SHADER_STAGES]; /** * Storage used by the driver for the uniform diff --git a/mesalib/src/glsl/ir_validate.cpp b/mesalib/src/glsl/ir_validate.cpp index 4bbb3ce65..527acea4c 100644 --- a/mesalib/src/glsl/ir_validate.cpp +++ b/mesalib/src/glsl/ir_validate.cpp @@ -813,8 +813,8 @@ validate_ir_tree(exec_list *instructions) v.run(instructions); - foreach_iter(exec_list_iterator, iter, *instructions) { - ir_instruction *ir = (ir_instruction *)iter.get(); + foreach_list(n, instructions) { + ir_instruction *ir = (ir_instruction *) n; visit_tree(ir, check_node_type, NULL); } diff --git a/mesalib/src/glsl/link_atomics.cpp b/mesalib/src/glsl/link_atomics.cpp index 603329c50..db9c53965 100644 --- a/mesalib/src/glsl/link_atomics.cpp +++ b/mesalib/src/glsl/link_atomics.cpp @@ -64,7 +64,7 @@ namespace { active_atomic_counter *counters; unsigned num_counters; - unsigned stage_references[MESA_SHADER_TYPES]; + unsigned stage_references[MESA_SHADER_STAGES]; unsigned size; }; @@ -96,7 +96,7 @@ namespace { *num_buffers = 0; - for (unsigned i = 0; i < MESA_SHADER_TYPES; ++i) { + for (unsigned i = 0; i < MESA_SHADER_STAGES; ++i) { struct gl_shader *sh = prog->_LinkedShaders[i]; if (sh == NULL) continue; @@ -199,7 +199,7 @@ link_assign_atomic_counter_resources(struct gl_context *ctx, } /* Assign stage-specific fields. */ - for (unsigned j = 0; j < MESA_SHADER_TYPES; ++j) + for (unsigned j = 0; j < MESA_SHADER_STAGES; ++j) mab.StageReferences[j] = (ab.stage_references[j] ? GL_TRUE : GL_FALSE); @@ -214,23 +214,11 @@ void link_check_atomic_counter_resources(struct gl_context *ctx, struct gl_shader_program *prog) { - const unsigned max_atomic_counters[] = { - ctx->Const.VertexProgram.MaxAtomicCounters, - ctx->Const.GeometryProgram.MaxAtomicCounters, - ctx->Const.FragmentProgram.MaxAtomicCounters - }; - STATIC_ASSERT(Elements(max_atomic_counters) == MESA_SHADER_TYPES); - const unsigned max_atomic_buffers[] = { - ctx->Const.VertexProgram.MaxAtomicBuffers, - ctx->Const.GeometryProgram.MaxAtomicBuffers, - ctx->Const.FragmentProgram.MaxAtomicBuffers - }; - STATIC_ASSERT(Elements(max_atomic_buffers) == MESA_SHADER_TYPES); unsigned num_buffers; active_atomic_buffer *const abs = find_active_atomic_counters(ctx, prog, &num_buffers); - unsigned atomic_counters[MESA_SHADER_TYPES] = {}; - unsigned atomic_buffers[MESA_SHADER_TYPES] = {}; + unsigned atomic_counters[MESA_SHADER_STAGES] = {}; + unsigned atomic_buffers[MESA_SHADER_STAGES] = {}; unsigned total_atomic_counters = 0; unsigned total_atomic_buffers = 0; @@ -243,7 +231,7 @@ link_check_atomic_counter_resources(struct gl_context *ctx, if (abs[i].size == 0) continue; - for (unsigned j = 0; j < MESA_SHADER_TYPES; ++j) { + for (unsigned j = 0; j < MESA_SHADER_STAGES; ++j) { const unsigned n = abs[i].stage_references[j]; if (n) { @@ -256,14 +244,14 @@ link_check_atomic_counter_resources(struct gl_context *ctx, } /* Check that they are within the supported limits. */ - for (unsigned i = 0; i < MESA_SHADER_TYPES; i++) { - if (atomic_counters[i] > max_atomic_counters[i]) + for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) { + if (atomic_counters[i] > ctx->Const.Program[i].MaxAtomicCounters) linker_error(prog, "Too many %s shader atomic counters", - _mesa_shader_type_to_string(i)); + _mesa_shader_stage_to_string(i)); - if (atomic_buffers[i] > max_atomic_buffers[i]) + if (atomic_buffers[i] > ctx->Const.Program[i].MaxAtomicBuffers) linker_error(prog, "Too many %s shader atomic counter buffers", - _mesa_shader_type_to_string(i)); + _mesa_shader_stage_to_string(i)); } if (total_atomic_counters > ctx->Const.MaxCombinedAtomicCounters) diff --git a/mesalib/src/glsl/link_interface_blocks.cpp b/mesalib/src/glsl/link_interface_blocks.cpp index 476963642..52552cc68 100644 --- a/mesalib/src/glsl/link_interface_blocks.cpp +++ b/mesalib/src/glsl/link_interface_blocks.cpp @@ -313,7 +313,7 @@ validate_interstage_inout_blocks(struct gl_shader_program *prog, const gl_shader *consumer) { interface_block_definitions definitions; - const bool extra_array_level = consumer->Type == GL_GEOMETRY_SHADER; + const bool extra_array_level = consumer->Stage == MESA_SHADER_GEOMETRY; /* Add input interfaces from the consumer to the symbol table. */ foreach_list(node, consumer->ir) { diff --git a/mesalib/src/glsl/link_uniform_initializers.cpp b/mesalib/src/glsl/link_uniform_initializers.cpp index 04daa1760..7d5c1472d 100644 --- a/mesalib/src/glsl/link_uniform_initializers.cpp +++ b/mesalib/src/glsl/link_uniform_initializers.cpp @@ -106,7 +106,7 @@ set_uniform_binding(void *mem_ctx, gl_shader_program *prog, storage->storage[i].i = binding + i; } - for (int sh = 0; sh < MESA_SHADER_TYPES; sh++) { + for (int sh = 0; sh < MESA_SHADER_STAGES; sh++) { gl_shader *shader = prog->_LinkedShaders[sh]; if (shader && storage->sampler[sh].active) { @@ -119,7 +119,7 @@ set_uniform_binding(void *mem_ctx, gl_shader_program *prog, } } else if (storage->block_index != -1) { /* This is a field of a UBO. val is the binding index. */ - for (int i = 0; i < MESA_SHADER_TYPES; i++) { + for (int i = 0; i < MESA_SHADER_STAGES; i++) { int stage_index = prog->UniformBlockStageIndex[i][storage->block_index]; if (stage_index != -1) { @@ -194,7 +194,7 @@ set_uniform_initializer(void *mem_ctx, gl_shader_program *prog, val->type->components()); if (storage->type->is_sampler()) { - for (int sh = 0; sh < MESA_SHADER_TYPES; sh++) { + for (int sh = 0; sh < MESA_SHADER_STAGES; sh++) { gl_shader *shader = prog->_LinkedShaders[sh]; if (shader && storage->sampler[sh].active) { @@ -215,7 +215,7 @@ link_set_uniform_initializers(struct gl_shader_program *prog) { void *mem_ctx = NULL; - for (unsigned int i = 0; i < MESA_SHADER_TYPES; i++) { + for (unsigned int i = 0; i < MESA_SHADER_STAGES; i++) { struct gl_shader *shader = prog->_LinkedShaders[i]; if (shader == NULL) diff --git a/mesalib/src/glsl/link_uniforms.cpp b/mesalib/src/glsl/link_uniforms.cpp index 1cbe80b2e..2255f7e6e 100644 --- a/mesalib/src/glsl/link_uniforms.cpp +++ b/mesalib/src/glsl/link_uniforms.cpp @@ -356,9 +356,9 @@ public: { } - void start_shader(gl_shader_type shader_type) + void start_shader(gl_shader_stage shader_type) { - assert(shader_type < MESA_SHADER_TYPES); + assert(shader_type < MESA_SHADER_STAGES); this->shader_type = shader_type; this->shader_samplers_used = 0; @@ -429,7 +429,7 @@ public: int ubo_block_index; int ubo_byte_offset; bool ubo_row_major; - gl_shader_type shader_type; + gl_shader_stage shader_type; private: void handle_samplers(const glsl_type *base_type, @@ -741,7 +741,7 @@ link_assign_uniform_locations(struct gl_shader_program *prog) * glGetUniformLocation. */ count_uniform_size uniform_size(prog->UniformHash); - for (unsigned i = 0; i < MESA_SHADER_TYPES; i++) { + for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) { struct gl_shader *sh = prog->_LinkedShaders[i]; if (sh == NULL) @@ -809,11 +809,11 @@ link_assign_uniform_locations(struct gl_shader_program *prog) parcel_out_uniform_storage parcel(prog->UniformHash, uniforms, data); - for (unsigned i = 0; i < MESA_SHADER_TYPES; i++) { + for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) { if (prog->_LinkedShaders[i] == NULL) continue; - parcel.start_shader((gl_shader_type)i); + parcel.start_shader((gl_shader_stage)i); foreach_list(node, prog->_LinkedShaders[i]->ir) { ir_variable *const var = ((ir_instruction *) node)->as_variable(); diff --git a/mesalib/src/glsl/link_varyings.cpp b/mesalib/src/glsl/link_varyings.cpp index 98f902ca4..c925c00e3 100644 --- a/mesalib/src/glsl/link_varyings.cpp +++ b/mesalib/src/glsl/link_varyings.cpp @@ -48,13 +48,13 @@ static void cross_validate_types_and_qualifiers(struct gl_shader_program *prog, const ir_variable *input, const ir_variable *output, - GLenum consumer_type, - GLenum producer_type) + gl_shader_stage consumer_stage, + gl_shader_stage producer_stage) { /* Check that the types match between stages. */ const glsl_type *type_to_match = input->type; - if (consumer_type == GL_GEOMETRY_SHADER) { + if (consumer_stage == MESA_SHADER_GEOMETRY) { assert(type_to_match->is_array()); /* Enforced by ast_to_hir */ type_to_match = type_to_match->element_type(); } @@ -82,10 +82,10 @@ cross_validate_types_and_qualifiers(struct gl_shader_program *prog, linker_error(prog, "%s shader output `%s' declared as type `%s', " "but %s shader input declared as type `%s'\n", - _mesa_shader_enum_to_string(producer_type), + _mesa_shader_stage_to_string(producer_stage), output->name, output->type->name, - _mesa_shader_enum_to_string(consumer_type), + _mesa_shader_stage_to_string(consumer_stage), input->type->name); return; } @@ -97,10 +97,10 @@ cross_validate_types_and_qualifiers(struct gl_shader_program *prog, linker_error(prog, "%s shader output `%s' %s centroid qualifier, " "but %s shader input %s centroid qualifier\n", - _mesa_shader_enum_to_string(producer_type), + _mesa_shader_stage_to_string(producer_stage), output->name, (output->data.centroid) ? "has" : "lacks", - _mesa_shader_enum_to_string(consumer_type), + _mesa_shader_stage_to_string(consumer_stage), (input->data.centroid) ? "has" : "lacks"); return; } @@ -109,10 +109,10 @@ cross_validate_types_and_qualifiers(struct gl_shader_program *prog, linker_error(prog, "%s shader output `%s' %s sample qualifier, " "but %s shader input %s sample qualifier\n", - _mesa_shader_enum_to_string(producer_type), + _mesa_shader_stage_to_string(producer_stage), output->name, (output->data.sample) ? "has" : "lacks", - _mesa_shader_enum_to_string(consumer_type), + _mesa_shader_stage_to_string(consumer_stage), (input->data.sample) ? "has" : "lacks"); return; } @@ -121,10 +121,10 @@ cross_validate_types_and_qualifiers(struct gl_shader_program *prog, linker_error(prog, "%s shader output `%s' %s invariant qualifier, " "but %s shader input %s invariant qualifier\n", - _mesa_shader_enum_to_string(producer_type), + _mesa_shader_stage_to_string(producer_stage), output->name, (output->data.invariant) ? "has" : "lacks", - _mesa_shader_enum_to_string(consumer_type), + _mesa_shader_stage_to_string(consumer_stage), (input->data.invariant) ? "has" : "lacks"); return; } @@ -135,10 +135,10 @@ cross_validate_types_and_qualifiers(struct gl_shader_program *prog, "interpolation qualifier, " "but %s shader input specifies %s " "interpolation qualifier\n", - _mesa_shader_enum_to_string(producer_type), + _mesa_shader_stage_to_string(producer_stage), output->name, interpolation_string(output->data.interpolation), - _mesa_shader_enum_to_string(consumer_type), + _mesa_shader_stage_to_string(consumer_stage), interpolation_string(input->data.interpolation)); return; } @@ -152,16 +152,16 @@ cross_validate_front_and_back_color(struct gl_shader_program *prog, const ir_variable *input, const ir_variable *front_color, const ir_variable *back_color, - GLenum consumer_type, - GLenum producer_type) + gl_shader_stage consumer_stage, + gl_shader_stage producer_stage) { if (front_color != NULL && front_color->data.assigned) cross_validate_types_and_qualifiers(prog, input, front_color, - consumer_type, producer_type); + consumer_stage, producer_stage); if (back_color != NULL && back_color->data.assigned) cross_validate_types_and_qualifiers(prog, input, back_color, - consumer_type, producer_type); + consumer_stage, producer_stage); } /** @@ -208,7 +208,7 @@ cross_validate_outputs_to_inputs(struct gl_shader_program *prog, cross_validate_front_and_back_color(prog, input, front_color, back_color, - consumer->Type, producer->Type); + consumer->Stage, producer->Stage); } else if (strcmp(input->name, "gl_SecondaryColor") == 0 && input->data.used) { const ir_variable *const front_color = parameters.get_variable("gl_FrontSecondaryColor"); @@ -218,12 +218,12 @@ cross_validate_outputs_to_inputs(struct gl_shader_program *prog, cross_validate_front_and_back_color(prog, input, front_color, back_color, - consumer->Type, producer->Type); + consumer->Stage, producer->Stage); } else { ir_variable *const output = parameters.get_variable(input->name); if (output != NULL) { cross_validate_types_and_qualifiers(prog, input, output, - consumer->Type, producer->Type); + consumer->Stage, producer->Stage); } } } @@ -943,10 +943,10 @@ varying_matches::match_comparator(const void *x_generic, const void *y_generic) * varyings, but excludes variables such as gl_FrontFacing and gl_FragCoord. */ static bool -is_varying_var(GLenum shaderType, const ir_variable *var) +is_varying_var(gl_shader_stage stage, const ir_variable *var) { /* Only fragment shaders will take a varying variable as an input */ - if (shaderType == GL_FRAGMENT_SHADER && + if (stage == MESA_SHADER_FRAGMENT && var->data.mode == ir_var_shader_in) { switch (var->data.location) { case VARYING_SLOT_POS: @@ -1072,7 +1072,7 @@ assign_varying_locations(struct gl_context *ctx, const unsigned producer_base = VARYING_SLOT_VAR0; const unsigned consumer_base = VARYING_SLOT_VAR0; varying_matches matches(ctx->Const.DisableVaryingPacking, - consumer && consumer->Type == GL_FRAGMENT_SHADER); + consumer && consumer->Stage == MESA_SHADER_FRAGMENT); hash_table *tfeedback_candidates = hash_table_ctor(0, hash_table_string_hash, hash_table_string_compare); hash_table *consumer_inputs @@ -1217,9 +1217,9 @@ assign_varying_locations(struct gl_context *ctx, linker_error(prog, "%s shader varying %s not written " "by %s shader\n.", - _mesa_shader_enum_to_string(consumer->Type), + _mesa_shader_stage_to_string(consumer->Stage), var->name, - _mesa_shader_enum_to_string(producer->Type)); + _mesa_shader_stage_to_string(producer->Stage)); } /* An 'in' variable is only really a shader input if its @@ -1244,24 +1244,14 @@ check_against_output_limit(struct gl_context *ctx, ir_variable *const var = ((ir_instruction *) node)->as_variable(); if (var && var->data.mode == ir_var_shader_out && - is_varying_var(producer->Type, var)) { + is_varying_var(producer->Stage, var)) { output_vectors += var->type->count_attribute_slots(); } } - unsigned max_output_components; - switch (producer->Type) { - case GL_VERTEX_SHADER: - max_output_components = ctx->Const.VertexProgram.MaxOutputComponents; - break; - case GL_GEOMETRY_SHADER: - max_output_components = ctx->Const.GeometryProgram.MaxOutputComponents; - break; - case GL_FRAGMENT_SHADER: - default: - assert(!"Should not get here."); - return false; - } + assert(producer->Stage != MESA_SHADER_FRAGMENT); + unsigned max_output_components = + ctx->Const.Program[producer->Stage].MaxOutputComponents; const unsigned output_components = output_vectors * 4; if (output_components > max_output_components) { @@ -1293,24 +1283,14 @@ check_against_input_limit(struct gl_context *ctx, ir_variable *const var = ((ir_instruction *) node)->as_variable(); if (var && var->data.mode == ir_var_shader_in && - is_varying_var(consumer->Type, var)) { + is_varying_var(consumer->Stage, var)) { input_vectors += var->type->count_attribute_slots(); } } - unsigned max_input_components; - switch (consumer->Type) { - case GL_GEOMETRY_SHADER: - max_input_components = ctx->Const.GeometryProgram.MaxInputComponents; - break; - case GL_FRAGMENT_SHADER: - max_input_components = ctx->Const.FragmentProgram.MaxInputComponents; - break; - case GL_VERTEX_SHADER: - default: - assert(!"Should not get here."); - return false; - } + assert(consumer->Stage != MESA_SHADER_VERTEX); + unsigned max_input_components = + ctx->Const.Program[consumer->Stage].MaxInputComponents; const unsigned input_components = input_vectors * 4; if (input_components > max_input_components) { diff --git a/mesalib/src/glsl/linker.cpp b/mesalib/src/glsl/linker.cpp index a81e10737..85a4d3883 100644 --- a/mesalib/src/glsl/linker.cpp +++ b/mesalib/src/glsl/linker.cpp @@ -109,10 +109,10 @@ public: virtual ir_visitor_status visit_enter(ir_call *ir) { - exec_list_iterator sig_iter = ir->callee->parameters.iterator(); - foreach_iter(exec_list_iterator, iter, *ir) { - ir_rvalue *param_rval = (ir_rvalue *)iter.get(); - ir_variable *sig_param = (ir_variable *)sig_iter.get(); + foreach_two_lists(formal_node, &ir->callee->parameters, + actual_node, &ir->actual_parameters) { + ir_rvalue *param_rval = (ir_rvalue *) actual_node; + ir_variable *sig_param = (ir_variable *) formal_node; if (sig_param->data.mode == ir_var_function_out || sig_param->data.mode == ir_var_function_inout) { @@ -122,7 +122,6 @@ public: return visit_stop; } } - sig_iter.next(); } if (ir->return_deref != NULL) { @@ -438,7 +437,7 @@ analyze_clip_usage(struct gl_shader_program *prog, if (clip_vertex.variable_found() && clip_distance.variable_found()) { linker_error(prog, "%s shader writes to both `gl_ClipVertex' " "and `gl_ClipDistance'\n", - _mesa_shader_enum_to_string(shader->Type)); + _mesa_shader_stage_to_string(shader->Stage)); return; } *UsesClipDistance = clip_distance.variable_found(); @@ -786,7 +785,7 @@ void cross_validate_uniforms(struct gl_shader_program *prog) { cross_validate_globals(prog, prog->_LinkedShaders, - MESA_SHADER_TYPES, true); + MESA_SHADER_STAGES, true); } /** @@ -797,12 +796,12 @@ static bool interstage_cross_validate_uniform_blocks(struct gl_shader_program *prog) { unsigned max_num_uniform_blocks = 0; - for (unsigned i = 0; i < MESA_SHADER_TYPES; i++) { + for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) { if (prog->_LinkedShaders[i]) max_num_uniform_blocks += prog->_LinkedShaders[i]->NumUniformBlocks; } - for (unsigned i = 0; i < MESA_SHADER_TYPES; i++) { + for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) { struct gl_shader *sh = prog->_LinkedShaders[i]; prog->UniformBlockStageIndex[i] = ralloc_array(prog, int, @@ -1209,7 +1208,7 @@ link_gs_inout_layout_qualifiers(struct gl_shader_program *prog, /* No in/out qualifiers defined for anything but GLSL 1.50+ * geometry shaders so far. */ - if (linked_shader->Type != GL_GEOMETRY_SHADER || prog->Version < 150) + if (linked_shader->Stage != MESA_SHADER_GEOMETRY || prog->Version < 150) return; /* From the GLSL 1.50 spec, page 46: @@ -1338,9 +1337,8 @@ link_intrastage_shaders(void *mem_ctx, if (other == NULL) continue; - foreach_iter (exec_list_iterator, iter, *f) { - ir_function_signature *sig = - (ir_function_signature *) iter.get(); + foreach_list(n, &f->signatures) { + ir_function_signature *sig = (ir_function_signature *) n; if (!sig->is_defined || sig->is_builtin()) continue; @@ -1376,7 +1374,7 @@ link_intrastage_shaders(void *mem_ctx, if (main == NULL) { linker_error(prog, "%s shader lacks `main'\n", - _mesa_shader_enum_to_string(shader_list[0]->Type)); + _mesa_shader_stage_to_string(shader_list[0]->Stage)); return NULL; } @@ -1450,11 +1448,11 @@ link_intrastage_shaders(void *mem_ctx, validate_ir_tree(linked->ir); /* Set the size of geometry shader input arrays */ - if (linked->Type == GL_GEOMETRY_SHADER) { + if (linked->Stage == MESA_SHADER_GEOMETRY) { unsigned num_vertices = vertices_per_prim(prog->Geom.InputType); geom_array_resize_visitor input_resize_visitor(num_vertices, prog); - foreach_iter(exec_list_iterator, iter, *linked->ir) { - ir_instruction *ir = (ir_instruction *)iter.get(); + foreach_list(n, linked->ir) { + ir_instruction *ir = (ir_instruction *) n; ir->accept(&input_resize_visitor); } } @@ -1488,7 +1486,7 @@ link_intrastage_shaders(void *mem_ctx, static void update_array_sizes(struct gl_shader_program *prog) { - for (unsigned i = 0; i < MESA_SHADER_TYPES; i++) { + for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) { if (prog->_LinkedShaders[i] == NULL) continue; @@ -1511,7 +1509,7 @@ update_array_sizes(struct gl_shader_program *prog) continue; unsigned int size = var->data.max_array_access; - for (unsigned j = 0; j < MESA_SHADER_TYPES; j++) { + for (unsigned j = 0; j < MESA_SHADER_STAGES; j++) { if (prog->_LinkedShaders[j] == NULL) continue; @@ -1894,80 +1892,51 @@ store_fragdepth_layout(struct gl_shader_program *prog) static void check_resources(struct gl_context *ctx, struct gl_shader_program *prog) { - const unsigned max_samplers[] = { - ctx->Const.VertexProgram.MaxTextureImageUnits, - ctx->Const.GeometryProgram.MaxTextureImageUnits, - ctx->Const.FragmentProgram.MaxTextureImageUnits - }; - STATIC_ASSERT(Elements(max_samplers) == MESA_SHADER_TYPES); - - const unsigned max_default_uniform_components[] = { - ctx->Const.VertexProgram.MaxUniformComponents, - ctx->Const.GeometryProgram.MaxUniformComponents, - ctx->Const.FragmentProgram.MaxUniformComponents - }; - STATIC_ASSERT(Elements(max_default_uniform_components) == - MESA_SHADER_TYPES); - - const unsigned max_combined_uniform_components[] = { - ctx->Const.VertexProgram.MaxCombinedUniformComponents, - ctx->Const.GeometryProgram.MaxCombinedUniformComponents, - ctx->Const.FragmentProgram.MaxCombinedUniformComponents - }; - STATIC_ASSERT(Elements(max_combined_uniform_components) == - MESA_SHADER_TYPES); - - const unsigned max_uniform_blocks[] = { - ctx->Const.VertexProgram.MaxUniformBlocks, - ctx->Const.GeometryProgram.MaxUniformBlocks, - ctx->Const.FragmentProgram.MaxUniformBlocks - }; - STATIC_ASSERT(Elements(max_uniform_blocks) == MESA_SHADER_TYPES); - - for (unsigned i = 0; i < MESA_SHADER_TYPES; i++) { + for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) { struct gl_shader *sh = prog->_LinkedShaders[i]; if (sh == NULL) continue; - if (sh->num_samplers > max_samplers[i]) { + if (sh->num_samplers > ctx->Const.Program[i].MaxTextureImageUnits) { linker_error(prog, "Too many %s shader texture samplers", - _mesa_shader_type_to_string(i)); + _mesa_shader_stage_to_string(i)); } - if (sh->num_uniform_components > max_default_uniform_components[i]) { + if (sh->num_uniform_components > + ctx->Const.Program[i].MaxUniformComponents) { if (ctx->Const.GLSLSkipStrictMaxUniformLimitCheck) { linker_warning(prog, "Too many %s shader default uniform block " "components, but the driver will try to optimize " "them out; this is non-portable out-of-spec " "behavior\n", - _mesa_shader_type_to_string(i)); + _mesa_shader_stage_to_string(i)); } else { linker_error(prog, "Too many %s shader default uniform block " "components", - _mesa_shader_type_to_string(i)); + _mesa_shader_stage_to_string(i)); } } if (sh->num_combined_uniform_components > - max_combined_uniform_components[i]) { + ctx->Const.Program[i].MaxCombinedUniformComponents) { if (ctx->Const.GLSLSkipStrictMaxUniformLimitCheck) { linker_warning(prog, "Too many %s shader uniform components, " "but the driver will try to optimize them out; " "this is non-portable out-of-spec behavior\n", - _mesa_shader_type_to_string(i)); + _mesa_shader_stage_to_string(i)); } else { linker_error(prog, "Too many %s shader uniform components", - _mesa_shader_type_to_string(i)); + _mesa_shader_stage_to_string(i)); } } } - unsigned blocks[MESA_SHADER_TYPES] = {0}; + unsigned blocks[MESA_SHADER_STAGES] = {0}; unsigned total_uniform_blocks = 0; for (unsigned i = 0; i < prog->NumUniformBlocks; i++) { - for (unsigned j = 0; j < MESA_SHADER_TYPES; j++) { + for (unsigned j = 0; j < MESA_SHADER_STAGES; j++) { if (prog->UniformBlockStageIndex[j][i] != -1) { blocks[j]++; total_uniform_blocks++; @@ -1979,12 +1948,14 @@ check_resources(struct gl_context *ctx, struct gl_shader_program *prog) prog->NumUniformBlocks, ctx->Const.MaxCombinedUniformBlocks); } else { - for (unsigned i = 0; i < MESA_SHADER_TYPES; i++) { - if (blocks[i] > max_uniform_blocks[i]) { + for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) { + const unsigned max_uniform_blocks = + ctx->Const.Program[i].MaxUniformBlocks; + if (blocks[i] > max_uniform_blocks) { linker_error(prog, "Too many %s uniform blocks (%d/%d)", - _mesa_shader_type_to_string(i), + _mesa_shader_stage_to_string(i), blocks[i], - max_uniform_blocks[i]); + max_uniform_blocks); break; } } @@ -2010,7 +1981,7 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog) ralloc_free(prog->UniformBlocks); prog->UniformBlocks = NULL; prog->NumUniformBlocks = 0; - for (int i = 0; i < MESA_SHADER_TYPES; i++) { + for (int i = 0; i < MESA_SHADER_STAGES; i++) { ralloc_free(prog->UniformBlockStageIndex[i]); prog->UniformBlockStageIndex[i] = NULL; } @@ -2049,16 +2020,16 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog) goto done; } - switch (prog->Shaders[i]->Type) { - case GL_VERTEX_SHADER: + switch (prog->Shaders[i]->Stage) { + case MESA_SHADER_VERTEX: vert_shader_list[num_vert_shaders] = prog->Shaders[i]; num_vert_shaders++; break; - case GL_FRAGMENT_SHADER: + case MESA_SHADER_FRAGMENT: frag_shader_list[num_frag_shaders] = prog->Shaders[i]; num_frag_shaders++; break; - case GL_GEOMETRY_SHADER: + case MESA_SHADER_GEOMETRY: geom_shader_list[num_geom_shaders] = prog->Shaders[i]; num_geom_shaders++; break; @@ -2085,7 +2056,7 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog) goto done; } - for (unsigned int i = 0; i < MESA_SHADER_TYPES; i++) { + for (unsigned int i = 0; i < MESA_SHADER_STAGES; i++) { if (prog->_LinkedShaders[i] != NULL) ctx->Driver.DeleteShader(ctx, prog->_LinkedShaders[i]); @@ -2154,7 +2125,7 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog) unsigned prev; - for (prev = 0; prev < MESA_SHADER_TYPES; prev++) { + for (prev = 0; prev < MESA_SHADER_STAGES; prev++) { if (prog->_LinkedShaders[prev] != NULL) break; } @@ -2162,7 +2133,7 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog) /* Validate the inputs of each stage with the output of the preceding * stage. */ - for (unsigned i = prev + 1; i < MESA_SHADER_TYPES; i++) { + for (unsigned i = prev + 1; i < MESA_SHADER_STAGES; i++) { if (prog->_LinkedShaders[i] == NULL) continue; @@ -2182,11 +2153,11 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog) /* Cross-validate uniform blocks between shader stages */ validate_interstage_uniform_blocks(prog, prog->_LinkedShaders, - MESA_SHADER_TYPES); + MESA_SHADER_STAGES); if (!prog->LinkStatus) goto done; - for (unsigned int i = 0; i < MESA_SHADER_TYPES; i++) { + for (unsigned int i = 0; i < MESA_SHADER_STAGES; i++) { if (prog->_LinkedShaders[i] != NULL) lower_named_interface_blocks(mem_ctx, prog->_LinkedShaders[i]); } @@ -2211,7 +2182,7 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog) * uniforms, and varyings. Later optimization could possibly make * some of that unused. */ - for (unsigned i = 0; i < MESA_SHADER_TYPES; i++) { + for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) { if (prog->_LinkedShaders[i] == NULL) continue; @@ -2257,7 +2228,7 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog) } unsigned first; - for (first = 0; first < MESA_SHADER_TYPES; first++) { + for (first = 0; first < MESA_SHADER_STAGES; first++) { if (prog->_LinkedShaders[first] != NULL) break; } @@ -2289,7 +2260,7 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog) * eliminated if they are (transitively) not used in a later stage. */ int last, next; - for (last = MESA_SHADER_TYPES-1; last >= 0; last--) { + for (last = MESA_SHADER_STAGES-1; last >= 0; last--) { if (prog->_LinkedShaders[last] != NULL) break; } @@ -2404,7 +2375,7 @@ done: free(frag_shader_list); free(geom_shader_list); - for (unsigned i = 0; i < MESA_SHADER_TYPES; i++) { + for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) { if (prog->_LinkedShaders[i] == NULL) continue; diff --git a/mesalib/src/glsl/list.h b/mesalib/src/glsl/list.h index 2934539fe..b2e249657 100644 --- a/mesalib/src/glsl/list.h +++ b/mesalib/src/glsl/list.h @@ -210,62 +210,8 @@ struct exec_node { #ifdef __cplusplus struct exec_node; - -class iterator { -public: - void next() - { - } - - void *get() - { - return NULL; - } - - bool has_next() const - { - return false; - } -}; - -class exec_list_iterator : public iterator { -public: - exec_list_iterator(exec_node *n) : node(n), _next(n->next) - { - /* empty */ - } - - void next() - { - node = _next; - _next = node->next; - } - - void remove() - { - node->remove(); - } - - exec_node *get() - { - return node; - } - - bool has_next() const - { - return _next != NULL; - } - -private: - exec_node *node; - exec_node *_next; -}; - -#define foreach_iter(iter_type, iter, container) \ - for (iter_type iter = (container) . iterator(); iter.has_next(); iter.next()) #endif - struct exec_list { struct exec_node *head; struct exec_node *tail; @@ -412,16 +358,6 @@ struct exec_list { */ source->make_empty(); } - - exec_list_iterator iterator() - { - return exec_list_iterator(head); - } - - exec_list_iterator iterator() const - { - return exec_list_iterator((exec_node *) head); - } #endif }; @@ -455,6 +391,22 @@ inline void exec_node::insert_before(exec_list *before) ; (__node)->next != NULL \ ; (__node) = (__node)->next) +/** + * Iterate through two lists at once. Stops at the end of the shorter list. + * + * This is safe against either current node being removed or replaced. + */ +#define foreach_two_lists(__node1, __list1, __node2, __list2) \ + for (exec_node * __node1 = (__list1)->head, \ + * __node2 = (__list2)->head, \ + * __next1 = __node1->next, \ + * __next2 = __node2->next \ + ; __next1 != NULL && __next2 != NULL \ + ; __node1 = __next1, \ + __node2 = __next2, \ + __next1 = __next1->next, \ + __next2 = __next2->next) + #define foreach_list_const(__node, __list) \ for (const exec_node * __node = (__list)->head \ ; (__node)->next != NULL \ diff --git a/mesalib/src/glsl/lower_clip_distance.cpp b/mesalib/src/glsl/lower_clip_distance.cpp index bb4f6ab11..2d6138d5a 100644 --- a/mesalib/src/glsl/lower_clip_distance.cpp +++ b/mesalib/src/glsl/lower_clip_distance.cpp @@ -54,10 +54,10 @@ namespace { class lower_clip_distance_visitor : public ir_rvalue_visitor { public: - explicit lower_clip_distance_visitor(GLenum shader_type) + explicit lower_clip_distance_visitor(gl_shader_stage shader_stage) : progress(false), old_clip_distance_1d_var(NULL), old_clip_distance_2d_var(NULL), new_clip_distance_1d_var(NULL), - new_clip_distance_2d_var(NULL), shader_type(shader_type) + new_clip_distance_2d_var(NULL), shader_stage(shader_stage) { } @@ -96,9 +96,9 @@ public: ir_variable *new_clip_distance_2d_var; /** - * Type of shader we are compiling (e.g. GL_VERTEX_SHADER) + * Type of shader we are compiling (e.g. MESA_SHADER_VERTEX) */ - const GLenum shader_type; + const gl_shader_stage shader_stage; }; } /* anonymous namespace */ @@ -142,7 +142,7 @@ lower_clip_distance_visitor::visit(ir_variable *ir) } else { /* 2D gl_ClipDistance (used for geometry input). */ assert(ir->data.mode == ir_var_shader_in && - this->shader_type == GL_GEOMETRY_SHADER_ARB); + this->shader_stage == MESA_SHADER_GEOMETRY); if (this->old_clip_distance_2d_var) return visit_continue; @@ -253,7 +253,7 @@ lower_clip_distance_visitor::is_clip_distance_vec8(ir_rvalue *ir) } if (this->old_clip_distance_2d_var) { /* 2D clip distance is only possible as a geometry input */ - assert(this->shader_type == GL_GEOMETRY_SHADER_ARB); + assert(this->shader_stage == MESA_SHADER_GEOMETRY); ir_dereference_array *array_ref = ir->as_dereference_array(); if (array_ref) { @@ -288,7 +288,7 @@ lower_clip_distance_visitor::lower_clip_distance_vec8(ir_rvalue *ir) } if (this->old_clip_distance_2d_var) { /* 2D clip distance is only possible as a geometry input */ - assert(this->shader_type == GL_GEOMETRY_SHADER_ARB); + assert(this->shader_stage == MESA_SHADER_GEOMETRY); ir_dereference_array *array_ref = ir->as_dereference_array(); if (array_ref) { @@ -536,7 +536,7 @@ lower_clip_distance_visitor::visit_leave(ir_call *ir) bool lower_clip_distance(gl_shader *shader) { - lower_clip_distance_visitor v(shader->Type); + lower_clip_distance_visitor v(shader->Stage); visit_list_elements(&v, shader->ir); diff --git a/mesalib/src/glsl/lower_if_to_cond_assign.cpp b/mesalib/src/glsl/lower_if_to_cond_assign.cpp index 1e7ce51c7..f15b217e0 100644 --- a/mesalib/src/glsl/lower_if_to_cond_assign.cpp +++ b/mesalib/src/glsl/lower_if_to_cond_assign.cpp @@ -178,12 +178,12 @@ ir_if_to_cond_assign_visitor::visit_leave(ir_if *ir) ir_assignment *assign; /* Check that both blocks don't contain anything we can't support. */ - foreach_iter(exec_list_iterator, then_iter, ir->then_instructions) { - ir_instruction *then_ir = (ir_instruction *)then_iter.get(); + foreach_list(n, &ir->then_instructions) { + ir_instruction *then_ir = (ir_instruction *) n; visit_tree(then_ir, check_control_flow, &found_control_flow); } - foreach_iter(exec_list_iterator, else_iter, ir->else_instructions) { - ir_instruction *else_ir = (ir_instruction *)else_iter.get(); + foreach_list(n, &ir->else_instructions) { + ir_instruction *else_ir = (ir_instruction *) n; visit_tree(else_ir, check_control_flow, &found_control_flow); } if (found_control_flow) diff --git a/mesalib/src/glsl/lower_packed_varyings.cpp b/mesalib/src/glsl/lower_packed_varyings.cpp index 9edef5d04..c23d1801b 100644 --- a/mesalib/src/glsl/lower_packed_varyings.cpp +++ b/mesalib/src/glsl/lower_packed_varyings.cpp @@ -669,7 +669,7 @@ lower_packed_varyings(void *mem_ctx, unsigned location_base, gs_input_vertices, &new_instructions); visitor.run(instructions); if (mode == ir_var_shader_out) { - if (shader->Type == GL_GEOMETRY_SHADER) { + if (shader->Stage == MESA_SHADER_GEOMETRY) { /* For geometry shaders, outputs need to be lowered before each call * to EmitVertex() */ diff --git a/mesalib/src/glsl/lower_vec_index_to_cond_assign.cpp b/mesalib/src/glsl/lower_vec_index_to_cond_assign.cpp index 8080006c1..fe6a3f208 100644 --- a/mesalib/src/glsl/lower_vec_index_to_cond_assign.cpp +++ b/mesalib/src/glsl/lower_vec_index_to_cond_assign.cpp @@ -197,8 +197,8 @@ ir_vec_index_to_cond_assign_visitor::visit_leave(ir_assignment *ir) ir_visitor_status ir_vec_index_to_cond_assign_visitor::visit_enter(ir_call *ir) { - foreach_iter(exec_list_iterator, iter, *ir) { - ir_rvalue *param = (ir_rvalue *)iter.get(); + foreach_list_safe(n, &ir->actual_parameters) { + ir_rvalue *param = (ir_rvalue *) n; ir_rvalue *new_param = convert_vector_extract_to_cond_assign(param); if (new_param != param) { diff --git a/mesalib/src/glsl/lower_vec_index_to_swizzle.cpp b/mesalib/src/glsl/lower_vec_index_to_swizzle.cpp index 46985791e..b5bb00c30 100644 --- a/mesalib/src/glsl/lower_vec_index_to_swizzle.cpp +++ b/mesalib/src/glsl/lower_vec_index_to_swizzle.cpp @@ -131,8 +131,8 @@ ir_vec_index_to_swizzle_visitor::visit_enter(ir_assignment *ir) ir_visitor_status ir_vec_index_to_swizzle_visitor::visit_enter(ir_call *ir) { - foreach_iter(exec_list_iterator, iter, *ir) { - ir_rvalue *param = (ir_rvalue *)iter.get(); + foreach_list_safe(n, &ir->actual_parameters) { + ir_rvalue *param = (ir_rvalue *) n; ir_rvalue *new_param = convert_vector_extract_to_swizzle(param); if (new_param != param) { diff --git a/mesalib/src/glsl/main.cpp b/mesalib/src/glsl/main.cpp index 4a5570608..56c32e688 100644 --- a/mesalib/src/glsl/main.cpp +++ b/mesalib/src/glsl/main.cpp @@ -73,20 +73,20 @@ initialize_context(struct gl_context *ctx, gl_api api) ctx->Const.MaxTextureCoordUnits = 0; ctx->Const.MaxTextureUnits = 8; - ctx->Const.VertexProgram.MaxAttribs = 8; - ctx->Const.VertexProgram.MaxTextureImageUnits = 0; - ctx->Const.VertexProgram.MaxUniformComponents = 128 * 4; - ctx->Const.VertexProgram.MaxInputComponents = 0; /* not used */ - ctx->Const.VertexProgram.MaxOutputComponents = 32; + ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs = 8; + ctx->Const.Program[MESA_SHADER_VERTEX].MaxTextureImageUnits = 0; + ctx->Const.Program[MESA_SHADER_VERTEX].MaxUniformComponents = 128 * 4; + ctx->Const.Program[MESA_SHADER_VERTEX].MaxInputComponents = 0; /* not used */ + ctx->Const.Program[MESA_SHADER_VERTEX].MaxOutputComponents = 32; - ctx->Const.FragmentProgram.MaxTextureImageUnits = + ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits = ctx->Const.MaxCombinedTextureImageUnits; - ctx->Const.FragmentProgram.MaxUniformComponents = 16 * 4; - ctx->Const.FragmentProgram.MaxInputComponents = - ctx->Const.VertexProgram.MaxOutputComponents; - ctx->Const.FragmentProgram.MaxOutputComponents = 0; /* not used */ + ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxUniformComponents = 16 * 4; + ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxInputComponents = + ctx->Const.Program[MESA_SHADER_VERTEX].MaxOutputComponents; + ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxOutputComponents = 0; /* not used */ - ctx->Const.MaxVarying = ctx->Const.VertexProgram.MaxOutputComponents / 4; + ctx->Const.MaxVarying = ctx->Const.Program[MESA_SHADER_VERTEX].MaxOutputComponents / 4; break; case 110: case 120: @@ -99,20 +99,20 @@ initialize_context(struct gl_context *ctx, gl_api api) ctx->Const.MaxTextureCoordUnits = 2; ctx->Const.MaxTextureUnits = 2; - ctx->Const.VertexProgram.MaxAttribs = 16; - ctx->Const.VertexProgram.MaxTextureImageUnits = 0; - ctx->Const.VertexProgram.MaxUniformComponents = 512; - ctx->Const.VertexProgram.MaxInputComponents = 0; /* not used */ - ctx->Const.VertexProgram.MaxOutputComponents = 32; + ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs = 16; + ctx->Const.Program[MESA_SHADER_VERTEX].MaxTextureImageUnits = 0; + ctx->Const.Program[MESA_SHADER_VERTEX].MaxUniformComponents = 512; + ctx->Const.Program[MESA_SHADER_VERTEX].MaxInputComponents = 0; /* not used */ + ctx->Const.Program[MESA_SHADER_VERTEX].MaxOutputComponents = 32; - ctx->Const.FragmentProgram.MaxTextureImageUnits = + ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits = ctx->Const.MaxCombinedTextureImageUnits; - ctx->Const.FragmentProgram.MaxUniformComponents = 64; - ctx->Const.FragmentProgram.MaxInputComponents = - ctx->Const.VertexProgram.MaxOutputComponents; - ctx->Const.FragmentProgram.MaxOutputComponents = 0; /* not used */ + ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxUniformComponents = 64; + ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxInputComponents = + ctx->Const.Program[MESA_SHADER_VERTEX].MaxOutputComponents; + ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxOutputComponents = 0; /* not used */ - ctx->Const.MaxVarying = ctx->Const.VertexProgram.MaxOutputComponents / 4; + ctx->Const.MaxVarying = ctx->Const.Program[MESA_SHADER_VERTEX].MaxOutputComponents / 4; break; case 130: case 140: @@ -125,19 +125,19 @@ initialize_context(struct gl_context *ctx, gl_api api) ctx->Const.MaxTextureCoordUnits = 8; ctx->Const.MaxTextureUnits = 2; - ctx->Const.VertexProgram.MaxAttribs = 16; - ctx->Const.VertexProgram.MaxTextureImageUnits = 16; - ctx->Const.VertexProgram.MaxUniformComponents = 1024; - ctx->Const.VertexProgram.MaxInputComponents = 0; /* not used */ - ctx->Const.VertexProgram.MaxOutputComponents = 64; + ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs = 16; + ctx->Const.Program[MESA_SHADER_VERTEX].MaxTextureImageUnits = 16; + ctx->Const.Program[MESA_SHADER_VERTEX].MaxUniformComponents = 1024; + ctx->Const.Program[MESA_SHADER_VERTEX].MaxInputComponents = 0; /* not used */ + ctx->Const.Program[MESA_SHADER_VERTEX].MaxOutputComponents = 64; - ctx->Const.FragmentProgram.MaxTextureImageUnits = 16; - ctx->Const.FragmentProgram.MaxUniformComponents = 1024; - ctx->Const.FragmentProgram.MaxInputComponents = - ctx->Const.VertexProgram.MaxOutputComponents; - ctx->Const.FragmentProgram.MaxOutputComponents = 0; /* not used */ + ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits = 16; + ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxUniformComponents = 1024; + ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxInputComponents = + ctx->Const.Program[MESA_SHADER_VERTEX].MaxOutputComponents; + ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxOutputComponents = 0; /* not used */ - ctx->Const.MaxVarying = ctx->Const.VertexProgram.MaxOutputComponents / 4; + ctx->Const.MaxVarying = ctx->Const.Program[MESA_SHADER_VERTEX].MaxOutputComponents / 4; break; case 150: case 330: @@ -149,28 +149,28 @@ initialize_context(struct gl_context *ctx, gl_api api) ctx->Const.MaxTextureCoordUnits = 8; ctx->Const.MaxTextureUnits = 2; - ctx->Const.VertexProgram.MaxAttribs = 16; - ctx->Const.VertexProgram.MaxTextureImageUnits = 16; - ctx->Const.VertexProgram.MaxUniformComponents = 1024; - ctx->Const.VertexProgram.MaxInputComponents = 0; /* not used */ - ctx->Const.VertexProgram.MaxOutputComponents = 64; + ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs = 16; + ctx->Const.Program[MESA_SHADER_VERTEX].MaxTextureImageUnits = 16; + ctx->Const.Program[MESA_SHADER_VERTEX].MaxUniformComponents = 1024; + ctx->Const.Program[MESA_SHADER_VERTEX].MaxInputComponents = 0; /* not used */ + ctx->Const.Program[MESA_SHADER_VERTEX].MaxOutputComponents = 64; - ctx->Const.GeometryProgram.MaxTextureImageUnits = 16; - ctx->Const.GeometryProgram.MaxUniformComponents = 1024; - ctx->Const.GeometryProgram.MaxInputComponents = - ctx->Const.VertexProgram.MaxOutputComponents; - ctx->Const.GeometryProgram.MaxOutputComponents = 128; + ctx->Const.Program[MESA_SHADER_GEOMETRY].MaxTextureImageUnits = 16; + ctx->Const.Program[MESA_SHADER_GEOMETRY].MaxUniformComponents = 1024; + ctx->Const.Program[MESA_SHADER_GEOMETRY].MaxInputComponents = + ctx->Const.Program[MESA_SHADER_VERTEX].MaxOutputComponents; + ctx->Const.Program[MESA_SHADER_GEOMETRY].MaxOutputComponents = 128; - ctx->Const.FragmentProgram.MaxTextureImageUnits = 16; - ctx->Const.FragmentProgram.MaxUniformComponents = 1024; - ctx->Const.FragmentProgram.MaxInputComponents = - ctx->Const.GeometryProgram.MaxOutputComponents; - ctx->Const.FragmentProgram.MaxOutputComponents = 0; /* not used */ + ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits = 16; + ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxUniformComponents = 1024; + ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxInputComponents = + ctx->Const.Program[MESA_SHADER_GEOMETRY].MaxOutputComponents; + ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxOutputComponents = 0; /* not used */ ctx->Const.MaxCombinedTextureImageUnits = - ctx->Const.VertexProgram.MaxTextureImageUnits - + ctx->Const.GeometryProgram.MaxTextureImageUnits - + ctx->Const.FragmentProgram.MaxTextureImageUnits; + ctx->Const.Program[MESA_SHADER_VERTEX].MaxTextureImageUnits + + ctx->Const.Program[MESA_SHADER_GEOMETRY].MaxTextureImageUnits + + ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits; ctx->Const.MaxGeometryOutputVertices = 256; ctx->Const.MaxGeometryTotalOutputComponents = 1024; @@ -189,18 +189,18 @@ initialize_context(struct gl_context *ctx, gl_api api) ctx->Const.MaxTextureCoordUnits = 0; ctx->Const.MaxTextureUnits = 0; - ctx->Const.VertexProgram.MaxAttribs = 16; - ctx->Const.VertexProgram.MaxTextureImageUnits = 16; - ctx->Const.VertexProgram.MaxUniformComponents = 1024; - ctx->Const.VertexProgram.MaxInputComponents = 0; /* not used */ - ctx->Const.VertexProgram.MaxOutputComponents = 16 * 4; + ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs = 16; + ctx->Const.Program[MESA_SHADER_VERTEX].MaxTextureImageUnits = 16; + ctx->Const.Program[MESA_SHADER_VERTEX].MaxUniformComponents = 1024; + ctx->Const.Program[MESA_SHADER_VERTEX].MaxInputComponents = 0; /* not used */ + ctx->Const.Program[MESA_SHADER_VERTEX].MaxOutputComponents = 16 * 4; - ctx->Const.FragmentProgram.MaxTextureImageUnits = 16; - ctx->Const.FragmentProgram.MaxUniformComponents = 224; - ctx->Const.FragmentProgram.MaxInputComponents = 15 * 4; - ctx->Const.FragmentProgram.MaxOutputComponents = 0; /* not used */ + ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits = 16; + ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxUniformComponents = 224; + ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxInputComponents = 15 * 4; + ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxOutputComponents = 0; /* not used */ - ctx->Const.MaxVarying = ctx->Const.FragmentProgram.MaxInputComponents / 4; + ctx->Const.MaxVarying = ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxInputComponents / 4; break; } @@ -287,7 +287,7 @@ void 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); + new(shader) _mesa_glsl_parse_state(ctx, shader->Stage, shader); _mesa_glsl_compile_shader(ctx, shader, dump_ast, dump_hir); @@ -373,6 +373,7 @@ main(int argc, char **argv) shader->Type = GL_FRAGMENT_SHADER; else usage_fail(argv[0]); + shader->Stage = _mesa_shader_enum_to_shader_stage(shader->Type); shader->Source = load_text_file(whole_program, argv[optind]); if (shader->Source == NULL) { @@ -399,7 +400,7 @@ main(int argc, char **argv) printf("Info log for linking:\n%s\n", whole_program->InfoLog); } - for (unsigned i = 0; i < MESA_SHADER_TYPES; i++) + for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) ralloc_free(whole_program->_LinkedShaders[i]); ralloc_free(whole_program); diff --git a/mesalib/src/glsl/opt_algebraic.cpp b/mesalib/src/glsl/opt_algebraic.cpp index 05a589989..332f0b77b 100644 --- a/mesalib/src/glsl/opt_algebraic.cpp +++ b/mesalib/src/glsl/opt_algebraic.cpp @@ -88,6 +88,12 @@ is_vec_one(ir_constant *ir) } static inline bool +is_vec_two(ir_constant *ir) +{ + return (ir == NULL) ? false : ir->is_value(2.0, 2); +} + +static inline bool is_vec_negative_one(ir_constant *ir) { return (ir == NULL) ? false : ir->is_negative_one(); @@ -416,6 +422,17 @@ ir_algebraic_visitor::handle_expression(ir_expression *ir) } break; + case ir_binop_pow: + /* 1^x == 1 */ + if (is_vec_one(op_const[0])) + return op_const[0]; + + /* pow(2,x) == exp2(x) */ + if (is_vec_two(op_const[0])) + return expr(ir_unop_exp2, ir->operands[1]); + + break; + case ir_unop_rcp: if (op_expr[0] && op_expr[0]->operation == ir_unop_rcp) return op_expr[0]->operands[0]; diff --git a/mesalib/src/glsl/opt_array_splitting.cpp b/mesalib/src/glsl/opt_array_splitting.cpp index e946e0ae5..f37d09022 100644 --- a/mesalib/src/glsl/opt_array_splitting.cpp +++ b/mesalib/src/glsl/opt_array_splitting.cpp @@ -135,8 +135,8 @@ ir_array_reference_visitor::get_variable_entry(ir_variable *var) if (var->type->is_unsized_array()) return NULL; - foreach_iter(exec_list_iterator, iter, this->variable_list) { - variable_entry *entry = (variable_entry *)iter.get(); + foreach_list(n, &this->variable_list) { + variable_entry *entry = (variable_entry *) n; if (entry->var == var) return entry; } @@ -224,8 +224,8 @@ ir_array_reference_visitor::get_split_list(exec_list *instructions, } /* Trim out variables we found that we can't split. */ - foreach_iter(exec_list_iterator, iter, variable_list) { - variable_entry *entry = (variable_entry *)iter.get(); + foreach_list_safe(n, &variable_list) { + variable_entry *entry = (variable_entry *) n; if (debug) { printf("array %s@%p: decl %d, split %d\n", @@ -270,8 +270,8 @@ ir_array_splitting_visitor::get_splitting_entry(ir_variable *var) { assert(var); - foreach_iter(exec_list_iterator, iter, *this->variable_list) { - variable_entry *entry = (variable_entry *)iter.get(); + foreach_list(n, this->variable_list) { + variable_entry *entry = (variable_entry *) n; if (entry->var == var) { return entry; } @@ -368,8 +368,8 @@ optimize_split_arrays(exec_list *instructions, bool linked) /* Replace the decls of the arrays to be split with their split * components. */ - foreach_iter(exec_list_iterator, iter, refs.variable_list) { - variable_entry *entry = (variable_entry *)iter.get(); + foreach_list(n, &refs.variable_list) { + variable_entry *entry = (variable_entry *) n; const struct glsl_type *type = entry->var->type; const struct glsl_type *subtype; diff --git a/mesalib/src/glsl/opt_constant_folding.cpp b/mesalib/src/glsl/opt_constant_folding.cpp index 08a47b96b..d0e575460 100644 --- a/mesalib/src/glsl/opt_constant_folding.cpp +++ b/mesalib/src/glsl/opt_constant_folding.cpp @@ -122,10 +122,10 @@ ir_visitor_status ir_constant_folding_visitor::visit_enter(ir_call *ir) { /* Attempt to constant fold parameters */ - exec_list_iterator sig_iter = ir->callee->parameters.iterator(); - foreach_iter(exec_list_iterator, iter, *ir) { - ir_rvalue *param_rval = (ir_rvalue *)iter.get(); - ir_variable *sig_param = (ir_variable *)sig_iter.get(); + foreach_two_lists(formal_node, &ir->callee->parameters, + actual_node, &ir->actual_parameters) { + ir_rvalue *param_rval = (ir_rvalue *) actual_node; + ir_variable *sig_param = (ir_variable *) formal_node; if (sig_param->data.mode == ir_var_function_in || sig_param->data.mode == ir_var_const_in) { @@ -136,7 +136,6 @@ ir_constant_folding_visitor::visit_enter(ir_call *ir) param_rval->replace_with(new_param); } } - sig_iter.next(); } /* Next, see if the call can be replaced with an assignment of a constant */ diff --git a/mesalib/src/glsl/opt_constant_propagation.cpp b/mesalib/src/glsl/opt_constant_propagation.cpp index f1a6fbdaa..18f5da689 100644 --- a/mesalib/src/glsl/opt_constant_propagation.cpp +++ b/mesalib/src/glsl/opt_constant_propagation.cpp @@ -172,8 +172,8 @@ ir_constant_propagation_visitor::handle_rvalue(ir_rvalue **rvalue) channel = i; } - foreach_iter(exec_list_iterator, iter, *this->acp) { - acp_entry *entry = (acp_entry *)iter.get(); + foreach_list(n, this->acp) { + acp_entry *entry = (acp_entry *) n; if (entry->var == deref->var && entry->write_mask & (1 << channel)) { found = entry; break; @@ -281,10 +281,10 @@ ir_visitor_status ir_constant_propagation_visitor::visit_enter(ir_call *ir) { /* Do constant propagation on call parameters, but skip any out params */ - exec_list_iterator sig_param_iter = ir->callee->parameters.iterator(); - foreach_iter(exec_list_iterator, iter, ir->actual_parameters) { - ir_variable *sig_param = (ir_variable *)sig_param_iter.get(); - ir_rvalue *param = (ir_rvalue *)iter.get(); + foreach_two_lists(formal_node, &ir->callee->parameters, + actual_node, &ir->actual_parameters) { + ir_variable *sig_param = (ir_variable *) formal_node; + ir_rvalue *param = (ir_rvalue *) actual_node; if (sig_param->data.mode != ir_var_function_out && sig_param->data.mode != ir_var_function_inout) { ir_rvalue *new_param = param; @@ -294,7 +294,6 @@ ir_constant_propagation_visitor::visit_enter(ir_call *ir) else param->accept(this); } - sig_param_iter.next(); } /* Since we're unlinked, we don't (necssarily) know the side effects of @@ -318,8 +317,8 @@ ir_constant_propagation_visitor::handle_if_block(exec_list *instructions) this->killed_all = false; /* Populate the initial acp with a constant of the original */ - foreach_iter(exec_list_iterator, iter, *orig_acp) { - acp_entry *a = (acp_entry *)iter.get(); + foreach_list(n, orig_acp) { + acp_entry *a = (acp_entry *) n; this->acp->push_tail(new(this->mem_ctx) acp_entry(a)); } @@ -334,8 +333,8 @@ ir_constant_propagation_visitor::handle_if_block(exec_list *instructions) this->acp = orig_acp; this->killed_all = this->killed_all || orig_killed_all; - foreach_iter(exec_list_iterator, iter, *new_kills) { - kill_entry *k = (kill_entry *)iter.get(); + foreach_list(n, new_kills) { + kill_entry *k = (kill_entry *) n; kill(k->var, k->write_mask); } } @@ -379,8 +378,8 @@ ir_constant_propagation_visitor::visit_enter(ir_loop *ir) this->acp = orig_acp; this->killed_all = this->killed_all || orig_killed_all; - foreach_iter(exec_list_iterator, iter, *new_kills) { - kill_entry *k = (kill_entry *)iter.get(); + foreach_list(n, new_kills) { + kill_entry *k = (kill_entry *) n; kill(k->var, k->write_mask); } @@ -398,8 +397,8 @@ ir_constant_propagation_visitor::kill(ir_variable *var, unsigned write_mask) return; /* Remove any entries currently in the ACP for this kill. */ - foreach_iter(exec_list_iterator, iter, *this->acp) { - acp_entry *entry = (acp_entry *)iter.get(); + foreach_list_safe(n, this->acp) { + acp_entry *entry = (acp_entry *) n; if (entry->var == var) { entry->write_mask &= ~write_mask; @@ -411,8 +410,8 @@ ir_constant_propagation_visitor::kill(ir_variable *var, unsigned write_mask) /* Add this writemask of the variable to the list of killed * variables in this block. */ - foreach_iter(exec_list_iterator, iter, *this->kills) { - kill_entry *entry = (kill_entry *)iter.get(); + foreach_list(n, this->kills) { + kill_entry *entry = (kill_entry *) n; if (entry->var == var) { entry->write_mask |= write_mask; diff --git a/mesalib/src/glsl/opt_constant_variable.cpp b/mesalib/src/glsl/opt_constant_variable.cpp index a026c51c3..961b8aa06 100644 --- a/mesalib/src/glsl/opt_constant_variable.cpp +++ b/mesalib/src/glsl/opt_constant_variable.cpp @@ -132,10 +132,10 @@ ir_visitor_status ir_constant_variable_visitor::visit_enter(ir_call *ir) { /* Mark any out parameters as assigned to */ - exec_list_iterator sig_iter = ir->callee->parameters.iterator(); - foreach_iter(exec_list_iterator, iter, *ir) { - ir_rvalue *param_rval = (ir_rvalue *)iter.get(); - ir_variable *param = (ir_variable *)sig_iter.get(); + foreach_two_lists(formal_node, &ir->callee->parameters, + actual_node, &ir->actual_parameters) { + ir_rvalue *param_rval = (ir_rvalue *) actual_node; + ir_variable *param = (ir_variable *) formal_node; if (param->data.mode == ir_var_function_out || param->data.mode == ir_var_function_inout) { @@ -146,7 +146,6 @@ ir_constant_variable_visitor::visit_enter(ir_call *ir) entry = get_assignment_entry(var, &this->list); entry->assignment_count++; } - sig_iter.next(); } /* Mark the return storage as having been assigned to */ @@ -194,13 +193,12 @@ do_constant_variable_unlinked(exec_list *instructions) { bool progress = false; - foreach_iter(exec_list_iterator, iter, *instructions) { - ir_instruction *ir = (ir_instruction *)iter.get(); + foreach_list(n, instructions) { + ir_instruction *ir = (ir_instruction *) n; ir_function *f = ir->as_function(); if (f) { - foreach_iter(exec_list_iterator, sigiter, *f) { - ir_function_signature *sig = - (ir_function_signature *) sigiter.get(); + foreach_list(signode, &f->signatures) { + ir_function_signature *sig = (ir_function_signature *) signode; if (do_constant_variable(&sig->body)) progress = true; } diff --git a/mesalib/src/glsl/opt_copy_propagation.cpp b/mesalib/src/glsl/opt_copy_propagation.cpp index db5dfc153..195cc8baa 100644 --- a/mesalib/src/glsl/opt_copy_propagation.cpp +++ b/mesalib/src/glsl/opt_copy_propagation.cpp @@ -167,8 +167,8 @@ ir_copy_propagation_visitor::visit(ir_dereference_variable *ir) ir_variable *var = ir->var; - foreach_iter(exec_list_iterator, iter, *this->acp) { - acp_entry *entry = (acp_entry *)iter.get(); + foreach_list(n, this->acp) { + acp_entry *entry = (acp_entry *) n; if (var == entry->lhs) { ir->var = entry->rhs; @@ -185,15 +185,14 @@ ir_visitor_status ir_copy_propagation_visitor::visit_enter(ir_call *ir) { /* Do copy propagation on call parameters, but skip any out params */ - exec_list_iterator sig_param_iter = ir->callee->parameters.iterator(); - foreach_iter(exec_list_iterator, iter, ir->actual_parameters) { - ir_variable *sig_param = (ir_variable *)sig_param_iter.get(); - ir_instruction *ir = (ir_instruction *)iter.get(); + foreach_two_lists(formal_node, &ir->callee->parameters, + actual_node, &ir->actual_parameters) { + ir_variable *sig_param = (ir_variable *) formal_node; + ir_rvalue *ir = (ir_rvalue *) actual_node; if (sig_param->data.mode != ir_var_function_out && sig_param->data.mode != ir_var_function_inout) { ir->accept(this); } - sig_param_iter.next(); } /* Since we're unlinked, we don't (necessarily) know the side effects of @@ -217,8 +216,8 @@ ir_copy_propagation_visitor::handle_if_block(exec_list *instructions) this->killed_all = false; /* Populate the initial acp with a copy of the original */ - foreach_iter(exec_list_iterator, iter, *orig_acp) { - acp_entry *a = (acp_entry *)iter.get(); + foreach_list(n, orig_acp) { + acp_entry *a = (acp_entry *) n; this->acp->push_tail(new(this->mem_ctx) acp_entry(a->lhs, a->rhs)); } @@ -233,8 +232,8 @@ ir_copy_propagation_visitor::handle_if_block(exec_list *instructions) this->acp = orig_acp; this->killed_all = this->killed_all || orig_killed_all; - foreach_iter(exec_list_iterator, iter, *new_kills) { - kill_entry *k = (kill_entry *)iter.get(); + foreach_list(n, new_kills) { + kill_entry *k = (kill_entry *) n; kill(k->var); } } @@ -277,8 +276,8 @@ ir_copy_propagation_visitor::visit_enter(ir_loop *ir) this->acp = orig_acp; this->killed_all = this->killed_all || orig_killed_all; - foreach_iter(exec_list_iterator, iter, *new_kills) { - kill_entry *k = (kill_entry *)iter.get(); + foreach_list(n, new_kills) { + kill_entry *k = (kill_entry *) n; kill(k->var); } @@ -292,8 +291,8 @@ ir_copy_propagation_visitor::kill(ir_variable *var) assert(var != NULL); /* Remove any entries currently in the ACP for this kill. */ - foreach_iter(exec_list_iterator, iter, *acp) { - acp_entry *entry = (acp_entry *)iter.get(); + foreach_list_safe(n, acp) { + acp_entry *entry = (acp_entry *) n; if (entry->lhs == var || entry->rhs == var) { entry->remove(); diff --git a/mesalib/src/glsl/opt_copy_propagation_elements.cpp b/mesalib/src/glsl/opt_copy_propagation_elements.cpp index ba8a0f532..cc53e0dd0 100644 --- a/mesalib/src/glsl/opt_copy_propagation_elements.cpp +++ b/mesalib/src/glsl/opt_copy_propagation_elements.cpp @@ -244,8 +244,8 @@ ir_copy_propagation_elements_visitor::handle_rvalue(ir_rvalue **ir) /* Try to find ACP entries covering swizzle_chan[], hoping they're * the same source variable. */ - foreach_iter(exec_list_iterator, iter, *this->acp) { - acp_entry *entry = (acp_entry *)iter.get(); + foreach_list(n, this->acp) { + acp_entry *entry = (acp_entry *) n; if (var == entry->lhs) { for (int c = 0; c < chans; c++) { @@ -293,15 +293,14 @@ ir_visitor_status ir_copy_propagation_elements_visitor::visit_enter(ir_call *ir) { /* Do copy propagation on call parameters, but skip any out params */ - exec_list_iterator sig_param_iter = ir->callee->parameters.iterator(); - foreach_iter(exec_list_iterator, iter, ir->actual_parameters) { - ir_variable *sig_param = (ir_variable *)sig_param_iter.get(); - ir_instruction *ir = (ir_instruction *)iter.get(); + foreach_two_lists(formal_node, &ir->callee->parameters, + actual_node, &ir->actual_parameters) { + ir_variable *sig_param = (ir_variable *) formal_node; + ir_rvalue *ir = (ir_rvalue *) actual_node; if (sig_param->data.mode != ir_var_function_out && sig_param->data.mode != ir_var_function_inout) { ir->accept(this); } - sig_param_iter.next(); } /* Since we're unlinked, we don't (necessarily) know the side effects of @@ -325,8 +324,8 @@ ir_copy_propagation_elements_visitor::handle_if_block(exec_list *instructions) this->killed_all = false; /* Populate the initial acp with a copy of the original */ - foreach_iter(exec_list_iterator, iter, *orig_acp) { - acp_entry *a = (acp_entry *)iter.get(); + foreach_list(n, orig_acp) { + acp_entry *a = (acp_entry *) n; this->acp->push_tail(new(this->mem_ctx) acp_entry(a)); } diff --git a/mesalib/src/glsl/opt_dead_builtin_varyings.cpp b/mesalib/src/glsl/opt_dead_builtin_varyings.cpp index a939a2b64..c2a306e7b 100644 --- a/mesalib/src/glsl/opt_dead_builtin_varyings.cpp +++ b/mesalib/src/glsl/opt_dead_builtin_varyings.cpp @@ -512,7 +512,7 @@ do_dead_builtin_varyings(struct gl_context *ctx, tfeedback_decl *tfeedback_decls) { /* Lower the gl_FragData array to separate variables. */ - if (consumer && consumer->Type == GL_FRAGMENT_SHADER) { + if (consumer && consumer->Stage == MESA_SHADER_FRAGMENT) { lower_fragdata_array(consumer->ir); } @@ -574,7 +574,7 @@ do_dead_builtin_varyings(struct gl_context *ctx, * This doesn't prevent elimination of the gl_TexCoord elements which * are not read by the fragment shader. We want to eliminate those anyway. */ - if (consumer->Type == GL_FRAGMENT_SHADER) { + if (consumer->Stage == MESA_SHADER_FRAGMENT) { producer_info.texcoord_usage = (1 << MAX_TEXTURE_COORD_UNITS) - 1; } diff --git a/mesalib/src/glsl/opt_dead_code.cpp b/mesalib/src/glsl/opt_dead_code.cpp index a8d8b4a39..af53d94fd 100644 --- a/mesalib/src/glsl/opt_dead_code.cpp +++ b/mesalib/src/glsl/opt_dead_code.cpp @@ -129,13 +129,12 @@ do_dead_code_unlinked(exec_list *instructions) { bool progress = false; - foreach_iter(exec_list_iterator, iter, *instructions) { - ir_instruction *ir = (ir_instruction *)iter.get(); + foreach_list(n, instructions) { + ir_instruction *ir = (ir_instruction *) n; ir_function *f = ir->as_function(); if (f) { - foreach_iter(exec_list_iterator, sigiter, *f) { - ir_function_signature *sig = - (ir_function_signature *) sigiter.get(); + foreach_list(signode, &f->signatures) { + ir_function_signature *sig = (ir_function_signature *) signode; /* The setting of the uniform_locations_assigned flag here is * irrelevent. If there is a uniform declaration encountered * inside the body of the function, something has already gone diff --git a/mesalib/src/glsl/opt_dead_code_local.cpp b/mesalib/src/glsl/opt_dead_code_local.cpp index 43a01662a..e7d46edbe 100644 --- a/mesalib/src/glsl/opt_dead_code_local.cpp +++ b/mesalib/src/glsl/opt_dead_code_local.cpp @@ -70,8 +70,8 @@ public: void kill_channels(ir_variable *const var, int used) { - foreach_iter(exec_list_iterator, iter, *this->assignments) { - assignment_entry *entry = (assignment_entry *)iter.get(); + foreach_list_safe(n, this->assignments) { + assignment_entry *entry = (assignment_entry *) n; if (entry->lhs == var) { if (var->type->is_scalar() || var->type->is_vector()) { @@ -119,8 +119,8 @@ public: /* For the purpose of dead code elimination, emitting a vertex counts as * "reading" all of the currently assigned output variables. */ - foreach_iter(exec_list_iterator, iter, *this->assignments) { - assignment_entry *entry = (assignment_entry *)iter.get(); + foreach_list_safe(n, this->assignments) { + assignment_entry *entry = (assignment_entry *) n; if (entry->lhs->data.mode == ir_var_shader_out) { if (debug) printf("kill %s\n", entry->lhs->name); @@ -196,8 +196,8 @@ process_assignment(void *ctx, ir_assignment *ir, exec_list *assignments) printf("looking for %s.0x%01x to remove\n", var->name, ir->write_mask); - foreach_iter(exec_list_iterator, iter, *assignments) { - assignment_entry *entry = (assignment_entry *)iter.get(); + foreach_list_safe(n, assignments) { + assignment_entry *entry = (assignment_entry *) n; if (entry->lhs != var) continue; @@ -258,8 +258,8 @@ process_assignment(void *ctx, ir_assignment *ir, exec_list *assignments) */ if (debug) printf("looking for %s to remove\n", var->name); - foreach_iter(exec_list_iterator, iter, *assignments) { - assignment_entry *entry = (assignment_entry *)iter.get(); + foreach_list_safe(n, assignments) { + assignment_entry *entry = (assignment_entry *) n; if (entry->lhs == var) { if (debug) @@ -280,8 +280,8 @@ process_assignment(void *ctx, ir_assignment *ir, exec_list *assignments) printf("add %s\n", var->name); printf("current entries\n"); - foreach_iter(exec_list_iterator, iter, *assignments) { - assignment_entry *entry = (assignment_entry *)iter.get(); + foreach_list(n, assignments) { + assignment_entry *entry = (assignment_entry *) n; printf(" %s (0x%01x)\n", entry->lhs->name, entry->available); } diff --git a/mesalib/src/glsl/opt_dead_functions.cpp b/mesalib/src/glsl/opt_dead_functions.cpp index cd3b2c12e..8bb278e45 100644 --- a/mesalib/src/glsl/opt_dead_functions.cpp +++ b/mesalib/src/glsl/opt_dead_functions.cpp @@ -74,8 +74,8 @@ public: signature_entry * ir_dead_functions_visitor::get_signature_entry(ir_function_signature *sig) { - foreach_iter(exec_list_iterator, iter, this->signature_list) { - signature_entry *entry = (signature_entry *)iter.get(); + foreach_list(n, &this->signature_list) { + signature_entry *entry = (signature_entry *) n; if (entry->signature == sig) return entry; } @@ -123,8 +123,8 @@ do_dead_functions(exec_list *instructions) * the unused ones, and remove function definitions that have no more * signatures. */ - foreach_iter(exec_list_iterator, iter, v.signature_list) { - signature_entry *entry = (signature_entry *)iter.get(); + foreach_list_safe(n, &v.signature_list) { + signature_entry *entry = (signature_entry *) n; if (!entry->used) { entry->signature->remove(); @@ -137,8 +137,8 @@ do_dead_functions(exec_list *instructions) /* We don't just do this above when we nuked a signature because of * const pointers. */ - foreach_iter(exec_list_iterator, iter, *instructions) { - ir_instruction *ir = (ir_instruction *)iter.get(); + foreach_list_safe(n, instructions) { + ir_instruction *ir = (ir_instruction *) n; ir_function *func = ir->as_function(); if (func && func->signatures.is_empty()) { diff --git a/mesalib/src/glsl/opt_function_inlining.cpp b/mesalib/src/glsl/opt_function_inlining.cpp index c8f42a424..9649598dd 100644 --- a/mesalib/src/glsl/opt_function_inlining.cpp +++ b/mesalib/src/glsl/opt_function_inlining.cpp @@ -107,7 +107,7 @@ ir_call::generate_inline(ir_instruction *next_ir) ht = hash_table_ctor(0, hash_table_pointer_hash, hash_table_pointer_compare); num_parameters = 0; - foreach_iter(exec_list_iterator, iter_sig, this->callee->parameters) + foreach_list(n, &this->callee->parameters) num_parameters++; parameters = new ir_variable *[num_parameters]; @@ -116,11 +116,10 @@ ir_call::generate_inline(ir_instruction *next_ir) * and set up the mapping of real function body variables to ours. */ i = 0; - exec_list_iterator sig_param_iter = this->callee->parameters.iterator(); - exec_list_iterator param_iter = this->actual_parameters.iterator(); - for (i = 0; i < num_parameters; i++) { - ir_variable *sig_param = (ir_variable *) sig_param_iter.get(); - ir_rvalue *param = (ir_rvalue *) param_iter.get(); + foreach_two_lists(formal_node, &this->callee->parameters, + actual_node, &this->actual_parameters) { + ir_variable *sig_param = (ir_variable *) formal_node; + ir_rvalue *param = (ir_rvalue *) actual_node; /* Generate a new variable for the parameter. */ if (sig_param->type->contains_opaque()) { @@ -154,15 +153,14 @@ ir_call::generate_inline(ir_instruction *next_ir) next_ir->insert_before(assign); } - sig_param_iter.next(); - param_iter.next(); + ++i; } exec_list new_instructions; /* Generate the inlined body of the function to a new list */ - foreach_iter(exec_list_iterator, iter, callee->body) { - ir_instruction *ir = (ir_instruction *)iter.get(); + foreach_list(n, &callee->body) { + ir_instruction *ir = (ir_instruction *) n; ir_instruction *new_ir = ir->clone(ctx, ht); new_instructions.push_tail(new_ir); @@ -172,11 +170,10 @@ ir_call::generate_inline(ir_instruction *next_ir) /* If any opaque types were passed in, replace any deref of the * opaque variable with a deref of the argument. */ - param_iter = this->actual_parameters.iterator(); - sig_param_iter = this->callee->parameters.iterator(); - for (i = 0; i < num_parameters; i++) { - ir_instruction *const param = (ir_instruction *) param_iter.get(); - ir_variable *sig_param = (ir_variable *) sig_param_iter.get(); + foreach_two_lists(formal_node, &this->callee->parameters, + actual_node, &this->actual_parameters) { + ir_rvalue *const param = (ir_rvalue *) actual_node; + ir_variable *sig_param = (ir_variable *) formal_node; if (sig_param->type->contains_opaque()) { ir_dereference *deref = param->as_dereference(); @@ -184,8 +181,6 @@ ir_call::generate_inline(ir_instruction *next_ir) assert(deref); do_variable_replacement(&new_instructions, sig_param, deref); } - param_iter.next(); - sig_param_iter.next(); } /* Now push those new instructions in. */ @@ -195,11 +190,10 @@ ir_call::generate_inline(ir_instruction *next_ir) * variables to our own. */ i = 0; - param_iter = this->actual_parameters.iterator(); - sig_param_iter = this->callee->parameters.iterator(); - for (i = 0; i < num_parameters; i++) { - ir_instruction *const param = (ir_instruction *) param_iter.get(); - const ir_variable *const sig_param = (ir_variable *) sig_param_iter.get(); + foreach_two_lists(formal_node, &this->callee->parameters, + actual_node, &this->actual_parameters) { + ir_rvalue *const param = (ir_rvalue *) actual_node; + const ir_variable *const sig_param = (ir_variable *) formal_node; /* Move our param variable into the actual param if it's an 'out' type. */ if (parameters[i] && (sig_param->data.mode == ir_var_function_out || @@ -212,8 +206,7 @@ ir_call::generate_inline(ir_instruction *next_ir) next_ir->insert_before(assign); } - param_iter.next(); - sig_param_iter.next(); + ++i; } delete [] parameters; @@ -349,8 +342,8 @@ ir_variable_replacement_visitor::visit_leave(ir_dereference_record *ir) ir_visitor_status ir_variable_replacement_visitor::visit_leave(ir_call *ir) { - foreach_iter(exec_list_iterator, iter, *ir) { - ir_rvalue *param = (ir_rvalue *)iter.get(); + foreach_list_safe(n, &ir->actual_parameters) { + ir_rvalue *param = (ir_rvalue *) n; ir_rvalue *new_param = param; replace_rvalue(&new_param); diff --git a/mesalib/src/glsl/opt_if_simplification.cpp b/mesalib/src/glsl/opt_if_simplification.cpp index db59b131d..2bec8252e 100644 --- a/mesalib/src/glsl/opt_if_simplification.cpp +++ b/mesalib/src/glsl/opt_if_simplification.cpp @@ -90,13 +90,13 @@ ir_if_simplification_visitor::visit_leave(ir_if *ir) * that matters out. */ if (condition_constant->value.b[0]) { - foreach_iter(exec_list_iterator, then_iter, ir->then_instructions) { - ir_instruction *then_ir = (ir_instruction *)then_iter.get(); + foreach_list_safe(n, &ir->then_instructions) { + ir_instruction *then_ir = (ir_instruction *) n; ir->insert_before(then_ir); } } else { - foreach_iter(exec_list_iterator, else_iter, ir->else_instructions) { - ir_instruction *else_ir = (ir_instruction *)else_iter.get(); + foreach_list_safe(n, &ir->else_instructions) { + ir_instruction *else_ir = (ir_instruction *) n; ir->insert_before(else_ir); } } diff --git a/mesalib/src/glsl/opt_structure_splitting.cpp b/mesalib/src/glsl/opt_structure_splitting.cpp index 414f0000d..1ec537b13 100644 --- a/mesalib/src/glsl/opt_structure_splitting.cpp +++ b/mesalib/src/glsl/opt_structure_splitting.cpp @@ -107,8 +107,8 @@ ir_structure_reference_visitor::get_variable_entry(ir_variable *var) || var->data.mode == ir_var_shader_in || var->data.mode == ir_var_shader_out) return NULL; - foreach_iter(exec_list_iterator, iter, this->variable_list) { - variable_entry *entry = (variable_entry *)iter.get(); + foreach_list(n, &this->variable_list) { + variable_entry *entry = (variable_entry *) n; if (entry->var == var) return entry; } @@ -209,8 +209,8 @@ ir_structure_splitting_visitor::get_splitting_entry(ir_variable *var) if (!var->type->is_record()) return NULL; - foreach_iter(exec_list_iterator, iter, *this->variable_list) { - variable_entry *entry = (variable_entry *)iter.get(); + foreach_list(n, this->variable_list) { + variable_entry *entry = (variable_entry *) n; if (entry->var == var) { return entry; } @@ -315,8 +315,8 @@ do_structure_splitting(exec_list *instructions) visit_list_elements(&refs, instructions); /* Trim out variables we can't split. */ - foreach_iter(exec_list_iterator, iter, refs.variable_list) { - variable_entry *entry = (variable_entry *)iter.get(); + foreach_list_safe(n, &refs.variable_list) { + variable_entry *entry = (variable_entry *) n; if (debug) { printf("structure %s@%p: decl %d, whole_access %d\n", @@ -337,8 +337,8 @@ do_structure_splitting(exec_list *instructions) /* Replace the decls of the structures to be split with their split * components. */ - foreach_iter(exec_list_iterator, iter, refs.variable_list) { - variable_entry *entry = (variable_entry *)iter.get(); + foreach_list_safe(n, &refs.variable_list) { + variable_entry *entry = (variable_entry *) n; const struct glsl_type *type = entry->var->type; entry->mem_ctx = ralloc_parent(entry->var); diff --git a/mesalib/src/glsl/opt_tree_grafting.cpp b/mesalib/src/glsl/opt_tree_grafting.cpp index 6d75a1573..f3bd580af 100644 --- a/mesalib/src/glsl/opt_tree_grafting.cpp +++ b/mesalib/src/glsl/opt_tree_grafting.cpp @@ -204,11 +204,10 @@ ir_tree_grafting_visitor::visit_enter(ir_function_signature *ir) ir_visitor_status ir_tree_grafting_visitor::visit_enter(ir_call *ir) { - exec_list_iterator sig_iter = ir->callee->parameters.iterator(); - /* Reminder: iterating ir_call iterates its parameters. */ - foreach_iter(exec_list_iterator, iter, *ir) { - ir_variable *sig_param = (ir_variable *)sig_iter.get(); - ir_rvalue *ir = (ir_rvalue *)iter.get(); + foreach_two_lists(formal_node, &ir->callee->parameters, + actual_node, &ir->actual_parameters) { + ir_variable *sig_param = (ir_variable *) formal_node; + ir_rvalue *ir = (ir_rvalue *) actual_node; ir_rvalue *new_ir = ir; if (sig_param->data.mode != ir_var_function_in @@ -222,7 +221,6 @@ ir_tree_grafting_visitor::visit_enter(ir_call *ir) ir->replace_with(new_ir); return visit_stop; } - sig_iter.next(); } if (ir->return_deref && check_graft(ir, ir->return_deref->var) == visit_stop) diff --git a/mesalib/src/glsl/s_expression.cpp b/mesalib/src/glsl/s_expression.cpp index 1bdf6bca6..6906ff0eb 100644 --- a/mesalib/src/glsl/s_expression.cpp +++ b/mesalib/src/glsl/s_expression.cpp @@ -162,8 +162,8 @@ void s_symbol::print() void s_list::print() { printf("("); - foreach_iter(exec_list_iterator, it, this->subexpressions) { - s_expression *expr = (s_expression*) it.get(); + foreach_list(n, &this->subexpressions) { + s_expression *expr = (s_expression *) n; expr->print(); if (!expr->next->is_tail_sentinel()) printf(" "); @@ -201,11 +201,11 @@ s_match(s_expression *top, unsigned n, s_pattern *pattern, bool partial) return false; unsigned i = 0; - foreach_iter(exec_list_iterator, it, list->subexpressions) { + foreach_list(node, &list->subexpressions) { if (i >= n) return partial; /* More actual items than the pattern expected */ - s_expression *expr = (s_expression *) it.get(); + s_expression *expr = (s_expression *) node; if (expr == NULL || !pattern[i].match(expr)) return false; diff --git a/mesalib/src/glsl/standalone_scaffolding.cpp b/mesalib/src/glsl/standalone_scaffolding.cpp index cbff6d182..257d2e7a9 100644 --- a/mesalib/src/glsl/standalone_scaffolding.cpp +++ b/mesalib/src/glsl/standalone_scaffolding.cpp @@ -76,6 +76,7 @@ _mesa_new_shader(struct gl_context *ctx, GLuint name, GLenum type) shader = rzalloc(NULL, struct gl_shader); if (shader) { shader->Type = type; + shader->Stage = _mesa_shader_enum_to_shader_stage(type); shader->Name = name; shader->RefCount = 1; } @@ -126,16 +127,16 @@ void initialize_context_to_defaults(struct gl_context *ctx, gl_api api) ctx->Const.MaxClipPlanes = 6; ctx->Const.MaxTextureUnits = 2; ctx->Const.MaxTextureCoordUnits = 2; - ctx->Const.VertexProgram.MaxAttribs = 16; + ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs = 16; - ctx->Const.VertexProgram.MaxUniformComponents = 512; - ctx->Const.VertexProgram.MaxOutputComponents = 32; + ctx->Const.Program[MESA_SHADER_VERTEX].MaxUniformComponents = 512; + ctx->Const.Program[MESA_SHADER_VERTEX].MaxOutputComponents = 32; ctx->Const.MaxVarying = 8; /* == gl_MaxVaryingFloats / 4 */ - ctx->Const.VertexProgram.MaxTextureImageUnits = 0; + ctx->Const.Program[MESA_SHADER_VERTEX].MaxTextureImageUnits = 0; ctx->Const.MaxCombinedTextureImageUnits = 2; - ctx->Const.FragmentProgram.MaxTextureImageUnits = 2; - ctx->Const.FragmentProgram.MaxUniformComponents = 64; - ctx->Const.FragmentProgram.MaxInputComponents = 32; + ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits = 2; + ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxUniformComponents = 64; + ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxInputComponents = 32; ctx->Const.MaxDrawBuffers = 1; @@ -148,6 +149,6 @@ void initialize_context_to_defaults(struct gl_context *ctx, gl_api api) /* Default pragma settings */ options.DefaultPragmas.Optimize = true; - for (int sh = 0; sh < MESA_SHADER_TYPES; ++sh) + for (int sh = 0; sh < MESA_SHADER_STAGES; ++sh) memcpy(&ctx->ShaderCompilerOptions[sh], &options, sizeof(options)); } diff --git a/mesalib/src/glsl/standalone_scaffolding.h b/mesalib/src/glsl/standalone_scaffolding.h index 9f4818a8a..327fef2df 100644 --- a/mesalib/src/glsl/standalone_scaffolding.h +++ b/mesalib/src/glsl/standalone_scaffolding.h @@ -48,8 +48,8 @@ extern "C" void _mesa_shader_debug(struct gl_context *ctx, GLenum type, GLuint *id, const char *msg, int len); -static inline gl_shader_type -_mesa_shader_type_to_index(GLenum v) +static inline gl_shader_stage +_mesa_shader_enum_to_shader_stage(GLenum v) { switch (v) { case GL_VERTEX_SHADER: @@ -59,7 +59,7 @@ _mesa_shader_type_to_index(GLenum v) case GL_GEOMETRY_SHADER: return MESA_SHADER_GEOMETRY; default: - assert(!"bad value in _mesa_shader_type_to_index()"); + assert(!"bad value in _mesa_shader_enum_to_shader_stage()"); return MESA_SHADER_VERTEX; } } diff --git a/mesalib/src/glsl/test_optpass.cpp b/mesalib/src/glsl/test_optpass.cpp index 67e2ab2b1..1a15f3c63 100644 --- a/mesalib/src/glsl/test_optpass.cpp +++ b/mesalib/src/glsl/test_optpass.cpp @@ -204,11 +204,12 @@ int test_optpass(int argc, char **argv) struct gl_shader *shader = rzalloc(NULL, struct gl_shader); shader->Type = shader_type; + shader->Stage = _mesa_shader_enum_to_shader_stage(shader_type); string input = read_stdin_to_eof(); struct _mesa_glsl_parse_state *state - = new(shader) _mesa_glsl_parse_state(ctx, shader->Type, shader); + = new(shader) _mesa_glsl_parse_state(ctx, shader->Stage, shader); if (input_format_ir) { shader->ir = new(shader) exec_list; @@ -242,7 +243,7 @@ int test_optpass(int argc, char **argv) if (!state->error) { GLboolean progress; const struct gl_shader_compiler_options *options = - &ctx->ShaderCompilerOptions[_mesa_shader_type_to_index(shader_type)]; + &ctx->ShaderCompilerOptions[_mesa_shader_enum_to_shader_stage(shader_type)]; do { progress = do_optimization_passes(shader->ir, &argv[optind], argc - optind, quiet != 0, options); diff --git a/mesalib/src/hgl/GLDispatcher.cpp b/mesalib/src/hgl/GLDispatcher.cpp new file mode 100644 index 000000000..46b91d57c --- /dev/null +++ b/mesalib/src/hgl/GLDispatcher.cpp @@ -0,0 +1,72 @@ +/* + * Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. + * Copyright 2000-2012 Haiku, Inc. All Rights Reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Brian Paul <brian.e.paul@gmail.com> + * Philippe Houdoin <philippe.houdoin@free.fr> + * Alexander von Gluck IV <kallisti5@unixzen.com> + */ + + +extern "C" { +#include "glapi/glapi.h" +#include "glapi/glapi_priv.h" + +/* + * NOTE: this file portion implements C-based dispatch of the OpenGL entrypoints + * (glAccum, glBegin, etc). + * This code IS NOT USED if we're compiling on an x86 system and using + * the glapi_x86.S assembly code. + */ +#if !(defined(USE_X86_ASM) || defined(USE_SPARC_ASM)) + +#define KEYWORD1 PUBLIC +#define KEYWORD2 +#define NAME(func) gl##func + +#define DISPATCH(func, args, msg) \ + const struct _glapi_table* dispatch; \ + dispatch = _glapi_Dispatch ? _glapi_Dispatch : _glapi_get_dispatch();\ + (dispatch->func) args + +#define RETURN_DISPATCH(func, args, msg) \ + const struct _glapi_table* dispatch; \ + dispatch = _glapi_Dispatch ? _glapi_Dispatch : _glapi_get_dispatch();\ + return (dispatch->func) args + +#endif +} + + +/* NOTE: this file portion implement a thin OpenGL entrypoints dispatching + C++ wrapper class + */ + +#include "GLDispatcher.h" + +BGLDispatcher::BGLDispatcher() +{ +} + + +BGLDispatcher::~BGLDispatcher() +{ +} + + +status_t +BGLDispatcher::CheckTable(const struct _glapi_table* table) +{ + _glapi_check_table(table ? table : _glapi_get_dispatch()); + return B_OK; +} + + +status_t +BGLDispatcher::SetTable(struct _glapi_table* table) +{ + _glapi_set_dispatch(table); + return B_OK; +} diff --git a/mesalib/src/hgl/GLDispatcher.h b/mesalib/src/hgl/GLDispatcher.h new file mode 100644 index 000000000..44bca8ce5 --- /dev/null +++ b/mesalib/src/hgl/GLDispatcher.h @@ -0,0 +1,109 @@ +/* + * Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. + * Copyright 2000-2012 Haiku, Inc. All Rights Reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Brian Paul <brian.e.paul@gmail.com> + * Philippe Houdoin <philippe.houdoin@free.fr> + */ +#ifndef GLDISPATCHER_H +#define GLDISPATCHER_H + + +#include <BeBuild.h> +#include <GL/gl.h> +#include <SupportDefs.h> + +#include "glheader.h" + +extern "C" { +#include "glapi/glapi.h" +} + + +class BGLDispatcher +{ + // Private unimplemented copy constructors + BGLDispatcher(const BGLDispatcher &); + BGLDispatcher & operator=(const BGLDispatcher &); + + public: + BGLDispatcher(); + ~BGLDispatcher(); + + void SetCurrentContext(void* context); + void* CurrentContext(); + + struct _glapi_table* Table(); + status_t CheckTable( + const struct _glapi_table* dispatch = NULL); + status_t SetTable(struct _glapi_table* dispatch); + uint32 TableSize(); + + const _glapi_proc operator[](const char* functionName); + const char* operator[](uint32 offset); + + const _glapi_proc AddressOf(const char* functionName); + uint32 OffsetOf(const char* functionName); +}; + + +// Inlines methods +inline void +BGLDispatcher::SetCurrentContext(void* context) +{ + _glapi_set_context(context); +} + + +inline void* +BGLDispatcher::CurrentContext() +{ + return _glapi_get_context(); +} + + +inline struct _glapi_table* +BGLDispatcher::Table() +{ + return _glapi_get_dispatch(); +} + + +inline uint32 +BGLDispatcher::TableSize() +{ + return _glapi_get_dispatch_table_size(); +} + + +inline const _glapi_proc +BGLDispatcher::operator[](const char* functionName) +{ + return _glapi_get_proc_address(functionName); +} + + +inline const char* +BGLDispatcher::operator[](uint32 offset) +{ + return _glapi_get_proc_name((GLuint) offset); +} + + +inline const _glapi_proc +BGLDispatcher::AddressOf(const char* functionName) +{ + return _glapi_get_proc_address(functionName); +} + + +inline uint32 +BGLDispatcher::OffsetOf(const char* functionName) +{ + return (uint32) _glapi_get_proc_offset(functionName); +} + + +#endif // GLDISPATCHER_H diff --git a/mesalib/src/hgl/GLRenderer.cpp b/mesalib/src/hgl/GLRenderer.cpp new file mode 100644 index 000000000..4573a64a3 --- /dev/null +++ b/mesalib/src/hgl/GLRenderer.cpp @@ -0,0 +1,106 @@ +/* + * Copyright 2006-2008, Philippe Houdoin. All rights reserved. + * Distributed under the terms of the MIT License. + */ + + +#include <kernel/image.h> + +#include "GLRenderer.h" + +#include "GLDispatcher.h" + + +BGLRenderer::BGLRenderer(BGLView* view, ulong glOptions, + BGLDispatcher* dispatcher) + : + fRefCount(1), + fView(view), + fOptions(glOptions), + fDispatcher(dispatcher) +{ +} + + +BGLRenderer::~BGLRenderer() +{ + delete fDispatcher; +} + + +void +BGLRenderer::Acquire() +{ + atomic_add(&fRefCount, 1); +} + + +void +BGLRenderer::Release() +{ + if (atomic_add(&fRefCount, -1) < 1) + delete this; +} + + +void +BGLRenderer::LockGL() +{ +} + + +void +BGLRenderer::UnlockGL() +{ +} + + +void +BGLRenderer::SwapBuffers(bool VSync) +{ +} + + +void +BGLRenderer::Draw(BRect updateRect) +{ +} + + +status_t +BGLRenderer::CopyPixelsOut(BPoint source, BBitmap* dest) +{ + return B_ERROR; +} + + +status_t +BGLRenderer::CopyPixelsIn(BBitmap* source, BPoint dest) +{ + return B_ERROR; +} + + +void +BGLRenderer::FrameResized(float width, float height) +{ +} + + +void +BGLRenderer::DirectConnected(direct_buffer_info* info) +{ +} + + +void +BGLRenderer::EnableDirectMode(bool enabled) +{ +} + + +status_t BGLRenderer::_Reserved_Renderer_0(int32 n, void* p) { return B_ERROR; } +status_t BGLRenderer::_Reserved_Renderer_1(int32 n, void* p) { return B_ERROR; } +status_t BGLRenderer::_Reserved_Renderer_2(int32 n, void* p) { return B_ERROR; } +status_t BGLRenderer::_Reserved_Renderer_3(int32 n, void* p) { return B_ERROR; } +status_t BGLRenderer::_Reserved_Renderer_4(int32 n, void* p) { return B_ERROR; } diff --git a/mesalib/src/hgl/GLRendererRoster.cpp b/mesalib/src/hgl/GLRendererRoster.cpp new file mode 100644 index 000000000..1712a871c --- /dev/null +++ b/mesalib/src/hgl/GLRendererRoster.cpp @@ -0,0 +1,224 @@ +/* + * Copyright 2006-2012 Haiku, Inc. All Rights Reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Philippe Houdoin <philippe.houdoin@free.fr> + * Alexander von Gluck IV <kallisti5@unixzen.com> + */ + + +#include <driver_settings.h> +#include <image.h> + +#include <kernel/image.h> +#include <system/safemode_defs.h> + +#include <Directory.h> +#include <FindDirectory.h> +#include <Path.h> +#include <String.h> +#include "GLDispatcher.h" +#include "GLRendererRoster.h" + +#include <new> +#include <string.h> + + +extern "C" status_t _kern_get_safemode_option(const char* parameter, + char* buffer, size_t* _bufferSize); + + +GLRendererRoster::GLRendererRoster(BGLView* view, ulong options) + : + fNextID(0), + fView(view), + fOptions(options), + fSafeMode(false), + fABISubDirectory(NULL) +{ + char parameter[32]; + size_t parameterLength = sizeof(parameter); + + if (_kern_get_safemode_option(B_SAFEMODE_SAFE_MODE, + parameter, ¶meterLength) == B_OK) { + if (!strcasecmp(parameter, "enabled") || !strcasecmp(parameter, "on") + || !strcasecmp(parameter, "true") || !strcasecmp(parameter, "yes") + || !strcasecmp(parameter, "enable") || !strcmp(parameter, "1")) + fSafeMode = true; + } + + if (_kern_get_safemode_option(B_SAFEMODE_DISABLE_USER_ADD_ONS, + parameter, ¶meterLength) == B_OK) { + if (!strcasecmp(parameter, "enabled") || !strcasecmp(parameter, "on") + || !strcasecmp(parameter, "true") || !strcasecmp(parameter, "yes") + || !strcasecmp(parameter, "enable") || !strcmp(parameter, "1")) + fSafeMode = true; + } + + // We might run in compatibility mode on a system with a different ABI. The + // renderers matching our ABI can usually be found in respective + // subdirectories of the opengl add-ons directories. + system_info info; + if (get_system_info(&info) == B_OK + && (info.abi & B_HAIKU_ABI_MAJOR) + != (B_HAIKU_ABI & B_HAIKU_ABI_MAJOR)) { + switch (B_HAIKU_ABI & B_HAIKU_ABI_MAJOR) { + case B_HAIKU_ABI_GCC_2: + fABISubDirectory = "gcc2"; + break; + case B_HAIKU_ABI_GCC_4: + fABISubDirectory = "gcc4"; + break; + } + } + + AddDefaultPaths(); +} + + +GLRendererRoster::~GLRendererRoster() +{ + +} + + +BGLRenderer* +GLRendererRoster::GetRenderer(int32 id) +{ + RendererMap::const_iterator iterator = fRenderers.find(id); + if (iterator == fRenderers.end()) + return NULL; + + struct renderer_item item = iterator->second; + return item.renderer; +} + + +void +GLRendererRoster::AddDefaultPaths() +{ + // add user directories first, so that they can override system renderers + const directory_which paths[] = { + B_USER_NONPACKAGED_ADDONS_DIRECTORY, + B_USER_ADDONS_DIRECTORY, + B_SYSTEM_ADDONS_DIRECTORY, + }; + + for (uint32 i = fSafeMode ? 4 : 0; + i < sizeof(paths) / sizeof(paths[0]); i++) { + BPath path; + status_t status = find_directory(paths[i], &path, true); + if (status == B_OK && path.Append("opengl") == B_OK) + AddPath(path.Path()); + } +} + + +status_t +GLRendererRoster::AddPath(const char* path) +{ + BDirectory directory(path); + status_t status = directory.InitCheck(); + if (status < B_OK) + return status; + + // if a subdirectory for our ABI exists, use that instead + if (fABISubDirectory != NULL) { + BEntry entry(&directory, fABISubDirectory); + if (entry.IsDirectory()) { + status = directory.SetTo(&entry); + if (status != B_OK) + return status; + } + } + + node_ref nodeRef; + status = directory.GetNodeRef(&nodeRef); + if (status < B_OK) + return status; + + int32 count = 0; + int32 files = 0; + + entry_ref ref; + BEntry entry; + while (directory.GetNextRef(&ref) == B_OK) { + entry.SetTo(&ref); + if (entry.InitCheck() == B_OK && !entry.IsFile()) + continue; + + if (CreateRenderer(ref) == B_OK) + count++; + + files++; + } + + if (files != 0 && count == 0) + return B_BAD_VALUE; + + return B_OK; +} + + +status_t +GLRendererRoster::AddRenderer(BGLRenderer* renderer, + image_id image, const entry_ref* ref, ino_t node) +{ + renderer_item item; + item.renderer = renderer; + item.image = image; + item.node = node; + if (ref != NULL) + item.ref = *ref; + + try { + fRenderers[fNextID] = item; + } catch (...) { + return B_NO_MEMORY; + } + + renderer->fOwningRoster = this; + renderer->fID = fNextID++; + return B_OK; +} + + +status_t +GLRendererRoster::CreateRenderer(const entry_ref& ref) +{ + BEntry entry(&ref); + node_ref nodeRef; + status_t status = entry.GetNodeRef(&nodeRef); + if (status < B_OK) + return status; + + BPath path(&ref); + image_id image = load_add_on(path.Path()); + if (image < B_OK) + return image; + + BGLRenderer* (*instantiate_renderer) + (BGLView* view, ulong options, BGLDispatcher* dispatcher); + + status = get_image_symbol(image, "instantiate_gl_renderer", + B_SYMBOL_TYPE_TEXT, (void**)&instantiate_renderer); + if (status == B_OK) { + BGLRenderer* renderer + = instantiate_renderer(fView, fOptions, new BGLDispatcher()); + if (!renderer) { + unload_add_on(image); + return B_UNSUPPORTED; + } + + if (AddRenderer(renderer, image, &ref, nodeRef.node) != B_OK) { + renderer->Release(); + // this will delete the renderer + unload_add_on(image); + } + return B_OK; + } + unload_add_on(image); + + return status; +} diff --git a/mesalib/src/hgl/GLRendererRoster.h b/mesalib/src/hgl/GLRendererRoster.h new file mode 100644 index 000000000..5c8da2711 --- /dev/null +++ b/mesalib/src/hgl/GLRendererRoster.h @@ -0,0 +1,51 @@ +/* + * Copyright 2006-2012, Haiku, Inc. All Rights Reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Philippe Houdoin <philippe.houdoin@free.fr> + */ +#ifndef _GLRENDERER_ROSTER_H +#define _GLRENDERER_ROSTER_H + + +#include <GLRenderer.h> + +#include <map> + + +struct renderer_item { + BGLRenderer* renderer; + entry_ref ref; + ino_t node; + image_id image; +}; + +typedef std::map<renderer_id, renderer_item> RendererMap; + + +class GLRendererRoster { + public: + GLRendererRoster(BGLView* view, ulong options); + virtual ~GLRendererRoster(); + + BGLRenderer* GetRenderer(int32 id = 0); + + private: + void AddDefaultPaths(); + status_t AddPath(const char* path); + status_t AddRenderer(BGLRenderer* renderer, + image_id image, const entry_ref* ref, ino_t node); + status_t CreateRenderer(const entry_ref& ref); + + RendererMap fRenderers; + int32 fNextID; + BGLView* fView; + ulong fOptions; + bool fSafeMode; + const char* fABISubDirectory; + +}; + + +#endif /* _GLRENDERER_ROSTER_H */ diff --git a/mesalib/src/hgl/GLView.cpp b/mesalib/src/hgl/GLView.cpp new file mode 100644 index 000000000..9ae5b5c83 --- /dev/null +++ b/mesalib/src/hgl/GLView.cpp @@ -0,0 +1,643 @@ +/* + * Copyright 2006-2012, Haiku. All rights reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Jérôme Duval, korli@users.berlios.de + * Philippe Houdoin, philippe.houdoin@free.fr + * Stefano Ceccherini, burton666@libero.it + */ + +#include <kernel/image.h> + +#include <GLView.h> + +#include <assert.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include <DirectWindow.h> +#include <GLRenderer.h> + +#include "interface/DirectWindowPrivate.h" +#include "GLDispatcher.h" +#include "GLRendererRoster.h" + + +struct glview_direct_info { + direct_buffer_info* direct_info; + bool direct_connected; + bool enable_direct_mode; + + glview_direct_info(); + ~glview_direct_info(); +}; + + +BGLView::BGLView(BRect rect, const char* name, ulong resizingMode, ulong mode, + ulong options) + : + BView(rect, name, B_FOLLOW_ALL_SIDES, mode | B_WILL_DRAW | B_FRAME_EVENTS), + // | B_FULL_UPDATE_ON_RESIZE) + fGc(NULL), + fOptions(options), + fDitherCount(0), + fDrawLock("BGLView draw lock"), + fDisplayLock("BGLView display lock"), + fClipInfo(NULL), + fRenderer(NULL), + fRoster(NULL), + fDitherMap(NULL) +{ + fRoster = new GLRendererRoster(this, options); +} + + +BGLView::~BGLView() +{ + delete fClipInfo; + if (fRenderer) + fRenderer->Release(); +} + + +void +BGLView::LockGL() +{ + // TODO: acquire the OpenGL API lock it on this glview + + fDisplayLock.Lock(); + if (fRenderer) + fRenderer->LockGL(); +} + + +void +BGLView::UnlockGL() +{ + if (fRenderer) + fRenderer->UnlockGL(); + fDisplayLock.Unlock(); + + // TODO: release the GL API lock to others glviews +} + + +void +BGLView::SwapBuffers() +{ + SwapBuffers(false); +} + + +void +BGLView::SwapBuffers(bool vSync) +{ + if (fRenderer) { + _LockDraw(); + fRenderer->SwapBuffers(vSync); + _UnlockDraw(); + } +} + + +BView* +BGLView::EmbeddedView() +{ + return NULL; +} + + +void* +BGLView::GetGLProcAddress(const char* procName) +{ + BGLDispatcher* glDispatcher = NULL; + + if (fRenderer) + glDispatcher = fRenderer->GLDispatcher(); + + if (glDispatcher) + return (void*)glDispatcher->AddressOf(procName); + + return NULL; +} + + +status_t +BGLView::CopyPixelsOut(BPoint source, BBitmap* dest) +{ + if (!fRenderer) + return B_ERROR; + + if (!dest || !dest->Bounds().IsValid()) + return B_BAD_VALUE; + + return fRenderer->CopyPixelsOut(source, dest); +} + + +status_t +BGLView::CopyPixelsIn(BBitmap* source, BPoint dest) +{ + if (!fRenderer) + return B_ERROR; + + if (!source || !source->Bounds().IsValid()) + return B_BAD_VALUE; + + return fRenderer->CopyPixelsIn(source, dest); +} + + +/*! Mesa's GLenum is not ulong but uint, so we can't use GLenum + without breaking this method signature. + Instead, we have to use the effective BeOS's SGI OpenGL GLenum type: + unsigned long. + */ +void +BGLView::ErrorCallback(unsigned long errorCode) +{ + char msg[32]; + sprintf(msg, "GL: Error code $%04lx.", errorCode); + // TODO: under BeOS R5, it call debugger(msg); + fprintf(stderr, "%s\n", msg); +} + + +void +BGLView::Draw(BRect updateRect) +{ + if (fRenderer) { + _LockDraw(); + fRenderer->Draw(updateRect); + _UnlockDraw(); + return; + } + // TODO: auto-size and center the string + MovePenTo(8, 32); + DrawString("No OpenGL renderer available!"); +} + + +void +BGLView::AttachedToWindow() +{ + BView::AttachedToWindow(); + + fBounds = Bounds(); + for (BView* view = this; view != NULL; view = view->Parent()) + view->ConvertToParent(&fBounds); + + fRenderer = fRoster->GetRenderer(); + if (fRenderer != NULL) { + // Jackburton: The following code was commented because it doesn't look + // good in "direct" mode: + // when the window is moved, the app_server doesn't paint the view's + // background, and the stuff behind the window itself shows up. + // Setting the view color to black, instead, looks a bit more elegant. +#if 0 + // Don't paint white window background when resized + SetViewColor(B_TRANSPARENT_32_BIT); +#else + SetViewColor(0, 0, 0); +#endif + + // Set default OpenGL viewport: + LockGL(); + glViewport(0, 0, Bounds().IntegerWidth(), Bounds().IntegerHeight()); + UnlockGL(); + fRenderer->FrameResized(Bounds().IntegerWidth(), + Bounds().IntegerHeight()); + + if (fClipInfo) { + fRenderer->DirectConnected(fClipInfo->direct_info); + fRenderer->EnableDirectMode(fClipInfo->enable_direct_mode); + } + + return; + } + + fprintf(stderr, "no renderer found! \n"); + + // No Renderer, no rendering. Setup a minimal "No Renderer" string drawing + // context + SetFont(be_bold_font); + // SetFontSize(16); +} + + +void +BGLView::AllAttached() +{ + BView::AllAttached(); +} + + +void +BGLView::DetachedFromWindow() +{ + if (fRenderer) + fRenderer->Release(); + fRenderer = NULL; + + BView::DetachedFromWindow(); +} + + +void +BGLView::AllDetached() +{ + BView::AllDetached(); +} + + +void +BGLView::FrameResized(float width, float height) +{ + fBounds = Bounds(); + for (BView* v = this; v; v = v->Parent()) + v->ConvertToParent(&fBounds); + + if (fRenderer) { + LockGL(); + _LockDraw(); + _CallDirectConnected(); + fRenderer->FrameResized(width, height); + _UnlockDraw(); + UnlockGL(); + } + + BView::FrameResized(width, height); +} + + +status_t +BGLView::Perform(perform_code d, void* arg) +{ + return BView::Perform(d, arg); +} + + +status_t +BGLView::Archive(BMessage* data, bool deep) const +{ + return BView::Archive(data, deep); +} + + +void +BGLView::MessageReceived(BMessage* msg) +{ + BView::MessageReceived(msg); +} + + +void +BGLView::SetResizingMode(uint32 mode) +{ + BView::SetResizingMode(mode); +} + + +void +BGLView::GetPreferredSize(float* _width, float* _height) +{ + if (_width) + *_width = 0; + if (_height) + *_height = 0; +} + + +void +BGLView::Show() +{ + BView::Show(); +} + + +void +BGLView::Hide() +{ + BView::Hide(); +} + + +BHandler* +BGLView::ResolveSpecifier(BMessage* msg, int32 index, BMessage* specifier, + int32 form, const char* property) +{ + return BView::ResolveSpecifier(msg, index, specifier, form, property); +} + + +status_t +BGLView::GetSupportedSuites(BMessage* data) +{ + return BView::GetSupportedSuites(data); +} + + +void +BGLView::DirectConnected(direct_buffer_info* info) +{ + if (fClipInfo == NULL) { + fClipInfo = new (std::nothrow) glview_direct_info(); + if (fClipInfo == NULL) + return; + } + + direct_buffer_info* localInfo = fClipInfo->direct_info; + + switch (info->buffer_state & B_DIRECT_MODE_MASK) { + case B_DIRECT_START: + fClipInfo->direct_connected = true; + memcpy(localInfo, info, DIRECT_BUFFER_INFO_AREA_SIZE); + _UnlockDraw(); + break; + + case B_DIRECT_MODIFY: + _LockDraw(); + memcpy(localInfo, info, DIRECT_BUFFER_INFO_AREA_SIZE); + _UnlockDraw(); + break; + + case B_DIRECT_STOP: + fClipInfo->direct_connected = false; + _LockDraw(); + break; + } + + if (fRenderer) + _CallDirectConnected(); +} + + +void +BGLView::EnableDirectMode(bool enabled) +{ + if (fRenderer) + fRenderer->EnableDirectMode(enabled); + if (fClipInfo == NULL) { + fClipInfo = new (std::nothrow) glview_direct_info(); + if (fClipInfo == NULL) + return; + } + + fClipInfo->enable_direct_mode = enabled; +} + + +void +BGLView::_LockDraw() +{ + if (!fClipInfo || !fClipInfo->enable_direct_mode) + return; + + fDrawLock.Lock(); +} + + +void +BGLView::_UnlockDraw() +{ + if (!fClipInfo || !fClipInfo->enable_direct_mode) + return; + + fDrawLock.Unlock(); +} + + +void +BGLView::_CallDirectConnected() +{ + if (!fClipInfo) + return; + + direct_buffer_info* localInfo = fClipInfo->direct_info; + direct_buffer_info* info = (direct_buffer_info*)malloc( + DIRECT_BUFFER_INFO_AREA_SIZE); + if (info == NULL) + return; + + memcpy(info, localInfo, DIRECT_BUFFER_INFO_AREA_SIZE); + + // Collect the rects into a BRegion, then clip to the view's bounds + BRegion region; + for (uint32 c = 0; c < localInfo->clip_list_count; c++) + region.Include(localInfo->clip_list[c]); + BRegion boundsRegion = fBounds.OffsetByCopy(localInfo->window_bounds.left, + localInfo->window_bounds.top); + info->window_bounds = boundsRegion.RectAtInt(0); + // window_bounds are now view bounds + region.IntersectWith(&boundsRegion); + + info->clip_list_count = region.CountRects(); + info->clip_bounds = region.FrameInt(); + + for (uint32 c = 0; c < info->clip_list_count; c++) + info->clip_list[c] = region.RectAtInt(c); + fRenderer->DirectConnected(info); + free(info); +} + + +//---- virtual reserved methods ---------- + + +void BGLView::_ReservedGLView1() {} +void BGLView::_ReservedGLView2() {} +void BGLView::_ReservedGLView3() {} +void BGLView::_ReservedGLView4() {} +void BGLView::_ReservedGLView5() {} +void BGLView::_ReservedGLView6() {} +void BGLView::_ReservedGLView7() {} +void BGLView::_ReservedGLView8() {} + + +// #pragma mark - + + +// BeOS compatibility: contrary to others BView's contructors, +// BGLView one wants a non-const name argument. +BGLView::BGLView(BRect rect, char* name, ulong resizingMode, ulong mode, + ulong options) + : + BView(rect, name, B_FOLLOW_ALL_SIDES, mode | B_WILL_DRAW | B_FRAME_EVENTS), + fGc(NULL), + fOptions(options), + fDitherCount(0), + fDrawLock("BGLView draw lock"), + fDisplayLock("BGLView display lock"), + fClipInfo(NULL), + fRenderer(NULL), + fRoster(NULL), + fDitherMap(NULL) +{ + fRoster = new GLRendererRoster(this, options); +} + + +#if 0 +// TODO: implement BGLScreen class... + + +BGLScreen::BGLScreen(char* name, ulong screenMode, ulong options, + status_t* error, bool debug) + : + BWindowScreen(name, screenMode, error, debug) +{ +} + + +BGLScreen::~BGLScreen() +{ +} + + +void +BGLScreen::LockGL() +{ +} + + +void +BGLScreen::UnlockGL() +{ +} + + +void +BGLScreen::SwapBuffers() +{ +} + + +void +BGLScreen::ErrorCallback(unsigned long errorCode) +{ + // Mesa's GLenum is not ulong but uint! + char msg[32]; + sprintf(msg, "GL: Error code $%04lx.", errorCode); + // debugger(msg); + fprintf(stderr, "%s\n", msg); + return; +} + + +void +BGLScreen::ScreenConnected(bool enabled) +{ +} + + +void +BGLScreen::FrameResized(float width, float height) +{ + return BWindowScreen::FrameResized(width, height); +} + + +status_t +BGLScreen::Perform(perform_code d, void* arg) +{ + return BWindowScreen::Perform(d, arg); +} + + +status_t +BGLScreen::Archive(BMessage* data, bool deep) const +{ + return BWindowScreen::Archive(data, deep); +} + + +void +BGLScreen::MessageReceived(BMessage* msg) +{ + BWindowScreen::MessageReceived(msg); +} + + +void +BGLScreen::Show() +{ + BWindowScreen::Show(); +} + + +void +BGLScreen::Hide() +{ + BWindowScreen::Hide(); +} + + +BHandler* +BGLScreen::ResolveSpecifier(BMessage* msg, int32 index, BMessage* specifier, + int32 form, const char* property) +{ + return BWindowScreen::ResolveSpecifier(msg, index, specifier, + form, property); +} + + +status_t +BGLScreen::GetSupportedSuites(BMessage* data) +{ + return BWindowScreen::GetSupportedSuites(data); +} + + +//---- virtual reserved methods ---------- + +void BGLScreen::_ReservedGLScreen1() {} +void BGLScreen::_ReservedGLScreen2() {} +void BGLScreen::_ReservedGLScreen3() {} +void BGLScreen::_ReservedGLScreen4() {} +void BGLScreen::_ReservedGLScreen5() {} +void BGLScreen::_ReservedGLScreen6() {} +void BGLScreen::_ReservedGLScreen7() {} +void BGLScreen::_ReservedGLScreen8() {} +#endif + + +const char* color_space_name(color_space space) +{ +#define C2N(a) case a: return #a + + switch (space) { + C2N(B_RGB24); + C2N(B_RGB32); + C2N(B_RGBA32); + C2N(B_RGB32_BIG); + C2N(B_RGBA32_BIG); + C2N(B_GRAY8); + C2N(B_GRAY1); + C2N(B_RGB16); + C2N(B_RGB15); + C2N(B_RGBA15); + C2N(B_CMAP8); + default: + return "Unknown!"; + }; + +#undef C2N +}; + + +glview_direct_info::glview_direct_info() +{ + // TODO: See direct_window_data() in app_server's ServerWindow.cpp + direct_info = (direct_buffer_info*)calloc(1, DIRECT_BUFFER_INFO_AREA_SIZE); + direct_connected = false; + enable_direct_mode = false; +} + + +glview_direct_info::~glview_direct_info() +{ + free(direct_info); +} + diff --git a/mesalib/src/hgl/SConscript b/mesalib/src/hgl/SConscript new file mode 100644 index 000000000..70db1494d --- /dev/null +++ b/mesalib/src/hgl/SConscript @@ -0,0 +1,36 @@ +####################################################################### +# SConscript for Haiku OpenGL kit + +Import('*') + +env = env.Clone() + +env.Append(CPPPATH = [ + '#/src/mapi', + '#/src/mesa', + '#/src/mesa/main', + '#/include/HaikuGL', + '/boot/system/develop/headers/private', + Dir('../../../mapi'), # src/mapi build path for python-generated GL API files/headers +]) + +env.Prepend(LIBS = [ + glapi +]) + +sources = [ + 'GLView.cpp', + 'GLRenderer.cpp', + 'GLRendererRoster.cpp', + 'GLDispatcher.cpp', +] + +# libGL.so +libgl = env.SharedLibrary( + target ='GL', + source = sources, + SHLIBSUFFIX = env['SHLIBSUFFIX'], +) + +env.Alias('libgl-haiku', libgl) +Export('libgl') diff --git a/mesalib/src/mapi/glapi/gen/ARB_shader_image_load_store.xml b/mesalib/src/mapi/glapi/gen/ARB_shader_image_load_store.xml new file mode 100644 index 000000000..7ccfca41d --- /dev/null +++ b/mesalib/src/mapi/glapi/gen/ARB_shader_image_load_store.xml @@ -0,0 +1,89 @@ +<?xml version="1.0"?> +<!DOCTYPE OpenGLAPI SYSTEM "gl_API.dtd"> + +<OpenGLAPI> + +<category name="GL_ARB_shader_image_load_store" number="115"> + +<enum name="VERTEX_ATTRIB_ARRAY_BARRIER_BIT" value="0x00000001"/> +<enum name="ELEMENT_ARRAY_BARRIER_BIT" value="0x00000002"/> +<enum name="UNIFORM_BARRIER_BIT" value="0x00000004"/> +<enum name="TEXTURE_FETCH_BARRIER_BIT" value="0x00000008"/> +<enum name="SHADER_IMAGE_ACCESS_BARRIER_BIT" value="0x00000020"/> +<enum name="COMMAND_BARRIER_BIT" value="0x00000040"/> +<enum name="PIXEL_BUFFER_BARRIER_BIT" value="0x00000080"/> +<enum name="TEXTURE_UPDATE_BARRIER_BIT" value="0x00000100"/> +<enum name="BUFFER_UPDATE_BARRIER_BIT" value="0x00000200"/> +<enum name="FRAMEBUFFER_BARRIER_BIT" value="0x00000400"/> +<enum name="TRANSFORM_FEEDBACK_BARRIER_BIT" value="0x00000800"/> +<enum name="ATOMIC_COUNTER_BARRIER_BIT" value="0x00001000"/> +<enum name="ALL_BARRIER_BITS" value="0xFFFFFFFF"/> +<enum name="MAX_IMAGE_UNITS" value="0x8F38"/> +<enum name="MAX_COMBINED_IMAGE_UNITS_AND_FRAGMENT_OUTPUTS" value="0x8F39"/> +<enum name="IMAGE_BINDING_NAME" value="0x8F3A"/> +<enum name="IMAGE_BINDING_LEVEL" value="0x8F3B"/> +<enum name="IMAGE_BINDING_LAYERED" value="0x8F3C"/> +<enum name="IMAGE_BINDING_LAYER" value="0x8F3D"/> +<enum name="IMAGE_BINDING_ACCESS" value="0x8F3E"/> +<enum name="IMAGE_1D" value="0x904C"/> +<enum name="IMAGE_2D" value="0x904D"/> +<enum name="IMAGE_3D" value="0x904E"/> +<enum name="IMAGE_2D_RECT" value="0x904F"/> +<enum name="IMAGE_CUBE" value="0x9050"/> +<enum name="IMAGE_BUFFER" value="0x9051"/> +<enum name="IMAGE_1D_ARRAY" value="0x9052"/> +<enum name="IMAGE_2D_ARRAY" value="0x9053"/> +<enum name="IMAGE_CUBE_MAP_ARRAY" value="0x9054"/> +<enum name="IMAGE_2D_MULTISAMPLE" value="0x9055"/> +<enum name="IMAGE_2D_MULTISAMPLE_ARRAY" value="0x9056"/> +<enum name="INT_IMAGE_1D" value="0x9057"/> +<enum name="INT_IMAGE_2D" value="0x9058"/> +<enum name="INT_IMAGE_3D" value="0x9059"/> +<enum name="INT_IMAGE_2D_RECT" value="0x905A"/> +<enum name="INT_IMAGE_CUBE" value="0x905B"/> +<enum name="INT_IMAGE_BUFFER" value="0x905C"/> +<enum name="INT_IMAGE_1D_ARRAY" value="0x905D"/> +<enum name="INT_IMAGE_2D_ARRAY" value="0x905E"/> +<enum name="INT_IMAGE_CUBE_MAP_ARRAY" value="0x905F"/> +<enum name="INT_IMAGE_2D_MULTISAMPLE" value="0x9060"/> +<enum name="INT_IMAGE_2D_MULTISAMPLE_ARRAY" value="0x9061"/> +<enum name="UNSIGNED_INT_IMAGE_1D" value="0x9062"/> +<enum name="UNSIGNED_INT_IMAGE_2D" value="0x9063"/> +<enum name="UNSIGNED_INT_IMAGE_3D" value="0x9064"/> +<enum name="UNSIGNED_INT_IMAGE_2D_RECT" value="0x9065"/> +<enum name="UNSIGNED_INT_IMAGE_CUBE" value="0x9066"/> +<enum name="UNSIGNED_INT_IMAGE_BUFFER" value="0x9067"/> +<enum name="UNSIGNED_INT_IMAGE_1D_ARRAY" value="0x9068"/> +<enum name="UNSIGNED_INT_IMAGE_2D_ARRAY" value="0x9069"/> +<enum name="UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY" value="0x906A"/> +<enum name="UNSIGNED_INT_IMAGE_2D_MULTISAMPLE" value="0x906B"/> +<enum name="UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY" value="0x906C"/> +<enum name="MAX_IMAGE_SAMPLES" value="0x906D"/> +<enum name="IMAGE_BINDING_FORMAT" value="0x906E"/> +<enum name="IMAGE_FORMAT_COMPATIBILITY_TYPE" value="0x90C7"/> +<enum name="IMAGE_FORMAT_COMPATIBILITY_BY_SIZE" value="0x90C8"/> +<enum name="IMAGE_FORMAT_COMPATIBILITY_BY_CLASS" value="0x90C9"/> +<enum name="MAX_VERTEX_IMAGE_UNIFORMS" value="0x90CA"/> +<enum name="MAX_TESS_CONTROL_IMAGE_UNIFORMS" value="0x90CB"/> +<enum name="MAX_TESS_EVALUATION_IMAGE_UNIFORMS" value="0x90CC"/> +<enum name="MAX_GEOMETRY_IMAGE_UNIFORMS" value="0x90CD"/> +<enum name="MAX_FRAGMENT_IMAGE_UNIFORMS" value="0x90CE"/> +<enum name="MAX_COMBINED_IMAGE_UNIFORMS" value="0x90CF"/> + +<function name="BindImageTexture" offset="assign"> + <param name="unit" type="GLuint"/> + <param name="texture" type="GLuint"/> + <param name="level" type="GLint"/> + <param name="layered" type="GLboolean"/> + <param name="layer" type="GLint"/> + <param name="access" type="GLenum"/> + <param name="format" type="GLenum"/> +</function> + +<function name="MemoryBarrier" offset="assign"> + <param name="barriers" type="GLbitfield"/> +</function> + +</category> + +</OpenGLAPI> diff --git a/mesalib/src/mapi/glapi/gen/Makefile.am b/mesalib/src/mapi/glapi/gen/Makefile.am index 65bd9137c..d5c20b71e 100644 --- a/mesalib/src/mapi/glapi/gen/Makefile.am +++ b/mesalib/src/mapi/glapi/gen/Makefile.am @@ -113,6 +113,7 @@ API_XML = \ ARB_sampler_objects.xml \ ARB_seamless_cube_map.xml \ ARB_shader_atomic_counters.xml \ + ARB_shader_image_load_store.xml \ ARB_sync.xml \ ARB_texture_buffer_object.xml \ ARB_texture_buffer_range.xml \ diff --git a/mesalib/src/mapi/glapi/gen/glX_proto_send.py b/mesalib/src/mapi/glapi/gen/glX_proto_send.py index f4d519f14..8b804418b 100755 --- a/mesalib/src/mapi/glapi/gen/glX_proto_send.py +++ b/mesalib/src/mapi/glapi/gen/glX_proto_send.py @@ -971,6 +971,8 @@ struct _glapi_table * __glXNewIndirectAPI( void ) entries = _glapi_get_dispatch_table_size(); table = malloc(entries * sizeof(_glapi_proc)); + if (table == NULL) + return NULL; /* first, set all entries to point to no-op functions */ for (i = 0; i < entries; i++) { diff --git a/mesalib/src/mapi/glapi/gen/gl_API.xml b/mesalib/src/mapi/glapi/gen/gl_API.xml index c51eb5f4c..5928d1493 100755 --- a/mesalib/src/mapi/glapi/gen/gl_API.xml +++ b/mesalib/src/mapi/glapi/gen/gl_API.xml @@ -8312,6 +8312,8 @@ <xi:include href="ARB_shader_atomic_counters.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/> +<xi:include href="ARB_shader_image_load_store.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/> + <xi:include href="ARB_texture_storage.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/> <!-- ARB extension #118 --> diff --git a/mesalib/src/mapi/glapi/gen/gl_genexec.py b/mesalib/src/mapi/glapi/gen/gl_genexec.py index b557b3b99..b7ac16b06 100644 --- a/mesalib/src/mapi/glapi/gen/gl_genexec.py +++ b/mesalib/src/mapi/glapi/gen/gl_genexec.py @@ -108,6 +108,7 @@ header = """/** #include "main/varray.h" #include "main/viewport.h" #include "main/shaderapi.h" +#include "main/shaderimage.h" #include "main/uniforms.h" #include "main/syncobj.h" #include "main/formatquery.h" diff --git a/mesalib/src/mesa/Makefile.am b/mesalib/src/mesa/Makefile.am index 884383652..cb038a5eb 100644 --- a/mesalib/src/mesa/Makefile.am +++ b/mesalib/src/mesa/Makefile.am @@ -36,18 +36,18 @@ endif gldir = $(includedir)/GL gl_HEADERS = $(top_srcdir)/include/GL/*.h -.PHONY: main/git_sha1.h.tmp -main/git_sha1.h.tmp: +.PHONY: $(BUILDDIR)main/git_sha1.h.tmp +$(BUILDDIR)main/git_sha1.h.tmp: @touch main/git_sha1.h.tmp - @if test -d ../../.git; then \ + @if test -d $(top_srcdir)/.git; then \ if which git > /dev/null; then \ - git log -n 1 --oneline | \ + git --git-dir=$(top_srcdir)/.git log -n 1 --oneline | \ sed 's/^\([^ ]*\) .*/#define MESA_GIT_SHA1 "git-\1"/' \ > main/git_sha1.h.tmp ; \ fi \ fi -main/git_sha1.h: main/git_sha1.h.tmp +$(BUILDDIR)main/git_sha1.h: $(BUILDDIR)main/git_sha1.h.tmp @echo "updating main/git_sha1.h" @if ! cmp -s main/git_sha1.h.tmp main/git_sha1.h; then \ mv main/git_sha1.h.tmp main/git_sha1.h ;\ @@ -63,8 +63,8 @@ BUILDDIR = $(builddir)/ include Makefile.sources BUILT_SOURCES = \ - main/git_sha1.h \ main/get_hash.h \ + $(BUILDDIR)main/git_sha1.h \ $(BUILDDIR)program/program_parse.tab.c \ $(BUILDDIR)program/lex.yy.c CLEANFILES = \ diff --git a/mesalib/src/mesa/Makefile.sources b/mesalib/src/mesa/Makefile.sources index 39525bc5b..d14823db9 100644 --- a/mesalib/src/mesa/Makefile.sources +++ b/mesalib/src/mesa/Makefile.sources @@ -81,6 +81,7 @@ MAIN_FILES = \ $(SRCDIR)main/scissor.c \ $(SRCDIR)main/set.c \ $(SRCDIR)main/shaderapi.c \ + $(SRCDIR)main/shaderimage.c \ $(SRCDIR)main/shaderobj.c \ $(SRCDIR)main/shader_query.cpp \ $(SRCDIR)main/shared.c \ diff --git a/mesalib/src/mesa/SConscript b/mesalib/src/mesa/SConscript index bb9b304ef..77e2aaa7e 100644 --- a/mesalib/src/mesa/SConscript +++ b/mesalib/src/mesa/SConscript @@ -110,6 +110,7 @@ main_sources = [ 'main/scissor.c', 'main/set.c', 'main/shaderapi.c', + 'main/shaderimage.c', 'main/shaderobj.c', 'main/shader_query.cpp', 'main/shared.c', diff --git a/mesalib/src/mesa/drivers/common/driverfuncs.c b/mesalib/src/mesa/drivers/common/driverfuncs.c index f18568827..e8dcb2476 100644 --- a/mesalib/src/mesa/drivers/common/driverfuncs.c +++ b/mesalib/src/mesa/drivers/common/driverfuncs.c @@ -302,8 +302,7 @@ _mesa_init_driver_state(struct gl_context *ctx) ctx->Driver.LogicOpcode(ctx, ctx->Color.LogicOp); ctx->Driver.PointSize(ctx, ctx->Point.Size); ctx->Driver.PolygonStipple(ctx, (const GLubyte *) ctx->PolygonStipple); - ctx->Driver.Scissor(ctx, ctx->Scissor.X, ctx->Scissor.Y, - ctx->Scissor.Width, ctx->Scissor.Height); + ctx->Driver.Scissor(ctx); ctx->Driver.ShadeModel(ctx, ctx->Light.ShadeModel); ctx->Driver.StencilFuncSeparate(ctx, GL_FRONT, ctx->Stencil.Function[0], diff --git a/mesalib/src/mesa/drivers/common/meta.c b/mesalib/src/mesa/drivers/common/meta.c index 7b41876b9..129451471 100644 --- a/mesalib/src/mesa/drivers/common/meta.c +++ b/mesalib/src/mesa/drivers/common/meta.c @@ -2407,9 +2407,9 @@ _mesa_meta_glsl_Clear(struct gl_context *ctx, GLbitfield buffers) GL_DYNAMIC_DRAW_ARB); /* draw quad(s) */ - if (fb->NumLayers > 0) { + if (fb->MaxNumLayers > 0) { unsigned layer; - for (layer = 0; layer < fb->NumLayers; layer++) { + for (layer = 0; layer < fb->MaxNumLayers; layer++) { if (fb->_IntegerColor) _mesa_Uniform1i(clear->IntegerLayerLocation, layer); else diff --git a/mesalib/src/mesa/drivers/dri/common/utils.c b/mesalib/src/mesa/drivers/dri/common/utils.c index 9c9483209..3e35fe2d0 100644 --- a/mesalib/src/mesa/drivers/dri/common/utils.c +++ b/mesalib/src/mesa/drivers/dri/common/utils.c @@ -308,6 +308,7 @@ driCreateConfigs(gl_format format, __DRI_ATTRIB_TEXTURE_2D_BIT | __DRI_ATTRIB_TEXTURE_RECTANGLE_BIT; + modes->yInverted = GL_TRUE; modes->sRGBCapable = is_srgb; } } diff --git a/mesalib/src/mesa/drivers/dri/swrast/swrast.c b/mesalib/src/mesa/drivers/dri/swrast/swrast.c index 1848da5d9..cddab6526 100644 --- a/mesalib/src/mesa/drivers/dri/swrast/swrast.c +++ b/mesalib/src/mesa/drivers/dri/swrast/swrast.c @@ -623,15 +623,11 @@ update_state( struct gl_context *ctx, GLuint new_state ) } static void -viewport(struct gl_context *ctx, GLint x, GLint y, GLsizei w, GLsizei h) +viewport(struct gl_context *ctx) { struct gl_framebuffer *draw = ctx->WinSysDrawBuffer; struct gl_framebuffer *read = ctx->WinSysReadBuffer; - (void) x; - (void) y; - (void) w; - (void) h; swrast_check_and_update_window_size(ctx, draw); swrast_check_and_update_window_size(ctx, read); } diff --git a/mesalib/src/mesa/drivers/haiku/swrast/SConscript b/mesalib/src/mesa/drivers/haiku/swrast/SConscript index 71ce88e20..aef730098 100644 --- a/mesalib/src/mesa/drivers/haiku/swrast/SConscript +++ b/mesalib/src/mesa/drivers/haiku/swrast/SConscript @@ -6,6 +6,7 @@ env.Append(CPPPATH = [ '#/src/mapi', '#/src/mesa', '#/src/mesa/main', + '#/include/HaikuGL', '/boot/system/develop/headers/private', Dir('../../../mapi'), # src/mapi build path for python-generated GL API files/headers ]) @@ -15,6 +16,8 @@ env.Prepend(LIBS = [ mesa, ]) +env.Prepend(LIBS = [libgl]) + sources = [ 'SoftwareRast.cpp' ] diff --git a/mesalib/src/mesa/drivers/windows/gdi/wmesa.c b/mesalib/src/mesa/drivers/windows/gdi/wmesa.c index d6eb82392..c1a9c28b1 100644 --- a/mesalib/src/mesa/drivers/windows/gdi/wmesa.c +++ b/mesalib/src/mesa/drivers/windows/gdi/wmesa.c @@ -484,9 +484,7 @@ wmesa_resize_buffers(struct gl_context *ctx, struct gl_framebuffer *buffer, * we get the viewport set correctly, even if the app does not call * glViewport and relies on the defaults. */ -static void wmesa_viewport(struct gl_context *ctx, - GLint x, GLint y, - GLsizei width, GLsizei height) +static void wmesa_viewport(struct gl_context *ctx) { GLuint new_width, new_height; diff --git a/mesalib/src/mesa/main/arbprogram.c b/mesalib/src/mesa/main/arbprogram.c index 8bd3f0bd0..247b49253 100644 --- a/mesalib/src/mesa/main/arbprogram.c +++ b/mesalib/src/mesa/main/arbprogram.c @@ -247,12 +247,12 @@ get_local_param_pointer(struct gl_context *ctx, const char *func, if (target == GL_VERTEX_PROGRAM_ARB && ctx->Extensions.ARB_vertex_program) { prog = &(ctx->VertexProgram.Current->Base); - maxParams = ctx->Const.VertexProgram.MaxLocalParams; + maxParams = ctx->Const.Program[MESA_SHADER_VERTEX].MaxLocalParams; } else if (target == GL_FRAGMENT_PROGRAM_ARB && ctx->Extensions.ARB_fragment_program) { prog = &(ctx->FragmentProgram.Current->Base); - maxParams = ctx->Const.FragmentProgram.MaxLocalParams; + maxParams = ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxLocalParams; } else { _mesa_error(ctx, GL_INVALID_ENUM, @@ -282,7 +282,7 @@ get_env_param_pointer(struct gl_context *ctx, const char *func, { if (target == GL_FRAGMENT_PROGRAM_ARB && ctx->Extensions.ARB_fragment_program) { - if (index >= ctx->Const.FragmentProgram.MaxEnvParams) { + if (index >= ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxEnvParams) { _mesa_error(ctx, GL_INVALID_VALUE, "%s(index)", func); return GL_FALSE; } @@ -291,7 +291,7 @@ get_env_param_pointer(struct gl_context *ctx, const char *func, } else if (target == GL_VERTEX_PROGRAM_ARB && ctx->Extensions.ARB_vertex_program) { - if (index >= ctx->Const.VertexProgram.MaxEnvParams) { + if (index >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxEnvParams) { _mesa_error(ctx, GL_INVALID_VALUE, "%s(index)", func); return GL_FALSE; } @@ -436,7 +436,7 @@ _mesa_ProgramEnvParameters4fvEXT(GLenum target, GLuint index, GLsizei count, if (target == GL_FRAGMENT_PROGRAM_ARB && ctx->Extensions.ARB_fragment_program) { - if ((index + count) > ctx->Const.FragmentProgram.MaxEnvParams) { + if ((index + count) > ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxEnvParams) { _mesa_error(ctx, GL_INVALID_VALUE, "glProgramEnvParameters4fv(index + count)"); return; } @@ -444,7 +444,7 @@ _mesa_ProgramEnvParameters4fvEXT(GLenum target, GLuint index, GLsizei count, } else if (target == GL_VERTEX_PROGRAM_ARB && ctx->Extensions.ARB_vertex_program) { - if ((index + count) > ctx->Const.VertexProgram.MaxEnvParams) { + if ((index + count) > ctx->Const.Program[MESA_SHADER_VERTEX].MaxEnvParams) { _mesa_error(ctx, GL_INVALID_VALUE, "glProgramEnvParameters4fv(index + count)"); return; } @@ -527,28 +527,20 @@ _mesa_ProgramLocalParameters4fvEXT(GLenum target, GLuint index, GLsizei count, _mesa_error(ctx, GL_INVALID_VALUE, "glProgramLocalParameters4fv(count)"); } - if (target == GL_FRAGMENT_PROGRAM_ARB - && ctx->Extensions.ARB_fragment_program) { - if ((index + count) > ctx->Const.FragmentProgram.MaxLocalParams) { - _mesa_error(ctx, GL_INVALID_VALUE, "glProgramLocalParameters4fvEXT(index + count)"); - return; - } - dest = ctx->FragmentProgram.Current->Base.LocalParams[index]; - } - else if (target == GL_VERTEX_PROGRAM_ARB - && ctx->Extensions.ARB_vertex_program) { - if ((index + count) > ctx->Const.VertexProgram.MaxLocalParams) { - _mesa_error(ctx, GL_INVALID_VALUE, "glProgramLocalParameters4fvEXT(index + count)"); + if (get_local_param_pointer(ctx, "glProgramLocalParameters4fvEXT", + target, index, &dest)) { + GLuint maxParams = target == GL_FRAGMENT_PROGRAM_ARB ? + ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxLocalParams : + ctx->Const.Program[MESA_SHADER_VERTEX].MaxLocalParams; + + if ((index + count) > maxParams) { + _mesa_error(ctx, GL_INVALID_VALUE, + "glProgramLocalParameters4fvEXT(index + count)"); return; } - dest = ctx->VertexProgram.Current->Base.LocalParams[index]; - } - else { - _mesa_error(ctx, GL_INVALID_ENUM, "glProgramLocalParameters4fvEXT(target)"); - return; - } - memcpy(dest, params, count * 4 * sizeof(GLfloat)); + memcpy(dest, params, count * 4 * sizeof(GLfloat)); + } } @@ -610,12 +602,12 @@ _mesa_GetProgramivARB(GLenum target, GLenum pname, GLint *params) if (target == GL_VERTEX_PROGRAM_ARB && ctx->Extensions.ARB_vertex_program) { prog = &(ctx->VertexProgram.Current->Base); - limits = &ctx->Const.VertexProgram; + limits = &ctx->Const.Program[MESA_SHADER_VERTEX]; } else if (target == GL_FRAGMENT_PROGRAM_ARB && ctx->Extensions.ARB_fragment_program) { prog = &(ctx->FragmentProgram.Current->Base); - limits = &ctx->Const.FragmentProgram; + limits = &ctx->Const.Program[MESA_SHADER_FRAGMENT]; } else { _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramivARB(target)"); diff --git a/mesalib/src/mesa/main/clear.c b/mesalib/src/mesa/main/clear.c index f0b525fa0..077c5fca3 100644 --- a/mesalib/src/mesa/main/clear.c +++ b/mesalib/src/mesa/main/clear.c @@ -179,7 +179,11 @@ _mesa_Clear( GLbitfield mask ) if (mask & GL_COLOR_BUFFER_BIT) { GLuint i; for (i = 0; i < ctx->DrawBuffer->_NumColorDrawBuffers; i++) { - bufferMask |= (1 << ctx->DrawBuffer->_ColorDrawBufferIndexes[i]); + GLint buf = ctx->DrawBuffer->_ColorDrawBufferIndexes[i]; + + if (buf >= 0) { + bufferMask |= 1 << buf; + } } } @@ -274,7 +278,7 @@ make_color_buffer_mask(struct gl_context *ctx, GLint drawbuffer) break; default: { - GLuint buf = ctx->DrawBuffer->_ColorDrawBufferIndexes[drawbuffer]; + GLint buf = ctx->DrawBuffer->_ColorDrawBufferIndexes[drawbuffer]; if (buf >= 0 && att[buf].Renderbuffer) { mask |= 1 << buf; diff --git a/mesalib/src/mesa/main/condrender.c b/mesalib/src/mesa/main/condrender.c index 2632f7a1a..0ad1e5c2a 100644 --- a/mesalib/src/mesa/main/condrender.c +++ b/mesalib/src/mesa/main/condrender.c @@ -40,17 +40,38 @@ void GLAPIENTRY _mesa_BeginConditionalRender(GLuint queryId, GLenum mode) { - struct gl_query_object *q; + struct gl_query_object *q = NULL; GET_CURRENT_CONTEXT(ctx); - if (!ctx->Extensions.NV_conditional_render || ctx->Query.CondRenderQuery || - queryId == 0) { + /* Section 2.14 (Conditional Rendering) of the OpenGL 3.0 spec says: + * + * "If BeginConditionalRender is called while conditional rendering is + * in progress, or if EndConditionalRender is called while conditional + * rendering is not in progress, the error INVALID_OPERATION is + * generated." + */ + if (!ctx->Extensions.NV_conditional_render || ctx->Query.CondRenderQuery) { _mesa_error(ctx, GL_INVALID_OPERATION, "glBeginConditionalRender()"); return; } ASSERT(ctx->Query.CondRenderMode == GL_NONE); + /* Section 2.14 (Conditional Rendering) of the OpenGL 3.0 spec says: + * + * "The error INVALID_VALUE is generated if <id> is not the name of an + * existing query object query." + */ + if (queryId != 0) + q = _mesa_lookup_query_object(ctx, queryId); + + if (!q) { + _mesa_error(ctx, GL_INVALID_VALUE, + "glBeginConditionalRender(bad queryId=%u)", queryId); + return; + } + ASSERT(q->Id == queryId); + switch (mode) { case GL_QUERY_WAIT: case GL_QUERY_NO_WAIT: @@ -64,14 +85,12 @@ _mesa_BeginConditionalRender(GLuint queryId, GLenum mode) return; } - q = _mesa_lookup_query_object(ctx, queryId); - if (!q) { - _mesa_error(ctx, GL_INVALID_VALUE, - "glBeginConditionalRender(bad queryId=%u)", queryId); - return; - } - ASSERT(q->Id == queryId); - + /* Section 2.14 (Conditional Rendering) of the OpenGL 3.0 spec says: + * + * "The error INVALID_OPERATION is generated if <id> is the name of a + * query object with a target other than SAMPLES_PASSED, or <id> is the + * name of a query currently in progress." + */ if ((q->Target != GL_SAMPLES_PASSED && q->Target != GL_ANY_SAMPLES_PASSED && q->Target != GL_ANY_SAMPLES_PASSED_CONSERVATIVE) || q->Active) { diff --git a/mesalib/src/mesa/main/config.h b/mesalib/src/mesa/main/config.h index ebf99c24b..1e1cfb6c5 100644 --- a/mesalib/src/mesa/main/config.h +++ b/mesalib/src/mesa/main/config.h @@ -179,6 +179,9 @@ #define MAX_COMBINED_ATOMIC_BUFFERS (MAX_UNIFORM_BUFFERS * 6) /* Size of an atomic counter in bytes according to ARB_shader_atomic_counters */ #define ATOMIC_COUNTER_SIZE 4 +#define MAX_IMAGE_UNIFORMS 16 +/* 6 is for vertex, hull, domain, geometry, fragment, and compute shader. */ +#define MAX_IMAGE_UNITS (MAX_IMAGE_UNIFORMS * 6) /*@}*/ /** diff --git a/mesalib/src/mesa/main/context.c b/mesalib/src/mesa/main/context.c index 4db27da9a..4f7bdbdbc 100644 --- a/mesalib/src/mesa/main/context.c +++ b/mesalib/src/mesa/main/context.c @@ -461,7 +461,7 @@ _mesa_init_current(struct gl_context *ctx) * Important: drivers should override these with actual limits. */ static void -init_program_limits(struct gl_context *ctx, GLenum type, +init_program_limits(struct gl_context *ctx, gl_shader_stage stage, struct gl_program_constants *prog) { prog->MaxInstructions = MAX_PROGRAM_INSTRUCTIONS; @@ -473,8 +473,8 @@ init_program_limits(struct gl_context *ctx, GLenum type, prog->MaxLocalParams = MAX_PROGRAM_LOCAL_PARAMS; prog->MaxAddressOffset = MAX_PROGRAM_LOCAL_PARAMS; - switch (type) { - case GL_VERTEX_PROGRAM_ARB: + switch (stage) { + case MESA_SHADER_VERTEX: prog->MaxParameters = MAX_VERTEX_PROGRAM_PARAMS; prog->MaxAttribs = MAX_VERTEX_GENERIC_ATTRIBS; prog->MaxAddressRegs = MAX_VERTEX_PROGRAM_ADDRESS_REGS; @@ -482,7 +482,7 @@ init_program_limits(struct gl_context *ctx, GLenum type, prog->MaxInputComponents = 0; /* value not used */ prog->MaxOutputComponents = 16 * 4; /* old limit not to break tnl and swrast */ break; - case GL_FRAGMENT_PROGRAM_ARB: + case MESA_SHADER_FRAGMENT: prog->MaxParameters = MAX_NV_FRAGMENT_PROGRAM_PARAMS; prog->MaxAttribs = MAX_NV_FRAGMENT_PROGRAM_INPUTS; prog->MaxAddressRegs = MAX_FRAGMENT_PROGRAM_ADDRESS_REGS; @@ -490,7 +490,7 @@ init_program_limits(struct gl_context *ctx, GLenum type, prog->MaxInputComponents = 16 * 4; /* old limit not to break tnl and swrast */ prog->MaxOutputComponents = 0; /* value not used */ break; - case MESA_GEOMETRY_PROGRAM: + case MESA_SHADER_GEOMETRY: prog->MaxParameters = MAX_VERTEX_PROGRAM_PARAMS; prog->MaxAttribs = MAX_VERTEX_GENERIC_ATTRIBS; prog->MaxAddressRegs = MAX_VERTEX_PROGRAM_ADDRESS_REGS; @@ -499,7 +499,7 @@ init_program_limits(struct gl_context *ctx, GLenum type, prog->MaxOutputComponents = 16 * 4; /* old limit not to break tnl and swrast */ break; default: - assert(0 && "Bad program type in init_program_limits()"); + assert(0 && "Bad shader stage in init_program_limits()"); } /* Set the native limits to zero. This implies that there is no native @@ -551,6 +551,7 @@ init_program_limits(struct gl_context *ctx, GLenum type, static void _mesa_init_constants(struct gl_context *ctx) { + int i; assert(ctx); /* Constants, may be overriden (usually only reduced) by device drivers */ @@ -561,9 +562,9 @@ _mesa_init_constants(struct gl_context *ctx) ctx->Const.MaxTextureRectSize = MAX_TEXTURE_RECT_SIZE; ctx->Const.MaxArrayTextureLayers = MAX_ARRAY_TEXTURE_LAYERS; ctx->Const.MaxTextureCoordUnits = MAX_TEXTURE_COORD_UNITS; - ctx->Const.FragmentProgram.MaxTextureImageUnits = MAX_TEXTURE_IMAGE_UNITS; + ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits = MAX_TEXTURE_IMAGE_UNITS; ctx->Const.MaxTextureUnits = MIN2(ctx->Const.MaxTextureCoordUnits, - ctx->Const.FragmentProgram.MaxTextureImageUnits); + ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits); ctx->Const.MaxTextureMaxAnisotropy = MAX_TEXTURE_MAX_ANISOTROPY; ctx->Const.MaxTextureLodBias = MAX_TEXTURE_LOD_BIAS; ctx->Const.MaxTextureBufferSize = 65536; @@ -593,9 +594,8 @@ _mesa_init_constants(struct gl_context *ctx) ctx->Const.MaxUniformBlockSize = 16384; ctx->Const.UniformBufferOffsetAlignment = 1; - init_program_limits(ctx, GL_VERTEX_PROGRAM_ARB, &ctx->Const.VertexProgram); - init_program_limits(ctx, GL_FRAGMENT_PROGRAM_ARB, &ctx->Const.FragmentProgram); - init_program_limits(ctx, MESA_GEOMETRY_PROGRAM, &ctx->Const.GeometryProgram); + for (i = 0; i < MESA_SHADER_STAGES; i++) + init_program_limits(ctx, i, &ctx->Const.Program[i]); ctx->Const.MaxProgramMatrices = MAX_PROGRAM_MATRICES; ctx->Const.MaxProgramMatrixStackDepth = MAX_PROGRAM_MATRIX_STACK_DEPTH; @@ -609,10 +609,10 @@ _mesa_init_constants(struct gl_context *ctx) ctx->Const.MaxColorAttachments = MAX_COLOR_ATTACHMENTS; ctx->Const.MaxRenderbufferSize = MAX_RENDERBUFFER_SIZE; - ctx->Const.VertexProgram.MaxTextureImageUnits = MAX_TEXTURE_IMAGE_UNITS; + ctx->Const.Program[MESA_SHADER_VERTEX].MaxTextureImageUnits = MAX_TEXTURE_IMAGE_UNITS; ctx->Const.MaxCombinedTextureImageUnits = MAX_COMBINED_TEXTURE_IMAGE_UNITS; ctx->Const.MaxVarying = 16; /* old limit not to break tnl and swrast */ - ctx->Const.GeometryProgram.MaxTextureImageUnits = MAX_TEXTURE_IMAGE_UNITS; + ctx->Const.Program[MESA_SHADER_GEOMETRY].MaxTextureImageUnits = MAX_TEXTURE_IMAGE_UNITS; ctx->Const.MaxGeometryOutputVertices = MAX_GEOMETRY_OUTPUT_VERTICES; ctx->Const.MaxGeometryTotalOutputComponents = MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS; @@ -699,24 +699,24 @@ check_context_limits(struct gl_context *ctx) (8 * sizeof(ctx->FragmentProgram._Current->Base.InputsRead))); /* shader-related checks */ - assert(ctx->Const.FragmentProgram.MaxLocalParams <= MAX_PROGRAM_LOCAL_PARAMS); - assert(ctx->Const.VertexProgram.MaxLocalParams <= MAX_PROGRAM_LOCAL_PARAMS); + assert(ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxLocalParams <= MAX_PROGRAM_LOCAL_PARAMS); + assert(ctx->Const.Program[MESA_SHADER_VERTEX].MaxLocalParams <= MAX_PROGRAM_LOCAL_PARAMS); /* Texture unit checks */ - assert(ctx->Const.FragmentProgram.MaxTextureImageUnits > 0); - assert(ctx->Const.FragmentProgram.MaxTextureImageUnits <= MAX_TEXTURE_IMAGE_UNITS); + assert(ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits > 0); + assert(ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits <= MAX_TEXTURE_IMAGE_UNITS); assert(ctx->Const.MaxTextureCoordUnits > 0); assert(ctx->Const.MaxTextureCoordUnits <= MAX_TEXTURE_COORD_UNITS); assert(ctx->Const.MaxTextureUnits > 0); assert(ctx->Const.MaxTextureUnits <= MAX_TEXTURE_IMAGE_UNITS); assert(ctx->Const.MaxTextureUnits <= MAX_TEXTURE_COORD_UNITS); - assert(ctx->Const.MaxTextureUnits == MIN2(ctx->Const.FragmentProgram.MaxTextureImageUnits, + assert(ctx->Const.MaxTextureUnits == MIN2(ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits, ctx->Const.MaxTextureCoordUnits)); assert(ctx->Const.MaxCombinedTextureImageUnits > 0); assert(ctx->Const.MaxCombinedTextureImageUnits <= MAX_COMBINED_TEXTURE_IMAGE_UNITS); assert(ctx->Const.MaxTextureCoordUnits <= MAX_COMBINED_TEXTURE_IMAGE_UNITS); /* number of coord units cannot be greater than number of image units */ - assert(ctx->Const.MaxTextureCoordUnits <= ctx->Const.FragmentProgram.MaxTextureImageUnits); + assert(ctx->Const.MaxTextureCoordUnits <= ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits); /* Texture size checks */ @@ -1851,14 +1851,14 @@ _mesa_valid_to_render(struct gl_context *ctx, const char *where) #ifdef DEBUG if (ctx->Shader.Flags & GLSL_LOG) { - struct gl_shader_program *shProg[MESA_SHADER_TYPES]; - gl_shader_type i; + struct gl_shader_program *shProg[MESA_SHADER_STAGES]; + gl_shader_stage i; shProg[MESA_SHADER_VERTEX] = ctx->Shader.CurrentVertexProgram; shProg[MESA_SHADER_GEOMETRY] = ctx->Shader.CurrentGeometryProgram; shProg[MESA_SHADER_FRAGMENT] = ctx->Shader.CurrentFragmentProgram; - for (i = 0; i < MESA_SHADER_TYPES; i++) { + for (i = 0; i < MESA_SHADER_STAGES; i++) { if (shProg[i] == NULL || shProg[i]->_Used || shProg[i]->_LinkedShaders[i] == NULL) continue; @@ -1875,7 +1875,7 @@ _mesa_valid_to_render(struct gl_context *ctx, const char *where) _mesa_append_uniforms_to_file(shProg[i]->_LinkedShaders[i]); } - for (i = 0; i < MESA_SHADER_TYPES; i++) { + for (i = 0; i < MESA_SHADER_STAGES; i++) { if (shProg[i] != NULL) shProg[i]->_Used = GL_TRUE; } diff --git a/mesalib/src/mesa/main/dd.h b/mesalib/src/mesa/main/dd.h index 6e73691ea..6c084afa3 100644 --- a/mesalib/src/mesa/main/dd.h +++ b/mesalib/src/mesa/main/dd.h @@ -39,6 +39,7 @@ struct gl_buffer_object; struct gl_context; struct gl_display_list; struct gl_framebuffer; +struct gl_image_unit; struct gl_pixelstore_attrib; struct gl_program; struct gl_renderbuffer; @@ -484,7 +485,7 @@ struct dd_function_table { /** Enable or disable writing into the depth buffer */ void (*DepthMask)(struct gl_context *ctx, GLboolean flag); /** Specify mapping of depth values from NDC to window coordinates */ - void (*DepthRange)(struct gl_context *ctx, GLclampd nearval, GLclampd farval); + void (*DepthRange)(struct gl_context *ctx); /** Specify the current buffer for writing */ void (*DrawBuffer)( struct gl_context *ctx, GLenum buffer ); /** Specify the buffers for writing for fragment programs*/ @@ -524,7 +525,7 @@ struct dd_function_table { /** Set rasterization mode */ void (*RenderMode)(struct gl_context *ctx, GLenum mode ); /** Define the scissor box */ - void (*Scissor)(struct gl_context *ctx, GLint x, GLint y, GLsizei w, GLsizei h); + void (*Scissor)(struct gl_context *ctx); /** Select flat or smooth shading */ void (*ShadeModel)(struct gl_context *ctx, GLenum mode); /** OpenGL 2.0 two-sided StencilFunc */ @@ -546,7 +547,7 @@ struct dd_function_table { struct gl_texture_object *texObj, GLenum pname, const GLfloat *params); /** Set the viewport */ - void (*Viewport)(struct gl_context *ctx, GLint x, GLint y, GLsizei w, GLsizei h); + void (*Viewport)(struct gl_context *ctx); /*@}*/ @@ -910,6 +911,19 @@ struct dd_function_table { * non-zero status should be returned for the duration of the reset. */ GLenum (*GetGraphicsResetStatus)(struct gl_context *ctx); + + /** + * \name GL_ARB_shader_image_load_store interface. + */ + /** @{ */ + void (*BindImageTexture)(struct gl_context *ctx, + struct gl_image_unit *unit, + struct gl_texture_object *texObj, + GLint level, GLboolean layered, GLint layer, + GLenum access, GLenum format); + + void (*MemoryBarrier)(struct gl_context *ctx, GLbitfield barriers); + /** @} */ }; diff --git a/mesalib/src/mesa/main/extensions.c b/mesalib/src/mesa/main/extensions.c index f0e1858e4..2e0ccc3b6 100644 --- a/mesalib/src/mesa/main/extensions.c +++ b/mesalib/src/mesa/main/extensions.c @@ -126,6 +126,7 @@ static const struct extension extension_table[] = { { "GL_ARB_seamless_cube_map", o(ARB_seamless_cube_map), GL, 2009 }, { "GL_ARB_shader_atomic_counters", o(ARB_shader_atomic_counters), GL, 2011 }, { "GL_ARB_shader_bit_encoding", o(ARB_shader_bit_encoding), GL, 2010 }, + { "GL_ARB_shader_image_load_store", o(ARB_shader_image_load_store), GL, 2011 }, { "GL_ARB_shader_objects", o(dummy_true), GL, 2002 }, { "GL_ARB_shader_stencil_export", o(ARB_shader_stencil_export), GL, 2009 }, { "GL_ARB_shader_texture_lod", o(ARB_shader_texture_lod), GL, 2009 }, @@ -304,6 +305,7 @@ static const struct extension extension_table[] = { { "GL_AMD_performance_monitor", o(AMD_performance_monitor), GL, 2007 }, { "GL_AMD_seamless_cubemap_per_texture", o(AMD_seamless_cubemap_per_texture), GL, 2009 }, { "GL_AMD_shader_stencil_export", o(ARB_shader_stencil_export), GL, 2009 }, + { "GL_AMD_shader_trinary_minmax", o(dummy_true), GL, 2012 }, { "GL_AMD_vertex_shader_layer", o(AMD_vertex_shader_layer), GLC, 2012 }, { "GL_APPLE_object_purgeable", o(APPLE_object_purgeable), GL, 2006 }, { "GL_APPLE_packed_pixels", o(dummy_true), GLL, 2002 }, @@ -396,10 +398,6 @@ _mesa_enable_sw_extensions(struct gl_context *ctx) ctx->Extensions.ARB_fragment_program_shadow = GL_TRUE; ctx->Extensions.ARB_fragment_shader = GL_TRUE; ctx->Extensions.ARB_framebuffer_object = GL_TRUE; - /* XXX re-enable when GLSL compiler again supports geometry shaders */ -#if 0 - ctx->Extensions.ARB_geometry_shader4 = GL_TRUE; -#endif ctx->Extensions.ARB_half_float_pixel = GL_TRUE; ctx->Extensions.ARB_half_float_vertex = GL_TRUE; ctx->Extensions.ARB_map_buffer_range = GL_TRUE; diff --git a/mesalib/src/mesa/main/fbobject.c b/mesalib/src/mesa/main/fbobject.c index 2892784f8..dc7184ad4 100644 --- a/mesalib/src/mesa/main/fbobject.c +++ b/mesalib/src/mesa/main/fbobject.c @@ -877,8 +877,11 @@ _mesa_test_framebuffer_completeness(struct gl_context *ctx, GLint fixedSampleLocations = -1; GLint i; GLuint j; - bool layer_count_valid = false; - GLuint layer_count = 0, att_layer_count; + /* Covers max_layer_count, is_layered, and layer_tex_target */ + bool layer_info_valid = false; + GLuint max_layer_count = 0, att_layer_count; + bool is_layered; + GLenum layer_tex_target = 0; assert(_mesa_is_user_fbo(fb)); @@ -1062,22 +1065,25 @@ _mesa_test_framebuffer_completeness(struct gl_context *ctx, } else { att_layer_count = 0; } - if (!layer_count_valid) { - layer_count = att_layer_count; - layer_count_valid = true; - } else if (layer_count != att_layer_count) { - if (layer_count == 0 || att_layer_count == 0) { - fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS; - fbo_incomplete(ctx, "framebuffer attachment layer mode is inconsistent", i); - } else { - fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_ARB; - fbo_incomplete(ctx, "framebuffer attachment layer count is inconsistent", i); - } + if (!layer_info_valid) { + is_layered = att->Layered; + max_layer_count = att_layer_count; + layer_tex_target = att_tex_target; + layer_info_valid = true; + } else if (max_layer_count > 0 && layer_tex_target != att_tex_target) { + fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS; + fbo_incomplete(ctx, "layered framebuffer has mismatched targets", i); + return; + } else if (is_layered != att->Layered) { + fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS; + fbo_incomplete(ctx, "framebuffer attachment layer mode is inconsistent", i); return; + } else if (att_layer_count > max_layer_count) { + max_layer_count = att_layer_count; } } - fb->NumLayers = layer_count; + fb->MaxNumLayers = max_layer_count; if (_mesa_is_desktop_gl(ctx) && !ctx->Extensions.ARB_ES2_compatibility) { /* Check that all DrawBuffers are present */ @@ -1504,6 +1510,22 @@ _mesa_base_fbo_format(struct gl_context *ctx, GLenum internalFormat) return ctx->API == API_OPENGL_COMPAT && ctx->Extensions.EXT_texture_snorm && ctx->Extensions.ARB_framebuffer_object ? GL_ALPHA : 0; + case GL_LUMINANCE_SNORM: + case GL_LUMINANCE8_SNORM: + case GL_LUMINANCE16_SNORM: + return _mesa_is_desktop_gl(ctx) && ctx->Extensions.EXT_texture_snorm + ? GL_LUMINANCE : 0; + case GL_LUMINANCE_ALPHA_SNORM: + case GL_LUMINANCE8_ALPHA8_SNORM: + case GL_LUMINANCE16_ALPHA16_SNORM: + return _mesa_is_desktop_gl(ctx) && ctx->Extensions.EXT_texture_snorm + ? GL_LUMINANCE_ALPHA : 0; + case GL_INTENSITY_SNORM: + case GL_INTENSITY8_SNORM: + case GL_INTENSITY16_SNORM: + return _mesa_is_desktop_gl(ctx) && ctx->Extensions.EXT_texture_snorm + ? GL_INTENSITY : 0; + case GL_R16F: case GL_R32F: return ((_mesa_is_desktop_gl(ctx) && diff --git a/mesalib/src/mesa/main/ff_fragment_shader.cpp b/mesalib/src/mesa/main/ff_fragment_shader.cpp index ba6258d89..00ca02558 100644 --- a/mesalib/src/mesa/main/ff_fragment_shader.cpp +++ b/mesalib/src/mesa/main/ff_fragment_shader.cpp @@ -1296,7 +1296,7 @@ create_new_program(struct gl_context *ctx, struct state_key *key) p.mem_ctx = ralloc_context(NULL); p.shader = ctx->Driver.NewShader(ctx, 0, GL_FRAGMENT_SHADER); p.shader->ir = new(p.shader) exec_list; - state = new(p.shader) _mesa_glsl_parse_state(ctx, GL_FRAGMENT_SHADER, + state = new(p.shader) _mesa_glsl_parse_state(ctx, MESA_SHADER_FRAGMENT, p.shader); p.shader->symbols = state->symbols; p.top_instructions = p.shader->ir; diff --git a/mesalib/src/mesa/main/ffvertex_prog.c b/mesalib/src/mesa/main/ffvertex_prog.c index 074fbf9a3..808ea9cbd 100644 --- a/mesalib/src/mesa/main/ffvertex_prog.c +++ b/mesalib/src/mesa/main/ffvertex_prog.c @@ -1677,7 +1677,7 @@ _mesa_get_fixed_func_vertex_program(struct gl_context *ctx) create_new_program( &key, prog, ctx->ShaderCompilerOptions[MESA_SHADER_VERTEX].PreferDP4, - ctx->Const.VertexProgram.MaxTemps ); + ctx->Const.Program[MESA_SHADER_VERTEX].MaxTemps ); #if 0 if (ctx->Driver.ProgramStringNotify) diff --git a/mesalib/src/mesa/main/format_pack.c b/mesalib/src/mesa/main/format_pack.c index 826fc10a6..41f5f99c1 100644 --- a/mesalib/src/mesa/main/format_pack.c +++ b/mesalib/src/mesa/main/format_pack.c @@ -1824,6 +1824,56 @@ pack_float_XBGR32323232_FLOAT(const GLfloat src[4], void *dst) d[3] = 1.0; } +/* MESA_FORMAT_ABGR2101010 */ + +static void +pack_ubyte_ABGR2101010(const GLubyte src[4], void *dst) +{ + GLuint *d = ((GLuint *) dst); + GLushort r = UBYTE_TO_USHORT(src[RCOMP]); + GLushort g = UBYTE_TO_USHORT(src[GCOMP]); + GLushort b = UBYTE_TO_USHORT(src[BCOMP]); + GLushort a = UBYTE_TO_USHORT(src[ACOMP]); + *d = PACK_COLOR_2101010_US(a, b, g, r); +} + +static void +pack_float_ABGR2101010(const GLfloat src[4], void *dst) +{ + GLuint *d = ((GLuint *) dst); + GLushort r, g, b, a; + UNCLAMPED_FLOAT_TO_USHORT(r, src[RCOMP]); + UNCLAMPED_FLOAT_TO_USHORT(g, src[GCOMP]); + UNCLAMPED_FLOAT_TO_USHORT(b, src[BCOMP]); + UNCLAMPED_FLOAT_TO_USHORT(a, src[ACOMP]); + *d = PACK_COLOR_2101010_US(a, b, g, r); +} + +/* + * MESA_FORMAT_SIGNED_RG88 + */ + +static void +pack_float_SIGNED_RG88(const GLfloat src[4], void *dst) +{ + GLushort *d = (GLushort *) dst; + GLbyte r = FLOAT_TO_BYTE(CLAMP(src[RCOMP], -1.0f, 1.0f)); + GLbyte g = FLOAT_TO_BYTE(CLAMP(src[GCOMP], -1.0f, 1.0f)); + *d = (r << 8) | (g & 0xff); +} + +/* + * MESA_FORMAT_SIGNED_RG1616 + */ + +static void +pack_float_SIGNED_RG1616(const GLfloat src[4], void *dst) +{ + GLuint *d = (GLuint *) dst; + GLshort r = FLOAT_TO_SHORT(CLAMP(src[RCOMP], -1.0f, 1.0f)); + GLshort g = FLOAT_TO_SHORT(CLAMP(src[GCOMP], -1.0f, 1.0f)); + *d = (r << 16) | (g & 0xffff); +} /** * Return a function that can pack a GLubyte rgba[4] color. @@ -1978,6 +2028,8 @@ _mesa_get_pack_ubyte_rgba_function(gl_format format) table[MESA_FORMAT_XBGR32323232_UINT] = NULL; table[MESA_FORMAT_XBGR32323232_SINT] = NULL; + table[MESA_FORMAT_ABGR2101010] = pack_ubyte_ABGR2101010; + initialized = GL_TRUE; } @@ -2136,6 +2188,11 @@ _mesa_get_pack_float_rgba_function(gl_format format) table[MESA_FORMAT_XBGR32323232_UINT] = NULL; table[MESA_FORMAT_XBGR32323232_SINT] = NULL; + table[MESA_FORMAT_ABGR2101010] = pack_float_ABGR2101010; + + table[MESA_FORMAT_SIGNED_RG88] = pack_float_SIGNED_RG88; + table[MESA_FORMAT_SIGNED_RG1616] = pack_float_SIGNED_RG1616; + initialized = GL_TRUE; } diff --git a/mesalib/src/mesa/main/format_unpack.c b/mesalib/src/mesa/main/format_unpack.c index 0a8b8b183..28a50f31e 100644 --- a/mesalib/src/mesa/main/format_unpack.c +++ b/mesalib/src/mesa/main/format_unpack.c @@ -2268,6 +2268,44 @@ unpack_XBGR32323232_SINT(const void *src, GLfloat dst[][4], GLuint n) } } +static void +unpack_ABGR2101010(const void *src, GLfloat dst[][4], GLuint n) +{ + const GLuint *s = ((const GLuint *) src); + GLuint i; + for (i = 0; i < n; i++) { + dst[i][RCOMP] = ((s[i] >> 0) & 0x3ff) * (1.0F / 1023.0F); + dst[i][GCOMP] = ((s[i] >> 10) & 0x3ff) * (1.0F / 1023.0F); + dst[i][BCOMP] = ((s[i] >> 20) & 0x3ff) * (1.0F / 1023.0F); + dst[i][ACOMP] = ((s[i] >> 30) & 0x03) * (1.0F / 3.0F); + } +} + +static void +unpack_SIGNED_RG88(const void *src, GLfloat dst[][4], GLuint n) +{ + const GLushort *s = ((const GLushort *) src); + GLuint i; + for (i = 0; i < n; i++) { + dst[i][RCOMP] = BYTE_TO_FLOAT_TEX( (GLbyte) (s[i] >> 8) ); + dst[i][GCOMP] = BYTE_TO_FLOAT_TEX( (GLbyte) (s[i] & 0xff) ); + dst[i][BCOMP] = 0.0F; + dst[i][ACOMP] = 1.0F; + } +} + +static void +unpack_SIGNED_RG1616(const void *src, GLfloat dst[][4], GLuint n) +{ + const GLuint *s = ((const GLuint *) src); + GLuint i; + for (i = 0; i < n; i++) { + dst[i][RCOMP] = SHORT_TO_FLOAT_TEX( (GLshort) (s[i] >> 16) ); + dst[i][GCOMP] = SHORT_TO_FLOAT_TEX( (GLshort) (s[i] & 0xffff) ); + dst[i][BCOMP] = 0.0F; + dst[i][ACOMP] = 1.0F; + } +} /** * Return the unpacker function for the given format. @@ -2481,6 +2519,11 @@ get_unpack_rgba_function(gl_format format) table[MESA_FORMAT_XBGR32323232_UINT] = unpack_XBGR32323232_UINT; table[MESA_FORMAT_XBGR32323232_SINT] = unpack_XBGR32323232_SINT; + table[MESA_FORMAT_ABGR2101010] = unpack_ABGR2101010; + + table[MESA_FORMAT_SIGNED_RG88] = unpack_SIGNED_RG88; + table[MESA_FORMAT_SIGNED_RG1616] = unpack_SIGNED_RG1616; + initialized = GL_TRUE; } @@ -3582,6 +3625,20 @@ unpack_int_rgba_XBGR32323232_UINT(const GLuint *src, GLuint dst[][4], GLuint n) } } +static void +unpack_int_rgba_ABGR2101010(const GLuint *src, GLuint dst[][4], GLuint n) +{ + unsigned int i; + + for (i = 0; i < n; i++) { + GLuint tmp = src[i]; + dst[i][0] = (tmp >> 0) & 0x3ff; + dst[i][1] = (tmp >> 10) & 0x3ff; + dst[i][2] = (tmp >> 20) & 0x3ff; + dst[i][3] = (tmp >> 30) & 0x3; + } +} + void _mesa_unpack_uint_rgba_row(gl_format format, GLuint n, const void *src, GLuint dst[][4]) @@ -3782,6 +3839,10 @@ _mesa_unpack_uint_rgba_row(gl_format format, GLuint n, unpack_int_rgba_XBGR32323232_UINT(src, dst, n); break; + case MESA_FORMAT_ABGR2101010: + unpack_int_rgba_ABGR2101010(src, dst, n); + break; + default: _mesa_problem(NULL, "%s: bad format %s", __FUNCTION__, _mesa_get_format_name(format)); diff --git a/mesalib/src/mesa/main/formats.c b/mesalib/src/mesa/main/formats.c index 07d2a7240..1246c4d92 100644 --- a/mesalib/src/mesa/main/formats.c +++ b/mesalib/src/mesa/main/formats.c @@ -1763,6 +1763,33 @@ static struct gl_format_info format_info[MESA_FORMAT_COUNT] = 0, 0, 0, 0, 0, 1, 1, 16 }, + { + MESA_FORMAT_ABGR2101010, + "MESA_FORMAT_ABGR2101010", + GL_RGBA, + GL_UNSIGNED_NORMALIZED, + 10, 10, 10, 2, + 0, 0, 0, 0, 0, + 1, 1, 4 + }, + { + MESA_FORMAT_SIGNED_RG88, + "MESA_FORMAT_SIGNED_RG88", + GL_RG, + GL_SIGNED_NORMALIZED, + 8, 8, 0, 0, + 0, 0, 0, 0, 0, + 1, 1, 2 + }, + { + MESA_FORMAT_SIGNED_RG1616, + "MESA_FORMAT_SIGNED_RG1616", + GL_RG, + GL_SIGNED_NORMALIZED, + 16, 16, 0, 0, + 0, 0, 0, 0, 0, + 1, 1, 4 + }, }; @@ -1967,6 +1994,26 @@ _mesa_is_format_unsigned(gl_format format) /** + * Does the given format store signed values? + */ +GLboolean +_mesa_is_format_signed(gl_format format) +{ + if (format == MESA_FORMAT_R11_G11_B10_FLOAT || + format == MESA_FORMAT_RGB9_E5_FLOAT) { + /* these packed float formats only store unsigned values */ + return GL_FALSE; + } + else { + const struct gl_format_info *info = _mesa_get_format_info(format); + return (info->DataType == GL_SIGNED_NORMALIZED || + info->DataType == GL_INT || + info->DataType == GL_FLOAT); + } +} + + +/** * Return color encoding for given format. * \return GL_LINEAR or GL_SRGB */ @@ -2821,6 +2868,21 @@ _mesa_format_to_type_and_comps(gl_format format, *comps = 4; return; + case MESA_FORMAT_ABGR2101010: + *datatype = GL_UNSIGNED_INT_2_10_10_10_REV; + *comps = 4; + return; + + case MESA_FORMAT_SIGNED_RG88: + *datatype = GL_BYTE; + *comps = 2; + return; + + case MESA_FORMAT_SIGNED_RG1616: + *datatype = GL_SHORT; + *comps = 2; + return; + case MESA_FORMAT_COUNT: assert(0); return; @@ -3362,6 +3424,18 @@ _mesa_format_matches_format_and_type(gl_format gl_format, case MESA_FORMAT_XBGR32323232_UINT: case MESA_FORMAT_XBGR32323232_SINT: return GL_FALSE; + + case MESA_FORMAT_ABGR2101010: + return format == GL_RGBA && type == GL_UNSIGNED_INT_2_10_10_10_REV && + !swapBytes; + + case MESA_FORMAT_SIGNED_RG88: + return format == GL_RG && type == GL_BYTE && !littleEndian && + !swapBytes; + + case MESA_FORMAT_SIGNED_RG1616: + return format == GL_RG && type == GL_SHORT && !littleEndian && + !swapBytes; } return GL_FALSE; diff --git a/mesalib/src/mesa/main/formats.h b/mesalib/src/mesa/main/formats.h index 64b4b9a01..a1f0d226a 100644 --- a/mesalib/src/mesa/main/formats.h +++ b/mesalib/src/mesa/main/formats.h @@ -304,6 +304,11 @@ typedef enum MESA_FORMAT_XBGR32323232_UINT, /* ... */ MESA_FORMAT_XBGR32323232_SINT, /* ... */ + MESA_FORMAT_ABGR2101010, + + MESA_FORMAT_SIGNED_RG88, + MESA_FORMAT_SIGNED_RG1616, + MESA_FORMAT_COUNT } gl_format; @@ -341,6 +346,9 @@ _mesa_is_format_integer_color(gl_format format); extern GLboolean _mesa_is_format_unsigned(gl_format format); +extern GLboolean +_mesa_is_format_signed(gl_format format); + extern GLenum _mesa_get_format_color_encoding(gl_format format); diff --git a/mesalib/src/mesa/main/get.c b/mesalib/src/mesa/main/get.c index 691380898..b13f9a3db 100644 --- a/mesalib/src/mesa/main/get.c +++ b/mesalib/src/mesa/main/get.c @@ -145,6 +145,7 @@ enum value_extra { EXTRA_GLSL_130, EXTRA_EXT_UBO_GS4, EXTRA_EXT_ATOMICS_GS4, + EXTRA_EXT_SHADER_IMAGE_GS4, }; #define NO_EXTRA NULL @@ -327,6 +328,12 @@ static const int extra_EXT_framebuffer_sRGB_and_new_buffers[] = { EXTRA_END }; +static const int extra_EXT_packed_float[] = { + EXT(EXT_packed_float), + EXTRA_NEW_BUFFERS, + EXTRA_END +}; + static const int extra_EXT_texture_array_es3[] = { EXT(EXT_texture_array), EXTRA_API_ES3, @@ -338,6 +345,11 @@ static const int extra_ARB_shader_atomic_counters_and_geometry_shader[] = { EXTRA_END }; +static const int extra_ARB_shader_image_load_store_and_geometry_shader[] = { + EXTRA_EXT_SHADER_IMAGE_GS4, + EXTRA_END +}; + EXTRA_EXT(ARB_texture_cube_map); EXTRA_EXT(EXT_texture_array); EXTRA_EXT(NV_fog_distance); @@ -376,6 +388,7 @@ EXTRA_EXT(ARB_texture_multisample); EXTRA_EXT(ARB_texture_gather); EXTRA_EXT(ARB_shader_atomic_counters); EXTRA_EXT(ARB_draw_indirect); +EXTRA_EXT(ARB_shader_image_load_store); static const int extra_ARB_color_buffer_float_or_glcore[] = { @@ -757,6 +770,45 @@ find_custom_value(struct gl_context *ctx, const struct value_desc *d, union valu ctx->Texture.Unit[unit].CurrentTex[d->offset]->Name; break; + /* GL_EXT_packed_float */ + case GL_RGBA_SIGNED_COMPONENTS_EXT: + { + /* Note: we only check the 0th color attachment. */ + const struct gl_renderbuffer *rb = + ctx->DrawBuffer->_ColorDrawBuffers[0]; + if (rb && _mesa_is_format_signed(rb->Format)) { + /* Issue 17 of GL_EXT_packed_float: If a component (such as + * alpha) has zero bits, the component should not be considered + * signed and so the bit for the respective component should be + * zeroed. + */ + GLint r_bits = + _mesa_get_format_bits(rb->Format, GL_RED_BITS); + GLint g_bits = + _mesa_get_format_bits(rb->Format, GL_GREEN_BITS); + GLint b_bits = + _mesa_get_format_bits(rb->Format, GL_BLUE_BITS); + GLint a_bits = + _mesa_get_format_bits(rb->Format, GL_ALPHA_BITS); + GLint l_bits = + _mesa_get_format_bits(rb->Format, GL_TEXTURE_LUMINANCE_SIZE); + GLint i_bits = + _mesa_get_format_bits(rb->Format, GL_TEXTURE_INTENSITY_SIZE); + + v->value_int_4[0] = r_bits + l_bits + i_bits > 0; + v->value_int_4[1] = g_bits + l_bits + i_bits > 0; + v->value_int_4[2] = b_bits + l_bits + i_bits > 0; + v->value_int_4[3] = a_bits + i_bits > 0; + } + else { + v->value_int_4[0] = + v->value_int_4[1] = + v->value_int_4[2] = + v->value_int_4[3] = 0; + } + } + break; + /* GL_ARB_vertex_buffer_object */ case GL_VERTEX_ARRAY_BUFFER_BINDING_ARB: case GL_NORMAL_ARRAY_BUFFER_BINDING_ARB: @@ -849,11 +901,11 @@ find_custom_value(struct gl_context *ctx, const struct value_desc *d, union valu v->value_float = ctx->Color.AlphaRefUnclamped; break; case GL_MAX_VERTEX_UNIFORM_VECTORS: - v->value_int = ctx->Const.VertexProgram.MaxUniformComponents / 4; + v->value_int = ctx->Const.Program[MESA_SHADER_VERTEX].MaxUniformComponents / 4; break; case GL_MAX_FRAGMENT_UNIFORM_VECTORS: - v->value_int = ctx->Const.FragmentProgram.MaxUniformComponents / 4; + v->value_int = ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxUniformComponents / 4; break; /* GL_ARB_texture_buffer_object */ @@ -1026,6 +1078,11 @@ check_extra(struct gl_context *ctx, const char *func, const struct value_desc *d api_found = (ctx->Extensions.ARB_shader_atomic_counters && _mesa_has_geometry_shaders(ctx)); break; + case EXTRA_EXT_SHADER_IMAGE_GS4: + api_check = GL_TRUE; + api_found = (ctx->Extensions.ARB_shader_image_load_store && + _mesa_has_geometry_shaders(ctx)); + break; case EXTRA_END: break; default: /* *e is a offset into the extension struct */ @@ -1747,7 +1804,7 @@ find_value_indexed(const char *func, GLenum pname, GLuint index, union value *v) case GL_VERTEX_BINDING_DIVISOR: if (!_mesa_is_desktop_gl(ctx) || !ctx->Extensions.ARB_instanced_arrays) goto invalid_enum; - if (index >= ctx->Const.VertexProgram.MaxAttribs) + if (index >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) goto invalid_value; v->value_int = ctx->Array.ArrayObj->VertexBinding[VERT_ATTRIB_GENERIC(index)].InstanceDivisor; return TYPE_INT; @@ -1755,7 +1812,7 @@ find_value_indexed(const char *func, GLenum pname, GLuint index, union value *v) case GL_VERTEX_BINDING_OFFSET: if (!_mesa_is_desktop_gl(ctx)) goto invalid_enum; - if (index >= ctx->Const.VertexProgram.MaxAttribs) + if (index >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) goto invalid_value; v->value_int = ctx->Array.ArrayObj->VertexBinding[VERT_ATTRIB_GENERIC(index)].Offset; return TYPE_INT; @@ -1763,9 +1820,67 @@ find_value_indexed(const char *func, GLenum pname, GLuint index, union value *v) case GL_VERTEX_BINDING_STRIDE: if (!_mesa_is_desktop_gl(ctx)) goto invalid_enum; - if (index >= ctx->Const.VertexProgram.MaxAttribs) + if (index >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) goto invalid_value; v->value_int = ctx->Array.ArrayObj->VertexBinding[VERT_ATTRIB_GENERIC(index)].Stride; + + /* ARB_shader_image_load_store */ + case GL_IMAGE_BINDING_NAME: { + struct gl_texture_object *t; + + if (!ctx->Extensions.ARB_shader_image_load_store) + goto invalid_enum; + if (index >= ctx->Const.MaxImageUnits) + goto invalid_value; + + t = ctx->ImageUnits[index].TexObj; + v->value_int = (t ? t->Name : 0); + return TYPE_INT; + } + + case GL_IMAGE_BINDING_LEVEL: + if (!ctx->Extensions.ARB_shader_image_load_store) + goto invalid_enum; + if (index >= ctx->Const.MaxImageUnits) + goto invalid_value; + + v->value_int = ctx->ImageUnits[index].Level; + return TYPE_INT; + + case GL_IMAGE_BINDING_LAYERED: + if (!ctx->Extensions.ARB_shader_image_load_store) + goto invalid_enum; + if (index >= ctx->Const.MaxImageUnits) + goto invalid_value; + + v->value_int = ctx->ImageUnits[index].Layered; + return TYPE_INT; + + case GL_IMAGE_BINDING_LAYER: + if (!ctx->Extensions.ARB_shader_image_load_store) + goto invalid_enum; + if (index >= ctx->Const.MaxImageUnits) + goto invalid_value; + + v->value_int = ctx->ImageUnits[index].Layer; + return TYPE_INT; + + case GL_IMAGE_BINDING_ACCESS: + if (!ctx->Extensions.ARB_shader_image_load_store) + goto invalid_enum; + if (index >= ctx->Const.MaxImageUnits) + goto invalid_value; + + v->value_int = ctx->ImageUnits[index].Access; + return TYPE_INT; + + case GL_IMAGE_BINDING_FORMAT: + if (!ctx->Extensions.ARB_shader_image_load_store) + goto invalid_enum; + if (index >= ctx->Const.MaxImageUnits) + goto invalid_value; + + v->value_int = ctx->ImageUnits[index].Format; return TYPE_INT; } diff --git a/mesalib/src/mesa/main/get_hash_params.py b/mesalib/src/mesa/main/get_hash_params.py index 653bf6256..6195d630d 100644 --- a/mesalib/src/mesa/main/get_hash_params.py +++ b/mesalib/src/mesa/main/get_hash_params.py @@ -271,8 +271,8 @@ descriptor=[ # GL_ARB_fragment_program # == GL_MAX_TEXTURE_IMAGE_UNITS_NV - [ "MAX_TEXTURE_IMAGE_UNITS_ARB", "CONTEXT_INT(Const.FragmentProgram.MaxTextureImageUnits), extra_ARB_fragment_program" ], - [ "MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB", "CONTEXT_INT(Const.VertexProgram.MaxTextureImageUnits), extra_ARB_vertex_shader" ], + [ "MAX_TEXTURE_IMAGE_UNITS_ARB", "CONTEXT_INT(Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits), extra_ARB_fragment_program" ], + [ "MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB", "CONTEXT_INT(Const.Program[MESA_SHADER_VERTEX].MaxTextureImageUnits), extra_ARB_vertex_shader" ], [ "MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB", "CONTEXT_INT(Const.MaxCombinedTextureImageUnits), extra_ARB_vertex_shader" ], # GL_ARB_shader_objects @@ -288,7 +288,7 @@ descriptor=[ [ "STENCIL_BACK_FAIL", "CONTEXT_ENUM(Stencil.FailFunc[1]), NO_EXTRA" ], [ "STENCIL_BACK_PASS_DEPTH_FAIL", "CONTEXT_ENUM(Stencil.ZFailFunc[1]), NO_EXTRA" ], [ "STENCIL_BACK_PASS_DEPTH_PASS", "CONTEXT_ENUM(Stencil.ZPassFunc[1]), NO_EXTRA" ], - [ "MAX_VERTEX_ATTRIBS_ARB", "CONTEXT_INT(Const.VertexProgram.MaxAttribs), extra_ARB_vertex_program_api_es2" ], + [ "MAX_VERTEX_ATTRIBS_ARB", "CONTEXT_INT(Const.Program[MESA_SHADER_VERTEX].MaxAttribs), extra_ARB_vertex_program_api_es2" ], # OES_texture_3D [ "TEXTURE_BINDING_3D", "LOC_CUSTOM, TYPE_INT, TEXTURE_3D_INDEX, NO_EXTRA" ], @@ -328,14 +328,14 @@ descriptor=[ [ "MINOR_VERSION", "LOC_CUSTOM, TYPE_INT, 0, extra_gl30_es3" ], # GL 3.2 / GLES3 - [ "MAX_VERTEX_OUTPUT_COMPONENTS", "CONTEXT_INT(Const.VertexProgram.MaxOutputComponents), extra_gl32_es3" ], - [ "MAX_FRAGMENT_INPUT_COMPONENTS", "CONTEXT_INT(Const.FragmentProgram.MaxInputComponents), extra_gl32_es3" ], + [ "MAX_VERTEX_OUTPUT_COMPONENTS", "CONTEXT_INT(Const.Program[MESA_SHADER_VERTEX].MaxOutputComponents), extra_gl32_es3" ], + [ "MAX_FRAGMENT_INPUT_COMPONENTS", "CONTEXT_INT(Const.Program[MESA_SHADER_FRAGMENT].MaxInputComponents), extra_gl32_es3" ], # GL_ARB_ES3_compatibility [ "MAX_ELEMENT_INDEX", "CONTEXT_INT64(Const.MaxElementIndex), extra_ARB_ES3_compatibility_api_es3"], # GL_ARB_fragment_shader - [ "MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB", "CONTEXT_INT(Const.FragmentProgram.MaxUniformComponents), extra_ARB_fragment_shader" ], + [ "MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB", "CONTEXT_INT(Const.Program[MESA_SHADER_FRAGMENT].MaxUniformComponents), extra_ARB_fragment_shader" ], # GL_ARB_framebuffer_object [ "MAX_SAMPLES", "CONTEXT_INT(Const.MaxSamples), extra_ARB_framebuffer_object_EXT_framebuffer_multisample" ], @@ -349,18 +349,18 @@ descriptor=[ [ "TRANSFORM_FEEDBACK_BINDING", "LOC_CUSTOM, TYPE_INT, 0, extra_ARB_transform_feedback2_api_es3" ], # GL_ARB_uniform_buffer_object - [ "MAX_VERTEX_UNIFORM_BLOCKS", "CONTEXT_INT(Const.VertexProgram.MaxUniformBlocks), extra_ARB_uniform_buffer_object" ], - [ "MAX_FRAGMENT_UNIFORM_BLOCKS", "CONTEXT_INT(Const.FragmentProgram.MaxUniformBlocks), extra_ARB_uniform_buffer_object" ], + [ "MAX_VERTEX_UNIFORM_BLOCKS", "CONTEXT_INT(Const.Program[MESA_SHADER_VERTEX].MaxUniformBlocks), extra_ARB_uniform_buffer_object" ], + [ "MAX_FRAGMENT_UNIFORM_BLOCKS", "CONTEXT_INT(Const.Program[MESA_SHADER_FRAGMENT].MaxUniformBlocks), extra_ARB_uniform_buffer_object" ], [ "MAX_COMBINED_UNIFORM_BLOCKS", "CONTEXT_INT(Const.MaxCombinedUniformBlocks), extra_ARB_uniform_buffer_object" ], [ "MAX_UNIFORM_BLOCK_SIZE", "CONTEXT_INT(Const.MaxUniformBlockSize), extra_ARB_uniform_buffer_object" ], [ "MAX_UNIFORM_BUFFER_BINDINGS", "CONTEXT_INT(Const.MaxUniformBufferBindings), extra_ARB_uniform_buffer_object" ], - [ "MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS", "CONTEXT_INT(Const.VertexProgram.MaxCombinedUniformComponents), extra_ARB_uniform_buffer_object" ], - [ "MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS", "CONTEXT_INT(Const.FragmentProgram.MaxCombinedUniformComponents), extra_ARB_uniform_buffer_object" ], + [ "MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS", "CONTEXT_INT(Const.Program[MESA_SHADER_VERTEX].MaxCombinedUniformComponents), extra_ARB_uniform_buffer_object" ], + [ "MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS", "CONTEXT_INT(Const.Program[MESA_SHADER_FRAGMENT].MaxCombinedUniformComponents), extra_ARB_uniform_buffer_object" ], [ "UNIFORM_BUFFER_OFFSET_ALIGNMENT", "CONTEXT_INT(Const.UniformBufferOffsetAlignment), extra_ARB_uniform_buffer_object" ], [ "UNIFORM_BUFFER_BINDING", "LOC_CUSTOM, TYPE_INT, 0, extra_ARB_uniform_buffer_object" ], # GL_ARB_vertex_shader - [ "MAX_VERTEX_UNIFORM_COMPONENTS_ARB", "CONTEXT_INT(Const.VertexProgram.MaxUniformComponents), extra_ARB_vertex_shader" ], + [ "MAX_VERTEX_UNIFORM_COMPONENTS_ARB", "CONTEXT_INT(Const.Program[MESA_SHADER_VERTEX].MaxUniformComponents), extra_ARB_vertex_shader" ], [ "MAX_VARYING_FLOATS_ARB", "LOC_CUSTOM, TYPE_INT, 0, extra_ARB_vertex_shader" ], # GL_EXT_framebuffer_blit @@ -611,6 +611,9 @@ descriptor=[ # GL_ARB_fragment_program [ "FRAGMENT_PROGRAM_ARB", "CONTEXT_BOOL(FragmentProgram.Enabled), extra_ARB_fragment_program" ], +# GL_EXT_packed_float + [ "RGBA_SIGNED_COMPONENTS_EXT", "LOC_CUSTOM, TYPE_INT_4, 0, extra_EXT_packed_float" ], + # GL_EXT_depth_bounds_test [ "DEPTH_BOUNDS_TEST_EXT", "CONTEXT_BOOL(Depth.BoundsTest), extra_EXT_depth_bounds_test" ], [ "DEPTH_BOUNDS_EXT", "CONTEXT_FLOAT2(Depth.BoundsMin), extra_EXT_depth_bounds_test" ], @@ -643,12 +646,12 @@ descriptor=[ [ "MAX_VERTEX_STREAMS", "CONTEXT_INT(Const.MaxVertexStreams), extra_ARB_transform_feedback3" ], # GL_ARB_geometry_shader4 - [ "MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_ARB", "CONTEXT_INT(Const.GeometryProgram.MaxTextureImageUnits), extra_gl32_ARB_geometry_shader4" ], + [ "MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_ARB", "CONTEXT_INT(Const.Program[MESA_SHADER_GEOMETRY].MaxTextureImageUnits), extra_gl32_ARB_geometry_shader4" ], [ "MAX_GEOMETRY_OUTPUT_VERTICES_ARB", "CONTEXT_INT(Const.MaxGeometryOutputVertices), extra_gl32_ARB_geometry_shader4" ], [ "MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_ARB", "CONTEXT_INT(Const.MaxGeometryTotalOutputComponents), extra_gl32_ARB_geometry_shader4" ], - [ "MAX_GEOMETRY_UNIFORM_COMPONENTS_ARB", "CONTEXT_INT(Const.GeometryProgram.MaxUniformComponents), extra_gl32_ARB_geometry_shader4" ], - [ "MAX_GEOMETRY_VARYING_COMPONENTS_ARB", "CONTEXT_INT(Const.GeometryProgram.MaxOutputComponents), extra_ARB_geometry_shader4" ], - [ "MAX_VERTEX_VARYING_COMPONENTS_ARB", "CONTEXT_INT(Const.VertexProgram.MaxOutputComponents), extra_ARB_geometry_shader4" ], + [ "MAX_GEOMETRY_UNIFORM_COMPONENTS_ARB", "CONTEXT_INT(Const.Program[MESA_SHADER_GEOMETRY].MaxUniformComponents), extra_gl32_ARB_geometry_shader4" ], + [ "MAX_GEOMETRY_VARYING_COMPONENTS_ARB", "CONTEXT_INT(Const.Program[MESA_SHADER_GEOMETRY].MaxOutputComponents), extra_ARB_geometry_shader4" ], + [ "MAX_VERTEX_VARYING_COMPONENTS_ARB", "CONTEXT_INT(Const.Program[MESA_SHADER_VERTEX].MaxOutputComponents), extra_ARB_geometry_shader4" ], # GL_ARB_color_buffer_float [ "RGBA_FLOAT_MODE_ARB", "BUFFER_FIELD(Visual.floatMode, TYPE_BOOLEAN), extra_core_ARB_color_buffer_float_and_new_buffers" ], @@ -688,8 +691,8 @@ descriptor=[ # GL 3.2 [ "CONTEXT_PROFILE_MASK", "CONTEXT_INT(Const.ProfileMask), extra_version_32" ], - [ "MAX_GEOMETRY_INPUT_COMPONENTS", "CONTEXT_INT(Const.GeometryProgram.MaxInputComponents), extra_version_32" ], - [ "MAX_GEOMETRY_OUTPUT_COMPONENTS", "CONTEXT_INT(Const.GeometryProgram.MaxOutputComponents), extra_version_32" ], + [ "MAX_GEOMETRY_INPUT_COMPONENTS", "CONTEXT_INT(Const.Program[MESA_SHADER_GEOMETRY].MaxInputComponents), extra_version_32" ], + [ "MAX_GEOMETRY_OUTPUT_COMPONENTS", "CONTEXT_INT(Const.Program[MESA_SHADER_GEOMETRY].MaxOutputComponents), extra_version_32" ], # GL_ARB_robustness [ "RESET_NOTIFICATION_STRATEGY_ARB", "CONTEXT_ENUM(Const.ResetStrategy), NO_EXTRA" ], @@ -706,8 +709,8 @@ descriptor=[ [ "MAX_DUAL_SOURCE_DRAW_BUFFERS", "CONTEXT_INT(Const.MaxDualSourceDrawBuffers), extra_ARB_blend_func_extended" ], # GL_ARB_uniform_buffer_object - [ "MAX_GEOMETRY_UNIFORM_BLOCKS", "CONTEXT_INT(Const.GeometryProgram.MaxUniformBlocks), extra_ARB_uniform_buffer_object_and_geometry_shader" ], - [ "MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS", "CONTEXT_INT(Const.GeometryProgram.MaxCombinedUniformComponents), extra_ARB_uniform_buffer_object_and_geometry_shader" ], + [ "MAX_GEOMETRY_UNIFORM_BLOCKS", "CONTEXT_INT(Const.Program[MESA_SHADER_GEOMETRY].MaxUniformBlocks), extra_ARB_uniform_buffer_object_and_geometry_shader" ], + [ "MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS", "CONTEXT_INT(Const.Program[MESA_SHADER_GEOMETRY].MaxCombinedUniformComponents), extra_ARB_uniform_buffer_object_and_geometry_shader" ], # GL_ARB_timer_query [ "TIMESTAMP", "LOC_CUSTOM, TYPE_INT64, 0, extra_ARB_timer_query" ], @@ -727,18 +730,27 @@ descriptor=[ [ "ATOMIC_COUNTER_BUFFER_BINDING", "LOC_CUSTOM, TYPE_INT, 0, extra_ARB_shader_atomic_counters" ], [ "MAX_ATOMIC_COUNTER_BUFFER_BINDINGS", "CONTEXT_INT(Const.MaxAtomicBufferBindings), extra_ARB_shader_atomic_counters" ], [ "MAX_ATOMIC_COUNTER_BUFFER_SIZE", "CONTEXT_INT(Const.MaxAtomicBufferSize), extra_ARB_shader_atomic_counters" ], - [ "MAX_VERTEX_ATOMIC_COUNTER_BUFFERS", "CONTEXT_INT(Const.VertexProgram.MaxAtomicBuffers), extra_ARB_shader_atomic_counters" ], - [ "MAX_VERTEX_ATOMIC_COUNTERS", "CONTEXT_INT(Const.VertexProgram.MaxAtomicCounters), extra_ARB_shader_atomic_counters" ], - [ "MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS", "CONTEXT_INT(Const.FragmentProgram.MaxAtomicBuffers), extra_ARB_shader_atomic_counters" ], - [ "MAX_FRAGMENT_ATOMIC_COUNTERS", "CONTEXT_INT(Const.FragmentProgram.MaxAtomicCounters), extra_ARB_shader_atomic_counters" ], - [ "MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS", "CONTEXT_INT(Const.GeometryProgram.MaxAtomicBuffers), extra_ARB_shader_atomic_counters_and_geometry_shader" ], - [ "MAX_GEOMETRY_ATOMIC_COUNTERS", "CONTEXT_INT(Const.GeometryProgram.MaxAtomicCounters), extra_ARB_shader_atomic_counters_and_geometry_shader" ], + [ "MAX_VERTEX_ATOMIC_COUNTER_BUFFERS", "CONTEXT_INT(Const.Program[MESA_SHADER_VERTEX].MaxAtomicBuffers), extra_ARB_shader_atomic_counters" ], + [ "MAX_VERTEX_ATOMIC_COUNTERS", "CONTEXT_INT(Const.Program[MESA_SHADER_VERTEX].MaxAtomicCounters), extra_ARB_shader_atomic_counters" ], + [ "MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS", "CONTEXT_INT(Const.Program[MESA_SHADER_FRAGMENT].MaxAtomicBuffers), extra_ARB_shader_atomic_counters" ], + [ "MAX_FRAGMENT_ATOMIC_COUNTERS", "CONTEXT_INT(Const.Program[MESA_SHADER_FRAGMENT].MaxAtomicCounters), extra_ARB_shader_atomic_counters" ], + [ "MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS", "CONTEXT_INT(Const.Program[MESA_SHADER_GEOMETRY].MaxAtomicBuffers), extra_ARB_shader_atomic_counters_and_geometry_shader" ], + [ "MAX_GEOMETRY_ATOMIC_COUNTERS", "CONTEXT_INT(Const.Program[MESA_SHADER_GEOMETRY].MaxAtomicCounters), extra_ARB_shader_atomic_counters_and_geometry_shader" ], [ "MAX_COMBINED_ATOMIC_COUNTER_BUFFERS", "CONTEXT_INT(Const.MaxCombinedAtomicBuffers), extra_ARB_shader_atomic_counters" ], [ "MAX_COMBINED_ATOMIC_COUNTERS", "CONTEXT_INT(Const.MaxCombinedAtomicCounters), extra_ARB_shader_atomic_counters" ], # GL_ARB_vertex_attrib_binding [ "MAX_VERTEX_ATTRIB_RELATIVE_OFFSET", "CONTEXT_ENUM(Const.MaxVertexAttribRelativeOffset), NO_EXTRA" ], [ "MAX_VERTEX_ATTRIB_BINDINGS", "CONTEXT_ENUM(Const.MaxVertexAttribBindings), NO_EXTRA" ], + +# GL_ARB_shader_image_load_store + [ "MAX_IMAGE_UNITS", "CONTEXT_INT(Const.MaxImageUnits), extra_ARB_shader_image_load_store"], + [ "MAX_COMBINED_IMAGE_UNITS_AND_FRAGMENT_OUTPUTS", "CONTEXT_INT(Const.MaxCombinedImageUnitsAndFragmentOutputs), extra_ARB_shader_image_load_store"], + [ "MAX_IMAGE_SAMPLES", "CONTEXT_INT(Const.MaxImageSamples), extra_ARB_shader_image_load_store"], + [ "MAX_VERTEX_IMAGE_UNIFORMS", "CONTEXT_INT(Const.Program[MESA_SHADER_VERTEX].MaxImageUniforms), extra_ARB_shader_image_load_store"], + [ "MAX_GEOMETRY_IMAGE_UNIFORMS", "CONTEXT_INT(Const.Program[MESA_SHADER_GEOMETRY].MaxImageUniforms), extra_ARB_shader_image_load_store_and_geometry_shader"], + [ "MAX_FRAGMENT_IMAGE_UNIFORMS", "CONTEXT_INT(Const.Program[MESA_SHADER_FRAGMENT].MaxImageUniforms), extra_ARB_shader_image_load_store"], + [ "MAX_COMBINED_IMAGE_UNIFORMS", "CONTEXT_INT(Const.MaxCombinedImageUniforms), extra_ARB_shader_image_load_store"], ]}, # Enums restricted to OpenGL Core profile diff --git a/mesalib/src/mesa/main/mtypes.h b/mesalib/src/mesa/main/mtypes.h index f93bb5641..33df682cf 100644 --- a/mesalib/src/mesa/main/mtypes.h +++ b/mesalib/src/mesa/main/mtypes.h @@ -393,6 +393,23 @@ typedef enum /** + * Shader stages. Note that these will become 5 with tessellation. + * + * The order must match how shaders are ordered in the pipeline. + * The GLSL linker assumes that if i<j, then the j-th shader is + * executed later than the i-th shader. + */ +typedef enum +{ + MESA_SHADER_VERTEX = 0, + MESA_SHADER_GEOMETRY = 1, + MESA_SHADER_FRAGMENT = 2, +} gl_shader_stage; + +#define MESA_SHADER_STAGES (MESA_SHADER_FRAGMENT + 1) + + +/** * Framebuffer configuration (aka visual / pixelformat) * Note: some of these fields should be boolean, but it appears that * code in drivers/dri/common/util.c requires int-sized fields. @@ -1213,6 +1230,9 @@ struct gl_texture_object /** GL_OES_EGL_image_external */ GLint RequiredTextureImageUnits; + + /** GL_ARB_shader_image_load_store */ + GLenum ImageFormatCompatibilityType; }; @@ -2302,6 +2322,7 @@ struct gl_shader * Must be the first field. */ GLenum Type; + gl_shader_stage Stage; GLuint Name; /**< AKA the handle */ GLchar *Label; /**< GL_KHR_debug */ GLint RefCount; /**< Reference count */ @@ -2384,24 +2405,33 @@ struct gl_shader */ GLenum OutputType; } Geom; -}; + /** + * Map from image uniform index to image unit (set by glUniform1i()) + * + * An image uniform index is associated with each image uniform by + * the linker. The image index associated with each uniform is + * stored in the \c gl_uniform_storage::image field. + */ + GLubyte ImageUnits[MAX_IMAGE_UNIFORMS]; -/** - * Shader stages. Note that these will become 5 with tessellation. - * - * The order must match how shaders are ordered in the pipeline. - * The GLSL linker assumes that if i<j, then the j-th shader is - * executed later than the i-th shader. - */ -typedef enum -{ - MESA_SHADER_VERTEX = 0, - MESA_SHADER_GEOMETRY = 1, - MESA_SHADER_FRAGMENT = 2, -} gl_shader_type; + /** + * Access qualifier specified in the shader for each image uniform + * index. Either \c GL_READ_ONLY, \c GL_WRITE_ONLY or \c + * GL_READ_WRITE. + * + * It may be different, though only more strict than the value of + * \c gl_image_unit::Access for the corresponding image unit. + */ + GLenum ImageAccess[MAX_IMAGE_UNIFORMS]; -#define MESA_SHADER_TYPES (MESA_SHADER_FRAGMENT + 1) + /** + * Number of image uniforms defined in the shader. It specifies + * the number of valid elements in the \c ImageUnits and \c + * ImageAccess arrays above. + */ + GLuint NumImages; +}; struct gl_uniform_buffer_variable @@ -2482,7 +2512,7 @@ struct gl_active_atomic_buffer GLuint MinimumSize; /** Shader stages making use of it. */ - GLboolean StageReferences[MESA_SHADER_TYPES]; + GLboolean StageReferences[MESA_SHADER_STAGES]; }; /** @@ -2620,7 +2650,7 @@ struct gl_shader_program * This is used to maintain the Binding values of the stage's UniformBlocks[] * and to answer the GL_UNIFORM_BLOCK_REFERENCED_BY_*_SHADER queries. */ - int *UniformBlockStageIndex[MESA_SHADER_TYPES]; + int *UniformBlockStageIndex[MESA_SHADER_STAGES]; /** * Map of active uniform names to locations @@ -2650,7 +2680,7 @@ struct gl_shader_program * \c MESA_SHADER_* defines. Entries for non-existent stages will be * \c NULL. */ - struct gl_shader *_LinkedShaders[MESA_SHADER_TYPES]; + struct gl_shader *_LinkedShaders[MESA_SHADER_STAGES]; }; @@ -3007,12 +3037,11 @@ struct gl_framebuffer struct gl_renderbuffer *_ColorReadBuffer; /** - * The number of layers in the framebuffer, or 0 if the framebuffer is not - * layered. For cube maps, this value is 6. For cube map arrays, this - * value is the "depth" value passed to TexImage3D (always a multiple of - * 6). + * The maximum number of layers in the framebuffer, or 0 if the framebuffer + * is not layered. For cube maps and cube map arrays, each cube face + * counts as a layer. */ - GLuint NumLayers; + GLuint MaxNumLayers; /** Delete this framebuffer */ void (*Delete)(struct gl_framebuffer *fb); @@ -3089,9 +3118,13 @@ struct gl_program_constants GLuint MaxUniformBlocks; GLuint MaxCombinedUniformComponents; GLuint MaxTextureImageUnits; + /* GL_ARB_shader_atomic_counters */ GLuint MaxAtomicBuffers; GLuint MaxAtomicCounters; + + /* GL_ARB_shader_image_load_store */ + GLuint MaxImageUniforms; }; @@ -3134,9 +3167,7 @@ struct gl_constants GLuint MaxViewportWidth, MaxViewportHeight; - struct gl_program_constants VertexProgram; /**< GL_ARB_vertex_program */ - struct gl_program_constants FragmentProgram; /**< GL_ARB_fragment_program */ - struct gl_program_constants GeometryProgram; /**< GL_ARB_geometry_shader4 */ + struct gl_program_constants Program[MESA_SHADER_STAGES]; GLuint MaxProgramMatrices; GLuint MaxProgramMatrixStackDepth; @@ -3314,6 +3345,12 @@ struct gl_constants /** GL_ARB_vertex_attrib_binding */ GLint MaxVertexAttribRelativeOffset; GLint MaxVertexAttribBindings; + + /* GL_ARB_shader_image_load_store */ + GLuint MaxImageUnits; + GLuint MaxCombinedImageUnitsAndFragmentOutputs; + GLuint MaxImageSamples; + GLuint MaxCombinedImageUniforms; }; @@ -3361,6 +3398,7 @@ struct gl_extensions GLboolean ARB_seamless_cube_map; GLboolean ARB_shader_atomic_counters; GLboolean ARB_shader_bit_encoding; + GLboolean ARB_shader_image_load_store; GLboolean ARB_shader_stencil_export; GLboolean ARB_shader_texture_lod; GLboolean ARB_shading_language_packing; @@ -3435,6 +3473,7 @@ struct gl_extensions /* vendor extensions */ GLboolean AMD_performance_monitor; GLboolean AMD_seamless_cubemap_per_texture; + GLboolean AMD_shader_trinary_minmax; GLboolean AMD_vertex_shader_layer; GLboolean APPLE_object_purgeable; GLboolean ATI_envmap_bumpmap; @@ -3738,6 +3777,11 @@ struct gl_driver_flags * gl_context::AtomicBufferBindings */ GLbitfield NewAtomicBuffer; + + /** + * gl_context::ImageUnits + */ + GLbitfield NewImageUnits; }; struct gl_uniform_buffer_binding @@ -3755,6 +3799,60 @@ struct gl_uniform_buffer_binding }; /** + * ARB_shader_image_load_store image unit. + */ +struct gl_image_unit +{ + /** + * Texture object bound to this unit. + */ + struct gl_texture_object *TexObj; + + /** + * Level of the texture object bound to this unit. + */ + GLuint Level; + + /** + * \c GL_TRUE if the whole level is bound as an array of layers, \c + * GL_FALSE if only some specific layer of the texture is bound. + * \sa Layer + */ + GLboolean Layered; + + /** + * Layer of the texture object bound to this unit, or zero if the + * whole level is bound. + */ + GLuint Layer; + + /** + * Access allowed to this texture image. Either \c GL_READ_ONLY, + * \c GL_WRITE_ONLY or \c GL_READ_WRITE. + */ + GLenum Access; + + /** + * GL internal format that determines the interpretation of the + * image memory when shader image operations are performed through + * this unit. + */ + GLenum Format; + + /** + * Mesa format corresponding to \c Format. + */ + gl_format _ActualFormat; + + /** + * GL_TRUE if the state of this image unit is valid and access from + * the shader is allowed. Otherwise loads from this unit should + * return zero and stores should have no effect. + */ + GLboolean _Valid; +}; + +/** * Binding point for an atomic counter buffer object. */ struct gl_atomic_buffer_binding @@ -3906,7 +4004,7 @@ struct gl_context struct gl_ati_fragment_shader_state ATIFragmentShader; struct gl_shader_state Shader; /**< GLSL shader object state */ - struct gl_shader_compiler_options ShaderCompilerOptions[MESA_SHADER_TYPES]; + struct gl_shader_compiler_options ShaderCompilerOptions[MESA_SHADER_STAGES]; struct gl_query_state Query; /**< occlusion, timer queries */ @@ -3946,6 +4044,11 @@ struct gl_context struct gl_atomic_buffer_binding AtomicBufferBindings[MAX_COMBINED_ATOMIC_BUFFERS]; + /** + * Array of image units for ARB_shader_image_load_store. + */ + struct gl_image_unit ImageUnits[MAX_IMAGE_UNITS]; + /*@}*/ struct gl_meta_state *Meta; /**< for "meta" operations */ diff --git a/mesalib/src/mesa/main/scissor.c b/mesalib/src/mesa/main/scissor.c index 0eddaa6c1..ac86bd591 100644 --- a/mesalib/src/mesa/main/scissor.c +++ b/mesalib/src/mesa/main/scissor.c @@ -79,7 +79,7 @@ _mesa_set_scissor(struct gl_context *ctx, ctx->Scissor.Height = height; if (ctx->Driver.Scissor) - ctx->Driver.Scissor( ctx, x, y, width, height ); + ctx->Driver.Scissor(ctx); } diff --git a/mesalib/src/mesa/main/shader_query.cpp b/mesalib/src/mesa/main/shader_query.cpp index f14e1a562..e1afe5315 100644 --- a/mesalib/src/mesa/main/shader_query.cpp +++ b/mesalib/src/mesa/main/shader_query.cpp @@ -59,7 +59,7 @@ _mesa_BindAttribLocation(GLhandleARB program, GLuint index, return; } - if (index >= ctx->Const.VertexProgram.MaxAttribs) { + if (index >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) { _mesa_error(ctx, GL_INVALID_VALUE, "glBindAttribLocation(index)"); return; } diff --git a/mesalib/src/mesa/main/shaderapi.c b/mesalib/src/mesa/main/shaderapi.c index 57511e83e..6042fa896 100644 --- a/mesalib/src/mesa/main/shaderapi.c +++ b/mesalib/src/mesa/main/shaderapi.c @@ -108,7 +108,7 @@ _mesa_init_shader_state(struct gl_context *ctx) * are generated by the GLSL compiler. */ struct gl_shader_compiler_options options; - gl_shader_type sh; + gl_shader_stage sh; memset(&options, 0, sizeof(options)); options.MaxUnrollIterations = 32; @@ -117,7 +117,7 @@ _mesa_init_shader_state(struct gl_context *ctx) /* Default pragma settings */ options.DefaultPragmas.Optimize = GL_TRUE; - for (sh = 0; sh < MESA_SHADER_TYPES; ++sh) + for (sh = 0; sh < MESA_SHADER_STAGES; ++sh) memcpy(&ctx->ShaderCompilerOptions[sh], &options, sizeof(options)); ctx->Shader.Flags = get_shader_flags(); @@ -778,7 +778,7 @@ compile_shader(struct gl_context *ctx, GLuint shaderObj) if (!sh) return; - options = &ctx->ShaderCompilerOptions[_mesa_shader_type_to_index(sh->Type)]; + options = &ctx->ShaderCompilerOptions[sh->Stage]; /* set default pragma state for shader */ sh->Pragmas = options->DefaultPragmas; @@ -791,7 +791,7 @@ compile_shader(struct gl_context *ctx, GLuint shaderObj) } else { if (ctx->Shader.Flags & GLSL_DUMP) { printf("GLSL source for %s shader %d:\n", - _mesa_shader_enum_to_string(sh->Type), sh->Name); + _mesa_shader_stage_to_string(sh->Stage), sh->Name); printf("%s\n", sh->Source); } @@ -823,7 +823,7 @@ compile_shader(struct gl_context *ctx, GLuint shaderObj) if (!sh->CompileStatus) { if (ctx->Shader.Flags & GLSL_DUMP_ON_ERROR) { fprintf(stderr, "GLSL source for %s shader %d:\n", - _mesa_shader_enum_to_string(sh->Type), sh->Name); + _mesa_shader_stage_to_string(sh->Stage), sh->Name); fprintf(stderr, "%s\n", sh->Source); fprintf(stderr, "Info Log:\n%s\n", sh->InfoLog); fflush(stderr); @@ -898,7 +898,7 @@ print_shader_info(const struct gl_shader_program *shProg) printf("Mesa: glUseProgram(%u)\n", shProg->Name); for (i = 0; i < shProg->NumShaders; i++) { printf(" %s shader %u, checksum %u\n", - _mesa_shader_enum_to_string(shProg->Shaders[i]->Type), + _mesa_shader_stage_to_string(shProg->Shaders[i]->Stage), shProg->Shaders[i]->Name, shProg->Shaders[i]->SourceChecksum); } @@ -1533,10 +1533,10 @@ _mesa_GetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, switch (shadertype) { case GL_VERTEX_SHADER: - limits = &ctx->Const.VertexProgram; + limits = &ctx->Const.Program[MESA_SHADER_VERTEX]; break; case GL_FRAGMENT_SHADER: - limits = &ctx->Const.FragmentProgram; + limits = &ctx->Const.Program[MESA_SHADER_FRAGMENT]; break; default: _mesa_error(ctx, GL_INVALID_ENUM, @@ -1836,7 +1836,7 @@ _mesa_CreateShaderProgramEXT(GLenum type, const GLchar *string) * object to a specific gl_program object. */ void -_mesa_copy_linked_program_data(gl_shader_type type, +_mesa_copy_linked_program_data(gl_shader_stage type, const struct gl_shader_program *src, struct gl_program *dst) { diff --git a/mesalib/src/mesa/main/shaderapi.h b/mesalib/src/mesa/main/shaderapi.h index fe58e7de9..4822e32c2 100644 --- a/mesalib/src/mesa/main/shaderapi.h +++ b/mesalib/src/mesa/main/shaderapi.h @@ -211,7 +211,7 @@ extern GLuint GLAPIENTRY _mesa_CreateShaderProgramEXT(GLenum type, const GLchar *string); extern void -_mesa_copy_linked_program_data(gl_shader_type type, +_mesa_copy_linked_program_data(gl_shader_stage type, const struct gl_shader_program *src, struct gl_program *dst); diff --git a/mesalib/src/mesa/main/shaderimage.c b/mesalib/src/mesa/main/shaderimage.c new file mode 100644 index 000000000..80c469366 --- /dev/null +++ b/mesalib/src/mesa/main/shaderimage.c @@ -0,0 +1,488 @@ +/* + * Copyright 2013 Intel Corporation + * + * 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 (including the next + * paragraph) 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 + * THE AUTHORS OR COPYRIGHT HOLDERS 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. + * + * Authors: + * Francisco Jerez <currojerez@riseup.net> + */ + +#include <assert.h> + +#include "shaderimage.h" +#include "mtypes.h" +#include "formats.h" +#include "errors.h" +#include "context.h" +#include "texobj.h" +#include "teximage.h" + +/* + * Define endian-invariant aliases for some mesa formats that are + * defined in terms of their channel layout from LSB to MSB in a + * 32-bit word. The actual byte offsets matter here because the user + * is allowed to bit-cast one format into another and get predictable + * results. + */ +#ifdef MESA_BIG_ENDIAN +# define MESA_FORMAT_RGBA_8 MESA_FORMAT_RGBA8888 +# define MESA_FORMAT_RG_16 MESA_FORMAT_RG1616 +# define MESA_FORMAT_RG_8 MESA_FORMAT_RG88 +# define MESA_FORMAT_SIGNED_RGBA_8 MESA_FORMAT_SIGNED_RGBA8888 +# define MESA_FORMAT_SIGNED_RG_16 MESA_FORMAT_SIGNED_RG1616 +# define MESA_FORMAT_SIGNED_RG_8 MESA_FORMAT_SIGNED_RG88 +#else +# define MESA_FORMAT_RGBA_8 MESA_FORMAT_RGBA8888_REV +# define MESA_FORMAT_RG_16 MESA_FORMAT_GR1616 +# define MESA_FORMAT_RG_8 MESA_FORMAT_GR88 +# define MESA_FORMAT_SIGNED_RGBA_8 MESA_FORMAT_SIGNED_RGBA8888_REV +# define MESA_FORMAT_SIGNED_RG_16 MESA_FORMAT_SIGNED_GR1616 +# define MESA_FORMAT_SIGNED_RG_8 MESA_FORMAT_SIGNED_RG88_REV +#endif + +static gl_format +get_image_format(GLenum format) +{ + switch (format) { + case GL_RGBA32F: + return MESA_FORMAT_RGBA_FLOAT32; + + case GL_RGBA16F: + return MESA_FORMAT_RGBA_FLOAT16; + + case GL_RG32F: + return MESA_FORMAT_RG_FLOAT32; + + case GL_RG16F: + return MESA_FORMAT_RG_FLOAT16; + + case GL_R11F_G11F_B10F: + return MESA_FORMAT_R11_G11_B10_FLOAT; + + case GL_R32F: + return MESA_FORMAT_R_FLOAT32; + + case GL_R16F: + return MESA_FORMAT_R_FLOAT16; + + case GL_RGBA32UI: + return MESA_FORMAT_RGBA_UINT32; + + case GL_RGBA16UI: + return MESA_FORMAT_RGBA_UINT16; + + case GL_RGB10_A2UI: + return MESA_FORMAT_ABGR2101010_UINT; + + case GL_RGBA8UI: + return MESA_FORMAT_RGBA_UINT8; + + case GL_RG32UI: + return MESA_FORMAT_RG_UINT32; + + case GL_RG16UI: + return MESA_FORMAT_RG_UINT16; + + case GL_RG8UI: + return MESA_FORMAT_RG_UINT8; + + case GL_R32UI: + return MESA_FORMAT_R_UINT32; + + case GL_R16UI: + return MESA_FORMAT_R_UINT16; + + case GL_R8UI: + return MESA_FORMAT_R_UINT8; + + case GL_RGBA32I: + return MESA_FORMAT_RGBA_INT32; + + case GL_RGBA16I: + return MESA_FORMAT_RGBA_INT16; + + case GL_RGBA8I: + return MESA_FORMAT_RGBA_INT8; + + case GL_RG32I: + return MESA_FORMAT_RG_INT32; + + case GL_RG16I: + return MESA_FORMAT_RG_INT16; + + case GL_RG8I: + return MESA_FORMAT_RG_INT8; + + case GL_R32I: + return MESA_FORMAT_R_INT32; + + case GL_R16I: + return MESA_FORMAT_R_INT16; + + case GL_R8I: + return MESA_FORMAT_R_INT8; + + case GL_RGBA16: + return MESA_FORMAT_RGBA_16; + + case GL_RGB10_A2: + return MESA_FORMAT_ABGR2101010; + + case GL_RGBA8: + return MESA_FORMAT_RGBA_8; + + case GL_RG16: + return MESA_FORMAT_RG_16; + + case GL_RG8: + return MESA_FORMAT_RG_8; + + case GL_R16: + return MESA_FORMAT_R16; + + case GL_R8: + return MESA_FORMAT_R8; + + case GL_RGBA16_SNORM: + return MESA_FORMAT_SIGNED_RGBA_16; + + case GL_RGBA8_SNORM: + return MESA_FORMAT_SIGNED_RGBA_8; + + case GL_RG16_SNORM: + return MESA_FORMAT_SIGNED_RG_16; + + case GL_RG8_SNORM: + return MESA_FORMAT_SIGNED_RG_8; + + case GL_R16_SNORM: + return MESA_FORMAT_SIGNED_R16; + + case GL_R8_SNORM: + return MESA_FORMAT_SIGNED_R8; + + default: + return MESA_FORMAT_NONE; + } +} + +enum image_format_class +{ + /** Not a valid image format. */ + IMAGE_FORMAT_CLASS_NONE = 0, + + /** Classes of image formats you can cast into each other. */ + /** \{ */ + IMAGE_FORMAT_CLASS_1X8, + IMAGE_FORMAT_CLASS_1X16, + IMAGE_FORMAT_CLASS_1X32, + IMAGE_FORMAT_CLASS_2X8, + IMAGE_FORMAT_CLASS_2X16, + IMAGE_FORMAT_CLASS_2X32, + IMAGE_FORMAT_CLASS_10_11_11, + IMAGE_FORMAT_CLASS_4X8, + IMAGE_FORMAT_CLASS_4X16, + IMAGE_FORMAT_CLASS_4X32, + IMAGE_FORMAT_CLASS_2_10_10_10 + /** \} */ +}; + +static enum image_format_class +get_image_format_class(gl_format format) +{ + switch (format) { + case MESA_FORMAT_RGBA_FLOAT32: + return IMAGE_FORMAT_CLASS_4X32; + + case MESA_FORMAT_RGBA_FLOAT16: + return IMAGE_FORMAT_CLASS_4X16; + + case MESA_FORMAT_RG_FLOAT32: + return IMAGE_FORMAT_CLASS_2X32; + + case MESA_FORMAT_RG_FLOAT16: + return IMAGE_FORMAT_CLASS_2X16; + + case MESA_FORMAT_R11_G11_B10_FLOAT: + return IMAGE_FORMAT_CLASS_10_11_11; + + case MESA_FORMAT_R_FLOAT32: + return IMAGE_FORMAT_CLASS_1X32; + + case MESA_FORMAT_R_FLOAT16: + return IMAGE_FORMAT_CLASS_1X16; + + case MESA_FORMAT_RGBA_UINT32: + return IMAGE_FORMAT_CLASS_4X32; + + case MESA_FORMAT_RGBA_UINT16: + return IMAGE_FORMAT_CLASS_4X16; + + case MESA_FORMAT_ABGR2101010_UINT: + return IMAGE_FORMAT_CLASS_2_10_10_10; + + case MESA_FORMAT_RGBA_UINT8: + return IMAGE_FORMAT_CLASS_4X8; + + case MESA_FORMAT_RG_UINT32: + return IMAGE_FORMAT_CLASS_2X32; + + case MESA_FORMAT_RG_UINT16: + return IMAGE_FORMAT_CLASS_2X16; + + case MESA_FORMAT_RG_UINT8: + return IMAGE_FORMAT_CLASS_2X8; + + case MESA_FORMAT_R_UINT32: + return IMAGE_FORMAT_CLASS_1X32; + + case MESA_FORMAT_R_UINT16: + return IMAGE_FORMAT_CLASS_1X16; + + case MESA_FORMAT_R_UINT8: + return IMAGE_FORMAT_CLASS_1X8; + + case MESA_FORMAT_RGBA_INT32: + return IMAGE_FORMAT_CLASS_4X32; + + case MESA_FORMAT_RGBA_INT16: + return IMAGE_FORMAT_CLASS_4X16; + + case MESA_FORMAT_RGBA_INT8: + return IMAGE_FORMAT_CLASS_4X8; + + case MESA_FORMAT_RG_INT32: + return IMAGE_FORMAT_CLASS_2X32; + + case MESA_FORMAT_RG_INT16: + return IMAGE_FORMAT_CLASS_2X16; + + case MESA_FORMAT_RG_INT8: + return IMAGE_FORMAT_CLASS_2X8; + + case MESA_FORMAT_R_INT32: + return IMAGE_FORMAT_CLASS_1X32; + + case MESA_FORMAT_R_INT16: + return IMAGE_FORMAT_CLASS_1X16; + + case MESA_FORMAT_R_INT8: + return IMAGE_FORMAT_CLASS_1X8; + + case MESA_FORMAT_RGBA_16: + return IMAGE_FORMAT_CLASS_4X16; + + case MESA_FORMAT_ABGR2101010: + return IMAGE_FORMAT_CLASS_2_10_10_10; + + case MESA_FORMAT_RGBA_8: + return IMAGE_FORMAT_CLASS_4X8; + + case MESA_FORMAT_RG_16: + return IMAGE_FORMAT_CLASS_2X16; + + case MESA_FORMAT_RG_8: + return IMAGE_FORMAT_CLASS_2X8; + + case MESA_FORMAT_R16: + return IMAGE_FORMAT_CLASS_1X16; + + case MESA_FORMAT_R8: + return IMAGE_FORMAT_CLASS_1X8; + + case MESA_FORMAT_SIGNED_RGBA_16: + return IMAGE_FORMAT_CLASS_4X16; + + case MESA_FORMAT_SIGNED_RGBA_8: + return IMAGE_FORMAT_CLASS_4X8; + + case MESA_FORMAT_SIGNED_RG_16: + return IMAGE_FORMAT_CLASS_2X16; + + case MESA_FORMAT_SIGNED_RG_8: + return IMAGE_FORMAT_CLASS_2X8; + + case MESA_FORMAT_SIGNED_R16: + return IMAGE_FORMAT_CLASS_1X16; + + case MESA_FORMAT_SIGNED_R8: + return IMAGE_FORMAT_CLASS_1X8; + + default: + return IMAGE_FORMAT_CLASS_NONE; + } +} + +static GLboolean +validate_image_unit(struct gl_context *ctx, struct gl_image_unit *u) +{ + struct gl_texture_object *t = u->TexObj; + struct gl_texture_image *img; + + if (!t || u->Level < t->BaseLevel || + u->Level > t->_MaxLevel) + return GL_FALSE; + + _mesa_test_texobj_completeness(ctx, t); + + if ((u->Level == t->BaseLevel && !t->_BaseComplete) || + (u->Level != t->BaseLevel && !t->_MipmapComplete)) + return GL_FALSE; + + if (_mesa_tex_target_is_layered(t->Target) && + u->Layer >= _mesa_get_texture_layers(t, u->Level)) + return GL_FALSE; + + if (t->Target == GL_TEXTURE_CUBE_MAP) + img = t->Image[u->Layer][u->Level]; + else + img = t->Image[0][u->Level]; + + if (!img || img->Border || + get_image_format_class(img->TexFormat) == IMAGE_FORMAT_CLASS_NONE || + img->NumSamples > ctx->Const.MaxImageSamples) + return GL_FALSE; + + switch (t->ImageFormatCompatibilityType) { + case GL_IMAGE_FORMAT_COMPATIBILITY_BY_SIZE: + if (_mesa_get_format_bytes(img->TexFormat) != + _mesa_get_format_bytes(u->_ActualFormat)) + return GL_FALSE; + break; + + case GL_IMAGE_FORMAT_COMPATIBILITY_BY_CLASS: + if (get_image_format_class(img->TexFormat) != + get_image_format_class(u->_ActualFormat)) + return GL_FALSE; + break; + + default: + assert(!"Unexpected image format compatibility type"); + } + + return GL_TRUE; +} + +void +_mesa_validate_image_units(struct gl_context *ctx) +{ + int i; + + for (i = 0; i < ctx->Const.MaxImageUnits; ++i) { + struct gl_image_unit *u = &ctx->ImageUnits[i]; + u->_Valid = validate_image_unit(ctx, u); + } +} + +static GLboolean +validate_bind_image_texture(struct gl_context *ctx, GLuint unit, + GLuint texture, GLint level, GLboolean layered, + GLint layer, GLenum access, GLenum format) +{ + assert(ctx->Const.MaxImageUnits <= MAX_IMAGE_UNITS); + + if (unit >= ctx->Const.MaxImageUnits) { + _mesa_error(ctx, GL_INVALID_VALUE, "glBindImageTexture(unit)"); + return GL_FALSE; + } + + if (level < 0) { + _mesa_error(ctx, GL_INVALID_VALUE, "glBindImageTexture(level)"); + return GL_FALSE; + } + + if (layer < 0) { + _mesa_error(ctx, GL_INVALID_VALUE, "glBindImageTexture(layer)"); + return GL_FALSE; + } + + if (access != GL_READ_ONLY && + access != GL_WRITE_ONLY && + access != GL_READ_WRITE) { + _mesa_error(ctx, GL_INVALID_VALUE, "glBindImageTexture(access)"); + return GL_FALSE; + } + + if (!get_image_format(format)) { + _mesa_error(ctx, GL_INVALID_VALUE, "glBindImageTexture(format)"); + return GL_FALSE; + } + + return GL_TRUE; +} + +void GLAPIENTRY +_mesa_BindImageTexture(GLuint unit, GLuint texture, GLint level, + GLboolean layered, GLint layer, GLenum access, + GLenum format) +{ + GET_CURRENT_CONTEXT(ctx); + struct gl_texture_object *t = NULL; + struct gl_image_unit *u; + + if (!validate_bind_image_texture(ctx, unit, texture, level, + layered, layer, access, format)) + return; + + u = &ctx->ImageUnits[unit]; + + FLUSH_VERTICES(ctx, 0); + ctx->NewDriverState |= ctx->DriverFlags.NewImageUnits; + + if (texture) { + t = _mesa_lookup_texture(ctx, texture); + if (!t) { + _mesa_error(ctx, GL_INVALID_VALUE, "glBindImageTexture(texture)"); + return; + } + + _mesa_reference_texobj(&u->TexObj, t); + u->Level = level; + u->Access = access; + u->Format = format; + u->_ActualFormat = get_image_format(format); + + if (_mesa_tex_target_is_layered(t->Target)) { + u->Layered = layered; + u->Layer = (layered ? 0 : layer); + } else { + u->Layered = GL_FALSE; + u->Layer = 0; + } + + } else { + _mesa_reference_texobj(&u->TexObj, NULL); + } + + u->_Valid = validate_image_unit(ctx, u); + + if (ctx->Driver.BindImageTexture) + ctx->Driver.BindImageTexture(ctx, u, t, level, layered, + layer, access, format); +} + +void GLAPIENTRY +_mesa_MemoryBarrier(GLbitfield barriers) +{ + GET_CURRENT_CONTEXT(ctx); + + if (ctx->Driver.MemoryBarrier) + ctx->Driver.MemoryBarrier(ctx, barriers); +} diff --git a/mesalib/src/mesa/main/shaderimage.h b/mesalib/src/mesa/main/shaderimage.h new file mode 100644 index 000000000..aaecc5d29 --- /dev/null +++ b/mesalib/src/mesa/main/shaderimage.h @@ -0,0 +1,51 @@ +/* + * Copyright 2013 Intel Corporation + * + * 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 (including the next + * paragraph) 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 + * THE AUTHORS OR COPYRIGHT HOLDERS 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. + * + * Authors: + * Francisco Jerez <currojerez@riseup.net> + */ + +#ifndef SHADERIMAGE_H +#define SHADERIMAGE_H + +#include "glheader.h" + +struct gl_context; + +/** + * Recalculate the \c _Valid flag of a context's shader image units. + * + * To be called when the state of any texture bound to an image unit + * changes. + */ +void +_mesa_validate_image_units(struct gl_context *ctx); + +void GLAPIENTRY +_mesa_BindImageTexture(GLuint unit, GLuint texture, GLint level, + GLboolean layered, GLint layer, GLenum access, + GLenum format); + +void GLAPIENTRY +_mesa_MemoryBarrier(GLbitfield barriers); + +#endif diff --git a/mesalib/src/mesa/main/shaderobj.c b/mesalib/src/mesa/main/shaderobj.c index 0d794ad96..dc81bbc77 100644 --- a/mesalib/src/mesa/main/shaderobj.c +++ b/mesalib/src/mesa/main/shaderobj.c @@ -110,6 +110,7 @@ _mesa_new_shader(struct gl_context *ctx, GLuint name, GLenum type) shader = rzalloc(NULL, struct gl_shader); if (shader) { shader->Type = type; + shader->Stage = _mesa_shader_enum_to_shader_stage(type); shader->Name = name; _mesa_init_shader(ctx, shader); } @@ -307,7 +308,7 @@ _mesa_free_shader_program_data(struct gl_context *ctx, struct gl_shader_program *shProg) { GLuint i; - gl_shader_type sh; + gl_shader_stage sh; assert(shProg->Type == GL_SHADER_PROGRAM_MESA); @@ -346,7 +347,7 @@ _mesa_free_shader_program_data(struct gl_context *ctx, shProg->TransformFeedback.NumVarying = 0; - for (sh = 0; sh < MESA_SHADER_TYPES; sh++) { + for (sh = 0; sh < MESA_SHADER_STAGES; sh++) { if (shProg->_LinkedShaders[sh] != NULL) { ctx->Driver.DeleteShader(ctx, shProg->_LinkedShaders[sh]); shProg->_LinkedShaders[sh] = NULL; diff --git a/mesalib/src/mesa/main/shaderobj.h b/mesalib/src/mesa/main/shaderobj.h index 155058d71..517557088 100644 --- a/mesalib/src/mesa/main/shaderobj.h +++ b/mesalib/src/mesa/main/shaderobj.h @@ -101,8 +101,8 @@ extern void _mesa_free_shader_state(struct gl_context *ctx); -static inline gl_shader_type -_mesa_shader_type_to_index(GLenum v) +static inline gl_shader_stage +_mesa_shader_enum_to_shader_stage(GLenum v) { switch (v) { case GL_VERTEX_SHADER: @@ -112,7 +112,7 @@ _mesa_shader_type_to_index(GLenum v) case GL_GEOMETRY_SHADER: return MESA_SHADER_GEOMETRY; default: - ASSERT(0 && "bad value in _mesa_shader_type_to_index()"); + ASSERT(0 && "bad value in _mesa_shader_enum_to_shader_stage()"); return MESA_SHADER_VERTEX; } } diff --git a/mesalib/src/mesa/main/texcompress.c b/mesalib/src/mesa/main/texcompress.c index e71d0c411..47ad30605 100644 --- a/mesalib/src/mesa/main/texcompress.c +++ b/mesalib/src/mesa/main/texcompress.c @@ -263,6 +263,43 @@ _mesa_get_compressed_formats(struct gl_context *ctx, GLint *formats) else { n += 3; } + + /* The ES and desktop GL specs diverge here. + * + * In desktop OpenGL, the driver can perform online compression of + * uncompressed texture data. GL_NUM_COMPRESSED_TEXTURE_FORMATS and + * GL_COMPRESSED_TEXTURE_FORMATS give the application a list of + * formats that it could ask the driver to compress with some + * expectation of quality. The GL_ARB_texture_compression spec + * calls this "suitable for general-purpose usage." As noted + * above, this means GL_COMPRESSED_RGBA_S3TC_DXT1_EXT is not + * included in the list. + * + * In OpenGL ES, the driver never performs compression. + * GL_NUM_COMPRESSED_TEXTURE_FORMATS and + * GL_COMPRESSED_TEXTURE_FORMATS give the application a list of + * formats that the driver can receive from the application. It + * is the *complete* list of formats. The + * GL_EXT_texture_compression_s3tc spec says: + * + * "New State for OpenGL ES 2.0.25 and 3.0.2 Specifications + * + * The queries for NUM_COMPRESSED_TEXTURE_FORMATS and + * COMPRESSED_TEXTURE_FORMATS include + * COMPRESSED_RGB_S3TC_DXT1_EXT, + * COMPRESSED_RGBA_S3TC_DXT1_EXT, + * COMPRESSED_RGBA_S3TC_DXT3_EXT, and + * COMPRESSED_RGBA_S3TC_DXT5_EXT." + * + * Note that the addition is only to the OpenGL ES specification! + */ + if (_mesa_is_gles(ctx)) { + if (formats) { + formats[n++] = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT; + } else { + n += 1; + } + } } /* The GL_OES_compressed_ETC1_RGB8_texture spec says: diff --git a/mesalib/src/mesa/main/texenv.c b/mesalib/src/mesa/main/texenv.c index 1aadd7fde..4848208f5 100644 --- a/mesalib/src/mesa/main/texenv.c +++ b/mesalib/src/mesa/main/texenv.c @@ -879,7 +879,7 @@ _mesa_GetTexBumpParameterivATI( GLenum pname, GLint *param ) } else if (pname == GL_BUMP_NUM_TEX_UNITS_ATI) { GLint count = 0; - for (i = 0; i < ctx->Const.FragmentProgram.MaxTextureImageUnits; i++) { + for (i = 0; i < ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits; i++) { if (ctx->Const.SupportedBumpUnits & (1 << i)) { count++; } @@ -887,7 +887,7 @@ _mesa_GetTexBumpParameterivATI( GLenum pname, GLint *param ) *param = count; } else if (pname == GL_BUMP_TEX_UNITS_ATI) { - for (i = 0; i < ctx->Const.FragmentProgram.MaxTextureImageUnits; i++) { + for (i = 0; i < ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits; i++) { if (ctx->Const.SupportedBumpUnits & (1 << i)) { *param++ = i + GL_TEXTURE0; } @@ -928,7 +928,7 @@ _mesa_GetTexBumpParameterfvATI( GLenum pname, GLfloat *param ) } else if (pname == GL_BUMP_NUM_TEX_UNITS_ATI) { GLint count = 0; - for (i = 0; i < ctx->Const.FragmentProgram.MaxTextureImageUnits; i++) { + for (i = 0; i < ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits; i++) { if (ctx->Const.SupportedBumpUnits & (1 << i)) { count++; } @@ -936,7 +936,7 @@ _mesa_GetTexBumpParameterfvATI( GLenum pname, GLfloat *param ) *param = (GLfloat) count; } else if (pname == GL_BUMP_TEX_UNITS_ATI) { - for (i = 0; i < ctx->Const.FragmentProgram.MaxTextureImageUnits; i++) { + for (i = 0; i < ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits; i++) { if (ctx->Const.SupportedBumpUnits & (1 << i)) { *param++ = (GLfloat) (i + GL_TEXTURE0); } diff --git a/mesalib/src/mesa/main/teximage.c b/mesalib/src/mesa/main/teximage.c index 9c3f1e86e..8aac54e9d 100644 --- a/mesalib/src/mesa/main/teximage.c +++ b/mesalib/src/mesa/main/teximage.c @@ -1088,6 +1088,93 @@ _mesa_get_texture_dimensions(GLenum target) /** + * Check if a texture target can have more than one layer. + */ +GLboolean +_mesa_tex_target_is_layered(GLenum target) +{ + switch (target) { + case GL_TEXTURE_1D: + case GL_PROXY_TEXTURE_1D: + case GL_TEXTURE_2D: + case GL_PROXY_TEXTURE_2D: + case GL_TEXTURE_RECTANGLE: + case GL_PROXY_TEXTURE_RECTANGLE: + case GL_TEXTURE_2D_MULTISAMPLE: + case GL_PROXY_TEXTURE_2D_MULTISAMPLE: + case GL_TEXTURE_BUFFER: + case GL_TEXTURE_CUBE_MAP_POSITIVE_X: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: + case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: + case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: + case GL_TEXTURE_EXTERNAL_OES: + return GL_FALSE; + + case GL_TEXTURE_3D: + case GL_PROXY_TEXTURE_3D: + case GL_TEXTURE_CUBE_MAP: + case GL_PROXY_TEXTURE_CUBE_MAP: + case GL_TEXTURE_1D_ARRAY: + case GL_PROXY_TEXTURE_1D_ARRAY: + case GL_TEXTURE_2D_ARRAY: + case GL_PROXY_TEXTURE_2D_ARRAY: + case GL_TEXTURE_CUBE_MAP_ARRAY: + case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY: + case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: + case GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY: + return GL_TRUE; + + default: + assert(!"Invalid texture target."); + return GL_FALSE; + } +} + + +/** + * Return the number of layers present in the given level of an array, + * cubemap or 3D texture. If the texture is not layered return zero. + */ +GLuint +_mesa_get_texture_layers(const struct gl_texture_object *texObj, GLint level) +{ + assert(level >= 0 && level < MAX_TEXTURE_LEVELS); + + switch (texObj->Target) { + case GL_TEXTURE_1D: + case GL_TEXTURE_2D: + case GL_TEXTURE_RECTANGLE: + case GL_TEXTURE_2D_MULTISAMPLE: + case GL_TEXTURE_BUFFER: + case GL_TEXTURE_EXTERNAL_OES: + return 0; + + case GL_TEXTURE_CUBE_MAP: + return 6; + + case GL_TEXTURE_1D_ARRAY: { + struct gl_texture_image *img = texObj->Image[0][level]; + return img ? img->Height : 0; + } + + case GL_TEXTURE_3D: + case GL_TEXTURE_2D_ARRAY: + case GL_TEXTURE_CUBE_MAP_ARRAY: + case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: { + struct gl_texture_image *img = texObj->Image[0][level]; + return img ? img->Depth : 0; + } + + default: + assert(!"Invalid texture target."); + return 0; + } +} + + +/** * Return the maximum number of mipmap levels for the given target * and the dimensions. * The dimensions are expected not to include the border. diff --git a/mesalib/src/mesa/main/teximage.h b/mesalib/src/mesa/main/teximage.h index 0b5786340..80a0a57b5 100644 --- a/mesalib/src/mesa/main/teximage.h +++ b/mesalib/src/mesa/main/teximage.h @@ -138,6 +138,12 @@ _mesa_tex_target_to_face(GLenum target); extern GLint _mesa_get_texture_dimensions(GLenum target); +extern GLboolean +_mesa_tex_target_is_layered(GLenum target); + +extern GLuint +_mesa_get_texture_layers(const struct gl_texture_object *texObj, GLint level); + extern GLsizei _mesa_get_tex_max_num_levels(GLenum target, GLsizei width, GLsizei height, GLsizei depth); diff --git a/mesalib/src/mesa/main/texobj.c b/mesalib/src/mesa/main/texobj.c index d6510fefd..3c64c4376 100644 --- a/mesalib/src/mesa/main/texobj.c +++ b/mesalib/src/mesa/main/texobj.c @@ -157,6 +157,7 @@ _mesa_initialize_texture_object( struct gl_context *ctx, obj->Sampler.sRGBDecode = GL_DECODE_EXT; obj->BufferObjectFormat = GL_R8; obj->_BufferObjectFormat = MESA_FORMAT_R8; + obj->ImageFormatCompatibilityType = GL_IMAGE_FORMAT_COMPATIBILITY_BY_SIZE; } @@ -1099,6 +1100,25 @@ unbind_texobj_from_texunits(struct gl_context *ctx, /** + * Check if the given texture object is bound to any shader image unit + * and unbind it if that's the case. + */ +static void +unbind_texobj_from_imgunits(struct gl_context *ctx, + struct gl_texture_object *texObj) +{ + int i; + + for (i = 0; i < ctx->Const.MaxImageUnits; i++) { + struct gl_image_unit *unit = &ctx->ImageUnits[i]; + + if (texObj == unit->TexObj) + _mesa_reference_texobj(&unit->TexObj, NULL); + } +} + + +/** * Delete named textures. * * \param n number of textures to be deleted. @@ -1145,6 +1165,12 @@ _mesa_DeleteTextures( GLsizei n, const GLuint *textures) */ unbind_texobj_from_texunits(ctx, delObj); + /* Check if this texture is currently bound to any shader + * image unit. If so, unbind it. + * See section 3.9.X of GL_ARB_shader_image_load_store. + */ + unbind_texobj_from_imgunits(ctx, delObj); + _mesa_unlock_texture(ctx, delObj); ctx->NewState |= _NEW_TEXTURE; diff --git a/mesalib/src/mesa/main/texparam.c b/mesalib/src/mesa/main/texparam.c index 94e498d20..7c59d119f 100644 --- a/mesalib/src/mesa/main/texparam.c +++ b/mesalib/src/mesa/main/texparam.c @@ -1808,6 +1808,12 @@ _mesa_GetTexParameteriv( GLenum target, GLenum pname, GLint *params ) *params = obj->Sampler.sRGBDecode; break; + case GL_IMAGE_FORMAT_COMPATIBILITY_TYPE: + if (!ctx->Extensions.ARB_shader_image_load_store) + goto invalid_pname; + *params = obj->ImageFormatCompatibilityType; + break; + default: goto invalid_pname; } diff --git a/mesalib/src/mesa/main/texstate.c b/mesalib/src/mesa/main/texstate.c index ad80dcfaa..7720965a8 100644 --- a/mesalib/src/mesa/main/texstate.c +++ b/mesalib/src/mesa/main/texstate.c @@ -35,6 +35,7 @@ #include "context.h" #include "enums.h" #include "macros.h" +#include "shaderimage.h" #include "texobj.h" #include "teximage.h" #include "texstate.h" @@ -674,6 +675,8 @@ update_texture_state( struct gl_context *ctx ) if (!fprog || !vprog) update_texgen(ctx); + + _mesa_validate_image_units(ctx); } diff --git a/mesalib/src/mesa/main/texstore.c b/mesalib/src/mesa/main/texstore.c index 5adbd5dc9..8eaf43a6a 100644 --- a/mesalib/src/mesa/main/texstore.c +++ b/mesalib/src/mesa/main/texstore.c @@ -2191,6 +2191,7 @@ _mesa_texstore_snorm88(TEXSTORE_PARAMS) const GLenum baseFormat = _mesa_get_format_base_format(dstFormat); ASSERT(dstFormat == MESA_FORMAT_SIGNED_AL88 || + dstFormat == MESA_FORMAT_SIGNED_RG88 || dstFormat == MESA_FORMAT_SIGNED_RG88_REV); ASSERT(_mesa_get_format_bytes(dstFormat) == 2); @@ -2210,13 +2211,27 @@ _mesa_texstore_snorm88(TEXSTORE_PARAMS) for (img = 0; img < srcDepth; img++) { GLbyte *dstRow = (GLbyte *) dstSlices[img]; for (row = 0; row < srcHeight; row++) { - GLbyte *dst = dstRow; - for (col = 0; col < srcWidth; col++) { - dst[0] = FLOAT_TO_BYTE_TEX(src[0]); - dst[1] = FLOAT_TO_BYTE_TEX(src[1]); - src += 2; - dst += 2; + GLushort *dst = (GLushort *) dstRow; + + if (dstFormat == MESA_FORMAT_SIGNED_AL88 || + dstFormat == MESA_FORMAT_SIGNED_RG88_REV) { + for (col = 0; col < srcWidth; col++) { + GLubyte l = FLOAT_TO_BYTE_TEX(src[0]); + GLubyte a = FLOAT_TO_BYTE_TEX(src[1]); + + dst[col] = PACK_COLOR_88_REV(l, a); + src += 2; + } + } else { + for (col = 0; col < srcWidth; col++) { + GLubyte l = FLOAT_TO_BYTE_TEX(src[0]); + GLubyte a = FLOAT_TO_BYTE_TEX(src[1]); + + dst[col] = PACK_COLOR_88(l, a); + src += 2; + } } + dstRow += dstRowStride; } } @@ -2278,6 +2293,7 @@ _mesa_texstore_snorm1616(TEXSTORE_PARAMS) const GLenum baseFormat = _mesa_get_format_base_format(dstFormat); ASSERT(dstFormat == MESA_FORMAT_SIGNED_AL1616 || + dstFormat == MESA_FORMAT_SIGNED_RG1616 || dstFormat == MESA_FORMAT_SIGNED_GR1616); ASSERT(_mesa_get_format_bytes(dstFormat) == 4); @@ -2297,17 +2313,29 @@ _mesa_texstore_snorm1616(TEXSTORE_PARAMS) for (img = 0; img < srcDepth; img++) { GLubyte *dstRow = dstSlices[img]; for (row = 0; row < srcHeight; row++) { - GLshort *dst = (GLshort *) dstRow; - for (col = 0; col < srcWidth; col++) { - GLushort l, a; + GLuint *dst = (GLuint *) dstRow; - UNCLAMPED_FLOAT_TO_SHORT(l, src[0]); - UNCLAMPED_FLOAT_TO_SHORT(a, src[1]); - dst[0] = l; - dst[1] = a; - src += 2; - dst += 2; + if (dstFormat == MESA_FORMAT_SIGNED_AL1616 || + dstFormat == MESA_FORMAT_SIGNED_GR1616) { + for (col = 0; col < srcWidth; col++) { + GLushort l, a; + + UNCLAMPED_FLOAT_TO_SHORT(l, src[0]); + UNCLAMPED_FLOAT_TO_SHORT(a, src[1]); + dst[col] = PACK_COLOR_1616_REV(l, a); + src += 2; + } + } else { + for (col = 0; col < srcWidth; col++) { + GLushort l, a; + + UNCLAMPED_FLOAT_TO_SHORT(l, src[0]); + UNCLAMPED_FLOAT_TO_SHORT(a, src[1]); + dst[col] = PACK_COLOR_1616_REV(l, a); + src += 2; + } } + dstRow += dstRowStride; } } @@ -3559,6 +3587,50 @@ _mesa_texstore_abgr2101010_uint(TEXSTORE_PARAMS) } static GLboolean +_mesa_texstore_abgr2101010(TEXSTORE_PARAMS) +{ + const GLenum baseFormat = _mesa_get_format_base_format(dstFormat); + + ASSERT(dstFormat == MESA_FORMAT_ABGR2101010); + ASSERT(_mesa_get_format_bytes(dstFormat) == 4); + + { + /* general path */ + const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims, + baseInternalFormat, + baseFormat, + srcWidth, srcHeight, srcDepth, + srcFormat, srcType, srcAddr, + srcPacking, + ctx->_ImageTransferState); + const GLfloat *src = tempImage; + GLint img, row, col; + if (!tempImage) + return GL_FALSE; + for (img = 0; img < srcDepth; img++) { + GLubyte *dstRow = dstSlices[img]; + + for (row = 0; row < srcHeight; row++) { + GLuint *dstUI = (GLuint *) dstRow; + for (col = 0; col < srcWidth; col++) { + GLushort a,r,g,b; + + UNCLAMPED_FLOAT_TO_USHORT(a, src[ACOMP]); + UNCLAMPED_FLOAT_TO_USHORT(r, src[RCOMP]); + UNCLAMPED_FLOAT_TO_USHORT(g, src[GCOMP]); + UNCLAMPED_FLOAT_TO_USHORT(b, src[BCOMP]); + dstUI[col] = PACK_COLOR_2101010_US(a, b, g, r); + src += 4; + } + dstRow += dstRowStride; + } + } + free((void *) tempImage); + } + return GL_TRUE; +} + +static GLboolean _mesa_texstore_null(TEXSTORE_PARAMS) { (void) ctx; (void) dims; @@ -3782,6 +3854,11 @@ _mesa_get_texstore_func(gl_format format) table[MESA_FORMAT_XBGR32323232_UINT] = _mesa_texstore_rgba_uint32; table[MESA_FORMAT_XBGR32323232_SINT] = _mesa_texstore_rgba_int32; + table[MESA_FORMAT_ABGR2101010] = _mesa_texstore_abgr2101010; + + table[MESA_FORMAT_SIGNED_RG88] = _mesa_texstore_snorm88; + table[MESA_FORMAT_SIGNED_RG1616] = _mesa_texstore_snorm1616; + initialized = GL_TRUE; } diff --git a/mesalib/src/mesa/main/uniform_query.cpp b/mesalib/src/mesa/main/uniform_query.cpp index 61bcbcb8a..82d7628e8 100644 --- a/mesalib/src/mesa/main/uniform_query.cpp +++ b/mesalib/src/mesa/main/uniform_query.cpp @@ -445,14 +445,14 @@ log_uniform(const void *values, enum glsl_base_type basicType, static void log_program_parameters(const struct gl_shader_program *shProg) { - for (unsigned i = 0; i < MESA_SHADER_TYPES; i++) { + for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) { if (shProg->_LinkedShaders[i] == NULL) continue; const struct gl_program *const prog = shProg->_LinkedShaders[i]->Program; printf("Program %d %s shader parameters:\n", - shProg->Name, _mesa_shader_enum_to_string(prog->Target)); + shProg->Name, _mesa_shader_stage_to_string(i)); for (unsigned j = 0; j < prog->Parameters->NumParameters; j++) { printf("%s: %p %f %f %f %f\n", prog->Parameters->Parameters[j].Name, @@ -784,7 +784,7 @@ _mesa_uniform(struct gl_context *ctx, struct gl_shader_program *shProg, int i; bool flushed = false; - for (i = 0; i < MESA_SHADER_TYPES; i++) { + for (i = 0; i < MESA_SHADER_STAGES; i++) { struct gl_shader *const sh = shProg->_LinkedShaders[i]; int j; diff --git a/mesalib/src/mesa/main/uniforms.c b/mesalib/src/mesa/main/uniforms.c index 17e24f678..071d668f3 100644 --- a/mesalib/src/mesa/main/uniforms.c +++ b/mesalib/src/mesa/main/uniforms.c @@ -68,7 +68,7 @@ _mesa_update_shader_textures_used(struct gl_shader_program *shProg, { GLuint s; struct gl_shader *shader = - shProg->_LinkedShaders[_mesa_program_target_to_index(prog->Target)]; + shProg->_LinkedShaders[_mesa_program_enum_to_shader_stage(prog->Target)]; assert(shader); @@ -642,7 +642,7 @@ _mesa_UniformBlockBinding(GLuint program, shProg->UniformBlocks[uniformBlockIndex].Binding = uniformBlockBinding; - for (i = 0; i < MESA_SHADER_TYPES; i++) { + for (i = 0; i < MESA_SHADER_STAGES; i++) { int stage_index = shProg->UniformBlockStageIndex[i][uniformBlockIndex]; if (stage_index != -1) { diff --git a/mesalib/src/mesa/main/varray.c b/mesalib/src/mesa/main/varray.c index 0f38270d5..b73a396e2 100644 --- a/mesalib/src/mesa/main/varray.c +++ b/mesalib/src/mesa/main/varray.c @@ -621,7 +621,7 @@ _mesa_VertexAttribPointer(GLuint index, GLint size, GLenum type, UNSIGNED_INT_10F_11F_11F_REV_BIT); GET_CURRENT_CONTEXT(ctx); - if (index >= ctx->Const.VertexProgram.MaxAttribs) { + if (index >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) { _mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribPointerARB(index)"); return; } @@ -649,7 +649,7 @@ _mesa_VertexAttribIPointer(GLuint index, GLint size, GLenum type, const GLboolean integer = GL_TRUE; GET_CURRENT_CONTEXT(ctx); - if (index >= ctx->Const.VertexProgram.MaxAttribs) { + if (index >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) { _mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribIPointer(index)"); return; } @@ -667,7 +667,7 @@ _mesa_EnableVertexAttribArray(GLuint index) struct gl_array_object *arrayObj; GET_CURRENT_CONTEXT(ctx); - if (index >= ctx->Const.VertexProgram.MaxAttribs) { + if (index >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) { _mesa_error(ctx, GL_INVALID_VALUE, "glEnableVertexAttribArrayARB(index)"); return; @@ -693,7 +693,7 @@ _mesa_DisableVertexAttribArray(GLuint index) struct gl_array_object *arrayObj; GET_CURRENT_CONTEXT(ctx); - if (index >= ctx->Const.VertexProgram.MaxAttribs) { + if (index >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) { _mesa_error(ctx, GL_INVALID_VALUE, "glDisableVertexAttribArrayARB(index)"); return; @@ -725,7 +725,7 @@ get_vertex_array_attrib(struct gl_context *ctx, GLuint index, GLenum pname, const struct gl_array_object *arrayObj = ctx->Array.ArrayObj; const struct gl_vertex_attrib_array *array; - if (index >= ctx->Const.VertexProgram.MaxAttribs) { + if (index >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) { _mesa_error(ctx, GL_INVALID_VALUE, "%s(index=%u)", caller, index); return 0; } @@ -795,7 +795,7 @@ get_current_attrib(struct gl_context *ctx, GLuint index, const char *function) return NULL; } } - else if (index >= ctx->Const.VertexProgram.MaxAttribs) { + else if (index >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) { _mesa_error(ctx, GL_INVALID_VALUE, "%s(index>=GL_MAX_VERTEX_ATTRIBS)", function); return NULL; @@ -913,7 +913,7 @@ _mesa_GetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid **pointer) { GET_CURRENT_CONTEXT(ctx); - if (index >= ctx->Const.VertexProgram.MaxAttribs) { + if (index >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) { _mesa_error(ctx, GL_INVALID_VALUE, "glGetVertexAttribPointerARB(index)"); return; } @@ -1308,7 +1308,7 @@ _mesa_VertexAttribDivisor(GLuint index, GLuint divisor) return; } - if (index >= ctx->Const.VertexProgram.MaxAttribs) { + if (index >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) { _mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribDivisor(index = %u)", index); return; @@ -1479,7 +1479,7 @@ _mesa_VertexAttribFormat(GLuint attribIndex, GLint size, GLenum type, * "The error INVALID_VALUE is generated if index is greater than or equal * to the value of MAX_VERTEX_ATTRIBS." */ - if (attribIndex >= ctx->Const.VertexProgram.MaxAttribs) { + if (attribIndex >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) { _mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribFormat(attribindex=%u > " "GL_MAX_VERTEX_ATTRIBS)", @@ -1526,7 +1526,7 @@ _mesa_VertexAttribIFormat(GLuint attribIndex, GLint size, GLenum type, * "The error INVALID_VALUE is generated if index is greater than * or equal to the value of MAX_VERTEX_ATTRIBS." */ - if (attribIndex >= ctx->Const.VertexProgram.MaxAttribs) { + if (attribIndex >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) { _mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribIFormat(attribindex=%u > " "GL_MAX_VERTEX_ATTRIBS)", @@ -1574,7 +1574,7 @@ _mesa_VertexAttribLFormat(GLuint attribIndex, GLint size, GLenum type, * "The error INVALID_VALUE is generated if <attribindex> is greater than * or equal to the value of MAX_VERTEX_ATTRIBS." */ - if (attribIndex >= ctx->Const.VertexProgram.MaxAttribs) { + if (attribIndex >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) { _mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribLFormat(attribindex=%u > " "GL_MAX_VERTEX_ATTRIBS)", @@ -1616,7 +1616,7 @@ _mesa_VertexAttribBinding(GLuint attribIndex, GLuint bindingIndex) * MAX_VERTEX_ATTRIB_BINDINGS, otherwise the error INVALID_VALUE * is generated." */ - if (attribIndex >= ctx->Const.VertexProgram.MaxAttribs) { + if (attribIndex >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) { _mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribBinding(attribindex=%u >= " "GL_MAX_VERTEX_ATTRIBS)", diff --git a/mesalib/src/mesa/main/version.c b/mesalib/src/mesa/main/version.c index 119c7dae3..587cb9ad5 100644 --- a/mesalib/src/mesa/main/version.c +++ b/mesalib/src/mesa/main/version.c @@ -255,7 +255,7 @@ compute_version(struct gl_context *ctx) ctx->Extensions.EXT_texture_snorm && ctx->Extensions.NV_primitive_restart && ctx->Extensions.NV_texture_rectangle && - ctx->Const.VertexProgram.MaxTextureImageUnits >= 16); + ctx->Const.Program[MESA_SHADER_VERTEX].MaxTextureImageUnits >= 16); const GLboolean ver_3_2 = (ver_3_1 && ctx->Const.GLSLVersion >= 150 && ctx->Extensions.ARB_depth_clamp && diff --git a/mesalib/src/mesa/main/viewport.c b/mesalib/src/mesa/main/viewport.c index 91578ba9d..3aaab2d46 100644 --- a/mesalib/src/mesa/main/viewport.c +++ b/mesalib/src/mesa/main/viewport.c @@ -99,7 +99,7 @@ _mesa_set_viewport(struct gl_context *ctx, GLint x, GLint y, /* Many drivers will use this call to check for window size changes * and reallocate the z/stencil/accum/etc buffers if needed. */ - ctx->Driver.Viewport(ctx, x, y, width, height); + ctx->Driver.Viewport(ctx); } } @@ -143,7 +143,7 @@ _mesa_DepthRange(GLclampd nearval, GLclampd farval) #endif if (ctx->Driver.DepthRange) { - ctx->Driver.DepthRange(ctx, nearval, farval); + ctx->Driver.DepthRange(ctx); } } diff --git a/mesalib/src/mesa/program/ir_to_mesa.cpp b/mesalib/src/mesa/program/ir_to_mesa.cpp index beb0c093b..85d414259 100644 --- a/mesalib/src/mesa/program/ir_to_mesa.cpp +++ b/mesalib/src/mesa/program/ir_to_mesa.cpp @@ -665,8 +665,8 @@ ir_to_mesa_visitor::find_variable_storage(ir_variable *var) variable_storage *entry; - foreach_iter(exec_list_iterator, iter, this->variables) { - entry = (variable_storage *)iter.get(); + foreach_list(node, &this->variables) { + entry = (variable_storage *) node; if (entry->var == var) return entry; @@ -801,8 +801,8 @@ ir_to_mesa_visitor::visit(ir_function *ir) assert(sig); - foreach_iter(exec_list_iterator, iter, sig->body) { - ir_instruction *ir = (ir_instruction *)iter.get(); + foreach_list(node, &sig->body) { + ir_instruction *ir = (ir_instruction *) node; ir->accept(this); } @@ -1868,8 +1868,8 @@ ir_to_mesa_visitor::visit(ir_constant *ir) src_reg temp_base = get_temp(ir->type); dst_reg temp = dst_reg(temp_base); - foreach_iter(exec_list_iterator, iter, ir->components) { - ir_constant *field_value = (ir_constant *)iter.get(); + foreach_list(node, &ir->components) { + ir_constant *field_value = (ir_constant *) node; int size = type_size(field_value->type); assert(size > 0); @@ -2338,8 +2338,8 @@ set_branchtargets(ir_to_mesa_visitor *v, mesa_instructions[loop_stack[loop_stack_pos]].BranchTarget = i; break; case OPCODE_CAL: - foreach_iter(exec_list_iterator, iter, v->function_signatures) { - function_entry *entry = (function_entry *)iter.get(); + foreach_list(n, &v->function_signatures) { + function_entry *entry = (function_entry *) n; if (entry->sig_id == mesa_instructions[i].BranchTarget) { mesa_instructions[i].BranchTarget = entry->inst; @@ -2392,7 +2392,7 @@ 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, - gl_shader_type shader_type) + gl_shader_stage shader_type) : shader_program(shader_program), params(params), idx(-1), shader_type(shader_type) { @@ -2414,7 +2414,7 @@ private: struct gl_shader_program *shader_program; struct gl_program_parameter_list *params; int idx; - gl_shader_type shader_type; + gl_shader_stage shader_type; }; } /* anonymous namespace */ @@ -2493,8 +2493,7 @@ _mesa_generate_parameters_list_for_uniforms(struct gl_shader_program struct gl_program_parameter_list *params) { - add_uniform_to_shader add(shader_program, params, - _mesa_shader_type_to_index(sh->Type)); + add_uniform_to_shader add(shader_program, params, sh->Stage); foreach_list(node, sh->ir) { ir_variable *var = ((ir_instruction *) node)->as_variable(); @@ -2621,8 +2620,8 @@ ir_to_mesa_visitor::copy_propagate(void) int *acp_level = rzalloc_array(mem_ctx, int, this->next_temp * 4); int level = 0; - foreach_iter(exec_list_iterator, iter, this->instructions) { - ir_to_mesa_instruction *inst = (ir_to_mesa_instruction *)iter.get(); + foreach_list(node, &this->instructions) { + ir_to_mesa_instruction *inst = (ir_to_mesa_instruction *) node; assert(inst->dst.file != PROGRAM_TEMPORARY || inst->dst.index < this->next_temp); @@ -2800,25 +2799,10 @@ get_mesa_program(struct gl_context *ctx, ir_instruction **mesa_instruction_annotation; int i; struct gl_program *prog; - GLenum target; - const char *target_string = _mesa_shader_enum_to_string(shader->Type); + GLenum target = _mesa_shader_stage_to_program(shader->Stage); + const char *target_string = _mesa_shader_stage_to_string(shader->Stage); 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; - break; - case GL_FRAGMENT_SHADER: - target = GL_FRAGMENT_PROGRAM_ARB; - break; - case GL_GEOMETRY_SHADER: - target = GL_GEOMETRY_PROGRAM_NV; - break; - default: - assert(!"should not be reached"); - return NULL; - } + &ctx->ShaderCompilerOptions[shader->Stage]; validate_ir_tree(shader->ir); @@ -2841,7 +2825,7 @@ get_mesa_program(struct gl_context *ctx, prog->NumTemporaries = v.next_temp; int num_instructions = 0; - foreach_iter(exec_list_iterator, iter, v.instructions) { + foreach_list(node, &v.instructions) { num_instructions++; } @@ -2857,8 +2841,8 @@ get_mesa_program(struct gl_context *ctx, */ mesa_inst = mesa_instructions; i = 0; - foreach_iter(exec_list_iterator, iter, v.instructions) { - const ir_to_mesa_instruction *inst = (ir_to_mesa_instruction *)iter.get(); + foreach_list(node, &v.instructions) { + const ir_to_mesa_instruction *inst = (ir_to_mesa_instruction *) node; mesa_inst->Opcode = inst->op; mesa_inst->CondUpdate = inst->cond_update; @@ -2952,7 +2936,7 @@ get_mesa_program(struct gl_context *ctx, */ mesa_instructions = NULL; - do_set_program_inouts(shader->ir, prog, shader->Type); + do_set_program_inouts(shader->ir, prog, shader->Stage); prog->SamplersUsed = shader->active_samplers; prog->ShadowSamplers = shader->shadow_samplers; @@ -3000,14 +2984,14 @@ _mesa_ir_link_shader(struct gl_context *ctx, struct gl_shader_program *prog) { assert(prog->LinkStatus); - for (unsigned i = 0; i < MESA_SHADER_TYPES; i++) { + for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) { if (prog->_LinkedShaders[i] == NULL) continue; bool progress; exec_list *ir = prog->_LinkedShaders[i]->ir; const struct gl_shader_compiler_options *options = - &ctx->ShaderCompilerOptions[_mesa_shader_type_to_index(prog->_LinkedShaders[i]->Type)]; + &ctx->ShaderCompilerOptions[prog->_LinkedShaders[i]->Stage]; do { progress = false; @@ -3055,7 +3039,7 @@ _mesa_ir_link_shader(struct gl_context *ctx, struct gl_shader_program *prog) validate_ir_tree(ir); } - for (unsigned i = 0; i < MESA_SHADER_TYPES; i++) { + for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) { struct gl_program *linked_prog; if (prog->_LinkedShaders[i] == NULL) @@ -3064,7 +3048,7 @@ _mesa_ir_link_shader(struct gl_context *ctx, struct gl_shader_program *prog) linked_prog = get_mesa_program(ctx, prog, prog->_LinkedShaders[i]); if (linked_prog) { - _mesa_copy_linked_program_data((gl_shader_type) i, prog, linked_prog); + _mesa_copy_linked_program_data((gl_shader_stage) i, prog, linked_prog); _mesa_reference_program(ctx, &prog->_LinkedShaders[i]->Program, linked_prog); diff --git a/mesalib/src/mesa/program/prog_print.c b/mesalib/src/mesa/program/prog_print.c index fa120cc5e..9391e99ff 100644 --- a/mesalib/src/mesa/program/prog_print.c +++ b/mesalib/src/mesa/program/prog_print.c @@ -1005,16 +1005,21 @@ _mesa_print_parameter_list(const struct gl_program_parameter_list *list) void _mesa_write_shader_to_file(const struct gl_shader *shader) { - const char *type; + const char *type = "????"; char filename[100]; FILE *f; - if (shader->Type == GL_FRAGMENT_SHADER) + switch (shader->Stage) { + case MESA_SHADER_FRAGMENT: type = "frag"; - else if (shader->Type == GL_VERTEX_SHADER) + break; + case MESA_SHADER_VERTEX: type = "vert"; - else + break; + case MESA_SHADER_GEOMETRY: type = "geom"; + break; + } _mesa_snprintf(filename, sizeof(filename), "shader_%u.%s", shader->Name, type); f = fopen(filename, "w"); @@ -1061,7 +1066,7 @@ _mesa_append_uniforms_to_file(const struct gl_shader *shader) char filename[100]; FILE *f; - if (shader->Type == GL_FRAGMENT_SHADER) + if (shader->Stage == MESA_SHADER_FRAGMENT) type = "frag"; else type = "vert"; diff --git a/mesalib/src/mesa/program/program.c b/mesalib/src/mesa/program/program.c index cdf1c03fa..3c19e8c60 100644 --- a/mesalib/src/mesa/program/program.c +++ b/mesalib/src/mesa/program/program.c @@ -56,21 +56,21 @@ _mesa_init_program(struct gl_context *ctx) * If this assertion fails, we need to increase the field * size for register indexes (see INST_INDEX_BITS). */ - ASSERT(ctx->Const.VertexProgram.MaxUniformComponents / 4 + ASSERT(ctx->Const.Program[MESA_SHADER_VERTEX].MaxUniformComponents / 4 <= (1 << INST_INDEX_BITS)); - ASSERT(ctx->Const.FragmentProgram.MaxUniformComponents / 4 + ASSERT(ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxUniformComponents / 4 <= (1 << INST_INDEX_BITS)); - ASSERT(ctx->Const.VertexProgram.MaxTemps <= (1 << INST_INDEX_BITS)); - ASSERT(ctx->Const.VertexProgram.MaxLocalParams <= (1 << INST_INDEX_BITS)); - ASSERT(ctx->Const.FragmentProgram.MaxTemps <= (1 << INST_INDEX_BITS)); - ASSERT(ctx->Const.FragmentProgram.MaxLocalParams <= (1 << INST_INDEX_BITS)); + ASSERT(ctx->Const.Program[MESA_SHADER_VERTEX].MaxTemps <= (1 << INST_INDEX_BITS)); + ASSERT(ctx->Const.Program[MESA_SHADER_VERTEX].MaxLocalParams <= (1 << INST_INDEX_BITS)); + ASSERT(ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTemps <= (1 << INST_INDEX_BITS)); + ASSERT(ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxLocalParams <= (1 << INST_INDEX_BITS)); - ASSERT(ctx->Const.VertexProgram.MaxUniformComponents <= 4 * MAX_UNIFORMS); - ASSERT(ctx->Const.FragmentProgram.MaxUniformComponents <= 4 * MAX_UNIFORMS); + ASSERT(ctx->Const.Program[MESA_SHADER_VERTEX].MaxUniformComponents <= 4 * MAX_UNIFORMS); + ASSERT(ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxUniformComponents <= 4 * MAX_UNIFORMS); - ASSERT(ctx->Const.VertexProgram.MaxAddressOffset <= (1 << INST_INDEX_BITS)); - ASSERT(ctx->Const.FragmentProgram.MaxAddressOffset <= (1 << INST_INDEX_BITS)); + ASSERT(ctx->Const.Program[MESA_SHADER_VERTEX].MaxAddressOffset <= (1 << INST_INDEX_BITS)); + ASSERT(ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxAddressOffset <= (1 << INST_INDEX_BITS)); /* If this fails, increase prog_instruction::TexSrcUnit size */ STATIC_ASSERT(MAX_TEXTURE_UNITS <= (1 << 5)); @@ -891,26 +891,13 @@ _mesa_find_free_register(const GLboolean used[], */ GLboolean _mesa_valid_register_index(const struct gl_context *ctx, - gl_shader_type shaderType, + gl_shader_stage shaderType, gl_register_file file, GLint index) { const struct gl_program_constants *c; - switch (shaderType) { - case MESA_SHADER_VERTEX: - c = &ctx->Const.VertexProgram; - break; - case MESA_SHADER_FRAGMENT: - c = &ctx->Const.FragmentProgram; - break; - case MESA_SHADER_GEOMETRY: - c = &ctx->Const.GeometryProgram; - break; - default: - _mesa_problem(ctx, - "unexpected shader type in _mesa_valid_register_index()"); - return GL_FALSE; - } + assert(0 <= shaderType && shaderType < MESA_SHADER_STAGES); + c = &ctx->Const.Program[shaderType]; switch (file) { case PROGRAM_UNDEFINED: diff --git a/mesalib/src/mesa/program/program.h b/mesalib/src/mesa/program/program.h index baff47376..0e350cd6f 100644 --- a/mesalib/src/mesa/program/program.h +++ b/mesalib/src/mesa/program/program.h @@ -181,7 +181,7 @@ _mesa_find_free_register(const GLboolean used[], extern GLboolean _mesa_valid_register_index(const struct gl_context *ctx, - gl_shader_type shaderType, + gl_shader_stage shaderType, gl_register_file file, GLint index); extern void @@ -192,7 +192,7 @@ _mesa_get_min_invocations_per_fragment(struct gl_context *ctx, const struct gl_fragment_program *prog); static inline GLuint -_mesa_program_target_to_index(GLenum v) +_mesa_program_enum_to_shader_stage(GLenum v) { switch (v) { case GL_VERTEX_PROGRAM_ARB: @@ -207,6 +207,24 @@ _mesa_program_target_to_index(GLenum v) } } + +static inline GLenum +_mesa_shader_stage_to_program(gl_shader_stage stage) +{ + switch (stage) { + case MESA_SHADER_VERTEX: + return GL_VERTEX_PROGRAM_ARB; + case MESA_SHADER_FRAGMENT: + return GL_FRAGMENT_PROGRAM_ARB; + case MESA_SHADER_GEOMETRY: + return GL_GEOMETRY_PROGRAM_NV; + } + + assert(!"Unexpected shader stage in _mesa_shader_stage_to_program"); + return GL_VERTEX_PROGRAM_ARB; +} + + static inline GLenum _mesa_program_index_to_target(GLuint i) { @@ -215,8 +233,8 @@ _mesa_program_index_to_target(GLuint i) GL_GEOMETRY_PROGRAM_NV, GL_FRAGMENT_PROGRAM_ARB }; - STATIC_ASSERT(Elements(enums) == MESA_SHADER_TYPES); - if(i >= MESA_SHADER_TYPES) { + STATIC_ASSERT(Elements(enums) == MESA_SHADER_STAGES); + if(i >= MESA_SHADER_STAGES) { assert(!"Unexpected program index"); return 0; } else diff --git a/mesalib/src/mesa/program/program_parse.y b/mesalib/src/mesa/program/program_parse.y index a76db4e86..6dde69d53 100644 --- a/mesalib/src/mesa/program/program_parse.y +++ b/mesalib/src/mesa/program/program_parse.y @@ -2707,10 +2707,10 @@ _mesa_parse_arb_program(struct gl_context *ctx, GLenum target, const GLubyte *st state->st = _mesa_symbol_table_ctor(); state->limits = (target == GL_VERTEX_PROGRAM_ARB) - ? & ctx->Const.VertexProgram - : & ctx->Const.FragmentProgram; + ? & ctx->Const.Program[MESA_SHADER_VERTEX] + : & ctx->Const.Program[MESA_SHADER_FRAGMENT]; - state->MaxTextureImageUnits = ctx->Const.FragmentProgram.MaxTextureImageUnits; + state->MaxTextureImageUnits = ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits; state->MaxTextureCoordUnits = ctx->Const.MaxTextureCoordUnits; state->MaxTextureUnits = ctx->Const.MaxTextureUnits; state->MaxClipPlanes = ctx->Const.MaxClipPlanes; diff --git a/mesalib/src/mesa/program/sampler.cpp b/mesalib/src/mesa/program/sampler.cpp index 9b9412730..e6532be84 100644 --- a/mesalib/src/mesa/program/sampler.cpp +++ b/mesalib/src/mesa/program/sampler.cpp @@ -111,7 +111,7 @@ _mesa_get_sampler_uniform_value(class ir_dereference *sampler, { get_sampler_name getname(sampler, shader_program); - GLuint shader = _mesa_program_target_to_index(prog->Target); + GLuint shader = _mesa_program_enum_to_shader_stage(prog->Target); sampler->accept(&getname); diff --git a/mesalib/src/mesa/state_tracker/st_atom_framebuffer.c b/mesalib/src/mesa/state_tracker/st_atom_framebuffer.c index 51f079cda..a77fe54ae 100644 --- a/mesalib/src/mesa/state_tracker/st_atom_framebuffer.c +++ b/mesalib/src/mesa/state_tracker/st_atom_framebuffer.c @@ -65,12 +65,14 @@ update_framebuffer_state( struct st_context *st ) /* Examine Mesa's ctx->DrawBuffer->_ColorDrawBuffers state * to determine which surfaces to draw to */ - framebuffer->nr_cbufs = 0; + framebuffer->nr_cbufs = fb->_NumColorDrawBuffers; + for (i = 0; i < fb->_NumColorDrawBuffers; i++) { + pipe_surface_reference(&framebuffer->cbufs[i], NULL); + strb = st_renderbuffer(fb->_ColorDrawBuffers[i]); if (strb) { - /*printf("--------- framebuffer surface rtt %p\n", strb->rtt);*/ if (strb->is_rtt || (strb->texture && util_format_is_srgb(strb->texture->format))) { /* rendering to a GL texture, may have to update surface */ @@ -78,13 +80,12 @@ update_framebuffer_state( struct st_context *st ) } if (strb->surface) { - pipe_surface_reference(&framebuffer->cbufs[framebuffer->nr_cbufs], - strb->surface); - framebuffer->nr_cbufs++; + pipe_surface_reference(&framebuffer->cbufs[i], strb->surface); } strb->defined = GL_TRUE; /* we'll be drawing something */ } } + for (i = framebuffer->nr_cbufs; i < PIPE_MAX_COLOR_BUFS; i++) { pipe_surface_reference(&framebuffer->cbufs[i], NULL); } @@ -113,7 +114,8 @@ update_framebuffer_state( struct st_context *st ) #ifdef DEBUG /* Make sure the resource binding flags were set properly */ for (i = 0; i < framebuffer->nr_cbufs; i++) { - assert(framebuffer->cbufs[i]->texture->bind & PIPE_BIND_RENDER_TARGET); + assert(!framebuffer->cbufs[i] || + framebuffer->cbufs[i]->texture->bind & PIPE_BIND_RENDER_TARGET); } if (framebuffer->zsbuf) { assert(framebuffer->zsbuf->texture->bind & PIPE_BIND_DEPTH_STENCIL); diff --git a/mesalib/src/mesa/state_tracker/st_atom_msaa.c b/mesalib/src/mesa/state_tracker/st_atom_msaa.c index fb760460c..2f3a42e02 100644 --- a/mesalib/src/mesa/state_tracker/st_atom_msaa.c +++ b/mesalib/src/mesa/state_tracker/st_atom_msaa.c @@ -31,6 +31,7 @@ #include "st_atom.h" #include "cso_cache/cso_context.h" +#include "util/u_framebuffer.h" /* Second state atom for user clip planes: @@ -38,14 +39,9 @@ static void update_sample_mask( struct st_context *st ) { unsigned sample_mask = 0xffffffff; - unsigned sample_count = 1; struct pipe_framebuffer_state *framebuffer = &st->state.framebuffer; - /* dependency here on bound surface (or rather, sample count) is worrying */ - if (framebuffer->zsbuf) - sample_count = framebuffer->zsbuf->texture->nr_samples; - else if (framebuffer->cbufs[0]) - sample_count = framebuffer->cbufs[0]->texture->nr_samples; + unsigned sample_count = util_framebuffer_get_num_samples(framebuffer); if (st->ctx->Multisample.Enabled && sample_count > 1) { /* unlike in gallium/d3d10 the mask is only active if msaa is enabled */ diff --git a/mesalib/src/mesa/state_tracker/st_atom_sampler.c b/mesalib/src/mesa/state_tracker/st_atom_sampler.c index 57670ce25..cb5369bed 100644 --- a/mesalib/src/mesa/state_tracker/st_atom_sampler.c +++ b/mesalib/src/mesa/state_tracker/st_atom_sampler.c @@ -279,14 +279,14 @@ update_samplers(struct st_context *st) update_shader_samplers(st, PIPE_SHADER_FRAGMENT, &ctx->FragmentProgram._Current->Base, - ctx->Const.FragmentProgram.MaxTextureImageUnits, + ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits, st->state.samplers[PIPE_SHADER_FRAGMENT], &st->state.num_samplers[PIPE_SHADER_FRAGMENT]); update_shader_samplers(st, PIPE_SHADER_VERTEX, &ctx->VertexProgram._Current->Base, - ctx->Const.VertexProgram.MaxTextureImageUnits, + ctx->Const.Program[MESA_SHADER_VERTEX].MaxTextureImageUnits, st->state.samplers[PIPE_SHADER_VERTEX], &st->state.num_samplers[PIPE_SHADER_VERTEX]); @@ -294,7 +294,7 @@ update_samplers(struct st_context *st) update_shader_samplers(st, PIPE_SHADER_GEOMETRY, &ctx->GeometryProgram._Current->Base, - ctx->Const.GeometryProgram.MaxTextureImageUnits, + ctx->Const.Program[MESA_SHADER_GEOMETRY].MaxTextureImageUnits, st->state.samplers[PIPE_SHADER_GEOMETRY], &st->state.num_samplers[PIPE_SHADER_GEOMETRY]); } diff --git a/mesalib/src/mesa/state_tracker/st_atom_texture.c b/mesalib/src/mesa/state_tracker/st_atom_texture.c index bd0a22dde..7604202ba 100644 --- a/mesalib/src/mesa/state_tracker/st_atom_texture.c +++ b/mesalib/src/mesa/state_tracker/st_atom_texture.c @@ -326,11 +326,11 @@ update_vertex_textures(struct st_context *st) { const struct gl_context *ctx = st->ctx; - if (ctx->Const.VertexProgram.MaxTextureImageUnits > 0) { + if (ctx->Const.Program[MESA_SHADER_VERTEX].MaxTextureImageUnits > 0) { update_textures(st, PIPE_SHADER_VERTEX, &ctx->VertexProgram._Current->Base, - ctx->Const.VertexProgram.MaxTextureImageUnits, + ctx->Const.Program[MESA_SHADER_VERTEX].MaxTextureImageUnits, st->state.sampler_views[PIPE_SHADER_VERTEX], &st->state.num_sampler_views[PIPE_SHADER_VERTEX]); } @@ -345,7 +345,7 @@ update_fragment_textures(struct st_context *st) update_textures(st, PIPE_SHADER_FRAGMENT, &ctx->FragmentProgram._Current->Base, - ctx->Const.FragmentProgram.MaxTextureImageUnits, + ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits, st->state.sampler_views[PIPE_SHADER_FRAGMENT], &st->state.num_sampler_views[PIPE_SHADER_FRAGMENT]); } @@ -360,7 +360,7 @@ update_geometry_textures(struct st_context *st) update_textures(st, PIPE_SHADER_GEOMETRY, &ctx->GeometryProgram._Current->Base, - ctx->Const.FragmentProgram.MaxTextureImageUnits, + ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits, st->state.sampler_views[PIPE_SHADER_GEOMETRY], &st->state.num_sampler_views[PIPE_SHADER_GEOMETRY]); } diff --git a/mesalib/src/mesa/state_tracker/st_cb_blit.c b/mesalib/src/mesa/state_tracker/st_cb_blit.c index a236a08e9..82c2e38e5 100644 --- a/mesalib/src/mesa/state_tracker/st_cb_blit.c +++ b/mesalib/src/mesa/state_tracker/st_cb_blit.c @@ -44,6 +44,34 @@ static void +st_adjust_blit_for_msaa_resolve(struct pipe_blit_info *blit) +{ + /* Even though we do multisample resolves at the time of the blit, OpenGL + * specification defines them as if they happen at the time of rendering, + * which means that the type of averaging we do during the resolve should + * only depend on the source format; the destination format should be + * ignored. But, specification doesn't seem to be strict about it. + * + * It has been observed that mulitisample resolves produce slightly better + * looking images when averaging is done using destination format. NVIDIA's + * proprietary OpenGL driver also follows this approach. + * + * When multisampling, if the source and destination formats are equal + * (aside from the color space), we choose to blit in sRGB space to get + * this higher quality image. + */ + if (blit->src.resource->nr_samples > 1 && + blit->dst.resource->nr_samples <= 1) { + blit->dst.format = blit->dst.resource->format; + + if (util_format_is_srgb(blit->dst.resource->format)) + blit->src.format = util_format_srgb(blit->src.resource->format); + else + blit->src.format = util_format_linear(blit->src.resource->format); + } +} + +static void st_BlitFramebuffer(struct gl_context *ctx, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, @@ -192,6 +220,8 @@ st_BlitFramebuffer(struct gl_context *ctx, blit.src.box.z = srcAtt->Zoffset + srcAtt->CubeMapFace; blit.src.format = util_format_linear(srcObj->pt->format); + st_adjust_blit_for_msaa_resolve(&blit); + st->pipe->blit(st->pipe, &blit); } } @@ -227,6 +257,8 @@ st_BlitFramebuffer(struct gl_context *ctx, blit.src.box.z = srcSurf->u.tex.first_layer; blit.src.format = util_format_linear(srcSurf->format); + st_adjust_blit_for_msaa_resolve(&blit); + st->pipe->blit(st->pipe, &blit); } } diff --git a/mesalib/src/mesa/state_tracker/st_cb_clear.c b/mesalib/src/mesa/state_tracker/st_cb_clear.c index 887e58bd9..79124b3da 100644 --- a/mesalib/src/mesa/state_tracker/st_cb_clear.c +++ b/mesalib/src/mesa/state_tracker/st_cb_clear.c @@ -399,6 +399,19 @@ is_color_masked(struct gl_context *ctx, int i) /** + * Return if all of the stencil bits are masked. + */ +static INLINE GLboolean +is_stencil_disabled(struct gl_context *ctx, struct gl_renderbuffer *rb) +{ + const GLuint stencilMax = 0xff; + + assert(_mesa_get_format_bits(rb->Format, GL_STENCIL_BITS) > 0); + return (ctx->Stencil.WriteMask[0] & stencilMax) == 0; +} + + +/** * Return if any of the stencil bits are masked. */ static INLINE GLboolean @@ -431,9 +444,9 @@ st_Clear(struct gl_context *ctx, GLbitfield mask) if (mask & BUFFER_BITS_COLOR) { for (i = 0; i < ctx->DrawBuffer->_NumColorDrawBuffers; i++) { - GLuint b = ctx->DrawBuffer->_ColorDrawBufferIndexes[i]; + GLint b = ctx->DrawBuffer->_ColorDrawBufferIndexes[i]; - if (mask & (1 << b)) { + if (b >= 0 && mask & (1 << b)) { struct gl_renderbuffer *rb = ctx->DrawBuffer->Attachment[b].Renderbuffer; struct st_renderbuffer *strb = st_renderbuffer(rb); @@ -457,7 +470,7 @@ st_Clear(struct gl_context *ctx, GLbitfield mask) if (mask & BUFFER_BIT_DEPTH) { struct st_renderbuffer *strb = st_renderbuffer(depthRb); - if (strb->surface) { + if (strb->surface && ctx->Depth.Mask) { if (is_scissor_enabled(ctx, depthRb)) quad_buffers |= PIPE_CLEAR_DEPTH; else @@ -467,7 +480,7 @@ st_Clear(struct gl_context *ctx, GLbitfield mask) if (mask & BUFFER_BIT_STENCIL) { struct st_renderbuffer *strb = st_renderbuffer(stencilRb); - if (strb->surface) { + if (strb->surface && !is_stencil_disabled(ctx, stencilRb)) { if (is_scissor_enabled(ctx, stencilRb) || is_stencil_masked(ctx, stencilRb)) quad_buffers |= PIPE_CLEAR_STENCIL; @@ -476,14 +489,23 @@ st_Clear(struct gl_context *ctx, GLbitfield mask) } } - /* - * If we're going to use clear_with_quad() for any reason, use it for - * everything possible. + /* Always clear depth and stencil together. + * This can only happen when the stencil writemask is not a full mask. + */ + if (quad_buffers & PIPE_CLEAR_DEPTHSTENCIL && + clear_buffers & PIPE_CLEAR_DEPTHSTENCIL) { + quad_buffers |= clear_buffers & PIPE_CLEAR_DEPTHSTENCIL; + clear_buffers &= ~PIPE_CLEAR_DEPTHSTENCIL; + } + + /* Only use quad-based clearing for the renderbuffers which cannot + * use pipe->clear. We want to always use pipe->clear for the other + * renderbuffers, because it's likely to be faster. */ if (quad_buffers) { - quad_buffers |= clear_buffers; clear_with_quad(ctx, quad_buffers); - } else if (clear_buffers) { + } + if (clear_buffers) { /* We can't translate the clear color to the colorbuffer format, * because different colorbuffers may have different formats. */ diff --git a/mesalib/src/mesa/state_tracker/st_cb_fbo.c b/mesalib/src/mesa/state_tracker/st_cb_fbo.c index 70baa9965..daa94df92 100644 --- a/mesalib/src/mesa/state_tracker/st_cb_fbo.c +++ b/mesalib/src/mesa/state_tracker/st_cb_fbo.c @@ -680,7 +680,10 @@ st_DrawBuffers(struct gl_context *ctx, GLsizei count, const GLenum *buffers) /* add the renderbuffers on demand */ for (i = 0; i < fb->_NumColorDrawBuffers; i++) { gl_buffer_index idx = fb->_ColorDrawBufferIndexes[i]; - st_manager_add_color_renderbuffer(st, fb, idx); + + if (idx >= 0) { + st_manager_add_color_renderbuffer(st, fb, idx); + } } } diff --git a/mesalib/src/mesa/state_tracker/st_cb_viewport.c b/mesalib/src/mesa/state_tracker/st_cb_viewport.c index d654ed6e7..f0e97296f 100644 --- a/mesalib/src/mesa/state_tracker/st_cb_viewport.c +++ b/mesalib/src/mesa/state_tracker/st_cb_viewport.c @@ -48,8 +48,7 @@ st_ws_framebuffer(struct gl_framebuffer *fb) return NULL; } -static void st_viewport(struct gl_context * ctx, GLint x, GLint y, - GLsizei width, GLsizei height) +static void st_viewport(struct gl_context *ctx) { struct st_context *st = ctx->st; struct st_framebuffer *stdraw; diff --git a/mesalib/src/mesa/state_tracker/st_extensions.c b/mesalib/src/mesa/state_tracker/st_extensions.c index 5e4a3b398..c17601a90 100644 --- a/mesalib/src/mesa/state_tracker/st_extensions.c +++ b/mesalib/src/mesa/state_tracker/st_extensions.c @@ -155,15 +155,15 @@ void st_init_limits(struct st_context *st) switch (sh) { case PIPE_SHADER_FRAGMENT: - pc = &c->FragmentProgram; + pc = &c->Program[MESA_SHADER_FRAGMENT]; options = &st->ctx->ShaderCompilerOptions[MESA_SHADER_FRAGMENT]; break; case PIPE_SHADER_VERTEX: - pc = &c->VertexProgram; + pc = &c->Program[MESA_SHADER_VERTEX]; options = &st->ctx->ShaderCompilerOptions[MESA_SHADER_VERTEX]; break; case PIPE_SHADER_GEOMETRY: - pc = &c->GeometryProgram; + pc = &c->Program[MESA_SHADER_GEOMETRY]; options = &st->ctx->ShaderCompilerOptions[MESA_SHADER_GEOMETRY]; break; default: @@ -245,21 +245,21 @@ void st_init_limits(struct st_context *st) /* This depends on program constants. */ c->MaxTextureCoordUnits - = _min(c->FragmentProgram.MaxTextureImageUnits, MAX_TEXTURE_COORD_UNITS); + = _min(c->Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits, MAX_TEXTURE_COORD_UNITS); - c->MaxTextureUnits = _min(c->FragmentProgram.MaxTextureImageUnits, c->MaxTextureCoordUnits); + c->MaxTextureUnits = _min(c->Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits, c->MaxTextureCoordUnits); - c->VertexProgram.MaxAttribs = MIN2(c->VertexProgram.MaxAttribs, 16); + c->Program[MESA_SHADER_VERTEX].MaxAttribs = MIN2(c->Program[MESA_SHADER_VERTEX].MaxAttribs, 16); /* PIPE_SHADER_CAP_MAX_INPUTS for the FS specifies the maximum number * of inputs. It's always 2 colors + N generic inputs. */ c->MaxVarying = screen->get_shader_param(screen, PIPE_SHADER_FRAGMENT, PIPE_SHADER_CAP_MAX_INPUTS); c->MaxVarying = MIN2(c->MaxVarying, MAX_VARYING); - c->FragmentProgram.MaxInputComponents = c->MaxVarying * 4; - c->VertexProgram.MaxOutputComponents = c->MaxVarying * 4; - c->GeometryProgram.MaxInputComponents = c->MaxVarying * 4; - c->GeometryProgram.MaxOutputComponents = c->MaxVarying * 4; + c->Program[MESA_SHADER_FRAGMENT].MaxInputComponents = c->MaxVarying * 4; + c->Program[MESA_SHADER_VERTEX].MaxOutputComponents = c->MaxVarying * 4; + c->Program[MESA_SHADER_GEOMETRY].MaxInputComponents = c->MaxVarying * 4; + c->Program[MESA_SHADER_GEOMETRY].MaxOutputComponents = c->MaxVarying * 4; c->MinProgramTexelOffset = screen->get_param(screen, PIPE_CAP_MIN_TEXEL_OFFSET); c->MaxProgramTexelOffset = screen->get_param(screen, PIPE_CAP_MAX_TEXEL_OFFSET); @@ -284,9 +284,9 @@ void st_init_limits(struct st_context *st) c->UniformBufferOffsetAlignment = screen->get_param(screen, PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT); c->MaxCombinedUniformBlocks = c->MaxUniformBufferBindings = - c->VertexProgram.MaxUniformBlocks + - c->GeometryProgram.MaxUniformBlocks + - c->FragmentProgram.MaxUniformBlocks; + c->Program[MESA_SHADER_VERTEX].MaxUniformBlocks + + c->Program[MESA_SHADER_GEOMETRY].MaxUniformBlocks + + c->Program[MESA_SHADER_FRAGMENT].MaxUniformBlocks; assert(c->MaxCombinedUniformBlocks <= MAX_COMBINED_UNIFORM_BUFFERS); } } diff --git a/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp b/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp index eb12426a5..f1b354429 100644 --- a/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp +++ b/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp @@ -897,8 +897,8 @@ glsl_to_tgsi_visitor::add_constant(gl_register_file file, /* Search immediate storage to see if we already have an identical * immediate that we can use instead of adding a duplicate entry. */ - foreach_iter(exec_list_iterator, iter, this->immediates) { - entry = (immediate_storage *)iter.get(); + foreach_list(node, &this->immediates) { + entry = (immediate_storage *) node; if (entry->size == size && entry->type == datatype && @@ -1040,8 +1040,8 @@ glsl_to_tgsi_visitor::find_variable_storage(ir_variable *var) variable_storage *entry; - foreach_iter(exec_list_iterator, iter, this->variables) { - entry = (variable_storage *)iter.get(); + foreach_list(node, &this->variables) { + entry = (variable_storage *) node; if (entry->var == var) return entry; @@ -1179,8 +1179,8 @@ glsl_to_tgsi_visitor::visit(ir_function *ir) assert(sig); - foreach_iter(exec_list_iterator, iter, sig->body) { - ir_instruction *ir = (ir_instruction *)iter.get(); + foreach_list(node, &sig->body) { + ir_instruction *ir = (ir_instruction *) node; ir->accept(this); } @@ -2455,8 +2455,8 @@ glsl_to_tgsi_visitor::visit(ir_constant *ir) st_src_reg temp_base = get_temp(ir->type); st_dst_reg temp = st_dst_reg(temp_base); - foreach_iter(exec_list_iterator, iter, ir->components) { - ir_constant *field_value = (ir_constant *)iter.get(); + foreach_list(node, &ir->components) { + ir_constant *field_value = (ir_constant *) node; int size = type_size(field_value->type); assert(size > 0); @@ -2572,8 +2572,8 @@ glsl_to_tgsi_visitor::get_function_signature(ir_function_signature *sig) { function_entry *entry; - foreach_iter(exec_list_iterator, iter, this->function_signatures) { - entry = (function_entry *)iter.get(); + foreach_list(node, &this->function_signatures) { + entry = (function_entry *) node; if (entry->sig == sig) return entry; @@ -2585,8 +2585,8 @@ glsl_to_tgsi_visitor::get_function_signature(ir_function_signature *sig) entry->bgn_inst = NULL; /* Allocate storage for all the parameters. */ - foreach_iter(exec_list_iterator, iter, sig->parameters) { - ir_variable *param = (ir_variable *)iter.get(); + foreach_list(node, &sig->parameters) { + ir_variable *param = (ir_variable *) node; variable_storage *storage; storage = find_variable_storage(param); @@ -2617,10 +2617,10 @@ glsl_to_tgsi_visitor::visit(ir_call *ir) int i; /* Process in parameters. */ - exec_list_iterator sig_iter = sig->parameters.iterator(); - foreach_iter(exec_list_iterator, iter, *ir) { - ir_rvalue *param_rval = (ir_rvalue *)iter.get(); - ir_variable *param = (ir_variable *)sig_iter.get(); + foreach_two_lists(formal_node, &sig->parameters, + actual_node, &ir->actual_parameters) { + ir_rvalue *param_rval = (ir_rvalue *) actual_node; + ir_variable *param = (ir_variable *) formal_node; if (param->data.mode == ir_var_function_in || param->data.mode == ir_var_function_inout) { @@ -2643,20 +2643,17 @@ glsl_to_tgsi_visitor::visit(ir_call *ir) r.index++; } } - - sig_iter.next(); } - assert(!sig_iter.has_next()); /* Emit call instruction */ call_inst = emit(ir, TGSI_OPCODE_CAL); call_inst->function = entry; /* Process out parameters. */ - sig_iter = sig->parameters.iterator(); - foreach_iter(exec_list_iterator, iter, *ir) { - ir_rvalue *param_rval = (ir_rvalue *)iter.get(); - ir_variable *param = (ir_variable *)sig_iter.get(); + foreach_two_lists(formal_node, &sig->parameters, + actual_node, &ir->actual_parameters) { + ir_rvalue *param_rval = (ir_rvalue *) actual_node; + ir_variable *param = (ir_variable *) formal_node; if (param->data.mode == ir_var_function_out || param->data.mode == ir_var_function_inout) { @@ -2679,10 +2676,7 @@ glsl_to_tgsi_visitor::visit(ir_call *ir) r.index++; } } - - sig_iter.next(); } - assert(!sig_iter.has_next()); /* Process return value. */ this->result = entry->return_reg; @@ -3070,8 +3064,8 @@ count_resources(glsl_to_tgsi_visitor *v, gl_program *prog) { v->samplers_used = 0; - foreach_iter(exec_list_iterator, iter, v->instructions) { - glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *)iter.get(); + foreach_list(node, &v->instructions) { + glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *) node; if (is_tex_instruction(inst->op)) { v->samplers_used |= 1 << inst->sampler; @@ -3216,8 +3210,8 @@ glsl_to_tgsi_visitor::simplify_cmp(void) memset(tempWrites, 0, sizeof(unsigned) * MAX_TEMPS); memset(outputWrites, 0, sizeof(outputWrites)); - foreach_iter(exec_list_iterator, iter, this->instructions) { - glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *)iter.get(); + foreach_list(node, &this->instructions) { + glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *) node; unsigned prevWriteMask = 0; /* Give up if we encounter relative addressing or flow control. */ @@ -3262,8 +3256,8 @@ glsl_to_tgsi_visitor::simplify_cmp(void) void glsl_to_tgsi_visitor::rename_temp_register(int index, int new_index) { - foreach_iter(exec_list_iterator, iter, this->instructions) { - glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *)iter.get(); + foreach_list(node, &this->instructions) { + glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *) node; unsigned j; for (j=0; j < num_inst_src_regs(inst->op); j++) { @@ -3286,8 +3280,8 @@ glsl_to_tgsi_visitor::get_first_temp_read(int index) int loop_start = -1; /* index of the first active BGNLOOP (if any) */ unsigned i = 0, j; - foreach_iter(exec_list_iterator, iter, this->instructions) { - glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *)iter.get(); + foreach_list(node, &this->instructions) { + glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *) node; for (j=0; j < num_inst_src_regs(inst->op); j++) { if (inst->src[j].file == PROGRAM_TEMPORARY && @@ -3318,8 +3312,8 @@ glsl_to_tgsi_visitor::get_first_temp_write(int index) int loop_start = -1; /* index of the first active BGNLOOP (if any) */ int i = 0; - foreach_iter(exec_list_iterator, iter, this->instructions) { - glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *)iter.get(); + foreach_list(node, &this->instructions) { + glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *) node; if (inst->dst.file == PROGRAM_TEMPORARY && inst->dst.index == index) { return (depth == 0) ? i : loop_start; @@ -3347,8 +3341,8 @@ glsl_to_tgsi_visitor::get_last_temp_read(int index) int last = -1; /* index of last instruction that reads the temporary */ unsigned i = 0, j; - foreach_iter(exec_list_iterator, iter, this->instructions) { - glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *)iter.get(); + foreach_list(node, &this->instructions) { + glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *) node; for (j=0; j < num_inst_src_regs(inst->op); j++) { if (inst->src[j].file == PROGRAM_TEMPORARY && @@ -3378,8 +3372,8 @@ glsl_to_tgsi_visitor::get_last_temp_write(int index) int last = -1; /* index of last instruction that writes to the temporary */ int i = 0; - foreach_iter(exec_list_iterator, iter, this->instructions) { - glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *)iter.get(); + foreach_list(node, &this->instructions) { + glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *) node; if (inst->dst.file == PROGRAM_TEMPORARY && inst->dst.index == index) last = (depth == 0) ? i : -2; @@ -3427,8 +3421,8 @@ glsl_to_tgsi_visitor::copy_propagate(void) int *acp_level = rzalloc_array(mem_ctx, int, this->next_temp * 4); int level = 0; - foreach_iter(exec_list_iterator, iter, this->instructions) { - glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *)iter.get(); + foreach_list(node, &this->instructions) { + glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *) node; assert(inst->dst.file != PROGRAM_TEMPORARY || inst->dst.index < this->next_temp); @@ -3624,13 +3618,13 @@ glsl_to_tgsi_visitor::eliminate_dead_code(void) int last_read = get_last_temp_read(i); int j = 0; - foreach_iter(exec_list_iterator, iter, this->instructions) { - glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *)iter.get(); + foreach_list_safe(node, &this->instructions) { + glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *) node; if (inst->dst.file == PROGRAM_TEMPORARY && inst->dst.index == i && j > last_read) { - iter.remove(); + inst->remove(); delete inst; } @@ -3661,8 +3655,8 @@ glsl_to_tgsi_visitor::eliminate_dead_code_advanced(void) int level = 0; int removed = 0; - foreach_iter(exec_list_iterator, iter, this->instructions) { - glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *)iter.get(); + foreach_list(node, &this->instructions) { + glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *) node; assert(inst->dst.file != PROGRAM_TEMPORARY || inst->dst.index < this->next_temp); @@ -3769,13 +3763,13 @@ glsl_to_tgsi_visitor::eliminate_dead_code_advanced(void) /* Now actually remove the instructions that are completely dead and update * the writemask of other instructions with dead channels. */ - foreach_iter(exec_list_iterator, iter, this->instructions) { - glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *)iter.get(); + foreach_list_safe(node, &this->instructions) { + glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *) node; if (!inst->dead_mask || !inst->dst.writemask) continue; else if ((inst->dst.writemask & ~inst->dead_mask) == 0) { - iter.remove(); + inst->remove(); delete inst; removed++; } else @@ -3956,8 +3950,8 @@ get_pixel_transfer_visitor(struct st_fragment_program *fp, /* Now copy the instructions from the original glsl_to_tgsi_visitor into the * new visitor. */ - foreach_iter(exec_list_iterator, iter, original->instructions) { - glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *)iter.get(); + foreach_list(node, &original->instructions) { + glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *) node; glsl_to_tgsi_instruction *newinst; st_src_reg src_regs[3]; @@ -4040,8 +4034,8 @@ get_bitmap_visitor(struct st_fragment_program *fp, /* Now copy the instructions from the original glsl_to_tgsi_visitor into the * new visitor. */ - foreach_iter(exec_list_iterator, iter, original->instructions) { - glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *)iter.get(); + foreach_list(node, &original->instructions) { + glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *) node; glsl_to_tgsi_instruction *newinst; st_src_reg src_regs[3]; @@ -4962,15 +4956,15 @@ st_translate_program( goto out; } i = 0; - foreach_iter(exec_list_iterator, iter, program->immediates) { - immediate_storage *imm = (immediate_storage *)iter.get(); + foreach_list(node, &program->immediates) { + immediate_storage *imm = (immediate_storage *) node; assert(i < program->num_immediates); t->immediates[i++] = emit_immediate(t, imm->values, imm->type, imm->size); } assert(i == program->num_immediates); /* texture samplers */ - for (i = 0; i < ctx->Const.FragmentProgram.MaxTextureImageUnits; i++) { + for (i = 0; i < ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits; i++) { if (program->samplers_used & (1 << i)) { t->samplers[i] = ureg_DECL_sampler(ureg, i); } @@ -4978,10 +4972,9 @@ st_translate_program( /* Emit each instruction in turn: */ - foreach_iter(exec_list_iterator, iter, program->instructions) { + foreach_list(n, &program->instructions) { set_insn_start(t, ureg_get_instruction_number(ureg)); - compile_tgsi_instruction(t, (glsl_to_tgsi_instruction *)iter.get(), - clamp_color); + compile_tgsi_instruction(t, (glsl_to_tgsi_instruction *) n, clamp_color); } /* Fix up all emitted labels: @@ -4996,7 +4989,7 @@ st_translate_program( * prog->ParameterValues to get reallocated (e.g., anything that adds a * program constant) has to happen before creating this linkage. */ - for (unsigned i = 0; i < MESA_SHADER_TYPES; i++) { + for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) { if (program->shader_program->_LinkedShaders[i] == NULL) continue; @@ -5023,6 +5016,24 @@ out: } /* ----------------------------- End TGSI code ------------------------------ */ + +static unsigned +shader_stage_to_ptarget(gl_shader_stage stage) +{ + switch (stage) { + case MESA_SHADER_VERTEX: + return PIPE_SHADER_VERTEX; + case MESA_SHADER_FRAGMENT: + return PIPE_SHADER_FRAGMENT; + case MESA_SHADER_GEOMETRY: + return PIPE_SHADER_GEOMETRY; + } + + assert(!"should not be reached"); + return PIPE_SHADER_VERTEX; +} + + /** * Convert a shader's GLSL IR into a Mesa gl_program, although without * generating Mesa IR. @@ -5034,30 +5045,12 @@ get_mesa_program(struct gl_context *ctx, { glsl_to_tgsi_visitor* v; struct gl_program *prog; - GLenum target; + GLenum target = _mesa_shader_stage_to_program(shader->Stage); bool progress; struct gl_shader_compiler_options *options = - &ctx->ShaderCompilerOptions[_mesa_shader_type_to_index(shader->Type)]; + &ctx->ShaderCompilerOptions[_mesa_shader_enum_to_shader_stage(shader->Type)]; struct pipe_screen *pscreen = ctx->st->pipe->screen; - unsigned ptarget; - - switch (shader->Type) { - case GL_VERTEX_SHADER: - target = GL_VERTEX_PROGRAM_ARB; - ptarget = PIPE_SHADER_VERTEX; - break; - case GL_FRAGMENT_SHADER: - target = GL_FRAGMENT_PROGRAM_ARB; - ptarget = PIPE_SHADER_FRAGMENT; - break; - case GL_GEOMETRY_SHADER: - target = GL_GEOMETRY_PROGRAM_NV; - ptarget = PIPE_SHADER_GEOMETRY; - break; - default: - assert(!"should not be reached"); - return NULL; - } + unsigned ptarget = shader_stage_to_ptarget(shader->Stage); validate_ir_tree(shader->ir); @@ -5089,8 +5082,8 @@ get_mesa_program(struct gl_context *ctx, do { progress = GL_FALSE; - foreach_iter(exec_list_iterator, iter, v->function_signatures) { - function_entry *entry = (function_entry *)iter.get(); + foreach_list(node, &v->function_signatures) { + function_entry *entry = (function_entry *) node; if (!entry->bgn_inst) { v->current_function = entry; @@ -5143,7 +5136,7 @@ get_mesa_program(struct gl_context *ctx, if (ctx->Shader.Flags & GLSL_DUMP) { printf("\n"); printf("GLSL IR for linked %s program %d:\n", - _mesa_shader_enum_to_string(shader->Type), + _mesa_shader_stage_to_string(shader->Stage), shader_program->Name); _mesa_print_ir(shader->ir, NULL); printf("\n"); @@ -5154,7 +5147,7 @@ get_mesa_program(struct gl_context *ctx, prog->Instructions = NULL; prog->NumInstructions = 0; - do_set_program_inouts(shader->ir, prog, shader->Type); + do_set_program_inouts(shader->ir, prog, shader->Stage); count_resources(v, prog); _mesa_reference_program(ctx, &shader->Program, prog); @@ -5207,6 +5200,7 @@ st_new_shader(struct gl_context *ctx, GLuint name, GLuint type) shader = rzalloc(NULL, struct gl_shader); if (shader) { shader->Type = type; + shader->Stage = _mesa_shader_enum_to_shader_stage(type); shader->Name = name; _mesa_init_shader(ctx, shader); } @@ -5236,14 +5230,14 @@ st_link_shader(struct gl_context *ctx, struct gl_shader_program *prog) { assert(prog->LinkStatus); - for (unsigned i = 0; i < MESA_SHADER_TYPES; i++) { + for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) { if (prog->_LinkedShaders[i] == NULL) continue; bool progress; exec_list *ir = prog->_LinkedShaders[i]->ir; const struct gl_shader_compiler_options *options = - &ctx->ShaderCompilerOptions[_mesa_shader_type_to_index(prog->_LinkedShaders[i]->Type)]; + &ctx->ShaderCompilerOptions[_mesa_shader_enum_to_shader_stage(prog->_LinkedShaders[i]->Type)]; /* If there are forms of indirect addressing that the driver * cannot handle, perform the lowering pass. @@ -5306,7 +5300,7 @@ st_link_shader(struct gl_context *ctx, struct gl_shader_program *prog) validate_ir_tree(ir); } - for (unsigned i = 0; i < MESA_SHADER_TYPES; i++) { + for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) { struct gl_program *linked_prog; if (prog->_LinkedShaders[i] == NULL) diff --git a/mesalib/src/mesa/state_tracker/st_mesa_to_tgsi.c b/mesalib/src/mesa/state_tracker/st_mesa_to_tgsi.c index 1c2abc122..aa9ec1359 100644 --- a/mesalib/src/mesa/state_tracker/st_mesa_to_tgsi.c +++ b/mesalib/src/mesa/state_tracker/st_mesa_to_tgsi.c @@ -1225,7 +1225,7 @@ st_translate_mesa_program( } /* texture samplers */ - for (i = 0; i < ctx->Const.FragmentProgram.MaxTextureImageUnits; i++) { + for (i = 0; i < ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits; i++) { if (program->SamplersUsed & (1 << i)) { t->samplers[i] = ureg_DECL_sampler( ureg, i ); } diff --git a/mesalib/src/mesa/swrast/s_context.c b/mesalib/src/mesa/swrast/s_context.c index 8934088df..fdf9b370a 100644 --- a/mesalib/src/mesa/swrast/s_context.c +++ b/mesalib/src/mesa/swrast/s_context.c @@ -794,9 +794,9 @@ _swrast_CreateContext( struct gl_context *ctx ) swrast->PointSpan.facing = 0; swrast->PointSpan.array = swrast->SpanArrays; - init_program_native_limits(&ctx->Const.VertexProgram); - init_program_native_limits(&ctx->Const.GeometryProgram); - init_program_native_limits(&ctx->Const.FragmentProgram); + init_program_native_limits(&ctx->Const.Program[MESA_SHADER_VERTEX]); + init_program_native_limits(&ctx->Const.Program[MESA_SHADER_GEOMETRY]); + init_program_native_limits(&ctx->Const.Program[MESA_SHADER_FRAGMENT]); ctx->swrast_context = swrast; diff --git a/mesalib/src/mesa/swrast/s_texcombine.c b/mesalib/src/mesa/swrast/s_texcombine.c index 7e07f4f8a..32d7c0944 100644 --- a/mesalib/src/mesa/swrast/s_texcombine.c +++ b/mesalib/src/mesa/swrast/s_texcombine.c @@ -602,6 +602,14 @@ _swrast_texture_span( struct gl_context *ctx, SWspan *span ) if (!swrast->TexelBuffer) { #ifdef _OPENMP const GLint maxThreads = omp_get_max_threads(); + + /* TexelBuffer memory allocation needs to be done in a critical section + * as this code runs in a parallel loop. + * When entering the section, first check if TexelBuffer has been + * initialized already by another thread while this thread was waiting. + */ + #pragma omp critical + if (!swrast->TexelBuffer) { #else const GLint maxThreads = 1; #endif @@ -611,8 +619,12 @@ _swrast_texture_span( struct gl_context *ctx, SWspan *span ) * thread. */ swrast->TexelBuffer = - malloc(ctx->Const.FragmentProgram.MaxTextureImageUnits * maxThreads * + malloc(ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits * maxThreads * SWRAST_MAX_WIDTH * 4 * sizeof(GLfloat)); +#ifdef _OPENMP + } /* critical section */ +#endif + if (!swrast->TexelBuffer) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "texture_combine"); return; diff --git a/mesalib/src/mesa/swrast/s_texfetch.c b/mesalib/src/mesa/swrast/s_texfetch.c index 0196aede1..b886e6586 100644 --- a/mesalib/src/mesa/swrast/s_texfetch.c +++ b/mesalib/src/mesa/swrast/s_texfetch.c @@ -1286,6 +1286,24 @@ texfetch_funcs[] = NULL, NULL }, + { + MESA_FORMAT_ABGR2101010, + NULL, + NULL, + NULL + }, + { + MESA_FORMAT_SIGNED_RG88, + NULL, + NULL, + NULL + }, + { + MESA_FORMAT_SIGNED_RG1616, + NULL, + NULL, + NULL + }, }; diff --git a/mesalib/src/mesa/tnl/t_vb_program.c b/mesalib/src/mesa/tnl/t_vb_program.c index e43d5d9eb..d08abe7c2 100644 --- a/mesalib/src/mesa/tnl/t_vb_program.c +++ b/mesalib/src/mesa/tnl/t_vb_program.c @@ -259,7 +259,7 @@ map_textures(struct gl_context *ctx, const struct gl_vertex_program *vp) { GLuint u; - for (u = 0; u < ctx->Const.VertexProgram.MaxTextureImageUnits; u++) { + for (u = 0; u < ctx->Const.Program[MESA_SHADER_VERTEX].MaxTextureImageUnits; u++) { if (vp->Base.TexturesUsed[u]) { /* Note: _Current *should* correspond to the target indicated * in TexturesUsed[u]. @@ -278,7 +278,7 @@ unmap_textures(struct gl_context *ctx, const struct gl_vertex_program *vp) { GLuint u; - for (u = 0; u < ctx->Const.VertexProgram.MaxTextureImageUnits; u++) { + for (u = 0; u < ctx->Const.Program[MESA_SHADER_VERTEX].MaxTextureImageUnits; u++) { if (vp->Base.TexturesUsed[u]) { /* Note: _Current *should* correspond to the target indicated * in TexturesUsed[u]. |