From 462f18c7b25fe3e467f837647d07ab0a78aa8d2b Mon Sep 17 00:00:00 2001 From: marha Date: Sun, 22 Feb 2015 21:39:56 +0100 Subject: Merged origin/release (checked in because wanted to merge new stuff) --- mesalib/src/mesa/Android.libmesa_dricore.mk | 2 - mesalib/src/mesa/Android.libmesa_st_mesa.mk | 2 - mesalib/src/mesa/Makefile.am | 74 +- mesalib/src/mesa/Makefile.sources | 845 ++-- mesalib/src/mesa/SConscript | 16 + mesalib/src/mesa/drivers/common/driverfuncs.c | 4 +- mesalib/src/mesa/drivers/common/meta.c | 42 +- mesalib/src/mesa/drivers/common/meta.h | 32 +- mesalib/src/mesa/drivers/common/meta_blit.c | 45 +- mesalib/src/mesa/drivers/common/meta_copy_image.c | 3 +- .../src/mesa/drivers/common/meta_generate_mipmap.c | 8 +- .../src/mesa/drivers/common/meta_tex_subimage.c | 361 ++ mesalib/src/mesa/drivers/dri/Makefile.am | 16 +- mesalib/src/mesa/drivers/dri/common/Makefile.am | 4 + .../src/mesa/drivers/dri/common/Makefile.sources | 5 +- mesalib/src/mesa/drivers/dri/common/drirc | 4 + mesalib/src/mesa/drivers/dri/common/mmio.h | 62 - mesalib/src/mesa/drivers/dri/common/xmlconfig.c | 3 +- .../mesa/drivers/dri/common/xmlpool/Makefile.am | 2 + mesalib/src/mesa/drivers/dri/swrast/Makefile.am | 2 + .../src/mesa/drivers/dri/swrast/Makefile.sources | 3 +- mesalib/src/mesa/drivers/dri/swrast/swrast.c | 5 +- mesalib/src/mesa/drivers/haiku/swrast/SConscript | 1 + mesalib/src/mesa/main/.gitignore | 2 + mesalib/src/mesa/main/api_validate.c | 326 +- mesalib/src/mesa/main/api_validate.h | 12 +- mesalib/src/mesa/main/attrib.c | 6 +- mesalib/src/mesa/main/bitset.h | 99 - mesalib/src/mesa/main/blit.c | 2 +- mesalib/src/mesa/main/bufferobj.c | 53 +- mesalib/src/mesa/main/buffers.c | 22 +- mesalib/src/mesa/main/clear.c | 25 +- mesalib/src/mesa/main/colormac.h | 3 - mesalib/src/mesa/main/compiler.h | 2 +- mesalib/src/mesa/main/config.h | 5 +- mesalib/src/mesa/main/context.c | 90 +- mesalib/src/mesa/main/context.h | 11 + mesalib/src/mesa/main/copyimage.c | 2 +- mesalib/src/mesa/main/dd.h | 20 +- mesalib/src/mesa/main/dlist.c | 364 +- mesalib/src/mesa/main/dlist.h | 5 +- mesalib/src/mesa/main/enable.c | 2 +- mesalib/src/mesa/main/enums.h | 11 + mesalib/src/mesa/main/errors.c | 11 +- mesalib/src/mesa/main/errors.h | 7 +- mesalib/src/mesa/main/extensions.c | 13 +- mesalib/src/mesa/main/fbobject.c | 70 +- mesalib/src/mesa/main/feedback.c | 2 +- mesalib/src/mesa/main/ff_fragment_shader.cpp | 10 +- mesalib/src/mesa/main/ffvertex_prog.c | 4 +- mesalib/src/mesa/main/format_info.py | 18 +- mesalib/src/mesa/main/format_pack.c | 2994 ----------- mesalib/src/mesa/main/format_pack.h | 4 +- mesalib/src/mesa/main/format_pack.py | 1004 ++++ mesalib/src/mesa/main/format_parser.py | 54 +- mesalib/src/mesa/main/format_unpack.c | 4400 ---------------- mesalib/src/mesa/main/format_unpack.py | 895 ++++ mesalib/src/mesa/main/format_utils.c | 1004 ++-- mesalib/src/mesa/main/format_utils.h | 195 +- mesalib/src/mesa/main/formatquery.c | 73 +- mesalib/src/mesa/main/formats.c | 291 +- mesalib/src/mesa/main/formats.csv | 10 + mesalib/src/mesa/main/formats.h | 159 +- mesalib/src/mesa/main/framebuffer.c | 2 +- mesalib/src/mesa/main/genmipmap.c | 73 +- mesalib/src/mesa/main/genmipmap.h | 6 + mesalib/src/mesa/main/get.c | 1 + mesalib/src/mesa/main/get_hash_params.py | 13 +- mesalib/src/mesa/main/getstring.c | 8 +- mesalib/src/mesa/main/glformats.c | 568 ++- mesalib/src/mesa/main/glformats.h | 8 +- mesalib/src/mesa/main/hash.c | 17 +- mesalib/src/mesa/main/image.c | 41 +- mesalib/src/mesa/main/image.h | 20 +- mesalib/src/mesa/main/light.c | 11 +- mesalib/src/mesa/main/light.h | 2 - mesalib/src/mesa/main/macros.h | 20 +- mesalib/src/mesa/main/matrix.c | 6 +- mesalib/src/mesa/main/mipmap.c | 8 +- mesalib/src/mesa/main/mtypes.h | 73 +- mesalib/src/mesa/main/multisample.c | 10 + mesalib/src/mesa/main/objectlabel.c | 9 +- mesalib/src/mesa/main/pack.c | 5337 ++------------------ mesalib/src/mesa/main/pack.h | 86 +- mesalib/src/mesa/main/pack_tmp.h | 122 - mesalib/src/mesa/main/performance_monitor.c | 2 +- mesalib/src/mesa/main/polygon.c | 84 +- mesalib/src/mesa/main/polygon.h | 12 +- mesalib/src/mesa/main/querymatrix.c | 18 +- mesalib/src/mesa/main/queryobj.c | 89 + mesalib/src/mesa/main/rastpos.c | 2 +- mesalib/src/mesa/main/readpix.c | 329 +- mesalib/src/mesa/main/renderbuffer.c | 20 +- mesalib/src/mesa/main/samplerobj.c | 92 +- mesalib/src/mesa/main/samplerobj.h | 9 + mesalib/src/mesa/main/set.c | 346 -- mesalib/src/mesa/main/set.h | 94 - mesalib/src/mesa/main/shader_query.cpp | 5 + mesalib/src/mesa/main/shaderapi.c | 148 +- mesalib/src/mesa/main/shaderobj.c | 6 +- mesalib/src/mesa/main/shaderobj.h | 13 +- mesalib/src/mesa/main/shared.c | 5 +- mesalib/src/mesa/main/simple_list.h | 210 - mesalib/src/mesa/main/sse_minmax.c | 3 - mesalib/src/mesa/main/stencil.c | 24 +- mesalib/src/mesa/main/syncobj.c | 14 +- mesalib/src/mesa/main/texcompress_bptc.c | 39 +- mesalib/src/mesa/main/texcompress_fxt1.c | 34 +- mesalib/src/mesa/main/texcompress_rgtc.c | 90 +- mesalib/src/mesa/main/texcompress_s3tc.c | 68 +- mesalib/src/mesa/main/texenvprogram.h | 11 + mesalib/src/mesa/main/texgetimage.c | 832 ++- mesalib/src/mesa/main/texgetimage.h | 33 +- mesalib/src/mesa/main/teximage.c | 1536 ++++-- mesalib/src/mesa/main/teximage.h | 150 +- mesalib/src/mesa/main/texobj.c | 523 +- mesalib/src/mesa/main/texobj.h | 59 +- mesalib/src/mesa/main/texparam.c | 790 ++- mesalib/src/mesa/main/texparam.h | 84 +- mesalib/src/mesa/main/texstate.c | 24 +- mesalib/src/mesa/main/texstate.h | 38 +- mesalib/src/mesa/main/texstorage.c | 214 +- mesalib/src/mesa/main/texstorage.h | 39 +- mesalib/src/mesa/main/texstore.c | 1181 +---- mesalib/src/mesa/main/texstore.h | 19 - mesalib/src/mesa/main/textureview.c | 5 +- mesalib/src/mesa/main/uniform_query.cpp | 63 +- mesalib/src/mesa/main/uniforms.c | 380 +- mesalib/src/mesa/main/uniforms.h | 92 +- mesalib/src/mesa/main/varray.c | 11 +- mesalib/src/mesa/main/vdpau.c | 21 +- mesalib/src/mesa/math/m_translate.c | 21 - mesalib/src/mesa/math/m_translate.h | 10 - mesalib/src/mesa/program/Android.mk | 2 - mesalib/src/mesa/program/arbprogparse.c | 3 - mesalib/src/mesa/program/hash_table.h | 34 + mesalib/src/mesa/program/ir_to_mesa.cpp | 54 +- mesalib/src/mesa/program/prog_cache.h | 11 + mesalib/src/mesa/program/prog_execute.c | 77 +- mesalib/src/mesa/program/prog_hash_table.c | 2 +- mesalib/src/mesa/program/prog_instruction.c | 23 - mesalib/src/mesa/program/prog_instruction.h | 4 - mesalib/src/mesa/program/prog_optimize.c | 4 +- mesalib/src/mesa/program/prog_optimize.h | 11 + mesalib/src/mesa/program/prog_parameter.c | 2 +- mesalib/src/mesa/program/prog_print.c | 4 +- mesalib/src/mesa/program/prog_print.h | 11 + mesalib/src/mesa/program/prog_statevars.c | 2 - mesalib/src/mesa/program/programopt.c | 91 - mesalib/src/mesa/program/programopt.h | 14 +- mesalib/src/mesa/program/sampler.cpp | 9 +- mesalib/src/mesa/program/sampler.h | 7 + mesalib/src/mesa/state_tracker/st_atom_blend.c | 2 +- .../src/mesa/state_tracker/st_atom_rasterizer.c | 1 + mesalib/src/mesa/state_tracker/st_atom_sampler.c | 5 +- mesalib/src/mesa/state_tracker/st_atom_scissor.c | 2 +- mesalib/src/mesa/state_tracker/st_atom_shader.c | 7 +- mesalib/src/mesa/state_tracker/st_atom_texture.c | 8 +- mesalib/src/mesa/state_tracker/st_atom_viewport.c | 2 +- mesalib/src/mesa/state_tracker/st_cb_blit.c | 6 +- .../src/mesa/state_tracker/st_cb_bufferobjects.c | 29 +- mesalib/src/mesa/state_tracker/st_cb_drawpixels.c | 15 +- mesalib/src/mesa/state_tracker/st_cb_drawtex.c | 3 +- mesalib/src/mesa/state_tracker/st_cb_fbo.c | 6 +- mesalib/src/mesa/state_tracker/st_cb_queryobj.c | 58 +- mesalib/src/mesa/state_tracker/st_cb_texture.c | 37 +- mesalib/src/mesa/state_tracker/st_cb_xformfb.c | 2 +- mesalib/src/mesa/state_tracker/st_context.c | 13 +- mesalib/src/mesa/state_tracker/st_context.h | 11 + mesalib/src/mesa/state_tracker/st_draw.c | 5 +- mesalib/src/mesa/state_tracker/st_extensions.c | 21 +- mesalib/src/mesa/state_tracker/st_format.c | 49 +- mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp | 1142 +++-- mesalib/src/mesa/state_tracker/st_manager.c | 2 +- mesalib/src/mesa/state_tracker/st_mesa_to_tgsi.c | 4 +- mesalib/src/mesa/state_tracker/st_program.c | 2 +- mesalib/src/mesa/state_tracker/st_program.h | 9 + mesalib/src/mesa/state_tracker/st_texture.h | 6 + mesalib/src/mesa/swrast/s_aaline.c | 1 + mesalib/src/mesa/swrast/s_aalinetemp.h | 3 +- mesalib/src/mesa/swrast/s_blit.c | 43 +- mesalib/src/mesa/swrast/s_copypix.c | 25 +- mesalib/src/mesa/swrast/s_drawpix.c | 41 +- mesalib/src/mesa/swrast/s_fragprog.c | 4 +- mesalib/src/mesa/swrast/s_span.c | 28 +- mesalib/src/mesa/swrast/s_texfetch.c | 11 + mesalib/src/mesa/swrast/s_texfetch_tmp.h | 1359 +---- mesalib/src/mesa/swrast/s_texfilter.c | 121 +- mesalib/src/mesa/swrast/s_triangle.c | 11 +- mesalib/src/mesa/swrast/swrast.h | 18 +- mesalib/src/mesa/tnl/t_rasterpos.c | 2 +- mesalib/src/mesa/tnl/t_vb_light.c | 2 +- mesalib/src/mesa/tnl/t_vertex_generic.c | 2 +- mesalib/src/mesa/tnl/t_vertex_sse.c | 2 +- mesalib/src/mesa/vbo/vbo_attrib_tmp.h | 1 + mesalib/src/mesa/vbo/vbo_exec_array.c | 29 +- mesalib/src/mesa/vbo/vbo_save_api.c | 17 +- mesalib/src/mesa/x86/3dnow.c | 7 - mesalib/src/mesa/x86/3dnow_normal.S | 852 ---- 199 files changed, 12379 insertions(+), 20166 deletions(-) create mode 100644 mesalib/src/mesa/drivers/common/meta_tex_subimage.c delete mode 100644 mesalib/src/mesa/drivers/dri/common/mmio.h delete mode 100644 mesalib/src/mesa/main/bitset.h delete mode 100644 mesalib/src/mesa/main/format_pack.c create mode 100644 mesalib/src/mesa/main/format_pack.py delete mode 100644 mesalib/src/mesa/main/format_unpack.c create mode 100644 mesalib/src/mesa/main/format_unpack.py delete mode 100644 mesalib/src/mesa/main/pack_tmp.h delete mode 100644 mesalib/src/mesa/main/set.c delete mode 100644 mesalib/src/mesa/main/set.h delete mode 100644 mesalib/src/mesa/main/simple_list.h delete mode 100644 mesalib/src/mesa/x86/3dnow_normal.S (limited to 'mesalib/src/mesa') diff --git a/mesalib/src/mesa/Android.libmesa_dricore.mk b/mesalib/src/mesa/Android.libmesa_dricore.mk index 2ab593d3c..e4a52677c 100644 --- a/mesalib/src/mesa/Android.libmesa_dricore.mk +++ b/mesalib/src/mesa/Android.libmesa_dricore.mk @@ -32,8 +32,6 @@ LOCAL_PATH := $(call my-dir) # MESA_FILES # X86_FILES include $(LOCAL_PATH)/Makefile.sources -SRCDIR := -BUILDDIR := include $(CLEAR_VARS) diff --git a/mesalib/src/mesa/Android.libmesa_st_mesa.mk b/mesalib/src/mesa/Android.libmesa_st_mesa.mk index 618d6bfb2..a08366d53 100644 --- a/mesalib/src/mesa/Android.libmesa_st_mesa.mk +++ b/mesalib/src/mesa/Android.libmesa_st_mesa.mk @@ -32,8 +32,6 @@ LOCAL_PATH := $(call my-dir) # MESA_GALLIUM_FILES. # X86_FILES include $(LOCAL_PATH)/Makefile.sources -SRCDIR := -BUILDDIR := include $(CLEAR_VARS) diff --git a/mesalib/src/mesa/Makefile.am b/mesalib/src/mesa/Makefile.am index 932db4fb8..b6cb8f111 100644 --- a/mesalib/src/mesa/Makefile.am +++ b/mesalib/src/mesa/Makefile.am @@ -19,6 +19,8 @@ # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS # IN THE SOFTWARE. +AUTOMAKE_OPTIONS = subdir-objects + SUBDIRS = . main/tests if HAVE_X11_DRIVER @@ -36,8 +38,8 @@ endif gldir = $(includedir)/GL gl_HEADERS = $(top_srcdir)/include/GL/*.h -.PHONY: $(BUILDDIR)main/git_sha1.h.tmp -$(BUILDDIR)main/git_sha1.h.tmp: +.PHONY: main/git_sha1.h.tmp +main/git_sha1.h.tmp: @touch main/git_sha1.h.tmp @if test -d $(top_srcdir)/.git; then \ if which git > /dev/null; then \ @@ -47,7 +49,7 @@ $(BUILDDIR)main/git_sha1.h.tmp: fi \ fi -$(BUILDDIR)main/git_sha1.h: $(BUILDDIR)main/git_sha1.h.tmp +main/git_sha1.h: main/git_sha1.h.tmp @echo "updating main/git_sha1.h" @if ! cmp -s main/git_sha1.h.tmp main/git_sha1.h; then \ mv main/git_sha1.h.tmp main/git_sha1.h ;\ @@ -55,27 +57,43 @@ $(BUILDDIR)main/git_sha1.h: $(BUILDDIR)main/git_sha1.h.tmp rm main/git_sha1.h.tmp ;\ fi -# include glapi_gen.mk for generating glapi headers for GLES -GLAPI = $(top_srcdir)/src/mapi/glapi/gen -include $(GLAPI)/glapi_gen.mk - -BUILDDIR = $(builddir)/ include Makefile.sources +EXTRA_DIST = \ + drivers/haiku \ + drivers/SConscript \ + drivers/windows \ + main/format_info.py \ + main/format_pack.py \ + main/format_parser.py \ + main/format_unpack.py \ + main/formats.csv \ + main/get_hash_generator.py \ + main/get_hash_params.py \ + program/program_lexer.l \ + program/program_parse.y \ + SConscript \ + swrast/NOTES \ + swrast_setup/NOTES \ + tnl/NOTES \ + tnl_dd + BUILT_SOURCES = \ main/get_hash.h \ main/format_info.c \ - $(BUILDDIR)main/git_sha1.h \ - $(BUILDDIR)program/program_parse.tab.c \ - $(BUILDDIR)program/lex.yy.c + main/git_sha1.h \ + main/format_pack.c \ + main/format_unpack.c \ + program/program_parse.tab.c \ + program/lex.yy.c CLEANFILES = \ $(BUILT_SOURCES) \ - $(BUILDDIR)program/program_parse.tab.h \ - $(BUILDDIR)main/git_sha1.h.tmp + program/program_parse.tab.h \ + main/git_sha1.h.tmp GET_HASH_GEN = main/get_hash_generator.py -main/get_hash.h: $(GLAPI)/gl_and_es_API.xml main/get_hash_params.py \ +main/get_hash.h: ../mapi/glapi/gen/gl_and_es_API.xml main/get_hash_params.py \ $(GET_HASH_GEN) Makefile $(AM_V_GEN)set -e; \ $(PYTHON2) $(PYTHON_FLAGS) $(srcdir)/$(GET_HASH_GEN) \ @@ -89,6 +107,22 @@ main/format_info.c: main/formats.csv \ $< > $@.tmp; \ mv $@.tmp $@; +main/format_pack.c: main/format_pack.py main/formats.csv \ + main/format_parser.py + $(AM_V_GEN)set -e; \ + $(PYTHON2) $(PYTHON_FLAGS) \ + $(srcdir)/main/format_pack.py \ + $(srcdir)/main/formats.csv \ + | $(INDENT) $(INDENT_FLAGS) > $@; + +main/format_unpack.c: main/format_unpack.py main/formats.csv \ + main/format_parser.py + $(AM_V_GEN)set -e; \ + $(PYTHON2) $(PYTHON_FLAGS) \ + $(srcdir)/main/format_unpack.py \ + $(srcdir)/main/formats.csv \ + | $(INDENT) $(INDENT_FLAGS) > $@; + main/formats.c: main/format_info.c noinst_LTLIBRARIES = $(ARCH_LIBS) @@ -152,19 +186,21 @@ libmesagallium_la_LIBADD = \ libmesa_sse41_la_SOURCES = \ main/streaming-load-memcpy.c \ - main/sse_minmax.c -libmesa_sse41_la_CFLAGS = $(AM_CFLAGS) -msse4.1 + main/streaming-load-memcpy.h \ + main/sse_minmax.c \ + main/sse_minmax.h +libmesa_sse41_la_CFLAGS = $(AM_CFLAGS) $(SSE41_CFLAGS) pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = gl.pc -$(BUILDDIR)program/lex.yy.c: program/program_lexer.l +program/lex.yy.c: program/program_lexer.l $(AM_V_at)$(MKDIR_P) program $(AM_V_GEN) $(LEX) --never-interactive --outfile=$@ $< -$(BUILDDIR)program/program_parse.tab.c $(BUILDDIR)program/program_parse.tab.h: program/program_parse.y +program/program_parse.tab.c program/program_parse.tab.h: program/program_parse.y $(AM_V_at)$(MKDIR_P) program - $(AM_V_GEN) $(YACC) -p "_mesa_program_" -v -d --output=$(BUILDDIR)program/program_parse.tab.c $< + $(AM_V_GEN) $(YACC) -p "_mesa_program_" -v -d --output=program/program_parse.tab.c $< if GEN_ASM_OFFSETS matypes.h: $(gen_matypes_SOURCES) diff --git a/mesalib/src/mesa/Makefile.sources b/mesalib/src/mesa/Makefile.sources index 475501877..5b4e71253 100644 --- a/mesalib/src/mesa/Makefile.sources +++ b/mesalib/src/mesa/Makefile.sources @@ -1,333 +1,582 @@ ### Lists of source files, included by Makefiles -# This file is among different build systems. SRCDIR must be defined with -# a trailing slash because the Android build system leaves it undefined. - -SRCDIR = $(top_srcdir)/src/mesa/ -BUILDDIR = $(top_builddir)/src/mesa/ - # this is part of MAIN_FILES MAIN_ES_FILES = \ - $(SRCDIR)main/es1_conversion.c + main/es1_conversion.c \ + main/es1_conversion.h MAIN_FILES = \ - $(SRCDIR)main/api_arrayelt.c \ - $(BUILDDIR)main/api_exec.c \ - $(SRCDIR)main/api_loopback.c \ - $(SRCDIR)main/api_validate.c \ - $(SRCDIR)main/accum.c \ - $(SRCDIR)main/arbprogram.c \ - $(SRCDIR)main/atifragshader.c \ - $(SRCDIR)main/attrib.c \ - $(SRCDIR)main/arrayobj.c \ - $(SRCDIR)main/blend.c \ - $(SRCDIR)main/blit.c \ - $(SRCDIR)main/bufferobj.c \ - $(SRCDIR)main/buffers.c \ - $(SRCDIR)main/clear.c \ - $(SRCDIR)main/clip.c \ - $(SRCDIR)main/colortab.c \ - $(SRCDIR)main/compute.c \ - $(SRCDIR)main/condrender.c \ - $(SRCDIR)main/context.c \ - $(SRCDIR)main/convolve.c \ - $(SRCDIR)main/copyimage.c \ - $(SRCDIR)main/cpuinfo.c \ - $(SRCDIR)main/debug.c \ - $(SRCDIR)main/depth.c \ - $(SRCDIR)main/dlist.c \ - $(SRCDIR)main/drawpix.c \ - $(SRCDIR)main/drawtex.c \ - $(SRCDIR)main/enable.c \ - $(SRCDIR)main/errors.c \ - $(SRCDIR)main/eval.c \ - $(SRCDIR)main/execmem.c \ - $(SRCDIR)main/extensions.c \ - $(SRCDIR)main/fbobject.c \ - $(SRCDIR)main/feedback.c \ - $(SRCDIR)main/ffvertex_prog.c \ - $(SRCDIR)main/ff_fragment_shader.cpp \ - $(SRCDIR)main/fog.c \ - $(SRCDIR)main/formatquery.c \ - $(SRCDIR)main/formats.c \ - $(SRCDIR)main/format_pack.c \ - $(SRCDIR)main/format_unpack.c \ - $(SRCDIR)main/format_utils.c \ - $(SRCDIR)main/framebuffer.c \ - $(SRCDIR)main/get.c \ - $(SRCDIR)main/genmipmap.c \ - $(SRCDIR)main/getstring.c \ - $(SRCDIR)main/glformats.c \ - $(SRCDIR)main/hash.c \ - $(SRCDIR)main/hint.c \ - $(SRCDIR)main/histogram.c \ - $(SRCDIR)main/image.c \ - $(SRCDIR)main/imports.c \ - $(SRCDIR)main/light.c \ - $(SRCDIR)main/lines.c \ - $(SRCDIR)main/matrix.c \ - $(SRCDIR)main/mipmap.c \ - $(SRCDIR)main/mm.c \ - $(SRCDIR)main/multisample.c \ - $(SRCDIR)main/objectlabel.c \ - $(SRCDIR)main/pack.c \ - $(SRCDIR)main/pbo.c \ - $(SRCDIR)main/performance_monitor.c \ - $(SRCDIR)main/pipelineobj.c \ - $(SRCDIR)main/pixel.c \ - $(SRCDIR)main/pixelstore.c \ - $(SRCDIR)main/pixeltransfer.c \ - $(SRCDIR)main/points.c \ - $(SRCDIR)main/polygon.c \ - $(SRCDIR)main/queryobj.c \ - $(SRCDIR)main/querymatrix.c \ - $(SRCDIR)main/rastpos.c \ - $(SRCDIR)main/readpix.c \ - $(SRCDIR)main/remap.c \ - $(SRCDIR)main/renderbuffer.c \ - $(SRCDIR)main/samplerobj.c \ - $(SRCDIR)main/scissor.c \ - $(SRCDIR)main/set.c \ - $(SRCDIR)main/shaderapi.c \ - $(SRCDIR)main/shaderimage.c \ - $(SRCDIR)main/shaderobj.c \ - $(SRCDIR)main/shader_query.cpp \ - $(SRCDIR)main/shared.c \ - $(SRCDIR)main/state.c \ - $(SRCDIR)main/stencil.c \ - $(SRCDIR)main/syncobj.c \ - $(SRCDIR)main/texcompress.c \ - $(SRCDIR)main/texcompress_bptc.c \ - $(SRCDIR)main/texcompress_cpal.c \ - $(SRCDIR)main/texcompress_rgtc.c \ - $(SRCDIR)main/texcompress_s3tc.c \ - $(SRCDIR)main/texcompress_fxt1.c \ - $(SRCDIR)main/texcompress_etc.c \ - $(SRCDIR)main/texenv.c \ - $(SRCDIR)main/texformat.c \ - $(SRCDIR)main/texgen.c \ - $(SRCDIR)main/texgetimage.c \ - $(SRCDIR)main/teximage.c \ - $(SRCDIR)main/texobj.c \ - $(SRCDIR)main/texparam.c \ - $(SRCDIR)main/texstate.c \ - $(SRCDIR)main/texstorage.c \ - $(SRCDIR)main/texstore.c \ - $(SRCDIR)main/textureview.c \ - $(SRCDIR)main/texturebarrier.c \ - $(SRCDIR)main/transformfeedback.c \ - $(SRCDIR)main/uniforms.c \ - $(SRCDIR)main/uniform_query.cpp \ - $(SRCDIR)main/varray.c \ - $(SRCDIR)main/vdpau.c \ - $(SRCDIR)main/version.c \ - $(SRCDIR)main/viewport.c \ - $(SRCDIR)main/vtxfmt.c \ - $(BUILDDIR)main/enums.c \ + main/accum.c \ + main/accum.h \ + main/api_arrayelt.c \ + main/api_arrayelt.h \ + main/api_exec.c \ + main/api_exec.h \ + main/api_loopback.c \ + main/api_loopback.h \ + main/api_validate.c \ + main/api_validate.h \ + main/arbprogram.c \ + main/arbprogram.h \ + main/arrayobj.c \ + main/arrayobj.h \ + main/atifragshader.c \ + main/atifragshader.h \ + main/attrib.c \ + main/attrib.h \ + main/blend.c \ + main/blend.h \ + main/blit.c \ + main/blit.h \ + main/bufferobj.c \ + main/bufferobj.h \ + main/buffers.c \ + main/buffers.h \ + main/clear.c \ + main/clear.h \ + main/clip.c \ + main/clip.h \ + main/colormac.h \ + main/colortab.c \ + main/colortab.h \ + main/compute.c \ + main/compute.h \ + main/compiler.h \ + main/condrender.c \ + main/condrender.h \ + main/config.h \ + main/context.c \ + main/context.h \ + main/convolve.c \ + main/convolve.h \ + main/copyimage.c \ + main/copyimage.h \ + main/core.h \ + main/cpuinfo.c \ + main/cpuinfo.h \ + main/dd.h \ + main/debug.c \ + main/debug.h \ + main/depth.c \ + main/depth.h \ + main/dlist.c \ + main/dlist.h \ + main/dlopen.h \ + main/drawpix.c \ + main/drawpix.h \ + main/drawtex.c \ + main/drawtex.h \ + main/enable.c \ + main/enable.h \ + main/enums.c \ + main/enums.h \ + main/errors.c \ + main/errors.h \ + main/eval.c \ + main/eval.h \ + main/execmem.c \ + main/extensions.c \ + main/extensions.h \ + main/fbobject.c \ + main/fbobject.h \ + main/feedback.c \ + main/feedback.h \ + main/ff_fragment_shader.cpp \ + main/ffvertex_prog.c \ + main/ffvertex_prog.h \ + main/fog.c \ + main/fog.h \ + main/format_pack.h \ + main/format_pack.c \ + main/format_unpack.h \ + main/format_unpack.c \ + main/formatquery.c \ + main/formatquery.h \ + main/formats.c \ + main/formats.h \ + main/format_utils.c \ + main/format_utils.h \ + main/framebuffer.c \ + main/framebuffer.h \ + main/get.c \ + main/get.h \ + main/genmipmap.c \ + main/genmipmap.h \ + main/getstring.c \ + main/glformats.c \ + main/glformats.h \ + main/glheader.h \ + main/hash.c \ + main/hash.h \ + main/hint.c \ + main/hint.h \ + main/histogram.c \ + main/histogram.h \ + main/image.c \ + main/image.h \ + main/imports.c \ + main/imports.h \ + main/light.c \ + main/light.h \ + main/lines.c \ + main/lines.h \ + main/macros.h \ + main/matrix.c \ + main/matrix.h \ + main/mipmap.c \ + main/mipmap.h \ + main/mm.c \ + main/mm.h \ + main/mtypes.h \ + main/multisample.c \ + main/multisample.h \ + main/objectlabel.c \ + main/objectlabel.h \ + main/pack.c \ + main/pack.h \ + main/pbo.c \ + main/pbo.h \ + main/performance_monitor.c \ + main/performance_monitor.h \ + main/pipelineobj.c \ + main/pipelineobj.h \ + main/pixel.c \ + main/pixel.h \ + main/pixelstore.c \ + main/pixelstore.h \ + main/pixeltransfer.c \ + main/pixeltransfer.h \ + main/points.c \ + main/points.h \ + main/polygon.c \ + main/polygon.h \ + main/querymatrix.c \ + main/querymatrix.h \ + main/queryobj.c \ + main/queryobj.h \ + main/rastpos.c \ + main/rastpos.h \ + main/readpix.c \ + main/readpix.h \ + main/remap.c \ + main/remap.h \ + main/renderbuffer.c \ + main/renderbuffer.h \ + main/samplerobj.c \ + main/samplerobj.h \ + main/scissor.c \ + main/scissor.h \ + main/shaderapi.c \ + main/shaderapi.h \ + main/shaderimage.c \ + main/shaderimage.h \ + main/shaderobj.c \ + main/shaderobj.h \ + main/shader_query.cpp \ + main/shared.c \ + main/shared.h \ + main/state.c \ + main/state.h \ + main/stencil.c \ + main/stencil.h \ + main/syncobj.c \ + main/syncobj.h \ + main/texcompress.c \ + main/texcompress_bptc.c \ + main/texcompress_bptc.h \ + main/texcompress_cpal.c \ + main/texcompress_cpal.h \ + main/texcompress_etc.c \ + main/texcompress_etc.h \ + main/texcompress_etc_tmp.h \ + main/texcompress_fxt1.c \ + main/texcompress_fxt1.h \ + main/texcompress.h \ + main/texcompress_rgtc.c \ + main/texcompress_rgtc.h \ + main/texcompress_s3tc.c \ + main/texcompress_s3tc.h \ + main/texenv.c \ + main/texenv.h \ + main/texenvprogram.h \ + main/texformat.c \ + main/texformat.h \ + main/texgen.c \ + main/texgen.h \ + main/texgetimage.c \ + main/texgetimage.h \ + main/teximage.c \ + main/teximage.h \ + main/texobj.c \ + main/texobj.h \ + main/texparam.c \ + main/texparam.h \ + main/texstate.c \ + main/texstate.h \ + main/texstorage.c \ + main/texstorage.h \ + main/texstore.c \ + main/texstore.h \ + main/textureview.c \ + main/textureview.h \ + main/texturebarrier.c \ + main/texturebarrier.h \ + main/transformfeedback.c \ + main/transformfeedback.h \ + main/uniform_query.cpp \ + main/uniforms.c \ + main/uniforms.h \ + main/varray.c \ + main/varray.h \ + main/vdpau.c \ + main/vdpau.h \ + main/version.c \ + main/version.h \ + main/viewport.c \ + main/viewport.h \ + main/vtxfmt.c \ + main/vtxfmt.h \ $(MAIN_ES_FILES) MATH_FILES = \ - $(SRCDIR)math/m_debug_clip.c \ - $(SRCDIR)math/m_debug_norm.c \ - $(SRCDIR)math/m_debug_xform.c \ - $(SRCDIR)math/m_eval.c \ - $(SRCDIR)math/m_matrix.c \ - $(SRCDIR)math/m_translate.c \ - $(SRCDIR)math/m_vector.c + math/m_debug.h \ + math/m_debug_clip.c \ + math/m_debug_norm.c \ + math/m_debug_util.h \ + math/m_debug_xform.c \ + math/m_eval.c \ + math/m_eval.h \ + math/m_matrix.c \ + math/m_matrix.h \ + math/m_trans_tmp.h \ + math/m_translate.c \ + math/m_translate.h \ + math/m_vector.c \ + math/m_vector.h MATH_XFORM_FILES = \ - $(SRCDIR)math/m_xform.c + math/m_clip_tmp.h \ + math/m_copy_tmp.h \ + math/m_dotprod_tmp.h \ + math/m_norm_tmp.h \ + math/m_xform.c \ + math/m_xform.h \ + math/m_xform_tmp.h SWRAST_FILES = \ - $(SRCDIR)swrast/s_aaline.c \ - $(SRCDIR)swrast/s_aatriangle.c \ - $(SRCDIR)swrast/s_alpha.c \ - $(SRCDIR)swrast/s_atifragshader.c \ - $(SRCDIR)swrast/s_bitmap.c \ - $(SRCDIR)swrast/s_blend.c \ - $(SRCDIR)swrast/s_blit.c \ - $(SRCDIR)swrast/s_clear.c \ - $(SRCDIR)swrast/s_copypix.c \ - $(SRCDIR)swrast/s_context.c \ - $(SRCDIR)swrast/s_depth.c \ - $(SRCDIR)swrast/s_drawpix.c \ - $(SRCDIR)swrast/s_feedback.c \ - $(SRCDIR)swrast/s_fog.c \ - $(SRCDIR)swrast/s_fragprog.c \ - $(SRCDIR)swrast/s_lines.c \ - $(SRCDIR)swrast/s_logic.c \ - $(SRCDIR)swrast/s_masking.c \ - $(SRCDIR)swrast/s_points.c \ - $(SRCDIR)swrast/s_renderbuffer.c \ - $(SRCDIR)swrast/s_span.c \ - $(SRCDIR)swrast/s_stencil.c \ - $(SRCDIR)swrast/s_texcombine.c \ - $(SRCDIR)swrast/s_texfetch.c \ - $(SRCDIR)swrast/s_texfilter.c \ - $(SRCDIR)swrast/s_texrender.c \ - $(SRCDIR)swrast/s_texture.c \ - $(SRCDIR)swrast/s_triangle.c \ - $(SRCDIR)swrast/s_zoom.c + swrast/s_aaline.c \ + swrast/s_aaline.h \ + swrast/s_aalinetemp.h \ + swrast/s_aatriangle.c \ + swrast/s_aatriangle.h \ + swrast/s_aatritemp.h \ + swrast/s_alpha.c \ + swrast/s_alpha.h \ + swrast/s_atifragshader.c \ + swrast/s_atifragshader.h \ + swrast/s_bitmap.c \ + swrast/s_blend.c \ + swrast/s_blend.h \ + swrast/s_blit.c \ + swrast/s_chan.h \ + swrast/s_clear.c \ + swrast/s_context.c \ + swrast/s_context.h \ + swrast/s_copypix.c \ + swrast/s_depth.c \ + swrast/s_depth.h \ + swrast/s_drawpix.c \ + swrast_setup/ss_tritmp.h \ + swrast_setup/ss_vb.h \ + swrast_setup/swrast_setup.h \ + swrast/s_feedback.c \ + swrast/s_feedback.h \ + swrast/s_fog.c \ + swrast/s_fog.h \ + swrast/s_fragprog.c \ + swrast/s_fragprog.h \ + swrast/s_lines.c \ + swrast/s_lines.h \ + swrast/s_linetemp.h \ + swrast/s_logic.c \ + swrast/s_logic.h \ + swrast/s_masking.c \ + swrast/s_masking.h \ + swrast/s_points.c \ + swrast/s_points.h \ + swrast/s_renderbuffer.c \ + swrast/s_renderbuffer.h \ + swrast/s_span.c \ + swrast/s_span.h \ + swrast/s_stencil.c \ + swrast/s_stencil.h \ + swrast/s_texcombine.c \ + swrast/s_texcombine.h \ + swrast/s_texfetch.c \ + swrast/s_texfetch.h \ + swrast/s_texfetch_tmp.h \ + swrast/s_texfilter.c \ + swrast/s_texfilter.h \ + swrast/s_texrender.c \ + swrast/s_texture.c \ + swrast/s_triangle.c \ + swrast/s_triangle.h \ + swrast/s_tritemp.h \ + swrast/swrast.h \ + swrast/s_zoom.c \ + swrast/s_zoom.h SWRAST_SETUP_FILES = \ - $(SRCDIR)swrast_setup/ss_context.c \ - $(SRCDIR)swrast_setup/ss_triangle.c + swrast_setup/ss_context.c \ + swrast_setup/ss_context.h \ + swrast_setup/ss_triangle.c \ + swrast_setup/ss_triangle.h TNL_FILES = \ - $(SRCDIR)tnl/t_context.c \ - $(SRCDIR)tnl/t_pipeline.c \ - $(SRCDIR)tnl/t_draw.c \ - $(SRCDIR)tnl/t_rasterpos.c \ - $(SRCDIR)tnl/t_vb_program.c \ - $(SRCDIR)tnl/t_vb_render.c \ - $(SRCDIR)tnl/t_vb_texgen.c \ - $(SRCDIR)tnl/t_vb_texmat.c \ - $(SRCDIR)tnl/t_vb_vertex.c \ - $(SRCDIR)tnl/t_vb_fog.c \ - $(SRCDIR)tnl/t_vb_light.c \ - $(SRCDIR)tnl/t_vb_normals.c \ - $(SRCDIR)tnl/t_vb_points.c \ - $(SRCDIR)tnl/t_vp_build.c \ - $(SRCDIR)tnl/t_vertex.c \ - $(SRCDIR)tnl/t_vertex_sse.c \ - $(SRCDIR)tnl/t_vertex_generic.c + tnl/t_context.c \ + tnl/t_context.h \ + tnl/t_draw.c \ + tnl/tnl.h \ + tnl/t_pipeline.c \ + tnl/t_pipeline.h \ + tnl/t_rasterpos.c \ + tnl/t_vb_cliptmp.h \ + tnl/t_vb_fog.c \ + tnl/t_vb_light.c \ + tnl/t_vb_lighttmp.h \ + tnl/t_vb_normals.c \ + tnl/t_vb_points.c \ + tnl/t_vb_program.c \ + tnl/t_vb_render.c \ + tnl/t_vb_rendertmp.h \ + tnl/t_vb_texgen.c \ + tnl/t_vb_texmat.c \ + tnl/t_vb_vertex.c \ + tnl/t_vertex.c \ + tnl/t_vertex_generic.c \ + tnl/t_vertex.h \ + tnl/t_vertex_sse.c \ + tnl/t_vp_build.c \ + tnl/t_vp_build.h VBO_FILES = \ - $(SRCDIR)vbo/vbo_context.c \ - $(SRCDIR)vbo/vbo_exec.c \ - $(SRCDIR)vbo/vbo_exec_api.c \ - $(SRCDIR)vbo/vbo_exec_array.c \ - $(SRCDIR)vbo/vbo_exec_draw.c \ - $(SRCDIR)vbo/vbo_exec_eval.c \ - $(SRCDIR)vbo/vbo_noop.c \ - $(SRCDIR)vbo/vbo_primitive_restart.c \ - $(SRCDIR)vbo/vbo_rebase.c \ - $(SRCDIR)vbo/vbo_split.c \ - $(SRCDIR)vbo/vbo_split_copy.c \ - $(SRCDIR)vbo/vbo_split_inplace.c \ - $(SRCDIR)vbo/vbo_save.c \ - $(SRCDIR)vbo/vbo_save_api.c \ - $(SRCDIR)vbo/vbo_save_draw.c \ - $(SRCDIR)vbo/vbo_save_loopback.c + vbo/vbo_attrib.h \ + vbo/vbo_attrib_tmp.h \ + vbo/vbo_context.c \ + vbo/vbo_context.h \ + vbo/vbo_exec_api.c \ + vbo/vbo_exec_array.c \ + vbo/vbo_exec.c \ + vbo/vbo_exec_draw.c \ + vbo/vbo_exec_eval.c \ + vbo/vbo_exec.h \ + vbo/vbo.h \ + vbo/vbo_noop.c \ + vbo/vbo_noop.h \ + vbo/vbo_primitive_restart.c \ + vbo/vbo_rebase.c \ + vbo/vbo_save_api.c \ + vbo/vbo_save.c \ + vbo/vbo_save_draw.c \ + vbo/vbo_save.h \ + vbo/vbo_save_loopback.c \ + vbo/vbo_split.c \ + vbo/vbo_split_copy.c \ + vbo/vbo_split.h \ + vbo/vbo_split_inplace.c STATETRACKER_FILES = \ - $(SRCDIR)state_tracker/st_atom.c \ - $(SRCDIR)state_tracker/st_atom_array.c \ - $(SRCDIR)state_tracker/st_atom_blend.c \ - $(SRCDIR)state_tracker/st_atom_clip.c \ - $(SRCDIR)state_tracker/st_atom_constbuf.c \ - $(SRCDIR)state_tracker/st_atom_depth.c \ - $(SRCDIR)state_tracker/st_atom_framebuffer.c \ - $(SRCDIR)state_tracker/st_atom_msaa.c \ - $(SRCDIR)state_tracker/st_atom_pixeltransfer.c \ - $(SRCDIR)state_tracker/st_atom_sampler.c \ - $(SRCDIR)state_tracker/st_atom_scissor.c \ - $(SRCDIR)state_tracker/st_atom_shader.c \ - $(SRCDIR)state_tracker/st_atom_rasterizer.c \ - $(SRCDIR)state_tracker/st_atom_stipple.c \ - $(SRCDIR)state_tracker/st_atom_texture.c \ - $(SRCDIR)state_tracker/st_atom_viewport.c \ - $(SRCDIR)state_tracker/st_cb_bitmap.c \ - $(SRCDIR)state_tracker/st_cb_blit.c \ - $(SRCDIR)state_tracker/st_cb_bufferobjects.c \ - $(SRCDIR)state_tracker/st_cb_clear.c \ - $(SRCDIR)state_tracker/st_cb_condrender.c \ - $(SRCDIR)state_tracker/st_cb_flush.c \ - $(SRCDIR)state_tracker/st_cb_drawpixels.c \ - $(SRCDIR)state_tracker/st_cb_drawtex.c \ - $(SRCDIR)state_tracker/st_cb_eglimage.c \ - $(SRCDIR)state_tracker/st_cb_fbo.c \ - $(SRCDIR)state_tracker/st_cb_feedback.c \ - $(SRCDIR)state_tracker/st_cb_msaa.c \ - $(SRCDIR)state_tracker/st_cb_program.c \ - $(SRCDIR)state_tracker/st_cb_queryobj.c \ - $(SRCDIR)state_tracker/st_cb_rasterpos.c \ - $(SRCDIR)state_tracker/st_cb_readpixels.c \ - $(SRCDIR)state_tracker/st_cb_syncobj.c \ - $(SRCDIR)state_tracker/st_cb_strings.c \ - $(SRCDIR)state_tracker/st_cb_texture.c \ - $(SRCDIR)state_tracker/st_cb_texturebarrier.c \ - $(SRCDIR)state_tracker/st_cb_viewport.c \ - $(SRCDIR)state_tracker/st_cb_xformfb.c \ - $(SRCDIR)state_tracker/st_context.c \ - $(SRCDIR)state_tracker/st_debug.c \ - $(SRCDIR)state_tracker/st_draw.c \ - $(SRCDIR)state_tracker/st_draw_feedback.c \ - $(SRCDIR)state_tracker/st_extensions.c \ - $(SRCDIR)state_tracker/st_format.c \ - $(SRCDIR)state_tracker/st_gen_mipmap.c \ - $(SRCDIR)state_tracker/st_glsl_to_tgsi.cpp \ - $(SRCDIR)state_tracker/st_manager.c \ - $(SRCDIR)state_tracker/st_mesa_to_tgsi.c \ - $(SRCDIR)state_tracker/st_program.c \ - $(SRCDIR)state_tracker/st_texture.c \ - $(SRCDIR)state_tracker/st_vdpau.c + state_tracker/st_atom_array.c \ + state_tracker/st_atom_blend.c \ + state_tracker/st_atom.c \ + state_tracker/st_atom_clip.c \ + state_tracker/st_atom_constbuf.c \ + state_tracker/st_atom_constbuf.h \ + state_tracker/st_atom_depth.c \ + state_tracker/st_atom_framebuffer.c \ + state_tracker/st_atom.h \ + state_tracker/st_atom_msaa.c \ + state_tracker/st_atom_pixeltransfer.c \ + state_tracker/st_atom_rasterizer.c \ + state_tracker/st_atom_sampler.c \ + state_tracker/st_atom_scissor.c \ + state_tracker/st_atom_shader.c \ + state_tracker/st_atom_shader.h \ + state_tracker/st_atom_stipple.c \ + state_tracker/st_atom_texture.c \ + state_tracker/st_atom_viewport.c \ + state_tracker/st_cache.h \ + state_tracker/st_cb_bitmap.c \ + state_tracker/st_cb_bitmap.h \ + state_tracker/st_cb_blit.c \ + state_tracker/st_cb_blit.h \ + state_tracker/st_cb_bufferobjects.c \ + state_tracker/st_cb_bufferobjects.h \ + state_tracker/st_cb_clear.c \ + state_tracker/st_cb_clear.h \ + state_tracker/st_cb_condrender.c \ + state_tracker/st_cb_condrender.h \ + state_tracker/st_cb_drawpixels.c \ + state_tracker/st_cb_drawpixels.h \ + state_tracker/st_cb_drawtex.c \ + state_tracker/st_cb_drawtex.h \ + state_tracker/st_cb_eglimage.c \ + state_tracker/st_cb_eglimage.h \ + state_tracker/st_cb_fbo.c \ + state_tracker/st_cb_fbo.h \ + state_tracker/st_cb_feedback.c \ + state_tracker/st_cb_feedback.h \ + state_tracker/st_cb_flush.c \ + state_tracker/st_cb_flush.h \ + state_tracker/st_cb_msaa.c \ + state_tracker/st_cb_msaa.h \ + state_tracker/st_cb_program.c \ + state_tracker/st_cb_program.h \ + state_tracker/st_cb_queryobj.c \ + state_tracker/st_cb_queryobj.h \ + state_tracker/st_cb_rasterpos.c \ + state_tracker/st_cb_rasterpos.h \ + state_tracker/st_cb_readpixels.c \ + state_tracker/st_cb_readpixels.h \ + state_tracker/st_cb_strings.c \ + state_tracker/st_cb_strings.h \ + state_tracker/st_cb_syncobj.c \ + state_tracker/st_cb_syncobj.h \ + state_tracker/st_cb_texturebarrier.c \ + state_tracker/st_cb_texturebarrier.h \ + state_tracker/st_cb_texture.c \ + state_tracker/st_cb_texture.h \ + state_tracker/st_cb_viewport.c \ + state_tracker/st_cb_viewport.h \ + state_tracker/st_cb_xformfb.c \ + state_tracker/st_cb_xformfb.h \ + state_tracker/st_context.c \ + state_tracker/st_context.h \ + state_tracker/st_debug.c \ + state_tracker/st_debug.h \ + state_tracker/st_draw.c \ + state_tracker/st_draw_feedback.c \ + state_tracker/st_draw.h \ + state_tracker/st_extensions.c \ + state_tracker/st_extensions.h \ + state_tracker/st_format.c \ + state_tracker/st_format.h \ + state_tracker/st_gen_mipmap.c \ + state_tracker/st_gen_mipmap.h \ + state_tracker/st_gl_api.h \ + state_tracker/st_glsl_to_tgsi.cpp \ + state_tracker/st_glsl_to_tgsi.h \ + state_tracker/st_manager.c \ + state_tracker/st_manager.h \ + state_tracker/st_mesa_to_tgsi.c \ + state_tracker/st_mesa_to_tgsi.h \ + state_tracker/st_program.c \ + state_tracker/st_program.h \ + state_tracker/st_texture.c \ + state_tracker/st_texture.h \ + state_tracker/st_vdpau.c \ + state_tracker/st_vdpau.h PROGRAM_FILES = \ - $(SRCDIR)program/arbprogparse.c \ - $(SRCDIR)program/prog_hash_table.c \ - $(SRCDIR)program/ir_to_mesa.cpp \ - $(SRCDIR)program/program.c \ - $(SRCDIR)program/program_parse_extra.c \ - $(SRCDIR)program/prog_cache.c \ - $(SRCDIR)program/prog_execute.c \ - $(SRCDIR)program/prog_instruction.c \ - $(SRCDIR)program/prog_noise.c \ - $(SRCDIR)program/prog_optimize.c \ - $(SRCDIR)program/prog_opt_constant_fold.c \ - $(SRCDIR)program/prog_parameter.c \ - $(SRCDIR)program/prog_parameter_layout.c \ - $(SRCDIR)program/prog_print.c \ - $(SRCDIR)program/prog_statevars.c \ - $(SRCDIR)program/programopt.c \ - $(SRCDIR)program/sampler.cpp \ - $(SRCDIR)program/string_to_uint_map.cpp \ - $(SRCDIR)program/symbol_table.c \ - $(BUILDDIR)program/lex.yy.c \ - $(BUILDDIR)program/program_parse.tab.c + program/arbprogparse.c \ + program/arbprogparse.h \ + program/hash_table.h \ + program/ir_to_mesa.cpp \ + program/ir_to_mesa.h \ + program/lex.yy.c \ + program/prog_cache.c \ + program/prog_cache.h \ + program/prog_execute.c \ + program/prog_execute.h \ + program/prog_hash_table.c \ + program/prog_instruction.c \ + program/prog_instruction.h \ + program/prog_noise.c \ + program/prog_noise.h \ + program/prog_opt_constant_fold.c \ + program/prog_optimize.c \ + program/prog_optimize.h \ + program/prog_parameter.c \ + program/prog_parameter.h \ + program/prog_parameter_layout.c \ + program/prog_parameter_layout.h \ + program/prog_print.c \ + program/prog_print.h \ + program/program.c \ + program/program.h \ + program/programopt.c \ + program/programopt.h \ + program/program_parse_extra.c \ + program/program_parse.tab.c \ + program/program_parse.tab.h \ + program/program_parser.h \ + program/prog_statevars.c \ + program/prog_statevars.h \ + program/sampler.cpp \ + program/sampler.h \ + program/string_to_uint_map.cpp \ + program/symbol_table.c \ + program/symbol_table.h ASM_C_FILES = \ - $(SRCDIR)x86/common_x86.c \ - $(SRCDIR)x86/x86_xform.c \ - $(SRCDIR)x86/3dnow.c \ - $(SRCDIR)x86/sse.c \ - $(SRCDIR)x86/rtasm/x86sse.c \ - $(SRCDIR)sparc/sparc.c \ - $(SRCDIR)x86-64/x86-64.c + x86/common_x86.c \ + x86/x86_xform.c \ + x86/3dnow.c \ + x86/sse.c \ + x86/rtasm/x86sse.c \ + x86/rtasm/x86sse.h \ + sparc/sparc.c \ + x86-64/x86-64.c X86_FILES = \ - $(SRCDIR)x86/common_x86_asm.S \ - $(SRCDIR)x86/x86_xform2.S \ - $(SRCDIR)x86/x86_xform3.S \ - $(SRCDIR)x86/x86_xform4.S \ - $(SRCDIR)x86/x86_cliptest.S \ - $(SRCDIR)x86/mmx_blend.S \ - $(SRCDIR)x86/3dnow_xform1.S \ - $(SRCDIR)x86/3dnow_xform2.S \ - $(SRCDIR)x86/3dnow_xform3.S \ - $(SRCDIR)x86/3dnow_xform4.S \ - $(SRCDIR)x86/3dnow_normal.S \ - $(SRCDIR)x86/sse_xform1.S \ - $(SRCDIR)x86/sse_xform2.S \ - $(SRCDIR)x86/sse_xform3.S \ - $(SRCDIR)x86/sse_xform4.S \ - $(SRCDIR)x86/sse_normal.S \ - $(SRCDIR)x86/read_rgba_span_x86.S + x86/assyntax.h \ + x86/clip_args.h \ + x86/norm_args.h \ + x86/xform_args.h \ + x86/common_x86_asm.S \ + x86/common_x86_asm.h \ + x86/common_x86_features.h \ + x86/x86_xform.h \ + x86/x86_xform2.S \ + x86/x86_xform3.S \ + x86/x86_xform4.S \ + x86/x86_cliptest.S \ + x86/mmx.h \ + x86/mmx_blend.S \ + x86/mmx_blendtmp.h \ + x86/3dnow.h \ + x86/3dnow_xform1.S \ + x86/3dnow_xform2.S \ + x86/3dnow_xform3.S \ + x86/3dnow_xform4.S \ + x86/sse.h \ + x86/sse_xform1.S \ + x86/sse_xform2.S \ + x86/sse_xform3.S \ + x86/sse_xform4.S \ + x86/sse_normal.S \ + x86/read_rgba_span_x86.S X86_64_FILES = \ - $(SRCDIR)x86-64/xform4.S + x86-64/x86-64.h \ + x86-64/xform4.S SPARC_FILES = \ - $(SRCDIR)sparc/sparc_clip.S \ - $(SRCDIR)sparc/norm.S \ - $(SRCDIR)sparc/xform.S + sparc/sparc.h \ + sparc/sparc_clip.S \ + sparc/sparc_matrix.h \ + sparc/norm.S \ + sparc/xform.S COMMON_DRIVER_FILES = \ - $(SRCDIR)drivers/common/driverfuncs.c \ - $(SRCDIR)drivers/common/meta_blit.c \ - $(SRCDIR)drivers/common/meta_copy_image.c \ - $(SRCDIR)drivers/common/meta_generate_mipmap.c \ - $(SRCDIR)drivers/common/meta.c + drivers/common/driverfuncs.c \ + drivers/common/driverfuncs.h \ + drivers/common/meta_blit.c \ + drivers/common/meta_copy_image.c \ + drivers/common/meta_generate_mipmap.c \ + drivers/common/meta_tex_subimage.c \ + drivers/common/meta.c \ + drivers/common/meta.h # Sources for building non-Gallium drivers @@ -348,7 +597,7 @@ MESA_GALLIUM_FILES = \ $(MATH_FILES) \ $(VBO_FILES) \ $(STATETRACKER_FILES) \ - $(SRCDIR)x86/common_x86.c + x86/common_x86.c ### Include directories diff --git a/mesalib/src/mesa/SConscript b/mesalib/src/mesa/SConscript index e7c4f5ca1..62e81ced1 100644 --- a/mesalib/src/mesa/SConscript +++ b/mesalib/src/mesa/SConscript @@ -15,6 +15,8 @@ env.Append(CPPPATH = [ '#/src/mapi', '#/src/glsl', '#/src/mesa', + '#/src/gallium/include', + '#/src/gallium/auxiliary', Dir('../mapi'), # src/mapi build path Dir('.'), # src/mesa build path ]) @@ -66,6 +68,20 @@ format_info = env.CodeGenerate( command = python_cmd + ' $SCRIPT ' + ' $SOURCE > $TARGET' ) +format_pack = env.CodeGenerate( + target = 'main/format_pack.c', + script = 'main/format_pack.py', + source = 'main/formats.csv', + command = python_cmd + ' $SCRIPT ' + ' $SOURCE > $TARGET' +) + +format_unpack = env.CodeGenerate( + target = 'main/format_unpack.c', + script = 'main/format_unpack.py', + source = 'main/formats.csv', + command = python_cmd + ' $SCRIPT ' + ' $SOURCE > $TARGET' +) + # # Assembly sources # diff --git a/mesalib/src/mesa/drivers/common/driverfuncs.c b/mesalib/src/mesa/drivers/common/driverfuncs.c index 4f0f7a686..0d094ddf4 100644 --- a/mesalib/src/mesa/drivers/common/driverfuncs.c +++ b/mesalib/src/mesa/drivers/common/driverfuncs.c @@ -101,7 +101,7 @@ _mesa_init_driver_functions(struct dd_function_table *driver) driver->TestProxyTexImage = _mesa_test_proxy_teximage; driver->CompressedTexImage = _mesa_store_compressed_teximage; driver->CompressedTexSubImage = _mesa_store_compressed_texsubimage; - driver->GetCompressedTexImage = _mesa_get_compressed_teximage; + driver->GetCompressedTexImage = _mesa_GetCompressedTexImage_sw; driver->BindTexture = NULL; driver->NewTextureObject = _mesa_new_texture_object; driver->DeleteTexture = _mesa_delete_texture_object; @@ -210,7 +210,7 @@ _mesa_init_driver_functions(struct dd_function_table *driver) driver->EndCallList = NULL; /* GL_ARB_texture_storage */ - driver->AllocTextureStorage = _mesa_alloc_texture_storage; + driver->AllocTextureStorage = _mesa_AllocTextureStorage_sw; /* GL_ARB_texture_view */ driver->TextureView = NULL; diff --git a/mesalib/src/mesa/drivers/common/meta.c b/mesalib/src/mesa/drivers/common/meta.c index 87532c1df..3636ee83b 100644 --- a/mesalib/src/mesa/drivers/common/meta.c +++ b/mesalib/src/mesa/drivers/common/meta.c @@ -243,6 +243,7 @@ _mesa_meta_compile_and_link_program(struct gl_context *ctx, void _mesa_meta_setup_blit_shader(struct gl_context *ctx, GLenum target, + bool do_depth, struct blit_shader_table *table) { char *vs_source, *fs_source; @@ -292,10 +293,11 @@ _mesa_meta_setup_blit_shader(struct gl_context *ctx, "void main()\n" "{\n" " gl_FragColor = %s(texSampler, %s);\n" - " gl_FragDepth = gl_FragColor.x;\n" + "%s" "}\n", fs_preprocess, shader->type, fs_input, - shader->func, shader->texcoords); + shader->func, shader->texcoords, + do_depth ? " gl_FragDepth = gl_FragColor.x;\n" : ""); _mesa_meta_compile_and_link_program(ctx, vs_source, fs_source, ralloc_asprintf(mem_ctx, "%s blit", @@ -825,15 +827,18 @@ _mesa_meta_end(struct gl_context *ctx) const GLbitfield state = save->SavedState; int i; - /* After starting a new occlusion query, initialize the results to the - * values saved previously. The driver will then continue to increment - * these values. - */ + /* Grab the result of the old occlusion query before starting it again. The + * old result is added to the result of the new query so the driver will + * continue adding where it left off. */ if (state & MESA_META_OCCLUSION_QUERY) { if (save->CurrentOcclusionObject) { - _mesa_BeginQuery(save->CurrentOcclusionObject->Target, - save->CurrentOcclusionObject->Id); - ctx->Query.CurrentOcclusionObject->Result = save->CurrentOcclusionObject->Result; + struct gl_query_object *q = save->CurrentOcclusionObject; + GLuint64EXT result; + if (!q->Ready) + ctx->Driver.WaitQuery(ctx, q); + result = q->Result; + _mesa_BeginQuery(q->Target, q->Id); + ctx->Query.CurrentOcclusionObject->Result += result; } } @@ -1212,16 +1217,6 @@ _mesa_meta_end(struct gl_context *ctx) } -/** - * Determine whether Mesa is currently in a meta state. - */ -GLboolean -_mesa_meta_in_progress(struct gl_context *ctx) -{ - return ctx->Meta->SaveStackDepth != 0; -} - - /** * Convert Z from a normalized value in the range [0, 1] to an object-space * Z coordinate in [-1, +1] so that drawing at the new Z position with the @@ -2801,7 +2796,8 @@ copytexsubimage_using_blit_framebuffer(struct gl_context *ctx, GLuint dims, * are too strict for CopyTexImage. We know meta will be fine with format * changes. */ - mask = _mesa_meta_BlitFramebuffer(ctx, x, y, + mask = _mesa_meta_BlitFramebuffer(ctx, ctx->ReadBuffer, ctx->DrawBuffer, + x, y, x + width, y + height, xoffset, yoffset, xoffset + width, yoffset + height, @@ -3045,7 +3041,7 @@ decompress_texture_image(struct gl_context *ctx, _mesa_meta_setup_vertex_objects(&decompress->VAO, &decompress->VBO, true, 2, 4, 0); - _mesa_meta_setup_blit_shader(ctx, target, &decompress->shaders); + _mesa_meta_setup_blit_shader(ctx, target, false, &decompress->shaders); } else { _mesa_meta_setup_ff_tnl_for_blit(&decompress->VAO, &decompress->VBO, 3); } @@ -3177,7 +3173,7 @@ _mesa_meta_GetTexImage(struct gl_context *ctx, { if (_mesa_is_format_compressed(texImage->TexFormat)) { GLuint slice; - bool result; + bool result = true; for (slice = 0; slice < texImage->Depth; slice++) { void *dst; @@ -3208,7 +3204,7 @@ _mesa_meta_GetTexImage(struct gl_context *ctx, return; } - _mesa_get_teximage(ctx, format, type, pixels, texImage); + _mesa_GetTexImage_sw(ctx, format, type, pixels, texImage); } diff --git a/mesalib/src/mesa/drivers/common/meta.h b/mesalib/src/mesa/drivers/common/meta.h index 6ecf3c005..e7d894df1 100644 --- a/mesalib/src/mesa/drivers/common/meta.h +++ b/mesalib/src/mesa/drivers/common/meta.h @@ -298,7 +298,8 @@ struct blit_state { GLuint VAO; GLuint VBO; - struct blit_shader_table shaders; + struct blit_shader_table shaders_with_depth; + struct blit_shader_table shaders_without_depth; GLuint msaa_shaders[BLIT_MSAA_SHADER_COUNT]; struct temp_texture depthTex; bool no_ctsi_fallback; @@ -446,8 +447,11 @@ _mesa_meta_begin(struct gl_context *ctx, GLbitfield state); extern void _mesa_meta_end(struct gl_context *ctx); -extern GLboolean -_mesa_meta_in_progress(struct gl_context *ctx); +static inline bool +_mesa_meta_in_progress(struct gl_context *ctx) +{ + return ctx->Meta->SaveStackDepth != 0; +} extern void _mesa_meta_fb_tex_blit_begin(const struct gl_context *ctx, @@ -471,12 +475,16 @@ _mesa_meta_setup_sampler(struct gl_context *ctx, extern GLbitfield _mesa_meta_BlitFramebuffer(struct gl_context *ctx, + const struct gl_framebuffer *readFb, + const struct gl_framebuffer *drawFb, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); extern void _mesa_meta_and_swrast_BlitFramebuffer(struct gl_context *ctx, + struct gl_framebuffer *readFb, + struct gl_framebuffer *drawFb, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, @@ -519,6 +527,23 @@ extern void _mesa_meta_GenerateMipmap(struct gl_context *ctx, GLenum target, struct gl_texture_object *texObj); +extern bool +_mesa_meta_pbo_TexSubImage(struct gl_context *ctx, GLuint dims, + struct gl_texture_image *tex_image, + int xoffset, int yoffset, int zoffset, + int width, int height, int depth, + GLenum format, GLenum type, const void *pixels, + bool allocate_storage, bool create_pbo, + const struct gl_pixelstore_attrib *packing); + +extern bool +_mesa_meta_pbo_GetTexSubImage(struct gl_context *ctx, GLuint dims, + struct gl_texture_image *tex_image, + int xoffset, int yoffset, int zoffset, + int width, int height, int depth, + GLenum format, GLenum type, const void *pixels, + const struct gl_pixelstore_attrib *packing); + extern void _mesa_meta_CopyTexSubImage(struct gl_context *ctx, GLuint dims, struct gl_texture_image *texImage, @@ -612,6 +637,7 @@ _mesa_meta_setup_copypix_texture(struct gl_context *ctx, void _mesa_meta_setup_blit_shader(struct gl_context *ctx, GLenum target, + bool do_depth, struct blit_shader_table *table); void diff --git a/mesalib/src/mesa/drivers/common/meta_blit.c b/mesalib/src/mesa/drivers/common/meta_blit.c index 01cb532fe..3406be1ed 100755 --- a/mesalib/src/mesa/drivers/common/meta_blit.c +++ b/mesalib/src/mesa/drivers/common/meta_blit.c @@ -232,6 +232,7 @@ setup_glsl_msaa_blit_scaled_shader(struct gl_context *ctx, static void setup_glsl_msaa_blit_shader(struct gl_context *ctx, struct blit_state *blit, + const struct gl_framebuffer *drawFb, struct gl_renderbuffer *src_rb, GLenum target) { @@ -267,7 +268,7 @@ setup_glsl_msaa_blit_shader(struct gl_context *ctx, /* Update the assert if we plan to support more than 16X MSAA. */ assert(shader_offset >= 0 && shader_offset <= 4); - if (ctx->DrawBuffer->Visual.samples > 1) { + if (drawFb->Visual.samples > 1) { /* If you're calling meta_BlitFramebuffer with the destination * multisampled, this is the only path that will work -- swrast and * CopyTexImage won't work on it either. @@ -508,9 +509,11 @@ setup_glsl_msaa_blit_shader(struct gl_context *ctx, static void setup_glsl_blit_framebuffer(struct gl_context *ctx, struct blit_state *blit, + const struct gl_framebuffer *drawFb, struct gl_renderbuffer *src_rb, GLenum target, GLenum filter, - bool is_scaled_blit) + bool is_scaled_blit, + bool do_depth) { unsigned texcoord_size; bool is_target_multisample = target == GL_TEXTURE_2D_MULTISAMPLE || @@ -529,9 +532,11 @@ setup_glsl_blit_framebuffer(struct gl_context *ctx, if (is_target_multisample && is_filter_scaled_resolve && is_scaled_blit) { setup_glsl_msaa_blit_scaled_shader(ctx, blit, src_rb, target, filter); } else if (is_target_multisample) { - setup_glsl_msaa_blit_shader(ctx, blit, src_rb, target); + setup_glsl_msaa_blit_shader(ctx, blit, drawFb, src_rb, target); } else { - _mesa_meta_setup_blit_shader(ctx, target, &blit->shaders); + _mesa_meta_setup_blit_shader(ctx, target, do_depth, + do_depth ? &blit->shaders_with_depth + : &blit->shaders_without_depth); } } @@ -543,12 +548,13 @@ setup_glsl_blit_framebuffer(struct gl_context *ctx, */ static bool blitframebuffer_texture(struct gl_context *ctx, + const struct gl_framebuffer *readFb, + const struct gl_framebuffer *drawFb, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLenum filter, GLint flipX, GLint flipY, GLboolean glsl_version, GLboolean do_depth) { - const struct gl_framebuffer *readFb = ctx->ReadBuffer; int att_index = do_depth ? BUFFER_DEPTH : readFb->_ColorReadBufferIndex; const struct gl_renderbuffer_attachment *readAtt = &readFb->Attachment[att_index]; @@ -642,7 +648,8 @@ blitframebuffer_texture(struct gl_context *ctx, scaled_blit = dstW != srcW || dstH != srcH; if (glsl_version) { - setup_glsl_blit_framebuffer(ctx, blit, rb, target, filter, scaled_blit); + setup_glsl_blit_framebuffer(ctx, blit, drawFb, rb, target, filter, scaled_blit, + do_depth); } else { _mesa_meta_setup_ff_tnl_for_blit(&ctx->Meta->Blit.VAO, @@ -677,7 +684,7 @@ blitframebuffer_texture(struct gl_context *ctx, */ if (ctx->Extensions.EXT_texture_sRGB_decode) { if (_mesa_get_format_color_encoding(rb->Format) == GL_SRGB && - ctx->DrawBuffer->Visual.sRGBCapable) { + drawFb->Visual.sRGBCapable) { _mesa_SamplerParameteri(fb_tex_blit.sampler, GL_TEXTURE_SRGB_DECODE_EXT, GL_DECODE_EXT); _mesa_set_framebuffer_srgb(ctx, GL_TRUE); @@ -701,7 +708,7 @@ blitframebuffer_texture(struct gl_context *ctx, if (target == GL_TEXTURE_2D) { const struct gl_texture_image *texImage - = _mesa_select_tex_image(ctx, texObj, target, srcLevel); + = _mesa_select_tex_image(texObj, target, srcLevel); s0 = srcX0 / (float) texImage->Width; s1 = srcX1 / (float) texImage->Width; t0 = srcY0 / (float) texImage->Height; @@ -869,6 +876,8 @@ _mesa_meta_setup_sampler(struct gl_context *ctx, */ GLbitfield _mesa_meta_BlitFramebuffer(struct gl_context *ctx, + const struct gl_framebuffer *readFb, + const struct gl_framebuffer *drawFb, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) @@ -890,7 +899,7 @@ _mesa_meta_BlitFramebuffer(struct gl_context *ctx, ctx->Extensions.ARB_fragment_shader; /* Multisample texture blit support requires texture multisample. */ - if (ctx->ReadBuffer->Visual.samples > 0 && + if (readFb->Visual.samples > 0 && !ctx->Extensions.ARB_texture_multisample) { return mask; } @@ -898,7 +907,8 @@ _mesa_meta_BlitFramebuffer(struct gl_context *ctx, /* Clip a copy of the blit coordinates. If these differ from the input * coordinates, then we'll set the scissor. */ - if (!_mesa_clip_blit(ctx, &clip.srcX0, &clip.srcY0, &clip.srcX1, &clip.srcY1, + if (!_mesa_clip_blit(ctx, readFb, drawFb, + &clip.srcX0, &clip.srcY0, &clip.srcX1, &clip.srcY1, &clip.dstX0, &clip.dstY0, &clip.dstX1, &clip.dstY1)) { /* clipped/scissored everything away */ return 0; @@ -926,7 +936,8 @@ _mesa_meta_BlitFramebuffer(struct gl_context *ctx, /* Try faster, direct texture approach first */ if (mask & GL_COLOR_BUFFER_BIT) { - if (blitframebuffer_texture(ctx, srcX0, srcY0, srcX1, srcY1, + if (blitframebuffer_texture(ctx, readFb, drawFb, + srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, filter, dstFlipX, dstFlipY, use_glsl_version, false)) { @@ -935,7 +946,8 @@ _mesa_meta_BlitFramebuffer(struct gl_context *ctx, } if (mask & GL_DEPTH_BUFFER_BIT && use_glsl_version) { - if (blitframebuffer_texture(ctx, srcX0, srcY0, srcX1, srcY1, + if (blitframebuffer_texture(ctx, readFb, drawFb, + srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, filter, dstFlipX, dstFlipY, use_glsl_version, true)) { @@ -962,7 +974,8 @@ _mesa_meta_glsl_blit_cleanup(struct blit_state *blit) blit->VBO = 0; } - _mesa_meta_blit_shader_table_cleanup(&blit->shaders); + _mesa_meta_blit_shader_table_cleanup(&blit->shaders_with_depth); + _mesa_meta_blit_shader_table_cleanup(&blit->shaders_without_depth); _mesa_DeleteTextures(1, &blit->depthTex.TexObj); blit->depthTex.TexObj = 0; @@ -970,20 +983,22 @@ _mesa_meta_glsl_blit_cleanup(struct blit_state *blit) void _mesa_meta_and_swrast_BlitFramebuffer(struct gl_context *ctx, + struct gl_framebuffer *readFb, + struct gl_framebuffer *drawFb, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) { - mask = _mesa_meta_BlitFramebuffer(ctx, + mask = _mesa_meta_BlitFramebuffer(ctx, readFb, drawFb, srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); if (mask == 0x0) return; - _swrast_BlitFramebuffer(ctx, + _swrast_BlitFramebuffer(ctx, readFb, drawFb, srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); diff --git a/mesalib/src/mesa/drivers/common/meta_copy_image.c b/mesalib/src/mesa/drivers/common/meta_copy_image.c index fc0cbaf1b..1729766f7 100644 --- a/mesalib/src/mesa/drivers/common/meta_copy_image.c +++ b/mesalib/src/mesa/drivers/common/meta_copy_image.c @@ -189,7 +189,8 @@ _mesa_meta_CopyImageSubData_uncompressed(struct gl_context *ctx, * We have already created views to ensure that the texture formats * match. */ - ctx->Driver.BlitFramebuffer(ctx, src_x, src_y, + ctx->Driver.BlitFramebuffer(ctx, ctx->ReadBuffer, ctx->DrawBuffer, + src_x, src_y, src_x + src_width, src_y + src_height, dst_x, dst_y, dst_x + src_width, dst_y + src_height, diff --git a/mesalib/src/mesa/drivers/common/meta_generate_mipmap.c b/mesalib/src/mesa/drivers/common/meta_generate_mipmap.c index 8ffd8da3b..c1b6d3c1f 100644 --- a/mesalib/src/mesa/drivers/common/meta_generate_mipmap.c +++ b/mesalib/src/mesa/drivers/common/meta_generate_mipmap.c @@ -71,7 +71,7 @@ fallback_required(struct gl_context *ctx, GLenum target, } srcLevel = texObj->BaseLevel; - baseImage = _mesa_select_tex_image(ctx, texObj, target, srcLevel); + baseImage = _mesa_select_tex_image(texObj, target, srcLevel); if (!baseImage) { _mesa_perf_debug(ctx, MESA_DEBUG_SEVERITY_HIGH, "glGenerateMipmap() couldn't find base teximage\n"); @@ -193,7 +193,7 @@ _mesa_meta_GenerateMipmap(struct gl_context *ctx, GLenum target, if (use_glsl_version) { _mesa_meta_setup_vertex_objects(&mipmap->VAO, &mipmap->VBO, true, 2, 4, 0); - _mesa_meta_setup_blit_shader(ctx, target, &mipmap->shaders); + _mesa_meta_setup_blit_shader(ctx, target, false, &mipmap->shaders); } else { _mesa_meta_setup_ff_tnl_for_blit(&mipmap->VAO, &mipmap->VBO, 3); _mesa_set_enable(ctx, target, GL_TRUE); @@ -265,7 +265,7 @@ _mesa_meta_GenerateMipmap(struct gl_context *ctx, GLenum target, GLsizei srcWidth, srcHeight, srcDepth; GLsizei dstWidth, dstHeight, dstDepth; - srcImage = _mesa_select_tex_image(ctx, texObj, faceTarget, srcLevel); + srcImage = _mesa_select_tex_image(texObj, faceTarget, srcLevel); assert(srcImage->Border == 0); /* src size */ @@ -304,7 +304,7 @@ _mesa_meta_GenerateMipmap(struct gl_context *ctx, GLenum target, */ break; } - dstImage = _mesa_select_tex_image(ctx, texObj, faceTarget, dstLevel); + dstImage = _mesa_select_tex_image(texObj, faceTarget, dstLevel); /* limit minification to src level */ _mesa_TexParameteri(target, GL_TEXTURE_MAX_LEVEL, srcLevel); diff --git a/mesalib/src/mesa/drivers/common/meta_tex_subimage.c b/mesalib/src/mesa/drivers/common/meta_tex_subimage.c new file mode 100644 index 000000000..68c8273fe --- /dev/null +++ b/mesalib/src/mesa/drivers/common/meta_tex_subimage.c @@ -0,0 +1,361 @@ +/* + * Mesa 3-D graphics library + * + * Copyright (C) 2015 Intel Corporation. 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 + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: + * Jason Ekstrand + */ + +#include "bufferobj.h" +#include "buffers.h" +#include "fbobject.h" +#include "glformats.h" +#include "glheader.h" +#include "image.h" +#include "macros.h" +#include "meta.h" +#include "pbo.h" +#include "shaderapi.h" +#include "state.h" +#include "teximage.h" +#include "texobj.h" +#include "texstate.h" +#include "uniforms.h" +#include "varray.h" + +static struct gl_texture_image * +create_texture_for_pbo(struct gl_context *ctx, bool create_pbo, + GLenum pbo_target, int width, int height, int depth, + GLenum format, GLenum type, const void *pixels, + const struct gl_pixelstore_attrib *packing, + GLuint *tmp_pbo, GLuint *tmp_tex) +{ + uint32_t pbo_format; + GLenum internal_format; + unsigned row_stride; + struct gl_buffer_object *buffer_obj; + struct gl_texture_object *tex_obj; + struct gl_texture_image *tex_image; + bool read_only; + + if ((packing->ImageHeight != 0 && packing->ImageHeight != height) || + packing->SwapBytes || + packing->LsbFirst || + packing->Invert) + return NULL; + + pbo_format = _mesa_format_from_format_and_type(format, type); + if (_mesa_format_is_mesa_array_format(pbo_format)) + pbo_format = _mesa_format_from_array_format(pbo_format); + + if (!pbo_format || !ctx->TextureFormatSupported[pbo_format]) + return NULL; + + /* Account for SKIP_PIXELS, SKIP_ROWS, ALIGNMENT, and SKIP_IMAGES */ + pixels = _mesa_image_address3d(packing, pixels, + width, height, format, type, 0, 0, 0); + row_stride = _mesa_image_row_stride(packing, width, format, type); + + if (_mesa_is_bufferobj(packing->BufferObj)) { + *tmp_pbo = 0; + buffer_obj = packing->BufferObj; + } else { + assert(create_pbo); + + _mesa_GenBuffers(1, tmp_pbo); + + /* We are not doing this inside meta_begin/end. However, we know the + * client doesn't have the given target bound, so we can go ahead and + * squash it. We'll set it back when we're done. + */ + _mesa_BindBuffer(pbo_target, *tmp_pbo); + + _mesa_BufferData(pbo_target, row_stride * height, pixels, GL_STREAM_DRAW); + + buffer_obj = ctx->Unpack.BufferObj; + pixels = NULL; + + _mesa_BindBuffer(pbo_target, 0); + } + + _mesa_GenTextures(1, tmp_tex); + tex_obj = _mesa_lookup_texture(ctx, *tmp_tex); + tex_obj->Target = depth > 1 ? GL_TEXTURE_2D_ARRAY : GL_TEXTURE_2D; + tex_obj->Immutable = GL_TRUE; + _mesa_initialize_texture_object(ctx, tex_obj, *tmp_tex, GL_TEXTURE_2D); + + internal_format = _mesa_get_format_base_format(pbo_format); + + tex_image = _mesa_get_tex_image(ctx, tex_obj, tex_obj->Target, 0); + _mesa_init_teximage_fields(ctx, tex_image, width, height, depth, + 0, internal_format, pbo_format); + + read_only = pbo_target == GL_PIXEL_UNPACK_BUFFER; + if (!ctx->Driver.SetTextureStorageForBufferObject(ctx, tex_obj, + buffer_obj, + (intptr_t)pixels, + row_stride, + read_only)) { + _mesa_DeleteTextures(1, tmp_tex); + _mesa_DeleteBuffers(1, tmp_pbo); + return NULL; + } + + return tex_image; +} + +bool +_mesa_meta_pbo_TexSubImage(struct gl_context *ctx, GLuint dims, + struct gl_texture_image *tex_image, + int xoffset, int yoffset, int zoffset, + int width, int height, int depth, + GLenum format, GLenum type, const void *pixels, + bool allocate_storage, bool create_pbo, + const struct gl_pixelstore_attrib *packing) +{ + GLuint pbo = 0, pbo_tex = 0, fbos[2] = { 0, 0 }; + struct gl_texture_image *pbo_tex_image; + GLenum status; + bool success = false; + int z; + + /* XXX: This should probably be passed in from somewhere */ + const char *where = "_mesa_meta_pbo_TexSubImage"; + + if (!_mesa_is_bufferobj(packing->BufferObj) && !create_pbo) + return false; + + if (format == GL_DEPTH_COMPONENT || + format == GL_DEPTH_STENCIL || + format == GL_STENCIL_INDEX || + format == GL_COLOR_INDEX) + return false; + + if (ctx->_ImageTransferState) + return false; + + if (!_mesa_validate_pbo_access(dims, packing, width, height, depth, + format, type, INT_MAX, pixels)) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "%s(out of bounds PBO access)", where); + return true; + } + + if (_mesa_check_disallowed_mapping(packing->BufferObj)) { + /* buffer is mapped - that's an error */ + _mesa_error(ctx, GL_INVALID_OPERATION, "%s(PBO is mapped)", where); + return true; + } + + pbo_tex_image = create_texture_for_pbo(ctx, create_pbo, + GL_PIXEL_UNPACK_BUFFER, + width, height, depth, + format, type, pixels, packing, + &pbo, &pbo_tex); + if (!pbo_tex_image) + return false; + + if (allocate_storage) + ctx->Driver.AllocTextureImageBuffer(ctx, tex_image); + + /* Only stash the current FBO */ + _mesa_meta_begin(ctx, 0); + + _mesa_GenFramebuffers(2, fbos); + _mesa_BindFramebuffer(GL_READ_FRAMEBUFFER, fbos[0]); + _mesa_BindFramebuffer(GL_DRAW_FRAMEBUFFER, fbos[1]); + + if (tex_image->TexObject->Target == GL_TEXTURE_1D_ARRAY) { + assert(depth == 1); + depth = height; + height = 1; + } + + _mesa_meta_bind_fbo_image(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, + pbo_tex_image, 0); + /* If this passes on the first layer it should pass on the others */ + status = _mesa_CheckFramebufferStatus(GL_READ_FRAMEBUFFER); + if (status != GL_FRAMEBUFFER_COMPLETE) + goto fail; + + _mesa_meta_bind_fbo_image(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, + tex_image, zoffset); + /* If this passes on the first layer it should pass on the others */ + status = _mesa_CheckFramebufferStatus(GL_DRAW_FRAMEBUFFER); + if (status != GL_FRAMEBUFFER_COMPLETE) + goto fail; + + _mesa_update_state(ctx); + + if (_mesa_meta_BlitFramebuffer(ctx, ctx->ReadBuffer, ctx->DrawBuffer, + 0, 0, width, height, + xoffset, yoffset, + xoffset + width, yoffset + height, + GL_COLOR_BUFFER_BIT, GL_NEAREST)) + goto fail; + + for (z = 1; z < depth; z++) { + _mesa_meta_bind_fbo_image(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, + pbo_tex_image, z); + _mesa_meta_bind_fbo_image(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, + tex_image, zoffset + z); + + _mesa_update_state(ctx); + + _mesa_meta_BlitFramebuffer(ctx, ctx->ReadBuffer, ctx->DrawBuffer, + 0, 0, width, height, + xoffset, yoffset, + xoffset + width, yoffset + height, + GL_COLOR_BUFFER_BIT, GL_NEAREST); + } + + success = true; + +fail: + _mesa_DeleteFramebuffers(2, fbos); + _mesa_DeleteTextures(1, &pbo_tex); + _mesa_DeleteBuffers(1, &pbo); + + _mesa_meta_end(ctx); + + return success; +} + +bool +_mesa_meta_pbo_GetTexSubImage(struct gl_context *ctx, GLuint dims, + struct gl_texture_image *tex_image, + int xoffset, int yoffset, int zoffset, + int width, int height, int depth, + GLenum format, GLenum type, const void *pixels, + const struct gl_pixelstore_attrib *packing) +{ + GLuint pbo = 0, pbo_tex = 0, fbos[2] = { 0, 0 }; + struct gl_texture_image *pbo_tex_image; + GLenum status; + bool success = false; + int z; + + /* XXX: This should probably be passed in from somewhere */ + const char *where = "_mesa_meta_pbo_GetTexSubImage"; + + if (!_mesa_is_bufferobj(packing->BufferObj)) + return false; + + if (format == GL_DEPTH_COMPONENT || + format == GL_DEPTH_STENCIL || + format == GL_STENCIL_INDEX || + format == GL_COLOR_INDEX) + return false; + + if (ctx->_ImageTransferState) + return false; + + if (!_mesa_validate_pbo_access(dims, packing, width, height, depth, + format, type, INT_MAX, pixels)) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "%s(out of bounds PBO access)", where); + return true; + } + + if (_mesa_check_disallowed_mapping(packing->BufferObj)) { + /* buffer is mapped - that's an error */ + _mesa_error(ctx, GL_INVALID_OPERATION, "%s(PBO is mapped)", where); + return true; + } + + pbo_tex_image = create_texture_for_pbo(ctx, false, GL_PIXEL_PACK_BUFFER, + width, height, depth, + format, type, pixels, packing, + &pbo, &pbo_tex); + if (!pbo_tex_image) + return false; + + /* Only stash the current FBO */ + _mesa_meta_begin(ctx, 0); + + _mesa_GenFramebuffers(2, fbos); + + if (tex_image && tex_image->TexObject->Target == GL_TEXTURE_1D_ARRAY) { + assert(depth == 1); + depth = height; + height = 1; + } + + /* If we were given a texture, bind it to the read framebuffer. If not, + * we're doing a ReadPixels and we should just use whatever framebuffer + * the client has bound. + */ + if (tex_image) { + _mesa_BindFramebuffer(GL_READ_FRAMEBUFFER, fbos[0]); + _mesa_meta_bind_fbo_image(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, + tex_image, zoffset); + /* If this passes on the first layer it should pass on the others */ + status = _mesa_CheckFramebufferStatus(GL_READ_FRAMEBUFFER); + if (status != GL_FRAMEBUFFER_COMPLETE) + goto fail; + } else { + assert(depth == 1); + } + + _mesa_BindFramebuffer(GL_DRAW_FRAMEBUFFER, fbos[1]); + _mesa_meta_bind_fbo_image(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, + pbo_tex_image, 0); + /* If this passes on the first layer it should pass on the others */ + status = _mesa_CheckFramebufferStatus(GL_DRAW_FRAMEBUFFER); + if (status != GL_FRAMEBUFFER_COMPLETE) + goto fail; + + _mesa_update_state(ctx); + + if (_mesa_meta_BlitFramebuffer(ctx, ctx->ReadBuffer, ctx->DrawBuffer, + xoffset, yoffset, + xoffset + width, yoffset + height, + 0, 0, width, height, + GL_COLOR_BUFFER_BIT, GL_NEAREST)) + goto fail; + + for (z = 1; z < depth; z++) { + _mesa_meta_bind_fbo_image(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, + tex_image, zoffset + z); + _mesa_meta_bind_fbo_image(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, + pbo_tex_image, z); + + _mesa_update_state(ctx); + + _mesa_meta_BlitFramebuffer(ctx, ctx->ReadBuffer, ctx->DrawBuffer, + xoffset, yoffset, + xoffset + width, yoffset + height, + 0, 0, width, height, + GL_COLOR_BUFFER_BIT, GL_NEAREST); + } + + success = true; + +fail: + _mesa_DeleteFramebuffers(2, fbos); + _mesa_DeleteTextures(1, &pbo_tex); + _mesa_DeleteBuffers(1, &pbo); + + _mesa_meta_end(ctx); + + return success; +} diff --git a/mesalib/src/mesa/drivers/dri/Makefile.am b/mesalib/src/mesa/drivers/dri/Makefile.am index 2009da921..fa1de103b 100644 --- a/mesalib/src/mesa/drivers/dri/Makefile.am +++ b/mesalib/src/mesa/drivers/dri/Makefile.am @@ -46,7 +46,8 @@ pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = dri.pc driincludedir = $(includedir)/GL/internal -driinclude_HEADERS = $(top_srcdir)/include/GL/internal/dri_interface.h +driinclude_HEADERS = \ + $(top_srcdir)/include/GL/internal/dri_interface.h nodist_EXTRA_mesa_dri_drivers_la_SOURCES = dummy.cpp mesa_dri_drivers_la_SOURCES = @@ -76,6 +77,12 @@ all-local: mesa_dri_drivers.la ln -f $(top_builddir)/$(LIB_DIR)/mesa_dri_drivers.so \ $(top_builddir)/$(LIB_DIR)/$$i; \ done; + +clean-local: + $(AM_V_GEN)$(RM) $(top_builddir)/$(LIB_DIR)/mesa_dri_drivers.so; + $(AM_V_GEN)for i in $(MEGADRIVERS); do \ + $(RM) $(top_builddir)/$(LIB_DIR)/$$i; \ + done; endif # hardlink each megadriver instance, but don't actually have @@ -85,6 +92,11 @@ install-data-hook: ln -f $(DESTDIR)$(dridir)/mesa_dri_drivers.so \ $(DESTDIR)$(dridir)/$$i; \ done; - $(RM) -f $(DESTDIR)$(dridir)/mesa_dri_drivers.* + $(RM) $(DESTDIR)$(dridir)/mesa_dri_drivers.* + +uninstall-hook: + for i in $(MEGADRIVERS); do \ + $(RM) $(DESTDIR)$(dridir)/$$i; \ + done; endif diff --git a/mesalib/src/mesa/drivers/dri/common/Makefile.am b/mesalib/src/mesa/drivers/dri/common/Makefile.am index 7222a96c6..da8f97a98 100644 --- a/mesalib/src/mesa/drivers/dri/common/Makefile.am +++ b/mesalib/src/mesa/drivers/dri/common/Makefile.am @@ -23,11 +23,15 @@ SUBDIRS = xmlpool include Makefile.sources +EXTRA_DIST = drirc xmlpool.h SConscript + AM_CFLAGS = \ -I$(top_srcdir)/include \ -I$(top_srcdir)/src/ \ -I$(top_srcdir)/src/mapi \ -I$(top_srcdir)/src/mesa/ \ + -I$(top_srcdir)/src/gallium/include \ + -I$(top_srcdir)/src/gallium/auxiliary \ $(DEFINES) \ $(EXPAT_CFLAGS) \ $(VISIBILITY_CFLAGS) diff --git a/mesalib/src/mesa/drivers/dri/common/Makefile.sources b/mesalib/src/mesa/drivers/dri/common/Makefile.sources index 43b289e90..d00ec5f73 100644 --- a/mesalib/src/mesa/drivers/dri/common/Makefile.sources +++ b/mesalib/src/mesa/drivers/dri/common/Makefile.sources @@ -1,7 +1,10 @@ DRI_COMMON_FILES := \ utils.c \ + utils.h \ dri_util.c \ - xmlconfig.c + dri_util.h \ + xmlconfig.c \ + xmlconfig.h # Paths are relative to MESA_TOP. mesa_dri_common_INCLUDES := \ diff --git a/mesalib/src/mesa/drivers/dri/common/drirc b/mesalib/src/mesa/drivers/dri/common/drirc index 4b9841bd2..cecd6a953 100644 --- a/mesalib/src/mesa/drivers/dri/common/drirc +++ b/mesalib/src/mesa/drivers/dri/common/drirc @@ -87,5 +87,9 @@ TODO: document the other workarounds. + + + diff --git a/mesalib/src/mesa/drivers/dri/common/mmio.h b/mesalib/src/mesa/drivers/dri/common/mmio.h deleted file mode 100644 index ce95d8c90..000000000 --- a/mesalib/src/mesa/drivers/dri/common/mmio.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * (C) Copyright IBM Corporation 2004 - * 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 - * on the rights to use, copy, modify, merge, publish, distribute, sub - * license, 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 NON-INFRINGEMENT. IN NO EVENT SHALL - * IBM AND/OR THEIR SUPPLIERS 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 mmio.h - * Functions for properly handling memory mapped IO on various platforms. - * - * \author Ian Romanick - */ - - -#ifndef MMIO_H -#define MMIO_H - -#include "main/glheader.h" - -#if defined( __powerpc__ ) - -static INLINE uint32_t -read_MMIO_LE32( volatile void * base, unsigned long offset ) -{ - uint32_t val; - - __asm__ __volatile__( "lwbrx %0, %1, %2 ; eieio" - : "=r" (val) - : "b" (base), "r" (offset) ); - return val; -} - -#else - -static INLINE uint32_t -read_MMIO_LE32( volatile void * base, unsigned long offset ) -{ - volatile uint32_t * p = (volatile uint32_t *) (((volatile char *) base) + offset); - return LE32_TO_CPU( p[0] ); -} - -#endif - -#endif /* MMIO_H */ diff --git a/mesalib/src/mesa/drivers/dri/common/xmlconfig.c b/mesalib/src/mesa/drivers/dri/common/xmlconfig.c index ffef73e8a..6beee4eb3 100644 --- a/mesalib/src/mesa/drivers/dri/common/xmlconfig.c +++ b/mesalib/src/mesa/drivers/dri/common/xmlconfig.c @@ -339,8 +339,7 @@ static unsigned char parseValue (driOptionValue *v, driOptionType type, v->_float = strToF (string, &tail); break; case DRI_STRING: - if (v->_string) - free (v->_string); + free (v->_string); v->_string = strndup(string, STRING_CONF_MAXLEN); return GL_TRUE; } diff --git a/mesalib/src/mesa/drivers/dri/common/xmlpool/Makefile.am b/mesalib/src/mesa/drivers/dri/common/xmlpool/Makefile.am index 57e604845..da7d03480 100644 --- a/mesalib/src/mesa/drivers/dri/common/xmlpool/Makefile.am +++ b/mesalib/src/mesa/drivers/dri/common/xmlpool/Makefile.am @@ -52,7 +52,9 @@ POT=xmlpool.pot .PHONY: all clean pot po mo +EXTRA_DIST = gen_xmlpool.py t_options.h $(POS) SConscript BUILT_SOURCES = options.h +CLEANFILES = $(MOS) options.h # All generated files are cleaned up. clean: diff --git a/mesalib/src/mesa/drivers/dri/swrast/Makefile.am b/mesalib/src/mesa/drivers/dri/swrast/Makefile.am index 0837b4518..bfc3c10e3 100644 --- a/mesalib/src/mesa/drivers/dri/swrast/Makefile.am +++ b/mesalib/src/mesa/drivers/dri/swrast/Makefile.am @@ -29,6 +29,8 @@ AM_CFLAGS = \ -I$(top_srcdir)/src/ \ -I$(top_srcdir)/src/mapi \ -I$(top_srcdir)/src/mesa/ \ + -I$(top_srcdir)/src/gallium/include \ + -I$(top_srcdir)/src/gallium/auxiliary \ -I$(top_srcdir)/src/mesa/drivers/dri/common \ -I$(top_builddir)/src/mesa/drivers/dri/common \ $(DEFINES) \ diff --git a/mesalib/src/mesa/drivers/dri/swrast/Makefile.sources b/mesalib/src/mesa/drivers/dri/swrast/Makefile.sources index 70e432feb..8154fcaf7 100644 --- a/mesalib/src/mesa/drivers/dri/swrast/Makefile.sources +++ b/mesalib/src/mesa/drivers/dri/swrast/Makefile.sources @@ -1,5 +1,6 @@ SWRAST_DRIVER_FILES = \ - swrast.c + swrast.c \ + swrast_priv.h SWRAST_C_FILES = \ $(SWRAST_DRIVER_FILES) diff --git a/mesalib/src/mesa/drivers/dri/swrast/swrast.c b/mesalib/src/mesa/drivers/dri/swrast/swrast.c index 396eaecbd..e42ba658f 100644 --- a/mesalib/src/mesa/drivers/dri/swrast/swrast.c +++ b/mesalib/src/mesa/drivers/dri/swrast/swrast.c @@ -59,6 +59,7 @@ #include "main/teximage.h" #include "main/texformat.h" +#include "main/texobj.h" #include "main/texstate.h" #include "swrast_priv.h" @@ -66,8 +67,8 @@ PUBLIC const __DRIextension **__driDriverGetExtensions_swrast(void); -const char const *swrast_vendor_string = "Mesa Project"; -const char const *swrast_renderer_string = "Software Rasterizer"; +const char * const swrast_vendor_string = "Mesa Project"; +const char * const swrast_renderer_string = "Software Rasterizer"; /** * Screen and config-related functions diff --git a/mesalib/src/mesa/drivers/haiku/swrast/SConscript b/mesalib/src/mesa/drivers/haiku/swrast/SConscript index 2c25f727d..907325e32 100644 --- a/mesalib/src/mesa/drivers/haiku/swrast/SConscript +++ b/mesalib/src/mesa/drivers/haiku/swrast/SConscript @@ -13,6 +13,7 @@ env.Append(CPPPATH = [ ]) env.Prepend(LIBS = [ + mesautil, glsl, mesa, ]) diff --git a/mesalib/src/mesa/main/.gitignore b/mesalib/src/mesa/main/.gitignore index 328aaf570..3e81f5310 100755 --- a/mesalib/src/mesa/main/.gitignore +++ b/mesalib/src/mesa/main/.gitignore @@ -10,3 +10,5 @@ get_hash.h get_hash.h.tmp format_info.c glapitable.h +format_pack.c +format_unpack.c diff --git a/mesalib/src/mesa/main/api_validate.c b/mesalib/src/mesa/main/api_validate.c index bf4fa3ea8..9c2e29e64 100644 --- a/mesalib/src/mesa/main/api_validate.c +++ b/mesalib/src/mesa/main/api_validate.c @@ -35,80 +35,72 @@ #include -/** - * \return number of bytes in array [count] of type. - */ -static GLsizei -index_bytes(GLenum type, GLsizei count) -{ - if (type == GL_UNSIGNED_INT) { - return count * sizeof(GLuint); - } - else if (type == GL_UNSIGNED_BYTE) { - return count * sizeof(GLubyte); - } - else { - ASSERT(type == GL_UNSIGNED_SHORT); - return count * sizeof(GLushort); - } -} - - /** * Check if OK to draw arrays/elements. */ -static GLboolean +static bool check_valid_to_render(struct gl_context *ctx, const char *function) { if (!_mesa_valid_to_render(ctx, function)) { - return GL_FALSE; + return false; } switch (ctx->API) { case API_OPENGLES2: /* For ES2, we can draw if we have a vertex program/shader). */ - if (!ctx->VertexProgram._Current) - return GL_FALSE; - break; + return ctx->VertexProgram._Current != NULL; case API_OPENGLES: /* For OpenGL ES, only draw if we have vertex positions */ if (!ctx->Array.VAO->VertexAttrib[VERT_ATTRIB_POS].Enabled) - return GL_FALSE; + return false; break; case API_OPENGL_CORE: - if (ctx->Array.VAO == ctx->Array.DefaultVAO) - return GL_FALSE; - /* fallthrough */ + /* Section 10.4 (Drawing Commands Using Vertex Arrays) of the OpenGL 4.5 + * Core Profile spec says: + * + * "An INVALID_OPERATION error is generated if no vertex array + * object is bound (see section 10.3.1)." + */ + if (ctx->Array.VAO == ctx->Array.DefaultVAO) { + _mesa_error(ctx, GL_INVALID_OPERATION, "%s(no VAO bound)", function); + return false; + } + + /* Section 7.3 (Program Objects) of the OpenGL 4.5 Core Profile spec + * says: + * + * "If there is no active program for the vertex or fragment shader + * stages, the results of vertex and/or fragment processing will be + * undefined. However, this is not an error." + * + * The fragment shader is not tested here because other state (e.g., + * GL_RASTERIZER_DISCARD) affects whether or not we actually care. + */ + return ctx->VertexProgram._Current != NULL; + case API_OPENGL_COMPAT: - { - const struct gl_shader_program *vsProg = - ctx->_Shader->CurrentProgram[MESA_SHADER_VERTEX]; - GLboolean haveVertexShader = (vsProg && vsProg->LinkStatus); - GLboolean haveVertexProgram = ctx->VertexProgram._Enabled; - if (haveVertexShader || haveVertexProgram) { - /* Draw regardless of whether or not we have any vertex arrays. - * (Ex: could draw a point using a constant vertex pos) - */ - return GL_TRUE; - } - else { - /* Draw if we have vertex positions (GL_VERTEX_ARRAY or generic - * array [0]). - */ - return (ctx->Array.VAO->VertexAttrib[VERT_ATTRIB_POS].Enabled || - ctx->Array.VAO->VertexAttrib[VERT_ATTRIB_GENERIC0].Enabled); - } + if (ctx->VertexProgram._Current != NULL) { + /* Draw regardless of whether or not we have any vertex arrays. + * (Ex: could draw a point using a constant vertex pos) + */ + return true; + } else { + /* Draw if we have vertex positions (GL_VERTEX_ARRAY or generic + * array [0]). + */ + return (ctx->Array.VAO->VertexAttrib[VERT_ATTRIB_POS].Enabled || + ctx->Array.VAO->VertexAttrib[VERT_ATTRIB_GENERIC0].Enabled); } break; default: - assert(!"Invalid API value in check_valid_to_render()"); + unreachable("Invalid API value in check_valid_to_render()"); } - return GL_TRUE; + return true; } @@ -121,27 +113,21 @@ check_valid_to_render(struct gl_context *ctx, const char *function) bool _mesa_is_valid_prim_mode(struct gl_context *ctx, GLenum mode) { - switch (mode) { - case GL_POINTS: - case GL_LINES: - case GL_LINE_LOOP: - case GL_LINE_STRIP: - case GL_TRIANGLES: - case GL_TRIANGLE_STRIP: - case GL_TRIANGLE_FAN: + /* The overwhelmingly common case is (mode <= GL_TRIANGLE_FAN). Test that + * first and exit. You would think that a switch-statement would be the + * right approach, but at least GCC 4.7.2 generates some pretty dire code + * for the common case. + */ + if (likely(mode <= GL_TRIANGLE_FAN)) return true; - case GL_QUADS: - case GL_QUAD_STRIP: - case GL_POLYGON: + + if (mode <= GL_POLYGON) return (ctx->API == API_OPENGL_COMPAT); - case GL_LINES_ADJACENCY: - case GL_LINE_STRIP_ADJACENCY: - case GL_TRIANGLES_ADJACENCY: - case GL_TRIANGLE_STRIP_ADJACENCY: + + if (mode <= GL_TRIANGLE_STRIP_ADJACENCY) return _mesa_has_geometry_shaders(ctx); - default: - return false; - } + + return false; } @@ -310,18 +296,12 @@ valid_elements_type(struct gl_context *ctx, GLenum type, const char *name) } } -/** - * Error checking for glDrawElements(). Includes parameter checking - * and VBO bounds checking. - * \return GL_TRUE if OK to render, GL_FALSE if error found - */ -GLboolean -_mesa_validate_DrawElements(struct gl_context *ctx, - GLenum mode, GLsizei count, GLenum type, - const GLvoid *indices, GLint basevertex) +static bool +validate_DrawElements_common(struct gl_context *ctx, + GLenum mode, GLsizei count, GLenum type, + const GLvoid *indices, + const char *caller) { - FLUSH_CURRENT(ctx, 0); - /* From the GLES3 specification, section 2.14.2 (Transform Feedback * Primitive Capture): * @@ -331,44 +311,50 @@ _mesa_validate_DrawElements(struct gl_context *ctx, */ if (_mesa_is_gles3(ctx) && _mesa_is_xfb_active_and_unpaused(ctx)) { _mesa_error(ctx, GL_INVALID_OPERATION, - "glDrawElements(transform feedback active)"); - return GL_FALSE; + "%s(transform feedback active)", caller); + return false; } if (count < 0) { - _mesa_error(ctx, GL_INVALID_VALUE, "glDrawElements(count)" ); - return GL_FALSE; + _mesa_error(ctx, GL_INVALID_VALUE, "%s(count)", caller); + return false; } - if (!_mesa_valid_prim_mode(ctx, mode, "glDrawElements")) { - return GL_FALSE; + if (!_mesa_valid_prim_mode(ctx, mode, caller)) { + return false; } - if (!valid_elements_type(ctx, type, "glDrawElements")) - return GL_FALSE; + if (!valid_elements_type(ctx, type, caller)) + return false; - if (!check_valid_to_render(ctx, "glDrawElements")) - return GL_FALSE; + if (!check_valid_to_render(ctx, caller)) + return false; - /* Vertex buffer object tests */ - if (_mesa_is_bufferobj(ctx->Array.VAO->IndexBufferObj)) { - /* use indices in the buffer object */ - /* make sure count doesn't go outside buffer bounds */ - if (index_bytes(type, count) > ctx->Array.VAO->IndexBufferObj->Size) { - _mesa_warning(ctx, "glDrawElements index out of buffer bounds"); - return GL_FALSE; - } - } - else { - /* not using a VBO */ - if (!indices) - return GL_FALSE; - } + /* Not using a VBO for indices, so avoid NULL pointer derefs later. + */ + if (!_mesa_is_bufferobj(ctx->Array.VAO->IndexBufferObj) && indices == NULL) + return false; if (count == 0) - return GL_FALSE; + return false; - return GL_TRUE; + return true; +} + +/** + * Error checking for glDrawElements(). Includes parameter checking + * and VBO bounds checking. + * \return GL_TRUE if OK to render, GL_FALSE if error found + */ +GLboolean +_mesa_validate_DrawElements(struct gl_context *ctx, + GLenum mode, GLsizei count, GLenum type, + const GLvoid *indices) +{ + FLUSH_CURRENT(ctx, 0); + + return validate_DrawElements_common(ctx, mode, count, type, indices, + "glDrawElements"); } @@ -381,7 +367,7 @@ GLboolean _mesa_validate_MultiDrawElements(struct gl_context *ctx, GLenum mode, const GLsizei *count, GLenum type, const GLvoid * const *indices, - GLuint primcount, const GLint *basevertex) + GLuint primcount) { unsigned i; @@ -405,21 +391,9 @@ _mesa_validate_MultiDrawElements(struct gl_context *ctx, if (!check_valid_to_render(ctx, "glMultiDrawElements")) return GL_FALSE; - /* Vertex buffer object tests */ - if (_mesa_is_bufferobj(ctx->Array.VAO->IndexBufferObj)) { - /* use indices in the buffer object */ - /* make sure count doesn't go outside buffer bounds */ - for (i = 0; i < primcount; i++) { - if (index_bytes(type, count[i]) > - ctx->Array.VAO->IndexBufferObj->Size) { - _mesa_warning(ctx, - "glMultiDrawElements index out of buffer bounds"); - return GL_FALSE; - } - } - } - else { - /* not using a VBO */ + /* Not using a VBO for indices, so avoid NULL pointer derefs later. + */ + if (!_mesa_is_bufferobj(ctx->Array.VAO->IndexBufferObj)) { for (i = 0; i < primcount; i++) { if (!indices[i]) return GL_FALSE; @@ -439,62 +413,17 @@ GLboolean _mesa_validate_DrawRangeElements(struct gl_context *ctx, GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, - const GLvoid *indices, GLint basevertex) + const GLvoid *indices) { FLUSH_CURRENT(ctx, 0); - /* From the GLES3 specification, section 2.14.2 (Transform Feedback - * Primitive Capture): - * - * The error INVALID_OPERATION is also generated by DrawElements, - * DrawElementsInstanced, and DrawRangeElements while transform feedback - * is active and not paused, regardless of mode. - */ - if (_mesa_is_gles3(ctx) && _mesa_is_xfb_active_and_unpaused(ctx)) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "glDrawElements(transform feedback active)"); - return GL_FALSE; - } - - if (count < 0) { - _mesa_error(ctx, GL_INVALID_VALUE, "glDrawRangeElements(count)" ); - return GL_FALSE; - } - - if (!_mesa_valid_prim_mode(ctx, mode, "glDrawRangeElements")) { - return GL_FALSE; - } - if (end < start) { _mesa_error(ctx, GL_INVALID_VALUE, "glDrawRangeElements(endArray.VAO->IndexBufferObj)) { - /* use indices in the buffer object */ - /* make sure count doesn't go outside buffer bounds */ - if (index_bytes(type, count) > ctx->Array.VAO->IndexBufferObj->Size) { - _mesa_warning(ctx, "glDrawRangeElements index out of buffer bounds"); - return GL_FALSE; - } - } - else { - /* not using a VBO */ - if (!indices) - return GL_FALSE; - } - - if (count == 0) - return GL_FALSE; - - return GL_TRUE; + return validate_DrawElements_common(ctx, mode, count, type, indices, + "glDrawRangeElements"); } @@ -504,8 +433,7 @@ _mesa_validate_DrawRangeElements(struct gl_context *ctx, GLenum mode, * \return GL_TRUE if OK to render, GL_FALSE if error found */ GLboolean -_mesa_validate_DrawArrays(struct gl_context *ctx, - GLenum mode, GLint start, GLsizei count) +_mesa_validate_DrawArrays(struct gl_context *ctx, GLenum mode, GLsizei count) { struct gl_transform_feedback_object *xfb_obj = ctx->TransformFeedback.CurrentObject; @@ -621,67 +549,19 @@ _mesa_validate_DrawArraysInstanced(struct gl_context *ctx, GLenum mode, GLint fi GLboolean _mesa_validate_DrawElementsInstanced(struct gl_context *ctx, GLenum mode, GLsizei count, GLenum type, - const GLvoid *indices, GLsizei numInstances, - GLint basevertex) + const GLvoid *indices, GLsizei numInstances) { FLUSH_CURRENT(ctx, 0); - /* From the GLES3 specification, section 2.14.2 (Transform Feedback - * Primitive Capture): - * - * The error INVALID_OPERATION is also generated by DrawElements, - * DrawElementsInstanced, and DrawRangeElements while transform feedback - * is active and not paused, regardless of mode. - */ - if (_mesa_is_gles3(ctx) && _mesa_is_xfb_active_and_unpaused(ctx)) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "glDrawElements(transform feedback active)"); - return GL_FALSE; - } - - if (count < 0) { + if (numInstances < 0) { _mesa_error(ctx, GL_INVALID_VALUE, - "glDrawElementsInstanced(count=%d)", count); + "glDrawElementsInstanced(numInstances=%d)", numInstances); return GL_FALSE; } - if (!_mesa_valid_prim_mode(ctx, mode, "glDrawElementsInstanced")) { - return GL_FALSE; - } - - if (!valid_elements_type(ctx, type, "glDrawElementsInstanced")) - return GL_FALSE; - - if (numInstances <= 0) { - if (numInstances < 0) - _mesa_error(ctx, GL_INVALID_VALUE, - "glDrawElementsInstanced(numInstances=%d)", numInstances); - return GL_FALSE; - } - - if (!check_valid_to_render(ctx, "glDrawElementsInstanced")) - return GL_FALSE; - - /* Vertex buffer object tests */ - if (_mesa_is_bufferobj(ctx->Array.VAO->IndexBufferObj)) { - /* use indices in the buffer object */ - /* make sure count doesn't go outside buffer bounds */ - if (index_bytes(type, count) > ctx->Array.VAO->IndexBufferObj->Size) { - _mesa_warning(ctx, - "glDrawElementsInstanced index out of buffer bounds"); - return GL_FALSE; - } - } - else { - /* not using a VBO */ - if (!indices) - return GL_FALSE; - } - - if (count == 0) - return GL_FALSE; - - return GL_TRUE; + return validate_DrawElements_common(ctx, mode, count, type, indices, + "glDrawElementsInstanced") + && (numInstances > 0); } diff --git a/mesalib/src/mesa/main/api_validate.h b/mesalib/src/mesa/main/api_validate.h index 0bb91c675..0ce7b69d5 100644 --- a/mesalib/src/mesa/main/api_validate.h +++ b/mesalib/src/mesa/main/api_validate.h @@ -43,25 +43,24 @@ _mesa_valid_prim_mode(struct gl_context *ctx, GLenum mode, const char *name); extern GLboolean -_mesa_validate_DrawArrays(struct gl_context *ctx, - GLenum mode, GLint start, GLsizei count); +_mesa_validate_DrawArrays(struct gl_context *ctx, GLenum mode, GLsizei count); extern GLboolean _mesa_validate_DrawElements(struct gl_context *ctx, GLenum mode, GLsizei count, GLenum type, - const GLvoid *indices, GLint basevertex); + const GLvoid *indices); extern GLboolean _mesa_validate_MultiDrawElements(struct gl_context *ctx, GLenum mode, const GLsizei *count, GLenum type, const GLvoid * const *indices, - GLuint primcount, const GLint *basevertex); + GLuint primcount); extern GLboolean _mesa_validate_DrawRangeElements(struct gl_context *ctx, GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, - const GLvoid *indices, GLint basevertex); + const GLvoid *indices); extern GLboolean @@ -71,8 +70,7 @@ _mesa_validate_DrawArraysInstanced(struct gl_context *ctx, GLenum mode, GLint fi extern GLboolean _mesa_validate_DrawElementsInstanced(struct gl_context *ctx, GLenum mode, GLsizei count, GLenum type, - const GLvoid *indices, GLsizei primcount, - GLint basevertex); + const GLvoid *indices, GLsizei primcount); extern GLboolean _mesa_validate_DrawTransformFeedback(struct gl_context *ctx, diff --git a/mesalib/src/mesa/main/attrib.c b/mesalib/src/mesa/main/attrib.c index 4684615a8..07934b9bc 100644 --- a/mesalib/src/mesa/main/attrib.c +++ b/mesalib/src/mesa/main/attrib.c @@ -1248,8 +1248,10 @@ _mesa_PopAttrib(void) _mesa_FrontFace(polygon->FrontFace); _mesa_PolygonMode(GL_FRONT, polygon->FrontMode); _mesa_PolygonMode(GL_BACK, polygon->BackMode); - _mesa_PolygonOffset(polygon->OffsetFactor, - polygon->OffsetUnits); + _mesa_polygon_offset_clamp(ctx, + polygon->OffsetFactor, + polygon->OffsetUnits, + polygon->OffsetClamp); _mesa_set_enable(ctx, GL_POLYGON_SMOOTH, polygon->SmoothFlag); _mesa_set_enable(ctx, GL_POLYGON_STIPPLE, polygon->StippleFlag); _mesa_set_enable(ctx, GL_CULL_FACE, polygon->CullFlag); diff --git a/mesalib/src/mesa/main/bitset.h b/mesalib/src/mesa/main/bitset.h deleted file mode 100644 index 601fd0ebf..000000000 --- a/mesalib/src/mesa/main/bitset.h +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Mesa 3-D graphics library - * - * Copyright (C) 2006 Brian Paul 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 - * 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. - */ - -/** - * \file bitset.h - * \brief Bitset of arbitrary size definitions. - * \author Michal Krol - */ - -#ifndef BITSET_H -#define BITSET_H - -#include "imports.h" - -/**************************************************************************** - * generic bitset implementation - */ - -#define BITSET_WORD GLuint -#define BITSET_WORDBITS (sizeof (BITSET_WORD) * 8) - -/* bitset declarations - */ -#define BITSET_WORDS(bits) (ALIGN(bits, BITSET_WORDBITS) / BITSET_WORDBITS) -#define BITSET_DECLARE(name, bits) BITSET_WORD name[BITSET_WORDS(bits)] - -/* bitset operations - */ -#define BITSET_COPY(x, y) memcpy( (x), (y), sizeof (x) ) -#define BITSET_EQUAL(x, y) (memcmp( (x), (y), sizeof (x) ) == 0) -#define BITSET_ZERO(x) memset( (x), 0, sizeof (x) ) -#define BITSET_ONES(x) memset( (x), 0xff, sizeof (x) ) - -#define BITSET_BITWORD(b) ((b) / BITSET_WORDBITS) -#define BITSET_BIT(b) (1 << ((b) % BITSET_WORDBITS)) - -/* single bit operations - */ -#define BITSET_TEST(x, b) ((x)[BITSET_BITWORD(b)] & BITSET_BIT(b)) -#define BITSET_SET(x, b) ((x)[BITSET_BITWORD(b)] |= BITSET_BIT(b)) -#define BITSET_CLEAR(x, b) ((x)[BITSET_BITWORD(b)] &= ~BITSET_BIT(b)) - -#define BITSET_MASK(b) ((b) == BITSET_WORDBITS ? ~0 : BITSET_BIT(b) - 1) -#define BITSET_RANGE(b, e) (BITSET_MASK((e) + 1) & ~BITSET_MASK(b)) - -/* bit range operations - */ -#define BITSET_TEST_RANGE(x, b, e) \ - (BITSET_BITWORD(b) == BITSET_BITWORD(e) ? \ - ((x)[BITSET_BITWORD(b)] & BITSET_RANGE(b, e)) : \ - (assert (!"BITSET_TEST_RANGE: bit range crosses word boundary"), 0)) -#define BITSET_SET_RANGE(x, b, e) \ - (BITSET_BITWORD(b) == BITSET_BITWORD(e) ? \ - ((x)[BITSET_BITWORD(b)] |= BITSET_RANGE(b, e)) : \ - (assert (!"BITSET_SET_RANGE: bit range crosses word boundary"), 0)) -#define BITSET_CLEAR_RANGE(x, b, e) \ - (BITSET_BITWORD(b) == BITSET_BITWORD(e) ? \ - ((x)[BITSET_BITWORD(b)] &= ~BITSET_RANGE(b, e)) : \ - (assert (!"BITSET_CLEAR_RANGE: bit range crosses word boundary"), 0)) - -/* Get first bit set in a bitset. - */ -static inline int -__bitset_ffs(const BITSET_WORD *x, int n) -{ - int i; - - for (i = 0; i < n; i++) { - if (x[i]) - return ffs(x[i]) + BITSET_WORDBITS * i; - } - - return 0; -} - -#define BITSET_FFS(x) __bitset_ffs(x, Elements(x)) - -#endif diff --git a/mesalib/src/mesa/main/blit.c b/mesalib/src/mesa/main/blit.c index 0b70a3da4..b97b56479 100644 --- a/mesalib/src/mesa/main/blit.c +++ b/mesalib/src/mesa/main/blit.c @@ -506,7 +506,7 @@ _mesa_BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, } ASSERT(ctx->Driver.BlitFramebuffer); - ctx->Driver.BlitFramebuffer(ctx, + ctx->Driver.BlitFramebuffer(ctx, ctx->ReadBuffer, ctx->DrawBuffer, srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); diff --git a/mesalib/src/mesa/main/bufferobj.c b/mesalib/src/mesa/main/bufferobj.c index 011e7be3f..303b268a8 100755 --- a/mesalib/src/mesa/main/bufferobj.c +++ b/mesalib/src/mesa/main/bufferobj.c @@ -117,6 +117,11 @@ get_buffer_target(struct gl_context *ctx, GLenum target) return &ctx->AtomicBuffer; } break; + case GL_EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD: + if (ctx->Extensions.AMD_pinned_memory) { + return &ctx->ExternalVirtualMemoryBuffer; + } + break; default: return NULL; } @@ -1226,7 +1231,7 @@ _mesa_DeleteBuffers(GLsizei n, const GLuint *ids) } } - if (ctx->UniformBuffer == bufObj) { + if (ctx->AtomicBuffer == bufObj) { _mesa_BindBuffer( GL_ATOMIC_COUNTER_BUFFER, 0 ); } @@ -1242,6 +1247,10 @@ _mesa_DeleteBuffers(GLsizei n, const GLuint *ids) _mesa_BindBuffer( GL_TEXTURE_BUFFER, 0 ); } + if (ctx->ExternalVirtualMemoryBuffer == bufObj) { + _mesa_BindBuffer(GL_EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD, 0); + } + /* The ID is immediately freed for re-use */ _mesa_HashRemove(ctx->Shared->BufferObjects, ids[i]); /* Make sure we do not run into the classic ABA problem on bind. @@ -1381,7 +1390,16 @@ _mesa_BufferStorage(GLenum target, GLsizeiptr size, const GLvoid *data, ASSERT(ctx->Driver.BufferData); if (!ctx->Driver.BufferData(ctx, target, size, data, GL_DYNAMIC_DRAW, flags, bufObj)) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBufferStorage()"); + if (target == GL_EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD) { + /* Even though the interaction between AMD_pinned_memory and + * glBufferStorage is not described in the spec, Graham Sellers + * said that it should behave the same as glBufferData. + */ + _mesa_error(ctx, GL_INVALID_OPERATION, "glBufferStorage()"); + } + else { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBufferStorage()"); + } } } @@ -1465,7 +1483,18 @@ _mesa_BufferData(GLenum target, GLsizeiptrARB size, GL_MAP_WRITE_BIT | GL_DYNAMIC_STORAGE_BIT, bufObj)) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBufferDataARB()"); + if (target == GL_EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD) { + /* From GL_AMD_pinned_memory: + * + * INVALID_OPERATION is generated by BufferData if is + * EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD, and the store cannot be + * mapped to the GPU address space. + */ + _mesa_error(ctx, GL_INVALID_OPERATION, "glBufferData()"); + } + else { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBufferData()"); + } } } @@ -2887,7 +2916,7 @@ static void unbind_uniform_buffers(struct gl_context *ctx, GLuint first, GLsizei count) { struct gl_buffer_object *bufObj = ctx->Shared->NullBufferObj; - GLuint i; + GLint i; for (i = 0; i < count; i++) set_ubo_binding(ctx, &ctx->UniformBufferBindings[first + i], @@ -2898,7 +2927,7 @@ static void bind_uniform_buffers_base(struct gl_context *ctx, GLuint first, GLsizei count, const GLuint *buffers) { - GLuint i; + GLint i; if (!error_check_bind_uniform_buffers(ctx, first, count, "glBindBuffersBase")) return; @@ -2965,7 +2994,7 @@ bind_uniform_buffers_range(struct gl_context *ctx, GLuint first, GLsizei count, const GLuint *buffers, const GLintptr *offsets, const GLsizeiptr *sizes) { - GLuint i; + GLint i; if (!error_check_bind_uniform_buffers(ctx, first, count, "glBindBuffersRange")) @@ -3122,7 +3151,7 @@ unbind_xfb_buffers(struct gl_context *ctx, GLuint first, GLsizei count) { struct gl_buffer_object * const bufObj = ctx->Shared->NullBufferObj; - GLuint i; + GLint i; for (i = 0; i < count; i++) _mesa_set_transform_feedback_binding(ctx, tfObj, first + i, @@ -3136,7 +3165,7 @@ bind_xfb_buffers_base(struct gl_context *ctx, { struct gl_transform_feedback_object *tfObj = ctx->TransformFeedback.CurrentObject; - GLuint i; + GLint i; if (!error_check_bind_xfb_buffers(ctx, tfObj, first, count, "glBindBuffersBase")) @@ -3204,7 +3233,7 @@ bind_xfb_buffers_range(struct gl_context *ctx, { struct gl_transform_feedback_object *tfObj = ctx->TransformFeedback.CurrentObject; - GLuint i; + GLint i; if (!error_check_bind_xfb_buffers(ctx, tfObj, first, count, "glBindBuffersRange")) @@ -3342,7 +3371,7 @@ static void unbind_atomic_buffers(struct gl_context *ctx, GLuint first, GLsizei count) { struct gl_buffer_object * const bufObj = ctx->Shared->NullBufferObj; - GLuint i; + GLint i; for (i = 0; i < count; i++) set_atomic_buffer_binding(ctx, &ctx->AtomicBufferBindings[first + i], @@ -3355,7 +3384,7 @@ bind_atomic_buffers_base(struct gl_context *ctx, GLsizei count, const GLuint *buffers) { - GLuint i; + GLint i; if (!error_check_bind_atomic_buffers(ctx, first, count, "glBindBuffersBase")) @@ -3422,7 +3451,7 @@ bind_atomic_buffers_range(struct gl_context *ctx, const GLintptr *offsets, const GLsizeiptr *sizes) { - GLuint i; + GLint i; if (!error_check_bind_atomic_buffers(ctx, first, count, "glBindBuffersRange")) diff --git a/mesalib/src/mesa/main/buffers.c b/mesalib/src/mesa/main/buffers.c index 1ee20098d..e5076e9bb 100644 --- a/mesalib/src/mesa/main/buffers.c +++ b/mesalib/src/mesa/main/buffers.c @@ -301,7 +301,7 @@ _mesa_DrawBuffer(GLenum buffer) void GLAPIENTRY _mesa_DrawBuffers(GLsizei n, const GLenum *buffers) { - GLint output; + GLuint output; GLbitfield usedBufferMask, supportedMask; GLbitfield destMask[MAX_DRAW_BUFFERS]; GET_CURRENT_CONTEXT(ctx); @@ -326,8 +326,9 @@ _mesa_DrawBuffers(GLsizei n, const GLenum *buffers) /* From the ES 3.0 specification, page 180: * "If the GL is bound to the default framebuffer, then n must be 1 * and the constant must be BACK or NONE." + * (same restriction applies with GL_EXT_draw_buffers specification) */ - if (_mesa_is_gles3(ctx) && _mesa_is_winsys_fbo(ctx->DrawBuffer) && + if (ctx->API == API_OPENGLES2 && _mesa_is_winsys_fbo(ctx->DrawBuffer) && (n != 1 || (buffers[0] != GL_NONE && buffers[0] != GL_BACK))) { _mesa_error(ctx, GL_INVALID_OPERATION, "glDrawBuffers(buffer)"); return; @@ -335,6 +336,20 @@ _mesa_DrawBuffers(GLsizei n, const GLenum *buffers) /* complicated error checking... */ for (output = 0; output < n; output++) { + /* Section 4.2 (Whole Framebuffer Operations) of the OpenGL 3.0 + * specification says: + * + * "Each buffer listed in bufs must be BACK, NONE, or one of the values + * from table 4.3 (NONE, COLOR_ATTACHMENTi)" + */ + if (_mesa_is_gles3(ctx) && buffers[output] != GL_NONE && + buffers[output] != GL_BACK && + (buffers[output] < GL_COLOR_ATTACHMENT0 || + buffers[output] >= GL_COLOR_ATTACHMENT0 + ctx->Const.MaxColorAttachments)) { + _mesa_error(ctx, GL_INVALID_ENUM, "glDrawBuffers(buffer)"); + return; + } + if (buffers[output] == GL_NONE) { destMask[output] = 0x0; } @@ -399,8 +414,9 @@ _mesa_DrawBuffers(GLsizei n, const GLenum *buffers) /* ES 3.0 is even more restrictive. From the ES 3.0 spec, page 180: * "If the GL is bound to a framebuffer object, the ith buffer listed * in bufs must be COLOR_ATTACHMENTi or NONE. [...] INVALID_OPERATION." + * (same restriction applies with GL_EXT_draw_buffers specification) */ - if (_mesa_is_gles3(ctx) && _mesa_is_user_fbo(ctx->DrawBuffer) && + if (ctx->API == API_OPENGLES2 && _mesa_is_user_fbo(ctx->DrawBuffer) && buffers[output] != GL_NONE && buffers[output] != GL_COLOR_ATTACHMENT0 + output) { _mesa_error(ctx, GL_INVALID_OPERATION, "glDrawBuffers(buffer)"); diff --git a/mesalib/src/mesa/main/clear.c b/mesalib/src/mesa/main/clear.c index f7f15cf59..3c4ced8ed 100644 --- a/mesalib/src/mesa/main/clear.c +++ b/mesalib/src/mesa/main/clear.c @@ -58,10 +58,6 @@ _mesa_ClearIndex( GLfloat c ) * \param alpha alpha component. * * \sa glClearColor(). - * - * Clamps the parameters and updates gl_colorbuffer_attrib::ClearColor. On a - * change, flushes the vertices and notifies the driver via the - * dd_function_table::ClearColor callback. */ void GLAPIENTRY _mesa_ClearColor( GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha ) @@ -132,14 +128,15 @@ color_buffer_writes_enabled(const struct gl_context *ctx, unsigned idx) /** * Clear buffers. - * + * * \param mask bit-mask indicating the buffers to be cleared. * - * Flushes the vertices and verifies the parameter. If __struct gl_contextRec::NewState - * is set then calls _mesa_update_state() to update gl_frame_buffer::_Xmin, - * etc. If the rasterization mode is set to GL_RENDER then requests the driver - * to clear the buffers, via the dd_function_table::Clear callback. - */ + * Flushes the vertices and verifies the parameter. + * If __struct gl_contextRec::NewState is set then calls _mesa_update_state() + * to update gl_frame_buffer::_Xmin, etc. If the rasterization mode is set to + * GL_RENDER then requests the driver to clear the buffers, via the + * dd_function_table::Clear callback. + */ void GLAPIENTRY _mesa_Clear( GLbitfield mask ) { @@ -228,7 +225,7 @@ _mesa_Clear( GLbitfield mask ) /** Returned by make_color_buffer_mask() for errors */ -#define INVALID_MASK ~0x0 +#define INVALID_MASK ~0x0U /** @@ -340,7 +337,8 @@ _mesa_ClearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *value) drawbuffer); return; } - else if (ctx->DrawBuffer->Attachment[BUFFER_STENCIL].Renderbuffer && !ctx->RasterDiscard) { + else if (ctx->DrawBuffer->Attachment[BUFFER_STENCIL].Renderbuffer + && !ctx->RasterDiscard) { /* Save current stencil clear value, set to 'value', do the * stencil clear and restore the clear value. * XXX in the future we may have a new ctx->Driver.ClearBuffer() @@ -503,7 +501,8 @@ _mesa_ClearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *value) drawbuffer); return; } - else if (ctx->DrawBuffer->Attachment[BUFFER_DEPTH].Renderbuffer && !ctx->RasterDiscard) { + else if (ctx->DrawBuffer->Attachment[BUFFER_DEPTH].Renderbuffer + && !ctx->RasterDiscard) { /* Save current depth clear value, set to 'value', do the * depth clear and restore the clear value. * XXX in the future we may have a new ctx->Driver.ClearBuffer() diff --git a/mesalib/src/mesa/main/colormac.h b/mesalib/src/mesa/main/colormac.h index c8adca6b6..bc69f4673 100644 --- a/mesalib/src/mesa/main/colormac.h +++ b/mesalib/src/mesa/main/colormac.h @@ -69,9 +69,6 @@ _mesa_unclamped_float_rgba_to_ubyte(GLubyte dst[4], const GLfloat src[4]) #define PACK_COLOR_565( X, Y, Z ) \ ((((X) & 0xf8) << 8) | (((Y) & 0xfc) << 3) | (((Z) & 0xf8) >> 3)) -#define PACK_COLOR_565_REV( X, Y, Z ) \ - (((X) & 0xf8) | ((Y) & 0xe0) >> 5 | (((Y) & 0x1c) << 11) | (((Z) & 0xf8) << 5)) - #define PACK_COLOR_5551( R, G, B, A ) \ ((((R) & 0xf8) << 8) | (((G) & 0xf8) << 3) | (((B) & 0xf8) >> 2) | \ ((A) >> 7)) diff --git a/mesalib/src/mesa/main/compiler.h b/mesalib/src/mesa/main/compiler.h index 34671dc7e..cdc843db2 100644 --- a/mesalib/src/mesa/main/compiler.h +++ b/mesalib/src/mesa/main/compiler.h @@ -122,7 +122,7 @@ extern "C" { * inline a static function that we later use in an alias. - ajax */ #ifndef PUBLIC -# if (defined(__GNUC__) && __GNUC__ >= 4) || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590)) +# if defined(__GNUC__) || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590)) # define PUBLIC __attribute__((visibility("default"))) # define USED __attribute__((used)) # else diff --git a/mesalib/src/mesa/main/config.h b/mesalib/src/mesa/main/config.h index a6d44f9fe..a011319b9 100644 --- a/mesalib/src/mesa/main/config.h +++ b/mesalib/src/mesa/main/config.h @@ -182,7 +182,7 @@ #define MAX_COMBINED_ATOMIC_BUFFERS (MAX_UNIFORM_BUFFERS * 6) /* Size of an atomic counter in bytes according to ARB_shader_atomic_counters */ #define ATOMIC_COUNTER_SIZE 4 -#define MAX_IMAGE_UNIFORMS 16 +#define MAX_IMAGE_UNIFORMS 32 /* 6 is for vertex, hull, domain, geometry, fragment, and compute shader. */ #define MAX_IMAGE_UNITS (MAX_IMAGE_UNIFORMS * 6) /*@}*/ @@ -304,6 +304,9 @@ #define MAX_COMPUTE_IMAGE_UNIFORMS 8 /*@}*/ +/** For GL_ARB_pipeline_statistics_query */ +#define MAX_PIPELINE_STATISTICS 11 + /* * Color channel component order * diff --git a/mesalib/src/mesa/main/context.c b/mesalib/src/mesa/main/context.c index 400c158a7..b186a1fad 100644 --- a/mesalib/src/mesa/main/context.c +++ b/mesalib/src/mesa/main/context.c @@ -118,7 +118,7 @@ #include "scissor.h" #include "shared.h" #include "shaderobj.h" -#include "simple_list.h" +#include "util/simple_list.h" #include "state.h" #include "stencil.h" #include "texcompress_s3tc.h" @@ -908,6 +908,9 @@ nop_glFlush(void) #endif +extern void (*__glapi_noop_table[])(void); + + /** * Allocate and initialize a new dispatch table. All the dispatch * function pointers will point at the _mesa_generic_nop() function @@ -929,7 +932,13 @@ _mesa_alloc_dispatch_table(void) _glapi_proc *entry = (_glapi_proc *) table; GLint i; for (i = 0; i < numEntries; i++) { +#if defined(_WIN32) + /* FIXME: This will not generate an error, but at least it won't + * corrupt the stack like _mesa_generic_nop does. */ + entry[i] = __glapi_noop_table[i]; +#else entry[i] = (_glapi_proc) _mesa_generic_nop; +#endif } #if defined(_WIN32) @@ -1271,7 +1280,6 @@ _mesa_free_context_data( struct gl_context *ctx ) _mesa_free_attrib_data(ctx); _mesa_free_buffer_objects(ctx); - _mesa_free_lighting_data( ctx ); _mesa_free_eval_data( ctx ); _mesa_free_texture_data( ctx ); _mesa_free_matrix_data( ctx ); @@ -1903,49 +1911,69 @@ shader_linked_or_absent(struct gl_context *ctx, GLboolean _mesa_valid_to_render(struct gl_context *ctx, const char *where) { - bool from_glsl_shader[MESA_SHADER_COMPUTE] = { false }; unsigned i; /* This depends on having up to date derived state (shaders) */ if (ctx->NewState) _mesa_update_state(ctx); - for (i = 0; i < MESA_SHADER_COMPUTE; i++) { - if (!shader_linked_or_absent(ctx, ctx->_Shader->CurrentProgram[i], - &from_glsl_shader[i], where)) - return GL_FALSE; - } + if (ctx->API == API_OPENGL_CORE || ctx->API == API_OPENGLES2) { + bool from_glsl_shader[MESA_SHADER_COMPUTE] = { false }; - /* Any shader stages that are not supplied by the GLSL shader and have - * assembly shaders enabled must now be validated. - */ - if (!from_glsl_shader[MESA_SHADER_VERTEX] - && ctx->VertexProgram.Enabled && !ctx->VertexProgram._Enabled) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "%s(vertex program not valid)", where); - return GL_FALSE; - } + for (i = 0; i < MESA_SHADER_COMPUTE; i++) { + if (!shader_linked_or_absent(ctx, ctx->_Shader->CurrentProgram[i], + &from_glsl_shader[i], where)) + return GL_FALSE; + } - /* FINISHME: If GL_NV_geometry_program4 is ever supported, the current - * FINISHME: geometry program should validated here. - */ - (void) from_glsl_shader[MESA_SHADER_GEOMETRY]; + /* In OpenGL Core Profile and OpenGL ES 2.0 / 3.0, there are no assembly + * shaders. Don't check state related to those. + */ + } else { + bool has_vertex_shader = false; + bool has_fragment_shader = false; + + /* In OpenGL Compatibility Profile, there is only vertex shader and + * fragment shader. We take this path also for API_OPENGLES because + * optimizing that path would make the other (more common) paths + * slightly slower. + */ + if (!shader_linked_or_absent(ctx, + ctx->_Shader->CurrentProgram[MESA_SHADER_VERTEX], + &has_vertex_shader, where)) + return GL_FALSE; - if (!from_glsl_shader[MESA_SHADER_FRAGMENT]) { - if (ctx->FragmentProgram.Enabled && !ctx->FragmentProgram._Enabled) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "%s(fragment program not valid)", where); - return GL_FALSE; - } + if (!shader_linked_or_absent(ctx, + ctx->_Shader->CurrentProgram[MESA_SHADER_FRAGMENT], + &has_fragment_shader, where)) + return GL_FALSE; - /* If drawing to integer-valued color buffers, there must be an - * active fragment shader (GL_EXT_texture_integer). + /* Any shader stages that are not supplied by the GLSL shader and have + * assembly shaders enabled must now be validated. */ - if (ctx->DrawBuffer && ctx->DrawBuffer->_IntegerColor) { + if (!has_vertex_shader + && ctx->VertexProgram.Enabled && !ctx->VertexProgram._Enabled) { _mesa_error(ctx, GL_INVALID_OPERATION, - "%s(integer format but no fragment shader)", where); + "%s(vertex program not valid)", where); return GL_FALSE; } + + if (!has_fragment_shader) { + if (ctx->FragmentProgram.Enabled && !ctx->FragmentProgram._Enabled) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "%s(fragment program not valid)", where); + return GL_FALSE; + } + + /* If drawing to integer-valued color buffers, there must be an + * active fragment shader (GL_EXT_texture_integer). + */ + if (ctx->DrawBuffer && ctx->DrawBuffer->_IntegerColor) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "%s(integer format but no fragment shader)", where); + return GL_FALSE; + } + } } /* A pipeline object is bound */ diff --git a/mesalib/src/mesa/main/context.h b/mesalib/src/mesa/main/context.h index d902ea76e..d5650877e 100644 --- a/mesalib/src/mesa/main/context.h +++ b/mesalib/src/mesa/main/context.h @@ -326,6 +326,17 @@ _mesa_has_geometry_shaders(const struct gl_context *ctx) } +/** + * Checks if the context supports compute shaders. + */ +static inline bool +_mesa_has_compute_shaders(const struct gl_context *ctx) +{ + return (ctx->API == API_OPENGL_CORE && ctx->Extensions.ARB_compute_shader) || + (ctx->API == API_OPENGLES2 && ctx->Version >= 31); +} + + #ifdef __cplusplus } #endif diff --git a/mesalib/src/mesa/main/copyimage.c b/mesalib/src/mesa/main/copyimage.c index df7d7c272..455929dc2 100644 --- a/mesalib/src/mesa/main/copyimage.c +++ b/mesalib/src/mesa/main/copyimage.c @@ -152,7 +152,7 @@ prepare_target(struct gl_context *ctx, GLuint name, GLenum *target, int level, return false; } - *tex_image = _mesa_select_tex_image(ctx, *tex_obj, *target, level); + *tex_image = _mesa_select_tex_image(*tex_obj, *target, level); if (!*tex_image) { _mesa_error(ctx, GL_INVALID_VALUE, "glCopyImageSubData(%sLevel = %u)", dbg_prefix, level); diff --git a/mesalib/src/mesa/main/dd.h b/mesalib/src/mesa/main/dd.h index 2f40915d9..ec8662b30 100644 --- a/mesalib/src/mesa/main/dd.h +++ b/mesalib/src/mesa/main/dd.h @@ -415,6 +415,22 @@ struct dd_function_table { struct gl_texture_object *texObj, struct gl_texture_object *origTexObj); + /** Sets the given buffer object as the texture's storage. The given + * texture must have target GL_TEXTURE_1D, GL_TEXTURE_2D, + * GL_TEXTURE_RECTANGLE, and GL_TEXTURE_2D_ARRAY; have only a single + * mipmap level; be immutable; and must not have any assigned storage. + * The format and dimensions of the gl_texture_object will already be + * initialized. + * + * This function is used by the meta PBO texture upload path. + */ + bool (*SetTextureStorageForBufferObject)(struct gl_context *ctx, + struct gl_texture_object *texObj, + struct gl_buffer_object *bufferObj, + uint32_t buffer_offset, + uint32_t row_stride, + bool read_only); + /** * Map a renderbuffer into user space. * \param mode bitmask of GL_MAP_READ_BIT, GL_MAP_WRITE_BIT and @@ -563,7 +579,7 @@ struct dd_function_table { /** Select a polygon rasterization mode */ void (*PolygonMode)(struct gl_context *ctx, GLenum face, GLenum mode); /** Set the scale and units used to calculate depth values */ - void (*PolygonOffset)(struct gl_context *ctx, GLfloat factor, GLfloat units); + void (*PolygonOffset)(struct gl_context *ctx, GLfloat factor, GLfloat units, GLfloat clamp); /** Set the polygon stippling pattern */ void (*PolygonStipple)(struct gl_context *ctx, const GLubyte *mask ); /* Specifies the current buffer for reading */ @@ -697,6 +713,8 @@ struct dd_function_table { struct gl_framebuffer *fb); /*@}*/ void (*BlitFramebuffer)(struct gl_context *ctx, + struct gl_framebuffer *readFb, + struct gl_framebuffer *drawFb, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); diff --git a/mesalib/src/mesa/main/dlist.c b/mesalib/src/mesa/main/dlist.c index 4b7b0604b..025f6abd2 100644 --- a/mesalib/src/mesa/main/dlist.c +++ b/mesalib/src/mesa/main/dlist.c @@ -81,7 +81,7 @@ struct gl_list_instruction GLuint Size; void (*Execute)( struct gl_context *ctx, void *data ); void (*Destroy)( struct gl_context *ctx, void *data ); - void (*Print)( struct gl_context *ctx, void *data ); + void (*Print)( struct gl_context *ctx, void *data, FILE *f ); }; @@ -484,9 +484,13 @@ typedef enum /* ARB_uniform_buffer_object */ OPCODE_UNIFORM_BLOCK_BINDING, + /* EXT_polygon_offset_clamp */ + OPCODE_POLYGON_OFFSET_CLAMP, + /* The following three are meta instructions */ OPCODE_ERROR, /* raise compiled-in error */ OPCODE_CONTINUE, + OPCODE_NOP, /* No-op (used for 8-byte alignment */ OPCODE_END_OF_LIST, OPCODE_EXT_0 } OpCode; @@ -545,13 +549,13 @@ union pointer * Save a 4 or 8-byte pointer at dest (and dest+1). */ static inline void -save_pointer(union gl_dlist_node *dest, void *src) +save_pointer(Node *dest, void *src) { union pointer p; unsigned i; STATIC_ASSERT(POINTER_DWORDS == 1 || POINTER_DWORDS == 2); - STATIC_ASSERT(sizeof(union gl_dlist_node) == 4); + STATIC_ASSERT(sizeof(Node) == 4); p.ptr = src; @@ -564,7 +568,7 @@ save_pointer(union gl_dlist_node *dest, void *src) * Retrieve a 4 or 8-byte pointer from node (node+1). */ static inline void * -get_pointer(const union gl_dlist_node *node) +get_pointer(const Node *node) { union pointer p; unsigned i; @@ -578,7 +582,7 @@ get_pointer(const union gl_dlist_node *node) /** * Used to store a 64-bit uint in a pair of "Nodes" for the sake of 32-bit - * environment. In 64-bit env, sizeof(Node)==8 anyway. + * environment. */ union uint64_pair { @@ -666,11 +670,11 @@ ext_opcode_execute(struct gl_context *ctx, Node *node) /** Print an extended opcode instruction */ static GLint -ext_opcode_print(struct gl_context *ctx, Node *node) +ext_opcode_print(struct gl_context *ctx, Node *node, FILE *f) { const GLint i = node[0].opcode - OPCODE_EXT_0; GLint step; - ctx->ListExt->Opcode[i].Print(ctx, &node[1]); + ctx->ListExt->Opcode[i].Print(ctx, &node[1], f); step = ctx->ListExt->Opcode[i].Size; return step; } @@ -957,11 +961,8 @@ unpack_image(struct gl_context *ctx, GLuint dimensions, /* no PBO */ GLvoid *image; - if (type == GL_BITMAP) - image = _mesa_unpack_bitmap(width, height, pixels, unpack); - else - image = _mesa_unpack_image(dimensions, width, height, depth, - format, type, pixels, unpack); + image = _mesa_unpack_image(dimensions, width, height, depth, + format, type, pixels, unpack); if (pixels && !image) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "display list construction"); } @@ -983,11 +984,8 @@ unpack_image(struct gl_context *ctx, GLuint dimensions, } src = ADD_POINTERS(map, pixels); - if (type == GL_BITMAP) - image = _mesa_unpack_bitmap(width, height, src, unpack); - else - image = _mesa_unpack_image(dimensions, width, height, depth, - format, type, src, unpack); + image = _mesa_unpack_image(dimensions, width, height, depth, + format, type, src, unpack); ctx->Driver.UnmapBuffer(ctx, unpack->BufferObj, MAP_INTERNAL); @@ -1018,16 +1016,19 @@ memdup(const void *src, GLsizei bytes) * Allocate space for a display list instruction (opcode + payload space). * \param opcode the instruction opcode (OPCODE_* value) * \param bytes instruction payload size (not counting opcode) - * \return pointer to allocated memory (the opcode space) + * \param align8 does the payload need to be 8-byte aligned? + * This is only relevant in 64-bit environments. + * \return pointer to allocated memory (the payload will be at pointer+1) */ static Node * -dlist_alloc(struct gl_context *ctx, OpCode opcode, GLuint bytes) +dlist_alloc(struct gl_context *ctx, OpCode opcode, GLuint bytes, bool align8) { const GLuint numNodes = 1 + (bytes + sizeof(Node) - 1) / sizeof(Node); const GLuint contNodes = 1 + POINTER_DWORDS; /* size of continue info */ + GLuint nopNode; Node *n; - if (opcode < (GLuint) OPCODE_EXT_0) { + if (opcode < OPCODE_EXT_0) { if (InstSize[opcode] == 0) { /* save instruction size now */ InstSize[opcode] = numNodes; @@ -1038,7 +1039,20 @@ dlist_alloc(struct gl_context *ctx, OpCode opcode, GLuint bytes) } } - if (ctx->ListState.CurrentPos + numNodes + contNodes > BLOCK_SIZE) { + if (sizeof(void *) > sizeof(Node) && align8 + && ctx->ListState.CurrentPos % 2 == 0) { + /* The opcode would get placed at node[0] and the payload would start + * at node[1]. But the payload needs to be at an even offset (8-byte + * multiple). + */ + nopNode = 1; + } + else { + nopNode = 0; + } + + if (ctx->ListState.CurrentPos + nopNode + numNodes + contNodes + > BLOCK_SIZE) { /* This block is full. Allocate a new block and chain to it */ Node *newblock; n = ctx->ListState.CurrentBlock + ctx->ListState.CurrentPos; @@ -1048,13 +1062,34 @@ dlist_alloc(struct gl_context *ctx, OpCode opcode, GLuint bytes) _mesa_error(ctx, GL_OUT_OF_MEMORY, "Building display list"); return NULL; } + + /* a fresh block should be 8-byte aligned on 64-bit systems */ + assert(((GLintptr) newblock) % sizeof(void *) == 0); + save_pointer(&n[1], newblock); ctx->ListState.CurrentBlock = newblock; ctx->ListState.CurrentPos = 0; + + /* Display list nodes are always 4 bytes. If we need 8-byte alignment + * we have to insert a NOP so that the payload of the real opcode lands + * on an even location: + * node[0] = OPCODE_NOP + * node[1] = OPCODE_x; + * node[2] = start of payload + */ + nopNode = sizeof(void *) > sizeof(Node) && align8; } n = ctx->ListState.CurrentBlock + ctx->ListState.CurrentPos; - ctx->ListState.CurrentPos += numNodes; + if (nopNode) { + assert(ctx->ListState.CurrentPos % 2 == 0); /* even value */ + n[0].opcode = OPCODE_NOP; + n++; + /* The "real" opcode will now be at an odd location and the payload + * will be at an even location. + */ + } + ctx->ListState.CurrentPos += nopNode + numNodes; n[0].opcode = opcode; @@ -1075,7 +1110,22 @@ dlist_alloc(struct gl_context *ctx, OpCode opcode, GLuint bytes) void * _mesa_dlist_alloc(struct gl_context *ctx, GLuint opcode, GLuint bytes) { - Node *n = dlist_alloc(ctx, (OpCode) opcode, bytes); + Node *n = dlist_alloc(ctx, (OpCode) opcode, bytes, false); + if (n) + return n + 1; /* return pointer to payload area, after opcode */ + else + return NULL; +} + + +/** + * Same as _mesa_dlist_alloc(), but return a pointer which is 8-byte + * aligned in 64-bit environments, 4-byte aligned otherwise. + */ +void * +_mesa_dlist_alloc_aligned(struct gl_context *ctx, GLuint opcode, GLuint bytes) +{ + Node *n = dlist_alloc(ctx, (OpCode) opcode, bytes, true); if (n) return n + 1; /* return pointer to payload area, after opcode */ else @@ -1098,7 +1148,7 @@ _mesa_dlist_alloc_opcode(struct gl_context *ctx, GLuint size, void (*execute) (struct gl_context *, void *), void (*destroy) (struct gl_context *, void *), - void (*print) (struct gl_context *, void *)) + void (*print) (struct gl_context *, void *, FILE *)) { if (ctx->ListExt->NumOpcodes < MAX_DLIST_EXT_OPCODES) { const GLuint i = ctx->ListExt->NumOpcodes++; @@ -1125,7 +1175,7 @@ _mesa_dlist_alloc_opcode(struct gl_context *ctx, static inline Node * alloc_instruction(struct gl_context *ctx, OpCode opcode, GLuint nparams) { - return dlist_alloc(ctx, opcode, nparams * sizeof(Node)); + return dlist_alloc(ctx, opcode, nparams * sizeof(Node), false); } @@ -3144,6 +3194,22 @@ save_PolygonOffsetEXT(GLfloat factor, GLfloat bias) save_PolygonOffset(factor, ctx->DrawBuffer->_DepthMaxF * bias); } +static void GLAPIENTRY +save_PolygonOffsetClampEXT(GLfloat factor, GLfloat units, GLfloat clamp) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = alloc_instruction(ctx, OPCODE_POLYGON_OFFSET_CLAMP, 3); + if (n) { + n[1].f = factor; + n[2].f = units; + n[3].f = clamp; + } + if (ctx->ExecuteFlag) { + CALL_PolygonOffsetClampEXT(ctx->Exec, (factor, units, clamp)); + } +} static void GLAPIENTRY save_PopAttrib(void) @@ -7985,17 +8051,8 @@ execute_list(struct gl_context *ctx, GLuint list) CALL_LoadIdentity(ctx->Exec, ()); break; case OPCODE_LOAD_MATRIX: - if (sizeof(Node) == sizeof(GLfloat)) { - CALL_LoadMatrixf(ctx->Exec, (&n[1].f)); - } - else { - GLfloat m[16]; - GLuint i; - for (i = 0; i < 16; i++) { - m[i] = n[1 + i].f; - } - CALL_LoadMatrixf(ctx->Exec, (m)); - } + STATIC_ASSERT(sizeof(Node) == sizeof(GLfloat)); + CALL_LoadMatrixf(ctx->Exec, (&n[1].f)); break; case OPCODE_LOAD_NAME: CALL_LoadName(ctx->Exec, (n[1].ui)); @@ -8041,17 +8098,7 @@ execute_list(struct gl_context *ctx, GLuint list) CALL_MatrixMode(ctx->Exec, (n[1].e)); break; case OPCODE_MULT_MATRIX: - if (sizeof(Node) == sizeof(GLfloat)) { - CALL_MultMatrixf(ctx->Exec, (&n[1].f)); - } - else { - GLfloat m[16]; - GLuint i; - for (i = 0; i < 16; i++) { - m[i] = n[1 + i].f; - } - CALL_MultMatrixf(ctx->Exec, (m)); - } + CALL_MultMatrixf(ctx->Exec, (&n[1].f)); break; case OPCODE_ORTHO: CALL_Ortho(ctx->Exec, @@ -8096,6 +8143,9 @@ execute_list(struct gl_context *ctx, GLuint list) case OPCODE_POLYGON_OFFSET: CALL_PolygonOffset(ctx->Exec, (n[1].f, n[2].f)); break; + case OPCODE_POLYGON_OFFSET_CLAMP: + CALL_PolygonOffsetClampEXT(ctx->Exec, (n[1].f, n[2].f, n[3].f)); + break; case OPCODE_POP_ATTRIB: CALL_PopAttrib(ctx->Exec, ()); break; @@ -8648,84 +8698,34 @@ execute_list(struct gl_context *ctx, GLuint list) CALL_BindFragmentShaderATI(ctx->Exec, (n[1].i)); break; case OPCODE_SET_FRAGMENT_SHADER_CONSTANTS_ATI: - { - GLfloat values[4]; - GLuint i, dst = n[1].ui; - - for (i = 0; i < 4; i++) - values[i] = n[1 + i].f; - CALL_SetFragmentShaderConstantATI(ctx->Exec, (dst, values)); - } + CALL_SetFragmentShaderConstantATI(ctx->Exec, (n[1].ui, &n[2].f)); break; case OPCODE_ATTR_1F_NV: CALL_VertexAttrib1fNV(ctx->Exec, (n[1].e, n[2].f)); break; case OPCODE_ATTR_2F_NV: - /* Really shouldn't have to do this - the Node structure - * is convenient, but it would be better to store the data - * packed appropriately so that it can be sent directly - * on. With x86_64 becoming common, this will start to - * matter more. - */ - if (sizeof(Node) == sizeof(GLfloat)) - CALL_VertexAttrib2fvNV(ctx->Exec, (n[1].e, &n[2].f)); - else - CALL_VertexAttrib2fNV(ctx->Exec, (n[1].e, n[2].f, n[3].f)); + CALL_VertexAttrib2fvNV(ctx->Exec, (n[1].e, &n[2].f)); break; case OPCODE_ATTR_3F_NV: - if (sizeof(Node) == sizeof(GLfloat)) - CALL_VertexAttrib3fvNV(ctx->Exec, (n[1].e, &n[2].f)); - else - CALL_VertexAttrib3fNV(ctx->Exec, (n[1].e, n[2].f, n[3].f, - n[4].f)); + CALL_VertexAttrib3fvNV(ctx->Exec, (n[1].e, &n[2].f)); break; case OPCODE_ATTR_4F_NV: - if (sizeof(Node) == sizeof(GLfloat)) - CALL_VertexAttrib4fvNV(ctx->Exec, (n[1].e, &n[2].f)); - else - CALL_VertexAttrib4fNV(ctx->Exec, (n[1].e, n[2].f, n[3].f, - n[4].f, n[5].f)); + CALL_VertexAttrib4fvNV(ctx->Exec, (n[1].e, &n[2].f)); break; case OPCODE_ATTR_1F_ARB: CALL_VertexAttrib1fARB(ctx->Exec, (n[1].e, n[2].f)); break; case OPCODE_ATTR_2F_ARB: - /* Really shouldn't have to do this - the Node structure - * is convenient, but it would be better to store the data - * packed appropriately so that it can be sent directly - * on. With x86_64 becoming common, this will start to - * matter more. - */ - if (sizeof(Node) == sizeof(GLfloat)) - CALL_VertexAttrib2fvARB(ctx->Exec, (n[1].e, &n[2].f)); - else - CALL_VertexAttrib2fARB(ctx->Exec, (n[1].e, n[2].f, n[3].f)); + CALL_VertexAttrib2fvARB(ctx->Exec, (n[1].e, &n[2].f)); break; case OPCODE_ATTR_3F_ARB: - if (sizeof(Node) == sizeof(GLfloat)) - CALL_VertexAttrib3fvARB(ctx->Exec, (n[1].e, &n[2].f)); - else - CALL_VertexAttrib3fARB(ctx->Exec, (n[1].e, n[2].f, n[3].f, - n[4].f)); + CALL_VertexAttrib3fvARB(ctx->Exec, (n[1].e, &n[2].f)); break; case OPCODE_ATTR_4F_ARB: - if (sizeof(Node) == sizeof(GLfloat)) - CALL_VertexAttrib4fvARB(ctx->Exec, (n[1].e, &n[2].f)); - else - CALL_VertexAttrib4fARB(ctx->Exec, (n[1].e, n[2].f, n[3].f, - n[4].f, n[5].f)); + CALL_VertexAttrib4fvARB(ctx->Exec, (n[1].e, &n[2].f)); break; case OPCODE_MATERIAL: - if (sizeof(Node) == sizeof(GLfloat)) - CALL_Materialfv(ctx->Exec, (n[1].e, n[2].e, &n[3].f)); - else { - GLfloat f[4]; - f[0] = n[3].f; - f[1] = n[4].f; - f[2] = n[5].f; - f[3] = n[6].f; - CALL_Materialfv(ctx->Exec, (n[1].e, n[2].e, f)); - } + CALL_Materialfv(ctx->Exec, (n[1].e, n[2].e, &n[3].f)); break; case OPCODE_BEGIN: CALL_Begin(ctx->Exec, (n[1].e)); @@ -8903,6 +8903,9 @@ execute_list(struct gl_context *ctx, GLuint list) case OPCODE_CONTINUE: n = (Node *) get_pointer(&n[1]); break; + case OPCODE_NOP: + /* no-op */ + break; case OPCODE_END_OF_LIST: done = GL_TRUE; break; @@ -9702,6 +9705,9 @@ _mesa_initialize_save_table(const struct gl_context *ctx) SET_ProgramUniformMatrix4x2fv(table, save_ProgramUniformMatrix4x2fv); SET_ProgramUniformMatrix3x4fv(table, save_ProgramUniformMatrix3x4fv); SET_ProgramUniformMatrix4x3fv(table, save_ProgramUniformMatrix4x3fv); + + /* GL_EXT_polygon_offset_clamp */ + SET_PolygonOffsetClampEXT(table, save_PolygonOffsetClampEXT); } @@ -9716,16 +9722,24 @@ enum_string(GLenum k) /** * Print the commands in a display list. For debugging only. * TODO: many commands aren't handled yet. + * \param fname filename to write display list to. If null, use stdout. */ static void GLAPIENTRY -print_list(struct gl_context *ctx, GLuint list) +print_list(struct gl_context *ctx, GLuint list, const char *fname) { struct gl_display_list *dlist; Node *n; GLboolean done; + FILE *f = stdout; + + if (fname) { + f = fopen(fname, "w"); + if (!f) + return; + } if (!islist(ctx, list)) { - printf("%u is not a display list ID\n", list); + fprintf(f, "%u is not a display list ID\n", list); return; } @@ -9735,199 +9749,202 @@ print_list(struct gl_context *ctx, GLuint list) n = dlist->Head; - printf("START-LIST %u, address %p\n", list, (void *) n); + fprintf(f, "START-LIST %u, address %p\n", list, (void *) n); done = n ? GL_FALSE : GL_TRUE; while (!done) { const OpCode opcode = n[0].opcode; if (is_ext_opcode(opcode)) { - n += ext_opcode_print(ctx, n); + n += ext_opcode_print(ctx, n, f); } else { switch (opcode) { case OPCODE_ACCUM: - printf("Accum %s %g\n", enum_string(n[1].e), n[2].f); + fprintf(f, "Accum %s %g\n", enum_string(n[1].e), n[2].f); + break; + case OPCODE_ACTIVE_TEXTURE: + fprintf(f, "ActiveTexture(%s)\n", enum_string(n[1].e)); break; case OPCODE_BITMAP: - printf("Bitmap %d %d %g %g %g %g %p\n", n[1].i, n[2].i, + fprintf(f, "Bitmap %d %d %g %g %g %g %p\n", n[1].i, n[2].i, n[3].f, n[4].f, n[5].f, n[6].f, get_pointer(&n[7])); break; case OPCODE_CALL_LIST: - printf("CallList %d\n", (int) n[1].ui); + fprintf(f, "CallList %d\n", (int) n[1].ui); break; case OPCODE_CALL_LIST_OFFSET: - printf("CallList %d + offset %u = %u\n", (int) n[1].ui, + fprintf(f, "CallList %d + offset %u = %u\n", (int) n[1].ui, ctx->List.ListBase, ctx->List.ListBase + n[1].ui); break; case OPCODE_DISABLE: - printf("Disable %s\n", enum_string(n[1].e)); + fprintf(f, "Disable %s\n", enum_string(n[1].e)); break; case OPCODE_ENABLE: - printf("Enable %s\n", enum_string(n[1].e)); + fprintf(f, "Enable %s\n", enum_string(n[1].e)); break; case OPCODE_FRUSTUM: - printf("Frustum %g %g %g %g %g %g\n", + fprintf(f, "Frustum %g %g %g %g %g %g\n", n[1].f, n[2].f, n[3].f, n[4].f, n[5].f, n[6].f); break; case OPCODE_LINE_STIPPLE: - printf("LineStipple %d %x\n", n[1].i, (int) n[2].us); + fprintf(f, "LineStipple %d %x\n", n[1].i, (int) n[2].us); break; case OPCODE_LOAD_IDENTITY: - printf("LoadIdentity\n"); + fprintf(f, "LoadIdentity\n"); break; case OPCODE_LOAD_MATRIX: - printf("LoadMatrix\n"); - printf(" %8f %8f %8f %8f\n", + fprintf(f, "LoadMatrix\n"); + fprintf(f, " %8f %8f %8f %8f\n", n[1].f, n[5].f, n[9].f, n[13].f); - printf(" %8f %8f %8f %8f\n", + fprintf(f, " %8f %8f %8f %8f\n", n[2].f, n[6].f, n[10].f, n[14].f); - printf(" %8f %8f %8f %8f\n", + fprintf(f, " %8f %8f %8f %8f\n", n[3].f, n[7].f, n[11].f, n[15].f); - printf(" %8f %8f %8f %8f\n", + fprintf(f, " %8f %8f %8f %8f\n", n[4].f, n[8].f, n[12].f, n[16].f); break; case OPCODE_MULT_MATRIX: - printf("MultMatrix (or Rotate)\n"); - printf(" %8f %8f %8f %8f\n", + fprintf(f, "MultMatrix (or Rotate)\n"); + fprintf(f, " %8f %8f %8f %8f\n", n[1].f, n[5].f, n[9].f, n[13].f); - printf(" %8f %8f %8f %8f\n", + fprintf(f, " %8f %8f %8f %8f\n", n[2].f, n[6].f, n[10].f, n[14].f); - printf(" %8f %8f %8f %8f\n", + fprintf(f, " %8f %8f %8f %8f\n", n[3].f, n[7].f, n[11].f, n[15].f); - printf(" %8f %8f %8f %8f\n", + fprintf(f, " %8f %8f %8f %8f\n", n[4].f, n[8].f, n[12].f, n[16].f); break; case OPCODE_ORTHO: - printf("Ortho %g %g %g %g %g %g\n", + fprintf(f, "Ortho %g %g %g %g %g %g\n", n[1].f, n[2].f, n[3].f, n[4].f, n[5].f, n[6].f); break; case OPCODE_POP_ATTRIB: - printf("PopAttrib\n"); + fprintf(f, "PopAttrib\n"); break; case OPCODE_POP_MATRIX: - printf("PopMatrix\n"); + fprintf(f, "PopMatrix\n"); break; case OPCODE_POP_NAME: - printf("PopName\n"); + fprintf(f, "PopName\n"); break; case OPCODE_PUSH_ATTRIB: - printf("PushAttrib %x\n", n[1].bf); + fprintf(f, "PushAttrib %x\n", n[1].bf); break; case OPCODE_PUSH_MATRIX: - printf("PushMatrix\n"); + fprintf(f, "PushMatrix\n"); break; case OPCODE_PUSH_NAME: - printf("PushName %d\n", (int) n[1].ui); + fprintf(f, "PushName %d\n", (int) n[1].ui); break; case OPCODE_RASTER_POS: - printf("RasterPos %g %g %g %g\n", + fprintf(f, "RasterPos %g %g %g %g\n", n[1].f, n[2].f, n[3].f, n[4].f); break; case OPCODE_ROTATE: - printf("Rotate %g %g %g %g\n", + fprintf(f, "Rotate %g %g %g %g\n", n[1].f, n[2].f, n[3].f, n[4].f); break; case OPCODE_SCALE: - printf("Scale %g %g %g\n", n[1].f, n[2].f, n[3].f); + fprintf(f, "Scale %g %g %g\n", n[1].f, n[2].f, n[3].f); break; case OPCODE_TRANSLATE: - printf("Translate %g %g %g\n", n[1].f, n[2].f, n[3].f); + fprintf(f, "Translate %g %g %g\n", n[1].f, n[2].f, n[3].f); break; case OPCODE_BIND_TEXTURE: - printf("BindTexture %s %d\n", + fprintf(f, "BindTexture %s %d\n", _mesa_lookup_enum_by_nr(n[1].ui), n[2].ui); break; case OPCODE_SHADE_MODEL: - printf("ShadeModel %s\n", _mesa_lookup_enum_by_nr(n[1].ui)); + fprintf(f, "ShadeModel %s\n", _mesa_lookup_enum_by_nr(n[1].ui)); break; case OPCODE_MAP1: - printf("Map1 %s %.3f %.3f %d %d\n", + fprintf(f, "Map1 %s %.3f %.3f %d %d\n", _mesa_lookup_enum_by_nr(n[1].ui), n[2].f, n[3].f, n[4].i, n[5].i); break; case OPCODE_MAP2: - printf("Map2 %s %.3f %.3f %.3f %.3f %d %d %d %d\n", + fprintf(f, "Map2 %s %.3f %.3f %.3f %.3f %d %d %d %d\n", _mesa_lookup_enum_by_nr(n[1].ui), n[2].f, n[3].f, n[4].f, n[5].f, n[6].i, n[7].i, n[8].i, n[9].i); break; case OPCODE_MAPGRID1: - printf("MapGrid1 %d %.3f %.3f\n", n[1].i, n[2].f, n[3].f); + fprintf(f, "MapGrid1 %d %.3f %.3f\n", n[1].i, n[2].f, n[3].f); break; case OPCODE_MAPGRID2: - printf("MapGrid2 %d %.3f %.3f, %d %.3f %.3f\n", + fprintf(f, "MapGrid2 %d %.3f %.3f, %d %.3f %.3f\n", n[1].i, n[2].f, n[3].f, n[4].i, n[5].f, n[6].f); break; case OPCODE_EVALMESH1: - printf("EvalMesh1 %d %d\n", n[1].i, n[2].i); + fprintf(f, "EvalMesh1 %d %d\n", n[1].i, n[2].i); break; case OPCODE_EVALMESH2: - printf("EvalMesh2 %d %d %d %d\n", + fprintf(f, "EvalMesh2 %d %d %d %d\n", n[1].i, n[2].i, n[3].i, n[4].i); break; case OPCODE_ATTR_1F_NV: - printf("ATTR_1F_NV attr %d: %f\n", n[1].i, n[2].f); + fprintf(f, "ATTR_1F_NV attr %d: %f\n", n[1].i, n[2].f); break; case OPCODE_ATTR_2F_NV: - printf("ATTR_2F_NV attr %d: %f %f\n", + fprintf(f, "ATTR_2F_NV attr %d: %f %f\n", n[1].i, n[2].f, n[3].f); break; case OPCODE_ATTR_3F_NV: - printf("ATTR_3F_NV attr %d: %f %f %f\n", + fprintf(f, "ATTR_3F_NV attr %d: %f %f %f\n", n[1].i, n[2].f, n[3].f, n[4].f); break; case OPCODE_ATTR_4F_NV: - printf("ATTR_4F_NV attr %d: %f %f %f %f\n", + fprintf(f, "ATTR_4F_NV attr %d: %f %f %f %f\n", n[1].i, n[2].f, n[3].f, n[4].f, n[5].f); break; case OPCODE_ATTR_1F_ARB: - printf("ATTR_1F_ARB attr %d: %f\n", n[1].i, n[2].f); + fprintf(f, "ATTR_1F_ARB attr %d: %f\n", n[1].i, n[2].f); break; case OPCODE_ATTR_2F_ARB: - printf("ATTR_2F_ARB attr %d: %f %f\n", + fprintf(f, "ATTR_2F_ARB attr %d: %f %f\n", n[1].i, n[2].f, n[3].f); break; case OPCODE_ATTR_3F_ARB: - printf("ATTR_3F_ARB attr %d: %f %f %f\n", + fprintf(f, "ATTR_3F_ARB attr %d: %f %f %f\n", n[1].i, n[2].f, n[3].f, n[4].f); break; case OPCODE_ATTR_4F_ARB: - printf("ATTR_4F_ARB attr %d: %f %f %f %f\n", + fprintf(f, "ATTR_4F_ARB attr %d: %f %f %f %f\n", n[1].i, n[2].f, n[3].f, n[4].f, n[5].f); break; case OPCODE_MATERIAL: - printf("MATERIAL %x %x: %f %f %f %f\n", + fprintf(f, "MATERIAL %x %x: %f %f %f %f\n", n[1].i, n[2].i, n[3].f, n[4].f, n[5].f, n[6].f); break; case OPCODE_BEGIN: - printf("BEGIN %x\n", n[1].i); + fprintf(f, "BEGIN %x\n", n[1].i); break; case OPCODE_END: - printf("END\n"); + fprintf(f, "END\n"); break; case OPCODE_RECTF: - printf("RECTF %f %f %f %f\n", n[1].f, n[2].f, n[3].f, + fprintf(f, "RECTF %f %f %f %f\n", n[1].f, n[2].f, n[3].f, n[4].f); break; case OPCODE_EVAL_C1: - printf("EVAL_C1 %f\n", n[1].f); + fprintf(f, "EVAL_C1 %f\n", n[1].f); break; case OPCODE_EVAL_C2: - printf("EVAL_C2 %f %f\n", n[1].f, n[2].f); + fprintf(f, "EVAL_C2 %f %f\n", n[1].f, n[2].f); break; case OPCODE_EVAL_P1: - printf("EVAL_P1 %d\n", n[1].i); + fprintf(f, "EVAL_P1 %d\n", n[1].i); break; case OPCODE_EVAL_P2: - printf("EVAL_P2 %d %d\n", n[1].i, n[2].i); + fprintf(f, "EVAL_P2 %d %d\n", n[1].i, n[2].i); break; case OPCODE_PROVOKING_VERTEX: - printf("ProvokingVertex %s\n", + fprintf(f, "ProvokingVertex %s\n", _mesa_lookup_enum_by_nr(n[1].ui)); break; @@ -9935,15 +9952,18 @@ print_list(struct gl_context *ctx, GLuint list) * meta opcodes/commands */ case OPCODE_ERROR: - printf("Error: %s %s\n", enum_string(n[1].e), + fprintf(f, "Error: %s %s\n", enum_string(n[1].e), (const char *) get_pointer(&n[2])); break; case OPCODE_CONTINUE: - printf("DISPLAY-LIST-CONTINUE\n"); + fprintf(f, "DISPLAY-LIST-CONTINUE\n"); n = (Node *) get_pointer(&n[1]); break; + case OPCODE_NOP: + fprintf(f, "NOP\n"); + break; case OPCODE_END_OF_LIST: - printf("END-LIST %u\n", list); + fprintf(f, "END-LIST %u\n", list); done = GL_TRUE; break; default: @@ -9954,7 +9974,7 @@ print_list(struct gl_context *ctx, GLuint list) return; } else { - printf("command %d, %u operands\n", opcode, + fprintf(f, "command %d, %u operands\n", opcode, InstSize[opcode]); } } @@ -9964,6 +9984,10 @@ print_list(struct gl_context *ctx, GLuint list) } } } + + fflush(f); + if (fname) + fclose(f); } @@ -9977,7 +10001,7 @@ void mesa_print_display_list(GLuint list) { GET_CURRENT_CONTEXT(ctx); - print_list(ctx, list); + print_list(ctx, list, NULL); } @@ -10088,6 +10112,8 @@ _mesa_init_display_list(struct gl_context *ctx) ctx->List.ListBase = 0; save_vtxfmt_init(&ctx->ListState.ListVtxfmt); + + InstSize[OPCODE_NOP] = 1; } diff --git a/mesalib/src/mesa/main/dlist.h b/mesalib/src/mesa/main/dlist.h index 7726e77d8..6189632d4 100644 --- a/mesalib/src/mesa/main/dlist.h +++ b/mesalib/src/mesa/main/dlist.h @@ -60,10 +60,13 @@ extern void _mesa_compile_error( struct gl_context *ctx, GLenum error, const cha extern void *_mesa_dlist_alloc(struct gl_context *ctx, GLuint opcode, GLuint sz); +extern void * +_mesa_dlist_alloc_aligned(struct gl_context *ctx, GLuint opcode, GLuint bytes); + extern GLint _mesa_dlist_alloc_opcode( struct gl_context *ctx, GLuint sz, void (*execute)( struct gl_context *, void * ), void (*destroy)( struct gl_context *, void * ), - void (*print)( struct gl_context *, void * ) ); + void (*print)( struct gl_context *, void *, FILE * ) ); extern void _mesa_delete_list(struct gl_context *ctx, struct gl_display_list *dlist); diff --git a/mesalib/src/mesa/main/enable.c b/mesalib/src/mesa/main/enable.c index 417548a3c..11365ecc4 100644 --- a/mesalib/src/mesa/main/enable.c +++ b/mesalib/src/mesa/main/enable.c @@ -34,7 +34,7 @@ #include "enable.h" #include "errors.h" #include "light.h" -#include "simple_list.h" +#include "util/simple_list.h" #include "mtypes.h" #include "enums.h" #include "api_arrayelt.h" diff --git a/mesalib/src/mesa/main/enums.h b/mesalib/src/mesa/main/enums.h index 36c053d4b..66bdd53bb 100644 --- a/mesalib/src/mesa/main/enums.h +++ b/mesalib/src/mesa/main/enums.h @@ -37,6 +37,11 @@ #define _ENUMS_H_ +#ifdef __cplusplus +extern "C" { +#endif + + extern const char *_mesa_lookup_enum_by_nr( int nr ); /* Get the name of an enum given that it is a primitive type. Avoids @@ -44,4 +49,10 @@ extern const char *_mesa_lookup_enum_by_nr( int nr ); */ const char *_mesa_lookup_prim_by_nr( unsigned nr ); + +#ifdef __cplusplus +} +#endif + + #endif diff --git a/mesalib/src/mesa/main/errors.c b/mesalib/src/mesa/main/errors.c index 7d622bb16..478e4ed33 100644 --- a/mesalib/src/mesa/main/errors.c +++ b/mesalib/src/mesa/main/errors.c @@ -134,7 +134,7 @@ static const GLenum debug_severity_enums[] = { static enum mesa_debug_source gl_enum_to_debug_source(GLenum e) { - int i; + unsigned i; for (i = 0; i < Elements(debug_source_enums); i++) { if (debug_source_enums[i] == e) @@ -146,7 +146,7 @@ gl_enum_to_debug_source(GLenum e) static enum mesa_debug_type gl_enum_to_debug_type(GLenum e) { - int i; + unsigned i; for (i = 0; i < Elements(debug_type_enums); i++) { if (debug_type_enums[i] == e) @@ -158,7 +158,7 @@ gl_enum_to_debug_type(GLenum e) static enum mesa_debug_severity gl_enum_to_debug_severity(GLenum e) { - int i; + unsigned i; for (i = 0; i < Elements(debug_severity_enums); i++) { if (debug_severity_enums[i] == e) @@ -633,7 +633,7 @@ debug_fetch_message(const struct gl_debug_state *debug) * Delete the oldest debug messages out of the log. */ static void -debug_delete_messages(struct gl_debug_state *debug, unsigned count) +debug_delete_messages(struct gl_debug_state *debug, int count) { struct gl_debug_log *log = &debug->Log; @@ -1395,6 +1395,7 @@ should_output(struct gl_context *ctx, GLenum error, const char *fmtString) void _mesa_gl_debug(struct gl_context *ctx, GLuint *id, + enum mesa_debug_source source, enum mesa_debug_type type, enum mesa_debug_severity severity, const char *fmtString, ...) @@ -1409,7 +1410,7 @@ _mesa_gl_debug(struct gl_context *ctx, len = _mesa_vsnprintf(s, MAX_DEBUG_MESSAGE_LENGTH, fmtString, args); va_end(args); - log_msg(ctx, MESA_DEBUG_SOURCE_API, type, *id, severity, len, s); + log_msg(ctx, source, type, *id, severity, len, s); } diff --git a/mesalib/src/mesa/main/errors.h b/mesalib/src/mesa/main/errors.h index b388138e8..0c521c0d0 100644 --- a/mesalib/src/mesa/main/errors.h +++ b/mesalib/src/mesa/main/errors.h @@ -38,14 +38,13 @@ #include "compiler.h" #include "glheader.h" +#include "mtypes.h" #ifdef __cplusplus extern "C" { #endif -#include "mtypes.h" - struct _glapi_table; extern void @@ -72,14 +71,16 @@ _mesa_debug( const struct gl_context *ctx, const char *fmtString, ... ) PRINTFLI extern void _mesa_gl_debug(struct gl_context *ctx, GLuint *id, + enum mesa_debug_source source, enum mesa_debug_type type, enum mesa_debug_severity severity, - const char *fmtString, ...) PRINTFLIKE(5, 6); + const char *fmtString, ...) PRINTFLIKE(6, 7); #define _mesa_perf_debug(ctx, sev, ...) do { \ static GLuint msg_id = 0; \ if (unlikely(ctx->Const.ContextFlags & GL_CONTEXT_FLAG_DEBUG_BIT)) { \ _mesa_gl_debug(ctx, &msg_id, \ + MESA_DEBUG_SOURCE_API, \ MESA_DEBUG_TYPE_PERFORMANCE, \ sev, \ __VA_ARGS__); \ diff --git a/mesalib/src/mesa/main/extensions.c b/mesalib/src/mesa/main/extensions.c index 0df04c2e6..f21201538 100644 --- a/mesalib/src/mesa/main/extensions.c +++ b/mesalib/src/mesa/main/extensions.c @@ -104,6 +104,7 @@ static const struct extension extension_table[] = { { "GL_ARB_depth_clamp", o(ARB_depth_clamp), GL, 2003 }, { "GL_ARB_depth_texture", o(ARB_depth_texture), GLL, 2001 }, { "GL_ARB_derivative_control", o(ARB_derivative_control), GL, 2014 }, + { "GL_ARB_direct_state_access", o(dummy_false), GL, 2014 }, { "GL_ARB_draw_buffers", o(dummy_true), GL, 2002 }, { "GL_ARB_draw_buffers_blend", o(ARB_draw_buffers_blend), GL, 2009 }, { "GL_ARB_draw_elements_base_vertex", o(ARB_draw_elements_base_vertex), GL, 2009 }, @@ -120,6 +121,7 @@ static const struct extension extension_table[] = { { "GL_ARB_framebuffer_sRGB", o(EXT_framebuffer_sRGB), GL, 1998 }, { "GL_ARB_get_program_binary", o(dummy_true), GL, 2010 }, { "GL_ARB_gpu_shader5", o(ARB_gpu_shader5), GLC, 2010 }, + { "GL_ARB_gpu_shader_fp64", o(ARB_gpu_shader_fp64), GLC, 2010 }, { "GL_ARB_half_float_pixel", o(dummy_true), GL, 2003 }, { "GL_ARB_half_float_vertex", o(ARB_half_float_vertex), GL, 2008 }, { "GL_ARB_instanced_arrays", o(ARB_instanced_arrays), GL, 2008 }, @@ -133,6 +135,7 @@ static const struct extension extension_table[] = { { "GL_ARB_multitexture", o(dummy_true), GLL, 1998 }, { "GL_ARB_occlusion_query2", o(ARB_occlusion_query2), GL, 2003 }, { "GL_ARB_occlusion_query", o(ARB_occlusion_query), GLL, 2001 }, + { "GL_ARB_pipeline_statistics_query", o(ARB_pipeline_statistics_query), GL, 2014 }, { "GL_ARB_pixel_buffer_object", o(EXT_pixel_buffer_object), GL, 2004 }, { "GL_ARB_point_parameters", o(EXT_point_parameters), GLL, 1997 }, { "GL_ARB_point_sprite", o(ARB_point_sprite), GL, 2003 }, @@ -147,6 +150,7 @@ static const struct extension extension_table[] = { { "GL_ARB_shader_bit_encoding", o(ARB_shader_bit_encoding), GL, 2010 }, { "GL_ARB_shader_image_load_store", o(ARB_shader_image_load_store), GL, 2011 }, { "GL_ARB_shader_objects", o(dummy_true), GL, 2002 }, + { "GL_ARB_shader_precision", o(ARB_shader_precision), GL, 2010 }, { "GL_ARB_shader_stencil_export", o(ARB_shader_stencil_export), GL, 2009 }, { "GL_ARB_shader_texture_lod", o(ARB_shader_texture_lod), GL, 2009 }, { "GL_ARB_shading_language_100", o(dummy_true), GLL, 2003 }, @@ -156,6 +160,7 @@ static const struct extension extension_table[] = { { "GL_ARB_stencil_texturing", o(ARB_stencil_texturing), GL, 2012 }, { "GL_ARB_sync", o(ARB_sync), GL, 2003 }, { "GL_ARB_texture_barrier", o(NV_texture_barrier), GL, 2014 }, + { "GL_ARB_tessellation_shader", o(ARB_tessellation_shader), GLC, 2009 }, { "GL_ARB_texture_border_clamp", o(ARB_texture_border_clamp), GLL, 2000 }, { "GL_ARB_texture_buffer_object", o(ARB_texture_buffer_object), GLC, 2008 }, { "GL_ARB_texture_buffer_object_rgb32", o(ARB_texture_buffer_object_rgb32), GLC, 2009 }, @@ -212,6 +217,7 @@ static const struct extension extension_table[] = { { "GL_EXT_compiled_vertex_array", o(dummy_true), GLL, 1996 }, { "GL_EXT_copy_texture", o(dummy_true), GLL, 1995 }, { "GL_EXT_depth_bounds_test", o(EXT_depth_bounds_test), GL, 2002 }, + { "GL_EXT_draw_buffers", o(dummy_true), ES2, 2012 }, { "GL_EXT_draw_buffers2", o(EXT_draw_buffers2), GL, 2006 }, { "GL_EXT_draw_instanced", o(ARB_draw_instanced), GL, 2006 }, { "GL_EXT_draw_range_elements", o(dummy_true), GLL, 1997 }, @@ -231,6 +237,7 @@ static const struct extension extension_table[] = { { "GL_EXT_pixel_buffer_object", o(EXT_pixel_buffer_object), GL, 2004 }, { "GL_EXT_point_parameters", o(EXT_point_parameters), GLL, 1997 }, { "GL_EXT_polygon_offset", o(dummy_true), GLL, 1995 }, + { "GL_EXT_polygon_offset_clamp", o(EXT_polygon_offset_clamp), GL, 2014 }, { "GL_EXT_provoking_vertex", o(EXT_provoking_vertex), GL, 2009 }, { "GL_EXT_rescale_normal", o(dummy_true), GLL, 1997 }, { "GL_EXT_secondary_color", o(dummy_true), GLL, 1999 }, @@ -314,6 +321,10 @@ static const struct extension extension_table[] = { { "GL_OES_texture_3D", o(EXT_texture3D), ES2, 2005 }, { "GL_OES_texture_cube_map", o(ARB_texture_cube_map), ES1, 2007 }, { "GL_OES_texture_env_crossbar", o(ARB_texture_env_crossbar), ES1, 2005 }, + { "GL_OES_texture_float", o(OES_texture_float), ES2, 2005 }, + { "GL_OES_texture_float_linear", o(OES_texture_float_linear), ES2, 2005 }, + { "GL_OES_texture_half_float", o(OES_texture_half_float), ES2, 2005 }, + { "GL_OES_texture_half_float_linear", o(OES_texture_half_float_linear), ES2, 2005 }, { "GL_OES_texture_mirrored_repeat", o(dummy_true), ES1, 2005 }, { "GL_OES_texture_npot", o(ARB_texture_non_power_of_two), ES1 | ES2, 2005 }, { "GL_OES_vertex_array_object", o(dummy_true), ES1 | ES2, 2010 }, @@ -327,6 +338,7 @@ static const struct extension extension_table[] = { { "GL_AMD_conservative_depth", o(ARB_conservative_depth), GL, 2009 }, { "GL_AMD_draw_buffers_blend", o(ARB_draw_buffers_blend), GL, 2009 }, { "GL_AMD_performance_monitor", o(AMD_performance_monitor), GL, 2007 }, + { "GL_AMD_pinned_memory", o(AMD_pinned_memory), GL, 2013 }, { "GL_AMD_seamless_cubemap_per_texture", o(AMD_seamless_cubemap_per_texture), GL, 2009 }, { "GL_AMD_shader_stencil_export", o(ARB_shader_stencil_export), GL, 2009 }, { "GL_AMD_shader_trinary_minmax", o(dummy_true), GL, 2012 }, @@ -503,7 +515,6 @@ _mesa_enable_sw_extensions(struct gl_context *ctx) ctx->Extensions.NV_point_sprite = GL_TRUE; ctx->Extensions.NV_texture_env_combine4 = GL_TRUE; ctx->Extensions.NV_texture_rectangle = GL_TRUE; - ctx->Extensions.NV_fragment_program_option = GL_TRUE; ctx->Extensions.EXT_gpu_program_parameters = GL_TRUE; ctx->Extensions.OES_standard_derivatives = GL_TRUE; ctx->Extensions.TDFX_texture_compression_FXT1 = GL_TRUE; diff --git a/mesalib/src/mesa/main/fbobject.c b/mesalib/src/mesa/main/fbobject.c index 8283373a4..305362297 100644 --- a/mesalib/src/mesa/main/fbobject.c +++ b/mesalib/src/mesa/main/fbobject.c @@ -468,6 +468,7 @@ set_renderbuffer_attachment(struct gl_context *ctx, remove_attachment(ctx, att); att->Type = GL_RENDERBUFFER_EXT; att->Texture = NULL; /* just to be safe */ + att->Layered = GL_FALSE; att->Complete = GL_FALSE; _mesa_reference_renderbuffer(&att->Renderbuffer, rb); } @@ -599,6 +600,7 @@ fbo_incomplete(struct gl_context *ctx, const char *msg, int index) static GLuint msg_id; _mesa_gl_debug(ctx, &msg_id, + MESA_DEBUG_SOURCE_API, MESA_DEBUG_TYPE_OTHER, MESA_DEBUG_SEVERITY_MEDIUM, "FBO incomplete: %s [%d]\n", msg, index); @@ -779,6 +781,18 @@ test_attachment_completeness(const struct gl_context *ctx, GLenum format, att->Complete = GL_FALSE; return; } + + /* OES_texture_float allows creation and use of floating point + * textures with GL_FLOAT, GL_HALF_FLOAT but it does not allow + * these textures to be used as a render target, this is done via + * GL_EXT_color_buffer(_half)_float with set of new sized types. + */ + if (_mesa_is_gles(ctx) && (texImage->TexObject->_IsFloat || + texImage->TexObject->_IsHalfFloat)) { + att_incomplete("bad internal format"); + att->Complete = GL_FALSE; + return; + } } else if (format == GL_DEPTH) { if (baseFormat == GL_DEPTH_COMPONENT) { @@ -885,6 +899,8 @@ _mesa_test_framebuffer_completeness(struct gl_context *ctx, GLuint max_layer_count = 0, att_layer_count; bool is_layered = false; GLenum layer_tex_target = 0; + bool has_depth_attachment = false; + bool has_stencil_attachment = false; assert(_mesa_is_user_fbo(fb)); @@ -922,6 +938,8 @@ _mesa_test_framebuffer_completeness(struct gl_context *ctx, fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT; fbo_incomplete(ctx, "depth attachment incomplete", -1); return; + } else if (att->Type != GL_NONE) { + has_depth_attachment = true; } } else if (i == -1) { @@ -931,6 +949,8 @@ _mesa_test_framebuffer_completeness(struct gl_context *ctx, fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT; fbo_incomplete(ctx, "stencil attachment incomplete", -1); return; + } else if (att->Type != GL_NONE) { + has_stencil_attachment = true; } } else { @@ -959,7 +979,7 @@ _mesa_test_framebuffer_completeness(struct gl_context *ctx, if (!is_format_color_renderable(ctx, attFormat, texImg->InternalFormat) && !is_legal_depth_format(ctx, f)) { - fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT; + fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; fbo_incomplete(ctx, "texture attachment incomplete", -1); return; } @@ -1127,6 +1147,20 @@ _mesa_test_framebuffer_completeness(struct gl_context *ctx, } } + /* The OpenGL ES3 spec, in chapter 9.4. FRAMEBUFFER COMPLETENESS, says: + * + * "Depth and stencil attachments, if present, are the same image." + * + * This restriction is not present in the OpenGL ES2 spec. + */ + if (_mesa_is_gles3(ctx) && + has_stencil_attachment && has_depth_attachment && + !_mesa_has_depthstencil_combined(fb)) { + fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED; + fbo_incomplete(ctx, "Depth and stencil attachments must be the same image", -1); + return; + } + /* Provisionally set status = COMPLETE ... */ fb->_Status = GL_FRAMEBUFFER_COMPLETE_EXT; @@ -1290,6 +1324,11 @@ _mesa_DeleteRenderbuffers(GLsizei n, const GLuint *renderbuffers) GLint i; GET_CURRENT_CONTEXT(ctx); + if (n < 0) { + _mesa_error(ctx, GL_INVALID_VALUE, "glDeleteRenderbuffers(n < 0)"); + return; + } + FLUSH_VERTICES(ctx, _NEW_BUFFERS); for (i = 0; i < n; i++) { @@ -2176,6 +2215,11 @@ _mesa_DeleteFramebuffers(GLsizei n, const GLuint *framebuffers) GLint i; GET_CURRENT_CONTEXT(ctx); + if (n < 0) { + _mesa_error(ctx, GL_INVALID_VALUE, "glDeleteFramebuffers(n < 0)"); + return; + } + FLUSH_VERTICES(ctx, _NEW_BUFFERS); for (i = 0; i < n; i++) { @@ -2316,7 +2360,7 @@ reuse_framebuffer_texture_attachment(struct gl_framebuffer *fb, static void framebuffer_texture(struct gl_context *ctx, const char *caller, GLenum target, GLenum attachment, GLenum textarget, GLuint texture, - GLint level, GLint zoffset, GLboolean layered) + GLint level, GLuint zoffset, GLboolean layered) { struct gl_renderbuffer_attachment *att; struct gl_texture_object *texObj = NULL; @@ -2410,8 +2454,8 @@ framebuffer_texture(struct gl_context *ctx, const char *caller, GLenum target, } if (texObj->Target == GL_TEXTURE_3D) { - const GLint maxSize = 1 << (ctx->Const.Max3DTextureLevels - 1); - if (zoffset < 0 || zoffset >= maxSize) { + const GLuint maxSize = 1 << (ctx->Const.Max3DTextureLevels - 1); + if (zoffset >= maxSize) { _mesa_error(ctx, GL_INVALID_VALUE, "glFramebufferTexture%s(zoffset)", caller); return; @@ -2421,8 +2465,7 @@ framebuffer_texture(struct gl_context *ctx, const char *caller, GLenum target, (texObj->Target == GL_TEXTURE_2D_ARRAY_EXT) || (texObj->Target == GL_TEXTURE_CUBE_MAP_ARRAY) || (texObj->Target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY)) { - if (zoffset < 0 || - zoffset >= (GLint) ctx->Const.MaxArrayTextureLayers) { + if (zoffset >= ctx->Const.MaxArrayTextureLayers) { _mesa_error(ctx, GL_INVALID_VALUE, "glFramebufferTexture%s(layer)", caller); return; @@ -2759,7 +2802,7 @@ _mesa_GetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, if (_mesa_is_gles3(ctx) && attachment != GL_BACK && attachment != GL_DEPTH && attachment != GL_STENCIL) { - _mesa_error(ctx, GL_INVALID_OPERATION, + _mesa_error(ctx, GL_INVALID_ENUM, "glGetFramebufferAttachmentParameteriv(attachment)"); return; } @@ -2862,7 +2905,8 @@ _mesa_GetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, _mesa_error(ctx, err, "glGetFramebufferAttachmentParameteriv(pname)"); } else if (att->Type == GL_TEXTURE) { - if (att->Texture && att->Texture->Target == GL_TEXTURE_3D) { + if (att->Texture && (att->Texture->Target == GL_TEXTURE_3D || + att->Texture->Target == GL_TEXTURE_2D_ARRAY)) { *params = att->Zoffset; } else { @@ -2960,7 +3004,7 @@ _mesa_GetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, } else if (att->Texture) { const struct gl_texture_image *texImage = - _mesa_select_tex_image(ctx, att->Texture, att->Texture->Target, + _mesa_select_tex_image(att->Texture, att->Texture->Target, att->TextureLevel); if (texImage) { *params = get_component_bits(pname, texImage->_BaseFormat, @@ -3073,6 +3117,14 @@ invalidate_framebuffer_storage(GLenum target, GLsizei numAttachments, case GL_DEPTH_ATTACHMENT: case GL_STENCIL_ATTACHMENT: break; + case GL_DEPTH_STENCIL_ATTACHMENT: + /* GL_DEPTH_STENCIL_ATTACHMENT is a valid attachment point only + * in desktop and ES 3.0 profiles. Note that OES_packed_depth_stencil + * extension does not make this attachment point valid on ES 2.0. + */ + if (_mesa_is_desktop_gl(ctx) || _mesa_is_gles3(ctx)) + break; + /* fallthrough */ case GL_COLOR_ATTACHMENT0: case GL_COLOR_ATTACHMENT1: case GL_COLOR_ATTACHMENT2: diff --git a/mesalib/src/mesa/main/feedback.c b/mesalib/src/mesa/main/feedback.c index 9ea0b92f3..6bc4294f9 100644 --- a/mesalib/src/mesa/main/feedback.c +++ b/mesalib/src/mesa/main/feedback.c @@ -89,7 +89,7 @@ _mesa_FeedbackBuffer( GLsizei size, GLenum type, GLfloat *buffer ) ctx->Feedback.Type = type; ctx->Feedback.BufferSize = size; ctx->Feedback.Buffer = buffer; - ctx->Feedback.Count = 0; /* Becaues of this. */ + ctx->Feedback.Count = 0; /* Because of this. */ } diff --git a/mesalib/src/mesa/main/ff_fragment_shader.cpp b/mesalib/src/mesa/main/ff_fragment_shader.cpp index 5591d57df..c6828925f 100644 --- a/mesalib/src/mesa/main/ff_fragment_shader.cpp +++ b/mesalib/src/mesa/main/ff_fragment_shader.cpp @@ -27,13 +27,15 @@ * **************************************************************************/ -extern "C" { #include "glheader.h" #include "imports.h" #include "mtypes.h" #include "main/context.h" #include "main/macros.h" #include "main/samplerobj.h" +#include "main/texenvprogram.h" +#include "main/texobj.h" +#include "main/uniforms.h" #include "program/program.h" #include "program/prog_parameter.h" #include "program/prog_cache.h" @@ -41,10 +43,6 @@ extern "C" { #include "program/prog_print.h" #include "program/prog_statevars.h" #include "program/programopt.h" -#include "texenvprogram.h" -#include "texobj.h" -} -#include "main/uniforms.h" #include "../glsl/glsl_types.h" #include "../glsl/ir.h" #include "../glsl/ir_builder.h" @@ -420,7 +418,7 @@ static GLuint make_state_key( struct gl_context *ctx, struct state_key *key ) continue; samp = _mesa_get_samplerobj(ctx, i); - format = texObj->Image[0][texObj->BaseLevel]->_BaseFormat; + format = _mesa_texture_base_format(texObj); key->unit[i].enabled = 1; key->enabled_units |= (1<program->Base.NumInstructions <= p->max_inst); + assert(p->program->Base.NumInstructions <= p->max_inst); if (p->program->Base.NumInstructions == p->max_inst) { /* need to extend the program's instruction array */ diff --git a/mesalib/src/mesa/main/format_info.py b/mesalib/src/mesa/main/format_info.py index 7424fe0cd..3bae57e54 100644 --- a/mesalib/src/mesa/main/format_info.py +++ b/mesalib/src/mesa/main/format_info.py @@ -58,7 +58,7 @@ def get_gl_base_format(fmat): elif fmat.has_channel('i') and fmat.num_channels() == 1: return 'GL_INTENSITY' else: - assert False + sys.exit("error, could not determine base format for {0}, check swizzle".format(fmat.name)); def get_gl_data_type(fmat): if fmat.is_compressed(): @@ -192,6 +192,22 @@ for fmat in formats: int(fmat.block_size() / 8)) print ' {{ {0} }},'.format(', '.join(map(str, fmat.swizzle))) + if fmat.is_array(): + chan = fmat.array_element() + norm = chan.norm or chan.type == parser.FLOAT + print ' MESA_ARRAY_FORMAT({0}),'.format(', '.join([ + str(chan.size / 8), + str(int(chan.sign)), + str(int(chan.type == parser.FLOAT)), + str(int(norm)), + str(len(fmat.channels)), + str(fmat.swizzle[0]), + str(fmat.swizzle[1]), + str(fmat.swizzle[2]), + str(fmat.swizzle[3]), + ])) + else: + print ' 0,' print ' },' print '};' diff --git a/mesalib/src/mesa/main/format_pack.c b/mesalib/src/mesa/main/format_pack.c deleted file mode 100644 index 31c9f7767..000000000 --- a/mesalib/src/mesa/main/format_pack.c +++ /dev/null @@ -1,2994 +0,0 @@ -/* - * Mesa 3-D graphics library - * - * Copyright (c) 2011 VMware, Inc. - * - * 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 - * 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. - */ - - -/** - * Color, depth, stencil packing functions. - * Used to pack basic color, depth and stencil formats to specific - * hardware formats. - * - * There are both per-pixel and per-row packing functions: - * - The former will be used by swrast to write values to the color, depth, - * stencil buffers when drawing points, lines and masked spans. - * - The later will be used for image-oriented functions like glDrawPixels, - * glAccum, and glTexImage. - */ - - -#include "colormac.h" -#include "format_pack.h" -#include "macros.h" -#include "../../gallium/auxiliary/util/u_format_rgb9e5.h" -#include "../../gallium/auxiliary/util/u_format_r11g11b10f.h" -#include "util/format_srgb.h" - - -/** Helper struct for MESA_FORMAT_Z32_FLOAT_S8X24_UINT */ -struct z32f_x24s8 -{ - float z; - uint32_t x24s8; -}; - - -typedef void (*pack_ubyte_rgba_row_func)(GLuint n, - const GLubyte src[][4], void *dst); - -typedef void (*pack_float_rgba_row_func)(GLuint n, - const GLfloat src[][4], void *dst); - - -/* - * MESA_FORMAT_A8B8G8R8_UNORM - */ - -static void -pack_ubyte_A8B8G8R8_UNORM(const GLubyte src[4], void *dst) -{ - GLuint *d = ((GLuint *) dst); - *d = PACK_COLOR_8888(src[RCOMP], src[GCOMP], src[BCOMP], src[ACOMP]); -} - -static void -pack_float_A8B8G8R8_UNORM(const GLfloat src[4], void *dst) -{ - GLubyte v[4]; - _mesa_unclamped_float_rgba_to_ubyte(v, src); - pack_ubyte_A8B8G8R8_UNORM(v, dst); -} - -static void -pack_row_ubyte_A8B8G8R8_UNORM(GLuint n, const GLubyte src[][4], void *dst) -{ - GLuint *d = ((GLuint *) dst); - GLuint i; - for (i = 0; i < n; i++) { - d[i] = PACK_COLOR_8888(src[i][RCOMP], src[i][GCOMP], - src[i][BCOMP], src[i][ACOMP]); - } -} - -static void -pack_row_float_A8B8G8R8_UNORM(GLuint n, const GLfloat src[][4], void *dst) -{ - GLuint *d = ((GLuint *) dst); - GLuint i; - for (i = 0; i < n; i++) { - GLubyte v[4]; - _mesa_unclamped_float_rgba_to_ubyte(v, src[i]); - pack_ubyte_A8B8G8R8_UNORM(v, d + i); - } -} - - - -/* - * MESA_FORMAT_R8G8B8A8_UNORM - */ - -static void -pack_ubyte_R8G8B8A8_UNORM(const GLubyte src[4], void *dst) -{ - GLuint *d = ((GLuint *) dst); - *d = PACK_COLOR_8888(src[ACOMP], src[BCOMP], src[GCOMP], src[RCOMP]); -} - -static void -pack_float_R8G8B8A8_UNORM(const GLfloat src[4], void *dst) -{ - GLubyte v[4]; - _mesa_unclamped_float_rgba_to_ubyte(v, src); - pack_ubyte_R8G8B8A8_UNORM(v, dst); -} - -static void -pack_row_ubyte_R8G8B8A8_UNORM(GLuint n, const GLubyte src[][4], void *dst) -{ - GLuint *d = ((GLuint *) dst); - GLuint i; - for (i = 0; i < n; i++) { - d[i] = PACK_COLOR_8888(src[i][ACOMP], src[i][BCOMP], - src[i][GCOMP], src[i][RCOMP]); - } -} - -static void -pack_row_float_R8G8B8A8_UNORM(GLuint n, const GLfloat src[][4], void *dst) -{ - GLuint *d = ((GLuint *) dst); - GLuint i; - for (i = 0; i < n; i++) { - GLubyte v[4]; - _mesa_unclamped_float_rgba_to_ubyte(v, src[i]); - pack_ubyte_R8G8B8A8_UNORM(v, d + i); - } -} - - -/* - * MESA_FORMAT_B8G8R8A8_UNORM - */ - -static void -pack_ubyte_B8G8R8A8_UNORM(const GLubyte src[4], void *dst) -{ - GLuint *d = ((GLuint *) dst); - *d = PACK_COLOR_8888(src[ACOMP], src[RCOMP], src[GCOMP], src[BCOMP]); -} - -static void -pack_float_B8G8R8A8_UNORM(const GLfloat src[4], void *dst) -{ - GLubyte v[4]; - _mesa_unclamped_float_rgba_to_ubyte(v, src); - pack_ubyte_B8G8R8A8_UNORM(v, dst); -} - -static void -pack_row_ubyte_B8G8R8A8_UNORM(GLuint n, const GLubyte src[][4], void *dst) -{ - GLuint *d = ((GLuint *) dst); - GLuint i; - for (i = 0; i < n; i++) { - d[i] = PACK_COLOR_8888(src[i][ACOMP], src[i][RCOMP], - src[i][GCOMP], src[i][BCOMP]); - } -} - -static void -pack_row_float_B8G8R8A8_UNORM(GLuint n, const GLfloat src[][4], void *dst) -{ - GLuint *d = ((GLuint *) dst); - GLuint i; - for (i = 0; i < n; i++) { - GLubyte v[4]; - _mesa_unclamped_float_rgba_to_ubyte(v, src[i]); - pack_ubyte_B8G8R8A8_UNORM(v, d + i); - } -} - - -/* - * MESA_FORMAT_A8R8G8B8_UNORM - */ - -static void -pack_ubyte_A8R8G8B8_UNORM(const GLubyte src[4], void *dst) -{ - GLuint *d = ((GLuint *) dst); - *d = PACK_COLOR_8888(src[BCOMP], src[GCOMP], src[RCOMP], src[ACOMP]); -} - -static void -pack_float_A8R8G8B8_UNORM(const GLfloat src[4], void *dst) -{ - GLubyte v[4]; - _mesa_unclamped_float_rgba_to_ubyte(v, src); - pack_ubyte_A8R8G8B8_UNORM(v, dst); -} - -static void -pack_row_ubyte_A8R8G8B8_UNORM(GLuint n, const GLubyte src[][4], void *dst) -{ - GLuint *d = ((GLuint *) dst); - GLuint i; - for (i = 0; i < n; i++) { - d[i] = PACK_COLOR_8888(src[i][BCOMP], src[i][GCOMP], - src[i][RCOMP], src[i][ACOMP]); - } -} - -static void -pack_row_float_A8R8G8B8_UNORM(GLuint n, const GLfloat src[][4], void *dst) -{ - GLuint *d = ((GLuint *) dst); - GLuint i; - for (i = 0; i < n; i++) { - GLubyte v[4]; - _mesa_unclamped_float_rgba_to_ubyte(v, src[i]); - pack_ubyte_A8R8G8B8_UNORM(v, d + i); - } -} - - -/* - * MESA_FORMAT_B8G8R8X8_UNORM - */ - -static void -pack_ubyte_B8G8R8X8_UNORM(const GLubyte src[4], void *dst) -{ - GLuint *d = ((GLuint *) dst); - *d = PACK_COLOR_8888(0x0, src[RCOMP], src[GCOMP], src[BCOMP]); -} - -static void -pack_float_B8G8R8X8_UNORM(const GLfloat src[4], void *dst) -{ - GLubyte v[4]; - _mesa_unclamped_float_rgba_to_ubyte(v, src); - pack_ubyte_B8G8R8X8_UNORM(v, dst); -} - -static void -pack_row_ubyte_B8G8R8X8_UNORM(GLuint n, const GLubyte src[][4], void *dst) -{ - GLuint *d = ((GLuint *) dst); - GLuint i; - for (i = 0; i < n; i++) { - d[i] = PACK_COLOR_8888(0, src[i][RCOMP], src[i][GCOMP], src[i][BCOMP]); - } -} - -static void -pack_row_float_B8G8R8X8_UNORM(GLuint n, const GLfloat src[][4], void *dst) -{ - GLuint *d = ((GLuint *) dst); - GLuint i; - for (i = 0; i < n; i++) { - GLubyte v[4]; - _mesa_unclamped_float_rgba_to_ubyte(v, src[i]); - pack_ubyte_B8G8R8X8_UNORM(v, d + i); - } -} - - -/* - * MESA_FORMAT_X8R8G8B8_UNORM - */ - -static void -pack_ubyte_X8R8G8B8_UNORM(const GLubyte src[4], void *dst) -{ - GLuint *d = ((GLuint *) dst); - *d = PACK_COLOR_8888(src[BCOMP], src[GCOMP], src[RCOMP], 0); -} - -static void -pack_float_X8R8G8B8_UNORM(const GLfloat src[4], void *dst) -{ - GLubyte v[4]; - _mesa_unclamped_float_rgba_to_ubyte(v, src); - pack_ubyte_X8R8G8B8_UNORM(v, dst); -} - -static void -pack_row_ubyte_X8R8G8B8_UNORM(GLuint n, const GLubyte src[][4], void *dst) -{ - GLuint *d = ((GLuint *) dst); - GLuint i; - for (i = 0; i < n; i++) { - d[i] = PACK_COLOR_8888(src[i][BCOMP], src[i][GCOMP], src[i][RCOMP], 0); - } -} - -static void -pack_row_float_X8R8G8B8_UNORM(GLuint n, const GLfloat src[][4], void *dst) -{ - GLuint *d = ((GLuint *) dst); - GLuint i; - for (i = 0; i < n; i++) { - GLubyte v[4]; - _mesa_unclamped_float_rgba_to_ubyte(v, src[i]); - pack_ubyte_X8R8G8B8_UNORM(v, d + i); - } -} - - -/* - * MESA_FORMAT_BGR_UNORM8 - */ - -static void -pack_ubyte_BGR_UNORM8(const GLubyte src[4], void *dst) -{ - GLubyte *d = ((GLubyte *) dst); - d[2] = src[RCOMP]; - d[1] = src[GCOMP]; - d[0] = src[BCOMP]; -} - -static void -pack_float_BGR_UNORM8(const GLfloat src[4], void *dst) -{ - GLubyte *d = ((GLubyte *) dst); - UNCLAMPED_FLOAT_TO_UBYTE(d[2], src[RCOMP]); - UNCLAMPED_FLOAT_TO_UBYTE(d[1], src[GCOMP]); - UNCLAMPED_FLOAT_TO_UBYTE(d[0], src[BCOMP]); -} - -static void -pack_row_ubyte_BGR_UNORM8(GLuint n, const GLubyte src[][4], void *dst) -{ - GLubyte *d = ((GLubyte *) dst); - GLuint i; - for (i = 0; i < n; i++) { - d[i*3+2] = src[i][RCOMP]; - d[i*3+1] = src[i][GCOMP]; - d[i*3+0] = src[i][BCOMP]; - } -} - -static void -pack_row_float_BGR_UNORM8(GLuint n, const GLfloat src[][4], void *dst) -{ - GLubyte *d = ((GLubyte *) dst); - GLuint i; - for (i = 0; i < n; i++) { - GLubyte v[4]; - _mesa_unclamped_float_rgba_to_ubyte(v, src[i]); - d[i*3+2] = v[RCOMP]; - d[i*3+1] = v[GCOMP]; - d[i*3+0] = v[BCOMP]; - } -} - - -/* - * MESA_FORMAT_RGB_UNORM8 - */ - -static void -pack_ubyte_RGB_UNORM8(const GLubyte src[4], void *dst) -{ - GLubyte *d = ((GLubyte *) dst); - d[2] = src[BCOMP]; - d[1] = src[GCOMP]; - d[0] = src[RCOMP]; -} - -static void -pack_float_RGB_UNORM8(const GLfloat src[4], void *dst) -{ - GLubyte *d = ((GLubyte *) dst); - UNCLAMPED_FLOAT_TO_UBYTE(d[2], src[BCOMP]); - UNCLAMPED_FLOAT_TO_UBYTE(d[1], src[GCOMP]); - UNCLAMPED_FLOAT_TO_UBYTE(d[0], src[RCOMP]); -} - -static void -pack_row_ubyte_RGB_UNORM8(GLuint n, const GLubyte src[][4], void *dst) -{ - GLubyte *d = ((GLubyte *) dst); - GLuint i; - for (i = 0; i < n; i++) { - d[i*3+2] = src[i][BCOMP]; - d[i*3+1] = src[i][GCOMP]; - d[i*3+0] = src[i][RCOMP]; - } -} - -static void -pack_row_float_RGB_UNORM8(GLuint n, const GLfloat src[][4], void *dst) -{ - GLubyte *d = ((GLubyte *) dst); - GLuint i; - for (i = 0; i < n; i++) { - GLubyte v[4]; - _mesa_unclamped_float_rgba_to_ubyte(v, src[i]); - d[i*3+2] = v[BCOMP]; - d[i*3+1] = v[GCOMP]; - d[i*3+0] = v[RCOMP]; - } -} - - -/* - * MESA_FORMAT_B5G6R5_UNORM - */ - -static void -pack_ubyte_B5G6R5_UNORM(const GLubyte src[4], void *dst) -{ - GLushort *d = ((GLushort *) dst); - *d = PACK_COLOR_565(src[RCOMP], src[GCOMP], src[BCOMP]); -} - -static void -pack_float_B5G6R5_UNORM(const GLfloat src[4], void *dst) -{ - GLubyte v[3]; - UNCLAMPED_FLOAT_TO_UBYTE(v[0], src[RCOMP]); - UNCLAMPED_FLOAT_TO_UBYTE(v[1], src[GCOMP]); - UNCLAMPED_FLOAT_TO_UBYTE(v[2], src[BCOMP]); - pack_ubyte_B5G6R5_UNORM(v, dst); -} - -static void -pack_row_ubyte_B5G6R5_UNORM(GLuint n, const GLubyte src[][4], void *dst) -{ - GLushort *d = ((GLushort *) dst); - GLuint i; - for (i = 0; i < n; i++) { - pack_ubyte_B5G6R5_UNORM(src[i], d + i); - } -} - -static void -pack_row_float_B5G6R5_UNORM(GLuint n, const GLfloat src[][4], void *dst) -{ - GLushort *d = ((GLushort *) dst); - GLuint i; - for (i = 0; i < n; i++) { - GLubyte v[4]; - _mesa_unclamped_float_rgba_to_ubyte(v, src[i]); - pack_ubyte_B5G6R5_UNORM(v, d + i); - } -} - - -/* - * MESA_FORMAT_R5G6B5_UNORM - * Warning: these functions do not match the current Mesa definition - * of MESA_FORMAT_R5G6B5_UNORM. - */ - -static void -pack_ubyte_R5G6B5_UNORM(const GLubyte src[4], void *dst) -{ - GLushort *d = ((GLushort *) dst); - *d = PACK_COLOR_565_REV(src[RCOMP], src[GCOMP], src[BCOMP]); -} - -static void -pack_float_R5G6B5_UNORM(const GLfloat src[4], void *dst) -{ - GLushort *d = ((GLushort *) dst); - GLubyte r, g, b; - UNCLAMPED_FLOAT_TO_UBYTE(r, src[RCOMP]); - UNCLAMPED_FLOAT_TO_UBYTE(g, src[GCOMP]); - UNCLAMPED_FLOAT_TO_UBYTE(b, src[BCOMP]); - *d = PACK_COLOR_565_REV(r, g, b); -} - -static void -pack_row_ubyte_R5G6B5_UNORM(GLuint n, const GLubyte src[][4], void *dst) -{ - GLushort *d = ((GLushort *) dst); - GLuint i; - for (i = 0; i < n; i++) { - pack_ubyte_R5G6B5_UNORM(src[i], d + i); - } -} - -static void -pack_row_float_R5G6B5_UNORM(GLuint n, const GLfloat src[][4], void *dst) -{ - GLushort *d = ((GLushort *) dst); - GLuint i; - for (i = 0; i < n; i++) { - GLubyte v[4]; - _mesa_unclamped_float_rgba_to_ubyte(v, src[i]); - pack_ubyte_R5G6B5_UNORM(v, d + i); - } -} - - -/* - * MESA_FORMAT_B4G4R4A4_UNORM - */ - -static void -pack_ubyte_B4G4R4A4_UNORM(const GLubyte src[4], void *dst) -{ - GLushort *d = ((GLushort *) dst); - *d = PACK_COLOR_4444(src[ACOMP], src[RCOMP], src[GCOMP], src[BCOMP]); -} - -static void -pack_float_B4G4R4A4_UNORM(const GLfloat src[4], void *dst) -{ - GLubyte v[4]; - _mesa_unclamped_float_rgba_to_ubyte(v, src); - pack_ubyte_B4G4R4A4_UNORM(v, dst); -} - -/* use fallback row packing functions */ - - -/* - * MESA_FORMAT_A4R4G4B4_UNORM - */ - -static void -pack_ubyte_A4R4G4B4_UNORM(const GLubyte src[4], void *dst) -{ - GLushort *d = ((GLushort *) dst); - *d = PACK_COLOR_4444(src[BCOMP], src[GCOMP], src[RCOMP], src[ACOMP]); -} - -static void -pack_float_A4R4G4B4_UNORM(const GLfloat src[4], void *dst) -{ - GLubyte v[4]; - _mesa_unclamped_float_rgba_to_ubyte(v, src); - pack_ubyte_A4R4G4B4_UNORM(v, dst); -} - -/* use fallback row packing functions */ - - -/* - * MESA_FORMAT_A1B5G5R5_UNORM - */ - -static void -pack_ubyte_A1B5G5R5_UNORM(const GLubyte src[4], void *dst) -{ - GLushort *d = ((GLushort *) dst); - *d = PACK_COLOR_5551(src[RCOMP], src[GCOMP], src[BCOMP], src[ACOMP]); -} - -static void -pack_float_A1B5G5R5_UNORM(const GLfloat src[4], void *dst) -{ - GLubyte v[4]; - _mesa_unclamped_float_rgba_to_ubyte(v, src); - pack_ubyte_A1B5G5R5_UNORM(v, dst); -} - -/* use fallback row packing functions */ - - -/* - * MESA_FORMAT_B5G5R5A1_UNORM - */ - -static void -pack_ubyte_B5G5R5A1_UNORM(const GLubyte src[4], void *dst) -{ - GLushort *d = ((GLushort *) dst); - *d = PACK_COLOR_1555(src[ACOMP], src[RCOMP], src[GCOMP], src[BCOMP]); -} - -static void -pack_float_B5G5R5A1_UNORM(const GLfloat src[4], void *dst) -{ - GLubyte v[4]; - _mesa_unclamped_float_rgba_to_ubyte(v, src); - pack_ubyte_B5G5R5A1_UNORM(v, dst); -} - - -/* MESA_FORMAT_A1R5G5B5_UNORM - * Warning: these functions do not match the current Mesa definition - * of MESA_FORMAT_A1R5G5B5_UNORM. - */ - -static void -pack_ubyte_A1R5G5B5_UNORM(const GLubyte src[4], void *dst) -{ - GLushort *d = ((GLushort *) dst), tmp; - tmp = PACK_COLOR_1555(src[ACOMP], src[RCOMP], src[GCOMP], src[BCOMP]); - *d = (tmp >> 8) | (tmp << 8); -} - -static void -pack_float_A1R5G5B5_UNORM(const GLfloat src[4], void *dst) -{ - GLubyte v[4]; - _mesa_unclamped_float_rgba_to_ubyte(v, src); - pack_ubyte_A1R5G5B5_UNORM(v, dst); -} - - -/* MESA_FORMAT_L4A4_UNORM */ - -static void -pack_ubyte_L4A4_UNORM(const GLubyte src[4], void *dst) -{ - GLubyte *d = ((GLubyte *) dst); - *d = PACK_COLOR_44(src[ACOMP], src[RCOMP]); -} - -static void -pack_float_L4A4_UNORM(const GLfloat src[4], void *dst) -{ - GLubyte v[4]; - UNCLAMPED_FLOAT_TO_UBYTE(v[0], src[RCOMP]); - UNCLAMPED_FLOAT_TO_UBYTE(v[3], src[ACOMP]); - pack_ubyte_L4A4_UNORM(v, dst); -} - - -/* MESA_FORMAT_L8A8_UNORM */ - -static void -pack_ubyte_L8A8_UNORM(const GLubyte src[4], void *dst) -{ - GLushort *d = ((GLushort *) dst); - *d = PACK_COLOR_88(src[ACOMP], src[RCOMP]); -} - -static void -pack_float_L8A8_UNORM(const GLfloat src[4], void *dst) -{ - GLubyte v[4]; - UNCLAMPED_FLOAT_TO_UBYTE(v[0], src[RCOMP]); - UNCLAMPED_FLOAT_TO_UBYTE(v[3], src[ACOMP]); - pack_ubyte_L8A8_UNORM(v, dst); -} - - -/* MESA_FORMAT_A8L8_UNORM */ - -static void -pack_ubyte_A8L8_UNORM(const GLubyte src[4], void *dst) -{ - GLushort *d = ((GLushort *) dst); - *d = PACK_COLOR_88(src[RCOMP], src[ACOMP]); -} - -static void -pack_float_A8L8_UNORM(const GLfloat src[4], void *dst) -{ - GLubyte v[4]; - UNCLAMPED_FLOAT_TO_UBYTE(v[0], src[RCOMP]); - UNCLAMPED_FLOAT_TO_UBYTE(v[3], src[ACOMP]); - pack_ubyte_A8L8_UNORM(v, dst); -} - - -/* MESA_FORMAT_L16A16_UNORM */ - -static void -pack_ubyte_L16A16_UNORM(const GLubyte src[4], void *dst) -{ - GLuint *d = ((GLuint *) dst); - GLushort l = UBYTE_TO_USHORT(src[RCOMP]); - GLushort a = UBYTE_TO_USHORT(src[ACOMP]); - *d = PACK_COLOR_1616(a, l); -} - -static void -pack_float_L16A16_UNORM(const GLfloat src[4], void *dst) -{ - GLuint *d = ((GLuint *) dst); - GLushort l, a; - UNCLAMPED_FLOAT_TO_USHORT(l, src[RCOMP]); - UNCLAMPED_FLOAT_TO_USHORT(a, src[ACOMP]); - *d = PACK_COLOR_1616(a, l); -} - - -/* MESA_FORMAT_A16L16_UNORM */ - -static void -pack_ubyte_A16L16_UNORM(const GLubyte src[4], void *dst) -{ - GLuint *d = ((GLuint *) dst); - GLushort l = UBYTE_TO_USHORT(src[RCOMP]); - GLushort a = UBYTE_TO_USHORT(src[ACOMP]); - *d = PACK_COLOR_1616(l, a); -} - -static void -pack_float_A16L16_UNORM(const GLfloat src[4], void *dst) -{ - GLuint *d = ((GLuint *) dst); - GLushort l, a; - UNCLAMPED_FLOAT_TO_USHORT(l, src[RCOMP]); - UNCLAMPED_FLOAT_TO_USHORT(a, src[ACOMP]); - *d = PACK_COLOR_1616(l, a); -} - - -/* MESA_FORMAT_B2G3R3_UNORM */ - -static void -pack_ubyte_B2G3R3_UNORM(const GLubyte src[4], void *dst) -{ - GLubyte *d = ((GLubyte *) dst); - *d = PACK_COLOR_332(src[RCOMP], src[GCOMP], src[BCOMP]); -} - -static void -pack_float_B2G3R3_UNORM(const GLfloat src[4], void *dst) -{ - GLubyte v[4]; - UNCLAMPED_FLOAT_TO_UBYTE(v[0], src[RCOMP]); - UNCLAMPED_FLOAT_TO_UBYTE(v[1], src[GCOMP]); - UNCLAMPED_FLOAT_TO_UBYTE(v[2], src[BCOMP]); - pack_ubyte_B2G3R3_UNORM(v, dst); -} - - -/* MESA_FORMAT_A_UNORM8 */ - -static void -pack_ubyte_A_UNORM8(const GLubyte src[4], void *dst) -{ - GLubyte *d = ((GLubyte *) dst); - *d = src[ACOMP]; -} - -static void -pack_float_A_UNORM8(const GLfloat src[4], void *dst) -{ - GLubyte *d = ((GLubyte *) dst); - UNCLAMPED_FLOAT_TO_UBYTE(d[0], src[ACOMP]); -} - - -/* MESA_FORMAT_A_UNORM16 */ - -static void -pack_ubyte_A_UNORM16(const GLubyte src[4], void *dst) -{ - GLushort *d = ((GLushort *) dst); - *d = UBYTE_TO_USHORT(src[ACOMP]); -} - -static void -pack_float_A_UNORM16(const GLfloat src[4], void *dst) -{ - GLushort *d = ((GLushort *) dst); - UNCLAMPED_FLOAT_TO_USHORT(d[0], src[ACOMP]); -} - - -/* MESA_FORMAT_L_UNORM8 */ - -static void -pack_ubyte_L_UNORM8(const GLubyte src[4], void *dst) -{ - GLubyte *d = ((GLubyte *) dst); - *d = src[RCOMP]; -} - -static void -pack_float_L_UNORM8(const GLfloat src[4], void *dst) -{ - GLubyte *d = ((GLubyte *) dst); - UNCLAMPED_FLOAT_TO_UBYTE(d[0], src[RCOMP]); -} - - -/* MESA_FORMAT_L_UNORM16 */ - -static void -pack_ubyte_L_UNORM16(const GLubyte src[4], void *dst) -{ - GLushort *d = ((GLushort *) dst); - *d = UBYTE_TO_USHORT(src[RCOMP]); -} - -static void -pack_float_L_UNORM16(const GLfloat src[4], void *dst) -{ - GLushort *d = ((GLushort *) dst); - UNCLAMPED_FLOAT_TO_USHORT(d[0], src[RCOMP]); -} - - -/* MESA_FORMAT_YCBCR */ - -static void -pack_ubyte_YCBCR(const GLubyte src[4], void *dst) -{ - /* todo */ -} - -static void -pack_float_YCBCR(const GLfloat src[4], void *dst) -{ - /* todo */ -} - - -/* MESA_FORMAT_YCBCR_REV */ - -static void -pack_ubyte_YCBCR_REV(const GLubyte src[4], void *dst) -{ - /* todo */ -} - -static void -pack_float_YCBCR_REV(const GLfloat src[4], void *dst) -{ - /* todo */ -} - - -/* MESA_FORMAT_R_UNORM8 */ - -static void -pack_ubyte_R_UNORM8(const GLubyte src[4], void *dst) -{ - GLubyte *d = ((GLubyte *) dst); - *d = src[RCOMP]; -} - -static void -pack_float_R_UNORM8(const GLfloat src[4], void *dst) -{ - GLubyte *d = ((GLubyte *) dst); - GLubyte r; - UNCLAMPED_FLOAT_TO_UBYTE(r, src[RCOMP]); - d[0] = r; -} - - -/* MESA_FORMAT_R8G8_UNORM */ - -static void -pack_ubyte_R8G8_UNORM(const GLubyte src[4], void *dst) -{ - GLushort *d = ((GLushort *) dst); - *d = PACK_COLOR_88(src[GCOMP], src[RCOMP]); -} - -static void -pack_float_R8G8_UNORM(const GLfloat src[4], void *dst) -{ - GLushort *d = ((GLushort *) dst); - GLubyte r, g; - UNCLAMPED_FLOAT_TO_UBYTE(r, src[RCOMP]); - UNCLAMPED_FLOAT_TO_UBYTE(g, src[GCOMP]); - *d = PACK_COLOR_88(g, r); -} - - -/* MESA_FORMAT_G8R8_UNORM */ - -static void -pack_ubyte_G8R8_UNORM(const GLubyte src[4], void *dst) -{ - GLubyte *d = ((GLubyte *) dst); - *d = PACK_COLOR_88(src[RCOMP], src[GCOMP]); -} - -static void -pack_float_G8R8_UNORM(const GLfloat src[4], void *dst) -{ - GLushort *d = ((GLushort *) dst); - GLubyte r, g; - UNCLAMPED_FLOAT_TO_UBYTE(r, src[RCOMP]); - UNCLAMPED_FLOAT_TO_UBYTE(g, src[GCOMP]); - *d = PACK_COLOR_88(r, g); -} - - -/* MESA_FORMAT_R_UNORM16 */ - -static void -pack_ubyte_R_UNORM16(const GLubyte src[4], void *dst) -{ - GLushort *d = ((GLushort *) dst); - *d = UBYTE_TO_USHORT(src[RCOMP]); -} - -static void -pack_float_R_UNORM16(const GLfloat src[4], void *dst) -{ - GLushort *d = ((GLushort *) dst); - UNCLAMPED_FLOAT_TO_USHORT(d[0], src[RCOMP]); -} - - -/* MESA_FORMAT_R16G16_UNORM */ - -static void -pack_ubyte_R16G16_UNORM(const GLubyte src[4], void *dst) -{ - GLuint *d = ((GLuint *) dst); - GLushort r = UBYTE_TO_USHORT(src[RCOMP]); - GLushort g = UBYTE_TO_USHORT(src[GCOMP]); - *d = PACK_COLOR_1616(g, r); -} - -static void -pack_float_R16G16_UNORM(const GLfloat src[4], void *dst) -{ - GLuint *d = ((GLuint *) dst); - GLushort r, g; - UNCLAMPED_FLOAT_TO_USHORT(r, src[RCOMP]); - UNCLAMPED_FLOAT_TO_USHORT(g, src[GCOMP]); - *d = PACK_COLOR_1616(g, r); -} - - -/* MESA_FORMAT_G16R16_UNORM */ - -static void -pack_ubyte_G16R16_UNORM(const GLubyte src[4], void *dst) -{ - GLuint *d = ((GLuint *) dst); - GLushort r = UBYTE_TO_USHORT(src[RCOMP]); - GLushort g = UBYTE_TO_USHORT(src[GCOMP]); - *d = PACK_COLOR_1616(r, g); -} - - -static void -pack_float_G16R16_UNORM(const GLfloat src[4], void *dst) -{ - GLuint *d = ((GLuint *) dst); - GLushort r, g; - UNCLAMPED_FLOAT_TO_USHORT(r, src[RCOMP]); - UNCLAMPED_FLOAT_TO_USHORT(g, src[GCOMP]); - *d = PACK_COLOR_1616(r, g); -} - - -/* MESA_FORMAT_B10G10R10A2_UNORM */ - -static void -pack_ubyte_B10G10R10A2_UNORM(const GLubyte src[4], void *dst) -{ - GLuint *d = ((GLuint *) dst); - GLushort r = UBYTE_TO_USHORT(src[RCOMP]); - GLushort g = UBYTE_TO_USHORT(src[GCOMP]); - GLushort b = UBYTE_TO_USHORT(src[BCOMP]); - GLushort a = UBYTE_TO_USHORT(src[ACOMP]); - *d = PACK_COLOR_2101010_US(a, r, g, b); -} - -static void -pack_float_B10G10R10A2_UNORM(const GLfloat src[4], void *dst) -{ - GLuint *d = ((GLuint *) dst); - GLushort r, g, b, a; - UNCLAMPED_FLOAT_TO_USHORT(r, src[RCOMP]); - UNCLAMPED_FLOAT_TO_USHORT(g, src[GCOMP]); - UNCLAMPED_FLOAT_TO_USHORT(b, src[BCOMP]); - UNCLAMPED_FLOAT_TO_USHORT(a, src[ACOMP]); - *d = PACK_COLOR_2101010_US(a, r, g, b); -} - - -/* MESA_FORMAT_R10G10B10A2_UINT */ - -static void -pack_ubyte_R10G10B10A2_UINT(const GLubyte src[4], void *dst) -{ - GLuint *d = ((GLuint *) dst); - GLushort r = UBYTE_TO_USHORT(src[RCOMP]); - GLushort g = UBYTE_TO_USHORT(src[GCOMP]); - GLushort b = UBYTE_TO_USHORT(src[BCOMP]); - GLushort a = UBYTE_TO_USHORT(src[ACOMP]); - *d = PACK_COLOR_2101010_US(a, b, g, r); -} - -static void -pack_float_R10G10B10A2_UINT(const GLfloat src[4], void *dst) -{ - GLuint *d = ((GLuint *) dst); - GLushort r, g, b, a; - UNCLAMPED_FLOAT_TO_USHORT(r, src[RCOMP]); - UNCLAMPED_FLOAT_TO_USHORT(g, src[GCOMP]); - UNCLAMPED_FLOAT_TO_USHORT(b, src[BCOMP]); - UNCLAMPED_FLOAT_TO_USHORT(a, src[ACOMP]); - *d = PACK_COLOR_2101010_US(a, b, g, r); -} - - -/* MESA_FORMAT_BGR_SRGB8 */ - -static void -pack_ubyte_BGR_SRGB8(const GLubyte src[4], void *dst) -{ - GLubyte *d = ((GLubyte *) dst); - d[2] = util_format_linear_to_srgb_8unorm(src[RCOMP]); - d[1] = util_format_linear_to_srgb_8unorm(src[GCOMP]); - d[0] = util_format_linear_to_srgb_8unorm(src[BCOMP]); -} - -static void -pack_float_BGR_SRGB8(const GLfloat src[4], void *dst) -{ - GLubyte *d = ((GLubyte *) dst); - d[2] = util_format_linear_float_to_srgb_8unorm(src[RCOMP]); - d[1] = util_format_linear_float_to_srgb_8unorm(src[GCOMP]); - d[0] = util_format_linear_float_to_srgb_8unorm(src[BCOMP]); -} - - -/* MESA_FORMAT_A8B8G8R8_SRGB */ - -static void -pack_ubyte_A8B8G8R8_SRGB(const GLubyte src[4], void *dst) -{ - GLuint *d = ((GLuint *) dst); - GLubyte r = util_format_linear_to_srgb_8unorm(src[RCOMP]); - GLubyte g = util_format_linear_to_srgb_8unorm(src[GCOMP]); - GLubyte b = util_format_linear_to_srgb_8unorm(src[BCOMP]); - *d = PACK_COLOR_8888(r, g, b, src[ACOMP]); -} - -static void -pack_float_A8B8G8R8_SRGB(const GLfloat src[4], void *dst) -{ - GLuint *d = ((GLuint *) dst); - GLubyte r, g, b, a; - r = util_format_linear_float_to_srgb_8unorm(src[RCOMP]); - g = util_format_linear_float_to_srgb_8unorm(src[GCOMP]); - b = util_format_linear_float_to_srgb_8unorm(src[BCOMP]); - UNCLAMPED_FLOAT_TO_UBYTE(a, src[ACOMP]); - *d = PACK_COLOR_8888(r, g, b, a); -} - - -/* MESA_FORMAT_B8G8R8A8_SRGB */ - -static void -pack_ubyte_B8G8R8A8_SRGB(const GLubyte src[4], void *dst) -{ - GLuint *d = ((GLuint *) dst); - GLubyte r = util_format_linear_to_srgb_8unorm(src[RCOMP]); - GLubyte g = util_format_linear_to_srgb_8unorm(src[GCOMP]); - GLubyte b = util_format_linear_to_srgb_8unorm(src[BCOMP]); - *d = PACK_COLOR_8888(src[ACOMP], r, g, b); -} - -static void -pack_float_B8G8R8A8_SRGB(const GLfloat src[4], void *dst) -{ - GLuint *d = ((GLuint *) dst); - GLubyte r, g, b, a; - r = util_format_linear_float_to_srgb_8unorm(src[RCOMP]); - g = util_format_linear_float_to_srgb_8unorm(src[GCOMP]); - b = util_format_linear_float_to_srgb_8unorm(src[BCOMP]); - UNCLAMPED_FLOAT_TO_UBYTE(a, src[ACOMP]); - *d = PACK_COLOR_8888(a, r, g, b); -} - - -/* MESA_FORMAT_A8R8G8B8_SRGB */ - -static void -pack_ubyte_A8R8G8B8_SRGB(const GLubyte src[4], void *dst) -{ - GLuint *d = ((GLuint *) dst); - GLubyte r = util_format_linear_to_srgb_8unorm(src[RCOMP]); - GLubyte g = util_format_linear_to_srgb_8unorm(src[GCOMP]); - GLubyte b = util_format_linear_to_srgb_8unorm(src[BCOMP]); - *d = PACK_COLOR_8888(b, g, r, src[ACOMP]); -} - -static void -pack_float_A8R8G8B8_SRGB(const GLfloat src[4], void *dst) -{ - GLuint *d = ((GLuint *) dst); - GLubyte r, g, b, a; - r = util_format_linear_float_to_srgb_8unorm(src[RCOMP]); - g = util_format_linear_float_to_srgb_8unorm(src[GCOMP]); - b = util_format_linear_float_to_srgb_8unorm(src[BCOMP]); - UNCLAMPED_FLOAT_TO_UBYTE(a, src[ACOMP]); - *d = PACK_COLOR_8888(b, g, r, a); -} - - -/* MESA_FORMAT_R8G8B8A8_SRGB */ - -static void -pack_ubyte_R8G8B8A8_SRGB(const GLubyte src[4], void *dst) -{ - GLuint *d = ((GLuint *) dst); - GLubyte r = util_format_linear_to_srgb_8unorm(src[RCOMP]); - GLubyte g = util_format_linear_to_srgb_8unorm(src[GCOMP]); - GLubyte b = util_format_linear_to_srgb_8unorm(src[BCOMP]); - *d = PACK_COLOR_8888(src[ACOMP], b, g, r); -} - -static void -pack_float_R8G8B8A8_SRGB(const GLfloat src[4], void *dst) -{ - GLuint *d = ((GLuint *) dst); - GLubyte r, g, b, a; - r = util_format_linear_float_to_srgb_8unorm(src[RCOMP]); - g = util_format_linear_float_to_srgb_8unorm(src[GCOMP]); - b = util_format_linear_float_to_srgb_8unorm(src[BCOMP]); - UNCLAMPED_FLOAT_TO_UBYTE(a, src[ACOMP]); - *d = PACK_COLOR_8888(a, b, g, r); -} - - -/* MESA_FORMAT_L_SRGB8 */ - -static void -pack_ubyte_L_SRGB8(const GLubyte src[4], void *dst) -{ - GLubyte *d = ((GLubyte *) dst); - *d = util_format_linear_to_srgb_8unorm(src[RCOMP]); -} - -static void -pack_float_L_SRGB8(const GLfloat src[4], void *dst) -{ - GLubyte *d = ((GLubyte *) dst); - GLubyte l = util_format_linear_float_to_srgb_8unorm(src[RCOMP]); - *d = l; -} - - -/* MESA_FORMAT_L8A8_SRGB */ - -static void -pack_ubyte_L8A8_SRGB(const GLubyte src[4], void *dst) -{ - GLushort *d = ((GLushort *) dst); - GLubyte l = util_format_linear_to_srgb_8unorm(src[RCOMP]); - *d = PACK_COLOR_88(src[ACOMP], l); -} - -/* MESA_FORMAT_A8L8_SRGB */ - -static void -pack_ubyte_A8L8_SRGB(const GLubyte src[4], void *dst) -{ - GLushort *d = ((GLushort *) dst); - GLubyte l = util_format_linear_to_srgb_8unorm(src[RCOMP]); - *d = PACK_COLOR_88(l, src[ACOMP]); -} - -static void -pack_float_L8A8_SRGB(const GLfloat src[4], void *dst) -{ - GLushort *d = ((GLushort *) dst); - GLubyte a, l = util_format_linear_float_to_srgb_8unorm(src[RCOMP]); - CLAMPED_FLOAT_TO_UBYTE(a, src[ACOMP]); - *d = PACK_COLOR_88(a, l); -} - -static void -pack_float_A8L8_SRGB(const GLfloat src[4], void *dst) -{ - GLushort *d = ((GLushort *) dst); - GLubyte a, l = util_format_linear_float_to_srgb_8unorm(src[RCOMP]); - CLAMPED_FLOAT_TO_UBYTE(a, src[ACOMP]); - *d = PACK_COLOR_88(l, a); -} - - -/* MESA_FORMAT_RGBA_FLOAT32 */ - -static void -pack_ubyte_RGBA_FLOAT32(const GLubyte src[4], void *dst) -{ - GLfloat *d = ((GLfloat *) dst); - d[0] = UBYTE_TO_FLOAT(src[0]); - d[1] = UBYTE_TO_FLOAT(src[1]); - d[2] = UBYTE_TO_FLOAT(src[2]); - d[3] = UBYTE_TO_FLOAT(src[3]); -} - -static void -pack_float_RGBA_FLOAT32(const GLfloat src[4], void *dst) -{ - GLfloat *d = ((GLfloat *) dst); - d[0] = src[0]; - d[1] = src[1]; - d[2] = src[2]; - d[3] = src[3]; -} - - -/* MESA_FORMAT_RGBA_FLOAT16 */ - -static void -pack_ubyte_RGBA_FLOAT16(const GLubyte src[4], void *dst) -{ - GLhalfARB *d = ((GLhalfARB *) dst); - d[0] = _mesa_float_to_half(UBYTE_TO_FLOAT(src[0])); - d[1] = _mesa_float_to_half(UBYTE_TO_FLOAT(src[1])); - d[2] = _mesa_float_to_half(UBYTE_TO_FLOAT(src[2])); - d[3] = _mesa_float_to_half(UBYTE_TO_FLOAT(src[3])); -} - -static void -pack_float_RGBA_FLOAT16(const GLfloat src[4], void *dst) -{ - GLhalfARB *d = ((GLhalfARB *) dst); - d[0] = _mesa_float_to_half(src[0]); - d[1] = _mesa_float_to_half(src[1]); - d[2] = _mesa_float_to_half(src[2]); - d[3] = _mesa_float_to_half(src[3]); -} - - -/* MESA_FORMAT_RGB_FLOAT32 */ - -static void -pack_ubyte_RGB_FLOAT32(const GLubyte src[4], void *dst) -{ - GLfloat *d = ((GLfloat *) dst); - d[0] = UBYTE_TO_FLOAT(src[0]); - d[1] = UBYTE_TO_FLOAT(src[1]); - d[2] = UBYTE_TO_FLOAT(src[2]); -} - -static void -pack_float_RGB_FLOAT32(const GLfloat src[4], void *dst) -{ - GLfloat *d = ((GLfloat *) dst); - d[0] = src[0]; - d[1] = src[1]; - d[2] = src[2]; -} - - -/* MESA_FORMAT_RGB_FLOAT16 */ - -static void -pack_ubyte_RGB_FLOAT16(const GLubyte src[4], void *dst) -{ - GLhalfARB *d = ((GLhalfARB *) dst); - d[0] = _mesa_float_to_half(UBYTE_TO_FLOAT(src[0])); - d[1] = _mesa_float_to_half(UBYTE_TO_FLOAT(src[1])); - d[2] = _mesa_float_to_half(UBYTE_TO_FLOAT(src[2])); -} - -static void -pack_float_RGB_FLOAT16(const GLfloat src[4], void *dst) -{ - GLhalfARB *d = ((GLhalfARB *) dst); - d[0] = _mesa_float_to_half(src[0]); - d[1] = _mesa_float_to_half(src[1]); - d[2] = _mesa_float_to_half(src[2]); -} - - -/* MESA_FORMAT_A_FLOAT32 */ - -static void -pack_ubyte_A_FLOAT32(const GLubyte src[4], void *dst) -{ - GLfloat *d = ((GLfloat *) dst); - d[0] = UBYTE_TO_FLOAT(src[ACOMP]); -} - -static void -pack_float_A_FLOAT32(const GLfloat src[4], void *dst) -{ - GLfloat *d = ((GLfloat *) dst); - d[0] = src[ACOMP]; -} - - -/* MESA_FORMAT_A_FLOAT16 */ - -static void -pack_ubyte_A_FLOAT16(const GLubyte src[4], void *dst) -{ - GLhalfARB *d = ((GLhalfARB *) dst); - d[0] = _mesa_float_to_half(UBYTE_TO_FLOAT(src[ACOMP])); -} - -static void -pack_float_A_FLOAT16(const GLfloat src[4], void *dst) -{ - GLhalfARB *d = ((GLhalfARB *) dst); - d[0] = _mesa_float_to_half(src[ACOMP]); -} - - -/* MESA_FORMAT_L_FLOAT32 (and I_FLOAT32, R_FLOAT32) */ - -static void -pack_ubyte_L_FLOAT32(const GLubyte src[4], void *dst) -{ - GLfloat *d = ((GLfloat *) dst); - d[0] = UBYTE_TO_FLOAT(src[RCOMP]); -} - -static void -pack_float_L_FLOAT32(const GLfloat src[4], void *dst) -{ - GLfloat *d = ((GLfloat *) dst); - d[0] = src[RCOMP]; -} - - -/* MESA_FORMAT_L_FLOAT16 (and I_FLOAT16, R_FLOAT32) */ - -static void -pack_ubyte_L_FLOAT16(const GLubyte src[4], void *dst) -{ - GLhalfARB *d = ((GLhalfARB *) dst); - d[0] = _mesa_float_to_half(UBYTE_TO_FLOAT(src[RCOMP])); -} - -static void -pack_float_L_FLOAT16(const GLfloat src[4], void *dst) -{ - GLhalfARB *d = ((GLhalfARB *) dst); - d[0] = _mesa_float_to_half(src[RCOMP]); -} - - -/* MESA_FORMAT_LA_FLOAT32 */ - -static void -pack_ubyte_LA_FLOAT32(const GLubyte src[4], void *dst) -{ - GLfloat *d = ((GLfloat *) dst); - d[0] = UBYTE_TO_FLOAT(src[RCOMP]); - d[1] = UBYTE_TO_FLOAT(src[ACOMP]); -} - -static void -pack_float_LA_FLOAT32(const GLfloat src[4], void *dst) -{ - GLfloat *d = ((GLfloat *) dst); - d[0] = src[RCOMP]; - d[1] = src[ACOMP]; -} - - -/* MESA_FORMAT_LA_FLOAT16 */ - -static void -pack_ubyte_LA_FLOAT16(const GLubyte src[4], void *dst) -{ - GLhalfARB *d = ((GLhalfARB *) dst); - d[0] = _mesa_float_to_half(UBYTE_TO_FLOAT(src[RCOMP])); - d[1] = _mesa_float_to_half(UBYTE_TO_FLOAT(src[ACOMP])); -} - -static void -pack_float_LA_FLOAT16(const GLfloat src[4], void *dst) -{ - GLhalfARB *d = ((GLhalfARB *) dst); - d[0] = _mesa_float_to_half(src[RCOMP]); - d[1] = _mesa_float_to_half(src[ACOMP]); -} - - -/* MESA_FORMAT_RG_FLOAT32 */ - -static void -pack_ubyte_RG_FLOAT32(const GLubyte src[4], void *dst) -{ - GLfloat *d = ((GLfloat *) dst); - d[0] = UBYTE_TO_FLOAT(src[RCOMP]); - d[1] = UBYTE_TO_FLOAT(src[GCOMP]); -} - -static void -pack_float_RG_FLOAT32(const GLfloat src[4], void *dst) -{ - GLfloat *d = ((GLfloat *) dst); - d[0] = src[RCOMP]; - d[1] = src[GCOMP]; -} - - -/* MESA_FORMAT_RG_FLOAT16 */ - -static void -pack_ubyte_RG_FLOAT16(const GLubyte src[4], void *dst) -{ - GLhalfARB *d = ((GLhalfARB *) dst); - d[0] = _mesa_float_to_half(UBYTE_TO_FLOAT(src[RCOMP])); - d[1] = _mesa_float_to_half(UBYTE_TO_FLOAT(src[GCOMP])); -} - -static void -pack_float_RG_FLOAT16(const GLfloat src[4], void *dst) -{ - GLhalfARB *d = ((GLhalfARB *) dst); - d[0] = _mesa_float_to_half(src[RCOMP]); - d[1] = _mesa_float_to_half(src[GCOMP]); -} - - -/* MESA_FORMAT_RGBA_UNORM16 */ - -static void -pack_ubyte_RGBA_16(const GLubyte src[4], void *dst) -{ - GLushort *d = ((GLushort *) dst); - d[0] = UBYTE_TO_USHORT(src[RCOMP]); - d[1] = UBYTE_TO_USHORT(src[GCOMP]); - d[2] = UBYTE_TO_USHORT(src[BCOMP]); - d[3] = UBYTE_TO_USHORT(src[ACOMP]); -} - -static void -pack_float_RGBA_16(const GLfloat src[4], void *dst) -{ - GLushort *d = ((GLushort *) dst); - UNCLAMPED_FLOAT_TO_USHORT(d[0], src[RCOMP]); - UNCLAMPED_FLOAT_TO_USHORT(d[1], src[GCOMP]); - UNCLAMPED_FLOAT_TO_USHORT(d[2], src[BCOMP]); - UNCLAMPED_FLOAT_TO_USHORT(d[3], src[ACOMP]); -} - - - -/* - * MESA_FORMAT_R_SNORM8 - */ - -static void -pack_float_R_SNORM8(const GLfloat src[4], void *dst) -{ - GLbyte *d = (GLbyte *) dst; - *d = FLOAT_TO_BYTE(CLAMP(src[RCOMP], -1.0f, 1.0f)); -} - - -/* - * MESA_FORMAT_R8G8_SNORM - */ - -static void -pack_float_R8G8_SNORM(const GLfloat src[4], void *dst) -{ - GLushort *d = (GLushort *) dst; - GLbyte r = FLOAT_TO_BYTE(CLAMP(src[RCOMP], -1.0f, 1.0f)); - GLbyte g = FLOAT_TO_BYTE(CLAMP(src[GCOMP], -1.0f, 1.0f)); - *d = (g << 8) | r; -} - - -/* - * MESA_FORMAT_X8B8G8R8_SNORM - */ - -static void -pack_float_X8B8G8R8_SNORM(const GLfloat src[4], void *dst) -{ - GLuint *d = (GLuint *) dst; - GLbyte r = FLOAT_TO_BYTE(CLAMP(src[RCOMP], -1.0f, 1.0f)); - GLbyte g = FLOAT_TO_BYTE(CLAMP(src[GCOMP], -1.0f, 1.0f)); - GLbyte b = FLOAT_TO_BYTE(CLAMP(src[BCOMP], -1.0f, 1.0f)); - GLbyte a = 127; - *d = PACK_COLOR_8888(r, g, b, a); -} - - -/* - * MESA_FORMAT_A8B8G8R8_SNORM - */ - -static void -pack_float_A8B8G8R8_SNORM(const GLfloat src[4], void *dst) -{ - GLuint *d = (GLuint *) dst; - GLbyte r = FLOAT_TO_BYTE(CLAMP(src[RCOMP], -1.0f, 1.0f)); - GLbyte g = FLOAT_TO_BYTE(CLAMP(src[GCOMP], -1.0f, 1.0f)); - GLbyte b = FLOAT_TO_BYTE(CLAMP(src[BCOMP], -1.0f, 1.0f)); - GLbyte a = FLOAT_TO_BYTE(CLAMP(src[ACOMP], -1.0f, 1.0f)); - *d = PACK_COLOR_8888(r, g, b, a); -} - - -/* - * MESA_FORMAT_R8G8B8A8_SNORM - */ - -static void -pack_float_R8G8B8A8_SNORM(const GLfloat src[4], void *dst) -{ - GLuint *d = (GLuint *) dst; - GLbyte r = FLOAT_TO_BYTE(CLAMP(src[RCOMP], -1.0f, 1.0f)); - GLbyte g = FLOAT_TO_BYTE(CLAMP(src[GCOMP], -1.0f, 1.0f)); - GLbyte b = FLOAT_TO_BYTE(CLAMP(src[BCOMP], -1.0f, 1.0f)); - GLbyte a = FLOAT_TO_BYTE(CLAMP(src[ACOMP], -1.0f, 1.0f)); - *d = PACK_COLOR_8888(a, b, g, r); -} - - -/* - * MESA_FORMAT_R_SNORM16 - */ - -static void -pack_float_R_SNORM16(const GLfloat src[4], void *dst) -{ - GLshort *d = (GLshort *) dst; - *d = FLOAT_TO_SHORT(CLAMP(src[RCOMP], -1.0f, 1.0f)); -} - - -/* - * MESA_FORMAT_R16G16_SNORM - */ - -static void -pack_float_R16G16_SNORM(const GLfloat src[4], void *dst) -{ - GLuint *d = (GLuint *) dst; - GLshort r = FLOAT_TO_SHORT(CLAMP(src[RCOMP], -1.0f, 1.0f)); - GLshort g = FLOAT_TO_SHORT(CLAMP(src[GCOMP], -1.0f, 1.0f)); - *d = (g << 16) | (r & 0xffff); -} - - -/* - * MESA_FORMAT_RGB_SNORM16 - */ - -static void -pack_float_RGB_SNORM16(const GLfloat src[4], void *dst) -{ - GLshort *d = (GLshort *) dst; - d[0] = FLOAT_TO_SHORT(CLAMP(src[RCOMP], -1.0f, 1.0f)); - d[1] = FLOAT_TO_SHORT(CLAMP(src[GCOMP], -1.0f, 1.0f)); - d[2] = FLOAT_TO_SHORT(CLAMP(src[BCOMP], -1.0f, 1.0f)); -} - - -/* - * MESA_FORMAT_RGBA_SNORM16 - */ - -static void -pack_float_RGBA_SNORM16(const GLfloat src[4], void *dst) -{ - GLshort *d = (GLshort *) dst; - d[0] = FLOAT_TO_SHORT(CLAMP(src[RCOMP], -1.0f, 1.0f)); - d[1] = FLOAT_TO_SHORT(CLAMP(src[GCOMP], -1.0f, 1.0f)); - d[2] = FLOAT_TO_SHORT(CLAMP(src[BCOMP], -1.0f, 1.0f)); - d[3] = FLOAT_TO_SHORT(CLAMP(src[ACOMP], -1.0f, 1.0f)); -} - - -/* - * MESA_FORMAT_A_SNORM8 - */ - -static void -pack_float_A_SNORM8(const GLfloat src[4], void *dst) -{ - GLbyte *d = (GLbyte *) dst; - *d = FLOAT_TO_BYTE(CLAMP(src[ACOMP], -1.0f, 1.0f)); -} - - -/* - * MESA_FORMAT_L_SNORM8 - */ - -static void -pack_float_L_SNORM8(const GLfloat src[4], void *dst) -{ - GLbyte *d = (GLbyte *) dst; - *d = FLOAT_TO_BYTE(CLAMP(src[RCOMP], -1.0f, 1.0f)); -} - - -/* - * MESA_FORMAT_L8A8_SNORM - */ - -static void -pack_float_L8A8_SNORM(const GLfloat src[4], void *dst) -{ - GLushort *d = (GLushort *) dst; - GLbyte l = FLOAT_TO_BYTE(CLAMP(src[RCOMP], -1.0f, 1.0f)); - GLbyte a = FLOAT_TO_BYTE(CLAMP(src[ACOMP], -1.0f, 1.0f)); - *d = (a << 8) | l; -} - - -/* - * MESA_FORMAT_A8L8_SNORM - */ - -static void -pack_float_A8L8_SNORM(const GLfloat src[4], void *dst) -{ - GLushort *d = (GLushort *) dst; - GLbyte l = FLOAT_TO_BYTE(CLAMP(src[RCOMP], -1.0f, 1.0f)); - GLbyte a = FLOAT_TO_BYTE(CLAMP(src[ACOMP], -1.0f, 1.0f)); - *d = (l << 8) | a; -} - - -/* - * MESA_FORMAT_A_SNORM16 - */ - -static void -pack_float_A_SNORM16(const GLfloat src[4], void *dst) -{ - GLshort *d = (GLshort *) dst; - *d = FLOAT_TO_SHORT(CLAMP(src[ACOMP], -1.0f, 1.0f)); -} - - -/* - * MESA_FORMAT_L_SNORM16 - */ - -static void -pack_float_L_SNORM16(const GLfloat src[4], void *dst) -{ - GLshort *d = (GLshort *) dst; - *d = FLOAT_TO_SHORT(CLAMP(src[RCOMP], -1.0f, 1.0f)); -} - - -/* - * MESA_FORMAT_LA_SNORM16 - */ - -static void -pack_float_LA_SNORM16(const GLfloat src[4], void *dst) -{ - GLuint *d = (GLuint *) dst; - GLshort l = FLOAT_TO_SHORT(CLAMP(src[RCOMP], -1.0f, 1.0f)); - GLshort a = FLOAT_TO_SHORT(CLAMP(src[ACOMP], -1.0f, 1.0f)); - *d = PACK_COLOR_1616(a, l); -} - - -/* - * MESA_FORMAT_R9G9B9E5_FLOAT; - */ - -static void -pack_float_R9G9B9E5_FLOAT(const GLfloat src[4], void *dst) -{ - GLuint *d = (GLuint *) dst; - *d = float3_to_rgb9e5(src); -} - -static void -pack_ubyte_R9G9B9E5_FLOAT(const GLubyte src[4], void *dst) -{ - GLuint *d = (GLuint *) dst; - GLfloat rgb[3]; - rgb[0] = UBYTE_TO_FLOAT(src[RCOMP]); - rgb[1] = UBYTE_TO_FLOAT(src[GCOMP]); - rgb[2] = UBYTE_TO_FLOAT(src[BCOMP]); - *d = float3_to_rgb9e5(rgb); -} - - - -/* - * MESA_FORMAT_R11G11B10_FLOAT; - */ - -static void -pack_ubyte_R11G11B10_FLOAT(const GLubyte src[4], void *dst) -{ - GLuint *d = (GLuint *) dst; - GLfloat rgb[3]; - rgb[0] = UBYTE_TO_FLOAT(src[RCOMP]); - rgb[1] = UBYTE_TO_FLOAT(src[GCOMP]); - rgb[2] = UBYTE_TO_FLOAT(src[BCOMP]); - *d = float3_to_r11g11b10f(rgb); -} - -static void -pack_float_R11G11B10_FLOAT(const GLfloat src[4], void *dst) -{ - GLuint *d = (GLuint *) dst; - *d = float3_to_r11g11b10f(src); -} - - -/* - * MESA_FORMAT_B4G4R4X4_UNORM - */ - -static void -pack_ubyte_XRGB4444_UNORM(const GLubyte src[4], void *dst) -{ - GLushort *d = ((GLushort *) dst); - *d = PACK_COLOR_4444(255, src[RCOMP], src[GCOMP], src[BCOMP]); -} - -static void -pack_float_XRGB4444_UNORM(const GLfloat src[4], void *dst) -{ - GLubyte v[4]; - _mesa_unclamped_float_rgba_to_ubyte(v, src); - pack_ubyte_XRGB4444_UNORM(v, dst); -} - - -/* - * MESA_FORMAT_B5G5R5X1_UNORM - */ - -static void -pack_ubyte_XRGB1555_UNORM(const GLubyte src[4], void *dst) -{ - GLushort *d = ((GLushort *) dst); - *d = PACK_COLOR_1555(255, src[RCOMP], src[GCOMP], src[BCOMP]); -} - -static void -pack_float_XRGB1555_UNORM(const GLfloat src[4], void *dst) -{ - GLubyte v[4]; - _mesa_unclamped_float_rgba_to_ubyte(v, src); - pack_ubyte_XRGB1555_UNORM(v, dst); -} - - -/* - * MESA_FORMAT_R8G8B8X8_SNORM - */ - -static void -pack_float_XBGR8888_SNORM(const GLfloat src[4], void *dst) -{ - GLuint *d = (GLuint *) dst; - GLbyte r = FLOAT_TO_BYTE(CLAMP(src[RCOMP], -1.0f, 1.0f)); - GLbyte g = FLOAT_TO_BYTE(CLAMP(src[GCOMP], -1.0f, 1.0f)); - GLbyte b = FLOAT_TO_BYTE(CLAMP(src[BCOMP], -1.0f, 1.0f)); - *d = PACK_COLOR_8888(127, b, g, r); -} - - -/* - * MESA_FORMAT_R8G8B8X8_SRGB - */ - -static void -pack_float_R8G8B8X8_SRGB(const GLfloat src[4], void *dst) -{ - GLuint *d = (GLuint *) dst; - GLubyte r = util_format_linear_float_to_srgb_8unorm(src[RCOMP]); - GLubyte g = util_format_linear_float_to_srgb_8unorm(src[GCOMP]); - GLubyte b = util_format_linear_float_to_srgb_8unorm(src[BCOMP]); - *d = PACK_COLOR_8888(255, b, g, r); -} - - -/* - * MESA_FORMAT_X8B8G8R8_SRGB - */ - -static void -pack_float_X8B8G8R8_SRGB(const GLfloat src[4], void *dst) -{ - GLuint *d = (GLuint *) dst; - GLubyte r = util_format_linear_float_to_srgb_8unorm(src[RCOMP]); - GLubyte g = util_format_linear_float_to_srgb_8unorm(src[GCOMP]); - GLubyte b = util_format_linear_float_to_srgb_8unorm(src[BCOMP]); - *d = PACK_COLOR_8888(r, g, b, 255); -} - - -/* MESA_FORMAT_B10G10R10X2_UNORM */ - -static void -pack_ubyte_B10G10R10X2_UNORM(const GLubyte src[4], void *dst) -{ - GLuint *d = ((GLuint *) dst); - GLushort r = UBYTE_TO_USHORT(src[RCOMP]); - GLushort g = UBYTE_TO_USHORT(src[GCOMP]); - GLushort b = UBYTE_TO_USHORT(src[BCOMP]); - *d = PACK_COLOR_2101010_US(3, r, g, b); -} - -static void -pack_float_B10G10R10X2_UNORM(const GLfloat src[4], void *dst) -{ - GLuint *d = ((GLuint *) dst); - GLushort r, g, b; - UNCLAMPED_FLOAT_TO_USHORT(r, src[RCOMP]); - UNCLAMPED_FLOAT_TO_USHORT(g, src[GCOMP]); - UNCLAMPED_FLOAT_TO_USHORT(b, src[BCOMP]); - *d = PACK_COLOR_2101010_US(3, r, g, b); -} - - -/* MESA_FORMAT_RGBX_UNORM16 */ - -static void -pack_ubyte_RGBX_UNORM16(const GLubyte src[4], void *dst) -{ - GLushort *d = ((GLushort *) dst); - d[0] = UBYTE_TO_USHORT(src[RCOMP]); - d[1] = UBYTE_TO_USHORT(src[GCOMP]); - d[2] = UBYTE_TO_USHORT(src[BCOMP]); - d[3] = 65535; -} - -static void -pack_float_RGBX_UNORM16(const GLfloat src[4], void *dst) -{ - GLushort *d = ((GLushort *) dst); - UNCLAMPED_FLOAT_TO_USHORT(d[0], src[RCOMP]); - UNCLAMPED_FLOAT_TO_USHORT(d[1], src[GCOMP]); - UNCLAMPED_FLOAT_TO_USHORT(d[2], src[BCOMP]); - d[3] = 65535; -} - - -/* MESA_FORMAT_RGBX_SNORM16 */ - -static void -pack_float_RGBX_SNORM16(const GLfloat src[4], void *dst) -{ - GLushort *d = ((GLushort *) dst); - UNCLAMPED_FLOAT_TO_SHORT(d[0], src[RCOMP]); - UNCLAMPED_FLOAT_TO_SHORT(d[1], src[GCOMP]); - UNCLAMPED_FLOAT_TO_SHORT(d[2], src[BCOMP]); - d[3] = 32767; -} - - -/* MESA_FORMAT_RGBX_FLOAT16 */ - -static void -pack_float_XBGR16161616_FLOAT(const GLfloat src[4], void *dst) -{ - GLushort *d = ((GLushort *) dst); - d[0] = _mesa_float_to_half(src[RCOMP]); - d[1] = _mesa_float_to_half(src[GCOMP]); - d[2] = _mesa_float_to_half(src[BCOMP]); - d[3] = _mesa_float_to_half(1.0); -} - -/* MESA_FORMAT_RGBX_FLOAT32 */ - -static void -pack_float_RGBX_FLOAT32(const GLfloat src[4], void *dst) -{ - GLfloat *d = ((GLfloat *) dst); - d[0] = src[RCOMP]; - d[1] = src[GCOMP]; - d[2] = src[BCOMP]; - d[3] = 1.0; -} - -/* MESA_FORMAT_R10G10B10A2_UNORM */ - -static void -pack_ubyte_R10G10B10A2_UNORM(const GLubyte src[4], void *dst) -{ - GLuint *d = ((GLuint *) dst); - GLushort r = UBYTE_TO_USHORT(src[RCOMP]); - GLushort g = UBYTE_TO_USHORT(src[GCOMP]); - GLushort b = UBYTE_TO_USHORT(src[BCOMP]); - GLushort a = UBYTE_TO_USHORT(src[ACOMP]); - *d = PACK_COLOR_2101010_US(a, b, g, r); -} - -static void -pack_float_R10G10B10A2_UNORM(const GLfloat src[4], void *dst) -{ - GLuint *d = ((GLuint *) dst); - GLushort r, g, b, a; - UNCLAMPED_FLOAT_TO_USHORT(r, src[RCOMP]); - UNCLAMPED_FLOAT_TO_USHORT(g, src[GCOMP]); - UNCLAMPED_FLOAT_TO_USHORT(b, src[BCOMP]); - UNCLAMPED_FLOAT_TO_USHORT(a, src[ACOMP]); - *d = PACK_COLOR_2101010_US(a, b, g, r); -} - -/* - * MESA_FORMAT_G8R8_SNORM - */ - -static void -pack_float_G8R8_SNORM(const GLfloat src[4], void *dst) -{ - GLushort *d = (GLushort *) dst; - GLbyte r = FLOAT_TO_BYTE(CLAMP(src[RCOMP], -1.0f, 1.0f)); - GLbyte g = FLOAT_TO_BYTE(CLAMP(src[GCOMP], -1.0f, 1.0f)); - *d = (r << 8) | (g & 0xff); -} - -/* - * MESA_FORMAT_G16R16_SNORM - */ - -static void -pack_float_G16R16_SNORM(const GLfloat src[4], void *dst) -{ - GLuint *d = (GLuint *) dst; - GLshort r = FLOAT_TO_SHORT(CLAMP(src[RCOMP], -1.0f, 1.0f)); - GLshort g = FLOAT_TO_SHORT(CLAMP(src[GCOMP], -1.0f, 1.0f)); - *d = (r << 16) | (g & 0xffff); -} - -/* - * MESA_FORMAT_B8G8R8X8_SRGB - */ - -static void -pack_float_B8G8R8X8_SRGB(const GLfloat src[4], void *dst) -{ - GLuint *d = (GLuint *) dst; - GLubyte r = util_format_linear_float_to_srgb_8unorm(src[RCOMP]); - GLubyte g = util_format_linear_float_to_srgb_8unorm(src[GCOMP]); - GLubyte b = util_format_linear_float_to_srgb_8unorm(src[BCOMP]); - *d = PACK_COLOR_8888(127, r, g, b); -} - -/* - * MESA_FORMAT_X8R8G8B8_SRGB - */ - -static void -pack_float_X8R8G8B8_SRGB(const GLfloat src[4], void *dst) -{ - GLuint *d = (GLuint *) dst; - GLubyte r = util_format_linear_float_to_srgb_8unorm(src[RCOMP]); - GLubyte g = util_format_linear_float_to_srgb_8unorm(src[GCOMP]); - GLubyte b = util_format_linear_float_to_srgb_8unorm(src[BCOMP]); - *d = PACK_COLOR_8888(b, g, r, 255); -} - -/** - * Return a function that can pack a GLubyte rgba[4] color. - */ -gl_pack_ubyte_rgba_func -_mesa_get_pack_ubyte_rgba_function(mesa_format format) -{ - static gl_pack_ubyte_rgba_func table[MESA_FORMAT_COUNT]; - static GLboolean initialized = GL_FALSE; - - if (!initialized) { - memset(table, 0, sizeof(table)); - - table[MESA_FORMAT_NONE] = NULL; - - table[MESA_FORMAT_A8B8G8R8_UNORM] = pack_ubyte_A8B8G8R8_UNORM; - table[MESA_FORMAT_R8G8B8A8_UNORM] = pack_ubyte_R8G8B8A8_UNORM; - table[MESA_FORMAT_B8G8R8A8_UNORM] = pack_ubyte_B8G8R8A8_UNORM; - table[MESA_FORMAT_A8R8G8B8_UNORM] = pack_ubyte_A8R8G8B8_UNORM; - table[MESA_FORMAT_X8B8G8R8_UNORM] = pack_ubyte_A8B8G8R8_UNORM; /* reused */ - table[MESA_FORMAT_R8G8B8X8_UNORM] = pack_ubyte_R8G8B8A8_UNORM; /* reused */ - table[MESA_FORMAT_B8G8R8X8_UNORM] = pack_ubyte_B8G8R8X8_UNORM; - table[MESA_FORMAT_X8R8G8B8_UNORM] = pack_ubyte_X8R8G8B8_UNORM; - table[MESA_FORMAT_BGR_UNORM8] = pack_ubyte_BGR_UNORM8; - table[MESA_FORMAT_RGB_UNORM8] = pack_ubyte_RGB_UNORM8; - table[MESA_FORMAT_B5G6R5_UNORM] = pack_ubyte_B5G6R5_UNORM; - table[MESA_FORMAT_R5G6B5_UNORM] = pack_ubyte_R5G6B5_UNORM; - table[MESA_FORMAT_B4G4R4A4_UNORM] = pack_ubyte_B4G4R4A4_UNORM; - table[MESA_FORMAT_A4R4G4B4_UNORM] = pack_ubyte_A4R4G4B4_UNORM; - table[MESA_FORMAT_A1B5G5R5_UNORM] = pack_ubyte_A1B5G5R5_UNORM; - table[MESA_FORMAT_B5G5R5A1_UNORM] = pack_ubyte_B5G5R5A1_UNORM; - table[MESA_FORMAT_A1R5G5B5_UNORM] = pack_ubyte_A1R5G5B5_UNORM; - table[MESA_FORMAT_L4A4_UNORM] = pack_ubyte_L4A4_UNORM; - table[MESA_FORMAT_L8A8_UNORM] = pack_ubyte_L8A8_UNORM; - table[MESA_FORMAT_A8L8_UNORM] = pack_ubyte_A8L8_UNORM; - table[MESA_FORMAT_L16A16_UNORM] = pack_ubyte_L16A16_UNORM; - table[MESA_FORMAT_A16L16_UNORM] = pack_ubyte_A16L16_UNORM; - table[MESA_FORMAT_B2G3R3_UNORM] = pack_ubyte_B2G3R3_UNORM; - table[MESA_FORMAT_A_UNORM8] = pack_ubyte_A_UNORM8; - table[MESA_FORMAT_A_UNORM16] = pack_ubyte_A_UNORM16; - table[MESA_FORMAT_L_UNORM8] = pack_ubyte_L_UNORM8; - table[MESA_FORMAT_L_UNORM16] = pack_ubyte_L_UNORM16; - table[MESA_FORMAT_I_UNORM8] = pack_ubyte_L_UNORM8; /* reuse pack_ubyte_L_UNORM8 */ - table[MESA_FORMAT_I_UNORM16] = pack_ubyte_L_UNORM16; /* reuse pack_ubyte_L_UNORM16 */ - table[MESA_FORMAT_YCBCR] = pack_ubyte_YCBCR; - table[MESA_FORMAT_YCBCR_REV] = pack_ubyte_YCBCR_REV; - table[MESA_FORMAT_R_UNORM8] = pack_ubyte_R_UNORM8; - table[MESA_FORMAT_R8G8_UNORM] = pack_ubyte_R8G8_UNORM; - table[MESA_FORMAT_G8R8_UNORM] = pack_ubyte_G8R8_UNORM; - table[MESA_FORMAT_R_UNORM16] = pack_ubyte_R_UNORM16; - table[MESA_FORMAT_R16G16_UNORM] = pack_ubyte_R16G16_UNORM; - table[MESA_FORMAT_G16R16_UNORM] = pack_ubyte_G16R16_UNORM; - table[MESA_FORMAT_B10G10R10A2_UNORM] = pack_ubyte_B10G10R10A2_UNORM; - table[MESA_FORMAT_R10G10B10A2_UINT] = pack_ubyte_R10G10B10A2_UINT; - - /* should never convert RGBA to these formats */ - table[MESA_FORMAT_S8_UINT_Z24_UNORM] = NULL; - table[MESA_FORMAT_Z24_UNORM_S8_UINT] = NULL; - table[MESA_FORMAT_Z_UNORM16] = NULL; - table[MESA_FORMAT_Z24_UNORM_X8_UINT] = NULL; - table[MESA_FORMAT_X8_UINT_Z24_UNORM] = NULL; - table[MESA_FORMAT_Z_UNORM32] = NULL; - table[MESA_FORMAT_S_UINT8] = NULL; - - /* sRGB */ - table[MESA_FORMAT_BGR_SRGB8] = pack_ubyte_BGR_SRGB8; - table[MESA_FORMAT_A8B8G8R8_SRGB] = pack_ubyte_A8B8G8R8_SRGB; - table[MESA_FORMAT_B8G8R8A8_SRGB] = pack_ubyte_B8G8R8A8_SRGB; - table[MESA_FORMAT_A8R8G8B8_SRGB] = pack_ubyte_A8R8G8B8_SRGB; - table[MESA_FORMAT_R8G8B8A8_SRGB] = pack_ubyte_R8G8B8A8_SRGB; - table[MESA_FORMAT_L_SRGB8] = pack_ubyte_L_SRGB8; - table[MESA_FORMAT_L8A8_SRGB] = pack_ubyte_L8A8_SRGB; - table[MESA_FORMAT_A8L8_SRGB] = pack_ubyte_A8L8_SRGB; - /* n/a */ - table[MESA_FORMAT_SRGB_DXT1] = NULL; /* pack_ubyte_SRGB_DXT1; */ - table[MESA_FORMAT_SRGBA_DXT1] = NULL; /* pack_ubyte_SRGBA_DXT1; */ - table[MESA_FORMAT_SRGBA_DXT3] = NULL; /* pack_ubyte_SRGBA_DXT3; */ - table[MESA_FORMAT_SRGBA_DXT5] = NULL; /* pack_ubyte_SRGBA_DXT5; */ - - table[MESA_FORMAT_RGB_FXT1] = NULL; /* pack_ubyte_RGB_FXT1; */ - table[MESA_FORMAT_RGBA_FXT1] = NULL; /* pack_ubyte_RGBA_FXT1; */ - table[MESA_FORMAT_RGB_DXT1] = NULL; /* pack_ubyte_RGB_DXT1; */ - table[MESA_FORMAT_RGBA_DXT1] = NULL; /* pack_ubyte_RGBA_DXT1; */ - table[MESA_FORMAT_RGBA_DXT3] = NULL; /* pack_ubyte_RGBA_DXT3; */ - table[MESA_FORMAT_RGBA_DXT5] = NULL; /* pack_ubyte_RGBA_DXT5; */ - - table[MESA_FORMAT_RGBA_FLOAT32] = pack_ubyte_RGBA_FLOAT32; - table[MESA_FORMAT_RGBA_FLOAT16] = pack_ubyte_RGBA_FLOAT16; - table[MESA_FORMAT_RGB_FLOAT32] = pack_ubyte_RGB_FLOAT32; - table[MESA_FORMAT_RGB_FLOAT16] = pack_ubyte_RGB_FLOAT16; - table[MESA_FORMAT_A_FLOAT32] = pack_ubyte_A_FLOAT32; - table[MESA_FORMAT_A_FLOAT16] = pack_ubyte_A_FLOAT16; - table[MESA_FORMAT_L_FLOAT32] = pack_ubyte_L_FLOAT32; - table[MESA_FORMAT_L_FLOAT16] = pack_ubyte_L_FLOAT16; - table[MESA_FORMAT_LA_FLOAT32] = pack_ubyte_LA_FLOAT32; - table[MESA_FORMAT_LA_FLOAT16] = pack_ubyte_LA_FLOAT16; - table[MESA_FORMAT_I_FLOAT32] = pack_ubyte_L_FLOAT32; - table[MESA_FORMAT_I_FLOAT16] = pack_ubyte_L_FLOAT16; - table[MESA_FORMAT_R_FLOAT32] = pack_ubyte_L_FLOAT32; - table[MESA_FORMAT_R_FLOAT16] = pack_ubyte_L_FLOAT16; - table[MESA_FORMAT_RG_FLOAT32] = pack_ubyte_RG_FLOAT32; - table[MESA_FORMAT_RG_FLOAT16] = pack_ubyte_RG_FLOAT16; - - /* n/a */ - table[MESA_FORMAT_RGBA_SINT8] = NULL; /* pack_ubyte_RGBA_INT8 */ - table[MESA_FORMAT_RGBA_SINT16] = NULL; /* pack_ubyte_RGBA_INT16 */ - table[MESA_FORMAT_RGBA_SINT32] = NULL; /* pack_ubyte_RGBA_INT32 */ - table[MESA_FORMAT_RGBA_UINT8] = NULL; /* pack_ubyte_RGBA_UINT8 */ - table[MESA_FORMAT_RGBA_UINT16] = NULL; /* pack_ubyte_RGBA_UINT16 */ - table[MESA_FORMAT_RGBA_UINT32] = NULL; /* pack_ubyte_RGBA_UINT32 */ - - table[MESA_FORMAT_RGBA_UNORM16] = pack_ubyte_RGBA_16; - - /* n/a */ - table[MESA_FORMAT_R_SNORM8] = NULL; - table[MESA_FORMAT_R8G8_SNORM] = NULL; - table[MESA_FORMAT_X8B8G8R8_SNORM] = NULL; - table[MESA_FORMAT_A8B8G8R8_SNORM] = NULL; - table[MESA_FORMAT_R8G8B8A8_SNORM] = NULL; - table[MESA_FORMAT_R_SNORM16] = NULL; - table[MESA_FORMAT_R16G16_SNORM] = NULL; - table[MESA_FORMAT_RGB_SNORM16] = NULL; - table[MESA_FORMAT_RGBA_SNORM16] = NULL; - table[MESA_FORMAT_A_SNORM8] = NULL; - table[MESA_FORMAT_L_SNORM8] = NULL; - table[MESA_FORMAT_L8A8_SNORM] = NULL; - table[MESA_FORMAT_A8L8_SNORM] = NULL; - table[MESA_FORMAT_I_SNORM8] = NULL; - table[MESA_FORMAT_A_SNORM16] = NULL; - table[MESA_FORMAT_L_SNORM16] = NULL; - table[MESA_FORMAT_LA_SNORM16] = NULL; - table[MESA_FORMAT_I_SNORM16] = NULL; - - - table[MESA_FORMAT_RGBA_UNORM16] = pack_ubyte_RGBA_16; - - table[MESA_FORMAT_R9G9B9E5_FLOAT] = pack_ubyte_R9G9B9E5_FLOAT; - table[MESA_FORMAT_R11G11B10_FLOAT] = pack_ubyte_R11G11B10_FLOAT; - - table[MESA_FORMAT_B4G4R4X4_UNORM] = pack_ubyte_XRGB4444_UNORM; - table[MESA_FORMAT_B5G5R5X1_UNORM] = pack_ubyte_XRGB1555_UNORM; - table[MESA_FORMAT_R8G8B8X8_SNORM] = NULL; - table[MESA_FORMAT_R8G8B8X8_SRGB] = NULL; - table[MESA_FORMAT_X8B8G8R8_SRGB] = NULL; - table[MESA_FORMAT_RGBX_UINT8] = NULL; - table[MESA_FORMAT_RGBX_SINT8] = NULL; - table[MESA_FORMAT_B10G10R10X2_UNORM] = pack_ubyte_B10G10R10X2_UNORM; - table[MESA_FORMAT_RGBX_UNORM16] = pack_ubyte_RGBX_UNORM16; - table[MESA_FORMAT_RGBX_SNORM16] = NULL; - table[MESA_FORMAT_RGBX_FLOAT16] = NULL; - table[MESA_FORMAT_RGBX_UINT16] = NULL; - table[MESA_FORMAT_RGBX_SINT16] = NULL; - table[MESA_FORMAT_RGBX_FLOAT32] = NULL; - table[MESA_FORMAT_RGBX_UINT32] = NULL; - table[MESA_FORMAT_RGBX_SINT32] = NULL; - - table[MESA_FORMAT_R10G10B10A2_UNORM] = pack_ubyte_R10G10B10A2_UNORM; - - table[MESA_FORMAT_B8G8R8X8_SRGB] = NULL; - table[MESA_FORMAT_X8R8G8B8_SRGB] = NULL; - - initialized = GL_TRUE; - } - - return table[format]; -} - - - -/** - * Return a function that can pack a GLfloat rgba[4] color. - */ -gl_pack_float_rgba_func -_mesa_get_pack_float_rgba_function(mesa_format format) -{ - static gl_pack_float_rgba_func table[MESA_FORMAT_COUNT]; - static GLboolean initialized = GL_FALSE; - - if (!initialized) { - memset(table, 0, sizeof(table)); - - table[MESA_FORMAT_NONE] = NULL; - - table[MESA_FORMAT_A8B8G8R8_UNORM] = pack_float_A8B8G8R8_UNORM; - table[MESA_FORMAT_R8G8B8A8_UNORM] = pack_float_R8G8B8A8_UNORM; - table[MESA_FORMAT_B8G8R8A8_UNORM] = pack_float_B8G8R8A8_UNORM; - table[MESA_FORMAT_A8R8G8B8_UNORM] = pack_float_A8R8G8B8_UNORM; - table[MESA_FORMAT_X8B8G8R8_UNORM] = pack_float_A8B8G8R8_UNORM; /* reused */ - table[MESA_FORMAT_R8G8B8X8_UNORM] = pack_float_R8G8B8A8_UNORM; /* reused */ - table[MESA_FORMAT_B8G8R8X8_UNORM] = pack_float_B8G8R8X8_UNORM; - table[MESA_FORMAT_X8R8G8B8_UNORM] = pack_float_X8R8G8B8_UNORM; - table[MESA_FORMAT_BGR_UNORM8] = pack_float_BGR_UNORM8; - table[MESA_FORMAT_RGB_UNORM8] = pack_float_RGB_UNORM8; - table[MESA_FORMAT_B5G6R5_UNORM] = pack_float_B5G6R5_UNORM; - table[MESA_FORMAT_R5G6B5_UNORM] = pack_float_R5G6B5_UNORM; - table[MESA_FORMAT_B4G4R4A4_UNORM] = pack_float_B4G4R4A4_UNORM; - table[MESA_FORMAT_A4R4G4B4_UNORM] = pack_float_A4R4G4B4_UNORM; - table[MESA_FORMAT_A1B5G5R5_UNORM] = pack_float_A1B5G5R5_UNORM; - table[MESA_FORMAT_B5G5R5A1_UNORM] = pack_float_B5G5R5A1_UNORM; - table[MESA_FORMAT_A1R5G5B5_UNORM] = pack_float_A1R5G5B5_UNORM; - - table[MESA_FORMAT_L4A4_UNORM] = pack_float_L4A4_UNORM; - table[MESA_FORMAT_L8A8_UNORM] = pack_float_L8A8_UNORM; - table[MESA_FORMAT_A8L8_UNORM] = pack_float_A8L8_UNORM; - table[MESA_FORMAT_L16A16_UNORM] = pack_float_L16A16_UNORM; - table[MESA_FORMAT_A16L16_UNORM] = pack_float_A16L16_UNORM; - table[MESA_FORMAT_B2G3R3_UNORM] = pack_float_B2G3R3_UNORM; - table[MESA_FORMAT_A_UNORM8] = pack_float_A_UNORM8; - table[MESA_FORMAT_A_UNORM16] = pack_float_A_UNORM16; - table[MESA_FORMAT_L_UNORM8] = pack_float_L_UNORM8; - table[MESA_FORMAT_L_UNORM16] = pack_float_L_UNORM16; - table[MESA_FORMAT_I_UNORM8] = pack_float_L_UNORM8; /* reuse pack_float_L_UNORM8 */ - table[MESA_FORMAT_I_UNORM16] = pack_float_L_UNORM16; /* reuse pack_float_L_UNORM16 */ - table[MESA_FORMAT_YCBCR] = pack_float_YCBCR; - table[MESA_FORMAT_YCBCR_REV] = pack_float_YCBCR_REV; - table[MESA_FORMAT_R_UNORM8] = pack_float_R_UNORM8; - table[MESA_FORMAT_R8G8_UNORM] = pack_float_R8G8_UNORM; - table[MESA_FORMAT_G8R8_UNORM] = pack_float_G8R8_UNORM; - table[MESA_FORMAT_R_UNORM16] = pack_float_R_UNORM16; - table[MESA_FORMAT_R16G16_UNORM] = pack_float_R16G16_UNORM; - table[MESA_FORMAT_G16R16_UNORM] = pack_float_G16R16_UNORM; - table[MESA_FORMAT_B10G10R10A2_UNORM] = pack_float_B10G10R10A2_UNORM; - table[MESA_FORMAT_R10G10B10A2_UINT] = pack_float_R10G10B10A2_UINT; - - /* should never convert RGBA to these formats */ - table[MESA_FORMAT_S8_UINT_Z24_UNORM] = NULL; - table[MESA_FORMAT_Z24_UNORM_S8_UINT] = NULL; - table[MESA_FORMAT_Z_UNORM16] = NULL; - table[MESA_FORMAT_Z24_UNORM_X8_UINT] = NULL; - table[MESA_FORMAT_X8_UINT_Z24_UNORM] = NULL; - table[MESA_FORMAT_Z_UNORM32] = NULL; - table[MESA_FORMAT_S_UINT8] = NULL; - - table[MESA_FORMAT_BGR_SRGB8] = pack_float_BGR_SRGB8; - table[MESA_FORMAT_A8B8G8R8_SRGB] = pack_float_A8B8G8R8_SRGB; - table[MESA_FORMAT_B8G8R8A8_SRGB] = pack_float_B8G8R8A8_SRGB; - table[MESA_FORMAT_A8R8G8B8_SRGB] = pack_float_A8R8G8B8_SRGB; - table[MESA_FORMAT_R8G8B8A8_SRGB] = pack_float_R8G8B8A8_SRGB; - table[MESA_FORMAT_L_SRGB8] = pack_float_L_SRGB8; - table[MESA_FORMAT_L8A8_SRGB] = pack_float_L8A8_SRGB; - table[MESA_FORMAT_A8L8_SRGB] = pack_float_A8L8_SRGB; - - /* n/a */ - table[MESA_FORMAT_SRGB_DXT1] = NULL; - table[MESA_FORMAT_SRGBA_DXT1] = NULL; - table[MESA_FORMAT_SRGBA_DXT3] = NULL; - table[MESA_FORMAT_SRGBA_DXT5] = NULL; - - table[MESA_FORMAT_RGB_FXT1] = NULL; - table[MESA_FORMAT_RGBA_FXT1] = NULL; - table[MESA_FORMAT_RGB_DXT1] = NULL; - table[MESA_FORMAT_RGBA_DXT1] = NULL; - table[MESA_FORMAT_RGBA_DXT3] = NULL; - table[MESA_FORMAT_RGBA_DXT5] = NULL; - - table[MESA_FORMAT_RGBA_FLOAT32] = pack_float_RGBA_FLOAT32; - table[MESA_FORMAT_RGBA_FLOAT16] = pack_float_RGBA_FLOAT16; - table[MESA_FORMAT_RGB_FLOAT32] = pack_float_RGB_FLOAT32; - table[MESA_FORMAT_RGB_FLOAT16] = pack_float_RGB_FLOAT16; - table[MESA_FORMAT_A_FLOAT32] = pack_float_A_FLOAT32; - table[MESA_FORMAT_A_FLOAT16] = pack_float_A_FLOAT16; - table[MESA_FORMAT_L_FLOAT32] = pack_float_L_FLOAT32; - table[MESA_FORMAT_L_FLOAT16] = pack_float_L_FLOAT16; - table[MESA_FORMAT_LA_FLOAT32] = pack_float_LA_FLOAT32; - table[MESA_FORMAT_LA_FLOAT16] = pack_float_LA_FLOAT16; - - table[MESA_FORMAT_I_FLOAT32] = pack_float_L_FLOAT32; - table[MESA_FORMAT_I_FLOAT16] = pack_float_L_FLOAT16; - table[MESA_FORMAT_R_FLOAT32] = pack_float_L_FLOAT32; - table[MESA_FORMAT_R_FLOAT16] = pack_float_L_FLOAT16; - table[MESA_FORMAT_RG_FLOAT32] = pack_float_RG_FLOAT32; - table[MESA_FORMAT_RG_FLOAT16] = pack_float_RG_FLOAT16; - - /* n/a */ - table[MESA_FORMAT_RGBA_SINT8] = NULL; - table[MESA_FORMAT_RGBA_SINT16] = NULL; - table[MESA_FORMAT_RGBA_SINT32] = NULL; - table[MESA_FORMAT_RGBA_UINT8] = NULL; - table[MESA_FORMAT_RGBA_UINT16] = NULL; - table[MESA_FORMAT_RGBA_UINT32] = NULL; - - table[MESA_FORMAT_RGBA_UNORM16] = pack_float_RGBA_16; - - table[MESA_FORMAT_R_SNORM8] = pack_float_R_SNORM8; - table[MESA_FORMAT_R8G8_SNORM] = pack_float_R8G8_SNORM; - table[MESA_FORMAT_X8B8G8R8_SNORM] = pack_float_X8B8G8R8_SNORM; - table[MESA_FORMAT_A8B8G8R8_SNORM] = pack_float_A8B8G8R8_SNORM; - table[MESA_FORMAT_R8G8B8A8_SNORM] = pack_float_R8G8B8A8_SNORM; - table[MESA_FORMAT_R_SNORM16] = pack_float_R_SNORM16; - table[MESA_FORMAT_R16G16_SNORM] = pack_float_R16G16_SNORM; - table[MESA_FORMAT_RGB_SNORM16] = pack_float_RGB_SNORM16; - table[MESA_FORMAT_RGBA_SNORM16] = pack_float_RGBA_SNORM16; - table[MESA_FORMAT_A_SNORM8] = pack_float_A_SNORM8; - table[MESA_FORMAT_L_SNORM8] = pack_float_L_SNORM8; - table[MESA_FORMAT_L8A8_SNORM] = pack_float_L8A8_SNORM; - table[MESA_FORMAT_A8L8_SNORM] = pack_float_A8L8_SNORM; - table[MESA_FORMAT_I_SNORM8] = pack_float_L_SNORM8; /* reused */ - table[MESA_FORMAT_A_SNORM16] = pack_float_A_SNORM16; - table[MESA_FORMAT_L_SNORM16] = pack_float_L_SNORM16; - table[MESA_FORMAT_LA_SNORM16] = pack_float_LA_SNORM16; - table[MESA_FORMAT_I_SNORM16] = pack_float_L_SNORM16; /* reused */ - - table[MESA_FORMAT_R9G9B9E5_FLOAT] = pack_float_R9G9B9E5_FLOAT; - table[MESA_FORMAT_R11G11B10_FLOAT] = pack_float_R11G11B10_FLOAT; - - table[MESA_FORMAT_B4G4R4X4_UNORM] = pack_float_XRGB4444_UNORM; - table[MESA_FORMAT_B5G5R5X1_UNORM] = pack_float_XRGB1555_UNORM; - table[MESA_FORMAT_R8G8B8X8_SNORM] = pack_float_XBGR8888_SNORM; - table[MESA_FORMAT_R8G8B8X8_SRGB] = pack_float_R8G8B8X8_SRGB; - table[MESA_FORMAT_X8B8G8R8_SRGB] = pack_float_X8B8G8R8_SRGB; - table[MESA_FORMAT_RGBX_UINT8] = NULL; - table[MESA_FORMAT_RGBX_SINT8] = NULL; - table[MESA_FORMAT_B10G10R10X2_UNORM] = pack_float_B10G10R10X2_UNORM; - table[MESA_FORMAT_RGBX_UNORM16] = pack_float_RGBX_UNORM16; - table[MESA_FORMAT_RGBX_SNORM16] = pack_float_RGBX_SNORM16; - table[MESA_FORMAT_RGBX_FLOAT16] = pack_float_XBGR16161616_FLOAT; - table[MESA_FORMAT_RGBX_UINT16] = NULL; - table[MESA_FORMAT_RGBX_SINT16] = NULL; - table[MESA_FORMAT_RGBX_FLOAT32] = pack_float_RGBX_FLOAT32; - table[MESA_FORMAT_RGBX_UINT32] = NULL; - table[MESA_FORMAT_RGBX_SINT32] = NULL; - - table[MESA_FORMAT_R10G10B10A2_UNORM] = pack_float_R10G10B10A2_UNORM; - - table[MESA_FORMAT_G8R8_SNORM] = pack_float_G8R8_SNORM; - table[MESA_FORMAT_G16R16_SNORM] = pack_float_G16R16_SNORM; - - table[MESA_FORMAT_B8G8R8X8_SRGB] = pack_float_B8G8R8X8_SRGB; - table[MESA_FORMAT_X8R8G8B8_SRGB] = pack_float_X8R8G8B8_SRGB; - - initialized = GL_TRUE; - } - - return table[format]; -} - - - -static pack_float_rgba_row_func -get_pack_float_rgba_row_function(mesa_format format) -{ - static pack_float_rgba_row_func table[MESA_FORMAT_COUNT]; - static GLboolean initialized = GL_FALSE; - - if (!initialized) { - /* We don't need a special row packing function for each format. - * There's a generic fallback which uses a per-pixel packing function. - */ - memset(table, 0, sizeof(table)); - - table[MESA_FORMAT_A8B8G8R8_UNORM] = pack_row_float_A8B8G8R8_UNORM; - table[MESA_FORMAT_R8G8B8A8_UNORM] = pack_row_float_R8G8B8A8_UNORM; - table[MESA_FORMAT_B8G8R8A8_UNORM] = pack_row_float_B8G8R8A8_UNORM; - table[MESA_FORMAT_A8R8G8B8_UNORM] = pack_row_float_A8R8G8B8_UNORM; - table[MESA_FORMAT_X8B8G8R8_UNORM] = pack_row_float_A8B8G8R8_UNORM; /* reused */ - table[MESA_FORMAT_R8G8B8X8_UNORM] = pack_row_float_R8G8B8A8_UNORM; /* reused */ - table[MESA_FORMAT_B8G8R8X8_UNORM] = pack_row_float_B8G8R8X8_UNORM; - table[MESA_FORMAT_X8R8G8B8_UNORM] = pack_row_float_X8R8G8B8_UNORM; - table[MESA_FORMAT_BGR_UNORM8] = pack_row_float_BGR_UNORM8; - table[MESA_FORMAT_RGB_UNORM8] = pack_row_float_RGB_UNORM8; - table[MESA_FORMAT_B5G6R5_UNORM] = pack_row_float_B5G6R5_UNORM; - table[MESA_FORMAT_R5G6B5_UNORM] = pack_row_float_R5G6B5_UNORM; - - initialized = GL_TRUE; - } - - return table[format]; -} - - - -static pack_ubyte_rgba_row_func -get_pack_ubyte_rgba_row_function(mesa_format format) -{ - static pack_ubyte_rgba_row_func table[MESA_FORMAT_COUNT]; - static GLboolean initialized = GL_FALSE; - - if (!initialized) { - /* We don't need a special row packing function for each format. - * There's a generic fallback which uses a per-pixel packing function. - */ - memset(table, 0, sizeof(table)); - - table[MESA_FORMAT_A8B8G8R8_UNORM] = pack_row_ubyte_A8B8G8R8_UNORM; - table[MESA_FORMAT_R8G8B8A8_UNORM] = pack_row_ubyte_R8G8B8A8_UNORM; - table[MESA_FORMAT_B8G8R8A8_UNORM] = pack_row_ubyte_B8G8R8A8_UNORM; - table[MESA_FORMAT_A8R8G8B8_UNORM] = pack_row_ubyte_A8R8G8B8_UNORM; - table[MESA_FORMAT_X8B8G8R8_UNORM] = pack_row_ubyte_A8B8G8R8_UNORM; /* reused */ - table[MESA_FORMAT_R8G8B8X8_UNORM] = pack_row_ubyte_R8G8B8A8_UNORM; /* reused */ - table[MESA_FORMAT_B8G8R8X8_UNORM] = pack_row_ubyte_B8G8R8X8_UNORM; - table[MESA_FORMAT_X8R8G8B8_UNORM] = pack_row_ubyte_X8R8G8B8_UNORM; - table[MESA_FORMAT_BGR_UNORM8] = pack_row_ubyte_BGR_UNORM8; - table[MESA_FORMAT_RGB_UNORM8] = pack_row_ubyte_RGB_UNORM8; - table[MESA_FORMAT_B5G6R5_UNORM] = pack_row_ubyte_B5G6R5_UNORM; - table[MESA_FORMAT_R5G6B5_UNORM] = pack_row_ubyte_R5G6B5_UNORM; - - initialized = GL_TRUE; - } - - return table[format]; -} - - - -/** - * Pack a row of GLfloat rgba[4] values to the destination. - */ -void -_mesa_pack_float_rgba_row(mesa_format format, GLuint n, - const GLfloat src[][4], void *dst) -{ - pack_float_rgba_row_func packrow = get_pack_float_rgba_row_function(format); - if (packrow) { - /* use "fast" function */ - packrow(n, src, dst); - } - else { - /* slower fallback */ - gl_pack_float_rgba_func pack = _mesa_get_pack_float_rgba_function(format); - GLuint dstStride = _mesa_get_format_bytes(format); - GLubyte *dstPtr = (GLubyte *) dst; - GLuint i; - - assert(pack); - if (!pack) - return; - - for (i = 0; i < n; i++) { - pack(src[i], dstPtr); - dstPtr += dstStride; - } - } -} - - -/** - * Pack a row of GLubyte rgba[4] values to the destination. - */ -void -_mesa_pack_ubyte_rgba_row(mesa_format format, GLuint n, - const GLubyte src[][4], void *dst) -{ - pack_ubyte_rgba_row_func packrow = get_pack_ubyte_rgba_row_function(format); - if (packrow) { - /* use "fast" function */ - packrow(n, src, dst); - } - else { - /* slower fallback */ - gl_pack_ubyte_rgba_func pack = _mesa_get_pack_ubyte_rgba_function(format); - const GLuint stride = _mesa_get_format_bytes(format); - GLubyte *d = ((GLubyte *) dst); - GLuint i; - - assert(pack); - if (!pack) - return; - - for (i = 0; i < n; i++) { - pack(src[i], d); - d += stride; - } - } -} - - -/** - * Pack a 2D image of ubyte RGBA pixels in the given format. - * \param srcRowStride source image row stride in bytes - * \param dstRowStride destination image row stride in bytes - */ -void -_mesa_pack_ubyte_rgba_rect(mesa_format format, GLuint width, GLuint height, - const GLubyte *src, GLint srcRowStride, - void *dst, GLint dstRowStride) -{ - pack_ubyte_rgba_row_func packrow = get_pack_ubyte_rgba_row_function(format); - GLubyte *dstUB = (GLubyte *) dst; - GLuint i; - - if (packrow) { - if (srcRowStride == width * 4 * sizeof(GLubyte) && - dstRowStride == _mesa_format_row_stride(format, width)) { - /* do whole image at once */ - packrow(width * height, (const GLubyte (*)[4]) src, dst); - } - else { - /* row by row */ - for (i = 0; i < height; i++) { - packrow(width, (const GLubyte (*)[4]) src, dstUB); - src += srcRowStride; - dstUB += dstRowStride; - } - } - } - else { - /* slower fallback */ - for (i = 0; i < height; i++) { - _mesa_pack_ubyte_rgba_row(format, width, - (const GLubyte (*)[4]) src, dstUB); - src += srcRowStride; - dstUB += dstRowStride; - } - } -} - - - -/** - ** Pack float Z pixels - **/ - -static void -pack_float_S8_UINT_Z24_UNORM(const GLfloat *src, void *dst) -{ - /* don't disturb the stencil values */ - GLuint *d = ((GLuint *) dst); - const GLdouble scale = (GLdouble) 0xffffff; - GLuint s = *d & 0xff; - GLuint z = (GLuint) (*src * scale); - assert(z <= 0xffffff); - *d = (z << 8) | s; -} - -static void -pack_float_Z24_UNORM_S8_UINT(const GLfloat *src, void *dst) -{ - /* don't disturb the stencil values */ - GLuint *d = ((GLuint *) dst); - const GLdouble scale = (GLdouble) 0xffffff; - GLuint s = *d & 0xff000000; - GLuint z = (GLuint) (*src * scale); - assert(z <= 0xffffff); - *d = s | z; -} - -static void -pack_float_Z_UNORM16(const GLfloat *src, void *dst) -{ - GLushort *d = ((GLushort *) dst); - const GLfloat scale = (GLfloat) 0xffff; - *d = (GLushort) (*src * scale); -} - -static void -pack_float_Z_UNORM32(const GLfloat *src, void *dst) -{ - GLuint *d = ((GLuint *) dst); - const GLdouble scale = (GLdouble) 0xffffffff; - *d = (GLuint) (*src * scale); -} - -static void -pack_float_Z_FLOAT32(const GLfloat *src, void *dst) -{ - GLfloat *d = (GLfloat *) dst; - *d = *src; -} - -gl_pack_float_z_func -_mesa_get_pack_float_z_func(mesa_format format) -{ - switch (format) { - case MESA_FORMAT_S8_UINT_Z24_UNORM: - case MESA_FORMAT_X8_UINT_Z24_UNORM: - return pack_float_S8_UINT_Z24_UNORM; - case MESA_FORMAT_Z24_UNORM_S8_UINT: - case MESA_FORMAT_Z24_UNORM_X8_UINT: - return pack_float_Z24_UNORM_S8_UINT; - case MESA_FORMAT_Z_UNORM16: - return pack_float_Z_UNORM16; - case MESA_FORMAT_Z_UNORM32: - return pack_float_Z_UNORM32; - case MESA_FORMAT_Z_FLOAT32: - case MESA_FORMAT_Z32_FLOAT_S8X24_UINT: - return pack_float_Z_FLOAT32; - default: - _mesa_problem(NULL, - "unexpected format in _mesa_get_pack_float_z_func()"); - return NULL; - } -} - - - -/** - ** Pack uint Z pixels. The incoming src value is always in - ** the range [0, 2^32-1]. - **/ - -static void -pack_uint_S8_UINT_Z24_UNORM(const GLuint *src, void *dst) -{ - /* don't disturb the stencil values */ - GLuint *d = ((GLuint *) dst); - GLuint s = *d & 0xff; - GLuint z = *src & 0xffffff00; - *d = z | s; -} - -static void -pack_uint_Z24_UNORM_S8_UINT(const GLuint *src, void *dst) -{ - /* don't disturb the stencil values */ - GLuint *d = ((GLuint *) dst); - GLuint s = *d & 0xff000000; - GLuint z = *src >> 8; - *d = s | z; -} - -static void -pack_uint_Z_UNORM16(const GLuint *src, void *dst) -{ - GLushort *d = ((GLushort *) dst); - *d = *src >> 16; -} - -static void -pack_uint_Z_UNORM32(const GLuint *src, void *dst) -{ - GLuint *d = ((GLuint *) dst); - *d = *src; -} - -static void -pack_uint_Z_FLOAT32(const GLuint *src, void *dst) -{ - GLuint *d = ((GLuint *) dst); - const GLdouble scale = 1.0 / (GLdouble) 0xffffffff; - *d = (GLuint) (*src * scale); - assert(*d >= 0.0f); - assert(*d <= 1.0f); -} - -static void -pack_uint_Z_FLOAT32_X24S8(const GLuint *src, void *dst) -{ - GLfloat *d = ((GLfloat *) dst); - const GLdouble scale = 1.0 / (GLdouble) 0xffffffff; - *d = (GLfloat) (*src * scale); - assert(*d >= 0.0f); - assert(*d <= 1.0f); -} - -gl_pack_uint_z_func -_mesa_get_pack_uint_z_func(mesa_format format) -{ - switch (format) { - case MESA_FORMAT_S8_UINT_Z24_UNORM: - case MESA_FORMAT_X8_UINT_Z24_UNORM: - return pack_uint_S8_UINT_Z24_UNORM; - case MESA_FORMAT_Z24_UNORM_S8_UINT: - case MESA_FORMAT_Z24_UNORM_X8_UINT: - return pack_uint_Z24_UNORM_S8_UINT; - case MESA_FORMAT_Z_UNORM16: - return pack_uint_Z_UNORM16; - case MESA_FORMAT_Z_UNORM32: - return pack_uint_Z_UNORM32; - case MESA_FORMAT_Z_FLOAT32: - return pack_uint_Z_FLOAT32; - case MESA_FORMAT_Z32_FLOAT_S8X24_UINT: - return pack_uint_Z_FLOAT32_X24S8; - default: - _mesa_problem(NULL, "unexpected format in _mesa_get_pack_uint_z_func()"); - return NULL; - } -} - - -/** - ** Pack ubyte stencil pixels - **/ - -static void -pack_ubyte_stencil_Z24_S8(const GLubyte *src, void *dst) -{ - /* don't disturb the Z values */ - GLuint *d = ((GLuint *) dst); - GLuint s = *src; - GLuint z = *d & 0xffffff00; - *d = z | s; -} - -static void -pack_ubyte_stencil_S8_Z24(const GLubyte *src, void *dst) -{ - /* don't disturb the Z values */ - GLuint *d = ((GLuint *) dst); - GLuint s = *src << 24; - GLuint z = *d & 0xffffff; - *d = s | z; -} - -static void -pack_ubyte_stencil_S8(const GLubyte *src, void *dst) -{ - GLubyte *d = (GLubyte *) dst; - *d = *src; -} - -static void -pack_ubyte_stencil_Z32_FLOAT_X24S8(const GLubyte *src, void *dst) -{ - GLfloat *d = ((GLfloat *) dst); - d[1] = *src; -} - - -gl_pack_ubyte_stencil_func -_mesa_get_pack_ubyte_stencil_func(mesa_format format) -{ - switch (format) { - case MESA_FORMAT_S8_UINT_Z24_UNORM: - return pack_ubyte_stencil_Z24_S8; - case MESA_FORMAT_Z24_UNORM_S8_UINT: - return pack_ubyte_stencil_S8_Z24; - case MESA_FORMAT_S_UINT8: - return pack_ubyte_stencil_S8; - case MESA_FORMAT_Z32_FLOAT_S8X24_UINT: - return pack_ubyte_stencil_Z32_FLOAT_X24S8; - default: - _mesa_problem(NULL, - "unexpected format in _mesa_pack_ubyte_stencil_func()"); - return NULL; - } -} - - - -void -_mesa_pack_float_z_row(mesa_format format, GLuint n, - const GLfloat *src, void *dst) -{ - switch (format) { - case MESA_FORMAT_S8_UINT_Z24_UNORM: - case MESA_FORMAT_X8_UINT_Z24_UNORM: - { - /* don't disturb the stencil values */ - GLuint *d = ((GLuint *) dst); - const GLdouble scale = (GLdouble) 0xffffff; - GLuint i; - for (i = 0; i < n; i++) { - GLuint s = d[i] & 0xff; - GLuint z = (GLuint) (src[i] * scale); - assert(z <= 0xffffff); - d[i] = (z << 8) | s; - } - } - break; - case MESA_FORMAT_Z24_UNORM_S8_UINT: - case MESA_FORMAT_Z24_UNORM_X8_UINT: - { - /* don't disturb the stencil values */ - GLuint *d = ((GLuint *) dst); - const GLdouble scale = (GLdouble) 0xffffff; - GLuint i; - for (i = 0; i < n; i++) { - GLuint s = d[i] & 0xff000000; - GLuint z = (GLuint) (src[i] * scale); - assert(z <= 0xffffff); - d[i] = s | z; - } - } - break; - case MESA_FORMAT_Z_UNORM16: - { - GLushort *d = ((GLushort *) dst); - const GLfloat scale = (GLfloat) 0xffff; - GLuint i; - for (i = 0; i < n; i++) { - d[i] = (GLushort) (src[i] * scale); - } - } - break; - case MESA_FORMAT_Z_UNORM32: - { - GLuint *d = ((GLuint *) dst); - const GLdouble scale = (GLdouble) 0xffffffff; - GLuint i; - for (i = 0; i < n; i++) { - d[i] = (GLuint) (src[i] * scale); - } - } - break; - case MESA_FORMAT_Z_FLOAT32: - memcpy(dst, src, n * sizeof(GLfloat)); - break; - case MESA_FORMAT_Z32_FLOAT_S8X24_UINT: - { - struct z32f_x24s8 *d = (struct z32f_x24s8 *) dst; - GLuint i; - for (i = 0; i < n; i++) { - d[i].z = src[i]; - } - } - break; - default: - _mesa_problem(NULL, "unexpected format in _mesa_pack_float_z_row()"); - } -} - - -/** - * The incoming Z values are always in the range [0, 0xffffffff]. - */ -void -_mesa_pack_uint_z_row(mesa_format format, GLuint n, - const GLuint *src, void *dst) -{ - switch (format) { - case MESA_FORMAT_S8_UINT_Z24_UNORM: - case MESA_FORMAT_X8_UINT_Z24_UNORM: - { - /* don't disturb the stencil values */ - GLuint *d = ((GLuint *) dst); - GLuint i; - for (i = 0; i < n; i++) { - GLuint s = d[i] & 0xff; - GLuint z = src[i] & 0xffffff00; - d[i] = z | s; - } - } - break; - case MESA_FORMAT_Z24_UNORM_S8_UINT: - case MESA_FORMAT_Z24_UNORM_X8_UINT: - { - /* don't disturb the stencil values */ - GLuint *d = ((GLuint *) dst); - GLuint i; - for (i = 0; i < n; i++) { - GLuint s = d[i] & 0xff000000; - GLuint z = src[i] >> 8; - d[i] = s | z; - } - } - break; - case MESA_FORMAT_Z_UNORM16: - { - GLushort *d = ((GLushort *) dst); - GLuint i; - for (i = 0; i < n; i++) { - d[i] = src[i] >> 16; - } - } - break; - case MESA_FORMAT_Z_UNORM32: - memcpy(dst, src, n * sizeof(GLfloat)); - break; - case MESA_FORMAT_Z_FLOAT32: - { - GLuint *d = ((GLuint *) dst); - const GLdouble scale = 1.0 / (GLdouble) 0xffffffff; - GLuint i; - for (i = 0; i < n; i++) { - d[i] = (GLuint) (src[i] * scale); - assert(d[i] >= 0.0f); - assert(d[i] <= 1.0f); - } - } - break; - case MESA_FORMAT_Z32_FLOAT_S8X24_UINT: - { - struct z32f_x24s8 *d = (struct z32f_x24s8 *) dst; - const GLdouble scale = 1.0 / (GLdouble) 0xffffffff; - GLuint i; - for (i = 0; i < n; i++) { - d[i].z = (GLfloat) (src[i] * scale); - assert(d[i].z >= 0.0f); - assert(d[i].z <= 1.0f); - } - } - break; - default: - _mesa_problem(NULL, "unexpected format in _mesa_pack_uint_z_row()"); - } -} - - -void -_mesa_pack_ubyte_stencil_row(mesa_format format, GLuint n, - const GLubyte *src, void *dst) -{ - switch (format) { - case MESA_FORMAT_S8_UINT_Z24_UNORM: - { - /* don't disturb the Z values */ - GLuint *d = ((GLuint *) dst); - GLuint i; - for (i = 0; i < n; i++) { - GLuint s = src[i]; - GLuint z = d[i] & 0xffffff00; - d[i] = z | s; - } - } - break; - case MESA_FORMAT_Z24_UNORM_S8_UINT: - { - /* don't disturb the Z values */ - GLuint *d = ((GLuint *) dst); - GLuint i; - for (i = 0; i < n; i++) { - GLuint s = src[i] << 24; - GLuint z = d[i] & 0xffffff; - d[i] = s | z; - } - } - break; - case MESA_FORMAT_S_UINT8: - memcpy(dst, src, n * sizeof(GLubyte)); - break; - case MESA_FORMAT_Z32_FLOAT_S8X24_UINT: - { - struct z32f_x24s8 *d = (struct z32f_x24s8 *) dst; - GLuint i; - for (i = 0; i < n; i++) { - d[i].x24s8 = src[i]; - } - } - break; - default: - _mesa_problem(NULL, "unexpected format in _mesa_pack_ubyte_stencil_row()"); - } -} - - -/** - * Incoming Z/stencil values are always in uint_24_8 format. - */ -void -_mesa_pack_uint_24_8_depth_stencil_row(mesa_format format, GLuint n, - const GLuint *src, void *dst) -{ - switch (format) { - case MESA_FORMAT_S8_UINT_Z24_UNORM: - memcpy(dst, src, n * sizeof(GLuint)); - break; - case MESA_FORMAT_Z24_UNORM_S8_UINT: - { - GLuint *d = ((GLuint *) dst); - GLuint i; - for (i = 0; i < n; i++) { - GLuint s = src[i] << 24; - GLuint z = src[i] >> 8; - d[i] = s | z; - } - } - break; - case MESA_FORMAT_Z32_FLOAT_S8X24_UINT: - { - const GLdouble scale = 1.0 / (GLdouble) 0xffffff; - struct z32f_x24s8 *d = (struct z32f_x24s8 *) dst; - GLuint i; - for (i = 0; i < n; i++) { - GLfloat z = (GLfloat) ((src[i] >> 8) * scale); - d[i].z = z; - d[i].x24s8 = src[i]; - } - } - break; - default: - _mesa_problem(NULL, "bad format %s in _mesa_pack_ubyte_s_row", - _mesa_get_format_name(format)); - return; - } -} - - - -/** - * Convert a boolean color mask to a packed color where each channel of - * the packed value at dst will be 0 or ~0 depending on the colorMask. - */ -void -_mesa_pack_colormask(mesa_format format, const GLubyte colorMask[4], void *dst) -{ - GLfloat maskColor[4]; - - switch (_mesa_get_format_datatype(format)) { - case GL_UNSIGNED_NORMALIZED: - /* simple: 1.0 will convert to ~0 in the right bit positions */ - maskColor[0] = colorMask[0] ? 1.0f : 0.0f; - maskColor[1] = colorMask[1] ? 1.0f : 0.0f; - maskColor[2] = colorMask[2] ? 1.0f : 0.0f; - maskColor[3] = colorMask[3] ? 1.0f : 0.0f; - _mesa_pack_float_rgba_row(format, 1, - (const GLfloat (*)[4]) maskColor, dst); - break; - case GL_SIGNED_NORMALIZED: - case GL_FLOAT: - /* These formats are harder because it's hard to know the floating - * point values that will convert to ~0 for each color channel's bits. - * This solution just generates a non-zero value for each color channel - * then fixes up the non-zero values to be ~0. - * Note: we'll need to add special case code if we ever have to deal - * with formats with unequal color channel sizes, like R11_G11_B10. - * We issue a warning below for channel sizes other than 8,16,32. - */ - { - GLuint bits = _mesa_get_format_max_bits(format); /* bits per chan */ - GLuint bytes = _mesa_get_format_bytes(format); - GLuint i; - - /* this should put non-zero values into the channels of dst */ - maskColor[0] = colorMask[0] ? -1.0f : 0.0f; - maskColor[1] = colorMask[1] ? -1.0f : 0.0f; - maskColor[2] = colorMask[2] ? -1.0f : 0.0f; - maskColor[3] = colorMask[3] ? -1.0f : 0.0f; - _mesa_pack_float_rgba_row(format, 1, - (const GLfloat (*)[4]) maskColor, dst); - - /* fix-up the dst channels by converting non-zero values to ~0 */ - if (bits == 8) { - GLubyte *d = (GLubyte *) dst; - for (i = 0; i < bytes; i++) { - d[i] = d[i] ? 0xff : 0x0; - } - } - else if (bits == 16) { - GLushort *d = (GLushort *) dst; - for (i = 0; i < bytes / 2; i++) { - d[i] = d[i] ? 0xffff : 0x0; - } - } - else if (bits == 32) { - GLuint *d = (GLuint *) dst; - for (i = 0; i < bytes / 4; i++) { - d[i] = d[i] ? 0xffffffffU : 0x0; - } - } - else { - _mesa_problem(NULL, "unexpected size in _mesa_pack_colormask()"); - return; - } - } - break; - default: - _mesa_problem(NULL, "unexpected format data type in gen_color_mask()"); - return; - } -} diff --git a/mesalib/src/mesa/main/format_pack.h b/mesalib/src/mesa/main/format_pack.h index 2577def41..aa7113e9b 100644 --- a/mesalib/src/mesa/main/format_pack.h +++ b/mesalib/src/mesa/main/format_pack.h @@ -68,7 +68,6 @@ extern gl_pack_ubyte_stencil_func _mesa_get_pack_ubyte_stencil_func(mesa_format format); - extern void _mesa_pack_float_rgba_row(mesa_format format, GLuint n, const GLfloat src[][4], void *dst); @@ -77,6 +76,9 @@ extern void _mesa_pack_ubyte_rgba_row(mesa_format format, GLuint n, const GLubyte src[][4], void *dst); +extern void +_mesa_pack_uint_rgba_row(mesa_format format, GLuint n, + const GLuint src[][4], void *dst); extern void _mesa_pack_ubyte_rgba_rect(mesa_format format, GLuint width, GLuint height, diff --git a/mesalib/src/mesa/main/format_pack.py b/mesalib/src/mesa/main/format_pack.py new file mode 100644 index 000000000..f141da83c --- /dev/null +++ b/mesalib/src/mesa/main/format_pack.py @@ -0,0 +1,1004 @@ +#!/usr/bin/env python + +from mako.template import Template +from sys import argv + +string = """/* + * Mesa 3-D graphics library + * + * Copyright (c) 2011 VMware, Inc. + * Copyright (c) 2014 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 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. + */ + + +/** + * Color, depth, stencil packing functions. + * Used to pack basic color, depth and stencil formats to specific + * hardware formats. + * + * There are both per-pixel and per-row packing functions: + * - The former will be used by swrast to write values to the color, depth, + * stencil buffers when drawing points, lines and masked spans. + * - The later will be used for image-oriented functions like glDrawPixels, + * glAccum, and glTexImage. + */ + +#include + +#include "colormac.h" +#include "format_pack.h" +#include "format_utils.h" +#include "macros.h" +#include "../../gallium/auxiliary/util/u_format_rgb9e5.h" +#include "../../gallium/auxiliary/util/u_format_r11g11b10f.h" +#include "util/format_srgb.h" + +#define UNPACK(SRC, OFFSET, BITS) (((SRC) >> (OFFSET)) & MAX_UINT(BITS)) +#define PACK(SRC, OFFSET, BITS) (((SRC) & MAX_UINT(BITS)) << (OFFSET)) + +<% +import format_parser as parser + +formats = parser.parse(argv[1]) + +rgb_formats = [] +for f in formats: + if f.name == 'MESA_FORMAT_NONE': + continue + if f.colorspace not in ('rgb', 'srgb'): + continue + + rgb_formats.append(f) +%> + +/* ubyte packing functions */ + +%for f in rgb_formats: + %if f.name in ('MESA_FORMAT_R9G9B9E5_FLOAT', 'MESA_FORMAT_R11G11B10_FLOAT'): + <% continue %> + %elif f.is_compressed(): + <% continue %> + %endif + +static inline void +pack_ubyte_${f.short_name()}(const GLubyte src[4], void *dst) +{ + %for (i, c) in enumerate(f.channels): + <% i = f.swizzle.inverse()[i] %> + %if c.type == 'x': + <% continue %> + %endif + + ${c.datatype()} ${c.name} = + %if not f.is_normalized() and f.is_int(): + %if c.type == parser.SIGNED: + _mesa_unsigned_to_signed(src[${i}], ${c.size}); + %else: + _mesa_unsigned_to_unsigned(src[${i}], ${c.size}); + %endif + %elif c.type == parser.UNSIGNED: + %if f.colorspace == 'srgb' and c.name in 'rgb': + <% assert c.size == 8 %> + util_format_linear_to_srgb_8unorm(src[${i}]); + %else: + _mesa_unorm_to_unorm(src[${i}], 8, ${c.size}); + %endif + %elif c.type == parser.SIGNED: + _mesa_unorm_to_snorm(src[${i}], 8, ${c.size}); + %elif c.type == parser.FLOAT: + %if c.size == 32: + _mesa_unorm_to_float(src[${i}], 8); + %elif c.size == 16: + _mesa_unorm_to_half(src[${i}], 8); + %else: + <% assert False %> + %endif + %else: + <% assert False %> + %endif + %endfor + + %if f.layout == parser.ARRAY: + ${f.datatype()} *d = (${f.datatype()} *)dst; + %for (i, c) in enumerate(f.channels): + %if c.type == 'x': + <% continue %> + %endif + d[${i}] = ${c.name}; + %endfor + %elif f.layout == parser.PACKED: + ${f.datatype()} d = 0; + %for (i, c) in enumerate(f.channels): + %if c.type == 'x': + <% continue %> + %endif + d |= PACK(${c.name}, ${c.shift}, ${c.size}); + %endfor + (*(${f.datatype()} *)dst) = d; + %else: + <% assert False %> + %endif +} +%endfor + +static inline void +pack_ubyte_r9g9b9e5_float(const GLubyte src[4], void *dst) +{ + GLuint *d = (GLuint *) dst; + GLfloat rgb[3]; + rgb[0] = _mesa_unorm_to_float(src[RCOMP], 8); + rgb[1] = _mesa_unorm_to_float(src[GCOMP], 8); + rgb[2] = _mesa_unorm_to_float(src[BCOMP], 8); + *d = float3_to_rgb9e5(rgb); +} + +static inline void +pack_ubyte_r11g11b10_float(const GLubyte src[4], void *dst) +{ + GLuint *d = (GLuint *) dst; + GLfloat rgb[3]; + rgb[0] = _mesa_unorm_to_float(src[RCOMP], 8); + rgb[1] = _mesa_unorm_to_float(src[GCOMP], 8); + rgb[2] = _mesa_unorm_to_float(src[BCOMP], 8); + *d = float3_to_r11g11b10f(rgb); +} + +/* uint packing functions */ + +%for f in rgb_formats: + %if not f.is_int(): + <% continue %> + %elif f.is_normalized(): + <% continue %> + %elif f.is_compressed(): + <% continue %> + %endif + +static inline void +pack_uint_${f.short_name()}(const GLuint src[4], void *dst) +{ + %for (i, c) in enumerate(f.channels): + <% i = f.swizzle.inverse()[i] %> + %if c.type == 'x': + <% continue %> + %endif + + ${c.datatype()} ${c.name} = + %if c.type == parser.SIGNED: + _mesa_signed_to_signed(src[${i}], ${c.size}); + %elif c.type == parser.UNSIGNED: + _mesa_unsigned_to_unsigned(src[${i}], ${c.size}); + %else: + assert(!"Invalid type: only integer types are allowed"); + %endif + %endfor + + %if f.layout == parser.ARRAY: + ${f.datatype()} *d = (${f.datatype()} *)dst; + %for (i, c) in enumerate(f.channels): + %if c.type == 'x': + <% continue %> + %endif + d[${i}] = ${c.name}; + %endfor + %elif f.layout == parser.PACKED: + ${f.datatype()} d = 0; + %for (i, c) in enumerate(f.channels): + %if c.type == 'x': + <% continue %> + %endif + d |= PACK(${c.name}, ${c.shift}, ${c.size}); + %endfor + (*(${f.datatype()} *)dst) = d; + %else: + <% assert False %> + %endif +} +%endfor + +/* float packing functions */ + +%for f in rgb_formats: + %if f.name in ('MESA_FORMAT_R9G9B9E5_FLOAT', 'MESA_FORMAT_R11G11B10_FLOAT'): + <% continue %> + %elif f.is_int() and not f.is_normalized(): + <% continue %> + %elif f.is_compressed(): + <% continue %> + %endif + +static inline void +pack_float_${f.short_name()}(const GLfloat src[4], void *dst) +{ + %for (i, c) in enumerate(f.channels): + <% i = f.swizzle.inverse()[i] %> + %if c.type == 'x': + <% continue %> + %endif + + ${c.datatype()} ${c.name} = + %if c.type == parser.UNSIGNED: + %if f.colorspace == 'srgb' and c.name in 'rgb': + <% assert c.size == 8 %> + util_format_linear_float_to_srgb_8unorm(src[${i}]); + %else: + _mesa_float_to_unorm(src[${i}], ${c.size}); + %endif + %elif c.type == parser.SIGNED: + _mesa_float_to_snorm(src[${i}], ${c.size}); + %elif c.type == parser.FLOAT: + %if c.size == 32: + src[${i}]; + %elif c.size == 16: + _mesa_float_to_half(src[${i}]); + %else: + <% assert False %> + %endif + %else: + <% assert False %> + %endif + %endfor + + %if f.layout == parser.ARRAY: + ${f.datatype()} *d = (${f.datatype()} *)dst; + %for (i, c) in enumerate(f.channels): + %if c.type == 'x': + <% continue %> + %endif + d[${i}] = ${c.name}; + %endfor + %elif f.layout == parser.PACKED: + ${f.datatype()} d = 0; + %for (i, c) in enumerate(f.channels): + %if c.type == 'x': + <% continue %> + %endif + d |= PACK(${c.name}, ${c.shift}, ${c.size}); + %endfor + (*(${f.datatype()} *)dst) = d; + %else: + <% assert False %> + %endif +} +%endfor + +static inline void +pack_float_r9g9b9e5_float(const GLfloat src[4], void *dst) +{ + GLuint *d = (GLuint *) dst; + *d = float3_to_rgb9e5(src); +} + +static inline void +pack_float_r11g11b10_float(const GLfloat src[4], void *dst) +{ + GLuint *d = (GLuint *) dst; + *d = float3_to_r11g11b10f(src); +} + +/** + * Return a function that can pack a GLubyte rgba[4] color. + */ +gl_pack_ubyte_rgba_func +_mesa_get_pack_ubyte_rgba_function(mesa_format format) +{ + switch (format) { +%for f in rgb_formats: + %if f.is_compressed(): + <% continue %> + %endif + + case ${f.name}: + return pack_ubyte_${f.short_name()}; +%endfor + default: + return NULL; + } +} + +/** + * Return a function that can pack a GLfloat rgba[4] color. + */ +gl_pack_float_rgba_func +_mesa_get_pack_float_rgba_function(mesa_format format) +{ + switch (format) { +%for f in rgb_formats: + %if f.is_compressed(): + <% continue %> + %elif f.is_int() and not f.is_normalized(): + <% continue %> + %endif + + case ${f.name}: + return pack_float_${f.short_name()}; +%endfor + default: + return NULL; + } +} + +/** + * Pack a row of GLubyte rgba[4] values to the destination. + */ +void +_mesa_pack_ubyte_rgba_row(mesa_format format, GLuint n, + const GLubyte src[][4], void *dst) +{ + GLuint i; + GLubyte *d = dst; + + switch (format) { +%for f in rgb_formats: + %if f.is_compressed(): + <% continue %> + %endif + + case ${f.name}: + for (i = 0; i < n; ++i) { + pack_ubyte_${f.short_name()}(src[i], d); + d += ${f.block_size() / 8}; + } + break; +%endfor + default: + assert(!"Invalid format"); + } +} + +/** + * Pack a row of GLuint rgba[4] values to the destination. + */ +void +_mesa_pack_uint_rgba_row(mesa_format format, GLuint n, + const GLuint src[][4], void *dst) +{ + GLuint i; + GLubyte *d = dst; + + switch (format) { +%for f in rgb_formats: + %if not f.is_int(): + <% continue %> + %elif f.is_normalized(): + <% continue %> + %elif f.is_compressed(): + <% continue %> + %endif + + case ${f.name}: + for (i = 0; i < n; ++i) { + pack_uint_${f.short_name()}(src[i], d); + d += ${f.block_size() / 8}; + } + break; +%endfor + default: + assert(!"Invalid format"); + } +} + +/** + * Pack a row of GLfloat rgba[4] values to the destination. + */ +void +_mesa_pack_float_rgba_row(mesa_format format, GLuint n, + const GLfloat src[][4], void *dst) +{ + GLuint i; + GLubyte *d = dst; + + switch (format) { +%for f in rgb_formats: + %if f.is_compressed(): + <% continue %> + %elif f.is_int() and not f.is_normalized(): + <% continue %> + %endif + + case ${f.name}: + for (i = 0; i < n; ++i) { + pack_float_${f.short_name()}(src[i], d); + d += ${f.block_size() / 8}; + } + break; +%endfor + default: + assert(!"Invalid format"); + } +} + +/** + * Pack a 2D image of ubyte RGBA pixels in the given format. + * \param srcRowStride source image row stride in bytes + * \param dstRowStride destination image row stride in bytes + */ +void +_mesa_pack_ubyte_rgba_rect(mesa_format format, GLuint width, GLuint height, + const GLubyte *src, GLint srcRowStride, + void *dst, GLint dstRowStride) +{ + GLubyte *dstUB = dst; + GLuint i; + + if (srcRowStride == width * 4 * sizeof(GLubyte) && + dstRowStride == _mesa_format_row_stride(format, width)) { + /* do whole image at once */ + _mesa_pack_ubyte_rgba_row(format, width * height, + (const GLubyte (*)[4]) src, dst); + } + else { + /* row by row */ + for (i = 0; i < height; i++) { + _mesa_pack_ubyte_rgba_row(format, width, + (const GLubyte (*)[4]) src, dstUB); + src += srcRowStride; + dstUB += dstRowStride; + } + } +} + + +/** Helper struct for MESA_FORMAT_Z32_FLOAT_S8X24_UINT */ +struct z32f_x24s8 +{ + float z; + uint32_t x24s8; +}; + + +/** + ** Pack float Z pixels + **/ + +static void +pack_float_S8_UINT_Z24_UNORM(const GLfloat *src, void *dst) +{ + /* don't disturb the stencil values */ + GLuint *d = ((GLuint *) dst); + const GLdouble scale = (GLdouble) 0xffffff; + GLuint s = *d & 0xff; + GLuint z = (GLuint) (*src * scale); + assert(z <= 0xffffff); + *d = (z << 8) | s; +} + +static void +pack_float_Z24_UNORM_S8_UINT(const GLfloat *src, void *dst) +{ + /* don't disturb the stencil values */ + GLuint *d = ((GLuint *) dst); + const GLdouble scale = (GLdouble) 0xffffff; + GLuint s = *d & 0xff000000; + GLuint z = (GLuint) (*src * scale); + assert(z <= 0xffffff); + *d = s | z; +} + +static void +pack_float_Z_UNORM16(const GLfloat *src, void *dst) +{ + GLushort *d = ((GLushort *) dst); + const GLfloat scale = (GLfloat) 0xffff; + *d = (GLushort) (*src * scale); +} + +static void +pack_float_Z_UNORM32(const GLfloat *src, void *dst) +{ + GLuint *d = ((GLuint *) dst); + const GLdouble scale = (GLdouble) 0xffffffff; + *d = (GLuint) (*src * scale); +} + +static void +pack_float_Z_FLOAT32(const GLfloat *src, void *dst) +{ + GLfloat *d = (GLfloat *) dst; + *d = *src; +} + +gl_pack_float_z_func +_mesa_get_pack_float_z_func(mesa_format format) +{ + switch (format) { + case MESA_FORMAT_S8_UINT_Z24_UNORM: + case MESA_FORMAT_X8_UINT_Z24_UNORM: + return pack_float_S8_UINT_Z24_UNORM; + case MESA_FORMAT_Z24_UNORM_S8_UINT: + case MESA_FORMAT_Z24_UNORM_X8_UINT: + return pack_float_Z24_UNORM_S8_UINT; + case MESA_FORMAT_Z_UNORM16: + return pack_float_Z_UNORM16; + case MESA_FORMAT_Z_UNORM32: + return pack_float_Z_UNORM32; + case MESA_FORMAT_Z_FLOAT32: + case MESA_FORMAT_Z32_FLOAT_S8X24_UINT: + return pack_float_Z_FLOAT32; + default: + _mesa_problem(NULL, + "unexpected format in _mesa_get_pack_float_z_func()"); + return NULL; + } +} + + + +/** + ** Pack uint Z pixels. The incoming src value is always in + ** the range [0, 2^32-1]. + **/ + +static void +pack_uint_S8_UINT_Z24_UNORM(const GLuint *src, void *dst) +{ + /* don't disturb the stencil values */ + GLuint *d = ((GLuint *) dst); + GLuint s = *d & 0xff; + GLuint z = *src & 0xffffff00; + *d = z | s; +} + +static void +pack_uint_Z24_UNORM_S8_UINT(const GLuint *src, void *dst) +{ + /* don't disturb the stencil values */ + GLuint *d = ((GLuint *) dst); + GLuint s = *d & 0xff000000; + GLuint z = *src >> 8; + *d = s | z; +} + +static void +pack_uint_Z_UNORM16(const GLuint *src, void *dst) +{ + GLushort *d = ((GLushort *) dst); + *d = *src >> 16; +} + +static void +pack_uint_Z_UNORM32(const GLuint *src, void *dst) +{ + GLuint *d = ((GLuint *) dst); + *d = *src; +} + +static void +pack_uint_Z_FLOAT32(const GLuint *src, void *dst) +{ + GLuint *d = ((GLuint *) dst); + const GLdouble scale = 1.0 / (GLdouble) 0xffffffff; + *d = (GLuint) (*src * scale); + assert(*d >= 0.0f); + assert(*d <= 1.0f); +} + +static void +pack_uint_Z_FLOAT32_X24S8(const GLuint *src, void *dst) +{ + GLfloat *d = ((GLfloat *) dst); + const GLdouble scale = 1.0 / (GLdouble) 0xffffffff; + *d = (GLfloat) (*src * scale); + assert(*d >= 0.0f); + assert(*d <= 1.0f); +} + +gl_pack_uint_z_func +_mesa_get_pack_uint_z_func(mesa_format format) +{ + switch (format) { + case MESA_FORMAT_S8_UINT_Z24_UNORM: + case MESA_FORMAT_X8_UINT_Z24_UNORM: + return pack_uint_S8_UINT_Z24_UNORM; + case MESA_FORMAT_Z24_UNORM_S8_UINT: + case MESA_FORMAT_Z24_UNORM_X8_UINT: + return pack_uint_Z24_UNORM_S8_UINT; + case MESA_FORMAT_Z_UNORM16: + return pack_uint_Z_UNORM16; + case MESA_FORMAT_Z_UNORM32: + return pack_uint_Z_UNORM32; + case MESA_FORMAT_Z_FLOAT32: + return pack_uint_Z_FLOAT32; + case MESA_FORMAT_Z32_FLOAT_S8X24_UINT: + return pack_uint_Z_FLOAT32_X24S8; + default: + _mesa_problem(NULL, "unexpected format in _mesa_get_pack_uint_z_func()"); + return NULL; + } +} + + +/** + ** Pack ubyte stencil pixels + **/ + +static void +pack_ubyte_stencil_Z24_S8(const GLubyte *src, void *dst) +{ + /* don't disturb the Z values */ + GLuint *d = ((GLuint *) dst); + GLuint s = *src; + GLuint z = *d & 0xffffff00; + *d = z | s; +} + +static void +pack_ubyte_stencil_S8_Z24(const GLubyte *src, void *dst) +{ + /* don't disturb the Z values */ + GLuint *d = ((GLuint *) dst); + GLuint s = *src << 24; + GLuint z = *d & 0xffffff; + *d = s | z; +} + +static void +pack_ubyte_stencil_S8(const GLubyte *src, void *dst) +{ + GLubyte *d = (GLubyte *) dst; + *d = *src; +} + +static void +pack_ubyte_stencil_Z32_FLOAT_X24S8(const GLubyte *src, void *dst) +{ + GLfloat *d = ((GLfloat *) dst); + d[1] = *src; +} + + +gl_pack_ubyte_stencil_func +_mesa_get_pack_ubyte_stencil_func(mesa_format format) +{ + switch (format) { + case MESA_FORMAT_S8_UINT_Z24_UNORM: + return pack_ubyte_stencil_Z24_S8; + case MESA_FORMAT_Z24_UNORM_S8_UINT: + return pack_ubyte_stencil_S8_Z24; + case MESA_FORMAT_S_UINT8: + return pack_ubyte_stencil_S8; + case MESA_FORMAT_Z32_FLOAT_S8X24_UINT: + return pack_ubyte_stencil_Z32_FLOAT_X24S8; + default: + _mesa_problem(NULL, + "unexpected format in _mesa_pack_ubyte_stencil_func()"); + return NULL; + } +} + + + +void +_mesa_pack_float_z_row(mesa_format format, GLuint n, + const GLfloat *src, void *dst) +{ + switch (format) { + case MESA_FORMAT_S8_UINT_Z24_UNORM: + case MESA_FORMAT_X8_UINT_Z24_UNORM: + { + /* don't disturb the stencil values */ + GLuint *d = ((GLuint *) dst); + const GLdouble scale = (GLdouble) 0xffffff; + GLuint i; + for (i = 0; i < n; i++) { + GLuint s = d[i] & 0xff; + GLuint z = (GLuint) (src[i] * scale); + assert(z <= 0xffffff); + d[i] = (z << 8) | s; + } + } + break; + case MESA_FORMAT_Z24_UNORM_S8_UINT: + case MESA_FORMAT_Z24_UNORM_X8_UINT: + { + /* don't disturb the stencil values */ + GLuint *d = ((GLuint *) dst); + const GLdouble scale = (GLdouble) 0xffffff; + GLuint i; + for (i = 0; i < n; i++) { + GLuint s = d[i] & 0xff000000; + GLuint z = (GLuint) (src[i] * scale); + assert(z <= 0xffffff); + d[i] = s | z; + } + } + break; + case MESA_FORMAT_Z_UNORM16: + { + GLushort *d = ((GLushort *) dst); + const GLfloat scale = (GLfloat) 0xffff; + GLuint i; + for (i = 0; i < n; i++) { + d[i] = (GLushort) (src[i] * scale); + } + } + break; + case MESA_FORMAT_Z_UNORM32: + { + GLuint *d = ((GLuint *) dst); + const GLdouble scale = (GLdouble) 0xffffffff; + GLuint i; + for (i = 0; i < n; i++) { + d[i] = (GLuint) (src[i] * scale); + } + } + break; + case MESA_FORMAT_Z_FLOAT32: + memcpy(dst, src, n * sizeof(GLfloat)); + break; + case MESA_FORMAT_Z32_FLOAT_S8X24_UINT: + { + struct z32f_x24s8 *d = (struct z32f_x24s8 *) dst; + GLuint i; + for (i = 0; i < n; i++) { + d[i].z = src[i]; + } + } + break; + default: + _mesa_problem(NULL, "unexpected format in _mesa_pack_float_z_row()"); + } +} + + +/** + * The incoming Z values are always in the range [0, 0xffffffff]. + */ +void +_mesa_pack_uint_z_row(mesa_format format, GLuint n, + const GLuint *src, void *dst) +{ + switch (format) { + case MESA_FORMAT_S8_UINT_Z24_UNORM: + case MESA_FORMAT_X8_UINT_Z24_UNORM: + { + /* don't disturb the stencil values */ + GLuint *d = ((GLuint *) dst); + GLuint i; + for (i = 0; i < n; i++) { + GLuint s = d[i] & 0xff; + GLuint z = src[i] & 0xffffff00; + d[i] = z | s; + } + } + break; + case MESA_FORMAT_Z24_UNORM_S8_UINT: + case MESA_FORMAT_Z24_UNORM_X8_UINT: + { + /* don't disturb the stencil values */ + GLuint *d = ((GLuint *) dst); + GLuint i; + for (i = 0; i < n; i++) { + GLuint s = d[i] & 0xff000000; + GLuint z = src[i] >> 8; + d[i] = s | z; + } + } + break; + case MESA_FORMAT_Z_UNORM16: + { + GLushort *d = ((GLushort *) dst); + GLuint i; + for (i = 0; i < n; i++) { + d[i] = src[i] >> 16; + } + } + break; + case MESA_FORMAT_Z_UNORM32: + memcpy(dst, src, n * sizeof(GLfloat)); + break; + case MESA_FORMAT_Z_FLOAT32: + { + GLuint *d = ((GLuint *) dst); + const GLdouble scale = 1.0 / (GLdouble) 0xffffffff; + GLuint i; + for (i = 0; i < n; i++) { + d[i] = (GLuint) (src[i] * scale); + assert(d[i] >= 0.0f); + assert(d[i] <= 1.0f); + } + } + break; + case MESA_FORMAT_Z32_FLOAT_S8X24_UINT: + { + struct z32f_x24s8 *d = (struct z32f_x24s8 *) dst; + const GLdouble scale = 1.0 / (GLdouble) 0xffffffff; + GLuint i; + for (i = 0; i < n; i++) { + d[i].z = (GLfloat) (src[i] * scale); + assert(d[i].z >= 0.0f); + assert(d[i].z <= 1.0f); + } + } + break; + default: + _mesa_problem(NULL, "unexpected format in _mesa_pack_uint_z_row()"); + } +} + + +void +_mesa_pack_ubyte_stencil_row(mesa_format format, GLuint n, + const GLubyte *src, void *dst) +{ + switch (format) { + case MESA_FORMAT_S8_UINT_Z24_UNORM: + { + /* don't disturb the Z values */ + GLuint *d = ((GLuint *) dst); + GLuint i; + for (i = 0; i < n; i++) { + GLuint s = src[i]; + GLuint z = d[i] & 0xffffff00; + d[i] = z | s; + } + } + break; + case MESA_FORMAT_Z24_UNORM_S8_UINT: + { + /* don't disturb the Z values */ + GLuint *d = ((GLuint *) dst); + GLuint i; + for (i = 0; i < n; i++) { + GLuint s = src[i] << 24; + GLuint z = d[i] & 0xffffff; + d[i] = s | z; + } + } + break; + case MESA_FORMAT_S_UINT8: + memcpy(dst, src, n * sizeof(GLubyte)); + break; + case MESA_FORMAT_Z32_FLOAT_S8X24_UINT: + { + struct z32f_x24s8 *d = (struct z32f_x24s8 *) dst; + GLuint i; + for (i = 0; i < n; i++) { + d[i].x24s8 = src[i]; + } + } + break; + default: + _mesa_problem(NULL, "unexpected format in _mesa_pack_ubyte_stencil_row()"); + } +} + + +/** + * Incoming Z/stencil values are always in uint_24_8 format. + */ +void +_mesa_pack_uint_24_8_depth_stencil_row(mesa_format format, GLuint n, + const GLuint *src, void *dst) +{ + switch (format) { + case MESA_FORMAT_S8_UINT_Z24_UNORM: + memcpy(dst, src, n * sizeof(GLuint)); + break; + case MESA_FORMAT_Z24_UNORM_S8_UINT: + { + GLuint *d = ((GLuint *) dst); + GLuint i; + for (i = 0; i < n; i++) { + GLuint s = src[i] << 24; + GLuint z = src[i] >> 8; + d[i] = s | z; + } + } + break; + case MESA_FORMAT_Z32_FLOAT_S8X24_UINT: + { + const GLdouble scale = 1.0 / (GLdouble) 0xffffff; + struct z32f_x24s8 *d = (struct z32f_x24s8 *) dst; + GLuint i; + for (i = 0; i < n; i++) { + GLfloat z = (GLfloat) ((src[i] >> 8) * scale); + d[i].z = z; + d[i].x24s8 = src[i]; + } + } + break; + default: + _mesa_problem(NULL, "bad format %s in _mesa_pack_ubyte_s_row", + _mesa_get_format_name(format)); + return; + } +} + + + +/** + * Convert a boolean color mask to a packed color where each channel of + * the packed value at dst will be 0 or ~0 depending on the colorMask. + */ +void +_mesa_pack_colormask(mesa_format format, const GLubyte colorMask[4], void *dst) +{ + GLfloat maskColor[4]; + + switch (_mesa_get_format_datatype(format)) { + case GL_UNSIGNED_NORMALIZED: + /* simple: 1.0 will convert to ~0 in the right bit positions */ + maskColor[0] = colorMask[0] ? 1.0f : 0.0f; + maskColor[1] = colorMask[1] ? 1.0f : 0.0f; + maskColor[2] = colorMask[2] ? 1.0f : 0.0f; + maskColor[3] = colorMask[3] ? 1.0f : 0.0f; + _mesa_pack_float_rgba_row(format, 1, + (const GLfloat (*)[4]) maskColor, dst); + break; + case GL_SIGNED_NORMALIZED: + case GL_FLOAT: + /* These formats are harder because it's hard to know the floating + * point values that will convert to ~0 for each color channel's bits. + * This solution just generates a non-zero value for each color channel + * then fixes up the non-zero values to be ~0. + * Note: we'll need to add special case code if we ever have to deal + * with formats with unequal color channel sizes, like R11_G11_B10. + * We issue a warning below for channel sizes other than 8,16,32. + */ + { + GLuint bits = _mesa_get_format_max_bits(format); /* bits per chan */ + GLuint bytes = _mesa_get_format_bytes(format); + GLuint i; + + /* this should put non-zero values into the channels of dst */ + maskColor[0] = colorMask[0] ? -1.0f : 0.0f; + maskColor[1] = colorMask[1] ? -1.0f : 0.0f; + maskColor[2] = colorMask[2] ? -1.0f : 0.0f; + maskColor[3] = colorMask[3] ? -1.0f : 0.0f; + _mesa_pack_float_rgba_row(format, 1, + (const GLfloat (*)[4]) maskColor, dst); + + /* fix-up the dst channels by converting non-zero values to ~0 */ + if (bits == 8) { + GLubyte *d = (GLubyte *) dst; + for (i = 0; i < bytes; i++) { + d[i] = d[i] ? 0xff : 0x0; + } + } + else if (bits == 16) { + GLushort *d = (GLushort *) dst; + for (i = 0; i < bytes / 2; i++) { + d[i] = d[i] ? 0xffff : 0x0; + } + } + else if (bits == 32) { + GLuint *d = (GLuint *) dst; + for (i = 0; i < bytes / 4; i++) { + d[i] = d[i] ? 0xffffffffU : 0x0; + } + } + else { + _mesa_problem(NULL, "unexpected size in _mesa_pack_colormask()"); + return; + } + } + break; + default: + _mesa_problem(NULL, "unexpected format data type in gen_color_mask()"); + return; + } +} +""" + +template = Template(string); + +print template.render(argv = argv[0:]) diff --git a/mesalib/src/mesa/main/format_parser.py b/mesalib/src/mesa/main/format_parser.py index 5e45c74de..11184f78e 100644 --- a/mesalib/src/mesa/main/format_parser.py +++ b/mesalib/src/mesa/main/format_parser.py @@ -24,6 +24,8 @@ # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +import sys + VOID = 'x' UNSIGNED = 'u' SIGNED = 's' @@ -102,6 +104,10 @@ class Channel: """Returns true if the size of this channel is a power of two.""" return is_power_of_two(self.size) + def datatype(self): + """Returns the datatype corresponding to a channel type and size""" + return _get_datatype(self.type, self.size) + class Swizzle: """Describes a swizzle operation. @@ -469,6 +475,49 @@ class Format: return channel return None + def datatype(self): + """Returns the datatype corresponding to a format's channel type and size""" + if self.layout == PACKED: + if self.block_size() == 8: + return 'uint8_t' + if self.block_size() == 16: + return 'uint16_t' + if self.block_size() == 32: + return 'uint32_t' + else: + assert False + else: + return _get_datatype(self.channel_type(), self.channel_size()) + +def _get_datatype(type, size): + if type == FLOAT: + if size == 32: + return 'float' + elif size == 16: + return 'uint16_t' + else: + assert False + elif type == UNSIGNED: + if size <= 8: + return 'uint8_t' + elif size <= 16: + return 'uint16_t' + elif size <= 32: + return 'uint32_t' + else: + assert False + elif type == SIGNED: + if size <= 8: + return 'int8_t' + elif size <= 16: + return 'int16_t' + elif size <= 32: + return 'int32_t' + else: + assert False + else: + assert False + def _parse_channels(fields, layout, colorspace, swizzle): channels = [] for field in fields: @@ -515,7 +564,10 @@ def parse(filename): block_height = int(fields[3]) colorspace = fields[9] - swizzle = Swizzle(fields[8]) + try: + swizzle = Swizzle(fields[8]) + except: + sys.exit("error parsing swizzle for format " + name) channels = _parse_channels(fields[4:8], layout, colorspace, swizzle) yield Format(name, layout, block_width, block_height, channels, swizzle, colorspace) diff --git a/mesalib/src/mesa/main/format_unpack.c b/mesalib/src/mesa/main/format_unpack.c deleted file mode 100644 index d5628a9e7..000000000 --- a/mesalib/src/mesa/main/format_unpack.c +++ /dev/null @@ -1,4400 +0,0 @@ -/* - * Mesa 3-D graphics library - * - * Copyright (c) 2011 VMware, Inc. - * - * 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 - * 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 "colormac.h" -#include "format_unpack.h" -#include "macros.h" -#include "../../gallium/auxiliary/util/u_format_rgb9e5.h" -#include "../../gallium/auxiliary/util/u_format_r11g11b10f.h" -#include "util/format_srgb.h" - - -/** Helper struct for MESA_FORMAT_Z32_FLOAT_S8X24_UINT */ -struct z32f_x24s8 -{ - float z; - uint32_t x24s8; -}; - - -/* Expand 1, 2, 3, 4, 5, 6-bit values to fill 8 bits */ - -#define EXPAND_1_8(X) ( (X) ? 0xff : 0x0 ) - -#define EXPAND_2_8(X) ( ((X) << 6) | ((X) << 4) | ((X) << 2) | (X) ) - -#define EXPAND_3_8(X) ( ((X) << 5) | ((X) << 2) | ((X) >> 1) ) - -#define EXPAND_4_8(X) ( ((X) << 4) | (X) ) - -#define EXPAND_5_8(X) ( ((X) << 3) | ((X) >> 2) ) - -#define EXPAND_6_8(X) ( ((X) << 2) | ((X) >> 4) ) - - -/**********************************************************************/ -/* Unpack, returning GLfloat colors */ -/**********************************************************************/ - -typedef void (*unpack_rgba_func)(const void *src, GLfloat dst[][4], GLuint n); - - -static void -unpack_A8B8G8R8_UNORM(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLuint *s = ((const GLuint *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = UBYTE_TO_FLOAT( (s[i] >> 24) ); - dst[i][GCOMP] = UBYTE_TO_FLOAT( (s[i] >> 16) & 0xff ); - dst[i][BCOMP] = UBYTE_TO_FLOAT( (s[i] >> 8) & 0xff ); - dst[i][ACOMP] = UBYTE_TO_FLOAT( (s[i] ) & 0xff ); - } -} - -static void -unpack_R8G8B8A8_UNORM(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLuint *s = ((const GLuint *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = UBYTE_TO_FLOAT( (s[i] ) & 0xff ); - dst[i][GCOMP] = UBYTE_TO_FLOAT( (s[i] >> 8) & 0xff ); - dst[i][BCOMP] = UBYTE_TO_FLOAT( (s[i] >> 16) & 0xff ); - dst[i][ACOMP] = UBYTE_TO_FLOAT( (s[i] >> 24) ); - } -} - -static void -unpack_B8G8R8A8_UNORM(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLuint *s = ((const GLuint *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = UBYTE_TO_FLOAT( (s[i] >> 16) & 0xff ); - dst[i][GCOMP] = UBYTE_TO_FLOAT( (s[i] >> 8) & 0xff ); - dst[i][BCOMP] = UBYTE_TO_FLOAT( (s[i] ) & 0xff ); - dst[i][ACOMP] = UBYTE_TO_FLOAT( (s[i] >> 24) ); - } -} - -static void -unpack_A8R8G8B8_UNORM(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLuint *s = ((const GLuint *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = UBYTE_TO_FLOAT( (s[i] >> 8) & 0xff ); - dst[i][GCOMP] = UBYTE_TO_FLOAT( (s[i] >> 16) & 0xff ); - dst[i][BCOMP] = UBYTE_TO_FLOAT( (s[i] >> 24) ); - dst[i][ACOMP] = UBYTE_TO_FLOAT( (s[i] ) & 0xff ); - } -} - -static void -unpack_RGBX8888(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLuint *s = ((const GLuint *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = UBYTE_TO_FLOAT( (s[i] >> 24) ); - dst[i][GCOMP] = UBYTE_TO_FLOAT( (s[i] >> 16) & 0xff ); - dst[i][BCOMP] = UBYTE_TO_FLOAT( (s[i] >> 8) & 0xff ); - dst[i][ACOMP] = 1.0f; - } -} - -static void -unpack_RGBX8888_REV(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLuint *s = ((const GLuint *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = UBYTE_TO_FLOAT( (s[i] ) & 0xff ); - dst[i][GCOMP] = UBYTE_TO_FLOAT( (s[i] >> 8) & 0xff ); - dst[i][BCOMP] = UBYTE_TO_FLOAT( (s[i] >> 16) & 0xff ); - dst[i][ACOMP] = 1.0f; - } -} - -static void -unpack_B8G8R8X8_UNORM(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLuint *s = ((const GLuint *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = UBYTE_TO_FLOAT( (s[i] >> 16) & 0xff ); - dst[i][GCOMP] = UBYTE_TO_FLOAT( (s[i] >> 8) & 0xff ); - dst[i][BCOMP] = UBYTE_TO_FLOAT( (s[i] ) & 0xff ); - dst[i][ACOMP] = 1.0f; - } -} - -static void -unpack_X8R8G8B8_UNORM(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLuint *s = ((const GLuint *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = UBYTE_TO_FLOAT( (s[i] >> 8) & 0xff ); - dst[i][GCOMP] = UBYTE_TO_FLOAT( (s[i] >> 16) & 0xff ); - dst[i][BCOMP] = UBYTE_TO_FLOAT( (s[i] >> 24) ); - dst[i][ACOMP] = 1.0f; - } -} - -static void -unpack_BGR_UNORM8(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLubyte *s = (const GLubyte *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = UBYTE_TO_FLOAT( s[i*3+2] ); - dst[i][GCOMP] = UBYTE_TO_FLOAT( s[i*3+1] ); - dst[i][BCOMP] = UBYTE_TO_FLOAT( s[i*3+0] ); - dst[i][ACOMP] = 1.0F; - } -} - -static void -unpack_RGB_UNORM8(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLubyte *s = (const GLubyte *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = UBYTE_TO_FLOAT( s[i*3+0] ); - dst[i][GCOMP] = UBYTE_TO_FLOAT( s[i*3+1] ); - dst[i][BCOMP] = UBYTE_TO_FLOAT( s[i*3+2] ); - dst[i][ACOMP] = 1.0F; - } -} - -static void -unpack_B5G6R5_UNORM(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLushort *s = ((const GLushort *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = ((s[i] >> 11) & 0x1f) * (1.0F / 31.0F); - dst[i][GCOMP] = ((s[i] >> 5 ) & 0x3f) * (1.0F / 63.0F); - dst[i][BCOMP] = ((s[i] ) & 0x1f) * (1.0F / 31.0F); - dst[i][ACOMP] = 1.0F; - } -} - -static void -unpack_R5G6B5_UNORM(const void *src, GLfloat dst[][4], GLuint n) -{ - /* Warning: this function does not match the current Mesa definition - * of MESA_FORMAT_R5G6B5_UNORM. - */ - const GLushort *s = ((const GLushort *) src); - GLuint i; - for (i = 0; i < n; i++) { - GLuint t = (s[i] >> 8) | (s[i] << 8); /* byte swap */ - dst[i][RCOMP] = UBYTE_TO_FLOAT( ((t >> 8) & 0xf8) | ((t >> 13) & 0x7) ); - dst[i][GCOMP] = UBYTE_TO_FLOAT( ((t >> 3) & 0xfc) | ((t >> 9) & 0x3) ); - dst[i][BCOMP] = UBYTE_TO_FLOAT( ((t << 3) & 0xf8) | ((t >> 2) & 0x7) ); - dst[i][ACOMP] = 1.0F; - } -} - -static void -unpack_B4G4R4A4_UNORM(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLushort *s = ((const GLushort *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = ((s[i] >> 8) & 0xf) * (1.0F / 15.0F); - dst[i][GCOMP] = ((s[i] >> 4) & 0xf) * (1.0F / 15.0F); - dst[i][BCOMP] = ((s[i] ) & 0xf) * (1.0F / 15.0F); - dst[i][ACOMP] = ((s[i] >> 12) & 0xf) * (1.0F / 15.0F); - } -} - -static void -unpack_A4R4G4B4_UNORM(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLushort *s = ((const GLushort *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = ((s[i] >> 4) & 0xf) * (1.0F / 15.0F); - dst[i][GCOMP] = ((s[i] >> 8) & 0xf) * (1.0F / 15.0F); - dst[i][BCOMP] = ((s[i] >> 12) & 0xf) * (1.0F / 15.0F); - dst[i][ACOMP] = ((s[i] ) & 0xf) * (1.0F / 15.0F); - } -} - -static void -unpack_A1B5G5R5_UNORM(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLushort *s = ((const GLushort *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = ((s[i] >> 11) & 0x1f) * (1.0F / 31.0F); - dst[i][GCOMP] = ((s[i] >> 6) & 0x1f) * (1.0F / 31.0F); - dst[i][BCOMP] = ((s[i] >> 1) & 0x1f) * (1.0F / 31.0F); - dst[i][ACOMP] = ((s[i] ) & 0x01) * 1.0F; - } -} - -static void -unpack_B5G5R5A1_UNORM(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLushort *s = ((const GLushort *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = ((s[i] >> 10) & 0x1f) * (1.0F / 31.0F); - dst[i][GCOMP] = ((s[i] >> 5) & 0x1f) * (1.0F / 31.0F); - dst[i][BCOMP] = ((s[i] >> 0) & 0x1f) * (1.0F / 31.0F); - dst[i][ACOMP] = ((s[i] >> 15) & 0x01) * 1.0F; - } -} - -static void -unpack_A1R5G5B5_UNORM(const void *src, GLfloat dst[][4], GLuint n) -{ - /* Warning: this function does not match the current Mesa definition - * of MESA_FORMAT_A1R5G5B5_UNORM. - */ - const GLushort *s = ((const GLushort *) src); - GLuint i; - for (i = 0; i < n; i++) { - GLushort tmp = (s[i] << 8) | (s[i] >> 8); /* byteswap */ - dst[i][RCOMP] = ((tmp >> 10) & 0x1f) * (1.0F / 31.0F); - dst[i][GCOMP] = ((tmp >> 5) & 0x1f) * (1.0F / 31.0F); - dst[i][BCOMP] = ((tmp >> 0) & 0x1f) * (1.0F / 31.0F); - dst[i][ACOMP] = ((tmp >> 15) & 0x01) * 1.0F; - } -} - -static void -unpack_L4A4_UNORM(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLubyte *s = ((const GLubyte *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = - dst[i][GCOMP] = - dst[i][BCOMP] = (s[i] & 0xf) * (1.0F / 15.0F); - dst[i][ACOMP] = ((s[i] >> 4) & 0xf) * (1.0F / 15.0F); - } -} - -static void -unpack_L8A8_UNORM(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLushort *s = ((const GLushort *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = - dst[i][GCOMP] = - dst[i][BCOMP] = UBYTE_TO_FLOAT( s[i] & 0xff ); - dst[i][ACOMP] = UBYTE_TO_FLOAT( s[i] >> 8 ); - } -} - -static void -unpack_A8L8_UNORM(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLushort *s = ((const GLushort *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = - dst[i][GCOMP] = - dst[i][BCOMP] = UBYTE_TO_FLOAT( s[i] >> 8 ); - dst[i][ACOMP] = UBYTE_TO_FLOAT( s[i] & 0xff ); - } -} - -static void -unpack_L16A16_UNORM(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLuint *s = ((const GLuint *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = - dst[i][GCOMP] = - dst[i][BCOMP] = USHORT_TO_FLOAT( s[i] & 0xffff ); - dst[i][ACOMP] = USHORT_TO_FLOAT( s[i] >> 16 ); - } -} - -static void -unpack_A16L16_UNORM(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLuint *s = ((const GLuint *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = - dst[i][GCOMP] = - dst[i][BCOMP] = USHORT_TO_FLOAT( s[i] >> 16 ); - dst[i][ACOMP] = USHORT_TO_FLOAT( s[i] & 0xffff ); - } -} - -static void -unpack_B2G3R3_UNORM(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLubyte *s = ((const GLubyte *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = ((s[i] >> 5) & 0x7) * (1.0F / 7.0F); - dst[i][GCOMP] = ((s[i] >> 2) & 0x7) * (1.0F / 7.0F); - dst[i][BCOMP] = ((s[i] ) & 0x3) * (1.0F / 3.0F); - dst[i][ACOMP] = 1.0F; - } -} - - -static void -unpack_A_UNORM8(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLubyte *s = ((const GLubyte *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = - dst[i][GCOMP] = - dst[i][BCOMP] = 0.0F; - dst[i][ACOMP] = UBYTE_TO_FLOAT(s[i]); - } -} - -static void -unpack_A_UNORM16(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLushort *s = ((const GLushort *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = - dst[i][GCOMP] = - dst[i][BCOMP] = 0.0F; - dst[i][ACOMP] = USHORT_TO_FLOAT(s[i]); - } -} - -static void -unpack_L_UNORM8(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLubyte *s = ((const GLubyte *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = - dst[i][GCOMP] = - dst[i][BCOMP] = UBYTE_TO_FLOAT(s[i]); - dst[i][ACOMP] = 1.0F; - } -} - -static void -unpack_L_UNORM16(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLushort *s = ((const GLushort *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = - dst[i][GCOMP] = - dst[i][BCOMP] = USHORT_TO_FLOAT(s[i]); - dst[i][ACOMP] = 1.0F; - } -} - -static void -unpack_I_UNORM8(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLubyte *s = ((const GLubyte *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = - dst[i][GCOMP] = - dst[i][BCOMP] = - dst[i][ACOMP] = UBYTE_TO_FLOAT(s[i]); - } -} - -static void -unpack_I_UNORM16(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLushort *s = ((const GLushort *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = - dst[i][GCOMP] = - dst[i][BCOMP] = - dst[i][ACOMP] = USHORT_TO_FLOAT(s[i]); - } -} - -static void -unpack_YCBCR(const void *src, GLfloat dst[][4], GLuint n) -{ - GLuint i; - for (i = 0; i < n; i++) { - const GLushort *src0 = ((const GLushort *) src) + i * 2; /* even */ - const GLushort *src1 = src0 + 1; /* odd */ - const GLubyte y0 = (*src0 >> 8) & 0xff; /* luminance */ - const GLubyte cb = *src0 & 0xff; /* chroma U */ - const GLubyte y1 = (*src1 >> 8) & 0xff; /* luminance */ - const GLubyte cr = *src1 & 0xff; /* chroma V */ - const GLubyte y = (i & 1) ? y1 : y0; /* choose even/odd luminance */ - GLfloat r = 1.164F * (y - 16) + 1.596F * (cr - 128); - GLfloat g = 1.164F * (y - 16) - 0.813F * (cr - 128) - 0.391F * (cb - 128); - GLfloat b = 1.164F * (y - 16) + 2.018F * (cb - 128); - r *= (1.0F / 255.0F); - g *= (1.0F / 255.0F); - b *= (1.0F / 255.0F); - dst[i][RCOMP] = CLAMP(r, 0.0F, 1.0F); - dst[i][GCOMP] = CLAMP(g, 0.0F, 1.0F); - dst[i][BCOMP] = CLAMP(b, 0.0F, 1.0F); - dst[i][ACOMP] = 1.0F; - } -} - -static void -unpack_YCBCR_REV(const void *src, GLfloat dst[][4], GLuint n) -{ - GLuint i; - for (i = 0; i < n; i++) { - const GLushort *src0 = ((const GLushort *) src) + i * 2; /* even */ - const GLushort *src1 = src0 + 1; /* odd */ - const GLubyte y0 = *src0 & 0xff; /* luminance */ - const GLubyte cr = (*src0 >> 8) & 0xff; /* chroma V */ - const GLubyte y1 = *src1 & 0xff; /* luminance */ - const GLubyte cb = (*src1 >> 8) & 0xff; /* chroma U */ - const GLubyte y = (i & 1) ? y1 : y0; /* choose even/odd luminance */ - GLfloat r = 1.164F * (y - 16) + 1.596F * (cr - 128); - GLfloat g = 1.164F * (y - 16) - 0.813F * (cr - 128) - 0.391F * (cb - 128); - GLfloat b = 1.164F * (y - 16) + 2.018F * (cb - 128); - r *= (1.0F / 255.0F); - g *= (1.0F / 255.0F); - b *= (1.0F / 255.0F); - dst[i][RCOMP] = CLAMP(r, 0.0F, 1.0F); - dst[i][GCOMP] = CLAMP(g, 0.0F, 1.0F); - dst[i][BCOMP] = CLAMP(b, 0.0F, 1.0F); - dst[i][ACOMP] = 1.0F; - } -} - -static void -unpack_R_UNORM8(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLubyte *s = ((const GLubyte *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][0] = UBYTE_TO_FLOAT(s[i]); - dst[i][1] = - dst[i][2] = 0.0F; - dst[i][3] = 1.0F; - } -} - -static void -unpack_R8G8_UNORM(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLushort *s = ((const GLushort *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = UBYTE_TO_FLOAT( s[i] & 0xff ); - dst[i][GCOMP] = UBYTE_TO_FLOAT( s[i] >> 8 ); - dst[i][BCOMP] = 0.0; - dst[i][ACOMP] = 1.0; - } -} - -static void -unpack_G8R8_UNORM(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLushort *s = ((const GLushort *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = UBYTE_TO_FLOAT( s[i] >> 8 ); - dst[i][GCOMP] = UBYTE_TO_FLOAT( s[i] & 0xff ); - dst[i][BCOMP] = 0.0; - dst[i][ACOMP] = 1.0; - } -} - -static void -unpack_R_UNORM16(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLushort *s = ((const GLushort *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = USHORT_TO_FLOAT(s[i]); - dst[i][GCOMP] = 0.0; - dst[i][BCOMP] = 0.0; - dst[i][ACOMP] = 1.0; - } -} - -static void -unpack_R16G16_UNORM(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLuint *s = ((const GLuint *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = USHORT_TO_FLOAT( s[i] & 0xffff ); - dst[i][GCOMP] = USHORT_TO_FLOAT( s[i] >> 16 ); - dst[i][BCOMP] = 0.0; - dst[i][ACOMP] = 1.0; - } -} - -static void -unpack_G16R16_UNORM(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLuint *s = ((const GLuint *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = USHORT_TO_FLOAT( s[i] >> 16 ); - dst[i][GCOMP] = USHORT_TO_FLOAT( s[i] & 0xffff ); - dst[i][BCOMP] = 0.0; - dst[i][ACOMP] = 1.0; - } -} - -static void -unpack_B10G10R10A2_UNORM(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLuint *s = ((const GLuint *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = ((s[i] >> 20) & 0x3ff) * (1.0F / 1023.0F); - dst[i][GCOMP] = ((s[i] >> 10) & 0x3ff) * (1.0F / 1023.0F); - dst[i][BCOMP] = ((s[i] >> 0) & 0x3ff) * (1.0F / 1023.0F); - dst[i][ACOMP] = ((s[i] >> 30) & 0x03) * (1.0F / 3.0F); - } -} - - -static void -unpack_B10G10R10A2_UINT(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLuint *s = (const GLuint *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = (GLfloat)((s[i] >> 20) & 0x3ff); - dst[i][GCOMP] = (GLfloat)((s[i] >> 10) & 0x3ff); - dst[i][BCOMP] = (GLfloat)((s[i] >> 0) & 0x3ff); - dst[i][ACOMP] = (GLfloat)((s[i] >> 30) & 0x03); - } -} - - -static void -unpack_R10G10B10A2_UINT(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLuint *s = ((const GLuint *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = (GLfloat)((s[i] >> 0) & 0x3ff); - dst[i][GCOMP] = (GLfloat)((s[i] >> 10) & 0x3ff); - dst[i][BCOMP] = (GLfloat)((s[i] >> 20) & 0x3ff); - dst[i][ACOMP] = (GLfloat)((s[i] >> 30) & 0x03); - } -} - - -static void -unpack_S8_UINT_Z24_UNORM(const void *src, GLfloat dst[][4], GLuint n) -{ - /* only return Z, not stencil data */ - const GLuint *s = ((const GLuint *) src); - const GLdouble scale = 1.0 / (GLdouble) 0xffffff; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][0] = - dst[i][1] = - dst[i][2] = (GLfloat) ((s[i] >> 8) * scale); - dst[i][3] = 1.0F; - ASSERT(dst[i][0] >= 0.0F); - ASSERT(dst[i][0] <= 1.0F); - } -} - -static void -unpack_Z24_UNORM_S8_UINT(const void *src, GLfloat dst[][4], GLuint n) -{ - /* only return Z, not stencil data */ - const GLuint *s = ((const GLuint *) src); - const GLdouble scale = 1.0 / (GLdouble) 0xffffff; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][0] = - dst[i][1] = - dst[i][2] = (float) ((s[i] & 0x00ffffff) * scale); - dst[i][3] = 1.0F; - ASSERT(dst[i][0] >= 0.0F); - ASSERT(dst[i][0] <= 1.0F); - } -} - -static void -unpack_Z_UNORM16(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLushort *s = ((const GLushort *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][0] = - dst[i][1] = - dst[i][2] = s[i] * (1.0F / 65535.0F); - dst[i][3] = 1.0F; - } -} - -static void -unpack_Z24_UNORM_X8_UINT(const void *src, GLfloat dst[][4], GLuint n) -{ - unpack_Z24_UNORM_S8_UINT(src, dst, n); -} - -static void -unpack_X8_UINT_Z24_UNORM(const void *src, GLfloat dst[][4], GLuint n) -{ - unpack_S8_UINT_Z24_UNORM(src, dst, n); -} - -static void -unpack_Z_UNORM32(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLuint *s = ((const GLuint *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][0] = - dst[i][1] = - dst[i][2] = s[i] * (1.0F / 0xffffffff); - dst[i][3] = 1.0F; - } -} - -static void -unpack_Z32_FLOAT_S8X24_UINT(const void *src, GLfloat dst[][4], GLuint n) -{ - const struct z32f_x24s8 *s = (const struct z32f_x24s8 *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][0] = - dst[i][1] = - dst[i][2] = s[i].z; - dst[i][3] = 1.0F; - } -} - -static void -unpack_Z_FLOAT32(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLfloat *s = ((const GLfloat *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][0] = - dst[i][1] = - dst[i][2] = s[i]; - dst[i][3] = 1.0F; - } -} - - -static void -unpack_S8(const void *src, GLfloat dst[][4], GLuint n) -{ - /* should never be used */ - GLuint i; - for (i = 0; i < n; i++) { - dst[i][0] = - dst[i][1] = - dst[i][2] = 0.0F; - dst[i][3] = 1.0F; - } -} - - -static void -unpack_BGR_SRGB8(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLubyte *s = (const GLubyte *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = util_format_srgb_8unorm_to_linear_float(s[i*3+2]); - dst[i][GCOMP] = util_format_srgb_8unorm_to_linear_float(s[i*3+1]); - dst[i][BCOMP] = util_format_srgb_8unorm_to_linear_float(s[i*3+0]); - dst[i][ACOMP] = 1.0F; - } -} - -static void -unpack_A8B8G8R8_SRGB(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLuint *s = ((const GLuint *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = util_format_srgb_8unorm_to_linear_float( (s[i] >> 24) ); - dst[i][GCOMP] = util_format_srgb_8unorm_to_linear_float( (s[i] >> 16) & 0xff ); - dst[i][BCOMP] = util_format_srgb_8unorm_to_linear_float( (s[i] >> 8) & 0xff ); - dst[i][ACOMP] = UBYTE_TO_FLOAT( s[i] & 0xff ); /* linear! */ - } -} - -static void -unpack_B8G8R8A8_SRGB(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLuint *s = ((const GLuint *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = util_format_srgb_8unorm_to_linear_float( (s[i] >> 16) & 0xff ); - dst[i][GCOMP] = util_format_srgb_8unorm_to_linear_float( (s[i] >> 8) & 0xff ); - dst[i][BCOMP] = util_format_srgb_8unorm_to_linear_float( (s[i] ) & 0xff ); - dst[i][ACOMP] = UBYTE_TO_FLOAT( s[i] >> 24 ); /* linear! */ - } -} - -static void -unpack_A8R8G8B8_SRGB(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLuint *s = ((const GLuint *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = util_format_srgb_8unorm_to_linear_float( (s[i] >> 8) & 0xff ); - dst[i][GCOMP] = util_format_srgb_8unorm_to_linear_float( (s[i] >> 16) & 0xff ); - dst[i][BCOMP] = util_format_srgb_8unorm_to_linear_float( (s[i] >> 24) ); - dst[i][ACOMP] = UBYTE_TO_FLOAT( s[i] & 0xff ); /* linear! */ - } -} - -static void -unpack_R8G8B8A8_SRGB(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLuint *s = ((const GLuint *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = util_format_srgb_8unorm_to_linear_float( (s[i] ) & 0xff ); - dst[i][GCOMP] = util_format_srgb_8unorm_to_linear_float( (s[i] >> 8) & 0xff ); - dst[i][BCOMP] = util_format_srgb_8unorm_to_linear_float( (s[i] >> 16) & 0xff ); - dst[i][ACOMP] = UBYTE_TO_FLOAT( s[i] >> 24 ); /* linear! */ - } -} - -static void -unpack_L_SRGB8(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLubyte *s = ((const GLubyte *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = - dst[i][GCOMP] = - dst[i][BCOMP] = util_format_srgb_8unorm_to_linear_float(s[i]); - dst[i][ACOMP] = 1.0F; - } -} - -static void -unpack_L8A8_SRGB(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLushort *s = (const GLushort *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = - dst[i][GCOMP] = - dst[i][BCOMP] = util_format_srgb_8unorm_to_linear_float(s[i] & 0xff); - dst[i][ACOMP] = UBYTE_TO_FLOAT(s[i] >> 8); /* linear! */ - } -} - -static void -unpack_A8L8_SRGB(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLushort *s = (const GLushort *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = - dst[i][GCOMP] = - dst[i][BCOMP] = util_format_srgb_8unorm_to_linear_float(s[i] >> 8); - dst[i][ACOMP] = UBYTE_TO_FLOAT(s[i] & 0xff); /* linear! */ - } -} - -static void -unpack_SRGB_DXT1(const void *src, GLfloat dst[][4], GLuint n) -{ -} - -static void -unpack_SRGBA_DXT1(const void *src, GLfloat dst[][4], GLuint n) -{ -} - -static void -unpack_SRGBA_DXT3(const void *src, GLfloat dst[][4], GLuint n) -{ -} - -static void -unpack_SRGBA_DXT5(const void *src, GLfloat dst[][4], GLuint n) -{ -} - -static void -unpack_RGB_FXT1(const void *src, GLfloat dst[][4], GLuint n) -{ -} - -static void -unpack_RGBA_FXT1(const void *src, GLfloat dst[][4], GLuint n) -{ -} - -static void -unpack_RGB_DXT1(const void *src, GLfloat dst[][4], GLuint n) -{ -} - -static void -unpack_RGBA_DXT1(const void *src, GLfloat dst[][4], GLuint n) -{ -} - -static void -unpack_RGBA_DXT3(const void *src, GLfloat dst[][4], GLuint n) -{ -} - -static void -unpack_RGBA_DXT5(const void *src, GLfloat dst[][4], GLuint n) -{ -} - - -static void -unpack_RGBA_FLOAT32(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLfloat *s = (const GLfloat *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = s[i*4+0]; - dst[i][GCOMP] = s[i*4+1]; - dst[i][BCOMP] = s[i*4+2]; - dst[i][ACOMP] = s[i*4+3]; - } -} - -static void -unpack_RGBA_FLOAT16(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLhalfARB *s = (const GLhalfARB *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = _mesa_half_to_float(s[i*4+0]); - dst[i][GCOMP] = _mesa_half_to_float(s[i*4+1]); - dst[i][BCOMP] = _mesa_half_to_float(s[i*4+2]); - dst[i][ACOMP] = _mesa_half_to_float(s[i*4+3]); - } -} - -static void -unpack_RGB_FLOAT32(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLfloat *s = (const GLfloat *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = s[i*3+0]; - dst[i][GCOMP] = s[i*3+1]; - dst[i][BCOMP] = s[i*3+2]; - dst[i][ACOMP] = 1.0F; - } -} - -static void -unpack_RGB_FLOAT16(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLhalfARB *s = (const GLhalfARB *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = _mesa_half_to_float(s[i*3+0]); - dst[i][GCOMP] = _mesa_half_to_float(s[i*3+1]); - dst[i][BCOMP] = _mesa_half_to_float(s[i*3+2]); - dst[i][ACOMP] = 1.0F; - } -} - -static void -unpack_A_FLOAT32(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLfloat *s = (const GLfloat *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = - dst[i][GCOMP] = - dst[i][BCOMP] = 0.0F; - dst[i][ACOMP] = s[i]; - } -} - -static void -unpack_A_FLOAT16(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLhalfARB *s = (const GLhalfARB *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = - dst[i][GCOMP] = - dst[i][BCOMP] = 0.0F; - dst[i][ACOMP] = _mesa_half_to_float(s[i]); - } -} - -static void -unpack_L_FLOAT32(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLfloat *s = (const GLfloat *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = - dst[i][GCOMP] = - dst[i][BCOMP] = s[i]; - dst[i][ACOMP] = 1.0F; - } -} - -static void -unpack_L_FLOAT16(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLhalfARB *s = (const GLhalfARB *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = - dst[i][GCOMP] = - dst[i][BCOMP] = _mesa_half_to_float(s[i]); - dst[i][ACOMP] = 1.0F; - } -} - -static void -unpack_LA_FLOAT32(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLfloat *s = (const GLfloat *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = - dst[i][GCOMP] = - dst[i][BCOMP] = s[i*2+0]; - dst[i][ACOMP] = s[i*2+1]; - } -} - -static void -unpack_LA_FLOAT16(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLhalfARB *s = (const GLhalfARB *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = - dst[i][GCOMP] = - dst[i][BCOMP] = _mesa_half_to_float(s[i*2+0]); - dst[i][ACOMP] = _mesa_half_to_float(s[i*2+1]); - } -} - -static void -unpack_I_FLOAT32(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLfloat *s = (const GLfloat *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = - dst[i][GCOMP] = - dst[i][BCOMP] = - dst[i][ACOMP] = s[i]; - } -} - -static void -unpack_I_FLOAT16(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLhalfARB *s = (const GLhalfARB *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = - dst[i][GCOMP] = - dst[i][BCOMP] = - dst[i][ACOMP] = _mesa_half_to_float(s[i]); - } -} - -static void -unpack_R_FLOAT32(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLfloat *s = (const GLfloat *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = s[i]; - dst[i][GCOMP] = 0.0F; - dst[i][BCOMP] = 0.0F; - dst[i][ACOMP] = 1.0F; - } -} - -static void -unpack_R_FLOAT16(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLhalfARB *s = (const GLhalfARB *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = _mesa_half_to_float(s[i]); - dst[i][GCOMP] = 0.0F; - dst[i][BCOMP] = 0.0F; - dst[i][ACOMP] = 1.0F; - } -} - -static void -unpack_RG_FLOAT32(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLfloat *s = (const GLfloat *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = s[i*2+0]; - dst[i][GCOMP] = s[i*2+1]; - dst[i][BCOMP] = 0.0F; - dst[i][ACOMP] = 1.0F; - } -} - -static void -unpack_RG_FLOAT16(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLhalfARB *s = (const GLhalfARB *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = _mesa_half_to_float(s[i*2+0]); - dst[i][GCOMP] = _mesa_half_to_float(s[i*2+1]); - dst[i][BCOMP] = 0.0F; - dst[i][ACOMP] = 1.0F; - } -} - -static void -unpack_ALPHA_UINT8(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLubyte *s = (const GLubyte *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = - dst[i][GCOMP] = - dst[i][BCOMP] = 0.0; - dst[i][ACOMP] = (GLfloat) s[i]; - } -} - -static void -unpack_ALPHA_UINT16(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLushort *s = (const GLushort *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = - dst[i][GCOMP] = - dst[i][BCOMP] = 0.0; - dst[i][ACOMP] = (GLfloat) s[i]; - } -} - -static void -unpack_ALPHA_UINT32(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLuint *s = (const GLuint *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = - dst[i][GCOMP] = - dst[i][BCOMP] = 0.0; - dst[i][ACOMP] = (GLfloat) s[i]; - } -} - -static void -unpack_ALPHA_INT8(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLbyte *s = (const GLbyte *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = - dst[i][GCOMP] = - dst[i][BCOMP] = 0.0; - dst[i][ACOMP] = (GLfloat) s[i]; - } -} - -static void -unpack_ALPHA_INT16(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLshort *s = (const GLshort *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = - dst[i][GCOMP] = - dst[i][BCOMP] = 0.0; - dst[i][ACOMP] = (GLfloat) s[i]; - } -} - -static void -unpack_ALPHA_INT32(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLint *s = (const GLint *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = - dst[i][GCOMP] = - dst[i][BCOMP] = 0.0; - dst[i][ACOMP] = (GLfloat) s[i]; - } -} - -static void -unpack_INTENSITY_UINT8(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLubyte *s = (const GLubyte *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = - dst[i][GCOMP] = - dst[i][BCOMP] = - dst[i][ACOMP] = (GLfloat) s[i]; - } -} - -static void -unpack_INTENSITY_UINT16(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLushort *s = (const GLushort *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = - dst[i][GCOMP] = - dst[i][BCOMP] = - dst[i][ACOMP] = (GLfloat) s[i]; - } -} - -static void -unpack_INTENSITY_UINT32(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLuint *s = (const GLuint *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = - dst[i][GCOMP] = - dst[i][BCOMP] = - dst[i][ACOMP] = (GLfloat) s[i]; - } -} - -static void -unpack_INTENSITY_INT8(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLbyte *s = (const GLbyte *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = - dst[i][GCOMP] = - dst[i][BCOMP] = - dst[i][ACOMP] = (GLfloat) s[i]; - } -} - -static void -unpack_INTENSITY_INT16(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLshort *s = (const GLshort *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = - dst[i][GCOMP] = - dst[i][BCOMP] = - dst[i][ACOMP] = (GLfloat) s[i]; - } -} - -static void -unpack_INTENSITY_INT32(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLint *s = (const GLint *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = - dst[i][GCOMP] = - dst[i][BCOMP] = - dst[i][ACOMP] = (GLfloat) s[i]; - } -} - -static void -unpack_LUMINANCE_UINT8(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLubyte *s = (const GLubyte *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = dst[i][GCOMP] = dst[i][BCOMP] = (GLfloat) s[i]; - dst[i][ACOMP] = 1.0; - } -} - -static void -unpack_LUMINANCE_UINT16(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLushort *s = (const GLushort *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = dst[i][GCOMP] = dst[i][BCOMP] = (GLfloat) s[i]; - dst[i][ACOMP] = 1.0; - } -} - -static void -unpack_LUMINANCE_UINT32(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLuint *s = (const GLuint *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = dst[i][GCOMP] = dst[i][BCOMP] = (GLfloat) s[i]; - dst[i][ACOMP] = 1.0; - } -} - -static void -unpack_LUMINANCE_INT8(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLbyte *s = (const GLbyte *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = dst[i][GCOMP] = dst[i][BCOMP] = (GLfloat) s[i]; - dst[i][ACOMP] = 1.0; - } -} - -static void -unpack_LUMINANCE_INT16(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLshort *s = (const GLshort *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = dst[i][GCOMP] = dst[i][BCOMP] = (GLfloat) s[i]; - dst[i][ACOMP] = 1.0; - } -} - -static void -unpack_LUMINANCE_INT32(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLint *s = (const GLint *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = dst[i][GCOMP] = dst[i][BCOMP] = (GLfloat) s[i]; - dst[i][ACOMP] = 1.0; - } -} - -static void -unpack_LUMINANCE_ALPHA_UINT8(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLubyte *s = (const GLubyte *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = - dst[i][GCOMP] = - dst[i][BCOMP] = (GLfloat) s[2*i+0]; - dst[i][ACOMP] = (GLfloat) s[2*i+1]; - } -} - -static void -unpack_LUMINANCE_ALPHA_UINT16(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLushort *s = (const GLushort *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = - dst[i][GCOMP] = - dst[i][BCOMP] = (GLfloat) s[2*i+0]; - dst[i][ACOMP] = (GLfloat) s[2*i+1]; - } -} - -static void -unpack_LUMINANCE_ALPHA_UINT32(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLuint *s = (const GLuint *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = - dst[i][GCOMP] = - dst[i][BCOMP] = (GLfloat) s[2*i+0]; - dst[i][ACOMP] = (GLfloat) s[2*i+1]; - } -} - -static void -unpack_LUMINANCE_ALPHA_INT8(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLbyte *s = (const GLbyte *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = - dst[i][GCOMP] = - dst[i][BCOMP] = (GLfloat) s[2*i+0]; - dst[i][ACOMP] = (GLfloat) s[2*i+1]; - } -} - -static void -unpack_LUMINANCE_ALPHA_INT16(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLshort *s = (const GLshort *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = - dst[i][GCOMP] = - dst[i][BCOMP] = (GLfloat) s[2*i+0]; - dst[i][ACOMP] = (GLfloat) s[2*i+1]; - } -} - -static void -unpack_LUMINANCE_ALPHA_INT32(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLint *s = (const GLint *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = - dst[i][GCOMP] = - dst[i][BCOMP] = (GLfloat) s[2*i+0]; - dst[i][ACOMP] = (GLfloat) s[2*i+1]; - } -} - -static void -unpack_R_INT8(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLbyte *s = (const GLbyte *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = (GLfloat) s[i]; - dst[i][GCOMP] = 0.0; - dst[i][BCOMP] = 0.0; - dst[i][ACOMP] = 1.0; - } -} - -static void -unpack_RG_INT8(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLbyte *s = (const GLbyte *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = (GLfloat) s[i*2+0]; - dst[i][GCOMP] = (GLfloat) s[i*2+1]; - dst[i][BCOMP] = 0.0; - dst[i][ACOMP] = 1.0; - } -} - -static void -unpack_RGB_INT8(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLbyte *s = (const GLbyte *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = (GLfloat) s[i*3+0]; - dst[i][GCOMP] = (GLfloat) s[i*3+1]; - dst[i][BCOMP] = (GLfloat) s[i*3+2]; - dst[i][ACOMP] = 1.0; - } -} - -static void -unpack_RGBA_INT8(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLbyte *s = (const GLbyte *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = (GLfloat) s[i*4+0]; - dst[i][GCOMP] = (GLfloat) s[i*4+1]; - dst[i][BCOMP] = (GLfloat) s[i*4+2]; - dst[i][ACOMP] = (GLfloat) s[i*4+3]; - } -} - -static void -unpack_R_INT16(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLshort *s = (const GLshort *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = (GLfloat) s[i]; - dst[i][GCOMP] = 0.0; - dst[i][BCOMP] = 0.0; - dst[i][ACOMP] = 1.0; - } -} - -static void -unpack_RG_INT16(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLshort *s = (const GLshort *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = (GLfloat) s[i*2+0]; - dst[i][GCOMP] = (GLfloat) s[i*2+1]; - dst[i][BCOMP] = 0.0; - dst[i][ACOMP] = 1.0; - } -} - -static void -unpack_RGB_INT16(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLshort *s = (const GLshort *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = (GLfloat) s[i*3+0]; - dst[i][GCOMP] = (GLfloat) s[i*3+1]; - dst[i][BCOMP] = (GLfloat) s[i*3+2]; - dst[i][ACOMP] = 1.0; - } -} - -static void -unpack_RGBA_INT16(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLshort *s = (const GLshort *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = (GLfloat) s[i*4+0]; - dst[i][GCOMP] = (GLfloat) s[i*4+1]; - dst[i][BCOMP] = (GLfloat) s[i*4+2]; - dst[i][ACOMP] = (GLfloat) s[i*4+3]; - } -} - -static void -unpack_R_INT32(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLint *s = (const GLint *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = (GLfloat) s[i]; - dst[i][GCOMP] = 0.0; - dst[i][BCOMP] = 0.0; - dst[i][ACOMP] = 1.0; - } -} - -static void -unpack_RG_INT32(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLint *s = (const GLint *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = (GLfloat) s[i*2+0]; - dst[i][GCOMP] = (GLfloat) s[i*2+1]; - dst[i][BCOMP] = 0.0; - dst[i][ACOMP] = 1.0; - } -} - -static void -unpack_RGB_INT32(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLint *s = (const GLint *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = (GLfloat) s[i*3+0]; - dst[i][GCOMP] = (GLfloat) s[i*3+1]; - dst[i][BCOMP] = (GLfloat) s[i*3+2]; - dst[i][ACOMP] = 1.0; - } -} - - -static void -unpack_RGBA_INT32(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLint *s = (const GLint *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = (GLfloat) s[i*4+0]; - dst[i][GCOMP] = (GLfloat) s[i*4+1]; - dst[i][BCOMP] = (GLfloat) s[i*4+2]; - dst[i][ACOMP] = (GLfloat) s[i*4+3]; - } -} - -static void -unpack_R_UINT8(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLubyte *s = (const GLubyte *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = (GLfloat) s[i]; - dst[i][GCOMP] = 0.0; - dst[i][BCOMP] = 0.0; - dst[i][ACOMP] = 1.0; - } -} - -static void -unpack_RG_UINT8(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLubyte *s = (const GLubyte *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = (GLfloat) s[i*2+0]; - dst[i][GCOMP] = (GLfloat) s[i*2+1]; - dst[i][BCOMP] = 0.0; - dst[i][ACOMP] = 1.0; - } -} - -static void -unpack_RGB_UINT8(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLubyte *s = (const GLubyte *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = (GLfloat) s[i*3+0]; - dst[i][GCOMP] = (GLfloat) s[i*3+1]; - dst[i][BCOMP] = (GLfloat) s[i*3+2]; - dst[i][ACOMP] = 1.0; - } -} - -static void -unpack_RGBA_UINT8(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLubyte *s = (const GLubyte *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = (GLfloat) s[i*4+0]; - dst[i][GCOMP] = (GLfloat) s[i*4+1]; - dst[i][BCOMP] = (GLfloat) s[i*4+2]; - dst[i][ACOMP] = (GLfloat) s[i*4+3]; - } -} - -static void -unpack_R_UINT16(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLushort *s = (const GLushort *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = (GLfloat) s[i]; - dst[i][GCOMP] = 0.0; - dst[i][BCOMP] = 0.0; - dst[i][ACOMP] = 1.0; - } -} - -static void -unpack_RG_UINT16(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLushort *s = (const GLushort *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = (GLfloat) s[i*2+0]; - dst[i][GCOMP] = (GLfloat) s[i*2+1]; - dst[i][BCOMP] = 0.0; - dst[i][ACOMP] = 1.0; - } -} - -static void -unpack_RGB_UINT16(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLushort *s = (const GLushort *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = (GLfloat) s[i*3+0]; - dst[i][GCOMP] = (GLfloat) s[i*3+1]; - dst[i][BCOMP] = (GLfloat) s[i*3+2]; - dst[i][ACOMP] = 1.0; - } -} - -static void -unpack_RGBA_UINT16(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLushort *s = (const GLushort *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = (GLfloat) s[i*4+0]; - dst[i][GCOMP] = (GLfloat) s[i*4+1]; - dst[i][BCOMP] = (GLfloat) s[i*4+2]; - dst[i][ACOMP] = (GLfloat) s[i*4+3]; - } -} - -static void -unpack_R_UINT32(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLuint *s = (const GLuint *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = (GLfloat) s[i]; - dst[i][GCOMP] = 0.0; - dst[i][BCOMP] = 0.0; - dst[i][ACOMP] = 1.0; - } -} - -static void -unpack_RG_UINT32(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLuint *s = (const GLuint *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = (GLfloat) s[i*2+0]; - dst[i][GCOMP] = (GLfloat) s[i*2+1]; - dst[i][BCOMP] = 0.0; - dst[i][ACOMP] = 1.0; - } -} - -static void -unpack_RGB_UINT32(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLuint *s = (const GLuint *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = (GLfloat) s[i*3+0]; - dst[i][GCOMP] = (GLfloat) s[i*3+1]; - dst[i][BCOMP] = (GLfloat) s[i*3+2]; - dst[i][ACOMP] = 1.0; - } -} - -static void -unpack_RGBA_UINT32(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLuint *s = (const GLuint *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = (GLfloat) s[i*4+0]; - dst[i][GCOMP] = (GLfloat) s[i*4+1]; - dst[i][BCOMP] = (GLfloat) s[i*4+2]; - dst[i][ACOMP] = (GLfloat) s[i*4+3]; - } -} - -static void -unpack_R_SNORM8(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLbyte *s = ((const GLbyte *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = BYTE_TO_FLOAT_TEX( s[i] ); - dst[i][GCOMP] = 0.0F; - dst[i][BCOMP] = 0.0F; - dst[i][ACOMP] = 1.0F; - } -} - -static void -unpack_R8G8_SNORM(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLushort *s = ((const GLushort *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = BYTE_TO_FLOAT_TEX( (GLbyte) (s[i] & 0xff) ); - dst[i][GCOMP] = BYTE_TO_FLOAT_TEX( (GLbyte) (s[i] >> 8) ); - dst[i][BCOMP] = 0.0F; - dst[i][ACOMP] = 1.0F; - } -} - -static void -unpack_X8B8G8R8_SNORM(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLuint *s = ((const GLuint *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = BYTE_TO_FLOAT_TEX( (GLbyte) (s[i] >> 24) ); - dst[i][GCOMP] = BYTE_TO_FLOAT_TEX( (GLbyte) (s[i] >> 16) ); - dst[i][BCOMP] = BYTE_TO_FLOAT_TEX( (GLbyte) (s[i] >> 8) ); - dst[i][ACOMP] = 1.0f; - } -} - -static void -unpack_A8B8G8R8_SNORM(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLuint *s = ((const GLuint *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = BYTE_TO_FLOAT_TEX( (GLbyte) (s[i] >> 24) ); - dst[i][GCOMP] = BYTE_TO_FLOAT_TEX( (GLbyte) (s[i] >> 16) ); - dst[i][BCOMP] = BYTE_TO_FLOAT_TEX( (GLbyte) (s[i] >> 8) ); - dst[i][ACOMP] = BYTE_TO_FLOAT_TEX( (GLbyte) (s[i] ) ); - } -} - -static void -unpack_R8G8B8A8_SNORM(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLuint *s = ((const GLuint *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = BYTE_TO_FLOAT_TEX( (GLbyte) (s[i] ) ); - dst[i][GCOMP] = BYTE_TO_FLOAT_TEX( (GLbyte) (s[i] >> 8) ); - dst[i][BCOMP] = BYTE_TO_FLOAT_TEX( (GLbyte) (s[i] >> 16) ); - dst[i][ACOMP] = BYTE_TO_FLOAT_TEX( (GLbyte) (s[i] >> 24) ); - } -} - -static void -unpack_R_SNORM16(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLshort *s = ((const GLshort *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = SHORT_TO_FLOAT_TEX( s[i] ); - dst[i][GCOMP] = 0.0F; - dst[i][BCOMP] = 0.0F; - dst[i][ACOMP] = 1.0F; - } -} - -static void -unpack_R16G16_SNORM(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLuint *s = ((const GLuint *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = SHORT_TO_FLOAT_TEX( (GLshort) (s[i] & 0xffff) ); - dst[i][GCOMP] = SHORT_TO_FLOAT_TEX( (GLshort) (s[i] >> 16) ); - dst[i][BCOMP] = 0.0F; - dst[i][ACOMP] = 1.0F; - } -} - -static void -unpack_RGB_SNORM16(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLshort *s = (const GLshort *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = SHORT_TO_FLOAT_TEX( s[i*3+0] ); - dst[i][GCOMP] = SHORT_TO_FLOAT_TEX( s[i*3+1] ); - dst[i][BCOMP] = SHORT_TO_FLOAT_TEX( s[i*3+2] ); - dst[i][ACOMP] = 1.0F; - } -} - -static void -unpack_RGBA_SNORM16(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLshort *s = (const GLshort *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = SHORT_TO_FLOAT_TEX( s[i*4+0] ); - dst[i][GCOMP] = SHORT_TO_FLOAT_TEX( s[i*4+1] ); - dst[i][BCOMP] = SHORT_TO_FLOAT_TEX( s[i*4+2] ); - dst[i][ACOMP] = SHORT_TO_FLOAT_TEX( s[i*4+3] ); - } -} - -static void -unpack_RGBA_16(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLushort *s = (const GLushort *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = USHORT_TO_FLOAT( s[i*4+0] ); - dst[i][GCOMP] = USHORT_TO_FLOAT( s[i*4+1] ); - dst[i][BCOMP] = USHORT_TO_FLOAT( s[i*4+2] ); - dst[i][ACOMP] = USHORT_TO_FLOAT( s[i*4+3] ); - } -} - -static void -unpack_RED_RGTC1(const void *src, GLfloat dst[][4], GLuint n) -{ - /* XXX to do */ -} - -static void -unpack_SIGNED_RED_RGTC1(const void *src, GLfloat dst[][4], GLuint n) -{ - /* XXX to do */ -} - -static void -unpack_RG_RGTC2(const void *src, GLfloat dst[][4], GLuint n) -{ - /* XXX to do */ -} - -static void -unpack_SIGNED_RG_RGTC2(const void *src, GLfloat dst[][4], GLuint n) -{ - /* XXX to do */ -} - -static void -unpack_L_LATC1(const void *src, GLfloat dst[][4], GLuint n) -{ - /* XXX to do */ -} - -static void -unpack_SIGNED_L_LATC1(const void *src, GLfloat dst[][4], GLuint n) -{ - /* XXX to do */ -} - -static void -unpack_LA_LATC2(const void *src, GLfloat dst[][4], GLuint n) -{ - /* XXX to do */ -} - -static void -unpack_SIGNED_LA_LATC2(const void *src, GLfloat dst[][4], GLuint n) -{ - /* XXX to do */ -} - -static void -unpack_ETC1_RGB8(const void *src, GLfloat dst[][4], GLuint n) -{ - /* XXX to do */ -} - -static void -unpack_ETC2_RGB8(const void *src, GLfloat dst[][4], GLuint n) -{ - /* XXX to do */ -} - -static void -unpack_ETC2_SRGB8(const void *src, GLfloat dst[][4], GLuint n) -{ - /* XXX to do */ -} - -static void -unpack_ETC2_RGBA8_EAC(const void *src, GLfloat dst[][4], GLuint n) -{ - /* XXX to do */ -} - -static void -unpack_ETC2_SRGB8_ALPHA8_EAC(const void *src, GLfloat dst[][4], GLuint n) -{ - /* XXX to do */ -} - -static void -unpack_ETC2_R11_EAC(const void *src, GLfloat dst[][4], GLuint n) -{ - /* XXX to do */ -} - -static void -unpack_ETC2_RG11_EAC(const void *src, GLfloat dst[][4], GLuint n) -{ - /* XXX to do */ -} - -static void -unpack_ETC2_SIGNED_R11_EAC(const void *src, GLfloat dst[][4], GLuint n) -{ - /* XXX to do */ -} - -static void -unpack_ETC2_SIGNED_RG11_EAC(const void *src, GLfloat dst[][4], GLuint n) -{ - /* XXX to do */ -} - -static void -unpack_ETC2_RGB8_PUNCHTHROUGH_ALPHA1(const void *src, GLfloat dst[][4], - GLuint n) -{ - /* XXX to do */ -} - -static void -unpack_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1(const void *src, GLfloat dst[][4], - GLuint n) -{ - /* XXX to do */ -} - -static void -unpack_A_SNORM8(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLbyte *s = ((const GLbyte *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = 0.0F; - dst[i][GCOMP] = 0.0F; - dst[i][BCOMP] = 0.0F; - dst[i][ACOMP] = BYTE_TO_FLOAT_TEX( s[i] ); - } -} - -static void -unpack_L_SNORM8(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLbyte *s = ((const GLbyte *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = - dst[i][GCOMP] = - dst[i][BCOMP] = BYTE_TO_FLOAT_TEX( s[i] ); - dst[i][ACOMP] = 1.0F; - } -} - -static void -unpack_L8A8_SNORM(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLshort *s = ((const GLshort *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = - dst[i][GCOMP] = - dst[i][BCOMP] = BYTE_TO_FLOAT_TEX( (GLbyte) (s[i] & 0xff) ); - dst[i][ACOMP] = BYTE_TO_FLOAT_TEX( (GLbyte) (s[i] >> 8) ); - } -} - - -static void -unpack_A8L8_SNORM(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLshort *s = ((const GLshort *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = - dst[i][GCOMP] = - dst[i][BCOMP] = BYTE_TO_FLOAT_TEX( (GLbyte) (s[i] >> 8) ); - dst[i][ACOMP] = BYTE_TO_FLOAT_TEX( (GLbyte) (s[i] & 0xff) ); - } -} - -static void -unpack_I_SNORM8(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLbyte *s = ((const GLbyte *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = - dst[i][GCOMP] = - dst[i][BCOMP] = - dst[i][ACOMP] = BYTE_TO_FLOAT_TEX( s[i] ); - } -} - -static void -unpack_A_SNORM16(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLshort *s = ((const GLshort *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = 0.0F; - dst[i][GCOMP] = 0.0F; - dst[i][BCOMP] = 0.0F; - dst[i][ACOMP] = SHORT_TO_FLOAT_TEX( s[i] ); - } -} - -static void -unpack_L_SNORM16(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLshort *s = ((const GLshort *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = - dst[i][GCOMP] = - dst[i][BCOMP] = SHORT_TO_FLOAT_TEX( s[i] ); - dst[i][ACOMP] = 1.0F; - } -} - -static void -unpack_LA_SNORM16(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLshort *s = (const GLshort *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = - dst[i][GCOMP] = - dst[i][BCOMP] = SHORT_TO_FLOAT_TEX( s[i*2+0] ); - dst[i][ACOMP] = SHORT_TO_FLOAT_TEX( s[i*2+1] ); - } -} - -static void -unpack_I_SNORM16(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLshort *s = ((const GLshort *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = - dst[i][GCOMP] = - dst[i][BCOMP] = - dst[i][ACOMP] = SHORT_TO_FLOAT_TEX( s[i] ); - } -} - -static void -unpack_R9G9B9E5_FLOAT(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLuint *s = (const GLuint *) src; - GLuint i; - for (i = 0; i < n; i++) { - rgb9e5_to_float3(s[i], dst[i]); - dst[i][ACOMP] = 1.0F; - } -} - -static void -unpack_R11G11B10_FLOAT(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLuint *s = (const GLuint *) src; - GLuint i; - for (i = 0; i < n; i++) { - r11g11b10f_to_float3(s[i], dst[i]); - dst[i][ACOMP] = 1.0F; - } -} - -static void -unpack_XRGB4444_UNORM(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLushort *s = ((const GLushort *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = ((s[i] >> 8) & 0xf) * (1.0F / 15.0F); - dst[i][GCOMP] = ((s[i] >> 4) & 0xf) * (1.0F / 15.0F); - dst[i][BCOMP] = ((s[i] ) & 0xf) * (1.0F / 15.0F); - dst[i][ACOMP] = 1.0; - } -} - -static void -unpack_XRGB1555_UNORM(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLushort *s = ((const GLushort *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = ((s[i] >> 10) & 0x1f) * (1.0F / 31.0F); - dst[i][GCOMP] = ((s[i] >> 5) & 0x1f) * (1.0F / 31.0F); - dst[i][BCOMP] = ((s[i] >> 0) & 0x1f) * (1.0F / 31.0F); - dst[i][ACOMP] = 1.0; - } -} - -static void -unpack_R8G8B8X8_SNORM(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLuint *s = ((const GLuint *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = BYTE_TO_FLOAT_TEX( (GLbyte) (s[i] ) ); - dst[i][GCOMP] = BYTE_TO_FLOAT_TEX( (GLbyte) (s[i] >> 8) ); - dst[i][BCOMP] = BYTE_TO_FLOAT_TEX( (GLbyte) (s[i] >> 16) ); - dst[i][ACOMP] = 1.0; - } -} - -static void -unpack_R8G8B8X8_SRGB(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLuint *s = ((const GLuint *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = util_format_srgb_8unorm_to_linear_float( (s[i] ) & 0xff ); - dst[i][GCOMP] = util_format_srgb_8unorm_to_linear_float( (s[i] >> 8) & 0xff ); - dst[i][BCOMP] = util_format_srgb_8unorm_to_linear_float( (s[i] >> 16) & 0xff ); - dst[i][ACOMP] = 1.0f; - } -} - -static void -unpack_X8B8G8R8_SRGB(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLuint *s = ((const GLuint *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = util_format_srgb_8unorm_to_linear_float( (s[i] >> 24) ); - dst[i][GCOMP] = util_format_srgb_8unorm_to_linear_float( (s[i] >> 16) & 0xff ); - dst[i][BCOMP] = util_format_srgb_8unorm_to_linear_float( (s[i] >> 8) & 0xff ); - dst[i][ACOMP] = 1.0f; - } -} - -static void -unpack_XBGR8888_UINT(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLbyte *s = (const GLbyte *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = s[i*4+0]; - dst[i][GCOMP] = s[i*4+1]; - dst[i][BCOMP] = s[i*4+2]; - dst[i][ACOMP] = 1.0; - } -} - -static void -unpack_XBGR8888_SINT(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLbyte *s = (const GLbyte *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = s[i*4+0]; - dst[i][GCOMP] = s[i*4+1]; - dst[i][BCOMP] = s[i*4+2]; - dst[i][ACOMP] = 1.0; - } -} - -static void -unpack_B10G10R10X2_UNORM(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLuint *s = ((const GLuint *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = ((s[i] >> 20) & 0x3ff) * (1.0F / 1023.0F); - dst[i][GCOMP] = ((s[i] >> 10) & 0x3ff) * (1.0F / 1023.0F); - dst[i][BCOMP] = ((s[i] >> 0) & 0x3ff) * (1.0F / 1023.0F); - dst[i][ACOMP] = 1.0; - } -} - -static void -unpack_RGBX_UNORM16(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLushort *s = (const GLushort *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = USHORT_TO_FLOAT( s[i*4+0] ); - dst[i][GCOMP] = USHORT_TO_FLOAT( s[i*4+1] ); - dst[i][BCOMP] = USHORT_TO_FLOAT( s[i*4+2] ); - dst[i][ACOMP] = 1.0; - } -} - -static void -unpack_RGBX_SNORM16(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLshort *s = (const GLshort *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = SHORT_TO_FLOAT_TEX( s[i*4+0] ); - dst[i][GCOMP] = SHORT_TO_FLOAT_TEX( s[i*4+1] ); - dst[i][BCOMP] = SHORT_TO_FLOAT_TEX( s[i*4+2] ); - dst[i][ACOMP] = 1.0; - } -} - -static void -unpack_XBGR16161616_FLOAT(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLshort *s = (const GLshort *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = _mesa_half_to_float(s[i*4+0]); - dst[i][GCOMP] = _mesa_half_to_float(s[i*4+1]); - dst[i][BCOMP] = _mesa_half_to_float(s[i*4+2]); - dst[i][ACOMP] = 1.0; - } -} - -static void -unpack_XBGR16161616_UINT(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLushort *s = (const GLushort *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = (GLfloat) s[i*4+0]; - dst[i][GCOMP] = (GLfloat) s[i*4+1]; - dst[i][BCOMP] = (GLfloat) s[i*4+2]; - dst[i][ACOMP] = 1.0; - } -} - -static void -unpack_XBGR16161616_SINT(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLshort *s = (const GLshort *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = (GLfloat) s[i*4+0]; - dst[i][GCOMP] = (GLfloat) s[i*4+1]; - dst[i][BCOMP] = (GLfloat) s[i*4+2]; - dst[i][ACOMP] = 1.0; - } -} - -static void -unpack_RGBX_FLOAT32(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLfloat *s = (const GLfloat *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = s[i*4+0]; - dst[i][GCOMP] = s[i*4+1]; - dst[i][BCOMP] = s[i*4+2]; - dst[i][ACOMP] = 1.0; - } -} - -static void -unpack_XBGR32323232_UINT(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLuint *s = (const GLuint *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = (GLfloat) s[i*4+0]; - dst[i][GCOMP] = (GLfloat) s[i*4+1]; - dst[i][BCOMP] = (GLfloat) s[i*4+2]; - dst[i][ACOMP] = 1.0; - } -} - -static void -unpack_XBGR32323232_SINT(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLint *s = (const GLint *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = (GLfloat) s[i*4+0]; - dst[i][GCOMP] = (GLfloat) s[i*4+1]; - dst[i][BCOMP] = (GLfloat) s[i*4+2]; - dst[i][ACOMP] = 1.0; - } -} - -static void -unpack_R10G10B10A2_UNORM(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLuint *s = ((const GLuint *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = ((s[i] >> 0) & 0x3ff) * (1.0F / 1023.0F); - dst[i][GCOMP] = ((s[i] >> 10) & 0x3ff) * (1.0F / 1023.0F); - dst[i][BCOMP] = ((s[i] >> 20) & 0x3ff) * (1.0F / 1023.0F); - dst[i][ACOMP] = ((s[i] >> 30) & 0x03) * (1.0F / 3.0F); - } -} - -static void -unpack_G8R8_SNORM(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLushort *s = ((const GLushort *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = BYTE_TO_FLOAT_TEX( (GLbyte) (s[i] >> 8) ); - dst[i][GCOMP] = BYTE_TO_FLOAT_TEX( (GLbyte) (s[i] & 0xff) ); - dst[i][BCOMP] = 0.0F; - dst[i][ACOMP] = 1.0F; - } -} - -static void -unpack_G16R16_SNORM(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLuint *s = ((const GLuint *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = SHORT_TO_FLOAT_TEX( (GLshort) (s[i] >> 16) ); - dst[i][GCOMP] = SHORT_TO_FLOAT_TEX( (GLshort) (s[i] & 0xffff) ); - dst[i][BCOMP] = 0.0F; - dst[i][ACOMP] = 1.0F; - } -} - -static void -unpack_B8G8R8X8_SRGB(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLuint *s = ((const GLuint *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = util_format_srgb_8unorm_to_linear_float( (s[i] >> 16) & 0xff ); - dst[i][GCOMP] = util_format_srgb_8unorm_to_linear_float( (s[i] >> 8) & 0xff ); - dst[i][BCOMP] = util_format_srgb_8unorm_to_linear_float( (s[i] ) & 0xff ); - dst[i][ACOMP] = 1.0F; - } -} - -static void -unpack_X8R8G8B8_SRGB(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLuint *s = ((const GLuint *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = util_format_srgb_8unorm_to_linear_float( (s[i] >> 8) & 0xff ); - dst[i][GCOMP] = util_format_srgb_8unorm_to_linear_float( (s[i] >> 16) & 0xff ); - dst[i][BCOMP] = util_format_srgb_8unorm_to_linear_float( (s[i] >> 24) ); - dst[i][ACOMP] = 1.0F; - } -} - -/** - * Return the unpacker function for the given format. - */ -static unpack_rgba_func -get_unpack_rgba_function(mesa_format format) -{ - static unpack_rgba_func table[MESA_FORMAT_COUNT]; - static GLboolean initialized = GL_FALSE; - - if (!initialized) { - table[MESA_FORMAT_NONE] = NULL; - - table[MESA_FORMAT_A8B8G8R8_UNORM] = unpack_A8B8G8R8_UNORM; - table[MESA_FORMAT_R8G8B8A8_UNORM] = unpack_R8G8B8A8_UNORM; - table[MESA_FORMAT_B8G8R8A8_UNORM] = unpack_B8G8R8A8_UNORM; - table[MESA_FORMAT_A8R8G8B8_UNORM] = unpack_A8R8G8B8_UNORM; - table[MESA_FORMAT_X8B8G8R8_UNORM] = unpack_RGBX8888; - table[MESA_FORMAT_R8G8B8X8_UNORM] = unpack_RGBX8888_REV; - table[MESA_FORMAT_B8G8R8X8_UNORM] = unpack_B8G8R8X8_UNORM; - table[MESA_FORMAT_X8R8G8B8_UNORM] = unpack_X8R8G8B8_UNORM; - table[MESA_FORMAT_BGR_UNORM8] = unpack_BGR_UNORM8; - table[MESA_FORMAT_RGB_UNORM8] = unpack_RGB_UNORM8; - table[MESA_FORMAT_B5G6R5_UNORM] = unpack_B5G6R5_UNORM; - table[MESA_FORMAT_R5G6B5_UNORM] = unpack_R5G6B5_UNORM; - table[MESA_FORMAT_B4G4R4A4_UNORM] = unpack_B4G4R4A4_UNORM; - table[MESA_FORMAT_A4R4G4B4_UNORM] = unpack_A4R4G4B4_UNORM; - table[MESA_FORMAT_A1B5G5R5_UNORM] = unpack_A1B5G5R5_UNORM; - table[MESA_FORMAT_B5G5R5A1_UNORM] = unpack_B5G5R5A1_UNORM; - table[MESA_FORMAT_A1R5G5B5_UNORM] = unpack_A1R5G5B5_UNORM; - table[MESA_FORMAT_L4A4_UNORM] = unpack_L4A4_UNORM; - table[MESA_FORMAT_L8A8_UNORM] = unpack_L8A8_UNORM; - table[MESA_FORMAT_A8L8_UNORM] = unpack_A8L8_UNORM; - table[MESA_FORMAT_L16A16_UNORM] = unpack_L16A16_UNORM; - table[MESA_FORMAT_A16L16_UNORM] = unpack_A16L16_UNORM; - table[MESA_FORMAT_B2G3R3_UNORM] = unpack_B2G3R3_UNORM; - table[MESA_FORMAT_A_UNORM8] = unpack_A_UNORM8; - table[MESA_FORMAT_A_UNORM16] = unpack_A_UNORM16; - table[MESA_FORMAT_L_UNORM8] = unpack_L_UNORM8; - table[MESA_FORMAT_L_UNORM16] = unpack_L_UNORM16; - table[MESA_FORMAT_I_UNORM8] = unpack_I_UNORM8; - table[MESA_FORMAT_I_UNORM16] = unpack_I_UNORM16; - table[MESA_FORMAT_YCBCR] = unpack_YCBCR; - table[MESA_FORMAT_YCBCR_REV] = unpack_YCBCR_REV; - table[MESA_FORMAT_R_UNORM8] = unpack_R_UNORM8; - table[MESA_FORMAT_R8G8_UNORM] = unpack_R8G8_UNORM; - table[MESA_FORMAT_G8R8_UNORM] = unpack_G8R8_UNORM; - table[MESA_FORMAT_R_UNORM16] = unpack_R_UNORM16; - table[MESA_FORMAT_R16G16_UNORM] = unpack_R16G16_UNORM; - table[MESA_FORMAT_G16R16_UNORM] = unpack_G16R16_UNORM; - table[MESA_FORMAT_B10G10R10A2_UNORM] = unpack_B10G10R10A2_UNORM; - table[MESA_FORMAT_B10G10R10A2_UINT] = unpack_B10G10R10A2_UINT; - table[MESA_FORMAT_R10G10B10A2_UINT] = unpack_R10G10B10A2_UINT; - table[MESA_FORMAT_S8_UINT_Z24_UNORM] = unpack_S8_UINT_Z24_UNORM; - table[MESA_FORMAT_Z24_UNORM_S8_UINT] = unpack_Z24_UNORM_S8_UINT; - table[MESA_FORMAT_Z_UNORM16] = unpack_Z_UNORM16; - table[MESA_FORMAT_Z24_UNORM_X8_UINT] = unpack_Z24_UNORM_X8_UINT; - table[MESA_FORMAT_X8_UINT_Z24_UNORM] = unpack_X8_UINT_Z24_UNORM; - table[MESA_FORMAT_Z_UNORM32] = unpack_Z_UNORM32; - table[MESA_FORMAT_S_UINT8] = unpack_S8; - table[MESA_FORMAT_BGR_SRGB8] = unpack_BGR_SRGB8; - table[MESA_FORMAT_A8B8G8R8_SRGB] = unpack_A8B8G8R8_SRGB; - table[MESA_FORMAT_B8G8R8A8_SRGB] = unpack_B8G8R8A8_SRGB; - table[MESA_FORMAT_A8R8G8B8_SRGB] = unpack_A8R8G8B8_SRGB; - table[MESA_FORMAT_R8G8B8A8_SRGB] = unpack_R8G8B8A8_SRGB; - table[MESA_FORMAT_L_SRGB8] = unpack_L_SRGB8; - table[MESA_FORMAT_L8A8_SRGB] = unpack_L8A8_SRGB; - table[MESA_FORMAT_A8L8_SRGB] = unpack_A8L8_SRGB; - table[MESA_FORMAT_SRGB_DXT1] = unpack_SRGB_DXT1; - table[MESA_FORMAT_SRGBA_DXT1] = unpack_SRGBA_DXT1; - table[MESA_FORMAT_SRGBA_DXT3] = unpack_SRGBA_DXT3; - table[MESA_FORMAT_SRGBA_DXT5] = unpack_SRGBA_DXT5; - - table[MESA_FORMAT_RGB_FXT1] = unpack_RGB_FXT1; - table[MESA_FORMAT_RGBA_FXT1] = unpack_RGBA_FXT1; - table[MESA_FORMAT_RGB_DXT1] = unpack_RGB_DXT1; - table[MESA_FORMAT_RGBA_DXT1] = unpack_RGBA_DXT1; - table[MESA_FORMAT_RGBA_DXT3] = unpack_RGBA_DXT3; - table[MESA_FORMAT_RGBA_DXT5] = unpack_RGBA_DXT5; - - table[MESA_FORMAT_RGBA_FLOAT32] = unpack_RGBA_FLOAT32; - table[MESA_FORMAT_RGBA_FLOAT16] = unpack_RGBA_FLOAT16; - table[MESA_FORMAT_RGB_FLOAT32] = unpack_RGB_FLOAT32; - table[MESA_FORMAT_RGB_FLOAT16] = unpack_RGB_FLOAT16; - table[MESA_FORMAT_A_FLOAT32] = unpack_A_FLOAT32; - table[MESA_FORMAT_A_FLOAT16] = unpack_A_FLOAT16; - table[MESA_FORMAT_L_FLOAT32] = unpack_L_FLOAT32; - table[MESA_FORMAT_L_FLOAT16] = unpack_L_FLOAT16; - table[MESA_FORMAT_LA_FLOAT32] = unpack_LA_FLOAT32; - table[MESA_FORMAT_LA_FLOAT16] = unpack_LA_FLOAT16; - table[MESA_FORMAT_I_FLOAT32] = unpack_I_FLOAT32; - table[MESA_FORMAT_I_FLOAT16] = unpack_I_FLOAT16; - table[MESA_FORMAT_R_FLOAT32] = unpack_R_FLOAT32; - table[MESA_FORMAT_R_FLOAT16] = unpack_R_FLOAT16; - table[MESA_FORMAT_RG_FLOAT32] = unpack_RG_FLOAT32; - table[MESA_FORMAT_RG_FLOAT16] = unpack_RG_FLOAT16; - - table[MESA_FORMAT_A_UINT8] = unpack_ALPHA_UINT8; - table[MESA_FORMAT_A_UINT16] = unpack_ALPHA_UINT16; - table[MESA_FORMAT_A_UINT32] = unpack_ALPHA_UINT32; - table[MESA_FORMAT_A_SINT8] = unpack_ALPHA_INT8; - table[MESA_FORMAT_A_SINT16] = unpack_ALPHA_INT16; - table[MESA_FORMAT_A_SINT32] = unpack_ALPHA_INT32; - - table[MESA_FORMAT_I_UINT8] = unpack_INTENSITY_UINT8; - table[MESA_FORMAT_I_UINT16] = unpack_INTENSITY_UINT16; - table[MESA_FORMAT_I_UINT32] = unpack_INTENSITY_UINT32; - table[MESA_FORMAT_I_SINT8] = unpack_INTENSITY_INT8; - table[MESA_FORMAT_I_SINT16] = unpack_INTENSITY_INT16; - table[MESA_FORMAT_I_SINT32] = unpack_INTENSITY_INT32; - - table[MESA_FORMAT_L_UINT8] = unpack_LUMINANCE_UINT8; - table[MESA_FORMAT_L_UINT16] = unpack_LUMINANCE_UINT16; - table[MESA_FORMAT_L_UINT32] = unpack_LUMINANCE_UINT32; - table[MESA_FORMAT_L_SINT8] = unpack_LUMINANCE_INT8; - table[MESA_FORMAT_L_SINT16] = unpack_LUMINANCE_INT16; - table[MESA_FORMAT_L_SINT32] = unpack_LUMINANCE_INT32; - - table[MESA_FORMAT_LA_UINT8] = unpack_LUMINANCE_ALPHA_UINT8; - table[MESA_FORMAT_LA_UINT16] = unpack_LUMINANCE_ALPHA_UINT16; - table[MESA_FORMAT_LA_UINT32] = unpack_LUMINANCE_ALPHA_UINT32; - table[MESA_FORMAT_LA_SINT8] = unpack_LUMINANCE_ALPHA_INT8; - table[MESA_FORMAT_LA_SINT16] = unpack_LUMINANCE_ALPHA_INT16; - table[MESA_FORMAT_LA_SINT32] = unpack_LUMINANCE_ALPHA_INT32; - - table[MESA_FORMAT_R_SINT8] = unpack_R_INT8; - table[MESA_FORMAT_RG_SINT8] = unpack_RG_INT8; - table[MESA_FORMAT_RGB_SINT8] = unpack_RGB_INT8; - table[MESA_FORMAT_RGBA_SINT8] = unpack_RGBA_INT8; - table[MESA_FORMAT_R_SINT16] = unpack_R_INT16; - table[MESA_FORMAT_RG_SINT16] = unpack_RG_INT16; - table[MESA_FORMAT_RGB_SINT16] = unpack_RGB_INT16; - table[MESA_FORMAT_RGBA_SINT16] = unpack_RGBA_INT16; - table[MESA_FORMAT_R_SINT32] = unpack_R_INT32; - table[MESA_FORMAT_RG_SINT32] = unpack_RG_INT32; - table[MESA_FORMAT_RGB_SINT32] = unpack_RGB_INT32; - table[MESA_FORMAT_RGBA_SINT32] = unpack_RGBA_INT32; - table[MESA_FORMAT_R_UINT8] = unpack_R_UINT8; - table[MESA_FORMAT_RG_UINT8] = unpack_RG_UINT8; - table[MESA_FORMAT_RGB_UINT8] = unpack_RGB_UINT8; - table[MESA_FORMAT_RGBA_UINT8] = unpack_RGBA_UINT8; - table[MESA_FORMAT_R_UINT16] = unpack_R_UINT16; - table[MESA_FORMAT_RG_UINT16] = unpack_RG_UINT16; - table[MESA_FORMAT_RGB_UINT16] = unpack_RGB_UINT16; - table[MESA_FORMAT_RGBA_UINT16] = unpack_RGBA_UINT16; - table[MESA_FORMAT_R_UINT32] = unpack_R_UINT32; - table[MESA_FORMAT_RG_UINT32] = unpack_RG_UINT32; - table[MESA_FORMAT_RGB_UINT32] = unpack_RGB_UINT32; - table[MESA_FORMAT_RGBA_UINT32] = unpack_RGBA_UINT32; - - table[MESA_FORMAT_R_SNORM8] = unpack_R_SNORM8; - table[MESA_FORMAT_R8G8_SNORM] = unpack_R8G8_SNORM; - table[MESA_FORMAT_X8B8G8R8_SNORM] = unpack_X8B8G8R8_SNORM; - table[MESA_FORMAT_A8B8G8R8_SNORM] = unpack_A8B8G8R8_SNORM; - table[MESA_FORMAT_R8G8B8A8_SNORM] = unpack_R8G8B8A8_SNORM; - table[MESA_FORMAT_R_SNORM16] = unpack_R_SNORM16; - table[MESA_FORMAT_R16G16_SNORM] = unpack_R16G16_SNORM; - table[MESA_FORMAT_RGB_SNORM16] = unpack_RGB_SNORM16; - table[MESA_FORMAT_RGBA_SNORM16] = unpack_RGBA_SNORM16; - table[MESA_FORMAT_RGBA_UNORM16] = unpack_RGBA_16; - - table[MESA_FORMAT_R_RGTC1_UNORM] = unpack_RED_RGTC1; - table[MESA_FORMAT_R_RGTC1_SNORM] = unpack_SIGNED_RED_RGTC1; - table[MESA_FORMAT_RG_RGTC2_UNORM] = unpack_RG_RGTC2; - table[MESA_FORMAT_RG_RGTC2_SNORM] = unpack_SIGNED_RG_RGTC2; - - table[MESA_FORMAT_L_LATC1_UNORM] = unpack_L_LATC1; - table[MESA_FORMAT_L_LATC1_SNORM] = unpack_SIGNED_L_LATC1; - table[MESA_FORMAT_LA_LATC2_UNORM] = unpack_LA_LATC2; - table[MESA_FORMAT_LA_LATC2_SNORM] = unpack_SIGNED_LA_LATC2; - - table[MESA_FORMAT_ETC1_RGB8] = unpack_ETC1_RGB8; - table[MESA_FORMAT_ETC2_RGB8] = unpack_ETC2_RGB8; - table[MESA_FORMAT_ETC2_SRGB8] = unpack_ETC2_SRGB8; - table[MESA_FORMAT_ETC2_RGBA8_EAC] = unpack_ETC2_RGBA8_EAC; - table[MESA_FORMAT_ETC2_SRGB8_ALPHA8_EAC] = unpack_ETC2_SRGB8_ALPHA8_EAC; - table[MESA_FORMAT_ETC2_R11_EAC] = unpack_ETC2_R11_EAC; - table[MESA_FORMAT_ETC2_RG11_EAC] = unpack_ETC2_RG11_EAC; - table[MESA_FORMAT_ETC2_SIGNED_R11_EAC] = unpack_ETC2_SIGNED_R11_EAC; - table[MESA_FORMAT_ETC2_SIGNED_RG11_EAC] = unpack_ETC2_SIGNED_RG11_EAC; - table[MESA_FORMAT_ETC2_RGB8_PUNCHTHROUGH_ALPHA1] = - unpack_ETC2_RGB8_PUNCHTHROUGH_ALPHA1; - table[MESA_FORMAT_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1] = - unpack_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1; - table[MESA_FORMAT_A_SNORM8] = unpack_A_SNORM8; - table[MESA_FORMAT_L_SNORM8] = unpack_L_SNORM8; - table[MESA_FORMAT_L8A8_SNORM] = unpack_L8A8_SNORM; - table[MESA_FORMAT_A8L8_SNORM] = unpack_A8L8_SNORM; - table[MESA_FORMAT_I_SNORM8] = unpack_I_SNORM8; - table[MESA_FORMAT_A_SNORM16] = unpack_A_SNORM16; - table[MESA_FORMAT_L_SNORM16] = unpack_L_SNORM16; - table[MESA_FORMAT_LA_SNORM16] = unpack_LA_SNORM16; - table[MESA_FORMAT_I_SNORM16] = unpack_I_SNORM16; - - table[MESA_FORMAT_R9G9B9E5_FLOAT] = unpack_R9G9B9E5_FLOAT; - table[MESA_FORMAT_R11G11B10_FLOAT] = unpack_R11G11B10_FLOAT; - - table[MESA_FORMAT_Z_FLOAT32] = unpack_Z_FLOAT32; - table[MESA_FORMAT_Z32_FLOAT_S8X24_UINT] = unpack_Z32_FLOAT_S8X24_UINT; - - table[MESA_FORMAT_B4G4R4X4_UNORM] = unpack_XRGB4444_UNORM; - table[MESA_FORMAT_B5G5R5X1_UNORM] = unpack_XRGB1555_UNORM; - table[MESA_FORMAT_R8G8B8X8_SNORM] = unpack_R8G8B8X8_SNORM; - table[MESA_FORMAT_R8G8B8X8_SRGB] = unpack_R8G8B8X8_SRGB; - table[MESA_FORMAT_X8B8G8R8_SRGB] = unpack_X8B8G8R8_SRGB; - table[MESA_FORMAT_RGBX_UINT8] = unpack_XBGR8888_UINT; - table[MESA_FORMAT_RGBX_SINT8] = unpack_XBGR8888_SINT; - table[MESA_FORMAT_B10G10R10X2_UNORM] = unpack_B10G10R10X2_UNORM; - table[MESA_FORMAT_RGBX_UNORM16] = unpack_RGBX_UNORM16; - table[MESA_FORMAT_RGBX_SNORM16] = unpack_RGBX_SNORM16; - table[MESA_FORMAT_RGBX_FLOAT16] = unpack_XBGR16161616_FLOAT; - table[MESA_FORMAT_RGBX_UINT16] = unpack_XBGR16161616_UINT; - table[MESA_FORMAT_RGBX_SINT16] = unpack_XBGR16161616_SINT; - table[MESA_FORMAT_RGBX_FLOAT32] = unpack_RGBX_FLOAT32; - table[MESA_FORMAT_RGBX_UINT32] = unpack_XBGR32323232_UINT; - table[MESA_FORMAT_RGBX_SINT32] = unpack_XBGR32323232_SINT; - - table[MESA_FORMAT_R10G10B10A2_UNORM] = unpack_R10G10B10A2_UNORM; - - table[MESA_FORMAT_G8R8_SNORM] = unpack_G8R8_SNORM; - table[MESA_FORMAT_G16R16_SNORM] = unpack_G16R16_SNORM; - - table[MESA_FORMAT_B8G8R8X8_SRGB] = unpack_B8G8R8X8_SRGB; - table[MESA_FORMAT_X8R8G8B8_SRGB] = unpack_X8R8G8B8_SRGB; - - initialized = GL_TRUE; - } - - if (table[format] == NULL) { - _mesa_problem(NULL, "unsupported unpack for format %s", - _mesa_get_format_name(format)); - } - - return table[format]; -} - - -/** - * Unpack rgba colors, returning as GLfloat values. - */ -void -_mesa_unpack_rgba_row(mesa_format format, GLuint n, - const void *src, GLfloat dst[][4]) -{ - unpack_rgba_func unpack = get_unpack_rgba_function(format); - unpack(src, dst, n); -} - - -/**********************************************************************/ -/* Unpack, returning GLubyte colors */ -/**********************************************************************/ - - -static void -unpack_ubyte_A8B8G8R8_UNORM(const void *src, GLubyte dst[][4], GLuint n) -{ - const GLuint *s = ((const GLuint *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = (s[i] >> 24); - dst[i][GCOMP] = (s[i] >> 16) & 0xff; - dst[i][BCOMP] = (s[i] >> 8) & 0xff; - dst[i][ACOMP] = (s[i] ) & 0xff; - } -} - -static void -unpack_ubyte_R8G8B8A8_UNORM(const void *src, GLubyte dst[][4], GLuint n) -{ - const GLuint *s = ((const GLuint *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = (s[i] ) & 0xff; - dst[i][GCOMP] = (s[i] >> 8) & 0xff; - dst[i][BCOMP] = (s[i] >> 16) & 0xff; - dst[i][ACOMP] = (s[i] >> 24); - } -} - -static void -unpack_ubyte_B8G8R8A8_UNORM(const void *src, GLubyte dst[][4], GLuint n) -{ - const GLuint *s = ((const GLuint *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = (s[i] >> 16) & 0xff; - dst[i][GCOMP] = (s[i] >> 8) & 0xff; - dst[i][BCOMP] = (s[i] ) & 0xff; - dst[i][ACOMP] = (s[i] >> 24); - } -} - -static void -unpack_ubyte_A8R8G8B8_UNORM(const void *src, GLubyte dst[][4], GLuint n) -{ - const GLuint *s = ((const GLuint *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = (s[i] >> 8) & 0xff; - dst[i][GCOMP] = (s[i] >> 16) & 0xff; - dst[i][BCOMP] = (s[i] >> 24); - dst[i][ACOMP] = (s[i] ) & 0xff; - } -} - -static void -unpack_ubyte_RGBX8888(const void *src, GLubyte dst[][4], GLuint n) -{ - const GLuint *s = ((const GLuint *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = (s[i] >> 24); - dst[i][GCOMP] = (s[i] >> 16) & 0xff; - dst[i][BCOMP] = (s[i] >> 8) & 0xff; - dst[i][ACOMP] = 0xff; - } -} - -static void -unpack_ubyte_RGBX8888_REV(const void *src, GLubyte dst[][4], GLuint n) -{ - const GLuint *s = ((const GLuint *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = (s[i] ) & 0xff; - dst[i][GCOMP] = (s[i] >> 8) & 0xff; - dst[i][BCOMP] = (s[i] >> 16) & 0xff; - dst[i][ACOMP] = 0xff; - } -} - -static void -unpack_ubyte_B8G8R8X8_UNORM(const void *src, GLubyte dst[][4], GLuint n) -{ - const GLuint *s = ((const GLuint *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = (s[i] >> 16) & 0xff; - dst[i][GCOMP] = (s[i] >> 8) & 0xff; - dst[i][BCOMP] = (s[i] ) & 0xff; - dst[i][ACOMP] = 0xff; - } -} - -static void -unpack_ubyte_X8R8G8B8_UNORM(const void *src, GLubyte dst[][4], GLuint n) -{ - const GLuint *s = ((const GLuint *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = (s[i] >> 8) & 0xff; - dst[i][GCOMP] = (s[i] >> 16) & 0xff; - dst[i][BCOMP] = (s[i] >> 24); - dst[i][ACOMP] = 0xff; - } -} - -static void -unpack_ubyte_BGR_UNORM8(const void *src, GLubyte dst[][4], GLuint n) -{ - const GLubyte *s = (const GLubyte *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = s[i*3+2]; - dst[i][GCOMP] = s[i*3+1]; - dst[i][BCOMP] = s[i*3+0]; - dst[i][ACOMP] = 0xff; - } -} - -static void -unpack_ubyte_RGB_UNORM8(const void *src, GLubyte dst[][4], GLuint n) -{ - const GLubyte *s = (const GLubyte *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = s[i*3+0]; - dst[i][GCOMP] = s[i*3+1]; - dst[i][BCOMP] = s[i*3+2]; - dst[i][ACOMP] = 0xff; - } -} - -static void -unpack_ubyte_B5G6R5_UNORM(const void *src, GLubyte dst[][4], GLuint n) -{ - const GLushort *s = ((const GLushort *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = EXPAND_5_8((s[i] >> 11) & 0x1f); - dst[i][GCOMP] = EXPAND_6_8((s[i] >> 5 ) & 0x3f); - dst[i][BCOMP] = EXPAND_5_8( s[i] & 0x1f); - dst[i][ACOMP] = 0xff; - } -} - -static void -unpack_ubyte_R5G6B5_UNORM(const void *src, GLubyte dst[][4], GLuint n) -{ - /* Warning: this function does not match the current Mesa definition - * of MESA_FORMAT_R5G6B5_UNORM. - */ - const GLushort *s = ((const GLushort *) src); - GLuint i; - for (i = 0; i < n; i++) { - GLuint t = (s[i] >> 8) | (s[i] << 8); /* byte swap */ - dst[i][RCOMP] = EXPAND_5_8((t >> 11) & 0x1f); - dst[i][GCOMP] = EXPAND_6_8((t >> 5 ) & 0x3f); - dst[i][BCOMP] = EXPAND_5_8( t & 0x1f); - dst[i][ACOMP] = 0xff; - } -} - -static void -unpack_ubyte_B4G4R4A4_UNORM(const void *src, GLubyte dst[][4], GLuint n) -{ - const GLushort *s = ((const GLushort *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = EXPAND_4_8((s[i] >> 8) & 0xf); - dst[i][GCOMP] = EXPAND_4_8((s[i] >> 4) & 0xf); - dst[i][BCOMP] = EXPAND_4_8((s[i] ) & 0xf); - dst[i][ACOMP] = EXPAND_4_8((s[i] >> 12) & 0xf); - } -} - -static void -unpack_ubyte_A4R4G4B4_UNORM(const void *src, GLubyte dst[][4], GLuint n) -{ - const GLushort *s = ((const GLushort *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = EXPAND_4_8((s[i] >> 4) & 0xf); - dst[i][GCOMP] = EXPAND_4_8((s[i] >> 8) & 0xf); - dst[i][BCOMP] = EXPAND_4_8((s[i] >> 12) & 0xf); - dst[i][ACOMP] = EXPAND_4_8((s[i] ) & 0xf); - } -} - -static void -unpack_ubyte_A1B5G5R5_UNORM(const void *src, GLubyte dst[][4], GLuint n) -{ - const GLushort *s = ((const GLushort *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = EXPAND_5_8((s[i] >> 11) & 0x1f); - dst[i][GCOMP] = EXPAND_5_8((s[i] >> 6) & 0x1f); - dst[i][BCOMP] = EXPAND_5_8((s[i] >> 1) & 0x1f); - dst[i][ACOMP] = EXPAND_1_8((s[i] ) & 0x01); - } -} - -static void -unpack_ubyte_B5G5R5A1_UNORM(const void *src, GLubyte dst[][4], GLuint n) -{ - const GLushort *s = ((const GLushort *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = EXPAND_5_8((s[i] >> 10) & 0x1f); - dst[i][GCOMP] = EXPAND_5_8((s[i] >> 5) & 0x1f); - dst[i][BCOMP] = EXPAND_5_8((s[i] >> 0) & 0x1f); - dst[i][ACOMP] = EXPAND_1_8((s[i] >> 15) & 0x01); - } -} - -static void -unpack_ubyte_A1R5G5B5_UNORM(const void *src, GLubyte dst[][4], GLuint n) -{ - /* Warning: this function does not match the current Mesa definition - * of MESA_FORMAT_A1R5G5B5_UNORM. - */ - const GLushort *s = ((const GLushort *) src); - GLuint i; - for (i = 0; i < n; i++) { - GLushort tmp = (s[i] << 8) | (s[i] >> 8); /* byteswap */ - dst[i][RCOMP] = EXPAND_5_8((tmp >> 10) & 0x1f); - dst[i][GCOMP] = EXPAND_5_8((tmp >> 5) & 0x1f); - dst[i][BCOMP] = EXPAND_5_8((tmp >> 0) & 0x1f); - dst[i][ACOMP] = EXPAND_1_8((tmp >> 15) & 0x01); - } -} - -static void -unpack_ubyte_L4A4_UNORM(const void *src, GLubyte dst[][4], GLuint n) -{ - const GLubyte *s = ((const GLubyte *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = - dst[i][GCOMP] = - dst[i][BCOMP] = EXPAND_4_8(s[i] & 0xf); - dst[i][ACOMP] = EXPAND_4_8(s[i] >> 4); - } -} - -static void -unpack_ubyte_L8A8_UNORM(const void *src, GLubyte dst[][4], GLuint n) -{ - const GLushort *s = ((const GLushort *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = - dst[i][GCOMP] = - dst[i][BCOMP] = EXPAND_4_8(s[i] & 0xff); - dst[i][ACOMP] = EXPAND_4_8(s[i] >> 8); - } -} - -static void -unpack_ubyte_A8L8_UNORM(const void *src, GLubyte dst[][4], GLuint n) -{ - const GLushort *s = ((const GLushort *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = - dst[i][GCOMP] = - dst[i][BCOMP] = EXPAND_4_8(s[i] >> 8); - dst[i][ACOMP] = EXPAND_4_8(s[i] & 0xff); - } -} - -static void -unpack_ubyte_B2G3R3_UNORM(const void *src, GLubyte dst[][4], GLuint n) -{ - const GLubyte *s = ((const GLubyte *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = EXPAND_3_8((s[i] >> 5) & 0x7); - dst[i][GCOMP] = EXPAND_3_8((s[i] >> 2) & 0x7); - dst[i][BCOMP] = EXPAND_2_8((s[i] ) & 0x3); - dst[i][ACOMP] = 0xff; - } -} - -static void -unpack_ubyte_A_UNORM8(const void *src, GLubyte dst[][4], GLuint n) -{ - const GLubyte *s = ((const GLubyte *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = - dst[i][GCOMP] = - dst[i][BCOMP] = 0; - dst[i][ACOMP] = s[i]; - } -} - -static void -unpack_ubyte_L_UNORM8(const void *src, GLubyte dst[][4], GLuint n) -{ - const GLubyte *s = ((const GLubyte *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = - dst[i][GCOMP] = - dst[i][BCOMP] = s[i]; - dst[i][ACOMP] = 0xff; - } -} - - -static void -unpack_ubyte_I_UNORM8(const void *src, GLubyte dst[][4], GLuint n) -{ - const GLubyte *s = ((const GLubyte *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = - dst[i][GCOMP] = - dst[i][BCOMP] = - dst[i][ACOMP] = s[i]; - } -} - -static void -unpack_ubyte_R_UNORM8(const void *src, GLubyte dst[][4], GLuint n) -{ - const GLubyte *s = ((const GLubyte *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][0] = s[i]; - dst[i][1] = - dst[i][2] = 0; - dst[i][3] = 0xff; - } -} - -static void -unpack_ubyte_R8G8_UNORM(const void *src, GLubyte dst[][4], GLuint n) -{ - const GLushort *s = ((const GLushort *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = s[i] & 0xff; - dst[i][GCOMP] = s[i] >> 8; - dst[i][BCOMP] = 0; - dst[i][ACOMP] = 0xff; - } -} - -static void -unpack_ubyte_G8R8_UNORM(const void *src, GLubyte dst[][4], GLuint n) -{ - const GLushort *s = ((const GLushort *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = s[i] >> 8; - dst[i][GCOMP] = s[i] & 0xff; - dst[i][BCOMP] = 0; - dst[i][ACOMP] = 0xff; - } -} - - -/** - * Unpack rgba colors, returning as GLubyte values. This should usually - * only be used for unpacking formats that use 8 bits or less per channel. - */ -void -_mesa_unpack_ubyte_rgba_row(mesa_format format, GLuint n, - const void *src, GLubyte dst[][4]) -{ - switch (format) { - case MESA_FORMAT_A8B8G8R8_UNORM: - unpack_ubyte_A8B8G8R8_UNORM(src, dst, n); - break; - case MESA_FORMAT_R8G8B8A8_UNORM: - unpack_ubyte_R8G8B8A8_UNORM(src, dst, n); - break; - case MESA_FORMAT_B8G8R8A8_UNORM: - unpack_ubyte_B8G8R8A8_UNORM(src, dst, n); - break; - case MESA_FORMAT_A8R8G8B8_UNORM: - unpack_ubyte_A8R8G8B8_UNORM(src, dst, n); - break; - case MESA_FORMAT_X8B8G8R8_UNORM: - unpack_ubyte_RGBX8888(src, dst, n); - break; - case MESA_FORMAT_R8G8B8X8_UNORM: - unpack_ubyte_RGBX8888_REV(src, dst, n); - break; - case MESA_FORMAT_B8G8R8X8_UNORM: - unpack_ubyte_B8G8R8X8_UNORM(src, dst, n); - break; - case MESA_FORMAT_X8R8G8B8_UNORM: - unpack_ubyte_X8R8G8B8_UNORM(src, dst, n); - break; - case MESA_FORMAT_BGR_UNORM8: - unpack_ubyte_BGR_UNORM8(src, dst, n); - break; - case MESA_FORMAT_RGB_UNORM8: - unpack_ubyte_RGB_UNORM8(src, dst, n); - break; - case MESA_FORMAT_B5G6R5_UNORM: - unpack_ubyte_B5G6R5_UNORM(src, dst, n); - break; - case MESA_FORMAT_R5G6B5_UNORM: - unpack_ubyte_R5G6B5_UNORM(src, dst, n); - break; - case MESA_FORMAT_B4G4R4A4_UNORM: - unpack_ubyte_B4G4R4A4_UNORM(src, dst, n); - break; - case MESA_FORMAT_A4R4G4B4_UNORM: - unpack_ubyte_A4R4G4B4_UNORM(src, dst, n); - break; - case MESA_FORMAT_A1B5G5R5_UNORM: - unpack_ubyte_A1B5G5R5_UNORM(src, dst, n); - break; - case MESA_FORMAT_B5G5R5A1_UNORM: - unpack_ubyte_B5G5R5A1_UNORM(src, dst, n); - break; - case MESA_FORMAT_A1R5G5B5_UNORM: - unpack_ubyte_A1R5G5B5_UNORM(src, dst, n); - break; - case MESA_FORMAT_L4A4_UNORM: - unpack_ubyte_L4A4_UNORM(src, dst, n); - break; - case MESA_FORMAT_L8A8_UNORM: - unpack_ubyte_L8A8_UNORM(src, dst, n); - break; - case MESA_FORMAT_A8L8_UNORM: - unpack_ubyte_A8L8_UNORM(src, dst, n); - break; - case MESA_FORMAT_B2G3R3_UNORM: - unpack_ubyte_B2G3R3_UNORM(src, dst, n); - break; - case MESA_FORMAT_A_UNORM8: - unpack_ubyte_A_UNORM8(src, dst, n); - break; - case MESA_FORMAT_L_UNORM8: - unpack_ubyte_L_UNORM8(src, dst, n); - break; - case MESA_FORMAT_I_UNORM8: - unpack_ubyte_I_UNORM8(src, dst, n); - break; - case MESA_FORMAT_R_UNORM8: - unpack_ubyte_R_UNORM8(src, dst, n); - break; - case MESA_FORMAT_R8G8_UNORM: - unpack_ubyte_R8G8_UNORM(src, dst, n); - break; - case MESA_FORMAT_G8R8_UNORM: - unpack_ubyte_G8R8_UNORM(src, dst, n); - break; - default: - /* get float values, convert to ubyte */ - { - GLfloat *tmp = malloc(n * 4 * sizeof(GLfloat)); - if (tmp) { - GLuint i; - _mesa_unpack_rgba_row(format, n, src, (GLfloat (*)[4]) tmp); - for (i = 0; i < n; i++) { - UNCLAMPED_FLOAT_TO_UBYTE(dst[i][0], tmp[i*4+0]); - UNCLAMPED_FLOAT_TO_UBYTE(dst[i][1], tmp[i*4+1]); - UNCLAMPED_FLOAT_TO_UBYTE(dst[i][2], tmp[i*4+2]); - UNCLAMPED_FLOAT_TO_UBYTE(dst[i][3], tmp[i*4+3]); - } - free(tmp); - } - } - break; - } -} - - -/**********************************************************************/ -/* Unpack, returning GLuint colors */ -/**********************************************************************/ - -static void -unpack_int_rgba_RGBA_UINT32(const GLuint *src, GLuint dst[][4], GLuint n) -{ - memcpy(dst, src, n * 4 * sizeof(GLuint)); -} - -static void -unpack_int_rgba_RGBA_UINT16(const GLushort *src, GLuint dst[][4], GLuint n) -{ - unsigned int i; - - for (i = 0; i < n; i++) { - dst[i][0] = src[i * 4 + 0]; - dst[i][1] = src[i * 4 + 1]; - dst[i][2] = src[i * 4 + 2]; - dst[i][3] = src[i * 4 + 3]; - } -} - -static void -unpack_int_rgba_RGBA_INT16(const GLshort *src, GLuint dst[][4], GLuint n) -{ - unsigned int i; - - for (i = 0; i < n; i++) { - dst[i][0] = src[i * 4 + 0]; - dst[i][1] = src[i * 4 + 1]; - dst[i][2] = src[i * 4 + 2]; - dst[i][3] = src[i * 4 + 3]; - } -} - -static void -unpack_int_rgba_RGBA_UINT8(const GLubyte *src, GLuint dst[][4], GLuint n) -{ - unsigned int i; - - for (i = 0; i < n; i++) { - dst[i][0] = src[i * 4 + 0]; - dst[i][1] = src[i * 4 + 1]; - dst[i][2] = src[i * 4 + 2]; - dst[i][3] = src[i * 4 + 3]; - } -} - -static void -unpack_int_rgba_RGBA_INT8(const GLbyte *src, GLuint dst[][4], GLuint n) -{ - unsigned int i; - - for (i = 0; i < n; i++) { - dst[i][0] = src[i * 4 + 0]; - dst[i][1] = src[i * 4 + 1]; - dst[i][2] = src[i * 4 + 2]; - dst[i][3] = src[i * 4 + 3]; - } -} - -static void -unpack_int_rgba_B8G8R8A8_UNORM(const GLbyte *src, GLuint dst[][4], GLuint n) -{ - unsigned int i; - - for (i = 0; i < n; i++) { - dst[i][RCOMP] = (GLubyte) src[i * 4 + 2]; - dst[i][GCOMP] = (GLubyte) src[i * 4 + 1]; - dst[i][BCOMP] = (GLubyte) src[i * 4 + 0]; - dst[i][ACOMP] = (GLubyte) src[i * 4 + 3]; - } -} - -static void -unpack_int_rgba_B8G8R8X8_UNORM(const GLbyte *src, GLuint dst[][4], GLuint n) -{ - unsigned int i; - - for (i = 0; i < n; i++) { - dst[i][RCOMP] = (GLubyte) src[i * 4 + 2]; - dst[i][GCOMP] = (GLubyte) src[i * 4 + 1]; - dst[i][BCOMP] = (GLubyte) src[i * 4 + 0]; - dst[i][ACOMP] = (GLubyte) 0xff; - } -} - -static void -unpack_int_rgba_RGB_UINT32(const GLuint *src, GLuint dst[][4], GLuint n) -{ - unsigned int i; - - for (i = 0; i < n; i++) { - dst[i][0] = src[i * 3 + 0]; - dst[i][1] = src[i * 3 + 1]; - dst[i][2] = src[i * 3 + 2]; - dst[i][3] = 1; - } -} - -static void -unpack_int_rgba_RGB_UINT16(const GLushort *src, GLuint dst[][4], GLuint n) -{ - unsigned int i; - - for (i = 0; i < n; i++) { - dst[i][0] = src[i * 3 + 0]; - dst[i][1] = src[i * 3 + 1]; - dst[i][2] = src[i * 3 + 2]; - dst[i][3] = 1; - } -} - -static void -unpack_int_rgba_RGB_INT16(const GLshort *src, GLuint dst[][4], GLuint n) -{ - unsigned int i; - - for (i = 0; i < n; i++) { - dst[i][0] = src[i * 3 + 0]; - dst[i][1] = src[i * 3 + 1]; - dst[i][2] = src[i * 3 + 2]; - dst[i][3] = 1; - } -} - -static void -unpack_int_rgba_RGB_UINT8(const GLubyte *src, GLuint dst[][4], GLuint n) -{ - unsigned int i; - - for (i = 0; i < n; i++) { - dst[i][0] = src[i * 3 + 0]; - dst[i][1] = src[i * 3 + 1]; - dst[i][2] = src[i * 3 + 2]; - dst[i][3] = 1; - } -} - -static void -unpack_int_rgba_RGB_INT8(const GLbyte *src, GLuint dst[][4], GLuint n) -{ - unsigned int i; - - for (i = 0; i < n; i++) { - dst[i][0] = src[i * 3 + 0]; - dst[i][1] = src[i * 3 + 1]; - dst[i][2] = src[i * 3 + 2]; - dst[i][3] = 1; - } -} - -static void -unpack_int_rgba_RG_UINT32(const GLuint *src, GLuint dst[][4], GLuint n) -{ - unsigned int i; - - for (i = 0; i < n; i++) { - dst[i][0] = src[i * 2 + 0]; - dst[i][1] = src[i * 2 + 1]; - dst[i][2] = 0; - dst[i][3] = 1; - } -} - -static void -unpack_int_rgba_RG_UINT16(const GLushort *src, GLuint dst[][4], GLuint n) -{ - unsigned int i; - - for (i = 0; i < n; i++) { - dst[i][0] = src[i * 2 + 0]; - dst[i][1] = src[i * 2 + 1]; - dst[i][2] = 0; - dst[i][3] = 1; - } -} - -static void -unpack_int_rgba_RG_INT16(const GLshort *src, GLuint dst[][4], GLuint n) -{ - unsigned int i; - - for (i = 0; i < n; i++) { - dst[i][0] = src[i * 2 + 0]; - dst[i][1] = src[i * 2 + 1]; - dst[i][2] = 0; - dst[i][3] = 1; - } -} - -static void -unpack_int_rgba_RG_UINT8(const GLubyte *src, GLuint dst[][4], GLuint n) -{ - unsigned int i; - - for (i = 0; i < n; i++) { - dst[i][0] = src[i * 2 + 0]; - dst[i][1] = src[i * 2 + 1]; - dst[i][2] = 0; - dst[i][3] = 1; - } -} - -static void -unpack_int_rgba_RG_INT8(const GLbyte *src, GLuint dst[][4], GLuint n) -{ - unsigned int i; - - for (i = 0; i < n; i++) { - dst[i][0] = src[i * 2 + 0]; - dst[i][1] = src[i * 2 + 1]; - dst[i][2] = 0; - dst[i][3] = 1; - } -} - -static void -unpack_int_rgba_R_UINT32(const GLuint *src, GLuint dst[][4], GLuint n) -{ - unsigned int i; - - for (i = 0; i < n; i++) { - dst[i][0] = src[i]; - dst[i][1] = 0; - dst[i][2] = 0; - dst[i][3] = 1; - } -} - -static void -unpack_int_rgba_R_UINT16(const GLushort *src, GLuint dst[][4], GLuint n) -{ - unsigned int i; - - for (i = 0; i < n; i++) { - dst[i][0] = src[i]; - dst[i][1] = 0; - dst[i][2] = 0; - dst[i][3] = 1; - } -} - -static void -unpack_int_rgba_R_INT16(const GLshort *src, GLuint dst[][4], GLuint n) -{ - unsigned int i; - - for (i = 0; i < n; i++) { - dst[i][0] = src[i]; - dst[i][1] = 0; - dst[i][2] = 0; - dst[i][3] = 1; - } -} - -static void -unpack_int_rgba_R_UINT8(const GLubyte *src, GLuint dst[][4], GLuint n) -{ - unsigned int i; - - for (i = 0; i < n; i++) { - dst[i][0] = src[i]; - dst[i][1] = 0; - dst[i][2] = 0; - dst[i][3] = 1; - } -} - -static void -unpack_int_rgba_R_INT8(const GLbyte *src, GLuint dst[][4], GLuint n) -{ - unsigned int i; - - for (i = 0; i < n; i++) { - dst[i][0] = src[i]; - dst[i][1] = 0; - dst[i][2] = 0; - dst[i][3] = 1; - } -} - -static void -unpack_int_rgba_ALPHA_UINT32(const GLuint *src, GLuint dst[][4], GLuint n) -{ - unsigned int i; - - for (i = 0; i < n; i++) { - dst[i][0] = dst[i][1] = dst[i][2] = 0; - dst[i][3] = src[i]; - } -} - -static void -unpack_int_rgba_ALPHA_UINT16(const GLushort *src, GLuint dst[][4], GLuint n) -{ - unsigned int i; - - for (i = 0; i < n; i++) { - dst[i][0] = dst[i][1] = dst[i][2] = 0; - dst[i][3] = src[i]; - } -} - -static void -unpack_int_rgba_ALPHA_INT16(const GLshort *src, GLuint dst[][4], GLuint n) -{ - unsigned int i; - - for (i = 0; i < n; i++) { - dst[i][0] = dst[i][1] = dst[i][2] = 0; - dst[i][3] = src[i]; - } -} - -static void -unpack_int_rgba_ALPHA_UINT8(const GLubyte *src, GLuint dst[][4], GLuint n) -{ - unsigned int i; - - for (i = 0; i < n; i++) { - dst[i][0] = dst[i][1] = dst[i][2] = 0; - dst[i][3] = src[i]; - } -} - -static void -unpack_int_rgba_ALPHA_INT8(const GLbyte *src, GLuint dst[][4], GLuint n) -{ - unsigned int i; - - for (i = 0; i < n; i++) { - dst[i][0] = dst[i][1] = dst[i][2] = 0; - dst[i][3] = src[i]; - } -} - -static void -unpack_int_rgba_LUMINANCE_UINT32(const GLuint *src, GLuint dst[][4], GLuint n) -{ - unsigned int i; - - for (i = 0; i < n; i++) { - dst[i][0] = dst[i][1] = dst[i][2] = src[i]; - dst[i][3] = 1; - } -} - -static void -unpack_int_rgba_LUMINANCE_UINT16(const GLushort *src, GLuint dst[][4], GLuint n) -{ - unsigned int i; - - for (i = 0; i < n; i++) { - dst[i][0] = dst[i][1] = dst[i][2] = src[i]; - dst[i][3] = 1; - } -} - -static void -unpack_int_rgba_LUMINANCE_INT16(const GLshort *src, GLuint dst[][4], GLuint n) -{ - unsigned int i; - - for (i = 0; i < n; i++) { - dst[i][0] = dst[i][1] = dst[i][2] = src[i]; - dst[i][3] = 1; - } -} - -static void -unpack_int_rgba_LUMINANCE_UINT8(const GLubyte *src, GLuint dst[][4], GLuint n) -{ - unsigned int i; - - for (i = 0; i < n; i++) { - dst[i][0] = dst[i][1] = dst[i][2] = src[i]; - dst[i][3] = 1; - } -} - -static void -unpack_int_rgba_LUMINANCE_INT8(const GLbyte *src, GLuint dst[][4], GLuint n) -{ - unsigned int i; - - for (i = 0; i < n; i++) { - dst[i][0] = dst[i][1] = dst[i][2] = src[i]; - dst[i][3] = 1; - } -} - - -static void -unpack_int_rgba_LUMINANCE_ALPHA_UINT32(const GLuint *src, GLuint dst[][4], GLuint n) -{ - unsigned int i; - - for (i = 0; i < n; i++) { - dst[i][0] = dst[i][1] = dst[i][2] = src[i * 2 + 0]; - dst[i][3] = src[i * 2 + 1]; - } -} - -static void -unpack_int_rgba_LUMINANCE_ALPHA_UINT16(const GLushort *src, GLuint dst[][4], GLuint n) -{ - unsigned int i; - - for (i = 0; i < n; i++) { - dst[i][0] = dst[i][1] = dst[i][2] = src[i * 2 + 0]; - dst[i][3] = src[i * 2 + 1]; - } -} - -static void -unpack_int_rgba_LUMINANCE_ALPHA_INT16(const GLshort *src, GLuint dst[][4], GLuint n) -{ - unsigned int i; - - for (i = 0; i < n; i++) { - dst[i][0] = dst[i][1] = dst[i][2] = src[i * 2 + 0]; - dst[i][3] = src[i * 2 + 1]; - } -} - -static void -unpack_int_rgba_LUMINANCE_ALPHA_UINT8(const GLubyte *src, GLuint dst[][4], GLuint n) -{ - unsigned int i; - - for (i = 0; i < n; i++) { - dst[i][0] = dst[i][1] = dst[i][2] = src[i * 2 + 0]; - dst[i][3] = src[i * 2 + 1]; - } -} - -static void -unpack_int_rgba_LUMINANCE_ALPHA_INT8(const GLbyte *src, GLuint dst[][4], GLuint n) -{ - unsigned int i; - - for (i = 0; i < n; i++) { - dst[i][0] = dst[i][1] = dst[i][2] = src[i * 2 + 0]; - dst[i][3] = src[i * 2 + 1]; - } -} - -static void -unpack_int_rgba_INTENSITY_UINT32(const GLuint *src, GLuint dst[][4], GLuint n) -{ - unsigned int i; - - for (i = 0; i < n; i++) { - dst[i][0] = dst[i][1] = dst[i][2] = dst[i][3] = src[i]; - } -} - -static void -unpack_int_rgba_INTENSITY_UINT16(const GLushort *src, GLuint dst[][4], GLuint n) -{ - unsigned int i; - - for (i = 0; i < n; i++) { - dst[i][0] = dst[i][1] = dst[i][2] = dst[i][3] = src[i]; - } -} - -static void -unpack_int_rgba_INTENSITY_INT16(const GLshort *src, GLuint dst[][4], GLuint n) -{ - unsigned int i; - - for (i = 0; i < n; i++) { - dst[i][0] = dst[i][1] = dst[i][2] = dst[i][3] = src[i]; - } -} - -static void -unpack_int_rgba_INTENSITY_UINT8(const GLubyte *src, GLuint dst[][4], GLuint n) -{ - unsigned int i; - - for (i = 0; i < n; i++) { - dst[i][0] = dst[i][1] = dst[i][2] = dst[i][3] = src[i]; - } -} - -static void -unpack_int_rgba_INTENSITY_INT8(const GLbyte *src, GLuint dst[][4], GLuint n) -{ - unsigned int i; - - for (i = 0; i < n; i++) { - dst[i][0] = dst[i][1] = dst[i][2] = dst[i][3] = src[i]; - } -} - -static void -unpack_int_rgba_B10G10R10A2_UINT(const GLuint *src, GLuint dst[][4], GLuint n) -{ - unsigned int i; - - for (i = 0; i < n; i++) { - GLuint tmp = src[i]; - dst[i][0] = (tmp >> 20) & 0x3ff; - dst[i][1] = (tmp >> 10) & 0x3ff; - dst[i][2] = (tmp >> 0) & 0x3ff; - dst[i][3] = (tmp >> 30) & 0x3; - } -} - -static void -unpack_int_rgba_R10G10B10A2_UINT(const GLuint *src, GLuint dst[][4], GLuint n) -{ - unsigned int i; - - for (i = 0; i < n; i++) { - GLuint tmp = src[i]; - dst[i][0] = (tmp >> 0) & 0x3ff; - dst[i][1] = (tmp >> 10) & 0x3ff; - dst[i][2] = (tmp >> 20) & 0x3ff; - dst[i][3] = (tmp >> 30) & 0x3; - } -} - -static void -unpack_int_rgba_B10G10R10A2_UNORM(const GLuint *src, GLuint dst[][4], GLuint n) -{ - unsigned int i; - - for (i = 0; i < n; i++) { - GLuint tmp = src[i]; - dst[i][0] = (tmp >> 20) & 0x3ff; - dst[i][1] = (tmp >> 10) & 0x3ff; - dst[i][2] = (tmp >> 0) & 0x3ff; - dst[i][3] = (tmp >> 30) & 0x3; - } -} - -static void -unpack_int_rgba_XBGR8888_UINT(const GLubyte *src, GLuint dst[][4], GLuint n) -{ - unsigned int i; - - for (i = 0; i < n; i++) { - dst[i][0] = src[i * 4 + 0]; - dst[i][1] = src[i * 4 + 1]; - dst[i][2] = src[i * 4 + 2]; - dst[i][3] = 1; - } -} - -static void -unpack_int_rgba_XBGR8888_SINT(const GLbyte *src, GLuint dst[][4], GLuint n) -{ - unsigned int i; - - for (i = 0; i < n; i++) { - dst[i][0] = src[i * 4 + 0]; - dst[i][1] = src[i * 4 + 1]; - dst[i][2] = src[i * 4 + 2]; - dst[i][3] = 1; - } -} - -static void -unpack_int_rgba_XBGR16161616_UINT(const GLushort *src, GLuint dst[][4], GLuint n) -{ - unsigned int i; - - for (i = 0; i < n; i++) { - dst[i][0] = src[i * 4 + 0]; - dst[i][1] = src[i * 4 + 1]; - dst[i][2] = src[i * 4 + 2]; - dst[i][3] = 1; - } -} - -static void -unpack_int_rgba_XBGR16161616_SINT(const GLshort *src, GLuint dst[][4], GLuint n) -{ - unsigned int i; - - for (i = 0; i < n; i++) { - dst[i][0] = src[i * 4 + 0]; - dst[i][1] = src[i * 4 + 1]; - dst[i][2] = src[i * 4 + 2]; - dst[i][3] = 1; - } -} - -static void -unpack_int_rgba_XBGR32323232_UINT(const GLuint *src, GLuint dst[][4], GLuint n) -{ - unsigned int i; - - for (i = 0; i < n; i++) { - dst[i][0] = src[i * 4 + 0]; - dst[i][1] = src[i * 4 + 1]; - dst[i][2] = src[i * 4 + 2]; - dst[i][3] = 1; - } -} - -static void -unpack_int_rgba_R10G10B10A2_UNORM(const GLuint *src, GLuint dst[][4], GLuint n) -{ - unsigned int i; - - for (i = 0; i < n; i++) { - GLuint tmp = src[i]; - dst[i][0] = (tmp >> 0) & 0x3ff; - dst[i][1] = (tmp >> 10) & 0x3ff; - dst[i][2] = (tmp >> 20) & 0x3ff; - dst[i][3] = (tmp >> 30) & 0x3; - } -} - -void -_mesa_unpack_uint_rgba_row(mesa_format format, GLuint n, - const void *src, GLuint dst[][4]) -{ - switch (format) { - /* Since there won't be any sign extension happening, there's no need to - * make separate paths for 32-bit-to-32-bit integer unpack. - */ - case MESA_FORMAT_RGBA_UINT32: - case MESA_FORMAT_RGBA_SINT32: - unpack_int_rgba_RGBA_UINT32(src, dst, n); - break; - - case MESA_FORMAT_RGBA_UINT16: - unpack_int_rgba_RGBA_UINT16(src, dst, n); - break; - case MESA_FORMAT_RGBA_SINT16: - unpack_int_rgba_RGBA_INT16(src, dst, n); - break; - - case MESA_FORMAT_RGBA_UINT8: - unpack_int_rgba_RGBA_UINT8(src, dst, n); - break; - case MESA_FORMAT_RGBA_SINT8: - unpack_int_rgba_RGBA_INT8(src, dst, n); - break; - - case MESA_FORMAT_B8G8R8A8_UNORM: - unpack_int_rgba_B8G8R8A8_UNORM(src, dst, n); - break; - - case MESA_FORMAT_B8G8R8X8_UNORM: - unpack_int_rgba_B8G8R8X8_UNORM(src, dst, n); - break; - - case MESA_FORMAT_RGB_UINT32: - case MESA_FORMAT_RGB_SINT32: - unpack_int_rgba_RGB_UINT32(src, dst, n); - break; - - case MESA_FORMAT_RGB_UINT16: - unpack_int_rgba_RGB_UINT16(src, dst, n); - break; - case MESA_FORMAT_RGB_SINT16: - unpack_int_rgba_RGB_INT16(src, dst, n); - break; - - case MESA_FORMAT_RGB_UINT8: - unpack_int_rgba_RGB_UINT8(src, dst, n); - break; - case MESA_FORMAT_RGB_SINT8: - unpack_int_rgba_RGB_INT8(src, dst, n); - break; - - case MESA_FORMAT_RG_UINT32: - case MESA_FORMAT_RG_SINT32: - unpack_int_rgba_RG_UINT32(src, dst, n); - break; - - case MESA_FORMAT_RG_UINT16: - unpack_int_rgba_RG_UINT16(src, dst, n); - break; - case MESA_FORMAT_RG_SINT16: - unpack_int_rgba_RG_INT16(src, dst, n); - break; - - case MESA_FORMAT_RG_UINT8: - unpack_int_rgba_RG_UINT8(src, dst, n); - break; - case MESA_FORMAT_RG_SINT8: - unpack_int_rgba_RG_INT8(src, dst, n); - break; - - case MESA_FORMAT_R_UINT32: - case MESA_FORMAT_R_SINT32: - unpack_int_rgba_R_UINT32(src, dst, n); - break; - - case MESA_FORMAT_R_UINT16: - unpack_int_rgba_R_UINT16(src, dst, n); - break; - case MESA_FORMAT_R_SINT16: - unpack_int_rgba_R_INT16(src, dst, n); - break; - - case MESA_FORMAT_R_UINT8: - unpack_int_rgba_R_UINT8(src, dst, n); - break; - case MESA_FORMAT_R_SINT8: - unpack_int_rgba_R_INT8(src, dst, n); - break; - - case MESA_FORMAT_A_UINT32: - case MESA_FORMAT_A_SINT32: - unpack_int_rgba_ALPHA_UINT32(src, dst, n); - break; - - case MESA_FORMAT_A_UINT16: - unpack_int_rgba_ALPHA_UINT16(src, dst, n); - break; - case MESA_FORMAT_A_SINT16: - unpack_int_rgba_ALPHA_INT16(src, dst, n); - break; - - case MESA_FORMAT_A_UINT8: - unpack_int_rgba_ALPHA_UINT8(src, dst, n); - break; - case MESA_FORMAT_A_SINT8: - unpack_int_rgba_ALPHA_INT8(src, dst, n); - break; - - case MESA_FORMAT_L_UINT32: - case MESA_FORMAT_L_SINT32: - unpack_int_rgba_LUMINANCE_UINT32(src, dst, n); - break; - case MESA_FORMAT_L_UINT16: - unpack_int_rgba_LUMINANCE_UINT16(src, dst, n); - break; - case MESA_FORMAT_L_SINT16: - unpack_int_rgba_LUMINANCE_INT16(src, dst, n); - break; - - case MESA_FORMAT_L_UINT8: - unpack_int_rgba_LUMINANCE_UINT8(src, dst, n); - break; - case MESA_FORMAT_L_SINT8: - unpack_int_rgba_LUMINANCE_INT8(src, dst, n); - break; - - case MESA_FORMAT_LA_UINT32: - case MESA_FORMAT_LA_SINT32: - unpack_int_rgba_LUMINANCE_ALPHA_UINT32(src, dst, n); - break; - - case MESA_FORMAT_LA_UINT16: - unpack_int_rgba_LUMINANCE_ALPHA_UINT16(src, dst, n); - break; - case MESA_FORMAT_LA_SINT16: - unpack_int_rgba_LUMINANCE_ALPHA_INT16(src, dst, n); - break; - - case MESA_FORMAT_LA_UINT8: - unpack_int_rgba_LUMINANCE_ALPHA_UINT8(src, dst, n); - break; - case MESA_FORMAT_LA_SINT8: - unpack_int_rgba_LUMINANCE_ALPHA_INT8(src, dst, n); - break; - - case MESA_FORMAT_I_UINT32: - case MESA_FORMAT_I_SINT32: - unpack_int_rgba_INTENSITY_UINT32(src, dst, n); - break; - - case MESA_FORMAT_I_UINT16: - unpack_int_rgba_INTENSITY_UINT16(src, dst, n); - break; - case MESA_FORMAT_I_SINT16: - unpack_int_rgba_INTENSITY_INT16(src, dst, n); - break; - - case MESA_FORMAT_I_UINT8: - unpack_int_rgba_INTENSITY_UINT8(src, dst, n); - break; - case MESA_FORMAT_I_SINT8: - unpack_int_rgba_INTENSITY_INT8(src, dst, n); - break; - - case MESA_FORMAT_B10G10R10A2_UINT: - unpack_int_rgba_B10G10R10A2_UINT(src, dst, n); - break; - - case MESA_FORMAT_R10G10B10A2_UINT: - unpack_int_rgba_R10G10B10A2_UINT(src, dst, n); - break; - - case MESA_FORMAT_B10G10R10A2_UNORM: - unpack_int_rgba_B10G10R10A2_UNORM(src, dst, n); - break; - - case MESA_FORMAT_RGBX_UINT8: - unpack_int_rgba_XBGR8888_UINT(src, dst, n); - break; - - case MESA_FORMAT_RGBX_SINT8: - unpack_int_rgba_XBGR8888_SINT(src, dst, n); - break; - - case MESA_FORMAT_RGBX_UINT16: - unpack_int_rgba_XBGR16161616_UINT(src, dst, n); - break; - - case MESA_FORMAT_RGBX_SINT16: - unpack_int_rgba_XBGR16161616_SINT(src, dst, n); - break; - - case MESA_FORMAT_RGBX_UINT32: - case MESA_FORMAT_RGBX_SINT32: - unpack_int_rgba_XBGR32323232_UINT(src, dst, n); - break; - - case MESA_FORMAT_R10G10B10A2_UNORM: - unpack_int_rgba_R10G10B10A2_UNORM(src, dst, n); - break; - - default: - _mesa_problem(NULL, "%s: bad format %s", __FUNCTION__, - _mesa_get_format_name(format)); - return; - } -} - -/** - * Unpack a 2D rect of pixels returning float RGBA colors. - * \param format the source image format - * \param src start address of the source image - * \param srcRowStride source image row stride in bytes - * \param dst start address of the dest image - * \param dstRowStride dest image row stride in bytes - * \param x source image start X pos - * \param y source image start Y pos - * \param width width of rect region to convert - * \param height height of rect region to convert - */ -void -_mesa_unpack_rgba_block(mesa_format format, - const void *src, GLint srcRowStride, - GLfloat dst[][4], GLint dstRowStride, - GLuint x, GLuint y, GLuint width, GLuint height) -{ - unpack_rgba_func unpack = get_unpack_rgba_function(format); - const GLuint srcPixStride = _mesa_get_format_bytes(format); - const GLuint dstPixStride = 4 * sizeof(GLfloat); - const GLubyte *srcRow; - GLubyte *dstRow; - GLuint i; - - /* XXX needs to be fixed for compressed formats */ - - srcRow = ((const GLubyte *) src) + srcRowStride * y + srcPixStride * x; - dstRow = ((GLubyte *) dst) + dstRowStride * y + dstPixStride * x; - - for (i = 0; i < height; i++) { - unpack(srcRow, (GLfloat (*)[4]) dstRow, width); - - dstRow += dstRowStride; - srcRow += srcRowStride; - } -} - - - - -typedef void (*unpack_float_z_func)(GLuint n, const void *src, GLfloat *dst); - -static void -unpack_float_z_X8_UINT_Z24_UNORM(GLuint n, const void *src, GLfloat *dst) -{ - /* only return Z, not stencil data */ - const GLuint *s = ((const GLuint *) src); - const GLdouble scale = 1.0 / (GLdouble) 0xffffff; - GLuint i; - for (i = 0; i < n; i++) { - dst[i] = (GLfloat) ((s[i] >> 8) * scale); - ASSERT(dst[i] >= 0.0F); - ASSERT(dst[i] <= 1.0F); - } -} - -static void -unpack_float_z_Z24_UNORM_X8_UINT(GLuint n, const void *src, GLfloat *dst) -{ - /* only return Z, not stencil data */ - const GLuint *s = ((const GLuint *) src); - const GLdouble scale = 1.0 / (GLdouble) 0xffffff; - GLuint i; - for (i = 0; i < n; i++) { - dst[i] = (GLfloat) ((s[i] & 0x00ffffff) * scale); - ASSERT(dst[i] >= 0.0F); - ASSERT(dst[i] <= 1.0F); - } -} - -static void -unpack_float_Z_UNORM16(GLuint n, const void *src, GLfloat *dst) -{ - const GLushort *s = ((const GLushort *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i] = s[i] * (1.0F / 65535.0F); - } -} - -static void -unpack_float_Z_UNORM32(GLuint n, const void *src, GLfloat *dst) -{ - const GLuint *s = ((const GLuint *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i] = s[i] * (1.0F / 0xffffffff); - } -} - -static void -unpack_float_Z_FLOAT32(GLuint n, const void *src, GLfloat *dst) -{ - memcpy(dst, src, n * sizeof(float)); -} - -static void -unpack_float_z_Z32X24S8(GLuint n, const void *src, GLfloat *dst) -{ - const struct z32f_x24s8 *s = (const struct z32f_x24s8 *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i] = s[i].z; - } -} - - - -/** - * Unpack Z values. - * The returned values will always be in the range [0.0, 1.0]. - */ -void -_mesa_unpack_float_z_row(mesa_format format, GLuint n, - const void *src, GLfloat *dst) -{ - unpack_float_z_func unpack; - - switch (format) { - case MESA_FORMAT_S8_UINT_Z24_UNORM: - case MESA_FORMAT_X8_UINT_Z24_UNORM: - unpack = unpack_float_z_X8_UINT_Z24_UNORM; - break; - case MESA_FORMAT_Z24_UNORM_S8_UINT: - case MESA_FORMAT_Z24_UNORM_X8_UINT: - unpack = unpack_float_z_Z24_UNORM_X8_UINT; - break; - case MESA_FORMAT_Z_UNORM16: - unpack = unpack_float_Z_UNORM16; - break; - case MESA_FORMAT_Z_UNORM32: - unpack = unpack_float_Z_UNORM32; - break; - case MESA_FORMAT_Z_FLOAT32: - unpack = unpack_float_Z_FLOAT32; - break; - case MESA_FORMAT_Z32_FLOAT_S8X24_UINT: - unpack = unpack_float_z_Z32X24S8; - break; - default: - _mesa_problem(NULL, "bad format %s in _mesa_unpack_float_z_row", - _mesa_get_format_name(format)); - return; - } - - unpack(n, src, dst); -} - - - -typedef void (*unpack_uint_z_func)(const void *src, GLuint *dst, GLuint n); - -static void -unpack_uint_z_X8_UINT_Z24_UNORM(const void *src, GLuint *dst, GLuint n) -{ - /* only return Z, not stencil data */ - const GLuint *s = ((const GLuint *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i] = (s[i] & 0xffffff00) | (s[i] >> 24); - } -} - -static void -unpack_uint_z_Z24_UNORM_X8_UINT(const void *src, GLuint *dst, GLuint n) -{ - /* only return Z, not stencil data */ - const GLuint *s = ((const GLuint *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i] = (s[i] << 8) | ((s[i] >> 16) & 0xff); - } -} - -static void -unpack_uint_Z_UNORM16(const void *src, GLuint *dst, GLuint n) -{ - const GLushort *s = ((const GLushort *)src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i] = (s[i] << 16) | s[i]; - } -} - -static void -unpack_uint_Z_UNORM32(const void *src, GLuint *dst, GLuint n) -{ - memcpy(dst, src, n * sizeof(GLuint)); -} - -static void -unpack_uint_Z_FLOAT32(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(CLAMP(s[i], 0.0F, 1.0F)); - } -} - -static void -unpack_uint_Z_FLOAT32_X24S8(const void *src, GLuint *dst, GLuint n) -{ - const struct z32f_x24s8 *s = (const struct z32f_x24s8 *) src; - GLuint i; - - for (i = 0; i < n; i++) { - dst[i] = FLOAT_TO_UINT(CLAMP(s[i].z, 0.0F, 1.0F)); - } -} - - -/** - * Unpack Z values. - * The returned values will always be in the range [0, 0xffffffff]. - */ -void -_mesa_unpack_uint_z_row(mesa_format format, GLuint n, - const void *src, GLuint *dst) -{ - unpack_uint_z_func unpack; - const GLubyte *srcPtr = (GLubyte *) src; - - switch (format) { - case MESA_FORMAT_S8_UINT_Z24_UNORM: - case MESA_FORMAT_X8_UINT_Z24_UNORM: - unpack = unpack_uint_z_X8_UINT_Z24_UNORM; - break; - case MESA_FORMAT_Z24_UNORM_S8_UINT: - case MESA_FORMAT_Z24_UNORM_X8_UINT: - unpack = unpack_uint_z_Z24_UNORM_X8_UINT; - break; - case MESA_FORMAT_Z_UNORM16: - unpack = unpack_uint_Z_UNORM16; - break; - case MESA_FORMAT_Z_UNORM32: - unpack = unpack_uint_Z_UNORM32; - break; - case MESA_FORMAT_Z_FLOAT32: - unpack = unpack_uint_Z_FLOAT32; - break; - case MESA_FORMAT_Z32_FLOAT_S8X24_UINT: - unpack = unpack_uint_Z_FLOAT32_X24S8; - break; - default: - _mesa_problem(NULL, "bad format %s in _mesa_unpack_uint_z_row", - _mesa_get_format_name(format)); - return; - } - - unpack(srcPtr, dst, n); -} - - -static void -unpack_ubyte_s_S_UINT8(const void *src, GLubyte *dst, GLuint n) -{ - memcpy(dst, src, n); -} - -static void -unpack_ubyte_s_S8_UINT_Z24_UNORM(const void *src, GLubyte *dst, GLuint n) -{ - GLuint i; - const GLuint *src32 = src; - - for (i = 0; i < n; i++) - dst[i] = src32[i] & 0xff; -} - -static void -unpack_ubyte_s_Z24_UNORM_S8_UINT(const void *src, GLubyte *dst, GLuint n) -{ - GLuint i; - const GLuint *src32 = src; - - for (i = 0; i < n; i++) - dst[i] = src32[i] >> 24; -} - -static void -unpack_ubyte_s_Z32_FLOAT_S8X24_UINT(const void *src, GLubyte *dst, GLuint n) -{ - GLuint i; - const struct z32f_x24s8 *s = (const struct z32f_x24s8 *) src; - - for (i = 0; i < n; i++) - dst[i] = s[i].x24s8 & 0xff; -} - -void -_mesa_unpack_ubyte_stencil_row(mesa_format format, GLuint n, - const void *src, GLubyte *dst) -{ - switch (format) { - case MESA_FORMAT_S_UINT8: - unpack_ubyte_s_S_UINT8(src, dst, n); - break; - case MESA_FORMAT_S8_UINT_Z24_UNORM: - unpack_ubyte_s_S8_UINT_Z24_UNORM(src, dst, n); - break; - case MESA_FORMAT_Z24_UNORM_S8_UINT: - unpack_ubyte_s_Z24_UNORM_S8_UINT(src, dst, n); - break; - case MESA_FORMAT_Z32_FLOAT_S8X24_UINT: - unpack_ubyte_s_Z32_FLOAT_S8X24_UINT(src, dst, n); - break; - default: - _mesa_problem(NULL, "bad format %s in _mesa_unpack_ubyte_s_row", - _mesa_get_format_name(format)); - return; - } -} - -static void -unpack_uint_24_8_depth_stencil_Z24_UNORM_S8_UINT(const GLuint *src, GLuint *dst, GLuint n) -{ - GLuint i; - - for (i = 0; i < n; i++) { - GLuint val = src[i]; - dst[i] = val >> 24 | val << 8; - } -} - -static void -unpack_uint_24_8_depth_stencil_Z32_S8X24(const GLuint *src, - GLuint *dst, GLuint n) -{ - GLuint i; - - for (i = 0; i < n; i++) { - /* 8 bytes per pixel (float + uint32) */ - GLfloat zf = ((GLfloat *) src)[i * 2 + 0]; - GLuint z24 = (GLuint) (zf * (GLfloat) 0xffffff); - GLuint s = src[i * 2 + 1] & 0xff; - dst[i] = (z24 << 8) | s; - } -} - -static void -unpack_uint_24_8_depth_stencil_S8_UINT_Z24_UNORM(const GLuint *src, GLuint *dst, GLuint n) -{ - memcpy(dst, src, n * 4); -} - -/** - * Unpack depth/stencil returning as GL_UNSIGNED_INT_24_8. - * \param format the source data format - */ -void -_mesa_unpack_uint_24_8_depth_stencil_row(mesa_format format, GLuint n, - const void *src, GLuint *dst) -{ - switch (format) { - case MESA_FORMAT_S8_UINT_Z24_UNORM: - unpack_uint_24_8_depth_stencil_S8_UINT_Z24_UNORM(src, dst, n); - break; - case MESA_FORMAT_Z24_UNORM_S8_UINT: - unpack_uint_24_8_depth_stencil_Z24_UNORM_S8_UINT(src, dst, n); - break; - case MESA_FORMAT_Z32_FLOAT_S8X24_UINT: - unpack_uint_24_8_depth_stencil_Z32_S8X24(src, dst, n); - break; - default: - _mesa_problem(NULL, - "bad format %s in _mesa_unpack_uint_24_8_depth_stencil_row", - _mesa_get_format_name(format)); - return; - } -} - -static void -unpack_float_32_uint_24_8_Z24_UNORM_S8_UINT(const GLuint *src, - GLuint *dst, GLuint n) -{ - GLuint i; - struct z32f_x24s8 *d = (struct z32f_x24s8 *) dst; - const GLdouble scale = 1.0 / (GLdouble) 0xffffff; - - for (i = 0; i < n; i++) { - const GLuint z24 = src[i] & 0xffffff; - d[i].z = z24 * scale; - d[i].x24s8 = src[i] >> 24; - assert(d[i].z >= 0.0f); - assert(d[i].z <= 1.0f); - } -} - -static void -unpack_float_32_uint_24_8_Z32_FLOAT_S8X24_UINT(const GLuint *src, - GLuint *dst, GLuint n) -{ - memcpy(dst, src, n * sizeof(struct z32f_x24s8)); -} - -static void -unpack_float_32_uint_24_8_S8_UINT_Z24_UNORM(const GLuint *src, - GLuint *dst, GLuint n) -{ - GLuint i; - struct z32f_x24s8 *d = (struct z32f_x24s8 *) dst; - const GLdouble scale = 1.0 / (GLdouble) 0xffffff; - - for (i = 0; i < n; i++) { - const GLuint z24 = src[i] >> 8; - d[i].z = z24 * scale; - d[i].x24s8 = src[i] & 0xff; - assert(d[i].z >= 0.0f); - assert(d[i].z <= 1.0f); - } -} - -/** - * Unpack depth/stencil returning as GL_FLOAT_32_UNSIGNED_INT_24_8_REV. - * \param format the source data format - * - * In GL_FLOAT_32_UNSIGNED_INT_24_8_REV lower 4 bytes contain float - * component and higher 4 bytes contain packed 24-bit and 8-bit - * components. - * - * 31 30 29 28 ... 4 3 2 1 0 31 30 29 ... 9 8 7 6 5 ... 2 1 0 - * +-------------------------+ +--------------------------------+ - * | Float Component | | Unused | 8 bit stencil | - * +-------------------------+ +--------------------------------+ - * lower 4 bytes higher 4 bytes - */ -void -_mesa_unpack_float_32_uint_24_8_depth_stencil_row(mesa_format format, GLuint n, - const void *src, GLuint *dst) -{ - switch (format) { - case MESA_FORMAT_S8_UINT_Z24_UNORM: - unpack_float_32_uint_24_8_S8_UINT_Z24_UNORM(src, dst, n); - break; - case MESA_FORMAT_Z24_UNORM_S8_UINT: - unpack_float_32_uint_24_8_Z24_UNORM_S8_UINT(src, dst, n); - break; - case MESA_FORMAT_Z32_FLOAT_S8X24_UINT: - unpack_float_32_uint_24_8_Z32_FLOAT_S8X24_UINT(src, dst, n); - break; - default: - _mesa_problem(NULL, - "bad format %s in _mesa_unpack_uint_24_8_depth_stencil_row", - _mesa_get_format_name(format)); - return; - } -} - -/** - * Unpack depth/stencil - * \param format the source data format - * \param type the destination data type - */ -void -_mesa_unpack_depth_stencil_row(mesa_format format, GLuint n, - const void *src, GLenum type, - GLuint *dst) -{ - assert(type == GL_UNSIGNED_INT_24_8 || - type == GL_FLOAT_32_UNSIGNED_INT_24_8_REV); - - switch (type) { - case GL_UNSIGNED_INT_24_8: - _mesa_unpack_uint_24_8_depth_stencil_row(format, n, src, dst); - break; - case GL_FLOAT_32_UNSIGNED_INT_24_8_REV: - _mesa_unpack_float_32_uint_24_8_depth_stencil_row(format, n, src, dst); - break; - default: - _mesa_problem(NULL, - "bad type 0x%x in _mesa_unpack_depth_stencil_row", - type); - return; - } -} diff --git a/mesalib/src/mesa/main/format_unpack.py b/mesalib/src/mesa/main/format_unpack.py new file mode 100644 index 000000000..2276a1063 --- /dev/null +++ b/mesalib/src/mesa/main/format_unpack.py @@ -0,0 +1,895 @@ +#!/usr/bin/env python + +from mako.template import Template +from sys import argv + +string = """/* + * Mesa 3-D graphics library + * + * Copyright (c) 2011 VMware, Inc. + * Copyright (c) 2014 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 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. + */ + + +/** + * Color, depth, stencil packing functions. + * Used to pack basic color, depth and stencil formats to specific + * hardware formats. + * + * There are both per-pixel and per-row packing functions: + * - The former will be used by swrast to write values to the color, depth, + * stencil buffers when drawing points, lines and masked spans. + * - The later will be used for image-oriented functions like glDrawPixels, + * glAccum, and glTexImage. + */ + +#include + +#include "colormac.h" +#include "format_unpack.h" +#include "format_utils.h" +#include "macros.h" +#include "../../gallium/auxiliary/util/u_format_rgb9e5.h" +#include "../../gallium/auxiliary/util/u_format_r11g11b10f.h" +#include "util/format_srgb.h" + +#define UNPACK(SRC, OFFSET, BITS) (((SRC) >> (OFFSET)) & MAX_UINT(BITS)) + +<% +import format_parser as parser + +formats = parser.parse(argv[1]) + +rgb_formats = [] +for f in formats: + if f.name == 'MESA_FORMAT_NONE': + continue + if f.colorspace not in ('rgb', 'srgb'): + continue + + rgb_formats.append(f) +%> + +/* float unpacking functions */ + +%for f in rgb_formats: + %if f.name in ('MESA_FORMAT_R9G9B9E5_FLOAT', 'MESA_FORMAT_R11G11B10_FLOAT'): + <% continue %> + %elif f.is_int() and not f.is_normalized(): + <% continue %> + %elif f.is_compressed(): + <% continue %> + %endif + +static inline void +unpack_float_${f.short_name()}(const void *void_src, GLfloat dst[4]) +{ + ${f.datatype()} *src = (${f.datatype()} *)void_src; + %if f.layout == parser.PACKED: + %for c in f.channels: + %if c.type != 'x': + ${c.datatype()} ${c.name} = UNPACK(*src, ${c.shift}, ${c.size}); + %endif + %endfor + %elif f.layout == parser.ARRAY: + %for (i, c) in enumerate(f.channels): + %if c.type != 'x': + ${c.datatype()} ${c.name} = src[${i}]; + %endif + %endfor + %else: + <% assert False %> + %endif + + %for i in range(4): + <% s = f.swizzle[i] %> + %if 0 <= s and s <= parser.Swizzle.SWIZZLE_W: + <% c = f.channels[s] %> + %if c.type == parser.UNSIGNED: + %if f.colorspace == 'srgb' and c.name in 'rgb': + <% assert c.size == 8 %> + dst[${i}] = util_format_srgb_8unorm_to_linear_float(${c.name}); + %else: + dst[${i}] = _mesa_unorm_to_float(${c.name}, ${c.size}); + %endif + %elif c.type == parser.SIGNED: + dst[${i}] = _mesa_snorm_to_float(${c.name}, ${c.size}); + %elif c.type == parser.FLOAT: + %if c.size == 32: + dst[${i}] = ${c.name}; + %elif c.size == 16: + dst[${i}] = _mesa_half_to_float(${c.name}); + %else: + <% assert False %> + %endif + %else: + <% assert False %> + %endif + %elif s == parser.Swizzle.SWIZZLE_ZERO: + dst[${i}] = 0.0f; + %elif s == parser.Swizzle.SWIZZLE_ONE: + dst[${i}] = 1.0f; + %else: + <% assert False %> + %endif + %endfor +} +%endfor + +static void +unpack_float_r9g9b9e5_float(const void *src, GLfloat dst[4]) +{ + rgb9e5_to_float3(*(const GLuint *)src, dst); + dst[3] = 1.0f; +} + +static void +unpack_float_r11g11b10_float(const void *src, GLfloat dst[4]) +{ + r11g11b10f_to_float3(*(const GLuint *)src, dst); + dst[3] = 1.0f; +} + +static void +unpack_float_ycbcr(const void *src, GLfloat dst[][4], GLuint n) +{ + GLuint i; + for (i = 0; i < n; i++) { + const GLushort *src0 = ((const GLushort *) src) + i * 2; /* even */ + const GLushort *src1 = src0 + 1; /* odd */ + const GLubyte y0 = (*src0 >> 8) & 0xff; /* luminance */ + const GLubyte cb = *src0 & 0xff; /* chroma U */ + const GLubyte y1 = (*src1 >> 8) & 0xff; /* luminance */ + const GLubyte cr = *src1 & 0xff; /* chroma V */ + const GLubyte y = (i & 1) ? y1 : y0; /* choose even/odd luminance */ + GLfloat r = 1.164F * (y - 16) + 1.596F * (cr - 128); + GLfloat g = 1.164F * (y - 16) - 0.813F * (cr - 128) - 0.391F * (cb - 128); + GLfloat b = 1.164F * (y - 16) + 2.018F * (cb - 128); + r *= (1.0F / 255.0F); + g *= (1.0F / 255.0F); + b *= (1.0F / 255.0F); + dst[i][0] = CLAMP(r, 0.0F, 1.0F); + dst[i][1] = CLAMP(g, 0.0F, 1.0F); + dst[i][2] = CLAMP(b, 0.0F, 1.0F); + dst[i][3] = 1.0F; + } +} + +static void +unpack_float_ycbcr_rev(const void *src, GLfloat dst[][4], GLuint n) +{ + GLuint i; + for (i = 0; i < n; i++) { + const GLushort *src0 = ((const GLushort *) src) + i * 2; /* even */ + const GLushort *src1 = src0 + 1; /* odd */ + const GLubyte y0 = *src0 & 0xff; /* luminance */ + const GLubyte cr = (*src0 >> 8) & 0xff; /* chroma V */ + const GLubyte y1 = *src1 & 0xff; /* luminance */ + const GLubyte cb = (*src1 >> 8) & 0xff; /* chroma U */ + const GLubyte y = (i & 1) ? y1 : y0; /* choose even/odd luminance */ + GLfloat r = 1.164F * (y - 16) + 1.596F * (cr - 128); + GLfloat g = 1.164F * (y - 16) - 0.813F * (cr - 128) - 0.391F * (cb - 128); + GLfloat b = 1.164F * (y - 16) + 2.018F * (cb - 128); + r *= (1.0F / 255.0F); + g *= (1.0F / 255.0F); + b *= (1.0F / 255.0F); + dst[i][0] = CLAMP(r, 0.0F, 1.0F); + dst[i][1] = CLAMP(g, 0.0F, 1.0F); + dst[i][2] = CLAMP(b, 0.0F, 1.0F); + dst[i][3] = 1.0F; + } +} + +/* ubyte packing functions */ + +%for f in rgb_formats: + %if not f.is_normalized(): + <% continue %> + %endif + +static inline void +unpack_ubyte_${f.short_name()}(const void *void_src, GLubyte dst[4]) +{ + ${f.datatype()} *src = (${f.datatype()} *)void_src; + %if f.layout == parser.PACKED: + %for c in f.channels: + %if c.type != 'x': + ${c.datatype()} ${c.name} = UNPACK(*src, ${c.shift}, ${c.size}); + %endif + %endfor + %elif f.layout == parser.ARRAY: + %for (i, c) in enumerate(f.channels): + %if c.type != 'x': + ${c.datatype()} ${c.name} = src[${i}]; + %endif + %endfor + %else: + <% assert False %> + %endif + + %for i in range(4): + <% s = f.swizzle[i] %> + %if 0 <= s and s <= parser.Swizzle.SWIZZLE_W: + <% c = f.channels[s] %> + %if c.type == parser.UNSIGNED: + %if f.colorspace == 'srgb' and c.name in 'rgb': + <% assert c.size == 8 %> + dst[${i}] = util_format_srgb_to_linear_8unorm(${c.name}); + %else: + dst[${i}] = _mesa_unorm_to_unorm(${c.name}, ${c.size}, 8); + %endif + %elif c.type == parser.SIGNED: + dst[${i}] = _mesa_snorm_to_unorm(${c.name}, ${c.size}, 8); + %elif c.type == parser.FLOAT: + %if c.size == 32: + dst[${i}] = _mesa_float_to_unorm(${c.name}, 8); + %elif c.size == 16: + dst[${i}] = _mesa_half_to_unorm(${c.name}, 8); + %else: + <% assert False %> + %endif + %else: + <% assert False %> + %endif + %elif s == parser.Swizzle.SWIZZLE_ZERO: + dst[${i}] = 0; + %elif s == parser.Swizzle.SWIZZLE_ONE: + dst[${i}] = 255; + %else: + <% assert False %> + %endif + %endfor +} +%endfor + +/* integer packing functions */ + +%for f in rgb_formats: + %if not f.is_int(): + <% continue %> + %elif f.is_normalized(): + <% continue %> + %endif + +static inline void +unpack_int_${f.short_name()}(const void *void_src, GLuint dst[4]) +{ + ${f.datatype()} *src = (${f.datatype()} *)void_src; + %if f.layout == parser.PACKED: + %for c in f.channels: + %if c.type != 'x': + ${c.datatype()} ${c.name} = UNPACK(*src, ${c.shift}, ${c.size}); + %endif + %endfor + %elif f.layout == parser.ARRAY: + %for (i, c) in enumerate(f.channels): + %if c.type != 'x': + ${c.datatype()} ${c.name} = src[${i}]; + %endif + %endfor + %else: + <% assert False %> + %endif + + %for i in range(4): + <% s = f.swizzle[i] %> + %if 0 <= s and s <= parser.Swizzle.SWIZZLE_W: + dst[${i}] = ${f.channels[s].name}; + %elif s == parser.Swizzle.SWIZZLE_ZERO: + dst[${i}] = 0; + %elif s == parser.Swizzle.SWIZZLE_ONE: + dst[${i}] = 1; + %else: + <% assert False %> + %endif + %endfor +} +%endfor + + +void +_mesa_unpack_rgba_row(mesa_format format, GLuint n, + const void *src, GLfloat dst[][4]) +{ + GLubyte *s = (GLubyte *)src; + GLuint i; + + switch (format) { +%for f in rgb_formats: + %if f.is_compressed(): + <% continue %> + %elif f.is_int() and not f.is_normalized(): + <% continue %> + %endif + case ${f.name}: + for (i = 0; i < n; ++i) { + unpack_float_${f.short_name()}(s, dst[i]); + s += ${f.block_size() / 8}; + } + break; +%endfor + case MESA_FORMAT_YCBCR: + unpack_float_ycbcr(src, dst, n); + break; + case MESA_FORMAT_YCBCR_REV: + unpack_float_ycbcr_rev(src, dst, n); + break; + default: + _mesa_problem(NULL, "%s: bad format %s", __FUNCTION__, + _mesa_get_format_name(format)); + return; + } +} + +void +_mesa_unpack_ubyte_rgba_row(mesa_format format, GLuint n, + const void *src, GLubyte dst[][4]) +{ + GLubyte *s = (GLubyte *)src; + GLuint i; + + switch (format) { +%for f in rgb_formats: + %if not f.is_normalized(): + <% continue %> + %endif + + case ${f.name}: + for (i = 0; i < n; ++i) { + unpack_ubyte_${f.short_name()}(s, dst[i]); + s += ${f.block_size() / 8}; + } + break; +%endfor + default: + /* get float values, convert to ubyte */ + { + GLfloat *tmp = malloc(n * 4 * sizeof(GLfloat)); + if (tmp) { + GLuint i; + _mesa_unpack_rgba_row(format, n, src, (GLfloat (*)[4]) tmp); + for (i = 0; i < n; i++) { + dst[i][0] = _mesa_float_to_unorm(tmp[i*4+0], 8); + dst[i][1] = _mesa_float_to_unorm(tmp[i*4+1], 8); + dst[i][2] = _mesa_float_to_unorm(tmp[i*4+2], 8); + dst[i][3] = _mesa_float_to_unorm(tmp[i*4+3], 8); + } + free(tmp); + } + } + break; + } +} + +void +_mesa_unpack_uint_rgba_row(mesa_format format, GLuint n, + const void *src, GLuint dst[][4]) +{ + GLubyte *s = (GLubyte *)src; + GLuint i; + + switch (format) { +%for f in rgb_formats: + %if not f.is_int(): + <% continue %> + %elif f.is_normalized(): + <% continue %> + %endif + + case ${f.name}: + for (i = 0; i < n; ++i) { + unpack_int_${f.short_name()}(s, dst[i]); + s += ${f.block_size() / 8}; + } + break; +%endfor + default: + _mesa_problem(NULL, "%s: bad format %s", __FUNCTION__, + _mesa_get_format_name(format)); + return; + } +} + +/** + * Unpack a 2D rect of pixels returning float RGBA colors. + * \param format the source image format + * \param src start address of the source image + * \param srcRowStride source image row stride in bytes + * \param dst start address of the dest image + * \param dstRowStride dest image row stride in bytes + * \param x source image start X pos + * \param y source image start Y pos + * \param width width of rect region to convert + * \param height height of rect region to convert + */ +void +_mesa_unpack_rgba_block(mesa_format format, + const void *src, GLint srcRowStride, + GLfloat dst[][4], GLint dstRowStride, + GLuint x, GLuint y, GLuint width, GLuint height) +{ + const GLuint srcPixStride = _mesa_get_format_bytes(format); + const GLuint dstPixStride = 4 * sizeof(GLfloat); + const GLubyte *srcRow; + GLubyte *dstRow; + GLuint i; + + /* XXX needs to be fixed for compressed formats */ + + srcRow = ((const GLubyte *) src) + srcRowStride * y + srcPixStride * x; + dstRow = ((GLubyte *) dst) + dstRowStride * y + dstPixStride * x; + + for (i = 0; i < height; i++) { + _mesa_unpack_rgba_row(format, width, srcRow, (GLfloat (*)[4]) dstRow); + + dstRow += dstRowStride; + srcRow += srcRowStride; + } +} + +/** Helper struct for MESA_FORMAT_Z32_FLOAT_S8X24_UINT */ +struct z32f_x24s8 +{ + float z; + uint32_t x24s8; +}; + +typedef void (*unpack_float_z_func)(GLuint n, const void *src, GLfloat *dst); + +static void +unpack_float_z_X8_UINT_Z24_UNORM(GLuint n, const void *src, GLfloat *dst) +{ + /* only return Z, not stencil data */ + const GLuint *s = ((const GLuint *) src); + const GLdouble scale = 1.0 / (GLdouble) 0xffffff; + GLuint i; + for (i = 0; i < n; i++) { + dst[i] = (GLfloat) ((s[i] >> 8) * scale); + ASSERT(dst[i] >= 0.0F); + ASSERT(dst[i] <= 1.0F); + } +} + +static void +unpack_float_z_Z24_UNORM_X8_UINT(GLuint n, const void *src, GLfloat *dst) +{ + /* only return Z, not stencil data */ + const GLuint *s = ((const GLuint *) src); + const GLdouble scale = 1.0 / (GLdouble) 0xffffff; + GLuint i; + for (i = 0; i < n; i++) { + dst[i] = (GLfloat) ((s[i] & 0x00ffffff) * scale); + ASSERT(dst[i] >= 0.0F); + ASSERT(dst[i] <= 1.0F); + } +} + +static void +unpack_float_Z_UNORM16(GLuint n, const void *src, GLfloat *dst) +{ + const GLushort *s = ((const GLushort *) src); + GLuint i; + for (i = 0; i < n; i++) { + dst[i] = s[i] * (1.0F / 65535.0F); + } +} + +static void +unpack_float_Z_UNORM32(GLuint n, const void *src, GLfloat *dst) +{ + const GLuint *s = ((const GLuint *) src); + GLuint i; + for (i = 0; i < n; i++) { + dst[i] = s[i] * (1.0F / 0xffffffff); + } +} + +static void +unpack_float_Z_FLOAT32(GLuint n, const void *src, GLfloat *dst) +{ + memcpy(dst, src, n * sizeof(float)); +} + +static void +unpack_float_z_Z32X24S8(GLuint n, const void *src, GLfloat *dst) +{ + const struct z32f_x24s8 *s = (const struct z32f_x24s8 *) src; + GLuint i; + for (i = 0; i < n; i++) { + dst[i] = s[i].z; + } +} + + + +/** + * Unpack Z values. + * The returned values will always be in the range [0.0, 1.0]. + */ +void +_mesa_unpack_float_z_row(mesa_format format, GLuint n, + const void *src, GLfloat *dst) +{ + unpack_float_z_func unpack; + + switch (format) { + case MESA_FORMAT_S8_UINT_Z24_UNORM: + case MESA_FORMAT_X8_UINT_Z24_UNORM: + unpack = unpack_float_z_X8_UINT_Z24_UNORM; + break; + case MESA_FORMAT_Z24_UNORM_S8_UINT: + case MESA_FORMAT_Z24_UNORM_X8_UINT: + unpack = unpack_float_z_Z24_UNORM_X8_UINT; + break; + case MESA_FORMAT_Z_UNORM16: + unpack = unpack_float_Z_UNORM16; + break; + case MESA_FORMAT_Z_UNORM32: + unpack = unpack_float_Z_UNORM32; + break; + case MESA_FORMAT_Z_FLOAT32: + unpack = unpack_float_Z_FLOAT32; + break; + case MESA_FORMAT_Z32_FLOAT_S8X24_UINT: + unpack = unpack_float_z_Z32X24S8; + break; + default: + _mesa_problem(NULL, "bad format %s in _mesa_unpack_float_z_row", + _mesa_get_format_name(format)); + return; + } + + unpack(n, src, dst); +} + + + +typedef void (*unpack_uint_z_func)(const void *src, GLuint *dst, GLuint n); + +static void +unpack_uint_z_X8_UINT_Z24_UNORM(const void *src, GLuint *dst, GLuint n) +{ + /* only return Z, not stencil data */ + const GLuint *s = ((const GLuint *) src); + GLuint i; + for (i = 0; i < n; i++) { + dst[i] = (s[i] & 0xffffff00) | (s[i] >> 24); + } +} + +static void +unpack_uint_z_Z24_UNORM_X8_UINT(const void *src, GLuint *dst, GLuint n) +{ + /* only return Z, not stencil data */ + const GLuint *s = ((const GLuint *) src); + GLuint i; + for (i = 0; i < n; i++) { + dst[i] = (s[i] << 8) | ((s[i] >> 16) & 0xff); + } +} + +static void +unpack_uint_Z_UNORM16(const void *src, GLuint *dst, GLuint n) +{ + const GLushort *s = ((const GLushort *)src); + GLuint i; + for (i = 0; i < n; i++) { + dst[i] = (s[i] << 16) | s[i]; + } +} + +static void +unpack_uint_Z_UNORM32(const void *src, GLuint *dst, GLuint n) +{ + memcpy(dst, src, n * sizeof(GLuint)); +} + +static void +unpack_uint_Z_FLOAT32(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(CLAMP(s[i], 0.0F, 1.0F)); + } +} + +static void +unpack_uint_Z_FLOAT32_X24S8(const void *src, GLuint *dst, GLuint n) +{ + const struct z32f_x24s8 *s = (const struct z32f_x24s8 *) src; + GLuint i; + + for (i = 0; i < n; i++) { + dst[i] = FLOAT_TO_UINT(CLAMP(s[i].z, 0.0F, 1.0F)); + } +} + + +/** + * Unpack Z values. + * The returned values will always be in the range [0, 0xffffffff]. + */ +void +_mesa_unpack_uint_z_row(mesa_format format, GLuint n, + const void *src, GLuint *dst) +{ + unpack_uint_z_func unpack; + const GLubyte *srcPtr = (GLubyte *) src; + + switch (format) { + case MESA_FORMAT_S8_UINT_Z24_UNORM: + case MESA_FORMAT_X8_UINT_Z24_UNORM: + unpack = unpack_uint_z_X8_UINT_Z24_UNORM; + break; + case MESA_FORMAT_Z24_UNORM_S8_UINT: + case MESA_FORMAT_Z24_UNORM_X8_UINT: + unpack = unpack_uint_z_Z24_UNORM_X8_UINT; + break; + case MESA_FORMAT_Z_UNORM16: + unpack = unpack_uint_Z_UNORM16; + break; + case MESA_FORMAT_Z_UNORM32: + unpack = unpack_uint_Z_UNORM32; + break; + case MESA_FORMAT_Z_FLOAT32: + unpack = unpack_uint_Z_FLOAT32; + break; + case MESA_FORMAT_Z32_FLOAT_S8X24_UINT: + unpack = unpack_uint_Z_FLOAT32_X24S8; + break; + default: + _mesa_problem(NULL, "bad format %s in _mesa_unpack_uint_z_row", + _mesa_get_format_name(format)); + return; + } + + unpack(srcPtr, dst, n); +} + + +static void +unpack_ubyte_s_S_UINT8(const void *src, GLubyte *dst, GLuint n) +{ + memcpy(dst, src, n); +} + +static void +unpack_ubyte_s_S8_UINT_Z24_UNORM(const void *src, GLubyte *dst, GLuint n) +{ + GLuint i; + const GLuint *src32 = src; + + for (i = 0; i < n; i++) + dst[i] = src32[i] & 0xff; +} + +static void +unpack_ubyte_s_Z24_UNORM_S8_UINT(const void *src, GLubyte *dst, GLuint n) +{ + GLuint i; + const GLuint *src32 = src; + + for (i = 0; i < n; i++) + dst[i] = src32[i] >> 24; +} + +static void +unpack_ubyte_s_Z32_FLOAT_S8X24_UINT(const void *src, GLubyte *dst, GLuint n) +{ + GLuint i; + const struct z32f_x24s8 *s = (const struct z32f_x24s8 *) src; + + for (i = 0; i < n; i++) + dst[i] = s[i].x24s8 & 0xff; +} + +void +_mesa_unpack_ubyte_stencil_row(mesa_format format, GLuint n, + const void *src, GLubyte *dst) +{ + switch (format) { + case MESA_FORMAT_S_UINT8: + unpack_ubyte_s_S_UINT8(src, dst, n); + break; + case MESA_FORMAT_S8_UINT_Z24_UNORM: + unpack_ubyte_s_S8_UINT_Z24_UNORM(src, dst, n); + break; + case MESA_FORMAT_Z24_UNORM_S8_UINT: + unpack_ubyte_s_Z24_UNORM_S8_UINT(src, dst, n); + break; + case MESA_FORMAT_Z32_FLOAT_S8X24_UINT: + unpack_ubyte_s_Z32_FLOAT_S8X24_UINT(src, dst, n); + break; + default: + _mesa_problem(NULL, "bad format %s in _mesa_unpack_ubyte_s_row", + _mesa_get_format_name(format)); + return; + } +} + +static void +unpack_uint_24_8_depth_stencil_Z24_UNORM_S8_UINT(const GLuint *src, GLuint *dst, GLuint n) +{ + GLuint i; + + for (i = 0; i < n; i++) { + GLuint val = src[i]; + dst[i] = val >> 24 | val << 8; + } +} + +static void +unpack_uint_24_8_depth_stencil_Z32_S8X24(const GLuint *src, + GLuint *dst, GLuint n) +{ + GLuint i; + + for (i = 0; i < n; i++) { + /* 8 bytes per pixel (float + uint32) */ + GLfloat zf = ((GLfloat *) src)[i * 2 + 0]; + GLuint z24 = (GLuint) (zf * (GLfloat) 0xffffff); + GLuint s = src[i * 2 + 1] & 0xff; + dst[i] = (z24 << 8) | s; + } +} + +static void +unpack_uint_24_8_depth_stencil_S8_UINT_Z24_UNORM(const GLuint *src, GLuint *dst, GLuint n) +{ + memcpy(dst, src, n * 4); +} + +/** + * Unpack depth/stencil returning as GL_UNSIGNED_INT_24_8. + * \param format the source data format + */ +void +_mesa_unpack_uint_24_8_depth_stencil_row(mesa_format format, GLuint n, + const void *src, GLuint *dst) +{ + switch (format) { + case MESA_FORMAT_S8_UINT_Z24_UNORM: + unpack_uint_24_8_depth_stencil_S8_UINT_Z24_UNORM(src, dst, n); + break; + case MESA_FORMAT_Z24_UNORM_S8_UINT: + unpack_uint_24_8_depth_stencil_Z24_UNORM_S8_UINT(src, dst, n); + break; + case MESA_FORMAT_Z32_FLOAT_S8X24_UINT: + unpack_uint_24_8_depth_stencil_Z32_S8X24(src, dst, n); + break; + default: + _mesa_problem(NULL, + "bad format %s in _mesa_unpack_uint_24_8_depth_stencil_row", + _mesa_get_format_name(format)); + return; + } +} + +static void +unpack_float_32_uint_24_8_Z24_UNORM_S8_UINT(const GLuint *src, + GLuint *dst, GLuint n) +{ + GLuint i; + struct z32f_x24s8 *d = (struct z32f_x24s8 *) dst; + const GLdouble scale = 1.0 / (GLdouble) 0xffffff; + + for (i = 0; i < n; i++) { + const GLuint z24 = src[i] & 0xffffff; + d[i].z = z24 * scale; + d[i].x24s8 = src[i] >> 24; + assert(d[i].z >= 0.0f); + assert(d[i].z <= 1.0f); + } +} + +static void +unpack_float_32_uint_24_8_Z32_FLOAT_S8X24_UINT(const GLuint *src, + GLuint *dst, GLuint n) +{ + memcpy(dst, src, n * sizeof(struct z32f_x24s8)); +} + +static void +unpack_float_32_uint_24_8_S8_UINT_Z24_UNORM(const GLuint *src, + GLuint *dst, GLuint n) +{ + GLuint i; + struct z32f_x24s8 *d = (struct z32f_x24s8 *) dst; + const GLdouble scale = 1.0 / (GLdouble) 0xffffff; + + for (i = 0; i < n; i++) { + const GLuint z24 = src[i] >> 8; + d[i].z = z24 * scale; + d[i].x24s8 = src[i] & 0xff; + assert(d[i].z >= 0.0f); + assert(d[i].z <= 1.0f); + } +} + +/** + * Unpack depth/stencil returning as GL_FLOAT_32_UNSIGNED_INT_24_8_REV. + * \param format the source data format + * + * In GL_FLOAT_32_UNSIGNED_INT_24_8_REV lower 4 bytes contain float + * component and higher 4 bytes contain packed 24-bit and 8-bit + * components. + * + * 31 30 29 28 ... 4 3 2 1 0 31 30 29 ... 9 8 7 6 5 ... 2 1 0 + * +-------------------------+ +--------------------------------+ + * | Float Component | | Unused | 8 bit stencil | + * +-------------------------+ +--------------------------------+ + * lower 4 bytes higher 4 bytes + */ +void +_mesa_unpack_float_32_uint_24_8_depth_stencil_row(mesa_format format, GLuint n, + const void *src, GLuint *dst) +{ + switch (format) { + case MESA_FORMAT_S8_UINT_Z24_UNORM: + unpack_float_32_uint_24_8_S8_UINT_Z24_UNORM(src, dst, n); + break; + case MESA_FORMAT_Z24_UNORM_S8_UINT: + unpack_float_32_uint_24_8_Z24_UNORM_S8_UINT(src, dst, n); + break; + case MESA_FORMAT_Z32_FLOAT_S8X24_UINT: + unpack_float_32_uint_24_8_Z32_FLOAT_S8X24_UINT(src, dst, n); + break; + default: + _mesa_problem(NULL, + "bad format %s in _mesa_unpack_uint_24_8_depth_stencil_row", + _mesa_get_format_name(format)); + return; + } +} + +/** + * Unpack depth/stencil + * \param format the source data format + * \param type the destination data type + */ +void +_mesa_unpack_depth_stencil_row(mesa_format format, GLuint n, + const void *src, GLenum type, + GLuint *dst) +{ + assert(type == GL_UNSIGNED_INT_24_8 || + type == GL_FLOAT_32_UNSIGNED_INT_24_8_REV); + + switch (type) { + case GL_UNSIGNED_INT_24_8: + _mesa_unpack_uint_24_8_depth_stencil_row(format, n, src, dst); + break; + case GL_FLOAT_32_UNSIGNED_INT_24_8_REV: + _mesa_unpack_float_32_uint_24_8_depth_stencil_row(format, n, src, dst); + break; + default: + _mesa_problem(NULL, + "bad type 0x%x in _mesa_unpack_depth_stencil_row", + type); + return; + } +} +""" + +template = Template(string); + +print template.render(argv = argv[0:]) diff --git a/mesalib/src/mesa/main/format_utils.c b/mesalib/src/mesa/main/format_utils.c index 93a0ceac0..810bb1634 100644 --- a/mesalib/src/mesa/main/format_utils.c +++ b/mesalib/src/mesa/main/format_utils.c @@ -24,6 +24,549 @@ #include "format_utils.h" #include "glformats.h" +#include "format_pack.h" +#include "format_unpack.h" + +const mesa_array_format RGBA32_FLOAT = + MESA_ARRAY_FORMAT(4, 1, 1, 1, 4, 0, 1, 2, 3); + +const mesa_array_format RGBA8_UBYTE = + MESA_ARRAY_FORMAT(1, 0, 0, 1, 4, 0, 1, 2, 3); + +const mesa_array_format RGBA32_UINT = + MESA_ARRAY_FORMAT(4, 0, 0, 0, 4, 0, 1, 2, 3); + +const mesa_array_format RGBA32_INT = + MESA_ARRAY_FORMAT(4, 1, 0, 0, 4, 0, 1, 2, 3); + +static void +invert_swizzle(uint8_t dst[4], const uint8_t src[4]) +{ + int i, j; + + dst[0] = MESA_FORMAT_SWIZZLE_NONE; + dst[1] = MESA_FORMAT_SWIZZLE_NONE; + dst[2] = MESA_FORMAT_SWIZZLE_NONE; + dst[3] = MESA_FORMAT_SWIZZLE_NONE; + + for (i = 0; i < 4; ++i) + for (j = 0; j < 4; ++j) + if (src[j] == i && dst[i] == MESA_FORMAT_SWIZZLE_NONE) + dst[i] = j; +} + +/* Takes a src to RGBA swizzle and applies a rebase swizzle to it. This + * is used when we need to rebase a format to match a different + * base internal format. + * + * The rebase swizzle can be NULL, which means that no rebase is necessary, + * in which case the src to RGBA swizzle is copied to the output without + * changes. + * + * The resulting rebased swizzle and well as the input swizzles are + * all 4-element swizzles, but the rebase swizzle can be NULL if no rebase + * is necessary. + */ +static void +compute_rebased_rgba_component_mapping(uint8_t *src2rgba, + uint8_t *rebase_swizzle, + uint8_t *rebased_src2rgba) +{ + int i; + + if (rebase_swizzle) { + for (i = 0; i < 4; i++) { + if (rebase_swizzle[i] > MESA_FORMAT_SWIZZLE_W) + rebased_src2rgba[i] = rebase_swizzle[i]; + else + rebased_src2rgba[i] = src2rgba[rebase_swizzle[i]]; + } + } else { + /* No rebase needed, so src2rgba is all that we need */ + memcpy(rebased_src2rgba, src2rgba, 4 * sizeof(uint8_t)); + } +} + +/* Computes the final swizzle transform to apply from src to dst in a + * conversion that might involve a rebase swizzle. + * + * This is used to compute the swizzle transform to apply in conversions + * between array formats where we have a src2rgba swizzle, a rgba2dst swizzle + * and possibly, a rebase swizzle. + * + * The final swizzle transform to apply (src2dst) when a rebase swizzle is + * involved is: src -> rgba -> base -> rgba -> dst + */ +static void +compute_src2dst_component_mapping(uint8_t *src2rgba, uint8_t *rgba2dst, + uint8_t *rebase_swizzle, uint8_t *src2dst) +{ + int i; + + if (!rebase_swizzle) { + for (i = 0; i < 4; i++) { + if (rgba2dst[i] > MESA_FORMAT_SWIZZLE_W) { + src2dst[i] = rgba2dst[i]; + } else { + src2dst[i] = src2rgba[rgba2dst[i]]; + } + } + } else { + for (i = 0; i < 4; i++) { + if (rgba2dst[i] > MESA_FORMAT_SWIZZLE_W) { + src2dst[i] = rgba2dst[i]; + } else if (rebase_swizzle[rgba2dst[i]] > MESA_FORMAT_SWIZZLE_W) { + src2dst[i] = rebase_swizzle[rgba2dst[i]]; + } else { + src2dst[i] = src2rgba[rebase_swizzle[rgba2dst[i]]]; + } + } + } +} + +/** + * This function is used by clients of _mesa_format_convert to obtain + * the rebase swizzle to use in a format conversion based on the base + * format involved. + * + * \param baseFormat the base internal format involved in the conversion. + * \param map the rebase swizzle to consider + * + * This function computes 'map' as rgba -> baseformat -> rgba and returns true + * if the resulting swizzle transform is not the identity transform (thus, a + * rebase is needed). If the function returns false then a rebase swizzle + * is not necessary and the value of 'map' is undefined. In this situation + * clients of _mesa_format_convert should pass NULL in the 'rebase_swizzle' + * parameter. + */ +bool +_mesa_compute_rgba2base2rgba_component_mapping(GLenum baseFormat, uint8_t *map) +{ + uint8_t rgba2base[6], base2rgba[6]; + int i; + + switch (baseFormat) { + case GL_ALPHA: + case GL_RED: + case GL_GREEN: + case GL_BLUE: + case GL_RG: + case GL_RGB: + case GL_BGR: + case GL_RGBA: + case GL_BGRA: + case GL_ABGR_EXT: + case GL_LUMINANCE: + case GL_INTENSITY: + case GL_LUMINANCE_ALPHA: + { + bool needRebase = false; + _mesa_compute_component_mapping(GL_RGBA, baseFormat, rgba2base); + _mesa_compute_component_mapping(baseFormat, GL_RGBA, base2rgba); + for (i = 0; i < 4; i++) { + if (base2rgba[i] > MESA_FORMAT_SWIZZLE_W) { + map[i] = base2rgba[i]; + } else { + map[i] = rgba2base[base2rgba[i]]; + } + if (map[i] != i) + needRebase = true; + } + return needRebase; + } + default: + unreachable("Unexpected base format"); + } +} + +/** + * This can be used to convert between most color formats. + * + * Limitations: + * - This function doesn't handle GL_COLOR_INDEX or YCBCR formats. + * - This function doesn't handle byte-swapping or transferOps, these should + * be handled by the caller. + * + * \param void_dst The address where converted color data will be stored. + * The caller must ensure that the buffer is large enough + * to hold the converted pixel data. + * \param dst_format The destination color format. It can be a mesa_format + * or a mesa_array_format represented as an uint32_t. + * \param dst_stride The stride of the destination format in bytes. + * \param void_src The address of the source color data to convert. + * \param src_format The source color format. It can be a mesa_format + * or a mesa_array_format represented as an uint32_t. + * \param src_stride The stride of the source format in bytes. + * \param width The width, in pixels, of the source image to convert. + * \param height The height, in pixels, of the source image to convert. + * \param rebase_swizzle A swizzle transform to apply during the conversion, + * typically used to match a different internal base + * format involved. NULL if no rebase transform is needed + * (i.e. the internal base format and the base format of + * the dst or the src -depending on whether we are doing + * an upload or a download respectively- are the same). + */ +void +_mesa_format_convert(void *void_dst, uint32_t dst_format, size_t dst_stride, + void *void_src, uint32_t src_format, size_t src_stride, + size_t width, size_t height, uint8_t *rebase_swizzle) +{ + uint8_t *dst = (uint8_t *)void_dst; + uint8_t *src = (uint8_t *)void_src; + mesa_array_format src_array_format, dst_array_format; + bool src_format_is_mesa_array_format, dst_format_is_mesa_array_format; + uint8_t src2dst[4], src2rgba[4], rgba2dst[4], dst2rgba[4]; + uint8_t rebased_src2rgba[4]; + enum mesa_array_format_datatype src_type = 0, dst_type = 0, common_type; + bool normalized, dst_integer, src_integer, is_signed; + int src_num_channels = 0, dst_num_channels = 0; + uint8_t (*tmp_ubyte)[4]; + float (*tmp_float)[4]; + uint32_t (*tmp_uint)[4]; + int bits; + size_t row; + + if (_mesa_format_is_mesa_array_format(src_format)) { + src_format_is_mesa_array_format = true; + src_array_format = src_format; + } else { + assert(_mesa_is_format_color_format(src_format)); + src_format_is_mesa_array_format = false; + src_array_format = _mesa_format_to_array_format(src_format); + } + + if (_mesa_format_is_mesa_array_format(dst_format)) { + dst_format_is_mesa_array_format = true; + dst_array_format = dst_format; + } else { + assert(_mesa_is_format_color_format(dst_format)); + dst_format_is_mesa_array_format = false; + dst_array_format = _mesa_format_to_array_format(dst_format); + } + + /* First we see if we can implement the conversion with a direct pack + * or unpack. + * + * In this case we want to be careful when we need to apply a swizzle to + * match an internal base format, since in these cases a simple pack/unpack + * to the dst format from the src format may not match the requirements + * of the internal base format. For now we decide to be safe and + * avoid this path in these scenarios but in the future we may want to + * enable it for specific combinations that are known to work. + */ + if (!rebase_swizzle) { + /* Handle the cases where we can directly unpack */ + if (!src_format_is_mesa_array_format) { + if (dst_array_format == RGBA32_FLOAT) { + for (row = 0; row < height; ++row) { + _mesa_unpack_rgba_row(src_format, width, + src, (float (*)[4])dst); + src += src_stride; + dst += dst_stride; + } + return; + } else if (dst_array_format == RGBA8_UBYTE) { + assert(!_mesa_is_format_integer_color(src_format)); + for (row = 0; row < height; ++row) { + _mesa_unpack_ubyte_rgba_row(src_format, width, + src, (uint8_t (*)[4])dst); + src += src_stride; + dst += dst_stride; + } + return; + } else if (dst_array_format == RGBA32_UINT && + _mesa_is_format_unsigned(src_format)) { + assert(_mesa_is_format_integer_color(src_format)); + for (row = 0; row < height; ++row) { + _mesa_unpack_uint_rgba_row(src_format, width, + src, (uint32_t (*)[4])dst); + src += src_stride; + dst += dst_stride; + } + return; + } + } + + /* Handle the cases where we can directly pack */ + if (!dst_format_is_mesa_array_format) { + if (src_array_format == RGBA32_FLOAT) { + for (row = 0; row < height; ++row) { + _mesa_pack_float_rgba_row(dst_format, width, + (const float (*)[4])src, dst); + src += src_stride; + dst += dst_stride; + } + return; + } else if (src_array_format == RGBA8_UBYTE) { + assert(!_mesa_is_format_integer_color(dst_format)); + for (row = 0; row < height; ++row) { + _mesa_pack_ubyte_rgba_row(dst_format, width, + (const uint8_t (*)[4])src, dst); + src += src_stride; + dst += dst_stride; + } + return; + } else if (src_array_format == RGBA32_UINT && + _mesa_is_format_unsigned(dst_format)) { + assert(_mesa_is_format_integer_color(dst_format)); + for (row = 0; row < height; ++row) { + _mesa_pack_uint_rgba_row(dst_format, width, + (const uint32_t (*)[4])src, dst); + src += src_stride; + dst += dst_stride; + } + return; + } + } + } + + /* Handle conversions between array formats */ + normalized = false; + if (src_array_format) { + src_type = _mesa_array_format_get_datatype(src_array_format); + + src_num_channels = _mesa_array_format_get_num_channels(src_array_format); + + _mesa_array_format_get_swizzle(src_array_format, src2rgba); + + normalized = _mesa_array_format_is_normalized(src_array_format); + } + + if (dst_array_format) { + dst_type = _mesa_array_format_get_datatype(dst_array_format); + + dst_num_channels = _mesa_array_format_get_num_channels(dst_array_format); + + _mesa_array_format_get_swizzle(dst_array_format, dst2rgba); + invert_swizzle(rgba2dst, dst2rgba); + + normalized |= _mesa_array_format_is_normalized(dst_array_format); + } + + if (src_array_format && dst_array_format) { + assert(_mesa_array_format_is_normalized(src_array_format) == + _mesa_array_format_is_normalized(dst_array_format)); + + compute_src2dst_component_mapping(src2rgba, rgba2dst, rebase_swizzle, + src2dst); + + for (row = 0; row < height; ++row) { + _mesa_swizzle_and_convert(dst, dst_type, dst_num_channels, + src, src_type, src_num_channels, + src2dst, normalized, width); + src += src_stride; + dst += dst_stride; + } + return; + } + + /* At this point, we're fresh out of fast-paths and we need to convert + * to float, uint32, or, if we're lucky, uint8. + */ + dst_integer = false; + src_integer = false; + + if (src_array_format) { + if (!_mesa_array_format_is_float(src_array_format) && + !_mesa_array_format_is_normalized(src_array_format)) + src_integer = true; + } else { + switch (_mesa_get_format_datatype(src_format)) { + case GL_UNSIGNED_INT: + case GL_INT: + src_integer = true; + break; + } + } + + /* If the destination format is signed but the source is unsigned, then we + * don't loose any data by converting to a signed intermediate format above + * and beyond the precision that we loose in the conversion itself. If the + * destination is unsigned then, by using an unsigned intermediate format, + * we make the conversion function that converts from the source to the + * intermediate format take care of truncating at zero. The exception here + * is if the intermediate format is float, in which case the first + * conversion will leave it signed and the second conversion will truncate + * at zero. + */ + is_signed = false; + if (dst_array_format) { + if (!_mesa_array_format_is_float(dst_array_format) && + !_mesa_array_format_is_normalized(dst_array_format)) + dst_integer = true; + is_signed = _mesa_array_format_is_signed(dst_array_format); + bits = 8 * _mesa_array_format_get_type_size(dst_array_format); + } else { + switch (_mesa_get_format_datatype(dst_format)) { + case GL_UNSIGNED_NORMALIZED: + is_signed = false; + break; + case GL_SIGNED_NORMALIZED: + is_signed = true; + break; + case GL_FLOAT: + is_signed = true; + break; + case GL_UNSIGNED_INT: + is_signed = false; + dst_integer = true; + break; + case GL_INT: + is_signed = true; + dst_integer = true; + break; + } + bits = _mesa_get_format_max_bits(dst_format); + } + + assert(src_integer == dst_integer); + + if (src_integer && dst_integer) { + tmp_uint = malloc(width * height * sizeof(*tmp_uint)); + + /* The [un]packing functions for unsigned datatypes treat the 32-bit + * integer array as signed for signed formats and as unsigned for + * unsigned formats. This is a bit of a problem if we ever convert from + * a signed to an unsigned format because the unsigned packing function + * doesn't know that the input is signed and will treat it as unsigned + * and not do the trunctation. The thing that saves us here is that all + * of the packed formats are unsigned, so we can just always use + * _mesa_swizzle_and_convert for signed formats, which is aware of the + * truncation problem. + */ + common_type = is_signed ? MESA_ARRAY_FORMAT_TYPE_INT : + MESA_ARRAY_FORMAT_TYPE_UINT; + if (src_array_format) { + compute_rebased_rgba_component_mapping(src2rgba, rebase_swizzle, + rebased_src2rgba); + for (row = 0; row < height; ++row) { + _mesa_swizzle_and_convert(tmp_uint + row * width, common_type, 4, + src, src_type, src_num_channels, + rebased_src2rgba, normalized, width); + src += src_stride; + } + } else { + for (row = 0; row < height; ++row) { + _mesa_unpack_uint_rgba_row(src_format, width, + src, tmp_uint + row * width); + if (rebase_swizzle) + _mesa_swizzle_and_convert(tmp_uint + row * width, common_type, 4, + tmp_uint + row * width, common_type, 4, + rebase_swizzle, false, width); + src += src_stride; + } + } + + /* At this point, we have already done the truncation if the source is + * signed but the destination is unsigned, so no need to force the + * _mesa_swizzle_and_convert path. + */ + if (dst_format_is_mesa_array_format) { + for (row = 0; row < height; ++row) { + _mesa_swizzle_and_convert(dst, dst_type, dst_num_channels, + tmp_uint + row * width, common_type, 4, + rgba2dst, normalized, width); + dst += dst_stride; + } + } else { + for (row = 0; row < height; ++row) { + _mesa_pack_uint_rgba_row(dst_format, width, + (const uint32_t (*)[4])tmp_uint + row * width, dst); + dst += dst_stride; + } + } + + free(tmp_uint); + } else if (is_signed || bits > 8) { + tmp_float = malloc(width * height * sizeof(*tmp_float)); + + if (src_format_is_mesa_array_format) { + compute_rebased_rgba_component_mapping(src2rgba, rebase_swizzle, + rebased_src2rgba); + for (row = 0; row < height; ++row) { + _mesa_swizzle_and_convert(tmp_float + row * width, + MESA_ARRAY_FORMAT_TYPE_FLOAT, 4, + src, src_type, src_num_channels, + rebased_src2rgba, normalized, width); + src += src_stride; + } + } else { + for (row = 0; row < height; ++row) { + _mesa_unpack_rgba_row(src_format, width, + src, tmp_float + row * width); + if (rebase_swizzle) + _mesa_swizzle_and_convert(tmp_float + row * width, + MESA_ARRAY_FORMAT_TYPE_FLOAT, 4, + tmp_float + row * width, + MESA_ARRAY_FORMAT_TYPE_FLOAT, 4, + rebase_swizzle, normalized, width); + src += src_stride; + } + } + + if (dst_format_is_mesa_array_format) { + for (row = 0; row < height; ++row) { + _mesa_swizzle_and_convert(dst, dst_type, dst_num_channels, + tmp_float + row * width, + MESA_ARRAY_FORMAT_TYPE_FLOAT, 4, + rgba2dst, normalized, width); + dst += dst_stride; + } + } else { + for (row = 0; row < height; ++row) { + _mesa_pack_float_rgba_row(dst_format, width, + (const float (*)[4])tmp_float + row * width, dst); + dst += dst_stride; + } + } + + free(tmp_float); + } else { + tmp_ubyte = malloc(width * height * sizeof(*tmp_ubyte)); + + if (src_format_is_mesa_array_format) { + compute_rebased_rgba_component_mapping(src2rgba, rebase_swizzle, + rebased_src2rgba); + for (row = 0; row < height; ++row) { + _mesa_swizzle_and_convert(tmp_ubyte + row * width, + MESA_ARRAY_FORMAT_TYPE_UBYTE, 4, + src, src_type, src_num_channels, + rebased_src2rgba, normalized, width); + src += src_stride; + } + } else { + for (row = 0; row < height; ++row) { + _mesa_unpack_ubyte_rgba_row(src_format, width, + src, tmp_ubyte + row * width); + if (rebase_swizzle) + _mesa_swizzle_and_convert(tmp_ubyte + row * width, + MESA_ARRAY_FORMAT_TYPE_UBYTE, 4, + tmp_ubyte + row * width, + MESA_ARRAY_FORMAT_TYPE_UBYTE, 4, + rebase_swizzle, normalized, width); + src += src_stride; + } + } + + if (dst_format_is_mesa_array_format) { + for (row = 0; row < height; ++row) { + _mesa_swizzle_and_convert(dst, dst_type, dst_num_channels, + tmp_ubyte + row * width, + MESA_ARRAY_FORMAT_TYPE_UBYTE, 4, + rgba2dst, normalized, width); + dst += dst_stride; + } + } else { + for (row = 0; row < height; ++row) { + _mesa_pack_ubyte_rgba_row(dst_format, width, + (const uint8_t (*)[4])tmp_ubyte + row * width, dst); + dst += dst_stride; + } + } + + free(tmp_ubyte); + } +} static const uint8_t map_identity[7] = { 0, 1, 2, 3, 4, 5, 6 }; static const uint8_t map_3210[7] = { 3, 2, 1, 0, 4, 5, 6 }; @@ -132,131 +675,6 @@ _mesa_format_to_array(mesa_format format, GLenum *type, int *num_components, } } -/* A bunch of format conversion macros and helper functions used below */ - -/* Only guaranteed to work for BITS <= 32 */ -#define MAX_UINT(BITS) ((BITS) == 32 ? UINT32_MAX : ((1u << (BITS)) - 1)) -#define MAX_INT(BITS) ((int)MAX_UINT((BITS) - 1)) - -/* Extends an integer of size SRC_BITS to one of size DST_BITS linearly */ -#define EXTEND_NORMALIZED_INT(X, SRC_BITS, DST_BITS) \ - (((X) * (int)(MAX_UINT(DST_BITS) / MAX_UINT(SRC_BITS))) + \ - ((DST_BITS % SRC_BITS) ? ((X) >> (SRC_BITS - DST_BITS % SRC_BITS)) : 0)) - -static inline float -unorm_to_float(unsigned x, unsigned src_bits) -{ - return x * (1.0f / (float)MAX_UINT(src_bits)); -} - -static inline float -snorm_to_float(int x, unsigned src_bits) -{ - if (x == -MAX_INT(src_bits)) - return -1.0f; - else - return x * (1.0f / (float)MAX_INT(src_bits)); -} - -static inline uint16_t -unorm_to_half(unsigned x, unsigned src_bits) -{ - return _mesa_float_to_half(unorm_to_float(x, src_bits)); -} - -static inline uint16_t -snorm_to_half(int x, unsigned src_bits) -{ - return _mesa_float_to_half(snorm_to_float(x, src_bits)); -} - -static inline unsigned -float_to_unorm(float x, unsigned dst_bits) -{ - if (x < 0.0f) - return 0; - else if (x > 1.0f) - return MAX_UINT(dst_bits); - else - return F_TO_I(x * MAX_UINT(dst_bits)); -} - -static inline unsigned -half_to_unorm(uint16_t x, unsigned dst_bits) -{ - return float_to_unorm(_mesa_half_to_float(x), dst_bits); -} - -static inline unsigned -unorm_to_unorm(unsigned x, unsigned src_bits, unsigned dst_bits) -{ - if (src_bits < dst_bits) - return EXTEND_NORMALIZED_INT(x, src_bits, dst_bits); - else - return x >> (src_bits - dst_bits); -} - -static inline unsigned -snorm_to_unorm(int x, unsigned src_bits, unsigned dst_bits) -{ - if (x < 0) - return 0; - else - return unorm_to_unorm(x, src_bits - 1, dst_bits); -} - -static inline int -float_to_snorm(float x, unsigned dst_bits) -{ - if (x < -1.0f) - return -MAX_INT(dst_bits); - else if (x > 1.0f) - return MAX_INT(dst_bits); - else - return F_TO_I(x * MAX_INT(dst_bits)); -} - -static inline int -half_to_snorm(uint16_t x, unsigned dst_bits) -{ - return float_to_snorm(_mesa_half_to_float(x), dst_bits); -} - -static inline int -unorm_to_snorm(unsigned x, unsigned src_bits, unsigned dst_bits) -{ - return unorm_to_unorm(x, src_bits, dst_bits - 1); -} - -static inline int -snorm_to_snorm(int x, unsigned src_bits, unsigned dst_bits) -{ - if (x < -MAX_INT(src_bits)) - return -MAX_INT(dst_bits); - else if (src_bits < dst_bits) - return EXTEND_NORMALIZED_INT(x, src_bits - 1, dst_bits - 1); - else - return x >> (src_bits - dst_bits); -} - -static inline unsigned -float_to_uint(float x) -{ - if (x < 0.0f) - return 0; - else - return x; -} - -static inline unsigned -half_to_uint(uint16_t x) -{ - if (_mesa_half_is_negative(x)) - return 0; - else - return _mesa_float_to_half(x); -} - /** * Attempts to perform the given swizzle-and-convert operation with memcpy * @@ -270,8 +688,12 @@ half_to_uint(uint16_t x) * operation with memcpy, false otherwise */ static bool -swizzle_convert_try_memcpy(void *dst, GLenum dst_type, int num_dst_channels, - const void *src, GLenum src_type, int num_src_channels, +swizzle_convert_try_memcpy(void *dst, + enum mesa_array_format_datatype dst_type, + int num_dst_channels, + const void *src, + enum mesa_array_format_datatype src_type, + int num_src_channels, const uint8_t swizzle[4], bool normalized, int count) { int i; @@ -285,7 +707,8 @@ swizzle_convert_try_memcpy(void *dst, GLenum dst_type, int num_dst_channels, if (swizzle[i] != i && swizzle[i] != MESA_FORMAT_SWIZZLE_NONE) return false; - memcpy(dst, src, count * num_src_channels * _mesa_sizeof_type(src_type)); + memcpy(dst, src, count * num_src_channels * + _mesa_array_format_datatype_get_size(src_type)); return true; } @@ -441,50 +864,50 @@ convert_float(void *void_dst, int num_dst_channels, const float one = 1.0f; switch (src_type) { - case GL_FLOAT: + case MESA_ARRAY_FORMAT_TYPE_FLOAT: SWIZZLE_CONVERT(float, float, src); break; - case GL_HALF_FLOAT: + case MESA_ARRAY_FORMAT_TYPE_HALF: SWIZZLE_CONVERT(float, uint16_t, _mesa_half_to_float(src)); break; - case GL_UNSIGNED_BYTE: + case MESA_ARRAY_FORMAT_TYPE_UBYTE: if (normalized) { - SWIZZLE_CONVERT(float, uint8_t, unorm_to_float(src, 8)); + SWIZZLE_CONVERT(float, uint8_t, _mesa_unorm_to_float(src, 8)); } else { SWIZZLE_CONVERT(float, uint8_t, src); } break; - case GL_BYTE: + case MESA_ARRAY_FORMAT_TYPE_BYTE: if (normalized) { - SWIZZLE_CONVERT(float, int8_t, snorm_to_float(src, 8)); + SWIZZLE_CONVERT(float, int8_t, _mesa_snorm_to_float(src, 8)); } else { SWIZZLE_CONVERT(float, int8_t, src); } break; - case GL_UNSIGNED_SHORT: + case MESA_ARRAY_FORMAT_TYPE_USHORT: if (normalized) { - SWIZZLE_CONVERT(float, uint16_t, unorm_to_float(src, 16)); + SWIZZLE_CONVERT(float, uint16_t, _mesa_unorm_to_float(src, 16)); } else { SWIZZLE_CONVERT(float, uint16_t, src); } break; - case GL_SHORT: + case MESA_ARRAY_FORMAT_TYPE_SHORT: if (normalized) { - SWIZZLE_CONVERT(float, int16_t, snorm_to_float(src, 16)); + SWIZZLE_CONVERT(float, int16_t, _mesa_snorm_to_float(src, 16)); } else { SWIZZLE_CONVERT(float, int16_t, src); } break; - case GL_UNSIGNED_INT: + case MESA_ARRAY_FORMAT_TYPE_UINT: if (normalized) { - SWIZZLE_CONVERT(float, uint32_t, unorm_to_float(src, 32)); + SWIZZLE_CONVERT(float, uint32_t, _mesa_unorm_to_float(src, 32)); } else { SWIZZLE_CONVERT(float, uint32_t, src); } break; - case GL_INT: + case MESA_ARRAY_FORMAT_TYPE_INT: if (normalized) { - SWIZZLE_CONVERT(float, int32_t, snorm_to_float(src, 32)); + SWIZZLE_CONVERT(float, int32_t, _mesa_snorm_to_float(src, 32)); } else { SWIZZLE_CONVERT(float, int32_t, src); } @@ -503,50 +926,50 @@ convert_half_float(void *void_dst, int num_dst_channels, const uint16_t one = _mesa_float_to_half(1.0f); switch (src_type) { - case GL_FLOAT: + case MESA_ARRAY_FORMAT_TYPE_FLOAT: SWIZZLE_CONVERT(uint16_t, float, _mesa_float_to_half(src)); break; - case GL_HALF_FLOAT: + case MESA_ARRAY_FORMAT_TYPE_HALF: SWIZZLE_CONVERT(uint16_t, uint16_t, src); break; - case GL_UNSIGNED_BYTE: + case MESA_ARRAY_FORMAT_TYPE_UBYTE: if (normalized) { - SWIZZLE_CONVERT(uint16_t, uint8_t, unorm_to_half(src, 8)); + SWIZZLE_CONVERT(uint16_t, uint8_t, _mesa_unorm_to_half(src, 8)); } else { SWIZZLE_CONVERT(uint16_t, uint8_t, _mesa_float_to_half(src)); } break; - case GL_BYTE: + case MESA_ARRAY_FORMAT_TYPE_BYTE: if (normalized) { - SWIZZLE_CONVERT(uint16_t, int8_t, snorm_to_half(src, 8)); + SWIZZLE_CONVERT(uint16_t, int8_t, _mesa_snorm_to_half(src, 8)); } else { SWIZZLE_CONVERT(uint16_t, int8_t, _mesa_float_to_half(src)); } break; - case GL_UNSIGNED_SHORT: + case MESA_ARRAY_FORMAT_TYPE_USHORT: if (normalized) { - SWIZZLE_CONVERT(uint16_t, uint16_t, unorm_to_half(src, 16)); + SWIZZLE_CONVERT(uint16_t, uint16_t, _mesa_unorm_to_half(src, 16)); } else { SWIZZLE_CONVERT(uint16_t, uint16_t, _mesa_float_to_half(src)); } break; - case GL_SHORT: + case MESA_ARRAY_FORMAT_TYPE_SHORT: if (normalized) { - SWIZZLE_CONVERT(uint16_t, int16_t, snorm_to_half(src, 16)); + SWIZZLE_CONVERT(uint16_t, int16_t, _mesa_snorm_to_half(src, 16)); } else { SWIZZLE_CONVERT(uint16_t, int16_t, _mesa_float_to_half(src)); } break; - case GL_UNSIGNED_INT: + case MESA_ARRAY_FORMAT_TYPE_UINT: if (normalized) { - SWIZZLE_CONVERT(uint16_t, uint32_t, unorm_to_half(src, 32)); + SWIZZLE_CONVERT(uint16_t, uint32_t, _mesa_unorm_to_half(src, 32)); } else { SWIZZLE_CONVERT(uint16_t, uint32_t, _mesa_float_to_half(src)); } break; - case GL_INT: + case MESA_ARRAY_FORMAT_TYPE_INT: if (normalized) { - SWIZZLE_CONVERT(uint16_t, int32_t, snorm_to_half(src, 32)); + SWIZZLE_CONVERT(uint16_t, int32_t, _mesa_snorm_to_half(src, 32)); } else { SWIZZLE_CONVERT(uint16_t, int32_t, _mesa_float_to_half(src)); } @@ -556,7 +979,6 @@ convert_half_float(void *void_dst, int num_dst_channels, } } - static void convert_ubyte(void *void_dst, int num_dst_channels, const void *void_src, GLenum src_type, int num_src_channels, @@ -565,56 +987,56 @@ convert_ubyte(void *void_dst, int num_dst_channels, const uint8_t one = normalized ? UINT8_MAX : 1; switch (src_type) { - case GL_FLOAT: + case MESA_ARRAY_FORMAT_TYPE_FLOAT: if (normalized) { - SWIZZLE_CONVERT(uint8_t, float, float_to_unorm(src, 8)); + SWIZZLE_CONVERT(uint8_t, float, _mesa_float_to_unorm(src, 8)); } else { - SWIZZLE_CONVERT(uint8_t, float, (src < 0) ? 0 : src); + SWIZZLE_CONVERT(uint8_t, float, _mesa_float_to_unsigned(src, 8)); } break; - case GL_HALF_FLOAT: + case MESA_ARRAY_FORMAT_TYPE_HALF: if (normalized) { - SWIZZLE_CONVERT(uint8_t, uint16_t, half_to_unorm(src, 8)); + SWIZZLE_CONVERT(uint8_t, uint16_t, _mesa_half_to_unorm(src, 8)); } else { - SWIZZLE_CONVERT(uint8_t, uint16_t, half_to_uint(src)); + SWIZZLE_CONVERT(uint8_t, uint16_t, _mesa_half_to_unsigned(src, 8)); } break; - case GL_UNSIGNED_BYTE: + case MESA_ARRAY_FORMAT_TYPE_UBYTE: SWIZZLE_CONVERT(uint8_t, uint8_t, src); break; - case GL_BYTE: + case MESA_ARRAY_FORMAT_TYPE_BYTE: if (normalized) { - SWIZZLE_CONVERT(uint8_t, int8_t, snorm_to_unorm(src, 8, 8)); + SWIZZLE_CONVERT(uint8_t, int8_t, _mesa_snorm_to_unorm(src, 8, 8)); } else { - SWIZZLE_CONVERT(uint8_t, int8_t, (src < 0) ? 0 : src); + SWIZZLE_CONVERT(uint8_t, int8_t, _mesa_signed_to_unsigned(src, 8)); } break; - case GL_UNSIGNED_SHORT: + case MESA_ARRAY_FORMAT_TYPE_USHORT: if (normalized) { - SWIZZLE_CONVERT(uint8_t, uint16_t, unorm_to_unorm(src, 16, 8)); + SWIZZLE_CONVERT(uint8_t, uint16_t, _mesa_unorm_to_unorm(src, 16, 8)); } else { - SWIZZLE_CONVERT(uint8_t, uint16_t, src); + SWIZZLE_CONVERT(uint8_t, uint16_t, _mesa_unsigned_to_unsigned(src, 8)); } break; - case GL_SHORT: + case MESA_ARRAY_FORMAT_TYPE_SHORT: if (normalized) { - SWIZZLE_CONVERT(uint8_t, int16_t, snorm_to_unorm(src, 16, 8)); + SWIZZLE_CONVERT(uint8_t, int16_t, _mesa_snorm_to_unorm(src, 16, 8)); } else { - SWIZZLE_CONVERT(uint8_t, int16_t, (src < 0) ? 0 : src); + SWIZZLE_CONVERT(uint8_t, int16_t, _mesa_signed_to_unsigned(src, 8)); } break; - case GL_UNSIGNED_INT: + case MESA_ARRAY_FORMAT_TYPE_UINT: if (normalized) { - SWIZZLE_CONVERT(uint8_t, uint32_t, unorm_to_unorm(src, 32, 8)); + SWIZZLE_CONVERT(uint8_t, uint32_t, _mesa_unorm_to_unorm(src, 32, 8)); } else { - SWIZZLE_CONVERT(uint8_t, uint32_t, src); + SWIZZLE_CONVERT(uint8_t, uint32_t, _mesa_unsigned_to_unsigned(src, 8)); } break; - case GL_INT: + case MESA_ARRAY_FORMAT_TYPE_INT: if (normalized) { - SWIZZLE_CONVERT(uint8_t, int32_t, snorm_to_unorm(src, 32, 8)); + SWIZZLE_CONVERT(uint8_t, int32_t, _mesa_snorm_to_unorm(src, 32, 8)); } else { - SWIZZLE_CONVERT(uint8_t, int32_t, (src < 0) ? 0 : src); + SWIZZLE_CONVERT(uint8_t, int32_t, _mesa_signed_to_unsigned(src, 8)); } break; default: @@ -631,56 +1053,56 @@ convert_byte(void *void_dst, int num_dst_channels, const int8_t one = normalized ? INT8_MAX : 1; switch (src_type) { - case GL_FLOAT: + case MESA_ARRAY_FORMAT_TYPE_FLOAT: if (normalized) { - SWIZZLE_CONVERT(uint8_t, float, float_to_snorm(src, 8)); + SWIZZLE_CONVERT(uint8_t, float, _mesa_float_to_snorm(src, 8)); } else { - SWIZZLE_CONVERT(uint8_t, float, src); + SWIZZLE_CONVERT(uint8_t, float, _mesa_float_to_signed(src, 8)); } break; - case GL_HALF_FLOAT: + case MESA_ARRAY_FORMAT_TYPE_HALF: if (normalized) { - SWIZZLE_CONVERT(uint8_t, uint16_t, half_to_snorm(src, 8)); + SWIZZLE_CONVERT(uint8_t, uint16_t, _mesa_half_to_snorm(src, 8)); } else { - SWIZZLE_CONVERT(uint8_t, uint16_t, _mesa_half_to_float(src)); + SWIZZLE_CONVERT(uint8_t, uint16_t, _mesa_half_to_signed(src, 8)); } break; - case GL_UNSIGNED_BYTE: + case MESA_ARRAY_FORMAT_TYPE_UBYTE: if (normalized) { - SWIZZLE_CONVERT(int8_t, uint8_t, unorm_to_snorm(src, 8, 8)); + SWIZZLE_CONVERT(int8_t, uint8_t, _mesa_unorm_to_snorm(src, 8, 8)); } else { - SWIZZLE_CONVERT(int8_t, uint8_t, src); + SWIZZLE_CONVERT(int8_t, uint8_t, _mesa_unsigned_to_signed(src, 8)); } break; - case GL_BYTE: + case MESA_ARRAY_FORMAT_TYPE_BYTE: SWIZZLE_CONVERT(int8_t, int8_t, src); break; - case GL_UNSIGNED_SHORT: + case MESA_ARRAY_FORMAT_TYPE_USHORT: if (normalized) { - SWIZZLE_CONVERT(int8_t, uint16_t, unorm_to_snorm(src, 16, 8)); + SWIZZLE_CONVERT(int8_t, uint16_t, _mesa_unorm_to_snorm(src, 16, 8)); } else { - SWIZZLE_CONVERT(int8_t, uint16_t, src); + SWIZZLE_CONVERT(int8_t, uint16_t, _mesa_unsigned_to_signed(src, 8)); } break; - case GL_SHORT: + case MESA_ARRAY_FORMAT_TYPE_SHORT: if (normalized) { - SWIZZLE_CONVERT(int8_t, int16_t, snorm_to_snorm(src, 16, 8)); + SWIZZLE_CONVERT(int8_t, int16_t, _mesa_snorm_to_snorm(src, 16, 8)); } else { - SWIZZLE_CONVERT(int8_t, int16_t, src); + SWIZZLE_CONVERT(int8_t, int16_t, _mesa_signed_to_signed(src, 8)); } break; - case GL_UNSIGNED_INT: + case MESA_ARRAY_FORMAT_TYPE_UINT: if (normalized) { - SWIZZLE_CONVERT(int8_t, uint32_t, unorm_to_snorm(src, 32, 8)); + SWIZZLE_CONVERT(int8_t, uint32_t, _mesa_unorm_to_snorm(src, 32, 8)); } else { - SWIZZLE_CONVERT(int8_t, uint32_t, src); + SWIZZLE_CONVERT(int8_t, uint32_t, _mesa_unsigned_to_signed(src, 8)); } break; - case GL_INT: + case MESA_ARRAY_FORMAT_TYPE_INT: if (normalized) { - SWIZZLE_CONVERT(int8_t, int32_t, snorm_to_snorm(src, 32, 8)); + SWIZZLE_CONVERT(int8_t, int32_t, _mesa_snorm_to_snorm(src, 32, 8)); } else { - SWIZZLE_CONVERT(int8_t, int32_t, src); + SWIZZLE_CONVERT(int8_t, int32_t, _mesa_signed_to_signed(src, 8)); } break; default: @@ -697,56 +1119,56 @@ convert_ushort(void *void_dst, int num_dst_channels, const uint16_t one = normalized ? UINT16_MAX : 1; switch (src_type) { - case GL_FLOAT: + case MESA_ARRAY_FORMAT_TYPE_FLOAT: if (normalized) { - SWIZZLE_CONVERT(uint16_t, float, float_to_unorm(src, 16)); + SWIZZLE_CONVERT(uint16_t, float, _mesa_float_to_unorm(src, 16)); } else { - SWIZZLE_CONVERT(uint16_t, float, (src < 0) ? 0 : src); + SWIZZLE_CONVERT(uint16_t, float, _mesa_float_to_unsigned(src, 16)); } break; - case GL_HALF_FLOAT: + case MESA_ARRAY_FORMAT_TYPE_HALF: if (normalized) { - SWIZZLE_CONVERT(uint16_t, uint16_t, half_to_unorm(src, 16)); + SWIZZLE_CONVERT(uint16_t, uint16_t, _mesa_half_to_unorm(src, 16)); } else { - SWIZZLE_CONVERT(uint16_t, uint16_t, half_to_uint(src)); + SWIZZLE_CONVERT(uint16_t, uint16_t, _mesa_half_to_unsigned(src, 16)); } break; - case GL_UNSIGNED_BYTE: + case MESA_ARRAY_FORMAT_TYPE_UBYTE: if (normalized) { - SWIZZLE_CONVERT(uint16_t, uint8_t, unorm_to_unorm(src, 8, 16)); + SWIZZLE_CONVERT(uint16_t, uint8_t, _mesa_unorm_to_unorm(src, 8, 16)); } else { SWIZZLE_CONVERT(uint16_t, uint8_t, src); } break; - case GL_BYTE: + case MESA_ARRAY_FORMAT_TYPE_BYTE: if (normalized) { - SWIZZLE_CONVERT(uint16_t, int8_t, snorm_to_unorm(src, 8, 16)); + SWIZZLE_CONVERT(uint16_t, int8_t, _mesa_snorm_to_unorm(src, 8, 16)); } else { - SWIZZLE_CONVERT(uint16_t, int8_t, (src < 0) ? 0 : src); + SWIZZLE_CONVERT(uint16_t, int8_t, _mesa_signed_to_unsigned(src, 16)); } break; - case GL_UNSIGNED_SHORT: + case MESA_ARRAY_FORMAT_TYPE_USHORT: SWIZZLE_CONVERT(uint16_t, uint16_t, src); break; - case GL_SHORT: + case MESA_ARRAY_FORMAT_TYPE_SHORT: if (normalized) { - SWIZZLE_CONVERT(uint16_t, int16_t, snorm_to_unorm(src, 16, 16)); + SWIZZLE_CONVERT(uint16_t, int16_t, _mesa_snorm_to_unorm(src, 16, 16)); } else { - SWIZZLE_CONVERT(uint16_t, int16_t, (src < 0) ? 0 : src); + SWIZZLE_CONVERT(uint16_t, int16_t, _mesa_signed_to_unsigned(src, 16)); } break; - case GL_UNSIGNED_INT: + case MESA_ARRAY_FORMAT_TYPE_UINT: if (normalized) { - SWIZZLE_CONVERT(uint16_t, uint32_t, unorm_to_unorm(src, 32, 16)); + SWIZZLE_CONVERT(uint16_t, uint32_t, _mesa_unorm_to_unorm(src, 32, 16)); } else { - SWIZZLE_CONVERT(uint16_t, uint32_t, src); + SWIZZLE_CONVERT(uint16_t, uint32_t, _mesa_unsigned_to_unsigned(src, 16)); } break; - case GL_INT: + case MESA_ARRAY_FORMAT_TYPE_INT: if (normalized) { - SWIZZLE_CONVERT(uint16_t, int32_t, snorm_to_unorm(src, 32, 16)); + SWIZZLE_CONVERT(uint16_t, int32_t, _mesa_snorm_to_unorm(src, 32, 16)); } else { - SWIZZLE_CONVERT(uint16_t, int32_t, (src < 0) ? 0 : src); + SWIZZLE_CONVERT(uint16_t, int32_t, _mesa_signed_to_unsigned(src, 16)); } break; default: @@ -763,56 +1185,56 @@ convert_short(void *void_dst, int num_dst_channels, const int16_t one = normalized ? INT16_MAX : 1; switch (src_type) { - case GL_FLOAT: + case MESA_ARRAY_FORMAT_TYPE_FLOAT: if (normalized) { - SWIZZLE_CONVERT(uint16_t, float, float_to_snorm(src, 16)); + SWIZZLE_CONVERT(uint16_t, float, _mesa_float_to_snorm(src, 16)); } else { - SWIZZLE_CONVERT(uint16_t, float, src); + SWIZZLE_CONVERT(uint16_t, float, _mesa_float_to_signed(src, 16)); } break; - case GL_HALF_FLOAT: + case MESA_ARRAY_FORMAT_TYPE_HALF: if (normalized) { - SWIZZLE_CONVERT(uint16_t, uint16_t, half_to_snorm(src, 16)); + SWIZZLE_CONVERT(uint16_t, uint16_t, _mesa_half_to_snorm(src, 16)); } else { - SWIZZLE_CONVERT(uint16_t, uint16_t, _mesa_half_to_float(src)); + SWIZZLE_CONVERT(uint16_t, uint16_t, _mesa_half_to_signed(src, 16)); } break; - case GL_UNSIGNED_BYTE: + case MESA_ARRAY_FORMAT_TYPE_UBYTE: if (normalized) { - SWIZZLE_CONVERT(int16_t, uint8_t, unorm_to_snorm(src, 8, 16)); + SWIZZLE_CONVERT(int16_t, uint8_t, _mesa_unorm_to_snorm(src, 8, 16)); } else { SWIZZLE_CONVERT(int16_t, uint8_t, src); } break; - case GL_BYTE: + case MESA_ARRAY_FORMAT_TYPE_BYTE: if (normalized) { - SWIZZLE_CONVERT(int16_t, int8_t, snorm_to_snorm(src, 8, 16)); + SWIZZLE_CONVERT(int16_t, int8_t, _mesa_snorm_to_snorm(src, 8, 16)); } else { SWIZZLE_CONVERT(int16_t, int8_t, src); } break; - case GL_UNSIGNED_SHORT: + case MESA_ARRAY_FORMAT_TYPE_USHORT: if (normalized) { - SWIZZLE_CONVERT(int16_t, uint16_t, unorm_to_snorm(src, 16, 16)); + SWIZZLE_CONVERT(int16_t, uint16_t, _mesa_unorm_to_snorm(src, 16, 16)); } else { - SWIZZLE_CONVERT(int16_t, uint16_t, src); + SWIZZLE_CONVERT(int16_t, uint16_t, _mesa_unsigned_to_signed(src, 16)); } break; - case GL_SHORT: + case MESA_ARRAY_FORMAT_TYPE_SHORT: SWIZZLE_CONVERT(int16_t, int16_t, src); break; - case GL_UNSIGNED_INT: + case MESA_ARRAY_FORMAT_TYPE_UINT: if (normalized) { - SWIZZLE_CONVERT(int16_t, uint32_t, unorm_to_snorm(src, 32, 16)); + SWIZZLE_CONVERT(int16_t, uint32_t, _mesa_unorm_to_snorm(src, 32, 16)); } else { - SWIZZLE_CONVERT(int16_t, uint32_t, src); + SWIZZLE_CONVERT(int16_t, uint32_t, _mesa_unsigned_to_signed(src, 16)); } break; - case GL_INT: + case MESA_ARRAY_FORMAT_TYPE_INT: if (normalized) { - SWIZZLE_CONVERT(int16_t, int32_t, snorm_to_snorm(src, 32, 16)); + SWIZZLE_CONVERT(int16_t, int32_t, _mesa_snorm_to_snorm(src, 32, 16)); } else { - SWIZZLE_CONVERT(int16_t, int32_t, src); + SWIZZLE_CONVERT(int16_t, int32_t, _mesa_signed_to_signed(src, 16)); } break; default: @@ -828,56 +1250,56 @@ convert_uint(void *void_dst, int num_dst_channels, const uint32_t one = normalized ? UINT32_MAX : 1; switch (src_type) { - case GL_FLOAT: + case MESA_ARRAY_FORMAT_TYPE_FLOAT: if (normalized) { - SWIZZLE_CONVERT(uint32_t, float, float_to_unorm(src, 32)); + SWIZZLE_CONVERT(uint32_t, float, _mesa_float_to_unorm(src, 32)); } else { - SWIZZLE_CONVERT(uint32_t, float, (src < 0) ? 0 : src); + SWIZZLE_CONVERT(uint32_t, float, _mesa_float_to_unsigned(src, 32)); } break; - case GL_HALF_FLOAT: + case MESA_ARRAY_FORMAT_TYPE_HALF: if (normalized) { - SWIZZLE_CONVERT(uint32_t, uint16_t, half_to_unorm(src, 32)); + SWIZZLE_CONVERT(uint32_t, uint16_t, _mesa_half_to_unorm(src, 32)); } else { - SWIZZLE_CONVERT(uint32_t, uint16_t, half_to_uint(src)); + SWIZZLE_CONVERT(uint32_t, uint16_t, _mesa_half_to_unsigned(src, 32)); } break; - case GL_UNSIGNED_BYTE: + case MESA_ARRAY_FORMAT_TYPE_UBYTE: if (normalized) { - SWIZZLE_CONVERT(uint32_t, uint8_t, unorm_to_unorm(src, 8, 32)); + SWIZZLE_CONVERT(uint32_t, uint8_t, _mesa_unorm_to_unorm(src, 8, 32)); } else { SWIZZLE_CONVERT(uint32_t, uint8_t, src); } break; - case GL_BYTE: + case MESA_ARRAY_FORMAT_TYPE_BYTE: if (normalized) { - SWIZZLE_CONVERT(uint32_t, int8_t, snorm_to_unorm(src, 8, 32)); + SWIZZLE_CONVERT(uint32_t, int8_t, _mesa_snorm_to_unorm(src, 8, 32)); } else { - SWIZZLE_CONVERT(uint32_t, int8_t, (src < 0) ? 0 : src); + SWIZZLE_CONVERT(uint32_t, int8_t, _mesa_signed_to_unsigned(src, 32)); } break; - case GL_UNSIGNED_SHORT: + case MESA_ARRAY_FORMAT_TYPE_USHORT: if (normalized) { - SWIZZLE_CONVERT(uint32_t, uint16_t, unorm_to_unorm(src, 16, 32)); + SWIZZLE_CONVERT(uint32_t, uint16_t, _mesa_unorm_to_unorm(src, 16, 32)); } else { SWIZZLE_CONVERT(uint32_t, uint16_t, src); } break; - case GL_SHORT: + case MESA_ARRAY_FORMAT_TYPE_SHORT: if (normalized) { - SWIZZLE_CONVERT(uint32_t, int16_t, snorm_to_unorm(src, 16, 32)); + SWIZZLE_CONVERT(uint32_t, int16_t, _mesa_snorm_to_unorm(src, 16, 32)); } else { - SWIZZLE_CONVERT(uint32_t, int16_t, (src < 0) ? 0 : src); + SWIZZLE_CONVERT(uint32_t, int16_t, _mesa_signed_to_unsigned(src, 32)); } break; - case GL_UNSIGNED_INT: + case MESA_ARRAY_FORMAT_TYPE_UINT: SWIZZLE_CONVERT(uint32_t, uint32_t, src); break; - case GL_INT: + case MESA_ARRAY_FORMAT_TYPE_INT: if (normalized) { - SWIZZLE_CONVERT(uint32_t, int32_t, snorm_to_unorm(src, 32, 32)); + SWIZZLE_CONVERT(uint32_t, int32_t, _mesa_snorm_to_unorm(src, 32, 32)); } else { - SWIZZLE_CONVERT(uint32_t, int32_t, (src < 0) ? 0 : src); + SWIZZLE_CONVERT(uint32_t, int32_t, _mesa_signed_to_unsigned(src, 32)); } break; default: @@ -891,59 +1313,59 @@ convert_int(void *void_dst, int num_dst_channels, const void *void_src, GLenum src_type, int num_src_channels, const uint8_t swizzle[4], bool normalized, int count) { - const int32_t one = normalized ? INT32_MAX : 12; + const int32_t one = normalized ? INT32_MAX : 1; switch (src_type) { - case GL_FLOAT: + case MESA_ARRAY_FORMAT_TYPE_FLOAT: if (normalized) { - SWIZZLE_CONVERT(uint32_t, float, float_to_snorm(src, 32)); + SWIZZLE_CONVERT(uint32_t, float, _mesa_float_to_snorm(src, 32)); } else { - SWIZZLE_CONVERT(uint32_t, float, src); + SWIZZLE_CONVERT(uint32_t, float, _mesa_float_to_signed(src, 32)); } break; - case GL_HALF_FLOAT: + case MESA_ARRAY_FORMAT_TYPE_HALF: if (normalized) { - SWIZZLE_CONVERT(uint32_t, uint16_t, half_to_snorm(src, 32)); + SWIZZLE_CONVERT(uint32_t, uint16_t, _mesa_half_to_snorm(src, 32)); } else { - SWIZZLE_CONVERT(uint32_t, uint16_t, _mesa_half_to_float(src)); + SWIZZLE_CONVERT(uint32_t, uint16_t, _mesa_half_to_signed(src, 32)); } break; - case GL_UNSIGNED_BYTE: + case MESA_ARRAY_FORMAT_TYPE_UBYTE: if (normalized) { - SWIZZLE_CONVERT(int32_t, uint8_t, unorm_to_snorm(src, 8, 32)); + SWIZZLE_CONVERT(int32_t, uint8_t, _mesa_unorm_to_snorm(src, 8, 32)); } else { SWIZZLE_CONVERT(int32_t, uint8_t, src); } break; - case GL_BYTE: + case MESA_ARRAY_FORMAT_TYPE_BYTE: if (normalized) { - SWIZZLE_CONVERT(int32_t, int8_t, snorm_to_snorm(src, 8, 32)); + SWIZZLE_CONVERT(int32_t, int8_t, _mesa_snorm_to_snorm(src, 8, 32)); } else { SWIZZLE_CONVERT(int32_t, int8_t, src); } break; - case GL_UNSIGNED_SHORT: + case MESA_ARRAY_FORMAT_TYPE_USHORT: if (normalized) { - SWIZZLE_CONVERT(int32_t, uint16_t, unorm_to_snorm(src, 16, 32)); + SWIZZLE_CONVERT(int32_t, uint16_t, _mesa_unorm_to_snorm(src, 16, 32)); } else { SWIZZLE_CONVERT(int32_t, uint16_t, src); } break; - case GL_SHORT: + case MESA_ARRAY_FORMAT_TYPE_SHORT: if (normalized) { - SWIZZLE_CONVERT(int32_t, int16_t, snorm_to_snorm(src, 16, 32)); + SWIZZLE_CONVERT(int32_t, int16_t, _mesa_snorm_to_snorm(src, 16, 32)); } else { SWIZZLE_CONVERT(int32_t, int16_t, src); } break; - case GL_UNSIGNED_INT: + case MESA_ARRAY_FORMAT_TYPE_UINT: if (normalized) { - SWIZZLE_CONVERT(int32_t, uint32_t, unorm_to_snorm(src, 32, 32)); + SWIZZLE_CONVERT(int32_t, uint32_t, _mesa_unorm_to_snorm(src, 32, 32)); } else { - SWIZZLE_CONVERT(int32_t, uint32_t, src); + SWIZZLE_CONVERT(int32_t, uint32_t, _mesa_unsigned_to_signed(src, 32)); } break; - case GL_INT: + case MESA_ARRAY_FORMAT_TYPE_INT: SWIZZLE_CONVERT(int32_t, int32_t, src); break; default: @@ -1001,8 +1423,8 @@ convert_int(void *void_dst, int num_dst_channels, * \param[in] count the number of pixels to convert */ void -_mesa_swizzle_and_convert(void *void_dst, GLenum dst_type, int num_dst_channels, - const void *void_src, GLenum src_type, int num_src_channels, +_mesa_swizzle_and_convert(void *void_dst, enum mesa_array_format_datatype dst_type, int num_dst_channels, + const void *void_src, enum mesa_array_format_datatype src_type, int num_src_channels, const uint8_t swizzle[4], bool normalized, int count) { if (swizzle_convert_try_memcpy(void_dst, dst_type, num_dst_channels, @@ -1011,35 +1433,35 @@ _mesa_swizzle_and_convert(void *void_dst, GLenum dst_type, int num_dst_channels, return; switch (dst_type) { - case GL_FLOAT: + case MESA_ARRAY_FORMAT_TYPE_FLOAT: convert_float(void_dst, num_dst_channels, void_src, src_type, num_src_channels, swizzle, normalized, count); break; - case GL_HALF_FLOAT: + case MESA_ARRAY_FORMAT_TYPE_HALF: convert_half_float(void_dst, num_dst_channels, void_src, src_type, num_src_channels, swizzle, normalized, count); break; - case GL_UNSIGNED_BYTE: + case MESA_ARRAY_FORMAT_TYPE_UBYTE: convert_ubyte(void_dst, num_dst_channels, void_src, src_type, num_src_channels, swizzle, normalized, count); break; - case GL_BYTE: + case MESA_ARRAY_FORMAT_TYPE_BYTE: convert_byte(void_dst, num_dst_channels, void_src, src_type, num_src_channels, swizzle, normalized, count); break; - case GL_UNSIGNED_SHORT: + case MESA_ARRAY_FORMAT_TYPE_USHORT: convert_ushort(void_dst, num_dst_channels, void_src, src_type, num_src_channels, swizzle, normalized, count); break; - case GL_SHORT: + case MESA_ARRAY_FORMAT_TYPE_SHORT: convert_short(void_dst, num_dst_channels, void_src, src_type, num_src_channels, swizzle, normalized, count); break; - case GL_UNSIGNED_INT: + case MESA_ARRAY_FORMAT_TYPE_UINT: convert_uint(void_dst, num_dst_channels, void_src, src_type, num_src_channels, swizzle, normalized, count); break; - case GL_INT: + case MESA_ARRAY_FORMAT_TYPE_INT: convert_int(void_dst, num_dst_channels, void_src, src_type, num_src_channels, swizzle, normalized, count); break; diff --git a/mesalib/src/mesa/main/format_utils.h b/mesalib/src/mesa/main/format_utils.h index 9f778e377..7f500ec78 100644 --- a/mesalib/src/mesa/main/format_utils.h +++ b/mesalib/src/mesa/main/format_utils.h @@ -32,14 +32,205 @@ #define FORMAT_UTILS_H #include "imports.h" +#include "macros.h" + +extern const mesa_array_format RGBA32_FLOAT; +extern const mesa_array_format RGBA8_UBYTE; +extern const mesa_array_format RGBA32_UINT; +extern const mesa_array_format RGBA32_INT; + +/* Only guaranteed to work for BITS <= 32 */ +#define MAX_UINT(BITS) ((BITS) == 32 ? UINT32_MAX : ((1u << (BITS)) - 1)) +#define MAX_INT(BITS) ((int)MAX_UINT((BITS) - 1)) +#define MIN_INT(BITS) ((BITS) == 32 ? INT32_MIN : (-(1 << (BITS - 1)))) + +/* Extends an integer of size SRC_BITS to one of size DST_BITS linearly */ +#define EXTEND_NORMALIZED_INT(X, SRC_BITS, DST_BITS) \ + (((X) * (int)(MAX_UINT(DST_BITS) / MAX_UINT(SRC_BITS))) + \ + ((DST_BITS % SRC_BITS) ? ((X) >> (SRC_BITS - DST_BITS % SRC_BITS)) : 0)) + +static inline float +_mesa_unorm_to_float(unsigned x, unsigned src_bits) +{ + return x * (1.0f / (float)MAX_UINT(src_bits)); +} + +static inline float +_mesa_snorm_to_float(int x, unsigned src_bits) +{ + if (x <= -MAX_INT(src_bits)) + return -1.0f; + else + return x * (1.0f / (float)MAX_INT(src_bits)); +} + +static inline uint16_t +_mesa_unorm_to_half(unsigned x, unsigned src_bits) +{ + return _mesa_float_to_half(_mesa_unorm_to_float(x, src_bits)); +} + +static inline uint16_t +_mesa_snorm_to_half(int x, unsigned src_bits) +{ + return _mesa_float_to_half(_mesa_snorm_to_float(x, src_bits)); +} + +static inline unsigned +_mesa_float_to_unorm(float x, unsigned dst_bits) +{ + if (x < 0.0f) + return 0; + else if (x > 1.0f) + return MAX_UINT(dst_bits); + else + return F_TO_I(x * MAX_UINT(dst_bits)); +} + +static inline unsigned +_mesa_half_to_unorm(uint16_t x, unsigned dst_bits) +{ + return _mesa_float_to_unorm(_mesa_half_to_float(x), dst_bits); +} + +static inline unsigned +_mesa_unorm_to_unorm(unsigned x, unsigned src_bits, unsigned dst_bits) +{ + if (src_bits < dst_bits) { + return EXTEND_NORMALIZED_INT(x, src_bits, dst_bits); + } else { + unsigned src_half = (1 << (src_bits - 1)) - 1; + + if (src_bits + dst_bits > sizeof(x) * 8) { + assert(src_bits + dst_bits <= sizeof(uint64_t) * 8); + return (((uint64_t) x * MAX_UINT(dst_bits) + src_half) / + MAX_UINT(src_bits)); + } else { + return (x * MAX_UINT(dst_bits) + src_half) / MAX_UINT(src_bits); + } + } +} + +static inline unsigned +_mesa_snorm_to_unorm(int x, unsigned src_bits, unsigned dst_bits) +{ + if (x < 0) + return 0; + else + return _mesa_unorm_to_unorm(x, src_bits - 1, dst_bits); +} + +static inline int +_mesa_float_to_snorm(float x, unsigned dst_bits) +{ + if (x < -1.0f) + return -MAX_INT(dst_bits); + else if (x > 1.0f) + return MAX_INT(dst_bits); + else + return F_TO_I(x * MAX_INT(dst_bits)); +} + +static inline int +_mesa_half_to_snorm(uint16_t x, unsigned dst_bits) +{ + return _mesa_float_to_snorm(_mesa_half_to_float(x), dst_bits); +} + +static inline int +_mesa_unorm_to_snorm(unsigned x, unsigned src_bits, unsigned dst_bits) +{ + return _mesa_unorm_to_unorm(x, src_bits, dst_bits - 1); +} + +static inline int +_mesa_snorm_to_snorm(int x, unsigned src_bits, unsigned dst_bits) +{ + if (x < -MAX_INT(src_bits)) + return -MAX_INT(dst_bits); + else if (src_bits < dst_bits) + return EXTEND_NORMALIZED_INT(x, src_bits - 1, dst_bits - 1); + else + return x >> (src_bits - dst_bits); +} + +static inline unsigned +_mesa_unsigned_to_unsigned(unsigned src, unsigned dst_size) +{ + return MIN2(src, MAX_UINT(dst_size)); +} + +static inline int +_mesa_unsigned_to_signed(unsigned src, unsigned dst_size) +{ + return MIN2(src, (unsigned)MAX_INT(dst_size)); +} + +static inline int +_mesa_signed_to_signed(int src, unsigned dst_size) +{ + return CLAMP(src, MIN_INT(dst_size), MAX_INT(dst_size)); +} + +static inline unsigned +_mesa_signed_to_unsigned(int src, unsigned dst_size) +{ + return CLAMP(src, 0, MAX_UINT(dst_size)); +} + +static inline unsigned +_mesa_float_to_unsigned(float src, unsigned dst_bits) +{ + if (src < 0.0f) + return 0; + if (src > (float)MAX_UINT(dst_bits)) + return MAX_UINT(dst_bits); + return _mesa_signed_to_unsigned(src, dst_bits); +} + +static inline unsigned +_mesa_float_to_signed(float src, unsigned dst_bits) +{ + if (src < (float)(-MAX_INT(dst_bits))) + return -MAX_INT(dst_bits); + if (src > (float)MAX_INT(dst_bits)) + return MAX_INT(dst_bits); + return _mesa_signed_to_signed(src, dst_bits); +} + +static inline unsigned +_mesa_half_to_unsigned(uint16_t src, unsigned dst_bits) +{ + if (_mesa_half_is_negative(src)) + return 0; + return _mesa_unsigned_to_unsigned(_mesa_float_to_half(src), dst_bits); +} + +static inline unsigned +_mesa_half_to_signed(uint16_t src, unsigned dst_bits) +{ + return _mesa_float_to_signed(_mesa_half_to_float(src), dst_bits); +} bool _mesa_format_to_array(mesa_format, GLenum *type, int *num_components, uint8_t swizzle[4], bool *normalized); void -_mesa_swizzle_and_convert(void *dst, GLenum dst_type, int num_dst_channels, - const void *src, GLenum src_type, int num_src_channels, +_mesa_swizzle_and_convert(void *dst, + enum mesa_array_format_datatype dst_type, + int num_dst_channels, + const void *src, + enum mesa_array_format_datatype src_type, + int num_src_channels, const uint8_t swizzle[4], bool normalized, int count); +bool +_mesa_compute_rgba2base2rgba_component_mapping(GLenum baseFormat, uint8_t *map); + +void +_mesa_format_convert(void *void_dst, uint32_t dst_format, size_t dst_stride, + void *void_src, uint32_t src_format, size_t src_stride, + size_t width, size_t height, uint8_t *rebase_swizzle); + #endif diff --git a/mesalib/src/mesa/main/formatquery.c b/mesalib/src/mesa/main/formatquery.c index 40eca8711..7741cabad 100644 --- a/mesalib/src/mesa/main/formatquery.c +++ b/mesalib/src/mesa/main/formatquery.c @@ -89,8 +89,22 @@ _mesa_GetInternalformativ(GLenum target, GLenum internalformat, GLenum pname, * "If the parameter to GetInternalformativ is not * color-, depth- or stencil-renderable, then an INVALID_ENUM error is * generated." + * + * Page 243 of the GLES 3.0.4 spec says this for GetInternalformativ: + * + * "internalformat must be color-renderable, depth-renderable or + * stencilrenderable (as defined in section 4.4.4)." + * + * Section 4.4.4 on page 212 of the same spec says: + * + * "An internal format is color-renderable if it is one of the + * formats from table 3.13 noted as color-renderable or if it + * is unsized format RGBA or RGB." + * + * Therefore, we must accept GL_RGB and GL_RGBA here. */ - if (_mesa_base_fbo_format(ctx, internalformat) == 0) { + if (internalformat != GL_RGB && internalformat != GL_RGBA && + _mesa_base_fbo_format(ctx, internalformat) == 0) { _mesa_error(ctx, GL_INVALID_ENUM, "glGetInternalformativ(internalformat=%s)", _mesa_lookup_enum_by_nr(internalformat)); @@ -115,29 +129,40 @@ _mesa_GetInternalformativ(GLenum target, GLenum internalformat, GLenum pname, internalformat, buffer); break; case GL_NUM_SAMPLE_COUNTS: { - /* The driver can return 0, and we should pass that along to the - * application. The ARB decided that ARB_internalformat_query should - * behave as ARB_internalformat_query2 in this situation. - * - * The ARB_internalformat_query2 spec says: - * - * "- NUM_SAMPLE_COUNTS: The number of sample counts that would be - * returned by querying SAMPLES is returned in . - * * If is not color-renderable, - * depth-renderable, or stencil-renderable (as defined in - * section 4.4.4), or if does not support multiple - * samples (ie other than TEXTURE_2D_MULTISAMPLE, - * TEXTURE_2D_MULTISAMPLE_ARRAY, or RENDERBUFFER), 0 is - * returned." - */ - const size_t num_samples = - ctx->Driver.QuerySamplesForFormat(ctx, target, internalformat, buffer); - - /* QuerySamplesForFormat writes some stuff to buffer, so we have to - * separately over-write it with the requested value. - */ - buffer[0] = (GLint) num_samples; - count = 1; + if (_mesa_is_gles3(ctx) && _mesa_is_enum_format_integer(internalformat)) { + /* From GL ES 3.0 specification, section 6.1.15 page 236: "Since + * multisampling is not supported for signed and unsigned integer + * internal formats, the value of NUM_SAMPLE_COUNTS will be zero + * for such formats. + */ + buffer[0] = 0; + count = 1; + } else { + size_t num_samples; + + /* The driver can return 0, and we should pass that along to the + * application. The ARB decided that ARB_internalformat_query should + * behave as ARB_internalformat_query2 in this situation. + * + * The ARB_internalformat_query2 spec says: + * + * "- NUM_SAMPLE_COUNTS: The number of sample counts that would be + * returned by querying SAMPLES is returned in . + * * If is not color-renderable, + * depth-renderable, or stencil-renderable (as defined in + * section 4.4.4), or if does not support multiple + * samples (ie other than TEXTURE_2D_MULTISAMPLE, + * TEXTURE_2D_MULTISAMPLE_ARRAY, or RENDERBUFFER), 0 is + * returned." + */ + num_samples = ctx->Driver.QuerySamplesForFormat(ctx, target, internalformat, buffer); + + /* QuerySamplesForFormat writes some stuff to buffer, so we have to + * separately over-write it with the requested value. + */ + buffer[0] = (GLint) num_samples; + count = 1; + } break; } default: diff --git a/mesalib/src/mesa/main/formats.c b/mesalib/src/mesa/main/formats.c index 58c32e23b..958d6f245 100644 --- a/mesalib/src/mesa/main/formats.c +++ b/mesalib/src/mesa/main/formats.c @@ -28,7 +28,8 @@ #include "formats.h" #include "macros.h" #include "glformats.h" - +#include "c11/threads.h" +#include "util/hash_table.h" /** * Information about texture formats. @@ -71,6 +72,7 @@ struct gl_format_info GLubyte BytesPerBlock; uint8_t Swizzle[4]; + mesa_array_format ArrayFormat; }; #include "format_info.c" @@ -213,17 +215,87 @@ _mesa_get_format_datatype(mesa_format format) return info->DataType; } +static GLenum +get_base_format_for_array_format(mesa_array_format format) +{ + uint8_t swizzle[4]; + int num_channels; + + _mesa_array_format_get_swizzle(format, swizzle); + num_channels = _mesa_array_format_get_num_channels(format); + + switch (num_channels) { + case 4: + /* FIXME: RGBX formats have 4 channels, but their base format is GL_RGB. + * This is not really a problem for now because we only create array + * formats from GL format/type combinations, and these cannot specify + * RGBX formats. + */ + return GL_RGBA; + case 3: + return GL_RGB; + case 2: + if (swizzle[0] == 0 && + swizzle[1] == 0 && + swizzle[2] == 0 && + swizzle[3] == 1) + return GL_LUMINANCE_ALPHA; + if (swizzle[0] == 1 && + swizzle[1] == 1 && + swizzle[2] == 1 && + swizzle[3] == 0) + return GL_LUMINANCE_ALPHA; + if (swizzle[0] == 0 && + swizzle[1] == 1 && + swizzle[2] == 4 && + swizzle[3] == 5) + return GL_RG; + if (swizzle[0] == 1 && + swizzle[1] == 0 && + swizzle[2] == 4 && + swizzle[3] == 5) + return GL_RG; + break; + case 1: + if (swizzle[0] == 0 && + swizzle[1] == 0 && + swizzle[2] == 0 && + swizzle[3] == 5) + return GL_LUMINANCE; + if (swizzle[0] == 0 && + swizzle[1] == 0 && + swizzle[2] == 0 && + swizzle[3] == 0) + return GL_INTENSITY; + if (swizzle[0] <= MESA_FORMAT_SWIZZLE_W) + return GL_RED; + if (swizzle[1] <= MESA_FORMAT_SWIZZLE_W) + return GL_GREEN; + if (swizzle[2] <= MESA_FORMAT_SWIZZLE_W) + return GL_BLUE; + if (swizzle[3] <= MESA_FORMAT_SWIZZLE_W) + return GL_ALPHA; + break; + } + + unreachable("Unsupported format"); +} /** * Return the basic format for the given type. The result will be one of * GL_RGB, GL_RGBA, GL_ALPHA, GL_LUMINANCE, GL_LUMINANCE_ALPHA, GL_INTENSITY, * GL_YCBCR_MESA, GL_DEPTH_COMPONENT, GL_STENCIL_INDEX, GL_DEPTH_STENCIL. + * This functions accepts a mesa_format or a mesa_array_format. */ GLenum -_mesa_get_format_base_format(mesa_format format) +_mesa_get_format_base_format(uint32_t format) { - const struct gl_format_info *info = _mesa_get_format_info(format); - return info->BaseFormat; + if (!_mesa_format_is_mesa_array_format(format)) { + const struct gl_format_info *info = _mesa_get_format_info(format); + return info->BaseFormat; + } else { + return get_base_format_for_array_format(format); + } } @@ -269,6 +341,105 @@ _mesa_get_format_swizzle(mesa_format format, uint8_t swizzle_out[4]) memcpy(swizzle_out, info->Swizzle, sizeof(info->Swizzle)); } +mesa_array_format +_mesa_array_format_flip_channels(mesa_array_format format) +{ + int num_channels; + uint8_t swizzle[4]; + + num_channels = _mesa_array_format_get_num_channels(format); + _mesa_array_format_get_swizzle(format, swizzle); + + if (num_channels == 1) + return format; + + if (num_channels == 2) { + _mesa_array_format_set_swizzle(&format, swizzle[1], swizzle[0], + swizzle[2], swizzle[3]); + return format; + } + + if (num_channels == 4) { + _mesa_array_format_set_swizzle(&format, swizzle[3], swizzle[2], + swizzle[1], swizzle[0]); + return format; + } + + unreachable("Invalid array format"); +} + +uint32_t +_mesa_format_to_array_format(mesa_format format) +{ + const struct gl_format_info *info = _mesa_get_format_info(format); + if (_mesa_little_endian()) + return info->ArrayFormat; + else + return _mesa_array_format_flip_channels(info->ArrayFormat); +} + +static struct hash_table *format_array_format_table; +static once_flag format_array_format_table_exists = ONCE_FLAG_INIT; + +static bool +array_formats_equal(const void *a, const void *b) +{ + return (intptr_t)a == (intptr_t)b; +} + +static void +format_array_format_table_init() +{ + const struct gl_format_info *info; + mesa_array_format array_format; + unsigned f; + + format_array_format_table = _mesa_hash_table_create(NULL, NULL, + array_formats_equal); + + for (f = 1; f < MESA_FORMAT_COUNT; ++f) { + info = _mesa_get_format_info(f); + if (!info->ArrayFormat) + continue; + + if (_mesa_little_endian()) { + array_format = info->ArrayFormat; + } else { + array_format = _mesa_array_format_flip_channels(info->ArrayFormat); + } + + /* This can happen and does for some of the BGR formats. Let's take + * the first one in the list. + */ + if (_mesa_hash_table_search_pre_hashed(format_array_format_table, + array_format, + (void *)(intptr_t)array_format)) + continue; + + _mesa_hash_table_insert_pre_hashed(format_array_format_table, + array_format, + (void *)(intptr_t)array_format, + (void *)(intptr_t)f); + } +} + +mesa_format +_mesa_format_from_array_format(uint32_t array_format) +{ + struct hash_entry *entry; + + assert(_mesa_format_is_mesa_array_format(array_format)); + + call_once(&format_array_format_table_exists, format_array_format_table_init); + + entry = _mesa_hash_table_search_pre_hashed(format_array_format_table, + array_format, + (void *)(intptr_t)array_format); + if (entry) + return (intptr_t)entry->data; + else + return MESA_FORMAT_NONE; +} /** Is the given format a compressed format? */ GLboolean @@ -345,6 +516,25 @@ _mesa_is_format_integer(mesa_format format) return (info->DataType == GL_INT || info->DataType == GL_UNSIGNED_INT); } + +/** + * Return true if the given format is a color format. + */ +GLenum +_mesa_is_format_color_format(mesa_format format) +{ + const struct gl_format_info *info = _mesa_get_format_info(format); + switch (info->BaseFormat) { + case GL_DEPTH_COMPONENT: + case GL_STENCIL_INDEX: + case GL_DEPTH_STENCIL: + return false; + default: + return true; + } +} + + /** * Return color encoding for given format. * \return GL_LINEAR or GL_SRGB @@ -864,6 +1054,34 @@ _mesa_format_to_type_and_comps(mesa_format format, *comps = 1; return; + case MESA_FORMAT_R3G3B2_UNORM: + *datatype = GL_UNSIGNED_BYTE_2_3_3_REV; + *comps = 3; + return; + case MESA_FORMAT_A4B4G4R4_UNORM: + *datatype = GL_UNSIGNED_SHORT_4_4_4_4; + *comps = 4; + return; + + case MESA_FORMAT_R4G4B4A4_UNORM: + *datatype = GL_UNSIGNED_SHORT_4_4_4_4; + *comps = 4; + return; + case MESA_FORMAT_R5G5B5A1_UNORM: + *datatype = GL_UNSIGNED_SHORT_1_5_5_5_REV; + *comps = 4; + return; + case MESA_FORMAT_A2B10G10R10_UNORM: + case MESA_FORMAT_A2B10G10R10_UINT: + *datatype = GL_UNSIGNED_INT_10_10_10_2; + *comps = 4; + return; + case MESA_FORMAT_A2R10G10B10_UNORM: + case MESA_FORMAT_A2R10G10B10_UINT: + *datatype = GL_UNSIGNED_INT_10_10_10_2; + *comps = 4; + return; + case MESA_FORMAT_B2G3R3_UNORM: *datatype = GL_UNSIGNED_BYTE_3_3_2; *comps = 3; @@ -1265,6 +1483,7 @@ _mesa_format_to_type_and_comps(mesa_format format, return; case MESA_FORMAT_B10G10R10X2_UNORM: + case MESA_FORMAT_R10G10B10X2_UNORM: *datatype = GL_UNSIGNED_INT_2_10_10_10_REV; *comps = 4; return; @@ -1462,14 +1681,14 @@ _mesa_format_matches_format_and_type(mesa_format mesa_format, return format == GL_RGB && type == GL_UNSIGNED_BYTE && littleEndian; case MESA_FORMAT_B5G6R5_UNORM: - return format == GL_RGB && type == GL_UNSIGNED_SHORT_5_6_5 && !swapBytes; + return ((format == GL_RGB && type == GL_UNSIGNED_SHORT_5_6_5) || + (format == GL_BGR && type == GL_UNSIGNED_SHORT_5_6_5_REV)) && + !swapBytes; case MESA_FORMAT_R5G6B5_UNORM: - /* Some of the 16-bit MESA_FORMATs that would seem to correspond to - * GL_UNSIGNED_SHORT_* are byte-swapped instead of channel-reversed, - * according to formats.h, so they can't be matched. - */ - return GL_FALSE; + return ((format == GL_BGR && type == GL_UNSIGNED_SHORT_5_6_5) || + (format == GL_RGB && type == GL_UNSIGNED_SHORT_5_6_5_REV)) && + !swapBytes; case MESA_FORMAT_B4G4R4A4_UNORM: return format == GL_BGRA && type == GL_UNSIGNED_SHORT_4_4_4_4_REV && @@ -1487,7 +1706,8 @@ _mesa_format_matches_format_and_type(mesa_format mesa_format, !swapBytes; case MESA_FORMAT_A1R5G5B5_UNORM: - return GL_FALSE; + return format == GL_BGRA && type == GL_UNSIGNED_SHORT_5_5_5_1 && + !swapBytes; case MESA_FORMAT_L4A4_UNORM: return GL_FALSE; @@ -1506,6 +1726,54 @@ _mesa_format_matches_format_and_type(mesa_format mesa_format, case MESA_FORMAT_B2G3R3_UNORM: return format == GL_RGB && type == GL_UNSIGNED_BYTE_3_3_2; + case MESA_FORMAT_R3G3B2_UNORM: + return format == GL_RGB && type == GL_UNSIGNED_BYTE_2_3_3_REV; + + case MESA_FORMAT_A4B4G4R4_UNORM: + if (format == GL_RGBA && type == GL_UNSIGNED_SHORT_4_4_4_4 && !swapBytes) + return GL_TRUE; + + if (format == GL_RGBA && type == GL_UNSIGNED_SHORT_4_4_4_4_REV && swapBytes) + return GL_TRUE; + + if (format == GL_ABGR_EXT && type == GL_UNSIGNED_SHORT_4_4_4_4_REV && !swapBytes) + return GL_TRUE; + + if (format == GL_ABGR_EXT && type == GL_UNSIGNED_SHORT_4_4_4_4 && swapBytes) + return GL_TRUE; + + return GL_FALSE; + + case MESA_FORMAT_R4G4B4A4_UNORM: + if (format == GL_ABGR_EXT && type == GL_UNSIGNED_SHORT_4_4_4_4 && !swapBytes) + return GL_TRUE; + + if (format == GL_ABGR_EXT && type == GL_UNSIGNED_SHORT_4_4_4_4_REV && swapBytes) + return GL_TRUE; + + if (format == GL_RGBA && type == GL_UNSIGNED_SHORT_4_4_4_4_REV && !swapBytes) + return GL_TRUE; + + if (format == GL_RGBA && type == GL_UNSIGNED_SHORT_4_4_4_4 && swapBytes) + return GL_TRUE; + + return GL_FALSE; + + case MESA_FORMAT_R5G5B5A1_UNORM: + return format == GL_RGBA && type == GL_UNSIGNED_SHORT_1_5_5_5_REV; + + case MESA_FORMAT_A2B10G10R10_UNORM: + return format == GL_RGBA && type == GL_UNSIGNED_INT_10_10_10_2; + + case MESA_FORMAT_A2B10G10R10_UINT: + return format == GL_RGBA_INTEGER_EXT && type == GL_UNSIGNED_INT_10_10_10_2; + + case MESA_FORMAT_A2R10G10B10_UNORM: + return format == GL_BGRA && type == GL_UNSIGNED_INT_10_10_10_2; + + case MESA_FORMAT_A2R10G10B10_UINT: + return format == GL_BGRA_INTEGER_EXT && type == GL_UNSIGNED_INT_10_10_10_2; + case MESA_FORMAT_A_UNORM8: return format == GL_ALPHA && type == GL_UNSIGNED_BYTE; case MESA_FORMAT_A_UNORM16: @@ -1867,6 +2135,7 @@ _mesa_format_matches_format_and_type(mesa_format mesa_format, case MESA_FORMAT_RGBX_UINT8: case MESA_FORMAT_RGBX_SINT8: case MESA_FORMAT_B10G10R10X2_UNORM: + case MESA_FORMAT_R10G10B10X2_UNORM: case MESA_FORMAT_RGBX_UNORM16: case MESA_FORMAT_RGBX_SNORM16: case MESA_FORMAT_RGBX_FLOAT16: diff --git a/mesalib/src/mesa/main/formats.csv b/mesalib/src/mesa/main/formats.csv index 39bcdbdd2..e159e7dd6 100644 --- a/mesalib/src/mesa/main/formats.csv +++ b/mesalib/src/mesa/main/formats.csv @@ -82,12 +82,20 @@ MESA_FORMAT_G16R16_UNORM , packed, 1, 1, un16, un16, , MESA_FORMAT_B10G10R10A2_UNORM , packed, 1, 1, un10, un10, un10, un2 , zyxw, rgb MESA_FORMAT_B10G10R10X2_UNORM , packed, 1, 1, un10, un10, un10, x2 , zyx1, rgb MESA_FORMAT_R10G10B10A2_UNORM , packed, 1, 1, un10, un10, un10, un2 , xyzw, rgb +MESA_FORMAT_R10G10B10X2_UNORM , packed, 1, 1, un10, un10, un10, x2 , xyz1, rgb MESA_FORMAT_S8_UINT_Z24_UNORM , packed, 1, 1, un24, u8 , , , xy__, zs MESA_FORMAT_X8_UINT_Z24_UNORM , packed, 1, 1, un24, x8 , , , x___, zs MESA_FORMAT_Z24_UNORM_S8_UINT , packed, 1, 1, u8 , un24, , , yx__, zs MESA_FORMAT_Z24_UNORM_X8_UINT , packed, 1, 1, x8 , un24, , , y___, zs +MESA_FORMAT_R3G3B2_UNORM , packed, 1, 1, un3 , un3 , un2 , , xyz1, rgb +MESA_FORMAT_A4B4G4R4_UNORM , packed, 1, 1, un4 , un4 , un4 , un4 , wzyx, rgb +MESA_FORMAT_R4G4B4A4_UNORM , packed, 1, 1, un4 , un4 , un4 , un4 , xyzw, rgb +MESA_FORMAT_R5G5B5A1_UNORM , packed, 1, 1, un5 , un5 , un5 , un1 , xyzw, rgb +MESA_FORMAT_A2B10G10R10_UNORM , packed, 1, 1, un2 , un10, un10, un10, wzyx, rgb +MESA_FORMAT_A2R10G10B10_UNORM , packed, 1, 1, un2 , un10, un10, un10, yzwx, rgb + MESA_FORMAT_YCBCR , other , 1, 1, x16 , , , , xyzw, yuv MESA_FORMAT_YCBCR_REV , other , 1, 1, x16 , , , , xyzw, yuv @@ -180,6 +188,8 @@ MESA_FORMAT_Z_FLOAT32 , array , 1, 1, f32 , , , # Packed signed/unsigned non-normalized integer formats MESA_FORMAT_B10G10R10A2_UINT , packed, 1, 1, u10 , u10 , u10 , u2 , zyxw, rgb MESA_FORMAT_R10G10B10A2_UINT , packed, 1, 1, u10 , u10 , u10 , u2 , xyzw, rgb +MESA_FORMAT_A2B10G10R10_UINT , packed, 1, 1, u2 , u10 , u10 , u10 , wzyx, rgb +MESA_FORMAT_A2R10G10B10_UINT , packed, 1, 1, u2 , u10 , u10 , u10 , yzwx, rgb # Array signed/unsigned non-normalized integer formats MESA_FORMAT_A_UINT8 , array , 1, 1, u8 , , , , 000x, rgb diff --git a/mesalib/src/mesa/main/formats.h b/mesalib/src/mesa/main/formats.h index 213ab563d..7e451caf0 100644 --- a/mesalib/src/mesa/main/formats.h +++ b/mesalib/src/mesa/main/formats.h @@ -36,7 +36,7 @@ #include #include #include - +#include "compiler.h" #ifdef __cplusplus extern "C" { @@ -81,6 +81,132 @@ enum { MESA_FORMAT_SWIZZLE_NONE = 6, }; +/** + * An uint32_t that encodes the information necessary to represent an + * array format + */ +typedef uint32_t mesa_array_format; + +/** + * Encoding for valid array format data types + */ +enum mesa_array_format_datatype { + MESA_ARRAY_FORMAT_TYPE_UBYTE = 0x0, + MESA_ARRAY_FORMAT_TYPE_USHORT = 0x1, + MESA_ARRAY_FORMAT_TYPE_UINT = 0x2, + MESA_ARRAY_FORMAT_TYPE_BYTE = 0x4, + MESA_ARRAY_FORMAT_TYPE_SHORT = 0x5, + MESA_ARRAY_FORMAT_TYPE_INT = 0x6, + MESA_ARRAY_FORMAT_TYPE_HALF = 0xd, + MESA_ARRAY_FORMAT_TYPE_FLOAT = 0xe, +}; + +/** + * An enum useful to encode/decode information stored in a mesa_array_format + */ +enum { + MESA_ARRAY_FORMAT_TYPE_IS_SIGNED = 0x4, + MESA_ARRAY_FORMAT_TYPE_IS_FLOAT = 0x8, + MESA_ARRAY_FORMAT_TYPE_NORMALIZED = 0x10, + MESA_ARRAY_FORMAT_DATATYPE_MASK = 0xf, + MESA_ARRAY_FORMAT_TYPE_MASK = 0x1f, + MESA_ARRAY_FORMAT_TYPE_SIZE_MASK = 0x3, + MESA_ARRAY_FORMAT_NUM_CHANS_MASK = 0xe0, + MESA_ARRAY_FORMAT_SWIZZLE_X_MASK = 0x00700, + MESA_ARRAY_FORMAT_SWIZZLE_Y_MASK = 0x03800, + MESA_ARRAY_FORMAT_SWIZZLE_Z_MASK = 0x1c000, + MESA_ARRAY_FORMAT_SWIZZLE_W_MASK = 0xe0000, + MESA_ARRAY_FORMAT_BIT = 0x80000000 +}; + +#define MESA_ARRAY_FORMAT(SIZE, SIGNED, IS_FLOAT, NORM, NUM_CHANS, \ + SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_W) ( \ + (((SIZE >> 1) ) & MESA_ARRAY_FORMAT_TYPE_SIZE_MASK) | \ + (((SIGNED) << 2 ) & MESA_ARRAY_FORMAT_TYPE_IS_SIGNED) | \ + (((IS_FLOAT) << 3 ) & MESA_ARRAY_FORMAT_TYPE_IS_FLOAT) | \ + (((NORM) << 4 ) & MESA_ARRAY_FORMAT_TYPE_NORMALIZED) | \ + (((NUM_CHANS) << 5 ) & MESA_ARRAY_FORMAT_NUM_CHANS_MASK) | \ + (((SWIZZLE_X) << 8 ) & MESA_ARRAY_FORMAT_SWIZZLE_X_MASK) | \ + (((SWIZZLE_Y) << 11) & MESA_ARRAY_FORMAT_SWIZZLE_Y_MASK) | \ + (((SWIZZLE_Z) << 14) & MESA_ARRAY_FORMAT_SWIZZLE_Z_MASK) | \ + (((SWIZZLE_W) << 17) & MESA_ARRAY_FORMAT_SWIZZLE_W_MASK) | \ + MESA_ARRAY_FORMAT_BIT) + +/** + * Various helpers to access the data encoded in a mesa_array_format + */ +static inline bool +_mesa_array_format_is_signed(mesa_array_format f) +{ + return (f & MESA_ARRAY_FORMAT_TYPE_IS_SIGNED) != 0; +} + +static inline bool +_mesa_array_format_is_float(mesa_array_format f) +{ + return (f & MESA_ARRAY_FORMAT_TYPE_IS_FLOAT) != 0; +} + +static inline bool +_mesa_array_format_is_normalized(mesa_array_format f) +{ + return (f & MESA_ARRAY_FORMAT_TYPE_NORMALIZED) !=0; +} + +static inline enum mesa_array_format_datatype +_mesa_array_format_get_datatype(mesa_array_format f) +{ + return (enum mesa_array_format_datatype) + (f & MESA_ARRAY_FORMAT_DATATYPE_MASK); +} + +static inline int +_mesa_array_format_datatype_get_size(enum mesa_array_format_datatype type) +{ + return 1 << (type & MESA_ARRAY_FORMAT_TYPE_SIZE_MASK); +} + +static inline int +_mesa_array_format_get_type_size(mesa_array_format f) +{ + return 1 << (f & MESA_ARRAY_FORMAT_TYPE_SIZE_MASK); +} + +static inline int +_mesa_array_format_get_num_channels(mesa_array_format f) +{ + return (f & MESA_ARRAY_FORMAT_NUM_CHANS_MASK) >> 5; +} + +static inline void +_mesa_array_format_get_swizzle(mesa_array_format f, uint8_t *swizzle) +{ + swizzle[0] = (f & MESA_ARRAY_FORMAT_SWIZZLE_X_MASK) >> 8; + swizzle[1] = (f & MESA_ARRAY_FORMAT_SWIZZLE_Y_MASK) >> 11; + swizzle[2] = (f & MESA_ARRAY_FORMAT_SWIZZLE_Z_MASK) >> 14; + swizzle[3] = (f & MESA_ARRAY_FORMAT_SWIZZLE_W_MASK) >> 17; +} + +static inline void +_mesa_array_format_set_swizzle(mesa_array_format *f, + int32_t x, int32_t y, int32_t z, int32_t w) +{ + *f |= ((x << 8 ) & MESA_ARRAY_FORMAT_SWIZZLE_X_MASK) | + ((y << 11) & MESA_ARRAY_FORMAT_SWIZZLE_Y_MASK) | + ((z << 14) & MESA_ARRAY_FORMAT_SWIZZLE_Z_MASK) | + ((w << 17) & MESA_ARRAY_FORMAT_SWIZZLE_W_MASK); +} + +/** + * A helper to know if the format stored in a uint32_t is a mesa_format + * or a mesa_array_format + */ +static inline bool +_mesa_format_is_mesa_array_format(uint32_t f) +{ + return (f & MESA_ARRAY_FORMAT_BIT) != 0; +} + /** * Mesa texture/renderbuffer image formats. */ @@ -139,9 +265,9 @@ typedef enum * ** when type applies to all components * * examples: msb <------ TEXEL BITS -----------> lsb - * MESA_FORMAT_A8B8G8R8_UNORM, AAAA AAAA BBBB BBBB GGGG GGGG RRRR RRRR - * MESA_FORMAT_R5G6B5_UNORM RRRR RGGG GGGB BBBB - * MESA_FORMAT_B4G4R4X4_UNORM BBBB GGGG RRRR XXXX + * MESA_FORMAT_A8B8G8R8_UNORM, RRRR RRRR GGGG GGGG BBBB BBBB AAAA AAAA + * MESA_FORMAT_R5G6B5_UNORM BBBB BGGG GGGR RRRR + * MESA_FORMAT_B4G4R4X4_UNORM XXXX RRRR GGGG BBBB * MESA_FORMAT_Z32_FLOAT_S8X24_UINT * MESA_FORMAT_R10G10B10A2_UINT * MESA_FORMAT_R9G9B9E5_FLOAT @@ -226,12 +352,21 @@ typedef enum MESA_FORMAT_B10G10R10A2_UNORM,/* AARR RRRR RRRR GGGG GGGG GGBB BBBB BBBB */ MESA_FORMAT_B10G10R10X2_UNORM,/* xxRR RRRR RRRR GGGG GGGG GGBB BBBB BBBB */ MESA_FORMAT_R10G10B10A2_UNORM,/* AABB BBBB BBBB GGGG GGGG GGRR RRRR RRRR */ + MESA_FORMAT_R10G10B10X2_UNORM,/* xxBB BBBB BBBB GGGG GGGG GGRR RRRR RRRR */ MESA_FORMAT_S8_UINT_Z24_UNORM,/* ZZZZ ZZZZ ZZZZ ZZZZ ZZZZ ZZZZ SSSS SSSS */ MESA_FORMAT_X8_UINT_Z24_UNORM,/* ZZZZ ZZZZ ZZZZ ZZZZ ZZZZ ZZZZ xxxx xxxx */ MESA_FORMAT_Z24_UNORM_S8_UINT,/* SSSS SSSS ZZZZ ZZZZ ZZZZ ZZZZ ZZZZ ZZZZ */ MESA_FORMAT_Z24_UNORM_X8_UINT,/* xxxx xxxx ZZZZ ZZZZ ZZZZ ZZZZ ZZZZ ZZZZ */ + /* Other formats */ + MESA_FORMAT_R3G3B2_UNORM, /* BBGG GRRR */ + MESA_FORMAT_A4B4G4R4_UNORM, /* RRRR GGGG BBBB AAAA */ + MESA_FORMAT_R4G4B4A4_UNORM, /* AAAA BBBB GGGG RRRR */ + MESA_FORMAT_R5G5B5A1_UNORM, /* ABBB BBGG GGGR RRRR */ + MESA_FORMAT_A2B10G10R10_UNORM,/* RRRR RRRR RRGG GGGG GGGG BBBB BBBB BBAA */ + MESA_FORMAT_A2R10G10B10_UNORM,/* BBBB BBBB BBGG GGGG GGGG RRRR RRRR RRAA */ + MESA_FORMAT_YCBCR, /* YYYY YYYY UorV UorV */ MESA_FORMAT_YCBCR_REV, /* UorV UorV YYYY YYYY */ @@ -326,6 +461,8 @@ typedef enum /* Packed signed/unsigned non-normalized integer formats */ MESA_FORMAT_B10G10R10A2_UINT, /* AARR RRRR RRRR GGGG GGGG GGBB BBBB BBBB */ MESA_FORMAT_R10G10B10A2_UINT, /* AABB BBBB BBBB GGGG GGGG GGRR RRRR RRRR */ + MESA_FORMAT_A2B10G10R10_UINT, /* RRRR RRRR RRGG GGGG GGGG BBBB BBBB BBAA */ + MESA_FORMAT_A2R10G10B10_UINT, /* BBBB BBBB BBGG GGGG GGGG RRRR RRRR RRAA */ /* Array signed/unsigned non-normalized integer formats */ MESA_FORMAT_A_UINT8, @@ -461,14 +598,23 @@ extern GLenum _mesa_get_format_datatype(mesa_format format); extern GLenum -_mesa_get_format_base_format(mesa_format format); +_mesa_get_format_base_format(uint32_t format); extern void _mesa_get_format_block_size(mesa_format format, GLuint *bw, GLuint *bh); +extern mesa_array_format +_mesa_array_format_flip_channels(mesa_array_format format); + extern void _mesa_get_format_swizzle(mesa_format format, uint8_t swizzle_out[4]); +extern uint32_t +_mesa_format_to_array_format(mesa_format format); + +extern mesa_format +_mesa_format_from_array_format(uint32_t array_format); + extern GLboolean _mesa_is_format_compressed(mesa_format format); @@ -490,6 +636,9 @@ _mesa_is_format_integer(mesa_format format); extern bool _mesa_is_format_etc2(mesa_format format); +GLenum +_mesa_is_format_color_format(mesa_format format); + extern GLenum _mesa_get_format_color_encoding(mesa_format format); diff --git a/mesalib/src/mesa/main/framebuffer.c b/mesalib/src/mesa/main/framebuffer.c index 7416bb118..dc0386d23 100644 --- a/mesalib/src/mesa/main/framebuffer.c +++ b/mesalib/src/mesa/main/framebuffer.c @@ -345,7 +345,7 @@ update_framebuffer_size(struct gl_context *ctx, struct gl_framebuffer *fb) } } - if (minWidth != ~0) { + if (minWidth != ~0U) { fb->Width = minWidth; fb->Height = minHeight; } diff --git a/mesalib/src/mesa/main/genmipmap.c b/mesalib/src/mesa/main/genmipmap.c index 9d111cab2..9aef09019 100644 --- a/mesalib/src/mesa/main/genmipmap.c +++ b/mesalib/src/mesa/main/genmipmap.c @@ -36,21 +36,20 @@ #include "mtypes.h" #include "teximage.h" #include "texobj.h" - +#include "hash.h" /** - * Generate all the mipmap levels below the base level. - * Note: this GL function would be more useful if one could specify a - * cube face, a set of array slices, etc. + * Implements glGenerateMipmap and glGenerateTextureMipmap. + * Generates all the mipmap levels below the base level. */ -void GLAPIENTRY -_mesa_GenerateMipmap(GLenum target) +void +_mesa_generate_texture_mipmap(struct gl_context *ctx, + struct gl_texture_object *texObj, GLenum target, + bool dsa) { struct gl_texture_image *srcImage; - struct gl_texture_object *texObj; GLboolean error; - - GET_CURRENT_CONTEXT(ctx); + const char *suffix = dsa ? "Texture" : ""; FLUSH_VERTICES(ctx, 0); @@ -83,13 +82,11 @@ _mesa_GenerateMipmap(GLenum target) } if (error) { - _mesa_error(ctx, GL_INVALID_ENUM, "glGenerateMipmapEXT(target=%s)", - _mesa_lookup_enum_by_nr(target)); + _mesa_error(ctx, GL_INVALID_ENUM, "glGenerate%sMipmap(target=%s)", + suffix, _mesa_lookup_enum_by_nr(target)); return; } - texObj = _mesa_get_current_tex_object(ctx, target); - if (texObj->BaseLevel >= texObj->MaxLevel) { /* nothing to do */ return; @@ -98,17 +95,17 @@ _mesa_GenerateMipmap(GLenum target) if (texObj->Target == GL_TEXTURE_CUBE_MAP && !_mesa_cube_complete(texObj)) { _mesa_error(ctx, GL_INVALID_OPERATION, - "glGenerateMipmap(incomplete cube map)"); + "glGenerate%sMipmap(incomplete cube map)", suffix); return; } _mesa_lock_texture(ctx, texObj); - srcImage = _mesa_select_tex_image(ctx, texObj, target, texObj->BaseLevel); + srcImage = _mesa_select_tex_image(texObj, target, texObj->BaseLevel); if (!srcImage) { _mesa_unlock_texture(ctx, texObj); _mesa_error(ctx, GL_INVALID_OPERATION, - "glGenerateMipmap(zero size base image)"); + "glGenerate%sMipmap(zero size base image)", suffix); return; } @@ -117,19 +114,53 @@ _mesa_GenerateMipmap(GLenum target) _mesa_is_stencil_format(srcImage->InternalFormat)) { _mesa_unlock_texture(ctx, texObj); _mesa_error(ctx, GL_INVALID_OPERATION, - "glGenerateMipmap(invalid internal format)"); + "glGenerate%sMipmap(invalid internal format)", suffix); return; } if (target == GL_TEXTURE_CUBE_MAP) { GLuint face; - for (face = 0; face < 6; face++) - ctx->Driver.GenerateMipmap(ctx, - GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB + face, - texObj); + for (face = 0; face < 6; face++) { + ctx->Driver.GenerateMipmap(ctx, + GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB + face, texObj); + } } else { ctx->Driver.GenerateMipmap(ctx, target, texObj); } _mesa_unlock_texture(ctx, texObj); } + +/** + * Generate all the mipmap levels below the base level. + * Note: this GL function would be more useful if one could specify a + * cube face, a set of array slices, etc. + */ +void GLAPIENTRY +_mesa_GenerateMipmap(GLenum target) +{ + struct gl_texture_object *texObj; + GET_CURRENT_CONTEXT(ctx); + + texObj = _mesa_get_current_tex_object(ctx, target); + if (!texObj) + return; + + _mesa_generate_texture_mipmap(ctx, texObj, target, false); +} + +/** + * Generate all the mipmap levels below the base level. + */ +void GLAPIENTRY +_mesa_GenerateTextureMipmap(GLuint texture) +{ + struct gl_texture_object *texObj; + GET_CURRENT_CONTEXT(ctx); + + texObj = _mesa_lookup_texture_err(ctx, texture, "glGenerateTextureMipmap"); + if (!texObj) + return; + + _mesa_generate_texture_mipmap(ctx, texObj, texObj->Target, true); +} diff --git a/mesalib/src/mesa/main/genmipmap.h b/mesalib/src/mesa/main/genmipmap.h index d546a8d7b..f4ef85951 100644 --- a/mesalib/src/mesa/main/genmipmap.h +++ b/mesalib/src/mesa/main/genmipmap.h @@ -28,9 +28,15 @@ #include "glheader.h" +extern void +_mesa_generate_texture_mipmap(struct gl_context *ctx, + struct gl_texture_object *texObj, GLenum target, + bool dsa); extern void GLAPIENTRY _mesa_GenerateMipmap(GLenum target); +extern void GLAPIENTRY +_mesa_GenerateTextureMipmap(GLuint texture); #endif /* GENMIPMAP_H */ diff --git a/mesalib/src/mesa/main/get.c b/mesalib/src/mesa/main/get.c index 6091efc7f..3f9d74516 100644 --- a/mesalib/src/mesa/main/get.c +++ b/mesalib/src/mesa/main/get.c @@ -392,6 +392,7 @@ EXTRA_EXT2(ARB_transform_feedback3, ARB_gpu_shader5); EXTRA_EXT(INTEL_performance_query); EXTRA_EXT(ARB_explicit_uniform_location); EXTRA_EXT(ARB_clip_control); +EXTRA_EXT(EXT_polygon_offset_clamp); static const int extra_ARB_color_buffer_float_or_glcore[] = { diff --git a/mesalib/src/mesa/main/get_hash_params.py b/mesalib/src/mesa/main/get_hash_params.py index 09a61acc1..41cb2c17b 100644 --- a/mesalib/src/mesa/main/get_hash_params.py +++ b/mesalib/src/mesa/main/get_hash_params.py @@ -343,6 +343,7 @@ descriptor=[ # GL_ARB_ES3_compatibility [ "MAX_ELEMENT_INDEX", "CONTEXT_INT64(Const.MaxElementIndex), extra_ARB_ES3_compatibility_api_es3"], + [ "PRIMITIVE_RESTART_FIXED_INDEX", "CONTEXT_BOOL(Array.PrimitiveRestartFixedIndex), extra_ARB_ES3_compatibility_api_es3" ], # GL_ARB_fragment_shader [ "MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB", "CONTEXT_INT(Const.Program[MESA_SHADER_FRAGMENT].MaxUniformComponents), extra_ARB_fragment_shader" ], @@ -403,6 +404,11 @@ descriptor=[ [ "TEXTURE_EXTERNAL_OES", "LOC_CUSTOM, TYPE_BOOLEAN, 0, extra_OES_EGL_image_external" ], ]}, +{ "apis": ["GL", "GL_CORE", "GLES3"], "params": [ +# GL_ARB_sampler_objects / GL 3.3 / GLES 3.0 + [ "SAMPLER_BINDING", "LOC_CUSTOM, TYPE_INT, GL_SAMPLER_BINDING, NO_EXTRA" ], +]}, + # Remaining enums are only in OpenGL { "apis": ["GL", "GL_CORE"], "params": [ [ "ACCUM_RED_BITS", "BUFFER_INT(Visual.accumRedBits), NO_EXTRA" ], @@ -695,10 +701,6 @@ descriptor=[ [ "SAMPLE_MASK", "CONTEXT_BOOL(Multisample.SampleMask), extra_ARB_texture_multisample" ], [ "MAX_SAMPLE_MASK_WORDS", "CONST(1), extra_ARB_texture_multisample" ], - -# GL_ARB_sampler_objects / GL 3.3 - [ "SAMPLER_BINDING", "LOC_CUSTOM, TYPE_INT, GL_SAMPLER_BINDING, NO_EXTRA" ], - # GL 3.0 [ "CONTEXT_FLAGS", "CONTEXT_INT(Const.ContextFlags), extra_version_30" ], @@ -811,6 +813,9 @@ descriptor=[ [ "VIEWPORT_BOUNDS_RANGE", "CONTEXT_FLOAT2(Const.ViewportBounds), extra_ARB_viewport_array" ], [ "LAYER_PROVOKING_VERTEX", "CONTEXT_ENUM(Light.ProvokingVertex), extra_ARB_viewport_array" ], [ "VIEWPORT_INDEX_PROVOKING_VERTEX", "CONTEXT_ENUM(Light.ProvokingVertex), extra_ARB_viewport_array" ], + +# GL_EXT_polygon_offset_clamp + [ "POLYGON_OFFSET_CLAMP_EXT", "CONTEXT_FLOAT(Polygon.OffsetClamp), extra_EXT_polygon_offset_clamp" ], ]} ] diff --git a/mesalib/src/mesa/main/getstring.c b/mesalib/src/mesa/main/getstring.c index 431d60b03..1b2c7f054 100644 --- a/mesalib/src/mesa/main/getstring.c +++ b/mesalib/src/mesa/main/getstring.c @@ -58,6 +58,12 @@ shading_language_version(struct gl_context *ctx) return (const GLubyte *) "4.10"; case 420: return (const GLubyte *) "4.20"; + case 430: + return (const GLubyte *) "4.30"; + case 440: + return (const GLubyte *) "4.40"; + case 450: + return (const GLubyte *) "4.50"; default: _mesa_problem(ctx, "Invalid GLSL version in shading_language_version()"); @@ -68,7 +74,7 @@ shading_language_version(struct gl_context *ctx) case API_OPENGLES2: return (ctx->Version < 30) ? (const GLubyte *) "OpenGL ES GLSL ES 1.0.16" - : (const GLubyte *) "OpenGL ES GLSL ES 3.0"; + : (const GLubyte *) "OpenGL ES GLSL ES 3.00"; case API_OPENGLES: /* fall-through */ diff --git a/mesalib/src/mesa/main/glformats.c b/mesalib/src/mesa/main/glformats.c index 00478f989..4e05229cf 100644 --- a/mesalib/src/mesa/main/glformats.c +++ b/mesalib/src/mesa/main/glformats.c @@ -27,7 +27,205 @@ #include "context.h" #include "glformats.h" +#include "formats.h" +#include "enums.h" + +enum { + ZERO = 4, + ONE = 5 +}; + +enum { + IDX_LUMINANCE = 0, + IDX_ALPHA, + IDX_INTENSITY, + IDX_LUMINANCE_ALPHA, + IDX_RGB, + IDX_RGBA, + IDX_RED, + IDX_GREEN, + IDX_BLUE, + IDX_BGR, + IDX_BGRA, + IDX_ABGR, + IDX_RG, + MAX_IDX +}; + +#define MAP1(x) MAP4(x, ZERO, ZERO, ZERO) +#define MAP2(x,y) MAP4(x, y, ZERO, ZERO) +#define MAP3(x,y,z) MAP4(x, y, z, ZERO) +#define MAP4(x,y,z,w) { x, y, z, w, ZERO, ONE } + +static const struct { + GLubyte format_idx; + GLubyte to_rgba[6]; + GLubyte from_rgba[6]; +} mappings[MAX_IDX] = +{ + { + IDX_LUMINANCE, + MAP4(0,0,0,ONE), + MAP1(0) + }, + + { + IDX_ALPHA, + MAP4(ZERO, ZERO, ZERO, 0), + MAP1(3) + }, + + { + IDX_INTENSITY, + MAP4(0, 0, 0, 0), + MAP1(0), + }, + + { + IDX_LUMINANCE_ALPHA, + MAP4(0,0,0,1), + MAP2(0,3) + }, + + { + IDX_RGB, + MAP4(0,1,2,ONE), + MAP3(0,1,2) + }, + + { + IDX_RGBA, + MAP4(0,1,2,3), + MAP4(0,1,2,3), + }, + + { + IDX_RED, + MAP4(0, ZERO, ZERO, ONE), + MAP1(0), + }, + + { + IDX_GREEN, + MAP4(ZERO, 0, ZERO, ONE), + MAP1(1), + }, + + { + IDX_BLUE, + MAP4(ZERO, ZERO, 0, ONE), + MAP1(2), + }, + + { + IDX_BGR, + MAP4(2,1,0,ONE), + MAP3(2,1,0) + }, + + { + IDX_BGRA, + MAP4(2,1,0,3), + MAP4(2,1,0,3) + }, + + { + IDX_ABGR, + MAP4(3,2,1,0), + MAP4(3,2,1,0) + }, + + { + IDX_RG, + MAP4(0, 1, ZERO, ONE), + MAP2(0, 1) + }, +}; + +/** + * Convert a GL image format enum to an IDX_* value (see above). + */ +static int +get_map_idx(GLenum value) +{ + switch (value) { + case GL_LUMINANCE: + case GL_LUMINANCE_INTEGER_EXT: + return IDX_LUMINANCE; + case GL_ALPHA: + case GL_ALPHA_INTEGER: + return IDX_ALPHA; + case GL_INTENSITY: + return IDX_INTENSITY; + case GL_LUMINANCE_ALPHA: + case GL_LUMINANCE_ALPHA_INTEGER_EXT: + return IDX_LUMINANCE_ALPHA; + case GL_RGB: + case GL_RGB_INTEGER: + return IDX_RGB; + case GL_RGBA: + case GL_RGBA_INTEGER: + return IDX_RGBA; + case GL_RED: + case GL_RED_INTEGER: + return IDX_RED; + case GL_GREEN: + return IDX_GREEN; + case GL_BLUE: + return IDX_BLUE; + case GL_BGR: + case GL_BGR_INTEGER: + return IDX_BGR; + case GL_BGRA: + case GL_BGRA_INTEGER: + return IDX_BGRA; + case GL_ABGR_EXT: + return IDX_ABGR; + case GL_RG: + case GL_RG_INTEGER: + return IDX_RG; + default: + _mesa_problem(NULL, "Unexpected inFormat %s", + _mesa_lookup_enum_by_nr(value)); + return 0; + } +} +/** + * When promoting texture formats (see below) we need to compute the + * mapping of dest components back to source components. + * This function does that. + * \param inFormat the incoming format of the texture + * \param outFormat the final texture format + * \return map[6] a full 6-component map + */ +void +_mesa_compute_component_mapping(GLenum inFormat, GLenum outFormat, GLubyte *map) +{ + const int inFmt = get_map_idx(inFormat); + const int outFmt = get_map_idx(outFormat); + const GLubyte *in2rgba = mappings[inFmt].to_rgba; + const GLubyte *rgba2out = mappings[outFmt].from_rgba; + int i; + + for (i = 0; i < 4; i++) + map[i] = in2rgba[rgba2out[i]]; + + map[ZERO] = ZERO; + map[ONE] = ONE; + +#if 0 + printf("from %x/%s to %x/%s map %d %d %d %d %d %d\n", + inFormat, _mesa_lookup_enum_by_nr(inFormat), + outFormat, _mesa_lookup_enum_by_nr(outFormat), + map[0], + map[1], + map[2], + map[3], + map[4], + map[5]); +#endif +} /** * \return GL_TRUE if type is packed pixel type, GL_FALSE otherwise. @@ -93,6 +291,7 @@ _mesa_sizeof_type(GLenum type) case GL_DOUBLE: return sizeof(GLdouble); case GL_HALF_FLOAT_ARB: + case GL_HALF_FLOAT_OES: return sizeof(GLhalfARB); case GL_FIXED: return sizeof(GLfixed); @@ -125,6 +324,7 @@ _mesa_sizeof_packed_type(GLenum type) case GL_INT: return sizeof(GLint); case GL_HALF_FLOAT_ARB: + case GL_HALF_FLOAT_OES: return sizeof(GLhalfARB); case GL_FLOAT: return sizeof(GLfloat); @@ -241,6 +441,7 @@ _mesa_bytes_per_pixel(GLenum format, GLenum type) case GL_FLOAT: return comps * sizeof(GLfloat); case GL_HALF_FLOAT_ARB: + case GL_HALF_FLOAT_OES: return comps * sizeof(GLhalfARB); case GL_UNSIGNED_BYTE_3_3_2: case GL_UNSIGNED_BYTE_2_3_3_REV: @@ -258,18 +459,29 @@ _mesa_bytes_per_pixel(GLenum format, GLenum type) return -1; /* error */ case GL_UNSIGNED_SHORT_4_4_4_4: case GL_UNSIGNED_SHORT_4_4_4_4_REV: + if (format == GL_RGBA || format == GL_BGRA || format == GL_ABGR_EXT || + format == GL_RGBA_INTEGER_EXT || format == GL_BGRA_INTEGER_EXT) + return sizeof(GLushort); + else + return -1; case GL_UNSIGNED_SHORT_5_5_5_1: case GL_UNSIGNED_SHORT_1_5_5_5_REV: - if (format == GL_RGBA || format == GL_BGRA || format == GL_ABGR_EXT || + if (format == GL_RGBA || format == GL_BGRA || format == GL_RGBA_INTEGER_EXT || format == GL_BGRA_INTEGER_EXT) return sizeof(GLushort); else return -1; case GL_UNSIGNED_INT_8_8_8_8: case GL_UNSIGNED_INT_8_8_8_8_REV: + if (format == GL_RGBA || format == GL_BGRA || format == GL_ABGR_EXT || + format == GL_RGBA_INTEGER_EXT || format == GL_BGRA_INTEGER_EXT || + format == GL_RGB) + return sizeof(GLuint); + else + return -1; case GL_UNSIGNED_INT_10_10_10_2: case GL_UNSIGNED_INT_2_10_10_10_REV: - if (format == GL_RGBA || format == GL_BGRA || format == GL_ABGR_EXT || + if (format == GL_RGBA || format == GL_BGRA || format == GL_RGBA_INTEGER_EXT || format == GL_BGRA_INTEGER_EXT || format == GL_RGB) return sizeof(GLuint); @@ -1403,12 +1615,8 @@ _mesa_error_check_format_and_type(const struct gl_context *ctx, case GL_UNSIGNED_SHORT_4_4_4_4: case GL_UNSIGNED_SHORT_4_4_4_4_REV: - case GL_UNSIGNED_SHORT_5_5_5_1: - case GL_UNSIGNED_SHORT_1_5_5_5_REV: case GL_UNSIGNED_INT_8_8_8_8: case GL_UNSIGNED_INT_8_8_8_8_REV: - case GL_UNSIGNED_INT_10_10_10_2: - case GL_UNSIGNED_INT_2_10_10_10_REV: if (format == GL_RGBA || format == GL_BGRA || format == GL_ABGR_EXT) { @@ -1418,6 +1626,20 @@ _mesa_error_check_format_and_type(const struct gl_context *ctx, ctx->Extensions.ARB_texture_rgb10_a2ui) { break; /* OK */ } + return GL_INVALID_OPERATION; + + case GL_UNSIGNED_SHORT_5_5_5_1: + case GL_UNSIGNED_SHORT_1_5_5_5_REV: + case GL_UNSIGNED_INT_10_10_10_2: + case GL_UNSIGNED_INT_2_10_10_10_REV: + if (format == GL_RGBA || + format == GL_BGRA) { + break; /* OK */ + } + if ((format == GL_RGBA_INTEGER_EXT || format == GL_BGRA_INTEGER_EXT) && + ctx->Extensions.ARB_texture_rgb10_a2ui) { + break; /* OK */ + } if (type == GL_UNSIGNED_INT_2_10_10_10_REV && format == GL_RGB && ctx->API == API_OPENGLES2) { break; /* OK by GL_EXT_texture_type_2_10_10_10_REV */ @@ -1448,6 +1670,18 @@ _mesa_error_check_format_and_type(const struct gl_context *ctx, } return GL_NO_ERROR; + case GL_HALF_FLOAT_OES: + switch (format) { + case GL_RGBA: + case GL_RGB: + case GL_LUMINANCE_ALPHA: + case GL_LUMINANCE: + case GL_ALPHA: + return GL_NO_ERROR; + default: + return GL_INVALID_OPERATION; + } + default: ; /* fall-through */ } @@ -1561,7 +1795,6 @@ _mesa_error_check_format_and_type(const struct gl_context *ctx, case GL_RGBA: case GL_BGRA: - case GL_ABGR_EXT: switch (type) { case GL_BYTE: case GL_UNSIGNED_BYTE: @@ -1584,6 +1817,25 @@ _mesa_error_check_format_and_type(const struct gl_context *ctx, return GL_INVALID_ENUM; } + case GL_ABGR_EXT: + switch (type) { + case GL_BYTE: + case GL_UNSIGNED_BYTE: + case GL_SHORT: + case GL_UNSIGNED_SHORT: + case GL_INT: + case GL_UNSIGNED_INT: + case GL_FLOAT: + case GL_UNSIGNED_SHORT_4_4_4_4: + case GL_UNSIGNED_SHORT_4_4_4_4_REV: + case GL_UNSIGNED_INT_8_8_8_8: + case GL_UNSIGNED_INT_8_8_8_8_REV: + case GL_HALF_FLOAT: + return GL_NO_ERROR; + default: + return GL_INVALID_ENUM; + } + case GL_YCBCR_MESA: if (!ctx->Extensions.MESA_ycbcr_texture) return GL_INVALID_ENUM; @@ -1782,7 +2034,8 @@ _mesa_es_error_check_format_and_type(GLenum format, GLenum type, * \return error code, or GL_NO_ERROR. */ GLenum -_mesa_es3_error_check_format_and_type(GLenum format, GLenum type, +_mesa_es3_error_check_format_and_type(const struct gl_context *ctx, + GLenum format, GLenum type, GLenum internalFormat) { switch (format) { @@ -1847,11 +2100,17 @@ _mesa_es3_error_check_format_and_type(GLenum format, GLenum type, case GL_RGBA16F: case GL_RGBA32F: break; + case GL_RGBA: + if (ctx->Extensions.OES_texture_float && internalFormat == format) + break; default: return GL_INVALID_OPERATION; } break; + case GL_HALF_FLOAT_OES: + if (ctx->Extensions.OES_texture_half_float && internalFormat == format) + break; default: return GL_INVALID_OPERATION; } @@ -1956,11 +2215,19 @@ _mesa_es3_error_check_format_and_type(GLenum format, GLenum type, case GL_R11F_G11F_B10F: case GL_RGB9_E5: break; + case GL_RGB: + if (ctx->Extensions.OES_texture_float && internalFormat == format) + break; default: return GL_INVALID_OPERATION; } break; + case GL_HALF_FLOAT_OES: + if (!ctx->Extensions.OES_texture_half_float || internalFormat != format) + return GL_INVALID_OPERATION; + break; + case GL_UNSIGNED_INT_2_10_10_10_REV: switch (internalFormat) { case GL_RGB: /* GL_EXT_texture_type_2_10_10_10_REV */ @@ -2200,10 +2467,289 @@ _mesa_es3_error_check_format_and_type(GLenum format, GLenum type, case GL_ALPHA: case GL_LUMINANCE: case GL_LUMINANCE_ALPHA: - if (type != GL_UNSIGNED_BYTE || format != internalFormat) - return GL_INVALID_OPERATION; - break; + switch (type) { + case GL_FLOAT: + if (ctx->Extensions.OES_texture_float && internalFormat == format) + break; + case GL_HALF_FLOAT_OES: + if (ctx->Extensions.OES_texture_half_float && internalFormat == format) + break; + default: + if (type != GL_UNSIGNED_BYTE || format != internalFormat) + return GL_INVALID_OPERATION; + } } return GL_NO_ERROR; } + +static void +set_swizzle(uint8_t *swizzle, int x, int y, int z, int w) +{ + swizzle[MESA_FORMAT_SWIZZLE_X] = x; + swizzle[MESA_FORMAT_SWIZZLE_Y] = y; + swizzle[MESA_FORMAT_SWIZZLE_Z] = z; + swizzle[MESA_FORMAT_SWIZZLE_W] = w; +} + +static bool +get_swizzle_from_gl_format(GLenum format, uint8_t *swizzle) +{ + switch (format) { + case GL_RGBA: + case GL_RGBA_INTEGER_EXT: + set_swizzle(swizzle, 0, 1, 2, 3); + return true; + case GL_BGRA: + case GL_BGRA_INTEGER_EXT: + set_swizzle(swizzle, 2, 1, 0, 3); + return true; + case GL_ABGR_EXT: + set_swizzle(swizzle, 3, 2, 1, 0); + return true; + case GL_RGB: + case GL_RGB_INTEGER_EXT: + set_swizzle(swizzle, 0, 1, 2, 5); + return true; + case GL_BGR: + case GL_BGR_INTEGER_EXT: + set_swizzle(swizzle, 2, 1, 0, 5); + return true; + case GL_LUMINANCE_ALPHA: + case GL_LUMINANCE_ALPHA_INTEGER_EXT: + set_swizzle(swizzle, 0, 0, 0, 1); + return true; + case GL_RG: + case GL_RG_INTEGER: + set_swizzle(swizzle, 0, 1, 4, 5); + return true; + case GL_RED: + case GL_RED_INTEGER_EXT: + set_swizzle(swizzle, 0, 4, 4, 5); + return true; + case GL_GREEN: + case GL_GREEN_INTEGER_EXT: + set_swizzle(swizzle, 4, 0, 4, 5); + return true; + case GL_BLUE: + case GL_BLUE_INTEGER_EXT: + set_swizzle(swizzle, 4, 4, 0, 5); + return true; + case GL_ALPHA: + case GL_ALPHA_INTEGER_EXT: + set_swizzle(swizzle, 4, 4, 4, 0); + return true; + case GL_LUMINANCE: + case GL_LUMINANCE_INTEGER_EXT: + set_swizzle(swizzle, 0, 0, 0, 5); + return true; + case GL_INTENSITY: + set_swizzle(swizzle, 0, 0, 0, 0); + return true; + default: + return false; + } +} + +/** +* Take an OpenGL format (GL_RGB, GL_RGBA, etc), OpenGL data type (GL_INT, +* GL_FOAT, etc) and return a matching mesa_array_format or a mesa_format +* otherwise (for non-array formats). +* +* This function will typically be used to compute a mesa format from a GL type +* so we can then call _mesa_format_convert. This function does +* not consider byte swapping, so it returns types assuming that no byte +* swapping is involved. If byte swapping is involved then clients are supposed +* to handle that on their side before calling _mesa_format_convert. +* +* This function returns an uint32_t that can pack a mesa_format or a +* mesa_array_format. Clients must check the mesa array format bit +* (MESA_ARRAY_FORMAT_BIT) on the return value to know if the returned +* format is a mesa_array_format or a mesa_format. +*/ +uint32_t +_mesa_format_from_format_and_type(GLenum format, GLenum type) +{ + mesa_array_format array_format; + + bool is_array_format = true; + uint8_t swizzle[4]; + bool normalized = false, is_float = false, is_signed = false; + int num_channels = 0, type_size = 0; + + /* Extract array format type information from the OpenGL data type */ + switch (type) { + case GL_UNSIGNED_BYTE: + type_size = 1; + break; + case GL_BYTE: + type_size = 1; + is_signed = true; + break; + case GL_UNSIGNED_SHORT: + type_size = 2; + break; + case GL_SHORT: + type_size = 2; + is_signed = true; + break; + case GL_UNSIGNED_INT: + type_size = 4; + break; + case GL_INT: + type_size = 4; + is_signed = true; + break; + case GL_HALF_FLOAT: + case GL_HALF_FLOAT_OES: + type_size = 2; + is_signed = true; + is_float = true; + break; + case GL_FLOAT: + type_size = 4; + is_signed = true; + is_float = true; + break; + default: + is_array_format = false; + break; + } + + /* Extract array format swizzle information from the OpenGL format */ + if (is_array_format) + is_array_format = get_swizzle_from_gl_format(format, swizzle); + + /* If this is an array format type after checking data type and format, + * create the array format + */ + if (is_array_format) { + normalized = !_mesa_is_enum_format_integer(format); + num_channels = _mesa_components_in_format(format); + + array_format = + MESA_ARRAY_FORMAT(type_size, is_signed, is_float, + normalized, num_channels, + swizzle[0], swizzle[1], swizzle[2], swizzle[3]); + + if (!_mesa_little_endian()) + array_format = _mesa_array_format_flip_channels(array_format); + + return array_format; + } + + /* Otherwise this is not an array format, so return the mesa_format + * matching the OpenGL format and data type + */ + switch (type) { + case GL_UNSIGNED_SHORT_5_6_5: + if (format == GL_RGB) + return MESA_FORMAT_B5G6R5_UNORM; + else if (format == GL_BGR) + return MESA_FORMAT_R5G6B5_UNORM; + break; + case GL_UNSIGNED_SHORT_5_6_5_REV: + if (format == GL_RGB) + return MESA_FORMAT_R5G6B5_UNORM; + else if (format == GL_BGR) + return MESA_FORMAT_B5G6R5_UNORM; + break; + case GL_UNSIGNED_SHORT_4_4_4_4: + if (format == GL_RGBA) + return MESA_FORMAT_A4B4G4R4_UNORM; + else if (format == GL_BGRA) + return MESA_FORMAT_A4R4G4B4_UNORM; + else if (format == GL_ABGR_EXT) + return MESA_FORMAT_R4G4B4A4_UNORM; + break; + case GL_UNSIGNED_SHORT_4_4_4_4_REV: + if (format == GL_RGBA) + return MESA_FORMAT_R4G4B4A4_UNORM; + else if (format == GL_BGRA) + return MESA_FORMAT_B4G4R4A4_UNORM; + else if (format == GL_ABGR_EXT) + return MESA_FORMAT_A4B4G4R4_UNORM; + break; + case GL_UNSIGNED_SHORT_5_5_5_1: + if (format == GL_RGBA) + return MESA_FORMAT_A1B5G5R5_UNORM; + else if (format == GL_BGRA) + return MESA_FORMAT_A1R5G5B5_UNORM; + break; + case GL_UNSIGNED_SHORT_1_5_5_5_REV: + if (format == GL_RGBA) + return MESA_FORMAT_R5G5B5A1_UNORM; + else if (format == GL_BGRA) + return MESA_FORMAT_B5G5R5A1_UNORM; + break; + case GL_UNSIGNED_BYTE_3_3_2: + if (format == GL_RGB) + return MESA_FORMAT_B2G3R3_UNORM; + break; + case GL_UNSIGNED_BYTE_2_3_3_REV: + if (format == GL_RGB) + return MESA_FORMAT_R3G3B2_UNORM; + break; + case GL_UNSIGNED_INT_5_9_9_9_REV: + if (format == GL_RGB) + return MESA_FORMAT_R9G9B9E5_FLOAT; + break; + case GL_UNSIGNED_INT_10_10_10_2: + if (format == GL_RGBA) + return MESA_FORMAT_A2B10G10R10_UNORM; + else if (format == GL_RGBA_INTEGER) + return MESA_FORMAT_A2B10G10R10_UINT; + else if (format == GL_BGRA) + return MESA_FORMAT_A2R10G10B10_UNORM; + else if (format == GL_BGRA_INTEGER) + return MESA_FORMAT_A2R10G10B10_UINT; + break; + case GL_UNSIGNED_INT_2_10_10_10_REV: + if (format == GL_RGB) + return MESA_FORMAT_R10G10B10X2_UNORM; + if (format == GL_RGBA) + return MESA_FORMAT_R10G10B10A2_UNORM; + else if (format == GL_RGBA_INTEGER) + return MESA_FORMAT_R10G10B10A2_UINT; + else if (format == GL_BGRA) + return MESA_FORMAT_B10G10R10A2_UNORM; + else if (format == GL_BGRA_INTEGER) + return MESA_FORMAT_B10G10R10A2_UINT; + break; + case GL_UNSIGNED_INT_8_8_8_8: + if (format == GL_RGBA) + return MESA_FORMAT_A8B8G8R8_UNORM; + else if (format == GL_BGRA) + return MESA_FORMAT_A8R8G8B8_UNORM; + else if (format == GL_ABGR_EXT) + return MESA_FORMAT_R8G8B8A8_UNORM; + break; + case GL_UNSIGNED_INT_8_8_8_8_REV: + if (format == GL_RGBA) + return MESA_FORMAT_R8G8B8A8_UNORM; + else if (format == GL_BGRA) + return MESA_FORMAT_B8G8R8A8_UNORM; + else if (format == GL_ABGR_EXT) + return MESA_FORMAT_A8B8G8R8_UNORM; + break; + case GL_UNSIGNED_SHORT_8_8_MESA: + if (format == GL_YCBCR_MESA) + return MESA_FORMAT_YCBCR; + break; + case GL_UNSIGNED_SHORT_8_8_REV_MESA: + if (format == GL_YCBCR_MESA) + return MESA_FORMAT_YCBCR_REV; + break; + case GL_UNSIGNED_INT_10F_11F_11F_REV: + if (format == GL_RGB) + return MESA_FORMAT_R11G11B10_FLOAT; + default: + break; + } + + /* If we got here it means that we could not find a Mesa format that + * matches the GL format/type provided. We may need to add a new Mesa + * format in that case. + */ + unreachable("Unsupported format"); +} diff --git a/mesalib/src/mesa/main/glformats.h b/mesalib/src/mesa/main/glformats.h index 7b0321570..e1ecd64d5 100644 --- a/mesalib/src/mesa/main/glformats.h +++ b/mesalib/src/mesa/main/glformats.h @@ -35,6 +35,9 @@ extern "C" { #endif +extern void +_mesa_compute_component_mapping(GLenum inFormat, GLenum outFormat, GLubyte *map); + extern GLboolean _mesa_type_is_packed(GLenum type); @@ -122,9 +125,12 @@ _mesa_es_error_check_format_and_type(GLenum format, GLenum type, unsigned dimensions); extern GLenum -_mesa_es3_error_check_format_and_type(GLenum format, GLenum type, +_mesa_es3_error_check_format_and_type(const struct gl_context *ctx, + GLenum format, GLenum type, GLenum internalFormat); +extern uint32_t +_mesa_format_from_format_and_type(GLenum format, GLenum type); #ifdef __cplusplus } diff --git a/mesalib/src/mesa/main/hash.c b/mesalib/src/mesa/main/hash.c index 52095f7d1..1a152ec34 100644 --- a/mesalib/src/mesa/main/hash.c +++ b/mesalib/src/mesa/main/hash.c @@ -96,6 +96,12 @@ uint_hash(GLuint id) return id; } +static uint32_t +uint_key_hash(const void *key) +{ + return uint_hash((uintptr_t)key); +} + static void * uint_key(GLuint id) { @@ -114,7 +120,8 @@ _mesa_NewHashTable(void) struct _mesa_HashTable *table = CALLOC_STRUCT(_mesa_HashTable); if (table) { - table->ht = _mesa_hash_table_create(NULL, uint_key_compare); + table->ht = _mesa_hash_table_create(NULL, uint_key_hash, + uint_key_compare); if (table->ht == NULL) { free(table); _mesa_error_no_memory(__func__); @@ -175,7 +182,7 @@ _mesa_HashLookup_unlocked(struct _mesa_HashTable *table, GLuint key) if (key == DELETED_KEY_VALUE) return table->deleted_key_data; - entry = _mesa_hash_table_search(table->ht, uint_hash(key), uint_key(key)); + entry = _mesa_hash_table_search(table->ht, uint_key(key)); if (!entry) return NULL; @@ -266,11 +273,11 @@ _mesa_HashInsert_unlocked(struct _mesa_HashTable *table, GLuint key, void *data) if (key == DELETED_KEY_VALUE) { table->deleted_key_data = data; } else { - entry = _mesa_hash_table_search(table->ht, hash, uint_key(key)); + entry = _mesa_hash_table_search_pre_hashed(table->ht, hash, uint_key(key)); if (entry) { entry->data = data; } else { - _mesa_hash_table_insert(table->ht, hash, uint_key(key), data); + _mesa_hash_table_insert_pre_hashed(table->ht, hash, uint_key(key), data); } } } @@ -340,7 +347,7 @@ _mesa_HashRemove(struct _mesa_HashTable *table, GLuint key) if (key == DELETED_KEY_VALUE) { table->deleted_key_data = NULL; } else { - entry = _mesa_hash_table_search(table->ht, uint_hash(key), uint_key(key)); + entry = _mesa_hash_table_search(table->ht, uint_key(key)); _mesa_hash_table_remove(table->ht, entry); } mtx_unlock(&table->Mutex); diff --git a/mesalib/src/mesa/main/image.c b/mesalib/src/mesa/main/image.c index 4ea5f04c9..e97b006e0 100644 --- a/mesalib/src/mesa/main/image.c +++ b/mesalib/src/mesa/main/image.c @@ -41,36 +41,45 @@ /** - * Flip the order of the 2 bytes in each word in the given array. + * Flip the order of the 2 bytes in each word in the given array (src) and + * store the result in another array (dst). For in-place byte-swapping this + * function can be called with the same array for src and dst. * - * \param p array. + * \param dst the array where byte-swapped data will be stored. + * \param src the array with the source data we want to byte-swap. * \param n number of words. */ void -_mesa_swap2( GLushort *p, GLuint n ) +_mesa_swap2_copy( GLushort *dst, GLushort *src, GLuint n ) { GLuint i; for (i = 0; i < n; i++) { - p[i] = (p[i] >> 8) | ((p[i] << 8) & 0xff00); + dst[i] = (src[i] >> 8) | ((src[i] << 8) & 0xff00); } } /* - * Flip the order of the 4 bytes in each word in the given array. + * Flip the order of the 4 bytes in each word in the given array (src) and + * store the result in another array (dst). For in-place byte-swapping this + * function can be called with the same array for src and dst. + * + * \param dst the array where byte-swapped data will be stored. + * \param src the array with the source data we want to byte-swap. + * \param n number of words. */ void -_mesa_swap4( GLuint *p, GLuint n ) +_mesa_swap4_copy( GLuint *dst, GLuint *src, GLuint n ) { GLuint i, a, b; for (i = 0; i < n; i++) { - b = p[i]; + b = src[i]; a = (b >> 24) | ((b >> 8) & 0xff00) | ((b << 8) & 0xff0000) | ((b << 24) & 0xff000000); - p[i] = a; + dst[i] = a; } } @@ -142,7 +151,7 @@ _mesa_image_offset( GLuint dimensions, assert(format == GL_COLOR_INDEX || format == GL_STENCIL_INDEX); bytes_per_row = alignment - * CEILING( comp_per_pixel*pixels_per_row, 8*alignment ); + * DIV_ROUND_UP( comp_per_pixel*pixels_per_row, 8*alignment ); bytes_per_image = bytes_per_row * rows_per_image; @@ -852,19 +861,21 @@ clip_left_or_bottom(GLint *srcX0, GLint *srcX1, */ GLboolean _mesa_clip_blit(struct gl_context *ctx, + const struct gl_framebuffer *readFb, + const struct gl_framebuffer *drawFb, GLint *srcX0, GLint *srcY0, GLint *srcX1, GLint *srcY1, GLint *dstX0, GLint *dstY0, GLint *dstX1, GLint *dstY1) { const GLint srcXmin = 0; - const GLint srcXmax = ctx->ReadBuffer->Width; + const GLint srcXmax = readFb->Width; const GLint srcYmin = 0; - const GLint srcYmax = ctx->ReadBuffer->Height; + const GLint srcYmax = readFb->Height; /* these include scissor bounds */ - const GLint dstXmin = ctx->DrawBuffer->_Xmin; - const GLint dstXmax = ctx->DrawBuffer->_Xmax; - const GLint dstYmin = ctx->DrawBuffer->_Ymin; - const GLint dstYmax = ctx->DrawBuffer->_Ymax; + const GLint dstXmin = drawFb->_Xmin; + const GLint dstXmax = drawFb->_Xmax; + const GLint dstYmin = drawFb->_Ymin; + const GLint dstYmax = drawFb->_Ymax; /* printf("PreClipX: src: %d .. %d dst: %d .. %d\n", diff --git a/mesalib/src/mesa/main/image.h b/mesalib/src/mesa/main/image.h index abd84bf2f..501586bfb 100644 --- a/mesalib/src/mesa/main/image.h +++ b/mesalib/src/mesa/main/image.h @@ -28,15 +28,29 @@ #include "glheader.h" +#include "compiler.h" struct gl_context; struct gl_pixelstore_attrib; +struct gl_framebuffer; extern void -_mesa_swap2( GLushort *p, GLuint n ); +_mesa_swap2_copy(GLushort *dst, GLushort *src, GLuint n); extern void -_mesa_swap4( GLuint *p, GLuint n ); +_mesa_swap4_copy(GLuint *dst, GLuint *src, GLuint n); + +static inline void +_mesa_swap2(GLushort *p, GLuint n) +{ + _mesa_swap2_copy(p, p, n); +} + +static inline void +_mesa_swap4(GLuint *p, GLuint n) +{ + _mesa_swap4_copy(p, p, n); +} extern GLintptr _mesa_image_offset( GLuint dimensions, @@ -127,6 +141,8 @@ _mesa_clip_to_region(GLint xmin, GLint ymin, extern GLboolean _mesa_clip_blit(struct gl_context *ctx, + const struct gl_framebuffer *readFb, + const struct gl_framebuffer *drawFb, GLint *srcX0, GLint *srcY0, GLint *srcX1, GLint *srcY1, GLint *dstX0, GLint *dstY0, GLint *dstX1, GLint *dstY1); diff --git a/mesalib/src/mesa/main/light.c b/mesalib/src/mesa/main/light.c index d8ef8f258..e483b826e 100644 --- a/mesalib/src/mesa/main/light.c +++ b/mesalib/src/mesa/main/light.c @@ -30,7 +30,7 @@ #include "enums.h" #include "light.h" #include "macros.h" -#include "simple_list.h" +#include "util/simple_list.h" #include "mtypes.h" #include "math/m_matrix.h" @@ -1207,12 +1207,3 @@ _mesa_init_lighting( struct gl_context *ctx ) ctx->_ForceEyeCoords = GL_FALSE; ctx->_ModelViewInvScale = 1.0; } - - -/** - * Deallocate malloc'd lighting state attached to given context. - */ -void -_mesa_free_lighting_data( struct gl_context *ctx ) -{ -} diff --git a/mesalib/src/mesa/main/light.h b/mesalib/src/mesa/main/light.h index c6fba2ea3..d009aa175 100644 --- a/mesalib/src/mesa/main/light.h +++ b/mesalib/src/mesa/main/light.h @@ -102,8 +102,6 @@ extern void _mesa_update_color_material( struct gl_context *ctx, extern void _mesa_init_lighting( struct gl_context *ctx ); -extern void _mesa_free_lighting_data( struct gl_context *ctx ); - extern void _mesa_allow_light_in_model( struct gl_context *ctx, GLboolean flag ); #endif diff --git a/mesalib/src/mesa/main/macros.h b/mesalib/src/mesa/main/macros.h index 5fc8f6b08..45e35a70d 100755 --- a/mesalib/src/mesa/main/macros.h +++ b/mesalib/src/mesa/main/macros.h @@ -31,6 +31,7 @@ #ifndef MACROS_H #define MACROS_H +#include "util/u_math.h" #include "imports.h" @@ -274,14 +275,6 @@ COPY_4UBV(GLubyte dst[4], const GLubyte src[4]) #endif } -/** Copy a 4-element float vector */ -static inline void -COPY_4FV(GLfloat dst[4], const GLfloat src[4]) -{ - /* memcpy seems to be most efficient */ - memcpy(dst, src, sizeof(GLfloat) * 4); -} - /** Copy \p SZ elements into a 4-element vector */ #define COPY_SZ_4V(DST, SZ, SRC) \ do { \ @@ -373,15 +366,6 @@ do { \ (DST)[3] *= S; \ } while (0) -/** Assignment */ -#define ASSIGN_4V( V, V0, V1, V2, V3 ) \ -do { \ - V[0] = V0; \ - V[1] = V1; \ - V[2] = V2; \ - V[3] = V3; \ -} while(0) - /*@}*/ @@ -808,7 +792,7 @@ DIFFERENT_SIGNS(GLfloat x, GLfloat y) /** Compute ceiling of integer quotient of A divided by B. */ -#define CEILING( A, B ) ( (A) % (B) == 0 ? (A)/(B) : (A)/(B)+1 ) +#define DIV_ROUND_UP( A, B ) ( (A) % (B) == 0 ? (A)/(B) : (A)/(B)+1 ) /** casts to silence warnings with some compilers */ diff --git a/mesalib/src/mesa/main/matrix.c b/mesalib/src/mesa/main/matrix.c index 99a501321..0539caa47 100644 --- a/mesalib/src/mesa/main/matrix.c +++ b/mesalib/src/mesa/main/matrix.c @@ -690,7 +690,7 @@ free_matrix_stack( struct gl_matrix_stack *stack ) */ void _mesa_init_matrix( struct gl_context * ctx ) { - GLint i; + GLuint i; /* Initialize matrix stacks */ init_matrix_stack(&ctx->ModelviewMatrixStack, MAX_MODELVIEW_STACK_DEPTH, @@ -701,7 +701,7 @@ void _mesa_init_matrix( struct gl_context * ctx ) init_matrix_stack(&ctx->TextureMatrixStack[i], MAX_TEXTURE_STACK_DEPTH, _NEW_TEXTURE_MATRIX); for (i = 0; i < Elements(ctx->ProgramMatrixStack); i++) - init_matrix_stack(&ctx->ProgramMatrixStack[i], + init_matrix_stack(&ctx->ProgramMatrixStack[i], MAX_PROGRAM_MATRIX_STACK_DEPTH, _NEW_TRACK_MATRIX); ctx->CurrentStack = &ctx->ModelviewMatrixStack; @@ -720,7 +720,7 @@ void _mesa_init_matrix( struct gl_context * ctx ) */ void _mesa_free_matrix_data( struct gl_context *ctx ) { - GLint i; + GLuint i; free_matrix_stack(&ctx->ModelviewMatrixStack); free_matrix_stack(&ctx->ProjectionMatrixStack); diff --git a/mesalib/src/mesa/main/mipmap.c b/mesalib/src/mesa/main/mipmap.c index fdaa68282..75a12cd16 100644 --- a/mesalib/src/mesa/main/mipmap.c +++ b/mesalib/src/mesa/main/mipmap.c @@ -1901,7 +1901,7 @@ generate_mipmap_uncompressed(struct gl_context *ctx, GLenum target, GLboolean success = GL_TRUE; /* get src image parameters */ - srcImage = _mesa_select_tex_image(ctx, texObj, target, level); + srcImage = _mesa_select_tex_image(texObj, target, level); ASSERT(srcImage); srcWidth = srcImage->Width; srcHeight = srcImage->Height; @@ -2093,10 +2093,10 @@ generate_mipmap_compressed(struct gl_context *ctx, GLenum target, GLint border; GLboolean nextLevel; GLuint temp_dst_row_stride, temp_dst_img_stride; /* in bytes */ - GLuint i; + GLint i; /* get src image parameters */ - srcImage = _mesa_select_tex_image(ctx, texObj, target, level); + srcImage = _mesa_select_tex_image(texObj, target, level); ASSERT(srcImage); srcWidth = srcImage->Width; srcHeight = srcImage->Height; @@ -2193,7 +2193,7 @@ _mesa_generate_mipmap(struct gl_context *ctx, GLenum target, GLint maxLevel; ASSERT(texObj); - srcImage = _mesa_select_tex_image(ctx, texObj, target, texObj->BaseLevel); + srcImage = _mesa_select_tex_image(texObj, target, texObj->BaseLevel); ASSERT(srcImage); maxLevel = _mesa_max_texture_levels(ctx, texObj->Target) - 1; diff --git a/mesalib/src/mesa/main/mtypes.h b/mesalib/src/mesa/main/mtypes.h index 7389baa1d..6e9977309 100644 --- a/mesalib/src/mesa/main/mtypes.h +++ b/mesalib/src/mesa/main/mtypes.h @@ -41,7 +41,7 @@ #include "main/config.h" #include "glapi/glapi.h" #include "math/m_matrix.h" /* GLmatrix */ -#include "main/simple_list.h" /* struct simple_node */ +#include "util/simple_list.h" /* struct simple_node */ #include "main/formats.h" /* MESA_FORMAT_COUNT */ @@ -1004,6 +1004,7 @@ struct gl_polygon_attrib GLenum CullFaceMode; /**< Culling mode GL_FRONT or GL_BACK */ GLfloat OffsetFactor; /**< Polygon offset factor, from user */ GLfloat OffsetUnits; /**< Polygon offset units, from user */ + GLfloat OffsetClamp; /**< Polygon offset clamp, from user */ GLboolean OffsetPoint; /**< Offset in GL_POINT mode */ GLboolean OffsetLine; /**< Offset in GL_LINE mode */ GLboolean OffsetFill; /**< Offset in GL_FILL mode */ @@ -1220,6 +1221,8 @@ struct gl_texture_object GLboolean Purgeable; /**< Is the buffer purgeable under memory pressure? */ GLboolean Immutable; /**< GL_ARB_texture_storage */ + GLboolean _IsFloat; /**< GL_OES_float_texture */ + GLboolean _IsHalfFloat; /**< GL_OES_half_float_texture */ GLuint MinLevel; /**< GL_ARB_texture_view */ GLuint MinLayer; /**< GL_ARB_texture_view */ @@ -1657,6 +1660,20 @@ typedef enum { DRAW_ARRAYS } gl_draw_method; +/** + * Enum for the OpenGL APIs we know about and may support. + * + * NOTE: This must match the api_enum table in + * src/mesa/main/get_hash_generator.py + */ +typedef enum +{ + API_OPENGL_COMPAT, /* legacy / compatibility contexts */ + API_OPENGLES, + API_OPENGLES2, + API_OPENGL_CORE, + API_OPENGL_LAST = API_OPENGL_CORE +} gl_api; /** * Vertex array state @@ -1701,8 +1718,9 @@ struct gl_array_attrib /** One of the DRAW_xxx flags, not consumed by drivers */ gl_draw_method DrawMethod; - /** Legal array datatypes */ + /** Legal array datatypes and the API for which they have been computed */ GLbitfield LegalTypesMask; + gl_api LegalTypesMaskAPI; }; @@ -2990,6 +3008,7 @@ struct gl_shader_compiler_options GLboolean EmitNoMainReturn; /**< Emit CONT/RET opcodes? */ GLboolean EmitNoNoise; /**< Emit NOISE opcodes? */ GLboolean EmitNoPow; /**< Emit POW opcodes? */ + GLboolean EmitNoSat; /**< Emit SAT opcodes? */ GLboolean LowerClipDistance; /**< Lower gl_ClipDistance from float[8] to vec4[2]? */ /** @@ -3015,6 +3034,8 @@ struct gl_shader_compiler_options GLboolean OptimizeForAOS; struct gl_sl_pragmas DefaultPragmas; /**< Default #pragma settings */ + + struct nir_shader_compiler_options *NirOptions; }; @@ -3053,6 +3074,9 @@ struct gl_query_state /** GL_ARB_timer_query */ struct gl_query_object *TimeElapsed; + /** GL_ARB_pipeline_statistics_query */ + struct gl_query_object *pipeline_stats[MAX_PIPELINE_STATISTICS]; + GLenum CondRenderMode; }; @@ -3439,6 +3463,17 @@ struct gl_constants GLuint Timestamp; GLuint PrimitivesGenerated; GLuint PrimitivesWritten; + GLuint VerticesSubmitted; + GLuint PrimitivesSubmitted; + GLuint VsInvocations; + GLuint TessPatches; + GLuint TessInvocations; + GLuint GsInvocations; + GLuint GsPrimitives; + GLuint FsInvocations; + GLuint ComputeInvocations; + GLuint ClInPrimitives; + GLuint ClOutPrimitives; } QueryCounterBits; GLuint MaxDrawBuffers; /**< GL_ARB_draw_buffers */ @@ -3729,18 +3764,21 @@ struct gl_extensions GLboolean ARB_explicit_uniform_location; GLboolean ARB_geometry_shader4; GLboolean ARB_gpu_shader5; + GLboolean ARB_gpu_shader_fp64; GLboolean ARB_half_float_vertex; GLboolean ARB_instanced_arrays; GLboolean ARB_internalformat_query; GLboolean ARB_map_buffer_range; GLboolean ARB_occlusion_query; GLboolean ARB_occlusion_query2; + GLboolean ARB_pipeline_statistics_query; GLboolean ARB_point_sprite; GLboolean ARB_sample_shading; GLboolean ARB_seamless_cube_map; GLboolean ARB_shader_atomic_counters; GLboolean ARB_shader_bit_encoding; GLboolean ARB_shader_image_load_store; + GLboolean ARB_shader_precision; GLboolean ARB_shader_stencil_export; GLboolean ARB_shader_texture_lod; GLboolean ARB_shading_language_packing; @@ -3748,6 +3786,7 @@ struct gl_extensions GLboolean ARB_shadow; GLboolean ARB_stencil_texturing; GLboolean ARB_sync; + GLboolean ARB_tessellation_shader; GLboolean ARB_texture_border_clamp; GLboolean ARB_texture_buffer_object; GLboolean ARB_texture_buffer_object_rgb32; @@ -3794,6 +3833,7 @@ struct gl_extensions GLboolean EXT_packed_float; GLboolean EXT_pixel_buffer_object; GLboolean EXT_point_parameters; + GLboolean EXT_polygon_offset_clamp; GLboolean EXT_provoking_vertex; GLboolean EXT_shader_integer_mix; GLboolean EXT_stencil_two_side; @@ -3816,6 +3856,7 @@ struct gl_extensions GLboolean OES_standard_derivatives; /* vendor extensions */ GLboolean AMD_performance_monitor; + GLboolean AMD_pinned_memory; GLboolean AMD_seamless_cubemap_per_texture; GLboolean AMD_vertex_shader_layer; GLboolean AMD_vertex_shader_viewport_index; @@ -3842,6 +3883,10 @@ struct gl_extensions GLboolean OES_draw_texture; GLboolean OES_depth_texture_cube_map; GLboolean OES_EGL_image_external; + GLboolean OES_texture_float; + GLboolean OES_texture_float_linear; + GLboolean OES_texture_half_float; + GLboolean OES_texture_half_float_linear; GLboolean OES_compressed_ETC1_RGB8_texture; GLboolean extension_sentinel; /** The extension string */ @@ -4038,21 +4083,6 @@ enum mesa_debug_severity { /** @} */ -/** - * Enum for the OpenGL APIs we know about and may support. - * - * NOTE: This must match the api_enum table in - * src/mesa/main/get_hash_generator.py - */ -typedef enum -{ - API_OPENGL_COMPAT, /* legacy / compatibility contexts */ - API_OPENGLES, - API_OPENGLES2, - API_OPENGL_CORE, - API_OPENGL_LAST = API_OPENGL_CORE -} gl_api; - /** * Driver-specific state flags. * @@ -4367,6 +4397,12 @@ struct gl_context */ struct gl_buffer_object *AtomicBuffer; + /** + * Object currently associated w/ the GL_EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD + * target. + */ + struct gl_buffer_object *ExternalVirtualMemoryBuffer; + /** * Array of atomic counter buffer binding points. */ @@ -4476,9 +4512,6 @@ extern int MESA_DEBUG_FLAGS; # define MESA_VERBOSE 0 # define MESA_DEBUG_FLAGS 0 # define MESA_FUNCTION "a function" -# ifndef NDEBUG -# define NDEBUG -# endif #endif diff --git a/mesalib/src/mesa/main/multisample.c b/mesalib/src/mesa/main/multisample.c index 1f3fa0c15..b696de9f2 100644 --- a/mesalib/src/mesa/main/multisample.c +++ b/mesalib/src/mesa/main/multisample.c @@ -150,6 +150,16 @@ GLenum _mesa_check_sample_count(struct gl_context *ctx, GLenum target, GLenum internalFormat, GLsizei samples) { + /* Section 4.4 (Framebuffer objects) of the OpenGL 3.0 specification says: + * + * "If internalformat is a signed or unsigned integer format and samples + * is greater than zero, then the error INVALID_OPERATION is generated." + */ + if (_mesa_is_gles3(ctx) && _mesa_is_enum_format_integer(internalFormat)) { + return GL_INVALID_OPERATION; + } + + /* If ARB_internalformat_query is supported, then treat its highest * returned sample count as the absolute maximum for this format; it is * allowed to exceed MAX_SAMPLES. diff --git a/mesalib/src/mesa/main/objectlabel.c b/mesalib/src/mesa/main/objectlabel.c index 8efc33e0d..78df96b9b 100644 --- a/mesalib/src/mesa/main/objectlabel.c +++ b/mesalib/src/mesa/main/objectlabel.c @@ -45,11 +45,8 @@ static void set_label(struct gl_context *ctx, char **labelPtr, const char *label, int length, const char *caller) { - if (*labelPtr) { - /* free old label string */ - free(*labelPtr); - *labelPtr = NULL; - } + free(*labelPtr); + *labelPtr = NULL; /* set new label string */ if (label) { @@ -61,7 +58,7 @@ set_label(struct gl_context *ctx, char **labelPtr, const char *label, MAX_LABEL_LENGTH); /* explicit length */ - *labelPtr = (char *) malloc(length+1); + *labelPtr = malloc(length+1); if (*labelPtr) { memcpy(*labelPtr, label, length); /* length is not required to include the null terminator so diff --git a/mesalib/src/mesa/main/pack.c b/mesalib/src/mesa/main/pack.c index 649a74cce..2111a7604 100644 --- a/mesalib/src/mesa/main/pack.c +++ b/mesalib/src/mesa/main/pack.c @@ -53,8 +53,8 @@ #include "pixeltransfer.h" #include "imports.h" #include "glformats.h" -#include "../../gallium/auxiliary/util/u_format_rgb9e5.h" -#include "../../gallium/auxiliary/util/u_format_r11g11b10f.h" +#include "format_utils.h" +#include "format_pack.h" /** @@ -98,7 +98,8 @@ void _mesa_unpack_polygon_stipple( const GLubyte *pattern, GLuint dest[32], const struct gl_pixelstore_attrib *unpacking ) { - GLubyte *ptrn = (GLubyte *) _mesa_unpack_bitmap(32, 32, pattern, unpacking); + GLubyte *ptrn = (GLubyte *) _mesa_unpack_image(2, 32, 32, 1, GL_COLOR_INDEX, + GL_BITMAP, pattern, unpacking); if (ptrn) { /* Convert pattern from GLubytes to GLuints and handle big/little * endian differences @@ -141,108 +142,6 @@ _mesa_pack_polygon_stipple( const GLuint pattern[32], GLubyte *dest, } -/* - * Unpack bitmap data. Resulting data will be in most-significant-bit-first - * order with row alignment = 1 byte. - */ -GLvoid * -_mesa_unpack_bitmap( GLint width, GLint height, const GLubyte *pixels, - const struct gl_pixelstore_attrib *packing ) -{ - GLint bytes, row, width_in_bytes; - GLubyte *buffer, *dst; - - if (!pixels) - return NULL; - - /* Alloc dest storage */ - bytes = ((width + 7) / 8 * height); - buffer = malloc( bytes ); - if (!buffer) - return NULL; - - width_in_bytes = CEILING( width, 8 ); - dst = buffer; - for (row = 0; row < height; row++) { - const GLubyte *src = (const GLubyte *) - _mesa_image_address2d(packing, pixels, width, height, - GL_COLOR_INDEX, GL_BITMAP, row, 0); - if (!src) { - free(buffer); - return NULL; - } - - if ((packing->SkipPixels & 7) == 0) { - memcpy( dst, src, width_in_bytes ); - if (packing->LsbFirst) { - flip_bytes( dst, width_in_bytes ); - } - } - else { - /* handling SkipPixels is a bit tricky (no pun intended!) */ - GLint i; - if (packing->LsbFirst) { - GLubyte srcMask = 1 << (packing->SkipPixels & 0x7); - GLubyte dstMask = 128; - const GLubyte *s = src; - GLubyte *d = dst; - *d = 0; - for (i = 0; i < width; i++) { - if (*s & srcMask) { - *d |= dstMask; - } - if (srcMask == 128) { - srcMask = 1; - s++; - } - else { - srcMask = srcMask << 1; - } - if (dstMask == 1) { - dstMask = 128; - d++; - *d = 0; - } - else { - dstMask = dstMask >> 1; - } - } - } - else { - GLubyte srcMask = 128 >> (packing->SkipPixels & 0x7); - GLubyte dstMask = 128; - const GLubyte *s = src; - GLubyte *d = dst; - *d = 0; - for (i = 0; i < width; i++) { - if (*s & srcMask) { - *d |= dstMask; - } - if (srcMask == 1) { - srcMask = 128; - s++; - } - else { - srcMask = srcMask >> 1; - } - if (dstMask == 1) { - dstMask = 128; - d++; - *d = 0; - } - else { - dstMask = dstMask >> 1; - } - } - } - } - dst += width_in_bytes; - } - - return buffer; -} - - /* * Pack bitmap data. */ @@ -256,7 +155,7 @@ _mesa_pack_bitmap( GLint width, GLint height, const GLubyte *source, if (!source) return; - width_in_bytes = CEILING( width, 8 ); + width_in_bytes = DIV_ROUND_UP( width, 8 ); src = source; for (row = 0; row < height; row++) { GLubyte *dst = (GLubyte *) _mesa_image_address2d(packing, dest, @@ -333,4663 +232,253 @@ _mesa_pack_bitmap( GLint width, GLint height, const GLubyte *source, } -/** - * Get indexes of color components for a basic color format, such as - * GL_RGBA, GL_RED, GL_LUMINANCE_ALPHA, etc. Return -1 for indexes - * that do not apply. - */ -static void -get_component_indexes(GLenum format, - GLint *redIndex, - GLint *greenIndex, - GLint *blueIndex, - GLint *alphaIndex, - GLint *luminanceIndex, - GLint *intensityIndex) -{ - *redIndex = -1; - *greenIndex = -1; - *blueIndex = -1; - *alphaIndex = -1; - *luminanceIndex = -1; - *intensityIndex = -1; - - switch (format) { - case GL_LUMINANCE: - case GL_LUMINANCE_INTEGER_EXT: - *luminanceIndex = 0; - break; - case GL_LUMINANCE_ALPHA: - case GL_LUMINANCE_ALPHA_INTEGER_EXT: - *luminanceIndex = 0; - *alphaIndex = 1; - break; - case GL_INTENSITY: - *intensityIndex = 0; - break; - case GL_RED: - case GL_RED_INTEGER_EXT: - *redIndex = 0; - break; - case GL_GREEN: - case GL_GREEN_INTEGER_EXT: - *greenIndex = 0; - break; - case GL_BLUE: - case GL_BLUE_INTEGER_EXT: - *blueIndex = 0; - break; - case GL_ALPHA: - case GL_ALPHA_INTEGER_EXT: - *alphaIndex = 0; - break; - case GL_RG: - case GL_RG_INTEGER: - *redIndex = 0; - *greenIndex = 1; - break; - case GL_RGB: - case GL_RGB_INTEGER_EXT: - *redIndex = 0; - *greenIndex = 1; - *blueIndex = 2; - break; - case GL_BGR: - case GL_BGR_INTEGER_EXT: - *blueIndex = 0; - *greenIndex = 1; - *redIndex = 2; - break; - case GL_RGBA: - case GL_RGBA_INTEGER_EXT: - *redIndex = 0; - *greenIndex = 1; - *blueIndex = 2; - *alphaIndex = 3; - break; - case GL_BGRA: - case GL_BGRA_INTEGER: - *redIndex = 2; - *greenIndex = 1; - *blueIndex = 0; - *alphaIndex = 3; - break; - case GL_ABGR_EXT: - *redIndex = 3; - *greenIndex = 2; - *blueIndex = 1; - *alphaIndex = 0; - break; - default: - assert(0 && "bad format in get_component_indexes()"); +#define SWAP2BYTE(VALUE) \ + { \ + GLubyte *bytes = (GLubyte *) &(VALUE); \ + GLubyte tmp = bytes[0]; \ + bytes[0] = bytes[1]; \ + bytes[1] = tmp; \ } -} - - -/** - * For small integer types, return the min and max possible values. - * Used for clamping floats to unscaled integer types. - * \return GL_TRUE if type is handled, GL_FALSE otherwise. - */ -static GLboolean -get_type_min_max(GLenum type, GLfloat *min, GLfloat *max) -{ - switch (type) { - case GL_BYTE: - *min = -128.0; - *max = 127.0; - return GL_TRUE; - case GL_UNSIGNED_BYTE: - *min = 0.0; - *max = 255.0; - return GL_TRUE; - case GL_SHORT: - *min = -32768.0; - *max = 32767.0; - return GL_TRUE; - case GL_UNSIGNED_SHORT: - *min = 0.0; - *max = 65535.0; - return GL_TRUE; - default: - return GL_FALSE; +#define SWAP4BYTE(VALUE) \ + { \ + GLubyte *bytes = (GLubyte *) &(VALUE); \ + GLubyte tmp = bytes[0]; \ + bytes[0] = bytes[3]; \ + bytes[3] = tmp; \ + tmp = bytes[1]; \ + bytes[1] = bytes[2]; \ + bytes[2] = tmp; \ } -} - -/* Customization of unsigned integer packing. - */ -#define SRC_TYPE GLuint - -#define DST_TYPE GLuint -#define SRC_CONVERT(x) (x) -#define FN_NAME pack_uint_from_uint_rgba -#include "pack_tmp.h" -#undef DST_TYPE -#undef SRC_CONVERT -#undef FN_NAME - -#define DST_TYPE GLint -#define SRC_CONVERT(x) MIN2(x, 0x7fffffff) -#define FN_NAME pack_int_from_uint_rgba -#include "pack_tmp.h" -#undef DST_TYPE -#undef SRC_CONVERT -#undef FN_NAME -#define DST_TYPE GLushort -#define SRC_CONVERT(x) MIN2(x, 0xffff) -#define FN_NAME pack_ushort_from_uint_rgba -#include "pack_tmp.h" -#undef DST_TYPE -#undef SRC_CONVERT -#undef FN_NAME - -#define DST_TYPE GLshort -#define SRC_CONVERT(x) CLAMP((int)x, -32768, 32767) -#define FN_NAME pack_short_from_uint_rgba -#include "pack_tmp.h" -#undef DST_TYPE -#undef SRC_CONVERT -#undef FN_NAME - -#define DST_TYPE GLubyte -#define SRC_CONVERT(x) MIN2(x, 0xff) -#define FN_NAME pack_ubyte_from_uint_rgba -#include "pack_tmp.h" -#undef DST_TYPE -#undef SRC_CONVERT -#undef FN_NAME - -#define DST_TYPE GLbyte -#define SRC_CONVERT(x) CLAMP((int)x, -128, 127) -#define FN_NAME pack_byte_from_uint_rgba -#include "pack_tmp.h" -#undef DST_TYPE -#undef SRC_CONVERT -#undef FN_NAME - -#undef SRC_TYPE static void -_pack_rgba_span_from_uints_problem(struct gl_context *ctx, - GLenum dstFormat, GLenum dstType) +extract_uint_indexes(GLuint n, GLuint indexes[], + GLenum srcFormat, GLenum srcType, const GLvoid *src, + const struct gl_pixelstore_attrib *unpack ) { - _mesa_problem(ctx, - "Unsupported type (%s) / format (%s) " - "in _mesa_pack_rgba_span_from_uints", - _mesa_lookup_enum_by_nr(dstType), - _mesa_lookup_enum_by_nr(dstFormat)); -} + ASSERT(srcFormat == GL_COLOR_INDEX || srcFormat == GL_STENCIL_INDEX); -void -_mesa_pack_rgba_span_from_uints(struct gl_context *ctx, GLuint n, GLuint rgba[][4], - GLenum dstFormat, GLenum dstType, - GLvoid *dstAddr) -{ - GLuint i; + ASSERT(srcType == GL_BITMAP || + srcType == GL_UNSIGNED_BYTE || + srcType == GL_BYTE || + srcType == GL_UNSIGNED_SHORT || + srcType == GL_SHORT || + srcType == GL_UNSIGNED_INT || + srcType == GL_INT || + srcType == GL_UNSIGNED_INT_24_8_EXT || + srcType == GL_HALF_FLOAT_ARB || + srcType == GL_HALF_FLOAT_OES || + srcType == GL_FLOAT || + srcType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV); - switch(dstType) { - case GL_UNSIGNED_INT: - pack_uint_from_uint_rgba(ctx, dstAddr, dstFormat, rgba, n); - break; - case GL_INT: - pack_int_from_uint_rgba(ctx, dstAddr, dstFormat, rgba, n); - break; - case GL_UNSIGNED_SHORT: - pack_ushort_from_uint_rgba(ctx, dstAddr, dstFormat, rgba, n); - break; - case GL_SHORT: - pack_short_from_uint_rgba(ctx, dstAddr, dstFormat, rgba, n); - break; - case GL_UNSIGNED_BYTE: - pack_ubyte_from_uint_rgba(ctx, dstAddr, dstFormat, rgba, n); - break; - case GL_BYTE: - pack_byte_from_uint_rgba(ctx, dstAddr, dstFormat, rgba, n); - break; - case GL_UNSIGNED_BYTE_3_3_2: - if ((dstFormat == GL_RGB) || (dstFormat == GL_RGB_INTEGER)) { - GLubyte *dst = (GLubyte *) dstAddr; - for (i=0;iLsbFirst) { + GLubyte mask = 1 << (unpack->SkipPixels & 0x7); + GLuint i; + for (i = 0; i < n; i++) { + indexes[i] = (*ubsrc & mask) ? 1 : 0; + if (mask == 128) { + mask = 1; + ubsrc++; + } + else { + mask = mask << 1; + } + } + } + else { + GLubyte mask = 128 >> (unpack->SkipPixels & 0x7); + GLuint i; + for (i = 0; i < n; i++) { + indexes[i] = (*ubsrc & mask) ? 1 : 0; + if (mask == 1) { + mask = 128; + ubsrc++; + } + else { + mask = mask >> 1; + } + } + } } - } - else if ((dstFormat == GL_BGRA) || (dstFormat == GL_BGRA_INTEGER)) { - GLushort *dst = (GLushort *) dstAddr; - for (i=0;iSwapBytes) { + for (i = 0; i < n; i++) { + GLushort value = s[i]; + SWAP2BYTE(value); + indexes[i] = value; + } + } + else { + for (i = 0; i < n; i++) + indexes[i] = s[i]; + } } - } - else if ((dstFormat == GL_BGRA) || (dstFormat == GL_BGRA_INTEGER)) { - GLushort *dst = (GLushort *) dstAddr; - for (i=0;iSwapBytes) { - GLint swapSize = _mesa_sizeof_packed_type(dstType); - if (swapSize == 2) { - _mesa_swap2((GLushort *) dstAddr, n * comps); - } - else if (swapSize == 4) { - _mesa_swap4((GLuint *) dstAddr, n * comps); - } - } - - free(luminance); -} - - - -#define SWAP2BYTE(VALUE) \ - { \ - GLubyte *bytes = (GLubyte *) &(VALUE); \ - GLubyte tmp = bytes[0]; \ - bytes[0] = bytes[1]; \ - bytes[1] = tmp; \ - } - -#define SWAP4BYTE(VALUE) \ - { \ - GLubyte *bytes = (GLubyte *) &(VALUE); \ - GLubyte tmp = bytes[0]; \ - bytes[0] = bytes[3]; \ - bytes[3] = tmp; \ - tmp = bytes[1]; \ - bytes[1] = bytes[2]; \ - bytes[2] = tmp; \ - } - - -static void -extract_uint_indexes(GLuint n, GLuint indexes[], - GLenum srcFormat, GLenum srcType, const GLvoid *src, - const struct gl_pixelstore_attrib *unpack ) -{ - ASSERT(srcFormat == GL_COLOR_INDEX || srcFormat == GL_STENCIL_INDEX); - - ASSERT(srcType == GL_BITMAP || - srcType == GL_UNSIGNED_BYTE || - srcType == GL_BYTE || - srcType == GL_UNSIGNED_SHORT || - srcType == GL_SHORT || - srcType == GL_UNSIGNED_INT || - srcType == GL_INT || - srcType == GL_UNSIGNED_INT_24_8_EXT || - srcType == GL_HALF_FLOAT_ARB || - srcType == GL_FLOAT || - srcType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV); - - switch (srcType) { - case GL_BITMAP: - { - GLubyte *ubsrc = (GLubyte *) src; - if (unpack->LsbFirst) { - GLubyte mask = 1 << (unpack->SkipPixels & 0x7); - GLuint i; - for (i = 0; i < n; i++) { - indexes[i] = (*ubsrc & mask) ? 1 : 0; - if (mask == 128) { - mask = 1; - ubsrc++; - } - else { - mask = mask << 1; - } - } - } - else { - GLubyte mask = 128 >> (unpack->SkipPixels & 0x7); - GLuint i; - for (i = 0; i < n; i++) { - indexes[i] = (*ubsrc & mask) ? 1 : 0; - if (mask == 1) { - mask = 128; - ubsrc++; - } - else { - mask = mask >> 1; - } - } - } - } - break; - case GL_UNSIGNED_BYTE: - { - GLuint i; - const GLubyte *s = (const GLubyte *) src; - for (i = 0; i < n; i++) - indexes[i] = s[i]; - } - break; - case GL_BYTE: - { - GLuint i; - const GLbyte *s = (const GLbyte *) src; - for (i = 0; i < n; i++) - indexes[i] = s[i]; - } - break; - case GL_UNSIGNED_SHORT: - { - GLuint i; - const GLushort *s = (const GLushort *) src; - if (unpack->SwapBytes) { - for (i = 0; i < n; i++) { - GLushort value = s[i]; - SWAP2BYTE(value); - indexes[i] = value; - } - } - else { - for (i = 0; i < n; i++) - indexes[i] = s[i]; - } - } - break; - case GL_SHORT: - { - GLuint i; - const GLshort *s = (const GLshort *) src; - if (unpack->SwapBytes) { - for (i = 0; i < n; i++) { - GLshort value = s[i]; - SWAP2BYTE(value); - indexes[i] = value; - } - } - else { - for (i = 0; i < n; i++) - indexes[i] = s[i]; - } - } - break; - case GL_UNSIGNED_INT: - { - GLuint i; - const GLuint *s = (const GLuint *) src; - if (unpack->SwapBytes) { - for (i = 0; i < n; i++) { - GLuint value = s[i]; - SWAP4BYTE(value); - indexes[i] = value; - } - } - else { - for (i = 0; i < n; i++) - indexes[i] = s[i]; - } - } - break; - case GL_INT: - { - GLuint i; - const GLint *s = (const GLint *) src; - if (unpack->SwapBytes) { - for (i = 0; i < n; i++) { - GLint value = s[i]; - SWAP4BYTE(value); - indexes[i] = value; - } - } - else { - for (i = 0; i < n; i++) - indexes[i] = s[i]; - } - } - break; - case GL_FLOAT: - { - GLuint i; - const GLfloat *s = (const GLfloat *) src; - if (unpack->SwapBytes) { - for (i = 0; i < n; i++) { - GLfloat value = s[i]; - SWAP4BYTE(value); - indexes[i] = (GLuint) value; - } - } - else { - for (i = 0; i < n; i++) - indexes[i] = (GLuint) s[i]; - } - } - break; - case GL_HALF_FLOAT_ARB: - { - GLuint i; - const GLhalfARB *s = (const GLhalfARB *) src; - if (unpack->SwapBytes) { - for (i = 0; i < n; i++) { - GLhalfARB value = s[i]; - SWAP2BYTE(value); - indexes[i] = (GLuint) _mesa_half_to_float(value); - } - } - else { - for (i = 0; i < n; i++) - indexes[i] = (GLuint) _mesa_half_to_float(s[i]); - } - } - break; - case GL_UNSIGNED_INT_24_8_EXT: - { - GLuint i; - const GLuint *s = (const GLuint *) src; - if (unpack->SwapBytes) { - for (i = 0; i < n; i++) { - GLuint value = s[i]; - SWAP4BYTE(value); - indexes[i] = value & 0xff; /* lower 8 bits */ - } - } - else { - for (i = 0; i < n; i++) - indexes[i] = s[i] & 0xff; /* lower 8 bits */ - } - } - break; - case GL_FLOAT_32_UNSIGNED_INT_24_8_REV: - { - GLuint i; - const GLuint *s = (const GLuint *) src; - if (unpack->SwapBytes) { - for (i = 0; i < n; i++) { - GLuint value = s[i*2+1]; - SWAP4BYTE(value); - indexes[i] = value & 0xff; /* lower 8 bits */ - } - } - else { - for (i = 0; i < n; i++) - indexes[i] = s[i*2+1] & 0xff; /* lower 8 bits */ - } - } - break; - - default: - _mesa_problem(NULL, "bad srcType in extract_uint_indexes"); - return; - } -} - - -/** - * Return source/dest RGBA indexes for unpacking pixels. - */ -static void -get_component_mapping(GLenum format, - GLint *rSrc, - GLint *gSrc, - GLint *bSrc, - GLint *aSrc, - GLint *rDst, - GLint *gDst, - GLint *bDst, - GLint *aDst) -{ - switch (format) { - case GL_RED: - case GL_RED_INTEGER_EXT: - *rSrc = 0; - *gSrc = *bSrc = *aSrc = -1; - break; - case GL_GREEN: - case GL_GREEN_INTEGER_EXT: - *gSrc = 0; - *rSrc = *bSrc = *aSrc = -1; - break; - case GL_BLUE: - case GL_BLUE_INTEGER_EXT: - *bSrc = 0; - *rSrc = *gSrc = *aSrc = -1; - break; - case GL_ALPHA: - case GL_ALPHA_INTEGER_EXT: - *rSrc = *gSrc = *bSrc = -1; - *aSrc = 0; - break; - case GL_LUMINANCE: - case GL_LUMINANCE_INTEGER_EXT: - *rSrc = *gSrc = *bSrc = 0; - *aSrc = -1; - break; - case GL_LUMINANCE_ALPHA: - case GL_LUMINANCE_ALPHA_INTEGER_EXT: - *rSrc = *gSrc = *bSrc = 0; - *aSrc = 1; - break; - case GL_INTENSITY: - *rSrc = *gSrc = *bSrc = *aSrc = 0; - break; - case GL_RG: - case GL_RG_INTEGER: - *rSrc = 0; - *gSrc = 1; - *bSrc = -1; - *aSrc = -1; - *rDst = 0; - *gDst = 1; - *bDst = 2; - *aDst = 3; - break; - case GL_RGB: - case GL_RGB_INTEGER: - *rSrc = 0; - *gSrc = 1; - *bSrc = 2; - *aSrc = -1; - *rDst = 0; - *gDst = 1; - *bDst = 2; - *aDst = 3; - break; - case GL_BGR: - case GL_BGR_INTEGER: - *rSrc = 2; - *gSrc = 1; - *bSrc = 0; - *aSrc = -1; - *rDst = 2; - *gDst = 1; - *bDst = 0; - *aDst = 3; - break; - case GL_RGBA: - case GL_RGBA_INTEGER: - *rSrc = 0; - *gSrc = 1; - *bSrc = 2; - *aSrc = 3; - *rDst = 0; - *gDst = 1; - *bDst = 2; - *aDst = 3; - break; - case GL_BGRA: - case GL_BGRA_INTEGER: - *rSrc = 2; - *gSrc = 1; - *bSrc = 0; - *aSrc = 3; - *rDst = 2; - *gDst = 1; - *bDst = 0; - *aDst = 3; - break; - case GL_ABGR_EXT: - *rSrc = 3; - *gSrc = 2; - *bSrc = 1; - *aSrc = 0; - *rDst = 3; - *gDst = 2; - *bDst = 1; - *aDst = 0; - break; - default: - _mesa_problem(NULL, "bad srcFormat %s in get_component_mapping", - _mesa_lookup_enum_by_nr(format)); - return; - } -} - - - -/* - * This function extracts floating point RGBA values from arbitrary - * image data. srcFormat and srcType are the format and type parameters - * passed to glDrawPixels, glTexImage[123]D, glTexSubImage[123]D, etc. - * - * Refering to section 3.6.4 of the OpenGL 1.2 spec, this function - * implements the "Conversion to floating point", "Conversion to RGB", - * and "Final Expansion to RGBA" operations. - * - * Args: n - number of pixels - * rgba - output colors - * srcFormat - format of incoming data - * srcType - data type of incoming data - * src - source data pointer - * swapBytes - perform byteswapping of incoming data? - */ -static void -extract_float_rgba(GLuint n, GLfloat rgba[][4], - GLenum srcFormat, GLenum srcType, const GLvoid *src, - GLboolean swapBytes) -{ - GLint rSrc, gSrc, bSrc, aSrc; - GLint stride; - GLint rDst, bDst, gDst, aDst; - GLboolean intFormat; - GLfloat rs = 1.0f, gs = 1.0f, bs = 1.0f, as = 1.0f; /* scale factors */ - - ASSERT(srcFormat == GL_RED || - srcFormat == GL_GREEN || - srcFormat == GL_BLUE || - srcFormat == GL_ALPHA || - srcFormat == GL_LUMINANCE || - srcFormat == GL_LUMINANCE_ALPHA || - srcFormat == GL_INTENSITY || - srcFormat == GL_RG || - srcFormat == GL_RGB || - srcFormat == GL_BGR || - srcFormat == GL_RGBA || - srcFormat == GL_BGRA || - srcFormat == GL_ABGR_EXT || - srcFormat == GL_RED_INTEGER_EXT || - srcFormat == GL_GREEN_INTEGER_EXT || - srcFormat == GL_BLUE_INTEGER_EXT || - srcFormat == GL_ALPHA_INTEGER_EXT || - srcFormat == GL_RG_INTEGER || - srcFormat == GL_RGB_INTEGER_EXT || - srcFormat == GL_RGBA_INTEGER_EXT || - srcFormat == GL_BGR_INTEGER_EXT || - srcFormat == GL_BGRA_INTEGER_EXT || - srcFormat == GL_LUMINANCE_INTEGER_EXT || - srcFormat == GL_LUMINANCE_ALPHA_INTEGER_EXT); - - ASSERT(srcType == GL_UNSIGNED_BYTE || - srcType == GL_BYTE || - srcType == GL_UNSIGNED_SHORT || - srcType == GL_SHORT || - srcType == GL_UNSIGNED_INT || - srcType == GL_INT || - srcType == GL_HALF_FLOAT_ARB || - srcType == GL_FLOAT || - srcType == GL_UNSIGNED_BYTE_3_3_2 || - srcType == GL_UNSIGNED_BYTE_2_3_3_REV || - srcType == GL_UNSIGNED_SHORT_5_6_5 || - srcType == GL_UNSIGNED_SHORT_5_6_5_REV || - srcType == GL_UNSIGNED_SHORT_4_4_4_4 || - srcType == GL_UNSIGNED_SHORT_4_4_4_4_REV || - srcType == GL_UNSIGNED_SHORT_5_5_5_1 || - srcType == GL_UNSIGNED_SHORT_1_5_5_5_REV || - srcType == GL_UNSIGNED_INT_8_8_8_8 || - srcType == GL_UNSIGNED_INT_8_8_8_8_REV || - srcType == GL_UNSIGNED_INT_10_10_10_2 || - srcType == GL_UNSIGNED_INT_2_10_10_10_REV || - srcType == GL_UNSIGNED_INT_5_9_9_9_REV || - srcType == GL_UNSIGNED_INT_10F_11F_11F_REV); - - get_component_mapping(srcFormat, - &rSrc, &gSrc, &bSrc, &aSrc, - &rDst, &gDst, &bDst, &aDst); - - stride = _mesa_components_in_format(srcFormat); - - intFormat = _mesa_is_enum_format_integer(srcFormat); - -#define PROCESS(SRC_INDEX, DST_INDEX, DEFAULT_FLT, DEFAULT_INT, TYPE, CONVERSION) \ - if ((SRC_INDEX) < 0) { \ - GLuint i; \ - if (intFormat) { \ - for (i = 0; i < n; i++) { \ - rgba[i][DST_INDEX] = DEFAULT_INT; \ - } \ - } \ - else { \ - for (i = 0; i < n; i++) { \ - rgba[i][DST_INDEX] = DEFAULT_FLT; \ - } \ - } \ - } \ - else if (swapBytes) { \ - const TYPE *s = (const TYPE *) src; \ - GLuint i; \ - for (i = 0; i < n; i++) { \ - TYPE value = s[SRC_INDEX]; \ - if (sizeof(TYPE) == 2) { \ - SWAP2BYTE(value); \ - } \ - else if (sizeof(TYPE) == 4) { \ - SWAP4BYTE(value); \ - } \ - if (intFormat) \ - rgba[i][DST_INDEX] = (GLfloat) value; \ - else \ - rgba[i][DST_INDEX] = (GLfloat) CONVERSION(value); \ - s += stride; \ - } \ - } \ - else { \ - const TYPE *s = (const TYPE *) src; \ - GLuint i; \ - if (intFormat) { \ - for (i = 0; i < n; i++) { \ - rgba[i][DST_INDEX] = (GLfloat) s[SRC_INDEX]; \ - s += stride; \ - } \ - } \ - else { \ - for (i = 0; i < n; i++) { \ - rgba[i][DST_INDEX] = (GLfloat) CONVERSION(s[SRC_INDEX]); \ - s += stride; \ - } \ - } \ - } - - switch (srcType) { - case GL_UNSIGNED_BYTE: - PROCESS(rSrc, RCOMP, 0.0F, 0, GLubyte, UBYTE_TO_FLOAT); - PROCESS(gSrc, GCOMP, 0.0F, 0, GLubyte, UBYTE_TO_FLOAT); - PROCESS(bSrc, BCOMP, 0.0F, 0, GLubyte, UBYTE_TO_FLOAT); - PROCESS(aSrc, ACOMP, 1.0F, 255, GLubyte, UBYTE_TO_FLOAT); - break; - case GL_BYTE: - PROCESS(rSrc, RCOMP, 0.0F, 0, GLbyte, BYTE_TO_FLOAT_TEX); - PROCESS(gSrc, GCOMP, 0.0F, 0, GLbyte, BYTE_TO_FLOAT_TEX); - PROCESS(bSrc, BCOMP, 0.0F, 0, GLbyte, BYTE_TO_FLOAT_TEX); - PROCESS(aSrc, ACOMP, 1.0F, 127, GLbyte, BYTE_TO_FLOAT_TEX); - break; - case GL_UNSIGNED_SHORT: - PROCESS(rSrc, RCOMP, 0.0F, 0, GLushort, USHORT_TO_FLOAT); - PROCESS(gSrc, GCOMP, 0.0F, 0, GLushort, USHORT_TO_FLOAT); - PROCESS(bSrc, BCOMP, 0.0F, 0, GLushort, USHORT_TO_FLOAT); - PROCESS(aSrc, ACOMP, 1.0F, 0xffff, GLushort, USHORT_TO_FLOAT); - break; - case GL_SHORT: - PROCESS(rSrc, RCOMP, 0.0F, 0, GLshort, SHORT_TO_FLOAT_TEX); - PROCESS(gSrc, GCOMP, 0.0F, 0, GLshort, SHORT_TO_FLOAT_TEX); - PROCESS(bSrc, BCOMP, 0.0F, 0, GLshort, SHORT_TO_FLOAT_TEX); - PROCESS(aSrc, ACOMP, 1.0F, 32767, GLshort, SHORT_TO_FLOAT_TEX); - break; - case GL_UNSIGNED_INT: - PROCESS(rSrc, RCOMP, 0.0F, 0, GLuint, UINT_TO_FLOAT); - PROCESS(gSrc, GCOMP, 0.0F, 0, GLuint, UINT_TO_FLOAT); - PROCESS(bSrc, BCOMP, 0.0F, 0, GLuint, UINT_TO_FLOAT); - PROCESS(aSrc, ACOMP, 1.0F, 0xffffffff, GLuint, UINT_TO_FLOAT); - break; - case GL_INT: - PROCESS(rSrc, RCOMP, 0.0F, 0, GLint, INT_TO_FLOAT); - PROCESS(gSrc, GCOMP, 0.0F, 0, GLint, INT_TO_FLOAT); - PROCESS(bSrc, BCOMP, 0.0F, 0, GLint, INT_TO_FLOAT); - PROCESS(aSrc, ACOMP, 1.0F, 2147483647, GLint, INT_TO_FLOAT); - break; - case GL_FLOAT: - PROCESS(rSrc, RCOMP, 0.0F, 0.0F, GLfloat, (GLfloat)); - PROCESS(gSrc, GCOMP, 0.0F, 0.0F, GLfloat, (GLfloat)); - PROCESS(bSrc, BCOMP, 0.0F, 0.0F, GLfloat, (GLfloat)); - PROCESS(aSrc, ACOMP, 1.0F, 1.0F, GLfloat, (GLfloat)); - break; - case GL_HALF_FLOAT_ARB: - PROCESS(rSrc, RCOMP, 0.0F, 0.0F, GLhalfARB, _mesa_half_to_float); - PROCESS(gSrc, GCOMP, 0.0F, 0.0F, GLhalfARB, _mesa_half_to_float); - PROCESS(bSrc, BCOMP, 0.0F, 0.0F, GLhalfARB, _mesa_half_to_float); - PROCESS(aSrc, ACOMP, 1.0F, 1.0F, GLhalfARB, _mesa_half_to_float); - break; - case GL_UNSIGNED_BYTE_3_3_2: - { - const GLubyte *ubsrc = (const GLubyte *) src; - GLuint i; - if (!intFormat) { - rs = 1.0F / 7.0F; - gs = 1.0F / 7.0F; - bs = 1.0F / 3.0F; - } - for (i = 0; i < n; i ++) { - GLubyte p = ubsrc[i]; - rgba[i][rDst] = ((p >> 5) ) * rs; - rgba[i][gDst] = ((p >> 2) & 0x7) * gs; - rgba[i][bDst] = ((p ) & 0x3) * bs; - rgba[i][aDst] = 1.0F; - } - } - break; - case GL_UNSIGNED_BYTE_2_3_3_REV: - { - const GLubyte *ubsrc = (const GLubyte *) src; - GLuint i; - if (!intFormat) { - rs = 1.0F / 7.0F; - gs = 1.0F / 7.0F; - bs = 1.0F / 3.0F; - } - for (i = 0; i < n; i ++) { - GLubyte p = ubsrc[i]; - rgba[i][rDst] = ((p ) & 0x7) * rs; - rgba[i][gDst] = ((p >> 3) & 0x7) * gs; - rgba[i][bDst] = ((p >> 6) ) * bs; - rgba[i][aDst] = 1.0F; - } - } - break; - case GL_UNSIGNED_SHORT_5_6_5: - if (!intFormat) { - rs = 1.0F / 31.0F; - gs = 1.0F / 63.0F; - bs = 1.0F / 31.0F; - } - if (swapBytes) { - const GLushort *ussrc = (const GLushort *) src; - GLuint i; - for (i = 0; i < n; i ++) { - GLushort p = ussrc[i]; - SWAP2BYTE(p); - rgba[i][rDst] = ((p >> 11) ) * rs; - rgba[i][gDst] = ((p >> 5) & 0x3f) * gs; - rgba[i][bDst] = ((p ) & 0x1f) * bs; - rgba[i][aDst] = 1.0F; - } - } - else { - const GLushort *ussrc = (const GLushort *) src; - GLuint i; - for (i = 0; i < n; i ++) { - GLushort p = ussrc[i]; - rgba[i][rDst] = ((p >> 11) ) * rs; - rgba[i][gDst] = ((p >> 5) & 0x3f) * gs; - rgba[i][bDst] = ((p ) & 0x1f) * bs; - rgba[i][aDst] = 1.0F; - } - } - break; - case GL_UNSIGNED_SHORT_5_6_5_REV: - if (!intFormat) { - rs = 1.0F / 31.0F; - gs = 1.0F / 63.0F; - bs = 1.0F / 31.0F; - } - if (swapBytes) { - const GLushort *ussrc = (const GLushort *) src; - GLuint i; - for (i = 0; i < n; i ++) { - GLushort p = ussrc[i]; - SWAP2BYTE(p); - rgba[i][rDst] = ((p ) & 0x1f) * rs; - rgba[i][gDst] = ((p >> 5) & 0x3f) * gs; - rgba[i][bDst] = ((p >> 11) ) * bs; - rgba[i][aDst] = 1.0F; - } - } - else { - const GLushort *ussrc = (const GLushort *) src; - GLuint i; - for (i = 0; i < n; i ++) { - GLushort p = ussrc[i]; - rgba[i][rDst] = ((p ) & 0x1f) * rs; - rgba[i][gDst] = ((p >> 5) & 0x3f) * gs; - rgba[i][bDst] = ((p >> 11) ) * bs; - rgba[i][aDst] = 1.0F; - } - } - break; - case GL_UNSIGNED_SHORT_4_4_4_4: - if (!intFormat) { - rs = gs = bs = as = 1.0F / 15.0F; - } - if (swapBytes) { - const GLushort *ussrc = (const GLushort *) src; - GLuint i; - for (i = 0; i < n; i ++) { - GLushort p = ussrc[i]; - SWAP2BYTE(p); - rgba[i][rDst] = ((p >> 12) ) * rs; - rgba[i][gDst] = ((p >> 8) & 0xf) * gs; - rgba[i][bDst] = ((p >> 4) & 0xf) * bs; - rgba[i][aDst] = ((p ) & 0xf) * as; - } - } - else { - const GLushort *ussrc = (const GLushort *) src; - GLuint i; - for (i = 0; i < n; i ++) { - GLushort p = ussrc[i]; - rgba[i][rDst] = ((p >> 12) ) * rs; - rgba[i][gDst] = ((p >> 8) & 0xf) * gs; - rgba[i][bDst] = ((p >> 4) & 0xf) * bs; - rgba[i][aDst] = ((p ) & 0xf) * as; - } - } - break; - case GL_UNSIGNED_SHORT_4_4_4_4_REV: - if (!intFormat) { - rs = gs = bs = as = 1.0F / 15.0F; - } - if (swapBytes) { - const GLushort *ussrc = (const GLushort *) src; - GLuint i; - for (i = 0; i < n; i ++) { - GLushort p = ussrc[i]; - SWAP2BYTE(p); - rgba[i][rDst] = ((p ) & 0xf) * rs; - rgba[i][gDst] = ((p >> 4) & 0xf) * gs; - rgba[i][bDst] = ((p >> 8) & 0xf) * bs; - rgba[i][aDst] = ((p >> 12) ) * as; - } - } - else { - const GLushort *ussrc = (const GLushort *) src; - GLuint i; - for (i = 0; i < n; i ++) { - GLushort p = ussrc[i]; - rgba[i][rDst] = ((p ) & 0xf) * rs; - rgba[i][gDst] = ((p >> 4) & 0xf) * gs; - rgba[i][bDst] = ((p >> 8) & 0xf) * bs; - rgba[i][aDst] = ((p >> 12) ) * as; - } - } - break; - case GL_UNSIGNED_SHORT_5_5_5_1: - if (!intFormat) { - rs = gs = bs = 1.0F / 31.0F; - } - if (swapBytes) { - const GLushort *ussrc = (const GLushort *) src; - GLuint i; - for (i = 0; i < n; i ++) { - GLushort p = ussrc[i]; - SWAP2BYTE(p); - rgba[i][rDst] = ((p >> 11) ) * rs; - rgba[i][gDst] = ((p >> 6) & 0x1f) * gs; - rgba[i][bDst] = ((p >> 1) & 0x1f) * bs; - rgba[i][aDst] = ((p ) & 0x1) * as; - } - } - else { - const GLushort *ussrc = (const GLushort *) src; - GLuint i; - for (i = 0; i < n; i ++) { - GLushort p = ussrc[i]; - rgba[i][rDst] = ((p >> 11) ) * rs; - rgba[i][gDst] = ((p >> 6) & 0x1f) * gs; - rgba[i][bDst] = ((p >> 1) & 0x1f) * bs; - rgba[i][aDst] = ((p ) & 0x1) * as; - } - } - break; - case GL_UNSIGNED_SHORT_1_5_5_5_REV: - if (!intFormat) { - rs = gs = bs = 1.0F / 31.0F; - } - if (swapBytes) { - const GLushort *ussrc = (const GLushort *) src; - GLuint i; - for (i = 0; i < n; i ++) { - GLushort p = ussrc[i]; - SWAP2BYTE(p); - rgba[i][rDst] = ((p ) & 0x1f) * rs; - rgba[i][gDst] = ((p >> 5) & 0x1f) * gs; - rgba[i][bDst] = ((p >> 10) & 0x1f) * bs; - rgba[i][aDst] = ((p >> 15) ) * as; - } - } - else { - const GLushort *ussrc = (const GLushort *) src; - GLuint i; - for (i = 0; i < n; i ++) { - GLushort p = ussrc[i]; - rgba[i][rDst] = ((p ) & 0x1f) * rs; - rgba[i][gDst] = ((p >> 5) & 0x1f) * gs; - rgba[i][bDst] = ((p >> 10) & 0x1f) * bs; - rgba[i][aDst] = ((p >> 15) ) * as; - } - } - break; - case GL_UNSIGNED_INT_8_8_8_8: - if (swapBytes) { - const GLuint *uisrc = (const GLuint *) src; - GLuint i; - if (intFormat) { - for (i = 0; i < n; i ++) { - GLuint p = uisrc[i]; - rgba[i][rDst] = (GLfloat) ((p ) & 0xff); - rgba[i][gDst] = (GLfloat) ((p >> 8) & 0xff); - rgba[i][bDst] = (GLfloat) ((p >> 16) & 0xff); - rgba[i][aDst] = (GLfloat) ((p >> 24) ); - } - } - else { - for (i = 0; i < n; i ++) { - GLuint p = uisrc[i]; - rgba[i][rDst] = UBYTE_TO_FLOAT((p ) & 0xff); - rgba[i][gDst] = UBYTE_TO_FLOAT((p >> 8) & 0xff); - rgba[i][bDst] = UBYTE_TO_FLOAT((p >> 16) & 0xff); - rgba[i][aDst] = UBYTE_TO_FLOAT((p >> 24) ); - } - } - } - else { - const GLuint *uisrc = (const GLuint *) src; - GLuint i; - if (intFormat) { - for (i = 0; i < n; i ++) { - GLuint p = uisrc[i]; - rgba[i][rDst] = (GLfloat) ((p >> 24) ); - rgba[i][gDst] = (GLfloat) ((p >> 16) & 0xff); - rgba[i][bDst] = (GLfloat) ((p >> 8) & 0xff); - rgba[i][aDst] = (GLfloat) ((p ) & 0xff); - } - } - else { - for (i = 0; i < n; i ++) { - GLuint p = uisrc[i]; - rgba[i][rDst] = UBYTE_TO_FLOAT((p >> 24) ); - rgba[i][gDst] = UBYTE_TO_FLOAT((p >> 16) & 0xff); - rgba[i][bDst] = UBYTE_TO_FLOAT((p >> 8) & 0xff); - rgba[i][aDst] = UBYTE_TO_FLOAT((p ) & 0xff); - } - } - } - break; - case GL_UNSIGNED_INT_8_8_8_8_REV: - if (swapBytes) { - const GLuint *uisrc = (const GLuint *) src; - GLuint i; - if (intFormat) { - for (i = 0; i < n; i ++) { - GLuint p = uisrc[i]; - rgba[i][rDst] = (GLfloat) ((p >> 24) ); - rgba[i][gDst] = (GLfloat) ((p >> 16) & 0xff); - rgba[i][bDst] = (GLfloat) ((p >> 8) & 0xff); - rgba[i][aDst] = (GLfloat) ((p ) & 0xff); - } - } - else { - for (i = 0; i < n; i ++) { - GLuint p = uisrc[i]; - rgba[i][rDst] = UBYTE_TO_FLOAT((p >> 24) ); - rgba[i][gDst] = UBYTE_TO_FLOAT((p >> 16) & 0xff); - rgba[i][bDst] = UBYTE_TO_FLOAT((p >> 8) & 0xff); - rgba[i][aDst] = UBYTE_TO_FLOAT((p ) & 0xff); - } - } - } - else { - const GLuint *uisrc = (const GLuint *) src; - GLuint i; - if (intFormat) { - for (i = 0; i < n; i ++) { - GLuint p = uisrc[i]; - rgba[i][rDst] = (GLfloat) ((p ) & 0xff); - rgba[i][gDst] = (GLfloat) ((p >> 8) & 0xff); - rgba[i][bDst] = (GLfloat) ((p >> 16) & 0xff); - rgba[i][aDst] = (GLfloat) ((p >> 24) ); - } - } - else { - for (i = 0; i < n; i ++) { - GLuint p = uisrc[i]; - rgba[i][rDst] = UBYTE_TO_FLOAT((p ) & 0xff); - rgba[i][gDst] = UBYTE_TO_FLOAT((p >> 8) & 0xff); - rgba[i][bDst] = UBYTE_TO_FLOAT((p >> 16) & 0xff); - rgba[i][aDst] = UBYTE_TO_FLOAT((p >> 24) ); - } - } - } - break; - case GL_UNSIGNED_INT_10_10_10_2: - if (!intFormat) { - rs = 1.0F / 1023.0F; - gs = 1.0F / 1023.0F; - bs = 1.0F / 1023.0F; - as = 1.0F / 3.0F; - } - if (swapBytes) { - const GLuint *uisrc = (const GLuint *) src; - GLuint i; - for (i = 0; i < n; i ++) { - GLuint p = uisrc[i]; - SWAP4BYTE(p); - rgba[i][rDst] = ((p >> 22) ) * rs; - rgba[i][gDst] = ((p >> 12) & 0x3ff) * gs; - rgba[i][bDst] = ((p >> 2) & 0x3ff) * bs; - rgba[i][aDst] = ((p ) & 0x3 ) * as; - } - } - else { - const GLuint *uisrc = (const GLuint *) src; - GLuint i; - for (i = 0; i < n; i ++) { - GLuint p = uisrc[i]; - rgba[i][rDst] = ((p >> 22) ) * rs; - rgba[i][gDst] = ((p >> 12) & 0x3ff) * gs; - rgba[i][bDst] = ((p >> 2) & 0x3ff) * bs; - rgba[i][aDst] = ((p ) & 0x3 ) * as; - } - } - break; - case GL_UNSIGNED_INT_2_10_10_10_REV: - if (!intFormat) { - rs = 1.0F / 1023.0F; - gs = 1.0F / 1023.0F; - bs = 1.0F / 1023.0F; - as = 1.0F / 3.0F; - } - if (swapBytes) { - const GLuint *uisrc = (const GLuint *) src; - GLuint i; - for (i = 0; i < n; i ++) { - GLuint p = uisrc[i]; - SWAP4BYTE(p); - rgba[i][rDst] = ((p ) & 0x3ff) * rs; - rgba[i][gDst] = ((p >> 10) & 0x3ff) * gs; - rgba[i][bDst] = ((p >> 20) & 0x3ff) * bs; - if (aSrc < 0) { - rgba[i][aDst] = 1.0F; - } else { - rgba[i][aDst] = (p >> 30) * as; - } - } - } - else { - const GLuint *uisrc = (const GLuint *) src; - GLuint i; - for (i = 0; i < n; i ++) { - GLuint p = uisrc[i]; - rgba[i][rDst] = ((p ) & 0x3ff) * rs; - rgba[i][gDst] = ((p >> 10) & 0x3ff) * gs; - rgba[i][bDst] = ((p >> 20) & 0x3ff) * bs; - if (aSrc < 0) { - rgba[i][aDst] = 1.0F; - } else { - rgba[i][aDst] = (p >> 30) * as; - } - } - } - break; - case GL_UNSIGNED_INT_5_9_9_9_REV: - if (swapBytes) { - const GLuint *uisrc = (const GLuint *) src; - GLuint i; - GLfloat f[3]; - for (i = 0; i < n; i ++) { - GLuint p = uisrc[i]; - SWAP4BYTE(p); - rgb9e5_to_float3(p, f); - rgba[i][rDst] = f[0]; - rgba[i][gDst] = f[1]; - rgba[i][bDst] = f[2]; - rgba[i][aDst] = 1.0F; - } - } - else { - const GLuint *uisrc = (const GLuint *) src; - GLuint i; - GLfloat f[3]; - for (i = 0; i < n; i ++) { - rgb9e5_to_float3(uisrc[i], f); - rgba[i][rDst] = f[0]; - rgba[i][gDst] = f[1]; - rgba[i][bDst] = f[2]; - rgba[i][aDst] = 1.0F; - } - } - break; - case GL_UNSIGNED_INT_10F_11F_11F_REV: - if (swapBytes) { - const GLuint *uisrc = (const GLuint *) src; - GLuint i; - GLfloat f[3]; - for (i = 0; i < n; i ++) { - GLuint p = uisrc[i]; - SWAP4BYTE(p); - r11g11b10f_to_float3(p, f); - rgba[i][rDst] = f[0]; - rgba[i][gDst] = f[1]; - rgba[i][bDst] = f[2]; - rgba[i][aDst] = 1.0F; - } - } - else { - const GLuint *uisrc = (const GLuint *) src; - GLuint i; - GLfloat f[3]; - for (i = 0; i < n; i ++) { - r11g11b10f_to_float3(uisrc[i], f); - rgba[i][rDst] = f[0]; - rgba[i][gDst] = f[1]; - rgba[i][bDst] = f[2]; - rgba[i][aDst] = 1.0F; - } - } - break; - default: - _mesa_problem(NULL, "bad srcType in extract float data"); - break; - } -#undef PROCESS -} - - -static inline GLuint -clamp_float_to_uint(GLfloat f) -{ - return f < 0.0F ? 0 : F_TO_I(f); -} - - -static inline GLuint -clamp_half_to_uint(GLhalfARB h) -{ - GLfloat f = _mesa_half_to_float(h); - return f < 0.0F ? 0 : F_TO_I(f); -} - - -/** - * \sa extract_float_rgba() - */ -static void -extract_uint_rgba(GLuint n, GLuint rgba[][4], - GLenum srcFormat, GLenum srcType, const GLvoid *src, - GLboolean swapBytes) -{ - GLint rSrc, gSrc, bSrc, aSrc; - GLint stride; - GLint rDst, bDst, gDst, aDst; - - ASSERT(srcFormat == GL_RED || - srcFormat == GL_GREEN || - srcFormat == GL_BLUE || - srcFormat == GL_ALPHA || - srcFormat == GL_LUMINANCE || - srcFormat == GL_LUMINANCE_ALPHA || - srcFormat == GL_INTENSITY || - srcFormat == GL_RG || - srcFormat == GL_RGB || - srcFormat == GL_BGR || - srcFormat == GL_RGBA || - srcFormat == GL_BGRA || - srcFormat == GL_ABGR_EXT || - srcFormat == GL_RED_INTEGER_EXT || - srcFormat == GL_RG_INTEGER || - srcFormat == GL_GREEN_INTEGER_EXT || - srcFormat == GL_BLUE_INTEGER_EXT || - srcFormat == GL_ALPHA_INTEGER_EXT || - srcFormat == GL_RGB_INTEGER_EXT || - srcFormat == GL_RGBA_INTEGER_EXT || - srcFormat == GL_BGR_INTEGER_EXT || - srcFormat == GL_BGRA_INTEGER_EXT || - srcFormat == GL_LUMINANCE_INTEGER_EXT || - srcFormat == GL_LUMINANCE_ALPHA_INTEGER_EXT); - - ASSERT(srcType == GL_UNSIGNED_BYTE || - srcType == GL_BYTE || - srcType == GL_UNSIGNED_SHORT || - srcType == GL_SHORT || - srcType == GL_UNSIGNED_INT || - srcType == GL_INT || - srcType == GL_HALF_FLOAT_ARB || - srcType == GL_FLOAT || - srcType == GL_UNSIGNED_BYTE_3_3_2 || - srcType == GL_UNSIGNED_BYTE_2_3_3_REV || - srcType == GL_UNSIGNED_SHORT_5_6_5 || - srcType == GL_UNSIGNED_SHORT_5_6_5_REV || - srcType == GL_UNSIGNED_SHORT_4_4_4_4 || - srcType == GL_UNSIGNED_SHORT_4_4_4_4_REV || - srcType == GL_UNSIGNED_SHORT_5_5_5_1 || - srcType == GL_UNSIGNED_SHORT_1_5_5_5_REV || - srcType == GL_UNSIGNED_INT_8_8_8_8 || - srcType == GL_UNSIGNED_INT_8_8_8_8_REV || - srcType == GL_UNSIGNED_INT_10_10_10_2 || - srcType == GL_UNSIGNED_INT_2_10_10_10_REV || - srcType == GL_UNSIGNED_INT_5_9_9_9_REV || - srcType == GL_UNSIGNED_INT_10F_11F_11F_REV); - - get_component_mapping(srcFormat, - &rSrc, &gSrc, &bSrc, &aSrc, - &rDst, &gDst, &bDst, &aDst); - - stride = _mesa_components_in_format(srcFormat); - -#define PROCESS(SRC_INDEX, DST_INDEX, DEFAULT, TYPE, CONVERSION) \ - if ((SRC_INDEX) < 0) { \ - GLuint i; \ - for (i = 0; i < n; i++) { \ - rgba[i][DST_INDEX] = DEFAULT; \ - } \ - } \ - else if (swapBytes) { \ - const TYPE *s = (const TYPE *) src; \ - GLuint i; \ - for (i = 0; i < n; i++) { \ - TYPE value = s[SRC_INDEX]; \ - if (sizeof(TYPE) == 2) { \ - SWAP2BYTE(value); \ - } \ - else if (sizeof(TYPE) == 4) { \ - SWAP4BYTE(value); \ - } \ - rgba[i][DST_INDEX] = CONVERSION(value); \ - s += stride; \ - } \ - } \ - else { \ - const TYPE *s = (const TYPE *) src; \ - GLuint i; \ - for (i = 0; i < n; i++) { \ - rgba[i][DST_INDEX] = CONVERSION(s[SRC_INDEX]); \ - s += stride; \ - } \ - } - - switch (srcType) { - case GL_UNSIGNED_BYTE: - PROCESS(rSrc, RCOMP, 0, GLubyte, (GLuint)); - PROCESS(gSrc, GCOMP, 0, GLubyte, (GLuint)); - PROCESS(bSrc, BCOMP, 0, GLubyte, (GLuint)); - PROCESS(aSrc, ACOMP, 1, GLubyte, (GLuint)); - break; - case GL_BYTE: - PROCESS(rSrc, RCOMP, 0, GLbyte, (GLuint)); - PROCESS(gSrc, GCOMP, 0, GLbyte, (GLuint)); - PROCESS(bSrc, BCOMP, 0, GLbyte, (GLuint)); - PROCESS(aSrc, ACOMP, 1, GLbyte, (GLuint)); - break; - case GL_UNSIGNED_SHORT: - PROCESS(rSrc, RCOMP, 0, GLushort, (GLuint)); - PROCESS(gSrc, GCOMP, 0, GLushort, (GLuint)); - PROCESS(bSrc, BCOMP, 0, GLushort, (GLuint)); - PROCESS(aSrc, ACOMP, 1, GLushort, (GLuint)); - break; - case GL_SHORT: - PROCESS(rSrc, RCOMP, 0, GLshort, (GLuint)); - PROCESS(gSrc, GCOMP, 0, GLshort, (GLuint)); - PROCESS(bSrc, BCOMP, 0, GLshort, (GLuint)); - PROCESS(aSrc, ACOMP, 1, GLshort, (GLuint)); - break; - case GL_UNSIGNED_INT: - PROCESS(rSrc, RCOMP, 0, GLuint, (GLuint)); - PROCESS(gSrc, GCOMP, 0, GLuint, (GLuint)); - PROCESS(bSrc, BCOMP, 0, GLuint, (GLuint)); - PROCESS(aSrc, ACOMP, 1, GLuint, (GLuint)); - break; - case GL_INT: - PROCESS(rSrc, RCOMP, 0, GLint, (GLuint)); - PROCESS(gSrc, GCOMP, 0, GLint, (GLuint)); - PROCESS(bSrc, BCOMP, 0, GLint, (GLuint)); - PROCESS(aSrc, ACOMP, 1, GLint, (GLuint)); - break; - case GL_FLOAT: - PROCESS(rSrc, RCOMP, 0, GLfloat, clamp_float_to_uint); - PROCESS(gSrc, GCOMP, 0, GLfloat, clamp_float_to_uint); - PROCESS(bSrc, BCOMP, 0, GLfloat, clamp_float_to_uint); - PROCESS(aSrc, ACOMP, 1, GLfloat, clamp_float_to_uint); - break; - case GL_HALF_FLOAT_ARB: - PROCESS(rSrc, RCOMP, 0, GLhalfARB, clamp_half_to_uint); - PROCESS(gSrc, GCOMP, 0, GLhalfARB, clamp_half_to_uint); - PROCESS(bSrc, BCOMP, 0, GLhalfARB, clamp_half_to_uint); - PROCESS(aSrc, ACOMP, 1, GLhalfARB, clamp_half_to_uint); - break; - case GL_UNSIGNED_BYTE_3_3_2: - { - const GLubyte *ubsrc = (const GLubyte *) src; - GLuint i; - for (i = 0; i < n; i ++) { - GLubyte p = ubsrc[i]; - rgba[i][rDst] = ((p >> 5) ); - rgba[i][gDst] = ((p >> 2) & 0x7); - rgba[i][bDst] = ((p ) & 0x3); - rgba[i][aDst] = 1; - } - } - break; - case GL_UNSIGNED_BYTE_2_3_3_REV: - { - const GLubyte *ubsrc = (const GLubyte *) src; - GLuint i; - for (i = 0; i < n; i ++) { - GLubyte p = ubsrc[i]; - rgba[i][rDst] = ((p ) & 0x7); - rgba[i][gDst] = ((p >> 3) & 0x7); - rgba[i][bDst] = ((p >> 6) ); - rgba[i][aDst] = 1; - } - } - break; - case GL_UNSIGNED_SHORT_5_6_5: - if (swapBytes) { - const GLushort *ussrc = (const GLushort *) src; - GLuint i; - for (i = 0; i < n; i ++) { - GLushort p = ussrc[i]; - SWAP2BYTE(p); - rgba[i][rDst] = ((p >> 11) ); - rgba[i][gDst] = ((p >> 5) & 0x3f); - rgba[i][bDst] = ((p ) & 0x1f); - rgba[i][aDst] = 1; - } - } - else { - const GLushort *ussrc = (const GLushort *) src; - GLuint i; - for (i = 0; i < n; i ++) { - GLushort p = ussrc[i]; - rgba[i][rDst] = ((p >> 11) ); - rgba[i][gDst] = ((p >> 5) & 0x3f); - rgba[i][bDst] = ((p ) & 0x1f); - rgba[i][aDst] = 1; - } - } - break; - case GL_UNSIGNED_SHORT_5_6_5_REV: - if (swapBytes) { - const GLushort *ussrc = (const GLushort *) src; - GLuint i; - for (i = 0; i < n; i ++) { - GLushort p = ussrc[i]; - SWAP2BYTE(p); - rgba[i][rDst] = ((p ) & 0x1f); - rgba[i][gDst] = ((p >> 5) & 0x3f); - rgba[i][bDst] = ((p >> 11) ); - rgba[i][aDst] = 1; - } - } - else { - const GLushort *ussrc = (const GLushort *) src; - GLuint i; - for (i = 0; i < n; i ++) { - GLushort p = ussrc[i]; - rgba[i][rDst] = ((p ) & 0x1f); - rgba[i][gDst] = ((p >> 5) & 0x3f); - rgba[i][bDst] = ((p >> 11) ); - rgba[i][aDst] = 1; - } - } - break; - case GL_UNSIGNED_SHORT_4_4_4_4: - if (swapBytes) { - const GLushort *ussrc = (const GLushort *) src; - GLuint i; - for (i = 0; i < n; i ++) { - GLushort p = ussrc[i]; - SWAP2BYTE(p); - rgba[i][rDst] = ((p >> 12) ); - rgba[i][gDst] = ((p >> 8) & 0xf); - rgba[i][bDst] = ((p >> 4) & 0xf); - rgba[i][aDst] = ((p ) & 0xf); - } - } - else { - const GLushort *ussrc = (const GLushort *) src; - GLuint i; - for (i = 0; i < n; i ++) { - GLushort p = ussrc[i]; - rgba[i][rDst] = ((p >> 12) ); - rgba[i][gDst] = ((p >> 8) & 0xf); - rgba[i][bDst] = ((p >> 4) & 0xf); - rgba[i][aDst] = ((p ) & 0xf); - } - } - break; - case GL_UNSIGNED_SHORT_4_4_4_4_REV: - if (swapBytes) { - const GLushort *ussrc = (const GLushort *) src; - GLuint i; - for (i = 0; i < n; i ++) { - GLushort p = ussrc[i]; - SWAP2BYTE(p); - rgba[i][rDst] = ((p ) & 0xf); - rgba[i][gDst] = ((p >> 4) & 0xf); - rgba[i][bDst] = ((p >> 8) & 0xf); - rgba[i][aDst] = ((p >> 12) ); - } - } - else { - const GLushort *ussrc = (const GLushort *) src; - GLuint i; - for (i = 0; i < n; i ++) { - GLushort p = ussrc[i]; - rgba[i][rDst] = ((p ) & 0xf); - rgba[i][gDst] = ((p >> 4) & 0xf); - rgba[i][bDst] = ((p >> 8) & 0xf); - rgba[i][aDst] = ((p >> 12) ); - } - } - break; - case GL_UNSIGNED_SHORT_5_5_5_1: - if (swapBytes) { - const GLushort *ussrc = (const GLushort *) src; - GLuint i; - for (i = 0; i < n; i ++) { - GLushort p = ussrc[i]; - SWAP2BYTE(p); - rgba[i][rDst] = ((p >> 11) ); - rgba[i][gDst] = ((p >> 6) & 0x1f); - rgba[i][bDst] = ((p >> 1) & 0x1f); - rgba[i][aDst] = ((p ) & 0x1 ); - } - } - else { - const GLushort *ussrc = (const GLushort *) src; - GLuint i; - for (i = 0; i < n; i ++) { - GLushort p = ussrc[i]; - rgba[i][rDst] = ((p >> 11) ); - rgba[i][gDst] = ((p >> 6) & 0x1f); - rgba[i][bDst] = ((p >> 1) & 0x1f); - rgba[i][aDst] = ((p ) & 0x1 ); - } - } - break; - case GL_UNSIGNED_SHORT_1_5_5_5_REV: - if (swapBytes) { - const GLushort *ussrc = (const GLushort *) src; - GLuint i; - for (i = 0; i < n; i ++) { - GLushort p = ussrc[i]; - SWAP2BYTE(p); - rgba[i][rDst] = ((p ) & 0x1f); - rgba[i][gDst] = ((p >> 5) & 0x1f); - rgba[i][bDst] = ((p >> 10) & 0x1f); - rgba[i][aDst] = ((p >> 15) ); - } - } - else { - const GLushort *ussrc = (const GLushort *) src; - GLuint i; - for (i = 0; i < n; i ++) { - GLushort p = ussrc[i]; - rgba[i][rDst] = ((p ) & 0x1f); - rgba[i][gDst] = ((p >> 5) & 0x1f); - rgba[i][bDst] = ((p >> 10) & 0x1f); - rgba[i][aDst] = ((p >> 15) ); - } - } - break; - case GL_UNSIGNED_INT_8_8_8_8: - if (swapBytes) { - const GLuint *uisrc = (const GLuint *) src; - GLuint i; - for (i = 0; i < n; i ++) { - GLuint p = uisrc[i]; - rgba[i][rDst] = ((p ) & 0xff); - rgba[i][gDst] = ((p >> 8) & 0xff); - rgba[i][bDst] = ((p >> 16) & 0xff); - rgba[i][aDst] = ((p >> 24) ); - } - } - else { - const GLuint *uisrc = (const GLuint *) src; - GLuint i; - for (i = 0; i < n; i ++) { - GLuint p = uisrc[i]; - rgba[i][rDst] = ((p >> 24) ); - rgba[i][gDst] = ((p >> 16) & 0xff); - rgba[i][bDst] = ((p >> 8) & 0xff); - rgba[i][aDst] = ((p ) & 0xff); - } - } - break; - case GL_UNSIGNED_INT_8_8_8_8_REV: - if (swapBytes) { - const GLuint *uisrc = (const GLuint *) src; - GLuint i; - for (i = 0; i < n; i ++) { - GLuint p = uisrc[i]; - rgba[i][rDst] = ((p >> 24) ); - rgba[i][gDst] = ((p >> 16) & 0xff); - rgba[i][bDst] = ((p >> 8) & 0xff); - rgba[i][aDst] = ((p ) & 0xff); - } - } - else { - const GLuint *uisrc = (const GLuint *) src; - GLuint i; - for (i = 0; i < n; i ++) { - GLuint p = uisrc[i]; - rgba[i][rDst] = ((p ) & 0xff); - rgba[i][gDst] = ((p >> 8) & 0xff); - rgba[i][bDst] = ((p >> 16) & 0xff); - rgba[i][aDst] = ((p >> 24) ); - } - } - break; - case GL_UNSIGNED_INT_10_10_10_2: - if (swapBytes) { - const GLuint *uisrc = (const GLuint *) src; - GLuint i; - for (i = 0; i < n; i ++) { - GLuint p = uisrc[i]; - SWAP4BYTE(p); - rgba[i][rDst] = ((p >> 22) ); - rgba[i][gDst] = ((p >> 12) & 0x3ff); - rgba[i][bDst] = ((p >> 2) & 0x3ff); - rgba[i][aDst] = ((p ) & 0x3 ); - } - } - else { - const GLuint *uisrc = (const GLuint *) src; - GLuint i; - for (i = 0; i < n; i ++) { - GLuint p = uisrc[i]; - rgba[i][rDst] = ((p >> 22) ); - rgba[i][gDst] = ((p >> 12) & 0x3ff); - rgba[i][bDst] = ((p >> 2) & 0x3ff); - rgba[i][aDst] = ((p ) & 0x3 ); - } - } - break; - case GL_UNSIGNED_INT_2_10_10_10_REV: - if (swapBytes) { - const GLuint *uisrc = (const GLuint *) src; - GLuint i; - for (i = 0; i < n; i ++) { - GLuint p = uisrc[i]; - SWAP4BYTE(p); - rgba[i][rDst] = ((p ) & 0x3ff); - rgba[i][gDst] = ((p >> 10) & 0x3ff); - rgba[i][bDst] = ((p >> 20) & 0x3ff); - rgba[i][aDst] = ((p >> 30) ); - } - } - else { - const GLuint *uisrc = (const GLuint *) src; - GLuint i; - for (i = 0; i < n; i ++) { - GLuint p = uisrc[i]; - rgba[i][rDst] = ((p ) & 0x3ff); - rgba[i][gDst] = ((p >> 10) & 0x3ff); - rgba[i][bDst] = ((p >> 20) & 0x3ff); - rgba[i][aDst] = ((p >> 30) ); - } - } - break; - case GL_UNSIGNED_INT_5_9_9_9_REV: - if (swapBytes) { - const GLuint *uisrc = (const GLuint *) src; - GLuint i; - float f[3]; - for (i = 0; i < n; i ++) { - GLuint p = uisrc[i]; - SWAP4BYTE(p); - rgb9e5_to_float3(p, f); - rgba[i][rDst] = clamp_float_to_uint(f[0]); - rgba[i][gDst] = clamp_float_to_uint(f[1]); - rgba[i][bDst] = clamp_float_to_uint(f[2]); - rgba[i][aDst] = 1; - } - } - else { - const GLuint *uisrc = (const GLuint *) src; - GLuint i; - float f[3]; - for (i = 0; i < n; i ++) { - GLuint p = uisrc[i]; - rgb9e5_to_float3(p, f); - rgba[i][rDst] = clamp_float_to_uint(f[0]); - rgba[i][gDst] = clamp_float_to_uint(f[1]); - rgba[i][bDst] = clamp_float_to_uint(f[2]); - rgba[i][aDst] = 1; - } - } - break; - case GL_UNSIGNED_INT_10F_11F_11F_REV: - if (swapBytes) { - const GLuint *uisrc = (const GLuint *) src; - GLuint i; - float f[3]; - for (i = 0; i < n; i ++) { - GLuint p = uisrc[i]; - SWAP4BYTE(p); - r11g11b10f_to_float3(p, f); - rgba[i][rDst] = clamp_float_to_uint(f[0]); - rgba[i][gDst] = clamp_float_to_uint(f[1]); - rgba[i][bDst] = clamp_float_to_uint(f[2]); - rgba[i][aDst] = 1; - } - } - else { - const GLuint *uisrc = (const GLuint *) src; - GLuint i; - float f[3]; - for (i = 0; i < n; i ++) { - GLuint p = uisrc[i]; - r11g11b10f_to_float3(p, f); - rgba[i][rDst] = clamp_float_to_uint(f[0]); - rgba[i][gDst] = clamp_float_to_uint(f[1]); - rgba[i][bDst] = clamp_float_to_uint(f[2]); - rgba[i][aDst] = 1; - } - } - break; - default: - _mesa_problem(NULL, "bad srcType in extract uint data"); - break; - } -#undef PROCESS -} - - - -/* - * Unpack a row of color image data from a client buffer according to - * the pixel unpacking parameters. - * Return GLubyte values in the specified dest image format. - * This is used by glDrawPixels and glTexImage?D(). - * \param ctx - the context - * n - number of pixels in the span - * dstFormat - format of destination color array - * dest - the destination color array - * srcFormat - source image format - * srcType - source image data type - * source - source image pointer - * srcPacking - pixel unpacking parameters - * transferOps - bitmask of IMAGE_*_BIT values of operations to apply - * - * XXX perhaps expand this to process whole images someday. - */ -void -_mesa_unpack_color_span_ubyte(struct gl_context *ctx, - GLuint n, GLenum dstFormat, GLubyte dest[], - GLenum srcFormat, GLenum srcType, - const GLvoid *source, - const struct gl_pixelstore_attrib *srcPacking, - GLbitfield transferOps ) -{ - GLboolean intFormat = _mesa_is_enum_format_integer(srcFormat); - ASSERT(dstFormat == GL_ALPHA || - dstFormat == GL_LUMINANCE || - dstFormat == GL_LUMINANCE_ALPHA || - dstFormat == GL_INTENSITY || - dstFormat == GL_RED || - dstFormat == GL_RG || - dstFormat == GL_RGB || - dstFormat == GL_RGBA); - - ASSERT(srcFormat == GL_RED || - srcFormat == GL_GREEN || - srcFormat == GL_BLUE || - srcFormat == GL_ALPHA || - srcFormat == GL_LUMINANCE || - srcFormat == GL_LUMINANCE_ALPHA || - srcFormat == GL_INTENSITY || - srcFormat == GL_RG || - srcFormat == GL_RGB || - srcFormat == GL_BGR || - srcFormat == GL_RGBA || - srcFormat == GL_BGRA || - srcFormat == GL_ABGR_EXT || - srcFormat == GL_COLOR_INDEX); - - ASSERT(srcType == GL_BITMAP || - srcType == GL_UNSIGNED_BYTE || - srcType == GL_BYTE || - srcType == GL_UNSIGNED_SHORT || - srcType == GL_SHORT || - srcType == GL_UNSIGNED_INT || - srcType == GL_INT || - srcType == GL_HALF_FLOAT_ARB || - srcType == GL_FLOAT || - srcType == GL_UNSIGNED_BYTE_3_3_2 || - srcType == GL_UNSIGNED_BYTE_2_3_3_REV || - srcType == GL_UNSIGNED_SHORT_5_6_5 || - srcType == GL_UNSIGNED_SHORT_5_6_5_REV || - srcType == GL_UNSIGNED_SHORT_4_4_4_4 || - srcType == GL_UNSIGNED_SHORT_4_4_4_4_REV || - srcType == GL_UNSIGNED_SHORT_5_5_5_1 || - srcType == GL_UNSIGNED_SHORT_1_5_5_5_REV || - srcType == GL_UNSIGNED_INT_8_8_8_8 || - srcType == GL_UNSIGNED_INT_8_8_8_8_REV || - srcType == GL_UNSIGNED_INT_10_10_10_2 || - srcType == GL_UNSIGNED_INT_2_10_10_10_REV || - srcType == GL_UNSIGNED_INT_5_9_9_9_REV || - srcType == GL_UNSIGNED_INT_10F_11F_11F_REV); - - /* EXT_texture_integer specifies no transfer ops on integer - * types in the resolved issues section. Just set them to 0 - * for integer surfaces. - */ - if (intFormat) - transferOps = 0; - - /* Try simple cases first */ - if (transferOps == 0) { - if (srcType == GL_UNSIGNED_BYTE) { - if (dstFormat == GL_RGBA) { - if (srcFormat == GL_RGBA) { - memcpy( dest, source, n * 4 * sizeof(GLubyte) ); - return; - } - else if (srcFormat == GL_RGB) { - GLuint i; - const GLubyte *src = (const GLubyte *) source; - GLubyte *dst = dest; - for (i = 0; i < n; i++) { - dst[0] = src[0]; - dst[1] = src[1]; - dst[2] = src[2]; - dst[3] = 255; - src += 3; - dst += 4; - } - return; - } - } - else if (dstFormat == GL_RGB) { - if (srcFormat == GL_RGB) { - memcpy( dest, source, n * 3 * sizeof(GLubyte) ); - return; - } - else if (srcFormat == GL_RGBA) { - GLuint i; - const GLubyte *src = (const GLubyte *) source; - GLubyte *dst = dest; - for (i = 0; i < n; i++) { - dst[0] = src[0]; - dst[1] = src[1]; - dst[2] = src[2]; - src += 4; - dst += 3; - } - return; - } - } - else if (dstFormat == srcFormat) { - GLint comps = _mesa_components_in_format(srcFormat); - assert(comps > 0); - memcpy( dest, source, n * comps * sizeof(GLubyte) ); - return; - } - } - } - - - /* general solution begins here */ - { - GLint dstComponents; - GLint rDst, gDst, bDst, aDst, lDst, iDst; - GLfloat (*rgba)[4] = malloc(4 * n * sizeof(GLfloat)); - - if (!rgba) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "pixel unpacking"); - return; - } - - dstComponents = _mesa_components_in_format( dstFormat ); - /* source & dest image formats should have been error checked by now */ - assert(dstComponents > 0); - - /* - * Extract image data and convert to RGBA floats - */ - if (srcFormat == GL_COLOR_INDEX) { - GLuint *indexes = malloc(n * sizeof(GLuint)); - - if (!indexes) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "pixel unpacking"); - free(rgba); - return; - } - - extract_uint_indexes(n, indexes, srcFormat, srcType, source, - srcPacking); - - /* Convert indexes to RGBA */ - if (transferOps & IMAGE_SHIFT_OFFSET_BIT) { - _mesa_shift_and_offset_ci(ctx, n, indexes); - } - _mesa_map_ci_to_rgba(ctx, n, indexes, rgba); - - /* Don't do RGBA scale/bias or RGBA->RGBA mapping if starting - * with color indexes. - */ - transferOps &= ~(IMAGE_SCALE_BIAS_BIT | IMAGE_MAP_COLOR_BIT); - - free(indexes); - } - else { - /* non-color index data */ - extract_float_rgba(n, rgba, srcFormat, srcType, source, - srcPacking->SwapBytes); - } - - /* Need to clamp if returning GLubytes */ - transferOps |= IMAGE_CLAMP_BIT; - - if (transferOps) { - _mesa_apply_rgba_transfer_ops(ctx, transferOps, n, rgba); - } - - get_component_indexes(dstFormat, - &rDst, &gDst, &bDst, &aDst, &lDst, &iDst); - - /* Now return the GLubyte data in the requested dstFormat */ - if (rDst >= 0) { - GLubyte *dst = dest; - GLuint i; - for (i = 0; i < n; i++) { - CLAMPED_FLOAT_TO_UBYTE(dst[rDst], rgba[i][RCOMP]); - dst += dstComponents; - } - } - - if (gDst >= 0) { - GLubyte *dst = dest; - GLuint i; - for (i = 0; i < n; i++) { - CLAMPED_FLOAT_TO_UBYTE(dst[gDst], rgba[i][GCOMP]); - dst += dstComponents; - } - } - - if (bDst >= 0) { - GLubyte *dst = dest; - GLuint i; - for (i = 0; i < n; i++) { - CLAMPED_FLOAT_TO_UBYTE(dst[bDst], rgba[i][BCOMP]); - dst += dstComponents; - } - } - - if (aDst >= 0) { - GLubyte *dst = dest; - GLuint i; - for (i = 0; i < n; i++) { - CLAMPED_FLOAT_TO_UBYTE(dst[aDst], rgba[i][ACOMP]); - dst += dstComponents; - } - } - - if (iDst >= 0) { - GLubyte *dst = dest; - GLuint i; - assert(iDst == 0); - assert(dstComponents == 1); - for (i = 0; i < n; i++) { - /* Intensity comes from red channel */ - CLAMPED_FLOAT_TO_UBYTE(dst[i], rgba[i][RCOMP]); - } - } - - if (lDst >= 0) { - GLubyte *dst = dest; - GLuint i; - assert(lDst == 0); - for (i = 0; i < n; i++) { - /* Luminance comes from red channel */ - CLAMPED_FLOAT_TO_UBYTE(dst[0], rgba[i][RCOMP]); - dst += dstComponents; - } - } - - free(rgba); - } -} - - -/** - * Same as _mesa_unpack_color_span_ubyte(), but return GLfloat data - * instead of GLubyte. - */ -void -_mesa_unpack_color_span_float( struct gl_context *ctx, - GLuint n, GLenum dstFormat, GLfloat dest[], - GLenum srcFormat, GLenum srcType, - const GLvoid *source, - const struct gl_pixelstore_attrib *srcPacking, - GLbitfield transferOps ) -{ - ASSERT(dstFormat == GL_ALPHA || - dstFormat == GL_LUMINANCE || - dstFormat == GL_LUMINANCE_ALPHA || - dstFormat == GL_INTENSITY || - dstFormat == GL_RED || - dstFormat == GL_RG || - dstFormat == GL_RGB || - dstFormat == GL_RGBA); - - ASSERT(srcFormat == GL_RED || - srcFormat == GL_GREEN || - srcFormat == GL_BLUE || - srcFormat == GL_ALPHA || - srcFormat == GL_LUMINANCE || - srcFormat == GL_LUMINANCE_ALPHA || - srcFormat == GL_INTENSITY || - srcFormat == GL_RG || - srcFormat == GL_RGB || - srcFormat == GL_BGR || - srcFormat == GL_RGBA || - srcFormat == GL_BGRA || - srcFormat == GL_ABGR_EXT || - srcFormat == GL_RED_INTEGER_EXT || - srcFormat == GL_GREEN_INTEGER_EXT || - srcFormat == GL_BLUE_INTEGER_EXT || - srcFormat == GL_ALPHA_INTEGER_EXT || - srcFormat == GL_RG_INTEGER || - srcFormat == GL_RGB_INTEGER_EXT || - srcFormat == GL_RGBA_INTEGER_EXT || - srcFormat == GL_BGR_INTEGER_EXT || - srcFormat == GL_BGRA_INTEGER_EXT || - srcFormat == GL_LUMINANCE_INTEGER_EXT || - srcFormat == GL_LUMINANCE_ALPHA_INTEGER_EXT || - srcFormat == GL_COLOR_INDEX); - - ASSERT(srcType == GL_BITMAP || - srcType == GL_UNSIGNED_BYTE || - srcType == GL_BYTE || - srcType == GL_UNSIGNED_SHORT || - srcType == GL_SHORT || - srcType == GL_UNSIGNED_INT || - srcType == GL_INT || - srcType == GL_HALF_FLOAT_ARB || - srcType == GL_FLOAT || - srcType == GL_UNSIGNED_BYTE_3_3_2 || - srcType == GL_UNSIGNED_BYTE_2_3_3_REV || - srcType == GL_UNSIGNED_SHORT_5_6_5 || - srcType == GL_UNSIGNED_SHORT_5_6_5_REV || - srcType == GL_UNSIGNED_SHORT_4_4_4_4 || - srcType == GL_UNSIGNED_SHORT_4_4_4_4_REV || - srcType == GL_UNSIGNED_SHORT_5_5_5_1 || - srcType == GL_UNSIGNED_SHORT_1_5_5_5_REV || - srcType == GL_UNSIGNED_INT_8_8_8_8 || - srcType == GL_UNSIGNED_INT_8_8_8_8_REV || - srcType == GL_UNSIGNED_INT_10_10_10_2 || - srcType == GL_UNSIGNED_INT_2_10_10_10_REV || - srcType == GL_UNSIGNED_INT_5_9_9_9_REV || - srcType == GL_UNSIGNED_INT_10F_11F_11F_REV); - - /* general solution, no special cases, yet */ - { - GLint dstComponents; - GLint rDst, gDst, bDst, aDst, lDst, iDst; - GLfloat (*rgba)[4] = malloc(4 * n * sizeof(GLfloat)); - GLboolean intFormat = _mesa_is_enum_format_integer(srcFormat); - - if (!rgba) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "pixel unpacking"); - return; - } - - dstComponents = _mesa_components_in_format( dstFormat ); - /* source & dest image formats should have been error checked by now */ - assert(dstComponents > 0); - - /* EXT_texture_integer specifies no transfer ops on integer - * types in the resolved issues section. Just set them to 0 - * for integer surfaces. - */ - if (intFormat) - transferOps = 0; - - /* - * Extract image data and convert to RGBA floats - */ - if (srcFormat == GL_COLOR_INDEX) { - GLuint *indexes = malloc(n * sizeof(GLuint)); - - if (!indexes) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "pixel unpacking"); - free(rgba); - return; - } - - extract_uint_indexes(n, indexes, srcFormat, srcType, source, - srcPacking); - - /* Convert indexes to RGBA */ - if (transferOps & IMAGE_SHIFT_OFFSET_BIT) { - _mesa_shift_and_offset_ci(ctx, n, indexes); - } - _mesa_map_ci_to_rgba(ctx, n, indexes, rgba); - - /* Don't do RGBA scale/bias or RGBA->RGBA mapping if starting - * with color indexes. - */ - transferOps &= ~(IMAGE_SCALE_BIAS_BIT | IMAGE_MAP_COLOR_BIT); - - free(indexes); - } - else { - /* non-color index data */ - extract_float_rgba(n, rgba, srcFormat, srcType, source, - srcPacking->SwapBytes); - } - - if (transferOps) { - _mesa_apply_rgba_transfer_ops(ctx, transferOps, n, rgba); - } - - get_component_indexes(dstFormat, - &rDst, &gDst, &bDst, &aDst, &lDst, &iDst); - - /* Now pack results in the requested dstFormat */ - if (rDst >= 0) { - GLfloat *dst = dest; - GLuint i; - for (i = 0; i < n; i++) { - dst[rDst] = rgba[i][RCOMP]; - dst += dstComponents; - } - } - - if (gDst >= 0) { - GLfloat *dst = dest; - GLuint i; - for (i = 0; i < n; i++) { - dst[gDst] = rgba[i][GCOMP]; - dst += dstComponents; - } - } - - if (bDst >= 0) { - GLfloat *dst = dest; - GLuint i; - for (i = 0; i < n; i++) { - dst[bDst] = rgba[i][BCOMP]; - dst += dstComponents; - } - } - - if (aDst >= 0) { - GLfloat *dst = dest; - GLuint i; - for (i = 0; i < n; i++) { - dst[aDst] = rgba[i][ACOMP]; - dst += dstComponents; - } - } - - if (iDst >= 0) { - GLfloat *dst = dest; - GLuint i; - assert(iDst == 0); - assert(dstComponents == 1); - for (i = 0; i < n; i++) { - /* Intensity comes from red channel */ - dst[i] = rgba[i][RCOMP]; - } - } - - if (lDst >= 0) { - GLfloat *dst = dest; - GLuint i; - assert(lDst == 0); - for (i = 0; i < n; i++) { - /* Luminance comes from red channel */ - dst[0] = rgba[i][RCOMP]; - dst += dstComponents; - } - } - - free(rgba); - } -} - - -/** - * Same as _mesa_unpack_color_span_ubyte(), but return GLuint data - * instead of GLubyte. - * No pixel transfer ops are applied. - */ -void -_mesa_unpack_color_span_uint(struct gl_context *ctx, - GLuint n, GLenum dstFormat, GLuint *dest, - GLenum srcFormat, GLenum srcType, - const GLvoid *source, - const struct gl_pixelstore_attrib *srcPacking) -{ - GLuint (*rgba)[4] = malloc(n * 4 * sizeof(GLfloat)); - - if (!rgba) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "pixel unpacking"); - return; - } - - ASSERT(dstFormat == GL_ALPHA || - dstFormat == GL_LUMINANCE || - dstFormat == GL_LUMINANCE_ALPHA || - dstFormat == GL_INTENSITY || - dstFormat == GL_RED || - dstFormat == GL_RG || - dstFormat == GL_RGB || - dstFormat == GL_RGBA); - - ASSERT(srcFormat == GL_RED || - srcFormat == GL_GREEN || - srcFormat == GL_BLUE || - srcFormat == GL_ALPHA || - srcFormat == GL_LUMINANCE || - srcFormat == GL_LUMINANCE_ALPHA || - srcFormat == GL_INTENSITY || - srcFormat == GL_RG || - srcFormat == GL_RGB || - srcFormat == GL_BGR || - srcFormat == GL_RGBA || - srcFormat == GL_BGRA || - srcFormat == GL_ABGR_EXT || - srcFormat == GL_RED_INTEGER_EXT || - srcFormat == GL_GREEN_INTEGER_EXT || - srcFormat == GL_BLUE_INTEGER_EXT || - srcFormat == GL_ALPHA_INTEGER_EXT || - srcFormat == GL_RG_INTEGER || - srcFormat == GL_RGB_INTEGER_EXT || - srcFormat == GL_RGBA_INTEGER_EXT || - srcFormat == GL_BGR_INTEGER_EXT || - srcFormat == GL_BGRA_INTEGER_EXT || - srcFormat == GL_LUMINANCE_INTEGER_EXT || - srcFormat == GL_LUMINANCE_ALPHA_INTEGER_EXT); - - ASSERT(srcType == GL_UNSIGNED_BYTE || - srcType == GL_BYTE || - srcType == GL_UNSIGNED_SHORT || - srcType == GL_SHORT || - srcType == GL_UNSIGNED_INT || - srcType == GL_INT || - srcType == GL_HALF_FLOAT_ARB || - srcType == GL_FLOAT || - srcType == GL_UNSIGNED_BYTE_3_3_2 || - srcType == GL_UNSIGNED_BYTE_2_3_3_REV || - srcType == GL_UNSIGNED_SHORT_5_6_5 || - srcType == GL_UNSIGNED_SHORT_5_6_5_REV || - srcType == GL_UNSIGNED_SHORT_4_4_4_4 || - srcType == GL_UNSIGNED_SHORT_4_4_4_4_REV || - srcType == GL_UNSIGNED_SHORT_5_5_5_1 || - srcType == GL_UNSIGNED_SHORT_1_5_5_5_REV || - srcType == GL_UNSIGNED_INT_8_8_8_8 || - srcType == GL_UNSIGNED_INT_8_8_8_8_REV || - srcType == GL_UNSIGNED_INT_10_10_10_2 || - srcType == GL_UNSIGNED_INT_2_10_10_10_REV || - srcType == GL_UNSIGNED_INT_5_9_9_9_REV || - srcType == GL_UNSIGNED_INT_10F_11F_11F_REV); - - - /* Extract image data as uint[4] pixels */ - extract_uint_rgba(n, rgba, srcFormat, srcType, source, - srcPacking->SwapBytes); - - if (dstFormat == GL_RGBA) { - /* simple case */ - memcpy(dest, rgba, 4 * sizeof(GLuint) * n); - } - else { - /* general case */ - GLint rDst, gDst, bDst, aDst, lDst, iDst; - GLint dstComponents = _mesa_components_in_format( dstFormat ); - - assert(dstComponents > 0); - - get_component_indexes(dstFormat, - &rDst, &gDst, &bDst, &aDst, &lDst, &iDst); - - /* Now pack values in the requested dest format */ - if (rDst >= 0) { - GLuint *dst = dest; - GLuint i; - for (i = 0; i < n; i++) { - dst[rDst] = rgba[i][RCOMP]; - dst += dstComponents; - } - } - - if (gDst >= 0) { - GLuint *dst = dest; - GLuint i; - for (i = 0; i < n; i++) { - dst[gDst] = rgba[i][GCOMP]; - dst += dstComponents; + break; + case GL_SHORT: + { + GLuint i; + const GLshort *s = (const GLshort *) src; + if (unpack->SwapBytes) { + for (i = 0; i < n; i++) { + GLshort value = s[i]; + SWAP2BYTE(value); + indexes[i] = value; + } + } + else { + for (i = 0; i < n; i++) + indexes[i] = s[i]; + } } - } - - if (bDst >= 0) { - GLuint *dst = dest; - GLuint i; - for (i = 0; i < n; i++) { - dst[bDst] = rgba[i][BCOMP]; - dst += dstComponents; + break; + case GL_UNSIGNED_INT: + { + GLuint i; + const GLuint *s = (const GLuint *) src; + if (unpack->SwapBytes) { + for (i = 0; i < n; i++) { + GLuint value = s[i]; + SWAP4BYTE(value); + indexes[i] = value; + } + } + else { + for (i = 0; i < n; i++) + indexes[i] = s[i]; + } } - } - - if (aDst >= 0) { - GLuint *dst = dest; - GLuint i; - for (i = 0; i < n; i++) { - dst[aDst] = rgba[i][ACOMP]; - dst += dstComponents; + break; + case GL_INT: + { + GLuint i; + const GLint *s = (const GLint *) src; + if (unpack->SwapBytes) { + for (i = 0; i < n; i++) { + GLint value = s[i]; + SWAP4BYTE(value); + indexes[i] = value; + } + } + else { + for (i = 0; i < n; i++) + indexes[i] = s[i]; + } } - } - - if (iDst >= 0) { - GLuint *dst = dest; - GLuint i; - assert(iDst == 0); - assert(dstComponents == 1); - for (i = 0; i < n; i++) { - /* Intensity comes from red channel */ - dst[i] = rgba[i][RCOMP]; + break; + case GL_FLOAT: + { + GLuint i; + const GLfloat *s = (const GLfloat *) src; + if (unpack->SwapBytes) { + for (i = 0; i < n; i++) { + GLfloat value = s[i]; + SWAP4BYTE(value); + indexes[i] = (GLuint) value; + } + } + else { + for (i = 0; i < n; i++) + indexes[i] = (GLuint) s[i]; + } } - } - - if (lDst >= 0) { - GLuint *dst = dest; - GLuint i; - assert(lDst == 0); - for (i = 0; i < n; i++) { - /* Luminance comes from red channel */ - dst[0] = rgba[i][RCOMP]; - dst += dstComponents; + break; + case GL_HALF_FLOAT_ARB: + case GL_HALF_FLOAT_OES: + { + GLuint i; + const GLhalfARB *s = (const GLhalfARB *) src; + if (unpack->SwapBytes) { + for (i = 0; i < n; i++) { + GLhalfARB value = s[i]; + SWAP2BYTE(value); + indexes[i] = (GLuint) _mesa_half_to_float(value); + } + } + else { + for (i = 0; i < n; i++) + indexes[i] = (GLuint) _mesa_half_to_float(s[i]); + } } - } - } - - free(rgba); -} - - -/* - * Unpack a row of color index data from a client buffer according to - * the pixel unpacking parameters. - * This is (or will be) used by glDrawPixels, glTexImage[123]D, etc. - * - * Args: ctx - the context - * n - number of pixels - * dstType - destination data type - * dest - destination array - * srcType - source pixel type - * source - source data pointer - * srcPacking - pixel unpacking parameters - * transferOps - the pixel transfer operations to apply - */ -void -_mesa_unpack_index_span( struct gl_context *ctx, GLuint n, - GLenum dstType, GLvoid *dest, - GLenum srcType, const GLvoid *source, - const struct gl_pixelstore_attrib *srcPacking, - GLbitfield transferOps ) -{ - ASSERT(srcType == GL_BITMAP || - srcType == GL_UNSIGNED_BYTE || - srcType == GL_BYTE || - srcType == GL_UNSIGNED_SHORT || - srcType == GL_SHORT || - srcType == GL_UNSIGNED_INT || - srcType == GL_INT || - srcType == GL_HALF_FLOAT_ARB || - srcType == GL_FLOAT); - - ASSERT(dstType == GL_UNSIGNED_BYTE || - dstType == GL_UNSIGNED_SHORT || - dstType == GL_UNSIGNED_INT); - - - transferOps &= (IMAGE_MAP_COLOR_BIT | IMAGE_SHIFT_OFFSET_BIT); - - /* - * Try simple cases first - */ - if (transferOps == 0 && srcType == GL_UNSIGNED_BYTE - && dstType == GL_UNSIGNED_BYTE) { - memcpy(dest, source, n * sizeof(GLubyte)); - } - else if (transferOps == 0 && srcType == GL_UNSIGNED_INT - && dstType == GL_UNSIGNED_INT && !srcPacking->SwapBytes) { - memcpy(dest, source, n * sizeof(GLuint)); - } - else { - /* - * general solution - */ - GLuint *indexes = malloc(n * sizeof(GLuint)); - - if (!indexes) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "pixel unpacking"); - return; - } - - extract_uint_indexes(n, indexes, GL_COLOR_INDEX, srcType, source, - srcPacking); - - if (transferOps) - _mesa_apply_ci_transfer_ops(ctx, transferOps, n, indexes); - - /* convert to dest type */ - switch (dstType) { - case GL_UNSIGNED_BYTE: - { - GLubyte *dst = (GLubyte *) dest; - GLuint i; + break; + case GL_UNSIGNED_INT_24_8_EXT: + { + GLuint i; + const GLuint *s = (const GLuint *) src; + if (unpack->SwapBytes) { for (i = 0; i < n; i++) { - dst[i] = (GLubyte) (indexes[i] & 0xff); + GLuint value = s[i]; + SWAP4BYTE(value); + indexes[i] = value & 0xff; /* lower 8 bits */ } } - break; - case GL_UNSIGNED_SHORT: - { - GLuint *dst = (GLuint *) dest; - GLuint i; + else { + for (i = 0; i < n; i++) + indexes[i] = s[i] & 0xff; /* lower 8 bits */ + } + } + break; + case GL_FLOAT_32_UNSIGNED_INT_24_8_REV: + { + GLuint i; + const GLuint *s = (const GLuint *) src; + if (unpack->SwapBytes) { for (i = 0; i < n; i++) { - dst[i] = (GLushort) (indexes[i] & 0xffff); + GLuint value = s[i*2+1]; + SWAP4BYTE(value); + indexes[i] = value & 0xff; /* lower 8 bits */ } } - break; - case GL_UNSIGNED_INT: - memcpy(dest, indexes, n * sizeof(GLuint)); - break; - default: - _mesa_problem(ctx, "bad dstType in _mesa_unpack_index_span"); - } + else { + for (i = 0; i < n; i++) + indexes[i] = s[i*2+1] & 0xff; /* lower 8 bits */ + } + } + break; - free(indexes); + default: + _mesa_problem(NULL, "bad srcType in extract_uint_indexes"); + return; } } -void -_mesa_pack_index_span( struct gl_context *ctx, GLuint n, - GLenum dstType, GLvoid *dest, const GLuint *source, - const struct gl_pixelstore_attrib *dstPacking, - GLbitfield transferOps ) +static inline GLuint +clamp_float_to_uint(GLfloat f) { - GLuint *indexes = malloc(n * sizeof(GLuint)); - - if (!indexes) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "pixel packing"); - return; - } - - transferOps &= (IMAGE_MAP_COLOR_BIT | IMAGE_SHIFT_OFFSET_BIT); - - if (transferOps & (IMAGE_MAP_COLOR_BIT | IMAGE_SHIFT_OFFSET_BIT)) { - /* make a copy of input */ - memcpy(indexes, source, n * sizeof(GLuint)); - _mesa_apply_ci_transfer_ops(ctx, transferOps, n, indexes); - source = indexes; - } + return f < 0.0F ? 0 : F_TO_I(f); +} - switch (dstType) { - case GL_UNSIGNED_BYTE: - { - GLubyte *dst = (GLubyte *) dest; - GLuint i; - for (i = 0; i < n; i++) { - *dst++ = (GLubyte) source[i]; - } - } - break; - case GL_BYTE: - { - GLbyte *dst = (GLbyte *) dest; - GLuint i; - for (i = 0; i < n; i++) { - dst[i] = (GLbyte) source[i]; - } - } - break; - case GL_UNSIGNED_SHORT: - { - GLushort *dst = (GLushort *) dest; - GLuint i; - for (i = 0; i < n; i++) { - dst[i] = (GLushort) source[i]; - } - if (dstPacking->SwapBytes) { - _mesa_swap2( (GLushort *) dst, n ); - } - } - break; - case GL_SHORT: - { - GLshort *dst = (GLshort *) dest; - GLuint i; - for (i = 0; i < n; i++) { - dst[i] = (GLshort) source[i]; - } - if (dstPacking->SwapBytes) { - _mesa_swap2( (GLushort *) dst, n ); - } - } - break; - case GL_UNSIGNED_INT: - { - GLuint *dst = (GLuint *) dest; - GLuint i; - for (i = 0; i < n; i++) { - dst[i] = (GLuint) source[i]; - } - if (dstPacking->SwapBytes) { - _mesa_swap4( (GLuint *) dst, n ); - } - } - break; - case GL_INT: - { - GLint *dst = (GLint *) dest; - GLuint i; - for (i = 0; i < n; i++) { - dst[i] = (GLint) source[i]; - } - if (dstPacking->SwapBytes) { - _mesa_swap4( (GLuint *) dst, n ); - } - } - break; - case GL_FLOAT: - { - GLfloat *dst = (GLfloat *) dest; - GLuint i; - for (i = 0; i < n; i++) { - dst[i] = (GLfloat) source[i]; - } - if (dstPacking->SwapBytes) { - _mesa_swap4( (GLuint *) dst, n ); - } - } - break; - case GL_HALF_FLOAT_ARB: - { - GLhalfARB *dst = (GLhalfARB *) dest; - GLuint i; - for (i = 0; i < n; i++) { - dst[i] = _mesa_float_to_half((GLfloat) source[i]); - } - if (dstPacking->SwapBytes) { - _mesa_swap2( (GLushort *) dst, n ); - } - } - break; - default: - _mesa_problem(ctx, "bad type in _mesa_pack_index_span"); - } - free(indexes); +static inline GLuint +clamp_half_to_uint(GLhalfARB h) +{ + GLfloat f = _mesa_half_to_float(h); + return f < 0.0F ? 0 : F_TO_I(f); } @@ -5023,6 +512,7 @@ _mesa_unpack_stencil_span( struct gl_context *ctx, GLuint n, srcType == GL_INT || srcType == GL_UNSIGNED_INT_24_8_EXT || srcType == GL_HALF_FLOAT_ARB || + srcType == GL_HALF_FLOAT_OES || srcType == GL_FLOAT || srcType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV); @@ -5213,6 +703,7 @@ _mesa_pack_stencil_span( struct gl_context *ctx, GLuint n, } break; case GL_HALF_FLOAT_ARB: + case GL_HALF_FLOAT_OES: { GLhalfARB *dst = (GLhalfARB *) dest; GLuint i; @@ -5430,6 +921,7 @@ _mesa_unpack_depth_span( struct gl_context *ctx, GLuint n, needClamp = GL_TRUE; break; case GL_HALF_FLOAT_ARB: + case GL_HALF_FLOAT_OES: { GLuint i; const GLhalfARB *src = (const GLhalfARB *) source; @@ -5619,6 +1111,7 @@ _mesa_pack_depth_span( struct gl_context *ctx, GLuint n, GLvoid *dest, } break; case GL_HALF_FLOAT_ARB: + case GL_HALF_FLOAT_OES: { GLhalfARB *dst = (GLhalfARB *) dest; GLuint i; @@ -5699,7 +1192,6 @@ _mesa_pack_depth_stencil_span(struct gl_context *ctx,GLuint n, - /** * Unpack image data. Apply byte swapping, byte flipping (bitmap). * Return all image data in a contiguous block. This is used when we @@ -5839,130 +1331,303 @@ _mesa_unpack_image( GLuint dimensions, } } - - -/** - * If we unpack colors from a luminance surface, we'll get pixel colors - * such as (l, l, l, a). - * When we call _mesa_pack_rgba_span_float(format=GL_LUMINANCE), that - * function will compute L=R+G+B before packing. The net effect is we'll - * accidentally store luminance values = 3*l. - * This function compensates for that by converting (aka rebasing) (l,l,l,a) - * to be (l,0,0,a). - * It's a similar story for other formats such as LUMINANCE_ALPHA, ALPHA - * and INTENSITY. - * - * Finally, we also need to do this when the actual surface format does - * not match the logical surface format. For example, suppose the user - * requests a GL_LUMINANCE texture but the driver stores it as RGBA. - * Again, we'll get pixel values like (l,l,l,a). - */ void -_mesa_rebase_rgba_float(GLuint n, GLfloat rgba[][4], GLenum baseFormat) +_mesa_pack_luminance_from_rgba_float(GLuint n, GLfloat rgba[][4], + GLvoid *dstAddr, GLenum dst_format, + GLbitfield transferOps) { - GLuint i; + int i; + GLfloat *dst = (GLfloat *) dstAddr; - switch (baseFormat) { - case GL_ALPHA: - for (i = 0; i < n; i++) { - rgba[i][RCOMP] = 0.0F; - rgba[i][GCOMP] = 0.0F; - rgba[i][BCOMP] = 0.0F; - } - break; - case GL_INTENSITY: - /* fall-through */ + switch (dst_format) { case GL_LUMINANCE: - for (i = 0; i < n; i++) { - rgba[i][GCOMP] = 0.0F; - rgba[i][BCOMP] = 0.0F; - rgba[i][ACOMP] = 1.0F; + if (transferOps & IMAGE_CLAMP_BIT) { + for (i = 0; i < n; i++) { + GLfloat sum = rgba[i][RCOMP] + rgba[i][GCOMP] + rgba[i][BCOMP]; + dst[i] = CLAMP(sum, 0.0F, 1.0F); + } + } else { + for (i = 0; i < n; i++) { + dst[i] = rgba[i][RCOMP] + rgba[i][GCOMP] + rgba[i][BCOMP]; + } } - break; + return; case GL_LUMINANCE_ALPHA: - for (i = 0; i < n; i++) { - rgba[i][GCOMP] = 0.0F; - rgba[i][BCOMP] = 0.0F; - } - break; - case GL_RGB: - for (i = 0; i < n; i++) { - rgba[i][ACOMP] = 1.0F; - } - break; - case GL_RG: - for (i = 0; i < n; i++) { - rgba[i][BCOMP] = 0.0F; - rgba[i][ACOMP] = 1.0F; - } - break; - case GL_RED: - for (i = 0; i < n; i++) { - rgba[i][GCOMP] = 0.0F; - rgba[i][BCOMP] = 0.0F; - rgba[i][ACOMP] = 1.0F; + if (transferOps & IMAGE_CLAMP_BIT) { + for (i = 0; i < n; i++) { + GLfloat sum = rgba[i][RCOMP] + rgba[i][GCOMP] + rgba[i][BCOMP]; + dst[2*i] = CLAMP(sum, 0.0F, 1.0F); + dst[2*i+1] = rgba[i][ACOMP]; + } + } else { + for (i = 0; i < n; i++) { + dst[2*i] = rgba[i][RCOMP] + rgba[i][GCOMP] + rgba[i][BCOMP]; + dst[2*i+1] = rgba[i][ACOMP]; + } } - break; - + return; default: - /* no-op */ - ; + assert(!"Unsupported format"); } } +static int32_t +clamp_sint64_to_sint32(int64_t src) +{ + return CLAMP(src, INT32_MIN, INT32_MAX); +} + +static int32_t +clamp_sint64_to_uint32(int64_t src) +{ + return CLAMP(src, 0, UINT32_MAX); +} + +static int32_t +clamp_uint64_to_uint32(uint64_t src) +{ + return MIN2(src, UINT32_MAX); +} + +static int32_t +clamp_uint64_to_sint32(uint64_t src) +{ + return MIN2(src, INT32_MAX); +} + +static int32_t +convert_integer_luminance64(int64_t src64, int bits, + bool dst_is_signed, bool src_is_signed) +{ + int32_t src32; + + /* Clamp Luminance value from 64-bit to 32-bit. Consider if we need + * any signed<->unsigned conversion too. + */ + if (src_is_signed && dst_is_signed) + src32 = clamp_sint64_to_sint32(src64); + else if (src_is_signed && !dst_is_signed) + src32 = clamp_sint64_to_uint32(src64); + else if (!src_is_signed && dst_is_signed) + src32 = clamp_uint64_to_sint32(src64); + else + src32 = clamp_uint64_to_uint32(src64); + + /* If the dst type is < 32-bit, we need an extra clamp */ + if (bits == 32) { + return src32; + } else { + if (dst_is_signed) + return _mesa_signed_to_signed(src32, bits); + else + return _mesa_unsigned_to_unsigned(src32, bits); + } +} + +static int32_t +convert_integer(int32_t src, int bits, bool dst_is_signed, bool src_is_signed) +{ + if (src_is_signed && dst_is_signed) + return _mesa_signed_to_signed(src, bits); + else if (src_is_signed && !dst_is_signed) + return _mesa_signed_to_unsigned(src, bits); + else if (!src_is_signed && dst_is_signed) + return _mesa_unsigned_to_signed(src, bits); + else + return _mesa_unsigned_to_unsigned(src, bits); +} -/** - * As above, but GLuint components. - */ void -_mesa_rebase_rgba_uint(GLuint n, GLuint rgba[][4], GLenum baseFormat) +_mesa_pack_luminance_from_rgba_integer(GLuint n, + GLuint rgba[][4], bool rgba_is_signed, + GLvoid *dstAddr, + GLenum dst_format, + GLenum dst_type) { - GLuint i; + int i; + int64_t lum64; + int32_t lum32, alpha; + bool dst_is_signed; + int dst_bits; + + assert(dst_format == GL_LUMINANCE_INTEGER_EXT || + dst_format == GL_LUMINANCE_ALPHA_INTEGER_EXT); + + /* We first compute luminance values as a 64-bit addition of the + * 32-bit R,G,B components, then we clamp the result to the dst type size. + * + * Notice that this operation involves casting the 32-bit R,G,B components + * to 64-bit before the addition. Since rgba is defined as a GLuint array + * we need to be careful when rgba packs signed data and make sure + * that we cast to a 32-bit signed integer values before casting them to + * 64-bit signed integers. + */ + dst_is_signed = (dst_type == GL_BYTE || dst_type == GL_SHORT || + dst_type == GL_INT); - switch (baseFormat) { - case GL_ALPHA: - for (i = 0; i < n; i++) { - rgba[i][RCOMP] = 0; - rgba[i][GCOMP] = 0; - rgba[i][BCOMP] = 0; - } - break; - case GL_INTENSITY: - /* fall-through */ - case GL_LUMINANCE: - for (i = 0; i < n; i++) { - rgba[i][GCOMP] = 0; - rgba[i][BCOMP] = 0; - rgba[i][ACOMP] = 1; - } - break; - case GL_LUMINANCE_ALPHA: - for (i = 0; i < n; i++) { - rgba[i][GCOMP] = 0; - rgba[i][BCOMP] = 0; - } - break; - case GL_RGB: - for (i = 0; i < n; i++) { - rgba[i][ACOMP] = 1; - } - break; - case GL_RG: + dst_bits = _mesa_sizeof_type(dst_type) * 8; + assert(dst_bits > 0); + + switch (dst_format) { + case GL_LUMINANCE_INTEGER_EXT: for (i = 0; i < n; i++) { - rgba[i][BCOMP] = 0; - rgba[i][ACOMP] = 1; + if (!rgba_is_signed) { + lum64 = (uint64_t) rgba[i][RCOMP] + + (uint64_t) rgba[i][GCOMP] + + (uint64_t) rgba[i][BCOMP]; + } else { + lum64 = (int64_t) ((int32_t) rgba[i][RCOMP]) + + (int64_t) ((int32_t) rgba[i][GCOMP]) + + (int64_t) ((int32_t) rgba[i][BCOMP]); + } + lum32 = convert_integer_luminance64(lum64, dst_bits, + dst_is_signed, rgba_is_signed); + switch (dst_type) { + case GL_BYTE: + case GL_UNSIGNED_BYTE: { + GLbyte *dst = (GLbyte *) dstAddr; + dst[i] = lum32; + } + break; + case GL_SHORT: + case GL_UNSIGNED_SHORT: { + GLshort *dst = (GLshort *) dstAddr; + dst[i] = lum32; + } + break; + case GL_INT: + case GL_UNSIGNED_INT: { + GLint *dst = (GLint *) dstAddr; + dst[i] = lum32; + } + break; + } } - break; - case GL_RED: + return; + case GL_LUMINANCE_ALPHA_INTEGER_EXT: for (i = 0; i < n; i++) { - rgba[i][GCOMP] = 0; - rgba[i][BCOMP] = 0; - rgba[i][ACOMP] = 1; + if (!rgba_is_signed) { + lum64 = (uint64_t) rgba[i][RCOMP] + + (uint64_t) rgba[i][GCOMP] + + (uint64_t) rgba[i][BCOMP]; + } else { + lum64 = (int64_t) ((int32_t) rgba[i][RCOMP]) + + (int64_t) ((int32_t) rgba[i][GCOMP]) + + (int64_t) ((int32_t) rgba[i][BCOMP]); + } + lum32 = convert_integer_luminance64(lum64, dst_bits, + dst_is_signed, rgba_is_signed); + alpha = convert_integer(rgba[i][ACOMP], dst_bits, + dst_is_signed, rgba_is_signed); + switch (dst_type) { + case GL_BYTE: + case GL_UNSIGNED_BYTE: { + GLbyte *dst = (GLbyte *) dstAddr; + dst[2*i] = lum32; + dst[2*i+1] = alpha; + } + case GL_SHORT: + case GL_UNSIGNED_SHORT: { + GLshort *dst = (GLshort *) dstAddr; + dst[i] = lum32; + dst[2*i+1] = alpha; + } + break; + case GL_INT: + case GL_UNSIGNED_INT: { + GLint *dst = (GLint *) dstAddr; + dst[i] = lum32; + dst[2*i+1] = alpha; + } + break; + } } - default: - /* no-op */ - ; + return; } } +GLfloat * +_mesa_unpack_color_index_to_rgba_float(struct gl_context *ctx, GLuint dims, + const void *src, GLenum srcFormat, GLenum srcType, + int srcWidth, int srcHeight, int srcDepth, + const struct gl_pixelstore_attrib *srcPacking, + GLbitfield transferOps) +{ + int count, img; + GLuint *indexes; + GLfloat *rgba, *dstPtr; + + count = srcWidth * srcHeight; + indexes = malloc(count * sizeof(GLuint)); + if (!indexes) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "pixel unpacking"); + return NULL; + } + + rgba = malloc(4 * count * srcDepth * sizeof(GLfloat)); + if (!rgba) { + free(indexes); + _mesa_error(ctx, GL_OUT_OF_MEMORY, "pixel unpacking"); + return NULL; + } + + /* Convert indexes to RGBA float */ + dstPtr = rgba; + for (img = 0; img < srcDepth; img++) { + const GLubyte *srcPtr = + (const GLubyte *) _mesa_image_address(dims, srcPacking, src, + srcWidth, srcHeight, + srcFormat, srcType, + img, 0, 0); + + extract_uint_indexes(count, indexes, srcFormat, srcType, srcPtr, srcPacking); + + if (transferOps & IMAGE_SHIFT_OFFSET_BIT) + _mesa_shift_and_offset_ci(ctx, count, indexes); + + _mesa_map_ci_to_rgba(ctx, count, indexes, (float (*)[4])dstPtr); + /* Don't do RGBA scale/bias or RGBA->RGBA mapping if starting + * with color indexes. + */ + transferOps &= ~(IMAGE_SCALE_BIAS_BIT | IMAGE_MAP_COLOR_BIT); + _mesa_apply_rgba_transfer_ops(ctx, transferOps, count, (float (*)[4])dstPtr); + + dstPtr += srcHeight * srcWidth * 4; + } + + free(indexes); + + return rgba; +} + +GLubyte * +_mesa_unpack_color_index_to_rgba_ubyte(struct gl_context *ctx, GLuint dims, + const void *src, GLenum srcFormat, GLenum srcType, + int srcWidth, int srcHeight, int srcDepth, + const struct gl_pixelstore_attrib *srcPacking, + GLbitfield transferOps) +{ + GLfloat *rgba; + GLubyte *dst; + int count, i; + + transferOps |= IMAGE_CLAMP_BIT; + rgba = _mesa_unpack_color_index_to_rgba_float(ctx, dims, + src, srcFormat, srcType, + srcWidth, srcHeight, srcDepth, + srcPacking, transferOps); + + count = srcWidth * srcHeight * srcDepth; + dst = malloc(count * 4 * sizeof(GLubyte)); + for (i = 0; i < count; i++) { + CLAMPED_FLOAT_TO_UBYTE(dst[i * 4 + 0], rgba[i * 4 + 0]); + CLAMPED_FLOAT_TO_UBYTE(dst[i * 4 + 1], rgba[i * 4 + 1]); + CLAMPED_FLOAT_TO_UBYTE(dst[i * 4 + 2], rgba[i * 4 + 2]); + CLAMPED_FLOAT_TO_UBYTE(dst[i * 4 + 3], rgba[i * 4 + 3]); + } + + free(rgba); + + return dst; +} diff --git a/mesalib/src/mesa/main/pack.h b/mesalib/src/mesa/main/pack.h index 2173b652e..ac0a099e3 100644 --- a/mesalib/src/mesa/main/pack.h +++ b/mesalib/src/mesa/main/pack.h @@ -41,62 +41,11 @@ _mesa_pack_polygon_stipple(const GLuint pattern[32], GLubyte *dest, const struct gl_pixelstore_attrib *packing); -extern GLvoid * -_mesa_unpack_bitmap(GLint width, GLint height, const GLubyte *pixels, - const struct gl_pixelstore_attrib *packing); - extern void _mesa_pack_bitmap(GLint width, GLint height, const GLubyte *source, GLubyte *dest, const struct gl_pixelstore_attrib *packing); -extern void -_mesa_pack_rgba_span_float(struct gl_context *ctx, GLuint n, - GLfloat rgba[][4], - GLenum dstFormat, GLenum dstType, GLvoid *dstAddr, - const struct gl_pixelstore_attrib *dstPacking, - GLbitfield transferOps); - - -extern void -_mesa_unpack_color_span_ubyte(struct gl_context *ctx, - GLuint n, GLenum dstFormat, GLubyte dest[], - GLenum srcFormat, GLenum srcType, - const GLvoid *source, - const struct gl_pixelstore_attrib *srcPacking, - GLbitfield transferOps); - - -extern void -_mesa_unpack_color_span_float(struct gl_context *ctx, - GLuint n, GLenum dstFormat, GLfloat dest[], - GLenum srcFormat, GLenum srcType, - const GLvoid *source, - const struct gl_pixelstore_attrib *srcPacking, - GLbitfield transferOps); - -extern void -_mesa_unpack_color_span_uint(struct gl_context *ctx, - GLuint n, GLenum dstFormat, GLuint *dest, - GLenum srcFormat, GLenum srcType, - const GLvoid *source, - const struct gl_pixelstore_attrib *srcPacking); - -extern void -_mesa_unpack_index_span(struct gl_context *ctx, GLuint n, - GLenum dstType, GLvoid *dest, - GLenum srcType, const GLvoid *source, - const struct gl_pixelstore_attrib *srcPacking, - GLbitfield transferOps); - - -extern void -_mesa_pack_index_span(struct gl_context *ctx, GLuint n, - GLenum dstType, GLvoid *dest, const GLuint *source, - const struct gl_pixelstore_attrib *dstPacking, - GLbitfield transferOps); - - extern void _mesa_unpack_stencil_span(struct gl_context *ctx, GLuint n, GLenum dstType, GLvoid *dest, @@ -136,23 +85,28 @@ _mesa_unpack_image(GLuint dimensions, GLenum format, GLenum type, const GLvoid *pixels, const struct gl_pixelstore_attrib *unpack); - -void -_mesa_pack_rgba_span_from_uints(struct gl_context *ctx, GLuint n, GLuint rgba[][4], - GLenum dstFormat, GLenum dstType, - GLvoid *dstAddr); - - -void -_mesa_pack_rgba_span_from_ints(struct gl_context *ctx, GLuint n, GLint rgba[][4], - GLenum dstFormat, GLenum dstType, - GLvoid *dstAddr); - - extern void -_mesa_rebase_rgba_float(GLuint n, GLfloat rgba[][4], GLenum baseFormat); +_mesa_pack_luminance_from_rgba_float(GLuint n, GLfloat rgba[][4], + GLvoid *dstAddr, GLenum dst_format, + GLbitfield transferOps); extern void -_mesa_rebase_rgba_uint(GLuint n, GLuint rgba[][4], GLenum baseFormat); +_mesa_pack_luminance_from_rgba_integer(GLuint n, GLuint rgba[][4], bool rgba_is_signed, + GLvoid *dstAddr, GLenum dst_format, + GLenum dst_type); + +extern GLfloat * +_mesa_unpack_color_index_to_rgba_float(struct gl_context *ctx, GLuint dims, + const void *src, GLenum srcFormat, GLenum srcType, + int srcWidth, int srcHeight, int srcDepth, + const struct gl_pixelstore_attrib *srcPacking, + GLbitfield transferOps); + +extern GLubyte * +_mesa_unpack_color_index_to_rgba_ubyte(struct gl_context *ctx, GLuint dims, + const void *src, GLenum srcFormat, GLenum srcType, + int srcWidth, int srcHeight, int srcDepth, + const struct gl_pixelstore_attrib *srcPacking, + GLbitfield transferOps); #endif diff --git a/mesalib/src/mesa/main/pack_tmp.h b/mesalib/src/mesa/main/pack_tmp.h deleted file mode 100644 index 0d4eb387d..000000000 --- a/mesalib/src/mesa/main/pack_tmp.h +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Copyright © 2012 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. - */ - -static void -FN_NAME(struct gl_context *ctx, - DST_TYPE *dst, - GLenum dstFormat, - SRC_TYPE rgba[][4], - int n) -{ - int i; - - switch (dstFormat) { - case GL_RED_INTEGER_EXT: - for (i=0;iPolygon.Stipple state. - * If we're getting the stipple data from a PBO, we map the buffer - * in order to access the data. - * In any case, we obey the current pixel unpacking parameters when fetching - * the stipple data. - * - * In the future, this routine should be used as a fallback, called via - * ctx->Driver.PolygonStipple(). We'll have to update all the DRI drivers - * too. + * Called by glPolygonStipple. */ -void -_mesa_polygon_stipple(struct gl_context *ctx, const GLubyte *pattern) +void GLAPIENTRY +_mesa_PolygonStipple(const GLubyte *pattern) { + GET_CURRENT_CONTEXT(ctx); + + if (MESA_VERBOSE & VERBOSE_API) + _mesa_debug(ctx, "glPolygonStipple\n"); + + FLUSH_VERTICES(ctx, _NEW_POLYGONSTIPPLE); + pattern = _mesa_map_validate_pbo_source(ctx, 2, &ctx->Unpack, 32, 32, 1, GL_COLOR_INDEX, GL_BITMAP, @@ -200,23 +199,6 @@ _mesa_polygon_stipple(struct gl_context *ctx, const GLubyte *pattern) _mesa_unpack_polygon_stipple(pattern, ctx->PolygonStipple, &ctx->Unpack); _mesa_unmap_pbo_source(ctx, &ctx->Unpack); -} - - -/** - * Called by glPolygonStipple. - */ -void GLAPIENTRY -_mesa_PolygonStipple( const GLubyte *pattern ) -{ - GET_CURRENT_CONTEXT(ctx); - - if (MESA_VERBOSE&VERBOSE_API) - _mesa_debug(ctx, "glPolygonStipple\n"); - - FLUSH_VERTICES(ctx, _NEW_POLYGONSTIPPLE); - - _mesa_polygon_stipple(ctx, pattern); if (ctx->Driver.PolygonStipple) ctx->Driver.PolygonStipple(ctx, pattern); @@ -253,25 +235,33 @@ _mesa_GetPolygonStipple( GLubyte *dest ) _mesa_GetnPolygonStippleARB(INT_MAX, dest); } - -void GLAPIENTRY -_mesa_PolygonOffset( GLfloat factor, GLfloat units ) +void +_mesa_polygon_offset_clamp(struct gl_context *ctx, + GLfloat factor, GLfloat units, GLfloat clamp) { - GET_CURRENT_CONTEXT(ctx); - - if (MESA_VERBOSE&VERBOSE_API) - _mesa_debug(ctx, "glPolygonOffset %f %f\n", factor, units); - if (ctx->Polygon.OffsetFactor == factor && - ctx->Polygon.OffsetUnits == units) + ctx->Polygon.OffsetUnits == units && + ctx->Polygon.OffsetClamp == clamp) return; FLUSH_VERTICES(ctx, _NEW_POLYGON); ctx->Polygon.OffsetFactor = factor; ctx->Polygon.OffsetUnits = units; + ctx->Polygon.OffsetClamp = clamp; if (ctx->Driver.PolygonOffset) - ctx->Driver.PolygonOffset( ctx, factor, units ); + ctx->Driver.PolygonOffset( ctx, factor, units, clamp ); +} + +void GLAPIENTRY +_mesa_PolygonOffset( GLfloat factor, GLfloat units ) +{ + GET_CURRENT_CONTEXT(ctx); + + if (MESA_VERBOSE&VERBOSE_API) + _mesa_debug(ctx, "glPolygonOffset %f %f\n", factor, units); + + _mesa_polygon_offset_clamp(ctx, factor, units, 0.0); } @@ -283,6 +273,23 @@ _mesa_PolygonOffsetEXT( GLfloat factor, GLfloat bias ) _mesa_PolygonOffset(factor, bias * ctx->DrawBuffer->_DepthMaxF ); } +void GLAPIENTRY +_mesa_PolygonOffsetClampEXT( GLfloat factor, GLfloat units, GLfloat clamp ) +{ + GET_CURRENT_CONTEXT(ctx); + + if (!ctx->Extensions.EXT_polygon_offset_clamp) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "unsupported function (glPolygonOffsetClampEXT) called"); + return; + } + + if (MESA_VERBOSE&VERBOSE_API) + _mesa_debug(ctx, "glPolygonOffsetClampEXT %f %f %f\n", factor, units, clamp); + + _mesa_polygon_offset_clamp(ctx, factor, units, clamp); +} + /**********************************************************************/ @@ -310,6 +317,7 @@ void _mesa_init_polygon( struct gl_context * ctx ) ctx->Polygon.StippleFlag = GL_FALSE; ctx->Polygon.OffsetFactor = 0.0F; ctx->Polygon.OffsetUnits = 0.0F; + ctx->Polygon.OffsetClamp = 0.0F; ctx->Polygon.OffsetPoint = GL_FALSE; ctx->Polygon.OffsetLine = GL_FALSE; ctx->Polygon.OffsetFill = GL_FALSE; diff --git a/mesalib/src/mesa/main/polygon.h b/mesalib/src/mesa/main/polygon.h index 69c5cbc45..41344a2ef 100644 --- a/mesalib/src/mesa/main/polygon.h +++ b/mesalib/src/mesa/main/polygon.h @@ -39,10 +39,6 @@ struct gl_context; extern void GLAPIENTRY _mesa_GetnPolygonStippleARB( GLsizei bufSize, GLubyte *dest ); -extern void -_mesa_polygon_stipple(struct gl_context *ctx, const GLubyte *pattern); - - extern void GLAPIENTRY _mesa_CullFace( GLenum mode ); @@ -58,13 +54,19 @@ _mesa_PolygonOffset( GLfloat factor, GLfloat units ); extern void GLAPIENTRY _mesa_PolygonOffsetEXT( GLfloat factor, GLfloat bias ); +extern void GLAPIENTRY +_mesa_PolygonOffsetClampEXT( GLfloat factor, GLfloat units, GLfloat clamp ); + extern void GLAPIENTRY _mesa_PolygonStipple( const GLubyte *mask ); extern void GLAPIENTRY _mesa_GetPolygonStipple( GLubyte *mask ); -extern void +extern void +_mesa_polygon_offset_clamp(struct gl_context *ctx, + GLfloat factor, GLfloat units, GLfloat clamp); +extern void _mesa_init_polygon( struct gl_context * ctx ); #endif diff --git a/mesalib/src/mesa/main/querymatrix.c b/mesalib/src/mesa/main/querymatrix.c index eb36c7604..ef8517571 100644 --- a/mesalib/src/mesa/main/querymatrix.c +++ b/mesalib/src/mesa/main/querymatrix.c @@ -37,8 +37,12 @@ #define INT_TO_FIXED(x) ((GLfixed) ((x) << 16)) #define FLOAT_TO_FIXED(x) ((GLfixed) ((x) * 65536.0)) -#if defined(_MSC_VER) -#if _MSC_VER < 1800 /* Not required on VS2013 and above. */ +#if defined(fpclassify) +/* ISO C99 says that fpclassify is a macro. Assume that any implementation + * of fpclassify, whether it's in a C99 compiler or not, will be a macro. + */ +#elif defined(_MSC_VER) +/* Not required on VS2013 and above. */ /* Oddly, the fpclassify() function doesn't exist in such a form * on MSVC. This is an implementation using slightly different * lower-level Windows functions. @@ -71,16 +75,8 @@ fpclassify(double x) return FP_NAN; } } -#endif /* _MSC_VER < 1800 */ - -#elif defined(__APPLE__) || defined(__CYGWIN__) || defined(__FreeBSD__) || \ - defined(__OpenBSD__) || defined(__NetBSD__) || defined(__DragonFly__) || \ - (defined(__sun) && defined(__C99FEATURES__)) || defined(__MINGW32__) || \ - (defined(__sun) && defined(__GNUC__)) || defined(ANDROID) || defined(__HAIKU__) - -/* fpclassify is available. */ -#elif !defined(_XOPEN_SOURCE) || _XOPEN_SOURCE < 600 +#else enum {FP_NAN, FP_INFINITE, FP_ZERO, FP_SUBNORMAL, FP_NORMAL} fpclassify(double x) diff --git a/mesalib/src/mesa/main/queryobj.c b/mesalib/src/mesa/main/queryobj.c index a9d067bbf..842d8dda5 100644 --- a/mesalib/src/mesa/main/queryobj.c +++ b/mesalib/src/mesa/main/queryobj.c @@ -142,6 +142,18 @@ _mesa_init_query_object_functions(struct dd_function_table *driver) driver->CheckQuery = _mesa_check_query; } +static struct gl_query_object ** +get_pipe_stats_binding_point(struct gl_context *ctx, + GLenum target) +{ + if (!_mesa_is_desktop_gl(ctx) || + !ctx->Extensions.ARB_pipeline_statistics_query) + return NULL; + + const int which = target - GL_VERTICES_SUBMITTED_ARB; + assert(which < MAX_PIPELINE_STATISTICS); + return &ctx->Query.pipeline_stats[which]; +} /** * Return pointer to the query object binding point for the given target and @@ -183,6 +195,38 @@ get_query_binding_point(struct gl_context *ctx, GLenum target, GLuint index) return &ctx->Query.PrimitivesWritten[index]; else return NULL; + + case GL_VERTICES_SUBMITTED_ARB: + case GL_PRIMITIVES_SUBMITTED_ARB: + case GL_VERTEX_SHADER_INVOCATIONS_ARB: + case GL_FRAGMENT_SHADER_INVOCATIONS_ARB: + case GL_CLIPPING_INPUT_PRIMITIVES_ARB: + case GL_CLIPPING_OUTPUT_PRIMITIVES_ARB: + return get_pipe_stats_binding_point(ctx, target); + + case GL_GEOMETRY_SHADER_INVOCATIONS: + /* GL_GEOMETRY_SHADER_INVOCATIONS is defined in a non-sequential order */ + target = GL_VERTICES_SUBMITTED_ARB + MAX_PIPELINE_STATISTICS - 1; + /* fallthrough */ + case GL_GEOMETRY_SHADER_PRIMITIVES_EMITTED_ARB: + if (_mesa_has_geometry_shaders(ctx)) + return get_pipe_stats_binding_point(ctx, target); + else + return NULL; + + case GL_TESS_CONTROL_SHADER_PATCHES_ARB: + case GL_TESS_EVALUATION_SHADER_INVOCATIONS_ARB: + if (ctx->Extensions.ARB_tessellation_shader) + return get_pipe_stats_binding_point(ctx, target); + else + return NULL; + + case GL_COMPUTE_SHADER_INVOCATIONS_ARB: + if (_mesa_has_compute_shaders(ctx)) + return get_pipe_stats_binding_point(ctx, target); + else + return NULL; + default: return NULL; } @@ -553,6 +597,39 @@ _mesa_GetQueryIndexediv(GLenum target, GLuint index, GLenum pname, case GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN: *params = ctx->Const.QueryCounterBits.PrimitivesWritten; break; + case GL_VERTICES_SUBMITTED_ARB: + *params = ctx->Const.QueryCounterBits.VerticesSubmitted; + break; + case GL_PRIMITIVES_SUBMITTED_ARB: + *params = ctx->Const.QueryCounterBits.PrimitivesSubmitted; + break; + case GL_VERTEX_SHADER_INVOCATIONS_ARB: + *params = ctx->Const.QueryCounterBits.VsInvocations; + break; + case GL_TESS_CONTROL_SHADER_PATCHES_ARB: + *params = ctx->Const.QueryCounterBits.TessPatches; + break; + case GL_TESS_EVALUATION_SHADER_INVOCATIONS_ARB: + *params = ctx->Const.QueryCounterBits.TessInvocations; + break; + case GL_GEOMETRY_SHADER_INVOCATIONS: + *params = ctx->Const.QueryCounterBits.GsInvocations; + break; + case GL_GEOMETRY_SHADER_PRIMITIVES_EMITTED_ARB: + *params = ctx->Const.QueryCounterBits.GsPrimitives; + break; + case GL_FRAGMENT_SHADER_INVOCATIONS_ARB: + *params = ctx->Const.QueryCounterBits.FsInvocations; + break; + case GL_COMPUTE_SHADER_INVOCATIONS_ARB: + *params = ctx->Const.QueryCounterBits.ComputeInvocations; + break; + case GL_CLIPPING_INPUT_PRIMITIVES_ARB: + *params = ctx->Const.QueryCounterBits.ClInPrimitives; + break; + case GL_CLIPPING_OUTPUT_PRIMITIVES_ARB: + *params = ctx->Const.QueryCounterBits.ClOutPrimitives; + break; default: _mesa_problem(ctx, "Unknown target in glGetQueryIndexediv(target = %s)", @@ -771,6 +848,18 @@ _mesa_init_queryobj(struct gl_context *ctx) ctx->Const.QueryCounterBits.Timestamp = 64; ctx->Const.QueryCounterBits.PrimitivesGenerated = 64; ctx->Const.QueryCounterBits.PrimitivesWritten = 64; + + ctx->Const.QueryCounterBits.VerticesSubmitted = 64; + ctx->Const.QueryCounterBits.PrimitivesSubmitted = 64; + ctx->Const.QueryCounterBits.VsInvocations = 64; + ctx->Const.QueryCounterBits.TessPatches = 64; + ctx->Const.QueryCounterBits.TessInvocations = 64; + ctx->Const.QueryCounterBits.GsInvocations = 64; + ctx->Const.QueryCounterBits.GsPrimitives = 64; + ctx->Const.QueryCounterBits.FsInvocations = 64; + ctx->Const.QueryCounterBits.ComputeInvocations = 64; + ctx->Const.QueryCounterBits.ClInPrimitives = 64; + ctx->Const.QueryCounterBits.ClOutPrimitives = 64; } diff --git a/mesalib/src/mesa/main/rastpos.c b/mesalib/src/mesa/main/rastpos.c index a9a6ceec0..2027a9bd0 100644 --- a/mesalib/src/mesa/main/rastpos.c +++ b/mesalib/src/mesa/main/rastpos.c @@ -490,7 +490,7 @@ void glWindowPos4fMESA( GLfloat x, GLfloat y, GLfloat z, GLfloat w ) */ void _mesa_init_rastpos( struct gl_context * ctx ) { - int i; + unsigned i; ASSIGN_4V( ctx->Current.RasterPos, 0.0, 0.0, 0.0, 1.0 ); ctx->Current.RasterDistance = 0.0; diff --git a/mesalib/src/mesa/main/readpix.c b/mesalib/src/mesa/main/readpix.c index b09cf5499..ca4b9431b 100644 --- a/mesalib/src/mesa/main/readpix.c +++ b/mesalib/src/mesa/main/readpix.c @@ -39,6 +39,8 @@ #include "state.h" #include "glformats.h" #include "fbobject.h" +#include "format_utils.h" +#include "pixeltransfer.h" /** @@ -405,174 +407,217 @@ read_stencil_pixels( struct gl_context *ctx, ctx->Driver.UnmapRenderbuffer(ctx, rb); } - -/** - * Try to do glReadPixels of RGBA data using swizzle. - * \return GL_TRUE if successful, GL_FALSE otherwise (use the slow path) +/* + * Read R, G, B, A, RGB, L, or LA pixels. */ -static GLboolean -read_rgba_pixels_swizzle(struct gl_context *ctx, - GLint x, GLint y, - GLsizei width, GLsizei height, - GLenum format, GLenum type, - GLvoid *pixels, - const struct gl_pixelstore_attrib *packing) +static void +read_rgba_pixels( struct gl_context *ctx, + GLint x, GLint y, + GLsizei width, GLsizei height, + GLenum format, GLenum type, GLvoid *pixels, + const struct gl_pixelstore_attrib *packing ) { - struct gl_renderbuffer *rb = ctx->ReadBuffer->_ColorReadBuffer; + GLbitfield transferOps; + bool dst_is_integer, dst_is_luminance, needs_rebase; + int dst_stride, src_stride, rb_stride; + uint32_t dst_format, src_format; GLubyte *dst, *map; - int dstStride, stride, j; - GLboolean swizzle_rb = GL_FALSE, copy_xrgb = GL_FALSE; - - /* XXX we could check for other swizzle/special cases here as needed */ - if (rb->Format == MESA_FORMAT_R8G8B8A8_UNORM && - format == GL_BGRA && - type == GL_UNSIGNED_INT_8_8_8_8_REV && - !ctx->Pack.SwapBytes) { - swizzle_rb = GL_TRUE; - } - else if (rb->Format == MESA_FORMAT_B8G8R8X8_UNORM && - format == GL_BGRA && - type == GL_UNSIGNED_INT_8_8_8_8_REV && - !ctx->Pack.SwapBytes) { - copy_xrgb = GL_TRUE; - } - else { - return GL_FALSE; - } + mesa_format rb_format; + bool needs_rgba; + void *rgba, *src; + bool src_is_uint = false; + uint8_t rebase_swizzle[4]; + struct gl_framebuffer *fb = ctx->ReadBuffer; + struct gl_renderbuffer *rb = fb->_ColorReadBuffer; - dstStride = _mesa_image_row_stride(packing, width, format, type); + if (!rb) + return; + + transferOps = get_readpixels_transfer_ops(ctx, rb->Format, format, type, + GL_FALSE); + /* Describe the dst format */ + dst_is_integer = _mesa_is_enum_format_integer(format); + dst_stride = _mesa_image_row_stride(packing, width, format, type); + dst_format = _mesa_format_from_format_and_type(format, type); + dst_is_luminance = format == GL_LUMINANCE || + format == GL_LUMINANCE_ALPHA || + format == GL_LUMINANCE_INTEGER_EXT || + format == GL_LUMINANCE_ALPHA_INTEGER_EXT; dst = (GLubyte *) _mesa_image_address2d(packing, pixels, width, height, - format, type, 0, 0); + format, type, 0, 0); + /* Map the source render buffer */ ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height, GL_MAP_READ_BIT, - &map, &stride); + &map, &rb_stride); if (!map) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels"); - return GL_TRUE; /* don't bother trying the slow path */ + return; } + rb_format = _mesa_get_srgb_format_linear(rb->Format); - if (swizzle_rb) { - /* swap R/B */ - for (j = 0; j < height; j++) { - int i; - for (i = 0; i < width; i++) { - GLuint *dst4 = (GLuint *) dst, *map4 = (GLuint *) map; - GLuint pixel = map4[i]; - dst4[i] = (pixel & 0xff00ff00) - | ((pixel & 0x00ff0000) >> 16) - | ((pixel & 0x000000ff) << 16); - } - dst += dstStride; - map += stride; - } - } else if (copy_xrgb) { - /* convert xrgb -> argb */ - for (j = 0; j < height; j++) { - GLuint *dst4 = (GLuint *) dst, *map4 = (GLuint *) map; - int i; - for (i = 0; i < width; i++) { - dst4[i] = map4[i] | 0xff000000; /* set A=0xff */ - } - dst += dstStride; - map += stride; - } + /* + * Depending on the base formats involved in the conversion we might need to + * rebase some values, so for these formats we compute a rebase swizzle. + */ + if (rb->_BaseFormat == GL_LUMINANCE || rb->_BaseFormat == GL_INTENSITY) { + needs_rebase = true; + rebase_swizzle[0] = MESA_FORMAT_SWIZZLE_X; + rebase_swizzle[1] = MESA_FORMAT_SWIZZLE_ZERO; + rebase_swizzle[2] = MESA_FORMAT_SWIZZLE_ZERO; + rebase_swizzle[3] = MESA_FORMAT_SWIZZLE_ONE; + } else if (rb->_BaseFormat == GL_LUMINANCE_ALPHA) { + needs_rebase = true; + rebase_swizzle[0] = MESA_FORMAT_SWIZZLE_X; + rebase_swizzle[1] = MESA_FORMAT_SWIZZLE_ZERO; + rebase_swizzle[2] = MESA_FORMAT_SWIZZLE_ZERO; + rebase_swizzle[3] = MESA_FORMAT_SWIZZLE_W; + } else if (_mesa_get_format_base_format(rb_format) != rb->_BaseFormat) { + needs_rebase = + _mesa_compute_rgba2base2rgba_component_mapping(rb->_BaseFormat, + rebase_swizzle); + } else { + needs_rebase = false; } - ctx->Driver.UnmapRenderbuffer(ctx, rb); - - return GL_TRUE; -} - -static void -slow_read_rgba_pixels( struct gl_context *ctx, - GLint x, GLint y, - GLsizei width, GLsizei height, - GLenum format, GLenum type, - GLvoid *pixels, - const struct gl_pixelstore_attrib *packing, - GLbitfield transferOps ) -{ - struct gl_renderbuffer *rb = ctx->ReadBuffer->_ColorReadBuffer; - const mesa_format rbFormat = _mesa_get_srgb_format_linear(rb->Format); - void *rgba; - GLubyte *dst, *map; - int dstStride, stride, j; - GLboolean dst_is_integer = _mesa_is_enum_format_integer(format); - GLboolean dst_is_uint = _mesa_is_format_unsigned(rbFormat); - - dstStride = _mesa_image_row_stride(packing, width, format, type); - dst = (GLubyte *) _mesa_image_address2d(packing, pixels, width, height, - format, type, 0, 0); - - ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height, GL_MAP_READ_BIT, - &map, &stride); - if (!map) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels"); - return; - } + /* Since _mesa_format_convert does not handle transferOps we need to handle + * them before we call the function. This requires to convert to RGBA float + * first so we can call _mesa_apply_rgba_transfer_ops. If the dst format is + * integer transferOps do not apply. + * + * Converting to luminance also requires converting to RGBA first, so we can + * then compute luminance values as L=R+G+B. Notice that this is different + * from GetTexImage, where we compute L=R. + */ + assert(!transferOps || (transferOps && !dst_is_integer)); - rgba = malloc(width * MAX_PIXEL_BYTES); - if (!rgba) - goto done; + needs_rgba = transferOps || dst_is_luminance; + rgba = NULL; + if (needs_rgba) { + uint32_t rgba_format; + int rgba_stride; + bool need_convert; - for (j = 0; j < height; j++) { + /* Convert to RGBA float or int/uint depending on the type of the src */ if (dst_is_integer) { - _mesa_unpack_uint_rgba_row(rbFormat, width, map, (GLuint (*)[4]) rgba); - _mesa_rebase_rgba_uint(width, (GLuint (*)[4]) rgba, - rb->_BaseFormat); - if (dst_is_uint) { - _mesa_pack_rgba_span_from_uints(ctx, width, (GLuint (*)[4]) rgba, format, - type, dst); + src_is_uint = _mesa_is_format_unsigned(rb_format); + if (src_is_uint) { + rgba_format = RGBA32_UINT; + rgba_stride = width * 4 * sizeof(GLuint); } else { - _mesa_pack_rgba_span_from_ints(ctx, width, (GLint (*)[4]) rgba, format, - type, dst); + rgba_format = RGBA32_INT; + rgba_stride = width * 4 * sizeof(GLint); } } else { - _mesa_unpack_rgba_row(rbFormat, width, map, (GLfloat (*)[4]) rgba); - _mesa_rebase_rgba_float(width, (GLfloat (*)[4]) rgba, - rb->_BaseFormat); - _mesa_pack_rgba_span_float(ctx, width, (GLfloat (*)[4]) rgba, format, - type, dst, packing, transferOps); + rgba_format = RGBA32_FLOAT; + rgba_stride = width * 4 * sizeof(GLfloat); } - dst += dstStride; - map += stride; - } - - free(rgba); - -done: - ctx->Driver.UnmapRenderbuffer(ctx, rb); -} -/* - * Read R, G, B, A, RGB, L, or LA pixels. - */ -static void -read_rgba_pixels( struct gl_context *ctx, - GLint x, GLint y, - GLsizei width, GLsizei height, - GLenum format, GLenum type, GLvoid *pixels, - const struct gl_pixelstore_attrib *packing ) -{ - GLbitfield transferOps; - struct gl_framebuffer *fb = ctx->ReadBuffer; - struct gl_renderbuffer *rb = fb->_ColorReadBuffer; + /* If we are lucky and the dst format matches the RGBA format we need to + * convert to, then we can convert directly into the dst buffer and avoid + * the final conversion/copy from the rgba buffer to the dst buffer. + */ + if (dst_format == rgba_format) { + need_convert = false; + rgba = dst; + } else { + need_convert = true; + rgba = malloc(height * rgba_stride); + if (!rgba) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels"); + goto done_unmap; + } + } - if (!rb) - return; + /* Convert to RGBA now */ + _mesa_format_convert(rgba, rgba_format, rgba_stride, + map, rb_format, rb_stride, + width, height, + needs_rebase ? rebase_swizzle : NULL); + + /* Handle transfer ops if necessary */ + if (transferOps) + _mesa_apply_rgba_transfer_ops(ctx, transferOps, width * height, rgba); + + /* If we had to rebase, we have already taken care of that */ + needs_rebase = false; + + /* If we were lucky and our RGBA conversion matches the dst format, then + * we are done. + */ + if (!need_convert) + goto done_swap; + + /* Otherwise, we need to convert from RGBA to dst next */ + src = rgba; + src_format = rgba_format; + src_stride = rgba_stride; + } else { + /* No RGBA conversion needed, convert directly to dst */ + src = map; + src_format = rb_format; + src_stride = rb_stride; + } - transferOps = get_readpixels_transfer_ops(ctx, rb->Format, format, type, - GL_FALSE); + /* Do the conversion. + * + * If the dst format is Luminance, we need to do the conversion by computing + * L=R+G+B values. + */ + if (!dst_is_luminance) { + _mesa_format_convert(dst, dst_format, dst_stride, + src, src_format, src_stride, + width, height, + needs_rebase ? rebase_swizzle : NULL); + } else if (!dst_is_integer) { + /* Compute float Luminance values from RGBA float */ + int luminance_stride, luminance_bytes; + void *luminance; + uint32_t luminance_format; + + luminance_stride = width * sizeof(GL_FLOAT); + if (format == GL_LUMINANCE_ALPHA) + luminance_stride *= 2; + luminance_bytes = height * luminance_stride; + luminance = malloc(luminance_bytes); + if (!luminance) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels"); + free(rgba); + goto done_unmap; + } + _mesa_pack_luminance_from_rgba_float(width * height, src, + luminance, format, transferOps); + + /* Convert from Luminance float to dst (this will hadle type conversion + * from float to the type of dst if necessary) + */ + luminance_format = _mesa_format_from_format_and_type(format, GL_FLOAT); + _mesa_format_convert(dst, dst_format, dst_stride, + luminance, luminance_format, luminance_stride, + width, height, NULL); + } else { + _mesa_pack_luminance_from_rgba_integer(width * height, src, !src_is_uint, + dst, format, type); + } - /* Try the optimized paths first. */ - if (!transferOps && - read_rgba_pixels_swizzle(ctx, x, y, width, height, - format, type, pixels, packing)) { - return; + if (rgba) + free(rgba); + +done_swap: + /* Handle byte swapping if required */ + if (packing->SwapBytes) { + GLint swapSize = _mesa_sizeof_packed_type(type); + if (swapSize == 2 || swapSize == 4) { + int swapsPerPixel = _mesa_bytes_per_pixel(format, type) / swapSize; + assert(_mesa_bytes_per_pixel(format, type) % swapSize == 0); + if (swapSize == 2) + _mesa_swap2((GLushort *) dst, width * height * swapsPerPixel); + else if (swapSize == 4) + _mesa_swap4((GLuint *) dst, width * height * swapsPerPixel); + } } - slow_read_rgba_pixels(ctx, x, y, width, height, - format, type, pixels, packing, transferOps); +done_unmap: + ctx->Driver.UnmapRenderbuffer(ctx, rb); } /** diff --git a/mesalib/src/mesa/main/renderbuffer.c b/mesalib/src/mesa/main/renderbuffer.c index 0bc7f2b96..98f3c13b5 100644 --- a/mesalib/src/mesa/main/renderbuffer.c +++ b/mesalib/src/mesa/main/renderbuffer.c @@ -38,6 +38,8 @@ void _mesa_init_renderbuffer(struct gl_renderbuffer *rb, GLuint name) { + GET_CURRENT_CONTEXT(ctx); + mtx_init(&rb->Mutex, mtx_plain); rb->ClassID = 0; @@ -53,7 +55,23 @@ _mesa_init_renderbuffer(struct gl_renderbuffer *rb, GLuint name) rb->Width = 0; rb->Height = 0; rb->Depth = 0; - rb->InternalFormat = GL_RGBA; + + /* In GL 3, the initial format is GL_RGBA according to Table 6.26 + * on page 302 of the GL 3.3 spec. + * + * In GLES 3, the initial format is GL_RGBA4 according to Table 6.15 + * on page 258 of the GLES 3.0.4 spec. + * + * If the context is current, set the initial format based on the + * specs. If the context is not current, we cannot determine the + * API, so default to GL_RGBA. + */ + if (ctx && _mesa_is_gles3(ctx)) { + rb->InternalFormat = GL_RGBA4; + } else { + rb->InternalFormat = GL_RGBA; + } + rb->Format = MESA_FORMAT_NONE; } diff --git a/mesalib/src/mesa/main/samplerobj.c b/mesalib/src/mesa/main/samplerobj.c index 18a14d89a..d62a06bf1 100644 --- a/mesalib/src/mesa/main/samplerobj.c +++ b/mesalib/src/mesa/main/samplerobj.c @@ -732,8 +732,16 @@ _mesa_SamplerParameteri(GLuint sampler, GLenum pname, GLint param) sampObj = _mesa_lookup_samplerobj(ctx, sampler); if (!sampObj) { - _mesa_error(ctx, GL_INVALID_VALUE, "glSamplerParameteri(sampler %u)", - sampler); + /* '3.8.2 Sampler Objects' section of the GL-ES 3.0 specification states: + * + * "An INVALID_OPERATION error is generated if sampler is not the name + * of a sampler object previously returned from a call to GenSamplers." + * + * In desktop GL, an GL_INVALID_VALUE is returned instead. + */ + _mesa_error(ctx, (_mesa_is_gles(ctx) ? + GL_INVALID_OPERATION : GL_INVALID_VALUE), + "glSamplerParameteri(sampler %u)", sampler); return; } @@ -817,8 +825,16 @@ _mesa_SamplerParameterf(GLuint sampler, GLenum pname, GLfloat param) sampObj = _mesa_lookup_samplerobj(ctx, sampler); if (!sampObj) { - _mesa_error(ctx, GL_INVALID_VALUE, "glSamplerParameterf(sampler %u)", - sampler); + /* '3.8.2 Sampler Objects' section of the GL-ES 3.0 specification states: + * + * "An INVALID_OPERATION error is generated if sampler is not the name + * of a sampler object previously returned from a call to GenSamplers." + * + * In desktop GL, an GL_INVALID_VALUE is returned instead. + */ + _mesa_error(ctx, (_mesa_is_gles(ctx) ? + GL_INVALID_OPERATION : GL_INVALID_VALUE), + "glSamplerParameterf(sampler %u)", sampler); return; } @@ -901,8 +917,16 @@ _mesa_SamplerParameteriv(GLuint sampler, GLenum pname, const GLint *params) sampObj = _mesa_lookup_samplerobj(ctx, sampler); if (!sampObj) { - _mesa_error(ctx, GL_INVALID_VALUE, "glSamplerParameteriv(sampler %u)", - sampler); + /* '3.8.2 Sampler Objects' section of the GL-ES 3.0 specification states: + * + * "An INVALID_OPERATION error is generated if sampler is not the name + * of a sampler object previously returned from a call to GenSamplers." + * + * In desktop GL, an GL_INVALID_VALUE is returned instead. + */ + _mesa_error(ctx, (_mesa_is_gles(ctx) ? + GL_INVALID_OPERATION : GL_INVALID_VALUE), + "glSamplerParameteriv(sampler %u)", sampler); return; } @@ -993,8 +1017,16 @@ _mesa_SamplerParameterfv(GLuint sampler, GLenum pname, const GLfloat *params) sampObj = _mesa_lookup_samplerobj(ctx, sampler); if (!sampObj) { - _mesa_error(ctx, GL_INVALID_VALUE, "glSamplerParameterfv(sampler %u)", - sampler); + /* '3.8.2 Sampler Objects' section of the GL-ES 3.0 specification states: + * + * "An INVALID_OPERATION error is generated if sampler is not the name + * of a sampler object previously returned from a call to GenSamplers." + * + * In desktop GL, an GL_INVALID_VALUE is returned instead. + */ + _mesa_error(ctx, (_mesa_is_gles(ctx) ? + GL_INVALID_OPERATION : GL_INVALID_VALUE), + "glSamplerParameterfv(sampler %u)", sampler); return; } @@ -1249,8 +1281,16 @@ _mesa_GetSamplerParameteriv(GLuint sampler, GLenum pname, GLint *params) sampObj = _mesa_lookup_samplerobj(ctx, sampler); if (!sampObj) { - _mesa_error(ctx, GL_INVALID_VALUE, "glGetSamplerParameteriv(sampler %u)", - sampler); + /* '3.8.2 Sampler Objects' section of the GL-ES 3.0 specification states: + * + * "An INVALID_OPERATION error is generated if sampler is not the name + * of a sampler object previously returned from a call to GenSamplers." + * + * In desktop GL, an GL_INVALID_VALUE is returned instead. + */ + _mesa_error(ctx, (_mesa_is_gles(ctx) ? + GL_INVALID_OPERATION : GL_INVALID_VALUE), + "glGetSamplerParameteriv(sampler %u)", sampler); return; } @@ -1271,13 +1311,22 @@ _mesa_GetSamplerParameteriv(GLuint sampler, GLenum pname, GLint *params) *params = sampObj->MagFilter; break; case GL_TEXTURE_MIN_LOD: - *params = (GLint) sampObj->MinLod; + /* GL spec 'Data Conversions' section specifies that floating-point + * value in integer Get function is rounded to nearest integer + */ + *params = IROUND(sampObj->MinLod); break; case GL_TEXTURE_MAX_LOD: - *params = (GLint) sampObj->MaxLod; + /* GL spec 'Data Conversions' section specifies that floating-point + * value in integer Get function is rounded to nearest integer + */ + *params = IROUND(sampObj->MaxLod); break; case GL_TEXTURE_LOD_BIAS: - *params = (GLint) sampObj->LodBias; + /* GL spec 'Data Conversions' section specifies that floating-point + * value in integer Get function is rounded to nearest integer + */ + *params = IROUND(sampObj->LodBias); break; case GL_TEXTURE_COMPARE_MODE: if (!ctx->Extensions.ARB_shadow) @@ -1290,7 +1339,10 @@ _mesa_GetSamplerParameteriv(GLuint sampler, GLenum pname, GLint *params) *params = sampObj->CompareFunc; break; case GL_TEXTURE_MAX_ANISOTROPY_EXT: - *params = (GLint) sampObj->MaxAnisotropy; + /* GL spec 'Data Conversions' section specifies that floating-point + * value in integer Get function is rounded to nearest integer + */ + *params = IROUND(sampObj->MaxAnisotropy); break; case GL_TEXTURE_BORDER_COLOR: params[0] = FLOAT_TO_INT(sampObj->BorderColor.f[0]); @@ -1327,8 +1379,16 @@ _mesa_GetSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat *params) sampObj = _mesa_lookup_samplerobj(ctx, sampler); if (!sampObj) { - _mesa_error(ctx, GL_INVALID_VALUE, "glGetSamplerParameterfv(sampler %u)", - sampler); + /* '3.8.2 Sampler Objects' section of the GL-ES 3.0 specification states: + * + * "An INVALID_OPERATION error is generated if sampler is not the name + * of a sampler object previously returned from a call to GenSamplers." + * + * In desktop GL, an GL_INVALID_VALUE is returned instead. + */ + _mesa_error(ctx, (_mesa_is_gles(ctx) ? + GL_INVALID_OPERATION : GL_INVALID_VALUE), + "glGetSamplerParameterfv(sampler %u)", sampler); return; } diff --git a/mesalib/src/mesa/main/samplerobj.h b/mesalib/src/mesa/main/samplerobj.h index 7d80b383d..1bb3193e4 100644 --- a/mesalib/src/mesa/main/samplerobj.h +++ b/mesalib/src/mesa/main/samplerobj.h @@ -27,6 +27,11 @@ #ifndef SAMPLEROBJ_H #define SAMPLEROBJ_H +#ifdef __cplusplus +extern "C" { +#endif + + struct dd_function_table; static inline struct gl_sampler_object * @@ -103,4 +108,8 @@ _mesa_GetSamplerParameterIiv(GLuint sampler, GLenum pname, GLint *params); void GLAPIENTRY _mesa_GetSamplerParameterIuiv(GLuint sampler, GLenum pname, GLuint *params); +#ifdef __cplusplus +} +#endif + #endif /* SAMPLEROBJ_H */ diff --git a/mesalib/src/mesa/main/set.c b/mesalib/src/mesa/main/set.c deleted file mode 100644 index 52c1dabd8..000000000 --- a/mesalib/src/mesa/main/set.c +++ /dev/null @@ -1,346 +0,0 @@ -/* - * Copyright © 2009-2012 Intel Corporation - * Copyright © 1988-2004 Keith Packard and Bart Massey. - * - * 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. - * - * Except as contained in this notice, the names of the authors - * or their institutions shall not be used in advertising or - * otherwise to promote the sale, use or other dealings in this - * Software without prior written authorization from the - * authors. - * - * Authors: - * Eric Anholt - * Keith Packard - */ - -#include - -#include "macros.h" -#include "set.h" -#include "util/ralloc.h" - -/* - * From Knuth -- a good choice for hash/rehash values is p, p-2 where - * p and p-2 are both prime. These tables are sized to have an extra 10% - * free to avoid exponential performance degradation as the hash table fills - */ - -uint32_t deleted_key_value; -const void *deleted_key = &deleted_key_value; - -static const struct { - uint32_t max_entries, size, rehash; -} hash_sizes[] = { - { 2, 5, 3 }, - { 4, 7, 5 }, - { 8, 13, 11 }, - { 16, 19, 17 }, - { 32, 43, 41 }, - { 64, 73, 71 }, - { 128, 151, 149 }, - { 256, 283, 281 }, - { 512, 571, 569 }, - { 1024, 1153, 1151 }, - { 2048, 2269, 2267 }, - { 4096, 4519, 4517 }, - { 8192, 9013, 9011 }, - { 16384, 18043, 18041 }, - { 32768, 36109, 36107 }, - { 65536, 72091, 72089 }, - { 131072, 144409, 144407 }, - { 262144, 288361, 288359 }, - { 524288, 576883, 576881 }, - { 1048576, 1153459, 1153457 }, - { 2097152, 2307163, 2307161 }, - { 4194304, 4613893, 4613891 }, - { 8388608, 9227641, 9227639 }, - { 16777216, 18455029, 18455027 }, - { 33554432, 36911011, 36911009 }, - { 67108864, 73819861, 73819859 }, - { 134217728, 147639589, 147639587 }, - { 268435456, 295279081, 295279079 }, - { 536870912, 590559793, 590559791 }, - { 1073741824, 1181116273, 1181116271 }, - { 2147483648ul, 2362232233ul, 2362232231ul } -}; - -static int -entry_is_free(struct set_entry *entry) -{ - return entry->key == NULL; -} - -static int -entry_is_deleted(struct set_entry *entry) -{ - return entry->key == deleted_key; -} - -static int -entry_is_present(struct set_entry *entry) -{ - return entry->key != NULL && entry->key != deleted_key; -} - -struct set * -_mesa_set_create(void *mem_ctx, - bool (*key_equals_function)(const void *a, - const void *b)) -{ - struct set *ht; - - ht = ralloc(mem_ctx, struct set); - if (ht == NULL) - return NULL; - - ht->size_index = 0; - ht->size = hash_sizes[ht->size_index].size; - ht->rehash = hash_sizes[ht->size_index].rehash; - ht->max_entries = hash_sizes[ht->size_index].max_entries; - ht->key_equals_function = key_equals_function; - ht->table = rzalloc_array(ht, struct set_entry, ht->size); - ht->entries = 0; - ht->deleted_entries = 0; - - if (ht->table == NULL) { - ralloc_free(ht); - return NULL; - } - - return ht; -} - -/** - * Frees the given set. - * - * If delete_function is passed, it gets called on each entry present before - * freeing. - */ -void -_mesa_set_destroy(struct set *ht, void (*delete_function)(struct set_entry *entry)) -{ - if (!ht) - return; - - if (delete_function) { - struct set_entry *entry; - - set_foreach (ht, entry) { - delete_function(entry); - } - } - ralloc_free(ht->table); - ralloc_free(ht); -} - -/** - * Finds a set entry with the given key and hash of that key. - * - * Returns NULL if no entry is found. - */ -struct set_entry * -_mesa_set_search(const struct set *ht, uint32_t hash, const void *key) -{ - uint32_t hash_address; - - hash_address = hash % ht->size; - do { - uint32_t double_hash; - - struct set_entry *entry = ht->table + hash_address; - - if (entry_is_free(entry)) { - return NULL; - } else if (entry_is_present(entry) && entry->hash == hash) { - if (ht->key_equals_function(key, entry->key)) { - return entry; - } - } - - double_hash = 1 + hash % ht->rehash; - - hash_address = (hash_address + double_hash) % ht->size; - } while (hash_address != hash % ht->size); - - return NULL; -} - -static void -set_rehash(struct set *ht, int new_size_index) -{ - struct set old_ht; - struct set_entry *table, *entry; - - if (new_size_index >= ARRAY_SIZE(hash_sizes)) - return; - - table = rzalloc_array(ht, struct set_entry, - hash_sizes[new_size_index].size); - if (table == NULL) - return; - - old_ht = *ht; - - ht->table = table; - ht->size_index = new_size_index; - ht->size = hash_sizes[ht->size_index].size; - ht->rehash = hash_sizes[ht->size_index].rehash; - ht->max_entries = hash_sizes[ht->size_index].max_entries; - ht->entries = 0; - ht->deleted_entries = 0; - - for (entry = old_ht.table; - entry != old_ht.table + old_ht.size; - entry++) { - if (entry_is_present(entry)) { - _mesa_set_add(ht, entry->hash, entry->key); - } - } - - ralloc_free(old_ht.table); -} - -/** - * Inserts the key with the given hash into the table. - * - * Note that insertion may rearrange the table on a resize or rehash, - * so previously found hash_entries are no longer valid after this function. - */ -struct set_entry * -_mesa_set_add(struct set *ht, uint32_t hash, const void *key) -{ - uint32_t hash_address; - - if (ht->entries >= ht->max_entries) { - set_rehash(ht, ht->size_index + 1); - } else if (ht->deleted_entries + ht->entries >= ht->max_entries) { - set_rehash(ht, ht->size_index); - } - - hash_address = hash % ht->size; - do { - struct set_entry *entry = ht->table + hash_address; - uint32_t double_hash; - - if (!entry_is_present(entry)) { - if (entry_is_deleted(entry)) - ht->deleted_entries--; - entry->hash = hash; - entry->key = key; - ht->entries++; - return entry; - } - - /* Implement replacement when another insert happens - * with a matching key. This is a relatively common - * feature of hash tables, with the alternative - * generally being "insert the new value as well, and - * return it first when the key is searched for". - * - * Note that the hash table doesn't have a delete callback. - * If freeing of old keys is required to avoid memory leaks, - * perform a search before inserting. - */ - if (entry->hash == hash && - ht->key_equals_function(key, entry->key)) { - entry->key = key; - return entry; - } - - double_hash = 1 + hash % ht->rehash; - - hash_address = (hash_address + double_hash) % ht->size; - } while (hash_address != hash % ht->size); - - /* We could hit here if a required resize failed. An unchecked-malloc - * application could ignore this result. - */ - return NULL; -} - -/** - * This function deletes the given hash table entry. - * - * Note that deletion doesn't otherwise modify the table, so an iteration over - * the table deleting entries is safe. - */ -void -_mesa_set_remove(struct set *ht, struct set_entry *entry) -{ - if (!entry) - return; - - entry->key = deleted_key; - ht->entries--; - ht->deleted_entries++; -} - -/** - * This function is an iterator over the hash table. - * - * Pass in NULL for the first entry, as in the start of a for loop. Note that - * an iteration over the table is O(table_size) not O(entries). - */ -struct set_entry * -_mesa_set_next_entry(const struct set *ht, struct set_entry *entry) -{ - if (entry == NULL) - entry = ht->table; - else - entry = entry + 1; - - for (; entry != ht->table + ht->size; entry++) { - if (entry_is_present(entry)) { - return entry; - } - } - - return NULL; -} - -struct set_entry * -_mesa_set_random_entry(struct set *ht, - int (*predicate)(struct set_entry *entry)) -{ - struct set_entry *entry; - uint32_t i = rand() % ht->size; - - if (ht->entries == 0) - return NULL; - - for (entry = ht->table + i; entry != ht->table + ht->size; entry++) { - if (entry_is_present(entry) && - (!predicate || predicate(entry))) { - return entry; - } - } - - for (entry = ht->table; entry != ht->table + i; entry++) { - if (entry_is_present(entry) && - (!predicate || predicate(entry))) { - return entry; - } - } - - return NULL; -} - diff --git a/mesalib/src/mesa/main/set.h b/mesalib/src/mesa/main/set.h deleted file mode 100644 index 206d0c4d2..000000000 --- a/mesalib/src/mesa/main/set.h +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright © 2009-2012 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - * - * Authors: - * Eric Anholt - * - */ - -#ifndef _SET_H -#define _SET_H - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -struct set_entry { - uint32_t hash; - const void *key; -}; - -struct set { - void *mem_ctx; - struct set_entry *table; - bool (*key_equals_function)(const void *a, const void *b); - uint32_t size; - uint32_t rehash; - uint32_t max_entries; - uint32_t size_index; - uint32_t entries; - uint32_t deleted_entries; -}; - -struct set * -_mesa_set_create(void *mem_ctx, - bool (*key_equals_function)(const void *a, - const void *b)); -void -_mesa_set_destroy(struct set *set, - void (*delete_function)(struct set_entry *entry)); - -struct set_entry * -_mesa_set_add(struct set *set, uint32_t hash, const void *key); - -struct set_entry * -_mesa_set_search(const struct set *set, uint32_t hash, - const void *key); - -void -_mesa_set_remove(struct set *set, struct set_entry *entry); - -struct set_entry * -_mesa_set_next_entry(const struct set *set, struct set_entry *entry); - -struct set_entry * -_mesa_set_random_entry(struct set *set, - int (*predicate)(struct set_entry *entry)); - -/** - * This foreach function is safe against deletion, but not against - * insertion (which may rehash the set, making entry a dangling - * pointer). - */ -#define set_foreach(set, entry) \ - for (entry = _mesa_set_next_entry(set, NULL); \ - entry != NULL; \ - entry = _mesa_set_next_entry(set, entry)) - -#ifdef __cplusplus -} /* extern C */ -#endif - -#endif /* _SET_H */ diff --git a/mesalib/src/mesa/main/shader_query.cpp b/mesalib/src/mesa/main/shader_query.cpp index 766ad2965..df9081b73 100644 --- a/mesalib/src/mesa/main/shader_query.cpp +++ b/mesalib/src/mesa/main/shader_query.cpp @@ -109,6 +109,11 @@ _mesa_GetActiveAttrib(GLhandleARB program, GLuint desired_index, GET_CURRENT_CONTEXT(ctx); struct gl_shader_program *shProg; + if (maxLength < 0) { + _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveAttrib(maxLength < 0)"); + return; + } + shProg = _mesa_lookup_shader_program_err(ctx, program, "glGetActiveAttrib"); if (!shProg) return; diff --git a/mesalib/src/mesa/main/shaderapi.c b/mesalib/src/mesa/main/shaderapi.c index 66578204f..52eab4655 100644 --- a/mesalib/src/mesa/main/shaderapi.c +++ b/mesalib/src/mesa/main/shaderapi.c @@ -274,9 +274,8 @@ attach_shader(struct gl_context *ctx, GLuint program, GLuint shader) } /* grow list */ - shProg->Shaders = (struct gl_shader **) - realloc(shProg->Shaders, - (n + 1) * sizeof(struct gl_shader *)); + shProg->Shaders = realloc(shProg->Shaders, + (n + 1) * sizeof(struct gl_shader *)); if (!shProg->Shaders) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glAttachShader"); return; @@ -308,7 +307,7 @@ create_shader(struct gl_context *ctx, GLenum type) } -static GLuint +static GLuint create_shader_program(struct gl_context *ctx) { GLuint name; @@ -327,8 +326,9 @@ create_shader_program(struct gl_context *ctx) /** - * Named w/ "2" to indicate OpenGL 2.x vs GL_ARB_fragment_programs's - * DeleteProgramARB. + * Delete a shader program. Actually, just decrement the program's + * reference count and mark it as DeletePending. + * Used to implement glDeleteProgram() and glDeleteObjectARB(). */ static void delete_shader_program(struct gl_context *ctx, GLuint name) @@ -431,9 +431,7 @@ detach_shader(struct gl_context *ctx, GLuint program, GLuint shader) /* not found */ { GLenum err; - if (is_shader(ctx, shader)) - err = GL_INVALID_OPERATION; - else if (is_program(ctx, shader)) + if (is_shader(ctx, shader) || is_program(ctx, shader)) err = GL_INVALID_OPERATION; else err = GL_INVALID_VALUE; @@ -450,8 +448,16 @@ static void get_attached_shaders(struct gl_context *ctx, GLuint program, GLsizei maxCount, GLsizei *count, GLuint *obj) { - struct gl_shader_program *shProg = + struct gl_shader_program *shProg; + + if (maxCount < 0) { + _mesa_error(ctx, GL_INVALID_VALUE, "glGetAttachedShaders(maxCount < 0)"); + return; + } + + shProg = _mesa_lookup_shader_program_err(ctx, program, "glGetAttachedShaders"); + if (shProg) { GLuint i; for (i = 0; i < (GLuint) maxCount && i < shProg->NumShaders; i++) { @@ -513,7 +519,8 @@ check_gs_query(struct gl_context *ctx, const struct gl_shader_program *shProg) * programs (see glGetProgramivARB). */ static void -get_programiv(struct gl_context *ctx, GLuint program, GLenum pname, GLint *params) +get_programiv(struct gl_context *ctx, GLuint program, GLenum pname, + GLint *params) { struct gl_shader_program *shProg = _mesa_lookup_shader_program(ctx, program); @@ -533,7 +540,8 @@ get_programiv(struct gl_context *ctx, GLuint program, GLenum pname, GLint *param /* Are uniform buffer objects available in this context? */ const bool has_ubo = - (ctx->API == API_OPENGL_COMPAT && ctx->Extensions.ARB_uniform_buffer_object) + (ctx->API == API_OPENGL_COMPAT && + ctx->Extensions.ARB_uniform_buffer_object) || ctx->API == API_OPENGL_CORE || _mesa_is_gles3(ctx); @@ -601,7 +609,8 @@ get_programiv(struct gl_context *ctx, GLuint program, GLenum pname, GLint *param for (i = 0; i < shProg->TransformFeedback.NumVarying; i++) { /* Add one for the terminating NUL character. */ - const GLint len = strlen(shProg->TransformFeedback.VaryingNames[i]) + 1; + const GLint len = + strlen(shProg->TransformFeedback.VaryingNames[i]) + 1; if (len > max_len) max_len = len; @@ -755,8 +764,7 @@ static void get_program_info_log(struct gl_context *ctx, GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog) { - struct gl_shader_program *shProg - = _mesa_lookup_shader_program(ctx, program); + struct gl_shader_program *shProg = _mesa_lookup_shader_program(ctx, program); if (!shProg) { _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramInfoLog(program)"); return; @@ -786,6 +794,12 @@ get_shader_source(struct gl_context *ctx, GLuint shader, GLsizei maxLength, GLsizei *length, GLchar *sourceOut) { struct gl_shader *sh; + + if (maxLength < 0) { + _mesa_error(ctx, GL_INVALID_VALUE, "glGetShaderSource(bufSize < 0)"); + return; + } + sh = _mesa_lookup_shader_err(ctx, shader, "glGetShaderSource"); if (!sh) { return; @@ -871,7 +885,6 @@ compile_shader(struct gl_context *ctx, GLuint shaderObj) } fflush(stderr); } - } if (!sh->CompileStatus) { @@ -918,7 +931,7 @@ link_program(struct gl_context *ctx, GLuint program) _mesa_glsl_link_shader(ctx, shProg); - if (shProg->LinkStatus == GL_FALSE && + if (shProg->LinkStatus == GL_FALSE && (ctx->_Shader->Flags & GLSL_REPORT_ERRORS)) { _mesa_debug(ctx, "Error linking program %u:\n%s\n", shProg->Name, shProg->InfoLog); @@ -986,8 +999,7 @@ _mesa_active_program(struct gl_context *ctx, struct gl_shader_program *shProg, } } -/** - */ + static void use_shader_program(struct gl_context *ctx, GLenum type, struct gl_shader_program *shProg, @@ -1034,6 +1046,7 @@ use_shader_program(struct gl_context *ctx, GLenum type, } } + /** * Use the named shader program for subsequent rendering. */ @@ -1071,7 +1084,7 @@ validate_shader_program(const struct gl_shader_program *shProg, any active sampler in the current program object refers to a texture image unit where fixed-function fragment processing accesses a - texture target that does not match the sampler type, or + texture target that does not match the sampler type, or the sum of the number of active samplers in the program and the number of texture image units enabled for fixed-function fragment @@ -1079,7 +1092,6 @@ validate_shader_program(const struct gl_shader_program *shProg, image units allowed. */ - /* * Check: any two active samplers in the current program object are of * different types, but refer to the same texture image unit, @@ -1673,7 +1685,7 @@ _mesa_ShaderBinary(GLint n, const GLuint* shaders, GLenum binaryformat, (void) binaryformat; (void) binary; (void) length; - _mesa_error(ctx, GL_INVALID_OPERATION, __FUNCTION__); + _mesa_error(ctx, GL_INVALID_OPERATION, "glShaderBinary"); } @@ -1682,30 +1694,46 @@ _mesa_GetProgramBinary(GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, GLvoid *binary) { struct gl_shader_program *shProg; + GLsizei length_dummy; GET_CURRENT_CONTEXT(ctx); - shProg = _mesa_lookup_shader_program_err(ctx, program, "glGetProgramBinary"); - if (!shProg) - return; - - if (!shProg->LinkStatus) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "glGetProgramBinary(program %u not linked)", - shProg->Name); - return; - } - if (bufSize < 0){ _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramBinary(bufSize < 0)"); return; } + shProg = _mesa_lookup_shader_program_err(ctx, program, "glGetProgramBinary"); + if (!shProg) + return; + /* The ARB_get_program_binary spec says: * * "If is NULL, then no length is returned." + * + * Ensure that length always points to valid storage to avoid multiple NULL + * pointer checks below. */ if (length != NULL) + length = &length_dummy; + + + /* The ARB_get_program_binary spec says: + * + * "When a program object's LINK_STATUS is FALSE, its program binary + * length is zero, and a call to GetProgramBinary will generate an + * INVALID_OPERATION error. + */ + if (!shProg->LinkStatus) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glGetProgramBinary(program %u not linked)", + shProg->Name); *length = 0; + return; + } + + *length = 0; + _mesa_error(ctx, GL_INVALID_OPERATION, + "glGetProgramBinary(driver supports zero binary formats)"); (void) binaryFormat; (void) binary; @@ -1724,8 +1752,31 @@ _mesa_ProgramBinary(GLuint program, GLenum binaryFormat, (void) binaryFormat; (void) binary; - (void) length; - _mesa_error(ctx, GL_INVALID_OPERATION, __FUNCTION__); + + /* Section 2.3.1 (Errors) of the OpenGL 4.5 spec says: + * + * "If a negative number is provided where an argument of type sizei or + * sizeiptr is specified, an INVALID_VALUE error is generated." + */ + if (length < 0) { + _mesa_error(ctx, GL_INVALID_VALUE, "glProgramBinary(length < 0)"); + return; + } + + /* The ARB_get_program_binary spec says: + * + * " and must be those returned by a previous + * call to GetProgramBinary, and must be the length of the + * program binary as returned by GetProgramBinary or GetProgramiv with + * PROGRAM_BINARY_LENGTH. Loading the program binary will fail, + * setting the LINK_STATUS of to FALSE, if these conditions + * are not met." + * + * Since any value of binaryFormat passed "is not one of those specified as + * allowable for [this] command, an INVALID_ENUM error is generated." + */ + shProg->LinkStatus = GL_FALSE; + _mesa_error(ctx, GL_INVALID_ENUM, "glProgramBinary"); } @@ -1756,12 +1807,7 @@ _mesa_ProgramParameteri(GLuint program, GLenum pname, GLint value) * ProgramParameteri is not TRUE or FALSE." */ if (value != GL_TRUE && value != GL_FALSE) { - _mesa_error(ctx, GL_INVALID_VALUE, - "glProgramParameteri(pname=%s, value=%d): " - "value must be 0 or 1.", - _mesa_lookup_enum_by_nr(pname), - value); - return; + goto invalid_value; } /* No need to notify the driver. Any changes will actually take effect @@ -1792,24 +1838,26 @@ _mesa_ProgramParameteri(GLuint program, GLenum pname, GLint value) * Chapter 7.3 Program Objects */ if (value != GL_TRUE && value != GL_FALSE) { - _mesa_error(ctx, GL_INVALID_VALUE, - "glProgramParameteri(pname=%s, value=%d): " - "value must be 0 or 1.", - _mesa_lookup_enum_by_nr(pname), - value); - return; + goto invalid_value; } shProg->SeparateShader = value; return; default: - break; + _mesa_error(ctx, GL_INVALID_ENUM, "glProgramParameteri(pname=%s)", + _mesa_lookup_enum_by_nr(pname)); + return; } - _mesa_error(ctx, GL_INVALID_ENUM, "glProgramParameteri(pname=%s)", - _mesa_lookup_enum_by_nr(pname)); +invalid_value: + _mesa_error(ctx, GL_INVALID_VALUE, + "glProgramParameteri(pname=%s, value=%d): " + "value must be 0 or 1.", + _mesa_lookup_enum_by_nr(pname), + value); } + void _mesa_use_shader_program(struct gl_context *ctx, GLenum type, struct gl_shader_program *shProg, diff --git a/mesalib/src/mesa/main/shaderobj.c b/mesalib/src/mesa/main/shaderobj.c index 81bd7829d..02ccf450b 100644 --- a/mesalib/src/mesa/main/shaderobj.c +++ b/mesalib/src/mesa/main/shaderobj.c @@ -193,9 +193,9 @@ _mesa_lookup_shader_err(struct gl_context *ctx, GLuint name, const char *caller) * Then set ptr to point to shProg, incrementing its refcount. */ void -_mesa_reference_shader_program(struct gl_context *ctx, - struct gl_shader_program **ptr, - struct gl_shader_program *shProg) +_mesa_reference_shader_program_(struct gl_context *ctx, + struct gl_shader_program **ptr, + struct gl_shader_program *shProg) { assert(ptr); if (*ptr == shProg) { diff --git a/mesalib/src/mesa/main/shaderobj.h b/mesalib/src/mesa/main/shaderobj.h index 05ddfeb50..92f7a33ee 100644 --- a/mesalib/src/mesa/main/shaderobj.h +++ b/mesalib/src/mesa/main/shaderobj.h @@ -62,9 +62,20 @@ _mesa_lookup_shader_err(struct gl_context *ctx, GLuint name, const char *caller) extern void -_mesa_reference_shader_program(struct gl_context *ctx, +_mesa_reference_shader_program_(struct gl_context *ctx, struct gl_shader_program **ptr, struct gl_shader_program *shProg); + +static inline void +_mesa_reference_shader_program(struct gl_context *ctx, + struct gl_shader_program **ptr, + struct gl_shader_program *shProg) +{ + if (*ptr != shProg) + _mesa_reference_shader_program_(ctx, ptr, shProg); +} + + extern void _mesa_init_shader(struct gl_context *ctx, struct gl_shader *shader); diff --git a/mesalib/src/mesa/main/shared.c b/mesalib/src/mesa/main/shared.c index f74a8232f..ccf5355f3 100644 --- a/mesalib/src/mesa/main/shared.c +++ b/mesalib/src/mesa/main/shared.c @@ -36,12 +36,12 @@ #include "program/program.h" #include "dlist.h" #include "samplerobj.h" -#include "set.h" #include "shaderapi.h" #include "shaderobj.h" #include "syncobj.h" #include "util/hash_table.h" +#include "util/set.h" /** * Allocate and initialize a shared context state structure. @@ -119,7 +119,8 @@ _mesa_alloc_shared_state(struct gl_context *ctx) shared->FrameBuffers = _mesa_NewHashTable(); shared->RenderBuffers = _mesa_NewHashTable(); - shared->SyncObjects = _mesa_set_create(NULL, _mesa_key_pointer_equal); + shared->SyncObjects = _mesa_set_create(NULL, _mesa_hash_pointer, + _mesa_key_pointer_equal); return shared; } diff --git a/mesalib/src/mesa/main/simple_list.h b/mesalib/src/mesa/main/simple_list.h deleted file mode 100644 index 903432dce..000000000 --- a/mesalib/src/mesa/main/simple_list.h +++ /dev/null @@ -1,210 +0,0 @@ -/** - * \file simple_list.h - * Simple macros for type-safe, intrusive lists. - * - * Intended to work with a list sentinal which is created as an empty - * list. Insert & delete are O(1). - * - * \author - * (C) 1997, Keith Whitwell - */ - -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2001 Brian Paul 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 - * 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. - */ - - -#ifndef _SIMPLE_LIST_H -#define _SIMPLE_LIST_H - -#ifdef __cplusplus -extern "C" { -#endif - -struct simple_node { - struct simple_node *next; - struct simple_node *prev; -}; - -/** - * Remove an element from list. - * - * \param elem element to remove. - */ -#define remove_from_list(elem) \ -do { \ - (elem)->next->prev = (elem)->prev; \ - (elem)->prev->next = (elem)->next; \ -} while (0) - -/** - * Insert an element to the list head. - * - * \param list list. - * \param elem element to insert. - */ -#define insert_at_head(list, elem) \ -do { \ - (elem)->prev = list; \ - (elem)->next = (list)->next; \ - (list)->next->prev = elem; \ - (list)->next = elem; \ -} while(0) - -/** - * Insert an element to the list tail. - * - * \param list list. - * \param elem element to insert. - */ -#define insert_at_tail(list, elem) \ -do { \ - (elem)->next = list; \ - (elem)->prev = (list)->prev; \ - (list)->prev->next = elem; \ - (list)->prev = elem; \ -} while(0) - -/** - * Move an element to the list head. - * - * \param list list. - * \param elem element to move. - */ -#define move_to_head(list, elem) \ -do { \ - remove_from_list(elem); \ - insert_at_head(list, elem); \ -} while (0) - -/** - * Move an element to the list tail. - * - * \param list list. - * \param elem element to move. - */ -#define move_to_tail(list, elem) \ -do { \ - remove_from_list(elem); \ - insert_at_tail(list, elem); \ -} while (0) - -/** - * Make a empty list empty. - * - * \param sentinal list (sentinal element). - */ -#define make_empty_list(sentinal) \ -do { \ - (sentinal)->next = sentinal; \ - (sentinal)->prev = sentinal; \ -} while (0) - -/** - * Get list first element. - * - * \param list list. - * - * \return pointer to first element. - */ -#define first_elem(list) ((list)->next) - -/** - * Get list last element. - * - * \param list list. - * - * \return pointer to last element. - */ -#define last_elem(list) ((list)->prev) - -/** - * Get next element. - * - * \param elem element. - * - * \return pointer to next element. - */ -#define next_elem(elem) ((elem)->next) - -/** - * Get previous element. - * - * \param elem element. - * - * \return pointer to previous element. - */ -#define prev_elem(elem) ((elem)->prev) - -/** - * Test whether element is at end of the list. - * - * \param list list. - * \param elem element. - * - * \return non-zero if element is at end of list, or zero otherwise. - */ -#define at_end(list, elem) ((elem) == (list)) - -/** - * Test if a list is empty. - * - * \param list list. - * - * \return non-zero if list empty, or zero otherwise. - */ -#define is_empty_list(list) ((list)->next == (list)) - -/** - * Walk through the elements of a list. - * - * \param ptr pointer to the current element. - * \param list list. - * - * \note It should be followed by a { } block or a single statement, as in a \c - * for loop. - */ -#define foreach(ptr, list) \ - for( ptr=(list)->next ; ptr!=list ; ptr=(ptr)->next ) - -/** - * Walk through the elements of a list. - * - * Same as #foreach but lets you unlink the current value during a list - * traversal. Useful for freeing a list, element by element. - * - * \param ptr pointer to the current element. - * \param t temporary pointer. - * \param list list. - * - * \note It should be followed by a { } block or a single statement, as in a \c - * for loop. - */ -#define foreach_s(ptr, t, list) \ - for(ptr=(list)->next,t=(ptr)->next; list != ptr; ptr=t, t=(t)->next) - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/mesalib/src/mesa/main/sse_minmax.c b/mesalib/src/mesa/main/sse_minmax.c index 222ac1454..2e3471625 100644 --- a/mesalib/src/mesa/main/sse_minmax.c +++ b/mesalib/src/mesa/main/sse_minmax.c @@ -25,7 +25,6 @@ * */ -#ifdef __SSE4_1__ #include "main/sse_minmax.h" #include #include @@ -93,5 +92,3 @@ _mesa_uint_array_min_max(const unsigned *ui_indices, unsigned *min_index, *min_index = min_ui; *max_index = max_ui; } - -#endif diff --git a/mesalib/src/mesa/main/stencil.c b/mesalib/src/mesa/main/stencil.c index f65116abe..2a19a17b8 100644 --- a/mesalib/src/mesa/main/stencil.c +++ b/mesalib/src/mesa/main/stencil.c @@ -573,12 +573,24 @@ _mesa_init_stencil(struct gl_context *ctx) ctx->Stencil.Ref[0] = 0; ctx->Stencil.Ref[1] = 0; ctx->Stencil.Ref[2] = 0; - ctx->Stencil.ValueMask[0] = ~0U; - ctx->Stencil.ValueMask[1] = ~0U; - ctx->Stencil.ValueMask[2] = ~0U; - ctx->Stencil.WriteMask[0] = ~0U; - ctx->Stencil.WriteMask[1] = ~0U; - ctx->Stencil.WriteMask[2] = ~0U; + + /* 4.1.4 Stencil Test section of the GL-ES 3.0 specification says: + * + * "In the initial state, [...] the front and back stencil mask are both + * set to the value 2^s − 1, where s is greater than or equal to the + * number of bits in the deepest stencil buffer* supported by the GL + * implementation." + * + * Since the maximum supported precision for stencil buffers is 8 bits, + * mask values should be initialized to 2^8 - 1 = 0xFF. + */ + ctx->Stencil.ValueMask[0] = 0xFF; + ctx->Stencil.ValueMask[1] = 0xFF; + ctx->Stencil.ValueMask[2] = 0xFF; + ctx->Stencil.WriteMask[0] = 0xFF; + ctx->Stencil.WriteMask[1] = 0xFF; + ctx->Stencil.WriteMask[2] = 0xFF; + ctx->Stencil.Clear = 0; ctx->Stencil._BackFace = 1; } diff --git a/mesalib/src/mesa/main/syncobj.c b/mesalib/src/mesa/main/syncobj.c index 9a9c572c5..ac130926a 100644 --- a/mesalib/src/mesa/main/syncobj.c +++ b/mesalib/src/mesa/main/syncobj.c @@ -63,8 +63,8 @@ #include "get.h" #include "dispatch.h" #include "mtypes.h" -#include "set.h" #include "util/hash_table.h" +#include "util/set.h" #include "syncobj.h" @@ -173,9 +173,7 @@ _mesa_validate_sync(struct gl_context *ctx, const struct gl_sync_object *syncObj) { return (syncObj != NULL) - && _mesa_set_search(ctx->Shared->SyncObjects, - _mesa_hash_pointer(syncObj), - syncObj) != NULL + && _mesa_set_search(ctx->Shared->SyncObjects, syncObj) != NULL && (syncObj->Type == GL_SYNC_FENCE) && !syncObj->DeletePending; } @@ -198,9 +196,7 @@ _mesa_unref_sync_object(struct gl_context *ctx, struct gl_sync_object *syncObj) mtx_lock(&ctx->Shared->Mutex); syncObj->RefCount--; if (syncObj->RefCount == 0) { - entry = _mesa_set_search(ctx->Shared->SyncObjects, - _mesa_hash_pointer(syncObj), - syncObj); + entry = _mesa_set_search(ctx->Shared->SyncObjects, syncObj); assert (entry != NULL); _mesa_set_remove(ctx->Shared->SyncObjects, entry); mtx_unlock(&ctx->Shared->Mutex); @@ -289,9 +285,7 @@ _mesa_FenceSync(GLenum condition, GLbitfield flags) ctx->Driver.FenceSync(ctx, syncObj, condition, flags); mtx_lock(&ctx->Shared->Mutex); - _mesa_set_add(ctx->Shared->SyncObjects, - _mesa_hash_pointer(syncObj), - syncObj); + _mesa_set_add(ctx->Shared->SyncObjects, syncObj); mtx_unlock(&ctx->Shared->Mutex); return (GLsync) syncObj; diff --git a/mesalib/src/mesa/main/texcompress_bptc.c b/mesalib/src/mesa/main/texcompress_bptc.c index 9204f123e..c944ac26f 100644 --- a/mesalib/src/mesa/main/texcompress_bptc.c +++ b/mesalib/src/mesa/main/texcompress_bptc.c @@ -1276,7 +1276,6 @@ _mesa_texstore_bptc_rgba_unorm(TEXSTORE_PARAMS) { const GLubyte *pixels; const GLubyte *tempImage = NULL; - GLenum baseFormat; int rowstride; if (srcFormat != GL_RGBA || @@ -1284,15 +1283,19 @@ _mesa_texstore_bptc_rgba_unorm(TEXSTORE_PARAMS) ctx->_ImageTransferState || srcPacking->SwapBytes) { /* convert image to RGBA/ubyte */ - baseFormat = _mesa_get_format_base_format(dstFormat); - tempImage = _mesa_make_temp_ubyte_image(ctx, dims, - baseInternalFormat, - baseFormat, - srcWidth, srcHeight, srcDepth, - srcFormat, srcType, srcAddr, - srcPacking); + GLubyte *tempImageSlices[1]; + int rgbaRowStride = 4 * srcWidth * sizeof(GLubyte); + tempImage = malloc(srcWidth * srcHeight * 4 * sizeof(GLubyte)); if (!tempImage) return GL_FALSE; /* out of memory */ + tempImageSlices[0] = (GLubyte *) tempImage; + _mesa_texstore(ctx, dims, + baseInternalFormat, + MESA_FORMAT_R8G8B8A8_UNORM, + rgbaRowStride, tempImageSlices, + srcWidth, srcHeight, srcDepth, + srcFormat, srcType, srcAddr, + srcPacking); pixels = tempImage; rowstride = srcWidth * 4; @@ -1584,7 +1587,6 @@ texstore_bptc_rgb_float(TEXSTORE_PARAMS, { const float *pixels; const float *tempImage = NULL; - GLenum baseFormat; int rowstride; if (srcFormat != GL_RGB || @@ -1592,16 +1594,19 @@ texstore_bptc_rgb_float(TEXSTORE_PARAMS, ctx->_ImageTransferState || srcPacking->SwapBytes) { /* convert image to RGB/float */ - baseFormat = _mesa_get_format_base_format(dstFormat); - tempImage = _mesa_make_temp_float_image(ctx, dims, - baseInternalFormat, - baseFormat, - srcWidth, srcHeight, srcDepth, - srcFormat, srcType, srcAddr, - srcPacking, - ctx->_ImageTransferState); + GLfloat *tempImageSlices[1]; + int rgbRowStride = 3 * srcWidth * sizeof(GLfloat); + tempImage = malloc(srcWidth * srcHeight * 3 * sizeof(GLfloat)); if (!tempImage) return GL_FALSE; /* out of memory */ + tempImageSlices[0] = (GLfloat *) tempImage; + _mesa_texstore(ctx, dims, + baseInternalFormat, + MESA_FORMAT_RGB_FLOAT32, + rgbRowStride, (GLubyte **)tempImageSlices, + srcWidth, srcHeight, srcDepth, + srcFormat, srcType, srcAddr, + srcPacking); pixels = tempImage; rowstride = srcWidth * sizeof(float) * 3; diff --git a/mesalib/src/mesa/main/texcompress_fxt1.c b/mesalib/src/mesa/main/texcompress_fxt1.c index 61b01c6b4..7b25e1039 100644 --- a/mesalib/src/mesa/main/texcompress_fxt1.c +++ b/mesalib/src/mesa/main/texcompress_fxt1.c @@ -69,14 +69,19 @@ _mesa_texstore_rgb_fxt1(TEXSTORE_PARAMS) srcPacking->RowLength != srcWidth || srcPacking->SwapBytes) { /* convert image to RGB/GLubyte */ - tempImage = _mesa_make_temp_ubyte_image(ctx, dims, - baseInternalFormat, - _mesa_get_format_base_format(dstFormat), - srcWidth, srcHeight, srcDepth, - srcFormat, srcType, srcAddr, - srcPacking); + GLubyte *tempImageSlices[1]; + int rgbRowStride = 3 * srcWidth * sizeof(GLubyte); + tempImage = malloc(srcWidth * srcHeight * 3 * sizeof(GLubyte)); if (!tempImage) return GL_FALSE; /* out of memory */ + tempImageSlices[0] = (GLubyte *) tempImage; + _mesa_texstore(ctx, dims, + baseInternalFormat, + MESA_FORMAT_RGB_UNORM8, + rgbRowStride, tempImageSlices, + srcWidth, srcHeight, srcDepth, + srcFormat, srcType, srcAddr, + srcPacking); pixels = tempImage; srcRowStride = 3 * srcWidth; srcFormat = GL_RGB; @@ -118,14 +123,19 @@ _mesa_texstore_rgba_fxt1(TEXSTORE_PARAMS) ctx->_ImageTransferState || srcPacking->SwapBytes) { /* convert image to RGBA/GLubyte */ - tempImage = _mesa_make_temp_ubyte_image(ctx, dims, - baseInternalFormat, - _mesa_get_format_base_format(dstFormat), - srcWidth, srcHeight, srcDepth, - srcFormat, srcType, srcAddr, - srcPacking); + GLubyte *tempImageSlices[1]; + int rgbaRowStride = 4 * srcWidth * sizeof(GLubyte); + tempImage = malloc(srcWidth * srcHeight * 4 * sizeof(GLubyte)); if (!tempImage) return GL_FALSE; /* out of memory */ + tempImageSlices[0] = (GLubyte *) tempImage; + _mesa_texstore(ctx, dims, + baseInternalFormat, + MESA_FORMAT_R8G8B8A8_UNORM, + rgbaRowStride, tempImageSlices, + srcWidth, srcHeight, srcDepth, + srcFormat, srcType, srcAddr, + srcPacking); pixels = tempImage; srcRowStride = 4 * srcWidth; srcFormat = GL_RGBA; diff --git a/mesalib/src/mesa/main/texcompress_rgtc.c b/mesalib/src/mesa/main/texcompress_rgtc.c index f7ee24d47..e3042011a 100644 --- a/mesalib/src/mesa/main/texcompress_rgtc.c +++ b/mesalib/src/mesa/main/texcompress_rgtc.c @@ -83,18 +83,24 @@ _mesa_texstore_red_rgtc1(TEXSTORE_PARAMS) const GLubyte *srcaddr; GLubyte srcpixels[4][4]; GLubyte *blkaddr; - GLint dstRowDiff; + GLint dstRowDiff, redRowStride; + GLubyte *tempImageSlices[1]; + ASSERT(dstFormat == MESA_FORMAT_R_RGTC1_UNORM || dstFormat == MESA_FORMAT_L_LATC1_UNORM); - tempImage = _mesa_make_temp_ubyte_image(ctx, dims, - baseInternalFormat, - _mesa_get_format_base_format(dstFormat), - srcWidth, srcHeight, srcDepth, - srcFormat, srcType, srcAddr, - srcPacking); + tempImage = malloc(srcWidth * srcHeight * 1 * sizeof(GLubyte)); if (!tempImage) return GL_FALSE; /* out of memory */ + redRowStride = 1 * srcWidth * sizeof(GLubyte); + tempImageSlices[0] = (GLubyte *) tempImage; + _mesa_texstore(ctx, dims, + baseInternalFormat, + MESA_FORMAT_R_UNORM8, + redRowStride, tempImageSlices, + srcWidth, srcHeight, srcDepth, + srcFormat, srcType, srcAddr, + srcPacking); dst = dstSlices[0]; @@ -130,18 +136,24 @@ _mesa_texstore_signed_red_rgtc1(TEXSTORE_PARAMS) const GLfloat *srcaddr; GLbyte srcpixels[4][4]; GLbyte *blkaddr; - GLint dstRowDiff; + GLint dstRowDiff, redRowStride; + GLfloat *tempImageSlices[1]; + ASSERT(dstFormat == MESA_FORMAT_R_RGTC1_SNORM || dstFormat == MESA_FORMAT_L_LATC1_SNORM); - tempImage = _mesa_make_temp_float_image(ctx, dims, - baseInternalFormat, - _mesa_get_format_base_format(dstFormat), - srcWidth, srcHeight, srcDepth, - srcFormat, srcType, srcAddr, - srcPacking, 0x0); + redRowStride = 1 * srcWidth * sizeof(GLfloat); + tempImage = malloc(srcWidth * srcHeight * 1 * sizeof(GLfloat)); if (!tempImage) return GL_FALSE; /* out of memory */ + tempImageSlices[0] = (GLfloat *) tempImage; + _mesa_texstore(ctx, dims, + baseInternalFormat, + MESA_FORMAT_R_FLOAT32, + redRowStride, (GLubyte **)tempImageSlices, + srcWidth, srcHeight, srcDepth, + srcFormat, srcType, srcAddr, + srcPacking); dst = (GLbyte *) dstSlices[0]; @@ -177,19 +189,30 @@ _mesa_texstore_rg_rgtc2(TEXSTORE_PARAMS) const GLubyte *srcaddr; GLubyte srcpixels[4][4]; GLubyte *blkaddr; - GLint dstRowDiff; + GLint dstRowDiff, rgRowStride; + mesa_format tempFormat; + GLubyte *tempImageSlices[1]; ASSERT(dstFormat == MESA_FORMAT_RG_RGTC2_UNORM || dstFormat == MESA_FORMAT_LA_LATC2_UNORM); - tempImage = _mesa_make_temp_ubyte_image(ctx, dims, - baseInternalFormat, - _mesa_get_format_base_format(dstFormat), - srcWidth, srcHeight, srcDepth, - srcFormat, srcType, srcAddr, - srcPacking); + if (baseInternalFormat == GL_RG) + tempFormat = MESA_FORMAT_R8G8_UNORM; + else + tempFormat = MESA_FORMAT_L8A8_UNORM; + + rgRowStride = 2 * srcWidth * sizeof(GLubyte); + tempImage = malloc(srcWidth * srcHeight * 2 * sizeof(GLubyte)); if (!tempImage) return GL_FALSE; /* out of memory */ + tempImageSlices[0] = (GLubyte *) tempImage; + _mesa_texstore(ctx, dims, + baseInternalFormat, + tempFormat, + rgRowStride, tempImageSlices, + srcWidth, srcHeight, srcDepth, + srcFormat, srcType, srcAddr, + srcPacking); dst = dstSlices[0]; @@ -231,19 +254,30 @@ _mesa_texstore_signed_rg_rgtc2(TEXSTORE_PARAMS) const GLfloat *srcaddr; GLbyte srcpixels[4][4]; GLbyte *blkaddr; - GLint dstRowDiff; + GLint dstRowDiff, rgRowStride; + mesa_format tempFormat; + GLfloat *tempImageSlices[1]; ASSERT(dstFormat == MESA_FORMAT_RG_RGTC2_SNORM || dstFormat == MESA_FORMAT_LA_LATC2_SNORM); - tempImage = _mesa_make_temp_float_image(ctx, dims, - baseInternalFormat, - _mesa_get_format_base_format(dstFormat), - srcWidth, srcHeight, srcDepth, - srcFormat, srcType, srcAddr, - srcPacking, 0x0); + if (baseInternalFormat == GL_RG) + tempFormat = MESA_FORMAT_RG_FLOAT32; + else + tempFormat = MESA_FORMAT_LA_FLOAT32; + + rgRowStride = 2 * srcWidth * sizeof(GLfloat); + tempImage = malloc(srcWidth * srcHeight * 2 * sizeof(GLfloat)); if (!tempImage) return GL_FALSE; /* out of memory */ + tempImageSlices[0] = (GLfloat *) tempImage; + _mesa_texstore(ctx, dims, + baseInternalFormat, + tempFormat, + rgRowStride, (GLubyte **)tempImageSlices, + srcWidth, srcHeight, srcDepth, + srcFormat, srcType, srcAddr, + srcPacking); dst = (GLbyte *) dstSlices[0]; diff --git a/mesalib/src/mesa/main/texcompress_s3tc.c b/mesalib/src/mesa/main/texcompress_s3tc.c index 254f84ef7..bfb53dce4 100644 --- a/mesalib/src/mesa/main/texcompress_s3tc.c +++ b/mesalib/src/mesa/main/texcompress_s3tc.c @@ -142,14 +142,19 @@ _mesa_texstore_rgb_dxt1(TEXSTORE_PARAMS) srcPacking->RowLength != srcWidth || srcPacking->SwapBytes) { /* convert image to RGB/GLubyte */ - tempImage = _mesa_make_temp_ubyte_image(ctx, dims, - baseInternalFormat, - _mesa_get_format_base_format(dstFormat), - srcWidth, srcHeight, srcDepth, - srcFormat, srcType, srcAddr, - srcPacking); + GLubyte *tempImageSlices[1]; + int rgbRowStride = 3 * srcWidth * sizeof(GLubyte); + tempImage = malloc(srcWidth * srcHeight * 3 * sizeof(GLubyte)); if (!tempImage) return GL_FALSE; /* out of memory */ + tempImageSlices[0] = (GLubyte *) tempImage; + _mesa_texstore(ctx, dims, + baseInternalFormat, + MESA_FORMAT_RGB_UNORM8, + rgbRowStride, tempImageSlices, + srcWidth, srcHeight, srcDepth, + srcFormat, srcType, srcAddr, + srcPacking); pixels = tempImage; srcFormat = GL_RGB; } @@ -194,14 +199,19 @@ _mesa_texstore_rgba_dxt1(TEXSTORE_PARAMS) srcPacking->RowLength != srcWidth || srcPacking->SwapBytes) { /* convert image to RGBA/GLubyte */ - tempImage = _mesa_make_temp_ubyte_image(ctx, dims, - baseInternalFormat, - _mesa_get_format_base_format(dstFormat), - srcWidth, srcHeight, srcDepth, - srcFormat, srcType, srcAddr, - srcPacking); + GLubyte *tempImageSlices[1]; + int rgbaRowStride = 4 * srcWidth * sizeof(GLubyte); + tempImage = malloc(srcWidth * srcHeight * 4 * sizeof(GLubyte)); if (!tempImage) return GL_FALSE; /* out of memory */ + tempImageSlices[0] = (GLubyte *) tempImage; + _mesa_texstore(ctx, dims, + baseInternalFormat, + MESA_FORMAT_R8G8B8A8_UNORM, + rgbaRowStride, tempImageSlices, + srcWidth, srcHeight, srcDepth, + srcFormat, srcType, srcAddr, + srcPacking); pixels = tempImage; srcFormat = GL_RGBA; } @@ -246,14 +256,19 @@ _mesa_texstore_rgba_dxt3(TEXSTORE_PARAMS) srcPacking->RowLength != srcWidth || srcPacking->SwapBytes) { /* convert image to RGBA/GLubyte */ - tempImage = _mesa_make_temp_ubyte_image(ctx, dims, - baseInternalFormat, - _mesa_get_format_base_format(dstFormat), - srcWidth, srcHeight, srcDepth, - srcFormat, srcType, srcAddr, - srcPacking); + GLubyte *tempImageSlices[1]; + int rgbaRowStride = 4 * srcWidth * sizeof(GLubyte); + tempImage = malloc(srcWidth * srcHeight * 4 * sizeof(GLubyte)); if (!tempImage) return GL_FALSE; /* out of memory */ + tempImageSlices[0] = (GLubyte *) tempImage; + _mesa_texstore(ctx, dims, + baseInternalFormat, + MESA_FORMAT_R8G8B8A8_UNORM, + rgbaRowStride, tempImageSlices, + srcWidth, srcHeight, srcDepth, + srcFormat, srcType, srcAddr, + srcPacking); pixels = tempImage; } else { @@ -297,14 +312,19 @@ _mesa_texstore_rgba_dxt5(TEXSTORE_PARAMS) srcPacking->RowLength != srcWidth || srcPacking->SwapBytes) { /* convert image to RGBA/GLubyte */ - tempImage = _mesa_make_temp_ubyte_image(ctx, dims, - baseInternalFormat, - _mesa_get_format_base_format(dstFormat), - srcWidth, srcHeight, srcDepth, - srcFormat, srcType, srcAddr, - srcPacking); + GLubyte *tempImageSlices[1]; + int rgbaRowStride = 4 * srcWidth * sizeof(GLubyte); + tempImage = malloc(srcWidth * srcHeight * 4 * sizeof(GLubyte)); if (!tempImage) return GL_FALSE; /* out of memory */ + tempImageSlices[0] = (GLubyte *) tempImage; + _mesa_texstore(ctx, dims, + baseInternalFormat, + MESA_FORMAT_R8G8B8A8_UNORM, + rgbaRowStride, tempImageSlices, + srcWidth, srcHeight, srcDepth, + srcFormat, srcType, srcAddr, + srcPacking); pixels = tempImage; } else { diff --git a/mesalib/src/mesa/main/texenvprogram.h b/mesalib/src/mesa/main/texenvprogram.h index 15ab31a50..11439f13b 100644 --- a/mesalib/src/mesa/main/texenvprogram.h +++ b/mesalib/src/mesa/main/texenvprogram.h @@ -27,9 +27,20 @@ #define TEXENVPROGRAM_H +#ifdef __cplusplus +extern "C" { +#endif + + struct gl_context; extern struct gl_shader_program * _mesa_get_fixed_func_fragment_program(struct gl_context *ctx); + +#ifdef __cplusplus +} +#endif + + #endif diff --git a/mesalib/src/mesa/main/texgetimage.c b/mesalib/src/mesa/main/texgetimage.c index cb5f7936c..24df5b6f8 100644 --- a/mesalib/src/mesa/main/texgetimage.c +++ b/mesalib/src/mesa/main/texgetimage.c @@ -44,9 +44,10 @@ #include "texcompress.h" #include "texgetimage.h" #include "teximage.h" +#include "texobj.h" #include "texstore.h" - - +#include "format_utils.h" +#include "pixeltransfer.h" /** * Can the given type represent negative values? @@ -241,13 +242,15 @@ get_tex_rgba_compressed(struct gl_context *ctx, GLuint dimensions, const mesa_format texFormat = _mesa_get_srgb_format_linear(texImage->TexFormat); const GLenum baseFormat = _mesa_get_format_base_format(texFormat); - const GLenum destBaseFormat = _mesa_base_tex_format(ctx, format); - GLenum rebaseFormat = GL_NONE; const GLuint width = texImage->Width; const GLuint height = texImage->Height; const GLuint depth = texImage->Depth; - GLfloat *tempImage, *tempSlice, *srcRow; - GLuint row, slice; + GLfloat *tempImage, *tempSlice; + GLuint slice; + int srcStride, dstStride; + uint32_t dstFormat; + bool needsRebase; + uint8_t rebaseSwizzle[4]; /* Decompress into temp float buffer, then pack into user buffer */ tempImage = malloc(width * height * depth @@ -281,46 +284,39 @@ get_tex_rgba_compressed(struct gl_context *ctx, GLuint dimensions, } } + /* Depending on the base format involved we may need to apply a rebase + * tranaform (for example: if we download to a Luminance format we want + * G=0 and B=0). + */ if (baseFormat == GL_LUMINANCE || - baseFormat == GL_INTENSITY || - baseFormat == GL_LUMINANCE_ALPHA) { - /* If a luminance (or intensity) texture is read back as RGB(A), the - * returned value should be (L,0,0,1), not (L,L,L,1). Set rebaseFormat - * here to get G=B=0. - */ - rebaseFormat = texImage->_BaseFormat; - } - else if ((baseFormat == GL_RGBA || - baseFormat == GL_RGB || - baseFormat == GL_RG) && - (destBaseFormat == GL_LUMINANCE || - destBaseFormat == GL_LUMINANCE_ALPHA || - destBaseFormat == GL_LUMINANCE_INTEGER_EXT || - destBaseFormat == GL_LUMINANCE_ALPHA_INTEGER_EXT)) { - /* If we're reading back an RGB(A) texture as luminance then we need - * to return L=tex(R). Note, that's different from glReadPixels which - * returns L=R+G+B. - */ - rebaseFormat = GL_LUMINANCE_ALPHA; /* this covers GL_LUMINANCE too */ - } - - if (rebaseFormat) { - _mesa_rebase_rgba_float(width * height, (GLfloat (*)[4]) tempImage, - rebaseFormat); + baseFormat == GL_INTENSITY) { + needsRebase = true; + rebaseSwizzle[0] = MESA_FORMAT_SWIZZLE_X; + rebaseSwizzle[1] = MESA_FORMAT_SWIZZLE_ZERO; + rebaseSwizzle[2] = MESA_FORMAT_SWIZZLE_ZERO; + rebaseSwizzle[3] = MESA_FORMAT_SWIZZLE_ONE; + } else if (baseFormat == GL_LUMINANCE_ALPHA) { + needsRebase = true; + rebaseSwizzle[0] = MESA_FORMAT_SWIZZLE_X; + rebaseSwizzle[1] = MESA_FORMAT_SWIZZLE_ZERO; + rebaseSwizzle[2] = MESA_FORMAT_SWIZZLE_ZERO; + rebaseSwizzle[3] = MESA_FORMAT_SWIZZLE_W; + } else { + needsRebase = false; } + srcStride = 4 * width * sizeof(GLfloat); + dstStride = _mesa_image_row_stride(&ctx->Pack, width, format, type); + dstFormat = _mesa_format_from_format_and_type(format, type); tempSlice = tempImage; for (slice = 0; slice < depth; slice++) { - srcRow = tempSlice; - for (row = 0; row < height; row++) { - void *dest = _mesa_image_address(dimensions, &ctx->Pack, pixels, - width, height, format, type, - slice, row, 0); - - _mesa_pack_rgba_span_float(ctx, width, (GLfloat (*)[4]) srcRow, - format, type, dest, &ctx->Pack, transferOps); - srcRow += 4 * width; - } + void *dest = _mesa_image_address(dimensions, &ctx->Pack, pixels, + width, height, format, type, + slice, 0, 0); + _mesa_format_convert(dest, dstFormat, dstStride, + tempSlice, RGBA32_FLOAT, srcStride, + width, height, + needsRebase ? rebaseSwizzle : NULL); tempSlice += 4 * width * height; } @@ -376,145 +372,162 @@ get_tex_rgba_uncompressed(struct gl_context *ctx, GLuint dimensions, const mesa_format texFormat = _mesa_get_srgb_format_linear(texImage->TexFormat); const GLuint width = texImage->Width; - GLenum destBaseFormat = _mesa_base_pack_format(format); - GLenum rebaseFormat = GL_NONE; GLuint height = texImage->Height; GLuint depth = texImage->Depth; - GLuint img, row; - GLfloat (*rgba)[4]; - GLuint (*rgba_uint)[4]; - GLboolean tex_is_integer = _mesa_is_format_integer_color(texImage->TexFormat); - GLboolean tex_is_uint = _mesa_is_format_unsigned(texImage->TexFormat); - GLenum texBaseFormat = _mesa_get_format_base_format(texImage->TexFormat); - - /* Allocate buffer for one row of texels */ - rgba = malloc(4 * width * sizeof(GLfloat)); - rgba_uint = (GLuint (*)[4]) rgba; - if (!rgba) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGetTexImage()"); - return; - } + GLuint img; + GLboolean dst_is_integer = _mesa_is_enum_format_integer(format); + uint32_t dst_format; + int dst_stride; + uint8_t rebaseSwizzle[4]; + bool needsRebase; + void *rgba = NULL; if (texImage->TexObject->Target == GL_TEXTURE_1D_ARRAY) { depth = height; height = 1; } + /* Depending on the base format involved we may need to apply a rebase + * tranaform (for example: if we download to a Luminance format we want + * G=0 and B=0). + */ if (texImage->_BaseFormat == GL_LUMINANCE || - texImage->_BaseFormat == GL_INTENSITY || - texImage->_BaseFormat == GL_LUMINANCE_ALPHA) { - /* If a luminance (or intensity) texture is read back as RGB(A), the - * returned value should be (L,0,0,1), not (L,L,L,1). Set rebaseFormat - * here to get G=B=0. - */ - rebaseFormat = texImage->_BaseFormat; - } - else if ((texImage->_BaseFormat == GL_RGBA || - texImage->_BaseFormat == GL_RGB || - texImage->_BaseFormat == GL_RG) && - (destBaseFormat == GL_LUMINANCE || - destBaseFormat == GL_LUMINANCE_ALPHA || - destBaseFormat == GL_LUMINANCE_INTEGER_EXT || - destBaseFormat == GL_LUMINANCE_ALPHA_INTEGER_EXT)) { - /* If we're reading back an RGB(A) texture as luminance then we need - * to return L=tex(R). Note, that's different from glReadPixels which - * returns L=R+G+B. - */ - rebaseFormat = GL_LUMINANCE_ALPHA; /* this covers GL_LUMINANCE too */ - } - else if (texImage->_BaseFormat != texBaseFormat) { - /* The internal format and the real format differ, so we can't rely - * on the unpack functions setting the correct constant values. - * (e.g. reading back GL_RGB8 which is actually RGBA won't set alpha=1) - */ - switch (texImage->_BaseFormat) { - case GL_RED: - if ((texBaseFormat == GL_RGBA || - texBaseFormat == GL_RGB || - texBaseFormat == GL_RG) && - (destBaseFormat == GL_RGBA || - destBaseFormat == GL_RGB || - destBaseFormat == GL_RG || - destBaseFormat == GL_GREEN)) { - rebaseFormat = texImage->_BaseFormat; - break; - } - /* fall through */ - case GL_RG: - if ((texBaseFormat == GL_RGBA || - texBaseFormat == GL_RGB) && - (destBaseFormat == GL_RGBA || - destBaseFormat == GL_RGB || - destBaseFormat == GL_BLUE)) { - rebaseFormat = texImage->_BaseFormat; - break; - } - /* fall through */ - case GL_RGB: - if (texBaseFormat == GL_RGBA && - (destBaseFormat == GL_RGBA || - destBaseFormat == GL_ALPHA || - destBaseFormat == GL_LUMINANCE_ALPHA)) { - rebaseFormat = texImage->_BaseFormat; - } - break; - - case GL_ALPHA: - if (destBaseFormat != GL_ALPHA) { - rebaseFormat = texImage->_BaseFormat; - } - break; - } - } + texImage->_BaseFormat == GL_INTENSITY) { + needsRebase = true; + rebaseSwizzle[0] = MESA_FORMAT_SWIZZLE_X; + rebaseSwizzle[1] = MESA_FORMAT_SWIZZLE_ZERO; + rebaseSwizzle[2] = MESA_FORMAT_SWIZZLE_ZERO; + rebaseSwizzle[3] = MESA_FORMAT_SWIZZLE_ONE; + } else if (texImage->_BaseFormat == GL_LUMINANCE_ALPHA) { + needsRebase = true; + rebaseSwizzle[0] = MESA_FORMAT_SWIZZLE_X; + rebaseSwizzle[1] = MESA_FORMAT_SWIZZLE_ZERO; + rebaseSwizzle[2] = MESA_FORMAT_SWIZZLE_ZERO; + rebaseSwizzle[3] = MESA_FORMAT_SWIZZLE_W; + } else if (texImage->_BaseFormat != _mesa_get_format_base_format(texFormat)) { + needsRebase = + _mesa_compute_rgba2base2rgba_component_mapping(texImage->_BaseFormat, + rebaseSwizzle); + } else { + needsRebase = false; + } + + /* Describe the dst format */ + dst_is_integer = _mesa_is_enum_format_integer(format); + dst_format = _mesa_format_from_format_and_type(format, type); + dst_stride = _mesa_image_row_stride(&ctx->Pack, width, format, type); + + /* Since _mesa_format_convert does not handle transferOps we need to handle + * them before we call the function. This requires to convert to RGBA float + * first so we can call _mesa_apply_rgba_transfer_ops. If the dst format is + * integer then transferOps do not apply. + */ + assert(!transferOps || (transferOps && !dst_is_integer)); for (img = 0; img < depth; img++) { GLubyte *srcMap; GLint rowstride; + GLubyte *img_src; + void *dest; + void *src; + int src_stride; + uint32_t src_format; /* map src texture buffer */ ctx->Driver.MapTextureImage(ctx, texImage, img, 0, 0, width, height, GL_MAP_READ_BIT, &srcMap, &rowstride); - if (srcMap) { - for (row = 0; row < height; row++) { - const GLubyte *src = srcMap + row * rowstride; - void *dest = _mesa_image_address(dimensions, &ctx->Pack, pixels, - width, height, format, type, - img, row, 0); + if (!srcMap) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGetTexImage"); + goto done; + } - if (tex_is_integer) { - _mesa_unpack_uint_rgba_row(texFormat, width, src, rgba_uint); - if (rebaseFormat) - _mesa_rebase_rgba_uint(width, rgba_uint, rebaseFormat); - if (tex_is_uint) { - _mesa_pack_rgba_span_from_uints(ctx, width, - (GLuint (*)[4]) rgba_uint, - format, type, dest); - } else { - _mesa_pack_rgba_span_from_ints(ctx, width, - (GLint (*)[4]) rgba_uint, - format, type, dest); - } - } else { - _mesa_unpack_rgba_row(texFormat, width, src, rgba); - if (rebaseFormat) - _mesa_rebase_rgba_float(width, rgba, rebaseFormat); - _mesa_pack_rgba_span_float(ctx, width, (GLfloat (*)[4]) rgba, - format, type, dest, - &ctx->Pack, transferOps); - } - } - - /* Unmap the src texture buffer */ - ctx->Driver.UnmapTextureImage(ctx, texImage, img); + img_src = srcMap; + dest = _mesa_image_address(dimensions, &ctx->Pack, pixels, + width, height, format, type, + img, 0, 0); + + if (transferOps) { + uint32_t rgba_format; + int rgba_stride; + bool need_convert = false; + + /* We will convert to RGBA float */ + rgba_format = RGBA32_FLOAT; + rgba_stride = width * 4 * sizeof(GLfloat); + + /* If we are lucky and the dst format matches the RGBA format we need + * to convert to, then we can convert directly into the dst buffer + * and avoid the final conversion/copy from the rgba buffer to the dst + * buffer. + */ + if (format == rgba_format) { + rgba = dest; + } else if (rgba == NULL) { /* Allocate the RGBA buffer only once */ + need_convert = true; + rgba = malloc(height * rgba_stride); + if (!rgba) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGetTexImage()"); + ctx->Driver.UnmapTextureImage(ctx, texImage, img); + return; + } + } + + _mesa_format_convert(rgba, rgba_format, rgba_stride, + img_src, texFormat, rowstride, + width, height, + needsRebase ? rebaseSwizzle : NULL); + + /* Handle transfer ops now */ + _mesa_apply_rgba_transfer_ops(ctx, transferOps, width * height, rgba); + + /* If we had to rebase, we have already handled that */ + needsRebase = false; + + /* If we were lucky and our RGBA conversion matches the dst format, then + * we are done. + */ + if (!need_convert) + goto do_swap; + + /* Otherwise, we need to convert from RGBA to dst next */ + src = rgba; + src_format = rgba_format; + src_stride = rgba_stride; + } else { + /* No RGBA conversion needed, convert directly to dst */ + src = img_src; + src_format = texFormat; + src_stride = rowstride; } - else { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGetTexImage"); - break; + + /* Do the conversion to destination format */ + _mesa_format_convert(dest, dst_format, dst_stride, + src, src_format, src_stride, + width, height, + needsRebase ? rebaseSwizzle : NULL); + + do_swap: + /* Handle byte swapping if required */ + if (ctx->Pack.SwapBytes) { + GLint swapSize = _mesa_sizeof_packed_type(type); + if (swapSize == 2 || swapSize == 4) { + int swapsPerPixel = _mesa_bytes_per_pixel(format, type) / swapSize; + assert(_mesa_bytes_per_pixel(format, type) % swapSize == 0); + if (swapSize == 2) + _mesa_swap2((GLushort *) dest, width * height * swapsPerPixel); + else if (swapSize == 4) + _mesa_swap4((GLuint *) dest, width * height * swapsPerPixel); + } } + + /* Unmap the src texture buffer */ + ctx->Driver.UnmapTextureImage(ctx, texImage, img); } - free(rgba); +done: + if (rgba) + free(rgba); } @@ -585,7 +598,7 @@ get_tex_memcpy(struct gl_context *ctx, GLenum format, GLenum type, if (memCopy) { const GLuint bpp = _mesa_get_format_bytes(texImage->TexFormat); - const GLuint bytesPerRow = texImage->Width * bpp; + const GLint bytesPerRow = texImage->Width * bpp; GLubyte *dst = _mesa_image_address2d(&ctx->Pack, pixels, texImage->Width, texImage->Height, format, type, 0, 0); @@ -631,9 +644,9 @@ get_tex_memcpy(struct gl_context *ctx, GLenum format, GLenum type, * unmap with ctx->Driver.UnmapTextureImage(). */ void -_mesa_get_teximage(struct gl_context *ctx, - GLenum format, GLenum type, GLvoid *pixels, - struct gl_texture_image *texImage) +_mesa_GetTexImage_sw(struct gl_context *ctx, + GLenum format, GLenum type, GLvoid *pixels, + struct gl_texture_image *texImage) { const GLuint dimensions = _mesa_get_texture_dimensions(texImage->TexObject->Target); @@ -689,14 +702,14 @@ _mesa_get_teximage(struct gl_context *ctx, * All error checking will have been done before this routine is called. */ void -_mesa_get_compressed_teximage(struct gl_context *ctx, - struct gl_texture_image *texImage, - GLvoid *img) +_mesa_GetCompressedTexImage_sw(struct gl_context *ctx, + struct gl_texture_image *texImage, + GLvoid *img) { const GLuint dimensions = _mesa_get_texture_dimensions(texImage->TexObject->Target); struct compressed_pixelstore store; - GLuint i, slice; + GLint slice; GLubyte *dest; _mesa_compute_compressed_pixelstore(dimensions, texImage->TexFormat, @@ -729,19 +742,19 @@ _mesa_get_compressed_teximage(struct gl_context *ctx, GLubyte *src; /* map src texture buffer */ - ctx->Driver.MapTextureImage(ctx, texImage, 0, + ctx->Driver.MapTextureImage(ctx, texImage, slice, 0, 0, texImage->Width, texImage->Height, GL_MAP_READ_BIT, &src, &srcRowStride); if (src) { - + GLint i; for (i = 0; i < store.CopyRowsPerSlice; i++) { memcpy(dest, src, store.CopyBytesPerRow); dest += store.TotalBytesPerRow; src += srcRowStride; } - ctx->Driver.UnmapTextureImage(ctx, texImage, 0); + ctx->Driver.UnmapTextureImage(ctx, texImage, slice); /* Advance to next slice */ dest += store.TotalBytesPerRow * (store.TotalRowsPerSlice - store.CopyRowsPerSlice); @@ -758,24 +771,17 @@ _mesa_get_compressed_teximage(struct gl_context *ctx, /** - * Validate the texture target enum supplied to glTexImage or - * glCompressedTexImage. + * Validate the texture target enum supplied to glGetTex(ture)Image or + * glGetCompressedTex(ture)Image. */ static GLboolean -legal_getteximage_target(struct gl_context *ctx, GLenum target) +legal_getteximage_target(struct gl_context *ctx, GLenum target, bool dsa) { switch (target) { case GL_TEXTURE_1D: case GL_TEXTURE_2D: case GL_TEXTURE_3D: return GL_TRUE; - case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB: - case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB: - case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB: - case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB: - case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB: - case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB: - return ctx->Extensions.ARB_texture_cube_map; case GL_TEXTURE_RECTANGLE_NV: return ctx->Extensions.NV_texture_rectangle; case GL_TEXTURE_1D_ARRAY_EXT: @@ -783,6 +789,24 @@ legal_getteximage_target(struct gl_context *ctx, GLenum target) return ctx->Extensions.EXT_texture_array; case GL_TEXTURE_CUBE_MAP_ARRAY: return ctx->Extensions.ARB_texture_cube_map_array; + + /* Section 8.11 (Texture Queries) of the OpenGL 4.5 core profile spec + * (30.10.2014) says: + * "An INVALID_ENUM error is generated if the effective target is not + * one of TEXTURE_1D, TEXTURE_2D, TEXTURE_3D, TEXTURE_1D_ARRAY, + * TEXTURE_2D_ARRAY, TEXTURE_CUBE_MAP_ARRAY, TEXTURE_RECTANGLE, one of + * the targets from table 8.19 (for GetTexImage and GetnTexImage *only*), + * or TEXTURE_CUBE_MAP (for GetTextureImage *only*)." (Emphasis added.) + */ + case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB: + case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB: + case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB: + return dsa ? GL_FALSE : ctx->Extensions.ARB_texture_cube_map; + case GL_TEXTURE_CUBE_MAP: + return dsa ? GL_TRUE : GL_FALSE; default: return GL_FALSE; } @@ -790,84 +814,74 @@ legal_getteximage_target(struct gl_context *ctx, GLenum target) /** - * Do error checking for a glGetTexImage() call. + * Do error checking for a glGetTex(ture)Image() call. * \return GL_TRUE if any error, GL_FALSE if no errors. */ static GLboolean -getteximage_error_check(struct gl_context *ctx, GLenum target, GLint level, +getteximage_error_check(struct gl_context *ctx, + struct gl_texture_image *texImage, + GLenum target, GLint level, GLenum format, GLenum type, GLsizei clientMemSize, - GLvoid *pixels ) + GLvoid *pixels, bool dsa) { - struct gl_texture_object *texObj; - struct gl_texture_image *texImage; const GLint maxLevels = _mesa_max_texture_levels(ctx, target); const GLuint dimensions = (target == GL_TEXTURE_3D) ? 3 : 2; - GLenum baseFormat, err; - - if (!legal_getteximage_target(ctx, target)) { - _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexImage(target=0x%x)", target); - return GL_TRUE; - } + GLenum baseFormat; + const char *suffix = dsa ? "ture" : ""; + assert(texImage); assert(maxLevels != 0); if (level < 0 || level >= maxLevels) { - _mesa_error( ctx, GL_INVALID_VALUE, "glGetTexImage(level)" ); - return GL_TRUE; - } - - err = _mesa_error_check_format_and_type(ctx, format, type); - if (err != GL_NO_ERROR) { - _mesa_error(ctx, err, "glGetTexImage(format/type)"); - return GL_TRUE; - } - - texObj = _mesa_get_current_tex_object(ctx, target); - - if (!texObj) { - _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexImage(target)"); + _mesa_error(ctx, GL_INVALID_VALUE, + "glGetTex%sImage(level out of range)", suffix); return GL_TRUE; } - texImage = _mesa_select_tex_image(ctx, texObj, target, level); - if (!texImage) { - /* non-existant texture image */ - return GL_TRUE; - } + /* + * Format and type checking has been moved up to GetnTexImage and + * GetTextureImage so that it happens before getting the texImage object. + */ baseFormat = _mesa_get_format_base_format(texImage->TexFormat); - + /* Make sure the requested image format is compatible with the * texture's format. */ if (_mesa_is_color_format(format) && !_mesa_is_color_format(baseFormat)) { - _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(format mismatch)"); + _mesa_error(ctx, GL_INVALID_OPERATION, + "glGetTex%sImage(format mismatch)", suffix); return GL_TRUE; } else if (_mesa_is_depth_format(format) && !_mesa_is_depth_format(baseFormat) && !_mesa_is_depthstencil_format(baseFormat)) { - _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(format mismatch)"); + _mesa_error(ctx, GL_INVALID_OPERATION, + "glGetTex%sImage(format mismatch)", suffix); return GL_TRUE; } else if (_mesa_is_stencil_format(format) && !ctx->Extensions.ARB_texture_stencil8) { - _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexImage(format=GL_STENCIL_INDEX)"); + _mesa_error(ctx, GL_INVALID_ENUM, + "glGetTex%sImage(format=GL_STENCIL_INDEX)", suffix); return GL_TRUE; } else if (_mesa_is_ycbcr_format(format) && !_mesa_is_ycbcr_format(baseFormat)) { - _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(format mismatch)"); + _mesa_error(ctx, GL_INVALID_OPERATION, + "glGetTex%sImage(format mismatch)", suffix); return GL_TRUE; } else if (_mesa_is_depthstencil_format(format) && !_mesa_is_depthstencil_format(baseFormat)) { - _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(format mismatch)"); + _mesa_error(ctx, GL_INVALID_OPERATION, + "glGetTex%sImage(format mismatch)", suffix); return GL_TRUE; } else if (_mesa_is_enum_format_integer(format) != _mesa_is_format_integer(texImage->TexFormat)) { - _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(format mismatch)"); + _mesa_error(ctx, GL_INVALID_OPERATION, + "glGetTex%sImage(format mismatch)", suffix); return GL_TRUE; } @@ -876,11 +890,13 @@ getteximage_error_check(struct gl_context *ctx, GLenum target, GLint level, format, type, clientMemSize, pixels)) { if (_mesa_is_bufferobj(ctx->Pack.BufferObj)) { _mesa_error(ctx, GL_INVALID_OPERATION, - "glGetTexImage(out of bounds PBO access)"); + "glGetTex%sImage(out of bounds PBO access)", suffix); } else { _mesa_error(ctx, GL_INVALID_OPERATION, - "glGetnTexImageARB(out of bounds access:" - " bufSize (%d) is too small)", clientMemSize); + "%s(out of bounds access:" + " bufSize (%d) is too small)", + dsa ? "glGetTextureImage" : "glGetnTexImageARB", + clientMemSize); } return GL_TRUE; } @@ -889,7 +905,7 @@ getteximage_error_check(struct gl_context *ctx, GLenum target, GLint level, /* PBO should not be mapped */ if (_mesa_check_disallowed_mapping(ctx->Pack.BufferObj)) { _mesa_error(ctx, GL_INVALID_OPERATION, - "glGetTexImage(PBO is mapped)"); + "glGetTex%sImage(PBO is mapped)", suffix); return GL_TRUE; } } @@ -898,9 +914,12 @@ getteximage_error_check(struct gl_context *ctx, GLenum target, GLint level, } - /** - * Get texture image. Called by glGetTexImage. + * This is the implementation for glGetnTexImageARB, glGetTextureImage, + * and glGetTexImage. + * + * Requires caller to pass in texImage object because _mesa_GetTextureImage + * must handle the GL_TEXTURE_CUBE_MAP target. * * \param target texture target. * \param level image level. @@ -908,19 +927,29 @@ getteximage_error_check(struct gl_context *ctx, GLenum target, GLint level, * \param type pixel data type for returned image. * \param bufSize size of the pixels data buffer. * \param pixels returned pixel data. + * \param dsa True when the caller is an ARB_direct_state_access function, + * false otherwise */ -void GLAPIENTRY -_mesa_GetnTexImageARB( GLenum target, GLint level, GLenum format, - GLenum type, GLsizei bufSize, GLvoid *pixels ) +void +_mesa_get_texture_image(struct gl_context *ctx, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage, GLenum target, + GLint level, GLenum format, GLenum type, + GLsizei bufSize, GLvoid *pixels, bool dsa) { - struct gl_texture_object *texObj; - struct gl_texture_image *texImage; - GET_CURRENT_CONTEXT(ctx); + assert(texObj); + assert(texImage); FLUSH_VERTICES(ctx, 0); - if (getteximage_error_check(ctx, target, level, format, type, - bufSize, pixels)) { + /* + * Legal target checking has been moved up to GetnTexImage and + * GetTextureImage so that it can be caught before receiving a NULL + * texImage object and exiting. + */ + + if (getteximage_error_check(ctx, texImage, target, level, format, + type, bufSize, pixels, dsa)) { return; } @@ -929,15 +958,13 @@ _mesa_GetnTexImageARB( GLenum target, GLint level, GLenum format, return; } - texObj = _mesa_get_current_tex_object(ctx, target); - texImage = _mesa_select_tex_image(ctx, texObj, target, level); - if (_mesa_is_zero_size_texture(texImage)) return; if (MESA_VERBOSE & (VERBOSE_API | VERBOSE_TEXTURE)) { - _mesa_debug(ctx, "glGetTexImage(tex %u) format = %s, w=%d, h=%d," + _mesa_debug(ctx, "glGetTex%sImage(tex %u) format = %s, w=%d, h=%d," " dstFmt=0x%x, dstType=0x%x\n", + dsa ? "ture": "", texObj->Name, _mesa_get_format_name(texImage->TexFormat), texImage->Width, texImage->Height, @@ -951,6 +978,58 @@ _mesa_GetnTexImageARB( GLenum target, GLint level, GLenum format, _mesa_unlock_texture(ctx, texObj); } +/** + * Get texture image. Called by glGetTexImage. + * + * \param target texture target. + * \param level image level. + * \param format pixel data format for returned image. + * \param type pixel data type for returned image. + * \param bufSize size of the pixels data buffer. + * \param pixels returned pixel data. + */ +void GLAPIENTRY +_mesa_GetnTexImageARB(GLenum target, GLint level, GLenum format, + GLenum type, GLsizei bufSize, GLvoid *pixels) +{ + struct gl_texture_object *texObj; + struct gl_texture_image *texImage; + GLenum err; + GET_CURRENT_CONTEXT(ctx); + + /* + * This has been moved here because a format/type mismatch can cause a NULL + * texImage object, which in turn causes the mismatch error to be + * ignored. + */ + err = _mesa_error_check_format_and_type(ctx, format, type); + if (err != GL_NO_ERROR) { + _mesa_error(ctx, err, "glGetnTexImage(format/type)"); + return; + } + + /* + * Legal target checking has been moved here to prevent exiting with a NULL + * texImage object. + */ + if (!legal_getteximage_target(ctx, target, false)) { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetnTexImage(target=0x%x)", + target); + return; + } + + texObj = _mesa_get_current_tex_object(ctx, target); + if (!texObj) + return; + + texImage = _mesa_select_tex_image(texObj, target, level); + if (!texImage) + return; + + _mesa_get_texture_image(ctx, texObj, texImage, target, level, format, type, + bufSize, pixels, false); +} + void GLAPIENTRY _mesa_GetTexImage( GLenum target, GLint level, GLenum format, @@ -959,51 +1038,162 @@ _mesa_GetTexImage( GLenum target, GLint level, GLenum format, _mesa_GetnTexImageARB(target, level, format, type, INT_MAX, pixels); } +/** + * Get texture image. + * + * \param texture texture name. + * \param level image level. + * \param format pixel data format for returned image. + * \param type pixel data type for returned image. + * \param bufSize size of the pixels data buffer. + * \param pixels returned pixel data. + */ +void GLAPIENTRY +_mesa_GetTextureImage(GLuint texture, GLint level, GLenum format, + GLenum type, GLsizei bufSize, GLvoid *pixels) +{ + struct gl_texture_object *texObj; + struct gl_texture_image *texImage; + int i; + GLint image_stride; + GLenum err; + GET_CURRENT_CONTEXT(ctx); + + /* + * This has been moved here because a format/type mismatch can cause a NULL + * texImage object, which in turn causes the mismatch error to be + * ignored. + */ + err = _mesa_error_check_format_and_type(ctx, format, type); + if (err != GL_NO_ERROR) { + _mesa_error(ctx, err, "glGetTextureImage(format/type)"); + return; + } + + texObj = _mesa_lookup_texture_err(ctx, texture, "glGetTextureImage"); + if (!texObj) + return; + + /* + * Legal target checking has been moved here to prevent exiting with a NULL + * texImage object. + */ + if (!legal_getteximage_target(ctx, texObj->Target, true)) { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetTextureImage(target=%s)", + _mesa_lookup_enum_by_nr(texObj->Target)); + return; + } + + /* Must handle special case GL_TEXTURE_CUBE_MAP. */ + if (texObj->Target == GL_TEXTURE_CUBE_MAP) { + + /* Error checking */ + if (texObj->NumLayers < 6) { + /* Not enough image planes for a cube map. The spec does not say + * what should happen in this case because the user has always + * specified each cube face separately (using + * GL_TEXTURE_CUBE_MAP_POSITIVE_X+i) in previous GL versions. + * This is addressed in Khronos Bug 13223. + */ + _mesa_error(ctx, GL_INVALID_OPERATION, + "glGetTextureImage(insufficient cube map storage)"); + return; + } + + /* + * What do we do if the user created a texture with the following code + * and then called this function with its handle? + * + * GLuint tex; + * glCreateTextures(GL_TEXTURE_CUBE_MAP, 1, &tex); + * glBindTexture(GL_TEXTURE_CUBE_MAP, tex); + * glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, ...); + * glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, ...); + * glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, ...); + * // Note: GL_TEXTURE_CUBE_MAP_NEGATIVE_Y not set, or given the + * // wrong format, or given the wrong size, etc. + * glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, ...); + * glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, ...); + * + * A bug has been filed against the spec for this case. In the + * meantime, we will check for cube completeness. + * + * According to Section 8.17 Texture Completeness in the OpenGL 4.5 + * Core Profile spec (30.10.2014): + * "[A] cube map texture is cube complete if the + * following conditions all hold true: The [base level] texture + * images of each of the six cube map faces have identical, positive, + * and square dimensions. The [base level] images were each specified + * with the same internal format." + * + * It seems reasonable to check for cube completeness of an arbitrary + * level here so that the returned data has a consistent format and size + * and therefore fits in the user's buffer. + */ + if (!_mesa_cube_level_complete(texObj, level)) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glGetTextureImage(cube map incomplete)"); + return; + } + + /* Copy each face. */ + for (i = 0; i < 6; ++i) { + texImage = texObj->Image[i][level]; + _mesa_get_texture_image(ctx, texObj, texImage, texObj->Target, level, + format, type, bufSize, pixels, true); + + image_stride = _mesa_image_image_stride(&ctx->Pack, texImage->Width, + texImage->Height, format, + type); + pixels = (GLubyte *) pixels + image_stride; + bufSize -= image_stride; + } + } + else { + texImage = _mesa_select_tex_image(texObj, texObj->Target, level); + if (!texImage) + return; + + _mesa_get_texture_image(ctx, texObj, texImage, texObj->Target, level, + format, type, bufSize, pixels, true); + } +} /** * Do error checking for a glGetCompressedTexImage() call. * \return GL_TRUE if any error, GL_FALSE if no errors. */ static GLboolean -getcompressedteximage_error_check(struct gl_context *ctx, GLenum target, - GLint level, GLsizei clientMemSize, GLvoid *img) +getcompressedteximage_error_check(struct gl_context *ctx, + struct gl_texture_image *texImage, + GLenum target, + GLint level, GLsizei clientMemSize, + GLvoid *img, bool dsa) { - struct gl_texture_object *texObj; - struct gl_texture_image *texImage; const GLint maxLevels = _mesa_max_texture_levels(ctx, target); GLuint compressedSize, dimensions; + const char *suffix = dsa ? "ture" : ""; - if (!legal_getteximage_target(ctx, target)) { - _mesa_error(ctx, GL_INVALID_ENUM, "glGetCompressedTexImage(target=0x%x)", - target); + assert(texImage); + + if (!legal_getteximage_target(ctx, target, dsa)) { + _mesa_error(ctx, GL_INVALID_ENUM, + "glGetCompressedTex%sImage(target=%s)", suffix, + _mesa_lookup_enum_by_nr(target)); return GL_TRUE; } assert(maxLevels != 0); if (level < 0 || level >= maxLevels) { _mesa_error(ctx, GL_INVALID_VALUE, - "glGetCompressedTexImageARB(bad level = %d)", level); - return GL_TRUE; - } - - texObj = _mesa_get_current_tex_object(ctx, target); - if (!texObj) { - _mesa_error(ctx, GL_INVALID_ENUM, "glGetCompressedTexImageARB(target)"); - return GL_TRUE; - } - - texImage = _mesa_select_tex_image(ctx, texObj, target, level); - - if (!texImage) { - /* probably invalid mipmap level */ - _mesa_error(ctx, GL_INVALID_VALUE, - "glGetCompressedTexImageARB(level)"); + "glGetCompressedTex%sImage(bad level = %d)", suffix, level); return GL_TRUE; } if (!_mesa_is_format_compressed(texImage->TexFormat)) { _mesa_error(ctx, GL_INVALID_OPERATION, - "glGetCompressedTexImageARB(texture is not compressed)"); + "glGetCompressedTex%sImage(texture is not compressed)", + suffix); return GL_TRUE; } @@ -1015,8 +1205,9 @@ getcompressedteximage_error_check(struct gl_context *ctx, GLenum target, /* Check for invalid pixel storage modes */ dimensions = _mesa_get_texture_dimensions(texImage->TexObject->Target); if (!_mesa_compressed_pixel_storage_error_check(ctx, dimensions, - &ctx->Pack, - "glGetCompressedTexImageARB")) { + &ctx->Pack, dsa ? + "glGetCompressedTextureImage": + "glGetCompressedTexImage")) { return GL_TRUE; } @@ -1024,8 +1215,9 @@ getcompressedteximage_error_check(struct gl_context *ctx, GLenum target, /* do bounds checking on writing to client memory */ if (clientMemSize < (GLsizei) compressedSize) { _mesa_error(ctx, GL_INVALID_OPERATION, - "glGetnCompressedTexImageARB(out of bounds access:" - " bufSize (%d) is too small)", clientMemSize); + "%s(out of bounds access: bufSize (%d) is too small)", + dsa ? "glGetCompressedTextureImage" : + "glGetnCompressedTexImageARB", clientMemSize); return GL_TRUE; } } else { @@ -1033,14 +1225,15 @@ getcompressedteximage_error_check(struct gl_context *ctx, GLenum target, if ((const GLubyte *) img + compressedSize > (const GLubyte *) ctx->Pack.BufferObj->Size) { _mesa_error(ctx, GL_INVALID_OPERATION, - "glGetCompressedTexImage(out of bounds PBO access)"); + "glGetCompressedTex%sImage(out of bounds PBO access)", + suffix); return GL_TRUE; } /* make sure PBO is not mapped */ if (_mesa_check_disallowed_mapping(ctx->Pack.BufferObj)) { _mesa_error(ctx, GL_INVALID_OPERATION, - "glGetCompressedTexImage(PBO is mapped)"); + "glGetCompressedTex%sImage(PBO is mapped)", suffix); return GL_TRUE; } } @@ -1048,49 +1241,132 @@ getcompressedteximage_error_check(struct gl_context *ctx, GLenum target, return GL_FALSE; } - -void GLAPIENTRY -_mesa_GetnCompressedTexImageARB(GLenum target, GLint level, GLsizei bufSize, - GLvoid *img) +/** Implements glGetnCompressedTexImageARB, glGetCompressedTexImage, and + * glGetCompressedTextureImage. + * + * texImage must be passed in because glGetCompressedTexImage must handle the + * target GL_TEXTURE_CUBE_MAP. + */ +void +_mesa_get_compressed_texture_image(struct gl_context *ctx, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage, + GLenum target, GLint level, + GLsizei bufSize, GLvoid *pixels, + bool dsa) { - struct gl_texture_object *texObj; - struct gl_texture_image *texImage; - GET_CURRENT_CONTEXT(ctx); + assert(texObj); + assert(texImage); FLUSH_VERTICES(ctx, 0); - if (getcompressedteximage_error_check(ctx, target, level, bufSize, img)) { + if (getcompressedteximage_error_check(ctx, texImage, target, level, + bufSize, pixels, dsa)) { return; } - if (!_mesa_is_bufferobj(ctx->Pack.BufferObj) && !img) { + if (!_mesa_is_bufferobj(ctx->Pack.BufferObj) && !pixels) { /* not an error, do nothing */ return; } - texObj = _mesa_get_current_tex_object(ctx, target); - texImage = _mesa_select_tex_image(ctx, texObj, target, level); - if (_mesa_is_zero_size_texture(texImage)) return; if (MESA_VERBOSE & (VERBOSE_API | VERBOSE_TEXTURE)) { _mesa_debug(ctx, - "glGetCompressedTexImage(tex %u) format = %s, w=%d, h=%d\n", - texObj->Name, + "glGetCompressedTex%sImage(tex %u) format = %s, w=%d, h=%d\n", + dsa ? "ture" : "", texObj->Name, _mesa_get_format_name(texImage->TexFormat), texImage->Width, texImage->Height); } _mesa_lock_texture(ctx, texObj); { - ctx->Driver.GetCompressedTexImage(ctx, texImage, img); + ctx->Driver.GetCompressedTexImage(ctx, texImage, pixels); } _mesa_unlock_texture(ctx, texObj); } +void GLAPIENTRY +_mesa_GetnCompressedTexImageARB(GLenum target, GLint level, GLsizei bufSize, + GLvoid *img) +{ + struct gl_texture_object *texObj; + struct gl_texture_image *texImage; + GET_CURRENT_CONTEXT(ctx); + + texObj = _mesa_get_current_tex_object(ctx, target); + if (!texObj) + return; + + texImage = _mesa_select_tex_image(texObj, target, level); + if (!texImage) + return; + + _mesa_get_compressed_texture_image(ctx, texObj, texImage, target, level, + bufSize, img, false); +} + void GLAPIENTRY _mesa_GetCompressedTexImage(GLenum target, GLint level, GLvoid *img) { _mesa_GetnCompressedTexImageARB(target, level, INT_MAX, img); } + +/** + * Get compressed texture image. + * + * \param texture texture name. + * \param level image level. + * \param bufSize size of the pixels data buffer. + * \param pixels returned pixel data. + */ +void GLAPIENTRY +_mesa_GetCompressedTextureImage(GLuint texture, GLint level, + GLsizei bufSize, GLvoid *pixels) +{ + struct gl_texture_object *texObj; + struct gl_texture_image *texImage; + int i; + GLint image_stride; + GET_CURRENT_CONTEXT(ctx); + + texObj = _mesa_lookup_texture_err(ctx, texture, + "glGetCompressedTextureImage"); + if (!texObj) + return; + + /* Must handle special case GL_TEXTURE_CUBE_MAP. */ + if (texObj->Target == GL_TEXTURE_CUBE_MAP) { + assert(texObj->NumLayers >= 6); + + /* Copy each face. */ + for (i = 0; i < 6; ++i) { + texImage = texObj->Image[i][level]; + if (!texImage) + return; + + _mesa_get_compressed_texture_image(ctx, texObj, texImage, + texObj->Target, level, + bufSize, pixels, true); + + /* Compressed images don't have a client format */ + image_stride = _mesa_format_image_size(texImage->TexFormat, + texImage->Width, + texImage->Height, 1); + + pixels = (GLubyte *) pixels + image_stride; + bufSize -= image_stride; + } + } + else { + texImage = _mesa_select_tex_image(texObj, texObj->Target, level); + if (!texImage) + return; + + _mesa_get_compressed_texture_image(ctx, texObj, texImage, + texObj->Target, level, bufSize, + pixels, true); + } +} diff --git a/mesalib/src/mesa/main/texgetimage.h b/mesalib/src/mesa/main/texgetimage.h index a292fabc0..1fa2f59dc 100644 --- a/mesalib/src/mesa/main/texgetimage.h +++ b/mesalib/src/mesa/main/texgetimage.h @@ -37,16 +37,30 @@ extern GLenum _mesa_base_pack_format(GLenum format); extern void -_mesa_get_teximage(struct gl_context *ctx, - GLenum format, GLenum type, GLvoid *pixels, - struct gl_texture_image *texImage); +_mesa_GetTexImage_sw(struct gl_context *ctx, + GLenum format, GLenum type, GLvoid *pixels, + struct gl_texture_image *texImage); extern void -_mesa_get_compressed_teximage(struct gl_context *ctx, - struct gl_texture_image *texImage, - GLvoid *data); +_mesa_GetCompressedTexImage_sw(struct gl_context *ctx, + struct gl_texture_image *texImage, + GLvoid *data); +extern void +_mesa_get_texture_image(struct gl_context *ctx, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage, GLenum target, + GLint level, GLenum format, GLenum type, + GLsizei bufSize, GLvoid *pixels, bool dsa); + +extern void +_mesa_get_compressed_texture_image( struct gl_context *ctx, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage, + GLenum target, GLint level, + GLsizei bufSize, GLvoid *pixels, + bool dsa ); extern void GLAPIENTRY @@ -55,6 +69,9 @@ _mesa_GetTexImage( GLenum target, GLint level, extern void GLAPIENTRY _mesa_GetnTexImageARB( GLenum target, GLint level, GLenum format, GLenum type, GLsizei bufSize, GLvoid *pixels ); +extern void GLAPIENTRY +_mesa_GetTextureImage(GLuint texture, GLint level, GLenum format, + GLenum type, GLsizei bufSize, GLvoid *pixels); extern void GLAPIENTRY _mesa_GetCompressedTexImage(GLenum target, GLint lod, GLvoid *img); @@ -63,4 +80,8 @@ extern void GLAPIENTRY _mesa_GetnCompressedTexImageARB(GLenum target, GLint level, GLsizei bufSize, GLvoid *img); +extern void GLAPIENTRY +_mesa_GetCompressedTextureImage(GLuint texture, GLint level, GLsizei bufSize, + GLvoid *pixels); + #endif /* TEXGETIMAGE_H */ diff --git a/mesalib/src/mesa/main/teximage.c b/mesalib/src/mesa/main/teximage.c index 4f4bb11dd..29c325bf2 100644 --- a/mesalib/src/mesa/main/teximage.c +++ b/mesalib/src/mesa/main/teximage.c @@ -62,7 +62,58 @@ */ #define NEW_COPY_TEX_STATE (_NEW_BUFFERS | _NEW_PIXEL) +/** + * Returns a corresponding internal floating point format for a given base + * format as specifed by OES_texture_float. In case of GL_FLOAT, the internal + * format needs to be a 32 bit component and in case of GL_HALF_FLOAT_OES it + * needs to be a 16 bit component. + * + * For example, given base format GL_RGBA, type GL_Float return GL_RGBA32F_ARB. + */ +static GLenum +adjust_for_oes_float_texture(GLenum format, GLenum type) +{ + switch (type) { + case GL_FLOAT: + switch (format) { + case GL_RGBA: + return GL_RGBA32F; + case GL_RGB: + return GL_RGB32F; + case GL_ALPHA: + return GL_ALPHA32F_ARB; + case GL_LUMINANCE: + return GL_LUMINANCE32F_ARB; + case GL_LUMINANCE_ALPHA: + return GL_LUMINANCE_ALPHA32F_ARB; + default: + break; + } + break; + + case GL_HALF_FLOAT_OES: + switch (format) { + case GL_RGBA: + return GL_RGBA16F; + case GL_RGB: + return GL_RGB16F; + case GL_ALPHA: + return GL_ALPHA16F_ARB; + case GL_LUMINANCE: + return GL_LUMINANCE16F_ARB; + case GL_LUMINANCE_ALPHA: + return GL_LUMINANCE_ALPHA16F_ARB; + default: + break; + } + break; + default: + break; + } + + return format; +} /** * Return the simple base format for a given internal texture format. @@ -81,92 +132,102 @@ GLint _mesa_base_tex_format( struct gl_context *ctx, GLint internalFormat ) { switch (internalFormat) { - case GL_ALPHA: - case GL_ALPHA4: - case GL_ALPHA8: - case GL_ALPHA12: - case GL_ALPHA16: - return (ctx->API != API_OPENGL_CORE) ? GL_ALPHA : -1; - case 1: - case GL_LUMINANCE: - case GL_LUMINANCE4: - case GL_LUMINANCE8: - case GL_LUMINANCE12: - case GL_LUMINANCE16: - return (ctx->API != API_OPENGL_CORE) ? GL_LUMINANCE : -1; - case 2: - case GL_LUMINANCE_ALPHA: - case GL_LUMINANCE4_ALPHA4: - case GL_LUMINANCE6_ALPHA2: - case GL_LUMINANCE8_ALPHA8: - case GL_LUMINANCE12_ALPHA4: - case GL_LUMINANCE12_ALPHA12: - case GL_LUMINANCE16_ALPHA16: - return (ctx->API != API_OPENGL_CORE) ? GL_LUMINANCE_ALPHA : -1; - case GL_INTENSITY: - case GL_INTENSITY4: - case GL_INTENSITY8: - case GL_INTENSITY12: - case GL_INTENSITY16: - return (ctx->API != API_OPENGL_CORE) ? GL_INTENSITY : -1; - case 3: - return (ctx->API != API_OPENGL_CORE) ? GL_RGB : -1; - case GL_RGB: - case GL_R3_G3_B2: - case GL_RGB4: - case GL_RGB5: - case GL_RGB8: - case GL_RGB10: - case GL_RGB12: - case GL_RGB16: - return GL_RGB; - case 4: - return (ctx->API != API_OPENGL_CORE) ? GL_RGBA : -1; - case GL_RGBA: - case GL_RGBA2: - case GL_RGBA4: - case GL_RGB5_A1: - case GL_RGBA8: - case GL_RGB10_A2: - case GL_RGBA12: - case GL_RGBA16: - return GL_RGBA; - default: - ; /* fallthrough */ + case GL_ALPHA: + case GL_ALPHA4: + case GL_ALPHA8: + case GL_ALPHA12: + case GL_ALPHA16: + return (ctx->API != API_OPENGL_CORE) ? GL_ALPHA : -1; + case 1: + case GL_LUMINANCE: + case GL_LUMINANCE4: + case GL_LUMINANCE8: + case GL_LUMINANCE12: + case GL_LUMINANCE16: + return (ctx->API != API_OPENGL_CORE) ? GL_LUMINANCE : -1; + case 2: + case GL_LUMINANCE_ALPHA: + case GL_LUMINANCE4_ALPHA4: + case GL_LUMINANCE6_ALPHA2: + case GL_LUMINANCE8_ALPHA8: + case GL_LUMINANCE12_ALPHA4: + case GL_LUMINANCE12_ALPHA12: + case GL_LUMINANCE16_ALPHA16: + return (ctx->API != API_OPENGL_CORE) ? GL_LUMINANCE_ALPHA : -1; + case GL_INTENSITY: + case GL_INTENSITY4: + case GL_INTENSITY8: + case GL_INTENSITY12: + case GL_INTENSITY16: + return (ctx->API != API_OPENGL_CORE) ? GL_INTENSITY : -1; + case 3: + return (ctx->API != API_OPENGL_CORE) ? GL_RGB : -1; + case GL_RGB: + case GL_R3_G3_B2: + case GL_RGB4: + case GL_RGB5: + case GL_RGB8: + case GL_RGB10: + case GL_RGB12: + case GL_RGB16: + return GL_RGB; + case 4: + return (ctx->API != API_OPENGL_CORE) ? GL_RGBA : -1; + case GL_RGBA: + case GL_RGBA2: + case GL_RGBA4: + case GL_RGB5_A1: + case GL_RGBA8: + case GL_RGB10_A2: + case GL_RGBA12: + case GL_RGBA16: + return GL_RGBA; + default: + ; /* fallthrough */ } /* GL_BGRA can be an internal format *only* in OpenGL ES (1.x or 2.0). */ if (_mesa_is_gles(ctx)) { switch (internalFormat) { - case GL_BGRA: - return GL_RGBA; - default: - ; /* fallthrough */ + case GL_BGRA: + return GL_RGBA; + default: + ; /* fallthrough */ } } if (ctx->Extensions.ARB_ES2_compatibility) { switch (internalFormat) { - case GL_RGB565: - return GL_RGB; - default: - ; /* fallthrough */ + case GL_RGB565: + return GL_RGB; + default: + ; /* fallthrough */ } } if (ctx->Extensions.ARB_depth_texture) { switch (internalFormat) { - case GL_DEPTH_COMPONENT: - case GL_DEPTH_COMPONENT16: - case GL_DEPTH_COMPONENT24: - case GL_DEPTH_COMPONENT32: - return GL_DEPTH_COMPONENT; - case GL_DEPTH_STENCIL: - case GL_DEPTH24_STENCIL8: - return GL_DEPTH_STENCIL; - default: - ; /* fallthrough */ + case GL_DEPTH_COMPONENT: + case GL_DEPTH_COMPONENT16: + case GL_DEPTH_COMPONENT24: + case GL_DEPTH_COMPONENT32: + return GL_DEPTH_COMPONENT; + case GL_DEPTH_STENCIL: + case GL_DEPTH24_STENCIL8: + return GL_DEPTH_STENCIL; + default: + ; /* fallthrough */ + } + } + + if (ctx->Extensions.ARB_stencil_texturing) { + switch (internalFormat) { + case GL_STENCIL_INDEX: + case GL_STENCIL_INDEX8: + return GL_STENCIL_INDEX; + default: + ; /* fallthrough */ } } @@ -189,12 +250,12 @@ _mesa_base_tex_format( struct gl_context *ctx, GLint internalFormat ) if (ctx->Extensions.TDFX_texture_compression_FXT1) { switch (internalFormat) { - case GL_COMPRESSED_RGB_FXT1_3DFX: - return GL_RGB; - case GL_COMPRESSED_RGBA_FXT1_3DFX: - return GL_RGBA; - default: - ; /* fallthrough */ + case GL_COMPRESSED_RGB_FXT1_3DFX: + return GL_RGB; + case GL_COMPRESSED_RGBA_FXT1_3DFX: + return GL_RGBA; + default: + ; /* fallthrough */ } } @@ -202,28 +263,28 @@ _mesa_base_tex_format( struct gl_context *ctx, GLint internalFormat ) */ if (ctx->Extensions.ANGLE_texture_compression_dxt) { switch (internalFormat) { - case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: - return GL_RGB; - case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: - case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: - case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: - return GL_RGBA; - default: - ; /* fallthrough */ + case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: + return GL_RGB; + case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: + case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: + case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: + return GL_RGBA; + default: + ; /* fallthrough */ } } if (_mesa_is_desktop_gl(ctx) && ctx->Extensions.ANGLE_texture_compression_dxt) { switch (internalFormat) { - case GL_RGB_S3TC: - case GL_RGB4_S3TC: - return GL_RGB; - case GL_RGBA_S3TC: - case GL_RGBA4_S3TC: - return GL_RGBA; - default: - ; /* fallthrough */ + case GL_RGB_S3TC: + case GL_RGB4_S3TC: + return GL_RGB; + case GL_RGBA_S3TC: + case GL_RGBA4_S3TC: + return GL_RGBA; + default: + ; /* fallthrough */ } } @@ -234,65 +295,65 @@ _mesa_base_tex_format( struct gl_context *ctx, GLint internalFormat ) if (ctx->Extensions.ARB_texture_float) { switch (internalFormat) { - case GL_ALPHA16F_ARB: - case GL_ALPHA32F_ARB: - return GL_ALPHA; - case GL_RGBA16F_ARB: - case GL_RGBA32F_ARB: - return GL_RGBA; - case GL_RGB16F_ARB: - case GL_RGB32F_ARB: - return GL_RGB; - case GL_INTENSITY16F_ARB: - case GL_INTENSITY32F_ARB: - return GL_INTENSITY; - case GL_LUMINANCE16F_ARB: - case GL_LUMINANCE32F_ARB: - return GL_LUMINANCE; - case GL_LUMINANCE_ALPHA16F_ARB: - case GL_LUMINANCE_ALPHA32F_ARB: - return GL_LUMINANCE_ALPHA; - default: - ; /* fallthrough */ + case GL_ALPHA16F_ARB: + case GL_ALPHA32F_ARB: + return GL_ALPHA; + case GL_RGBA16F_ARB: + case GL_RGBA32F_ARB: + return GL_RGBA; + case GL_RGB16F_ARB: + case GL_RGB32F_ARB: + return GL_RGB; + case GL_INTENSITY16F_ARB: + case GL_INTENSITY32F_ARB: + return GL_INTENSITY; + case GL_LUMINANCE16F_ARB: + case GL_LUMINANCE32F_ARB: + return GL_LUMINANCE; + case GL_LUMINANCE_ALPHA16F_ARB: + case GL_LUMINANCE_ALPHA32F_ARB: + return GL_LUMINANCE_ALPHA; + default: + ; /* fallthrough */ } } if (ctx->Extensions.EXT_texture_snorm) { switch (internalFormat) { - case GL_RED_SNORM: - case GL_R8_SNORM: - case GL_R16_SNORM: - return GL_RED; - case GL_RG_SNORM: - case GL_RG8_SNORM: - case GL_RG16_SNORM: - return GL_RG; - case GL_RGB_SNORM: - case GL_RGB8_SNORM: - case GL_RGB16_SNORM: - return GL_RGB; - case GL_RGBA_SNORM: - case GL_RGBA8_SNORM: - case GL_RGBA16_SNORM: - return GL_RGBA; - case GL_ALPHA_SNORM: - case GL_ALPHA8_SNORM: - case GL_ALPHA16_SNORM: - return GL_ALPHA; - case GL_LUMINANCE_SNORM: - case GL_LUMINANCE8_SNORM: - case GL_LUMINANCE16_SNORM: - return GL_LUMINANCE; - case GL_LUMINANCE_ALPHA_SNORM: - case GL_LUMINANCE8_ALPHA8_SNORM: - case GL_LUMINANCE16_ALPHA16_SNORM: - return GL_LUMINANCE_ALPHA; - case GL_INTENSITY_SNORM: - case GL_INTENSITY8_SNORM: - case GL_INTENSITY16_SNORM: - return GL_INTENSITY; - default: - ; /* fallthrough */ + case GL_RED_SNORM: + case GL_R8_SNORM: + case GL_R16_SNORM: + return GL_RED; + case GL_RG_SNORM: + case GL_RG8_SNORM: + case GL_RG16_SNORM: + return GL_RG; + case GL_RGB_SNORM: + case GL_RGB8_SNORM: + case GL_RGB16_SNORM: + return GL_RGB; + case GL_RGBA_SNORM: + case GL_RGBA8_SNORM: + case GL_RGBA16_SNORM: + return GL_RGBA; + case GL_ALPHA_SNORM: + case GL_ALPHA8_SNORM: + case GL_ALPHA16_SNORM: + return GL_ALPHA; + case GL_LUMINANCE_SNORM: + case GL_LUMINANCE8_SNORM: + case GL_LUMINANCE16_SNORM: + return GL_LUMINANCE; + case GL_LUMINANCE_ALPHA_SNORM: + case GL_LUMINANCE8_ALPHA8_SNORM: + case GL_LUMINANCE16_ALPHA16_SNORM: + return GL_LUMINANCE_ALPHA; + case GL_INTENSITY_SNORM: + case GL_INTENSITY8_SNORM: + case GL_INTENSITY16_SNORM: + return GL_INTENSITY; + default: + ; /* fallthrough */ } } @@ -727,87 +788,6 @@ proxy_target(GLenum target) } -/** - * Return a pointer to the current texture object for the given target - * on the current texture unit. - * Note: all error checking should have been done by this point. - */ -struct gl_texture_object * -_mesa_get_current_tex_object(struct gl_context *ctx, GLenum target) -{ - struct gl_texture_unit *texUnit = _mesa_get_current_tex_unit(ctx); - const GLboolean arrayTex = ctx->Extensions.EXT_texture_array; - - switch (target) { - case GL_TEXTURE_1D: - return texUnit->CurrentTex[TEXTURE_1D_INDEX]; - case GL_PROXY_TEXTURE_1D: - return ctx->Texture.ProxyTex[TEXTURE_1D_INDEX]; - case GL_TEXTURE_2D: - return texUnit->CurrentTex[TEXTURE_2D_INDEX]; - case GL_PROXY_TEXTURE_2D: - return ctx->Texture.ProxyTex[TEXTURE_2D_INDEX]; - case GL_TEXTURE_3D: - return texUnit->CurrentTex[TEXTURE_3D_INDEX]; - case GL_PROXY_TEXTURE_3D: - return ctx->Texture.ProxyTex[TEXTURE_3D_INDEX]; - case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB: - case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB: - case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB: - case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB: - case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB: - case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB: - case GL_TEXTURE_CUBE_MAP_ARB: - return ctx->Extensions.ARB_texture_cube_map - ? texUnit->CurrentTex[TEXTURE_CUBE_INDEX] : NULL; - case GL_PROXY_TEXTURE_CUBE_MAP_ARB: - return ctx->Extensions.ARB_texture_cube_map - ? ctx->Texture.ProxyTex[TEXTURE_CUBE_INDEX] : NULL; - case GL_TEXTURE_CUBE_MAP_ARRAY: - return ctx->Extensions.ARB_texture_cube_map_array - ? texUnit->CurrentTex[TEXTURE_CUBE_ARRAY_INDEX] : NULL; - case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY: - return ctx->Extensions.ARB_texture_cube_map_array - ? ctx->Texture.ProxyTex[TEXTURE_CUBE_ARRAY_INDEX] : NULL; - case GL_TEXTURE_RECTANGLE_NV: - return ctx->Extensions.NV_texture_rectangle - ? texUnit->CurrentTex[TEXTURE_RECT_INDEX] : NULL; - case GL_PROXY_TEXTURE_RECTANGLE_NV: - return ctx->Extensions.NV_texture_rectangle - ? ctx->Texture.ProxyTex[TEXTURE_RECT_INDEX] : NULL; - case GL_TEXTURE_1D_ARRAY_EXT: - return arrayTex ? texUnit->CurrentTex[TEXTURE_1D_ARRAY_INDEX] : NULL; - case GL_PROXY_TEXTURE_1D_ARRAY_EXT: - return arrayTex ? ctx->Texture.ProxyTex[TEXTURE_1D_ARRAY_INDEX] : NULL; - case GL_TEXTURE_2D_ARRAY_EXT: - return arrayTex ? texUnit->CurrentTex[TEXTURE_2D_ARRAY_INDEX] : NULL; - case GL_PROXY_TEXTURE_2D_ARRAY_EXT: - return arrayTex ? ctx->Texture.ProxyTex[TEXTURE_2D_ARRAY_INDEX] : NULL; - case GL_TEXTURE_BUFFER: - return ctx->API == API_OPENGL_CORE && - ctx->Extensions.ARB_texture_buffer_object ? - texUnit->CurrentTex[TEXTURE_BUFFER_INDEX] : NULL; - case GL_TEXTURE_EXTERNAL_OES: - return _mesa_is_gles(ctx) && ctx->Extensions.OES_EGL_image_external - ? texUnit->CurrentTex[TEXTURE_EXTERNAL_INDEX] : NULL; - case GL_TEXTURE_2D_MULTISAMPLE: - return ctx->Extensions.ARB_texture_multisample - ? texUnit->CurrentTex[TEXTURE_2D_MULTISAMPLE_INDEX] : NULL; - case GL_PROXY_TEXTURE_2D_MULTISAMPLE: - return ctx->Extensions.ARB_texture_multisample - ? ctx->Texture.ProxyTex[TEXTURE_2D_MULTISAMPLE_INDEX] : NULL; - case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: - return ctx->Extensions.ARB_texture_multisample - ? texUnit->CurrentTex[TEXTURE_2D_MULTISAMPLE_ARRAY_INDEX] : NULL; - case GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY: - return ctx->Extensions.ARB_texture_multisample - ? ctx->Texture.ProxyTex[TEXTURE_2D_MULTISAMPLE_ARRAY_INDEX] : NULL; - default: - _mesa_problem(NULL, "bad target in _mesa_get_current_tex_object()"); - return NULL; - } -} - /** @@ -815,7 +795,6 @@ _mesa_get_current_tex_object(struct gl_context *ctx, GLenum target) * target and mipmap level. The target and level parameters should * have already been error-checked. * - * \param ctx GL context. * \param texObj texture unit. * \param target texture target. * \param level image level. @@ -823,9 +802,8 @@ _mesa_get_current_tex_object(struct gl_context *ctx, GLenum target) * \return pointer to the texture image structure, or NULL on failure. */ struct gl_texture_image * -_mesa_select_tex_image(struct gl_context *ctx, - const struct gl_texture_object *texObj, - GLenum target, GLint level) +_mesa_select_tex_image(const struct gl_texture_object *texObj, + GLenum target, GLint level) { const GLuint face = _mesa_tex_target_to_face(target); @@ -851,7 +829,7 @@ _mesa_get_tex_image(struct gl_context *ctx, struct gl_texture_object *texObj, if (!texObj) return NULL; - texImage = _mesa_select_tex_image(ctx, texObj, target, level); + texImage = _mesa_select_tex_image(texObj, target, level); if (!texImage) { texImage = ctx->Driver.NewTextureImage(ctx); if (!texImage) { @@ -1313,7 +1291,7 @@ init_teximage_fields_ms(struct gl_context *ctx, target = img->TexObject->Target; img->_BaseFormat = _mesa_base_tex_format( ctx, internalFormat ); - ASSERT(img->_BaseFormat > 0); + ASSERT(img->_BaseFormat != -1); img->InternalFormat = internalFormat; img->Border = border; img->Width = width; @@ -1542,7 +1520,7 @@ _mesa_legal_texture_dimensions(struct gl_context *ctx, GLenum target, maxSize >>= level; if (width < 2 * border || width > 2 * border + maxSize) return GL_FALSE; - if (height < 1 || height > ctx->Const.MaxArrayTextureLayers) + if (height < 0 || height > ctx->Const.MaxArrayTextureLayers) return GL_FALSE; if (!ctx->Extensions.ARB_texture_non_power_of_two) { if (width > 0 && !_mesa_is_pow_two(width - 2 * border)) @@ -1604,12 +1582,11 @@ _mesa_legal_texture_dimensions(struct gl_context *ctx, GLenum target, * \return GL_TRUE if error found, GL_FALSE otherwise. */ static GLboolean -error_check_subtexture_dimensions(struct gl_context *ctx, - const char *function, GLuint dims, +error_check_subtexture_dimensions(struct gl_context *ctx, GLuint dims, const struct gl_texture_image *destImage, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei subWidth, GLsizei subHeight, - GLsizei subDepth) + GLsizei subDepth, const char *func) { const GLenum target = destImage->TexObject->Target; GLuint bw, bh; @@ -1617,32 +1594,32 @@ error_check_subtexture_dimensions(struct gl_context *ctx, /* Check size */ if (subWidth < 0) { _mesa_error(ctx, GL_INVALID_VALUE, - "%s%dD(width=%d)", function, dims, subWidth); + "%s%dD(width=%d)", func, dims, subWidth); return GL_TRUE; } if (dims > 1 && subHeight < 0) { _mesa_error(ctx, GL_INVALID_VALUE, - "%s%dD(height=%d)", function, dims, subHeight); + "%s%dD(height=%d)", func, dims, subHeight); return GL_TRUE; } if (dims > 2 && subDepth < 0) { _mesa_error(ctx, GL_INVALID_VALUE, - "%s%dD(depth=%d)", function, dims, subDepth); + "%s%dD(depth=%d)", func, dims, subDepth); return GL_TRUE; } /* check xoffset and width */ if (xoffset < - (GLint) destImage->Border) { _mesa_error(ctx, GL_INVALID_VALUE, "%s%dD(xoffset)", - function, dims); + func, dims); return GL_TRUE; } if (xoffset + subWidth > (GLint) destImage->Width) { _mesa_error(ctx, GL_INVALID_VALUE, "%s%dD(xoffset+width)", - function, dims); + func, dims); return GL_TRUE; } @@ -1651,28 +1628,33 @@ error_check_subtexture_dimensions(struct gl_context *ctx, GLint yBorder = (target == GL_TEXTURE_1D_ARRAY) ? 0 : destImage->Border; if (yoffset < -yBorder) { _mesa_error(ctx, GL_INVALID_VALUE, "%s%dD(yoffset)", - function, dims); + func, dims); return GL_TRUE; } if (yoffset + subHeight > (GLint) destImage->Height) { _mesa_error(ctx, GL_INVALID_VALUE, "%s%dD(yoffset+height)", - function, dims); + func, dims); return GL_TRUE; } } /* check zoffset and depth */ if (dims > 2) { + GLint depth; GLint zBorder = (target == GL_TEXTURE_2D_ARRAY || target == GL_TEXTURE_CUBE_MAP_ARRAY) ? 0 : destImage->Border; if (zoffset < -zBorder) { - _mesa_error(ctx, GL_INVALID_VALUE, "%s3D(zoffset)", function); + _mesa_error(ctx, GL_INVALID_VALUE, "%s3D(zoffset)", func); return GL_TRUE; } - if (zoffset + subDepth > (GLint) destImage->Depth) { - _mesa_error(ctx, GL_INVALID_VALUE, "%s3D(zoffset+depth)", function); + + depth = (GLint) destImage->Depth; + if (target == GL_TEXTURE_CUBE_MAP) + depth = 6; + if (zoffset + subDepth > depth) { + _mesa_error(ctx, GL_INVALID_VALUE, "%s3D(zoffset+depth)", func); return GL_TRUE; } } @@ -1691,7 +1673,7 @@ error_check_subtexture_dimensions(struct gl_context *ctx, if ((xoffset % bw != 0) || (yoffset % bh != 0)) { _mesa_error(ctx, GL_INVALID_OPERATION, "%s%dD(xoffset = %d, yoffset = %d)", - function, dims, xoffset, yoffset); + func, dims, xoffset, yoffset); return GL_TRUE; } @@ -1703,14 +1685,14 @@ error_check_subtexture_dimensions(struct gl_context *ctx, if ((subWidth % bw != 0) && (xoffset + subWidth != (GLint) destImage->Width)) { _mesa_error(ctx, GL_INVALID_OPERATION, - "%s%dD(width = %d)", function, dims, subWidth); + "%s%dD(width = %d)", func, dims, subWidth); return GL_TRUE; } if ((subHeight % bh != 0) && (yoffset + subHeight != (GLint) destImage->Height)) { _mesa_error(ctx, GL_INVALID_OPERATION, - "%s%dD(height = %d)", function, dims, subHeight); + "%s%dD(height = %d)", func, dims, subHeight); return GL_TRUE; } } @@ -1889,7 +1871,8 @@ legal_teximage_target(struct gl_context *ctx, GLuint dims, GLenum target) * proxy targets are not supported. */ static GLboolean -legal_texsubimage_target(struct gl_context *ctx, GLuint dims, GLenum target) +legal_texsubimage_target(struct gl_context *ctx, GLuint dims, GLenum target, + bool dsa) { switch (dims) { case 1: @@ -1923,6 +1906,13 @@ legal_texsubimage_target(struct gl_context *ctx, GLuint dims, GLenum target) case GL_TEXTURE_CUBE_MAP_ARRAY: case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY: return ctx->Extensions.ARB_texture_cube_map_array; + + /* Table 8.15 of the OpenGL 4.5 core profile spec + * (20141030) says that TEXTURE_CUBE_MAP is valid for TextureSubImage3D + * and CopyTextureSubImage3D. + */ + case GL_TEXTURE_CUBE_MAP: + return dsa; default: return GL_FALSE; } @@ -1942,6 +1932,9 @@ static GLboolean mutable_tex_object(struct gl_context *ctx, GLenum target) { struct gl_texture_object *texObj = _mesa_get_current_tex_object(ctx, target); + if (!texObj) + return GL_FALSE; + return !texObj->Immutable; } @@ -2137,7 +2130,7 @@ texture_error_check( struct gl_context *ctx, if (_mesa_is_gles(ctx)) { if (_mesa_is_gles3(ctx)) { - err = _mesa_es3_error_check_format_and_type(format, type, + err = _mesa_es3_error_check_format_and_type(ctx, format, type, internalFormat); } else { if (format != internalFormat) { @@ -2317,14 +2310,14 @@ compressed_texture_error_check(struct gl_context *ctx, GLint dimensions, case GL_PALETTE8_RGB5_A1_OES: /* check level (note that level should be zero or less!) */ if (level > 0 || level < -maxLevels) { - reason = "level"; - error = GL_INVALID_VALUE; + reason = "level"; + error = GL_INVALID_VALUE; goto error; } if (dimensions != 2) { - reason = "compressed paletted textures must be 2D"; - error = GL_INVALID_OPERATION; + reason = "compressed paletted textures must be 2D"; + error = GL_INVALID_OPERATION; goto error; } @@ -2332,7 +2325,7 @@ compressed_texture_error_check(struct gl_context *ctx, GLint dimensions, * checked against the actual size later. */ expectedSize = _mesa_cpal_compressed_size(level, internalFormat, - width, height); + width, height); /* This is for the benefit of the TestProxyTexImage below. It expects * level to be non-negative. OES_compressed_paletted_texture uses a @@ -2347,8 +2340,8 @@ compressed_texture_error_check(struct gl_context *ctx, GLint dimensions, default: /* check level */ if (level < 0 || level >= maxLevels) { - reason = "level"; - error = GL_INVALID_VALUE; + reason = "level"; + error = GL_INVALID_VALUE; goto error; } @@ -2401,7 +2394,8 @@ compressed_texture_error_check(struct gl_context *ctx, GLint dimensions, error: /* Note: not all error paths exit through here. */ - _mesa_error(ctx, error, "glCompressedTexImage%dD(%s)", dimensions, reason); + _mesa_error(ctx, error, "glCompressedTexImage%dD(%s)", + dimensions, reason); return GL_TRUE; } @@ -2431,26 +2425,34 @@ error: */ static GLboolean texsubimage_error_check(struct gl_context *ctx, GLuint dimensions, + struct gl_texture_object *texObj, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint width, GLint height, GLint depth, - GLenum format, GLenum type) + GLenum format, GLenum type, bool dsa) { - struct gl_texture_object *texObj; struct gl_texture_image *texImage; GLenum err; + const char* suffix = dsa ? "ture" : ""; + + if (!texObj) { + /* must be out of memory */ + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTex%sSubImage%dD()", + suffix, dimensions); + return GL_TRUE; + } /* check target (proxies not allowed) */ - if (!legal_texsubimage_target(ctx, dimensions, target)) { - _mesa_error(ctx, GL_INVALID_ENUM, "glTexSubImage%uD(target=%s)", - dimensions, _mesa_lookup_enum_by_nr(target)); + if (!legal_texsubimage_target(ctx, dimensions, target, dsa)) { + _mesa_error(ctx, GL_INVALID_ENUM, "glTex%sSubImage%uD(target=%s)", + suffix, dimensions, _mesa_lookup_enum_by_nr(target)); return GL_TRUE; } /* level check */ if (level < 0 || level >= _mesa_max_texture_levels(ctx, target)) { - _mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage%uD(level=%d)", - dimensions, level); + _mesa_error(ctx, GL_INVALID_VALUE, "glTex%sSubImage%uD(level=%d)", + suffix, dimensions, level); return GL_TRUE; } @@ -2463,9 +2465,8 @@ texsubimage_error_check(struct gl_context *ctx, GLuint dimensions, err = _mesa_es_error_check_format_and_type(format, type, dimensions); if (err != GL_NO_ERROR) { _mesa_error(ctx, err, - "glTexSubImage%dD(format = %s, type = %s)", - dimensions, - _mesa_lookup_enum_by_nr(format), + "glTex%sSubImage%dD(format = %s, type = %s)", + suffix, dimensions, _mesa_lookup_enum_by_nr(format), _mesa_lookup_enum_by_nr(type)); return GL_TRUE; } @@ -2474,38 +2475,34 @@ texsubimage_error_check(struct gl_context *ctx, GLuint dimensions, err = _mesa_error_check_format_and_type(ctx, format, type); if (err != GL_NO_ERROR) { _mesa_error(ctx, err, - "glTexSubImage%dD(incompatible format = %s, type = %s)", - dimensions, _mesa_lookup_enum_by_nr(format), + "glTex%sSubImage%dD(incompatible format = %s, type = %s)", + suffix, dimensions, _mesa_lookup_enum_by_nr(format), _mesa_lookup_enum_by_nr(type)); return GL_TRUE; } - /* Get dest texture object / image pointers */ - texObj = _mesa_get_current_tex_object(ctx, target); - if (!texObj) { - /* must be out of memory */ - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage%dD()", dimensions); - return GL_TRUE; - } - - texImage = _mesa_select_tex_image(ctx, texObj, target, level); + texImage = _mesa_select_tex_image(texObj, target, level); if (!texImage) { /* non-existant texture level */ _mesa_error(ctx, GL_INVALID_OPERATION, - "glTexSubImage%dD(invalid texture image)", dimensions); + "glTex%sSubImage%dD(invalid texture image)", suffix, + dimensions); return GL_TRUE; } - if (error_check_subtexture_dimensions(ctx, "glTexSubImage", dimensions, + if (error_check_subtexture_dimensions(ctx, dimensions, texImage, xoffset, yoffset, 0, - width, height, 1)) { + width, height, 1, + dsa ? "glTextureSubImage" : + "glTexSubImage")) { return GL_TRUE; } if (_mesa_is_format_compressed(texImage->TexFormat)) { if (compressedteximage_only_format(ctx, texImage->InternalFormat)) { _mesa_error(ctx, GL_INVALID_OPERATION, - "glTexSubImage%dD(no compression for format)", dimensions); + "glTex%sSubImage%dD(no compression for format)", + suffix, dimensions); return GL_TRUE; } } @@ -2515,8 +2512,8 @@ texsubimage_error_check(struct gl_context *ctx, GLuint dimensions, if (_mesa_is_format_integer_color(texImage->TexFormat) != _mesa_is_enum_format_integer(format)) { _mesa_error(ctx, GL_INVALID_OPERATION, - "glTexSubImage%dD(integer/non-integer format mismatch)", - dimensions); + "glTex%sSubImage%dD(integer/non-integer format mismatch)", + suffix, dimensions); return GL_TRUE; } } @@ -2554,7 +2551,7 @@ copytexture_error_check( struct gl_context *ctx, GLuint dimensions, GLenum rb_internal_format; /* check target */ - if (!legal_texsubimage_target(ctx, dimensions, target)) { + if (!legal_texsubimage_target(ctx, dimensions, target, false)) { _mesa_error(ctx, GL_INVALID_ENUM, "glCopyTexImage%uD(target=%s)", dimensions, _mesa_lookup_enum_by_nr(target)); return GL_TRUE; @@ -2579,10 +2576,9 @@ copytexture_error_check( struct gl_context *ctx, GLuint dimensions, } if (ctx->ReadBuffer->Visual.samples > 0) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "glCopyTexImage%dD(multisample FBO)", - dimensions); - return GL_TRUE; + _mesa_error(ctx, GL_INVALID_OPERATION, + "glCopyTexImage%dD(multisample FBO)", dimensions); + return GL_TRUE; } } @@ -2791,12 +2787,13 @@ copytexture_error_check( struct gl_context *ctx, GLuint dimensions, */ static GLboolean copytexsubimage_error_check(struct gl_context *ctx, GLuint dimensions, + const struct gl_texture_object *texObj, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, - GLint width, GLint height) + GLint width, GLint height, bool dsa) { - struct gl_texture_object *texObj; struct gl_texture_image *texImage; + const char *suffix = dsa ? "ture" : ""; /* Check that the source buffer is complete */ if (_mesa_is_user_fbo(ctx->ReadBuffer)) { @@ -2805,89 +2802,97 @@ copytexsubimage_error_check(struct gl_context *ctx, GLuint dimensions, } if (ctx->ReadBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) { _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT, - "glCopyTexImage%dD(invalid readbuffer)", dimensions); + "glCopyTex%sSubImage%dD(invalid readbuffer)", + suffix, dimensions); return GL_TRUE; } if (ctx->ReadBuffer->Visual.samples > 0) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "glCopyTexSubImage%dD(multisample FBO)", - dimensions); - return GL_TRUE; + _mesa_error(ctx, GL_INVALID_OPERATION, + "glCopyTex%sSubImage%dD(multisample FBO)", suffix, + dimensions); + return GL_TRUE; } } /* check target (proxies not allowed) */ - if (!legal_texsubimage_target(ctx, dimensions, target)) { - _mesa_error(ctx, GL_INVALID_ENUM, "glCopyTexSubImage%uD(target=%s)", - dimensions, _mesa_lookup_enum_by_nr(target)); + if (!legal_texsubimage_target(ctx, dimensions, target, dsa)) { + _mesa_error(ctx, GL_INVALID_ENUM, "glCopyTex%sSubImage%uD(target=%s)", + suffix, dimensions, + _mesa_lookup_enum_by_nr(target)); return GL_TRUE; } /* Check level */ if (level < 0 || level >= _mesa_max_texture_levels(ctx, target)) { _mesa_error(ctx, GL_INVALID_VALUE, - "glCopyTexSubImage%dD(level=%d)", dimensions, level); + "glCopyTex%sSubImage%dD(level=%d)", suffix, + dimensions, level); return GL_TRUE; } - /* Get dest texture object / image pointers */ - texObj = _mesa_get_current_tex_object(ctx, target); + /* Get dest image pointers */ if (!texObj) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexSubImage%dD()", dimensions); + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTex%sSubImage%dD()", + suffix, dimensions); return GL_TRUE; } - texImage = _mesa_select_tex_image(ctx, texObj, target, level); + texImage = _mesa_select_tex_image(texObj, target, level); if (!texImage) { /* destination image does not exist */ _mesa_error(ctx, GL_INVALID_OPERATION, - "glCopyTexSubImage%dD(invalid texture image)", dimensions); + "glCopyTex%sSubImage%dD(invalid texture image)", + suffix, dimensions); return GL_TRUE; } - if (error_check_subtexture_dimensions(ctx, "glCopyTexSubImage", - dimensions, texImage, + if (error_check_subtexture_dimensions(ctx, dimensions, texImage, xoffset, yoffset, zoffset, - width, height, 1)) { + width, height, 1, dsa ? + "glCompressedTextureSubImage" : + "glCompressedTexSubImage")) { return GL_TRUE; } if (_mesa_is_format_compressed(texImage->TexFormat)) { if (compressedteximage_only_format(ctx, texImage->InternalFormat)) { _mesa_error(ctx, GL_INVALID_OPERATION, - "glCopyTexSubImage%dD(no compression for format)", dimensions); + "glCopyTex%sSubImage%dD(no compression for format)", + suffix, dimensions); return GL_TRUE; } } if (texImage->InternalFormat == GL_YCBCR_MESA) { - _mesa_error(ctx, GL_INVALID_OPERATION, "glCopyTexSubImage2D"); + _mesa_error(ctx, GL_INVALID_OPERATION, "glCopyTex%sSubImage2D", suffix); return GL_TRUE; } if (!_mesa_source_buffer_exists(ctx, texImage->_BaseFormat)) { _mesa_error(ctx, GL_INVALID_OPERATION, - "glCopyTexSubImage%dD(missing readbuffer, format=0x%x)", - dimensions, texImage->_BaseFormat); + "glCopyTex%sSubImage%dD(missing readbuffer, format=0x%x)", + suffix, dimensions, texImage->_BaseFormat); return GL_TRUE; } /* From the EXT_texture_integer spec: * - * "INVALID_OPERATION is generated by CopyTexImage* and CopyTexSubImage* - * if the texture internalformat is an integer format and the read color - * buffer is not an integer format, or if the internalformat is not an - * integer format and the read color buffer is an integer format." + * "INVALID_OPERATION is generated by CopyTexImage* and + * CopyTexSubImage* if the texture internalformat is an integer format + * and the read color buffer is not an integer format, or if the + * internalformat is not an integer format and the read color buffer + * is an integer format." */ if (_mesa_is_color_format(texImage->InternalFormat)) { struct gl_renderbuffer *rb = ctx->ReadBuffer->_ColorReadBuffer; if (_mesa_is_format_integer_color(rb->Format) != - _mesa_is_format_integer_color(texImage->TexFormat)) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "glCopyTexImage%dD(integer vs non-integer)", dimensions); - return GL_TRUE; + _mesa_is_format_integer_color(texImage->TexFormat)) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glCopyTex%sSubImage%dD(integer vs non-integer)", + suffix, dimensions); + return GL_TRUE; } } @@ -2969,7 +2974,6 @@ static inline void check_gen_mipmap(struct gl_context *ctx, GLenum target, struct gl_texture_object *texObj, GLint level) { - ASSERT(target != GL_TEXTURE_CUBE_MAP); if (texObj->GenerateMipmap && level == texObj->BaseLevel && level < texObj->MaxLevel) { @@ -3042,7 +3046,7 @@ _mesa_choose_texture_format(struct gl_context *ctx, /* see if we've already chosen a format for the previous level */ if (level > 0) { struct gl_texture_image *prevImage = - _mesa_select_tex_image(ctx, texObj, target, level - 1); + _mesa_select_tex_image(texObj, target, level - 1); /* See if the prev level is defined and has an internal format which * matches the new internal format. */ @@ -3239,6 +3243,19 @@ teximage(struct gl_context *ctx, GLboolean compressed, GLuint dims, texFormat = _mesa_glenum_to_compressed_format(internalFormat); } else { + /* In case of HALF_FLOAT_OES or FLOAT_OES, find corresponding sized + * internal floating point format for the given base format. + */ + if (_mesa_is_gles(ctx) && format == internalFormat) { + if (type == GL_FLOAT) { + texObj->_IsFloat = GL_TRUE; + } else if (type == GL_HALF_FLOAT_OES || type == GL_HALF_FLOAT) { + texObj->_IsHalfFloat = GL_TRUE; + } + + internalFormat = adjust_for_oes_float_texture(format, type); + } + texFormat = _mesa_choose_texture_format(ctx, texObj, target, level, internalFormat, format, type); } @@ -3419,13 +3436,13 @@ _mesa_EGLImageTargetTexture2DOES (GLenum target, GLeglImageOES image) if (!valid_target) { _mesa_error(ctx, GL_INVALID_ENUM, - "glEGLImageTargetTexture2D(target=%d)", target); + "glEGLImageTargetTexture2D(target=%d)", target); return; } if (!image) { _mesa_error(ctx, GL_INVALID_OPERATION, - "glEGLImageTargetTexture2D(image=%p)", image); + "glEGLImageTargetTexture2D(image=%p)", image); return; } @@ -3433,11 +3450,14 @@ _mesa_EGLImageTargetTexture2DOES (GLenum target, GLeglImageOES image) _mesa_update_state(ctx); texObj = _mesa_get_current_tex_object(ctx, target); + if (!texObj) + return; + _mesa_lock_texture(ctx, texObj); if (texObj->Immutable) { _mesa_error(ctx, GL_INVALID_OPERATION, - "glEGLImageTargetTexture2D(texture is immutable)"); + "glEGLImageTargetTexture2D(texture is immutable)"); _mesa_unlock_texture(ctx, texObj); return; } @@ -3458,32 +3478,26 @@ _mesa_EGLImageTargetTexture2DOES (GLenum target, GLeglImageOES image) } - /** - * Implement all the glTexSubImage1/2/3D() functions. + * Helper that implements the glTexSubImage1/2/3D() + * and glTextureSubImage1/2/3D() functions. */ -static void -texsubimage(struct gl_context *ctx, GLuint dims, GLenum target, GLint level, - GLint xoffset, GLint yoffset, GLint zoffset, - GLsizei width, GLsizei height, GLsizei depth, - GLenum format, GLenum type, const GLvoid *pixels ) +void +_mesa_texture_sub_image(struct gl_context *ctx, GLuint dims, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage, + GLenum target, GLint level, + GLint xoffset, GLint yoffset, GLint zoffset, + GLsizei width, GLsizei height, GLsizei depth, + GLenum format, GLenum type, const GLvoid *pixels, + bool dsa) { - struct gl_texture_object *texObj; - struct gl_texture_image *texImage; - FLUSH_VERTICES(ctx, 0); - if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) - _mesa_debug(ctx, "glTexSubImage%uD %s %d %d %d %d %d %d %d %s %s %p\n", - dims, - _mesa_lookup_enum_by_nr(target), level, - xoffset, yoffset, zoffset, width, height, depth, - _mesa_lookup_enum_by_nr(format), - _mesa_lookup_enum_by_nr(type), pixels); - /* check target (proxies not allowed) */ - if (!legal_texsubimage_target(ctx, dims, target)) { - _mesa_error(ctx, GL_INVALID_ENUM, "glTexSubImage%uD(target=%s)", + if (!legal_texsubimage_target(ctx, dims, target, dsa)) { + _mesa_error(ctx, GL_INVALID_ENUM, "glTex%sSubImage%uD(target=%s)", + dsa ? "ture" : "", dims, _mesa_lookup_enum_by_nr(target)); return; } @@ -3491,18 +3505,8 @@ texsubimage(struct gl_context *ctx, GLuint dims, GLenum target, GLint level, if (ctx->NewState & _NEW_PIXEL) _mesa_update_state(ctx); - if (texsubimage_error_check(ctx, dims, target, level, - xoffset, yoffset, zoffset, - width, height, depth, format, type)) { - return; /* error was detected */ - } - - texObj = _mesa_get_current_tex_object(ctx, target); - _mesa_lock_texture(ctx, texObj); { - texImage = _mesa_select_tex_image(ctx, texObj, target, level); - if (width > 0 && height > 0 && depth > 0) { /* If we have a border, offset=-1 is legal. Bias by border width. */ switch (dims) { @@ -3533,18 +3537,174 @@ texsubimage(struct gl_context *ctx, GLuint dims, GLenum target, GLint level, _mesa_unlock_texture(ctx, texObj); } - -void GLAPIENTRY -_mesa_TexSubImage1D( GLenum target, GLint level, - GLint xoffset, GLsizei width, - GLenum format, GLenum type, - const GLvoid *pixels ) +/** + * Implement all the glTexSubImage1/2/3D() functions. + * Must split this out this way because of GL_TEXTURE_CUBE_MAP. + */ +static void +texsubimage(struct gl_context *ctx, GLuint dims, GLenum target, GLint level, + GLint xoffset, GLint yoffset, GLint zoffset, + GLsizei width, GLsizei height, GLsizei depth, + GLenum format, GLenum type, const GLvoid *pixels) { - GET_CURRENT_CONTEXT(ctx); - texsubimage(ctx, 1, target, level, - xoffset, 0, 0, - width, 1, 1, - format, type, pixels); + struct gl_texture_object *texObj; + struct gl_texture_image *texImage; + + texObj = _mesa_get_current_tex_object(ctx, target); + if (!texObj) + return; + + if (texsubimage_error_check(ctx, dims, texObj, target, level, + xoffset, yoffset, zoffset, + width, height, depth, format, type, false)) { + return; /* error was detected */ + } + + texImage = _mesa_select_tex_image(texObj, target, level); + /* texsubimage_error_check ensures that texImage is not NULL */ + + if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) + _mesa_debug(ctx, "glTexSubImage%uD %s %d %d %d %d %d %d %d %s %s %p\n", + dims, + _mesa_lookup_enum_by_nr(target), level, + xoffset, yoffset, zoffset, width, height, depth, + _mesa_lookup_enum_by_nr(format), + _mesa_lookup_enum_by_nr(type), pixels); + + _mesa_texture_sub_image(ctx, dims, texObj, texImage, target, level, + xoffset, yoffset, zoffset, width, height, depth, + format, type, pixels, false); +} + + +/** + * Implement all the glTextureSubImage1/2/3D() functions. + * Must split this out this way because of GL_TEXTURE_CUBE_MAP. + */ +static void +texturesubimage(struct gl_context *ctx, GLuint dims, + GLuint texture, GLint level, + GLint xoffset, GLint yoffset, GLint zoffset, + GLsizei width, GLsizei height, GLsizei depth, + GLenum format, GLenum type, const GLvoid *pixels) +{ + struct gl_texture_object *texObj; + struct gl_texture_image *texImage; + int i; + + if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) + _mesa_debug(ctx, + "glTextureSubImage%uD %d %d %d %d %d %d %d %d %s %s %p\n", + dims, texture, level, + xoffset, yoffset, zoffset, width, height, depth, + _mesa_lookup_enum_by_nr(format), + _mesa_lookup_enum_by_nr(type), pixels); + + /* Get the texture object by Name. */ + texObj = _mesa_lookup_texture(ctx, texture); + if (!texObj) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glTextureSubImage%uD(texture)", + dims); + return; + } + + if (texsubimage_error_check(ctx, dims, texObj, texObj->Target, level, + xoffset, yoffset, zoffset, + width, height, depth, format, type, true)) { + return; /* error was detected */ + } + + + /* Must handle special case GL_TEXTURE_CUBE_MAP. */ + if (texObj->Target == GL_TEXTURE_CUBE_MAP) { + GLint rowStride; + + /* Error checking */ + if (texObj->NumLayers < 6) { + /* Not enough image planes for a cube map. The spec does not say + * what should happen in this case because the user has always + * specified each cube face separately (using + * GL_TEXTURE_CUBE_MAP_POSITIVE_X+i) in previous GL versions. + * This is addressed in Khronos Bug 13223. + */ + _mesa_error(ctx, GL_INVALID_OPERATION, + "glTextureSubImage%uD(insufficient cube map storage)", + dims); + return; + } + + /* + * What do we do if the user created a texture with the following code + * and then called this function with its handle? + * + * GLuint tex; + * glCreateTextures(GL_TEXTURE_CUBE_MAP, 1, &tex); + * glBindTexture(GL_TEXTURE_CUBE_MAP, tex); + * glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, ...); + * glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, ...); + * glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, ...); + * // Note: GL_TEXTURE_CUBE_MAP_NEGATIVE_Y not set, or given the + * // wrong format, or given the wrong size, etc. + * glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, ...); + * glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, ...); + * + * A bug has been filed against the spec for this case. In the + * meantime, we will check for cube completeness. + * + * According to Section 8.17 Texture Completeness in the OpenGL 4.5 + * Core Profile spec (30.10.2014): + * "[A] cube map texture is cube complete if the + * following conditions all hold true: The [base level] texture + * images of each of the six cube map faces have identical, positive, + * and square dimensions. The [base level] images were each specified + * with the same internal format." + * + * It seems reasonable to check for cube completeness of an arbitrary + * level here so that the image data has a consistent format and size. + */ + if (!_mesa_cube_level_complete(texObj, level)) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glTextureSubImage%uD(cube map incomplete)", + dims); + return; + } + + rowStride = _mesa_image_image_stride(&ctx->Unpack, width, height, + format, type); + /* Copy in each face. */ + for (i = 0; i < 6; ++i) { + texImage = texObj->Image[i][level]; + _mesa_texture_sub_image(ctx, 3, texObj, texImage, texObj->Target, + level, xoffset, yoffset, zoffset, + width, height, 1, format, + type, pixels, true); + pixels = (GLubyte *) pixels + rowStride; + } + } + else { + texImage = _mesa_select_tex_image(texObj, texObj->Target, level); + if (!texImage) + return; + + _mesa_texture_sub_image(ctx, dims, texObj, texImage, texObj->Target, + level, xoffset, yoffset, zoffset, + width, height, depth, format, + type, pixels, true); + } +} + + +void GLAPIENTRY +_mesa_TexSubImage1D( GLenum target, GLint level, + GLint xoffset, GLsizei width, + GLenum format, GLenum type, + const GLvoid *pixels ) +{ + GET_CURRENT_CONTEXT(ctx); + texsubimage(ctx, 1, target, level, + xoffset, 0, 0, + width, 1, 1, + format, type, pixels); } @@ -3578,6 +3738,48 @@ _mesa_TexSubImage3D( GLenum target, GLint level, format, type, pixels); } +void GLAPIENTRY +_mesa_TextureSubImage1D(GLuint texture, GLint level, + GLint xoffset, GLsizei width, + GLenum format, GLenum type, + const GLvoid *pixels) +{ + GET_CURRENT_CONTEXT(ctx); + texturesubimage(ctx, 1, texture, level, + xoffset, 0, 0, + width, 1, 1, + format, type, pixels); +} + + +void GLAPIENTRY +_mesa_TextureSubImage2D(GLuint texture, GLint level, + GLint xoffset, GLint yoffset, + GLsizei width, GLsizei height, + GLenum format, GLenum type, + const GLvoid *pixels) +{ + GET_CURRENT_CONTEXT(ctx); + texturesubimage(ctx, 2, texture, level, + xoffset, yoffset, 0, + width, height, 1, + format, type, pixels); +} + + +void GLAPIENTRY +_mesa_TextureSubImage3D(GLuint texture, GLint level, + GLint xoffset, GLint yoffset, GLint zoffset, + GLsizei width, GLsizei height, GLsizei depth, + GLenum format, GLenum type, + const GLvoid *pixels) +{ + GET_CURRENT_CONTEXT(ctx); + texturesubimage(ctx, 3, texture, level, + xoffset, yoffset, zoffset, + width, height, depth, + format, type, pixels); +} /** @@ -3811,40 +4013,40 @@ _mesa_CopyTexImage2D( GLenum target, GLint level, GLenum internalFormat, x, y, width, height, border); } - - /** - * Implementation for glCopyTexSubImage1/2/3D() functions. + * Implementation for glCopyTex(ture)SubImage1/2/3D() functions. */ -static void -copytexsubimage(struct gl_context *ctx, GLuint dims, GLenum target, GLint level, - GLint xoffset, GLint yoffset, GLint zoffset, - GLint x, GLint y, GLsizei width, GLsizei height) +void +_mesa_copy_texture_sub_image(struct gl_context *ctx, GLuint dims, + struct gl_texture_object *texObj, + GLenum target, GLint level, + GLint xoffset, GLint yoffset, GLint zoffset, + GLint x, GLint y, + GLsizei width, GLsizei height, + bool dsa) { - struct gl_texture_object *texObj; struct gl_texture_image *texImage; FLUSH_VERTICES(ctx, 0); if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) - _mesa_debug(ctx, "glCopyTexSubImage%uD %s %d %d %d %d %d %d %d %d\n", - dims, + _mesa_debug(ctx, "glCopyTex%sSubImage%uD %s %d %d %d %d %d %d %d %d\n", + dsa ? "ture" : "", dims, _mesa_lookup_enum_by_nr(target), level, xoffset, yoffset, zoffset, x, y, width, height); if (ctx->NewState & NEW_COPY_TEX_STATE) _mesa_update_state(ctx); - if (copytexsubimage_error_check(ctx, dims, target, level, - xoffset, yoffset, zoffset, width, height)) { + if (copytexsubimage_error_check(ctx, dims, texObj, target, level, + xoffset, yoffset, zoffset, + width, height, dsa)) { return; } - texObj = _mesa_get_current_tex_object(ctx, target); - _mesa_lock_texture(ctx, texObj); { - texImage = _mesa_select_tex_image(ctx, texObj, target, level); + texImage = _mesa_select_tex_image(texObj, target, level); /* If we have a border, offset=-1 is legal. Bias by border width. */ switch (dims) { @@ -3879,13 +4081,19 @@ copytexsubimage(struct gl_context *ctx, GLuint dims, GLenum target, GLint level, _mesa_unlock_texture(ctx, texObj); } - void GLAPIENTRY _mesa_CopyTexSubImage1D( GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width ) { + struct gl_texture_object* texObj; GET_CURRENT_CONTEXT(ctx); - copytexsubimage(ctx, 1, target, level, xoffset, 0, 0, x, y, width, 1); + + texObj = _mesa_get_current_tex_object(ctx, target); + if (!texObj) + return; + + _mesa_copy_texture_sub_image(ctx, 1, texObj, target, level, xoffset, 0, 0, + x, y, width, 1, false); } @@ -3895,9 +4103,16 @@ _mesa_CopyTexSubImage2D( GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height ) { + struct gl_texture_object* texObj; GET_CURRENT_CONTEXT(ctx); - copytexsubimage(ctx, 2, target, level, xoffset, yoffset, 0, x, y, - width, height); + + texObj = _mesa_get_current_tex_object(ctx, target); + if (!texObj) + return; + + _mesa_copy_texture_sub_image(ctx, 2, texObj, target, level, + xoffset, yoffset, 0, + x, y, width, height, false); } @@ -3907,9 +4122,67 @@ _mesa_CopyTexSubImage3D( GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height ) { + struct gl_texture_object* texObj; GET_CURRENT_CONTEXT(ctx); - copytexsubimage(ctx, 3, target, level, xoffset, yoffset, zoffset, - x, y, width, height); + + texObj = _mesa_get_current_tex_object(ctx, target); + if (!texObj) + return; + + _mesa_copy_texture_sub_image(ctx, 3, texObj, target, level, + xoffset, yoffset, zoffset, + x, y, width, height, false); +} + +void GLAPIENTRY +_mesa_CopyTextureSubImage1D(GLuint texture, GLint level, + GLint xoffset, GLint x, GLint y, GLsizei width) +{ + struct gl_texture_object* texObj; + GET_CURRENT_CONTEXT(ctx); + + texObj = _mesa_lookup_texture_err(ctx, texture, "glCopyTextureSubImage1D"); + if (!texObj) + return; + + _mesa_copy_texture_sub_image(ctx, 1, texObj, texObj->Target, level, + xoffset, 0, 0, x, y, width, 1, true); +} + +void GLAPIENTRY +_mesa_CopyTextureSubImage2D(GLuint texture, GLint level, + GLint xoffset, GLint yoffset, + GLint x, GLint y, GLsizei width, GLsizei height) +{ + struct gl_texture_object* texObj; + GET_CURRENT_CONTEXT(ctx); + + texObj = _mesa_lookup_texture_err(ctx, texture, "glCopyTextureSubImage2D"); + if (!texObj) + return; + + _mesa_copy_texture_sub_image(ctx, 2, texObj, texObj->Target, level, + xoffset, yoffset, 0, + x, y, width, height, true); +} + + + +void GLAPIENTRY +_mesa_CopyTextureSubImage3D(GLuint texture, GLint level, + GLint xoffset, GLint yoffset, GLint zoffset, + GLint x, GLint y, GLsizei width, GLsizei height) +{ + struct gl_texture_object* texObj; + GET_CURRENT_CONTEXT(ctx); + + texObj = _mesa_lookup_texture_err(ctx, texture, "glCopyTextureSubImage3D"); + if (!texObj) + return; + + _mesa_copy_texture_sub_image(ctx, 3, texObj, texObj->Target, level, + xoffset, yoffset, zoffset, + x, y, width, height, true); } static bool @@ -4031,7 +4304,7 @@ get_tex_images_for_clear(struct gl_context *ctx, for (i = 0; i < MAX_FACES; i++) { target = GL_TEXTURE_CUBE_MAP_POSITIVE_X + i; - texImages[i] = _mesa_select_tex_image(ctx, texObj, target, level); + texImages[i] = _mesa_select_tex_image(texObj, target, level); if (texImages[i] == NULL) { _mesa_error(ctx, GL_INVALID_OPERATION, "%s(invalid level)", function); @@ -4042,7 +4315,7 @@ get_tex_images_for_clear(struct gl_context *ctx, return MAX_FACES; } - texImages[0] = _mesa_select_tex_image(ctx, texObj, texObj->Target, level); + texImages[0] = _mesa_select_tex_image(texObj, texObj->Target, level); if (texImages[0] == NULL) { _mesa_error(ctx, GL_INVALID_OPERATION, "%s(invalid level)", function); @@ -4186,15 +4459,22 @@ out: */ static GLboolean compressed_subtexture_error_check(struct gl_context *ctx, GLint dims, + const struct gl_texture_object *texObj, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, - GLenum format, GLsizei imageSize) + GLenum format, GLsizei imageSize, bool dsa) { - struct gl_texture_object *texObj; struct gl_texture_image *texImage; GLint expectedSize; GLboolean targetOK; + const char *suffix = dsa ? "ture" : ""; + + if (dsa && target == GL_TEXTURE_RECTANGLE) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glCompressedSubTexture%dD(target)", dims); + return GL_TRUE; + } switch (dims) { case 2: @@ -4214,7 +4494,52 @@ compressed_subtexture_error_check(struct gl_context *ctx, GLint dims, } break; case 3: - targetOK = (target == GL_TEXTURE_2D_ARRAY); + targetOK = (target == GL_TEXTURE_3D) || + (target == GL_TEXTURE_2D_ARRAY) || + (target == GL_TEXTURE_CUBE_MAP_ARRAY) || + (target == GL_TEXTURE_CUBE_MAP && dsa); + + /* OpenGL 4.5 spec (30.10.2014) says in Section 8.7 Compressed Texture + * Images: + * "An INVALID_OPERATION error is generated by + * CompressedTex*SubImage3D if the internal format of the texture is + * one of the EAC, ETC2, or RGTC formats and either border is + * non-zero, or the effective target for the texture is not + * TEXTURE_2D_ARRAY." + */ + if (target != GL_TEXTURE_2D_ARRAY) { + bool invalidformat; + switch (format) { + /* These came from _mesa_is_compressed_format in glformats.c. */ + /* EAC formats */ + case GL_COMPRESSED_RGBA8_ETC2_EAC: + case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC: + case GL_COMPRESSED_R11_EAC: + case GL_COMPRESSED_RG11_EAC: + case GL_COMPRESSED_SIGNED_R11_EAC: + case GL_COMPRESSED_SIGNED_RG11_EAC: + /* ETC2 formats */ + case GL_COMPRESSED_RGB8_ETC2: + case GL_COMPRESSED_SRGB8_ETC2: + case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2: + case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2: + /* RGTC formats */ + case GL_COMPRESSED_RED_RGTC1: + case GL_COMPRESSED_SIGNED_RED_RGTC1: + case GL_COMPRESSED_RG_RGTC2: + case GL_COMPRESSED_SIGNED_RG_RGTC2: + invalidformat = true; + break; + default: + invalidformat = false; + } + if (invalidformat) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glCompressedTex%sSubImage%uD(target)", suffix, dims); + return GL_TRUE; + } + } + break; default: assert(dims == 1); @@ -4224,68 +4549,67 @@ compressed_subtexture_error_check(struct gl_context *ctx, GLint dims, } if (!targetOK) { - _mesa_error(ctx, GL_INVALID_ENUM, "glCompressedTexSubImage%uD(target)", - dims); + _mesa_error(ctx, GL_INVALID_ENUM, + "glCompressedTex%sSubImage%uD(target)", suffix, dims); return GL_TRUE; } /* this will catch any invalid compressed format token */ if (!_mesa_is_compressed_format(ctx, format)) { - _mesa_error(ctx, GL_INVALID_ENUM, "glCompressedTexImage%uD(format)", - dims); + _mesa_error(ctx, GL_INVALID_ENUM, + "glCompressedTex%sSubImage%uD(format)", suffix, dims); return GL_TRUE; } if (level < 0 || level >= _mesa_max_texture_levels(ctx, target)) { - _mesa_error(ctx, GL_INVALID_VALUE, "glCompressedTexSubImage%uD(level=%d)", - dims, level); + _mesa_error(ctx, GL_INVALID_VALUE, + "glCompressedTex%sSubImage%uD(level=%d)", + suffix, dims, level); return GL_TRUE; } /* Check for invalid pixel storage modes */ if (!_mesa_compressed_pixel_storage_error_check(ctx, dims, - &ctx->Unpack, - "glCompressedTexSubImage")) { + &ctx->Unpack, + dsa ? "glCompressedTextureSubImage" : + "glCompressedTexSubImage")) { return GL_TRUE; } expectedSize = compressed_tex_size(width, height, depth, format); if (expectedSize != imageSize) { - _mesa_error(ctx, GL_INVALID_VALUE, "glCompressedTexSubImage%uD(size=%d)", - dims, imageSize); - return GL_TRUE; - } - - texObj = _mesa_get_current_tex_object(ctx, target); - if (!texObj) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, - "glCompressedTexSubImage%uD()", dims); + _mesa_error(ctx, GL_INVALID_VALUE, + "glCompressedTex%sSubImage%uD(size=%d)", + suffix, dims, imageSize); return GL_TRUE; } - texImage = _mesa_select_tex_image(ctx, texObj, target, level); + texImage = _mesa_select_tex_image(texObj, target, level); if (!texImage) { _mesa_error(ctx, GL_INVALID_OPERATION, - "glCompressedTexSubImage%uD(invalid texture image)", dims); + "glCompressedTex%sSubImage%uD(invalid texture image)", + suffix, dims); return GL_TRUE; } if ((GLint) format != texImage->InternalFormat) { _mesa_error(ctx, GL_INVALID_OPERATION, - "glCompressedTexSubImage%uD(format=0x%x)", dims, format); + "glCompressedTex%sSubImage%uD(format=0x%x)", + suffix, dims, format); return GL_TRUE; } if (compressedteximage_only_format(ctx, format)) { _mesa_error(ctx, GL_INVALID_OPERATION, - "glCompressedTexSubImage%uD(format=0x%x cannot be updated)" - , dims, format); + "glCompressedTex%sSubImage%uD(format=0x%x cannot be updated)", + suffix, dims, format); return GL_TRUE; } - if (error_check_subtexture_dimensions(ctx, "glCompressedTexSubImage", dims, + if (error_check_subtexture_dimensions(ctx, dims, texImage, xoffset, yoffset, zoffset, - width, height, depth)) { + width, height, depth, + "glCompressedTexSubImage")) { return GL_TRUE; } @@ -4330,31 +4654,34 @@ _mesa_CompressedTexImage3D(GLenum target, GLint level, /** - * Common helper for glCompressedTexSubImage1/2/3D(). + * Common helper for glCompressedTexSubImage1/2/3D() and + * glCompressedTextureSubImage1/2/3D(). */ -static void -compressed_tex_sub_image(GLuint dims, GLenum target, GLint level, - GLint xoffset, GLint yoffset, GLint zoffset, - GLsizei width, GLsizei height, GLsizei depth, - GLenum format, GLsizei imageSize, const GLvoid *data) +void +_mesa_compressed_texture_sub_image(struct gl_context *ctx, GLuint dims, + struct gl_texture_object *texObj, + GLenum target, GLint level, + GLint xoffset, GLint yoffset, + GLint zoffset, + GLsizei width, GLsizei height, + GLsizei depth, + GLenum format, GLsizei imageSize, + const GLvoid *data, bool dsa) { - struct gl_texture_object *texObj; struct gl_texture_image *texImage; - GET_CURRENT_CONTEXT(ctx); - FLUSH_VERTICES(ctx, 0); - if (compressed_subtexture_error_check(ctx, dims, target, level, - xoffset, yoffset, zoffset, + if (compressed_subtexture_error_check(ctx, dims, texObj, target, + level, xoffset, yoffset, zoffset, width, height, depth, - format, imageSize)) { + format, imageSize, dsa)) { return; } - texObj = _mesa_get_current_tex_object(ctx, target); + FLUSH_VERTICES(ctx, 0); _mesa_lock_texture(ctx, texObj); { - texImage = _mesa_select_tex_image(ctx, texObj, target, level); + texImage = _mesa_select_tex_image(texObj, target, level); assert(texImage); if (width > 0 && height > 0 && depth > 0) { @@ -4376,33 +4703,116 @@ compressed_tex_sub_image(GLuint dims, GLenum target, GLint level, void GLAPIENTRY _mesa_CompressedTexSubImage1D(GLenum target, GLint level, GLint xoffset, - GLsizei width, GLenum format, - GLsizei imageSize, const GLvoid *data) + GLsizei width, GLenum format, + GLsizei imageSize, const GLvoid *data) +{ + struct gl_texture_object *texObj; + GET_CURRENT_CONTEXT(ctx); + + texObj = _mesa_get_current_tex_object(ctx, target); + if (!texObj) + return; + + _mesa_compressed_texture_sub_image(ctx, 1, texObj, target, level, + xoffset, 0, 0, width, 1, 1, + format, imageSize, data, false); +} + +void GLAPIENTRY +_mesa_CompressedTextureSubImage1D(GLuint texture, GLint level, GLint xoffset, + GLsizei width, GLenum format, + GLsizei imageSize, const GLvoid *data) { - compressed_tex_sub_image(1, target, level, xoffset, 0, 0, width, 1, 1, - format, imageSize, data); + struct gl_texture_object *texObj; + GET_CURRENT_CONTEXT(ctx); + + texObj = _mesa_lookup_texture_err(ctx, texture, + "glCompressedTextureSubImage1D"); + if (!texObj) + return; + + _mesa_compressed_texture_sub_image(ctx, 1, texObj, texObj->Target, level, + xoffset, 0, 0, width, 1, 1, + format, imageSize, data, true); } void GLAPIENTRY _mesa_CompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, - GLint yoffset, GLsizei width, GLsizei height, - GLenum format, GLsizei imageSize, - const GLvoid *data) + GLint yoffset, GLsizei width, GLsizei height, + GLenum format, GLsizei imageSize, + const GLvoid *data) { - compressed_tex_sub_image(2, target, level, xoffset, yoffset, 0, - width, height, 1, format, imageSize, data); + struct gl_texture_object *texObj; + GET_CURRENT_CONTEXT(ctx); + + texObj = _mesa_get_current_tex_object(ctx, target); + if (!texObj) + return; + + _mesa_compressed_texture_sub_image(ctx, 2, texObj, target, level, + xoffset, yoffset, 0, width, height, 1, + format, imageSize, data, false); } +void GLAPIENTRY +_mesa_CompressedTextureSubImage2D(GLuint texture, GLint level, GLint xoffset, + GLint yoffset, + GLsizei width, GLsizei height, + GLenum format, GLsizei imageSize, + const GLvoid *data) +{ + struct gl_texture_object *texObj; + GET_CURRENT_CONTEXT(ctx); + + texObj = _mesa_lookup_texture_err(ctx, texture, + "glCompressedTextureSubImage2D"); + if (!texObj) + return; + + _mesa_compressed_texture_sub_image(ctx, 2, texObj, texObj->Target, level, + xoffset, yoffset, 0, width, height, 1, + format, imageSize, data, true); +} void GLAPIENTRY _mesa_CompressedTexSubImage3D(GLenum target, GLint level, GLint xoffset, - GLint yoffset, GLint zoffset, GLsizei width, - GLsizei height, GLsizei depth, GLenum format, - GLsizei imageSize, const GLvoid *data) + GLint yoffset, GLint zoffset, GLsizei width, + GLsizei height, GLsizei depth, GLenum format, + GLsizei imageSize, const GLvoid *data) { - compressed_tex_sub_image(3, target, level, xoffset, yoffset, zoffset, - width, height, depth, format, imageSize, data); + struct gl_texture_object *texObj; + GET_CURRENT_CONTEXT(ctx); + + texObj = _mesa_get_current_tex_object(ctx, target); + if (!texObj) + return; + + _mesa_compressed_texture_sub_image(ctx, 3, texObj, target, level, + xoffset, yoffset, zoffset, + width, height, depth, + format, imageSize, data, false); +} + +void GLAPIENTRY +_mesa_CompressedTextureSubImage3D(GLuint texture, GLint level, GLint xoffset, + GLint yoffset, GLint zoffset, GLsizei width, + GLsizei height, GLsizei depth, + GLenum format, GLsizei imageSize, + const GLvoid *data) +{ + struct gl_texture_object *texObj; + GET_CURRENT_CONTEXT(ctx); + + texObj = _mesa_lookup_texture_err(ctx, texture, + "glCompressedTextureSubImage3D"); + if (!texObj) + return; + + _mesa_compressed_texture_sub_image(ctx, 3, texObj, texObj->Target, level, + xoffset, yoffset, zoffset, + width, height, depth, + format, imageSize, data, true); } static mesa_format @@ -4461,9 +4871,9 @@ get_texbuffer_format(const struct gl_context *ctx, GLenum internalFormat) case GL_LUMINANCE_ALPHA8I_EXT: return MESA_FORMAT_LA_SINT8; case GL_LUMINANCE_ALPHA16I_EXT: - return MESA_FORMAT_LA_SINT8; - case GL_LUMINANCE_ALPHA32I_EXT: return MESA_FORMAT_LA_SINT16; + case GL_LUMINANCE_ALPHA32I_EXT: + return MESA_FORMAT_LA_SINT32; case GL_LUMINANCE_ALPHA8UI_EXT: return MESA_FORMAT_LA_UINT8; case GL_LUMINANCE_ALPHA16UI_EXT: @@ -4619,30 +5029,26 @@ _mesa_validate_texbuffer_format(const struct gl_context *ctx, } -static void -texbufferrange(struct gl_context *ctx, GLenum target, GLenum internalFormat, - struct gl_buffer_object *bufObj, - GLintptr offset, GLsizeiptr size) +void +_mesa_texture_buffer_range(struct gl_context *ctx, + struct gl_texture_object *texObj, GLenum target, + GLenum internalFormat, + struct gl_buffer_object *bufObj, + GLintptr offset, GLsizeiptr size, bool range, + bool dsa) { - struct gl_texture_object *texObj; mesa_format format; FLUSH_VERTICES(ctx, 0); - if (target != GL_TEXTURE_BUFFER_ARB) { - _mesa_error(ctx, GL_INVALID_ENUM, "glTexBuffer(target)"); - return; - } - format = _mesa_validate_texbuffer_format(ctx, internalFormat); if (format == MESA_FORMAT_NONE) { - _mesa_error(ctx, GL_INVALID_ENUM, "glTexBuffer(internalFormat 0x%x)", - internalFormat); + _mesa_error(ctx, GL_INVALID_ENUM, + "glTex%sBuffer%s(internalFormat 0x%x)", dsa ? "ture" : "", + range ? "Range" : "", internalFormat); return; } - texObj = _mesa_get_current_tex_object(ctx, target); - _mesa_lock_texture(ctx, texObj); { _mesa_reference_buffer_object(ctx, &texObj->BufferObject, bufObj); @@ -4665,10 +5071,17 @@ texbufferrange(struct gl_context *ctx, GLenum target, GLenum internalFormat, void GLAPIENTRY _mesa_TexBuffer(GLenum target, GLenum internalFormat, GLuint buffer) { + struct gl_texture_object *texObj; struct gl_buffer_object *bufObj; GET_CURRENT_CONTEXT(ctx); + /* Need to catch this before it gets to _mesa_get_current_tex_object */ + if (target != GL_TEXTURE_BUFFER_ARB) { + _mesa_error(ctx, GL_INVALID_ENUM, "glTexBuffer(target)"); + return; + } + /* NOTE: ARB_texture_buffer_object has interactions with * the compatibility profile that are not implemented. */ @@ -4684,7 +5097,12 @@ _mesa_TexBuffer(GLenum target, GLenum internalFormat, GLuint buffer) return; } - texbufferrange(ctx, target, internalFormat, bufObj, 0, buffer ? -1 : 0); + texObj = _mesa_get_current_tex_object(ctx, target); + if (!texObj) + return; + + _mesa_texture_buffer_range(ctx, texObj, target, internalFormat, bufObj, 0, + buffer ? -1 : 0, false, false); } @@ -4693,10 +5111,17 @@ void GLAPIENTRY _mesa_TexBufferRange(GLenum target, GLenum internalFormat, GLuint buffer, GLintptr offset, GLsizeiptr size) { + struct gl_texture_object *texObj; struct gl_buffer_object *bufObj; GET_CURRENT_CONTEXT(ctx); + /* Need to catch this before it gets to _mesa_get_current_tex_object */ + if (target != GL_TEXTURE_BUFFER_ARB) { + _mesa_error(ctx, GL_INVALID_ENUM, "glTexBufferRange(target)"); + return; + } + if (!(ctx->API == API_OPENGL_CORE && ctx->Extensions.ARB_texture_buffer_range)) { _mesa_error(ctx, GL_INVALID_OPERATION, "glTexBufferRange"); @@ -4725,9 +5150,52 @@ _mesa_TexBufferRange(GLenum target, GLenum internalFormat, GLuint buffer, size = 0; } - texbufferrange(ctx, target, internalFormat, bufObj, offset, size); + texObj = _mesa_get_current_tex_object(ctx, target); + if (!texObj) + return; + + _mesa_texture_buffer_range(ctx, texObj, target, internalFormat, bufObj, + offset, size, true, false); } +void GLAPIENTRY +_mesa_TextureBuffer(GLuint texture, GLenum internalFormat, GLuint buffer) +{ + struct gl_texture_object *texObj; + struct gl_buffer_object *bufObj; + + GET_CURRENT_CONTEXT(ctx); + + /* NOTE: ARB_texture_buffer_object has interactions with + * the compatibility profile that are not implemented. + */ + if (!(ctx->API == API_OPENGL_CORE && + ctx->Extensions.ARB_texture_buffer_object)) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glTextureBuffer"); + return; + } + + bufObj = _mesa_lookup_bufferobj(ctx, buffer); + if (!bufObj && buffer) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glTextureBuffer(buffer %u)", + buffer); + return; + } + + /* Get the texture object by Name. */ + texObj = _mesa_lookup_texture_err(ctx, texture, + "glTextureBuffer(texture)"); + if (!texObj) + return; + + if (texObj->Target != GL_TEXTURE_BUFFER_ARB) { + _mesa_error(ctx, GL_INVALID_ENUM, "glTextureBuffer(target)"); + return; + } + + _mesa_texture_buffer_range(ctx, texObj, texObj->Target, internalFormat, + bufObj, 0, buffer ? -1 : 0, false, true); +} static GLboolean is_renderable_texture_format(struct gl_context *ctx, GLenum internalformat) @@ -4742,16 +5210,18 @@ is_renderable_texture_format(struct gl_context *ctx, GLenum internalformat) /** GL_ARB_texture_multisample */ static GLboolean -check_multisample_target(GLuint dims, GLenum target) +check_multisample_target(GLuint dims, GLenum target, bool dsa) { switch(target) { case GL_TEXTURE_2D_MULTISAMPLE: - case GL_PROXY_TEXTURE_2D_MULTISAMPLE: return dims == 2; + case GL_PROXY_TEXTURE_2D_MULTISAMPLE: + return dims == 2 && !dsa; case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: - case GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY: return dims == 3; + case GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY: + return dims == 3 && !dsa; default: return GL_FALSE; @@ -4759,19 +5229,20 @@ check_multisample_target(GLuint dims, GLenum target) } -static void -teximagemultisample(GLuint dims, GLenum target, GLsizei samples, - GLint internalformat, GLsizei width, GLsizei height, - GLsizei depth, GLboolean fixedsamplelocations, - GLboolean immutable, const char *func) +void +_mesa_texture_image_multisample(struct gl_context *ctx, GLuint dims, + struct gl_texture_object *texObj, + GLenum target, GLsizei samples, + GLint internalformat, GLsizei width, + GLsizei height, GLsizei depth, + GLboolean fixedsamplelocations, + GLboolean immutable, const char *func) { - struct gl_texture_object *texObj; struct gl_texture_image *texImage; GLboolean sizeOK, dimensionsOK, samplesOK; mesa_format texFormat; GLenum sample_count_error; - - GET_CURRENT_CONTEXT(ctx); + bool dsa = strstr(func, "ture") ? true : false; if (!(ctx->Extensions.ARB_texture_multisample && _mesa_is_desktop_gl(ctx))) { @@ -4779,9 +5250,15 @@ teximagemultisample(GLuint dims, GLenum target, GLsizei samples, return; } - if (!check_multisample_target(dims, target)) { - _mesa_error(ctx, GL_INVALID_ENUM, "%s(target)", func); - return; + if (!check_multisample_target(dims, target, dsa)) { + if (dsa) { + _mesa_error(ctx, GL_INVALID_OPERATION, "%s(target)", func); + return; + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "%s(target)", func); + return; + } } /* check that the specified internalformat is color/depth/stencil-renderable; @@ -4819,8 +5296,6 @@ teximagemultisample(GLuint dims, GLenum target, GLsizei samples, return; } - texObj = _mesa_get_current_tex_object(ctx, target); - if (immutable && (!texObj || (texObj->Name == 0))) { _mesa_error(ctx, GL_INVALID_OPERATION, "%s(texture object 0)", @@ -4893,7 +5368,7 @@ teximagemultisample(GLuint dims, GLenum target, GLsizei samples, } } - texObj->Immutable = immutable; + texObj->Immutable |= immutable; if (immutable) { _mesa_set_texture_view_state(ctx, texObj, target, 1); @@ -4909,9 +5384,17 @@ _mesa_TexImage2DMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations) { - teximagemultisample(2, target, samples, internalformat, - width, height, 1, fixedsamplelocations, GL_FALSE, - "glTexImage2DMultisample"); + struct gl_texture_object *texObj; + GET_CURRENT_CONTEXT(ctx); + + texObj = _mesa_get_current_tex_object(ctx, target); + if (!texObj) + return; + + _mesa_texture_image_multisample(ctx, 2, texObj, target, samples, + internalformat, width, height, 1, + fixedsamplelocations, GL_FALSE, + "glTexImage2DMultisample"); } @@ -4921,9 +5404,17 @@ _mesa_TexImage3DMultisample(GLenum target, GLsizei samples, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations) { - teximagemultisample(3, target, samples, internalformat, - width, height, depth, fixedsamplelocations, GL_FALSE, - "glTexImage3DMultisample"); + struct gl_texture_object *texObj; + GET_CURRENT_CONTEXT(ctx); + + texObj = _mesa_get_current_tex_object(ctx, target); + if (!texObj) + return; + + _mesa_texture_image_multisample(ctx, 3, texObj, target, samples, + internalformat, width, height, depth, + fixedsamplelocations, GL_FALSE, + "glTexImage3DMultisample"); } @@ -4932,9 +5423,17 @@ _mesa_TexStorage2DMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations) { - teximagemultisample(2, target, samples, internalformat, - width, height, 1, fixedsamplelocations, GL_TRUE, - "glTexStorage2DMultisample"); + struct gl_texture_object *texObj; + GET_CURRENT_CONTEXT(ctx); + + texObj = _mesa_get_current_tex_object(ctx, target); + if (!texObj) + return; + + _mesa_texture_image_multisample(ctx, 2, texObj, target, samples, + internalformat, width, height, 1, + fixedsamplelocations, GL_TRUE, + "glTexStorage2DMultisample"); } void GLAPIENTRY @@ -4943,7 +5442,56 @@ _mesa_TexStorage3DMultisample(GLenum target, GLsizei samples, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations) { - teximagemultisample(3, target, samples, internalformat, - width, height, depth, fixedsamplelocations, GL_TRUE, - "glTexStorage3DMultisample"); + struct gl_texture_object *texObj; + GET_CURRENT_CONTEXT(ctx); + + texObj = _mesa_get_current_tex_object(ctx, target); + if (!texObj) + return; + + _mesa_texture_image_multisample(ctx, 3, texObj, target, samples, + internalformat, width, height, depth, + fixedsamplelocations, GL_TRUE, + "glTexStorage3DMultisample"); +} + +void GLAPIENTRY +_mesa_TextureStorage2DMultisample(GLuint texture, GLsizei samples, + GLenum internalformat, GLsizei width, + GLsizei height, + GLboolean fixedsamplelocations) +{ + struct gl_texture_object *texObj; + GET_CURRENT_CONTEXT(ctx); + + texObj = _mesa_lookup_texture_err(ctx, texture, + "glTextureStorage2DMultisample"); + if (!texObj) + return; + + _mesa_texture_image_multisample(ctx, 2, texObj, texObj->Target, samples, + internalformat, width, height, 1, + fixedsamplelocations, GL_TRUE, + "glTextureStorage2DMultisample"); +} + +void GLAPIENTRY +_mesa_TextureStorage3DMultisample(GLuint texture, GLsizei samples, + GLenum internalformat, GLsizei width, + GLsizei height, GLsizei depth, + GLboolean fixedsamplelocations) +{ + struct gl_texture_object *texObj; + GET_CURRENT_CONTEXT(ctx); + + /* Get the texture object by Name. */ + texObj = _mesa_lookup_texture_err(ctx, texture, + "glTextureStorage3DMultisample"); + if (!texObj) + return; + + _mesa_texture_image_multisample(ctx, 3, texObj, texObj->Target, samples, + internalformat, width, height, depth, + fixedsamplelocations, GL_TRUE, + "glTextureStorage3DMultisample"); } diff --git a/mesalib/src/mesa/main/teximage.h b/mesalib/src/mesa/main/teximage.h index 4b27381a0..02b0eda38 100644 --- a/mesalib/src/mesa/main/teximage.h +++ b/mesalib/src/mesa/main/teximage.h @@ -47,7 +47,7 @@ _mesa_is_cube_face(GLenum target) target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB); } -/** Is any of the dimensions of given texture equal to zero? */ +/** Are any of the dimensions of given texture equal to zero? */ static inline GLboolean _mesa_is_zero_size_texture(const struct gl_texture_image *texImage) { @@ -99,13 +99,8 @@ _mesa_clear_texture_image(struct gl_context *ctx, struct gl_texture_image *texImage); -extern struct gl_texture_object * -_mesa_get_current_tex_object(struct gl_context *ctx, GLenum target); - - extern struct gl_texture_image * -_mesa_select_tex_image(struct gl_context *ctx, - const struct gl_texture_object *texObj, +_mesa_select_tex_image(const struct gl_texture_object *texObj, GLenum target, GLint level); @@ -114,6 +109,16 @@ _mesa_get_tex_image(struct gl_context *ctx, struct gl_texture_object *texObj, GLenum target, GLint level); +/** + * Return the base-level texture image for the given texture object. + */ +static inline const struct gl_texture_image * +_mesa_base_tex_image(const struct gl_texture_object *texObj) +{ + return texObj->Image[0][texObj->BaseLevel]; +} + + extern GLint _mesa_max_texture_levels(struct gl_context *ctx, GLenum target); @@ -160,24 +165,51 @@ _mesa_legal_texture_base_format_for_target(struct gl_context *ctx, unsigned dimensions, const char *caller); -/** - * Lock a texture for updating. See also _mesa_lock_context_textures(). - */ -static inline void -_mesa_lock_texture(struct gl_context *ctx, struct gl_texture_object *texObj) -{ - mtx_lock(&ctx->Shared->TexMutex); - ctx->Shared->TextureStateStamp++; - (void) texObj; -} +extern void +_mesa_texture_sub_image(struct gl_context *ctx, GLuint dims, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage, + GLenum target, GLint level, + GLint xoffset, GLint yoffset, GLint zoffset, + GLsizei width, GLsizei height, GLsizei depth, + GLenum format, GLenum type, const GLvoid *pixels, + bool dsa); -static inline void -_mesa_unlock_texture(struct gl_context *ctx, struct gl_texture_object *texObj) -{ - (void) texObj; - mtx_unlock(&ctx->Shared->TexMutex); -} +extern void +_mesa_compressed_texture_sub_image(struct gl_context *ctx, GLuint dims, + struct gl_texture_object *texObj, + GLenum target, GLint level, + GLint xoffset, GLint yoffset, + GLint zoffset, + GLsizei width, GLsizei height, + GLsizei depth, + GLenum format, GLsizei imageSize, + const GLvoid *data, bool dsa); + +extern void +_mesa_copy_texture_sub_image(struct gl_context *ctx, GLuint dims, + struct gl_texture_object *texObj, + GLenum target, GLint level, + GLint xoffset, GLint yoffset, GLint zoffset, + GLint x, GLint y, + GLsizei width, GLsizei height, bool dsa); + +extern void +_mesa_texture_image_multisample(struct gl_context *ctx, GLuint dims, + struct gl_texture_object *texObj, + GLenum target, GLsizei samples, + GLint internalformat, GLsizei width, + GLsizei height, GLsizei depth, + GLboolean fixedsamplelocations, + GLboolean immutable, const char *func); +extern void +_mesa_texture_buffer_range(struct gl_context *ctx, + struct gl_texture_object *texObj, GLenum target, + GLenum internalFormat, + struct gl_buffer_object *bufObj, + GLintptr offset, GLsizeiptr size, bool range, + bool dsa); /*@}*/ @@ -233,10 +265,31 @@ _mesa_TexSubImage3D( GLenum target, GLint level, GLenum format, GLenum type, const GLvoid *pixels ); +extern void GLAPIENTRY +_mesa_TextureSubImage1D(GLuint texture, GLint level, GLint xoffset, + GLsizei width, + GLenum format, GLenum type, + const GLvoid *pixels); + extern void GLAPIENTRY -_mesa_CopyTexImage1D( GLenum target, GLint level, GLenum internalformat, - GLint x, GLint y, GLsizei width, GLint border ); +_mesa_TextureSubImage2D(GLuint texture, GLint level, + GLint xoffset, GLint yoffset, + GLsizei width, GLsizei height, + GLenum format, GLenum type, + const GLvoid *pixels); + +extern void GLAPIENTRY +_mesa_TextureSubImage3D(GLuint texture, GLint level, + GLint xoffset, GLint yoffset, GLint zoffset, + GLsizei width, GLsizei height, GLsizei depth, + GLenum format, GLenum type, + const GLvoid *pixels); + + +extern void GLAPIENTRY +_mesa_CopyTexImage1D(GLenum target, GLint level, GLenum internalformat, + GLint x, GLint y, GLsizei width, GLint border); extern void GLAPIENTRY @@ -261,7 +314,21 @@ _mesa_CopyTexSubImage3D( GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height ); +extern void GLAPIENTRY +_mesa_CopyTextureSubImage1D(GLuint texture, GLint level, + GLint xoffset, GLint x, GLint y, GLsizei width); +extern void GLAPIENTRY +_mesa_CopyTextureSubImage2D(GLuint texture, GLint level, + GLint xoffset, GLint yoffset, + GLint x, GLint y, + GLsizei width, GLsizei height); + +extern void GLAPIENTRY +_mesa_CopyTextureSubImage3D(GLuint texture, GLint level, + GLint xoffset, GLint yoffset, GLint zoffset, + GLint x, GLint y, + GLsizei width, GLsizei height); extern void GLAPIENTRY _mesa_ClearTexSubImage( GLuint texture, GLint level, @@ -296,18 +363,37 @@ _mesa_CompressedTexSubImage1D(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *data); +extern void GLAPIENTRY +_mesa_CompressedTextureSubImage1D(GLuint texture, GLint level, GLint xoffset, + GLsizei width, GLenum format, + GLsizei imageSize, const GLvoid *data); + extern void GLAPIENTRY _mesa_CompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data); +extern void GLAPIENTRY +_mesa_CompressedTextureSubImage2D(GLuint texture, GLint level, GLint xoffset, + GLint yoffset, + GLsizei width, GLsizei height, + GLenum format, GLsizei imageSize, + const GLvoid *data); + extern void GLAPIENTRY _mesa_CompressedTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *data); +extern void GLAPIENTRY +_mesa_CompressedTextureSubImage3D(GLuint texture, GLint level, GLint xoffset, + GLint yoffset, GLint zoffset, + GLsizei width, GLsizei height, + GLsizei depth, + GLenum format, GLsizei imageSize, + const GLvoid *data); extern void GLAPIENTRY _mesa_TexBuffer(GLenum target, GLenum internalFormat, GLuint buffer); @@ -316,6 +402,9 @@ extern void GLAPIENTRY _mesa_TexBufferRange(GLenum target, GLenum internalFormat, GLuint buffer, GLintptr offset, GLsizeiptr size); +extern void GLAPIENTRY +_mesa_TextureBuffer(GLuint texture, GLenum internalFormat, GLuint buffer); + extern void GLAPIENTRY _mesa_TexImage2DMultisample(GLenum target, GLsizei samples, @@ -339,6 +428,17 @@ _mesa_TexStorage3DMultisample(GLenum target, GLsizei samples, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations); +void GLAPIENTRY +_mesa_TextureStorage2DMultisample(GLuint texture, GLsizei samples, + GLenum internalformat, GLsizei width, + GLsizei height, + GLboolean fixedsamplelocations); + +void GLAPIENTRY +_mesa_TextureStorage3DMultisample(GLuint texture, GLsizei samples, + GLenum internalformat, GLsizei width, + GLsizei height, GLsizei depth, + GLboolean fixedsamplelocations); /*@}*/ #ifdef __cplusplus diff --git a/mesalib/src/mesa/main/texobj.c b/mesalib/src/mesa/main/texobj.c index 923cf60d7..59090db4e 100644 --- a/mesalib/src/mesa/main/texobj.c +++ b/mesalib/src/mesa/main/texobj.c @@ -49,6 +49,54 @@ /** \name Internal functions */ /*@{*/ +/** + * This function checks for all valid combinations of Min and Mag filters for + * Float types, when extensions like OES_texture_float and + * OES_texture_float_linear are supported. OES_texture_float mentions support + * for NEAREST, NEAREST_MIPMAP_NEAREST magnification and minification filters. + * Mag filters like LINEAR and min filters like NEAREST_MIPMAP_LINEAR, + * LINEAR_MIPMAP_NEAREST and LINEAR_MIPMAP_LINEAR are only valid in case + * OES_texture_float_linear is supported. + * + * Returns true in case the filter is valid for given Float type else false. + */ +static bool +valid_filter_for_float(const struct gl_context *ctx, + const struct gl_texture_object *obj) +{ + switch (obj->Sampler.MagFilter) { + case GL_LINEAR: + if (obj->_IsHalfFloat && !ctx->Extensions.OES_texture_half_float_linear) { + return false; + } else if (obj->_IsFloat && !ctx->Extensions.OES_texture_float_linear) { + return false; + } + case GL_NEAREST: + case GL_NEAREST_MIPMAP_NEAREST: + break; + default: + unreachable("Invalid mag filter"); + } + + switch (obj->Sampler.MinFilter) { + case GL_LINEAR: + case GL_NEAREST_MIPMAP_LINEAR: + case GL_LINEAR_MIPMAP_NEAREST: + case GL_LINEAR_MIPMAP_LINEAR: + if (obj->_IsHalfFloat && !ctx->Extensions.OES_texture_half_float_linear) { + return false; + } else if (obj->_IsFloat && !ctx->Extensions.OES_texture_float_linear) { + return false; + } + case GL_NEAREST: + case GL_NEAREST_MIPMAP_NEAREST: + break; + default: + unreachable("Invalid min filter"); + } + + return true; +} /** * Return the gl_texture_object for a given ID. @@ -60,6 +108,22 @@ _mesa_lookup_texture(struct gl_context *ctx, GLuint id) _mesa_HashLookup(ctx->Shared->TexObjects, id); } +/** + * Wrapper around _mesa_lookup_texture that throws GL_INVALID_OPERATION if id + * is not in the hash table. After calling _mesa_error, it returns NULL. + */ +struct gl_texture_object * +_mesa_lookup_texture_err(struct gl_context *ctx, GLuint id, const char* func) +{ + struct gl_texture_object *texObj; + + texObj = _mesa_lookup_texture(ctx, id); /* Returns NULL if not found. */ + + if (!texObj) + _mesa_error(ctx, GL_INVALID_OPERATION, "%s(texture)", func); + + return texObj; +} void _mesa_begin_texture_lookups(struct gl_context *ctx) @@ -82,6 +146,87 @@ _mesa_lookup_texture_locked(struct gl_context *ctx, GLuint id) _mesa_HashLookupLocked(ctx->Shared->TexObjects, id); } +/** + * Return a pointer to the current texture object for the given target + * on the current texture unit. + * Note: all error checking should have been done by this point. + */ +struct gl_texture_object * +_mesa_get_current_tex_object(struct gl_context *ctx, GLenum target) +{ + struct gl_texture_unit *texUnit = _mesa_get_current_tex_unit(ctx); + const GLboolean arrayTex = ctx->Extensions.EXT_texture_array; + + switch (target) { + case GL_TEXTURE_1D: + return texUnit->CurrentTex[TEXTURE_1D_INDEX]; + case GL_PROXY_TEXTURE_1D: + return ctx->Texture.ProxyTex[TEXTURE_1D_INDEX]; + case GL_TEXTURE_2D: + return texUnit->CurrentTex[TEXTURE_2D_INDEX]; + case GL_PROXY_TEXTURE_2D: + return ctx->Texture.ProxyTex[TEXTURE_2D_INDEX]; + case GL_TEXTURE_3D: + return texUnit->CurrentTex[TEXTURE_3D_INDEX]; + case GL_PROXY_TEXTURE_3D: + return ctx->Texture.ProxyTex[TEXTURE_3D_INDEX]; + case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB: + case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB: + case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB: + case GL_TEXTURE_CUBE_MAP_ARB: + return ctx->Extensions.ARB_texture_cube_map + ? texUnit->CurrentTex[TEXTURE_CUBE_INDEX] : NULL; + case GL_PROXY_TEXTURE_CUBE_MAP_ARB: + return ctx->Extensions.ARB_texture_cube_map + ? ctx->Texture.ProxyTex[TEXTURE_CUBE_INDEX] : NULL; + case GL_TEXTURE_CUBE_MAP_ARRAY: + return ctx->Extensions.ARB_texture_cube_map_array + ? texUnit->CurrentTex[TEXTURE_CUBE_ARRAY_INDEX] : NULL; + case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY: + return ctx->Extensions.ARB_texture_cube_map_array + ? ctx->Texture.ProxyTex[TEXTURE_CUBE_ARRAY_INDEX] : NULL; + case GL_TEXTURE_RECTANGLE_NV: + return ctx->Extensions.NV_texture_rectangle + ? texUnit->CurrentTex[TEXTURE_RECT_INDEX] : NULL; + case GL_PROXY_TEXTURE_RECTANGLE_NV: + return ctx->Extensions.NV_texture_rectangle + ? ctx->Texture.ProxyTex[TEXTURE_RECT_INDEX] : NULL; + case GL_TEXTURE_1D_ARRAY_EXT: + return arrayTex ? texUnit->CurrentTex[TEXTURE_1D_ARRAY_INDEX] : NULL; + case GL_PROXY_TEXTURE_1D_ARRAY_EXT: + return arrayTex ? ctx->Texture.ProxyTex[TEXTURE_1D_ARRAY_INDEX] : NULL; + case GL_TEXTURE_2D_ARRAY_EXT: + return arrayTex ? texUnit->CurrentTex[TEXTURE_2D_ARRAY_INDEX] : NULL; + case GL_PROXY_TEXTURE_2D_ARRAY_EXT: + return arrayTex ? ctx->Texture.ProxyTex[TEXTURE_2D_ARRAY_INDEX] : NULL; + case GL_TEXTURE_BUFFER: + return ctx->API == API_OPENGL_CORE && + ctx->Extensions.ARB_texture_buffer_object ? + texUnit->CurrentTex[TEXTURE_BUFFER_INDEX] : NULL; + case GL_TEXTURE_EXTERNAL_OES: + return _mesa_is_gles(ctx) && ctx->Extensions.OES_EGL_image_external + ? texUnit->CurrentTex[TEXTURE_EXTERNAL_INDEX] : NULL; + case GL_TEXTURE_2D_MULTISAMPLE: + return ctx->Extensions.ARB_texture_multisample + ? texUnit->CurrentTex[TEXTURE_2D_MULTISAMPLE_INDEX] : NULL; + case GL_PROXY_TEXTURE_2D_MULTISAMPLE: + return ctx->Extensions.ARB_texture_multisample + ? ctx->Texture.ProxyTex[TEXTURE_2D_MULTISAMPLE_INDEX] : NULL; + case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: + return ctx->Extensions.ARB_texture_multisample + ? texUnit->CurrentTex[TEXTURE_2D_MULTISAMPLE_ARRAY_INDEX] : NULL; + case GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY: + return ctx->Extensions.ARB_texture_multisample + ? ctx->Texture.ProxyTex[TEXTURE_2D_MULTISAMPLE_ARRAY_INDEX] : NULL; + default: + _mesa_problem(NULL, "bad target in _mesa_get_current_tex_object()"); + return NULL; + } +} + /** * Allocate and initialize a new texture object. But don't put it into the @@ -89,7 +234,7 @@ _mesa_lookup_texture_locked(struct gl_context *ctx, GLuint id) * * Called via ctx->Driver.NewTextureObject, unless overridden by a device * driver. - * + * * \param shared the shared GL state structure to contain the texture object * \param name integer name for the texture object * \param target either GL_TEXTURE_1D, GL_TEXTURE_2D, GL_TEXTURE_3D, @@ -268,7 +413,6 @@ _mesa_delete_texture_object(struct gl_context *ctx, } - /** * Copy texture object state from one texture object to another. * Use for glPush/PopAttrib. @@ -312,6 +456,8 @@ _mesa_copy_texture_object( struct gl_texture_object *dest, dest->_MipmapComplete = src->_MipmapComplete; COPY_4V(dest->Swizzle, src->Swizzle); dest->_Swizzle = src->_Swizzle; + dest->_IsHalfFloat = src->_IsHalfFloat; + dest->_IsFloat = src->_IsFloat; dest->RequiredTextureImageUnits = src->RequiredTextureImageUnits; } @@ -406,6 +552,9 @@ _mesa_reference_texobj_(struct gl_texture_object **ptr, mtx_unlock(&oldTex->Mutex); if (deleteFlag) { + /* Passing in the context drastically changes the driver code for + * framebuffer deletion. + */ GET_CURRENT_CONTEXT(ctx); if (ctx) ctx->Driver.DeleteTexture(ctx, oldTex); @@ -542,6 +691,14 @@ _mesa_test_texobj_completeness( const struct gl_context *ctx, t->_IsIntegerFormat = datatype == GL_INT || datatype == GL_UNSIGNED_INT; } + /* Check if the texture type is Float or HalfFloatOES and ensure Min and Mag + * filters are supported in this case. + */ + if (_mesa_is_gles(ctx) && !valid_filter_for_float(ctx, t)) { + incomplete(t, BASE, "Filter is not supported with Float types."); + return; + } + /* Compute _MaxLevel (the maximum mipmap level we'll sample from given the * mipmap image sizes and GL_TEXTURE_MAX_LEVEL state). */ @@ -653,7 +810,8 @@ _mesa_test_texobj_completeness( const struct gl_context *ctx, if (height > 1 && t->Target != GL_TEXTURE_1D_ARRAY) { height /= 2; } - if (depth > 1 && t->Target != GL_TEXTURE_2D_ARRAY && t->Target != GL_TEXTURE_CUBE_MAP_ARRAY) { + if (depth > 1 && t->Target != GL_TEXTURE_2D_ARRAY + && t->Target != GL_TEXTURE_CUBE_MAP_ARRAY) { depth /= 2; } @@ -675,22 +833,25 @@ _mesa_test_texobj_completeness( const struct gl_context *ctx, return; } if (img->Width2 != width) { - incomplete(t, MIPMAP, "TexImage[%d] bad width %u", i, img->Width2); + incomplete(t, MIPMAP, "TexImage[%d] bad width %u", i, + img->Width2); return; } if (img->Height2 != height) { - incomplete(t, MIPMAP, "TexImage[%d] bad height %u", i, img->Height2); + incomplete(t, MIPMAP, "TexImage[%d] bad height %u", i, + img->Height2); return; } if (img->Depth2 != depth) { - incomplete(t, MIPMAP, "TexImage[%d] bad depth %u", i, img->Depth2); + incomplete(t, MIPMAP, "TexImage[%d] bad depth %u", i, + img->Depth2); return; } /* Extra checks for cube textures */ if (face > 0) { /* check that cube faces are the same size */ - if (img->Width2 != t->Image[0][i]->Width2 || + if (img->Width2 != t->Image[0][i]->Width2 || img->Height2 != t->Image[0][i]->Height2) { incomplete(t, MIPMAP, "CubeMap Image[n][i] bad size"); return; @@ -698,7 +859,7 @@ _mesa_test_texobj_completeness( const struct gl_context *ctx, } } } - + if (width == 1 && height == 1 && depth == 1) { return; /* found smallest needed mipmap, all done! */ } @@ -707,25 +868,21 @@ _mesa_test_texobj_completeness( const struct gl_context *ctx, } -/** - * Check if the given cube map texture is "cube complete" as defined in - * the OpenGL specification. - */ GLboolean -_mesa_cube_complete(const struct gl_texture_object *texObj) +_mesa_cube_level_complete(const struct gl_texture_object *texObj, + const GLint level) { - const GLint baseLevel = texObj->BaseLevel; const struct gl_texture_image *img0, *img; GLuint face; if (texObj->Target != GL_TEXTURE_CUBE_MAP) return GL_FALSE; - if ((baseLevel < 0) || (baseLevel >= MAX_TEXTURE_LEVELS)) + if ((level < 0) || (level >= MAX_TEXTURE_LEVELS)) return GL_FALSE; /* check first face */ - img0 = texObj->Image[0][baseLevel]; + img0 = texObj->Image[0][level]; if (!img0 || img0->Width < 1 || img0->Width != img0->Height) @@ -733,7 +890,7 @@ _mesa_cube_complete(const struct gl_texture_object *texObj) /* check remaining faces vs. first face */ for (face = 1; face < 6; face++) { - img = texObj->Image[face][baseLevel]; + img = texObj->Image[face][level]; if (!img || img->Width != img0->Width || img->Height != img0->Height || @@ -744,6 +901,15 @@ _mesa_cube_complete(const struct gl_texture_object *texObj) return GL_TRUE; } +/** + * Check if the given cube map texture is "cube complete" as defined in + * the OpenGL specification. + */ +GLboolean +_mesa_cube_complete(const struct gl_texture_object *texObj) +{ + return _mesa_cube_level_complete(texObj, texObj->BaseLevel); +} /** * Mark a texture object dirty. It forces the object to be incomplete @@ -950,6 +1116,21 @@ _mesa_total_texture_memory(struct gl_context *ctx) return total; } + +/** + * Return the base format for the given texture object by looking + * at the base texture image. + * \return base format (such as GL_RGBA) or GL_NONE if it can't be determined + */ +GLenum +_mesa_texture_base_format(const struct gl_texture_object *texObj) +{ + const struct gl_texture_image *texImage = _mesa_base_tex_image(texObj); + + return texImage ? texImage->_BaseFormat : GL_NONE; +} + + static struct gl_texture_object * invalidate_tex_image_error_check(struct gl_context *ctx, GLuint texture, GLint level, const char *name) @@ -1003,38 +1184,46 @@ invalidate_tex_image_error_check(struct gl_context *ctx, GLuint texture, return t; } -/*@}*/ +/** + * Wrapper for the driver function. Need this because _mesa_new_texture_object + * permits a target of 0 and does not initialize targetIndex. + */ +struct gl_texture_object * +_mesa_create_nameless_texture(struct gl_context *ctx, GLenum target) +{ + struct gl_texture_object *texObj = NULL; + GLint targetIndex; + if (target == 0) + return texObj; -/***********************************************************************/ -/** \name API functions */ -/*@{*/ + texObj = ctx->Driver.NewTextureObject(ctx, 0, target); + targetIndex = _mesa_tex_target_to_index(ctx, texObj->Target); + assert(targetIndex < NUM_TEXTURE_TARGETS); + texObj->TargetIndex = targetIndex; + return texObj; +} /** - * Generate texture names. - * - * \param n number of texture names to be generated. - * \param textures an array in which will hold the generated texture names. - * - * \sa glGenTextures(). - * - * Calls _mesa_HashFindFreeKeyBlock() to find a block of free texture - * IDs which are stored in \p textures. Corresponding empty texture - * objects are also generated. - */ -void GLAPIENTRY -_mesa_GenTextures( GLsizei n, GLuint *textures ) + * Helper function for glCreateTextures and glGenTextures. Need this because + * glCreateTextures should throw errors if target = 0. This is not exposed to + * the rest of Mesa to encourage Mesa internals to use nameless textures, + * which do not require expensive hash lookups. + */ +static void +create_textures(struct gl_context *ctx, GLenum target, + GLsizei n, GLuint *textures, bool dsa) { - GET_CURRENT_CONTEXT(ctx); GLuint first; GLint i; + const char *func = dsa ? "Create" : "Gen"; if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) - _mesa_debug(ctx, "glGenTextures %d\n", n); + _mesa_debug(ctx, "gl%sTextures %d\n", func, n); if (n < 0) { - _mesa_error( ctx, GL_INVALID_VALUE, "glGenTextures" ); + _mesa_error( ctx, GL_INVALID_VALUE, "gl%sTextures(n < 0)", func ); return; } @@ -1051,15 +1240,28 @@ _mesa_GenTextures( GLsizei n, GLuint *textures ) /* Allocate new, empty texture objects */ for (i = 0; i < n; i++) { struct gl_texture_object *texObj; + GLint targetIndex; GLuint name = first + i; - GLenum target = 0; texObj = ctx->Driver.NewTextureObject(ctx, name, target); if (!texObj) { mtx_unlock(&ctx->Shared->Mutex); - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGenTextures"); + _mesa_error(ctx, GL_OUT_OF_MEMORY, "gl%sTextures", func); return; } + /* Initialize the target index if target is non-zero. */ + if (target != 0) { + targetIndex = _mesa_tex_target_to_index(ctx, texObj->Target); + if (targetIndex < 0) { /* Bad Target */ + mtx_unlock(&ctx->Shared->Mutex); + _mesa_error(ctx, GL_INVALID_ENUM, "gl%sTextures(target = %s)", + func, _mesa_lookup_enum_by_nr(texObj->Target)); + return; + } + assert(targetIndex < NUM_TEXTURE_TARGETS); + texObj->TargetIndex = targetIndex; + } + /* insert into hash table */ _mesa_HashInsert(ctx->Shared->TexObjects, texObj->Name, texObj); @@ -1069,6 +1271,65 @@ _mesa_GenTextures( GLsizei n, GLuint *textures ) mtx_unlock(&ctx->Shared->Mutex); } +/*@}*/ + + +/***********************************************************************/ +/** \name API functions */ +/*@{*/ + + +/** + * Generate texture names. + * + * \param n number of texture names to be generated. + * \param textures an array in which will hold the generated texture names. + * + * \sa glGenTextures(), glCreateTextures(). + * + * Calls _mesa_HashFindFreeKeyBlock() to find a block of free texture + * IDs which are stored in \p textures. Corresponding empty texture + * objects are also generated. + */ +void GLAPIENTRY +_mesa_GenTextures(GLsizei n, GLuint *textures) +{ + GET_CURRENT_CONTEXT(ctx); + create_textures(ctx, 0, n, textures, false); +} + +/** + * Create texture objects. + * + * \param target the texture target for each name to be generated. + * \param n number of texture names to be generated. + * \param textures an array in which will hold the generated texture names. + * + * \sa glCreateTextures(), glGenTextures(). + * + * Calls _mesa_HashFindFreeKeyBlock() to find a block of free texture + * IDs which are stored in \p textures. Corresponding empty texture + * objects are also generated. + */ +void GLAPIENTRY +_mesa_CreateTextures(GLenum target, GLsizei n, GLuint *textures) +{ + GLint targetIndex; + GET_CURRENT_CONTEXT(ctx); + + /* + * The 4.5 core profile spec (30.10.2014) doesn't specify what + * glCreateTextures should do with invalid targets, which was probably an + * oversight. This conforms to the spec for glBindTexture. + */ + targetIndex = _mesa_tex_target_to_index(ctx, target); + if (targetIndex < 0) { + _mesa_error(ctx, GL_INVALID_ENUM, "glCreateTextures(target)"); + return; + } + + create_textures(ctx, target, n, textures, true); +} /** * Check if the given texture object is bound to the current draw or @@ -1155,6 +1416,7 @@ unbind_texobj_from_image_units(struct gl_context *ctx, } } + /** * Unbinds all textures bound to the given texture image unit. */ @@ -1178,6 +1440,7 @@ unbind_textures_from_unit(struct gl_context *ctx, GLuint unit) } } + /** * Delete named textures. * @@ -1201,8 +1464,18 @@ _mesa_DeleteTextures( GLsizei n, const GLuint *textures) if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) _mesa_debug(ctx, "glDeleteTextures %d\n", n); + if (n < 0) { + _mesa_error(ctx, GL_INVALID_VALUE, "glDeleteTextures(n < 0)"); + return; + } + FLUSH_VERTICES(ctx, 0); /* too complex */ + if (n < 0) { + _mesa_error(ctx, GL_INVALID_VALUE, "glDeleteTextures(n)"); + return; + } + if (!textures) return; @@ -1251,6 +1524,47 @@ _mesa_DeleteTextures( GLsizei n, const GLuint *textures) } } +/** + * This deletes a texObj without altering the hash table. + */ +void +_mesa_delete_nameless_texture(struct gl_context *ctx, + struct gl_texture_object *texObj) +{ + if (!texObj) + return; + + FLUSH_VERTICES(ctx, 0); + + _mesa_lock_texture(ctx, texObj); + { + /* Check if texture is bound to any framebuffer objects. + * If so, unbind. + * See section 4.4.2.3 of GL_EXT_framebuffer_object. + */ + unbind_texobj_from_fbo(ctx, texObj); + + /* Check if this texture is currently bound to any texture units. + * If so, unbind it. + */ + unbind_texobj_from_texunits(ctx, texObj); + + /* Check if this texture is currently bound to any shader + * image unit. If so, unbind it. + * See section 3.9.X of GL_ARB_shader_image_load_store. + */ + unbind_texobj_from_image_units(ctx, texObj); + } + _mesa_unlock_texture(ctx, texObj); + + ctx->NewState |= _NEW_TEXTURE; + + /* Unreference the texobj. If refcount hits zero, the texture + * will be deleted. + */ + _mesa_reference_texobj(&texObj, NULL); +} + /** * Convert a GL texture target enum such as GL_TEXTURE_2D or GL_TEXTURE_3D @@ -1305,10 +1619,10 @@ _mesa_tex_target_to_index(const struct gl_context *ctx, GLenum target) /** * Bind a named texture to a texturing target. - * + * * \param target texture target. * \param texName texture name. - * + * * \sa glBindTexture(). * * Determines the old texture object bound and returns immediately if rebinding @@ -1350,7 +1664,9 @@ _mesa_BindTexture( GLenum target, GLuint texName ) if (newTexObj) { /* error checking */ if (newTexObj->Target != 0 && newTexObj->Target != target) { - /* the named texture object's target doesn't match the given target */ + /* The named texture object's target doesn't match the + * given target + */ _mesa_error( ctx, GL_INVALID_OPERATION, "glBindTexture(target mismatch)" ); return; @@ -1361,7 +1677,8 @@ _mesa_BindTexture( GLenum target, GLuint texName ) } else { if (ctx->API == API_OPENGL_CORE) { - _mesa_error(ctx, GL_INVALID_OPERATION, "glBindTexture(non-gen name)"); + _mesa_error(ctx, GL_INVALID_OPERATION, + "glBindTexture(non-gen name)"); return; } @@ -1419,6 +1736,107 @@ _mesa_BindTexture( GLenum target, GLuint texName ) ctx->Driver.BindTexture(ctx, ctx->Texture.CurrentUnit, target, newTexObj); } +/** + * Do the actual binding to a numbered texture unit. + * The refcount on the previously bound + * texture object will be decremented. It'll be deleted if the + * count hits zero. + */ +void +_mesa_bind_texture_unit(struct gl_context *ctx, + GLuint unit, + struct gl_texture_object *texObj) +{ + struct gl_texture_unit *texUnit; + + /* Get the texture unit (this is an array look-up) */ + texUnit = _mesa_get_tex_unit_err(ctx, unit, "glBindTextureUnit"); + if (!texUnit) + return; + + /* Check if this texture is only used by this context and is already bound. + * If so, just return. + */ + { + bool early_out; + mtx_lock(&ctx->Shared->Mutex); + early_out = ((ctx->Shared->RefCount == 1) + && (texObj == texUnit->CurrentTex[texObj->TargetIndex])); + mtx_unlock(&ctx->Shared->Mutex); + if (early_out) { + return; + } + } + + /* flush before changing binding */ + FLUSH_VERTICES(ctx, _NEW_TEXTURE); + + _mesa_reference_texobj(&texUnit->CurrentTex[texObj->TargetIndex], + texObj); + ASSERT(texUnit->CurrentTex[texObj->TargetIndex]); + ctx->Texture.NumCurrentTexUsed = MAX2(ctx->Texture.NumCurrentTexUsed, + unit + 1); + texUnit->_BoundTextures |= (1 << texObj->TargetIndex); + + + /* Pass BindTexture call to device driver */ + if (ctx->Driver.BindTexture) { + ctx->Driver.BindTexture(ctx, unit, texObj->Target, texObj); + } +} + +/** + * Bind a named texture to the specified texture unit. + * + * \param unit texture unit. + * \param texture texture name. + * + * \sa glBindTexture(). + * + * If the named texture is 0, this will reset each target for the specified + * texture unit to its default texture. + * If the named texture is not 0 or a recognized texture name, this throws + * GL_INVALID_OPERATION. + */ +void GLAPIENTRY +_mesa_BindTextureUnit(GLuint unit, GLuint texture) +{ + GET_CURRENT_CONTEXT(ctx); + struct gl_texture_object *texObj; + + if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) + _mesa_debug(ctx, "glBindTextureUnit %s %d\n", + _mesa_lookup_enum_by_nr(GL_TEXTURE0+unit), (GLint) texture); + + /* Section 8.1 (Texture Objects) of the OpenGL 4.5 core profile spec + * (20141030) says: + * "When texture is zero, each of the targets enumerated at the + * beginning of this section is reset to its default texture for the + * corresponding texture image unit." + */ + if (texture == 0) { + unbind_textures_from_unit(ctx, unit); + return; + } + + /* Get the non-default texture object */ + texObj = _mesa_lookup_texture(ctx, texture); + + /* Error checking */ + if (!texObj) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glBindTextureUnit(non-gen name)"); + return; + } + if (texObj->Target == 0) { + _mesa_error(ctx, GL_INVALID_ENUM, "glBindTextureUnit(target)"); + return; + } + assert(valid_texture_object(texObj)); + + _mesa_bind_texture_unit(ctx, unit, texObj); +} + void GLAPIENTRY _mesa_BindTextures(GLuint first, GLsizei count, const GLuint *textures) @@ -1526,13 +1944,13 @@ _mesa_BindTextures(GLuint first, GLsizei count, const GLuint *textures) /** * Set texture priorities. - * + * * \param n number of textures. * \param texName texture names. * \param priorities corresponding texture priorities. - * + * * \sa glPrioritizeTextures(). - * + * * Looks up each texture in the hash, clamps the corresponding priority between * 0.0 and 1.0, and calls dd_function_table::PrioritizeTexture. */ @@ -1572,13 +1990,14 @@ _mesa_PrioritizeTextures( GLsizei n, const GLuint *texName, /** * See if textures are loaded in texture memory. - * + * * \param n number of textures to query. * \param texName array with the texture names. * \param residences array which will hold the residence status. * - * \return GL_TRUE if all textures are resident and \p residences is left unchanged, - * + * \return GL_TRUE if all textures are resident and + * residences is left unchanged, + * * Note: we assume all textures are always resident */ GLboolean GLAPIENTRY @@ -1614,7 +2033,7 @@ _mesa_AreTexturesResident(GLsizei n, const GLuint *texName, return GL_FALSE; } } - + return allResident; } @@ -1626,7 +2045,7 @@ _mesa_AreTexturesResident(GLsizei n, const GLuint *texName, * * \return GL_TRUE if texture name corresponds to a texture, or GL_FALSE * otherwise. - * + * * \sa glIsTexture(). * * Calls _mesa_HashLookup(). @@ -1681,6 +2100,7 @@ _mesa_unlock_context_textures( struct gl_context *ctx ) mtx_unlock(&ctx->Shared->TexMutex); } + void GLAPIENTRY _mesa_InvalidateTexSubImage(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, @@ -1827,6 +2247,7 @@ _mesa_InvalidateTexSubImage(GLuint texture, GLint level, GLint xoffset, return; } + void GLAPIENTRY _mesa_InvalidateTexImage(GLuint texture, GLint level) { diff --git a/mesalib/src/mesa/main/texobj.h b/mesalib/src/mesa/main/texobj.h index b1b7a3027..ec5ccb276 100644 --- a/mesalib/src/mesa/main/texobj.h +++ b/mesalib/src/mesa/main/texobj.h @@ -38,6 +38,11 @@ #include "samplerobj.h" +#ifdef __cplusplus +extern "C" { +#endif + + /** * \name Internal functions */ @@ -46,6 +51,9 @@ extern struct gl_texture_object * _mesa_lookup_texture(struct gl_context *ctx, GLuint id); +extern struct gl_texture_object * +_mesa_lookup_texture_err(struct gl_context *ctx, GLuint id, const char* func); + extern void _mesa_begin_texture_lookups(struct gl_context *ctx); @@ -55,6 +63,9 @@ _mesa_end_texture_lookups(struct gl_context *ctx); extern struct gl_texture_object * _mesa_lookup_texture_locked(struct gl_context *ctx, GLuint id); +extern struct gl_texture_object * +_mesa_get_current_tex_object(struct gl_context *ctx, GLenum target); + extern struct gl_texture_object * _mesa_new_texture_object( struct gl_context *ctx, GLuint name, GLenum target ); @@ -90,6 +101,24 @@ _mesa_reference_texobj(struct gl_texture_object **ptr, _mesa_reference_texobj_(ptr, tex); } +/** + * Lock a texture for updating. See also _mesa_lock_context_textures(). + */ +static inline void +_mesa_lock_texture(struct gl_context *ctx, struct gl_texture_object *texObj) +{ + mtx_lock(&ctx->Shared->TexMutex); + ctx->Shared->TextureStateStamp++; + (void) texObj; +} + +static inline void +_mesa_unlock_texture(struct gl_context *ctx, struct gl_texture_object *texObj) +{ + (void) texObj; + mtx_unlock(&ctx->Shared->TexMutex); +} + /** * Return number of faces for a texture target. This will be 6 for @@ -148,6 +177,10 @@ extern void _mesa_test_texobj_completeness( const struct gl_context *ctx, struct gl_texture_object *obj ); +extern GLboolean +_mesa_cube_level_complete(const struct gl_texture_object *texObj, + const GLint level); + extern GLboolean _mesa_cube_complete(const struct gl_texture_object *texObj); @@ -160,12 +193,27 @@ _mesa_get_fallback_texture(struct gl_context *ctx, gl_texture_index tex); extern GLuint _mesa_total_texture_memory(struct gl_context *ctx); +extern GLenum +_mesa_texture_base_format(const struct gl_texture_object *texObj); + extern void _mesa_unlock_context_textures( struct gl_context *ctx ); extern void _mesa_lock_context_textures( struct gl_context *ctx ); +extern struct gl_texture_object * +_mesa_create_nameless_texture(struct gl_context *ctx, GLenum target); + +extern void +_mesa_delete_nameless_texture(struct gl_context *ctx, + struct gl_texture_object *texObj); + +extern void +_mesa_bind_texture_unit(struct gl_context *ctx, + GLuint unit, + struct gl_texture_object *texObj); + /*@}*/ /** @@ -174,8 +222,10 @@ _mesa_lock_context_textures( struct gl_context *ctx ); /*@{*/ extern void GLAPIENTRY -_mesa_GenTextures( GLsizei n, GLuint *textures ); +_mesa_GenTextures(GLsizei n, GLuint *textures); +extern void GLAPIENTRY +_mesa_CreateTextures(GLenum target, GLsizei n, GLuint *textures); extern void GLAPIENTRY _mesa_DeleteTextures( GLsizei n, const GLuint *textures ); @@ -184,6 +234,8 @@ _mesa_DeleteTextures( GLsizei n, const GLuint *textures ); extern void GLAPIENTRY _mesa_BindTexture( GLenum target, GLuint texture ); +extern void GLAPIENTRY +_mesa_BindTextureUnit(GLuint unit, GLuint texture); extern void GLAPIENTRY _mesa_BindTextures( GLuint first, GLsizei count, const GLuint *textures ); @@ -212,4 +264,9 @@ _mesa_InvalidateTexImage(GLuint texture, GLint level); /*@}*/ +#ifdef __cplusplus +} +#endif + + #endif diff --git a/mesalib/src/mesa/main/texparam.c b/mesalib/src/mesa/main/texparam.c index e40fb249e..c4a5841c5 100644 --- a/mesalib/src/mesa/main/texparam.c +++ b/mesalib/src/mesa/main/texparam.c @@ -123,7 +123,7 @@ validate_texture_wrap_mode(struct gl_context * ctx, GLenum target, GLenum wrap) * Only the glGetTexLevelParameter() functions accept proxy targets. */ static struct gl_texture_object * -get_texobj(struct gl_context *ctx, GLenum target, GLboolean get) +get_texobj_by_target(struct gl_context *ctx, GLenum target, GLboolean get) { struct gl_texture_unit *texUnit; int targetIndex; @@ -147,6 +147,46 @@ get_texobj(struct gl_context *ctx, GLenum target, GLboolean get) return texUnit->CurrentTex[targetIndex]; } +/** + * Get current texture object for given name. + * Return NULL if any error (and record the error). + * Note that proxy targets are not accepted. + * Only the glGetTexLevelParameter() functions accept proxy targets. + */ +static struct gl_texture_object * +get_texobj_by_name(struct gl_context *ctx, GLuint texture, GLboolean get) +{ + struct gl_texture_object *texObj; + + texObj = _mesa_lookup_texture(ctx, texture); + if (!texObj) { + /* + * User passed a non-generated name. + * Throw the error in the caller. + */ + return NULL; + } + + switch (texObj->Target) { + case GL_TEXTURE_1D: + case GL_TEXTURE_1D_ARRAY: + case GL_TEXTURE_2D: + case GL_TEXTURE_2D_ARRAY: + case GL_TEXTURE_2D_MULTISAMPLE: + case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: + case GL_TEXTURE_3D: + case GL_TEXTURE_CUBE_MAP: + case GL_TEXTURE_CUBE_MAP_ARRAY: + case GL_TEXTURE_RECTANGLE: + return texObj; + default: + _mesa_error(ctx, GL_INVALID_ENUM, + "gl%sTextureParameter(target)", get ? "Get" : ""); + return NULL; + } + +} + /** * Convert GL_RED/GREEN/BLUE/ALPHA/ZERO/ONE to SWIZZLE_X/Y/Z/W/ZERO/ONE. @@ -189,7 +229,7 @@ set_swizzle_component(GLuint *swizzle, GLuint comp, GLuint swz) /** * This is called just prior to changing any texture object state which - * will not effect texture completeness. + * will not affect texture completeness. */ static inline void flush(struct gl_context *ctx) @@ -200,7 +240,7 @@ flush(struct gl_context *ctx) /** * This is called just prior to changing any texture object state which - * can effect texture completeness (texture base level, max level). + * could affect texture completeness (texture base level, max level). * Any pending rendering will be flushed out, we'll set the _NEW_TEXTURE * state flag and then mark the texture object as 'incomplete' so that any * per-texture derived state gets recomputed. @@ -234,12 +274,14 @@ target_allows_setting_sampler_parameters(GLenum target) static GLboolean set_tex_parameteri(struct gl_context *ctx, struct gl_texture_object *texObj, - GLenum pname, const GLint *params) + GLenum pname, const GLint *params, bool dsa) { + const char *suffix = dsa ? "ture" : ""; + switch (pname) { case GL_TEXTURE_MIN_FILTER: if (!target_allows_setting_sampler_parameters(texObj->Target)) - goto invalid_operation; + goto invalid_enum; if (texObj->Sampler.MinFilter == params[0]) return GL_FALSE; @@ -267,7 +309,7 @@ set_tex_parameteri(struct gl_context *ctx, case GL_TEXTURE_MAG_FILTER: if (!target_allows_setting_sampler_parameters(texObj->Target)) - goto invalid_operation; + goto invalid_enum; if (texObj->Sampler.MagFilter == params[0]) return GL_FALSE; @@ -284,7 +326,7 @@ set_tex_parameteri(struct gl_context *ctx, case GL_TEXTURE_WRAP_S: if (!target_allows_setting_sampler_parameters(texObj->Target)) - goto invalid_operation; + goto invalid_enum; if (texObj->Sampler.WrapS == params[0]) return GL_FALSE; @@ -297,7 +339,7 @@ set_tex_parameteri(struct gl_context *ctx, case GL_TEXTURE_WRAP_T: if (!target_allows_setting_sampler_parameters(texObj->Target)) - goto invalid_operation; + goto invalid_enum; if (texObj->Sampler.WrapT == params[0]) return GL_FALSE; @@ -310,7 +352,7 @@ set_tex_parameteri(struct gl_context *ctx, case GL_TEXTURE_WRAP_R: if (!target_allows_setting_sampler_parameters(texObj->Target)) - goto invalid_operation; + goto invalid_enum; if (texObj->Sampler.WrapR == params[0]) return GL_FALSE; @@ -332,10 +374,15 @@ set_tex_parameteri(struct gl_context *ctx, texObj->Target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY) && params[0] != 0) goto invalid_operation; - if (params[0] < 0 || - (texObj->Target == GL_TEXTURE_RECTANGLE_ARB && params[0] != 0)) { + if (params[0] < 0) { _mesa_error(ctx, GL_INVALID_VALUE, - "glTexParameter(param=%d)", params[0]); + "glTex%sParameter(param=%d)", suffix, params[0]); + return GL_FALSE; + } + if (texObj->Target == GL_TEXTURE_RECTANGLE_ARB && params[0] != 0) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glTex%sParameter(target=%s, param=%d)", suffix, + _mesa_lookup_enum_by_nr(texObj->Target), params[0]); return GL_FALSE; } incomplete(ctx, texObj); @@ -355,7 +402,8 @@ set_tex_parameteri(struct gl_context *ctx, if (params[0] < 0 || (texObj->Target == GL_TEXTURE_RECTANGLE_ARB && params[0] > 0)) { _mesa_error(ctx, GL_INVALID_VALUE, - "glTexParameter(param=%d)", params[0]); + "glTex%sParameter(param=%d)", suffix, + params[0]); return GL_FALSE; } incomplete(ctx, texObj); @@ -392,7 +440,7 @@ set_tex_parameteri(struct gl_context *ctx, || _mesa_is_gles3(ctx)) { if (!target_allows_setting_sampler_parameters(texObj->Target)) - goto invalid_operation; + goto invalid_enum; if (texObj->Sampler.CompareMode == params[0]) return GL_FALSE; @@ -411,7 +459,7 @@ set_tex_parameteri(struct gl_context *ctx, || _mesa_is_gles3(ctx)) { if (!target_allows_setting_sampler_parameters(texObj->Target)) - goto invalid_operation; + goto invalid_enum; if (texObj->Sampler.CompareFunc == params[0]) return GL_FALSE; @@ -486,7 +534,7 @@ set_tex_parameteri(struct gl_context *ctx, const GLint swz = comp_to_swizzle(params[0]); if (swz < 0) { _mesa_error(ctx, GL_INVALID_ENUM, - "glTexParameter(swizzle 0x%x)", params[0]); + "glTex%sParameter(swizzle 0x%x)", suffix, params[0]); return GL_FALSE; } ASSERT(comp < 4); @@ -511,7 +559,8 @@ set_tex_parameteri(struct gl_context *ctx, } else { _mesa_error(ctx, GL_INVALID_ENUM, - "glTexParameter(swizzle 0x%x)", params[comp]); + "glTex%sParameter(swizzle 0x%x)", + suffix, params[comp]); return GL_FALSE; } } @@ -525,7 +574,7 @@ set_tex_parameteri(struct gl_context *ctx, GLenum decode = params[0]; if (!target_allows_setting_sampler_parameters(texObj->Target)) - goto invalid_operation; + goto invalid_enum; if (decode == GL_DECODE_EXT || decode == GL_SKIP_DECODE_EXT) { if (texObj->Sampler.sRGBDecode != decode) { @@ -543,7 +592,7 @@ set_tex_parameteri(struct gl_context *ctx, GLenum param = params[0]; if (!target_allows_setting_sampler_parameters(texObj->Target)) - goto invalid_operation; + goto invalid_enum; if (param != GL_TRUE && param != GL_FALSE) { goto invalid_param; @@ -561,18 +610,23 @@ set_tex_parameteri(struct gl_context *ctx, } invalid_pname: - _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(pname=%s)", - _mesa_lookup_enum_by_nr(pname)); + _mesa_error(ctx, GL_INVALID_ENUM, "glTex%sParameter(pname=%s)", + suffix, _mesa_lookup_enum_by_nr(pname)); return GL_FALSE; invalid_param: - _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(param=%s)", - _mesa_lookup_enum_by_nr(params[0])); + _mesa_error(ctx, GL_INVALID_ENUM, "glTex%sParameter(param=%s)", + suffix, _mesa_lookup_enum_by_nr(params[0])); return GL_FALSE; invalid_operation: - _mesa_error(ctx, GL_INVALID_OPERATION, "glTexParameter(pname=%s)", - _mesa_lookup_enum_by_nr(pname)); + _mesa_error(ctx, GL_INVALID_OPERATION, "glTex%sParameter(pname=%s)", + suffix, _mesa_lookup_enum_by_nr(pname)); + return GL_FALSE; + +invalid_enum: + _mesa_error(ctx, GL_INVALID_ENUM, "glTex%sParameter(pname=%s)", + suffix, _mesa_lookup_enum_by_nr(pname)); return GL_FALSE; } @@ -584,15 +638,17 @@ invalid_operation: static GLboolean set_tex_parameterf(struct gl_context *ctx, struct gl_texture_object *texObj, - GLenum pname, const GLfloat *params) + GLenum pname, const GLfloat *params, bool dsa) { + const char *suffix = dsa ? "ture" : ""; + switch (pname) { case GL_TEXTURE_MIN_LOD: if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx)) goto invalid_pname; if (!target_allows_setting_sampler_parameters(texObj->Target)) - goto invalid_operation; + goto invalid_enum; if (texObj->Sampler.MinLod == params[0]) return GL_FALSE; @@ -605,7 +661,7 @@ set_tex_parameterf(struct gl_context *ctx, goto invalid_pname; if (!target_allows_setting_sampler_parameters(texObj->Target)) - goto invalid_operation; + goto invalid_enum; if (texObj->Sampler.MaxLod == params[0]) return GL_FALSE; @@ -624,12 +680,13 @@ set_tex_parameterf(struct gl_context *ctx, case GL_TEXTURE_MAX_ANISOTROPY_EXT: if (ctx->Extensions.EXT_texture_filter_anisotropic) { if (!target_allows_setting_sampler_parameters(texObj->Target)) - goto invalid_operation; + goto invalid_enum; if (texObj->Sampler.MaxAnisotropy == params[0]) return GL_FALSE; if (params[0] < 1.0) { - _mesa_error(ctx, GL_INVALID_VALUE, "glTexParameter(param)" ); + _mesa_error(ctx, GL_INVALID_VALUE, "glTex%sParameter(param)", + suffix); return GL_FALSE; } flush(ctx); @@ -651,7 +708,7 @@ set_tex_parameterf(struct gl_context *ctx, goto invalid_pname; if (!target_allows_setting_sampler_parameters(texObj->Target)) - goto invalid_operation; + goto invalid_enum; if (texObj->Sampler.LodBias != params[0]) { flush(ctx); @@ -665,7 +722,7 @@ set_tex_parameterf(struct gl_context *ctx, goto invalid_pname; if (!target_allows_setting_sampler_parameters(texObj->Target)) - goto invalid_operation; + goto invalid_enum; flush(ctx); /* ARB_texture_float disables clamping */ @@ -688,27 +745,23 @@ set_tex_parameterf(struct gl_context *ctx, return GL_FALSE; invalid_pname: - _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(pname=%s)", - _mesa_lookup_enum_by_nr(pname)); + _mesa_error(ctx, GL_INVALID_ENUM, "glTex%sParameter(pname=%s)", + suffix, _mesa_lookup_enum_by_nr(pname)); return GL_FALSE; -invalid_operation: - _mesa_error(ctx, GL_INVALID_OPERATION, "glTexParameter(pname=%s)", - _mesa_lookup_enum_by_nr(pname)); +invalid_enum: + _mesa_error(ctx, GL_INVALID_ENUM, "glTex%sParameter(pname=%s)", + suffix, _mesa_lookup_enum_by_nr(pname)); return GL_FALSE; } -void GLAPIENTRY -_mesa_TexParameterf(GLenum target, GLenum pname, GLfloat param) +void +_mesa_texture_parameterf(struct gl_context *ctx, + struct gl_texture_object *texObj, + GLenum pname, GLfloat param, bool dsa) { GLboolean need_update; - struct gl_texture_object *texObj; - GET_CURRENT_CONTEXT(ctx); - - texObj = get_texobj(ctx, target, GL_FALSE); - if (!texObj) - return; switch (pname) { case GL_TEXTURE_MIN_FILTER: @@ -736,16 +789,21 @@ _mesa_TexParameterf(GLenum target, GLenum pname, GLfloat param) ((param < INT_MIN) ? INT_MIN : (GLint) (param - 0.5)); p[1] = p[2] = p[3] = 0; - need_update = set_tex_parameteri(ctx, texObj, pname, p); + need_update = set_tex_parameteri(ctx, texObj, pname, p, dsa); } break; + case GL_TEXTURE_BORDER_COLOR: + case GL_TEXTURE_SWIZZLE_RGBA: + _mesa_error(ctx, GL_INVALID_ENUM, "glTex%sParameterf(non-scalar pname)", + dsa ? "ture" : ""); + return; default: { /* this will generate an error if pname is illegal */ GLfloat p[4]; p[0] = param; p[1] = p[2] = p[3] = 0.0F; - need_update = set_tex_parameterf(ctx, texObj, pname, p); + need_update = set_tex_parameterf(ctx, texObj, pname, p, dsa); } } @@ -755,17 +813,12 @@ _mesa_TexParameterf(GLenum target, GLenum pname, GLfloat param) } -void GLAPIENTRY -_mesa_TexParameterfv(GLenum target, GLenum pname, const GLfloat *params) +void +_mesa_texture_parameterfv(struct gl_context *ctx, + struct gl_texture_object *texObj, + GLenum pname, const GLfloat *params, bool dsa) { GLboolean need_update; - struct gl_texture_object *texObj; - GET_CURRENT_CONTEXT(ctx); - - texObj = get_texobj(ctx, target, GL_FALSE); - if (!texObj) - return; - switch (pname) { case GL_TEXTURE_MIN_FILTER: case GL_TEXTURE_MAG_FILTER: @@ -786,7 +839,7 @@ _mesa_TexParameterfv(GLenum target, GLenum pname, const GLfloat *params) GLint p[4]; p[0] = (GLint) params[0]; p[1] = p[2] = p[3] = 0; - need_update = set_tex_parameteri(ctx, texObj, pname, p); + need_update = set_tex_parameteri(ctx, texObj, pname, p, dsa); } break; case GL_TEXTURE_CROP_RECT_OES: @@ -797,7 +850,7 @@ _mesa_TexParameterfv(GLenum target, GLenum pname, const GLfloat *params) iparams[1] = (GLint) params[1]; iparams[2] = (GLint) params[2]; iparams[3] = (GLint) params[3]; - need_update = set_tex_parameteri(ctx, texObj, pname, iparams); + need_update = set_tex_parameteri(ctx, texObj, pname, iparams, dsa); } break; case GL_TEXTURE_SWIZZLE_R_EXT: @@ -813,12 +866,12 @@ _mesa_TexParameterfv(GLenum target, GLenum pname, const GLfloat *params) p[2] = (GLint) params[2]; p[3] = (GLint) params[3]; } - need_update = set_tex_parameteri(ctx, texObj, pname, p); + need_update = set_tex_parameteri(ctx, texObj, pname, p, dsa); } break; default: /* this will generate an error if pname is illegal */ - need_update = set_tex_parameterf(ctx, texObj, pname, params); + need_update = set_tex_parameterf(ctx, texObj, pname, params, dsa); } if (ctx->Driver.TexParameter && need_update) { @@ -827,17 +880,12 @@ _mesa_TexParameterfv(GLenum target, GLenum pname, const GLfloat *params) } -void GLAPIENTRY -_mesa_TexParameteri(GLenum target, GLenum pname, GLint param) +void +_mesa_texture_parameteri(struct gl_context *ctx, + struct gl_texture_object *texObj, + GLenum pname, GLint param, bool dsa) { GLboolean need_update; - struct gl_texture_object *texObj; - GET_CURRENT_CONTEXT(ctx); - - texObj = get_texobj(ctx, target, GL_FALSE); - if (!texObj) - return; - switch (pname) { case GL_TEXTURE_MIN_LOD: case GL_TEXTURE_MAX_LOD: @@ -850,16 +898,24 @@ _mesa_TexParameteri(GLenum target, GLenum pname, GLint param) fparam[0] = (GLfloat) param; fparam[1] = fparam[2] = fparam[3] = 0.0F; /* convert int param to float */ - need_update = set_tex_parameterf(ctx, texObj, pname, fparam); + need_update = set_tex_parameterf(ctx, texObj, pname, fparam, dsa); } break; + case GL_TEXTURE_BORDER_COLOR: + case GL_TEXTURE_SWIZZLE_RGBA: + { + _mesa_error(ctx, GL_INVALID_ENUM, + "glTex%sParameteri(non-scalar pname)", + dsa ? "ture" : ""); + return; + } default: /* this will generate an error if pname is illegal */ { GLint iparam[4]; iparam[0] = param; iparam[1] = iparam[2] = iparam[3] = 0; - need_update = set_tex_parameteri(ctx, texObj, pname, iparam); + need_update = set_tex_parameteri(ctx, texObj, pname, iparam, dsa); } } @@ -870,16 +926,12 @@ _mesa_TexParameteri(GLenum target, GLenum pname, GLint param) } -void GLAPIENTRY -_mesa_TexParameteriv(GLenum target, GLenum pname, const GLint *params) +void +_mesa_texture_parameteriv(struct gl_context *ctx, + struct gl_texture_object *texObj, + GLenum pname, const GLint *params, bool dsa) { GLboolean need_update; - struct gl_texture_object *texObj; - GET_CURRENT_CONTEXT(ctx); - - texObj = get_texobj(ctx, target, GL_FALSE); - if (!texObj) - return; switch (pname) { case GL_TEXTURE_BORDER_COLOR: @@ -890,7 +942,7 @@ _mesa_TexParameteriv(GLenum target, GLenum pname, const GLint *params) fparams[1] = INT_TO_FLOAT(params[1]); fparams[2] = INT_TO_FLOAT(params[2]); fparams[3] = INT_TO_FLOAT(params[3]); - need_update = set_tex_parameterf(ctx, texObj, pname, fparams); + need_update = set_tex_parameterf(ctx, texObj, pname, fparams, dsa); } break; case GL_TEXTURE_MIN_LOD: @@ -904,12 +956,12 @@ _mesa_TexParameteriv(GLenum target, GLenum pname, const GLint *params) GLfloat fparams[4]; fparams[0] = (GLfloat) params[0]; fparams[1] = fparams[2] = fparams[3] = 0.0F; - need_update = set_tex_parameterf(ctx, texObj, pname, fparams); + need_update = set_tex_parameterf(ctx, texObj, pname, fparams, dsa); } break; default: /* this will generate an error if pname is illegal */ - need_update = set_tex_parameteri(ctx, texObj, pname, params); + need_update = set_tex_parameteri(ctx, texObj, pname, params, dsa); } if (ctx->Driver.TexParameter && need_update) { @@ -925,6 +977,94 @@ _mesa_TexParameteriv(GLenum target, GLenum pname, const GLint *params) } } +void +_mesa_texture_parameterIiv(struct gl_context *ctx, + struct gl_texture_object *texObj, + GLenum pname, const GLint *params, bool dsa) +{ + switch (pname) { + case GL_TEXTURE_BORDER_COLOR: + FLUSH_VERTICES(ctx, _NEW_TEXTURE); + /* set the integer-valued border color */ + COPY_4V(texObj->Sampler.BorderColor.i, params); + break; + default: + _mesa_texture_parameteriv(ctx, texObj, pname, params, dsa); + break; + } + /* XXX no driver hook for TexParameterIiv() yet */ +} + +void +_mesa_texture_parameterIuiv(struct gl_context *ctx, + struct gl_texture_object *texObj, + GLenum pname, const GLuint *params, bool dsa) +{ + switch (pname) { + case GL_TEXTURE_BORDER_COLOR: + FLUSH_VERTICES(ctx, _NEW_TEXTURE); + /* set the unsigned integer-valued border color */ + COPY_4V(texObj->Sampler.BorderColor.ui, params); + break; + default: + _mesa_texture_parameteriv(ctx, texObj, pname, (const GLint *) params, + dsa); + break; + } + /* XXX no driver hook for TexParameterIuiv() yet */ +} + +void GLAPIENTRY +_mesa_TexParameterf(GLenum target, GLenum pname, GLfloat param) +{ + struct gl_texture_object *texObj; + GET_CURRENT_CONTEXT(ctx); + + texObj = get_texobj_by_target(ctx, target, GL_FALSE); + if (!texObj) + return; + + _mesa_texture_parameterf(ctx, texObj, pname, param, false); +} + +void GLAPIENTRY +_mesa_TexParameterfv(GLenum target, GLenum pname, const GLfloat *params) +{ + struct gl_texture_object *texObj; + GET_CURRENT_CONTEXT(ctx); + + texObj = get_texobj_by_target(ctx, target, GL_FALSE); + if (!texObj) + return; + + _mesa_texture_parameterfv(ctx, texObj, pname, params, false); +} + +void GLAPIENTRY +_mesa_TexParameteri(GLenum target, GLenum pname, GLint param) +{ + struct gl_texture_object *texObj; + GET_CURRENT_CONTEXT(ctx); + + texObj = get_texobj_by_target(ctx, target, GL_FALSE); + if (!texObj) + return; + + _mesa_texture_parameteri(ctx, texObj, pname, param, false); +} + +void GLAPIENTRY +_mesa_TexParameteriv(GLenum target, GLenum pname, const GLint *params) +{ + struct gl_texture_object *texObj; + GET_CURRENT_CONTEXT(ctx); + + texObj = get_texobj_by_target(ctx, target, GL_FALSE); + if (!texObj) + return; + + _mesa_texture_parameteriv(ctx, texObj, pname, params, false); +} /** * Set tex parameter to integer value(s). Primarily intended to set @@ -937,24 +1077,13 @@ _mesa_TexParameterIiv(GLenum target, GLenum pname, const GLint *params) struct gl_texture_object *texObj; GET_CURRENT_CONTEXT(ctx); - texObj = get_texobj(ctx, target, GL_FALSE); + texObj = get_texobj_by_target(ctx, target, GL_FALSE); if (!texObj) return; - switch (pname) { - case GL_TEXTURE_BORDER_COLOR: - FLUSH_VERTICES(ctx, _NEW_TEXTURE); - /* set the integer-valued border color */ - COPY_4V(texObj->Sampler.BorderColor.i, params); - break; - default: - _mesa_TexParameteriv(target, pname, params); - break; - } - /* XXX no driver hook for TexParameterIiv() yet */ + _mesa_texture_parameterIiv(ctx, texObj, pname, params, false); } - /** * Set tex parameter to unsigned integer value(s). Primarily intended to set * uint-valued texture border color (for integer-valued textures). @@ -966,26 +1095,117 @@ _mesa_TexParameterIuiv(GLenum target, GLenum pname, const GLuint *params) struct gl_texture_object *texObj; GET_CURRENT_CONTEXT(ctx); - texObj = get_texobj(ctx, target, GL_FALSE); + texObj = get_texobj_by_target(ctx, target, GL_FALSE); if (!texObj) return; - switch (pname) { - case GL_TEXTURE_BORDER_COLOR: - FLUSH_VERTICES(ctx, _NEW_TEXTURE); - /* set the unsigned integer-valued border color */ - COPY_4V(texObj->Sampler.BorderColor.ui, params); - break; - default: - _mesa_TexParameteriv(target, pname, (const GLint *) params); - break; + _mesa_texture_parameterIuiv(ctx, texObj, pname, params, false); +} + + +void GLAPIENTRY +_mesa_TextureParameterfv(GLuint texture, GLenum pname, const GLfloat *params) +{ + struct gl_texture_object *texObj; + GET_CURRENT_CONTEXT(ctx); + + texObj = get_texobj_by_name(ctx, texture, GL_FALSE); + if (!texObj) { + /* User passed a non-generated name. */ + _mesa_error(ctx, GL_INVALID_OPERATION, "glTextureParameterfv(texture)"); + return; } - /* XXX no driver hook for TexParameterIuiv() yet */ + + _mesa_texture_parameterfv(ctx, texObj, pname, params, true); +} + +void GLAPIENTRY +_mesa_TextureParameterf(GLuint texture, GLenum pname, GLfloat param) +{ + struct gl_texture_object *texObj; + GET_CURRENT_CONTEXT(ctx); + + texObj = get_texobj_by_name(ctx, texture, GL_FALSE); + if (!texObj) { + /* User passed a non-generated name. */ + _mesa_error(ctx, GL_INVALID_OPERATION, "glTextureParameterf(texture)"); + return; + } + + _mesa_texture_parameterf(ctx, texObj, pname, param, true); } +void GLAPIENTRY +_mesa_TextureParameteri(GLuint texture, GLenum pname, GLint param) +{ + struct gl_texture_object *texObj; + GET_CURRENT_CONTEXT(ctx); + + texObj = get_texobj_by_name(ctx, texture, GL_FALSE); + if (!texObj) { + /* User passed a non-generated name. */ + _mesa_error(ctx, GL_INVALID_OPERATION, "glTextureParameteri(texture)"); + return; + } + + _mesa_texture_parameteri(ctx, texObj, pname, param, true); +} + +void GLAPIENTRY +_mesa_TextureParameteriv(GLuint texture, GLenum pname, + const GLint *params) +{ + struct gl_texture_object *texObj; + GET_CURRENT_CONTEXT(ctx); + + texObj = get_texobj_by_name(ctx, texture, GL_FALSE); + if (!texObj) { + /* User passed a non-generated name. */ + _mesa_error(ctx, GL_INVALID_OPERATION, "glTextureParameteriv(texture)"); + return; + } + + _mesa_texture_parameteriv(ctx, texObj, pname, params, true); +} + + +void GLAPIENTRY +_mesa_TextureParameterIiv(GLuint texture, GLenum pname, const GLint *params) +{ + struct gl_texture_object *texObj; + GET_CURRENT_CONTEXT(ctx); + + texObj = get_texobj_by_name(ctx, texture, GL_FALSE); + if (!texObj) { + /* User passed a non-generated name. */ + _mesa_error(ctx, GL_INVALID_OPERATION, + "glTextureParameterIiv(texture)"); + return; + } + + _mesa_texture_parameterIiv(ctx, texObj, pname, params, true); +} + +void GLAPIENTRY +_mesa_TextureParameterIuiv(GLuint texture, GLenum pname, const GLuint *params) +{ + struct gl_texture_object *texObj; + GET_CURRENT_CONTEXT(ctx); + + texObj = get_texobj_by_name(ctx, texture, GL_FALSE); + if (!texObj) { + /* User passed a non-generated name. */ + _mesa_error(ctx, GL_INVALID_OPERATION, + "glTextureParameterIuiv(texture)"); + return; + } + + _mesa_texture_parameterIuiv(ctx, texObj, pname, params, true); +} static GLboolean -legal_get_tex_level_parameter_target(struct gl_context *ctx, GLenum target) +legal_get_tex_level_parameter_target(struct gl_context *ctx, GLenum target, + bool dsa) { switch (target) { case GL_TEXTURE_1D: @@ -1038,6 +1258,16 @@ legal_get_tex_level_parameter_target(struct gl_context *ctx, GLenum target) case GL_PROXY_TEXTURE_2D_MULTISAMPLE: case GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY: return ctx->Extensions.ARB_texture_multisample; + + /* This is a valid target for dsa, but the OpenGL 4.5 core spec + * (30.10.2014) Section 8.11 Texture Queries says: + * "For GetTextureLevelParameter* only, texture may also be a cube + * map texture object. In this case the query is always performed + * for face zero (the TEXTURE_CUBE_MAP_POSITIVE_X face), since there + * is no way to specify another face." + */ + case GL_TEXTURE_CUBE_MAP: + return dsa; default: return GL_FALSE; } @@ -1048,13 +1278,15 @@ static void get_tex_level_parameter_image(struct gl_context *ctx, const struct gl_texture_object *texObj, GLenum target, GLint level, - GLenum pname, GLint *params) + GLenum pname, GLint *params, + bool dsa) { const struct gl_texture_image *img = NULL; struct gl_texture_image dummy_image; mesa_format texFormat; + const char *suffix = dsa ? "ture" : ""; - img = _mesa_select_tex_image(ctx, texObj, target, level); + img = _mesa_select_tex_image(texObj, target, level); if (!img || img->TexFormat == MESA_FORMAT_NONE) { /* In case of undefined texture image return the default values. * @@ -1160,11 +1392,12 @@ get_tex_level_parameter_image(struct gl_context *ctx, !_mesa_is_proxy_texture(target)) { *params = _mesa_format_image_size(texFormat, img->Width, img->Height, img->Depth); - } - else { - _mesa_error(ctx, GL_INVALID_OPERATION, - "glGetTexLevelParameter[if]v(pname)"); - } + } + else { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glGetTex%sLevelParameter[if]v(pname=%s)", suffix, + _mesa_lookup_enum_by_nr(pname)); + } break; case GL_TEXTURE_COMPRESSED: *params = (GLint) _mesa_is_format_compressed(texFormat); @@ -1211,7 +1444,7 @@ get_tex_level_parameter_image(struct gl_context *ctx, invalid_pname: _mesa_error(ctx, GL_INVALID_ENUM, - "glGetTexLevelParameter[if]v(pname=%s)", + "glGetTex%sLevelParameter[if]v(pname=%s)", suffix, _mesa_lookup_enum_by_nr(pname)); } @@ -1219,12 +1452,13 @@ invalid_pname: static void get_tex_level_parameter_buffer(struct gl_context *ctx, const struct gl_texture_object *texObj, - GLenum pname, GLint *params) + GLenum pname, GLint *params, bool dsa) { const struct gl_buffer_object *bo = texObj->BufferObject; mesa_format texFormat = texObj->_BufferObjectFormat; GLenum internalFormat = texObj->BufferObjectFormat; GLenum baseFormat = _mesa_get_format_base_format(texFormat); + const char *suffix = dsa ? "ture" : ""; if (!bo) { /* undefined texture buffer object */ @@ -1294,7 +1528,8 @@ get_tex_level_parameter_buffer(struct gl_context *ctx, case GL_TEXTURE_COMPRESSED_IMAGE_SIZE: /* Always illegal for GL_TEXTURE_BUFFER */ _mesa_error(ctx, GL_INVALID_OPERATION, - "glGetTexLevelParameter[if]v(pname)"); + "glGetTex%sLevelParameter[if]v(pname=%s)", suffix, + _mesa_lookup_enum_by_nr(pname)); break; /* GL_ARB_texture_float */ @@ -1322,38 +1557,37 @@ get_tex_level_parameter_buffer(struct gl_context *ctx, invalid_pname: _mesa_error(ctx, GL_INVALID_ENUM, - "glGetTexLevelParameter[if]v(pname=%s)", + "glGetTex%sLevelParameter[if]v(pname=%s)", suffix, _mesa_lookup_enum_by_nr(pname)); } -void GLAPIENTRY -_mesa_GetTexLevelParameterfv( GLenum target, GLint level, - GLenum pname, GLfloat *params ) -{ - GLint iparam; - _mesa_GetTexLevelParameteriv( target, level, pname, &iparam ); - *params = (GLfloat) iparam; -} - - -void GLAPIENTRY -_mesa_GetTexLevelParameteriv( GLenum target, GLint level, - GLenum pname, GLint *params ) +/** + * This isn't exposed to the rest of the driver because it is a part of the + * OpenGL API that is rarely used. + */ +static void +get_tex_level_parameteriv(struct gl_context *ctx, + struct gl_texture_object *texObj, + GLenum target, GLint level, + GLenum pname, GLint *params, + bool dsa) { - struct gl_texture_object *texObj; GLint maxLevels; - GET_CURRENT_CONTEXT(ctx); + const char *suffix = dsa ? "ture" : ""; + /* Check for errors */ if (ctx->Texture.CurrentUnit >= ctx->Const.MaxCombinedTextureImageUnits) { _mesa_error(ctx, GL_INVALID_OPERATION, - "glGetTexLevelParameteriv(current unit)"); + "glGetTex%sLevelParameter[if]v(" + "current unit >= max combined texture units)", suffix); return; } - if (!legal_get_tex_level_parameter_target(ctx, target)) { + if (!legal_get_tex_level_parameter_target(ctx, target, dsa)) { _mesa_error(ctx, GL_INVALID_ENUM, - "glGetTexLevelParameter[if]v(target=0x%x)", target); + "glGetTex%sLevelParameter[if]v(target=%s)", suffix, + _mesa_lookup_enum_by_nr(target)); return; } @@ -1361,29 +1595,98 @@ _mesa_GetTexLevelParameteriv( GLenum target, GLint level, assert(maxLevels != 0); if (level < 0 || level >= maxLevels) { - _mesa_error( ctx, GL_INVALID_VALUE, "glGetTexLevelParameter[if]v" ); + _mesa_error(ctx, GL_INVALID_VALUE, + "glGetTex%sLevelParameter[if]v(level out of range)", suffix); return; } + /* Get the level parameter */ + if (target == GL_TEXTURE_BUFFER) { + get_tex_level_parameter_buffer(ctx, texObj, pname, params, dsa); + } + else { + get_tex_level_parameter_image(ctx, texObj, target, + level, pname, params, dsa); + } +} + +void GLAPIENTRY +_mesa_GetTexLevelParameterfv( GLenum target, GLint level, + GLenum pname, GLfloat *params ) +{ + struct gl_texture_object *texObj; + GLint iparam; + GET_CURRENT_CONTEXT(ctx); + + texObj = _mesa_get_current_tex_object(ctx, target); + if (!texObj) + return; + + get_tex_level_parameteriv(ctx, texObj, target, level, + pname, &iparam, false); + + *params = (GLfloat) iparam; +} + +void GLAPIENTRY +_mesa_GetTexLevelParameteriv( GLenum target, GLint level, + GLenum pname, GLint *params ) +{ + struct gl_texture_object *texObj; + GET_CURRENT_CONTEXT(ctx); + texObj = _mesa_get_current_tex_object(ctx, target); + if (!texObj) + return; - if (target == GL_TEXTURE_BUFFER) - get_tex_level_parameter_buffer(ctx, texObj, pname, params); - else - get_tex_level_parameter_image(ctx, texObj, target, level, pname, params); + get_tex_level_parameteriv(ctx, texObj, target, level, + pname, params, false); } +void GLAPIENTRY +_mesa_GetTextureLevelParameterfv(GLuint texture, GLint level, + GLenum pname, GLfloat *params) +{ + struct gl_texture_object *texObj; + GLint iparam; + GET_CURRENT_CONTEXT(ctx); + + texObj = _mesa_lookup_texture_err(ctx, texture, + "glGetTextureLevelParameterfv"); + if (!texObj) + return; + + get_tex_level_parameteriv(ctx, texObj, texObj->Target, level, + pname, &iparam, true); + + *params = (GLfloat) iparam; +} void GLAPIENTRY -_mesa_GetTexParameterfv( GLenum target, GLenum pname, GLfloat *params ) +_mesa_GetTextureLevelParameteriv(GLuint texture, GLint level, + GLenum pname, GLint *params) { - struct gl_texture_object *obj; + struct gl_texture_object *texObj; GET_CURRENT_CONTEXT(ctx); - obj = get_texobj(ctx, target, GL_TRUE); - if (!obj) + texObj = _mesa_lookup_texture_err(ctx, texture, + "glGetTextureLevelParameteriv"); + if (!texObj) return; + get_tex_level_parameteriv(ctx, texObj, texObj->Target, level, + pname, params, true); +} + +/** + * This isn't exposed to the rest of the driver because it is a part of the + * OpenGL API that is rarely used. + */ +static void +get_tex_parameterfv(struct gl_context *ctx, + struct gl_texture_object *obj, + GLenum pname, GLfloat *params, bool dsa) +{ _mesa_lock_context_textures(ctx); switch (pname) { case GL_TEXTURE_MAG_FILTER: @@ -1596,20 +1899,16 @@ _mesa_GetTexParameterfv( GLenum target, GLenum pname, GLfloat *params ) invalid_pname: _mesa_unlock_context_textures(ctx); - _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexParameterfv(pname=0x%x)", pname); + _mesa_error(ctx, GL_INVALID_ENUM, "glGetTex%sParameterfv(pname=0x%x)", + dsa ? "ture" : "", pname); } -void GLAPIENTRY -_mesa_GetTexParameteriv( GLenum target, GLenum pname, GLint *params ) +static void +get_tex_parameteriv(struct gl_context *ctx, + struct gl_texture_object *obj, + GLenum pname, GLint *params, bool dsa) { - struct gl_texture_object *obj; - GET_CURRENT_CONTEXT(ctx); - - obj = get_texobj(ctx, target, GL_TRUE); - if (!obj) - return; - _mesa_lock_texture(ctx, obj); switch (pname) { case GL_TEXTURE_MAG_FILTER: @@ -1658,14 +1957,18 @@ _mesa_GetTexParameteriv( GLenum target, GLenum pname, GLint *params ) case GL_TEXTURE_MIN_LOD: if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx)) goto invalid_pname; - - *params = (GLint) obj->Sampler.MinLod; + /* GL spec 'Data Conversions' section specifies that floating-point + * value in integer Get function is rounded to nearest integer + */ + *params = IROUND(obj->Sampler.MinLod); break; case GL_TEXTURE_MAX_LOD: if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx)) goto invalid_pname; - - *params = (GLint) obj->Sampler.MaxLod; + /* GL spec 'Data Conversions' section specifies that floating-point + * value in integer Get function is rounded to nearest integer + */ + *params = IROUND(obj->Sampler.MaxLod); break; case GL_TEXTURE_BASE_LEVEL: if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx)) @@ -1679,7 +1982,10 @@ _mesa_GetTexParameteriv( GLenum target, GLenum pname, GLint *params ) case GL_TEXTURE_MAX_ANISOTROPY_EXT: if (!ctx->Extensions.EXT_texture_filter_anisotropic) goto invalid_pname; - *params = (GLint) obj->Sampler.MaxAnisotropy; + /* GL spec 'Data Conversions' section specifies that floating-point + * value in integer Get function is rounded to nearest integer + */ + *params = IROUND(obj->Sampler.MaxAnisotropy); break; case GL_GENERATE_MIPMAP_SGIS: if (ctx->API != API_OPENGL_COMPAT && ctx->API != API_OPENGLES) @@ -1818,9 +2124,73 @@ _mesa_GetTexParameteriv( GLenum target, GLenum pname, GLint *params ) invalid_pname: _mesa_unlock_texture(ctx, obj); - _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexParameteriv(pname=0x%x)", pname); + _mesa_error(ctx, GL_INVALID_ENUM, "glGetTex%sParameteriv(pname=0x%x)", + dsa ? "ture" : "", pname); +} + +static void +get_tex_parameterIiv(struct gl_context *ctx, + struct gl_texture_object *obj, + GLenum pname, GLint *params, bool dsa) +{ + switch (pname) { + case GL_TEXTURE_BORDER_COLOR: + COPY_4V(params, obj->Sampler.BorderColor.i); + break; + default: + get_tex_parameteriv(ctx, obj, pname, params, dsa); + } +} + +static void +get_tex_parameterIuiv(struct gl_context *ctx, + struct gl_texture_object *obj, + GLenum pname, GLuint *params, bool dsa) +{ + switch (pname) { + case GL_TEXTURE_BORDER_COLOR: + COPY_4V(params, obj->Sampler.BorderColor.i); + break; + default: + { + GLint ip[4]; + get_tex_parameteriv(ctx, obj, pname, ip, dsa); + params[0] = ip[0]; + if (pname == GL_TEXTURE_SWIZZLE_RGBA_EXT || + pname == GL_TEXTURE_CROP_RECT_OES) { + params[1] = ip[1]; + params[2] = ip[2]; + params[3] = ip[3]; + } + } + } +} + +void GLAPIENTRY +_mesa_GetTexParameterfv(GLenum target, GLenum pname, GLfloat *params) +{ + struct gl_texture_object *obj; + GET_CURRENT_CONTEXT(ctx); + + obj = get_texobj_by_target(ctx, target, GL_TRUE); + if (!obj) + return; + + get_tex_parameterfv(ctx, obj, pname, params, false); } +void GLAPIENTRY +_mesa_GetTexParameteriv(GLenum target, GLenum pname, GLint *params) +{ + struct gl_texture_object *obj; + GET_CURRENT_CONTEXT(ctx); + + obj = get_texobj_by_target(ctx, target, GL_TRUE); + if (!obj) + return; + + get_tex_parameteriv(ctx, obj, pname, params, false); +} /** New in GL 3.0 */ void GLAPIENTRY @@ -1829,17 +2199,11 @@ _mesa_GetTexParameterIiv(GLenum target, GLenum pname, GLint *params) struct gl_texture_object *texObj; GET_CURRENT_CONTEXT(ctx); - texObj = get_texobj(ctx, target, GL_TRUE); + texObj = get_texobj_by_target(ctx, target, GL_TRUE); if (!texObj) return; - switch (pname) { - case GL_TEXTURE_BORDER_COLOR: - COPY_4V(params, texObj->Sampler.BorderColor.i); - break; - default: - _mesa_GetTexParameteriv(target, pname, params); - } + get_tex_parameterIiv(ctx, texObj, pname, params, false); } @@ -1850,25 +2214,79 @@ _mesa_GetTexParameterIuiv(GLenum target, GLenum pname, GLuint *params) struct gl_texture_object *texObj; GET_CURRENT_CONTEXT(ctx); - texObj = get_texobj(ctx, target, GL_TRUE); + texObj = get_texobj_by_target(ctx, target, GL_TRUE); if (!texObj) return; - switch (pname) { - case GL_TEXTURE_BORDER_COLOR: - COPY_4V(params, texObj->Sampler.BorderColor.i); - break; - default: - { - GLint ip[4]; - _mesa_GetTexParameteriv(target, pname, ip); - params[0] = ip[0]; - if (pname == GL_TEXTURE_SWIZZLE_RGBA_EXT || - pname == GL_TEXTURE_CROP_RECT_OES) { - params[1] = ip[1]; - params[2] = ip[2]; - params[3] = ip[3]; - } - } + get_tex_parameterIuiv(ctx, texObj, pname, params, false); +} + + +void GLAPIENTRY +_mesa_GetTextureParameterfv(GLuint texture, GLenum pname, GLfloat *params) +{ + struct gl_texture_object *obj; + GET_CURRENT_CONTEXT(ctx); + + obj = get_texobj_by_name(ctx, texture, GL_TRUE); + if (!obj) { + /* User passed a non-generated name. */ + _mesa_error(ctx, GL_INVALID_OPERATION, + "glGetTextureParameterfv(texture)"); + return; + } + + get_tex_parameterfv(ctx, obj, pname, params, true); +} + +void GLAPIENTRY +_mesa_GetTextureParameteriv(GLuint texture, GLenum pname, GLint *params) +{ + struct gl_texture_object *obj; + GET_CURRENT_CONTEXT(ctx); + + obj = get_texobj_by_name(ctx, texture, GL_TRUE); + if (!obj) { + /* User passed a non-generated name. */ + _mesa_error(ctx, GL_INVALID_OPERATION, + "glGetTextureParameteriv(texture)"); + return; + } + + get_tex_parameteriv(ctx, obj, pname, params, true); +} + +void GLAPIENTRY +_mesa_GetTextureParameterIiv(GLuint texture, GLenum pname, GLint *params) +{ + struct gl_texture_object *texObj; + GET_CURRENT_CONTEXT(ctx); + + texObj = get_texobj_by_name(ctx, texture, GL_TRUE); + if (!texObj) { + /* User passed a non-generated name. */ + _mesa_error(ctx, GL_INVALID_OPERATION, + "glGetTextureParameterIiv(texture)"); + return; } + + get_tex_parameterIiv(ctx, texObj, pname, params, true); +} + + +void GLAPIENTRY +_mesa_GetTextureParameterIuiv(GLuint texture, GLenum pname, GLuint *params) +{ + struct gl_texture_object *texObj; + GET_CURRENT_CONTEXT(ctx); + + texObj = get_texobj_by_name(ctx, texture, GL_TRUE); + if (!texObj) { + /* User passed a non-generated name. */ + _mesa_error(ctx, GL_INVALID_OPERATION, + "glGetTextureParameterIuiv(texture)"); + return; + } + + get_tex_parameterIuiv(ctx, texObj, pname, params, true); } diff --git a/mesalib/src/mesa/main/texparam.h b/mesalib/src/mesa/main/texparam.h index 557a7bcb4..96defbec2 100644 --- a/mesalib/src/mesa/main/texparam.h +++ b/mesalib/src/mesa/main/texparam.h @@ -29,6 +29,49 @@ #include "main/glheader.h" +/** + * \name Internal functions + */ +/*@{*/ + +extern void +_mesa_texture_parameterf(struct gl_context *ctx, + struct gl_texture_object *texObj, + GLenum pname, GLfloat param, bool dsa); + +extern void +_mesa_texture_parameterfv(struct gl_context *ctx, + struct gl_texture_object *texObj, + GLenum pname, const GLfloat *params, bool dsa); + + +extern void +_mesa_texture_parameteri(struct gl_context *ctx, + struct gl_texture_object *texObj, + GLenum pname, GLint param, bool dsa); + +extern void +_mesa_texture_parameteriv(struct gl_context *ctx, + struct gl_texture_object *texObj, + GLenum pname, const GLint *params, bool dsa); + +extern void +_mesa_texture_parameterIiv(struct gl_context *ctx, + struct gl_texture_object *texObj, + GLenum pname, const GLint *params, bool dsa); + +extern void +_mesa_texture_parameterIuiv(struct gl_context *ctx, + struct gl_texture_object *texObj, + GLenum pname, const GLuint *params, bool dsa); + +/*@}*/ + +/** + * \name API functions + */ +/*@{*/ + extern void GLAPIENTRY _mesa_GetTexLevelParameterfv( GLenum target, GLint level, @@ -38,6 +81,15 @@ extern void GLAPIENTRY _mesa_GetTexLevelParameteriv( GLenum target, GLint level, GLenum pname, GLint *params ); +extern void GLAPIENTRY +_mesa_GetTextureLevelParameterfv(GLuint texture, GLint level, + GLenum pname, GLfloat *params); + +extern void GLAPIENTRY +_mesa_GetTextureLevelParameteriv(GLuint texture, GLint level, + GLenum pname, GLint *params); + + extern void GLAPIENTRY _mesa_GetTexParameterfv( GLenum target, GLenum pname, GLfloat *params ); @@ -51,25 +103,53 @@ extern void GLAPIENTRY _mesa_GetTexParameterIuiv(GLenum target, GLenum pname, GLuint *params); +extern void GLAPIENTRY +_mesa_GetTextureParameterfv(GLuint texture, GLenum pname, GLfloat *params); + +extern void GLAPIENTRY +_mesa_GetTextureParameteriv(GLuint texture, GLenum pname, GLint *params); + +extern void GLAPIENTRY +_mesa_GetTextureParameterIiv(GLuint texture, GLenum pname, GLint *params); + +extern void GLAPIENTRY +_mesa_GetTextureParameterIuiv(GLuint texture, GLenum pname, GLuint *params); + + extern void GLAPIENTRY _mesa_TexParameterfv( GLenum target, GLenum pname, const GLfloat *params ); extern void GLAPIENTRY _mesa_TexParameterf( GLenum target, GLenum pname, GLfloat param ); - extern void GLAPIENTRY _mesa_TexParameteri( GLenum target, GLenum pname, GLint param ); extern void GLAPIENTRY _mesa_TexParameteriv( GLenum target, GLenum pname, const GLint *params ); - extern void GLAPIENTRY _mesa_TexParameterIiv(GLenum target, GLenum pname, const GLint *params); extern void GLAPIENTRY _mesa_TexParameterIuiv(GLenum target, GLenum pname, const GLuint *params); +extern void GLAPIENTRY +_mesa_TextureParameterfv(GLuint texture, GLenum pname, const GLfloat *params); + +extern void GLAPIENTRY +_mesa_TextureParameterf(GLuint texture, GLenum pname, GLfloat param); + +extern void GLAPIENTRY +_mesa_TextureParameteri(GLuint texture, GLenum pname, GLint param); + +extern void GLAPIENTRY +_mesa_TextureParameteriv(GLuint texture, GLenum pname, const GLint *params); + +extern void GLAPIENTRY +_mesa_TextureParameterIiv(GLuint texture, GLenum pname, const GLint *params); + +extern void GLAPIENTRY +_mesa_TextureParameterIuiv(GLuint texture, GLenum pname, const GLuint *params); #endif /* TEXPARAM_H */ diff --git a/mesalib/src/mesa/main/texstate.c b/mesalib/src/mesa/main/texstate.c index e0f085218..99c7c8178 100644 --- a/mesalib/src/mesa/main/texstate.c +++ b/mesalib/src/mesa/main/texstate.c @@ -22,7 +22,7 @@ * OTHER DEALINGS IN THE SOFTWARE. */ -/** +/** * \file texstate.c * * Texture state handling. @@ -40,7 +40,7 @@ #include "teximage.h" #include "texstate.h" #include "mtypes.h" -#include "bitset.h" +#include "util/bitset.h" /** @@ -153,7 +153,7 @@ _mesa_print_texunit_state( struct gl_context *ctx, GLuint unit ) /** * Convert "classic" texture environment to ARB_texture_env_combine style * environments. - * + * * \param state texture_env_combine state vector to be filled-in. * \param mode Classic texture environment mode (i.e., \c GL_REPLACE, * \c GL_BLEND, \c GL_DECAL, etc.). @@ -186,7 +186,7 @@ calculate_derived_texenv( struct gl_tex_env_combine_state *state, case GL_YCBCR_MESA: state->SourceA[0] = GL_PREVIOUS; break; - + default: _mesa_problem(NULL, "Invalid texBaseFormat 0x%x in calculate_derived_texenv", @@ -203,7 +203,7 @@ calculate_derived_texenv( struct gl_tex_env_combine_state *state, mode_rgb = (texBaseFormat == GL_ALPHA) ? GL_REPLACE : mode; mode_a = mode; break; - + case GL_DECAL: mode_rgb = GL_INTERPOLATE; mode_a = GL_REPLACE; @@ -272,7 +272,7 @@ calculate_derived_texenv( struct gl_tex_env_combine_state *state, mode); return; } - + state->ModeRGB = (state->SourceRGB[0] != GL_PREVIOUS) ? mode_rgb : GL_REPLACE; state->ModeA = (state->SourceA[0] != GL_PREVIOUS) @@ -290,9 +290,7 @@ _mesa_ActiveTexture(GLenum texture) GLuint k; GET_CURRENT_CONTEXT(ctx); - /* See OpenGL spec for glActiveTexture: */ - k = MAX2(ctx->Const.MaxCombinedTextureImageUnits, - ctx->Const.MaxTextureCoordUnits); + k = _mesa_max_tex_unit(ctx); ASSERT(k <= Elements(ctx->Texture.Unit)); @@ -769,11 +767,11 @@ _mesa_update_texture( struct gl_context *ctx, GLuint new_state ) /** * Allocate the proxy textures for the given context. - * + * * \param ctx the context to allocate proxies for. - * + * * \return GL_TRUE on success, or GL_FALSE on failure - * + * * If run out of memory part way through the allocations, clean up and return * GL_FALSE. */ @@ -944,7 +942,7 @@ _mesa_free_texture_data(struct gl_context *ctx) /** * Update the default texture objects in the given context to reference those - * specified in the shared state and release those referencing the old + * specified in the shared state and release those referencing the old * shared state. */ void diff --git a/mesalib/src/mesa/main/texstate.h b/mesalib/src/mesa/main/texstate.h index 5cd1684f2..abc07eafb 100644 --- a/mesalib/src/mesa/main/texstate.h +++ b/mesalib/src/mesa/main/texstate.h @@ -33,9 +33,18 @@ #include "compiler.h" +#include "enums.h" +#include "macros.h" #include "mtypes.h" +static inline struct gl_texture_unit * +_mesa_get_tex_unit(struct gl_context *ctx, GLuint unit) +{ + ASSERT(unit < Elements(ctx->Texture.Unit)); + return &(ctx->Texture.Unit[unit]); +} + /** * Return pointer to current texture unit. * This the texture unit set by glActiveTexture(), not glClientActiveTexture(). @@ -43,8 +52,33 @@ static inline struct gl_texture_unit * _mesa_get_current_tex_unit(struct gl_context *ctx) { - ASSERT(ctx->Texture.CurrentUnit < Elements(ctx->Texture.Unit)); - return &(ctx->Texture.Unit[ctx->Texture.CurrentUnit]); + return _mesa_get_tex_unit(ctx, ctx->Texture.CurrentUnit); +} + +static inline GLuint +_mesa_max_tex_unit(struct gl_context *ctx) +{ + /* See OpenGL spec for glActiveTexture: */ + return MAX2(ctx->Const.MaxCombinedTextureImageUnits, + ctx->Const.MaxTextureCoordUnits); +} + +static inline struct gl_texture_unit * +_mesa_get_tex_unit_err(struct gl_context *ctx, GLuint unit, const char *func) +{ + if (unit < _mesa_max_tex_unit(ctx)) + return _mesa_get_tex_unit(ctx, unit); + + /* Note: This error is a precedent set by glBindTextures. From the GL 4.5 + * specification (30.10.2014) Section 8.1 ("Texture Objects"): + * + * "An INVALID_OPERATION error is generated if first + count is greater + * than the number of texture image units supported by the + * implementation." + */ + _mesa_error(ctx, GL_INVALID_OPERATION, "%s(unit=%s)", func, + _mesa_lookup_enum_by_nr(GL_TEXTURE0+unit)); + return NULL; } diff --git a/mesalib/src/mesa/main/texstorage.c b/mesalib/src/mesa/main/texstorage.c index 897d5891a..3ace5e8bb 100644 --- a/mesalib/src/mesa/main/texstorage.c +++ b/mesalib/src/mesa/main/texstorage.c @@ -42,7 +42,7 @@ #include "textureview.h" #include "mtypes.h" #include "glformats.h" - +#include "hash.h" /** @@ -242,10 +242,10 @@ _mesa_is_legal_tex_storage_format(struct gl_context *ctx, GLenum internalformat) * checks at glTexImage* time. */ GLboolean -_mesa_alloc_texture_storage(struct gl_context *ctx, - struct gl_texture_object *texObj, - GLsizei levels, GLsizei width, - GLsizei height, GLsizei depth) +_mesa_AllocTextureStorage_sw(struct gl_context *ctx, + struct gl_texture_object *texObj, + GLsizei levels, GLsizei width, + GLsizei height, GLsizei depth) { const int numFaces = _mesa_num_tex_faces(texObj->Target); int face; @@ -274,34 +274,26 @@ _mesa_alloc_texture_storage(struct gl_context *ctx, * \return GL_TRUE if any error, GL_FALSE otherwise. */ static GLboolean -tex_storage_error_check(struct gl_context *ctx, GLuint dims, GLenum target, +tex_storage_error_check(struct gl_context *ctx, + struct gl_texture_object *texObj, + GLuint dims, GLenum target, GLsizei levels, GLenum internalformat, - GLsizei width, GLsizei height, GLsizei depth) + GLsizei width, GLsizei height, GLsizei depth, + bool dsa) { - struct gl_texture_object *texObj; + const char* suffix = dsa ? "ture" : ""; - if (!_mesa_is_legal_tex_storage_format(ctx, internalformat)) { - _mesa_error(ctx, GL_INVALID_ENUM, - "glTexStorage%uD(internalformat = %s)", dims, - _mesa_lookup_enum_by_nr(internalformat)); - return GL_TRUE; - } + /* Legal format checking has been moved to texstorage and texturestorage in + * order to allow meta functions to use legacy formats. */ /* size check */ if (width < 1 || height < 1 || depth < 1) { _mesa_error(ctx, GL_INVALID_VALUE, - "glTexStorage%uD(width, height or depth < 1)", dims); + "glTex%sStorage%uD(width, height or depth < 1)", + suffix, dims); return GL_TRUE; } - /* target check */ - if (!legal_texobj_target(ctx, dims, target)) { - _mesa_error(ctx, GL_INVALID_ENUM, - "glTexStorage%uD(illegal target=%s)", - dims, _mesa_lookup_enum_by_nr(target)); - return GL_TRUE; - } - /* From section 3.8.6, page 146 of OpenGL ES 3.0 spec: * * "The ETC2/EAC texture compression algorithm supports only @@ -315,50 +307,54 @@ tex_storage_error_check(struct gl_context *ctx, GLuint dims, GLenum target, && !_mesa_target_can_be_compressed(ctx, target, internalformat)) { _mesa_error(ctx, _mesa_is_desktop_gl(ctx)? GL_INVALID_ENUM : GL_INVALID_OPERATION, - "glTexStorage3D(internalformat = %s)", + "glTex%sStorage%dD(internalformat = %s)", suffix, dims, _mesa_lookup_enum_by_nr(internalformat)); } /* levels check */ if (levels < 1) { - _mesa_error(ctx, GL_INVALID_VALUE, "glTexStorage%uD(levels < 1)", - dims); + _mesa_error(ctx, GL_INVALID_VALUE, "glTex%sStorage%uD(levels < 1)", + suffix, dims); return GL_TRUE; } /* check levels against maximum (note different error than above) */ if (levels > (GLint) _mesa_max_texture_levels(ctx, target)) { _mesa_error(ctx, GL_INVALID_OPERATION, - "glTexStorage%uD(levels too large)", dims); + "glTex%sStorage%uD(levels too large)", + suffix, dims); return GL_TRUE; } /* check levels against width/height/depth */ if (levels > _mesa_get_tex_max_num_levels(target, width, height, depth)) { _mesa_error(ctx, GL_INVALID_OPERATION, - "glTexStorage%uD(too many levels for max texture dimension)", - dims); + "glTex%sStorage%uD(too many levels" + " for max texture dimension)", + suffix, dims); return GL_TRUE; } /* non-default texture object check */ - texObj = _mesa_get_current_tex_object(ctx, target); if (!_mesa_is_proxy_texture(target) && (!texObj || (texObj->Name == 0))) { _mesa_error(ctx, GL_INVALID_OPERATION, - "glTexStorage%uD(texture object 0)", dims); + "glTex%sStorage%uD(texture object 0)", + suffix, dims); return GL_TRUE; } /* Check if texObj->Immutable is set */ if (!_mesa_is_proxy_texture(target) && texObj->Immutable) { - _mesa_error(ctx, GL_INVALID_OPERATION, "glTexStorage%uD(immutable)", - dims); + _mesa_error(ctx, GL_INVALID_OPERATION, "glTex%sStorage%uD(immutable)", + suffix, dims); return GL_TRUE; } /* additional checks for depth textures */ if (!_mesa_legal_texture_base_format_for_target(ctx, target, internalformat, - dims, "glTexStorage")) + dims, dsa ? + "glTextureStorage" : + "glTexStorage")) return GL_TRUE; return GL_FALSE; @@ -366,32 +362,27 @@ tex_storage_error_check(struct gl_context *ctx, GLuint dims, GLenum target, /** - * Helper used by _mesa_TexStorage1/2/3D(). + * Helper that does the storage allocation for _mesa_TexStorage1/2/3D() + * and _mesa_TextureStorage1/2/3D(). */ -static void -texstorage(GLuint dims, GLenum target, GLsizei levels, GLenum internalformat, - GLsizei width, GLsizei height, GLsizei depth) +void +_mesa_texture_storage(struct gl_context *ctx, GLuint dims, + struct gl_texture_object *texObj, + GLenum target, GLsizei levels, + GLenum internalformat, GLsizei width, + GLsizei height, GLsizei depth, bool dsa) { - struct gl_texture_object *texObj; GLboolean sizeOK, dimensionsOK; mesa_format texFormat; + const char* suffix = dsa ? "ture" : ""; - GET_CURRENT_CONTEXT(ctx); - - if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) - _mesa_debug(ctx, "glTexStorage%uD %s %d %s %d %d %d\n", - dims, - _mesa_lookup_enum_by_nr(target), levels, - _mesa_lookup_enum_by_nr(internalformat), - width, height, depth); + assert(texObj); - if (tex_storage_error_check(ctx, dims, target, levels, - internalformat, width, height, depth)) { + if (tex_storage_error_check(ctx, texObj, dims, target, levels, + internalformat, width, height, depth, dsa)) { return; /* error was recorded */ } - texObj = _mesa_get_current_tex_object(ctx, target); - assert(texObj); texFormat = _mesa_choose_texture_format(ctx, texObj, target, 0, internalformat, GL_NONE, GL_NONE); @@ -404,7 +395,7 @@ texstorage(GLuint dims, GLenum target, GLsizei levels, GLenum internalformat, sizeOK = ctx->Driver.TestProxyTexImage(ctx, target, 0, texFormat, width, height, depth, 0); - if (_mesa_is_proxy_texture(texObj->Target)) { + if (_mesa_is_proxy_texture(target)) { if (dimensionsOK && sizeOK) { initialize_texture_fields(ctx, texObj, levels, width, height, depth, internalformat, texFormat); @@ -417,13 +408,15 @@ texstorage(GLuint dims, GLenum target, GLsizei levels, GLenum internalformat, else { if (!dimensionsOK) { _mesa_error(ctx, GL_INVALID_VALUE, - "glTexStorage%uD(invalid width, height or depth)", dims); + "glTex%sStorage%uD(invalid width, height or depth)", + suffix, dims); return; } if (!sizeOK) { _mesa_error(ctx, GL_OUT_OF_MEMORY, - "glTexStorage%uD(texture too large)", dims); + "glTex%sStorage%uD(texture too large)", + suffix, dims); } assert(levels > 0); @@ -445,7 +438,8 @@ texstorage(GLuint dims, GLenum target, GLsizei levels, GLenum internalformat, * state but this puts things in a consistent state. */ clear_texture_fields(ctx, texObj); - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexStorage%uD", dims); + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTex%sStorage%uD", + suffix, dims); return; } @@ -454,6 +448,94 @@ texstorage(GLuint dims, GLenum target, GLsizei levels, GLenum internalformat, } } +/** + * Helper used by _mesa_TexStorage1/2/3D(). + */ +static void +texstorage(GLuint dims, GLenum target, GLsizei levels, GLenum internalformat, + GLsizei width, GLsizei height, GLsizei depth) +{ + struct gl_texture_object *texObj; + GET_CURRENT_CONTEXT(ctx); + + /* target check */ + /* This is done here so that _mesa_texture_storage can receive unsized + * formats. */ + if (!legal_texobj_target(ctx, dims, target)) { + _mesa_error(ctx, GL_INVALID_ENUM, + "glTexStorage%uD(illegal target=%s)", + dims, _mesa_lookup_enum_by_nr(target)); + return; + } + + if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) + _mesa_debug(ctx, "glTexStorage%uD %s %d %s %d %d %d\n", + dims, + _mesa_lookup_enum_by_nr(target), levels, + _mesa_lookup_enum_by_nr(internalformat), + width, height, depth); + /* Check the format to make sure it is sized. */ + if (!_mesa_is_legal_tex_storage_format(ctx, internalformat)) { + _mesa_error(ctx, GL_INVALID_ENUM, + "glTexStorage%uD(internalformat = %s)", dims, + _mesa_lookup_enum_by_nr(internalformat)); + return; + } + + texObj = _mesa_get_current_tex_object(ctx, target); + if (!texObj) + return; + + _mesa_texture_storage(ctx, dims, texObj, target, levels, + internalformat, width, height, depth, false); +} + +/** + * Helper used by _mesa_TextureStorage1/2/3D(). + */ +static void +texturestorage(GLuint dims, GLuint texture, GLsizei levels, + GLenum internalformat, GLsizei width, GLsizei height, + GLsizei depth) +{ + struct gl_texture_object *texObj; + GET_CURRENT_CONTEXT(ctx); + + if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) + _mesa_debug(ctx, "glTextureStorage%uD %d %d %s %d %d %d\n", + dims, texture, levels, + _mesa_lookup_enum_by_nr(internalformat), + width, height, depth); + + /* Check the format to make sure it is sized. */ + if (!_mesa_is_legal_tex_storage_format(ctx, internalformat)) { + _mesa_error(ctx, GL_INVALID_ENUM, + "glTextureStorage%uD(internalformat = %s)", dims, + _mesa_lookup_enum_by_nr(internalformat)); + return; + } + + /* Get the texture object by Name. */ + texObj = _mesa_lookup_texture(ctx, texture); + if (!texObj) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glTextureStorage%uD(texture = %d)", dims, texture); + return; + } + + /* target check */ + /* This is done here so that _mesa_texture_storage can receive unsized + * formats. */ + if (!legal_texobj_target(ctx, dims, texObj->Target)) { + _mesa_error(ctx, GL_INVALID_ENUM, + "glTextureStorage%uD(illegal target=%s)", + dims, _mesa_lookup_enum_by_nr(texObj->Target)); + return; + } + + _mesa_texture_storage(ctx, dims, texObj, texObj->Target, + levels, internalformat, width, height, depth, true); +} void GLAPIENTRY _mesa_TexStorage1D(GLenum target, GLsizei levels, GLenum internalformat, @@ -478,6 +560,28 @@ _mesa_TexStorage3D(GLenum target, GLsizei levels, GLenum internalformat, texstorage(3, target, levels, internalformat, width, height, depth); } +void GLAPIENTRY +_mesa_TextureStorage1D(GLuint texture, GLsizei levels, GLenum internalformat, + GLsizei width) +{ + texturestorage(1, texture, levels, internalformat, width, 1, 1); +} + + +void GLAPIENTRY +_mesa_TextureStorage2D(GLuint texture, GLsizei levels, + GLenum internalformat, + GLsizei width, GLsizei height) +{ + texturestorage(2, texture, levels, internalformat, width, height, 1); +} + +void GLAPIENTRY +_mesa_TextureStorage3D(GLuint texture, GLsizei levels, GLenum internalformat, + GLsizei width, GLsizei height, GLsizei depth) +{ + texturestorage(3, texture, levels, internalformat, width, height, depth); +} /* diff --git a/mesalib/src/mesa/main/texstorage.h b/mesalib/src/mesa/main/texstorage.h index ec4f71374..6f5495f38 100644 --- a/mesalib/src/mesa/main/texstorage.h +++ b/mesalib/src/mesa/main/texstorage.h @@ -26,6 +26,24 @@ #ifndef TEXSTORAGE_H #define TEXSTORAGE_H +/** + * \name Internal functions + */ +/*@{*/ + +extern void +_mesa_texture_storage(struct gl_context *ctx, GLuint dims, + struct gl_texture_object *texObj, + GLenum target, GLsizei levels, + GLenum internalformat, GLsizei width, + GLsizei height, GLsizei depth, bool dsa); + +/*@}*/ + +/** + * \name API functions + */ +/*@{*/ extern void GLAPIENTRY _mesa_TexStorage1D(GLenum target, GLsizei levels, GLenum internalformat, @@ -41,6 +59,19 @@ extern void GLAPIENTRY _mesa_TexStorage3D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); +extern void GLAPIENTRY +_mesa_TextureStorage1D(GLuint texture, GLsizei levels, GLenum internalformat, + GLsizei width); + + +extern void GLAPIENTRY +_mesa_TextureStorage2D(GLuint texture, GLsizei levels, GLenum internalformat, + GLsizei width, GLsizei height); + + +extern void GLAPIENTRY +_mesa_TextureStorage3D(GLuint texture, GLsizei levels, GLenum internalformat, + GLsizei width, GLsizei height, GLsizei depth); extern void GLAPIENTRY @@ -62,9 +93,9 @@ extern GLboolean _mesa_is_legal_tex_storage_format(struct gl_context *ctx, GLenum internalformat); extern GLboolean -_mesa_alloc_texture_storage(struct gl_context *ctx, - struct gl_texture_object *texObj, - GLsizei levels, GLsizei width, - GLsizei height, GLsizei depth); +_mesa_AllocTextureStorage_sw(struct gl_context *ctx, + struct gl_texture_object *texObj, + GLsizei levels, GLsizei width, + GLsizei height, GLsizei depth); #endif /* TEXSTORAGE_H */ diff --git a/mesalib/src/mesa/main/texstore.c b/mesalib/src/mesa/main/texstore.c index f858cef50..7039cdf81 100644 --- a/mesalib/src/mesa/main/texstore.c +++ b/mesalib/src/mesa/main/texstore.c @@ -73,6 +73,7 @@ #include "texstore.h" #include "enums.h" #include "glformats.h" +#include "pixeltransfer.h" #include "../../gallium/auxiliary/util/u_format_rgb9e5.h" #include "../../gallium/auxiliary/util/u_format_r11g11b10f.h" @@ -87,577 +88,6 @@ enum { * Texture image storage function. */ typedef GLboolean (*StoreTexImageFunc)(TEXSTORE_PARAMS); - - -enum { - IDX_LUMINANCE = 0, - IDX_ALPHA, - IDX_INTENSITY, - IDX_LUMINANCE_ALPHA, - IDX_RGB, - IDX_RGBA, - IDX_RED, - IDX_GREEN, - IDX_BLUE, - IDX_BGR, - IDX_BGRA, - IDX_ABGR, - IDX_RG, - MAX_IDX -}; - -#define MAP1(x) MAP4(x, ZERO, ZERO, ZERO) -#define MAP2(x,y) MAP4(x, y, ZERO, ZERO) -#define MAP3(x,y,z) MAP4(x, y, z, ZERO) -#define MAP4(x,y,z,w) { x, y, z, w, ZERO, ONE } - - -static const struct { - GLubyte format_idx; - GLubyte to_rgba[6]; - GLubyte from_rgba[6]; -} mappings[MAX_IDX] = -{ - { - IDX_LUMINANCE, - MAP4(0,0,0,ONE), - MAP1(0) - }, - - { - IDX_ALPHA, - MAP4(ZERO, ZERO, ZERO, 0), - MAP1(3) - }, - - { - IDX_INTENSITY, - MAP4(0, 0, 0, 0), - MAP1(0), - }, - - { - IDX_LUMINANCE_ALPHA, - MAP4(0,0,0,1), - MAP2(0,3) - }, - - { - IDX_RGB, - MAP4(0,1,2,ONE), - MAP3(0,1,2) - }, - - { - IDX_RGBA, - MAP4(0,1,2,3), - MAP4(0,1,2,3), - }, - - { - IDX_RED, - MAP4(0, ZERO, ZERO, ONE), - MAP1(0), - }, - - { - IDX_GREEN, - MAP4(ZERO, 0, ZERO, ONE), - MAP1(1), - }, - - { - IDX_BLUE, - MAP4(ZERO, ZERO, 0, ONE), - MAP1(2), - }, - - { - IDX_BGR, - MAP4(2,1,0,ONE), - MAP3(2,1,0) - }, - - { - IDX_BGRA, - MAP4(2,1,0,3), - MAP4(2,1,0,3) - }, - - { - IDX_ABGR, - MAP4(3,2,1,0), - MAP4(3,2,1,0) - }, - - { - IDX_RG, - MAP4(0, 1, ZERO, ONE), - MAP2(0, 1) - }, -}; - - - -/** - * Convert a GL image format enum to an IDX_* value (see above). - */ -static int -get_map_idx(GLenum value) -{ - switch (value) { - case GL_LUMINANCE: - case GL_LUMINANCE_INTEGER_EXT: - return IDX_LUMINANCE; - case GL_ALPHA: - case GL_ALPHA_INTEGER: - return IDX_ALPHA; - case GL_INTENSITY: - return IDX_INTENSITY; - case GL_LUMINANCE_ALPHA: - case GL_LUMINANCE_ALPHA_INTEGER_EXT: - return IDX_LUMINANCE_ALPHA; - case GL_RGB: - case GL_RGB_INTEGER: - return IDX_RGB; - case GL_RGBA: - case GL_RGBA_INTEGER: - return IDX_RGBA; - case GL_RED: - case GL_RED_INTEGER: - return IDX_RED; - case GL_GREEN: - return IDX_GREEN; - case GL_BLUE: - return IDX_BLUE; - case GL_BGR: - case GL_BGR_INTEGER: - return IDX_BGR; - case GL_BGRA: - case GL_BGRA_INTEGER: - return IDX_BGRA; - case GL_ABGR_EXT: - return IDX_ABGR; - case GL_RG: - case GL_RG_INTEGER: - return IDX_RG; - default: - _mesa_problem(NULL, "Unexpected inFormat %s", - _mesa_lookup_enum_by_nr(value)); - return 0; - } -} - - -/** - * When promoting texture formats (see below) we need to compute the - * mapping of dest components back to source components. - * This function does that. - * \param inFormat the incoming format of the texture - * \param outFormat the final texture format - * \return map[6] a full 6-component map - */ -static void -compute_component_mapping(GLenum inFormat, GLenum outFormat, - GLubyte *map) -{ - const int inFmt = get_map_idx(inFormat); - const int outFmt = get_map_idx(outFormat); - const GLubyte *in2rgba = mappings[inFmt].to_rgba; - const GLubyte *rgba2out = mappings[outFmt].from_rgba; - int i; - - for (i = 0; i < 4; i++) - map[i] = in2rgba[rgba2out[i]]; - - map[ZERO] = ZERO; - map[ONE] = ONE; - -#if 0 - printf("from %x/%s to %x/%s map %d %d %d %d %d %d\n", - inFormat, _mesa_lookup_enum_by_nr(inFormat), - outFormat, _mesa_lookup_enum_by_nr(outFormat), - map[0], - map[1], - map[2], - map[3], - map[4], - map[5]); -#endif -} - - -/** - * Make a temporary (color) texture image with GLfloat components. - * Apply all needed pixel unpacking and pixel transfer operations. - * Note that there are both logicalBaseFormat and textureBaseFormat parameters. - * Suppose the user specifies GL_LUMINANCE as the internal texture format - * but the graphics hardware doesn't support luminance textures. So, we might - * use an RGB hardware format instead. - * If logicalBaseFormat != textureBaseFormat we have some extra work to do. - * - * \param ctx the rendering context - * \param dims image dimensions: 1, 2 or 3 - * \param logicalBaseFormat basic texture derived from the user's - * internal texture format value - * \param textureBaseFormat the actual basic format of the texture - * \param srcWidth source image width - * \param srcHeight source image height - * \param srcDepth source image depth - * \param srcFormat source image format - * \param srcType source image type - * \param srcAddr source image address - * \param srcPacking source image pixel packing - * \return resulting image with format = textureBaseFormat and type = GLfloat. - */ -GLfloat * -_mesa_make_temp_float_image(struct gl_context *ctx, GLuint dims, - GLenum logicalBaseFormat, - GLenum textureBaseFormat, - GLint srcWidth, GLint srcHeight, GLint srcDepth, - GLenum srcFormat, GLenum srcType, - const GLvoid *srcAddr, - const struct gl_pixelstore_attrib *srcPacking, - GLbitfield transferOps) -{ - GLfloat *tempImage; - const GLint components = _mesa_components_in_format(logicalBaseFormat); - const GLint srcStride = - _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType); - GLfloat *dst; - GLint img, row; - - ASSERT(dims >= 1 && dims <= 3); - - ASSERT(logicalBaseFormat == GL_RGBA || - logicalBaseFormat == GL_RGB || - logicalBaseFormat == GL_RG || - logicalBaseFormat == GL_RED || - logicalBaseFormat == GL_LUMINANCE_ALPHA || - logicalBaseFormat == GL_LUMINANCE || - logicalBaseFormat == GL_ALPHA || - logicalBaseFormat == GL_INTENSITY || - logicalBaseFormat == GL_DEPTH_COMPONENT); - - ASSERT(textureBaseFormat == GL_RGBA || - textureBaseFormat == GL_RGB || - textureBaseFormat == GL_RG || - textureBaseFormat == GL_RED || - textureBaseFormat == GL_LUMINANCE_ALPHA || - textureBaseFormat == GL_LUMINANCE || - textureBaseFormat == GL_ALPHA || - textureBaseFormat == GL_INTENSITY || - textureBaseFormat == GL_DEPTH_COMPONENT); - - tempImage = malloc(srcWidth * srcHeight * srcDepth - * components * sizeof(GLfloat)); - if (!tempImage) - return NULL; - - dst = tempImage; - for (img = 0; img < srcDepth; img++) { - const GLubyte *src - = (const GLubyte *) _mesa_image_address(dims, srcPacking, srcAddr, - srcWidth, srcHeight, - srcFormat, srcType, - img, 0, 0); - for (row = 0; row < srcHeight; row++) { - _mesa_unpack_color_span_float(ctx, srcWidth, logicalBaseFormat, - dst, srcFormat, srcType, src, - srcPacking, transferOps); - dst += srcWidth * components; - src += srcStride; - } - } - - if (logicalBaseFormat != textureBaseFormat) { - /* more work */ - GLint texComponents = _mesa_components_in_format(textureBaseFormat); - GLint logComponents = _mesa_components_in_format(logicalBaseFormat); - GLfloat *newImage; - GLint i, n; - GLubyte map[6]; - - /* we only promote up to RGB, RGBA and LUMINANCE_ALPHA formats for now */ - ASSERT(textureBaseFormat == GL_RGB || textureBaseFormat == GL_RGBA || - textureBaseFormat == GL_LUMINANCE_ALPHA); - - /* The actual texture format should have at least as many components - * as the logical texture format. - */ - ASSERT(texComponents >= logComponents); - - newImage = malloc(srcWidth * srcHeight * srcDepth - * texComponents * sizeof(GLfloat)); - if (!newImage) { - free(tempImage); - return NULL; - } - - compute_component_mapping(logicalBaseFormat, textureBaseFormat, map); - - n = srcWidth * srcHeight * srcDepth; - for (i = 0; i < n; i++) { - GLint k; - for (k = 0; k < texComponents; k++) { - GLint j = map[k]; - if (j == ZERO) - newImage[i * texComponents + k] = 0.0F; - else if (j == ONE) - newImage[i * texComponents + k] = 1.0F; - else - newImage[i * texComponents + k] = tempImage[i * logComponents + j]; - } - } - - free(tempImage); - tempImage = newImage; - } - - return tempImage; -} - - -/** - * Make temporary image with uint pixel values. Used for unsigned - * integer-valued textures. - */ -static GLuint * -make_temp_uint_image(struct gl_context *ctx, GLuint dims, - GLenum logicalBaseFormat, - GLenum textureBaseFormat, - GLint srcWidth, GLint srcHeight, GLint srcDepth, - GLenum srcFormat, GLenum srcType, - const GLvoid *srcAddr, - const struct gl_pixelstore_attrib *srcPacking) -{ - GLuint *tempImage; - const GLint components = _mesa_components_in_format(logicalBaseFormat); - const GLint srcStride = - _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType); - GLuint *dst; - GLint img, row; - - ASSERT(dims >= 1 && dims <= 3); - - ASSERT(logicalBaseFormat == GL_RGBA || - logicalBaseFormat == GL_RGB || - logicalBaseFormat == GL_RG || - logicalBaseFormat == GL_RED || - logicalBaseFormat == GL_LUMINANCE_ALPHA || - logicalBaseFormat == GL_LUMINANCE || - logicalBaseFormat == GL_INTENSITY || - logicalBaseFormat == GL_ALPHA); - - ASSERT(textureBaseFormat == GL_RGBA || - textureBaseFormat == GL_RGB || - textureBaseFormat == GL_RG || - textureBaseFormat == GL_RED || - textureBaseFormat == GL_LUMINANCE_ALPHA || - textureBaseFormat == GL_LUMINANCE || - textureBaseFormat == GL_INTENSITY || - textureBaseFormat == GL_ALPHA); - - tempImage = malloc(srcWidth * srcHeight * srcDepth - * components * sizeof(GLuint)); - if (!tempImage) - return NULL; - - dst = tempImage; - for (img = 0; img < srcDepth; img++) { - const GLubyte *src - = (const GLubyte *) _mesa_image_address(dims, srcPacking, srcAddr, - srcWidth, srcHeight, - srcFormat, srcType, - img, 0, 0); - for (row = 0; row < srcHeight; row++) { - _mesa_unpack_color_span_uint(ctx, srcWidth, logicalBaseFormat, - dst, srcFormat, srcType, src, - srcPacking); - dst += srcWidth * components; - src += srcStride; - } - } - - if (logicalBaseFormat != textureBaseFormat) { - /* more work */ - GLint texComponents = _mesa_components_in_format(textureBaseFormat); - GLint logComponents = _mesa_components_in_format(logicalBaseFormat); - GLuint *newImage; - GLint i, n; - GLubyte map[6]; - - /* we only promote up to RGB, RGBA and LUMINANCE_ALPHA formats for now */ - ASSERT(textureBaseFormat == GL_RGB || textureBaseFormat == GL_RGBA || - textureBaseFormat == GL_LUMINANCE_ALPHA); - - /* The actual texture format should have at least as many components - * as the logical texture format. - */ - ASSERT(texComponents >= logComponents); - - newImage = malloc(srcWidth * srcHeight * srcDepth - * texComponents * sizeof(GLuint)); - if (!newImage) { - free(tempImage); - return NULL; - } - - compute_component_mapping(logicalBaseFormat, textureBaseFormat, map); - - n = srcWidth * srcHeight * srcDepth; - for (i = 0; i < n; i++) { - GLint k; - for (k = 0; k < texComponents; k++) { - GLint j = map[k]; - if (j == ZERO) - newImage[i * texComponents + k] = 0; - else if (j == ONE) - newImage[i * texComponents + k] = 1; - else - newImage[i * texComponents + k] = tempImage[i * logComponents + j]; - } - } - - free(tempImage); - tempImage = newImage; - } - - return tempImage; -} - - - -/** - * Make a temporary (color) texture image with GLubyte components. - * Apply all needed pixel unpacking and pixel transfer operations. - * Note that there are both logicalBaseFormat and textureBaseFormat parameters. - * Suppose the user specifies GL_LUMINANCE as the internal texture format - * but the graphics hardware doesn't support luminance textures. So, we might - * use an RGB hardware format instead. - * If logicalBaseFormat != textureBaseFormat we have some extra work to do. - * - * \param ctx the rendering context - * \param dims image dimensions: 1, 2 or 3 - * \param logicalBaseFormat basic texture derived from the user's - * internal texture format value - * \param textureBaseFormat the actual basic format of the texture - * \param srcWidth source image width - * \param srcHeight source image height - * \param srcDepth source image depth - * \param srcFormat source image format - * \param srcType source image type - * \param srcAddr source image address - * \param srcPacking source image pixel packing - * \return resulting image with format = textureBaseFormat and type = GLubyte. - */ -GLubyte * -_mesa_make_temp_ubyte_image(struct gl_context *ctx, GLuint dims, - GLenum logicalBaseFormat, - GLenum textureBaseFormat, - GLint srcWidth, GLint srcHeight, GLint srcDepth, - GLenum srcFormat, GLenum srcType, - const GLvoid *srcAddr, - const struct gl_pixelstore_attrib *srcPacking) -{ - GLuint transferOps = ctx->_ImageTransferState; - const GLint components = _mesa_components_in_format(logicalBaseFormat); - GLint img, row; - GLubyte *tempImage, *dst; - - ASSERT(dims >= 1 && dims <= 3); - - ASSERT(logicalBaseFormat == GL_RGBA || - logicalBaseFormat == GL_RGB || - logicalBaseFormat == GL_RG || - logicalBaseFormat == GL_RED || - logicalBaseFormat == GL_LUMINANCE_ALPHA || - logicalBaseFormat == GL_LUMINANCE || - logicalBaseFormat == GL_ALPHA || - logicalBaseFormat == GL_INTENSITY); - - ASSERT(textureBaseFormat == GL_RGBA || - textureBaseFormat == GL_RGB || - textureBaseFormat == GL_RG || - textureBaseFormat == GL_RED || - textureBaseFormat == GL_LUMINANCE_ALPHA || - textureBaseFormat == GL_LUMINANCE || - textureBaseFormat == GL_ALPHA || - textureBaseFormat == GL_INTENSITY); - - /* unpack and transfer the source image */ - tempImage = malloc(srcWidth * srcHeight * srcDepth - * components * sizeof(GLubyte)); - if (!tempImage) { - return NULL; - } - - dst = tempImage; - for (img = 0; img < srcDepth; img++) { - const GLint srcStride = - _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType); - const GLubyte *src = - (const GLubyte *) _mesa_image_address(dims, srcPacking, srcAddr, - srcWidth, srcHeight, - srcFormat, srcType, - img, 0, 0); - for (row = 0; row < srcHeight; row++) { - _mesa_unpack_color_span_ubyte(ctx, srcWidth, logicalBaseFormat, dst, - srcFormat, srcType, src, srcPacking, - transferOps); - dst += srcWidth * components; - src += srcStride; - } - } - - if (logicalBaseFormat != textureBaseFormat) { - /* one more conversion step */ - GLint texComponents = _mesa_components_in_format(textureBaseFormat); - GLint logComponents = _mesa_components_in_format(logicalBaseFormat); - GLubyte *newImage; - GLint i, n; - GLubyte map[6]; - - /* we only promote up to RGB, RGBA and LUMINANCE_ALPHA formats for now */ - ASSERT(textureBaseFormat == GL_RGB || textureBaseFormat == GL_RGBA || - textureBaseFormat == GL_LUMINANCE_ALPHA); - - /* The actual texture format should have at least as many components - * as the logical texture format. - */ - ASSERT(texComponents >= logComponents); - - newImage = malloc(srcWidth * srcHeight * srcDepth - * texComponents * sizeof(GLubyte)); - if (!newImage) { - free(tempImage); - return NULL; - } - - compute_component_mapping(logicalBaseFormat, textureBaseFormat, map); - - n = srcWidth * srcHeight * srcDepth; - for (i = 0; i < n; i++) { - GLint k; - for (k = 0; k < texComponents; k++) { - GLint j = map[k]; - if (j == ZERO) - newImage[i * texComponents + k] = 0; - else if (j == ONE) - newImage[i * texComponents + k] = 255; - else - newImage[i * texComponents + k] = tempImage[i * logComponents + j]; - } - } - - free(tempImage); - tempImage = newImage; - } - - return tempImage; -} - - static const GLubyte map_identity[6] = { 0, 1, 2, 3, ZERO, ONE }; static const GLubyte map_3210[6] = { 3, 2, 1, 0, ZERO, ONE }; static const GLubyte map_1032[6] = { 1, 0, 3, 2, ZERO, ONE }; @@ -715,46 +145,6 @@ memcpy_texture(struct gl_context *ctx, } -/** - * General-case function for storing a color texture images with - * components that can be represented with ubytes. Example destination - * texture formats are MESA_FORMAT_ARGB888, ARGB4444, RGB565. - */ -static GLboolean -store_ubyte_texture(TEXSTORE_PARAMS) -{ - const GLint srcRowStride = srcWidth * 4 * sizeof(GLubyte); - GLubyte *tempImage, *src; - GLint img; - - tempImage = _mesa_make_temp_ubyte_image(ctx, dims, - baseInternalFormat, - GL_RGBA, - srcWidth, srcHeight, srcDepth, - srcFormat, srcType, srcAddr, - srcPacking); - if (!tempImage) - return GL_FALSE; - - /* This way we will use the RGB versions of the packing functions and it - * will work for both RGB and sRGB textures*/ - dstFormat = _mesa_get_srgb_format_linear(dstFormat); - - src = tempImage; - for (img = 0; img < srcDepth; img++) { - _mesa_pack_ubyte_rgba_rect(dstFormat, srcWidth, srcHeight, - src, srcRowStride, - dstSlices[img], dstRowStride); - src += srcHeight * srcRowStride; - } - free(tempImage); - - return GL_TRUE; -} - - - - /** * Store a 32-bit integer or float depth component texture image. */ @@ -887,56 +277,6 @@ _mesa_texstore_z16(TEXSTORE_PARAMS) } -/** - * Store an rgb565 or rgb565_rev texture image. - */ -static GLboolean -_mesa_texstore_rgb565(TEXSTORE_PARAMS) -{ - ASSERT(dstFormat == MESA_FORMAT_B5G6R5_UNORM || - dstFormat == MESA_FORMAT_R5G6B5_UNORM); - ASSERT(_mesa_get_format_bytes(dstFormat) == 2); - - if (!ctx->_ImageTransferState && - !srcPacking->SwapBytes && - baseInternalFormat == GL_RGB && - srcFormat == GL_RGB && - srcType == GL_UNSIGNED_BYTE && - dims == 2) { - /* do optimized tex store */ - const GLint srcRowStride = - _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType); - const GLubyte *src = (const GLubyte *) - _mesa_image_address(dims, srcPacking, srcAddr, srcWidth, srcHeight, - srcFormat, srcType, 0, 0, 0); - GLubyte *dst = dstSlices[0]; - GLint row, col; - for (row = 0; row < srcHeight; row++) { - const GLubyte *srcUB = (const GLubyte *) src; - GLushort *dstUS = (GLushort *) dst; - /* check for byteswapped format */ - if (dstFormat == MESA_FORMAT_B5G6R5_UNORM) { - for (col = 0; col < srcWidth; col++) { - dstUS[col] = PACK_COLOR_565( srcUB[0], srcUB[1], srcUB[2] ); - srcUB += 3; - } - } - else { - for (col = 0; col < srcWidth; col++) { - dstUS[col] = PACK_COLOR_565_REV( srcUB[0], srcUB[1], srcUB[2] ); - srcUB += 3; - } - } - dst += dstRowStride; - src += srcRowStride; - } - return GL_TRUE; - } else { - return GL_FALSE; - } -} - - /** * Texstore for _mesa_texformat_ycbcr or _mesa_texformat_ycbcr_REV. */ @@ -1244,119 +584,6 @@ _mesa_texstore_z32f_x24s8(TEXSTORE_PARAMS) return GL_TRUE; } -static GLboolean -_mesa_texstore_argb2101010_uint(TEXSTORE_PARAMS) -{ - const GLenum baseFormat = _mesa_get_format_base_format(dstFormat); - - ASSERT(dstFormat == MESA_FORMAT_B10G10R10A2_UINT); - ASSERT(_mesa_get_format_bytes(dstFormat) == 4); - - { - /* general path */ - const GLuint *tempImage = make_temp_uint_image(ctx, dims, - baseInternalFormat, - baseFormat, - srcWidth, srcHeight, - srcDepth, srcFormat, - srcType, srcAddr, - srcPacking); - const GLuint *src = tempImage; - GLint img, row, col; - GLboolean is_unsigned = _mesa_is_type_unsigned(srcType); - if (!tempImage) - return GL_FALSE; - for (img = 0; img < srcDepth; img++) { - GLubyte *dstRow = dstSlices[img]; - - for (row = 0; row < srcHeight; row++) { - GLuint *dstUI = (GLuint *) dstRow; - if (is_unsigned) { - for (col = 0; col < srcWidth; col++) { - GLushort a,r,g,b; - r = MIN2(src[RCOMP], 0x3ff); - g = MIN2(src[GCOMP], 0x3ff); - b = MIN2(src[BCOMP], 0x3ff); - a = MIN2(src[ACOMP], 0x003); - dstUI[col] = (a << 30) | (r << 20) | (g << 10) | (b); - src += 4; - } - } else { - for (col = 0; col < srcWidth; col++) { - GLushort a,r,g,b; - r = CLAMP((GLint) src[RCOMP], 0, 0x3ff); - g = CLAMP((GLint) src[GCOMP], 0, 0x3ff); - b = CLAMP((GLint) src[BCOMP], 0, 0x3ff); - a = CLAMP((GLint) src[ACOMP], 0, 0x003); - dstUI[col] = (a << 30) | (r << 20) | (g << 10) | (b); - src += 4; - } - } - dstRow += dstRowStride; - } - } - free((void *) tempImage); - } - return GL_TRUE; -} - -static GLboolean -_mesa_texstore_abgr2101010_uint(TEXSTORE_PARAMS) -{ - const GLenum baseFormat = _mesa_get_format_base_format(dstFormat); - - ASSERT(dstFormat == MESA_FORMAT_R10G10B10A2_UINT); - ASSERT(_mesa_get_format_bytes(dstFormat) == 4); - - { - /* general path */ - const GLuint *tempImage = make_temp_uint_image(ctx, dims, - baseInternalFormat, - baseFormat, - srcWidth, srcHeight, - srcDepth, srcFormat, - srcType, srcAddr, - srcPacking); - const GLuint *src = tempImage; - GLint img, row, col; - GLboolean is_unsigned = _mesa_is_type_unsigned(srcType); - if (!tempImage) - return GL_FALSE; - for (img = 0; img < srcDepth; img++) { - GLubyte *dstRow = dstSlices[img]; - - for (row = 0; row < srcHeight; row++) { - GLuint *dstUI = (GLuint *) dstRow; - if (is_unsigned) { - for (col = 0; col < srcWidth; col++) { - GLushort a,r,g,b; - r = MIN2(src[RCOMP], 0x3ff); - g = MIN2(src[GCOMP], 0x3ff); - b = MIN2(src[BCOMP], 0x3ff); - a = MIN2(src[ACOMP], 0x003); - dstUI[col] = (a << 30) | (b << 20) | (g << 10) | (r); - src += 4; - } - } else { - for (col = 0; col < srcWidth; col++) { - GLushort a,r,g,b; - r = CLAMP((GLint) src[RCOMP], 0, 0x3ff); - g = CLAMP((GLint) src[GCOMP], 0, 0x3ff); - b = CLAMP((GLint) src[BCOMP], 0, 0x3ff); - a = CLAMP((GLint) src[ACOMP], 0, 0x003); - dstUI[col] = (a << 30) | (b << 20) | (g << 10) | (r); - src += 4; - } - } - dstRow += dstRowStride; - } - } - free((void *) tempImage); - } - return GL_TRUE; -} - - static GLboolean texstore_depth_stencil(TEXSTORE_PARAMS) { @@ -1446,329 +673,149 @@ texstore_compressed(TEXSTORE_PARAMS) srcFormat, srcType, srcAddr, srcPacking); } -static void -invert_swizzle(uint8_t dst[4], const uint8_t src[4]) -{ - int i, j; - - dst[0] = MESA_FORMAT_SWIZZLE_NONE; - dst[1] = MESA_FORMAT_SWIZZLE_NONE; - dst[2] = MESA_FORMAT_SWIZZLE_NONE; - dst[3] = MESA_FORMAT_SWIZZLE_NONE; - - for (i = 0; i < 4; ++i) - for (j = 0; j < 4; ++j) - if (src[j] == i && dst[i] == MESA_FORMAT_SWIZZLE_NONE) - dst[i] = j; -} - -/** Store a texture by per-channel conversions and swizzling. - * - * This function attempts to perform a texstore operation by doing simple - * per-channel conversions and swizzling. This covers a huge chunk of the - * texture storage operations that anyone cares about. If this function is - * incapable of performing the operation, it bails and returns GL_FALSE. - */ static GLboolean -texstore_swizzle(TEXSTORE_PARAMS) +texstore_rgba(TEXSTORE_PARAMS) { - const GLint srcRowStride = _mesa_image_row_stride(srcPacking, srcWidth, - srcFormat, srcType); - const GLint srcImageStride = _mesa_image_image_stride(srcPacking, - srcWidth, srcHeight, srcFormat, srcType); - const GLubyte *srcImage = (const GLubyte *) _mesa_image_address(dims, - srcPacking, srcAddr, srcWidth, srcHeight, srcFormat, srcType, 0, 0, 0); - const int src_components = _mesa_components_in_format(srcFormat); - - GLubyte swizzle[4], rgba2base[6], base2src[6], rgba2dst[4], dst2rgba[4]; - const GLubyte *swap; - GLenum dst_type; - int dst_components; - bool is_array, normalized, need_swap; - GLint i, img, row; - const GLubyte *src_row; - GLubyte *dst_row; - - is_array = _mesa_format_to_array(dstFormat, &dst_type, &dst_components, - rgba2dst, &normalized); - - if (!is_array) - return GL_FALSE; - - if (srcFormat == GL_COLOR_INDEX) - return GL_FALSE; - - if (_mesa_texstore_needs_transfer_ops(ctx, baseInternalFormat, dstFormat)) - return GL_FALSE; - - switch (srcType) { - case GL_FLOAT: - case GL_UNSIGNED_BYTE: - case GL_BYTE: - case GL_UNSIGNED_SHORT: - case GL_SHORT: - case GL_UNSIGNED_INT: - case GL_INT: - /* If wa have to swap bytes in a multi-byte datatype, that means - * we're not doing an array conversion anymore */ - if (srcPacking->SwapBytes) - return GL_FALSE; - need_swap = false; - break; - case GL_UNSIGNED_INT_8_8_8_8: - need_swap = srcPacking->SwapBytes; - if (_mesa_little_endian()) - need_swap = !need_swap; - srcType = GL_UNSIGNED_BYTE; - break; - case GL_UNSIGNED_INT_8_8_8_8_REV: - need_swap = srcPacking->SwapBytes; - if (!_mesa_little_endian()) - need_swap = !need_swap; - srcType = GL_UNSIGNED_BYTE; - break; - default: - return GL_FALSE; + void *tempImage = NULL, *tempRGBA = NULL; + int srcRowStride, img; + GLubyte *src, *dst; + uint32_t srcMesaFormat; + uint8_t rebaseSwizzle[4]; + bool needRebase; + bool transferOpsDone = false; + + /* We have to handle MESA_FORMAT_YCBCR manually because it is a special case + * and _mesa_format_convert does not support it. In this case the we only + * allow conversions between YCBCR formats and it is mostly a memcpy. + */ + if (dstFormat == MESA_FORMAT_YCBCR || dstFormat == MESA_FORMAT_YCBCR_REV) { + return _mesa_texstore_ycbcr(ctx, dims, baseInternalFormat, + dstFormat, dstRowStride, dstSlices, + srcWidth, srcHeight, srcDepth, + srcFormat, srcType, srcAddr, + srcPacking); } - swap = need_swap ? map_3210 : map_identity; - - compute_component_mapping(srcFormat, baseInternalFormat, base2src); - compute_component_mapping(baseInternalFormat, GL_RGBA, rgba2base); - invert_swizzle(dst2rgba, rgba2dst); - for (i = 0; i < 4; i++) { - if (dst2rgba[i] == MESA_FORMAT_SWIZZLE_NONE) - swizzle[i] = MESA_FORMAT_SWIZZLE_NONE; - else - swizzle[i] = swap[base2src[rgba2base[dst2rgba[i]]]]; - } + /* We have to deal with GL_COLOR_INDEX manually because + * _mesa_format_convert does not handle this format. So what we do here is + * convert it to RGBA ubyte first and then convert from that to dst as usual. + */ + if (srcFormat == GL_COLOR_INDEX) { + /* Notice that this will already handle byte swapping if necessary */ + tempImage = + _mesa_unpack_color_index_to_rgba_ubyte(ctx, dims, + srcAddr, srcFormat, srcType, + srcWidth, srcHeight, srcDepth, + srcPacking, + ctx->_ImageTransferState); + if (!tempImage) + return GL_FALSE; - /* Is it normalized? */ - normalized |= !_mesa_is_enum_format_integer(srcFormat); + /* _mesa_unpack_color_index_to_rgba_ubyte has handled transferops + * if needed. + */ + transferOpsDone = true; - for (img = 0; img < srcDepth; img++) { - if (dstRowStride == srcWidth * dst_components && - srcRowStride == srcWidth * src_components) { - _mesa_swizzle_and_convert(dstSlices[img], dst_type, dst_components, - srcImage, srcType, src_components, - swizzle, normalized, srcWidth * srcHeight); - } else { - src_row = srcImage; - dst_row = dstSlices[img]; - for (row = 0; row < srcHeight; row++) { - _mesa_swizzle_and_convert(dst_row, dst_type, dst_components, - src_row, srcType, src_components, - swizzle, normalized, srcWidth); - dst_row += dstRowStride; - src_row += srcRowStride; - } + /* Now we only have to adjust our src info for a conversion from + * the RGBA ubyte and then we continue as usual. + */ + srcAddr = tempImage; + srcFormat = GL_RGBA; + srcType = GL_UNSIGNED_BYTE; + } else if (srcPacking->SwapBytes) { + /* We have to handle byte-swapping scenarios before calling + * _mesa_format_convert + */ + GLint swapSize = _mesa_sizeof_packed_type(srcType); + if (swapSize == 2 || swapSize == 4) { + int bytesPerPixel = _mesa_bytes_per_pixel(srcFormat, srcType); + int swapsPerPixel = bytesPerPixel / swapSize; + int elementCount = srcWidth * srcHeight * srcDepth; + assert(bytesPerPixel % swapSize == 0); + tempImage = malloc(elementCount * bytesPerPixel); + if (!tempImage) + return GL_FALSE; + if (swapSize == 2) + _mesa_swap2_copy(tempImage, (GLushort *) srcAddr, + elementCount * swapsPerPixel); + else + _mesa_swap4_copy(tempImage, (GLuint *) srcAddr, + elementCount * swapsPerPixel); + srcAddr = tempImage; } - srcImage += srcImageStride; } - return GL_TRUE; -} - - -/** Stores a texture by converting float and then to the texture format - * - * This function performs a texstore operation by converting to float, - * applying pixel transfer ops, and then converting to the texture's - * internal format using pixel store functions. This function will work - * for any rgb or srgb textore format. - */ -static GLboolean -texstore_via_float(TEXSTORE_PARAMS) -{ - GLuint i, img, row; - const GLint src_stride = + srcRowStride = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType); - float *tmp_row; - bool need_convert; - uint8_t *src_row, *dst_row, map[4], rgba2base[6], base2rgba[6]; - - tmp_row = malloc(srcWidth * 4 * sizeof(*tmp_row)); - if (!tmp_row) - return GL_FALSE; - /* The GL spec (4.0, compatibility profile) only specifies srgb - * conversion as something that is done in the sampler during the - * filtering process before the colors are handed to the shader. - * Furthermore, the flowchart (Figure 3.7 in the 4.0 compatibility spec) - * does not list RGB <-> sRGB conversions anywhere. Therefore, we just - * treat sRGB formats the same as RGB formats for the purposes of - * texture upload and transfer ops. - */ + srcMesaFormat = _mesa_format_from_format_and_type(srcFormat, srcType); dstFormat = _mesa_get_srgb_format_linear(dstFormat); - need_convert = false; - if (baseInternalFormat != _mesa_get_format_base_format(dstFormat)) { - compute_component_mapping(GL_RGBA, baseInternalFormat, base2rgba); - compute_component_mapping(baseInternalFormat, GL_RGBA, rgba2base); - for (i = 0; i < 4; ++i) { - map[i] = base2rgba[rgba2base[i]]; - if (map[i] != i) - need_convert = true; + /* If we have transferOps then we need to convert to RGBA float first, + then apply transferOps, then do the conversion to dst + */ + if (!transferOpsDone && + _mesa_texstore_needs_transfer_ops(ctx, baseInternalFormat, dstFormat)) { + /* Allocate RGBA float image */ + int elementCount = srcWidth * srcHeight * srcDepth; + tempRGBA = malloc(4 * elementCount * sizeof(float)); + if (!tempRGBA) { + free(tempImage); + free(tempRGBA); + return GL_FALSE; } - } - for (img = 0; img < srcDepth; img++) { - dst_row = dstSlices[img]; - src_row = _mesa_image_address(dims, srcPacking, srcAddr, - srcWidth, srcHeight, - srcFormat, srcType, - img, 0, 0); - for (row = 0; row < srcHeight; row++) { - _mesa_unpack_color_span_float(ctx, srcWidth, GL_RGBA, tmp_row, - srcFormat, srcType, src_row, - srcPacking, ctx->_ImageTransferState); - if (need_convert) - _mesa_swizzle_and_convert(tmp_row, GL_FLOAT, 4, - tmp_row, GL_FLOAT, 4, - map, false, srcWidth); - _mesa_pack_float_rgba_row(dstFormat, srcWidth, - (const GLfloat (*)[4])tmp_row, - dst_row); - dst_row += dstRowStride; - src_row += src_stride; + /* Convert from src to RGBA float */ + src = (GLubyte *) srcAddr; + dst = (GLubyte *) tempRGBA; + for (img = 0; img < srcDepth; img++) { + _mesa_format_convert(dst, RGBA32_FLOAT, 4 * srcWidth * sizeof(float), + src, srcMesaFormat, srcRowStride, + srcWidth, srcHeight, NULL); + src += srcHeight * srcRowStride; + dst += srcHeight * 4 * srcWidth * sizeof(float); } - } - free(tmp_row); - - return GL_TRUE; -} + /* Apply transferOps */ + _mesa_apply_rgba_transfer_ops(ctx, ctx->_ImageTransferState, elementCount, + (float(*)[4]) tempRGBA); -/** Stores an integer rgba texture - * - * This function performs an integer texture storage operation by unpacking - * the texture to 32-bit integers, and repacking it into the internal - * format of the texture. This will work for any integer rgb texture - * storage operation. - */ -static GLboolean -texstore_rgba_integer(TEXSTORE_PARAMS) -{ - GLuint i, img, row, *tmp_row; - GLenum dst_type, tmp_type; - const GLint src_stride = - _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType); - int num_dst_components; - bool is_array, normalized; - uint8_t *src_row, *dst_row; - uint8_t swizzle[4], rgba2base[6], base2rgba[6], rgba2dst[4], dst2rgba[4]; - - tmp_row = malloc(srcWidth * 4 * sizeof(*tmp_row)); - if (!tmp_row) - return GL_FALSE; - - is_array = _mesa_format_to_array(dstFormat, &dst_type, &num_dst_components, - rgba2dst, &normalized); - - assert(is_array && !normalized); - - if (!is_array) { - free(tmp_row); - return GL_FALSE; + /* Now we have to adjust our src info for a conversion from + * the RGBA float image and then we continue as usual. + */ + srcAddr = tempRGBA; + srcFormat = GL_RGBA; + srcType = GL_FLOAT; + srcRowStride = srcWidth * 4 * sizeof(float); + srcMesaFormat = RGBA32_FLOAT; } - invert_swizzle(dst2rgba, rgba2dst); - compute_component_mapping(GL_RGBA, baseInternalFormat, base2rgba); - compute_component_mapping(baseInternalFormat, GL_RGBA, rgba2base); - - for (i = 0; i < 4; ++i) { - if (dst2rgba[i] == MESA_FORMAT_SWIZZLE_NONE) - swizzle[i] = MESA_FORMAT_SWIZZLE_NONE; - else - swizzle[i] = base2rgba[rgba2base[dst2rgba[i]]]; - } + src = (GLubyte *) + _mesa_image_address(dims, srcPacking, srcAddr, srcWidth, srcHeight, + srcFormat, srcType, 0, 0, 0); - if (_mesa_is_type_unsigned(srcType)) { - tmp_type = GL_UNSIGNED_INT; + if (_mesa_get_format_base_format(dstFormat) != baseInternalFormat) { + needRebase = + _mesa_compute_rgba2base2rgba_component_mapping(baseInternalFormat, + rebaseSwizzle); } else { - tmp_type = GL_INT; + needRebase = false; } for (img = 0; img < srcDepth; img++) { - dst_row = dstSlices[img]; - src_row = _mesa_image_address(dims, srcPacking, srcAddr, - srcWidth, srcHeight, - srcFormat, srcType, - img, 0, 0); - for (row = 0; row < srcHeight; row++) { - _mesa_unpack_color_span_uint(ctx, srcWidth, GL_RGBA, tmp_row, - srcFormat, srcType, src_row, srcPacking); - _mesa_swizzle_and_convert(dst_row, dst_type, num_dst_components, - tmp_row, tmp_type, 4, - swizzle, false, srcWidth); - dst_row += dstRowStride; - src_row += src_stride; - } + _mesa_format_convert(dstSlices[img], dstFormat, dstRowStride, + src, srcMesaFormat, srcRowStride, + srcWidth, srcHeight, + needRebase ? rebaseSwizzle : NULL); + src += srcHeight * srcRowStride; } - free(tmp_row); + free(tempImage); + free(tempRGBA); return GL_TRUE; } -static GLboolean -texstore_rgba(TEXSTORE_PARAMS) -{ - static StoreTexImageFunc table[MESA_FORMAT_COUNT]; - static GLboolean initialized = GL_FALSE; - - if (!initialized) { - memset(table, 0, sizeof table); - - table[MESA_FORMAT_B5G6R5_UNORM] = _mesa_texstore_rgb565; - table[MESA_FORMAT_R5G6B5_UNORM] = _mesa_texstore_rgb565; - table[MESA_FORMAT_YCBCR] = _mesa_texstore_ycbcr; - table[MESA_FORMAT_YCBCR_REV] = _mesa_texstore_ycbcr; - - table[MESA_FORMAT_B10G10R10A2_UINT] = _mesa_texstore_argb2101010_uint; - table[MESA_FORMAT_R10G10B10A2_UINT] = _mesa_texstore_abgr2101010_uint; - - initialized = GL_TRUE; - } - - if (table[dstFormat] && table[dstFormat](ctx, dims, baseInternalFormat, - dstFormat, dstRowStride, dstSlices, - srcWidth, srcHeight, srcDepth, - srcFormat, srcType, srcAddr, - srcPacking)) { - return GL_TRUE; - } - - if (texstore_swizzle(ctx, dims, baseInternalFormat, - dstFormat, - dstRowStride, dstSlices, - srcWidth, srcHeight, srcDepth, - srcFormat, srcType, srcAddr, srcPacking)) { - return GL_TRUE; - } - - if (_mesa_is_format_integer(dstFormat)) { - return texstore_rgba_integer(ctx, dims, baseInternalFormat, - dstFormat, dstRowStride, dstSlices, - srcWidth, srcHeight, srcDepth, - srcFormat, srcType, srcAddr, - srcPacking); - } else if (_mesa_get_format_max_bits(dstFormat) <= 8 && - !_mesa_is_format_signed(dstFormat)) { - return store_ubyte_texture(ctx, dims, baseInternalFormat, - dstFormat, - dstRowStride, dstSlices, - srcWidth, srcHeight, srcDepth, - srcFormat, srcType, srcAddr, srcPacking); - } else { - return texstore_via_float(ctx, dims, baseInternalFormat, - dstFormat, dstRowStride, dstSlices, - srcWidth, srcHeight, srcDepth, - srcFormat, srcType, srcAddr, - srcPacking); - } -} - GLboolean _mesa_texstore_needs_transfer_ops(struct gl_context *ctx, GLenum baseInternalFormat, @@ -2231,7 +1278,7 @@ _mesa_compute_compressed_pixelstore(GLuint dims, mesa_format texFormat, if (packing->RowLength) { store->TotalBytesPerRow = packing->CompressedBlockSize * - (packing->RowLength + bw - 1) / bw; + ((packing->RowLength + bw - 1) / bw); } store->SkipBytes += packing->SkipPixels * packing->CompressedBlockSize / bw; diff --git a/mesalib/src/mesa/main/texstore.h b/mesalib/src/mesa/main/texstore.h index 4c41d1fcd..2c974f74a 100644 --- a/mesalib/src/mesa/main/texstore.h +++ b/mesalib/src/mesa/main/texstore.h @@ -81,25 +81,6 @@ _mesa_texstore_can_use_memcpy(struct gl_context *ctx, const struct gl_pixelstore_attrib *srcPacking); -extern GLubyte * -_mesa_make_temp_ubyte_image(struct gl_context *ctx, GLuint dims, - GLenum logicalBaseFormat, - GLenum textureBaseFormat, - GLint srcWidth, GLint srcHeight, GLint srcDepth, - GLenum srcFormat, GLenum srcType, - const GLvoid *srcAddr, - const struct gl_pixelstore_attrib *srcPacking); - -GLfloat * -_mesa_make_temp_float_image(struct gl_context *ctx, GLuint dims, - GLenum logicalBaseFormat, - GLenum textureBaseFormat, - GLint srcWidth, GLint srcHeight, GLint srcDepth, - GLenum srcFormat, GLenum srcType, - const GLvoid *srcAddr, - const struct gl_pixelstore_attrib *srcPacking, - GLbitfield transferOps); - extern void _mesa_store_teximage(struct gl_context *ctx, GLuint dims, diff --git a/mesalib/src/mesa/main/textureview.c b/mesalib/src/mesa/main/textureview.c index 6e86a9a44..cd87a27d2 100644 --- a/mesalib/src/mesa/main/textureview.c +++ b/mesalib/src/mesa/main/textureview.c @@ -355,7 +355,7 @@ _mesa_set_texture_view_state(struct gl_context *ctx, struct gl_texture_image *texImage; /* Get a reference to what will become this View's base level */ - texImage = _mesa_select_tex_image(ctx, texObj, target, 0); + texImage = _mesa_select_tex_image(texObj, target, 0); /* When an immutable texture is created via glTexStorage or glTexImageMultisample, * TEXTURE_IMMUTABLE_FORMAT becomes TRUE. @@ -527,8 +527,7 @@ _mesa_TextureView(GLuint texture, GLenum target, GLuint origtexture, faceTarget = GL_TEXTURE_CUBE_MAP_POSITIVE_X + minlayer; /* Get a reference to what will become this View's base level */ - origTexImage = _mesa_select_tex_image(ctx, origTexObj, - faceTarget, minlevel); + origTexImage = _mesa_select_tex_image(origTexObj, faceTarget, minlevel); width = origTexImage->Width; height = origTexImage->Height; depth = origTexImage->Depth; diff --git a/mesalib/src/mesa/main/uniform_query.cpp b/mesalib/src/mesa/main/uniform_query.cpp index 32870d0c4..40327fba4 100644 --- a/mesalib/src/mesa/main/uniform_query.cpp +++ b/mesalib/src/mesa/main/uniform_query.cpp @@ -45,9 +45,14 @@ _mesa_GetActiveUniform(GLuint program, GLuint index, GLenum *type, GLcharARB *nameOut) { GET_CURRENT_CONTEXT(ctx); - struct gl_shader_program *shProg = - _mesa_lookup_shader_program_err(ctx, program, "glGetActiveUniform"); + struct gl_shader_program *shProg; + + if (maxLength < 0) { + _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveUniform(maxLength < 0)"); + return; + } + shProg = _mesa_lookup_shader_program_err(ctx, program, "glGetActiveUniform"); if (!shProg) return; @@ -85,16 +90,16 @@ _mesa_GetActiveUniformsiv(GLuint program, struct gl_shader_program *shProg; GLsizei i; - shProg = _mesa_lookup_shader_program_err(ctx, program, "glGetActiveUniform"); - if (!shProg) - return; - if (uniformCount < 0) { _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveUniformsiv(uniformCount < 0)"); return; } + shProg = _mesa_lookup_shader_program_err(ctx, program, "glGetActiveUniform"); + if (!shProg) + return; + for (i = 0; i < uniformCount; i++) { GLuint index = uniformIndices[i]; @@ -464,6 +469,9 @@ log_uniform(const void *values, enum glsl_base_type basicType, case GLSL_TYPE_FLOAT: printf("%g ", v[i].f); break; + case GLSL_TYPE_DOUBLE: + printf("%g ", *(double* )&v[i * 2].f); + break; default: assert(!"Should not get here."); break; @@ -524,11 +532,12 @@ _mesa_propagate_uniforms_to_driver_storage(struct gl_uniform_storage *uni, */ const unsigned components = MAX2(1, uni->type->vector_elements); const unsigned vectors = MAX2(1, uni->type->matrix_columns); + const int dmul = uni->type->base_type == GLSL_TYPE_DOUBLE ? 2 : 1; /* Store the data in the driver's requested type in the driver's storage * areas. */ - unsigned src_vector_byte_stride = components * 4; + unsigned src_vector_byte_stride = components * 4 * dmul; for (i = 0; i < uni->num_driver_storage; i++) { struct gl_uniform_driver_storage *const store = &uni->driver_storage[i]; @@ -536,7 +545,7 @@ _mesa_propagate_uniforms_to_driver_storage(struct gl_uniform_storage *uni, const unsigned extra_stride = store->element_stride - (vectors * store->vector_stride); const uint8_t *src = - (uint8_t *) (&uni->storage[array_index * (components * vectors)].i); + (uint8_t *) (&uni->storage[array_index * (dmul * components * vectors)].i); #if 0 printf("%s: %p[%d] components=%u vectors=%u count=%u vector_stride=%u " @@ -603,6 +612,7 @@ _mesa_uniform(struct gl_context *ctx, struct gl_shader_program *shProg, unsigned src_components) { unsigned offset; + int size_mul = basicType == GLSL_TYPE_DOUBLE ? 2 : 1; struct gl_uniform_storage *const uni = validate_uniform_parameters(ctx, shProg, location, count, @@ -618,7 +628,7 @@ _mesa_uniform(struct gl_context *ctx, struct gl_shader_program *shProg, bool match; switch (uni->type->base_type) { case GLSL_TYPE_BOOL: - match = true; + match = (basicType != GLSL_TYPE_DOUBLE); break; case GLSL_TYPE_SAMPLER: case GLSL_TYPE_IMAGE: @@ -705,8 +715,8 @@ _mesa_uniform(struct gl_context *ctx, struct gl_shader_program *shProg, /* Store the data in the "actual type" backing storage for the uniform. */ if (!uni->type->is_boolean()) { - memcpy(&uni->storage[components * offset], values, - sizeof(uni->storage[0]) * components * count); + memcpy(&uni->storage[size_mul * components * offset], values, + sizeof(uni->storage[0]) * components * count * size_mul); } else { const union gl_constant_value *src = (const union gl_constant_value *) values; @@ -803,13 +813,14 @@ extern "C" void _mesa_uniform_matrix(struct gl_context *ctx, struct gl_shader_program *shProg, GLuint cols, GLuint rows, GLint location, GLsizei count, - GLboolean transpose, const GLfloat *values) + GLboolean transpose, + const GLvoid *values, GLenum type) { unsigned offset; unsigned vectors; unsigned components; unsigned elements; - + int size_mul; struct gl_uniform_storage *const uni = validate_uniform_parameters(ctx, shProg, location, count, &offset, "glUniformMatrix"); @@ -822,6 +833,9 @@ _mesa_uniform_matrix(struct gl_context *ctx, struct gl_shader_program *shProg, return; } + assert(type == GL_FLOAT || type == GL_DOUBLE); + size_mul = type == GL_DOUBLE ? 2 : 1; + assert(!uni->type->is_sampler()); vectors = uni->type->matrix_columns; components = uni->type->vector_elements; @@ -847,7 +861,7 @@ _mesa_uniform_matrix(struct gl_context *ctx, struct gl_shader_program *shProg, } if (unlikely(ctx->_Shader->Flags & GLSL_UNIFORMS)) { - log_uniform(values, GLSL_TYPE_FLOAT, components, vectors, count, + log_uniform(values, uni->type->base_type, components, vectors, count, bool(transpose), shProg, location, uni); } @@ -874,13 +888,28 @@ _mesa_uniform_matrix(struct gl_context *ctx, struct gl_shader_program *shProg, if (!transpose) { memcpy(&uni->storage[elements * offset], values, - sizeof(uni->storage[0]) * elements * count); - } else { + sizeof(uni->storage[0]) * elements * count * size_mul); + } else if (type == GL_FLOAT) { /* Copy and transpose the matrix. */ - const float *src = values; + const float *src = (const float *)values; float *dst = &uni->storage[elements * offset].f; + for (int i = 0; i < count; i++) { + for (unsigned r = 0; r < rows; r++) { + for (unsigned c = 0; c < cols; c++) { + dst[(c * components) + r] = src[c + (r * vectors)]; + } + } + + dst += elements; + src += elements; + } + } else { + assert(type == GL_DOUBLE); + const double *src = (const double *)values; + double *dst = (double *)&uni->storage[elements * offset].f; + for (int i = 0; i < count; i++) { for (unsigned r = 0; r < rows; r++) { for (unsigned c = 0; c < cols; c++) { diff --git a/mesalib/src/mesa/main/uniforms.c b/mesalib/src/mesa/main/uniforms.c index d2d70e7f7..e471b878c 100644 --- a/mesalib/src/mesa/main/uniforms.c +++ b/mesalib/src/mesa/main/uniforms.c @@ -553,7 +553,7 @@ _mesa_UniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, { GET_CURRENT_CONTEXT(ctx); _mesa_uniform_matrix(ctx, ctx->_Shader->ActiveProgram, - 2, 2, location, count, transpose, value); + 2, 2, location, count, transpose, value, GL_FLOAT); } void GLAPIENTRY @@ -562,7 +562,7 @@ _mesa_UniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, { GET_CURRENT_CONTEXT(ctx); _mesa_uniform_matrix(ctx, ctx->_Shader->ActiveProgram, - 3, 3, location, count, transpose, value); + 3, 3, location, count, transpose, value, GL_FLOAT); } void GLAPIENTRY @@ -571,7 +571,7 @@ _mesa_UniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, { GET_CURRENT_CONTEXT(ctx); _mesa_uniform_matrix(ctx, ctx->_Shader->ActiveProgram, - 4, 4, location, count, transpose, value); + 4, 4, location, count, transpose, value, GL_FLOAT); } /** Same as above with direct state access **/ @@ -683,7 +683,7 @@ _mesa_ProgramUniformMatrix2fv(GLuint program, GLint location, GLsizei count, struct gl_shader_program *shProg = _mesa_lookup_shader_program_err(ctx, program, "glProgramUniformMatrix2fv"); - _mesa_uniform_matrix(ctx, shProg, 2, 2, location, count, transpose, value); + _mesa_uniform_matrix(ctx, shProg, 2, 2, location, count, transpose, value, GL_FLOAT); } void GLAPIENTRY @@ -694,7 +694,7 @@ _mesa_ProgramUniformMatrix3fv(GLuint program, GLint location, GLsizei count, struct gl_shader_program *shProg = _mesa_lookup_shader_program_err(ctx, program, "glProgramUniformMatrix3fv"); - _mesa_uniform_matrix(ctx, shProg, 3, 3, location, count, transpose, value); + _mesa_uniform_matrix(ctx, shProg, 3, 3, location, count, transpose, value, GL_FLOAT); } void GLAPIENTRY @@ -705,7 +705,7 @@ _mesa_ProgramUniformMatrix4fv(GLuint program, GLint location, GLsizei count, struct gl_shader_program *shProg = _mesa_lookup_shader_program_err(ctx, program, "glProgramUniformMatrix4fv"); - _mesa_uniform_matrix(ctx, shProg, 4, 4, location, count, transpose, value); + _mesa_uniform_matrix(ctx, shProg, 4, 4, location, count, transpose, value, GL_FLOAT); } @@ -718,7 +718,7 @@ _mesa_UniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose, { GET_CURRENT_CONTEXT(ctx); _mesa_uniform_matrix(ctx, ctx->_Shader->ActiveProgram, - 2, 3, location, count, transpose, value); + 2, 3, location, count, transpose, value, GL_FLOAT); } void GLAPIENTRY @@ -727,7 +727,7 @@ _mesa_UniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose, { GET_CURRENT_CONTEXT(ctx); _mesa_uniform_matrix(ctx, ctx->_Shader->ActiveProgram, - 3, 2, location, count, transpose, value); + 3, 2, location, count, transpose, value, GL_FLOAT); } void GLAPIENTRY @@ -736,7 +736,7 @@ _mesa_UniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose, { GET_CURRENT_CONTEXT(ctx); _mesa_uniform_matrix(ctx, ctx->_Shader->ActiveProgram, - 2, 4, location, count, transpose, value); + 2, 4, location, count, transpose, value, GL_FLOAT); } void GLAPIENTRY @@ -745,7 +745,7 @@ _mesa_UniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose, { GET_CURRENT_CONTEXT(ctx); _mesa_uniform_matrix(ctx, ctx->_Shader->ActiveProgram, - 4, 2, location, count, transpose, value); + 4, 2, location, count, transpose, value, GL_FLOAT); } void GLAPIENTRY @@ -754,7 +754,7 @@ _mesa_UniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, { GET_CURRENT_CONTEXT(ctx); _mesa_uniform_matrix(ctx, ctx->_Shader->ActiveProgram, - 3, 4, location, count, transpose, value); + 3, 4, location, count, transpose, value, GL_FLOAT); } void GLAPIENTRY @@ -763,7 +763,7 @@ _mesa_UniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, { GET_CURRENT_CONTEXT(ctx); _mesa_uniform_matrix(ctx, ctx->_Shader->ActiveProgram, - 4, 3, location, count, transpose, value); + 4, 3, location, count, transpose, value, GL_FLOAT); } /** Same as above with direct state access **/ @@ -776,7 +776,7 @@ _mesa_ProgramUniformMatrix2x3fv(GLuint program, GLint location, GLsizei count, struct gl_shader_program *shProg = _mesa_lookup_shader_program_err(ctx, program, "glProgramUniformMatrix2x3fv"); - _mesa_uniform_matrix(ctx, shProg, 2, 3, location, count, transpose, value); + _mesa_uniform_matrix(ctx, shProg, 2, 3, location, count, transpose, value, GL_FLOAT); } void GLAPIENTRY @@ -787,7 +787,7 @@ _mesa_ProgramUniformMatrix3x2fv(GLuint program, GLint location, GLsizei count, struct gl_shader_program *shProg = _mesa_lookup_shader_program_err(ctx, program, "glProgramUniformMatrix3x2fv"); - _mesa_uniform_matrix(ctx, shProg, 3, 2, location, count, transpose, value); + _mesa_uniform_matrix(ctx, shProg, 3, 2, location, count, transpose, value, GL_FLOAT); } void GLAPIENTRY @@ -798,7 +798,7 @@ _mesa_ProgramUniformMatrix2x4fv(GLuint program, GLint location, GLsizei count, struct gl_shader_program *shProg = _mesa_lookup_shader_program_err(ctx, program, "glProgramUniformMatrix2x4fv"); - _mesa_uniform_matrix(ctx, shProg, 2, 4, location, count, transpose, value); + _mesa_uniform_matrix(ctx, shProg, 2, 4, location, count, transpose, value, GL_FLOAT); } void GLAPIENTRY @@ -809,7 +809,7 @@ _mesa_ProgramUniformMatrix4x2fv(GLuint program, GLint location, GLsizei count, struct gl_shader_program *shProg = _mesa_lookup_shader_program_err(ctx, program, "glProgramUniformMatrix4x2fv"); - _mesa_uniform_matrix(ctx, shProg, 4, 2, location, count, transpose, value); + _mesa_uniform_matrix(ctx, shProg, 4, 2, location, count, transpose, value, GL_FLOAT); } void GLAPIENTRY @@ -820,7 +820,7 @@ _mesa_ProgramUniformMatrix3x4fv(GLuint program, GLint location, GLsizei count, struct gl_shader_program *shProg = _mesa_lookup_shader_program_err(ctx, program, "glProgramUniformMatrix3x4fv"); - _mesa_uniform_matrix(ctx, shProg, 3, 4, location, count, transpose, value); + _mesa_uniform_matrix(ctx, shProg, 3, 4, location, count, transpose, value, GL_FLOAT); } void GLAPIENTRY @@ -831,7 +831,7 @@ _mesa_ProgramUniformMatrix4x3fv(GLuint program, GLint location, GLsizei count, struct gl_shader_program *shProg = _mesa_lookup_shader_program_err(ctx, program, "glProgramUniformMatrix4x3fv"); - _mesa_uniform_matrix(ctx, shProg, 4, 3, location, count, transpose, value); + _mesa_uniform_matrix(ctx, shProg, 4, 3, location, count, transpose, value, GL_FLOAT); } @@ -1338,3 +1338,347 @@ _mesa_GetActiveAtomicCounterBufferiv(GLuint program, GLuint bufferIndex, return; } } + +void GLAPIENTRY +_mesa_Uniform1d(GLint location, GLdouble v0) +{ + GET_CURRENT_CONTEXT(ctx); + _mesa_uniform(ctx, ctx->_Shader->ActiveProgram, location, 1, &v0, GLSL_TYPE_DOUBLE, 1); +} + +void GLAPIENTRY +_mesa_Uniform2d(GLint location, GLdouble v0, GLdouble v1) +{ + GET_CURRENT_CONTEXT(ctx); + GLdouble v[2]; + v[0] = v0; + v[1] = v1; + _mesa_uniform(ctx, ctx->_Shader->ActiveProgram, location, 1, v, GLSL_TYPE_DOUBLE, 2); +} + +void GLAPIENTRY +_mesa_Uniform3d(GLint location, GLdouble v0, GLdouble v1, GLdouble v2) +{ + GET_CURRENT_CONTEXT(ctx); + GLdouble v[3]; + v[0] = v0; + v[1] = v1; + v[2] = v2; + _mesa_uniform(ctx, ctx->_Shader->ActiveProgram, location, 1, v, GLSL_TYPE_DOUBLE, 3); +} + +void GLAPIENTRY +_mesa_Uniform4d(GLint location, GLdouble v0, GLdouble v1, GLdouble v2, + GLdouble v3) +{ + GET_CURRENT_CONTEXT(ctx); + GLdouble v[4]; + v[0] = v0; + v[1] = v1; + v[2] = v2; + v[3] = v3; + _mesa_uniform(ctx, ctx->_Shader->ActiveProgram, location, 1, v, GLSL_TYPE_DOUBLE, 4); +} + +void GLAPIENTRY +_mesa_Uniform1dv(GLint location, GLsizei count, const GLdouble * value) +{ + GET_CURRENT_CONTEXT(ctx); + _mesa_uniform(ctx, ctx->_Shader->ActiveProgram, location, count, value, GLSL_TYPE_DOUBLE, 1); +} + +void GLAPIENTRY +_mesa_Uniform2dv(GLint location, GLsizei count, const GLdouble * value) +{ + GET_CURRENT_CONTEXT(ctx); + _mesa_uniform(ctx, ctx->_Shader->ActiveProgram, location, count, value, GLSL_TYPE_DOUBLE, 2); +} + +void GLAPIENTRY +_mesa_Uniform3dv(GLint location, GLsizei count, const GLdouble * value) +{ + GET_CURRENT_CONTEXT(ctx); + _mesa_uniform(ctx, ctx->_Shader->ActiveProgram, location, count, value, GLSL_TYPE_DOUBLE, 3); +} + +void GLAPIENTRY +_mesa_Uniform4dv(GLint location, GLsizei count, const GLdouble * value) +{ + GET_CURRENT_CONTEXT(ctx); + _mesa_uniform(ctx, ctx->_Shader->ActiveProgram, location, count, value, GLSL_TYPE_DOUBLE, 4); +} + +void GLAPIENTRY +_mesa_UniformMatrix2dv(GLint location, GLsizei count, GLboolean transpose, + const GLdouble * value) +{ + GET_CURRENT_CONTEXT(ctx); + _mesa_uniform_matrix(ctx, ctx->_Shader->ActiveProgram, + 2, 2, location, count, transpose, value, GL_DOUBLE); +} + +void GLAPIENTRY +_mesa_UniformMatrix3dv(GLint location, GLsizei count, GLboolean transpose, + const GLdouble * value) +{ + GET_CURRENT_CONTEXT(ctx); + _mesa_uniform_matrix(ctx, ctx->_Shader->ActiveProgram, + 3, 3, location, count, transpose, value, GL_DOUBLE); +} + +void GLAPIENTRY +_mesa_UniformMatrix4dv(GLint location, GLsizei count, GLboolean transpose, + const GLdouble * value) +{ + GET_CURRENT_CONTEXT(ctx); + _mesa_uniform_matrix(ctx, ctx->_Shader->ActiveProgram, + 4, 4, location, count, transpose, value, GL_DOUBLE); +} + +void GLAPIENTRY +_mesa_UniformMatrix2x3dv(GLint location, GLsizei count, GLboolean transpose, + const GLdouble *value) +{ + GET_CURRENT_CONTEXT(ctx); + _mesa_uniform_matrix(ctx, ctx->_Shader->ActiveProgram, + 2, 3, location, count, transpose, value, GL_DOUBLE); +} + +void GLAPIENTRY +_mesa_UniformMatrix3x2dv(GLint location, GLsizei count, GLboolean transpose, + const GLdouble *value) +{ + GET_CURRENT_CONTEXT(ctx); + _mesa_uniform_matrix(ctx, ctx->_Shader->ActiveProgram, + 3, 2, location, count, transpose, value, GL_DOUBLE); +} + +void GLAPIENTRY +_mesa_UniformMatrix2x4dv(GLint location, GLsizei count, GLboolean transpose, + const GLdouble *value) +{ + GET_CURRENT_CONTEXT(ctx); + _mesa_uniform_matrix(ctx, ctx->_Shader->ActiveProgram, + 2, 4, location, count, transpose, value, GL_DOUBLE); +} + +void GLAPIENTRY +_mesa_UniformMatrix4x2dv(GLint location, GLsizei count, GLboolean transpose, + const GLdouble *value) +{ + GET_CURRENT_CONTEXT(ctx); + _mesa_uniform_matrix(ctx, ctx->_Shader->ActiveProgram, + 4, 2, location, count, transpose, value, GL_DOUBLE); +} + +void GLAPIENTRY +_mesa_UniformMatrix3x4dv(GLint location, GLsizei count, GLboolean transpose, + const GLdouble *value) +{ + GET_CURRENT_CONTEXT(ctx); + _mesa_uniform_matrix(ctx, ctx->_Shader->ActiveProgram, + 3, 4, location, count, transpose, value, GL_DOUBLE); +} + +void GLAPIENTRY +_mesa_UniformMatrix4x3dv(GLint location, GLsizei count, GLboolean transpose, + const GLdouble *value) +{ + GET_CURRENT_CONTEXT(ctx); + _mesa_uniform_matrix(ctx, ctx->_Shader->ActiveProgram, + 4, 3, location, count, transpose, value, GL_DOUBLE); +} + +void GLAPIENTRY +_mesa_ProgramUniform1d(GLuint program, GLint location, GLdouble v0) +{ + GET_CURRENT_CONTEXT(ctx); + struct gl_shader_program *shProg = + _mesa_lookup_shader_program_err(ctx, program, + "glProgramUniform1d"); + _mesa_uniform(ctx, shProg, location, 1, &v0, GLSL_TYPE_DOUBLE, 1); +} + +void GLAPIENTRY +_mesa_ProgramUniform2d(GLuint program, GLint location, GLdouble v0, GLdouble v1) +{ + GET_CURRENT_CONTEXT(ctx); + GLdouble v[2]; + struct gl_shader_program *shProg; + v[0] = v0; + v[1] = v1; + shProg = _mesa_lookup_shader_program_err(ctx, program, "glProgramUniform2d"); + _mesa_uniform(ctx, shProg, location, 1, v, GLSL_TYPE_DOUBLE, 2); +} + +void GLAPIENTRY +_mesa_ProgramUniform3d(GLuint program, GLint location, GLdouble v0, GLdouble v1, + GLdouble v2) +{ + GET_CURRENT_CONTEXT(ctx); + GLdouble v[3]; + struct gl_shader_program *shProg; + v[0] = v0; + v[1] = v1; + v[2] = v2; + shProg = _mesa_lookup_shader_program_err(ctx, program, "glProgramUniform3d"); + _mesa_uniform(ctx, shProg, location, 1, v, GLSL_TYPE_DOUBLE, 3); +} + +void GLAPIENTRY +_mesa_ProgramUniform4d(GLuint program, GLint location, GLdouble v0, GLdouble v1, + GLdouble v2, GLdouble v3) +{ + GET_CURRENT_CONTEXT(ctx); + GLdouble v[4]; + struct gl_shader_program *shProg; + v[0] = v0; + v[1] = v1; + v[2] = v2; + v[3] = v3; + shProg = _mesa_lookup_shader_program_err(ctx, program, "glProgramUniform4d"); + _mesa_uniform(ctx, shProg, location, 1, v, GLSL_TYPE_DOUBLE, 4); +} + +void GLAPIENTRY +_mesa_ProgramUniform1dv(GLuint program, GLint location, GLsizei count, + const GLdouble * value) +{ + GET_CURRENT_CONTEXT(ctx); + struct gl_shader_program *shProg = + _mesa_lookup_shader_program_err(ctx, program, + "glProgramUniform1dv"); + _mesa_uniform(ctx, shProg, location, count, value, GLSL_TYPE_DOUBLE, 1); +} + +void GLAPIENTRY +_mesa_ProgramUniform2dv(GLuint program, GLint location, GLsizei count, + const GLdouble * value) +{ + GET_CURRENT_CONTEXT(ctx); + struct gl_shader_program *shProg = + _mesa_lookup_shader_program_err(ctx, program, + "glProgramUniform2dv"); + _mesa_uniform(ctx, shProg, location, count, value, GLSL_TYPE_DOUBLE, 2); +} + +void GLAPIENTRY +_mesa_ProgramUniform3dv(GLuint program, GLint location, GLsizei count, + const GLdouble * value) +{ + GET_CURRENT_CONTEXT(ctx); + struct gl_shader_program *shProg = + _mesa_lookup_shader_program_err(ctx, program, + "glProgramUniform3dv"); + _mesa_uniform(ctx, shProg, location, count, value, GLSL_TYPE_DOUBLE, 3); +} + +void GLAPIENTRY +_mesa_ProgramUniform4dv(GLuint program, GLint location, GLsizei count, + const GLdouble * value) +{ + GET_CURRENT_CONTEXT(ctx); + struct gl_shader_program *shProg = + _mesa_lookup_shader_program_err(ctx, program, + "glProgramUniform4dv"); + _mesa_uniform(ctx, shProg, location, count, value, GLSL_TYPE_DOUBLE, 4); +} + +void GLAPIENTRY +_mesa_ProgramUniformMatrix2dv(GLuint program, GLint location, GLsizei count, + GLboolean transpose, const GLdouble * value) +{ + GET_CURRENT_CONTEXT(ctx); + struct gl_shader_program *shProg = + _mesa_lookup_shader_program_err(ctx, program, + "glProgramUniformMatrix2dv"); + _mesa_uniform_matrix(ctx, shProg, 2, 2, location, count, transpose, value, GL_DOUBLE); +} + +void GLAPIENTRY +_mesa_ProgramUniformMatrix3dv(GLuint program, GLint location, GLsizei count, + GLboolean transpose, const GLdouble * value) +{ + GET_CURRENT_CONTEXT(ctx); + struct gl_shader_program *shProg = + _mesa_lookup_shader_program_err(ctx, program, + "glProgramUniformMatrix3dv"); + _mesa_uniform_matrix(ctx, shProg, 3, 3, location, count, transpose, value, GL_DOUBLE); +} + +void GLAPIENTRY +_mesa_ProgramUniformMatrix4dv(GLuint program, GLint location, GLsizei count, + GLboolean transpose, const GLdouble * value) +{ + GET_CURRENT_CONTEXT(ctx); + struct gl_shader_program *shProg = + _mesa_lookup_shader_program_err(ctx, program, + "glProgramUniformMatrix4dv"); + _mesa_uniform_matrix(ctx, shProg, 4, 4, location, count, transpose, value, GL_DOUBLE); +} + +void GLAPIENTRY +_mesa_ProgramUniformMatrix2x3dv(GLuint program, GLint location, GLsizei count, + GLboolean transpose, const GLdouble * value) +{ + GET_CURRENT_CONTEXT(ctx); + struct gl_shader_program *shProg = + _mesa_lookup_shader_program_err(ctx, program, + "glProgramUniformMatrix2x3dv"); + _mesa_uniform_matrix(ctx, shProg, 2, 3, location, count, transpose, value, GL_DOUBLE); +} + +void GLAPIENTRY +_mesa_ProgramUniformMatrix3x2dv(GLuint program, GLint location, GLsizei count, + GLboolean transpose, const GLdouble * value) +{ + GET_CURRENT_CONTEXT(ctx); + struct gl_shader_program *shProg = + _mesa_lookup_shader_program_err(ctx, program, + "glProgramUniformMatrix3x2dv"); + _mesa_uniform_matrix(ctx, shProg, 3, 2, location, count, transpose, value, GL_DOUBLE); +} + +void GLAPIENTRY +_mesa_ProgramUniformMatrix2x4dv(GLuint program, GLint location, GLsizei count, + GLboolean transpose, const GLdouble * value) +{ + GET_CURRENT_CONTEXT(ctx); + struct gl_shader_program *shProg = + _mesa_lookup_shader_program_err(ctx, program, + "glProgramUniformMatrix2x4dv"); + _mesa_uniform_matrix(ctx, shProg, 2, 4, location, count, transpose, value, GL_DOUBLE); +} + +void GLAPIENTRY +_mesa_ProgramUniformMatrix4x2dv(GLuint program, GLint location, GLsizei count, + GLboolean transpose, const GLdouble * value) +{ + GET_CURRENT_CONTEXT(ctx); + struct gl_shader_program *shProg = + _mesa_lookup_shader_program_err(ctx, program, + "glProgramUniformMatrix4x2dv"); + _mesa_uniform_matrix(ctx, shProg, 4, 2, location, count, transpose, value, GL_DOUBLE); +} + +void GLAPIENTRY +_mesa_ProgramUniformMatrix3x4dv(GLuint program, GLint location, GLsizei count, + GLboolean transpose, const GLdouble * value) +{ + GET_CURRENT_CONTEXT(ctx); + struct gl_shader_program *shProg = + _mesa_lookup_shader_program_err(ctx, program, + "glProgramUniformMatrix3x4dv"); + _mesa_uniform_matrix(ctx, shProg, 3, 4, location, count, transpose, value, GL_DOUBLE); +} + +void GLAPIENTRY +_mesa_ProgramUniformMatrix4x3dv(GLuint program, GLint location, GLsizei count, + GLboolean transpose, const GLdouble * value) +{ + GET_CURRENT_CONTEXT(ctx); + struct gl_shader_program *shProg = + _mesa_lookup_shader_program_err(ctx, program, + "glProgramUniformMatrix4x3dv"); + _mesa_uniform_matrix(ctx, shProg, 4, 3, location, count, transpose, value, GL_DOUBLE); +} diff --git a/mesalib/src/mesa/main/uniforms.h b/mesalib/src/mesa/main/uniforms.h index 0a9ee7de9..0e6113fe9 100644 --- a/mesalib/src/mesa/main/uniforms.h +++ b/mesalib/src/mesa/main/uniforms.h @@ -254,6 +254,95 @@ _mesa_GetActiveUniformsiv(GLuint program, void GLAPIENTRY _mesa_GetUniformiv(GLuint, GLint, GLint *); +void GLAPIENTRY +_mesa_Uniform1d(GLint, GLdouble); +void GLAPIENTRY +_mesa_Uniform2d(GLint, GLdouble, GLdouble); +void GLAPIENTRY +_mesa_Uniform3d(GLint, GLdouble, GLdouble, GLdouble); +void GLAPIENTRY +_mesa_Uniform4d(GLint, GLdouble, GLdouble, GLdouble, GLdouble); + +void GLAPIENTRY +_mesa_Uniform1dv(GLint, GLsizei, const GLdouble *); +void GLAPIENTRY +_mesa_Uniform2dv(GLint, GLsizei, const GLdouble *); +void GLAPIENTRY +_mesa_Uniform3dv(GLint, GLsizei, const GLdouble *); +void GLAPIENTRY +_mesa_Uniform4dv(GLint, GLsizei, const GLdouble *); + +void GLAPIENTRY +_mesa_UniformMatrix2dv(GLint, GLsizei, GLboolean, const GLdouble *); +void GLAPIENTRY +_mesa_UniformMatrix3dv(GLint, GLsizei, GLboolean, const GLdouble *); +void GLAPIENTRY +_mesa_UniformMatrix4dv(GLint, GLsizei, GLboolean, const GLdouble *); +void GLAPIENTRY +_mesa_UniformMatrix2x3dv(GLint location, GLsizei count, GLboolean transpose, + const GLdouble *value); +void GLAPIENTRY +_mesa_UniformMatrix3x2dv(GLint location, GLsizei count, GLboolean transpose, + const GLdouble *value); +void GLAPIENTRY +_mesa_UniformMatrix2x4dv(GLint location, GLsizei count, GLboolean transpose, + const GLdouble *value); +void GLAPIENTRY +_mesa_UniformMatrix4x2dv(GLint location, GLsizei count, GLboolean transpose, + const GLdouble *value); +void GLAPIENTRY +_mesa_UniformMatrix3x4dv(GLint location, GLsizei count, GLboolean transpose, + const GLdouble *value); +void GLAPIENTRY +_mesa_UniformMatrix4x3dv(GLint location, GLsizei count, GLboolean transpose, + const GLdouble *value); + +void GLAPIENTRY +_mesa_ProgramUniform1d(GLuint program, GLint, GLdouble); +void GLAPIENTRY +_mesa_ProgramUniform2d(GLuint program, GLint, GLdouble, GLdouble); +void GLAPIENTRY +_mesa_ProgramUniform3d(GLuint program, GLint, GLdouble, GLdouble, GLdouble); +void GLAPIENTRY +_mesa_ProgramUniform4d(GLuint program, GLint, GLdouble, GLdouble, GLdouble, GLdouble); + +void GLAPIENTRY +_mesa_ProgramUniform1dv(GLuint program, GLint, GLsizei, const GLdouble *); +void GLAPIENTRY +_mesa_ProgramUniform2dv(GLuint program, GLint, GLsizei, const GLdouble *); +void GLAPIENTRY +_mesa_ProgramUniform3dv(GLuint program, GLint, GLsizei, const GLdouble *); +void GLAPIENTRY +_mesa_ProgramUniform4dv(GLuint program, GLint, GLsizei, const GLdouble *); + +void GLAPIENTRY +_mesa_ProgramUniformMatrix2dv(GLuint program, GLint, GLsizei, GLboolean, + const GLdouble *); +void GLAPIENTRY +_mesa_ProgramUniformMatrix3dv(GLuint program, GLint, GLsizei, GLboolean, + const GLdouble *); +void GLAPIENTRY +_mesa_ProgramUniformMatrix4dv(GLuint program, GLint, GLsizei, GLboolean, + const GLdouble *); +void GLAPIENTRY +_mesa_ProgramUniformMatrix2x3dv(GLuint program, GLint location, GLsizei count, + GLboolean transpose, const GLdouble *value); +void GLAPIENTRY +_mesa_ProgramUniformMatrix3x2dv(GLuint program, GLint location, GLsizei count, + GLboolean transpose, const GLdouble *value); +void GLAPIENTRY +_mesa_ProgramUniformMatrix2x4dv(GLuint program, GLint location, GLsizei count, + GLboolean transpose, const GLdouble *value); +void GLAPIENTRY +_mesa_ProgramUniformMatrix4x2dv(GLuint program, GLint location, GLsizei count, + GLboolean transpose, const GLdouble *value); +void GLAPIENTRY +_mesa_ProgramUniformMatrix3x4dv(GLuint program, GLint location, GLsizei count, + GLboolean transpose, const GLdouble *value); +void GLAPIENTRY +_mesa_ProgramUniformMatrix4x3dv(GLuint program, GLint location, GLsizei count, + GLboolean transpose, const GLdouble *value); + long _mesa_parse_program_resource_name(const GLchar *name, const GLchar **out_base_name_end); @@ -273,7 +362,8 @@ void _mesa_uniform_matrix(struct gl_context *ctx, struct gl_shader_program *shProg, GLuint cols, GLuint rows, GLint location, GLsizei count, - GLboolean transpose, const GLfloat *values); + GLboolean transpose, + const GLvoid *values, GLenum type); void _mesa_get_uniform(struct gl_context *ctx, GLuint program, GLint location, diff --git a/mesalib/src/mesa/main/varray.c b/mesalib/src/mesa/main/varray.c index 96c2b26f7..978ec7b53 100644 --- a/mesalib/src/mesa/main/varray.c +++ b/mesalib/src/mesa/main/varray.c @@ -255,14 +255,17 @@ update_array_format(struct gl_context *ctx, { struct gl_vertex_attrib_array *array; GLbitfield typeBit; - GLuint elementSize; + GLint elementSize; GLenum format = GL_RGBA; - if (ctx->Array.LegalTypesMask == 0) { - /* One-time initialization. We can't do this in _mesa_init_varrays() - * below because extensions are not yet enabled at that point. + if (ctx->Array.LegalTypesMask == 0 || ctx->Array.LegalTypesMaskAPI != ctx->API) { + /* Compute the LegalTypesMask only once, unless the context API has + * changed, in which case we want to compute it again. We can't do this + * in _mesa_init_varrays() below because extensions are not yet enabled + * at that point. */ ctx->Array.LegalTypesMask = get_legal_types_mask(ctx); + ctx->Array.LegalTypesMaskAPI = ctx->API; } legalTypesMask &= ctx->Array.LegalTypesMask; diff --git a/mesalib/src/mesa/main/vdpau.c b/mesalib/src/mesa/main/vdpau.c index e1c3e00ba..0efa56e4f 100644 --- a/mesalib/src/mesa/main/vdpau.c +++ b/mesalib/src/mesa/main/vdpau.c @@ -33,9 +33,9 @@ #include #include "util/hash_table.h" +#include "util/set.h" #include "context.h" #include "glformats.h" -#include "set.h" #include "texobj.h" #include "teximage.h" #include "vdpau.h" @@ -73,7 +73,8 @@ _mesa_VDPAUInitNV(const GLvoid *vdpDevice, const GLvoid *getProcAddress) ctx->vdpDevice = vdpDevice; ctx->vdpGetProcAddress = getProcAddress; - ctx->vdpSurfaces = _mesa_set_create(NULL, _mesa_key_pointer_equal); + ctx->vdpSurfaces = _mesa_set_create(NULL, _mesa_hash_pointer, + _mesa_key_pointer_equal); } static void @@ -179,7 +180,7 @@ register_surface(struct gl_context *ctx, GLboolean isOutput, _mesa_reference_texobj(&surf->textures[i], tex); } - _mesa_set_add(ctx->vdpSurfaces, _mesa_hash_pointer(surf), surf); + _mesa_set_add(ctx->vdpSurfaces, surf); return (GLintptr)surf; } @@ -227,7 +228,7 @@ _mesa_VDPAUIsSurfaceNV(GLintptr surface) return false; } - if (!_mesa_set_search(ctx->vdpSurfaces, _mesa_hash_pointer(surf), surf)) { + if (!_mesa_set_search(ctx->vdpSurfaces, surf)) { return false; } @@ -251,7 +252,7 @@ _mesa_VDPAUUnregisterSurfaceNV(GLintptr surface) if (surface == 0) return; - entry = _mesa_set_search(ctx->vdpSurfaces, _mesa_hash_pointer(surf), surf); + entry = _mesa_set_search(ctx->vdpSurfaces, surf); if (!entry) { _mesa_error(ctx, GL_INVALID_VALUE, "VDPAUUnregisterSurfaceNV"); return; @@ -280,7 +281,7 @@ _mesa_VDPAUGetSurfaceivNV(GLintptr surface, GLenum pname, GLsizei bufSize, return; } - if (!_mesa_set_search(ctx->vdpSurfaces, _mesa_hash_pointer(surf), surf)) { + if (!_mesa_set_search(ctx->vdpSurfaces, surf)) { _mesa_error(ctx, GL_INVALID_VALUE, "VDPAUGetSurfaceivNV"); return; } @@ -312,7 +313,7 @@ _mesa_VDPAUSurfaceAccessNV(GLintptr surface, GLenum access) return; } - if (!_mesa_set_search(ctx->vdpSurfaces, _mesa_hash_pointer(surf), surf)) { + if (!_mesa_set_search(ctx->vdpSurfaces, surf)) { _mesa_error(ctx, GL_INVALID_VALUE, "VDPAUSurfaceAccessNV"); return; } @@ -346,7 +347,7 @@ _mesa_VDPAUMapSurfacesNV(GLsizei numSurfaces, const GLintptr *surfaces) for (i = 0; i < numSurfaces; ++i) { struct vdp_surface *surf = (struct vdp_surface *)surfaces[i]; - if (!_mesa_set_search(ctx->vdpSurfaces, _mesa_hash_pointer(surf), surf)) { + if (!_mesa_set_search(ctx->vdpSurfaces, surf)) { _mesa_error(ctx, GL_INVALID_VALUE, "VDPAUSurfaceAccessNV"); return; } @@ -400,7 +401,7 @@ _mesa_VDPAUUnmapSurfacesNV(GLsizei numSurfaces, const GLintptr *surfaces) for (i = 0; i < numSurfaces; ++i) { struct vdp_surface *surf = (struct vdp_surface *)surfaces[i]; - if (!_mesa_set_search(ctx->vdpSurfaces, _mesa_hash_pointer(surf), surf)) { + if (!_mesa_set_search(ctx->vdpSurfaces, surf)) { _mesa_error(ctx, GL_INVALID_VALUE, "VDPAUSurfaceAccessNV"); return; } @@ -422,7 +423,7 @@ _mesa_VDPAUUnmapSurfacesNV(GLsizei numSurfaces, const GLintptr *surfaces) _mesa_lock_texture(ctx, tex); - image = _mesa_select_tex_image(ctx, tex, surf->target, 0); + image = _mesa_select_tex_image(tex, surf->target, 0); ctx->Driver.VDPAUUnmapSurface(ctx, surf->target, surf->access, surf->output, tex, image, diff --git a/mesalib/src/mesa/math/m_translate.c b/mesalib/src/mesa/math/m_translate.c index 0b8c858d7..3a8ca74f6 100644 --- a/mesalib/src/mesa/math/m_translate.c +++ b/mesalib/src/mesa/math/m_translate.c @@ -30,7 +30,6 @@ #include "main/glheader.h" #include "main/macros.h" -#include "main/mtypes.h" /* GLchan hack */ #include "m_translate.h" @@ -675,26 +674,6 @@ void _math_trans_4ub(GLubyte (*to)[4], _math_trans_4ub_tab[size][TYPE_IDX(type)]( to, ptr, stride, start, n ); } -/** - * Translate vector of values to GLchan [4]. - */ -void _math_trans_4chan( GLchan (*to)[4], - const void *ptr, - GLuint stride, - GLenum type, - GLuint size, - GLuint start, - GLuint n ) -{ -#if CHAN_TYPE == GL_UNSIGNED_BYTE - _math_trans_4ub( to, ptr, stride, type, size, start, n ); -#elif CHAN_TYPE == GL_UNSIGNED_SHORT - _math_trans_4us( to, ptr, stride, type, size, start, n ); -#elif CHAN_TYPE == GL_FLOAT - _math_trans_4fn( to, ptr, stride, type, size, start, n ); -#endif -} - /** * Translate vector of values to GLushort [4]. */ diff --git a/mesalib/src/mesa/math/m_translate.h b/mesalib/src/mesa/math/m_translate.h index 250921a3f..bdfa4c770 100644 --- a/mesalib/src/mesa/math/m_translate.h +++ b/mesalib/src/mesa/math/m_translate.h @@ -28,8 +28,6 @@ #include "main/compiler.h" #include "main/glheader.h" -#include "main/mtypes.h" /* hack for GLchan */ -#include "swrast/s_chan.h" /** * Array translation. @@ -76,14 +74,6 @@ extern void _math_trans_4ub(GLubyte (*to)[4], GLuint start, GLuint n ); -extern void _math_trans_4chan( GLchan (*to)[4], - const void *ptr, - GLuint stride, - GLenum type, - GLuint size, - GLuint start, - GLuint n ); - extern void _math_trans_4us(GLushort (*to)[4], const void *ptr, GLuint stride, diff --git a/mesalib/src/mesa/program/Android.mk b/mesalib/src/mesa/program/Android.mk index 19c4be0fe..a237b65bc 100644 --- a/mesalib/src/mesa/program/Android.mk +++ b/mesalib/src/mesa/program/Android.mk @@ -39,8 +39,6 @@ endef # Import the following variables: # PROGRAM_FILES include $(MESA_TOP)/src/mesa/Makefile.sources -SRCDIR := -BUILDDIR := include $(CLEAR_VARS) diff --git a/mesalib/src/mesa/program/arbprogparse.c b/mesalib/src/mesa/program/arbprogparse.c index 7dec399a5..53a6f37cb 100644 --- a/mesalib/src/mesa/program/arbprogparse.c +++ b/mesalib/src/mesa/program/arbprogparse.c @@ -85,9 +85,6 @@ _mesa_parse_arb_fragment_program(struct gl_context* ctx, GLenum target, return; } - if ((ctx->_Shader->Flags & GLSL_NO_OPT) == 0) - _mesa_optimize_program(ctx, &prog); - free(program->Base.String); /* Copy the relevant contents of the arb_program struct into the diff --git a/mesalib/src/mesa/program/hash_table.h b/mesalib/src/mesa/program/hash_table.h index b814497a6..6122b1f8a 100644 --- a/mesalib/src/mesa/program/hash_table.h +++ b/mesalib/src/mesa/program/hash_table.h @@ -199,6 +199,11 @@ string_to_uint_map_dtor(struct string_to_uint_map *); #ifdef __cplusplus } +struct string_map_iterate_wrapper_closure { + void (*callback)(const char *key, unsigned value, void *closure); + void *closure; +}; + /** * Map from a string (name) to an unsigned integer value * @@ -229,6 +234,24 @@ public: hash_table_clear(this->ht); } + /** + * Runs a passed callback for the hash + */ + void iterate(void (*func)(const char *, unsigned, void *), void *closure) + { + struct string_map_iterate_wrapper_closure *wrapper; + + wrapper = (struct string_map_iterate_wrapper_closure *) + malloc(sizeof(struct string_map_iterate_wrapper_closure)); + if (wrapper == NULL) + return; + + wrapper->callback = func; + wrapper->closure = closure; + + hash_table_call_foreach(this->ht, subtract_one_wrapper, wrapper); + } + /** * Get the value associated with a particular key * @@ -282,6 +305,17 @@ private: free((char *)key); } + static void subtract_one_wrapper(const void *key, void *data, void *closure) + { + struct string_map_iterate_wrapper_closure *wrapper = + (struct string_map_iterate_wrapper_closure *) closure; + unsigned value = (intptr_t) data; + + value -= 1; + + wrapper->callback((const char *) key, value, wrapper->closure); + } + struct hash_table *ht; }; diff --git a/mesalib/src/mesa/program/ir_to_mesa.cpp b/mesalib/src/mesa/program/ir_to_mesa.cpp index 5cd905822..b2776da45 100644 --- a/mesalib/src/mesa/program/ir_to_mesa.cpp +++ b/mesalib/src/mesa/program/ir_to_mesa.cpp @@ -43,19 +43,18 @@ #include "linker.h" #include "main/mtypes.h" +#include "main/shaderapi.h" #include "main/shaderobj.h" #include "main/uniforms.h" -#include "program/hash_table.h" -extern "C" { -#include "main/shaderapi.h" +#include "program/hash_table.h" #include "program/prog_instruction.h" #include "program/prog_optimize.h" #include "program/prog_print.h" #include "program/program.h" #include "program/prog_parameter.h" #include "program/sampler.h" -} + static int swizzle_for_size(int size); @@ -607,6 +606,20 @@ type_size(const struct glsl_type *type) */ return 1; } + break; + case GLSL_TYPE_DOUBLE: + if (type->is_matrix()) { + if (type->vector_elements > 2) + return type->matrix_columns * 2; + else + return type->matrix_columns; + } else { + if (type->vector_elements > 2) + return 2; + else + return 1; + } + break; case GLSL_TYPE_ARRAY: assert(type->length > 0); return type_size(type->fields.array) * type->length; @@ -1153,7 +1166,7 @@ ir_to_mesa_visitor::visit(ir_expression *ir) assert(!"not reached: should be handled by ir_div_to_mul_rcp"); break; case ir_binop_mod: - /* Floating point should be lowered by MOD_TO_FRACT in the compiler. */ + /* Floating point should be lowered by MOD_TO_FLOOR in the compiler. */ assert(ir->type->is_integer()); emit(ir, OPCODE_MUL, result_dst, op[0], op[1]); break; @@ -1349,6 +1362,7 @@ ir_to_mesa_visitor::visit(ir_expression *ir) case ir_unop_pack_unorm_2x16: case ir_unop_pack_unorm_4x8: case ir_unop_pack_half_2x16: + case ir_unop_pack_double_2x32: case ir_unop_unpack_snorm_2x16: case ir_unop_unpack_snorm_4x8: case ir_unop_unpack_unorm_2x16: @@ -1356,11 +1370,21 @@ ir_to_mesa_visitor::visit(ir_expression *ir) case ir_unop_unpack_half_2x16: case ir_unop_unpack_half_2x16_split_x: case ir_unop_unpack_half_2x16_split_y: + case ir_unop_unpack_double_2x32: case ir_binop_pack_half_2x16_split: case ir_unop_bitfield_reverse: case ir_unop_bit_count: case ir_unop_find_msb: case ir_unop_find_lsb: + case ir_unop_d2f: + case ir_unop_f2d: + case ir_unop_d2i: + case ir_unop_i2d: + case ir_unop_d2u: + case ir_unop_u2d: + case ir_unop_d2b: + case ir_unop_frexp_sig: + case ir_unop_frexp_exp: assert(!"not supported"); break; case ir_binop_min: @@ -1450,6 +1474,7 @@ ir_to_mesa_visitor::visit(ir_swizzle *ir) ir->val->accept(this); src = this->result; assert(src.file != PROGRAM_UNDEFINED); + assert(ir->type->vector_elements > 0); for (i = 0; i < 4; i++) { if (i < ir->type->vector_elements) { @@ -2385,6 +2410,8 @@ add_uniform_to_shader::visit_field(const glsl_type *type, const char *name, if (type->is_vector() || type->is_scalar()) { size = type->vector_elements; + if (type->is_double()) + size *= 2; } else { size = type_size(type) * 4; } @@ -2489,6 +2516,7 @@ _mesa_associate_uniform_storage(struct gl_context *ctx, enum gl_uniform_driver_format format = uniform_native; unsigned columns = 0; + int dmul = 4 * sizeof(float); switch (storage->type->base_type) { case GLSL_TYPE_UINT: assert(ctx->Const.NativeIntegers); @@ -2500,6 +2528,11 @@ _mesa_associate_uniform_storage(struct gl_context *ctx, (ctx->Const.NativeIntegers) ? uniform_native : uniform_int_float; columns = 1; break; + + case GLSL_TYPE_DOUBLE: + if (storage->type->vector_elements > 2) + dmul *= 2; + /* fallthrough */ case GLSL_TYPE_FLOAT: format = uniform_native; columns = storage->type->matrix_columns; @@ -2524,8 +2557,8 @@ _mesa_associate_uniform_storage(struct gl_context *ctx, } _mesa_uniform_attach_driver_storage(storage, - 4 * sizeof(float) * columns, - 4 * sizeof(float), + dmul * columns, + dmul, format, ¶ms->ParameterValues[i]); @@ -2943,12 +2976,9 @@ _mesa_ir_link_shader(struct gl_context *ctx, struct gl_shader_program *prog) /* Lowering */ do_mat_op_to_vec(ir); - GLenum target = _mesa_shader_stage_to_program(prog->_LinkedShaders[i]->Stage); - lower_instructions(ir, (MOD_TO_FRACT | DIV_TO_MUL_RCP | EXP_TO_EXP2 + lower_instructions(ir, (MOD_TO_FLOOR | DIV_TO_MUL_RCP | EXP_TO_EXP2 | LOG_TO_LOG2 | INT_DIV_TO_MUL_RCP - | ((options->EmitNoPow) ? POW_TO_EXP2 : 0) - | ((target == GL_VERTEX_PROGRAM_ARB) ? SAT_TO_CLAMP - : 0))); + | ((options->EmitNoPow) ? POW_TO_EXP2 : 0))); progress = do_lower_jumps(ir, true, true, options->EmitNoMainReturn, options->EmitNoCont, options->EmitNoLoops) || progress; diff --git a/mesalib/src/mesa/program/prog_cache.h b/mesalib/src/mesa/program/prog_cache.h index fdd7e264b..e37f1d7be 100644 --- a/mesalib/src/mesa/program/prog_cache.h +++ b/mesalib/src/mesa/program/prog_cache.h @@ -32,6 +32,12 @@ #include "main/glheader.h" + +#ifdef __cplusplus +extern "C" { +#endif + + struct gl_context; /** Opaque type */ @@ -65,4 +71,9 @@ _mesa_shader_cache_insert(struct gl_context *ctx, struct gl_shader_program *program); +#ifdef __cplusplus +} +#endif + + #endif /* PROG_CACHE_H */ diff --git a/mesalib/src/mesa/program/prog_execute.c b/mesalib/src/mesa/program/prog_execute.c index 650c40f2a..b2fbc808a 100644 --- a/mesalib/src/mesa/program/prog_execute.c +++ b/mesalib/src/mesa/program/prog_execute.c @@ -123,7 +123,7 @@ get_src_register_pointer(const struct prog_src_register *source, return (GLfloat *) prog->Parameters->ParameterValues[reg]; case PROGRAM_SYSTEM_VALUE: - assert(reg < Elements(machine->SystemValues)); + assert(reg < (GLint) Elements(machine->SystemValues)); return machine->SystemValues[reg]; default: @@ -298,15 +298,6 @@ fetch_vector1(const struct prog_src_register *source, } -static GLuint -fetch_vector1ui(const struct prog_src_register *source, - const struct gl_program_machine *machine) -{ - const GLuint *src = (GLuint *) get_src_register_pointer(source, machine); - return src[GET_SWZ(source->Swizzle, 0)]; -} - - /** * Fetch texel from texture. Use partial derivatives when possible. */ @@ -487,71 +478,6 @@ store_vector4(const struct prog_instruction *inst, } -/** - * Store 4 uints into a register. Observe the set-condition-code flags. - */ -static void -store_vector4ui(const struct prog_instruction *inst, - struct gl_program_machine *machine, const GLuint value[4]) -{ - const struct prog_dst_register *dstReg = &(inst->DstReg); - GLuint writeMask = dstReg->WriteMask; - GLuint *dst = (GLuint *) get_dst_register_pointer(dstReg, machine); - - if (dstReg->CondMask != COND_TR) { - /* condition codes may turn off some writes */ - if (writeMask & WRITEMASK_X) { - if (!test_cc(machine->CondCodes[GET_SWZ(dstReg->CondSwizzle, 0)], - dstReg->CondMask)) - writeMask &= ~WRITEMASK_X; - } - if (writeMask & WRITEMASK_Y) { - if (!test_cc(machine->CondCodes[GET_SWZ(dstReg->CondSwizzle, 1)], - dstReg->CondMask)) - writeMask &= ~WRITEMASK_Y; - } - if (writeMask & WRITEMASK_Z) { - if (!test_cc(machine->CondCodes[GET_SWZ(dstReg->CondSwizzle, 2)], - dstReg->CondMask)) - writeMask &= ~WRITEMASK_Z; - } - if (writeMask & WRITEMASK_W) { - if (!test_cc(machine->CondCodes[GET_SWZ(dstReg->CondSwizzle, 3)], - dstReg->CondMask)) - writeMask &= ~WRITEMASK_W; - } - } - - if (writeMask & WRITEMASK_X) - dst[0] = value[0]; - if (writeMask & WRITEMASK_Y) - dst[1] = value[1]; - if (writeMask & WRITEMASK_Z) - dst[2] = value[2]; - if (writeMask & WRITEMASK_W) - dst[3] = value[3]; - - if (inst->CondUpdate) { - if (writeMask & WRITEMASK_X) - machine->CondCodes[0] = generate_cc((float)value[0]); - if (writeMask & WRITEMASK_Y) - machine->CondCodes[1] = generate_cc((float)value[1]); - if (writeMask & WRITEMASK_Z) - machine->CondCodes[2] = generate_cc((float)value[2]); - if (writeMask & WRITEMASK_W) - machine->CondCodes[3] = generate_cc((float)value[3]); -#if DEBUG_PROG - printf("CondCodes=(%s,%s,%s,%s) for:\n", - _mesa_condcode_string(machine->CondCodes[0]), - _mesa_condcode_string(machine->CondCodes[1]), - _mesa_condcode_string(machine->CondCodes[2]), - _mesa_condcode_string(machine->CondCodes[3])); -#endif - } -} - - - /** * Execute the given vertex/fragment program. * @@ -1334,7 +1260,6 @@ _mesa_execute_program(struct gl_context * ctx, else if (swz == SWIZZLE_ONE) result[i] = 1.0; else { - ASSERT(swz >= 0); ASSERT(swz <= 3); result[i] = src[swz]; } diff --git a/mesalib/src/mesa/program/prog_hash_table.c b/mesalib/src/mesa/program/prog_hash_table.c index 2445d8434..5592b6fb8 100644 --- a/mesalib/src/mesa/program/prog_hash_table.c +++ b/mesalib/src/mesa/program/prog_hash_table.c @@ -29,7 +29,7 @@ */ #include "main/imports.h" -#include "main/simple_list.h" +#include "util/simple_list.h" #include "hash_table.h" struct node { diff --git a/mesalib/src/mesa/program/prog_instruction.c b/mesalib/src/mesa/program/prog_instruction.c index 976024e3c..254c0128f 100644 --- a/mesalib/src/mesa/program/prog_instruction.c +++ b/mesalib/src/mesa/program/prog_instruction.c @@ -74,29 +74,6 @@ _mesa_alloc_instructions(GLuint numInst) } -/** - * Reallocate memory storing an array of program instructions. - * This is used when we need to append additional instructions onto an - * program. - * \param oldInst pointer to first of old/src instructions - * \param numOldInst number of instructions at - * \param numNewInst desired size of new instruction array. - * \return pointer to start of new instruction array. - */ -struct prog_instruction * -_mesa_realloc_instructions(struct prog_instruction *oldInst, - GLuint numOldInst, GLuint numNewInst) -{ - struct prog_instruction *newInst; - - newInst = (struct prog_instruction *) - realloc(oldInst, - numNewInst * sizeof(struct prog_instruction)); - - return newInst; -} - - /** * Copy an array of program instructions. * \param dest pointer to destination. diff --git a/mesalib/src/mesa/program/prog_instruction.h b/mesalib/src/mesa/program/prog_instruction.h index de7880499..0957bd9d7 100644 --- a/mesalib/src/mesa/program/prog_instruction.h +++ b/mesalib/src/mesa/program/prog_instruction.h @@ -384,10 +384,6 @@ _mesa_init_instructions(struct prog_instruction *inst, GLuint count); extern struct prog_instruction * _mesa_alloc_instructions(GLuint numInst); -extern struct prog_instruction * -_mesa_realloc_instructions(struct prog_instruction *oldInst, - GLuint numOldInst, GLuint numNewInst); - extern struct prog_instruction * _mesa_copy_instructions(struct prog_instruction *dest, const struct prog_instruction *src, GLuint n); diff --git a/mesalib/src/mesa/program/prog_optimize.c b/mesalib/src/mesa/program/prog_optimize.c index 60530ebf0..65d427cb4 100644 --- a/mesalib/src/mesa/program/prog_optimize.c +++ b/mesalib/src/mesa/program/prog_optimize.c @@ -408,7 +408,7 @@ find_next_use(const struct gl_program *prog, for (j = 0; j < numSrc; j++) { if (inst->SrcReg[j].RelAddr || (inst->SrcReg[j].File == PROGRAM_TEMPORARY && - inst->SrcReg[j].Index == index && + inst->SrcReg[j].Index == (GLint)index && (get_src_arg_mask(inst,j,NO_MASK) & mask))) return READ; } @@ -944,7 +944,7 @@ update_interval(GLint intBegin[], GLint intEnd[], struct loop_info *loopStack, GLuint loopStackDepth, GLuint index, GLuint ic) { - int i; + unsigned i; GLuint begin = ic; GLuint end = ic; diff --git a/mesalib/src/mesa/program/prog_optimize.h b/mesalib/src/mesa/program/prog_optimize.h index 7607bffdd..1f20ac0f8 100644 --- a/mesalib/src/mesa/program/prog_optimize.h +++ b/mesalib/src/mesa/program/prog_optimize.h @@ -29,6 +29,11 @@ #include "main/glheader.h" +#ifdef __cplusplus +extern "C" { +#endif + + struct gl_context; struct gl_program; struct prog_instruction; @@ -46,4 +51,10 @@ _mesa_optimize_program(struct gl_context *ctx, struct gl_program *program); extern GLboolean _mesa_constant_fold(struct gl_program *prog); + +#ifdef __cplusplus +} +#endif + + #endif diff --git a/mesalib/src/mesa/program/prog_parameter.c b/mesalib/src/mesa/program/prog_parameter.c index 896c6052b..0ef46415d 100644 --- a/mesalib/src/mesa/program/prog_parameter.c +++ b/mesalib/src/mesa/program/prog_parameter.c @@ -120,7 +120,7 @@ _mesa_add_parameter(struct gl_program_parameter_list *paramList, paramList->Size = paramList->Size + 4 * sz4; /* realloc arrays */ - paramList->Parameters = (struct gl_program_parameter *) + paramList->Parameters = realloc(paramList->Parameters, paramList->Size * sizeof(struct gl_program_parameter)); diff --git a/mesalib/src/mesa/program/prog_print.c b/mesalib/src/mesa/program/prog_print.c index 4a5c1c1fb..3f499749a 100644 --- a/mesalib/src/mesa/program/prog_print.c +++ b/mesalib/src/mesa/program/prog_print.c @@ -82,7 +82,7 @@ _mesa_register_file_name(gl_register_file f) * Return ARB_v/f_prog-style input attrib string. */ static const char * -arb_input_attrib_string(GLint index, GLenum progType) +arb_input_attrib_string(GLuint index, GLenum progType) { /* * These strings should match the VERT_ATTRIB_x and VARYING_SLOT_x tokens. @@ -242,7 +242,7 @@ _mesa_print_fp_inputs(GLbitfield inputs) * Return ARB_v/f_prog-style output attrib string. */ static const char * -arb_output_attrib_string(GLint index, GLenum progType) +arb_output_attrib_string(GLuint index, GLenum progType) { /* * These strings should match the VARYING_SLOT_x and FRAG_RESULT_x tokens. diff --git a/mesalib/src/mesa/program/prog_print.h b/mesalib/src/mesa/program/prog_print.h index cd61568e9..9058dfa76 100644 --- a/mesalib/src/mesa/program/prog_print.h +++ b/mesalib/src/mesa/program/prog_print.h @@ -31,6 +31,12 @@ #include "main/glheader.h" #include "main/mtypes.h" + +#ifdef __cplusplus +extern "C" { +#endif + + struct gl_program; struct gl_program_parameter_list; struct gl_shader; @@ -115,4 +121,9 @@ extern void _mesa_append_uniforms_to_file(const struct gl_shader *shader); +#ifdef __cplusplus +} +#endif + + #endif /* PROG_PRINT_H */ diff --git a/mesalib/src/mesa/program/prog_statevars.c b/mesalib/src/mesa/program/prog_statevars.c index be5ddb106..7f5daf8c6 100644 --- a/mesalib/src/mesa/program/prog_statevars.c +++ b/mesalib/src/mesa/program/prog_statevars.c @@ -295,9 +295,7 @@ _mesa_fetch_state(struct gl_context *ctx, const gl_state_index state[], const gl_state_index modifier = state[4]; const GLfloat *m; GLuint row, i; - ASSERT(firstRow >= 0); ASSERT(firstRow < 4); - ASSERT(lastRow >= 0); ASSERT(lastRow < 4); if (mat == STATE_MODELVIEW_MATRIX) { matrix = ctx->ModelviewMatrixStack.Top; diff --git a/mesalib/src/mesa/program/programopt.c b/mesalib/src/mesa/program/programopt.c index b654b1db6..fdaa4a465 100644 --- a/mesalib/src/mesa/program/programopt.c +++ b/mesalib/src/mesa/program/programopt.c @@ -589,94 +589,3 @@ _mesa_remove_output_reads(struct gl_program *prog, gl_register_file type) } } } - - -/** - * Make the given fragment program into a "no-op" shader. - * Actually, just copy the incoming fragment color (or texcoord) - * to the output color. - * This is for debug/test purposes. - */ -void -_mesa_nop_fragment_program(struct gl_context *ctx, struct gl_fragment_program *prog) -{ - struct prog_instruction *inst; - GLuint inputAttr; - - inst = _mesa_alloc_instructions(2); - if (!inst) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "_mesa_nop_fragment_program"); - return; - } - - _mesa_init_instructions(inst, 2); - - inst[0].Opcode = OPCODE_MOV; - inst[0].DstReg.File = PROGRAM_OUTPUT; - inst[0].DstReg.Index = FRAG_RESULT_COLOR; - inst[0].SrcReg[0].File = PROGRAM_INPUT; - if (prog->Base.InputsRead & VARYING_BIT_COL0) - inputAttr = VARYING_SLOT_COL0; - else - inputAttr = VARYING_SLOT_TEX0; - inst[0].SrcReg[0].Index = inputAttr; - - inst[1].Opcode = OPCODE_END; - - _mesa_free_instructions(prog->Base.Instructions, - prog->Base.NumInstructions); - - prog->Base.Instructions = inst; - prog->Base.NumInstructions = 2; - prog->Base.InputsRead = BITFIELD64_BIT(inputAttr); - prog->Base.OutputsWritten = BITFIELD64_BIT(FRAG_RESULT_COLOR); -} - - -/** - * \sa _mesa_nop_fragment_program - * Replace the given vertex program with a "no-op" program that just - * transforms vertex position and emits color. - */ -void -_mesa_nop_vertex_program(struct gl_context *ctx, struct gl_vertex_program *prog) -{ - struct prog_instruction *inst; - GLuint inputAttr; - - /* - * Start with a simple vertex program that emits color. - */ - inst = _mesa_alloc_instructions(2); - if (!inst) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "_mesa_nop_vertex_program"); - return; - } - - _mesa_init_instructions(inst, 2); - - inst[0].Opcode = OPCODE_MOV; - inst[0].DstReg.File = PROGRAM_OUTPUT; - inst[0].DstReg.Index = VARYING_SLOT_COL0; - inst[0].SrcReg[0].File = PROGRAM_INPUT; - if (prog->Base.InputsRead & VERT_BIT_COLOR0) - inputAttr = VERT_ATTRIB_COLOR0; - else - inputAttr = VERT_ATTRIB_TEX0; - inst[0].SrcReg[0].Index = inputAttr; - - inst[1].Opcode = OPCODE_END; - - _mesa_free_instructions(prog->Base.Instructions, - prog->Base.NumInstructions); - - prog->Base.Instructions = inst; - prog->Base.NumInstructions = 2; - prog->Base.InputsRead = BITFIELD64_BIT(inputAttr); - prog->Base.OutputsWritten = BITFIELD64_BIT(VARYING_SLOT_COL0); - - /* - * Now insert code to do standard modelview/projection transformation. - */ - _mesa_insert_mvp_code(ctx, prog); -} diff --git a/mesalib/src/mesa/program/programopt.h b/mesalib/src/mesa/program/programopt.h index f22109fb4..757421edf 100644 --- a/mesalib/src/mesa/program/programopt.h +++ b/mesalib/src/mesa/program/programopt.h @@ -28,6 +28,12 @@ #include "main/mtypes.h" + +#ifdef __cplusplus +extern "C" { +#endif + + extern void _mesa_insert_mvp_code(struct gl_context *ctx, struct gl_vertex_program *vprog); @@ -45,11 +51,9 @@ _mesa_count_texture_instructions(struct gl_program *prog); extern void _mesa_remove_output_reads(struct gl_program *prog, gl_register_file type); -extern void -_mesa_nop_fragment_program(struct gl_context *ctx, struct gl_fragment_program *prog); - -extern void -_mesa_nop_vertex_program(struct gl_context *ctx, struct gl_vertex_program *prog); +#ifdef __cplusplus +} +#endif #endif /* PROGRAMOPT_H */ diff --git a/mesalib/src/mesa/program/sampler.cpp b/mesalib/src/mesa/program/sampler.cpp index 29a540871..f8584c968 100644 --- a/mesalib/src/mesa/program/sampler.cpp +++ b/mesalib/src/mesa/program/sampler.cpp @@ -27,15 +27,14 @@ #include "glsl_types.h" #include "ir_visitor.h" #include "../glsl/program.h" -#include "program/hash_table.h" #include "ir_uniform.h" -extern "C" { #include "main/compiler.h" #include "main/mtypes.h" +#include "program/hash_table.h" #include "program/prog_parameter.h" #include "program/program.h" -} + class get_sampler_name : public ir_hierarchical_visitor { @@ -104,7 +103,7 @@ public: }; -extern "C" int +int _mesa_get_sampler_uniform_value(class ir_dereference *sampler, struct gl_shader_program *shader_program, const struct gl_program *prog) @@ -136,7 +135,7 @@ _mesa_get_sampler_uniform_value(class ir_dereference *sampler, } -extern "C" class ir_rvalue * +class ir_rvalue * _mesa_get_sampler_array_nonconst_index(class ir_dereference *sampler) { ir_dereference_array *deref_arr = sampler->as_dereference_array(); diff --git a/mesalib/src/mesa/program/sampler.h b/mesalib/src/mesa/program/sampler.h index 8b7c3b63e..61c7f5851 100644 --- a/mesalib/src/mesa/program/sampler.h +++ b/mesalib/src/mesa/program/sampler.h @@ -23,6 +23,10 @@ * DEALINGS IN THE SOFTWARE. */ +#ifndef SAMPLER_H +#define SAMPLER_H + + int _mesa_get_sampler_uniform_value(class ir_dereference *sampler, struct gl_shader_program *shader_program, @@ -30,3 +34,6 @@ _mesa_get_sampler_uniform_value(class ir_dereference *sampler, class ir_rvalue * _mesa_get_sampler_array_nonconst_index(class ir_dereference *sampler); + + +#endif /* SAMPLER_H */ diff --git a/mesalib/src/mesa/state_tracker/st_atom_blend.c b/mesalib/src/mesa/state_tracker/st_atom_blend.c index 064e0c14f..6bb4077f3 100644 --- a/mesalib/src/mesa/state_tracker/st_atom_blend.c +++ b/mesalib/src/mesa/state_tracker/st_atom_blend.c @@ -175,7 +175,7 @@ static GLboolean blend_per_rt(const struct gl_context *ctx) { if (ctx->Color.BlendEnabled && - (ctx->Color.BlendEnabled != ((1 << ctx->Const.MaxDrawBuffers) - 1))) { + (ctx->Color.BlendEnabled != ((1U << ctx->Const.MaxDrawBuffers) - 1))) { /* This can only happen if GL_EXT_draw_buffers2 is enabled */ return GL_TRUE; } diff --git a/mesalib/src/mesa/state_tracker/st_atom_rasterizer.c b/mesalib/src/mesa/state_tracker/st_atom_rasterizer.c index 606f19a18..cceed42c8 100644 --- a/mesalib/src/mesa/state_tracker/st_atom_rasterizer.c +++ b/mesalib/src/mesa/state_tracker/st_atom_rasterizer.c @@ -155,6 +155,7 @@ static void update_raster_state( struct st_context *st ) raster->offset_tri = ctx->Polygon.OffsetFill; raster->offset_units = ctx->Polygon.OffsetUnits; raster->offset_scale = ctx->Polygon.OffsetFactor; + raster->offset_clamp = ctx->Polygon.OffsetClamp; } raster->poly_smooth = ctx->Polygon.SmoothFlag; diff --git a/mesalib/src/mesa/state_tracker/st_atom_sampler.c b/mesalib/src/mesa/state_tracker/st_atom_sampler.c index 17b536bf5..b68eb16d7 100644 --- a/mesalib/src/mesa/state_tracker/st_atom_sampler.c +++ b/mesalib/src/mesa/state_tracker/st_atom_sampler.c @@ -36,6 +36,7 @@ #include "main/mtypes.h" #include "main/glformats.h" #include "main/samplerobj.h" +#include "main/teximage.h" #include "main/texobj.h" #include "st_context.h" @@ -133,7 +134,6 @@ convert_sampler(struct st_context *st, const struct gl_texture_object *texobj; struct gl_context *ctx = st->ctx; struct gl_sampler_object *msamp; - const struct gl_texture_image *teximg; GLenum texBaseFormat; texobj = ctx->Texture.Unit[texUnit]._Current; @@ -141,8 +141,7 @@ convert_sampler(struct st_context *st, texobj = _mesa_get_fallback_texture(ctx, TEXTURE_2D_INDEX); } - teximg = texobj->Image[0][texobj->BaseLevel]; - texBaseFormat = teximg ? teximg->_BaseFormat : GL_RGBA; + texBaseFormat = _mesa_texture_base_format(texobj); msamp = _mesa_get_samplerobj(ctx, texUnit); diff --git a/mesalib/src/mesa/state_tracker/st_atom_scissor.c b/mesalib/src/mesa/state_tracker/st_atom_scissor.c index b72030944..4ebe799e3 100644 --- a/mesalib/src/mesa/state_tracker/st_atom_scissor.c +++ b/mesalib/src/mesa/state_tracker/st_atom_scissor.c @@ -47,7 +47,7 @@ update_scissor( struct st_context *st ) const struct gl_context *ctx = st->ctx; const struct gl_framebuffer *fb = ctx->DrawBuffer; GLint miny, maxy; - int i; + unsigned i; bool changed = false; for (i = 0 ; i < ctx->Const.MaxViewports; i++) { scissor[i].minx = 0; diff --git a/mesalib/src/mesa/state_tracker/st_atom_shader.c b/mesalib/src/mesa/state_tracker/st_atom_shader.c index 6515a98a3..73768ed12 100644 --- a/mesalib/src/mesa/state_tracker/st_atom_shader.c +++ b/mesalib/src/mesa/state_tracker/st_atom_shader.c @@ -149,7 +149,12 @@ update_vp( struct st_context *st ) key.passthrough_edgeflags = st->vertdata_edgeflags; key.clamp_color = st->clamp_vert_color_in_shader && - st->ctx->Light._ClampVertexColor; + st->ctx->Light._ClampVertexColor && + (stvp->Base.Base.OutputsWritten & + (VARYING_SLOT_COL0 | + VARYING_SLOT_COL1 | + VARYING_SLOT_BFC0 | + VARYING_SLOT_BFC1)); st->vp_variant = st_get_vp_variant(st, stvp, &key); diff --git a/mesalib/src/mesa/state_tracker/st_atom_texture.c b/mesalib/src/mesa/state_tracker/st_atom_texture.c index 19072ae2f..eff28fc6f 100644 --- a/mesalib/src/mesa/state_tracker/st_atom_texture.c +++ b/mesalib/src/mesa/state_tracker/st_atom_texture.c @@ -35,6 +35,7 @@ #include "main/macros.h" #include "main/mtypes.h" #include "main/samplerobj.h" +#include "main/teximage.h" #include "main/texobj.h" #include "program/prog_instruction.h" @@ -175,12 +176,11 @@ compute_texture_format_swizzle(GLenum baseFormat, GLenum depthMode, static unsigned get_texture_format_swizzle(const struct st_texture_object *stObj) { - const struct gl_texture_image *texImage = - stObj->base.Image[0][stObj->base.BaseLevel]; + GLenum baseFormat = _mesa_texture_base_format(&stObj->base); unsigned tex_swizzle; - if (texImage) { - tex_swizzle = compute_texture_format_swizzle(texImage->_BaseFormat, + if (baseFormat != GL_NONE) { + tex_swizzle = compute_texture_format_swizzle(baseFormat, stObj->base.DepthMode, stObj->pt->format); } diff --git a/mesalib/src/mesa/state_tracker/st_atom_viewport.c b/mesalib/src/mesa/state_tracker/st_atom_viewport.c index efa056e10..2f62590c4 100644 --- a/mesalib/src/mesa/state_tracker/st_atom_viewport.c +++ b/mesalib/src/mesa/state_tracker/st_atom_viewport.c @@ -44,7 +44,7 @@ update_viewport( struct st_context *st ) { struct gl_context *ctx = st->ctx; GLfloat yScale, yBias; - int i; + unsigned i; /* _NEW_BUFFERS */ if (st_fb_orientation(ctx->DrawBuffer) == Y_0_TOP) { diff --git a/mesalib/src/mesa/state_tracker/st_cb_blit.c b/mesalib/src/mesa/state_tracker/st_cb_blit.c index 9c33f4eb9..bbaedd108 100644 --- a/mesalib/src/mesa/state_tracker/st_cb_blit.c +++ b/mesalib/src/mesa/state_tracker/st_cb_blit.c @@ -73,6 +73,8 @@ st_adjust_blit_for_msaa_resolve(struct pipe_blit_info *blit) static void st_BlitFramebuffer(struct gl_context *ctx, + struct gl_framebuffer *readFB, + struct gl_framebuffer *drawFB, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) @@ -83,8 +85,6 @@ st_BlitFramebuffer(struct gl_context *ctx, const uint pFilter = ((filter == GL_NEAREST) ? PIPE_TEX_FILTER_NEAREST : PIPE_TEX_FILTER_LINEAR); - struct gl_framebuffer *readFB = ctx->ReadBuffer; - struct gl_framebuffer *drawFB = ctx->DrawBuffer; struct { GLint srcX0, srcY0, srcX1, srcY1; GLint dstX0, dstY0, dstX1, dstY1; @@ -108,7 +108,7 @@ st_BlitFramebuffer(struct gl_context *ctx, * * XXX: This should depend on mask ! */ - if (!_mesa_clip_blit(ctx, + if (!_mesa_clip_blit(ctx, readFB, drawFB, &clip.srcX0, &clip.srcY0, &clip.srcX1, &clip.srcY1, &clip.dstX0, &clip.dstY0, &clip.dstX1, &clip.dstY1)) { return; /* nothing to draw/blit */ diff --git a/mesalib/src/mesa/state_tracker/st_cb_bufferobjects.c b/mesalib/src/mesa/state_tracker/st_cb_bufferobjects.c index 55f36442a..f24805cf5 100644 --- a/mesalib/src/mesa/state_tracker/st_cb_bufferobjects.c +++ b/mesalib/src/mesa/state_tracker/st_cb_bufferobjects.c @@ -186,7 +186,8 @@ st_bufferobj_data(struct gl_context *ctx, struct st_buffer_object *st_obj = st_buffer_object(obj); unsigned bind, pipe_usage, pipe_flags = 0; - if (size && data && st_obj->buffer && + if (target != GL_EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD && + size && data && st_obj->buffer && st_obj->Base.Size == size && st_obj->Base.Usage == usage && st_obj->Base.StorageFlags == storageFlags) { @@ -256,8 +257,15 @@ st_bufferobj_data(struct gl_context *ctx, break; case GL_STREAM_DRAW: case GL_STREAM_COPY: - pipe_usage = PIPE_USAGE_STREAM; - break; + /* XXX: Remove this test and fall-through when we have PBO unpacking + * acceleration. Right now, PBO unpacking is done by the CPU, so we + * have to make sure CPU reads are fast. + */ + if (target != GL_PIXEL_UNPACK_BUFFER_ARB) { + pipe_usage = PIPE_USAGE_STREAM; + break; + } + /* fall through */ case GL_STATIC_READ: case GL_DYNAMIC_READ: case GL_STREAM_READ: @@ -280,6 +288,7 @@ st_bufferobj_data(struct gl_context *ctx, } if (size != 0) { + struct pipe_screen *screen = pipe->screen; struct pipe_resource buffer; memset(&buffer, 0, sizeof buffer); @@ -293,16 +302,22 @@ st_bufferobj_data(struct gl_context *ctx, buffer.depth0 = 1; buffer.array_size = 1; - st_obj->buffer = pipe->screen->resource_create(pipe->screen, &buffer); + if (target == GL_EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD) { + st_obj->buffer = + screen->resource_from_user_memory(screen, &buffer, (void*)data); + } + else { + st_obj->buffer = screen->resource_create(screen, &buffer); + + if (st_obj->buffer && data) + pipe_buffer_write(pipe, st_obj->buffer, 0, size, data); + } if (!st_obj->buffer) { /* out of memory */ st_obj->Base.Size = 0; return GL_FALSE; } - - if (data) - pipe_buffer_write(pipe, st_obj->buffer, 0, size, data); } /* BufferData may change an array or uniform buffer, need to update it */ diff --git a/mesalib/src/mesa/state_tracker/st_cb_drawpixels.c b/mesalib/src/mesa/state_tracker/st_cb_drawpixels.c index 939fc2065..14fc13952 100644 --- a/mesalib/src/mesa/state_tracker/st_cb_drawpixels.c +++ b/mesalib/src/mesa/state_tracker/st_cb_drawpixels.c @@ -1100,7 +1100,7 @@ st_DrawPixels(struct gl_context *ctx, GLint x, GLint y, const GLfloat *color; struct pipe_context *pipe = st->pipe; GLboolean write_stencil = GL_FALSE, write_depth = GL_FALSE; - struct pipe_sampler_view *sv[2]; + struct pipe_sampler_view *sv[2] = { NULL }; int num_sampler_view = 1; struct st_fp_variant *fpv; struct gl_pixelstore_attrib clippedUnpack; @@ -1154,8 +1154,9 @@ st_DrawPixels(struct gl_context *ctx, GLint x, GLint y, color = NULL; if (st->pixel_xfer.pixelmap_enabled) { - sv[1] = st->pixel_xfer.pixelmap_sampler_view; - num_sampler_view++; + pipe_sampler_view_reference(&sv[1], + st->pixel_xfer.pixelmap_sampler_view); + num_sampler_view++; } } @@ -1176,7 +1177,8 @@ st_DrawPixels(struct gl_context *ctx, GLint x, GLint y, if (write_stencil) { enum pipe_format stencil_format = util_format_stencil_only(pt->format); - + /* we should not be doing pixel map/transfer (see above) */ + assert(num_sampler_view == 1); sv[1] = st_create_texture_sampler_view_format(st->pipe, pt, stencil_format); num_sampler_view++; @@ -1467,7 +1469,7 @@ st_CopyPixels(struct gl_context *ctx, GLint srcx, GLint srcy, struct st_renderbuffer *rbRead; void *driver_vp, *driver_fp; struct pipe_resource *pt; - struct pipe_sampler_view *sv[2]; + struct pipe_sampler_view *sv[2] = { NULL }; int num_sampler_view = 1; GLfloat *color; enum pipe_format srcFormat; @@ -1516,7 +1518,8 @@ st_CopyPixels(struct gl_context *ctx, GLint srcx, GLint srcy, driver_vp = make_passthrough_vertex_shader(st, GL_FALSE); if (st->pixel_xfer.pixelmap_enabled) { - sv[1] = st->pixel_xfer.pixelmap_sampler_view; + pipe_sampler_view_reference(&sv[1], + st->pixel_xfer.pixelmap_sampler_view); num_sampler_view++; } } diff --git a/mesalib/src/mesa/state_tracker/st_cb_drawtex.c b/mesalib/src/mesa/state_tracker/st_cb_drawtex.c index d057ff62a..1420b96e5 100644 --- a/mesalib/src/mesa/state_tracker/st_cb_drawtex.c +++ b/mesalib/src/mesa/state_tracker/st_cb_drawtex.c @@ -15,6 +15,7 @@ #include "main/imports.h" #include "main/image.h" #include "main/macros.h" +#include "main/teximage.h" #include "program/program.h" #include "program/prog_print.h" @@ -196,7 +197,7 @@ st_DrawTex(struct gl_context *ctx, GLfloat x, GLfloat y, GLfloat z, if (ctx->Texture.Unit[i]._Current && ctx->Texture.Unit[i]._Current->Target == GL_TEXTURE_2D) { struct gl_texture_object *obj = ctx->Texture.Unit[i]._Current; - struct gl_texture_image *img = obj->Image[0][obj->BaseLevel]; + const struct gl_texture_image *img = _mesa_base_tex_image(obj); const GLfloat wt = (GLfloat) img->Width; const GLfloat ht = (GLfloat) img->Height; const GLfloat s0 = obj->CropRect[0] / wt; diff --git a/mesalib/src/mesa/state_tracker/st_cb_fbo.c b/mesalib/src/mesa/state_tracker/st_cb_fbo.c index 7b6a444e6..296ea1e0d 100644 --- a/mesalib/src/mesa/state_tracker/st_cb_fbo.c +++ b/mesalib/src/mesa/state_tracker/st_cb_fbo.c @@ -408,9 +408,9 @@ st_update_renderbuffer_surface(struct st_context *st, { struct pipe_context *pipe = st->pipe; struct pipe_resource *resource = strb->texture; - int rtt_width = strb->Base.Width; - int rtt_height = strb->Base.Height; - int rtt_depth = strb->Base.Depth; + unsigned rtt_width = strb->Base.Width; + unsigned rtt_height = strb->Base.Height; + unsigned rtt_depth = strb->Base.Depth; /* * For winsys fbo, it is possible that the renderbuffer is sRGB-capable but * the format of strb->texture is linear (because we have no control over diff --git a/mesalib/src/mesa/state_tracker/st_cb_queryobj.c b/mesalib/src/mesa/state_tracker/st_cb_queryobj.c index 489f537d8..71222e80b 100644 --- a/mesalib/src/mesa/state_tracker/st_cb_queryobj.c +++ b/mesalib/src/mesa/state_tracker/st_cb_queryobj.c @@ -110,6 +110,19 @@ st_BeginQuery(struct gl_context *ctx, struct gl_query_object *q) else type = PIPE_QUERY_TIMESTAMP; break; + case GL_VERTICES_SUBMITTED_ARB: + case GL_PRIMITIVES_SUBMITTED_ARB: + case GL_VERTEX_SHADER_INVOCATIONS_ARB: + case GL_TESS_CONTROL_SHADER_PATCHES_ARB: + case GL_TESS_EVALUATION_SHADER_INVOCATIONS_ARB: + case GL_GEOMETRY_SHADER_INVOCATIONS: + case GL_GEOMETRY_SHADER_PRIMITIVES_EMITTED_ARB: + case GL_FRAGMENT_SHADER_INVOCATIONS_ARB: + case GL_COMPUTE_SHADER_INVOCATIONS_ARB: + case GL_CLIPPING_INPUT_PRIMITIVES_ARB: + case GL_CLIPPING_OUTPUT_PRIMITIVES_ARB: + type = PIPE_QUERY_PIPELINE_STATISTICS; + break; default: assert(0 && "unexpected query target in st_BeginQuery()"); return; @@ -178,6 +191,8 @@ get_query_result(struct pipe_context *pipe, struct st_query_object *stq, boolean wait) { + union pipe_query_result data; + if (!stq->pq) { /* Only needed in case we failed to allocate the gallium query earlier. * Return TRUE so we don't spin on this forever. @@ -185,11 +200,46 @@ get_query_result(struct pipe_context *pipe, return TRUE; } - if (!pipe->get_query_result(pipe, - stq->pq, - wait, - (void *)&stq->base.Result)) { + if (!pipe->get_query_result(pipe, stq->pq, wait, &data)) return FALSE; + + switch (stq->base.Target) { + case GL_VERTICES_SUBMITTED_ARB: + stq->base.Result = data.pipeline_statistics.ia_vertices; + break; + case GL_PRIMITIVES_SUBMITTED_ARB: + stq->base.Result = data.pipeline_statistics.ia_primitives; + break; + case GL_VERTEX_SHADER_INVOCATIONS_ARB: + stq->base.Result = data.pipeline_statistics.vs_invocations; + break; + case GL_TESS_CONTROL_SHADER_PATCHES_ARB: + stq->base.Result = data.pipeline_statistics.hs_invocations; + break; + case GL_TESS_EVALUATION_SHADER_INVOCATIONS_ARB: + stq->base.Result = data.pipeline_statistics.ds_invocations; + break; + case GL_GEOMETRY_SHADER_INVOCATIONS: + stq->base.Result = data.pipeline_statistics.gs_invocations; + break; + case GL_GEOMETRY_SHADER_PRIMITIVES_EMITTED_ARB: + stq->base.Result = data.pipeline_statistics.gs_primitives; + break; + case GL_FRAGMENT_SHADER_INVOCATIONS_ARB: + stq->base.Result = data.pipeline_statistics.ps_invocations; + break; + case GL_COMPUTE_SHADER_INVOCATIONS_ARB: + stq->base.Result = data.pipeline_statistics.cs_invocations; + break; + case GL_CLIPPING_INPUT_PRIMITIVES_ARB: + stq->base.Result = data.pipeline_statistics.c_invocations; + break; + case GL_CLIPPING_OUTPUT_PRIMITIVES_ARB: + stq->base.Result = data.pipeline_statistics.c_primitives; + break; + default: + stq->base.Result = data.u64; + break; } if (stq->base.Target == GL_TIME_ELAPSED && diff --git a/mesalib/src/mesa/state_tracker/st_cb_texture.c b/mesalib/src/mesa/state_tracker/st_cb_texture.c index a8dbb7888..0525e879f 100644 --- a/mesalib/src/mesa/state_tracker/st_cb_texture.c +++ b/mesalib/src/mesa/state_tracker/st_cb_texture.c @@ -29,6 +29,8 @@ #include "main/enums.h" #include "main/fbobject.h" #include "main/formats.h" +#include "main/format_utils.h" +#include "main/glformats.h" #include "main/image.h" #include "main/imports.h" #include "main/macros.h" @@ -209,7 +211,7 @@ st_MapTextureImage(struct gl_context *ctx, map = st_texture_image_map(st, stImage, pipeMode, x, y, slice, w, h, 1, &transfer); if (map) { - if (_mesa_is_format_etc2(texImage->TexFormat) || + if ((_mesa_is_format_etc2(texImage->TexFormat) && !st->has_etc2) || (texImage->TexFormat == MESA_FORMAT_ETC1_RGB8 && !st->has_etc1)) { /* ETC isn't supported by gallium and it's represented * by uncompressed formats. Only write transfers with precompressed @@ -252,7 +254,7 @@ st_UnmapTextureImage(struct gl_context *ctx, struct st_context *st = st_context(ctx); struct st_texture_image *stImage = st_texture_image(texImage); - if (_mesa_is_format_etc2(texImage->TexFormat) || + if ((_mesa_is_format_etc2(texImage->TexFormat) && !st->has_etc2) || (texImage->TexFormat == MESA_FORMAT_ETC1_RGB8 && !st->has_etc1)) { /* Decompress the ETC texture to the mapped one. */ unsigned z = slice + stImage->base.Face; @@ -899,7 +901,7 @@ st_CompressedTexImage(struct gl_context *ctx, GLuint dims, * We can do arbitrary X/Y/Z/W/0/1 swizzling here as long as there is * a format which matches the swizzling. * - * If such a format isn't available, it falls back to _mesa_get_teximage. + * If such a format isn't available, it falls back to _mesa_GetTexImage_sw. * * NOTE: Drivers usually do a blit to convert between tiled and linear * texture layouts during texture uploads/downloads, so the blit @@ -944,14 +946,14 @@ st_GetTexImage(struct gl_context * ctx, goto fallback; } - /* XXX Fallback to _mesa_get_teximage for depth-stencil formats + /* XXX Fallback to _mesa_GetTexImage_sw for depth-stencil formats * due to an incomplete stencil blit implementation in some drivers. */ if (format == GL_DEPTH_STENCIL) { goto fallback; } /* If the base internal format and the texture format don't match, we have - * to fall back to _mesa_get_teximage. */ + * to fall back to _mesa_GetTexImage_sw. */ if (texImage->_BaseFormat != _mesa_get_format_base_format(texImage->TexFormat)) { goto fallback; @@ -1005,7 +1007,7 @@ st_GetTexImage(struct gl_context * ctx, if (dst_format == PIPE_FORMAT_NONE) { GLenum dst_glformat; - /* Fall back to _mesa_get_teximage except for compressed formats, + /* Fall back to _mesa_GetTexImage_sw except for compressed formats, * where decompression with a blit is always preferred. */ if (!util_format_is_compressed(src->format)) { goto fallback; @@ -1138,6 +1140,8 @@ st_GetTexImage(struct gl_context * ctx, /* format translation via floats */ GLuint row, slice; GLfloat *rgba; + uint32_t dstMesaFormat; + int dstStride, srcStride; assert(util_format_is_compressed(src->format)); @@ -1149,6 +1153,9 @@ st_GetTexImage(struct gl_context * ctx, if (ST_DEBUG & DEBUG_FALLBACK) debug_printf("%s: fallback format translation\n", __FUNCTION__); + dstMesaFormat = _mesa_format_from_format_and_type(format, type); + dstStride = _mesa_image_row_stride(&ctx->Pack, width, format, type); + srcStride = 4 * width * sizeof(GLfloat); for (slice = 0; slice < depth; slice++) { if (gl_target == GL_TEXTURE_1D_ARRAY) { /* 1D array textures. @@ -1162,8 +1169,9 @@ st_GetTexImage(struct gl_context * ctx, pipe_get_tile_rgba_format(tex_xfer, map, 0, 0, width, 1, dst_format, rgba); - _mesa_pack_rgba_span_float(ctx, width, (GLfloat (*)[4]) rgba, format, - type, dest, &ctx->Pack, 0); + _mesa_format_convert(dest, dstMesaFormat, dstStride, + rgba, RGBA32_FLOAT, srcStride, + width, 1, NULL); } else { for (row = 0; row < height; row++) { @@ -1175,8 +1183,9 @@ st_GetTexImage(struct gl_context * ctx, pipe_get_tile_rgba_format(tex_xfer, map, 0, row, width, 1, dst_format, rgba); - _mesa_pack_rgba_span_float(ctx, width, (GLfloat (*)[4]) rgba, format, - type, dest, &ctx->Pack, 0); + _mesa_format_convert(dest, dstMesaFormat, dstStride, + rgba, RGBA32_FLOAT, srcStride, + width, 1, NULL); } } map += tex_xfer->layer_stride; @@ -1195,7 +1204,7 @@ end: fallback: if (!done) { - _mesa_get_teximage(ctx, format, type, pixels, texImage); + _mesa_GetTexImage_sw(ctx, format, type, pixels, texImage); } } @@ -1546,7 +1555,7 @@ st_finalize_texture(struct gl_context *ctx, struct st_texture_object *stObj = st_texture_object(tObj); const GLuint nr_faces = (stObj->base.Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1; GLuint face; - struct st_texture_image *firstImage; + const struct st_texture_image *firstImage; enum pipe_format firstImageFormat; GLuint ptWidth, ptHeight, ptDepth, ptLayers, ptNumSamples; @@ -1587,7 +1596,7 @@ st_finalize_texture(struct gl_context *ctx, } - firstImage = st_texture_image(stObj->base.Image[0][stObj->base.BaseLevel]); + firstImage = st_texture_image_const(_mesa_base_tex_image(&stObj->base)); assert(firstImage); /* If both firstImage and stObj point to a texture which can contain @@ -1886,7 +1895,7 @@ st_init_texture_functions(struct dd_function_table *functions) /* compressed texture functions */ functions->CompressedTexImage = st_CompressedTexImage; - functions->GetCompressedTexImage = _mesa_get_compressed_teximage; + functions->GetCompressedTexImage = _mesa_GetCompressedTexImage_sw; functions->NewTextureObject = st_NewTextureObject; functions->NewTextureImage = st_NewTextureImage; diff --git a/mesalib/src/mesa/state_tracker/st_cb_xformfb.c b/mesalib/src/mesa/state_tracker/st_cb_xformfb.c index 8f75eda8a..a2bd86aff 100644 --- a/mesalib/src/mesa/state_tracker/st_cb_xformfb.c +++ b/mesalib/src/mesa/state_tracker/st_cb_xformfb.c @@ -122,7 +122,7 @@ st_begin_transform_feedback(struct gl_context *ctx, GLenum mode, for (i = 0; i < max_num_targets; i++) { struct st_buffer_object *bo = st_buffer_object(sobj->base.Buffers[i]); - if (bo) { + if (bo && bo->buffer) { /* Check whether we need to recreate the target. */ if (!sobj->targets[i] || sobj->targets[i] == sobj->draw_count || diff --git a/mesalib/src/mesa/state_tracker/st_context.c b/mesalib/src/mesa/state_tracker/st_context.c index 17235132e..5834ebad3 100644 --- a/mesalib/src/mesa/state_tracker/st_context.c +++ b/mesalib/src/mesa/state_tracker/st_context.c @@ -136,6 +136,8 @@ st_destroy_context_priv(struct st_context *st) if (st->constbuf_uploader) { u_upload_destroy(st->constbuf_uploader); } + + cso_destroy_context(st->cso_context); free( st ); } @@ -228,6 +230,9 @@ st_create_context_priv( struct gl_context *ctx, struct pipe_context *pipe, st->has_etc1 = screen->is_format_supported(screen, PIPE_FORMAT_ETC1_RGB8, PIPE_TEXTURE_2D, 0, PIPE_BIND_SAMPLER_VIEW); + st->has_etc2 = screen->is_format_supported(screen, PIPE_FORMAT_ETC2_RGB8, + PIPE_TEXTURE_2D, 0, + PIPE_BIND_SAMPLER_VIEW); st->prefer_blit_based_texture_transfer = screen->get_param(screen, PIPE_CAP_PREFER_BLIT_BASED_TEXTURE_TRANSFER); @@ -271,6 +276,8 @@ st_create_context_priv( struct gl_context *ctx, struct pipe_context *pipe, */ st->ctx->Point.MaxSize = MAX2(ctx->Const.MaxPointSize, ctx->Const.MaxPointSizeAA); + /* For vertex shaders, make sure not to emit saturate when SM 3.0 is not supported */ + ctx->Const.ShaderCompilerOptions[MESA_SHADER_VERTEX].EmitNoSat = !st->has_shader_model3; _mesa_compute_version(ctx); @@ -346,15 +353,11 @@ destroy_tex_sampler_cb(GLuint id, void *data, void *userData) void st_destroy_context( struct st_context *st ) { struct pipe_context *pipe = st->pipe; - struct cso_context *cso = st->cso_context; struct gl_context *ctx = st->ctx; GLuint i; _mesa_HashWalk(ctx->Shared->TexObjects, destroy_tex_sampler_cb, st); - /* need to unbind and destroy CSO objects before anything else */ - cso_release_all(st->cso_context); - st_reference_fragprog(st, &st->fp, NULL); st_reference_geomprog(st, &st->gp, NULL); st_reference_vertprog(st, &st->vp, NULL); @@ -384,8 +387,6 @@ void st_destroy_context( struct st_context *st ) st_destroy_context_priv(st); st = NULL; - cso_destroy_context(cso); - pipe->destroy( pipe ); free(ctx); diff --git a/mesalib/src/mesa/state_tracker/st_context.h b/mesalib/src/mesa/state_tracker/st_context.h index 15f9df492..b091a8856 100644 --- a/mesalib/src/mesa/state_tracker/st_context.h +++ b/mesalib/src/mesa/state_tracker/st_context.h @@ -33,6 +33,12 @@ #include "state_tracker/st_api.h" #include "main/fbobject.h" + +#ifdef __cplusplus +extern "C" { +#endif + + struct bitmap_cache; struct dd_function_table; struct draw_context; @@ -87,6 +93,7 @@ struct st_context boolean has_time_elapsed; boolean has_shader_model3; boolean has_etc1; + boolean has_etc2; boolean prefer_blit_based_texture_transfer; boolean needs_texcoord_semantic; @@ -278,4 +285,8 @@ extern void st_destroy_context(struct st_context *st); +#ifdef __cplusplus +} +#endif + #endif diff --git a/mesalib/src/mesa/state_tracker/st_draw.c b/mesalib/src/mesa/state_tracker/st_draw.c index 64d6ef525..488f6ead2 100644 --- a/mesalib/src/mesa/state_tracker/st_draw.c +++ b/mesalib/src/mesa/state_tracker/st_draw.c @@ -40,6 +40,7 @@ #include "main/image.h" #include "main/bufferobj.h" #include "main/macros.h" +#include "main/varray.h" #include "vbo/vbo.h" @@ -225,7 +226,7 @@ st_draw_vbo(struct gl_context *ctx, } info.indexed = TRUE; - if (min_index != ~0 && max_index != ~0) { + if (min_index != ~0U && max_index != ~0U) { info.min_index = min_index; info.max_index = max_index; } @@ -234,7 +235,7 @@ st_draw_vbo(struct gl_context *ctx, * so we only set these fields for indexed drawing: */ info.primitive_restart = ctx->Array._PrimitiveRestart; - info.restart_index = ctx->Array.RestartIndex; + info.restart_index = _mesa_primitive_restart_index(ctx, ib->type); } else { /* Transform feedback drawing is always non-indexed. */ diff --git a/mesalib/src/mesa/state_tracker/st_extensions.c b/mesalib/src/mesa/state_tracker/st_extensions.c index bdfab8b41..ce29d076c 100644 --- a/mesalib/src/mesa/state_tracker/st_extensions.c +++ b/mesalib/src/mesa/state_tracker/st_extensions.c @@ -411,7 +411,8 @@ void st_init_extensions(struct pipe_screen *screen, struct st_config_options *options, boolean has_lib_dxtc) { - int i, glsl_feature_level; + unsigned i; + int glsl_feature_level; GLboolean *extension_table = (GLboolean *) extensions; static const struct st_extension_cap_mapping cap_mapping[] = { @@ -425,6 +426,7 @@ void st_init_extensions(struct pipe_screen *screen, { o(ARB_instanced_arrays), PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR }, { o(ARB_occlusion_query), PIPE_CAP_OCCLUSION_QUERY }, { o(ARB_occlusion_query2), PIPE_CAP_OCCLUSION_QUERY }, + { o(ARB_pipeline_statistics_query), PIPE_CAP_QUERY_PIPELINE_STATISTICS }, { o(ARB_point_sprite), PIPE_CAP_POINT_SPRITE }, { o(ARB_seamless_cube_map), PIPE_CAP_SEAMLESS_CUBE_MAP }, { o(ARB_shader_stencil_export), PIPE_CAP_SHADER_STENCIL_EXPORT }, @@ -445,6 +447,7 @@ void st_init_extensions(struct pipe_screen *screen, { o(EXT_texture_swizzle), PIPE_CAP_TEXTURE_SWIZZLE }, { o(EXT_transform_feedback), PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS }, + { o(AMD_pinned_memory), PIPE_CAP_RESOURCE_FROM_USER_MEMORY }, { o(AMD_seamless_cubemap_per_texture), PIPE_CAP_SEAMLESS_CUBE_MAP_PER_TEXTURE }, { o(ATI_separate_stencil), PIPE_CAP_TWO_SIDED_STENCIL }, { o(ATI_texture_mirror_once), PIPE_CAP_TEXTURE_MIRROR_CLAMP }, @@ -463,6 +466,7 @@ void st_init_extensions(struct pipe_screen *screen, { o(ARB_conditional_render_inverted), PIPE_CAP_CONDITIONAL_RENDER_INVERTED }, { o(ARB_texture_view), PIPE_CAP_SAMPLER_VIEW_TARGET }, { o(ARB_clip_control), PIPE_CAP_CLIP_HALFZ }, + { o(EXT_polygon_offset_clamp), PIPE_CAP_POLYGON_OFFSET_CLAMP }, }; /* Required: render target and sampler support */ @@ -674,6 +678,10 @@ void st_init_extensions(struct pipe_screen *screen, consts->NativeIntegers = GL_TRUE; consts->MaxClipPlanes = 8; + if (screen->get_param(screen, PIPE_CAP_VERTEXID_NOBASE)) { + consts->VertexID_is_zero_based = GL_TRUE; + } + /* Extensions that either depend on GLSL 1.30 or are a subset thereof. */ extensions->ARB_conservative_depth = GL_TRUE; extensions->ARB_shading_language_packing = GL_TRUE; @@ -696,9 +704,12 @@ void st_init_extensions(struct pipe_screen *screen, extensions->EXT_shader_integer_mix = GL_TRUE; } + + /* Integer textures make no sense before GLSL 1.30 */ + extensions->EXT_texture_integer = GL_FALSE; } - consts->UniformBooleanTrue = consts->NativeIntegers ? ~0 : fui(1.0f); + consts->UniformBooleanTrue = consts->NativeIntegers ? ~0U : fui(1.0f); /* Below are the cases which cannot be moved into tables easily. */ @@ -889,4 +900,10 @@ void st_init_extensions(struct pipe_screen *screen, PIPE_VIDEO_CAP_SUPPORTS_INTERLACED)) { extensions->NV_vdpau_interop = GL_TRUE; } + + if (screen->get_shader_param(screen, PIPE_SHADER_VERTEX, + PIPE_SHADER_CAP_DOUBLES) && + screen->get_shader_param(screen, PIPE_SHADER_FRAGMENT, + PIPE_SHADER_CAP_DOUBLES)) + extensions->ARB_gpu_shader_fp64 = GL_TRUE; } diff --git a/mesalib/src/mesa/state_tracker/st_format.c b/mesalib/src/mesa/state_tracker/st_format.c index 6c53567fc..7868bb501 100644 --- a/mesalib/src/mesa/state_tracker/st_format.c +++ b/mesalib/src/mesa/state_tracker/st_format.c @@ -443,21 +443,25 @@ st_mesa_format_to_pipe_format(struct st_context *st, mesa_format mesaFormat) * The destination formats mustn't be changed, because they are also * destination formats of the unpack/decompression function. */ case MESA_FORMAT_ETC2_RGB8: - case MESA_FORMAT_ETC2_RGBA8_EAC: - case MESA_FORMAT_ETC2_RGB8_PUNCHTHROUGH_ALPHA1: - return PIPE_FORMAT_R8G8B8A8_UNORM; + return st->has_etc2 ? PIPE_FORMAT_ETC2_RGB8 : PIPE_FORMAT_R8G8B8A8_UNORM; case MESA_FORMAT_ETC2_SRGB8: + return st->has_etc2 ? PIPE_FORMAT_ETC2_SRGB8 : PIPE_FORMAT_B8G8R8A8_SRGB; + case MESA_FORMAT_ETC2_RGBA8_EAC: + return st->has_etc2 ? PIPE_FORMAT_ETC2_RGBA8 : PIPE_FORMAT_R8G8B8A8_UNORM; case MESA_FORMAT_ETC2_SRGB8_ALPHA8_EAC: - case MESA_FORMAT_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1: - return PIPE_FORMAT_B8G8R8A8_SRGB; + return st->has_etc2 ? PIPE_FORMAT_ETC2_SRGBA8 : PIPE_FORMAT_B8G8R8A8_SRGB; case MESA_FORMAT_ETC2_R11_EAC: - return PIPE_FORMAT_R16_UNORM; + return st->has_etc2 ? PIPE_FORMAT_ETC2_R11_UNORM : PIPE_FORMAT_R16_UNORM; case MESA_FORMAT_ETC2_RG11_EAC: - return PIPE_FORMAT_R16G16_UNORM; + return st->has_etc2 ? PIPE_FORMAT_ETC2_RG11_UNORM : PIPE_FORMAT_R16G16_UNORM; case MESA_FORMAT_ETC2_SIGNED_R11_EAC: - return PIPE_FORMAT_R16_SNORM; + return st->has_etc2 ? PIPE_FORMAT_ETC2_R11_SNORM : PIPE_FORMAT_R16_SNORM; case MESA_FORMAT_ETC2_SIGNED_RG11_EAC: - return PIPE_FORMAT_R16G16_SNORM; + return st->has_etc2 ? PIPE_FORMAT_ETC2_RG11_SNORM : PIPE_FORMAT_R16G16_SNORM; + case MESA_FORMAT_ETC2_RGB8_PUNCHTHROUGH_ALPHA1: + return st->has_etc2 ? PIPE_FORMAT_ETC2_RGB8A1 : PIPE_FORMAT_R8G8B8A8_UNORM; + case MESA_FORMAT_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1: + return st->has_etc2 ? PIPE_FORMAT_ETC2_SRGB8A1 : PIPE_FORMAT_B8G8R8A8_SRGB; default: return PIPE_FORMAT_NONE; @@ -856,6 +860,27 @@ st_pipe_format_to_mesa_format(enum pipe_format format) case PIPE_FORMAT_XRGB8888_SRGB: return MESA_FORMAT_X8R8G8B8_SRGB; + case PIPE_FORMAT_ETC2_RGB8: + return MESA_FORMAT_ETC2_RGB8; + case PIPE_FORMAT_ETC2_SRGB8: + return MESA_FORMAT_ETC2_SRGB8; + case PIPE_FORMAT_ETC2_RGB8A1: + return MESA_FORMAT_ETC2_RGB8_PUNCHTHROUGH_ALPHA1; + case PIPE_FORMAT_ETC2_SRGB8A1: + return MESA_FORMAT_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1; + case PIPE_FORMAT_ETC2_RGBA8: + return MESA_FORMAT_ETC2_RGBA8_EAC; + case PIPE_FORMAT_ETC2_SRGBA8: + return MESA_FORMAT_ETC2_SRGB8_ALPHA8_EAC; + case PIPE_FORMAT_ETC2_R11_UNORM: + return MESA_FORMAT_ETC2_R11_EAC; + case PIPE_FORMAT_ETC2_R11_SNORM: + return MESA_FORMAT_ETC2_SIGNED_R11_EAC; + case PIPE_FORMAT_ETC2_RG11_UNORM: + return MESA_FORMAT_ETC2_RG11_EAC; + case PIPE_FORMAT_ETC2_RG11_SNORM: + return MESA_FORMAT_ETC2_SIGNED_RG11_EAC; + default: return MESA_FORMAT_NONE; } @@ -896,6 +921,9 @@ test_format_conversion(struct st_context *st) if (i == PIPE_FORMAT_ETC1_RGB8 && !st->has_etc1) continue; + if (_mesa_is_format_etc2(mf) && !st->has_etc2) + continue; + if (mf != MESA_FORMAT_NONE) { enum pipe_format pf = st_mesa_format_to_pipe_format(st, mf); assert(pf == i); @@ -1797,7 +1825,8 @@ st_choose_format(struct st_context *st, GLenum internalFormat, unsigned bindings, boolean allow_dxt) { struct pipe_screen *screen = st->pipe->screen; - int i, j; + unsigned i; + int j; enum pipe_format pf; #ifdef DEBUG diff --git a/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp b/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp index 8e91c4b61..0b3477161 100644 --- a/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp +++ b/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp @@ -44,10 +44,8 @@ #include "main/mtypes.h" #include "main/shaderobj.h" #include "main/uniforms.h" -#include "program/hash_table.h" - -extern "C" { #include "main/shaderapi.h" +#include "program/hash_table.h" #include "program/prog_instruction.h" #include "program/prog_optimize.h" #include "program/prog_print.h" @@ -67,7 +65,7 @@ extern "C" { #include "st_program.h" #include "st_glsl_to_tgsi.h" #include "st_mesa_to_tgsi.h" -} + #define PROGRAM_IMMEDIATE PROGRAM_FILE_MAX #define PROGRAM_ANY_CONST ((1 << PROGRAM_STATE_VAR) | \ @@ -231,7 +229,7 @@ public: DECLARE_RALLOC_CXX_OPERATORS(glsl_to_tgsi_instruction) unsigned op; - st_dst_reg dst; + st_dst_reg dst[2]; st_src_reg src[4]; /** Pointer to the ir source this tree came from for debugging */ ir_instruction *ir; @@ -264,16 +262,17 @@ public: class immediate_storage : public exec_node { public: - immediate_storage(gl_constant_value *values, int size, int type) + immediate_storage(gl_constant_value *values, int size32, int type) { - memcpy(this->values, values, size * sizeof(gl_constant_value)); - this->size = size; + memcpy(this->values, values, size32 * sizeof(gl_constant_value)); + this->size32 = size32; this->type = type; } - + + /* doubles are stored across 2 gl_constant_values */ gl_constant_value values[4]; - int size; /**< Number of components (1-4) */ - int type; /**< GL_FLOAT, GL_INT, GL_BOOL, or GL_UNSIGNED_INT */ + int size32; /**< Number of 32-bit components (1-4) */ + int type; /**< GL_DOUBLE, GL_FLOAT, GL_INT, GL_BOOL, or GL_UNSIGNED_INT */ }; class function_entry : public exec_node { @@ -329,14 +328,14 @@ public: int num_address_regs; int samplers_used; bool indirect_addr_consts; - + int glsl_version; bool native_integers; bool have_sqrt; variable_storage *find_variable_storage(ir_variable *var); - int add_constant(gl_register_file file, gl_constant_value values[4], + int add_constant(gl_register_file file, gl_constant_value values[8], int size, int datatype, GLuint *swizzle_out); function_entry *get_function_signature(ir_function_signature *sig); @@ -344,6 +343,7 @@ public: st_src_reg get_temp(const glsl_type *type); void reladdr_to_temp(ir_instruction *ir, st_src_reg *reg, int *num_reladdr); + st_src_reg st_src_reg_for_double(double val); st_src_reg st_src_reg_for_float(float val); st_src_reg st_src_reg_for_int(int val); st_src_reg st_src_reg_for_type(int type, int val); @@ -396,17 +396,26 @@ public: glsl_to_tgsi_instruction *emit(ir_instruction *ir, unsigned op); glsl_to_tgsi_instruction *emit(ir_instruction *ir, unsigned op, - st_dst_reg dst, st_src_reg src0); + st_dst_reg dst, st_src_reg src0); glsl_to_tgsi_instruction *emit(ir_instruction *ir, unsigned op, - st_dst_reg dst, st_src_reg src0, st_src_reg src1); + st_dst_reg dst, st_dst_reg dst1, + st_src_reg src0); glsl_to_tgsi_instruction *emit(ir_instruction *ir, unsigned op, - st_dst_reg dst, - st_src_reg src0, st_src_reg src1, st_src_reg src2); + st_dst_reg dst, st_src_reg src0, st_src_reg src1); glsl_to_tgsi_instruction *emit(ir_instruction *ir, unsigned op, st_dst_reg dst, + st_src_reg src0, st_src_reg src1, st_src_reg src2); + + glsl_to_tgsi_instruction *emit(ir_instruction *ir, unsigned op, + st_dst_reg dst, + st_src_reg src0, st_src_reg src1, + st_src_reg src2, st_src_reg src3); + + glsl_to_tgsi_instruction *emit(ir_instruction *ir, unsigned op, + st_dst_reg dst, st_dst_reg dst1, st_src_reg src0, st_src_reg src1, st_src_reg src2, st_src_reg src3); @@ -424,15 +433,15 @@ public: unsigned elements); void emit_scalar(ir_instruction *ir, unsigned op, - st_dst_reg dst, st_src_reg src0); + st_dst_reg dst, st_src_reg src0); void emit_scalar(ir_instruction *ir, unsigned op, - st_dst_reg dst, st_src_reg src0, st_src_reg src1); + st_dst_reg dst, st_src_reg src0, st_src_reg src1); void emit_arl(ir_instruction *ir, st_dst_reg dst, st_src_reg src0); void emit_scs(ir_instruction *ir, unsigned op, - st_dst_reg dst, const st_src_reg &src); + st_dst_reg dst, const st_src_reg &src); bool try_emit_mad(ir_expression *ir, int mul_operand); @@ -453,11 +462,14 @@ public: void copy_propagate(void); int eliminate_dead_code(void); + + void merge_two_dsts(void); void merge_registers(void); void renumber_registers(void); void emit_block_mov(ir_assignment *ir, const struct glsl_type *type, - st_dst_reg *l, st_src_reg *r); + st_dst_reg *l, st_src_reg *r, + st_src_reg *cond, bool cond_swap); void *mem_ctx; }; @@ -487,7 +499,7 @@ fail_link(struct gl_shader_program *prog, const char *fmt, ...) static int swizzle_for_size(int size) { - int size_swizzles[4] = { + static const int size_swizzles[4] = { MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_X), MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Y, SWIZZLE_Y), MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_Z), @@ -521,13 +533,13 @@ num_inst_src_regs(unsigned opcode) glsl_to_tgsi_instruction * glsl_to_tgsi_visitor::emit(ir_instruction *ir, unsigned op, - st_dst_reg dst, + st_dst_reg dst, st_dst_reg dst1, st_src_reg src0, st_src_reg src1, st_src_reg src2, st_src_reg src3) { glsl_to_tgsi_instruction *inst = new(mem_ctx) glsl_to_tgsi_instruction(); - int num_reladdr = 0, i; - + int num_reladdr = 0, i, j; + op = get_opcode(ir, op, dst, src0, src1); /* If we have to do relative addressing, we want to load the ARL @@ -535,6 +547,7 @@ glsl_to_tgsi_visitor::emit(ir_instruction *ir, unsigned op, * sources into temps. */ num_reladdr += dst.reladdr != NULL; + num_reladdr += dst1.reladdr != NULL; num_reladdr += src0.reladdr != NULL || src0.reladdr2 != NULL; num_reladdr += src1.reladdr != NULL || src1.reladdr2 != NULL; num_reladdr += src2.reladdr != NULL || src2.reladdr2 != NULL; @@ -549,10 +562,15 @@ glsl_to_tgsi_visitor::emit(ir_instruction *ir, unsigned op, emit_arl(ir, address_reg, *dst.reladdr); num_reladdr--; } + if (dst1.reladdr) { + emit_arl(ir, address_reg, *dst1.reladdr); + num_reladdr--; + } assert(num_reladdr == 0); inst->op = op; - inst->dst = dst; + inst->dst[0] = dst; + inst->dst[1] = dst1; inst->src[0] = src0; inst->src[1] = src1; inst->src[2] = src2; @@ -561,7 +579,7 @@ glsl_to_tgsi_visitor::emit(ir_instruction *ir, unsigned op, inst->dead_mask = 0; inst->function = NULL; - + /* Update indirect addressing status used by TGSI */ if (dst.reladdr) { switch(dst.file) { @@ -578,7 +596,7 @@ glsl_to_tgsi_visitor::emit(ir_instruction *ir, unsigned op, } } else { - for (i=0; i<4; i++) { + for (i = 0; i < 4; i++) { if(inst->src[i].reladdr) { switch(inst->src[i].file) { case PROGRAM_STATE_VAR: @@ -598,46 +616,162 @@ glsl_to_tgsi_visitor::emit(ir_instruction *ir, unsigned op, this->instructions.push_tail(inst); + /* + * This section contains the double processing. + * GLSL just represents doubles as single channel values, + * however most HW and TGSI represent doubles as pairs of register channels. + * + * so we have to fixup destination writemask/index and src swizzle/indexes. + * dest writemasks need to translate from single channel write mask + * to a dual-channel writemask, but also need to modify the index, + * if we are touching the Z,W fields in the pre-translated writemask. + * + * src channels have similiar index modifications along with swizzle + * changes to we pick the XY, ZW pairs from the correct index. + * + * GLSL [0].x -> TGSI [0].xy + * GLSL [0].y -> TGSI [0].zw + * GLSL [0].z -> TGSI [1].xy + * GLSL [0].w -> TGSI [1].zw + */ + if (inst->dst[0].type == GLSL_TYPE_DOUBLE || inst->dst[1].type == GLSL_TYPE_DOUBLE || + inst->src[0].type == GLSL_TYPE_DOUBLE) { + glsl_to_tgsi_instruction *dinst = NULL; + int initial_src_swz[4], initial_src_idx[4]; + int initial_dst_idx[2], initial_dst_writemask[2]; + /* select the writemask for dst0 or dst1 */ + unsigned writemask = inst->dst[0].file == PROGRAM_UNDEFINED ? inst->dst[1].writemask : inst->dst[0].writemask; + + /* copy out the writemask, index and swizzles for all src/dsts. */ + for (j = 0; j < 2; j++) { + initial_dst_writemask[j] = inst->dst[j].writemask; + initial_dst_idx[j] = inst->dst[j].index; + } + + for (j = 0; j < 4; j++) { + initial_src_swz[j] = inst->src[j].swizzle; + initial_src_idx[j] = inst->src[j].index; + } + + /* + * scan all the components in the dst writemask + * generate an instruction for each of them if required. + */ + while (writemask) { + + int i = u_bit_scan(&writemask); + + /* first time use previous instruction */ + if (dinst == NULL) { + dinst = inst; + } else { + /* create a new instructions for subsequent attempts */ + dinst = new(mem_ctx) glsl_to_tgsi_instruction(); + *dinst = *inst; + dinst->next = NULL; + dinst->prev = NULL; + this->instructions.push_tail(dinst); + } + + /* modify the destination if we are splitting */ + for (j = 0; j < 2; j++) { + if (dinst->dst[j].type == GLSL_TYPE_DOUBLE) { + dinst->dst[j].writemask = (i & 1) ? WRITEMASK_ZW : WRITEMASK_XY; + dinst->dst[j].index = initial_dst_idx[j]; + if (i > 1) + dinst->dst[j].index++; + } else { + /* if we aren't writing to a double, just get the bit of the initial writemask + for this channel */ + dinst->dst[j].writemask = initial_dst_writemask[j] & (1 << i); + } + } + + /* modify the src registers */ + for (j = 0; j < 4; j++) { + int swz = GET_SWZ(initial_src_swz[j], i); + + if (dinst->src[j].type == GLSL_TYPE_DOUBLE) { + dinst->src[j].index = initial_src_idx[j]; + if (swz > 1) + dinst->src[j].index++; + + if (swz & 1) + dinst->src[j].swizzle = MAKE_SWIZZLE4(SWIZZLE_Z, SWIZZLE_W, SWIZZLE_Z, SWIZZLE_W); + else + dinst->src[j].swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_X, SWIZZLE_Y); + + } else { + /* some opcodes are special case in what they use as sources + - F2D is a float src0, DLDEXP is integer src1 */ + if (op == TGSI_OPCODE_F2D || + op == TGSI_OPCODE_DLDEXP || + (op == TGSI_OPCODE_UCMP && dinst->dst[0].type == GLSL_TYPE_DOUBLE)) { + dinst->src[j].swizzle = MAKE_SWIZZLE4(swz, swz, swz, swz); + } + } + } + } + inst = dinst; + } + + return inst; } +glsl_to_tgsi_instruction * +glsl_to_tgsi_visitor::emit(ir_instruction *ir, unsigned op, + st_dst_reg dst, + st_src_reg src0, st_src_reg src1, + st_src_reg src2, st_src_reg src3) +{ + return emit(ir, op, dst, undef_dst, src0, src1, src2, src3); +} + glsl_to_tgsi_instruction * glsl_to_tgsi_visitor::emit(ir_instruction *ir, unsigned op, st_dst_reg dst, st_src_reg src0, st_src_reg src1, st_src_reg src2) { - return emit(ir, op, dst, src0, src1, src2, undef_src); + return emit(ir, op, dst, undef_dst, src0, src1, src2, undef_src); } glsl_to_tgsi_instruction * glsl_to_tgsi_visitor::emit(ir_instruction *ir, unsigned op, - st_dst_reg dst, st_src_reg src0, st_src_reg src1) + st_dst_reg dst, st_src_reg src0, st_src_reg src1) { - return emit(ir, op, dst, src0, src1, undef_src, undef_src); + return emit(ir, op, dst, undef_dst, src0, src1, undef_src, undef_src); } glsl_to_tgsi_instruction * glsl_to_tgsi_visitor::emit(ir_instruction *ir, unsigned op, - st_dst_reg dst, st_src_reg src0) + st_dst_reg dst, st_src_reg src0) { assert(dst.writemask != 0); - return emit(ir, op, dst, src0, undef_src, undef_src, undef_src); + return emit(ir, op, dst, undef_dst, src0, undef_src, undef_src, undef_src); +} + +glsl_to_tgsi_instruction * +glsl_to_tgsi_visitor::emit(ir_instruction *ir, unsigned op, + st_dst_reg dst, st_dst_reg dst1, st_src_reg src0) +{ + return emit(ir, op, dst, dst1, src0, undef_src, undef_src, undef_src); } glsl_to_tgsi_instruction * glsl_to_tgsi_visitor::emit(ir_instruction *ir, unsigned op) { - return emit(ir, op, undef_dst, undef_src, undef_src, undef_src, undef_src); + return emit(ir, op, undef_dst, undef_dst, undef_src, undef_src, undef_src, undef_src); } /** - * Determines whether to use an integer, unsigned integer, or float opcode + * Determines whether to use an integer, unsigned integer, or float opcode * based on the operands and input opcode, then emits the result. */ unsigned glsl_to_tgsi_visitor::get_opcode(ir_instruction *ir, unsigned op, - st_dst_reg dst, - st_src_reg src0, st_src_reg src1) + st_dst_reg dst, + st_src_reg src0, st_src_reg src1) { int type = GLSL_TYPE_FLOAT; @@ -649,12 +783,26 @@ glsl_to_tgsi_visitor::get_opcode(ir_instruction *ir, unsigned op, assert(src1.type != GLSL_TYPE_ARRAY); assert(src1.type != GLSL_TYPE_STRUCT); - if (src0.type == GLSL_TYPE_FLOAT || src1.type == GLSL_TYPE_FLOAT) + if (src0.type == GLSL_TYPE_DOUBLE || src1.type == GLSL_TYPE_DOUBLE) + type = GLSL_TYPE_DOUBLE; + else if (src0.type == GLSL_TYPE_FLOAT || src1.type == GLSL_TYPE_FLOAT) type = GLSL_TYPE_FLOAT; else if (native_integers) type = src0.type == GLSL_TYPE_BOOL ? GLSL_TYPE_INT : src0.type; -#define case4(c, f, i, u) \ +#define case5(c, f, i, u, d) \ + case TGSI_OPCODE_##c: \ + if (type == GLSL_TYPE_DOUBLE) \ + op = TGSI_OPCODE_##d; \ + else if (type == GLSL_TYPE_INT) \ + op = TGSI_OPCODE_##i; \ + else if (type == GLSL_TYPE_UINT) \ + op = TGSI_OPCODE_##u; \ + else \ + op = TGSI_OPCODE_##f; \ + break; + +#define case4(c, f, i, u) \ case TGSI_OPCODE_##c: \ if (type == GLSL_TYPE_INT) \ op = TGSI_OPCODE_##i; \ @@ -665,12 +813,16 @@ glsl_to_tgsi_visitor::get_opcode(ir_instruction *ir, unsigned op, break; #define case3(f, i, u) case4(f, f, i, u) +#define case4d(f, i, u, d) case5(f, f, i, u, d) +#define case3fid(f, i, d) case5(f, f, i, i, d) #define case2fi(f, i) case4(f, f, i, i) #define case2iu(i, u) case4(i, LAST, i, u) -#define casecomp(c, f, i, u) \ +#define casecomp(c, f, i, u, d) \ case TGSI_OPCODE_##c: \ - if (type == GLSL_TYPE_INT) \ + if (type == GLSL_TYPE_DOUBLE) \ + op = TGSI_OPCODE_##d; \ + else if (type == GLSL_TYPE_INT) \ op = TGSI_OPCODE_##i; \ else if (type == GLSL_TYPE_UINT) \ op = TGSI_OPCODE_##u; \ @@ -681,38 +833,50 @@ glsl_to_tgsi_visitor::get_opcode(ir_instruction *ir, unsigned op, break; switch(op) { - case2fi(ADD, UADD); - case2fi(MUL, UMUL); - case2fi(MAD, UMAD); + case3fid(ADD, UADD, DADD); + case3fid(MUL, UMUL, DMUL); + case3fid(MAD, UMAD, DMAD); case3(DIV, IDIV, UDIV); - case3(MAX, IMAX, UMAX); - case3(MIN, IMIN, UMIN); + case4d(MAX, IMAX, UMAX, DMAX); + case4d(MIN, IMIN, UMIN, DMIN); case2iu(MOD, UMOD); - casecomp(SEQ, FSEQ, USEQ, USEQ); - casecomp(SNE, FSNE, USNE, USNE); - casecomp(SGE, FSGE, ISGE, USGE); - casecomp(SLT, FSLT, ISLT, USLT); + casecomp(SEQ, FSEQ, USEQ, USEQ, DSEQ); + casecomp(SNE, FSNE, USNE, USNE, DSNE); + casecomp(SGE, FSGE, ISGE, USGE, DSGE); + casecomp(SLT, FSLT, ISLT, USLT, DSLT); case2iu(ISHR, USHR); - case2fi(SSG, ISSG); - case3(ABS, IABS, IABS); + case3fid(SSG, ISSG, DSSG); + case3fid(ABS, IABS, DABS); case2iu(IBFE, UBFE); case2iu(IMSB, UMSB); case2iu(IMUL_HI, UMUL_HI); + + case3fid(SQRT, SQRT, DSQRT); + + case3fid(RCP, RCP, DRCP); + case3fid(RSQ, RSQ, DRSQ); + + case3fid(FRC, FRC, DFRAC); + case3fid(TRUNC, TRUNC, DTRUNC); + case3fid(CEIL, CEIL, DCEIL); + case3fid(FLR, FLR, DFLR); + case3fid(ROUND, ROUND, DROUND); + default: break; } - + assert(op != TGSI_OPCODE_LAST); return op; } glsl_to_tgsi_instruction * glsl_to_tgsi_visitor::emit_dp(ir_instruction *ir, - st_dst_reg dst, st_src_reg src0, st_src_reg src1, - unsigned elements) + st_dst_reg dst, st_src_reg src0, st_src_reg src1, + unsigned elements) { static const unsigned dot_opcodes[] = { TGSI_OPCODE_DP2, TGSI_OPCODE_DP3, TGSI_OPCODE_DP4 @@ -731,8 +895,8 @@ glsl_to_tgsi_visitor::emit_dp(ir_instruction *ir, */ void glsl_to_tgsi_visitor::emit_scalar(ir_instruction *ir, unsigned op, - st_dst_reg dst, - st_src_reg orig_src0, st_src_reg orig_src1) + st_dst_reg dst, + st_src_reg orig_src0, st_src_reg orig_src1) { int i, j; int done_mask = ~dst.writemask; @@ -743,7 +907,6 @@ glsl_to_tgsi_visitor::emit_scalar(ir_instruction *ir, unsigned op, */ for (i = 0; i < 4; i++) { GLuint this_mask = (1 << i); - glsl_to_tgsi_instruction *inst; st_src_reg src0 = orig_src0; st_src_reg src1 = orig_src1; @@ -764,19 +927,19 @@ glsl_to_tgsi_visitor::emit_scalar(ir_instruction *ir, unsigned op, } } src0.swizzle = MAKE_SWIZZLE4(src0_swiz, src0_swiz, - src0_swiz, src0_swiz); + src0_swiz, src0_swiz); src1.swizzle = MAKE_SWIZZLE4(src1_swiz, src1_swiz, - src1_swiz, src1_swiz); + src1_swiz, src1_swiz); - inst = emit(ir, op, dst, src0, src1); - inst->dst.writemask = this_mask; + dst.writemask = this_mask; + emit(ir, op, dst, src0, src1); done_mask |= this_mask; } } void glsl_to_tgsi_visitor::emit_scalar(ir_instruction *ir, unsigned op, - st_dst_reg dst, st_src_reg src0) + st_dst_reg dst, st_src_reg src0) { st_src_reg undef = undef_src; @@ -787,7 +950,7 @@ glsl_to_tgsi_visitor::emit_scalar(ir_instruction *ir, unsigned op, void glsl_to_tgsi_visitor::emit_arl(ir_instruction *ir, - st_dst_reg dst, st_src_reg src0) + st_dst_reg dst, st_src_reg src0) { int op = TGSI_OPCODE_ARL; @@ -805,20 +968,20 @@ glsl_to_tgsi_visitor::emit_arl(ir_instruction *ir, * Emit an TGSI_OPCODE_SCS instruction * * The \c SCS opcode functions a bit differently than the other TGSI opcodes. - * Instead of splatting its result across all four components of the - * destination, it writes one value to the \c x component and another value to + * Instead of splatting its result across all four components of the + * destination, it writes one value to the \c x component and another value to * the \c y component. * * \param ir IR instruction being processed - * \param op Either \c TGSI_OPCODE_SIN or \c TGSI_OPCODE_COS depending + * \param op Either \c TGSI_OPCODE_SIN or \c TGSI_OPCODE_COS depending * on which value is desired. * \param dst Destination register * \param src Source register */ void glsl_to_tgsi_visitor::emit_scs(ir_instruction *ir, unsigned op, - st_dst_reg dst, - const st_src_reg &src) + st_dst_reg dst, + const st_src_reg &src) { /* Vertex programs cannot use the SCS opcode. */ @@ -857,7 +1020,7 @@ glsl_to_tgsi_visitor::emit_scs(ir_instruction *ir, unsigned op, unsigned src0_swiz = GET_SWZ(src.swizzle, i); src0.swizzle = MAKE_SWIZZLE4(src0_swiz, src0_swiz, - src0_swiz, src0_swiz); + src0_swiz, src0_swiz); for (unsigned j = i + 1; j < 4; j++) { /* If there is another enabled component in the destination that is * derived from the same inputs, generate its value on this pass as @@ -876,20 +1039,20 @@ glsl_to_tgsi_visitor::emit_scs(ir_instruction *ir, unsigned op, /* Emit the SCS instruction. */ inst = emit(ir, TGSI_OPCODE_SCS, tmp_dst, src0); - inst->dst.writemask = scs_mask; + inst->dst[0].writemask = scs_mask; /* Move the result of the SCS instruction to the desired location in * the destination. */ tmp.swizzle = MAKE_SWIZZLE4(component, component, - component, component); + component, component); inst = emit(ir, TGSI_OPCODE_SCS, dst, tmp); - inst->dst.writemask = this_mask; + inst->dst[0].writemask = this_mask; } else { /* Emit the SCS instruction to write directly to the destination. */ glsl_to_tgsi_instruction *inst = emit(ir, TGSI_OPCODE_SCS, dst, src0); - inst->dst.writemask = scs_mask; + inst->dst[0].writemask = scs_mask; } done_mask |= this_mask; @@ -898,35 +1061,54 @@ glsl_to_tgsi_visitor::emit_scs(ir_instruction *ir, unsigned op, int glsl_to_tgsi_visitor::add_constant(gl_register_file file, - gl_constant_value values[4], int size, int datatype, - GLuint *swizzle_out) + gl_constant_value values[8], int size, int datatype, + GLuint *swizzle_out) { if (file == PROGRAM_CONSTANT) { return _mesa_add_typed_unnamed_constant(this->prog->Parameters, values, size, datatype, swizzle_out); - } else { - int index = 0; - immediate_storage *entry; - assert(file == PROGRAM_IMMEDIATE); + } - /* Search immediate storage to see if we already have an identical - * immediate that we can use instead of adding a duplicate entry. - */ - foreach_in_list(immediate_storage, entry, &this->immediates) { - if (entry->size == size && - entry->type == datatype && - !memcmp(entry->values, values, size * sizeof(gl_constant_value))) { - return index; - } - index++; + assert(file == PROGRAM_IMMEDIATE); + + int index = 0; + immediate_storage *entry; + int size32 = size * (datatype == GL_DOUBLE ? 2 : 1); + int i; + + /* Search immediate storage to see if we already have an identical + * immediate that we can use instead of adding a duplicate entry. + */ + foreach_in_list(immediate_storage, entry, &this->immediates) { + immediate_storage *tmp = entry; + + for (i = 0; i * 4 < size32; i++) { + int slot_size = MIN2(size32 - (i * 4), 4); + if (tmp->type != datatype || tmp->size32 != slot_size) + break; + if (memcmp(tmp->values, &values[i * 4], + slot_size * sizeof(gl_constant_value))) + break; + + /* Everything matches, keep going until the full size is matched */ + tmp = (immediate_storage *)tmp->next; } - + + /* The full value matched */ + if (i * 4 >= size32) + return index; + + index++; + } + + for (i = 0; i * 4 < size32; i++) { + int slot_size = MIN2(size32 - (i * 4), 4); /* Add this immediate to the list. */ - entry = new(mem_ctx) immediate_storage(values, size, datatype); + entry = new(mem_ctx) immediate_storage(&values[i * 4], slot_size, datatype); this->immediates.push_tail(entry); this->num_immediates++; - return index; } + return index; } st_src_reg @@ -941,12 +1123,25 @@ glsl_to_tgsi_visitor::st_src_reg_for_float(float val) return src; } +st_src_reg +glsl_to_tgsi_visitor::st_src_reg_for_double(double val) +{ + st_src_reg src(PROGRAM_IMMEDIATE, -1, GLSL_TYPE_DOUBLE); + union gl_constant_value uval[2]; + + uval[0].u = *(uint32_t *)&val; + uval[1].u = *(((uint32_t *)&val) + 1); + src.index = add_constant(src.file, uval, 1, GL_DOUBLE, &src.swizzle); + + return src; +} + st_src_reg glsl_to_tgsi_visitor::st_src_reg_for_int(int val) { st_src_reg src(PROGRAM_IMMEDIATE, -1, GLSL_TYPE_INT); union gl_constant_value uval; - + assert(native_integers); uval.i = val; @@ -959,7 +1154,7 @@ st_src_reg glsl_to_tgsi_visitor::st_src_reg_for_type(int type, int val) { if (native_integers) - return type == GLSL_TYPE_FLOAT ? st_src_reg_for_float(val) : + return type == GLSL_TYPE_FLOAT ? st_src_reg_for_float(val) : st_src_reg_for_int(val); else return st_src_reg_for_float(val); @@ -986,6 +1181,23 @@ type_size(const struct glsl_type *type) */ return 1; } + break; + case GLSL_TYPE_DOUBLE: + if (type->is_matrix()) { + if (type->vector_elements <= 2) + return type->matrix_columns; + else + return type->matrix_columns * 2; + } else { + /* For doubles if we have a double or dvec2 they fit in one + * vec4, else they need 2 vec4s. + */ + if (type->vector_elements <= 2) + return 1; + else + return 2; + } + break; case GLSL_TYPE_ARRAY: assert(type->length > 0); return type_size(type->fields.array) * type->length; @@ -1051,7 +1263,7 @@ glsl_to_tgsi_visitor::get_temp(const glsl_type *type) variable_storage * glsl_to_tgsi_visitor::find_variable_storage(ir_variable *var) { - + foreach_in_list(variable_storage, entry, &this->variables) { if (entry->var == var) return entry; @@ -1112,7 +1324,7 @@ glsl_to_tgsi_visitor::visit(ir_variable *ir) for (unsigned int i = 0; i < ir->get_num_state_slots(); i++) { int index = _mesa_add_state_reference(this->prog->Parameters, - (gl_state_index *)slots[i].tokens); + (gl_state_index *)slots[i].tokens); if (storage->file == PROGRAM_STATE_VAR) { if (storage->index == -1) { @@ -1121,11 +1333,11 @@ glsl_to_tgsi_visitor::visit(ir_variable *ir) assert(index == storage->index + (int)i); } } else { - /* We use GLSL_TYPE_FLOAT here regardless of the actual type of - * the data being moved since MOV does not care about the type of - * data it is moving, and we don't want to declare registers with - * array or struct types. - */ + /* We use GLSL_TYPE_FLOAT here regardless of the actual type of + * the data being moved since MOV does not care about the type of + * data it is moving, and we don't want to declare registers with + * array or struct types. + */ st_src_reg src(PROGRAM_STATE_VAR, index, GLSL_TYPE_FLOAT); src.swizzle = slots[i].swizzle; emit(ir, TGSI_OPCODE_MOV, dst, src); @@ -1137,9 +1349,9 @@ glsl_to_tgsi_visitor::visit(ir_variable *ir) if (storage->file == PROGRAM_TEMPORARY && dst.index != storage->index + (int) ir->get_num_state_slots()) { fail_link(this->shader_program, - "failed to load builtin uniform `%s' (%d/%d regs loaded)\n", - ir->name, dst.index - storage->index, - type_size(ir->type)); + "failed to load builtin uniform `%s' (%d/%d regs loaded)\n", + ir->name, dst.index - storage->index, + type_size(ir->type)); } } } @@ -1263,7 +1475,7 @@ glsl_to_tgsi_visitor::try_emit_mad_for_and_not(ir_expression *ir, int try_operan void glsl_to_tgsi_visitor::reladdr_to_temp(ir_instruction *ir, - st_src_reg *reg, int *num_reladdr) + st_src_reg *reg, int *num_reladdr) { if (!reg->reladdr && !reg->reladdr2) return; @@ -1302,9 +1514,9 @@ glsl_to_tgsi_visitor::visit(ir_expression *ir) */ if (!native_integers && ir->operation == ir_binop_logic_and) { if (try_emit_mad_for_and_not(ir, 1)) - return; + return; if (try_emit_mad_for_and_not(ir, 0)) - return; + return; } if (ir->operation == ir_quadop_vector) @@ -1330,7 +1542,7 @@ glsl_to_tgsi_visitor::visit(ir_expression *ir) int vector_elements = ir->operands[0]->type->vector_elements; if (ir->operands[1]) { vector_elements = MAX2(vector_elements, - ir->operands[1]->type->vector_elements); + ir->operands[1]->type->vector_elements); } this->result.file = PROGRAM_UNDEFINED; @@ -1364,6 +1576,8 @@ glsl_to_tgsi_visitor::visit(ir_expression *ir) case ir_unop_neg: if (result_dst.type == GLSL_TYPE_INT || result_dst.type == GLSL_TYPE_UINT) emit(ir, TGSI_OPCODE_INEG, result_dst, op[0]); + else if (result_dst.type == GLSL_TYPE_DOUBLE) + emit(ir, TGSI_OPCODE_DNEG, result_dst, op[0]); else { op[0].negate = ~op[0].negate; result_src = op[0]; @@ -1443,6 +1657,14 @@ glsl_to_tgsi_visitor::visit(ir_expression *ir) break; } + case ir_unop_frexp_sig: + emit(ir, TGSI_OPCODE_DFRACEXP, result_dst, undef_dst, op[0]); + break; + + case ir_unop_frexp_exp: + emit(ir, TGSI_OPCODE_DFRACEXP, undef_dst, result_dst, op[0]); + break; + case ir_unop_noise: { /* At some point, a motivated person could add a better * implementation of noise. Currently not even the nvidia @@ -1465,7 +1687,7 @@ glsl_to_tgsi_visitor::visit(ir_expression *ir) emit(ir, TGSI_OPCODE_MUL, result_dst, op[0], op[1]); break; case ir_binop_div: - if (result_dst.type == GLSL_TYPE_FLOAT) + if (result_dst.type == GLSL_TYPE_FLOAT || result_dst.type == GLSL_TYPE_DOUBLE) assert(!"not reached: should be handled by ir_div_to_mul_rcp"); else emit(ir, TGSI_OPCODE_DIV, result_dst, op[0], op[1]); @@ -1500,15 +1722,15 @@ glsl_to_tgsi_visitor::visit(ir_expression *ir) if (ir->operands[0]->type->is_vector() || ir->operands[1]->type->is_vector()) { st_src_reg temp = get_temp(native_integers ? - glsl_type::get_instance(ir->operands[0]->type->base_type, 4, 1) : - glsl_type::vec4_type); - + glsl_type::uvec4_type : + glsl_type::vec4_type); + if (native_integers) { st_dst_reg temp_dst = st_dst_reg(temp); st_src_reg temp1 = st_src_reg(temp), temp2 = st_src_reg(temp); - + emit(ir, TGSI_OPCODE_SEQ, st_dst_reg(temp), op[0], op[1]); - + /* Emit 1-3 AND operations to combine the SEQ results. */ switch (ir->operands[0]->type->vector_elements) { case 2: @@ -1529,13 +1751,13 @@ glsl_to_tgsi_visitor::visit(ir_expression *ir) temp2.swizzle = SWIZZLE_WWWW; emit(ir, TGSI_OPCODE_AND, temp_dst, temp1, temp2); } - + temp1.swizzle = SWIZZLE_XXXX; temp2.swizzle = SWIZZLE_YYYY; emit(ir, TGSI_OPCODE_AND, result_dst, temp1, temp2); } else { emit(ir, TGSI_OPCODE_SNE, st_dst_reg(temp), op[0], op[1]); - + /* After the dot-product, the value will be an integer on the * range [0,4]. Zero becomes 1.0, and positive values become zero. */ @@ -1558,14 +1780,14 @@ glsl_to_tgsi_visitor::visit(ir_expression *ir) if (ir->operands[0]->type->is_vector() || ir->operands[1]->type->is_vector()) { st_src_reg temp = get_temp(native_integers ? - glsl_type::get_instance(ir->operands[0]->type->base_type, 4, 1) : - glsl_type::vec4_type); + glsl_type::uvec4_type : + glsl_type::vec4_type); emit(ir, TGSI_OPCODE_SNE, st_dst_reg(temp), op[0], op[1]); if (native_integers) { st_dst_reg temp_dst = st_dst_reg(temp); st_src_reg temp1 = st_src_reg(temp), temp2 = st_src_reg(temp); - + /* Emit 1-3 OR operations to combine the SNE results. */ switch (ir->operands[0]->type->vector_elements) { case 2: @@ -1586,7 +1808,7 @@ glsl_to_tgsi_visitor::visit(ir_expression *ir) temp2.swizzle = SWIZZLE_WWWW; emit(ir, TGSI_OPCODE_OR, temp_dst, temp1, temp2); } - + temp1.swizzle = SWIZZLE_XXXX; temp2.swizzle = SWIZZLE_YYYY; emit(ir, TGSI_OPCODE_OR, result_dst, temp1, temp2); @@ -1708,7 +1930,7 @@ glsl_to_tgsi_visitor::visit(ir_expression *ir) case ir_binop_logic_or: { if (native_integers) { - /* If integers are used as booleans, we can use an actual "or" + /* If integers are used as booleans, we can use an actual "or" * instruction. */ assert(native_integers); @@ -1758,8 +1980,7 @@ glsl_to_tgsi_visitor::visit(ir_expression *ir) case ir_unop_sqrt: if (have_sqrt) { emit_scalar(ir, TGSI_OPCODE_SQRT, result_dst, op[0]); - } - else { + } else { /* sqrt(x) = x * rsq(x). */ emit_scalar(ir, TGSI_OPCODE_RSQ, result_dst, op[0]); emit(ir, TGSI_OPCODE_MUL, result_dst, result_src, op[0]); @@ -1797,7 +2018,7 @@ glsl_to_tgsi_visitor::visit(ir_expression *ir) */ emit(ir, TGSI_OPCODE_AND, result_dst, op[0], st_src_reg_for_int(1)); } else { - /* Booleans and integers are both stored as floats when native + /* Booleans and integers are both stored as floats when native * integers are disabled. */ result_src = op[0]; @@ -1831,6 +2052,9 @@ glsl_to_tgsi_visitor::visit(ir_expression *ir) case ir_unop_f2b: emit(ir, TGSI_OPCODE_SNE, result_dst, op[0], st_src_reg_for_float(0.0)); break; + case ir_unop_d2b: + emit(ir, TGSI_OPCODE_SNE, result_dst, op[0], st_src_reg_for_double(0.0)); + break; case ir_unop_i2b: if (native_integers) emit(ir, TGSI_OPCODE_INEG, result_dst, op[0]); @@ -1910,12 +2134,12 @@ glsl_to_tgsi_visitor::visit(ir_expression *ir) st_src_reg index_reg = get_temp(glsl_type::uint_type); st_src_reg cbuf; - cbuf.type = glsl_type::vec4_type->base_type; + cbuf.type = ir->type->base_type; cbuf.file = PROGRAM_CONSTANT; cbuf.index = 0; cbuf.reladdr = NULL; cbuf.negate = 0; - + assert(ir->type->is_vector() || ir->type->is_scalar()); if (const_offset_ir) { @@ -1946,10 +2170,16 @@ glsl_to_tgsi_visitor::visit(ir_expression *ir) } cbuf.swizzle = swizzle_for_size(ir->type->vector_elements); - cbuf.swizzle += MAKE_SWIZZLE4(const_offset % 16 / 4, - const_offset % 16 / 4, - const_offset % 16 / 4, - const_offset % 16 / 4); + if (cbuf.type == GLSL_TYPE_DOUBLE) + cbuf.swizzle += MAKE_SWIZZLE4(const_offset % 16 / 8, + const_offset % 16 / 8, + const_offset % 16 / 8, + const_offset % 16 / 8); + else + cbuf.swizzle += MAKE_SWIZZLE4(const_offset % 16 / 4, + const_offset % 16 / 4, + const_offset % 16 / 4, + const_offset % 16 / 4); if (ir->type->base_type == GLSL_TYPE_BOOL) { emit(ir, TGSI_OPCODE_USNE, result_dst, cbuf, st_src_reg_for_int(0)); @@ -2006,11 +2236,44 @@ glsl_to_tgsi_visitor::visit(ir_expression *ir) case ir_binop_interpolate_at_sample: emit(ir, TGSI_OPCODE_INTERP_SAMPLE, result_dst, op[0], op[1]); break; + + case ir_unop_d2f: + emit(ir, TGSI_OPCODE_D2F, result_dst, op[0]); + break; + case ir_unop_f2d: + emit(ir, TGSI_OPCODE_F2D, result_dst, op[0]); + break; + case ir_unop_d2i: + emit(ir, TGSI_OPCODE_D2I, result_dst, op[0]); + break; + case ir_unop_i2d: + emit(ir, TGSI_OPCODE_I2D, result_dst, op[0]); + break; + case ir_unop_d2u: + emit(ir, TGSI_OPCODE_D2U, result_dst, op[0]); + break; + case ir_unop_u2d: + emit(ir, TGSI_OPCODE_U2D, result_dst, op[0]); + break; + case ir_unop_unpack_double_2x32: + case ir_unop_pack_double_2x32: + emit(ir, TGSI_OPCODE_MOV, result_dst, op[0]); + break; + + case ir_binop_ldexp: + if (ir->operands[0]->type->base_type == GLSL_TYPE_DOUBLE) { + emit(ir, TGSI_OPCODE_DLDEXP, result_dst, op[0], op[1]); + } else { + assert(!"Invalid ldexp for non-double opcode in glsl_to_tgsi_visitor::visit()"); + } + break; + case ir_unop_pack_snorm_2x16: case ir_unop_pack_unorm_2x16: case ir_unop_pack_half_2x16: case ir_unop_pack_snorm_4x8: case ir_unop_pack_unorm_4x8: + case ir_unop_unpack_snorm_2x16: case ir_unop_unpack_unorm_2x16: case ir_unop_unpack_half_2x16: @@ -2018,13 +2281,13 @@ glsl_to_tgsi_visitor::visit(ir_expression *ir) case ir_unop_unpack_half_2x16_split_y: case ir_unop_unpack_snorm_4x8: case ir_unop_unpack_unorm_4x8: + case ir_binop_pack_half_2x16_split: case ir_binop_bfm: case ir_triop_bfi: case ir_quadop_vector: case ir_binop_vector_extract: case ir_triop_vector_insert: - case ir_binop_ldexp: case ir_binop_carry: case ir_binop_borrow: /* This operation is not supported, or should have already been handled. @@ -2052,6 +2315,7 @@ glsl_to_tgsi_visitor::visit(ir_swizzle *ir) ir->val->accept(this); src = this->result; assert(src.file != PROGRAM_UNDEFINED); + assert(ir->type->vector_elements > 0); for (i = 0; i < 4; i++) { if (i < ir->type->vector_elements) { @@ -2092,7 +2356,7 @@ glsl_to_tgsi_visitor::visit(ir_dereference_variable *ir) switch (var->data.mode) { case ir_var_uniform: entry = new(mem_ctx) variable_storage(var, PROGRAM_UNIFORM, - var->data.location); + var->data.location); this->variables.push_tail(entry); break; case ir_var_shader_in: @@ -2288,6 +2552,37 @@ glsl_to_tgsi_visitor::process_move_condition(ir_rvalue *ir) bool switch_order = false; ir_expression *const expr = ir->as_expression(); + + if (native_integers) { + if ((expr != NULL) && (expr->get_num_operands() == 2)) { + enum glsl_base_type type = expr->operands[0]->type->base_type; + if (type == GLSL_TYPE_INT || type == GLSL_TYPE_UINT || + type == GLSL_TYPE_BOOL) { + if (expr->operation == ir_binop_equal) { + if (expr->operands[0]->is_zero()) { + src_ir = expr->operands[1]; + switch_order = true; + } + else if (expr->operands[1]->is_zero()) { + src_ir = expr->operands[0]; + switch_order = true; + } + } + else if (expr->operation == ir_binop_nequal) { + if (expr->operands[0]->is_zero()) { + src_ir = expr->operands[1]; + } + else if (expr->operands[1]->is_zero()) { + src_ir = expr->operands[0]; + } + } + } + } + + src_ir->accept(this); + return switch_order; + } + if ((expr != NULL) && (expr->get_num_operands() == 2)) { bool zero_on_left = false; @@ -2359,18 +2654,20 @@ glsl_to_tgsi_visitor::process_move_condition(ir_rvalue *ir) void glsl_to_tgsi_visitor::emit_block_mov(ir_assignment *ir, const struct glsl_type *type, - st_dst_reg *l, st_src_reg *r) + st_dst_reg *l, st_src_reg *r, + st_src_reg *cond, bool cond_swap) { if (type->base_type == GLSL_TYPE_STRUCT) { for (unsigned int i = 0; i < type->length; i++) { - emit_block_mov(ir, type->fields.structure[i].type, l, r); + emit_block_mov(ir, type->fields.structure[i].type, l, r, + cond, cond_swap); } return; } if (type->is_array()) { for (unsigned int i = 0; i < type->length; i++) { - emit_block_mov(ir, type->fields.array, l, r); + emit_block_mov(ir, type->fields.array, l, r, cond, cond_swap); } return; } @@ -2379,10 +2676,10 @@ glsl_to_tgsi_visitor::emit_block_mov(ir_assignment *ir, const struct glsl_type * const struct glsl_type *vec_type; vec_type = glsl_type::get_instance(GLSL_TYPE_FLOAT, - type->vector_elements, 1); + type->vector_elements, 1); for (int i = 0; i < type->matrix_columns; i++) { - emit_block_mov(ir, vec_type, l, r); + emit_block_mov(ir, vec_type, l, r, cond, cond_swap); } return; } @@ -2390,7 +2687,22 @@ glsl_to_tgsi_visitor::emit_block_mov(ir_assignment *ir, const struct glsl_type * assert(type->is_scalar() || type->is_vector()); r->type = type->base_type; - emit(ir, TGSI_OPCODE_MOV, *l, *r); + if (cond) { + st_src_reg l_src = st_src_reg(*l); + l_src.swizzle = swizzle_for_size(type->vector_elements); + + if (native_integers) { + emit(ir, TGSI_OPCODE_UCMP, *l, *cond, + cond_swap ? l_src : *r, + cond_swap ? *r : l_src); + } else { + emit(ir, TGSI_OPCODE_CMP, *l, *cond, + cond_swap ? l_src : *r, + cond_swap ? *r : l_src); + } + } else { + emit(ir, TGSI_OPCODE_MOV, *l, *r); + } l->index++; r->index++; } @@ -2400,7 +2712,6 @@ glsl_to_tgsi_visitor::visit(ir_assignment *ir) { st_dst_reg l; st_src_reg r; - int i; ir->rhs->accept(this); r = this->result; @@ -2447,7 +2758,7 @@ glsl_to_tgsi_visitor::visit(ir_assignment *ir) swizzles[i] = first_enabled_chan; } r.swizzle = MAKE_SWIZZLE4(swizzles[0], swizzles[1], - swizzles[2], swizzles[3]); + swizzles[2], swizzles[3]); } assert(l.file != PROGRAM_UNDEFINED); @@ -2457,38 +2768,13 @@ glsl_to_tgsi_visitor::visit(ir_assignment *ir) const bool switch_order = this->process_move_condition(ir->condition); st_src_reg condition = this->result; - for (i = 0; i < type_size(ir->lhs->type); i++) { - st_src_reg l_src = st_src_reg(l); - st_src_reg condition_temp = condition; - l_src.swizzle = swizzle_for_size(ir->lhs->type->vector_elements); - - if (native_integers) { - /* This is necessary because TGSI's CMP instruction expects the - * condition to be a float, and we store booleans as integers. - * TODO: really want to avoid i2f path and use UCMP. Requires - * changes to process_move_condition though too. - */ - condition_temp = get_temp(glsl_type::vec4_type); - condition.negate = 0; - emit(ir, TGSI_OPCODE_I2F, st_dst_reg(condition_temp), condition); - condition_temp.swizzle = condition.swizzle; - } - - if (switch_order) { - emit(ir, TGSI_OPCODE_CMP, l, condition_temp, l_src, r); - } else { - emit(ir, TGSI_OPCODE_CMP, l, condition_temp, r, l_src); - } - - l.index++; - r.index++; - } + emit_block_mov(ir, ir->lhs->type, &l, &r, &condition, switch_order); } else if (ir->rhs->as_expression() && this->instructions.get_tail() && ir->rhs == ((glsl_to_tgsi_instruction *)this->instructions.get_tail())->ir && type_size(ir->lhs->type) == 1 && - l.writemask == ((glsl_to_tgsi_instruction *)this->instructions.get_tail())->dst.writemask) { - /* To avoid emitting an extra MOV when assigning an expression to a + l.writemask == ((glsl_to_tgsi_instruction *)this->instructions.get_tail())->dst[0].writemask) { + /* To avoid emitting an extra MOV when assigning an expression to a * variable, emit the last instruction of the expression again, but * replace the destination register with the target of the assignment. * Dead code elimination will remove the original instruction. @@ -2497,9 +2783,9 @@ glsl_to_tgsi_visitor::visit(ir_assignment *ir) inst = (glsl_to_tgsi_instruction *)this->instructions.get_tail(); new_inst = emit(ir, inst->op, l, inst->src[0], inst->src[1], inst->src[2]); new_inst->saturate = inst->saturate; - inst->dead_mask = inst->dst.writemask; + inst->dead_mask = inst->dst[0].writemask; } else { - emit_block_mov(ir, ir->rhs->type, &l, &r); + emit_block_mov(ir, ir->rhs->type, &l, &r, NULL, false); } } @@ -2508,7 +2794,7 @@ void glsl_to_tgsi_visitor::visit(ir_constant *ir) { st_src_reg src; - GLfloat stack_vals[4] = { 0 }; + GLdouble stack_vals[4] = { 0 }; gl_constant_value *values = (gl_constant_value *) stack_vals; GLenum gl_type = GL_NONE; unsigned int i; @@ -2596,6 +2882,13 @@ glsl_to_tgsi_visitor::visit(ir_constant *ir) values[i].f = ir->value.f[i]; } break; + case GLSL_TYPE_DOUBLE: + gl_type = GL_DOUBLE; + for (i = 0; i < ir->type->vector_elements; i++) { + values[i * 2].i = *(uint32_t *)&ir->value.d[i]; + values[i * 2 + 1].i = *(((uint32_t *)&ir->value.d[i]) + 1); + } + break; case GLSL_TYPE_UINT: gl_type = native_integers ? GL_UNSIGNED_INT : GL_FLOAT; for (i = 0; i < ir->type->vector_elements; i++) { @@ -2790,7 +3083,7 @@ glsl_to_tgsi_visitor::visit(ir_texture *ir) switch (ir->op) { case ir_tex: - opcode = (is_cube_array && ir->shadow_comparitor) ? TGSI_OPCODE_TEX2 : TGSI_OPCODE_TEX; + opcode = (is_cube_array && ir->shadow_comparitor) ? TGSI_OPCODE_TEX2 : TGSI_OPCODE_TEX; if (ir->offset) { ir->offset->accept(this); offset[0] = this->result; @@ -2910,8 +3203,8 @@ glsl_to_tgsi_visitor::visit(ir_texture *ir) tmp_src = get_temp(glsl_type::vec4_type); st_dst_reg tmp_dst = st_dst_reg(tmp_src); - /* Projective division not allowed for array samplers. */ - assert(!sampler_type->sampler_array); + /* Projective division not allowed for array samplers. */ + assert(!sampler_type->sampler_array); tmp_dst.writemask = WRITEMASK_Z; emit(ir, TGSI_OPCODE_MOV, tmp_dst, this->result); @@ -2953,7 +3246,6 @@ glsl_to_tgsi_visitor::visit(ir_texture *ir) } else { coord_dst.writemask = WRITEMASK_Z; } - emit(ir, TGSI_OPCODE_MOV, coord_dst, this->result); coord_dst.writemask = WRITEMASK_XYZW; } @@ -3203,7 +3495,6 @@ count_resources(glsl_to_tgsi_visitor *v, gl_program *prog) } } } - prog->SamplersUsed = v->samplers_used; if (v->shader_program != NULL) @@ -3242,9 +3533,9 @@ get_src_arg_mask(st_dst_reg dst, st_src_reg src) * Here is why this conversion is safe: * CMP T0, T1 T2 T0 can be expanded to: * if (T1 < 0.0) - * MOV T0, T2; + * MOV T0, T2; * else - * MOV T0, T0; + * MOV T0, T0; * * If (T1 < 0.0) evaluates to true then our replacement MOV T0, T2 is the same * as the original program. If (T1 < 0.0) evaluates to false, executing @@ -3266,7 +3557,8 @@ glsl_to_tgsi_visitor::simplify_cmp(void) unsigned prevWriteMask = 0; /* Give up if we encounter relative addressing or flow control. */ - if (inst->dst.reladdr || + if (inst->dst[0].reladdr || + inst->dst[1].reladdr || tgsi_get_opcode_info(inst->op)->is_branch || inst->op == TGSI_OPCODE_BGNSUB || inst->op == TGSI_OPCODE_CONT || @@ -3276,12 +3568,12 @@ glsl_to_tgsi_visitor::simplify_cmp(void) break; } - if (inst->dst.file == PROGRAM_OUTPUT) { - assert(inst->dst.index < MAX_PROGRAM_OUTPUTS); - prevWriteMask = outputWrites[inst->dst.index]; - outputWrites[inst->dst.index] |= inst->dst.writemask; - } else if (inst->dst.file == PROGRAM_TEMPORARY) { - if (inst->dst.index >= tempWritesSize) { + if (inst->dst[0].file == PROGRAM_OUTPUT) { + assert(inst->dst[0].index < MAX_PROGRAM_OUTPUTS); + prevWriteMask = outputWrites[inst->dst[0].index]; + outputWrites[inst->dst[0].index] |= inst->dst[0].writemask; + } else if (inst->dst[0].file == PROGRAM_TEMPORARY) { + if (inst->dst[0].index >= tempWritesSize) { const int inc = 4096; tempWrites = (unsigned*) @@ -3294,18 +3586,18 @@ glsl_to_tgsi_visitor::simplify_cmp(void) tempWritesSize += inc; } - prevWriteMask = tempWrites[inst->dst.index]; - tempWrites[inst->dst.index] |= inst->dst.writemask; + prevWriteMask = tempWrites[inst->dst[0].index]; + tempWrites[inst->dst[0].index] |= inst->dst[0].writemask; } else continue; /* For a CMP to be considered a conditional write, the destination * register and source register two must be the same. */ if (inst->op == TGSI_OPCODE_CMP - && !(inst->dst.writemask & prevWriteMask) - && inst->src[2].file == inst->dst.file - && inst->src[2].index == inst->dst.index - && inst->dst.writemask == get_src_arg_mask(inst->dst, inst->src[2])) { + && !(inst->dst[0].writemask & prevWriteMask) + && inst->src[2].file == inst->dst[0].file + && inst->src[2].index == inst->dst[0].index + && inst->dst[0].writemask == get_src_arg_mask(inst->dst[0], inst->src[2])) { inst->op = TGSI_OPCODE_MOV; inst->src[0] = inst->src[1]; @@ -3321,23 +3613,25 @@ glsl_to_tgsi_visitor::rename_temp_register(int index, int new_index) { foreach_in_list(glsl_to_tgsi_instruction, inst, &this->instructions) { unsigned j; - - for (j=0; j < num_inst_src_regs(inst->op); j++) { - if (inst->src[j].file == PROGRAM_TEMPORARY && + + for (j = 0; j < num_inst_src_regs(inst->op); j++) { + if (inst->src[j].file == PROGRAM_TEMPORARY && inst->src[j].index == index) { inst->src[j].index = new_index; } } - for (j=0; j < inst->tex_offset_num_offset; j++) { - if (inst->tex_offsets[j].file == PROGRAM_TEMPORARY && + for (j = 0; j < inst->tex_offset_num_offset; j++) { + if (inst->tex_offsets[j].file == PROGRAM_TEMPORARY && inst->tex_offsets[j].index == index) { inst->tex_offsets[j].index = new_index; } } - - if (inst->dst.file == PROGRAM_TEMPORARY && inst->dst.index == index) { - inst->dst.index = new_index; + + for (j = 0; j < num_inst_dst_regs(inst->op); j++) { + if (inst->dst[j].file == PROGRAM_TEMPORARY && inst->dst[j].index == index) { + inst->dst[j].index = new_index; + } } } } @@ -3348,21 +3642,20 @@ glsl_to_tgsi_visitor::get_first_temp_read(int index) int depth = 0; /* loop depth */ int loop_start = -1; /* index of the first active BGNLOOP (if any) */ unsigned i = 0, j; - + foreach_in_list(glsl_to_tgsi_instruction, inst, &this->instructions) { - for (j=0; j < num_inst_src_regs(inst->op); j++) { - if (inst->src[j].file == PROGRAM_TEMPORARY && + for (j = 0; j < num_inst_src_regs(inst->op); j++) { + if (inst->src[j].file == PROGRAM_TEMPORARY && inst->src[j].index == index) { return (depth == 0) ? i : loop_start; } } - for (j=0; j < inst->tex_offset_num_offset; j++) { - if (inst->tex_offsets[j].file == PROGRAM_TEMPORARY && + for (j = 0; j < inst->tex_offset_num_offset; j++) { + if (inst->tex_offsets[j].file == PROGRAM_TEMPORARY && inst->tex_offsets[j].index == index) { return (depth == 0) ? i : loop_start; } } - if (inst->op == TGSI_OPCODE_BGNLOOP) { if(depth++ == 0) loop_start = i; @@ -3371,10 +3664,8 @@ glsl_to_tgsi_visitor::get_first_temp_read(int index) loop_start = -1; } assert(depth >= 0); - i++; } - return -1; } @@ -3384,12 +3675,14 @@ glsl_to_tgsi_visitor::get_first_temp_write(int index) int depth = 0; /* loop depth */ int loop_start = -1; /* index of the first active BGNLOOP (if any) */ int i = 0; - + unsigned j; + foreach_in_list(glsl_to_tgsi_instruction, inst, &this->instructions) { - if (inst->dst.file == PROGRAM_TEMPORARY && inst->dst.index == index) { - return (depth == 0) ? i : loop_start; + for (j = 0; j < num_inst_dst_regs(inst->op); j++) { + if (inst->dst[j].file == PROGRAM_TEMPORARY && inst->dst[j].index == index) { + return (depth == 0) ? i : loop_start; + } } - if (inst->op == TGSI_OPCODE_BGNLOOP) { if(depth++ == 0) loop_start = i; @@ -3398,10 +3691,8 @@ glsl_to_tgsi_visitor::get_first_temp_write(int index) loop_start = -1; } assert(depth >= 0); - i++; } - return -1; } @@ -3411,30 +3702,27 @@ glsl_to_tgsi_visitor::get_last_temp_read(int index) int depth = 0; /* loop depth */ int last = -1; /* index of last instruction that reads the temporary */ unsigned i = 0, j; - + foreach_in_list(glsl_to_tgsi_instruction, inst, &this->instructions) { - for (j=0; j < num_inst_src_regs(inst->op); j++) { - if (inst->src[j].file == PROGRAM_TEMPORARY && + for (j = 0; j < num_inst_src_regs(inst->op); j++) { + if (inst->src[j].file == PROGRAM_TEMPORARY && inst->src[j].index == index) { last = (depth == 0) ? i : -2; } } - for (j=0; j < inst->tex_offset_num_offset; j++) { + for (j = 0; j < inst->tex_offset_num_offset; j++) { if (inst->tex_offsets[j].file == PROGRAM_TEMPORARY && inst->tex_offsets[j].index == index) last = (depth == 0) ? i : -2; } - if (inst->op == TGSI_OPCODE_BGNLOOP) depth++; else if (inst->op == TGSI_OPCODE_ENDLOOP) if (--depth == 0 && last == -2) last = i; assert(depth >= 0); - i++; } - assert(last >= -1); return last; } @@ -3445,21 +3733,22 @@ glsl_to_tgsi_visitor::get_last_temp_write(int index) int depth = 0; /* loop depth */ int last = -1; /* index of last instruction that writes to the temporary */ int i = 0; - + unsigned j; + foreach_in_list(glsl_to_tgsi_instruction, inst, &this->instructions) { - if (inst->dst.file == PROGRAM_TEMPORARY && inst->dst.index == index) - last = (depth == 0) ? i : -2; - + for (j = 0; j < num_inst_dst_regs(inst->op); j++) { + if (inst->dst[j].file == PROGRAM_TEMPORARY && inst->dst[j].index == index) + last = (depth == 0) ? i : -2; + } + if (inst->op == TGSI_OPCODE_BGNLOOP) depth++; else if (inst->op == TGSI_OPCODE_ENDLOOP) if (--depth == 0 && last == -2) last = i; assert(depth >= 0); - i++; } - assert(last >= -1); return last; } @@ -3488,14 +3777,14 @@ void glsl_to_tgsi_visitor::copy_propagate(void) { glsl_to_tgsi_instruction **acp = rzalloc_array(mem_ctx, - glsl_to_tgsi_instruction *, - this->next_temp * 4); + glsl_to_tgsi_instruction *, + this->next_temp * 4); int *acp_level = rzalloc_array(mem_ctx, int, this->next_temp * 4); int level = 0; foreach_in_list(glsl_to_tgsi_instruction, inst, &this->instructions) { - assert(inst->dst.file != PROGRAM_TEMPORARY - || inst->dst.index < this->next_temp); + assert(inst->dst[0].file != PROGRAM_TEMPORARY + || inst->dst[0].index < this->next_temp); /* First, do any copy propagation possible into the src regs. */ for (int r = 0; r < 3; r++) { @@ -3527,9 +3816,10 @@ glsl_to_tgsi_visitor::copy_propagate(void) first = copy_chan; } else { if (first->src[0].file != copy_chan->src[0].file || - first->src[0].index != copy_chan->src[0].index) { - good = false; - break; + first->src[0].index != copy_chan->src[0].index || + first->src[0].index2D != copy_chan->src[0].index2D) { + good = false; + break; } } } @@ -3547,8 +3837,7 @@ glsl_to_tgsi_visitor::copy_propagate(void) for (int i = 0; i < 4; i++) { int src_chan = GET_SWZ(inst->src[r].swizzle, i); glsl_to_tgsi_instruction *copy_inst = acp[acp_base + src_chan]; - swizzle |= (GET_SWZ(copy_inst->src[0].swizzle, src_chan) << - (3 * i)); + swizzle |= (GET_SWZ(copy_inst->src[0].swizzle, src_chan) << (3 * i)); } inst->src[r].swizzle = swizzle; } @@ -3574,10 +3863,10 @@ glsl_to_tgsi_visitor::copy_propagate(void) for (int r = 0; r < this->next_temp; r++) { for (int c = 0; c < 4; c++) { if (!acp[4 * r + c]) - continue; + continue; if (acp_level[4 * r + c] >= level) - acp[4 * r + c] = NULL; + acp[4 * r + c] = NULL; } } if (inst->op == TGSI_OPCODE_ENDIF) @@ -3588,50 +3877,50 @@ glsl_to_tgsi_visitor::copy_propagate(void) /* Continuing the block, clear any written channels from * the ACP. */ - if (inst->dst.file == PROGRAM_TEMPORARY && inst->dst.reladdr) { - /* Any temporary might be written, so no copy propagation - * across this instruction. - */ - memset(acp, 0, sizeof(*acp) * this->next_temp * 4); - } else if (inst->dst.file == PROGRAM_OUTPUT && - inst->dst.reladdr) { - /* Any output might be written, so no copy propagation - * from outputs across this instruction. - */ - for (int r = 0; r < this->next_temp; r++) { - for (int c = 0; c < 4; c++) { - if (!acp[4 * r + c]) - continue; - - if (acp[4 * r + c]->src[0].file == PROGRAM_OUTPUT) - acp[4 * r + c] = NULL; + for (int d = 0; d < 2; d++) { + if (inst->dst[d].file == PROGRAM_TEMPORARY && inst->dst[d].reladdr) { + /* Any temporary might be written, so no copy propagation + * across this instruction. + */ + memset(acp, 0, sizeof(*acp) * this->next_temp * 4); + } else if (inst->dst[d].file == PROGRAM_OUTPUT && + inst->dst[d].reladdr) { + /* Any output might be written, so no copy propagation + * from outputs across this instruction. + */ + for (int r = 0; r < this->next_temp; r++) { + for (int c = 0; c < 4; c++) { + if (!acp[4 * r + c]) + continue; + + if (acp[4 * r + c]->src[0].file == PROGRAM_OUTPUT) + acp[4 * r + c] = NULL; + } } - } - } else if (inst->dst.file == PROGRAM_TEMPORARY || - inst->dst.file == PROGRAM_OUTPUT) { - /* Clear where it's used as dst. */ - if (inst->dst.file == PROGRAM_TEMPORARY) { - for (int c = 0; c < 4; c++) { - if (inst->dst.writemask & (1 << c)) { - acp[4 * inst->dst.index + c] = NULL; - } + } else if (inst->dst[d].file == PROGRAM_TEMPORARY || + inst->dst[d].file == PROGRAM_OUTPUT) { + /* Clear where it's used as dst. */ + if (inst->dst[d].file == PROGRAM_TEMPORARY) { + for (int c = 0; c < 4; c++) { + if (inst->dst[d].writemask & (1 << c)) + acp[4 * inst->dst[d].index + c] = NULL; + } } - } - - /* Clear where it's used as src. */ - for (int r = 0; r < this->next_temp; r++) { - for (int c = 0; c < 4; c++) { - if (!acp[4 * r + c]) - continue; - int src_chan = GET_SWZ(acp[4 * r + c]->src[0].swizzle, c); - - if (acp[4 * r + c]->src[0].file == inst->dst.file && - acp[4 * r + c]->src[0].index == inst->dst.index && - inst->dst.writemask & (1 << src_chan)) - { - acp[4 * r + c] = NULL; - } + /* Clear where it's used as src. */ + for (int r = 0; r < this->next_temp; r++) { + for (int c = 0; c < 4; c++) { + if (!acp[4 * r + c]) + continue; + + int src_chan = GET_SWZ(acp[4 * r + c]->src[0].swizzle, c); + + if (acp[4 * r + c]->src[0].file == inst->dst[d].file && + acp[4 * r + c]->src[0].index == inst->dst[d].index && + inst->dst[d].writemask & (1 << src_chan)) { + acp[4 * r + c] = NULL; + } + } } } } @@ -3640,18 +3929,18 @@ glsl_to_tgsi_visitor::copy_propagate(void) /* If this is a copy, add it to the ACP. */ if (inst->op == TGSI_OPCODE_MOV && - inst->dst.file == PROGRAM_TEMPORARY && - !(inst->dst.file == inst->src[0].file && - inst->dst.index == inst->src[0].index) && - !inst->dst.reladdr && + inst->dst[0].file == PROGRAM_TEMPORARY && + !(inst->dst[0].file == inst->src[0].file && + inst->dst[0].index == inst->src[0].index) && + !inst->dst[0].reladdr && !inst->saturate && !inst->src[0].reladdr && !inst->src[0].reladdr2 && !inst->src[0].negate) { for (int i = 0; i < 4; i++) { - if (inst->dst.writemask & (1 << i)) { - acp[4 * inst->dst.index + i] = inst; - acp_level[4 * inst->dst.index + i] = level; + if (inst->dst[0].writemask & (1 << i)) { + acp[4 * inst->dst[0].index + i] = inst; + acp_level[4 * inst->dst[0].index + i] = level; } } } @@ -3666,7 +3955,7 @@ glsl_to_tgsi_visitor::copy_propagate(void) * code elimination. * * The glsl_to_tgsi_visitor lazily produces code assuming that this pass - * will occur. As an example, a TXP production after copy propagation but + * will occur. As an example, a TXP production after copy propagation but * before this pass: * * 0: MOV TEMP[1], INPUT[4].xyyy; @@ -3688,9 +3977,9 @@ glsl_to_tgsi_visitor::eliminate_dead_code(void) int removed = 0; foreach_in_list(glsl_to_tgsi_instruction, inst, &this->instructions) { - assert(inst->dst.file != PROGRAM_TEMPORARY - || inst->dst.index < this->next_temp); - + assert(inst->dst[0].file != PROGRAM_TEMPORARY + || inst->dst[0].index < this->next_temp); + switch (inst->op) { case TGSI_OPCODE_BGNLOOP: case TGSI_OPCODE_ENDLOOP: @@ -3715,30 +4004,27 @@ glsl_to_tgsi_visitor::eliminate_dead_code(void) for (int r = 0; r < this->next_temp; r++) { for (int c = 0; c < 4; c++) { if (!writes[4 * r + c]) - continue; + continue; if (write_level[4 * r + c] == level) - write_level[4 * r + c] = level-1; + write_level[4 * r + c] = level-1; } } - if(inst->op == TGSI_OPCODE_ENDIF) --level; - break; case TGSI_OPCODE_IF: case TGSI_OPCODE_UIF: ++level; /* fallthrough to default case to mark the condition as read */ - default: /* Continuing the block, clear any channels from the write array that * are read by this instruction. */ for (unsigned i = 0; i < Elements(inst->src); i++) { if (inst->src[i].file == PROGRAM_TEMPORARY && inst->src[i].reladdr){ - /* Any temporary might be read, so no dead code elimination + /* Any temporary might be read, so no dead code elimination * across this instruction. */ memset(writes, 0, sizeof(*writes) * this->next_temp * 4); @@ -3748,17 +4034,16 @@ glsl_to_tgsi_visitor::eliminate_dead_code(void) src_chans |= 1 << GET_SWZ(inst->src[i].swizzle, 1); src_chans |= 1 << GET_SWZ(inst->src[i].swizzle, 2); src_chans |= 1 << GET_SWZ(inst->src[i].swizzle, 3); - + for (int c = 0; c < 4; c++) { - if (src_chans & (1 << c)) { - writes[4 * inst->src[i].index + c] = NULL; - } + if (src_chans & (1 << c)) + writes[4 * inst->src[i].index + c] = NULL; } } } for (unsigned i = 0; i < inst->tex_offset_num_offset; i++) { if (inst->tex_offsets[i].file == PROGRAM_TEMPORARY && inst->tex_offsets[i].reladdr){ - /* Any temporary might be read, so no dead code elimination + /* Any temporary might be read, so no dead code elimination * across this instruction. */ memset(writes, 0, sizeof(*writes) * this->next_temp * 4); @@ -3768,11 +4053,10 @@ glsl_to_tgsi_visitor::eliminate_dead_code(void) src_chans |= 1 << GET_SWZ(inst->tex_offsets[i].swizzle, 1); src_chans |= 1 << GET_SWZ(inst->tex_offsets[i].swizzle, 2); src_chans |= 1 << GET_SWZ(inst->tex_offsets[i].swizzle, 3); - + for (int c = 0; c < 4; c++) { - if (src_chans & (1 << c)) { - writes[4 * inst->tex_offsets[i].index + c] = NULL; - } + if (src_chans & (1 << c)) + writes[4 * inst->tex_offsets[i].index + c] = NULL; } } } @@ -3783,19 +4067,21 @@ glsl_to_tgsi_visitor::eliminate_dead_code(void) * If there is already an instruction in the write array for one or more * of the channels, flag that channel write as dead. */ - if (inst->dst.file == PROGRAM_TEMPORARY && - !inst->dst.reladdr && - !inst->saturate) { - for (int c = 0; c < 4; c++) { - if (inst->dst.writemask & (1 << c)) { - if (writes[4 * inst->dst.index + c]) { - if (write_level[4 * inst->dst.index + c] < level) - continue; - else - writes[4 * inst->dst.index + c]->dead_mask |= (1 << c); + for (unsigned i = 0; i < Elements(inst->dst); i++) { + if (inst->dst[i].file == PROGRAM_TEMPORARY && + !inst->dst[i].reladdr && + !inst->saturate) { + for (int c = 0; c < 4; c++) { + if (inst->dst[i].writemask & (1 << c)) { + if (writes[4 * inst->dst[i].index + c]) { + if (write_level[4 * inst->dst[i].index + c] < level) + continue; + else + writes[4 * inst->dst[i].index + c]->dead_mask |= (1 << c); + } + writes[4 * inst->dst[i].index + c] = inst; + write_level[4 * inst->dst[i].index + c] = level; } - writes[4 * inst->dst.index + c] = inst; - write_level[4 * inst->dst.index + c] = level; } } } @@ -3814,26 +4100,75 @@ glsl_to_tgsi_visitor::eliminate_dead_code(void) * the writemask of other instructions with dead channels. */ foreach_in_list_safe(glsl_to_tgsi_instruction, inst, &this->instructions) { - if (!inst->dead_mask || !inst->dst.writemask) + if (!inst->dead_mask || !inst->dst[0].writemask) continue; - else if ((inst->dst.writemask & ~inst->dead_mask) == 0) { + else if ((inst->dst[0].writemask & ~inst->dead_mask) == 0) { inst->remove(); delete inst; removed++; - } else - inst->dst.writemask &= ~(inst->dead_mask); + } else { + if (inst->dst[0].type == GLSL_TYPE_DOUBLE) { + if (inst->dead_mask == WRITEMASK_XY || + inst->dead_mask == WRITEMASK_ZW) + inst->dst[0].writemask &= ~(inst->dead_mask); + } else + inst->dst[0].writemask &= ~(inst->dead_mask); + } } ralloc_free(write_level); ralloc_free(writes); - + return removed; } -/* Merges temporary registers together where possible to reduce the number of +/* merge DFRACEXP instructions into one. */ +void +glsl_to_tgsi_visitor::merge_two_dsts(void) +{ + foreach_in_list_safe(glsl_to_tgsi_instruction, inst, &this->instructions) { + glsl_to_tgsi_instruction *inst2; + bool merged; + if (num_inst_dst_regs(inst->op) != 2) + continue; + + if (inst->dst[0].file != PROGRAM_UNDEFINED && + inst->dst[1].file != PROGRAM_UNDEFINED) + continue; + + inst2 = (glsl_to_tgsi_instruction *) inst->next; + do { + + if (inst->src[0].file == inst2->src[0].file && + inst->src[0].index == inst2->src[0].index && + inst->src[0].type == inst2->src[0].type && + inst->src[0].swizzle == inst2->src[0].swizzle) + break; + inst2 = (glsl_to_tgsi_instruction *) inst2->next; + } while (inst2); + + if (!inst2) + continue; + merged = false; + if (inst->dst[0].file == PROGRAM_UNDEFINED) { + merged = true; + inst->dst[0] = inst2->dst[0]; + } else if (inst->dst[1].file == PROGRAM_UNDEFINED) { + inst->dst[1] = inst2->dst[1]; + merged = true; + } + + if (merged) { + inst2->remove(); + delete inst2; + } + } +} + +/* Merges temporary registers together where possible to reduce the number of * registers needed to run a program. - * - * Produces optimal code only after copy propagation and dead code elimination + * + * Produces optimal code only after copy propagation and dead code elimination * have been run. */ void glsl_to_tgsi_visitor::merge_registers(void) @@ -3841,36 +4176,35 @@ glsl_to_tgsi_visitor::merge_registers(void) int *last_reads = rzalloc_array(mem_ctx, int, this->next_temp); int *first_writes = rzalloc_array(mem_ctx, int, this->next_temp); int i, j; - + /* Read the indices of the last read and first write to each temp register - * into an array so that we don't have to traverse the instruction list as + * into an array so that we don't have to traverse the instruction list as * much. */ - for (i=0; i < this->next_temp; i++) { + for (i = 0; i < this->next_temp; i++) { last_reads[i] = get_last_temp_read(i); first_writes[i] = get_first_temp_write(i); } - - /* Start looking for registers with non-overlapping usages that can be + + /* Start looking for registers with non-overlapping usages that can be * merged together. */ - for (i=0; i < this->next_temp; i++) { + for (i = 0; i < this->next_temp; i++) { /* Don't touch unused registers. */ if (last_reads[i] < 0 || first_writes[i] < 0) continue; - - for (j=0; j < this->next_temp; j++) { + + for (j = 0; j < this->next_temp; j++) { /* Don't touch unused registers. */ if (last_reads[j] < 0 || first_writes[j] < 0) continue; - - /* We can merge the two registers if the first write to j is after or - * in the same instruction as the last read from i. Note that the - * register at index i will always be used earlier or at the same time + + /* We can merge the two registers if the first write to j is after or + * in the same instruction as the last read from i. Note that the + * register at index i will always be used earlier or at the same time * as the register at index j. */ - if (first_writes[i] <= first_writes[j] && - last_reads[i] <= first_writes[j]) - { + if (first_writes[i] <= first_writes[j] && + last_reads[i] <= first_writes[j]) { rename_temp_register(j, i); /* Replace all references to j with i.*/ - - /* Update the first_writes and last_reads arrays with the new - * values for the merged register index, and mark the newly unused + + /* Update the first_writes and last_reads arrays with the new + * values for the merged register index, and mark the newly unused * register index as such. */ last_reads[i] = last_reads[j]; first_writes[j] = -1; @@ -3878,26 +4212,26 @@ glsl_to_tgsi_visitor::merge_registers(void) } } } - + ralloc_free(last_reads); ralloc_free(first_writes); } -/* Reassign indices to temporary registers by reusing unused indices created +/* Reassign indices to temporary registers by reusing unused indices created * by optimization passes. */ void glsl_to_tgsi_visitor::renumber_registers(void) { int i = 0; int new_index = 0; - - for (i=0; i < this->next_temp; i++) { + + for (i = 0; i < this->next_temp; i++) { if (get_first_temp_read(i) < 0) continue; if (i != new_index) rename_temp_register(i, new_index); new_index++; } - + this->next_temp = new_index; } @@ -4005,14 +4339,13 @@ get_pixel_transfer_visitor(struct st_fragment_program *fp, glsl_to_tgsi_instruction *newinst; st_src_reg src_regs[3]; - if (inst->dst.file == PROGRAM_OUTPUT) - prog->OutputsWritten |= BITFIELD64_BIT(inst->dst.index); + if (inst->dst[0].file == PROGRAM_OUTPUT) + prog->OutputsWritten |= BITFIELD64_BIT(inst->dst[0].index); - for (int i=0; i<3; i++) { + for (int i = 0; i < 3; i++) { src_regs[i] = inst->src[i]; if (src_regs[i].file == PROGRAM_INPUT && - src_regs[i].index == VARYING_SLOT_COL0) - { + src_regs[i].index == VARYING_SLOT_COL0) { src_regs[i].file = PROGRAM_TEMPORARY; src_regs[i].index = src0.index; } @@ -4020,7 +4353,7 @@ get_pixel_transfer_visitor(struct st_fragment_program *fp, prog->InputsRead |= BITFIELD64_BIT(src_regs[i].index); } - newinst = v->emit(NULL, inst->op, inst->dst, src_regs[0], src_regs[1], src_regs[2]); + newinst = v->emit(NULL, inst->op, inst->dst[0], src_regs[0], src_regs[1], src_regs[2]); newinst->tex_target = inst->tex_target; newinst->sampler_array_size = inst->sampler_array_size; } @@ -4091,16 +4424,16 @@ get_bitmap_visitor(struct st_fragment_program *fp, glsl_to_tgsi_instruction *newinst; st_src_reg src_regs[3]; - if (inst->dst.file == PROGRAM_OUTPUT) - prog->OutputsWritten |= BITFIELD64_BIT(inst->dst.index); + if (inst->dst[0].file == PROGRAM_OUTPUT) + prog->OutputsWritten |= BITFIELD64_BIT(inst->dst[0].index); - for (int i=0; i<3; i++) { + for (int i = 0; i < 3; i++) { src_regs[i] = inst->src[i]; if (src_regs[i].file == PROGRAM_INPUT) prog->InputsRead |= BITFIELD64_BIT(src_regs[i].index); } - newinst = v->emit(NULL, inst->op, inst->dst, src_regs[0], src_regs[1], src_regs[2]); + newinst = v->emit(NULL, inst->op, inst->dst[0], src_regs[0], src_regs[1], src_regs[2]); newinst->tex_target = inst->tex_target; newinst->sampler_array_size = inst->sampler_array_size; } @@ -4167,8 +4500,8 @@ const unsigned _mesa_sysval_to_semantic[SYSTEM_VALUE_MAX] = { */ TGSI_SEMANTIC_VERTEXID, TGSI_SEMANTIC_INSTANCEID, - 0, - 0, + TGSI_SEMANTIC_VERTEXID_NOBASE, + TGSI_SEMANTIC_BASEVERTEX, /* Geometry shader */ @@ -4194,7 +4527,7 @@ static unsigned *get_label(struct st_translate *t, unsigned branch_target) if (t->labels_count + 1 >= t->labels_size) { t->labels_size = 1 << (util_logbase2(t->labels_size) + 1); - t->labels = (struct label *)realloc(t->labels, + t->labels = (struct label *)realloc(t->labels, t->labels_size * sizeof(struct label)); if (t->labels == NULL) { static unsigned dummy; @@ -4242,6 +4575,8 @@ emit_immediate(struct st_translate *t, { case GL_FLOAT: return ureg_DECL_immediate(ureg, &values[0].f, size); + case GL_DOUBLE: + return ureg_DECL_immediate_f64(ureg, (double *)&values[0].f, size); case GL_INT: return ureg_DECL_immediate_int(ureg, &values[0].i, size); case GL_UNSIGNED_INT: @@ -4378,20 +4713,23 @@ translate_dst(struct st_translate *t, const st_dst_reg *dst_reg, bool saturate, bool clamp_color) { - struct ureg_dst dst = dst_register(t, + struct ureg_dst dst = dst_register(t, dst_reg->file, dst_reg->index); + if (dst.File == TGSI_FILE_NULL) + return dst; + dst = ureg_writemask(dst, dst_reg->writemask); - + if (saturate) dst = ureg_saturate(dst); else if (clamp_color && dst_reg->file == PROGRAM_OUTPUT) { /* Clamp colors for ARB_color_buffer_float. */ switch (t->procType) { case TGSI_PROCESSOR_VERTEX: - /* XXX if the geometry shader is present, this must be done there - * instead of here. */ + /* This can only occur with a compatibility profile, which doesn't + * support geometry shaders. */ if (dst_reg->index == VARYING_SLOT_COL0 || dst_reg->index == VARYING_SLOT_COL1 || dst_reg->index == VARYING_SLOT_BFC0 || @@ -4509,7 +4847,7 @@ compile_tgsi_instruction(struct st_translate *t, { struct ureg_program *ureg = t->ureg; GLuint i; - struct ureg_dst dst[1]; + struct ureg_dst dst[2]; struct ureg_src src[4]; struct tgsi_texture_offset texoffsets[MAX_GLSL_TEXTURE_OFFSET]; @@ -4520,9 +4858,9 @@ compile_tgsi_instruction(struct st_translate *t, num_dst = num_inst_dst_regs(inst->op); num_src = num_inst_src_regs(inst->op); - if (num_dst) - dst[0] = translate_dst(t, - &inst->dst, + for (i = 0; i < num_dst; i++) + dst[i] = translate_dst(t, + &inst->dst[i], inst->saturate, clamp_dst_color_output); @@ -4542,7 +4880,7 @@ compile_tgsi_instruction(struct st_translate *t, ureg_label_insn(ureg, inst->op, src, num_src, - get_label(t, + get_label(t, inst->op == TGSI_OPCODE_CAL ? inst->function->sig_id : 0)); return; @@ -4609,9 +4947,9 @@ emit_wpos_adjustment( struct st_translate *t, * where T = INPUT[WPOS] by y is inverted. */ static const gl_state_index wposTransformState[STATE_LENGTH] - = { STATE_INTERNAL, STATE_FB_WPOS_Y_TRANSFORM, + = { STATE_INTERNAL, STATE_FB_WPOS_Y_TRANSFORM, (gl_state_index)0, (gl_state_index)0, (gl_state_index)0 }; - + /* XXX: note we are modifying the incoming shader here! Need to * do this before emitting the constant decls below, or this * will be missed: @@ -4745,7 +5083,7 @@ emit_wpos(struct st_context *st, else assert(0); } - + if (fp->PixelCenterInteger) { /* Fragment shader wants pixel center integer */ if (pscreen->get_param(pscreen, PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER)) { @@ -4879,6 +5217,10 @@ st_translate_program( TGSI_SEMANTIC_SAMPLEMASK); assert(_mesa_sysval_to_semantic[SYSTEM_VALUE_INVOCATION_ID] == TGSI_SEMANTIC_INVOCATIONID); + assert(_mesa_sysval_to_semantic[SYSTEM_VALUE_VERTEX_ID_ZERO_BASE] == + TGSI_SEMANTIC_VERTEXID_NOBASE); + assert(_mesa_sysval_to_semantic[SYSTEM_VALUE_BASE_VERTEX] == + TGSI_SEMANTIC_BASEVERTEX); t = CALLOC_STRUCT(st_translate); if (!t) { @@ -4993,7 +5335,7 @@ st_translate_program( ureg_writemask(t->outputs[i], TGSI_WRITEMASK_YZW), ureg_imm4f(ureg, 0.0f, 0.0f, 0.0f, 1.0f)); t->outputs[i] = ureg_writemask(t->outputs[i], TGSI_WRITEMASK_X); - } + } } if (passthrough_edgeflags) emit_edgeflags(t); @@ -5045,7 +5387,7 @@ st_translate_program( */ memcpy(t->array_sizes, program->array_sizes, sizeof(unsigned) * program->next_array); - /* Emit constants and uniforms. TGSI uses a single index space for these, + /* Emit constants and uniforms. TGSI uses a single index space for these, * so we put all the translated regs in t->constants. */ if (proginfo->Parameters) { @@ -5097,7 +5439,7 @@ st_translate_program( ureg_DECL_constant2D(t->ureg, first, last, i + 1); } } - + /* Emit immediate values. */ t->immediates = (struct ureg_src *) @@ -5109,7 +5451,7 @@ st_translate_program( i = 0; foreach_in_list(immediate_storage, imm, &program->immediates) { assert(i < program->num_immediates); - t->immediates[i++] = emit_immediate(t, imm->values, imm->type, imm->size); + t->immediates[i++] = emit_immediate(t, imm->values, imm->type, imm->size32); } assert(i == program->num_immediates); @@ -5188,7 +5530,7 @@ shader_stage_to_ptarget(gl_shader_stage stage) /** - * Convert a shader's GLSL IR into a Mesa gl_program, although without + * Convert a shader's GLSL IR into a Mesa gl_program, although without * generating Mesa IR. */ static struct gl_program * @@ -5225,7 +5567,7 @@ get_mesa_program(struct gl_context *ctx, _mesa_copy_linked_program_data(shader->Stage, shader_program, prog); _mesa_generate_parameters_list_for_uniforms(shader_program, shader, - prog->Parameters); + prog->Parameters); /* Remove reads from output registers. */ lower_output_reads(shader->ir); @@ -5261,14 +5603,14 @@ get_mesa_program(struct gl_context *ctx, } while (progress); #if 0 - /* Print out some information (for debugging purposes) used by the + /* Print out some information (for debugging purposes) used by the * optimization passes. */ - for (i=0; i < v->next_temp; i++) { + for (i = 0; i < v->next_temp; i++) { int fr = v->get_first_temp_read(i); int fw = v->get_first_temp_write(i); int lr = v->get_last_temp_read(i); int lw = v->get_last_temp_write(i); - + printf("Temp %d: FR=%3d FW=%3d LR=%3d LW=%3d\n", i, fr, fw, lr, lw); assert(fw <= fr); } @@ -5279,9 +5621,10 @@ get_mesa_program(struct gl_context *ctx, v->copy_propagate(); while (v->eliminate_dead_code()); + v->merge_two_dsts(); v->merge_registers(); v->renumber_registers(); - + /* Write the END instruction. */ v->emit(NULL, TGSI_OPCODE_END); @@ -5303,7 +5646,7 @@ get_mesa_program(struct gl_context *ctx, count_resources(v, prog); _mesa_reference_program(ctx, &shader->Program, prog); - + /* This has to be done last. Any operation the can cause * prog->ParameterValues to get reallocated (e.g., anything that adds a * program constant) has to happen before creating this linkage. @@ -5316,7 +5659,7 @@ get_mesa_program(struct gl_context *ctx, struct st_vertex_program *stvp; struct st_fragment_program *stfp; struct st_geometry_program *stgp; - + switch (shader->Type) { case GL_VERTEX_SHADER: stvp = (struct st_vertex_program *)prog; @@ -5343,7 +5686,7 @@ extern "C" { /** * Link a shader. * Called via ctx->Driver.LinkShader() - * This actually involves converting GLSL IR into an intermediate TGSI-like IR + * This actually involves converting GLSL IR into an intermediate TGSI-like IR * with code lowering and other optimizations. */ GLboolean @@ -5358,8 +5701,14 @@ st_link_shader(struct gl_context *ctx, struct gl_shader_program *prog) bool progress; exec_list *ir = prog->_LinkedShaders[i]->ir; + gl_shader_stage stage = _mesa_shader_enum_to_shader_stage(prog->_LinkedShaders[i]->Type); const struct gl_shader_compiler_options *options = - &ctx->Const.ShaderCompilerOptions[_mesa_shader_enum_to_shader_stage(prog->_LinkedShaders[i]->Type)]; + &ctx->Const.ShaderCompilerOptions[stage]; + unsigned ptarget = shader_stage_to_ptarget(stage); + bool have_dround = pscreen->get_shader_param(pscreen, ptarget, + PIPE_SHADER_CAP_TGSI_DROUND_SUPPORTED); + bool have_dfrexp = pscreen->get_shader_param(pscreen, ptarget, + PIPE_SHADER_CAP_TGSI_DFRACEXP_DLDEXP_SUPPORTED); /* If there are forms of indirect addressing that the driver * cannot handle, perform the lowering pass. @@ -5391,20 +5740,19 @@ st_link_shader(struct gl_context *ctx, struct gl_shader_program *prog) if (!pscreen->get_param(pscreen, PIPE_CAP_TEXTURE_GATHER_OFFSETS)) lower_offset_arrays(ir); do_mat_op_to_vec(ir); - /* Emit saturates in the vertex shader only if SM 3.0 is supported. */ - bool vs_sm3 = (_mesa_shader_stage_to_program(prog->_LinkedShaders[i]->Stage) == - GL_VERTEX_PROGRAM_ARB) && st_context(ctx)->has_shader_model3; lower_instructions(ir, - MOD_TO_FRACT | + MOD_TO_FLOOR | DIV_TO_MUL_RCP | EXP_TO_EXP2 | LOG_TO_LOG2 | LDEXP_TO_ARITH | + (have_dfrexp ? 0 : DFREXP_DLDEXP_TO_ARITH) | CARRY_TO_ARITH | BORROW_TO_ARITH | + (have_dround ? 0 : DOPS_TO_DFRAC) | (options->EmitNoPow ? POW_TO_EXP2 : 0) | (!ctx->Const.NativeIntegers ? INT_DIV_TO_MUL_RCP : 0) | - (vs_sm3 ? SAT_TO_CLAMP : 0)); + (options->EmitNoSat ? SAT_TO_CLAMP : 0)); lower_ubo_reference(prog->_LinkedShaders[i], ir); do_vec_index_to_cond_assign(ir); @@ -5422,7 +5770,7 @@ st_link_shader(struct gl_context *ctx, struct gl_shader_program *prog) progress = do_common_optimization(ir, true, true, options, ctx->Const.NativeIntegers) - || progress; + || progress; progress = lower_if_to_cond_assign(ir, options->MaxIfDepth) || progress; @@ -5440,13 +5788,13 @@ st_link_shader(struct gl_context *ctx, struct gl_shader_program *prog) linked_prog = get_mesa_program(ctx, prog, prog->_LinkedShaders[i]); if (linked_prog) { - _mesa_reference_program(ctx, &prog->_LinkedShaders[i]->Program, - linked_prog); + _mesa_reference_program(ctx, &prog->_LinkedShaders[i]->Program, + linked_prog); if (!ctx->Driver.ProgramStringNotify(ctx, _mesa_shader_stage_to_program(i), linked_prog)) { - _mesa_reference_program(ctx, &prog->_LinkedShaders[i]->Program, - NULL); + _mesa_reference_program(ctx, &prog->_LinkedShaders[i]->Program, + NULL); _mesa_reference_program(ctx, &linked_prog, NULL); return GL_FALSE; } diff --git a/mesalib/src/mesa/state_tracker/st_manager.c b/mesalib/src/mesa/state_tracker/st_manager.c index 606d67891..5411d84b0 100644 --- a/mesalib/src/mesa/state_tracker/st_manager.c +++ b/mesalib/src/mesa/state_tracker/st_manager.c @@ -685,7 +685,7 @@ st_api_create_context(struct st_api *stapi, struct st_manager *smapi, if (attribs->major > 1 || attribs->minor > 0) { /* Is the actual version less than the requested version? */ - if (st->ctx->Version < attribs->major * 10 + attribs->minor) { + if (st->ctx->Version < attribs->major * 10U + attribs->minor) { *error = ST_CONTEXT_ERROR_BAD_VERSION; st_destroy_context(st); return NULL; diff --git a/mesalib/src/mesa/state_tracker/st_mesa_to_tgsi.c b/mesalib/src/mesa/state_tracker/st_mesa_to_tgsi.c index 2c9d9a523..3dd8a14b6 100644 --- a/mesalib/src/mesa/state_tracker/st_mesa_to_tgsi.c +++ b/mesalib/src/mesa/state_tracker/st_mesa_to_tgsi.c @@ -299,8 +299,8 @@ translate_dst( struct st_translate *t, /* Clamp colors for ARB_color_buffer_float. */ switch (t->procType) { case TGSI_PROCESSOR_VERTEX: - /* XXX if the geometry shader is present, this must be done there - * instead of here. */ + /* This can only occur with a compatibility profile, which doesn't + * support geometry shaders. */ if (DstReg->Index == VARYING_SLOT_COL0 || DstReg->Index == VARYING_SLOT_COL1 || DstReg->Index == VARYING_SLOT_BFC0 || diff --git a/mesalib/src/mesa/state_tracker/st_program.c b/mesalib/src/mesa/state_tracker/st_program.c index 737c2694e..10a5f2900 100644 --- a/mesalib/src/mesa/state_tracker/st_program.c +++ b/mesalib/src/mesa/state_tracker/st_program.c @@ -1095,7 +1095,7 @@ st_translate_geometry_program(struct st_context *st, /* find max output slot referenced to compute gs_num_outputs */ for (attr = 0; attr < VARYING_SLOT_MAX; attr++) { - if (outputMapping[attr] != ~0 && outputMapping[attr] > maxSlot) + if (outputMapping[attr] != ~0U && outputMapping[attr] > maxSlot) maxSlot = outputMapping[attr]; } gs_num_outputs = maxSlot + 1; diff --git a/mesalib/src/mesa/state_tracker/st_program.h b/mesalib/src/mesa/state_tracker/st_program.h index cf1b40a55..870d0d57a 100644 --- a/mesalib/src/mesa/state_tracker/st_program.h +++ b/mesalib/src/mesa/state_tracker/st_program.h @@ -41,6 +41,11 @@ #include "st_glsl_to_tgsi.h" +#ifdef __cplusplus +extern "C" { +#endif + + /** Fragment program variant key */ struct st_fp_variant_key { @@ -347,4 +352,8 @@ extern void st_print_current_vertex_program(void); +#ifdef __cplusplus +} +#endif + #endif diff --git a/mesalib/src/mesa/state_tracker/st_texture.h b/mesalib/src/mesa/state_tracker/st_texture.h index d66afcb56..2f540295f 100644 --- a/mesalib/src/mesa/state_tracker/st_texture.h +++ b/mesalib/src/mesa/state_tracker/st_texture.h @@ -123,6 +123,12 @@ st_texture_image(struct gl_texture_image *img) return (struct st_texture_image *) img; } +static INLINE const struct st_texture_image * +st_texture_image_const(const struct gl_texture_image *img) +{ + return (const struct st_texture_image *) img; +} + static INLINE struct st_texture_object * st_texture_object(struct gl_texture_object *obj) { diff --git a/mesalib/src/mesa/swrast/s_aaline.c b/mesalib/src/mesa/swrast/s_aaline.c index b4e05ff80..6aea9d545 100644 --- a/mesalib/src/mesa/swrast/s_aaline.c +++ b/mesalib/src/mesa/swrast/s_aaline.c @@ -27,6 +27,7 @@ #include "main/imports.h" #include "main/macros.h" #include "main/mtypes.h" +#include "main/teximage.h" #include "swrast/s_aaline.h" #include "swrast/s_context.h" #include "swrast/s_span.h" diff --git a/mesalib/src/mesa/swrast/s_aalinetemp.h b/mesalib/src/mesa/swrast/s_aalinetemp.h index 670b663bd..f1d078fd8 100644 --- a/mesalib/src/mesa/swrast/s_aalinetemp.h +++ b/mesalib/src/mesa/swrast/s_aalinetemp.h @@ -179,7 +179,8 @@ NAME(line)(struct gl_context *ctx, const SWvertex *v0, const SWvertex *v1) if (attr >= VARYING_SLOT_TEX0 && attr < VARYING_SLOT_VAR0) { const GLuint u = attr - VARYING_SLOT_TEX0; const struct gl_texture_object *obj = ctx->Texture.Unit[u]._Current; - const struct gl_texture_image *texImage = obj->Image[0][obj->BaseLevel]; + const struct gl_texture_image *texImage = + _mesa_base_tex_image(obj); line.texWidth[attr] = (GLfloat) texImage->Width; line.texHeight[attr] = (GLfloat) texImage->Height; } diff --git a/mesalib/src/mesa/swrast/s_blit.c b/mesalib/src/mesa/swrast/s_blit.c index e3b45f146..16e5b8c1c 100644 --- a/mesalib/src/mesa/swrast/s_blit.c +++ b/mesalib/src/mesa/swrast/s_blit.c @@ -107,14 +107,14 @@ RESAMPLE(resample_row_16, GLuint, 4) */ static void blit_nearest(struct gl_context *ctx, + struct gl_framebuffer *readFb, + struct gl_framebuffer *drawFb, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield buffer) { struct gl_renderbuffer *readRb, *drawRb = NULL; struct gl_renderbuffer_attachment *readAtt = NULL, *drawAtt = NULL; - struct gl_framebuffer *readFb = ctx->ReadBuffer; - struct gl_framebuffer *drawFb = ctx->DrawBuffer; GLuint numDrawBuffers = 0; GLuint i; @@ -508,11 +508,11 @@ resample_linear_row_float(GLint srcWidth, GLint dstWidth, */ static void blit_linear(struct gl_context *ctx, + struct gl_framebuffer *readFb, + struct gl_framebuffer *drawFb, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1) { - struct gl_framebuffer *drawFb = ctx->DrawBuffer; - struct gl_framebuffer *readFb = ctx->ReadBuffer; struct gl_renderbuffer *readRb = readFb->_ColorReadBuffer; struct gl_renderbuffer_attachment *readAtt = &readFb->Attachment[readFb->_ColorReadBufferIndex]; @@ -733,6 +733,8 @@ fail_no_memory: */ void _swrast_BlitFramebuffer(struct gl_context *ctx, + struct gl_framebuffer *readFb, + struct gl_framebuffer *drawFb, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) @@ -756,7 +758,7 @@ _swrast_BlitFramebuffer(struct gl_context *ctx, if (!_mesa_check_conditional_render(ctx)) return; /* Do not blit */ - if (!_mesa_clip_blit(ctx, &srcX0, &srcY0, &srcX1, &srcY1, + if (!_mesa_clip_blit(ctx, readFb, drawFb, &srcX0, &srcY0, &srcX1, &srcY1, &dstX0, &dstY0, &dstX1, &dstY1)) { return; } @@ -775,33 +777,34 @@ _swrast_BlitFramebuffer(struct gl_context *ctx, dstY0 < dstY1) { for (i = 0; i < 3; i++) { if (mask & buffers[i]) { - if (swrast_fast_copy_pixels(ctx, - srcX0, srcY0, - srcX1 - srcX0, srcY1 - srcY0, - dstX0, dstY0, - buffer_enums[i])) { - mask &= ~buffers[i]; - } - } + if (swrast_fast_copy_pixels(ctx, + readFb, drawFb, + srcX0, srcY0, + srcX1 - srcX0, srcY1 - srcY0, + dstX0, dstY0, + buffer_enums[i])) { + mask &= ~buffers[i]; + } + } } if (!mask) - return; + return; } if (filter == GL_NEAREST) { for (i = 0; i < 3; i++) { - if (mask & buffers[i]) { - blit_nearest(ctx, srcX0, srcY0, srcX1, srcY1, - dstX0, dstY0, dstX1, dstY1, buffers[i]); - } + if (mask & buffers[i]) { + blit_nearest(ctx, readFb, drawFb, srcX0, srcY0, srcX1, srcY1, + dstX0, dstY0, dstX1, dstY1, buffers[i]); + } } } else { ASSERT(filter == GL_LINEAR); if (mask & GL_COLOR_BUFFER_BIT) { /* depth/stencil not allowed */ - blit_linear(ctx, srcX0, srcY0, srcX1, srcY1, - dstX0, dstY0, dstX1, dstY1); + blit_linear(ctx, readFb, drawFb, srcX0, srcY0, srcX1, srcY1, + dstX0, dstY0, dstX1, dstY1); } } diff --git a/mesalib/src/mesa/swrast/s_copypix.c b/mesalib/src/mesa/swrast/s_copypix.c index d00173476..e21c69dbc 100644 --- a/mesalib/src/mesa/swrast/s_copypix.c +++ b/mesalib/src/mesa/swrast/s_copypix.c @@ -442,11 +442,11 @@ end: */ GLboolean swrast_fast_copy_pixels(struct gl_context *ctx, - GLint srcX, GLint srcY, GLsizei width, GLsizei height, - GLint dstX, GLint dstY, GLenum type) + struct gl_framebuffer *srcFb, + struct gl_framebuffer *dstFb, + GLint srcX, GLint srcY, GLsizei width, GLsizei height, + GLint dstX, GLint dstY, GLenum type) { - struct gl_framebuffer *srcFb = ctx->ReadBuffer; - struct gl_framebuffer *dstFb = ctx->DrawBuffer; struct gl_renderbuffer *srcRb, *dstRb; GLint row; GLuint pixelBytes, widthInBytes; @@ -620,9 +620,9 @@ map_readbuffer(struct gl_context *ctx, GLenum type) * By time we get here, all parameters will have been error-checked. */ void -_swrast_CopyPixels( struct gl_context *ctx, - GLint srcx, GLint srcy, GLsizei width, GLsizei height, - GLint destx, GLint desty, GLenum type ) +_swrast_CopyPixels(struct gl_context *ctx, + GLint srcx, GLint srcy, GLsizei width, GLsizei height, + GLint destx, GLint desty, GLenum type) { SWcontext *swrast = SWRAST_CONTEXT(ctx); struct gl_renderbuffer *rb; @@ -634,11 +634,12 @@ _swrast_CopyPixels( struct gl_context *ctx, _swrast_validate_derived( ctx ); if (!(SWRAST_CONTEXT(ctx)->_RasterMask != 0x0 || - ctx->Pixel.ZoomX != 1.0F || - ctx->Pixel.ZoomY != 1.0F || - ctx->_ImageTransferState) && - swrast_fast_copy_pixels(ctx, srcx, srcy, width, height, destx, desty, - type)) { + ctx->Pixel.ZoomX != 1.0F || + ctx->Pixel.ZoomY != 1.0F || + ctx->_ImageTransferState) && + swrast_fast_copy_pixels(ctx, ctx->ReadBuffer, ctx->DrawBuffer, + srcx, srcy, width, height, destx, desty, + type)) { /* all done */ return; } diff --git a/mesalib/src/mesa/swrast/s_drawpix.c b/mesalib/src/mesa/swrast/s_drawpix.c index f7926e426..c99251904 100644 --- a/mesalib/src/mesa/swrast/s_drawpix.c +++ b/mesalib/src/mesa/swrast/s_drawpix.c @@ -29,6 +29,8 @@ #include "main/condrender.h" #include "main/context.h" #include "main/format_pack.h" +#include "main/format_utils.h" +#include "main/glformats.h" #include "main/image.h" #include "main/imports.h" #include "main/macros.h" @@ -414,7 +416,6 @@ draw_rgba_pixels( struct gl_context *ctx, GLint x, GLint y, { const GLint imgX = x, imgY = y; const GLboolean zoom = ctx->Pixel.ZoomX!=1.0 || ctx->Pixel.ZoomY!=1.0; - GLfloat *convImage = NULL; GLbitfield transferOps = ctx->_ImageTransferState; SWspan span; @@ -452,6 +453,28 @@ draw_rgba_pixels( struct gl_context *ctx, GLint x, GLint y, GLint skipPixels = 0; /* use span array for temp color storage */ GLfloat *rgba = (GLfloat *) span.array->attribs[VARYING_SLOT_COL0]; + void *tempImage = NULL; + + if (unpack->SwapBytes) { + /* We have to handle byte-swapping scenarios before calling + * _mesa_format_convert + */ + GLint swapSize = _mesa_sizeof_packed_type(type); + if (swapSize == 2 || swapSize == 4) { + int components = _mesa_components_in_format(format); + int elementCount = width * height * components; + tempImage = malloc(elementCount * swapSize); + if (!tempImage) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glDrawPixels"); + return; + } + if (swapSize == 2) + _mesa_swap2_copy(tempImage, (GLushort *) pixels, elementCount); + else + _mesa_swap4_copy(tempImage, (GLuint *) pixels, elementCount); + pixels = tempImage; + } + } /* if the span is wider than SWRAST_MAX_WIDTH we have to do it in chunks */ while (skipPixels < width) { @@ -462,11 +485,15 @@ draw_rgba_pixels( struct gl_context *ctx, GLint x, GLint y, type, 0, skipPixels); GLint row; + /* get image row as float/RGBA */ + uint32_t srcMesaFormat = _mesa_format_from_format_and_type(format, type); for (row = 0; row < height; row++) { - /* get image row as float/RGBA */ - _mesa_unpack_color_span_float(ctx, spanWidth, GL_RGBA, rgba, - format, type, source, unpack, - transferOps); + int dstRowStride = 4 * width * sizeof(float); + _mesa_format_convert(rgba, RGBA32_FLOAT, dstRowStride, + (void*)source, srcMesaFormat, srcStride, + spanWidth, 1, NULL); + if (transferOps) + _mesa_apply_rgba_transfer_ops(ctx, transferOps, spanWidth, (GLfloat (*)[4])rgba); /* Set these for each row since the _swrast_write_* functions * may change them while clipping/rendering. */ @@ -491,9 +518,9 @@ draw_rgba_pixels( struct gl_context *ctx, GLint x, GLint y, /* XXX this is ugly/temporary, to undo above change */ span.array->ChanType = CHAN_TYPE; - } - free(convImage); + free(tempImage); + } swrast_render_finish(ctx); } diff --git a/mesalib/src/mesa/swrast/s_fragprog.c b/mesalib/src/mesa/swrast/s_fragprog.c index 21699f3ea..1d7c33619 100644 --- a/mesalib/src/mesa/swrast/s_fragprog.c +++ b/mesalib/src/mesa/swrast/s_fragprog.c @@ -25,6 +25,7 @@ #include "main/glheader.h" #include "main/colormac.h" #include "main/samplerobj.h" +#include "main/teximage.h" #include "program/prog_instruction.h" #include "s_context.h" @@ -116,8 +117,7 @@ fetch_texel_deriv( struct gl_context *ctx, const GLfloat texcoord[4], const struct gl_texture_object *texObj = texUnit->_Current; if (texObj) { - const struct gl_texture_image *texImg = - texObj->Image[0][texObj->BaseLevel]; + const struct gl_texture_image *texImg = _mesa_base_tex_image(texObj); const struct swrast_texture_image *swImg = swrast_texture_image_const(texImg); const struct gl_sampler_object *samp = _mesa_get_samplerobj(ctx, unit); diff --git a/mesalib/src/mesa/swrast/s_span.c b/mesalib/src/mesa/swrast/s_span.c index 10aa33c6f..321959df9 100644 --- a/mesalib/src/mesa/swrast/s_span.c +++ b/mesalib/src/mesa/swrast/s_span.c @@ -39,6 +39,7 @@ #include "main/imports.h" #include "main/image.h" #include "main/samplerobj.h" +#include "main/teximage.h" #include "s_atifragshader.h" #include "s_alpha.h" @@ -495,7 +496,7 @@ interpolate_texcoords(struct gl_context *ctx, SWspan *span) GLfloat q = span->attrStart[attr][3] + span->leftClip * dqdx; if (obj) { - const struct gl_texture_image *img = obj->Image[0][obj->BaseLevel]; + const struct gl_texture_image *img = _mesa_base_tex_image(obj); const struct swrast_texture_image *swImg = swrast_texture_image_const(img); const struct gl_sampler_object *samp = _mesa_get_samplerobj(ctx, u); @@ -932,19 +933,19 @@ clamp_colors(SWspan *span) * \param output which fragment program color output is being processed */ static inline void -convert_color_type(SWspan *span, GLenum newType, GLuint output) +convert_color_type(SWspan *span, GLenum srcType, GLenum newType, GLuint output) { GLvoid *src, *dst; - if (output > 0 || span->array->ChanType == GL_FLOAT) { + if (output > 0 || srcType == GL_FLOAT) { src = span->array->attribs[VARYING_SLOT_COL0 + output]; span->array->ChanType = GL_FLOAT; } - else if (span->array->ChanType == GL_UNSIGNED_BYTE) { + else if (srcType == GL_UNSIGNED_BYTE) { src = span->array->rgba8; } else { - ASSERT(span->array->ChanType == GL_UNSIGNED_SHORT); + ASSERT(srcType == GL_UNSIGNED_SHORT); src = span->array->rgba16; } @@ -978,7 +979,7 @@ shade_texture_span(struct gl_context *ctx, SWspan *span) ctx->ATIFragmentShader._Enabled) { /* programmable shading */ if (span->primitive == GL_BITMAP && span->array->ChanType != GL_FLOAT) { - convert_color_type(span, GL_FLOAT, 0); + convert_color_type(span, span->array->ChanType, GL_FLOAT, 0); } else { span->array->rgba = (void *) span->array->attribs[VARYING_SLOT_COL0]; @@ -1313,6 +1314,8 @@ _swrast_write_rgba_span( struct gl_context *ctx, SWspan *span) const GLboolean multiFragOutputs = _swrast_use_fragment_program(ctx) && fp->Base.OutputsWritten >= (1 << FRAG_RESULT_DATA0); + /* Save srcColorType because convert_color_type() can change it */ + const GLenum srcColorType = span->array->ChanType; GLuint buf; for (buf = 0; buf < numBuffers; buf++) { @@ -1324,17 +1327,18 @@ _swrast_write_rgba_span( struct gl_context *ctx, SWspan *span) /* re-use one of the attribute array buffers for rgbaSave */ GLchan (*rgbaSave)[4] = (GLchan (*)[4]) span->array->attribs[0]; struct swrast_renderbuffer *srb = swrast_renderbuffer(rb); - GLenum colorType = srb->ColorType; + const GLenum dstColorType = srb->ColorType; - assert(colorType == GL_UNSIGNED_BYTE || - colorType == GL_FLOAT); + assert(dstColorType == GL_UNSIGNED_BYTE || + dstColorType == GL_FLOAT); /* set span->array->rgba to colors for renderbuffer's datatype */ - if (span->array->ChanType != colorType) { - convert_color_type(span, colorType, 0); + if (srcColorType != dstColorType) { + convert_color_type(span, srcColorType, dstColorType, + multiFragOutputs ? buf : 0); } else { - if (span->array->ChanType == GL_UNSIGNED_BYTE) { + if (srcColorType == GL_UNSIGNED_BYTE) { span->array->rgba = span->array->rgba8; } else { diff --git a/mesalib/src/mesa/swrast/s_texfetch.c b/mesalib/src/mesa/swrast/s_texfetch.c index 0f6da919d..9629024b9 100644 --- a/mesalib/src/mesa/swrast/s_texfetch.c +++ b/mesalib/src/mesa/swrast/s_texfetch.c @@ -166,6 +166,8 @@ texfetch_funcs[] = FETCH_FUNCS(B10G10R10A2_UNORM), FETCH_NULL(B10G10R10X2_UNORM), FETCH_FUNCS(R10G10B10A2_UNORM), + FETCH_NULL(R10G10B10X2_UNORM), + FETCH_FUNCS(S8_UINT_Z24_UNORM), { MESA_FORMAT_X8_UINT_Z24_UNORM, @@ -180,6 +182,13 @@ texfetch_funcs[] = fetch_texel_2d_Z24_UNORM_S8_UINT, fetch_texel_3d_Z24_UNORM_S8_UINT }, + FETCH_NULL(R3G3B2_UNORM), + FETCH_NULL(A4B4G4R4_UNORM), + FETCH_NULL(R4G4B4A4_UNORM), + FETCH_NULL(R5G5B5A1_UNORM), + FETCH_NULL(A2B10G10R10_UNORM), + FETCH_NULL(A2R10G10B10_UNORM), + FETCH_FUNCS(YCBCR), FETCH_FUNCS(YCBCR_REV), @@ -276,6 +285,8 @@ texfetch_funcs[] = /* Packed signed/unsigned non-normalized integer formats */ FETCH_NULL(B10G10R10A2_UINT), FETCH_NULL(R10G10B10A2_UINT), + FETCH_NULL(A2B10G10R10_UINT), + FETCH_NULL(A2R10G10B10_UINT), /* Array signed/unsigned non-normalized integer formats */ FETCH_NULL(A_UINT8), diff --git a/mesalib/src/mesa/swrast/s_texfetch_tmp.h b/mesalib/src/mesa/swrast/s_texfetch_tmp.h index 7ff30f6b4..45bd83950 100644 --- a/mesalib/src/mesa/swrast/s_texfetch_tmp.h +++ b/mesalib/src/mesa/swrast/s_texfetch_tmp.h @@ -39,6 +39,7 @@ * \author Brian Paul */ +#include #if DIM == 1 @@ -68,1244 +69,128 @@ #error illegal number of texture dimensions #endif - -static void -FETCH(Z_UNORM32)(const struct swrast_texture_image *texImage, - GLint i, GLint j, GLint k, GLfloat *texel) -{ - const GLuint *src = TEXEL_ADDR(GLuint, texImage, i, j, k, 1); - texel[0] = src[0] * (1.0F / 0xffffffff); -} - - -static void -FETCH(Z_UNORM16)(const struct swrast_texture_image *texImage, - GLint i, GLint j, GLint k, GLfloat *texel) -{ - const GLushort *src = TEXEL_ADDR(GLushort, texImage, i, j, k, 1); - texel[0] = src[0] * (1.0F / 65535.0F); -} - - -static void -FETCH(RGBA_FLOAT32)(const struct swrast_texture_image *texImage, - GLint i, GLint j, GLint k, GLfloat *texel) -{ - const GLfloat *src = TEXEL_ADDR(GLfloat, texImage, i, j, k, 4); - texel[RCOMP] = src[0]; - texel[GCOMP] = src[1]; - texel[BCOMP] = src[2]; - texel[ACOMP] = src[3]; -} - - -static void -FETCH(RGBA_FLOAT16)(const struct swrast_texture_image *texImage, - GLint i, GLint j, GLint k, GLfloat *texel) -{ - const GLhalfARB *src = TEXEL_ADDR(GLhalfARB, texImage, i, j, k, 4); - texel[RCOMP] = _mesa_half_to_float(src[0]); - texel[GCOMP] = _mesa_half_to_float(src[1]); - texel[BCOMP] = _mesa_half_to_float(src[2]); - texel[ACOMP] = _mesa_half_to_float(src[3]); -} - - -static void -FETCH(RGB_FLOAT32)(const struct swrast_texture_image *texImage, - GLint i, GLint j, GLint k, GLfloat *texel) -{ - const GLfloat *src = TEXEL_ADDR(GLfloat, texImage, i, j, k, 3); - texel[RCOMP] = src[0]; - texel[GCOMP] = src[1]; - texel[BCOMP] = src[2]; - texel[ACOMP] = 1.0F; -} - - -static void -FETCH(RGB_FLOAT16)(const struct swrast_texture_image *texImage, - GLint i, GLint j, GLint k, GLfloat *texel) -{ - const GLhalfARB *src = TEXEL_ADDR(GLhalfARB, texImage, i, j, k, 3); - texel[RCOMP] = _mesa_half_to_float(src[0]); - texel[GCOMP] = _mesa_half_to_float(src[1]); - texel[BCOMP] = _mesa_half_to_float(src[2]); - texel[ACOMP] = 1.0F; -} - - -static void -FETCH(A_FLOAT32)(const struct swrast_texture_image *texImage, - GLint i, GLint j, GLint k, GLfloat *texel) -{ - const GLfloat *src = TEXEL_ADDR(GLfloat, texImage, i, j, k, 1); - texel[RCOMP] = - texel[GCOMP] = - texel[BCOMP] = 0.0F; - texel[ACOMP] = src[0]; -} - - -static void -FETCH(A_FLOAT16)(const struct swrast_texture_image *texImage, - GLint i, GLint j, GLint k, GLfloat *texel) -{ - const GLhalfARB *src = TEXEL_ADDR(GLhalfARB, texImage, i, j, k, 1); - texel[RCOMP] = - texel[GCOMP] = - texel[BCOMP] = 0.0F; - texel[ACOMP] = _mesa_half_to_float(src[0]); -} - - -static void -FETCH(L_FLOAT32)(const struct swrast_texture_image *texImage, - GLint i, GLint j, GLint k, GLfloat *texel) -{ - const GLfloat *src = TEXEL_ADDR(GLfloat, texImage, i, j, k, 1); - texel[RCOMP] = - texel[GCOMP] = - texel[BCOMP] = src[0]; - texel[ACOMP] = 1.0F; -} - - -static void -FETCH(L_FLOAT16)(const struct swrast_texture_image *texImage, - GLint i, GLint j, GLint k, GLfloat *texel) -{ - const GLhalfARB *src = TEXEL_ADDR(GLhalfARB, texImage, i, j, k, 1); - texel[RCOMP] = - texel[GCOMP] = - texel[BCOMP] = _mesa_half_to_float(src[0]); - texel[ACOMP] = 1.0F; -} - - -static void -FETCH(LA_FLOAT32)(const struct swrast_texture_image *texImage, - GLint i, GLint j, GLint k, GLfloat *texel) -{ - const GLfloat *src = TEXEL_ADDR(GLfloat, texImage, i, j, k, 2); - texel[RCOMP] = - texel[GCOMP] = - texel[BCOMP] = src[0]; - texel[ACOMP] = src[1]; -} - - -static void -FETCH(LA_FLOAT16)(const struct swrast_texture_image *texImage, - GLint i, GLint j, GLint k, GLfloat *texel) -{ - const GLhalfARB *src = TEXEL_ADDR(GLhalfARB, texImage, i, j, k, 2); - texel[RCOMP] = - texel[GCOMP] = - texel[BCOMP] = _mesa_half_to_float(src[0]); - texel[ACOMP] = _mesa_half_to_float(src[1]); -} - - -static void -FETCH(I_FLOAT32)(const struct swrast_texture_image *texImage, - GLint i, GLint j, GLint k, GLfloat *texel) -{ - const GLfloat *src = TEXEL_ADDR(GLfloat, texImage, i, j, k, 1); - texel[RCOMP] = - texel[GCOMP] = - texel[BCOMP] = - texel[ACOMP] = src[0]; -} - - -static void -FETCH(I_FLOAT16)(const struct swrast_texture_image *texImage, - GLint i, GLint j, GLint k, GLfloat *texel) -{ - const GLhalfARB *src = TEXEL_ADDR(GLhalfARB, texImage, i, j, k, 1); - texel[RCOMP] = - texel[GCOMP] = - texel[BCOMP] = - texel[ACOMP] = _mesa_half_to_float(src[0]); -} - - -static void -FETCH(R_FLOAT32)(const struct swrast_texture_image *texImage, - GLint i, GLint j, GLint k, GLfloat *texel) -{ - const GLfloat *src = TEXEL_ADDR(GLfloat, texImage, i, j, k, 1); - texel[RCOMP] = src[0]; - texel[GCOMP] = 0.0F; - texel[BCOMP] = 0.0F; - texel[ACOMP] = 1.0F; -} - - -static void -FETCH(R_FLOAT16)(const struct swrast_texture_image *texImage, - GLint i, GLint j, GLint k, GLfloat *texel) -{ - const GLhalfARB *src = TEXEL_ADDR(GLhalfARB, texImage, i, j, k, 1); - texel[RCOMP] = _mesa_half_to_float(src[0]); - texel[GCOMP] = 0.0F; - texel[BCOMP] = 0.0F; - texel[ACOMP] = 1.0F; -} - - -static void -FETCH(RG_FLOAT32)(const struct swrast_texture_image *texImage, - GLint i, GLint j, GLint k, GLfloat *texel) -{ - const GLfloat *src = TEXEL_ADDR(GLfloat, texImage, i, j, k, 2); - texel[RCOMP] = src[0]; - texel[GCOMP] = src[1]; - texel[BCOMP] = 0.0F; - texel[ACOMP] = 1.0F; -} - - -static void -FETCH(RG_FLOAT16)(const struct swrast_texture_image *texImage, - GLint i, GLint j, GLint k, GLfloat *texel) -{ - const GLhalfARB *src = TEXEL_ADDR(GLhalfARB, texImage, i, j, k, 2); - texel[RCOMP] = _mesa_half_to_float(src[0]); - texel[GCOMP] = _mesa_half_to_float(src[1]); - texel[BCOMP] = 0.0F; - texel[ACOMP] = 1.0F; -} - - -static void -FETCH(A8B8G8R8_UNORM)(const struct swrast_texture_image *texImage, - GLint i, GLint j, GLint k, GLfloat *texel) -{ - const GLuint s = *TEXEL_ADDR(GLuint, texImage, i, j, k, 1); - texel[RCOMP] = UBYTE_TO_FLOAT( (s >> 24) ); - texel[GCOMP] = UBYTE_TO_FLOAT( (s >> 16) & 0xff ); - texel[BCOMP] = UBYTE_TO_FLOAT( (s >> 8) & 0xff ); - texel[ACOMP] = UBYTE_TO_FLOAT( (s ) & 0xff ); -} - - -static void -FETCH(R8G8B8A8_UNORM)(const struct swrast_texture_image *texImage, - GLint i, GLint j, GLint k, GLfloat *texel) -{ - const GLuint s = *TEXEL_ADDR(GLuint, texImage, i, j, k, 1); - texel[RCOMP] = UBYTE_TO_FLOAT( (s ) & 0xff ); - texel[GCOMP] = UBYTE_TO_FLOAT( (s >> 8) & 0xff ); - texel[BCOMP] = UBYTE_TO_FLOAT( (s >> 16) & 0xff ); - texel[ACOMP] = UBYTE_TO_FLOAT( (s >> 24) ); -} - - -static void -FETCH(B8G8R8A8_UNORM)(const struct swrast_texture_image *texImage, - GLint i, GLint j, GLint k, GLfloat *texel) -{ - const GLuint s = *TEXEL_ADDR(GLuint, texImage, i, j, k, 1); - texel[RCOMP] = UBYTE_TO_FLOAT( (s >> 16) & 0xff ); - texel[GCOMP] = UBYTE_TO_FLOAT( (s >> 8) & 0xff ); - texel[BCOMP] = UBYTE_TO_FLOAT( (s ) & 0xff ); - texel[ACOMP] = UBYTE_TO_FLOAT( (s >> 24) ); -} - - -static void -FETCH(A8R8G8B8_UNORM)(const struct swrast_texture_image *texImage, - GLint i, GLint j, GLint k, GLfloat *texel) -{ - const GLuint s = *TEXEL_ADDR(GLuint, texImage, i, j, k, 1); - texel[RCOMP] = UBYTE_TO_FLOAT( (s >> 8) & 0xff ); - texel[GCOMP] = UBYTE_TO_FLOAT( (s >> 16) & 0xff ); - texel[BCOMP] = UBYTE_TO_FLOAT( (s >> 24) ); - texel[ACOMP] = UBYTE_TO_FLOAT( (s ) & 0xff ); -} - - -static void -FETCH(X8B8G8R8_UNORM)(const struct swrast_texture_image *texImage, - GLint i, GLint j, GLint k, GLfloat *texel) -{ - const GLuint s = *TEXEL_ADDR(GLuint, texImage, i, j, k, 1); - texel[RCOMP] = UBYTE_TO_FLOAT( (s >> 24) ); - texel[GCOMP] = UBYTE_TO_FLOAT( (s >> 16) & 0xff ); - texel[BCOMP] = UBYTE_TO_FLOAT( (s >> 8) & 0xff ); - texel[ACOMP] = 1.0f; -} - - -static void -FETCH(R8G8B8X8_UNORM)(const struct swrast_texture_image *texImage, - GLint i, GLint j, GLint k, GLfloat *texel) -{ - const GLuint s = *TEXEL_ADDR(GLuint, texImage, i, j, k, 1); - texel[RCOMP] = UBYTE_TO_FLOAT( (s ) & 0xff ); - texel[GCOMP] = UBYTE_TO_FLOAT( (s >> 8) & 0xff ); - texel[BCOMP] = UBYTE_TO_FLOAT( (s >> 16) & 0xff ); - texel[ACOMP] = 1.0f; -} - - -static void -FETCH(B8G8R8X8_UNORM)(const struct swrast_texture_image *texImage, - GLint i, GLint j, GLint k, GLfloat *texel) -{ - const GLuint s = *TEXEL_ADDR(GLuint, texImage, i, j, k, 1); - texel[RCOMP] = UBYTE_TO_FLOAT( (s >> 16) & 0xff ); - texel[GCOMP] = UBYTE_TO_FLOAT( (s >> 8) & 0xff ); - texel[BCOMP] = UBYTE_TO_FLOAT( (s ) & 0xff ); - texel[ACOMP] = 1.0f; -} - - -static void -FETCH(X8R8G8B8_UNORM)(const struct swrast_texture_image *texImage, - GLint i, GLint j, GLint k, GLfloat *texel) -{ - const GLuint s = *TEXEL_ADDR(GLuint, texImage, i, j, k, 1); - texel[RCOMP] = UBYTE_TO_FLOAT( (s >> 8) & 0xff ); - texel[GCOMP] = UBYTE_TO_FLOAT( (s >> 16) & 0xff ); - texel[BCOMP] = UBYTE_TO_FLOAT( (s >> 24) ); - texel[ACOMP] = 1.0f; -} - - -static void -FETCH(BGR_UNORM8)(const struct swrast_texture_image *texImage, - GLint i, GLint j, GLint k, GLfloat *texel) -{ - const GLubyte *src = TEXEL_ADDR(GLubyte, texImage, i, j, k, 3); - texel[RCOMP] = UBYTE_TO_FLOAT( src[2] ); - texel[GCOMP] = UBYTE_TO_FLOAT( src[1] ); - texel[BCOMP] = UBYTE_TO_FLOAT( src[0] ); - texel[ACOMP] = 1.0F; -} - - -static void -FETCH(RGB_UNORM8)(const struct swrast_texture_image *texImage, - GLint i, GLint j, GLint k, GLfloat *texel) -{ - const GLubyte *src = TEXEL_ADDR(GLubyte, texImage, i, j, k, 3); - texel[RCOMP] = UBYTE_TO_FLOAT( src[0] ); - texel[GCOMP] = UBYTE_TO_FLOAT( src[1] ); - texel[BCOMP] = UBYTE_TO_FLOAT( src[2] ); - texel[ACOMP] = 1.0F; -} - - -static void -FETCH(B5G6R5_UNORM)(const struct swrast_texture_image *texImage, - GLint i, GLint j, GLint k, GLfloat *texel) -{ - const GLushort *src = TEXEL_ADDR(GLushort, texImage, i, j, k, 1); - const GLushort s = *src; - texel[RCOMP] = ((s >> 11) & 0x1f) * (1.0F / 31.0F); - texel[GCOMP] = ((s >> 5 ) & 0x3f) * (1.0F / 63.0F); - texel[BCOMP] = ((s ) & 0x1f) * (1.0F / 31.0F); - texel[ACOMP] = 1.0F; -} - - -static void -FETCH(R5G6B5_UNORM)(const struct swrast_texture_image *texImage, - GLint i, GLint j, GLint k, GLfloat *texel) -{ - const GLushort *src = TEXEL_ADDR(GLushort, texImage, i, j, k, 1); - const GLushort s = (*src >> 8) | (*src << 8); /* byte swap */ - texel[RCOMP] = UBYTE_TO_FLOAT( ((s >> 8) & 0xf8) | ((s >> 13) & 0x7) ); - texel[GCOMP] = UBYTE_TO_FLOAT( ((s >> 3) & 0xfc) | ((s >> 9) & 0x3) ); - texel[BCOMP] = UBYTE_TO_FLOAT( ((s << 3) & 0xf8) | ((s >> 2) & 0x7) ); - texel[ACOMP] = 1.0F; -} - - -static void -FETCH(B4G4R4A4_UNORM)(const struct swrast_texture_image *texImage, - GLint i, GLint j, GLint k, GLfloat *texel) -{ - const GLushort *src = TEXEL_ADDR(GLushort, texImage, i, j, k, 1); - const GLushort s = *src; - texel[RCOMP] = ((s >> 8) & 0xf) * (1.0F / 15.0F); - texel[GCOMP] = ((s >> 4) & 0xf) * (1.0F / 15.0F); - texel[BCOMP] = ((s ) & 0xf) * (1.0F / 15.0F); - texel[ACOMP] = ((s >> 12) & 0xf) * (1.0F / 15.0F); -} - - -static void -FETCH(A4R4G4B4_UNORM)(const struct swrast_texture_image *texImage, - GLint i, GLint j, GLint k, GLfloat *texel) -{ - const GLushort s = *TEXEL_ADDR(GLushort, texImage, i, j, k, 1); - texel[RCOMP] = ((s >> 4) & 0xf) * (1.0F / 15.0F); - texel[GCOMP] = ((s >> 8) & 0xf) * (1.0F / 15.0F); - texel[BCOMP] = ((s >> 12) & 0xf) * (1.0F / 15.0F); - texel[ACOMP] = ((s ) & 0xf) * (1.0F / 15.0F); -} - - -static void -FETCH(A1B5G5R5_UNORM)(const struct swrast_texture_image *texImage, - GLint i, GLint j, GLint k, GLfloat *texel) -{ - const GLushort *src = TEXEL_ADDR(GLushort, texImage, i, j, k, 1); - const GLushort s = *src; - texel[RCOMP] = ((s >> 11) & 0x1f) * (1.0F / 31.0F); - texel[GCOMP] = ((s >> 6) & 0x1f) * (1.0F / 31.0F); - texel[BCOMP] = ((s >> 1) & 0x1f) * (1.0F / 31.0F); - texel[ACOMP] = ((s ) & 0x01) * 1.0F; -} - - -static void -FETCH(B5G5R5A1_UNORM)(const struct swrast_texture_image *texImage, - GLint i, GLint j, GLint k, GLfloat *texel) -{ - const GLushort *src = TEXEL_ADDR(GLushort, texImage, i, j, k, 1); - const GLushort s = *src; - texel[RCOMP] = ((s >> 10) & 0x1f) * (1.0F / 31.0F); - texel[GCOMP] = ((s >> 5) & 0x1f) * (1.0F / 31.0F); - texel[BCOMP] = ((s >> 0) & 0x1f) * (1.0F / 31.0F); - texel[ACOMP] = ((s >> 15) & 0x01) * 1.0F; -} - - -static void -FETCH(A1R5G5B5_UNORM)(const struct swrast_texture_image *texImage, - GLint i, GLint j, GLint k, GLfloat *texel) -{ - const GLushort *src = TEXEL_ADDR(GLushort, texImage, i, j, k, 1); - const GLushort s = (*src << 8) | (*src >> 8); /* byteswap */ - texel[RCOMP] = UBYTE_TO_FLOAT( ((s >> 7) & 0xf8) | ((s >> 12) & 0x7) ); - texel[GCOMP] = UBYTE_TO_FLOAT( ((s >> 2) & 0xf8) | ((s >> 7) & 0x7) ); - texel[BCOMP] = UBYTE_TO_FLOAT( ((s << 3) & 0xf8) | ((s >> 2) & 0x7) ); - texel[ACOMP] = UBYTE_TO_FLOAT( ((s >> 15) & 0x01) * 255 ); -} - - -static void -FETCH(B10G10R10A2_UNORM)(const struct swrast_texture_image *texImage, - GLint i, GLint j, GLint k, GLfloat *texel) -{ - const GLuint *src = TEXEL_ADDR(GLuint, texImage, i, j, k, 1); - const GLuint s = *src; - texel[RCOMP] = ((s >> 20) & 0x3ff) * (1.0F / 1023.0F); - texel[GCOMP] = ((s >> 10) & 0x3ff) * (1.0F / 1023.0F); - texel[BCOMP] = ((s >> 0) & 0x3ff) * (1.0F / 1023.0F); - texel[ACOMP] = ((s >> 30) & 0x03) * (1.0F / 3.0F); -} - - -static void -FETCH(R10G10B10A2_UNORM)(const struct swrast_texture_image *texImage, - GLint i, GLint j, GLint k, GLfloat *texel) -{ - const GLuint *src = TEXEL_ADDR(GLuint, texImage, i, j, k, 1); - const GLuint s = *src; - texel[RCOMP] = ((s >> 0) & 0x3ff) * (1.0F / 1023.0F); - texel[GCOMP] = ((s >> 10) & 0x3ff) * (1.0F / 1023.0F); - texel[BCOMP] = ((s >> 20) & 0x3ff) * (1.0F / 1023.0F); - texel[ACOMP] = ((s >> 30) & 0x03) * (1.0F / 3.0F); -} - - -static void -FETCH(R8G8_UNORM)(const struct swrast_texture_image *texImage, - GLint i, GLint j, GLint k, GLfloat *texel) -{ - const GLushort s = *TEXEL_ADDR(GLushort, texImage, i, j, k, 1); - texel[RCOMP] = UBYTE_TO_FLOAT( s & 0xff ); - texel[GCOMP] = UBYTE_TO_FLOAT( s >> 8 ); - texel[BCOMP] = 0.0; - texel[ACOMP] = 1.0; -} - - -static void -FETCH(G8R8_UNORM)(const struct swrast_texture_image *texImage, - GLint i, GLint j, GLint k, GLfloat *texel) -{ - const GLushort s = *TEXEL_ADDR(GLushort, texImage, i, j, k, 1); - texel[RCOMP] = UBYTE_TO_FLOAT( s >> 8 ); - texel[GCOMP] = UBYTE_TO_FLOAT( s & 0xff ); - texel[BCOMP] = 0.0; - texel[ACOMP] = 1.0; -} - - -static void -FETCH(L4A4_UNORM)(const struct swrast_texture_image *texImage, - GLint i, GLint j, GLint k, GLfloat *texel) -{ - const GLubyte s = *TEXEL_ADDR(GLubyte, texImage, i, j, k, 1); - texel[RCOMP] = - texel[GCOMP] = - texel[BCOMP] = (s & 0xf) * (1.0F / 15.0F); - texel[ACOMP] = ((s >> 4) & 0xf) * (1.0F / 15.0F); -} - - -static void -FETCH(L8A8_UNORM)(const struct swrast_texture_image *texImage, - GLint i, GLint j, GLint k, GLfloat *texel) -{ - const GLushort s = *TEXEL_ADDR(GLushort, texImage, i, j, k, 1); - texel[RCOMP] = - texel[GCOMP] = - texel[BCOMP] = UBYTE_TO_FLOAT( s & 0xff ); - texel[ACOMP] = UBYTE_TO_FLOAT( s >> 8 ); -} - - -static void -FETCH(R_UNORM8)(const struct swrast_texture_image *texImage, - GLint i, GLint j, GLint k, GLfloat *texel) -{ - const GLubyte s = *TEXEL_ADDR(GLubyte, texImage, i, j, k, 1); - texel[RCOMP] = UBYTE_TO_FLOAT(s); - texel[GCOMP] = 0.0; - texel[BCOMP] = 0.0; - texel[ACOMP] = 1.0; -} - - -static void -FETCH(R_UNORM16)(const struct swrast_texture_image *texImage, - GLint i, GLint j, GLint k, GLfloat *texel) -{ - const GLushort s = *TEXEL_ADDR(GLushort, texImage, i, j, k, 1); - texel[RCOMP] = USHORT_TO_FLOAT(s); - texel[GCOMP] = 0.0; - texel[BCOMP] = 0.0; - texel[ACOMP] = 1.0; -} - - -static void -FETCH(A8L8_UNORM)(const struct swrast_texture_image *texImage, - GLint i, GLint j, GLint k, GLfloat *texel) -{ - const GLushort s = *TEXEL_ADDR(GLushort, texImage, i, j, k, 1); - texel[RCOMP] = - texel[GCOMP] = - texel[BCOMP] = UBYTE_TO_FLOAT( s >> 8 ); - texel[ACOMP] = UBYTE_TO_FLOAT( s & 0xff ); -} - - -static void -FETCH(R16G16_UNORM)(const struct swrast_texture_image *texImage, - GLint i, GLint j, GLint k, GLfloat *texel) -{ - const GLuint s = *TEXEL_ADDR(GLuint, texImage, i, j, k, 1); - texel[RCOMP] = USHORT_TO_FLOAT( s & 0xffff ); - texel[GCOMP] = USHORT_TO_FLOAT( s >> 16 ); - texel[BCOMP] = 0.0; - texel[ACOMP] = 1.0; -} - - -static void -FETCH(G16R16_UNORM)(const struct swrast_texture_image *texImage, - GLint i, GLint j, GLint k, GLfloat *texel) -{ - const GLuint s = *TEXEL_ADDR(GLuint, texImage, i, j, k, 1); - texel[RCOMP] = USHORT_TO_FLOAT( s >> 16 ); - texel[GCOMP] = USHORT_TO_FLOAT( s & 0xffff ); - texel[BCOMP] = 0.0; - texel[ACOMP] = 1.0; -} - - -static void -FETCH(L16A16_UNORM)(const struct swrast_texture_image *texImage, - GLint i, GLint j, GLint k, GLfloat *texel) -{ - const GLuint s = *TEXEL_ADDR(GLuint, texImage, i, j, k, 1); - texel[RCOMP] = - texel[GCOMP] = - texel[BCOMP] = USHORT_TO_FLOAT( s & 0xffff ); - texel[ACOMP] = USHORT_TO_FLOAT( s >> 16 ); -} - - -static void -FETCH(A16L16_UNORM)(const struct swrast_texture_image *texImage, - GLint i, GLint j, GLint k, GLfloat *texel) -{ - const GLuint s = *TEXEL_ADDR(GLuint, texImage, i, j, k, 1); - texel[RCOMP] = - texel[GCOMP] = - texel[BCOMP] = USHORT_TO_FLOAT( s >> 16 ); - texel[ACOMP] = USHORT_TO_FLOAT( s & 0xffff ); -} - - -static void -FETCH(B2G3R3_UNORM)(const struct swrast_texture_image *texImage, - GLint i, GLint j, GLint k, GLfloat *texel) -{ - const GLubyte *src = TEXEL_ADDR(GLubyte, texImage, i, j, k, 1); - const GLubyte s = *src; - texel[RCOMP] = ((s >> 5) & 0x7) * (1.0F / 7.0F); - texel[GCOMP] = ((s >> 2) & 0x7) * (1.0F / 7.0F); - texel[BCOMP] = ((s ) & 0x3) * (1.0F / 3.0F); - texel[ACOMP] = 1.0F; -} - - -static void -FETCH(A_UNORM8)(const struct swrast_texture_image *texImage, - GLint i, GLint j, GLint k, GLfloat *texel) -{ - const GLubyte *src = TEXEL_ADDR(GLubyte, texImage, i, j, k, 1); - texel[RCOMP] = - texel[GCOMP] = - texel[BCOMP] = 0.0F; - texel[ACOMP] = UBYTE_TO_FLOAT( src[0] ); -} - - -static void -FETCH(A_UNORM16)(const struct swrast_texture_image *texImage, - GLint i, GLint j, GLint k, GLfloat *texel) -{ - const GLushort *src = TEXEL_ADDR(GLushort, texImage, i, j, k, 1); - texel[RCOMP] = - texel[GCOMP] = - texel[BCOMP] = 0.0F; - texel[ACOMP] = USHORT_TO_FLOAT( src[0] ); -} - - -static void -FETCH(L_UNORM8)(const struct swrast_texture_image *texImage, - GLint i, GLint j, GLint k, GLfloat *texel) -{ - const GLubyte *src = TEXEL_ADDR(GLubyte, texImage, i, j, k, 1); - texel[RCOMP] = - texel[GCOMP] = - texel[BCOMP] = UBYTE_TO_FLOAT( src[0] ); - texel[ACOMP] = 1.0F; -} - - -static void -FETCH(L_UNORM16)(const struct swrast_texture_image *texImage, - GLint i, GLint j, GLint k, GLfloat *texel) -{ - const GLushort *src = TEXEL_ADDR(GLushort, texImage, i, j, k, 1); - texel[RCOMP] = - texel[GCOMP] = - texel[BCOMP] = USHORT_TO_FLOAT( src[0] ); - texel[ACOMP] = 1.0F; -} - - -static void -FETCH(I_UNORM8)(const struct swrast_texture_image *texImage, - GLint i, GLint j, GLint k, GLfloat *texel) -{ - const GLubyte *src = TEXEL_ADDR(GLubyte, texImage, i, j, k, 1); - texel[RCOMP] = - texel[GCOMP] = - texel[BCOMP] = - texel[ACOMP] = UBYTE_TO_FLOAT( src[0] ); -} - - -static void -FETCH(I_UNORM16)(const struct swrast_texture_image *texImage, - GLint i, GLint j, GLint k, GLfloat *texel) -{ - const GLushort *src = TEXEL_ADDR(GLushort, texImage, i, j, k, 1); - texel[RCOMP] = - texel[GCOMP] = - texel[BCOMP] = - texel[ACOMP] = USHORT_TO_FLOAT( src[0] ); -} - - -static void -FETCH(BGR_SRGB8)(const struct swrast_texture_image *texImage, - GLint i, GLint j, GLint k, GLfloat *texel) -{ - const GLubyte *src = TEXEL_ADDR(GLubyte, texImage, i, j, k, 3); - texel[RCOMP] = util_format_srgb_8unorm_to_linear_float(src[2]); - texel[GCOMP] = util_format_srgb_8unorm_to_linear_float(src[1]); - texel[BCOMP] = util_format_srgb_8unorm_to_linear_float(src[0]); - texel[ACOMP] = 1.0F; -} - - -static void -FETCH(A8B8G8R8_SRGB)(const struct swrast_texture_image *texImage, - GLint i, GLint j, GLint k, GLfloat *texel) -{ - const GLuint s = *TEXEL_ADDR(GLuint, texImage, i, j, k, 1); - texel[RCOMP] = util_format_srgb_8unorm_to_linear_float( (s >> 24) ); - texel[GCOMP] = util_format_srgb_8unorm_to_linear_float( (s >> 16) & 0xff ); - texel[BCOMP] = util_format_srgb_8unorm_to_linear_float( (s >> 8) & 0xff ); - texel[ACOMP] = UBYTE_TO_FLOAT( (s ) & 0xff ); /* linear! */ -} - - -static void -FETCH(B8G8R8A8_SRGB)(const struct swrast_texture_image *texImage, - GLint i, GLint j, GLint k, GLfloat *texel) -{ - const GLuint s = *TEXEL_ADDR(GLuint, texImage, i, j, k, 1); - texel[RCOMP] = util_format_srgb_8unorm_to_linear_float( (s >> 16) & 0xff ); - texel[GCOMP] = util_format_srgb_8unorm_to_linear_float( (s >> 8) & 0xff ); - texel[BCOMP] = util_format_srgb_8unorm_to_linear_float( (s ) & 0xff ); - texel[ACOMP] = UBYTE_TO_FLOAT( (s >> 24) ); /* linear! */ -} - - -static void -FETCH(A8R8G8B8_SRGB)(const struct swrast_texture_image *texImage, - GLint i, GLint j, GLint k, GLfloat *texel) -{ - const GLuint s = *TEXEL_ADDR(GLuint, texImage, i, j, k, 1); - texel[RCOMP] = util_format_srgb_8unorm_to_linear_float( (s >> 8) & 0xff ); - texel[GCOMP] = util_format_srgb_8unorm_to_linear_float( (s >> 16) & 0xff ); - texel[BCOMP] = util_format_srgb_8unorm_to_linear_float( (s >> 24) ); - texel[ACOMP] = UBYTE_TO_FLOAT( s & 0xff ); /* linear! */ -} - - -static void -FETCH(R8G8B8A8_SRGB)(const struct swrast_texture_image *texImage, - GLint i, GLint j, GLint k, GLfloat *texel) -{ - const GLuint s = *TEXEL_ADDR(GLuint, texImage, i, j, k, 1); - texel[RCOMP] = util_format_srgb_8unorm_to_linear_float( (s ) & 0xff ); - texel[GCOMP] = util_format_srgb_8unorm_to_linear_float( (s >> 8) & 0xff ); - texel[BCOMP] = util_format_srgb_8unorm_to_linear_float( (s >> 16) & 0xff ); - texel[ACOMP] = UBYTE_TO_FLOAT( (s >> 24) ); /* linear! */ -} - - -static void -FETCH(R8G8B8X8_SRGB)(const struct swrast_texture_image *texImage, - GLint i, GLint j, GLint k, GLfloat *texel) -{ - const GLuint s = *TEXEL_ADDR(GLuint, texImage, i, j, k, 1); - texel[RCOMP] = util_format_srgb_8unorm_to_linear_float( (s ) & 0xff ); - texel[GCOMP] = util_format_srgb_8unorm_to_linear_float( (s >> 8) & 0xff ); - texel[BCOMP] = util_format_srgb_8unorm_to_linear_float( (s >> 16) & 0xff ); - texel[ACOMP] = 1.0f; -} - - -static void -FETCH(X8B8G8R8_SRGB)(const struct swrast_texture_image *texImage, - GLint i, GLint j, GLint k, GLfloat *texel) -{ - const GLuint s = *TEXEL_ADDR(GLuint, texImage, i, j, k, 1); - texel[RCOMP] = util_format_srgb_8unorm_to_linear_float( (s >> 24) ); - texel[GCOMP] = util_format_srgb_8unorm_to_linear_float( (s >> 16) & 0xff ); - texel[BCOMP] = util_format_srgb_8unorm_to_linear_float( (s >> 8) & 0xff ); - texel[ACOMP] = 1.0f; -} - - -static void -FETCH(L_SRGB8)(const struct swrast_texture_image *texImage, - GLint i, GLint j, GLint k, GLfloat *texel) -{ - const GLubyte *src = TEXEL_ADDR(GLubyte, texImage, i, j, k, 1); - texel[RCOMP] = - texel[GCOMP] = - texel[BCOMP] = util_format_srgb_8unorm_to_linear_float(src[0]); - texel[ACOMP] = 1.0F; -} - - -static void -FETCH(L8A8_SRGB)(const struct swrast_texture_image *texImage, - GLint i, GLint j, GLint k, GLfloat *texel) -{ - const GLushort s = *TEXEL_ADDR(GLushort, texImage, i, j, k, 1); - texel[RCOMP] = - texel[GCOMP] = - texel[BCOMP] = util_format_srgb_8unorm_to_linear_float(s & 0xff); - texel[ACOMP] = UBYTE_TO_FLOAT(s >> 8); /* linear */ -} - - -static void -FETCH(A8L8_SRGB)(const struct swrast_texture_image *texImage, - GLint i, GLint j, GLint k, GLfloat *texel) -{ - const GLushort s = *TEXEL_ADDR(GLushort, texImage, i, j, k, 2); - texel[RCOMP] = - texel[GCOMP] = - texel[BCOMP] = util_format_srgb_8unorm_to_linear_float(s >> 8); - texel[ACOMP] = UBYTE_TO_FLOAT(s & 0xff); /* linear */ -} - - -static void -FETCH(RGBA_SINT8)(const struct swrast_texture_image *texImage, - GLint i, GLint j, GLint k, GLfloat *texel) -{ - const GLbyte *src = TEXEL_ADDR(GLbyte, texImage, i, j, k, 4); - texel[RCOMP] = (GLfloat) src[0]; - texel[GCOMP] = (GLfloat) src[1]; - texel[BCOMP] = (GLfloat) src[2]; - texel[ACOMP] = (GLfloat) src[3]; -} - - -static void -FETCH(RGBA_SINT16)(const struct swrast_texture_image *texImage, - GLint i, GLint j, GLint k, GLfloat *texel) -{ - const GLshort *src = TEXEL_ADDR(GLshort, texImage, i, j, k, 4); - texel[RCOMP] = (GLfloat) src[0]; - texel[GCOMP] = (GLfloat) src[1]; - texel[BCOMP] = (GLfloat) src[2]; - texel[ACOMP] = (GLfloat) src[3]; -} - - -static void -FETCH(RGBA_SINT32)(const struct swrast_texture_image *texImage, - GLint i, GLint j, GLint k, GLfloat *texel) -{ - const GLint *src = TEXEL_ADDR(GLint, texImage, i, j, k, 4); - texel[RCOMP] = (GLfloat) src[0]; - texel[GCOMP] = (GLfloat) src[1]; - texel[BCOMP] = (GLfloat) src[2]; - texel[ACOMP] = (GLfloat) src[3]; -} - - -static void -FETCH(RGBA_UINT8)(const struct swrast_texture_image *texImage, - GLint i, GLint j, GLint k, GLfloat *texel) -{ - const GLubyte *src = TEXEL_ADDR(GLubyte, texImage, i, j, k, 4); - texel[RCOMP] = (GLfloat) src[0]; - texel[GCOMP] = (GLfloat) src[1]; - texel[BCOMP] = (GLfloat) src[2]; - texel[ACOMP] = (GLfloat) src[3]; -} - - -static void -FETCH(RGBA_UINT16)(const struct swrast_texture_image *texImage, - GLint i, GLint j, GLint k, GLfloat *texel) -{ - const GLushort *src = TEXEL_ADDR(GLushort, texImage, i, j, k, 4); - texel[RCOMP] = (GLfloat) src[0]; - texel[GCOMP] = (GLfloat) src[1]; - texel[BCOMP] = (GLfloat) src[2]; - texel[ACOMP] = (GLfloat) src[3]; -} - - -static void -FETCH(RGBA_UINT32)(const struct swrast_texture_image *texImage, - GLint i, GLint j, GLint k, GLfloat *texel) -{ - const GLuint *src = TEXEL_ADDR(GLuint, texImage, i, j, k, 4); - texel[RCOMP] = (GLfloat) src[0]; - texel[GCOMP] = (GLfloat) src[1]; - texel[BCOMP] = (GLfloat) src[2]; - texel[ACOMP] = (GLfloat) src[3]; -} - - -static void -FETCH(R_SNORM8)(const struct swrast_texture_image *texImage, - GLint i, GLint j, GLint k, GLfloat *texel) -{ - const GLbyte s = *TEXEL_ADDR(GLbyte, texImage, i, j, k, 1); - texel[RCOMP] = BYTE_TO_FLOAT_TEX( s ); - texel[GCOMP] = 0.0F; - texel[BCOMP] = 0.0F; - texel[ACOMP] = 1.0F; -} - - -static void -FETCH(A_SNORM8)(const struct swrast_texture_image *texImage, - GLint i, GLint j, GLint k, GLfloat *texel) -{ - const GLbyte s = *TEXEL_ADDR(GLbyte, texImage, i, j, k, 1); - texel[RCOMP] = 0.0F; - texel[GCOMP] = 0.0F; - texel[BCOMP] = 0.0F; - texel[ACOMP] = BYTE_TO_FLOAT_TEX( s ); -} - - -static void -FETCH(L_SNORM8)(const struct swrast_texture_image *texImage, - GLint i, GLint j, GLint k, GLfloat *texel) -{ - const GLbyte s = *TEXEL_ADDR(GLbyte, texImage, i, j, k, 1); - texel[RCOMP] = - texel[GCOMP] = - texel[BCOMP] = BYTE_TO_FLOAT_TEX( s ); - texel[ACOMP] = 1.0F; -} - - -static void -FETCH(I_SNORM8)(const struct swrast_texture_image *texImage, - GLint i, GLint j, GLint k, GLfloat *texel) -{ - const GLbyte s = *TEXEL_ADDR(GLbyte, texImage, i, j, k, 1); - texel[RCOMP] = - texel[GCOMP] = - texel[BCOMP] = - texel[ACOMP] = BYTE_TO_FLOAT_TEX( s ); -} - - -static void -FETCH(R8G8_SNORM)(const struct swrast_texture_image *texImage, - GLint i, GLint j, GLint k, GLfloat *texel) -{ - const GLushort s = *TEXEL_ADDR(GLshort, texImage, i, j, k, 1); - texel[RCOMP] = BYTE_TO_FLOAT_TEX( (GLbyte) (s & 0xff) ); - texel[GCOMP] = BYTE_TO_FLOAT_TEX( (GLbyte) (s >> 8) ); - texel[BCOMP] = 0.0F; - texel[ACOMP] = 1.0F; -} - - -static void -FETCH(L8A8_SNORM)(const struct swrast_texture_image *texImage, - GLint i, GLint j, GLint k, GLfloat *texel) -{ - const GLushort s = *TEXEL_ADDR(GLshort, texImage, i, j, k, 1); - texel[RCOMP] = - texel[GCOMP] = - texel[BCOMP] = BYTE_TO_FLOAT_TEX( (GLbyte) (s & 0xff) ); - texel[ACOMP] = BYTE_TO_FLOAT_TEX( (GLbyte) (s >> 8) ); -} - - -static void -FETCH(A8L8_SNORM)(const struct swrast_texture_image *texImage, - GLint i, GLint j, GLint k, GLfloat *texel) -{ - const GLushort s = *TEXEL_ADDR(GLshort, texImage, i, j, k, 1); - texel[RCOMP] = - texel[GCOMP] = - texel[BCOMP] = BYTE_TO_FLOAT_TEX( (GLbyte) (s >> 8) ); - texel[ACOMP] = BYTE_TO_FLOAT_TEX( (GLbyte) (s & 0xff) ); -} - - -static void -FETCH(X8B8G8R8_SNORM)(const struct swrast_texture_image *texImage, - GLint i, GLint j, GLint k, GLfloat *texel) -{ - const GLuint s = *TEXEL_ADDR(GLuint, texImage, i, j, k, 1); - texel[RCOMP] = BYTE_TO_FLOAT_TEX( (GLbyte) (s >> 24) ); - texel[GCOMP] = BYTE_TO_FLOAT_TEX( (GLbyte) (s >> 16) ); - texel[BCOMP] = BYTE_TO_FLOAT_TEX( (GLbyte) (s >> 8) ); - texel[ACOMP] = 1.0f; -} - - -static void -FETCH(A8B8G8R8_SNORM)(const struct swrast_texture_image *texImage, - GLint i, GLint j, GLint k, GLfloat *texel) -{ - const GLuint s = *TEXEL_ADDR(GLuint, texImage, i, j, k, 1); - texel[RCOMP] = BYTE_TO_FLOAT_TEX( (GLbyte) (s >> 24) ); - texel[GCOMP] = BYTE_TO_FLOAT_TEX( (GLbyte) (s >> 16) ); - texel[BCOMP] = BYTE_TO_FLOAT_TEX( (GLbyte) (s >> 8) ); - texel[ACOMP] = BYTE_TO_FLOAT_TEX( (GLbyte) (s ) ); -} - - -static void -FETCH(R8G8B8A8_SNORM)(const struct swrast_texture_image *texImage, - GLint i, GLint j, GLint k, GLfloat *texel) -{ - const GLuint s = *TEXEL_ADDR(GLuint, texImage, i, j, k, 1); - texel[RCOMP] = BYTE_TO_FLOAT_TEX( (GLbyte) (s ) ); - texel[GCOMP] = BYTE_TO_FLOAT_TEX( (GLbyte) (s >> 8) ); - texel[BCOMP] = BYTE_TO_FLOAT_TEX( (GLbyte) (s >> 16) ); - texel[ACOMP] = BYTE_TO_FLOAT_TEX( (GLbyte) (s >> 24) ); -} - - -static void -FETCH(R_SNORM16)(const struct swrast_texture_image *texImage, - GLint i, GLint j, GLint k, GLfloat *texel) -{ - const GLshort s = *TEXEL_ADDR(GLshort, texImage, i, j, k, 1); - texel[RCOMP] = SHORT_TO_FLOAT_TEX( s ); - texel[GCOMP] = 0.0F; - texel[BCOMP] = 0.0F; - texel[ACOMP] = 1.0F; -} - - -static void -FETCH(A_SNORM16)(const struct swrast_texture_image *texImage, - GLint i, GLint j, GLint k, GLfloat *texel) -{ - const GLshort s = *TEXEL_ADDR(GLshort, texImage, i, j, k, 1); - texel[RCOMP] = 0.0F; - texel[GCOMP] = 0.0F; - texel[BCOMP] = 0.0F; - texel[ACOMP] = SHORT_TO_FLOAT_TEX( s ); -} - - -static void -FETCH(L_SNORM16)(const struct swrast_texture_image *texImage, - GLint i, GLint j, GLint k, GLfloat *texel) -{ - const GLshort s = *TEXEL_ADDR(GLshort, texImage, i, j, k, 1); - texel[RCOMP] = - texel[GCOMP] = - texel[BCOMP] = SHORT_TO_FLOAT_TEX( s ); - texel[ACOMP] = 1.0F; -} - - -static void -FETCH(I_SNORM16)(const struct swrast_texture_image *texImage, - GLint i, GLint j, GLint k, GLfloat *texel) -{ - const GLshort s = *TEXEL_ADDR(GLshort, texImage, i, j, k, 1); - texel[RCOMP] = - texel[GCOMP] = - texel[BCOMP] = - texel[ACOMP] = SHORT_TO_FLOAT_TEX( s ); -} - - -static void -FETCH(R16G16_SNORM)(const struct swrast_texture_image *texImage, - GLint i, GLint j, GLint k, GLfloat *texel) -{ - const GLshort *s = TEXEL_ADDR(GLshort, texImage, i, j, k, 2); - texel[RCOMP] = SHORT_TO_FLOAT_TEX( s[0] ); - texel[GCOMP] = SHORT_TO_FLOAT_TEX( s[1] ); - texel[BCOMP] = 0.0F; - texel[ACOMP] = 1.0F; -} - - -static void -FETCH(LA_SNORM16)(const struct swrast_texture_image *texImage, - GLint i, GLint j, GLint k, GLfloat *texel) -{ - const GLshort *s = TEXEL_ADDR(GLshort, texImage, i, j, k, 2); - texel[RCOMP] = - texel[GCOMP] = - texel[BCOMP] = SHORT_TO_FLOAT_TEX( s[0] ); - texel[ACOMP] = SHORT_TO_FLOAT_TEX( s[1] ); -} - - -static void - -FETCH(RGB_SNORM16)(const struct swrast_texture_image *texImage, - GLint i, GLint j, GLint k, GLfloat *texel) -{ - const GLshort *s = TEXEL_ADDR(GLshort, texImage, i, j, k, 3); - texel[RCOMP] = SHORT_TO_FLOAT_TEX( s[0] ); - texel[GCOMP] = SHORT_TO_FLOAT_TEX( s[1] ); - texel[BCOMP] = SHORT_TO_FLOAT_TEX( s[2] ); - texel[ACOMP] = 1.0F; -} - - -static void -FETCH(RGBA_SNORM16)(const struct swrast_texture_image *texImage, - GLint i, GLint j, GLint k, GLfloat *texel) -{ - const GLshort *s = TEXEL_ADDR(GLshort, texImage, i, j, k, 4); - texel[RCOMP] = SHORT_TO_FLOAT_TEX( s[0] ); - texel[GCOMP] = SHORT_TO_FLOAT_TEX( s[1] ); - texel[BCOMP] = SHORT_TO_FLOAT_TEX( s[2] ); - texel[ACOMP] = SHORT_TO_FLOAT_TEX( s[3] ); -} - - -static void -FETCH(RGBA_UNORM16)(const struct swrast_texture_image *texImage, - GLint i, GLint j, GLint k, GLfloat *texel) -{ - const GLushort *s = TEXEL_ADDR(GLushort, texImage, i, j, k, 4); - texel[RCOMP] = USHORT_TO_FLOAT( s[0] ); - texel[GCOMP] = USHORT_TO_FLOAT( s[1] ); - texel[BCOMP] = USHORT_TO_FLOAT( s[2] ); - texel[ACOMP] = USHORT_TO_FLOAT( s[3] ); -} - - -static void -FETCH(RGBX_UNORM16)(const struct swrast_texture_image *texImage, - GLint i, GLint j, GLint k, GLfloat *texel) -{ - const GLushort *s = TEXEL_ADDR(GLushort, texImage, i, j, k, 4); - texel[RCOMP] = USHORT_TO_FLOAT(s[0]); - texel[GCOMP] = USHORT_TO_FLOAT(s[1]); - texel[BCOMP] = USHORT_TO_FLOAT(s[2]); - texel[ACOMP] = 1.0f; -} - - -static void -FETCH(RGBX_FLOAT16)(const struct swrast_texture_image *texImage, - GLint i, GLint j, GLint k, GLfloat *texel) -{ - const GLhalfARB *s = TEXEL_ADDR(GLhalfARB, texImage, i, j, k, 4); - texel[RCOMP] = _mesa_half_to_float(s[0]); - texel[GCOMP] = _mesa_half_to_float(s[1]); - texel[BCOMP] = _mesa_half_to_float(s[2]); - texel[ACOMP] = 1.0f; -} - - -static void -FETCH(RGBX_FLOAT32)(const struct swrast_texture_image *texImage, - GLint i, GLint j, GLint k, GLfloat *texel) -{ - const GLfloat *s = TEXEL_ADDR(GLfloat, texImage, i, j, k, 4); - texel[RCOMP] = s[0]; - texel[GCOMP] = s[1]; - texel[BCOMP] = s[2]; - texel[ACOMP] = 1.0f; -} - - -/** - * Fetch texel from 1D, 2D or 3D ycbcr texture, returning RGBA. - */ -static void -FETCH(YCBCR)(const struct swrast_texture_image *texImage, - GLint i, GLint j, GLint k, GLfloat *texel) -{ - const GLushort *src0 = TEXEL_ADDR(GLushort, texImage, (i & ~1), j, k, 1); /* even */ - const GLushort *src1 = src0 + 1; /* odd */ - const GLubyte y0 = (*src0 >> 8) & 0xff; /* luminance */ - const GLubyte cb = *src0 & 0xff; /* chroma U */ - const GLubyte y1 = (*src1 >> 8) & 0xff; /* luminance */ - const GLubyte cr = *src1 & 0xff; /* chroma V */ - const GLubyte y = (i & 1) ? y1 : y0; /* choose even/odd luminance */ - GLfloat r = 1.164F * (y - 16) + 1.596F * (cr - 128); - GLfloat g = 1.164F * (y - 16) - 0.813F * (cr - 128) - 0.391F * (cb - 128); - GLfloat b = 1.164F * (y - 16) + 2.018F * (cb - 128); - r *= (1.0F / 255.0F); - g *= (1.0F / 255.0F); - b *= (1.0F / 255.0F); - texel[RCOMP] = CLAMP(r, 0.0F, 1.0F); - texel[GCOMP] = CLAMP(g, 0.0F, 1.0F); - texel[BCOMP] = CLAMP(b, 0.0F, 1.0F); - texel[ACOMP] = 1.0F; -} - - -/** - * Fetch texel from 1D, 2D or 3D ycbcr texture, returning RGBA. - */ -static void -FETCH(YCBCR_REV)(const struct swrast_texture_image *texImage, - GLint i, GLint j, GLint k, GLfloat *texel) -{ - const GLushort *src0 = TEXEL_ADDR(GLushort, texImage, (i & ~1), j, k, 1); /* even */ - const GLushort *src1 = src0 + 1; /* odd */ - const GLubyte y0 = *src0 & 0xff; /* luminance */ - const GLubyte cr = (*src0 >> 8) & 0xff; /* chroma V */ - const GLubyte y1 = *src1 & 0xff; /* luminance */ - const GLubyte cb = (*src1 >> 8) & 0xff; /* chroma U */ - const GLubyte y = (i & 1) ? y1 : y0; /* choose even/odd luminance */ - GLfloat r = 1.164F * (y - 16) + 1.596F * (cr - 128); - GLfloat g = 1.164F * (y - 16) - 0.813F * (cr - 128) - 0.391F * (cb - 128); - GLfloat b = 1.164F * (y - 16) + 2.018F * (cb - 128); - r *= (1.0F / 255.0F); - g *= (1.0F / 255.0F); - b *= (1.0F / 255.0F); - texel[RCOMP] = CLAMP(r, 0.0F, 1.0F); - texel[GCOMP] = CLAMP(g, 0.0F, 1.0F); - texel[BCOMP] = CLAMP(b, 0.0F, 1.0F); - texel[ACOMP] = 1.0F; -} - - -static void -FETCH(S8_UINT_Z24_UNORM)(const struct swrast_texture_image *texImage, - GLint i, GLint j, GLint k, GLfloat *texel) -{ - /* only return Z, not stencil data */ - const GLuint *src = TEXEL_ADDR(GLuint, texImage, i, j, k, 1); - const GLdouble scale = 1.0 / (GLdouble) 0xffffff; - texel[0] = (GLfloat) (((*src) >> 8) * scale); - ASSERT(texImage->Base.TexFormat == MESA_FORMAT_S8_UINT_Z24_UNORM || - texImage->Base.TexFormat == MESA_FORMAT_X8_UINT_Z24_UNORM); - ASSERT(texel[0] >= 0.0F); - ASSERT(texel[0] <= 1.0F); -} - - -static void -FETCH(Z24_UNORM_S8_UINT)(const struct swrast_texture_image *texImage, - GLint i, GLint j, GLint k, GLfloat *texel) -{ - /* only return Z, not stencil data */ - const GLuint *src = TEXEL_ADDR(GLuint, texImage, i, j, k, 1); - const GLdouble scale = 1.0 / (GLdouble) 0xffffff; - texel[0] = (GLfloat) (((*src) & 0x00ffffff) * scale); - ASSERT(texImage->Base.TexFormat == MESA_FORMAT_Z24_UNORM_S8_UINT || - texImage->Base.TexFormat == MESA_FORMAT_Z24_UNORM_X8_UINT); - ASSERT(texel[0] >= 0.0F); - ASSERT(texel[0] <= 1.0F); -} - - -static void -FETCH(R9G9B9E5_FLOAT)(const struct swrast_texture_image *texImage, - GLint i, GLint j, GLint k, GLfloat *texel) -{ - const GLuint *src = TEXEL_ADDR(GLuint, texImage, i, j, k, 1); - rgb9e5_to_float3(*src, texel); - texel[ACOMP] = 1.0F; -} - - -static void -FETCH(R11G11B10_FLOAT)(const struct swrast_texture_image *texImage, - GLint i, GLint j, GLint k, GLfloat *texel) -{ - const GLuint *src = TEXEL_ADDR(GLuint, texImage, i, j, k, 1); - r11g11b10f_to_float3(*src, texel); - texel[ACOMP] = 1.0F; -} - - -static void -FETCH(Z32_FLOAT_S8X24_UINT)(const struct swrast_texture_image *texImage, - GLint i, GLint j, GLint k, GLfloat *texel) -{ - const GLfloat *src = TEXEL_ADDR(GLfloat, texImage, i, j, k, 2); - texel[RCOMP] = src[0]; - texel[GCOMP] = 0.0F; - texel[BCOMP] = 0.0F; - texel[ACOMP] = 1.0F; -} - - +#define FETCH_Z(x, type, size) \ + static void \ + FETCH(x) (const struct swrast_texture_image *texImage, \ + GLint i, GLint j, GLint k, GLfloat *texel) \ + { \ + const type *src = TEXEL_ADDR(type, texImage, i, j, k, size); \ + _mesa_unpack_float_z_row(MESA_FORMAT_##x, 1, src, texel); \ + } + +#define FETCH_RGBA(x, type, size) \ + static void \ + FETCH(x) (const struct swrast_texture_image *texImage, \ + GLint i, GLint j, GLint k, GLfloat *texel) \ + { \ + const type *src = TEXEL_ADDR(type, texImage, i, j, k, size); \ + _mesa_unpack_rgba_row(MESA_FORMAT_##x, 1, src, (GLvoid *)texel); \ + } + +FETCH_Z(Z_UNORM32, GLuint, 1) +FETCH_Z(Z_UNORM16, GLushort, 1) +FETCH_Z(S8_UINT_Z24_UNORM, GLuint, 1) /* only return Z, not stencil data */ +FETCH_Z(Z24_UNORM_S8_UINT, GLuint, 1) /* only return Z, not stencil data */ +FETCH_Z(Z32_FLOAT_S8X24_UINT, GLfloat, 2) + +FETCH_RGBA(RGBA_FLOAT32, GLfloat, 4) +FETCH_RGBA(RGBA_FLOAT16, GLhalfARB, 4) +FETCH_RGBA(RGB_FLOAT32, GLfloat, 3) +FETCH_RGBA(RGB_FLOAT16, GLhalfARB, 3) +FETCH_RGBA(A_FLOAT32, GLfloat, 1) +FETCH_RGBA(A_FLOAT16, GLhalfARB, 1) +FETCH_RGBA(L_FLOAT32, GLfloat, 1) +FETCH_RGBA(L_FLOAT16, GLhalfARB, 1) +FETCH_RGBA(LA_FLOAT32, GLfloat, 2) +FETCH_RGBA(LA_FLOAT16, GLhalfARB, 2) +FETCH_RGBA(I_FLOAT32, GLfloat, 1) +FETCH_RGBA(I_FLOAT16, GLhalfARB, 1) +FETCH_RGBA(R_FLOAT32, GLfloat, 1) +FETCH_RGBA(R_FLOAT16, GLhalfARB, 1) +FETCH_RGBA(RG_FLOAT32, GLfloat, 2) +FETCH_RGBA(RG_FLOAT16, GLhalfARB, 2) +FETCH_RGBA(A8B8G8R8_UNORM, GLuint, 1) +FETCH_RGBA(R8G8B8A8_UNORM, GLuint, 1) +FETCH_RGBA(B8G8R8A8_UNORM, GLuint, 1) +FETCH_RGBA(A8R8G8B8_UNORM, GLuint, 1) +FETCH_RGBA(X8B8G8R8_UNORM, GLuint, 1) +FETCH_RGBA(R8G8B8X8_UNORM, GLuint, 1) +FETCH_RGBA(B8G8R8X8_UNORM, GLuint, 1) +FETCH_RGBA(X8R8G8B8_UNORM, GLuint, 1) +FETCH_RGBA(BGR_UNORM8, GLubyte, 3) +FETCH_RGBA(RGB_UNORM8, GLubyte, 3) +FETCH_RGBA(B5G6R5_UNORM, GLushort, 1) +FETCH_RGBA(R5G6B5_UNORM, GLushort, 1) +FETCH_RGBA(B4G4R4A4_UNORM, GLushort, 1) +FETCH_RGBA(A4R4G4B4_UNORM, GLushort, 1) +FETCH_RGBA(A1B5G5R5_UNORM, GLushort, 1) +FETCH_RGBA(B5G5R5A1_UNORM, GLushort, 1) +FETCH_RGBA(A1R5G5B5_UNORM, GLushort, 1) +FETCH_RGBA(B10G10R10A2_UNORM, GLuint, 1) +FETCH_RGBA(R10G10B10A2_UNORM, GLuint, 1) +FETCH_RGBA(R8G8_UNORM, GLushort, 1) +FETCH_RGBA(G8R8_UNORM, GLushort, 1) +FETCH_RGBA(L4A4_UNORM, GLubyte, 1) +FETCH_RGBA(L8A8_UNORM, GLushort, 1) +FETCH_RGBA(R_UNORM8, GLubyte, 1) +FETCH_RGBA(R_UNORM16, GLushort, 1) +FETCH_RGBA(A8L8_UNORM, GLushort, 1) +FETCH_RGBA(R16G16_UNORM, GLuint, 1) +FETCH_RGBA(G16R16_UNORM, GLuint, 1) +FETCH_RGBA(L16A16_UNORM, GLuint, 1) +FETCH_RGBA(A16L16_UNORM, GLuint, 1) +FETCH_RGBA(B2G3R3_UNORM, GLubyte, 1) +FETCH_RGBA(A_UNORM8, GLubyte, 1) +FETCH_RGBA(A_UNORM16, GLushort, 1) +FETCH_RGBA(L_UNORM8, GLubyte, 1) +FETCH_RGBA(L_UNORM16, GLushort, 1) +FETCH_RGBA(I_UNORM8, GLubyte, 1) +FETCH_RGBA(I_UNORM16, GLushort, 1) +FETCH_RGBA(BGR_SRGB8, GLubyte, 3) +FETCH_RGBA(A8B8G8R8_SRGB, GLuint, 1) +FETCH_RGBA(B8G8R8A8_SRGB, GLuint, 1) +FETCH_RGBA(A8R8G8B8_SRGB, GLuint, 1) +FETCH_RGBA(R8G8B8A8_SRGB, GLuint, 1) +FETCH_RGBA(R8G8B8X8_SRGB, GLuint, 1) +FETCH_RGBA(X8B8G8R8_SRGB, GLuint, 1) +FETCH_RGBA(L_SRGB8, GLubyte, 1) +FETCH_RGBA(L8A8_SRGB, GLushort, 1) +FETCH_RGBA(A8L8_SRGB, GLushort, 2) +FETCH_RGBA(RGBA_SINT8, GLbyte, 4) +FETCH_RGBA(RGBA_SINT16, GLshort, 4) +FETCH_RGBA(RGBA_SINT32, GLint, 4) +FETCH_RGBA(RGBA_UINT8, GLubyte, 4) +FETCH_RGBA(RGBA_UINT16, GLushort, 4) +FETCH_RGBA(RGBA_UINT32, GLuint, 4) +FETCH_RGBA(R_SNORM8, GLbyte, 1) +FETCH_RGBA(A_SNORM8, GLbyte, 1) +FETCH_RGBA(L_SNORM8, GLbyte, 1) +FETCH_RGBA(I_SNORM8, GLbyte, 1) +FETCH_RGBA(R8G8_SNORM, GLshort, 1) +FETCH_RGBA(L8A8_SNORM, GLshort, 1) +FETCH_RGBA(A8L8_SNORM, GLshort, 1) +FETCH_RGBA(X8B8G8R8_SNORM, GLint, 1) +FETCH_RGBA(A8B8G8R8_SNORM, GLint, 1) +FETCH_RGBA(R8G8B8A8_SNORM, GLint, 1) +FETCH_RGBA(R_SNORM16, GLshort, 1) +FETCH_RGBA(A_SNORM16, GLshort, 1) +FETCH_RGBA(L_SNORM16, GLshort, 1) +FETCH_RGBA(I_SNORM16, GLshort, 1) +FETCH_RGBA(R16G16_SNORM, GLshort, 2) +FETCH_RGBA(LA_SNORM16, GLshort, 2) +FETCH_RGBA(RGB_SNORM16, GLshort, 3) +FETCH_RGBA(RGBA_SNORM16, GLshort, 4) +FETCH_RGBA(RGBA_UNORM16, GLushort, 4) +FETCH_RGBA(RGBX_UNORM16, GLushort, 4) +FETCH_RGBA(RGBX_FLOAT16, GLhalfARB, 4) +FETCH_RGBA(RGBX_FLOAT32, GLfloat, 4) +FETCH_RGBA(YCBCR, GLushort, 1) /* Fetch texel from 1D, 2D or 3D ycbcr texture, returning RGBA. */ +FETCH_RGBA(YCBCR_REV, GLushort, 1) /* Fetch texel from 1D, 2D or 3D ycbcr texture, returning RGBA. */ +FETCH_RGBA(R9G9B9E5_FLOAT, GLuint, 1) +FETCH_RGBA(R11G11B10_FLOAT, GLuint, 1) #undef TEXEL_ADDR #undef DIM #undef FETCH +#undef FETCH_Z +#undef FETCH_RGBA diff --git a/mesalib/src/mesa/swrast/s_texfilter.c b/mesalib/src/mesa/swrast/s_texfilter.c index 65cf52e21..fa79fdc5b 100644 --- a/mesalib/src/mesa/swrast/s_texfilter.c +++ b/mesalib/src/mesa/swrast/s_texfilter.c @@ -27,8 +27,9 @@ #include "main/context.h" #include "main/colormac.h" #include "main/imports.h" -#include "main/texobj.h" #include "main/samplerobj.h" +#include "main/teximage.h" +#include "main/texobj.h" #include "s_context.h" #include "s_texfilter.h" @@ -73,7 +74,7 @@ lerp_2d(GLfloat a, GLfloat b, * Do 3D/trilinear interpolation of float values. * \sa lerp_2d */ -static inline GLfloat +static GLfloat lerp_3d(GLfloat a, GLfloat b, GLfloat c, GLfloat v000, GLfloat v100, GLfloat v010, GLfloat v110, GLfloat v001, GLfloat v101, GLfloat v011, GLfloat v111) @@ -91,7 +92,7 @@ lerp_3d(GLfloat a, GLfloat b, GLfloat c, /** * Do linear interpolation of colors. */ -static inline void +static void lerp_rgba(GLfloat result[4], GLfloat t, const GLfloat a[4], const GLfloat b[4]) { result[0] = LERP(t, a[0], b[0]); @@ -104,7 +105,7 @@ lerp_rgba(GLfloat result[4], GLfloat t, const GLfloat a[4], const GLfloat b[4]) /** * Do bilinear interpolation of colors. */ -static inline void +static void lerp_rgba_2d(GLfloat result[4], GLfloat a, GLfloat b, const GLfloat t00[4], const GLfloat t10[4], const GLfloat t01[4], const GLfloat t11[4]) @@ -119,7 +120,7 @@ lerp_rgba_2d(GLfloat result[4], GLfloat a, GLfloat b, /** * Do trilinear interpolation of colors. */ -static inline void +static void lerp_rgba_3d(GLfloat result[4], GLfloat a, GLfloat b, GLfloat c, const GLfloat t000[4], const GLfloat t100[4], const GLfloat t010[4], const GLfloat t110[4], @@ -155,7 +156,7 @@ lerp_rgba_3d(GLfloat result[4], GLfloat a, GLfloat b, GLfloat c, * i0, i1 = returns two nearest texel indexes * weight = returns blend factor between texels */ -static inline void +static void linear_texel_locations(GLenum wrapMode, const struct gl_texture_image *img, GLint size, GLfloat s, @@ -285,7 +286,7 @@ linear_texel_locations(GLenum wrapMode, /** * Used to compute texel location for nearest sampling. */ -static inline GLint +static GLint nearest_texel_location(GLenum wrapMode, const struct gl_texture_image *img, GLint size, GLfloat s) @@ -410,7 +411,7 @@ nearest_texel_location(GLenum wrapMode, /* Power of two image sizes only */ -static inline void +static void linear_repeat_texel_location(GLuint size, GLfloat s, GLint *i0, GLint *i1, GLfloat *weight) { @@ -424,7 +425,7 @@ linear_repeat_texel_location(GLuint size, GLfloat s, /** * Do clamp/wrap for a texture rectangle coord, GL_NEAREST filter mode. */ -static inline GLint +static GLint clamp_rect_coord_nearest(GLenum wrapMode, GLfloat coord, GLint max) { switch (wrapMode) { @@ -444,7 +445,7 @@ clamp_rect_coord_nearest(GLenum wrapMode, GLfloat coord, GLint max) /** * As above, but GL_LINEAR filtering. */ -static inline void +static void clamp_rect_coord_linear(GLenum wrapMode, GLfloat coord, GLint max, GLint *i0out, GLint *i1out, GLfloat *weight) { @@ -486,7 +487,7 @@ clamp_rect_coord_linear(GLenum wrapMode, GLfloat coord, GLint max, /** * Compute slice/image to use for 1D or 2D array texture. */ -static inline GLint +static GLint tex_array_slice(GLfloat coord, GLsizei size) { GLint slice = IFLOOR(coord + 0.5f); @@ -499,7 +500,7 @@ tex_array_slice(GLfloat coord, GLsizei size) * Compute nearest integer texcoords for given texobj and coordinate. * NOTE: only used for depth texture sampling. */ -static inline void +static void nearest_texcoord(const struct gl_sampler_object *samp, const struct gl_texture_object *texObj, GLuint level, @@ -548,7 +549,7 @@ nearest_texcoord(const struct gl_sampler_object *samp, * Compute linear integer texcoords for given texobj and coordinate. * NOTE: only used for depth texture sampling. */ -static inline void +static void linear_texcoord(const struct gl_sampler_object *samp, const struct gl_texture_object *texObj, GLuint level, @@ -607,7 +608,7 @@ linear_texcoord(const struct gl_sampler_object *samp, * For linear interpolation between mipmap levels N and N+1, this function * computes N. */ -static inline GLint +static GLint linear_mipmap_level(const struct gl_texture_object *tObj, GLfloat lambda) { if (lambda < 0.0F) @@ -622,7 +623,7 @@ linear_mipmap_level(const struct gl_texture_object *tObj, GLfloat lambda) /** * Compute the nearest mipmap level to take texels from. */ -static inline GLint +static GLint nearest_mipmap_level(const struct gl_texture_object *tObj, GLfloat lambda) { GLfloat l; @@ -658,7 +659,7 @@ nearest_mipmap_level(const struct gl_texture_object *tObj, GLfloat lambda) * will be minified, magnified, or split between the two. This function * determines the subranges in [0, n-1] that are to be minified or magnified. */ -static inline void +static void compute_min_mag_ranges(const struct gl_sampler_object *samp, GLuint n, const GLfloat lambda[], GLuint *minStart, GLuint *minEnd, @@ -767,7 +768,7 @@ compute_min_mag_ranges(const struct gl_sampler_object *samp, * the base texture format. Ex: if the texture base format it GL_ALPHA, * we return (0,0,0,BorderAlpha). */ -static inline void +static void get_border_color(const struct gl_sampler_object *samp, const struct gl_texture_image *img, GLfloat rgba[4]) @@ -804,7 +805,7 @@ get_border_color(const struct gl_sampler_object *samp, /** * Put z into texel according to GL_DEPTH_MODE. */ -static inline void +static void apply_depth_mode(GLenum depthMode, GLfloat z, GLfloat texel[4]) { switch (depthMode) { @@ -832,7 +833,7 @@ apply_depth_mode(GLenum depthMode, GLfloat z, GLfloat texel[4]) static GLboolean is_depth_texture(const struct gl_texture_object *tObj) { - GLenum format = tObj->Image[0][tObj->BaseLevel]->_BaseFormat; + GLenum format = _mesa_texture_base_format(tObj); return format == GL_DEPTH_COMPONENT || format == GL_DEPTH_STENCIL_EXT; } @@ -844,7 +845,7 @@ is_depth_texture(const struct gl_texture_object *tObj) /** * Return the texture sample for coordinate (s) using GL_NEAREST filter. */ -static inline void +static void sample_1d_nearest(struct gl_context *ctx, const struct gl_sampler_object *samp, const struct gl_texture_image *img, @@ -869,7 +870,7 @@ sample_1d_nearest(struct gl_context *ctx, /** * Return the texture sample for coordinate (s) using GL_LINEAR filter. */ -static inline void +static void sample_1d_linear(struct gl_context *ctx, const struct gl_sampler_object *samp, const struct gl_texture_image *img, @@ -1004,7 +1005,7 @@ sample_nearest_1d( struct gl_context *ctx, GLfloat rgba[][4] ) { GLuint i; - struct gl_texture_image *image = tObj->Image[0][tObj->BaseLevel]; + const struct gl_texture_image *image = _mesa_base_tex_image(tObj); (void) lambda; for (i = 0; i < n; i++) { sample_1d_nearest(ctx, samp, image, texcoords[i], rgba[i]); @@ -1021,7 +1022,7 @@ sample_linear_1d( struct gl_context *ctx, GLfloat rgba[][4] ) { GLuint i; - struct gl_texture_image *image = tObj->Image[0][tObj->BaseLevel]; + const struct gl_texture_image *image = _mesa_base_tex_image(tObj); (void) lambda; for (i = 0; i < n; i++) { sample_1d_linear(ctx, samp, image, texcoords[i], rgba[i]); @@ -1051,12 +1052,12 @@ sample_lambda_1d( struct gl_context *ctx, switch (samp->MinFilter) { case GL_NEAREST: for (i = minStart; i < minEnd; i++) - sample_1d_nearest(ctx, samp, tObj->Image[0][tObj->BaseLevel], + sample_1d_nearest(ctx, samp, _mesa_base_tex_image(tObj), texcoords[i], rgba[i]); break; case GL_LINEAR: for (i = minStart; i < minEnd; i++) - sample_1d_linear(ctx, samp, tObj->Image[0][tObj->BaseLevel], + sample_1d_linear(ctx, samp, _mesa_base_tex_image(tObj), texcoords[i], rgba[i]); break; case GL_NEAREST_MIPMAP_NEAREST: @@ -1086,12 +1087,12 @@ sample_lambda_1d( struct gl_context *ctx, switch (samp->MagFilter) { case GL_NEAREST: for (i = magStart; i < magEnd; i++) - sample_1d_nearest(ctx, samp, tObj->Image[0][tObj->BaseLevel], + sample_1d_nearest(ctx, samp, _mesa_base_tex_image(tObj), texcoords[i], rgba[i]); break; case GL_LINEAR: for (i = magStart; i < magEnd; i++) - sample_1d_linear(ctx, samp, tObj->Image[0][tObj->BaseLevel], + sample_1d_linear(ctx, samp, _mesa_base_tex_image(tObj), texcoords[i], rgba[i]); break; default: @@ -1110,7 +1111,7 @@ sample_lambda_1d( struct gl_context *ctx, /** * Return the texture sample for coordinate (s,t) using GL_NEAREST filter. */ -static inline void +static void sample_2d_nearest(struct gl_context *ctx, const struct gl_sampler_object *samp, const struct gl_texture_image *img, @@ -1144,7 +1145,7 @@ sample_2d_nearest(struct gl_context *ctx, * Return the texture sample for coordinate (s,t) using GL_LINEAR filter. * New sampling code contributed by Lynn Quam . */ -static inline void +static void sample_2d_linear(struct gl_context *ctx, const struct gl_sampler_object *samp, const struct gl_texture_image *img, @@ -1209,7 +1210,7 @@ sample_2d_linear(struct gl_context *ctx, * As above, but we know WRAP_S == REPEAT and WRAP_T == REPEAT. * We don't have to worry about the texture border. */ -static inline void +static void sample_2d_linear_repeat(struct gl_context *ctx, const struct gl_sampler_object *samp, const struct gl_texture_image *img, @@ -1364,7 +1365,7 @@ sample_nearest_2d(struct gl_context *ctx, const GLfloat lambda[], GLfloat rgba[][4]) { GLuint i; - struct gl_texture_image *image = tObj->Image[0][tObj->BaseLevel]; + const struct gl_texture_image *image = _mesa_base_tex_image(tObj); (void) lambda; for (i = 0; i < n; i++) { sample_2d_nearest(ctx, samp, image, texcoords[i], rgba[i]); @@ -1381,7 +1382,7 @@ sample_linear_2d(struct gl_context *ctx, const GLfloat lambda[], GLfloat rgba[][4]) { GLuint i; - struct gl_texture_image *image = tObj->Image[0][tObj->BaseLevel]; + const struct gl_texture_image *image = _mesa_base_tex_image(tObj); const struct swrast_texture_image *swImg = swrast_texture_image_const(image); (void) lambda; if (samp->WrapS == GL_REPEAT && @@ -1415,7 +1416,7 @@ opt_sample_rgb_2d(struct gl_context *ctx, GLuint n, const GLfloat texcoords[][4], const GLfloat lambda[], GLfloat rgba[][4]) { - const struct gl_texture_image *img = tObj->Image[0][tObj->BaseLevel]; + const struct gl_texture_image *img = _mesa_base_tex_image(tObj); const struct swrast_texture_image *swImg = swrast_texture_image_const(img); const GLfloat width = (GLfloat) img->Width; const GLfloat height = (GLfloat) img->Height; @@ -1460,7 +1461,7 @@ opt_sample_rgba_2d(struct gl_context *ctx, GLuint n, const GLfloat texcoords[][4], const GLfloat lambda[], GLfloat rgba[][4]) { - const struct gl_texture_image *img = tObj->Image[0][tObj->BaseLevel]; + const struct gl_texture_image *img = _mesa_base_tex_image(tObj); const struct swrast_texture_image *swImg = swrast_texture_image_const(img); const GLfloat width = (GLfloat) img->Width; const GLfloat height = (GLfloat) img->Height; @@ -1498,7 +1499,7 @@ sample_lambda_2d(struct gl_context *ctx, GLuint n, const GLfloat texcoords[][4], const GLfloat lambda[], GLfloat rgba[][4]) { - const struct gl_texture_image *tImg = tObj->Image[0][tObj->BaseLevel]; + const struct gl_texture_image *tImg = _mesa_base_tex_image(tObj); const struct swrast_texture_image *swImg = swrast_texture_image_const(tImg); GLuint minStart, minEnd; /* texels with minification */ GLuint magStart, magEnd; /* texels with magnification */ @@ -1653,7 +1654,7 @@ sample_2d_ewa(struct gl_context *ctx, GLfloat scaling = 1.0f / (1 << level); const struct gl_texture_image *img = tObj->Image[0][level]; const struct gl_texture_image *mostDetailedImage = - tObj->Image[0][tObj->BaseLevel]; + _mesa_base_tex_image(tObj); const struct swrast_texture_image *swImg = swrast_texture_image_const(mostDetailedImage); GLfloat tex_u = -0.5f + texcoord[0] * swImg->WidthScale * scaling; @@ -1830,7 +1831,7 @@ sample_2d_footprint(struct gl_context *ctx, * Returns the index of the specified texture object in the * gl_context texture unit array. */ -static inline GLuint +static GLuint texture_unit_index(const struct gl_context *ctx, const struct gl_texture_object *tObj) { @@ -1865,7 +1866,7 @@ sample_lambda_2d_aniso(struct gl_context *ctx, GLuint n, const GLfloat texcoords[][4], const GLfloat lambda_iso[], GLfloat rgba[][4]) { - const struct gl_texture_image *tImg = tObj->Image[0][tObj->BaseLevel]; + const struct gl_texture_image *tImg = _mesa_base_tex_image(tObj); const struct swrast_texture_image *swImg = swrast_texture_image_const(tImg); const GLfloat maxEccentricity = samp->MaxAnisotropy * samp->MaxAnisotropy; @@ -2012,7 +2013,7 @@ sample_lambda_2d_aniso(struct gl_context *ctx, /** * Return the texture sample for coordinate (s,t,r) using GL_NEAREST filter. */ -static inline void +static void sample_3d_nearest(struct gl_context *ctx, const struct gl_sampler_object *samp, const struct gl_texture_image *img, @@ -2232,7 +2233,7 @@ sample_nearest_3d(struct gl_context *ctx, GLfloat rgba[][4]) { GLuint i; - struct gl_texture_image *image = tObj->Image[0][tObj->BaseLevel]; + const struct gl_texture_image *image = _mesa_base_tex_image(tObj); (void) lambda; for (i = 0; i < n; i++) { sample_3d_nearest(ctx, samp, image, texcoords[i], rgba[i]); @@ -2249,7 +2250,7 @@ sample_linear_3d(struct gl_context *ctx, const GLfloat lambda[], GLfloat rgba[][4]) { GLuint i; - struct gl_texture_image *image = tObj->Image[0][tObj->BaseLevel]; + const struct gl_texture_image *image = _mesa_base_tex_image(tObj); (void) lambda; for (i = 0; i < n; i++) { sample_3d_linear(ctx, samp, image, texcoords[i], rgba[i]); @@ -2279,12 +2280,12 @@ sample_lambda_3d(struct gl_context *ctx, switch (samp->MinFilter) { case GL_NEAREST: for (i = minStart; i < minEnd; i++) - sample_3d_nearest(ctx, samp, tObj->Image[0][tObj->BaseLevel], + sample_3d_nearest(ctx, samp, _mesa_base_tex_image(tObj), texcoords[i], rgba[i]); break; case GL_LINEAR: for (i = minStart; i < minEnd; i++) - sample_3d_linear(ctx, samp, tObj->Image[0][tObj->BaseLevel], + sample_3d_linear(ctx, samp, _mesa_base_tex_image(tObj), texcoords[i], rgba[i]); break; case GL_NEAREST_MIPMAP_NEAREST: @@ -2314,12 +2315,12 @@ sample_lambda_3d(struct gl_context *ctx, switch (samp->MagFilter) { case GL_NEAREST: for (i = magStart; i < magEnd; i++) - sample_3d_nearest(ctx, samp, tObj->Image[0][tObj->BaseLevel], + sample_3d_nearest(ctx, samp, _mesa_base_tex_image(tObj), texcoords[i], rgba[i]); break; case GL_LINEAR: for (i = magStart; i < magEnd; i++) - sample_3d_linear(ctx, samp, tObj->Image[0][tObj->BaseLevel], + sample_3d_linear(ctx, samp, _mesa_base_tex_image(tObj), texcoords[i], rgba[i]); break; default: @@ -3020,7 +3021,7 @@ sample_nearest_2d_array(struct gl_context *ctx, GLfloat rgba[][4]) { GLuint i; - struct gl_texture_image *image = tObj->Image[0][tObj->BaseLevel]; + const struct gl_texture_image *image = _mesa_base_tex_image(tObj); (void) lambda; for (i = 0; i < n; i++) { sample_2d_array_nearest(ctx, samp, image, texcoords[i], rgba[i]); @@ -3038,7 +3039,7 @@ sample_linear_2d_array(struct gl_context *ctx, const GLfloat lambda[], GLfloat rgba[][4]) { GLuint i; - struct gl_texture_image *image = tObj->Image[0][tObj->BaseLevel]; + const struct gl_texture_image *image = _mesa_base_tex_image(tObj); (void) lambda; for (i = 0; i < n; i++) { sample_2d_array_linear(ctx, samp, image, texcoords[i], rgba[i]); @@ -3068,12 +3069,12 @@ sample_lambda_2d_array(struct gl_context *ctx, switch (samp->MinFilter) { case GL_NEAREST: for (i = minStart; i < minEnd; i++) - sample_2d_array_nearest(ctx, samp, tObj->Image[0][tObj->BaseLevel], + sample_2d_array_nearest(ctx, samp, _mesa_base_tex_image(tObj), texcoords[i], rgba[i]); break; case GL_LINEAR: for (i = minStart; i < minEnd; i++) - sample_2d_array_linear(ctx, samp, tObj->Image[0][tObj->BaseLevel], + sample_2d_array_linear(ctx, samp, _mesa_base_tex_image(tObj), texcoords[i], rgba[i]); break; case GL_NEAREST_MIPMAP_NEAREST: @@ -3111,12 +3112,12 @@ sample_lambda_2d_array(struct gl_context *ctx, switch (samp->MagFilter) { case GL_NEAREST: for (i = magStart; i < magEnd; i++) - sample_2d_array_nearest(ctx, samp, tObj->Image[0][tObj->BaseLevel], + sample_2d_array_nearest(ctx, samp, _mesa_base_tex_image(tObj), texcoords[i], rgba[i]); break; case GL_LINEAR: for (i = magStart; i < magEnd; i++) - sample_2d_array_linear(ctx, samp, tObj->Image[0][tObj->BaseLevel], + sample_2d_array_linear(ctx, samp, _mesa_base_tex_image(tObj), texcoords[i], rgba[i]); break; default: @@ -3311,7 +3312,7 @@ sample_nearest_1d_array(struct gl_context *ctx, GLfloat rgba[][4]) { GLuint i; - struct gl_texture_image *image = tObj->Image[0][tObj->BaseLevel]; + const struct gl_texture_image *image = _mesa_base_tex_image(tObj); (void) lambda; for (i = 0; i < n; i++) { sample_1d_array_nearest(ctx, samp, image, texcoords[i], rgba[i]); @@ -3328,7 +3329,7 @@ sample_linear_1d_array(struct gl_context *ctx, const GLfloat lambda[], GLfloat rgba[][4]) { GLuint i; - struct gl_texture_image *image = tObj->Image[0][tObj->BaseLevel]; + const struct gl_texture_image *image = _mesa_base_tex_image(tObj); (void) lambda; for (i = 0; i < n; i++) { sample_1d_array_linear(ctx, samp, image, texcoords[i], rgba[i]); @@ -3358,12 +3359,12 @@ sample_lambda_1d_array(struct gl_context *ctx, switch (samp->MinFilter) { case GL_NEAREST: for (i = minStart; i < minEnd; i++) - sample_1d_array_nearest(ctx, samp, tObj->Image[0][tObj->BaseLevel], + sample_1d_array_nearest(ctx, samp, _mesa_base_tex_image(tObj), texcoords[i], rgba[i]); break; case GL_LINEAR: for (i = minStart; i < minEnd; i++) - sample_1d_array_linear(ctx, samp, tObj->Image[0][tObj->BaseLevel], + sample_1d_array_linear(ctx, samp, _mesa_base_tex_image(tObj), texcoords[i], rgba[i]); break; case GL_NEAREST_MIPMAP_NEAREST: @@ -3397,12 +3398,12 @@ sample_lambda_1d_array(struct gl_context *ctx, switch (samp->MagFilter) { case GL_NEAREST: for (i = magStart; i < magEnd; i++) - sample_1d_array_nearest(ctx, samp, tObj->Image[0][tObj->BaseLevel], + sample_1d_array_nearest(ctx, samp, _mesa_base_tex_image(tObj), texcoords[i], rgba[i]); break; case GL_LINEAR: for (i = magStart; i < magEnd; i++) - sample_1d_array_linear(ctx, samp, tObj->Image[0][tObj->BaseLevel], + sample_1d_array_linear(ctx, samp, _mesa_base_tex_image(tObj), texcoords[i], rgba[i]); break; default: @@ -3416,7 +3417,7 @@ sample_lambda_1d_array(struct gl_context *ctx, /** * Compare texcoord against depth sample. Return 1.0 or 0.0 value. */ -static inline GLfloat +static GLfloat shadow_compare(GLenum function, GLfloat coord, GLfloat depthSample) { switch (function) { @@ -3448,7 +3449,7 @@ shadow_compare(GLenum function, GLfloat coord, GLfloat depthSample) /** * Compare texcoord against four depth samples. */ -static inline GLfloat +static GLfloat shadow_compare4(GLenum function, GLfloat coord, GLfloat depth00, GLfloat depth01, GLfloat depth10, GLfloat depth11, @@ -3749,7 +3750,7 @@ _swrast_choose_texture_sample_func( struct gl_context *ctx, } else { /* check for a few optimized cases */ - const struct gl_texture_image *img = t->Image[0][t->BaseLevel]; + const struct gl_texture_image *img = _mesa_base_tex_image(t); const struct swrast_texture_image *swImg = swrast_texture_image_const(img); texture_sample_func func; diff --git a/mesalib/src/mesa/swrast/s_triangle.c b/mesalib/src/mesa/swrast/s_triangle.c index 164906643..1d8e31c2e 100644 --- a/mesalib/src/mesa/swrast/s_triangle.c +++ b/mesalib/src/mesa/swrast/s_triangle.c @@ -37,6 +37,7 @@ #include "main/mtypes.h" #include "main/state.h" #include "main/samplerobj.h" +#include "main/teximage.h" #include "program/prog_instruction.h" #include "s_aatriangle.h" @@ -127,7 +128,7 @@ _swrast_culltriangle( struct gl_context *ctx, const struct gl_texture_object *obj = \ ctx->Texture.Unit[0].CurrentTex[TEXTURE_2D_INDEX]; \ const struct gl_texture_image *texImg = \ - obj->Image[0][obj->BaseLevel]; \ + _mesa_base_tex_image(obj); \ const struct swrast_texture_image *swImg = \ swrast_texture_image_const(texImg); \ const GLfloat twidth = (GLfloat) texImg->Width; \ @@ -185,7 +186,7 @@ _swrast_culltriangle( struct gl_context *ctx, const struct gl_texture_object *obj = \ ctx->Texture.Unit[0].CurrentTex[TEXTURE_2D_INDEX]; \ const struct gl_texture_image *texImg = \ - obj->Image[0][obj->BaseLevel]; \ + _mesa_base_tex_image(obj); \ const struct swrast_texture_image *swImg = \ swrast_texture_image_const(texImg); \ const GLfloat twidth = (GLfloat) texImg->Width; \ @@ -542,7 +543,7 @@ affine_span(struct gl_context *ctx, SWspan *span, const struct gl_texture_object *obj = \ ctx->Texture.Unit[0].CurrentTex[TEXTURE_2D_INDEX]; \ const struct gl_texture_image *texImg = \ - obj->Image[0][obj->BaseLevel]; \ + _mesa_base_tex_image(obj); \ const struct swrast_texture_image *swImg = \ swrast_texture_image_const(texImg); \ const GLfloat twidth = (GLfloat) texImg->Width; \ @@ -811,7 +812,7 @@ fast_persp_span(struct gl_context *ctx, SWspan *span, const struct gl_texture_object *obj = \ ctx->Texture.Unit[0].CurrentTex[TEXTURE_2D_INDEX]; \ const struct gl_texture_image *texImg = \ - obj->Image[0][obj->BaseLevel]; \ + _mesa_base_tex_image(obj); \ const struct swrast_texture_image *swImg = \ swrast_texture_image_const(texImg); \ info.texture = (const GLchan *) swImg->ImageSlices[0]; \ @@ -1059,7 +1060,7 @@ _swrast_choose_triangle( struct gl_context *ctx ) else samp = NULL; - texImg = texObj2D ? texObj2D->Image[0][texObj2D->BaseLevel] : NULL; + texImg = texObj2D ? _mesa_base_tex_image(texObj2D) : NULL; swImg = swrast_texture_image_const(texImg); format = texImg ? texImg->TexFormat : MESA_FORMAT_NONE; diff --git a/mesalib/src/mesa/swrast/swrast.h b/mesalib/src/mesa/swrast/swrast.h index ac3dbe304..a89dc6cda 100644 --- a/mesalib/src/mesa/swrast/swrast.h +++ b/mesalib/src/mesa/swrast/swrast.h @@ -132,16 +132,18 @@ _swrast_Bitmap( struct gl_context *ctx, const GLubyte *bitmap ); extern void -_swrast_CopyPixels( struct gl_context *ctx, - GLint srcx, GLint srcy, - GLint destx, GLint desty, - GLsizei width, GLsizei height, - GLenum type ); +_swrast_CopyPixels(struct gl_context *ctx, + GLint srcx, GLint srcy, + GLint destx, GLint desty, + GLsizei width, GLsizei height, + GLenum type); extern GLboolean swrast_fast_copy_pixels(struct gl_context *ctx, - GLint srcX, GLint srcY, GLsizei width, GLsizei height, - GLint dstX, GLint dstY, GLenum type); + struct gl_framebuffer *srcFb, + struct gl_framebuffer *dstFb, + GLint srcX, GLint srcY, GLsizei width, GLsizei height, + GLint dstX, GLint dstY, GLenum type); extern void _swrast_DrawPixels( struct gl_context *ctx, @@ -153,6 +155,8 @@ _swrast_DrawPixels( struct gl_context *ctx, extern void _swrast_BlitFramebuffer(struct gl_context *ctx, + struct gl_framebuffer *readFb, + struct gl_framebuffer *drawFb, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); diff --git a/mesalib/src/mesa/tnl/t_rasterpos.c b/mesalib/src/mesa/tnl/t_rasterpos.c index e538c348f..2f52bb306 100644 --- a/mesalib/src/mesa/tnl/t_rasterpos.c +++ b/mesalib/src/mesa/tnl/t_rasterpos.c @@ -28,7 +28,7 @@ #include "main/feedback.h" #include "main/light.h" #include "main/macros.h" -#include "main/simple_list.h" +#include "util/simple_list.h" #include "main/mtypes.h" #include "math/m_matrix.h" diff --git a/mesalib/src/mesa/tnl/t_vb_light.c b/mesalib/src/mesa/tnl/t_vb_light.c index ee80f1b82..f6884a464 100644 --- a/mesalib/src/mesa/tnl/t_vb_light.c +++ b/mesalib/src/mesa/tnl/t_vb_light.c @@ -29,7 +29,7 @@ #include "main/light.h" #include "main/macros.h" #include "main/imports.h" -#include "main/simple_list.h" +#include "util/simple_list.h" #include "main/mtypes.h" #include "math/m_translate.h" diff --git a/mesalib/src/mesa/tnl/t_vertex_generic.c b/mesalib/src/mesa/tnl/t_vertex_generic.c index 8926c178d..079d473fc 100644 --- a/mesalib/src/mesa/tnl/t_vertex_generic.c +++ b/mesalib/src/mesa/tnl/t_vertex_generic.c @@ -29,7 +29,7 @@ #include "main/glheader.h" #include "main/context.h" #include "main/colormac.h" -#include "main/simple_list.h" +#include "util/simple_list.h" #include "swrast/s_chan.h" #include "t_context.h" #include "t_vertex.h" diff --git a/mesalib/src/mesa/tnl/t_vertex_sse.c b/mesalib/src/mesa/tnl/t_vertex_sse.c index 4b52f7dbb..93128fbe6 100644 --- a/mesalib/src/mesa/tnl/t_vertex_sse.c +++ b/mesalib/src/mesa/tnl/t_vertex_sse.c @@ -28,7 +28,7 @@ #include "main/glheader.h" #include "main/context.h" #include "main/colormac.h" -#include "main/simple_list.h" +#include "util/simple_list.h" #include "main/enums.h" #include "swrast/s_chan.h" #include "t_context.h" diff --git a/mesalib/src/mesa/vbo/vbo_attrib_tmp.h b/mesalib/src/mesa/vbo/vbo_attrib_tmp.h index ec66934fc..0c44540fc 100644 --- a/mesalib/src/mesa/vbo/vbo_attrib_tmp.h +++ b/mesalib/src/mesa/vbo/vbo_attrib_tmp.h @@ -210,6 +210,7 @@ static inline float conv_i2_to_norm_float(const struct gl_context *ctx, int i2) } \ } else if ((type) == GL_UNSIGNED_INT_10F_11F_11F_REV) { \ float res[4]; \ + res[3] = 1; \ r11g11b10f_to_float3((arg), res); \ ATTR##val##FV((attr), res); \ } else \ diff --git a/mesalib/src/mesa/vbo/vbo_exec_array.c b/mesalib/src/mesa/vbo/vbo_exec_array.c index e623b361a..c16fe77ee 100644 --- a/mesalib/src/mesa/vbo/vbo_exec_array.c +++ b/mesalib/src/mesa/vbo/vbo_exec_array.c @@ -300,7 +300,8 @@ check_draw_elements_data(struct gl_context *ctx, GLsizei count, GLenum elemType, { struct gl_vertex_array_object *vao = ctx->Array.VAO; const void *elemMap; - GLint i, k; + GLint i; + GLuint k; if (_mesa_is_bufferobj(ctx->Array.VAO->IndexBufferObj)) { elemMap = ctx->Driver.MapBufferRange(ctx, 0, @@ -596,7 +597,8 @@ vbo_draw_arrays(struct gl_context *ctx, GLenum mode, GLint start, prim[0].is_indirect = 0; /* Implement the primitive restart index */ - if (ctx->Array.PrimitiveRestart && ctx->Array.RestartIndex < count) { + if (ctx->Array.PrimitiveRestart && !ctx->Array.PrimitiveRestartFixedIndex && + ctx->Array.RestartIndex < count) { GLuint primCount = 0; if (ctx->Array.RestartIndex == start) { @@ -786,7 +788,7 @@ vbo_exec_DrawArrays(GLenum mode, GLint start, GLsizei count) _mesa_debug(ctx, "glDrawArrays(%s, %d, %d)\n", _mesa_lookup_enum_by_nr(mode), start, count); - if (!_mesa_validate_DrawArrays( ctx, mode, start, count )) + if (!_mesa_validate_DrawArrays(ctx, mode, count)) return; if (0) @@ -1022,8 +1024,8 @@ vbo_exec_DrawRangeElementsBaseVertex(GLenum mode, _mesa_lookup_enum_by_nr(mode), start, end, count, _mesa_lookup_enum_by_nr(type), indices, basevertex); - if (!_mesa_validate_DrawRangeElements( ctx, mode, start, end, count, - type, indices, basevertex )) + if (!_mesa_validate_DrawRangeElements(ctx, mode, start, end, count, + type, indices)) return; if ((int) end + basevertex < 0 || @@ -1120,7 +1122,7 @@ vbo_exec_DrawElements(GLenum mode, GLsizei count, GLenum type, _mesa_lookup_enum_by_nr(mode), count, _mesa_lookup_enum_by_nr(type), indices); - if (!_mesa_validate_DrawElements( ctx, mode, count, type, indices, 0 )) + if (!_mesa_validate_DrawElements(ctx, mode, count, type, indices)) return; vbo_validated_drawrangeelements(ctx, mode, GL_FALSE, ~0, ~0, @@ -1142,8 +1144,7 @@ vbo_exec_DrawElementsBaseVertex(GLenum mode, GLsizei count, GLenum type, _mesa_lookup_enum_by_nr(mode), count, _mesa_lookup_enum_by_nr(type), indices, basevertex); - if (!_mesa_validate_DrawElements( ctx, mode, count, type, indices, - basevertex )) + if (!_mesa_validate_DrawElements(ctx, mode, count, type, indices)) return; vbo_validated_drawrangeelements(ctx, mode, GL_FALSE, ~0, ~0, @@ -1166,7 +1167,7 @@ vbo_exec_DrawElementsInstanced(GLenum mode, GLsizei count, GLenum type, _mesa_lookup_enum_by_nr(type), indices, numInstances); if (!_mesa_validate_DrawElementsInstanced(ctx, mode, count, type, indices, - numInstances, 0)) + numInstances)) return; vbo_validated_drawrangeelements(ctx, mode, GL_FALSE, ~0, ~0, @@ -1191,7 +1192,7 @@ vbo_exec_DrawElementsInstancedBaseVertex(GLenum mode, GLsizei count, GLenum type numInstances, basevertex); if (!_mesa_validate_DrawElementsInstanced(ctx, mode, count, type, indices, - numInstances, basevertex)) + numInstances)) return; vbo_validated_drawrangeelements(ctx, mode, GL_FALSE, ~0, ~0, @@ -1216,7 +1217,7 @@ vbo_exec_DrawElementsInstancedBaseInstance(GLenum mode, GLsizei count, GLenum ty numInstances, baseInstance); if (!_mesa_validate_DrawElementsInstanced(ctx, mode, count, type, indices, - numInstances, 0)) + numInstances)) return; vbo_validated_drawrangeelements(ctx, mode, GL_FALSE, ~0, ~0, @@ -1242,7 +1243,7 @@ vbo_exec_DrawElementsInstancedBaseVertexBaseInstance(GLenum mode, GLsizei count, numInstances, basevertex, baseInstance); if (!_mesa_validate_DrawElementsInstanced(ctx, mode, count, type, indices, - numInstances, basevertex)) + numInstances)) return; vbo_validated_drawrangeelements(ctx, mode, GL_FALSE, ~0, ~0, @@ -1399,7 +1400,7 @@ vbo_exec_MultiDrawElements(GLenum mode, GET_CURRENT_CONTEXT(ctx); if (!_mesa_validate_MultiDrawElements(ctx, mode, count, type, indices, - primcount, NULL)) + primcount)) return; vbo_validated_multidrawelements(ctx, mode, count, type, indices, primcount, @@ -1417,7 +1418,7 @@ vbo_exec_MultiDrawElementsBaseVertex(GLenum mode, GET_CURRENT_CONTEXT(ctx); if (!_mesa_validate_MultiDrawElements(ctx, mode, count, type, indices, - primcount, basevertex)) + primcount)) return; vbo_validated_multidrawelements(ctx, mode, count, type, indices, primcount, diff --git a/mesalib/src/mesa/vbo/vbo_save_api.c b/mesalib/src/mesa/vbo/vbo_save_api.c index 848eedaa4..beef342be 100644 --- a/mesalib/src/mesa/vbo/vbo_save_api.c +++ b/mesalib/src/mesa/vbo/vbo_save_api.c @@ -375,11 +375,14 @@ _save_compile_vertex_list(struct gl_context *ctx) * being compiled. */ node = (struct vbo_save_vertex_list *) - _mesa_dlist_alloc(ctx, save->opcode_vertex_list, sizeof(*node)); + _mesa_dlist_alloc_aligned(ctx, save->opcode_vertex_list, sizeof(*node)); if (!node) return; + /* Make sure the pointer is aligned to the size of a pointer */ + assert((GLintptr) node % sizeof(void *) == 0); + /* Duplicate our template, increment refcounts to the storage structs: */ memcpy(node->attrsz, save->attrsz, sizeof(node->attrsz)); @@ -1523,18 +1526,22 @@ vbo_destroy_vertex_list(struct gl_context *ctx, void *data) static void -vbo_print_vertex_list(struct gl_context *ctx, void *data) +vbo_print_vertex_list(struct gl_context *ctx, void *data, FILE *f) { struct vbo_save_vertex_list *node = (struct vbo_save_vertex_list *) data; GLuint i; + struct gl_buffer_object *buffer = node->vertex_store ? + node->vertex_store->bufferobj : NULL; (void) ctx; - printf("VBO-VERTEX-LIST, %u vertices %d primitives, %d vertsize\n", - node->count, node->prim_count, node->vertex_size); + fprintf(f, "VBO-VERTEX-LIST, %u vertices %d primitives, %d vertsize " + "buffer %p\n", + node->count, node->prim_count, node->vertex_size, + buffer); for (i = 0; i < node->prim_count; i++) { struct _mesa_prim *prim = &node->prim[i]; - printf(" prim %d: %s%s %d..%d %s %s\n", + fprintf(f, " prim %d: %s%s %d..%d %s %s\n", i, _mesa_lookup_prim_by_nr(prim->mode), prim->weak ? " (weak)" : "", diff --git a/mesalib/src/mesa/x86/3dnow.c b/mesalib/src/mesa/x86/3dnow.c index 4e3003b43..c46cfbc57 100644 --- a/mesalib/src/mesa/x86/3dnow.c +++ b/mesalib/src/mesa/x86/3dnow.c @@ -46,8 +46,6 @@ DECLARE_XFORM_GROUP( 3dnow, 2 ) DECLARE_XFORM_GROUP( 3dnow, 3 ) DECLARE_XFORM_GROUP( 3dnow, 4 ) -DECLARE_NORM_GROUP( 3dnow ) - extern void _ASMAPI _mesa_v16_3dnow_general_xform( GLfloat *first_vert, @@ -78,11 +76,6 @@ void _mesa_init_3dnow_transform_asm( void ) ASSIGN_XFORM_GROUP( 3dnow, 3 ); ASSIGN_XFORM_GROUP( 3dnow, 4 ); - /* There's a bug somewhere in the 3dnow_normal.S file that causes - * bad shading. Disable for now. - ASSIGN_NORM_GROUP( 3dnow ); - */ - #ifdef DEBUG_MATH _math_test_all_transform_functions( "3DNow!" ); _math_test_all_normal_transform_functions( "3DNow!" ); diff --git a/mesalib/src/mesa/x86/3dnow_normal.S b/mesalib/src/mesa/x86/3dnow_normal.S deleted file mode 100644 index ca95f2548..000000000 --- a/mesalib/src/mesa/x86/3dnow_normal.S +++ /dev/null @@ -1,852 +0,0 @@ - -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2003 Brian Paul 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 - * 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. - */ - -/* - * 3Dnow assembly code by Holger Waechtler - */ - -#ifdef USE_3DNOW_ASM - -#include "assyntax.h" -#include "matypes.h" -#include "norm_args.h" - - SEG_TEXT - -#define M(i) REGOFF(i * 4, ECX) -#define STRIDE REGOFF(12, ESI) - - -ALIGNTEXT16 -GLOBL GLNAME(_mesa_3dnow_transform_normalize_normals) -HIDDEN(_mesa_3dnow_transform_normalize_normals) -GLNAME(_mesa_3dnow_transform_normalize_normals): - -#define FRAME_OFFSET 12 - - PUSH_L ( EDI ) - PUSH_L ( ESI ) - PUSH_L ( EBP ) - - MOV_L ( ARG_LENGTHS, EDI ) - MOV_L ( ARG_IN, ESI ) - MOV_L ( ARG_DEST, EAX ) - MOV_L ( REGOFF(V4F_COUNT, ESI), EBP ) /* dest->count = in->count */ - MOV_L ( EBP, REGOFF(V4F_COUNT, EAX) ) - MOV_L ( REGOFF(V4F_START, ESI), EDX ) /* in->start */ - MOV_L ( REGOFF(V4F_START, EAX), EAX ) /* dest->start */ - MOV_L ( ARG_MAT, ECX ) - MOV_L ( REGOFF(MATRIX_INV, ECX), ECX ) /* mat->inv */ - - CMP_L ( CONST(0), EBP ) /* count > 0 ?? */ - JE ( LLBL (G3TN_end) ) - - MOV_L ( REGOFF (V4F_COUNT, ESI), EBP ) - FEMMS - - PUSH_L ( EBP ) - PUSH_L ( EAX ) - PUSH_L ( EDX ) /* save counter & pointer for */ - /* the normalize pass */ -#undef FRAME_OFFSET -#define FRAME_OFFSET 24 - - MOVQ ( M(0), MM3 ) /* m1 | m0 */ - MOVQ ( M(4), MM4 ) /* m5 | m4 */ - - MOVD ( M(2), MM5 ) /* | m2 */ - PUNPCKLDQ ( M(6), MM5 ) /* m6 | m2 */ - - MOVQ ( M(8), MM6 ) /* m9 | m8 */ - MOVQ ( M(10), MM7 ) /* | m10 */ - - CMP_L ( CONST(0), EDI ) /* lengths == 0 ? */ - JNE ( LLBL (G3TN_scale_end ) ) - - MOVD ( ARG_SCALE, MM0 ) /* | scale */ - PUNPCKLDQ ( MM0, MM0 ) /* scale | scale */ - - PFMUL ( MM0, MM3 ) /* scale * m1 | scale * m0 */ - PFMUL ( MM0, MM4 ) /* scale * m5 | scale * m4 */ - PFMUL ( MM0, MM5 ) /* scale * m6 | scale * m2 */ - PFMUL ( MM0, MM6 ) /* scale * m9 | scale * m8 */ - PFMUL ( MM0, MM7 ) /* | scale * m10 */ - -ALIGNTEXT32 -LLBL (G3TN_scale_end): -LLBL (G3TN_transform): - MOVQ ( REGIND (EDX), MM0 ) /* x1 | x0 */ - MOVD ( REGOFF (8, EDX), MM2 ) /* | x2 */ - - MOVQ ( MM0, MM1 ) /* x1 | x0 */ - PUNPCKLDQ ( MM2, MM2 ) /* x2 | x2 */ - - PFMUL ( MM3, MM0 ) /* x1*m1 | x0*m0 */ - ADD_L ( CONST(16), EAX ) /* next r */ - - PREFETCHW ( REGIND(EAX) ) - - PFMUL ( MM4, MM1 ) /* x1*m5 | x0*m4 */ - PFACC ( MM1, MM0 ) /* x0*m4+x1*m5 | x0*m0+x1*m1 */ - - PFMUL ( MM5, MM2 ) /* x2*m6 | x2*m2 */ - PFADD ( MM2, MM0 ) /* x0*m4+x1*m5+x2*m6| x0*m0+...+x2**/ - - MOVQ ( REGIND (EDX), MM1 ) /* x1 | x0 */ - MOVQ ( MM0, REGOFF(-16, EAX) ) /* write r0, r1 */ - - PFMUL ( MM6, MM1 ) /* x1*m9 | x0*m8 */ - MOVD ( REGOFF (8, EDX), MM2 ) /* | x2 */ - - PFMUL ( MM7, MM2 ) /* | x2*m10 */ - PFACC ( MM1, MM1 ) /* *not used* | x0*m8+x1*m9 */ - - PFADD ( MM2, MM1 ) /* *not used* | x0*m8+x1*m9+x2*m*/ - ADD_L ( STRIDE, EDX ) /* next normal */ - - PREFETCH ( REGIND(EDX) ) - - MOVD ( MM1, REGOFF(-8, EAX) ) /* write r2 */ - SUB_L ( CONST(1), EBP ) /* decrement normal counter */ - JNZ ( LLBL (G3TN_transform) ) - - - POP_L ( EDX ) /* end of transform --- */ - POP_L ( EAX ) /* now normalizing ... */ - POP_L ( EBP ) - - CMP_L ( CONST(0), EDI ) /* lengths == 0 ? */ - JE ( LLBL (G3TN_norm ) ) /* calculate lengths */ - - -ALIGNTEXT32 -LLBL (G3TN_norm_w_lengths): - - PREFETCHW ( REGOFF(12,EAX) ) - - MOVQ ( REGIND(EAX), MM0 ) /* x1 | x0 */ - MOVD ( REGOFF(8, EAX), MM1 ) /* | x2 */ - - MOVD ( REGIND (EDI), MM3 ) /* | length (x) */ - PFMUL ( MM3, MM1 ) /* | x2 (normalize*/ - - PUNPCKLDQ ( MM3, MM3 ) /* length (x) | length (x) */ - PFMUL ( MM3, MM0 ) /* x1 (normalized) | x0 (normalize*/ - - ADD_L ( STRIDE, EDX ) /* next normal */ - ADD_L ( CONST(4), EDI ) /* next length */ - - PREFETCH ( REGIND(EDI) ) - - MOVQ ( MM0, REGIND(EAX) ) /* write new x0, x1 */ - MOVD ( MM1, REGOFF(8, EAX) ) /* write new x2 */ - - ADD_L ( CONST(16), EAX ) /* next r */ - SUB_L ( CONST(1), EBP ) /* decrement normal counter */ - - JNZ ( LLBL (G3TN_norm_w_lengths) ) - JMP ( LLBL (G3TN_exit_3dnow) ) - -ALIGNTEXT32 -LLBL (G3TN_norm): - - PREFETCHW ( REGIND(EAX) ) - - MOVQ ( REGIND (EAX), MM0 ) /* x1 | x0 */ - MOVD ( REGOFF(8, EAX), MM1 ) /* | x2 */ - - MOVQ ( MM0, MM3 ) /* x1 | x0 */ - MOVQ ( MM1, MM4 ) /* | x2 */ - - PFMUL ( MM0, MM3 ) /* x1*x1 | x0*x0 */ - ADD_L ( CONST(16), EAX ) /* next r */ - - PFMUL ( MM1, MM4 ) /* | x2*x2 */ - PFADD ( MM4, MM3 ) /* | x0*x0+x2*x2 */ - - PFACC ( MM3, MM3 ) /* **not used** | x0*x0+x1*x1+x2**/ - PFRSQRT ( MM3, MM5 ) /* 1/sqrt (x0*x0+x1*x1+x2*x2) */ - - MOVQ ( MM5, MM4 ) - PUNPCKLDQ ( MM3, MM3 ) - - SUB_L ( CONST(1), EBP ) /* decrement normal counter */ - PFMUL ( MM5, MM5 ) - - PFRSQIT1 ( MM3, MM5 ) - PFRCPIT2 ( MM4, MM5 ) - - PFMUL ( MM5, MM0 ) /* x1 (normalized) | x0 (normalize*/ - - MOVQ ( MM0, REGOFF(-16, EAX) ) /* write new x0, x1 */ - PFMUL ( MM5, MM1 ) /* | x2 (normalize*/ - - MOVD ( MM1, REGOFF(-8, EAX) ) /* write new x2 */ - JNZ ( LLBL (G3TN_norm) ) - -LLBL (G3TN_exit_3dnow): - FEMMS - -LLBL (G3TN_end): - POP_L ( EBP ) - POP_L ( ESI ) - POP_L ( EDI ) - RET - - - -ALIGNTEXT16 -GLOBL GLNAME(_mesa_3dnow_transform_normalize_normals_no_rot) -HIDDEN(_mesa_3dnow_transform_normalize_normals_no_rot) -GLNAME(_mesa_3dnow_transform_normalize_normals_no_rot): - -#undef FRAME_OFFSET -#define FRAME_OFFSET 12 - - PUSH_L ( EDI ) - PUSH_L ( ESI ) - PUSH_L ( EBP ) - - MOV_L ( ARG_LENGTHS, EDI ) - MOV_L ( ARG_IN, ESI ) - MOV_L ( ARG_DEST, EAX ) - MOV_L ( REGOFF(V4F_COUNT, ESI), EBP ) /* dest->count = in->count */ - MOV_L ( EBP, REGOFF(V4F_COUNT, EAX) ) - MOV_L ( ARG_MAT, ECX ) - MOV_L ( REGOFF(V4F_START, EAX), EAX ) /* dest->start */ - MOV_L ( REGOFF(MATRIX_INV, ECX), ECX ) /* mat->inv */ - MOV_L ( REGOFF(V4F_START, ESI), EDX ) /* in->start */ - - CMP_L ( CONST(0), EBP ) /* count > 0 ?? */ - JE ( LLBL (G3TNNR_end) ) - - FEMMS - - MOVD ( M(0), MM0 ) /* | m0 */ - PUNPCKLDQ ( M(5), MM0 ) /* m5 | m0 */ - - MOVD ( M(10), MM2 ) /* | m10 */ - PUNPCKLDQ ( MM2, MM2 ) /* m10 | m10 */ - - CMP_L ( CONST(0), EDI ) /* lengths == 0 ? */ - JNE ( LLBL (G3TNNR_scale_end ) ) - - MOVD ( ARG_SCALE, MM7 ) /* | scale */ - PUNPCKLDQ ( MM7, MM7 ) /* scale | scale */ - - PFMUL ( MM7, MM0 ) /* scale * m5 | scale * m0 */ - PFMUL ( MM7, MM2 ) /* scale * m10 | scale * m10 */ - -ALIGNTEXT32 -LLBL (G3TNNR_scale_end): - CMP_L ( CONST(0), EDI ) /* lengths == 0 ? */ - JE ( LLBL (G3TNNR_norm) ) /* need to calculate lengths */ - - MOVD ( REGIND(EDI), MM3 ) /* | length (x) */ - - -ALIGNTEXT32 -LLBL (G3TNNR_norm_w_lengths): /* use precalculated lengths */ - - PREFETCHW ( REGIND(EAX) ) - - MOVQ ( REGIND(EDX), MM6 ) /* x1 | x0 */ - MOVD ( REGOFF(8, EDX), MM7 ) /* | x2 */ - - PFMUL ( MM0, MM6 ) /* x1*m5 | x0*m0 */ - ADD_L ( STRIDE, EDX ) /* next normal */ - - PREFETCH ( REGIND(EDX) ) - - PFMUL ( MM2, MM7 ) /* | x2*m10 */ - ADD_L ( CONST(16), EAX ) /* next r */ - - PFMUL ( MM3, MM7 ) /* | x2 (normalized) */ - PUNPCKLDQ ( MM3, MM3 ) /* length (x) | length (x) */ - - ADD_L ( CONST(4), EDI ) /* next length */ - PFMUL ( MM3, MM6 ) /* x1 (normalized) | x0 (normalized) */ - - SUB_L ( CONST(1), EBP ) /* decrement normal counter */ - MOVQ ( MM6, REGOFF(-16, EAX) ) /* write r0, r1 */ - - MOVD ( MM7, REGOFF(-8, EAX) ) /* write r2 */ - MOVD ( REGIND(EDI), MM3 ) /* | length (x) */ - - JNZ ( LLBL (G3TNNR_norm_w_lengths) ) - JMP ( LLBL (G3TNNR_exit_3dnow) ) - -ALIGNTEXT32 -LLBL (G3TNNR_norm): /* need to calculate lengths */ - - PREFETCHW ( REGIND(EAX) ) - - MOVQ ( REGIND(EDX), MM6 ) /* x1 | x0 */ - MOVD ( REGOFF(8, EDX), MM7 ) /* | x2 */ - - PFMUL ( MM0, MM6 ) /* x1*m5 | x0*m0 */ - ADD_L ( CONST(16), EAX ) /* next r */ - - PFMUL ( MM2, MM7 ) /* | x2*m10 */ - MOVQ ( MM6, MM3 ) /* x1 (transformed)| x0 (transformed) */ - - MOVQ ( MM7, MM4 ) /* | x2 (transformed) */ - PFMUL ( MM6, MM3 ) /* x1*x1 | x0*x0 */ - - - PFMUL ( MM7, MM4 ) /* | x2*x2 */ - PFACC ( MM3, MM3 ) /* **not used** | x0*x0+x1*x1 */ - - PFADD ( MM4, MM3 ) /* | x0*x0+x1*x1+x2*x2*/ - ADD_L ( STRIDE, EDX ) /* next normal */ - - PREFETCH ( REGIND(EDX) ) - - PFRSQRT ( MM3, MM5 ) /* 1/sqrt (x0*x0+x1*x1+x2*x2) */ - MOVQ ( MM5, MM4 ) - - PUNPCKLDQ ( MM3, MM3 ) - PFMUL ( MM5, MM5 ) - - PFRSQIT1 ( MM3, MM5 ) - SUB_L ( CONST(1), EBP ) /* decrement normal counter */ - - PFRCPIT2 ( MM4, MM5 ) - PFMUL ( MM5, MM6 ) /* x1 (normalized) | x0 (normalized) */ - - MOVQ ( MM6, REGOFF(-16, EAX) ) /* write r0, r1 */ - PFMUL ( MM5, MM7 ) /* | x2 (normalized) */ - - MOVD ( MM7, REGOFF(-8, EAX) ) /* write r2 */ - JNZ ( LLBL (G3TNNR_norm) ) - - -LLBL (G3TNNR_exit_3dnow): - FEMMS - -LLBL (G3TNNR_end): - POP_L ( EBP ) - POP_L ( ESI ) - POP_L ( EDI ) - RET - - - - - - -ALIGNTEXT16 -GLOBL GLNAME(_mesa_3dnow_transform_rescale_normals_no_rot) -HIDDEN(_mesa_3dnow_transform_rescale_normals_no_rot) -GLNAME(_mesa_3dnow_transform_rescale_normals_no_rot): - -#undef FRAME_OFFSET -#define FRAME_OFFSET 12 - - PUSH_L ( EDI ) - PUSH_L ( ESI ) - PUSH_L ( EBP ) - - MOV_L ( ARG_IN, EAX ) - MOV_L ( ARG_DEST, EDX ) - MOV_L ( REGOFF(V4F_COUNT, EAX), EBP ) /* dest->count = in->count */ - MOV_L ( EBP, REGOFF(V4F_COUNT, EDX) ) - MOV_L ( ARG_IN, ESI ) - MOV_L ( ARG_MAT, ECX ) - MOV_L ( REGOFF(MATRIX_INV, ECX), ECX ) /* mat->inv */ - MOV_L ( REGOFF(V4F_START, EDX), EAX ) /* dest->start */ - MOV_L ( REGOFF(V4F_START, ESI), EDX ) /* in->start */ - - CMP_L ( CONST(0), EBP ) - JE ( LLBL (G3TRNR_end) ) - - FEMMS - - MOVD ( ARG_SCALE, MM6 ) /* | scale */ - PUNPCKLDQ ( MM6, MM6 ) /* scale | scale */ - - MOVD ( REGIND(ECX), MM0 ) /* | m0 */ - PUNPCKLDQ ( REGOFF(20, ECX), MM0 ) /* m5 | m0 */ - - PFMUL ( MM6, MM0 ) /* scale*m5 | scale*m0 */ - MOVD ( REGOFF(40, ECX), MM2 ) /* | m10 */ - - PFMUL ( MM6, MM2 ) /* | scale*m10 */ - -ALIGNTEXT32 -LLBL (G3TRNR_rescale): - - PREFETCHW ( REGIND(EAX) ) - - MOVQ ( REGIND(EDX), MM4 ) /* x1 | x0 */ - MOVD ( REGOFF(8, EDX), MM5 ) /* | x2 */ - - PFMUL ( MM0, MM4 ) /* x1*m5 | x0*m0 */ - ADD_L ( STRIDE, EDX ) /* next normal */ - - PREFETCH ( REGIND(EDX) ) - - PFMUL ( MM2, MM5 ) /* | x2*m10 */ - ADD_L ( CONST(16), EAX ) /* next r */ - - SUB_L ( CONST(1), EBP ) /* decrement normal counter */ - MOVQ ( MM4, REGOFF(-16, EAX) ) /* write r0, r1 */ - - MOVD ( MM5, REGOFF(-8, EAX) ) /* write r2 */ - JNZ ( LLBL (G3TRNR_rescale) ) /* cnt > 0 ? -> process next normal */ - - FEMMS - -LLBL (G3TRNR_end): - POP_L ( EBP ) - POP_L ( ESI ) - POP_L ( EDI ) - RET - - - - - -ALIGNTEXT16 -GLOBL GLNAME(_mesa_3dnow_transform_rescale_normals) -HIDDEN(_mesa_3dnow_transform_rescale_normals) -GLNAME(_mesa_3dnow_transform_rescale_normals): - -#undef FRAME_OFFSET -#define FRAME_OFFSET 8 - - PUSH_L ( EDI ) - PUSH_L ( ESI ) - - MOV_L ( ARG_IN, ESI ) - MOV_L ( ARG_DEST, EAX ) - MOV_L ( ARG_MAT, ECX ) - MOV_L ( REGOFF(V4F_COUNT, ESI), EDI ) /* dest->count = in->count */ - MOV_L ( EDI, REGOFF(V4F_COUNT, EAX) ) - MOV_L ( REGOFF(V4F_START, EAX), EAX ) /* dest->start */ - MOV_L ( REGOFF(V4F_START, ESI), EDX ) /* in->start */ - MOV_L ( REGOFF(MATRIX_INV, ECX), ECX ) /* mat->inv */ - - CMP_L ( CONST(0), EDI ) - JE ( LLBL (G3TR_end) ) - - FEMMS - - MOVQ ( REGIND(ECX), MM3 ) /* m1 | m0 */ - - MOVQ ( REGOFF(16,ECX), MM4 ) /* m5 | m4 */ - MOVD ( ARG_SCALE, MM0 ) /* scale */ - - MOVD ( REGOFF(8,ECX), MM5 ) /* | m2 */ - PUNPCKLDQ ( MM0, MM0 ) /* scale | scale */ - - PUNPCKLDQ ( REGOFF(24, ECX), MM5 ) - PFMUL ( MM0, MM3 ) /* scale*m1 | scale*m0 */ - - MOVQ ( REGOFF(32, ECX), MM6 ) /* m9 | m8*/ - PFMUL ( MM0, MM4 ) /* scale*m5 | scale*m4 */ - - MOVD ( REGOFF(40, ECX), MM7 ) /* | m10 */ - PFMUL ( MM0, MM5 ) /* scale*m6 | scale*m2 */ - - PFMUL ( MM0, MM6 ) /* scale*m9 | scale*m8 */ - - PFMUL ( MM0, MM7 ) /* | scale*m10 */ - -ALIGNTEXT32 -LLBL (G3TR_rescale): - - PREFETCHW ( REGIND(EAX) ) - - MOVQ ( REGIND(EDX), MM0 ) /* x1 | x0 */ - MOVD ( REGOFF(8, EDX), MM2 ) /* | x2 */ - - MOVQ ( MM0, MM1 ) /* x1 | x0 */ - PUNPCKLDQ ( MM2, MM2 ) /* x2 | x2 */ - - PFMUL ( MM3, MM0 ) /* x1*m1 | x0*m0 */ - ADD_L ( CONST(16), EAX ) /* next r */ - - PFMUL ( MM4, MM1 ) /* x1*m5 | x0*m4 */ - PFACC ( MM1, MM0 ) /* x0*m4+x1*m5 | x0*m0+x1*m1 */ - - MOVQ ( REGIND(EDX), MM1 ) /* x1 | x0 */ - - PFMUL ( MM5, MM2 ) /* x2*m6 | x2*m2 */ - PFADD ( MM2, MM0 ) /* x0*m4...+x2*m6| x0*m0+x1*m1+x2*m2 */ - - MOVD ( REGOFF(8, EDX), MM2 ) /* | x2 */ - ADD_L ( STRIDE, EDX ) /* next normal */ - - PREFETCH ( REGIND(EDX) ) - - MOVQ ( MM0, REGOFF(-16, EAX) ) /* write r0, r1 */ - PFMUL ( MM6, MM1 ) /* x1*m9 | x0*m8 */ - - PFMUL ( MM7, MM2 ) /* | x2*m10 */ - PFACC ( MM1, MM1 ) /* *not used* | x0*m8+x1*m9 */ - - PFADD ( MM2, MM1 ) /* *not used* | x0*m8+x1*m9+x2*m10 */ - MOVD ( MM1, REGOFF(-8, EAX) ) /* write r2 */ - - SUB_L ( CONST(1), EDI ) /* decrement normal counter */ - JNZ ( LLBL (G3TR_rescale) ) - - FEMMS - -LLBL (G3TR_end): - POP_L ( ESI ) - POP_L ( EDI ) - RET - - - - - - - -ALIGNTEXT16 -GLOBL GLNAME(_mesa_3dnow_transform_normals_no_rot) -HIDDEN(_mesa_3dnow_transform_normals_no_rot) -GLNAME(_mesa_3dnow_transform_normals_no_rot): - -#undef FRAME_OFFSET -#define FRAME_OFFSET 8 - - PUSH_L ( EDI ) - PUSH_L ( ESI ) - - MOV_L ( ARG_IN, ESI ) - MOV_L ( ARG_DEST, EAX ) - MOV_L ( ARG_MAT, ECX ) - MOV_L ( REGOFF(V4F_COUNT, ESI), EDI ) /* dest->count = in->count */ - MOV_L ( EDI, REGOFF(V4F_COUNT, EAX) ) - MOV_L ( REGOFF(V4F_START, EAX), EAX ) /* dest->start */ - MOV_L ( REGOFF(V4F_START, ESI), EDX ) /* in->start */ - MOV_L ( REGOFF(MATRIX_INV, ECX), ECX ) /* mat->inv */ - - CMP_L ( CONST(0), EDI ) - JE ( LLBL (G3TNR_end) ) - - FEMMS - - MOVD ( REGIND(ECX), MM0 ) /* | m0 */ - PUNPCKLDQ ( REGOFF(20, ECX), MM0 ) /* m5 | m0 */ - - MOVD ( REGOFF(40, ECX), MM2 ) /* | m10 */ - PUNPCKLDQ ( MM2, MM2 ) /* m10 | m10 */ - -ALIGNTEXT32 -LLBL (G3TNR_transform): - - PREFETCHW ( REGIND(EAX) ) - - MOVQ ( REGIND(EDX), MM4 ) /* x1 | x0 */ - MOVD ( REGOFF(8, EDX), MM5 ) /* | x2 */ - - PFMUL ( MM0, MM4 ) /* x1*m5 | x0*m0 */ - ADD_L ( STRIDE, EDX) /* next normal */ - - PREFETCH ( REGIND(EDX) ) - - PFMUL ( MM2, MM5 ) /* | x2*m10 */ - ADD_L ( CONST(16), EAX ) /* next r */ - - SUB_L ( CONST(1), EDI ) /* decrement normal counter */ - MOVQ ( MM4, REGOFF(-16, EAX) ) /* write r0, r1 */ - - MOVD ( MM5, REGOFF(-8, EAX) ) /* write r2 */ - JNZ ( LLBL (G3TNR_transform) ) - - FEMMS - -LLBL (G3TNR_end): - POP_L ( ESI ) - POP_L ( EDI ) - RET - - - - - - - - -ALIGNTEXT16 -GLOBL GLNAME(_mesa_3dnow_transform_normals) -HIDDEN(_mesa_3dnow_transform_normals) -GLNAME(_mesa_3dnow_transform_normals): - -#undef FRAME_OFFSET -#define FRAME_OFFSET 8 - - PUSH_L ( EDI ) - PUSH_L ( ESI ) - - MOV_L ( ARG_IN, ESI ) - MOV_L ( ARG_DEST, EAX ) - MOV_L ( ARG_MAT, ECX ) - MOV_L ( REGOFF(V4F_COUNT, ESI), EDI ) /* dest->count = in->count */ - MOV_L ( EDI, REGOFF(V4F_COUNT, EAX) ) - MOV_L ( REGOFF(V4F_START, EAX), EAX ) /* dest->start */ - MOV_L ( REGOFF(V4F_START, ESI), EDX ) /* in->start */ - MOV_L ( REGOFF(MATRIX_INV, ECX), ECX ) /* mat->inv */ - - CMP_L ( CONST(0), EDI ) /* count > 0 ?? */ - JE ( LLBL (G3T_end) ) - - FEMMS - - MOVQ ( REGIND(ECX), MM3 ) /* m1 | m0 */ - MOVQ ( REGOFF(16, ECX), MM4 ) /* m5 | m4 */ - - MOVD ( REGOFF(8, ECX), MM5 ) /* | m2 */ - PUNPCKLDQ ( REGOFF(24, ECX), MM5 ) /* m6 | m2 */ - - MOVQ ( REGOFF(32, ECX), MM6 ) /* m9 | m8 */ - MOVD ( REGOFF(40, ECX), MM7 ) /* | m10 */ - -ALIGNTEXT32 -LLBL (G3T_transform): - - PREFETCHW ( REGIND(EAX) ) - - MOVQ ( REGIND(EDX), MM0 ) /* x1 | x0 */ - MOVD ( REGOFF(8, EDX), MM2 ) /* | x2 */ - - MOVQ ( MM0, MM1 ) /* x1 | x0 */ - PUNPCKLDQ ( MM2, MM2 ) /* x2 | x2 */ - - PFMUL ( MM3, MM0 ) /* x1*m1 | x0*m0 */ - ADD_L ( CONST(16), EAX ) /* next r */ - - PFMUL ( MM4, MM1 ) /* x1*m5 | x0*m4 */ - PFACC ( MM1, MM0 ) /* x0*m4+x1*m5 | x0*m0+x1*m1 */ - - PFMUL ( MM5, MM2 ) /* x2*m6 | x2*m2 */ - PFADD ( MM2, MM0 ) /* x0*m4...+x2*m6| x0*m0+x1*m1+x2*m2 */ - - MOVQ ( REGIND(EDX), MM1 ) /* x1 | x0 */ - MOVQ ( MM0, REGOFF(-16, EAX) ) /* write r0, r1 */ - - PFMUL ( MM6, MM1 ) /* x1*m9 | x0*m8 */ - MOVD ( REGOFF(8, EDX), MM2 ) /* | x2 */ - - PFMUL ( MM7, MM2 ) /* | x2*m10 */ - ADD_L ( STRIDE, EDX ) /* next normal */ - - PREFETCH ( REGIND(EDX) ) - - PFACC ( MM1, MM1 ) /* *not used* | x0*m8+x1*m9 */ - PFADD ( MM2, MM1 ) /* *not used* | x0*m8+x1*m9+x2*m10 */ - - MOVD ( MM1, REGOFF(-8, EAX) ) /* write r2 */ - SUB_L ( CONST(1), EDI ) /* decrement normal counter */ - - JNZ ( LLBL (G3T_transform) ) - - FEMMS - -LLBL (G3T_end): - POP_L ( ESI ) - POP_L ( EDI ) - RET - - - - - - -ALIGNTEXT16 -GLOBL GLNAME(_mesa_3dnow_normalize_normals) -HIDDEN(_mesa_3dnow_normalize_normals) -GLNAME(_mesa_3dnow_normalize_normals): - -#undef FRAME_OFFSET -#define FRAME_OFFSET 12 - - PUSH_L ( EDI ) - PUSH_L ( ESI ) - PUSH_L ( EBP ) - - MOV_L ( ARG_IN, ESI ) - MOV_L ( ARG_DEST, EAX ) - MOV_L ( REGOFF(V4F_COUNT, ESI), EBP ) /* dest->count = in->count */ - MOV_L ( EBP, REGOFF(V4F_COUNT, EAX) ) - MOV_L ( REGOFF(V4F_START, EAX), EAX ) /* dest->start */ - MOV_L ( REGOFF(V4F_START, ESI), ECX ) /* in->start */ - MOV_L ( ARG_LENGTHS, EDX ) - - CMP_L ( CONST(0), EBP ) /* count > 0 ?? */ - JE ( LLBL (G3N_end) ) - - FEMMS - - CMP_L ( CONST(0), EDX ) /* lengths == 0 ? */ - JE ( LLBL (G3N_norm2) ) /* calculate lengths */ - -ALIGNTEXT32 -LLBL (G3N_norm1): /* use precalculated lengths */ - - PREFETCH ( REGIND(EAX) ) - - MOVQ ( REGIND(ECX), MM0 ) /* x1 | x0 */ - MOVD ( REGOFF(8, ECX), MM1 ) /* | x2 */ - - MOVD ( REGIND(EDX), MM3 ) /* | length (x) */ - PFMUL ( MM3, MM1 ) /* | x2 (normalized) */ - - PUNPCKLDQ ( MM3, MM3 ) /* length (x) | length (x) */ - ADD_L ( STRIDE, ECX ) /* next normal */ - - PREFETCH ( REGIND(ECX) ) - - PFMUL ( MM3, MM0 ) /* x1 (normalized) | x0 (normalized) */ - MOVQ ( MM0, REGIND(EAX) ) /* write new x0, x1 */ - - MOVD ( MM1, REGOFF(8, EAX) ) /* write new x2 */ - ADD_L ( CONST(16), EAX ) /* next r */ - - ADD_L ( CONST(4), EDX ) /* next length */ - SUB_L ( CONST(1), EBP ) /* decrement normal counter */ - - JNZ ( LLBL (G3N_norm1) ) - - JMP ( LLBL (G3N_end1) ) - -ALIGNTEXT32 -LLBL (G3N_norm2): /* need to calculate lengths */ - - PREFETCHW ( REGIND(EAX) ) - - PREFETCH ( REGIND(ECX) ) - - MOVQ ( REGIND(ECX), MM0 ) /* x1 | x0 */ - MOVD ( REGOFF(8, ECX), MM1 ) /* | x2 */ - - MOVQ ( MM0, MM3 ) /* x1 | x0 */ - ADD_L ( STRIDE, ECX ) /* next normal */ - - PFMUL ( MM0, MM3 ) /* x1*x1 | x0*x0 */ - MOVQ ( MM1, MM4 ) /* | x2 */ - - ADD_L ( CONST(16), EAX ) /* next r */ - PFMUL ( MM1, MM4 ) /* | x2*x2 */ - - PFADD ( MM4, MM3 ) /* | x0*x0+x2*x2 */ - PFACC ( MM3, MM3 ) /* x0*x0+...+x2*x2 | x0*x0+x1*x1+x2*x2*/ - - PFRSQRT ( MM3, MM5 ) /* 1/sqrt (x0*x0+x1*x1+x2*x2) */ - MOVQ ( MM5, MM4 ) - - PUNPCKLDQ ( MM3, MM3 ) - PFMUL ( MM5, MM5 ) - - PFRSQIT1 ( MM3, MM5 ) - SUB_L ( CONST(1), EBP ) /* decrement normal counter */ - - PFRCPIT2 ( MM4, MM5 ) - - PFMUL ( MM5, MM0 ) /* x1 (normalized) | x0 (normalized) */ - MOVQ ( MM0, REGOFF(-16, EAX) ) /* write new x0, x1 */ - - PFMUL ( MM5, MM1 ) /* | x2 (normalized) */ - MOVD ( MM1, REGOFF(-8, EAX) ) /* write new x2 */ - - JNZ ( LLBL (G3N_norm2) ) - -LLBL (G3N_end1): - FEMMS - -LLBL (G3N_end): - POP_L ( EBP ) - POP_L ( ESI ) - POP_L ( EDI ) - RET - - - - - - -ALIGNTEXT16 -GLOBL GLNAME(_mesa_3dnow_rescale_normals) -HIDDEN(_mesa_3dnow_rescale_normals) -GLNAME(_mesa_3dnow_rescale_normals): - -#undef FRAME_OFFSET -#define FRAME_OFFSET 8 - PUSH_L ( EDI ) - PUSH_L ( ESI ) - - MOV_L ( ARG_IN, ESI ) - MOV_L ( ARG_DEST, EAX ) - MOV_L ( REGOFF(V4F_COUNT, ESI), EDX ) /* dest->count = in->count */ - MOV_L ( EDX, REGOFF(V4F_COUNT, EAX) ) - MOV_L ( REGOFF(V4F_START, EAX), EAX ) /* dest->start */ - MOV_L ( REGOFF(V4F_START, ESI), ECX ) /* in->start */ - - CMP_L ( CONST(0), EDX ) - JE ( LLBL (G3R_end) ) - - FEMMS - - MOVD ( ARG_SCALE, MM0 ) /* scale */ - PUNPCKLDQ ( MM0, MM0 ) - -ALIGNTEXT32 -LLBL (G3R_rescale): - - PREFETCHW ( REGIND(EAX) ) - - MOVQ ( REGIND(ECX), MM1 ) /* x1 | x0 */ - MOVD ( REGOFF(8, ECX), MM2 ) /* | x2 */ - - PFMUL ( MM0, MM1 ) /* x1*scale | x0*scale */ - ADD_L ( STRIDE, ECX ) /* next normal */ - - PREFETCH ( REGIND(ECX) ) - - PFMUL ( MM0, MM2 ) /* | x2*scale */ - ADD_L ( CONST(16), EAX ) /* next r */ - - MOVQ ( MM1, REGOFF(-16, EAX) ) /* write r0, r1 */ - MOVD ( MM2, REGOFF(-8, EAX) ) /* write r2 */ - - SUB_L ( CONST(1), EDX ) /* decrement normal counter */ - JNZ ( LLBL (G3R_rescale) ) - - FEMMS - -LLBL (G3R_end): - POP_L ( ESI ) - POP_L ( EDI ) - RET - -#endif - -#if defined (__ELF__) && defined (__linux__) - .section .note.GNU-stack,"",%progbits -#endif -- cgit v1.2.3