diff options
author | marha <marha@users.sourceforge.net> | 2011-07-07 08:34:33 +0200 |
---|---|---|
committer | marha <marha@users.sourceforge.net> | 2011-07-07 08:34:33 +0200 |
commit | 47a6ae678489d7082b5d7da35d1a92b4233fb5eb (patch) | |
tree | bebaf8b6b97255c4363a6b4fc9499763c22dfb11 /mesalib | |
parent | 92c298bd203bf001b159752fe31ea701fbc0eae6 (diff) | |
download | vcxsrv-47a6ae678489d7082b5d7da35d1a92b4233fb5eb.tar.gz vcxsrv-47a6ae678489d7082b5d7da35d1a92b4233fb5eb.tar.bz2 vcxsrv-47a6ae678489d7082b5d7da35d1a92b4233fb5eb.zip |
mesa xkbcomp git update 7 Juli 2011
Diffstat (limited to 'mesalib')
-rw-r--r-- | mesalib/configure.ac | 22 | ||||
-rw-r--r-- | mesalib/src/glsl/Makefile | 426 | ||||
-rw-r--r-- | mesalib/src/glsl/ir_function.cpp | 2 | ||||
-rw-r--r-- | mesalib/src/glsl/ir_print_visitor.cpp | 10 | ||||
-rw-r--r-- | mesalib/src/glsl/linker.cpp | 108 | ||||
-rw-r--r-- | mesalib/src/glsl/opt_constant_propagation.cpp | 17 | ||||
-rw-r--r-- | mesalib/src/mesa/main/arbprogram.c | 229 | ||||
-rw-r--r-- | mesalib/src/mesa/main/feedback.c | 1084 | ||||
-rw-r--r-- | mesalib/src/mesa/main/texstore.c | 21 | ||||
-rw-r--r-- | mesalib/src/mesa/program/ir_to_mesa.cpp | 28 |
10 files changed, 995 insertions, 952 deletions
diff --git a/mesalib/configure.ac b/mesalib/configure.ac index 7d0f3d8ba..f19f6478b 100644 --- a/mesalib/configure.ac +++ b/mesalib/configure.ac @@ -570,6 +570,11 @@ AC_ARG_ENABLE([xorg], [enable support for X.Org DDX API @<:@default=no@:>@])], [enable_xorg="$enableval"], [enable_xorg=no]) +AC_ARG_ENABLE([xa], + [AS_HELP_STRING([--enable-xa], + [enable build of the XA X Acceleration API @<:@default=no@:>@])], + [enable_xa="$enableval"], + [enable_xa=no]) AC_ARG_ENABLE([d3d1x], [AS_HELP_STRING([--enable-d3d1x], [enable support for Direct3D 10 & 11 low-level API @<:@default=no@:>@])], @@ -617,6 +622,7 @@ if test "x$enable_opengl" = xno -a \ "x$enable_gles2" = xno -a \ "x$enable_openvg" = xno -a \ "x$enable_xorg" = xno -a \ + "x$enable_xa" = xno -a \ "x$enable_d3d1x" = xno; then AC_MSG_ERROR([at least one API should be enabled]) fi @@ -1422,6 +1428,14 @@ if test "x$enable_xorg" = xyes; then fi dnl +dnl XA configuration +dnl +if test "x$enable_xa" = xyes; then + GALLIUM_STATE_TRACKERS_DIRS="xa $GALLIUM_STATE_TRACKERS_DIRS" + HAVE_ST_XA=yes +fi + +dnl dnl OpenVG configuration dnl VG_LIB_DEPS="" @@ -1810,7 +1824,8 @@ dnl dnl Gallium helper functions dnl gallium_check_st() { - if test "x$HAVE_ST_DRI" = xyes || test "x$HAVE_ST_XORG" = xyes; then + if test "x$HAVE_ST_DRI" = xyes || test "x$HAVE_ST_XORG" = xyes || + test "x$HAVE_ST_XA" = xyes; then if test "x$have_libdrm" != xyes; then AC_MSG_ERROR([DRI or Xorg DDX requires libdrm >= $LIBDRM_REQUIRED]) fi @@ -1822,6 +1837,9 @@ gallium_check_st() { if test "x$HAVE_ST_XORG" = xyes && test "x$3" != x; then GALLIUM_TARGET_DIRS="$GALLIUM_TARGET_DIRS $3" fi + if test "x$HAVE_ST_XA" = xyes && test "x$4" != x; then + GALLIUM_TARGET_DIRS="$GALLIUM_TARGET_DIRS $4" + fi } gallium_require_llvm() { @@ -1842,7 +1860,7 @@ if test "x$with_gallium_drivers" != x; then for driver in $gallium_drivers; do case "x$driver" in xsvga) - gallium_check_st "svga/drm" "dri-vmwgfx" "xorg-vmwgfx" + gallium_check_st "svga/drm" "dri-vmwgfx" "xorg-vmwgfx" "xa-vmwgfx" ;; xi915) gallium_check_st "i915/drm" "dri-i915" "xorg-i915" diff --git a/mesalib/src/glsl/Makefile b/mesalib/src/glsl/Makefile index 2e379d84b..e0776c1b5 100644 --- a/mesalib/src/glsl/Makefile +++ b/mesalib/src/glsl/Makefile @@ -1,213 +1,213 @@ -
-#src/glsl/pp/Makefile
-
-TOP = ../..
-
-include $(TOP)/configs/current
-
-LIBNAME = glsl
-
-LIBGLCPP_SOURCES = \
- glcpp/glcpp-lex.c \
- glcpp/glcpp-parse.c \
- glcpp/pp.c
-
-GLCPP_SOURCES = \
- $(LIBGLCPP_SOURCES) \
- ralloc.c \
- glcpp/glcpp.c
-
-C_SOURCES = \
- strtod.c \
- ralloc.c \
- $(LIBGLCPP_SOURCES)
-
-CXX_SOURCES = \
- ast_expr.cpp \
- ast_function.cpp \
- ast_to_hir.cpp \
- ast_type.cpp \
- glsl_lexer.cpp \
- glsl_parser.cpp \
- glsl_parser_extras.cpp \
- glsl_types.cpp \
- glsl_symbol_table.cpp \
- hir_field_selection.cpp \
- ir_basic_block.cpp \
- ir_clone.cpp \
- ir_constant_expression.cpp \
- ir.cpp \
- ir_expression_flattening.cpp \
- ir_function_can_inline.cpp \
- ir_function.cpp \
- ir_hierarchical_visitor.cpp \
- ir_hv_accept.cpp \
- ir_import_prototypes.cpp \
- ir_print_visitor.cpp \
- ir_reader.cpp \
- ir_rvalue_visitor.cpp \
- ir_set_program_inouts.cpp \
- ir_validate.cpp \
- ir_variable.cpp \
- ir_variable_refcount.cpp \
- linker.cpp \
- link_functions.cpp \
- loop_analysis.cpp \
- loop_controls.cpp \
- loop_unroll.cpp \
- lower_discard.cpp \
- lower_if_to_cond_assign.cpp \
- lower_instructions.cpp \
- lower_jumps.cpp \
- lower_mat_op_to_vec.cpp \
- lower_noise.cpp \
- lower_texture_projection.cpp \
- lower_variable_index_to_cond_assign.cpp \
- lower_vec_index_to_cond_assign.cpp \
- lower_vec_index_to_swizzle.cpp \
- lower_vector.cpp \
- opt_algebraic.cpp \
- opt_constant_folding.cpp \
- opt_constant_propagation.cpp \
- opt_constant_variable.cpp \
- opt_copy_propagation.cpp \
- opt_copy_propagation_elements.cpp \
- opt_dead_code.cpp \
- opt_dead_code_local.cpp \
- opt_dead_functions.cpp \
- opt_discard_simplification.cpp \
- opt_function_inlining.cpp \
- opt_if_simplification.cpp \
- opt_noop_swizzle.cpp \
- opt_redundant_jumps.cpp \
- opt_structure_splitting.cpp \
- opt_swizzle_swizzle.cpp \
- opt_tree_grafting.cpp \
- s_expression.cpp
-
-LIBS = \
- $(TOP)/src/glsl/libglsl.a
-
-APPS = glsl_compiler glcpp/glcpp
-
-GLSL2_C_SOURCES = \
- ../mesa/program/hash_table.c \
- ../mesa/program/symbol_table.c
-GLSL2_CXX_SOURCES = \
- main.cpp
-
-GLSL2_OBJECTS = \
- $(GLSL2_C_SOURCES:.c=.o) \
- $(GLSL2_CXX_SOURCES:.cpp=.o)
-
-### Basic defines ###
-
-DEFINES += \
- $(LIBRARY_DEFINES) \
- $(API_DEFINES)
-
-GLCPP_OBJECTS = \
- $(GLCPP_SOURCES:.c=.o) \
- ../mesa/program/hash_table.o
-
-OBJECTS = \
- $(C_SOURCES:.c=.o) \
- $(CXX_SOURCES:.cpp=.o)
-
-DRICORE_OBJ_DIR = obj-visible
-OBJECTS_DRICORE = $(addprefix $(DRICORE_OBJ_DIR)/,$(OBJECTS))
-
-INCLUDES = \
- -I. \
- -I../mesa \
- -I../mapi \
- -I../../include \
- $(LIBRARY_INCLUDES)
-
-ALL_SOURCES = \
- $(C_SOURCES) \
- $(CXX_SOURCES) \
- $(GLSL2_CXX_SOURCES) \
- $(GLSL2_C_SOURCES)
-
-##### TARGETS #####
-
-default: depend lib$(LIBNAME).a $(APPS) $(DRICORE_GLSL_LIBS)
-
-$(TOP)/$(LIB_DIR)/libglsl.so: $(OBJECTS_DRICORE) builtin_function.o Makefile $(TOP)/src/glsl/Makefile.template
- $(MKLIB) -o $@ -linker '$(CXX)' -ldflags '$(LDFLAGS)' \
- -cplusplus -noprefix \
- -install $(TOP)/$(LIB_DIR) -id $(INSTALL_LIB_DIR)/$@.dylib \
- $(OBJECTS_DRICORE) builtin_function.o
-
-lib$(LIBNAME).a: $(OBJECTS) builtin_function.o Makefile $(TOP)/src/glsl/Makefile.template
- $(MKLIB) -cplusplus -o $(LIBNAME) -static $(OBJECTS) builtin_function.o
-
-depend: $(ALL_SOURCES) Makefile
- rm -f depend
- touch depend
- $(MKDEP) $(MKDEP_OPTIONS) $(INCLUDES) $(ALL_SOURCES) 2> /dev/null
-
-# Remove .o and backup files
-clean: clean-dricore
- rm -f $(GLCPP_OBJECTS) $(GLSL2_OBJECTS) $(OBJECTS) lib$(LIBNAME).a depend depend.bak builtin_function.cpp builtin_function.o builtin_stubs.o builtin_compiler
- -rm -f $(APPS)
-
-clean-dricore:
- -rm -f $(DRICORE_OBJ_DIR) $(TOP)/$(LIB_DIR)/libglsl.so libglsl.so
-
-ifneq (,$(DRICORE_GLSL_LIBS))
-DRICORE_INSTALL_TARGET = install-dricore
-endif
-
-# Dummy target
-install: $(DRICORE_INSTALL_TARGET)
- @echo -n ""
-
-install-dricore: default
- $(INSTALL) -d $(DESTDIR)$(DRI_DRIVER_INSTALL_DIR)
- $(INSTALL) -m 755 $(DRICORE_GLSL_LIBS) $(DESTDIR)$(DRI_DRIVER_INSTALL_DIR)
-
-##### RULES #####
-
-glsl_compiler: $(GLSL2_OBJECTS) libglsl.a builtin_stubs.o
- $(APP_CXX) $(INCLUDES) $(CFLAGS) $(LDFLAGS) $(GLSL2_OBJECTS) builtin_stubs.o $(LIBS) -o $@
-
-glcpp: glcpp/glcpp
-glcpp/glcpp: $(GLCPP_OBJECTS)
- $(APP_CC) $(INCLUDES) $(CFLAGS) $(LDFLAGS) $(GLCPP_OBJECTS) -o $@
-
-.cpp.o:
- $(CXX) -c $(INCLUDES) $(CXXFLAGS) $(DEFINES) $< -o $@
-
-.c.o:
- $(CC) -c $(INCLUDES) $(CFLAGS) $(DEFINES) $< -o $@
-
-$(DRICORE_OBJ_DIR)/%.o : %.cpp
- @mkdir -p $(dir $@)
- $(CXX) -c $(INCLUDES) $(DRI_CXXFLAGS) $(DEFINES) $< -o $@
-
-$(DRICORE_OBJ_DIR)/%.o : %.c
- @mkdir -p $(dir $@)
- $(CC) -c $(INCLUDES) $(DRI_CFLAGS) $(DEFINES) $< -o $@
-
-glsl_lexer.cpp: glsl_lexer.ll
- $(FLEX) --nounistd -o$@ $<
-
-glsl_parser.cpp: glsl_parser.yy
- $(BISON) -v -o "$@" -p "_mesa_glsl_" --defines=glsl_parser.h $<
-
-glcpp/glcpp-lex.c: glcpp/glcpp-lex.l
- $(FLEX) --nounistd -o$@ $<
-
-glcpp/glcpp-parse.c: glcpp/glcpp-parse.y
- $(BISON) -v -o "$@" --defines=glcpp/glcpp-parse.h $<
-
-builtin_compiler: $(GLSL2_OBJECTS) $(OBJECTS) builtin_stubs.o
- $(APP_CXX) $(INCLUDES) $(CXXFLAGS) $(LDFLAGS) $(OBJECTS) $(GLSL2_OBJECTS) builtin_stubs.o -o $@
-
-builtin_function.cpp: builtins/profiles/* builtins/ir/* builtins/tools/generate_builtins.py builtins/tools/texture_builtins.py builtin_compiler
- @echo Regenerating builtin_function.cpp...
- $(PYTHON2) $(PYTHON_FLAGS) builtins/tools/generate_builtins.py ./builtin_compiler > builtin_function.cpp || rm -f builtin_function.cpp
-
--include depend
+ +#src/glsl/pp/Makefile + +TOP = ../.. + +include $(TOP)/configs/current + +LIBNAME = glsl + +LIBGLCPP_SOURCES = \ + glcpp/glcpp-lex.c \ + glcpp/glcpp-parse.c \ + glcpp/pp.c + +GLCPP_SOURCES = \ + $(LIBGLCPP_SOURCES) \ + ralloc.c \ + glcpp/glcpp.c + +C_SOURCES = \ + strtod.c \ + ralloc.c \ + $(LIBGLCPP_SOURCES) + +CXX_SOURCES = \ + ast_expr.cpp \ + ast_function.cpp \ + ast_to_hir.cpp \ + ast_type.cpp \ + glsl_lexer.cpp \ + glsl_parser.cpp \ + glsl_parser_extras.cpp \ + glsl_types.cpp \ + glsl_symbol_table.cpp \ + hir_field_selection.cpp \ + ir_basic_block.cpp \ + ir_clone.cpp \ + ir_constant_expression.cpp \ + ir.cpp \ + ir_expression_flattening.cpp \ + ir_function_can_inline.cpp \ + ir_function.cpp \ + ir_hierarchical_visitor.cpp \ + ir_hv_accept.cpp \ + ir_import_prototypes.cpp \ + ir_print_visitor.cpp \ + ir_reader.cpp \ + ir_rvalue_visitor.cpp \ + ir_set_program_inouts.cpp \ + ir_validate.cpp \ + ir_variable.cpp \ + ir_variable_refcount.cpp \ + linker.cpp \ + link_functions.cpp \ + loop_analysis.cpp \ + loop_controls.cpp \ + loop_unroll.cpp \ + lower_discard.cpp \ + lower_if_to_cond_assign.cpp \ + lower_instructions.cpp \ + lower_jumps.cpp \ + lower_mat_op_to_vec.cpp \ + lower_noise.cpp \ + lower_texture_projection.cpp \ + lower_variable_index_to_cond_assign.cpp \ + lower_vec_index_to_cond_assign.cpp \ + lower_vec_index_to_swizzle.cpp \ + lower_vector.cpp \ + opt_algebraic.cpp \ + opt_constant_folding.cpp \ + opt_constant_propagation.cpp \ + opt_constant_variable.cpp \ + opt_copy_propagation.cpp \ + opt_copy_propagation_elements.cpp \ + opt_dead_code.cpp \ + opt_dead_code_local.cpp \ + opt_dead_functions.cpp \ + opt_discard_simplification.cpp \ + opt_function_inlining.cpp \ + opt_if_simplification.cpp \ + opt_noop_swizzle.cpp \ + opt_redundant_jumps.cpp \ + opt_structure_splitting.cpp \ + opt_swizzle_swizzle.cpp \ + opt_tree_grafting.cpp \ + s_expression.cpp + +LIBS = \ + $(TOP)/src/glsl/libglsl.a + +APPS = glsl_compiler glcpp/glcpp + +GLSL2_C_SOURCES = \ + ../mesa/program/hash_table.c \ + ../mesa/program/symbol_table.c +GLSL2_CXX_SOURCES = \ + main.cpp + +GLSL2_OBJECTS = \ + $(GLSL2_C_SOURCES:.c=.o) \ + $(GLSL2_CXX_SOURCES:.cpp=.o) + +### Basic defines ### + +DEFINES += \ + $(LIBRARY_DEFINES) \ + $(API_DEFINES) + +GLCPP_OBJECTS = \ + $(GLCPP_SOURCES:.c=.o) \ + ../mesa/program/hash_table.o + +OBJECTS = \ + $(C_SOURCES:.c=.o) \ + $(CXX_SOURCES:.cpp=.o) + +DRICORE_OBJ_DIR = obj-visible +OBJECTS_DRICORE = $(addprefix $(DRICORE_OBJ_DIR)/,$(OBJECTS)) + +INCLUDES = \ + -I. \ + -I../mesa \ + -I../mapi \ + -I../../include \ + $(LIBRARY_INCLUDES) + +ALL_SOURCES = \ + $(C_SOURCES) \ + $(CXX_SOURCES) \ + $(GLSL2_CXX_SOURCES) \ + $(GLSL2_C_SOURCES) + +##### TARGETS ##### + +default: depend lib$(LIBNAME).a $(APPS) $(DRICORE_GLSL_LIBS) + +$(TOP)/$(LIB_DIR)/libglsl.so: $(OBJECTS_DRICORE) builtin_function.o Makefile $(TOP)/src/glsl/Makefile.template + $(MKLIB) -o $@ -linker '$(CXX)' -ldflags '$(LDFLAGS)' \ + -cplusplus -noprefix \ + -install $(TOP)/$(LIB_DIR) -id $(INSTALL_LIB_DIR)/$@.dylib \ + $(OBJECTS_DRICORE) builtin_function.o + +lib$(LIBNAME).a: $(OBJECTS) builtin_function.o Makefile $(TOP)/src/glsl/Makefile.template + $(MKLIB) -cplusplus -o $(LIBNAME) -static $(OBJECTS) builtin_function.o + +depend: $(ALL_SOURCES) Makefile + rm -f depend + touch depend + $(MKDEP) $(MKDEP_OPTIONS) $(INCLUDES) $(ALL_SOURCES) 2> /dev/null + +# Remove .o and backup files +clean: clean-dricore + rm -f $(GLCPP_OBJECTS) $(GLSL2_OBJECTS) $(OBJECTS) lib$(LIBNAME).a depend depend.bak builtin_function.cpp builtin_function.o builtin_stubs.o builtin_compiler + -rm -f $(APPS) + +clean-dricore: + -rm -f $(OBJECTS_DRICORE) $(TOP)/$(LIB_DIR)/libglsl.so libglsl.so + +ifneq (,$(DRICORE_GLSL_LIBS)) +DRICORE_INSTALL_TARGET = install-dricore +endif + +# Dummy target +install: $(DRICORE_INSTALL_TARGET) + @echo -n "" + +install-dricore: default + $(INSTALL) -d $(DESTDIR)$(DRI_DRIVER_INSTALL_DIR) + $(INSTALL) -m 755 $(DRICORE_GLSL_LIBS) $(DESTDIR)$(DRI_DRIVER_INSTALL_DIR) + +##### RULES ##### + +glsl_compiler: $(GLSL2_OBJECTS) libglsl.a builtin_stubs.o + $(APP_CXX) $(INCLUDES) $(CFLAGS) $(LDFLAGS) $(GLSL2_OBJECTS) builtin_stubs.o $(LIBS) -o $@ + +glcpp: glcpp/glcpp +glcpp/glcpp: $(GLCPP_OBJECTS) + $(APP_CC) $(INCLUDES) $(CFLAGS) $(LDFLAGS) $(GLCPP_OBJECTS) -o $@ + +.cpp.o: + $(CXX) -c $(INCLUDES) $(CXXFLAGS) $(DEFINES) $< -o $@ + +.c.o: + $(CC) -c $(INCLUDES) $(CFLAGS) $(DEFINES) $< -o $@ + +$(DRICORE_OBJ_DIR)/%.o : %.cpp + @mkdir -p $(dir $@) + $(CXX) -c $(INCLUDES) $(DRI_CXXFLAGS) $(DEFINES) $< -o $@ + +$(DRICORE_OBJ_DIR)/%.o : %.c + @mkdir -p $(dir $@) + $(CC) -c $(INCLUDES) $(DRI_CFLAGS) $(DEFINES) $< -o $@ + +glsl_lexer.cpp: glsl_lexer.ll + $(FLEX) --nounistd -o$@ $< + +glsl_parser.cpp: glsl_parser.yy + $(BISON) -v -o "$@" -p "_mesa_glsl_" --defines=glsl_parser.h $< + +glcpp/glcpp-lex.c: glcpp/glcpp-lex.l + $(FLEX) --nounistd -o$@ $< + +glcpp/glcpp-parse.c: glcpp/glcpp-parse.y + $(BISON) -v -o "$@" --defines=glcpp/glcpp-parse.h $< + +builtin_compiler: $(GLSL2_OBJECTS) $(OBJECTS) builtin_stubs.o + $(APP_CXX) $(INCLUDES) $(CXXFLAGS) $(LDFLAGS) $(OBJECTS) $(GLSL2_OBJECTS) builtin_stubs.o -o $@ + +builtin_function.cpp: builtins/profiles/* builtins/ir/* builtins/tools/generate_builtins.py builtins/tools/texture_builtins.py builtin_compiler + @echo Regenerating builtin_function.cpp... + $(PYTHON2) $(PYTHON_FLAGS) builtins/tools/generate_builtins.py ./builtin_compiler > builtin_function.cpp || rm -f builtin_function.cpp + +-include depend diff --git a/mesalib/src/glsl/ir_function.cpp b/mesalib/src/glsl/ir_function.cpp index ef8d4fcfc..1255072a5 100644 --- a/mesalib/src/glsl/ir_function.cpp +++ b/mesalib/src/glsl/ir_function.cpp @@ -165,7 +165,7 @@ ir_function_signature * ir_function::matching_signature(const exec_list *actual_parameters) { ir_function_signature *match = NULL; - int matched_score; + int matched_score = 0; foreach_iter(exec_list_iterator, iter, signatures) { ir_function_signature *const sig = diff --git a/mesalib/src/glsl/ir_print_visitor.cpp b/mesalib/src/glsl/ir_print_visitor.cpp index 5b5409daa..518910bd1 100644 --- a/mesalib/src/glsl/ir_print_visitor.cpp +++ b/mesalib/src/glsl/ir_print_visitor.cpp @@ -96,6 +96,16 @@ void ir_print_visitor::indent(void) const char * ir_print_visitor::unique_name(ir_variable *var) { + /* var->name can be NULL in function prototypes when a type is given for a + * parameter but no name is given. In that case, just return an empty + * string. Don't worry about tracking the generated name in the printable + * names hash because this is the only scope where it can ever appear. + */ + if (var->name == NULL) { + static unsigned arg = 1; + return ralloc_asprintf(this->mem_ctx, "parameter@%u", arg++); + } + /* Do we already have a name for this variable? */ const char *name = (const char *) hash_table_find(this->printable_names, var); if (name != NULL) diff --git a/mesalib/src/glsl/linker.cpp b/mesalib/src/glsl/linker.cpp index b6479e7a3..265da84e5 100644 --- a/mesalib/src/glsl/linker.cpp +++ b/mesalib/src/glsl/linker.cpp @@ -1194,16 +1194,43 @@ find_available_slots(unsigned used_mask, unsigned needed_count) } +/** + * Assign locations for either VS inputs for FS outputs + * + * \param prog Shader program whose variables need locations assigned + * \param target_index Selector for the program target to receive location + * assignmnets. Must be either \c MESA_SHADER_VERTEX or + * \c MESA_SHADER_FRAGMENT. + * \param max_index Maximum number of generic locations. This corresponds + * to either the maximum number of draw buffers or the + * maximum number of generic attributes. + * + * \return + * If locations are successfully assigned, true is returned. Otherwise an + * error is emitted to the shader link log and false is returned. + * + * \bug + * Locations set via \c glBindFragDataLocation are not currently supported. + * Only locations assigned automatically by the linker, explicitly set by a + * layout qualifier, or explicitly set by a built-in variable (e.g., \c + * gl_FragColor) are supported for fragment shaders. + */ bool -assign_attribute_locations(gl_shader_program *prog, unsigned max_attribute_index) +assign_attribute_or_color_locations(gl_shader_program *prog, + unsigned target_index, + unsigned max_index) { - /* Mark invalid attribute locations as being used. + /* Mark invalid locations as being used. */ - unsigned used_locations = (max_attribute_index >= 32) - ? ~0 : ~((1 << max_attribute_index) - 1); + unsigned used_locations = (max_index >= 32) + ? ~0 : ~((1 << max_index) - 1); - gl_shader *const sh = prog->_LinkedShaders[0]; - assert(sh->Type == GL_VERTEX_SHADER); + assert((target_index == MESA_SHADER_VERTEX) + || (target_index == MESA_SHADER_FRAGMENT)); + + gl_shader *const sh = prog->_LinkedShaders[target_index]; + if (sh == NULL) + return true; /* Operate in a total of four passes. * @@ -1220,9 +1247,16 @@ assign_attribute_locations(gl_shader_program *prog, unsigned max_attribute_index * 4. Assign locations to any inputs without assigned locations. */ - invalidate_variable_locations(sh, ir_var_in, VERT_ATTRIB_GENERIC0); + const int generic_base = (target_index == MESA_SHADER_VERTEX) + ? VERT_ATTRIB_GENERIC0 : FRAG_RESULT_DATA0; + + const enum ir_variable_mode direction = + (target_index == MESA_SHADER_VERTEX) ? ir_var_in : ir_var_out; + - if (prog->Attributes != NULL) { + invalidate_variable_locations(sh, direction, generic_base); + + if ((target_index == MESA_SHADER_VERTEX) && (prog->Attributes != NULL)) { for (unsigned i = 0; i < prog->Attributes->NumParameters; i++) { ir_variable *const var = sh->symbols->get_variable(prog->Attributes->Parameters[i].Name); @@ -1309,15 +1343,15 @@ assign_attribute_locations(gl_shader_program *prog, unsigned max_attribute_index foreach_list(node, sh->ir) { ir_variable *const var = ((ir_instruction *) node)->as_variable(); - if ((var == NULL) || (var->mode != ir_var_in)) + if ((var == NULL) || (var->mode != direction)) continue; if (var->explicit_location) { const unsigned slots = count_attribute_slots(var->type); const unsigned use_mask = (1 << slots) - 1; - const int attr = var->location - VERT_ATTRIB_GENERIC0; + const int attr = var->location - generic_base; - if ((var->location >= (int)(max_attribute_index + VERT_ATTRIB_GENERIC0)) + if ((var->location >= (int)(max_index + generic_base)) || (var->location < 0)) { linker_error_printf(prog, "invalid explicit location %d specified for " @@ -1325,7 +1359,7 @@ assign_attribute_locations(gl_shader_program *prog, unsigned max_attribute_index (var->location < 0) ? var->location : attr, var->name); return false; - } else if (var->location >= VERT_ATTRIB_GENERIC0) { + } else if (var->location >= generic_base) { used_locations |= (use_mask << attr); } } @@ -1349,14 +1383,16 @@ assign_attribute_locations(gl_shader_program *prog, unsigned max_attribute_index qsort(to_assign, num_attr, sizeof(to_assign[0]), temp_attr::compare); - /* VERT_ATTRIB_GENERIC0 is a pseudo-alias for VERT_ATTRIB_POS. It can only - * be explicitly assigned by via glBindAttribLocation. Mark it as reserved - * to prevent it from being automatically allocated below. - */ - find_deref_visitor find("gl_Vertex"); - find.run(sh->ir); - if (find.variable_found()) - used_locations |= (1 << 0); + if (target_index == MESA_SHADER_VERTEX) { + /* VERT_ATTRIB_GENERIC0 is a pseudo-alias for VERT_ATTRIB_POS. It can + * only be explicitly assigned by via glBindAttribLocation. Mark it as + * reserved to prevent it from being automatically allocated below. + */ + find_deref_visitor find("gl_Vertex"); + find.run(sh->ir); + if (find.variable_found()) + used_locations |= (1 << 0); + } for (unsigned i = 0; i < num_attr; i++) { /* Mask representing the contiguous slots that will be used by this @@ -1367,14 +1403,17 @@ assign_attribute_locations(gl_shader_program *prog, unsigned max_attribute_index int location = find_available_slots(used_locations, to_assign[i].slots); if (location < 0) { + const char *const string = (target_index == MESA_SHADER_VERTEX) + ? "vertex shader input" : "fragment shader output"; + linker_error_printf(prog, "insufficient contiguous attribute locations " - "available for vertex shader input `%s'", - to_assign[i].var->name); + "available for %s `%s'", + string, to_assign[i].var->name); return false; } - to_assign[i].var->location = VERT_ATTRIB_GENERIC0 + location; + to_assign[i].var->location = generic_base + location; used_locations |= (use_mask << location); } @@ -1671,16 +1710,19 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog) assign_uniform_locations(prog); - if (prog->_LinkedShaders[MESA_SHADER_VERTEX] != NULL) { - /* FINISHME: The value of the max_attribute_index parameter is - * FINISHME: implementation dependent based on the value of - * FINISHME: GL_MAX_VERTEX_ATTRIBS. GL_MAX_VERTEX_ATTRIBS must be - * FINISHME: at least 16, so hardcode 16 for now. - */ - if (!assign_attribute_locations(prog, 16)) { - prog->LinkStatus = false; - goto done; - } + /* FINISHME: The value of the max_attribute_index parameter is + * FINISHME: implementation dependent based on the value of + * FINISHME: GL_MAX_VERTEX_ATTRIBS. GL_MAX_VERTEX_ATTRIBS must be + * FINISHME: at least 16, so hardcode 16 for now. + */ + if (!assign_attribute_or_color_locations(prog, MESA_SHADER_VERTEX, 16)) { + prog->LinkStatus = false; + goto done; + } + + if (!assign_attribute_or_color_locations(prog, MESA_SHADER_FRAGMENT, ctx->Const.MaxDrawBuffers)) { + prog->LinkStatus = false; + goto done; } unsigned prev; diff --git a/mesalib/src/glsl/opt_constant_propagation.cpp b/mesalib/src/glsl/opt_constant_propagation.cpp index 4425f4211..af77e4906 100644 --- a/mesalib/src/glsl/opt_constant_propagation.cpp +++ b/mesalib/src/glsl/opt_constant_propagation.cpp @@ -51,11 +51,23 @@ public: this->var = var; this->write_mask = write_mask; this->constant = constant; + this->initial_values = write_mask; + } + + acp_entry(const acp_entry *src) + { + this->var = src->var; + this->write_mask = src->write_mask; + this->constant = src->constant; + this->initial_values = src->initial_values; } ir_variable *var; ir_constant *constant; unsigned write_mask; + + /** Mask of values initially available in the constant. */ + unsigned initial_values; }; @@ -172,7 +184,7 @@ ir_constant_propagation_visitor::handle_rvalue(ir_rvalue **rvalue) for (int j = 0; j < 4; j++) { if (j == channel) break; - if (found->write_mask & (1 << j)) + if (found->initial_values & (1 << j)) rhs_channel++; } @@ -285,8 +297,7 @@ ir_constant_propagation_visitor::handle_if_block(exec_list *instructions) /* 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(); - this->acp->push_tail(new(this->mem_ctx) acp_entry(a->var, a->write_mask, - a->constant)); + this->acp->push_tail(new(this->mem_ctx) acp_entry(a)); } visit_list_elements(this, instructions); diff --git a/mesalib/src/mesa/main/arbprogram.c b/mesalib/src/mesa/main/arbprogram.c index 26d781954..b83369d9e 100644 --- a/mesalib/src/mesa/main/arbprogram.c +++ b/mesalib/src/mesa/main/arbprogram.c @@ -269,6 +269,71 @@ _mesa_IsProgramARB(GLuint id) return GL_FALSE; } +static GLboolean +get_local_param_pointer(struct gl_context *ctx, const char *func, + GLenum target, GLuint index, GLfloat **param) +{ + struct gl_program *prog; + GLuint maxParams; + + if (target == GL_VERTEX_PROGRAM_ARB + && ctx->Extensions.ARB_vertex_program) { + prog = &(ctx->VertexProgram.Current->Base); + maxParams = ctx->Const.VertexProgram.MaxLocalParams; + } + else if (target == GL_FRAGMENT_PROGRAM_ARB + && ctx->Extensions.ARB_fragment_program) { + prog = &(ctx->FragmentProgram.Current->Base); + maxParams = ctx->Const.FragmentProgram.MaxLocalParams; + } + else if (target == GL_FRAGMENT_PROGRAM_NV + && ctx->Extensions.NV_fragment_program) { + prog = &(ctx->FragmentProgram.Current->Base); + maxParams = MAX_NV_FRAGMENT_PROGRAM_PARAMS; + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, + "%s(target)", func); + return GL_FALSE; + } + + if (index >= maxParams) { + _mesa_error(ctx, GL_INVALID_VALUE, "%s(index)", func); + return GL_FALSE; + } + + *param = prog->LocalParams[index]; + return GL_TRUE; +} + + +static GLboolean +get_env_param_pointer(struct gl_context *ctx, const char *func, + GLenum target, GLuint index, GLfloat **param) +{ + if (target == GL_FRAGMENT_PROGRAM_ARB + && ctx->Extensions.ARB_fragment_program) { + if (index >= ctx->Const.FragmentProgram.MaxEnvParams) { + _mesa_error(ctx, GL_INVALID_VALUE, "%s(index)", func); + return GL_FALSE; + } + *param = ctx->FragmentProgram.Parameters[index]; + return GL_TRUE; + } + else if (target == GL_VERTEX_PROGRAM_ARB && + (ctx->Extensions.ARB_vertex_program || + ctx->Extensions.NV_vertex_program)) { + if (index >= ctx->Const.VertexProgram.MaxEnvParams) { + _mesa_error(ctx, GL_INVALID_VALUE, "%s(index)", func); + return GL_FALSE; + } + *param = ctx->VertexProgram.Parameters[index]; + return GL_TRUE; + } else { + _mesa_error(ctx, GL_INVALID_ENUM, "%s(target)", func); + return GL_FALSE; + } +} void GLAPIENTRY _mesa_ProgramStringARB(GLenum target, GLenum format, GLsizei len, @@ -383,30 +448,16 @@ void GLAPIENTRY _mesa_ProgramEnvParameter4fARB(GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w) { + GLfloat *param; + GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END(ctx); FLUSH_VERTICES(ctx, _NEW_PROGRAM_CONSTANTS); - if (target == GL_FRAGMENT_PROGRAM_ARB - && ctx->Extensions.ARB_fragment_program) { - if (index >= ctx->Const.FragmentProgram.MaxEnvParams) { - _mesa_error(ctx, GL_INVALID_VALUE, "glProgramEnvParameter(index)"); - return; - } - ASSIGN_4V(ctx->FragmentProgram.Parameters[index], x, y, z, w); - } - else if (target == GL_VERTEX_PROGRAM_ARB /* == GL_VERTEX_PROGRAM_NV */ - && (ctx->Extensions.ARB_vertex_program || ctx->Extensions.NV_vertex_program)) { - if (index >= ctx->Const.VertexProgram.MaxEnvParams) { - _mesa_error(ctx, GL_INVALID_VALUE, "glProgramEnvParameter(index)"); - return; - } - ASSIGN_4V(ctx->VertexProgram.Parameters[index], x, y, z, w); - } - else { - _mesa_error(ctx, GL_INVALID_ENUM, "glProgramEnvParameter(target)"); - return; + if (get_env_param_pointer(ctx, "glProgramEnvParameter", + target, index, ¶m)) { + ASSIGN_4V(param, x, y, z, w); } } @@ -422,32 +473,16 @@ void GLAPIENTRY _mesa_ProgramEnvParameter4fvARB(GLenum target, GLuint index, const GLfloat *params) { + GLfloat *param; + GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END(ctx); FLUSH_VERTICES(ctx, _NEW_PROGRAM_CONSTANTS); - if (target == GL_FRAGMENT_PROGRAM_ARB - && ctx->Extensions.ARB_fragment_program) { - if (index >= ctx->Const.FragmentProgram.MaxEnvParams) { - _mesa_error(ctx, GL_INVALID_VALUE, "glProgramEnvParameter4fv(index)"); - return; - } - memcpy(ctx->FragmentProgram.Parameters[index], params, - 4 * sizeof(GLfloat)); - } - else if (target == GL_VERTEX_PROGRAM_ARB /* == GL_VERTEX_PROGRAM_NV */ - && (ctx->Extensions.ARB_vertex_program || ctx->Extensions.NV_vertex_program)) { - if (index >= ctx->Const.VertexProgram.MaxEnvParams) { - _mesa_error(ctx, GL_INVALID_VALUE, "glProgramEnvParameter4fv(index)"); - return; - } - memcpy(ctx->VertexProgram.Parameters[index], params, - 4 * sizeof(GLfloat)); - } - else { - _mesa_error(ctx, GL_INVALID_ENUM, "glProgramEnvParameter4fv(target)"); - return; + if (get_env_param_pointer(ctx, "glProgramEnvParameter4fv", + target, index, ¶m)) { + memcpy(param, params, 4 * sizeof(GLfloat)); } } @@ -496,14 +531,11 @@ _mesa_GetProgramEnvParameterdvARB(GLenum target, GLuint index, GLdouble *params) { GET_CURRENT_CONTEXT(ctx); - GLfloat fparams[4]; + GLfloat *fparam; - _mesa_GetProgramEnvParameterfvARB(target, index, fparams); - if (ctx->ErrorValue == GL_NO_ERROR) { - params[0] = fparams[0]; - params[1] = fparams[1]; - params[2] = fparams[2]; - params[3] = fparams[3]; + if (get_env_param_pointer(ctx, "glGetProgramEnvParameterdv", + target, index, &fparam)) { + COPY_4V(params, fparam); } } @@ -512,29 +544,15 @@ void GLAPIENTRY _mesa_GetProgramEnvParameterfvARB(GLenum target, GLuint index, GLfloat *params) { + GLfloat *param; + GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END(ctx); - if (target == GL_FRAGMENT_PROGRAM_ARB - && ctx->Extensions.ARB_fragment_program) { - if (index >= ctx->Const.FragmentProgram.MaxEnvParams) { - _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramEnvParameter(index)"); - return; - } - COPY_4V(params, ctx->FragmentProgram.Parameters[index]); - } - else if (target == GL_VERTEX_PROGRAM_ARB - && ctx->Extensions.ARB_vertex_program) { - if (index >= ctx->Const.VertexProgram.MaxEnvParams) { - _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramEnvParameter(index)"); - return; - } - COPY_4V(params, ctx->VertexProgram.Parameters[index]); - } - else { - _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramEnvParameter(target)"); - return; + if (get_env_param_pointer(ctx, "glGetProgramEnvParameterfv", + target, index, ¶m)) { + COPY_4V(params, param); } } @@ -547,39 +565,16 @@ _mesa_ProgramLocalParameter4fARB(GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w) { GET_CURRENT_CONTEXT(ctx); - struct gl_program *prog; + GLfloat *param; ASSERT_OUTSIDE_BEGIN_END(ctx); FLUSH_VERTICES(ctx, _NEW_PROGRAM_CONSTANTS); - if ((target == GL_FRAGMENT_PROGRAM_NV - && ctx->Extensions.NV_fragment_program) || - (target == GL_FRAGMENT_PROGRAM_ARB - && ctx->Extensions.ARB_fragment_program)) { - if (index >= ctx->Const.FragmentProgram.MaxLocalParams) { - _mesa_error(ctx, GL_INVALID_VALUE, "glProgramLocalParameterARB"); - return; - } - prog = &(ctx->FragmentProgram.Current->Base); - } - else if (target == GL_VERTEX_PROGRAM_ARB - && ctx->Extensions.ARB_vertex_program) { - if (index >= ctx->Const.VertexProgram.MaxLocalParams) { - _mesa_error(ctx, GL_INVALID_VALUE, "glProgramLocalParameterARB"); - return; - } - prog = &(ctx->VertexProgram.Current->Base); + if (get_local_param_pointer(ctx, "glProgramLocalParameterARB", + target, index, ¶m)) { + ASSERT(index < MAX_PROGRAM_LOCAL_PARAMS); + ASSIGN_4V(param, x, y, z, w); } - else { - _mesa_error(ctx, GL_INVALID_ENUM, "glProgramLocalParameterARB"); - return; - } - - ASSERT(index < MAX_PROGRAM_LOCAL_PARAMS); - prog->LocalParams[index][0] = x; - prog->LocalParams[index][1] = y; - prog->LocalParams[index][2] = z; - prog->LocalParams[index][3] = w; } @@ -667,41 +662,14 @@ void GLAPIENTRY _mesa_GetProgramLocalParameterfvARB(GLenum target, GLuint index, GLfloat *params) { - const struct gl_program *prog; - GLuint maxParams; + GLfloat *param; GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END(ctx); - if (target == GL_VERTEX_PROGRAM_ARB - && ctx->Extensions.ARB_vertex_program) { - prog = &(ctx->VertexProgram.Current->Base); - maxParams = ctx->Const.VertexProgram.MaxLocalParams; - } - else if (target == GL_FRAGMENT_PROGRAM_ARB - && ctx->Extensions.ARB_fragment_program) { - prog = &(ctx->FragmentProgram.Current->Base); - maxParams = ctx->Const.FragmentProgram.MaxLocalParams; - } - else if (target == GL_FRAGMENT_PROGRAM_NV - && ctx->Extensions.NV_fragment_program) { - prog = &(ctx->FragmentProgram.Current->Base); - maxParams = MAX_NV_FRAGMENT_PROGRAM_PARAMS; - } - else { - _mesa_error(ctx, GL_INVALID_ENUM, - "glGetProgramLocalParameterARB(target)"); - return; - } - - if (index >= maxParams) { - _mesa_error(ctx, GL_INVALID_VALUE, - "glGetProgramLocalParameterARB(index)"); - return; + if (get_local_param_pointer(ctx, "glProgramLocalParameters4fvEXT", + target, index, ¶m)) { + COPY_4V(params, param); } - - ASSERT(prog); - ASSERT(index < MAX_PROGRAM_LOCAL_PARAMS); - COPY_4V(params, prog->LocalParams[index]); } @@ -712,12 +680,13 @@ void GLAPIENTRY _mesa_GetProgramLocalParameterdvARB(GLenum target, GLuint index, GLdouble *params) { + GLfloat *param; GET_CURRENT_CONTEXT(ctx); - GLfloat floatParams[4]; - ASSIGN_4V(floatParams, 0.0F, 0.0F, 0.0F, 0.0F); - _mesa_GetProgramLocalParameterfvARB(target, index, floatParams); - if (ctx->ErrorValue == GL_NO_ERROR) { - COPY_4V(params, floatParams); + ASSERT_OUTSIDE_BEGIN_END(ctx); + + if (get_local_param_pointer(ctx, "glProgramLocalParameters4fvEXT", + target, index, ¶m)) { + COPY_4V(params, param); } } diff --git a/mesalib/src/mesa/main/feedback.c b/mesalib/src/mesa/main/feedback.c index 80565c62c..597ec1e3f 100644 --- a/mesalib/src/mesa/main/feedback.c +++ b/mesalib/src/mesa/main/feedback.c @@ -1,542 +1,542 @@ -/*
- * Mesa 3-D graphics library
- * Version: 7.5
- *
- * Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
- * Copyright (C) 2009 VMware, Inc. All Rights Reserved.
- *
- * 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 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
- * BRIAN PAUL 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.
- */
-
-/**
- * \file feedback.c
- * Selection and feedback modes functions.
- */
-
-
-#include "glheader.h"
-#include "colormac.h"
-#include "context.h"
-#include "enums.h"
-#include "feedback.h"
-#include "macros.h"
-#include "mfeatures.h"
-#include "mtypes.h"
-#include "main/dispatch.h"
-
-
-#if FEATURE_feedback
-
-
-#define FB_3D 0x01
-#define FB_4D 0x02
-#define FB_COLOR 0x04
-#define FB_TEXTURE 0X08
-
-
-
-static void GLAPIENTRY
-_mesa_FeedbackBuffer( GLsizei size, GLenum type, GLfloat *buffer )
-{
- GET_CURRENT_CONTEXT(ctx);
- ASSERT_OUTSIDE_BEGIN_END(ctx);
-
- if (ctx->RenderMode==GL_FEEDBACK) {
- _mesa_error( ctx, GL_INVALID_OPERATION, "glFeedbackBuffer" );
- return;
- }
- if (size<0) {
- _mesa_error( ctx, GL_INVALID_VALUE, "glFeedbackBuffer(size<0)" );
- return;
- }
- if (!buffer) {
- _mesa_error( ctx, GL_INVALID_VALUE, "glFeedbackBuffer(buffer==NULL)" );
- ctx->Feedback.BufferSize = 0;
- return;
- }
-
- switch (type) {
- case GL_2D:
- ctx->Feedback._Mask = 0;
- break;
- case GL_3D:
- ctx->Feedback._Mask = FB_3D;
- break;
- case GL_3D_COLOR:
- ctx->Feedback._Mask = (FB_3D | FB_COLOR);
- break;
- case GL_3D_COLOR_TEXTURE:
- ctx->Feedback._Mask = (FB_3D | FB_COLOR | FB_TEXTURE);
- break;
- case GL_4D_COLOR_TEXTURE:
- ctx->Feedback._Mask = (FB_3D | FB_4D | FB_COLOR | FB_TEXTURE);
- break;
- default:
- _mesa_error( ctx, GL_INVALID_ENUM, "glFeedbackBuffer" );
- return;
- }
-
- FLUSH_VERTICES(ctx, _NEW_RENDERMODE); /* Always flush */
- ctx->Feedback.Type = type;
- ctx->Feedback.BufferSize = size;
- ctx->Feedback.Buffer = buffer;
- ctx->Feedback.Count = 0; /* Becaues of this. */
-}
-
-
-static void GLAPIENTRY
-_mesa_PassThrough( GLfloat token )
-{
- GET_CURRENT_CONTEXT(ctx);
- ASSERT_OUTSIDE_BEGIN_END(ctx);
-
- if (ctx->RenderMode==GL_FEEDBACK) {
- FLUSH_VERTICES(ctx, 0);
- _mesa_feedback_token( ctx, (GLfloat) (GLint) GL_PASS_THROUGH_TOKEN );
- _mesa_feedback_token( ctx, token );
- }
-}
-
-
-/**
- * Put a vertex into the feedback buffer.
- */
-void
-_mesa_feedback_vertex(struct gl_context *ctx,
- const GLfloat win[4],
- const GLfloat color[4],
- const GLfloat texcoord[4])
-{
- _mesa_feedback_token( ctx, win[0] );
- _mesa_feedback_token( ctx, win[1] );
- if (ctx->Feedback._Mask & FB_3D) {
- _mesa_feedback_token( ctx, win[2] );
- }
- if (ctx->Feedback._Mask & FB_4D) {
- _mesa_feedback_token( ctx, win[3] );
- }
- if (ctx->Feedback._Mask & FB_COLOR) {
- _mesa_feedback_token( ctx, color[0] );
- _mesa_feedback_token( ctx, color[1] );
- _mesa_feedback_token( ctx, color[2] );
- _mesa_feedback_token( ctx, color[3] );
- }
- if (ctx->Feedback._Mask & FB_TEXTURE) {
- _mesa_feedback_token( ctx, texcoord[0] );
- _mesa_feedback_token( ctx, texcoord[1] );
- _mesa_feedback_token( ctx, texcoord[2] );
- _mesa_feedback_token( ctx, texcoord[3] );
- }
-}
-
-
-/**********************************************************************/
-/** \name Selection */
-/*@{*/
-
-/**
- * Establish a buffer for selection mode values.
- *
- * \param size buffer size.
- * \param buffer buffer.
- *
- * \sa glSelectBuffer().
- *
- * \note this function can't be put in a display list.
- *
- * Verifies we're not in selection mode, flushes the vertices and initialize
- * the fields in __struct gl_contextRec::Select with the given buffer.
- */
-static void GLAPIENTRY
-_mesa_SelectBuffer( GLsizei size, GLuint *buffer )
-{
- GET_CURRENT_CONTEXT(ctx);
- ASSERT_OUTSIDE_BEGIN_END(ctx);
-
- if (ctx->RenderMode==GL_SELECT) {
- _mesa_error( ctx, GL_INVALID_OPERATION, "glSelectBuffer" );
- return; /* KW: added return */
- }
-
- FLUSH_VERTICES(ctx, _NEW_RENDERMODE);
- ctx->Select.Buffer = buffer;
- ctx->Select.BufferSize = size;
- ctx->Select.BufferCount = 0;
- ctx->Select.HitFlag = GL_FALSE;
- ctx->Select.HitMinZ = 1.0;
- ctx->Select.HitMaxZ = 0.0;
-}
-
-
-/**
- * Write a value of a record into the selection buffer.
- *
- * \param ctx GL context.
- * \param value value.
- *
- * Verifies there is free space in the buffer to write the value and
- * increments the pointer.
- */
-static INLINE void
-write_record(struct gl_context *ctx, GLuint value)
-{
- if (ctx->Select.BufferCount < ctx->Select.BufferSize) {
- ctx->Select.Buffer[ctx->Select.BufferCount] = value;
- }
- ctx->Select.BufferCount++;
-}
-
-
-/**
- * Update the hit flag and the maximum and minimum depth values.
- *
- * \param ctx GL context.
- * \param z depth.
- *
- * Sets gl_selection::HitFlag and updates gl_selection::HitMinZ and
- * gl_selection::HitMaxZ.
- */
-void
-_mesa_update_hitflag(struct gl_context *ctx, GLfloat z)
-{
- ctx->Select.HitFlag = GL_TRUE;
- if (z < ctx->Select.HitMinZ) {
- ctx->Select.HitMinZ = z;
- }
- if (z > ctx->Select.HitMaxZ) {
- ctx->Select.HitMaxZ = z;
- }
-}
-
-
-/**
- * Write the hit record.
- *
- * \param ctx GL context.
- *
- * Write the hit record, i.e., the number of names in the stack, the minimum and
- * maximum depth values and the number of names in the name stack at the time
- * of the event. Resets the hit flag.
- *
- * \sa gl_selection.
- */
-static void
-write_hit_record(struct gl_context *ctx)
-{
- GLuint i;
- GLuint zmin, zmax, zscale = (~0u);
-
- /* HitMinZ and HitMaxZ are in [0,1]. Multiply these values by */
- /* 2^32-1 and round to nearest unsigned integer. */
-
- assert( ctx != NULL ); /* this line magically fixes a SunOS 5.x/gcc bug */
- zmin = (GLuint) ((GLfloat) zscale * ctx->Select.HitMinZ);
- zmax = (GLuint) ((GLfloat) zscale * ctx->Select.HitMaxZ);
-
- write_record( ctx, ctx->Select.NameStackDepth );
- write_record( ctx, zmin );
- write_record( ctx, zmax );
- for (i = 0; i < ctx->Select.NameStackDepth; i++) {
- write_record( ctx, ctx->Select.NameStack[i] );
- }
-
- ctx->Select.Hits++;
- ctx->Select.HitFlag = GL_FALSE;
- ctx->Select.HitMinZ = 1.0;
- ctx->Select.HitMaxZ = -1.0;
-}
-
-
-/**
- * Initialize the name stack.
- *
- * Verifies we are in select mode and resets the name stack depth and resets
- * the hit record data in gl_selection. Marks new render mode in
- * __struct gl_contextRec::NewState.
- */
-static void GLAPIENTRY
-_mesa_InitNames( void )
-{
- GET_CURRENT_CONTEXT(ctx);
- ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
-
- /* Record the hit before the HitFlag is wiped out again. */
- if (ctx->RenderMode == GL_SELECT) {
- if (ctx->Select.HitFlag) {
- write_hit_record( ctx );
- }
- }
- ctx->Select.NameStackDepth = 0;
- ctx->Select.HitFlag = GL_FALSE;
- ctx->Select.HitMinZ = 1.0;
- ctx->Select.HitMaxZ = 0.0;
- ctx->NewState |= _NEW_RENDERMODE;
-}
-
-
-/**
- * Load the top-most name of the name stack.
- *
- * \param name name.
- *
- * Verifies we are in selection mode and that the name stack is not empty.
- * Flushes vertices. If there is a hit flag writes it (via write_hit_record()),
- * and replace the top-most name in the stack.
- *
- * sa __struct gl_contextRec::Select.
- */
-static void GLAPIENTRY
-_mesa_LoadName( GLuint name )
-{
- GET_CURRENT_CONTEXT(ctx);
- ASSERT_OUTSIDE_BEGIN_END(ctx);
-
- if (ctx->RenderMode != GL_SELECT) {
- return;
- }
- if (ctx->Select.NameStackDepth == 0) {
- _mesa_error( ctx, GL_INVALID_OPERATION, "glLoadName" );
- return;
- }
-
- FLUSH_VERTICES(ctx, _NEW_RENDERMODE);
-
- if (ctx->Select.HitFlag) {
- write_hit_record( ctx );
- }
- if (ctx->Select.NameStackDepth < MAX_NAME_STACK_DEPTH) {
- ctx->Select.NameStack[ctx->Select.NameStackDepth-1] = name;
- }
- else {
- ctx->Select.NameStack[MAX_NAME_STACK_DEPTH-1] = name;
- }
-}
-
-
-/**
- * Push a name into the name stack.
- *
- * \param name name.
- *
- * Verifies we are in selection mode and that the name stack is not full.
- * Flushes vertices. If there is a hit flag writes it (via write_hit_record()),
- * and adds the name to the top of the name stack.
- *
- * sa __struct gl_contextRec::Select.
- */
-static void GLAPIENTRY
-_mesa_PushName( GLuint name )
-{
- GET_CURRENT_CONTEXT(ctx);
- ASSERT_OUTSIDE_BEGIN_END(ctx);
-
- if (ctx->RenderMode != GL_SELECT) {
- return;
- }
-
- FLUSH_VERTICES(ctx, _NEW_RENDERMODE);
- if (ctx->Select.HitFlag) {
- write_hit_record( ctx );
- }
- if (ctx->Select.NameStackDepth >= MAX_NAME_STACK_DEPTH) {
- _mesa_error( ctx, GL_STACK_OVERFLOW, "glPushName" );
- }
- else
- ctx->Select.NameStack[ctx->Select.NameStackDepth++] = name;
-}
-
-
-/**
- * Pop a name into the name stack.
- *
- * Verifies we are in selection mode and that the name stack is not empty.
- * Flushes vertices. If there is a hit flag writes it (via write_hit_record()),
- * and removes top-most name in the name stack.
- *
- * sa __struct gl_contextRec::Select.
- */
-static void GLAPIENTRY
-_mesa_PopName( void )
-{
- GET_CURRENT_CONTEXT(ctx);
- ASSERT_OUTSIDE_BEGIN_END(ctx);
-
- if (ctx->RenderMode != GL_SELECT) {
- return;
- }
-
- FLUSH_VERTICES(ctx, _NEW_RENDERMODE);
- if (ctx->Select.HitFlag) {
- write_hit_record( ctx );
- }
- if (ctx->Select.NameStackDepth == 0) {
- _mesa_error( ctx, GL_STACK_UNDERFLOW, "glPopName" );
- }
- else
- ctx->Select.NameStackDepth--;
-}
-
-/*@}*/
-
-
-/**********************************************************************/
-/** \name Render Mode */
-/*@{*/
-
-/**
- * Set rasterization mode.
- *
- * \param mode rasterization mode.
- *
- * \note this function can't be put in a display list.
- *
- * \sa glRenderMode().
- *
- * Flushes the vertices and do the necessary cleanup according to the previous
- * rasterization mode, such as writing the hit record or resent the select
- * buffer index when exiting the select mode. Updates
- * __struct gl_contextRec::RenderMode and notifies the driver via the
- * dd_function_table::RenderMode callback.
- */
-static GLint GLAPIENTRY
-_mesa_RenderMode( GLenum mode )
-{
- GET_CURRENT_CONTEXT(ctx);
- GLint result;
- ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, 0);
-
- if (MESA_VERBOSE & VERBOSE_API)
- _mesa_debug(ctx, "glRenderMode %s\n", _mesa_lookup_enum_by_nr(mode));
-
- FLUSH_VERTICES(ctx, _NEW_RENDERMODE);
-
- switch (ctx->RenderMode) {
- case GL_RENDER:
- result = 0;
- break;
- case GL_SELECT:
- if (ctx->Select.HitFlag) {
- write_hit_record( ctx );
- }
- if (ctx->Select.BufferCount > ctx->Select.BufferSize) {
- /* overflow */
-#ifdef DEBUG
- _mesa_warning(ctx, "Feedback buffer overflow");
-#endif
- result = -1;
- }
- else {
- result = ctx->Select.Hits;
- }
- ctx->Select.BufferCount = 0;
- ctx->Select.Hits = 0;
- ctx->Select.NameStackDepth = 0;
- break;
-#if _HAVE_FULL_GL
- case GL_FEEDBACK:
- if (ctx->Feedback.Count > ctx->Feedback.BufferSize) {
- /* overflow */
- result = -1;
- }
- else {
- result = ctx->Feedback.Count;
- }
- ctx->Feedback.Count = 0;
- break;
-#endif
- default:
- _mesa_error( ctx, GL_INVALID_ENUM, "glRenderMode" );
- return 0;
- }
-
- switch (mode) {
- case GL_RENDER:
- break;
- case GL_SELECT:
- if (ctx->Select.BufferSize==0) {
- /* haven't called glSelectBuffer yet */
- _mesa_error( ctx, GL_INVALID_OPERATION, "glRenderMode" );
- }
- break;
-#if _HAVE_FULL_GL
- case GL_FEEDBACK:
- if (ctx->Feedback.BufferSize==0) {
- /* haven't called glFeedbackBuffer yet */
- _mesa_error( ctx, GL_INVALID_OPERATION, "glRenderMode" );
- }
- break;
-#endif
- default:
- _mesa_error( ctx, GL_INVALID_ENUM, "glRenderMode" );
- return 0;
- }
-
- ctx->RenderMode = mode;
- if (ctx->Driver.RenderMode)
- ctx->Driver.RenderMode( ctx, mode );
-
- return result;
-}
-
-/*@}*/
-
-
-void
-_mesa_init_feedback_dispatch(struct _glapi_table *disp)
-{
- SET_InitNames(disp, _mesa_InitNames);
- SET_FeedbackBuffer(disp, _mesa_FeedbackBuffer);
- SET_LoadName(disp, _mesa_LoadName);
- SET_PassThrough(disp, _mesa_PassThrough);
- SET_PopName(disp, _mesa_PopName);
- SET_PushName(disp, _mesa_PushName);
- SET_SelectBuffer(disp, _mesa_SelectBuffer);
- SET_RenderMode(disp, _mesa_RenderMode);
-}
-
-
-#endif /* FEATURE_feedback */
-
-
-/**********************************************************************/
-/** \name Initialization */
-/*@{*/
-
-/**
- * Initialize context feedback data.
- */
-void _mesa_init_feedback( struct gl_context * ctx )
-{
- /* Feedback */
- ctx->Feedback.Type = GL_2D; /* TODO: verify */
- ctx->Feedback.Buffer = NULL;
- ctx->Feedback.BufferSize = 0;
- ctx->Feedback.Count = 0;
-
- /* Selection/picking */
- ctx->Select.Buffer = NULL;
- ctx->Select.BufferSize = 0;
- ctx->Select.BufferCount = 0;
- ctx->Select.Hits = 0;
- ctx->Select.NameStackDepth = 0;
-
- /* Miscellaneous */
- ctx->RenderMode = GL_RENDER;
-}
-
-/*@}*/
+/* + * Mesa 3-D graphics library + * Version: 7.5 + * + * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. + * Copyright (C) 2009 VMware, Inc. All Rights Reserved. + * + * 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 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 + * BRIAN PAUL 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. + */ + +/** + * \file feedback.c + * Selection and feedback modes functions. + */ + + +#include "glheader.h" +#include "colormac.h" +#include "context.h" +#include "enums.h" +#include "feedback.h" +#include "macros.h" +#include "mfeatures.h" +#include "mtypes.h" +#include "main/dispatch.h" + + +#if FEATURE_feedback + + +#define FB_3D 0x01 +#define FB_4D 0x02 +#define FB_COLOR 0x04 +#define FB_TEXTURE 0X08 + + + +static void GLAPIENTRY +_mesa_FeedbackBuffer( GLsizei size, GLenum type, GLfloat *buffer ) +{ + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END(ctx); + + if (ctx->RenderMode==GL_FEEDBACK) { + _mesa_error( ctx, GL_INVALID_OPERATION, "glFeedbackBuffer" ); + return; + } + if (size<0) { + _mesa_error( ctx, GL_INVALID_VALUE, "glFeedbackBuffer(size<0)" ); + return; + } + if (!buffer && size > 0) { + _mesa_error( ctx, GL_INVALID_VALUE, "glFeedbackBuffer(buffer==NULL)" ); + ctx->Feedback.BufferSize = 0; + return; + } + + switch (type) { + case GL_2D: + ctx->Feedback._Mask = 0; + break; + case GL_3D: + ctx->Feedback._Mask = FB_3D; + break; + case GL_3D_COLOR: + ctx->Feedback._Mask = (FB_3D | FB_COLOR); + break; + case GL_3D_COLOR_TEXTURE: + ctx->Feedback._Mask = (FB_3D | FB_COLOR | FB_TEXTURE); + break; + case GL_4D_COLOR_TEXTURE: + ctx->Feedback._Mask = (FB_3D | FB_4D | FB_COLOR | FB_TEXTURE); + break; + default: + _mesa_error( ctx, GL_INVALID_ENUM, "glFeedbackBuffer" ); + return; + } + + FLUSH_VERTICES(ctx, _NEW_RENDERMODE); /* Always flush */ + ctx->Feedback.Type = type; + ctx->Feedback.BufferSize = size; + ctx->Feedback.Buffer = buffer; + ctx->Feedback.Count = 0; /* Becaues of this. */ +} + + +static void GLAPIENTRY +_mesa_PassThrough( GLfloat token ) +{ + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END(ctx); + + if (ctx->RenderMode==GL_FEEDBACK) { + FLUSH_VERTICES(ctx, 0); + _mesa_feedback_token( ctx, (GLfloat) (GLint) GL_PASS_THROUGH_TOKEN ); + _mesa_feedback_token( ctx, token ); + } +} + + +/** + * Put a vertex into the feedback buffer. + */ +void +_mesa_feedback_vertex(struct gl_context *ctx, + const GLfloat win[4], + const GLfloat color[4], + const GLfloat texcoord[4]) +{ + _mesa_feedback_token( ctx, win[0] ); + _mesa_feedback_token( ctx, win[1] ); + if (ctx->Feedback._Mask & FB_3D) { + _mesa_feedback_token( ctx, win[2] ); + } + if (ctx->Feedback._Mask & FB_4D) { + _mesa_feedback_token( ctx, win[3] ); + } + if (ctx->Feedback._Mask & FB_COLOR) { + _mesa_feedback_token( ctx, color[0] ); + _mesa_feedback_token( ctx, color[1] ); + _mesa_feedback_token( ctx, color[2] ); + _mesa_feedback_token( ctx, color[3] ); + } + if (ctx->Feedback._Mask & FB_TEXTURE) { + _mesa_feedback_token( ctx, texcoord[0] ); + _mesa_feedback_token( ctx, texcoord[1] ); + _mesa_feedback_token( ctx, texcoord[2] ); + _mesa_feedback_token( ctx, texcoord[3] ); + } +} + + +/**********************************************************************/ +/** \name Selection */ +/*@{*/ + +/** + * Establish a buffer for selection mode values. + * + * \param size buffer size. + * \param buffer buffer. + * + * \sa glSelectBuffer(). + * + * \note this function can't be put in a display list. + * + * Verifies we're not in selection mode, flushes the vertices and initialize + * the fields in __struct gl_contextRec::Select with the given buffer. + */ +static void GLAPIENTRY +_mesa_SelectBuffer( GLsizei size, GLuint *buffer ) +{ + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END(ctx); + + if (ctx->RenderMode==GL_SELECT) { + _mesa_error( ctx, GL_INVALID_OPERATION, "glSelectBuffer" ); + return; /* KW: added return */ + } + + FLUSH_VERTICES(ctx, _NEW_RENDERMODE); + ctx->Select.Buffer = buffer; + ctx->Select.BufferSize = size; + ctx->Select.BufferCount = 0; + ctx->Select.HitFlag = GL_FALSE; + ctx->Select.HitMinZ = 1.0; + ctx->Select.HitMaxZ = 0.0; +} + + +/** + * Write a value of a record into the selection buffer. + * + * \param ctx GL context. + * \param value value. + * + * Verifies there is free space in the buffer to write the value and + * increments the pointer. + */ +static INLINE void +write_record(struct gl_context *ctx, GLuint value) +{ + if (ctx->Select.BufferCount < ctx->Select.BufferSize) { + ctx->Select.Buffer[ctx->Select.BufferCount] = value; + } + ctx->Select.BufferCount++; +} + + +/** + * Update the hit flag and the maximum and minimum depth values. + * + * \param ctx GL context. + * \param z depth. + * + * Sets gl_selection::HitFlag and updates gl_selection::HitMinZ and + * gl_selection::HitMaxZ. + */ +void +_mesa_update_hitflag(struct gl_context *ctx, GLfloat z) +{ + ctx->Select.HitFlag = GL_TRUE; + if (z < ctx->Select.HitMinZ) { + ctx->Select.HitMinZ = z; + } + if (z > ctx->Select.HitMaxZ) { + ctx->Select.HitMaxZ = z; + } +} + + +/** + * Write the hit record. + * + * \param ctx GL context. + * + * Write the hit record, i.e., the number of names in the stack, the minimum and + * maximum depth values and the number of names in the name stack at the time + * of the event. Resets the hit flag. + * + * \sa gl_selection. + */ +static void +write_hit_record(struct gl_context *ctx) +{ + GLuint i; + GLuint zmin, zmax, zscale = (~0u); + + /* HitMinZ and HitMaxZ are in [0,1]. Multiply these values by */ + /* 2^32-1 and round to nearest unsigned integer. */ + + assert( ctx != NULL ); /* this line magically fixes a SunOS 5.x/gcc bug */ + zmin = (GLuint) ((GLfloat) zscale * ctx->Select.HitMinZ); + zmax = (GLuint) ((GLfloat) zscale * ctx->Select.HitMaxZ); + + write_record( ctx, ctx->Select.NameStackDepth ); + write_record( ctx, zmin ); + write_record( ctx, zmax ); + for (i = 0; i < ctx->Select.NameStackDepth; i++) { + write_record( ctx, ctx->Select.NameStack[i] ); + } + + ctx->Select.Hits++; + ctx->Select.HitFlag = GL_FALSE; + ctx->Select.HitMinZ = 1.0; + ctx->Select.HitMaxZ = -1.0; +} + + +/** + * Initialize the name stack. + * + * Verifies we are in select mode and resets the name stack depth and resets + * the hit record data in gl_selection. Marks new render mode in + * __struct gl_contextRec::NewState. + */ +static void GLAPIENTRY +_mesa_InitNames( void ) +{ + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); + + /* Record the hit before the HitFlag is wiped out again. */ + if (ctx->RenderMode == GL_SELECT) { + if (ctx->Select.HitFlag) { + write_hit_record( ctx ); + } + } + ctx->Select.NameStackDepth = 0; + ctx->Select.HitFlag = GL_FALSE; + ctx->Select.HitMinZ = 1.0; + ctx->Select.HitMaxZ = 0.0; + ctx->NewState |= _NEW_RENDERMODE; +} + + +/** + * Load the top-most name of the name stack. + * + * \param name name. + * + * Verifies we are in selection mode and that the name stack is not empty. + * Flushes vertices. If there is a hit flag writes it (via write_hit_record()), + * and replace the top-most name in the stack. + * + * sa __struct gl_contextRec::Select. + */ +static void GLAPIENTRY +_mesa_LoadName( GLuint name ) +{ + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END(ctx); + + if (ctx->RenderMode != GL_SELECT) { + return; + } + if (ctx->Select.NameStackDepth == 0) { + _mesa_error( ctx, GL_INVALID_OPERATION, "glLoadName" ); + return; + } + + FLUSH_VERTICES(ctx, _NEW_RENDERMODE); + + if (ctx->Select.HitFlag) { + write_hit_record( ctx ); + } + if (ctx->Select.NameStackDepth < MAX_NAME_STACK_DEPTH) { + ctx->Select.NameStack[ctx->Select.NameStackDepth-1] = name; + } + else { + ctx->Select.NameStack[MAX_NAME_STACK_DEPTH-1] = name; + } +} + + +/** + * Push a name into the name stack. + * + * \param name name. + * + * Verifies we are in selection mode and that the name stack is not full. + * Flushes vertices. If there is a hit flag writes it (via write_hit_record()), + * and adds the name to the top of the name stack. + * + * sa __struct gl_contextRec::Select. + */ +static void GLAPIENTRY +_mesa_PushName( GLuint name ) +{ + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END(ctx); + + if (ctx->RenderMode != GL_SELECT) { + return; + } + + FLUSH_VERTICES(ctx, _NEW_RENDERMODE); + if (ctx->Select.HitFlag) { + write_hit_record( ctx ); + } + if (ctx->Select.NameStackDepth >= MAX_NAME_STACK_DEPTH) { + _mesa_error( ctx, GL_STACK_OVERFLOW, "glPushName" ); + } + else + ctx->Select.NameStack[ctx->Select.NameStackDepth++] = name; +} + + +/** + * Pop a name into the name stack. + * + * Verifies we are in selection mode and that the name stack is not empty. + * Flushes vertices. If there is a hit flag writes it (via write_hit_record()), + * and removes top-most name in the name stack. + * + * sa __struct gl_contextRec::Select. + */ +static void GLAPIENTRY +_mesa_PopName( void ) +{ + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END(ctx); + + if (ctx->RenderMode != GL_SELECT) { + return; + } + + FLUSH_VERTICES(ctx, _NEW_RENDERMODE); + if (ctx->Select.HitFlag) { + write_hit_record( ctx ); + } + if (ctx->Select.NameStackDepth == 0) { + _mesa_error( ctx, GL_STACK_UNDERFLOW, "glPopName" ); + } + else + ctx->Select.NameStackDepth--; +} + +/*@}*/ + + +/**********************************************************************/ +/** \name Render Mode */ +/*@{*/ + +/** + * Set rasterization mode. + * + * \param mode rasterization mode. + * + * \note this function can't be put in a display list. + * + * \sa glRenderMode(). + * + * Flushes the vertices and do the necessary cleanup according to the previous + * rasterization mode, such as writing the hit record or resent the select + * buffer index when exiting the select mode. Updates + * __struct gl_contextRec::RenderMode and notifies the driver via the + * dd_function_table::RenderMode callback. + */ +static GLint GLAPIENTRY +_mesa_RenderMode( GLenum mode ) +{ + GET_CURRENT_CONTEXT(ctx); + GLint result; + ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, 0); + + if (MESA_VERBOSE & VERBOSE_API) + _mesa_debug(ctx, "glRenderMode %s\n", _mesa_lookup_enum_by_nr(mode)); + + FLUSH_VERTICES(ctx, _NEW_RENDERMODE); + + switch (ctx->RenderMode) { + case GL_RENDER: + result = 0; + break; + case GL_SELECT: + if (ctx->Select.HitFlag) { + write_hit_record( ctx ); + } + if (ctx->Select.BufferCount > ctx->Select.BufferSize) { + /* overflow */ +#ifdef DEBUG + _mesa_warning(ctx, "Feedback buffer overflow"); +#endif + result = -1; + } + else { + result = ctx->Select.Hits; + } + ctx->Select.BufferCount = 0; + ctx->Select.Hits = 0; + ctx->Select.NameStackDepth = 0; + break; +#if _HAVE_FULL_GL + case GL_FEEDBACK: + if (ctx->Feedback.Count > ctx->Feedback.BufferSize) { + /* overflow */ + result = -1; + } + else { + result = ctx->Feedback.Count; + } + ctx->Feedback.Count = 0; + break; +#endif + default: + _mesa_error( ctx, GL_INVALID_ENUM, "glRenderMode" ); + return 0; + } + + switch (mode) { + case GL_RENDER: + break; + case GL_SELECT: + if (ctx->Select.BufferSize==0) { + /* haven't called glSelectBuffer yet */ + _mesa_error( ctx, GL_INVALID_OPERATION, "glRenderMode" ); + } + break; +#if _HAVE_FULL_GL + case GL_FEEDBACK: + if (ctx->Feedback.BufferSize==0) { + /* haven't called glFeedbackBuffer yet */ + _mesa_error( ctx, GL_INVALID_OPERATION, "glRenderMode" ); + } + break; +#endif + default: + _mesa_error( ctx, GL_INVALID_ENUM, "glRenderMode" ); + return 0; + } + + ctx->RenderMode = mode; + if (ctx->Driver.RenderMode) + ctx->Driver.RenderMode( ctx, mode ); + + return result; +} + +/*@}*/ + + +void +_mesa_init_feedback_dispatch(struct _glapi_table *disp) +{ + SET_InitNames(disp, _mesa_InitNames); + SET_FeedbackBuffer(disp, _mesa_FeedbackBuffer); + SET_LoadName(disp, _mesa_LoadName); + SET_PassThrough(disp, _mesa_PassThrough); + SET_PopName(disp, _mesa_PopName); + SET_PushName(disp, _mesa_PushName); + SET_SelectBuffer(disp, _mesa_SelectBuffer); + SET_RenderMode(disp, _mesa_RenderMode); +} + + +#endif /* FEATURE_feedback */ + + +/**********************************************************************/ +/** \name Initialization */ +/*@{*/ + +/** + * Initialize context feedback data. + */ +void _mesa_init_feedback( struct gl_context * ctx ) +{ + /* Feedback */ + ctx->Feedback.Type = GL_2D; /* TODO: verify */ + ctx->Feedback.Buffer = NULL; + ctx->Feedback.BufferSize = 0; + ctx->Feedback.Count = 0; + + /* Selection/picking */ + ctx->Select.Buffer = NULL; + ctx->Select.BufferSize = 0; + ctx->Select.BufferCount = 0; + ctx->Select.Hits = 0; + ctx->Select.NameStackDepth = 0; + + /* Miscellaneous */ + ctx->RenderMode = GL_RENDER; +} + +/*@}*/ diff --git a/mesalib/src/mesa/main/texstore.c b/mesalib/src/mesa/main/texstore.c index 5c925a3d3..e527981ff 100644 --- a/mesalib/src/mesa/main/texstore.c +++ b/mesalib/src/mesa/main/texstore.c @@ -3303,8 +3303,7 @@ _mesa_texstore_z24_s8(TEXSTORE_PARAMS) { const GLuint depthScale = 0xffffff; const GLint srcRowStride - = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType) - / sizeof(GLuint); + = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType); GLint img, row; ASSERT(dstFormat == MESA_FORMAT_Z24_S8); @@ -3332,8 +3331,8 @@ _mesa_texstore_z24_s8(TEXSTORE_PARAMS) + dstImageOffsets[dstZoffset + img] + dstYoffset * dstRowStride / sizeof(GLuint) + dstXoffset; - const GLuint *src - = (const GLuint *) _mesa_image_address(dims, srcPacking, srcAddr, + const GLubyte *src + = (const GLubyte *) _mesa_image_address(dims, srcPacking, srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, 0, 0); @@ -3390,8 +3389,7 @@ _mesa_texstore_s8_z24(TEXSTORE_PARAMS) { const GLuint depthScale = 0xffffff; const GLint srcRowStride - = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType) - / sizeof(GLuint); + = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType); GLint img, row; ASSERT(dstFormat == MESA_FORMAT_S8_Z24); @@ -3406,8 +3404,8 @@ _mesa_texstore_s8_z24(TEXSTORE_PARAMS) + dstImageOffsets[dstZoffset + img] + dstYoffset * dstRowStride / sizeof(GLuint) + dstXoffset; - const GLuint *src - = (const GLuint *) _mesa_image_address(dims, srcPacking, srcAddr, + const GLubyte *src + = (const GLubyte *) _mesa_image_address(dims, srcPacking, srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, 0, 0); @@ -3479,8 +3477,7 @@ _mesa_texstore_s8(TEXSTORE_PARAMS) } else { const GLint srcRowStride - = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType) - / sizeof(GLuint); + = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType); GLint img, row; for (img = 0; img < srcDepth; img++) { @@ -3488,8 +3485,8 @@ _mesa_texstore_s8(TEXSTORE_PARAMS) + dstImageOffsets[dstZoffset + img] + dstYoffset * dstRowStride / sizeof(GLuint) + dstXoffset; - const GLuint *src - = (const GLuint *) _mesa_image_address(dims, srcPacking, srcAddr, + const GLubyte *src + = (const GLubyte *) _mesa_image_address(dims, srcPacking, srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, 0, 0); diff --git a/mesalib/src/mesa/program/ir_to_mesa.cpp b/mesalib/src/mesa/program/ir_to_mesa.cpp index 67adb8f3d..738e97ca5 100644 --- a/mesalib/src/mesa/program/ir_to_mesa.cpp +++ b/mesalib/src/mesa/program/ir_to_mesa.cpp @@ -803,48 +803,44 @@ ir_to_mesa_visitor::visit(ir_loop *ir) ir_dereference_variable *counter = NULL; if (ir->counter != NULL) - counter = new(ir) ir_dereference_variable(ir->counter); + counter = new(mem_ctx) ir_dereference_variable(ir->counter); if (ir->from != NULL) { assert(ir->counter != NULL); - ir_assignment *a = new(ir) ir_assignment(counter, ir->from, NULL); + ir_assignment *a = + new(mem_ctx) ir_assignment(counter, ir->from, NULL); a->accept(this); - delete a; } emit(NULL, OPCODE_BGNLOOP); if (ir->to) { ir_expression *e = - new(ir) ir_expression(ir->cmp, glsl_type::bool_type, - counter, ir->to); - ir_if *if_stmt = new(ir) ir_if(e); + new(mem_ctx) ir_expression(ir->cmp, glsl_type::bool_type, + counter, ir->to); + ir_if *if_stmt = new(mem_ctx) ir_if(e); - ir_loop_jump *brk = new(ir) ir_loop_jump(ir_loop_jump::jump_break); + ir_loop_jump *brk = + new(mem_ctx) ir_loop_jump(ir_loop_jump::jump_break); if_stmt->then_instructions.push_tail(brk); if_stmt->accept(this); - - delete if_stmt; - delete e; - delete brk; } visit_exec_list(&ir->body_instructions, this); if (ir->increment) { ir_expression *e = - new(ir) ir_expression(ir_binop_add, counter->type, - counter, ir->increment); + new(mem_ctx) ir_expression(ir_binop_add, counter->type, + counter, ir->increment); - ir_assignment *a = new(ir) ir_assignment(counter, e, NULL); + ir_assignment *a = + new(mem_ctx) ir_assignment(counter, e, NULL); a->accept(this); - delete a; - delete e; } emit(NULL, OPCODE_ENDLOOP); |