diff options
25 files changed, 870 insertions, 762 deletions
diff --git a/mesalib/configure.ac b/mesalib/configure.ac index 1353c28c9..e859d4cc6 100644 --- a/mesalib/configure.ac +++ b/mesalib/configure.ac @@ -18,6 +18,10 @@ AC_CONFIG_AUX_DIR([bin]) AC_CANONICAL_HOST AM_INIT_AUTOMAKE([foreign]) +dnl http://people.gnome.org/~walters/docs/build-api.txt +dnl We don't support srcdir != builddir. +echo \#buildapi-variable-no-builddir >/dev/null + # Support silent build rules, requires at least automake-1.11. Disable # by either passing --disable-silent-rules to configure or passing V=1 # to make @@ -1411,8 +1415,10 @@ if test "x$enable_egl" = xyes; then EGL_DRIVER_DRI2=dri2 DEFINES="$DEFINES -DHAVE_XCB_DRI2" # workaround a bug in xcb-dri2 generated by xcb-proto 1.6 + save_LIBS="$LIBS" AC_CHECK_LIB(xcb-dri2, xcb_dri2_connect_alignment_pad, [], [DEFINES="$DEFINES -DXCB_DRI2_CONNECT_DEVICE_NAME_BROKEN"]) + LIBS="$save_LIBS" fi fi diff --git a/mesalib/src/glsl/ast_to_hir.cpp b/mesalib/src/glsl/ast_to_hir.cpp index cde7052b0..c580359fd 100644 --- a/mesalib/src/glsl/ast_to_hir.cpp +++ b/mesalib/src/glsl/ast_to_hir.cpp @@ -54,6 +54,7 @@ #include "glsl_parser_extras.h" #include "ast.h" #include "glsl_types.h" +#include "program/hash_table.h" #include "ir.h" void @@ -3405,7 +3406,7 @@ ast_jump_statement::hir(exec_list *instructions, "continue may only appear in a loop"); } else if (mode == ast_break && state->loop_nesting_ast == NULL && - state->switch_nesting_ast == NULL) { + state->switch_state.switch_nesting_ast == NULL) { YYLTYPE loc = this->get_location(); _mesa_glsl_error(& loc, state, @@ -3423,11 +3424,11 @@ ast_jump_statement::hir(exec_list *instructions, state); } - if (state->is_switch_innermost && + if (state->switch_state.is_switch_innermost && mode == ast_break) { /* Force break out of switch by setting is_break switch state. */ - ir_variable *const is_break_var = state->is_break_var; + ir_variable *const is_break_var = state->switch_state.is_break_var; ir_dereference_variable *const deref_is_break_var = new(ctx) ir_dereference_variable(is_break_var); ir_constant *const true_val = new(ctx) ir_constant(true); @@ -3530,25 +3531,25 @@ ast_switch_statement::hir(exec_list *instructions, /* Track the switch-statement nesting in a stack-like manner. */ - ir_variable *saved_test_var = state->test_var; - ir_variable *saved_is_fallthru_var = state->is_fallthru_var; - - bool save_is_switch_innermost = state->is_switch_innermost; - ast_switch_statement *saved_nesting_ast = state->switch_nesting_ast; + struct glsl_switch_state saved = state->switch_state; - state->is_switch_innermost = true; - state->switch_nesting_ast = this; + state->switch_state.is_switch_innermost = true; + state->switch_state.switch_nesting_ast = this; + state->switch_state.labels_ht = hash_table_ctor(0, hash_table_pointer_hash, + hash_table_pointer_compare); + state->switch_state.previous_default = NULL; /* Initalize is_fallthru state to false. */ ir_rvalue *const is_fallthru_val = new (ctx) ir_constant(false); - state->is_fallthru_var = new(ctx) ir_variable(glsl_type::bool_type, - "switch_is_fallthru_tmp", - ir_var_temporary); - instructions->push_tail(state->is_fallthru_var); + state->switch_state.is_fallthru_var = + new(ctx) ir_variable(glsl_type::bool_type, + "switch_is_fallthru_tmp", + ir_var_temporary); + instructions->push_tail(state->switch_state.is_fallthru_var); ir_dereference_variable *deref_is_fallthru_var = - new(ctx) ir_dereference_variable(state->is_fallthru_var); + new(ctx) ir_dereference_variable(state->switch_state.is_fallthru_var); instructions->push_tail(new(ctx) ir_assignment(deref_is_fallthru_var, is_fallthru_val, NULL)); @@ -3556,13 +3557,13 @@ ast_switch_statement::hir(exec_list *instructions, /* Initalize is_break state to false. */ ir_rvalue *const is_break_val = new (ctx) ir_constant(false); - state->is_break_var = new(ctx) ir_variable(glsl_type::bool_type, - "switch_is_break_tmp", - ir_var_temporary); - instructions->push_tail(state->is_break_var); + state->switch_state.is_break_var = new(ctx) ir_variable(glsl_type::bool_type, + "switch_is_break_tmp", + ir_var_temporary); + instructions->push_tail(state->switch_state.is_break_var); ir_dereference_variable *deref_is_break_var = - new(ctx) ir_dereference_variable(state->is_break_var); + new(ctx) ir_dereference_variable(state->switch_state.is_break_var); instructions->push_tail(new(ctx) ir_assignment(deref_is_break_var, is_break_val, NULL)); @@ -3575,254 +3576,294 @@ ast_switch_statement::hir(exec_list *instructions, */ body->hir(instructions, state); - /* Restore previous nesting before returning. - */ - state->switch_nesting_ast = saved_nesting_ast; - state->is_switch_innermost = save_is_switch_innermost; + hash_table_dtor(state->switch_state.labels_ht); - state->test_var = saved_test_var; - state->is_fallthru_var = saved_is_fallthru_var; + state->switch_state = saved; - /* Switch statements do not have r-values. - */ - return NULL; -} + /* Switch statements do not have r-values. + */ + return NULL; + } -void -ast_switch_statement::test_to_hir(exec_list *instructions, - struct _mesa_glsl_parse_state *state) -{ - void *ctx = state; - - /* Cache value of test expression. - */ - ir_rvalue *const test_val = - test_expression->hir(instructions, - state); + void + ast_switch_statement::test_to_hir(exec_list *instructions, + struct _mesa_glsl_parse_state *state) + { + void *ctx = state; - state->test_var = new(ctx) ir_variable(glsl_type::int_type, - "switch_test_tmp", - ir_var_temporary); - ir_dereference_variable *deref_test_var = - new(ctx) ir_dereference_variable(state->test_var); + /* Cache value of test expression. + */ + ir_rvalue *const test_val = + test_expression->hir(instructions, + state); - instructions->push_tail(state->test_var); - instructions->push_tail(new(ctx) ir_assignment(deref_test_var, - test_val, - NULL)); -} + state->switch_state.test_var = new(ctx) ir_variable(glsl_type::int_type, + "switch_test_tmp", + ir_var_temporary); + ir_dereference_variable *deref_test_var = + new(ctx) ir_dereference_variable(state->switch_state.test_var); + instructions->push_tail(state->switch_state.test_var); + instructions->push_tail(new(ctx) ir_assignment(deref_test_var, + test_val, + NULL)); + } -ir_rvalue * -ast_switch_body::hir(exec_list *instructions, - struct _mesa_glsl_parse_state *state) -{ - if (stmts != NULL) - stmts->hir(instructions, state); - - /* Switch bodies do not have r-values. - */ - return NULL; -} + ir_rvalue * + ast_switch_body::hir(exec_list *instructions, + struct _mesa_glsl_parse_state *state) + { + if (stmts != NULL) + stmts->hir(instructions, state); -ir_rvalue * -ast_case_statement_list::hir(exec_list *instructions, - struct _mesa_glsl_parse_state *state) -{ - foreach_list_typed (ast_case_statement, case_stmt, link, & this->cases) - case_stmt->hir(instructions, state); - - /* Case statements do not have r-values. - */ - return NULL; -} + /* Switch bodies do not have r-values. + */ + return NULL; + } -ir_rvalue * -ast_case_statement::hir(exec_list *instructions, - struct _mesa_glsl_parse_state *state) -{ - labels->hir(instructions, state); - - /* Conditionally set fallthru state based on break state. - */ - ir_constant *const false_val = new(state) ir_constant(false); - ir_dereference_variable *const deref_is_fallthru_var = - new(state) ir_dereference_variable(state->is_fallthru_var); - ir_dereference_variable *const deref_is_break_var = - new(state) ir_dereference_variable(state->is_break_var); - ir_assignment *const reset_fallthru_on_break = - new(state) ir_assignment(deref_is_fallthru_var, - false_val, - deref_is_break_var); - instructions->push_tail(reset_fallthru_on_break); - - /* Guard case statements depending on fallthru state. - */ - ir_dereference_variable *const deref_fallthru_guard = - new(state) ir_dereference_variable(state->is_fallthru_var); - ir_if *const test_fallthru = new(state) ir_if(deref_fallthru_guard); - - foreach_list_typed (ast_node, stmt, link, & this->stmts) - stmt->hir(& test_fallthru->then_instructions, state); - - instructions->push_tail(test_fallthru); - - /* Case statements do not have r-values. - */ - return NULL; -} - - -ir_rvalue * -ast_case_label_list::hir(exec_list *instructions, - struct _mesa_glsl_parse_state *state) -{ - foreach_list_typed (ast_case_label, label, link, & this->labels) - label->hir(instructions, state); - - /* Case labels do not have r-values. - */ - return NULL; -} - - -ir_rvalue * -ast_case_label::hir(exec_list *instructions, - struct _mesa_glsl_parse_state *state) -{ - void *ctx = state; - - ir_dereference_variable *deref_fallthru_var = - new(ctx) ir_dereference_variable(state->is_fallthru_var); - - ir_rvalue *const true_val = new(ctx) ir_constant(true); - - /* If not default case, ... - */ - if (this->test_value != NULL) { - /* Conditionally set fallthru state based on - * comparison of cached test expression value to case label. - */ - ir_rvalue *const test_val = this->test_value->hir(instructions, state); + ir_rvalue * + ast_case_statement_list::hir(exec_list *instructions, + struct _mesa_glsl_parse_state *state) + { + foreach_list_typed (ast_case_statement, case_stmt, link, & this->cases) + case_stmt->hir(instructions, state); - ir_dereference_variable *deref_test_var = - new(ctx) ir_dereference_variable(state->test_var); + /* Case statements do not have r-values. + */ + return NULL; + } - ir_rvalue *const test_cond = new(ctx) ir_expression(ir_binop_all_equal, - glsl_type::bool_type, - test_val, - deref_test_var); - ir_assignment *set_fallthru_on_test = - new(ctx) ir_assignment(deref_fallthru_var, - true_val, - test_cond); - - instructions->push_tail(set_fallthru_on_test); - } else { /* default case */ - /* Set falltrhu state. - */ - ir_assignment *set_fallthru = - new(ctx) ir_assignment(deref_fallthru_var, - true_val, - NULL); - - instructions->push_tail(set_fallthru); - } - - /* Case statements do not have r-values. - */ - return NULL; -} - - -void -ast_iteration_statement::condition_to_hir(ir_loop *stmt, - struct _mesa_glsl_parse_state *state) -{ - void *ctx = state; - - if (condition != NULL) { - ir_rvalue *const cond = - condition->hir(& stmt->body_instructions, state); - - if ((cond == NULL) - || !cond->type->is_boolean() || !cond->type->is_scalar()) { - YYLTYPE loc = condition->get_location(); - - _mesa_glsl_error(& loc, state, - "loop condition must be scalar boolean"); - } else { - /* As the first code in the loop body, generate a block that looks - * like 'if (!condition) break;' as the loop termination condition. - */ - ir_rvalue *const not_cond = - new(ctx) ir_expression(ir_unop_logic_not, glsl_type::bool_type, cond, - NULL); - - ir_if *const if_stmt = new(ctx) ir_if(not_cond); - - ir_jump *const break_stmt = - new(ctx) ir_loop_jump(ir_loop_jump::jump_break); - - if_stmt->then_instructions.push_tail(break_stmt); - stmt->body_instructions.push_tail(if_stmt); - } - } -} - - -ir_rvalue * -ast_iteration_statement::hir(exec_list *instructions, - struct _mesa_glsl_parse_state *state) -{ - void *ctx = state; - - /* For-loops and while-loops start a new scope, but do-while loops do not. - */ - if (mode != ast_do_while) - state->symbols->push_scope(); - - if (init_statement != NULL) - init_statement->hir(instructions, state); - - ir_loop *const stmt = new(ctx) ir_loop(); - instructions->push_tail(stmt); - - /* Track the current loop nesting. - */ - ast_iteration_statement *nesting_ast = state->loop_nesting_ast; - - state->loop_nesting_ast = this; - - /* Likewise, indicate that following code is closest to a loop, - * NOT closest to a switch. - */ - bool saved_is_switch_innermost = state->is_switch_innermost; - state->is_switch_innermost = false; - - if (mode != ast_do_while) - condition_to_hir(stmt, state); - - if (body != NULL) - body->hir(& stmt->body_instructions, state); - - if (rest_expression != NULL) - rest_expression->hir(& stmt->body_instructions, state); - - if (mode == ast_do_while) - condition_to_hir(stmt, state); - - if (mode != ast_do_while) - state->symbols->pop_scope(); + ir_rvalue * + ast_case_statement::hir(exec_list *instructions, + struct _mesa_glsl_parse_state *state) + { + labels->hir(instructions, state); + + /* Conditionally set fallthru state based on break state. + */ + ir_constant *const false_val = new(state) ir_constant(false); + ir_dereference_variable *const deref_is_fallthru_var = + new(state) ir_dereference_variable(state->switch_state.is_fallthru_var); + ir_dereference_variable *const deref_is_break_var = + new(state) ir_dereference_variable(state->switch_state.is_break_var); + ir_assignment *const reset_fallthru_on_break = + new(state) ir_assignment(deref_is_fallthru_var, + false_val, + deref_is_break_var); + instructions->push_tail(reset_fallthru_on_break); + + /* Guard case statements depending on fallthru state. + */ + ir_dereference_variable *const deref_fallthru_guard = + new(state) ir_dereference_variable(state->switch_state.is_fallthru_var); + ir_if *const test_fallthru = new(state) ir_if(deref_fallthru_guard); + + foreach_list_typed (ast_node, stmt, link, & this->stmts) + stmt->hir(& test_fallthru->then_instructions, state); + + instructions->push_tail(test_fallthru); + + /* Case statements do not have r-values. + */ + return NULL; + } + + + ir_rvalue * + ast_case_label_list::hir(exec_list *instructions, + struct _mesa_glsl_parse_state *state) + { + foreach_list_typed (ast_case_label, label, link, & this->labels) + label->hir(instructions, state); + + /* Case labels do not have r-values. + */ + return NULL; + } + + + ir_rvalue * + ast_case_label::hir(exec_list *instructions, + struct _mesa_glsl_parse_state *state) + { + void *ctx = state; + + ir_dereference_variable *deref_fallthru_var = + new(ctx) ir_dereference_variable(state->switch_state.is_fallthru_var); + + ir_rvalue *const true_val = new(ctx) ir_constant(true); + + /* If not default case, ... + */ + if (this->test_value != NULL) { + /* Conditionally set fallthru state based on + * comparison of cached test expression value to case label. + */ + ir_rvalue *const label_rval = this->test_value->hir(instructions, state); + ir_constant *label_const = label_rval->constant_expression_value(); + + if (!label_const) { + YYLTYPE loc = this->test_value->get_location(); + + _mesa_glsl_error(& loc, state, + "switch statement case label must be a " + "constant expression"); + + /* Stuff a dummy value in to allow processing to continue. */ + label_const = new(ctx) ir_constant(0); + } else { + ast_expression *previous_label = (ast_expression *) + hash_table_find(state->switch_state.labels_ht, + (void *)(uintptr_t)label_const->value.u[0]); + + if (previous_label) { + YYLTYPE loc = this->test_value->get_location(); + _mesa_glsl_error(& loc, state, + "duplicate case value"); + + loc = previous_label->get_location(); + _mesa_glsl_error(& loc, state, + "this is the previous case label"); + } else { + hash_table_insert(state->switch_state.labels_ht, + this->test_value, + (void *)(uintptr_t)label_const->value.u[0]); + } + } + + ir_dereference_variable *deref_test_var = + new(ctx) ir_dereference_variable(state->switch_state.test_var); + + ir_rvalue *const test_cond = new(ctx) ir_expression(ir_binop_all_equal, + glsl_type::bool_type, + label_const, + deref_test_var); + + ir_assignment *set_fallthru_on_test = + new(ctx) ir_assignment(deref_fallthru_var, + true_val, + test_cond); + + instructions->push_tail(set_fallthru_on_test); + } else { /* default case */ + if (state->switch_state.previous_default) { + printf("a\n"); + YYLTYPE loc = this->get_location(); + _mesa_glsl_error(& loc, state, + "multiple default labels in one switch"); + + printf("b\n"); + + loc = state->switch_state.previous_default->get_location(); + _mesa_glsl_error(& loc, state, + "this is the first default label"); + } + state->switch_state.previous_default = this; + + /* Set falltrhu state. + */ + ir_assignment *set_fallthru = + new(ctx) ir_assignment(deref_fallthru_var, + true_val, + NULL); + + instructions->push_tail(set_fallthru); + } + + /* Case statements do not have r-values. + */ + return NULL; + } + + + void + ast_iteration_statement::condition_to_hir(ir_loop *stmt, + struct _mesa_glsl_parse_state *state) + { + void *ctx = state; + + if (condition != NULL) { + ir_rvalue *const cond = + condition->hir(& stmt->body_instructions, state); + + if ((cond == NULL) + || !cond->type->is_boolean() || !cond->type->is_scalar()) { + YYLTYPE loc = condition->get_location(); + + _mesa_glsl_error(& loc, state, + "loop condition must be scalar boolean"); + } else { + /* As the first code in the loop body, generate a block that looks + * like 'if (!condition) break;' as the loop termination condition. + */ + ir_rvalue *const not_cond = + new(ctx) ir_expression(ir_unop_logic_not, glsl_type::bool_type, cond, + NULL); + + ir_if *const if_stmt = new(ctx) ir_if(not_cond); + + ir_jump *const break_stmt = + new(ctx) ir_loop_jump(ir_loop_jump::jump_break); + + if_stmt->then_instructions.push_tail(break_stmt); + stmt->body_instructions.push_tail(if_stmt); + } + } + } + + + ir_rvalue * + ast_iteration_statement::hir(exec_list *instructions, + struct _mesa_glsl_parse_state *state) + { + void *ctx = state; + + /* For-loops and while-loops start a new scope, but do-while loops do not. + */ + if (mode != ast_do_while) + state->symbols->push_scope(); + + if (init_statement != NULL) + init_statement->hir(instructions, state); + + ir_loop *const stmt = new(ctx) ir_loop(); + instructions->push_tail(stmt); + + /* Track the current loop nesting. + */ + ast_iteration_statement *nesting_ast = state->loop_nesting_ast; + + state->loop_nesting_ast = this; + + /* Likewise, indicate that following code is closest to a loop, + * NOT closest to a switch. + */ + bool saved_is_switch_innermost = state->switch_state.is_switch_innermost; + state->switch_state.is_switch_innermost = false; + + if (mode != ast_do_while) + condition_to_hir(stmt, state); + + if (body != NULL) + body->hir(& stmt->body_instructions, state); + + if (rest_expression != NULL) + rest_expression->hir(& stmt->body_instructions, state); - /* Restore previous nesting before returning. - */ - state->loop_nesting_ast = nesting_ast; - state->is_switch_innermost = saved_is_switch_innermost; + if (mode == ast_do_while) + condition_to_hir(stmt, state); + + if (mode != ast_do_while) + state->symbols->pop_scope(); + + /* Restore previous nesting before returning. + */ + state->loop_nesting_ast = nesting_ast; + state->switch_state.is_switch_innermost = saved_is_switch_innermost; /* Loops do not have r-values. */ diff --git a/mesalib/src/glsl/glcpp/glcpp-lex.l b/mesalib/src/glsl/glcpp/glcpp-lex.l index 596c6db70..b34f2c0e9 100644 --- a/mesalib/src/glsl/glcpp/glcpp-lex.l +++ b/mesalib/src/glsl/glcpp/glcpp-lex.l @@ -1,324 +1,332 @@ -%{
-/*
- * Copyright © 2010 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.
- */
-
-#include <stdio.h>
-#include <string.h>
-#include <ctype.h>
-
-#include "glcpp.h"
-#include "glcpp-parse.h"
-
-/* Flex annoyingly generates some functions without making them
- * static. Let's declare them here. */
-int glcpp_get_column (yyscan_t yyscanner);
-void glcpp_set_column (int column_no , yyscan_t yyscanner);
-
-#ifdef _MSC_VER
-#define YY_NO_UNISTD_H
-#endif
-
-#define YY_NO_INPUT
-
-#define YY_USER_ACTION \
- do { \
- yylloc->first_column = yycolumn + 1; \
- yylloc->first_line = yylineno; \
- yycolumn += yyleng; \
- } while(0);
-
-#define YY_USER_INIT \
- do { \
- yylineno = 1; \
- yycolumn = 1; \
- yylloc->source = 0; \
- } while(0)
-%}
-
-%option bison-bridge bison-locations reentrant noyywrap
-%option extra-type="glcpp_parser_t *"
-%option prefix="glcpp_"
-%option stack
-%option never-interactive
-
-%x DONE COMMENT UNREACHABLE SKIP
-
-SPACE [[:space:]]
-NONSPACE [^[:space:]]
-NEWLINE [\n]
-HSPACE [ \t]
-HASH ^{HSPACE}*#{HSPACE}*
-IDENTIFIER [_a-zA-Z][_a-zA-Z0-9]*
-PUNCTUATION [][(){}.&*~!/%<>^|;,=+-]
-OTHER [^][(){}.&*~!/%<>^|;,=#[:space:]+-]+
-
-DIGITS [0-9][0-9]*
-DECIMAL_INTEGER [1-9][0-9]*[uU]?
-OCTAL_INTEGER 0[0-7]*[uU]?
-HEXADECIMAL_INTEGER 0[xX][0-9a-fA-F]+[uU]?
-
-%%
- /* Implicitly switch between SKIP and INITIAL (non-skipping);
- * don't switch if some other state was explicitly set.
- */
- glcpp_parser_t *parser = yyextra;
- if (YY_START == 0 || YY_START == SKIP) {
- if (parser->lexing_if || parser->skip_stack == NULL || parser->skip_stack->type == SKIP_NO_SKIP) {
- BEGIN 0;
- } else {
- BEGIN SKIP;
- }
- }
-
- /* Single-line comments */
-"//"[^\n]* {
-}
-
- /* Multi-line comments */
-"/*" { yy_push_state(COMMENT, yyscanner); }
-<COMMENT>[^*\n]*
-<COMMENT>[^*\n]*\n { yylineno++; yycolumn = 0; return NEWLINE; }
-<COMMENT>"*"+[^*/\n]*
-<COMMENT>"*"+[^*/\n]*\n { yylineno++; yycolumn = 0; return NEWLINE; }
-<COMMENT>"*"+"/" {
- yy_pop_state(yyscanner);
- if (yyextra->space_tokens)
- return SPACE;
-}
-
-{HASH}version {
- yylval->str = ralloc_strdup (yyextra, yytext);
- yyextra->space_tokens = 0;
- return HASH_VERSION;
-}
-
- /* glcpp doesn't handle #extension, #version, or #pragma directives.
- * Simply pass them through to the main compiler's lexer/parser. */
-{HASH}(extension|pragma)[^\n]+ {
- yylval->str = ralloc_strdup (yyextra, yytext);
- yylineno++;
- yycolumn = 0;
- return OTHER;
-}
-
-{HASH}line{HSPACE}+{DIGITS}{HSPACE}+{DIGITS}{HSPACE}*$ {
- /* Eat characters until the first digit is
- * encountered
- */
- char *ptr = yytext;
- while (!isdigit(*ptr))
- ptr++;
-
- /* Subtract one from the line number because
- * yylineno is zero-based instead of
- * one-based.
- */
- yylineno = strtol(ptr, &ptr, 0) - 1;
- yylloc->source = strtol(ptr, NULL, 0);
-}
-
-{HASH}line{HSPACE}+{DIGITS}{HSPACE}*$ {
- /* Eat characters until the first digit is
- * encountered
- */
- char *ptr = yytext;
- while (!isdigit(*ptr))
- ptr++;
-
- /* Subtract one from the line number because
- * yylineno is zero-based instead of
- * one-based.
- */
- yylineno = strtol(ptr, &ptr, 0) - 1;
-}
-
-<SKIP,INITIAL>{
-{HASH}ifdef {
- yyextra->lexing_if = 1;
- yyextra->space_tokens = 0;
- return HASH_IFDEF;
-}
-
-{HASH}ifndef {
- yyextra->lexing_if = 1;
- yyextra->space_tokens = 0;
- return HASH_IFNDEF;
-}
-
-{HASH}if/[^_a-zA-Z0-9] {
- yyextra->lexing_if = 1;
- yyextra->space_tokens = 0;
- return HASH_IF;
-}
-
-{HASH}elif {
- yyextra->lexing_if = 1;
- yyextra->space_tokens = 0;
- return HASH_ELIF;
-}
-
-{HASH}else {
- yyextra->space_tokens = 0;
- return HASH_ELSE;
-}
-
-{HASH}endif {
- yyextra->space_tokens = 0;
- return HASH_ENDIF;
-}
-}
-
-<SKIP>[^\n] ;
-
-{HASH}error.* {
- char *p;
- for (p = yytext; !isalpha(p[0]); p++); /* skip " # " */
- p += 5; /* skip "error" */
- glcpp_error(yylloc, yyextra, "#error%s", p);
-}
-
-{HASH}define{HSPACE}+/{IDENTIFIER}"(" {
- yyextra->space_tokens = 0;
- return HASH_DEFINE_FUNC;
-}
-
-{HASH}define {
- yyextra->space_tokens = 0;
- return HASH_DEFINE_OBJ;
-}
-
-{HASH}undef {
- yyextra->space_tokens = 0;
- return HASH_UNDEF;
-}
-
-{HASH} {
- yyextra->space_tokens = 0;
- return HASH;
-}
-
-{DECIMAL_INTEGER} {
- yylval->str = ralloc_strdup (yyextra, yytext);
- return INTEGER_STRING;
-}
-
-{OCTAL_INTEGER} {
- yylval->str = ralloc_strdup (yyextra, yytext);
- return INTEGER_STRING;
-}
-
-{HEXADECIMAL_INTEGER} {
- yylval->str = ralloc_strdup (yyextra, yytext);
- return INTEGER_STRING;
-}
-
-"<<" {
- return LEFT_SHIFT;
-}
-
-">>" {
- return RIGHT_SHIFT;
-}
-
-"<=" {
- return LESS_OR_EQUAL;
-}
-
-">=" {
- return GREATER_OR_EQUAL;
-}
-
-"==" {
- return EQUAL;
-}
-
-"!=" {
- return NOT_EQUAL;
-}
-
-"&&" {
- return AND;
-}
-
-"||" {
- return OR;
-}
-
-"##" {
- return PASTE;
-}
-
-"defined" {
- return DEFINED;
-}
-
-{IDENTIFIER} {
- yylval->str = ralloc_strdup (yyextra, yytext);
- return IDENTIFIER;
-}
-
-{PUNCTUATION} {
- return yytext[0];
-}
-
-{OTHER}+ {
- yylval->str = ralloc_strdup (yyextra, yytext);
- return OTHER;
-}
-
-{HSPACE}+ {
- if (yyextra->space_tokens) {
- return SPACE;
- }
-}
-
-<SKIP,INITIAL>\n {
- yyextra->lexing_if = 0;
- yylineno++;
- yycolumn = 0;
- return NEWLINE;
-}
-
- /* Handle missing newline at EOF. */
-<INITIAL><<EOF>> {
- BEGIN DONE; /* Don't keep matching this rule forever. */
- yyextra->lexing_if = 0;
- return NEWLINE;
-}
-
- /* We don't actually use the UNREACHABLE start condition. We
- only have this action here so that we can pretend to call some
- generated functions, (to avoid "defined but not used"
- warnings. */
-<UNREACHABLE>. {
- unput('.');
- yy_top_state(yyextra);
-}
-
-%%
-
-void
-glcpp_lex_set_source_string(glcpp_parser_t *parser, const char *shader)
-{
- yy_scan_string(shader, parser->scanner);
-}
+%{ +/* + * Copyright © 2010 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. + */ + +#include <stdio.h> +#include <string.h> +#include <ctype.h> + +#include "glcpp.h" +#include "glcpp-parse.h" + +/* Flex annoyingly generates some functions without making them + * static. Let's declare them here. */ +int glcpp_get_column (yyscan_t yyscanner); +void glcpp_set_column (int column_no , yyscan_t yyscanner); + +#ifdef _MSC_VER +#define YY_NO_UNISTD_H +#endif + +#define YY_NO_INPUT + +#define YY_USER_ACTION \ + do { \ + yylloc->first_column = yycolumn + 1; \ + yylloc->first_line = yylineno; \ + yycolumn += yyleng; \ + } while(0); + +#define YY_USER_INIT \ + do { \ + yylineno = 1; \ + yycolumn = 1; \ + yylloc->source = 0; \ + } while(0) +%} + +%option bison-bridge bison-locations reentrant noyywrap +%option extra-type="glcpp_parser_t *" +%option prefix="glcpp_" +%option stack +%option never-interactive + +%x DONE COMMENT UNREACHABLE SKIP + +SPACE [[:space:]] +NONSPACE [^[:space:]] +NEWLINE [\n] +HSPACE [ \t] +HASH ^{HSPACE}*#{HSPACE}* +IDENTIFIER [_a-zA-Z][_a-zA-Z0-9]* +PUNCTUATION [][(){}.&*~!/%<>^|;,=+-] + +/* The OTHER class is simply a catch-all for things that the CPP +parser just doesn't care about. Since flex regular expressions that +match longer strings take priority over those matching shorter +strings, we have to be careful to avoid OTHER matching and hiding +something that CPP does care about. So we simply exclude all +characters that appear in any other expressions. */ + +OTHER [^][_#[:space:]#a-zA-Z0-9(){}.&*~!/%<>^|;,=+-] + +DIGITS [0-9][0-9]* +DECIMAL_INTEGER [1-9][0-9]*[uU]? +OCTAL_INTEGER 0[0-7]*[uU]? +HEXADECIMAL_INTEGER 0[xX][0-9a-fA-F]+[uU]? + +%% + /* Implicitly switch between SKIP and INITIAL (non-skipping); + * don't switch if some other state was explicitly set. + */ + glcpp_parser_t *parser = yyextra; + if (YY_START == 0 || YY_START == SKIP) { + if (parser->lexing_if || parser->skip_stack == NULL || parser->skip_stack->type == SKIP_NO_SKIP) { + BEGIN 0; + } else { + BEGIN SKIP; + } + } + + /* Single-line comments */ +"//"[^\n]* { +} + + /* Multi-line comments */ +"/*" { yy_push_state(COMMENT, yyscanner); } +<COMMENT>[^*\n]* +<COMMENT>[^*\n]*\n { yylineno++; yycolumn = 0; return NEWLINE; } +<COMMENT>"*"+[^*/\n]* +<COMMENT>"*"+[^*/\n]*\n { yylineno++; yycolumn = 0; return NEWLINE; } +<COMMENT>"*"+"/" { + yy_pop_state(yyscanner); + if (yyextra->space_tokens) + return SPACE; +} + +{HASH}version { + yylval->str = ralloc_strdup (yyextra, yytext); + yyextra->space_tokens = 0; + return HASH_VERSION; +} + + /* glcpp doesn't handle #extension, #version, or #pragma directives. + * Simply pass them through to the main compiler's lexer/parser. */ +{HASH}(extension|pragma)[^\n]+ { + yylval->str = ralloc_strdup (yyextra, yytext); + yylineno++; + yycolumn = 0; + return OTHER; +} + +{HASH}line{HSPACE}+{DIGITS}{HSPACE}+{DIGITS}{HSPACE}*$ { + /* Eat characters until the first digit is + * encountered + */ + char *ptr = yytext; + while (!isdigit(*ptr)) + ptr++; + + /* Subtract one from the line number because + * yylineno is zero-based instead of + * one-based. + */ + yylineno = strtol(ptr, &ptr, 0) - 1; + yylloc->source = strtol(ptr, NULL, 0); +} + +{HASH}line{HSPACE}+{DIGITS}{HSPACE}*$ { + /* Eat characters until the first digit is + * encountered + */ + char *ptr = yytext; + while (!isdigit(*ptr)) + ptr++; + + /* Subtract one from the line number because + * yylineno is zero-based instead of + * one-based. + */ + yylineno = strtol(ptr, &ptr, 0) - 1; +} + +<SKIP,INITIAL>{ +{HASH}ifdef { + yyextra->lexing_if = 1; + yyextra->space_tokens = 0; + return HASH_IFDEF; +} + +{HASH}ifndef { + yyextra->lexing_if = 1; + yyextra->space_tokens = 0; + return HASH_IFNDEF; +} + +{HASH}if/[^_a-zA-Z0-9] { + yyextra->lexing_if = 1; + yyextra->space_tokens = 0; + return HASH_IF; +} + +{HASH}elif { + yyextra->lexing_if = 1; + yyextra->space_tokens = 0; + return HASH_ELIF; +} + +{HASH}else { + yyextra->space_tokens = 0; + return HASH_ELSE; +} + +{HASH}endif { + yyextra->space_tokens = 0; + return HASH_ENDIF; +} +} + +<SKIP>[^\n] ; + +{HASH}error.* { + char *p; + for (p = yytext; !isalpha(p[0]); p++); /* skip " # " */ + p += 5; /* skip "error" */ + glcpp_error(yylloc, yyextra, "#error%s", p); +} + +{HASH}define{HSPACE}+/{IDENTIFIER}"(" { + yyextra->space_tokens = 0; + return HASH_DEFINE_FUNC; +} + +{HASH}define { + yyextra->space_tokens = 0; + return HASH_DEFINE_OBJ; +} + +{HASH}undef { + yyextra->space_tokens = 0; + return HASH_UNDEF; +} + +{HASH} { + yyextra->space_tokens = 0; + return HASH; +} + +{DECIMAL_INTEGER} { + yylval->str = ralloc_strdup (yyextra, yytext); + return INTEGER_STRING; +} + +{OCTAL_INTEGER} { + yylval->str = ralloc_strdup (yyextra, yytext); + return INTEGER_STRING; +} + +{HEXADECIMAL_INTEGER} { + yylval->str = ralloc_strdup (yyextra, yytext); + return INTEGER_STRING; +} + +"<<" { + return LEFT_SHIFT; +} + +">>" { + return RIGHT_SHIFT; +} + +"<=" { + return LESS_OR_EQUAL; +} + +">=" { + return GREATER_OR_EQUAL; +} + +"==" { + return EQUAL; +} + +"!=" { + return NOT_EQUAL; +} + +"&&" { + return AND; +} + +"||" { + return OR; +} + +"##" { + return PASTE; +} + +"defined" { + return DEFINED; +} + +{IDENTIFIER} { + yylval->str = ralloc_strdup (yyextra, yytext); + return IDENTIFIER; +} + +{PUNCTUATION} { + return yytext[0]; +} + +{OTHER}+ { + yylval->str = ralloc_strdup (yyextra, yytext); + return OTHER; +} + +{HSPACE}+ { + if (yyextra->space_tokens) { + return SPACE; + } +} + +<SKIP,INITIAL>\n { + yyextra->lexing_if = 0; + yylineno++; + yycolumn = 0; + return NEWLINE; +} + + /* Handle missing newline at EOF. */ +<INITIAL><<EOF>> { + BEGIN DONE; /* Don't keep matching this rule forever. */ + yyextra->lexing_if = 0; + return NEWLINE; +} + + /* We don't actually use the UNREACHABLE start condition. We + only have this action here so that we can pretend to call some + generated functions, (to avoid "defined but not used" + warnings. */ +<UNREACHABLE>. { + unput('.'); + yy_top_state(yyextra); +} + +%% + +void +glcpp_lex_set_source_string(glcpp_parser_t *parser, const char *shader) +{ + yy_scan_string(shader, parser->scanner); +} diff --git a/mesalib/src/glsl/glcpp/glcpp-parse.y b/mesalib/src/glsl/glcpp/glcpp-parse.y index 2b7e65cd4..efcc205c2 100644 --- a/mesalib/src/glsl/glcpp/glcpp-parse.y +++ b/mesalib/src/glsl/glcpp/glcpp-parse.y @@ -85,7 +85,6 @@ _token_create_ival (void *ctx, int type, int ival); static token_list_t * _token_list_create (void *ctx); -/* Note: This function calls ralloc_steal on token. */ static void _token_list_append (token_list_t *list, token_t *token); @@ -763,8 +762,6 @@ _token_list_append (token_list_t *list, token_t *token) node->token = token; node->next = NULL; - ralloc_steal (list, token); - if (list->head == NULL) { list->head = node; } else { diff --git a/mesalib/src/glsl/glsl_parser.yy b/mesalib/src/glsl/glsl_parser.yy index e774b4697..d5e85abc0 100644 --- a/mesalib/src/glsl/glsl_parser.yy +++ b/mesalib/src/glsl/glsl_parser.yy @@ -1671,6 +1671,7 @@ switch_statement: SWITCH '(' expression ')' switch_body { $$ = new(state) ast_switch_statement($3, $5); + $$->set_location(yylloc); } ; @@ -1691,10 +1692,12 @@ case_label: CASE expression ':' { $$ = new(state) ast_case_label($2); + $$->set_location(yylloc); } | DEFAULT ':' { $$ = new(state) ast_case_label(NULL); + $$->set_location(yylloc); } ; @@ -1705,6 +1708,7 @@ case_label_list: labels->labels.push_tail(& $1->link); $$ = labels; + $$->set_location(yylloc); } | case_label_list case_label { @@ -1717,6 +1721,7 @@ case_statement: case_label_list statement { ast_case_statement *stmts = new(state) ast_case_statement($1); + stmts->set_location(yylloc); stmts->stmts.push_tail(& $2->link); $$ = stmts; @@ -1732,6 +1737,7 @@ case_statement_list: case_statement { ast_case_statement_list *cases= new(state) ast_case_statement_list(); + cases->set_location(yylloc); cases->cases.push_tail(& $1->link); $$ = cases; diff --git a/mesalib/src/glsl/glsl_parser_extras.cpp b/mesalib/src/glsl/glsl_parser_extras.cpp index 7f8d47ce9..2a72ba1f6 100644 --- a/mesalib/src/glsl/glsl_parser_extras.cpp +++ b/mesalib/src/glsl/glsl_parser_extras.cpp @@ -51,7 +51,7 @@ _mesa_glsl_parse_state::_mesa_glsl_parse_state(struct gl_context *ctx, this->info_log = ralloc_strdup(mem_ctx, ""); this->error = false; this->loop_nesting_ast = NULL; - this->switch_nesting_ast = NULL; + this->switch_state.switch_nesting_ast = NULL; this->num_builtins_to_link = 0; diff --git a/mesalib/src/glsl/glsl_parser_extras.h b/mesalib/src/glsl/glsl_parser_extras.h index dd932951f..ee8f71b82 100644 --- a/mesalib/src/glsl/glsl_parser_extras.h +++ b/mesalib/src/glsl/glsl_parser_extras.h @@ -42,6 +42,20 @@ enum _mesa_glsl_parser_targets { struct gl_context; +struct glsl_switch_state { + /** Temporary variables needed for switch statement. */ + ir_variable *test_var; + ir_variable *is_fallthru_var; + ir_variable *is_break_var; + class ast_switch_statement *switch_nesting_ast; + + /** Table of constant values already used in case labels */ + struct hash_table *labels_ht; + class ast_case_label *previous_default; + + bool is_switch_innermost; // if switch stmt is closest to break, ... +}; + struct _mesa_glsl_parse_state { _mesa_glsl_parse_state(struct gl_context *ctx, GLenum target, void *mem_ctx); @@ -150,13 +164,8 @@ struct _mesa_glsl_parse_state { /** Loop or switch statement containing the current instructions. */ class ast_iteration_statement *loop_nesting_ast; - class ast_switch_statement *switch_nesting_ast; - bool is_switch_innermost; // if switch stmt is closest to break, ... - /** Temporary variables needed for switch statement. */ - ir_variable *test_var; - ir_variable *is_fallthru_var; - ir_variable *is_break_var; + struct glsl_switch_state switch_state; /** List of structures defined in user code. */ const glsl_type **user_structures; diff --git a/mesalib/src/glsl/linker.cpp b/mesalib/src/glsl/linker.cpp index 509575192..82bddb003 100644 --- a/mesalib/src/glsl/linker.cpp +++ b/mesalib/src/glsl/linker.cpp @@ -856,6 +856,27 @@ get_main_function_signature(gl_shader *sh) /** + * This class is only used in link_intrastage_shaders() below but declaring + * it inside that function leads to compiler warnings with some versions of + * gcc. + */ +class array_sizing_visitor : public ir_hierarchical_visitor { +public: + virtual ir_visitor_status visit(ir_variable *var) + { + if (var->type->is_array() && (var->type->length == 0)) { + const glsl_type *type = + glsl_type::get_array_instance(var->type->fields.array, + var->max_array_access + 1); + assert(type != NULL); + var->type = type; + } + return visit_continue; + } +}; + + +/** * Combine a group of shaders for a single stage to generate a linked shader * * \note @@ -1005,22 +1026,7 @@ link_intrastage_shaders(void *mem_ctx, * max_array_access field. */ if (linked != NULL) { - class array_sizing_visitor : public ir_hierarchical_visitor { - public: - virtual ir_visitor_status visit(ir_variable *var) - { - if (var->type->is_array() && (var->type->length == 0)) { - const glsl_type *type = - glsl_type::get_array_instance(var->type->fields.array, - var->max_array_access + 1); - - assert(type != NULL); - var->type = type; - } - - return visit_continue; - } - } v; + array_sizing_visitor v; v.run(linked->ir); } diff --git a/mesalib/src/mapi/glapi/glapi_nop.c b/mesalib/src/mapi/glapi/glapi_nop.c index 9b0929715..69b1ae6dd 100644 --- a/mesalib/src/mapi/glapi/glapi_nop.c +++ b/mesalib/src/mapi/glapi/glapi_nop.c @@ -51,7 +51,11 @@ _glapi_set_warning_func(_glapi_proc func) { } -#ifdef DEBUG +/* + * When GLAPIENTRY is __stdcall (i.e. Windows), the stack is popped by the + * callee making the number/type of arguments significant. + */ +#if defined(_WIN32) || defined(DEBUG) /** * Called by each of the no-op GL entrypoints. @@ -59,7 +63,7 @@ _glapi_set_warning_func(_glapi_proc func) static int Warn(const char *func) { -#if !defined(_WIN32_WCE) +#if defined(DEBUG) && !defined(_WIN32_WCE) if (getenv("MESA_DEBUG") || getenv("LIBGL_DEBUG")) { fprintf(stderr, "GL User Error: gl%s called without a rendering context\n", func); diff --git a/mesalib/src/mesa/drivers/dri/common/drirc b/mesalib/src/mesa/drivers/dri/common/drirc index 7abc64648..59c00d7ad 100644 --- a/mesalib/src/mesa/drivers/dri/common/drirc +++ b/mesalib/src/mesa/drivers/dri/common/drirc @@ -1,6 +1,9 @@ <driconf> <device screen="0" driver="i965"> - <application name="Sanctuary"> + <application executable="Sanctuary"> + <option name="force_glsl_extensions_warn" value="true" /> + </application> + <application executable="Tropics"> <option name="force_glsl_extensions_warn" value="true" /> </application> </device> diff --git a/mesalib/src/mesa/main/api_validate.c b/mesalib/src/mesa/main/api_validate.c index b6871d0db..1ae491f25 100644 --- a/mesalib/src/mesa/main/api_validate.c +++ b/mesalib/src/mesa/main/api_validate.c @@ -187,7 +187,7 @@ check_index_bounds(struct gl_context *ctx, GLsizei count, GLenum type, vbo_get_minmax_indices(ctx, &prim, &ib, &min, &max, 1); if ((int)(min + basevertex) < 0 || - max + basevertex > ctx->Array.ArrayObj->_MaxElement) { + max + basevertex >= ctx->Array.ArrayObj->_MaxElement) { /* the max element is out of bounds of one or more enabled arrays */ _mesa_warning(ctx, "glDrawElements() index=%u is out of bounds (max=%u)", max, ctx->Array.ArrayObj->_MaxElement); diff --git a/mesalib/src/mesa/main/arrayobj.c b/mesalib/src/mesa/main/arrayobj.c index d9ae187bb..c7584d903 100644 --- a/mesalib/src/mesa/main/arrayobj.c +++ b/mesalib/src/mesa/main/arrayobj.c @@ -373,6 +373,10 @@ bind_vertex_array(struct gl_context *ctx, GLuint id, GLboolean genRequired) return; } + save_array_object(ctx, newObj); + } + + if (!newObj->_Used) { /* The "Interactions with APPLE_vertex_array_object" section of the * GL_ARB_vertex_array_object spec says: * @@ -380,7 +384,7 @@ bind_vertex_array(struct gl_context *ctx, GLuint id, GLboolean genRequired) * BindVertexArrayAPPLE, determines the semantic of the object." */ newObj->ARBsemantics = genRequired; - save_array_object(ctx, newObj); + newObj->_Used = GL_TRUE; } } diff --git a/mesalib/src/mesa/main/attrib.c b/mesalib/src/mesa/main/attrib.c index 01e79455c..846da35e9 100644 --- a/mesalib/src/mesa/main/attrib.c +++ b/mesalib/src/mesa/main/attrib.c @@ -47,6 +47,7 @@ #include "multisample.h" #include "points.h" #include "polygon.h" +#include "shared.h" #include "scissor.h" #include "stencil.h" #include "texenv.h" @@ -165,6 +166,13 @@ struct texture_state * deleted while saved in the attribute stack). */ struct gl_texture_object *SavedTexRef[MAX_TEXTURE_UNITS][NUM_TEXTURE_TARGETS]; + + /* We need to keep a reference to the shared state. That's where the + * default texture objects are kept. We don't want that state to be + * freed while the attribute stack contains pointers to any default + * texture objects. + */ + struct gl_shared_state *SharedRef; }; @@ -437,6 +445,8 @@ _mesa_PushAttrib(GLbitfield mask) } } + _mesa_reference_shared_state(ctx, &texstate->SharedRef, ctx->Shared); + _mesa_unlock_context_textures(ctx); save_attrib_data(&head, GL_TEXTURE_BIT, texstate); @@ -806,6 +816,8 @@ pop_texture_group(struct gl_context *ctx, struct texture_state *texstate) _mesa_ActiveTextureARB(GL_TEXTURE0_ARB + texstate->Texture.CurrentUnit); + _mesa_reference_shared_state(ctx, &texstate->SharedRef, NULL); + _mesa_unlock_context_textures(ctx); } @@ -1244,7 +1256,6 @@ _mesa_PopAttrib(void) } break; case GL_TEXTURE_BIT: - /* Take care of texture object reference counters */ { struct texture_state *texstate = (struct texture_state *) attr->data; @@ -1605,6 +1616,7 @@ _mesa_free_attrib_data(struct gl_context *ctx) _mesa_reference_texobj(&texstate->SavedTexRef[u][tgt], NULL); } } + _mesa_reference_shared_state(ctx, &texstate->SharedRef, NULL); } else { /* any other chunks of state that requires special handling? */ diff --git a/mesalib/src/mesa/main/bufferobj.c b/mesalib/src/mesa/main/bufferobj.c index 85ad9b55c..2483f1905 100644 --- a/mesalib/src/mesa/main/bufferobj.c +++ b/mesalib/src/mesa/main/bufferobj.c @@ -106,12 +106,21 @@ get_buffer_target(struct gl_context *ctx, GLenum target) * specified context or \c NULL if \c target is invalid. */ static inline struct gl_buffer_object * -get_buffer(struct gl_context *ctx, GLenum target) +get_buffer(struct gl_context *ctx, const char *func, GLenum target) { struct gl_buffer_object **bufObj = get_buffer_target(ctx, target); - if (bufObj) - return *bufObj; - return NULL; + + if (!bufObj) { + _mesa_error(ctx, GL_INVALID_ENUM, "%s(target)", func); + return NULL; + } + + if (!_mesa_is_bufferobj(*bufObj)) { + _mesa_error(ctx, GL_INVALID_OPERATION, "%s(buffer 0)", func); + return NULL; + } + + return *bufObj; } @@ -190,15 +199,10 @@ buffer_object_subdata_range_good( struct gl_context * ctx, GLenum target, return NULL; } - bufObj = get_buffer(ctx, target); - if (!bufObj) { - _mesa_error(ctx, GL_INVALID_ENUM, "%s(target)", caller); - return NULL; - } - if (!_mesa_is_bufferobj(bufObj)) { - _mesa_error(ctx, GL_INVALID_OPERATION, "%s", caller); + bufObj = get_buffer(ctx, caller, target); + if (!bufObj) return NULL; - } + if (offset + size > bufObj->Size) { _mesa_error(ctx, GL_INVALID_VALUE, "%s(offset %lu + size %lu > buffer size %lu)", caller, @@ -918,16 +922,10 @@ _mesa_BufferDataARB(GLenum target, GLsizeiptrARB size, return; } - bufObj = get_buffer(ctx, target); - if (!bufObj) { - _mesa_error(ctx, GL_INVALID_ENUM, "glBufferDataARB(target)" ); + bufObj = get_buffer(ctx, "glBufferDataARB", target); + if (!bufObj) return; - } - if (!_mesa_is_bufferobj(bufObj)) { - _mesa_error(ctx, GL_INVALID_OPERATION, "glBufferDataARB(buffer 0)" ); - return; - } - + if (_mesa_bufferobj_mapped(bufObj)) { /* Unmap the existing buffer. We'll replace it now. Not an error. */ ctx->Driver.UnmapBuffer(ctx, bufObj); @@ -1025,15 +1023,10 @@ _mesa_MapBufferARB(GLenum target, GLenum access) return NULL; } - bufObj = get_buffer(ctx, target); - if (!bufObj) { - _mesa_error(ctx, GL_INVALID_ENUM, "glMapBufferARB(target)" ); + bufObj = get_buffer(ctx, "glMapBufferARB", target); + if (!bufObj) return NULL; - } - if (!_mesa_is_bufferobj(bufObj)) { - _mesa_error(ctx, GL_INVALID_OPERATION, "glMapBufferARB(buffer 0)" ); - return NULL; - } + if (_mesa_bufferobj_mapped(bufObj)) { _mesa_error(ctx, GL_INVALID_OPERATION, "glMapBufferARB(already mapped)"); return NULL; @@ -1099,15 +1092,10 @@ _mesa_UnmapBufferARB(GLenum target) GLboolean status = GL_TRUE; ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE); - bufObj = get_buffer(ctx, target); - if (!bufObj) { - _mesa_error(ctx, GL_INVALID_ENUM, "glUnmapBufferARB(target)" ); + bufObj = get_buffer(ctx, "glUnmapBufferARB", target); + if (!bufObj) return GL_FALSE; - } - if (!_mesa_is_bufferobj(bufObj)) { - _mesa_error(ctx, GL_INVALID_OPERATION, "glUnmapBufferARB" ); - return GL_FALSE; - } + if (!_mesa_bufferobj_mapped(bufObj)) { _mesa_error(ctx, GL_INVALID_OPERATION, "glUnmapBufferARB"); return GL_FALSE; @@ -1166,15 +1154,9 @@ _mesa_GetBufferParameterivARB(GLenum target, GLenum pname, GLint *params) struct gl_buffer_object *bufObj; ASSERT_OUTSIDE_BEGIN_END(ctx); - bufObj = get_buffer(ctx, target); - if (!bufObj) { - _mesa_error(ctx, GL_INVALID_ENUM, "glGetBufferParameterivARB(target)" ); - return; - } - if (!_mesa_is_bufferobj(bufObj)) { - _mesa_error(ctx, GL_INVALID_OPERATION, "glGetBufferParameterivARB" ); + bufObj = get_buffer(ctx, "glGetBufferParameterivARB", target); + if (!bufObj) return; - } switch (pname) { case GL_BUFFER_SIZE_ARB: @@ -1226,15 +1208,9 @@ _mesa_GetBufferParameteri64v(GLenum target, GLenum pname, GLint64 *params) struct gl_buffer_object *bufObj; ASSERT_OUTSIDE_BEGIN_END(ctx); - bufObj = get_buffer(ctx, target); - if (!bufObj) { - _mesa_error(ctx, GL_INVALID_ENUM, "glGetBufferParameteri64v(target)" ); + bufObj = get_buffer(ctx, "glGetBufferParameteri64v", target); + if (!bufObj) return; - } - if (!_mesa_is_bufferobj(bufObj)) { - _mesa_error(ctx, GL_INVALID_OPERATION, "glGetBufferParameteri64v" ); - return; - } switch (pname) { case GL_BUFFER_SIZE_ARB: @@ -1286,15 +1262,9 @@ _mesa_GetBufferPointervARB(GLenum target, GLenum pname, GLvoid **params) return; } - bufObj = get_buffer(ctx, target); - if (!bufObj) { - _mesa_error(ctx, GL_INVALID_ENUM, "glGetBufferPointervARB(target)" ); - return; - } - if (!_mesa_is_bufferobj(bufObj)) { - _mesa_error(ctx, GL_INVALID_OPERATION, "glGetBufferPointervARB" ); + bufObj = get_buffer(ctx, "glGetBufferPointervARB", target); + if (!bufObj) return; - } *params = bufObj->Pointer; } @@ -1309,19 +1279,13 @@ _mesa_CopyBufferSubData(GLenum readTarget, GLenum writeTarget, struct gl_buffer_object *src, *dst; ASSERT_OUTSIDE_BEGIN_END(ctx); - src = get_buffer(ctx, readTarget); - if (!_mesa_is_bufferobj(src)) { - _mesa_error(ctx, GL_INVALID_ENUM, - "glCopyBuffserSubData(readTarget = 0x%x)", readTarget); + src = get_buffer(ctx, "glCopyBuffserSubData", readTarget); + if (!src) return; - } - dst = get_buffer(ctx, writeTarget); - if (!_mesa_is_bufferobj(dst)) { - _mesa_error(ctx, GL_INVALID_ENUM, - "glCopyBuffserSubData(writeTarget = 0x%x)", writeTarget); + dst = get_buffer(ctx, "glCopyBuffserSubData", writeTarget); + if (!dst) return; - } if (_mesa_bufferobj_mapped(src)) { _mesa_error(ctx, GL_INVALID_OPERATION, @@ -1444,12 +1408,9 @@ _mesa_MapBufferRange(GLenum target, GLintptr offset, GLsizeiptr length, return NULL; } - bufObj = get_buffer(ctx, target); - if (!_mesa_is_bufferobj(bufObj)) { - _mesa_error(ctx, GL_INVALID_ENUM, - "glMapBufferRange(target = 0x%x)", target); + bufObj = get_buffer(ctx, "glMapBufferRange", target); + if (!bufObj) return NULL; - } if (offset + length > bufObj->Size) { _mesa_error(ctx, GL_INVALID_VALUE, @@ -1511,51 +1472,42 @@ _mesa_FlushMappedBufferRange(GLenum target, GLintptr offset, GLsizeiptr length) if (!ctx->Extensions.ARB_map_buffer_range) { _mesa_error(ctx, GL_INVALID_OPERATION, - "glMapBufferRange(extension not supported)"); + "glFlushMappedBufferRange(extension not supported)"); return; } if (offset < 0) { _mesa_error(ctx, GL_INVALID_VALUE, - "glMapBufferRange(offset = %ld)", (long)offset); + "glFlushMappedBufferRange(offset = %ld)", (long)offset); return; } if (length < 0) { _mesa_error(ctx, GL_INVALID_VALUE, - "glMapBufferRange(length = %ld)", (long)length); + "glFlushMappedBufferRange(length = %ld)", (long)length); return; } - bufObj = get_buffer(ctx, target); - if (!bufObj) { - _mesa_error(ctx, GL_INVALID_ENUM, - "glMapBufferRange(target = 0x%x)", target); - return; - } - - if (!_mesa_is_bufferobj(bufObj)) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "glMapBufferRange(current buffer is 0)"); + bufObj = get_buffer(ctx, "glFlushMappedBufferRange", target); + if (!bufObj) return; - } if (!_mesa_bufferobj_mapped(bufObj)) { /* buffer is not mapped */ _mesa_error(ctx, GL_INVALID_OPERATION, - "glMapBufferRange(buffer is not mapped)"); + "glFlushMappedBufferRange(buffer is not mapped)"); return; } if ((bufObj->AccessFlags & GL_MAP_FLUSH_EXPLICIT_BIT) == 0) { _mesa_error(ctx, GL_INVALID_OPERATION, - "glMapBufferRange(GL_MAP_FLUSH_EXPLICIT_BIT not set)"); + "glFlushMappedBufferRange(GL_MAP_FLUSH_EXPLICIT_BIT not set)"); return; } if (offset + length > bufObj->Length) { _mesa_error(ctx, GL_INVALID_VALUE, - "glMapBufferRange(offset %ld + length %ld > mapped length %ld)", + "glFlushMappedBufferRange(offset %ld + length %ld > mapped length %ld)", (long)offset, (long)length, (long)bufObj->Length); return; } diff --git a/mesalib/src/mesa/main/context.c b/mesalib/src/mesa/main/context.c index f39cab5e4..43e7438ad 100644 --- a/mesalib/src/mesa/main/context.c +++ b/mesalib/src/mesa/main/context.c @@ -939,13 +939,10 @@ _mesa_initialize_context(struct gl_context *ctx, return GL_FALSE; } - _glthread_LOCK_MUTEX(shared->Mutex); - ctx->Shared = shared; - shared->RefCount++; - _glthread_UNLOCK_MUTEX(shared->Mutex); + _mesa_reference_shared_state(ctx, &ctx->Shared, shared); if (!init_attrib_groups( ctx )) { - _mesa_release_shared_state(ctx, ctx->Shared); + _mesa_reference_shared_state(ctx, &ctx->Shared, NULL); return GL_FALSE; } @@ -973,7 +970,7 @@ _mesa_initialize_context(struct gl_context *ctx, } if (!ctx->Exec) { - _mesa_release_shared_state(ctx, ctx->Shared); + _mesa_reference_shared_state(ctx, &ctx->Shared, NULL); return GL_FALSE; } #endif @@ -1002,7 +999,7 @@ _mesa_initialize_context(struct gl_context *ctx, #if FEATURE_dlist ctx->Save = _mesa_create_save_table(); if (!ctx->Save) { - _mesa_release_shared_state(ctx, ctx->Shared); + _mesa_reference_shared_state(ctx, &ctx->Shared, NULL); free(ctx->Exec); return GL_FALSE; } @@ -1140,7 +1137,7 @@ _mesa_free_context_data( struct gl_context *ctx ) free(ctx->Save); /* Shared context state (display lists, textures, etc) */ - _mesa_release_shared_state( ctx, ctx->Shared ); + _mesa_reference_shared_state(ctx, &ctx->Shared, NULL); /* needs to be after freeing shared state */ _mesa_free_display_list_data(ctx); @@ -1540,17 +1537,18 @@ GLboolean _mesa_share_state(struct gl_context *ctx, struct gl_context *ctxToShare) { if (ctx && ctxToShare && ctx->Shared && ctxToShare->Shared) { - struct gl_shared_state *oldSharedState = ctx->Shared; + struct gl_shared_state *oldShared = NULL; - ctx->Shared = ctxToShare->Shared; - - _glthread_LOCK_MUTEX(ctx->Shared->Mutex); - ctx->Shared->RefCount++; - _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex); + /* save ref to old state to prevent it from being deleted immediately */ + _mesa_reference_shared_state(ctx, &oldShared, ctx->Shared); + + /* update ctx's Shared pointer */ + _mesa_reference_shared_state(ctx, &ctx->Shared, ctxToShare->Shared); update_default_objects(ctx); - _mesa_release_shared_state(ctx, oldSharedState); + /* release the old shared state */ + _mesa_reference_shared_state(ctx, &oldShared, NULL); return GL_TRUE; } diff --git a/mesalib/src/mesa/main/format_unpack.c b/mesalib/src/mesa/main/format_unpack.c index cd16a9ea6..a484979e2 100644 --- a/mesalib/src/mesa/main/format_unpack.c +++ b/mesalib/src/mesa/main/format_unpack.c @@ -2916,6 +2916,32 @@ unpack_uint_z_Z32(const void *src, GLuint *dst, GLuint n) memcpy(dst, src, n * sizeof(GLuint)); } +static void +unpack_uint_z_Z32_FLOAT(const void *src, GLuint *dst, GLuint n) +{ + const float *s = (const float *)src; + GLuint i; + for (i = 0; i < n; i++) { + dst[i] = FLOAT_TO_UINT(IROUND(CLAMP((s[i]), 0.0F, 1.0F))); + } +} + +static void +unpack_uint_z_Z32_FLOAT_X24S8(const void *src, GLuint *dst, GLuint n) +{ + struct z32f_x24s8 { + float z; + uint32_t x24s8; + }; + + const struct z32f_x24s8 *s = (const struct z32f_x24s8 *) src; + GLuint i; + + for (i = 0; i < n; i++) { + dst[i] = FLOAT_TO_UINT(IROUND(CLAMP((s[i].z), 0.0F, 1.0F))); + } +} + /** * Unpack Z values. @@ -2943,6 +2969,12 @@ _mesa_unpack_uint_z_row(gl_format format, GLuint n, case MESA_FORMAT_Z32: unpack = unpack_uint_z_Z32; break; + case MESA_FORMAT_Z32_FLOAT: + unpack = unpack_uint_z_Z32_FLOAT; + break; + case MESA_FORMAT_Z32_FLOAT_X24S8: + unpack = unpack_uint_z_Z32_FLOAT_X24S8; + break; default: _mesa_problem(NULL, "bad format %s in _mesa_unpack_uint_z_row", _mesa_get_format_name(format)); diff --git a/mesalib/src/mesa/main/mipmap.c b/mesalib/src/mesa/main/mipmap.c index 03ce5361e..756316a82 100644 --- a/mesalib/src/mesa/main/mipmap.c +++ b/mesalib/src/mesa/main/mipmap.c @@ -991,7 +991,7 @@ do_row_3D(GLenum datatype, GLuint comps, GLint srcWidth, } } else if ((datatype == GL_HALF_FLOAT_ARB) && (comps == 3)) { - DECLARE_ROW_POINTERS(GLhalfARB, 4); + DECLARE_ROW_POINTERS(GLhalfARB, 3); for (i = j = 0, k = k0; i < (GLuint) dstWidth; i++, j += colStride, k += colStride) { @@ -1001,7 +1001,7 @@ do_row_3D(GLenum datatype, GLuint comps, GLint srcWidth, } } else if ((datatype == GL_HALF_FLOAT_ARB) && (comps == 2)) { - DECLARE_ROW_POINTERS(GLhalfARB, 4); + DECLARE_ROW_POINTERS(GLhalfARB, 2); for (i = j = 0, k = k0; i < (GLuint) dstWidth; i++, j += colStride, k += colStride) { @@ -1010,7 +1010,7 @@ do_row_3D(GLenum datatype, GLuint comps, GLint srcWidth, } } else if ((datatype == GL_HALF_FLOAT_ARB) && (comps == 1)) { - DECLARE_ROW_POINTERS(GLhalfARB, 4); + DECLARE_ROW_POINTERS(GLhalfARB, 1); for (i = j = 0, k = k0; i < (GLuint) dstWidth; i++, j += colStride, k += colStride) { diff --git a/mesalib/src/mesa/main/mtypes.h b/mesalib/src/mesa/main/mtypes.h index 99dcb389b..d3001d35c 100644 --- a/mesalib/src/mesa/main/mtypes.h +++ b/mesalib/src/mesa/main/mtypes.h @@ -1631,6 +1631,11 @@ struct gl_array_object */ GLboolean ARBsemantics; + /** + * Has this array object been bound? + */ + GLboolean _Used; + /** Vertex attribute arrays */ struct gl_client_array VertexAttrib[VERT_ATTRIB_MAX]; diff --git a/mesalib/src/mesa/main/pack.c b/mesalib/src/mesa/main/pack.c index d07e2aaa8..41485a1bf 100644 --- a/mesalib/src/mesa/main/pack.c +++ b/mesalib/src/mesa/main/pack.c @@ -1175,9 +1175,8 @@ _mesa_pack_rgba_span_float(struct gl_context *ctx, GLuint n, GLfloat rgba[][4], break; case GL_RG_INTEGER: for (i=0;i<n;i++) { - dst[i*3+0] = (GLshort) rgba[i][RCOMP]; - dst[i*3+1] = (GLshort) rgba[i][GCOMP]; - dst[i*3+2] = (GLshort) rgba[i][BCOMP]; + dst[i*2+0] = (GLshort) rgba[i][RCOMP]; + dst[i*2+1] = (GLshort) rgba[i][GCOMP]; } break; case GL_RGB_INTEGER_EXT: diff --git a/mesalib/src/mesa/main/shared.c b/mesalib/src/mesa/main/shared.c index c3e93b5a5..c07ce8238 100644 --- a/mesalib/src/mesa/main/shared.c +++ b/mesalib/src/mesa/main/shared.c @@ -388,28 +388,40 @@ free_shared_state(struct gl_context *ctx, struct gl_shared_state *shared) /** - * Decrement shared state object reference count and potentially free it - * and all children structures. - * - * \param ctx GL context. - * \param shared shared state pointer. - * - * \sa free_shared_state(). + * gl_shared_state objects are ref counted. + * If ptr's refcount goes to zero, free the shared state. */ void -_mesa_release_shared_state(struct gl_context *ctx, - struct gl_shared_state *shared) +_mesa_reference_shared_state(struct gl_context *ctx, + struct gl_shared_state **ptr, + struct gl_shared_state *state) { - GLint RefCount; - - _glthread_LOCK_MUTEX(shared->Mutex); - RefCount = --shared->RefCount; - _glthread_UNLOCK_MUTEX(shared->Mutex); + if (*ptr == state) + return; + + if (*ptr) { + /* unref old state */ + struct gl_shared_state *old = *ptr; + GLboolean delete; + + _glthread_LOCK_MUTEX(old->Mutex); + assert(old->RefCount >= 1); + old->RefCount--; + delete = (old->RefCount == 0); + _glthread_UNLOCK_MUTEX(old->Mutex); + + if (delete) { + free_shared_state(ctx, old); + } - assert(RefCount >= 0); + *ptr = NULL; + } - if (RefCount == 0) { - /* free shared state */ - free_shared_state( ctx, shared ); + if (state) { + /* reference new state */ + _glthread_LOCK_MUTEX(state->Mutex); + state->RefCount++; + *ptr = state; + _glthread_UNLOCK_MUTEX(state->Mutex); } } diff --git a/mesalib/src/mesa/main/shared.h b/mesalib/src/mesa/main/shared.h index 55516a8c3..3fe4578cf 100644 --- a/mesalib/src/mesa/main/shared.h +++ b/mesalib/src/mesa/main/shared.h @@ -27,13 +27,14 @@ struct gl_context; -struct gl_shared_state * -_mesa_alloc_shared_state(struct gl_context *ctx); +void +_mesa_reference_shared_state(struct gl_context *ctx, + struct gl_shared_state **ptr, + struct gl_shared_state *state); -void -_mesa_release_shared_state(struct gl_context *ctx, - struct gl_shared_state *shared); +struct gl_shared_state * +_mesa_alloc_shared_state(struct gl_context *ctx); #endif diff --git a/mesalib/src/mesa/main/teximage.c b/mesalib/src/mesa/main/teximage.c index d11425d5e..018aca063 100644 --- a/mesalib/src/mesa/main/teximage.c +++ b/mesalib/src/mesa/main/teximage.c @@ -1179,7 +1179,7 @@ _mesa_test_proxy_teximage(struct gl_context *ctx, GLenum target, GLint level, switch (target) { case GL_PROXY_TEXTURE_1D: maxSize = 1 << (ctx->Const.MaxTextureLevels - 1); - if (width < 2 * border || width > 2 + maxSize) + if (width < 2 * border || width > maxSize) return GL_FALSE; if (level >= ctx->Const.MaxTextureLevels) return GL_FALSE; @@ -1191,9 +1191,9 @@ _mesa_test_proxy_teximage(struct gl_context *ctx, GLenum target, GLint level, case GL_PROXY_TEXTURE_2D: maxSize = 1 << (ctx->Const.MaxTextureLevels - 1); - if (width < 2 * border || width > 2 + maxSize) + if (width < 2 * border || width > maxSize) return GL_FALSE; - if (height < 2 * border || height > 2 + maxSize) + if (height < 2 * border || height > maxSize) return GL_FALSE; if (level >= ctx->Const.MaxTextureLevels) return GL_FALSE; @@ -1207,11 +1207,11 @@ _mesa_test_proxy_teximage(struct gl_context *ctx, GLenum target, GLint level, case GL_PROXY_TEXTURE_3D: maxSize = 1 << (ctx->Const.Max3DTextureLevels - 1); - if (width < 2 * border || width > 2 + maxSize) + if (width < 2 * border || width > maxSize) return GL_FALSE; - if (height < 2 * border || height > 2 + maxSize) + if (height < 2 * border || height > maxSize) return GL_FALSE; - if (depth < 2 * border || depth > 2 + maxSize) + if (depth < 2 * border || depth > maxSize) return GL_FALSE; if (level >= ctx->Const.Max3DTextureLevels) return GL_FALSE; @@ -1237,9 +1237,9 @@ _mesa_test_proxy_teximage(struct gl_context *ctx, GLenum target, GLint level, case GL_PROXY_TEXTURE_CUBE_MAP_ARB: maxSize = 1 << (ctx->Const.MaxCubeTextureLevels - 1); - if (width < 2 * border || width > 2 + maxSize) + if (width < 2 * border || width > maxSize) return GL_FALSE; - if (height < 2 * border || height > 2 + maxSize) + if (height < 2 * border || height > maxSize) return GL_FALSE; if (level >= ctx->Const.MaxCubeTextureLevels) return GL_FALSE; @@ -1253,7 +1253,7 @@ _mesa_test_proxy_teximage(struct gl_context *ctx, GLenum target, GLint level, case GL_PROXY_TEXTURE_1D_ARRAY_EXT: maxSize = 1 << (ctx->Const.MaxTextureLevels - 1); - if (width < 2 * border || width > 2 + maxSize) + if (width < 2 * border || width > maxSize) return GL_FALSE; if (height < 1 || height > ctx->Const.MaxArrayTextureLayers) return GL_FALSE; @@ -1267,9 +1267,9 @@ _mesa_test_proxy_teximage(struct gl_context *ctx, GLenum target, GLint level, case GL_PROXY_TEXTURE_2D_ARRAY_EXT: maxSize = 1 << (ctx->Const.MaxTextureLevels - 1); - if (width < 2 * border || width > 2 + maxSize) + if (width < 2 * border || width > maxSize) return GL_FALSE; - if (height < 2 * border || height > 2 + maxSize) + if (height < 2 * border || height > maxSize) return GL_FALSE; if (depth < 1 || depth > ctx->Const.MaxArrayTextureLayers) return GL_FALSE; diff --git a/mesalib/src/mesa/swrast/s_span.c b/mesalib/src/mesa/swrast/s_span.c index 28f2f3d3f..422d86c00 100644 --- a/mesalib/src/mesa/swrast/s_span.c +++ b/mesalib/src/mesa/swrast/s_span.c @@ -1321,12 +1321,23 @@ _swrast_write_rgba_span( struct gl_context *ctx, SWspan *span) if (rb) { GLchan rgbaSave[MAX_WIDTH][4]; - if (span->array->ChanType == GL_UNSIGNED_BYTE) { - span->array->rgba = span->array->rgba8; + GLenum datatype; + GLuint comps; + + _mesa_format_to_type_and_comps(rb->Format, &datatype, &comps); + + /* set span->array->rgba to colors for render buffer's datatype */ + if (datatype != span->array->ChanType) { + convert_color_type(span, datatype, 0); } else { - span->array->rgba = (void *) - span->array->attribs[FRAG_ATTRIB_COL0]; + if (span->array->ChanType == GL_UNSIGNED_BYTE) { + span->array->rgba = span->array->rgba8; + } + else { + span->array->rgba = (void *) + span->array->attribs[FRAG_ATTRIB_COL0]; + } } if (!multiFragOutputs && numBuffers > 1) { diff --git a/mesalib/src/mesa/vbo/vbo_exec_array.c b/mesalib/src/mesa/vbo/vbo_exec_array.c index 9861b21c9..d6b4d615c 100644 --- a/mesalib/src/mesa/vbo/vbo_exec_array.c +++ b/mesalib/src/mesa/vbo/vbo_exec_array.c @@ -1337,7 +1337,9 @@ vbo_exec_array_init( struct vbo_exec_context *exec ) exec->vtxfmt.DrawArraysInstanced = vbo_exec_DrawArraysInstanced; exec->vtxfmt.DrawElementsInstanced = vbo_exec_DrawElementsInstanced; exec->vtxfmt.DrawElementsInstancedBaseVertex = vbo_exec_DrawElementsInstancedBaseVertex; +#if FEATURE_EXT_transform_feedback exec->vtxfmt.DrawTransformFeedback = vbo_exec_DrawTransformFeedback; +#endif } diff --git a/mesalib/src/mesa/vbo/vbo_save_draw.c b/mesalib/src/mesa/vbo/vbo_save_draw.c index 9f0290561..b903757c0 100644 --- a/mesalib/src/mesa/vbo/vbo_save_draw.c +++ b/mesalib/src/mesa/vbo/vbo_save_draw.c @@ -191,7 +191,7 @@ static void vbo_bind_vertex_list(struct gl_context *ctx, save->inputs[attr] = &arrays[attr]; arrays[attr].Ptr = (const GLubyte *) NULL + buffer_offset; - arrays[attr].Size = node->attrsz[src]; + arrays[attr].Size = node_attrsz[src]; arrays[attr].StrideB = node->vertex_size * sizeof(GLfloat); arrays[attr].Stride = node->vertex_size * sizeof(GLfloat); arrays[attr].Type = GL_FLOAT; @@ -205,7 +205,7 @@ static void vbo_bind_vertex_list(struct gl_context *ctx, assert(arrays[attr].BufferObj->Name); - buffer_offset += node->attrsz[src] * sizeof(GLfloat); + buffer_offset += node_attrsz[src] * sizeof(GLfloat); varying_inputs |= VERT_BIT(attr); ctx->NewState |= _NEW_ARRAY; } |